Browse Source

Preliminary third-eye integration

pull/46/head
coomdev 2 years ago
parent
commit
113def4ef0
  1. 16
      build.js
  2. 1
      main.d.ts
  3. 2
      main.meta.js
  4. 23119
      main.user.js
  5. 180
      package-lock.json
  6. 12
      package.json
  7. 114
      src/App.svelte
  8. 81
      src/Embedding.svelte
  9. 2
      src/SettingsButton.svelte
  10. 16
      src/gif.ts
  11. 70
      src/main.ts
  12. 24
      src/png.ts
  13. 11
      src/stores.ts
  14. 138
      src/thirdeye.ts
  15. 15
      src/webm.ts
  16. 4
      tsconfig.json

16
build.js

@ -29,20 +29,7 @@ const extheader = `// ==UserScript==
`;
(async () => {
let res;/*
res = await esbuild.build({
entryPoints: ['src/main.ts'],
bundle: true,
outfile: 'dist/main.js',
define: {
global: 'window'
},
inject: ['./esbuild.inject.js'],
metafile: true
});
console.log(Object.entries(res.metafile.inputs).sort((a, b) => a[1].bytes - b[1].bytes).map(e => `${e[0]} -> ${e[1].bytes}`).join('\n'));
writeFileSync('./main.user.js', extheader + readFileSync('./dist/main.js'));
*/
let res;
res = await esbuild
.build({
@ -65,5 +52,4 @@ const extheader = `// ==UserScript==
console.log(Object.entries(res.metafile.inputs).sort((a, b) => a[1].bytes - b[1].bytes).map(e => `${e[0]} -> ${e[1].bytes}`).join('\n'));
writeFileSync('./main.user.js', extheader + readFileSync('./dist/main.js'));
writeFileSync('./main.meta.js', extheader);
})();

1
main.d.ts

@ -1 +0,0 @@
/* eslint-disable */

2
main.meta.js

@ -1,7 +1,7 @@
// ==UserScript==
// @name PNGExtraEmbed
// @namespace https://coom.tech/
// @version 0.60
// @version 0.61
// @description uhh
// @author You
// @match https://boards.4channel.org/*

23119
main.user.js

File diff suppressed because it is too large

180
package-lock.json

@ -9,23 +9,23 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@tsconfig/svelte": "^3.0.0",
"buffer": "^6.0.3",
"crc-32": "^1.2.0",
"esbuild-svelte": "^0.6.0",
"events": "^3.3.0",
"file-type": "^17.0.2",
"readable-stream": "^3.6.0",
"svelte-preprocess": "^4.10.1",
"ts-ebml": "^2.0.2",
"typescript": "^4.5.4"
"ts-ebml": "^2.0.2"
},
"devDependencies": {
"@tsconfig/svelte": "^3.0.0",
"@types/tampermonkey": "^4.0.5",
"esbuild": "^0.14.7",
"esbuild-css-modules-plugin": "^2.0.9",
"esbuild-svelte": "^0.6.0",
"svelte": "^3.44.3",
"svelte-check": "^2.2.11"
"svelte-check": "^2.2.11",
"svelte-preprocess": "^4.10.1",
"typescript": "^4.5.4"
}
},
"node_modules/@babel/code-frame": {
@ -103,7 +103,8 @@
"node_modules/@tsconfig/svelte": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-3.0.0.tgz",
"integrity": "sha512-pYrtLtOwku/7r1i9AMONsJMVYAtk3hzOfiGNekhtq5tYBGA7unMve8RvUclKLMT3PrihvJqUmzsRGh0RP84hKg=="
"integrity": "sha512-pYrtLtOwku/7r1i9AMONsJMVYAtk3hzOfiGNekhtq5tYBGA7unMve8RvUclKLMT3PrihvJqUmzsRGh0RP84hKg==",
"dev": true
},
"node_modules/@types/minimist": {
"version": "1.2.2",
@ -113,7 +114,8 @@
"node_modules/@types/node": {
"version": "17.0.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.6.tgz",
"integrity": "sha512-+XBAjfZmmivILUzO0HwBJoYkAyyySSLg5KCGBDFLomJo0sV6szvVLAf4ANZZ0pfWzgEds5KmGLG9D5hfEqOhaA=="
"integrity": "sha512-+XBAjfZmmivILUzO0HwBJoYkAyyySSLg5KCGBDFLomJo0sV6szvVLAf4ANZZ0pfWzgEds5KmGLG9D5hfEqOhaA==",
"dev": true
},
"node_modules/@types/normalize-package-data": {
"version": "2.4.1",
@ -123,12 +125,14 @@
"node_modules/@types/pug": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.6.tgz",
"integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg=="
"integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==",
"dev": true
},
"node_modules/@types/sass": {
"version": "1.43.1",
"resolved": "https://registry.npmjs.org/@types/sass/-/sass-1.43.1.tgz",
"integrity": "sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
@ -188,7 +192,8 @@
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"node_modules/base64-js": {
"version": "1.5.1",
@ -222,6 +227,7 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -266,6 +272,7 @@
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
"dev": true,
"engines": {
"node": "*"
}
@ -370,7 +377,8 @@
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"node_modules/crc": {
"version": "3.2.1",
@ -492,6 +500,7 @@
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
"integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==",
"dev": true,
"engines": {
"node": ">=8"
}
@ -521,12 +530,14 @@
"node_modules/es6-promise": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz",
"integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM="
"integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=",
"dev": true
},
"node_modules/esbuild": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.10.tgz",
"integrity": "sha512-ibZb+NwFqBwHHJlpnFMtg4aNmVK+LUtYMFC9CuKs6lDCBEvCHpqCFZFEirpqt1jOugwKGx8gALNGvX56lQyfew==",
"dev": true,
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
@ -559,6 +570,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"android"
@ -584,6 +596,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
@ -596,6 +609,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
@ -608,6 +622,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
@ -620,6 +635,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
@ -632,6 +648,7 @@
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"linux"
@ -644,6 +661,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@ -656,6 +674,7 @@
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
@ -668,6 +687,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@ -680,6 +700,7 @@
"cpu": [
"mips64el"
],
"dev": true,
"optional": true,
"os": [
"linux"
@ -692,6 +713,7 @@
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@ -704,6 +726,7 @@
"cpu": [
"s390x"
],
"dev": true,
"optional": true,
"os": [
"linux"
@ -716,6 +739,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"netbsd"
@ -728,6 +752,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"openbsd"
@ -740,6 +765,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"sunos"
@ -749,6 +775,7 @@
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/esbuild-svelte/-/esbuild-svelte-0.6.0.tgz",
"integrity": "sha512-XxfVGWWIIagrL8ElwE5im10hGeJWH8xDKplFmg/B64GGwc3i2k96Y6/NiDdskB8ZZ3gABsG2r3hXdH6Nb+ck3w==",
"dev": true,
"dependencies": {
"svelte": "^3.44.1"
},
@ -763,6 +790,7 @@
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
@ -775,6 +803,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
@ -787,6 +816,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
@ -910,7 +940,8 @@
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"node_modules/fsevents": {
"version": "2.3.2",
@ -955,6 +986,7 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@ -985,7 +1017,8 @@
"node_modules/graceful-fs": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg=="
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
"dev": true
},
"node_modules/hard-rejection": {
"version": "2.1.0",
@ -1093,6 +1126,7 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@ -1253,6 +1287,7 @@
"version": "0.25.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
"integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
"dev": true,
"dependencies": {
"sourcemap-codec": "^1.4.4"
}
@ -1365,6 +1400,7 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@ -1375,7 +1411,8 @@
"node_modules/minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true
},
"node_modules/minimist-options": {
"version": "4.1.0",
@ -1394,6 +1431,7 @@
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"dev": true,
"dependencies": {
"minimist": "^1.2.5"
},
@ -1419,7 +1457,7 @@
"version": "3.1.30",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz",
"integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==",
"devOptional": true,
"dev": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
},
@ -1454,6 +1492,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"dependencies": {
"wrappy": "1"
}
@ -1527,6 +1566,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@ -1547,7 +1587,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"devOptional": true
"dev": true
},
"node_modules/picomatch": {
"version": "2.3.0",
@ -1565,7 +1605,7 @@
"version": "8.4.5",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz",
"integrity": "sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==",
"devOptional": true,
"dev": true,
"dependencies": {
"nanoid": "^3.1.30",
"picocolors": "^1.0.0",
@ -1829,6 +1869,7 @@
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
"dev": true,
"dependencies": {
"glob": "^7.1.3"
},
@ -1894,6 +1935,7 @@
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz",
"integrity": "sha1-dB4kXiMfB8r7b98PEzrfohalAq0=",
"dev": true,
"dependencies": {
"es6-promise": "^3.1.2",
"graceful-fs": "^4.1.3",
@ -1919,6 +1961,7 @@
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.10.0.tgz",
"integrity": "sha1-iukK19fLBfxZ8asMY3hF1cFaUrc=",
"dev": true,
"dependencies": {
"buffer-crc32": "^0.2.5",
"minimist": "^1.2.0",
@ -1942,7 +1985,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz",
"integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==",
"devOptional": true,
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@ -1950,7 +1993,8 @@
"node_modules/sourcemap-codec": {
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"dev": true
},
"node_modules/spdx-correct": {
"version": "3.1.1",
@ -2039,6 +2083,7 @@
"version": "3.44.3",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.44.3.tgz",
"integrity": "sha512-aGgrNCip5PQFNfq9e9tmm7EYxWLVHoFsEsmKrtOeRD8dmoGDdyTQ+21xd7qgFd8MNdKGSYvg7F9dr+Tc0yDymg==",
"dev": true,
"engines": {
"node": ">= 8"
}
@ -2140,6 +2185,7 @@
"version": "4.10.1",
"resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-4.10.1.tgz",
"integrity": "sha512-NSNloaylf+o9UeyUR2KvpdxrAyMdHl3U7rMnoP06/sG0iwJvlUM4TpMno13RaNqovh4AAoGsx1jeYcIyuGUXMw==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
"@types/pug": "^2.0.4",
@ -2205,6 +2251,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
"dev": true,
"dependencies": {
"min-indent": "^1.0.0"
},
@ -2341,6 +2388,7 @@
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@ -2380,7 +2428,8 @@
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
},
"node_modules/yallist": {
"version": "4.0.0",
@ -2465,7 +2514,8 @@
"@tsconfig/svelte": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-3.0.0.tgz",
"integrity": "sha512-pYrtLtOwku/7r1i9AMONsJMVYAtk3hzOfiGNekhtq5tYBGA7unMve8RvUclKLMT3PrihvJqUmzsRGh0RP84hKg=="
"integrity": "sha512-pYrtLtOwku/7r1i9AMONsJMVYAtk3hzOfiGNekhtq5tYBGA7unMve8RvUclKLMT3PrihvJqUmzsRGh0RP84hKg==",
"dev": true
},
"@types/minimist": {
"version": "1.2.2",
@ -2475,7 +2525,8 @@
"@types/node": {
"version": "17.0.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.6.tgz",
"integrity": "sha512-+XBAjfZmmivILUzO0HwBJoYkAyyySSLg5KCGBDFLomJo0sV6szvVLAf4ANZZ0pfWzgEds5KmGLG9D5hfEqOhaA=="
"integrity": "sha512-+XBAjfZmmivILUzO0HwBJoYkAyyySSLg5KCGBDFLomJo0sV6szvVLAf4ANZZ0pfWzgEds5KmGLG9D5hfEqOhaA==",
"dev": true
},
"@types/normalize-package-data": {
"version": "2.4.1",
@ -2485,12 +2536,14 @@
"@types/pug": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.6.tgz",
"integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg=="
"integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==",
"dev": true
},
"@types/sass": {
"version": "1.43.1",
"resolved": "https://registry.npmjs.org/@types/sass/-/sass-1.43.1.tgz",
"integrity": "sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==",
"dev": true,
"requires": {
"@types/node": "*"
}
@ -2538,7 +2591,8 @@
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"base64-js": {
"version": "1.5.1",
@ -2555,6 +2609,7 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -2581,7 +2636,8 @@
"buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
"dev": true
},
"buffers": {
"version": "0.1.1",
@ -2657,7 +2713,8 @@
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"crc": {
"version": "3.2.1",
@ -2743,7 +2800,8 @@
"detect-indent": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
"integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA=="
"integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==",
"dev": true
},
"ebml": {
"version": "2.2.4",
@ -2770,12 +2828,14 @@
"es6-promise": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz",
"integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM="
"integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=",
"dev": true
},
"esbuild": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.10.tgz",
"integrity": "sha512-ibZb+NwFqBwHHJlpnFMtg4aNmVK+LUtYMFC9CuKs6lDCBEvCHpqCFZFEirpqt1jOugwKGx8gALNGvX56lQyfew==",
"dev": true,
"requires": {
"esbuild-android-arm64": "0.14.10",
"esbuild-darwin-64": "0.14.10",
@ -2801,6 +2861,7 @@
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.10.tgz",
"integrity": "sha512-vzkTafHKoiMX4uIN1kBnE/HXYLpNT95EgGanVk6DHGeYgDolU0NBxjO7yZpq4ZGFPOx8384eAdDrBYhO11TAlQ==",
"dev": true,
"optional": true
},
"esbuild-css-modules-plugin": {
@ -2820,90 +2881,105 @@
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.10.tgz",
"integrity": "sha512-DJwzFVB95ZV7C3PQbf052WqaUuuMFXJeZJ0LKdnP1w+QOU0rlbKfX0tzuhoS//rOXUj1TFIwRuRsd0FX6skR7A==",
"dev": true,
"optional": true
},
"esbuild-darwin-arm64": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.10.tgz",
"integrity": "sha512-RNaaoZDg3nsqs5z56vYCjk/VJ76npf752W0rOaCl5lO5TsgV9zecfdYgt7dtUrIx8b7APhVaNYud+tGsDOVC9g==",
"dev": true,
"optional": true
},
"esbuild-freebsd-64": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.10.tgz",
"integrity": "sha512-10B3AzW894u6bGZZhWiJOHw1uEHb4AFbUuBdyml1Ht0vIqd+KqWW+iY/yMwQAzILr2WJZqEhbOXRkJtY8aRqOw==",
"dev": true,
"optional": true
},
"esbuild-freebsd-arm64": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.10.tgz",
"integrity": "sha512-mSQrKB7UaWvuryBTCo9leOfY2uEUSimAvcKIaUWbk5Hth9Sg+Try+qNA/NibPgs/vHkX0KFo/Rce6RPea+P15g==",
"dev": true,
"optional": true
},
"esbuild-linux-32": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.10.tgz",
"integrity": "sha512-lktF09JgJLZ63ANYHIPdYe339PDuVn19Q/FcGKkXWf+jSPkn5xkYzAabboNGZNUgNqSJ/vY7VrOn6UrBbJjgYA==",
"dev": true,
"optional": true
},
"esbuild-linux-64": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.10.tgz",
"integrity": "sha512-K+gCQz2oLIIBI8ZM77e9sYD5/DwEpeYCrOQ2SYXx+R4OU2CT9QjJDi4/OpE7ko4AcYMlMW7qrOCuLSgAlEj4Wg==",
"dev": true,
"optional": true
},
"esbuild-linux-arm": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.10.tgz",
"integrity": "sha512-BYa60dZ/KPmNKYxtHa3LSEdfKWHcm/RzP0MjB4AeBPhjS0D6/okhaBesZIY9kVIGDyeenKsJNOmnVt4+dhNnvQ==",
"dev": true,
"optional": true
},
"esbuild-linux-arm64": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.10.tgz",
"integrity": "sha512-+qocQuQvcp5wo/V+OLXxqHPc+gxHttJEvbU/xrCGE03vIMqraL4wMua8JQx0SWEnJCWP+Nhf//v8OSwz1Xr5kA==",
"dev": true,
"optional": true
},
"esbuild-linux-mips64le": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.10.tgz",
"integrity": "sha512-nmUd2xoBXpGo4NJCEWoaBj+n4EtDoLEvEYc8Z3aSJrY0Oa6s04czD1flmhd0I/d6QEU8b7GQ9U0g/rtBfhtxBg==",
"dev": true,
"optional": true
},
"esbuild-linux-ppc64le": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.10.tgz",
"integrity": "sha512-vsOWZjm0rZix7HSmqwPph9arRVCyPtUpcURdayQDuIhMG2/UxJxpbdRaa//w4zYqcJzAWwuyH2PAlyy0ZNuxqQ==",
"dev": true,
"optional": true
},
"esbuild-linux-s390x": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.10.tgz",
"integrity": "sha512-knArKKZm0ypIYWOWyOT7+accVwbVV1LZnl2FWWy05u9Tyv5oqJ2F5+X2Vqe/gqd61enJXQWqoufXopvG3zULOg==",
"dev": true,
"optional": true
},
"esbuild-netbsd-64": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.10.tgz",
"integrity": "sha512-6Gg8neVcLeyq0yt9bZpReb8ntZ8LBEjthxrcYWVrBElcltnDjIy1hrzsujt0+sC2rL+TlSsE9dzgyuvlDdPp2w==",
"dev": true,
"optional": true
},
"esbuild-openbsd-64": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.10.tgz",
"integrity": "sha512-9rkHZzp10zI90CfKbFrwmQjqZaeDmyQ6s9/hvCwRkbOCHuto6RvMYH9ghQpcr5cUxD5OQIA+sHXi0zokRNXjcg==",
"dev": true,
"optional": true
},
"esbuild-sunos-64": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.10.tgz",
"integrity": "sha512-mEU+pqkhkhbwpJj5DiN3vL0GUFR/yrL3qj8ER1amIVyRibKbj02VM1QaIuk1sy5DRVIKiFXXgCaHvH3RNWCHIw==",
"dev": true,
"optional": true
},
"esbuild-svelte": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/esbuild-svelte/-/esbuild-svelte-0.6.0.tgz",
"integrity": "sha512-XxfVGWWIIagrL8ElwE5im10hGeJWH8xDKplFmg/B64GGwc3i2k96Y6/NiDdskB8ZZ3gABsG2r3hXdH6Nb+ck3w==",
"dev": true,
"requires": {
"svelte": "^3.44.1"
}
@ -2912,18 +2988,21 @@
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.10.tgz",
"integrity": "sha512-Z5DieUL1N6s78dOSdL95KWf8Y89RtPGxIoMF+LEy8ChDsX+pZpz6uAVCn+YaWpqQXO+2TnrcbgBIoprq2Mco1g==",
"dev": true,
"optional": true
},
"esbuild-windows-64": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.10.tgz",
"integrity": "sha512-LE5Mm62y0Bilu7RDryBhHIX8rK3at5VwJ6IGM3BsASidCfOBTzqcs7Yy0/Vkq39VKeTmy9/66BAfVoZRNznoDw==",
"dev": true,
"optional": true
},
"esbuild-windows-arm64": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.10.tgz",
"integrity": "sha512-OJOyxDtabvcUYTc+O4dR0JMzLBz6G9+gXIHA7Oc5d5Fv1xiYa0nUeo8+W5s2e6ZkPRdIwOseYoL70rZz80S5BA==",
"dev": true,
"optional": true
},
"escape-string-regexp": {
@ -3014,7 +3093,8 @@
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"fsevents": {
"version": "2.3.2",
@ -3046,6 +3126,7 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@ -3067,7 +3148,8 @@
"graceful-fs": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg=="
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
"dev": true
},
"hard-rejection": {
"version": "2.1.0",
@ -3132,6 +3214,7 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
@ -3257,6 +3340,7 @@
"version": "0.25.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
"integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
"dev": true,
"requires": {
"sourcemap-codec": "^1.4.4"
}
@ -3341,6 +3425,7 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -3348,7 +3433,8 @@
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true
},
"minimist-options": {
"version": "4.1.0",
@ -3364,6 +3450,7 @@
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"dev": true,
"requires": {
"minimist": "^1.2.5"
}
@ -3383,7 +3470,7 @@
"version": "3.1.30",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz",
"integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==",
"devOptional": true
"dev": true
},
"normalize-package-data": {
"version": "3.0.3",
@ -3406,6 +3493,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1"
}
@ -3454,7 +3542,8 @@
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
"peek-readable": {
"version": "5.0.0-alpha.5",
@ -3465,7 +3554,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"devOptional": true
"dev": true
},
"picomatch": {
"version": "2.3.0",
@ -3477,7 +3566,7 @@
"version": "8.4.5",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz",
"integrity": "sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==",
"devOptional": true,
"dev": true,
"requires": {
"nanoid": "^3.1.30",
"picocolors": "^1.0.0",
@ -3641,6 +3730,7 @@
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
@ -3672,6 +3762,7 @@
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz",
"integrity": "sha1-dB4kXiMfB8r7b98PEzrfohalAq0=",
"dev": true,
"requires": {
"es6-promise": "^3.1.2",
"graceful-fs": "^4.1.3",
@ -3691,6 +3782,7 @@
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.10.0.tgz",
"integrity": "sha1-iukK19fLBfxZ8asMY3hF1cFaUrc=",
"dev": true,
"requires": {
"buffer-crc32": "^0.2.5",
"minimist": "^1.2.0",
@ -3708,12 +3800,13 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz",
"integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==",
"devOptional": true
"dev": true
},
"sourcemap-codec": {
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"dev": true
},
"spdx-correct": {
"version": "3.1.1",
@ -3785,7 +3878,8 @@
"svelte": {
"version": "3.44.3",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.44.3.tgz",
"integrity": "sha512-aGgrNCip5PQFNfq9e9tmm7EYxWLVHoFsEsmKrtOeRD8dmoGDdyTQ+21xd7qgFd8MNdKGSYvg7F9dr+Tc0yDymg=="
"integrity": "sha512-aGgrNCip5PQFNfq9e9tmm7EYxWLVHoFsEsmKrtOeRD8dmoGDdyTQ+21xd7qgFd8MNdKGSYvg7F9dr+Tc0yDymg==",
"dev": true
},
"svelte-check": {
"version": "2.2.11",
@ -3859,6 +3953,7 @@
"version": "4.10.1",
"resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-4.10.1.tgz",
"integrity": "sha512-NSNloaylf+o9UeyUR2KvpdxrAyMdHl3U7rMnoP06/sG0iwJvlUM4TpMno13RaNqovh4AAoGsx1jeYcIyuGUXMw==",
"dev": true,
"requires": {
"@types/pug": "^2.0.4",
"@types/sass": "^1.16.0",
@ -3872,6 +3967,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
"dev": true,
"requires": {
"min-indent": "^1.0.0"
}
@ -3959,7 +4055,8 @@
"typescript": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg=="
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
"dev": true
},
"underscore": {
"version": "1.13.2",
@ -3989,7 +4086,8 @@
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
},
"yallist": {
"version": "4.0.0",

12
package.json

@ -13,18 +13,18 @@
"author": "",
"license": "ISC",
"dependencies": {
"@tsconfig/svelte": "^3.0.0",
"ts-ebml": "^2.0.2",
"buffer": "^6.0.3",
"crc-32": "^1.2.0",
"esbuild-svelte": "^0.6.0",
"events": "^3.3.0",
"file-type": "^17.0.2",
"readable-stream": "^3.6.0",
"svelte-preprocess": "^4.10.1",
"ts-ebml": "^2.0.2",
"typescript": "^4.5.4"
"readable-stream": "^3.6.0"
},
"devDependencies": {
"esbuild-svelte": "^0.6.0",
"@tsconfig/svelte": "^3.0.0",
"svelte-preprocess": "^4.10.1",
"typescript": "^4.5.4",
"@types/tampermonkey": "^4.0.5",
"esbuild": "^0.14.7",
"esbuild-css-modules-plugin": "^2.0.9",

114
src/App.svelte

@ -1,18 +1,53 @@
<script lang="ts">
import { onDestroy } from 'svelte';
import { hasContext, onDestroy } from 'svelte'
import { settings } from './stores'
let visible = false;
let visible = false
let penisEvent = () => {
console.log("bepis")
visible = !visible;
console.log('bepis')
visible = !visible
}
document.addEventListener('penis', penisEvent);
console.log("app loaded")
document.addEventListener('penis', penisEvent)
console.log('app loaded')
let sources = [
'gelbooru.com',
'yande.re',
'capi-v2.sankakucomplex.com',
'api.rule34.xxx',
'danbooru.donmai.us',
'lolibooru.moe',
]
let selectobj: HTMLSelectElement
let selectobj2: HTMLSelectElement
function toggleSelection() {
for (let i = 0; i < selectobj.selectedOptions.length; ++i) {
let item = selectobj.selectedOptions.item(i)
if (!item) continue
if ($settings.sources.includes(item.value))
$settings.sources = $settings.sources.filter(
(e: string) => e != item!.value,
)
else $settings.sources = [...$settings.sources, item.value]
}
}
function removeSelection() {
let s = new Set<string>();
for (let i = 0; i < selectobj2.selectedOptions.length; ++i) {
let obj = selectobj2.selectedOptions.item(i)
if (!obj) continue
s.add(obj.value)
$settings.blacklist = $settings.blacklist.filter((e: any) => !s.has(e))
}
}
onDestroy(() => {
document.removeEventListener('penis', penisEvent);
});
document.removeEventListener('penis', penisEvent)
})
</script>
<div class="backpanel" class:enabled={visible} class:disabled={!visible}>
@ -31,24 +66,69 @@ import { onDestroy } from 'svelte';
<input type="checkbox" bind:checked={$settings.loop} />
Loop media content.
</label>
<label>
<input type="checkbox" bind:checked={$settings.dh} />
Turn off hover preview.
</label>
<label>
<input type="checkbox" bind:checked={$settings.te} />
Turn off third-eye.
</label>
{#if !$settings.te}
<h3>Booru sources</h3>
<select multiple bind:this={selectobj} size={sources.length}>
{#each sources as source, i}
<option
class="sourcedi"
class:sourceen={$settings.sources.includes(source)}
value={source}>{source}</option
>
{/each}
</select>
<button on:click={toggleSelection}>Toggle sources</button>
<hr />
<h3>Blacklisted tags</h3>
<select multiple bind:this={selectobj2} size={sources.length}>
{#each $settings.blacklist as source, i}
<option value={source}>{source}</option>
{/each}
</select>
<button on:click={removeSelection}>Remove</button>
<input
placeholder="Press enter after typing your tag"
on:keydown={ev => {
if (ev.key == 'Enter') {
$settings.blacklist = [
...$settings.blacklist,
ev.currentTarget.value,
]
ev.currentTarget.value = ''
}
}}
/>
{/if}
</div>
</div>
<style scoped>
select {
font-size: 1.2em;
}
.enabled {
display: block;
}
.disabled {
display: none;
.sourcedi {
border-right: 10px solid lightcoral;
}
.glow {
text-shadow: 0 0 4px red;
.sourceen {
border-right: 10px solid lightgreen;
}
.clickable {
cursor: pointer;
.disabled {
display: none;
}
.content {
@ -68,7 +148,7 @@ import { onDestroy } from 'svelte';
position: absolute;
right: 32px;
padding: 10px;
width: 10%;
width: 15%;
top: 32px;
border: 1px solid;
border-radius: 5px;
@ -76,8 +156,4 @@ import { onDestroy } from 'svelte';
pointer-events: all;
backdrop-filter: blur(9px);
}
.clickable:hover {
text-shadow: 0 0 2px palevioletred;
}
</style>

81
src/Embedding.svelte

@ -1,9 +1,10 @@
<script lang="ts">
import { fileTypeFromBuffer } from 'file-type'
import { settings } from './stores'
import { beforeUpdate } from 'svelte'
import { beforeUpdate, tick } from 'svelte'
import type {EmbeddedFile} from './main';
export let file: { filename: string; data: Buffer }
export let file: EmbeddedFile
let isVideo = false
let isImage = false
let isAudio = false
@ -19,15 +20,18 @@
let videoElem: HTMLVideoElement
let hoverVideo: HTMLVideoElement
let dims: [number, number] = [0, 0]
let furl: string | undefined = undefined;
beforeUpdate(async () => {
if (settled) return
settled = true
const type = await fileTypeFromBuffer(file.data)
url = URL.createObjectURL(new Blob([file.data], { type: type?.mime }))
const thumb = file.thumbnail || file.data;
const type = await fileTypeFromBuffer(thumb);
url = URL.createObjectURL(new Blob([thumb], { type: type?.mime }))
if (!type) {
isFile = true
return
return;
}
isVideo = type.mime.startsWith('video/')
isAudio = type.mime.startsWith('audio/')
@ -39,15 +43,34 @@
}
})
async function unzip() {
if (!file.thumbnail)
return;
let full = await file.data();
const type = await fileTypeFromBuffer(full);
furl = URL.createObjectURL(new Blob([full], { type: type?.mime }));
if (!type)
return;
isVideo = type.mime.startsWith('video/')
isAudio = type.mime.startsWith('audio/')
isImage = type.mime.startsWith('image/')
if (hovering) {
// reset hovering to recompute proper image coordinates
await tick();
recompute();
await tick();
}
}
function hasAudio(video: any) {
return (
video.mozHasAudio ||
Boolean(video.webkitAudioDecodedByteCount) ||
Boolean(video.audioTracks && video.audioTracks.length)
!!(video.webkitAudioDecodedByteCount) ||
!!(video.audioTracks && video.audioTracks.length)
)
}
function bepis() {
async function bepis() {
contracted = !contracted
if (hovering) hoverStop()
if (contracted && isVideo) {
@ -57,14 +80,15 @@
if (!contracted && isVideo) {
videoElem.controls = true
// has to be delayed
setTimeout(() => videoElem.play(), 10)
setTimeout(async () => await videoElem.play(), 10)
}
if (file.thumbnail && !furl) {
// don't know how you managed to click before hovering but oh well
unzip()
}
}
function hoverStart(ev: MouseEvent) {
if (!isImage && !isVideo) return
if (!contracted) return
function recompute() {
const [sw, sh] = [visualViewport.width, visualViewport.height]
let [iw, ih] = [0, 0]
@ -79,15 +103,34 @@
hoverElem.style.width = `${dims[0]}px`
hoverElem.style.height = `${dims[1]}px`
hovering = true
if (isVideo) hoverVideo.play()
}
async function hoverStart(ev?: MouseEvent) {
if ($settings.dh)return;
if (file.thumbnail && !furl) {
unzip();
}
if (!isImage && !isVideo) return
if (!contracted) return
recompute();
try {
if (isVideo) await hoverVideo.play()
} catch (e) {
console.log(e)
}
}
function hoverStop(ev?: MouseEvent) {
if ($settings.dh) return;
hovering = false
if (isVideo) hoverVideo.pause()
}
function hoverUpdate(ev: MouseEvent) {
if ($settings.dh) return;
if (!contracted) return
const [sw, sh] = [visualViewport.width, visualViewport.height]
// shamelessly stolen from 4chanX
@ -130,14 +173,15 @@
bind:this={place}
>
{#if isImage}
<img bind:this={imgElem} alt={file.filename} src={url} />
<img bind:this={imgElem} alt={file.filename} src={furl || url} />
{/if}
{#if isAudio}
<audio loop={$settings.loop} alt={file.filename} src={url} />
{/if}
{#if isVideo}
<!-- svelte-ignore a11y-media-has-caption -->
<video loop={$settings.loop} bind:this={videoElem} src={url} />
<video loop={$settings.loop} bind:this={videoElem} src={furl || url} />
<!-- assoom videos will never be loaded from thumbnails -->
{/if}
{#if isFile}
<button>Download {file.filename}</button>
@ -149,11 +193,12 @@
class="hoverer"
>
{#if isImage}
<img alt={file.filename} src={url} />
<img alt={file.filename} src={furl || url} />
{/if}
{#if isVideo}
<!-- svelte-ignore a11y-media-has-caption -->
<video loop={$settings.loop} bind:this={hoverVideo} src={url} />
<video loop={$settings.loop} bind:this={hoverVideo} src={furl || url} />
<!-- assoom videos will never be loaded from thumbnails -->
{/if}
</div>

2
src/SettingsButton.svelte

@ -21,6 +21,6 @@
}
.clickable:hover {
text-shadow: 0 0 2px palevioletred;
text-shadow: 0 0 4px palevioletred;
}
</style>

16
src/gif.ts

@ -1,4 +1,5 @@
import { Buffer } from "buffer";
import type { ImageProcessor } from "./main";
import { BufferWriteStream } from "./png";
const netscape = Buffer.from("!\xFF\x0BNETSCAPE2.0", 'ascii');
@ -44,7 +45,7 @@ const extractBuff = (gif: Buffer) => {
// metadata ended, nothing...
};
export const extract = extractBuff;
const extract = extractBuff;
const write_embedding = async (writer: WritableStreamDefaultWriter<Buffer>, inj: Buffer) => {
await writer.write(magic);
@ -64,7 +65,7 @@ const write_embedding = async (writer: WritableStreamDefaultWriter<Buffer>, inj:
await writer.write(byte);
};
export const inject = async (container: File, inj: File) => {
const inject = async (container: File, inj: File) => {
const [writestream, extract] = BufferWriteStream();
const writer = writestream.getWriter();
@ -84,7 +85,7 @@ export const inject = async (container: File, inj: File) => {
return extract();
};
export const has_embed = (gif: Buffer) => {
const has_embed = (gif: Buffer) => {
const field = gif.readUInt8(10);
const gcte = !!(field & (1 << 7));
let end = 13;
@ -109,4 +110,11 @@ export const has_embed = (gif: Buffer) => {
if (end >= gif.byteLength)
return; // Don't know yet, need more to decide.
return false; // no more extension blocks, so definite no
};
};
export default {
extract,
has_embed,
inject,
match: fn => !!fn.match(/\.gif$/)
} as ImageProcessor;

70
src/main.ts

@ -1,10 +1,10 @@
import { Buffer } from "buffer";
import { fileTypeFromBuffer } from 'file-type';
import { settings } from "./stores";
import * as png from "./png";
import * as webm from "./webm";
import * as gif from "./gif";
import png from "./png";
import webm from "./webm";
import gif from "./gif";
import thirdeye from "./thirdeye";
import { GM_fetch, GM_head, headerStringToObject } from "./requests";
@ -12,8 +12,23 @@ import App from "./App.svelte";
import SettingsButton from './SettingsButton.svelte';
import Embedding from './Embedding.svelte';
export interface ImageProcessor {
skip?: true;
match(fn: string): boolean;
has_embed(b: Buffer, fn?: string): boolean | Promise<boolean>;
extract(b: Buffer, fn?: string): EmbeddedFile | Promise<EmbeddedFile>;
inject?(b: File, c: File): Buffer | Promise<Buffer>;
}
let csettings: any;
settings.subscribe(b => csettings = b);
let processors: ImageProcessor[] =
[thirdeye, png, webm, gif];
settings.subscribe(b => {
csettings = b;
processors = [...(csettings.te ? [thirdeye] : []), png, webm, gif
];
});
// most pngs are encoded with 65k idat chunks
async function* streamRemote(url: string, chunkSize = 16 * 1024, fetchRestOnNonCanceled = true) {
@ -41,20 +56,31 @@ async function* streamRemote(url: string, chunkSize = 16 * 1024, fetchRestOnNonC
//console.log("streaming ended, ", ptr, size);
}
type EmbeddedFile = { filename: string; data: Buffer };
const processors: [RegExp,
(b: Buffer) => (boolean | undefined) | Promise<boolean | undefined>,
(b: Buffer) => EmbeddedFile | undefined | Promise<EmbeddedFile | undefined>,
(container: File, inj: File) => Promise<Buffer>][] = [
[/\.png$/, png.has_embed, png.extract, png.inject],
[/\.webm$/, webm.has_embed, webm.extract, webm.inject],
[/\.gif$/, gif.has_embed, gif.extract, gif.inject],
];
type EmbeddedFileWithPreview = {
thumbnail: Buffer;
filename: string;
data: () => Promise<Buffer>;
};
const processImage = async (src: string) => {
const proc = processors.find(e => src.match(e[0]));
type EmbeddedFileWithoutPreview = {
thumbnail: undefined;
filename: string;
data: Buffer;
};
export type EmbeddedFile = EmbeddedFileWithPreview | EmbeddedFileWithoutPreview;
const processImage = async (src: string, fn: string) => {
const proc = processors.find(e => e.match(fn));
if (!proc)
return;
if (proc.skip) {
// skip file downloading, file is referenced from the filename
// basically does things like filtering out blacklisted tags
if (await proc.has_embed(Buffer.alloc(0), fn) === true)
return await proc.extract(Buffer.alloc(0), fn);
return;
}
const iter = streamRemote(src);
if (!iter)
return;
@ -70,14 +96,14 @@ const processImage = async (src: string) => {
}
if (!done)
cumul = Buffer.concat([cumul, value!]);
found = await proc[1](cumul);
found = await proc.has_embed(cumul);
} while (found !== false && !chunk.done);
await iter.next(false);
if (found === false) {
//console.log(`Gave up on ${src} after downloading ${cumul.byteLength} bytes...`);
return;
}
return await proc[2](cumul);
return await proc.extract(cumul);
};
const textToElement = <T = HTMLElement>(s: string) =>
@ -88,7 +114,7 @@ const processPost = async (post: HTMLDivElement) => {
const origlink = post.querySelector('.file-info > a') as HTMLAnchorElement;
if (!thumb || !origlink)
return;
const res = await processImage(origlink.href);
const res = await processImage(origlink.href, (origlink.querySelector('.fnfull') || origlink).textContent || '');
if (!res)
return;
const replyBox = post.querySelector('.post');
@ -195,10 +221,12 @@ document.addEventListener('QRDialogCreation', <any>((e: CustomEvent<string>) =>
input.onchange = (async ev => {
if (input.files) {
try {
const proc = processors.find(e => file.name.match(e[0]));
const proc = processors.find(e => e.match(file.name));
if (!proc)
throw new Error("Container filetype not supported");
const buff = await proc[3](file, input.files[0]);
if (!proc.inject)
return;
const buff = await proc.inject(file, input.files[0]);
document.dispatchEvent(new CustomEvent('QRSetFile', {
//detail: { file: new Blob([buff]), name: file.name, type: file.type }
detail: { file: new Blob([buff], { type }), name: file.name }

24
src/png.ts

@ -1,9 +1,10 @@
import { buf } from "crc-32";
import { Buffer } from "buffer";
import type { ImageProcessor } from "./main";
export type PNGChunk = [string, Buffer, number, number];
type PNGChunk = [string, Buffer, number, number];
export class PNGDecoder {
class PNGDecoder {
repr: Buffer;
req = 8;
@ -46,7 +47,7 @@ export class PNGDecoder {
}
}
export class PNGEncoder {
class PNGEncoder {
writer: WritableStreamDefaultWriter<Buffer>;
constructor(bytes: WritableStream<Buffer>) {
@ -72,7 +73,7 @@ export class PNGEncoder {
const CUM0 = Buffer.from("CUM\0" + "0");
export const BufferReadStream = (b: Buffer) => {
const BufferReadStream = (b: Buffer) => {
const ret = new ReadableStream<Buffer>({
pull(cont) {
cont.enqueue(b);
@ -82,7 +83,7 @@ export const BufferReadStream = (b: Buffer) => {
return ret;
};
export const extract = async (png: Buffer) => {
const extract = async (png: Buffer) => {
let magic = false;
const reader = BufferReadStream(png).getReader();
const sneed = new PNGDecoder(reader);
@ -143,7 +144,7 @@ export const BufferWriteStream = () => {
return [ret, () => b] as [WritableStream<Buffer>, () => Buffer];
};
export const inject = async (container: File, inj: File) => {
const inject = async (container: File, inj: File) => {
const [writestream, extract] = BufferWriteStream();
const encoder = new PNGEncoder(writestream);
const decoder = new PNGDecoder(container.stream().getReader());
@ -167,7 +168,7 @@ export const inject = async (container: File, inj: File) => {
return extract();
};
export const has_embed = async (png: Buffer) => {
const has_embed = async (png: Buffer) => {
const reader = BufferReadStream(png).getReader();
const sneed = new PNGDecoder(reader);
try {
@ -195,4 +196,11 @@ export const has_embed = async (png: Buffer) => {
} finally {
reader.releaseLock();
}
};
};
export default {
extract,
has_embed,
inject,
match: fn => !!fn.match(/\.png$/)
} as ImageProcessor;

11
src/stores.ts

@ -10,10 +10,17 @@ const localSet = (key: string, value: any) =>
export const settings = writable(localLoad('settings', {
loop: true,
dh: false,
xpv: false,
xpi: false,
blacklist: [],
sources: []
te: false,
blacklist: ['guro', 'scat', 'ryona', 'gore'],
sources: ['gelbooru.com',
'yande.re',
'capi-v2.sankakucomplex.com',
'api.rule34.xxx',
'danbooru.donmai.us',
'lolibooru.moe']
}));
settings.subscribe(newVal => {

138
src/thirdeye.ts

@ -0,0 +1,138 @@
import type { EmbeddedFile, ImageProcessor } from "./main";
import { GM_fetch } from "./requests";
import { settings } from "./stores";
export type Booru = {
domain: string;
endpoint: string;
quirks: tran;
};
export type BooruMatch = {
tags: string[];
full_url: string;
preview_url: string;
ext: string;
};
type tran = (a: any) => BooruMatch[];
const gelquirk: tran = a =>
a.post?.map((e: any) => ({
ext: e.image.substr(e.image.indexOf('.') + 1),
full_url: e.file_url,
preview_url: e.preview_url,
tags: e.tags.split(' ')
} as BooruMatch)) || [];
export const boorus: Booru[] = [
{
domain: 'gelbooru.com',
endpoint: '/index.php?page=dapi&s=post&q=index&json=1&tags=md5:',
quirks: gelquirk
},
{
domain: 'yande.re',
endpoint: '/post.json?tags=md5:',
quirks: a =>
a.map((e: any) => ({
ext: e.file_ext,
full_url: e.file_url,
preview_url: e.preview_url,
tags: e.tags.split(' ')
} as BooruMatch))
},
{
domain: 'capi-v2.sankakucomplex.com',
endpoint: '/posts/keyset?tags=md5:',
quirks: a => a.data ?
a.data.map((e: any) => ({
ext: e.file_type.substr(e.file_type.indexOf('/') + 1),
full_url: e.file_url,
preview_url: e.preview_url,
tags: e.tags.map((e: any) => e.name_en)
} as BooruMatch)) : []
},
{
domain: 'api.rule34.xxx',
endpoint: '/index.php?page=dapi&s=post&q=index&json=1&tags=md5:',
quirks: gelquirk
},
{
domain: 'danbooru.donmai.us',
endpoint: '/posts.json?tags=md5:',
quirks: a =>
a.map((e: any) => ({
ext: e.file_ext,
full_url: e.file_url,
preview_url: e.preview_url,
tags: e.tag_string.split(' ')
} as BooruMatch))
},
{
domain: 'lolibooru.moe',
endpoint: '/post.json?tags=md5:',
quirks: a =>
a.map((e: any) => ({
ext: e.file_url.substr(e.file_url.lastIndexOf('.') + 1),
full_url: e.file_url,
preview_url: e.preview_url,
tags: e.tags.split(' ')
} as BooruMatch))
}
];
let black = new Set<string>();
let sources = new Set<string>();
settings.subscribe(s => {
black = new Set(s.blacklist);
sources = new Set(s.sources);
});
const cache: any = {};
const findFileFrom = async (b: Booru, hex: string) => {
try {
if (hex in cache)
return cache[hex] as BooruMatch[];
const res = await GM_fetch(`https://${b.domain}${b.endpoint}${hex}`);
// might throw because some endpoint respond with invalid json when an error occurs
const pres = await res.json();
const tran = b.quirks(pres);
cache[hex] = tran;
return tran;
} catch {
return [];
}
};
const extract = async (b: Buffer, fn?: string) => {
const result = await Promise.race(Object.values(boorus)
.filter(e => sources.has(e.domain))
.map(e => findFileFrom(e, fn!.substring(0, 32))));
return {
filename: fn!.substring(33) + result[0].ext,
thumbnail: (await (await GM_fetch(result[0].preview_url)).arrayBuffer()),
data: async () => (await (await GM_fetch(result[0].full_url)).arrayBuffer())
} as EmbeddedFile;
};
const has_embed = async (b: Buffer, fn?: string) => {
// It's not worth to bother skipping images with filenames that match their md5 because
// 4chan reencodes jpegs, which is well over half the files posted
let result: BooruMatch[] | undefined = undefined;
for (const e of Object.values(boorus)) {
if (!sources.has(e.domain))
continue;
result = await findFileFrom(e, fn!.substring(0, 32));
}
return result && result.length != 0;
};
export default {
skip: true,
extract,
has_embed,
match: fn => !!fn.match(/[0-9a-fA-F]{32}\.....?/)
} as ImageProcessor;

15
src/webm.ts

@ -1,5 +1,6 @@
import { Buffer } from "buffer";
import * as ebml from "ts-ebml";
import type { ImageProcessor } from "./main";
// unused, but will in case 4chan does file sig checks
//const password = Buffer.from("NOA");
@ -107,7 +108,7 @@ const embed = (webm: Buffer, data: Buffer) => {
return Buffer.from(enc.encode(chunks.filter(e => e.name != "unknown")));
};
export const extract = (webm: Buffer) => {
const extract = (webm: Buffer) => {
const dec = new ebml.Decoder();
const chunks = dec.decode(webm);
@ -122,10 +123,10 @@ export const extract = (webm: Buffer) => {
return { filename: 'string', data: chk.data };
};
export const inject = async (container: File, inj: File): Promise<Buffer> =>
const inject = async (container: File, inj: File): Promise<Buffer> =>
embed(Buffer.from(await container.arrayBuffer()), Buffer.from(await inj.arrayBuffer()));
export const has_embed = (webm: Buffer) => {
const has_embed = (webm: Buffer) => {
const dec = new ebml.Decoder();
const chunks = dec.decode(webm);
@ -136,4 +137,10 @@ export const has_embed = (webm: Buffer) => {
if (embed == -1) // Found no coomtag, but no cluster, so it might be further
return;
return true;
};
};
export default {
extract,
has_embed,
match: fn => !!fn.match(/\.webm$/)
} as ImageProcessor;

4
tsconfig.json

@ -16,7 +16,7 @@
/** Requests the runtime types from the svelte modules by default. Needed for TS files or else you get errors. */
"types": ["svelte", "tampermonkey"],
"incremental": true, /* Enable incremental compilation */
"target": "es2021", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"target": "es2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
//"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"outDir": "./dist", /* Redirect output structure to the directory. */
"strict": true, /* Enable all strict type-checking options. */
@ -28,4 +28,4 @@
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
}

Loading…
Cancel
Save