├── .gitignore ├── commit-lint ├── config │ ├── czrc.json │ └── package.json └── custom-config │ ├── cz-config.js │ ├── czrc.json │ └── package.json ├── data-base ├── package.json └── src │ ├── app.config.js │ ├── database │ └── index.js │ ├── index.js │ ├── models │ ├── index.js │ └── product.js │ ├── routes │ ├── index.js │ └── product │ │ ├── create.js │ │ ├── delete.js │ │ ├── readed.js │ │ └── update.js │ └── utils │ └── setting.js ├── doc-site ├── .umirc.ts ├── docs │ └── index.md └── package.json ├── js-lib ├── bruce-us │ ├── .gitignore │ ├── .npmignore │ ├── dist │ │ ├── index.d.ts │ │ ├── node.esm.js │ │ ├── node.js │ │ ├── web.esm.js │ │ ├── web.js │ │ └── web.umd.js │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── common │ │ │ ├── array.ts │ │ │ ├── boolean.ts │ │ │ ├── date.ts │ │ │ ├── function.ts │ │ │ ├── index.ts │ │ │ ├── number.ts │ │ │ ├── object.ts │ │ │ ├── regexp.ts │ │ │ └── string.ts │ │ ├── index.ts │ │ ├── node.ts │ │ ├── node │ │ │ ├── fs.ts │ │ │ ├── index.ts │ │ │ ├── os.ts │ │ │ ├── process.ts │ │ │ └── type.ts │ │ ├── web.ts │ │ ├── web.umd.ts │ │ └── web │ │ │ ├── cookie.ts │ │ │ ├── dom.ts │ │ │ ├── function.ts │ │ │ ├── index.ts │ │ │ ├── storage.ts │ │ │ ├── type.ts │ │ │ └── url.ts │ └── tsconfig.json ├── rollup │ ├── dist │ │ └── index.bundle.js │ ├── package.json │ ├── rollup.config.js │ └── src │ │ ├── a.js │ │ ├── b.js │ │ └── index.js └── webpack │ ├── dist │ └── index.bundle.js │ ├── package.json │ ├── src │ ├── a.js │ ├── b.js │ └── index.js │ └── webpack.config.js └── node-esm ├── for-babel ├── package.json └── src │ └── index.js ├── for-node ├── package.json └── src │ └── index.js └── for-nodemon ├── package.json └── src └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .umi 3 | node_modules 4 | package-lock.json 5 | yarn.lock -------------------------------------------------------------------------------- /commit-lint/config/czrc.json: -------------------------------------------------------------------------------- 1 | { "path": "cz-conventional-changelog" } -------------------------------------------------------------------------------- /commit-lint/config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "commit-lint", 3 | "version": "1.0.0", 4 | "script": { 5 | "commit": "git-cz" 6 | }, 7 | "config": { 8 | "commitizen": { 9 | "path": "node_modules/cz-conventional-changelog" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /commit-lint/custom-config/cz-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | allowBreakingChanges: ["feat", "fix"], 3 | allowCustomScopes: true, 4 | scopes: [], 5 | types: [{ 6 | name: "功能:新增功能,迭代项目需求 (feat)", 7 | value: "feat" 8 | }, { 9 | name: "修复:修复缺陷,修复上一版本存在问题 (fix)", 10 | value: "fix" 11 | }, { 12 | name: "文档:更新文档,仅改动文档不改动代码 (docs)", 13 | value: "docs" 14 | }, { 15 | name: "样式:变动格式,不影响代码逻辑 (style)", 16 | value: "style" 17 | }, { 18 | name: "重构:重构代码,非新增功能也非修改缺陷 (refactor)", 19 | value: "refactor" 20 | }, { 21 | name: "性能:优化性能,提高代码执行性能 (perf)", 22 | value: "perf" 23 | }, { 24 | name: "测试:新增测试,追加测试用例验证代码 (test)", 25 | value: "test" 26 | }, { 27 | name: "构建:更新构建,改动构建工具或外部依赖 (build)", 28 | value: "build" 29 | }, { 30 | name: "脚本:更新脚本,改动CI或执行脚本配置 (ci)", 31 | value: "ci" 32 | }, { 33 | name: "事务:变动事务,改动其他不影响代码的事务 (chore)", 34 | value: "chore" 35 | }, { 36 | name: "回滚:回滚版本,撤销某次代码提交 (revert)", 37 | value: "revert" 38 | }, { 39 | name: "合并:合并分支,合并分支代码到其他分支 (merge)", 40 | value: "merge" 41 | }, { 42 | name: "同步:同步分支,同步分支代码到其他分支 (sync)", 43 | value: "sync" 44 | }, { 45 | name: "改进:改进功能,升级当前功能模块 (impr)", 46 | value: "impr" 47 | }] 48 | }; -------------------------------------------------------------------------------- /commit-lint/custom-config/czrc.json: -------------------------------------------------------------------------------- 1 | { "path": "cz-customizable" } -------------------------------------------------------------------------------- /commit-lint/custom-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "commit-lint", 3 | "version": "1.0.0", 4 | "script": { 5 | "commit": "git-cz" 6 | }, 7 | "config": { 8 | "commitizen": { 9 | "path": "node_modules/cz-customizable" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /data-base/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "data-base", 3 | "version": "1.0.0", 4 | "main": "src/index.js", 5 | "type": "module", 6 | "scripts": { 7 | "clean": "rimraf coverage dist node_modules package-lock.json yarn.lock", 8 | "deploy": "cross-env NODE_ENV=prod node --es-module-specifier-resolution=node src/index.js", 9 | "start": "cross-env NODE_ENV=dev nodemon --es-module-specifier-resolution=node src/index.js" 10 | }, 11 | "engines": { 12 | "node": ">=13.2.0", 13 | "npm": ">=6.13.1" 14 | }, 15 | "dependencies": { 16 | "@yangzw/bruce-us": "1.0.2", 17 | "cross-env": "7.0.3", 18 | "dayjs": "1.11.2", 19 | "koa": "2.13.4", 20 | "koa-body": "5.0.0", 21 | "koa-json": "2.0.2", 22 | "koa-logger": "3.2.1", 23 | "koa-onerror": "4.2.0", 24 | "koa-router": "10.1.1", 25 | "koa2-cors": "2.0.6", 26 | "mongoose": "6.3.3" 27 | }, 28 | "devDependencies": { 29 | "nodemon": "2.0.16" 30 | }, 31 | "nodemonConfig": { 32 | "execMap": { 33 | "js": "node --harmony" 34 | }, 35 | "ext": "js json", 36 | "ignore": [ 37 | "dist/" 38 | ], 39 | "watch": [ 40 | "src/" 41 | ] 42 | } 43 | } -------------------------------------------------------------------------------- /data-base/src/app.config.js: -------------------------------------------------------------------------------- 1 | import { env } from "process"; 2 | 3 | export default { 4 | mongodb: { 5 | host: env.NODE_ENV === "dev" ? "your server host" : "127.0.0.1", 6 | password: "123456", 7 | port: 27017, 8 | username: "root" 9 | }, 10 | publicPath: env.NODE_ENV === "dev" ? "" : "/mall" 11 | }; -------------------------------------------------------------------------------- /data-base/src/database/index.js: -------------------------------------------------------------------------------- 1 | import Mongoose from "mongoose"; 2 | 3 | import AppConfig from "../app.config"; 4 | 5 | const { connect, connection } = Mongoose; 6 | const { mongodb: { host, password, port, username } } = AppConfig; 7 | 8 | connect(`mongodb://${username}:${password}@${host}:${port}/mall`, { 9 | authSource: "admin", 10 | useNewUrlParser: true, 11 | useUnifiedTopology: true 12 | }); 13 | connection.on("connected", () => console.log("数据库连接成功")); 14 | connection.on("disconnected", () => console.log("数据库连接断开")); 15 | connection.on("error", () => console.log("数据库连接异常")); -------------------------------------------------------------------------------- /data-base/src/index.js: -------------------------------------------------------------------------------- 1 | import Koa from "koa"; 2 | import KoaBody from "koa-body"; 3 | import KoaJson from "koa-json"; 4 | import KoaLogger from "koa-logger"; 5 | import KoaOnerror from "koa-onerror"; 6 | 7 | import "./database"; 8 | import Router from "./routes"; 9 | 10 | // 创建实例 11 | const app = new Koa(); 12 | KoaOnerror(app); // 美化错误参数 13 | app.on("error", (err, ctx) => console.error("server error", err, ctx)); // 捕获错误 14 | 15 | // 配置中间件 16 | app.use(KoaLogger()); // 日志解析 17 | app.use(KoaBody({ multipart: true })); // Body解析 18 | app.use(KoaJson()); // JSON解析 19 | 20 | // 匹配路由 21 | Object.values(Router).forEach(v => app.use(v.routes(), v.allowedMethods())); 22 | 23 | // 监听服务 24 | app.listen(3000); 25 | console.log("Node服务已启动,监听端口3000"); -------------------------------------------------------------------------------- /data-base/src/models/index.js: -------------------------------------------------------------------------------- 1 | import Mongoose from "mongoose"; 2 | 3 | import Product from "./product"; 4 | 5 | const { model, Schema } = Mongoose; 6 | 7 | const ProductModel = model("product", new Schema(Product, { versionKey: false })); 8 | 9 | export { 10 | Product, 11 | ProductModel 12 | }; -------------------------------------------------------------------------------- /data-base/src/models/product.js: -------------------------------------------------------------------------------- 1 | import Day from "dayjs"; 2 | 3 | export default { 4 | brand: { 5 | match: /^.{2,200}$/, 6 | msg: "品牌只能由2到200位任意字符组成", 7 | required: true, 8 | trim: true, 9 | type: String 10 | }, 11 | code: { 12 | match: /^[A-Za-z0-9]{4,30}$/, 13 | msg: "条形码只能由4到30位英文或数字组成", 14 | required: true, 15 | trim: true, 16 | type: String 17 | }, 18 | createtime: { 19 | default: Day().format("YYYY-MM-DD HH:mm:ss"), 20 | match: /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/, 21 | msg: "创建日期由系统自动生成", 22 | required: true, 23 | trim: true, 24 | type: String 25 | }, 26 | description: { 27 | match: /^.{2,500}$/, 28 | msg: "描述只能由2到500位任意字符组成", 29 | required: true, 30 | trim: true, 31 | type: String 32 | }, 33 | name: { 34 | match: /^[\u4e00-\u9fa5A-Za-z\d-\s]{2,200}$/, 35 | msg: "名称只能由2到200位中文、英文、数字、中划线或空格组成", 36 | required: true, 37 | trim: true, 38 | type: String 39 | }, 40 | origin: { 41 | match: /^[\u4e00-\u9fa5A-Za-z\d-]{2,100}$/, 42 | msg: "产地只能由2到100位中文、英文、数字或中划线组成", 43 | required: true, 44 | trim: true, 45 | type: String 46 | } 47 | }; -------------------------------------------------------------------------------- /data-base/src/routes/index.js: -------------------------------------------------------------------------------- 1 | import CreateProduct from "./product/create"; 2 | import DeleteProduct from "./product/delete"; 3 | import ReadedProduct from "./product/readed"; 4 | import UpdateProduct from "./product/update"; 5 | 6 | export default { 7 | CreateProduct, 8 | DeleteProduct, 9 | ReadedProduct, 10 | UpdateProduct 11 | }; -------------------------------------------------------------------------------- /data-base/src/routes/product/create.js: -------------------------------------------------------------------------------- 1 | import KoaRouter from "koa-router"; 2 | import { AsyncTo } from "@yangzw/bruce-us/dist/node"; 3 | 4 | import { Product, ProductModel } from "../../models"; 5 | import { CheckData } from "../../utils/setting"; 6 | import AppConfig from "../../app.config"; 7 | 8 | const Router = KoaRouter(); 9 | 10 | Router.post(`${AppConfig.publicPath}/product/create`, async ctx => { 11 | const params = ctx.request.body; 12 | // 校验全部字段是否为空 13 | if (!CheckData(params, 5)) { 14 | ctx.body = { code: 300, msg: "产品信息都不能为空" }; 15 | return false; 16 | } 17 | // 校验全部字段是否符合正则 18 | const checkMsg = Object.entries(params).reduce((t, v) => { 19 | const { match, msg } = Product[v[0]]; 20 | return !t && !match.test(v[1]) ? { code: 400, msg } : t; 21 | }, ""); 22 | if (checkMsg) { 23 | ctx.body = checkMsg; 24 | return false; 25 | } 26 | // 判断产品是否存在 27 | const [err1, res1] = await AsyncTo(ProductModel.findOne({ code: params.code })); 28 | if (err1) { 29 | ctx.body = { code: 400, msg: "新增产品失败" }; 30 | return false; 31 | } 32 | if (res1) { 33 | ctx.body = { code: 400, msg: "当前产品已存在" }; 34 | return false; 35 | } 36 | // 新增产品 37 | const [err2, res2] = await AsyncTo(ProductModel.create(params)); 38 | if (!err2 && res2) { 39 | ctx.body = { code: 200, data: res2, msg: "新增产品成功" }; 40 | } else { 41 | ctx.body = { code: 400, msg: "新增产品失败" }; 42 | } 43 | }); 44 | 45 | export default Router; -------------------------------------------------------------------------------- /data-base/src/routes/product/delete.js: -------------------------------------------------------------------------------- 1 | import KoaRouter from "koa-router"; 2 | import { AsyncTo } from "@yangzw/bruce-us/dist/node"; 3 | 4 | import { ProductModel } from "../../models"; 5 | import AppConfig from "../../app.config"; 6 | 7 | const Router = KoaRouter(); 8 | 9 | Router.post(`${AppConfig.publicPath}/product/delete`, async ctx => { 10 | const { id } = ctx.request.body; 11 | // 校验全部字段是否为空 12 | if (!id) { 13 | ctx.body = { code: 400, msg: "产品ID不能为空" }; 14 | return false; 15 | } 16 | // 删除产品 17 | const [err, res] = await AsyncTo(ProductModel.findByIdAndDelete(id)); 18 | if (!err && res) { 19 | ctx.body = { code: 200, data: res, msg: "删除产品成功" }; 20 | } else { 21 | ctx.body = { code: 400, msg: "删除产品失败" }; 22 | } 23 | }); 24 | 25 | export default Router; -------------------------------------------------------------------------------- /data-base/src/routes/product/readed.js: -------------------------------------------------------------------------------- 1 | import KoaRouter from "koa-router"; 2 | import { AsyncTo } from "@yangzw/bruce-us/dist/node"; 3 | 4 | import { ProductModel } from "../../models"; 5 | import AppConfig from "../../app.config"; 6 | 7 | const Router = KoaRouter(); 8 | 9 | Router.get(`${AppConfig.publicPath}/product/readed`, async ctx => { 10 | const { id } = ctx.request.query; 11 | // 校验全部字段是否为空 12 | if (!id) { 13 | ctx.body = { code: 400, msg: "产品ID不能为空" }; 14 | return false; 15 | } 16 | // 读取产品 17 | const [err, res] = await AsyncTo(ProductModel.findById(id)); 18 | if (!err && res) { 19 | ctx.body = { code: 200, data: res, msg: "读取产品成功" }; 20 | } else { 21 | ctx.body = { code: 400, msg: "读取产品失败" }; 22 | } 23 | }); 24 | 25 | export default Router; -------------------------------------------------------------------------------- /data-base/src/routes/product/update.js: -------------------------------------------------------------------------------- 1 | import KoaRouter from "koa-router"; 2 | import { AsyncTo } from "@yangzw/bruce-us/dist/node"; 3 | 4 | import { Product, ProductModel } from "../../models"; 5 | import { CheckData } from "../../utils/setting"; 6 | import AppConfig from "../../app.config"; 7 | 8 | const Router = KoaRouter(); 9 | 10 | Router.post(`${AppConfig.publicPath}/product/update`, async ctx => { 11 | const { id, ...params } = ctx.request.body; 12 | // 校验全部字段是否为空 13 | if (!id) { 14 | ctx.body = { code: 400, msg: "产品ID不能为空" }; 15 | return false; 16 | } 17 | if (!CheckData(params, 1)) { 18 | ctx.body = { code: 400, msg: "产品信息不能为空" }; 19 | return false; 20 | } 21 | // 校验全部字段是否符合正则 22 | const checkMsg = Object.entries(params).reduce((t, v) => { 23 | const { match, msg } = Product[v[0]]; 24 | return !t && !match.test(v[1]) ? { code: 400, msg } : t; 25 | }, ""); 26 | if (checkMsg) { 27 | ctx.body = checkMsg; 28 | return false; 29 | } 30 | // 判断产品是否存在 31 | const [err1, res1] = await AsyncTo(ProductModel.findById(id)); 32 | if (err1 || !res1) { 33 | ctx.body = { code: 400, msg: "当前产品不已存在" }; 34 | return false; 35 | } 36 | // 更新产品 37 | const [err2, res2] = await AsyncTo(ProductModel.findByIdAndUpdate(id, params)); 38 | console.log(res2); 39 | if (!err2 && res2) { 40 | ctx.body = { code: 200, data: { ...res2.toObject(), ...params }, msg: "更新产品成功" }; 41 | } else { 42 | ctx.body = { code: 400, msg: "更新产品失败" }; 43 | } 44 | }); 45 | 46 | export default Router; -------------------------------------------------------------------------------- /data-base/src/utils/setting.js: -------------------------------------------------------------------------------- 1 | import { IsEmptyObject } from "@yangzw/bruce-us/dist/node"; 2 | 3 | function CheckData(obj, len = 0) { 4 | return IsEmptyObject(obj) ? false : Object.values(obj).filter(Boolean).length >= len; 5 | } 6 | 7 | export { 8 | CheckData 9 | }; -------------------------------------------------------------------------------- /doc-site/.umirc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "dumi"; 2 | 3 | const logo = "data:image/png;base64,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"; 4 | 5 | export default defineConfig({ 6 | favicon: logo, 7 | logo, 8 | mode: "site", 9 | title: "Bruce FEES" 10 | }); -------------------------------------------------------------------------------- /doc-site/docs/index.md: -------------------------------------------------------------------------------- 1 | ### Bruce FEES 2 | 3 | **Bruce FEES**是一套多功能**前端工程化多包管理**实践方案,包括多个前端开发流程中常用的`脚手架`、`工具`和`类库`,其目的是简化整个开发流程,对那些重复繁琐的流程使用工具自动化完成,以提升整体的开发效率。 -------------------------------------------------------------------------------- /doc-site/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "doc-site", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "deploy": "dumi build", 6 | "docs": "dumi dev" 7 | }, 8 | "dependencies": { 9 | "dumi": "1.1.40", 10 | "dumi-theme-mobile": "1.1.22" 11 | } 12 | } -------------------------------------------------------------------------------- /js-lib/bruce-us/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | package-lock.json 4 | yarn.lock -------------------------------------------------------------------------------- /js-lib/bruce-us/.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | package-lock.json 4 | yarn.lock -------------------------------------------------------------------------------- /js-lib/bruce-us/dist/index.d.ts: -------------------------------------------------------------------------------- 1 | interface KeyArr { 2 | [index: string | number]: string | number; 3 | } 4 | interface GroupObj { 5 | [key: string | number]: KeyArr[]; 6 | } 7 | interface CountObj { 8 | [key: string | number]: number; 9 | } 10 | declare function GroupArrKey(arr?: KeyArr[], key?: string): GroupObj; 11 | declare function RecordArrPosition(arr: (string | number | boolean)[] | undefined, val: string | number | boolean): number[]; 12 | declare function StatArrCount(arr?: Array): CountObj; 13 | declare function StatArrKeyword(arr?: string[], keys?: string[]): string[]; 14 | 15 | declare function EnvType(): string; 16 | declare function IsWeb(): boolean; 17 | declare function IsNode(): boolean; 18 | declare function TypeOf(data: T): string; 19 | declare function IsUndefined(data: T): boolean; 20 | declare function IsNull(data: T): boolean; 21 | declare function IsString(data: T): boolean; 22 | declare function IsNumber(data: T): boolean; 23 | declare function IsBoolean(data: T): boolean; 24 | declare function IsSymbol(data: T): boolean; 25 | declare function IsArray(data: T): boolean; 26 | declare function IsObject(data: T): boolean; 27 | declare function IsDate(data: T): boolean; 28 | declare function IsRegExp(data: T): boolean; 29 | declare function IsFunction(data: T): boolean; 30 | declare function IsClass(data: T): boolean; 31 | declare function IsSet(data: T): boolean; 32 | declare function IsMap(data: T): boolean; 33 | declare function IsWeakSet(data: T): boolean; 34 | declare function IsWeakMap(data: T): boolean; 35 | declare function IsElement(data: T): boolean; 36 | declare function IsAsyncFunction(data: T): boolean; 37 | declare function IsSyncFunction(data: T): boolean; 38 | declare function IsArguments(data: T): boolean; 39 | declare function IsError(data: T): boolean; 40 | declare function IsEmpty(data: T): boolean; 41 | declare function IsEmptyArray(data: T): boolean; 42 | declare function IsEmptyObject(data: T): boolean; 43 | 44 | declare function FormatCountdown(date: string | number | Date): string; 45 | declare function FormatTimeDiff(date: string | number | Date): string; 46 | 47 | declare type TgtFunc = (...args: T[]) => void; 48 | declare function AsyncTo(pfn: Promise, error?: object): Promise<[U, undefined] | [null, T]>; 49 | declare function Debounce(fn: TgtFunc, dura?: number): TgtFunc; 50 | declare function Throttle(fn: TgtFunc, dura?: number): TgtFunc; 51 | declare function WaitFor(dura?: number): Promise; 52 | 53 | declare function FillNum(num?: number, len?: number): string; 54 | declare function FormatByte(byte?: number): string; 55 | declare function RandomNum(min?: number, max?: number): number; 56 | declare function RandomNumPlus(min?: number, max?: number, count?: number): number[]; 57 | declare function RoundNum(num?: number, dec?: number, per?: boolean): string | number; 58 | declare function ThousandNum(num?: number): string; 59 | 60 | interface Obj { 61 | [key: string | number]: T; 62 | } 63 | declare function FilterObj(obj?: Obj, keys?: Array): Obj; 64 | 65 | interface CheckObj { 66 | flag: boolean; 67 | msg: string; 68 | } 69 | declare function CheckText(type?: string, text?: string): CheckObj; 70 | declare function CheckTextPlus(regexp: RegExp, text?: string, msg?: string): CheckObj; 71 | declare function MatchBracketText(tgt?: string, text?: string): string[]; 72 | 73 | declare function DesePhone(phone?: string): string; 74 | declare function FormatPhone(phone?: string, sign?: string): string; 75 | declare function RandomColor(): string; 76 | declare function RandomId(len?: number): string; 77 | declare function RemoveTag(text?: string): string; 78 | declare function ReverseText(text?: string): string; 79 | declare function StartScore(rate?: number, len?: number): string; 80 | 81 | declare type FilterFunc = (src: string, dist: string) => boolean; 82 | declare function AbsPath(path?: string, dir?: string): string; 83 | declare function CopyDir(src: string | undefined, dist: string | undefined, filter: FilterFunc): void; 84 | declare function CreateDir(dir?: string): void; 85 | declare function ReadDir(type?: string, dir?: string, filter?: RegExp): string[]; 86 | declare function ReadJson(path?: string, dir?: string): object; 87 | declare function RemoveDir(dir?: string): void; 88 | 89 | declare function GetIP(): string; 90 | 91 | declare function RunCmd(cmd?: string): string; 92 | 93 | interface NodeObj { 94 | nodeVs: string; 95 | npmVs: string; 96 | system: string; 97 | systemVs: string; 98 | } 99 | declare function NodeType(): NodeObj; 100 | 101 | interface CookieObj { 102 | [key: string]: string; 103 | } 104 | declare function GetCookie(): CookieObj; 105 | declare function RemoveCookie(key?: string): void; 106 | declare function SetCookie(key?: string, val?: string, day?: number): void; 107 | 108 | declare function AutoResponse(width?: number): void; 109 | declare function CopyPaste(elem?: HTMLElement): void; 110 | declare function DownloadFile(url?: string, name?: string): void; 111 | declare function FilterXss(html?: string): string; 112 | declare function Img2Base64(url?: string, type?: string): Promise; 113 | declare function Jsonp(url?: string, name?: string, cb?: null | ((d: T) => T)): Promise; 114 | declare function LoadScript(url?: string, pst?: string): Promise; 115 | 116 | interface AjaxObj { 117 | data?: { 118 | [key: string]: string; 119 | }; 120 | error?: null | ((status: number) => void); 121 | success?: null | ((res: string) => void); 122 | type?: string; 123 | url: string; 124 | } 125 | declare function Ajax({ data, error, success, type, url }: AjaxObj): void; 126 | 127 | declare function ClearLStorage(): void; 128 | declare function ClearSStorage(): void; 129 | declare function GetLStorage(key?: string): T; 130 | declare function GetSStorage(key?: string): T; 131 | declare function RemoveLStorage(key?: string): void; 132 | declare function RemoveSStorage(key?: string): void; 133 | declare function SetLStorage(key: string | undefined, val: T): void; 134 | declare function SetSStorage(key: string | undefined, val: T): void; 135 | 136 | interface WebObj { 137 | engine: string; 138 | engineVs: string; 139 | platform: string; 140 | supporter: string; 141 | supporterVs: string; 142 | system: string; 143 | systemVs: string; 144 | shell?: string; 145 | shellVs?: string; 146 | } 147 | declare function WebType(ua?: string): WebObj; 148 | 149 | interface SearchObj { 150 | [key: string]: string; 151 | } 152 | declare function ParseUrlSearch(): SearchObj; 153 | declare function RemoveUrlSearch(...search: string[]): void; 154 | declare function SetUrlSearch(search?: SearchObj): void; 155 | declare function StringifyUrlSearch(search?: SearchObj, clear?: boolean): string; 156 | 157 | export { AbsPath, Ajax, AsyncTo, AutoResponse, CheckText, CheckTextPlus, ClearLStorage, ClearSStorage, CopyDir, CopyPaste, CreateDir, Debounce, DesePhone, DownloadFile, EnvType, FillNum, FilterObj, FilterXss, FormatByte, FormatCountdown, FormatPhone, FormatTimeDiff, GetCookie, GetIP, GetLStorage, GetSStorage, GroupArrKey, Img2Base64, IsArguments, IsArray, IsAsyncFunction, IsBoolean, IsClass, IsDate, IsElement, IsEmpty, IsEmptyArray, IsEmptyObject, IsError, IsFunction, IsMap, IsNode, IsNull, IsNumber, IsObject, IsRegExp, IsSet, IsString, IsSymbol, IsSyncFunction, IsUndefined, IsWeakMap, IsWeakSet, IsWeb, Jsonp, LoadScript, MatchBracketText, NodeType, ParseUrlSearch, RandomColor, RandomId, RandomNum, RandomNumPlus, ReadDir, ReadJson, RecordArrPosition, RemoveCookie, RemoveDir, RemoveLStorage, RemoveSStorage, RemoveTag, RemoveUrlSearch, ReverseText, RoundNum, RunCmd, SetCookie, SetLStorage, SetSStorage, SetUrlSearch, StartScore, StatArrCount, StatArrKeyword, StringifyUrlSearch, ThousandNum, Throttle, TypeOf, WaitFor, WebType }; 158 | -------------------------------------------------------------------------------- /js-lib/bruce-us/dist/node.esm.js: -------------------------------------------------------------------------------- 1 | import t,{statSync as n,readdirSync as e,readFileSync as r}from"fs";import i,{join as o,extname as c}from"path";import{cwd as s}from"process";import u from"constants";import a from"stream";import f from"util";import l from"assert";import{networkInterfaces as d,type as y,release as h}from"os";import{execSync as p}from"child_process";function m(t,n){return void 0===t&&(t=[]),void 0===n&&(n=""),n?t.reduce((function(t,e){return!t[e[n]]&&(t[e[n]]=[]),t[e[n]].push(e),t}),{}):{}}function v(t,n){return void 0===t&&(t=[]),t.reduce((function(t,e,r){return e===n&&t.push(r),t}),[])}function S(t){return void 0===t&&(t=[]),t.reduce((function(t,n){return t[n]=(t[n]||0)+1,t}),{})}function w(t,n){return void 0===t&&(t=[]),void 0===n&&(n=[]),n.reduce((function(n,e){return t.some((function(t){return t.includes(e)}))&&n.push(e),n}),[])}function g(){return"undefined"!=typeof window?"web":"undefined"!=typeof global?"node":"unknow"}function b(){return"web"===g()}function E(){return"node"===g()}function k(t){return Object.prototype.toString.call(t).replace(/\[object (\w+)\]/,"$1").toLowerCase()}function $(t){return"undefined"===k(t)}function O(t){return"null"===k(t)}function D(t){return"string"===k(t)}function M(t){return"number"===k(t)}function N(t){return"boolean"===k(t)}function F(t){return"symbol"===k(t)}function P(t){return"array"===k(t)}function x(t){return"object"===k(t)}function T(t){return"date"===k(t)}function C(t){return"regexp"===k(t)}function _(t){return"function"===k(t)}function L(t){return _(t)&&/^class\s+[\dA-Za-z]/.test(t.toString())}function j(t){return"set"===k(t)}function I(t){return"map"===k(t)}function Y(t){return"weakset"===k(t)}function A(t){return"weakmap"===k(t)}function R(t){return/^html(.+?)element$/.test(k(t))}function J(t){return"asyncfunction"===k(t)}function B(t){return"function"===k(t)}function W(t){return"arguments"===k(t)}function U(t){return t instanceof Error}function G(t){return!t}function H(t){return Array.isArray(t)&&!t.length}function q(t){return x(t)&&!Object.keys(t).length}var V="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},z={exports:{}},K=z.exports=function(){var t=1e3,n=6e4,e=36e5,r="millisecond",i="second",o="minute",c="hour",s="day",u="week",a="month",f="quarter",l="year",d="date",y="Invalid Date",h=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,p=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,m={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_")},v=function(t,n,e){var r=String(t);return!r||r.length>=n?t:""+Array(n+1-r.length).join(e)+t},S={s:v,z:function(t){var n=-t.utcOffset(),e=Math.abs(n),r=Math.floor(e/60),i=e%60;return(n<=0?"+":"-")+v(r,2,"0")+":"+v(i,2,"0")},m:function t(n,e){if(n.date()1)return t(c[0])}else{var s=n.name;g[s]=n,i=s}return!r&&i&&(w=i),i||!r&&w},k=function(t,n){if(b(t))return t.clone();var e="object"==typeof n?n:{};return e.date=t,e.args=arguments,new O(e)},$=S;$.l=E,$.i=b,$.w=function(t,n){return k(t,{locale:n.$L,utc:n.$u,x:n.$x,$offset:n.$offset})};var O=function(){function m(t){this.$L=E(t.locale,null,!0),this.parse(t)}var v=m.prototype;return v.parse=function(t){this.$d=function(t){var n=t.date,e=t.utc;if(null===n)return new Date(NaN);if($.u(n))return new Date;if(n instanceof Date)return new Date(n);if("string"==typeof n&&!/Z$/i.test(n)){var r=n.match(h);if(r){var i=r[2]-1||0,o=(r[7]||"0").substring(0,3);return e?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,o)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,o)}}return new Date(n)}(t),this.$x=t.x||{},this.init()},v.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},v.$utils=function(){return $},v.isValid=function(){return!(this.$d.toString()===y)},v.isSame=function(t,n){var e=k(t);return this.startOf(n)<=e&&e<=this.endOf(n)},v.isAfter=function(t,n){return k(t)=0){var r=Math.floor(e/1e3/3600/24),i=Math.floor(e/1e3/60/60%24),o=Math.floor(e/1e3/60%60),c=Math.floor(e/1e3%60),s=r?"".concat(r,"天"):"",u=i?"".concat(i,"时"):"",a=o?"".concat(o,"分"):"",f=c?"".concat(c,"秒"):"";return"".concat(s).concat(u).concat(a).concat(f)}return"时间已到"}function X(t){if(!t)return"时间无效";var n=+new Date,e=+new Date(t),r=n-e,i=r>=0?"前":"后",o=Math.abs(r),c=30.4375,s=36e5,u=24*s,a=o/6e4,f=o/s,l=o/u,d=o/26298e5;return o/315576e5>=1||d>=12?K(e).format("YYYY-MM-DD HH:mm:ss"):d>=1&&d<12?"".concat(parseInt(d.toString()),"个月").concat(i):l>=1&&l=1&&f<24?"".concat(parseInt(f.toString()),"小时").concat(i):a>=1&&a<60?"".concat(parseInt(a.toString()),"分钟").concat(i):r>=0?"刚刚":"准备"}function Q(t,n,e,r){return new(e||(e=Promise))((function(i,o){function c(t){try{u(r.next(t))}catch(t){o(t)}}function s(t){try{u(r.throw(t))}catch(t){o(t)}}function u(t){var n;t.done?i(t.value):(n=t.value,n instanceof e?n:new e((function(t){t(n)}))).then(c,s)}u((r=r.apply(t,n||[])).next())}))}function tt(t,n){var e,r,i,o,c={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(e)throw new TypeError("Generator is already executing.");for(;c;)try{if(e=1,r&&(i=2&o[0]?r.return:o[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return c.label++,{value:o[1],done:!1};case 5:c.label++,r=o[1],o=[0];continue;case 7:o=c.ops.pop(),c.trys.pop();continue;default:if(!(i=c.trys,(i=i.length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){c=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0)&&!(r=o.next()).done;)c.push(r.value)}catch(t){i={error:t}}finally{try{r&&!r.done&&(e=o.return)&&e.call(o)}finally{if(i)throw i.error}}return c}function et(t,n,e){if(e||2===arguments.length)for(var r,i=0,o=n.length;i=n&&(t.apply(o,c),i=Date.now())}),Math.max(n-(Date.now()-i),0))):(t.apply(this,c),i=Date.now(),r=!0)}}function ct(t){return void 0===t&&(t=1e3),Q(this,void 0,void 0,(function(){return tt(this,(function(n){switch(n.label){case 0:return[4,new Promise((function(n){return setTimeout((function(){return n(!0)}),t)}))];case 1:return[2,n.sent()]}}))}))}function st(t,n){return void 0===t&&(t=0),void 0===n&&(n=0),t.toString().padStart(n,"0")}function ut(t){if(void 0===t&&(t=0),0===t)return"0 B";var n=Math.floor(Math.log(t)/Math.log(1024));return(t/Math.pow(1024,n)).toPrecision(3)+" "+["B","KB","MB","GB","TB","PB","EB","ZB","YB"][n]}function at(t,n){return void 0===t&&(t=0),void 0===n&&(n=10),Math.floor(Math.random()*(n-t+1)+t)}function ft(t,n,e){void 0===t&&(t=0),void 0===n&&(n=10),void 0===e&&(e=1);for(var r=[];;){for(var i=!1,o=at(t,n),c=0;c10)&&(t=5),Math.random().toString(36).substr(3,t)}function kt(t){return void 0===t&&(t=""),t.replace(/<[^>]*>/g,"")}function $t(t){return void 0===t&&(t=""),t.split("").reduceRight((function(t,n){return t+n}))}function Ot(t,n){return void 0===t&&(t=0),void 0===n&&(n=5),t<0&&(t=0),t>n&&(t=n),et(et([],nt(new Array(n).fill("★")),!1),nt(new Array(n).fill("☆")),!1).join("").slice(n-t,2*n-t)}var Dt={},Mt={fromCallback:function(t){return Object.defineProperty((function(...n){if("function"!=typeof n[n.length-1])return new Promise(((e,r)=>{t.call(this,...n,((t,n)=>null!=t?r(t):e(n)))}));t.apply(this,n)}),"name",{value:t.name})},fromPromise:function(t){return Object.defineProperty((function(...n){const e=n[n.length-1];if("function"!=typeof e)return t.apply(this,n);t.apply(this,n.slice(0,-1)).then((t=>e(null,t)),e)}),"name",{value:t.name})}},Nt=u,Ft=process.cwd,Pt=null,xt=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return Pt||(Pt=Ft.call(process)),Pt};try{process.cwd()}catch(t){}if("function"==typeof process.chdir){var Tt=process.chdir;process.chdir=function(t){Pt=null,Tt.call(process,t)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,Tt)}var Ct=function(t){Nt.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(t){t.lchmod=function(n,e,r){t.open(n,Nt.O_WRONLY|Nt.O_SYMLINK,e,(function(n,i){n?r&&r(n):t.fchmod(i,e,(function(n){t.close(i,(function(t){r&&r(n||t)}))}))}))},t.lchmodSync=function(n,e){var r,i=t.openSync(n,Nt.O_WRONLY|Nt.O_SYMLINK,e),o=!0;try{r=t.fchmodSync(i,e),o=!1}finally{if(o)try{t.closeSync(i)}catch(t){}else t.closeSync(i)}return r}}(t);t.lutimes||function(t){Nt.hasOwnProperty("O_SYMLINK")&&t.futimes?(t.lutimes=function(n,e,r,i){t.open(n,Nt.O_SYMLINK,(function(n,o){n?i&&i(n):t.futimes(o,e,r,(function(n){t.close(o,(function(t){i&&i(n||t)}))}))}))},t.lutimesSync=function(n,e,r){var i,o=t.openSync(n,Nt.O_SYMLINK),c=!0;try{i=t.futimesSync(o,e,r),c=!1}finally{if(c)try{t.closeSync(o)}catch(t){}else t.closeSync(o)}return i}):t.futimes&&(t.lutimes=function(t,n,e,r){r&&process.nextTick(r)},t.lutimesSync=function(){})}(t);t.chown=r(t.chown),t.fchown=r(t.fchown),t.lchown=r(t.lchown),t.chmod=n(t.chmod),t.fchmod=n(t.fchmod),t.lchmod=n(t.lchmod),t.chownSync=i(t.chownSync),t.fchownSync=i(t.fchownSync),t.lchownSync=i(t.lchownSync),t.chmodSync=e(t.chmodSync),t.fchmodSync=e(t.fchmodSync),t.lchmodSync=e(t.lchmodSync),t.stat=o(t.stat),t.fstat=o(t.fstat),t.lstat=o(t.lstat),t.statSync=c(t.statSync),t.fstatSync=c(t.fstatSync),t.lstatSync=c(t.lstatSync),t.chmod&&!t.lchmod&&(t.lchmod=function(t,n,e){e&&process.nextTick(e)},t.lchmodSync=function(){});t.chown&&!t.lchown&&(t.lchown=function(t,n,e,r){r&&process.nextTick(r)},t.lchownSync=function(){});"win32"===xt&&(t.rename="function"!=typeof t.rename?t.rename:function(n){function e(e,r,i){var o=Date.now(),c=0;n(e,r,(function s(u){if(u&&("EACCES"===u.code||"EPERM"===u.code)&&Date.now()-o<6e4)return setTimeout((function(){t.stat(r,(function(t,o){t&&"ENOENT"===t.code?n(e,r,s):i(u)}))}),c),void(c<100&&(c+=10));i&&i(u)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(e,n),e}(t.rename));function n(n){return n?function(e,r,i){return n.call(t,e,r,(function(t){s(t)&&(t=null),i&&i.apply(this,arguments)}))}:n}function e(n){return n?function(e,r){try{return n.call(t,e,r)}catch(t){if(!s(t))throw t}}:n}function r(n){return n?function(e,r,i,o){return n.call(t,e,r,i,(function(t){s(t)&&(t=null),o&&o.apply(this,arguments)}))}:n}function i(n){return n?function(e,r,i){try{return n.call(t,e,r,i)}catch(t){if(!s(t))throw t}}:n}function o(n){return n?function(e,r,i){function o(t,n){n&&(n.uid<0&&(n.uid+=4294967296),n.gid<0&&(n.gid+=4294967296)),i&&i.apply(this,arguments)}return"function"==typeof r&&(i=r,r=null),r?n.call(t,e,r,o):n.call(t,e,o)}:n}function c(n){return n?function(e,r){var i=r?n.call(t,e,r):n.call(t,e);return i&&(i.uid<0&&(i.uid+=4294967296),i.gid<0&&(i.gid+=4294967296)),i}:n}function s(t){return!t||("ENOSYS"===t.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==t.code&&"EPERM"!==t.code))}t.read="function"!=typeof t.read?t.read:function(n){function e(e,r,i,o,c,s){var u;if(s&&"function"==typeof s){var a=0;u=function(f,l,d){if(f&&"EAGAIN"===f.code&&a<10)return a++,n.call(t,e,r,i,o,c,u);s.apply(this,arguments)}}return n.call(t,e,r,i,o,c,u)}return Object.setPrototypeOf&&Object.setPrototypeOf(e,n),e}(t.read),t.readSync="function"!=typeof t.readSync?t.readSync:(u=t.readSync,function(n,e,r,i,o){for(var c=0;;)try{return u.call(t,n,e,r,i,o)}catch(t){if("EAGAIN"===t.code&&c<10){c++;continue}throw t}});var u};var _t=a.Stream,Lt=function(t){return{ReadStream:function n(e,r){if(!(this instanceof n))return new n(e,r);_t.call(this);var i=this;this.path=e,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),c=0,s=o.length;cthis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){i._read()}));t.open(this.path,this.flags,this.mode,(function(t,n){if(t)return i.emit("error",t),void(i.readable=!1);i.fd=n,i.emit("open",n),i._read()}))},WriteStream:function n(e,r){if(!(this instanceof n))return new n(e,r);_t.call(this),this.path=e,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var i=Object.keys(r),o=0,c=i.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=t.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var jt=function(t){if(null===t||"object"!=typeof t)return t;if(t instanceof Object)var n={__proto__:It(t)};else n=Object.create(null);return Object.getOwnPropertyNames(t).forEach((function(e){Object.defineProperty(n,e,Object.getOwnPropertyDescriptor(t,e))})),n},It=Object.getPrototypeOf||function(t){return t.__proto__};var Yt,At,Rt=t,Jt=Ct,Bt=Lt,Wt=jt,Ut=f;function Gt(t,n){Object.defineProperty(t,Yt,{get:function(){return n}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(Yt=Symbol.for("graceful-fs.queue"),At=Symbol.for("graceful-fs.previous")):(Yt="___graceful-fs.queue",At="___graceful-fs.previous");var Ht=function(){};if(Ut.debuglog?Ht=Ut.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ht=function(){var t=Ut.format.apply(Ut,arguments);t="GFS4: "+t.split(/\n/).join("\nGFS4: "),console.error(t)}),!Rt[Yt]){var qt=V[Yt]||[];Gt(Rt,qt),Rt.close=function(t){function n(n,e){return t.call(Rt,n,(function(t){t||Xt(),"function"==typeof e&&e.apply(this,arguments)}))}return Object.defineProperty(n,At,{value:t}),n}(Rt.close),Rt.closeSync=function(t){function n(n){t.apply(Rt,arguments),Xt()}return Object.defineProperty(n,At,{value:t}),n}(Rt.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ht(Rt[Yt]),l.equal(Rt[Yt].length,0)}))}V[Yt]||Gt(V,Rt[Yt]);var Vt,zt=Kt(Wt(Rt));function Kt(t){Jt(t),t.gracefulify=Kt,t.createReadStream=function(n,e){return new t.ReadStream(n,e)},t.createWriteStream=function(n,e){return new t.WriteStream(n,e)};var n=t.readFile;t.readFile=function(t,e,r){"function"==typeof e&&(r=e,e=null);return function t(e,r,i,o){return n(e,r,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof i&&i.apply(this,arguments):Zt([t,[e,r,i],n,o||Date.now(),Date.now()])}))}(t,e,r)};var e=t.writeFile;t.writeFile=function(t,n,r,i){"function"==typeof r&&(i=r,r=null);return function t(n,r,i,o,c){return e(n,r,i,(function(e){!e||"EMFILE"!==e.code&&"ENFILE"!==e.code?"function"==typeof o&&o.apply(this,arguments):Zt([t,[n,r,i,o],e,c||Date.now(),Date.now()])}))}(t,n,r,i)};var r=t.appendFile;r&&(t.appendFile=function(t,n,e,i){"function"==typeof e&&(i=e,e=null);return function t(n,e,i,o,c){return r(n,e,i,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):Zt([t,[n,e,i,o],r,c||Date.now(),Date.now()])}))}(t,n,e,i)});var i=t.copyFile;i&&(t.copyFile=function(t,n,e,r){"function"==typeof e&&(r=e,e=0);return function t(n,e,r,o,c){return i(n,e,r,(function(i){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof o&&o.apply(this,arguments):Zt([t,[n,e,r,o],i,c||Date.now(),Date.now()])}))}(t,n,e,r)});var o=t.readdir;t.readdir=function(t,n,e){"function"==typeof n&&(e=n,n=null);var r=c.test(process.version)?function(t,n,e,r){return o(t,i(t,n,e,r))}:function(t,n,e,r){return o(t,n,i(t,n,e,r))};return r(t,n,e);function i(t,n,e,i){return function(o,c){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(c&&c.sort&&c.sort(),"function"==typeof e&&e.call(this,o,c)):Zt([r,[t,n,e],o,i||Date.now(),Date.now()])}}};var c=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=Bt(t);d=s.ReadStream,y=s.WriteStream}var u=t.ReadStream;u&&(d.prototype=Object.create(u.prototype),d.prototype.open=function(){var t=this;p(t.path,t.flags,t.mode,(function(n,e){n?(t.autoClose&&t.destroy(),t.emit("error",n)):(t.fd=e,t.emit("open",e),t.read())}))});var a=t.WriteStream;a&&(y.prototype=Object.create(a.prototype),y.prototype.open=function(){var t=this;p(t.path,t.flags,t.mode,(function(n,e){n?(t.destroy(),t.emit("error",n)):(t.fd=e,t.emit("open",e))}))}),Object.defineProperty(t,"ReadStream",{get:function(){return d},set:function(t){d=t},enumerable:!0,configurable:!0}),Object.defineProperty(t,"WriteStream",{get:function(){return y},set:function(t){y=t},enumerable:!0,configurable:!0});var f=d;Object.defineProperty(t,"FileReadStream",{get:function(){return f},set:function(t){f=t},enumerable:!0,configurable:!0});var l=y;function d(t,n){return this instanceof d?(u.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function y(t,n){return this instanceof y?(a.apply(this,arguments),this):y.apply(Object.create(y.prototype),arguments)}Object.defineProperty(t,"FileWriteStream",{get:function(){return l},set:function(t){l=t},enumerable:!0,configurable:!0});var h=t.open;function p(t,n,e,r){return"function"==typeof e&&(r=e,e=null),function t(n,e,r,i,o){return h(n,e,r,(function(c,s){!c||"EMFILE"!==c.code&&"ENFILE"!==c.code?"function"==typeof i&&i.apply(this,arguments):Zt([t,[n,e,r,i],c,o||Date.now(),Date.now()])}))}(t,n,e,r)}return t.open=p,t}function Zt(t){Ht("ENQUEUE",t[0].name,t[1]),Rt[Yt].push(t),Qt()}function Xt(){for(var t=Date.now(),n=0;n2&&(Rt[Yt][n][3]=t,Rt[Yt][n][4]=t);Qt()}function Qt(){if(clearTimeout(Vt),Vt=void 0,0!==Rt[Yt].length){var t=Rt[Yt].shift(),n=t[0],e=t[1],r=t[2],i=t[3],o=t[4];if(void 0===i)Ht("RETRY",n.name,e),n.apply(null,e);else if(Date.now()-i>=6e4){Ht("TIMEOUT",n.name,e);var c=e.pop();"function"==typeof c&&c.call(null,r)}else{var s=Date.now()-o,u=Math.max(o-i,1);s>=Math.min(1.2*u,100)?(Ht("RETRY",n.name,e),n.apply(null,e.concat([i]))):Rt[Yt].push(t)}void 0===Vt&&(Vt=setTimeout(Qt,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!Rt.__patched&&(zt=Kt(Rt),Rt.__patched=!0),function(t){const n=Mt.fromCallback,e=zt,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((t=>"function"==typeof e[t]));Object.assign(t,e),r.forEach((r=>{t[r]=n(e[r])})),t.realpath.native=n(e.realpath.native),t.exists=function(t,n){return"function"==typeof n?e.exists(t,n):new Promise((n=>e.exists(t,n)))},t.read=function(t,n,r,i,o,c){return"function"==typeof c?e.read(t,n,r,i,o,c):new Promise(((c,s)=>{e.read(t,n,r,i,o,((t,n,e)=>{if(t)return s(t);c({bytesRead:n,buffer:e})}))}))},t.write=function(t,n,...r){return"function"==typeof r[r.length-1]?e.write(t,n,...r):new Promise(((i,o)=>{e.write(t,n,...r,((t,n,e)=>{if(t)return o(t);i({bytesWritten:n,buffer:e})}))}))},"function"==typeof e.writev&&(t.writev=function(t,n,...r){return"function"==typeof r[r.length-1]?e.writev(t,n,...r):new Promise(((i,o)=>{e.writev(t,n,...r,((t,n,e)=>{if(t)return o(t);i({bytesWritten:n,buffers:e})}))}))})}(Dt);var tn={},nn={};const en=i;nn.checkPath=function(t){if("win32"===process.platform){if(/[<>:"|?*]/.test(t.replace(en.parse(t).root,""))){const n=new Error(`Path contains invalid characters: ${t}`);throw n.code="EINVAL",n}}};const rn=Dt,{checkPath:on}=nn,cn=t=>"number"==typeof t?t:{mode:511,...t}.mode;tn.makeDir=async(t,n)=>(on(t),rn.mkdir(t,{mode:cn(n),recursive:!0})),tn.makeDirSync=(t,n)=>(on(t),rn.mkdirSync(t,{mode:cn(n),recursive:!0}));const sn=Mt.fromPromise,{makeDir:un,makeDirSync:an}=tn,fn=sn(un);var ln={mkdirs:fn,mkdirsSync:an,mkdirp:fn,mkdirpSync:an,ensureDir:fn,ensureDirSync:an};const dn=Mt.fromPromise,yn=Dt;var hn={pathExists:dn((function(t){return yn.access(t).then((()=>!0)).catch((()=>!1))})),pathExistsSync:yn.existsSync};const pn=zt;var mn=function(t,n,e,r){pn.open(t,"r+",((t,i)=>{if(t)return r(t);pn.futimes(i,n,e,(t=>{pn.close(i,(n=>{r&&r(t||n)}))}))}))},vn=function(t,n,e){const r=pn.openSync(t,"r+");return pn.futimesSync(r,n,e),pn.closeSync(r)};const Sn=Dt,wn=i,gn=f;function bn(t,n,e){const r=e.dereference?t=>Sn.stat(t,{bigint:!0}):t=>Sn.lstat(t,{bigint:!0});return Promise.all([r(t),r(n).catch((t=>{if("ENOENT"===t.code)return null;throw t}))]).then((([t,n])=>({srcStat:t,destStat:n})))}function En(t,n){return n.ino&&n.dev&&n.ino===t.ino&&n.dev===t.dev}function kn(t,n){const e=wn.resolve(t).split(wn.sep).filter((t=>t)),r=wn.resolve(n).split(wn.sep).filter((t=>t));return e.reduce(((t,n,e)=>t&&r[e]===n),!0)}function $n(t,n,e){return`Cannot ${e} '${t}' to a subdirectory of itself, '${n}'.`}var On={checkPaths:function(t,n,e,r,i){gn.callbackify(bn)(t,n,r,((r,o)=>{if(r)return i(r);const{srcStat:c,destStat:s}=o;if(s){if(En(c,s)){const r=wn.basename(t),o=wn.basename(n);return"move"===e&&r!==o&&r.toLowerCase()===o.toLowerCase()?i(null,{srcStat:c,destStat:s,isChangingCase:!0}):i(new Error("Source and destination must not be the same."))}if(c.isDirectory()&&!s.isDirectory())return i(new Error(`Cannot overwrite non-directory '${n}' with directory '${t}'.`));if(!c.isDirectory()&&s.isDirectory())return i(new Error(`Cannot overwrite directory '${n}' with non-directory '${t}'.`))}return c.isDirectory()&&kn(t,n)?i(new Error($n(t,n,e))):i(null,{srcStat:c,destStat:s})}))},checkPathsSync:function(t,n,e,r){const{srcStat:i,destStat:o}=function(t,n,e){let r;const i=e.dereference?t=>Sn.statSync(t,{bigint:!0}):t=>Sn.lstatSync(t,{bigint:!0}),o=i(t);try{r=i(n)}catch(t){if("ENOENT"===t.code)return{srcStat:o,destStat:null};throw t}return{srcStat:o,destStat:r}}(t,n,r);if(o){if(En(i,o)){const r=wn.basename(t),c=wn.basename(n);if("move"===e&&r!==c&&r.toLowerCase()===c.toLowerCase())return{srcStat:i,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(i.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${n}' with directory '${t}'.`);if(!i.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${n}' with non-directory '${t}'.`)}if(i.isDirectory()&&kn(t,n))throw new Error($n(t,n,e));return{srcStat:i,destStat:o}},checkParentPaths:function t(n,e,r,i,o){const c=wn.resolve(wn.dirname(n)),s=wn.resolve(wn.dirname(r));if(s===c||s===wn.parse(s).root)return o();Sn.stat(s,{bigint:!0},((c,u)=>c?"ENOENT"===c.code?o():o(c):En(e,u)?o(new Error($n(n,r,i))):t(n,e,s,i,o)))},checkParentPathsSync:function t(n,e,r,i){const o=wn.resolve(wn.dirname(n)),c=wn.resolve(wn.dirname(r));if(c===o||c===wn.parse(c).root)return;let s;try{s=Sn.statSync(c,{bigint:!0})}catch(t){if("ENOENT"===t.code)return;throw t}if(En(e,s))throw new Error($n(n,r,i));return t(n,e,c,i)},isSrcSubdir:kn,areIdentical:En};const Dn=zt,Mn=i,Nn=ln.mkdirs,Fn=hn.pathExists,Pn=mn,xn=On;function Tn(t,n,e,r,i){const o=Mn.dirname(e);Fn(o,((c,s)=>c?i(c):s?_n(t,n,e,r,i):void Nn(o,(o=>o?i(o):_n(t,n,e,r,i)))))}function Cn(t,n,e,r,i,o){Promise.resolve(i.filter(e,r)).then((c=>c?t(n,e,r,i,o):o()),(t=>o(t)))}function _n(t,n,e,r,i){(r.dereference?Dn.stat:Dn.lstat)(n,((o,c)=>o?i(o):c.isDirectory()?function(t,n,e,r,i,o){return n?Yn(e,r,i,o):function(t,n,e,r,i){Dn.mkdir(e,(o=>{if(o)return i(o);Yn(n,e,r,(n=>n?i(n):In(e,t,i)))}))}(t.mode,e,r,i,o)}(c,t,n,e,r,i):c.isFile()||c.isCharacterDevice()||c.isBlockDevice()?function(t,n,e,r,i,o){return n?function(t,n,e,r,i){if(!r.overwrite)return r.errorOnExist?i(new Error(`'${e}' already exists`)):i();Dn.unlink(e,(o=>o?i(o):Ln(t,n,e,r,i)))}(t,e,r,i,o):Ln(t,e,r,i,o)}(c,t,n,e,r,i):c.isSymbolicLink()?function(t,n,e,r,i){Dn.readlink(n,((n,o)=>n?i(n):(r.dereference&&(o=Mn.resolve(process.cwd(),o)),t?void Dn.readlink(e,((n,c)=>n?"EINVAL"===n.code||"UNKNOWN"===n.code?Dn.symlink(o,e,i):i(n):(r.dereference&&(c=Mn.resolve(process.cwd(),c)),xn.isSrcSubdir(o,c)?i(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${c}'.`)):t.isDirectory()&&xn.isSrcSubdir(c,o)?i(new Error(`Cannot overwrite '${c}' with '${o}'.`)):function(t,n,e){Dn.unlink(n,(r=>r?e(r):Dn.symlink(t,n,e)))}(o,e,i)))):Dn.symlink(o,e,i))))}(t,n,e,r,i):c.isSocket()?i(new Error(`Cannot copy a socket file: ${n}`)):c.isFIFO()?i(new Error(`Cannot copy a FIFO pipe: ${n}`)):i(new Error(`Unknown file: ${n}`))))}function Ln(t,n,e,r,i){Dn.copyFile(n,e,(o=>o?i(o):r.preserveTimestamps?function(t,n,e,r){if(function(t){return 0==(128&t)}(t))return function(t,n,e){return In(t,128|n,e)}(e,t,(i=>i?r(i):jn(t,n,e,r)));return jn(t,n,e,r)}(t.mode,n,e,i):In(e,t.mode,i)))}function jn(t,n,e,r){!function(t,n,e){Dn.stat(t,((t,r)=>t?e(t):Pn(n,r.atime,r.mtime,e)))}(n,e,(n=>n?r(n):In(e,t,r)))}function In(t,n,e){return Dn.chmod(t,n,e)}function Yn(t,n,e,r){Dn.readdir(t,((i,o)=>i?r(i):An(o,t,n,e,r)))}function An(t,n,e,r,i){const o=t.pop();return o?function(t,n,e,r,i,o){const c=Mn.join(e,n),s=Mn.join(r,n);xn.checkPaths(c,s,"copy",i,((n,u)=>{if(n)return o(n);const{destStat:a}=u;!function(t,n,e,r,i){r.filter?Cn(_n,t,n,e,r,i):_n(t,n,e,r,i)}(a,c,s,i,(n=>n?o(n):An(t,e,r,i,o)))}))}(t,o,n,e,r,i):i()}var Rn=function(t,n,e,r){"function"!=typeof e||r?"function"==typeof e&&(e={filter:e}):(r=e,e={}),r=r||function(){},(e=e||{}).clobber=!("clobber"in e)||!!e.clobber,e.overwrite="overwrite"in e?!!e.overwrite:e.clobber,e.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),xn.checkPaths(t,n,"copy",e,((i,o)=>{if(i)return r(i);const{srcStat:c,destStat:s}=o;xn.checkParentPaths(t,c,n,"copy",(i=>i?r(i):e.filter?Cn(Tn,s,t,n,e,r):Tn(s,t,n,e,r)))}))};const Jn=zt,Bn=i,Wn=ln.mkdirsSync,Un=vn,Gn=On;function Hn(t,n,e,r){const i=(r.dereference?Jn.statSync:Jn.lstatSync)(n);if(i.isDirectory())return function(t,n,e,r,i){return n?zn(e,r,i):function(t,n,e,r){return Jn.mkdirSync(e),zn(n,e,r),Vn(e,t)}(t.mode,e,r,i)}(i,t,n,e,r);if(i.isFile()||i.isCharacterDevice()||i.isBlockDevice())return function(t,n,e,r,i){return n?function(t,n,e,r){if(r.overwrite)return Jn.unlinkSync(e),qn(t,n,e,r);if(r.errorOnExist)throw new Error(`'${e}' already exists`)}(t,e,r,i):qn(t,e,r,i)}(i,t,n,e,r);if(i.isSymbolicLink())return function(t,n,e,r){let i=Jn.readlinkSync(n);r.dereference&&(i=Bn.resolve(process.cwd(),i));if(t){let t;try{t=Jn.readlinkSync(e)}catch(t){if("EINVAL"===t.code||"UNKNOWN"===t.code)return Jn.symlinkSync(i,e);throw t}if(r.dereference&&(t=Bn.resolve(process.cwd(),t)),Gn.isSrcSubdir(i,t))throw new Error(`Cannot copy '${i}' to a subdirectory of itself, '${t}'.`);if(Jn.statSync(e).isDirectory()&&Gn.isSrcSubdir(t,i))throw new Error(`Cannot overwrite '${t}' with '${i}'.`);return function(t,n){return Jn.unlinkSync(n),Jn.symlinkSync(t,n)}(i,e)}return Jn.symlinkSync(i,e)}(t,n,e,r);if(i.isSocket())throw new Error(`Cannot copy a socket file: ${n}`);if(i.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${n}`);throw new Error(`Unknown file: ${n}`)}function qn(t,n,e,r){return Jn.copyFileSync(n,e),r.preserveTimestamps&&function(t,n,e){(function(t){return 0==(128&t)})(t)&&function(t,n){Vn(t,128|n)}(e,t);(function(t,n){const e=Jn.statSync(t);Un(n,e.atime,e.mtime)})(n,e)}(t.mode,n,e),Vn(e,t.mode)}function Vn(t,n){return Jn.chmodSync(t,n)}function zn(t,n,e){Jn.readdirSync(t).forEach((r=>function(t,n,e,r){const i=Bn.join(n,t),o=Bn.join(e,t),{destStat:c}=Gn.checkPathsSync(i,o,"copy",r);return function(t,n,e,r){if(!r.filter||r.filter(n,e))return Hn(t,n,e,r)}(c,i,o,r)}(r,t,n,e)))}var Kn=function(t,n,e){"function"==typeof e&&(e={filter:e}),(e=e||{}).clobber=!("clobber"in e)||!!e.clobber,e.overwrite="overwrite"in e?!!e.overwrite:e.clobber,e.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:i}=Gn.checkPathsSync(t,n,"copy",e);return Gn.checkParentPathsSync(t,r,n,"copy"),function(t,n,e,r){if(r.filter&&!r.filter(n,e))return;const i=Bn.dirname(e);Jn.existsSync(i)||Wn(i);return Hn(t,n,e,r)}(i,t,n,e)};var Zn={copy:(0,Mt.fromCallback)(Rn),copySync:Kn};const Xn=zt,Qn=i,te=l,ne="win32"===process.platform;function ee(t){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((n=>{t[n]=t[n]||Xn[n],t[n+="Sync"]=t[n]||Xn[n]})),t.maxBusyTries=t.maxBusyTries||3}function re(t,n,e){let r=0;"function"==typeof n&&(e=n,n={}),te(t,"rimraf: missing path"),te.strictEqual(typeof t,"string","rimraf: path should be a string"),te.strictEqual(typeof e,"function","rimraf: callback function required"),te(n,"rimraf: invalid options argument provided"),te.strictEqual(typeof n,"object","rimraf: options should be object"),ee(n),ie(t,n,(function i(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rie(t,n,i)),100*r)}"ENOENT"===o.code&&(o=null)}e(o)}))}function ie(t,n,e){te(t),te(n),te("function"==typeof e),n.lstat(t,((r,i)=>r&&"ENOENT"===r.code?e(null):r&&"EPERM"===r.code&&ne?oe(t,n,r,e):i&&i.isDirectory()?se(t,n,r,e):void n.unlink(t,(r=>{if(r){if("ENOENT"===r.code)return e(null);if("EPERM"===r.code)return ne?oe(t,n,r,e):se(t,n,r,e);if("EISDIR"===r.code)return se(t,n,r,e)}return e(r)}))))}function oe(t,n,e,r){te(t),te(n),te("function"==typeof r),n.chmod(t,438,(i=>{i?r("ENOENT"===i.code?null:e):n.stat(t,((i,o)=>{i?r("ENOENT"===i.code?null:e):o.isDirectory()?se(t,n,e,r):n.unlink(t,r)}))}))}function ce(t,n,e){let r;te(t),te(n);try{n.chmodSync(t,438)}catch(t){if("ENOENT"===t.code)return;throw e}try{r=n.statSync(t)}catch(t){if("ENOENT"===t.code)return;throw e}r.isDirectory()?ae(t,n,e):n.unlinkSync(t)}function se(t,n,e,r){te(t),te(n),te("function"==typeof r),n.rmdir(t,(i=>{!i||"ENOTEMPTY"!==i.code&&"EEXIST"!==i.code&&"EPERM"!==i.code?i&&"ENOTDIR"===i.code?r(e):r(i):function(t,n,e){te(t),te(n),te("function"==typeof e),n.readdir(t,((r,i)=>{if(r)return e(r);let o,c=i.length;if(0===c)return n.rmdir(t,e);i.forEach((r=>{re(Qn.join(t,r),n,(r=>{if(!o)return r?e(o=r):void(0==--c&&n.rmdir(t,e))}))}))}))}(t,n,r)}))}function ue(t,n){let e;ee(n=n||{}),te(t,"rimraf: missing path"),te.strictEqual(typeof t,"string","rimraf: path should be a string"),te(n,"rimraf: missing options"),te.strictEqual(typeof n,"object","rimraf: options should be object");try{e=n.lstatSync(t)}catch(e){if("ENOENT"===e.code)return;"EPERM"===e.code&&ne&&ce(t,n,e)}try{e&&e.isDirectory()?ae(t,n,null):n.unlinkSync(t)}catch(e){if("ENOENT"===e.code)return;if("EPERM"===e.code)return ne?ce(t,n,e):ae(t,n,e);if("EISDIR"!==e.code)throw e;ae(t,n,e)}}function ae(t,n,e){te(t),te(n);try{n.rmdirSync(t)}catch(r){if("ENOTDIR"===r.code)throw e;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(t,n){if(te(t),te(n),n.readdirSync(t).forEach((e=>ue(Qn.join(t,e),n))),!ne){return n.rmdirSync(t,n)}{const e=Date.now();do{try{return n.rmdirSync(t,n)}catch{}}while(Date.now()-e<500)}}(t,n);else if("ENOENT"!==r.code)throw r}}var fe=re;re.sync=ue;const le=zt,de=Mt.fromCallback,ye=fe;var he={remove:de((function(t,n){if(le.rm)return le.rm(t,{recursive:!0,force:!0},n);ye(t,n)})),removeSync:function(t){if(le.rmSync)return le.rmSync(t,{recursive:!0,force:!0});ye.sync(t)}};const pe=Mt.fromPromise,me=Dt,ve=i,Se=ln,we=he,ge=pe((async function(t){let n;try{n=await me.readdir(t)}catch{return Se.mkdirs(t)}return Promise.all(n.map((n=>we.remove(ve.join(t,n)))))}));function be(t){let n;try{n=me.readdirSync(t)}catch{return Se.mkdirsSync(t)}n.forEach((n=>{n=ve.join(t,n),we.removeSync(n)}))}var Ee={emptyDirSync:be,emptydirSync:be,emptyDir:ge,emptydir:ge};const ke=Mt.fromCallback,$e=i,Oe=zt,De=ln;var Me={createFile:ke((function(t,n){function e(){Oe.writeFile(t,"",(t=>{if(t)return n(t);n()}))}Oe.stat(t,((r,i)=>{if(!r&&i.isFile())return n();const o=$e.dirname(t);Oe.stat(o,((t,r)=>{if(t)return"ENOENT"===t.code?De.mkdirs(o,(t=>{if(t)return n(t);e()})):n(t);r.isDirectory()?e():Oe.readdir(o,(t=>{if(t)return n(t)}))}))}))})),createFileSync:function(t){let n;try{n=Oe.statSync(t)}catch{}if(n&&n.isFile())return;const e=$e.dirname(t);try{Oe.statSync(e).isDirectory()||Oe.readdirSync(e)}catch(t){if(!t||"ENOENT"!==t.code)throw t;De.mkdirsSync(e)}Oe.writeFileSync(t,"")}};const Ne=Mt.fromCallback,Fe=i,Pe=zt,xe=ln,Te=hn.pathExists,{areIdentical:Ce}=On;var _e={createLink:Ne((function(t,n,e){function r(t,n){Pe.link(t,n,(t=>{if(t)return e(t);e(null)}))}Pe.lstat(n,((i,o)=>{Pe.lstat(t,((i,c)=>{if(i)return i.message=i.message.replace("lstat","ensureLink"),e(i);if(o&&Ce(c,o))return e(null);const s=Fe.dirname(n);Te(s,((i,o)=>i?e(i):o?r(t,n):void xe.mkdirs(s,(i=>{if(i)return e(i);r(t,n)}))))}))}))})),createLinkSync:function(t,n){let e;try{e=Pe.lstatSync(n)}catch{}try{const n=Pe.lstatSync(t);if(e&&Ce(n,e))return}catch(t){throw t.message=t.message.replace("lstat","ensureLink"),t}const r=Fe.dirname(n);return Pe.existsSync(r)||xe.mkdirsSync(r),Pe.linkSync(t,n)}};const Le=i,je=zt,Ie=hn.pathExists;var Ye={symlinkPaths:function(t,n,e){if(Le.isAbsolute(t))return je.lstat(t,(n=>n?(n.message=n.message.replace("lstat","ensureSymlink"),e(n)):e(null,{toCwd:t,toDst:t})));{const r=Le.dirname(n),i=Le.join(r,t);return Ie(i,((n,o)=>n?e(n):o?e(null,{toCwd:i,toDst:t}):je.lstat(t,(n=>n?(n.message=n.message.replace("lstat","ensureSymlink"),e(n)):e(null,{toCwd:t,toDst:Le.relative(r,t)})))))}},symlinkPathsSync:function(t,n){let e;if(Le.isAbsolute(t)){if(e=je.existsSync(t),!e)throw new Error("absolute srcpath does not exist");return{toCwd:t,toDst:t}}{const r=Le.dirname(n),i=Le.join(r,t);if(e=je.existsSync(i),e)return{toCwd:i,toDst:t};if(e=je.existsSync(t),!e)throw new Error("relative srcpath does not exist");return{toCwd:t,toDst:Le.relative(r,t)}}}};const Ae=zt;var Re={symlinkType:function(t,n,e){if(e="function"==typeof n?n:e,n="function"!=typeof n&&n)return e(null,n);Ae.lstat(t,((t,r)=>{if(t)return e(null,"file");n=r&&r.isDirectory()?"dir":"file",e(null,n)}))},symlinkTypeSync:function(t,n){let e;if(n)return n;try{e=Ae.lstatSync(t)}catch{return"file"}return e&&e.isDirectory()?"dir":"file"}};const Je=Mt.fromCallback,Be=i,We=Dt,Ue=ln.mkdirs,Ge=ln.mkdirsSync,He=Ye.symlinkPaths,qe=Ye.symlinkPathsSync,Ve=Re.symlinkType,ze=Re.symlinkTypeSync,Ke=hn.pathExists,{areIdentical:Ze}=On;function Xe(t,n,e,r){He(t,n,((i,o)=>{if(i)return r(i);t=o.toDst,Ve(o.toCwd,e,((e,i)=>{if(e)return r(e);const o=Be.dirname(n);Ke(o,((e,c)=>e?r(e):c?We.symlink(t,n,i,r):void Ue(o,(e=>{if(e)return r(e);We.symlink(t,n,i,r)}))))}))}))}var Qe={createSymlink:Je((function(t,n,e,r){r="function"==typeof e?e:r,e="function"!=typeof e&&e,We.lstat(n,((i,o)=>{!i&&o.isSymbolicLink()?Promise.all([We.stat(t),We.stat(n)]).then((([i,o])=>{if(Ze(i,o))return r(null);Xe(t,n,e,r)})):Xe(t,n,e,r)}))})),createSymlinkSync:function(t,n,e){let r;try{r=We.lstatSync(n)}catch{}if(r&&r.isSymbolicLink()){const e=We.statSync(t),r=We.statSync(n);if(Ze(e,r))return}const i=qe(t,n);t=i.toDst,e=ze(i.toCwd,e);const o=Be.dirname(n);return We.existsSync(o)||Ge(o),We.symlinkSync(t,n,e)}};const{createFile:tr,createFileSync:nr}=Me,{createLink:er,createLinkSync:rr}=_e,{createSymlink:ir,createSymlinkSync:or}=Qe;var cr={createFile:tr,createFileSync:nr,ensureFile:tr,ensureFileSync:nr,createLink:er,createLinkSync:rr,ensureLink:er,ensureLinkSync:rr,createSymlink:ir,createSymlinkSync:or,ensureSymlink:ir,ensureSymlinkSync:or};var sr={stringify:function(t,{EOL:n="\n",finalEOL:e=!0,replacer:r=null,spaces:i}={}){const o=e?n:"";return JSON.stringify(t,r,i).replace(/\n/g,n)+o},stripBom:function(t){return Buffer.isBuffer(t)&&(t=t.toString("utf8")),t.replace(/^\uFEFF/,"")}};let ur;try{ur=require("graceful-fs")}catch(n){ur=t}const ar=Mt,{stringify:fr,stripBom:lr}=sr;const dr=ar.fromPromise((async function(t,n={}){"string"==typeof n&&(n={encoding:n});const e=n.fs||ur,r=!("throws"in n)||n.throws;let i,o=await ar.fromCallback(e.readFile)(t,n);o=lr(o);try{i=JSON.parse(o,n?n.reviver:null)}catch(n){if(r)throw n.message=`${t}: ${n.message}`,n;return null}return i}));const yr=ar.fromPromise((async function(t,n,e={}){const r=e.fs||ur,i=fr(n,e);await ar.fromCallback(r.writeFile)(t,i,e)}));const hr={readFile:dr,readFileSync:function(t,n={}){"string"==typeof n&&(n={encoding:n});const e=n.fs||ur,r=!("throws"in n)||n.throws;try{let r=e.readFileSync(t,n);return r=lr(r),JSON.parse(r,n.reviver)}catch(n){if(r)throw n.message=`${t}: ${n.message}`,n;return null}},writeFile:yr,writeFileSync:function(t,n,e={}){const r=e.fs||ur,i=fr(n,e);return r.writeFileSync(t,i,e)}};var pr={readJson:hr.readFile,readJsonSync:hr.readFileSync,writeJson:hr.writeFile,writeJsonSync:hr.writeFileSync};const mr=Mt.fromCallback,vr=zt,Sr=i,wr=ln,gr=hn.pathExists;var br={outputFile:mr((function(t,n,e,r){"function"==typeof e&&(r=e,e="utf8");const i=Sr.dirname(t);gr(i,((o,c)=>o?r(o):c?vr.writeFile(t,n,e,r):void wr.mkdirs(i,(i=>{if(i)return r(i);vr.writeFile(t,n,e,r)}))))})),outputFileSync:function(t,...n){const e=Sr.dirname(t);if(vr.existsSync(e))return vr.writeFileSync(t,...n);wr.mkdirsSync(e),vr.writeFileSync(t,...n)}};const{stringify:Er}=sr,{outputFile:kr}=br;var $r=async function(t,n,e={}){const r=Er(n,e);await kr(t,r,e)};const{stringify:Or}=sr,{outputFileSync:Dr}=br;var Mr=function(t,n,e){const r=Or(n,e);Dr(t,r,e)};const Nr=Mt.fromPromise,Fr=pr;Fr.outputJson=Nr($r),Fr.outputJsonSync=Mr,Fr.outputJSON=Fr.outputJson,Fr.outputJSONSync=Fr.outputJsonSync,Fr.writeJSON=Fr.writeJson,Fr.writeJSONSync=Fr.writeJsonSync,Fr.readJSON=Fr.readJson,Fr.readJSONSync=Fr.readJsonSync;var Pr=Fr;const xr=zt,Tr=i,Cr=Zn.copy,_r=he.remove,Lr=ln.mkdirp,jr=hn.pathExists,Ir=On;function Yr(t,n,e,r,i){return r?Ar(t,n,e,i):e?_r(n,(r=>r?i(r):Ar(t,n,e,i))):void jr(n,((r,o)=>r?i(r):o?i(new Error("dest already exists.")):Ar(t,n,e,i)))}function Ar(t,n,e,r){xr.rename(t,n,(i=>i?"EXDEV"!==i.code?r(i):function(t,n,e,r){Cr(t,n,{overwrite:e,errorOnExist:!0},(n=>n?r(n):_r(t,r)))}(t,n,e,r):r()))}var Rr=function(t,n,e,r){"function"==typeof e&&(r=e,e={});const i=e.overwrite||e.clobber||!1;Ir.checkPaths(t,n,"move",e,((e,o)=>{if(e)return r(e);const{srcStat:c,isChangingCase:s=!1}=o;Ir.checkParentPaths(t,c,n,"move",(e=>e?r(e):function(t){const n=Tr.dirname(t);return Tr.parse(n).root===n}(n)?Yr(t,n,i,s,r):void Lr(Tr.dirname(n),(e=>e?r(e):Yr(t,n,i,s,r)))))}))};const Jr=zt,Br=i,Wr=Zn.copySync,Ur=he.removeSync,Gr=ln.mkdirpSync,Hr=On;function qr(t,n,e){try{Jr.renameSync(t,n)}catch(r){if("EXDEV"!==r.code)throw r;return function(t,n,e){return Wr(t,n,{overwrite:e,errorOnExist:true}),Ur(t)}(t,n,e)}}var Vr=function(t,n,e){const r=(e=e||{}).overwrite||e.clobber||!1,{srcStat:i,isChangingCase:o=!1}=Hr.checkPathsSync(t,n,"move",e);return Hr.checkParentPathsSync(t,i,n,"move"),function(t){const n=Br.dirname(t);return Br.parse(n).root===n}(n)||Gr(Br.dirname(n)),function(t,n,e,r){if(r)return qr(t,n,e);if(e)return Ur(n),qr(t,n,e);if(Jr.existsSync(n))throw new Error("dest already exists.");return qr(t,n,e)}(t,n,r,o)};var zr={move:(0,Mt.fromCallback)(Rr),moveSync:Vr},Kr={...Dt,...Zn,...Ee,...cr,...Pr,...ln,...zr,...br,...hn,...he};function Zr(t,n){return void 0===t&&(t=""),void 0===n&&(n=s()),o(n,t)}function Xr(t,n,e){void 0===t&&(t=""),void 0===n&&(n=""),Kr.copySync(t,n,{filter:e})}function Qr(t){void 0===t&&(t=""),Kr.ensureDirSync(t)}function ti(t,r,i){var c;if(void 0===t&&(t="bfs"),void 0===r&&(r=s()),void 0===i&&(i=/(node_modules|\.git|\.DS_Store)$/),"bfs"===t){var u=[],a=[];!i.test(r)&&a.unshift(r);for(var f=function(){var t=null!==(c=a.shift())&&void 0!==c?c:"",r=n(t);if(r&&!i.test(t)){var s=r.isDirectory,f=r.isFile;s()?e(t).forEach((function(n){var e=o(t,n);a.push(e)})):f()&&u.push(t)}};a.length;)f();return u}if("dfs"===t){u=[];var l=n(r);return i.test(r)||(l.isDirectory()?e(r).reduce((function(t,n){var e=ti("dfs",o(r,n),i);return t.push.apply(t,et([],nt(e),!1)),t}),u):l.isFile()&&u.push(r)),u}return[]}function ni(t,n){void 0===t&&(t=""),void 0===n&&(n=s());var e=Zr(t,n),i=c(e);if(!/^\.json$/.test(i))return{};var o=r(e,"utf8");return JSON.parse(o)}function ei(t){void 0===t&&(t=""),Kr.removeSync(t)}function ri(){var t,n="127.0.0.1",e=d();for(var r in e)for(var i=null!==(t=e[r])&&void 0!==t?t:[],o=0;o=n?t:""+Array(n+1-r.length).join(e)+t},w={s:m,z:function(t){var n=-t.utcOffset(),e=Math.abs(n),r=Math.floor(e/60),o=e%60;return(n<=0?"+":"-")+m(r,2,"0")+":"+m(o,2,"0")},m:function t(n,e){if(n.date()1)return t(u[0])}else{var a=n.name;$[a]=n,o=a}return!r&&o&&(y=o),o||!r&&y},M=function(t,n){if(b(t))return t.clone();var e="object"==typeof n?n:{};return e.date=t,e.args=arguments,new D(e)},x=w;x.l=S,x.i=b,x.w=function(t,n){return M(t,{locale:n.$L,utc:n.$u,x:n.$x,$offset:n.$offset})};var D=function(){function p(t){this.$L=S(t.locale,null,!0),this.parse(t)}var m=p.prototype;return m.parse=function(t){this.$d=function(t){var n=t.date,e=t.utc;if(null===n)return new Date(NaN);if(x.u(n))return new Date;if(n instanceof Date)return new Date(n);if("string"==typeof n&&!/Z$/i.test(n)){var r=n.match(g);if(r){var o=r[2]-1||0,i=(r[7]||"0").substring(0,3);return e?new Date(Date.UTC(r[1],o,r[3]||1,r[4]||0,r[5]||0,r[6]||0,i)):new Date(r[1],o,r[3]||1,r[4]||0,r[5]||0,r[6]||0,i)}}return new Date(n)}(t),this.$x=t.x||{},this.init()},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},m.$utils=function(){return x},m.isValid=function(){return!(this.$d.toString()===h)},m.isSame=function(t,n){var e=M(t);return this.startOf(n)<=e&&e<=this.endOf(n)},m.isAfter=function(t,n){return M(t)=0){var r=Math.floor(e/1e3/3600/24),o=Math.floor(e/1e3/60/60%24),i=Math.floor(e/1e3/60%60),u=Math.floor(e/1e3%60),a=r?"".concat(r,"天"):"",c=o?"".concat(o,"时"):"",s=i?"".concat(i,"分"):"",d=u?"".concat(u,"秒"):"";return"".concat(a).concat(c).concat(s).concat(d)}return"时间已到"}function L(t){if(!t)return"时间无效";var n=+new Date,e=+new Date(t),r=n-e,o=r>=0?"前":"后",i=Math.abs(r),u=30.4375,a=36e5,c=24*a,s=i/6e4,d=i/a,f=i/c,l=i/26298e5;return i/315576e5>=1||l>=12?Y(e).format("YYYY-MM-DD HH:mm:ss"):l>=1&&l<12?"".concat(parseInt(l.toString()),"个月").concat(o):f>=1&&f=1&&d<24?"".concat(parseInt(d.toString()),"小时").concat(o):s>=1&&s<60?"".concat(parseInt(s.toString()),"分钟").concat(o):r>=0?"刚刚":"准备"}function C(t,n,e,r){return new(e||(e=Promise))((function(o,i){function u(t){try{c(r.next(t))}catch(t){i(t)}}function a(t){try{c(r.throw(t))}catch(t){i(t)}}function c(t){var n;t.done?o(t.value):(n=t.value,n instanceof e?n:new e((function(t){t(n)}))).then(u,a)}c((r=r.apply(t,n||[])).next())}))}function H(t,n){var e,r,o,i,u={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(e)throw new TypeError("Generator is already executing.");for(;u;)try{if(e=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return u.label++,{value:i[1],done:!1};case 5:u.label++,r=i[1],i=[0];continue;case 7:i=u.ops.pop(),u.trys.pop();continue;default:if(!(o=u.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){u=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0)&&!(r=i.next()).done;)u.push(r.value)}catch(t){o={error:t}}finally{try{r&&!r.done&&(e=i.return)&&e.call(i)}finally{if(o)throw o.error}}return u}function N(t,n,e){if(e||2===arguments.length)for(var r,o=0,i=n.length;o=n&&(t.apply(i,u),o=Date.now())}),Math.max(n-(Date.now()-o),0))):(t.apply(this,u),o=Date.now(),r=!0)}}function W(t){return void 0===t&&(t=1e3),C(this,void 0,void 0,(function(){return H(this,(function(n){switch(n.label){case 0:return[4,new Promise((function(n){return setTimeout((function(){return n(!0)}),t)}))];case 1:return[2,n.sent()]}}))}))}function q(t,n){return void 0===t&&(t=0),void 0===n&&(n=0),t.toString().padStart(n,"0")}function J(t){if(void 0===t&&(t=0),0===t)return"0 B";var n=Math.floor(Math.log(t)/Math.log(1024));return(t/Math.pow(1024,n)).toPrecision(3)+" "+["B","KB","MB","GB","TB","PB","EB","ZB","YB"][n]}function U(t,n){return void 0===t&&(t=0),void 0===n&&(n=10),Math.floor(Math.random()*(n-t+1)+t)}function Z(t,n,e){void 0===t&&(t=0),void 0===n&&(n=10),void 0===e&&(e=1);for(var r=[];;){for(var o=!1,i=U(t,n),u=0;u10)&&(t=5),Math.random().toString(36).substr(3,t)}function ut(t){return void 0===t&&(t=""),t.replace(/<[^>]*>/g,"")}function at(t){return void 0===t&&(t=""),t.split("").reduceRight((function(t,n){return t+n}))}function ct(t,n){return void 0===t&&(t=0),void 0===n&&(n=5),t<0&&(t=0),t>n&&(t=n),N(N([],B(new Array(n).fill("★")),!1),B(new Array(n).fill("☆")),!1).join("").slice(n-t,2*n-t)}function st(){var t=document.cookie;return t?t.split("; ").reduce((function(t,n){var e=n.split("=");return t[e[0]]=e[1],t}),{}):{}}function dt(t){void 0===t&&(t=""),ft(t,"",-1)}function ft(t,n,e){void 0===t&&(t=""),void 0===n&&(n=""),void 0===e&&(e=1);var r=new Date;r.setDate(r.getDate()+e),document.cookie="".concat(t,"=").concat(n,";expires=").concat(r.toString())}function lt(t){void 0===t&&(t=750);var n=document.documentElement;n.clientWidth>=600?n.style.fontSize="80px":n.style.fontSize="".concat(n.clientWidth/t*100,"px")}function ht(t){void 0===t&&(t=document.body);var n=t.childNodes.length,e=document.createRange(),r=getSelection();r&&(e.setStart(t,0),e.setEnd(t,n),r.removeAllRanges(),r.addRange(e),document.execCommand("copy",!1),r.removeRange(e))}function gt(t,n){void 0===t&&(t=""),void 0===n&&(n="");var e=document.createElement("a"),r=document.createEvent("MouseEvents");e.setAttribute("href",t),e.setAttribute("download",n),e.click(),e.dispatchEvent(r)}function vt(t){void 0===t&&(t="");var n=document.createElement("div");return n.innerText=t,n.innerHTML}function pt(t,n){return void 0===t&&(t=""),void 0===n&&(n="jpg"),C(this,void 0,void 0,(function(){var e,r,o,i;return H(this,(function(u){switch(u.label){case 0:return e=new Promise((function(e,r){var o=new Image;"jpg"===n&&(n="jpeg"),o.setAttribute("src",t),o.setAttribute("crossOrigin",""),o.addEventListener("load",(function(){var t,r=document.createElement("canvas");if(r){r.setAttribute("width","".concat(o.width,"px")),r.setAttribute("height","".concat(o.height,"px")),null===(t=r.getContext("2d"))||void 0===t||t.drawImage(o,0,0);var i=r.toDataURL('"image/'.concat(n,'"'));e(i)}else e("")})),o.addEventListener("error",(function(){return r(new Error("error"))}))})),[4,P(e)];case 1:return r=B.apply(void 0,[u.sent(),2]),o=r[0],i=r[1],[2,!o&&i?i:""]}}))}))}function mt(t,n,e){return void 0===t&&(t=""),void 0===n&&(n="jsonp"),void 0===e&&(e=null),C(this,void 0,void 0,(function(){var r,o,i;return H(this,(function(u){switch(u.label){case 0:return[4,P(new Promise((function(r,o){var i=document.createElement("script");i.setAttribute("src",t),i.setAttribute("async","true"),i.addEventListener("load",(function(){return r(!0)})),i.addEventListener("error",(function(){return o(new Error("error"))})),window[n]=function(t){return null==e?void 0:e(t)},document.body.appendChild(i)})))];case 1:return r=B.apply(void 0,[u.sent(),2]),o=r[0],i=r[1],[2,!o&&!!i]}}))}))}function wt(t,n){return void 0===t&&(t=""),void 0===n&&(n="body"),C(this,void 0,void 0,(function(){var e,r,o;return H(this,(function(i){switch(i.label){case 0:return[4,P(new Promise((function(e,r){N([],B(document.getElementsByTagName("script")),!1).some((function(n){return n.src===t||n.src.includes(t)}))&&r(new Error("<".concat(n,">已存在").concat(t,"该脚本")));var o=document.createElement("script");o.setAttribute("src",t),o.addEventListener("load",(function(){return e(!0)})),o.addEventListener("error",(function(){return r(new Error("error"))})),"head"===n&&document.head.appendChild(o),"body"===n&&document.body.appendChild(o)})))];case 1:return e=B.apply(void 0,[i.sent(),2]),r=e[0],o=e[1],[2,!r&&!!o]}}))}))}function yt(){var t=location.search;return t?t.replace(/(^\?)|(&$)/g,"").split("&").reduce((function(t,n){var e=B(n.split("="),2),r=e[0],o=e[1];return t[r]=decodeURIComponent(o),t}),{}):{}}function $t(){for(var t=[],n=0;n=e?t:""+Array(e+1-r.length).join(n)+t},w={s:m,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),o=n%60;return(e<=0?"+":"-")+m(r,2,"0")+":"+m(o,2,"0")},m:function t(e,n){if(e.date()1)return t(s[0])}else{var u=e.name;y[u]=e,o=u}return!r&&o&&(x=o),o||!r&&x},b=function(t,e){if(S(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new D(n)},M=w;M.l=$,M.i=S,M.w=function(t,e){return b(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var D=function(){function v(t){this.$L=$(t.locale,null,!0),this.parse(t)}var m=v.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(M.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match(h);if(r){var o=r[2]-1||0,i=(r[7]||"0").substring(0,3);return n?new Date(Date.UTC(r[1],o,r[3]||1,r[4]||0,r[5]||0,r[6]||0,i)):new Date(r[1],o,r[3]||1,r[4]||0,r[5]||0,r[6]||0,i)}}return new Date(e)}(t),this.$x=t.x||{},this.init()},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},m.$utils=function(){return M},m.isValid=function(){return!(this.$d.toString()===p)},m.isSame=function(t,e){var n=b(t);return this.startOf(e)<=n&&n<=this.endOf(e)},m.isAfter=function(t,e){return b(t)0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0)&&!(r=i.next()).done;)s.push(r.value)}catch(t){o={error:t}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return s}function f(t,e,n){if(n||2===arguments.length)for(var r,o=0,i=e.length;o=600?e.style.fontSize="80px":e.style.fontSize="".concat(e.clientWidth/t*100,"px")},exports.CheckText=function(t,e){void 0===t&&(t=""),void 0===e&&(e="");var n=h[t],r=n.regexp,o=n.msg,i=r.test(e);return{flag:i,msg:i?"":o}},exports.CheckTextPlus=function(t,e,n){void 0===e&&(e=""),void 0===n&&(n="");var r=t.test(e);return{flag:r,msg:r?"":n}},exports.ClearLStorage=function(){localStorage.clear()},exports.ClearSStorage=function(){sessionStorage.clear()},exports.CopyPaste=function(t){void 0===t&&(t=document.body);var e=t.childNodes.length,n=document.createRange(),r=getSelection();r&&(n.setStart(t,0),n.setEnd(t,e),r.removeAllRanges(),r.addRange(n),document.execCommand("copy",!1),r.removeRange(n))},exports.Debounce=function(t,e){var n;return void 0===e&&(e=50),function(){for(var r=this,o=[],i=0;i=0){var r=Math.floor(n/1e3/3600/24),o=Math.floor(n/1e3/60/60%24),i=Math.floor(n/1e3/60%60),s=Math.floor(n/1e3%60),u=r?"".concat(r,"天"):"",a=o?"".concat(o,"时"):"",c=i?"".concat(i,"分"):"",d=s?"".concat(s,"秒"):"";return"".concat(u).concat(a).concat(c).concat(d)}return"时间已到"},exports.FormatPhone=function(t,e){return void 0===t&&(t=""),void 0===e&&(e="-"),h.phone.regexp.test(t)&&["-"," "].includes(e)?t.toString().replace(/(\d{3})(\d{4})(\d{4})/g,"$1".concat(e,"$2").concat(e,"$3")):t},exports.FormatTimeDiff=function(t){if(!t)return"时间无效";var e=+new Date,n=+new Date(t),r=e-n,o=r>=0?"前":"后",i=Math.abs(r),s=30.4375,a=36e5,c=24*a,d=i/6e4,f=i/a,l=i/c,p=i/26298e5;return i/315576e5>=1||p>=12?u(n).format("YYYY-MM-DD HH:mm:ss"):p>=1&&p<12?"".concat(parseInt(p.toString()),"个月").concat(o):l>=1&&l=1&&f<24?"".concat(parseInt(f.toString()),"小时").concat(o):d>=1&&d<60?"".concat(parseInt(d.toString()),"分钟").concat(o):r>=0?"刚刚":"准备"},exports.GetCookie=function(){var t=document.cookie;return t?t.split("; ").reduce((function(t,e){var n=e.split("=");return t[n[0]]=n[1],t}),{}):{}},exports.GetLStorage=function(t){void 0===t&&(t="");var e=localStorage.getItem(t);return e?JSON.parse(e):null},exports.GetSStorage=function(t){void 0===t&&(t="");var e=sessionStorage.getItem(t);return e?JSON.parse(e):null},exports.GroupArrKey=function(t,e){return void 0===t&&(t=[]),void 0===e&&(e=""),e?t.reduce((function(t,n){return!t[n[e]]&&(t[n[e]]=[]),t[n[e]].push(n),t}),{}):{}},exports.Img2Base64=function(t,e){return void 0===t&&(t=""),void 0===e&&(e="jpg"),a(this,void 0,void 0,(function(){var n,r,o,i;return c(this,(function(s){switch(s.label){case 0:return n=new Promise((function(n,r){var o=new Image;"jpg"===e&&(e="jpeg"),o.setAttribute("src",t),o.setAttribute("crossOrigin",""),o.addEventListener("load",(function(){var t,r=document.createElement("canvas");if(r){r.setAttribute("width","".concat(o.width,"px")),r.setAttribute("height","".concat(o.height,"px")),null===(t=r.getContext("2d"))||void 0===t||t.drawImage(o,0,0);var i=r.toDataURL('"image/'.concat(e,'"'));n(i)}else n("")})),o.addEventListener("error",(function(){return r(new Error("error"))}))})),[4,l(n)];case 1:return r=d.apply(void 0,[s.sent(),2]),o=r[0],i=r[1],[2,!o&&i?i:""]}}))}))},exports.IsArguments=function(t){return"arguments"===e(t)},exports.IsArray=function(t){return"array"===e(t)},exports.IsAsyncFunction=function(t){return"asyncfunction"===e(t)},exports.IsBoolean=function(t){return"boolean"===e(t)},exports.IsClass=function(t){return r(t)&&/^class\s+[\dA-Za-z]/.test(t.toString())},exports.IsDate=function(t){return"date"===e(t)},exports.IsElement=function(t){return/^html(.+?)element$/.test(e(t))},exports.IsEmpty=function(t){return!t},exports.IsEmptyArray=o,exports.IsEmptyObject=i,exports.IsError=function(t){return t instanceof Error},exports.IsFunction=r,exports.IsMap=function(t){return"map"===e(t)},exports.IsNode=function(){return"node"===t()},exports.IsNull=function(t){return"null"===e(t)},exports.IsNumber=function(t){return"number"===e(t)},exports.IsObject=n,exports.IsRegExp=function(t){return"regexp"===e(t)},exports.IsSet=function(t){return"set"===e(t)},exports.IsString=function(t){return"string"===e(t)},exports.IsSymbol=function(t){return"symbol"===e(t)},exports.IsSyncFunction=function(t){return"function"===e(t)},exports.IsUndefined=function(t){return"undefined"===e(t)},exports.IsWeakMap=function(t){return"weakmap"===e(t)},exports.IsWeakSet=function(t){return"weakset"===e(t)},exports.IsWeb=function(){return"web"===t()},exports.Jsonp=function(t,e,n){return void 0===t&&(t=""),void 0===e&&(e="jsonp"),void 0===n&&(n=null),a(this,void 0,void 0,(function(){var r,o,i;return c(this,(function(s){switch(s.label){case 0:return[4,l(new Promise((function(r,o){var i=document.createElement("script");i.setAttribute("src",t),i.setAttribute("async","true"),i.addEventListener("load",(function(){return r(!0)})),i.addEventListener("error",(function(){return o(new Error("error"))})),window[e]=function(t){return null==n?void 0:n(t)},document.body.appendChild(i)})))];case 1:return r=d.apply(void 0,[s.sent(),2]),o=r[0],i=r[1],[2,!o&&!!i]}}))}))},exports.LoadScript=function(t,e){return void 0===t&&(t=""),void 0===e&&(e="body"),a(this,void 0,void 0,(function(){var n,r,o;return c(this,(function(i){switch(i.label){case 0:return[4,l(new Promise((function(n,r){f([],d(document.getElementsByTagName("script")),!1).some((function(e){return e.src===t||e.src.includes(t)}))&&r(new Error("<".concat(e,">已存在").concat(t,"该脚本")));var o=document.createElement("script");o.setAttribute("src",t),o.addEventListener("load",(function(){return n(!0)})),o.addEventListener("error",(function(){return r(new Error("error"))})),"head"===e&&document.head.appendChild(o),"body"===e&&document.body.appendChild(o)})))];case 1:return n=d.apply(void 0,[i.sent(),2]),r=n[0],o=n[1],[2,!r&&!!o]}}))}))},exports.MatchBracketText=function(t,e){var n;void 0===t&&(t="(*)"),void 0===e&&(e="");var r=t.split("*").map((function(t){return g.includes(t)?"\\"+t:t})),o=new RegExp(r[0]+"(.+?)"+r[1],"g");return(null!==(n=e.match(o))&&void 0!==n?n:[]).map((function(t){return t.replace(o,"$1")}))},exports.ParseUrlSearch=m,exports.RandomColor=function(){return"#"+Math.floor(16777215*Math.random()).toString(16).padEnd(6,"0")},exports.RandomId=function(t){return void 0===t&&(t=5),(t<1||t>10)&&(t=5),Math.random().toString(36).substr(3,t)},exports.RandomNum=p,exports.RandomNumPlus=function(t,e,n){void 0===t&&(t=0),void 0===e&&(e=10),void 0===n&&(n=1);for(var r=[];;){for(var o=!1,i=p(t,e),s=0;s]*>/g,"")},exports.RemoveUrlSearch=function(){for(var t=[],e=0;ee&&(t=e),f(f([],d(new Array(e).fill("★")),!1),d(new Array(e).fill("☆")),!1).join("").slice(e-t,2*e-t)},exports.StatArrCount=function(t){return void 0===t&&(t=[]),t.reduce((function(t,e){return t[e]=(t[e]||0)+1,t}),{})},exports.StatArrKeyword=function(t,e){return void 0===t&&(t=[]),void 0===e&&(e=[]),e.reduce((function(e,n){return t.some((function(t){return t.includes(n)}))&&e.push(n),e}),[])},exports.StringifyUrlSearch=w,exports.ThousandNum=function(t){return void 0===t&&(t=0),t.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")},exports.Throttle=function(t,e){var n;void 0===e&&(e=50);var r=!1,o=0;return function(){for(var i=this,s=[],u=0;u=e&&(t.apply(i,s),o=Date.now())}),Math.max(e-(Date.now()-o),0))):(t.apply(this,s),o=Date.now(),r=!0)}},exports.TypeOf=e,exports.WaitFor=function(t){return void 0===t&&(t=1e3),a(this,void 0,void 0,(function(){return c(this,(function(e){switch(e.label){case 0:return[4,new Promise((function(e){return setTimeout((function(){return e(!0)}),t)}))];case 1:return[2,e.sent()]}}))}))},exports.WebType=function(t){var e,n,r,o;void 0===t&&(t=navigator.userAgent.toLowerCase());var i=function(e){return e.test(t)},s=function(e){var n;return e?(null!==(n=t.match(e))&&void 0!==n?n:"").toString().replace(/[^0-9|_.]/g,"").replace(/_/g,"."):"unknow"},u={windows:/windows|win32|win64|wow32|wow64/g,macos:/macintosh|macintel/g,linux:/x11/g,android:/android|adr/g,ios:/ios|iphone|ipad|ipod|iwatch/g},a=null!==(e=Object.keys(u).find((function(t){return i(u[t])})))&&void 0!==e?e:"unknow",c="unknow"===a?"unknow version":"windows"===a?function(){var e,n,r=(null!==(e=t.match(/(windows nt [\d._]+)|(windows [\w._]+)/g))&&void 0!==e?e:"").toString().replace(/windows( nt)? /g,""),o={2e3:/^(5\.0|2000)/g,xp:/^(5\.1|xp)/g,2003:/^(5\.2|2003)/g,vista:/^(6\.0|vista)/g,7:/^(6\.1|7)/g,8:/^(6\.2|8)/g,8.1:/^(6\.3|8\.1)/g,10:/^(10\.0|10)/g};return null!==(n=Object.keys(o).find((function(t){return o[t].test(r)})))&&void 0!==n?n:"unknow"}():s({macos:/os x [\d._]+/g,android:/android [\d._]+/g,ios:/os [\d._]+/g}[a]),d={desktop:["windows","macos","linux"],mobile:["android","ios"]},f=i(/mobile/g)?"mobile":null!==(n=Object.keys(d).find((function(t){return d[t].includes(a)})))&&void 0!==n?n:"unknow",l={webkit:[/applewebkit/g,/applewebkit\/[\d._]+/g],gecko:[/(?=.*gecko)(?=.*firefox)/g,/gecko\/[\d._]+/g],presto:[/presto/g,/presto\/[\d._]+/g],trident:[/trident|compatible|msie/g,/trident\/[\d._]+/g]},p=null!==(r=Object.keys(l).find((function(t){return i(l[t][0])})))&&void 0!==r?r:"unknow",h="unknow"===p?"unknow version":s(l[p][1]),g={gecko:"firefox",presto:"opera",trident:"iexplore"},v=g[p]?"webkit"===p?function(){var t,e={edge:/edge/g,opera:/opr/g,chrome:/chrome/g,safari:/safari/g};return null!==(t=Object.keys(e).find((function(t){return i(e[t])})))&&void 0!==t?t:"unknow"}():g[p]:"unknow",m=s({chrome:/chrome\/[\d._]+/g,safari:/version\/[\d._]+/g,firefox:/firefox\/[\d._]+/g,opera:/opr\/[\d._]+/g,iexplore:/(msie [\d._]+)|(rv:[\d._]+)/g,edge:/edge\/[\d._]+/g}[v]),w={wechat:[/micromessenger/g,/micromessenger\/[\d._]+/g],qq:[/qqbrowser/g,/qqbrowser\/[\d._]+/g],uc:[/ucbrowser/g,/ucbrowser\/[\d._]+/g],360:[/qihu 360se/g],2345:[/2345explorer/g,/2345explorer\/[\d._]+/g],sougou:[/metasr/g],liebao:[/lbbrowser/g],maxthon:[/maxthon/g,/maxthon\/[\d._]+/g]},x=null!==(o=Object.keys(w).find((function(t){return i(w[t][0])})))&&void 0!==o?o:"none",y="none"===x?"none":w[x][1]?s(w[x][1]):"unknow version";return Object.assign({engine:p,engineVs:h,platform:f,supporter:v,supporterVs:m,system:a,systemVs:c},"none"===x?{}:{shell:x,shellVs:y})}; 2 | -------------------------------------------------------------------------------- /js-lib/bruce-us/dist/web.umd.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).BruceUs=e()}(this,(function(){"use strict";function t(){return"undefined"!=typeof window?"web":"undefined"!=typeof global?"node":"unknow"}function e(t){return Object.prototype.toString.call(t).replace(/\[object (\w+)\]/,"$1").toLowerCase()}function n(t){return"object"===e(t)}function r(t){return"function"===e(t)}function o(t){return Array.isArray(t)&&!t.length}function i(t){return n(t)&&!Object.keys(t).length}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var u={exports:{}};!function(t,e){t.exports=function(){var t=1e3,e=6e4,n=36e5,r="millisecond",o="second",i="minute",u="hour",a="day",s="week",c="month",d="quarter",f="year",l="date",h="Invalid Date",g=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,v=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,p={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_")},m=function(t,e,n){var r=String(t);return!r||r.length>=e?t:""+Array(e+1-r.length).join(n)+t},w={s:m,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),o=n%60;return(e<=0?"+":"-")+m(r,2,"0")+":"+m(o,2,"0")},m:function t(e,n){if(e.date()1)return t(u[0])}else{var a=e.name;S[a]=e,o=a}return!r&&o&&(y=o),o||!r&&y},M=function(t,e){if($(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new D(n)},x=w;x.l=b,x.i=$,x.w=function(t,e){return M(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var D=function(){function p(t){this.$L=b(t.locale,null,!0),this.parse(t)}var m=p.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(x.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match(g);if(r){var o=r[2]-1||0,i=(r[7]||"0").substring(0,3);return n?new Date(Date.UTC(r[1],o,r[3]||1,r[4]||0,r[5]||0,r[6]||0,i)):new Date(r[1],o,r[3]||1,r[4]||0,r[5]||0,r[6]||0,i)}}return new Date(e)}(t),this.$x=t.x||{},this.init()},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},m.$utils=function(){return x},m.isValid=function(){return!(this.$d.toString()===h)},m.isSame=function(t,e){var n=M(t);return this.startOf(e)<=n&&n<=this.endOf(e)},m.isAfter=function(t,e){return M(t)0&&o[o.length-1])||6!==i[0]&&2!==i[0])){u=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0)&&!(r=i.next()).done;)u.push(r.value)}catch(t){o={error:t}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return u}function f(t,e,n){if(n||2===arguments.length)for(var r,o=0,i=e.length;o=600?e.style.fontSize="80px":e.style.fontSize="".concat(e.clientWidth/t*100,"px")},CheckText:function(t,e){void 0===t&&(t=""),void 0===e&&(e="");var n=g[t],r=n.regexp,o=n.msg,i=r.test(e);return{flag:i,msg:i?"":o}},CheckTextPlus:function(t,e,n){void 0===e&&(e=""),void 0===n&&(n="");var r=t.test(e);return{flag:r,msg:r?"":n}},ClearLStorage:function(){localStorage.clear()},ClearSStorage:function(){sessionStorage.clear()},CopyPaste:function(t){void 0===t&&(t=document.body);var e=t.childNodes.length,n=document.createRange(),r=getSelection();r&&(n.setStart(t,0),n.setEnd(t,e),r.removeAllRanges(),r.addRange(n),document.execCommand("copy",!1),r.removeRange(n))},Debounce:function(t,e){var n;return void 0===e&&(e=50),function(){for(var r=this,o=[],i=0;i=0){var r=Math.floor(n/1e3/3600/24),o=Math.floor(n/1e3/60/60%24),i=Math.floor(n/1e3/60%60),u=Math.floor(n/1e3%60),a=r?"".concat(r,"天"):"",s=o?"".concat(o,"时"):"",c=i?"".concat(i,"分"):"",d=u?"".concat(u,"秒"):"";return"".concat(a).concat(s).concat(c).concat(d)}return"时间已到"},FormatPhone:function(t,e){return void 0===t&&(t=""),void 0===e&&(e="-"),g.phone.regexp.test(t)&&["-"," "].includes(e)?t.toString().replace(/(\d{3})(\d{4})(\d{4})/g,"$1".concat(e,"$2").concat(e,"$3")):t},FormatTimeDiff:function(t){if(!t)return"时间无效";var e=+new Date,n=+new Date(t),r=e-n,o=r>=0?"前":"后",i=Math.abs(r),u=30.4375,s=36e5,c=24*s,d=i/6e4,f=i/s,l=i/c,h=i/26298e5;return i/315576e5>=1||h>=12?a(n).format("YYYY-MM-DD HH:mm:ss"):h>=1&&h<12?"".concat(parseInt(h.toString()),"个月").concat(o):l>=1&&l=1&&f<24?"".concat(parseInt(f.toString()),"小时").concat(o):d>=1&&d<60?"".concat(parseInt(d.toString()),"分钟").concat(o):r>=0?"刚刚":"准备"},GetCookie:function(){var t=document.cookie;return t?t.split("; ").reduce((function(t,e){var n=e.split("=");return t[n[0]]=n[1],t}),{}):{}},GetLStorage:function(t){void 0===t&&(t="");var e=localStorage.getItem(t);return e?JSON.parse(e):null},GetSStorage:function(t){void 0===t&&(t="");var e=sessionStorage.getItem(t);return e?JSON.parse(e):null},GroupArrKey:function(t,e){return void 0===t&&(t=[]),void 0===e&&(e=""),e?t.reduce((function(t,n){return!t[n[e]]&&(t[n[e]]=[]),t[n[e]].push(n),t}),{}):{}},Img2Base64:function(t,e){return void 0===t&&(t=""),void 0===e&&(e="jpg"),s(this,void 0,void 0,(function(){var n,r,o,i;return c(this,(function(u){switch(u.label){case 0:return n=new Promise((function(n,r){var o=new Image;"jpg"===e&&(e="jpeg"),o.setAttribute("src",t),o.setAttribute("crossOrigin",""),o.addEventListener("load",(function(){var t,r=document.createElement("canvas");if(r){r.setAttribute("width","".concat(o.width,"px")),r.setAttribute("height","".concat(o.height,"px")),null===(t=r.getContext("2d"))||void 0===t||t.drawImage(o,0,0);var i=r.toDataURL('"image/'.concat(e,'"'));n(i)}else n("")})),o.addEventListener("error",(function(){return r(new Error("error"))}))})),[4,l(n)];case 1:return r=d.apply(void 0,[u.sent(),2]),o=r[0],i=r[1],[2,!o&&i?i:""]}}))}))},IsArguments:function(t){return"arguments"===e(t)},IsArray:function(t){return"array"===e(t)},IsAsyncFunction:function(t){return"asyncfunction"===e(t)},IsBoolean:function(t){return"boolean"===e(t)},IsClass:function(t){return r(t)&&/^class\s+[\dA-Za-z]/.test(t.toString())},IsDate:function(t){return"date"===e(t)},IsElement:function(t){return/^html(.+?)element$/.test(e(t))},IsEmpty:function(t){return!t},IsEmptyArray:o,IsEmptyObject:i,IsError:function(t){return t instanceof Error},IsFunction:r,IsMap:function(t){return"map"===e(t)},IsNode:function(){return"node"===t()},IsNull:function(t){return"null"===e(t)},IsNumber:function(t){return"number"===e(t)},IsObject:n,IsRegExp:function(t){return"regexp"===e(t)},IsSet:function(t){return"set"===e(t)},IsString:function(t){return"string"===e(t)},IsSymbol:function(t){return"symbol"===e(t)},IsSyncFunction:function(t){return"function"===e(t)},IsUndefined:function(t){return"undefined"===e(t)},IsWeakMap:function(t){return"weakmap"===e(t)},IsWeakSet:function(t){return"weakset"===e(t)},IsWeb:function(){return"web"===t()},Jsonp:function(t,e,n){return void 0===t&&(t=""),void 0===e&&(e="jsonp"),void 0===n&&(n=null),s(this,void 0,void 0,(function(){var r,o,i;return c(this,(function(u){switch(u.label){case 0:return[4,l(new Promise((function(r,o){var i=document.createElement("script");i.setAttribute("src",t),i.setAttribute("async","true"),i.addEventListener("load",(function(){return r(!0)})),i.addEventListener("error",(function(){return o(new Error("error"))})),window[e]=function(t){return null==n?void 0:n(t)},document.body.appendChild(i)})))];case 1:return r=d.apply(void 0,[u.sent(),2]),o=r[0],i=r[1],[2,!o&&!!i]}}))}))},LoadScript:function(t,e){return void 0===t&&(t=""),void 0===e&&(e="body"),s(this,void 0,void 0,(function(){var n,r,o;return c(this,(function(i){switch(i.label){case 0:return[4,l(new Promise((function(n,r){f([],d(document.getElementsByTagName("script")),!1).some((function(e){return e.src===t||e.src.includes(t)}))&&r(new Error("<".concat(e,">已存在").concat(t,"该脚本")));var o=document.createElement("script");o.setAttribute("src",t),o.addEventListener("load",(function(){return n(!0)})),o.addEventListener("error",(function(){return r(new Error("error"))})),"head"===e&&document.head.appendChild(o),"body"===e&&document.body.appendChild(o)})))];case 1:return n=d.apply(void 0,[i.sent(),2]),r=n[0],o=n[1],[2,!r&&!!o]}}))}))},MatchBracketText:function(t,e){var n;void 0===t&&(t="(*)"),void 0===e&&(e="");var r=t.split("*").map((function(t){return v.includes(t)?"\\"+t:t})),o=new RegExp(r[0]+"(.+?)"+r[1],"g");return(null!==(n=e.match(o))&&void 0!==n?n:[]).map((function(t){return t.replace(o,"$1")}))},ParseUrlSearch:m,RandomColor:function(){return"#"+Math.floor(16777215*Math.random()).toString(16).padEnd(6,"0")},RandomId:function(t){return void 0===t&&(t=5),(t<1||t>10)&&(t=5),Math.random().toString(36).substr(3,t)},RandomNum:h,RandomNumPlus:function(t,e,n){void 0===t&&(t=0),void 0===e&&(e=10),void 0===n&&(n=1);for(var r=[];;){for(var o=!1,i=h(t,e),u=0;u]*>/g,"")},RemoveUrlSearch:function(){for(var t=[],e=0;ee&&(t=e),f(f([],d(new Array(e).fill("★")),!1),d(new Array(e).fill("☆")),!1).join("").slice(e-t,2*e-t)},StatArrCount:function(t){return void 0===t&&(t=[]),t.reduce((function(t,e){return t[e]=(t[e]||0)+1,t}),{})},StatArrKeyword:function(t,e){return void 0===t&&(t=[]),void 0===e&&(e=[]),e.reduce((function(e,n){return t.some((function(t){return t.includes(n)}))&&e.push(n),e}),[])},StringifyUrlSearch:w,ThousandNum:function(t){return void 0===t&&(t=0),t.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")},Throttle:function(t,e){var n;void 0===e&&(e=50);var r=!1,o=0;return function(){for(var i=this,u=[],a=0;a=e&&(t.apply(i,u),o=Date.now())}),Math.max(e-(Date.now()-o),0))):(t.apply(this,u),o=Date.now(),r=!0)}},TypeOf:e,WaitFor:function(t){return void 0===t&&(t=1e3),s(this,void 0,void 0,(function(){return c(this,(function(e){switch(e.label){case 0:return[4,new Promise((function(e){return setTimeout((function(){return e(!0)}),t)}))];case 1:return[2,e.sent()]}}))}))},WebType:function(t){var e,n,r,o;void 0===t&&(t=navigator.userAgent.toLowerCase());var i=function(e){return e.test(t)},u=function(e){var n;return e?(null!==(n=t.match(e))&&void 0!==n?n:"").toString().replace(/[^0-9|_.]/g,"").replace(/_/g,"."):"unknow"},a={windows:/windows|win32|win64|wow32|wow64/g,macos:/macintosh|macintel/g,linux:/x11/g,android:/android|adr/g,ios:/ios|iphone|ipad|ipod|iwatch/g},s=null!==(e=Object.keys(a).find((function(t){return i(a[t])})))&&void 0!==e?e:"unknow",c="unknow"===s?"unknow version":"windows"===s?function(){var e,n,r=(null!==(e=t.match(/(windows nt [\d._]+)|(windows [\w._]+)/g))&&void 0!==e?e:"").toString().replace(/windows( nt)? /g,""),o={2e3:/^(5\.0|2000)/g,xp:/^(5\.1|xp)/g,2003:/^(5\.2|2003)/g,vista:/^(6\.0|vista)/g,7:/^(6\.1|7)/g,8:/^(6\.2|8)/g,8.1:/^(6\.3|8\.1)/g,10:/^(10\.0|10)/g};return null!==(n=Object.keys(o).find((function(t){return o[t].test(r)})))&&void 0!==n?n:"unknow"}():u({macos:/os x [\d._]+/g,android:/android [\d._]+/g,ios:/os [\d._]+/g}[s]),d={desktop:["windows","macos","linux"],mobile:["android","ios"]},f=i(/mobile/g)?"mobile":null!==(n=Object.keys(d).find((function(t){return d[t].includes(s)})))&&void 0!==n?n:"unknow",l={webkit:[/applewebkit/g,/applewebkit\/[\d._]+/g],gecko:[/(?=.*gecko)(?=.*firefox)/g,/gecko\/[\d._]+/g],presto:[/presto/g,/presto\/[\d._]+/g],trident:[/trident|compatible|msie/g,/trident\/[\d._]+/g]},h=null!==(r=Object.keys(l).find((function(t){return i(l[t][0])})))&&void 0!==r?r:"unknow",g="unknow"===h?"unknow version":u(l[h][1]),v={gecko:"firefox",presto:"opera",trident:"iexplore"},p=v[h]?"webkit"===h?function(){var t,e={edge:/edge/g,opera:/opr/g,chrome:/chrome/g,safari:/safari/g};return null!==(t=Object.keys(e).find((function(t){return i(e[t])})))&&void 0!==t?t:"unknow"}():v[h]:"unknow",m=u({chrome:/chrome\/[\d._]+/g,safari:/version\/[\d._]+/g,firefox:/firefox\/[\d._]+/g,opera:/opr\/[\d._]+/g,iexplore:/(msie [\d._]+)|(rv:[\d._]+)/g,edge:/edge\/[\d._]+/g}[p]),w={wechat:[/micromessenger/g,/micromessenger\/[\d._]+/g],qq:[/qqbrowser/g,/qqbrowser\/[\d._]+/g],uc:[/ucbrowser/g,/ucbrowser\/[\d._]+/g],360:[/qihu 360se/g],2345:[/2345explorer/g,/2345explorer\/[\d._]+/g],sougou:[/metasr/g],liebao:[/lbbrowser/g],maxthon:[/maxthon/g,/maxthon\/[\d._]+/g]},y=null!==(o=Object.keys(w).find((function(t){return i(w[t][0])})))&&void 0!==o?o:"none",S="none"===y?"none":w[y][1]?u(w[y][1]):"unknow version";return Object.assign({engine:h,engineVs:g,platform:f,supporter:p,supporterVs:m,system:s,systemVs:c},"none"===y?{}:{shell:y,shellVs:S})}};return y})); 2 | -------------------------------------------------------------------------------- /js-lib/bruce-us/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bruce-us", 3 | "version": "1.0.0", 4 | "description": "A Web/Node General Util Set", 5 | "keywords": [ 6 | "bruce-us", 7 | "util", 8 | "tool", 9 | "set", 10 | "common", 11 | "node", 12 | "web", 13 | "array", 14 | "boolean", 15 | "cookie", 16 | "date", 17 | "dom", 18 | "fs", 19 | "function", 20 | "number", 21 | "object", 22 | "os", 23 | "process", 24 | "regexp", 25 | "storage", 26 | "string", 27 | "type", 28 | "url" 29 | ], 30 | "license": "MIT", 31 | "main": "dist/web.js", 32 | "jsnext:main": "dist/web.esm.js", 33 | "module": "dist/web.esm.js", 34 | "browser": "dist/web.umd.js", 35 | "types": "dist/index.d.ts", 36 | "scripts": { 37 | "build": "rollup -c", 38 | "clean": "rimraf coverage dist node_modules package-lock.json yarn.lock", 39 | "test": "jest --coverage" 40 | }, 41 | "engines": { 42 | "node": ">=12.0.0", 43 | "npm": ">=6.9.0" 44 | }, 45 | "dependencies": { 46 | "dayjs": "1.11.2", 47 | "fs-extra": "10.1.0" 48 | }, 49 | "devDependencies": { 50 | "@rollup/plugin-commonjs": "22.0.0", 51 | "@rollup/plugin-node-resolve": "13.3.0", 52 | "@rollup/plugin-typescript": "8.3.2", 53 | "@types/fs-extra": "9.0.13", 54 | "@types/jest": "27.5.0", 55 | "@types/node": "17.0.31", 56 | "jest": "28.1.0", 57 | "rollup": "2.72.1", 58 | "rollup-plugin-cleandir": "2.0.0", 59 | "rollup-plugin-dts": "4.2.1", 60 | "rollup-plugin-terser": "7.0.2", 61 | "ts-jest": "28.0.2", 62 | "tslib": "2.4.0", 63 | "typescript": "4.6.4" 64 | } 65 | } -------------------------------------------------------------------------------- /js-lib/bruce-us/rollup.config.js: -------------------------------------------------------------------------------- 1 | import CommonjsPlugin from "@rollup/plugin-commonjs"; 2 | import NodeResolvePlugin from "@rollup/plugin-node-resolve"; 3 | import TypescriptPlugin from "@rollup/plugin-typescript"; 4 | import { cleandir as CleandirPlugin } from "rollup-plugin-cleandir"; 5 | import DtsPlugin from "rollup-plugin-dts"; 6 | import { terser as TerserPlugin } from "rollup-plugin-terser"; 7 | 8 | const PLUGINS = [ 9 | NodeResolvePlugin(), 10 | CommonjsPlugin(), 11 | TypescriptPlugin(), 12 | TerserPlugin({ 13 | compress: { drop_console: false }, 14 | format: { comments: false } 15 | }) 16 | ]; 17 | 18 | export default [{ 19 | input: "src/web.ts", 20 | output: { file: "dist/web.js", format: "cjs" }, 21 | plugins: [...PLUGINS, CleandirPlugin("dist")] 22 | }, { 23 | input: "src/web.ts", 24 | output: { file: "dist/web.esm.js", format: "esm" }, 25 | plugins: PLUGINS 26 | }, { 27 | input: "src/web.umd.ts", 28 | output: { file: "dist/web.umd.js", format: "umd", name: "BruceUs" }, 29 | plugins: PLUGINS 30 | }, { 31 | input: "src/node.ts", 32 | output: { file: "dist/node.js", format: "cjs" }, 33 | plugins: PLUGINS 34 | }, { 35 | input: "src/node.ts", 36 | output: { file: "dist/node.esm.js", format: "esm" }, 37 | plugins: PLUGINS 38 | }, { 39 | input: "src/index.ts", 40 | output: { file: "dist/index.d.ts", format: "esm" }, 41 | plugins: [DtsPlugin()] 42 | }]; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/common/array.ts: -------------------------------------------------------------------------------- 1 | /** 数组工具 **/ 2 | 3 | interface KeyArr { 4 | [index: string|number]: string|number 5 | } 6 | 7 | interface GroupObj { 8 | [key: string|number]: KeyArr[] 9 | } 10 | 11 | interface CountObj { 12 | [key: string|number]: number 13 | } 14 | 15 | /** 16 | * @name 分组成员特性 17 | * @param {array} [arr=[]] 数组 18 | * @param {string} [key=""] 属性 19 | */ 20 | function GroupArrKey(arr: KeyArr[] = [], key: string = ""): GroupObj { 21 | return key ? arr.reduce((t: GroupObj, v) => (!t[v[key]] && (t[v[key]] = []), t[v[key]].push(v), t), {}) : {}; 22 | } 23 | 24 | /** 25 | * @name 记录成员位置 26 | * @param {array} [arr=[]] 数组 27 | * @param {string|number|boolean} [val] 值 28 | */ 29 | function RecordArrPosition(arr: Array = [], val: string|number|boolean): number[] { 30 | return arr.reduce((t: number[], v, i) => (v === val && t.push(i), t), []); 31 | } 32 | 33 | /** 34 | * @name 统计成员个数 35 | * @param {array} [arr=[]] 数组 36 | */ 37 | function StatArrCount(arr: Array = []): CountObj { 38 | return arr.reduce((t: CountObj, v) => (t[v] = (t[v] || 0) + 1, t), {}); 39 | } 40 | 41 | /** 42 | * @name 统计成员所含关键字 43 | * @param {array} [arr=[]] 数组 44 | * @param {array} [keys=[]] 关键字集合 45 | */ 46 | function StatArrKeyword(arr: string[] = [], keys: string[] = []): string[] { 47 | return keys.reduce((t: string[], v) => (arr.some(w => w.includes(v)) && t.push(v), t), []); 48 | } 49 | 50 | export { 51 | GroupArrKey, 52 | RecordArrPosition, 53 | StatArrCount, 54 | StatArrKeyword 55 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/common/boolean.ts: -------------------------------------------------------------------------------- 1 | /** 布尔工具 **/ 2 | 3 | /** 4 | * @name 环境类型 5 | */ 6 | function EnvType(): string { 7 | return typeof window !== "undefined" 8 | ? "web" 9 | : typeof global !== "undefined" ? "node" : "unknow"; 10 | } 11 | 12 | /** 13 | * @name 判断环境 14 | */ 15 | function IsWeb(): boolean { 16 | return EnvType() === "web"; 17 | } 18 | 19 | function IsNode(): boolean { 20 | return EnvType() === "node"; 21 | } 22 | 23 | /** 24 | * @name 数据类型 25 | * @param {*} [data] 数据 26 | */ 27 | function TypeOf(data: T): string { 28 | return Object.prototype.toString.call(data).replace(/\[object (\w+)\]/, "$1").toLowerCase(); 29 | } 30 | 31 | /** 32 | * @name 判断基础数据类型:undefined、null、string、number、boolean、symbol 33 | * @param {*} [data] 数据 34 | */ 35 | function IsUndefined(data: T): boolean { 36 | return TypeOf(data) === "undefined"; 37 | } 38 | 39 | function IsNull(data: T): boolean { 40 | return TypeOf(data) === "null"; 41 | } 42 | 43 | function IsString(data: T): boolean { 44 | return TypeOf(data) === "string"; 45 | } 46 | 47 | function IsNumber(data: T): boolean { 48 | return TypeOf(data) === "number"; 49 | } 50 | 51 | function IsBoolean(data: T): boolean { 52 | return TypeOf(data) === "boolean"; 53 | } 54 | 55 | function IsSymbol(data: T): boolean { 56 | return TypeOf(data) === "symbol"; 57 | } 58 | 59 | /** 60 | * @name 判断复合数据类型:array、object、date、regexp、function、class、element、set、map、weakset、weakmap 61 | * @param {*} [data] 数据 62 | */ 63 | function IsArray(data: T): boolean { 64 | return TypeOf(data) === "array"; 65 | } 66 | 67 | function IsObject(data: T): boolean { 68 | return TypeOf(data) === "object"; 69 | } 70 | 71 | function IsDate(data: T): boolean { 72 | return TypeOf(data) === "date"; 73 | } 74 | 75 | function IsRegExp(data: T): boolean { 76 | return TypeOf(data) === "regexp"; 77 | } 78 | 79 | function IsFunction(data: T): boolean { 80 | return TypeOf(data) === "function"; 81 | } 82 | 83 | function IsClass(data: T): boolean { 84 | return IsFunction(data) && /^class\s+[\dA-Za-z]/.test(data.toString()); 85 | } 86 | 87 | function IsSet(data: T): boolean { 88 | return TypeOf(data) === "set"; 89 | } 90 | 91 | function IsMap(data: T): boolean { 92 | return TypeOf(data) === "map"; 93 | } 94 | 95 | function IsWeakSet(data: T): boolean { 96 | return TypeOf(data) === "weakset"; 97 | } 98 | 99 | function IsWeakMap(data: T): boolean { 100 | return TypeOf(data) === "weakmap"; 101 | } 102 | 103 | function IsElement(data: T): boolean { 104 | return /^html(.+?)element$/.test(TypeOf(data)); 105 | } 106 | 107 | /** 108 | * @name 判断函数类型:asyncfunction、function、arguments 109 | * @param {*} [data] 数据 110 | */ 111 | function IsAsyncFunction(data: T): boolean { 112 | return TypeOf(data) === "asyncfunction"; 113 | } 114 | 115 | function IsSyncFunction(data: T): boolean { 116 | return TypeOf(data) === "function"; 117 | } 118 | 119 | function IsArguments(data: T): boolean { 120 | return TypeOf(data) === "arguments"; 121 | } 122 | 123 | /** 124 | * @name 判断空类型:error、empty、emptyarray、emptyobject 125 | * @param {*} [data] 数据 126 | */ 127 | function IsError(data: T): boolean { 128 | return data instanceof Error; 129 | } 130 | 131 | function IsEmpty(data: T): boolean { 132 | return !data; // undefined null "" 0 false NaN 133 | } 134 | 135 | function IsEmptyArray(data: T): boolean { 136 | return Array.isArray(data) && !data.length; 137 | } 138 | 139 | function IsEmptyObject(data: T): boolean { 140 | return IsObject(data) && !Object.keys(data).length; 141 | } 142 | 143 | export { 144 | EnvType, // 环境类型 145 | IsArguments, // 判断函数参数 146 | IsArray, // 判断数组 147 | IsAsyncFunction, // 判断异步函数 148 | IsBoolean, // 判断布尔 149 | IsClass, // 判断类 150 | IsDate, // 判断日期 151 | IsElement, // 判断元素 152 | IsEmpty, // 判断空 153 | IsEmptyArray, // 判断空数组 154 | IsEmptyObject, // 判断空对象 155 | IsError, // 判断错误 156 | IsFunction, // 判断函数 157 | IsMap, // 判断映射 158 | IsNode, // 判断Node 159 | IsNull, // 判断空值 160 | IsNumber, // 判断数值 161 | IsObject, // 判断对象 162 | IsRegExp, // 判断正则 163 | IsSet, // 判断集合 164 | IsString, // 判断字符 165 | IsSymbol, // 判断标记 166 | IsSyncFunction, // 判断同步函数 167 | IsUndefined, // 判断未定义 168 | IsWeakMap, // 判断弱映射 169 | IsWeakSet, // 判断弱集合 170 | IsWeb, // 判断Web 171 | TypeOf // 数据类型 172 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/common/date.ts: -------------------------------------------------------------------------------- 1 | /** 日期工具 **/ 2 | import Day from "dayjs"; 3 | 4 | /** 5 | * @name 格式倒计时 6 | * @param {string|number|date} [date] 日期:YYYY-MM-DD HH:mm:ss 7 | */ 8 | function FormatCountdown(date: string|number|Date): string { 9 | if (!date) return "时间无效"; 10 | const nowTime = +new Date(); 11 | const nextTime = +new Date(date); 12 | const diff = nextTime - nowTime; 13 | if (diff >= 0) { 14 | const day = Math.floor(diff / 1000 / 3600 / 24); 15 | const hou = Math.floor(diff / 1000 / 60 / 60 % 24); 16 | const min = Math.floor(diff / 1000 / 60 % 60); 17 | const sec = Math.floor(diff / 1000 % 60); 18 | const dayText = day ? `${day}天` : ""; 19 | const houText = hou ? `${hou}时` : ""; 20 | const minText = min ? `${min}分` : ""; 21 | const secText = sec ? `${sec}秒` : ""; 22 | return `${dayText}${houText}${minText}${secText}`; 23 | } else { 24 | return "时间已到"; 25 | } 26 | } 27 | 28 | /** 29 | * @name 格式时间差 30 | * @param {string|number|date} [date] 日期:YYYY-MM-DD HH:mm:ss 31 | */ 32 | function FormatTimeDiff(date: string|number|Date): string { 33 | if (!date) return "时间无效"; 34 | const nowTime = +new Date(); 35 | const tgtTime = +new Date(date); 36 | const diff = nowTime - tgtTime; 37 | const slot = diff >= 0 ? "前" : "后"; 38 | const absDiff = Math.abs(diff); 39 | const monNum = 1461 / 48; 40 | const yearNum = 1461 / 4; 41 | const min = 1000 * 60; 42 | const hou = min * 60; 43 | const day = hou * 24; 44 | const mon = day * monNum; 45 | const year = day * yearNum; 46 | const minDiff = absDiff / min; 47 | const houDiff = absDiff / hou; 48 | const dayDiff = absDiff / day; 49 | const monDiff = absDiff / mon; 50 | const yearDiff = absDiff / year; 51 | if (yearDiff >= 1 || monDiff >= 12) { 52 | return Day(tgtTime).format("YYYY-MM-DD HH:mm:ss"); 53 | } else if (monDiff >= 1 && monDiff < 12) { 54 | return `${parseInt(monDiff.toString())}个月${slot}`; 55 | } else if (dayDiff >= 1 && dayDiff < monNum) { 56 | return `${parseInt(dayDiff.toString())}天${slot}`; 57 | } else if (houDiff >= 1 && houDiff < 24) { 58 | return `${parseInt(houDiff.toString())}小时${slot}`; 59 | } else if (minDiff >= 1 && minDiff < 60) { 60 | return `${parseInt(minDiff.toString())}分钟${slot}`; 61 | } else { 62 | return diff >= 0 ? "刚刚" : "准备"; 63 | } 64 | } 65 | 66 | export { 67 | FormatCountdown, 68 | FormatTimeDiff 69 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/common/function.ts: -------------------------------------------------------------------------------- 1 | /** 函数工具 **/ 2 | 3 | type TgtFunc = (...args: T[]) => void; 4 | 5 | /** 6 | * @name 格式异步返回值 7 | * @param {function} [pfn] Promise函数 8 | */ 9 | async function AsyncTo(pfn: Promise, error?: object): Promise<[U, undefined]|[null, T]> { 10 | return await pfn 11 | .then<[null, T]>((data: T) => [null, data]) 12 | .catch<[U, undefined]>((err: U) => [error ? Object.assign({}, err, error) : err, undefined]); 13 | } 14 | 15 | /** 16 | * @name 防抖 17 | * @param {function} [fn] 函数 18 | * @param {number} [dura=50] 时延 19 | */ 20 | function Debounce(fn: TgtFunc, dura: number = 50): TgtFunc { 21 | let timer: ReturnType; 22 | return function(this: object, ...args: T[]) { 23 | timer && clearTimeout(timer); 24 | timer = setTimeout(() => fn.apply(this, args), dura); 25 | }; 26 | } 27 | 28 | /** 29 | * @name 节流 30 | * @param {function} [fn] 函数 31 | * @param {number} [dura=50] 时延 32 | */ 33 | function Throttle(fn: TgtFunc, dura: number = 50): TgtFunc { 34 | let timer: ReturnType; 35 | let lock = false; 36 | let lastTime = 0; 37 | return function(this: object, ...args: T[]) { 38 | if (lock) { 39 | clearTimeout(timer); 40 | timer = setTimeout(() => { 41 | if (Date.now() - lastTime >= dura) { 42 | fn.apply(this, args); 43 | lastTime = Date.now(); 44 | } 45 | }, Math.max(dura - (Date.now() - lastTime), 0)); 46 | } else { 47 | fn.apply(this, args); 48 | lastTime = Date.now(); 49 | lock = true; 50 | } 51 | }; 52 | } 53 | 54 | /** 55 | * @name 等待 56 | * @param {number} [dura=1000] 时延 57 | */ 58 | async function WaitFor(dura: number = 1000): Promise { 59 | return await new Promise(resolve => setTimeout(() => resolve(true), dura)); 60 | } 61 | 62 | export { 63 | AsyncTo, 64 | Debounce, 65 | Throttle, 66 | WaitFor 67 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/common/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | GroupArrKey, 3 | RecordArrPosition, 4 | StatArrCount, 5 | StatArrKeyword 6 | } from "./array"; 7 | import { 8 | EnvType, 9 | IsArguments, 10 | IsArray, 11 | IsAsyncFunction, 12 | IsBoolean, 13 | IsClass, 14 | IsDate, 15 | IsElement, 16 | IsEmpty, 17 | IsEmptyArray, 18 | IsEmptyObject, 19 | IsError, 20 | IsFunction, 21 | IsMap, 22 | IsNode, 23 | IsNull, 24 | IsNumber, 25 | IsObject, 26 | IsRegExp, 27 | IsSet, 28 | IsString, 29 | IsSymbol, 30 | IsSyncFunction, 31 | IsUndefined, 32 | IsWeakMap, 33 | IsWeakSet, 34 | IsWeb, 35 | TypeOf 36 | } from "./boolean"; 37 | import { 38 | FormatCountdown, 39 | FormatTimeDiff 40 | } from "./date"; 41 | import { 42 | AsyncTo, 43 | Debounce, 44 | Throttle, 45 | WaitFor 46 | } from "./function"; 47 | import { 48 | FillNum, 49 | FormatByte, 50 | RandomNum, 51 | RandomNumPlus, 52 | RoundNum, 53 | ThousandNum 54 | } from "./number"; 55 | import { 56 | FilterObj 57 | } from "./object"; 58 | import { 59 | CheckText, 60 | CheckTextPlus, 61 | MatchBracketText 62 | } from "./regexp"; 63 | import { 64 | DesePhone, 65 | FormatPhone, 66 | RandomColor, 67 | RandomId, 68 | RemoveTag, 69 | ReverseText, 70 | StartScore 71 | } from "./string"; 72 | 73 | export { 74 | // ✅数组Array 75 | GroupArrKey, 76 | RecordArrPosition, 77 | StatArrCount, 78 | StatArrKeyword, 79 | // ✅布尔Boolean 80 | EnvType, 81 | IsArguments, 82 | IsArray, 83 | IsAsyncFunction, 84 | IsBoolean, 85 | IsClass, 86 | IsDate, 87 | IsElement, 88 | IsEmpty, 89 | IsEmptyArray, 90 | IsEmptyObject, 91 | IsError, 92 | IsFunction, 93 | IsMap, 94 | IsNode, 95 | IsNull, 96 | IsNumber, 97 | IsObject, 98 | IsRegExp, 99 | IsSet, 100 | IsString, 101 | IsSymbol, 102 | IsSyncFunction, 103 | IsUndefined, 104 | IsWeakMap, 105 | IsWeakSet, 106 | IsWeb, 107 | TypeOf, 108 | // ✅日期Date 109 | FormatCountdown, 110 | FormatTimeDiff, 111 | // ✅日期Function 112 | AsyncTo, 113 | Debounce, 114 | Throttle, 115 | WaitFor, 116 | // ✅数值Number 117 | FillNum, 118 | FormatByte, 119 | RandomNum, 120 | RandomNumPlus, 121 | RoundNum, 122 | ThousandNum, 123 | // ✅对象Object 124 | FilterObj, 125 | // ✅正则Regexp 126 | CheckText, 127 | CheckTextPlus, 128 | MatchBracketText, 129 | // ✅字符String 130 | DesePhone, 131 | FormatPhone, 132 | RandomColor, 133 | RandomId, 134 | RemoveTag, 135 | ReverseText, 136 | StartScore 137 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/common/number.ts: -------------------------------------------------------------------------------- 1 | /** 数值工具 **/ 2 | 3 | /** 4 | * @name 补零数值 5 | * @param {number} [num=0] 数值 6 | * @param {number} [len=0] 补位 7 | */ 8 | function FillNum(num: number = 0, len: number = 0): string { 9 | return num.toString().padStart(len, "0"); 10 | } 11 | 12 | /** 13 | * @name 格式字节 14 | * @param {number} [byte=0] 字节 15 | */ 16 | function FormatByte(byte: number = 0): string { 17 | if (byte === 0) return "0 B"; 18 | const unit = 1024; 19 | const sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; 20 | const i = Math.floor(Math.log(byte) / Math.log(unit)); 21 | return (byte / Math.pow(unit, i)).toPrecision(3) + " " + sizes[i]; 22 | } 23 | 24 | /** 25 | * @name 范围随机数 26 | * @param {number} [min=0] 最小数 27 | * @param {number} [max=10] 最大数 28 | */ 29 | function RandomNum(min: number = 0, max: number = 10): number { 30 | return Math.floor(Math.random() * (max - min + 1) + min); 31 | } 32 | 33 | /** 34 | * @name N个范围随机数 35 | * @param {number} [min=0] 最小数 36 | * @param {number} [max=10] 最大数 37 | * @param {number} [count=1] 个数 38 | */ 39 | function RandomNumPlus(min: number = 0, max: number = 10, count: number = 1): number[] { 40 | const randoms: number[] = []; 41 | while (true) { 42 | let isExists = false; 43 | const random = RandomNum(min, max); 44 | for (let i = 0; i < randoms.length; i++) { 45 | if (random === randoms[i]) { 46 | isExists = true; 47 | break; 48 | } 49 | } 50 | if (!isExists) { 51 | randoms.push(random); 52 | } 53 | if (randoms.length === count) { 54 | return randoms; 55 | } 56 | } 57 | } 58 | 59 | /** 60 | * @name 精确数值(四舍五入与百分比) 61 | * @param {number} [num=0] 数值 62 | * @param {number} [dec=2] 小数个数 63 | * @param {boolean} [per=false] 百分比 64 | */ 65 | function RoundNum(num: number = 0, dec: number = 2, per: boolean = false): string|number { 66 | return per 67 | ? `${Math.round(num * 10 ** dec * 100) / 10 ** dec}%` 68 | : Math.round(num * 10 ** dec) / 10 ** dec; 69 | } 70 | 71 | /** 72 | * @name 千分数值 73 | * @param {number} [num=0] 数值 74 | */ 75 | function ThousandNum(num: number = 0): string { 76 | return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); 77 | } 78 | 79 | export { 80 | FillNum, 81 | FormatByte, 82 | RandomNum, 83 | RandomNumPlus, 84 | RoundNum, 85 | ThousandNum 86 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/common/object.ts: -------------------------------------------------------------------------------- 1 | /** 对象工具 **/ 2 | 3 | interface Obj { 4 | [key: string|number]: T 5 | } 6 | 7 | /** 8 | * @name 过滤对象 9 | * @param {object} [obj={}] 对象 10 | * @param {array} [keys=[]] 键集合 11 | */ 12 | function FilterObj(obj: Obj = {}, keys: Array = []): Obj { 13 | return Object.keys(obj).reduce((t: Obj, v) => (keys.includes(v) && (t[v] = obj[v]), t), {}); 14 | } 15 | 16 | export { 17 | FilterObj 18 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/common/regexp.ts: -------------------------------------------------------------------------------- 1 | /** 正则工具 **/ 2 | 3 | interface MatchObj { 4 | [key: string]: { 5 | msg: string 6 | regexp: RegExp 7 | } 8 | } 9 | 10 | interface CheckObj { 11 | flag: boolean 12 | msg: string 13 | } 14 | 15 | const MATCH: MatchObj = { 16 | address: { 17 | msg: "地址只能由2~200位中文、英文、数字或空格组成", 18 | regexp: /^[\u4e00-\u9fa5A-Za-z0-9 ]{2,200}$/g 19 | }, 20 | count: { 21 | msg: "数量只能由数字组成", 22 | regexp: /^\d{1,}$/g 23 | }, 24 | date: { 25 | msg: "日期只能由YYYY-MM-DD hh:mm:ss形式组成", 26 | regexp: /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/g 27 | }, 28 | email: { 29 | msg: "邮箱只能由xxx@yyy.zzz形式组成", 30 | regexp: /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/g 31 | }, 32 | idcard: { 33 | msg: "身份证只能由13位数字或12位数字与X组成", 34 | regexp: /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/g 35 | }, 36 | image: { 37 | msg: "图片只能是JPG、PNG、GIF、SVG或WEBP类型", 38 | regexp: /\.(jpe?g|png|gif|svg|webp)$/g 39 | }, 40 | name: { 41 | msg: "名称只能由2~50位中文、英文、数字、下划线或中划线组成", 42 | regexp: /^[\u4e00-\u9fa5\w-]{2,50}$/g 43 | }, 44 | number: { 45 | msg: "计数只能由数字或小数点组成", 46 | regexp: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g 47 | }, 48 | password: { 49 | msg: "密码只能由8~20位英文、数字或符号至少两种组成", 50 | regexp: /^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)])+$)^.{8,20}$/g 51 | }, 52 | phone: { 53 | msg: "手机只能由11位数字组成且需符合通讯运营商规范", 54 | regexp: /^1\d{10}$/g 55 | } 56 | }; 57 | 58 | const SIGN = "^$.*+-?=!:|\\/()[]{}".split(""); 59 | 60 | /** 61 | * @name 校验文本 62 | * @param {string} [type=""] 类型:address、count、date、email、idcard、image、name、number、password、phone 63 | * @param {string} [text=""] 文本 64 | */ 65 | function CheckText(type: string = "", text: string = ""): CheckObj { 66 | const { regexp, msg } = MATCH[type]; 67 | const flag = regexp.test(text); 68 | return { flag, msg: flag ? "" : msg }; 69 | } 70 | 71 | /** 72 | * @name 自定义校验文本 73 | * @param {regexp} [regexp] 正则 74 | * @param {string} [text=""] 文本 75 | * @param {string} [msg=""] 提示 76 | */ 77 | function CheckTextPlus(regexp: RegExp, text: string = "", msg: string = ""): CheckObj { 78 | const flag = regexp.test(text); 79 | return { flag, msg: flag ? "" : msg }; 80 | } 81 | 82 | /** 83 | * @name 匹配括号文本 84 | * @param {string} [tgt="(*)"] 括号形式(提取的内容必须使用*代替) 85 | * @param {string} [text=""] 文本 86 | */ 87 | function MatchBracketText(tgt: string = "(*)", text: string = ""): string[] { 88 | const bracket = tgt.split("*").map(v => SIGN.includes(v) ? "\\" + v : v); 89 | const regexp = new RegExp(bracket[0] + "(.+?)" + bracket[1], "g"); 90 | const match = text.match(regexp) ?? []; 91 | return match.map(v => v.replace(regexp, "$1")); 92 | } 93 | 94 | export { 95 | MATCH, 96 | CheckText, 97 | CheckTextPlus, 98 | MatchBracketText 99 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/common/string.ts: -------------------------------------------------------------------------------- 1 | /** 字符工具 **/ 2 | import { MATCH } from "./regexp"; 3 | 4 | /** 5 | * @name 脱敏手机 6 | * @param {string} [phone=""] 手机 7 | */ 8 | function DesePhone(phone: string = ""): string { 9 | return MATCH.phone.regexp.test(phone) 10 | ? phone.toString().replace(/(\d{3})\d*(\d{4})/g, "$1****$2") 11 | : phone; 12 | } 13 | 14 | /** 15 | * @name 格式手机 16 | * @param {string} [phone=""] 手机 17 | * @param {string} [sign="-"] 标记:-、\s 18 | */ 19 | function FormatPhone(phone: string = "", sign: string = "-"): string { 20 | return MATCH.phone.regexp.test(phone) && ["-", " "].includes(sign) 21 | ? phone.toString().replace(/(\d{3})(\d{4})(\d{4})/g, `$1${sign}$2${sign}$3`) 22 | : phone; 23 | } 24 | 25 | /** 26 | * @name 随机HEX色值 27 | */ 28 | function RandomColor(): string { 29 | return "#" + Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0"); 30 | } 31 | 32 | /** 33 | * @name 随机长度ID 34 | * @param {number} [len=5] 长度 在1~10间 35 | */ 36 | function RandomId(len: number = 5): string { 37 | (len < 1 || len > 10) && (len = 5); 38 | return Math.random().toString(36).substr(3, len); 39 | } 40 | 41 | /** 42 | * @name 删除标签 43 | * @param {string} [text=""] 文本 44 | */ 45 | function RemoveTag(text: string = ""): string { 46 | return text.replace(/<[^>]*>/g, ""); 47 | } 48 | 49 | /** 50 | * @name 翻转文本 51 | * @param {string} [text=""] 文本 52 | */ 53 | function ReverseText(text: string = ""): string { 54 | return text.split("").reduceRight((t, v) => t + v); 55 | } 56 | 57 | /** 58 | * @name 星级评分 59 | * @param {number} [rate=0] 星级 在0~len间 60 | * @param {number} [len=5] 长度 61 | */ 62 | function StartScore(rate: number = 0, len: number = 5): string { 63 | (rate < 0) && (rate = 0); 64 | (rate > len) && (rate = len); 65 | return [ 66 | ...new Array(len).fill("★"), 67 | ...new Array(len).fill("☆") 68 | ].join("").slice(len - rate, len * 2 - rate); 69 | } 70 | 71 | export { 72 | DesePhone, 73 | FormatPhone, 74 | RandomColor, 75 | RandomId, 76 | RemoveTag, 77 | ReverseText, 78 | StartScore 79 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | // ✅数组Array 3 | GroupArrKey, 4 | RecordArrPosition, 5 | StatArrCount, 6 | StatArrKeyword, 7 | // ✅布尔Boolean 8 | EnvType, 9 | IsArguments, 10 | IsArray, 11 | IsAsyncFunction, 12 | IsBoolean, 13 | IsClass, 14 | IsDate, 15 | IsElement, 16 | IsEmpty, 17 | IsEmptyArray, 18 | IsEmptyObject, 19 | IsError, 20 | IsFunction, 21 | IsMap, 22 | IsNode, 23 | IsNull, 24 | IsNumber, 25 | IsObject, 26 | IsRegExp, 27 | IsSet, 28 | IsString, 29 | IsSymbol, 30 | IsSyncFunction, 31 | IsUndefined, 32 | IsWeakMap, 33 | IsWeakSet, 34 | IsWeb, 35 | TypeOf, 36 | // ✅日期Date 37 | FormatCountdown, 38 | FormatTimeDiff, 39 | // ✅日期Function 40 | AsyncTo, 41 | Debounce, 42 | Throttle, 43 | WaitFor, 44 | // ✅数值Number 45 | FillNum, 46 | FormatByte, 47 | RandomNum, 48 | RandomNumPlus, 49 | RoundNum, 50 | ThousandNum, 51 | // ✅对象Object 52 | FilterObj, 53 | // ✅正则Regexp 54 | CheckText, 55 | CheckTextPlus, 56 | MatchBracketText, 57 | // ✅字符String 58 | DesePhone, 59 | FormatPhone, 60 | RandomColor, 61 | RandomId, 62 | RemoveTag, 63 | ReverseText, 64 | StartScore 65 | } from "./common/index"; 66 | import { 67 | // ✅Fs文件 68 | AbsPath, 69 | CopyDir, 70 | CreateDir, 71 | ReadDir, 72 | ReadJson, 73 | RemoveDir, 74 | // ✅Os系统 75 | GetIP, 76 | // ✅Process进程 77 | RunCmd, 78 | // ✅Type类型 79 | NodeType 80 | } from "./node/index"; 81 | import { 82 | // ✅Cookie缓存 83 | GetCookie, 84 | RemoveCookie, 85 | SetCookie, 86 | // ✅Dom节点 87 | AutoResponse, 88 | CopyPaste, 89 | DownloadFile, 90 | FilterXss, 91 | Img2Base64, 92 | Jsonp, 93 | LoadScript, 94 | // ✅Function函数 95 | Ajax, 96 | // ✅Storage存储 97 | ClearLStorage, 98 | ClearSStorage, 99 | GetLStorage, 100 | GetSStorage, 101 | RemoveLStorage, 102 | RemoveSStorage, 103 | SetLStorage, 104 | SetSStorage, 105 | // ✅Type类型 106 | WebType, 107 | // ✅Url链接 108 | ParseUrlSearch, 109 | RemoveUrlSearch, 110 | SetUrlSearch, 111 | StringifyUrlSearch 112 | } from "./web/index"; 113 | 114 | export { 115 | AbsPath, 116 | Ajax, 117 | AsyncTo, 118 | AutoResponse, 119 | CheckText, 120 | CheckTextPlus, 121 | ClearLStorage, 122 | ClearSStorage, 123 | CopyDir, 124 | CopyPaste, 125 | CreateDir, 126 | Debounce, 127 | DesePhone, 128 | DownloadFile, 129 | EnvType, 130 | FillNum, 131 | FilterObj, 132 | FilterXss, 133 | FormatByte, 134 | FormatCountdown, 135 | FormatPhone, 136 | FormatTimeDiff, 137 | GetCookie, 138 | GetIP, 139 | GetLStorage, 140 | GetSStorage, 141 | GroupArrKey, 142 | Img2Base64, 143 | IsArguments, 144 | IsArray, 145 | IsAsyncFunction, 146 | IsBoolean, 147 | IsClass, 148 | IsDate, 149 | IsElement, 150 | IsEmpty, 151 | IsEmptyArray, 152 | IsEmptyObject, 153 | IsError, 154 | IsFunction, 155 | IsMap, 156 | IsNode, 157 | IsNull, 158 | IsNumber, 159 | IsObject, 160 | IsRegExp, 161 | IsSet, 162 | IsString, 163 | IsSymbol, 164 | IsSyncFunction, 165 | IsUndefined, 166 | IsWeakMap, 167 | IsWeakSet, 168 | IsWeb, 169 | Jsonp, 170 | LoadScript, 171 | MatchBracketText, 172 | NodeType, 173 | ParseUrlSearch, 174 | RandomColor, 175 | RandomId, 176 | RandomNum, 177 | RandomNumPlus, 178 | ReadDir, 179 | ReadJson, 180 | RecordArrPosition, 181 | RemoveCookie, 182 | RemoveDir, 183 | RemoveLStorage, 184 | RemoveSStorage, 185 | RemoveTag, 186 | RemoveUrlSearch, 187 | ReverseText, 188 | RoundNum, 189 | RunCmd, 190 | SetCookie, 191 | SetLStorage, 192 | SetSStorage, 193 | SetUrlSearch, 194 | StartScore, 195 | StatArrCount, 196 | StatArrKeyword, 197 | StringifyUrlSearch, 198 | ThousandNum, 199 | Throttle, 200 | TypeOf, 201 | WaitFor, 202 | WebType 203 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/node.ts: -------------------------------------------------------------------------------- 1 | import { 2 | // ✅数组Array 3 | GroupArrKey, 4 | RecordArrPosition, 5 | StatArrCount, 6 | StatArrKeyword, 7 | // ✅布尔Boolean 8 | EnvType, 9 | IsArguments, 10 | IsArray, 11 | IsAsyncFunction, 12 | IsBoolean, 13 | IsClass, 14 | IsDate, 15 | IsElement, 16 | IsEmpty, 17 | IsEmptyArray, 18 | IsEmptyObject, 19 | IsError, 20 | IsFunction, 21 | IsMap, 22 | IsNode, 23 | IsNull, 24 | IsNumber, 25 | IsObject, 26 | IsRegExp, 27 | IsSet, 28 | IsString, 29 | IsSymbol, 30 | IsSyncFunction, 31 | IsUndefined, 32 | IsWeakMap, 33 | IsWeakSet, 34 | IsWeb, 35 | TypeOf, 36 | // ✅日期Date 37 | FormatCountdown, 38 | FormatTimeDiff, 39 | // ✅日期Function 40 | AsyncTo, 41 | Debounce, 42 | Throttle, 43 | WaitFor, 44 | // ✅数值Number 45 | FillNum, 46 | FormatByte, 47 | RandomNum, 48 | RandomNumPlus, 49 | RoundNum, 50 | ThousandNum, 51 | // ✅对象Object 52 | FilterObj, 53 | // ✅正则Regexp 54 | CheckText, 55 | CheckTextPlus, 56 | MatchBracketText, 57 | // ✅字符String 58 | DesePhone, 59 | FormatPhone, 60 | RandomColor, 61 | RandomId, 62 | RemoveTag, 63 | ReverseText, 64 | StartScore 65 | } from "./common/index"; 66 | import { 67 | // ✅Fs文件 68 | AbsPath, 69 | CopyDir, 70 | CreateDir, 71 | ReadDir, 72 | ReadJson, 73 | RemoveDir, 74 | // ✅Os系统 75 | GetIP, 76 | // ✅Process进程 77 | RunCmd, 78 | // ✅Type类型 79 | NodeType 80 | } from "./node/index"; 81 | 82 | export { 83 | AbsPath, 84 | AsyncTo, 85 | CheckText, 86 | CheckTextPlus, 87 | CopyDir, 88 | CreateDir, 89 | Debounce, 90 | DesePhone, 91 | EnvType, 92 | FillNum, 93 | FilterObj, 94 | FormatByte, 95 | FormatCountdown, 96 | FormatPhone, 97 | FormatTimeDiff, 98 | GetIP, 99 | GroupArrKey, 100 | IsArguments, 101 | IsArray, 102 | IsAsyncFunction, 103 | IsBoolean, 104 | IsClass, 105 | IsDate, 106 | IsElement, 107 | IsEmpty, 108 | IsEmptyArray, 109 | IsEmptyObject, 110 | IsError, 111 | IsFunction, 112 | IsMap, 113 | IsNode, 114 | IsNull, 115 | IsNumber, 116 | IsObject, 117 | IsRegExp, 118 | IsSet, 119 | IsString, 120 | IsSymbol, 121 | IsSyncFunction, 122 | IsUndefined, 123 | IsWeakMap, 124 | IsWeakSet, 125 | IsWeb, 126 | MatchBracketText, 127 | NodeType, 128 | RandomColor, 129 | RandomId, 130 | RandomNum, 131 | RandomNumPlus, 132 | ReadDir, 133 | ReadJson, 134 | RecordArrPosition, 135 | RemoveDir, 136 | RemoveTag, 137 | ReverseText, 138 | RoundNum, 139 | RunCmd, 140 | StartScore, 141 | StatArrCount, 142 | StatArrKeyword, 143 | ThousandNum, 144 | Throttle, 145 | TypeOf, 146 | WaitFor 147 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/node/fs.ts: -------------------------------------------------------------------------------- 1 | /** 文件工具 **/ 2 | import { readdirSync, readFileSync, statSync } from "fs"; 3 | import { extname, join } from "path"; 4 | import { cwd } from "process"; 5 | import { copySync, ensureDirSync, removeSync } from "fs-extra"; 6 | 7 | type FilterFunc = (src: string, dist: string) => boolean; 8 | 9 | /** 10 | * @name 绝对路径 11 | * @param {string} [path=""] 路径 12 | * @param {string} [dir=cwd()] 上下文 13 | */ 14 | function AbsPath(path: string = "", dir: string = cwd()): string { 15 | // const __dirname = dirname(fileURLToPath(import.meta.url)); 在使用该函数的文件里直接获取__dirname 16 | return join(dir, path); 17 | } 18 | 19 | /** 20 | * @name 复制文件路径 21 | * @param {string} [src=""] 输入路径 22 | * @param {string} [dist=""] 输出路径 23 | * @param {function} [filter] 过滤函数(返回true表示复制,返回false表示不复制) 24 | */ 25 | function CopyDir(src: string = "", dist: string = "", filter: FilterFunc): void { 26 | copySync(src, dist, { filter }); 27 | } 28 | 29 | /** 30 | * @name 创建文件路径 31 | * @param {string} [dir=""] 路径 32 | */ 33 | function CreateDir(dir: string = ""): void { 34 | ensureDirSync(dir); 35 | } 36 | 37 | /** 38 | * @name 读取文件路径 39 | * @param {string} [type="bfs"] 类型:bfs、dfs 40 | * @param {string} [dir=""] 路径 41 | * @param {regexp} [filter=/(node_modules|\.git|\.DS_Store)$/] 过滤正则 42 | */ 43 | 44 | function ReadDir(type: string = "bfs", dir: string = cwd(), filter: RegExp = /(node_modules|\.git|\.DS_Store)$/): string[] { 45 | if (type === "bfs") { 46 | const paths = []; 47 | const queue = []; 48 | !filter.test(dir) && queue.unshift(dir); 49 | while (queue.length) { 50 | const topPath = queue.shift() ?? ""; 51 | const stat = statSync(topPath); 52 | if (stat && !filter.test(topPath)) { 53 | const { isDirectory, isFile } = stat; 54 | if (isDirectory()) { 55 | readdirSync(topPath).forEach(v => { 56 | const spath = join(topPath, v); 57 | queue.push(spath); 58 | }); 59 | } else if (isFile()) { 60 | paths.push(topPath); 61 | } 62 | } 63 | } 64 | return paths; 65 | } else if (type === "dfs") { 66 | const paths: string[] = []; 67 | const stat = statSync(dir); 68 | if (!filter.test(dir)) { 69 | if (stat.isDirectory()) { 70 | readdirSync(dir).reduce((t, v) => { 71 | const spath = join(dir, v); 72 | const spaths = ReadDir("dfs", spath, filter); 73 | t.push(...spaths); 74 | return t; 75 | }, paths); 76 | } else if (stat.isFile()) { 77 | paths.push(dir); 78 | } 79 | } 80 | return paths; 81 | } else { 82 | return []; 83 | } 84 | } 85 | 86 | /** 87 | * @name 读取JSON文件 88 | * @param {string} [path=""] 路径 89 | * @param {string} [dir=cwd()] 上下文 90 | */ 91 | function ReadJson(path: string = "", dir: string = cwd()): object { 92 | const _path = AbsPath(path, dir); 93 | const ext = extname(_path); 94 | if (!/^\.json$/.test(ext)) return {}; 95 | const text = readFileSync(_path, "utf8"); 96 | return JSON.parse(text); 97 | } 98 | 99 | /** 100 | * @name 删除文件路径 101 | * @param {string} [dir=""] 路径 102 | */ 103 | function RemoveDir(dir: string = ""): void { 104 | removeSync(dir); 105 | } 106 | 107 | export { 108 | AbsPath, 109 | CopyDir, 110 | CreateDir, 111 | ReadDir, 112 | ReadJson, 113 | RemoveDir 114 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/node/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AbsPath, 3 | CopyDir, 4 | CreateDir, 5 | ReadDir, 6 | ReadJson, 7 | RemoveDir 8 | } from "./fs"; 9 | import { 10 | GetIP 11 | } from "./os"; 12 | import { 13 | RunCmd 14 | } from "./process"; 15 | import { 16 | NodeType 17 | } from "./type"; 18 | 19 | export { 20 | // ✅Fs文件 21 | AbsPath, 22 | CopyDir, 23 | CreateDir, 24 | ReadDir, 25 | ReadJson, 26 | RemoveDir, 27 | // ✅Os系统 28 | GetIP, 29 | // ✅Process进程 30 | RunCmd, 31 | // ✅Type类型 32 | NodeType 33 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/node/os.ts: -------------------------------------------------------------------------------- 1 | /** 系统工具 **/ 2 | import { networkInterfaces } from "os"; 3 | 4 | /** 5 | * @name 读取IP 6 | */ 7 | function GetIP(): string { 8 | const ip = "127.0.0.1"; 9 | const obj = networkInterfaces(); 10 | for (const k in obj) { 11 | const val = obj[k] ?? []; 12 | for (let i = 0; i < val.length; i++) { 13 | const { address, family, internal } = val[i]; 14 | if (family === "IPv4" && address !== ip && !internal) { 15 | return address; 16 | } 17 | } 18 | } 19 | return ip; 20 | } 21 | 22 | export { 23 | GetIP 24 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/node/process.ts: -------------------------------------------------------------------------------- 1 | /** 进程工具 **/ 2 | import { execSync } from "child_process"; 3 | 4 | /** 5 | * @name 运行命令 6 | * @param {string} [cmd="node -v"] 命令行 7 | */ 8 | function RunCmd(cmd: string = "node -v"): string { 9 | return execSync(cmd, { encoding: "utf8" }); 10 | } 11 | 12 | export { 13 | RunCmd 14 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/node/type.ts: -------------------------------------------------------------------------------- 1 | /** 类型工具 **/ 2 | import { release, type } from "os"; 3 | 4 | import { RunCmd } from "./process"; 5 | 6 | interface SystemObj { 7 | [key: string]: RegExp 8 | } 9 | 10 | interface NodeObj { 11 | nodeVs: string 12 | npmVs: string 13 | system: string 14 | systemVs: string 15 | } 16 | 17 | /** 18 | * @name Node类型 19 | */ 20 | function NodeType(): NodeObj { 21 | const info = type().toLocaleLowerCase(); 22 | const testUa = (regexp: RegExp): boolean => regexp.test(info); 23 | /* eslint-disable sort-keys */ 24 | const systemMap: SystemObj = { 25 | windows: /windows/g, // windows系统 26 | macos: /darwin/g, // macos系统 27 | linux: /linux/g // linux系统 28 | }; 29 | /* eslint-enable */ 30 | const system = Object.keys(systemMap).find(v => testUa(systemMap[v])) ?? "unknow"; 31 | return { 32 | nodeVs: RunCmd("node -v").replace(/(v|\n|\r\n)/g, ""), 33 | npmVs: RunCmd("npm -v").replace(/\n/g, ""), 34 | system, 35 | systemVs: release().split("-")[0] 36 | }; 37 | } 38 | 39 | export { 40 | NodeType 41 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/web.ts: -------------------------------------------------------------------------------- 1 | import { 2 | // ✅数组Array 3 | GroupArrKey, 4 | RecordArrPosition, 5 | StatArrCount, 6 | StatArrKeyword, 7 | // ✅布尔Boolean 8 | EnvType, 9 | IsArguments, 10 | IsArray, 11 | IsAsyncFunction, 12 | IsBoolean, 13 | IsClass, 14 | IsDate, 15 | IsElement, 16 | IsEmpty, 17 | IsEmptyArray, 18 | IsEmptyObject, 19 | IsError, 20 | IsFunction, 21 | IsMap, 22 | IsNode, 23 | IsNull, 24 | IsNumber, 25 | IsObject, 26 | IsRegExp, 27 | IsSet, 28 | IsString, 29 | IsSymbol, 30 | IsSyncFunction, 31 | IsUndefined, 32 | IsWeakMap, 33 | IsWeakSet, 34 | IsWeb, 35 | TypeOf, 36 | // ✅日期Date 37 | FormatCountdown, 38 | FormatTimeDiff, 39 | // ✅日期Function 40 | AsyncTo, 41 | Debounce, 42 | Throttle, 43 | WaitFor, 44 | // ✅数值Number 45 | FillNum, 46 | FormatByte, 47 | RandomNum, 48 | RandomNumPlus, 49 | RoundNum, 50 | ThousandNum, 51 | // ✅对象Object 52 | FilterObj, 53 | // ✅正则Regexp 54 | CheckText, 55 | CheckTextPlus, 56 | MatchBracketText, 57 | // ✅字符String 58 | DesePhone, 59 | FormatPhone, 60 | RandomColor, 61 | RandomId, 62 | RemoveTag, 63 | ReverseText, 64 | StartScore 65 | } from "./common/index"; 66 | import { 67 | // ✅Cookie缓存 68 | GetCookie, 69 | RemoveCookie, 70 | SetCookie, 71 | // ✅Dom节点 72 | AutoResponse, 73 | CopyPaste, 74 | DownloadFile, 75 | FilterXss, 76 | Img2Base64, 77 | Jsonp, 78 | LoadScript, 79 | // ✅Function函数 80 | Ajax, 81 | // ✅Storage存储 82 | ClearLStorage, 83 | ClearSStorage, 84 | GetLStorage, 85 | GetSStorage, 86 | RemoveLStorage, 87 | RemoveSStorage, 88 | SetLStorage, 89 | SetSStorage, 90 | // ✅Type类型 91 | WebType, 92 | // ✅Url链接 93 | ParseUrlSearch, 94 | RemoveUrlSearch, 95 | SetUrlSearch, 96 | StringifyUrlSearch 97 | } from "./web/index"; 98 | 99 | export { 100 | Ajax, 101 | AsyncTo, 102 | AutoResponse, 103 | CheckText, 104 | CheckTextPlus, 105 | ClearLStorage, 106 | ClearSStorage, 107 | CopyPaste, 108 | Debounce, 109 | DesePhone, 110 | DownloadFile, 111 | EnvType, 112 | FillNum, 113 | FilterObj, 114 | FilterXss, 115 | FormatByte, 116 | FormatCountdown, 117 | FormatPhone, 118 | FormatTimeDiff, 119 | GetCookie, 120 | GetLStorage, 121 | GetSStorage, 122 | GroupArrKey, 123 | Img2Base64, 124 | IsArguments, 125 | IsArray, 126 | IsAsyncFunction, 127 | IsBoolean, 128 | IsClass, 129 | IsDate, 130 | IsElement, 131 | IsEmpty, 132 | IsEmptyArray, 133 | IsEmptyObject, 134 | IsError, 135 | IsFunction, 136 | IsMap, 137 | IsNode, 138 | IsNull, 139 | IsNumber, 140 | IsObject, 141 | IsRegExp, 142 | IsSet, 143 | IsString, 144 | IsSymbol, 145 | IsSyncFunction, 146 | IsUndefined, 147 | IsWeakMap, 148 | IsWeakSet, 149 | IsWeb, 150 | Jsonp, 151 | LoadScript, 152 | MatchBracketText, 153 | ParseUrlSearch, 154 | RandomColor, 155 | RandomId, 156 | RandomNum, 157 | RandomNumPlus, 158 | RecordArrPosition, 159 | RemoveCookie, 160 | RemoveLStorage, 161 | RemoveSStorage, 162 | RemoveTag, 163 | RemoveUrlSearch, 164 | ReverseText, 165 | RoundNum, 166 | SetCookie, 167 | SetLStorage, 168 | SetSStorage, 169 | SetUrlSearch, 170 | StartScore, 171 | StatArrCount, 172 | StatArrKeyword, 173 | StringifyUrlSearch, 174 | ThousandNum, 175 | Throttle, 176 | TypeOf, 177 | WaitFor, 178 | WebType 179 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/web.umd.ts: -------------------------------------------------------------------------------- 1 | import { 2 | // ✅数组Array 3 | GroupArrKey, 4 | RecordArrPosition, 5 | StatArrCount, 6 | StatArrKeyword, 7 | // ✅布尔Boolean 8 | EnvType, 9 | IsArguments, 10 | IsArray, 11 | IsAsyncFunction, 12 | IsBoolean, 13 | IsClass, 14 | IsDate, 15 | IsElement, 16 | IsEmpty, 17 | IsEmptyArray, 18 | IsEmptyObject, 19 | IsError, 20 | IsFunction, 21 | IsMap, 22 | IsNode, 23 | IsNull, 24 | IsNumber, 25 | IsObject, 26 | IsRegExp, 27 | IsSet, 28 | IsString, 29 | IsSymbol, 30 | IsSyncFunction, 31 | IsUndefined, 32 | IsWeakMap, 33 | IsWeakSet, 34 | IsWeb, 35 | TypeOf, 36 | // ✅日期Date 37 | FormatCountdown, 38 | FormatTimeDiff, 39 | // ✅日期Function 40 | AsyncTo, 41 | Debounce, 42 | Throttle, 43 | WaitFor, 44 | // ✅数值Number 45 | FillNum, 46 | FormatByte, 47 | RandomNum, 48 | RandomNumPlus, 49 | RoundNum, 50 | ThousandNum, 51 | // ✅对象Object 52 | FilterObj, 53 | // ✅正则Regexp 54 | CheckText, 55 | CheckTextPlus, 56 | MatchBracketText, 57 | // ✅字符String 58 | DesePhone, 59 | FormatPhone, 60 | RandomColor, 61 | RandomId, 62 | RemoveTag, 63 | ReverseText, 64 | StartScore 65 | } from "./common/index"; 66 | import { 67 | // ✅Cookie缓存 68 | GetCookie, 69 | RemoveCookie, 70 | SetCookie, 71 | // ✅Dom节点 72 | AutoResponse, 73 | CopyPaste, 74 | DownloadFile, 75 | FilterXss, 76 | Img2Base64, 77 | Jsonp, 78 | LoadScript, 79 | // ✅Function函数 80 | Ajax, 81 | // ✅Storage存储 82 | ClearLStorage, 83 | ClearSStorage, 84 | GetLStorage, 85 | GetSStorage, 86 | RemoveLStorage, 87 | RemoveSStorage, 88 | SetLStorage, 89 | SetSStorage, 90 | // ✅Type类型 91 | WebType, 92 | // ✅Url链接 93 | ParseUrlSearch, 94 | RemoveUrlSearch, 95 | SetUrlSearch, 96 | StringifyUrlSearch 97 | } from "./web/index"; 98 | 99 | export default { 100 | Ajax, 101 | AsyncTo, 102 | AutoResponse, 103 | CheckText, 104 | CheckTextPlus, 105 | ClearLStorage, 106 | ClearSStorage, 107 | CopyPaste, 108 | Debounce, 109 | DesePhone, 110 | DownloadFile, 111 | EnvType, 112 | FillNum, 113 | FilterObj, 114 | FilterXss, 115 | FormatByte, 116 | FormatCountdown, 117 | FormatPhone, 118 | FormatTimeDiff, 119 | GetCookie, 120 | GetLStorage, 121 | GetSStorage, 122 | GroupArrKey, 123 | Img2Base64, 124 | IsArguments, 125 | IsArray, 126 | IsAsyncFunction, 127 | IsBoolean, 128 | IsClass, 129 | IsDate, 130 | IsElement, 131 | IsEmpty, 132 | IsEmptyArray, 133 | IsEmptyObject, 134 | IsError, 135 | IsFunction, 136 | IsMap, 137 | IsNode, 138 | IsNull, 139 | IsNumber, 140 | IsObject, 141 | IsRegExp, 142 | IsSet, 143 | IsString, 144 | IsSymbol, 145 | IsSyncFunction, 146 | IsUndefined, 147 | IsWeakMap, 148 | IsWeakSet, 149 | IsWeb, 150 | Jsonp, 151 | LoadScript, 152 | MatchBracketText, 153 | ParseUrlSearch, 154 | RandomColor, 155 | RandomId, 156 | RandomNum, 157 | RandomNumPlus, 158 | RecordArrPosition, 159 | RemoveCookie, 160 | RemoveLStorage, 161 | RemoveSStorage, 162 | RemoveTag, 163 | RemoveUrlSearch, 164 | ReverseText, 165 | RoundNum, 166 | SetCookie, 167 | SetLStorage, 168 | SetSStorage, 169 | SetUrlSearch, 170 | StartScore, 171 | StatArrCount, 172 | StatArrKeyword, 173 | StringifyUrlSearch, 174 | ThousandNum, 175 | Throttle, 176 | TypeOf, 177 | WaitFor, 178 | WebType 179 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/web/cookie.ts: -------------------------------------------------------------------------------- 1 | /** Cookie工具 **/ 2 | 3 | interface CookieObj { 4 | [key: string]: string 5 | } 6 | 7 | /** 8 | * @name 读取Cookie 9 | */ 10 | function GetCookie(): CookieObj { 11 | const cookies = document.cookie; 12 | return cookies ? cookies.split("; ").reduce((t: CookieObj, v) => { 13 | const cookie = v.split("="); 14 | t[cookie[0]] = cookie[1]; 15 | return t; 16 | }, {}) : {}; 17 | } 18 | 19 | /** 20 | * @name 删除Cookie 21 | * @param {string} [key=""] 键 22 | */ 23 | function RemoveCookie(key: string = ""): void { 24 | SetCookie(key, "", -1); 25 | } 26 | 27 | /** 28 | * @name 设置Cookie 29 | * @param {string} [key=""] 键 30 | * @param {string} [val=""] 值 31 | * @param {number} [day=1] 过期时间(日) 32 | */ 33 | function SetCookie(key: string = "", val: string = "", day: number = 1): void { 34 | const date = new Date(); 35 | date.setDate(date.getDate() + day); 36 | document.cookie = `${key}=${val};expires=${date.toString()}`; 37 | } 38 | 39 | export { 40 | GetCookie, 41 | RemoveCookie, 42 | SetCookie 43 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/web/dom.ts: -------------------------------------------------------------------------------- 1 | /** DOM工具 **/ 2 | import { AsyncTo } from "../common/function"; 3 | 4 | /** 5 | * @name 自适应 6 | * @param {number} [width=750] 设计图宽度 7 | */ 8 | function AutoResponse(width: number = 750): void { 9 | const target = document.documentElement; 10 | if (target.clientWidth >= 600) { 11 | target.style.fontSize = "80px"; 12 | } else { 13 | target.style.fontSize = `${target.clientWidth / width * 100}px`; 14 | } 15 | } 16 | 17 | /** 18 | * @name 复制粘贴 19 | * @param {element} [elem=document.body] 节点 20 | */ 21 | function CopyPaste(elem: HTMLElement = document.body): void { 22 | const end = elem.childNodes.length; 23 | const range = document.createRange(); 24 | const selection = getSelection(); 25 | if (selection) { 26 | range.setStart(elem, 0); 27 | range.setEnd(elem, end); 28 | selection.removeAllRanges(); 29 | selection.addRange(range); 30 | document.execCommand("copy", false); 31 | selection.removeRange(range); 32 | } 33 | } 34 | 35 | /** 36 | * @name 下载文件 37 | * @param {string} [url=""] 地址 38 | * @param {string} [name=""] 文件名 39 | */ 40 | function DownloadFile(url: string = "", name: string = ""): void { 41 | const target = document.createElement("a"); 42 | const event = document.createEvent("MouseEvents"); 43 | target.setAttribute("href", url); 44 | target.setAttribute("download", name); 45 | target.click(); 46 | target.dispatchEvent(event); 47 | } 48 | 49 | /** 50 | * @name 过滤XSS 51 | * @param {string} [html=""] HTML内容 52 | */ 53 | function FilterXss(html: string = ""): string { 54 | const elem = document.createElement("div"); 55 | elem.innerText = html; 56 | const result = elem.innerHTML; 57 | return result; 58 | } 59 | 60 | /** 61 | * @name 图像转B64 62 | * @param {string} [url=""] 地址 63 | * @param {string} [type="jpg"] 类型:jpg、png 64 | */ 65 | async function Img2Base64(url: string = "", type: string = "jpg"): Promise { 66 | const promise: Promise = new Promise((resolve, reject) => { 67 | const img = new Image(); 68 | type === "jpg" && (type = "jpeg"); 69 | img.setAttribute("src", url); 70 | img.setAttribute("crossOrigin", ""); 71 | img.addEventListener("load", () => { 72 | const canvas = document.createElement("canvas"); 73 | if (canvas) { 74 | canvas.setAttribute("width", `${img.width}px`); 75 | canvas.setAttribute("height", `${img.height}px`); 76 | canvas.getContext("2d")?.drawImage(img, 0, 0); 77 | const dataURL = canvas.toDataURL(`"image/${type}"`); 78 | resolve(dataURL); 79 | } else { 80 | resolve(""); 81 | } 82 | }); 83 | img.addEventListener("error", () => reject(new Error("error"))); 84 | }); 85 | const [err, res] = await AsyncTo(promise); 86 | return !err && res ? res : ""; 87 | } 88 | 89 | /** 90 | * @name JSONP 91 | * @param {string} [url=""] 地址 92 | * @param {string} [name="jsonp"] 全局变量 93 | * @param {function} [cb=null] 回调函数 94 | */ 95 | async function Jsonp(url: string = "", name: string = "jsonp", cb: null|((d: T) => T) = null): Promise { 96 | const promise: Promise = new Promise((resolve, reject) => { 97 | const script = document.createElement("script"); 98 | script.setAttribute("src", url); 99 | script.setAttribute("async", "true"); 100 | script.addEventListener("load", () => resolve(true)); 101 | script.addEventListener("error", () => reject(new Error("error"))); 102 | (window as any)[name] = (data: T) => cb?.(data); // eslint-disable-line 103 | document.body.appendChild(script); 104 | }); 105 | const [err, res] = await AsyncTo(promise); 106 | return !err && !!res; 107 | } 108 | 109 | /** 110 | * @name 加载脚本 111 | * @param {string} [url=""] 地址 112 | * @param {string} [pst="body"] 插入位置:head、body 113 | */ 114 | async function LoadScript(url: string = "", pst: string = "body"): Promise { 115 | const promise: Promise = new Promise((resolve, reject) => { 116 | const scripts = document.getElementsByTagName("script"); 117 | if ([...scripts].some(v => v.src === url || v.src.includes(url))) { 118 | reject(new Error(`<${pst}>已存在${url}该脚本`)); 119 | } 120 | const script = document.createElement("script"); 121 | script.setAttribute("src", url); 122 | script.addEventListener("load", () => resolve(true)); 123 | script.addEventListener("error", () => reject(new Error("error"))); 124 | pst === "head" && document.head.appendChild(script); 125 | pst === "body" && document.body.appendChild(script); 126 | }); 127 | const [err, res] = await AsyncTo(promise); 128 | return !err && !!res; 129 | } 130 | 131 | export { 132 | AutoResponse, 133 | CopyPaste, 134 | DownloadFile, 135 | FilterXss, 136 | Img2Base64, 137 | Jsonp, 138 | LoadScript 139 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/web/function.ts: -------------------------------------------------------------------------------- 1 | /** 函数工具 **/ 2 | import { StringifyUrlSearch } from "./url"; 3 | 4 | interface AjaxObj { 5 | data?: { 6 | [key: string]: string 7 | } 8 | error?: null|((status: number) => void) 9 | success?: null|((res: string) => void) 10 | type?: string 11 | url: string 12 | } 13 | 14 | /** 15 | * @name 异步请求 16 | * @param {object} [data={}] 参数集合 17 | * @param {function} [error=null] 失败回调函数 18 | * @param {function} [success=null] 成功回调函数 19 | * @param {string} [type="get"] 类型:get、post 20 | * @param {string} [url=""] 地址 21 | */ 22 | function Ajax({ data = {}, error = null, success = null, type = "get", url = "" }: AjaxObj): void { 23 | const xhr = new XMLHttpRequest(); 24 | const method = type.toUpperCase(); 25 | const params = StringifyUrlSearch(data); 26 | if (method === "GET") { 27 | xhr.open("GET", data ? `${url}${params}` : `${url}?t=${+new Date()}`, true); 28 | xhr.send(); 29 | } else if (method === "POST") { 30 | xhr.open("POST", url, true); 31 | xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 32 | xhr.send(params); 33 | } 34 | xhr.onreadystatechange = function() { 35 | if (xhr.readyState === 4) { 36 | if (xhr.status === 200) { 37 | success?.(xhr.responseText); 38 | } else { 39 | error?.(xhr.status); 40 | } 41 | } 42 | }; 43 | } 44 | 45 | export { 46 | Ajax 47 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/web/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | GetCookie, 3 | RemoveCookie, 4 | SetCookie 5 | } from "./cookie"; 6 | import { 7 | AutoResponse, 8 | CopyPaste, 9 | DownloadFile, 10 | FilterXss, 11 | Img2Base64, 12 | Jsonp, 13 | LoadScript 14 | } from "./dom"; 15 | import { 16 | Ajax 17 | } from "./function"; 18 | import { 19 | ClearLStorage, 20 | ClearSStorage, 21 | GetLStorage, 22 | GetSStorage, 23 | RemoveLStorage, 24 | RemoveSStorage, 25 | SetLStorage, 26 | SetSStorage 27 | } from "./storage"; 28 | import { 29 | WebType 30 | } from "./type"; 31 | import { 32 | ParseUrlSearch, 33 | RemoveUrlSearch, 34 | SetUrlSearch, 35 | StringifyUrlSearch 36 | } from "./url"; 37 | 38 | export { 39 | // ✅Cookie缓存 40 | GetCookie, 41 | RemoveCookie, 42 | SetCookie, 43 | // ✅Dom节点 44 | AutoResponse, 45 | CopyPaste, 46 | DownloadFile, 47 | FilterXss, 48 | Img2Base64, 49 | Jsonp, 50 | LoadScript, 51 | // ✅Function函数 52 | Ajax, 53 | // ✅Storage存储 54 | ClearLStorage, 55 | ClearSStorage, 56 | GetLStorage, 57 | GetSStorage, 58 | RemoveLStorage, 59 | RemoveSStorage, 60 | SetLStorage, 61 | SetSStorage, 62 | // ✅Type类型 63 | WebType, 64 | // ✅Url链接 65 | ParseUrlSearch, 66 | RemoveUrlSearch, 67 | SetUrlSearch, 68 | StringifyUrlSearch 69 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/web/storage.ts: -------------------------------------------------------------------------------- 1 | /** Storage工具 **/ 2 | 3 | /** 4 | * @name 清空LocalStorage 5 | */ 6 | function ClearLStorage(): void { 7 | localStorage.clear(); 8 | } 9 | 10 | /** 11 | * @name 清空SessionStorage 12 | */ 13 | function ClearSStorage(): void { 14 | sessionStorage.clear(); 15 | } 16 | 17 | /** 18 | * @name 读取LocalStorage 19 | * @param {string} [key=""] 键 20 | */ 21 | function GetLStorage(key: string = ""): T { 22 | const item = localStorage.getItem(key); 23 | return item ? JSON.parse(item) : null; 24 | } 25 | 26 | /** 27 | * @name 读取SessionStorage 28 | * @param {string} [key=""] 键 29 | */ 30 | function GetSStorage(key: string = ""): T { 31 | const item = sessionStorage.getItem(key); 32 | return item ? JSON.parse(item) : null; 33 | } 34 | 35 | /** 36 | * @name 删除LocalStorage 37 | * @param {string} [key=""] 键 38 | */ 39 | function RemoveLStorage(key: string = ""): void { 40 | localStorage.removeItem(key); 41 | } 42 | 43 | /** 44 | * @name 删除SessionStorage 45 | * @param {string} [key=""] 键 46 | */ 47 | function RemoveSStorage(key: string = ""): void { 48 | sessionStorage.removeItem(key); 49 | } 50 | 51 | /** 52 | * @name 设置LocalStorage 53 | * @param {string} [key=""] 键 54 | * @param {string} [val=""] 值 55 | */ 56 | function SetLStorage(key: string = "", val: T): void { 57 | localStorage.setItem(key, JSON.stringify(val)); 58 | } 59 | 60 | /** 61 | * @name 设置SessionStorage 62 | * @param {string} [key=""] 键 63 | * @param {string} [val=""] 值 64 | */ 65 | function SetSStorage(key: string = "", val: T): void { 66 | sessionStorage.setItem(key, JSON.stringify(val)); 67 | } 68 | 69 | export { 70 | ClearLStorage, 71 | ClearSStorage, 72 | GetLStorage, 73 | GetSStorage, 74 | RemoveLStorage, 75 | RemoveSStorage, 76 | SetLStorage, 77 | SetSStorage 78 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/web/type.ts: -------------------------------------------------------------------------------- 1 | /** 类型工具 **/ 2 | 3 | interface SystemObj { 4 | [key: string]: RegExp 5 | } 6 | 7 | interface SystemVsObj { 8 | [key: string|number]: RegExp 9 | } 10 | 11 | interface PlatformObj { 12 | [key: string]: string[] 13 | } 14 | 15 | interface EngineObj { 16 | [key: string]: RegExp[] 17 | } 18 | 19 | interface SupporterObj { 20 | [key: string]: string 21 | } 22 | 23 | interface SupporterForWebkitObj { 24 | [key: string]: RegExp 25 | } 26 | 27 | interface SupporterVsObj { 28 | [key: string]: RegExp 29 | } 30 | 31 | interface ShellObj { 32 | [key: string|number]: RegExp[] 33 | } 34 | 35 | interface WebObj { 36 | engine: string 37 | engineVs: string 38 | platform: string 39 | supporter: string 40 | supporterVs: string 41 | system: string 42 | systemVs: string 43 | shell?: string 44 | shellVs?: string 45 | } 46 | 47 | /** 48 | * @name Web类型 49 | * @param {string} [ua=navigator.userAgent.toLowerCase()] 用户代理 50 | */ 51 | function WebType(ua = navigator.userAgent.toLowerCase()): WebObj { 52 | // 权重:系统 > 平台 > 内核 > 载体 > 外壳 53 | const testUa = (regexp: RegExp): boolean => regexp.test(ua); 54 | const testVs = (regexp: RegExp): string => regexp 55 | ? (ua.match(regexp) ?? "").toString().replace(/[^0-9|_.]/g, "").replace(/_/g, ".") 56 | : "unknow"; 57 | /* eslint-disable sort-keys */ 58 | // 系统 59 | const systemMap: SystemObj = { 60 | windows: /windows|win32|win64|wow32|wow64/g, // windows系统 61 | macos: /macintosh|macintel/g, // macos系统 62 | linux: /x11/g, // linux系统 63 | android: /android|adr/g, // android系统 64 | ios: /ios|iphone|ipad|ipod|iwatch/g // ios系统 65 | }; 66 | const systemVsMap: SystemVsObj = { 67 | macos: /os x [\d._]+/g, 68 | android: /android [\d._]+/g, 69 | ios: /os [\d._]+/g 70 | }; 71 | const systemVsForWindows = (): string => { 72 | const vs = (ua.match(/(windows nt [\d._]+)|(windows [\w._]+)/g) ?? "") 73 | .toString() 74 | .replace(/windows( nt)? /g, ""); 75 | const map: SystemVsObj = { 76 | 2000: /^(5\.0|2000)/g, 77 | xp: /^(5\.1|xp)/g, 78 | 2003: /^(5\.2|2003)/g, 79 | vista: /^(6\.0|vista)/g, 80 | 7: /^(6\.1|7)/g, 81 | 8: /^(6\.2|8)/g, 82 | 8.1: /^(6\.3|8\.1)/g, 83 | 10: /^(10\.0|10)/g 84 | }; 85 | return Object.keys(map).find(v => map[v].test(vs)) ?? "unknow"; 86 | }; 87 | const system = Object.keys(systemMap).find(v => testUa(systemMap[v])) ?? "unknow"; 88 | const systemVs = system === "unknow" 89 | ? "unknow version" 90 | : system === "windows" 91 | ? systemVsForWindows() 92 | : testVs(systemVsMap[system]); 93 | // 平台 94 | const platformMap: PlatformObj = { 95 | desktop: ["windows", "macos", "linux"], // 桌面端 96 | mobile: ["android", "ios"] // 移动端 97 | }; 98 | const platform = testUa(/mobile/g) 99 | ? "mobile" 100 | : Object.keys(platformMap).find(v => platformMap[v].includes(system)) ?? "unknow"; 101 | // 内核 102 | const engineMap: EngineObj = { 103 | webkit: [/applewebkit/g, /applewebkit\/[\d._]+/g], // webkit内核 104 | gecko: [/(?=.*gecko)(?=.*firefox)/g, /gecko\/[\d._]+/g], // gecko内核 105 | presto: [/presto/g, /presto\/[\d._]+/g], // presto内核 106 | trident: [/trident|compatible|msie/g, /trident\/[\d._]+/g] // trident内核 107 | }; 108 | const engine = Object.keys(engineMap).find(v => testUa(engineMap[v][0])) ?? "unknow"; 109 | const engineVs = engine === "unknow" 110 | ? "unknow version" 111 | : testVs(engineMap[engine][1]); 112 | // 载体 113 | const supporterMap: SupporterObj = { 114 | gecko: "firefox", // firefox浏览器 115 | presto: "opera", // opera浏览器 116 | trident: "iexplore" // iexplore浏览器 117 | }; 118 | const supporterForWebkit = (): string => { 119 | const map: SupporterForWebkitObj = { 120 | edge: /edge/g, // edge浏览器 121 | opera: /opr/g, // opera浏览器 122 | chrome: /chrome/g, // chrome浏览器 123 | safari: /safari/g // safari浏览器 124 | }; 125 | return Object.keys(map).find(v => testUa(map[v])) ?? "unknow"; 126 | }; 127 | const supporterVsMap: SupporterVsObj = { 128 | chrome: /chrome\/[\d._]+/g, 129 | safari: /version\/[\d._]+/g, 130 | firefox: /firefox\/[\d._]+/g, 131 | opera: /opr\/[\d._]+/g, 132 | iexplore: /(msie [\d._]+)|(rv:[\d._]+)/g, 133 | edge: /edge\/[\d._]+/g 134 | }; 135 | const supporter = supporterMap[engine] 136 | ? engine === "webkit" ? supporterForWebkit() : supporterMap[engine] 137 | : "unknow"; 138 | const supporterVs = testVs(supporterVsMap[supporter]); 139 | // 外壳 140 | const shellMap: ShellObj = { 141 | wechat: [/micromessenger/g, /micromessenger\/[\d._]+/g], // 微信浏览器 142 | qq: [/qqbrowser/g, /qqbrowser\/[\d._]+/g], // QQ浏览器 143 | uc: [/ucbrowser/g, /ucbrowser\/[\d._]+/g], // UC浏览器 144 | 360: [/qihu 360se/g], // 360浏览器(无版本) 145 | 2345: [/2345explorer/g, /2345explorer\/[\d._]+/g], // 2345浏览器 146 | sougou: [/metasr/g], // 搜狗浏览器(无版本) 147 | liebao: [/lbbrowser/g], // 猎豹浏览器(无版本) 148 | maxthon: [/maxthon/g, /maxthon\/[\d._]+/g] // 遨游浏览器 149 | }; 150 | const shell = Object.keys(shellMap).find(v => testUa(shellMap[v][0])) ?? "none"; 151 | const shellVs = shell === "none" 152 | ? "none" 153 | : !shellMap[shell][1] 154 | ? "unknow version" 155 | : testVs(shellMap[shell][1]); 156 | /* eslint-enable */ 157 | return Object.assign({ 158 | engine, // webkit gecko presto trident 159 | engineVs, 160 | platform, // desktop mobile 161 | supporter, // chrome safari firefox opera iexplore edge 162 | supporterVs, 163 | system, // windows macos linux android ios 164 | systemVs 165 | }, shell === "none" ? {} : { 166 | shell, // wechat qq uc 360 2345 sougou liebao maxthon 167 | shellVs 168 | }); 169 | } 170 | 171 | export { 172 | WebType 173 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/src/web/url.ts: -------------------------------------------------------------------------------- 1 | /** URL工具 **/ 2 | import { IsEmptyArray, IsEmptyObject } from "../common/boolean"; 3 | 4 | interface SearchObj { 5 | [key: string]: string 6 | } 7 | 8 | /** 9 | * @name URL参数反序列化 10 | */ 11 | function ParseUrlSearch(): SearchObj { 12 | const { search } = location; 13 | return search ? search.replace(/(^\?)|(&$)/g, "").split("&").reduce((t: SearchObj, v) => { 14 | const [key, val] = v.split("="); 15 | t[key] = decodeURIComponent(val); 16 | return t; 17 | }, {}) : {}; 18 | } 19 | 20 | /** 21 | * @name 删除URL参数 22 | * @param {array} search 参数集合 23 | */ 24 | function RemoveUrlSearch(...search: string[]): void { 25 | if (IsEmptyArray(search)) return; 26 | const url = location.origin + location.pathname; 27 | const hash = location.hash; 28 | const oldSearch = ParseUrlSearch(); 29 | search.forEach(v => Reflect.deleteProperty(oldSearch, v)); 30 | const newSearchStr = StringifyUrlSearch(oldSearch); 31 | history.pushState({}, document.title, url + newSearchStr + hash); 32 | } 33 | 34 | /** 35 | * @name 设置URL参数 36 | * @param {object} [search={}] 参数集合 37 | */ 38 | function SetUrlSearch(search: SearchObj = {}): void { 39 | if (IsEmptyObject(search)) return; 40 | const url = location.origin + location.pathname; 41 | const hash = location.hash; 42 | const oldSearch = ParseUrlSearch(); 43 | const newSearch = Object.assign({}, oldSearch, search); 44 | const newSearchStr = StringifyUrlSearch(newSearch); 45 | history.pushState({}, document.title, url + newSearchStr + hash); 46 | } 47 | 48 | /** 49 | * @name URL参数序列化 50 | * @param {object} [search={}] 参数集合 51 | * @param {boolean} [clear=false] 清除假值(undefined、null、""、NaN) 52 | */ 53 | function StringifyUrlSearch(search: SearchObj = {}, clear = false): string { 54 | return Object.entries(search).reduce((t, v) => { 55 | if (clear) { 56 | return [undefined, null, "", NaN].includes(v[1]) ? t : `${t}${v[0]}=${encodeURIComponent(v[1])}&`; 57 | } else { 58 | return `${t}${v[0]}=${encodeURIComponent(v[1])}&`; 59 | } 60 | }, IsEmptyObject(search) ? "" : "?").replace(/&$/, ""); 61 | } 62 | 63 | export { 64 | ParseUrlSearch, 65 | RemoveUrlSearch, 66 | SetUrlSearch, 67 | StringifyUrlSearch 68 | }; -------------------------------------------------------------------------------- /js-lib/bruce-us/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "allowSyntheticDefaultImports": true, 5 | "baseUrl": ".", 6 | "declaration": true, 7 | "declarationDir": "dist", 8 | "downlevelIteration": true, 9 | "esModuleInterop": true, 10 | "experimentalDecorators": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "jsx": "react", 13 | "lib": [ 14 | "DOM", 15 | "DOM.Iterable", 16 | "ES2015", 17 | "ES2016", 18 | "ES2017", 19 | "ES2018", 20 | "ES2019", 21 | "ES2020", 22 | "ES2021", 23 | "ESNext" 24 | ], 25 | "module": "ES6", 26 | "moduleResolution": "node", 27 | "removeComments": true, 28 | "paths": { 29 | "#/*": ["*"], 30 | "@/*": ["src/*"] 31 | }, 32 | "sourceMap": true, 33 | "strict": false, 34 | "target": "ES5", 35 | "typeRoots": [ 36 | "node_modules/@types", 37 | "typings" 38 | ] 39 | }, 40 | "exclude": [ 41 | "dist", 42 | "node_modules", 43 | "jest.config.js", 44 | "rollup.config.js" 45 | ] 46 | } -------------------------------------------------------------------------------- /js-lib/rollup/dist/index.bundle.js: -------------------------------------------------------------------------------- 1 | function helloA() { 2 | const msg = "a"; 3 | console.log(msg); 4 | } 5 | 6 | helloA(); 7 | -------------------------------------------------------------------------------- /js-lib/rollup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rollup", 3 | "version": "1.0.0", 4 | "main": "dist/index.js", 5 | "scripts": { 6 | "build": "rollup -c" 7 | }, 8 | "engines": { 9 | "node": ">=13.2.0", 10 | "npm": ">=6.13.1" 11 | }, 12 | "dependencies": { 13 | "rollup": "2.72.1" 14 | } 15 | } -------------------------------------------------------------------------------- /js-lib/rollup/rollup.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | input: "src/index.js", 3 | output: { 4 | file: "dist/index.bundle.js", 5 | format: "esm" 6 | } 7 | }; -------------------------------------------------------------------------------- /js-lib/rollup/src/a.js: -------------------------------------------------------------------------------- 1 | export function helloA() { 2 | const msg = "a"; 3 | console.log(msg); 4 | } -------------------------------------------------------------------------------- /js-lib/rollup/src/b.js: -------------------------------------------------------------------------------- 1 | export function helloB() { 2 | const msg = "a"; 3 | console.log(msg); 4 | } -------------------------------------------------------------------------------- /js-lib/rollup/src/index.js: -------------------------------------------------------------------------------- 1 | import { helloA } from "./a.js"; 2 | import { helloB } from "./b.js"; 3 | 4 | helloA(); -------------------------------------------------------------------------------- /js-lib/webpack/dist/index.bundle.js: -------------------------------------------------------------------------------- 1 | (()=>{"use strict";console.log("a")})(); -------------------------------------------------------------------------------- /js-lib/webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack", 3 | "version": "1.0.0", 4 | "type": "module", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "build": "webpack" 8 | }, 9 | "engines": { 10 | "node": ">=13.2.0", 11 | "npm": ">=6.13.1" 12 | }, 13 | "dependencies": { 14 | "webpack": "5.72.1", 15 | "webpack-cli": "4.9.2" 16 | } 17 | } -------------------------------------------------------------------------------- /js-lib/webpack/src/a.js: -------------------------------------------------------------------------------- 1 | export function helloA() { 2 | const msg = "a"; 3 | console.log(msg); 4 | } -------------------------------------------------------------------------------- /js-lib/webpack/src/b.js: -------------------------------------------------------------------------------- 1 | export function helloB() { 2 | const msg = "b"; 3 | console.log(msg); 4 | } -------------------------------------------------------------------------------- /js-lib/webpack/src/index.js: -------------------------------------------------------------------------------- 1 | import { helloA } from "./a.js"; 2 | import { helloB } from "./b.js"; 3 | 4 | helloA(); -------------------------------------------------------------------------------- /js-lib/webpack/webpack.config.js: -------------------------------------------------------------------------------- 1 | import { join } from "path"; 2 | import { cwd } from "process"; 3 | 4 | export default { 5 | entry: "./src/index.js", 6 | mode: "production", 7 | output: { 8 | filename: "index.bundle.js", 9 | path: join(cwd(), "dist") 10 | } 11 | }; -------------------------------------------------------------------------------- /node-esm/for-babel/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-esm", 3 | "version": "1.0.0", 4 | "main": "src/index.js", 5 | "scripts": { 6 | "start": "babel-node src/index.js" 7 | }, 8 | "dependencies": { 9 | "@yangzw/bruce-us": "1.0.3" 10 | }, 11 | "devDependencies": { 12 | "@babel/cli": "7.17.10", 13 | "@babel/core": "7.18.2", 14 | "@babel/node": "7.17.10", 15 | "@babel/preset-env": "7.18.2" 16 | }, 17 | "babel": { 18 | "presets": [ 19 | "@babel/preset-env" 20 | ] 21 | } 22 | } -------------------------------------------------------------------------------- /node-esm/for-babel/src/index.js: -------------------------------------------------------------------------------- 1 | import { NodeType } from "@yangzw/bruce-us/dist/node"; 2 | 3 | console.log(NodeType()); -------------------------------------------------------------------------------- /node-esm/for-node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-esm", 3 | "version": "1.0.0", 4 | "main": "src/index.js", 5 | "type": "module", 6 | "scripts": { 7 | "start": "node --es-module-specifier-resolution=node src/index.js" 8 | }, 9 | "engines": { 10 | "node": ">=13.2.0", 11 | "npm": ">=6.13.1" 12 | }, 13 | "dependencies": { 14 | "@yangzw/bruce-us": "1.0.3" 15 | } 16 | } -------------------------------------------------------------------------------- /node-esm/for-node/src/index.js: -------------------------------------------------------------------------------- 1 | import { NodeType } from "@yangzw/bruce-us/dist/node"; 2 | 3 | console.log(NodeType()); -------------------------------------------------------------------------------- /node-esm/for-nodemon/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-esm", 3 | "version": "1.0.0", 4 | "main": "src/index.js", 5 | "scripts": { 6 | "start": "nodemon -x babel-node src/index.js" 7 | }, 8 | "dependencies": { 9 | "@yangzw/bruce-us": "1.0.3" 10 | }, 11 | "devDependencies": { 12 | "@babel/cli": "7.17.10", 13 | "@babel/core": "7.18.2", 14 | "@babel/node": "7.17.10", 15 | "@babel/preset-env": "7.18.2", 16 | "nodemon": "2.0.16" 17 | }, 18 | "babel": { 19 | "presets": [ 20 | "@babel/preset-env" 21 | ] 22 | }, 23 | "nodemonConfig": { 24 | "env": { 25 | "NODE_ENV": "dev" 26 | }, 27 | "execMap": { 28 | "js": "node --harmony" 29 | }, 30 | "ext": "js json", 31 | "ignore": [ 32 | "dist/" 33 | ], 34 | "watch": [ 35 | "src/" 36 | ] 37 | } 38 | } -------------------------------------------------------------------------------- /node-esm/for-nodemon/src/index.js: -------------------------------------------------------------------------------- 1 | import { NodeType } from "@yangzw/bruce-us/dist/node"; 2 | 3 | console.log(NodeType()); --------------------------------------------------------------------------------