From ce59119a030a10120b4e4facd84e842c792f31ab Mon Sep 17 00:00:00 2001
From: quoid <7660254+quoid@users.noreply.github.com>
Date: Mon, 1 May 2023 13:06:30 -0400
Subject: [PATCH 01/13] chore: update linters to use prettier
---
.editorconfig | 10 -
.eslintrc.json | 187 +++++----
.prettierignore | 15 +
.prettierrc | 18 +
.stylelintrc.json | 64 ++--
.vscode/settings.json | 27 +-
package.json | 57 +--
pnpm-lock.yaml | 858 +++++++++++-------------------------------
8 files changed, 436 insertions(+), 800 deletions(-)
delete mode 100644 .editorconfig
create mode 100644 .prettierignore
create mode 100644 .prettierrc
diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index 459f3d62..00000000
--- a/.editorconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-root = true
-
-[*]
-charset = utf-8
-end_of_line = lf
-indent_size = 4
-indent_style = space
-insert_final_newline = true
-max_line_length = 80
-trim_trailing_whitespace = true
diff --git a/.eslintrc.json b/.eslintrc.json
index d51e455f..43a440ec 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -1,82 +1,109 @@
{
- "env": {
- "browser": true,
- "node": true,
- "es2021": true,
- "es2022": true,
- "webextensions": true
- },
- "extends": ["eslint:recommended", "airbnb-base"],
- "globals": {
- "_browser": "writable",
- "browser": "readonly"
- },
- "ignorePatterns": [
- "/etc",
- "build",
- "dist",
- "node_modules"
- ],
- "overrides": [
- {
- "files": ["*.svelte"],
- "processor": "svelte3/svelte3"
- }
- ],
- "parserOptions": {
- "ecmaVersion": "latest",
- "sourceType": "module"
- },
- "plugins": ["svelte3"],
- "rules": {
- "array-callback-return": "off",
- "arrow-body-style": "off",
- "arrow-parens": ["error", "as-needed"],
- "comma-dangle": ["error", "never"],
- "consistent-return": "off",
- "default-case": "off",
- "eqeqeq": ["error", "smart"],
- "global-require": "off",
- "guard-for-in": "warn",
- "import/extensions": "off",
- "import/first": "off",
- "import/no-mutable-exports": "off",
- "import/no-extraneous-dependencies": ["error", {
- "devDependencies": true
- }],
- "import/prefer-default-export": "off",
- "import/no-unresolved": "off",
- "indent": ["error", 4, {"SwitchCase": 1}],
- "max-len": "off",
- "no-alert":"off",
- "no-await-in-loop":"warn",
- "no-confusing-arrow": ["warn", {
- "allowParens": true,
- "onlyOneSimpleParam": true
- }],
- "no-console": ["warn", {"allow": ["info", "warn", "error"]}],
- "no-continue": "off",
- "no-else-return": ["error", {"allowElseIf": true}],
- "no-nested-ternary": "off",
- "no-param-reassign": ["warn", { "props": false }],
- "no-plusplus": "off",
- "no-restricted-syntax": "off",
- "no-return-assign": "off",
- "no-underscore-dangle":"off",
- "no-unused-expressions": "off",
- "no-use-before-define": ["error", {
- "functions": false,
- "classes": true,
- "variables": true,
- "allowNamedExports": false
- }],
- "object-curly-newline": ["error", {"consistent": true}],
- "object-curly-spacing": ["error", "never"],
- "one-var": "off",
- "one-var-declaration-per-line": "off",
- "prefer-destructuring": "off",
- "prefer-object-spread": "warn",
- "quotes": ["error", "double"],
- "import/no-namespace": "warn"
- }
+ "env": {
+ "browser": true,
+ "es2021": true,
+ "node": true
+ },
+ "extends": ["prettier"],
+ "globals": {
+ "browser": "readonly",
+ "webkit": "readonly"
+ },
+ "ignorePatterns": ["node_modules", "xcode"],
+ "parserOptions": {
+ "ecmaVersion": 13,
+ "sourceType": "module"
+ },
+ "overrides": [
+ {
+ "files": ["*.svelte"],
+ // why use this instead of the svelte3 plugin?
+ // eslint prettier errors are ignored for stylelint, and...
+ // https://github.com/prettier/eslint-plugin-prettier#svelte-support
+ "parser": "svelte-eslint-parser"
+ }
+ ],
+ "plugins": ["prettier"],
+ "rules": {
+ "curly": ["error", "multi-line"],
+ "eqeqeq": ["error", "smart"],
+ "max-len": [
+ "error",
+ {
+ "code": 80,
+ "ignoreRegExpLiterals": true,
+ "tabWidth": 4
+ }
+ ],
+ "no-bitwise": "error",
+ "no-console": [1, {"allow": ["error", "info", "warn"]}],
+ "no-duplicate-imports": "error",
+ "no-mixed-operators": "error",
+ "no-multi-str": "error",
+ "no-restricted-syntax": [
+ "error",
+ {
+ "selector": "VariableDeclaration[kind='var'][declare!=true]",
+ "message": "Unexpected var, use let or const instead."
+ }
+ ],
+ "no-useless-concat": "error",
+ "no-unused-vars": [
+ "error",
+ {
+ "args": "all",
+ "argsIgnorePattern": "^_",
+ "caughtErrors": "all",
+ "caughtErrorsIgnorePattern": "^_",
+ "destructuredArrayIgnorePattern": "^_"
+ }
+ ],
+ "no-undef": "error",
+ "no-use-before-define": [
+ "error",
+ {
+ "classes": true,
+ "functions": false,
+ "variables": true
+ }
+ ],
+ "no-var": "off",
+ "operator-assignment": ["error", "always"],
+ "padding-line-between-statements": [
+ "error",
+ // {
+ // "blankLine": "always",
+ // "prev": "*",
+ // "next": ["return", "throw"]
+ // },
+ // {
+ // "blankLine": "always",
+ // "prev": ["const", "let", "var"],
+ // "next": "*"
+ // },
+ // {
+ // "blankLine": "any",
+ // "prev": ["const", "let", "var"],
+ // "next": ["const", "let", "var"]
+ // },
+ {
+ "blankLine": "always",
+ "prev": ["directive", "import"],
+ "next": "*"
+ },
+ {
+ "blankLine": "any",
+ "prev": ["directive", "import"],
+ "next": ["directive", "import"]
+ }
+ ],
+ "prefer-const": "error",
+ "prefer-template": "error",
+ "quotes": [
+ "error",
+ "double",
+ {"allowTemplateLiterals": false, "avoidEscape": true}
+ ],
+ "prettier/prettier": "error"
+ }
}
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 00000000..ee41c12f
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,15 @@
+!.env.example
+.DS_Store
+.env
+.env.*
+*.png
+*.svg
+/build
+/package
+node_modules
+xcode
+
+# Ignore files for PNPM, NPM and YARN
+pnpm-lock.yaml
+package-lock.json
+yarn.lock
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 00000000..340347ec
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,18 @@
+{
+ "arrowParens": "always",
+ "bracketSpacing": false,
+ "bracketSameLine": false,
+ "plugins": ["prettier-plugin-svelte"],
+ "printWidth": 80,
+ "quoteProps": "as-needed",
+ "semi": true,
+ "singleAttributePerLine": false,
+ "singleQuote": false,
+ "tabWidth": 4,
+ "trailingComma": "none",
+ "useTabs": true,
+ "overrides": [
+ {"files": "*.svelte", "options": {"parser": "svelte"}},
+ {"files": "*.yml", "options": {"tabWidth": 2, "useTabs": false}}
+ ]
+}
diff --git a/.stylelintrc.json b/.stylelintrc.json
index ea60b077..2504a70b 100644
--- a/.stylelintrc.json
+++ b/.stylelintrc.json
@@ -1,29 +1,39 @@
{
- "extends": [
- "stylelint-config-recommended",
- "stylelint-config-standard",
- "stylelint-config-html/svelte"
- ],
- "ignoreFiles": [
- "**/build/**",
- "**/dist/**",
- "**/etc/**",
- "**/node_modules/**",
- "**/reset.css"
- ],
- "rules": {
- "alpha-value-notation": "number",
- "comment-empty-line-before": ["always",{
- "ignore": ["after-comment", "stylelint-commands"]
- }],
- "custom-property-empty-line-before": null,
- "indentation": 4,
- "max-empty-lines": 1,
- "no-descending-specificity": null,
- "property-no-vendor-prefix": null,
- "selector-class-pattern": null,
- "selector-pseudo-class-no-unknown": [true, {
- "ignorePseudoClasses": ["global"]
- }]
- }
+ "extends": [
+ "stylelint-config-standard",
+ "stylelint-prettier/recommended",
+ "stylelint-config-prettier"
+ ],
+ "ignoreFiles": [
+ "**/node_modules/**",
+ "**/reset.css",
+ "xcode/**/*"
+ ],
+ "plugins": ["stylelint-order"],
+ "rules": {
+ "alpha-value-notation": "number",
+ "custom-property-empty-line-before": "never",
+ "declaration-block-no-duplicate-properties": true,
+ "order/properties-alphabetical-order": true,
+ "property-no-vendor-prefix": true,
+ "selector-class-pattern": [
+ "^[a-z]([-]?[a-z0-9]+)*(__[a-z0-9]([-]?[a-z0-9]+)*)?(--[a-z0-9]([-]?[a-z0-9]+)*)?$",
+ {
+ "resolveNestedSelectors": true,
+ "message": "Expected class selector to match BEM CSS pattern https://en.bem.info/methodology/css. Regex examples: https://regex101.com/r/DhEhbS/1"
+ }
+ ],
+ "selector-pseudo-class-no-unknown": [
+ true,
+ {
+ "ignorePseudoClasses": ["global"]
+ }
+ ]
+ },
+ "overrides": [
+ {
+ "customSyntax": "postcss-html",
+ "files": ["**/*svelte"]
+ }
+ ]
}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index ffec34dc..375327e7 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,24 +1,7 @@
{
- "editor.formatOnSave": false,
- "files.associations": {
- ".htmlhintrc": "json"
- },
- "eslint.validate": [
- "svelte"
- ],
- "stylelint.validate": [
- "css",
- "postcss",
- "svelte"
- ],
- "svelte.plugin.svelte.compilerWarnings": {
- "a11y-missing-attribute": "error"
- },
- "svelte.plugin.svelte.rename.enable": false,
- "[svelte]": {
- "editor.defaultFormatter": "svelte.svelte-vscode"
- },
- "[css]": {
- "editor.defaultFormatter": "stylelint.vscode-stylelint"
- }
+ "eslint.validate": ["javascript", "svelte"],
+ "stylelint.validate": ["css", "postcss", "svelte"],
+ "[svelte]": {
+ "editor.defaultFormatter": "svelte.svelte-vscode"
+ }
}
diff --git a/package.json b/package.json
index b6e5e482..ac87a448 100644
--- a/package.json
+++ b/package.json
@@ -1,28 +1,33 @@
{
- "name": "userscripts",
- "private": true,
- "type": "module",
- "scripts": {
- "dev": "vite",
- "build": "vite build",
- "lint-js": "eslint ./",
- "lint-css": "stylelint '**/*.{css,svelte}'"
- },
- "devDependencies": {
- "@sveltejs/vite-plugin-svelte": "^2.0.3",
- "autoprefixer": "^10.4.13",
- "cm-show-invisibles": "^3.1.0",
- "codemirror": "^5.65.12",
- "eslint": "^8.35.0",
- "eslint-config-airbnb-base": "^15.0.0",
- "eslint-plugin-import": "^2.27.5",
- "eslint-plugin-svelte3": "^4.0.0",
- "postcss-html": "^1.5.0",
- "stylelint": "^15.2.0",
- "stylelint-config-html": "^1.1.0",
- "stylelint-config-recommended": "^10.0.1",
- "stylelint-config-standard": "^30.0.1",
- "svelte": "^3.55.1",
- "vite": "^4.1.4"
- }
+ "name": "userscripts",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "lint-js": "eslint ./",
+ "lint-css": "stylelint '**/*.{css,svelte}'"
+ },
+ "devDependencies": {
+ "@sveltejs/vite-plugin-svelte": "^2.0.3",
+ "autoprefixer": "^10.4.13",
+ "cm-show-invisibles": "^3.1.0",
+ "codemirror": "^5.65.12",
+ "eslint": "^8.35.0",
+ "eslint-config-prettier": "^8.8.0",
+ "eslint-plugin-prettier": "^4.2.1",
+ "eslint-plugin-svelte": "^2.27.2",
+ "postcss": "^8.4.23",
+ "postcss-html": "^1.5.0",
+ "prettier": "^2.8.8",
+ "prettier-plugin-svelte": "^2.10.0",
+ "stylelint": "^14.16.1",
+ "stylelint-config-html": "^1.1.0",
+ "stylelint-config-prettier": "^9.0.5",
+ "stylelint-config-standard": "^29.0.0",
+ "stylelint-order": "^6.0.3",
+ "stylelint-prettier": "^3.0.0",
+ "svelte": "^3.55.1",
+ "vite": "^4.1.4"
+ }
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f5b48ea0..989c0f26 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -6,31 +6,41 @@ specifiers:
cm-show-invisibles: ^3.1.0
codemirror: ^5.65.12
eslint: ^8.35.0
- eslint-config-airbnb-base: ^15.0.0
- eslint-plugin-import: ^2.27.5
- eslint-plugin-svelte3: ^4.0.0
+ eslint-config-prettier: ^8.8.0
+ eslint-plugin-prettier: ^4.2.1
+ eslint-plugin-svelte: ^2.27.2
+ postcss: ^8.4.23
postcss-html: ^1.5.0
- stylelint: ^15.2.0
+ prettier: ^2.8.8
+ prettier-plugin-svelte: ^2.10.0
+ stylelint: ^14.16.1
stylelint-config-html: ^1.1.0
- stylelint-config-recommended: ^10.0.1
- stylelint-config-standard: ^30.0.1
+ stylelint-config-prettier: ^9.0.5
+ stylelint-config-standard: ^29.0.0
+ stylelint-order: ^6.0.3
+ stylelint-prettier: ^3.0.0
svelte: ^3.55.1
vite: ^4.1.4
devDependencies:
'@sveltejs/vite-plugin-svelte': 2.0.3_svelte@3.55.1+vite@4.1.4
- autoprefixer: 10.4.13
+ autoprefixer: 10.4.13_postcss@8.4.23
cm-show-invisibles: 3.1.0
codemirror: 5.65.12
eslint: 8.35.0
- eslint-config-airbnb-base: 15.0.0_yckic57kx266ph64dhq6ozvb54
- eslint-plugin-import: 2.27.5_eslint@8.35.0
- eslint-plugin-svelte3: 4.0.0_n4ieifq2d7jq3sqoe474cgqlim
+ eslint-config-prettier: 8.8.0_eslint@8.35.0
+ eslint-plugin-prettier: 4.2.1_hlw7btvvbpomsbv6wtkjlnqoee
+ eslint-plugin-svelte: 2.27.2_n4ieifq2d7jq3sqoe474cgqlim
+ postcss: 8.4.23
postcss-html: 1.5.0
- stylelint: 15.2.0
- stylelint-config-html: 1.1.0_x2qzl5lwlwnkkekx7bj2y4o6y4
- stylelint-config-recommended: 10.0.1_stylelint@15.2.0
- stylelint-config-standard: 30.0.1_stylelint@15.2.0
+ prettier: 2.8.8
+ prettier-plugin-svelte: 2.10.0_aufncwtidwpazwvtgfg5gzupc4
+ stylelint: 14.16.1
+ stylelint-config-html: 1.1.0_kbto3rg3njmczth2rrsgfnlsqa
+ stylelint-config-prettier: 9.0.5_stylelint@14.16.1
+ stylelint-config-standard: 29.0.0_stylelint@14.16.1
+ stylelint-order: 6.0.3_stylelint@14.16.1
+ stylelint-prettier: 3.0.0_ijjwmmxqo5tkozh2kjbk6pd5e4
svelte: 3.55.1
vite: 4.1.4
@@ -57,39 +67,14 @@ packages:
js-tokens: 4.0.0
dev: true
- /@csstools/css-parser-algorithms/2.0.1_5vzy4lghjvuzkedkkk4tqwjftm:
- resolution: {integrity: sha512-B9/8PmOtU6nBiibJg0glnNktQDZ3rZnGn/7UmDfrm2vMtrdlXO3p7ErE95N0up80IRk9YEtB5jyj/TmQ1WH3dw==}
- engines: {node: ^14 || ^16 || >=18}
- peerDependencies:
- '@csstools/css-tokenizer': ^2.0.0
- dependencies:
- '@csstools/css-tokenizer': 2.1.0
- dev: true
-
- /@csstools/css-tokenizer/2.1.0:
- resolution: {integrity: sha512-dtqFyoJBHUxGi9zPZdpCKP1xk8tq6KPHJ/NY4qWXiYo6IcSGwzk3L8x2XzZbbyOyBs9xQARoGveU2AsgLj6D2A==}
- engines: {node: ^14 || ^16 || >=18}
- dev: true
-
- /@csstools/media-query-list-parser/2.0.1_ppok7cytzjc65mcyxmtit3wdyi:
- resolution: {integrity: sha512-X2/OuzEbjaxhzm97UJ+95GrMeT29d1Ib+Pu+paGLuRWZnWRK9sI9r3ikmKXPWGA1C4y4JEdBEFpp9jEqCvLeRA==}
- engines: {node: ^14 || ^16 || >=18}
- peerDependencies:
- '@csstools/css-parser-algorithms': ^2.0.0
- '@csstools/css-tokenizer': ^2.0.0
- dependencies:
- '@csstools/css-parser-algorithms': 2.0.1_5vzy4lghjvuzkedkkk4tqwjftm
- '@csstools/css-tokenizer': 2.1.0
- dev: true
-
- /@csstools/selector-specificity/2.1.1_wajs5nedgkikc5pcuwett7legi:
+ /@csstools/selector-specificity/2.1.1_s3s7cysqdh2c5ra7frs7uhrtc4:
resolution: {integrity: sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw==}
engines: {node: ^14 || ^16 || >=18}
peerDependencies:
postcss: ^8.4
postcss-selector-parser: ^6.0.10
dependencies:
- postcss: 8.4.21
+ postcss: 8.4.23
postcss-selector-parser: 6.0.11
dev: true
@@ -291,6 +276,16 @@ packages:
dev: true
optional: true
+ /@eslint-community/eslint-utils/4.4.0_eslint@8.35.0:
+ resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+ dependencies:
+ eslint: 8.35.0
+ eslint-visitor-keys: 3.3.0
+ dev: true
+
/@eslint/eslintrc/2.0.0:
resolution: {integrity: sha512-fluIaaV+GyV24CCu/ggiHdV+j4RNh85yQnAYS/G2mZODZgGmmlrgCydjUcV3YvxCm9x8nMAfThsqTni4KiXT4A==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -377,10 +372,6 @@ packages:
- supports-color
dev: true
- /@types/json5/0.0.29:
- resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
- dev: true
-
/@types/minimist/1.2.2:
resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==}
dev: true
@@ -389,6 +380,10 @@ packages:
resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
dev: true
+ /@types/parse-json/4.0.0:
+ resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==}
+ dev: true
+
/acorn-jsx/5.3.2_acorn@8.8.2:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
@@ -444,42 +439,11 @@ packages:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
dev: true
- /array-includes/3.1.6:
- resolution: {integrity: sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.2
- define-properties: 1.2.0
- es-abstract: 1.21.1
- get-intrinsic: 1.2.0
- is-string: 1.0.7
- dev: true
-
/array-union/2.1.0:
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
engines: {node: '>=8'}
dev: true
- /array.prototype.flat/1.3.1:
- resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.2
- define-properties: 1.2.0
- es-abstract: 1.21.1
- es-shim-unscopables: 1.0.0
- dev: true
-
- /array.prototype.flatmap/1.3.1:
- resolution: {integrity: sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.2
- define-properties: 1.2.0
- es-abstract: 1.21.1
- es-shim-unscopables: 1.0.0
- dev: true
-
/arrify/1.0.1:
resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==}
engines: {node: '>=0.10.0'}
@@ -490,7 +454,7 @@ packages:
engines: {node: '>=8'}
dev: true
- /autoprefixer/10.4.13:
+ /autoprefixer/10.4.13_postcss@8.4.23:
resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==}
engines: {node: ^10 || ^12 || >=14}
hasBin: true
@@ -502,14 +466,10 @@ packages:
fraction.js: 4.2.0
normalize-range: 0.1.2
picocolors: 1.0.0
+ postcss: 8.4.23
postcss-value-parser: 4.2.0
dev: true
- /available-typed-arrays/1.0.5:
- resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==}
- engines: {node: '>= 0.4'}
- dev: true
-
/balanced-match/1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
dev: true
@@ -543,13 +503,6 @@ packages:
update-browserslist-db: 1.0.10_browserslist@4.21.5
dev: true
- /call-bind/1.0.2:
- resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
- dependencies:
- function-bind: 1.1.1
- get-intrinsic: 1.2.0
- dev: true
-
/callsites/3.1.0:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
@@ -627,18 +580,15 @@ packages:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
dev: true
- /confusing-browser-globals/1.0.11:
- resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==}
- dev: true
-
- /cosmiconfig/8.1.0:
- resolution: {integrity: sha512-0tLZ9URlPGU7JsKq0DQOQ3FoRsYX8xDZ7xMiATQfaiGMz7EHowNkbU9u1coAOmnh9p/1ySpm0RB3JNWRXM5GCg==}
- engines: {node: '>=14'}
+ /cosmiconfig/7.1.0:
+ resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==}
+ engines: {node: '>=10'}
dependencies:
+ '@types/parse-json': 4.0.0
import-fresh: 3.3.0
- js-yaml: 4.1.0
parse-json: 5.2.0
path-type: 4.0.0
+ yaml: 1.10.2
dev: true
/cross-spawn/7.0.3:
@@ -655,31 +605,12 @@ packages:
engines: {node: '>=12.22'}
dev: true
- /css-tree/2.3.1:
- resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
- engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
- dependencies:
- mdn-data: 2.0.30
- source-map-js: 1.0.2
- dev: true
-
/cssesc/3.0.0:
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
engines: {node: '>=4'}
hasBin: true
dev: true
- /debug/3.2.7:
- resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
- peerDependencies:
- supports-color: '*'
- peerDependenciesMeta:
- supports-color:
- optional: true
- dependencies:
- ms: 2.1.3
- dev: true
-
/debug/4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
@@ -714,14 +645,6 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
- /define-properties/1.2.0:
- resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==}
- engines: {node: '>= 0.4'}
- dependencies:
- has-property-descriptors: 1.0.0
- object-keys: 1.1.1
- dev: true
-
/dir-glob/3.0.1:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'}
@@ -729,13 +652,6 @@ packages:
path-type: 4.0.0
dev: true
- /doctrine/2.1.0:
- resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
- engines: {node: '>=0.10.0'}
- dependencies:
- esutils: 2.0.3
- dev: true
-
/doctrine/3.0.0:
resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
engines: {node: '>=6.0.0'}
@@ -789,69 +705,6 @@ packages:
is-arrayish: 0.2.1
dev: true
- /es-abstract/1.21.1:
- resolution: {integrity: sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==}
- engines: {node: '>= 0.4'}
- dependencies:
- available-typed-arrays: 1.0.5
- call-bind: 1.0.2
- es-set-tostringtag: 2.0.1
- es-to-primitive: 1.2.1
- function-bind: 1.1.1
- function.prototype.name: 1.1.5
- get-intrinsic: 1.2.0
- get-symbol-description: 1.0.0
- globalthis: 1.0.3
- gopd: 1.0.1
- has: 1.0.3
- has-property-descriptors: 1.0.0
- has-proto: 1.0.1
- has-symbols: 1.0.3
- internal-slot: 1.0.5
- is-array-buffer: 3.0.1
- is-callable: 1.2.7
- is-negative-zero: 2.0.2
- is-regex: 1.1.4
- is-shared-array-buffer: 1.0.2
- is-string: 1.0.7
- is-typed-array: 1.1.10
- is-weakref: 1.0.2
- object-inspect: 1.12.3
- object-keys: 1.1.1
- object.assign: 4.1.4
- regexp.prototype.flags: 1.4.3
- safe-regex-test: 1.0.0
- string.prototype.trimend: 1.0.6
- string.prototype.trimstart: 1.0.6
- typed-array-length: 1.0.4
- unbox-primitive: 1.0.2
- which-typed-array: 1.1.9
- dev: true
-
- /es-set-tostringtag/2.0.1:
- resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==}
- engines: {node: '>= 0.4'}
- dependencies:
- get-intrinsic: 1.2.0
- has: 1.0.3
- has-tostringtag: 1.0.0
- dev: true
-
- /es-shim-unscopables/1.0.0:
- resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==}
- dependencies:
- has: 1.0.3
- dev: true
-
- /es-to-primitive/1.2.1:
- resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
- engines: {node: '>= 0.4'}
- dependencies:
- is-callable: 1.2.7
- is-date-object: 1.0.5
- is-symbol: 1.0.4
- dev: true
-
/esbuild/0.16.17:
resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==}
engines: {node: '>=12'}
@@ -897,99 +750,56 @@ packages:
engines: {node: '>=10'}
dev: true
- /eslint-config-airbnb-base/15.0.0_yckic57kx266ph64dhq6ozvb54:
- resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==}
- engines: {node: ^10.12.0 || >=12.0.0}
+ /eslint-config-prettier/8.8.0_eslint@8.35.0:
+ resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==}
+ hasBin: true
peerDependencies:
- eslint: ^7.32.0 || ^8.2.0
- eslint-plugin-import: ^2.25.2
+ eslint: '>=7.0.0'
dependencies:
- confusing-browser-globals: 1.0.11
eslint: 8.35.0
- eslint-plugin-import: 2.27.5_eslint@8.35.0
- object.assign: 4.1.4
- object.entries: 1.1.6
- semver: 6.3.0
dev: true
- /eslint-import-resolver-node/0.3.7:
- resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==}
- dependencies:
- debug: 3.2.7
- is-core-module: 2.11.0
- resolve: 1.22.1
- transitivePeerDependencies:
- - supports-color
- dev: true
-
- /eslint-module-utils/2.7.4_noxuapdo33xou3o5tg3un5cxoy:
- resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==}
- engines: {node: '>=4'}
+ /eslint-plugin-prettier/4.2.1_hlw7btvvbpomsbv6wtkjlnqoee:
+ resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==}
+ engines: {node: '>=12.0.0'}
peerDependencies:
- '@typescript-eslint/parser': '*'
- eslint: '*'
- eslint-import-resolver-node: '*'
- eslint-import-resolver-typescript: '*'
- eslint-import-resolver-webpack: '*'
+ eslint: '>=7.28.0'
+ eslint-config-prettier: '*'
+ prettier: '>=2.0.0'
peerDependenciesMeta:
- '@typescript-eslint/parser':
- optional: true
- eslint:
- optional: true
- eslint-import-resolver-node:
- optional: true
- eslint-import-resolver-typescript:
- optional: true
- eslint-import-resolver-webpack:
+ eslint-config-prettier:
optional: true
dependencies:
- debug: 3.2.7
eslint: 8.35.0
- eslint-import-resolver-node: 0.3.7
- transitivePeerDependencies:
- - supports-color
+ eslint-config-prettier: 8.8.0_eslint@8.35.0
+ prettier: 2.8.8
+ prettier-linter-helpers: 1.0.0
dev: true
- /eslint-plugin-import/2.27.5_eslint@8.35.0:
- resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==}
- engines: {node: '>=4'}
+ /eslint-plugin-svelte/2.27.2_n4ieifq2d7jq3sqoe474cgqlim:
+ resolution: {integrity: sha512-1tIl65TMF0MtY26+O/1Y5S5HEFc0vRzzoX3m9FHI6VuiruqFU9PBr8WzoqdaSPlcL/q7xPUzQYl4Fzg/3GBpcg==}
+ engines: {node: ^14.17.0 || >=16.0.0}
peerDependencies:
- '@typescript-eslint/parser': '*'
- eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
+ eslint: ^7.0.0 || ^8.0.0-0
+ svelte: ^3.37.0
peerDependenciesMeta:
- '@typescript-eslint/parser':
+ svelte:
optional: true
dependencies:
- array-includes: 3.1.6
- array.prototype.flat: 1.3.1
- array.prototype.flatmap: 1.3.1
- debug: 3.2.7
- doctrine: 2.1.0
+ '@eslint-community/eslint-utils': 4.4.0_eslint@8.35.0
+ '@jridgewell/sourcemap-codec': 1.4.14
+ debug: 4.3.4
eslint: 8.35.0
- eslint-import-resolver-node: 0.3.7
- eslint-module-utils: 2.7.4_noxuapdo33xou3o5tg3un5cxoy
- has: 1.0.3
- is-core-module: 2.11.0
- is-glob: 4.0.3
- minimatch: 3.1.2
- object.values: 1.1.6
- resolve: 1.22.1
- semver: 6.3.0
- tsconfig-paths: 3.14.2
+ esutils: 2.0.3
+ known-css-properties: 0.27.0
+ postcss: 8.4.23
+ postcss-load-config: 3.1.4_postcss@8.4.23
+ postcss-safe-parser: 6.0.0_postcss@8.4.23
+ svelte: 3.55.1
+ svelte-eslint-parser: 0.27.0_svelte@3.55.1
transitivePeerDependencies:
- - eslint-import-resolver-typescript
- - eslint-import-resolver-webpack
- supports-color
- dev: true
-
- /eslint-plugin-svelte3/4.0.0_n4ieifq2d7jq3sqoe474cgqlim:
- resolution: {integrity: sha512-OIx9lgaNzD02+MDFNLw0GEUbuovNcglg+wnd/UY0fbZmlQSz7GlQiQ1f+yX0XvC07XPcDOnFcichqI3xCwp71g==}
- peerDependencies:
- eslint: '>=8.0.0'
- svelte: ^3.2.0
- dependencies:
- eslint: 8.35.0
- svelte: 3.55.1
+ - ts-node
dev: true
/eslint-scope/7.1.1:
@@ -1106,6 +916,10 @@ packages:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
dev: true
+ /fast-diff/1.2.0:
+ resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==}
+ dev: true
+
/fast-glob/3.2.12:
resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==}
engines: {node: '>=8.6.0'}
@@ -1178,12 +992,6 @@ packages:
resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
dev: true
- /for-each/0.3.3:
- resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
- dependencies:
- is-callable: 1.2.7
- dev: true
-
/fraction.js/4.2.0:
resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
dev: true
@@ -1204,36 +1012,6 @@ packages:
resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
dev: true
- /function.prototype.name/1.1.5:
- resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.2
- define-properties: 1.2.0
- es-abstract: 1.21.1
- functions-have-names: 1.2.3
- dev: true
-
- /functions-have-names/1.2.3:
- resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
- dev: true
-
- /get-intrinsic/1.2.0:
- resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==}
- dependencies:
- function-bind: 1.1.1
- has: 1.0.3
- has-symbols: 1.0.3
- dev: true
-
- /get-symbol-description/1.0.0:
- resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.2
- get-intrinsic: 1.2.0
- dev: true
-
/glob-parent/5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@@ -1282,13 +1060,6 @@ packages:
type-fest: 0.20.2
dev: true
- /globalthis/1.0.3:
- resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==}
- engines: {node: '>= 0.4'}
- dependencies:
- define-properties: 1.2.0
- dev: true
-
/globby/11.1.0:
resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
engines: {node: '>=10'}
@@ -1305,12 +1076,6 @@ packages:
resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==}
dev: true
- /gopd/1.0.1:
- resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
- dependencies:
- get-intrinsic: 1.2.0
- dev: true
-
/grapheme-splitter/1.0.4:
resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
dev: true
@@ -1320,10 +1085,6 @@ packages:
engines: {node: '>=6'}
dev: true
- /has-bigints/1.0.2:
- resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
- dev: true
-
/has-flag/3.0.0:
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
engines: {node: '>=4'}
@@ -1334,29 +1095,6 @@ packages:
engines: {node: '>=8'}
dev: true
- /has-property-descriptors/1.0.0:
- resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==}
- dependencies:
- get-intrinsic: 1.2.0
- dev: true
-
- /has-proto/1.0.1:
- resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==}
- engines: {node: '>= 0.4'}
- dev: true
-
- /has-symbols/1.0.3:
- resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
- engines: {node: '>= 0.4'}
- dev: true
-
- /has-tostringtag/1.0.0:
- resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==}
- engines: {node: '>= 0.4'}
- dependencies:
- has-symbols: 1.0.3
- dev: true
-
/has/1.0.3:
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
engines: {node: '>= 0.4.0'}
@@ -1432,59 +1170,16 @@ packages:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
dev: true
- /internal-slot/1.0.5:
- resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==}
- engines: {node: '>= 0.4'}
- dependencies:
- get-intrinsic: 1.2.0
- has: 1.0.3
- side-channel: 1.0.4
- dev: true
-
- /is-array-buffer/3.0.1:
- resolution: {integrity: sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==}
- dependencies:
- call-bind: 1.0.2
- get-intrinsic: 1.2.0
- is-typed-array: 1.1.10
- dev: true
-
/is-arrayish/0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
dev: true
- /is-bigint/1.0.4:
- resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
- dependencies:
- has-bigints: 1.0.2
- dev: true
-
- /is-boolean-object/1.1.2:
- resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.2
- has-tostringtag: 1.0.0
- dev: true
-
- /is-callable/1.2.7:
- resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
- engines: {node: '>= 0.4'}
- dev: true
-
/is-core-module/2.11.0:
resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==}
dependencies:
has: 1.0.3
dev: true
- /is-date-object/1.0.5:
- resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
- engines: {node: '>= 0.4'}
- dependencies:
- has-tostringtag: 1.0.0
- dev: true
-
/is-extglob/2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
@@ -1502,18 +1197,6 @@ packages:
is-extglob: 2.1.1
dev: true
- /is-negative-zero/2.0.2:
- resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==}
- engines: {node: '>= 0.4'}
- dev: true
-
- /is-number-object/1.0.7:
- resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
- engines: {node: '>= 0.4'}
- dependencies:
- has-tostringtag: 1.0.0
- dev: true
-
/is-number/7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
@@ -1534,51 +1217,6 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
- /is-regex/1.1.4:
- resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.2
- has-tostringtag: 1.0.0
- dev: true
-
- /is-shared-array-buffer/1.0.2:
- resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==}
- dependencies:
- call-bind: 1.0.2
- dev: true
-
- /is-string/1.0.7:
- resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
- engines: {node: '>= 0.4'}
- dependencies:
- has-tostringtag: 1.0.0
- dev: true
-
- /is-symbol/1.0.4:
- resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
- engines: {node: '>= 0.4'}
- dependencies:
- has-symbols: 1.0.3
- dev: true
-
- /is-typed-array/1.1.10:
- resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==}
- engines: {node: '>= 0.4'}
- dependencies:
- available-typed-arrays: 1.0.5
- call-bind: 1.0.2
- for-each: 0.3.3
- gopd: 1.0.1
- has-tostringtag: 1.0.0
- dev: true
-
- /is-weakref/1.0.2:
- resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
- dependencies:
- call-bind: 1.0.2
- dev: true
-
/isexe/2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
dev: true
@@ -1618,13 +1256,6 @@ packages:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
dev: true
- /json5/1.0.2:
- resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
- hasBin: true
- dependencies:
- minimist: 1.2.8
- dev: true
-
/kind-of/6.0.3:
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
engines: {node: '>=0.10.0'}
@@ -1639,6 +1270,10 @@ packages:
resolution: {integrity: sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg==}
dev: true
+ /known-css-properties/0.27.0:
+ resolution: {integrity: sha512-uMCj6+hZYDoffuvAJjFAPz56E9uoowFHmTkqRtRq5WyC5Q6Cu/fTZKNQpX/RbzChBYLLl3lo8CjFZBAZXq9qFg==}
+ dev: true
+
/levn/0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
@@ -1647,6 +1282,11 @@ packages:
type-check: 0.4.0
dev: true
+ /lilconfig/2.1.0:
+ resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
+ engines: {node: '>=10'}
+ dev: true
+
/lines-and-columns/1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
dev: true
@@ -1701,10 +1341,6 @@ packages:
resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==}
dev: true
- /mdn-data/2.0.30:
- resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
- dev: true
-
/meow/9.0.0:
resolution: {integrity: sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==}
engines: {node: '>=10'}
@@ -1756,20 +1392,12 @@ packages:
kind-of: 6.0.3
dev: true
- /minimist/1.2.8:
- resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
- dev: true
-
/ms/2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
dev: true
- /ms/2.1.3:
- resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
- dev: true
-
- /nanoid/3.3.4:
- resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==}
+ /nanoid/3.3.6:
+ resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
dev: true
@@ -1811,43 +1439,6 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
- /object-inspect/1.12.3:
- resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==}
- dev: true
-
- /object-keys/1.1.1:
- resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
- engines: {node: '>= 0.4'}
- dev: true
-
- /object.assign/4.1.4:
- resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.2
- define-properties: 1.2.0
- has-symbols: 1.0.3
- object-keys: 1.1.1
- dev: true
-
- /object.entries/1.1.6:
- resolution: {integrity: sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.2
- define-properties: 1.2.0
- es-abstract: 1.21.1
- dev: true
-
- /object.values/1.1.6:
- resolution: {integrity: sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.2
- define-properties: 1.2.0
- es-abstract: 1.21.1
- dev: true
-
/once/1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
dependencies:
@@ -1955,8 +1546,25 @@ packages:
dependencies:
htmlparser2: 8.0.1
js-tokens: 8.0.1
- postcss: 8.4.21
- postcss-safe-parser: 6.0.0_postcss@8.4.21
+ postcss: 8.4.23
+ postcss-safe-parser: 6.0.0_postcss@8.4.23
+ dev: true
+
+ /postcss-load-config/3.1.4_postcss@8.4.23:
+ resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
+ engines: {node: '>= 10'}
+ peerDependencies:
+ postcss: '>=8.0.9'
+ ts-node: '>=9.0.0'
+ peerDependenciesMeta:
+ postcss:
+ optional: true
+ ts-node:
+ optional: true
+ dependencies:
+ lilconfig: 2.1.0
+ postcss: 8.4.23
+ yaml: 1.10.2
dev: true
/postcss-media-query-parser/0.2.3:
@@ -1967,13 +1575,13 @@ packages:
resolution: {integrity: sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==}
dev: true
- /postcss-safe-parser/6.0.0_postcss@8.4.21:
+ /postcss-safe-parser/6.0.0_postcss@8.4.23:
resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==}
engines: {node: '>=12.0'}
peerDependencies:
postcss: ^8.3.3
dependencies:
- postcss: 8.4.21
+ postcss: 8.4.23
dev: true
/postcss-selector-parser/6.0.11:
@@ -1984,15 +1592,23 @@ packages:
util-deprecate: 1.0.2
dev: true
+ /postcss-sorting/8.0.2_postcss@8.4.23:
+ resolution: {integrity: sha512-M9dkSrmU00t/jK7rF6BZSZauA5MAaBW4i5EnJXspMwt4iqTh/L9j6fgMnbElEOfyRyfLfVbIHj/R52zHzAPe1Q==}
+ peerDependencies:
+ postcss: ^8.4.20
+ dependencies:
+ postcss: 8.4.23
+ dev: true
+
/postcss-value-parser/4.2.0:
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
dev: true
- /postcss/8.4.21:
- resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==}
+ /postcss/8.4.23:
+ resolution: {integrity: sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==}
engines: {node: ^10 || ^12 || >=14}
dependencies:
- nanoid: 3.3.4
+ nanoid: 3.3.6
picocolors: 1.0.0
source-map-js: 1.0.2
dev: true
@@ -2002,6 +1618,29 @@ packages:
engines: {node: '>= 0.8.0'}
dev: true
+ /prettier-linter-helpers/1.0.0:
+ resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ fast-diff: 1.2.0
+ dev: true
+
+ /prettier-plugin-svelte/2.10.0_aufncwtidwpazwvtgfg5gzupc4:
+ resolution: {integrity: sha512-GXMY6t86thctyCvQq+jqElO+MKdB09BkL3hexyGP3Oi8XLKRFaJP1ud/xlWCZ9ZIa2BxHka32zhHfcuU+XsRQg==}
+ peerDependencies:
+ prettier: ^1.16.4 || ^2.0.0
+ svelte: ^3.2.0
+ dependencies:
+ prettier: 2.8.8
+ svelte: 3.55.1
+ dev: true
+
+ /prettier/2.8.8:
+ resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==}
+ engines: {node: '>=10.13.0'}
+ hasBin: true
+ dev: true
+
/punycode/2.3.0:
resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
engines: {node: '>=6'}
@@ -2043,15 +1682,6 @@ packages:
strip-indent: 3.0.0
dev: true
- /regexp.prototype.flags/1.4.3:
- resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.2
- define-properties: 1.2.0
- functions-have-names: 1.2.3
- dev: true
-
/regexpp/3.2.0:
resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==}
engines: {node: '>=8'}
@@ -2107,24 +1737,11 @@ packages:
queue-microtask: 1.2.3
dev: true
- /safe-regex-test/1.0.0:
- resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==}
- dependencies:
- call-bind: 1.0.2
- get-intrinsic: 1.2.0
- is-regex: 1.1.4
- dev: true
-
/semver/5.7.1:
resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==}
hasBin: true
dev: true
- /semver/6.3.0:
- resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==}
- hasBin: true
- dev: true
-
/semver/7.3.8:
resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==}
engines: {node: '>=10'}
@@ -2145,14 +1762,6 @@ packages:
engines: {node: '>=8'}
dev: true
- /side-channel/1.0.4:
- resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
- dependencies:
- call-bind: 1.0.2
- get-intrinsic: 1.2.0
- object-inspect: 1.12.3
- dev: true
-
/signal-exit/3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
dev: true
@@ -2207,22 +1816,6 @@ packages:
strip-ansi: 6.0.1
dev: true
- /string.prototype.trimend/1.0.6:
- resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==}
- dependencies:
- call-bind: 1.0.2
- define-properties: 1.2.0
- es-abstract: 1.21.1
- dev: true
-
- /string.prototype.trimstart/1.0.6:
- resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==}
- dependencies:
- call-bind: 1.0.2
- define-properties: 1.2.0
- es-abstract: 1.21.1
- dev: true
-
/strip-ansi/6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
@@ -2230,11 +1823,6 @@ packages:
ansi-regex: 5.0.1
dev: true
- /strip-bom/3.0.0:
- resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
- engines: {node: '>=4'}
- dev: true
-
/strip-indent/3.0.0:
resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
engines: {node: '>=8'}
@@ -2251,7 +1839,7 @@ packages:
resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==}
dev: true
- /stylelint-config-html/1.1.0_x2qzl5lwlwnkkekx7bj2y4o6y4:
+ /stylelint-config-html/1.1.0_kbto3rg3njmczth2rrsgfnlsqa:
resolution: {integrity: sha512-IZv4IVESjKLumUGi+HWeb7skgO6/g4VMuAYrJdlqQFndgbj6WJAXPhaysvBiXefX79upBdQVumgYcdd17gCpjQ==}
engines: {node: ^12 || >=14}
peerDependencies:
@@ -2259,40 +1847,68 @@ packages:
stylelint: '>=14.0.0'
dependencies:
postcss-html: 1.5.0
- stylelint: 15.2.0
+ stylelint: 14.16.1
dev: true
- /stylelint-config-recommended/10.0.1_stylelint@15.2.0:
- resolution: {integrity: sha512-TQ4xQ48tW4QSlODcti7pgSRqBZcUaBzuh0jPpfiMhwJKBPkqzTIAU+IrSWL/7BgXlOM90DjB7YaNgFpx8QWhuA==}
+ /stylelint-config-prettier/9.0.5_stylelint@14.16.1:
+ resolution: {integrity: sha512-U44lELgLZhbAD/xy/vncZ2Pq8sh2TnpiPvo38Ifg9+zeioR+LAkHu0i6YORIOxFafZoVg0xqQwex6e6F25S5XA==}
+ engines: {node: '>= 12'}
+ hasBin: true
peerDependencies:
- stylelint: ^15.0.0
+ stylelint: '>= 11.x < 15'
dependencies:
- stylelint: 15.2.0
+ stylelint: 14.16.1
dev: true
- /stylelint-config-standard/30.0.1_stylelint@15.2.0:
- resolution: {integrity: sha512-NbeHOmpRQhjZh5XB1B/S4MLRWvz4xxAxeDBjzl0tY2xEcayNhLbaRGF0ZQzq+DQZLCcPpOHeS2Ru1ydbkhkmLg==}
+ /stylelint-config-recommended/9.0.0_stylelint@14.16.1:
+ resolution: {integrity: sha512-9YQSrJq4NvvRuTbzDsWX3rrFOzOlYBmZP+o513BJN/yfEmGSr0AxdvrWs0P/ilSpVV/wisamAHu5XSk8Rcf4CQ==}
peerDependencies:
- stylelint: ^15.0.0
+ stylelint: ^14.10.0
dependencies:
- stylelint: 15.2.0
- stylelint-config-recommended: 10.0.1_stylelint@15.2.0
+ stylelint: 14.16.1
dev: true
- /stylelint/15.2.0:
- resolution: {integrity: sha512-wjg5OLn8zQwjlj5cYUgyQpMWKzct42AG5dYlqkHRJQJqsystFFn3onqEc263KH4xfEI0W3lZCnlIhFfS64uwSA==}
- engines: {node: ^14.13.1 || >=16.0.0}
+ /stylelint-config-standard/29.0.0_stylelint@14.16.1:
+ resolution: {integrity: sha512-uy8tZLbfq6ZrXy4JKu3W+7lYLgRQBxYTUUB88vPgQ+ZzAxdrvcaSUW9hOMNLYBnwH+9Kkj19M2DHdZ4gKwI7tg==}
+ peerDependencies:
+ stylelint: ^14.14.0
+ dependencies:
+ stylelint: 14.16.1
+ stylelint-config-recommended: 9.0.0_stylelint@14.16.1
+ dev: true
+
+ /stylelint-order/6.0.3_stylelint@14.16.1:
+ resolution: {integrity: sha512-1j1lOb4EU/6w49qZeT2SQVJXm0Ht+Qnq9GMfUa3pMwoyojIWfuA+JUDmoR97Bht1RLn4ei0xtLGy87M7d29B1w==}
+ peerDependencies:
+ stylelint: ^14.0.0 || ^15.0.0
+ dependencies:
+ postcss: 8.4.23
+ postcss-sorting: 8.0.2_postcss@8.4.23
+ stylelint: 14.16.1
+ dev: true
+
+ /stylelint-prettier/3.0.0_ijjwmmxqo5tkozh2kjbk6pd5e4:
+ resolution: {integrity: sha512-kIks1xw6np0zElokMT2kP6ar3S4MBoj6vUtPJuND1pFELMpZxVS/0uHPR4HDAVn0WAD3I5oF0IA3qBFxBpMkLg==}
+ engines: {node: ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ prettier: '>=2.0.0'
+ stylelint: '>=14.0.0'
+ dependencies:
+ prettier: 2.8.8
+ prettier-linter-helpers: 1.0.0
+ stylelint: 14.16.1
+ dev: true
+
+ /stylelint/14.16.1:
+ resolution: {integrity: sha512-ErlzR/T3hhbV+a925/gbfc3f3Fep9/bnspMiJPorfGEmcBbXdS+oo6LrVtoUZ/w9fqD6o6k7PtUlCOsCRdjX/A==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
hasBin: true
dependencies:
- '@csstools/css-parser-algorithms': 2.0.1_5vzy4lghjvuzkedkkk4tqwjftm
- '@csstools/css-tokenizer': 2.1.0
- '@csstools/media-query-list-parser': 2.0.1_ppok7cytzjc65mcyxmtit3wdyi
- '@csstools/selector-specificity': 2.1.1_wajs5nedgkikc5pcuwett7legi
+ '@csstools/selector-specificity': 2.1.1_s3s7cysqdh2c5ra7frs7uhrtc4
balanced-match: 2.0.0
colord: 2.9.3
- cosmiconfig: 8.1.0
+ cosmiconfig: 7.1.0
css-functions-list: 3.1.0
- css-tree: 2.3.1
debug: 4.3.4
fast-glob: 3.2.12
fastest-levenshtein: 1.0.16
@@ -2311,10 +1927,10 @@ packages:
micromatch: 4.0.5
normalize-path: 3.0.0
picocolors: 1.0.0
- postcss: 8.4.21
+ postcss: 8.4.23
postcss-media-query-parser: 0.2.3
postcss-resolve-nested-selector: 0.1.1
- postcss-safe-parser: 6.0.0_postcss@8.4.21
+ postcss-safe-parser: 6.0.0_postcss@8.4.23
postcss-selector-parser: 6.0.11
postcss-value-parser: 4.2.0
resolve-from: 5.0.0
@@ -2325,7 +1941,7 @@ packages:
svg-tags: 1.0.0
table: 6.8.1
v8-compile-cache: 2.3.0
- write-file-atomic: 5.0.0
+ write-file-atomic: 4.0.2
transitivePeerDependencies:
- supports-color
dev: true
@@ -2357,6 +1973,21 @@ packages:
engines: {node: '>= 0.4'}
dev: true
+ /svelte-eslint-parser/0.27.0_svelte@3.55.1:
+ resolution: {integrity: sha512-x9cBbCZwLdCnNE3yPqGhvAqEl9FCILC6AaV2xRtwzaMCpvpqO7ceONXj9xka3fQFczSqLzkwOxP4Ln4cIQNqXg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ svelte: ^3.37.0
+ peerDependenciesMeta:
+ svelte:
+ optional: true
+ dependencies:
+ eslint-scope: 7.1.1
+ eslint-visitor-keys: 3.3.0
+ espree: 9.4.1
+ svelte: 3.55.1
+ dev: true
+
/svelte-hmr/0.15.1_svelte@3.55.1:
resolution: {integrity: sha512-BiKB4RZ8YSwRKCNVdNxK/GfY+r4Kjgp9jCLEy0DuqAKfmQtpL38cQK3afdpjw4sqSs4PLi3jIPJIFp259NkZtA==}
engines: {node: ^12.20 || ^14.13.1 || >= 16}
@@ -2402,15 +2033,6 @@ packages:
engines: {node: '>=8'}
dev: true
- /tsconfig-paths/3.14.2:
- resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==}
- dependencies:
- '@types/json5': 0.0.29
- json5: 1.0.2
- minimist: 1.2.8
- strip-bom: 3.0.0
- dev: true
-
/type-check/0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}
@@ -2438,23 +2060,6 @@ packages:
engines: {node: '>=8'}
dev: true
- /typed-array-length/1.0.4:
- resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==}
- dependencies:
- call-bind: 1.0.2
- for-each: 0.3.3
- is-typed-array: 1.1.10
- dev: true
-
- /unbox-primitive/1.0.2:
- resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
- dependencies:
- call-bind: 1.0.2
- has-bigints: 1.0.2
- has-symbols: 1.0.3
- which-boxed-primitive: 1.0.2
- dev: true
-
/update-browserslist-db/1.0.10_browserslist@4.21.5:
resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==}
hasBin: true
@@ -2513,7 +2118,7 @@ packages:
optional: true
dependencies:
esbuild: 0.16.17
- postcss: 8.4.21
+ postcss: 8.4.23
resolve: 1.22.1
rollup: 3.17.3
optionalDependencies:
@@ -2531,28 +2136,6 @@ packages:
vite: 4.1.4
dev: true
- /which-boxed-primitive/1.0.2:
- resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
- dependencies:
- is-bigint: 1.0.4
- is-boolean-object: 1.1.2
- is-number-object: 1.0.7
- is-string: 1.0.7
- is-symbol: 1.0.4
- dev: true
-
- /which-typed-array/1.1.9:
- resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==}
- engines: {node: '>= 0.4'}
- dependencies:
- available-typed-arrays: 1.0.5
- call-bind: 1.0.2
- for-each: 0.3.3
- gopd: 1.0.1
- has-tostringtag: 1.0.0
- is-typed-array: 1.1.10
- dev: true
-
/which/1.3.1:
resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
hasBin: true
@@ -2577,9 +2160,9 @@ packages:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
dev: true
- /write-file-atomic/5.0.0:
- resolution: {integrity: sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ /write-file-atomic/4.0.2:
+ resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==}
+ engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
dependencies:
imurmurhash: 0.1.4
signal-exit: 3.0.7
@@ -2589,6 +2172,11 @@ packages:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
dev: true
+ /yaml/1.10.2:
+ resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
+ engines: {node: '>= 6'}
+ dev: true
+
/yargs-parser/20.2.9:
resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==}
engines: {node: '>=10'}
From 7b495159cf9855bc6ce1d33893c96521de1e7c3a Mon Sep 17 00:00:00 2001
From: quoid <7660254+quoid@users.noreply.github.com>
Date: Mon, 1 May 2023 13:11:47 -0400
Subject: [PATCH 02/13] chore: update basic type checks
---
jsconfig.json | 48 +++++++++++++++++-------------------------------
package.json | 1 +
pnpm-lock.yaml | 6 ++++++
src/global.d.ts | 15 +++++++++++++++
4 files changed, 39 insertions(+), 31 deletions(-)
create mode 100644 src/global.d.ts
diff --git a/jsconfig.json b/jsconfig.json
index a8284bdf..a9411595 100644
--- a/jsconfig.json
+++ b/jsconfig.json
@@ -1,33 +1,19 @@
{
- "compilerOptions": {
- "moduleResolution": "Node",
- "target": "ESNext",
- "module": "ESNext",
- /**
- * svelte-preprocess cannot figure out whether you have
- * a value or a type, so tell TypeScript to enforce using
- * `import type` instead of `import` for Types.
- */
- "importsNotUsedAsValues": "error",
- "isolatedModules": true,
- "resolveJsonModule": true,
- /**
- * To have warnings / errors of the Svelte compiler at the
- * correct position, enable source maps by default.
- */
- "sourceMap": true,
- "esModuleInterop": true,
- "skipLibCheck": true,
- "forceConsistentCasingInFileNames": true,
- /**
- * Typecheck JS in `.svelte` and `.js` files by default.
- * Disable this if you'd like to use dynamic types.
- */
- // "checkJs": true
- },
- /**
- * Use global.d.ts instead of compilerOptions.types
- * to avoid limiting type declarations.
- */
- "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"]
+ "compilerOptions": {
+ "allowJs": true,
+ "checkJs": true,
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "module": "ESNext",
+ "moduleResolution": "node",
+ "noImplicitAny": false,
+ "paths": {},
+ "resolveJsonModule": true,
+ "skipLibCheck": true,
+ "sourceMap": true,
+ "strict": true,
+ "target": "ESNext"
+ },
+ "exclude": ["node_modules", "src/**/main.js"],
+ "include": ["*.js", "src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"]
}
diff --git a/package.json b/package.json
index ac87a448..ae836d60 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^2.0.3",
+ "@types/webextension-polyfill": "^0.10.0",
"autoprefixer": "^10.4.13",
"cm-show-invisibles": "^3.1.0",
"codemirror": "^5.65.12",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 989c0f26..952fd4ed 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -2,6 +2,7 @@ lockfileVersion: 5.4
specifiers:
'@sveltejs/vite-plugin-svelte': ^2.0.3
+ '@types/webextension-polyfill': ^0.10.0
autoprefixer: ^10.4.13
cm-show-invisibles: ^3.1.0
codemirror: ^5.65.12
@@ -24,6 +25,7 @@ specifiers:
devDependencies:
'@sveltejs/vite-plugin-svelte': 2.0.3_svelte@3.55.1+vite@4.1.4
+ '@types/webextension-polyfill': 0.10.0
autoprefixer: 10.4.13_postcss@8.4.23
cm-show-invisibles: 3.1.0
codemirror: 5.65.12
@@ -384,6 +386,10 @@ packages:
resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==}
dev: true
+ /@types/webextension-polyfill/0.10.0:
+ resolution: {integrity: sha512-If4EcaHzYTqcbNMp/FdReVdRmLL/Te42ivnJII551bYjhX19bWem5m14FERCqdJA732OloGuxCRvLBvcMGsn4A==}
+ dev: true
+
/acorn-jsx/5.3.2_acorn@8.8.2:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
diff --git a/src/global.d.ts b/src/global.d.ts
new file mode 100644
index 00000000..31e3154c
--- /dev/null
+++ b/src/global.d.ts
@@ -0,0 +1,15 @@
+import {Browser} from "webextension-polyfill";
+
+export {};
+
+declare global {
+ var browser: Browser;
+ const webkit: any;
+ interface Window {
+ show: (
+ platform: "ios" | "mac",
+ enabled: boolean,
+ useSettingsInsteadOfPreferences: boolean
+ ) => void;
+ }
+}
From 58d6530b11c5d13eb28916ded426f37c34c6ee74 Mon Sep 17 00:00:00 2001
From: quoid <7660254+quoid@users.noreply.github.com>
Date: Mon, 1 May 2023 16:21:14 -0400
Subject: [PATCH 03/13] chore: update vite dev and build process
---
.gitignore | 9 +-
entry-page.html | 14 -
entry-popup.html | 14 -
index.html | 26 -
package.json | 11 +-
src/App.svelte | 37 --
src/app.css | 82 ---
src/main.js | 8 -
src/page/index.html | 14 +
src/popup/index.html | 14 +
src/scripts/background.js | 501 ++++++++++++++++++
src/scripts/content.js | 500 +++++++++++++++++
src/shared/utils.js | 4 +-
vite.config.js | 216 ++++++--
.../Safari-Extension/Resources/background.js | 487 -----------------
xcode/Safari-Extension/Resources/content.js | 469 ----------------
.../Safari-Extension/Resources/manifest.json | 2 +-
xcode/Userscripts.xcodeproj/project.pbxproj | 34 +-
18 files changed, 1253 insertions(+), 1189 deletions(-)
delete mode 100644 entry-page.html
delete mode 100644 entry-popup.html
delete mode 100644 index.html
delete mode 100644 src/App.svelte
delete mode 100644 src/app.css
delete mode 100644 src/main.js
create mode 100644 src/page/index.html
create mode 100644 src/popup/index.html
create mode 100644 src/scripts/background.js
create mode 100644 src/scripts/content.js
delete mode 100644 xcode/Safari-Extension/Resources/background.js
delete mode 100644 xcode/Safari-Extension/Resources/content.js
diff --git a/.gitignore b/.gitignore
index 73b92ed1..0792aa6a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,10 +35,13 @@ ehthumbs.db
Thumbs.db
# xcode
-xcuserdata/
-*.xcuserstate
*.dev.xcconfig
+*.xcuserstate
+**/Safari-Extension/Resources/*.html
+**/Safari-Extension/Resources/*.js
+**/Safari-Extension/Resources/assets/**/*
XCBuildData
xcode/**/build/
xcode/**/dist/
-# xcode/Userscripts-iOS/Base.lproj/Main.html
\ No newline at end of file
+xcuserdata/
+# xcode/Userscripts-iOS/Base.lproj/Main.html
diff --git a/entry-page.html b/entry-page.html
deleted file mode 100644
index 2e585fc0..00000000
--- a/entry-page.html
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
- Userscripts page
-
-
-
-
-
-
-
diff --git a/entry-popup.html b/entry-popup.html
deleted file mode 100644
index 2694df66..00000000
--- a/entry-popup.html
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
- Userscripts popup
-
-
-
-
-
-
-
diff --git a/index.html b/index.html
deleted file mode 100644
index b97bad98..00000000
--- a/index.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
- Userscripts dev
-
-
-
-
-
-
-
-
diff --git a/package.json b/package.json
index ae836d60..c316505d 100644
--- a/package.json
+++ b/package.json
@@ -3,10 +3,15 @@
"private": true,
"type": "module",
"scripts": {
+ "build:content": "VITE_ENTRY=content vite build",
+ "build": "vite build && VITE_ENTRY=content vite build",
+ "dev:page": "VITE_ENTRY=page vite",
+ "dev:popup": "VITE_ENTRY=popup vite",
"dev": "vite",
- "build": "vite build",
- "lint-js": "eslint ./",
- "lint-css": "stylelint '**/*.{css,svelte}'"
+ "format": "prettier --write '**/*.{js,ts,css,svelte}'",
+ "lint:css": "stylelint '**/*.{css,svelte}'",
+ "lint:js": "eslint ./ --max-warnings 10",
+ "preview": "vite preview"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^2.0.3",
diff --git a/src/App.svelte b/src/App.svelte
deleted file mode 100644
index 937e58ef..00000000
--- a/src/App.svelte
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
- Userscripts dev
-
-
- page,
- popup
-
-
-
- This is the development preview environment
-
-
-
-
diff --git a/src/app.css b/src/app.css
deleted file mode 100644
index 1fedad38..00000000
--- a/src/app.css
+++ /dev/null
@@ -1,82 +0,0 @@
-/* stylelint-disable */
-:root {
- font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
- font-size: 16px;
- line-height: 24px;
- font-weight: 400;
-
- color-scheme: light dark;
- color: rgba(255, 255, 255, 0.87);
- background-color: #242424;
-
- font-synthesis: none;
- text-rendering: optimizeLegibility;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- -webkit-text-size-adjust: 100%;
-}
-
-a {
- font-weight: 500;
- color: #646cff;
- text-decoration: inherit;
-}
-a:hover {
- color: #535bf2;
-}
-
-body {
- margin: 0;
- display: flex;
- place-items: center;
- min-width: 320px;
- min-height: 100vh;
-}
-
-h1 {
- font-size: 3.2em;
- line-height: 1.1;
-}
-
-.card {
- padding: 2em;
-}
-
-#app {
- max-width: 1280px;
- margin: 0 auto;
- padding: 2rem;
- text-align: center;
-}
-
-button {
- border-radius: 8px;
- border: 1px solid transparent;
- padding: 0.6em 1.2em;
- font-size: 1em;
- font-weight: 500;
- font-family: inherit;
- background-color: #1a1a1a;
- cursor: pointer;
- transition: border-color 0.25s;
-}
-button:hover {
- border-color: #646cff;
-}
-button:focus,
-button:focus-visible {
- outline: 4px auto -webkit-focus-ring-color;
-}
-
-@media (prefers-color-scheme: light) {
- :root {
- color: #213547;
- background-color: #ffffff;
- }
- a:hover {
- color: #747bff;
- }
- button {
- background-color: #f9f9f9;
- }
-}
diff --git a/src/main.js b/src/main.js
deleted file mode 100644
index 37103c68..00000000
--- a/src/main.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import "./app.css";
-import App from "./App.svelte";
-
-const app = new App({
- target: document.getElementById("app")
-});
-
-export default app;
diff --git a/src/page/index.html b/src/page/index.html
new file mode 100644
index 00000000..c2cd597f
--- /dev/null
+++ b/src/page/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ Userscripts page
+
+
+
+
+
+
+
diff --git a/src/popup/index.html b/src/popup/index.html
new file mode 100644
index 00000000..08d3ee22
--- /dev/null
+++ b/src/popup/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ Userscripts popup
+
+
+
+
+
+
+
diff --git a/src/scripts/background.js b/src/scripts/background.js
new file mode 100644
index 00000000..c3abd1bf
--- /dev/null
+++ b/src/scripts/background.js
@@ -0,0 +1,501 @@
+// functions from "src/shared/utils.js";
+async function openExtensionPage() {
+ const extensionPageUrl = browser.runtime.getURL("page.html");
+ const tabs = await browser.tabs.query({});
+ for (let i = 0; i < tabs.length; i++) {
+ if (tabs[i].url === extensionPageUrl) {
+ await browser.windows.update(tabs[i].windowId, {focused: true});
+ await browser.tabs.update(tabs[i].id, {active: true});
+ return;
+ }
+ }
+ await browser.tabs.create({url: extensionPageUrl});
+}
+
+// functions from "src/shared/settings.js";
+
+// first sorts files by run-at value, then by weight value
+function userscriptSort(a, b) {
+ // map the run-at values to numeric values
+ const runAtValues = {
+ "document-start": 1,
+ "document-end": 2,
+ "document-idle": 3
+ };
+ const runAtA = a.scriptObject["run-at"];
+ const runAtB = b.scriptObject["run-at"];
+ if (runAtA !== runAtB && runAtValues[runAtA] && runAtValues[runAtB]) {
+ return runAtValues[runAtA] > runAtValues[runAtB];
+ }
+ return Number(a.scriptObject.weight) < Number(b.scriptObject.weight);
+}
+
+async function readAsDataURL(blob) {
+ return new Promise((resolve) => {
+ const reader = new FileReader();
+ reader.readAsDataURL(blob);
+ reader.onloadend = () => resolve(reader.result); // base64data
+ });
+}
+
+async function getPlatform() {
+ let platform = localStorage.getItem("platform");
+ if (!platform) {
+ const message = {name: "REQ_PLATFORM"};
+ const response = await browser.runtime.sendNativeMessage(message);
+ if (!response.platform) {
+ console.error("Failed to get platform");
+ return "";
+ }
+ platform = response.platform;
+ localStorage.setItem("platform", platform);
+ }
+ return platform;
+}
+
+function setClipboard(data, type = "text/plain") {
+ // future enhancement?
+ // https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/write
+ // https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText
+ const onCopy = (e) => {
+ e.stopImmediatePropagation();
+ e.preventDefault();
+ e.clipboardData.setData(type, data);
+ document.removeEventListener("copy", onCopy, true);
+ };
+
+ const textarea = document.createElement("textarea");
+ textarea.textContent = "";
+ document.body.appendChild(textarea);
+ textarea.select();
+ document.addEventListener("copy", onCopy, true);
+ try {
+ return document.execCommand("copy");
+ } catch (error) {
+ console.warn("setClipboard failed", error);
+ document.removeEventListener("copy", onCopy, true);
+ return false;
+ } finally {
+ document.body.removeChild(textarea);
+ }
+}
+
+async function setBadgeCount() {
+ const clearBadge = () => browser.browserAction.setBadgeText({text: ""});
+ // @todo until better introduce in ios, only set badge on macOS
+ const platform = await getPlatform();
+ if (platform !== "macos") return clearBadge();
+ // @todo after the background script is modularized, import and use:
+ // settingsStorage.get(["global_active","toolbar_badge_count","global_exclude_match"])
+ const results = await browser.storage.local.get([
+ "US_GLOBAL_ACTIVE",
+ "US_TOOLBAR_BADGE_COUNT"
+ ]);
+ if (results?.US_GLOBAL_ACTIVE === false) return clearBadge();
+ if (results?.US_TOOLBAR_BADGE_COUNT === false) return clearBadge();
+
+ const currentTab = await browser.tabs.getCurrent();
+ // no active tabs exist (user closed all windows)
+ if (!currentTab) return clearBadge();
+ const url = currentTab.url;
+ // if url doesn't exist, stop
+ if (!url) return clearBadge();
+ // only check for http/s pages
+ if (!url.startsWith("http://") && !url.startsWith("https://"))
+ return clearBadge();
+ // @todo if url match in global exclude list, clear badge
+ const frameUrls = new Set();
+ const frames = await browser.webNavigation.getAllFrames({
+ tabId: currentTab.id
+ });
+ for (let i = 0; i < frames.length; i++) {
+ const frameUrl = frames[i].url;
+ if (frameUrl !== url && frameUrl.startsWith("http")) {
+ frameUrls.add(frameUrl);
+ }
+ }
+ const message = {
+ name: "POPUP_BADGE_COUNT",
+ url,
+ frameUrls: Array.from(frameUrls)
+ };
+ browser.runtime.sendNativeMessage(message, (response) => {
+ if (response.error) return console.error(response.error);
+ const count = response.count;
+ if (count > 0) {
+ browser.browserAction.setBadgeText({text: count.toString()});
+ } else {
+ const _url = new URL(url);
+ if (_url.pathname.endsWith(".user.js")) {
+ browser.browserAction.setBadgeText({text: "JS"});
+ } else {
+ clearBadge();
+ }
+ }
+ });
+}
+
+async function setSessionRules() {
+ // not supported below safari 15.4
+ if (!browser.declarativeNetRequest.updateSessionRules) return;
+ await clearAllSessionRules();
+ const message = {name: "REQ_REQUESTS"};
+ const response = await browser.runtime.sendNativeMessage(message);
+ if (response.error) {
+ console.error(response.error);
+ return;
+ }
+ // there are no rules to apply
+ if (!response.length) return;
+ // loop through response, parse the rules, push to array and log
+ const rules = [];
+ for (let i = 0; i < response.length; i++) {
+ const rule = response[i];
+ const code = JSON.parse(rule.code);
+ // check if an array or single rule
+ if (Array.isArray(code)) {
+ code.forEach((r) => rules.push(r));
+ console.info(`Setting session rule: ${rule.name} (${code.length})`);
+ } else {
+ rules.push(code);
+ console.info(`Setting session rule: ${rule.name}`);
+ }
+ }
+ // generate unique ids for all rules to ensure no repeats
+ const ids = randomNumberSet(1000, rules.length);
+ rules.map((rule, index) => (rule.id = ids[index]));
+ try {
+ await browser.declarativeNetRequest.updateSessionRules({
+ addRules: rules
+ });
+ } catch (error) {
+ console.error(`Error setting session rules: ${error}`);
+ return;
+ }
+ console.info(`Finished setting ${rules.length} session rules`);
+}
+
+async function clearAllSessionRules() {
+ const rules = await browser.declarativeNetRequest.getSessionRules();
+ if (!rules.length) return;
+ console.info(`Clearing ${rules.length} session rules`);
+ const ruleIds = rules.map((a) => a.id);
+ await browser.declarativeNetRequest.updateSessionRules({
+ removeRuleIds: ruleIds
+ });
+}
+
+function randomNumberSet(max, count) {
+ // generates a set of random unique numbers
+ // returns an array
+ const numbers = new Set();
+ while (numbers.size < count) {
+ numbers.add(Math.floor(Math.random() * (max - 1 + 1)) + 1);
+ }
+ return [...numbers];
+}
+
+async function getContextMenuItems() {
+ // macos exclusive feature
+ const platform = await getPlatform();
+ if (platform !== "macos") return;
+ // since it's not possible to get a list of currently active menu items
+ // on update, all context-menu items are cleared, then re-added
+ // this is done to ensure fresh code changes appear
+ await browser.menus.removeAll();
+ // get the context-menu scripts
+ const message = {name: "REQ_CONTEXT_MENU_SCRIPTS"};
+ const response = await browser.runtime.sendNativeMessage(message);
+ if (response.error) {
+ console.error(response.error);
+ return;
+ }
+ // add menus items
+ const items = response.files?.menu || [];
+ if (items.length) {
+ console.info(`Setting ${items.length} context-menu userscripts`);
+ }
+ for (let i = 0; i < items.length; i++) {
+ const item = items[i];
+ // context-menu scripts require @match value
+ // @include values are ignored
+ if (!item.scriptObject.matches.length) continue;
+ addContextMenuItem(item);
+ }
+}
+
+async function addContextMenuItem(userscript) {
+ // context-menu items persist for a session
+ // to avoid duplication, when created, save the filename to session storage
+ const savedItems = sessionStorage.getItem("menu");
+ // if the session storage key doesn't exist use empty array
+ const activeItems = savedItems ? JSON.parse(savedItems) : [];
+ if (activeItems.indexOf(userscript.scriptObject.filename) !== -1) {
+ // if already saved, remove it, to get fresh code changes
+ await browser.menus.remove(userscript.scriptObject.filename);
+ }
+ // potential bug? https://developer.apple.com/forums/thread/685273
+ // https://stackoverflow.com/q/68431201
+ // parse through match values and change pathnames to deal with bug
+ const patterns = userscript.scriptObject.matches;
+ patterns.forEach((pattern, index) => {
+ try {
+ const url = new URL(pattern);
+ let pathname = url.pathname;
+ if (pathname.length > 1 && pathname.endsWith("/")) {
+ pathname = pathname.slice(0, -1);
+ }
+ patterns[index] = `${url.protocol}//${url.hostname}${pathname}`;
+ } catch (error) {
+ // prevent breaking when non-url pattern present
+ }
+ });
+
+ browser.menus.create(
+ {
+ contexts: ["all"],
+ documentUrlPatterns: patterns,
+ id: userscript.scriptObject.filename,
+ title: userscript.scriptObject.name
+ },
+ () => {
+ // add event listener if needed
+ if (!browser.menus.onClicked.hasListener(contextClick)) {
+ browser.menus.onClicked.addListener(contextClick);
+ }
+ // save the context-menu item reference to sessionStorage
+ const value = JSON.stringify([userscript.scriptObject.filename]);
+ sessionStorage.setItem("menu", value);
+ }
+ );
+}
+
+function contextClick(info, tab) {
+ // when any created context-menu item is clicked, send message to tab
+ // the content script for that tag will have the context-menu code
+ // which will get send back in the response if/when found
+ const message = {name: "CONTEXT_RUN", menuItemId: info.menuItemId};
+ browser.tabs.sendMessage(tab.id, message, (response) => {
+ // if code is returned, execute on that tab
+ if (!response.code) return;
+ browser.tabs.executeScript(tab.id, {
+ code: response.code
+ });
+ });
+}
+
+// handles messages sent with browser.runtime.sendMessage
+function handleMessage(request, sender, sendResponse) {
+ switch (request.name) {
+ case "REQ_USERSCRIPTS": {
+ // get the page url from the content script that sent request
+ const url = sender.url;
+ // use frameId to determine if request came from top level window
+ // if @noframes true, and isTop false, swift layer won't return code
+ const isTop = sender.frameId === 0;
+ // send request to swift layer to provide code for page url
+ const message = {name: "REQ_USERSCRIPTS", url, isTop};
+ browser.runtime.sendNativeMessage(message, (response) => {
+ // if request failed, send error to content script for logging
+ if (response.error) return sendResponse(response);
+ // sort files
+ response.files.js.sort(userscriptSort);
+ response.files.css.sort((a, b) => {
+ return Number(a.weight) < Number(b.weight);
+ });
+ // return sorted files for injection
+ sendResponse(response);
+ });
+ return true;
+ }
+ case "API_CLOSE_TAB": {
+ const tabId = request.tabId || sender.tab.id;
+ browser.tabs.remove(tabId, () => sendResponse({success: 1}));
+ return true;
+ }
+ case "API_OPEN_TAB": {
+ const props = {
+ active: request.active,
+ index: sender.tab.index + 1,
+ url: request.url
+ };
+ browser.tabs.create(props, (response) => sendResponse(response));
+ return true;
+ }
+ case "API_ADD_STYLE": {
+ const tabId = sender.tab.id;
+ const details = {code: request.css, cssOrigin: "user"};
+ browser.tabs.insertCSS(tabId, details, () => {
+ sendResponse(request.css);
+ });
+ return true;
+ }
+ case "API_GET_TAB": {
+ let tab = null;
+ if (typeof sender.tab !== "undefined") {
+ const tabData = sessionStorage.getItem(`tab-${sender.tab.id}`);
+ try {
+ // if tabData is null, can still parse it and return that
+ tab = JSON.parse(tabData);
+ } catch (error) {
+ console.error("failed to parse tab data for getTab");
+ }
+ } else {
+ console.error("unable to deliver tab due to empty tab id");
+ }
+ sendResponse(tab == null ? {} : tab);
+ break;
+ }
+ case "API_SAVE_TAB": {
+ if (sender.tab != null && sender.tab.id) {
+ const key = `tab-${sender.tab.id}`;
+ sessionStorage.setItem(key, JSON.stringify(request.tab));
+ sendResponse({success: true});
+ } else {
+ console.error("unable to save tab, empty tab id");
+ sendResponse({success: false});
+ }
+ break;
+ }
+ case "API_SET_CLIPBOARD": {
+ const result = setClipboard(request.data, request.type);
+ sendResponse(result);
+ break;
+ }
+ case "API_XHR": {
+ // parse details and set up for XMLHttpRequest
+ const details = request.details;
+ const method = details.method ? details.method : "GET";
+ const user = details.user || null;
+ const password = details.password || null;
+ let body = details.data || null;
+ if (body != null && details.binary != null) {
+ const len = body.length;
+ const arr = new Uint8Array(len);
+ for (let i = 0; i < len; i++) {
+ arr[i] = body.charCodeAt(i);
+ }
+ body = new Blob([arr], {type: "text/plain"});
+ }
+ // establish a long-lived port connection to content script
+ const port = browser.tabs.connect(sender.tab.id, {
+ name: request.xhrPortName
+ });
+ // set up XMLHttpRequest
+ const xhr = new XMLHttpRequest();
+ xhr.withCredentials = details.user && details.password;
+ xhr.timeout = details.timeout || 0;
+ if (details.overrideMimeType) {
+ xhr.overrideMimeType(details.overrideMimeType);
+ }
+ // add required listeners and send result back to the content script
+ for (const e of request.events) {
+ if (!details[e]) continue;
+ xhr[e] = async (event) => {
+ // can not send xhr through postMessage
+ // construct new object to be sent as "response"
+ const x = {
+ readyState: xhr.readyState,
+ response: xhr.response,
+ responseHeaders: xhr.getAllResponseHeaders(),
+ responseType: xhr.responseType,
+ responseURL: xhr.responseURL,
+ status: xhr.status,
+ statusText: xhr.statusText,
+ timeout: xhr.timeout,
+ withCredentials: xhr.withCredentials
+ };
+ // only include responseText when needed
+ if (["", "text"].indexOf(xhr.responseType) !== -1) {
+ x.responseText = xhr.responseText;
+ }
+ // need to convert arraybuffer data to postMessage
+ if (xhr.responseType === "arraybuffer") {
+ const arr = Array.from(new Uint8Array(xhr.response));
+ x.response = arr;
+ }
+ // need to blob arraybuffer data to postMessage
+ if (xhr.responseType === "blob") {
+ const base64data = await readAsDataURL(xhr.response);
+ x.response = {
+ data: base64data,
+ type: xhr.responseType
+ };
+ }
+ port.postMessage({name: e, event, response: x});
+ };
+ }
+ xhr.open(method, details.url, true, user, password);
+ xhr.responseType = details.responseType || "";
+ if (details.headers) {
+ for (const key in details.headers) {
+ const val = details.headers[key];
+ xhr.setRequestHeader(key, val);
+ }
+ }
+ // receive messages from content script and process them
+ port.onMessage.addListener((msg) => {
+ if (msg.name === "ABORT") xhr.abort();
+ if (msg.name === "DISCONNECT") port.disconnect();
+ });
+ // handle port disconnect and clean tasks
+ port.onDisconnect.addListener((p) => {
+ if (p?.error) {
+ console.error(
+ `port disconnected due to an error: ${p.error.message}`
+ );
+ }
+ });
+ xhr.send(body);
+ // if onloadend not set in xhr details
+ // onloadend event won't be passed to content script
+ // if that happens port DISCONNECT message won't be posted
+ // if details lacks onloadend attach listener
+ if (!details.onloadend) {
+ xhr.onloadend = (event) => {
+ port.postMessage({name: "onloadend", event});
+ };
+ }
+ break;
+ }
+ case "REFRESH_SESSION_RULES": {
+ setSessionRules();
+ break;
+ }
+ case "REFRESH_CONTEXT_MENU_SCRIPTS": {
+ getContextMenuItems();
+ break;
+ }
+ }
+}
+
+browser.runtime.onStartup.addListener(async () => {
+ // on startup get declarativeNetRequests
+ // and set the requests for the session
+ // should also check and refresh when:
+ // 1. popup opens (done)
+ // 2. a new save event in the page occurs
+ // 3. the refresh button is pushed in the popup
+ await setSessionRules();
+ await getContextMenuItems();
+});
+// listens for messages from content script, popup and page
+browser.runtime.onMessage.addListener(handleMessage);
+// set the badge count
+browser.tabs.onActivated.addListener(setBadgeCount);
+browser.windows.onFocusChanged.addListener(setBadgeCount);
+browser.webNavigation.onCompleted.addListener(setBadgeCount);
+
+// handle native app messages
+const port = browser.runtime.connectNative();
+port.onMessage.addListener((message) => {
+ // console.info(message); // DEBUG
+ if (message.name === "SAVE_LOCATION_CHANGED") {
+ openExtensionPage();
+ if (message?.userInfo?.returnApp === true)
+ browser.runtime.sendNativeMessage({name: "OPEN_APP"});
+ }
+ // if (message.name === "OPEN_EXTENSION_PAGE") {
+ // openExtensionPage();
+ // }
+});
diff --git a/src/scripts/content.js b/src/scripts/content.js
new file mode 100644
index 00000000..6cb3a6ff
--- /dev/null
+++ b/src/scripts/content.js
@@ -0,0 +1,500 @@
+// code received from background page will be stored in this variable
+// code referenced again when strict CSPs block initial injection attempt
+let data;
+// determines whether strict csp injection has already run (JS only)
+let cspFallbackAttempted = false;
+// save reference to window's browser object
+const browser = window.browser;
+// GM APIs
+const apis = {
+ closeTab(tabId) {
+ return new Promise((resolve) => {
+ const message = {
+ name: "API_CLOSE_TAB",
+ tabId
+ };
+ browser.runtime.sendMessage(message, (response) =>
+ resolve(response)
+ );
+ });
+ },
+ openInTab(url, openInBackground = false) {
+ if (!url) return console.error("openInTab missing url arg");
+ return new Promise((resolve) => {
+ const message = {
+ name: "API_OPEN_TAB",
+ url,
+ active: !openInBackground
+ };
+ browser.runtime.sendMessage(message, (response) =>
+ resolve(response)
+ );
+ });
+ },
+ setValue(key, value) {
+ if (typeof key !== "string" || !key.length) {
+ return console.error("setValue invalid key arg");
+ }
+ if (value == null) {
+ return console.error("setValue invalid value arg");
+ }
+ return new Promise((resolve) => {
+ const item = {};
+ item[`${this.US_filename}---${key}`] = value;
+ browser.storage.local.set(item, () => resolve({success: 1}));
+ });
+ },
+ getValue(key, defaultValue) {
+ if (typeof key !== "string" || !key.length) {
+ return console.error("getValue invalid key arg");
+ }
+ const prefixedKey = `${this.US_filename}---${key}`;
+ return new Promise((resolve) => {
+ browser.storage.local.get(prefixedKey, (item) => {
+ if (Object.keys(item).length === 0) {
+ if (defaultValue != null) {
+ resolve(defaultValue);
+ } else {
+ resolve(undefined);
+ }
+ } else {
+ resolve(Object.values(item)[0]);
+ }
+ });
+ });
+ },
+ deleteValue(key) {
+ if (typeof key !== "string" || !key.length) {
+ return console.error("deleteValue missing key arg");
+ }
+ return new Promise((resolve) => {
+ const prefixedKey = `${this.US_filename}---${key}`;
+ browser.storage.local.remove(prefixedKey, () => {
+ resolve({success: 1});
+ });
+ });
+ },
+ listValues() {
+ return new Promise((resolve) => {
+ const prefix = `${this.US_filename}---`;
+ const keys = [];
+ browser.storage.local.get().then((items) => {
+ for (const key in items) {
+ if (key.startsWith(prefix)) {
+ const k = key.replace(prefix, "");
+ keys.push(k);
+ }
+ }
+ resolve(keys);
+ });
+ });
+ },
+ addStyle(css) {
+ if (typeof css !== "string") {
+ return console.error("addStyle invalid css arg");
+ }
+ return new Promise((resolve) => {
+ const message = {
+ name: "API_ADD_STYLE",
+ css
+ };
+ browser.runtime.sendMessage(message, (response) =>
+ resolve(response)
+ );
+ });
+ },
+ getTab() {
+ return new Promise((resolve) => {
+ const message = {name: "API_GET_TAB"};
+ browser.runtime.sendMessage(message, (response) => {
+ resolve(response);
+ });
+ });
+ },
+ saveTab(tab) {
+ if (tab == null) return console.error("saveTab invalid arg");
+ return new Promise((resolve) => {
+ const message = {
+ name: "API_SAVE_TAB",
+ tab
+ };
+ browser.runtime.sendMessage(message, (response) => {
+ resolve(response);
+ });
+ });
+ },
+ setClipboard(clipboardData, type) {
+ return new Promise((resolve) => {
+ const message = {
+ name: "API_SET_CLIPBOARD",
+ clipboardData,
+ type
+ };
+ browser.runtime.sendMessage(message, (response) => {
+ resolve(response);
+ });
+ });
+ },
+ xhr(details) {
+ if (details == null) return console.error("xhr invalid details arg");
+ if (!details.url) return console.error("xhr details missing url key");
+ // generate random port name for single xhr
+ const xhrPortName = Math.random().toString(36).substring(1, 9);
+ // strip out functions from details
+ const detailsParsed = JSON.parse(JSON.stringify(details));
+ // get all the "on" events from XMLHttpRequest object
+ const events = [];
+ for (const k in XMLHttpRequest.prototype) {
+ if (k.slice(0, 2) === "on") events.push(k);
+ }
+ // check which functions are included in the original details object
+ // add a bool to indicate if event listeners should be attached
+ for (const e of events) {
+ if (typeof details[e] === "function") detailsParsed[e] = true;
+ }
+ // define return method, will be populated after port is established
+ const response = {
+ abort: () => console.error("xhr has not yet been initialized")
+ };
+ // port listener, most of the messaging logic goes here
+ const listener = (port) => {
+ if (port.name !== xhrPortName) return;
+ port.onMessage.addListener(async (msg) => {
+ if (
+ events.includes(msg.name) &&
+ typeof details[msg.name] === "function"
+ ) {
+ // process xhr response
+ const r = msg.response;
+ if (r.responseType === "arraybuffer") {
+ // arraybuffer responses had their data converted in background
+ // convert it back to arraybuffer
+ try {
+ const buffer = new Uint8Array(r.response).buffer;
+ r.response = buffer;
+ } catch (err) {
+ console.error("error parsing xhr arraybuffer", err);
+ }
+ } else if (r.responseType === "blob" && r.response.data) {
+ // blob responses had their data converted in background
+ // convert it back to blob
+ const resp = await fetch(r.response.data);
+ const b = await resp.blob();
+ r.response = b;
+ }
+ // call userscript method
+ details[msg.name](msg.response);
+ }
+ // all messages received
+ // tell background it's safe to close port
+ if (msg.name === "onloadend") {
+ port.postMessage({name: "DISCONNECT"});
+ }
+ });
+
+ // handle port disconnect and clean tasks
+ port.onDisconnect.addListener((p) => {
+ if (p?.error) {
+ console.error(
+ `port disconnected due to an error: ${p.error.message}`
+ );
+ }
+ browser.runtime.onConnect.removeListener(listener);
+ });
+ // fill the method returned to the user script
+ response.abort = () => port.postMessage({name: "ABORT"});
+ };
+ // wait for the background to establish a port connection
+ browser.runtime.onConnect.addListener(listener);
+ // pass the basic information to the background through a common message
+ const message = {
+ name: "API_XHR",
+ details: detailsParsed,
+ xhrPortName,
+ events
+ };
+ browser.runtime.sendMessage(message);
+ return response;
+ },
+ // include method names so they don't get skipped when adding to userscript
+ xmlHttpRequest: true,
+ GM_xmlhttpRequest: true
+};
+// remote window's browser object
+delete window.browser;
+
+// label used to distinguish frames in console
+const label = randomLabel();
+
+function randomLabel() {
+ const a = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ r = Math.random();
+ return a[Math.floor(r * a.length)] + r.toString().slice(5, 6);
+}
+
+function processJS(userscript) {
+ const runAt = userscript.scriptObject["run-at"];
+ if (runAt === "document-start") {
+ injectJS(userscript);
+ } else if (runAt === "document-end") {
+ if (document.readyState !== "loading") {
+ injectJS(userscript);
+ } else {
+ document.addEventListener("DOMContentLoaded", () => {
+ injectJS(userscript);
+ });
+ }
+ } else if (runAt === "document-idle") {
+ if (document.readyState === "complete") {
+ injectJS(userscript);
+ } else {
+ document.addEventListener("readystatechange", () => {
+ if (document.readyState === "complete") {
+ injectJS(userscript);
+ }
+ });
+ }
+ }
+}
+
+function wrapCode(preCode, code, filename) {
+ const tag = window.self === window.top ? "" : `(${label})`;
+ return `
+ (function() {
+ ${preCode}
+ (function() {
+ const US_filename = "${filename}";
+ const apis = undefined;
+ const browser = undefined;
+ // userscript code below
+ ${code}
+ //# sourceURL=${filename.replace(/\s/g, "-") + tag}
+ })();
+ })();
+ `;
+}
+
+function injectJS(userscript) {
+ const filename = userscript.scriptObject.filename;
+ const code = wrapCode(userscript.preCode, userscript.code, filename);
+ const name = userscript.scriptObject.name;
+ let injectInto = userscript.scriptObject["inject-into"];
+ // change scope to content since strict CSP event detected
+ if (
+ injectInto === "auto" &&
+ (userscript.fallback || cspFallbackAttempted)
+ ) {
+ injectInto = "content";
+ console.warn(`Attempting fallback injection for ${name}`);
+ } else if (window.self === window.top) {
+ console.info(`Injecting ${name} %c(js)`, "color: #fff600");
+ } else {
+ console.info(
+ `Injecting ${name} %c(js)%c - %cframe(${label})(${window.location})`,
+ "color: #fff600",
+ "color: inherit",
+ "color: #006fff"
+ );
+ }
+ if (injectInto !== "content") {
+ const tag = document.createElement("script");
+ tag.textContent = code;
+ document.head.appendChild(tag);
+ } else {
+ try {
+ // eslint-disable-next-line no-new-func
+ return Function(code)();
+ } catch (error) {
+ console.error(`${filename} error`, error);
+ }
+ }
+}
+
+function injectCSS(name, code) {
+ if (window.self === window.top) {
+ console.info(`Injecting ${name} %c(css)`, "color: #60f36c");
+ } else {
+ console.info(
+ `Injecting ${name} %c(css)%c - %cframe(${label})(${window.location})`,
+ "color: #60f36c",
+ "color: inherit",
+ "color: #006fff"
+ );
+ }
+ // Safari lacks full support for tabs.insertCSS
+ // https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/insertCSS
+ // specifically frameId and cssOrigin
+ // if support for those details keys arrives, the method below can be used
+ // NOTE: manifest V3 does support frameId, but not origin
+ // https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/insertCSS
+
+ // write the css code to head of the document
+ const tag = document.createElement("style");
+ tag.textContent = code;
+ document.head.appendChild(tag);
+}
+
+function cspFallback(e) {
+ // if a security policy violation event has occurred
+ // and the directive is script-src or script-src-elem
+ // it's fair to assume that there is a strict CSP for javascript
+ // and that injection was blocked for all userscripts
+ // when any script-src violation is detected, re-attempt injection
+ if (
+ e.effectiveDirective === "script-src" ||
+ e.effectiveDirective === "script-src-elem"
+ ) {
+ // get all "auto" code
+ // since other code can trigger a security policy violation event
+ // make sure data var is not undefined before attempting fallback
+ if (!data || cspFallbackAttempted) return;
+ // update global that tracks security policy violations
+ cspFallbackAttempted = 1;
+ // for all userscripts with @inject-into: auto, attempt re-injection
+ for (let i = 0; i < data.files.js.length; i++) {
+ const userscript = data.files.js[i];
+ if (userscript.scriptObject["inject-into"] !== "auto") continue;
+ userscript.fallback = 1;
+ processJS(userscript);
+ }
+ }
+}
+
+function injection() {
+ browser.runtime.sendMessage({name: "REQ_USERSCRIPTS"}, (response) => {
+ // cancel injection if errors detected
+ if (!response || response.error) {
+ console.error(
+ response?.error || "REQ_USERSCRIPTS returned undefined"
+ );
+ return;
+ }
+ // save response locally in case CSP events occur
+ data = response;
+ // combine regular and context-menu scripts
+ const scripts = [...data.files.js, ...data.files.menu];
+ // loop through each userscript and prepare for processing
+ for (let i = 0; i < scripts.length; i++) {
+ const userscript = scripts[i];
+ userscript.preCode = "";
+ // pass references to the api methods as needed
+ const gmMethods = [];
+ const filename = userscript.scriptObject.filename;
+ const grants = userscript.scriptObject.grant;
+ const injectInto = userscript.scriptObject["inject-into"];
+ // create GM.info object
+ const scriptData = {
+ script: userscript.scriptObject,
+ scriptHandler: data.scriptHandler,
+ scriptHandlerVersion: data.scriptHandlerVersion,
+ scriptMetaStr: userscript.scriptMetaStr
+ };
+ // all userscripts get access to GM.info
+ gmMethods.push("info: GM_info");
+ // if @grant explicitly set to none, empty grants array
+ if (grants.includes("none")) grants.length = 0;
+ // @grant values exist for page scoped userscript
+ if (grants.length && injectInto === "page") {
+ // remove grants
+ grants.length = 0;
+ // log warning
+ console.warn(
+ `${filename} @grant values removed due to @inject-into value: ${injectInto} - https://github.com/quoid/userscripts/issues/265#issuecomment-1213462394`
+ );
+ }
+ // @grant exist for auto scoped userscript
+ if (grants.length && injectInto === "auto") {
+ // change scope
+ userscript.scriptObject["inject-into"] = "content";
+ // log warning
+ console.warn(
+ `${filename} @inject-into value set to 'content' due to @grant values: ${grants} - https://github.com/quoid/userscripts/issues/265#issuecomment-1213462394`
+ );
+ }
+ // loop through each userscript @grant value, add methods as needed
+ for (let j = 0; j < grants.length; j++) {
+ const grant = grants[j];
+ const method = grant.split(".")[1] || grant.split(".")[0];
+ // ensure API method exists in apis object
+ if (!Object.keys(apis).includes(method)) continue;
+ // create the method string to be pushed to methods array
+ let methodStr = `${method}: apis.${method}`;
+ // add require variables to specific methods
+ switch (method) {
+ case "getValue":
+ case "setValue":
+ case "deleteValue":
+ case "listValues":
+ methodStr += `.bind({"US_filename": "${filename}"})`;
+ break;
+ case "info":
+ case "GM_info":
+ continue;
+ case "xmlHttpRequest":
+ gmMethods.push("xmlHttpRequest: apis.xhr");
+ continue;
+ case "GM_xmlhttpRequest":
+ userscript.preCode +=
+ "const GM_xmlhttpRequest = apis.xhr;";
+ continue;
+ }
+ gmMethods.push(methodStr);
+ }
+ // add GM.info
+ userscript.preCode += `const GM_info = ${JSON.stringify(
+ scriptData
+ )};`;
+ // add other included GM API methods
+ userscript.preCode += `const GM = {${gmMethods.join(",")}};`;
+ // process file for injection
+ processJS(userscript);
+ }
+ for (let i = 0; i < data.files.css.length; i++) {
+ const userstyle = data.files.css[i];
+ injectCSS(userstyle.name, userstyle.code);
+ }
+ });
+}
+
+function listeners() {
+ // listens for messages from background, popup, etc...
+ browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
+ const name = request.name;
+ if (name === "CONTEXT_RUN") {
+ // from bg script when context-menu item is clicked
+ // double check to ensure context-menu scripts only run in top windows
+ if (window !== window.top) return;
+
+ // loop through context-menu scripts saved to data object and find match
+ // if no match found, nothing will execute and error will log
+ const filename = request.menuItemId;
+ for (let i = 0; i < data.files.menu.length; i++) {
+ const item = data.files.menu[i];
+ if (item.scriptObject.filename === filename) {
+ console.info(
+ `Injecting ${filename} %c(js)`,
+ "color: #fff600"
+ );
+ sendResponse({
+ code: wrapCode(item.preCode, item.code, filename)
+ });
+ return;
+ }
+ }
+ console.error(`Couldn't find ${filename} code!`);
+ }
+ });
+ // listen for CSP violations
+ document.addEventListener("securitypolicyviolation", cspFallback);
+}
+
+async function initialize() {
+ const results = await browser.storage.local.get("US_GLOBAL_ACTIVE");
+ if (results?.US_GLOBAL_ACTIVE === false)
+ return console.info("Userscripts off");
+ // start the injection process and add the listeners
+ injection();
+ listeners();
+}
+
+initialize();
diff --git a/src/shared/utils.js b/src/shared/utils.js
index 9f73ff56..37d9bbba 100644
--- a/src/shared/utils.js
+++ b/src/shared/utils.js
@@ -178,8 +178,8 @@ export const validMetaKeys = new Set([
]);
export const extensionPaths = {
- page: "/dist/entry-page.html",
- popup: "/dist/entry-popup.html"
+ page: "page.html",
+ popup: "popup.html"
};
export async function openExtensionPage() {
diff --git a/vite.config.js b/vite.config.js
index 044b986d..fe7e6672 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -1,44 +1,188 @@
-import {resolve} from "path";
import {defineConfig} from "vite";
import {svelte} from "@sveltejs/vite-plugin-svelte";
+import autoprefixer from "autoprefixer";
-// [inline-svg]
-// TODO: remove this once vite resolved issue
-// https://github.com/vitejs/vite/issues/1204
-// import fs from "fs";
-// import svgpkg from "svg-inline-loader";
-// export function svgInline() { // custom plugin
-// return {
-// name: "transform-file",
-// transform(code, id) {
-// if (id.endsWith(".svg")) {
-// const svg = fs.readFileSync(id, "utf8");
-// const ret = svgpkg.getExtractedSVG(svg, {});
-// return `export default '${ret}'`;
-// }
-// }
-// };
-// }
-// [inline-svg]
-// NOW: use `?raw` suffix import svg assets as inline
-// https://vitejs.dev/guide/assets.html#importing-asset-as-string
+const entry = process?.env?.VITE_ENTRY;
+const parentDir = "xcode";
+const assetsDir = "assets";
-// [autoprefixer]
-// https://vitejs.dev/guide/features.html#postcss
-// have config with `.postcssrc.json` file
-// about `missing peer postcss` error, ignore it
+let root = "src";
+if (entry === "app") root = "src/app";
+if (entry === "content") root = "src/scripts";
+if (entry === "page") root = "src/page";
+if (entry === "popup") root = "src/popup";
+
+let outDir = `../${parentDir}/Safari-Extension/Resources`;
+if (entry === "app") outDir = `../../${parentDir}/Shared (App)/`;
+if (entry === "content") outDir = `../${outDir}`;
+
+/**
+ * Plugin that serves a couple different purposes:
+ * 1. Updates the html bundle fileNames so that the path they are output to
+ * matches the structure of the extension directory. For example, rather than
+ * the path being page/index.html, it will be dist/page.html, etc...
+ * 2. Transforms relative paths within these files. Since we are renaming files,
+ * the paths reflected in these html files need to be updated to point t0
+ * the correct location of the files and assets.
+ *
+ * @returns {import("vite").Plugin}
+ * @see {@link https://vitejs.dev/guide/api-plugin.html Vite Plugin API}
+ * @see {@link https://rollupjs.org/plugin-development/ Rollup Plugin API}
+ */
+const processIndexFiles = () => ({
+ name: "rename-index-files",
+ apply: "build",
+ enforce: "post",
+ generateBundle(_options, bundle) {
+ for (const key of Object.keys(bundle)) {
+ if (key.includes(".html")) {
+ if (entry === "app") {
+ bundle[key].fileName = "Base.lproj/app.html";
+ } else {
+ const name = key.split("/")[0];
+ bundle[key].fileName = `${name}.html`;
+ }
+ }
+ }
+ },
+ transformIndexHtml(html) {
+ if (entry === "app") return html;
+ return html.replace(/(href|src)="\.\.\//g, '$1="./');
+ }
+});
+
+/**
+ * Plugin to create an index.html file when running `pnpm dev`. When using this
+ * command the browser will serve the the src` directory. This plugin will
+ * create an index.html file that lists the available entry points for the
+ * extension without the need to create an index.html file for this purpose.
+ *
+ * @returns {import("vite").Plugin}
+ * @see {@link https://vitejs.dev/guide/api-plugin.html Vite Plugin API}
+ * @see {@link https://rollupjs.org/plugin-development/ Rollup Plugin API}
+ */
+const buildEntryIndex = () => ({
+ name: "build-entry-index",
+ apply: "serve",
+ configureServer(server) {
+ server.middlewares.use((req, res, next) => {
+ if (req.originalUrl === "/" && !entry) {
+ res.setHeader("Content-Type", "text/html");
+ const html = `
+
+
+
+ Userscripts Entry Page
+
+
+
+ Choose an app component:
+
+
+
+ `;
+ res.end(html);
+ } else {
+ next();
+ }
+ });
+ }
+});
+
+/**
+ * Custom plugin to add browser condition to vite; necessary for running tests.
+ * Alternative option is to add the following to the test property.
+ * alias: [{find: /^svelte$/, replacement: "svelte/internal"}]
+ *
+ * @returns {import("vite").Plugin}
+ * @see {@link https://github.com/vitest-dev/vitest/issues/2834 GitHub Issue}
+ */
+const vitestBrowserConditionPlugin = () => ({
+ name: "vite-plugin-vitest-browser-condition",
+ config({resolve}) {
+ if (process.env.VITEST && resolve) {
+ resolve.conditions?.unshift("browser");
+ }
+ }
+});
// https://vitejs.dev/config/
+// https://rollupjs.org/configuration-options/
export default defineConfig({
- plugins: [svelte()],
- base: "./",
- build: {
- outDir: "xcode/Safari-Extension/Resources/dist/",
- rollupOptions: {
- input: {
- page: resolve(__dirname, "entry-page.html"),
- popup: resolve(__dirname, "entry-popup.html")
- }
- }
- }
+ base: "./",
+ build: {
+ emptyOutDir: false,
+ lib:
+ entry === "content"
+ ? {
+ entry: `${entry}.js`,
+ fileName: entry,
+ formats: ["es"],
+ name: entry
+ }
+ : false,
+ // https://caniuse.com/link-rel-modulepreload
+ modulePreload: {polyfill: true},
+ outDir: outDir,
+ rollupOptions: {
+ input:
+ entry === "app" || entry === "content"
+ ? undefined
+ : {
+ background: "src/scripts/background.js",
+ page: "src/page/index.html",
+ popup: "src/popup/index.html"
+ },
+ output: {
+ // use a more meaningful chunk name
+ manualChunks:
+ entry === "app" || entry === "content"
+ ? undefined
+ : (id) => {
+ if (id.includes("shared")) {
+ return "shared";
+ }
+ },
+ assetFileNames: () => {
+ if (entry === "app") return "Resources/[name][extname]";
+ return `${assetsDir}/[name][extname]`;
+ },
+ chunkFileNames: `${assetsDir}/[name].js`,
+ // depending on the chunk, output to different directories
+ entryFileNames: (chunkInfo) => {
+ if (entry === "app") return "Resources/app.js";
+ if (
+ chunkInfo.name === "background" ||
+ ["page", "popup"].includes(chunkInfo.name)
+ ) {
+ return "[name].js";
+ }
+ if (entry === "content") return "[name].js";
+ return `${assetsDir}/[name].js`;
+ },
+ // when building the shared app, inline all imports
+ inlineDynamicImports: entry === "app"
+ }
+ }
+ },
+ css: {
+ postcss: {
+ plugins: [
+ autoprefixer({
+ overrideBrowserslist: ["safari >= 16"]
+ })
+ ]
+ }
+ },
+ plugins: [
+ vitestBrowserConditionPlugin(),
+ buildEntryIndex(),
+ svelte(),
+ processIndexFiles()
+ ],
+ publicDir: false,
+ root: root
});
diff --git a/xcode/Safari-Extension/Resources/background.js b/xcode/Safari-Extension/Resources/background.js
deleted file mode 100644
index 12505364..00000000
--- a/xcode/Safari-Extension/Resources/background.js
+++ /dev/null
@@ -1,487 +0,0 @@
-// functions from "src/shared/utils.js";
-async function openExtensionPage() {
- const extensionPageUrl = browser.runtime.getURL("dist/entry-page.html");
- const tabs = await browser.tabs.query({});
- for (let i = 0; i < tabs.length; i++) {
- if (tabs[i].url === extensionPageUrl) {
- await browser.windows.update(tabs[i].windowId, {focused: true});
- await browser.tabs.update(tabs[i].id, {active: true});
- return;
- }
- }
- await browser.tabs.create({url: extensionPageUrl});
-}
-
-// functions from "src/shared/settings.js";
-
-// first sorts files by run-at value, then by weight value
-function userscriptSort(a, b) {
- // map the run-at values to numeric values
- const runAtValues = {
- "document-start": 1,
- "document-end": 2,
- "document-idle": 3
- };
- const runAtA = a.scriptObject["run-at"];
- const runAtB = b.scriptObject["run-at"];
- if (runAtA !== runAtB && runAtValues[runAtA] && runAtValues[runAtB]) {
- return runAtValues[runAtA] > runAtValues[runAtB];
- }
- return Number(a.scriptObject.weight) < Number(b.scriptObject.weight);
-}
-
-async function readAsDataURL(blob) {
- return new Promise(resolve => {
- const reader = new FileReader();
- reader.readAsDataURL(blob);
- reader.onloadend = () => resolve(reader.result); // base64data
- });
-}
-
-async function getPlatform() {
- let platform = localStorage.getItem("platform");
- if (!platform) {
- const message = {name: "REQ_PLATFORM"};
- const response = await browser.runtime.sendNativeMessage(message);
- if (!response.platform) {
- console.error("Failed to get platform");
- return "";
- }
- platform = response.platform;
- localStorage.setItem("platform", platform);
- }
- return platform;
-}
-
-function setClipboard(data, type = "text/plain") {
- // future enhancement?
- // https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/write
- // https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText
- const onCopy = e => {
- e.stopImmediatePropagation();
- e.preventDefault();
- e.clipboardData.setData(type, data);
- document.removeEventListener("copy", onCopy, true);
- };
-
- const textarea = document.createElement("textarea");
- textarea.textContent = "";
- document.body.appendChild(textarea);
- textarea.select();
- document.addEventListener("copy", onCopy, true);
- try {
- return document.execCommand("copy");
- } catch (error) {
- console.warn("setClipboard failed", error);
- document.removeEventListener("copy", onCopy, true);
- return false;
- } finally {
- document.body.removeChild(textarea);
- }
-}
-
-async function setBadgeCount() {
- const clearBadge = () => browser.browserAction.setBadgeText({text: ""});
- // @todo until better introduce in ios, only set badge on macOS
- const platform = await getPlatform();
- if (platform !== "macos") return clearBadge();
- // @todo after the background script is modularized, import and use:
- // settingsStorage.get(["global_active","toolbar_badge_count","global_exclude_match"])
- const results = await browser.storage.local.get(["US_GLOBAL_ACTIVE", "US_TOOLBAR_BADGE_COUNT"]);
- if (results?.US_GLOBAL_ACTIVE === false) return clearBadge();
- if (results?.US_TOOLBAR_BADGE_COUNT === false) return clearBadge();
-
- const currentTab = await browser.tabs.getCurrent();
- // no active tabs exist (user closed all windows)
- if (!currentTab) return clearBadge();
- const url = currentTab.url;
- // if url doesn't exist, stop
- if (!url) return clearBadge();
- // only check for http/s pages
- if (!url.startsWith("http://") && !url.startsWith("https://")) return clearBadge();
- // @todo if url match in global exclude list, clear badge
- const frameUrls = new Set();
- const frames = await browser.webNavigation.getAllFrames({tabId: currentTab.id});
- for (let i = 0; i < frames.length; i++) {
- const frameUrl = frames[i].url;
- if (frameUrl !== url && frameUrl.startsWith("http")) {
- frameUrls.add(frameUrl);
- }
- }
- const message = {
- name: "POPUP_BADGE_COUNT",
- url,
- frameUrls: Array.from(frameUrls)
- };
- browser.runtime.sendNativeMessage(message, response => {
- if (response.error) return console.error(response.error);
- const count = response.count;
- if (count > 0) {
- browser.browserAction.setBadgeText({text: count.toString()});
- } else {
- const _url = new URL(url);
- if (_url.pathname.endsWith(".user.js")) {
- browser.browserAction.setBadgeText({text: "JS"});
- } else {
- clearBadge();
- }
- }
- });
-}
-
-async function setSessionRules() {
- // not supported below safari 15.4
- if (!browser.declarativeNetRequest.updateSessionRules) return;
- await clearAllSessionRules();
- const message = {name: "REQ_REQUESTS"};
- const response = await browser.runtime.sendNativeMessage(message);
- if (response.error) {
- console.error(response.error);
- return;
- }
- // there are no rules to apply
- if (!response.length) return;
- // loop through response, parse the rules, push to array and log
- const rules = [];
- for (let i = 0; i < response.length; i++) {
- const rule = response[i];
- const code = JSON.parse(rule.code);
- // check if an array or single rule
- if (Array.isArray(code)) {
- code.forEach(r => rules.push(r));
- console.info(`Setting session rule: ${rule.name} (${code.length})`);
- } else {
- rules.push(code);
- console.info(`Setting session rule: ${rule.name}`);
- }
- }
- // generate unique ids for all rules to ensure no repeats
- const ids = randomNumberSet(1000, rules.length);
- rules.map((rule, index) => rule.id = ids[index]);
- try {
- await browser.declarativeNetRequest.updateSessionRules({addRules: rules});
- } catch (error) {
- console.error(`Error setting session rules: ${error}`);
- return;
- }
- console.info(`Finished setting ${rules.length} session rules`);
-}
-
-async function clearAllSessionRules() {
- const rules = await browser.declarativeNetRequest.getSessionRules();
- if (!rules.length) return;
- console.info(`Clearing ${rules.length} session rules`);
- const ruleIds = rules.map(a => a.id);
- await browser.declarativeNetRequest.updateSessionRules({
- removeRuleIds: ruleIds
- });
-}
-
-function randomNumberSet(max, count) {
- // generates a set of random unique numbers
- // returns an array
- const numbers = new Set();
- while (numbers.size < count) {
- numbers.add((Math.floor(Math.random() * (max - 1 + 1)) + 1));
- }
- return [...numbers];
-}
-
-async function getContextMenuItems() {
- // macos exclusive feature
- const platform = await getPlatform();
- if (platform !== "macos") return;
- // since it's not possible to get a list of currently active menu items
- // on update, all context-menu items are cleared, then re-added
- // this is done to ensure fresh code changes appear
- await browser.menus.removeAll();
- // get the context-menu scripts
- const message = {name: "REQ_CONTEXT_MENU_SCRIPTS"};
- const response = await browser.runtime.sendNativeMessage(message);
- if (response.error) {
- console.error(response.error);
- return;
- }
- // add menus items
- const items = response.files?.menu || [];
- if (items.length) {
- console.info(`Setting ${items.length} context-menu userscripts`);
- }
- for (let i = 0; i < items.length; i++) {
- const item = items[i];
- // context-menu scripts require @match value
- // @include values are ignored
- if (!item.scriptObject.matches.length) continue;
- addContextMenuItem(item);
- }
-}
-
-async function addContextMenuItem(userscript) {
- // context-menu items persist for a session
- // to avoid duplication, when created, save the filename to session storage
- const savedItems = sessionStorage.getItem("menu");
- // if the session storage key doesn't exist use empty array
- const activeItems = savedItems ? JSON.parse(savedItems) : [];
- if (activeItems.indexOf(userscript.scriptObject.filename) !== -1) {
- // if already saved, remove it, to get fresh code changes
- await browser.menus.remove(userscript.scriptObject.filename);
- }
- // potential bug? https://developer.apple.com/forums/thread/685273
- // https://stackoverflow.com/q/68431201
- // parse through match values and change pathnames to deal with bug
- const patterns = userscript.scriptObject.matches;
- patterns.forEach((pattern, index) => {
- try {
- const url = new URL(pattern);
- let pathname = url.pathname;
- if (pathname.length > 1 && pathname.endsWith("/")) {
- pathname = pathname.slice(0, -1);
- }
- patterns[index] = `${url.protocol}//${url.hostname}${pathname}`;
- } catch (error) {
- // prevent breaking when non-url pattern present
- }
- });
-
- browser.menus.create({
- contexts: ["all"],
- documentUrlPatterns: patterns,
- id: userscript.scriptObject.filename,
- title: userscript.scriptObject.name
- }, () => {
- // add event listener if needed
- if (!browser.menus.onClicked.hasListener(contextClick)) {
- browser.menus.onClicked.addListener(contextClick);
- }
- // save the context-menu item reference to sessionStorage
- const value = JSON.stringify([userscript.scriptObject.filename]);
- sessionStorage.setItem("menu", value);
- });
-}
-
-function contextClick(info, tab) {
- // when any created context-menu item is clicked, send message to tab
- // the content script for that tag will have the context-menu code
- // which will get send back in the response if/when found
- const message = {name: "CONTEXT_RUN", menuItemId: info.menuItemId};
- browser.tabs.sendMessage(tab.id, message, response => {
- // if code is returned, execute on that tab
- if (!response.code) return;
- browser.tabs.executeScript(tab.id, {
- code: response.code
- });
- });
-}
-
-// handles messages sent with browser.runtime.sendMessage
-function handleMessage(request, sender, sendResponse) {
- switch (request.name) {
- case "REQ_USERSCRIPTS": {
- // get the page url from the content script that sent request
- const url = sender.url;
- // use frameId to determine if request came from top level window
- // if @noframes true, and isTop false, swift layer won't return code
- const isTop = sender.frameId === 0;
- // send request to swift layer to provide code for page url
- const message = {name: "REQ_USERSCRIPTS", url, isTop};
- browser.runtime.sendNativeMessage(message, response => {
- // if request failed, send error to content script for logging
- if (response.error) return sendResponse(response);
- // sort files
- response.files.js.sort(userscriptSort);
- response.files.css.sort((a, b) => {
- return Number(a.weight) < Number(b.weight);
- });
- // return sorted files for injection
- sendResponse(response);
- });
- return true;
- }
- case "API_CLOSE_TAB": {
- const tabId = request.tabId || sender.tab.id;
- browser.tabs.remove(tabId, () => sendResponse({success: 1}));
- return true;
- }
- case "API_OPEN_TAB": {
- const props = {
- active: request.active,
- index: sender.tab.index + 1,
- url: request.url
- };
- browser.tabs.create(props, response => sendResponse(response));
- return true;
- }
- case "API_ADD_STYLE": {
- const tabId = sender.tab.id;
- const details = {code: request.css, cssOrigin: "user"};
- browser.tabs.insertCSS(tabId, details, () => {
- sendResponse(request.css);
- });
- return true;
- }
- case "API_GET_TAB": {
- let tab = null;
- if (typeof sender.tab !== "undefined") {
- const tabData = sessionStorage.getItem(`tab-${sender.tab.id}`);
- try {
- // if tabData is null, can still parse it and return that
- tab = JSON.parse(tabData);
- } catch (error) {
- console.error("failed to parse tab data for getTab");
- }
- } else {
- console.error("unable to deliver tab due to empty tab id");
- }
- sendResponse(tab == null ? {} : tab);
- break;
- }
- case "API_SAVE_TAB": {
- if (sender.tab != null && sender.tab.id) {
- const key = `tab-${sender.tab.id}`;
- sessionStorage.setItem(key, JSON.stringify(request.tab));
- sendResponse({success: true});
- } else {
- console.error("unable to save tab, empty tab id");
- sendResponse({success: false});
- }
- break;
- }
- case "API_SET_CLIPBOARD": {
- const result = setClipboard(request.data, request.type);
- sendResponse(result);
- break;
- }
- case "API_XHR": {
- // parse details and set up for XMLHttpRequest
- const details = request.details;
- const method = details.method ? details.method : "GET";
- const user = details.user || null;
- const password = details.password || null;
- let body = details.data || null;
- if (body != null && details.binary != null) {
- const len = body.length;
- const arr = new Uint8Array(len);
- for (let i = 0; i < len; i++) {
- arr[i] = body.charCodeAt(i);
- }
- body = new Blob([arr], {type: "text/plain"});
- }
- // establish a long-lived port connection to content script
- const port = browser.tabs.connect(sender.tab.id, {
- name: request.xhrPortName
- });
- // set up XMLHttpRequest
- const xhr = new XMLHttpRequest();
- xhr.withCredentials = (details.user && details.password);
- xhr.timeout = details.timeout || 0;
- if (details.overrideMimeType) {
- xhr.overrideMimeType(details.overrideMimeType);
- }
- // add required listeners and send result back to the content script
- for (const e of request.events) {
- if (!details[e]) continue;
- xhr[e] = async event => {
- // can not send xhr through postMessage
- // construct new object to be sent as "response"
- const x = {
- readyState: xhr.readyState,
- response: xhr.response,
- responseHeaders: xhr.getAllResponseHeaders(),
- responseType: xhr.responseType,
- responseURL: xhr.responseURL,
- status: xhr.status,
- statusText: xhr.statusText,
- timeout: xhr.timeout,
- withCredentials: xhr.withCredentials
- };
- // only include responseText when needed
- if (["", "text"].indexOf(xhr.responseType) !== -1) {
- x.responseText = xhr.responseText;
- }
- // need to convert arraybuffer data to postMessage
- if (xhr.responseType === "arraybuffer") {
- const arr = Array.from(new Uint8Array(xhr.response));
- x.response = arr;
- }
- // need to blob arraybuffer data to postMessage
- if (xhr.responseType === "blob") {
- const base64data = await readAsDataURL(xhr.response);
- x.response = {
- data: base64data,
- type: xhr.responseType
- };
- }
- port.postMessage({name: e, event, response: x});
- };
- }
- xhr.open(method, details.url, true, user, password);
- xhr.responseType = details.responseType || "";
- if (details.headers) {
- for (const key in details.headers) {
- const val = details.headers[key];
- xhr.setRequestHeader(key, val);
- }
- }
- // receive messages from content script and process them
- port.onMessage.addListener(msg => {
- if (msg.name === "ABORT") xhr.abort();
- if (msg.name === "DISCONNECT") port.disconnect();
- });
- // handle port disconnect and clean tasks
- port.onDisconnect.addListener(p => {
- if (p?.error) {
- console.error(`port disconnected due to an error: ${p.error.message}`);
- }
- });
- xhr.send(body);
- // if onloadend not set in xhr details
- // onloadend event won't be passed to content script
- // if that happens port DISCONNECT message won't be posted
- // if details lacks onloadend attach listener
- if (!details.onloadend) {
- xhr.onloadend = event => {
- port.postMessage({name: "onloadend", event});
- };
- }
- break;
- }
- case "REFRESH_SESSION_RULES": {
- setSessionRules();
- break;
- }
- case "REFRESH_CONTEXT_MENU_SCRIPTS": {
- getContextMenuItems();
- break;
- }
- }
-}
-
-browser.runtime.onStartup.addListener(async () => {
- // on startup get declarativeNetRequests
- // and set the requests for the session
- // should also check and refresh when:
- // 1. popup opens (done)
- // 2. a new save event in the page occurs
- // 3. the refresh button is pushed in the popup
- await setSessionRules();
- await getContextMenuItems();
-});
-// listens for messages from content script, popup and page
-browser.runtime.onMessage.addListener(handleMessage);
-// set the badge count
-browser.tabs.onActivated.addListener(setBadgeCount);
-browser.windows.onFocusChanged.addListener(setBadgeCount);
-browser.webNavigation.onCompleted.addListener(setBadgeCount);
-
-// handle native app messages
-const port = browser.runtime.connectNative();
-port.onMessage.addListener(message => {
- // console.info(message); // DEBUG
- if (message.name === "SAVE_LOCATION_CHANGED") {
- openExtensionPage();
- if (message?.userInfo?.returnApp === true) browser.runtime.sendNativeMessage({name: "OPEN_APP"});
- }
- // if (message.name === "OPEN_EXTENSION_PAGE") {
- // openExtensionPage();
- // }
-});
diff --git a/xcode/Safari-Extension/Resources/content.js b/xcode/Safari-Extension/Resources/content.js
deleted file mode 100644
index 2060a321..00000000
--- a/xcode/Safari-Extension/Resources/content.js
+++ /dev/null
@@ -1,469 +0,0 @@
-// code received from background page will be stored in this variable
-// code referenced again when strict CSPs block initial injection attempt
-let data;
-// determines whether strict csp injection has already run (JS only)
-let cspFallbackAttempted = false;
-// save reference to window's browser object
-const browser = window.browser;
-// GM APIs
-const apis = {
- closeTab(tabId) {
- return new Promise(resolve => {
- const message = {
- name: "API_CLOSE_TAB",
- tabId
- };
- browser.runtime.sendMessage(message, response => resolve(response));
- });
- },
- openInTab(url, openInBackground = false) {
- if (!url) return console.error("openInTab missing url arg");
- return new Promise(resolve => {
- const message = {
- name: "API_OPEN_TAB",
- url,
- active: !openInBackground
- };
- browser.runtime.sendMessage(message, response => resolve(response));
- });
- },
- setValue(key, value) {
- if (typeof key !== "string" || !key.length) {
- return console.error("setValue invalid key arg");
- }
- if (value == null) {
- return console.error("setValue invalid value arg");
- }
- return new Promise(resolve => {
- const item = {};
- item[`${this.US_filename}---${key}`] = value;
- browser.storage.local.set(item, () => resolve({success: 1}));
- });
- },
- getValue(key, defaultValue) {
- if (typeof key !== "string" || !key.length) {
- return console.error("getValue invalid key arg");
- }
- const prefixedKey = `${this.US_filename}---${key}`;
- return new Promise(resolve => {
- browser.storage.local.get(prefixedKey, item => {
- if (Object.keys(item).length === 0) {
- if (defaultValue != null) {
- resolve(defaultValue);
- } else {
- resolve(undefined);
- }
- } else {
- resolve(Object.values(item)[0]);
- }
- });
- });
- },
- deleteValue(key) {
- if (typeof key !== "string" || !key.length) {
- return console.error("deleteValue missing key arg");
- }
- return new Promise(resolve => {
- const prefixedKey = `${this.US_filename}---${key}`;
- browser.storage.local.remove(prefixedKey, () => {
- resolve({success: 1});
- });
- });
- },
- listValues() {
- return new Promise(resolve => {
- const prefix = `${this.US_filename}---`;
- const keys = [];
- browser.storage.local.get().then(items => {
- for (const key in items) {
- if (key.startsWith(prefix)) {
- const k = key.replace(prefix, "");
- keys.push(k);
- }
- }
- resolve(keys);
- });
- });
- },
- addStyle(css) {
- if (typeof css !== "string") {
- return console.error("addStyle invalid css arg");
- }
- return new Promise(resolve => {
- const message = {
- name: "API_ADD_STYLE",
- css
- };
- browser.runtime.sendMessage(message, response => resolve(response));
- });
- },
- getTab() {
- return new Promise(resolve => {
- const message = {name: "API_GET_TAB"};
- browser.runtime.sendMessage(message, response => {
- resolve(response);
- });
- });
- },
- saveTab(tab) {
- if (tab == null) return console.error("saveTab invalid arg");
- return new Promise(resolve => {
- const message = {
- name: "API_SAVE_TAB",
- tab
- };
- browser.runtime.sendMessage(message, response => {
- resolve(response);
- });
- });
- },
- setClipboard(clipboardData, type) {
- return new Promise(resolve => {
- const message = {
- name: "API_SET_CLIPBOARD",
- clipboardData,
- type
- };
- browser.runtime.sendMessage(message, response => {
- resolve(response);
- });
- });
- },
- xhr(details) {
- if (details == null) return console.error("xhr invalid details arg");
- if (!details.url) return console.error("xhr details missing url key");
- // generate random port name for single xhr
- const xhrPortName = Math.random().toString(36).substring(1, 9);
- // strip out functions from details
- const detailsParsed = JSON.parse(JSON.stringify(details));
- // get all the "on" events from XMLHttpRequest object
- const events = [];
- for (const k in XMLHttpRequest.prototype) {
- if (k.slice(0, 2) === "on") events.push(k);
- }
- // check which functions are included in the original details object
- // add a bool to indicate if event listeners should be attached
- for (const e of events) {
- if (typeof details[e] === "function") detailsParsed[e] = true;
- }
- // define return method, will be populated after port is established
- const response = {
- abort: () => console.error("xhr has not yet been initialized")
- };
- // port listener, most of the messaging logic goes here
- const listener = port => {
- if (port.name !== xhrPortName) return;
- port.onMessage.addListener(async msg => {
- if (
- events.includes(msg.name)
- && typeof details[msg.name] === "function"
- ) {
- // process xhr response
- const r = msg.response;
- if (r.responseType === "arraybuffer") {
- // arraybuffer responses had their data converted in background
- // convert it back to arraybuffer
- try {
- const buffer = new Uint8Array(r.response).buffer;
- r.response = buffer;
- } catch (err) {
- console.error("error parsing xhr arraybuffer", err);
- }
- } else if (r.responseType === "blob" && r.response.data) {
- // blob responses had their data converted in background
- // convert it back to blob
- const resp = await fetch(r.response.data);
- const b = await resp.blob();
- r.response = b;
- }
- // call userscript method
- details[msg.name](msg.response);
- }
- // all messages received
- // tell background it's safe to close port
- if (msg.name === "onloadend") {
- port.postMessage({name: "DISCONNECT"});
- }
- });
-
- // handle port disconnect and clean tasks
- port.onDisconnect.addListener(p => {
- if (p?.error) {
- console.error(`port disconnected due to an error: ${p.error.message}`);
- }
- browser.runtime.onConnect.removeListener(listener);
- });
- // fill the method returned to the user script
- response.abort = () => port.postMessage({name: "ABORT"});
- };
- // wait for the background to establish a port connection
- browser.runtime.onConnect.addListener(listener);
- // pass the basic information to the background through a common message
- const message = {
- name: "API_XHR",
- details: detailsParsed,
- xhrPortName,
- events
- };
- browser.runtime.sendMessage(message);
- return response;
- },
- // include method names so they don't get skipped when adding to userscript
- xmlHttpRequest: true,
- GM_xmlhttpRequest: true
-};
-// remote window's browser object
-delete window.browser;
-
-// label used to distinguish frames in console
-const label = randomLabel();
-
-function randomLabel() {
- const a = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", r = Math.random();
- return a[Math.floor(r * a.length)] + r.toString().slice(5, 6);
-}
-
-function processJS(userscript) {
- const runAt = userscript.scriptObject["run-at"];
- if (runAt === "document-start") {
- injectJS(userscript);
- } else if (runAt === "document-end") {
- if (document.readyState !== "loading") {
- injectJS(userscript);
- } else {
- document.addEventListener("DOMContentLoaded", () => {
- injectJS(userscript);
- });
- }
- } else if (runAt === "document-idle") {
- if (document.readyState === "complete") {
- injectJS(userscript);
- } else {
- document.addEventListener("readystatechange", () => {
- if (document.readyState === "complete") {
- injectJS(userscript);
- }
- });
- }
- }
-}
-
-function wrapCode(preCode, code, filename) {
- const tag = window.self === window.top ? "" : `(${label})`;
- return `
- (function() {
- ${preCode}
- (function() {
- const US_filename = "${filename}";
- const apis = undefined;
- const browser = undefined;
- // userscript code below
- ${code}
- //# sourceURL=${filename.replace(/\s/g, "-") + tag}
- })();
- })();
- `;
-}
-
-function injectJS(userscript) {
- const filename = userscript.scriptObject.filename;
- const code = wrapCode(userscript.preCode, userscript.code, filename);
- const name = userscript.scriptObject.name;
- let injectInto = userscript.scriptObject["inject-into"];
- // change scope to content since strict CSP event detected
- if (injectInto === "auto" && (userscript.fallback || cspFallbackAttempted)) {
- injectInto = "content";
- console.warn(`Attempting fallback injection for ${name}`);
- } else if (window.self === window.top) {
- console.info(`Injecting ${name} %c(js)`, "color: #fff600");
- } else {
- console.info(`Injecting ${name} %c(js)%c - %cframe(${label})(${window.location})`, "color: #fff600", "color: inherit", "color: #006fff");
- }
- if (injectInto !== "content") {
- const tag = document.createElement("script");
- tag.textContent = code;
- document.head.appendChild(tag);
- } else {
- try {
- // eslint-disable-next-line no-new-func
- return Function(code)();
- } catch (error) {
- console.error(`${filename} error`, error);
- }
- }
-}
-
-function injectCSS(name, code) {
- if (window.self === window.top) {
- console.info(`Injecting ${name} %c(css)`, "color: #60f36c");
- } else {
- console.info(`Injecting ${name} %c(css)%c - %cframe(${label})(${window.location})`, "color: #60f36c", "color: inherit", "color: #006fff");
- }
- // Safari lacks full support for tabs.insertCSS
- // https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/insertCSS
- // specifically frameId and cssOrigin
- // if support for those details keys arrives, the method below can be used
- // NOTE: manifest V3 does support frameId, but not origin
- // https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/insertCSS
-
- // write the css code to head of the document
- const tag = document.createElement("style");
- tag.textContent = code;
- document.head.appendChild(tag);
-}
-
-function cspFallback(e) {
- // if a security policy violation event has occurred
- // and the directive is script-src or script-src-elem
- // it's fair to assume that there is a strict CSP for javascript
- // and that injection was blocked for all userscripts
- // when any script-src violation is detected, re-attempt injection
- if (
- e.effectiveDirective === "script-src"
- || e.effectiveDirective === "script-src-elem"
- ) {
- // get all "auto" code
- // since other code can trigger a security policy violation event
- // make sure data var is not undefined before attempting fallback
- if (!data || cspFallbackAttempted) return;
- // update global that tracks security policy violations
- cspFallbackAttempted = 1;
- // for all userscripts with @inject-into: auto, attempt re-injection
- for (let i = 0; i < data.files.js.length; i++) {
- const userscript = data.files.js[i];
- if (userscript.scriptObject["inject-into"] !== "auto") continue;
- userscript.fallback = 1;
- processJS(userscript);
- }
- }
-}
-
-function injection() {
- browser.runtime.sendMessage({name: "REQ_USERSCRIPTS"}, response => {
- // cancel injection if errors detected
- if (!response || response.error) {
- console.error(response?.error || "REQ_USERSCRIPTS returned undefined");
- return;
- }
- // save response locally in case CSP events occur
- data = response;
- // combine regular and context-menu scripts
- const scripts = [...data.files.js, ...data.files.menu];
- // loop through each userscript and prepare for processing
- for (let i = 0; i < scripts.length; i++) {
- const userscript = scripts[i];
- userscript.preCode = "";
- // pass references to the api methods as needed
- const gmMethods = [];
- const filename = userscript.scriptObject.filename;
- const grants = userscript.scriptObject.grant;
- const injectInto = userscript.scriptObject["inject-into"];
- // create GM.info object
- const scriptData = {
- script: userscript.scriptObject,
- scriptHandler: data.scriptHandler,
- scriptHandlerVersion: data.scriptHandlerVersion,
- scriptMetaStr: userscript.scriptMetaStr
- };
- // all userscripts get access to GM.info
- gmMethods.push("info: GM_info");
- // if @grant explicitly set to none, empty grants array
- if (grants.includes("none")) grants.length = 0;
- // @grant values exist for page scoped userscript
- if (grants.length && injectInto === "page") {
- // remove grants
- grants.length = 0;
- // log warning
- console.warn(`${filename} @grant values removed due to @inject-into value: ${injectInto} - https://github.com/quoid/userscripts/issues/265#issuecomment-1213462394`);
- }
- // @grant exist for auto scoped userscript
- if (grants.length && injectInto === "auto") {
- // change scope
- userscript.scriptObject["inject-into"] = "content";
- // log warning
- console.warn(`${filename} @inject-into value set to 'content' due to @grant values: ${grants} - https://github.com/quoid/userscripts/issues/265#issuecomment-1213462394`);
- }
- // loop through each userscript @grant value, add methods as needed
- for (let j = 0; j < grants.length; j++) {
- const grant = grants[j];
- const method = grant.split(".")[1] || grant.split(".")[0];
- // ensure API method exists in apis object
- if (!Object.keys(apis).includes(method)) continue;
- // create the method string to be pushed to methods array
- let methodStr = `${method}: apis.${method}`;
- // add require variables to specific methods
- switch (method) {
- case "getValue":
- case "setValue":
- case "deleteValue":
- case "listValues":
- methodStr += `.bind({"US_filename": "${filename}"})`;
- break;
- case "info":
- case "GM_info":
- continue;
- case "xmlHttpRequest":
- gmMethods.push("xmlHttpRequest: apis.xhr");
- continue;
- case "GM_xmlhttpRequest":
- userscript.preCode += "const GM_xmlhttpRequest = apis.xhr;";
- continue;
- }
- gmMethods.push(methodStr);
- }
- // add GM.info
- userscript.preCode += `const GM_info = ${JSON.stringify(scriptData)};`;
- // add other included GM API methods
- userscript.preCode += `const GM = {${gmMethods.join(",")}};`;
- // process file for injection
- processJS(userscript);
- }
- for (let i = 0; i < data.files.css.length; i++) {
- const userstyle = data.files.css[i];
- injectCSS(userstyle.name, userstyle.code);
- }
- });
-}
-
-function listeners() {
- // listens for messages from background, popup, etc...
- browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
- const name = request.name;
- if (name === "CONTEXT_RUN") {
- // from bg script when context-menu item is clicked
- // double check to ensure context-menu scripts only run in top windows
- if (window !== window.top) return;
-
- // loop through context-menu scripts saved to data object and find match
- // if no match found, nothing will execute and error will log
- const filename = request.menuItemId;
- for (let i = 0; i < data.files.menu.length; i++) {
- const item = data.files.menu[i];
- if (item.scriptObject.filename === filename) {
- console.info(`Injecting ${filename} %c(js)`, "color: #fff600");
- sendResponse({
- code: wrapCode(
- item.preCode,
- item.code,
- filename
- )
- });
- return;
- }
- }
- console.error(`Couldn't find ${filename} code!`);
- }
- });
- // listen for CSP violations
- document.addEventListener("securitypolicyviolation", cspFallback);
-}
-
-async function initialize() {
- const results = await browser.storage.local.get("US_GLOBAL_ACTIVE");
- if (results?.US_GLOBAL_ACTIVE === false) return console.info("Userscripts off");
- // start the injection process and add the listeners
- injection();
- listeners();
-}
-
-initialize();
diff --git a/xcode/Safari-Extension/Resources/manifest.json b/xcode/Safari-Extension/Resources/manifest.json
index 875d3d91..99f6e1d4 100644
--- a/xcode/Safari-Extension/Resources/manifest.json
+++ b/xcode/Safari-Extension/Resources/manifest.json
@@ -17,7 +17,7 @@
"persistent": false
},
"browser_action": {
- "default_popup": "dist/entry-popup.html",
+ "default_popup": "popup.html",
"default_icon": {
"16": "images/toolbar-icon-16.png",
"32": "images/toolbar-icon-32.png"
diff --git a/xcode/Userscripts.xcodeproj/project.pbxproj b/xcode/Userscripts.xcodeproj/project.pbxproj
index 8286d541..05dbe5fd 100644
--- a/xcode/Userscripts.xcodeproj/project.pbxproj
+++ b/xcode/Userscripts.xcodeproj/project.pbxproj
@@ -10,8 +10,6 @@
0336619F294DF7C900CFE179 /* Functions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0336619E294DF7C900CFE179 /* Functions.swift */; };
033661A529510B7900CFE179 /* View.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 033661A329510B7900CFE179 /* View.storyboard */; };
0376905B29808EEA00F3474D /* background.js in Resources */ = {isa = PBXBuildFile; fileRef = 0376905A29808EEA00F3474D /* background.js */; };
- 03E20D06291E170000B4F692 /* dist in Resources */ = {isa = PBXBuildFile; fileRef = 03E20D05291E170000B4F692 /* dist */; };
- 03E20D07291E170000B4F692 /* dist in Resources */ = {isa = PBXBuildFile; fileRef = 03E20D05291E170000B4F692 /* dist */; };
4A143AAC279DE6FF0029BFD0 /* UserscriptsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A143AAB279DE6FF0029BFD0 /* UserscriptsTests.swift */; };
4A143AB2279DEA170029BFD0 /* Functions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AED6491268CDB58001794BF /* Functions.swift */; };
4A301B2A270A474400C7E9E1 /* SafariWebExtensionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A57BA07227235CE008A9763 /* SafariWebExtensionHandler.swift */; };
@@ -37,7 +35,15 @@
4A57B9F9227235CE008A9763 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4A57B9F8227235CE008A9763 /* Assets.xcassets */; };
4A57BA00227235CE008A9763 /* Userscripts-Mac-Safari-Extension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 4A57B9FF227235CE008A9763 /* Userscripts-Mac-Safari-Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
4A57BA08227235CE008A9763 /* SafariWebExtensionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A57BA07227235CE008A9763 /* SafariWebExtensionHandler.swift */; };
+ 4A77B5A52A00528C0066A26F /* popup.js in Resources */ = {isa = PBXBuildFile; fileRef = 4AD50E9C2A004AE000247952 /* popup.js */; };
+ 4A77B5A62A0052C80066A26F /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 4AD50EB12A004CE200247952 /* assets */; };
+ 4A77B5A72A0052C90066A26F /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 4AD50EB12A004CE200247952 /* assets */; };
+ 4A77B5A82A0052D00066A26F /* popup.js in Resources */ = {isa = PBXBuildFile; fileRef = 4AD50E9C2A004AE000247952 /* popup.js */; };
4AB22358268B9B9200D551C6 /* content.js in Resources */ = {isa = PBXBuildFile; fileRef = 4AB22357268B9B9200D551C6 /* content.js */; };
+ 4AD50E9F2A004AE000247952 /* page.js in Resources */ = {isa = PBXBuildFile; fileRef = 4AD50E9B2A004AE000247952 /* page.js */; };
+ 4AD50EA32A004AE000247952 /* popup.html in Resources */ = {isa = PBXBuildFile; fileRef = 4AD50E9D2A004AE000247952 /* popup.html */; };
+ 4AD50EA42A004AE000247952 /* popup.html in Resources */ = {isa = PBXBuildFile; fileRef = 4AD50E9D2A004AE000247952 /* popup.html */; };
+ 4AD50EA52A004AE000247952 /* page.html in Resources */ = {isa = PBXBuildFile; fileRef = 4AD50E9E2A004AE000247952 /* page.html */; };
4AD66D2326826D8100B004E8 /* manifest.json in Resources */ = {isa = PBXBuildFile; fileRef = 4AD66D2026826D8100B004E8 /* manifest.json */; };
4AED6492268CDB58001794BF /* Functions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AED6491268CDB58001794BF /* Functions.swift */; };
7878ED24299BA27B00E36A24 /* SafariWebExtensionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A57BA07227235CE008A9763 /* SafariWebExtensionHandler.swift */; };
@@ -102,7 +108,6 @@
0336619E294DF7C900CFE179 /* Functions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Functions.swift; sourceTree = ""; };
033661A429510B7900CFE179 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/View.storyboard; sourceTree = ""; };
0376905A29808EEA00F3474D /* background.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = background.js; sourceTree = ""; };
- 03E20D05291E170000B4F692 /* dist */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dist; sourceTree = ""; };
4A143AA9279DE6FF0029BFD0 /* Mac-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Mac-Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
4A143AAB279DE6FF0029BFD0 /* UserscriptsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserscriptsTests.swift; sourceTree = ""; };
4A36A616268266B30018536B /* images */ = {isa = PBXFileReference; lastKnownFileType = folder; path = images; sourceTree = ""; };
@@ -131,6 +136,11 @@
4A57BA0E227235CE008A9763 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
4A57BA1D227235E6008A9763 /* Mac.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Mac.entitlements; sourceTree = ""; };
4AB22357268B9B9200D551C6 /* content.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = content.js; sourceTree = ""; };
+ 4AD50E9B2A004AE000247952 /* page.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = page.js; sourceTree = ""; };
+ 4AD50E9C2A004AE000247952 /* popup.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = popup.js; sourceTree = ""; };
+ 4AD50E9D2A004AE000247952 /* popup.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = popup.html; sourceTree = ""; };
+ 4AD50E9E2A004AE000247952 /* page.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = page.html; sourceTree = ""; };
+ 4AD50EB12A004CE200247952 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = ""; };
4AD66D2026826D8100B004E8 /* manifest.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = manifest.json; sourceTree = ""; };
4AED6491268CDB58001794BF /* Functions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Functions.swift; sourceTree = ""; };
78391D4629A4CB3C00979E34 /* Userscripts-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Userscripts-Debug.xcconfig"; sourceTree = ""; };
@@ -273,11 +283,15 @@
isa = PBXGroup;
children = (
4A36A617268266B30018536B /* _locales */,
+ 4AD50EB12A004CE200247952 /* assets */,
4A36A616268266B30018536B /* images */,
- 03E20D05291E170000B4F692 /* dist */,
- 4AD66D2026826D8100B004E8 /* manifest.json */,
0376905A29808EEA00F3474D /* background.js */,
4AB22357268B9B9200D551C6 /* content.js */,
+ 4AD66D2026826D8100B004E8 /* manifest.json */,
+ 4AD50E9E2A004AE000247952 /* page.html */,
+ 4AD50E9B2A004AE000247952 /* page.js */,
+ 4AD50E9D2A004AE000247952 /* popup.html */,
+ 4AD50E9C2A004AE000247952 /* popup.js */,
);
path = Resources;
sourceTree = "";
@@ -477,11 +491,13 @@
buildActionMask = 2147483647;
files = (
4A301B2E270A475D00C7E9E1 /* content.js in Resources */,
+ 4A77B5A62A0052C80066A26F /* assets in Resources */,
4A301B2C270A475200C7E9E1 /* images in Resources */,
7878ED2B299BA36800E36A24 /* background.js in Resources */,
- 03E20D07291E170000B4F692 /* dist in Resources */,
+ 4AD50EA42A004AE000247952 /* popup.html in Resources */,
4A301B2F270A476000C7E9E1 /* manifest.json in Resources */,
4A301B2B270A474F00C7E9E1 /* _locales in Resources */,
+ 4A77B5A52A00528C0066A26F /* popup.js in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -499,10 +515,14 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 4AD50E9F2A004AE000247952 /* page.js in Resources */,
+ 4AD50EA52A004AE000247952 /* page.html in Resources */,
4AD66D2326826D8100B004E8 /* manifest.json in Resources */,
4AB22358268B9B9200D551C6 /* content.js in Resources */,
- 03E20D06291E170000B4F692 /* dist in Resources */,
+ 4AD50EA32A004AE000247952 /* popup.html in Resources */,
+ 4A77B5A72A0052C90066A26F /* assets in Resources */,
4A36A61A268266B30018536B /* images in Resources */,
+ 4A77B5A82A0052D00066A26F /* popup.js in Resources */,
0376905B29808EEA00F3474D /* background.js in Resources */,
4A36A61B268266B30018536B /* _locales in Resources */,
);
From 3a862b5530279dd0c137ea6f279f164f007d3313 Mon Sep 17 00:00:00 2001
From: quoid <7660254+quoid@users.noreply.github.com>
Date: Mon, 1 May 2023 16:28:24 -0400
Subject: [PATCH 04/13] chore: set up vitest
---
package.json | 8 +-
pnpm-lock.yaml | 1152 +++++++++++++++++++++++++++++++++++++++-
tests/page/App.test.js | 17 +
vite.config.js | 7 +-
4 files changed, 1163 insertions(+), 21 deletions(-)
create mode 100644 tests/page/App.test.js
diff --git a/package.json b/package.json
index c316505d..168f32f2 100644
--- a/package.json
+++ b/package.json
@@ -11,10 +11,12 @@
"format": "prettier --write '**/*.{js,ts,css,svelte}'",
"lint:css": "stylelint '**/*.{css,svelte}'",
"lint:js": "eslint ./ --max-warnings 10",
- "preview": "vite preview"
+ "preview": "vite preview",
+ "test": "vitest run"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^2.0.3",
+ "@testing-library/svelte": "^3.2.2",
"@types/webextension-polyfill": "^0.10.0",
"autoprefixer": "^10.4.13",
"cm-show-invisibles": "^3.1.0",
@@ -23,6 +25,7 @@
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-svelte": "^2.27.2",
+ "jsdom": "^21.1.2",
"postcss": "^8.4.23",
"postcss-html": "^1.5.0",
"prettier": "^2.8.8",
@@ -34,6 +37,7 @@
"stylelint-order": "^6.0.3",
"stylelint-prettier": "^3.0.0",
"svelte": "^3.55.1",
- "vite": "^4.1.4"
+ "vite": "^4.1.4",
+ "vitest": "^0.30.1"
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 952fd4ed..689d63d5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -2,6 +2,7 @@ lockfileVersion: 5.4
specifiers:
'@sveltejs/vite-plugin-svelte': ^2.0.3
+ '@testing-library/svelte': ^3.2.2
'@types/webextension-polyfill': ^0.10.0
autoprefixer: ^10.4.13
cm-show-invisibles: ^3.1.0
@@ -10,6 +11,7 @@ specifiers:
eslint-config-prettier: ^8.8.0
eslint-plugin-prettier: ^4.2.1
eslint-plugin-svelte: ^2.27.2
+ jsdom: ^21.1.2
postcss: ^8.4.23
postcss-html: ^1.5.0
prettier: ^2.8.8
@@ -22,9 +24,11 @@ specifiers:
stylelint-prettier: ^3.0.0
svelte: ^3.55.1
vite: ^4.1.4
+ vitest: ^0.30.1
devDependencies:
'@sveltejs/vite-plugin-svelte': 2.0.3_svelte@3.55.1+vite@4.1.4
+ '@testing-library/svelte': 3.2.2_svelte@3.55.1
'@types/webextension-polyfill': 0.10.0
autoprefixer: 10.4.13_postcss@8.4.23
cm-show-invisibles: 3.1.0
@@ -33,6 +37,7 @@ devDependencies:
eslint-config-prettier: 8.8.0_eslint@8.35.0
eslint-plugin-prettier: 4.2.1_hlw7btvvbpomsbv6wtkjlnqoee
eslint-plugin-svelte: 2.27.2_n4ieifq2d7jq3sqoe474cgqlim
+ jsdom: 21.1.2
postcss: 8.4.23
postcss-html: 1.5.0
prettier: 2.8.8
@@ -45,6 +50,7 @@ devDependencies:
stylelint-prettier: 3.0.0_ijjwmmxqo5tkozh2kjbk6pd5e4
svelte: 3.55.1
vite: 4.1.4
+ vitest: 0.30.1_jsdom@21.1.2
packages:
@@ -69,6 +75,13 @@ packages:
js-tokens: 4.0.0
dev: true
+ /@babel/runtime/7.21.5:
+ resolution: {integrity: sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ regenerator-runtime: 0.13.11
+ dev: true
+
/@csstools/selector-specificity/2.1.1_s3s7cysqdh2c5ra7frs7uhrtc4:
resolution: {integrity: sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw==}
engines: {node: ^14 || ^16 || >=18}
@@ -374,10 +387,57 @@ packages:
- supports-color
dev: true
+ /@testing-library/dom/8.20.0:
+ resolution: {integrity: sha512-d9ULIT+a4EXLX3UU8FBjauG9NnsZHkHztXoIcTsOKoOw030fyjheN9svkTULjJxtYag9DZz5Jz5qkWZDPxTFwA==}
+ engines: {node: '>=12'}
+ dependencies:
+ '@babel/code-frame': 7.18.6
+ '@babel/runtime': 7.21.5
+ '@types/aria-query': 5.0.1
+ aria-query: 5.1.3
+ chalk: 4.1.2
+ dom-accessibility-api: 0.5.16
+ lz-string: 1.5.0
+ pretty-format: 27.5.1
+ dev: true
+
+ /@testing-library/svelte/3.2.2_svelte@3.55.1:
+ resolution: {integrity: sha512-IKwZgqbekC3LpoRhSwhd0JswRGxKdAGkf39UiDXTywK61YyLXbCYoR831e/UUC6EeNW4hiHPY+2WuovxOgI5sw==}
+ engines: {node: '>= 10'}
+ peerDependencies:
+ svelte: 3.x
+ dependencies:
+ '@testing-library/dom': 8.20.0
+ svelte: 3.55.1
+ dev: true
+
+ /@tootallnate/once/2.0.0:
+ resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==}
+ engines: {node: '>= 10'}
+ dev: true
+
+ /@types/aria-query/5.0.1:
+ resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==}
+ dev: true
+
+ /@types/chai-subset/1.3.3:
+ resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==}
+ dependencies:
+ '@types/chai': 4.3.5
+ dev: true
+
+ /@types/chai/4.3.5:
+ resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==}
+ dev: true
+
/@types/minimist/1.2.2:
resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==}
dev: true
+ /@types/node/18.16.3:
+ resolution: {integrity: sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==}
+ dev: true
+
/@types/normalize-package-data/2.4.1:
resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
dev: true
@@ -390,6 +450,56 @@ packages:
resolution: {integrity: sha512-If4EcaHzYTqcbNMp/FdReVdRmLL/Te42ivnJII551bYjhX19bWem5m14FERCqdJA732OloGuxCRvLBvcMGsn4A==}
dev: true
+ /@vitest/expect/0.30.1:
+ resolution: {integrity: sha512-c3kbEtN8XXJSeN81iDGq29bUzSjQhjES2WR3aColsS4lPGbivwLtas4DNUe0jD9gg/FYGIteqOenfU95EFituw==}
+ dependencies:
+ '@vitest/spy': 0.30.1
+ '@vitest/utils': 0.30.1
+ chai: 4.3.7
+ dev: true
+
+ /@vitest/runner/0.30.1:
+ resolution: {integrity: sha512-W62kT/8i0TF1UBCNMRtRMOBWJKRnNyv9RrjIgdUryEe0wNpGZvvwPDLuzYdxvgSckzjp54DSpv1xUbv4BQ0qVA==}
+ dependencies:
+ '@vitest/utils': 0.30.1
+ concordance: 5.0.4
+ p-limit: 4.0.0
+ pathe: 1.1.0
+ dev: true
+
+ /@vitest/snapshot/0.30.1:
+ resolution: {integrity: sha512-fJZqKrE99zo27uoZA/azgWyWbFvM1rw2APS05yB0JaLwUIg9aUtvvnBf4q7JWhEcAHmSwbrxKFgyBUga6tq9Tw==}
+ dependencies:
+ magic-string: 0.30.0
+ pathe: 1.1.0
+ pretty-format: 27.5.1
+ dev: true
+
+ /@vitest/spy/0.30.1:
+ resolution: {integrity: sha512-YfJeIf37GvTZe04ZKxzJfnNNuNSmTEGnla2OdL60C8od16f3zOfv9q9K0nNii0NfjDJRt/CVN/POuY5/zTS+BA==}
+ dependencies:
+ tinyspy: 2.1.0
+ dev: true
+
+ /@vitest/utils/0.30.1:
+ resolution: {integrity: sha512-/c8Xv2zUVc+rnNt84QF0Y0zkfxnaGhp87K2dYJMLtLOIckPzuxLVzAtFCicGFdB4NeBHNzTRr1tNn7rCtQcWFA==}
+ dependencies:
+ concordance: 5.0.4
+ loupe: 2.3.6
+ pretty-format: 27.5.1
+ dev: true
+
+ /abab/2.0.6:
+ resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==}
+ dev: true
+
+ /acorn-globals/7.0.1:
+ resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==}
+ dependencies:
+ acorn: 8.8.2
+ acorn-walk: 8.2.0
+ dev: true
+
/acorn-jsx/5.3.2_acorn@8.8.2:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
@@ -398,12 +508,26 @@ packages:
acorn: 8.8.2
dev: true
+ /acorn-walk/8.2.0:
+ resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
+ engines: {node: '>=0.4.0'}
+ dev: true
+
/acorn/8.8.2:
resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==}
engines: {node: '>=0.4.0'}
hasBin: true
dev: true
+ /agent-base/6.0.2:
+ resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
+ engines: {node: '>= 6.0.0'}
+ dependencies:
+ debug: 4.3.4
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/ajv/6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
dependencies:
@@ -441,10 +565,28 @@ packages:
color-convert: 2.0.1
dev: true
+ /ansi-styles/5.2.0:
+ resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
+ engines: {node: '>=10'}
+ dev: true
+
/argparse/2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
dev: true
+ /aria-query/5.1.3:
+ resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==}
+ dependencies:
+ deep-equal: 2.2.1
+ dev: true
+
+ /array-buffer-byte-length/1.0.0:
+ resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==}
+ dependencies:
+ call-bind: 1.0.2
+ is-array-buffer: 3.0.2
+ dev: true
+
/array-union/2.1.0:
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
engines: {node: '>=8'}
@@ -455,11 +597,19 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
+ /assertion-error/1.1.0:
+ resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
+ dev: true
+
/astral-regex/2.0.0:
resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
engines: {node: '>=8'}
dev: true
+ /asynckit/0.4.0:
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+ dev: true
+
/autoprefixer/10.4.13_postcss@8.4.23:
resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==}
engines: {node: ^10 || ^12 || >=14}
@@ -476,6 +626,11 @@ packages:
postcss-value-parser: 4.2.0
dev: true
+ /available-typed-arrays/1.0.5:
+ resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
/balanced-match/1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
dev: true
@@ -484,6 +639,10 @@ packages:
resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==}
dev: true
+ /blueimp-md5/2.19.0:
+ resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==}
+ dev: true
+
/brace-expansion/1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
dependencies:
@@ -509,6 +668,18 @@ packages:
update-browserslist-db: 1.0.10_browserslist@4.21.5
dev: true
+ /cac/6.7.14:
+ resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /call-bind/1.0.2:
+ resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
+ dependencies:
+ function-bind: 1.1.1
+ get-intrinsic: 1.2.0
+ dev: true
+
/callsites/3.1.0:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
@@ -532,6 +703,19 @@ packages:
resolution: {integrity: sha512-lQ1VlUUq5q9ro9X+5gOEyH7i3vm+AYVT1WDCVB69XOZ17KZRhnZ9J0Sqz7wTHQaLBJccNCHq8/Ww5LlOIZbB0w==}
dev: true
+ /chai/4.3.7:
+ resolution: {integrity: sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==}
+ engines: {node: '>=4'}
+ dependencies:
+ assertion-error: 1.1.0
+ check-error: 1.0.2
+ deep-eql: 4.1.3
+ get-func-name: 2.0.0
+ loupe: 2.3.6
+ pathval: 1.1.1
+ type-detect: 4.0.8
+ dev: true
+
/chalk/2.4.2:
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
engines: {node: '>=4'}
@@ -549,6 +733,10 @@ packages:
supports-color: 7.2.0
dev: true
+ /check-error/1.0.2:
+ resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==}
+ dev: true
+
/cm-show-invisibles/3.1.0:
resolution: {integrity: sha512-dfWd4QmuSMoSgONkCv4+REfPrxp3R3OE8jnxR3u2IjkLPolHArGOhMetBLo6gTeiL8tA4ff5v+VBZ1u1AZx+4A==}
dev: true
@@ -582,10 +770,31 @@ packages:
resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==}
dev: true
+ /combined-stream/1.0.8:
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+ engines: {node: '>= 0.8'}
+ dependencies:
+ delayed-stream: 1.0.0
+ dev: true
+
/concat-map/0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
dev: true
+ /concordance/5.0.4:
+ resolution: {integrity: sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==}
+ engines: {node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14'}
+ dependencies:
+ date-time: 3.1.0
+ esutils: 2.0.3
+ fast-diff: 1.2.0
+ js-string-escape: 1.0.1
+ lodash: 4.17.21
+ md5-hex: 3.0.1
+ semver: 7.3.8
+ well-known-symbols: 2.0.0
+ dev: true
+
/cosmiconfig/7.1.0:
resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==}
engines: {node: '>=10'}
@@ -617,6 +826,29 @@ packages:
hasBin: true
dev: true
+ /cssstyle/3.0.0:
+ resolution: {integrity: sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==}
+ engines: {node: '>=14'}
+ dependencies:
+ rrweb-cssom: 0.6.0
+ dev: true
+
+ /data-urls/4.0.0:
+ resolution: {integrity: sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==}
+ engines: {node: '>=14'}
+ dependencies:
+ abab: 2.0.6
+ whatwg-mimetype: 3.0.0
+ whatwg-url: 12.0.1
+ dev: true
+
+ /date-time/3.1.0:
+ resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==}
+ engines: {node: '>=6'}
+ dependencies:
+ time-zone: 1.0.0
+ dev: true
+
/debug/4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
@@ -642,6 +874,40 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
+ /decimal.js/10.4.3:
+ resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==}
+ dev: true
+
+ /deep-eql/4.1.3:
+ resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
+ engines: {node: '>=6'}
+ dependencies:
+ type-detect: 4.0.8
+ dev: true
+
+ /deep-equal/2.2.1:
+ resolution: {integrity: sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ==}
+ dependencies:
+ array-buffer-byte-length: 1.0.0
+ call-bind: 1.0.2
+ es-get-iterator: 1.1.3
+ get-intrinsic: 1.2.0
+ is-arguments: 1.1.1
+ is-array-buffer: 3.0.2
+ is-date-object: 1.0.5
+ is-regex: 1.1.4
+ is-shared-array-buffer: 1.0.2
+ isarray: 2.0.5
+ object-is: 1.1.5
+ object-keys: 1.1.1
+ object.assign: 4.1.4
+ regexp.prototype.flags: 1.5.0
+ side-channel: 1.0.4
+ which-boxed-primitive: 1.0.2
+ which-collection: 1.0.1
+ which-typed-array: 1.1.9
+ dev: true
+
/deep-is/0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
dev: true
@@ -651,6 +917,19 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
+ /define-properties/1.2.0:
+ resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-property-descriptors: 1.0.0
+ object-keys: 1.1.1
+ dev: true
+
+ /delayed-stream/1.0.0:
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+ engines: {node: '>=0.4.0'}
+ dev: true
+
/dir-glob/3.0.1:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'}
@@ -665,6 +944,10 @@ packages:
esutils: 2.0.3
dev: true
+ /dom-accessibility-api/0.5.16:
+ resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==}
+ dev: true
+
/dom-serializer/2.0.0:
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
dependencies:
@@ -677,6 +960,13 @@ packages:
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
dev: true
+ /domexception/4.0.0:
+ resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==}
+ engines: {node: '>=12'}
+ dependencies:
+ webidl-conversions: 7.0.0
+ dev: true
+
/domhandler/5.0.3:
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
engines: {node: '>= 4'}
@@ -711,6 +1001,20 @@ packages:
is-arrayish: 0.2.1
dev: true
+ /es-get-iterator/1.1.3:
+ resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.0
+ has-symbols: 1.0.3
+ is-arguments: 1.1.1
+ is-map: 2.0.2
+ is-set: 2.0.2
+ is-string: 1.0.7
+ isarray: 2.0.5
+ stop-iteration-iterator: 1.0.0
+ dev: true
+
/esbuild/0.16.17:
resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==}
engines: {node: '>=12'}
@@ -756,6 +1060,19 @@ packages:
engines: {node: '>=10'}
dev: true
+ /escodegen/2.0.0:
+ resolution: {integrity: sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==}
+ engines: {node: '>=6.0'}
+ hasBin: true
+ dependencies:
+ esprima: 4.0.1
+ estraverse: 5.3.0
+ esutils: 2.0.3
+ optionator: 0.8.3
+ optionalDependencies:
+ source-map: 0.6.1
+ dev: true
+
/eslint-config-prettier/8.8.0_eslint@8.35.0:
resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==}
hasBin: true
@@ -894,6 +1211,12 @@ packages:
eslint-visitor-keys: 3.3.0
dev: true
+ /esprima/4.0.1:
+ resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
+ engines: {node: '>=4'}
+ hasBin: true
+ dev: true
+
/esquery/1.4.2:
resolution: {integrity: sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==}
engines: {node: '>=0.10'}
@@ -998,6 +1321,21 @@ packages:
resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
dev: true
+ /for-each/0.3.3:
+ resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
+ dependencies:
+ is-callable: 1.2.7
+ dev: true
+
+ /form-data/4.0.0:
+ resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
+ engines: {node: '>= 6'}
+ dependencies:
+ asynckit: 0.4.0
+ combined-stream: 1.0.8
+ mime-types: 2.1.35
+ dev: true
+
/fraction.js/4.2.0:
resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
dev: true
@@ -1018,6 +1356,22 @@ packages:
resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
dev: true
+ /functions-have-names/1.2.3:
+ resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
+ dev: true
+
+ /get-func-name/2.0.0:
+ resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==}
+ dev: true
+
+ /get-intrinsic/1.2.0:
+ resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==}
+ dependencies:
+ function-bind: 1.1.1
+ has: 1.0.3
+ has-symbols: 1.0.3
+ dev: true
+
/glob-parent/5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@@ -1082,6 +1436,12 @@ packages:
resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==}
dev: true
+ /gopd/1.0.1:
+ resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
+ dependencies:
+ get-intrinsic: 1.2.0
+ dev: true
+
/grapheme-splitter/1.0.4:
resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
dev: true
@@ -1091,6 +1451,10 @@ packages:
engines: {node: '>=6'}
dev: true
+ /has-bigints/1.0.2:
+ resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
+ dev: true
+
/has-flag/3.0.0:
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
engines: {node: '>=4'}
@@ -1101,6 +1465,24 @@ packages:
engines: {node: '>=8'}
dev: true
+ /has-property-descriptors/1.0.0:
+ resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==}
+ dependencies:
+ get-intrinsic: 1.2.0
+ dev: true
+
+ /has-symbols/1.0.3:
+ resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /has-tostringtag/1.0.0:
+ resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-symbols: 1.0.3
+ dev: true
+
/has/1.0.3:
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
engines: {node: '>= 0.4.0'}
@@ -1119,6 +1501,13 @@ packages:
lru-cache: 6.0.0
dev: true
+ /html-encoding-sniffer/3.0.0:
+ resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==}
+ engines: {node: '>=12'}
+ dependencies:
+ whatwg-encoding: 2.0.0
+ dev: true
+
/html-tags/3.2.0:
resolution: {integrity: sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==}
engines: {node: '>=8'}
@@ -1133,6 +1522,34 @@ packages:
entities: 4.4.0
dev: true
+ /http-proxy-agent/5.0.0:
+ resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==}
+ engines: {node: '>= 6'}
+ dependencies:
+ '@tootallnate/once': 2.0.0
+ agent-base: 6.0.2
+ debug: 4.3.4
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /https-proxy-agent/5.0.1:
+ resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
+ engines: {node: '>= 6'}
+ dependencies:
+ agent-base: 6.0.2
+ debug: 4.3.4
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /iconv-lite/0.6.3:
+ resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ safer-buffer: 2.1.2
+ dev: true
+
/ignore/5.2.4:
resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
engines: {node: '>= 4'}
@@ -1176,16 +1593,67 @@ packages:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
dev: true
+ /internal-slot/1.0.5:
+ resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ get-intrinsic: 1.2.0
+ has: 1.0.3
+ side-channel: 1.0.4
+ dev: true
+
+ /is-arguments/1.1.1:
+ resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /is-array-buffer/3.0.2:
+ resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.0
+ is-typed-array: 1.1.10
+ dev: true
+
/is-arrayish/0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
dev: true
+ /is-bigint/1.0.4:
+ resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
+ dependencies:
+ has-bigints: 1.0.2
+ dev: true
+
+ /is-boolean-object/1.1.2:
+ resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /is-callable/1.2.7:
+ resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
/is-core-module/2.11.0:
resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==}
dependencies:
has: 1.0.3
dev: true
+ /is-date-object/1.0.5:
+ resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.0
+ dev: true
+
/is-extglob/2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
@@ -1203,6 +1671,17 @@ packages:
is-extglob: 2.1.1
dev: true
+ /is-map/2.0.2:
+ resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==}
+ dev: true
+
+ /is-number-object/1.0.7:
+ resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.0
+ dev: true
+
/is-number/7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
@@ -1223,45 +1702,157 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
- /isexe/2.0.0:
- resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+ /is-potential-custom-element-name/1.0.1:
+ resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
dev: true
- /js-sdsl/4.3.0:
- resolution: {integrity: sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==}
+ /is-regex/1.1.4:
+ resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ has-tostringtag: 1.0.0
dev: true
- /js-tokens/4.0.0:
- resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+ /is-set/2.0.2:
+ resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==}
dev: true
- /js-tokens/8.0.1:
- resolution: {integrity: sha512-3AGrZT6tuMm1ZWWn9mLXh7XMfi2YtiLNPALCVxBCiUVq0LD1OQMxV/AdS/s7rLJU5o9i/jBZw/N4vXXL5dm29A==}
+ /is-shared-array-buffer/1.0.2:
+ resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==}
+ dependencies:
+ call-bind: 1.0.2
dev: true
- /js-yaml/4.1.0:
- resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
- hasBin: true
+ /is-string/1.0.7:
+ resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
+ engines: {node: '>= 0.4'}
dependencies:
- argparse: 2.0.1
+ has-tostringtag: 1.0.0
dev: true
- /json-parse-even-better-errors/2.3.1:
- resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
+ /is-symbol/1.0.4:
+ resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-symbols: 1.0.3
dev: true
- /json-schema-traverse/0.4.1:
- resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+ /is-typed-array/1.1.10:
+ resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ available-typed-arrays: 1.0.5
+ call-bind: 1.0.2
+ for-each: 0.3.3
+ gopd: 1.0.1
+ has-tostringtag: 1.0.0
dev: true
- /json-schema-traverse/1.0.0:
- resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+ /is-weakmap/2.0.1:
+ resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==}
+ dev: true
+
+ /is-weakset/2.0.2:
+ resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.0
+ dev: true
+
+ /isarray/2.0.5:
+ resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
+ dev: true
+
+ /isexe/2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+ dev: true
+
+ /js-sdsl/4.3.0:
+ resolution: {integrity: sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==}
+ dev: true
+
+ /js-string-escape/1.0.1:
+ resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==}
+ engines: {node: '>= 0.8'}
+ dev: true
+
+ /js-tokens/4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+ dev: true
+
+ /js-tokens/8.0.1:
+ resolution: {integrity: sha512-3AGrZT6tuMm1ZWWn9mLXh7XMfi2YtiLNPALCVxBCiUVq0LD1OQMxV/AdS/s7rLJU5o9i/jBZw/N4vXXL5dm29A==}
+ dev: true
+
+ /js-yaml/4.1.0:
+ resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
+ hasBin: true
+ dependencies:
+ argparse: 2.0.1
+ dev: true
+
+ /jsdom/21.1.2:
+ resolution: {integrity: sha512-sCpFmK2jv+1sjff4u7fzft+pUh2KSUbUrEHYHyfSIbGTIcmnjyp83qg6qLwdJ/I3LpTXx33ACxeRL7Lsyc6lGQ==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ canvas: ^2.5.0
+ peerDependenciesMeta:
+ canvas:
+ optional: true
+ dependencies:
+ abab: 2.0.6
+ acorn: 8.8.2
+ acorn-globals: 7.0.1
+ cssstyle: 3.0.0
+ data-urls: 4.0.0
+ decimal.js: 10.4.3
+ domexception: 4.0.0
+ escodegen: 2.0.0
+ form-data: 4.0.0
+ html-encoding-sniffer: 3.0.0
+ http-proxy-agent: 5.0.0
+ https-proxy-agent: 5.0.1
+ is-potential-custom-element-name: 1.0.1
+ nwsapi: 2.2.4
+ parse5: 7.1.2
+ rrweb-cssom: 0.6.0
+ saxes: 6.0.0
+ symbol-tree: 3.2.4
+ tough-cookie: 4.1.2
+ w3c-xmlserializer: 4.0.0
+ webidl-conversions: 7.0.0
+ whatwg-encoding: 2.0.0
+ whatwg-mimetype: 3.0.0
+ whatwg-url: 12.0.1
+ ws: 8.13.0
+ xml-name-validator: 4.0.0
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+ dev: true
+
+ /json-parse-even-better-errors/2.3.1:
+ resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
+ dev: true
+
+ /json-schema-traverse/0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+ dev: true
+
+ /json-schema-traverse/1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
dev: true
/json-stable-stringify-without-jsonify/1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
dev: true
+ /jsonc-parser/3.2.0:
+ resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==}
+ dev: true
+
/kind-of/6.0.3:
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
engines: {node: '>=0.10.0'}
@@ -1280,6 +1871,14 @@ packages:
resolution: {integrity: sha512-uMCj6+hZYDoffuvAJjFAPz56E9uoowFHmTkqRtRq5WyC5Q6Cu/fTZKNQpX/RbzChBYLLl3lo8CjFZBAZXq9qFg==}
dev: true
+ /levn/0.3.0:
+ resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ prelude-ls: 1.1.2
+ type-check: 0.3.2
+ dev: true
+
/levn/0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
@@ -1297,6 +1896,11 @@ packages:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
dev: true
+ /local-pkg/0.4.3:
+ resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==}
+ engines: {node: '>=14'}
+ dev: true
+
/locate-path/5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'}
@@ -1319,6 +1923,16 @@ packages:
resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==}
dev: true
+ /lodash/4.17.21:
+ resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+ dev: true
+
+ /loupe/2.3.6:
+ resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==}
+ dependencies:
+ get-func-name: 2.0.0
+ dev: true
+
/lru-cache/6.0.0:
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
engines: {node: '>=10'}
@@ -1326,6 +1940,11 @@ packages:
yallist: 4.0.0
dev: true
+ /lz-string/1.5.0:
+ resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
+ hasBin: true
+ dev: true
+
/magic-string/0.29.0:
resolution: {integrity: sha512-WcfidHrDjMY+eLjlU+8OvwREqHwpgCeKVBUpQ3OhYYuvfaYCUgcbuBzappNzZvg/v8onU3oQj+BYpkOJe9Iw4Q==}
engines: {node: '>=12'}
@@ -1333,6 +1952,13 @@ packages:
'@jridgewell/sourcemap-codec': 1.4.14
dev: true
+ /magic-string/0.30.0:
+ resolution: {integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==}
+ engines: {node: '>=12'}
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.4.14
+ dev: true
+
/map-obj/1.0.1:
resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==}
engines: {node: '>=0.10.0'}
@@ -1347,6 +1973,13 @@ packages:
resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==}
dev: true
+ /md5-hex/3.0.1:
+ resolution: {integrity: sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==}
+ engines: {node: '>=8'}
+ dependencies:
+ blueimp-md5: 2.19.0
+ dev: true
+
/meow/9.0.0:
resolution: {integrity: sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==}
engines: {node: '>=10'}
@@ -1378,6 +2011,18 @@ packages:
picomatch: 2.3.1
dev: true
+ /mime-db/1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+ dev: true
+
+ /mime-types/2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+ dependencies:
+ mime-db: 1.52.0
+ dev: true
+
/min-indent/1.0.1:
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
engines: {node: '>=4'}
@@ -1398,6 +2043,15 @@ packages:
kind-of: 6.0.3
dev: true
+ /mlly/1.2.0:
+ resolution: {integrity: sha512-+c7A3CV0KGdKcylsI6khWyts/CYrGTrRVo4R/I7u/cUsy0Conxa6LUhiEzVKIw14lc2L5aiO4+SeVe4TeGRKww==}
+ dependencies:
+ acorn: 8.8.2
+ pathe: 1.1.0
+ pkg-types: 1.0.2
+ ufo: 1.1.1
+ dev: true
+
/ms/2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
dev: true
@@ -1445,12 +2099,55 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
+ /nwsapi/2.2.4:
+ resolution: {integrity: sha512-NHj4rzRo0tQdijE9ZqAx6kYDcoRwYwSYzCA8MY3JzfxlrvEU0jhnhJT9BhqhJs7I/dKcrDm6TyulaRqZPIhN5g==}
+ dev: true
+
+ /object-inspect/1.12.3:
+ resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==}
+ dev: true
+
+ /object-is/1.1.5:
+ resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ dev: true
+
+ /object-keys/1.1.1:
+ resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /object.assign/4.1.4:
+ resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ has-symbols: 1.0.3
+ object-keys: 1.1.1
+ dev: true
+
/once/1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
dependencies:
wrappy: 1.0.2
dev: true
+ /optionator/0.8.3:
+ resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ deep-is: 0.1.4
+ fast-levenshtein: 2.0.6
+ levn: 0.3.0
+ prelude-ls: 1.1.2
+ type-check: 0.3.2
+ word-wrap: 1.2.3
+ dev: true
+
/optionator/0.9.1:
resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==}
engines: {node: '>= 0.8.0'}
@@ -1477,6 +2174,13 @@ packages:
yocto-queue: 0.1.0
dev: true
+ /p-limit/4.0.0:
+ resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ dependencies:
+ yocto-queue: 1.0.0
+ dev: true
+
/p-locate/4.1.0:
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
engines: {node: '>=8'}
@@ -1513,6 +2217,12 @@ packages:
lines-and-columns: 1.2.4
dev: true
+ /parse5/7.1.2:
+ resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==}
+ dependencies:
+ entities: 4.4.0
+ dev: true
+
/path-exists/4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
@@ -1537,6 +2247,14 @@ packages:
engines: {node: '>=8'}
dev: true
+ /pathe/1.1.0:
+ resolution: {integrity: sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w==}
+ dev: true
+
+ /pathval/1.1.1:
+ resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==}
+ dev: true
+
/picocolors/1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
dev: true
@@ -1546,6 +2264,14 @@ packages:
engines: {node: '>=8.6'}
dev: true
+ /pkg-types/1.0.2:
+ resolution: {integrity: sha512-hM58GKXOcj8WTqUXnsQyJYXdeAPbythQgEF3nTcEo+nkD49chjQ9IKm/QJy9xf6JakXptz86h7ecP2024rrLaQ==}
+ dependencies:
+ jsonc-parser: 3.2.0
+ mlly: 1.2.0
+ pathe: 1.1.0
+ dev: true
+
/postcss-html/1.5.0:
resolution: {integrity: sha512-kCMRWJRHKicpA166kc2lAVUGxDZL324bkj/pVOb6RhjB0Z5Krl7mN0AsVkBhVIRZZirY0lyQXG38HCVaoKVNoA==}
engines: {node: ^12 || >=14}
@@ -1619,6 +2345,11 @@ packages:
source-map-js: 1.0.2
dev: true
+ /prelude-ls/1.1.2:
+ resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==}
+ engines: {node: '>= 0.8.0'}
+ dev: true
+
/prelude-ls/1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
@@ -1647,11 +2378,28 @@ packages:
hasBin: true
dev: true
+ /pretty-format/27.5.1:
+ resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==}
+ engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+ dependencies:
+ ansi-regex: 5.0.1
+ ansi-styles: 5.2.0
+ react-is: 17.0.2
+ dev: true
+
+ /psl/1.9.0:
+ resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==}
+ dev: true
+
/punycode/2.3.0:
resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
engines: {node: '>=6'}
dev: true
+ /querystringify/2.2.0:
+ resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
+ dev: true
+
/queue-microtask/1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
dev: true
@@ -1661,6 +2409,10 @@ packages:
engines: {node: '>=8'}
dev: true
+ /react-is/17.0.2:
+ resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
+ dev: true
+
/read-pkg-up/7.0.1:
resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==}
engines: {node: '>=8'}
@@ -1688,6 +2440,19 @@ packages:
strip-indent: 3.0.0
dev: true
+ /regenerator-runtime/0.13.11:
+ resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
+ dev: true
+
+ /regexp.prototype.flags/1.5.0:
+ resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ functions-have-names: 1.2.3
+ dev: true
+
/regexpp/3.2.0:
resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==}
engines: {node: '>=8'}
@@ -1698,6 +2463,10 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
+ /requires-port/1.0.0:
+ resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
+ dev: true
+
/resolve-from/4.0.0:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
@@ -1737,12 +2506,27 @@ packages:
fsevents: 2.3.2
dev: true
+ /rrweb-cssom/0.6.0:
+ resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==}
+ dev: true
+
/run-parallel/1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
dependencies:
queue-microtask: 1.2.3
dev: true
+ /safer-buffer/2.1.2:
+ resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+ dev: true
+
+ /saxes/6.0.0:
+ resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
+ engines: {node: '>=v12.22.7'}
+ dependencies:
+ xmlchars: 2.2.0
+ dev: true
+
/semver/5.7.1:
resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==}
hasBin: true
@@ -1768,6 +2552,18 @@ packages:
engines: {node: '>=8'}
dev: true
+ /side-channel/1.0.4:
+ resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.0
+ object-inspect: 1.12.3
+ dev: true
+
+ /siginfo/2.0.0:
+ resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+ dev: true
+
/signal-exit/3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
dev: true
@@ -1791,6 +2587,11 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
+ /source-map/0.6.1:
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
/spdx-correct/3.1.1:
resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==}
dependencies:
@@ -1813,6 +2614,21 @@ packages:
resolution: {integrity: sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==}
dev: true
+ /stackback/0.0.2:
+ resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+ dev: true
+
+ /std-env/3.3.2:
+ resolution: {integrity: sha512-uUZI65yrV2Qva5gqE0+A7uVAvO40iPo6jGhs7s8keRfHCmtg+uB2X6EiLGCI9IgL1J17xGhvoOqSz79lzICPTA==}
+ dev: true
+
+ /stop-iteration-iterator/1.0.0:
+ resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ internal-slot: 1.0.5
+ dev: true
+
/string-width/4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
@@ -1841,6 +2657,12 @@ packages:
engines: {node: '>=8'}
dev: true
+ /strip-literal/1.0.1:
+ resolution: {integrity: sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==}
+ dependencies:
+ acorn: 8.8.2
+ dev: true
+
/style-search/0.1.0:
resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==}
dev: true
@@ -2012,6 +2834,10 @@ packages:
resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==}
dev: true
+ /symbol-tree/3.2.4:
+ resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
+ dev: true
+
/table/6.8.1:
resolution: {integrity: sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==}
engines: {node: '>=10.0.0'}
@@ -2027,6 +2853,25 @@ packages:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
dev: true
+ /time-zone/1.0.0:
+ resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /tinybench/2.5.0:
+ resolution: {integrity: sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==}
+ dev: true
+
+ /tinypool/0.4.0:
+ resolution: {integrity: sha512-2ksntHOKf893wSAH4z/+JbPpi92esw8Gn9N2deXX+B0EO92hexAVI9GIZZPx7P5aYo5KULfeOSt3kMOmSOy6uA==}
+ engines: {node: '>=14.0.0'}
+ dev: true
+
+ /tinyspy/2.1.0:
+ resolution: {integrity: sha512-7eORpyqImoOvkQJCSkL0d0mB4NHHIFAy4b1u8PHdDa7SjGS2njzl6/lyGoZLm+eyYEtlUmFGE0rFj66SWxZgQQ==}
+ engines: {node: '>=14.0.0'}
+ dev: true
+
/to-regex-range/5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
@@ -2034,11 +2879,35 @@ packages:
is-number: 7.0.0
dev: true
+ /tough-cookie/4.1.2:
+ resolution: {integrity: sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==}
+ engines: {node: '>=6'}
+ dependencies:
+ psl: 1.9.0
+ punycode: 2.3.0
+ universalify: 0.2.0
+ url-parse: 1.5.10
+ dev: true
+
+ /tr46/4.1.1:
+ resolution: {integrity: sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==}
+ engines: {node: '>=14'}
+ dependencies:
+ punycode: 2.3.0
+ dev: true
+
/trim-newlines/3.0.1:
resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==}
engines: {node: '>=8'}
dev: true
+ /type-check/0.3.2:
+ resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ prelude-ls: 1.1.2
+ dev: true
+
/type-check/0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}
@@ -2046,6 +2915,11 @@ packages:
prelude-ls: 1.2.1
dev: true
+ /type-detect/4.0.8:
+ resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==}
+ engines: {node: '>=4'}
+ dev: true
+
/type-fest/0.18.1:
resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==}
engines: {node: '>=10'}
@@ -2066,6 +2940,15 @@ packages:
engines: {node: '>=8'}
dev: true
+ /ufo/1.1.1:
+ resolution: {integrity: sha512-MvlCc4GHrmZdAllBc0iUDowff36Q9Ndw/UzqmEKyrfSzokTd9ZCy1i+IIk5hrYKkjoYVQyNbrw7/F8XJ2rEwTg==}
+ dev: true
+
+ /universalify/0.2.0:
+ resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==}
+ engines: {node: '>= 4.0.0'}
+ dev: true
+
/update-browserslist-db/1.0.10_browserslist@4.21.5:
resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==}
hasBin: true
@@ -2083,6 +2966,13 @@ packages:
punycode: 2.3.0
dev: true
+ /url-parse/1.5.10:
+ resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
+ dependencies:
+ querystringify: 2.2.0
+ requires-port: 1.0.0
+ dev: true
+
/util-deprecate/1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
dev: true
@@ -2098,6 +2988,27 @@ packages:
spdx-expression-parse: 3.0.1
dev: true
+ /vite-node/0.30.1_@types+node@18.16.3:
+ resolution: {integrity: sha512-vTikpU/J7e6LU/8iM3dzBo8ZhEiKZEKRznEMm+mJh95XhWaPrJQraT/QsT2NWmuEf+zgAoMe64PKT7hfZ1Njmg==}
+ engines: {node: '>=v14.18.0'}
+ hasBin: true
+ dependencies:
+ cac: 6.7.14
+ debug: 4.3.4
+ mlly: 1.2.0
+ pathe: 1.1.0
+ picocolors: 1.0.0
+ vite: 4.1.4_@types+node@18.16.3
+ transitivePeerDependencies:
+ - '@types/node'
+ - less
+ - sass
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+ dev: true
+
/vite/4.1.4:
resolution: {integrity: sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==}
engines: {node: ^14.18.0 || >=16.0.0}
@@ -2131,6 +3042,40 @@ packages:
fsevents: 2.3.2
dev: true
+ /vite/4.1.4_@types+node@18.16.3:
+ resolution: {integrity: sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': '>= 14'
+ less: '*'
+ sass: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.4.0
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ less:
+ optional: true
+ sass:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ dependencies:
+ '@types/node': 18.16.3
+ esbuild: 0.16.17
+ postcss: 8.4.23
+ resolve: 1.22.1
+ rollup: 3.17.3
+ optionalDependencies:
+ fsevents: 2.3.2
+ dev: true
+
/vitefu/0.2.4_vite@4.1.4:
resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==}
peerDependencies:
@@ -2142,6 +3087,141 @@ packages:
vite: 4.1.4
dev: true
+ /vitest/0.30.1_jsdom@21.1.2:
+ resolution: {integrity: sha512-y35WTrSTlTxfMLttgQk4rHcaDkbHQwDP++SNwPb+7H8yb13Q3cu2EixrtHzF27iZ8v0XCciSsLg00RkPAzB/aA==}
+ engines: {node: '>=v14.18.0'}
+ hasBin: true
+ peerDependencies:
+ '@edge-runtime/vm': '*'
+ '@vitest/browser': '*'
+ '@vitest/ui': '*'
+ happy-dom: '*'
+ jsdom: '*'
+ playwright: '*'
+ safaridriver: '*'
+ webdriverio: '*'
+ peerDependenciesMeta:
+ '@edge-runtime/vm':
+ optional: true
+ '@vitest/browser':
+ optional: true
+ '@vitest/ui':
+ optional: true
+ happy-dom:
+ optional: true
+ jsdom:
+ optional: true
+ playwright:
+ optional: true
+ safaridriver:
+ optional: true
+ webdriverio:
+ optional: true
+ dependencies:
+ '@types/chai': 4.3.5
+ '@types/chai-subset': 1.3.3
+ '@types/node': 18.16.3
+ '@vitest/expect': 0.30.1
+ '@vitest/runner': 0.30.1
+ '@vitest/snapshot': 0.30.1
+ '@vitest/spy': 0.30.1
+ '@vitest/utils': 0.30.1
+ acorn: 8.8.2
+ acorn-walk: 8.2.0
+ cac: 6.7.14
+ chai: 4.3.7
+ concordance: 5.0.4
+ debug: 4.3.4
+ jsdom: 21.1.2
+ local-pkg: 0.4.3
+ magic-string: 0.30.0
+ pathe: 1.1.0
+ picocolors: 1.0.0
+ source-map: 0.6.1
+ std-env: 3.3.2
+ strip-literal: 1.0.1
+ tinybench: 2.5.0
+ tinypool: 0.4.0
+ vite: 4.1.4_@types+node@18.16.3
+ vite-node: 0.30.1_@types+node@18.16.3
+ why-is-node-running: 2.2.2
+ transitivePeerDependencies:
+ - less
+ - sass
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+ dev: true
+
+ /w3c-xmlserializer/4.0.0:
+ resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==}
+ engines: {node: '>=14'}
+ dependencies:
+ xml-name-validator: 4.0.0
+ dev: true
+
+ /webidl-conversions/7.0.0:
+ resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==}
+ engines: {node: '>=12'}
+ dev: true
+
+ /well-known-symbols/2.0.0:
+ resolution: {integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /whatwg-encoding/2.0.0:
+ resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==}
+ engines: {node: '>=12'}
+ dependencies:
+ iconv-lite: 0.6.3
+ dev: true
+
+ /whatwg-mimetype/3.0.0:
+ resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==}
+ engines: {node: '>=12'}
+ dev: true
+
+ /whatwg-url/12.0.1:
+ resolution: {integrity: sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==}
+ engines: {node: '>=14'}
+ dependencies:
+ tr46: 4.1.1
+ webidl-conversions: 7.0.0
+ dev: true
+
+ /which-boxed-primitive/1.0.2:
+ resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
+ dependencies:
+ is-bigint: 1.0.4
+ is-boolean-object: 1.1.2
+ is-number-object: 1.0.7
+ is-string: 1.0.7
+ is-symbol: 1.0.4
+ dev: true
+
+ /which-collection/1.0.1:
+ resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==}
+ dependencies:
+ is-map: 2.0.2
+ is-set: 2.0.2
+ is-weakmap: 2.0.1
+ is-weakset: 2.0.2
+ dev: true
+
+ /which-typed-array/1.1.9:
+ resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ available-typed-arrays: 1.0.5
+ call-bind: 1.0.2
+ for-each: 0.3.3
+ gopd: 1.0.1
+ has-tostringtag: 1.0.0
+ is-typed-array: 1.1.10
+ dev: true
+
/which/1.3.1:
resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
hasBin: true
@@ -2157,6 +3237,15 @@ packages:
isexe: 2.0.0
dev: true
+ /why-is-node-running/2.2.2:
+ resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==}
+ engines: {node: '>=8'}
+ hasBin: true
+ dependencies:
+ siginfo: 2.0.0
+ stackback: 0.0.2
+ dev: true
+
/word-wrap/1.2.3:
resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
engines: {node: '>=0.10.0'}
@@ -2174,6 +3263,28 @@ packages:
signal-exit: 3.0.7
dev: true
+ /ws/8.13.0:
+ resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==}
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: '>=5.0.2'
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+ dev: true
+
+ /xml-name-validator/4.0.0:
+ resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
+ engines: {node: '>=12'}
+ dev: true
+
+ /xmlchars/2.2.0:
+ resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
+ dev: true
+
/yallist/4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
dev: true
@@ -2192,3 +3303,8 @@ packages:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
dev: true
+
+ /yocto-queue/1.0.0:
+ resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==}
+ engines: {node: '>=12.20'}
+ dev: true
diff --git a/tests/page/App.test.js b/tests/page/App.test.js
new file mode 100644
index 00000000..82120143
--- /dev/null
+++ b/tests/page/App.test.js
@@ -0,0 +1,17 @@
+import {afterEach, beforeAll, describe, expect, test} from "vitest";
+import {cleanup, render} from "@testing-library/svelte";
+import {browser} from "../../src/shared/dev.js";
+import App from "../../src/page/App.svelte";
+
+describe("App", () => {
+ beforeAll(() => {
+ global.browser = browser;
+ });
+
+ afterEach(() => cleanup());
+
+ test("mounts", () => {
+ const {container} = render(App);
+ expect(container).toBeTruthy();
+ });
+});
diff --git a/vite.config.js b/vite.config.js
index fe7e6672..6a1bee3f 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -184,5 +184,10 @@ export default defineConfig({
processIndexFiles()
],
publicDir: false,
- root: root
+ root: root,
+ test: {
+ dir: "tests",
+ environment: "jsdom",
+ root: "./"
+ }
});
From cd64127e9e49725c046d94a4da230c310efce208 Mon Sep 17 00:00:00 2001
From: quoid <7660254+quoid@users.noreply.github.com>
Date: Mon, 1 May 2023 16:36:47 -0400
Subject: [PATCH 05/13] chore: set up svelte-i18n
---
package.json | 1 +
pnpm-lock.yaml | 203 +++++++++++++++++++++++++++++++++++++++++++
src/locales/en.json | 4 +
src/page/App.svelte | 2 +
src/popup/App.svelte | 2 +
src/shared/i18n.js | 8 ++
6 files changed, 220 insertions(+)
create mode 100644 src/locales/en.json
create mode 100644 src/shared/i18n.js
diff --git a/package.json b/package.json
index 168f32f2..d288de97 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,7 @@
"stylelint-order": "^6.0.3",
"stylelint-prettier": "^3.0.0",
"svelte": "^3.55.1",
+ "svelte-i18n": "^3.6.0",
"vite": "^4.1.4",
"vitest": "^0.30.1"
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 689d63d5..5a8b699a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -23,6 +23,7 @@ specifiers:
stylelint-order: ^6.0.3
stylelint-prettier: ^3.0.0
svelte: ^3.55.1
+ svelte-i18n: ^3.6.0
vite: ^4.1.4
vitest: ^0.30.1
@@ -49,6 +50,7 @@ devDependencies:
stylelint-order: 6.0.3_stylelint@14.16.1
stylelint-prettier: 3.0.0_ijjwmmxqo5tkozh2kjbk6pd5e4
svelte: 3.55.1
+ svelte-i18n: 3.6.0_svelte@3.55.1
vite: 4.1.4
vitest: 0.30.1_jsdom@21.1.2
@@ -323,6 +325,40 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
+ /@formatjs/ecma402-abstract/1.11.4:
+ resolution: {integrity: sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==}
+ dependencies:
+ '@formatjs/intl-localematcher': 0.2.25
+ tslib: 2.5.0
+ dev: true
+
+ /@formatjs/fast-memoize/1.2.1:
+ resolution: {integrity: sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==}
+ dependencies:
+ tslib: 2.5.0
+ dev: true
+
+ /@formatjs/icu-messageformat-parser/2.1.0:
+ resolution: {integrity: sha512-Qxv/lmCN6hKpBSss2uQ8IROVnta2r9jd3ymUEIjm2UyIkUCHVcbUVRGL/KS/wv7876edvsPe+hjHVJ4z8YuVaw==}
+ dependencies:
+ '@formatjs/ecma402-abstract': 1.11.4
+ '@formatjs/icu-skeleton-parser': 1.3.6
+ tslib: 2.5.0
+ dev: true
+
+ /@formatjs/icu-skeleton-parser/1.3.6:
+ resolution: {integrity: sha512-I96mOxvml/YLrwU2Txnd4klA7V8fRhb6JG/4hm3VMNmeJo1F03IpV2L3wWt7EweqNLES59SZ4d6hVOPCSf80Bg==}
+ dependencies:
+ '@formatjs/ecma402-abstract': 1.11.4
+ tslib: 2.5.0
+ dev: true
+
+ /@formatjs/intl-localematcher/0.2.25:
+ resolution: {integrity: sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==}
+ dependencies:
+ tslib: 2.5.0
+ dev: true
+
/@humanwhocodes/config-array/0.11.8:
resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==}
engines: {node: '>=10.10.0'}
@@ -737,6 +773,17 @@ packages:
resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==}
dev: true
+ /cli-color/2.0.3:
+ resolution: {integrity: sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==}
+ engines: {node: '>=0.10'}
+ dependencies:
+ d: 1.0.1
+ es5-ext: 0.10.62
+ es6-iterator: 2.0.3
+ memoizee: 0.4.15
+ timers-ext: 0.1.7
+ dev: true
+
/cm-show-invisibles/3.1.0:
resolution: {integrity: sha512-dfWd4QmuSMoSgONkCv4+REfPrxp3R3OE8jnxR3u2IjkLPolHArGOhMetBLo6gTeiL8tA4ff5v+VBZ1u1AZx+4A==}
dev: true
@@ -833,6 +880,13 @@ packages:
rrweb-cssom: 0.6.0
dev: true
+ /d/1.0.1:
+ resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==}
+ dependencies:
+ es5-ext: 0.10.62
+ type: 1.2.0
+ dev: true
+
/data-urls/4.0.0:
resolution: {integrity: sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==}
engines: {node: '>=14'}
@@ -1015,6 +1069,40 @@ packages:
stop-iteration-iterator: 1.0.0
dev: true
+ /es5-ext/0.10.62:
+ resolution: {integrity: sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==}
+ engines: {node: '>=0.10'}
+ requiresBuild: true
+ dependencies:
+ es6-iterator: 2.0.3
+ es6-symbol: 3.1.3
+ next-tick: 1.1.0
+ dev: true
+
+ /es6-iterator/2.0.3:
+ resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==}
+ dependencies:
+ d: 1.0.1
+ es5-ext: 0.10.62
+ es6-symbol: 3.1.3
+ dev: true
+
+ /es6-symbol/3.1.3:
+ resolution: {integrity: sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==}
+ dependencies:
+ d: 1.0.1
+ ext: 1.7.0
+ dev: true
+
+ /es6-weak-map/2.0.3:
+ resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==}
+ dependencies:
+ d: 1.0.1
+ es5-ext: 0.10.62
+ es6-iterator: 2.0.3
+ es6-symbol: 3.1.3
+ dev: true
+
/esbuild/0.16.17:
resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==}
engines: {node: '>=12'}
@@ -1236,11 +1324,28 @@ packages:
engines: {node: '>=4.0'}
dev: true
+ /estree-walker/2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+ dev: true
+
/esutils/2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
dev: true
+ /event-emitter/0.3.5:
+ resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==}
+ dependencies:
+ d: 1.0.1
+ es5-ext: 0.10.62
+ dev: true
+
+ /ext/1.7.0:
+ resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==}
+ dependencies:
+ type: 2.7.2
+ dev: true
+
/fast-deep-equal/3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
dev: true
@@ -1420,6 +1525,10 @@ packages:
type-fest: 0.20.2
dev: true
+ /globalyzer/0.1.0:
+ resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==}
+ dev: true
+
/globby/11.1.0:
resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
engines: {node: '>=10'}
@@ -1436,6 +1545,10 @@ packages:
resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==}
dev: true
+ /globrex/0.1.2:
+ resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==}
+ dev: true
+
/gopd/1.0.1:
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
dependencies:
@@ -1602,6 +1715,15 @@ packages:
side-channel: 1.0.4
dev: true
+ /intl-messageformat/9.13.0:
+ resolution: {integrity: sha512-7sGC7QnSQGa5LZP7bXLDhVDtQOeKGeBFGHF2Y8LVBwYZoQZCgWeKoPGTa5GMG8g/TzDgeXuYJQis7Ggiw2xTOw==}
+ dependencies:
+ '@formatjs/ecma402-abstract': 1.11.4
+ '@formatjs/fast-memoize': 1.2.1
+ '@formatjs/icu-messageformat-parser': 2.1.0
+ tslib: 2.5.0
+ dev: true
+
/is-arguments/1.1.1:
resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==}
engines: {node: '>= 0.4'}
@@ -1706,6 +1828,10 @@ packages:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
dev: true
+ /is-promise/2.2.2:
+ resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==}
+ dev: true
+
/is-regex/1.1.4:
resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
engines: {node: '>= 0.4'}
@@ -1940,6 +2066,12 @@ packages:
yallist: 4.0.0
dev: true
+ /lru-queue/0.1.0:
+ resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==}
+ dependencies:
+ es5-ext: 0.10.62
+ dev: true
+
/lz-string/1.5.0:
resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
hasBin: true
@@ -1980,6 +2112,19 @@ packages:
blueimp-md5: 2.19.0
dev: true
+ /memoizee/0.4.15:
+ resolution: {integrity: sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==}
+ dependencies:
+ d: 1.0.1
+ es5-ext: 0.10.62
+ es6-weak-map: 2.0.3
+ event-emitter: 0.3.5
+ is-promise: 2.2.2
+ lru-queue: 0.1.0
+ next-tick: 1.1.0
+ timers-ext: 0.1.7
+ dev: true
+
/meow/9.0.0:
resolution: {integrity: sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==}
engines: {node: '>=10'}
@@ -2052,6 +2197,11 @@ packages:
ufo: 1.1.1
dev: true
+ /mri/1.2.0:
+ resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
+ engines: {node: '>=4'}
+ dev: true
+
/ms/2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
dev: true
@@ -2066,6 +2216,10 @@ packages:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
dev: true
+ /next-tick/1.1.0:
+ resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==}
+ dev: true
+
/node-releases/2.0.10:
resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==}
dev: true
@@ -2516,6 +2670,13 @@ packages:
queue-microtask: 1.2.3
dev: true
+ /sade/1.8.1:
+ resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==}
+ engines: {node: '>=6'}
+ dependencies:
+ mri: 1.2.0
+ dev: true
+
/safer-buffer/2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
dev: true
@@ -2825,6 +2986,22 @@ packages:
svelte: 3.55.1
dev: true
+ /svelte-i18n/3.6.0_svelte@3.55.1:
+ resolution: {integrity: sha512-qvvcMqHVCXJ5pHoQR5uGzWAW5vS3qB9mBq+W6veLZ6jkrzZGOziR+wyOUJsc59BupMh+Ae30qjOndFrRU6v5jA==}
+ engines: {node: '>= 16'}
+ hasBin: true
+ peerDependencies:
+ svelte: ^3.25.1
+ dependencies:
+ cli-color: 2.0.3
+ deepmerge: 4.3.0
+ estree-walker: 2.0.2
+ intl-messageformat: 9.13.0
+ sade: 1.8.1
+ svelte: 3.55.1
+ tiny-glob: 0.2.9
+ dev: true
+
/svelte/3.55.1:
resolution: {integrity: sha512-S+87/P0Ve67HxKkEV23iCdAh/SX1xiSfjF1HOglno/YTbSTW7RniICMCofWGdJJbdjw3S+0PfFb1JtGfTXE0oQ==}
engines: {node: '>= 8'}
@@ -2858,6 +3035,20 @@ packages:
engines: {node: '>=4'}
dev: true
+ /timers-ext/0.1.7:
+ resolution: {integrity: sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==}
+ dependencies:
+ es5-ext: 0.10.62
+ next-tick: 1.1.0
+ dev: true
+
+ /tiny-glob/0.2.9:
+ resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==}
+ dependencies:
+ globalyzer: 0.1.0
+ globrex: 0.1.2
+ dev: true
+
/tinybench/2.5.0:
resolution: {integrity: sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==}
dev: true
@@ -2901,6 +3092,10 @@ packages:
engines: {node: '>=8'}
dev: true
+ /tslib/2.5.0:
+ resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==}
+ dev: true
+
/type-check/0.3.2:
resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==}
engines: {node: '>= 0.8.0'}
@@ -2940,6 +3135,14 @@ packages:
engines: {node: '>=8'}
dev: true
+ /type/1.2.0:
+ resolution: {integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==}
+ dev: true
+
+ /type/2.7.2:
+ resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==}
+ dev: true
+
/ufo/1.1.1:
resolution: {integrity: sha512-MvlCc4GHrmZdAllBc0iUDowff36Q9Ndw/UzqmEKyrfSzokTd9ZCy1i+IIk5hrYKkjoYVQyNbrw7/F8XJ2rEwTg==}
dev: true
diff --git a/src/locales/en.json b/src/locales/en.json
new file mode 100644
index 00000000..c8b41883
--- /dev/null
+++ b/src/locales/en.json
@@ -0,0 +1,4 @@
+{
+ "page": {},
+ "popup": {}
+}
diff --git a/src/page/App.svelte b/src/page/App.svelte
index 62e46a66..2542802f 100644
--- a/src/page/App.svelte
+++ b/src/page/App.svelte
@@ -4,6 +4,7 @@
import {
items, log, notifications, settings, state
} from "./store.js";
+ import {t, waitLocale} from "svelte-i18n";
import Sidebar from "./Components/Sidebar/Sidebar.svelte";
import Editor from "./Components/Editor/Editor.svelte";
import Settings from "./Components/Settings.svelte";
@@ -43,6 +44,7 @@
// }
onMount(async () => {
+ await waitLocale();
log.add("Requesting initialization data", "info", false);
const initData = await browser.runtime.sendNativeMessage({name: "PAGE_INIT_DATA"});
if (initData.error) return console.error(initData.error);
diff --git a/src/popup/App.svelte b/src/popup/App.svelte
index f12154c7..85c8706b 100644
--- a/src/popup/App.svelte
+++ b/src/popup/App.svelte
@@ -1,5 +1,6 @@