diff --git a/chrome/dist/main.js b/chrome/dist/main.js index 02ef6f9..57b1a37 100644 --- a/chrome/dist/main.js +++ b/chrome/dist/main.js @@ -51,7 +51,7 @@ var define_BUILD_VERSION_default; var init_define_BUILD_VERSION = __esm({ ""() { - define_BUILD_VERSION_default = [0, 268]; + define_BUILD_VERSION_default = [0, 270]; } }); @@ -5213,6 +5213,151 @@ } }); + // node_modules/base-x/src/index.js + var require_src = __commonJS({ + "node_modules/base-x/src/index.js"(exports, module) { + "use strict"; + init_define_BUILD_VERSION(); + init_esbuild_inject(); + function base(ALPHABET) { + if (ALPHABET.length >= 255) { + throw new TypeError("Alphabet too long"); + } + var BASE_MAP = new Uint8Array(256); + for (var j = 0; j < BASE_MAP.length; j++) { + BASE_MAP[j] = 255; + } + for (var i = 0; i < ALPHABET.length; i++) { + var x = ALPHABET.charAt(i); + var xc = x.charCodeAt(0); + if (BASE_MAP[xc] !== 255) { + throw new TypeError(x + " is ambiguous"); + } + BASE_MAP[xc] = i; + } + var BASE = ALPHABET.length; + var LEADER = ALPHABET.charAt(0); + var FACTOR = Math.log(BASE) / Math.log(256); + var iFACTOR = Math.log(256) / Math.log(BASE); + function encode2(source) { + if (source instanceof Uint8Array) { + } else if (ArrayBuffer.isView(source)) { + source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + } else if (Array.isArray(source)) { + source = Uint8Array.from(source); + } + if (!(source instanceof Uint8Array)) { + throw new TypeError("Expected Uint8Array"); + } + if (source.length === 0) { + return ""; + } + var zeroes = 0; + var length = 0; + var pbegin = 0; + var pend = source.length; + while (pbegin !== pend && source[pbegin] === 0) { + pbegin++; + zeroes++; + } + var size = (pend - pbegin) * iFACTOR + 1 >>> 0; + var b58 = new Uint8Array(size); + while (pbegin !== pend) { + var carry = source[pbegin]; + var i2 = 0; + for (var it1 = size - 1; (carry !== 0 || i2 < length) && it1 !== -1; it1--, i2++) { + carry += 256 * b58[it1] >>> 0; + b58[it1] = carry % BASE >>> 0; + carry = carry / BASE >>> 0; + } + if (carry !== 0) { + throw new Error("Non-zero carry"); + } + length = i2; + pbegin++; + } + var it2 = size - length; + while (it2 !== size && b58[it2] === 0) { + it2++; + } + var str = LEADER.repeat(zeroes); + for (; it2 < size; ++it2) { + str += ALPHABET.charAt(b58[it2]); + } + return str; + } + function decodeUnsafe(source) { + if (typeof source !== "string") { + throw new TypeError("Expected String"); + } + if (source.length === 0) { + return new Uint8Array(); + } + var psz = 0; + var zeroes = 0; + var length = 0; + while (source[psz] === LEADER) { + zeroes++; + psz++; + } + var size = (source.length - psz) * FACTOR + 1 >>> 0; + var b256 = new Uint8Array(size); + while (source[psz]) { + var carry = BASE_MAP[source.charCodeAt(psz)]; + if (carry === 255) { + return; + } + var i2 = 0; + for (var it3 = size - 1; (carry !== 0 || i2 < length) && it3 !== -1; it3--, i2++) { + carry += BASE * b256[it3] >>> 0; + b256[it3] = carry % 256 >>> 0; + carry = carry / 256 >>> 0; + } + if (carry !== 0) { + throw new Error("Non-zero carry"); + } + length = i2; + psz++; + } + var it4 = size - length; + while (it4 !== size && b256[it4] === 0) { + it4++; + } + var vch = new Uint8Array(zeroes + (size - it4)); + var j2 = zeroes; + while (it4 !== size) { + vch[j2++] = b256[it4++]; + } + return vch; + } + function decode3(string) { + var buffer = decodeUnsafe(string); + if (buffer) { + return buffer; + } + throw new Error("Non-base" + BASE + " character"); + } + return { + encode: encode2, + decodeUnsafe, + decode: decode3 + }; + } + module.exports = base; + } + }); + + // node_modules/bs58/index.js + var require_bs58 = __commonJS({ + "node_modules/bs58/index.js"(exports, module) { + init_define_BUILD_VERSION(); + init_esbuild_inject(); + var basex = require_src(); + var ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + module.exports = basex(ALPHABET); + } + }); + // node_modules/int64-buffer/int64-buffer.js var require_int64_buffer = __commonJS({ "node_modules/int64-buffer/int64-buffer.js"(exports) { @@ -13476,12 +13621,12 @@ init5(); } if (typeof module !== "undefined") { - module.exports = encode; + module.exports = encode2; } else if (typeof window !== "undefined") { window["jpeg-js"] = window["jpeg-js"] || {}; - window["jpeg-js"].encode = encode; + window["jpeg-js"].encode = encode2; } - function encode(imgData, qu) { + function encode2(imgData, qu) { if (typeof qu === "undefined") qu = 50; var encoder = new JPEGEncoder(qu); @@ -13769,21 +13914,21 @@ successiveACState = 0; } } - function decodeMcu(component2, decode3, mcu2, row, col) { + function decodeMcu(component2, decode4, mcu2, row, col) { var mcuRow = mcu2 / mcusPerLine | 0; var mcuCol = mcu2 % mcusPerLine; var blockRow = mcuRow * component2.v + row; var blockCol = mcuCol * component2.h + col; if (component2.blocks[blockRow] === void 0 && opts.tolerantDecoding) return; - decode3(component2, component2.blocks[blockRow][blockCol]); + decode4(component2, component2.blocks[blockRow][blockCol]); } - function decodeBlock(component2, decode3, mcu2) { + function decodeBlock(component2, decode4, mcu2) { var blockRow = mcu2 / component2.blocksPerLine | 0; var blockCol = mcu2 % component2.blocksPerLine; if (component2.blocks[blockRow] === void 0 && opts.tolerantDecoding) return; - decode3(component2, component2.blocks[blockRow][blockCol]); + decode4(component2, component2.blocks[blockRow][blockCol]); } var componentsLength = components.length; var component, i, j, k, n; @@ -14481,12 +14626,12 @@ return constructor; }(); if (typeof module !== "undefined") { - module.exports = decode2; + module.exports = decode3; } else if (typeof window !== "undefined") { window["jpeg-js"] = window["jpeg-js"] || {}; - window["jpeg-js"].decode = decode2; + window["jpeg-js"].decode = decode3; } - function decode2(jpegData, userOpts = {}) { + function decode3(jpegData, userOpts = {}) { var defaultOpts = { colorTransform: void 0, useTArray: false, @@ -14536,11 +14681,11 @@ "node_modules/jpeg-js/index.js"(exports, module) { init_define_BUILD_VERSION(); init_esbuild_inject(); - var encode = require_encoder(); - var decode2 = require_decoder(); + var encode2 = require_encoder(); + var decode3 = require_decoder(); module.exports = { - encode, - decode: decode2 + encode: encode2, + decode: decode3 }; } }); @@ -18231,6 +18376,7 @@ }; // src/pngv3.ts + var bs58 = __toESM(require_bs58(), 1); var csettings2; settings.subscribe((b) => { csettings2 = b; @@ -18303,15 +18449,21 @@ const passed = buff.slice(4 + w.length); if (!passed.toString().match(/^[0-9a-zA-Z+/=]+$/g)) continue; - try { - const decoded = import_buffer3.Buffer.from(passed.toString(), "base64").toString().split(" ").map((e) => { - if (!(e[0] in rprefs)) - throw "Uhh"; - return `https://${rprefs[e[0]]}/${e.slice(1)}`; - }).join(" "); - const k = await decodeCoom3Payload(import_buffer3.Buffer.from(decoded)); - ret.push(...k.filter((e) => e).map((e) => e)); - } finally { + const decoders = [ + (b) => import_buffer3.Buffer.from(b.toString(), "base64").toString(), + (b) => import_buffer3.Buffer.from(bs58.decode(passed.toString())).toString() + ]; + for (const d of decoders) { + try { + const decoded = d(passed).split(" ").map((e) => { + if (!(e[0] in rprefs)) + throw "Uhh"; + return `https://${rprefs[e[0]]}/${e.slice(1)}`; + }).join(" "); + const k = await decodeCoom3Payload(import_buffer3.Buffer.from(decoded)); + ret.push(...k.filter((e) => e).map((e) => e)); + } catch (e) { + } } } break; @@ -18376,7 +18528,7 @@ } return ""; }); - const injb = import_buffer3.Buffer.from(import_buffer3.Buffer.from(links.join(" ")).toString("base64")); + const injb = import_buffer3.Buffer.from(bs58.encode(import_buffer3.Buffer.from(links.join(" ")))); return inject_data(container, injb); }; var has_embed = async (png) => { @@ -18406,6 +18558,8 @@ if (passed.match(/^[0-9a-zA-Z+/=]+$/g)) { if (import_buffer3.Buffer.from(passed, "base64").toString().split(" ").every((l) => l[0] in rprefs)) return true; + if (import_buffer3.Buffer.from(bs58.decode(passed)).toString().split(" ").every((l) => l[0] in rprefs)) + return true; } } break; @@ -18759,7 +18913,7 @@ var injectTrue = async (b, links) => { if (b.size / 20 < links.join(" ").length) throw "Image too small to embed."; - const arr = new Uint8Array(await b.arrayBuffer()); + const arr = new Uint8Array(new Uint8Array(await b.arrayBuffer())); const buff = f5inst.embed(arr, new TextEncoder().encode(links.join(" "))); return import_buffer6.Buffer.from(buff); }; @@ -21072,7 +21226,7 @@ // src/Components/App.svelte function add_css8(target) { - append_styles(target, "svelte-2r0xqp", '.bepis.svelte-2r0xqp.svelte-2r0xqp{max-height:260px;overflow-y:auto}.tagcont.svelte-2r0xqp.svelte-2r0xqp{display:flex;gap:5px;margin-bottom:10px;flex-wrap:wrap}label.svelte-2r0xqp>input[type="text"].svelte-2r0xqp,label.svelte-2r0xqp>input[type="number"].svelte-2r0xqp{width:95%}.content.svelte-2r0xqp.svelte-2r0xqp{display:flex;flex-direction:column}.error.svelte-2r0xqp.svelte-2r0xqp{color:red}hr.svelte-2r0xqp.svelte-2r0xqp{width:100%}h1.svelte-2r0xqp.svelte-2r0xqp{text-align:center}.form.svelte-2r0xqp.svelte-2r0xqp{display:flex;flex-direction:column;gap:20px;position:absolute;padding:15px;border:1px solid white;background-color:black;border-radius:10px}.form.svelte-2r0xqp>label.svelte-2r0xqp{display:flex;flex-direction:column;gap:10px}.newsbox.svelte-2r0xqp.svelte-2r0xqp{max-height:300px;overflow-y:scroll}.backpanel.svelte-2r0xqp.svelte-2r0xqp{position:absolute;right:32px;padding:10px;width:15%;top:32px;border:1px solid;border-radius:5px;background-color:rgba(0, 0, 0, 0.8);pointer-events:all;backdrop-filter:blur(9px);max-height:80vh;min-width:321px}'); + append_styles(target, "svelte-1d9zqg3", '.bepis.svelte-1d9zqg3.svelte-1d9zqg3{max-height:260px;overflow-y:auto}.tagcont.svelte-1d9zqg3.svelte-1d9zqg3{display:flex;gap:5px;margin-bottom:10px;flex-wrap:wrap}label.svelte-1d9zqg3>input[type="text"].svelte-1d9zqg3,label.svelte-1d9zqg3>input[type="number"].svelte-1d9zqg3{width:95%}.content.svelte-1d9zqg3.svelte-1d9zqg3{display:flex;flex-direction:column}.error.svelte-1d9zqg3.svelte-1d9zqg3{color:red}hr.svelte-1d9zqg3.svelte-1d9zqg3{width:100%}h1.svelte-1d9zqg3.svelte-1d9zqg3{text-align:center;margin-bottom:0}h4.svelte-1d9zqg3.svelte-1d9zqg3{margin:0}.form.svelte-1d9zqg3.svelte-1d9zqg3{display:flex;flex-direction:column;gap:20px;position:absolute;padding:15px;border:1px solid white;background-color:black;border-radius:10px}.form.svelte-1d9zqg3>label.svelte-1d9zqg3{display:flex;flex-direction:column;gap:10px}.newsbox.svelte-1d9zqg3.svelte-1d9zqg3{max-height:300px;overflow-y:scroll}.backpanel.svelte-1d9zqg3.svelte-1d9zqg3{position:absolute;right:32px;padding:10px;width:15%;top:32px;border:1px solid;border-radius:5px;background-color:rgba(0, 0, 0, 0.8);pointer-events:all;backdrop-filter:blur(9px);max-height:80vh;min-width:321px}'); } function get_each_context2(ctx, list, i) { const child_ctx = ctx.slice(); @@ -21109,8 +21263,10 @@ let t0; let t1; let t2; + let h4; + let t4; let hr; - let t3; + let t5; let tabs; let div1_transition; let current; @@ -21128,13 +21284,17 @@ t0 = text("PEE Settings 0."); t1 = text(ctx[0]); t2 = space(); + h4 = element("h4"); + h4.innerHTML = `Join us on 2chen!`; + t4 = space(); hr = element("hr"); - t3 = space(); + t5 = space(); create_component(tabs.$$.fragment); - attr(h1, "class", "svelte-2r0xqp"); - attr(hr, "class", "svelte-2r0xqp"); - attr(div0, "class", "content svelte-2r0xqp"); - attr(div1, "class", "backpanel svelte-2r0xqp"); + attr(h1, "class", "svelte-1d9zqg3"); + attr(h4, "class", "svelte-1d9zqg3"); + attr(hr, "class", "svelte-1d9zqg3"); + attr(div0, "class", "content svelte-1d9zqg3"); + attr(div1, "class", "backpanel svelte-1d9zqg3"); }, m(target, anchor) { insert(target, div1, anchor); @@ -21143,8 +21303,10 @@ append(h1, t0); append(h1, t1); append(div0, t2); + append(div0, h4); + append(div0, t4); append(div0, hr); - append(div0, t3); + append(div0, t5); mount_component(tabs, div0, null); current = true; }, @@ -21538,8 +21700,8 @@ if_block1_anchor = empty(); attr(a, "title", "Only requires Search Files permission. See Hydrus docs on where to set this up."); attr(input, "type", "text"); - attr(input, "class", "svelte-2r0xqp"); - attr(label, "class", "svelte-2r0xqp"); + attr(input, "class", "svelte-1d9zqg3"); + attr(label, "class", "svelte-1d9zqg3"); }, m(target, anchor) { if (if_block0) @@ -21615,7 +21777,7 @@ c() { span = element("span"); t = text(t_value); - attr(span, "class", "error svelte-2r0xqp"); + attr(span, "class", "error svelte-1d9zqg3"); }, m(target, anchor) { insert(target, span, anchor); @@ -21652,12 +21814,12 @@ input1 = element("input"); set_style(input0, "width", "5ch"); attr(input0, "type", "number"); - attr(input0, "class", "svelte-2r0xqp"); - attr(label0, "class", "svelte-2r0xqp"); + attr(input0, "class", "svelte-1d9zqg3"); + attr(label0, "class", "svelte-1d9zqg3"); attr(input1, "placeholder", "Restrict to these tags (space to separate tags, _ to separate words)"); attr(input1, "type", "text"); - attr(input1, "class", "svelte-2r0xqp"); - attr(label1, "class", "svelte-2r0xqp"); + attr(input1, "class", "svelte-1d9zqg3"); + attr(label1, "class", "svelte-1d9zqg3"); }, m(target, anchor) { insert(target, label0, anchor); @@ -22214,9 +22376,9 @@ t13 = space(); input1 = element("input"); attr(input0, "type", "checkbox"); - attr(div0, "class", "tagcont svelte-2r0xqp"); - attr(hr, "class", "svelte-2r0xqp"); - attr(div1, "class", "tagcont svelte-2r0xqp"); + attr(div0, "class", "tagcont svelte-1d9zqg3"); + attr(hr, "class", "svelte-1d9zqg3"); + attr(div1, "class", "tagcont svelte-1d9zqg3"); attr(input1, "placeholder", "Press enter after typing your tag"); }, m(target, anchor) { @@ -22426,9 +22588,9 @@ a = element("a"); a.textContent = "?"; attr(input, "type", "number"); - attr(input, "class", "svelte-2r0xqp"); + attr(input, "class", "svelte-1d9zqg3"); attr(a, "title", "Higher will filter more potentially different images, lower will let more identical images through"); - attr(label, "class", "svelte-2r0xqp"); + attr(label, "class", "svelte-1d9zqg3"); }, m(target, anchor) { insert(target, label, anchor); @@ -22567,21 +22729,21 @@ button.textContent = "Add"; attr(input0, "type", "text"); attr(input0, "placeholder", "Safebooru"); - attr(input0, "class", "svelte-2r0xqp"); - attr(label0, "class", "svelte-2r0xqp"); + attr(input0, "class", "svelte-1d9zqg3"); + attr(label0, "class", "svelte-1d9zqg3"); attr(input1, "type", "text"); attr(input1, "placeholder", "safebooru.com"); - attr(input1, "class", "svelte-2r0xqp"); - attr(label1, "class", "svelte-2r0xqp"); + attr(input1, "class", "svelte-1d9zqg3"); + attr(label1, "class", "svelte-1d9zqg3"); attr(input2, "type", "text"); attr(input2, "placeholder", "/post.json?tags=md5:"); - attr(input2, "class", "svelte-2r0xqp"); - attr(label2, "class", "svelte-2r0xqp"); + attr(input2, "class", "svelte-1d9zqg3"); + attr(label2, "class", "svelte-1d9zqg3"); attr(input3, "type", "text"); attr(input3, "placeholder", "https://safebooru.com/post/show/"); - attr(input3, "class", "svelte-2r0xqp"); - attr(label3, "class", "svelte-2r0xqp"); - attr(div, "class", "form svelte-2r0xqp"); + attr(input3, "class", "svelte-1d9zqg3"); + attr(label3, "class", "svelte-1d9zqg3"); + attr(div, "class", "form svelte-1d9zqg3"); }, m(target, anchor) { insert(target, div, anchor); @@ -22815,8 +22977,8 @@ if (ctx[7].fhost === void 0) add_render_callback(() => ctx[54].call(select)); attr(input, "type", "number"); - attr(input, "class", "svelte-2r0xqp"); - attr(label, "class", "svelte-2r0xqp"); + attr(input, "class", "svelte-1d9zqg3"); + attr(label, "class", "svelte-1d9zqg3"); }, m(target, anchor) { insert(target, p, anchor); @@ -22917,7 +23079,7 @@ for (let i = 0; i < each_blocks.length; i += 1) { each_blocks[i].c(); } - attr(div, "class", "bepis svelte-2r0xqp"); + attr(div, "class", "bepis svelte-1d9zqg3"); }, m(target, anchor) { insert(target, div, anchor); @@ -23205,7 +23367,7 @@ t2 = space(); div = element("div"); if_block.c(); - attr(div, "class", "newsbox svelte-2r0xqp"); + attr(div, "class", "newsbox svelte-1d9zqg3"); }, m(target, anchor) { insert(target, p, anchor); diff --git a/chrome/manifest.json b/chrome/manifest.json index c3fe106..2685137 100644 --- a/chrome/manifest.json +++ b/chrome/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 3, "name": "PngExtraEmbedder", "description": "Discover embedded files on 4chan and archives!", - "version": "0.268", + "version": "0.270", "icons": { "64": "1449696017588.png" }, diff --git a/dist/main.js b/dist/main.js index bb9fb44..c389348 100644 --- a/dist/main.js +++ b/dist/main.js @@ -51,7 +51,7 @@ var define_BUILD_VERSION_default; var init_define_BUILD_VERSION = __esm({ ""() { - define_BUILD_VERSION_default = [0, 268]; + define_BUILD_VERSION_default = [0, 270]; } }); @@ -5213,6 +5213,151 @@ } }); + // node_modules/base-x/src/index.js + var require_src = __commonJS({ + "node_modules/base-x/src/index.js"(exports, module) { + "use strict"; + init_define_BUILD_VERSION(); + init_esbuild_inject(); + function base(ALPHABET) { + if (ALPHABET.length >= 255) { + throw new TypeError("Alphabet too long"); + } + var BASE_MAP = new Uint8Array(256); + for (var j = 0; j < BASE_MAP.length; j++) { + BASE_MAP[j] = 255; + } + for (var i = 0; i < ALPHABET.length; i++) { + var x = ALPHABET.charAt(i); + var xc = x.charCodeAt(0); + if (BASE_MAP[xc] !== 255) { + throw new TypeError(x + " is ambiguous"); + } + BASE_MAP[xc] = i; + } + var BASE = ALPHABET.length; + var LEADER = ALPHABET.charAt(0); + var FACTOR = Math.log(BASE) / Math.log(256); + var iFACTOR = Math.log(256) / Math.log(BASE); + function encode2(source) { + if (source instanceof Uint8Array) { + } else if (ArrayBuffer.isView(source)) { + source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + } else if (Array.isArray(source)) { + source = Uint8Array.from(source); + } + if (!(source instanceof Uint8Array)) { + throw new TypeError("Expected Uint8Array"); + } + if (source.length === 0) { + return ""; + } + var zeroes = 0; + var length = 0; + var pbegin = 0; + var pend = source.length; + while (pbegin !== pend && source[pbegin] === 0) { + pbegin++; + zeroes++; + } + var size = (pend - pbegin) * iFACTOR + 1 >>> 0; + var b58 = new Uint8Array(size); + while (pbegin !== pend) { + var carry = source[pbegin]; + var i2 = 0; + for (var it1 = size - 1; (carry !== 0 || i2 < length) && it1 !== -1; it1--, i2++) { + carry += 256 * b58[it1] >>> 0; + b58[it1] = carry % BASE >>> 0; + carry = carry / BASE >>> 0; + } + if (carry !== 0) { + throw new Error("Non-zero carry"); + } + length = i2; + pbegin++; + } + var it2 = size - length; + while (it2 !== size && b58[it2] === 0) { + it2++; + } + var str = LEADER.repeat(zeroes); + for (; it2 < size; ++it2) { + str += ALPHABET.charAt(b58[it2]); + } + return str; + } + function decodeUnsafe(source) { + if (typeof source !== "string") { + throw new TypeError("Expected String"); + } + if (source.length === 0) { + return new Uint8Array(); + } + var psz = 0; + var zeroes = 0; + var length = 0; + while (source[psz] === LEADER) { + zeroes++; + psz++; + } + var size = (source.length - psz) * FACTOR + 1 >>> 0; + var b256 = new Uint8Array(size); + while (source[psz]) { + var carry = BASE_MAP[source.charCodeAt(psz)]; + if (carry === 255) { + return; + } + var i2 = 0; + for (var it3 = size - 1; (carry !== 0 || i2 < length) && it3 !== -1; it3--, i2++) { + carry += BASE * b256[it3] >>> 0; + b256[it3] = carry % 256 >>> 0; + carry = carry / 256 >>> 0; + } + if (carry !== 0) { + throw new Error("Non-zero carry"); + } + length = i2; + psz++; + } + var it4 = size - length; + while (it4 !== size && b256[it4] === 0) { + it4++; + } + var vch = new Uint8Array(zeroes + (size - it4)); + var j2 = zeroes; + while (it4 !== size) { + vch[j2++] = b256[it4++]; + } + return vch; + } + function decode3(string) { + var buffer = decodeUnsafe(string); + if (buffer) { + return buffer; + } + throw new Error("Non-base" + BASE + " character"); + } + return { + encode: encode2, + decodeUnsafe, + decode: decode3 + }; + } + module.exports = base; + } + }); + + // node_modules/bs58/index.js + var require_bs58 = __commonJS({ + "node_modules/bs58/index.js"(exports, module) { + init_define_BUILD_VERSION(); + init_esbuild_inject(); + var basex = require_src(); + var ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + module.exports = basex(ALPHABET); + } + }); + // node_modules/int64-buffer/int64-buffer.js var require_int64_buffer = __commonJS({ "node_modules/int64-buffer/int64-buffer.js"(exports) { @@ -13476,12 +13621,12 @@ init5(); } if (typeof module !== "undefined") { - module.exports = encode; + module.exports = encode2; } else if (typeof window !== "undefined") { window["jpeg-js"] = window["jpeg-js"] || {}; - window["jpeg-js"].encode = encode; + window["jpeg-js"].encode = encode2; } - function encode(imgData, qu) { + function encode2(imgData, qu) { if (typeof qu === "undefined") qu = 50; var encoder = new JPEGEncoder(qu); @@ -13769,21 +13914,21 @@ successiveACState = 0; } } - function decodeMcu(component2, decode3, mcu2, row, col) { + function decodeMcu(component2, decode4, mcu2, row, col) { var mcuRow = mcu2 / mcusPerLine | 0; var mcuCol = mcu2 % mcusPerLine; var blockRow = mcuRow * component2.v + row; var blockCol = mcuCol * component2.h + col; if (component2.blocks[blockRow] === void 0 && opts.tolerantDecoding) return; - decode3(component2, component2.blocks[blockRow][blockCol]); + decode4(component2, component2.blocks[blockRow][blockCol]); } - function decodeBlock(component2, decode3, mcu2) { + function decodeBlock(component2, decode4, mcu2) { var blockRow = mcu2 / component2.blocksPerLine | 0; var blockCol = mcu2 % component2.blocksPerLine; if (component2.blocks[blockRow] === void 0 && opts.tolerantDecoding) return; - decode3(component2, component2.blocks[blockRow][blockCol]); + decode4(component2, component2.blocks[blockRow][blockCol]); } var componentsLength = components.length; var component, i, j, k, n; @@ -14481,12 +14626,12 @@ return constructor; }(); if (typeof module !== "undefined") { - module.exports = decode2; + module.exports = decode3; } else if (typeof window !== "undefined") { window["jpeg-js"] = window["jpeg-js"] || {}; - window["jpeg-js"].decode = decode2; + window["jpeg-js"].decode = decode3; } - function decode2(jpegData, userOpts = {}) { + function decode3(jpegData, userOpts = {}) { var defaultOpts = { colorTransform: void 0, useTArray: false, @@ -14536,11 +14681,11 @@ "node_modules/jpeg-js/index.js"(exports, module) { init_define_BUILD_VERSION(); init_esbuild_inject(); - var encode = require_encoder(); - var decode2 = require_decoder(); + var encode2 = require_encoder(); + var decode3 = require_decoder(); module.exports = { - encode, - decode: decode2 + encode: encode2, + decode: decode3 }; } }); @@ -18066,6 +18211,7 @@ }; // src/pngv3.ts + var bs58 = __toESM(require_bs58(), 1); var csettings2; settings.subscribe((b) => { csettings2 = b; @@ -18138,15 +18284,21 @@ const passed = buff.slice(4 + w.length); if (!passed.toString().match(/^[0-9a-zA-Z+/=]+$/g)) continue; - try { - const decoded = import_buffer3.Buffer.from(passed.toString(), "base64").toString().split(" ").map((e) => { - if (!(e[0] in rprefs)) - throw "Uhh"; - return `https://${rprefs[e[0]]}/${e.slice(1)}`; - }).join(" "); - const k = await decodeCoom3Payload(import_buffer3.Buffer.from(decoded)); - ret.push(...k.filter((e) => e).map((e) => e)); - } finally { + const decoders = [ + (b) => import_buffer3.Buffer.from(b.toString(), "base64").toString(), + (b) => import_buffer3.Buffer.from(bs58.decode(passed.toString())).toString() + ]; + for (const d of decoders) { + try { + const decoded = d(passed).split(" ").map((e) => { + if (!(e[0] in rprefs)) + throw "Uhh"; + return `https://${rprefs[e[0]]}/${e.slice(1)}`; + }).join(" "); + const k = await decodeCoom3Payload(import_buffer3.Buffer.from(decoded)); + ret.push(...k.filter((e) => e).map((e) => e)); + } catch (e) { + } } } break; @@ -18211,7 +18363,7 @@ } return ""; }); - const injb = import_buffer3.Buffer.from(import_buffer3.Buffer.from(links.join(" ")).toString("base64")); + const injb = import_buffer3.Buffer.from(bs58.encode(import_buffer3.Buffer.from(links.join(" ")))); return inject_data(container, injb); }; var has_embed = async (png) => { @@ -18241,6 +18393,8 @@ if (passed.match(/^[0-9a-zA-Z+/=]+$/g)) { if (import_buffer3.Buffer.from(passed, "base64").toString().split(" ").every((l) => l[0] in rprefs)) return true; + if (import_buffer3.Buffer.from(bs58.decode(passed)).toString().split(" ").every((l) => l[0] in rprefs)) + return true; } } break; @@ -18594,7 +18748,7 @@ var injectTrue = async (b, links) => { if (b.size / 20 < links.join(" ").length) throw "Image too small to embed."; - const arr = new Uint8Array(await b.arrayBuffer()); + const arr = new Uint8Array(new Uint8Array(await b.arrayBuffer())); const buff = f5inst.embed(arr, new TextEncoder().encode(links.join(" "))); return import_buffer6.Buffer.from(buff); }; @@ -20907,7 +21061,7 @@ // src/Components/App.svelte function add_css8(target) { - append_styles(target, "svelte-2r0xqp", '.bepis.svelte-2r0xqp.svelte-2r0xqp{max-height:260px;overflow-y:auto}.tagcont.svelte-2r0xqp.svelte-2r0xqp{display:flex;gap:5px;margin-bottom:10px;flex-wrap:wrap}label.svelte-2r0xqp>input[type="text"].svelte-2r0xqp,label.svelte-2r0xqp>input[type="number"].svelte-2r0xqp{width:95%}.content.svelte-2r0xqp.svelte-2r0xqp{display:flex;flex-direction:column}.error.svelte-2r0xqp.svelte-2r0xqp{color:red}hr.svelte-2r0xqp.svelte-2r0xqp{width:100%}h1.svelte-2r0xqp.svelte-2r0xqp{text-align:center}.form.svelte-2r0xqp.svelte-2r0xqp{display:flex;flex-direction:column;gap:20px;position:absolute;padding:15px;border:1px solid white;background-color:black;border-radius:10px}.form.svelte-2r0xqp>label.svelte-2r0xqp{display:flex;flex-direction:column;gap:10px}.newsbox.svelte-2r0xqp.svelte-2r0xqp{max-height:300px;overflow-y:scroll}.backpanel.svelte-2r0xqp.svelte-2r0xqp{position:absolute;right:32px;padding:10px;width:15%;top:32px;border:1px solid;border-radius:5px;background-color:rgba(0, 0, 0, 0.8);pointer-events:all;backdrop-filter:blur(9px);max-height:80vh;min-width:321px}'); + append_styles(target, "svelte-1d9zqg3", '.bepis.svelte-1d9zqg3.svelte-1d9zqg3{max-height:260px;overflow-y:auto}.tagcont.svelte-1d9zqg3.svelte-1d9zqg3{display:flex;gap:5px;margin-bottom:10px;flex-wrap:wrap}label.svelte-1d9zqg3>input[type="text"].svelte-1d9zqg3,label.svelte-1d9zqg3>input[type="number"].svelte-1d9zqg3{width:95%}.content.svelte-1d9zqg3.svelte-1d9zqg3{display:flex;flex-direction:column}.error.svelte-1d9zqg3.svelte-1d9zqg3{color:red}hr.svelte-1d9zqg3.svelte-1d9zqg3{width:100%}h1.svelte-1d9zqg3.svelte-1d9zqg3{text-align:center;margin-bottom:0}h4.svelte-1d9zqg3.svelte-1d9zqg3{margin:0}.form.svelte-1d9zqg3.svelte-1d9zqg3{display:flex;flex-direction:column;gap:20px;position:absolute;padding:15px;border:1px solid white;background-color:black;border-radius:10px}.form.svelte-1d9zqg3>label.svelte-1d9zqg3{display:flex;flex-direction:column;gap:10px}.newsbox.svelte-1d9zqg3.svelte-1d9zqg3{max-height:300px;overflow-y:scroll}.backpanel.svelte-1d9zqg3.svelte-1d9zqg3{position:absolute;right:32px;padding:10px;width:15%;top:32px;border:1px solid;border-radius:5px;background-color:rgba(0, 0, 0, 0.8);pointer-events:all;backdrop-filter:blur(9px);max-height:80vh;min-width:321px}'); } function get_each_context2(ctx, list, i) { const child_ctx = ctx.slice(); @@ -20944,8 +21098,10 @@ let t0; let t1; let t2; + let h4; + let t4; let hr; - let t3; + let t5; let tabs; let div1_transition; let current; @@ -20963,13 +21119,17 @@ t0 = text("PEE Settings 0."); t1 = text(ctx[0]); t2 = space(); + h4 = element("h4"); + h4.innerHTML = `Join us on 2chen!`; + t4 = space(); hr = element("hr"); - t3 = space(); + t5 = space(); create_component(tabs.$$.fragment); - attr(h1, "class", "svelte-2r0xqp"); - attr(hr, "class", "svelte-2r0xqp"); - attr(div0, "class", "content svelte-2r0xqp"); - attr(div1, "class", "backpanel svelte-2r0xqp"); + attr(h1, "class", "svelte-1d9zqg3"); + attr(h4, "class", "svelte-1d9zqg3"); + attr(hr, "class", "svelte-1d9zqg3"); + attr(div0, "class", "content svelte-1d9zqg3"); + attr(div1, "class", "backpanel svelte-1d9zqg3"); }, m(target, anchor) { insert(target, div1, anchor); @@ -20978,8 +21138,10 @@ append(h1, t0); append(h1, t1); append(div0, t2); + append(div0, h4); + append(div0, t4); append(div0, hr); - append(div0, t3); + append(div0, t5); mount_component(tabs, div0, null); current = true; }, @@ -21373,8 +21535,8 @@ if_block1_anchor = empty(); attr(a, "title", "Only requires Search Files permission. See Hydrus docs on where to set this up."); attr(input, "type", "text"); - attr(input, "class", "svelte-2r0xqp"); - attr(label, "class", "svelte-2r0xqp"); + attr(input, "class", "svelte-1d9zqg3"); + attr(label, "class", "svelte-1d9zqg3"); }, m(target, anchor) { if (if_block0) @@ -21450,7 +21612,7 @@ c() { span = element("span"); t = text(t_value); - attr(span, "class", "error svelte-2r0xqp"); + attr(span, "class", "error svelte-1d9zqg3"); }, m(target, anchor) { insert(target, span, anchor); @@ -21487,12 +21649,12 @@ input1 = element("input"); set_style(input0, "width", "5ch"); attr(input0, "type", "number"); - attr(input0, "class", "svelte-2r0xqp"); - attr(label0, "class", "svelte-2r0xqp"); + attr(input0, "class", "svelte-1d9zqg3"); + attr(label0, "class", "svelte-1d9zqg3"); attr(input1, "placeholder", "Restrict to these tags (space to separate tags, _ to separate words)"); attr(input1, "type", "text"); - attr(input1, "class", "svelte-2r0xqp"); - attr(label1, "class", "svelte-2r0xqp"); + attr(input1, "class", "svelte-1d9zqg3"); + attr(label1, "class", "svelte-1d9zqg3"); }, m(target, anchor) { insert(target, label0, anchor); @@ -22049,9 +22211,9 @@ t13 = space(); input1 = element("input"); attr(input0, "type", "checkbox"); - attr(div0, "class", "tagcont svelte-2r0xqp"); - attr(hr, "class", "svelte-2r0xqp"); - attr(div1, "class", "tagcont svelte-2r0xqp"); + attr(div0, "class", "tagcont svelte-1d9zqg3"); + attr(hr, "class", "svelte-1d9zqg3"); + attr(div1, "class", "tagcont svelte-1d9zqg3"); attr(input1, "placeholder", "Press enter after typing your tag"); }, m(target, anchor) { @@ -22261,9 +22423,9 @@ a = element("a"); a.textContent = "?"; attr(input, "type", "number"); - attr(input, "class", "svelte-2r0xqp"); + attr(input, "class", "svelte-1d9zqg3"); attr(a, "title", "Higher will filter more potentially different images, lower will let more identical images through"); - attr(label, "class", "svelte-2r0xqp"); + attr(label, "class", "svelte-1d9zqg3"); }, m(target, anchor) { insert(target, label, anchor); @@ -22402,21 +22564,21 @@ button.textContent = "Add"; attr(input0, "type", "text"); attr(input0, "placeholder", "Safebooru"); - attr(input0, "class", "svelte-2r0xqp"); - attr(label0, "class", "svelte-2r0xqp"); + attr(input0, "class", "svelte-1d9zqg3"); + attr(label0, "class", "svelte-1d9zqg3"); attr(input1, "type", "text"); attr(input1, "placeholder", "safebooru.com"); - attr(input1, "class", "svelte-2r0xqp"); - attr(label1, "class", "svelte-2r0xqp"); + attr(input1, "class", "svelte-1d9zqg3"); + attr(label1, "class", "svelte-1d9zqg3"); attr(input2, "type", "text"); attr(input2, "placeholder", "/post.json?tags=md5:"); - attr(input2, "class", "svelte-2r0xqp"); - attr(label2, "class", "svelte-2r0xqp"); + attr(input2, "class", "svelte-1d9zqg3"); + attr(label2, "class", "svelte-1d9zqg3"); attr(input3, "type", "text"); attr(input3, "placeholder", "https://safebooru.com/post/show/"); - attr(input3, "class", "svelte-2r0xqp"); - attr(label3, "class", "svelte-2r0xqp"); - attr(div, "class", "form svelte-2r0xqp"); + attr(input3, "class", "svelte-1d9zqg3"); + attr(label3, "class", "svelte-1d9zqg3"); + attr(div, "class", "form svelte-1d9zqg3"); }, m(target, anchor) { insert(target, div, anchor); @@ -22650,8 +22812,8 @@ if (ctx[7].fhost === void 0) add_render_callback(() => ctx[54].call(select)); attr(input, "type", "number"); - attr(input, "class", "svelte-2r0xqp"); - attr(label, "class", "svelte-2r0xqp"); + attr(input, "class", "svelte-1d9zqg3"); + attr(label, "class", "svelte-1d9zqg3"); }, m(target, anchor) { insert(target, p, anchor); @@ -22752,7 +22914,7 @@ for (let i = 0; i < each_blocks.length; i += 1) { each_blocks[i].c(); } - attr(div, "class", "bepis svelte-2r0xqp"); + attr(div, "class", "bepis svelte-1d9zqg3"); }, m(target, anchor) { insert(target, div, anchor); @@ -23040,7 +23202,7 @@ t2 = space(); div = element("div"); if_block.c(); - attr(div, "class", "newsbox svelte-2r0xqp"); + attr(div, "class", "newsbox svelte-1d9zqg3"); }, m(target, anchor) { insert(target, p, anchor); diff --git a/firefox/dist/main.js b/firefox/dist/main.js index 70d8d3f..73c46fb 100644 --- a/firefox/dist/main.js +++ b/firefox/dist/main.js @@ -51,7 +51,7 @@ var define_BUILD_VERSION_default; var init_define_BUILD_VERSION = __esm({ ""() { - define_BUILD_VERSION_default = [0, 269]; + define_BUILD_VERSION_default = [0, 270]; } }); @@ -5213,6 +5213,151 @@ } }); + // node_modules/base-x/src/index.js + var require_src = __commonJS({ + "node_modules/base-x/src/index.js"(exports, module) { + "use strict"; + init_define_BUILD_VERSION(); + init_esbuild_inject(); + function base(ALPHABET) { + if (ALPHABET.length >= 255) { + throw new TypeError("Alphabet too long"); + } + var BASE_MAP = new Uint8Array(256); + for (var j = 0; j < BASE_MAP.length; j++) { + BASE_MAP[j] = 255; + } + for (var i = 0; i < ALPHABET.length; i++) { + var x = ALPHABET.charAt(i); + var xc = x.charCodeAt(0); + if (BASE_MAP[xc] !== 255) { + throw new TypeError(x + " is ambiguous"); + } + BASE_MAP[xc] = i; + } + var BASE = ALPHABET.length; + var LEADER = ALPHABET.charAt(0); + var FACTOR = Math.log(BASE) / Math.log(256); + var iFACTOR = Math.log(256) / Math.log(BASE); + function encode2(source) { + if (source instanceof Uint8Array) { + } else if (ArrayBuffer.isView(source)) { + source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + } else if (Array.isArray(source)) { + source = Uint8Array.from(source); + } + if (!(source instanceof Uint8Array)) { + throw new TypeError("Expected Uint8Array"); + } + if (source.length === 0) { + return ""; + } + var zeroes = 0; + var length = 0; + var pbegin = 0; + var pend = source.length; + while (pbegin !== pend && source[pbegin] === 0) { + pbegin++; + zeroes++; + } + var size = (pend - pbegin) * iFACTOR + 1 >>> 0; + var b58 = new Uint8Array(size); + while (pbegin !== pend) { + var carry = source[pbegin]; + var i2 = 0; + for (var it1 = size - 1; (carry !== 0 || i2 < length) && it1 !== -1; it1--, i2++) { + carry += 256 * b58[it1] >>> 0; + b58[it1] = carry % BASE >>> 0; + carry = carry / BASE >>> 0; + } + if (carry !== 0) { + throw new Error("Non-zero carry"); + } + length = i2; + pbegin++; + } + var it2 = size - length; + while (it2 !== size && b58[it2] === 0) { + it2++; + } + var str = LEADER.repeat(zeroes); + for (; it2 < size; ++it2) { + str += ALPHABET.charAt(b58[it2]); + } + return str; + } + function decodeUnsafe(source) { + if (typeof source !== "string") { + throw new TypeError("Expected String"); + } + if (source.length === 0) { + return new Uint8Array(); + } + var psz = 0; + var zeroes = 0; + var length = 0; + while (source[psz] === LEADER) { + zeroes++; + psz++; + } + var size = (source.length - psz) * FACTOR + 1 >>> 0; + var b256 = new Uint8Array(size); + while (source[psz]) { + var carry = BASE_MAP[source.charCodeAt(psz)]; + if (carry === 255) { + return; + } + var i2 = 0; + for (var it3 = size - 1; (carry !== 0 || i2 < length) && it3 !== -1; it3--, i2++) { + carry += BASE * b256[it3] >>> 0; + b256[it3] = carry % 256 >>> 0; + carry = carry / 256 >>> 0; + } + if (carry !== 0) { + throw new Error("Non-zero carry"); + } + length = i2; + psz++; + } + var it4 = size - length; + while (it4 !== size && b256[it4] === 0) { + it4++; + } + var vch = new Uint8Array(zeroes + (size - it4)); + var j2 = zeroes; + while (it4 !== size) { + vch[j2++] = b256[it4++]; + } + return vch; + } + function decode3(string) { + var buffer = decodeUnsafe(string); + if (buffer) { + return buffer; + } + throw new Error("Non-base" + BASE + " character"); + } + return { + encode: encode2, + decodeUnsafe, + decode: decode3 + }; + } + module.exports = base; + } + }); + + // node_modules/bs58/index.js + var require_bs58 = __commonJS({ + "node_modules/bs58/index.js"(exports, module) { + init_define_BUILD_VERSION(); + init_esbuild_inject(); + var basex = require_src(); + var ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + module.exports = basex(ALPHABET); + } + }); + // node_modules/int64-buffer/int64-buffer.js var require_int64_buffer = __commonJS({ "node_modules/int64-buffer/int64-buffer.js"(exports) { @@ -13476,12 +13621,12 @@ init5(); } if (typeof module !== "undefined") { - module.exports = encode; + module.exports = encode2; } else if (typeof window !== "undefined") { window["jpeg-js"] = window["jpeg-js"] || {}; - window["jpeg-js"].encode = encode; + window["jpeg-js"].encode = encode2; } - function encode(imgData, qu) { + function encode2(imgData, qu) { if (typeof qu === "undefined") qu = 50; var encoder = new JPEGEncoder(qu); @@ -13769,21 +13914,21 @@ successiveACState = 0; } } - function decodeMcu(component2, decode3, mcu2, row, col) { + function decodeMcu(component2, decode4, mcu2, row, col) { var mcuRow = mcu2 / mcusPerLine | 0; var mcuCol = mcu2 % mcusPerLine; var blockRow = mcuRow * component2.v + row; var blockCol = mcuCol * component2.h + col; if (component2.blocks[blockRow] === void 0 && opts.tolerantDecoding) return; - decode3(component2, component2.blocks[blockRow][blockCol]); + decode4(component2, component2.blocks[blockRow][blockCol]); } - function decodeBlock(component2, decode3, mcu2) { + function decodeBlock(component2, decode4, mcu2) { var blockRow = mcu2 / component2.blocksPerLine | 0; var blockCol = mcu2 % component2.blocksPerLine; if (component2.blocks[blockRow] === void 0 && opts.tolerantDecoding) return; - decode3(component2, component2.blocks[blockRow][blockCol]); + decode4(component2, component2.blocks[blockRow][blockCol]); } var componentsLength = components.length; var component, i, j, k, n; @@ -14481,12 +14626,12 @@ return constructor; }(); if (typeof module !== "undefined") { - module.exports = decode2; + module.exports = decode3; } else if (typeof window !== "undefined") { window["jpeg-js"] = window["jpeg-js"] || {}; - window["jpeg-js"].decode = decode2; + window["jpeg-js"].decode = decode3; } - function decode2(jpegData, userOpts = {}) { + function decode3(jpegData, userOpts = {}) { var defaultOpts = { colorTransform: void 0, useTArray: false, @@ -14536,11 +14681,11 @@ "node_modules/jpeg-js/index.js"(exports, module) { init_define_BUILD_VERSION(); init_esbuild_inject(); - var encode = require_encoder(); - var decode2 = require_decoder(); + var encode2 = require_encoder(); + var decode3 = require_decoder(); module.exports = { - encode, - decode: decode2 + encode: encode2, + decode: decode3 }; } }); @@ -18208,6 +18353,7 @@ }; // src/pngv3.ts + var bs58 = __toESM(require_bs58(), 1); var csettings2; settings.subscribe((b) => { csettings2 = b; @@ -18280,15 +18426,21 @@ const passed = buff.slice(4 + w.length); if (!passed.toString().match(/^[0-9a-zA-Z+/=]+$/g)) continue; - try { - const decoded = import_buffer3.Buffer.from(passed.toString(), "base64").toString().split(" ").map((e) => { - if (!(e[0] in rprefs)) - throw "Uhh"; - return `https://${rprefs[e[0]]}/${e.slice(1)}`; - }).join(" "); - const k = await decodeCoom3Payload(import_buffer3.Buffer.from(decoded)); - ret.push(...k.filter((e) => e).map((e) => e)); - } finally { + const decoders = [ + (b) => import_buffer3.Buffer.from(b.toString(), "base64").toString(), + (b) => import_buffer3.Buffer.from(bs58.decode(passed.toString())).toString() + ]; + for (const d of decoders) { + try { + const decoded = d(passed).split(" ").map((e) => { + if (!(e[0] in rprefs)) + throw "Uhh"; + return `https://${rprefs[e[0]]}/${e.slice(1)}`; + }).join(" "); + const k = await decodeCoom3Payload(import_buffer3.Buffer.from(decoded)); + ret.push(...k.filter((e) => e).map((e) => e)); + } catch (e) { + } } } break; @@ -18353,7 +18505,7 @@ } return ""; }); - const injb = import_buffer3.Buffer.from(import_buffer3.Buffer.from(links.join(" ")).toString("base64")); + const injb = import_buffer3.Buffer.from(bs58.encode(import_buffer3.Buffer.from(links.join(" ")))); return inject_data(container, injb); }; var has_embed = async (png) => { @@ -18383,6 +18535,8 @@ if (passed.match(/^[0-9a-zA-Z+/=]+$/g)) { if (import_buffer3.Buffer.from(passed, "base64").toString().split(" ").every((l) => l[0] in rprefs)) return true; + if (import_buffer3.Buffer.from(bs58.decode(passed)).toString().split(" ").every((l) => l[0] in rprefs)) + return true; } } break; @@ -21049,7 +21203,7 @@ // src/Components/App.svelte function add_css8(target) { - append_styles(target, "svelte-2r0xqp", '.bepis.svelte-2r0xqp.svelte-2r0xqp{max-height:260px;overflow-y:auto}.tagcont.svelte-2r0xqp.svelte-2r0xqp{display:flex;gap:5px;margin-bottom:10px;flex-wrap:wrap}label.svelte-2r0xqp>input[type="text"].svelte-2r0xqp,label.svelte-2r0xqp>input[type="number"].svelte-2r0xqp{width:95%}.content.svelte-2r0xqp.svelte-2r0xqp{display:flex;flex-direction:column}.error.svelte-2r0xqp.svelte-2r0xqp{color:red}hr.svelte-2r0xqp.svelte-2r0xqp{width:100%}h1.svelte-2r0xqp.svelte-2r0xqp{text-align:center}.form.svelte-2r0xqp.svelte-2r0xqp{display:flex;flex-direction:column;gap:20px;position:absolute;padding:15px;border:1px solid white;background-color:black;border-radius:10px}.form.svelte-2r0xqp>label.svelte-2r0xqp{display:flex;flex-direction:column;gap:10px}.newsbox.svelte-2r0xqp.svelte-2r0xqp{max-height:300px;overflow-y:scroll}.backpanel.svelte-2r0xqp.svelte-2r0xqp{position:absolute;right:32px;padding:10px;width:15%;top:32px;border:1px solid;border-radius:5px;background-color:rgba(0, 0, 0, 0.8);pointer-events:all;backdrop-filter:blur(9px);max-height:80vh;min-width:321px}'); + append_styles(target, "svelte-1d9zqg3", '.bepis.svelte-1d9zqg3.svelte-1d9zqg3{max-height:260px;overflow-y:auto}.tagcont.svelte-1d9zqg3.svelte-1d9zqg3{display:flex;gap:5px;margin-bottom:10px;flex-wrap:wrap}label.svelte-1d9zqg3>input[type="text"].svelte-1d9zqg3,label.svelte-1d9zqg3>input[type="number"].svelte-1d9zqg3{width:95%}.content.svelte-1d9zqg3.svelte-1d9zqg3{display:flex;flex-direction:column}.error.svelte-1d9zqg3.svelte-1d9zqg3{color:red}hr.svelte-1d9zqg3.svelte-1d9zqg3{width:100%}h1.svelte-1d9zqg3.svelte-1d9zqg3{text-align:center;margin-bottom:0}h4.svelte-1d9zqg3.svelte-1d9zqg3{margin:0}.form.svelte-1d9zqg3.svelte-1d9zqg3{display:flex;flex-direction:column;gap:20px;position:absolute;padding:15px;border:1px solid white;background-color:black;border-radius:10px}.form.svelte-1d9zqg3>label.svelte-1d9zqg3{display:flex;flex-direction:column;gap:10px}.newsbox.svelte-1d9zqg3.svelte-1d9zqg3{max-height:300px;overflow-y:scroll}.backpanel.svelte-1d9zqg3.svelte-1d9zqg3{position:absolute;right:32px;padding:10px;width:15%;top:32px;border:1px solid;border-radius:5px;background-color:rgba(0, 0, 0, 0.8);pointer-events:all;backdrop-filter:blur(9px);max-height:80vh;min-width:321px}'); } function get_each_context2(ctx, list, i) { const child_ctx = ctx.slice(); @@ -21086,8 +21240,10 @@ let t0; let t1; let t2; + let h4; + let t4; let hr; - let t3; + let t5; let tabs; let div1_transition; let current; @@ -21105,13 +21261,17 @@ t0 = text("PEE Settings 0."); t1 = text(ctx[0]); t2 = space(); + h4 = element("h4"); + h4.innerHTML = `Join us on 2chen!`; + t4 = space(); hr = element("hr"); - t3 = space(); + t5 = space(); create_component(tabs.$$.fragment); - attr(h1, "class", "svelte-2r0xqp"); - attr(hr, "class", "svelte-2r0xqp"); - attr(div0, "class", "content svelte-2r0xqp"); - attr(div1, "class", "backpanel svelte-2r0xqp"); + attr(h1, "class", "svelte-1d9zqg3"); + attr(h4, "class", "svelte-1d9zqg3"); + attr(hr, "class", "svelte-1d9zqg3"); + attr(div0, "class", "content svelte-1d9zqg3"); + attr(div1, "class", "backpanel svelte-1d9zqg3"); }, m(target, anchor) { insert(target, div1, anchor); @@ -21120,8 +21280,10 @@ append(h1, t0); append(h1, t1); append(div0, t2); + append(div0, h4); + append(div0, t4); append(div0, hr); - append(div0, t3); + append(div0, t5); mount_component(tabs, div0, null); current = true; }, @@ -21515,8 +21677,8 @@ if_block1_anchor = empty(); attr(a, "title", "Only requires Search Files permission. See Hydrus docs on where to set this up."); attr(input, "type", "text"); - attr(input, "class", "svelte-2r0xqp"); - attr(label, "class", "svelte-2r0xqp"); + attr(input, "class", "svelte-1d9zqg3"); + attr(label, "class", "svelte-1d9zqg3"); }, m(target, anchor) { if (if_block0) @@ -21592,7 +21754,7 @@ c() { span = element("span"); t = text(t_value); - attr(span, "class", "error svelte-2r0xqp"); + attr(span, "class", "error svelte-1d9zqg3"); }, m(target, anchor) { insert(target, span, anchor); @@ -21629,12 +21791,12 @@ input1 = element("input"); set_style(input0, "width", "5ch"); attr(input0, "type", "number"); - attr(input0, "class", "svelte-2r0xqp"); - attr(label0, "class", "svelte-2r0xqp"); + attr(input0, "class", "svelte-1d9zqg3"); + attr(label0, "class", "svelte-1d9zqg3"); attr(input1, "placeholder", "Restrict to these tags (space to separate tags, _ to separate words)"); attr(input1, "type", "text"); - attr(input1, "class", "svelte-2r0xqp"); - attr(label1, "class", "svelte-2r0xqp"); + attr(input1, "class", "svelte-1d9zqg3"); + attr(label1, "class", "svelte-1d9zqg3"); }, m(target, anchor) { insert(target, label0, anchor); @@ -22191,9 +22353,9 @@ t13 = space(); input1 = element("input"); attr(input0, "type", "checkbox"); - attr(div0, "class", "tagcont svelte-2r0xqp"); - attr(hr, "class", "svelte-2r0xqp"); - attr(div1, "class", "tagcont svelte-2r0xqp"); + attr(div0, "class", "tagcont svelte-1d9zqg3"); + attr(hr, "class", "svelte-1d9zqg3"); + attr(div1, "class", "tagcont svelte-1d9zqg3"); attr(input1, "placeholder", "Press enter after typing your tag"); }, m(target, anchor) { @@ -22403,9 +22565,9 @@ a = element("a"); a.textContent = "?"; attr(input, "type", "number"); - attr(input, "class", "svelte-2r0xqp"); + attr(input, "class", "svelte-1d9zqg3"); attr(a, "title", "Higher will filter more potentially different images, lower will let more identical images through"); - attr(label, "class", "svelte-2r0xqp"); + attr(label, "class", "svelte-1d9zqg3"); }, m(target, anchor) { insert(target, label, anchor); @@ -22544,21 +22706,21 @@ button.textContent = "Add"; attr(input0, "type", "text"); attr(input0, "placeholder", "Safebooru"); - attr(input0, "class", "svelte-2r0xqp"); - attr(label0, "class", "svelte-2r0xqp"); + attr(input0, "class", "svelte-1d9zqg3"); + attr(label0, "class", "svelte-1d9zqg3"); attr(input1, "type", "text"); attr(input1, "placeholder", "safebooru.com"); - attr(input1, "class", "svelte-2r0xqp"); - attr(label1, "class", "svelte-2r0xqp"); + attr(input1, "class", "svelte-1d9zqg3"); + attr(label1, "class", "svelte-1d9zqg3"); attr(input2, "type", "text"); attr(input2, "placeholder", "/post.json?tags=md5:"); - attr(input2, "class", "svelte-2r0xqp"); - attr(label2, "class", "svelte-2r0xqp"); + attr(input2, "class", "svelte-1d9zqg3"); + attr(label2, "class", "svelte-1d9zqg3"); attr(input3, "type", "text"); attr(input3, "placeholder", "https://safebooru.com/post/show/"); - attr(input3, "class", "svelte-2r0xqp"); - attr(label3, "class", "svelte-2r0xqp"); - attr(div, "class", "form svelte-2r0xqp"); + attr(input3, "class", "svelte-1d9zqg3"); + attr(label3, "class", "svelte-1d9zqg3"); + attr(div, "class", "form svelte-1d9zqg3"); }, m(target, anchor) { insert(target, div, anchor); @@ -22792,8 +22954,8 @@ if (ctx[7].fhost === void 0) add_render_callback(() => ctx[54].call(select)); attr(input, "type", "number"); - attr(input, "class", "svelte-2r0xqp"); - attr(label, "class", "svelte-2r0xqp"); + attr(input, "class", "svelte-1d9zqg3"); + attr(label, "class", "svelte-1d9zqg3"); }, m(target, anchor) { insert(target, p, anchor); @@ -22894,7 +23056,7 @@ for (let i = 0; i < each_blocks.length; i += 1) { each_blocks[i].c(); } - attr(div, "class", "bepis svelte-2r0xqp"); + attr(div, "class", "bepis svelte-1d9zqg3"); }, m(target, anchor) { insert(target, div, anchor); @@ -23182,7 +23344,7 @@ t2 = space(); div = element("div"); if_block.c(); - attr(div, "class", "newsbox svelte-2r0xqp"); + attr(div, "class", "newsbox svelte-1d9zqg3"); }, m(target, anchor) { insert(target, p, anchor); diff --git a/firefox/manifest.json b/firefox/manifest.json index 7ae1314..043c708 100644 --- a/firefox/manifest.json +++ b/firefox/manifest.json @@ -7,7 +7,7 @@ }, "name": "PngExtraEmbedder", "description": "Discover embedded files on 4chan and archives!", - "version": "0.269", + "version": "0.270", "icons": { "64": "1449696017588.png" }, diff --git a/firefox_update.json b/firefox_update.json index 0551cb3..d346802 100644 --- a/firefox_update.json +++ b/firefox_update.json @@ -1 +1 @@ -{"addons":{"{34ac4994-07f2-44d2-8599-682516a6c6a6}":{"updates":[{"version":"0.269","update_link":"https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.269.xpi"}]}}} \ No newline at end of file +{"addons":{"{34ac4994-07f2-44d2-8599-682516a6c6a6}":{"updates":[{"version":"0.270","update_link":"https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.270.xpi"}]}}} \ No newline at end of file diff --git a/main.meta.js b/main.meta.js index 57e6402..73b5a52 100644 --- a/main.meta.js +++ b/main.meta.js @@ -1,7 +1,7 @@ // ==UserScript== // @name PNGExtraEmbed // @namespace https://coom.tech/ -// @version 0.268 +// @version 0.270 // @description uhh // @author You // @match https://boards.4channel.org/* diff --git a/main.user.js b/main.user.js index e65b5b4..03c943d 100644 --- a/main.user.js +++ b/main.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name PNGExtraEmbed // @namespace https://coom.tech/ -// @version 0.268 +// @version 0.270 // @description uhh // @author You // @match https://boards.4channel.org/* @@ -87,7 +87,7 @@ const _DOMParser = DOMParser; var define_BUILD_VERSION_default; var init_define_BUILD_VERSION = __esm({ ""() { - define_BUILD_VERSION_default = [0, 268]; + define_BUILD_VERSION_default = [0, 270]; } }); @@ -5249,6 +5249,151 @@ const _DOMParser = DOMParser; } }); + // node_modules/base-x/src/index.js + var require_src = __commonJS({ + "node_modules/base-x/src/index.js"(exports, module) { + "use strict"; + init_define_BUILD_VERSION(); + init_esbuild_inject(); + function base(ALPHABET) { + if (ALPHABET.length >= 255) { + throw new TypeError("Alphabet too long"); + } + var BASE_MAP = new Uint8Array(256); + for (var j = 0; j < BASE_MAP.length; j++) { + BASE_MAP[j] = 255; + } + for (var i = 0; i < ALPHABET.length; i++) { + var x = ALPHABET.charAt(i); + var xc = x.charCodeAt(0); + if (BASE_MAP[xc] !== 255) { + throw new TypeError(x + " is ambiguous"); + } + BASE_MAP[xc] = i; + } + var BASE = ALPHABET.length; + var LEADER = ALPHABET.charAt(0); + var FACTOR = Math.log(BASE) / Math.log(256); + var iFACTOR = Math.log(256) / Math.log(BASE); + function encode2(source) { + if (source instanceof Uint8Array) { + } else if (ArrayBuffer.isView(source)) { + source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + } else if (Array.isArray(source)) { + source = Uint8Array.from(source); + } + if (!(source instanceof Uint8Array)) { + throw new TypeError("Expected Uint8Array"); + } + if (source.length === 0) { + return ""; + } + var zeroes = 0; + var length = 0; + var pbegin = 0; + var pend = source.length; + while (pbegin !== pend && source[pbegin] === 0) { + pbegin++; + zeroes++; + } + var size = (pend - pbegin) * iFACTOR + 1 >>> 0; + var b58 = new Uint8Array(size); + while (pbegin !== pend) { + var carry = source[pbegin]; + var i2 = 0; + for (var it1 = size - 1; (carry !== 0 || i2 < length) && it1 !== -1; it1--, i2++) { + carry += 256 * b58[it1] >>> 0; + b58[it1] = carry % BASE >>> 0; + carry = carry / BASE >>> 0; + } + if (carry !== 0) { + throw new Error("Non-zero carry"); + } + length = i2; + pbegin++; + } + var it2 = size - length; + while (it2 !== size && b58[it2] === 0) { + it2++; + } + var str = LEADER.repeat(zeroes); + for (; it2 < size; ++it2) { + str += ALPHABET.charAt(b58[it2]); + } + return str; + } + function decodeUnsafe(source) { + if (typeof source !== "string") { + throw new TypeError("Expected String"); + } + if (source.length === 0) { + return new Uint8Array(); + } + var psz = 0; + var zeroes = 0; + var length = 0; + while (source[psz] === LEADER) { + zeroes++; + psz++; + } + var size = (source.length - psz) * FACTOR + 1 >>> 0; + var b256 = new Uint8Array(size); + while (source[psz]) { + var carry = BASE_MAP[source.charCodeAt(psz)]; + if (carry === 255) { + return; + } + var i2 = 0; + for (var it3 = size - 1; (carry !== 0 || i2 < length) && it3 !== -1; it3--, i2++) { + carry += BASE * b256[it3] >>> 0; + b256[it3] = carry % 256 >>> 0; + carry = carry / 256 >>> 0; + } + if (carry !== 0) { + throw new Error("Non-zero carry"); + } + length = i2; + psz++; + } + var it4 = size - length; + while (it4 !== size && b256[it4] === 0) { + it4++; + } + var vch = new Uint8Array(zeroes + (size - it4)); + var j2 = zeroes; + while (it4 !== size) { + vch[j2++] = b256[it4++]; + } + return vch; + } + function decode3(string) { + var buffer = decodeUnsafe(string); + if (buffer) { + return buffer; + } + throw new Error("Non-base" + BASE + " character"); + } + return { + encode: encode2, + decodeUnsafe, + decode: decode3 + }; + } + module.exports = base; + } + }); + + // node_modules/bs58/index.js + var require_bs58 = __commonJS({ + "node_modules/bs58/index.js"(exports, module) { + init_define_BUILD_VERSION(); + init_esbuild_inject(); + var basex = require_src(); + var ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + module.exports = basex(ALPHABET); + } + }); + // node_modules/int64-buffer/int64-buffer.js var require_int64_buffer = __commonJS({ "node_modules/int64-buffer/int64-buffer.js"(exports) { @@ -13512,12 +13657,12 @@ const _DOMParser = DOMParser; init5(); } if (typeof module !== "undefined") { - module.exports = encode; + module.exports = encode2; } else if (typeof window !== "undefined") { window["jpeg-js"] = window["jpeg-js"] || {}; - window["jpeg-js"].encode = encode; + window["jpeg-js"].encode = encode2; } - function encode(imgData, qu) { + function encode2(imgData, qu) { if (typeof qu === "undefined") qu = 50; var encoder = new JPEGEncoder(qu); @@ -13805,21 +13950,21 @@ const _DOMParser = DOMParser; successiveACState = 0; } } - function decodeMcu(component2, decode3, mcu2, row, col) { + function decodeMcu(component2, decode4, mcu2, row, col) { var mcuRow = mcu2 / mcusPerLine | 0; var mcuCol = mcu2 % mcusPerLine; var blockRow = mcuRow * component2.v + row; var blockCol = mcuCol * component2.h + col; if (component2.blocks[blockRow] === void 0 && opts.tolerantDecoding) return; - decode3(component2, component2.blocks[blockRow][blockCol]); + decode4(component2, component2.blocks[blockRow][blockCol]); } - function decodeBlock(component2, decode3, mcu2) { + function decodeBlock(component2, decode4, mcu2) { var blockRow = mcu2 / component2.blocksPerLine | 0; var blockCol = mcu2 % component2.blocksPerLine; if (component2.blocks[blockRow] === void 0 && opts.tolerantDecoding) return; - decode3(component2, component2.blocks[blockRow][blockCol]); + decode4(component2, component2.blocks[blockRow][blockCol]); } var componentsLength = components.length; var component, i, j, k, n; @@ -14517,12 +14662,12 @@ const _DOMParser = DOMParser; return constructor; }(); if (typeof module !== "undefined") { - module.exports = decode2; + module.exports = decode3; } else if (typeof window !== "undefined") { window["jpeg-js"] = window["jpeg-js"] || {}; - window["jpeg-js"].decode = decode2; + window["jpeg-js"].decode = decode3; } - function decode2(jpegData, userOpts = {}) { + function decode3(jpegData, userOpts = {}) { var defaultOpts = { colorTransform: void 0, useTArray: false, @@ -14572,11 +14717,11 @@ const _DOMParser = DOMParser; "node_modules/jpeg-js/index.js"(exports, module) { init_define_BUILD_VERSION(); init_esbuild_inject(); - var encode = require_encoder(); - var decode2 = require_decoder(); + var encode2 = require_encoder(); + var decode3 = require_decoder(); module.exports = { - encode, - decode: decode2 + encode: encode2, + decode: decode3 }; } }); @@ -18102,6 +18247,7 @@ const _DOMParser = DOMParser; }; // src/pngv3.ts + var bs58 = __toESM(require_bs58(), 1); var csettings2; settings.subscribe((b) => { csettings2 = b; @@ -18174,15 +18320,21 @@ const _DOMParser = DOMParser; const passed = buff.slice(4 + w.length); if (!passed.toString().match(/^[0-9a-zA-Z+/=]+$/g)) continue; - try { - const decoded = import_buffer3.Buffer.from(passed.toString(), "base64").toString().split(" ").map((e) => { - if (!(e[0] in rprefs)) - throw "Uhh"; - return `https://${rprefs[e[0]]}/${e.slice(1)}`; - }).join(" "); - const k = await decodeCoom3Payload(import_buffer3.Buffer.from(decoded)); - ret.push(...k.filter((e) => e).map((e) => e)); - } finally { + const decoders = [ + (b) => import_buffer3.Buffer.from(b.toString(), "base64").toString(), + (b) => import_buffer3.Buffer.from(bs58.decode(passed.toString())).toString() + ]; + for (const d of decoders) { + try { + const decoded = d(passed).split(" ").map((e) => { + if (!(e[0] in rprefs)) + throw "Uhh"; + return `https://${rprefs[e[0]]}/${e.slice(1)}`; + }).join(" "); + const k = await decodeCoom3Payload(import_buffer3.Buffer.from(decoded)); + ret.push(...k.filter((e) => e).map((e) => e)); + } catch (e) { + } } } break; @@ -18247,7 +18399,7 @@ const _DOMParser = DOMParser; } return ""; }); - const injb = import_buffer3.Buffer.from(import_buffer3.Buffer.from(links.join(" ")).toString("base64")); + const injb = import_buffer3.Buffer.from(bs58.encode(import_buffer3.Buffer.from(links.join(" ")))); return inject_data(container, injb); }; var has_embed = async (png) => { @@ -18277,6 +18429,8 @@ const _DOMParser = DOMParser; if (passed.match(/^[0-9a-zA-Z+/=]+$/g)) { if (import_buffer3.Buffer.from(passed, "base64").toString().split(" ").every((l) => l[0] in rprefs)) return true; + if (import_buffer3.Buffer.from(bs58.decode(passed)).toString().split(" ").every((l) => l[0] in rprefs)) + return true; } } break; @@ -18630,7 +18784,7 @@ const _DOMParser = DOMParser; var injectTrue = async (b, links) => { if (b.size / 20 < links.join(" ").length) throw "Image too small to embed."; - const arr = new Uint8Array(await b.arrayBuffer()); + const arr = new Uint8Array(new Uint8Array(await b.arrayBuffer())); const buff = f5inst.embed(arr, new TextEncoder().encode(links.join(" "))); return import_buffer6.Buffer.from(buff); }; @@ -20943,7 +21097,7 @@ const _DOMParser = DOMParser; // src/Components/App.svelte function add_css8(target) { - append_styles(target, "svelte-2r0xqp", '.bepis.svelte-2r0xqp.svelte-2r0xqp{max-height:260px;overflow-y:auto}.tagcont.svelte-2r0xqp.svelte-2r0xqp{display:flex;gap:5px;margin-bottom:10px;flex-wrap:wrap}label.svelte-2r0xqp>input[type="text"].svelte-2r0xqp,label.svelte-2r0xqp>input[type="number"].svelte-2r0xqp{width:95%}.content.svelte-2r0xqp.svelte-2r0xqp{display:flex;flex-direction:column}.error.svelte-2r0xqp.svelte-2r0xqp{color:red}hr.svelte-2r0xqp.svelte-2r0xqp{width:100%}h1.svelte-2r0xqp.svelte-2r0xqp{text-align:center}.form.svelte-2r0xqp.svelte-2r0xqp{display:flex;flex-direction:column;gap:20px;position:absolute;padding:15px;border:1px solid white;background-color:black;border-radius:10px}.form.svelte-2r0xqp>label.svelte-2r0xqp{display:flex;flex-direction:column;gap:10px}.newsbox.svelte-2r0xqp.svelte-2r0xqp{max-height:300px;overflow-y:scroll}.backpanel.svelte-2r0xqp.svelte-2r0xqp{position:absolute;right:32px;padding:10px;width:15%;top:32px;border:1px solid;border-radius:5px;background-color:rgba(0, 0, 0, 0.8);pointer-events:all;backdrop-filter:blur(9px);max-height:80vh;min-width:321px}'); + append_styles(target, "svelte-1d9zqg3", '.bepis.svelte-1d9zqg3.svelte-1d9zqg3{max-height:260px;overflow-y:auto}.tagcont.svelte-1d9zqg3.svelte-1d9zqg3{display:flex;gap:5px;margin-bottom:10px;flex-wrap:wrap}label.svelte-1d9zqg3>input[type="text"].svelte-1d9zqg3,label.svelte-1d9zqg3>input[type="number"].svelte-1d9zqg3{width:95%}.content.svelte-1d9zqg3.svelte-1d9zqg3{display:flex;flex-direction:column}.error.svelte-1d9zqg3.svelte-1d9zqg3{color:red}hr.svelte-1d9zqg3.svelte-1d9zqg3{width:100%}h1.svelte-1d9zqg3.svelte-1d9zqg3{text-align:center;margin-bottom:0}h4.svelte-1d9zqg3.svelte-1d9zqg3{margin:0}.form.svelte-1d9zqg3.svelte-1d9zqg3{display:flex;flex-direction:column;gap:20px;position:absolute;padding:15px;border:1px solid white;background-color:black;border-radius:10px}.form.svelte-1d9zqg3>label.svelte-1d9zqg3{display:flex;flex-direction:column;gap:10px}.newsbox.svelte-1d9zqg3.svelte-1d9zqg3{max-height:300px;overflow-y:scroll}.backpanel.svelte-1d9zqg3.svelte-1d9zqg3{position:absolute;right:32px;padding:10px;width:15%;top:32px;border:1px solid;border-radius:5px;background-color:rgba(0, 0, 0, 0.8);pointer-events:all;backdrop-filter:blur(9px);max-height:80vh;min-width:321px}'); } function get_each_context2(ctx, list, i) { const child_ctx = ctx.slice(); @@ -20980,8 +21134,10 @@ const _DOMParser = DOMParser; let t0; let t1; let t2; + let h4; + let t4; let hr; - let t3; + let t5; let tabs; let div1_transition; let current; @@ -20999,13 +21155,17 @@ const _DOMParser = DOMParser; t0 = text("PEE Settings 0."); t1 = text(ctx[0]); t2 = space(); + h4 = element("h4"); + h4.innerHTML = `Join us on 2chen!`; + t4 = space(); hr = element("hr"); - t3 = space(); + t5 = space(); create_component(tabs.$$.fragment); - attr(h1, "class", "svelte-2r0xqp"); - attr(hr, "class", "svelte-2r0xqp"); - attr(div0, "class", "content svelte-2r0xqp"); - attr(div1, "class", "backpanel svelte-2r0xqp"); + attr(h1, "class", "svelte-1d9zqg3"); + attr(h4, "class", "svelte-1d9zqg3"); + attr(hr, "class", "svelte-1d9zqg3"); + attr(div0, "class", "content svelte-1d9zqg3"); + attr(div1, "class", "backpanel svelte-1d9zqg3"); }, m(target, anchor) { insert(target, div1, anchor); @@ -21014,8 +21174,10 @@ const _DOMParser = DOMParser; append(h1, t0); append(h1, t1); append(div0, t2); + append(div0, h4); + append(div0, t4); append(div0, hr); - append(div0, t3); + append(div0, t5); mount_component(tabs, div0, null); current = true; }, @@ -21409,8 +21571,8 @@ const _DOMParser = DOMParser; if_block1_anchor = empty(); attr(a, "title", "Only requires Search Files permission. See Hydrus docs on where to set this up."); attr(input, "type", "text"); - attr(input, "class", "svelte-2r0xqp"); - attr(label, "class", "svelte-2r0xqp"); + attr(input, "class", "svelte-1d9zqg3"); + attr(label, "class", "svelte-1d9zqg3"); }, m(target, anchor) { if (if_block0) @@ -21486,7 +21648,7 @@ const _DOMParser = DOMParser; c() { span = element("span"); t = text(t_value); - attr(span, "class", "error svelte-2r0xqp"); + attr(span, "class", "error svelte-1d9zqg3"); }, m(target, anchor) { insert(target, span, anchor); @@ -21523,12 +21685,12 @@ const _DOMParser = DOMParser; input1 = element("input"); set_style(input0, "width", "5ch"); attr(input0, "type", "number"); - attr(input0, "class", "svelte-2r0xqp"); - attr(label0, "class", "svelte-2r0xqp"); + attr(input0, "class", "svelte-1d9zqg3"); + attr(label0, "class", "svelte-1d9zqg3"); attr(input1, "placeholder", "Restrict to these tags (space to separate tags, _ to separate words)"); attr(input1, "type", "text"); - attr(input1, "class", "svelte-2r0xqp"); - attr(label1, "class", "svelte-2r0xqp"); + attr(input1, "class", "svelte-1d9zqg3"); + attr(label1, "class", "svelte-1d9zqg3"); }, m(target, anchor) { insert(target, label0, anchor); @@ -22085,9 +22247,9 @@ const _DOMParser = DOMParser; t13 = space(); input1 = element("input"); attr(input0, "type", "checkbox"); - attr(div0, "class", "tagcont svelte-2r0xqp"); - attr(hr, "class", "svelte-2r0xqp"); - attr(div1, "class", "tagcont svelte-2r0xqp"); + attr(div0, "class", "tagcont svelte-1d9zqg3"); + attr(hr, "class", "svelte-1d9zqg3"); + attr(div1, "class", "tagcont svelte-1d9zqg3"); attr(input1, "placeholder", "Press enter after typing your tag"); }, m(target, anchor) { @@ -22297,9 +22459,9 @@ const _DOMParser = DOMParser; a = element("a"); a.textContent = "?"; attr(input, "type", "number"); - attr(input, "class", "svelte-2r0xqp"); + attr(input, "class", "svelte-1d9zqg3"); attr(a, "title", "Higher will filter more potentially different images, lower will let more identical images through"); - attr(label, "class", "svelte-2r0xqp"); + attr(label, "class", "svelte-1d9zqg3"); }, m(target, anchor) { insert(target, label, anchor); @@ -22438,21 +22600,21 @@ const _DOMParser = DOMParser; button.textContent = "Add"; attr(input0, "type", "text"); attr(input0, "placeholder", "Safebooru"); - attr(input0, "class", "svelte-2r0xqp"); - attr(label0, "class", "svelte-2r0xqp"); + attr(input0, "class", "svelte-1d9zqg3"); + attr(label0, "class", "svelte-1d9zqg3"); attr(input1, "type", "text"); attr(input1, "placeholder", "safebooru.com"); - attr(input1, "class", "svelte-2r0xqp"); - attr(label1, "class", "svelte-2r0xqp"); + attr(input1, "class", "svelte-1d9zqg3"); + attr(label1, "class", "svelte-1d9zqg3"); attr(input2, "type", "text"); attr(input2, "placeholder", "/post.json?tags=md5:"); - attr(input2, "class", "svelte-2r0xqp"); - attr(label2, "class", "svelte-2r0xqp"); + attr(input2, "class", "svelte-1d9zqg3"); + attr(label2, "class", "svelte-1d9zqg3"); attr(input3, "type", "text"); attr(input3, "placeholder", "https://safebooru.com/post/show/"); - attr(input3, "class", "svelte-2r0xqp"); - attr(label3, "class", "svelte-2r0xqp"); - attr(div, "class", "form svelte-2r0xqp"); + attr(input3, "class", "svelte-1d9zqg3"); + attr(label3, "class", "svelte-1d9zqg3"); + attr(div, "class", "form svelte-1d9zqg3"); }, m(target, anchor) { insert(target, div, anchor); @@ -22686,8 +22848,8 @@ const _DOMParser = DOMParser; if (ctx[7].fhost === void 0) add_render_callback(() => ctx[54].call(select)); attr(input, "type", "number"); - attr(input, "class", "svelte-2r0xqp"); - attr(label, "class", "svelte-2r0xqp"); + attr(input, "class", "svelte-1d9zqg3"); + attr(label, "class", "svelte-1d9zqg3"); }, m(target, anchor) { insert(target, p, anchor); @@ -22788,7 +22950,7 @@ const _DOMParser = DOMParser; for (let i = 0; i < each_blocks.length; i += 1) { each_blocks[i].c(); } - attr(div, "class", "bepis svelte-2r0xqp"); + attr(div, "class", "bepis svelte-1d9zqg3"); }, m(target, anchor) { insert(target, div, anchor); @@ -23076,7 +23238,7 @@ const _DOMParser = DOMParser; t2 = space(); div = element("div"); if_block.c(); - attr(div, "class", "newsbox svelte-2r0xqp"); + attr(div, "class", "newsbox svelte-1d9zqg3"); }, m(target, anchor) { insert(target, p, anchor); diff --git a/package-lock.json b/package-lock.json index 6973013..036d179 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,9 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "base58": "^2.0.1", "blockhash": "^0.2.0", + "bs58": "^5.0.0", "buffer": "^6.0.3", "crc-32": "^1.2.0", "events": "^3.3.0", @@ -1792,6 +1794,19 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base-x": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" + }, + "node_modules/base58": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/base58/-/base58-2.0.1.tgz", + "integrity": "sha512-qK6gt2fMSxN2xGOi+btI5oAnXL+vEq0AsHWHhf5jfm2hE6MwmW+2414qF96utV3Xfg3En8hEA9Q4lif4lbXcgw==", + "engines": { + "node": ">= 6" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -1990,6 +2005,14 @@ "url": "https://opencollective.com/browserslist" } }, + "node_modules/bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "dependencies": { + "base-x": "^4.0.0" + } + }, "node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", @@ -10613,6 +10636,16 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "base-x": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" + }, + "base58": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/base58/-/base58-2.0.1.tgz", + "integrity": "sha512-qK6gt2fMSxN2xGOi+btI5oAnXL+vEq0AsHWHhf5jfm2hE6MwmW+2414qF96utV3Xfg3En8hEA9Q4lif4lbXcgw==" + }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -10747,6 +10780,14 @@ "picocolors": "^1.0.0" } }, + "bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "requires": { + "base-x": "^4.0.0" + } + }, "buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", diff --git a/package.json b/package.json index 7155168..1063816 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,9 @@ "author": "", "license": "ISC", "dependencies": { + "base58": "^2.0.1", "blockhash": "^0.2.0", + "bs58": "^5.0.0", "buffer": "^6.0.3", "crc-32": "^1.2.0", "events": "^3.3.0", diff --git a/src/Components/App.svelte b/src/Components/App.svelte index 17a3ef9..339d921 100644 --- a/src/Components/App.svelte +++ b/src/Components/App.svelte @@ -110,6 +110,7 @@

