diff --git a/package.json b/package.json index 60ace59..66881d1 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "", "main": "index.js", "scripts": { + "build:runtime":"pnpm build --filter \"@voerkai18n/runtime\"", "test": "jest", "test:babelplugin": "jest babel", "test:extract": "jest extract", @@ -26,7 +27,6 @@ "jest": "^27.5.1", "rollup": "^2.69.0", "rollup-plugin-clear": "^2.0.7", - "rollup-plugin-uglify": "^6.0.4", "vinyl": "^2.2.1" } } diff --git a/packages/demo/apps/app/a/a1.js b/packages/demo/apps/app/a/a1.js deleted file mode 100644 index 470d7e4..0000000 --- a/packages/demo/apps/app/a/a1.js +++ /dev/null @@ -1,21 +0,0 @@ - - -t("a1:aaaaa") - -t('no aaaaa') -t("no aaaaa") -t('no aaaaa') - -t('bbbbb',a,b,c) - -t("cccc Arrow Function",()=>{},c) - - -t("eeeeee", ) - - - -t("x:from a") - - -t("中华人民共和国") \ No newline at end of file diff --git a/packages/demo/apps/app/a/a2.js b/packages/demo/apps/app/a/a2.js deleted file mode 100644 index 70e6f24..0000000 --- a/packages/demo/apps/app/a/a2.js +++ /dev/null @@ -1,18 +0,0 @@ - - -t("a2:aaaaa") - -t('no erer') -t("no aaareraa") -t('no fdfd') - -t('fdgfdgfdg',a,b,c) - -t("cccc Arrow Function",()=>{},c) - - -t("eeeeee", ) - - - -t("x::from a") \ No newline at end of file diff --git a/packages/demo/apps/app/auth/changepassword.js b/packages/demo/apps/app/auth/changepassword.js new file mode 100644 index 0000000..6a595bd --- /dev/null +++ b/packages/demo/apps/app/auth/changepassword.js @@ -0,0 +1,15 @@ + + +t("请输入旧密码:") + +t("请再次输入旧密码:") + + +t("请输入新密码:") + +t("请再次输入新密码:") + +t("密码至少需要6位,并且至少包含数字、字符或特殊符号中的两种") + +t("密码强度: {strength}",2) + diff --git a/packages/demo/apps/app/auth/login.html b/packages/demo/apps/app/auth/login.html new file mode 100644 index 0000000..d260fd7 --- /dev/null +++ b/packages/demo/apps/app/auth/login.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/packages/demo/apps/app/auth/login.js b/packages/demo/apps/app/auth/login.js new file mode 100644 index 0000000..b9cf7cd --- /dev/null +++ b/packages/demo/apps/app/auth/login.js @@ -0,0 +1,6 @@ + + +t("用户名或密码错误"); +t('请输入用户名:') +t("请输入密码:"); +t("欢迎您: {}","张三丰") \ No newline at end of file diff --git a/packages/demo/apps/app/b/b1.js b/packages/demo/apps/app/b/b1.js deleted file mode 100644 index 8a693ef..0000000 --- a/packages/demo/apps/app/b/b1.js +++ /dev/null @@ -1,16 +0,0 @@ - - -t("aaaaa") - - -t('bbbbb',a,b,c) - -t("cccc",()=>{},c) - - - -t("ddddd中国",()=>{},c) -t("eeeeee") - -t("ddddd中国",()=>{},c) -t("x::from b") \ No newline at end of file diff --git a/packages/demo/apps/app/c/c1.js b/packages/demo/apps/app/c/c1.js deleted file mode 100644 index 992392a..0000000 --- a/packages/demo/apps/app/c/c1.js +++ /dev/null @@ -1,9 +0,0 @@ - - -t("ccccc") - -t('cccccdc') - - - -t("x::from c1",ddd) \ No newline at end of file diff --git a/packages/demo/apps/app/c/c2.js b/packages/demo/apps/app/c/c2.js deleted file mode 100644 index 94498c8..0000000 --- a/packages/demo/apps/app/c/c2.js +++ /dev/null @@ -1,20 +0,0 @@ - - -t("a2:aaaaa") - -t('no erer') -t("no aaareraa") -t('no fdfd') - -t('fdgfdgfdg',a,b,c) - -t("cccc Arrow Function",()=>{},c) - - - -t("ddddd中国",c) -t("eeeeee", ) - - - -t("x::from c2") \ No newline at end of file diff --git a/packages/demo/apps/app/c/h1.html b/packages/demo/apps/app/c/h1.html deleted file mode 100644 index 5d88750..0000000 --- a/packages/demo/apps/app/c/h1.html +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/packages/demo/apps/app/db/index.js b/packages/demo/apps/app/db/index.js new file mode 100644 index 0000000..e3913f5 --- /dev/null +++ b/packages/demo/apps/app/db/index.js @@ -0,0 +1,7 @@ +t('数据库类型:{}、{}、{}',"sqlite","mysql","mssql"); + +t("数据库密码:{pwd}","123456"); +t("数据库地址:{url}",""); + +t("编码:{encode}","utf-8"); + diff --git a/packages/demo/apps/app/db/models.js b/packages/demo/apps/app/db/models.js new file mode 100644 index 0000000..545d68f --- /dev/null +++ b/packages/demo/apps/app/db/models.js @@ -0,0 +1,20 @@ +import {Table, Column} from "typeorm"; + +@Table() +export class Photo { + + @Column(t("编码")) + id: number; + + @Column(t("名称")) + name: string; + + @Column(t("描述")) + description: string; + + @Column(t("文件名称")) + fileName: string; + + @Column("视图") + views: number; +} \ No newline at end of file diff --git a/packages/demo/apps/app/index.js b/packages/demo/apps/app/index.js index 7627cca..e3ab573 100644 --- a/packages/demo/apps/app/index.js +++ b/packages/demo/apps/app/index.js @@ -1,21 +1,26 @@ -const { t,languages,scope } = reuire("./languages") +import { t,languages,scope } from "./languages/index.js" + +VoerkaI18n.on((language)=>{ + console.log("切换到语言:",language) +}) - - -function output(){ - t("aaaaa") - - t('aaaaa1') - t("aaaaa2") - t('aaaaa 3') - - t('bbbbb',a,b,c) - - t("cccc",()=>{},c) - - - - t("ddddd中国",()=>{},c) - t("eeeeee", ) +async function output(){ + console.log(t("用户名或密码错误")) + console.log(t('请输入用户名:')) + console.log(t("请输入密码:")) + console.log(t("欢迎您: {}","张三丰")) + console.log("----------------") + await VoerkaI18n.change("en") + console.log(t("用户名或密码错误")) + console.log(t('请输入用户名:')) + console.log(t("请输入密码:")) + console.log(t("欢迎您: {}","tom")) + console.log("----------------") + await VoerkaI18n.change("cn") + console.log(t("用户名或密码错误")) + console.log(t('请输入用户名:')) + console.log(t("请输入密码:")) + console.log(t("欢迎您: {}","tom")) } +output().then(()=>{}) \ No newline at end of file diff --git a/packages/demo/apps/app/messages/index.js b/packages/demo/apps/app/messages/index.js new file mode 100644 index 0000000..e5915c4 --- /dev/null +++ b/packages/demo/apps/app/messages/index.js @@ -0,0 +1,5 @@ + + + t("您有{}条未读消息",100) + t("消息总数:{$count}",100) + t("消息类型:{type}",1) \ No newline at end of file diff --git a/packages/demo/apps/app/package.json b/packages/demo/apps/app/package.json new file mode 100644 index 0000000..504c663 --- /dev/null +++ b/packages/demo/apps/app/package.json @@ -0,0 +1,15 @@ +{ + "name": "app", + "version": "1.0.0", + "description": "", + "main": "index.js", + "type": "module", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "@voerkai18n/tools": "workspace:^1.0.0" + } +} diff --git a/packages/runtime/formatters.js b/packages/runtime/formatters.js index 84fd762..ef249c0 100644 --- a/packages/runtime/formatters.js +++ b/packages/runtime/formatters.js @@ -27,12 +27,14 @@ * @returns */ function dict(value,...args){ - for(let i=0;i0 && (args.length % 2!==0)) return args[args.length-1] + if(args.length >0 && (args.length % 2!==0)) return args[args.length-1] + }catch{} return value } diff --git a/packages/runtime/index.cjs b/packages/runtime/index.cjs new file mode 100644 index 0000000..97f30ec --- /dev/null +++ b/packages/runtime/index.cjs @@ -0,0 +1,883 @@ +'use strict'; + +var isMergeableObject = function isMergeableObject(value) { + return isNonNullObject(value) + && !isSpecial(value) +}; + +function isNonNullObject(value) { + return !!value && typeof value === 'object' +} + +function isSpecial(value) { + var stringValue = Object.prototype.toString.call(value); + + return stringValue === '[object RegExp]' + || stringValue === '[object Date]' + || isReactElement(value) +} + +// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25 +var canUseSymbol = typeof Symbol === 'function' && Symbol.for; +var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7; + +function isReactElement(value) { + return value.$$typeof === REACT_ELEMENT_TYPE +} + +function emptyTarget(val) { + return Array.isArray(val) ? [] : {} +} + +function cloneUnlessOtherwiseSpecified(value, options) { + return (options.clone !== false && options.isMergeableObject(value)) + ? deepmerge(emptyTarget(value), value, options) + : value +} + +function defaultArrayMerge(target, source, options) { + return target.concat(source).map(function(element) { + return cloneUnlessOtherwiseSpecified(element, options) + }) +} + +function getMergeFunction(key, options) { + if (!options.customMerge) { + return deepmerge + } + var customMerge = options.customMerge(key); + return typeof customMerge === 'function' ? customMerge : deepmerge +} + +function getEnumerableOwnPropertySymbols(target) { + return Object.getOwnPropertySymbols + ? Object.getOwnPropertySymbols(target).filter(function(symbol) { + return target.propertyIsEnumerable(symbol) + }) + : [] +} + +function getKeys(target) { + return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target)) +} + +function propertyIsOnObject(object, property) { + try { + return property in object + } catch(_) { + return false + } +} + +// Protects from prototype poisoning and unexpected merging up the prototype chain. +function propertyIsUnsafe(target, key) { + return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet, + && !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain, + && Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable. +} + +function mergeObject(target, source, options) { + var destination = {}; + if (options.isMergeableObject(target)) { + getKeys(target).forEach(function(key) { + destination[key] = cloneUnlessOtherwiseSpecified(target[key], options); + }); + } + getKeys(source).forEach(function(key) { + if (propertyIsUnsafe(target, key)) { + return + } + + if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) { + destination[key] = getMergeFunction(key, options)(target[key], source[key], options); + } else { + destination[key] = cloneUnlessOtherwiseSpecified(source[key], options); + } + }); + return destination +} + +function deepmerge(target, source, options) { + options = options || {}; + options.arrayMerge = options.arrayMerge || defaultArrayMerge; + options.isMergeableObject = options.isMergeableObject || isMergeableObject; + // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge() + // implementations can use it. The caller may not replace it. + options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified; + + var sourceIsArray = Array.isArray(source); + var targetIsArray = Array.isArray(target); + var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray; + + if (!sourceAndTargetTypesMatch) { + return cloneUnlessOtherwiseSpecified(source, options) + } else if (sourceIsArray) { + return options.arrayMerge(target, source, options) + } else { + return mergeObject(target, source, options) + } +} + +deepmerge.all = function deepmergeAll(array, options) { + if (!Array.isArray(array)) { + throw new Error('first argument should be an array') + } + + return array.reduce(function(prev, next) { + return deepmerge(prev, next, options) + }, {}) +}; + +var deepmerge_1 = deepmerge; + +var cjs = deepmerge_1; + +/** + * 内置的格式化器 + * + */ + +/** + * 字典格式化器 + * 根据输入data的值,返回后续参数匹配的结果 + * dict(data,,,,,,,...) + * + * + * dict(1,1,"one",2,"two",3,"three",4,"four") == "one" + * dict(2,1,"one",2,"two",3,"three",4,"four") == "two" + * dict(3,1,"one",2,"two",3,"three",4,"four") == "three" + * dict(4,1,"one",2,"two",3,"three",4,"four") == "four" + * // 无匹配时返回原始值 + * dict(5,1,"one",2,"two",3,"three",4,"four") == 5 + * // 无匹配时并且后续参数个数是奇数,则返回最后一个参数 + * dict(5,1,"one",2,"two",3,"three",4,"four","more") == "more" + * + * 在翻译中使用 + * I have { value | dict(1,"one",2,"two",3,"three",4,"four")} apples + * + * @param {*} value + * @param {...any} args + * @returns + */ +function dict(value,...args){ + try{ + for(let i=0;i0 && (args.length % 2!==0)) return args[args.length-1] + }catch{} + return value +} + + +var formatters$1 = { + "*":{ + $types:{ + Date:(value)=>value.toLocaleString() + }, + time:(value)=> value.toLocaleTimeString(), + date: (value)=> value.toLocaleDateString(), + dict, //字典格式化器 + }, + cn:{ + $types:{ + Date:(value)=> `${value.getFullYear()}年${value.getMonth()+1}月${value.getDate()}日 ${value.getHours()}点${value.getMinutes()}分${value.getSeconds()}秒` + }, + time:(value)=>`${value.getHours()}点${value.getMinutes()}分${value.getSeconds()}秒`, + date: (value)=> `${value.getFullYear()}年${value.getMonth()+1}月${value.getDate()}日`, + currency:(value)=>`${value}元`, + }, + en:{ + currency:(value)=>`$${value}`, + } +}; + +/** + * 获取指定变量类型名称 + * getDataTypeName(1) == Number + * getDataTypeName("") == String + * getDataTypeName(null) == Null + * getDataTypeName(undefined) == Undefined + * getDataTypeName(new Date()) == Date + * getDataTypeName(new Error()) == Error + * + * @param {*} v + * @returns + */ +function getDataTypeName$1(v){ + if (v === null) return 'Null' + if (v === undefined) return 'Undefined' + if(typeof(v)==="function") return "Function" + return v.constructor && v.constructor.name; +}function isPlainObject$1(obj){ + if (typeof obj !== 'object' || obj === null) return false; + var proto = Object.getPrototypeOf(obj); + if (proto === null) return true; + var baseProto = proto; + + while (Object.getPrototypeOf(baseProto) !== null) { + baseProto = Object.getPrototypeOf(baseProto); + } + return proto === baseProto; +} +function isNumber$1(value){ + return !isNaN(parseInt(value)) +} + +var utils = { + getDataTypeName: getDataTypeName$1, + isNumber: isNumber$1, + isPlainObject: isPlainObject$1 +}; + +const deepMerge = cjs; +const formatters = formatters$1; +const {isPlainObject ,isNumber , getDataTypeName} = utils; + +// 用来提取字符里面的插值变量参数 , 支持管道符 { var | formatter | formatter } +// 不支持参数: let varWithPipeRegexp = /\{\s*(?\w+)?(?(\s*\|\s*\w*\s*)*)\s*\}/g + +// 支持参数: { var | formatter(x,x,..) | formatter } +let varWithPipeRegexp = /\{\s*(?\w+)?(?(\s*\|\s*\w*(\(.*\)){0,1}\s*)*)\s*\}/g; + +// 有效的语言名称列表 +const languages = ["af","am","ar-dz","ar-iq","ar-kw","ar-ly","ar-ma","ar-sa","ar-tn","ar","az","be","bg","bi","bm","bn","bo","br","bs","ca","cs","cv","cy","da","de-at","de-ch","de","dv","el","en-au","en-ca","en-gb","en-ie","en-il","en-in","en-nz","en-sg","en-tt","en","eo","es-do","es-mx","es-pr","es-us","es","et","eu","fa","fi","fo","fr-ca","fr-ch","fr","fy","ga","gd","gl","gom-latn","gu","he","hi","hr","ht","hu","hy-am","id","is","it-ch","it","ja","jv","ka","kk","km","kn","ko","ku","ky","lb","lo","lt","lv","me","mi","mk","ml","mn","mr","ms-my","ms","mt","my","nb","ne","nl-be","nl","nn","oc-lnc","pa-in","pl","pt-br","pt","ro","ru","rw","sd","se","si","sk","sl","sq","sr-cyrl","sr","ss","sv-fi","sv","sw","ta","te","tet","tg","th","tk","tl-ph","tlh","tr","tzl","tzm-latn","tzm","ug-cn","uk","ur","uz-latn","uz","vi","x-pseudo","yo","zh-cn","zh-hk","zh-tw","zh"]; + +/** + * 考虑到通过正则表达式进行插件的替换可能较慢,因此提供一个简单方法来过滤掉那些 + * 不需要进行插值处理的字符串 + * 原理很简单,就是判断一下是否同时具有{和}字符,如果有则认为可能有插值变量,如果没有则一定没有插件变量,则就不需要进行正则匹配 + * 从而可以减少不要的正则匹配 + * 注意:该方法只能快速判断一个字符串不包括插值变量 + * @param {*} str + * @returns {boolean} true=可能包含插值变量, + */ +function hasInterpolation(str){ + return str.includes("{") && str.includes("}") +} + + +/** + 通过正则表达式对原始文本内容进行解析匹配后得到的 + formatters="| aaa(1,1) | bbb " + + 需要统一解析为 + + [ + [aaa,[1,1]], // [formatter'name,[args,...]] + [bbb,[]], + ] + + formatters="| aaa(1,1,"dddd") | bbb " + + 目前对参数采用简单的split(",")来解析,因为无法正确解析aaa(1,1,"dd,,dd")形式的参数 + 在此场景下基本够用了,如果需要支持更复杂的参数解析,可以后续考虑使用正则表达式来解析 + + @returns [[,[,,...]]] + */ +function parseFormatters(formatters){ + if(!formatters) return [] + // 1. 先解析为 ["aaa()","bbb"]形式 + let result = formatters.trim().substr(1).trim().split("|").map(r=>r.trim()); + + // 2. 解析格式化器参数 + return result.map(formatter=>{ + let firstIndex = formatter.indexOf("("); + let lastIndex = formatter.lastIndexOf(")"); + if(firstIndex!==-1 && lastIndex!==-1){ // 带参数的格式化器 + const argsContent = formatter.substr(firstIndex+1,lastIndex-firstIndex-1).trim(); + let args = argsContent=="" ? [] : argsContent.split(",").map(arg=>{ + arg = arg.trim(); + if(!isNaN(parseInt(arg))){ + return parseInt(arg) // 数字 + }else if((arg.startsWith('\"') && arg.endsWith('\"')) || (arg.startsWith('\'') && arg.endsWith('\'')) ){ + return arg.substr(1,arg.length-2) // 字符串 + }else if(arg.toLowerCase()==="true" || arg.toLowerCase()==="false"){ + return arg.toLowerCase()==="true" // 布尔值 + }else if((arg.startsWith('{') && arg.endsWith('}')) || (arg.startsWith('[') && arg.endsWith(']'))){ + try{ + return JSON.parse(arg) + }catch(e){ + return String(arg) + } + }else { + return String(arg) + } + }); + return [formatter.substr(0,firstIndex),args] + }else {// 不带参数的格式化器 + return [formatter,[]] + } + }) +} + +/** + * 提取字符串中的插值变量 + * // [ + // { + name:<变量名称>,formatters:[{name:<格式化器名称>,args:[<参数>,<参数>,....]]}],<匹配字符串>], + // .... + // + * @param {*} str + * @param {*} isFull =true 保留所有插值变量 =false 进行去重 + * @returns {Array} + * [ + * { + * name:"<变量名称>", + * formatters:[ + * {name:"<格式化器名称>",args:[<参数>,<参数>,....]}, + * {name:"<格式化器名称>",args:[<参数>,<参数>,....]}, + * ], + * match:"<匹配字符串>" + * }, + * ... + * ] + */ +function getInterpolatedVars(str){ + let vars = []; + forEachInterpolatedVars(str,(varName,formatters,match)=>{ + let varItem = { + name:varName, + formatters:formatters.map(([formatter,args])=>{ + return { + name:formatter, + args:args + } + }), + match:match + }; + if(vars.findIndex(varDef=>((varDef.name===varItem.name) && (varItem.formatters.toString() == varDef.formatters.toString())))===-1){ + vars.push(varItem); + } + return "" + }); + return vars +} +/** + * 遍历str中的所有插值变量传递给callback,将callback返回的结果替换到str中对应的位置 + * @param {*} str + * @param {Function(<变量名称>,[formatters],match[0])} callback + * @returns 返回替换后的字符串 + */ +function forEachInterpolatedVars(str,callback,options={}){ + let result=str, match; + let opts = Object.assign({ + replaceAll:true, // 是否替换所有插值变量,当使用命名插值时应置为true,当使用位置插值时应置为false + },options); + varWithPipeRegexp.lastIndex=0; + while ((match = varWithPipeRegexp.exec(result)) !== null) { + const varname = match.groups.varname || ""; + // 解析格式化器和参数 = [,[,[,,...]]] + const formatters = parseFormatters(match.groups.formatters); + if(typeof(callback)==="function"){ + try{ + if(opts.replaceAll){ + result=result.replaceAll(match[0],callback(varname,formatters,match[0])); + }else { + result=result.replace(match[0],callback(varname,formatters,match[0])); + } + }catch{// callback函数可能会抛出异常,如果抛出异常,则中断匹配过程 + break + } + } + varWithPipeRegexp.lastIndex=0; + } + return result +} + + +// 缓存数据类型的格式化器,避免每次都调用getDataTypeDefaultFormatter +let datatypeFormattersCache ={ + $activeLanguage:null, +}; +/** + * 取得指定数据类型的默认格式化器 + * + * 可以为每一个数据类型指定一个格式化器,当传入插值变量时,会自动调用该格式化器来对值进行格式化转换 + + const formatters = { + "*":{ + $types:{...} // 在所有语言下只作用于特定数据类型的格式化器 + }, // 在所有语言下生效的格式化器 + cn:{ + $types:{ + [数据类型]:(value)=>{...}, + }, + [格式化器名称]:(value)=>{...}, + [格式化器名称]:(value)=>{...}, + [格式化器名称]:(value)=>{...}, + }, + } + * @param {*} scope + * @param {*} activeLanguage + * @param {*} dataType 数字类型 + * @returns {Function} 格式化函数 + */ +function getDataTypeDefaultFormatter(scope,activeLanguage,dataType){ + if(datatypeFormattersCache.$activeLanguage === activeLanguage) { + if(dataType in datatypeFormattersCache) return datatypeFormattersCache[dataType] + }else {// 清空缓存 + datatypeFormattersCache = { $activeLanguage:activeLanguage }; + } + + // 先在当前作用域中查找,再在全局查找 + const targets = [scope.formatters,scope.global.formatters]; + for(const target of targets){ + if(activeLanguage in target){ + // 在当前语言的$types中查找 + let formatters = target[activeLanguage].$types || {}; + for(let [name,formatter] of Object.entries(formatters)){ + if(name === dataType && typeof(formatter)==="function") { + datatypeFormattersCache[dataType] = formatter; + return formatter + } + } + } + // 在所有语言的$types中查找 + let formatters = target["*"].$types || {}; + for(let [name,formatter] of Object.entries(formatters)){ + if(name === dataType && typeof(formatter)==="function") { + datatypeFormattersCache[dataType] = formatter; + return formatter + } + } + } +} + +/** + * 获取指定名称的格式化器函数 + * @param {*} scope + * @param {*} activeLanguage + * @param {*} name 格式化器名称 + * @returns {Function} 格式化函数 + */ +let formattersCache = { $activeLanguage:null}; +function getFormatter(scope,activeLanguage,name){ + if(formattersCache.$activeLanguage === activeLanguage) { + if(name in formattersCache) return formattersCache[name] + }else { // 当切换语言时需要清空缓存 + formattersCache = { $activeLanguage:activeLanguage }; + } + // 先在当前作用域中查找,再在全局查找 + const targets = [scope.formatters,scope.global.formatters]; + for(const target of targets){ + // 优先在当前语言查找 + if(activeLanguage in target){ + let formatters = target[activeLanguage] || {}; + if((name in formatters) && typeof(formatters[name])==="function") return formattersCache[name] = formatters[name] + } + // 在所有语言的$types中查找 + let formatters = target["*"] || {}; + if((name in formatters) && typeof(formatters[name])==="function") return formattersCache[name] = formatters[name] + } +} + +/** + * 执行格式化器并返回结果 + * @param {*} value + * @param {*} formatters + */ +function executeFormatter(value,formatters){ + if(formatters.length===0) return value + let result = value; + try{ + for(let formatter of formatters){ + if(typeof(formatter) === "function") { + result = formatter(result); + }else { + return result + } + } + }catch(e){ + console.error(`Error while execute i18n formatter for ${value}: ${e.message} ` ); + } + return result +} +/** + * 将 [[格式化器名称,[参数,参数,...]],[格式化器名称,[参数,参数,...]]]格式化器转化为 + * + * + * + * @param {*} scope + * @param {*} activeLanguage + * @param {*} formatters + */ +function buildFormatters(scope,activeLanguage,formatters){ + let results = []; + for(let formatter of formatters){ + if(formatter[0]){ + const func = getFormatter(scope,activeLanguage,formatter[0]); + if(typeof(func)==="function"){ + results.push((v)=>{ + return func(v,...formatter[1]) + }); + }else {// 格式化器无效或者没有定义时,查看当前值是否具有同名的方法,如果有则执行调用 + results.push((v)=>{ + if(typeof(v[formatter[0]])==="function"){ + return v[formatter[0]].call(v,...formatter[1]) + }else { + return v + } + }); + } + } + } + return results +} + +/** + * 将value经过格式化器处理后返回 + * @param {*} scope + * @param {*} activeLanguage + * @param {*} formatters + * @param {*} value + * @returns + */ +function getFormattedValue(scope,activeLanguage,formatters,value){ + // 1. 取得格式化器函数列表 + const formatterFuncs = buildFormatters(scope,activeLanguage,formatters); + // 3. 查找每种数据类型默认格式化器,并添加到formatters最前面,默认数据类型格式化器优先级最高 + const defaultFormatter = getDataTypeDefaultFormatter(scope,activeLanguage,getDataTypeName(value)); + if(defaultFormatter){ + formatterFuncs.splice(0,0,defaultFormatter); + } + // 3. 执行格式化器 + value = executeFormatter(value,formatterFuncs); + return value +} + +/** + * 字符串可以进行变量插值替换, + * replaceInterpolatedVars("<模板字符串>",{变量名称:变量值,变量名称:变量值,...}) + * replaceInterpolatedVars("<模板字符串>",[变量值,变量值,...]) + * replaceInterpolatedVars("<模板字符串>",变量值,变量值,...]) + * +- 当只有两个参数并且第2个参数是{}时,将第2个参数视为命名变量的字典 + replaceInterpolatedVars("this is {a}+{b},{a:1,b:2}) --> this is 1+2 +- 当只有两个参数并且第2个参数是[]时,将第2个参数视为位置参数 + replaceInterpolatedVars"this is {}+{}",[1,2]) --> this is 1+2 +- 普通位置参数替换 + replaceInterpolatedVars("this is {a}+{b}",1,2) --> this is 1+2 +- +this == scope == { formatters: {}, ... } +* @param {*} template +* @returns +*/ +function replaceInterpolatedVars(template,...args) { + const scope = this; + // 当前激活语言 + const activeLanguage = scope.global.activeLanguage; + + // 没有变量插值则的返回原字符串 + if(args.length===0 || !hasInterpolation(template)) return template + + // ****************************变量插值**************************** + if(args.length===1 && isPlainObject(args[0])){ + // 读取模板字符串中的插值变量列表 + // [[var1,[formatter,formatter,...],match],[var2,[formatter,formatter,...],match],...} + let varValues = args[0]; + return forEachInterpolatedVars(template,(varname,formatters)=>{ + let value = (varname in varValues) ? varValues[varname] : ''; + return getFormattedValue(scope,activeLanguage,formatters,value) + }) + }else { + // ****************************位置插值**************************** + // 如果只有一个Array参数,则认为是位置变量列表,进行展开 + const params=(args.length===1 && Array.isArray(args[0])) ? [...args[0]] : args; + if(params.length===0) return template // 没有变量则不需要进行插值处理,返回原字符串 + let i = 0; + return forEachInterpolatedVars(template,(varname,formatters)=>{ + if(params.length>i){ + return getFormattedValue(scope,activeLanguage,formatters,params[i++]) + }else { + throw new Error() // 抛出异常,停止插值处理 + } + },{replaceAll:false}) + + } +} + +// 默认语言配置 +const defaultLanguageSettings = { + defaultLanguage: "cn", + activeLanguage: "cn", + languages:{ + cn:{name:"cn",title:"中文",default:true}, + en:{name:"en",title:"英文"}, + }, + formatters +}; + +function isMessageId(content){ + return parseInt(content)>0 +} +/** + * 根据值的单数和复数形式,从messages中取得相应的消息 + * + * @param {*} messages 复数形式的文本内容 = [<=0时的内容>,<=1时的内容>,<=2时的内容>,...] + * @param {*} value + */ +function getPluraMessage(messages,value){ + try{ + if(Array.isArray(messages)){ + return messages.length > value ? messages[value] : messages[messages.length-1] + }else { + return messages + } + }catch{ + return Array.isArray(messages) ? messages[0] : messages + } +} + +/** + * 翻译函数 + * +* translate("要翻译的文本内容") 如果默认语言是中文,则不会进行翻译直接返回 +* translate("I am {} {}","man") == I am man 位置插值 +* translate("I am {p}",{p:"man"}) 字典插值 +* translate("total {$count} items", {$count:1}) //复数形式 +* translate("total {} {} {} items",a,b,c) // 位置变量插值 + * + * this===scope 当前绑定的scope + * + */ +function translate(message) { + const scope = this; + const activeLanguage = scope.global.activeLanguage; + let content = message; + let vars=[]; // 插值变量列表 + let pluralVars= []; // 复数变量 + let pluraValue = null; // 复数值 + try{ + // 1. 预处理变量: 复数变量保存至pluralVars中 , 变量如果是Function则调用 + if(arguments.length === 2 && isPlainObject(arguments[1])){ + Object.entries(arguments[1]).forEach(([name,value])=>{ + if(typeof(value)==="function"){ + try{ + vars[name] = value(); + }catch(e){ + vars[name] = value; + } + } + // 以$开头的视为复数变量 + if(name.startsWith("$")) pluralVars.push(name); + }); + vars = [arguments[1]]; + }else if(arguments.length >= 2){ + vars = [...arguments].splice(1).map((arg,index)=>{ + try{ + arg = typeof(arg)==="function" ? arg() : arg; + // 位置参数中以第一个数值变量为复数变量 + if(isNumber(arg)) pluraValue = parseInt(arg); + }catch(e){ } + return arg + }); + + } + + // 2. 取得翻译文本模板字符串 + if(activeLanguage === scope.defaultLanguage){ + // 2.1 从默认语言中取得翻译文本模板字符串 + // 如果当前语言就是默认语言,不需要查询加载,只需要做插值变换即可 + // 当源文件运用了babel插件后会将原始文本内容转换为msgId + // 如果是msgId则从scope.default中读取,scope.default=默认语言包={:} + if(isMessageId(content)){ + content = scope.default[content] || message; + } + }else { + // 2.2 从当前语言包中取得翻译文本模板字符串 + // 如果没有启用babel插件将源文本转换为msgId,需要先将文本内容转换为msgId + let msgId = isMessageId(content) ? content : scope.idMap[content]; + content = scope.messages[msgId] || content; + } + + // 3. 处理复数 + // 经过上面的处理,content可能是字符串或者数组 + // content = "原始文本内容" || 复数形式["原始文本内容","原始文本内容"....] + // 如果是数组说明要启用复数机制,需要根据插值变量中的某个变量来判断复数形式 + if(Array.isArray(content) && content.length>0){ + // 如果存在复数命名变量,只取第一个复数变量 + if(pluraValue!==null){ // 启用的是位置插值,pluraIndex=第一个数字变量的位置 + content = getPluraMessage(content,pluraValue); + }else if(pluralVar.length>0){ + content = getPluraMessage(content,parseInt(vars(pluralVar[0]))); + }else { // 如果找不到复数变量,则使用第一个内容 + content = content[0]; + } + } + // 进行插值处理 + if(vars.length==0){ + return content + }else { + return replaceInterpolatedVars.call(scope,content,...vars) + } + }catch(e){ + return content // 出错则返回原始文本 + } +} + +/** + * 多语言管理类 + * + * 当导入编译后的多语言文件时(import("./languages")),会自动生成全局实例VoerkaI18n + * + * VoerkaI18n.languages // 返回支持的语言列表 + * VoerkaI18n.defaultLanguage // 默认语言 + * VoerkaI18n.language // 当前语言 + * VoerkaI18n.change(language) // 切换到新的语言 + * + * + * VoerkaI18n.on("change",(language)=>{}) // 注册语言切换事件 + * VoerkaI18n.off("change",(language)=>{}) + * + * */ + class I18nManager{ + static instance = null; // 单例引用 + callbacks = [] // 当切换语言时的回调事件 + constructor(settings={}){ + if(I18nManager.instance!=null){ + return I18nManager.instance; + } + I18nManager.instance = this; + this._settings = deepMerge(defaultLanguageSettings,settings); + this._scopes=[]; + return I18nManager.instance; + } + get settings(){ return this._settings } + get scopes(){ return this._scopes } + // 当前激活语言 + get activeLanguage(){ return this._settings.activeLanguage} + // 默认语言 + get defaultLanguage(){ return this.this._settings.defaultLanguage} + // 支持的语言列表 + get languages(){ return this._settings.languages} + // 订阅语言切换事件 + on(callback){ + this.callbacks.push(callback); + } + off(callback){ + for(let i=0;iawait cb(newLanguage))); + }catch(e){ + console.warn("Error while executing language change events",e.message); + } + } + /** + * 切换语言 + */ + async change(value){ + if(value in this.languages){ + await this._triggerChangeEvents(value); + this._settings.activeLanguage = value; + }else { + throw new Error("Not supported language:"+value) + } + } + /** + * 获取指定作用域的下的语言包加载器 + * + * 同时会进行语言兼容性处理 + * + * 如scope里面定义了一个cn的语言包,当切换到zh-cn时,会自动加载cn语言包 + * + * + * @param {*} scope + * @param {*} lang + */ + _getScopeLoader(scope,lang){ + + } + /** + * 当切换语言时调用此方法来加载更新语言包 + * @param {*} newLanguage + */ + async _updateScopes(newLanguage){ + // 并发执行所有作用域语言包的加载 + try{ + await (Promise.allSettled || Promise.all)(this._scopes.map(scope=>{ + return async ()=>{ + // 默认语言,所有均默认语言均采用静态加载方式,只需要简单的替换即可 + if(newLanguage === scope.defaultLanguage){ + scope.messages = scope.default; + return + } + // 异步加载语言文件 + const loader = scope.loaders[newLanguage]; + if(typeof(loader) === "function"){ + try{ + scope.messages = await loader(); + }catch(e){ + console.warn(`Error loading language ${newLanguage} : ${e.message}`); + scope.messages = defaultMessages; // 出错时回退到默认语言 + } + }else { + scope.messages = defaultMessages; + } + } + })); + }catch(e){ + console.warn("Error while refreshing scope:",e.message); + } + } + /** + * + * 注册一个新的作用域 + * + * 每一个库均对应一个作用域,每个作用域可以有多个语言包,且对应一个翻译函数 + * scope={ + * defaultLanguage:"cn", + default: defaultMessages, // 转换文本信息 + messages : defaultMessages, // 当前语言的消息 + idMap:messageIds, + formatters:{ + ...formatters, + ...i18nSettings.formatters || {} + }, + loaders:{}, // 异步加载语言文件的函数列表 + settings:{} // 引用全局VoerkaI18n实例的配置 + * } + * + * 除了默认语言外,其他语言采用动态加载的方式 + * + * @param {*} scope + */ + register(scope){ + scope.global = this._settings; + this._scopes.push(scope); + } + /** + * 注册全局格式化器 + * @param {*} formatters + */ + registerFormatters(formatters){ + + } +} + +var runtime ={ + getInterpolatedVars, + replaceInterpolatedVars, + I18nManager, + translate, + languages, + defaultLanguageSettings +}; + +module.exports = runtime; diff --git a/packages/runtime/index.esm.js b/packages/runtime/index.esm.js new file mode 100644 index 0000000..c22bc2b --- /dev/null +++ b/packages/runtime/index.esm.js @@ -0,0 +1,881 @@ +var isMergeableObject = function isMergeableObject(value) { + return isNonNullObject(value) + && !isSpecial(value) +}; + +function isNonNullObject(value) { + return !!value && typeof value === 'object' +} + +function isSpecial(value) { + var stringValue = Object.prototype.toString.call(value); + + return stringValue === '[object RegExp]' + || stringValue === '[object Date]' + || isReactElement(value) +} + +// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25 +var canUseSymbol = typeof Symbol === 'function' && Symbol.for; +var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7; + +function isReactElement(value) { + return value.$$typeof === REACT_ELEMENT_TYPE +} + +function emptyTarget(val) { + return Array.isArray(val) ? [] : {} +} + +function cloneUnlessOtherwiseSpecified(value, options) { + return (options.clone !== false && options.isMergeableObject(value)) + ? deepmerge(emptyTarget(value), value, options) + : value +} + +function defaultArrayMerge(target, source, options) { + return target.concat(source).map(function(element) { + return cloneUnlessOtherwiseSpecified(element, options) + }) +} + +function getMergeFunction(key, options) { + if (!options.customMerge) { + return deepmerge + } + var customMerge = options.customMerge(key); + return typeof customMerge === 'function' ? customMerge : deepmerge +} + +function getEnumerableOwnPropertySymbols(target) { + return Object.getOwnPropertySymbols + ? Object.getOwnPropertySymbols(target).filter(function(symbol) { + return target.propertyIsEnumerable(symbol) + }) + : [] +} + +function getKeys(target) { + return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target)) +} + +function propertyIsOnObject(object, property) { + try { + return property in object + } catch(_) { + return false + } +} + +// Protects from prototype poisoning and unexpected merging up the prototype chain. +function propertyIsUnsafe(target, key) { + return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet, + && !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain, + && Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable. +} + +function mergeObject(target, source, options) { + var destination = {}; + if (options.isMergeableObject(target)) { + getKeys(target).forEach(function(key) { + destination[key] = cloneUnlessOtherwiseSpecified(target[key], options); + }); + } + getKeys(source).forEach(function(key) { + if (propertyIsUnsafe(target, key)) { + return + } + + if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) { + destination[key] = getMergeFunction(key, options)(target[key], source[key], options); + } else { + destination[key] = cloneUnlessOtherwiseSpecified(source[key], options); + } + }); + return destination +} + +function deepmerge(target, source, options) { + options = options || {}; + options.arrayMerge = options.arrayMerge || defaultArrayMerge; + options.isMergeableObject = options.isMergeableObject || isMergeableObject; + // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge() + // implementations can use it. The caller may not replace it. + options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified; + + var sourceIsArray = Array.isArray(source); + var targetIsArray = Array.isArray(target); + var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray; + + if (!sourceAndTargetTypesMatch) { + return cloneUnlessOtherwiseSpecified(source, options) + } else if (sourceIsArray) { + return options.arrayMerge(target, source, options) + } else { + return mergeObject(target, source, options) + } +} + +deepmerge.all = function deepmergeAll(array, options) { + if (!Array.isArray(array)) { + throw new Error('first argument should be an array') + } + + return array.reduce(function(prev, next) { + return deepmerge(prev, next, options) + }, {}) +}; + +var deepmerge_1 = deepmerge; + +var cjs = deepmerge_1; + +/** + * 内置的格式化器 + * + */ + +/** + * 字典格式化器 + * 根据输入data的值,返回后续参数匹配的结果 + * dict(data,,,,,,,...) + * + * + * dict(1,1,"one",2,"two",3,"three",4,"four") == "one" + * dict(2,1,"one",2,"two",3,"three",4,"four") == "two" + * dict(3,1,"one",2,"two",3,"three",4,"four") == "three" + * dict(4,1,"one",2,"two",3,"three",4,"four") == "four" + * // 无匹配时返回原始值 + * dict(5,1,"one",2,"two",3,"three",4,"four") == 5 + * // 无匹配时并且后续参数个数是奇数,则返回最后一个参数 + * dict(5,1,"one",2,"two",3,"three",4,"four","more") == "more" + * + * 在翻译中使用 + * I have { value | dict(1,"one",2,"two",3,"three",4,"four")} apples + * + * @param {*} value + * @param {...any} args + * @returns + */ +function dict(value,...args){ + try{ + for(let i=0;i0 && (args.length % 2!==0)) return args[args.length-1] + }catch{} + return value +} + + +var formatters$1 = { + "*":{ + $types:{ + Date:(value)=>value.toLocaleString() + }, + time:(value)=> value.toLocaleTimeString(), + date: (value)=> value.toLocaleDateString(), + dict, //字典格式化器 + }, + cn:{ + $types:{ + Date:(value)=> `${value.getFullYear()}年${value.getMonth()+1}月${value.getDate()}日 ${value.getHours()}点${value.getMinutes()}分${value.getSeconds()}秒` + }, + time:(value)=>`${value.getHours()}点${value.getMinutes()}分${value.getSeconds()}秒`, + date: (value)=> `${value.getFullYear()}年${value.getMonth()+1}月${value.getDate()}日`, + currency:(value)=>`${value}元`, + }, + en:{ + currency:(value)=>`$${value}`, + } +}; + +/** + * 获取指定变量类型名称 + * getDataTypeName(1) == Number + * getDataTypeName("") == String + * getDataTypeName(null) == Null + * getDataTypeName(undefined) == Undefined + * getDataTypeName(new Date()) == Date + * getDataTypeName(new Error()) == Error + * + * @param {*} v + * @returns + */ +function getDataTypeName$1(v){ + if (v === null) return 'Null' + if (v === undefined) return 'Undefined' + if(typeof(v)==="function") return "Function" + return v.constructor && v.constructor.name; +}function isPlainObject$1(obj){ + if (typeof obj !== 'object' || obj === null) return false; + var proto = Object.getPrototypeOf(obj); + if (proto === null) return true; + var baseProto = proto; + + while (Object.getPrototypeOf(baseProto) !== null) { + baseProto = Object.getPrototypeOf(baseProto); + } + return proto === baseProto; +} +function isNumber$1(value){ + return !isNaN(parseInt(value)) +} + +var utils = { + getDataTypeName: getDataTypeName$1, + isNumber: isNumber$1, + isPlainObject: isPlainObject$1 +}; + +const deepMerge = cjs; +const formatters = formatters$1; +const {isPlainObject ,isNumber , getDataTypeName} = utils; + +// 用来提取字符里面的插值变量参数 , 支持管道符 { var | formatter | formatter } +// 不支持参数: let varWithPipeRegexp = /\{\s*(?\w+)?(?(\s*\|\s*\w*\s*)*)\s*\}/g + +// 支持参数: { var | formatter(x,x,..) | formatter } +let varWithPipeRegexp = /\{\s*(?\w+)?(?(\s*\|\s*\w*(\(.*\)){0,1}\s*)*)\s*\}/g; + +// 有效的语言名称列表 +const languages = ["af","am","ar-dz","ar-iq","ar-kw","ar-ly","ar-ma","ar-sa","ar-tn","ar","az","be","bg","bi","bm","bn","bo","br","bs","ca","cs","cv","cy","da","de-at","de-ch","de","dv","el","en-au","en-ca","en-gb","en-ie","en-il","en-in","en-nz","en-sg","en-tt","en","eo","es-do","es-mx","es-pr","es-us","es","et","eu","fa","fi","fo","fr-ca","fr-ch","fr","fy","ga","gd","gl","gom-latn","gu","he","hi","hr","ht","hu","hy-am","id","is","it-ch","it","ja","jv","ka","kk","km","kn","ko","ku","ky","lb","lo","lt","lv","me","mi","mk","ml","mn","mr","ms-my","ms","mt","my","nb","ne","nl-be","nl","nn","oc-lnc","pa-in","pl","pt-br","pt","ro","ru","rw","sd","se","si","sk","sl","sq","sr-cyrl","sr","ss","sv-fi","sv","sw","ta","te","tet","tg","th","tk","tl-ph","tlh","tr","tzl","tzm-latn","tzm","ug-cn","uk","ur","uz-latn","uz","vi","x-pseudo","yo","zh-cn","zh-hk","zh-tw","zh"]; + +/** + * 考虑到通过正则表达式进行插件的替换可能较慢,因此提供一个简单方法来过滤掉那些 + * 不需要进行插值处理的字符串 + * 原理很简单,就是判断一下是否同时具有{和}字符,如果有则认为可能有插值变量,如果没有则一定没有插件变量,则就不需要进行正则匹配 + * 从而可以减少不要的正则匹配 + * 注意:该方法只能快速判断一个字符串不包括插值变量 + * @param {*} str + * @returns {boolean} true=可能包含插值变量, + */ +function hasInterpolation(str){ + return str.includes("{") && str.includes("}") +} + + +/** + 通过正则表达式对原始文本内容进行解析匹配后得到的 + formatters="| aaa(1,1) | bbb " + + 需要统一解析为 + + [ + [aaa,[1,1]], // [formatter'name,[args,...]] + [bbb,[]], + ] + + formatters="| aaa(1,1,"dddd") | bbb " + + 目前对参数采用简单的split(",")来解析,因为无法正确解析aaa(1,1,"dd,,dd")形式的参数 + 在此场景下基本够用了,如果需要支持更复杂的参数解析,可以后续考虑使用正则表达式来解析 + + @returns [[,[,,...]]] + */ +function parseFormatters(formatters){ + if(!formatters) return [] + // 1. 先解析为 ["aaa()","bbb"]形式 + let result = formatters.trim().substr(1).trim().split("|").map(r=>r.trim()); + + // 2. 解析格式化器参数 + return result.map(formatter=>{ + let firstIndex = formatter.indexOf("("); + let lastIndex = formatter.lastIndexOf(")"); + if(firstIndex!==-1 && lastIndex!==-1){ // 带参数的格式化器 + const argsContent = formatter.substr(firstIndex+1,lastIndex-firstIndex-1).trim(); + let args = argsContent=="" ? [] : argsContent.split(",").map(arg=>{ + arg = arg.trim(); + if(!isNaN(parseInt(arg))){ + return parseInt(arg) // 数字 + }else if((arg.startsWith('\"') && arg.endsWith('\"')) || (arg.startsWith('\'') && arg.endsWith('\'')) ){ + return arg.substr(1,arg.length-2) // 字符串 + }else if(arg.toLowerCase()==="true" || arg.toLowerCase()==="false"){ + return arg.toLowerCase()==="true" // 布尔值 + }else if((arg.startsWith('{') && arg.endsWith('}')) || (arg.startsWith('[') && arg.endsWith(']'))){ + try{ + return JSON.parse(arg) + }catch(e){ + return String(arg) + } + }else { + return String(arg) + } + }); + return [formatter.substr(0,firstIndex),args] + }else {// 不带参数的格式化器 + return [formatter,[]] + } + }) +} + +/** + * 提取字符串中的插值变量 + * // [ + // { + name:<变量名称>,formatters:[{name:<格式化器名称>,args:[<参数>,<参数>,....]]}],<匹配字符串>], + // .... + // + * @param {*} str + * @param {*} isFull =true 保留所有插值变量 =false 进行去重 + * @returns {Array} + * [ + * { + * name:"<变量名称>", + * formatters:[ + * {name:"<格式化器名称>",args:[<参数>,<参数>,....]}, + * {name:"<格式化器名称>",args:[<参数>,<参数>,....]}, + * ], + * match:"<匹配字符串>" + * }, + * ... + * ] + */ +function getInterpolatedVars(str){ + let vars = []; + forEachInterpolatedVars(str,(varName,formatters,match)=>{ + let varItem = { + name:varName, + formatters:formatters.map(([formatter,args])=>{ + return { + name:formatter, + args:args + } + }), + match:match + }; + if(vars.findIndex(varDef=>((varDef.name===varItem.name) && (varItem.formatters.toString() == varDef.formatters.toString())))===-1){ + vars.push(varItem); + } + return "" + }); + return vars +} +/** + * 遍历str中的所有插值变量传递给callback,将callback返回的结果替换到str中对应的位置 + * @param {*} str + * @param {Function(<变量名称>,[formatters],match[0])} callback + * @returns 返回替换后的字符串 + */ +function forEachInterpolatedVars(str,callback,options={}){ + let result=str, match; + let opts = Object.assign({ + replaceAll:true, // 是否替换所有插值变量,当使用命名插值时应置为true,当使用位置插值时应置为false + },options); + varWithPipeRegexp.lastIndex=0; + while ((match = varWithPipeRegexp.exec(result)) !== null) { + const varname = match.groups.varname || ""; + // 解析格式化器和参数 = [,[,[,,...]]] + const formatters = parseFormatters(match.groups.formatters); + if(typeof(callback)==="function"){ + try{ + if(opts.replaceAll){ + result=result.replaceAll(match[0],callback(varname,formatters,match[0])); + }else { + result=result.replace(match[0],callback(varname,formatters,match[0])); + } + }catch{// callback函数可能会抛出异常,如果抛出异常,则中断匹配过程 + break + } + } + varWithPipeRegexp.lastIndex=0; + } + return result +} + + +// 缓存数据类型的格式化器,避免每次都调用getDataTypeDefaultFormatter +let datatypeFormattersCache ={ + $activeLanguage:null, +}; +/** + * 取得指定数据类型的默认格式化器 + * + * 可以为每一个数据类型指定一个格式化器,当传入插值变量时,会自动调用该格式化器来对值进行格式化转换 + + const formatters = { + "*":{ + $types:{...} // 在所有语言下只作用于特定数据类型的格式化器 + }, // 在所有语言下生效的格式化器 + cn:{ + $types:{ + [数据类型]:(value)=>{...}, + }, + [格式化器名称]:(value)=>{...}, + [格式化器名称]:(value)=>{...}, + [格式化器名称]:(value)=>{...}, + }, + } + * @param {*} scope + * @param {*} activeLanguage + * @param {*} dataType 数字类型 + * @returns {Function} 格式化函数 + */ +function getDataTypeDefaultFormatter(scope,activeLanguage,dataType){ + if(datatypeFormattersCache.$activeLanguage === activeLanguage) { + if(dataType in datatypeFormattersCache) return datatypeFormattersCache[dataType] + }else {// 清空缓存 + datatypeFormattersCache = { $activeLanguage:activeLanguage }; + } + + // 先在当前作用域中查找,再在全局查找 + const targets = [scope.formatters,scope.global.formatters]; + for(const target of targets){ + if(activeLanguage in target){ + // 在当前语言的$types中查找 + let formatters = target[activeLanguage].$types || {}; + for(let [name,formatter] of Object.entries(formatters)){ + if(name === dataType && typeof(formatter)==="function") { + datatypeFormattersCache[dataType] = formatter; + return formatter + } + } + } + // 在所有语言的$types中查找 + let formatters = target["*"].$types || {}; + for(let [name,formatter] of Object.entries(formatters)){ + if(name === dataType && typeof(formatter)==="function") { + datatypeFormattersCache[dataType] = formatter; + return formatter + } + } + } +} + +/** + * 获取指定名称的格式化器函数 + * @param {*} scope + * @param {*} activeLanguage + * @param {*} name 格式化器名称 + * @returns {Function} 格式化函数 + */ +let formattersCache = { $activeLanguage:null}; +function getFormatter(scope,activeLanguage,name){ + if(formattersCache.$activeLanguage === activeLanguage) { + if(name in formattersCache) return formattersCache[name] + }else { // 当切换语言时需要清空缓存 + formattersCache = { $activeLanguage:activeLanguage }; + } + // 先在当前作用域中查找,再在全局查找 + const targets = [scope.formatters,scope.global.formatters]; + for(const target of targets){ + // 优先在当前语言查找 + if(activeLanguage in target){ + let formatters = target[activeLanguage] || {}; + if((name in formatters) && typeof(formatters[name])==="function") return formattersCache[name] = formatters[name] + } + // 在所有语言的$types中查找 + let formatters = target["*"] || {}; + if((name in formatters) && typeof(formatters[name])==="function") return formattersCache[name] = formatters[name] + } +} + +/** + * 执行格式化器并返回结果 + * @param {*} value + * @param {*} formatters + */ +function executeFormatter(value,formatters){ + if(formatters.length===0) return value + let result = value; + try{ + for(let formatter of formatters){ + if(typeof(formatter) === "function") { + result = formatter(result); + }else { + return result + } + } + }catch(e){ + console.error(`Error while execute i18n formatter for ${value}: ${e.message} ` ); + } + return result +} +/** + * 将 [[格式化器名称,[参数,参数,...]],[格式化器名称,[参数,参数,...]]]格式化器转化为 + * + * + * + * @param {*} scope + * @param {*} activeLanguage + * @param {*} formatters + */ +function buildFormatters(scope,activeLanguage,formatters){ + let results = []; + for(let formatter of formatters){ + if(formatter[0]){ + const func = getFormatter(scope,activeLanguage,formatter[0]); + if(typeof(func)==="function"){ + results.push((v)=>{ + return func(v,...formatter[1]) + }); + }else {// 格式化器无效或者没有定义时,查看当前值是否具有同名的方法,如果有则执行调用 + results.push((v)=>{ + if(typeof(v[formatter[0]])==="function"){ + return v[formatter[0]].call(v,...formatter[1]) + }else { + return v + } + }); + } + } + } + return results +} + +/** + * 将value经过格式化器处理后返回 + * @param {*} scope + * @param {*} activeLanguage + * @param {*} formatters + * @param {*} value + * @returns + */ +function getFormattedValue(scope,activeLanguage,formatters,value){ + // 1. 取得格式化器函数列表 + const formatterFuncs = buildFormatters(scope,activeLanguage,formatters); + // 3. 查找每种数据类型默认格式化器,并添加到formatters最前面,默认数据类型格式化器优先级最高 + const defaultFormatter = getDataTypeDefaultFormatter(scope,activeLanguage,getDataTypeName(value)); + if(defaultFormatter){ + formatterFuncs.splice(0,0,defaultFormatter); + } + // 3. 执行格式化器 + value = executeFormatter(value,formatterFuncs); + return value +} + +/** + * 字符串可以进行变量插值替换, + * replaceInterpolatedVars("<模板字符串>",{变量名称:变量值,变量名称:变量值,...}) + * replaceInterpolatedVars("<模板字符串>",[变量值,变量值,...]) + * replaceInterpolatedVars("<模板字符串>",变量值,变量值,...]) + * +- 当只有两个参数并且第2个参数是{}时,将第2个参数视为命名变量的字典 + replaceInterpolatedVars("this is {a}+{b},{a:1,b:2}) --> this is 1+2 +- 当只有两个参数并且第2个参数是[]时,将第2个参数视为位置参数 + replaceInterpolatedVars"this is {}+{}",[1,2]) --> this is 1+2 +- 普通位置参数替换 + replaceInterpolatedVars("this is {a}+{b}",1,2) --> this is 1+2 +- +this == scope == { formatters: {}, ... } +* @param {*} template +* @returns +*/ +function replaceInterpolatedVars(template,...args) { + const scope = this; + // 当前激活语言 + const activeLanguage = scope.global.activeLanguage; + + // 没有变量插值则的返回原字符串 + if(args.length===0 || !hasInterpolation(template)) return template + + // ****************************变量插值**************************** + if(args.length===1 && isPlainObject(args[0])){ + // 读取模板字符串中的插值变量列表 + // [[var1,[formatter,formatter,...],match],[var2,[formatter,formatter,...],match],...} + let varValues = args[0]; + return forEachInterpolatedVars(template,(varname,formatters)=>{ + let value = (varname in varValues) ? varValues[varname] : ''; + return getFormattedValue(scope,activeLanguage,formatters,value) + }) + }else { + // ****************************位置插值**************************** + // 如果只有一个Array参数,则认为是位置变量列表,进行展开 + const params=(args.length===1 && Array.isArray(args[0])) ? [...args[0]] : args; + if(params.length===0) return template // 没有变量则不需要进行插值处理,返回原字符串 + let i = 0; + return forEachInterpolatedVars(template,(varname,formatters)=>{ + if(params.length>i){ + return getFormattedValue(scope,activeLanguage,formatters,params[i++]) + }else { + throw new Error() // 抛出异常,停止插值处理 + } + },{replaceAll:false}) + + } +} + +// 默认语言配置 +const defaultLanguageSettings = { + defaultLanguage: "cn", + activeLanguage: "cn", + languages:{ + cn:{name:"cn",title:"中文",default:true}, + en:{name:"en",title:"英文"}, + }, + formatters +}; + +function isMessageId(content){ + return parseInt(content)>0 +} +/** + * 根据值的单数和复数形式,从messages中取得相应的消息 + * + * @param {*} messages 复数形式的文本内容 = [<=0时的内容>,<=1时的内容>,<=2时的内容>,...] + * @param {*} value + */ +function getPluraMessage(messages,value){ + try{ + if(Array.isArray(messages)){ + return messages.length > value ? messages[value] : messages[messages.length-1] + }else { + return messages + } + }catch{ + return Array.isArray(messages) ? messages[0] : messages + } +} + +/** + * 翻译函数 + * +* translate("要翻译的文本内容") 如果默认语言是中文,则不会进行翻译直接返回 +* translate("I am {} {}","man") == I am man 位置插值 +* translate("I am {p}",{p:"man"}) 字典插值 +* translate("total {$count} items", {$count:1}) //复数形式 +* translate("total {} {} {} items",a,b,c) // 位置变量插值 + * + * this===scope 当前绑定的scope + * + */ +function translate(message) { + const scope = this; + const activeLanguage = scope.global.activeLanguage; + let content = message; + let vars=[]; // 插值变量列表 + let pluralVars= []; // 复数变量 + let pluraValue = null; // 复数值 + try{ + // 1. 预处理变量: 复数变量保存至pluralVars中 , 变量如果是Function则调用 + if(arguments.length === 2 && isPlainObject(arguments[1])){ + Object.entries(arguments[1]).forEach(([name,value])=>{ + if(typeof(value)==="function"){ + try{ + vars[name] = value(); + }catch(e){ + vars[name] = value; + } + } + // 以$开头的视为复数变量 + if(name.startsWith("$")) pluralVars.push(name); + }); + vars = [arguments[1]]; + }else if(arguments.length >= 2){ + vars = [...arguments].splice(1).map((arg,index)=>{ + try{ + arg = typeof(arg)==="function" ? arg() : arg; + // 位置参数中以第一个数值变量为复数变量 + if(isNumber(arg)) pluraValue = parseInt(arg); + }catch(e){ } + return arg + }); + + } + + // 2. 取得翻译文本模板字符串 + if(activeLanguage === scope.defaultLanguage){ + // 2.1 从默认语言中取得翻译文本模板字符串 + // 如果当前语言就是默认语言,不需要查询加载,只需要做插值变换即可 + // 当源文件运用了babel插件后会将原始文本内容转换为msgId + // 如果是msgId则从scope.default中读取,scope.default=默认语言包={:} + if(isMessageId(content)){ + content = scope.default[content] || message; + } + }else { + // 2.2 从当前语言包中取得翻译文本模板字符串 + // 如果没有启用babel插件将源文本转换为msgId,需要先将文本内容转换为msgId + let msgId = isMessageId(content) ? content : scope.idMap[content]; + content = scope.messages[msgId] || content; + } + + // 3. 处理复数 + // 经过上面的处理,content可能是字符串或者数组 + // content = "原始文本内容" || 复数形式["原始文本内容","原始文本内容"....] + // 如果是数组说明要启用复数机制,需要根据插值变量中的某个变量来判断复数形式 + if(Array.isArray(content) && content.length>0){ + // 如果存在复数命名变量,只取第一个复数变量 + if(pluraValue!==null){ // 启用的是位置插值,pluraIndex=第一个数字变量的位置 + content = getPluraMessage(content,pluraValue); + }else if(pluralVar.length>0){ + content = getPluraMessage(content,parseInt(vars(pluralVar[0]))); + }else { // 如果找不到复数变量,则使用第一个内容 + content = content[0]; + } + } + // 进行插值处理 + if(vars.length==0){ + return content + }else { + return replaceInterpolatedVars.call(scope,content,...vars) + } + }catch(e){ + return content // 出错则返回原始文本 + } +} + +/** + * 多语言管理类 + * + * 当导入编译后的多语言文件时(import("./languages")),会自动生成全局实例VoerkaI18n + * + * VoerkaI18n.languages // 返回支持的语言列表 + * VoerkaI18n.defaultLanguage // 默认语言 + * VoerkaI18n.language // 当前语言 + * VoerkaI18n.change(language) // 切换到新的语言 + * + * + * VoerkaI18n.on("change",(language)=>{}) // 注册语言切换事件 + * VoerkaI18n.off("change",(language)=>{}) + * + * */ + class I18nManager{ + static instance = null; // 单例引用 + callbacks = [] // 当切换语言时的回调事件 + constructor(settings={}){ + if(I18nManager.instance!=null){ + return I18nManager.instance; + } + I18nManager.instance = this; + this._settings = deepMerge(defaultLanguageSettings,settings); + this._scopes=[]; + return I18nManager.instance; + } + get settings(){ return this._settings } + get scopes(){ return this._scopes } + // 当前激活语言 + get activeLanguage(){ return this._settings.activeLanguage} + // 默认语言 + get defaultLanguage(){ return this.this._settings.defaultLanguage} + // 支持的语言列表 + get languages(){ return this._settings.languages} + // 订阅语言切换事件 + on(callback){ + this.callbacks.push(callback); + } + off(callback){ + for(let i=0;iawait cb(newLanguage))); + }catch(e){ + console.warn("Error while executing language change events",e.message); + } + } + /** + * 切换语言 + */ + async change(value){ + if(value in this.languages){ + await this._triggerChangeEvents(value); + this._settings.activeLanguage = value; + }else { + throw new Error("Not supported language:"+value) + } + } + /** + * 获取指定作用域的下的语言包加载器 + * + * 同时会进行语言兼容性处理 + * + * 如scope里面定义了一个cn的语言包,当切换到zh-cn时,会自动加载cn语言包 + * + * + * @param {*} scope + * @param {*} lang + */ + _getScopeLoader(scope,lang){ + + } + /** + * 当切换语言时调用此方法来加载更新语言包 + * @param {*} newLanguage + */ + async _updateScopes(newLanguage){ + // 并发执行所有作用域语言包的加载 + try{ + await (Promise.allSettled || Promise.all)(this._scopes.map(scope=>{ + return async ()=>{ + // 默认语言,所有均默认语言均采用静态加载方式,只需要简单的替换即可 + if(newLanguage === scope.defaultLanguage){ + scope.messages = scope.default; + return + } + // 异步加载语言文件 + const loader = scope.loaders[newLanguage]; + if(typeof(loader) === "function"){ + try{ + scope.messages = await loader(); + }catch(e){ + console.warn(`Error loading language ${newLanguage} : ${e.message}`); + scope.messages = defaultMessages; // 出错时回退到默认语言 + } + }else { + scope.messages = defaultMessages; + } + } + })); + }catch(e){ + console.warn("Error while refreshing scope:",e.message); + } + } + /** + * + * 注册一个新的作用域 + * + * 每一个库均对应一个作用域,每个作用域可以有多个语言包,且对应一个翻译函数 + * scope={ + * defaultLanguage:"cn", + default: defaultMessages, // 转换文本信息 + messages : defaultMessages, // 当前语言的消息 + idMap:messageIds, + formatters:{ + ...formatters, + ...i18nSettings.formatters || {} + }, + loaders:{}, // 异步加载语言文件的函数列表 + settings:{} // 引用全局VoerkaI18n实例的配置 + * } + * + * 除了默认语言外,其他语言采用动态加载的方式 + * + * @param {*} scope + */ + register(scope){ + scope.global = this._settings; + this._scopes.push(scope); + } + /** + * 注册全局格式化器 + * @param {*} formatters + */ + registerFormatters(formatters){ + + } +} + +var runtime ={ + getInterpolatedVars, + replaceInterpolatedVars, + I18nManager, + translate, + languages, + defaultLanguageSettings +}; + +export { runtime as default }; diff --git a/packages/runtime/index.js b/packages/runtime/index.js index c9f6dc5..7e67742 100644 --- a/packages/runtime/index.js +++ b/packages/runtime/index.js @@ -1,6 +1,5 @@ const deepMerge = require("deepmerge") -const formatters = require("./formatters") -const {isPlainObject ,isNumber , getDataTypeName} = require("./utils") +const formatters = require("./formatters") // 用来提取字符里面的插值变量参数 , 支持管道符 { var | formatter | formatter } // 不支持参数: let varWithPipeRegexp = /\{\s*(?\w+)?(?(\s*\|\s*\w*\s*)*)\s*\}/g @@ -31,7 +30,39 @@ let varReplaceRegexp =String.raw`\{\s*{varname}\s*\}` function hasInterpolation(str){ return str.includes("{") && str.includes("}") } +/** + * 获取指定变量类型名称 + * getDataTypeName(1) == Number + * getDataTypeName("") == String + * getDataTypeName(null) == Null + * getDataTypeName(undefined) == Undefined + * getDataTypeName(new Date()) == Date + * getDataTypeName(new Error()) == Error + * + * @param {*} v + * @returns + */ + function getDataTypeName(v){ + if (v === null) return 'Null' + if (v === undefined) return 'Undefined' + if(typeof(v)==="function") return "Function" + return v.constructor && v.constructor.name; +}; +function isPlainObject(obj){ + if (typeof obj !== 'object' || obj === null) return false; + var proto = Object.getPrototypeOf(obj); + if (proto === null) return true; + var baseProto = proto; + while (Object.getPrototypeOf(baseProto) !== null) { + baseProto = Object.getPrototypeOf(baseProto); + } + return proto === baseProto; +} +function isNumber(value){ + return !isNaN(parseInt(value)) +} + /** 通过正则表达式对原始文本内容进行解析匹配后得到的 @@ -182,15 +213,14 @@ function transformToString(value){ return result } - -// 缓存数据类型的格式化器,避免每次都调用getDataTypeDefaultFormatter -let datatypeFormattersCache ={ - $activeLanguage:null, +function resetScopeCache(scope,activeLanguage=null){ + scope.$cache = {activeLanguage,typedFormatters:{},formatters:{}} } /** * 取得指定数据类型的默认格式化器 * - * 可以为每一个数据类型指定一个格式化器,当传入插值变量时,会自动调用该格式化器来对值进行格式化转换 + * 可以为每一个数据类型指定一个默认的格式化器,当传入插值变量时, + * 会自动调用该格式化器来对值进行格式化转换 const formatters = { "*":{ @@ -211,33 +241,30 @@ let datatypeFormattersCache ={ * @returns {Function} 格式化函数 */ function getDataTypeDefaultFormatter(scope,activeLanguage,dataType){ - if(datatypeFormattersCache.$activeLanguage === activeLanguage) { - if(dataType in datatypeFormattersCache) return datatypeFormattersCache[dataType] - }else{// 清空缓存 - datatypeFormattersCache = { $activeLanguage:activeLanguage } + if(!scope.$cache) resetScopeCache(scope) + if(scope.$cache.activeLanguage === activeLanguage) { + if(dataType in scope.$cache.typedFormatters) return scope.$cache.typedFormatters[dataType] + }else{// 当语言切换时清空缓存 + resetScopeCache(scope,activeLanguage) } // 先在当前作用域中查找,再在全局查找 const targets = [scope.formatters,scope.global.formatters] for(const target of targets){ - if(activeLanguage in target){ - // 在当前语言的$types中查找 - let formatters = target[activeLanguage].$types || {} - for(let [name,formatter] of Object.entries(formatters)){ - if(name === dataType && typeof(formatter)==="function") { - datatypeFormattersCache[dataType] = formatter - return formatter - } - } + // 优先在当前语言的$types中查找 + if((activeLanguage in target) && isPlainObject(target[activeLanguage].$types)){ + let formatters = target[activeLanguage].$types + if(dataType in formatters && typeof(formatters[dataType])==="function"){ + return scope.$cache.typedFormatters[dataType] = formatters[dataType] + } } // 在所有语言的$types中查找 - let formatters = target["*"].$types || {} - for(let [name,formatter] of Object.entries(formatters)){ - if(name === dataType && typeof(formatter)==="function") { - datatypeFormattersCache[dataType] = formatter - return formatter - } - } + if(("*" in target) && isPlainObject(target["*"].$types)){ + let formatters = target["*"].$types + if(dataType in formatters && typeof(formatters[dataType])==="function"){ + return scope.$cache.typedFormatters[dataType] = formatters[dataType] + } + } } } @@ -247,13 +274,14 @@ function getDataTypeDefaultFormatter(scope,activeLanguage,dataType){ * @param {*} activeLanguage * @param {*} name 格式化器名称 * @returns {Function} 格式化函数 - */ -let formattersCache = { $activeLanguage:null} + */ function getFormatter(scope,activeLanguage,name){ - if(formattersCache.$activeLanguage === activeLanguage) { - if(name in formattersCache) return formattersCache[name] - }else{ // 当切换语言时需要清空缓存 - formattersCache = { $activeLanguage:activeLanguage } + // 缓存格式化器引用,避免重复检索 + if(!scope.$cache) resetScopeCache(scope) + if(scope.$cache.activeLanguage === activeLanguage) { + if(dataType in scope.$cache.formatters) return scope.$cache.formatters[dataType] + }else{// 当语言切换时清空缓存 + resetScopeCache(scope,activeLanguage) } // 先在当前作用域中查找,再在全局查找 const targets = [scope.formatters,scope.global.formatters] @@ -261,11 +289,11 @@ function getFormatter(scope,activeLanguage,name){ // 优先在当前语言查找 if(activeLanguage in target){ let formatters = target[activeLanguage] || {} - if((name in formatters) && typeof(formatters[name])==="function") return formattersCache[name] = formatters[name] + if((name in formatters) && typeof(formatters[name])==="function") return scope.$cache.formatters[name] = formatters[name] } // 在所有语言的$types中查找 let formatters = target["*"] || {} - if((name in formatters) && typeof(formatters[name])==="function") return formattersCache[name] = formatters[name] + if((name in formatters) && typeof(formatters[name])==="function") return scope.$cache.formatters[name] = formatters[name] } } @@ -308,7 +336,9 @@ function buildFormatters(scope,activeLanguage,formatters){ results.push((v)=>{ return func(v,...formatter[1]) }) - }else{// 格式化器无效或者没有定义时,查看当前值是否具有同名的方法,如果有则执行调用 + }else{ + // 格式化器无效或者没有定义时,查看当前值是否具有同名的原型方法,如果有则执行调用 + // 比如padStart格式化器是String的原型方法,不需要配置就可以直接作为格式化器调用 results.push((v)=>{ if(typeof(v[formatter[0]])==="function"){ return v[formatter[0]].call(v,...formatter[1]) @@ -333,7 +363,7 @@ function buildFormatters(scope,activeLanguage,formatters){ function getFormattedValue(scope,activeLanguage,formatters,value){ // 1. 取得格式化器函数列表 const formatterFuncs = buildFormatters(scope,activeLanguage,formatters) - // 3. 查找每种数据类型默认格式化器,并添加到formatters最前面,默认数据类型格式化器优先级最高 + // 2. 查找每种数据类型默认格式化器,并添加到formatters最前面,默认数据类型格式化器优先级最高 const defaultFormatter = getDataTypeDefaultFormatter(scope,activeLanguage,getDataTypeName(value)) if(defaultFormatter){ formatterFuncs.splice(0,0,defaultFormatter) @@ -534,13 +564,13 @@ function translate(message) { static instance = null; // 单例引用 callbacks = [] // 当切换语言时的回调事件 constructor(settings={}){ - if(i18n.instance==null){ - this.reset() - i18n.instance = this; + if(I18nManager.instance!=null){ + return I18nManager.instance; } + I18nManager.instance = this; this._settings = deepMerge(defaultLanguageSettings,settings) this._scopes=[] - return i18n.instance; + return I18nManager.instance; } get settings(){ return this._settings } get scopes(){ return this._scopes } @@ -571,16 +601,20 @@ function translate(message) { async _triggerChangeEvents(newLanguage){ try{ await this._updateScopes(newLanguage) - await (Promise.allSettled || Promise.all)(this.callbacks.map(async cb=>await cb(newLanguage))) + if(Promise.allSettled){ + await Promise.allSettled(this.callbacks.map(cb=>cb(newLanguage))) + }else{ + await Promise.all(this.callbacks.map(cb=>cb(newLanguage))) + } }catch(e){ - console.warn("Error while executing language change events",e.message) + console.warn("Error while executing language change events:",e.message) } } /** * 切换语言 */ async change(value){ - if(value in this.languages){ + if(this.languages.findIndex(lang=>lang.name === value)!==-1){ await this._triggerChangeEvents(value) this._settings.activeLanguage = value }else{ @@ -608,7 +642,7 @@ function translate(message) { async _updateScopes(newLanguage){ // 并发执行所有作用域语言包的加载 try{ - await (Promise.allSettled || Promise.all)(this._scopes.map(scope=>{ + let scopeLoders = this._scopes.map(scope=>{ return async ()=>{ // 默认语言,所有均默认语言均采用静态加载方式,只需要简单的替换即可 if(newLanguage === scope.defaultLanguage){ @@ -619,7 +653,7 @@ function translate(message) { const loader = scope.loaders[newLanguage] if(typeof(loader) === "function"){ try{ - scope.messages = await loader() + scope.messages = (await loader() ).default }catch(e){ console.warn(`Error loading language ${newLanguage} : ${e.message}`) scope.messages = defaultMessages // 出错时回退到默认语言 @@ -627,8 +661,13 @@ function translate(message) { }else{ scope.messages = defaultMessages } - } - })) + } + }) + if(Promise.allSettled){ + await Promise.allSettled(scopeLoders.map((f)=>f())) + }else{ + await Promise.all(scopeLoders.map((f)=>f())) + } }catch(e){ console.warn("Error while refreshing scope:",e.message) } @@ -674,5 +713,8 @@ module.exports ={ I18nManager, translate, languages, - defaultLanguageSettings + defaultLanguageSettings, + getDataTypeName, + isNumber, + isPlainObject } \ No newline at end of file diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 31ea294..d689f7c 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -3,12 +3,16 @@ "version": "1.0.0", "description": "Voerkai18n Runtime", "main": "index.js", + "module": "index.esm.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "build": "rollup -c" }, "author": "", "license": "ISC", "devDependencies": { - "deepmerge": "^4.2.2" + "@rollup/plugin-node-resolve": "^13.1.3", + "deepmerge": "^4.2.2", + "rollup-plugin-terser": "^7.0.2" } } diff --git a/packages/runtime/rollup.config.js b/packages/runtime/rollup.config.js index f17bbda..57e230b 100644 --- a/packages/runtime/rollup.config.js +++ b/packages/runtime/rollup.config.js @@ -1,33 +1,30 @@ import clear from 'rollup-plugin-clear' -import { uglify } from "rollup-plugin-uglify"; -import { babel } from '@rollup/plugin-babel'; import commonjs from '@rollup/plugin-commonjs'; +import resolve from "@rollup/plugin-node-resolve"; +import { terser } from "rollup-plugin-terser"; +// import { babel } from '@rollup/plugin-babel'; export default [ { input: './index.js', output: [ { - file: 'dist/index.mjs', - format:"es" + file: 'index.esm.js', + format:"esm" }, { - file: 'dist/index.cjs', + file: 'index.cjs', exports:"default", format:"cjs" } ], plugins: [ - //resolve(), - commonjs(), - babel({ - babelHelpers:"runtime", - exclude: 'node_modules/**' - }), + resolve(), + commonjs(), clear({targets:["dist"]}), - uglify() + //terser() ], - external:["@babel/runtime"] + //external:["@babel/runtime"] } ] \ No newline at end of file diff --git a/packages/runtime/utils.js b/packages/runtime/utils.js deleted file mode 100644 index 3478449..0000000 --- a/packages/runtime/utils.js +++ /dev/null @@ -1,41 +0,0 @@ - -/** - * 获取指定变量类型名称 - * getDataTypeName(1) == Number - * getDataTypeName("") == String - * getDataTypeName(null) == Null - * getDataTypeName(undefined) == Undefined - * getDataTypeName(new Date()) == Date - * getDataTypeName(new Error()) == Error - * - * @param {*} v - * @returns - */ -function getDataTypeName(v){ - if (v === null) return 'Null' - if (v === undefined) return 'Undefined' - if(typeof(v)==="function") return "Function" - return v.constructor && v.constructor.name; -}; -function isPlainObject(obj){ - if (typeof obj !== 'object' || obj === null) return false; - var proto = Object.getPrototypeOf(obj); - if (proto === null) return true; - var baseProto = proto; - - while (Object.getPrototypeOf(baseProto) !== null) { - baseProto = Object.getPrototypeOf(baseProto); - } - return proto === baseProto; -} -function isNumber(value){ - return !isNaN(parseInt(value)) -} - -module.exports = { - getDataTypeName, - isNumber, - isPlainObject -} - - diff --git a/packages/tools/compile.js b/packages/tools/compile.js index fa05b58..7ebdc60 100644 --- a/packages/tools/compile.js +++ b/packages/tools/compile.js @@ -27,7 +27,7 @@ const readJson = require("readjson") const glob = require("glob") const createLogger = require("logsets") const path = require("path") -const { importModule } = require("./utils") +const { importModule,findModuleType } = require("./utils") const fs = require("fs") const logger = createLogger() const artTemplate = require("art-template") @@ -45,24 +45,7 @@ function normalizeCompileOptions(opts={}) { } -/** - * 从当前文件夹开始向上查找package.json文件,并解析出语言包的类型 - * @param {*} folder - */ -function findModuleType(folder){ - try{ - let pkgPath = path.join(folder, "package.json") - if(fs.existsSync(pkgPath)){ - let pkg = readJson.sync(pkgPath) - return pkg.type || "commonjs" - } - let parent = path.dirname(folder) - if(parent===folder) return null - return findModuleType(parent) - }catch{ - return "esm" - } -} + module.exports =async function compile(langFolder,opts={}){ const options = normalizeCompileOptions(opts); diff --git a/packages/tools/extract.plugin.js b/packages/tools/extract.plugin.js index 020477c..6521188 100644 --- a/packages/tools/extract.plugin.js +++ b/packages/tools/extract.plugin.js @@ -11,7 +11,8 @@ const path = require('path') const fs = require('fs') const readJson = require("readjson") const createLogger = require("logsets") -const { replaceInterpolateVars,getDataTypeName } = require("../runtime/utils") +const { replaceInterpolateVars,getDataTypeName } = require("@voerkai18n/runtime") +const { findModuleType } = require("./utils") const logger = createLogger() // 捕获翻译文本的默认正则表达式 @@ -415,7 +416,10 @@ module.exports = function(options={}){ logger.log(" - Generate settings of language : {}",settingsFile) }else{ logger.log(" - Settings of language already exists : {}",settingsFile) - } + } + // 生成package.json + const packageJsonFile = path.join(outputPath,"package.json") + fs.writeFileSync(packageJsonFile,`${JSON.stringify({type:"commonjs"},null,4)}`) callback() }); } diff --git a/packages/tools/index.js b/packages/tools/index.js index fe4c383..ff52591 100644 --- a/packages/tools/index.js +++ b/packages/tools/index.js @@ -1,4 +1,7 @@ const { Command } = require('commander'); +const createLogger = require("logsets") + +const logger = createLogger() const program = new Command(); @@ -6,14 +9,34 @@ program .option('-d, --debug', '输出调试信息') program - .command('extract [destination]') - .description('扫描指定的项目目录,提取文件中的国际化字符串') + .command('init') + .argument('[location]', '工程项目所在目录') + .description('初始化项目国际化配置') + .option('-r, --reset', '重新生成当前项目的语言配置') + .option('-p, --langPath [name]', '语言包保存路径,默认/langauges',"languages") + .option('-m, --moduleType [type]', '生成的js模块类型,默认esm',"esm") + .option('-lngs, --languages ', '支持的语言列表', ['cn','en']) + .action((location,options) => { + if(!location) location = process.cwd() + const initializer = require("./initializer") + options.debug=true + initializer(location,options) + }); + + +program + .command('extract') + .description('扫描并提取所有待翻译的字符串到文件夹中') + .argument('[location]', 'js项目所在目录') .option('-d, --debug', '输出调试信息') - .option('-l, --languages', '支持的语言', 'cn,en,de,fr,es,it,jp') + .option('-ls, --languages', '支持的语言', 'cn,en,de,fr,es,it,jp') .option('-d, --default', '默认语言', 'cn') - .option('-a, --active', '激活语言', 'cn') - .action((source, destination) => { - console.log('clone command called'); + .option('-a, --active', '激活语言', 'cn') + .option('-o, --output', '输出目录', './languages') + .argument('', '工程所在目录') + .action((location) => { + if(!location) location = process.cwd() + console.log('location=',location); }); diff --git a/packages/tools/initializer.js b/packages/tools/initializer.js new file mode 100644 index 0000000..f55a019 --- /dev/null +++ b/packages/tools/initializer.js @@ -0,0 +1,51 @@ + +/** + * 初始化指定项目的语言包 + */ + + +const { findModuleType } = require("./utils") +const path = require("path") +const fs = require("fs") +const createLogger = require("logsets") +const logger = createLogger() + +module.exports = function(targetPath,{debug = true, langPath = "languages",languages=["cn","en"],defaultLanguage="cn",activeLanguage="cn",moduleType = "auto",reset=false}={}){ + // 查找当前项目的语言包类型路径 + if(moduleType==="auto"){ + moduleType = findModuleType(targetPath) + } + if(moduleType==null) { + if(debug){ + logger.log("找不到{}文件,{}只能在js项目工程中使用","package.json","voerkai18n") + }else{ + throw new Error("找不到package.json文件,voerkai18n只能在js项目工程中使用") + } + } + + const lngPath = path.join(targetPath,langPath) + if(!fs.existsSync(lngPath)){ + fs.mkdirSync(lngPath) + if(debug) logger.log("创建语言包文件夹: {}",lngPath) + } + + // 创建settings.js文件 + const settingsFile = path.join(lngPath,"settings.js") + if(fs.existsSync(settingsFile) && !reset){ + if(debug) logger.log("语言配置文件{}文件已存在,跳过创建。\n使用{}可以重新覆盖创建",settingsFile,"-r") + return + } + const settings = { + languages:languages.map(lng=>({name:lng,title:lng})), + defaultLanguage, + activeLanguage, + namespaces:{} + } + if(["esm","es"].includes(moduleType)){ + fs.writeFileSync(settingsFile,`export default ${JSON.stringify(settings,null,4)}`) + }else{ + fs.writeFileSync(settingsFile,`module.exports = ${JSON.stringify(settings,null,4)}`) + } + + if(debug) logger.log("创建语言配置文件<{}>成功",settingsFile) +} \ No newline at end of file diff --git a/packages/tools/package.json b/packages/tools/package.json index cdf865a..d1b88f1 100644 --- a/packages/tools/package.json +++ b/packages/tools/package.json @@ -7,20 +7,25 @@ "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", + "bin": { + "voerkai18n": "./index.js" + }, "license": "ISC", "dependencies": { "@babel/cli": "^7.17.6", "@babel/core": "^7.17.5", + "@voerkai18n/runtime": "workspace:^1.0.0", "art-template": "^4.13.2", "commander": "^9.0.0", "glob": "^7.2.0", "logsets": "^1.0.6", "readjson": "^2.2.2", - "through2": "^4.0.2" - }, - "devDependencies": { + "through2": "^4.0.2", "deepmerge": "^4.2.2", "gulp": "^4.0.2", "vinyl": "^2.2.1" + }, + "devDependencies": { + } } diff --git a/packages/tools/templates/entry.js b/packages/tools/templates/entry.js index d731729..59b952c 100644 --- a/packages/tools/templates/entry.js +++ b/packages/tools/templates/entry.js @@ -22,25 +22,28 @@ let scope = { idMap:messageIds, // 消息id映射列表 formatters:{}, // 当前作用域的格式化函数列表 loaders:{}, // 异步加载语言文件的函数列表 - global:{} // 引用全局VoerkaI18n配置,注册后自动引用 + global:{}, // 引用全局VoerkaI18n配置,注册后自动引用 + // 主要用来缓存格式化器的引用,当使用格式化器时可以直接引用,避免检索 + $cache:{ + activeLanguage:null, + typedFormatters:{}, + formatters:{}, + } } let supportedlanguages = {} -messages["{{defaultLanguage}}"]= defaultMessages {{each languages}}{{if $value.name !== defaultLanguage}} scope.loaders["{{$value.name}}"] = ()=>import("./{{$value.name}}.js") {{/if}}{{/each}} -const t = ()=> translate.bind(scope)(...arguments) +const t = translate.bind(scope) const languages = {{@ JSON.stringify(languages,null,4) }} // 注册当前作用域到全局VoerkaI18n实例 VoerkaI18n.register(scope) {{if moduleType === "esm"}} -export languages -export scope -export t +export { t, languages,scope } {{else}} module.exports.languages = languages module.exports.scope = scope diff --git a/packages/tools/utils.js b/packages/tools/utils.js index c4f80dd..3a792f3 100644 --- a/packages/tools/utils.js +++ b/packages/tools/utils.js @@ -7,9 +7,95 @@ async function importModule(url){ return await import(url) } } +/** + * 从当前文件夹开始向上查找package.json文件,并解析出语言包的类型 + * @param {*} folder + */ + function findModuleType(folder){ + try{ + let pkgPath = path.join(folder, "package.json") + if(fs.existsSync(pkgPath)){ + let pkg = readJson.sync(pkgPath) + return pkg.type || "commonjs" + } + let parent = path.dirname(folder) + if(parent===folder) return null + return findModuleType(parent) + }catch{ + return "esm" + } +} +function isPlainObject(obj){ + if (typeof obj !== 'object' || obj === null) return false; + var proto = Object.getPrototypeOf(obj); + if (proto === null) return true; + var baseProto = proto; + while (Object.getPrototypeOf(baseProto) !== null) { + baseProto = Object.getPrototypeOf(baseProto); + } + return proto === baseProto; +} +/** + * + * getExportContent({a:1}) == export let a = 1 + * + * @param {*} values + * @param {*} moduleType + * @returns + */ +function generateExportContents(values,{moduleType="esm",varExportDeclare="let"}={}){ + if(!isPlainObject(values)) throw new TypeError("export value must be a function or plain object") + let results = [] + let varExports = [] + let varExportSyntax = moduleType === "esm" ? `export ${varExportDeclare} ` : "module.exports." + let funcExportSyntax = moduleType === "esm" ? `export ` : "module.exports." + + Object.entries(values).forEach(([name,value])=>{ + if(Array.isArray(value) || isPlainObject(value)){ + results.push(`${varExportDeclare} ${name} = ${JSON.stringify(value,null,4)}`) + }else if(typeof(value)==="function"){ + if(value.prototype){ + results.push(value.toString()) + }else{// 箭头函数 + results.push(`const ${name} = ${value.toString()}`) + } + }else{ + results.push(`${varExportDeclare} ${name} = ${JSON.stringify(value)}`) + } + }) + + if(moduleType === "esm"){ + results.push(`export {\n\t${Object.keys(values).join(",\n\t")}\n}`) + }else{ fu + results.push(`module.exports = {\n\t${Object.keys(values).join(",\n\t")}\n}`) + } + + return results.join("\n") +} + +/** + * 创建js文件 + * @param {*} filename + * @param {*} defaultExports + * @param {*} namedExports {name:value} + * + * @param {*} moduleType + */ +function createJsModuleFile(filename,defaultExports={},namedExports={},moduleType="esm"){ + let jsContents = [] + if(moduleType === "esm"){ + Object.entries(namedExports).forEach(([name,value])=>{ + + }) + jsContents.push + }else{ + + } +} module.exports = { - importModule + importModule, + findModuleType } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b01bcc3..46c1590 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,7 +15,6 @@ importers: jest: ^27.5.1 rollup: ^2.69.0 rollup-plugin-clear: ^2.0.7 - rollup-plugin-uglify: ^6.0.4 vinyl: ^2.2.1 devDependencies: '@babel/core': 7.17.5 @@ -29,7 +28,6 @@ importers: jest: 27.5.1 rollup: 2.69.0 rollup-plugin-clear: 2.0.7 - rollup-plugin-uglify: 6.0.4_rollup@2.69.0 vinyl: 2.2.1 packages/demo: @@ -47,6 +45,15 @@ importers: gulp: 4.0.2 vinyl: 2.2.1 + packages/demo/apps/app: + specifiers: + '@voerkai18n/tools': workspace:^1.0.0 + dependencies: + '@voerkai18n/tools': link:../../../tools + + packages/demo/apps/app/languages: + specifiers: {} + packages/formatters: specifiers: deepmerge: ^4.2.2 @@ -69,14 +76,19 @@ importers: packages/runtime: specifiers: + '@rollup/plugin-node-resolve': ^13.1.3 deepmerge: ^4.2.2 + rollup-plugin-terser: ^7.0.2 devDependencies: + '@rollup/plugin-node-resolve': 13.1.3_rollup@2.69.0 deepmerge: 4.2.2 + rollup-plugin-terser: 7.0.2_rollup@2.69.0 packages/tools: specifiers: '@babel/cli': ^7.17.6 '@babel/core': ^7.17.5 + '@voerkai18n/runtime': workspace:^1.0.0 art-template: ^4.13.2 commander: ^9.0.0 deepmerge: ^4.2.2 @@ -89,15 +101,15 @@ importers: dependencies: '@babel/cli': 7.17.6_@babel+core@7.17.5 '@babel/core': 7.17.5 + '@voerkai18n/runtime': link:../runtime art-template: 4.13.2 commander: 9.0.0 + deepmerge: 4.2.2 glob: 7.2.0 + gulp: 4.0.2 logsets: 1.0.6 readjson: 2.2.2 through2: 4.0.2 - devDependencies: - deepmerge: 4.2.2 - gulp: 4.0.2 vinyl: 2.2.1 packages/vue: @@ -135,8 +147,8 @@ packages: slash: 2.0.0 source-map: 0.5.7 optionalDependencies: - '@nicolo-ribaudo/chokidar-2': registry.npmmirror.com/@nicolo-ribaudo/chokidar-2/2.1.8-no-fsevents.3 - chokidar: registry.npmmirror.com/chokidar/3.5.3 + '@nicolo-ribaudo/chokidar-2': 2.1.8-no-fsevents.3 + chokidar: 3.5.3 dev: false /@babel/code-frame/7.16.7: @@ -1512,6 +1524,12 @@ packages: '@jridgewell/resolve-uri': 3.0.5 '@jridgewell/sourcemap-codec': 1.4.11 + /@nicolo-ribaudo/chokidar-2/2.1.8-no-fsevents.3: + resolution: {integrity: sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==} + requiresBuild: true + dev: false + optional: true + /@rollup/plugin-babel/5.3.1_@babel+core@7.17.5+rollup@2.69.0: resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} engines: {node: '>= 10.0.0'} @@ -1545,6 +1563,21 @@ packages: rollup: 2.69.0 dev: true + /@rollup/plugin-node-resolve/13.1.3_rollup@2.69.0: + resolution: {integrity: sha512-BdxNk+LtmElRo5d06MGY4zoepyrXX1tkzX2hrnPEZ53k78GuOMWLqmJDGIIOPwVRIFZrLQOo+Yr6KtCuLIA0AQ==} + engines: {node: '>= 10.0.0'} + peerDependencies: + rollup: ^2.42.0 + dependencies: + '@rollup/pluginutils': 3.1.0_rollup@2.69.0 + '@types/resolve': 1.17.1 + builtin-modules: 3.2.0 + deepmerge: 4.2.2 + is-module: 1.0.0 + resolve: 1.22.0 + rollup: 2.69.0 + dev: true + /@rollup/pluginutils/3.1.0_rollup@2.69.0: resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} engines: {node: '>= 8.0.0'} @@ -1641,6 +1674,12 @@ packages: resolution: {integrity: sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==} dev: true + /@types/resolve/1.17.1: + resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} + dependencies: + '@types/node': 17.0.21 + dev: true + /@types/stack-utils/2.0.1: resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} dev: true @@ -1703,7 +1742,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: ansi-wrap: 0.1.0 - dev: true /ansi-escapes/4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} @@ -1717,12 +1755,10 @@ packages: engines: {node: '>=0.10.0'} dependencies: ansi-wrap: 0.1.0 - dev: true /ansi-regex/2.1.1: resolution: {integrity: sha1-w7M6te42DYbg5ijwRorn7yfWVN8=} engines: {node: '>=0.10.0'} - dev: true /ansi-regex/5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} @@ -1750,14 +1786,12 @@ packages: /ansi-wrap/0.1.0: resolution: {integrity: sha1-qCJQ3bABXponyoLoLqYDu/pF768=} engines: {node: '>=0.10.0'} - dev: true /anymatch/2.0.0: resolution: {integrity: sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==} dependencies: micromatch: 3.1.10 normalize-path: 2.1.1 - dev: true /anymatch/3.1.2: resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} @@ -1771,11 +1805,9 @@ packages: engines: {node: '>=0.10.0'} dependencies: buffer-equal: 1.0.0 - dev: true /archy/1.0.0: resolution: {integrity: sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=} - dev: true /argparse/1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -1786,36 +1818,30 @@ packages: /arr-diff/4.0.0: resolution: {integrity: sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=} engines: {node: '>=0.10.0'} - dev: true /arr-filter/1.1.2: resolution: {integrity: sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=} engines: {node: '>=0.10.0'} dependencies: make-iterator: 1.0.1 - dev: true /arr-flatten/1.1.0: resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} engines: {node: '>=0.10.0'} - dev: true /arr-map/2.0.2: resolution: {integrity: sha1-Onc0X/wc814qkYJWAfnljy4kysQ=} engines: {node: '>=0.10.0'} dependencies: make-iterator: 1.0.1 - dev: true /arr-union/3.1.0: resolution: {integrity: sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=} engines: {node: '>=0.10.0'} - dev: true /array-each/1.0.1: resolution: {integrity: sha1-p5SvDAWrF1KEbudTofIRoFugxE8=} engines: {node: '>=0.10.0'} - dev: true /array-initial/1.1.0: resolution: {integrity: sha1-L6dLJnOTccOUe9enrcc74zSz15U=} @@ -1823,19 +1849,16 @@ packages: dependencies: array-slice: 1.1.0 is-number: 4.0.0 - dev: true /array-last/1.3.0: resolution: {integrity: sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==} engines: {node: '>=0.10.0'} dependencies: is-number: 4.0.0 - dev: true /array-slice/1.1.0: resolution: {integrity: sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==} engines: {node: '>=0.10.0'} - dev: true /array-sort/1.0.0: resolution: {integrity: sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==} @@ -1844,12 +1867,10 @@ packages: default-compare: 1.0.0 get-value: 2.0.6 kind-of: 5.1.0 - dev: true /array-unique/0.3.2: resolution: {integrity: sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=} engines: {node: '>=0.10.0'} - dev: true /art-template/4.13.2: resolution: {integrity: sha512-04ws5k+ndA5DghfheY4c8F1304XJKeTcaXqZCLpxFkNMSkaR3ChW1pX2i9d3sEEOZuLy7de8lFriRaik1jEeOQ==} @@ -1868,7 +1889,6 @@ packages: /assign-symbols/1.0.0: resolution: {integrity: sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=} engines: {node: '>=0.10.0'} - dev: true /async-done/1.3.2: resolution: {integrity: sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==} @@ -1878,18 +1898,15 @@ packages: once: 1.4.0 process-nextick-args: 2.0.1 stream-exhaust: 1.0.2 - dev: true /async-each/1.0.3: resolution: {integrity: sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==} - dev: true /async-settle/1.0.0: resolution: {integrity: sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=} engines: {node: '>= 0.10'} dependencies: async-done: 1.3.2 - dev: true /asynckit/0.4.0: resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=} @@ -1899,7 +1916,6 @@ packages: resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} engines: {node: '>= 4.5.0'} hasBin: true - dev: true /babel-jest/27.5.1_@babel+core@7.17.5: resolution: {integrity: sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==} @@ -2029,7 +2045,6 @@ packages: async-done: 1.3.2 async-settle: 1.0.0 now-and-later: 2.0.1 - dev: true /balanced-match/1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -2045,12 +2060,10 @@ packages: isobject: 3.0.1 mixin-deep: 1.3.2 pascalcase: 0.1.1 - dev: true /binary-extensions/1.13.1: resolution: {integrity: sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==} engines: {node: '>=0.10.0'} - dev: true /binary-extensions/2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} @@ -2058,6 +2071,13 @@ packages: dev: false optional: true + /bindings/1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + requiresBuild: true + dependencies: + file-uri-to-path: 1.0.0 + optional: true + /brace-expansion/1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -2078,7 +2098,6 @@ packages: snapdragon-node: 2.1.1 split-string: 3.1.0 to-regex: 3.0.2 - dev: true /braces/3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} @@ -2110,10 +2129,13 @@ packages: /buffer-equal/1.0.0: resolution: {integrity: sha1-WWFrSYME1Var1GaWayLu2j7KX74=} engines: {node: '>=0.4.0'} - dev: true /buffer-from/1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + /builtin-modules/3.2.0: + resolution: {integrity: sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==} + engines: {node: '>=6'} dev: true /cache-base/1.0.1: @@ -2129,14 +2151,12 @@ packages: to-object-path: 0.3.0 union-value: 1.0.1 unset-value: 1.0.0 - dev: true /call-bind/1.0.2: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} dependencies: function-bind: 1.1.1 get-intrinsic: 1.1.1 - dev: true /callsites/3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} @@ -2153,7 +2173,6 @@ packages: /camelcase/3.0.0: resolution: {integrity: sha1-MvxLn82vhF/N9+c7uXysImHwqwo=} engines: {node: '>=0.10.0'} - dev: true /camelcase/5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} @@ -2205,8 +2224,24 @@ packages: readdirp: 2.2.1 upath: 1.2.0 optionalDependencies: - fsevents: registry.npmmirror.com/fsevents/1.2.13 - dev: true + fsevents: 1.2.13 + + /chokidar/3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + requiresBuild: true + dependencies: + anymatch: 3.1.2 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.2 + dev: false + optional: true /ci-info/3.3.0: resolution: {integrity: sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==} @@ -2224,13 +2259,12 @@ packages: define-property: 0.2.5 isobject: 3.0.1 static-extend: 0.1.2 - dev: true /clean-css/4.2.4: resolution: {integrity: sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==} engines: {node: '>= 4.0'} dependencies: - source-map: registry.npmmirror.com/source-map/0.6.1 + source-map: 0.6.1 dev: false /cliui/3.2.0: @@ -2239,7 +2273,6 @@ packages: string-width: 1.0.2 strip-ansi: 3.0.1 wrap-ansi: 2.1.0 - dev: true /cliui/7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} @@ -2252,16 +2285,13 @@ packages: /clone-buffer/1.0.0: resolution: {integrity: sha1-4+JbIHrE5wGvch4staFnksrD3Fg=} engines: {node: '>= 0.10'} - dev: true /clone-stats/1.0.0: resolution: {integrity: sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=} - dev: true /clone/2.1.2: resolution: {integrity: sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=} engines: {node: '>=0.8'} - dev: true /cloneable-readable/1.1.3: resolution: {integrity: sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==} @@ -2269,7 +2299,6 @@ packages: inherits: 2.0.4 process-nextick-args: 2.0.1 readable-stream: 2.3.7 - dev: true /co/4.6.0: resolution: {integrity: sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=} @@ -2279,7 +2308,6 @@ packages: /code-point-at/1.1.0: resolution: {integrity: sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=} engines: {node: '>=0.10.0'} - dev: true /collect-v8-coverage/1.0.1: resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} @@ -2292,7 +2320,6 @@ packages: arr-map: 2.0.2 for-own: 1.0.0 make-iterator: 1.0.1 - dev: true /collection-visit/1.0.0: resolution: {integrity: sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=} @@ -2300,7 +2327,6 @@ packages: dependencies: map-visit: 1.0.0 object-visit: 1.0.1 - dev: true /color-convert/1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -2324,7 +2350,6 @@ packages: /color-support/1.1.3: resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} hasBin: true - dev: true /combined-stream/1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} @@ -2339,6 +2364,11 @@ packages: /commander/2.19.0: resolution: {integrity: sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==} + dev: false + + /commander/2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true /commander/4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} @@ -2356,7 +2386,6 @@ packages: /component-emitter/1.3.0: resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} - dev: true /concat-map/0.0.1: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} @@ -2369,7 +2398,6 @@ packages: inherits: 2.0.4 readable-stream: 2.3.7 typedarray: 0.0.6 - dev: true /convert-source-map/1.8.0: resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==} @@ -2379,14 +2407,12 @@ packages: /copy-descriptor/0.1.1: resolution: {integrity: sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=} engines: {node: '>=0.10.0'} - dev: true /copy-props/2.0.5: resolution: {integrity: sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==} dependencies: each-props: 1.3.2 is-plain-object: 5.0.0 - dev: true /core-js-compat/3.21.1: resolution: {integrity: sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g==} @@ -2397,7 +2423,6 @@ packages: /core-util-is/1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - dev: true /cross-spawn/7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} @@ -2428,7 +2453,6 @@ packages: dependencies: es5-ext: 0.10.53 type: 1.2.0 - dev: true /data-urls/2.0.0: resolution: {integrity: sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==} @@ -2447,7 +2471,6 @@ packages: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} dependencies: ms: 2.0.0 - dev: true /debug/4.3.3: resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} @@ -2463,7 +2486,6 @@ packages: /decamelize/1.2.0: resolution: {integrity: sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=} engines: {node: '>=0.10.0'} - dev: true /decimal.js/10.3.1: resolution: {integrity: sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==} @@ -2472,7 +2494,6 @@ packages: /decode-uri-component/0.2.0: resolution: {integrity: sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=} engines: {node: '>=0.10'} - dev: true /dedent/0.7.0: resolution: {integrity: sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=} @@ -2490,33 +2511,28 @@ packages: engines: {node: '>=0.10.0'} dependencies: kind-of: 5.1.0 - dev: true /default-resolution/2.0.0: resolution: {integrity: sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=} engines: {node: '>= 0.10'} - dev: true /define-properties/1.1.3: resolution: {integrity: sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==} engines: {node: '>= 0.4'} dependencies: object-keys: 1.1.1 - dev: true /define-property/0.2.5: resolution: {integrity: sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=} engines: {node: '>=0.10.0'} dependencies: is-descriptor: 0.1.6 - dev: true /define-property/1.0.0: resolution: {integrity: sha1-dp66rz9KY6rTr56NMEybvnm/sOY=} engines: {node: '>=0.10.0'} dependencies: is-descriptor: 1.0.2 - dev: true /define-property/2.0.2: resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} @@ -2524,7 +2540,6 @@ packages: dependencies: is-descriptor: 1.0.2 isobject: 3.0.1 - dev: true /delayed-stream/1.0.0: resolution: {integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk=} @@ -2534,7 +2549,6 @@ packages: /detect-file/1.0.0: resolution: {integrity: sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=} engines: {node: '>=0.10.0'} - dev: true /detect-newline/3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} @@ -2560,14 +2574,12 @@ packages: inherits: 2.0.4 readable-stream: 2.3.7 stream-shift: 1.0.1 - dev: true /each-props/1.3.2: resolution: {integrity: sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==} dependencies: is-plain-object: 2.0.4 object.defaults: 1.1.0 - dev: true /electron-to-chromium/1.4.73: resolution: {integrity: sha512-RlCffXkE/LliqfA5m29+dVDPB2r72y2D2egMMfIy3Le8ODrxjuZNVo4NIC2yPL01N4xb4nZQLwzi6Z5tGIGLnA==} @@ -2585,13 +2597,11 @@ packages: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: once: 1.4.0 - dev: true /error-ex/1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: is-arrayish: 0.2.1 - dev: true /es5-ext/0.10.53: resolution: {integrity: sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==} @@ -2599,7 +2609,6 @@ packages: es6-iterator: 2.0.3 es6-symbol: 3.1.3 next-tick: 1.0.0 - dev: true /es6-iterator/2.0.3: resolution: {integrity: sha1-p96IkUGgWpSwhUQDstCg+/qY87c=} @@ -2607,14 +2616,12 @@ packages: d: 1.0.1 es5-ext: 0.10.53 es6-symbol: 3.1.3 - dev: true /es6-symbol/3.1.3: resolution: {integrity: sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==} dependencies: d: 1.0.1 ext: 1.6.0 - dev: true /es6-weak-map/2.0.3: resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} @@ -2623,7 +2630,6 @@ packages: es5-ext: 0.10.53 es6-iterator: 2.0.3 es6-symbol: 3.1.3 - dev: true /escalade/3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} @@ -2648,7 +2654,7 @@ packages: esutils: 2.0.3 optionator: 0.8.3 optionalDependencies: - source-map: registry.npmmirror.com/source-map/0.6.1 + source-map: 0.6.1 dev: false /escodegen/2.0.0: @@ -2661,7 +2667,7 @@ packages: esutils: 2.0.3 optionator: 0.8.3 optionalDependencies: - source-map: registry.npmmirror.com/source-map/0.6.1 + source-map: 0.6.1 dev: true /esprima/4.0.1: @@ -2722,14 +2728,12 @@ packages: regex-not: 1.0.2 snapdragon: 0.8.2 to-regex: 3.0.2 - dev: true /expand-tilde/2.0.2: resolution: {integrity: sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=} engines: {node: '>=0.10.0'} dependencies: homedir-polyfill: 1.0.3 - dev: true /expect/27.5.1: resolution: {integrity: sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==} @@ -2745,14 +2749,12 @@ packages: resolution: {integrity: sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==} dependencies: type: 2.6.0 - dev: true /extend-shallow/2.0.1: resolution: {integrity: sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=} engines: {node: '>=0.10.0'} dependencies: is-extendable: 0.1.1 - dev: true /extend-shallow/3.0.2: resolution: {integrity: sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=} @@ -2760,11 +2762,9 @@ packages: dependencies: assign-symbols: 1.0.0 is-extendable: 1.0.1 - dev: true /extend/3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - dev: true /extglob/2.0.4: resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} @@ -2778,7 +2778,6 @@ packages: regex-not: 1.0.2 snapdragon: 0.8.2 to-regex: 3.0.2 - dev: true /fancy-log/1.3.3: resolution: {integrity: sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==} @@ -2788,7 +2787,6 @@ packages: color-support: 1.1.3 parse-node-version: 1.0.1 time-stamp: 1.1.0 - dev: true /fast-json-stable-stringify/2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -2796,7 +2794,6 @@ packages: /fast-levenshtein/1.1.4: resolution: {integrity: sha1-5qdUzI8V5YmHqpy9J69m/W9OWvk=} - dev: true /fast-levenshtein/2.0.6: resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=} @@ -2807,6 +2804,11 @@ packages: bser: 2.1.1 dev: true + /file-uri-to-path/1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + requiresBuild: true + optional: true + /fill-range/4.0.0: resolution: {integrity: sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=} engines: {node: '>=0.10.0'} @@ -2815,7 +2817,6 @@ packages: is-number: 3.0.0 repeat-string: 1.6.1 to-regex-range: 2.1.1 - dev: true /fill-range/7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} @@ -2829,7 +2830,6 @@ packages: dependencies: path-exists: 2.1.0 pinkie-promise: 2.0.1 - dev: true /find-up/4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} @@ -2847,7 +2847,6 @@ packages: is-glob: 3.1.0 micromatch: 3.1.10 resolve-dir: 1.0.1 - dev: true /findup-sync/3.0.0: resolution: {integrity: sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==} @@ -2857,7 +2856,6 @@ packages: is-glob: 4.0.3 micromatch: 3.1.10 resolve-dir: 1.0.1 - dev: true /fined/1.2.0: resolution: {integrity: sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==} @@ -2868,31 +2866,26 @@ packages: object.defaults: 1.1.0 object.pick: 1.3.0 parse-filepath: 1.0.2 - dev: true /flagged-respawn/1.0.1: resolution: {integrity: sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==} engines: {node: '>= 0.10'} - dev: true /flush-write-stream/1.1.1: resolution: {integrity: sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==} dependencies: inherits: 2.0.4 readable-stream: 2.3.7 - dev: true /for-in/1.0.2: resolution: {integrity: sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=} engines: {node: '>=0.10.0'} - dev: true /for-own/1.0.0: resolution: {integrity: sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=} engines: {node: '>=0.10.0'} dependencies: for-in: 1.0.2 - dev: true /form-data/3.0.1: resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} @@ -2908,7 +2901,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: map-cache: 0.2.2 - dev: true /fs-mkdirp-stream/1.0.0: resolution: {integrity: sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=} @@ -2916,7 +2908,6 @@ packages: dependencies: graceful-fs: 4.2.9 through2: 2.0.5 - dev: true /fs-readdir-recursive/1.1.0: resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} @@ -2925,9 +2916,26 @@ packages: /fs.realpath/1.0.0: resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} + /fsevents/1.2.13: + resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==} + engines: {node: '>= 4.0'} + os: [darwin] + deprecated: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2. + requiresBuild: true + dependencies: + bindings: 1.5.0 + nan: 2.15.0 + optional: true + + /fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + optional: true + /function-bind/1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - dev: true /gensync/1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} @@ -2935,7 +2943,6 @@ packages: /get-caller-file/1.0.3: resolution: {integrity: sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==} - dev: true /get-caller-file/2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} @@ -2948,7 +2955,6 @@ packages: function-bind: 1.1.1 has: 1.0.3 has-symbols: 1.0.2 - dev: true /get-package-type/0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} @@ -2963,14 +2969,12 @@ packages: /get-value/2.0.6: resolution: {integrity: sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=} engines: {node: '>=0.10.0'} - dev: true /glob-parent/3.1.0: resolution: {integrity: sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=} dependencies: is-glob: 3.1.0 path-dirname: 1.0.2 - dev: true /glob-parent/5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} @@ -2994,7 +2998,6 @@ packages: remove-trailing-separator: 1.1.0 to-absolute-glob: 2.0.2 unique-stream: 2.3.1 - dev: true /glob-watcher/5.0.5: resolution: {integrity: sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==} @@ -3007,7 +3010,6 @@ packages: just-debounce: 1.1.0 normalize-path: 3.0.0 object.defaults: 1.1.0 - dev: true /glob/7.2.0: resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} @@ -3026,7 +3028,6 @@ packages: global-prefix: 1.0.2 is-windows: 1.0.2 resolve-dir: 1.0.1 - dev: true /global-prefix/1.0.2: resolution: {integrity: sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=} @@ -3037,7 +3038,6 @@ packages: ini: 1.3.8 is-windows: 1.0.2 which: 1.3.1 - dev: true /globals/11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} @@ -3048,11 +3048,9 @@ packages: engines: {node: '>= 0.10'} dependencies: sparkles: 1.0.1 - dev: true /graceful-fs/4.2.9: resolution: {integrity: sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==} - dev: true /gulp-cli/2.3.0: resolution: {integrity: sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==} @@ -3077,7 +3075,6 @@ packages: semver-greatest-satisfied-range: 1.1.0 v8flags: 3.2.0 yargs: 7.1.2 - dev: true /gulp/4.0.2: resolution: {integrity: sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==} @@ -3088,14 +3085,12 @@ packages: gulp-cli: 2.3.0 undertaker: 1.3.0 vinyl-fs: 3.0.3 - dev: true /gulplog/1.0.0: resolution: {integrity: sha1-4oxNRdBey77YGDY86PnFkmIp/+U=} engines: {node: '>= 0.10'} dependencies: glogg: 1.0.2 - dev: true /has-flag/3.0.0: resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=} @@ -3109,7 +3104,6 @@ packages: /has-symbols/1.0.2: resolution: {integrity: sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==} engines: {node: '>= 0.4'} - dev: true /has-value/0.3.1: resolution: {integrity: sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=} @@ -3118,7 +3112,6 @@ packages: get-value: 2.0.6 has-values: 0.1.4 isobject: 2.1.0 - dev: true /has-value/1.0.0: resolution: {integrity: sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=} @@ -3127,12 +3120,10 @@ packages: get-value: 2.0.6 has-values: 1.0.0 isobject: 3.0.1 - dev: true /has-values/0.1.4: resolution: {integrity: sha1-bWHeldkd/Km5oCCJrThL/49it3E=} engines: {node: '>=0.10.0'} - dev: true /has-values/1.0.0: resolution: {integrity: sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=} @@ -3140,14 +3131,12 @@ packages: dependencies: is-number: 3.0.0 kind-of: 4.0.0 - dev: true /has/1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} dependencies: function-bind: 1.1.1 - dev: true /he/1.2.0: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} @@ -3159,11 +3148,9 @@ packages: engines: {node: '>=0.10.0'} dependencies: parse-passwd: 1.0.0 - dev: true /hosted-git-info/2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} - dev: true /html-encoding-sniffer/2.0.1: resolution: {integrity: sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==} @@ -3248,17 +3235,14 @@ packages: /ini/1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - dev: true /interpret/1.4.0: resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} engines: {node: '>= 0.10'} - dev: true /invert-kv/1.0.0: resolution: {integrity: sha1-EEqOSqym09jNFXqO+L+rLXo//bY=} engines: {node: '>=0.10.0'} - dev: true /is-absolute/1.0.0: resolution: {integrity: sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==} @@ -3266,32 +3250,27 @@ packages: dependencies: is-relative: 1.0.0 is-windows: 1.0.2 - dev: true /is-accessor-descriptor/0.1.6: resolution: {integrity: sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=} engines: {node: '>=0.10.0'} dependencies: kind-of: 3.2.2 - dev: true /is-accessor-descriptor/1.0.0: resolution: {integrity: sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==} engines: {node: '>=0.10.0'} dependencies: kind-of: 6.0.3 - dev: true /is-arrayish/0.2.1: resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=} - dev: true /is-binary-path/1.0.1: resolution: {integrity: sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=} engines: {node: '>=0.10.0'} dependencies: binary-extensions: 1.13.1 - dev: true /is-binary-path/2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} @@ -3303,27 +3282,23 @@ packages: /is-buffer/1.1.6: resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - dev: true /is-core-module/2.8.1: resolution: {integrity: sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==} dependencies: has: 1.0.3 - dev: true /is-data-descriptor/0.1.4: resolution: {integrity: sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=} engines: {node: '>=0.10.0'} dependencies: kind-of: 3.2.2 - dev: true /is-data-descriptor/1.0.0: resolution: {integrity: sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==} engines: {node: '>=0.10.0'} dependencies: kind-of: 6.0.3 - dev: true /is-descriptor/0.1.6: resolution: {integrity: sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==} @@ -3332,7 +3307,6 @@ packages: is-accessor-descriptor: 0.1.6 is-data-descriptor: 0.1.4 kind-of: 5.1.0 - dev: true /is-descriptor/1.0.2: resolution: {integrity: sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==} @@ -3341,19 +3315,16 @@ packages: is-accessor-descriptor: 1.0.0 is-data-descriptor: 1.0.0 kind-of: 6.0.3 - dev: true /is-extendable/0.1.1: resolution: {integrity: sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=} engines: {node: '>=0.10.0'} - dev: true /is-extendable/1.0.1: resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} engines: {node: '>=0.10.0'} dependencies: is-plain-object: 2.0.4 - dev: true /is-extglob/2.1.1: resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=} @@ -3364,7 +3335,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: number-is-nan: 1.0.1 - dev: true /is-fullwidth-code-point/3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} @@ -3381,7 +3351,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 - dev: true /is-glob/4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} @@ -3394,22 +3363,23 @@ packages: engines: {node: '>=0.10.0'} dev: false + /is-module/1.0.0: + resolution: {integrity: sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=} + dev: true + /is-negated-glob/1.0.0: resolution: {integrity: sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=} engines: {node: '>=0.10.0'} - dev: true /is-number/3.0.0: resolution: {integrity: sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=} engines: {node: '>=0.10.0'} dependencies: kind-of: 3.2.2 - dev: true /is-number/4.0.0: resolution: {integrity: sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==} engines: {node: '>=0.10.0'} - dev: true /is-number/7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} @@ -3420,12 +3390,10 @@ packages: engines: {node: '>=0.10.0'} dependencies: isobject: 3.0.1 - dev: true /is-plain-object/5.0.0: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} - dev: true /is-potential-custom-element-name/1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} @@ -3442,7 +3410,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: is-unc-path: 1.0.0 - dev: true /is-stream/2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} @@ -3458,41 +3425,33 @@ packages: engines: {node: '>=0.10.0'} dependencies: unc-path-regex: 0.1.2 - dev: true /is-utf8/0.2.1: resolution: {integrity: sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=} - dev: true /is-valid-glob/1.0.0: resolution: {integrity: sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=} engines: {node: '>=0.10.0'} - dev: true /is-windows/1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} - dev: true /isarray/1.0.0: resolution: {integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=} - dev: true /isexe/2.0.0: resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=} - dev: true /isobject/2.1.0: resolution: {integrity: sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=} engines: {node: '>=0.10.0'} dependencies: isarray: 1.0.0 - dev: true /isobject/3.0.1: resolution: {integrity: sha1-TkMekrEalzFjaqH5yNHMvP2reN8=} engines: {node: '>=0.10.0'} - dev: true /istanbul-lib-coverage/3.2.0: resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} @@ -3726,7 +3685,7 @@ packages: micromatch: 4.0.4 walker: 1.0.8 optionalDependencies: - fsevents: registry.npmmirror.com/fsevents/2.3.2 + fsevents: 2.3.2 dev: true /jest-jasmine2/27.5.1: @@ -3976,12 +3935,13 @@ packages: string-length: 4.0.2 dev: true - /jest-worker/24.9.0: - resolution: {integrity: sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==} - engines: {node: '>= 6'} + /jest-worker/26.6.2: + resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} + engines: {node: '>= 10.13.0'} dependencies: + '@types/node': 17.0.21 merge-stream: 2.0.0 - supports-color: 6.1.0 + supports-color: 7.2.0 dev: true /jest-worker/27.5.1: @@ -4091,7 +4051,6 @@ packages: /json-stable-stringify-without-jsonify/1.0.1: resolution: {integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=} - dev: true /json5/2.2.0: resolution: {integrity: sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==} @@ -4102,31 +4061,26 @@ packages: /just-debounce/1.1.0: resolution: {integrity: sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==} - dev: true /kind-of/3.2.2: resolution: {integrity: sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=} engines: {node: '>=0.10.0'} dependencies: is-buffer: 1.1.6 - dev: true /kind-of/4.0.0: resolution: {integrity: sha1-IIE989cSkosgc3hpGkUGb65y3Vc=} engines: {node: '>=0.10.0'} dependencies: is-buffer: 1.1.6 - dev: true /kind-of/5.1.0: resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} engines: {node: '>=0.10.0'} - dev: true /kind-of/6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - dev: true /kleur/3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} @@ -4139,28 +4093,24 @@ packages: dependencies: default-resolution: 2.0.0 es6-weak-map: 2.0.3 - dev: true /lazystream/1.0.1: resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} engines: {node: '>= 0.6.3'} dependencies: readable-stream: 2.3.7 - dev: true /lcid/1.0.0: resolution: {integrity: sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=} engines: {node: '>=0.10.0'} dependencies: invert-kv: 1.0.0 - dev: true /lead/1.0.0: resolution: {integrity: sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=} engines: {node: '>= 0.10'} dependencies: flush-write-stream: 1.1.1 - dev: true /leven/3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} @@ -4186,7 +4136,6 @@ packages: object.map: 1.0.1 rechoir: 0.6.2 resolve: 1.22.0 - dev: true /lines-and-columns/1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -4201,7 +4150,6 @@ packages: pify: 2.3.0 pinkie-promise: 2.0.1 strip-bom: 2.0.0 - dev: true /locate-path/5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} @@ -4264,7 +4212,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: kind-of: 6.0.3 - dev: true /makeerror/1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} @@ -4275,14 +4222,12 @@ packages: /map-cache/0.2.2: resolution: {integrity: sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=} engines: {node: '>=0.10.0'} - dev: true /map-visit/1.0.0: resolution: {integrity: sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=} engines: {node: '>=0.10.0'} dependencies: object-visit: 1.0.1 - dev: true /matchdep/2.0.0: resolution: {integrity: sha1-xvNINKDY28OzfCfui7yyfHd1WC4=} @@ -4292,7 +4237,6 @@ packages: micromatch: 3.1.10 resolve: 1.22.0 stack-trace: 0.0.10 - dev: true /merge-source-map/1.1.0: resolution: {integrity: sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==} @@ -4321,7 +4265,6 @@ packages: regex-not: 1.0.2 snapdragon: 0.8.2 to-regex: 3.0.2 - dev: true /micromatch/4.0.4: resolution: {integrity: sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==} @@ -4362,11 +4305,9 @@ packages: dependencies: for-in: 1.0.2 is-extendable: 1.0.1 - dev: true /ms/2.0.0: resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=} - dev: true /ms/2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} @@ -4374,7 +4315,11 @@ packages: /mute-stdout/1.0.1: resolution: {integrity: sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==} engines: {node: '>= 0.10'} - dev: true + + /nan/2.15.0: + resolution: {integrity: sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==} + requiresBuild: true + optional: true /nanomatch/1.2.13: resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} @@ -4391,7 +4336,6 @@ packages: regex-not: 1.0.2 snapdragon: 0.8.2 to-regex: 3.0.2 - dev: true /natural-compare/1.4.0: resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=} @@ -4399,7 +4343,6 @@ packages: /next-tick/1.0.0: resolution: {integrity: sha1-yobR/ogoFpsBICCOPchCS524NCw=} - dev: true /no-case/2.3.2: resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==} @@ -4421,14 +4364,12 @@ packages: resolve: 1.22.0 semver: 5.7.1 validate-npm-package-license: 3.0.4 - dev: true /normalize-path/2.1.1: resolution: {integrity: sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=} engines: {node: '>=0.10.0'} dependencies: remove-trailing-separator: 1.1.0 - dev: true /normalize-path/3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} @@ -4439,7 +4380,6 @@ packages: engines: {node: '>= 0.10'} dependencies: once: 1.4.0 - dev: true /npm-run-path/4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} @@ -4451,7 +4391,6 @@ packages: /number-is-nan/1.0.1: resolution: {integrity: sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=} engines: {node: '>=0.10.0'} - dev: true /nwsapi/2.2.0: resolution: {integrity: sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==} @@ -4464,19 +4403,16 @@ packages: copy-descriptor: 0.1.1 define-property: 0.2.5 kind-of: 3.2.2 - dev: true /object-keys/1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} - dev: true /object-visit/1.0.1: resolution: {integrity: sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=} engines: {node: '>=0.10.0'} dependencies: isobject: 3.0.1 - dev: true /object.assign/4.1.2: resolution: {integrity: sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==} @@ -4486,7 +4422,6 @@ packages: define-properties: 1.1.3 has-symbols: 1.0.2 object-keys: 1.1.1 - dev: true /object.defaults/1.1.0: resolution: {integrity: sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=} @@ -4496,7 +4431,6 @@ packages: array-slice: 1.1.0 for-own: 1.0.0 isobject: 3.0.1 - dev: true /object.map/1.0.1: resolution: {integrity: sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=} @@ -4504,14 +4438,12 @@ packages: dependencies: for-own: 1.0.0 make-iterator: 1.0.1 - dev: true /object.pick/1.3.0: resolution: {integrity: sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=} engines: {node: '>=0.10.0'} dependencies: isobject: 3.0.1 - dev: true /object.reduce/1.0.1: resolution: {integrity: sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=} @@ -4519,7 +4451,6 @@ packages: dependencies: for-own: 1.0.0 make-iterator: 1.0.1 - dev: true /once/1.4.0: resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} @@ -4548,14 +4479,12 @@ packages: resolution: {integrity: sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=} dependencies: readable-stream: 2.3.7 - dev: true /os-locale/1.4.0: resolution: {integrity: sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=} engines: {node: '>=0.10.0'} dependencies: lcid: 1.0.0 - dev: true /p-limit/2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} @@ -4589,14 +4518,12 @@ packages: is-absolute: 1.0.0 map-cache: 0.2.2 path-root: 0.1.1 - dev: true /parse-json/2.2.0: resolution: {integrity: sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=} engines: {node: '>=0.10.0'} dependencies: error-ex: 1.3.2 - dev: true /parse-json/5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} @@ -4611,12 +4538,10 @@ packages: /parse-node-version/1.0.1: resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} engines: {node: '>= 0.10'} - dev: true /parse-passwd/1.0.0: resolution: {integrity: sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=} engines: {node: '>=0.10.0'} - dev: true /parse5/6.0.1: resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} @@ -4625,18 +4550,15 @@ packages: /pascalcase/0.1.1: resolution: {integrity: sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=} engines: {node: '>=0.10.0'} - dev: true /path-dirname/1.0.2: resolution: {integrity: sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=} - dev: true /path-exists/2.1.0: resolution: {integrity: sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=} engines: {node: '>=0.10.0'} dependencies: pinkie-promise: 2.0.1 - dev: true /path-exists/4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} @@ -4654,19 +4576,16 @@ packages: /path-parse/1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true /path-root-regex/0.1.2: resolution: {integrity: sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=} engines: {node: '>=0.10.0'} - dev: true /path-root/0.1.1: resolution: {integrity: sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=} engines: {node: '>=0.10.0'} dependencies: path-root-regex: 0.1.2 - dev: true /path-type/1.1.0: resolution: {integrity: sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=} @@ -4675,7 +4594,6 @@ packages: graceful-fs: 4.2.9 pify: 2.3.0 pinkie-promise: 2.0.1 - dev: true /picocolors/1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} @@ -4687,7 +4605,6 @@ packages: /pify/2.3.0: resolution: {integrity: sha1-7RQaasBDqEnqWISY59yosVMw6Qw=} engines: {node: '>=0.10.0'} - dev: true /pify/4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} @@ -4699,12 +4616,10 @@ packages: engines: {node: '>=0.10.0'} dependencies: pinkie: 2.0.4 - dev: true /pinkie/2.0.4: resolution: {integrity: sha1-clVrgM+g1IqXToDnckjoDtT3+HA=} engines: {node: '>=0.10.0'} - dev: true /pirates/4.0.5: resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} @@ -4721,7 +4636,6 @@ packages: /posix-character-classes/0.1.1: resolution: {integrity: sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=} engines: {node: '>=0.10.0'} - dev: true /prelude-ls/1.1.2: resolution: {integrity: sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=} @@ -4739,11 +4653,9 @@ packages: /pretty-hrtime/1.0.3: resolution: {integrity: sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=} engines: {node: '>= 0.8'} - dev: true /process-nextick-args/2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - dev: true /prompts/2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} @@ -4762,7 +4674,6 @@ packages: dependencies: end-of-stream: 1.4.4 once: 1.4.0 - dev: true /pumpify/1.5.1: resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} @@ -4770,13 +4681,18 @@ packages: duplexify: 3.7.1 inherits: 2.0.4 pump: 2.0.1 - dev: true /punycode/2.1.1: resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} engines: {node: '>=6'} dev: true + /randombytes/2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + /react-is/17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} dev: true @@ -4787,7 +4703,6 @@ packages: dependencies: find-up: 1.1.2 read-pkg: 1.1.0 - dev: true /read-pkg/1.1.0: resolution: {integrity: sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=} @@ -4796,7 +4711,6 @@ packages: load-json-file: 1.1.0 normalize-package-data: 2.5.0 path-type: 1.1.0 - dev: true /readable-stream/2.3.7: resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} @@ -4808,7 +4722,6 @@ packages: safe-buffer: 5.1.2 string_decoder: 1.1.1 util-deprecate: 1.0.2 - dev: true /readable-stream/3.6.0: resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} @@ -4826,7 +4739,6 @@ packages: graceful-fs: 4.2.9 micromatch: 3.1.10 readable-stream: 2.3.7 - dev: true /readdirp/3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} @@ -4849,7 +4761,6 @@ packages: engines: {node: '>= 0.10'} dependencies: resolve: 1.22.0 - dev: true /regenerate-unicode-properties/10.0.1: resolution: {integrity: sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==} @@ -4878,7 +4789,6 @@ packages: dependencies: extend-shallow: 3.0.2 safe-regex: 1.1.0 - dev: true /regexpu-core/5.0.1: resolution: {integrity: sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw==} @@ -4914,7 +4824,6 @@ packages: dependencies: is-buffer: 1.1.6 is-utf8: 0.2.1 - dev: true /remove-bom-stream/1.2.0: resolution: {integrity: sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=} @@ -4923,26 +4832,21 @@ packages: remove-bom-buffer: 3.0.0 safe-buffer: 5.2.1 through2: 2.0.5 - dev: true /remove-trailing-separator/1.1.0: resolution: {integrity: sha1-wkvOKig62tW8P1jg1IJJuSN52O8=} - dev: true /repeat-element/1.1.4: resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} engines: {node: '>=0.10.0'} - dev: true /repeat-string/1.6.1: resolution: {integrity: sha1-jcrkcOHIirwtYA//Sndihtp15jc=} engines: {node: '>=0.10'} - dev: true /replace-ext/1.0.1: resolution: {integrity: sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==} engines: {node: '>= 0.10'} - dev: true /replace-homedir/1.0.0: resolution: {integrity: sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=} @@ -4951,16 +4855,13 @@ packages: homedir-polyfill: 1.0.3 is-absolute: 1.0.0 remove-trailing-separator: 1.1.0 - dev: true /require-directory/2.1.1: resolution: {integrity: sha1-jGStX9MNqxyXbiNE/+f3kqam30I=} engines: {node: '>=0.10.0'} - dev: true /require-main-filename/1.0.1: resolution: {integrity: sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=} - dev: true /resolve-cwd/3.0.0: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} @@ -4975,7 +4876,6 @@ packages: dependencies: expand-tilde: 2.0.2 global-modules: 1.0.0 - dev: true /resolve-from/5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} @@ -4987,12 +4887,10 @@ packages: engines: {node: '>= 0.10'} dependencies: value-or-function: 3.0.0 - dev: true /resolve-url/0.2.1: resolution: {integrity: sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=} deprecated: https://github.com/lydell/resolve-url#deprecated - dev: true /resolve.exports/1.1.0: resolution: {integrity: sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==} @@ -5006,12 +4904,10 @@ packages: is-core-module: 2.8.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - dev: true /ret/0.1.15: resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} engines: {node: '>=0.12'} - dev: true /rimraf/2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} @@ -5033,16 +4929,16 @@ packages: rimraf: 2.7.1 dev: true - /rollup-plugin-uglify/6.0.4_rollup@2.69.0: - resolution: {integrity: sha512-ddgqkH02klveu34TF0JqygPwZnsbhHVI6t8+hGTcYHngPkQb5MIHI0XiztXIN/d6V9j+efwHAqEL7LspSxQXGw==} + /rollup-plugin-terser/7.0.2_rollup@2.69.0: + resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} peerDependencies: - rollup: '>=0.66.0 <2' + rollup: ^2.0.0 dependencies: '@babel/code-frame': 7.16.7 - jest-worker: 24.9.0 + jest-worker: 26.6.2 rollup: 2.69.0 - serialize-javascript: 2.1.2 - uglify-js: 3.4.10 + serialize-javascript: 4.0.0 + terser: 5.12.0 dev: true /rollup/2.69.0: @@ -5050,7 +4946,7 @@ packages: engines: {node: '>=10.0.0'} hasBin: true optionalDependencies: - fsevents: registry.npmmirror.com/fsevents/2.3.2 + fsevents: 2.3.2 dev: true /safe-buffer/5.1.2: @@ -5058,13 +4954,11 @@ packages: /safe-buffer/5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: true /safe-regex/1.1.0: resolution: {integrity: sha1-QKNmnzsHfR6UPURinhV91IAjvy4=} dependencies: ret: 0.1.15 - dev: true /safer-buffer/2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -5082,7 +4976,6 @@ packages: engines: {node: '>= 0.10'} dependencies: sver-compat: 1.5.0 - dev: true /semver/5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} @@ -5105,13 +4998,14 @@ packages: lru-cache: 6.0.0 dev: true - /serialize-javascript/2.1.2: - resolution: {integrity: sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==} + /serialize-javascript/4.0.0: + resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==} + dependencies: + randombytes: 2.1.0 dev: true /set-blocking/2.0.0: resolution: {integrity: sha1-BF+XgtARrppoA93TgrJDkrPYkPc=} - dev: true /set-value/2.0.1: resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} @@ -5121,7 +5015,6 @@ packages: is-extendable: 0.1.1 is-plain-object: 2.0.4 split-string: 3.1.0 - dev: true /shebang-command/2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} @@ -5160,14 +5053,12 @@ packages: define-property: 1.0.0 isobject: 3.0.1 snapdragon-util: 3.0.1 - dev: true /snapdragon-util/3.0.1: resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} engines: {node: '>=0.10.0'} dependencies: kind-of: 3.2.2 - dev: true /snapdragon/0.8.2: resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} @@ -5181,7 +5072,6 @@ packages: source-map: 0.5.7 source-map-resolve: 0.5.3 use: 3.1.1 - dev: true /source-map-resolve/0.5.3: resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} @@ -5192,7 +5082,6 @@ packages: resolve-url: 0.2.1 source-map-url: 0.4.1 urix: 0.1.0 - dev: true /source-map-support/0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} @@ -5204,7 +5093,6 @@ packages: /source-map-url/0.4.1: resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} deprecated: See https://github.com/lydell/source-map-url#deprecated - dev: true /source-map/0.5.7: resolution: {integrity: sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=} @@ -5226,36 +5114,30 @@ packages: /sparkles/1.0.1: resolution: {integrity: sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==} engines: {node: '>= 0.10'} - dev: true /spdx-correct/3.1.1: resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} dependencies: spdx-expression-parse: 3.0.1 spdx-license-ids: 3.0.11 - dev: true /spdx-exceptions/2.3.0: resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} - dev: true /spdx-expression-parse/3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} dependencies: spdx-exceptions: 2.3.0 spdx-license-ids: 3.0.11 - dev: true /spdx-license-ids/3.0.11: resolution: {integrity: sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==} - dev: true /split-string/3.1.0: resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} engines: {node: '>=0.10.0'} dependencies: extend-shallow: 3.0.2 - dev: true /sprintf-js/1.0.3: resolution: {integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=} @@ -5263,7 +5145,6 @@ packages: /stack-trace/0.0.10: resolution: {integrity: sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=} - dev: true /stack-utils/2.0.5: resolution: {integrity: sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==} @@ -5278,15 +5159,12 @@ packages: dependencies: define-property: 0.2.5 object-copy: 0.1.0 - dev: true /stream-exhaust/1.0.2: resolution: {integrity: sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==} - dev: true /stream-shift/1.0.1: resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} - dev: true /string-length/4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} @@ -5303,7 +5181,6 @@ packages: code-point-at: 1.1.0 is-fullwidth-code-point: 1.0.0 strip-ansi: 3.0.1 - dev: true /string-width/4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} @@ -5324,7 +5201,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: ansi-regex: 2.1.1 - dev: true /strip-ansi/6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} @@ -5338,7 +5214,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: is-utf8: 0.2.1 - dev: true /strip-bom/4.0.0: resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} @@ -5361,13 +5236,6 @@ packages: dependencies: has-flag: 3.0.0 - /supports-color/6.1.0: - resolution: {integrity: sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==} - engines: {node: '>=6'} - dependencies: - has-flag: 3.0.0 - dev: true - /supports-color/7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -5393,14 +5261,12 @@ packages: /supports-preserve-symlinks-flag/1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - dev: true /sver-compat/1.5.0: resolution: {integrity: sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=} dependencies: es6-iterator: 2.0.3 es6-symbol: 3.1.3 - dev: true /symbol-tree/3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} @@ -5414,6 +5280,17 @@ packages: supports-hyperlinks: 2.2.0 dev: true + /terser/5.12.0: + resolution: {integrity: sha512-R3AUhNBGWiFc77HXag+1fXpAxTAFRQTJemlJKjAgD9r8xXTpjNKqIXwHM/o7Rh+O0kUJtS3WQVdBeMKFk5sw9A==} + engines: {node: '>=10'} + hasBin: true + dependencies: + acorn: 8.7.0 + commander: 2.20.3 + source-map: 0.7.3 + source-map-support: 0.5.21 + dev: true + /test-exclude/6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} @@ -5432,14 +5309,12 @@ packages: dependencies: through2: 2.0.5 xtend: 4.0.2 - dev: true /through2/2.0.5: resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} dependencies: readable-stream: 2.3.7 xtend: 4.0.2 - dev: true /through2/4.0.2: resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} @@ -5450,7 +5325,6 @@ packages: /time-stamp/1.1.0: resolution: {integrity: sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=} engines: {node: '>=0.10.0'} - dev: true /tmpl/1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} @@ -5462,7 +5336,6 @@ packages: dependencies: is-absolute: 1.0.0 is-negated-glob: 1.0.0 - dev: true /to-fast-properties/2.0.0: resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=} @@ -5473,7 +5346,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: kind-of: 3.2.2 - dev: true /to-regex-range/2.1.1: resolution: {integrity: sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=} @@ -5481,7 +5353,6 @@ packages: dependencies: is-number: 3.0.0 repeat-string: 1.6.1 - dev: true /to-regex-range/5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} @@ -5497,14 +5368,12 @@ packages: extend-shallow: 3.0.2 regex-not: 1.0.2 safe-regex: 1.1.0 - dev: true /to-through/2.0.0: resolution: {integrity: sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=} engines: {node: '>= 0.10'} dependencies: through2: 2.0.5 - dev: true /tough-cookie/4.0.0: resolution: {integrity: sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==} @@ -5545,11 +5414,9 @@ packages: /type/1.2.0: resolution: {integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==} - dev: true /type/2.6.0: resolution: {integrity: sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==} - dev: true /typedarray-to-buffer/3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} @@ -5559,7 +5426,6 @@ packages: /typedarray/0.0.6: resolution: {integrity: sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=} - dev: true /uglify-js/3.4.10: resolution: {integrity: sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==} @@ -5567,17 +5433,16 @@ packages: hasBin: true dependencies: commander: 2.19.0 - source-map: registry.npmmirror.com/source-map/0.6.1 + source-map: 0.6.1 + dev: false /unc-path-regex/0.1.2: resolution: {integrity: sha1-5z3T17DXxe2G+6xrCufYxqadUPo=} engines: {node: '>=0.10.0'} - dev: true /undertaker-registry/1.0.1: resolution: {integrity: sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=} engines: {node: '>= 0.10'} - dev: true /undertaker/1.3.0: resolution: {integrity: sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==} @@ -5593,7 +5458,6 @@ packages: object.defaults: 1.1.0 object.reduce: 1.0.1 undertaker-registry: 1.0.1 - dev: true /unicode-canonical-property-names-ecmascript/2.0.0: resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} @@ -5626,14 +5490,12 @@ packages: get-value: 2.0.6 is-extendable: 0.1.1 set-value: 2.0.1 - dev: true /unique-stream/2.3.1: resolution: {integrity: sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==} dependencies: json-stable-stringify-without-jsonify: 1.0.1 through2-filter: 3.0.0 - dev: true /universalify/0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} @@ -5646,12 +5508,10 @@ packages: dependencies: has-value: 0.3.1 isobject: 3.0.1 - dev: true /upath/1.2.0: resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} engines: {node: '>=4'} - dev: true /upper-case/1.1.3: resolution: {integrity: sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=} @@ -5660,12 +5520,10 @@ packages: /urix/0.1.0: resolution: {integrity: sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=} deprecated: Please see https://github.com/lydell/urix#deprecated - dev: true /use/3.1.1: resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} engines: {node: '>=0.10.0'} - dev: true /util-deprecate/1.0.2: resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=} @@ -5684,19 +5542,16 @@ packages: engines: {node: '>= 0.10'} dependencies: homedir-polyfill: 1.0.3 - dev: true /validate-npm-package-license/3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: spdx-correct: 3.1.1 spdx-expression-parse: 3.0.1 - dev: true /value-or-function/3.0.0: resolution: {integrity: sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=} engines: {node: '>= 0.10'} - dev: true /vinyl-fs/3.0.3: resolution: {integrity: sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==} @@ -5719,7 +5574,6 @@ packages: value-or-function: 3.0.0 vinyl: 2.2.1 vinyl-sourcemap: 1.1.0 - dev: true /vinyl-sourcemap/1.1.0: resolution: {integrity: sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=} @@ -5732,7 +5586,6 @@ packages: now-and-later: 2.0.1 remove-bom-buffer: 3.0.0 vinyl: 2.2.1 - dev: true /vinyl/2.2.1: resolution: {integrity: sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==} @@ -5744,7 +5597,6 @@ packages: cloneable-readable: 1.1.3 remove-trailing-separator: 1.1.0 replace-ext: 1.0.1 - dev: true /w3c-hr-time/1.0.2: resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} @@ -5796,14 +5648,12 @@ packages: /which-module/1.0.0: resolution: {integrity: sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=} - dev: true /which/1.3.1: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} hasBin: true dependencies: isexe: 2.0.0 - dev: true /which/2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} @@ -5823,7 +5673,6 @@ packages: dependencies: string-width: 1.0.2 strip-ansi: 3.0.1 - dev: true /wrap-ansi/7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} @@ -5870,11 +5719,9 @@ packages: /xtend/4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} - dev: true /y18n/3.2.2: resolution: {integrity: sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==} - dev: true /y18n/5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} @@ -5895,7 +5742,6 @@ packages: dependencies: camelcase: 3.0.0 object.assign: 4.1.2 - dev: true /yargs/16.2.0: resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} @@ -5926,7 +5772,6 @@ packages: which-module: 1.0.0 y18n: 3.2.2 yargs-parser: 5.0.1 - dev: true registry.npmmirror.com/@babel/runtime-corejs3/7.17.2: resolution: {integrity: sha512-NcKtr2epxfIrNM4VOmPKO46TvDMCBhgi2CrSHaEarrz+Plk2K5r9QemmOFTGpZaoKnWoGH5MO+CzeRsih/Fcgg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/runtime-corejs3/-/runtime-corejs3-7.17.2.tgz} @@ -5938,49 +5783,12 @@ packages: regenerator-runtime: registry.npmmirror.com/regenerator-runtime/0.13.9 dev: false - registry.npmmirror.com/@nicolo-ribaudo/chokidar-2/2.1.8-no-fsevents.3: - resolution: {integrity: sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz} - name: '@nicolo-ribaudo/chokidar-2' - version: 2.1.8-no-fsevents.3 - requiresBuild: true - dev: false - optional: true - registry.npmmirror.com/ansicolor/1.1.100: resolution: {integrity: sha512-Jl0pxRfa9WaQVUX57AB8/V2my6FJxrOR1Pp2qqFbig20QB4HzUoQ48THTKAgHlUCJeQm/s2WoOPcoIDhyCL/kw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ansicolor/-/ansicolor-1.1.100.tgz} name: ansicolor version: 1.1.100 dev: false - registry.npmmirror.com/bindings/1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/bindings/-/bindings-1.5.0.tgz} - name: bindings - version: 1.5.0 - requiresBuild: true - dependencies: - file-uri-to-path: registry.npmmirror.com/file-uri-to-path/1.0.0 - dev: true - optional: true - - registry.npmmirror.com/chokidar/3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz} - name: chokidar - version: 3.5.3 - engines: {node: '>= 8.10.0'} - requiresBuild: true - dependencies: - anymatch: 3.1.2 - braces: 3.0.2 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: registry.npmmirror.com/fsevents/2.3.2 - dev: false - optional: true - registry.npmmirror.com/core-js-pure/3.21.1: resolution: {integrity: sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.21.1.tgz} name: core-js-pure @@ -5995,53 +5803,8 @@ packages: requiresBuild: true dev: false - registry.npmmirror.com/file-uri-to-path/1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz} - name: file-uri-to-path - version: 1.0.0 - requiresBuild: true - dev: true - optional: true - - registry.npmmirror.com/fsevents/1.2.13: - resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fsevents/-/fsevents-1.2.13.tgz} - name: fsevents - version: 1.2.13 - engines: {node: '>= 4.0'} - os: [darwin] - deprecated: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2. - requiresBuild: true - dependencies: - bindings: registry.npmmirror.com/bindings/1.5.0 - nan: registry.npmmirror.com/nan/2.15.0 - dev: true - optional: true - - registry.npmmirror.com/fsevents/2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz} - name: fsevents - version: 2.3.2 - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - optional: true - - registry.npmmirror.com/nan/2.15.0: - resolution: {integrity: sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/nan/-/nan-2.15.0.tgz} - name: nan - version: 2.15.0 - requiresBuild: true - dev: true - optional: true - registry.npmmirror.com/regenerator-runtime/0.13.9: resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz} name: regenerator-runtime version: 0.13.9 dev: false - - registry.npmmirror.com/source-map/0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz} - name: source-map - version: 0.6.1 - engines: {node: '>=0.10.0'}