diff --git a/.editorconfig b/.editorconfig index aa40651..c422078 100644 --- a/.editorconfig +++ b/.editorconfig @@ -3,5 +3,6 @@ root = true [*] indent_style = space charset = utf-8 +indent_size = 4 trim_trailing_whitespace = true insert_final_newline = true diff --git a/.eslintrc b/.eslintrc index 0d57268..2df5b32 100644 --- a/.eslintrc +++ b/.eslintrc @@ -12,6 +12,7 @@ "comma-dangle": "off", "generator-star-spacing": "off", "no-return-assign": "off", + "indent": ["error", 4], "no-trailing-spaces": [ "error", { diff --git a/.npm/plugin/mss/.gitignore b/.npm/plugin/mss/.gitignore deleted file mode 100644 index 3c3629e..0000000 --- a/.npm/plugin/mss/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/.npm/plugin/mss/README b/.npm/plugin/mss/README deleted file mode 100644 index 3d49255..0000000 --- a/.npm/plugin/mss/README +++ /dev/null @@ -1,7 +0,0 @@ -This directory and the files immediately inside it are automatically generated -when you change this package's NPM dependencies. Commit the files in this -directory (npm-shrinkwrap.json, .gitignore, and this README) to source control -so that others run the same versions of sub-dependencies. - -You should NOT check in the node_modules directory that Meteor automatically -creates; if you are using git, the .gitignore file tells git to ignore it. diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fea73a..c1518c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -176,7 +176,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [2.1.3] - 2016-07-26 ### Fixed -- Updated to nathantreid:css-modules-import-path-helpers@0.1.4 to fix issues with importing files from Atmosphere packages +- Updated to wolasss:css-modules-import-path-helpers@0.1.4 to fix issues with importing files from Atmosphere packages ## [2.1.2] - 2016-07-26 ### Fixed diff --git a/LICENSE b/LICENSE index 6e75e0c..277f2b9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ The MIT License (MIT) -Copyright © 2017 Nathan Reid +Copyright © 2022 Adam Wolski Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index 6283f3c..fe5b0b9 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Or, as stated on the main CSS modules page: Install using Meteor's package management system: ```bash -meteor add nathantreid:css-modules +meteor add wolasss:css-modules ``` By default, this plugin will handle .css files as well as .m.css and .mss files (legacy). This can be adjusted in the [package options](https://github.com/nathantreid/meteor-css-modules/wiki/Package-Options). diff --git a/check-npm-package.js b/check-npm-package.js deleted file mode 100644 index a194fb4..0000000 --- a/check-npm-package.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Adapted from https://github.com/tmeasday/check-npm-versions - */ -import fs from 'fs'; -import semver from 'semver'; -import colors from 'colors'; -import logger from './logger'; -import ImportPathHelpers from './helpers/import-path-helpers'; - -export default function checkNpmPackage(packageWithVersion) { - const [ packageName, packageVersion ] = packageWithVersion.split('@'); - - if (!verifyPackageExists(packageName, packageVersion)) { - return false; - } - - return checkNpmVersion(packageName, packageVersion); -} - -function verifyPackageExists(packageName, packageVersion) { - const packagePath = `${ImportPathHelpers.basePath}/node_modules/${packageName}`; - const doesPackageExist = fs.existsSync(packagePath); - if (!doesPackageExist) { - logger.error(colors.red.bold(`Error checking npm module: ${packageName}@${packageVersion} (required by nathantreid:css-modules): module not found. Please ensure you have installed the module; here is the command:\n meteor npm install ${packageName} --save-dev\n`)); - } - - return doesPackageExist; -} - -function checkNpmVersion(name, version) { - try { - const installedVersion = require(`${name}/package.json`).version; - if (semver.satisfies(installedVersion, version)) { - return true; - } else { - logger.warn(colors.yellow.bold(`WARNING: version mismatch for ${name}; installed version is ${installedVersion}, but version ${version} is required by nathantreid:css-modules)`)); - return true; - } - } catch (e) { - logger.error(colors.red.bold(`Error checking package: ${name}@${version} (required by nathantreid:css-modules): ${e.message}`)); - return false; - } -} - diff --git a/check-npm-package.tests.js b/check-npm-package.tests.js deleted file mode 100644 index a6ca445..0000000 --- a/check-npm-package.tests.js +++ /dev/null @@ -1,58 +0,0 @@ -/* eslint-env node, mocha */ -import checkNpmPackage from './check-npm-package'; -import chai from 'chai'; -import logger from './logger'; - -const expect = chai.expect; - -describe('checkNpmPackage', function() { - it('should return false if the package is not installed', function() { - logger.test(function() { - expect(checkNpmPackage('fake-package')).to.be.false; - }); - }); - - it('should output an error if the package is not installed', function(done) { - logger.test(function() { - let receivedErrorMessage = ''; - logger.error.addHook(errorMessage => { - try { - receivedErrorMessage += errorMessage + '\n'; - return false; - } catch (e) { - done(e); - } - }); - - checkNpmPackage('fake-package@0.0.1'); - expect(receivedErrorMessage).to.have.string('Error checking npm module: fake-package@0.0.1 (required by nathantreid:css-modules): module not found. Please ensure you have installed the module; here is the command:\n meteor npm install fake-package --save-dev\n'); - done(); - }); - }); - - it('should return true if an invalid version of the package is installed', function() { - logger.test(function() { - expect(checkNpmPackage('eslint@1.0.0')).to.be.true; - }); - }); - - it('should output a warning if an invalid version of the package is installed', function(done) { - logger.test(function() { - logger.warn.addHook(errorMessage => { - try { - expect(errorMessage).to.have.string('WARNING: version mismatch for eslint; installed version is 3.3.1, but version 1.0.0 is required by nathantreid:css-modules)'); - done(); - return false; - } catch (e) { - done(e); - } - }); - - checkNpmPackage('eslint@1.0.0'); - }); - }); - - it('should return true if a matching package version is installed', function() { - expect(checkNpmPackage('eslint@^3.3.1')).to.be.true; - }); -}); diff --git a/css-modules-build-plugin.js b/css-modules-build-plugin.js index dbb7b91..b3370b2 100644 --- a/css-modules-build-plugin.js +++ b/css-modules-build-plugin.js @@ -6,15 +6,16 @@ import { Babel } from 'meteor/babel-compiler'; import recursiveUnwrapped from 'recursive-readdir'; import ScssProcessor from './scss-processor'; -import LessProcessor from './less-processor'; -import StylusProcessor from './stylus-processor'; import CssModulesProcessor from './css-modules-processor'; import IncludedFile from './included-file'; import pluginOptionsWrapper, { reloadOptions } from './options'; import getOutputPath from './get-output-path'; import profile from './helpers/profile'; import ImportPathHelpers from './helpers/import-path-helpers'; -import { stripIndent, stripIndents } from 'common-tags'; + +if (process.platform !== 'darwin' || process.arch !== 'arm64') { + return; +} let pluginOptions = pluginOptionsWrapper.options; const recursive = Meteor.wrapAsync(recursiveUnwrapped); @@ -39,7 +40,7 @@ class FileMap extends Map { export default class CssModulesBuildPlugin extends MultiFileCachingCompiler { constructor() { super({ - compilerName: 'mss', + compilerName: 'scss-compiler', defaultCacheSize: 1024 * 1024 * 10 }); this.profilingResults = { @@ -73,7 +74,11 @@ export default class CssModulesBuildPlugin extends MultiFileCachingCompiler { files = removeFilesFromExcludedFolders(files); files = addFilesFromIncludedFolders(files); - this._setupPreprocessors(); + const scssProcessor = new ScssProcessor(pluginOptions); + await scssProcessor.init(); + + this.preprocessors = []; + this.preprocessors.push(scssProcessor); this.cssModulesProcessor = new CssModulesProcessor(pluginOptions, this); await super.processFilesForTarget(files); @@ -121,19 +126,6 @@ export default class CssModulesBuildPlugin extends MultiFileCachingCompiler { }); } - _setupPreprocessors() { - this.preprocessors = []; - if (pluginOptions.enableSassCompilation) { - this.preprocessors.push(new ScssProcessor(pluginOptions)); - } - if (pluginOptions.enableStylusCompilation) { - this.preprocessors.push(new StylusProcessor(pluginOptions)); - } - if (pluginOptions.enableLessCompilation) { - this.preprocessors.push(new LessProcessor(pluginOptions)); - } - } - isRoot(inputFile) { if ('isRoot' in inputFile) { return inputFile.isRoot; @@ -156,20 +148,20 @@ export default class CssModulesBuildPlugin extends MultiFileCachingCompiler { return inputFile.isRoot; } - compileOneFile(inputFile) { + async compileOneFile(inputFile) { const filesByName = this.filesByName; this._prepInputFile(inputFile); - this._preprocessFile(inputFile, filesByName); + await this._preprocessFile(inputFile, filesByName); if (inputFile.transpileCssModules !== false) { - this._transpileCssModulesToCss(inputFile, filesByName).await(); + await this._transpileCssModulesToCss(inputFile, filesByName); } const compileResult = this._generateOutput(inputFile); return { compileResult, referencedImportPaths: inputFile.referencedImportPaths }; } - compileFromSource(source, backingInputFile, { transpileCssModules = true } = {}) { + async compileFromSource(source, backingInputFile, { transpileCssModules = true } = {}) { pluginOptions = this.reloadOptions(); if (!pluginOptions.cache.enableCache) { this._cache.reset(); @@ -186,7 +178,7 @@ export default class CssModulesBuildPlugin extends MultiFileCachingCompiler { const inputFile = this._createIncludedFile(backingInputFile.getPathInPackage(), backingInputFile, source); inputFile.transpileCssModules = transpileCssModules; - return this.compileOneFile(inputFile, this.filesByName); + return await this.compileOneFile(inputFile, this.filesByName); } _createIncludedFile(importPath, rootFile, contents) { @@ -234,7 +226,7 @@ export default class CssModulesBuildPlugin extends MultiFileCachingCompiler { const shouldAddStylesheet = inputFile.getArch().indexOf('web') === 0; compileResult.stylesheetCode = (isLazy && shouldAddStylesheet && inputFile.contents) - ? tryBabelCompile(stripIndent` + ? tryBabelCompile(` import modules from 'meteor/modules'; modules.addStyles(${JSON.stringify(inputFile.contents)});`) : ''; @@ -243,7 +235,7 @@ export default class CssModulesBuildPlugin extends MultiFileCachingCompiler { const isLegacy = inputFile.getArch() === 'web.browser.legacy'; compileResult.stylesCode = inputFile.tokens ? addMissingStylesHandler(JSON.stringify(inputFile.tokens), filePath, isLegacy) : ''; compileResult.tokensCode = inputFile.tokens - ? tryBabelCompile(stripIndent` + ? tryBabelCompile(` const styles = ${compileResult.stylesCode}; export { styles as default, styles }; exports.__esModule = true;`, diskCache) @@ -268,12 +260,12 @@ export default class CssModulesBuildPlugin extends MultiFileCachingCompiler { function addMissingStylesHandler(stylesJson, filePath, isLegacy) { if (!isLegacy && pluginOptions.missingClassErrorLevel) { const logFunction = `console.${pluginOptions.missingClassErrorLevel}`; - return `new Proxy(${stylesJson}, { + return `new Proxy(${stylesJson}, { get: function(target, name) { if (typeof name === 'symbol') { return; } - + var ignoredProperties = [ 'toJSON', 'state', @@ -283,8 +275,8 @@ export default class CssModulesBuildPlugin extends MultiFileCachingCompiler { Symbol.toStringTag, ${(pluginOptions.missingClassIgnoreList).map(JSON.stringify).join(',')} ]; - - return name in target + + return name in target ? target[name] : ignoredProperties.indexOf(name) === -1 ? ${logFunction}(name, ': CSS module class not found in ${filePath}') @@ -312,9 +304,9 @@ export default class CssModulesBuildPlugin extends MultiFileCachingCompiler { file.isPrepped = true; } - _preprocessFile(inputFile, filesByName) { + async _preprocessFile(inputFile, filesByName) { if (inputFile.preprocessor) { - inputFile.preprocessor.process(inputFile, filesByName); + await inputFile.preprocessor.process(inputFile, filesByName); } } @@ -340,7 +332,7 @@ export default class CssModulesBuildPlugin extends MultiFileCachingCompiler { } const js = (result.importsCode || result.stylesheetCode || result.tokensCode) - ? stripIndents` + ? ` ${result.importsCode} ${isWebArchitecture ? result.stylesheetCode : ''} ${result.tokensCode}` diff --git a/css-modules-build-plugin.tests.js b/css-modules-build-plugin.tests.js deleted file mode 100644 index 17a751c..0000000 --- a/css-modules-build-plugin.tests.js +++ /dev/null @@ -1,699 +0,0 @@ -/* eslint-env node, mocha */ -import './test-helpers/global-variables.stub'; -import './test-helpers/import-path-helpers.stub'; -import chai from 'chai'; -// import CssModulesBuildPlugin from './css-modules-build-plugin'; -// import { reloadOptions } from './options'; -import ImportPathHelpers from './helpers/import-path-helpers'; -// import path from 'path'; -// import logger from './logger'; -import mock from 'mock-require'; -import generateFileObject from './test-helpers/generate-file-object'; -import { reloadOptions } from './options'; -import Fiber from 'fibers'; -import Future from 'fibers/future'; -import ScssProcessor from './scss-processor'; -import CssModulesProcessor from './css-modules-processor'; -import { stripIndent } from 'common-tags'; - -const expect = chai.expect; - -mock('meteor/meteor', { - Meteor: { - wrapAsync(fn) { - return function(...args) { - const future = new Future(); - fn(...args, function(err, result) { - if (err) { - future.throw(err); - } else { - future.return(result); - } - }); - return future.wait(); - }; - } - } -}); - -const MockBabel = { compile: (code) => ({ code }) }; -mock('meteor/babel-compiler', { Babel: MockBabel }); - -import { MultiFileCachingCompiler } from './test-helpers/multi-file-caching-compiler'; -mock('meteor/caching-compiler', { MultiFileCachingCompiler }); - -const CssModulesBuildPlugin = require('./css-modules-build-plugin').default; - -describe('CssModulesBuildPlugin', function() { - describe('#isRoot', function() { - it('should return true when there are no preprocessors ', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.preprocessors = []; - - expect(buildPlugin.isRoot({})).to.be.true; - }); - - it('should pass the input file argument to preprocessors[]#shouldProcess', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - let arg; - const file = {}; - buildPlugin.preprocessors = [ - { - shouldProcess(file) { - arg = file; - } - }, - ]; - buildPlugin.isRoot(file); - - expect(arg).to.equal(file); - }); - - it('should pass the input file argument to preprocessors[]#isRoot', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - let arg; - const file = {}; - buildPlugin.preprocessors = [ - { - shouldProcess: returnsTrue, - isRoot(file) { - arg = file; - } - }, - ]; - buildPlugin.isRoot(file); - - expect(arg).to.equal(file); - }); - - it('should return true when preprocessors[]#shouldProcess returns false', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.preprocessors = [ - { shouldProcess: returnsFalse }, - { shouldProcess: returnsFalse }, - { shouldProcess: returnsFalse }, - ]; - - expect(buildPlugin.isRoot({})).to.be.true; - }); - - it('should return false when preprocessors[]#shouldProcess returns true and preprocessors[]#isRoot returns false', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.preprocessors = [ - { shouldProcess: returnsTrue, isRoot: returnsFalse }, - { shouldProcess: returnsTrue, isRoot: returnsFalse }, - { shouldProcess: returnsTrue, isRoot: returnsFalse }, - ]; - - expect(buildPlugin.isRoot({})).to.be.false; - }); - - it('should return true when preprocessors[]#shouldProcess returns true and preprocessors[]#isRoot returns true', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.preprocessors = [ - { shouldProcess: returnsTrue, isRoot: returnsFalse }, - { shouldProcess: returnsTrue, isRoot: returnsFalse }, - { shouldProcess: returnsTrue, isRoot: returnsTrue }, - ]; - - expect(buildPlugin.isRoot({})).to.be.true; - }); - - it('should not call preprocessors[]#isRoot if preprocessors[]#shouldProcess returns false', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - - let wasIsRootCalled = false; - - function calledIsRoot() { - wasIsRootCalled = true; - } - - buildPlugin.preprocessors = [ - { shouldProcess: returnsFalse, isRoot: calledIsRoot }, - { shouldProcess: returnsFalse, isRoot: calledIsRoot }, - { shouldProcess: returnsFalse, isRoot: calledIsRoot }, - ]; - - buildPlugin.isRoot({}); - - expect(wasIsRootCalled).to.be.false; - }); - - it('should call preprocessors[]#isRoot if preprocessors[]#shouldProcess returns true', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - - let isRootCalledCount = 0; - - function calledIsRoot() { - isRootCalledCount++; - } - - buildPlugin.preprocessors = [ - { shouldProcess: returnsTrue, isRoot: calledIsRoot }, - { shouldProcess: returnsTrue, isRoot: calledIsRoot }, - { shouldProcess: returnsTrue, isRoot: calledIsRoot }, - ]; - - buildPlugin.isRoot({}); - - expect(isRootCalledCount).to.equal(3); - }); - - it('should call all preprocessors[]#shouldProcess when preprocessors[]#shouldProcess or #isRoot return false', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - let callCount = 0; - - function incrementCallCount(result = false) { - if (typeof result !== 'boolean') { - result = false; - } - - callCount++; - return result; - } - - buildPlugin.preprocessors = [ - { shouldProcess: incrementCallCount }, - { shouldProcess: () => incrementCallCount(true), isRoot: () => incrementCallCount(false) }, - { shouldProcess: incrementCallCount }, - ]; - buildPlugin.isRoot({}); - expect(callCount).to.equal(4); - }); - - it('should call all preprocessors[]#isRoot when preprocessors[]#shouldProcess returns true and preprocessors[]#isRoot returns false', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - let callCount = 0; - - function incrementCallCount() { - callCount++; - return false; - } - - buildPlugin.preprocessors = [ - { shouldProcess: returnsTrue, isRoot: incrementCallCount }, - { shouldProcess: returnsTrue, isRoot: incrementCallCount }, - { shouldProcess: returnsTrue, isRoot: incrementCallCount }, - ]; - buildPlugin.isRoot({}); - expect(callCount).to.equal(3); - }); - - it('should stop calling preprocessors[]#shouldProcess when preprocessors[]#isRoot returns true', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - - const calledIsRootList = [false, false, false]; - - function calledIsRoot(index, result = false) { - calledIsRootList[index] = true; - return result; - } - - buildPlugin.preprocessors = [ - { shouldProcess: returnsTrue, isRoot: () => calledIsRoot(0, false) }, - { shouldProcess: returnsTrue, isRoot: () => calledIsRoot(1, true) }, - { shouldProcess: returnsTrue, isRoot: () => calledIsRoot(2, true) }, - ]; - - buildPlugin.isRoot({}); - - expect(calledIsRootList).to.eql([true, true, false]); - }); - }); - - describe('#compileResultSize', function() { - it('should return the length of the stringified compile result', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - - expect(buildPlugin.compileResultSize({})).to.equal(2); - expect(buildPlugin.compileResultSize({ test: 1 })).to.equal(10); - }); - }); - - describe('#getCacheKey', function() { - it('should return the inputFile`s source hash combined with the plugin options hash', function z() { - const pluginOptions = reloadOptions(); - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.optionsHash = pluginOptions.hash; - const result = `${pluginOptions.hash}...test`; - const sourceHash = 'test'; - const file = { getSourceHash: () => sourceHash }; - - expect(buildPlugin.getCacheKey(file)).to.equal(result); - }); - }); - - describe('#getAbsoluteImportPath', function() { - it('should return the inputFile`s importPath as calculated by ImportPathHelpers', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - const file = generateFileObject('./test.css'); - const result = `${ImportPathHelpers.basePath.replace(/\\/g, '/')}/test.css`; - - expect(buildPlugin.getAbsoluteImportPath(file)).to.equal(result); - }); - }); - - describe('#processFilesForTarget', function() { - it('should store the plugin options hash', function z() { - const pluginOptions = reloadOptions(); - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.processFilesForTarget([]); - expect(buildPlugin.optionsHash).to.equal(pluginOptions.hash); - }); - - it('should pass the files array to MultiFileCachingCompiler#processFilesForTarget', function z(done) { - const filesToProcess = []; - const processFilesForTarget = MultiFileCachingCompiler.prototype.processFilesForTarget; - MultiFileCachingCompiler.prototype.processFilesForTarget = function(files) { - expect(files).to.equal(filesToProcess); - - MultiFileCachingCompiler.prototype.processFilesForTarget = processFilesForTarget; - done(); - }; - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.processFilesForTarget(filesToProcess); - }); - - it('should reset the filesByName property', function z(done) { - const processFilesForTarget = MultiFileCachingCompiler.prototype.processFilesForTarget; - MultiFileCachingCompiler.prototype.processFilesForTarget = function() { - expect(this.filesByName).to.be.null; - - MultiFileCachingCompiler.prototype.processFilesForTarget = processFilesForTarget; - done(); - }; - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.filesByName = []; - buildPlugin.processFilesForTarget([]); - }); - - describe('ignorePaths', function() { - it('should remove files from excluded folders', function z(done) { - const originalFiles = [ - generateFileObject('./test.css'), - generateFileObject('./yellow.css'), - generateFileObject('./red.css'), - ]; - - const processFilesForTarget = MultiFileCachingCompiler.prototype.processFilesForTarget; - MultiFileCachingCompiler.prototype.processFilesForTarget = function(files) { - expect(files.length).to.equal(2); - expect(files[0]).to.equal(originalFiles[0]); - expect(files[1]).to.equal(originalFiles[2]); - - MultiFileCachingCompiler.prototype.processFilesForTarget = processFilesForTarget; - done(); - }; - - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.reloadOptions = () => ({ ...reloadOptions(), ignorePaths: ['yellow'] }); - buildPlugin.processFilesForTarget(originalFiles); - }); - }); - - describe('explicitIncludes', function() { - it('should add files from explicitly included folders', function z(done) { - Fiber(function() { - const originalFiles = [ - generateFileObject('./test.css'), - generateFileObject('./yellow.css'), - ]; - - const processFilesForTarget = MultiFileCachingCompiler.prototype.processFilesForTarget; - MultiFileCachingCompiler.prototype.processFilesForTarget = function(files) { - expect(files.length).to.equal(4); - expect(files[0]).to.equal(originalFiles[0]); - expect(files[1]).to.equal(originalFiles[1]); - const newFiles = files.slice(2); - newFiles.sort(function(a, b) { - if (a.path < b.path) return -1; - if (a.path > b.path) return 1; - return 0; - }); - expect(newFiles[0].path).to.equal('test-helpers/explicit-includes/a.css'); - expect(newFiles[1].path).to.equal('test-helpers/explicit-includes/b.css'); - - MultiFileCachingCompiler.prototype.processFilesForTarget = processFilesForTarget; - done(); - }; - - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.reloadOptions = () => ({ - ...reloadOptions(), - explicitIncludes: ['./test-helpers/explicit-includes'] - }); - buildPlugin.processFilesForTarget(originalFiles); - }).run(); - }); - }); - - describe('scss preprocessor', function() { - it('should not setup the scss preprocessor when enableSassCompilation is false', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.reloadOptions = () => ({ ...reloadOptions(), enableSassCompilation: false }); - buildPlugin.processFilesForTarget([]); - - expect(buildPlugin.preprocessors.length).to.equal(0); - }); - - it('should not setup the scss preprocessor when enableSassCompilation is falsy', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.reloadOptions = () => ({ ...reloadOptions(), enableSassCompilation: null }); - buildPlugin.processFilesForTarget([]); - - expect(buildPlugin.preprocessors.length).to.equal(0); - }); - - it('should setup the scss preprocessor when enableSassCompilation is true', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.reloadOptions = () => ({ ...reloadOptions(), enableSassCompilation: true }); - buildPlugin.processFilesForTarget([]); - - expect(buildPlugin.preprocessors[0]).to.be.an.instanceOf(ScssProcessor); - }); - - it('should setup the scss preprocessor when enableSassCompilation is truthy', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.reloadOptions = () => ({ ...reloadOptions(), enableSassCompilation: [] }); - buildPlugin.processFilesForTarget([]); - - expect(buildPlugin.preprocessors[0]).to.be.an.instanceOf(ScssProcessor); - }); - }); - - describe('css modules processor', function() { - it('should set up the cssModulesProcessor', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.processFilesForTarget([]); - - expect(buildPlugin.cssModulesProcessor).to.be.an.instanceOf(CssModulesProcessor); - }); - }); - }); - - describe('#compileOneFile', function() { - describe('.compileResult', function() { - describe('stylesheet', function() { - it('should return stylesheet code for web architecture', function z(done) { - Fiber(function() { - const file = generateFileObject('./test.css', '.test { color: red; }'); - const cssModulesProcessor = { process: noop }; - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.cssModulesProcessor = cssModulesProcessor; - buildPlugin.preprocessors = []; - buildPlugin.filesByName = new Map(); - - const result = buildPlugin.compileOneFile(file); - - expect(result.compileResult.stylesheet).to.equal('.test { color: red; }'); - done(); - }).run(); - }); - - it('should not return stylesheet code for lazy-loaded files', function z(done) { - Fiber(function() { - const file = generateFileObject('./imports/test.css', '.test { color: red; }'); - - const cssModulesProcessor = { process: noop }; - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.cssModulesProcessor = cssModulesProcessor; - buildPlugin.preprocessors = []; - buildPlugin.filesByName = new Map(); - - const result = buildPlugin.compileOneFile(file); - - expect('stylesheet' in result.compileResult).to.be.false; - done(); - }).run(); - }); - - it('should not return stylesheet code for server architecture', function z(done) { - Fiber(function() { - const file = generateFileObject('./test.css', '.test { color: red; }'); - file.arch = 'server'; - - const cssModulesProcessor = { process: noop }; - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.cssModulesProcessor = cssModulesProcessor; - buildPlugin.preprocessors = []; - buildPlugin.filesByName = new Map(); - - const result = buildPlugin.compileOneFile(file); - - expect('stylesheet' in result.compileResult).to.be.false; - done(); - }).run(); - }); - }); - - describe('javascript', function() { - it('should include the javascript class mappings', function z(done) { - Fiber(function() { - const file = generateFileObject('./test.css', '.test { color: red; }'); - file.tokens = { 'test': 'TEST' }; - const cssModulesProcessor = { process: noop }; - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.cssModulesProcessor = cssModulesProcessor; - buildPlugin.preprocessors = []; - buildPlugin.filesByName = new Map(); - - const result = buildPlugin.compileOneFile(file); - - expect(result.compileResult.javascript).to.equal(stripIndent` - const styles = {"test":"TEST"}; - export { styles as default, styles }; - `); - done(); - }).run(); - }); - - it('should include module imports for imported files', function z(done) { - Fiber(function() { - const file = generateFileObject('./test.css', '.test { color: red; }'); - file.imports = ['./a.css', './b/b.css']; - const cssModulesProcessor = { process: noop }; - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.cssModulesProcessor = cssModulesProcessor; - buildPlugin.preprocessors = []; - buildPlugin.filesByName = new Map(); - - const result = buildPlugin.compileOneFile(file); - - expect(result.compileResult.javascript).to.equal(stripIndent` - import './a.css'; - import './b/b.css'; - `); - done(); - }).run(); - }); - - it('should include the stylesheet for lazy-loaded files', function z(done) { - Fiber(function() { - const file = generateFileObject('./imports/test.css', '.test { color: red; }'); - const cssModulesProcessor = { process: noop }; - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.cssModulesProcessor = cssModulesProcessor; - buildPlugin.preprocessors = []; - buildPlugin.filesByName = new Map(); - - const result = buildPlugin.compileOneFile(file); - - expect(result.compileResult.javascript).to.equal(stripIndent` - import modules from 'meteor/modules'; - modules.addStyles(".test { color: red; }"); - `); - done(); - }).run(); - }); - - it('should include the module imports, stylesheet, and class mapping when applicable', function z(done) { - Fiber(function() { - const file = generateFileObject('./imports/test.css', '.test { color: red; }'); - file.tokens = { 'test': 'TEST' }; - file.imports = ['./a.css', './b/b.css']; - const cssModulesProcessor = { process: noop }; - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.cssModulesProcessor = cssModulesProcessor; - buildPlugin.preprocessors = []; - buildPlugin.filesByName = new Map(); - - const result = buildPlugin.compileOneFile(file); - - expect(result.compileResult.javascript).to.equal(stripIndent` - import './a.css'; - import './b/b.css'; - import modules from 'meteor/modules'; - modules.addStyles(".test { color: red; }"); - const styles = {"test":"TEST"}; - export { styles as default, styles }; - ` - ); - done(); - }).run(); - }); - }); - }); - - describe('.referencedImportPaths', function() { - it('should return the referencedImportPaths', function z(done) { - Fiber(function() { - const file = generateFileObject('./test.css', '.test { color: red; }'); - file.referencedImportPaths = []; - const cssModulesProcessor = { process: noop }; - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.cssModulesProcessor = cssModulesProcessor; - buildPlugin.preprocessors = []; - buildPlugin.filesByName = new Map(); - - const result = buildPlugin.compileOneFile(file); - - expect(result.referencedImportPaths).to.equal(file.referencedImportPaths); - done(); - }).run(); - }); - }); - - describe('css modules processor', function() { - it('should process the files through the css modules processor', function z(done) { - Fiber(function() { - const file = generateFileObject('./test.css'); - - const cssModulesProcessor = { - process(fileArg) { - expect(fileArg).to.equal(file); - done(); - } - }; - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.cssModulesProcessor = cssModulesProcessor; - buildPlugin.preprocessors = []; - buildPlugin.filesByName = new Map(); - buildPlugin.compileOneFile(file); - }).run(); - }); - }); - - describe('preprocessor', function() { - it('should run the files through any matching preprocessors', function z(done) { - Fiber(function() { - const file = generateFileObject('./test.css'); - - let error; - let numberOfPreprocessorsCalled = 0; - - const notMatchingPreprocessor1 = { - shouldProcess: returnsFalse, - isRoot: returnsFalse, - process: shouldNotBeCalled, - }; - - const notMatchingPreprocessor2 = { - shouldProcess: returnsFalse, - isRoot: returnsFalse, - process: shouldNotBeCalled, - }; - - const matchingPreprocessor1 = { - shouldProcess: returnsTrue, - isRoot: returnsTrue, - process(fileArg) { - expect(fileArg).to.equal(file); - numberOfPreprocessorsCalled++; - } - }; - const matchingPreprocessor2 = { - shouldProcess: returnsTrue, - isRoot: returnsTrue, - process(fileArg) { - expect(fileArg).to.equal(file); - numberOfPreprocessorsCalled++; - } - }; - - const cssModulesProcessor = { - process() { - expect(numberOfPreprocessorsCalled).to.equal(2); - done(error); - } - }; - const buildPlugin = new CssModulesBuildPlugin(); - buildPlugin.cssModulesProcessor = cssModulesProcessor; - buildPlugin.preprocessors = [ - notMatchingPreprocessor1, - matchingPreprocessor1, - matchingPreprocessor2, - notMatchingPreprocessor2, - ]; - buildPlugin.filesByName = new Map(); - buildPlugin.compileOneFile(file); - }).run(); - }); - }); - }); - - describe('#addCompileResult', function() { - it('should add the stylesheet result', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - let wasCalled = false; - - const compileResult = { - stylesheet: {}, - filePath: './test.css', - sourceMap: { test: true } - }; - const file = { - addStylesheet(stylesheet) { - wasCalled = true; - expect(stylesheet.data).to.equal(compileResult.stylesheet); - expect(stylesheet.path).to.equal('./test.css.css'); - expect(stylesheet.sourcePath).to.equal('./test.css.css'); - expect(stylesheet.sourceMap).to.equal(JSON.stringify(compileResult.sourceMap)); - expect(stylesheet.lazy).to.be.false; - } - }; - buildPlugin.addCompileResult(file, compileResult); - - expect(wasCalled).to.be.true; - }); - - it('should add the javascript result', function z() { - const buildPlugin = new CssModulesBuildPlugin(); - let wasCalled = false; - - const compileResult = { - javascript: {}, - filePath: './test.css', - sourceMap: { test: true }, - isLazy: {}, - }; - const file = { - addJavaScript(javascript) { - wasCalled = true; - expect(javascript.data).to.equal(compileResult.javascript); - expect(javascript.path).to.equal('./test.css.js'); - expect(javascript.sourcePath).to.equal('./test.css'); - expect(javascript.lazy).to.equal(compileResult.isLazy); - expect(javascript.bare).to.be.false; - } - }; - buildPlugin.addCompileResult(file, compileResult); - - expect(wasCalled).to.be.true; - }); - }); -}); - -function noop() { -} - -function returnsFalse() { - return false; -} - -function returnsTrue() { - return true; -} - -function shouldNotBeCalled() { - throw new Error('This function should not called in the tested execution path!'); -} diff --git a/css-modules-processor.js b/css-modules-processor.js index 1a62ff5..99ccf9e 100644 --- a/css-modules-processor.js +++ b/css-modules-processor.js @@ -9,171 +9,176 @@ import postcss from 'postcss'; import Parser from 'css-modules-loader-core/lib/parser'; import logger from './logger'; +if (process.platform !== 'darwin' || process.arch !== 'arm64') { + return; +} + class CssModulesError { - constructor(message) { - this.message = message; - this.name = 'CssModulesError'; - this.stack = ''; - } + constructor(message) { + this.message = message; + this.name = 'CssModulesError'; + this.stack = ''; + } } export default class CssModulesProcessor { - constructor(pluginOptions, compiler) { - this.importNumber = 0; - this.resultsByFile = {}; - this.importsByFile = {}; - this.importTreeByFile = {}; - this.filesByName = null; - this.pluginOptions = pluginOptions; - this.postcssPlugins = loadPostcssPlugins(pluginOptions); - this.compiler = compiler; - } - - async process(file, filesByName) { - this.filesByName = filesByName; - if (this.pluginOptions.passthroughPaths.some(regex => regex.test(file.getPathInPackage()))) { - return; + constructor(pluginOptions, compiler) { + this.importNumber = 0; + this.resultsByFile = {}; + this.importsByFile = {}; + this.importTreeByFile = {}; + this.filesByName = null; + this.pluginOptions = pluginOptions; + this.postcssPlugins = loadPostcssPlugins(pluginOptions); + this.compiler = compiler; } - const source = { - path: file.importPath, - contents: file.contents - }; - - const result = await this._tryProcessFile(source); - file.contents = result.css; - file.tokens = result.tokens; - file.sourceMap = result.sourceMap; - file.imports = result.imports; - file.referencedImportPaths = [...new Set([...file.referencedImportPaths, ...result.importTree])]; - } - - async _tryProcessFile(source) { - try { - return await this._processFile(source); - } catch (err) { - logger.error(`\n/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`); - logger.error(`Processing Step: CSS Modules / PostCSS compilation`); - logger.error(`Unable to compile ${source.path}\n${err}`); - logger.error(`\n/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`); - throw new CssModulesError(err.message); - } - } + async process(file, filesByName) { + this.filesByName = filesByName; + if (this.pluginOptions.passthroughPaths.some(regex => regex.test(file.getPathInPackage()))) { + return; + } - async _processFile(source, trace = String.fromCharCode(this.importNumber++)) { - const result = this.resultsByFile[source.path]; - if (result) { - return result; + const source = { + path: file.importPath, + contents: file.contents + }; + + const result = await this._tryProcessFile(source); + file.contents = result.css; + file.tokens = result.tokens; + file.sourceMap = result.sourceMap; + file.imports = result.imports; + file.referencedImportPaths = [...new Set([...file.referencedImportPaths, ...result.importTree])]; } - const { css, tokens, sourceMap } = await this._transpileFile(source.contents, source.path, trace, this._importFile.bind(this, source)); - - const imports = (this.importsByFile[source.path] || []).map(importedFile => importedFile.relativePath); - const importTree = this._generateImportTree(source.path); - return this.resultsByFile[source.path] = { - css, - tokens, - sourceMap, - imports, - importTree - }; - } - - async _importFile(parent, source, relativeTo, trace) { - relativeTo = fixRelativePath(relativeTo); - source = await loadFile(source, relativeTo, this.filesByName, this.compiler); - const parentImports = this.importsByFile[parent.path] = (this.importsByFile[parent.path] || []); - parentImports.push({ relativePath: source.originalPath, absolutePath: source.path }); - - return (await this._processFile(source, trace)).tokens; - - function fixRelativePath(relativeTo) { - return relativeTo.replace(/.*(\{.*)/, '$1').replace(/\\/g, '/'); + async _tryProcessFile(source) { + try { + return await this._processFile(source); + } catch (err) { + logger.error(`\n/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`); + logger.error(`Processing Step: CSS Modules / PostCSS compilation`); + logger.error(`Unable to compile ${source.path}\n${err}`); + logger.error(`\n/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`); + throw new CssModulesError(err.message); + } } - async function loadFile(source, relativeTo, filesByName, compiler) { - if (source instanceof Object) { - return source; - } - - const originalPath = source.replace(/^["'](.*)["']$/, '$1'); - source = ImportPathHelpers.getImportPathRelativeToFile(source, relativeTo); - return { - path: source, - originalPath, - contents: await loadFileContents(source, filesByName, compiler) - }; + async _processFile(source, trace = String.fromCharCode(this.importNumber++)) { + const result = this.resultsByFile[source.path]; + if (result) { + return result; + } + + const { css, tokens, sourceMap } = await this._transpileFile(source.contents, source.path, trace, this._importFile.bind(this, source)); + + const imports = (this.importsByFile[source.path] || []).map(importedFile => importedFile.relativePath); + const importTree = this._generateImportTree(source.path); + return this.resultsByFile[source.path] = { + css, + tokens, + sourceMap, + imports, + importTree + }; } - async function loadFileContents(importPath, filesByName, compiler) { - try { - const file = filesByName.get(importPath) || await createIncludedFile(importPath, parent, filesByName, compiler); - if (file.preprocessor && !file.isPreprocessed) { - file.preprocessor.process(file, filesByName); + async _importFile(parent, source, relativeTo, trace) { + relativeTo = fixRelativePath(relativeTo); + source = await loadFile(source, relativeTo, this.filesByName, this.compiler); + const parentImports = this.importsByFile[parent.path] = (this.importsByFile[parent.path] || []); + parentImports.push({ relativePath: source.originalPath, absolutePath: source.path }); + + return (await this._processFile(source, trace)).tokens; + + function fixRelativePath(relativeTo) { + return relativeTo.replace(/.*(\{.*)/, '$1').replace(/\\/g, '/'); } - return file.contents; - } catch (err) { - throw err; - throw new Error(`CSS Modules: unable to read file ${importPath}: ${err}`); - } - } - async function createIncludedFile(importPath, rootFile, filesByName, compiler) { - if (importPath.indexOf(ImportPathHelpers.basePath) === -1) { - importPath = ImportPathHelpers.basePath + importPath; - } - const file = new IncludedFile(importPath, rootFile); - file.importPath = ImportPathHelpers.getImportPathInPackage(file); - file.prepInputFile(); - compiler.isRoot(file); - filesByName.set(importPath, file); - - return file; + async function loadFile(source, relativeTo, filesByName, compiler) { + if (source instanceof Object) { + return source; + } + + const originalPath = source.replace(/^["'](.*)["']$/, '$1'); + source = ImportPathHelpers.getImportPathRelativeToFile(source, relativeTo); + return { + path: source, + originalPath, + contents: await loadFileContents(source, filesByName, compiler) + }; + } + + async function loadFileContents(importPath, filesByName, compiler) { + try { + const file = filesByName.get(importPath) || await createIncludedFile(importPath, parent, filesByName, compiler); + if (file.preprocessor && !file.isPreprocessed) { + file.preprocessor.process(file, filesByName); + } + return file.contents; + } catch (err) { + throw err; + throw new Error(`CSS Modules: unable to read file ${importPath}: ${err}`); + } + } + + async function createIncludedFile(importPath, rootFile, filesByName, compiler) { + if (importPath.indexOf(ImportPathHelpers.basePath) === -1) { + importPath = ImportPathHelpers.basePath + importPath; + } + const file = new IncludedFile(importPath, rootFile); + file.importPath = ImportPathHelpers.getImportPathInPackage(file); + file.prepInputFile(); + compiler.isRoot(file); + filesByName.set(importPath, file); + + return file; + } } - } - async _transpileFile(sourceString, sourcePath, trace, pathFetcher) { - const cssModulesParser = new Parser(pathFetcher, trace); - sourcePath = ImportPathHelpers.getAbsoluteImportPath(sourcePath); - const result = await postcss(this.postcssPlugins.concat([cssModulesParser.plugin])) - .process(sourceString, { - from: sourcePath, - to: getOutputPath(sourcePath, this.pluginOptions.outputCssFilePath), - map: { - inline: false, - annotation: false, - }, - parser: this.pluginOptions.parser ? require(this.pluginOptions.parser) : undefined - }); - - return { - css: result.css, - tokens: transformTokens(cssModulesParser.exportTokens, this.pluginOptions.jsClassNamingConvention), - sourceMap: result.map.toJSON() - }; - - function transformTokens(tokens, jsClassNamingConvention) { - if (!jsClassNamingConvention.camelCase) { - return tokens; - } - - let transformedTokens = {}; - let keys = Object.keys(tokens); - keys.forEach(key => transformedTokens[camelcase(key)] = tokens[key]); - return transformedTokens; + async _transpileFile(sourceString, sourcePath, trace, pathFetcher) { + const cssModulesParser = new Parser(pathFetcher, trace); + sourcePath = ImportPathHelpers.getAbsoluteImportPath(sourcePath); + + const result = await postcss(this.postcssPlugins.concat([cssModulesParser.plugin])) + .process(sourceString, { + from: sourcePath, + to: getOutputPath(sourcePath, this.pluginOptions.outputCssFilePath), + map: { + inline: false, + annotation: false, + }, + parser: this.pluginOptions.parser ? require(this.pluginOptions.parser) : undefined + }); + + return { + css: result.css, + tokens: transformTokens(cssModulesParser.exportTokens, this.pluginOptions.jsClassNamingConvention), + sourceMap: result.map.toJSON() + }; + + function transformTokens(tokens, jsClassNamingConvention) { + if (!jsClassNamingConvention.camelCase) { + return tokens; + } + + let transformedTokens = {}; + let keys = Object.keys(tokens); + keys.forEach(key => transformedTokens[camelcase(key)] = tokens[key]); + return transformedTokens; + } } - } - _generateImportTree(filePath) { - /* If we've already worked out the import tree, return it. */ - let imports = this.importTreeByFile[filePath]; - if (imports) return imports; + _generateImportTree(filePath) { + /* If we've already worked out the import tree, return it. */ + let imports = this.importTreeByFile[filePath]; + if (imports) return imports; - /* If this file has no imports, return an empty array for concatenating with referencedImportPaths. */ - imports = this.importsByFile[filePath]; - if (!imports) return []; + /* If this file has no imports, return an empty array for concatenating with referencedImportPaths. */ + imports = this.importsByFile[filePath]; + if (!imports) return []; - /* If this file has imports, traverse them to build the import tree. */ - const absoluteImports = imports.map(importedFile => importedFile.absolutePath); - return this.importTreeByFile[filePath] = absoluteImports.concat(absoluteImports.reduce((combinedImports, importPath) => combinedImports.concat(this._generateImportTree(importPath)), [])); - } + /* If this file has imports, traverse them to build the import tree. */ + const absoluteImports = imports.map(importedFile => importedFile.absolutePath); + return this.importTreeByFile[filePath] = absoluteImports.concat(absoluteImports.reduce((combinedImports, importPath) => combinedImports.concat(this._generateImportTree(importPath)), [])); + } }; diff --git a/css-modules-processor.tests.js b/css-modules-processor.tests.js deleted file mode 100644 index 2f16589..0000000 --- a/css-modules-processor.tests.js +++ /dev/null @@ -1,204 +0,0 @@ -/* eslint-env node, mocha */ -import './test-helpers/global-variables.stub'; -import chai from 'chai'; -import CssModulesProcessor from './css-modules-processor'; -import { reloadOptions } from './options'; -import { generatePreprocessedFileObject } from './test-helpers/generate-file-object'; - -const expect = chai.expect; - -describe('CssModulesProcessor', function() { - describe('#process()', function() { - describe('file.contents', function() { - it('should transpile the passed in file', async function z() { - const file = { - importPath: './test.css', - contents: '.test { color: red; } .test2 { color: blue; }', - referencedImportPaths: [], - getPathInPackage() { - return './test.css'; - } - }; - - const processor = new CssModulesProcessor({ ...reloadOptions() }); - await processor.process(file); - - expect(file.contents).to.equal('._test__test { color: red; } ._test__test2 { color: blue; }\n/*# sourceMappingURL=test.css.map */'); - }); - - it('should not transpile passthrough files', async function z() { - const file = { - importPath: './test.css', - contents: '.test { color: red; } .test2 { color: blue; }', - referencedImportPaths: [], - getPathInPackage() { - return './test.css'; - } - }; - const pluginOptions = { ...reloadOptions() }; - pluginOptions.passthroughPaths.push(/test/); - - const processor = new CssModulesProcessor(pluginOptions); - await processor.process(file); - - expect(file.contents).to.equal('.test { color: red; } .test2 { color: blue; }'); - }); - }); - - describe('file.tokens', function() { - it('should export the class names as an object', async function z() { - const file = { - importPath: './test.css', - contents: '.test { color: red; } .test-two { color: blue; }', - referencedImportPaths: [], - getPathInPackage() { - return './test.css'; - } - }; - const pluginOptions = { ...reloadOptions() }; - const processor = new CssModulesProcessor(pluginOptions); - await processor.process(file); - - expect(file.tokens).to.eql({ - 'test': '_test__test', - 'test-two': '_test__test-two' - }); - }); - - it('should camelcase the JS class names when the camelcase option is enabled', async function z() { - const file = { - importPath: './test.css', - contents: '.test { color: red; } .test-two { color: blue; }', - referencedImportPaths: [], - getPathInPackage() { - return './test.css'; - } - }; - const pluginOptions = { ...reloadOptions() }; - pluginOptions.jsClassNamingConvention.camelCase = true; - const processor = new CssModulesProcessor(pluginOptions); - await processor.process(file); - - expect(file.tokens).to.eql({ - 'test': '_test__test', - 'testTwo': '_test__test-two' - }); - }); - - it('should pull in tokens from imported files', async function z() { - const allFiles = new Map(); - addFile(generatePreprocessedFileObject('./direct-import1.css', '.test { color: red; }')); - addFile(generatePreprocessedFileObject('./direct-import2.css', '.test { composes: test from "./indirect-import.css"; }')); - addFile(generatePreprocessedFileObject('./indirect-import.css', '.test { color: red; }')); - const file = generatePreprocessedFileObject('./test.css', '.test { composes: test from "./direct-import1.css"; } .test-two { composes: test from "./direct-import2.css"; }'); - const pluginOptions = { ...reloadOptions() }; - const processor = new CssModulesProcessor(pluginOptions); - await processor.process(file, allFiles); - - expect(file.tokens).to.eql({ - 'test': '_test__test _direct_import1__test', - 'test-two': '_test__test-two _direct_import2__test _indirect_import__test' - }); - - function addFile(file) { - allFiles.set(file.importPath, file); - } - }); - }); - - describe('file.referencedImportPaths', function() { - it('should list all of the files that the current file imports', async function z() { - const allFiles = new Map(); - addFile(generatePreprocessedFileObject('./direct-import1.css', '.test { color: red; }')); - addFile(generatePreprocessedFileObject('./direct-import2.css', '.test { composes: test from "./indirect-import.css"; }')); - addFile(generatePreprocessedFileObject('./indirect-import.css', '.test { color: red; }')); - const file = generatePreprocessedFileObject('./test.css', '.test { composes: test from "./direct-import1.css"; } .test-two { composes: test from "./direct-import2.css"; }'); - const pluginOptions = { ...reloadOptions() }; - const processor = new CssModulesProcessor(pluginOptions); - await processor.process(file, allFiles); - - expect(file.referencedImportPaths).to.eql([ - 'D:/projects/meteor-css-modules/direct-import1.css', - 'D:/projects/meteor-css-modules/direct-import2.css', - 'D:/projects/meteor-css-modules/indirect-import.css' - ]); - - function addFile(file) { - allFiles.set(file.importPath, file); - } - }); - - it('should build a deduplicated list of all the files that the current file imports directly or indirectly', async function z() { - const allFiles = new Map(); - addFile(generatePreprocessedFileObject('./direct-import1.css', '.test { color: red; }')); - addFile(generatePreprocessedFileObject('./direct-import2.css', '.test { composes: test from "./indirect-import.css"; }')); - addFile(generatePreprocessedFileObject('./indirect-import.css', '.test { composes: test from "./direct-import1.css"; }')); - const file = generatePreprocessedFileObject('./test.css', '.test { composes: test from "./direct-import1.css"; } .test-two { composes: test from "./direct-import2.css"; }'); - const pluginOptions = { ...reloadOptions() }; - const processor = new CssModulesProcessor(pluginOptions); - await processor.process(file, allFiles); - - expect(file.referencedImportPaths).to.eql([ - 'D:/projects/meteor-css-modules/direct-import1.css', - 'D:/projects/meteor-css-modules/direct-import2.css', - 'D:/projects/meteor-css-modules/indirect-import.css' - ]); - - function addFile(file) { - allFiles.set(file.importPath, file); - } - }); - }); - - describe('file.imports', function() { - it('should list the files that the current file imports directly', async function z() { - const allFiles = new Map(); - addFile(generatePreprocessedFileObject('./direct-import1.css', '.test { color: red; }')); - addFile(generatePreprocessedFileObject('./direct-import2.css', '.test { composes: test from "./indirect-import.css"; }')); - addFile(generatePreprocessedFileObject('./indirect-import.css', '.test { color: red; }')); - const file = generatePreprocessedFileObject('./test.css', '.test { composes: test from "./direct-import1.css"; } .test-two { composes: test from "./direct-import2.css"; }'); - const pluginOptions = { ...reloadOptions() }; - const processor = new CssModulesProcessor(pluginOptions); - await processor.process(file, allFiles); - - expect(file.imports).to.eql([ - './direct-import1.css', - './direct-import2.css' - ]); - - function addFile(file) { - allFiles.set(file.importPath, file); - } - }); - }); - - describe('file.sourcemap', function() { - it('should generate a sourcemap', async function z() { - const file = { - importPath: './test.css', - contents: '.test { color: red; } .test2 { color: blue; }', - referencedImportPaths: [], - getPathInPackage() { - return './test.css'; - } - }; - - const processor = new CssModulesProcessor({ ...reloadOptions() }); - await processor.process(file); - - expect(file.sourceMap).to.eql({ - 'file': 'test.css', - 'mappings': 'AAAA,eAAQ,WAAW,EAAE,CAAC,gBAAS,YAAY,EAAE', - 'names': [], - 'sources': [ - 'test.css' - ], - 'sourcesContent': [ - '.test { color: red; } .test2 { color: blue; }' - ], - 'version': 3 - }); - }); - }); - }); -}); diff --git a/get-output-path.js b/get-output-path.js index d157849..5606050 100644 --- a/get-output-path.js +++ b/get-output-path.js @@ -1,36 +1,35 @@ /* globals Npm */ -import R from 'ramda'; import path from 'path'; import format from 'string-template'; export default function getOutputPath(filePath, outputPathTemplates) { - const template = getTemplate(filePath, outputPathTemplates); - const extname = path.extname(filePath); + const template = getTemplate(filePath, outputPathTemplates); + const extname = path.extname(filePath); - return format(template, { - dirname: path.dirname(filePath), - basename: path.basename(filePath, extname), - extname - }); + return format(template, { + dirname: path.dirname(filePath), + basename: path.basename(filePath, extname), + extname + }); } function getTemplate(filePath, outputPathTemplates) { - if (R.type(outputPathTemplates) === 'String') { - return outputPathTemplates; - } - - const keys = Object.keys(outputPathTemplates); - for (let index = 0; index < keys.length; index++) { - const key = keys[index]; - if (key === 'default') continue; - let val = outputPathTemplates[key]; - if (R.type(val) === 'String') { - val = outputPathTemplates[key] = { template: val, regex: new RegExp(key) }; + if (typeof outputPathTemplates === 'string') { + return outputPathTemplates; } - if (val.regex.test(filePath)) { - return val.template; + + const keys = Object.keys(outputPathTemplates); + for (let index = 0; index < keys.length; index++) { + const key = keys[index]; + if (key === 'default') continue; + let val = outputPathTemplates[key]; + if (typeof val === 'string') { + val = outputPathTemplates[key] = { template: val, regex: new RegExp(key) }; + } + if (val.regex.test(filePath)) { + return val.template; + } } - } - return outputPathTemplates['default'] || '{dirname}/{basename}{extname}'; + return outputPathTemplates['default'] || '{dirname}/{basename}{extname}'; } diff --git a/helpers/import-path-helpers.js b/helpers/import-path-helpers.js index 7954168..f2b9baf 100644 --- a/helpers/import-path-helpers.js +++ b/helpers/import-path-helpers.js @@ -1,120 +1,118 @@ import cjson from 'cjson'; import path from 'path'; -import pathIsAbsolute from 'path-is-absolute'; import fs from 'fs'; -if (!path.isAbsolute) path.isAbsolute = pathIsAbsolute; - let basePath = getBasePath(process.cwd().replace(/\\/g, '/')); function getBasePath(directory) { - if (fs.existsSync(path.join(directory, '.meteor'))) { - return directory; - } - const pathAbove = path.resolve(directory, '..'); - if (pathAbove === directory) { - console.warn('No .meteor directory found in the path tree; ImportPathHelpers.basePath must be set manually.'); - return null; - } - return getBasePath(pathAbove); + if (fs.existsSync(path.join(directory, '.meteor'))) { + return directory; + } + const pathAbove = path.resolve(directory, '..'); + if (pathAbove === directory) { + console.warn('No .meteor directory found in the path tree; ImportPathHelpers.basePath must be set manually.'); + return null; + } + return getBasePath(pathAbove); } function getAbsoluteImportPath(relativePath) { - if (path.isAbsolute(relativePath)) { - return relativePath.replace(/\\/g, '/'); - } + if (path.isAbsolute(relativePath)) { + return relativePath.replace(/\\/g, '/'); + } - return path.join(basePath, relativePath).replace(/\\/g, '/'); + return path.join(basePath, relativePath).replace(/\\/g, '/'); } export default { - init: function() { - }, - - get basePath() { - return basePath; - }, - - set basePath(newPath) { - basePath = newPath; - }, - - getImportPathInPackage: function getImportPathInPackage(inputFile) { - if (inputFile.getPathInPackage().indexOf(basePath) === 0) { - return inputFile.getPathInPackage(); - } - - if (inputFile.getPackageName() === null) { - return path.join(basePath, inputFile.getPathInPackage()).replace(/\\/g, '/'); - } - return path.join(basePath, 'packages', inputFile.getPackageName().replace(':', '_'), inputFile.getPathInPackage()).replace(/\\/g, '/'); - }, - - getAbsoluteImportPath, - - getAppRelativeImportPath: function getAppRelativeImportPath(absolutePath) { - return '/' + path.relative(basePath, absolutePath).replace(/\\/g, '/'); - }, - - getImportPathRelativeToFile: function getRealImportPath(importPath, relativeTo) { - importPath = importPath.replace(/^["']|["']$/g, ''); - if (importPath[0] === '~') { - return getModulePath(importPath.substring(1)); - } - - if (importPath[0] === '/') { - return getAbsoluteImportPath(importPath.substring(1)) - } - - // Fix relative paths that don't start with ./ - if (['.', '/', '~', '{'].indexOf(importPath[0]) === -1 && !importPath.match(/^([A-Za-z]:|meteor\/)/)) { - importPath = './' + importPath; - } - - if (importPath[0] === '.') { - importPath = path.join(path.dirname(relativeTo), importPath); - } - - importPath = convertCurlySyntaxToAbsolutePath(importPath); - importPath = convertMeteorPackageSyntaxToAbsolutePath(importPath); - - return importPath.replace(/\\/g, '/'); - - function getModulePath(importPath) { - const nodeModulesDir = `${basePath}/node_modules`; - if (importPath.match(/\//)) { - return `${nodeModulesDir}/${importPath}`; - } - - const modulePath = `${nodeModulesDir}/${importPath}`; - const mainFile = cjson.load(`${modulePath}/package.json`).main; - return `${modulePath}/${mainFile}`; - } - - function convertCurlySyntaxToAbsolutePath(importPath) { - let accPosition = importPath.indexOf('{'); - if (accPosition === -1) { - return importPath; - } - - importPath = importPath.substr(accPosition, importPath.length); - if (importPath.indexOf('{}') === 0) { - return path.join(basePath, importPath.substring(2)); - } - - return path.join(basePath, 'packages/' + importPath.replace(/\{(.*?):(.*?)}/, '$1_$2').replace(/\{(.*?)}/, '$1')); - } - - function convertMeteorPackageSyntaxToAbsolutePath(importPath) { - const packageNameMatch = importPath.match(/^meteor\/(.*?)\//); - if (!packageNameMatch) { - return importPath; - } - - const packageName = packageNameMatch[1]; - const packageOnDisk = packageName.replace(':', '_'); - const pathInPackage = importPath.substring(packageNameMatch[0].length); - return path.join(basePath, `packages/${packageOnDisk}/${pathInPackage}`); + init: function() { + }, + + get basePath() { + return basePath; + }, + + set basePath(newPath) { + basePath = newPath; + }, + + getImportPathInPackage: function getImportPathInPackage(inputFile) { + if (inputFile.getPathInPackage().indexOf(basePath) === 0) { + return inputFile.getPathInPackage(); + } + + if (inputFile.getPackageName() === null) { + return path.join(basePath, inputFile.getPathInPackage()).replace(/\\/g, '/'); + } + return path.join(basePath, 'packages', inputFile.getPackageName().replace(':', '_'), inputFile.getPathInPackage()).replace(/\\/g, '/'); + }, + + getAbsoluteImportPath, + + getAppRelativeImportPath: function getAppRelativeImportPath(absolutePath) { + return '/' + path.relative(basePath, absolutePath).replace(/\\/g, '/'); + }, + + getImportPathRelativeToFile: function getRealImportPath(importPath, relativeTo) { + // url decode the import path + importPath = importPath.replace(/^["']|["']$/g, ''); + if (importPath[0] === '~') { + return getModulePath(importPath.substring(1)); + } + + if (importPath[0] === '/') { + return getAbsoluteImportPath(importPath.substring(1)) + } + + // Fix relative paths that don't start with ./ + if (['.', '/', '~', '{'].indexOf(importPath[0]) === -1 && !importPath.match(/^([A-Za-z]:|meteor\/)/)) { + importPath = './' + importPath; + } + + if (importPath[0] === '.') { + importPath = path.join(path.dirname(relativeTo), importPath); + } + + importPath = convertCurlySyntaxToAbsolutePath(importPath); + importPath = convertMeteorPackageSyntaxToAbsolutePath(importPath); + + return importPath.replace(/\\/g, '/'); + + function getModulePath(importPath) { + const nodeModulesDir = `${basePath}/node_modules`; + if (importPath.match(/\//)) { + return `${nodeModulesDir}/${importPath}`; + } + + const modulePath = `${nodeModulesDir}/${importPath}`; + const mainFile = cjson.load(`${modulePath}/package.json`).main; + return `${modulePath}/${mainFile}`; + } + + function convertCurlySyntaxToAbsolutePath(importPath) { + let accPosition = importPath.indexOf('{'); + if (accPosition === -1) { + return importPath; + } + + importPath = importPath.substr(accPosition, importPath.length); + if (importPath.indexOf('{}') === 0) { + return path.join(basePath, importPath.substring(2)); + } + + return path.join(basePath, 'packages/' + importPath.replace(/\{(.*?):(.*?)}/, '$1_$2').replace(/\{(.*?)}/, '$1')); + } + + function convertMeteorPackageSyntaxToAbsolutePath(importPath) { + const packageNameMatch = importPath.match(/^meteor\/(.*?)\//); + if (!packageNameMatch) { + return importPath; + } + + const packageName = packageNameMatch[1]; + const packageOnDisk = packageName.replace(':', '_'); + const pathInPackage = importPath.substring(packageNameMatch[0].length); + return path.join(basePath, `packages/${packageOnDisk}/${pathInPackage}`); + } } - } }; diff --git a/helpers/import-path-helpers.tests.js b/helpers/import-path-helpers.tests.js deleted file mode 100644 index 0b2c3af..0000000 --- a/helpers/import-path-helpers.tests.js +++ /dev/null @@ -1,120 +0,0 @@ -/* eslint-env node, mocha */ -import ImportPathHelpers from './import-path-helpers'; -import chai from 'chai'; - -chai.should(); - -let basePath; -describe('ImportPathHelpers', function() { - before(function() { - basePath = ImportPathHelpers.basePath; - }); - - after(function() { - ImportPathHelpers.basePath = basePath; - }); - - describe('getAbsoluteImportPath', function() { - it('should return the input path if the input is absolute', function z() { - const inputPath = 'C:/test'; - const outputPath = ImportPathHelpers.getAbsoluteImportPath(inputPath); - outputPath.should.equal(inputPath); - }); - - it('should return an absolute path if the input is relative', function z() { - const inputPath = 'test'; - ImportPathHelpers.basePath = 'C:/'; - const outputPath = ImportPathHelpers.getAbsoluteImportPath(inputPath); - outputPath.should.equal('C:/test'); - }); - - it('should convert backslashes to forward slashes', function z() { - const inputPath = 'C:\\test'; - const outputPath = ImportPathHelpers.getAbsoluteImportPath(inputPath); - outputPath.should.equal('C:/test'); - }); - }); - - describe('getAppRelativeImportPath', function() { - it('should return the input path as an "absolute" path with the app base path as the root', function z() { - const inputPath = 'C:/test/hello'; - ImportPathHelpers.basePath = 'C:/test'; - const outputPath = ImportPathHelpers.getAppRelativeImportPath(inputPath); - outputPath.should.equal('/hello'); - }); - }); - - describe('getImportPathRelativeToFile', function() { - it('should return absolute path when supplied absolute path', function z() { - const inputPath = 'C:/test/hello'; - const relativeTo = 'C:/test/other'; - ImportPathHelpers.basePath = 'C:/test'; - const outputPath = ImportPathHelpers.getImportPathRelativeToFile(inputPath, relativeTo); - outputPath.should.equal('C:/test/hello'); - }); - - it('should return absolute path to file in same directory', function z() { - const inputPath = './hello'; - const relativeTo = 'C:/test/other'; - ImportPathHelpers.basePath = 'C:/test'; - const outputPath = ImportPathHelpers.getImportPathRelativeToFile(inputPath, relativeTo); - outputPath.should.equal('C:/test/hello'); - }); - - it('should return absolute path to file in same directory without ./', function z() { - const inputPath = 'hello'; - const relativeTo = 'C:/test/other'; - ImportPathHelpers.basePath = 'C:/test'; - const outputPath = ImportPathHelpers.getImportPathRelativeToFile(inputPath, relativeTo); - outputPath.should.equal('C:/test/hello'); - }); - - it('should return absolute path to file in parent directory', function z() { - const inputPath = '../hello'; - const relativeTo = 'C:/test/other'; - ImportPathHelpers.basePath = 'C:/test'; - const outputPath = ImportPathHelpers.getImportPathRelativeToFile(inputPath, relativeTo); - outputPath.should.equal('C:/hello'); - }); - - it('should return absolute path to file in child directory', function z() { - const inputPath = './world/hello'; - const relativeTo = 'C:/test/other'; - ImportPathHelpers.basePath = 'C:/test'; - const outputPath = ImportPathHelpers.getImportPathRelativeToFile(inputPath, relativeTo); - outputPath.should.equal('C:/test/world/hello'); - }); - - it('should return absolute path to node modules file', function z() { - const inputPath = '~world/hello'; - const relativeTo = 'C:/test/other'; - ImportPathHelpers.basePath = 'C:/test'; - const outputPath = ImportPathHelpers.getImportPathRelativeToFile(inputPath, relativeTo); - outputPath.should.equal('C:/test/node_modules/world/hello'); - }); - - it('should return absolute path to curly-syntax non-package path', function z() { - const inputPath = '{}/world/hello'; - const relativeTo = 'C:/test/other'; - ImportPathHelpers.basePath = 'C:/test'; - const outputPath = ImportPathHelpers.getImportPathRelativeToFile(inputPath, relativeTo); - outputPath.should.equal('C:/test/world/hello'); - }); - - it('should return absolute path to curly-syntax package path without colon', function z() { - const inputPath = '{my_package}/world/hello'; - const relativeTo = 'C:/test/other'; - ImportPathHelpers.basePath = 'C:/test'; - const outputPath = ImportPathHelpers.getImportPathRelativeToFile(inputPath, relativeTo); - outputPath.should.equal('C:/test/packages/my_package/world/hello'); - }); - - it('should return absolute path to curly-syntax package path without colon', function z() { - const inputPath = '{my:package}/world/hello'; - const relativeTo = 'C:/test/other'; - ImportPathHelpers.basePath = 'C:/test'; - const outputPath = ImportPathHelpers.getImportPathRelativeToFile(inputPath, relativeTo); - outputPath.should.equal('C:/test/packages/my_package/world/hello'); - }); - }); -}); diff --git a/helpers/profile.js b/helpers/profile.js index 3d89b0d..ecc95de 100644 --- a/helpers/profile.js +++ b/helpers/profile.js @@ -5,22 +5,22 @@ let isFirstLogStatement = true; /* clock function thanks to NextLocal: http://stackoverflow.com/a/34970550/1090626 */ function clock(start) { - if (!start) return process.hrtime(); - var end = process.hrtime(start); - return Math.round((end[0] * 1000) + (end[1] / 1000000)); + if (!start) return process.hrtime(); + var end = process.hrtime(start); + return Math.round((end[0] * 1000) + (end[1] / 1000000)); } export default function profile(start, message) { - if (!pluginOptions.enableProfiling) return; + if (!pluginOptions.enableProfiling) return; - const time = clock(start); - if (start !== undefined) { - if (isFirstLogStatement) { - isFirstLogStatement = false; - console.log(''); + const time = clock(start); + if (start !== undefined) { + if (isFirstLogStatement) { + isFirstLogStatement = false; + console.log(''); + } + console.log(`${message} ${time}ms`); } - console.log(`${message} ${time}ms`); - } - return time; + return time; } diff --git a/included-file.js b/included-file.js index 2b4cb6e..e697383 100644 --- a/included-file.js +++ b/included-file.js @@ -1,6 +1,6 @@ import path from 'path'; import fs from 'fs'; -import sha1 from './sha1'; +import { sha1 } from './utils'; import pluginOptionsWrapper from './options'; const pluginOptions = pluginOptionsWrapper.options; @@ -76,4 +76,3 @@ export default class IncludedFile { } }; - diff --git a/less-processor.js b/less-processor.js deleted file mode 100644 index f525331..0000000 --- a/less-processor.js +++ /dev/null @@ -1,76 +0,0 @@ -import Future from 'fibers/future'; -import path from 'path'; -import logger from './logger'; - -export default class LessProcessor { - constructor(pluginOptions) { - this.fileCache = {}; - this.filesByName = null; - this.pluginOptions = pluginOptions; - this.less = pluginOptions.enableLessCompilation ? require('less') : null; - } - - isRoot(inputFile) { - const fileOptions = inputFile.getFileOptions(); - if (fileOptions.hasOwnProperty('isImport')) { - return !fileOptions.isImport; - } - - return !hasUnderscore(inputFile.getPathInPackage()); - - function hasUnderscore(file) { - return path.basename(file)[0] === '_'; - } - } - - shouldProcess(file) { - const lessCompilationExtensions = this.pluginOptions.enableLessCompilation; - if (!lessCompilationExtensions || typeof lessCompilationExtensions === 'boolean') { - return lessCompilationExtensions; - } - - return lessCompilationExtensions.some((extension) => file.getPathInPackage().endsWith(extension)); - } - - process(file, filesByName) { - this.filesByName = filesByName; - try { - this._process(file); - } catch (err) { - const numberOfAdditionalLines = this.pluginOptions.globalVariablesTextLineCount - ? this.pluginOptions.globalVariablesTextLineCount + 1 - : 0; - const adjustedLineNumber = err.line - numberOfAdditionalLines; - logger.error(`\n/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`); - logger.error(`Processing Step: Less compilation`); - logger.error(`Unable to compile ${file.importPath}\nLine: ${adjustedLineNumber}, Column: ${err.column}\n${err}`); - logger.error(`\n/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`); - throw err; - } - } - - _process(file) { - if (file.isPreprocessed) return; - - const {css, map} = this._transpile(file); - - file.contents = css; - file.sourceMap = map; - file.isPreprocessed = true; - } - - _transpile(sourceFile) { - const future = new Future(); - const options = { - filename: sourceFile.importPath, - sourceMap: { - comment: false - } - }; - - this.less.render(sourceFile.rawContents, options) - .then(output => future.return(output), error => future.throw(error)); - - return future.wait(); - } -}; diff --git a/logger.js b/logger.js index b8d96ac..f78f70c 100644 --- a/logger.js +++ b/logger.js @@ -1,33 +1,33 @@ let suppressAllOutput = false; const logFunctions = [ - 'log', - 'error', - 'warn', - 'info' + 'log', + 'error', + 'warn', + 'info' ]; const logger = { - async test(cb) { - suppressAllOutput = true; - const result = await cb(); - suppressAllOutput = false; + async test(cb) { + suppressAllOutput = true; + const result = await cb(); + suppressAllOutput = false; - logFunctions.forEach(logFunction => logger[logFunction].removeAllHooks()); + logFunctions.forEach(logFunction => logger[logFunction].removeAllHooks()); - if (result) return result; - }, + if (result) return result; + }, }; logger.logException = function logException(err) { - logger.error(stringifyError(err, null, 2)); - - /* Bryan Larsen, http://stackoverflow.com/a/20405830/1090626 */ - function stringifyError(err, filter, space) { - var plainObject = {}; - Object.getOwnPropertyNames(err).forEach(function(key) { - plainObject[key] = err[key]; - }); - return JSON.stringify(plainObject, filter, space); - }; + logger.error(stringifyError(err, null, 2)); + + /* Bryan Larsen, http://stackoverflow.com/a/20405830/1090626 */ + function stringifyError(err, filter, space) { + var plainObject = {}; + Object.getOwnPropertyNames(err).forEach(function(key) { + plainObject[key] = err[key]; + }); + return JSON.stringify(plainObject, filter, space); + }; }; export default logger; @@ -35,15 +35,15 @@ export default logger; logFunctions.forEach(logFunction => logger[logFunction] = generateOutputFunction(logFunction)); function generateOutputFunction(logFunction) { - const hooks = []; - const fn = function callLogFunction(...args) { - const suppressMessage = hooks.some(hookFn => hookFn(...args) === false); - if (suppressAllOutput || suppressMessage) return; - console[logFunction](...args); - }; - fn.addHook = hookFn => hooks.push(hookFn); - fn.removeHook = hookFn => hooks.splice(hooks.indexOf(hookFn), 1); - fn.removeAllHooks = () => hooks.length = 0; - - return fn; + const hooks = []; + const fn = function callLogFunction(...args) { + const suppressMessage = hooks.some(hookFn => hookFn(...args) === false); + if (suppressAllOutput || suppressMessage) return; + console[logFunction](...args); + }; + fn.addHook = hookFn => hooks.push(hookFn); + fn.removeHook = hookFn => hooks.splice(hooks.indexOf(hookFn), 1); + fn.removeAllHooks = () => hooks.length = 0; + + return fn; } diff --git a/options.js b/options.js index ba2597a..7185fd9 100644 --- a/options.js +++ b/options.js @@ -1,9 +1,8 @@ -import { Meteor } from 'meteor/meteor'; +// import { Meteor } from 'meteor/meteor'; -import R from 'ramda'; -import checkNpmPackage from './check-npm-package'; +import * as R from 'ramda'; import { createReplacer } from './text-replacer'; -import sha1 from './sha1'; +import { sha1 } from './utils'; import cjson from 'cjson'; import ImportPathHelpers from './helpers/import-path-helpers'; import jsonToRegex from 'json-to-regex'; @@ -21,227 +20,184 @@ export { loadOptions as reloadOptions }; export default pluginOptions; function getDefaultOptions() { - return { - cache: { - enableCache: true, - }, - cssClassNamingConvention: { - replacements: [] - }, - defaultIgnorePath: 'node_modules/.*/(examples|docs|test|tests)/', - enableDebugLog: false, - enableProfiling: false, - enableSassCompilation: ['scss', 'sass'], - enableLessCompilation: ['less'], - enableStylusCompilation: ['styl', 'm.styl'], - explicitIncludes: [], - extensions: ['css', 'm.css', 'mss'], - filenames: [], - globalVariablesText: '', - ignorePaths: [], - includePaths: [], - jsClassNamingConvention: { - camelCase: false - }, - missingClassErrorLevel: 'warn', - missingClassIgnoreList: [], - outputJsFilePath: '{dirname}/{basename}{extname}', - outputCssFilePath: '{dirname}/{basename}{extname}', - passthroughPaths: [], - specificArchitecture: 'web', - hash: null - }; + return { + cache: { + enableCache: true, + }, + cssClassNamingConvention: { + replacements: [] + }, + defaultIgnorePath: 'node_modules/.*/(examples|docs|test|tests)/', + enableDebugLog: false, + enableProfiling: false, + enableSassCompilation: ['scss', 'sass'], + explicitIncludes: [], + extensions: ['m.css', 'mss'], + filenames: [], + globalVariablesText: '', + ignorePaths: [], + includePaths: [], + jsClassNamingConvention: { + camelCase: false + }, + missingClassErrorLevel: 'warn', + missingClassIgnoreList: [], + outputJsFilePath: '{dirname}/{basename}{extname}', + outputCssFilePath: '{dirname}/{basename}{extname}', + passthroughPaths: [], + specificArchitecture: 'web', + hash: null + }; } export function getHash() { - return pluginOptions.options.hash; + return pluginOptions.options.hash; } function loadOptions() { - let options = null; - if (fs.existsSync(optionsFilePath)) { - options = cjson.load(optionsFilePath).cssModules; - } - options = options || {}; - - options = processGlobalVariables(options); - options = R.merge(getDefaultOptions(), options || {}); + let options = null; + if (fs.existsSync(optionsFilePath)) { + options = cjson.load(optionsFilePath).cssModules; + } + options = options || {}; - processPluginOptions(options.postcssPlugins); + options = processGlobalVariables(options); + options = R.mergeAll([getDefaultOptions(), options || {}]); - if (!Meteor.isDevelopment) { - options.missingClassErrorLevel = false; - } + processPluginOptions(options.postcssPlugins); - options.hash = sha1(JSON.stringify(options)); - if (options.hash === pluginOptions.hash) { - return pluginOptions.options; - } + // if (!Meteor.isDevelopment) { + // options.missingClassErrorLevel = false; + // } - processCssClassNamingConventionReplacements(options); - options.passthroughPaths = options.passthroughPaths.map(jsonToRegex); - options.includePaths = options.includePaths.map(jsonToRegex); - options.ignorePaths = [options.defaultIgnorePath, ...options.ignorePaths].map(jsonToRegex); + options.hash = sha1(JSON.stringify(options)); + if (options.hash === pluginOptions.hash) { + return pluginOptions.options; + } - checkSassCompilation(options); - checkLessCompilation(options); - checkStylusCompilation(options); + processCssClassNamingConventionReplacements(options); + options.passthroughPaths = options.passthroughPaths.map(jsonToRegex); + options.includePaths = options.includePaths.map(jsonToRegex); + options.ignorePaths = [options.defaultIgnorePath, ...options.ignorePaths].map(jsonToRegex); - return pluginOptions.options = options; + return pluginOptions.options = options; } function processCssClassNamingConventionReplacements(options) { - if (!options.cssClassNamingConvention || !options.cssClassNamingConvention.replacements) return; + if (!options.cssClassNamingConvention || !options.cssClassNamingConvention.replacements) return; - const replacements = options.cssClassNamingConvention.replacements; - options.cssClassNamingConvention.replacements = replacements.map(createReplacer); -} - -function checkSassCompilation(options) { - if (!options.enableSassCompilation) { - return; - } - - if (options.enableSassCompilation === true || - (Array.isArray(options.enableSassCompilation) && R.intersection(options.enableSassCompilation, options.extensions).length)) { - const result = checkNpmPackage('node-sass@>=3.x <=4.x'); - if (result === true) return; - } - options.enableSassCompilation = false; -} - -function checkLessCompilation(options) { - if (!options.enableLessCompilation) return; - - if (options.enableLessCompilation === true || - (Array.isArray(options.enableLessCompilation) && R.intersection(options.enableLessCompilation, options.extensions).length)) { - const result = checkNpmPackage('less@2.x'); - if (result === true) return; - } - - options.enableLessCompilation = false; -} - -function checkStylusCompilation(options) { - if (!options.enableStylusCompilation) return; - - if (options.enableStylusCompilation === true || - (Array.isArray(options.enableStylusCompilation) && R.intersection(options.enableStylusCompilation, options.extensions).length)) { - const result = checkNpmPackage('stylus@0.x'); - if (result === true) return; - } - - options.enableStylusCompilation = false; + const replacements = options.cssClassNamingConvention.replacements; + options.cssClassNamingConvention.replacements = replacements.map(createReplacer); } function processGlobalVariables(options) { - if (!options.globalVariables) return options; - - const globalVariablesText = []; - const globalVariablesJs = []; - options.globalVariables.forEach(entry => { - switch (R.type(entry)) { - case 'Object': - globalVariablesJs.push(entry); - globalVariablesText.push(convertJsonVariablesToScssVariables(entry)); - break; - case 'String': - const fileContents = fs.readFileSync(entry, 'utf-8'); - if (path.extname(entry) === '.json') { - const jsonVariables = cjson.parse(fileContents); - globalVariablesJs.push(jsonVariables); - globalVariablesText.push(convertJsonVariablesToScssVariables(jsonVariables)); - } else { - globalVariablesJs.push(convertScssVariablesToJsonVariables(fileContents)); - globalVariablesText.push(fileContents); + if (!options.globalVariables) return options; + + const globalVariablesText = []; + const globalVariablesJs = []; + options.globalVariables.forEach(entry => { + switch (R.type(entry)) { + case 'Object': + globalVariablesJs.push(entry); + globalVariablesText.push(convertJsonVariablesToScssVariables(entry)); + break; + case 'String': + const fileContents = fs.readFileSync(entry, 'utf-8'); + if (path.extname(entry) === '.json') { + const jsonVariables = cjson.parse(fileContents); + globalVariablesJs.push(jsonVariables); + globalVariablesText.push(convertJsonVariablesToScssVariables(jsonVariables)); + } else { + globalVariablesJs.push(convertScssVariablesToJsonVariables(fileContents)); + globalVariablesText.push(fileContents); + } + break; } - break; - } - }); + }); - options.globalVariablesJs = R.mergeAll(globalVariablesJs); - options.globalVariablesText = R.join('\n', globalVariablesText); - options.globalVariablesTextLineCount = options.globalVariablesText.split(/\r\n|\r|\n/).length; + options.globalVariablesJs = R.mergeAll(globalVariablesJs); + options.globalVariablesText = R.join('\n', globalVariablesText); + options.globalVariablesTextLineCount = options.globalVariablesText.split(/\r\n|\r|\n/).length; - return options; + return options; - function convertJsonVariablesToScssVariables(variables) { - const convertObjectToKeyValueArray = R.toPairs; - const convertVariablesToScss = R.reduce((variables, pair) => variables + `$${pair[0]}: ${pair[1]};\n`, ''); - const processVariables = R.pipe(convertObjectToKeyValueArray, convertVariablesToScss); - return processVariables(variables); - } + function convertJsonVariablesToScssVariables(variables) { + const convertObjectToKeyValueArray = R.toPairs; + const convertVariablesToScss = R.reduce((variables, pair) => variables + `$${pair[0]}: ${pair[1]};\n`, ''); + const processVariables = R.pipe(convertObjectToKeyValueArray, convertVariablesToScss); + return processVariables(variables); + } - function convertScssVariablesToJsonVariables(text) { - const extractVariables = R.match(/^\$.*/gm); - const convertVariableToJson = R.pipe(R.replace(/"/g, '\\"'), R.replace(/\$(.*):\s*(.*);/g, '"$1":"$2"')); - const surroundWithBraces = (str) => `{${str}}`; + function convertScssVariablesToJsonVariables(text) { + const extractVariables = R.match(/^\$.*/gm); + const convertVariableToJson = R.pipe(R.replace(/"/g, '\\"'), R.replace(/\$(.*):\s*(.*);/g, '"$1":"$2"')); + const surroundWithBraces = (str) => `{${str}}`; - const processText = R.pipe(extractVariables, R.map(convertVariableToJson), R.join(',\n'), surroundWithBraces, cjson.parse); - return processText(text); - } + const processText = R.pipe(extractVariables, R.map(convertVariableToJson), R.join(',\n'), surroundWithBraces, cjson.parse); + return processText(text); + } } function processPluginOptions(plugins) { - if (!plugins) return; + if (!plugins) return; - const keys = Object.keys(plugins); - keys.forEach(key => { - plugins[key] = getPluginOptions(plugins[key]); - }); + const keys = Object.keys(plugins); + keys.forEach(key => { + plugins[key] = getPluginOptions(plugins[key]); + }); } function getPluginOptions(pluginEntry) { - let combinedOptions = pluginEntry.inlineOptions !== undefined ? pluginEntry.inlineOptions : undefined; - let fileOptions; - if (R.type(pluginEntry.fileOptions) === 'Array') { - const getFilesAsJson = R.compose(R.reduce(deepExtend, {}), R.map(R.compose(loadJsonOrMssFile, decodeFilePath))); - fileOptions = getFilesAsJson(pluginEntry.fileOptions); - if (Object.keys(fileOptions).length) { - combinedOptions = deepExtend(combinedOptions || {}, fileOptions || {}); + let combinedOptions = pluginEntry.inlineOptions !== undefined ? pluginEntry.inlineOptions : undefined; + let fileOptions; + if (R.type(pluginEntry.fileOptions) === 'Array') { + const getFilesAsJson = R.compose(R.reduce(deepExtend, {}), R.map(R.compose(loadJsonOrMssFile, decodeFilePath))); + fileOptions = getFilesAsJson(pluginEntry.fileOptions); + if (Object.keys(fileOptions).length) { + combinedOptions = deepExtend(combinedOptions || {}, fileOptions || {}); + } } - } - return combinedOptions; + return combinedOptions; } function loadJsonOrMssFile(filePath) { - const removeLastOccurrence = (character, str) => { - const index = str.lastIndexOf(character); - return str.substring(0, index) + str.substring(index + 1); - }; - const loadMssFile = R.compose(variables => ({ variables: variables }), cjson.parse, str => `{${str}}`, R.curry(removeLastOccurrence)(','), R.replace(/\$(.*):\s*(.*),/g, '"$1":"$2",'), R.replace(/;/g, ','), R.partialRight(fs.readFileSync, ['utf-8'])); - return filePath.endsWith('.json') ? cjson.load(filePath) : loadMssFile(filePath); + const removeLastOccurrence = (character, str) => { + const index = str.lastIndexOf(character); + return str.substring(0, index) + str.substring(index + 1); + }; + const loadMssFile = R.compose(variables => ({ variables: variables }), cjson.parse, str => `{${str}}`, R.curry(removeLastOccurrence)(','), R.replace(/\$(.*):\s*(.*),/g, '"$1":"$2",'), R.replace(/;/g, ','), R.partialRight(fs.readFileSync, ['utf-8'])); + return filePath.endsWith('.json') ? cjson.load(filePath) : loadMssFile(filePath); } function decodeFilePath(filePath) { - const match = filePath.match(/{(.*)}\/(.*)$/); - if (!match) return filePath; + const match = filePath.match(/{(.*)}\/(.*)$/); + if (!match) return filePath; - if (match[1] === '') return match[2]; + if (match[1] === '') return match[2]; - const paths = []; + const paths = []; - paths[1] = paths[0] = `packages/${match[1].replace(':', '_')}/${match[2]}`; - if (!fs.existsSync(paths[0])) { - paths[2] = paths[0] = 'packages/' + match[1].replace(/.*:/, '') + '/' + match[2]; - } - if (!fs.existsSync(paths[0])) { - throw new Error(`Path not exist: ${filePath}\nTested path 1: ${paths[1]}\nTest path 2: ${paths[2]}`); - } + paths[1] = paths[0] = `packages/${match[1].replace(':', '_')}/${match[2]}`; + if (!fs.existsSync(paths[0])) { + paths[2] = paths[0] = 'packages/' + match[1].replace(/.*:/, '') + '/' + match[2]; + } + if (!fs.existsSync(paths[0])) { + throw new Error(`Path not exist: ${filePath}\nTested path 1: ${paths[1]}\nTest path 2: ${paths[2]}`); + } - return paths[0]; + return paths[0]; } function deepExtend(destination, source) { - for (let property in source) { - if (source[property] && source[property].constructor && - source[property].constructor === Object) { - destination[property] = destination[property] || {}; - // eslint-disable-next-line no-caller - arguments.callee(destination[property], source[property]); - } else { - destination[property] = source[property]; + for (let property in source) { + if (source[property] && source[property].constructor && + source[property].constructor === Object) { + destination[property] = destination[property] || {}; + // eslint-disable-next-line no-caller + arguments.callee(destination[property], source[property]); + } else { + destination[property] = source[property]; + } + } + return destination; } - } - return destination; -} diff --git a/options.tests.js b/options.tests.js deleted file mode 100644 index 0bdc1a3..0000000 --- a/options.tests.js +++ /dev/null @@ -1,96 +0,0 @@ -/* eslint-env node, mocha */ -import chai from 'chai'; -import packageOptionsWrapper, { reloadOptions } from './options'; -import cjson from 'cjson'; -import path from 'path'; -import ImportPathHelpers from './helpers/import-path-helpers'; - -const expect = chai.expect; - -cjson._load = cjson.load; -function testCjson(testFunction) { - testFunction(); - cjson.load = cjson._load; -} - -describe('package options', function() { - before(function() { - cjson._load = cjson.load; - cjson.test = (testFunction) => { - testFunction(); - cjson.load = cjson._load; - }; - }); - - describe('.options', function() { - it('should contain the options', function z() { - expect(packageOptionsWrapper.options.test).to.be.true; - }); - }); - - describe('reloadOptions', function() { - it('should read package.json', function z() { - testCjson(function() { - cjson.load = (filePath) => { - expect(filePath).to.equal(path.join(ImportPathHelpers.basePath, 'package.json')); - return {}; - }; - - reloadOptions(); - }); - }); - - it('should reload the options from package.json', function z() { - packageOptionsWrapper.options.test = false; - reloadOptions(); - expect(packageOptionsWrapper.options.test).to.be.true; - }); - - it('should merge the default options with the options from package.json', function z() { - expect(packageOptionsWrapper.options).to.eql({ - cssClassNamingConvention: { - replacements: [] - }, - enableProfiling: false, - enableSassCompilation: false, - enableStylusCompilation: false, - explicitIncludes: [], - extensions: ['css', 'm.css', 'mss'], - filenames: [], - globalVariablesText: '', - ignorePaths: [], - jsClassNamingConvention: { - camelCase: false - }, - outputJsFilePath: '{dirname}/{basename}{extname}', - outputCssFilePath: '{dirname}/{basename}{extname}', - passthroughPaths: [], - specificArchitecture: 'web', - hash: '4ff9a143d6b0b9cc0d90193e6d55cdf6577faf70', - test: true - }); - }); - - it('should hash the options file', function z() { - reloadOptions(); - expect(packageOptionsWrapper.options.hash).to.equal('4ff9a143d6b0b9cc0d90193e6d55cdf6577faf70'); - testCjson(function() { - cjson.load = (filePath) => { - expect(filePath).to.equal(path.join(ImportPathHelpers.basePath, 'package.json')); - return { test: false }; - }; - reloadOptions(); - - expect(packageOptionsWrapper.options.hash).to.equal('b70a64c10c6426233b51cf8d3162ec604c4614bc'); - }); - }); - - /** - * TODO: Tests for: - * options.cssClassNamingConvention.replacements - * options.passthroughPaths - * options.enableSassCompilation - * options.enableStylusCompilation - **/ - }); -}); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..2703855 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4053 @@ +{ + "name": "meteor-css-modules", + "version": "0.0.1", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "meteor-css-modules", + "version": "0.0.1", + "dependencies": { + "app-module-path": "2.2.0", + "camelcase": "8.0.0", + "cjson": "0.5.0", + "css-modules-loader-core": "1.1.0", + "es6-template-strings": "2.0.1", + "json-to-regex": "0.0.2", + "postcss": "8.4.47", + "postcss-modules-extract-imports": "3.1.0", + "postcss-modules-local-by-default": "4.0.5", + "postcss-modules-scope": "3.2.0", + "postcss-modules-values": "4.0.0", + "ramda": "0.30.1", + "recursive-readdir": "2.2.3", + "sass-embedded": "1.80.5", + "string-template": "1.0.0" + }, + "devDependencies": { + "babel-eslint": "10.1.0", + "eslint": "8.35.0", + "eslint-config-standard": "17.0.0", + "eslint-plugin-async-await": "0.0.0", + "eslint-plugin-promise": "6.1.1" + }, + "optionalDependencies": { + "sass-embedded-darwin-arm64": "1.80.7", + "sass-embedded-linux-x64": "1.80.7" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.26.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bufbuild/protobuf": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.2.1.tgz", + "integrity": "sha512-gdWzq7eX017a1kZCU/bP/sbk4e0GZ6idjsXOcMrQwODCb/rx985fHJJ8+hCu79KpuG7PfZh7bo3BBjPH37JuZw==" + }, + "node_modules/@eslint/eslintrc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.0.tgz", + "integrity": "sha512-fluIaaV+GyV24CCu/ggiHdV+j4RNh85yQnAYS/G2mZODZgGmmlrgCydjUcV3YvxCm9x8nMAfThsqTni4KiXT4A==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.35.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.35.0.tgz", + "integrity": "sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/app-module-path": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/babel-eslint": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", + "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", + "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + }, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "eslint": ">= 4.12.1" + } + }, + "node_modules/babel-eslint/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer-builder": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/buffer-builder/-/buffer-builder-0.2.0.tgz", + "integrity": "sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==" + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cjson": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cjson/-/cjson-0.5.0.tgz", + "integrity": "sha512-D3CKJU9YnZNyerUQ1IzNUvMnToP3MGC2XbIAPi/7yqunJJW3rBwCVapousoFtaR9IbejeEM0KIshxC1n4HQcXw==", + "dependencies": { + "json-parse-helpfulerror": "^1.0.3" + }, + "engines": { + "node": ">= 0.3.0" + } + }, + "node_modules/colorjs.io": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.5.2.tgz", + "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-modules-loader-core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-modules-loader-core/-/css-modules-loader-core-1.1.0.tgz", + "integrity": "sha512-XWOBwgy5nwBn76aA+6ybUGL/3JBnCtBX9Ay9/OWIpzKYWlVHMazvJ+WtHumfi+xxdPF440cWK7JCYtt8xDifew==", + "dependencies": { + "icss-replace-symbols": "1.1.0", + "postcss": "6.0.1", + "postcss-modules-extract-imports": "1.1.0", + "postcss-modules-local-by-default": "1.2.0", + "postcss-modules-scope": "1.1.0", + "postcss-modules-values": "1.3.0" + } + }, + "node_modules/css-modules-loader-core/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-modules-loader-core/node_modules/postcss": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.1.tgz", + "integrity": "sha512-VbGX1LQgQbf9l3cZ3qbUuC3hGqIEOGQFHAEHQ/Diaeo0yLgpgK5Rb8J+OcamIfQ9PbAU/fzBjVtQX3AhJHUvZw==", + "dependencies": { + "chalk": "^1.1.3", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/css-modules-loader-core/node_modules/postcss-modules-extract-imports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz", + "integrity": "sha512-zF9+UIEvtpeqMGxhpeT9XaIevQSrBBCz9fi7SwfkmjVacsSj8DY5eFVgn+wY8I9vvdDDwK5xC8Myq4UkoLFIkA==", + "dependencies": { + "postcss": "^6.0.1" + } + }, + "node_modules/css-modules-loader-core/node_modules/postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha512-X4cquUPIaAd86raVrBwO8fwRfkIdbwFu7CTfEOjiZQHVQwlHRSkTgH5NLDmMm5+1hQO8u6dZ+TOOJDbay1hYpA==", + "dependencies": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "node_modules/css-modules-loader-core/node_modules/postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha512-LTYwnA4C1He1BKZXIx1CYiHixdSe9LWYVKadq9lK5aCCMkoOkFyZ7aigt+srfjlRplJY3gIol6KUNefdMQJdlw==", + "dependencies": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "node_modules/css-modules-loader-core/node_modules/postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha512-i7IFaR9hlQ6/0UgFuqM6YWaCfA1Ej8WMg8A5DggnH1UGKJvTV/ugqq/KaULixzzOi3T/tF6ClBXcHGCzdd5unA==", + "dependencies": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^6.0.1" + } + }, + "node_modules/css-modules-loader-core/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-modules-loader-core/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/css-selector-tokenizer": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz", + "integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==", + "dependencies": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/es6-template-strings": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es6-template-strings/-/es6-template-strings-2.0.1.tgz", + "integrity": "sha512-5kTq0dEJfsm/EAteUCgLazcvWEhriVGwWFY3YgIsz89fJd+smi65/N1eS1Hn3B2dAngiqd0EvpXjr8lb7Quzkw==", + "dependencies": { + "es5-ext": "^0.10.12", + "esniff": "^1.1" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.35.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.35.0.tgz", + "integrity": "sha512-BxAf1fVL7w+JLRQhWl2pzGeSiGqbWumV4WNvc9Rhp6tiCtm4oHnyPBSEtMGZwrQgudFQ+otqzWoPB7x+hxoWsw==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^2.0.0", + "@eslint/js": "8.35.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-standard": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz", + "integrity": "sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==", + "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" + } + ], + "peerDependencies": { + "eslint": "^8.0.1", + "eslint-plugin-import": "^2.25.2", + "eslint-plugin-n": "^15.0.0", + "eslint-plugin-promise": "^6.0.0" + } + }, + "node_modules/eslint-plugin-async-await": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-async-await/-/eslint-plugin-async-await-0.0.0.tgz", + "integrity": "sha512-CNizhDO2f1dLaoA6wah3Yj8bSmsDC7wRTt4bsFBOUEYvzcd6XNhxBmz3EgqxD6a+V4Zjl8qTiDMZo3ug+qjojg==", + "dev": true + }, + "node_modules/eslint-plugin-promise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", + "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/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/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/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/eslint/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/eslint/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/eslint/node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esniff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-1.1.0.tgz", + "integrity": "sha512-vmHXOeOt7FJLsqofvFk4WB3ejvcHizCd8toXXwADmYfd02p2QwHRgkUbhYDX54y08nqk818CUTWipgZGlyN07g==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.12" + } + }, + "node_modules/espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dev": true, + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==" + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==" + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/immutable": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==" + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==" + }, + "node_modules/js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-helpfulerror": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz", + "integrity": "sha512-XgP0FGR77+QhUxjXkwOMkC94k3WtqEBfcnjWqhRd82qTat4SWKRE+9kUnynz/shm3I4ea2+qISvTIeGTNU7kJg==", + "dependencies": { + "jju": "^1.1.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json-to-regex": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/json-to-regex/-/json-to-regex-0.0.2.tgz", + "integrity": "sha512-XTLFW7m4ZnOODwZkN9eJVgsdpUQF9NcxxhvOh80NSWJ5fTlzXfPLavqEMUETSR0TXOIiGY5E/lsq6dae3of/Hw==" + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "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/ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "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" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/sass-embedded": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.80.5.tgz", + "integrity": "sha512-2rmFO02+NMk1no+OElI+H3+8wf0QDcbjmdIBATJhnPLKzbYbRt88U40rGN4pQWETFZ4hxppOGmGxn9MnHppHjw==", + "dependencies": { + "@bufbuild/protobuf": "^2.0.0", + "buffer-builder": "^0.2.0", + "colorjs.io": "^0.5.0", + "immutable": "^4.0.0", + "rxjs": "^7.4.0", + "supports-color": "^8.1.1", + "varint": "^6.0.0" + }, + "bin": { + "sass": "dist/bin/sass.js" + }, + "engines": { + "node": ">=16.0.0" + }, + "optionalDependencies": { + "sass-embedded-android-arm": "1.80.5", + "sass-embedded-android-arm64": "1.80.5", + "sass-embedded-android-ia32": "1.80.5", + "sass-embedded-android-riscv64": "1.80.5", + "sass-embedded-android-x64": "1.80.5", + "sass-embedded-darwin-arm64": "1.80.5", + "sass-embedded-darwin-x64": "1.80.5", + "sass-embedded-linux-arm": "1.80.5", + "sass-embedded-linux-arm64": "1.80.5", + "sass-embedded-linux-ia32": "1.80.5", + "sass-embedded-linux-musl-arm": "1.80.5", + "sass-embedded-linux-musl-arm64": "1.80.5", + "sass-embedded-linux-musl-ia32": "1.80.5", + "sass-embedded-linux-musl-riscv64": "1.80.5", + "sass-embedded-linux-musl-x64": "1.80.5", + "sass-embedded-linux-riscv64": "1.80.5", + "sass-embedded-linux-x64": "1.80.5", + "sass-embedded-win32-arm64": "1.80.5", + "sass-embedded-win32-ia32": "1.80.5", + "sass-embedded-win32-x64": "1.80.5" + } + }, + "node_modules/sass-embedded-android-arm": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.80.5.tgz", + "integrity": "sha512-3af/JRxWJabeADvZTWG7FGGk1O1X+ptHpTwGc+jvtwciTguNnRJy5KOFY0hi0hRfgd/ku6jao2DktwRkC0pz6g==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-arm64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.80.5.tgz", + "integrity": "sha512-ZPX/gg28vClcP1p4RbEkP5bHhQB35fI8TucJx/gRJDR+A1nyX4vHYEy+qhkmTSshuiFJQcKjtBgfbRRNC0jSdA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-ia32": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-android-ia32/-/sass-embedded-android-ia32-1.80.5.tgz", + "integrity": "sha512-zfKf81HygpBZ8IFo/C9KTJYdZIRVK8w1nbkwlp1n/plubZHN9kGAUWrMRy14lKM2bLripmrjxi4XwRKEt4dWEw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-riscv64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.80.5.tgz", + "integrity": "sha512-6Jm72UluidtDSjKRNHV2V6eFBVY9W5v95HEA4oF62WXu/eerB6fvEmqWfKYkSegtPyc8q/1J5dBiKPtQrJjDzw==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-x64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.80.5.tgz", + "integrity": "sha512-v+hpf61/pMOvwYp5FQzRm+Ekv1KXIuhTobAhghfB6ufVJdeGZffu0IXc/NeKXSoOjO9stiwjISnHFT6/9tHXyQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-darwin-arm64": { + "version": "1.80.7", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.80.7.tgz", + "integrity": "sha512-Vi5BbTWd9OO0tC60CPw5IY7w3Tccr1/Gy2DdkfE4qP6Rc368WmUis5ceG8ehAye0IT7aoRXpw8XTzWyXAZHbfw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-darwin-x64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.80.5.tgz", + "integrity": "sha512-/QiaUEJsSJYITKz9oO98GJz7Cw8BeDJuQHfXehFg9tMYZDWqskgKqZ0tAX/e0M1eagU8/RVbndav+EY19G+yqg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-arm": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.80.5.tgz", + "integrity": "sha512-N+UkxXdWGSReJ5AOFJzITY5nWI1jjtPlI8+syu5OvQk0r6uvous+XMTAm3GHyETHi1G90f8PU2nDBW0aVrFJ/A==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-arm64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.80.5.tgz", + "integrity": "sha512-M7YV2ZZRZ7BYnAKkFEUxguNf0HLGGu2wxait31qLLdQ3Cm8Oqdnrj4EdwqXm6umWBy9pPAOhptleo6TgxlAJgQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-ia32": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-ia32/-/sass-embedded-linux-ia32-1.80.5.tgz", + "integrity": "sha512-VGv0xJFsoszPGOyClhJSbRQan/zGlwX+skbBkxUnWaK79KYK3rIAt/8L7yvLOuB/QvGcdmbLqVcDaolntK1SWA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-arm": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.80.5.tgz", + "integrity": "sha512-cZfGOQrfkKYSSsOd1Bdge7IT9604wp/DNCMBi1U2yENHIVftoo8JYdH08wlBUjpD6nuCO3OH9IiMmtRwb5Wa2w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-arm64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.80.5.tgz", + "integrity": "sha512-G4qEewtCkP7l1y7Kj2UTJd7KdyJLC8PGg7Pz3ScyIMBwOpAMJYUEy+UEDpIgshv87CigNPzoVeKQZifDBEuXzQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-ia32": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-ia32/-/sass-embedded-linux-musl-ia32-1.80.5.tgz", + "integrity": "sha512-KGykpYQ4LcYecjaAYgKXrWWk9H0/Ls5KSgwNbeaspVjsrYQOQguEOTDS0e/tdjZkS2kVMhorkD9ZySsaucxLdw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-riscv64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.80.5.tgz", + "integrity": "sha512-ba4NbmyH7hAuWo9v6XrTLZvxDO5bMcgEKBkDhJLyCo2ywioXjXgAuRANt7qAzVz9JJxJnVT2K8bc8aZ+8h7T3A==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-x64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.80.5.tgz", + "integrity": "sha512-oznwZKX4K3vB3yITiV7beDfOrgnL7GpDXjDSVQvH2XuR9c/VueUdzGNpogiXJ/spydJ79eMt2rZCYVD/V9LsUw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-riscv64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.80.5.tgz", + "integrity": "sha512-hDVRbfA/XPtD0ESlWasvBB00aw50/Ir1pun+a5eTmzuvzgiQ7yT8kRUojfZA3eHWYQFKmjQ1FnIvPk+YjzPplw==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-x64": { + "version": "1.80.7", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.80.7.tgz", + "integrity": "sha512-nQB+IZwCzVPpPkP5L9zV416/AGPLky7L2GGPWtvxG2CEeTV1Rzet+gkhzk2eYEdbh+3py/w9YVRTaQuZ3QV0vQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-arm64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.80.5.tgz", + "integrity": "sha512-ok85M2ptV81B+EkUs0T1DmRQ6ELgOWJGtnhBt7WwRPalZBl59gFQFNsRWNqxOpROlVYJya+RFnNieq6kQdL9Vg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-ia32": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-ia32/-/sass-embedded-win32-ia32-1.80.5.tgz", + "integrity": "sha512-Bp1Fe2vixWiJnWZ59QjXpyqlyy3DTFjAUhJV5ybKNeISYw6FdY85jSIaM2wH/mt8zTd+ZkoGPBwF5DWueD61ZQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-x64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.80.5.tgz", + "integrity": "sha512-RJjvNAgi2oVsSTKjAyEfdjlWnpgCVov8sUFvMv97Vcq8i8BCx4oztO3X2P8neFP3QGwHclDqEPINLdiTGHwcZw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/sass-embedded/node_modules/sass-embedded-darwin-arm64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.80.5.tgz", + "integrity": "sha512-6P1suMeGiiSdbqwYNbCS4NbgFQaUMgvNMABydPfJ0KssTkFbpnPATQ5k8K1siZbxhw0kyxDbYMJebnpCS1lWbw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded/node_modules/sass-embedded-linux-x64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.80.5.tgz", + "integrity": "sha512-jQeCOGFgOk8Dt4nabHiG1Xf0d2ethPuk4VDvfXsWhUiRllahZ+CfqoPPr630AQdaDtcNKwWuXwBsZLyI2wP3aw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-template": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-1.0.0.tgz", + "integrity": "sha512-SLqR3GBUXuoPP5MmYtD7ompvXiG87QjT6lzOszyXjTM86Uu7At7vNnt2xgyTLq5o9T4IxTYFyGxcULqpsmsfdg==" + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/tslib": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==" + }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/varint": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", + "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + } + }, + "@babel/generator": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "dev": true, + "requires": { + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + } + }, + "@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true + }, + "@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "dev": true, + "requires": { + "@babel/types": "^7.26.0" + } + }, + "@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + } + }, + "@babel/traverse": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + } + }, + "@bufbuild/protobuf": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.2.1.tgz", + "integrity": "sha512-gdWzq7eX017a1kZCU/bP/sbk4e0GZ6idjsXOcMrQwODCb/rx985fHJJ8+hCu79KpuG7PfZh7bo3BBjPH37JuZw==" + }, + "@eslint/eslintrc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.0.tgz", + "integrity": "sha512-fluIaaV+GyV24CCu/ggiHdV+j4RNh85yQnAYS/G2mZODZgGmmlrgCydjUcV3YvxCm9x8nMAfThsqTni4KiXT4A==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "@eslint/js": { + "version": "8.35.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.35.0.tgz", + "integrity": "sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==", + "dev": true + }, + "@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==" + }, + "app-module-path": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==" + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "babel-eslint": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", + "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-builder": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/buffer-builder/-/buffer-builder-0.2.0.tgz", + "integrity": "sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==" + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "cjson": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cjson/-/cjson-0.5.0.tgz", + "integrity": "sha512-D3CKJU9YnZNyerUQ1IzNUvMnToP3MGC2XbIAPi/7yqunJJW3rBwCVapousoFtaR9IbejeEM0KIshxC1n4HQcXw==", + "requires": { + "json-parse-helpfulerror": "^1.0.3" + } + }, + "colorjs.io": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.5.2.tgz", + "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "css-modules-loader-core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-modules-loader-core/-/css-modules-loader-core-1.1.0.tgz", + "integrity": "sha512-XWOBwgy5nwBn76aA+6ybUGL/3JBnCtBX9Ay9/OWIpzKYWlVHMazvJ+WtHumfi+xxdPF440cWK7JCYtt8xDifew==", + "requires": { + "icss-replace-symbols": "1.1.0", + "postcss": "6.0.1", + "postcss-modules-extract-imports": "1.1.0", + "postcss-modules-local-by-default": "1.2.0", + "postcss-modules-scope": "1.1.0", + "postcss-modules-values": "1.3.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==" + }, + "postcss": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.1.tgz", + "integrity": "sha512-VbGX1LQgQbf9l3cZ3qbUuC3hGqIEOGQFHAEHQ/Diaeo0yLgpgK5Rb8J+OcamIfQ9PbAU/fzBjVtQX3AhJHUvZw==", + "requires": { + "chalk": "^1.1.3", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "postcss-modules-extract-imports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz", + "integrity": "sha512-zF9+UIEvtpeqMGxhpeT9XaIevQSrBBCz9fi7SwfkmjVacsSj8DY5eFVgn+wY8I9vvdDDwK5xC8Myq4UkoLFIkA==", + "requires": { + "postcss": "^6.0.1" + } + }, + "postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha512-X4cquUPIaAd86raVrBwO8fwRfkIdbwFu7CTfEOjiZQHVQwlHRSkTgH5NLDmMm5+1hQO8u6dZ+TOOJDbay1hYpA==", + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha512-LTYwnA4C1He1BKZXIx1CYiHixdSe9LWYVKadq9lK5aCCMkoOkFyZ7aigt+srfjlRplJY3gIol6KUNefdMQJdlw==", + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha512-i7IFaR9hlQ6/0UgFuqM6YWaCfA1Ej8WMg8A5DggnH1UGKJvTV/ugqq/KaULixzzOi3T/tF6ClBXcHGCzdd5unA==", + "requires": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^6.0.1" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "css-selector-tokenizer": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz", + "integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==", + "requires": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2" + } + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "requires": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "es6-template-strings": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es6-template-strings/-/es6-template-strings-2.0.1.tgz", + "integrity": "sha512-5kTq0dEJfsm/EAteUCgLazcvWEhriVGwWFY3YgIsz89fJd+smi65/N1eS1Hn3B2dAngiqd0EvpXjr8lb7Quzkw==", + "requires": { + "es5-ext": "^0.10.12", + "esniff": "^1.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "eslint": { + "version": "8.35.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.35.0.tgz", + "integrity": "sha512-BxAf1fVL7w+JLRQhWl2pzGeSiGqbWumV4WNvc9Rhp6tiCtm4oHnyPBSEtMGZwrQgudFQ+otqzWoPB7x+hxoWsw==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^2.0.0", + "@eslint/js": "8.35.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "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" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.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 + }, + "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 + }, + "globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "eslint-config-standard": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz", + "integrity": "sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==", + "dev": true + }, + "eslint-plugin-async-await": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-async-await/-/eslint-plugin-async-await-0.0.0.tgz", + "integrity": "sha512-CNizhDO2f1dLaoA6wah3Yj8bSmsDC7wRTt4bsFBOUEYvzcd6XNhxBmz3EgqxD6a+V4Zjl8qTiDMZo3ug+qjojg==", + "dev": true + }, + "eslint-plugin-promise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", + "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "dev": true + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + }, + "esniff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-1.1.0.tgz", + "integrity": "sha512-vmHXOeOt7FJLsqofvFk4WB3ejvcHizCd8toXXwADmYfd02p2QwHRgkUbhYDX54y08nqk818CUTWipgZGlyN07g==", + "requires": { + "d": "1", + "es5-ext": "^0.10.12" + } + }, + "espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dev": true, + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + } + }, + "esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "requires": { + "type": "^2.7.2" + }, + "dependencies": { + "type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==" + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==" + }, + "icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==" + }, + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true + }, + "immutable": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==" + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dev": true, + "requires": { + "hasown": "^2.0.2" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==" + }, + "js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true + }, + "json-parse-helpfulerror": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz", + "integrity": "sha512-XgP0FGR77+QhUxjXkwOMkC94k3WtqEBfcnjWqhRd82qTat4SWKRE+9kUnynz/shm3I4ea2+qISvTIeGTNU7kJg==", + "requires": { + "jju": "^1.1.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "json-to-regex": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/json-to-regex/-/json-to-regex-0.0.2.tgz", + "integrity": "sha512-XTLFW7m4ZnOODwZkN9eJVgsdpUQF9NcxxhvOh80NSWJ5fTlzXfPLavqEMUETSR0TXOIiGY5E/lsq6dae3of/Hw==" + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "requires": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + } + }, + "postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==" + }, + "postcss-modules-local-by-default": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "requires": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-modules-scope": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "requires": { + "postcss-selector-parser": "^6.0.4" + } + }, + "postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "requires": { + "icss-utils": "^5.0.0" + } + }, + "postcss-selector-parser": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "ramda": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==" + }, + "recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "requires": { + "minimatch": "^3.0.5" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "requires": { + "tslib": "^2.1.0" + } + }, + "sass-embedded": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.80.5.tgz", + "integrity": "sha512-2rmFO02+NMk1no+OElI+H3+8wf0QDcbjmdIBATJhnPLKzbYbRt88U40rGN4pQWETFZ4hxppOGmGxn9MnHppHjw==", + "requires": { + "@bufbuild/protobuf": "^2.0.0", + "buffer-builder": "^0.2.0", + "colorjs.io": "^0.5.0", + "immutable": "^4.0.0", + "rxjs": "^7.4.0", + "sass-embedded-android-arm": "1.80.5", + "sass-embedded-android-arm64": "1.80.5", + "sass-embedded-android-ia32": "1.80.5", + "sass-embedded-android-riscv64": "1.80.5", + "sass-embedded-android-x64": "1.80.5", + "sass-embedded-darwin-arm64": "1.80.5", + "sass-embedded-darwin-x64": "1.80.5", + "sass-embedded-linux-arm": "1.80.5", + "sass-embedded-linux-arm64": "1.80.5", + "sass-embedded-linux-ia32": "1.80.5", + "sass-embedded-linux-musl-arm": "1.80.5", + "sass-embedded-linux-musl-arm64": "1.80.5", + "sass-embedded-linux-musl-ia32": "1.80.5", + "sass-embedded-linux-musl-riscv64": "1.80.5", + "sass-embedded-linux-musl-x64": "1.80.5", + "sass-embedded-linux-riscv64": "1.80.5", + "sass-embedded-linux-x64": "1.80.5", + "sass-embedded-win32-arm64": "1.80.5", + "sass-embedded-win32-ia32": "1.80.5", + "sass-embedded-win32-x64": "1.80.5", + "supports-color": "^8.1.1", + "varint": "^6.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "sass-embedded-darwin-arm64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.80.5.tgz", + "integrity": "sha512-6P1suMeGiiSdbqwYNbCS4NbgFQaUMgvNMABydPfJ0KssTkFbpnPATQ5k8K1siZbxhw0kyxDbYMJebnpCS1lWbw==", + "optional": true + }, + "sass-embedded-linux-x64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.80.5.tgz", + "integrity": "sha512-jQeCOGFgOk8Dt4nabHiG1Xf0d2ethPuk4VDvfXsWhUiRllahZ+CfqoPPr630AQdaDtcNKwWuXwBsZLyI2wP3aw==", + "optional": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "sass-embedded-android-arm": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.80.5.tgz", + "integrity": "sha512-3af/JRxWJabeADvZTWG7FGGk1O1X+ptHpTwGc+jvtwciTguNnRJy5KOFY0hi0hRfgd/ku6jao2DktwRkC0pz6g==", + "optional": true + }, + "sass-embedded-android-arm64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.80.5.tgz", + "integrity": "sha512-ZPX/gg28vClcP1p4RbEkP5bHhQB35fI8TucJx/gRJDR+A1nyX4vHYEy+qhkmTSshuiFJQcKjtBgfbRRNC0jSdA==", + "optional": true + }, + "sass-embedded-android-ia32": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-android-ia32/-/sass-embedded-android-ia32-1.80.5.tgz", + "integrity": "sha512-zfKf81HygpBZ8IFo/C9KTJYdZIRVK8w1nbkwlp1n/plubZHN9kGAUWrMRy14lKM2bLripmrjxi4XwRKEt4dWEw==", + "optional": true + }, + "sass-embedded-android-riscv64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.80.5.tgz", + "integrity": "sha512-6Jm72UluidtDSjKRNHV2V6eFBVY9W5v95HEA4oF62WXu/eerB6fvEmqWfKYkSegtPyc8q/1J5dBiKPtQrJjDzw==", + "optional": true + }, + "sass-embedded-android-x64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.80.5.tgz", + "integrity": "sha512-v+hpf61/pMOvwYp5FQzRm+Ekv1KXIuhTobAhghfB6ufVJdeGZffu0IXc/NeKXSoOjO9stiwjISnHFT6/9tHXyQ==", + "optional": true + }, + "sass-embedded-darwin-arm64": { + "version": "1.80.7", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.80.7.tgz", + "integrity": "sha512-Vi5BbTWd9OO0tC60CPw5IY7w3Tccr1/Gy2DdkfE4qP6Rc368WmUis5ceG8ehAye0IT7aoRXpw8XTzWyXAZHbfw==", + "optional": true + }, + "sass-embedded-darwin-x64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.80.5.tgz", + "integrity": "sha512-/QiaUEJsSJYITKz9oO98GJz7Cw8BeDJuQHfXehFg9tMYZDWqskgKqZ0tAX/e0M1eagU8/RVbndav+EY19G+yqg==", + "optional": true + }, + "sass-embedded-linux-arm": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.80.5.tgz", + "integrity": "sha512-N+UkxXdWGSReJ5AOFJzITY5nWI1jjtPlI8+syu5OvQk0r6uvous+XMTAm3GHyETHi1G90f8PU2nDBW0aVrFJ/A==", + "optional": true + }, + "sass-embedded-linux-arm64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.80.5.tgz", + "integrity": "sha512-M7YV2ZZRZ7BYnAKkFEUxguNf0HLGGu2wxait31qLLdQ3Cm8Oqdnrj4EdwqXm6umWBy9pPAOhptleo6TgxlAJgQ==", + "optional": true + }, + "sass-embedded-linux-ia32": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-ia32/-/sass-embedded-linux-ia32-1.80.5.tgz", + "integrity": "sha512-VGv0xJFsoszPGOyClhJSbRQan/zGlwX+skbBkxUnWaK79KYK3rIAt/8L7yvLOuB/QvGcdmbLqVcDaolntK1SWA==", + "optional": true + }, + "sass-embedded-linux-musl-arm": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.80.5.tgz", + "integrity": "sha512-cZfGOQrfkKYSSsOd1Bdge7IT9604wp/DNCMBi1U2yENHIVftoo8JYdH08wlBUjpD6nuCO3OH9IiMmtRwb5Wa2w==", + "optional": true + }, + "sass-embedded-linux-musl-arm64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.80.5.tgz", + "integrity": "sha512-G4qEewtCkP7l1y7Kj2UTJd7KdyJLC8PGg7Pz3ScyIMBwOpAMJYUEy+UEDpIgshv87CigNPzoVeKQZifDBEuXzQ==", + "optional": true + }, + "sass-embedded-linux-musl-ia32": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-ia32/-/sass-embedded-linux-musl-ia32-1.80.5.tgz", + "integrity": "sha512-KGykpYQ4LcYecjaAYgKXrWWk9H0/Ls5KSgwNbeaspVjsrYQOQguEOTDS0e/tdjZkS2kVMhorkD9ZySsaucxLdw==", + "optional": true + }, + "sass-embedded-linux-musl-riscv64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.80.5.tgz", + "integrity": "sha512-ba4NbmyH7hAuWo9v6XrTLZvxDO5bMcgEKBkDhJLyCo2ywioXjXgAuRANt7qAzVz9JJxJnVT2K8bc8aZ+8h7T3A==", + "optional": true + }, + "sass-embedded-linux-musl-x64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.80.5.tgz", + "integrity": "sha512-oznwZKX4K3vB3yITiV7beDfOrgnL7GpDXjDSVQvH2XuR9c/VueUdzGNpogiXJ/spydJ79eMt2rZCYVD/V9LsUw==", + "optional": true + }, + "sass-embedded-linux-riscv64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.80.5.tgz", + "integrity": "sha512-hDVRbfA/XPtD0ESlWasvBB00aw50/Ir1pun+a5eTmzuvzgiQ7yT8kRUojfZA3eHWYQFKmjQ1FnIvPk+YjzPplw==", + "optional": true + }, + "sass-embedded-linux-x64": { + "version": "1.80.7", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.80.7.tgz", + "integrity": "sha512-nQB+IZwCzVPpPkP5L9zV416/AGPLky7L2GGPWtvxG2CEeTV1Rzet+gkhzk2eYEdbh+3py/w9YVRTaQuZ3QV0vQ==", + "optional": true + }, + "sass-embedded-win32-arm64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.80.5.tgz", + "integrity": "sha512-ok85M2ptV81B+EkUs0T1DmRQ6ELgOWJGtnhBt7WwRPalZBl59gFQFNsRWNqxOpROlVYJya+RFnNieq6kQdL9Vg==", + "optional": true + }, + "sass-embedded-win32-ia32": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-ia32/-/sass-embedded-win32-ia32-1.80.5.tgz", + "integrity": "sha512-Bp1Fe2vixWiJnWZ59QjXpyqlyy3DTFjAUhJV5ybKNeISYw6FdY85jSIaM2wH/mt8zTd+ZkoGPBwF5DWueD61ZQ==", + "optional": true + }, + "sass-embedded-win32-x64": { + "version": "1.80.5", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.80.5.tgz", + "integrity": "sha512-RJjvNAgi2oVsSTKjAyEfdjlWnpgCVov8sUFvMv97Vcq8i8BCx4oztO3X2P8neFP3QGwHclDqEPINLdiTGHwcZw==", + "optional": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==" + }, + "string-template": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-1.0.0.tgz", + "integrity": "sha512-SLqR3GBUXuoPP5MmYtD7ompvXiG87QjT6lzOszyXjTM86Uu7At7vNnt2xgyTLq5o9T4IxTYFyGxcULqpsmsfdg==" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==" + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "tslib": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==" + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "varint": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", + "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/package.js b/package.js index bb28d8f..910c4fe 100644 --- a/package.js +++ b/package.js @@ -1,68 +1,62 @@ /* globals Package */ Package.describe({ - name: 'nathantreid:css-modules', - version: '4.1.0', - summary: 'CSS modules implementation. CSS for components!', - git: 'https://github.com/nathantreid/meteor-css-modules.git', - documentation: 'README.md' + name: 'wolas:scss-modules-darwin-arm64', + version: '7.0.7', + summary: 'CSS modules implementation. CSS for components!', + git: 'https://github.com/wolasss/meteor-css-modules', + documentation: 'README.md' }); Package.registerBuildPlugin({ - name: 'mss', - use: [ - 'babel-compiler@7.0.0', - 'ecmascript@0.10.0', - 'caching-compiler@1.1.7_1', - 'underscore@1.0.9', - ], - npmDependencies: { - 'app-module-path': '1.0.4', - 'camelcase': '3.0.0', - 'cjson': '0.3.3', - 'colors': '1.1.2', - 'common-tags': '1.3.1', - 'css-modules-loader-core': '1.0.0', - 'json-to-regex': '0.0.2', - 'es6-template-strings': '2.0.1', - 'hasha': '3.0.0', - 'lru-cache': '2.6.4', - 'path-is-absolute': '1.0.0', - 'postcss': '5.1.2', - 'postcss-modules-local-by-default': '1.1.1', - 'postcss-modules-extract-imports': '1.0.1', - 'postcss-modules-scope': '1.0.2', - 'postcss-modules-values': '1.2.2', - 'ramda': '0.19.0', - 'recursive-readdir': '1.3.0', - 'shorthash': '0.0.2', - 'string-template': '1.0.0', - }, - sources: [ - 'sha1.js', - 'logger.js', - 'text-replacer.js', - 'included-file.js', - 'get-output-path.js', - 'check-npm-package.js', - 'options.js', - 'helpers/import-path-helpers.js', - 'helpers/profile.js', - 'postcss-plugins.js', - 'scss-processor.js', - 'less-processor.js', - 'stylus-processor.js', - 'css-modules-processor.js', - 'css-modules-build-plugin.js', - 'plugin.js' - ] + name: 'scss-modules', + use: [ + 'babel-compiler@7.11.1', + 'ecmascript@0.16.9', + 'caching-compiler@2.0.1' + ], + npmDependencies: { + 'app-module-path': '2.2.0', + 'camelcase': '8.0.0', + 'cjson': '0.5.0', + 'css-modules-loader-core': '1.1.0', + 'json-to-regex': '0.0.2', + 'es6-template-strings': '2.0.1', + 'postcss': '8.4.47', + 'postcss-modules-local-by-default': '4.0.5', + 'postcss-modules-extract-imports': '3.1.0', + 'postcss-modules-scope': '3.2.0', + 'postcss-modules-values': '4.0.0', + 'ramda': '0.30.1', + 'sass-embedded': '1.58.3', + 'sass-embedded-darwin-arm64': '1.80.7', + 'recursive-readdir': '2.2.3', + 'string-template': '1.0.0', + '@babel/runtime': '7.17.2', + 'sass-embedded': '1.80.5' + }, + sources: [ + 'logger.js', + 'text-replacer.js', + 'included-file.js', + 'get-output-path.js', + 'options.js', + 'helpers/import-path-helpers.js', + 'helpers/profile.js', + 'postcss-plugins.js', + 'scss-processor.js', + 'css-modules-processor.js', + 'css-modules-build-plugin.js', + 'plugin.js', + 'utils.js' + ] }); Package.onUse(function (api) { - api.versionsFrom('1.6.1'); - api.use('isobuild:compiler-plugin@1.0.0'); - api.use([ - 'ecmascript@0.10.0', - ]); + api.versionsFrom(['1.6.1', '2.3', '3.0']); + api.use('isobuild:compiler-plugin@1.0.0'); + api.use([ + 'ecmascript@0.16.9', + ]); - api.mainModule('package/main.js'); + api.mainModule('package/main.js'); }); diff --git a/package.json b/package.json index e337edb..4f6b1db 100644 --- a/package.json +++ b/package.json @@ -1,57 +1,29 @@ { "name": "meteor-css-modules", "version": "0.0.1", - "scripts": { - "test": "node ./node_modules/mocha/bin/mocha --compilers js:babel-register --require ./test-helpers/babel-hook.js .\\{,!(node_modules)\\**\\}*.tests.js" - }, "devDependencies": { - "async": "^2.0.1", - "babel-eslint": "^6.1.2", - "babel-plugin-syntax-async-functions": "^6.13.0", - "babel-plugin-syntax-async-generators": "^6.13.0", - "babel-plugin-transform-es2015-destructuring": "^6.9.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.11.5", - "babel-plugin-transform-object-rest-spread": "^6.8.0", - "babel-plugin-transform-regenerator": "^6.11.4", - "babel-polyfill": "^6.13.0", - "babel-preset-es2015": "^6.13.2", - "babel-preset-meteor": "^6.12.0", - "babel-project-relative-import": "^2.0.0", - "babel-register": "^6.11.6", - "babel-runtime": "^6.11.6", - "chai": "^3.5.0", - "eslint": "^3.3.1", - "eslint-config-standard": "^5.3.5", + "babel-eslint": "10.1.0", + "eslint": "8.35.0", + "eslint-config-standard": "17.0.0", "eslint-plugin-async-await": "0.0.0", - "eslint-plugin-promise": "^2.0.0", - "eslint-plugin-standard": "^2.0.0", - "fibers": "^1.0.13", - "mocha": "^3.0.2", - "mock-require": "^1.3.0", - "node-sass": "^3.8.0", - "less": "^2.7.1", - "ramda": "0.19.0", - "standard": "^7.1.2" + "eslint-plugin-promise": "6.1.1" }, "dependencies": { - "app-module-path": "1.0.4", - "camelcase": "3.0.0", - "cjson": "0.3.3", - "colors": "1.1.2", - "common-tags": "^1.3.1", - "css-modules-loader-core": "1.0.0", - "lru-cache": "2.6.4", - "path-is-absolute": "^1.0.0", - "postcss": "5.0.14", - "postcss-modules-extract-imports": "1.0.0", - "postcss-modules-local-by-default": "1.0.1", - "postcss-modules-scope": "1.0.0", - "postcss-modules-values": "1.1.1", - "recursive-readdir": "1.3.0", - "semver": "^5.3.0", + "app-module-path": "2.2.0", + "camelcase": "8.0.0", + "cjson": "0.5.0", + "css-modules-loader-core": "1.1.0", + "es6-template-strings": "2.0.1", + "json-to-regex": "0.0.2", + "postcss": "8.4.47", + "postcss-modules-extract-imports": "3.1.0", + "postcss-modules-local-by-default": "4.0.5", + "postcss-modules-scope": "3.2.0", + "postcss-modules-values": "4.0.0", + "ramda": "0.30.1", + "recursive-readdir": "2.2.3", + "sass-embedded": "1.80.5", + "sass-embedded-darwin-arm64": "1.80.7", "string-template": "1.0.0" - }, - "cssModules": { - "test": true } } diff --git a/package/main.js b/package/main.js index d663da4..8875316 100644 --- a/package/main.js +++ b/package/main.js @@ -1,3 +1,3 @@ export default { - onCssModuleMissingStyle: undefined, + onCssModuleMissingStyle: undefined, }; diff --git a/plugin.js b/plugin.js index 939223f..1c5d399 100644 --- a/plugin.js +++ b/plugin.js @@ -3,56 +3,22 @@ import CssModulesBuildPlugin from './css-modules-build-plugin'; import pluginOptionsWrapper from './options'; import ImportPathHelpers from './helpers/import-path-helpers'; +// if architecture is different than darwin arm return +if (process.platform !== 'darwin' || process.arch !== 'arm64') { + return; +} + const pluginOptions = pluginOptionsWrapper.options; ImportPathHelpers.init(Plugin); -if (pluginOptions.extensions.indexOf('css') === -1) { - registerCompiler(); -} else { - monkeyPatchToHandleCssExtension(); -} global.cssModules = global.cssModules || {}; global.cssModules.compiler = new CssModulesBuildPlugin(Plugin); -function registerCompiler() { - Plugin.registerCompiler({ - extensions: pluginOptions.extensions, - archMatching: pluginOptions.specificArchitecture, - filenames: pluginOptions.filenames - }, function() { - return new CssModulesBuildPlugin(Plugin); - }); -} -/** - * Monkey patch _registerSourceProcessor and SourceProcessorSet.merge so we can block the default CSS compiler - */ -function monkeyPatchToHandleCssExtension() { - const registerSourceProcessor = Plugin._registerSourceProcessor; - Plugin._registerSourceProcessor = function(options, factory, { sourceProcessorSet, methodName, featurePackage }) { - const buildPluginMerge = sourceProcessorSet.constructor.prototype.merge; - sourceProcessorSet.constructor.prototype.merge = function(otherSet, options) { - /* If a css plugin handler has already been added, - * don't merge the meteor package, which only includes the 'css' package - */ - if (otherSet._myPackageDisplayName !== 'meteor' || !('css' in this._byExtension)) { - /* If we're using CSS modules inside of a package, it's possible that Meteor's CSS build plugin got merged - * before we could block it. In that case, unregister the Meteor CSS processor. - */ - if (('css' in this._byExtension) && 'css' in otherSet._byExtension) { // && sp.isopack.displayName() === 'meteor') - const previouslyRegisteredSourceProcessor = this._byExtension.css[0]; - if (previouslyRegisteredSourceProcessor.isopack.displayName() === 'meteor' && otherSet._myPackageDisplayName === 'nathantreid:css-modules') { - this.allSourceProcessors.splice(this.allSourceProcessors.indexOf(previouslyRegisteredSourceProcessor), 1); - delete this._byExtension.css; - } - } - buildPluginMerge.call(this, ...arguments); - } - }; - registerSourceProcessor(options, factory, { sourceProcessorSet, methodName, featurePackage }); - }; - - registerCompiler(); - - Plugin._registerSourceProcessor = registerSourceProcessor; -} +Plugin.registerCompiler({ + extensions: ['scss', 'sass'], + archMatching: pluginOptions.specificArchitecture || [], + filenames: pluginOptions.filenames || [] +}, function() { + return global.cssModules.compiler; +}); diff --git a/postcss-plugins.js b/postcss-plugins.js index 8f03e23..ed4d60c 100644 --- a/postcss-plugins.js +++ b/postcss-plugins.js @@ -1,84 +1,78 @@ import pluginOptionsWrapper from './options'; let pluginOptions = pluginOptionsWrapper.options; -import fs from 'fs'; -import cjson from 'cjson'; import path from 'path'; -import R from 'ramda'; +import * as R from 'ramda'; import ImportPathHelpers from './helpers/import-path-helpers'; import applyTemplateString from 'es6-template-strings'; -import hasha from 'hasha'; -import shorthash from 'shorthash'; const corePlugins = { - 'postcss-modules-local-by-default': require('postcss-modules-local-by-default'), - 'postcss-modules-extract-imports': require('postcss-modules-extract-imports'), - 'postcss-modules-scope': require('postcss-modules-scope'), - 'postcss-modules-values': require('postcss-modules-values'), + 'postcss-modules-local-by-default': require('postcss-modules-local-by-default'), + 'postcss-modules-extract-imports': require('postcss-modules-extract-imports'), + 'postcss-modules-scope': require('postcss-modules-scope'), + 'postcss-modules-values': require('postcss-modules-values'), }; corePlugins['postcss-modules-scope'].generateScopedName = function generateScopedName(exportedName, filePath) { - let sanitisedPath = path.relative(ImportPathHelpers.basePath, filePath).replace(/.*\{}[/\\]/, '').replace(/.*\{.*?}/, 'packages').replace(/\.[^\.\/\\]+$/, '').replace(/[\W_]+/g, '_').replace(/^_|_$/g, ''); - const filename = path.basename(filePath).replace(/\.[^\.\/\\]+$/, '').replace(/[\W_]+/g, '_').replace(/^_|_$/g, ''); - sanitisedPath = sanitisedPath.replace(new RegExp(`_(${filename})$`), '__$1'); - if (global.cssModules && global.cssModules.generateScopedName && typeof global.cssModules.generateScopedName === 'function') { - return global.cssModules.generateScopedName(exportedName, filePath, sanitisedPath); - } - let scopedName = `_${sanitisedPath}__${exportedName}`; - if (pluginOptions.cssClassNamingConvention && pluginOptions.cssClassNamingConvention.template) { - let templateString = pluginOptions.cssClassNamingConvention.template; - scopedName = applyTemplateString(templateString, { - hasha, - originalPath: filePath, - name: exportedName, - path: sanitisedPath, - scopedName, - shorthash, - }); - } - return runReplacers(scopedName); + let sanitisedPath = path.relative(ImportPathHelpers.basePath, filePath).replace(/.*\{}[/\\]/, '').replace(/.*\{.*?}/, 'packages').replace(/\.[^\.\/\\]+$/, '').replace(/[\W_]+/g, '_').replace(/^_|_$/g, ''); + const filename = path.basename(filePath).replace(/\.[^\.\/\\]+$/, '').replace(/[\W_]+/g, '_').replace(/^_|_$/g, ''); + sanitisedPath = sanitisedPath.replace(new RegExp(`_(${filename})$`), '__$1'); + if (global.cssModules && global.cssModules.generateScopedName && typeof global.cssModules.generateScopedName === 'function') { + return global.cssModules.generateScopedName(exportedName, filePath, sanitisedPath); + } + let scopedName = `_${sanitisedPath}__${exportedName}`; + if (pluginOptions.cssClassNamingConvention && pluginOptions.cssClassNamingConvention.template) { + let templateString = pluginOptions.cssClassNamingConvention.template; + scopedName = applyTemplateString(templateString, { + originalPath: filePath, + name: exportedName, + path: sanitisedPath, + scopedName + }); + } + return runReplacers(scopedName); }; function runReplacers(name) { - if (!pluginOptions.cssClassNamingConvention || !pluginOptions.cssClassNamingConvention.replacements || + if (!pluginOptions.cssClassNamingConvention || !pluginOptions.cssClassNamingConvention.replacements || pluginOptions.cssClassNamingConvention.replacements.length === 0) { - return name; - } + return name; + } - let trimmed = name; - for (let replacer of pluginOptions.cssClassNamingConvention.replacements) { - trimmed = replacer(trimmed); - } - return trimmed; + let trimmed = name; + for (let replacer of pluginOptions.cssClassNamingConvention.replacements) { + trimmed = replacer(trimmed); + } + return trimmed; } export default loadPlugins; function loadPlugins(options) { - pluginOptions = options; + pluginOptions = options; - const defaultOptions = { - 'postcss-modules-local-by-default': {}, - 'postcss-modules-extract-imports': {}, - 'postcss-modules-scope': {}, - 'postcss-modules-values': {} - }; - const postcssPluginsOptions = options.postcssPlugins || defaultOptions; - const plugins = []; + const defaultOptions = { + 'postcss-modules-local-by-default': {}, + 'postcss-modules-extract-imports': {}, + 'postcss-modules-scope': {}, + 'postcss-modules-values': {} + }; + const postcssPluginsOptions = options.postcssPlugins || defaultOptions; + const plugins = []; - R.forEach((pluginEntry) => { - const packageName = pluginEntry[0]; - let plugin = corePlugins[packageName] || require(packageName); - if (plugin === undefined) throw new Error(`plugin ${packageName} was not found by NPM!`); + R.forEach((pluginEntry) => { + const packageName = pluginEntry[0]; + let plugin = corePlugins[packageName] || require(packageName); + if (plugin === undefined) throw new Error(`plugin ${packageName} was not found by NPM!`); - var pluginEntryOptions = pluginEntry[1]; - if (options.globalVariablesJs && packageName === 'postcss-simple-vars') { - pluginEntryOptions = R.merge({ variables: options.globalVariablesJs }, pluginEntryOptions); - } - if (pluginEntryOptions && typeof pluginEntryOptions === 'object' && Object.keys(pluginEntryOptions).length === 0) { - pluginEntryOptions = undefined; - } - plugin = pluginEntryOptions !== undefined ? plugin(pluginEntryOptions) : plugin; - plugins.push(plugin); - }, R.toPairs(postcssPluginsOptions)); - return plugins; + var pluginEntryOptions = pluginEntry[1]; + if (options.globalVariablesJs && packageName === 'postcss-simple-vars') { + pluginEntryOptions = R.mergeAll([{ variables: options.globalVariablesJs }, pluginEntryOptions]); + } + if (pluginEntryOptions && typeof pluginEntryOptions === 'object' && Object.keys(pluginEntryOptions).length === 0) { + pluginEntryOptions = undefined; + } + plugin = pluginEntryOptions !== undefined ? plugin(pluginEntryOptions) : plugin; + plugins.push(plugin); + }, R.toPairs(postcssPluginsOptions)); + return plugins; } diff --git a/scss-processor.js b/scss-processor.js index c65c939..1ef76e9 100644 --- a/scss-processor.js +++ b/scss-processor.js @@ -1,145 +1,143 @@ import path from 'path'; -import fs from 'fs'; import IncludedFile from './included-file'; import ImportPathHelpers from './helpers/import-path-helpers'; import logger from './logger'; +import sass from 'sass-embedded'; +import { Meteor } from 'meteor/meteor'; +import { pathToFileURL } from 'url'; export default class ScssProcessor { - constructor(pluginOptions) { - this.fileCache = {}; - this.filesByName = null; - this.pluginOptions = pluginOptions; - this.sass = pluginOptions.enableSassCompilation ? require('node-sass') : null; - } - - isRoot(inputFile) { - const fileOptions = inputFile.getFileOptions(); - if (fileOptions.hasOwnProperty('isImport')) { - return !fileOptions.isImport; + constructor(pluginOptions) { + this.fileCache = {}; + this.filesByName = null; + this.pluginOptions = pluginOptions; } - return !hasUnderscore(inputFile.getPathInPackage()); - - function hasUnderscore(file) { - return path.basename(file)[0] === '_'; + async init() { + this.compiler = await sass.initAsyncCompiler(); } - } - shouldProcess(file) { - const sassCompilationExtensions = this.pluginOptions.enableSassCompilation; - if (!sassCompilationExtensions || typeof sassCompilationExtensions === 'boolean') { - return sassCompilationExtensions; - } + isRoot(inputFile) { + const fileOptions = inputFile.getFileOptions(); + if (fileOptions.hasOwnProperty('isImport')) { + return !fileOptions.isImport; + } - return sassCompilationExtensions.some((extension) => file.getPathInPackage().endsWith(extension)); - } - - process(file, filesByName) { - this.filesByName = filesByName; - try { - this._process(file); - } catch (err) { - const numberOfAdditionalLines = this.pluginOptions.globalVariablesTextLineCount - ? this.pluginOptions.globalVariablesTextLineCount + 1 - : 0; - const adjustedLineNumber = err.line - numberOfAdditionalLines; - logger.error(`\n/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`); - logger.error(`Processing Step: SCSS compilation`); - logger.error(`Unable to compile ${file.importPath}\nLine: ${adjustedLineNumber}, Column: ${err.column}\n${err}`); - logger.error(`\n/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`); - throw err; + return !hasUnderscore(inputFile.getPathInPackage()); + + function hasUnderscore(file) { + return path.basename(file)[0] === '_'; + } } - } - _process(file) { - if (file.isPreprocessed) return; + shouldProcess(file) { + const sassCompilationExtensions = this.pluginOptions.enableSassCompilation; + if (!sassCompilationExtensions || typeof sassCompilationExtensions === 'boolean') { + return sassCompilationExtensions; + } + + return sassCompilationExtensions.some((extension) => file.getPathInPackage().endsWith(extension)); + } - if (this.pluginOptions.enableDebugLog) { - console.log(`***\nSCSS process: ${file.importPath}`); + async process(file, filesByName) { + this.filesByName = filesByName; + try { + await this._process(file); + } catch (err) { + const numberOfAdditionalLines = this.pluginOptions.globalVariablesTextLineCount + ? this.pluginOptions.globalVariablesTextLineCount + 1 + : 0; + const adjustedLineNumber = err.line - numberOfAdditionalLines; + logger.error(`\n/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`); + logger.error(`Processing Step: SCSS compilation`); + logger.error(`Unable to compile ${file.importPath}\nLine: ${adjustedLineNumber}, Column: ${err.column}\n${err}`); + logger.error(`\n/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`); + throw err; + } } - const sourceFile = this._wrapFileForNodeSass(file); - const { css, sourceMap } = this._transpile(sourceFile); - file.contents = css; - file.sourceMap = sourceMap; - file.isPreprocessed = true; - } - - _wrapFileForNodeSass(file) { - return { path: file.importPath, contents: file.rawContents, file: file }; - } - - _discoverImportPath(importPath) { - const potentialPaths = [importPath]; - const potentialFileExtensions = this.pluginOptions.enableSassCompilation === true ? this.pluginOptions.extensions : this.pluginOptions.enableSassCompilation; - - potentialFileExtensions.forEach(extension => potentialPaths.push(`${importPath}.${extension}`)); - if (path.basename(importPath)[0] !== '_') { - [].concat(potentialPaths).forEach(potentialPath => potentialPaths.push(`${path.dirname(potentialPath)}/_${path.basename(potentialPath)}`)); + + async _process(file) { + if (file.isPreprocessed) return; + + if (this.pluginOptions.enableDebugLog) { + console.log(`***\nSCSS process: ${file.importPath}`); + } + const sourceFile = this._wrapFileForNodeSass(file); + const { css, sourceMap } = await this._transpile(sourceFile); + file.contents = css; + file.sourceMap = sourceMap; + file.isPreprocessed = true; } - for (let i = 0, potentialPath = potentialPaths[i]; i < potentialPaths.length; i++, potentialPath = potentialPaths[i]) { - if (this.filesByName.has(potentialPath) || (fs.existsSync(potentialPaths[i]) && fs.lstatSync(potentialPaths[i]).isFile())) { - return potentialPath; - } + _wrapFileForNodeSass(file) { + return { path: file.importPath, contents: file.rawContents, file: file }; } - throw new Error(`File '${importPath}' not found at any of the following paths: ${JSON.stringify(potentialPaths, null, 2)}`); - } - - _transpile(sourceFile) { - const sassOptions = { - sourceMap: true, - sourceMapContents: true, - sourceMapEmbed: false, - sourceComments: false, - sourceMapRoot: '.', - omitSourceMapUrl: true, - indentedSyntax: sourceFile.file.getExtension() === 'sass', - outFile: `.${sourceFile.file.getBasename()}`, - importer: this._importFile.bind(this, sourceFile), - includePaths: [], - file: sourceFile.path, - data: sourceFile.contents - }; - - /* Empty options.data workaround from fourseven:scss */ - if (!sassOptions.data.trim()) { - sassOptions.data = '$fakevariable : blue;'; + async _transpile(sourceFile) { + const sassOptions = { + sourceMap: Meteor.isProduction ? false : true, + sourceMapContents: Meteor.isProduction ? false : true, + sourceMapEmbed: false, + sourceComments: false, + sourceMapRoot: '.', + omitSourceMapUrl: true, + outFile: `.${sourceFile.file.getBasename()}`, + importer: { + findFileUrl: function(path) { + + let importPath = ImportPathHelpers.getImportPathRelativeToFile(decodeURI(path), sourceFile.file.importPath); + importPath = !importPath.endsWith('.scss') ? importPath + '.scss' : importPath; + + return pathToFileURL(importPath); + } + }, + includePaths: [], + }; + + try { + const output = await this.compiler.compileStringAsync(sourceFile.contents, sassOptions); + + return { css: output.css.toString('utf-8'), sourceMap: output && output.map && JSON.parse(output.map.toString('utf-8')) }; + } catch(err) { + logger.error(`\n/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`); + logger.error(`Processing Step: SCSS compilation`); + logger.error(`Unable to compile ${sourceFile.path}`); + logger.error(`Error: ${err.message}`); + logger.error(`\n/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`); + } } - const output = this.sass.renderSync(sassOptions); - return { css: output.css.toString('utf-8'), sourceMap: JSON.parse(output.map.toString('utf-8')) }; - } - - _importFile(rootFile, sourceFilePath, relativeTo) { - try { - if (this.pluginOptions.enableDebugLog) { - console.log(`***\nImport: ${sourceFilePath}\n rootFile: ${rootFile}`); - } - let importPath = ImportPathHelpers.getImportPathRelativeToFile(sourceFilePath, relativeTo); - importPath = this._discoverImportPath(importPath); - let inputFile = this.filesByName.get(importPath); - if (inputFile) { - rootFile.file.referencedImportPaths.push(importPath); - } else { - inputFile = this._createIncludedFile(importPath, rootFile); - } - - return this._wrapFileForNodeSassImport(inputFile, importPath); - } catch (err) { - return err; + _importFile(rootFile, sourceFilePath, relativeTo) { + try { + if (this.pluginOptions.enableDebugLog) { + console.log(`***\nImport: ${sourceFilePath}\n rootFile: ${rootFile}`); + } + let importPath = ImportPathHelpers.getImportPathRelativeToFile(sourceFilePath, relativeTo); + importPath = !importPath.endsWith('.scss') ? importPath + '.scss' : importPath; + + let inputFile = this.filesByName.get(importPath); + if (inputFile) { + rootFile.file.referencedImportPaths.push(importPath); + } else { + console.log('creating included file'); + inputFile = this._createIncludedFile(importPath, rootFile); + } + + return this._wrapFileForNodeSassImport(inputFile, importPath); + } catch (err) { + return err; + } } - } - _createIncludedFile(importPath, rootFile) { - const file = new IncludedFile(importPath, rootFile); - file.prepInputFile(); - this.filesByName.set(importPath, file); - return file; - } + _createIncludedFile(importPath, rootFile) { + const file = new IncludedFile(importPath, rootFile); + file.prepInputFile(); + this.filesByName.set(importPath, file); - _wrapFileForNodeSassImport(file, importPath) { - return { contents: file.rawContents, file: file.importPath || importPath }; - } + return file; + } + _wrapFileForNodeSassImport(file, importPath) { + return { contents: file.rawContents, file: file.importPath || importPath }; + } }; diff --git a/scss-processor.tests.js b/scss-processor.tests.js deleted file mode 100644 index cb2a0b7..0000000 --- a/scss-processor.tests.js +++ /dev/null @@ -1,177 +0,0 @@ -/* eslint-env node, mocha */ -import './test-helpers/global-variables.stub'; -import chai from 'chai'; -import ScssProcessor from './scss-processor'; -import { reloadOptions } from './options'; -import logger from './logger'; -import generateFileObject from './test-helpers/generate-file-object'; - -const expect = chai.expect; - -describe('ScssProcessor', function() { - describe('#isRoot', function() { - it('should return false if the filename starts with an underscore', function z() { - const file = generateFileObject('./_test.scss', ''); - - const options = { ...reloadOptions(), enableSassCompilation: true }; - const processor = new ScssProcessor(options); - - expect(processor.isRoot(file)).to.be.false; - }); - - it('should return false if the file options "isImport" property is true', function z() { - const file = generateFileObject('./test.scss', ''); - file.fileOptions.isImport = true; - - const options = { ...reloadOptions(), enableSassCompilation: true }; - const processor = new ScssProcessor(options); - - expect(processor.isRoot(file)).to.be.false; - }); - - it('should return true if the above conditions are not met', function z() { - const file = generateFileObject('./test.scss', ''); - - const options = { ...reloadOptions(), enableSassCompilation: true }; - const processor = new ScssProcessor(options); - - expect(processor.isRoot(file)).to.be.true; - }); - }); - - describe('#shouldProcess', function() { - it('should return true if enableSassCompilation is true', function z() { - const file = generateFileObject('./test.scss', ''); - - const options = { ...reloadOptions(), enableSassCompilation: true }; - const processor = new ScssProcessor(options); - - expect(processor.shouldProcess(file)).to.be.true; - }); - - it('should return false if enableSassCompilation is false', function z() { - const file = generateFileObject('./test.scss', ''); - - const options = { ...reloadOptions(), enableSassCompilation: false }; - const processor = new ScssProcessor(options); - - expect(processor.shouldProcess(file)).to.be.false; - }); - - it('should return true if the enableSassCompilation array contains the file\'s extension', function z() { - const file = generateFileObject('./test.scss', ''); - - const options = { ...reloadOptions(), enableSassCompilation: ['scss'] }; - const processor = new ScssProcessor(options); - - expect(processor.shouldProcess(file)).to.be.true; - }); - - it('should return false if the enableSassCompilation array does not contain the file\'s extension', function z() { - const file = generateFileObject('./test.scss', ''); - - const options = { ...reloadOptions(), enableSassCompilation: [] }; - const processor = new ScssProcessor(options); - - expect(processor.shouldProcess(file)).to.be.false; - }); - }); - - describe('#process', function() { - describe('file.contents', function() { - it('should transpile the passed in file', async function z() { - const file = generateFileObject('./test.scss', '.test { .nested { color: red; } } .test2 { color: blue; } // a comment'); - - const options = { ...reloadOptions(), enableSassCompilation: true }; - const processor = new ScssProcessor(options); - await processor.process(file); - - expect(file.contents).to.equal('.test .nested {\n color: red; }\n\n.test2 {\n color: blue; }\n\n/*# sourceMappingURL=.test.scss.map */'); - }); - }); - - describe('file.referencedImportPaths', function() { - it('should list all of the files that the current file imports', async function z() { - const allFiles = new Map(); - addFile(generateFileObject('./direct-import1.scss', '.test { color: red; }')); - addFile(generateFileObject('./direct-import2.scss', '@import "./indirect-import.scss"; .test { color: red; }')); - addFile(generateFileObject('./indirect-import.scss', '.test { color: red; }')); - const file = generateFileObject('./test.scss', '@import "./direct-import1.scss"; @import "./direct-import2"; .test { color: blue; }'); - - const options = { ...reloadOptions(), enableSassCompilation: true, extensions: ['scss'] }; - const processor = new ScssProcessor(options); - await processor.process(file, allFiles); - - expect(file.referencedImportPaths).to.eql([ - 'D:/projects/meteor-css-modules/direct-import1.scss', - 'D:/projects/meteor-css-modules/direct-import2.scss', - 'D:/projects/meteor-css-modules/indirect-import.scss' - ]); - - function addFile(file) { - allFiles.set(file.importPath, file); - } - }); - }); - - describe('file.sourcemap', function() { - it('should generate a sourcemap', async function z() { - const file = generateFileObject('./test.scss', '.test { color: red; } .test2 { color: blue; }'); - - const options = { ...reloadOptions(), enableSassCompilation: true }; - const processor = new ScssProcessor(options); - await processor.process(file); - - expect(file.sourceMap).to.eql({ - 'version': 3, - 'sourceRoot': '.', - 'file': '.test.scss', - 'sources': [ - 'test.scss' - ], - 'sourcesContent': [ - '.test { color: red; } .test2 { color: blue; }' - ], - 'mappings': 'AAAA,AAAA,KAAK,CAAC;EAAE,KAAK,EAAE,GAAI,GAAI;;AAAA,AAAA,MAAM,CAAC;EAAE,KAAK,EAAE,IAAK,GAAI', - 'names': [] - }); - }); - }); - - it('should log a friendly error when node-sass encounters an error', function z(done) { - const file = generateFileObject('./test.scss', '.test { error! }'); - - let fullErrorMessage = ''; - logger.test(function() { - logger.error.addHook(errorMessage => { - fullErrorMessage += errorMessage; - }); - - const options = { ...reloadOptions(), enableSassCompilation: true }; - const processor = new ScssProcessor(options); - try { - processor.process(file); - } catch (err) { - expect(fullErrorMessage).to.equal('\n/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Processing Step: SCSS compilationUnable to compile D:/projects/meteor-css-modules/test.scss\nLine: 1, Column: 9\nError: property "error" must be followed by a \':\'\n/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'); - done(); - } - }); - }); - - it('should throw an error when node-sass encounters an error', function z(done) { - const file = generateFileObject('./test.scss', '.test { error! }'); - - logger.test(function() { - const options = { ...reloadOptions(), enableSassCompilation: true }; - const processor = new ScssProcessor(options); - try { - processor.process(file); - } catch (err) { - done(); - } - }); - }); - - }); -}); - diff --git a/stylus-processor.js b/stylus-processor.js deleted file mode 100644 index a59d2b5..0000000 --- a/stylus-processor.js +++ /dev/null @@ -1,80 +0,0 @@ -import Future from 'fibers/future'; -import path from 'path'; -import pluginOptions from './options'; -import logger from './logger'; - -export default class StylusProcessor { - constructor(pluginOptions) { - this.fileCache = {}; - this.filesByName = null; - this.pluginOptions = pluginOptions; - this.stylus = pluginOptions.enableStylusCompilation ? require('stylus') : null; - } - - isRoot(inputFile) { - const fileOptions = inputFile.getFileOptions(); - if (fileOptions.hasOwnProperty('isImport')) { - return !fileOptions.isImport; - } - - return !hasUnderscore(inputFile.getPathInPackage()); - - function hasUnderscore(file) { - return path.basename(file)[0] === '_'; - } - } - - shouldProcess(file) { - const stylusCompilationExtensions = this.pluginOptions.enableStylusCompilation; - if (!stylusCompilationExtensions || typeof stylusCompilationExtensions === 'boolean') { - return stylusCompilationExtensions; - } - - return stylusCompilationExtensions.some((extension) => file.getPathInPackage().endsWith(extension)); - } - - process(file, filesByName) { - this.filesByName = filesByName; - try { - this._process(file); - } catch (err) { - const numberOfAdditionalLines = this.pluginOptions.globalVariablesTextLineCount - ? this.pluginOptions.globalVariablesTextLineCount + 1 - : 0; - const adjustedLineNumber = err.line - numberOfAdditionalLines; - logger.error(`\n/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`); - logger.error(`Processing Step: Stylus compilation`); - logger.error(`Unable to compile ${file.importPath}\nLine: ${adjustedLineNumber}, Column: ${err.column}\n${err}`); - logger.error(`\n/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`); - throw err; - } - } - - _process(file) { - if (file.isPreprocessed) return; - - const { css, sourceMap } = this._transpile(file); - file.contents = css; - file.sourceMap = sourceMap; - file.isPreprocessed = true; - } - - _transpile(sourceFile) { - const future = new Future(); - const options = { - filename: sourceFile.importPath, - sourcemap: { - comment: false - } - }; - - this.stylus.render(sourceFile.rawContents, options, (err, css) => { - if (err) { - return future.throw(err); - } - future.return({ css, sourceMap: this.stylus.sourcemap }); - }); - - return future.wait(); - } -}; diff --git a/test-helpers/babel-hook.js b/test-helpers/babel-hook.js deleted file mode 100644 index bbde9a0..0000000 --- a/test-helpers/babel-hook.js +++ /dev/null @@ -1,25 +0,0 @@ -// This file is required in mocha.opts -// The only purpose of this file is to ensure -// the babel transpiler is activated prior to any -// test code, and using the same babel options -require('babel-register')({ - presets: [ - 'es2015' - ], - plugins: [ - 'transform-object-rest-spread', - 'transform-es2015-destructuring', - 'syntax-async-functions', - 'syntax-async-generators', - 'transform-regenerator', - // 'babel-project-relative-import', - // { - // 'importPathPrefix': '/' - // }, - - ] -}) - -require('babel-polyfill') - -require('./import-path-helpers.stub'); diff --git a/test-helpers/caching-compiler.js b/test-helpers/caching-compiler.js deleted file mode 100644 index bb66128..0000000 --- a/test-helpers/caching-compiler.js +++ /dev/null @@ -1,362 +0,0 @@ -import { Random } from './random'; - -/* https://raw.githubusercontent.com/meteor/meteor/devel/packages/caching-compiler/caching-compiler.js*/ -/* eslint-disable space-unary-ops, curly, template-curly-spacing, operator-linebreak, space-before-function-paren */ -/* eslint-disable handle-callback-err, new-parens */ -const fs = require('fs'); -const path = require('path'); -const createHash = require('crypto').createHash; -const assert = require('assert'); -const Future = require('fibers/future'); -const LRU = require('lru-cache'); -const async = require('async'); - -// Base class for CachingCompiler and MultiFileCachingCompiler. -export class CachingCompilerBase { - constructor({ - compilerName, - defaultCacheSize, - maxParallelism = 20, - }) { - this._compilerName = compilerName; - this._maxParallelism = maxParallelism; - const envVarPrefix = 'METEOR_' + compilerName.toUpperCase() + '_CACHE_'; - - const debugEnvVar = envVarPrefix + 'DEBUG'; - this._cacheDebugEnabled = !! process.env[debugEnvVar]; - - const cacheSizeEnvVar = envVarPrefix + 'SIZE'; - this._cacheSize = +process.env[cacheSizeEnvVar] || defaultCacheSize; - - this._diskCache = null; - - // For testing. - this._callCount = 0; - } - - // Your subclass must override this method to define the key used to identify - // a particular version of an InputFile. - // - // Given an InputFile (the data type passed to processFilesForTarget as part - // of the Plugin.registerCompiler API), returns a cache key that represents - // it. This cache key can be any JSON value (it will be converted internally - // into a hash). This should reflect any aspect of the InputFile that affects - // the output of `compileOneFile`. Typically you'll want to include - // `inputFile.getDeclaredExports()`, and perhaps - // `inputFile.getPathInPackage()` or `inputFile.getDeclaredExports` if - // `compileOneFile` pays attention to them. - // - // Note that for MultiFileCachingCompiler, your cache key doesn't need to - // include the file's path, because that is automatically taken into account - // by the implementation. CachingCompiler subclasses can choose whether or not - // to include the file's path in the cache key. - getCacheKey(inputFile) { - throw Error('CachingCompiler subclass should implement getCacheKey!'); - } - - // Your subclass must override this method to define how a CompileResult - // translates into adding assets to the bundle. - // - // This method is given an InputFile (the data type passed to - // processFilesForTarget as part of the Plugin.registerCompiler API) and a - // CompileResult (either returned directly from compileOneFile or read from - // the cache). It should call methods like `inputFile.addJavaScript` - // and `inputFile.error`. - addCompileResult(inputFile, compileResult) { - throw Error('CachingCompiler subclass should implement addCompileResult!'); - } - - // Your subclass must override this method to define the size of a - // CompilerResult (used by the in-memory cache to limit the total amount of - // data cached). - compileResultSize(compileResult) { - throw Error('CachingCompiler subclass should implement compileResultSize!'); - } - - // Your subclass may override this method to define an alternate way of - // stringifying CompilerResults. Takes a CompileResult and returns a string. - stringifyCompileResult(compileResult) { - return JSON.stringify(compileResult); - } - // Your subclass may override this method to define an alternate way of - // parsing CompilerResults from string. Takes a string and returns a - // CompileResult. If the string doesn't represent a valid CompileResult, you - // may want to return null instead of throwing, which will make - // CachingCompiler ignore the cache. - parseCompileResult(stringifiedCompileResult) { - return this._parseJSONOrNull(stringifiedCompileResult); - } - _parseJSONOrNull(json) { - try { - return JSON.parse(json); - } catch (e) { - if (e instanceof SyntaxError) - return null; - throw e; - } - } - - _cacheDebug(message) { - if (!this._cacheDebugEnabled) - return; - console.log(`CACHE(${ this._compilerName }): ${ message }`); - } - - setDiskCacheDirectory(diskCache) { - if (this._diskCache) - throw Error('setDiskCacheDirectory called twice?'); - this._diskCache = diskCache; - } - - // Since so many compilers will need to calculate the size of a SourceMap in - // their compileResultSize, this method is provided. - sourceMapSize(sm) { - if (! sm) return 0; - // sum the length of sources and the mappings, the size of - // metadata is ignored, but it is not a big deal - return sm.mappings.length - + (sm.sourcesContent || []).reduce(function (soFar, current) { - return soFar + (current ? current.length : 0); - }, 0); - } - - // Borrowed from another MIT-licensed project that benjamn wrote: - // https://github.com/reactjs/commoner/blob/235d54a12c/lib/util.js#L136-L168 - _deepHash(val) { - const hash = createHash('sha1'); - let type = typeof val; - - if (val === null) { - type = 'null'; - } - hash.update(type + '\0'); - - switch (type) { - case 'object': - const keys = Object.keys(val); - - // Array keys will already be sorted. - if (! Array.isArray(val)) { - keys.sort(); - } - - keys.forEach((key) => { - if (typeof val[key] === 'function') { - // Silently ignore nested methods, but nevertheless complain below - // if the root value is a function. - return; - } - - hash.update(key + '\0').update(this._deepHash(val[key])); - }); - - break; - - case 'function': - assert.ok(false, 'cannot hash function objects'); - break; - - default: - hash.update('' + val); - break; - } - - return hash.digest('hex'); - } - - // We want to write the file atomically. But we also don't want to block - // processing on the file write. - _writeFileAsync(filename, contents) { - const tempFilename = filename + '.tmp.' + Random.id(); - fs.writeFile(tempFilename, contents, (err) => { - // ignore errors, it's just a cache - if (err) { - return; - } - fs.rename(tempFilename, filename, (err) => { - // ignore this error too. - }); - }); - } - - // Helper function. Returns the body of the file as a string, or null if it - // doesn't exist. - _readFileOrNull(filename) { - try { - return fs.readFileSync(filename, 'utf8'); - } catch (e) { - if (e && e.code === 'ENOENT') - return null; - throw e; - } - } -} - -// CachingCompiler is a class designed to be used with Plugin.registerCompiler -// which implements in-memory and on-disk caches for the files that it -// processes. You should subclass CachingCompiler and define the following -// methods: getCacheKey, compileOneFile, addCompileResult, and -// compileResultSize. -// -// CachingCompiler assumes that files are processed independently of each other; -// there is no 'import' directive allowing one file to reference another. That -// is, editing one file should only require that file to be rebuilt, not other -// files. -// -// The data that is cached for each file is of a type that is (implicitly) -// defined by your subclass. CachingCompiler refers to this type as -// `CompileResult`, but this isn't a single type: it's up to your subclass to -// decide what type of data this is. You should document what your subclass's -// CompileResult type is. -// -// Your subclass's compiler should call the superclass compiler specifying the -// compiler name (used to generate environment variables for debugging and -// tweaking in-memory cache size) and the default cache size. -// -// By default, CachingCompiler processes each file in "parallel". That is, if it -// needs to yield to read from the disk cache, or if getCacheKey, -// compileOneFile, or addCompileResult yields, it will start processing the next -// few files. To set how many files can be processed in parallel (including -// setting it to 1 if your subclass doesn't support any parallelism), pass the -// maxParallelism option to the superclass constructor. -// -// For example (using ES2015 via the ecmascript package): -// -// class AwesomeCompiler extends CachingCompiler { -// constructor() { -// super({ -// compilerName: 'awesome', -// defaultCacheSize: 1024*1024*10, -// }); -// } -// // ... define the other methods -// } -// Plugin.registerCompile({ -// extensions: ['awesome'], -// }, () => new AwesomeCompiler()); -// -// XXX maybe compileResultSize and stringifyCompileResult should just be methods -// on CompileResult? Sort of hard to do that with parseCompileResult. -export class CachingCompiler extends CachingCompilerBase { - constructor({ - compilerName, - defaultCacheSize, - maxParallelism = 20, - }) { - super({compilerName, defaultCacheSize, maxParallelism}); - - // Maps from a hashed cache key to a compileResult. - this._cache = new LRU({ - max: this._cacheSize, - length: (value) => this.compileResultSize(value), - }); - } - - // Your subclass must override this method to define the transformation from - // InputFile to its cacheable CompileResult). - // - // Given an InputFile (the data type passed to processFilesForTarget as part - // of the Plugin.registerCompiler API), compiles the file and returns a - // CompileResult (the cacheable data type specific to your subclass). - // - // This method is not called on files when a valid cache entry exists in - // memory or on disk. - // - // On a compile error, you should call `inputFile.error` appropriately and - // return null; this will not be cached. - // - // This method should not call `inputFile.addJavaScript` and similar files! - // That's what addCompileResult is for. - compileOneFile(inputFile) { - throw Error('CachingCompiler subclass should implement compileOneFile!'); - } - - // The processFilesForTarget method from the Plugin.registerCompiler API. If - // you have processing you want to perform at the beginning or end of a - // processing phase, you may want to override this method and call the - // superclass implementation from within your method. - processFilesForTarget(inputFiles) { - const cacheMisses = []; - - const future = new Future; - async.eachLimit(inputFiles, this._maxParallelism, (inputFile, cb) => { - let error = null; - try { - const cacheKey = this._deepHash(this.getCacheKey(inputFile)); - let compileResult = this._cache.get(cacheKey); - - if (! compileResult) { - compileResult = this._readCache(cacheKey); - if (compileResult) { - this._cacheDebug(`Loaded ${ inputFile.getDisplayPath() }`); - } - } - - if (! compileResult) { - cacheMisses.push(inputFile.getDisplayPath()); - compileResult = this.compileOneFile(inputFile); - - if (! compileResult) { - // compileOneFile should have called inputFile.error. - // We don't cache failures for now. - return; - } - - // Save what we've compiled. - this._cache.set(cacheKey, compileResult); - this._writeCacheAsync(cacheKey, compileResult); - } - - this.addCompileResult(inputFile, compileResult); - } catch (e) { - error = e; - } finally { - cb(error); - } - }, future.resolver()); - future.wait(); - - if (this._cacheDebugEnabled) { - cacheMisses.sort(); - this._cacheDebug( - `Ran (#${ ++this._callCount }) on: ${ JSON.stringify(cacheMisses) }`); - } - } - - _cacheFilename(cacheKey) { - // We want cacheKeys to be hex so that they work on any FS and never end in - // .cache. - if (!/^[a-f0-9]+$/.test(cacheKey)) { - throw Error('bad cacheKey: ' + cacheKey); - } - return path.join(this._diskCache, cacheKey + '.cache'); - } - // Load a cache entry from disk. Returns the compileResult object - // and loads it into the in-memory cache too. - _readCache(cacheKey) { - if (! this._diskCache) { - return null; - } - const cacheFilename = this._cacheFilename(cacheKey); - const compileResult = this._readAndParseCompileResultOrNull(cacheFilename); - if (! compileResult) { - return null; - } - this._cache.set(cacheKey, compileResult); - return compileResult; - } - _writeCacheAsync(cacheKey, compileResult) { - if (! this._diskCache) - return; - const cacheFilename = this._cacheFilename(cacheKey); - const cacheContents = this.stringifyCompileResult(compileResult); - this._writeFileAsync(cacheFilename, cacheContents); - } - - // Returns null if the file does not exist or can't be parsed; otherwise - // returns the parsed compileResult in the file. - _readAndParseCompileResultOrNull(filename) { - const raw = this._readFileOrNull(filename); - return this.parseCompileResult(raw); - } -} diff --git a/test-helpers/explicit-includes/a.css b/test-helpers/explicit-includes/a.css deleted file mode 100644 index e69de29..0000000 diff --git a/test-helpers/explicit-includes/b.css b/test-helpers/explicit-includes/b.css deleted file mode 100644 index e69de29..0000000 diff --git a/test-helpers/generate-file-object.js b/test-helpers/generate-file-object.js deleted file mode 100644 index 24d0503..0000000 --- a/test-helpers/generate-file-object.js +++ /dev/null @@ -1,45 +0,0 @@ -import ImportPathHelpers from '../helpers/import-path-helpers'; -import path from 'path'; - -export default function generateFileObject(filePath, rawContents, packageName = null) { - const file = { - fileOptions: {}, - rawContents, - referencedImportPaths: [], - arch: 'web', - getPackageName() { - return packageName; - }, - getPathInPackage() { - return filePath; - }, - getBasename() { - return path.basename(filePath); - }, - getExtension() { - return path.extname(filePath); - } - }; - - file.getFileOptions = function() { - return file.fileOptions; - }; - - file.getContentsAsString = function() { - return file.rawContents; - }; - - file.getArch = function() { - return file.arch; - }; - - file.importPath = ImportPathHelpers.getImportPathInPackage(file); - - return file; -} - -export function generatePreprocessedFileObject(filePath, rawContents, packageName = null) { - const file = generateFileObject(filePath, rawContents, packageName = null); - file.contents = file.rawContents; - return file; -} diff --git a/test-helpers/global-variables.stub.js b/test-helpers/global-variables.stub.js deleted file mode 100644 index 73eb624..0000000 --- a/test-helpers/global-variables.stub.js +++ /dev/null @@ -1,20 +0,0 @@ -/* eslint-env node */ -/* global Promise */ -import Future from 'fibers/future'; - -// noinspection JSUndefinedPropertyAssignment -// noinspection JSAnnotator -global.Npm = { - require -}; - -/* eslint-disable no-extend-native */ -Promise.prototype.await = function await() { - const future = new Future(); - this.then(function(result) { - future.return(result); - }).catch(function(err) { - future.throw(err); - }); - return future.wait(); -}; diff --git a/test-helpers/import-path-helpers.stub.js b/test-helpers/import-path-helpers.stub.js deleted file mode 100644 index 69a5a9d..0000000 --- a/test-helpers/import-path-helpers.stub.js +++ /dev/null @@ -1,2 +0,0 @@ -import ImportPathHelpers from '../helpers/import-path-helpers'; -ImportPathHelpers.basePath = process.cwd(); diff --git a/test-helpers/multi-file-caching-compiler.js b/test-helpers/multi-file-caching-compiler.js deleted file mode 100644 index fe586a5..0000000 --- a/test-helpers/multi-file-caching-compiler.js +++ /dev/null @@ -1,219 +0,0 @@ -/* https://raw.githubusercontent.com/meteor/meteor/devel/packages/caching-compiler/multi-file-caching-compiler.js */ -const path = require('path'); -const Future = require('fibers/future'); -const LRU = require('lru-cache'); -const async = require('async'); - -import { CachingCompilerBase } from './caching-compiler'; - -// MultiFileCachingCompiler is like CachingCompiler, but for implementing -// languages which allow files to reference each other, such as CSS -// preprocessors with `@import` directives. -// -// Like CachingCompiler, you should subclass MultiFileCachingCompiler and define -// the following methods: getCacheKey, compileOneFile, addCompileResult, and -// compileResultSize. compileOneFile gets an additional allFiles argument and -// returns an array of referenced import paths in addition to the CompileResult. -// You may also override isRoot and getAbsoluteImportPath to customize -// MultiFileCachingCompiler further. -export class MultiFileCachingCompiler -extends CachingCompilerBase { - constructor({ - compilerName, - defaultCacheSize, - maxParallelism - }) { - super({compilerName, defaultCacheSize, maxParallelism}); - - // Maps from absolute import path to { compileResult, cacheKeys }, where - // cacheKeys is an object mapping from absolute import path to hashed - // cacheKey for each file referenced by this file (including itself). - this._cache = new LRU({ - max: this._cacheSize, - // We ignore the size of cacheKeys here. - length: (value) => this.compileResultSize(value.compileResult), - }); - } - - // Your subclass must override this method to define the transformation from - // InputFile to its cacheable CompileResult). - // - // Arguments: - // - inputFile is the InputFile to process - // - allFiles is a a Map mapping from absolute import path to InputFile of - // all files being processed in the target - // Returns an object with keys: - // - compileResult: the CompileResult (the cacheable data type specific to - // your subclass). - // - referencedImportPaths: an array of absolute import paths of files - // which were refererenced by the current file. The current file - // is included implicitly. - // - // This method is not called on files when a valid cache entry exists in - // memory or on disk. - // - // On a compile error, you should call `inputFile.error` appropriately and - // return null; this will not be cached. - // - // This method should not call `inputFile.addJavaScript` and similar files! - // That's what addCompileResult is for. - compileOneFile(inputFile, allFiles) { - throw Error( - 'MultiFileCachingCompiler subclass should implement compileOneFile!'); - } - - // Your subclass may override this to declare that a file is not a "root" --- - // ie, it can be included from other files but is not processed on its own. In - // this case, MultiFileCachingCompiler won't waste time trying to look for a - // cache for its compilation on disk. - isRoot(inputFile) { - return true; - } - - // Returns the absolute import path for an InputFile. By default, this is a - // path is a path of the form "{package}/path/to/file" for files in packages - // and "{}/path/to/file" for files in apps. Your subclass may override and/or - // call this method. - getAbsoluteImportPath(inputFile) { - if (inputFile.getPackageName() === null) { - return '{}/' + inputFile.getPathInPackage(); - } - return '{' + inputFile.getPackageName() + '}/' - + inputFile.getPathInPackage(); - } - - // The processFilesForTarget method from the Plugin.registerCompiler API. - processFilesForTarget(inputFiles) { - const allFiles = new Map; - const cacheKeyMap = new Map; - const cacheMisses = []; - - inputFiles.forEach((inputFile) => { - const importPath = this.getAbsoluteImportPath(inputFile); - allFiles.set(importPath, inputFile); - cacheKeyMap.set(importPath, this._deepHash(this.getCacheKey(inputFile))); - }); - - const allProcessedFuture = new Future; - async.eachLimit(inputFiles, this._maxParallelism, (inputFile, cb) => { - let error = null; - try { - // If this isn't a root, skip it (and definitely don't waste time - // looking for a cache file that won't be there). - if (!this.isRoot(inputFile)) { - return; - } - - const absoluteImportPath = this.getAbsoluteImportPath(inputFile); - let cacheEntry = this._cache.get(absoluteImportPath); - if (! cacheEntry) { - cacheEntry = this._readCache(absoluteImportPath); - if (cacheEntry) { - this._cacheDebug(`Loaded ${ absoluteImportPath }`); - } - } - if (! (cacheEntry && this._cacheEntryValid(cacheEntry, cacheKeyMap))) { - cacheMisses.push(inputFile.getDisplayPath()); - - const compileOneFileReturn = this.compileOneFile(inputFile, allFiles); - if (! compileOneFileReturn) { - // compileOneFile should have called inputFile.error. - // We don't cache failures for now. - return; - } - const {compileResult, referencedImportPaths} = compileOneFileReturn; - - cacheEntry = { - compileResult, - cacheKeys: { - // Include the hashed cache key of the file itself... - [absoluteImportPath]: cacheKeyMap.get(absoluteImportPath) - } - }; - - // ... and of the other referenced files. - referencedImportPaths.forEach((path) => { - if (!cacheKeyMap.has(path)) { - throw Error(`Unknown absolute import path ${ path }`); - } - cacheEntry.cacheKeys[path] = cacheKeyMap.get(path); - }); - - // Save the cache entry. - this._cache.set(absoluteImportPath, cacheEntry); - this._writeCacheAsync(absoluteImportPath, cacheEntry); - } - - this.addCompileResult(inputFile, cacheEntry.compileResult); - } catch (e) { - error = e; - } finally { - cb(error); - } - }, allProcessedFuture.resolver()); - allProcessedFuture.wait(); - - if (this._cacheDebugEnabled) { - cacheMisses.sort(); - this._cacheDebug( - `Ran (#${ ++this._callCount }) on: ${ JSON.stringify(cacheMisses) }`); - } - } - - _cacheEntryValid(cacheEntry, cacheKeyMap) { - return Object.keys(cacheEntry.cacheKeys).every( - (path) => cacheEntry.cacheKeys[path] === cacheKeyMap.get(path) - ); - } - - // The format of a cache file on disk is the JSON-stringified cacheKeys - // object, a newline, followed by the CompileResult as returned from - // this.stringifyCompileResult. - _cacheFilename(absoluteImportPath) { - return path.join(this._diskCache, - this._deepHash(absoluteImportPath) + '.cache'); - } - // Loads a {compileResult, cacheKeys} cache entry from disk. Returns the whole - // cache entry and loads it into the in-memory cache too. - _readCache(absoluteImportPath) { - if (! this._diskCache) { - return null; - } - const cacheFilename = this._cacheFilename(absoluteImportPath); - const raw = this._readFileOrNull(cacheFilename); - if (!raw) { - return null; - } - - // Split on newline. - const newlineIndex = raw.indexOf('\n'); - if (newlineIndex === -1) { - return null; - } - const cacheKeysString = raw.substring(0, newlineIndex); - const compileResultString = raw.substring(newlineIndex + 1); - - const cacheKeys = this._parseJSONOrNull(cacheKeysString); - if (!cacheKeys) { - return null; - } - const compileResult = this.parseCompileResult(compileResultString); - if (! compileResult) { - return null; - } - - const cacheEntry = {compileResult, cacheKeys}; - this._cache.set(absoluteImportPath, cacheEntry); - return cacheEntry; - } - _writeCacheAsync(absoluteImportPath, cacheEntry) { - if (! this._diskCache) { - return null; - } - const cacheFilename = this._cacheFilename(absoluteImportPath); - const cacheContents = - JSON.stringify(cacheEntry.cacheKeys) + '\n' - + this.stringifyCompileResult(cacheEntry.compileResult); - this._writeFileAsync(cacheFilename, cacheContents); - } -} diff --git a/test-helpers/random.js b/test-helpers/random.js deleted file mode 100644 index d20f985..0000000 --- a/test-helpers/random.js +++ /dev/null @@ -1,309 +0,0 @@ -const Meteor = { - isServer: true -}; -const Npm = { - require -}; -let Random; - -/* https://raw.githubusercontent.com/meteor/meteor/devel/packages/random/random.js */ -// We use cryptographically strong PRNGs (crypto.getRandomBytes() on the server, -// window.crypto.getRandomValues() in the browser) when available. If these -// PRNGs fail, we fall back to the Alea PRNG, which is not cryptographically -// strong, and we seed it with various sources such as the date, Math.random, -// and window size on the client. When using crypto.getRandomValues(), our -// primitive is hexString(), from which we construct fraction(). When using -// window.crypto.getRandomValues() or alea, the primitive is fraction and we use -// that to construct hex string. - -if (Meteor.isServer) - var nodeCrypto = Npm.require('crypto'); - -// see http://baagoe.org/en/wiki/Better_random_numbers_for_javascript -// for a full discussion and Alea implementation. -var Alea = function () { - function Mash() { - var n = 0xefc8249d; - - var mash = function(data) { - data = data.toString(); - for (var i = 0; i < data.length; i++) { - n += data.charCodeAt(i); - var h = 0.02519603282416938 * n; - n = h >>> 0; - h -= n; - h *= n; - n = h >>> 0; - h -= n; - n += h * 0x100000000; // 2^32 - } - return (n >>> 0) * 2.3283064365386963e-10; // 2^-32 - }; - - mash.version = 'Mash 0.9'; - return mash; - } - - return (function (args) { - var s0 = 0; - var s1 = 0; - var s2 = 0; - var c = 1; - - if (args.length == 0) { - args = [+new Date]; - } - var mash = Mash(); - s0 = mash(' '); - s1 = mash(' '); - s2 = mash(' '); - - for (var i = 0; i < args.length; i++) { - s0 -= mash(args[i]); - if (s0 < 0) { - s0 += 1; - } - s1 -= mash(args[i]); - if (s1 < 0) { - s1 += 1; - } - s2 -= mash(args[i]); - if (s2 < 0) { - s2 += 1; - } - } - mash = null; - - var random = function() { - var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32 - s0 = s1; - s1 = s2; - return s2 = t - (c = t | 0); - }; - random.uint32 = function() { - return random() * 0x100000000; // 2^32 - }; - random.fract53 = function() { - return random() + - (random() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53 - }; - random.version = 'Alea 0.9'; - random.args = args; - return random; - - } (Array.prototype.slice.call(arguments))); -}; - -var UNMISTAKABLE_CHARS = "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz"; -var BASE64_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + - "0123456789-_"; - -// `type` is one of `RandomGenerator.Type` as defined below. -// -// options: -// - seeds: (required, only for RandomGenerator.Type.ALEA) an array -// whose items will be `toString`ed and used as the seed to the Alea -// algorithm -var RandomGenerator = function (type, options) { - var self = this; - self.type = type; - - if (!RandomGenerator.Type[type]) { - throw new Error("Unknown random generator type: " + type); - } - - if (type === RandomGenerator.Type.ALEA) { - if (!options.seeds) { - throw new Error("No seeds were provided for Alea PRNG"); - } - self.alea = Alea.apply(null, options.seeds); - } -}; - -// Types of PRNGs supported by the `RandomGenerator` class -RandomGenerator.Type = { - // Use Node's built-in `crypto.getRandomBytes` (cryptographically - // secure but not seedable, runs only on the server). Reverts to - // `crypto.getPseudoRandomBytes` in the extremely uncommon case that - // there isn't enough entropy yet - NODE_CRYPTO: "NODE_CRYPTO", - - // Use non-IE browser's built-in `window.crypto.getRandomValues` - // (cryptographically secure but not seedable, runs only in the - // browser). - BROWSER_CRYPTO: "BROWSER_CRYPTO", - - // Use the *fast*, seedaable and not cryptographically secure - // Alea algorithm - ALEA: "ALEA", -}; - -/** - * @name Random.fraction - * @summary Return a number between 0 and 1, like `Math.random`. - * @locus Anywhere - */ -RandomGenerator.prototype.fraction = function () { - var self = this; - if (self.type === RandomGenerator.Type.ALEA) { - return self.alea(); - } else if (self.type === RandomGenerator.Type.NODE_CRYPTO) { - var numerator = parseInt(self.hexString(8), 16); - return numerator * 2.3283064365386963e-10; // 2^-32 - } else if (self.type === RandomGenerator.Type.BROWSER_CRYPTO) { - var array = new Uint32Array(1); - window.crypto.getRandomValues(array); - return array[0] * 2.3283064365386963e-10; // 2^-32 - } else { - throw new Error('Unknown random generator type: ' + self.type); - } -}; - -/** - * @name Random.hexString - * @summary Return a random string of `n` hexadecimal digits. - * @locus Anywhere - * @param {Number} n Length of the string - */ -RandomGenerator.prototype.hexString = function (digits) { - var self = this; - if (self.type === RandomGenerator.Type.NODE_CRYPTO) { - var numBytes = Math.ceil(digits / 2); - var bytes; - // Try to get cryptographically strong randomness. Fall back to - // non-cryptographically strong if not available. - try { - bytes = nodeCrypto.randomBytes(numBytes); - } catch (e) { - // XXX should re-throw any error except insufficient entropy - bytes = nodeCrypto.pseudoRandomBytes(numBytes); - } - var result = bytes.toString("hex"); - // If the number of digits is odd, we'll have generated an extra 4 bits - // of randomness, so we need to trim the last digit. - return result.substring(0, digits); - } else { - return this._randomString(digits, "0123456789abcdef"); - } -}; - -RandomGenerator.prototype._randomString = function (charsCount, - alphabet) { - var self = this; - var digits = []; - for (var i = 0; i < charsCount; i++) { - digits[i] = self.choice(alphabet); - } - return digits.join(""); -}; - -/** - * @name Random.id - * @summary Return a unique identifier, such as `"Jjwjg6gouWLXhMGKW"`, that is - * likely to be unique in the whole world. - * @locus Anywhere - * @param {Number} [n] Optional length of the identifier in characters - * (defaults to 17) - */ -RandomGenerator.prototype.id = function (charsCount) { - var self = this; - // 17 characters is around 96 bits of entropy, which is the amount of - // state in the Alea PRNG. - if (charsCount === undefined) - charsCount = 17; - - return self._randomString(charsCount, UNMISTAKABLE_CHARS); -}; - -/** - * @name Random.secret - * @summary Return a random string of printable characters with 6 bits of - * entropy per character. Use `Random.secret` for security-critical secrets - * that are intended for machine, rather than human, consumption. - * @locus Anywhere - * @param {Number} [n] Optional length of the secret string (defaults to 43 - * characters, or 256 bits of entropy) - */ -RandomGenerator.prototype.secret = function (charsCount) { - var self = this; - // Default to 256 bits of entropy, or 43 characters at 6 bits per - // character. - if (charsCount === undefined) - charsCount = 43; - return self._randomString(charsCount, BASE64_CHARS); -}; - -/** - * @name Random.choice - * @summary Return a random element of the given array or string. - * @locus Anywhere - * @param {Array|String} arrayOrString Array or string to choose from - */ -RandomGenerator.prototype.choice = function (arrayOrString) { - var index = Math.floor(this.fraction() * arrayOrString.length); - if (typeof arrayOrString === "string") - return arrayOrString.substr(index, 1); - else - return arrayOrString[index]; -}; - -// instantiate RNG. Heuristically collect entropy from various sources when a -// cryptographic PRNG isn't available. - -// client sources -var height = (typeof window !== 'undefined' && window.innerHeight) || - (typeof document !== 'undefined' - && document.documentElement - && document.documentElement.clientHeight) || - (typeof document !== 'undefined' - && document.body - && document.body.clientHeight) || - 1; - -var width = (typeof window !== 'undefined' && window.innerWidth) || - (typeof document !== 'undefined' - && document.documentElement - && document.documentElement.clientWidth) || - (typeof document !== 'undefined' - && document.body - && document.body.clientWidth) || - 1; - -var agent = (typeof navigator !== 'undefined' && navigator.userAgent) || ""; - -function createAleaGeneratorWithGeneratedSeed() { - return new RandomGenerator( - RandomGenerator.Type.ALEA, - {seeds: [new Date, height, width, agent, Math.random()]}); -}; - -if (Meteor.isServer) { - Random = new RandomGenerator(RandomGenerator.Type.NODE_CRYPTO); -} else { - if (typeof window !== "undefined" && window.crypto && - window.crypto.getRandomValues) { - Random = new RandomGenerator(RandomGenerator.Type.BROWSER_CRYPTO); - } else { - // On IE 10 and below, there's no browser crypto API - // available. Fall back to Alea - // - // XXX looks like at the moment, we use Alea in IE 11 as well, - // which has `window.msCrypto` instead of `window.crypto`. - Random = createAleaGeneratorWithGeneratedSeed(); - } -} - -// Create a non-cryptographically secure PRNG with a given seed (using -// the Alea algorithm) -Random.createWithSeeds = function (...seeds) { - if (seeds.length === 0) { - throw new Error("No seeds were provided"); - } - return new RandomGenerator(RandomGenerator.Type.ALEA, {seeds: seeds}); -}; - -// Used like `Random`, but much faster and not cryptographically -// secure -Random.insecure = createAleaGeneratorWithGeneratedSeed(); - -export { Random }; diff --git a/utils.js b/utils.js new file mode 100644 index 0000000..99a25c6 --- /dev/null +++ b/utils.js @@ -0,0 +1,17 @@ +import { createHash } from 'crypto'; + +export function sha1(contents) { + var hash = createHash('sha1'); + hash.update(contents); + return hash.digest('hex'); +}; + +export function toPairs(obj) { + var pairs = []; + for (var prop in obj) { + if (Object.prototype.hasOwnProperty(prop, obj)) { + pairs[pairs.length] = [prop, obj[prop]]; + } + } + return pairs; +}