PEE Settings 0.{rev}

+

Join us on 2chen!


@@ -441,7 +442,13 @@ h1 { text-align: center; + margin-bottom: 0; } + + h4 { + margin: 0; + } + .form { display: flex; flex-direction: column; diff --git a/src/f5stego.ts b/src/f5stego.ts new file mode 100644 index 0000000..f75d51a --- /dev/null +++ b/src/f5stego.ts @@ -0,0 +1,1758 @@ +/* This software is licensed under the MIT License. + + Copyright (c) 2016 desudesutalk + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + https://github.com/desudesutalk/f5stegojs + + This library is based on https://github.com/owencm/js-steg by Owen Campbell- + Moore. Decoder and encoder was optimized for speed, F5 algorithm and metadata + manipulation utils was added to library. + + Original code was released under MIT and Apache licenses, so here follows + original licenses of Owen code: + + jpeg decoder license: + + Modified JPEG decoder for Steganography by Owen Campbell-Moore, based on one + released by Adobe. + + Copyright 2011 notmasteryet + + Licensed under the Apache License, Version 2.0 (the "License"); you may not use + this file except in compliance with the License. You may obtain a copy of the + License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed + under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. See the License for the + specific language governing permissions and limitations under the License. + + + jpeg encoder license: + + JPEG encoder ported to JavaScript, optimized by Andreas Ritter + (www.bytestrom.eu, 11/2009) and made suitable for steganography by Owen + Campbell-Moore (www.owencampbellmoore.com, 03/13) + + Based on v 0.9a + + Licensed under the MIT License + + Copyright (c) 2009 Andreas Ritter + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Copyright (c) 2008, Adobe Systems Incorporated All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list + of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + + Neither the name of Adobe Systems Incorporated nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* global define, module, exports */ +/* jshint sub:true */ + + + +// Standard Huffman tables for coder initialization +// =========================================================================================================== +var bitcode = new Array(65535), + category = new Array(65535), + std_dc_luminance_nrcodes = [0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], + std_dc_luminance_values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], + std_ac_luminance_nrcodes = [0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d], + std_ac_luminance_values = [ + 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa + ], + std_dc_chrominance_nrcodes = [0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], + std_dc_chrominance_values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], + std_ac_chrominance_nrcodes = [0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77], + std_ac_chrominance_values = [ + 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa + ]; + +function _initCategoryNumber() { + var nrlower = 1; + var nrupper = 2; + for (var cat = 1; cat <= 15; cat++) { + //Positive numbers + for (var nr = nrlower; nr < nrupper; nr++) { + category[32767 + nr] = cat; + bitcode[32767 + nr] = []; + bitcode[32767 + nr][1] = cat; + bitcode[32767 + nr][0] = nr; + } + //Negative numbers + for (var nrneg = -(nrupper - 1); nrneg <= -nrlower; nrneg++) { + category[32767 + nrneg] = cat; + bitcode[32767 + nrneg] = []; + bitcode[32767 + nrneg][1] = cat; + bitcode[32767 + nrneg][0] = nrupper - 1 + nrneg; + } + nrlower <<= 1; + nrupper <<= 1; + } +} + +_initCategoryNumber(); + +function _computeHuffmanTbl(nrcodes: number[], std_table: number[]) { + var codevalue = 0; + var pos_in_table = 0; + var HT: number[][] = []; + for (var k = 1; k <= 16; k++) { + for (var j = 1; j <= nrcodes[k]; j++) { + HT[std_table[pos_in_table]] = []; + HT[std_table[pos_in_table]][0] = codevalue; + HT[std_table[pos_in_table]][1] = k; + pos_in_table++; + codevalue++; + } + codevalue *= 2; + } + return HT; +} + +const YDC_HT = _computeHuffmanTbl(std_dc_luminance_nrcodes, std_dc_luminance_values), + UVDC_HT = _computeHuffmanTbl(std_dc_chrominance_nrcodes, std_dc_chrominance_values), + YAC_HT = _computeHuffmanTbl(std_ac_luminance_nrcodes, std_ac_luminance_values), + UVAC_HT = _computeHuffmanTbl(std_ac_chrominance_nrcodes, std_ac_chrominance_values); + + +type FrameComponentType = { + componentId: number, + h: number, + v: number, + quantizationTable: number; + huffmanTableDC?: Uint16Array; + huffmanTableAC?: Uint16Array; +} | { + componentId: number, + blocks: Int16Array, + blocksDC: Int16Array; + blocksPerLine: number; + blocksPerColumn: number; + blocksPerLineForMcu: number; + blocksPerColumnForMcu: number; + h: number, + v: number, + quantizationTable: number + huffmanTableDC: Uint16Array; + huffmanTableAC: Uint16Array; + pred: number; +}; + +type DiscriminateUnion = T extends Record ? T : never; + +type FrameType = { + extended: boolean, + progressive: boolean, + precision: number, + scanLines: number, + samplesPerLine: number, + components: (FrameComponentType)[]; + mcusPerLine?: number, + mcusPerColumn?: number, + componentIds: Record, + maxH: number, + maxV: number +}; + +export class f5stego { + #randPool!: ArrayBuffer; + + constructor(key: ArrayLike, private maxPixels: number = 4096 * 4096) { + this.#shuffleInit(key); + }; + + embed(image: Uint8Array, data: ArrayLike, k?: number) { + this.parse(image); + this.f5put(data, k); + return this.pack(); + }; + + extract(image: Uint8Array) { + this.parse(image, true); + return this.f5get(); + }; + + #_raw?: Uint8Array; + #jfif?: any; + #APPn?: any; + #qts?: any[]; + + #frame: FrameType | null = null; + + #tail: Uint8Array | null = null; + + #shuffleInit(key: ArrayLike) { + this.#randPool = new ArrayBuffer(this.maxPixels * 4.125); + + if (!key.length) throw 'key needed'; + + var i = 0, + j = 0, + t = 0, + k = 0, + S = new Uint8Array(256), + rnd = new Uint8Array(this.#randPool); + + // init state from key + for (i = 0; i < 256; ++i) S[i] = i; + + for (i = 0; i < 256; ++i) { + j = (j + S[i] + key[i % key.length]) & 255; + t = S[i]; + S[i] = S[j]; + S[j] = t; + } + i = 0; + j = 0; + + // shuffle data + for (k = 0; k < this.maxPixels * 4.125; ++k) { + i = (i + 1) & 255; + j = (j + S[i]) & 255; + t = S[i]; + S[i] = S[j]; + S[j] = t; + rnd[k] = S[(t + S[i]) & 255]; + } + } + + #stegShuffle(pm: number | Uint32Array | Int16Array) { + let t, l, k, random_index, rand32Array = new Uint32Array(this.#randPool); + + if (typeof pm == 'number') { + l = pm; + pm = new Uint32Array(l); + for (k = 1; k < l; k++) { + random_index = rand32Array[k] % (k + 1); + if (random_index != k) pm[k] = pm[random_index]; + pm[random_index] = k; + } + } else { + l = pm.length; + for (k = 1; k < l; k++) { + random_index = rand32Array[k] % (k + 1); + // if (random_index != k) { + t = pm[k]; + pm[k] = pm[random_index]; + pm[random_index] = t; + // } + } + } + return { pm: pm, gamma: new Uint8Array(this.#randPool, l * 4) }; + } + + #_analyze(coeff: Int16Array) { + var _one = 0, + _zero = 0, + _large, _ratio, usable, i, k, embedded, matched, changed; + + for (i = 0; i < coeff.length; i++) { + if (i % 64 === 0) continue; + if (coeff[i] === 0) _zero++; + if (coeff[i] == 1 || coeff[i] == -1) _one++; + } + + _large = coeff.length - _zero - _one - coeff.length / 64; + _ratio = _one / (_large + _one); + + var res = { + 'capacity': [0, ((_large + (0.49 * _one)) >> 3) - 1], + 'coeff_total': coeff.length, + 'coeff_large': _large, + 'coeff_zero': _zero, + 'coeff_one': _one, + 'coeff_one_ratio': _one / (_large + _one) + }; + + for (i = 2; i < 17; i++) { + k = (1 << i) - 1; + usable = _large + _one; + embedded = 0; + while (usable > k) { + matched = (usable / k / (1 << i) / (1 << i)) | 0; + usable -= matched * k; + + changed = (usable * (1 - _ratio) / k * 0.96) | 0; + usable -= changed * k; + embedded += changed + matched; + + k++; + } + res.capacity[i] = ((i * embedded) >> 3) - 1; + } + + return res; + } + + #_f5write(coeff: Int16Array, data: ArrayLike, k: number) { + var coeff_count = coeff.length; + + var _changed = 0, + _embedded = 0, + _examined = 0, + _thrown = 0, + shuffled_index = 0, + i, n, ii; + + //let { gamma, pm } = this.#stegShuffle(coeff_count); + //let gammaI = 0; + + var next_bit_to_embed = 0, + byte_to_embed = data.length, + data_idx = 0, + available_bits_to_embed = 0; + + n = (1 << k) - 1; + + byte_to_embed = k - 1; + byte_to_embed ^= 0; // nop + //byte_to_embed ^= gamma[gammaI++]; + next_bit_to_embed = byte_to_embed & 1; + byte_to_embed >>= 1; + available_bits_to_embed = 3; + + for (ii = 0; ii < coeff_count; ii++) { + //shuffled_index = pm[ii]; + shuffled_index = ii; + + if (shuffled_index % 64 === 0 || coeff[shuffled_index] === 0) continue; + + var cc = coeff[shuffled_index]; + _examined++; + + if (cc > 0 && (cc & 1) != next_bit_to_embed) { + coeff[shuffled_index]--; + _changed++; + } else if (cc < 0 && (cc & 1) == next_bit_to_embed) { + coeff[shuffled_index]++; + _changed++; + } + + if (coeff[shuffled_index] !== 0) { + _embedded++; + if (available_bits_to_embed === 0) { + if (k != 1 || data_idx >= data.length) break; + byte_to_embed = data[data_idx++]; + //byte_to_embed ^= gamma[gammaI++]; + byte_to_embed ^= 0; // nop + available_bits_to_embed = 8; + } + next_bit_to_embed = byte_to_embed & 1; + byte_to_embed >>= 1; + available_bits_to_embed--; + } else { + _thrown++; + } + } + + if (k == 1 && _embedded < data.length * 8) throw 'capacity exceeded ' + (_embedded / 8) + ' ' + data.length; + + if (k != 1) { + //ii--; + var is_last_byte = false, + k_bits_to_embed = 0; + + while (!is_last_byte || (available_bits_to_embed !== 0 && is_last_byte)) { + k_bits_to_embed = 0; + + for (i = 0; i < k; i++) { + if (available_bits_to_embed === 0) { + if (data_idx >= data.length) { + is_last_byte = true; + break; + } + byte_to_embed = data[data_idx++]; + //byte_to_embed ^= gamma[gammaI++]; + byte_to_embed ^= 0; // nop + available_bits_to_embed = 8; + } + next_bit_to_embed = byte_to_embed & 1; + byte_to_embed >>= 1; + available_bits_to_embed--; + k_bits_to_embed |= next_bit_to_embed << i; + + } + + var code_word = []; + var ci = null; + + for (i = 0; i < n; i++) { + while (true) { + if (++ii >= coeff_count) { + throw 'capacity exceeded ' + (_embedded / 8); + } + //ci = pm[ii]; + ci = ii; + + if (ci % 64 !== 0 && coeff[ci] !== 0) break; + } + code_word.push(ci); + } + _examined += n; + + while (true) { + var vhash = 0, + extracted_bit; + + for (i = 0; i < code_word.length; i++) { + if (coeff[code_word[i]] > 0) { + extracted_bit = coeff[code_word[i]] & 1; + } else { + extracted_bit = 1 - (coeff[code_word[i]] & 1); + } + + if (extracted_bit == 1) + vhash ^= i + 1; + } + + i = vhash ^ k_bits_to_embed; + if (!i) { + _embedded += k; + break; + } + + i--; + coeff[code_word[i]] += coeff[code_word[i]] < 0 ? 1 : -1; + _changed++; + + if (coeff[code_word[i]] === 0) { + _thrown++; + code_word.splice(i, 1); + + while (true) { + if (++ii >= coeff_count) { + throw 'capacity exceeded ' + (_embedded / 8); + } + //ci = pm[ii]; + ci = ii; + if (ci % 64 !== 0 && coeff[ci] !== 0) break; + + } + _examined++; + code_word.push(ci); + } else { + _embedded += k; + break; + } + } + } + } + + return { + 'k': k, + 'embedded': _embedded / 8, + 'examined': _examined, + 'changed': _changed, + 'thrown': _thrown, + 'efficiency': (_embedded / _changed).toFixed(2) + }; + } + + analyze() { + if (!this.#frame) + throw "Parser not run"; + var i, comp = this.#frame.components[0]; + + + if (comp.componentId != 1) { + for (i = 0; i < this.#frame.components.length; i++) { + if (this.#frame.components[i].componentId == 1) { + comp = this.#frame.components[i]; + break; + } + } + } + + if (!('blocks' in comp)) { + throw "Blocks failed to be parsed"; + } + + return this.#_analyze(comp.blocks); + }; + + f5put(data: ArrayLike, k?: number) { + if (!this.#frame) + throw "Parser not run"; + var t, i, comp = this.#frame.components[0]; + + // Looks funny, but who knows? + // From the other hand you need ~80MB jpeg to hide 8MB of data and this will be bigger than 4096x4096 pixels + if (data.length > 8388607) throw 'Data too big. Max 8388607 bytes allowed.'; + + if (data.length < 32768) { + t = new Uint8Array(2 + data.length); + t[0] = data.length & 255; + t[1] = data.length >>> 8; + t.set(data, 2); + } else { + t = new Uint8Array(3 + data.length); + t[0] = data.length & 255; + t[1] = ((data.length >>> 8) & 127) + 128; + t[2] = data.length >>> 15; + t.set(data, 3); + } + + if (comp.componentId != 1) { + for (i = 0; i < this.#frame.components.length; i++) { + if (this.#frame.components[i].componentId == 1) { + comp = this.#frame.components[i]; + break; + } + } + } + + if (k) { + if (!('blocks' in comp)) { + throw "Blocks failed to be parsed"; + } + + return this.#_f5write(comp.blocks, t, k); + } + + + if (!('blocks' in comp)) { + throw "Blocks failed to be parsed"; + } + + let ret: { + k: number; + embedded: number; + examined: number; + changed: number; + thrown: number; + efficiency: string; + stats?: { + capacity: number[]; + coeff_total: number; + coeff_large: number; + coeff_zero: number; + coeff_one: number; + coeff_one_ratio: number; + } + }; + + let prop = this.#_analyze(comp.blocks); + + k = 0; + + for (i = prop.capacity.length - 1; i >= 0; i--) { + if (prop.capacity[i] >= t.length) { + k = i; + break; + } + } + + if (k === 0) throw 'capacity exceeded'; + + try { + ret = this.#_f5write(comp.blocks, t, k); + } catch (e) { + k--; + if (k === 0) throw 'capacity exceeded'; + ret = this.#_f5write(comp.blocks, t, k); + } + + ret['stats'] = prop; + + return ret; + } + + f5get() { + if (!this.#frame) + throw "Parser not run"; + var comp = this.#frame.components[0]; + + if (comp.componentId != 1) { + for (var i = 0; i < this.#frame.components.length; i++) { + if (this.#frame.components[i].componentId == 1) { + comp = this.#frame.components[i]; + break; + } + } + } + + if (!('blocks' in comp)) { + throw "Blocks failed to be parsed"; + } + + var coeff = new Int16Array(comp.blocks.length); + coeff.set(comp.blocks); + + var pos = -1, + extrBit = 0, + cCount = coeff.length - 1; + + //var pm = this.#stegShuffle(coeff), + // gamma = pm.gamma, + // gammaI = 0; + + var n, k = 0; + + var out = new Uint8Array((coeff.length / 8) | 0), + extrByte = 0, + outPos = 0, + bitsAvail = 0, + code = 0, + hash = 0; + + while (bitsAvail < 4) { + pos++; + + if (coeff[pos] === 0) { + continue; + } + + extrBit = coeff[pos] & 1; + + + if (coeff[pos] < 0) { + extrBit = 1 - extrBit; + } + + k |= extrBit << bitsAvail; + bitsAvail++; + } + + //k = (k ^ gamma[gammaI++] & 15) + 1; + k = (k & 15) + 1; + n = (1 << k) - 1; + + bitsAvail = 0; + + if (k == 1) { + while (pos < cCount) { + pos++; + + if (coeff[pos] === 0) { + continue; + } + + extrBit = coeff[pos] & 1; + + if (coeff[pos] < 0) { + extrBit = 1 - extrBit; + } + + extrByte |= extrBit << bitsAvail; + bitsAvail++; + + if (bitsAvail == 8) { + out[outPos++] = extrByte; + //out[outPos++] = extrByte ^ gamma[gammaI++]; + extrByte = 0; + bitsAvail = 0; + } + } + } else { + while (pos < cCount) { + pos++; + + if (coeff[pos] === 0) { + continue; + } + + extrBit = coeff[pos] & 1; + + if (coeff[pos] < 0) { + extrBit = 1 - extrBit; + } + + hash ^= extrBit * ++code; + + if (code == n) { + extrByte |= hash << bitsAvail; + bitsAvail += k; + code = 0; + hash = 0; + + while (bitsAvail >= 8) { + //out[outPos++] = (extrByte & 0xFF) ^ gamma[gammaI++]; + out[outPos++] = (extrByte & 0xFF); + bitsAvail -= 8; + extrByte = extrByte >> 8; + } + } + } + } + + while (bitsAvail > 0) { + //out[outPos++] = (extrByte & 0xFF) ^ gamma[gammaI++]; + out[outPos++] = (extrByte & 0xFF); + bitsAvail -= 8; + extrByte = extrByte >> 8; + } + + var s = 2, + l = out[0]; + + if (out[1] & 128) { + s++; + l += ((out[1] & 127) << 8) + (out[2] << 15); + } else { + l += out[1] << 8; + } + + return out.subarray(s, s + l); + } + + + parse(data: Uint8Array, tolerant = false) { + var offset = 0; + + function _buildHuffmanTable(nrcodes: Uint8Array, values: Uint8Array) { + var codevalue = 0, + pos_in_table = 0, + HT = new Uint16Array(65536); + for (var k = 0; k < 16; k++) { + for (var j = 0; j < nrcodes[k]; j++) { + for (var i = codevalue << (15 - k), cntTo = ((codevalue + 1) << (15 - k)); i < cntTo; i++) { + HT[i] = values[pos_in_table] + ((k + 1) << 8); + } + pos_in_table++; + codevalue++; + } + codevalue *= 2; + } + return HT; + } + + function decodeScan(data: ArrayLike, + offset: number, + frame: FrameType, + components: DiscriminateUnion[], + resetInterval: number | undefined, + spectralStart: number, + spectralEnd: number, + successivePrev: number, + successive: number) { + + var startOffset = offset, + bitsData = 0, + bitsCount = 0, + eobrun = 0, + p1 = 1 << successive, /* 1 in the bit position being coded */ + m1 = -1 << successive; /* -1 in the bit position being coded */ + + function decodeBaseline(component: typeof components[0], pos: number) { + while (bitsCount < 16) { + bitsData = (bitsData << 8) + (data[offset] | 0); + bitsCount += 8; + if (data[offset] == 0xFF) offset++; + offset++; + } + var t = component.huffmanTableDC[(bitsData >>> (bitsCount - 16)) & 0xFFFF]; + if (!t) throw "invalid huffman sequence"; + bitsCount -= t >>> 8; + t &= 255; + + var diff = 0; + if (t !== 0) { + while (bitsCount < t) { + bitsData = (bitsData << 8) + data[offset++]; + if ((bitsData & 0xff) == 0xFF) offset++; + bitsCount += 8; + } + diff = (bitsData >>> (bitsCount - t)) & ((1 << t) - 1); + bitsCount -= t; + if (diff < 1 << (t - 1)) diff += (-1 << t) + 1; + } + component.blocksDC[pos >> 6] = (component.pred += diff); + + var k = 1, + s, r; + while (k < 64) { + + while (bitsCount < 16) { + bitsData = (bitsData << 8) + (data[offset] | 0); + bitsCount += 8; + if (data[offset] == 0xFF) offset++; + offset++; + } + s = component.huffmanTableAC![(bitsData >>> (bitsCount - 16)) & 0xFFFF]; + if (!s) throw "invalid huffman sequence"; + bitsCount -= s >>> 8; + r = (s >> 4) & 15; + s &= 15; + + if (s === 0) { + if (r < 15) { + break; + } + k += 16; + continue; + } + k += r; + while (bitsCount < s) { + bitsData = (bitsData << 8) + data[offset++]; + if ((bitsData & 0xff) == 0xFF) offset++; + bitsCount += 8; + } + component.blocks[pos + k] = (bitsData >>> (bitsCount - s)) & ((1 << s) - 1); + bitsCount -= s; + if (component.blocks[pos + k] < 1 << (s - 1)) component.blocks[pos + k] += (-1 << s) + 1; + k++; + } + } + + function decodeDCFirst(component: typeof components[0], pos: number) { + var diff = 0; + while (bitsCount < 16) { + bitsData = (bitsData << 8) + (data[offset] | 0); + bitsCount += 8; + if (data[offset] == 0xFF) offset++; + offset++; + } + var t = component.huffmanTableDC[(bitsData >>> (bitsCount - 16)) & 0xFFFF]; + if (!t) throw "invalid huffman sequence"; + bitsCount -= t >>> 8; + t &= 255; + + if (t !== 0) { + while (bitsCount < t) { + bitsData = (bitsData << 8) + data[offset++]; + if ((bitsData & 0xff) == 0xFF) offset++; + bitsCount += 8; + } + diff = (bitsData >>> (bitsCount - t)) & ((1 << t) - 1); + bitsCount -= t; + if (diff < 1 << (t - 1)) diff += (-1 << t) + 1; + } + component.blocksDC[pos >> 6] = (component.pred += diff << successive); + } + + function decodeDCSuccessive(component: typeof components[0], pos: number) { + if (!bitsCount) { + bitsData = data[offset++]; + if (bitsData == 0xFF) offset++; + bitsCount = 8; + } + component.blocksDC[pos >> 6] |= ((bitsData >>> --bitsCount) & 1) << successive; + } + + if (!frame) + throw "Frame not parsed yet"; + + function decodeACFirst(component: typeof components[0], pos: number) { + if (eobrun > 0) { + eobrun--; + return; + } + + + var k = spectralStart, + s, r; + + while (k <= spectralEnd) { + while (bitsCount < 16) { + bitsData = (bitsData << 8) + (data[offset] | 0); + bitsCount += 8; + if (data[offset] == 0xFF) offset++; + offset++; + } + s = component.huffmanTableAC[(bitsData >>> (bitsCount - 16)) & 0xFFFF]; + if (!s) throw "invalid huffman sequence"; + bitsCount -= s >>> 8; + r = (s >> 4) & 15; + s &= 15; + + if (s === 0) { + if (r != 15) { + eobrun = (1 << r) - 1; + if (r) { + while (bitsCount < r) { + bitsData = (bitsData << 8) + data[offset++]; + if ((bitsData & 0xff) == 0xFF) offset++; + bitsCount += 8; + } + eobrun += (bitsData >>> (bitsCount - r)) & ((1 << r) - 1); + bitsCount -= r; + } + break; + } + k += 16; + continue; + } + + k += r; + while (bitsCount < s) { + bitsData = (bitsData << 8) + data[offset++]; + if ((bitsData & 0xff) == 0xFF) offset++; + bitsCount += 8; + } + component.blocks[pos + k] = (bitsData >>> (bitsCount - s)) & ((1 << s) - 1); + bitsCount -= s; + if (component.blocks[pos + k] < 1 << (s - 1)) component.blocks[pos + k] += (-1 << s) + 1; + component.blocks[pos + k] *= p1; + k++; + } + } + + + function decodeACSuccessive(component: typeof components[0], pos: number) { + var k = spectralStart, + r, s; + if (frame == null) + throw "Frame not defined"; + + if (!eobrun) { + while (k <= spectralEnd) { + while (bitsCount < 16) { + bitsData = (bitsData << 8) + (data[offset] | 0); + bitsCount += 8; + if (data[offset] == 0xFF) offset++; + offset++; + } + s = component.huffmanTableAC[(bitsData >>> (bitsCount - 16)) & 0xFFFF]; + if (!s) throw "invalid huffman sequence"; + bitsCount -= s >>> 8; + r = (s >> 4) & 15; + s &= 15; + + if (s) { + if (s != 1) throw "bad jpeg"; + if (!bitsCount) { + bitsData = data[offset++]; + if (bitsData == 0xFF) offset++; + bitsCount = 8; + } + s = ((bitsData >>> --bitsCount) & 1) ? p1 : m1; + } else { + if (r != 15) { + eobrun = (1 << r); + if (r) { + while (bitsCount < r) { + bitsData = (bitsData << 8) + data[offset++]; + if ((bitsData & 0xff) == 0xFF) offset++; + bitsCount += 8; + } + eobrun += (bitsData >>> (bitsCount - r)) & ((1 << r) - 1); + bitsCount -= r; + } + break; + } + } + + while (k <= spectralEnd) { + if (component.blocks[pos + k]) { + if (!bitsCount) { + bitsData = data[offset++]; + if (bitsData == 0xFF) offset++; + bitsCount = 8; + } + component.blocks[pos + k] += ((bitsData >>> --bitsCount) & 1) * (component.blocks[pos + k] >= 0 ? p1 : m1); + } else { + if (--r < 0) break; + } + k++; + } + + if (s) component.blocks[pos + k] = s; + k++; + } + } + + if (eobrun) { + while (k <= spectralEnd) { + if (component.blocks[pos + k]) { + if (!bitsCount) { + bitsData = data[offset++]; + if (bitsData == 0xFF) offset++; + bitsCount = 8; + } + component.blocks[pos + k] += ((bitsData >>> --bitsCount) & 1) * (component.blocks[pos + k] >= 0 ? p1 : m1); + } + k++; + } + eobrun--; + } + } + + var decodeFn; + + if (frame.progressive) { + if (spectralStart === 0) + decodeFn = successivePrev === 0 ? decodeDCFirst : decodeDCSuccessive; + else + decodeFn = successivePrev === 0 ? decodeACFirst : decodeACSuccessive; + } else { + decodeFn = decodeBaseline; + } + + var marker, mcuExpected, i, j, k, n, mcusPerLine, mcusPerRow, x, y; + + if (components.length == 1) { + mcusPerLine = components[0].blocksPerLine; + mcusPerRow = components[0].blocksPerColumn; + mcuExpected = mcusPerRow * mcusPerLine; + + if (!resetInterval) resetInterval = mcuExpected; + n = resetInterval; + components[0].pred = 0; + eobrun = 0; + + for (y = 0; y < mcusPerRow; y++) { + for (x = 0; x < mcusPerLine; x++) { + if (!n) { + n = resetInterval; + components[0].pred = 0; + eobrun = 0; + + // find marker + offset -= (bitsCount / 8) | 0; + if (data[offset - 1] == 0xFF) offset--; + bitsCount = 0; + marker = (data[offset] << 8) | data[offset + 1]; + + if (marker >= 0xFFD0 && marker <= 0xFFD7) { // RSTx + offset += 2; + } else { + if (marker <= 0xFF00) { + throw "bad jpeg"; + } + break; + } + } + n--; + for (i = 0; i < components.length; i++) { + decodeFn(components[i], (y * components[i].blocksPerLineForMcu + x) * 64); + } + + } + } + } else { + mcusPerLine = frame.mcusPerLine; + mcusPerRow = frame.mcusPerColumn; + mcuExpected = mcusPerRow! * mcusPerLine!; + + if (!resetInterval) resetInterval = mcuExpected; + n = resetInterval; + for (i = 0; i < components.length; i++) components[i].pred = 0; + eobrun = 0; + + for (y = 0; y < mcusPerRow!; y++) { + for (x = 0; x < mcusPerLine!; x++) { + if (!n) { + n = resetInterval; + for (i = 0; i < components.length; i++) components[i].pred = 0; + eobrun = 0; + + // find marker + offset -= (bitsCount / 8) | 0; + if (data[offset - 1] == 0xFF) offset--; + bitsCount = 0; + marker = (data[offset] << 8) | data[offset + 1]; + + if (marker >= 0xFFD0 && marker <= 0xFFD7) { // RSTx + offset += 2; + } else { + if (marker <= 0xFF00) { + throw "bad jpeg"; + } + break; + } + } + n--; + for (i = 0; i < components.length; i++) { + for (j = 0; j < components[i].v; j++) { + for (k = 0; k < components[i].h; k++) { + decodeFn(components[i], ((y * components[i].v + j) * components[i].blocksPerLineForMcu + x * components[i].h + k) * 64); + } + } + } + } + } + } + offset -= (bitsCount / 8) | 0; + if (data[offset - 1] == 0xFF) offset--; + return offset - startOffset; + } + + function readUint16() { + var value = (data[offset] << 8) | data[offset + 1]; + offset += 2; + return value; + } + + function readDataBlock() { + var length = readUint16(); + var array = data.subarray(offset, offset + length - 2); + offset += array.length; + return array; + } + + this.#_raw = data; + this.#jfif = null; + this.#APPn = []; + this.#qts = []; + this.#frame = null; + this.#tail = null; + + var markerHi, markerLo, i, j, resetInterval, component; + let huffmanTablesAC: Uint16Array[] = []; + let huffmanTablesDC: Uint16Array[] = []; + + while (1) { + if (offset >= data.length) { + if (tolerant) break; + throw "unexpected EOF"; + } + + markerHi = data[offset++]; + markerLo = data[offset++]; + + if (markerHi == 0xFF) { + if (markerLo == 0xE0) { //APP0 - JFIF header + this.#jfif = readDataBlock(); + } + + if ((markerLo > 0xE0 && markerLo < 0xF0) || markerLo == 0xFE) { //APPn + COM + this.#APPn.push({ + 'app': markerLo, + 'data': readDataBlock() + }); + } + + if (markerLo == 0xDB) { // DQT (Define Quantization Tables) + this.#qts.push(readDataBlock()); + } + + if (markerLo >= 0xC0 && markerLo <= 0xC2) { + // SOF0 (Start of Frame, Baseline DCT) + // SOF1 (Start of Frame, Extended DCT) + // SOF2 (Start of Frame, Progressive DCT) + if (this.#frame) throw "Only single frame JPEGs supported"; + readUint16(); // skip data length + + this.#frame = { + 'extended': (markerLo === 0xC1), + 'progressive': (markerLo === 0xC2), + 'precision': data[offset++], + 'scanLines': readUint16(), + 'samplesPerLine': readUint16(), + 'components': [], + 'componentIds': {}, + 'maxH': 1, + 'maxV': 1 + }; + + if (this.#frame.scanLines * this.#frame.samplesPerLine > this.maxPixels) throw "Image is too big."; + + var componentsCount = data[offset++], + componentId; + var maxH = 0, + maxV = 0; + for (i = 0; i < componentsCount; i++) { + componentId = data[offset]; + var h = data[offset + 1] >> 4; + var v = data[offset + 1] & 15; + if (maxH < h) maxH = h; + if (maxV < v) maxV = v; + var qId = data[offset + 2]; + var l = this.#frame.components.push({ + componentId: componentId, + h, + v, + quantizationTable: qId + }); + this.#frame.componentIds[componentId] = l - 1; + offset += 3; + } + this.#frame.maxH = maxH; + this.#frame.maxV = maxV; + + var mcusPerLine = Math.ceil(this.#frame.samplesPerLine / 8 / maxH); + var mcusPerColumn = Math.ceil(this.#frame.scanLines / 8 / maxV); + for (i = 0; i < this.#frame.components.length; i++) { + component = this.#frame.components[i]; + var blocksPerLine = Math.ceil(Math.ceil(this.#frame.samplesPerLine / 8) * component.h / maxH); + var blocksPerColumn = Math.ceil(Math.ceil(this.#frame.scanLines / 8) * component.v / maxV); + var blocksPerLineForMcu = mcusPerLine * component.h; + var blocksPerColumnForMcu = mcusPerColumn * component.v; + + this.#frame.components[i] = { + ...component, + blocks: new Int16Array(blocksPerColumnForMcu * blocksPerLineForMcu * 64), + blocksDC: new Int16Array(blocksPerColumnForMcu * blocksPerLineForMcu), + blocksPerLine: blocksPerLine, + blocksPerColumn: blocksPerColumn, + blocksPerLineForMcu: blocksPerLineForMcu, + blocksPerColumnForMcu: blocksPerColumnForMcu, + }; + } + this.#frame.mcusPerLine = mcusPerLine; + this.#frame.mcusPerColumn = mcusPerColumn; + } + + if (markerLo == 0xC4) { // DHT (Define Huffman Tables) + var huffmanLength = readUint16(); + for (i = 2; i < huffmanLength;) { + var huffmanTableSpec = data[offset++]; + var codeLengths = new Uint8Array(16); + var codeLengthSum = 0; + for (j = 0; j < 16; j++, offset++) + codeLengthSum += (codeLengths[j] = data[offset]); + var huffmanValues = new Uint8Array(codeLengthSum); + for (j = 0; j < codeLengthSum; j++, offset++) + huffmanValues[j] = data[offset]; + i += 17 + codeLengthSum; + const v = _buildHuffmanTable(codeLengths, huffmanValues); + if ((huffmanTableSpec >> 4) === 0) + huffmanTablesDC[huffmanTableSpec & 15] = v; + else + huffmanTablesAC[huffmanTableSpec & 15] = v; + } + } + + if (markerLo == 0xDD) { // DRI (Define Restart Interval) + resetInterval = readUint16(); + } + + if (markerLo == 0xDA) { // SOS (Start of Scan) + if (this.#frame == null) + throw "SOS before SOF"; + readUint16(); + var selectorsCount = data[offset++]; + var components = []; + + for (i = 0; i < selectorsCount; i++) { + var componentIndex = this.#frame.componentIds[data[offset++]]; + component = this.#frame.components[componentIndex]; + var tableSpec = data[offset++]; + component.huffmanTableDC = huffmanTablesDC[tableSpec >> 4]; + component.huffmanTableAC = huffmanTablesAC[tableSpec & 15]; + components.push(component); + } + + var spectralStart = data[offset++]; + var spectralEnd = data[offset++]; + var successiveApproximation = data[offset++]; + var processed = decodeScan(data, offset, + this.#frame, components as any, resetInterval, + spectralStart, spectralEnd, + successiveApproximation >> 4, successiveApproximation & 15); + offset += processed; + } + + if (markerLo == 0xD9) { // EOI (End of image) + break; + } + } else { + if (data[offset - 3] == 0xFF && + data[offset - 2] >= 0xC0 && data[offset - 2] <= 0xFE) { + // could be incorrect encoding -- last 0xFF byte of the previous + // block was eaten by the encoder + offset -= 3; + } + while (data[offset] != 0xFF && offset < data.length) { + // file could be damaged and have some extra data between blocks + offset++; + } + + if (data[offset] != 0xFF) { + throw "bad jpeg "; + } + } + } + + if (!this.#frame) throw 'bad jpeg'; + + if (offset < data.length) this.#tail = data.subarray(offset); + + return this; + }; + + pack() { + let byteout: Uint8Array; + let bytenew: number; + let bytepos: number; + let poslast: number; + let outpos: number; + let byte: number; + + // IO functions + function writeByte(value: number) { + var t; + + byteout[outpos++] = value; + if (outpos > poslast) { + t = new Uint8Array(byteout.length * 2); + t.set(byteout); + byteout = t; + poslast = t.length - 128; + } + } + + function writeWord(value: number) { + writeByte((value >> 8) & 0xFF); + writeByte((value) & 0xFF); + } + + function writeBlock(block: Uint8Array) { + var t; + if (outpos + block.length > poslast) { + t = new Uint8Array(byteout.length * 2 + block.length); + t.set(byteout); + byteout = t; + poslast = t.length - 128; + } + + byteout.set(block, outpos); + outpos += block.length; + } + + function writeAPP0(self: f5stego) { + writeWord(0xFFE0); // marker + if (!self.#jfif) { + writeWord(16); // length + writeByte(0x4A); // J + writeByte(0x46); // F + writeByte(0x49); // I + writeByte(0x46); // F + writeByte(0); // = "JFIF",'\0' + writeByte(1); // versionhi + writeByte(1); // versionlo + writeByte(0); // xyunits + writeWord(1); // xdensity + writeWord(1); // ydensity + writeByte(0); // thumbnwidth + writeByte(0); // thumbnheight + } else { + writeWord(self.#jfif.length + 2); // length + writeBlock(self.#jfif); + } + } + + function writeDQT(self: f5stego) { + for (var i = 0; i < self.#qts!.length; i++) { + writeWord(0xFFDB); // marker + writeWord(self.#qts![i].length + 2); // length + writeBlock(self.#qts![i]); + } + } + + function writeAPPn(self: f5stego) { + for (var i = 0; i < self.#APPn.length; i++) { + writeWord(0xFF00 | self.#APPn[i].app); + writeWord(self.#APPn[i].data.length + 2); + writeBlock(self.#APPn[i].data); + } + } + + function writeSOF0(self: f5stego) { + if (!self.#frame) + throw "Frame not ready"; + writeWord(0xFFC0); // marker + writeWord(8 + self.#frame.components.length * 3); // length + writeByte(self.#frame.precision); // precision + writeWord(self.#frame.scanLines); + writeWord(self.#frame.samplesPerLine); + writeByte(self.#frame.components.length); // nrofcomponents + + for (var i = 0; i < self.#frame.components.length; i++) { + var c = self.#frame.components[i]; + writeByte(c.componentId); + writeByte(c.h << 4 | c.v); + writeByte(c.quantizationTable); + } + } + + function writeDHT(self: f5stego) { + if (!self.#frame) + throw "Frame not ready"; + + writeWord(0xFFC4); // marker + writeWord(31); // length + writeByte(0); // HTYDCinfo + for (var i = 0; i < 16; i++) { + writeByte(std_dc_luminance_nrcodes[i + 1]); + } + for (var j = 0; j <= 11; j++) { + writeByte(std_dc_luminance_values[j]); + } + + writeWord(0xFFC4); // marker + writeWord(181); // length + writeByte(0x10); // HTYACinfo + for (var k = 0; k < 16; k++) { + writeByte(std_ac_luminance_nrcodes[k + 1]); + } + for (var l = 0; l <= 161; l++) { + writeByte(std_ac_luminance_values[l]); + } + + if (self.#frame.components.length != 1) { + writeWord(0xFFC4); // marker + writeWord(31); // length + writeByte(1); // HTUDCinfo + for (var m = 0; m < 16; m++) { + writeByte(std_dc_chrominance_nrcodes[m + 1]); + } + for (var n = 0; n <= 11; n++) { + writeByte(std_dc_chrominance_values[n]); + } + + writeWord(0xFFC4); // marker + writeWord(181); // length + writeByte(0x11); // HTUACinfo + for (var o = 0; o < 16; o++) { + writeByte(std_ac_chrominance_nrcodes[o + 1]); + } + for (var p = 0; p <= 161; p++) { + writeByte(std_ac_chrominance_values[p]); + } + } + } + + function writeSOS(self: f5stego) { + if (!self.#frame) + throw "Frame not ready"; + + writeWord(0xFFDA); // marker + writeWord(6 + self.#frame.components.length * 2); // length + writeByte(self.#frame.components.length); // nrofcomponents + + for (var i = 0; i < self.#frame.components.length; i++) { + var c = self.#frame.components[i]; + writeByte(c.componentId); + if (i === 0) { + writeByte(0); + } else { + writeByte(0x11); + } + } + + writeByte(0); // Ss + writeByte(0x3f); // Se + writeByte(0); // Bf + } + + function processDU(comp: FrameComponentType, POS: number, DC: number, HTDC: number[][], HTAC: number[][]) { + var pos, posval, t; + + if (bytepos === 0) bytenew = 0; + + if (!('blocks' in comp)) + throw "Blocks not parsed"; + + var Diff = comp.blocksDC[POS >> 6] - DC; + DC = comp.blocksDC[POS >> 6]; + //Encode DC + if (Diff === 0) { + posval = HTDC[0][1]; + + bytenew <<= posval; + bytenew += HTDC[0][0]; + bytepos += posval; + + while (bytepos > 7) { + byte = 0xFF & (bytenew >>> (bytepos - 8)); + byteout[outpos++] = byte; + if (byte == 0xFF) { + outpos++; + } + bytepos -= 8; + bytenew &= (1 << bytepos) - 1; + } + + } else { + pos = 32767 + Diff; + + posval = HTDC[category[pos]][1]; + bytenew <<= posval; + bytenew += HTDC[category[pos]][0]; + bytepos += posval; + + posval = bitcode[pos][1]; + bytenew <<= posval; + bytenew += bitcode[pos][0]; + bytepos += posval; + + while (bytepos > 7) { + byte = 0xFF & (bytenew >>> (bytepos - 8)); + byteout[outpos++] = byte; + if (byte == 0xFF) { + outpos++; + } + bytepos -= 8; + bytenew &= (1 << bytepos) - 1; + } + } + //Encode ACs + var end0pos = 63; // was const... which is crazy + for (; + (end0pos > 0) && (comp.blocks[POS + end0pos] === 0); end0pos--) { } + //end0pos = first element in reverse order !=0 + if (end0pos === 0) { + posval = HTAC[0x00][1]; + bytenew <<= posval; + bytenew += HTAC[0x00][0]; + bytepos += posval; + + while (bytepos > 7) { + byte = 0xFF & (bytenew >>> (bytepos - 8)); + byteout[outpos++] = byte; + if (byte == 0xFF) { + outpos++; + } + bytepos -= 8; + bytenew &= (1 << bytepos) - 1; + } + return DC; + } + var i = 1; + var lng; + while (i <= end0pos) { + var startpos = i; + for (; + (comp.blocks[POS + i] === 0) && (i <= end0pos); ++i) { } + var nrzeroes = i - startpos; + if (nrzeroes >= 16) { + lng = nrzeroes >> 4; + for (var nrmarker = 1; nrmarker <= lng; ++nrmarker) { + posval = HTAC[0xF0][1]; + bytenew <<= posval; + bytenew += HTAC[0xF0][0]; + bytepos += posval; + + while (bytepos > 7) { + byte = 0xFF & (bytenew >>> (bytepos - 8)); + byteout[outpos++] = byte; + if (byte == 0xFF) { + outpos++; + } + bytepos -= 8; + bytenew &= (1 << bytepos) - 1; + } + } + nrzeroes = nrzeroes & 0xF; + } + pos = 32767 + comp.blocks[POS + i]; + + posval = HTAC[(nrzeroes << 4) + category[pos]][1]; + bytenew <<= posval; + bytenew += HTAC[(nrzeroes << 4) + category[pos]][0]; + bytepos += posval; + + while (bytepos > 7) { + byte = 0xFF & (bytenew >>> (bytepos - 8)); + byteout[outpos++] = byte; + if (byte == 0xFF) { + outpos++; + } + bytepos -= 8; + bytenew &= (1 << bytepos) - 1; + } + + posval = bitcode[pos][1]; + bytenew <<= posval; + bytenew += bitcode[pos][0]; + bytepos += posval; + + while (bytepos > 7) { + byte = 0xFF & (bytenew >>> (bytepos - 8)); + byteout[outpos++] = byte; + if (byte == 0xFF) { + outpos++; + } + bytepos -= 8; + bytenew &= (1 << bytepos) - 1; + } + i++; + } + if (end0pos != 63) { + posval = HTAC[0x00][1]; + bytenew <<= posval; + bytenew += HTAC[0x00][0]; + bytepos += posval; + + while (bytepos > 7) { + byte = 0xFF & (bytenew >>> (bytepos - 8)); + byteout[outpos++] = byte; + if (byte == 0xFF) { + outpos++; + } + bytepos -= 8; + bytenew &= (1 << bytepos) - 1; + } + } + + if (outpos > poslast) { + t = new Uint8Array(byteout.length * 2); + t.set(byteout); + byteout = t; + poslast = t.length - 128; + } + + return DC; + } + + // Initialize bit writer + byteout = new Uint8Array(65536); + poslast = 65536 - 128; + outpos = 0; + bytenew = 0; + bytepos = 0; + + // Add JPEG headers + writeWord(0xFFD8); // SOI + writeAPP0(this); + writeAPPn(this); + writeDQT(this); + writeSOF0(this); + writeDHT(this); + writeSOS(this); + + bytenew = 0; + bytepos = 0; + + if (!this.#frame) + throw "Frame not ready"; + + var c, mcuRow, mcuCol, blockRow, blockCol, mcu, i, v, h; + + var DCdiff = []; + for (i = 0; i < this.#frame.components.length; i++) { + DCdiff.push(0); + } + + for (mcu = 0; mcu < this.#frame.mcusPerLine! * this.#frame.mcusPerColumn!; mcu++) { + mcuRow = (mcu / this.#frame.mcusPerLine!) | 0; + mcuCol = mcu % this.#frame.mcusPerLine!; + for (i = 0; i < this.#frame.components.length; i++) { + c = this.#frame.components[i]; + for (v = 0; v < c.v; v++) { + blockRow = mcuRow * c.v + v; + for (h = 0; h < c.h; h++) { + blockCol = mcuCol * c.h + h; + if (i === 0) { + DCdiff[i] = processDU(c, (blockRow * this.#frame.mcusPerLine! * c.h + blockCol) * 64, DCdiff[i], YDC_HT, YAC_HT); + } else { + DCdiff[i] = processDU(c, (blockRow * this.#frame.mcusPerLine! * c.h + blockCol) * 64, DCdiff[i], UVDC_HT, UVAC_HT); + } + } + } + } + } + + // Write last bytes from coder + while (bytepos > 7) { + byte = 0xFF & (bytenew >>> (bytepos - 8)); + byteout[outpos++] = byte; + if (byte == 0xFF) { + outpos++; + } + bytepos -= 8; + } + // And do the bit alignment of the EOI marker + if (bytepos > 0) { + bytenew <<= 8 - bytepos; + bytenew += (1 << (8 - bytepos)) - 1; + byteout[outpos++] = 0xFF & bytenew; + } + + writeWord(0xFFD9); //EOI + if (this.#tail) writeBlock(this.#tail); + + return byteout.slice(0, outpos); + }; + +} diff --git a/src/pngv3.ts b/src/pngv3.ts index dcaa0a0..da4d55e 100644 --- a/src/pngv3.ts +++ b/src/pngv3.ts @@ -4,6 +4,7 @@ import { PNGDecoder, PNGEncoder } from "./png"; import { decodeCoom3Payload } from "./utils"; import { settings } from "./stores"; import { filehosts } from "./filehosts"; +import * as bs58 from 'bs58'; export let csettings: Parameters[0]; @@ -87,22 +88,26 @@ const extract = async (png: Buffer) => { if (w = [CUM6, CUM7].find(e => buff.slice(4, 4 + e.length).equals(e))) { const passed = buff.slice(4 + w.length); if (!passed.toString().match(/^[0-9a-zA-Z+/=]+$/g)) continue; - try { - const decoded = Buffer - .from(passed.toString(), 'base64') - .toString() - .split(' ') - .map(e => { - if (!(e[0] in rprefs)) - throw "Uhh"; - // should also check if the id has a len of 6-8 or ends in .pee - return `https://${rprefs[e[0]]}/${e.slice(1)}`; - }).join(' '); - const k = await decodeCoom3Payload(Buffer.from(decoded)); - ret.push(...k.filter(e => e).map(e => e as EmbeddedFile)); - } finally { - // + const decoders = [(b: Buffer) => Buffer + .from(b.toString(), 'base64').toString(), + (b: Buffer) => Buffer.from(bs58.decode(passed.toString())).toString()]; + for (const d of decoders) { + try { + const decoded = d(passed) + .split(' ') + .map(e => { + if (!(e[0] in rprefs)) + throw "Uhh"; + // should also check if the id has a len of 6-8 or ends in .pee + return `https://${rprefs[e[0]]}/${e.slice(1)}`; + }).join(' '); + const k = await decodeCoom3Payload(Buffer.from(decoded)); + ret.push(...k.filter(e => e).map(e => e as EmbeddedFile)); + } catch(e) { + // + } } + } break; case 'IDAT': @@ -173,7 +178,7 @@ const inject = async (container: File, links: string[]) => { } return ''; }); - const injb = Buffer.from(Buffer.from(links.join(' ')).toString("base64")); + const injb = Buffer.from(bs58.encode(Buffer.from(links.join(' ')))); return inject_data(container, injb); }; @@ -203,8 +208,11 @@ const has_embed = async (png: Buffer) => { if (buff.slice(4, 4 + CUM7.length).equals(CUM7)) { const passed = buff.slice(4 + CUM7.length).toString(); if (passed.match(/^[0-9a-zA-Z+/=]+$/g)) { + // base 58 is a subset of base64 so test that first if (Buffer.from(passed, "base64").toString().split(" ").every(l => l[0] in rprefs)) return true; + if (Buffer.from(bs58.decode(passed)).toString().split(" ").every(l => l[0] in rprefs)) + return true; } } break; diff --git a/src/stores.ts b/src/stores.ts index 3b5a419..d7fbf51 100644 --- a/src/stores.ts +++ b/src/stores.ts @@ -40,7 +40,7 @@ export const initial_settings = localLoad('settingsv2', { maxe: 5, conc: 8, ho: false, - blacklist: [], + blacklist: [] as string[], rsources: [] as (Omit & {view: string, disabled?: boolean})[], ...localLoad('settingsv2', {}), });