diff --git a/package-lock.json b/package-lock.json index 3132039396..b3276dc0a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "phoenix", - "version": "4.0.0-0", + "version": "4.0.2-0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "phoenix", - "version": "4.0.0-0", + "version": "4.0.2-0", "dependencies": { "@bugsnag/js": "^7.18.0", "@floating-ui/dom": "^0.5.4", @@ -22,6 +22,7 @@ "codemirror": "^5.65.16", "cross-env": "^7.0.3", "devicon": "^2.15.1", + "emmet": "^2.4.11", "file-saver": "^2.0.5", "idb-keyval": "^6.2.1", "jshint": "^2.13.5", @@ -41,7 +42,6 @@ "devDependencies": { "@commitlint/cli": "^16.0.2", "@commitlint/config-conventional": "^16.0.0", - "@google-cloud/translate": "^7.0.3", "@playwright/test": "^1.38.1", "del": "^6.0.0", "eslint": "^8.18.0", @@ -595,6 +595,27 @@ "node": ">=12" } }, + "node_modules/@emmetio/abbreviation": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.3.3.tgz", + "integrity": "sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==", + "dependencies": { + "@emmetio/scanner": "^1.0.4" + } + }, + "node_modules/@emmetio/css-abbreviation": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@emmetio/css-abbreviation/-/css-abbreviation-2.1.8.tgz", + "integrity": "sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==", + "dependencies": { + "@emmetio/scanner": "^1.0.4" + } + }, + "node_modules/@emmetio/scanner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@emmetio/scanner/-/scanner-1.0.4.tgz", + "integrity": "sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==" + }, "node_modules/@eslint/eslintrc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", @@ -655,232 +676,6 @@ "node": ">=6" } }, - "node_modules/@google-cloud/common": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-4.0.2.tgz", - "integrity": "sha512-LgUoPQq1CNzMAtqnIJLetj7hlzZUS+CG9mBuZthqek6+eGu3PsH2IuEbbtLSUgPZNgOgi/fWGWpbNPP7wgjF0A==", - "dev": true, - "dependencies": { - "@google-cloud/projectify": "^3.0.0", - "@google-cloud/promisify": "^3.0.0", - "arrify": "^2.0.1", - "duplexify": "^4.1.1", - "ent": "^2.2.0", - "extend": "^3.0.2", - "google-auth-library": "^8.0.2", - "retry-request": "^5.0.0", - "teeny-request": "^8.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@google-cloud/common/node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@google-cloud/common/node_modules/duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "node_modules/@google-cloud/projectify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-3.0.0.tgz", - "integrity": "sha512-HRkZsNmjScY6Li8/kb70wjGlDDyLkVk3KvoEo9uIoxSjYLJasGiCch9+PqRVDOCGUFvEIqyogl+BeqILL4OJHA==", - "dev": true, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@google-cloud/promisify": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-3.0.1.tgz", - "integrity": "sha512-z1CjRjtQyBOYL+5Qr9DdYIfrdLBe746jRTYfaYU6MeXkqp7UfYs/jX16lFFVzZ7PGEJvqZNqYUEtb1mvDww4pA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@google-cloud/translate": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@google-cloud/translate/-/translate-7.2.2.tgz", - "integrity": "sha512-IAJhPKotLH/OF/NzWml/byLDN+OILbs1P4k+7HNUJK618NsShFelRKzh3pRUUQA4DX0je3HaEZw9nR+5uJ6ZEg==", - "dev": true, - "dependencies": { - "@google-cloud/common": "^4.0.0", - "@google-cloud/promisify": "^3.0.0", - "arrify": "^2.0.0", - "extend": "^3.0.2", - "google-gax": "^3.5.8", - "is-html": "^2.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@google-cloud/translate/node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@grpc/grpc-js": { - "version": "1.8.22", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.22.tgz", - "integrity": "sha512-oAjDdN7fzbUi+4hZjKG96MR6KTEubAeMpQEb+77qy+3r0Ua5xTFuie6JOLr4ZZgl5g+W5/uRTS2M1V8mVAFPuA==", - "dev": true, - "dependencies": { - "@grpc/proto-loader": "^0.7.0", - "@types/node": ">=12.12.47" - }, - "engines": { - "node": "^8.13.0 || >=10.10.0" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.8.tgz", - "integrity": "sha512-GU12e2c8dmdXb7XUlOgYWZ2o2i+z9/VeACkxTA/zzAe2IjclC5PnVL0lpgjhrqfpDYHzM8B1TF6pqWegMYAzlA==", - "dev": true, - "dependencies": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^7.2.4", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@grpc/proto-loader/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@grpc/proto-loader/node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@grpc/proto-loader/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@grpc/proto-loader/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@grpc/proto-loader/node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/@grpc/proto-loader/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/@grpc/proto-loader/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@grpc/proto-loader/node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@grpc/proto-loader/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/@gulp-sourcemaps/identity-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz", @@ -1252,79 +1047,6 @@ "prettier": "^3.0.0" } }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "dev": true - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "dev": true - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "dev": true - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "dev": true - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dev": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "dev": true - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "dev": true - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "dev": true - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "dev": true - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "dev": true - }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -1349,28 +1071,12 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, - "node_modules/@types/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", - "dev": true, - "dependencies": { - "@types/minimatch": "^5.1.2", - "@types/node": "*" - } - }, "node_modules/@types/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", "dev": true }, - "node_modules/@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", - "dev": true - }, "node_modules/@types/markdown-it": { "version": "14.1.2", "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", @@ -1387,12 +1093,6 @@ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", "dev": true }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true - }, "node_modules/@types/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", @@ -1417,16 +1117,6 @@ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", "dev": true }, - "node_modules/@types/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==", - "dev": true, - "dependencies": { - "@types/glob": "*", - "@types/node": "*" - } - }, "node_modules/@uiw/file-icons": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@uiw/file-icons/-/file-icons-1.3.2.tgz", @@ -1441,18 +1131,6 @@ "node": ">=10.0.0" } }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, "node_modules/accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -1521,18 +1199,6 @@ "node": ">=0.4.0" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -2178,26 +1844,6 @@ "node": ">=0.10.0" } }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", @@ -2216,15 +1862,6 @@ "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", "dev": true }, - "node_modules/bignumber.js": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", - "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", @@ -2368,12 +2005,6 @@ "node": ">=0.4.0" } }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "dev": true - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -4392,15 +4023,6 @@ "object.defaults": "^1.1.0" } }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -4413,6 +4035,21 @@ "integrity": "sha512-c/uKWR1Z/W30Wy/sx3dkZoj4BijbXX85QKWu9jJfjho3LBAXNEGAEW3oWiGb+dotA6C6BzCTxL2/aLes7jlUeg==", "dev": true }, + "node_modules/emmet": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/emmet/-/emmet-2.4.11.tgz", + "integrity": "sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==", + "workspaces": [ + "./packages/scanner", + "./packages/abbreviation", + "./packages/css-abbreviation", + "./" + ], + "dependencies": { + "@emmetio/abbreviation": "^2.3.3", + "@emmetio/css-abbreviation": "^2.1.8" + } + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -4450,12 +4087,6 @@ "node": ">=0.6" } }, - "node_modules/ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", - "dev": true - }, "node_modules/entities": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", @@ -4532,129 +4163,37 @@ "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", "dev": true, "dependencies": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", - "dev": true, - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=4.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" } }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, "engines": { - "node": ">= 0.8.0" + "node": ">=6" } }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, "engines": { - "node": ">= 0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint": { @@ -4823,19 +4362,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/esquery": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", @@ -4912,15 +4438,6 @@ "through": "^2.3.8" } }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -5215,12 +4732,6 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, - "node_modules/fast-text-encoding": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz", - "integrity": "sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==", - "dev": true - }, "node_modules/fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -5735,54 +5246,6 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "node_modules/gaxios": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.0.1.tgz", - "integrity": "sha512-keK47BGKHyyOVQxgcUaSaFvr3ehZYAlvhvpHXy0YB2itzZef+GqZR8TBsfVRWghdwlKrYsn+8L8i3eblF7Oviw==", - "dev": true, - "dependencies": { - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.7" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/gaxios/node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/gcp-metadata": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.0.0.tgz", - "integrity": "sha512-gfwuX3yA3nNsHSWUL4KG90UulNiq922Ukj3wLTrcnX33BB7PwB1o0ubR8KVvXu9nJH+P5w1j2SQSNNqto+H0DA==", - "dev": true, - "dependencies": { - "gaxios": "^5.0.0", - "json-bigint": "^1.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", @@ -6427,143 +5890,11 @@ "node": ">= 0.10" } }, - "node_modules/google-auth-library": { - "version": "8.5.2", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-8.5.2.tgz", - "integrity": "sha512-FPfOSaI8n2TVXFHTP8/vAVFCXhyALj7w9/Rgefux3oeKZ/nQDNmfNTJ+lIKcoYT1cKkvMllp1Eood7Y5L+TP+A==", - "dev": true, - "dependencies": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^5.0.0", - "gcp-metadata": "^5.0.0", - "gtoken": "^6.1.0", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/google-auth-library/node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/google-auth-library/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/google-gax": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-3.6.1.tgz", - "integrity": "sha512-g/lcUjGcB6DSw2HxgEmCDOrI/CByOwqRvsuUvNalHUK2iPPPlmAIpbMbl62u0YufGMr8zgE3JL7th6dCb1Ry+w==", - "dev": true, - "dependencies": { - "@grpc/grpc-js": "~1.8.0", - "@grpc/proto-loader": "^0.7.0", - "@types/long": "^4.0.0", - "@types/rimraf": "^3.0.2", - "abort-controller": "^3.0.0", - "duplexify": "^4.0.0", - "fast-text-encoding": "^1.0.3", - "google-auth-library": "^8.0.2", - "is-stream-ended": "^0.1.4", - "node-fetch": "^2.6.1", - "object-hash": "^3.0.0", - "proto3-json-serializer": "^1.0.0", - "protobufjs": "7.2.4", - "protobufjs-cli": "1.1.1", - "retry-request": "^5.0.0" - }, - "bin": { - "compileProtos": "build/tools/compileProtos.js", - "minifyProtoJson": "build/tools/minify.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/google-gax/node_modules/duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "node_modules/google-gax/node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/google-p12-pem": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-4.0.1.tgz", - "integrity": "sha512-WPkN4yGtz05WZ5EhtlxNDWPhC4JIic6G8ePitwUWy4l+XPVYec+a0j0Ts47PDtW59y3RwAhUd9/h9ZZ63px6RQ==", - "dev": true, - "dependencies": { - "node-forge": "^1.3.1" - }, - "bin": { - "gp12-pem": "build/src/bin/gp12-pem.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/graceful-fs": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, - "node_modules/gtoken": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-6.1.2.tgz", - "integrity": "sha512-4ccGpzz7YAr7lxrT2neugmXQ3hP9ho2gcaityLVkiUecAiwiy60Ii8gRbZeOsXV19fYaRjgBSshs8kXw+NKCPQ==", - "dev": true, - "dependencies": { - "gaxios": "^5.0.1", - "google-p12-pem": "^4.0.0", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/gulp": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", @@ -7575,18 +6906,6 @@ "node": ">=12" } }, - "node_modules/html-tags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz", - "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/htmlparser2": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", @@ -7661,20 +6980,6 @@ "node": ">=8.0.0" } }, - "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/http-server": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.0.tgz", @@ -7702,19 +7007,6 @@ "node": ">=12" } }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -8043,18 +7335,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-html": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-html/-/is-html-2.0.0.tgz", - "integrity": "sha512-S+OpgB5i7wzIue/YSE5hg0e5ZYfG3hhpNh9KGl6ayJ38p7ED6wxQLd1TV91xHpcTvw90KMJ9EwN3F/iNflHBVg==", - "dev": true, - "dependencies": { - "html-tags": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-negated-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", @@ -8150,12 +7430,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-stream-ended": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", - "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", - "dev": true - }, "node_modules/is-svg": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", @@ -8492,15 +7766,6 @@ "node": ">=0.8.0" } }, - "node_modules/json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "dev": true, - "dependencies": { - "bignumber.js": "^9.0.0" - } - }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -8587,27 +7852,6 @@ "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", "dev": true }, - "node_modules/jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "dev": true, - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "dev": true, - "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -8983,12 +8227,6 @@ "lodash.keys": "~2.4.1" } }, - "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - }, "node_modules/loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -9700,15 +8938,6 @@ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", "dev": true }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "dev": true, - "engines": { - "node": ">= 6.13.0" - } - }, "node_modules/node.extend": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-1.1.8.tgz", @@ -9860,15 +9089,6 @@ "node": ">=0.10.0" } }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, "node_modules/object-inspect": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", @@ -10839,93 +10059,23 @@ "engines": { "node": ">=14" }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/proto3-json-serializer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-1.1.0.tgz", - "integrity": "sha512-SjXwUWe/vANGs/mJJTbw5++7U67nwsymg7qsoPtw6GiXqw3kUy8ByojrlEdVE2efxAdKreX8WkDafxvYW95ZQg==", - "dev": true, - "dependencies": { - "protobufjs": "^7.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/protobufjs": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.4.tgz", - "integrity": "sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/protobufjs-cli": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/protobufjs-cli/-/protobufjs-cli-1.1.1.tgz", - "integrity": "sha512-VPWMgIcRNyQwWUv8OLPyGQ/0lQY/QTQAVN5fh+XzfDwsVw1FZ2L3DM/bcBf8WPiRz2tNpaov9lPZfNcmNo6LXA==", + "node_modules/pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "escodegen": "^1.13.0", - "espree": "^9.0.0", - "estraverse": "^5.1.0", - "glob": "^8.0.0", - "jsdoc": "^4.0.0", - "minimist": "^1.2.0", - "semver": "^7.1.2", - "tmp": "^0.2.1", - "uglify-js": "^3.7.7" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - }, "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "protobufjs": "^7.0.0" + "node": ">= 0.8" } }, - "node_modules/protobufjs/node_modules/long": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.0.tgz", - "integrity": "sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w==", - "dev": true + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/proxy-middleware": { "version": "0.5.1", @@ -11582,19 +10732,6 @@ "node": ">=0.12" } }, - "node_modules/retry-request": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-5.0.2.tgz", - "integrity": "sha512-wfI3pk7EE80lCIXprqh7ym48IHYdwmAAzESdbU8Q9l7pnRCk9LEhpbOTNKjz6FARLm/Bl5m+4F0ABxOkYUujSQ==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "extend": "^3.0.2" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -12355,15 +11492,6 @@ "through": "~2.3.4" } }, - "node_modules/stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "dev": true, - "dependencies": { - "stubs": "^3.0.0" - } - }, "node_modules/stream-exhaust": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", @@ -12476,12 +11604,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", - "dev": true - }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -12547,42 +11669,6 @@ "node": ">=0.6" } }, - "node_modules/teeny-request": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-8.0.1.tgz", - "integrity": "sha512-q1yTwqoS5aH1pjur3kBbI+wFpiAswdVirHMB3pYT5x/B0d+ulYdrruB/xVtbTEaxJemHu5aTbh11rsOLlFk/ZQ==", - "dev": true, - "dependencies": { - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.1", - "stream-events": "^1.0.5", - "uuid": "^8.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/teeny-request/node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/tern": { "version": "0.24.3", "resolved": "https://registry.npmjs.org/tern/-/tern-0.24.3.tgz", @@ -12820,18 +11906,6 @@ "node": "*" } }, - "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, "node_modules/to-absolute-glob": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", @@ -12941,12 +12015,6 @@ "node": ">=0.6" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, "node_modules/trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", @@ -13358,15 +12426,6 @@ "node": ">= 0.4.0" } }, - "node_modules/uuid": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", - "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -13547,12 +12606,6 @@ "node >=0.1.95" ] }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, "node_modules/websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", @@ -13600,16 +12653,6 @@ "node": ">=0.10.0" } }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/whet.extend": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", @@ -14317,6 +13360,27 @@ "@jridgewell/trace-mapping": "0.3.9" } }, + "@emmetio/abbreviation": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.3.3.tgz", + "integrity": "sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==", + "requires": { + "@emmetio/scanner": "^1.0.4" + } + }, + "@emmetio/css-abbreviation": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@emmetio/css-abbreviation/-/css-abbreviation-2.1.8.tgz", + "integrity": "sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==", + "requires": { + "@emmetio/scanner": "^1.0.4" + } + }, + "@emmetio/scanner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@emmetio/scanner/-/scanner-1.0.4.tgz", + "integrity": "sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==" + }, "@eslint/eslintrc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", @@ -14369,181 +13433,6 @@ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.1.2.tgz", "integrity": "sha512-XwWADtfdSN73/udaFm+1mnGIj/ShDZNFMe/PRoqv3FhQ4GNI2PUN70yFTPsjq65Lw2C9i4TG5/hTbxXIXVCiqQ==" }, - "@google-cloud/common": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-4.0.2.tgz", - "integrity": "sha512-LgUoPQq1CNzMAtqnIJLetj7hlzZUS+CG9mBuZthqek6+eGu3PsH2IuEbbtLSUgPZNgOgi/fWGWpbNPP7wgjF0A==", - "dev": true, - "requires": { - "@google-cloud/projectify": "^3.0.0", - "@google-cloud/promisify": "^3.0.0", - "arrify": "^2.0.1", - "duplexify": "^4.1.1", - "ent": "^2.2.0", - "extend": "^3.0.2", - "google-auth-library": "^8.0.2", - "retry-request": "^5.0.0", - "teeny-request": "^8.0.0" - }, - "dependencies": { - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - }, - "duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "dev": true, - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - } - } - }, - "@google-cloud/projectify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-3.0.0.tgz", - "integrity": "sha512-HRkZsNmjScY6Li8/kb70wjGlDDyLkVk3KvoEo9uIoxSjYLJasGiCch9+PqRVDOCGUFvEIqyogl+BeqILL4OJHA==", - "dev": true - }, - "@google-cloud/promisify": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-3.0.1.tgz", - "integrity": "sha512-z1CjRjtQyBOYL+5Qr9DdYIfrdLBe746jRTYfaYU6MeXkqp7UfYs/jX16lFFVzZ7PGEJvqZNqYUEtb1mvDww4pA==", - "dev": true - }, - "@google-cloud/translate": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@google-cloud/translate/-/translate-7.2.2.tgz", - "integrity": "sha512-IAJhPKotLH/OF/NzWml/byLDN+OILbs1P4k+7HNUJK618NsShFelRKzh3pRUUQA4DX0je3HaEZw9nR+5uJ6ZEg==", - "dev": true, - "requires": { - "@google-cloud/common": "^4.0.0", - "@google-cloud/promisify": "^3.0.0", - "arrify": "^2.0.0", - "extend": "^3.0.2", - "google-gax": "^3.5.8", - "is-html": "^2.0.0" - }, - "dependencies": { - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - } - } - }, - "@grpc/grpc-js": { - "version": "1.8.22", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.22.tgz", - "integrity": "sha512-oAjDdN7fzbUi+4hZjKG96MR6KTEubAeMpQEb+77qy+3r0Ua5xTFuie6JOLr4ZZgl5g+W5/uRTS2M1V8mVAFPuA==", - "dev": true, - "requires": { - "@grpc/proto-loader": "^0.7.0", - "@types/node": ">=12.12.47" - } - }, - "@grpc/proto-loader": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.8.tgz", - "integrity": "sha512-GU12e2c8dmdXb7XUlOgYWZ2o2i+z9/VeACkxTA/zzAe2IjclC5PnVL0lpgjhrqfpDYHzM8B1TF6pqWegMYAzlA==", - "dev": true, - "requires": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^7.2.4", - "yargs": "^17.7.2" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - } - } - }, "@gulp-sourcemaps/identity-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz", @@ -14824,76 +13713,6 @@ "php-parser": "^3.1.5" } }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "dev": true - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "dev": true - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "dev": true - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "dev": true - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dev": true, - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "dev": true - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "dev": true - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "dev": true - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "dev": true - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "dev": true - }, - "@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true - }, "@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -14918,26 +13737,10 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, - "@types/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", - "dev": true, - "requires": { - "@types/minimatch": "^5.1.2", - "@types/node": "*" - } - }, "@types/linkify-it": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", - "dev": true - }, - "@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", "dev": true }, "@types/markdown-it": { @@ -14956,12 +13759,6 @@ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", "dev": true }, - "@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true - }, "@types/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", @@ -14986,16 +13783,6 @@ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", "dev": true }, - "@types/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==", - "dev": true, - "requires": { - "@types/glob": "*", - "@types/node": "*" - } - }, "@uiw/file-icons": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@uiw/file-icons/-/file-icons-1.3.2.tgz", @@ -15007,15 +13794,6 @@ "integrity": "sha512-PrJx38EfpitFhwmILRl37jAdBlsww6AZ6rRVK4QS7T7RHLhX7mSs647sTmgr9GIxe3qjXdesmomEgbgaokrVFg==", "dev": true }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "requires": { - "event-target-shim": "^5.0.0" - } - }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -15063,15 +13841,6 @@ "acorn": "^8.11.0" } }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, "aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -15588,12 +14357,6 @@ } } }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, "basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", @@ -15609,12 +14372,6 @@ "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", "dev": true }, - "bignumber.js": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", - "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", - "dev": true - }, "binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", @@ -15732,12 +14489,6 @@ "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", "dev": true }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "dev": true - }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -17348,15 +16099,6 @@ "object.defaults": "^1.1.0" } }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -17369,6 +16111,15 @@ "integrity": "sha512-c/uKWR1Z/W30Wy/sx3dkZoj4BijbXX85QKWu9jJfjho3LBAXNEGAEW3oWiGb+dotA6C6BzCTxL2/aLes7jlUeg==", "dev": true }, + "emmet": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/emmet/-/emmet-2.4.11.tgz", + "integrity": "sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==", + "requires": { + "@emmetio/abbreviation": "^2.3.3", + "@emmetio/css-abbreviation": "^2.1.8" + } + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -17400,12 +16151,6 @@ "tapable": "^0.2.3" } }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", - "dev": true - }, "entities": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", @@ -17499,73 +16244,6 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - } - } - }, "eslint": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.19.0.tgz", @@ -17699,12 +16377,6 @@ "eslint-visitor-keys": "^3.3.0" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, "esquery": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", @@ -17766,12 +16438,6 @@ "through": "^2.3.8" } }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true - }, "eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -18019,12 +16685,6 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, - "fast-text-encoding": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz", - "integrity": "sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==", - "dev": true - }, "fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -18440,39 +17100,6 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "gaxios": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.0.1.tgz", - "integrity": "sha512-keK47BGKHyyOVQxgcUaSaFvr3ehZYAlvhvpHXy0YB2itzZef+GqZR8TBsfVRWghdwlKrYsn+8L8i3eblF7Oviw==", - "dev": true, - "requires": { - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.7" - }, - "dependencies": { - "node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - } - } - }, - "gcp-metadata": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.0.0.tgz", - "integrity": "sha512-gfwuX3yA3nNsHSWUL4KG90UulNiq922Ukj3wLTrcnX33BB7PwB1o0ubR8KVvXu9nJH+P5w1j2SQSNNqto+H0DA==", - "dev": true, - "requires": { - "gaxios": "^5.0.0", - "json-bigint": "^1.0.0" - } - }, "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", @@ -18965,111 +17592,11 @@ "sparkles": "^1.0.0" } }, - "google-auth-library": { - "version": "8.5.2", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-8.5.2.tgz", - "integrity": "sha512-FPfOSaI8n2TVXFHTP8/vAVFCXhyALj7w9/Rgefux3oeKZ/nQDNmfNTJ+lIKcoYT1cKkvMllp1Eood7Y5L+TP+A==", - "dev": true, - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^5.0.0", - "gcp-metadata": "^5.0.0", - "gtoken": "^6.1.0", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - }, - "dependencies": { - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "google-gax": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-3.6.1.tgz", - "integrity": "sha512-g/lcUjGcB6DSw2HxgEmCDOrI/CByOwqRvsuUvNalHUK2iPPPlmAIpbMbl62u0YufGMr8zgE3JL7th6dCb1Ry+w==", - "dev": true, - "requires": { - "@grpc/grpc-js": "~1.8.0", - "@grpc/proto-loader": "^0.7.0", - "@types/long": "^4.0.0", - "@types/rimraf": "^3.0.2", - "abort-controller": "^3.0.0", - "duplexify": "^4.0.0", - "fast-text-encoding": "^1.0.3", - "google-auth-library": "^8.0.2", - "is-stream-ended": "^0.1.4", - "node-fetch": "^2.6.1", - "object-hash": "^3.0.0", - "proto3-json-serializer": "^1.0.0", - "protobufjs": "7.2.4", - "protobufjs-cli": "1.1.1", - "retry-request": "^5.0.0" - }, - "dependencies": { - "duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "dev": true, - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - } - } - }, - "google-p12-pem": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-4.0.1.tgz", - "integrity": "sha512-WPkN4yGtz05WZ5EhtlxNDWPhC4JIic6G8ePitwUWy4l+XPVYec+a0j0Ts47PDtW59y3RwAhUd9/h9ZZ63px6RQ==", - "dev": true, - "requires": { - "node-forge": "^1.3.1" - } - }, "graceful-fs": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, - "gtoken": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-6.1.2.tgz", - "integrity": "sha512-4ccGpzz7YAr7lxrT2neugmXQ3hP9ho2gcaityLVkiUecAiwiy60Ii8gRbZeOsXV19fYaRjgBSshs8kXw+NKCPQ==", - "dev": true, - "requires": { - "gaxios": "^5.0.1", - "google-p12-pem": "^4.0.0", - "jws": "^4.0.0" - } - }, "gulp": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", @@ -19909,12 +18436,6 @@ "whatwg-encoding": "^2.0.0" } }, - "html-tags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz", - "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", - "dev": true - }, "htmlparser2": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", @@ -19987,17 +18508,6 @@ "requires-port": "^1.0.0" } }, - "http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - } - }, "http-server": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.0.tgz", @@ -20019,16 +18529,6 @@ "url-join": "^4.0.1" } }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, "human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -20270,15 +18770,6 @@ "is-extglob": "^2.1.1" } }, - "is-html": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-html/-/is-html-2.0.0.tgz", - "integrity": "sha512-S+OpgB5i7wzIue/YSE5hg0e5ZYfG3hhpNh9KGl6ayJ38p7ED6wxQLd1TV91xHpcTvw90KMJ9EwN3F/iNflHBVg==", - "dev": true, - "requires": { - "html-tags": "^3.0.0" - } - }, "is-negated-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", @@ -20344,12 +18835,6 @@ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, - "is-stream-ended": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", - "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", - "dev": true - }, "is-svg": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", @@ -20599,15 +19084,6 @@ } } }, - "json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "dev": true, - "requires": { - "bignumber.js": "^9.0.0" - } - }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -20685,27 +19161,6 @@ "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", "dev": true }, - "jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "dev": true, - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "dev": true, - "requires": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -21044,12 +19499,6 @@ "lodash.keys": "~2.4.1" } }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -21628,12 +20077,6 @@ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", "dev": true }, - "node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "dev": true - }, "node.extend": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-1.1.8.tgz", @@ -21753,12 +20196,6 @@ } } }, - "object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true - }, "object-inspect": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", @@ -22562,61 +20999,6 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, - "proto3-json-serializer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-1.1.0.tgz", - "integrity": "sha512-SjXwUWe/vANGs/mJJTbw5++7U67nwsymg7qsoPtw6GiXqw3kUy8ByojrlEdVE2efxAdKreX8WkDafxvYW95ZQg==", - "dev": true, - "requires": { - "protobufjs": "^7.0.0" - } - }, - "protobufjs": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.4.tgz", - "integrity": "sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ==", - "dev": true, - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "dependencies": { - "long": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.0.tgz", - "integrity": "sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w==", - "dev": true - } - } - }, - "protobufjs-cli": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/protobufjs-cli/-/protobufjs-cli-1.1.1.tgz", - "integrity": "sha512-VPWMgIcRNyQwWUv8OLPyGQ/0lQY/QTQAVN5fh+XzfDwsVw1FZ2L3DM/bcBf8WPiRz2tNpaov9lPZfNcmNo6LXA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "escodegen": "^1.13.0", - "espree": "^9.0.0", - "estraverse": "^5.1.0", - "glob": "^8.0.0", - "jsdoc": "^4.0.0", - "minimist": "^1.2.0", - "semver": "^7.1.2", - "tmp": "^0.2.1", - "uglify-js": "^3.7.7" - } - }, "proxy-middleware": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.5.1.tgz", @@ -23141,16 +21523,6 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, - "retry-request": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-5.0.2.tgz", - "integrity": "sha512-wfI3pk7EE80lCIXprqh7ym48IHYdwmAAzESdbU8Q9l7pnRCk9LEhpbOTNKjz6FARLm/Bl5m+4F0ABxOkYUujSQ==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "extend": "^3.0.2" - } - }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -23777,15 +22149,6 @@ "through": "~2.3.4" } }, - "stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "dev": true, - "requires": { - "stubs": "^3.0.0" - } - }, "stream-exhaust": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", @@ -23868,12 +22231,6 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, - "stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", - "dev": true - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -23923,30 +22280,6 @@ "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.9.tgz", "integrity": "sha512-2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A==" }, - "teeny-request": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-8.0.1.tgz", - "integrity": "sha512-q1yTwqoS5aH1pjur3kBbI+wFpiAswdVirHMB3pYT5x/B0d+ulYdrruB/xVtbTEaxJemHu5aTbh11rsOLlFk/ZQ==", - "dev": true, - "requires": { - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.1", - "stream-events": "^1.0.5", - "uuid": "^8.0.0" - }, - "dependencies": { - "node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - } - } - }, "tern": { "version": "0.24.3", "resolved": "https://registry.npmjs.org/tern/-/tern-0.24.3.tgz", @@ -24152,15 +22485,6 @@ "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==" }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } - }, "to-absolute-glob": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", @@ -24253,12 +22577,6 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", @@ -24568,12 +22886,6 @@ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", "dev": true }, - "uuid": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", - "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", - "dev": true - }, "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -24730,12 +23042,6 @@ "integrity": "sha1-6NugkbdFZ5mjr1eXi5hud+EyBAY=", "dev": true }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, "websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", @@ -24773,16 +23079,6 @@ } } }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "whet.extend": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", diff --git a/package.json b/package.json index a92d7eb156..a0057a252b 100644 --- a/package.json +++ b/package.json @@ -100,6 +100,7 @@ "codemirror": "^5.65.16", "cross-env": "^7.0.3", "devicon": "^2.15.1", + "emmet": "^2.4.11", "file-saver": "^2.0.5", "idb-keyval": "^6.2.1", "jshint": "^2.13.5", @@ -116,4 +117,4 @@ "tinycolor2": "^1.4.2", "underscore": "^1.13.4" } -} \ No newline at end of file +} diff --git a/src-node/package-lock.json b/src-node/package-lock.json index a5681759d6..058d71e5a2 100644 --- a/src-node/package-lock.json +++ b/src-node/package-lock.json @@ -1,12 +1,12 @@ { "name": "@phcode/node-core", - "version": "4.0.1-0", + "version": "4.0.4-0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@phcode/node-core", - "version": "4.0.1-0", + "version": "4.0.4-0", "license": "GNU-AGPL3.0", "dependencies": { "@phcode/fs": "^3.0.1", diff --git a/src/extensionsIntegrated/Emmet/main.js b/src/extensionsIntegrated/Emmet/main.js new file mode 100644 index 0000000000..2639560b21 --- /dev/null +++ b/src/extensionsIntegrated/Emmet/main.js @@ -0,0 +1,484 @@ +define(function (require, exports, module) { + const AppInit = require("utils/AppInit"); + const EditorManager = require("editor/EditorManager"); + // const KeyBindingManager = require("command/KeyBindingManager"); + //const CommandManager = require("command/CommandManager"); + const PreferencesManager = require("preferences/PreferencesManager"); + const Strings = require("strings"); + + const Emmet = require("thirdparty/emmet"); + + // For preferences settings, to toggle this feature on/off + const PREFERENCES_EMMET = "emmet"; + let enabled = true; // by default:- on + + PreferencesManager.definePreference(PREFERENCES_EMMET, "boolean", enabled, { + description: Strings.DESCRIPTION_EMMET + }); + + /** + * A list of all the markup snippets that can be expanded. + * For ex: 'link:css', 'iframe' + * They expand differently as compared to normal tags. + */ + const markupSnippetsList = Object.keys(Emmet.markupSnippets); + + /** + * A list of all the HTML tags that expand like normal tags + */ + const htmlTags = [ + "a", "abbr", "address", "area", "article", "aside", "audio", "b", "base", + "bdi", "bdo", "blockquote", "body", "br", "button", "canvas", "caption", + "cite", "code", "col", "colgroup", "data", "datalist", "dd", "del", + "details", "dfn", "dialog", "div", "dl", "dt", "em", "embed", "fieldset", + "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", + "h6", "head", "header", "hgroup", "hr", "html", "i", "iframe", "img", + "input", "ins", "kbd", "label", "legend", "li", "link", "main", "map", + "mark", "meta", "meter", "nav", "noscript", "object", "ol", "optgroup", + "option", "output", "p", "param", "picture", "pre", "progress", "q", + "rp", "rt", "ruby", "s", "samp", "script", "section", "select", "small", + "source", "span", "strong", "style", "sub", "summary", "sup", "table", + "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", + "title", "tr", "track", "u", "ul", "var", "video", "wbr" + ]; + + /** + * A list of all those symbols which if present in a word, that word can be expanded + */ + const positiveSymbols = [ + '.', // classes + '#', // ids + '!', // document generator + '>', // Child Selector + '+', // Adjacent Sibling Selector + '^', // Parent Selector + '*', // Multiplication (Repeat Element) + '[', + ']', // Attributes + '{', + '}', // Text Content + '(', + ')', // Group + '&' // Current Element Reference + ]; + + /** + * A list of all those symbols which if present in a word, that word cannot be expanded + */ + const negativeSymbols = [ + '' // closing tag + ]; + + + + /** + * Responsible to create the configuration based on the file type. + * Config is an object with two properties, type & snytax. + * This is required by the Emmet API to distinguish between HTML & Stylesheets + * + * @param {Editor} editor - The editor instance + * @returns {Object | False} Object with two properties 'syntax' and 'type' + */ + function createConfig(editor) { + const fileType = editor.document.getLanguage().getId(); + + if (fileType === "html") { + return { syntax: "html", type: "markup" }; + } + + if (fileType === "css" || fileType === "scss" || fileType === "less") { + return { syntax: "css", type: "stylesheet" }; + } + + return false; + } + + /** + * Responsible to get the current word before cursor + * + * @param {Editor} editor - The editor instance + * @returns {Object} an object in the format : + * { + * word: "", // the word before the cursor + * start: {line: Number, ch: Number}, + * end: {line: Number, ch: Number} + * } + */ + function getWordBeforeCursor(editor) { + const pos = editor.getCursorPos(); + const line = editor.document.getLine(pos.line); + let start = pos.ch; + let insideBraces = false; + // special chars that may be in emmet abbr + const specialChars = new Set(['.', '#', '[', ']', '"', '=', '//', ':', '-', ',']); + + // If the cursor is right before '}', move it inside + if (line.charAt(start) === '}') { + start--; + insideBraces = true; + } + + // Look backwards + while (start > 0) { + const char = line.charAt(start - 1); + + if (char === '}' || char === ']') { + insideBraces = true; + } else if (char === '{' || char === '[') { + insideBraces = false; + } + + if (/[a-zA-Z0-9:+*<>()/!$\-@#}{]/.test(char) || + specialChars.has(char) || + (insideBraces && char === ' ')) { + start--; + } else { + break; + } + } + + return { + word: line.substring(start, pos.ch), + start: { line: pos.line, ch: start }, + end: pos + }; + } + + + /** + * Calculate the indentation level for the current line + * + * @param {Editor} editor - the editor instance + * @param {Object} position - position object with line number + * @returns {String} - the indentation string + */ + function getLineIndentation(editor, position) { + const line = editor.document.getLine(position.line); + const match = line.match(/^\s*/); + return match ? match[0] : ''; + } + + + /** + * Adds proper indentation to multiline Emmet expansion + * + * @param {String} expandedText - the expanded Emmet abbreviation + * @param {String} baseIndent - the base indentation string + * @returns {String} - properly indented text + */ + function addIndentation(expandedText, baseIndent) { + // Split into lines, preserve empty lines + const lines = expandedText.split(/(\r\n|\n)/g); + + // Process each line + let result = ''; + let isFirstLine = true; + + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + + // If it's a newline character, just add it + if (line === '\n' || line === '\r\n') { + result += line; + continue; + } + + // Skip indenting empty lines + if (line.trim() === '') { + result += line; + continue; + } + + // Don't indent the first line as it inherits the current indent + if (isFirstLine) { + result += line; + isFirstLine = false; + } else { + // Add base indent plus the existing indent in the expanded text + result += baseIndent + line; + } + } + + return result; + } + + + + /** + * Find the position where cursor should be placed after expansion + * Looks for patterns like '><', '""', '' + * + * @param {Editor} editor - The editor instance + * @param {String} indentedAbbr - the indented abbreviation + * @param {Object} startPos - Starting position {line, ch} of the expansion + * @returns {Object | false} - Cursor position {line, ch} or false if no pattern found + */ + function findCursorPosition(editor, indentedAbbr, startPos) { + const totalLines = startPos.line + indentedAbbr.split('\n').length; + + for (let i = startPos.line; i < totalLines; i++) { + const line = editor.document.getLine(i); + + for (let j = 0; j < line.length - 1; j++) { + const pair = line[j] + line[j + 1]; + + if (pair === '""' || pair === "''") { + return { line: i, ch: j + 1 }; + } + } + for (let j = 0; j < line.length - 1; j++) { + const pair = line[j] + line[j + 1]; + + if (pair === '><') { + return { line: i, ch: j + 1 }; + } + } + } + + // Look for opening and closing tag pairs with empty line in between + //
+ // | + // + // here in such scenarios, we want the cursor to be placed in between + // Look for opening and closing tag pairs with empty line in between + for (let i = startPos.line; i < totalLines; i++) { + const line = editor.document.getLine(i).trim(); + if (line.endsWith('>') && line.includes('<') && !line.includes('')) { + if (editor.document.getLine(i + 1) && !editor.document.getLine(i + 1).trim()) { + const tempLine = editor.document.getLine(i + 2); + if (tempLine) { + const trimmedTempLine = tempLine.trim(); + if (trimmedTempLine.includes('') && trimmedTempLine.startsWith('<')) { + // Get the current line's indentation by counting spaces/tabs + const openingTagLine = editor.document.getLine(i); + const indentMatch = openingTagLine.match(/^[\s\t]*/)[0]; + // Add 4 more spaces (or equivalent tab) for inner content + const extraIndent = ' '; // 4 spaces for additional indentation + + return { + line: i + 1, + ch: indentMatch.length + extraIndent.length + }; + } + } + } + } + } + + return false; + } + + + + /** + * This function is responsible to replace the abbreviation in the editor, + * with its expanded version + * + * @param {Editor} editor - the editor instance + * @param {Object} wordObj - an object in the format : + * { + * word: "", // the word before the cursor + * start: {line: Number, ch: Number}, + * end: {line: Number, ch: Number} + * } + * @param {String} expandedAbbr - the expanded version of abbr that will replace the abbr + */ + function updateAbbrInEditor(editor, wordObj, expandedAbbr) { + // Get the current line's indentation + const baseIndent = getLineIndentation(editor, wordObj.start); + + // Add proper indentation to the expanded abbreviation + const indentedAbbr = addIndentation(expandedAbbr, baseIndent); + + // Handle the special case for braces + // this check is added because in some situations such as + // `ul>li{Hello}` and the cursor is before the closing braces right after 'o', + // then when this is expanded it results in an extra closing braces at the end. + // so we remove the extra closing brace from the end + if (wordObj.word.includes('{') || wordObj.word.includes('[')) { + const pos = editor.getCursorPos(); + const line = editor.document.getLine(pos.line); + const char = line.charAt(wordObj.end.ch); + const charsNext = line.charAt(wordObj.end.ch+1); + + if (char === '}' || char === ']') { + wordObj.end.ch += 1; + } + + // sometimes at the end we get `"]` as extra with some abbreviations. + if(char === '"' && charsNext && charsNext === ']') { + wordObj.end.ch += 2; + } + + } + + // Replace the abbreviation + editor.document.replaceRange( + indentedAbbr, + wordObj.start, + wordObj.end + ); + + // Calculate and set the new cursor position + const cursorPos = findCursorPosition(editor, indentedAbbr, wordObj.start); + if (cursorPos) { + editor.setCursorPos(cursorPos.line, cursorPos.ch); + } + } + + + /** + * This function checks whether the abbreviation can be expanded or not. + * There are a lot of cases to check: + * There should not be any negative symbols + * The abbr should be either in htmlTags or in markupSnippetsList + * For other cases such as 'ul>li', we will check if there is any, + * positive word. This is done to handle complex abbreviations such as, + * 'ul>li' or 'li*3{Hello}'. So we check if the word includes any positive symbols. + * + * @param {Editor} editor - the editor instance + * @param {String} word - the abbr + * @param {Object} config - the config object, to make sure it is a valid file type, + * refer to createConfig function for more info about config object. + * @returns {String | false} - returns the expanded abbr, and if cannot be expanded, returns false + */ + function isExpandable(editor, word, config) { + + // make sure that word doesn't contain any negativeSymbols + if (negativeSymbols.some(symbol => word.includes(symbol))) { + return false; + } + + // the word must be either in markupSnippetsList, htmlList or it must have a positive symbol + if (markupSnippetsList.includes(word) || + htmlTags.includes(word) || + positiveSymbols.some(symbol => word.includes(symbol))) { + + try { + const expanded = Emmet.expandAbbreviation(word, config); + return expanded; + } catch (error) { + + // emmet api throws an error when abbr contains unclosed quotes, handling that case + const pos = editor.getCursorPos(); + const line = editor.document.getLine(pos.line); + const nextChar = line.charAt(pos.ch); + + if (nextChar) { + // If the next character is a quote, add quote to abbr + if (nextChar === '"' || nextChar === "'") { + const modifiedWord = word + nextChar; + + try { + const expandedModified = Emmet.expandAbbreviation(modifiedWord, config); + return expandedModified; + } catch (innerError) { + // If it still fails, return false + return false; + } + } + } + + // If no quote is found or expansion fails, return false + return false; + } + } + + return false; + } + + + /** + * Responsible to handle the flow of the program + * + * @param {Editor} editor - the editor instance + * @param {Object} keyboardEvent - the keyboard event object + */ + function driver(editor, keyboardEvent) { + const config = createConfig(editor); + + if (config) { + + // to make sure it is an html file + if (config.syntax === "html") { + const wordObj = getWordBeforeCursor(editor); + + // make sure we donot have empty spaces + if (wordObj.word.trim()) { + + const expandedAbbr = isExpandable(editor, wordObj.word, config); + if (expandedAbbr) { + updateAbbrInEditor(editor, wordObj, expandedAbbr); + + // prevent the default working of the 'tab' key + keyboardEvent.preventDefault(); + } + } + } + } + } + + /** + * Function that gets triggered when any key is pressed. + * We only want to look for 'tab' key events + * + * @param {Event} event - unused event detail + * @param {Editor} editor - the editor instance + * @param {Object} keyboardEvent - an object that has properties related to the keyboard, + * mainly the key that is pressed (keyboardEvent.key) + * @returns {Boolean} True if abbreviation is expanded else false + */ + function handleKeyEvent(event, editor, keyboardEvent) { + if (!enabled) { + return false; + } + + // if not a 'tab' key press, ignore + if (keyboardEvent.key !== "Tab") { + return false; + } + + // the function that drives the flow of the program + driver(editor, keyboardEvent); + } + + /** + * Register all the required handlers + */ + function registerHandlers() { + // Get the current active editor and attach the change listener + const activeEditor = EditorManager.getActiveEditor(); + if (activeEditor) { + activeEditor.on("keydown", handleKeyEvent); + } + + // Listen for active editor changes, to attach the handler to new editor + EditorManager.on("activeEditorChange", function (event, newEditor, oldEditor) { + if (oldEditor) { + // Remove listener from old editor + oldEditor.off("keydown", handleKeyEvent); + } + if (newEditor) { + // Add listener to new editor + newEditor.off("change", handleKeyEvent); + newEditor.on("keydown", handleKeyEvent); + } + }); + } + + /** + * Checks for preference changes, to enable/disable the feature + */ + function preferenceChanged() { + const value = PreferencesManager.get(PREFERENCES_EMMET); + enabled = value; + } + + AppInit.appReady(function () { + // Set up preferences + PreferencesManager.on("change", PREFERENCES_EMMET, preferenceChanged); + preferenceChanged(); + + registerHandlers(); + }); +}); diff --git a/src/extensionsIntegrated/loader.js b/src/extensionsIntegrated/loader.js index 337e3f82f9..6b64df3bdb 100644 --- a/src/extensionsIntegrated/loader.js +++ b/src/extensionsIntegrated/loader.js @@ -43,4 +43,5 @@ define(function (require, exports, module) { require("./HtmlTagSyncEdit/main"); require("./indentGuides/main"); require("./CSSColorPreview/main"); + require("./Emmet/main"); }); diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index d37504a04e..a9d4061037 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -1263,6 +1263,9 @@ define({ "DESCRIPTION_HIDE_FIRST": "true to show the first Indent Guide line else false.", "DESCRIPTION_CSS_COLOR_PREVIEW": "true to display color previews in the gutter, else false.", + // Emmet + "DESCRIPTION_EMMET": "true to enable emmet, else false.", + // Git extension "ENABLE_GIT": "Enable Git", "ACTION": "Action", diff --git a/src/thirdparty/emmet.js b/src/thirdparty/emmet.js new file mode 100644 index 0000000000..a586e4cc78 --- /dev/null +++ b/src/thirdparty/emmet.js @@ -0,0 +1,5457 @@ +'use strict'; + +// Object.defineProperty(exports, '__esModule', { value: true }); +define(function (require, exports, module) { + + + + /** + * Check if given code is a number + */ + function isNumber$1(code) { + return code > 47 && code < 58; + } + /** + * Check if given character code is alpha code (letter through A to Z) + */ + function isAlpha$1(code, from, to) { + from = from || 65; // A + to = to || 90; // Z + code &= ~32; // quick hack to convert any char code to uppercase char code + return code >= from && code <= to; + } + function isAlphaNumericWord(code) { + return isNumber$1(code) || isAlphaWord(code); + } + function isAlphaWord(code) { + return code === 95 /* _ */ || isAlpha$1(code); + } + /** + * Check for Umlauts i.e. ä, Ä, ö, Ö, ü and Ü + */ + function isUmlaut(code) { + return code === 196 + || code == 214 + || code === 220 + || code === 228 + || code === 246 + || code === 252; + } + /** + * Check if given character code is a white-space character: a space character + * or line breaks + */ + function isWhiteSpace$3(code) { + return code === 32 /* space */ + || code === 9 /* tab */ + || code === 160; /* non-breaking space */ + } + /** + * Check if given character code is a space character + */ + function isSpace(code) { + return isWhiteSpace$3(code) + || code === 10 /* LF */ + || code === 13; /* CR */ + } + /** + * Check if given character code is a quote character + */ + function isQuote$2(code) { + return code === 39 /* ' */ || code === 34 /* " */; + } + + /** + * A streaming, character code-based string reader + */ + class Scanner { + constructor(str, start, end) { + if (end == null && typeof str === 'string') { + end = str.length; + } + this.string = str; + this.pos = this.start = start || 0; + this.end = end || 0; + } + /** + * Returns true only if the stream is at the end of the file. + */ + eof() { + return this.pos >= this.end; + } + /** + * Creates a new stream instance which is limited to given `start` and `end` + * range. E.g. its `eof()` method will look at `end` property, not actual + * stream end + */ + limit(start, end) { + return new Scanner(this.string, start, end); + } + /** + * Returns the next character code in the stream without advancing it. + * Will return NaN at the end of the file. + */ + peek() { + return this.string.charCodeAt(this.pos); + } + /** + * Returns the next character in the stream and advances it. + * Also returnsundefined when no more characters are available.
+ */
+ next() {
+ if (this.pos < this.string.length) {
+ return this.string.charCodeAt(this.pos++);
+ }
+ }
+ /**
+ * `match` can be a character code or a function that takes a character code
+ * and returns a boolean. If the next character in the stream 'matches'
+ * the given argument, it is consumed and returned.
+ * Otherwise, `false` is returned.
+ */
+ eat(match) {
+ const ch = this.peek();
+ const ok = typeof match === 'function' ? match(ch) : ch === match;
+ if (ok) {
+ this.next();
+ }
+ return ok;
+ }
+ /**
+ * Repeatedly calls eat with the given argument, until it
+ * fails. Returns true if any characters were eaten.
+ */
+ eatWhile(match) {
+ const start = this.pos;
+ while (!this.eof() && this.eat(match)) { /* */ }
+ return this.pos !== start;
+ }
+ /**
+ * Backs up the stream n characters. Backing it up further than the
+ * start of the current token will cause things to break, so be careful.
+ */
+ backUp(n) {
+ this.pos -= (n || 1);
+ }
+ /**
+ * Get the string between the start of the current token and the
+ * current stream position.
+ */
+ current() {
+ return this.substring(this.start, this.pos);
+ }
+ /**
+ * Returns substring for given range
+ */
+ substring(start, end) {
+ return this.string.slice(start, end);
+ }
+ /**
+ * Creates error object with current stream state
+ */
+ error(message, pos = this.pos) {
+ return new ScannerError(`${message} at ${pos + 1}`, pos, this.string);
+ }
+ }
+ class ScannerError extends Error {
+ constructor(message, pos, str) {
+ super(message);
+ this.pos = pos;
+ this.string = str;
+ }
+ }
+
+ function tokenScanner$1(tokens) {
+ return {
+ tokens,
+ start: 0,
+ pos: 0,
+ size: tokens.length
+ };
+ }
+ function peek$3(scanner) {
+ return scanner.tokens[scanner.pos];
+ }
+ function next(scanner) {
+ return scanner.tokens[scanner.pos++];
+ }
+ function slice(scanner, from = scanner.start, to = scanner.pos) {
+ return scanner.tokens.slice(from, to);
+ }
+ function readable$1(scanner) {
+ return scanner.pos < scanner.size;
+ }
+ function consume$2(scanner, test) {
+ const token = peek$3(scanner);
+ if (token && test(token)) {
+ scanner.pos++;
+ return true;
+ }
+ return false;
+ }
+ function error$1(scanner, message, token = peek$3(scanner)) {
+ if (token && token.start != null) {
+ message += ` at ${token.start}`;
+ }
+ const err = new Error(message);
+ err['pos'] = token && token.start;
+ return err;
+ }
+
+ function abbreviation(abbr, options = {}) {
+ const scanner = tokenScanner$1(abbr);
+ const result = statements(scanner, options);
+ if (readable$1(scanner)) {
+ throw error$1(scanner, 'Unexpected character');
+ }
+ return result;
+ }
+ function statements(scanner, options) {
+ const result = {
+ type: 'TokenGroup',
+ elements: []
+ };
+ let ctx = result;
+ let node;
+ const stack = [];
+ while (readable$1(scanner)) {
+ if (node = element$2(scanner, options) || group(scanner, options)) {
+ ctx.elements.push(node);
+ if (consume$2(scanner, isChildOperator)) {
+ stack.push(ctx);
+ ctx = node;
+ }
+ else if (consume$2(scanner, isSiblingOperator$1)) {
+ continue;
+ }
+ else if (consume$2(scanner, isClimbOperator)) {
+ do {
+ if (stack.length) {
+ ctx = stack.pop();
+ }
+ } while (consume$2(scanner, isClimbOperator));
+ }
+ }
+ else {
+ break;
+ }
+ }
+ return result;
+ }
+ /**
+ * Consumes group from given scanner
+ */
+ function group(scanner, options) {
+ if (consume$2(scanner, isGroupStart)) {
+ const result = statements(scanner, options);
+ const token = next(scanner);
+ if (isBracket$2(token, 'group', false)) {
+ result.repeat = repeater$1(scanner);
+ }
+ return result;
+ }
+ }
+ /**
+ * Consumes single element from given scanner
+ */
+ function element$2(scanner, options) {
+ let attr;
+ const elem = {
+ type: 'TokenElement',
+ name: void 0,
+ attributes: void 0,
+ value: void 0,
+ repeat: void 0,
+ selfClose: false,
+ elements: []
+ };
+ if (elementName(scanner, options)) {
+ elem.name = slice(scanner);
+ }
+ while (readable$1(scanner)) {
+ scanner.start = scanner.pos;
+ if (!elem.repeat && !isEmpty(elem) && consume$2(scanner, isRepeater)) {
+ elem.repeat = scanner.tokens[scanner.pos - 1];
+ }
+ else if (!elem.value && text(scanner)) {
+ elem.value = getText(scanner);
+ }
+ else if (attr = shortAttribute(scanner, 'id', options) || shortAttribute(scanner, 'class', options) || attributeSet(scanner)) {
+ if (!elem.attributes) {
+ elem.attributes = Array.isArray(attr) ? attr.slice() : [attr];
+ }
+ else {
+ elem.attributes = elem.attributes.concat(attr);
+ }
+ }
+ else {
+ if (!isEmpty(elem) && consume$2(scanner, isCloseOperator)) {
+ elem.selfClose = true;
+ if (!elem.repeat && consume$2(scanner, isRepeater)) {
+ elem.repeat = scanner.tokens[scanner.pos - 1];
+ }
+ }
+ break;
+ }
+ }
+ return !isEmpty(elem) ? elem : void 0;
+ }
+ /**
+ * Consumes attribute set from given scanner
+ */
+ function attributeSet(scanner) {
+ if (consume$2(scanner, isAttributeSetStart)) {
+ const attributes = [];
+ let attr;
+ while (readable$1(scanner)) {
+ if (attr = attribute(scanner)) {
+ attributes.push(attr);
+ }
+ else if (consume$2(scanner, isAttributeSetEnd)) {
+ break;
+ }
+ else if (!consume$2(scanner, isWhiteSpace$2)) {
+ throw error$1(scanner, `Unexpected "${peek$3(scanner).type}" token`);
+ }
+ }
+ return attributes;
+ }
+ }
+ /**
+ * Consumes attribute shorthand (class or id) from given scanner
+ */
+ function shortAttribute(scanner, type, options) {
+ if (isOperator$1(peek$3(scanner), type)) {
+ scanner.pos++;
+ // Consume multiple operators
+ let count = 1;
+ while (isOperator$1(peek$3(scanner), type)) {
+ scanner.pos++;
+ count++;
+ }
+ const attr = {
+ name: [createLiteral$1(type)]
+ };
+ if (count > 1) {
+ attr.multiple = true;
+ }
+ // Consume expression after shorthand start for React-like components
+ if (options.jsx && text(scanner)) {
+ attr.value = getText(scanner);
+ attr.expression = true;
+ }
+ else {
+ attr.value = literal$1$1(scanner) ? slice(scanner) : void 0;
+ }
+ return attr;
+ }
+ }
+ /**
+ * Consumes single attribute from given scanner
+ */
+ function attribute(scanner) {
+ if (quoted(scanner)) {
+ // Consumed quoted value: it’s a value for default attribute
+ return {
+ value: slice(scanner)
+ };
+ }
+ if (literal$1$1(scanner, true)) {
+ const name = slice(scanner);
+ let value;
+ if (consume$2(scanner, isEquals)) {
+ if (quoted(scanner) || literal$1$1(scanner, true)) {
+ value = slice(scanner);
+ }
+ }
+ return { name, value };
+ }
+ }
+ function repeater$1(scanner) {
+ return isRepeater(peek$3(scanner))
+ ? scanner.tokens[scanner.pos++]
+ : void 0;
+ }
+ /**
+ * Consumes quoted value from given scanner, if possible
+ */
+ function quoted(scanner) {
+ const start = scanner.pos;
+ const quote = peek$3(scanner);
+ if (isQuote$1(quote)) {
+ scanner.pos++;
+ while (readable$1(scanner)) {
+ if (isQuote$1(next(scanner), quote.single)) {
+ scanner.start = start;
+ return true;
+ }
+ }
+ throw error$1(scanner, 'Unclosed quote', quote);
+ }
+ return false;
+ }
+ /**
+ * Consumes literal (unquoted value) from given scanner
+ */
+ function literal$1$1(scanner, allowBrackets) {
+ const start = scanner.pos;
+ const brackets = {
+ attribute: 0,
+ expression: 0,
+ group: 0
+ };
+ while (readable$1(scanner)) {
+ const token = peek$3(scanner);
+ if (brackets.expression) {
+ // If we’re inside expression, we should consume all content in it
+ if (isBracket$2(token, 'expression')) {
+ brackets[token.context] += token.open ? 1 : -1;
+ }
+ }
+ else if (isQuote$1(token) || isOperator$1(token) || isWhiteSpace$2(token) || isRepeater(token)) {
+ break;
+ }
+ else if (isBracket$2(token)) {
+ if (!allowBrackets) {
+ break;
+ }
+ if (token.open) {
+ brackets[token.context]++;
+ }
+ else if (!brackets[token.context]) {
+ // Stop if found unmatched closing brace: it must be handled
+ // by parent consumer
+ break;
+ }
+ else {
+ brackets[token.context]--;
+ }
+ }
+ scanner.pos++;
+ }
+ if (start !== scanner.pos) {
+ scanner.start = start;
+ return true;
+ }
+ return false;
+ }
+ /**
+ * Consumes element name from given scanner
+ */
+ function elementName(scanner, options) {
+ const start = scanner.pos;
+ if (options.jsx && consume$2(scanner, isCapitalizedLiteral)) {
+ // Check for edge case: consume immediate capitalized class names
+ // for React-like components, e.g. `Foo.Bar.Baz`
+ while (readable$1(scanner)) {
+ const { pos } = scanner;
+ if (!consume$2(scanner, isClassNameOperator) || !consume$2(scanner, isCapitalizedLiteral)) {
+ scanner.pos = pos;
+ break;
+ }
+ }
+ }
+ while (readable$1(scanner) && consume$2(scanner, isElementName$1)) {
+ // empty
+ }
+ if (scanner.pos !== start) {
+ scanner.start = start;
+ return true;
+ }
+ return false;
+ }
+ /**
+ * Consumes text value from given scanner
+ */
+ function text(scanner) {
+ const start = scanner.pos;
+ if (consume$2(scanner, isTextStart)) {
+ let brackets = 0;
+ while (readable$1(scanner)) {
+ const token = next(scanner);
+ if (isBracket$2(token, 'expression')) {
+ if (token.open) {
+ brackets++;
+ }
+ else if (!brackets) {
+ break;
+ }
+ else {
+ brackets--;
+ }
+ }
+ }
+ scanner.start = start;
+ return true;
+ }
+ return false;
+ }
+ function getText(scanner) {
+ let from = scanner.start;
+ let to = scanner.pos;
+ if (isBracket$2(scanner.tokens[from], 'expression', true)) {
+ from++;
+ }
+ if (isBracket$2(scanner.tokens[to - 1], 'expression', false)) {
+ to--;
+ }
+ return slice(scanner, from, to);
+ }
+ function isBracket$2(token, context, isOpen) {
+ return Boolean(token && token.type === 'Bracket'
+ && (!context || token.context === context)
+ && (isOpen == null || token.open === isOpen));
+ }
+ function isOperator$1(token, type) {
+ return Boolean(token && token.type === 'Operator' && (!type || token.operator === type));
+ }
+ function isQuote$1(token, isSingle) {
+ return Boolean(token && token.type === 'Quote' && (isSingle == null || token.single === isSingle));
+ }
+ function isWhiteSpace$2(token) {
+ return Boolean(token && token.type === 'WhiteSpace');
+ }
+ function isEquals(token) {
+ return isOperator$1(token, 'equal');
+ }
+ function isRepeater(token) {
+ return Boolean(token && token.type === 'Repeater');
+ }
+ function isLiteral$2(token) {
+ return token.type === 'Literal';
+ }
+ function isCapitalizedLiteral(token) {
+ if (isLiteral$2(token)) {
+ const ch = token.value.charCodeAt(0);
+ return ch >= 65 && ch <= 90;
+ }
+ return false;
+ }
+ function isElementName$1(token) {
+ return token.type === 'Literal' || token.type === 'RepeaterNumber' || token.type === 'RepeaterPlaceholder';
+ }
+ function isClassNameOperator(token) {
+ return isOperator$1(token, 'class');
+ }
+ function isAttributeSetStart(token) {
+ return isBracket$2(token, 'attribute', true);
+ }
+ function isAttributeSetEnd(token) {
+ return isBracket$2(token, 'attribute', false);
+ }
+ function isTextStart(token) {
+ return isBracket$2(token, 'expression', true);
+ }
+ function isGroupStart(token) {
+ return isBracket$2(token, 'group', true);
+ }
+ function createLiteral$1(value) {
+ return { type: 'Literal', value };
+ }
+ function isEmpty(elem) {
+ return !elem.name && !elem.value && !elem.attributes;
+ }
+ function isChildOperator(token) {
+ return isOperator$1(token, 'child');
+ }
+ function isSiblingOperator$1(token) {
+ return isOperator$1(token, 'sibling');
+ }
+ function isClimbOperator(token) {
+ return isOperator$1(token, 'climb');
+ }
+ function isCloseOperator(token) {
+ return isOperator$1(token, 'close');
+ }
+
+ var Chars$3;
+ (function (Chars) {
+ /** `{` character */
+ Chars[Chars["CurlyBracketOpen"] = 123] = "CurlyBracketOpen";
+ /** `}` character */
+ Chars[Chars["CurlyBracketClose"] = 125] = "CurlyBracketClose";
+ /** `\\` character */
+ Chars[Chars["Escape"] = 92] = "Escape";
+ /** `=` character */
+ Chars[Chars["Equals"] = 61] = "Equals";
+ /** `[` character */
+ Chars[Chars["SquareBracketOpen"] = 91] = "SquareBracketOpen";
+ /** `]` character */
+ Chars[Chars["SquareBracketClose"] = 93] = "SquareBracketClose";
+ /** `*` character */
+ Chars[Chars["Asterisk"] = 42] = "Asterisk";
+ /** `#` character */
+ Chars[Chars["Hash"] = 35] = "Hash";
+ /** `$` character */
+ Chars[Chars["Dollar"] = 36] = "Dollar";
+ /** `-` character */
+ Chars[Chars["Dash"] = 45] = "Dash";
+ /** `.` character */
+ Chars[Chars["Dot"] = 46] = "Dot";
+ /** `/` character */
+ Chars[Chars["Slash"] = 47] = "Slash";
+ /** `:` character */
+ Chars[Chars["Colon"] = 58] = "Colon";
+ /** `!` character */
+ Chars[Chars["Excl"] = 33] = "Excl";
+ /** `@` character */
+ Chars[Chars["At"] = 64] = "At";
+ /** `_` character */
+ Chars[Chars["Underscore"] = 95] = "Underscore";
+ /** `(` character */
+ Chars[Chars["RoundBracketOpen"] = 40] = "RoundBracketOpen";
+ /** `)` character */
+ Chars[Chars["RoundBracketClose"] = 41] = "RoundBracketClose";
+ /** `+` character */
+ Chars[Chars["Sibling"] = 43] = "Sibling";
+ /** `>` character */
+ Chars[Chars["Child"] = 62] = "Child";
+ /** `^` character */
+ Chars[Chars["Climb"] = 94] = "Climb";
+ /** `'` character */
+ Chars[Chars["SingleQuote"] = 39] = "SingleQuote";
+ /** `""` character */
+ Chars[Chars["DoubleQuote"] = 34] = "DoubleQuote";
+ })(Chars$3 || (Chars$3 = {}));
+ /**
+ * If consumes escape character, sets current stream range to escaped value
+ */
+ function escaped(scanner) {
+ if (scanner.eat(Chars$3.Escape)) {
+ scanner.start = scanner.pos;
+ if (!scanner.eof()) {
+ scanner.pos++;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ function tokenize$1(source) {
+ const scanner = new Scanner(source);
+ const result = [];
+ const ctx = {
+ group: 0,
+ attribute: 0,
+ expression: 0,
+ quote: 0
+ };
+ let ch = 0;
+ let token;
+ while (!scanner.eof()) {
+ ch = scanner.peek();
+ token = getToken$1(scanner, ctx);
+ if (token) {
+ result.push(token);
+ if (token.type === 'Quote') {
+ ctx.quote = ch === ctx.quote ? 0 : ch;
+ }
+ else if (token.type === 'Bracket') {
+ ctx[token.context] += token.open ? 1 : -1;
+ }
+ }
+ else {
+ throw scanner.error('Unexpected character');
+ }
+ }
+ return result;
+ }
+ /**
+ * Returns next token from given scanner, if possible
+ */
+ function getToken$1(scanner, ctx) {
+ return field$2(scanner, ctx)
+ || repeaterPlaceholder(scanner)
+ || repeaterNumber(scanner)
+ || repeater(scanner)
+ || whiteSpace$1(scanner)
+ || literal$2(scanner, ctx)
+ || operator$1(scanner)
+ || quote(scanner)
+ || bracket$1(scanner);
+ }
+ /**
+ * Consumes literal from given scanner
+ */
+ function literal$2(scanner, ctx) {
+ const start = scanner.pos;
+ const expressionStart = ctx.expression;
+ let value = '';
+ while (!scanner.eof()) {
+ // Consume escaped sequence no matter of context
+ if (escaped(scanner)) {
+ value += scanner.current();
+ continue;
+ }
+ const ch = scanner.peek();
+ if (ch === Chars$3.Slash && !ctx.quote && !ctx.expression && !ctx.attribute) {
+ // Special case for `/` character between numbers in class names
+ const prev = scanner.string.charCodeAt(scanner.pos - 1);
+ const next = scanner.string.charCodeAt(scanner.pos + 1);
+ if (isNumber$1(prev) && isNumber$1(next)) {
+ value += scanner.string[scanner.pos++];
+ continue;
+ }
+ }
+ if (ch === ctx.quote || ch === Chars$3.Dollar || isAllowedOperator(ch, ctx)) {
+ // 1. Found matching quote
+ // 2. The `$` character has special meaning in every context
+ // 3. Depending on context, some characters should be treated as operators
+ break;
+ }
+ if (expressionStart) {
+ // Consume nested expressions, e.g. span{{foo}}
+ if (ch === Chars$3.CurlyBracketOpen) {
+ ctx.expression++;
+ }
+ else if (ch === Chars$3.CurlyBracketClose) {
+ if (ctx.expression > expressionStart) {
+ ctx.expression--;
+ }
+ else {
+ break;
+ }
+ }
+ }
+ else if (!ctx.quote) {
+ // Consuming element name
+ if (!ctx.attribute && !isElementName(ch)) {
+ break;
+ }
+ if (isAllowedSpace(ch, ctx) || isAllowedRepeater(ch, ctx) || isQuote$2(ch) || bracketType(ch)) {
+ // Stop for characters not allowed in unquoted literal
+ break;
+ }
+ }
+ value += scanner.string[scanner.pos++];
+ }
+ if (start !== scanner.pos) {
+ scanner.start = start;
+ return {
+ type: 'Literal',
+ value,
+ start,
+ end: scanner.pos
+ };
+ }
+ }
+ /**
+ * Consumes white space characters as string literal from given scanner
+ */
+ function whiteSpace$1(scanner) {
+ const start = scanner.pos;
+ if (scanner.eatWhile(isSpace)) {
+ return {
+ type: 'WhiteSpace',
+ start,
+ end: scanner.pos,
+ value: scanner.substring(start, scanner.pos)
+ };
+ }
+ }
+ /**
+ * Consumes quote from given scanner
+ */
+ function quote(scanner) {
+ const ch = scanner.peek();
+ if (isQuote$2(ch)) {
+ return {
+ type: 'Quote',
+ single: ch === Chars$3.SingleQuote,
+ start: scanner.pos++,
+ end: scanner.pos
+ };
+ }
+ }
+ /**
+ * Consumes bracket from given scanner
+ */
+ function bracket$1(scanner) {
+ const ch = scanner.peek();
+ const context = bracketType(ch);
+ if (context) {
+ return {
+ type: 'Bracket',
+ open: isOpenBracket$2(ch),
+ context,
+ start: scanner.pos++,
+ end: scanner.pos
+ };
+ }
+ }
+ /**
+ * Consumes operator from given scanner
+ */
+ function operator$1(scanner) {
+ const op = operatorType$1(scanner.peek());
+ if (op) {
+ return {
+ type: 'Operator',
+ operator: op,
+ start: scanner.pos++,
+ end: scanner.pos
+ };
+ }
+ }
+ /**
+ * Consumes node repeat token from current stream position and returns its
+ * parsed value
+ */
+ function repeater(scanner) {
+ const start = scanner.pos;
+ if (scanner.eat(Chars$3.Asterisk)) {
+ scanner.start = scanner.pos;
+ let count = 1;
+ let implicit = false;
+ if (scanner.eatWhile(isNumber$1)) {
+ count = Number(scanner.current());
+ }
+ else {
+ implicit = true;
+ }
+ return {
+ type: 'Repeater',
+ count,
+ value: 0,
+ implicit,
+ start,
+ end: scanner.pos
+ };
+ }
+ }
+ /**
+ * Consumes repeater placeholder `$#` from given scanner
+ */
+ function repeaterPlaceholder(scanner) {
+ const start = scanner.pos;
+ if (scanner.eat(Chars$3.Dollar) && scanner.eat(Chars$3.Hash)) {
+ return {
+ type: 'RepeaterPlaceholder',
+ value: void 0,
+ start,
+ end: scanner.pos
+ };
+ }
+ scanner.pos = start;
+ }
+ /**
+ * Consumes numbering token like `$` from given scanner state
+ */
+ function repeaterNumber(scanner) {
+ const start = scanner.pos;
+ if (scanner.eatWhile(Chars$3.Dollar)) {
+ const size = scanner.pos - start;
+ let reverse = false;
+ let base = 1;
+ let parent = 0;
+ if (scanner.eat(Chars$3.At)) {
+ // Consume numbering modifiers
+ while (scanner.eat(Chars$3.Climb)) {
+ parent++;
+ }
+ reverse = scanner.eat(Chars$3.Dash);
+ scanner.start = scanner.pos;
+ if (scanner.eatWhile(isNumber$1)) {
+ base = Number(scanner.current());
+ }
+ }
+ scanner.start = start;
+ return {
+ type: 'RepeaterNumber',
+ size,
+ reverse,
+ base,
+ parent,
+ start,
+ end: scanner.pos
+ };
+ }
+ }
+ function field$2(scanner, ctx) {
+ const start = scanner.pos;
+ // Fields are allowed inside expressions and attributes
+ if ((ctx.expression || ctx.attribute) && scanner.eat(Chars$3.Dollar) && scanner.eat(Chars$3.CurlyBracketOpen)) {
+ scanner.start = scanner.pos;
+ let index;
+ let name = '';
+ if (scanner.eatWhile(isNumber$1)) {
+ // It’s a field
+ index = Number(scanner.current());
+ name = scanner.eat(Chars$3.Colon) ? consumePlaceholder$2(scanner) : '';
+ }
+ else if (isAlpha$1(scanner.peek())) {
+ // It’s a variable
+ name = consumePlaceholder$2(scanner);
+ }
+ if (scanner.eat(Chars$3.CurlyBracketClose)) {
+ return {
+ type: 'Field',
+ index, name,
+ start,
+ end: scanner.pos
+ };
+ }
+ throw scanner.error('Expecting }');
+ }
+ // If we reached here then there’s no valid field here, revert
+ // back to starting position
+ scanner.pos = start;
+ }
+ /**
+ * Consumes a placeholder: value right after `:` in field. Could be empty
+ */
+ function consumePlaceholder$2(stream) {
+ const stack = [];
+ stream.start = stream.pos;
+ while (!stream.eof()) {
+ if (stream.eat(Chars$3.CurlyBracketOpen)) {
+ stack.push(stream.pos);
+ }
+ else if (stream.eat(Chars$3.CurlyBracketClose)) {
+ if (!stack.length) {
+ stream.pos--;
+ break;
+ }
+ stack.pop();
+ }
+ else {
+ stream.pos++;
+ }
+ }
+ if (stack.length) {
+ stream.pos = stack.pop();
+ throw stream.error(`Expecting }`);
+ }
+ return stream.current();
+ }
+ /**
+ * Check if given character code is an operator and it’s allowed in current context
+ */
+ function isAllowedOperator(ch, ctx) {
+ const op = operatorType$1(ch);
+ if (!op || ctx.quote || ctx.expression) {
+ // No operators inside quoted values or expressions
+ return false;
+ }
+ // Inside attributes, only `equals` is allowed
+ return !ctx.attribute || op === 'equal';
+ }
+ /**
+ * Check if given character is a space character and is allowed to be consumed
+ * as a space token in current context
+ */
+ function isAllowedSpace(ch, ctx) {
+ return isSpace(ch) && !ctx.expression;
+ }
+ /**
+ * Check if given character can be consumed as repeater in current context
+ */
+ function isAllowedRepeater(ch, ctx) {
+ return ch === Chars$3.Asterisk && !ctx.attribute && !ctx.expression;
+ }
+ /**
+ * If given character is a bracket, returns it’s type
+ */
+ function bracketType(ch) {
+ if (ch === Chars$3.RoundBracketOpen || ch === Chars$3.RoundBracketClose) {
+ return 'group';
+ }
+ if (ch === Chars$3.SquareBracketOpen || ch === Chars$3.SquareBracketClose) {
+ return 'attribute';
+ }
+ if (ch === Chars$3.CurlyBracketOpen || ch === Chars$3.CurlyBracketClose) {
+ return 'expression';
+ }
+ }
+ /**
+ * If given character is an operator, returns it’s type
+ */
+ function operatorType$1(ch) {
+ return (ch === Chars$3.Child && 'child')
+ || (ch === Chars$3.Sibling && 'sibling')
+ || (ch === Chars$3.Climb && 'climb')
+ || (ch === Chars$3.Dot && 'class')
+ || (ch === Chars$3.Hash && 'id')
+ || (ch === Chars$3.Slash && 'close')
+ || (ch === Chars$3.Equals && 'equal')
+ || void 0;
+ }
+ /**
+ * Check if given character is an open bracket
+ */
+ function isOpenBracket$2(ch) {
+ return ch === Chars$3.CurlyBracketOpen
+ || ch === Chars$3.SquareBracketOpen
+ || ch === Chars$3.RoundBracketOpen;
+ }
+ /**
+ * Check if given character is allowed in element name
+ */
+ function isElementName(ch) {
+ return isAlphaNumericWord(ch)
+ || isUmlaut(ch)
+ || ch === Chars$3.Dash
+ || ch === Chars$3.Colon
+ || ch === Chars$3.Excl;
+ }
+
+ const operators = {
+ child: '>',
+ class: '.',
+ climb: '^',
+ id: '#',
+ equal: '=',
+ close: '/',
+ sibling: '+'
+ };
+ const tokenVisitor = {
+ Literal(token) {
+ return token.value;
+ },
+ Quote(token) {
+ return token.single ? '\'' : '"';
+ },
+ Bracket(token) {
+ if (token.context === 'attribute') {
+ return token.open ? '[' : ']';
+ }
+ else if (token.context === 'expression') {
+ return token.open ? '{' : '}';
+ }
+ else {
+ return token.open ? '(' : '}';
+ }
+ },
+ Operator(token) {
+ return operators[token.operator];
+ },
+ Field(token, state) {
+ if (token.index != null) {
+ // It’s a field: by default, return TextMate-compatible field
+ return token.name
+ ? `\${${token.index}:${token.name}}`
+ : `\${${token.index}`;
+ }
+ else if (token.name) {
+ // It’s a variable
+ return state.getVariable(token.name);
+ }
+ return '';
+ },
+ RepeaterPlaceholder(token, state) {
+ // Find closest implicit repeater
+ let repeater;
+ for (let i = state.repeaters.length - 1; i >= 0; i--) {
+ if (state.repeaters[i].implicit) {
+ repeater = state.repeaters[i];
+ break;
+ }
+ }
+ state.inserted = true;
+ return state.getText(repeater && repeater.value);
+ },
+ RepeaterNumber(token, state) {
+ let value = 1;
+ const lastIx = state.repeaters.length - 1;
+ // const repeaterIx = Math.max(0, state.repeaters.length - 1 - token.parent);
+ const repeater = state.repeaters[lastIx];
+ if (repeater) {
+ value = token.reverse
+ ? token.base + repeater.count - repeater.value - 1
+ : token.base + repeater.value;
+ if (token.parent) {
+ const parentIx = Math.max(0, lastIx - token.parent);
+ if (parentIx !== lastIx) {
+ const parentRepeater = state.repeaters[parentIx];
+ value += repeater.count * parentRepeater.value;
+ }
+ }
+ }
+ let result = String(value);
+ while (result.length < token.size) {
+ result = '0' + result;
+ }
+ return result;
+ },
+ WhiteSpace(token) {
+ return token.value;
+ }
+ };
+ /**
+ * Converts given value token to string
+ */
+ function stringify$1(token, state) {
+ if (!tokenVisitor[token.type]) {
+ throw new Error(`Unknown token ${token.type}`);
+ }
+ return tokenVisitor[token.type](token, state);
+ }
+
+ const urlRegex = /^((https?:|ftp:|file:)?\/\/|(www|ftp)\.)[^ ]*$/;
+ const emailRegex = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,5}$/;
+ /**
+ * Converts given token-based abbreviation into simplified and unrolled node-based
+ * abbreviation
+ */
+ function convert(abbr, options = {}) {
+ let textInserted = false;
+ let cleanText;
+ if (options.text) {
+ if (Array.isArray(options.text)) {
+ cleanText = options.text.filter(s => s.trim());
+ }
+ else {
+ cleanText = options.text;
+ }
+ }
+ const result = {
+ type: 'Abbreviation',
+ children: convertGroup(abbr, {
+ inserted: false,
+ repeaters: [],
+ text: options.text,
+ cleanText,
+ repeatGuard: options.maxRepeat || Number.POSITIVE_INFINITY,
+ getText(pos) {
+ var _a;
+ textInserted = true;
+ let value;
+ if (Array.isArray(options.text)) {
+ if (pos !== undefined && pos >= 0 && pos < cleanText.length) {
+ return cleanText[pos];
+ }
+ value = pos !== undefined ? options.text[pos] : options.text.join('\n');
+ }
+ else {
+ value = (_a = options.text) !== null && _a !== void 0 ? _a : '';
+ }
+ return value;
+ },
+ getVariable(name) {
+ const varValue = options.variables && options.variables[name];
+ return varValue != null ? varValue : name;
+ }
+ })
+ };
+ if (options.text != null && !textInserted) {
+ // Text given but no implicitly repeated elements: insert it into
+ // deepest child
+ const deepest = deepestNode(last$1(result.children));
+ if (deepest) {
+ const text = Array.isArray(options.text) ? options.text.join('\n') : options.text;
+ insertText(deepest, text);
+ if (deepest.name === 'a' && options.href) {
+ // Automatically update value of `` element if inserting URL or email
+ insertHref(deepest, text);
+ }
+ }
+ }
+ return result;
+ }
+ /**
+ * Converts given statement to abbreviation nodes
+ */
+ function convertStatement(node, state) {
+ let result = [];
+ if (node.repeat) {
+ // Node is repeated: we should create copies of given node
+ // and supply context token with actual repeater state
+ const original = node.repeat;
+ const repeat = Object.assign({}, original);
+ repeat.count = repeat.implicit && Array.isArray(state.text)
+ ? state.cleanText.length
+ : (repeat.count || 1);
+ let items;
+ state.repeaters.push(repeat);
+ for (let i = 0; i < repeat.count; i++) {
+ repeat.value = i;
+ node.repeat = repeat;
+ items = isGroup(node)
+ ? convertGroup(node, state)
+ : convertElement(node, state);
+ if (repeat.implicit && !state.inserted) {
+ // It’s an implicit repeater but no repeater placeholders found inside,
+ // we should insert text into deepest node
+ const target = last$1(items);
+ const deepest = target && deepestNode(target);
+ if (deepest) {
+ insertText(deepest, state.getText(repeat.value));
+ }
+ }
+ result = result.concat(items);
+ // We should output at least one repeated item even if it’s reached
+ // repeat limit
+ if (--state.repeatGuard <= 0) {
+ break;
+ }
+ }
+ state.repeaters.pop();
+ node.repeat = original;
+ if (repeat.implicit) {
+ state.inserted = true;
+ }
+ }
+ else {
+ result = result.concat(isGroup(node) ? convertGroup(node, state) : convertElement(node, state));
+ }
+ return result;
+ }
+ function convertElement(node, state) {
+ let children = [];
+ const elem = {
+ type: 'AbbreviationNode',
+ name: node.name && stringifyName(node.name, state),
+ value: node.value && stringifyValue$1(node.value, state),
+ attributes: void 0,
+ children,
+ repeat: node.repeat && Object.assign({}, node.repeat),
+ selfClosing: node.selfClose,
+ };
+ let result = [elem];
+ for (const child of node.elements) {
+ children = children.concat(convertStatement(child, state));
+ }
+ if (node.attributes) {
+ elem.attributes = [];
+ for (const attr of node.attributes) {
+ elem.attributes.push(convertAttribute(attr, state));
+ }
+ }
+ // In case if current node is a text-only snippet without fields, we should
+ // put all children as siblings
+ if (!elem.name && !elem.attributes && elem.value && !elem.value.some(isField$1)) {
+ // XXX it’s unclear that `children` is not bound to `elem`
+ // due to concat operation
+ result = result.concat(children);
+ }
+ else {
+ elem.children = children;
+ }
+ return result;
+ }
+ function convertGroup(node, state) {
+ let result = [];
+ for (const child of node.elements) {
+ result = result.concat(convertStatement(child, state));
+ }
+ if (node.repeat) {
+ result = attachRepeater(result, node.repeat);
+ }
+ return result;
+ }
+ function convertAttribute(node, state) {
+ let implied = false;
+ let isBoolean = false;
+ let valueType = node.expression ? 'expression' : 'raw';
+ let value;
+ const name = node.name && stringifyName(node.name, state);
+ if (name && name[0] === '!') {
+ implied = true;
+ }
+ if (name && name[name.length - 1] === '.') {
+ isBoolean = true;
+ }
+ if (node.value) {
+ const tokens = node.value.slice();
+ if (isQuote$1(tokens[0])) {
+ // It’s a quoted value: remove quotes from output but mark attribute
+ // value as quoted
+ const quote = tokens.shift();
+ if (tokens.length && last$1(tokens).type === quote.type) {
+ tokens.pop();
+ }
+ valueType = quote.single ? 'singleQuote' : 'doubleQuote';
+ }
+ else if (isBracket$2(tokens[0], 'expression', true)) {
+ // Value is expression: remove brackets but mark value type
+ valueType = 'expression';
+ tokens.shift();
+ if (isBracket$2(last$1(tokens), 'expression', false)) {
+ tokens.pop();
+ }
+ }
+ value = stringifyValue$1(tokens, state);
+ }
+ return {
+ name: isBoolean || implied
+ ? name.slice(implied ? 1 : 0, isBoolean ? -1 : void 0)
+ : name,
+ value,
+ boolean: isBoolean,
+ implied,
+ valueType,
+ multiple: node.multiple
+ };
+ }
+ /**
+ * Converts given token list to string
+ */
+ function stringifyName(tokens, state) {
+ let str = '';
+ for (let i = 0; i < tokens.length; i++) {
+ str += stringify$1(tokens[i], state);
+ }
+ return str;
+ }
+ /**
+ * Converts given token list to value list
+ */
+ function stringifyValue$1(tokens, state) {
+ const result = [];
+ let str = '';
+ for (let i = 0, token; i < tokens.length; i++) {
+ token = tokens[i];
+ if (isField$1(token)) {
+ // We should keep original fields in output since some editors has their
+ // own syntax for field or doesn’t support fields at all so we should
+ // capture actual field location in output stream
+ if (str) {
+ result.push(str);
+ str = '';
+ }
+ result.push(token);
+ }
+ else {
+ str += stringify$1(token, state);
+ }
+ }
+ if (str) {
+ result.push(str);
+ }
+ return result;
+ }
+ function isGroup(node) {
+ return node.type === 'TokenGroup';
+ }
+ function isField$1(token) {
+ return typeof token === 'object' && token.type === 'Field' && token.index != null;
+ }
+ function last$1(arr) {
+ return arr[arr.length - 1];
+ }
+ function deepestNode(node) {
+ return node.children.length ? deepestNode(last$1(node.children)) : node;
+ }
+ function insertText(node, text) {
+ if (node.value) {
+ const lastToken = last$1(node.value);
+ if (typeof lastToken === 'string') {
+ node.value[node.value.length - 1] += text;
+ }
+ else {
+ node.value.push(text);
+ }
+ }
+ else {
+ node.value = [text];
+ }
+ }
+ function insertHref(node, text) {
+ var _a;
+ let href = '';
+ if (urlRegex.test(text)) {
+ href = text;
+ if (!/\w+:/.test(href) && !href.startsWith('//')) {
+ href = `http://${href}`;
+ }
+ }
+ else if (emailRegex.test(text)) {
+ href = `mailto:${text}`;
+ }
+ const hrefAttribute = (_a = node.attributes) === null || _a === void 0 ? void 0 : _a.find(attr => attr.name === 'href');
+ if (!hrefAttribute) {
+ if (!node.attributes) {
+ node.attributes = [];
+ }
+ node.attributes.push({ name: 'href', value: [href], valueType: 'doubleQuote' });
+ }
+ else if (!hrefAttribute.value) {
+ hrefAttribute.value = [href];
+ }
+ }
+ function attachRepeater(items, repeater) {
+ for (const item of items) {
+ if (!item.repeat) {
+ item.repeat = Object.assign({}, repeater);
+ }
+ }
+ return items;
+ }
+
+ /**
+ * Parses given abbreviation into node tree
+ */
+ function parseAbbreviation(abbr, options) {
+ try {
+ const tokens = typeof abbr === 'string' ? tokenize$1(abbr) : abbr;
+ return convert(abbreviation(tokens, options), options);
+ }
+ catch (err) {
+ if (err instanceof ScannerError && typeof abbr === 'string') {
+ err.message += `\n${abbr}\n${'-'.repeat(err.pos)}^`;
+ }
+ throw err;
+ }
+ }
+
+ var OperatorType;
+ (function (OperatorType) {
+ OperatorType["Sibling"] = "+";
+ OperatorType["Important"] = "!";
+ OperatorType["ArgumentDelimiter"] = ",";
+ OperatorType["ValueDelimiter"] = "-";
+ OperatorType["PropertyDelimiter"] = ":";
+ })(OperatorType || (OperatorType = {}));
+
+ var Chars$2;
+ (function (Chars) {
+ /** `#` character */
+ Chars[Chars["Hash"] = 35] = "Hash";
+ /** `$` character */
+ Chars[Chars["Dollar"] = 36] = "Dollar";
+ /** `-` character */
+ Chars[Chars["Dash"] = 45] = "Dash";
+ /** `.` character */
+ Chars[Chars["Dot"] = 46] = "Dot";
+ /** `:` character */
+ Chars[Chars["Colon"] = 58] = "Colon";
+ /** `,` character */
+ Chars[Chars["Comma"] = 44] = "Comma";
+ /** `!` character */
+ Chars[Chars["Excl"] = 33] = "Excl";
+ /** `@` character */
+ Chars[Chars["At"] = 64] = "At";
+ /** `%` character */
+ Chars[Chars["Percent"] = 37] = "Percent";
+ /** `_` character */
+ Chars[Chars["Underscore"] = 95] = "Underscore";
+ /** `(` character */
+ Chars[Chars["RoundBracketOpen"] = 40] = "RoundBracketOpen";
+ /** `)` character */
+ Chars[Chars["RoundBracketClose"] = 41] = "RoundBracketClose";
+ /** `{` character */
+ Chars[Chars["CurlyBracketOpen"] = 123] = "CurlyBracketOpen";
+ /** `}` character */
+ Chars[Chars["CurlyBracketClose"] = 125] = "CurlyBracketClose";
+ /** `+` character */
+ Chars[Chars["Sibling"] = 43] = "Sibling";
+ /** `'` character */
+ Chars[Chars["SingleQuote"] = 39] = "SingleQuote";
+ /** `"` character */
+ Chars[Chars["DoubleQuote"] = 34] = "DoubleQuote";
+ /** `t` character */
+ Chars[Chars["Transparent"] = 116] = "Transparent";
+ /** `/` character */
+ Chars[Chars["Slash"] = 47] = "Slash";
+ })(Chars$2 || (Chars$2 = {}));
+
+ function tokenize(abbr, isValue) {
+ let brackets = 0;
+ let token;
+ const scanner = new Scanner(abbr);
+ const tokens = [];
+ while (!scanner.eof()) {
+ token = getToken(scanner, brackets === 0 && !isValue);
+ if (!token) {
+ throw scanner.error('Unexpected character');
+ }
+ if (token.type === 'Bracket') {
+ if (!brackets && token.open) {
+ mergeTokens(scanner, tokens);
+ }
+ brackets += token.open ? 1 : -1;
+ if (brackets < 0) {
+ throw scanner.error('Unexpected bracket', token.start);
+ }
+ }
+ tokens.push(token);
+ // Forcibly consume next operator after unit-less numeric value or color:
+ // next dash `-` must be used as value delimiter
+ if (shouldConsumeDashAfter(token) && (token = operator(scanner))) {
+ tokens.push(token);
+ }
+ }
+ return tokens;
+ }
+ /**
+ * Returns next token from given scanner, if possible
+ */
+ function getToken(scanner, short) {
+ return field$1(scanner)
+ || customProperty(scanner)
+ || numberValue(scanner)
+ || colorValue(scanner)
+ || stringValue(scanner)
+ || bracket(scanner)
+ || operator(scanner)
+ || whiteSpace(scanner)
+ || literal$1(scanner, short);
+ }
+ function field$1(scanner) {
+ const start = scanner.pos;
+ if (scanner.eat(Chars$2.Dollar) && scanner.eat(Chars$2.CurlyBracketOpen)) {
+ scanner.start = scanner.pos;
+ let index;
+ let name = '';
+ if (scanner.eatWhile(isNumber$1)) {
+ // It’s a field
+ index = Number(scanner.current());
+ name = scanner.eat(Chars$2.Colon) ? consumePlaceholder$1(scanner) : '';
+ }
+ else if (isAlpha$1(scanner.peek())) {
+ // It’s a variable
+ name = consumePlaceholder$1(scanner);
+ }
+ if (scanner.eat(Chars$2.CurlyBracketClose)) {
+ return {
+ type: 'Field',
+ index, name,
+ start,
+ end: scanner.pos
+ };
+ }
+ throw scanner.error('Expecting }');
+ }
+ // If we reached here then there’s no valid field here, revert
+ // back to starting position
+ scanner.pos = start;
+ }
+ /**
+ * Consumes a placeholder: value right after `:` in field. Could be empty
+ */
+ function consumePlaceholder$1(stream) {
+ const stack = [];
+ stream.start = stream.pos;
+ while (!stream.eof()) {
+ if (stream.eat(Chars$2.CurlyBracketOpen)) {
+ stack.push(stream.pos);
+ }
+ else if (stream.eat(Chars$2.CurlyBracketClose)) {
+ if (!stack.length) {
+ stream.pos--;
+ break;
+ }
+ stack.pop();
+ }
+ else {
+ stream.pos++;
+ }
+ }
+ if (stack.length) {
+ stream.pos = stack.pop();
+ throw stream.error(`Expecting }`);
+ }
+ return stream.current();
+ }
+ /**
+ * Consumes literal from given scanner
+ * @param short Use short notation for consuming value.
+ * The difference between “short” and “full” notation is that first one uses
+ * alpha characters only and used for extracting keywords from abbreviation,
+ * while “full” notation also supports numbers and dashes
+ */
+ function literal$1(scanner, short) {
+ const start = scanner.pos;
+ if (scanner.eat(isIdentPrefix)) {
+ // SCSS or LESS variable
+ // NB a bit dirty hack: if abbreviation starts with identifier prefix,
+ // consume alpha characters only to allow embedded variables
+ scanner.eatWhile(start ? isKeyword : isLiteral$1);
+ }
+ else if (scanner.eat(isAlphaWord)) {
+ scanner.eatWhile(short ? isLiteral$1 : isKeyword);
+ }
+ else {
+ // Allow dots only at the beginning of literal
+ scanner.eat(Chars$2.Dot);
+ scanner.eatWhile(isLiteral$1);
+ }
+ if (start !== scanner.pos) {
+ scanner.start = start;
+ return createLiteral(scanner, scanner.start = start);
+ }
+ }
+ function createLiteral(scanner, start = scanner.start, end = scanner.pos) {
+ return {
+ type: 'Literal',
+ value: scanner.substring(start, end),
+ start,
+ end
+ };
+ }
+ /**
+ * Consumes numeric CSS value (number with optional unit) from current stream,
+ * if possible
+ */
+ function numberValue(scanner) {
+ const start = scanner.pos;
+ if (consumeNumber(scanner)) {
+ scanner.start = start;
+ const rawValue = scanner.current();
+ // eat unit, which can be a % or alpha word
+ scanner.start = scanner.pos;
+ scanner.eat(Chars$2.Percent) || scanner.eatWhile(isAlphaWord);
+ return {
+ type: 'NumberValue',
+ value: Number(rawValue),
+ rawValue,
+ unit: scanner.current(),
+ start,
+ end: scanner.pos
+ };
+ }
+ }
+ /**
+ * Consumes quoted string value from given scanner
+ */
+ function stringValue(scanner) {
+ const ch = scanner.peek();
+ const start = scanner.pos;
+ let finished = false;
+ if (isQuote$2(ch)) {
+ scanner.pos++;
+ while (!scanner.eof()) {
+ // Do not throw error on malformed string
+ if (scanner.eat(ch)) {
+ finished = true;
+ break;
+ }
+ else {
+ scanner.pos++;
+ }
+ }
+ scanner.start = start;
+ return {
+ type: 'StringValue',
+ value: scanner.substring(start + 1, scanner.pos - (finished ? 1 : 0)),
+ quote: ch === Chars$2.SingleQuote ? 'single' : 'double',
+ start,
+ end: scanner.pos
+ };
+ }
+ }
+ /**
+ * Consumes a color token from given string
+ */
+ function colorValue(scanner) {
+ // supported color variations:
+ // #abc → #aabbccc
+ // #0 → #000000
+ // #fff.5 → rgba(255, 255, 255, 0.5)
+ // #t → transparent
+ const start = scanner.pos;
+ if (scanner.eat(Chars$2.Hash)) {
+ const valueStart = scanner.pos;
+ let color = '';
+ let alpha = '';
+ if (scanner.eatWhile(isHex)) {
+ color = scanner.substring(valueStart, scanner.pos);
+ alpha = colorAlpha(scanner);
+ }
+ else if (scanner.eat(Chars$2.Transparent)) {
+ color = '0';
+ alpha = colorAlpha(scanner) || '0';
+ }
+ else {
+ alpha = colorAlpha(scanner);
+ }
+ if (color || alpha || scanner.eof()) {
+ const { r, g, b, a } = parseColor(color, alpha);
+ return {
+ type: 'ColorValue',
+ r, g, b, a,
+ raw: scanner.substring(start + 1, scanner.pos),
+ start,
+ end: scanner.pos
+ };
+ }
+ else {
+ // Consumed # but no actual value: invalid color value, treat it as literal
+ return createLiteral(scanner, start);
+ }
+ }
+ scanner.pos = start;
+ }
+ /**
+ * Consumes alpha value of color: `.1`
+ */
+ function colorAlpha(scanner) {
+ const start = scanner.pos;
+ if (scanner.eat(Chars$2.Dot)) {
+ scanner.start = start;
+ if (scanner.eatWhile(isNumber$1)) {
+ return scanner.current();
+ }
+ return '1';
+ }
+ return '';
+ }
+ /**
+ * Consumes white space characters as string literal from given scanner
+ */
+ function whiteSpace(scanner) {
+ const start = scanner.pos;
+ if (scanner.eatWhile(isSpace)) {
+ return {
+ type: 'WhiteSpace',
+ start,
+ end: scanner.pos
+ };
+ }
+ }
+ /**
+ * Consumes custom CSS property: --foo-bar
+ */
+ function customProperty(scanner) {
+ const start = scanner.pos;
+ if (scanner.eat(Chars$2.Dash) && scanner.eat(Chars$2.Dash)) {
+ scanner.start = start;
+ scanner.eatWhile(isKeyword);
+ return {
+ type: 'CustomProperty',
+ value: scanner.current(),
+ start,
+ end: scanner.pos
+ };
+ }
+ scanner.pos = start;
+ }
+ /**
+ * Consumes bracket from given scanner
+ */
+ function bracket(scanner) {
+ const ch = scanner.peek();
+ if (isBracket$1(ch)) {
+ return {
+ type: 'Bracket',
+ open: ch === Chars$2.RoundBracketOpen,
+ start: scanner.pos++,
+ end: scanner.pos
+ };
+ }
+ }
+ /**
+ * Consumes operator from given scanner
+ */
+ function operator(scanner) {
+ const op = operatorType(scanner.peek());
+ if (op) {
+ return {
+ type: 'Operator',
+ operator: op,
+ start: scanner.pos++,
+ end: scanner.pos
+ };
+ }
+ }
+ /**
+ * Eats number value from given stream
+ * @return Returns `true` if number was consumed
+ */
+ function consumeNumber(stream) {
+ const start = stream.pos;
+ stream.eat(Chars$2.Dash);
+ const afterNegative = stream.pos;
+ const hasDecimal = stream.eatWhile(isNumber$1);
+ const prevPos = stream.pos;
+ if (stream.eat(Chars$2.Dot)) {
+ // It’s perfectly valid to have numbers like `1.`, which enforces
+ // value to float unit type
+ const hasFloat = stream.eatWhile(isNumber$1);
+ if (!hasDecimal && !hasFloat) {
+ // Lone dot
+ stream.pos = prevPos;
+ }
+ }
+ // Edge case: consumed dash only: not a number, bail-out
+ if (stream.pos === afterNegative) {
+ stream.pos = start;
+ }
+ return stream.pos !== start;
+ }
+ function isIdentPrefix(code) {
+ return code === Chars$2.At || code === Chars$2.Dollar;
+ }
+ /**
+ * If given character is an operator, returns it’s type
+ */
+ function operatorType(ch) {
+ return (ch === Chars$2.Sibling && OperatorType.Sibling)
+ || (ch === Chars$2.Excl && OperatorType.Important)
+ || (ch === Chars$2.Comma && OperatorType.ArgumentDelimiter)
+ || (ch === Chars$2.Colon && OperatorType.PropertyDelimiter)
+ || (ch === Chars$2.Dash && OperatorType.ValueDelimiter)
+ || void 0;
+ }
+ /**
+ * Check if given code is a hex value (/0-9a-f/)
+ */
+ function isHex(code) {
+ return isNumber$1(code) || isAlpha$1(code, 65, 70); // A-F
+ }
+ function isKeyword(code) {
+ return isAlphaNumericWord(code) || code === Chars$2.Dash;
+ }
+ function isBracket$1(code) {
+ return code === Chars$2.RoundBracketOpen || code === Chars$2.RoundBracketClose;
+ }
+ function isLiteral$1(code) {
+ return isAlphaWord(code) || code === Chars$2.Percent || code === Chars$2.Slash;
+ }
+ /**
+ * Parses given color value from abbreviation into RGBA format
+ */
+ function parseColor(value, alpha) {
+ let r = '0';
+ let g = '0';
+ let b = '0';
+ let a = Number(alpha != null && alpha !== '' ? alpha : 1);
+ if (value === 't') {
+ a = 0;
+ }
+ else {
+ switch (value.length) {
+ case 0:
+ break;
+ case 1:
+ r = g = b = value + value;
+ break;
+ case 2:
+ r = g = b = value;
+ break;
+ case 3:
+ r = value[0] + value[0];
+ g = value[1] + value[1];
+ b = value[2] + value[2];
+ break;
+ default:
+ value += value;
+ r = value.slice(0, 2);
+ g = value.slice(2, 4);
+ b = value.slice(4, 6);
+ }
+ }
+ return {
+ r: parseInt(r, 16),
+ g: parseInt(g, 16),
+ b: parseInt(b, 16),
+ a
+ };
+ }
+ /**
+ * Check if scanner reader must consume dash after given token.
+ * Used in cases where user must explicitly separate numeric values
+ */
+ function shouldConsumeDashAfter(token) {
+ return token.type === 'ColorValue' || (token.type === 'NumberValue' && !token.unit);
+ }
+ /**
+ * Merges last adjacent tokens into a single literal.
+ * This function is used to overcome edge case when function name was parsed
+ * as a list of separate tokens. For example, a `scale3d()` value will be
+ * parsed as literal and number tokens (`scale` and `3d`) which is a perfectly
+ * valid abbreviation but undesired result. This function will detect last adjacent
+ * literal and number values and combine them into single literal
+ */
+ function mergeTokens(scanner, tokens) {
+ let start = 0;
+ let end = 0;
+ while (tokens.length) {
+ const token = last(tokens);
+ if (token.type === 'Literal' || token.type === 'NumberValue') {
+ start = token.start;
+ if (!end) {
+ end = token.end;
+ }
+ tokens.pop();
+ }
+ else {
+ break;
+ }
+ }
+ if (start !== end) {
+ tokens.push(createLiteral(scanner, start, end));
+ }
+ }
+ function last(arr) {
+ return arr[arr.length - 1];
+ }
+
+ function tokenScanner(tokens) {
+ return {
+ tokens,
+ start: 0,
+ pos: 0,
+ size: tokens.length
+ };
+ }
+ function peek$2(scanner) {
+ return scanner.tokens[scanner.pos];
+ }
+ function readable(scanner) {
+ return scanner.pos < scanner.size;
+ }
+ function consume$1(scanner, test) {
+ if (test(peek$2(scanner))) {
+ scanner.pos++;
+ return true;
+ }
+ return false;
+ }
+ function error(scanner, message, token = peek$2(scanner)) {
+ if (token && token.start != null) {
+ message += ` at ${token.start}`;
+ }
+ const err = new Error(message);
+ err['pos'] = token && token.start;
+ return err;
+ }
+
+ function parser(tokens, options = {}) {
+ const scanner = tokenScanner(tokens);
+ const result = [];
+ let property;
+ while (readable(scanner)) {
+ if (property = consumeProperty(scanner, options)) {
+ result.push(property);
+ }
+ else if (!consume$1(scanner, isSiblingOperator)) {
+ throw error(scanner, 'Unexpected token');
+ }
+ }
+ return result;
+ }
+ /**
+ * Consumes single CSS property
+ */
+ function consumeProperty(scanner, options) {
+ let name;
+ let important = false;
+ let valueFragment;
+ const value = [];
+ const token = peek$2(scanner);
+ const valueMode = !!options.value;
+ if (!valueMode && isLiteral(token) && !isFunctionStart(scanner)) {
+ scanner.pos++;
+ name = token.value;
+ // Consume any following value delimiter after property name
+ consume$1(scanner, isValueDelimiter);
+ }
+ // Skip whitespace right after property name, if any
+ if (valueMode) {
+ consume$1(scanner, isWhiteSpace$1);
+ }
+ while (readable(scanner)) {
+ if (consume$1(scanner, isImportant)) {
+ important = true;
+ }
+ else if (valueFragment = consumeValue(scanner, valueMode)) {
+ value.push(valueFragment);
+ }
+ else if (!consume$1(scanner, isFragmentDelimiter)) {
+ break;
+ }
+ }
+ if (name || value.length || important) {
+ return { name, value, important };
+ }
+ }
+ /**
+ * Consumes single value fragment, e.g. all value tokens before comma
+ */
+ function consumeValue(scanner, inArgument) {
+ const result = [];
+ let token;
+ let args;
+ while (readable(scanner)) {
+ token = peek$2(scanner);
+ if (isValue(token)) {
+ scanner.pos++;
+ if (isLiteral(token) && (args = consumeArguments(scanner))) {
+ result.push({
+ type: 'FunctionCall',
+ name: token.value,
+ arguments: args
+ });
+ }
+ else {
+ result.push(token);
+ }
+ }
+ else if (isValueDelimiter(token) || (inArgument && isWhiteSpace$1(token))) {
+ scanner.pos++;
+ }
+ else {
+ break;
+ }
+ }
+ return result.length
+ ? { type: 'CSSValue', value: result }
+ : void 0;
+ }
+ function consumeArguments(scanner) {
+ const start = scanner.pos;
+ if (consume$1(scanner, isOpenBracket$1)) {
+ const args = [];
+ let value;
+ while (readable(scanner) && !consume$1(scanner, isCloseBracket$1)) {
+ if (value = consumeValue(scanner, true)) {
+ args.push(value);
+ }
+ else if (!consume$1(scanner, isWhiteSpace$1) && !consume$1(scanner, isArgumentDelimiter)) {
+ throw error(scanner, 'Unexpected token');
+ }
+ }
+ scanner.start = start;
+ return args;
+ }
+ }
+ function isLiteral(token) {
+ return token && token.type === 'Literal';
+ }
+ function isBracket(token, open) {
+ return token && token.type === 'Bracket' && (open == null || token.open === open);
+ }
+ function isOpenBracket$1(token) {
+ return isBracket(token, true);
+ }
+ function isCloseBracket$1(token) {
+ return isBracket(token, false);
+ }
+ function isWhiteSpace$1(token) {
+ return token && token.type === 'WhiteSpace';
+ }
+ function isOperator(token, operator) {
+ return token && token.type === 'Operator' && (!operator || token.operator === operator);
+ }
+ function isSiblingOperator(token) {
+ return isOperator(token, OperatorType.Sibling);
+ }
+ function isArgumentDelimiter(token) {
+ return isOperator(token, OperatorType.ArgumentDelimiter);
+ }
+ function isFragmentDelimiter(token) {
+ return isArgumentDelimiter(token);
+ }
+ function isImportant(token) {
+ return isOperator(token, OperatorType.Important);
+ }
+ function isValue(token) {
+ return token.type === 'StringValue'
+ || token.type === 'ColorValue'
+ || token.type === 'NumberValue'
+ || token.type === 'Literal'
+ || token.type === 'Field'
+ || token.type === 'CustomProperty';
+ }
+ function isValueDelimiter(token) {
+ return isOperator(token, OperatorType.PropertyDelimiter)
+ || isOperator(token, OperatorType.ValueDelimiter);
+ }
+ function isFunctionStart(scanner) {
+ const t1 = scanner.tokens[scanner.pos];
+ const t2 = scanner.tokens[scanner.pos + 1];
+ return t1 && t2 && isLiteral(t1) && t2.type === 'Bracket';
+ }
+
+ /**
+ * Parses given abbreviation into property set
+ */
+ function parse$2(abbr, options) {
+ try {
+ const tokens = typeof abbr === 'string' ? tokenize(abbr, options && options.value) : abbr;
+ return parser(tokens, options);
+ }
+ catch (err) {
+ if (err instanceof ScannerError && typeof abbr === 'string') {
+ err.message += `\n${abbr}\n${'-'.repeat(err.pos)}^`;
+ }
+ throw err;
+ }
+ }
+
+ /**
+ * Merges attributes in current node: de-duplicates attributes with the same name
+ * and merges class names
+ */
+ function mergeAttributes(node, config) {
+ if (!node.attributes) {
+ return;
+ }
+ const attributes = [];
+ const lookup = {};
+ for (const attr of node.attributes) {
+ if (attr.name) {
+ const attrName = attr.name;
+ if (attrName in lookup) {
+ const prev = lookup[attrName];
+ if (attrName === 'class') {
+ prev.value = mergeValue(prev.value, attr.value, ' ');
+ }
+ else {
+ mergeDeclarations(prev, attr, config);
+ }
+ }
+ else {
+ // Create new attribute instance so we can safely modify it later
+ attributes.push(lookup[attrName] = Object.assign({}, attr));
+ }
+ }
+ else {
+ attributes.push(attr);
+ }
+ }
+ node.attributes = attributes;
+ }
+ /**
+ * Merges two token lists into single list. Adjacent strings are merged together
+ */
+ function mergeValue(prev, next, glue) {
+ if (prev && next) {
+ if (prev.length && glue) {
+ append(prev, glue);
+ }
+ for (const t of next) {
+ append(prev, t);
+ }
+ return prev;
+ }
+ const result = prev || next;
+ return result && result.slice();
+ }
+ /**
+ * Merges data from `src` attribute into `dest` and returns it
+ */
+ function mergeDeclarations(dest, src, config) {
+ dest.name = src.name;
+ if (!config.options['output.reverseAttributes']) {
+ dest.value = src.value;
+ }
+ // Keep high-priority properties
+ if (!dest.implied) {
+ dest.implied = src.implied;
+ }
+ if (!dest.boolean) {
+ dest.boolean = src.boolean;
+ }
+ if (dest.valueType !== 'expression') {
+ dest.valueType = src.valueType;
+ }
+ return dest;
+ }
+ function append(tokens, value) {
+ const lastIx = tokens.length - 1;
+ if (typeof tokens[lastIx] === 'string' && typeof value === 'string') {
+ tokens[lastIx] += value;
+ }
+ else {
+ tokens.push(value);
+ }
+ }
+
+ /**
+ * Walks over each child node of given markup abbreviation AST node (not including
+ * given one) and invokes `fn` on each node.
+ * The `fn` callback accepts context node, list of ancestor nodes and optional
+ * state object
+ */
+ function walk$1(node, fn, state) {
+ const ancestors = [node];
+ const callback = (ctx) => {
+ fn(ctx, ancestors, state);
+ ancestors.push(ctx);
+ ctx.children.forEach(callback);
+ ancestors.pop();
+ };
+ node.children.forEach(callback);
+ }
+ /**
+ * Finds first child node that matches given `callback`
+ */
+ function find$1(node, callback) {
+ for (let i = 0; i < node.children.length; i++) {
+ const child = node.children[i];
+ if (callback(child)) {
+ return child;
+ }
+ const result = find$1(child, callback);
+ if (result) {
+ return result;
+ }
+ }
+ }
+ /**
+ * Finds node which is the deepest for in current node or node itself.
+ */
+ function findDeepest(node) {
+ let parent;
+ while (node.children.length) {
+ parent = node;
+ node = node.children[node.children.length - 1];
+ }
+ return { parent, node };
+ }
+ function isNode(node) {
+ return node.type === 'AbbreviationNode';
+ }
+
+ /**
+ * Finds matching snippet from `registry` and resolves it into a parsed abbreviation.
+ * Resolved node is then updated or replaced with matched abbreviation tree.
+ *
+ * A HTML registry basically contains aliases to another Emmet abbreviations,
+ * e.g. a predefined set of name, attributes and so on, possibly a complex
+ * abbreviation with multiple elements. So we have to get snippet, parse it
+ * and recursively resolve it.
+ */
+ function resolveSnippets(abbr, config) {
+ const stack = [];
+ const reversed = config.options['output.reverseAttributes'];
+ const { warn } = config;
+ const resolve = (child) => {
+ const snippet = child.name && config.snippets[child.name];
+ // A snippet in stack means circular reference.
+ // It can be either a user error or a perfectly valid snippet like
+ // "img": "img[src alt]/", e.g. an element with predefined shape.
+ // In any case, simply stop parsing and keep element as is
+ if (!snippet || stack.includes(snippet)) {
+ return null;
+ }
+ let snippetAbbr;
+ try {
+ // User may add invlid snippet. In this case, silently bail out
+ snippetAbbr = parseAbbreviation(snippet, config);
+ }
+ catch (err) {
+ warn === null || warn === void 0 ? void 0 : warn(`Unable to parse "${snippet}" snippet`, err);
+ return null;
+ }
+ stack.push(snippet);
+ walkResolve(snippetAbbr, resolve);
+ stack.pop();
+ // Add attributes from current node into every top-level node of parsed abbreviation
+ for (const topNode of snippetAbbr.children) {
+ if (child.attributes) {
+ const from = topNode.attributes || [];
+ const to = child.attributes || [];
+ topNode.attributes = reversed ? to.concat(from) : from.concat(to);
+ }
+ mergeNodes(child, topNode);
+ }
+ return snippetAbbr;
+ };
+ walkResolve(abbr, resolve);
+ return abbr;
+ }
+ function walkResolve(node, resolve, config) {
+ let children = [];
+ for (const child of node.children) {
+ const resolved = resolve(child);
+ if (resolved) {
+ children = children.concat(resolved.children);
+ const deepest = findDeepest(resolved);
+ if (isNode(deepest.node)) {
+ deepest.node.children = deepest.node.children.concat(walkResolve(child, resolve));
+ }
+ }
+ else {
+ children.push(child);
+ child.children = walkResolve(child, resolve);
+ }
+ }
+ return node.children = children;
+ }
+ /**
+ * Adds data from first node into second node
+ */
+ function mergeNodes(from, to) {
+ if (from.selfClosing) {
+ to.selfClosing = true;
+ }
+ if (from.value != null) {
+ to.value = from.value;
+ }
+ if (from.repeat) {
+ to.repeat = from.repeat;
+ }
+ }
+
+ const expressionStart = '{';
+ const expressionEnd = '}';
+ function createOutputStream(options, level = 0) {
+ return {
+ options,
+ value: '',
+ level,
+ offset: 0,
+ line: 0,
+ column: 0
+ };
+ }
+ /**
+ * Pushes plain string into output stream without newline processing
+ */
+ function push(stream, text) {
+ const processText = stream.options['output.text'];
+ _push(stream, processText(text, stream.offset, stream.line, stream.column));
+ }
+ /**
+ * Pushes given string with possible newline formatting into output
+ */
+ function pushString(stream, value) {
+ // If given value contains newlines, we should push content line-by-line and
+ // use `pushNewline()` to maintain proper line/column state
+ const lines = splitByLines$1(value);
+ for (let i = 0, il = lines.length - 1; i <= il; i++) {
+ push(stream, lines[i]);
+ if (i !== il) {
+ pushNewline(stream, true);
+ }
+ }
+ }
+ /**
+ * Pushes new line into given output stream
+ */
+ function pushNewline(stream, indent) {
+ const baseIndent = stream.options['output.baseIndent'];
+ const newline = stream.options['output.newline'];
+ push(stream, newline + baseIndent);
+ stream.line++;
+ stream.column = baseIndent.length;
+ if (indent) {
+ pushIndent(stream, indent === true ? stream.level : indent);
+ }
+ }
+ /**
+ * Adds indentation of `size` to current output stream
+ */
+ function pushIndent(stream, size = stream.level) {
+ const indent = stream.options['output.indent'];
+ push(stream, indent.repeat(Math.max(size, 0)));
+ }
+ /**
+ * Pushes field/tabstop into output stream
+ */
+ function pushField(stream, index, placeholder) {
+ const field = stream.options['output.field'];
+ // NB: use `_push` instead of `push` to skip text processing
+ _push(stream, field(index, placeholder, stream.offset, stream.line, stream.column));
+ }
+ /**
+ * Returns given tag name formatted according to given config
+ */
+ function tagName(name, config) {
+ return strCase(name, config.options['output.tagCase']);
+ }
+ /**
+ * Returns given attribute name formatted according to given config
+ */
+ function attrName(name, config) {
+ return strCase(name, config.options['output.attributeCase']);
+ }
+ /**
+ * Returns character for quoting value of given attribute
+ */
+ function attrQuote(attr, config, isOpen) {
+ if (attr.valueType === 'expression') {
+ return isOpen ? expressionStart : expressionEnd;
+ }
+ return config.options['output.attributeQuotes'] === 'single' ? '\'' : '"';
+ }
+ /**
+ * Check if given attribute is boolean
+ */
+ function isBooleanAttribute(attr, config) {
+ return attr.boolean
+ || config.options['output.booleanAttributes'].includes((attr.name || '').toLowerCase());
+ }
+ /**
+ * Returns a token for self-closing tag, depending on current options
+ */
+ function selfClose(config) {
+ switch (config.options['output.selfClosingStyle']) {
+ case 'xhtml': return ' /';
+ case 'xml': return '/';
+ default: return '';
+ }
+ }
+ /**
+ * Check if given tag name belongs to inline-level element
+ * @param node Parsed node or tag name
+ */
+ function isInline(node, config) {
+ if (typeof node === 'string') {
+ return config.options.inlineElements.includes(node.toLowerCase());
+ }
+ // inline node is a node either with inline-level name or text-only node
+ return node.name ? isInline(node.name, config) : Boolean(node.value && !node.attributes);
+ }
+ /**
+ * Splits given text by lines
+ */
+ function splitByLines$1(text) {
+ return text.split(/\r\n|\r|\n/g);
+ }
+ /**
+ * Pushes raw string into output stream without any processing
+ */
+ function _push(stream, text) {
+ stream.value += text;
+ stream.offset += text.length;
+ stream.column += text.length;
+ }
+ function strCase(str, type) {
+ if (type) {
+ return type === 'upper' ? str.toUpperCase() : str.toLowerCase();
+ }
+ return str;
+ }
+
+ const elementMap = {
+ p: 'span',
+ ul: 'li',
+ ol: 'li',
+ table: 'tr',
+ tr: 'td',
+ tbody: 'tr',
+ thead: 'tr',
+ tfoot: 'tr',
+ colgroup: 'col',
+ select: 'option',
+ optgroup: 'option',
+ audio: 'source',
+ video: 'source',
+ object: 'param',
+ map: 'area'
+ };
+ function implicitTag(node, ancestors, config) {
+ if (!node.name && node.attributes) {
+ resolveImplicitTag(node, ancestors, config);
+ }
+ }
+ function resolveImplicitTag(node, ancestors, config) {
+ const parent = getParentElement(ancestors);
+ const contextName = config.context ? config.context.name : '';
+ const parentName = lowercase(parent ? parent.name : contextName);
+ node.name = elementMap[parentName]
+ || (isInline(parentName, config) ? 'span' : 'div');
+ }
+ function lowercase(str) {
+ return (str || '').toLowerCase();
+ }
+ /**
+ * Returns closest element node from given ancestors list
+ */
+ function getParentElement(ancestors) {
+ for (let i = ancestors.length - 1; i >= 0; i--) {
+ const elem = ancestors[i];
+ if (isNode(elem)) {
+ return elem;
+ }
+ }
+ }
+
+ var latin = {
+ "common": ["lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipisicing", "elit"],
+ "words": ["exercitationem", "perferendis", "perspiciatis", "laborum", "eveniet",
+ "sunt", "iure", "nam", "nobis", "eum", "cum", "officiis", "excepturi",
+ "odio", "consectetur", "quasi", "aut", "quisquam", "vel", "eligendi",
+ "itaque", "non", "odit", "tempore", "quaerat", "dignissimos",
+ "facilis", "neque", "nihil", "expedita", "vitae", "vero", "ipsum",
+ "nisi", "animi", "cumque", "pariatur", "velit", "modi", "natus",
+ "iusto", "eaque", "sequi", "illo", "sed", "ex", "et", "voluptatibus",
+ "tempora", "veritatis", "ratione", "assumenda", "incidunt", "nostrum",
+ "placeat", "aliquid", "fuga", "provident", "praesentium", "rem",
+ "necessitatibus", "suscipit", "adipisci", "quidem", "possimus",
+ "voluptas", "debitis", "sint", "accusantium", "unde", "sapiente",
+ "voluptate", "qui", "aspernatur", "laudantium", "soluta", "amet",
+ "quo", "aliquam", "saepe", "culpa", "libero", "ipsa", "dicta",
+ "reiciendis", "nesciunt", "doloribus", "autem", "impedit", "minima",
+ "maiores", "repudiandae", "ipsam", "obcaecati", "ullam", "enim",
+ "totam", "delectus", "ducimus", "quis", "voluptates", "dolores",
+ "molestiae", "harum", "dolorem", "quia", "voluptatem", "molestias",
+ "magni", "distinctio", "omnis", "illum", "dolorum", "voluptatum", "ea",
+ "quas", "quam", "corporis", "quae", "blanditiis", "atque", "deserunt",
+ "laboriosam", "earum", "consequuntur", "hic", "cupiditate",
+ "quibusdam", "accusamus", "ut", "rerum", "error", "minus", "eius",
+ "ab", "ad", "nemo", "fugit", "officia", "at", "in", "id", "quos",
+ "reprehenderit", "numquam", "iste", "fugiat", "sit", "inventore",
+ "beatae", "repellendus", "magnam", "recusandae", "quod", "explicabo",
+ "doloremque", "aperiam", "consequatur", "asperiores", "commodi",
+ "optio", "dolor", "labore", "temporibus", "repellat", "veniam",
+ "architecto", "est", "esse", "mollitia", "nulla", "a", "similique",
+ "eos", "alias", "dolore", "tenetur", "deleniti", "porro", "facere",
+ "maxime", "corrupti"]
+ };
+
+ var ru = {
+ "common": ["далеко-далеко", "за", "словесными", "горами", "в стране", "гласных", "и согласных", "живут", "рыбные", "тексты"],
+ "words": ["вдали", "от всех", "они", "буквенных", "домах", "на берегу", "семантика",
+ "большого", "языкового", "океана", "маленький", "ручеек", "даль",
+ "журчит", "по всей", "обеспечивает", "ее", "всеми", "необходимыми",
+ "правилами", "эта", "парадигматическая", "страна", "которой", "жаренные",
+ "предложения", "залетают", "прямо", "рот", "даже", "всемогущая",
+ "пунктуация", "не", "имеет", "власти", "над", "рыбными", "текстами",
+ "ведущими", "безорфографичный", "образ", "жизни", "однажды", "одна",
+ "маленькая", "строчка", "рыбного", "текста", "имени", "lorem", "ipsum",
+ "решила", "выйти", "большой", "мир", "грамматики", "великий", "оксмокс",
+ "предупреждал", "о", "злых", "запятых", "диких", "знаках", "вопроса",
+ "коварных", "точках", "запятой", "но", "текст", "дал", "сбить",
+ "себя", "толку", "он", "собрал", "семь", "своих", "заглавных", "букв",
+ "подпоясал", "инициал", "за", "пояс", "пустился", "дорогу",
+ "взобравшись", "первую", "вершину", "курсивных", "гор", "бросил",
+ "последний", "взгляд", "назад", "силуэт", "своего", "родного", "города",
+ "буквоград", "заголовок", "деревни", "алфавит", "подзаголовок", "своего",
+ "переулка", "грустный", "реторический", "вопрос", "скатился", "его",
+ "щеке", "продолжил", "свой", "путь", "дороге", "встретил", "рукопись",
+ "она", "предупредила", "моей", "все", "переписывается", "несколько",
+ "раз", "единственное", "что", "меня", "осталось", "это", "приставка",
+ "возвращайся", "ты", "лучше", "свою", "безопасную", "страну", "послушавшись",
+ "рукописи", "наш", "продолжил", "свой", "путь", "вскоре", "ему",
+ "повстречался", "коварный", "составитель", "рекламных", "текстов",
+ "напоивший", "языком", "речью", "заманивший", "свое", "агентство",
+ "которое", "использовало", "снова", "снова", "своих", "проектах",
+ "если", "переписали", "то", "живет", "там", "до", "сих", "пор"]
+ };
+
+ var sp = {
+ "common": ["mujer", "uno", "dolor", "más", "de", "poder", "mismo", "si"],
+ "words": ["ejercicio", "preferencia", "perspicacia", "laboral", "paño",
+ "suntuoso", "molde", "namibia", "planeador", "mirar", "demás", "oficinista", "excepción",
+ "odio", "consecuencia", "casi", "auto", "chicharra", "velo", "elixir",
+ "ataque", "no", "odio", "temporal", "cuórum", "dignísimo",
+ "facilismo", "letra", "nihilista", "expedición", "alma", "alveolar", "aparte",
+ "león", "animal", "como", "paria", "belleza", "modo", "natividad",
+ "justo", "ataque", "séquito", "pillo", "sed", "ex", "y", "voluminoso",
+ "temporalidad", "verdades", "racional", "asunción", "incidente", "marejada",
+ "placenta", "amanecer", "fuga", "previsor", "presentación", "lejos",
+ "necesariamente", "sospechoso", "adiposidad", "quindío", "pócima",
+ "voluble", "débito", "sintió", "accesorio", "falda", "sapiencia",
+ "volutas", "queso", "permacultura", "laudo", "soluciones", "entero",
+ "pan", "litro", "tonelada", "culpa", "libertario", "mosca", "dictado",
+ "reincidente", "nascimiento", "dolor", "escolar", "impedimento", "mínima",
+ "mayores", "repugnante", "dulce", "obcecado", "montaña", "enigma",
+ "total", "deletéreo", "décima", "cábala", "fotografía", "dolores",
+ "molesto", "olvido", "paciencia", "resiliencia", "voluntad", "molestias",
+ "magnífico", "distinción", "ovni", "marejada", "cerro", "torre", "y",
+ "abogada", "manantial", "corporal", "agua", "crepúsculo", "ataque", "desierto",
+ "laboriosamente", "angustia", "afortunado", "alma", "encefalograma",
+ "materialidad", "cosas", "o", "renuncia", "error", "menos", "conejo",
+ "abadía", "analfabeto", "remo", "fugacidad", "oficio", "en", "almácigo", "vos", "pan",
+ "represión", "números", "triste", "refugiado", "trote", "inventor",
+ "corchea", "repelente", "magma", "recusado", "patrón", "explícito",
+ "paloma", "síndrome", "inmune", "autoinmune", "comodidad",
+ "ley", "vietnamita", "demonio", "tasmania", "repeler", "apéndice",
+ "arquitecto", "columna", "yugo", "computador", "mula", "a", "propósito",
+ "fantasía", "alias", "rayo", "tenedor", "deleznable", "ventana", "cara",
+ "anemia", "corrupto"]
+ };
+
+ const vocabularies = { ru, sp, latin };
+ const reLorem = /^lorem([a-z]*)(\d*)(-\d*)?$/i;
+ function lorem(node, ancestors, config) {
+ let m;
+ if (node.name && (m = node.name.match(reLorem))) {
+ const db = vocabularies[m[1]] || vocabularies.latin;
+ const minWordCount = m[2] ? Math.max(1, Number(m[2])) : 30;
+ const maxWordCount = m[3] ? Math.max(minWordCount, Number(m[3].slice(1))) : minWordCount;
+ const wordCount = rand(minWordCount, maxWordCount);
+ const repeat = node.repeat || findRepeater(ancestors);
+ node.name = node.attributes = void 0;
+ node.value = [paragraph(db, wordCount, !repeat || repeat.value === 0)];
+ if (node.repeat && ancestors.length > 1) {
+ resolveImplicitTag(node, ancestors, config);
+ }
+ }
+ }
+ /**
+ * Returns random integer between from and to values
+ */
+ function rand(from, to) {
+ return Math.floor(Math.random() * (to - from) + from);
+ }
+ function sample(arr, count) {
+ const len = arr.length;
+ const iterations = Math.min(len, count);
+ const result = [];
+ while (result.length < iterations) {
+ const str = arr[rand(0, len)];
+ if (!result.includes(str)) {
+ result.push(str);
+ }
+ }
+ return result;
+ }
+ function choice(val) {
+ return val[rand(0, val.length - 1)];
+ }
+ function sentence(words, end) {
+ if (words.length) {
+ words = [capitalize(words[0])].concat(words.slice(1));
+ }
+ return words.join(' ') + (end || choice('?!...')); // more dots than question marks
+ }
+ function capitalize(word) {
+ return word[0].toUpperCase() + word.slice(1);
+ }
+ /**
+ * Insert commas at randomly selected words. This function modifies values
+ * inside `words` array
+ */
+ function insertCommas(words) {
+ if (words.length < 2) {
+ return words;
+ }
+ words = words.slice();
+ const len = words.length;
+ const hasComma = /,$/;
+ let totalCommas = 0;
+ if (len > 3 && len <= 6) {
+ totalCommas = rand(0, 1);
+ }
+ else if (len > 6 && len <= 12) {
+ totalCommas = rand(0, 2);
+ }
+ else {
+ totalCommas = rand(1, 4);
+ }
+ for (let i = 0, pos; i < totalCommas; i++) {
+ pos = rand(0, len - 2);
+ if (!hasComma.test(words[pos])) {
+ words[pos] += ',';
+ }
+ }
+ return words;
+ }
+ /**
+ * Generate a paragraph of "Lorem ipsum" text
+ * @param dict Words dictionary
+ * @param wordCount Words count in paragraph
+ * @param startWithCommon Should paragraph start with common "lorem ipsum" sentence.
+ */
+ function paragraph(dict, wordCount, startWithCommon) {
+ const result = [];
+ let totalWords = 0;
+ let words;
+ if (startWithCommon && dict.common) {
+ words = dict.common.slice(0, wordCount);
+ totalWords += words.length;
+ result.push(sentence(insertCommas(words), '.'));
+ }
+ while (totalWords < wordCount) {
+ words = sample(dict.words, Math.min(rand(2, 30), wordCount - totalWords));
+ totalWords += words.length;
+ result.push(sentence(insertCommas(words)));
+ }
+ return result.join(' ');
+ }
+ function findRepeater(ancestors) {
+ for (let i = ancestors.length - 1; i >= 0; i--) {
+ const element = ancestors[i];
+ if (element.type === 'AbbreviationNode' && element.repeat) {
+ return element.repeat;
+ }
+ }
+ }
+
+ /**
+ * XSL transformer: removes `select` attributes from certain nodes that contain
+ * children
+ */
+ function xsl(node) {
+ if (matchesName(node.name) && node.attributes && (node.children.length || node.value)) {
+ node.attributes = node.attributes.filter(isAllowed);
+ }
+ }
+ function isAllowed(attr) {
+ return attr.name !== 'select';
+ }
+ function matchesName(name) {
+ return name === 'xsl:variable' || name === 'xsl:with-param';
+ }
+
+ const reElement = /^(-+)([a-z0-9]+[a-z0-9-]*)/i;
+ const reModifier = /^(_+)([a-z0-9]+[a-z0-9-_]*)/i;
+ const blockCandidates1 = (className) => /^[a-z]\-/i.test(className);
+ const blockCandidates2 = (className) => /^[a-z]/i.test(className);
+ function bem(node, ancestors, config) {
+ expandClassNames(node);
+ expandShortNotation(node, ancestors, config);
+ }
+ /**
+ * Expands existing class names in BEM notation in given `node`.
+ * For example, if node contains `b__el_mod` class name, this method ensures
+ * that element contains `b__el` class as well
+ */
+ function expandClassNames(node) {
+ const data = getBEMData(node);
+ const classNames = [];
+ for (const cl of data.classNames) {
+ // remove all modifiers and element prefixes from class name to get a base element name
+ const ix = cl.indexOf('_');
+ if (ix > 0 && !cl.startsWith('-')) {
+ classNames.push(cl.slice(0, ix));
+ classNames.push(cl.slice(ix));
+ }
+ else {
+ classNames.push(cl);
+ }
+ }
+ if (classNames.length) {
+ data.classNames = classNames.filter(uniqueClass);
+ data.block = findBlockName(data.classNames);
+ updateClass(node, data.classNames.join(' '));
+ }
+ }
+ /**
+ * Expands short BEM notation, e.g. `-element` and `_modifier`
+ */
+ function expandShortNotation(node, ancestors, config) {
+ const data = getBEMData(node);
+ const classNames = [];
+ const { options } = config;
+ const path = ancestors.slice(1).concat(node);
+ for (let cl of data.classNames) {
+ let prefix = '';
+ let m;
+ const originalClass = cl;
+ // parse element definition (could be only one)
+ if (m = cl.match(reElement)) {
+ prefix = getBlockName(path, m[1].length, config.context) + options['bem.element'] + m[2];
+ classNames.push(prefix);
+ cl = cl.slice(m[0].length);
+ }
+ // parse modifiers definitions
+ if (m = cl.match(reModifier)) {
+ if (!prefix) {
+ prefix = getBlockName(path, m[1].length);
+ classNames.push(prefix);
+ }
+ classNames.push(`${prefix}${options['bem.modifier']}${m[2]}`);
+ cl = cl.slice(m[0].length);
+ }
+ if (cl === originalClass) {
+ // class name wasn’t modified: it’s not a BEM-specific class,
+ // add it as-is into output
+ classNames.push(originalClass);
+ }
+ }
+ const arrClassNames = classNames.filter(uniqueClass);
+ if (arrClassNames.length) {
+ updateClass(node, arrClassNames.join(' '));
+ }
+ }
+ /**
+ * Returns BEM data from given abbreviation node
+ */
+ function getBEMData(node) {
+ if (!node._bem) {
+ let classValue = '';
+ if (node.attributes) {
+ for (const attr of node.attributes) {
+ if (attr.name === 'class' && attr.value) {
+ classValue = stringifyValue(attr.value);
+ break;
+ }
+ }
+ }
+ node._bem = parseBEM(classValue);
+ }
+ return node._bem;
+ }
+ function getBEMDataFromContext(context) {
+ if (!context._bem) {
+ context._bem = parseBEM(context.attributes && context.attributes.class || '');
+ }
+ return context._bem;
+ }
+ /**
+ * Parses BEM data from given class name
+ */
+ function parseBEM(classValue) {
+ const classNames = classValue ? classValue.split(/\s+/) : [];
+ return {
+ classNames,
+ block: findBlockName(classNames)
+ };
+ }
+ /**
+ * Returns block name for given `node` by `prefix`, which tells the depth of
+ * of parent node lookup
+ */
+ function getBlockName(ancestors, depth = 0, context) {
+ const maxParentIx = 0;
+ let parentIx = Math.max(ancestors.length - depth, maxParentIx);
+ do {
+ const parent = ancestors[parentIx];
+ if (parent) {
+ const data = getBEMData(parent);
+ if (data.block) {
+ return data.block;
+ }
+ }
+ } while (maxParentIx < parentIx--);
+ if (context) {
+ const data = getBEMDataFromContext(context);
+ if (data.block) {
+ return data.block;
+ }
+ }
+ return '';
+ }
+ function findBlockName(classNames) {
+ return find(classNames, blockCandidates1)
+ || find(classNames, blockCandidates2)
+ || void 0;
+ }
+ /**
+ * Finds class name from given list which may be used as block name
+ */
+ function find(classNames, filter) {
+ for (const cl of classNames) {
+ if (reElement.test(cl) || reModifier.test(cl)) {
+ break;
+ }
+ if (filter(cl)) {
+ return cl;
+ }
+ }
+ }
+ function updateClass(node, value) {
+ for (const attr of node.attributes) {
+ if (attr.name === 'class') {
+ attr.value = [value];
+ break;
+ }
+ }
+ }
+ function stringifyValue(value) {
+ let result = '';
+ for (const t of value) {
+ result += typeof t === 'string' ? t : t.name;
+ }
+ return result;
+ }
+ function uniqueClass(item, ix, arr) {
+ return !!item && arr.indexOf(item) === ix;
+ }
+
+ /**
+ * Preprocessor of `