coomdev
2 years ago
commit
9823da0ad6
7 changed files with 7963 additions and 0 deletions
@ -0,0 +1,38 @@ |
|||
PNG Extra Embedder (PEE) |
|||
======================== |
|||
|
|||
Can embed any file in a PNG and upload it through 4chanX. |
|||
Requires 4chanX and tampermonkey. |
|||
|
|||
Notes: 4chan seems to limit the amount of embedded data to around 140kb files. |
|||
|
|||
How to Build |
|||
============ |
|||
|
|||
npm i and npm run build |
|||
then add something like |
|||
|
|||
``` |
|||
// ==UserScript== |
|||
// @name PNGFileEmbed |
|||
// @namespace http://tampermonkey.net/ |
|||
// @version 0.1 |
|||
// @description uhh |
|||
// @author You |
|||
// @match https://boards.4channel.org/g/thread/* |
|||
// @icon https://www.google.com/s2/favicons?domain=4channel.org |
|||
// @grant GM_xmlhttpRequest |
|||
// @run-at document-start |
|||
// @connect 4chan.org |
|||
// @connect 4channel.org |
|||
// @connect i.4cdn.org |
|||
// ==/UserScript== |
|||
``` |
|||
|
|||
at the very top of the file `dist/main.js` and import it in tampermonkey. |
|||
Don't know how to make this automatically yet. |
|||
|
|||
How to Install |
|||
============== |
|||
|
|||
Or use the prebuilt main.user.js at the root of this repo. |
File diff suppressed because it is too large
@ -0,0 +1,28 @@ |
|||
{ |
|||
"name": "coomext", |
|||
"version": "1.0.0", |
|||
"lockfileVersion": 2, |
|||
"requires": true, |
|||
"packages": { |
|||
"": { |
|||
"name": "coomext", |
|||
"version": "1.0.0", |
|||
"license": "ISC", |
|||
"dependencies": { |
|||
"@types/tampermonkey": "^4.0.5" |
|||
} |
|||
}, |
|||
"node_modules/@types/tampermonkey": { |
|||
"version": "4.0.5", |
|||
"resolved": "https://registry.npmjs.org/@types/tampermonkey/-/tampermonkey-4.0.5.tgz", |
|||
"integrity": "sha512-FGPo7d+qZkDF7vyrwY1WNhcUnfDyVpt2uyL7krAu3WKCUMCfIUzOuvt8aSk8N2axHT8XPr9stAEDGVHLvag6Pw==" |
|||
} |
|||
}, |
|||
"dependencies": { |
|||
"@types/tampermonkey": { |
|||
"version": "4.0.5", |
|||
"resolved": "https://registry.npmjs.org/@types/tampermonkey/-/tampermonkey-4.0.5.tgz", |
|||
"integrity": "sha512-FGPo7d+qZkDF7vyrwY1WNhcUnfDyVpt2uyL7krAu3WKCUMCfIUzOuvt8aSk8N2axHT8XPr9stAEDGVHLvag6Pw==" |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,28 @@ |
|||
{ |
|||
"name": "coomext", |
|||
"version": "1.0.0", |
|||
"description": "", |
|||
"main": "index.js", |
|||
"scripts": { |
|||
"test": "echo \"Error: no test specified\" && exit 1", |
|||
"build": "esbuild src/main.ts --bundle --outfile=dist/main.js --define:global=window", |
|||
"watch": "esbuild src/main.ts --bundle --outfile=dist/main.js --define:global=window --watch" |
|||
}, |
|||
"author": "", |
|||
"license": "ISC", |
|||
"dependencies": { |
|||
"@types/tampermonkey": "^4.0.5", |
|||
"buffer": "^6.0.3", |
|||
"crc-32": "^1.2.0", |
|||
"events": "^3.3.0", |
|||
"file-type": "^17.0.2", |
|||
"readable-stream": "^3.6.0" |
|||
}, |
|||
"devDependencies": { |
|||
"esbuild": "^0.14.7" |
|||
}, |
|||
"browser": { |
|||
"node:buffer": "buffer", |
|||
"node:stream": "readable-stream" |
|||
} |
|||
} |
@ -0,0 +1,352 @@ |
|||
/* eslint-disable */ |
|||
|
|||
import { Buffer } from "buffer"; |
|||
import { buf } from "crc-32"; |
|||
import { fileTypeFromBuffer } from 'file-type'; |
|||
|
|||
const IDAT = Buffer.from("IDAT"); |
|||
const IEND = Buffer.from("IEND"); |
|||
const tEXt = Buffer.from("tEXt"); |
|||
const CUM0 = Buffer.from("CUM0"); |
|||
|
|||
let concatAB = (...bufs: Buffer[]) => { |
|||
let sz = bufs.map(e => e.byteLength).reduce((a, b) => a + b); |
|||
const ret = Buffer.alloc(sz); |
|||
let ptr = 0; |
|||
for (const b of bufs) { |
|||
b.copy(ret, ptr); |
|||
ptr += b.byteLength; |
|||
} |
|||
return ret; |
|||
} |
|||
|
|||
let extractTextData = async (reader: ReadableStreamDefaultReader<Uint8Array>) => { |
|||
let total = Buffer.from(''); |
|||
let ptr = 8; |
|||
let req = 8; // required bytes: require the png signature
|
|||
|
|||
try { |
|||
let chunk: ReadableStreamDefaultReadResult<Uint8Array>; |
|||
|
|||
const catchup = async () => { |
|||
while (total.byteLength < req) { |
|||
chunk = await reader.read(); |
|||
if (chunk.done) |
|||
throw new Error("Unexpected EOF"); |
|||
total = concatAB(total, Buffer.from(chunk.value)); |
|||
} |
|||
} |
|||
|
|||
do { |
|||
req += 8; // require the bytes that store the length of the next chunk and its name
|
|||
await catchup(); |
|||
// at this point, ptr pointing to length of current chunk
|
|||
let length = total.readInt32BE(ptr); |
|||
// ptr pointing to type of current chunk
|
|||
ptr += 4; |
|||
const name = total.slice(ptr, ptr + 4); |
|||
if (Buffer.compare(IDAT, name) == 0 || |
|||
Buffer.compare(IEND, name) == 0) { |
|||
// reached idat or iend before finding a tEXt, bail out
|
|||
throw new Error("Couldn't find tEXt chunk"); |
|||
} |
|||
req += length + 4; // require the rest of the chunk + CRC
|
|||
//let crc = total.readInt32BE(ptr + 4 + length); // dont really care
|
|||
ptr += 4; // ptr now points to the chunk data
|
|||
if (Buffer.compare(tEXt, name) == 0) { |
|||
// our specific format stores a single file, CUM0 stores it as Base64. Could be enhanced to use more characters (the whole printable ascii characters, ie base85, but we lack good encoders...)
|
|||
// catchup because we need to know the type;
|
|||
await catchup(); |
|||
if (Buffer.compare(total.slice(ptr, ptr + 4), CUM0) == 0) { |
|||
let data = Buffer.from(total.slice(ptr + 4, ptr + length - 4).toString(), 'base64'); |
|||
let fns = data.readUInt32LE(0); |
|||
let filename = data.slice(4, 4 + fns).toString(); |
|||
return { data: data.slice(4 + fns), filename }; |
|||
} |
|||
// Unknown tEXt format
|
|||
} |
|||
ptr += length + 4; // skips over data section and crc
|
|||
} while (!chunk!.done); |
|||
} catch (e) { |
|||
console.error(e); |
|||
await reader.cancel(); |
|||
reader.releaseLock(); |
|||
} |
|||
} |
|||
|
|||
let TMFetch = GM_xmlhttpRequest || GM.xmlHttpRequest; |
|||
|
|||
let getUrl = (u: string) => { |
|||
let xml: Tampermonkey.AbortHandle<void>; |
|||
|
|||
let pos = 0; |
|||
let total = 0; |
|||
return new ReadableStream<Uint8Array>({ |
|||
cancel() { |
|||
xml?.abort(); |
|||
}, |
|||
|
|||
start(cont) { |
|||
/* |
|||
get a small 128k chunk first then get the rest if required |
|||
*/ |
|||
return new Promise<void>(reso => { |
|||
const size = (cont.desiredSize! > 2 ** 17 ? cont.desiredSize! : 2 ** 17); |
|||
const range = !total ? `bytes=${pos}-${pos + size - 1}` : `bytes=${pos}-${total - 1}`; |
|||
console.log(range, cont.desiredSize); |
|||
xml = TMFetch({ |
|||
url: u, |
|||
fetch: true, |
|||
method: "GET", |
|||
binary: true, |
|||
responseType: "arraybuffer", |
|||
headers: { |
|||
range |
|||
}, |
|||
|
|||
// a bit spagetthi
|
|||
onload(res) { |
|||
let hr = res.responseHeaders.split('\n').map(e => e.split(':')); |
|||
let r = hr.find(e => e[0] == "content-range")!; |
|||
let er = hr.find(e => e[0] == "content-length")!; |
|||
cont.enqueue(Buffer.from(res.response)) |
|||
pos += +er[1]; |
|||
if (r) { |
|||
let m = r[1].match(/bytes 0-\d+\/(\d+)/) |
|||
if (m) |
|||
total = +m[1]; |
|||
} |
|||
if (pos >= total) { |
|||
cont.close() |
|||
reso(); |
|||
return; |
|||
} |
|||
reso(); |
|||
} |
|||
}); |
|||
}) |
|||
|
|||
}, |
|||
pull(cont) { |
|||
console.log("pulling") // shouldn't ever happen
|
|||
return this.start!(cont); |
|||
} |
|||
}, { |
|||
highWaterMark: 40, |
|||
size(c) { |
|||
return 1; |
|||
} |
|||
}) |
|||
} |
|||
|
|||
let processImage = async (src: string) => { |
|||
if (!src.match(/\.png$/)) |
|||
return; |
|||
let resp = getUrl(src); |
|||
let reader = resp?.getReader(); |
|||
if (!reader) |
|||
return; |
|||
return await extractTextData(reader); |
|||
}; |
|||
|
|||
/* Used for debugging */ |
|||
let processImage2 = async (src: string) => { |
|||
if (!src.match(/\.png$/)) |
|||
return; |
|||
let resp = getUrl(src); |
|||
let reader = resp.getReader(); |
|||
|
|||
let data = Buffer.alloc(0); |
|||
let chunk; |
|||
while ((chunk = await reader.read()) && !chunk.done) { |
|||
data = concatAB(data, Buffer.from(chunk.value)); |
|||
} |
|||
|
|||
return { |
|||
filename: 'aaaa', |
|||
data |
|||
}; |
|||
}; |
|||
|
|||
let processPost = async (post: HTMLDivElement) => { |
|||
let thumb = post.querySelector(".fileThumb") as HTMLAnchorElement; |
|||
if (!thumb) |
|||
return; |
|||
console.log("Processing post", post) |
|||
let res = await processImage(thumb.href); |
|||
if (!res) |
|||
return; |
|||
// add buttons
|
|||
let fi = post.querySelector(".file-info")!; |
|||
let a = document.createElement('a'); |
|||
a.className = "fa fa-eye"; |
|||
let type = await fileTypeFromBuffer(res.data); |
|||
let cont: HTMLImageElement | HTMLVideoElement; |
|||
let w: number, h: number; |
|||
if (type?.mime.startsWith("image")) { |
|||
cont = document.createElement("img"); |
|||
} else if (type?.mime.startsWith("video")) { |
|||
cont = document.createElement("video"); |
|||
} else |
|||
return; // TODO: handle new file types??? Or direct "download"?
|
|||
|
|||
cont.src = URL.createObjectURL(new Blob([res.data])); |
|||
|
|||
await new Promise(res => { |
|||
cont.onload = res; |
|||
}); |
|||
|
|||
if (cont instanceof HTMLImageElement) { |
|||
w = cont.naturalWidth; |
|||
h = cont.naturalHeight; |
|||
} |
|||
|
|||
if (cont instanceof HTMLVideoElement) { |
|||
w = cont.width; |
|||
h = cont.height; |
|||
} |
|||
|
|||
let contract = () => { |
|||
cont.style.width = "auto"; |
|||
cont.style.height = "auto"; |
|||
cont.style.maxWidth = "125px"; |
|||
cont.style.maxHeight = "125px"; |
|||
} |
|||
|
|||
let expand = () => { |
|||
cont.style.width = `${w}px`; |
|||
cont.style.height = `${h}px`; |
|||
cont.style.maxWidth = "unset"; |
|||
cont.style.maxHeight = "unset"; |
|||
} |
|||
|
|||
let imgcont = document.createElement('div'); |
|||
let p = thumb.parentElement!; |
|||
p.removeChild(thumb); |
|||
imgcont.appendChild(thumb); |
|||
p.appendChild(imgcont); |
|||
|
|||
thumb.style.display = "flex"; |
|||
thumb.style.gap = "5px"; |
|||
thumb.style.flexDirection = "column"; |
|||
a.classList.toggle("disabled"); |
|||
let contracted = true; |
|||
contract(); |
|||
cont.onclick = (e) => { |
|||
contracted = !contracted; |
|||
(contracted) ? contract() : expand(); |
|||
e.stopPropagation(); |
|||
} |
|||
|
|||
let visible = false; |
|||
a.onclick = () => { |
|||
visible = !visible; |
|||
if (visible) { |
|||
imgcont.appendChild(cont) |
|||
} else { |
|||
imgcont.removeChild(cont); |
|||
} |
|||
a.classList.toggle("disabled"); |
|||
} |
|||
fi.children[1].insertAdjacentElement('afterend', a); |
|||
} |
|||
|
|||
let buildTextChunk = async (f: File) => { |
|||
let ab = await f.arrayBuffer(); |
|||
let fns = Buffer.alloc(4); |
|||
fns.writeInt32LE(f.name.length, 0) |
|||
let fb = Buffer.from(await new Blob([fns, f.name, ab]).arrayBuffer()).toString('base64'); |
|||
let buff = Buffer.alloc(4 /*Length storage*/ + 4 /*Chunk Type*/ + 4 /*Magic*/ + 1 /*Null separator*/ + fb.length + 4 /* CRC */); |
|||
let ptr = 0; |
|||
buff.writeInt32BE(buff.byteLength - 12, ptr); // doesn't count chunk type, lenght storage and crc
|
|||
ptr += 4; |
|||
buff.write("tEXtCUM0\0", ptr); // Writes Chunktype+ Magic+null byte
|
|||
ptr += 9; |
|||
buff.write(fb, ptr); |
|||
ptr += fb.length; |
|||
// CRC over the chunk name to the last piece of data
|
|||
let checksum = buf(buff.slice(4, -4)) |
|||
buff.writeInt32BE(checksum, ptr); |
|||
return buff; |
|||
} |
|||
|
|||
let buildInjection = async (container: File, inj: File) => { |
|||
let tEXtChunk = await buildTextChunk(inj); |
|||
let ogFile = Buffer.from(await container.arrayBuffer()); |
|||
let ret = Buffer.alloc(tEXtChunk.byteLength + ogFile.byteLength); |
|||
let ptr = 8; |
|||
let wptr = 8; |
|||
let wrote = false; |
|||
ogFile.copy(ret, 0, 0, ptr);// copy PNG signature
|
|||
// copy every chunk as is except inject the text chunk before the first IDAT or END
|
|||
while (ptr < ogFile.byteLength) { |
|||
let len = ogFile.readInt32BE(ptr); |
|||
let name = ogFile.slice(ptr + 4, ptr + 8); |
|||
if (name.equals(IDAT) || name.equals(IEND)) { |
|||
if (!wrote) { |
|||
wrote = true; |
|||
tEXtChunk.copy(ret, wptr); |
|||
wptr += tEXtChunk.byteLength; |
|||
} |
|||
} |
|||
ret.writeInt32BE(len, wptr); |
|||
wptr += 4; |
|||
name.copy(ret, wptr); |
|||
wptr += 4; |
|||
ogFile.slice(ptr + 8, ptr + 8 + len + 4).copy(ret, wptr); |
|||
ptr += len + 8 + 4; |
|||
wptr += len + 4; |
|||
} |
|||
|
|||
return { file: new Blob([ret]), name: container.name }; |
|||
} |
|||
|
|||
let embedded; |
|||
|
|||
const startup = async () => { |
|||
//await Promise.all(
|
|||
|
|||
let glow = [...document.querySelectorAll('.postContainer')].find(e => e.textContent?.includes("191 KB")); |
|||
await processPost(glow as any) |
|||
|
|||
document.addEventListener('PostsInserted', <any>(async (e: CustomEvent<string>) => { |
|||
processPost(e.target as any); |
|||
})); |
|||
|
|||
let getSelectedFile = () => { |
|||
return new Promise<File>(res => { |
|||
document.addEventListener('QRFile', e => res((e as any).detail), { once: true }); |
|||
document.dispatchEvent(new CustomEvent('QRGetFile')); |
|||
}) |
|||
} |
|||
|
|||
let injected = false; |
|||
document.addEventListener('QRDialogCreation', <any>((e: CustomEvent<string>) => { |
|||
if (injected) |
|||
return; |
|||
injected = true; |
|||
let target = e.target as HTMLDivElement; |
|||
let bts = target.querySelector('#qr-filename-container') |
|||
let i = document.createElement('i'); |
|||
i.className = "fa fa-magnet"; |
|||
let a = document.createElement('a') |
|||
a.appendChild(i); |
|||
a.title = "Embed File (Select a file before...)"; |
|||
bts?.appendChild(a); |
|||
a.onclick = async (e) => { |
|||
let file = await getSelectedFile(); |
|||
if (!file) |
|||
return; |
|||
let input = document.createElement('input') as HTMLInputElement; |
|||
input.setAttribute("type", "file"); |
|||
input.onchange = (async ev => { |
|||
if (input.files) |
|||
document.dispatchEvent(new CustomEvent('QRSetFile', { detail: await buildInjection(file, input.files[0]) })) |
|||
}) |
|||
input.click(); |
|||
|
|||
} |
|||
})); |
|||
}; |
|||
|
|||
document.addEventListener('4chanXInitFinished', startup); |
@ -0,0 +1,64 @@ |
|||
{ |
|||
"compilerOptions": { |
|||
/* Visit https://aka.ms/tsconfig.json to read more about this file */ |
|||
/* Basic Options */ |
|||
// "incremental": true, /* Enable incremental compilation */ |
|||
"target": "es2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ |
|||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ |
|||
// "lib": [], /* Specify library files to be included in the compilation. */ |
|||
// "allowJs": true, /* Allow javascript files to be compiled. */ |
|||
// "checkJs": true, /* Report errors in .js files. */ |
|||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ |
|||
// "declaration": true, /* Generates corresponding '.d.ts' file. */ |
|||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ |
|||
//"sourceMap": true, /* Generates corresponding '.map' file. */ |
|||
// "outFile": "./", /* Concatenate and emit output to single file. */ |
|||
"outDir": "./dist", /* Redirect output structure to the directory. */ |
|||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ |
|||
// "composite": true, /* Enable project compilation */ |
|||
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ |
|||
// "removeComments": true, /* Do not emit comments to output. */ |
|||
// "noEmit": true, /* Do not emit outputs. */ |
|||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */ |
|||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ |
|||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ |
|||
/* Strict Type-Checking Options */ |
|||
"strict": true, /* Enable all strict type-checking options. */ |
|||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ |
|||
// "strictNullChecks": true, /* Enable strict null checks. */ |
|||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */ |
|||
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ |
|||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ |
|||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ |
|||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ |
|||
/* Additional Checks */ |
|||
// "noUnusedLocals": true, /* Report errors on unused locals. */ |
|||
// "noUnusedParameters": true, /* Report errors on unused parameters. */ |
|||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ |
|||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ |
|||
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ |
|||
// "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ |
|||
/* Module Resolution Options */ |
|||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ |
|||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ |
|||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ |
|||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ |
|||
// "typeRoots": [], /* List of folders to include type definitions from. */ |
|||
// "types": [], /* Type declaration files to be included in compilation. */ |
|||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ |
|||
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ |
|||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ |
|||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ |
|||
/* Source Map Options */ |
|||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ |
|||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ |
|||
"inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ |
|||
"inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ |
|||
/* Experimental Options */ |
|||
"experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ |
|||
"emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ |
|||
/* Advanced Options */ |
|||
"skipLibCheck": true, /* Skip type checking of declaration files. */ |
|||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ |
|||
} |
|||
} |
@ -0,0 +1,230 @@ |
|||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. |
|||
# yarn lockfile v1 |
|||
|
|||
|
|||
"@tokenizer/token@^0.3.0": |
|||
version "0.3.0" |
|||
resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" |
|||
integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== |
|||
|
|||
"@types/tampermonkey@^4.0.5": |
|||
version "4.0.5" |
|||
resolved "https://registry.yarnpkg.com/@types/tampermonkey/-/tampermonkey-4.0.5.tgz#03a0c2366a7c1fe5e1c77c88adf568f40b3c18e5" |
|||
integrity sha512-FGPo7d+qZkDF7vyrwY1WNhcUnfDyVpt2uyL7krAu3WKCUMCfIUzOuvt8aSk8N2axHT8XPr9stAEDGVHLvag6Pw== |
|||
|
|||
base64-js@^1.3.1: |
|||
version "1.5.1" |
|||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" |
|||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== |
|||
|
|||
buffer@^6.0.3: |
|||
version "6.0.3" |
|||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" |
|||
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== |
|||
dependencies: |
|||
base64-js "^1.3.1" |
|||
ieee754 "^1.2.1" |
|||
|
|||
crc-32@^1.2.0: |
|||
version "1.2.0" |
|||
resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" |
|||
integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA== |
|||
dependencies: |
|||
exit-on-epipe "~1.0.1" |
|||
printj "~1.1.0" |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.7.tgz#8c78cbb617f9f216abfb5a84cca453b51421a1b6" |
|||
integrity sha512-9/Q1NC4JErvsXzJKti0NHt+vzKjZOgPIjX/e6kkuCzgfT/GcO3FVBcGIv4HeJG7oMznE6KyKhvLrFgt7CdU2/w== |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.7.tgz#7424bdb64c104556d36b7429af79ab51415ab8f4" |
|||
integrity sha512-Z9X+3TT/Xj+JiZTVlwHj2P+8GoiSmUnGVz0YZTSt8WTbW3UKw5Pw2ucuJ8VzbD2FPy0jbIKJkko/6CMTQchShQ== |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.7.tgz#6a243dc0132aeb11c1991f968a6a9e393f43c6bc" |
|||
integrity sha512-68e7COhmwIiLXBEyxUxZSSU0akgv8t3e50e2QOtKdBUE0F6KIRISzFntLe2rYlNqSsjGWsIO6CCc9tQxijjSkw== |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.7.tgz#e7281e50522e724c4da502504dcd75be0db46c94" |
|||
integrity sha512-76zy5jAjPiXX/S3UvRgG85Bb0wy0zv/J2lel3KtHi4V7GUTBfhNUPt0E5bpSXJ6yMT7iThhnA5rOn+IJiUcslQ== |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.7.tgz#31e513098efd181d76a3ba3ea285836d37f018a3" |
|||
integrity sha512-lSlYNLiqyzd7qCN5CEOmLxn7MhnGHPcu5KuUYOG1i+t5A6q7LgBmfYC9ZHJBoYyow3u4CNu79AWHbvVLpE/VQQ== |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.7.tgz#82cf96accbf55d3007c3338dc3b3144efa9ae108" |
|||
integrity sha512-Vk28u409wVOXqTaT6ek0TnfQG4Ty1aWWfiysIaIRERkNLhzLhUf4i+qJBN8mMuGTYOkE40F0Wkbp6m+IidOp2A== |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.7.tgz#67bdfe23a6ca918a0bb8e9558a3ee0fdf98c0bc0" |
|||
integrity sha512-+Lvz6x+8OkRk3K2RtZwO+0a92jy9si9cUea5Zoru4yJ/6EQm9ENX5seZE0X9DTwk1dxJbjmLsJsd3IoowyzgVg== |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.7.tgz#f79c69ff0c176559c418de8e59aa3cf388fff992" |
|||
integrity sha512-kJd5beWSqteSAW086qzCEsH6uwpi7QRIpzYWHzEYwKKu9DiG1TwIBegQJmLpPsLp4v5RAFjea0JAmAtpGtRpqg== |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.7.tgz#3d665b35e1c27dbe1c9deb8bf956d7d1f191a21b" |
|||
integrity sha512-OzpXEBogbYdcBqE4uKynuSn5YSetCvK03Qv1HcOY1VN6HmReuatjJ21dCH+YPHSpMEF0afVCnNfffvsGEkxGJQ== |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.7.tgz#226114a0cc6649ba0ffd3428118a8f622872f16d" |
|||
integrity sha512-mFWpnDhZJmj/h7pxqn1GGDsKwRfqtV7fx6kTF5pr4PfXe8pIaTERpwcKkoCwZUkWAOmUEjMIUAvFM72A6hMZnA== |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.7.tgz#5c67ae56517f2644d567b2ca5ecb97f9520cfc49" |
|||
integrity sha512-wM7f4M0bsQXfDL4JbbYD0wsr8cC8KaQ3RPWc/fV27KdErPW7YsqshZZSjDV0kbhzwpNNdhLItfbaRT8OE8OaKA== |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.7.tgz#69dc0469ea089013956d8c6aa71c9e7fc25fc567" |
|||
integrity sha512-J/afS7woKyzGgAL5FlgvMyqgt5wQ597lgsT+xc2yJ9/7BIyezeXutXqfh05vszy2k3kSvhLesugsxIA71WsqBw== |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.7.tgz#3a9d04ecf820708e2e5b7d26fa7332e3f19f6b6c" |
|||
integrity sha512-7CcxgdlCD+zAPyveKoznbgr3i0Wnh0L8BDGRCjE/5UGkm5P/NQko51tuIDaYof8zbmXjjl0OIt9lSo4W7I8mrw== |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.7.tgz#7c33a682f0fd9565cae7df165d0e8736b7b62623" |
|||
integrity sha512-GKCafP2j/KUljVC3nesw1wLFSZktb2FGCmoT1+730zIF5O6hNroo0bSEofm6ZK5mNPnLiSaiLyRB9YFgtkd5Xg== |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.7.tgz#24ec706a5f25b4499048f56146bcff0ed3839dce" |
|||
integrity sha512-5I1GeL/gZoUUdTPA0ws54bpYdtyeA2t6MNISalsHpY269zK8Jia/AXB3ta/KcDHv2SvNwabpImeIPXC/k0YW6A== |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.7.tgz#dd6d5b5bace93cd7a9174d31fbd727ba21885abf" |
|||
integrity sha512-CIGKCFpQOSlYsLMbxt8JjxxvVw9MlF1Rz2ABLVfFyHUF5OeqHD5fPhGrCVNaVrhO8Xrm+yFmtjcZudUGr5/WYQ== |
|||
|
|||
[email protected]: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.7.tgz#ecfd9ac289606f26760c4f737caaeeadfff3cfe3" |
|||
integrity sha512-eOs1eSivOqN7cFiRIukEruWhaCf75V0N8P0zP7dh44LIhLl8y6/z++vv9qQVbkBm5/D7M7LfCfCTmt1f1wHOCw== |
|||
|
|||
esbuild@^0.14.7: |
|||
version "0.14.7" |
|||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.7.tgz#e85cead55b0e1001abf1b2ce4a11c1d4d709d13c" |
|||
integrity sha512-+u/msd6iu+HvfysUPkZ9VHm83LImmSNnecYPfFI01pQ7TTcsFR+V0BkybZX7mPtIaI7LCrse6YRj+v3eraJSgw== |
|||
optionalDependencies: |
|||
esbuild-android-arm64 "0.14.7" |
|||
esbuild-darwin-64 "0.14.7" |
|||
esbuild-darwin-arm64 "0.14.7" |
|||
esbuild-freebsd-64 "0.14.7" |
|||
esbuild-freebsd-arm64 "0.14.7" |
|||
esbuild-linux-32 "0.14.7" |
|||
esbuild-linux-64 "0.14.7" |
|||
esbuild-linux-arm "0.14.7" |
|||
esbuild-linux-arm64 "0.14.7" |
|||
esbuild-linux-mips64le "0.14.7" |
|||
esbuild-linux-ppc64le "0.14.7" |
|||
esbuild-netbsd-64 "0.14.7" |
|||
esbuild-openbsd-64 "0.14.7" |
|||
esbuild-sunos-64 "0.14.7" |
|||
esbuild-windows-32 "0.14.7" |
|||
esbuild-windows-64 "0.14.7" |
|||
esbuild-windows-arm64 "0.14.7" |
|||
|
|||
events@^3.3.0: |
|||
version "3.3.0" |
|||
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" |
|||
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== |
|||
|
|||
exit-on-epipe@~1.0.1: |
|||
version "1.0.1" |
|||
resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" |
|||
integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== |
|||
|
|||
file-type@^17.0.2: |
|||
version "17.0.2" |
|||
resolved "https://registry.yarnpkg.com/file-type/-/file-type-17.0.2.tgz#7e7564058a18aeb232b75832e5f38c6881fc7822" |
|||
integrity sha512-lrBLqujGI8O1aOsXuCuwvAu0kmU+pUNsusQNlp2Xs+8JNJm8VNGGPDwLfmtQPmnOxoIKvwk5rOEijrF0RbYHvQ== |
|||
dependencies: |
|||
readable-web-to-node-stream "^3.0.2" |
|||
strtok3 "^7.0.0-alpha.7" |
|||
token-types "^5.0.0-alpha.1" |
|||
|
|||
ieee754@^1.2.1: |
|||
version "1.2.1" |
|||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" |
|||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== |
|||
|
|||
inherits@^2.0.3: |
|||
version "2.0.4" |
|||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" |
|||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== |
|||
|
|||
peek-readable@^5.0.0-alpha.5: |
|||
version "5.0.0-alpha.5" |
|||
resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.0.0-alpha.5.tgz#ace5dfedf7bc33f17c9b5170b9d54f69a4fba79b" |
|||
integrity sha512-pJohF/tDwV3ntnT5+EkUo4E700q/j/OCDuPxtM+5/kFGjyOai/sK4/We4Cy1MB2OiTQliWU5DxPvYIKQAdPqAA== |
|||
|
|||
printj@~1.1.0: |
|||
version "1.1.2" |
|||
resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" |
|||
integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== |
|||
|
|||
readable-stream@^3.6.0: |
|||
version "3.6.0" |
|||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" |
|||
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== |
|||
dependencies: |
|||
inherits "^2.0.3" |
|||
string_decoder "^1.1.1" |
|||
util-deprecate "^1.0.1" |
|||
|
|||
readable-web-to-node-stream@^3.0.2: |
|||
version "3.0.2" |
|||
resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb" |
|||
integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw== |
|||
dependencies: |
|||
readable-stream "^3.6.0" |
|||
|
|||
safe-buffer@~5.2.0: |
|||
version "5.2.1" |
|||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" |
|||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== |
|||
|
|||
string_decoder@^1.1.1: |
|||
version "1.3.0" |
|||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" |
|||
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== |
|||
dependencies: |
|||
safe-buffer "~5.2.0" |
|||
|
|||
strtok3@^7.0.0-alpha.7: |
|||
version "7.0.0-alpha.7" |
|||
resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-7.0.0-alpha.7.tgz#631b7684ba7fc432a04846ceddd1d564b44b448e" |
|||
integrity sha512-lISXV4xwiHu4Oi0KzSod9CT3LPnJNIQueXrgVr+xCZ5avUakHxgOwEztm0buiw2pLbWBatZ48GxsoSMyuObLdQ== |
|||
dependencies: |
|||
"@tokenizer/token" "^0.3.0" |
|||
peek-readable "^5.0.0-alpha.5" |
|||
|
|||
token-types@^5.0.0-alpha.1: |
|||
version "5.0.0-alpha.2" |
|||
resolved "https://registry.yarnpkg.com/token-types/-/token-types-5.0.0-alpha.2.tgz#e43d63b2a8223a593d1c782a5149bec18f1abf97" |
|||
integrity sha512-EsG9UxAW4M6VATrEEjhPFTKEUi1OiJqTUMIZOGBN49fGxYjZB36k0p7to3HZSmWRoHm1QfZgrg3e02fpqAt5fQ== |
|||
dependencies: |
|||
"@tokenizer/token" "^0.3.0" |
|||
ieee754 "^1.2.1" |
|||
|
|||
util-deprecate@^1.0.1: |
|||
version "1.0.2" |
|||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" |
|||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= |
Loading…
Reference in new issue