diff --git a/.claude/settings.local.json b/.claude/settings.local.json index fe8d034..5f1fc48 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -8,7 +8,11 @@ "Bash(timeout 2 node:*)", "Bash(npm ls:*)", "Bash(timeout 1 node:*)", - "Bash(node -e:*)" + "Bash(node -e:*)", + "Bash(node --check:*)", + "Bash(npm search:*)", + "Bash(mkdir:*)", + "Bash(./bin/assimp.exe:*)" ] } } diff --git a/.stats.json b/.stats.json new file mode 100644 index 0000000..801c389 --- /dev/null +++ b/.stats.json @@ -0,0 +1,6 @@ +{ + "convert_format": { + "stp": 1, + "glb2": 2 + } +} \ No newline at end of file diff --git a/bin/assimp-vc143-mt.dll b/bin/assimp-vc143-mt.dll new file mode 100644 index 0000000..f072412 Binary files /dev/null and b/bin/assimp-vc143-mt.dll differ diff --git a/bin/assimp.exe b/bin/assimp.exe new file mode 100644 index 0000000..c3bd008 Binary files /dev/null and b/bin/assimp.exe differ diff --git a/cuba.fbx b/cuba.fbx new file mode 100644 index 0000000..f717f6b Binary files /dev/null and b/cuba.fbx differ diff --git a/cuba.glb b/cuba.glb new file mode 100644 index 0000000..b9b79c1 Binary files /dev/null and b/cuba.glb differ diff --git a/cuba.stp b/cuba.stp new file mode 100644 index 0000000..d9147d7 --- /dev/null +++ b/cuba.stp @@ -0,0 +1,296 @@ +ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('STEP AP214'),'1'); +FILE_NAME('cuba.stp','2025-12-20T11:13:44',(' '),(' '),'Spatial InterOp 3D',' ',' '); +FILE_SCHEMA(('automotive_design')); +ENDSEC; +DATA; +#1=MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION(' ',(#148,#183,#218,#253,#288,#323),#6); +#2=PRODUCT_DEFINITION_CONTEXT('',#7,'design'); +#3=APPLICATION_PROTOCOL_DEFINITION('INTERNATIONAL STANDARD','automotive_design',1994,#7); +#4=PRODUCT_CATEGORY_RELATIONSHIP('NONE','NONE',#8,#9); +#5=SHAPE_DEFINITION_REPRESENTATION(#10,#11); +#6= (GEOMETRIC_REPRESENTATION_CONTEXT(3)GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#12))GLOBAL_UNIT_ASSIGNED_CONTEXT((#13,#14,#15))REPRESENTATION_CONTEXT('NONE','WORKSPACE')); +#7=APPLICATION_CONTEXT(' '); +#8=PRODUCT_CATEGORY('part','NONE'); +#9=PRODUCT_RELATED_PRODUCT_CATEGORY('detail',' ',(#17)); +#10=PRODUCT_DEFINITION_SHAPE('NONE','NONE',#18); +#11=MANIFOLD_SURFACE_SHAPE_REPRESENTATION('Root',(#16,#19),#6); +#12=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.0E-006),#13,'',''); +#13=(CONVERSION_BASED_UNIT('METRE',#20)LENGTH_UNIT()NAMED_UNIT(#21)); +#14=(NAMED_UNIT(#22)PLANE_ANGLE_UNIT()SI_UNIT($,.RADIAN.)); +#15=(NAMED_UNIT(#22)SOLID_ANGLE_UNIT()SI_UNIT($,.STERADIAN.)); +#16=SHELL_BASED_SURFACE_MODEL('Root',(#29)); +#17=PRODUCT('Root','Root','Root',(#23)); +#18=PRODUCT_DEFINITION('NONE','NONE',#24,#2); +#19=AXIS2_PLACEMENT_3D('',#25,#26,#27); +#20=LENGTH_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.0),#28); +#21=DIMENSIONAL_EXPONENTS(1.0,0.0,0.0,0.0,0.0,0.0,0.0); +#22=DIMENSIONAL_EXPONENTS(0.0,0.0,0.0,0.0,0.0,0.0,0.0); +#23=PRODUCT_CONTEXT('',#7,'mechanical'); +#24=PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE(' ','NONE',#17,.NOT_KNOWN.); +#25=CARTESIAN_POINT('',(0.0,0.0,0.0)); +#26=DIRECTION('',(0.0,0.0,1.0)); +#27=DIRECTION('',(1.0,0.0,0.0)); +#28= (NAMED_UNIT(#21)LENGTH_UNIT()SI_UNIT(.MILLI.,.METRE.)); +#29=CLOSED_SHELL('',(#156,#191,#226,#261,#296,#331)); +#100=CARTESIAN_POINT('',(-100.000000000,-99.999984741,100.000015259)); +#101=VERTEX_POINT('',#100); +#102=CARTESIAN_POINT('',(-100.000000000,100.000015259,99.999984741)); +#103=VERTEX_POINT('',#102); +#104=CARTESIAN_POINT('',(-100.000000000,99.999984741,-100.000015259)); +#105=VERTEX_POINT('',#104); +#106=CARTESIAN_POINT('',(-100.000000000,-100.000015259,-99.999984741)); +#107=VERTEX_POINT('',#106); +#108=CARTESIAN_POINT('',(-100.000000000,-100.000015259,-99.999984741)); +#109=VERTEX_POINT('',#108); +#110=CARTESIAN_POINT('',(-100.000000000,99.999984741,-100.000015259)); +#111=VERTEX_POINT('',#110); +#112=CARTESIAN_POINT('',(100.000000000,99.999984741,-100.000015259)); +#113=VERTEX_POINT('',#112); +#114=CARTESIAN_POINT('',(100.000000000,-100.000015259,-99.999984741)); +#115=VERTEX_POINT('',#114); +#116=CARTESIAN_POINT('',(100.000000000,-100.000015259,-99.999984741)); +#117=VERTEX_POINT('',#116); +#118=CARTESIAN_POINT('',(100.000000000,99.999984741,-100.000015259)); +#119=VERTEX_POINT('',#118); +#120=CARTESIAN_POINT('',(100.000000000,100.000015259,99.999984741)); +#121=VERTEX_POINT('',#120); +#122=CARTESIAN_POINT('',(100.000000000,-99.999984741,100.000015259)); +#123=VERTEX_POINT('',#122); +#124=CARTESIAN_POINT('',(100.000000000,-99.999984741,100.000015259)); +#125=VERTEX_POINT('',#124); +#126=CARTESIAN_POINT('',(100.000000000,100.000015259,99.999984741)); +#127=VERTEX_POINT('',#126); +#128=CARTESIAN_POINT('',(-100.000000000,100.000015259,99.999984741)); +#129=VERTEX_POINT('',#128); +#130=CARTESIAN_POINT('',(-100.000000000,-99.999984741,100.000015259)); +#131=VERTEX_POINT('',#130); +#132=CARTESIAN_POINT('',(-100.000000000,-100.000015259,-99.999984741)); +#133=VERTEX_POINT('',#132); +#134=CARTESIAN_POINT('',(100.000000000,-100.000015259,-99.999984741)); +#135=VERTEX_POINT('',#134); +#136=CARTESIAN_POINT('',(100.000000000,-99.999984741,100.000015259)); +#137=VERTEX_POINT('',#136); +#138=CARTESIAN_POINT('',(-100.000000000,-99.999984741,100.000015259)); +#139=VERTEX_POINT('',#138); +#140=CARTESIAN_POINT('',(100.000000000,99.999984741,-100.000015259)); +#141=VERTEX_POINT('',#140); +#142=CARTESIAN_POINT('',(-100.000000000,99.999984741,-100.000015259)); +#143=VERTEX_POINT('',#142); +#144=CARTESIAN_POINT('',(-100.000000000,100.000015259,99.999984741)); +#145=VERTEX_POINT('',#144); +#146=CARTESIAN_POINT('',(100.000000000,100.000015259,99.999984741)); +#147=VERTEX_POINT('',#146); +#148=STYLED_ITEM('',(#149),#156); +#149=PRESENTATION_STYLE_ASSIGNMENT((#150)); +#150=SURFACE_STYLE_USAGE(.BOTH.,#151); +#151=SURFACE_SIDE_STYLE('',(#152)); +#152=SURFACE_STYLE_FILL_AREA(#153); +#153=FILL_AREA_STYLE('',(#154)); +#154=FILL_AREA_STYLE_COLOUR('',#155); +#155=COLOUR_RGB('',0.800000012,0.800000012,0.800000012); +#156=FACE_SURFACE('',(#161),#157,.T.); +#157=PLANE('',#158); +#158=AXIS2_PLACEMENT_3D('',#100,#159,#160); +#159=DIRECTION('',(1.000000000,0.000000000,0.000000000)); +#160=DIRECTION('',(0.000000000,1.000000000,0.000000000)); +#161=FACE_BOUND('',#162,.T.); +#162=EDGE_LOOP('',(#163,#164,#165,#166)); +#163=ORIENTED_EDGE('',*,*,#167,.T.); +#164=ORIENTED_EDGE('',*,*,#168,.T.); +#165=ORIENTED_EDGE('',*,*,#169,.T.); +#166=ORIENTED_EDGE('',*,*,#170,.T.); +#167=EDGE_CURVE('',#101,#103,#171,.F.); +#168=EDGE_CURVE('',#103,#105,#172,.T.); +#169=EDGE_CURVE('',#105,#107,#173,.T.); +#170=EDGE_CURVE('',#107,#101,#174,.T.); +#171=LINE('',#100,#175); +#172=LINE('',#102,#176); +#173=LINE('',#104,#177); +#174=LINE('',#106,#178); +#175=VECTOR('',#179,1.0); +#176=VECTOR('',#180,1.0); +#177=VECTOR('',#181,1.0); +#178=VECTOR('',#182,1.0); +#179=DIRECTION('',(0.000000000,0.000000000,1.000000000)); +#180=DIRECTION('',(0.000000000,1.000000000,0.000000000)); +#181=DIRECTION('',(0.000000000,0.000000000,-1.000000000)); +#182=DIRECTION('',(0.000000000,-1.000000000,0.000000000)); +#183=STYLED_ITEM('',(#184),#191); +#184=PRESENTATION_STYLE_ASSIGNMENT((#185)); +#185=SURFACE_STYLE_USAGE(.BOTH.,#186); +#186=SURFACE_SIDE_STYLE('',(#187)); +#187=SURFACE_STYLE_FILL_AREA(#188); +#188=FILL_AREA_STYLE('',(#189)); +#189=FILL_AREA_STYLE_COLOUR('',#190); +#190=COLOUR_RGB('',0.800000012,0.800000012,0.800000012); +#191=FACE_SURFACE('',(#196),#192,.T.); +#192=PLANE('',#193); +#193=AXIS2_PLACEMENT_3D('',#108,#194,#195); +#194=DIRECTION('',(0.000000000,-1.000000000,0.000000000)); +#195=DIRECTION('',(1.000000000,0.000000000,0.000000000)); +#196=FACE_BOUND('',#197,.T.); +#197=EDGE_LOOP('',(#198,#199,#200,#201)); +#198=ORIENTED_EDGE('',*,*,#202,.T.); +#199=ORIENTED_EDGE('',*,*,#203,.T.); +#200=ORIENTED_EDGE('',*,*,#204,.T.); +#201=ORIENTED_EDGE('',*,*,#205,.T.); +#202=EDGE_CURVE('',#109,#111,#206,.F.); +#203=EDGE_CURVE('',#111,#113,#207,.T.); +#204=EDGE_CURVE('',#113,#115,#208,.T.); +#205=EDGE_CURVE('',#115,#109,#209,.T.); +#206=LINE('',#108,#210); +#207=LINE('',#110,#211); +#208=LINE('',#112,#212); +#209=LINE('',#114,#213); +#210=VECTOR('',#214,1.0); +#211=VECTOR('',#215,1.0); +#212=VECTOR('',#216,1.0); +#213=VECTOR('',#217,1.0); +#214=DIRECTION('',(0.000000000,0.000000000,1.000000000)); +#215=DIRECTION('',(1.000000000,0.000000000,0.000000000)); +#216=DIRECTION('',(0.000000000,0.000000000,-1.000000000)); +#217=DIRECTION('',(-1.000000000,0.000000000,0.000000000)); +#218=STYLED_ITEM('',(#219),#226); +#219=PRESENTATION_STYLE_ASSIGNMENT((#220)); +#220=SURFACE_STYLE_USAGE(.BOTH.,#221); +#221=SURFACE_SIDE_STYLE('',(#222)); +#222=SURFACE_STYLE_FILL_AREA(#223); +#223=FILL_AREA_STYLE('',(#224)); +#224=FILL_AREA_STYLE_COLOUR('',#225); +#225=COLOUR_RGB('',0.800000012,0.800000012,0.800000012); +#226=FACE_SURFACE('',(#231),#227,.T.); +#227=PLANE('',#228); +#228=AXIS2_PLACEMENT_3D('',#116,#229,#230); +#229=DIRECTION('',(-1.000000000,0.000000000,0.000000000)); +#230=DIRECTION('',(0.000000000,-1.000000000,0.000000000)); +#231=FACE_BOUND('',#232,.T.); +#232=EDGE_LOOP('',(#233,#234,#235,#236)); +#233=ORIENTED_EDGE('',*,*,#237,.T.); +#234=ORIENTED_EDGE('',*,*,#238,.T.); +#235=ORIENTED_EDGE('',*,*,#239,.T.); +#236=ORIENTED_EDGE('',*,*,#240,.T.); +#237=EDGE_CURVE('',#117,#119,#241,.F.); +#238=EDGE_CURVE('',#119,#121,#242,.T.); +#239=EDGE_CURVE('',#121,#123,#243,.T.); +#240=EDGE_CURVE('',#123,#117,#244,.T.); +#241=LINE('',#116,#245); +#242=LINE('',#118,#246); +#243=LINE('',#120,#247); +#244=LINE('',#122,#248); +#245=VECTOR('',#249,1.0); +#246=VECTOR('',#250,1.0); +#247=VECTOR('',#251,1.0); +#248=VECTOR('',#252,1.0); +#249=DIRECTION('',(0.000000000,0.000000000,1.000000000)); +#250=DIRECTION('',(0.000000000,-1.000000000,0.000000000)); +#251=DIRECTION('',(0.000000000,0.000000000,-1.000000000)); +#252=DIRECTION('',(0.000000000,1.000000000,0.000000000)); +#253=STYLED_ITEM('',(#254),#261); +#254=PRESENTATION_STYLE_ASSIGNMENT((#255)); +#255=SURFACE_STYLE_USAGE(.BOTH.,#256); +#256=SURFACE_SIDE_STYLE('',(#257)); +#257=SURFACE_STYLE_FILL_AREA(#258); +#258=FILL_AREA_STYLE('',(#259)); +#259=FILL_AREA_STYLE_COLOUR('',#260); +#260=COLOUR_RGB('',0.800000012,0.800000012,0.800000012); +#261=FACE_SURFACE('',(#266),#262,.T.); +#262=PLANE('',#263); +#263=AXIS2_PLACEMENT_3D('',#124,#264,#265); +#264=DIRECTION('',(0.000000000,1.000000000,-0.000000000)); +#265=DIRECTION('',(-1.000000000,0.000000000,0.000000000)); +#266=FACE_BOUND('',#267,.T.); +#267=EDGE_LOOP('',(#268,#269,#270,#271)); +#268=ORIENTED_EDGE('',*,*,#272,.T.); +#269=ORIENTED_EDGE('',*,*,#273,.T.); +#270=ORIENTED_EDGE('',*,*,#274,.T.); +#271=ORIENTED_EDGE('',*,*,#275,.T.); +#272=EDGE_CURVE('',#125,#127,#276,.F.); +#273=EDGE_CURVE('',#127,#129,#277,.T.); +#274=EDGE_CURVE('',#129,#131,#278,.T.); +#275=EDGE_CURVE('',#131,#125,#279,.T.); +#276=LINE('',#124,#280); +#277=LINE('',#126,#281); +#278=LINE('',#128,#282); +#279=LINE('',#130,#283); +#280=VECTOR('',#284,1.0); +#281=VECTOR('',#285,1.0); +#282=VECTOR('',#286,1.0); +#283=VECTOR('',#287,1.0); +#284=DIRECTION('',(0.000000000,0.000000000,1.000000000)); +#285=DIRECTION('',(-1.000000000,0.000000000,0.000000000)); +#286=DIRECTION('',(0.000000000,0.000000000,-1.000000000)); +#287=DIRECTION('',(1.000000000,0.000000000,0.000000000)); +#288=STYLED_ITEM('',(#289),#296); +#289=PRESENTATION_STYLE_ASSIGNMENT((#290)); +#290=SURFACE_STYLE_USAGE(.BOTH.,#291); +#291=SURFACE_SIDE_STYLE('',(#292)); +#292=SURFACE_STYLE_FILL_AREA(#293); +#293=FILL_AREA_STYLE('',(#294)); +#294=FILL_AREA_STYLE_COLOUR('',#295); +#295=COLOUR_RGB('',0.800000012,0.800000012,0.800000012); +#296=FACE_SURFACE('',(#301),#297,.T.); +#297=PLANE('',#298); +#298=AXIS2_PLACEMENT_3D('',#132,#299,#300); +#299=DIRECTION('',(-0.000000000,0.000000000,1.000000000)); +#300=DIRECTION('',(0.000000000,-1.000000000,0.000000000)); +#301=FACE_BOUND('',#302,.T.); +#302=EDGE_LOOP('',(#303,#304,#305,#306)); +#303=ORIENTED_EDGE('',*,*,#307,.T.); +#304=ORIENTED_EDGE('',*,*,#308,.T.); +#305=ORIENTED_EDGE('',*,*,#309,.T.); +#306=ORIENTED_EDGE('',*,*,#310,.T.); +#307=EDGE_CURVE('',#133,#135,#311,.F.); +#308=EDGE_CURVE('',#135,#137,#312,.T.); +#309=EDGE_CURVE('',#137,#139,#313,.T.); +#310=EDGE_CURVE('',#139,#133,#314,.T.); +#311=LINE('',#132,#315); +#312=LINE('',#134,#316); +#313=LINE('',#136,#317); +#314=LINE('',#138,#318); +#315=VECTOR('',#319,1.0); +#316=VECTOR('',#320,1.0); +#317=VECTOR('',#321,1.0); +#318=VECTOR('',#322,1.0); +#319=DIRECTION('',(1.000000000,0.000000000,0.000000000)); +#320=DIRECTION('',(0.000000000,-1.000000000,0.000000000)); +#321=DIRECTION('',(-1.000000000,0.000000000,0.000000000)); +#322=DIRECTION('',(0.000000000,1.000000000,0.000000000)); +#323=STYLED_ITEM('',(#324),#331); +#324=PRESENTATION_STYLE_ASSIGNMENT((#325)); +#325=SURFACE_STYLE_USAGE(.BOTH.,#326); +#326=SURFACE_SIDE_STYLE('',(#327)); +#327=SURFACE_STYLE_FILL_AREA(#328); +#328=FILL_AREA_STYLE('',(#329)); +#329=FILL_AREA_STYLE_COLOUR('',#330); +#330=COLOUR_RGB('',0.800000012,0.800000012,0.800000012); +#331=FACE_SURFACE('',(#336),#332,.T.); +#332=PLANE('',#333); +#333=AXIS2_PLACEMENT_3D('',#140,#334,#335); +#334=DIRECTION('',(-0.000000000,-0.000000000,-1.000000000)); +#335=DIRECTION('',(0.000000000,-1.000000000,0.000000000)); +#336=FACE_BOUND('',#337,.T.); +#337=EDGE_LOOP('',(#338,#339,#340,#341)); +#338=ORIENTED_EDGE('',*,*,#342,.T.); +#339=ORIENTED_EDGE('',*,*,#343,.T.); +#340=ORIENTED_EDGE('',*,*,#344,.T.); +#341=ORIENTED_EDGE('',*,*,#345,.T.); +#342=EDGE_CURVE('',#141,#143,#346,.F.); +#343=EDGE_CURVE('',#143,#145,#347,.T.); +#344=EDGE_CURVE('',#145,#147,#348,.T.); +#345=EDGE_CURVE('',#147,#141,#349,.T.); +#346=LINE('',#140,#350); +#347=LINE('',#142,#351); +#348=LINE('',#144,#352); +#349=LINE('',#146,#353); +#350=VECTOR('',#354,1.0); +#351=VECTOR('',#355,1.0); +#352=VECTOR('',#356,1.0); +#353=VECTOR('',#357,1.0); +#354=DIRECTION('',(-1.000000000,0.000000000,0.000000000)); +#355=DIRECTION('',(0.000000000,-1.000000000,0.000000000)); +#356=DIRECTION('',(1.000000000,0.000000000,0.000000000)); +#357=DIRECTION('',(0.000000000,1.000000000,0.000000000)); +ENDSEC; +END-ISO-10303-21; diff --git a/index.js b/index.js index a7f2bbd..f16d9b4 100644 --- a/index.js +++ b/index.js @@ -2,28 +2,21 @@ import color from "picocolors"; import { showMainMenu } from "./lib/menu.js"; -// 主循环 while (true) { const selected = await showMainMenu(); console.clear(); - console.log(color.cyan(`\n正在启动: ${selected.name}...\n`)); + console.log(color.cyan("\n正在启动: " + selected.name + "...\n")); try { const tool = await import(selected.module); const result = await tool.run(); - - // 返回主菜单 if (result === "back") continue; - - // 工具完成后退出 break; } catch (err) { - console.log(color.yellow(`\n⚠️ ${selected.name} 模块尚未实现`)); + console.log(color.yellow("\n⚠️ " + selected.name + " 模块尚未实现")); console.log(color.dim(err.message)); console.log(color.dim("\n按任意键返回主菜单...")); - - // 等待按键 await new Promise(resolve => { process.stdin.setRawMode(true); process.stdin.once("data", () => { diff --git a/lib/convert/config.js b/lib/convert/config.js new file mode 100644 index 0000000..6ff27bc --- /dev/null +++ b/lib/convert/config.js @@ -0,0 +1,35 @@ +import fs from "fs"; +import { getImportExtensions, getExportFormats } from "./converters.js"; +import { sortByUsage } from "../stats.js"; + +export function listConvertibleFiles() { + const cwd = process.cwd(); + const exts = getImportExtensions(); + return fs.readdirSync(cwd).filter(file => { + const ext = file.slice(file.lastIndexOf(".")).toLowerCase(); + return exts.includes(ext); + }); +} + +export function getSteps() { + const files = listConvertibleFiles(); + const formats = sortByUsage("convert_format", getExportFormats()); + + return [ + { + name: "源文件", + type: "multiselect", + message: files.length ? "选择要转换的模型文件" : "当前目录未找到可转换的模型文件", + options: files.map(file => ({ value: file, label: file })), + default: [], + emptyMessage: "请按 Esc 返回并放入模型文件后重试" + }, + { + name: "输出格式", + type: "select", + message: "选择目标格式", + options: formats.map(f => ({ value: f, label: f })), + default: formats[0] + } + ]; +} diff --git a/lib/convert/converters.js b/lib/convert/converters.js new file mode 100644 index 0000000..1c003b6 --- /dev/null +++ b/lib/convert/converters.js @@ -0,0 +1,31 @@ +import { spawnSync } from "child_process"; +import path from "path"; +import { fileURLToPath } from "url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const ASSIMP_PATH = path.join(__dirname, "../../bin/assimp.exe"); + +let importExts = null; +let exportFormats = null; + +export function getImportExtensions() { + if (!importExts) { + const r = spawnSync(ASSIMP_PATH, ["listext"], { encoding: "utf8" }); + importExts = r.stdout.trim().split(";").map(e => e.replace("*", "").toLowerCase()); + } + return importExts; +} + +export function getExportFormats() { + if (!exportFormats) { + const r = spawnSync(ASSIMP_PATH, ["listexport"], { encoding: "utf8" }); + exportFormats = r.stdout.trim().split(/\r?\n/).filter(Boolean); + } + return exportFormats; +} + +export async function convert(inputFile, outputFile, format, cwd = process.cwd()) { + const r = spawnSync(ASSIMP_PATH, ["export", inputFile, outputFile, `-f${format}`], { encoding: "utf8", cwd }); + if (r.status !== 0) throw new Error(r.stderr || r.stdout || "转换失败"); + return outputFile; +} diff --git a/lib/convert/index.js b/lib/convert/index.js new file mode 100644 index 0000000..4e9a635 --- /dev/null +++ b/lib/convert/index.js @@ -0,0 +1,108 @@ +import fs from "fs"; +import path from "path"; +import color from "picocolors"; +import { convert } from "./converters.js"; +import { runInteractive, showSummary } from "./ui.js"; +import { stopKeypress, initKeypress, onKey } from "../keyboard.js"; +import { record } from "../stats.js"; + +const FORMAT_EXT = { + collada: ".dae", x: ".x", stp: ".stp", obj: ".obj", objnomtl: ".obj", + stl: ".stl", stlb: ".stl", ply: ".ply", plyb: ".ply", "3ds": ".3ds", + gltf2: ".gltf", glb2: ".glb", gltf: ".gltf", glb: ".glb", + assbin: ".assbin", assxml: ".assxml", x3d: ".x3d", + fbx: ".fbx", fbxa: ".fbx", "3mf": ".3mf", pbrt: ".pbrt", assjson: ".json" +}; + +function getOutputExt(format) { + return FORMAT_EXT[format] || "." + format; +} + +async function processFile(file, config) { + const cwd = process.cwd(); + const baseName = file.slice(0, file.lastIndexOf(".")); + const outputExt = getOutputExt(config.outputFormat); + const outputFile = baseName + outputExt; + + if (!fs.existsSync(path.join(cwd, file))) { + return { ok: false, file, reason: "文件不存在" }; + } + + await convert(file, outputFile, config.outputFormat, cwd); + return { ok: true, file, output: outputFile }; +} + +async function waitForEsc() { + initKeypress(); + return new Promise(resolve => { + onKey((str, key) => { + if (key?.name === "escape" || (key?.ctrl && key?.name === "c")) { + resolve(); + } + }); + }); +} + +export async function run() { + const result = await runInteractive(); + if (!result) return "back"; + + const { steps, results } = result; + const config = { + files: results[0] || [], + outputFormat: results[1] || "glb2" + }; + + stopKeypress(); + showSummary([ + "源文件: " + (config.files.length ? config.files.join(", ") : "未选择"), + "目标格式: " + config.outputFormat.toUpperCase() + ]); + + if (!config.files.length) { + console.log(color.yellow("未选择任何模型文件")); + console.log(color.dim("\n按 Esc 返回")); + await waitForEsc(); + return "back"; + } + + const total = config.files.length; + let success = 0; + const failed = []; + + console.log(color.cyan(`开始转换 ${total} 个文件...\n`)); + + for (let i = 0; i < config.files.length; i++) { + const file = config.files[i]; + const progress = `[${i + 1}/${total}]`; + console.log(color.dim(`${progress} 处理中: ${file}`)); + + try { + const result = await processFile(file, config); + if (result.ok) { + success++; + record("convert_format", config.outputFormat); + console.log(color.green(`${progress} ✓ ${file} → ${path.basename(result.output)}`)); + } else { + failed.push({ file, reason: result.reason }); + console.log(color.yellow(`${progress} ⊘ 跳过: ${file} (${result.reason})`)); + } + } catch (err) { + failed.push({ file, reason: err?.message || String(err) }); + console.log(color.red(`${progress} ✖ 失败: ${file}`)); + console.log(color.dim(" " + String(err?.message || err))); + } + } + + console.log("\n" + color.bgGreen(color.black(" 转换完成 "))); + if (success) { + console.log(color.green(`成功: ${success} 个`)); + } + if (failed.length) { + console.log(color.yellow(`失败: ${failed.length} 个`)); + } + + console.log(color.dim("\n按 Esc 返回")); + await waitForEsc(); + return "back"; +} diff --git a/lib/convert/ui.js b/lib/convert/ui.js new file mode 100644 index 0000000..5b1b5cd --- /dev/null +++ b/lib/convert/ui.js @@ -0,0 +1,9 @@ +import { createStepUI } from "../utils/stepui.js"; +import { getSteps } from "./config.js"; + +const ui = createStepUI({ + title: "格式转换工具", + getSteps +}); + +export const { runInteractive, showSummary } = ui; diff --git a/lib/gltf/config.js b/lib/gltf/config.js new file mode 100644 index 0000000..68d0a95 --- /dev/null +++ b/lib/gltf/config.js @@ -0,0 +1,27 @@ +import { listGltfFiles } from "../utils/gltf.js"; + +const extensionStep = { + name: "扩展选项", + type: "multiselect", + message: "请选择要添加的glTF扩展", + options: [ + { value: "textureBasisu", label: "KHR_texture_basisu(纹理自动扩展)", hint: "自动添加KTX2纹理扩展支持" }, + { value: "placeholder1", label: "预留选项1", hint: "功能开发中..." }, + { value: "placeholder2", label: "预留选项2", hint: "功能开发中..." }, + { value: "placeholder3", label: "预留选项3", hint: "功能开发中..." } + ], + default: ["textureBasisu"] +}; + +export function getSteps() { + const files = listGltfFiles(); + const fileStep = { + name: "文件选择", + type: "multiselect", + message: files.length ? "请选择要处理的glTF文件" : "当前目录未找到glTF文件", + options: files.map(file => ({ value: file, label: file })), + default: [...files] + }; + + return [fileStep, extensionStep]; +} diff --git a/lib/gltf/index.js b/lib/gltf/index.js new file mode 100644 index 0000000..83f4320 --- /dev/null +++ b/lib/gltf/index.js @@ -0,0 +1,73 @@ +import fs from "fs"; +import path from "path"; +import color from "picocolors"; +import { checkRequiredFiles, modifyGltfContent, listGltfFiles, BACKUP_SUFFIX } from "../utils/gltf.js"; +import { runInteractive, showSummary } from "./ui.js"; +import { stopKeypress, waitForKey } from "../keyboard.js"; + +export function runGltfExtension(config = { files: [], extensions: ["textureBasisu"] }) { + const cwd = process.cwd(); + const { files = [], extensions = ["textureBasisu"] } = config; + const selectedExtensions = extensions.length ? extensions : ["textureBasisu"]; + + const { ok, missing } = checkRequiredFiles(); + if (!ok) { + console.log(color.red("\n✖ 缺少必要文件: " + missing.join(", "))); + console.log(color.dim("请确保当前目录包含 .ktx2、.gltf 和 .bin 文件\n")); + return { success: false, count: 0 }; + } + + const fallbackFiles = listGltfFiles(); + const gltfFiles = (files.length ? files : fallbackFiles).filter(f => f.toLowerCase().endsWith(".gltf")); + if (!gltfFiles.length) { + console.log(color.yellow("未选择可处理的 glTF 文件")); + return { success: false, count: 0 }; + } + + let count = 0; + + for (const file of gltfFiles) { + const fullPath = path.join(cwd, file); + if (!fs.existsSync(fullPath)) { + console.log(color.yellow("跳过缺失的文件: " + file)); + continue; + } + const baseName = file.replace(/\.gltf$/i, ""); + const backupName = baseName + BACKUP_SUFFIX + ".gltf"; + const backupPath = path.join(cwd, backupName); + + fs.copyFileSync(fullPath, backupPath); + const modified = modifyGltfContent(fullPath, selectedExtensions); + fs.writeFileSync(fullPath, JSON.stringify(modified, null, 2), "utf-8"); + console.log(color.green("✓ " + file + " (备份: " + backupName + ")")); + count++; + } + + return { success: count > 0, count }; +} + +export async function run() { + const result = await runInteractive(); + if (!result) return "back"; + + stopKeypress(); + + const { results } = result; + const config = { + files: results[0] || [], + extensions: results[1] || [] + }; + + showSummary([ + "处理文件: " + (config.files.length ? config.files.join(", ") : "未选择"), + "扩展选项: " + (config.extensions.length ? config.extensions.join(", ") : "未选择") + ]); + + const { success, count } = runGltfExtension(config); + if (success) { + console.log(color.green("\n✓ 已修改 " + count + " 个 glTF 文件")); + } + + await waitForKey(); + return "back"; +} diff --git a/lib/gltf/ui.js b/lib/gltf/ui.js new file mode 100644 index 0000000..98c5dff --- /dev/null +++ b/lib/gltf/ui.js @@ -0,0 +1,9 @@ +import { createStepUI } from "../utils/stepui.js"; +import { getSteps } from "./config.js"; + +const ui = createStepUI({ + title: "glTF 扩展工具", + getSteps +}); + +export const { runInteractive, showSummary } = ui; diff --git a/lib/grid.js b/lib/grid.js index 45e315f..810dc11 100644 --- a/lib/grid.js +++ b/lib/grid.js @@ -1,6 +1,16 @@ import color from "picocolors"; import { initKeypress, onKey } from "./keyboard.js"; +function clearScreen() { + if (process.stdout.isTTY) { + process.stdout.write("\x1b[2J"); // clear screen + process.stdout.write("\x1b[3J"); // clear scrollback + process.stdout.write("\x1b[H"); // move cursor home + } else { + console.clear(); + } +} + // 计算字符串显示宽度 function strWidth(str) { let width = 0; @@ -35,7 +45,7 @@ export async function gridSelect(options) { const pad = " ".repeat(Math.max(0, Math.floor((termWidth - totalWidth) / 2))); function render() { - console.clear(); + clearScreen(); if (renderHeader) { console.log(renderHeader()); @@ -110,7 +120,7 @@ export async function gridSelect(options) { setImmediate(() => resolve(items[current])); } else if (key.name === "escape" || (key.ctrl && key.name === "c")) { process.stdin.setRawMode(false); - console.clear(); + clearScreen(); console.log(color.yellow("👋 再见!")); process.exit(0); } diff --git a/lib/keyboard.js b/lib/keyboard.js index 98142e3..2675a64 100644 --- a/lib/keyboard.js +++ b/lib/keyboard.js @@ -16,3 +16,22 @@ export function initKeypress() { export function onKey(handler) { process.stdin.on("keypress", handler); } + +export function stopKeypress() { + process.stdin.removeAllListeners("keypress"); + if (process.stdin.isTTY) { + process.stdin.setRawMode(false); + } +} + +export function waitForKey(message = "按任意键返回...") { + return new Promise(resolve => { + console.log("\n" + message); + initKeypress(); + const handler = () => { + stopKeypress(); + resolve(); + }; + process.stdin.once("keypress", handler); + }); +} diff --git a/lib/ktx2/config.js b/lib/ktx2/config.js index 1d9f0da..1efcbda 100644 --- a/lib/ktx2/config.js +++ b/lib/ktx2/config.js @@ -55,7 +55,8 @@ export const steps = [ { value: "overwrite", label: "覆盖已存在文件(自动替换同名文件)" }, { value: "keepOriginal", label: "保留原文件(压缩后不删除源文件)" }, { value: "report", label: "生成压缩报告(输出详细的压缩统计信息)" }, - { value: "silent", label: "静默模式(减少控制台输出信息)" } + { value: "silent", label: "静默模式(减少控制台输出信息)" }, + { value: "gltfExtension", label: "修改glTF扩展(添加KHR_texture_basisu)", dynamic: true } ], default: ["overwrite", "keepOriginal"] } diff --git a/lib/ktx2/gltf.js b/lib/ktx2/gltf.js new file mode 100644 index 0000000..263e514 --- /dev/null +++ b/lib/ktx2/gltf.js @@ -0,0 +1,3 @@ +// 从 utils 导出,保持兼容 +export { hasGltfFile, checkRequiredFiles, modifyGltfContent } from "../utils/gltf.js"; +export { runGltfExtension } from "../gltf/index.js"; diff --git a/lib/ktx2/index.js b/lib/ktx2/index.js index 79a2468..cae45c1 100644 --- a/lib/ktx2/index.js +++ b/lib/ktx2/index.js @@ -1,40 +1,49 @@ import color from "picocolors"; import { checkToktx, scanImages, compressAll } from "./compressor.js"; import { runInteractive, showSummary } from "./ui.js"; +import { runGltfExtension } from "./gltf.js"; +import { stopKeypress, waitForKey } from "../keyboard.js"; export async function run() { - // 检查 toktx checkToktx(); - - // 运行交互界面 const result = await runInteractive(); - - // ESC 返回主菜单 if (!result) return "back"; - const [exts, quality, encoding, mipmap, outputOpts] = result; + stopKeypress(); + + const { results } = result; + const [exts, quality, encoding, mipmap, outputOpts] = results; const config = { exts, quality, encoding, mipmap, outputOpts }; + showSummary([ + "文件格式: " + config.exts.join(", "), + "压缩程度: " + config.quality, + "编码格式: " + config.encoding, + "Mipmap: " + config.mipmap, + "输出选项: " + config.outputOpts.join(", ") + ]); - // 显示配置摘要 - showSummary(config); - - // 扫描文件 const { images, cwd } = scanImages(exts); - if (images.length === 0) { console.log(color.yellow("当前目录没有匹配的图片")); - return; + await waitForKey(); + return "back"; } - console.log(`📁 找到 ${color.cyan(images.length)} 个待转换文件\n`); - - // 执行压缩 + console.log("📁 找到 " + color.cyan(images.length) + " 个待转换文件\n"); const { total, failed } = await compressAll(images, config, cwd); - // 显示结果 if (failed > 0) { - console.log(color.yellow(`\n⚠️ 完成,但有 ${failed} 个文件失败`)); + console.log(color.yellow("\n⚠️ 完成,但有 " + failed + " 个文件失败")); } else { console.log(color.green("\n🎉 全部文件压缩完成!")); } + + if (outputOpts.includes("gltfExtension")) { + console.log(color.cyan("\n正在修改 glTF 文件...")); + const { success, count } = runGltfExtension(); + if (success) console.log(color.green("✓ 已修改 " + count + " 个 glTF 文件")); + } + + await waitForKey(); + return "back"; } diff --git a/lib/ktx2/ui.js b/lib/ktx2/ui.js index 5725a19..4c59a92 100644 --- a/lib/ktx2/ui.js +++ b/lib/ktx2/ui.js @@ -1,151 +1,20 @@ -import color from "picocolors"; +import { createStepUI } from "../utils/stepui.js"; import { steps } from "./config.js"; -import { initKeypress, onKey } from "../keyboard.js"; +import { hasGltfFile } from "./gltf.js"; -// 存储结果和状态 -let results = []; -let completed = new Set(); -let currentStep = 0; -let currentOption = 0; - -// 初始化结果 -export function initResults() { - results = steps.map(s => s.type === "multiselect" ? [...s.default] : s.default); - completed = new Set(); - currentStep = 0; - currentOption = 0; -} - -// 渲染导航栏 -function renderNav() { - const nav = steps.map((step, i) => { - if (completed.has(i)) { - return color.green(`☑ ${step.name}`); - } else if (i === currentStep) { - return color.bgCyan(color.black(` ${step.name} `)); - } else { - return color.dim(`□ ${step.name}`); +function getFilteredSteps() { + const hasGltf = hasGltfFile(); + return steps.map(step => { + if (step.name === "输出选项") { + return { ...step, options: step.options.filter(opt => !opt.dynamic || hasGltf) }; } - }); - return `← ${nav.join(" ")} ${color.green("✓Submit")} →`; -} - -// 渲染选项列表 -function renderOptions() { - const step = steps[currentStep]; - const lines = []; - - lines.push(color.cyan(step.message)); - lines.push(""); - - step.options.forEach((opt, i) => { - const isCurrent = i === currentOption; - const isSelected = step.type === "multiselect" - ? results[currentStep].includes(opt.value) - : results[currentStep] === opt.value; - - let prefix; - if (step.type === "multiselect") { - prefix = isSelected ? color.green("◉ ") : "○ "; - } else { - prefix = isSelected ? color.green("● ") : "○ "; - } - - const cursor = isCurrent ? color.cyan("❯ ") : " "; - const label = isCurrent ? color.cyan(opt.label) : opt.label; - const check = isSelected ? color.green(" ✓") : ""; - - lines.push(`${cursor}${prefix}${label}${check}`); - if (opt.hint) { - lines.push(` ${color.dim(opt.hint)}`); - } - }); - - return lines.join("\n"); -} - -// 渲染整个界面 -function render() { - console.clear(); - console.log(color.bgCyan(color.black(" KTX2 纹理压缩工具 "))); - console.log("\n" + renderNav()); - console.log(color.dim("\n← → 切换步骤 | ↑ ↓ 选择 | Space 选中 | Tab 提交 | Esc 返回\n")); - console.log(renderOptions()); -} - -// 主交互循环 -export async function runInteractive() { - initResults(); - initKeypress(); - - return new Promise((resolve) => { - render(); - - onKey((str, key) => { - if (!key) return; - - const step = steps[currentStep]; - const optCount = step.options.length; - - if (key.name === "left") { - if (currentStep > 0) { - currentStep--; - currentOption = 0; - } - render(); - } else if (key.name === "right") { - if (currentStep < steps.length - 1) { - currentStep++; - currentOption = 0; - } - render(); - } else if (key.name === "up") { - currentOption = (currentOption - 1 + optCount) % optCount; - render(); - } else if (key.name === "down") { - currentOption = (currentOption + 1) % optCount; - render(); - } else if (key.name === "space") { - const opt = step.options[currentOption]; - if (step.type === "multiselect") { - const idx = results[currentStep].indexOf(opt.value); - if (idx >= 0) { - results[currentStep].splice(idx, 1); - } else { - results[currentStep].push(opt.value); - } - } else { - results[currentStep] = opt.value; - } - completed.add(currentStep); - render(); - } else if (key.name === "return") { - if (step.type === "select") { - results[currentStep] = step.options[currentOption].value; - } - completed.add(currentStep); - if (currentStep < steps.length - 1) { - currentStep++; - currentOption = 0; - } - render(); - } else if (key.name === "tab") { - resolve(results); - } else if (key.name === "escape" || (key.ctrl && key.name === "c")) { - resolve(null); - } - }); + return step; }); } -// 显示配置摘要 -export function showSummary(config) { - console.clear(); - console.log(color.bgCyan(color.black(" KTX2 纹理压缩工具 "))); - console.log("\n" + color.green("配置完成!当前设置:")); - console.log(` 文件格式: ${config.exts.join(", ")}`); - console.log(` 压缩程度: ${config.quality}`); - console.log(` 编码格式: ${config.encoding}`); - console.log(` Mipmap: ${config.mipmap}`); - console.log(` 输出选项: ${config.outputOpts.join(", ")}\n`); -} +const ui = createStepUI({ + title: "KTX2 纹理压缩工具", + getSteps: getFilteredSteps +}); + +export const { runInteractive, showSummary } = ui; diff --git a/lib/menu.js b/lib/menu.js index fc95072..81b77e1 100644 --- a/lib/menu.js +++ b/lib/menu.js @@ -3,7 +3,6 @@ import boxen from "boxen"; import figlet from "figlet"; import { gridSelect } from "./grid.js"; -// 古诗配置 let poemConfig = { lines: ["你我皆牛马", "生在人世间", "终日奔波苦", "一刻不得闲"], perLine: 2, @@ -12,16 +11,16 @@ let poemConfig = { borderColor: "cyan", }; -// 标题配置 let titleConfig = { text: "Zguiy Tool Box", font: "Standard", color: "magenta", }; -// 工具列表 const tools = [ + { name: "格式转换", desc: "OBJ/FBX转glTF", module: "./lib/convert/index.js" }, { name: "KTX2 纹理压缩", desc: "图片转KTX2格式", module: "./lib/ktx2/index.js" }, + { name: "glTF扩展", desc: "添加KHR_texture_basisu", module: "./lib/gltf/index.js" }, { name: "模型压缩", desc: "压缩glTF/GLB模型", module: "./lib/model/index.js" }, { name: "图片批量处理", desc: "裁剪/缩放/转换", module: "./lib/image/index.js" }, { name: "Sprite图集", desc: "合并精灵图集", module: "./lib/sprite/index.js" }, @@ -29,25 +28,21 @@ const tools = [ { name: "音频压缩", desc: "压缩音频文件", module: "./lib/audio/index.js" }, ]; -// 设置古诗 export function setPoem(lines, perLine = 2) { poemConfig.lines = lines; poemConfig.perLine = perLine; } -// 设置古诗框样式 export function setPoemStyle(style) { Object.assign(poemConfig, style); } -// 设置标题 export function setTitle(text, font = "Standard", titleColor = "magenta") { titleConfig.text = text; titleConfig.font = font; titleConfig.color = titleColor; } -// 渲染古诗 function renderPoem() { const merged = []; for (let i = 0; i < poemConfig.lines.length; i += poemConfig.perLine) { @@ -62,7 +57,6 @@ function renderPoem() { }); } -// 渲染标题 function renderTitle() { const art = figlet.textSync(titleConfig.text, { font: titleConfig.font }); const termWidth = process.stdout.columns || 80; @@ -72,12 +66,10 @@ function renderTitle() { }).join("\n"); } -// 渲染头部 function renderHeader() { return renderPoem() + "\n\n" + renderTitle(); } -// 主菜单 export async function showMainMenu() { return gridSelect({ items: tools, diff --git a/lib/model/config.js b/lib/model/config.js new file mode 100644 index 0000000..a96c421 --- /dev/null +++ b/lib/model/config.js @@ -0,0 +1,71 @@ +import { listAllModelFiles } from "../utils/gltf.js"; + +const transformOptions = [ + { value: "dedup", label: "dedup(去重)", hint: "删除重复的访问器、材质、网格" }, + { value: "prune", label: "prune(清理无用节点)", hint: "移除未被引用的节点、材质、动画" }, + { value: "resample", label: "resample(动画重采样)", hint: "统一动画关键帧间隔,减少多余数据" }, + { value: "weld", label: "weld(合并顶点)", hint: "合并共享位置的顶点以减少面数" }, + { value: "quantize", label: "quantize(量化顶点数据)", hint: "降低顶点属性精度减小模型体积" } +]; + +const quantizePresets = [ + { value: "high", label: "高质量(位置16位,法线12位,UV14位)", hint: "尽量保证细节,适合高保真场景" }, + { value: "balanced", label: "均衡(位置14位,法线10位,UV12位)", hint: "默认推荐,兼顾体积与质量" }, + { value: "aggressive", label: "极限压缩(位置12位,法线8位,UV10位)", hint: "最小体积,但可能损失细节" }, + { value: "light", label: "轻量(位置10位,法线8位,UV10位)", hint: "适合移动端、卡通等对精度不敏感场景" } +]; + +const outputFormats = [ + { value: "auto", label: "保持原格式", hint: "glTF/GLB保持原格式,OBJ/FBX转为GLB" }, + { value: "glb", label: "统一导出为 GLB(二进制)", hint: "单文件发布更方便" }, + { value: "gltf", label: "统一导出为 glTF(JSON)", hint: "可读性好,调试方便" } +]; + +const outputOptions = [ + { value: "overwrite", label: "覆盖原文件", hint: "直接把结果写回源文件" }, + { value: "backup", label: "保留备份 (_备份)", hint: "覆盖前在同目录生成 _备份 副本" }, + { value: "copy", label: "输出副本 (_compressed)", hint: "保留原文件不动,结果写入新文件" } +]; + +export function getSteps() { + const files = listAllModelFiles(); + const fileStep = { + name: "模型选择", + type: "multiselect", + message: files.length ? "选择要处理的模型(支持 glTF/GLB/OBJ/FBX)" : "当前目录未找到模型文件", + options: files.map(file => ({ value: file, label: file })), + default: [...files] + }; + + return [ + fileStep, + { + name: "压缩命令", + type: "multiselect", + message: "请选择要执行的 gltf-transform 操作", + options: transformOptions, + default: ["dedup", "prune", "weld", "quantize"] + }, + { + name: "量化级别", + type: "select", + message: "量化可显著减小体积(如未启用 quantize 可直接 Tab)", + options: quantizePresets, + default: "balanced" + }, + { + name: "输出格式", + type: "select", + message: "选择最终模型格式", + options: outputFormats, + default: "auto" + }, + { + name: "输出选项", + type: "multiselect", + message: "请选择输出行为", + options: outputOptions, + default: ["overwrite", "backup"] + } + ]; +} diff --git a/lib/model/index.js b/lib/model/index.js new file mode 100644 index 0000000..45d2912 --- /dev/null +++ b/lib/model/index.js @@ -0,0 +1,195 @@ +import fs from "fs"; +import path from "path"; +import color from "picocolors"; +import { NodeIO } from "@gltf-transform/core"; +import { ALL_EXTENSIONS } from "@gltf-transform/extensions"; +import { dedup, prune, resample, weld, quantize } from "@gltf-transform/functions"; +import { BACKUP_SUFFIX, needsConversion } from "../utils/gltf.js"; +import { convert } from "../convert/converters.js"; +import { runInteractive, showSummary } from "./ui.js"; +import { stopKeypress, waitForKey } from "../keyboard.js"; + +const io = new NodeIO().registerExtensions(ALL_EXTENSIONS); + +const QUANTIZE_PRESETS = { + high: { position: 16, normal: 12, texcoord: 14, color: 10, generic: 12 }, + balanced: { position: 14, normal: 10, texcoord: 12, color: 8, generic: 12 }, + aggressive: { position: 12, normal: 8, texcoord: 10, color: 8, generic: 10 }, + light: { position: 10, normal: 8, texcoord: 10, color: 8, generic: 10 } +}; + +function buildTransforms(config) { + const transforms = []; + const selected = new Set(config.commands); + if (selected.has("dedup")) transforms.push(dedup()); + if (selected.has("prune")) transforms.push(prune()); + if (selected.has("resample")) transforms.push(resample()); + if (selected.has("weld")) transforms.push(weld()); + if (selected.has("quantize")) { + const preset = QUANTIZE_PRESETS[config.quantizePreset] || QUANTIZE_PRESETS.balanced; + transforms.push(quantize({ + quantizePosition: preset.position, + quantizeNormal: preset.normal, + quantizeTexcoord: preset.texcoord, + quantizeColor: preset.color, + quantizeGeneric: preset.generic + })); + } + return transforms; +} + +function resolveOutput(file, config) { + const cwd = process.cwd(); + const originalExt = path.extname(file).toLowerCase() || ".gltf"; + const baseName = originalExt ? file.slice(0, -originalExt.length) : file; + const isConvertible = needsConversion(file); + + // OBJ/FBX 默认输出 GLB,除非指定了 gltf + const targetExt = config.outputFormat === "gltf" ? ".gltf" + : (config.outputFormat === "glb" || isConvertible) ? ".glb" + : originalExt; + + const wantsCopy = config.outputOptions.includes("copy"); + const wantsOverwrite = config.outputOptions.includes("overwrite"); + const mode = wantsCopy ? "copy" : (wantsOverwrite ? "overwrite" : "copy"); + const backup = config.outputOptions.includes("backup") && mode === "overwrite"; + + const targetName = mode === "copy" + ? `${baseName}_compressed${targetExt}` + : `${baseName}${targetExt}`; + + return { + cwd, + mode, + backup, + sourcePath: path.join(cwd, file), + sourceExt: originalExt, + targetExt, + targetPath: path.join(cwd, targetName), + baseName, + needsConversion: isConvertible + }; +} + +async function processFile(file, config, transforms) { + const output = resolveOutput(file, config); + if (!fs.existsSync(output.sourcePath)) { + console.log(color.yellow("跳过,文件不存在: " + file)); + return { ok: false, file, reason: "missing" }; + } + + if (!transforms.length) { + console.log(color.yellow("未选择任何 gltf-transform 操作,已中止")); + return { ok: false, file, reason: "no-transform" }; + } + + if (output.backup) { + const backupName = `${output.baseName}${BACKUP_SUFFIX}${output.sourceExt}`; + const backupPath = path.join(output.cwd, backupName); + fs.copyFileSync(output.sourcePath, backupPath); + } + + let inputPath = output.sourcePath; + + // 如果是 OBJ/FBX,先转换为临时 GLB + if (output.needsConversion) { + const tempPath = path.join(output.cwd, `${output.baseName}_temp.glb`); + console.log(color.dim("转换中: " + file + " → GLB")); + await convert(output.sourcePath, tempPath, { binary: true }); + inputPath = tempPath; + } + + const document = io.read(inputPath); + await document.transform(...transforms); + io.write(output.targetPath, document); + + // 清理临时文件 + if (output.needsConversion) { + fs.rmSync(inputPath, { force: true }); + } + + if (output.mode === "overwrite" && output.targetPath !== output.sourcePath) { + fs.rmSync(output.sourcePath, { force: true }); + } + + if (output.mode === "overwrite" && output.targetPath !== output.sourcePath) { + console.log(color.dim("已生成新文件: " + path.basename(output.targetPath))); + } + + return { ok: true, file, output: output.targetPath }; +} + +export async function run() { + const result = await runInteractive(); + if (!result) return "back"; + + stopKeypress(); + + const { results } = result; + const config = { + files: results[0] || [], + commands: results[1] || [], + quantizePreset: results[2] || "balanced", + outputFormat: results[3] || "auto", + outputOptions: results[4] || [] + }; + + showSummary([ + "模型文件: " + (config.files.length ? config.files.join(", ") : "未选择"), + "gltf-transform 命令: " + (config.commands.length ? config.commands.join(", ") : "无"), + "量化级别: " + config.quantizePreset, + "输出格式: " + config.outputFormat, + "输出选项: " + (config.outputOptions.length ? config.outputOptions.join(", ") : "默认") + ]); + + if (!config.files.length) { + console.log(color.yellow("未选择任何模型文件")); + await waitForKey(); + return "back"; + } + + const transforms = buildTransforms(config); + if (!transforms.length) { + console.log(color.yellow("未配置任何压缩命令,请至少选择一项 gltf-transform 操作")); + await waitForKey(); + return "back"; + } + + const total = config.files.length; + let success = 0; + const failed = []; + + console.log(color.cyan(`开始压缩 ${total} 个文件...\n`)); + + for (let i = 0; i < config.files.length; i++) { + const file = config.files[i]; + const progress = `[${i + 1}/${total}]`; + console.log(color.dim(`${progress} 处理中: ${file}`)); + + try { + const result = await processFile(file, config, transforms); + if (result.ok) { + success++; + console.log(color.green(`${progress} ✓ ${file} → ${path.basename(result.output)}`)); + } else { + failed.push(file); + console.log(color.yellow(`${progress} ⊘ 跳过: ${file}`)); + } + } catch (err) { + failed.push(file); + console.log(color.red(`${progress} ✖ 失败: ${file}`)); + console.log(color.dim(" " + String(err?.message || err))); + } + } + + console.log("\n" + color.bgGreen(color.black(" 压缩完成 "))); + if (success) { + console.log(color.green(`成功: ${success} 个`)); + } + if (failed.length) { + console.log(color.yellow(`失败: ${failed.length} 个 (${failed.join(", ")})`)); + } + + await waitForKey(); + return "back"; +} diff --git a/lib/model/ui.js b/lib/model/ui.js new file mode 100644 index 0000000..3aeb478 --- /dev/null +++ b/lib/model/ui.js @@ -0,0 +1,9 @@ +import { createStepUI } from "../utils/stepui.js"; +import { getSteps } from "./config.js"; + +const ui = createStepUI({ + title: "模型压缩工具", + getSteps +}); + +export const { runInteractive, showSummary } = ui; diff --git a/lib/poem.js b/lib/poem.js index ff58e1a..35da273 100644 --- a/lib/poem.js +++ b/lib/poem.js @@ -28,4 +28,4 @@ export function showPoem(lines, perLine = 2) { } // 默认古诗 -export const defaultPoem = ["你我皆牛马", "生在人世间", "终日奔波苦", "一刻不得闲"]; +export const defaultPoem = ["你我皆牛马1", "生在人世间", "终日奔波苦", "一刻不得闲"]; diff --git a/lib/stats.js b/lib/stats.js new file mode 100644 index 0000000..797798b --- /dev/null +++ b/lib/stats.js @@ -0,0 +1,35 @@ +import fs from "fs"; +import path from "path"; +import { fileURLToPath } from "url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const STATS_FILE = path.join(__dirname, "../.stats.json"); + +let data = null; + +function load() { + if (data) return data; + try { + data = JSON.parse(fs.readFileSync(STATS_FILE, "utf8")); + } catch { + data = {}; + } + return data; +} + +function save() { + fs.writeFileSync(STATS_FILE, JSON.stringify(data, null, 2)); +} + +export function record(category, key) { + load(); + if (!data[category]) data[category] = {}; + data[category][key] = (data[category][key] || 0) + 1; + save(); +} + +export function sortByUsage(category, items, getKey = v => v) { + load(); + const counts = data[category] || {}; + return [...items].sort((a, b) => (counts[getKey(b)] || 0) - (counts[getKey(a)] || 0)); +} diff --git a/lib/utils/gltf.js b/lib/utils/gltf.js new file mode 100644 index 0000000..ba19332 --- /dev/null +++ b/lib/utils/gltf.js @@ -0,0 +1,82 @@ +import fs from "fs"; + +export const BACKUP_SUFFIX = "_备份"; + +// 检查当前目录是否有 gltf 文件 +export function hasGltfFile() { + return listGltfFiles().length > 0; +} + +// 获取当前目录下可用的 gltf 文件列表 +export function listGltfFiles() { + const cwd = process.cwd(); + return fs.readdirSync(cwd).filter(f => f.toLowerCase().endsWith(".gltf") && !f.includes(BACKUP_SUFFIX)); +} + +// 获取 glTF / GLB 模型文件 +export function listModelFiles() { + const cwd = process.cwd(); + return fs + .readdirSync(cwd) + .filter(file => /\.(gltf|glb)$/i.test(file) && !file.includes(BACKUP_SUFFIX)); +} + +// 获取所有支持的模型文件(包括需要转换的格式) +export function listAllModelFiles() { + const cwd = process.cwd(); + return fs + .readdirSync(cwd) + .filter(file => /\.(gltf|glb|obj|fbx)$/i.test(file) && !file.includes(BACKUP_SUFFIX)); +} + +// 判断是否需要先转换 +export function needsConversion(file) { + return /\.(obj|fbx)$/i.test(file); +} + +// 检查是否满足执行条件(有 ktx2、gltf、bin 文件) +export function checkRequiredFiles() { + const cwd = process.cwd(); + const files = fs.readdirSync(cwd); + const hasKtx2 = files.some(f => f.toLowerCase().endsWith(".ktx2")); + const hasGltf = files.some(f => f.toLowerCase().endsWith(".gltf")); + const hasBin = files.some(f => f.toLowerCase().endsWith(".bin")); + + const missing = []; + if (!hasKtx2) missing.push("ktx2"); + if (!hasGltf) missing.push("gltf"); + if (!hasBin) missing.push("bin"); + + return { ok: missing.length === 0, missing }; +} + +// 修改 gltf 文件,根据选项添加扩展 +export function modifyGltfContent(gltfPath, options = ["textureBasisu"]) { + const content = fs.readFileSync(gltfPath, "utf-8"); + const gltf = JSON.parse(content); + + if (options.includes("textureBasisu")) { + if (!gltf.extensionsUsed) gltf.extensionsUsed = []; + if (!gltf.extensionsUsed.includes("KHR_texture_basisu")) { + gltf.extensionsUsed.push("KHR_texture_basisu"); + } + + if (gltf.textures) { + gltf.textures = gltf.textures.map(tex => ({ + extensions: { KHR_texture_basisu: { source: tex.source } } + })); + } + + if (gltf.images) { + gltf.images = gltf.images.map(img => { + const uri = img.uri || ""; + const newUri = uri.replace(/\.(png|jpg|jpeg|webp|tga)$/i, ".ktx2"); + return { uri: newUri, mimeType: "image/ktx2" }; + }); + } + } + + // placeholder1, placeholder2, placeholder3 预留扩展点 + + return gltf; +} diff --git a/lib/utils/stepui.js b/lib/utils/stepui.js new file mode 100644 index 0000000..05ab9e9 --- /dev/null +++ b/lib/utils/stepui.js @@ -0,0 +1,124 @@ +import color from "picocolors"; +import { initKeypress, onKey } from "../keyboard.js"; + +export function createStepUI(options) { + const { title, getSteps } = options; + + let steps = []; + let results = []; + let completed = new Set(); + let currentStep = 0; + let currentOption = 0; + + function initResults() { + steps = typeof getSteps === "function" ? getSteps() : getSteps; + results = steps.map(s => s.type === "multiselect" ? [...(s.default || [])] : s.default); + completed = new Set(); + currentStep = 0; + currentOption = 0; + } + + function renderNav() { + const nav = steps.map((step, i) => { + if (completed.has(i)) return color.green("☑ " + step.name); + if (i === currentStep) return color.bgCyan(color.black(" " + step.name + " ")); + return color.dim("□ " + step.name); + }); + return "← " + nav.join(" ") + " " + color.green("✓Submit") + " →"; + } + + function renderOptions() { + const step = steps[currentStep]; + const lines = [color.cyan(step.message), ""]; + if (!step.options || !step.options.length) { + lines.push(color.dim(step.emptyMessage || "无可用选项")); + return lines.join("\n"); + } + step.options.forEach((opt, i) => { + const isCurrent = i === currentOption; + const isSelected = step.type === "multiselect" + ? results[currentStep]?.includes(opt.value) + : results[currentStep] === opt.value; + const prefix = step.type === "multiselect" + ? (isSelected ? color.green("◉ ") : "○ ") + : (isSelected ? color.green("● ") : "○ "); + const cursor = isCurrent ? color.cyan("❯ ") : " "; + const label = isCurrent ? color.cyan(opt.label) : opt.label; + const check = isSelected ? color.green(" ✓") : ""; + lines.push(cursor + prefix + label + check); + if (opt.hint) lines.push(" " + color.dim(opt.hint)); + }); + return lines.join("\n"); + } + + function render() { + console.clear(); + console.log(color.bgCyan(color.black(` ${title} `))); + console.log("\n" + renderNav()); + console.log(color.dim("\n← → 切换步骤 | ↑ ↓ 选择 | Space 选中 | Tab 提交 | Esc 返回\n")); + console.log(renderOptions()); + } + + function runInteractive() { + initResults(); + initKeypress(); + return new Promise(resolve => { + render(); + onKey((str, key) => { + if (!key) return; + const step = steps[currentStep]; + const optCount = step.options?.length || 0; + if (key.name === "left") { + if (currentStep > 0) { currentStep--; currentOption = 0; } + render(); + } else if (key.name === "right") { + if (currentStep < steps.length - 1) { currentStep++; currentOption = 0; } + render(); + } else if (key.name === "up") { + if (!optCount) return; + currentOption = (currentOption - 1 + optCount) % optCount; + render(); + } else if (key.name === "down") { + if (!optCount) return; + currentOption = (currentOption + 1) % optCount; + render(); + } else if (key.name === "space") { + if (!optCount) return; + const opt = step.options[currentOption]; + if (step.type === "multiselect") { + const list = results[currentStep]; + const idx = list.indexOf(opt.value); + if (idx >= 0) list.splice(idx, 1); + else list.push(opt.value); + } else { + results[currentStep] = opt.value; + } + completed.add(currentStep); + render(); + } else if (key.name === "return") { + if (!optCount) return; + if (step.type === "select") { + results[currentStep] = step.options[currentOption].value; + } + completed.add(currentStep); + if (currentStep < steps.length - 1) { currentStep++; currentOption = 0; } + render(); + } else if (key.name === "tab") { + resolve({ steps, results }); + } else if (key.name === "escape" || (key.ctrl && key.name === "c")) { + resolve(null); + } + }); + }); + } + + function showSummary(lines) { + console.clear(); + console.log(color.bgCyan(color.black(` ${title} `))); + console.log("\n" + color.green("配置完成!当前设置:")); + lines.forEach(line => console.log(" " + line)); + console.log(); + } + + return { runInteractive, showSummary, initResults }; +} diff --git a/package-lock.json b/package-lock.json index e968a3a..0978125 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,42 +1,429 @@ { - "name": "demo", - "version": "1.0.0", + "name": "@yinshuangxi/yinx-cli", + "version": "1.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "demo", - "version": "1.0.0", + "name": "@yinshuangxi/yinx-cli", + "version": "1.0.2", + "license": "MIT", "dependencies": { - "@clack/prompts": "^0.11.0", + "@cocos/fbx2gltf": "^1.0.8", + "@gltf-transform/core": "^3.10.1", + "@gltf-transform/extensions": "^3.10.1", + "@gltf-transform/functions": "^3.10.1", "boxen": "^8.0.1", "figlet": "^1.9.4", - "picocolors": "^1.1.1", - "prompts": "^2.4.2" + "obj2gltf": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { - "yinx": "cli.js" + "yinx": "dist/index.js" + }, + "devDependencies": { + "javascript-obfuscator": "^5.1.0", + "rimraf": "^6.1.2" + }, + "engines": { + "node": ">=16" } }, - "node_modules/@clack/core": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.5.0.tgz", - "integrity": "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==", - "license": "MIT", + "node_modules/@cesium/engine": { + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/@cesium/engine/-/engine-22.1.0.tgz", + "integrity": "sha512-grL8/wiIkKLFG+FrizORhUTMpOcFMFawa0fmLH3I/1K46TcDQn6Gom+qrcGqbJoc4diYM75xsAC9M8Yajgh4rQ==", + "license": "Apache-2.0", "dependencies": { - "picocolors": "^1.0.0", - "sisteransi": "^1.0.5" + "@cesium/wasm-splats": "^0.1.0-alpha.2", + "@spz-loader/core": "0.3.0", + "@tweenjs/tween.js": "^25.0.0", + "@zip.js/zip.js": "^2.8.1", + "autolinker": "^4.0.0", + "bitmap-sdf": "^1.0.3", + "dompurify": "^3.3.0", + "draco3d": "^1.5.1", + "earcut": "^3.0.0", + "grapheme-splitter": "^1.0.4", + "jsep": "^1.3.8", + "kdbush": "^4.0.1", + "ktx-parse": "^1.0.0", + "lerc": "^2.0.0", + "mersenne-twister": "^1.1.0", + "meshoptimizer": "^0.25.0", + "pako": "^2.0.4", + "protobufjs": "^7.1.0", + "rbush": "^4.0.1", + "topojson-client": "^3.1.0", + "urijs": "^1.19.7" + }, + "engines": { + "node": ">=20.19.0" } }, - "node_modules/@clack/prompts": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.11.0.tgz", - "integrity": "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==", + "node_modules/@cesium/engine/node_modules/ktx-parse": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-1.1.0.tgz", + "integrity": "sha512-mKp3y+FaYgR7mXWAbyyzpa/r1zDWeaunH+INJO4fou3hb45XuNSwar+7llrRyvpMWafxSIi99RNFJ05MHedaJQ==", + "license": "MIT" + }, + "node_modules/@cesium/wasm-splats": { + "version": "0.1.0-alpha.2", + "resolved": "https://registry.npmjs.org/@cesium/wasm-splats/-/wasm-splats-0.1.0-alpha.2.tgz", + "integrity": "sha512-t9pMkknv31hhIbLpMa8yPvmqfpvs5UkUjgqlQv9SeO8VerCXOYnyP8/486BDaFrztM0A7FMbRjsXtNeKvqQghA==", + "license": "Apache-2.0" + }, + "node_modules/@cesium/widgets": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@cesium/widgets/-/widgets-14.1.0.tgz", + "integrity": "sha512-/8xJTi95XZrdkmJGABEHuQLu2ZarJ59J4V21dmgU/GJAFoqnjPlqFaFajx5XBZzRufGFYW1vGsq9BMqbdOJn5Q==", + "license": "Apache-2.0", + "dependencies": { + "@cesium/engine": "^22.1.0", + "nosleep.js": "^0.12.0" + }, + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@cocos/fbx2gltf": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@cocos/fbx2gltf/-/fbx2gltf-1.0.8.tgz", + "integrity": "sha512-HxcTxxcaety8Ya1JhJbfx26kxy8ZFG/t8j73DphKlWQMM6YbLn3/hdu4eEsP9vAIXhJ88V34KqOsL9izgGwlZg==", + "license": "BSD-3-Clause", + "dependencies": { + "rimraf": "^2.6.2" + } + }, + "node_modules/@cocos/fbx2gltf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@cocos/fbx2gltf/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/@gltf-transform/core": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@gltf-transform/core/-/core-3.10.1.tgz", + "integrity": "sha512-50OYemknGNxjBmiOM6iJp04JAu0bl9jvXJfN/gFt9QdJO02cPDcoXlTfSPJG6TVWDcfl0xPlsx1vybcbPVGFcQ==", "license": "MIT", "dependencies": { - "@clack/core": "0.5.0", - "picocolors": "^1.0.0", - "sisteransi": "^1.0.5" + "property-graph": "^1.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/donmccurdy" + } + }, + "node_modules/@gltf-transform/extensions": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@gltf-transform/extensions/-/extensions-3.10.1.tgz", + "integrity": "sha512-xUS9K5fMvW2dkYN4VzxHg2aBPG54M2WqgIjQ7RoSyybMoD7DsPUyMyVgRja+aiTVt/Bxza2ve7zJBD3+tN+aTA==", + "license": "MIT", + "dependencies": { + "@gltf-transform/core": "^3.10.1", + "ktx-parse": "^0.6.0" + }, + "funding": { + "url": "https://github.com/sponsors/donmccurdy" + } + }, + "node_modules/@gltf-transform/functions": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@gltf-transform/functions/-/functions-3.10.1.tgz", + "integrity": "sha512-Zs6+1qvTD9w40R5qv70E4wJXXacNQ46ZxjKKW6dmfGIyjT8bsSJmV3Tdj+WJ8R6lWXXZ8e2p3ZvAUfPDEG73bQ==", + "license": "MIT", + "dependencies": { + "@gltf-transform/core": "^3.10.1", + "@gltf-transform/extensions": "^3.10.1", + "ktx-parse": "^0.6.0", + "ndarray": "^1.0.19", + "ndarray-lanczos": "^0.3.0", + "ndarray-pixels": "^3.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/donmccurdy" + } + }, + "node_modules/@inversifyjs/common": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@inversifyjs/common/-/common-1.3.3.tgz", + "integrity": "sha512-ZH0wrgaJwIo3s9gMCDM2wZoxqrJ6gB97jWXncROfYdqZJv8f3EkqT57faZqN5OTeHWgtziQ6F6g3L8rCvGceCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@inversifyjs/core": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@inversifyjs/core/-/core-1.3.4.tgz", + "integrity": "sha512-gCCmA4BdbHEFwvVZ2elWgHuXZWk6AOu/1frxsS+2fWhjEk2c/IhtypLo5ytSUie1BCiT6i9qnEo4bruBomQsAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inversifyjs/common": "1.3.3", + "@inversifyjs/reflect-metadata-utils": "0.2.3" + } + }, + "node_modules/@inversifyjs/reflect-metadata-utils": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@inversifyjs/reflect-metadata-utils/-/reflect-metadata-utils-0.2.3.tgz", + "integrity": "sha512-d3D0o9TeSlvaGM2I24wcNw/Aj3rc4OYvHXOKDC09YEph5fMMiKd6fq1VTQd9tOkDNWvVbw+cnt45Wy9P/t5Lvw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "reflect-metadata": "0.2.2" + } + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@javascript-obfuscator/escodegen": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@javascript-obfuscator/escodegen/-/escodegen-2.3.1.tgz", + "integrity": "sha512-Z0HEAVwwafOume+6LFXirAVZeuEMKWuPzpFbQhCEU9++BMz0IwEa9bmedJ+rMn/IlXRBID9j3gQ0XYAa6jM10g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@javascript-obfuscator/estraverse": "^5.3.0", + "esprima": "^4.0.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/@javascript-obfuscator/estraverse": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@javascript-obfuscator/estraverse/-/estraverse-5.4.0.tgz", + "integrity": "sha512-CZFX7UZVN9VopGbjTx4UXaXsi9ewoM1buL0kY7j1ftYdSs7p2spv9opxFjHlQ/QGTgh4UqufYqJJ0WKLml7b6w==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@spz-loader/core": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@spz-loader/core/-/core-0.3.0.tgz", + "integrity": "sha512-sbStwMHb/MIE29st7rRuMYWqhX1UmLSFzdpyGtUZUXLkFNIuYKblzjQdtiet8bau8sUf21uL1DQ451zuySGmcA==", + "license": "Apache-2.0", + "engines": { + "node": ">=16", + "pnpm": ">=8" + } + }, + "node_modules/@tweenjs/tween.js": { + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-25.0.0.tgz", + "integrity": "sha512-XKLA6syeBUaPzx4j3qwMqzzq+V4uo72BnlbOjmuljLrRqdsd3qnzvZZoxvMHZ23ndsRS4aufU6JOZYpCbU6T1A==", + "license": "MIT" + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ndarray": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/@types/ndarray/-/ndarray-1.0.14.tgz", + "integrity": "sha512-oANmFZMnFQvb219SSBIhI1Ih/r4CvHDOzkWyJS/XRqkMrGH5/kaPSA1hQhdIBzouaE+5KpE/f5ylI9cujmckQg==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.0.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz", + "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/validator": { + "version": "13.15.10", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.10.tgz", + "integrity": "sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@zip.js/zip.js": { + "version": "2.8.11", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.8.11.tgz", + "integrity": "sha512-0fztsk/0ryJ+2PPr9EyXS5/Co7OK8q3zY/xOoozEWaUsL5x+C0cyZ4YyMuUffOO2Dx/rAdq4JMPqW0VUtm+vzA==", + "license": "BSD-3-Clause", + "engines": { + "bun": ">=0.7.0", + "deno": ">=1.0.0", + "node": ">=18.0.0" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, "node_modules/ansi-align": { @@ -113,6 +500,243 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/assert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" + } + }, + "node_modules/atomically": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-2.1.0.tgz", + "integrity": "sha512-+gDffFXRW6sl/HCwbta7zK4uNqbPjv4YJEAdz7Vu+FLQHe77eZ4bvbJGi4hE0QPeJlMYMA3piXEr1UL3dAwx7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "stubborn-fs": "^2.0.0", + "when-exit": "^2.1.4" + } + }, + "node_modules/autolinker": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-4.1.5.tgz", + "integrity": "sha512-vEfYZPmvVOIuE567XBVCsx8SBgOYtjB2+S1iAaJ+HgH+DNjAcrHem2hmAeC9yaNGWayicv4yR+9UaJlkF3pvtw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + }, + "engines": { + "pnpm": ">=10.10.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/b4a": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/bare-events": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", + "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", + "license": "Apache-2.0", + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } + } + }, + "node_modules/bare-fs": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.2.tgz", + "integrity": "sha512-veTnRzkb6aPHOvSKIOy60KzURfBdUflr5VReI+NSaPL6xf+XLdONQgZgpYvUuZLVQ8dCqxpBAudaOM1+KpAUxw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-events": "^2.5.4", + "bare-path": "^3.0.0", + "bare-stream": "^2.6.4", + "bare-url": "^2.2.2", + "fast-fifo": "^1.3.2" + }, + "engines": { + "bare": ">=1.16.0" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } + } + }, + "node_modules/bare-os": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", + "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "bare": ">=1.14.0" + } + }, + "node_modules/bare-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-os": "^3.0.1" + } + }, + "node_modules/bare-stream": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.7.0.tgz", + "integrity": "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "streamx": "^2.21.0" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-events": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-events": { + "optional": true + } + } + }, + "node_modules/bare-url": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz", + "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-path": "^3.0.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bitmap-sdf": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/bitmap-sdf/-/bitmap-sdf-1.0.4.tgz", + "integrity": "sha512-1G3U4n5JE6RAiALMxu0p1XmeZkTeCwGKykzsLTCqVzfSDaN6S7fKnkIkfejogz+iwqBWc0UYAIKnKHNN7pSfDg==", + "license": "MIT" + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "license": "MIT" + }, "node_modules/boxen": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/boxen/-/boxen-8.0.1.tgz", @@ -135,6 +759,97 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/camelcase": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", @@ -147,6 +862,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cesium": { + "version": "1.136.0", + "resolved": "https://registry.npmjs.org/cesium/-/cesium-1.136.0.tgz", + "integrity": "sha512-sHSFNNLgrgJQxpdLxdmjytT7qfs8dkn23tpPnXKweqvynQn+yAybepK6AwzYBbKQ017qBkrS/Wb4DORIFcjjhQ==", + "license": "Apache-2.0", + "workspaces": [ + "packages/engine", + "packages/widgets", + "packages/sandcastle" + ], + "dependencies": { + "@cesium/engine": "^22.1.0", + "@cesium/widgets": "^14.1.0" + }, + "engines": { + "node": ">=20.19.0" + } + }, "node_modules/chalk": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", @@ -159,6 +892,51 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chance": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/chance/-/chance-1.1.13.tgz", + "integrity": "sha512-V6lQCljcLznE7tUYUM9EOAnnKXbctE6j/rdQkYOHIWbfGQbrzTsAXNW9CdU5XCo4ArXQCj/rb6HgxPlmGJcaUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, + "node_modules/class-validator": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.3.tgz", + "integrity": "sha512-rXXekcjofVN1LTOSw+u4u9WXVEUvNBVjORW154q/IdmYWy1nMbOU9aNtZB0t8m+FJQ9q91jlr2f9CwwUFdFMRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/validator": "^13.15.3", + "libphonenumber-js": "^1.11.1", + "validator": "^13.15.20" + } + }, "node_modules/cli-boxes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", @@ -171,6 +949,134 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/commander": { "version": "14.0.2", "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", @@ -180,12 +1086,417 @@ "node": ">=20" } }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/conf": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/conf/-/conf-15.0.2.tgz", + "integrity": "sha512-JBSrutapCafTrddF9dH3lc7+T2tBycGF4uPkI4Js+g4vLLEhG6RZcFi3aJd5zntdf5tQxAejJt8dihkoQ/eSJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "atomically": "^2.0.3", + "debounce-fn": "^6.0.0", + "dot-prop": "^10.0.0", + "env-paths": "^3.0.0", + "json-schema-typed": "^8.0.1", + "semver": "^7.7.2", + "uint8array-extras": "^1.5.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/cwise-compiler": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cwise-compiler/-/cwise-compiler-1.1.3.tgz", + "integrity": "sha512-WXlK/m+Di8DMMcCjcWr4i+XzcQra9eCdXIJrgh4TUgh0pIS/yJduLxS9JgefsHJ/YVLdgPtXm9r62W92MvanEQ==", + "license": "MIT", + "dependencies": { + "uniq": "^1.0.0" + } + }, + "node_modules/debounce-fn": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-6.0.0.tgz", + "integrity": "sha512-rBMW+F2TXryBwB54Q0d8drNEI+TfoS9JpNTAoVpukbWEhjXQq4rySFYLaqXMFXwdv61Zb2OHtj5bviSoimqxRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dompurify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.1.tgz", + "integrity": "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, + "node_modules/dot-prop": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-10.1.0.tgz", + "integrity": "sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^5.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dot-prop/node_modules/type-fest": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.3.1.tgz", + "integrity": "sha512-VCn+LMHbd4t6sF3wfU/+HKT63C9OoyrSIf4b+vtWHpt2U7/4InZG467YDNMFMR70DdHjAdpPWmw2lzRdg0Xqqg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/draco3d": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.7.tgz", + "integrity": "sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ==", + "license": "Apache-2.0" + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/earcut": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.2.tgz", + "integrity": "sha512-X7hshQbLyMJ/3RPhyObLARM2sNxxmRALLKx1+NVFFnQ9gKzmCrxm9+uLIAdBcvc8FNLpctqlQ2V6AE92Ol9UDQ==", + "license": "ISC" + }, "node_modules/emoji-regex": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "license": "MIT" }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/env-paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/figlet": { "version": "1.9.4", "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.9.4.tgz", @@ -201,6 +1512,77 @@ "node": ">= 17.0.0" } }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", + "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-east-asian-width": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", @@ -213,6 +1595,277 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "license": "MIT" + }, + "node_modules/glob": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/inversify": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/inversify/-/inversify-6.1.4.tgz", + "integrity": "sha512-PbxrZH/gTa1fpPEEGAjJQzK8tKMIp5gRg6EFNJlCtzUcycuNdmhv3uk5P8Itm/RIjgHJO16oQRLo9IHzQN51bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inversifyjs/common": "1.3.3", + "@inversifyjs/core": "1.3.4" + } + }, + "node_modules/iota-array": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/iota-array/-/iota-array-1.0.0.tgz", + "integrity": "sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==", + "license": "MIT" + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "license": "MIT" + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "license": "MIT" + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -222,13 +1875,613 @@ "node": ">=8" } }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/javascript-obfuscator": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/javascript-obfuscator/-/javascript-obfuscator-5.1.0.tgz", + "integrity": "sha512-yw0zSxH20YVxJ7Jg23ii9eojcsGkfZmP6AEvaddv026+3H3QPOd/qPo168+80gvzN6pyMQDCbLwxjrP76jkPAg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@javascript-obfuscator/escodegen": "2.3.1", + "@javascript-obfuscator/estraverse": "5.4.0", + "acorn": "8.15.0", + "assert": "2.1.0", + "chalk": "4.1.2", + "chance": "1.1.13", + "class-validator": "0.14.3", + "commander": "12.1.0", + "conf": "15.0.2", + "eslint-scope": "8.4.0", + "eslint-visitor-keys": "4.2.1", + "fast-deep-equal": "3.1.3", + "inversify": "6.1.4", + "js-string-escape": "1.0.1", + "md5": "2.3.0", + "mkdirp": "3.0.1", + "multimatch": "5.0.0", + "process": "0.11.10", + "reflect-metadata": "0.2.2", + "source-map-support": "0.5.21", + "string-template": "1.0.0", + "stringz": "2.1.0", + "tslib": "2.8.1" + }, + "bin": { + "javascript-obfuscator": "bin/javascript-obfuscator" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/javascript-obfuscator/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/javascript-obfuscator/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/javascript-obfuscator/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">=18" + } + }, + "node_modules/jpeg-js": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", + "license": "BSD-3-Clause" + }, + "node_modules/js-string-escape": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", + "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/jsep": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.4.0.tgz", + "integrity": "sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==", + "license": "MIT", + "engines": { + "node": ">= 10.16.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/kdbush": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", + "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==", + "license": "ISC" + }, + "node_modules/ktx-parse": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-0.6.0.tgz", + "integrity": "sha512-hYOJUI86N9+YPm0M3t8hVzW9t5FnFFibRalZCrqHs/qM2eNziqQzBtAaF0ErgkXm8F+5uE8CjPUYr32vWlXLkQ==", + "license": "MIT" + }, + "node_modules/lerc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lerc/-/lerc-2.0.0.tgz", + "integrity": "sha512-7qo1Mq8ZNmaR4USHHm615nEW2lPeeWJ3bTyoqFbd35DLx0LUH7C6ptt5FDCTAlbIzs3+WKrk5SkJvw8AFDE2hg==", + "license": "Apache-2.0" + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/libphonenumber-js": { + "version": "1.12.31", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.31.tgz", + "integrity": "sha512-Z3IhgVgrqO1S5xPYM3K5XwbkDasU67/Vys4heW+lfSBALcUZjeIIzI8zCLifY+OCzSq+fpDdywMDa7z+4srJPQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "node_modules/mersenne-twister": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mersenne-twister/-/mersenne-twister-1.1.0.tgz", + "integrity": "sha512-mUYWsMKNrm4lfygPkL3OfGzOPTR2DBlTkBNHM//F6hGp8cLThY897crAlk3/Jo17LEOOjQUrNAx6DvgO77QJkA==", + "license": "MIT" + }, + "node_modules/meshoptimizer": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.25.0.tgz", + "integrity": "sha512-ewwuAo3ujPZ7T3Y2oTkEoLlXvNOqnr0cjyAxfv5djXJqwD9QlxDDO0qGtsqB4Z9QUVvhruKXg9q/xfK9I5S1xQ==", + "license": "MIT" + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT" + }, + "node_modules/multimatch": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", + "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "license": "MIT" + }, + "node_modules/ndarray": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/ndarray/-/ndarray-1.0.19.tgz", + "integrity": "sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==", + "license": "MIT", + "dependencies": { + "iota-array": "^1.0.0", + "is-buffer": "^1.0.2" + } + }, + "node_modules/ndarray-lanczos": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ndarray-lanczos/-/ndarray-lanczos-0.3.0.tgz", + "integrity": "sha512-5kBmmG3Zvyj77qxIAC4QFLKuYdDIBJwCG+DukT6jQHNa1Ft74/hPH1z5mbQXeHBt8yvGPBGVrr3wEOdJPYYZYg==", + "license": "MIT", + "dependencies": { + "@types/ndarray": "^1.0.11", + "ndarray": "^1.0.19" + } + }, + "node_modules/ndarray-ops": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ndarray-ops/-/ndarray-ops-1.2.2.tgz", + "integrity": "sha512-BppWAFRjMYF7N/r6Ie51q6D4fs0iiGmeXIACKY66fLpnwIui3Wc3CXiD/30mgLbDjPpSLrsqcp3Z62+IcHZsDw==", + "license": "MIT", + "dependencies": { + "cwise-compiler": "^1.0.0" + } + }, + "node_modules/ndarray-pixels": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ndarray-pixels/-/ndarray-pixels-3.1.0.tgz", + "integrity": "sha512-icw7L/kbxlHVoBgFWc0fCl1sYcatYSoZrAudD6KiQ1WXy84hRXIfqel5CLkh/SeLhb02Q2NW1ud9lE5G84V0zQ==", + "license": "MIT", + "dependencies": { + "@types/ndarray": "^1.0.11", + "ndarray": "^1.0.19", + "ndarray-ops": "^1.2.2", + "sharp": "^0.32.6" + } + }, + "node_modules/node-abi": { + "version": "3.85.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.85.0.tgz", + "integrity": "sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "license": "MIT" + }, + "node_modules/nosleep.js": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/nosleep.js/-/nosleep.js-0.12.0.tgz", + "integrity": "sha512-9d1HbpKLh3sdWlhXMhU6MMH+wQzKkrgfRkYV0EBdvt99YJfj0ilCJrWRDYG2130Tm4GXbEoTCx5b34JSaP+HhA==", + "license": "MIT" + }, + "node_modules/obj2gltf": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/obj2gltf/-/obj2gltf-3.2.0.tgz", + "integrity": "sha512-1pCbHSK55tiTkJG8Td0Nfqx97jcCtIKNeoukWhmuiyEtty3gmLBxHRN6WdYM6XKKAVgZVgeJ/PxXAizeRbQFxQ==", + "license": "Apache-2.0", + "dependencies": { + "bluebird": "^3.7.2", + "cesium": "^1.86.1", + "fs-extra": "^11.0.0", + "jpeg-js": "^0.4.3", + "mime": "^3.0.0", + "pngjs": "^7.0.0", + "yargs": "^17.2.1" + }, + "bin": { + "obj2gltf": "bin/obj2gltf.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "license": "(MIT AND Zlib)" + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/picocolors": { @@ -237,23 +2490,419 @@ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "node_modules/pngjs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", + "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==", + "license": "MIT", + "engines": { + "node": ">=14.19.0" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", "license": "MIT", "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prebuild-install/node_modules/tar-fs": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/prebuild-install/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/property-graph": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/property-graph/-/property-graph-1.3.1.tgz", + "integrity": "sha512-gei3N/bHWJdCItJ4blnlGWd9iauEZI+JZYj/A0D177XSI01+QhiJGAVscYBhe3Yywow3A2QJzVtsO2P+UgrRRQ==", + "license": "MIT" + }, + "node_modules/protobufjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/quickselect": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", + "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", + "license": "ISC" + }, + "node_modules/rbush": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/rbush/-/rbush-4.0.1.tgz", + "integrity": "sha512-IP0UpfeWQujYC8Jg162rMNc01Rf0gWMMAb2Uxus/Q0qOFw4lCcq6ZnQEZwUoJqWyUGJ9th7JjwI4yIWo+uvoAQ==", + "license": "MIT", + "dependencies": { + "quickselect": "^3.0.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", + "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "glob": "^13.0.0", + "package-json-from-dist": "^1.0.1" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sharp": { + "version": "0.32.6", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", + "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.2", + "node-addon-api": "^6.1.0", + "prebuild-install": "^7.1.1", + "semver": "^7.5.4", + "simple-get": "^4.0.1", + "tar-fs": "^3.0.4", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", + "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/streamx": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", + "license": "MIT", + "dependencies": { + "events-universal": "^1.0.0", + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-template": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-1.0.0.tgz", + "integrity": "sha512-SLqR3GBUXuoPP5MmYtD7ompvXiG87QjT6lzOszyXjTM86Uu7At7vNnt2xgyTLq5o9T4IxTYFyGxcULqpsmsfdg==", + "dev": true, "license": "MIT" }, "node_modules/string-width": { @@ -273,6 +2922,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/stringz": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/stringz/-/stringz-2.1.0.tgz", + "integrity": "sha512-KlywLT+MZ+v0IRepfMxRtnSvDCMc3nR1qqCs3m/qIbSOWkNZYT8XHQA31rS3TnKp0c5xjZu3M4GY/2aRKSi/6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2" + } + }, "node_modules/strip-ansi": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", @@ -288,6 +2947,143 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stubborn-fs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stubborn-fs/-/stubborn-fs-2.0.0.tgz", + "integrity": "sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "stubborn-utils": "^1.0.1" + } + }, + "node_modules/stubborn-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stubborn-utils/-/stubborn-utils-1.0.2.tgz", + "integrity": "sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg==", + "dev": true, + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tagged-tag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", + "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tar-fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", + "license": "MIT", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/topojson-client": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz", + "integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==", + "license": "ISC", + "dependencies": { + "commander": "2" + }, + "bin": { + "topo2geo": "bin/topo2geo", + "topomerge": "bin/topomerge", + "topoquantize": "bin/topoquantize" + } + }, + "node_modules/topojson-client/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/type-fest": { "version": "4.41.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", @@ -300,6 +3096,105 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==", + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/urijs": { + "version": "1.19.11", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", + "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==", + "license": "MIT" + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/validator": { + "version": "13.15.23", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.23.tgz", + "integrity": "sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/when-exit": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/when-exit/-/when-exit-2.1.5.tgz", + "integrity": "sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg==", + "dev": true, + "license": "MIT" + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/widest-line": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz", @@ -315,6 +3210,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", @@ -331,6 +3236,89 @@ "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } } } } diff --git a/package.json b/package.json index d56357c..e3072df 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,19 @@ { "name": "@yinshuangxi/yinx-cli", - "version": "1.0.0", + "version": "1.0.2", "description": "游戏资源工具箱 - KTX2纹理压缩、模型压缩等", - "main": "index.js", + "main": "dist/index.js", "type": "module", + "scripts": { + "clean": "rimraf dist", + "build": "node scripts/build.js", + "prepublishOnly": "npm run clean && npm run build" + }, "bin": { - "yinx": "./index.js" + "yinx": "./dist/index.js" }, "files": [ - "index.js", - "lib", - "bin" + "dist" ], "keywords": [ "ktx2", @@ -30,8 +33,17 @@ "node": ">=16" }, "dependencies": { + "@cocos/fbx2gltf": "^1.0.8", + "@gltf-transform/core": "^3.10.1", + "@gltf-transform/extensions": "^3.10.1", + "@gltf-transform/functions": "^3.10.1", "boxen": "^8.0.1", "figlet": "^1.9.4", + "obj2gltf": "^3.2.0", "picocolors": "^1.1.1" + }, + "devDependencies": { + "javascript-obfuscator": "^5.1.0", + "rimraf": "^6.1.2" } } diff --git a/scripts/build.js b/scripts/build.js new file mode 100644 index 0000000..e9b2dec --- /dev/null +++ b/scripts/build.js @@ -0,0 +1,100 @@ +#!/usr/bin/env node +import { promises as fs } from "fs"; +import path from "path"; +import { fileURLToPath } from "url"; +import JavaScriptObfuscator from "javascript-obfuscator"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const rootDir = path.resolve(__dirname, ".."); +const distDir = path.join(rootDir, "dist"); + +const copyTargets = [ + { from: path.join(rootDir, "index.js"), to: path.join(distDir, "index.js") }, + { from: path.join(rootDir, "lib"), to: path.join(distDir, "lib") }, + { from: path.join(rootDir, "bin"), to: path.join(distDir, "bin") } +]; + +async function main() { + await fs.rm(distDir, { recursive: true, force: true }); + await fs.mkdir(distDir, { recursive: true }); + + for (const target of copyTargets) { + await copy(target.from, target.to); + } + + await obfuscateDirectory(distDir); + console.log("Obfuscated build written to", distDir); +} + +async function copy(src, dest) { + const stat = await fs.stat(src); + if (stat.isDirectory()) { + await fs.mkdir(dest, { recursive: true }); + const entries = await fs.readdir(src); + for (const entry of entries) { + await copy(path.join(src, entry), path.join(dest, entry)); + } + return; + } + + await fs.copyFile(src, dest); +} + +async function obfuscateDirectory(dir) { + const entries = await fs.readdir(dir, { withFileTypes: true }); + await Promise.all( + entries.map(async entry => { + const entryPath = path.join(dir, entry.name); + if (entry.isDirectory()) { + await obfuscateDirectory(entryPath); + return; + } + + if (entry.isFile() && entry.name.endsWith(".js")) { + await obfuscateFile(entryPath); + } + }) + ); +} + +async function obfuscateFile(filePath) { + const original = await fs.readFile(filePath, "utf8"); + const { shebang, body } = extractShebang(original); + const obfuscated = JavaScriptObfuscator.obfuscate(body, { + compact: true, + controlFlowFlattening: true, + stringArray: true, + stringArrayEncoding: ["base64"], + deadCodeInjection: true, + target: "node", + identifierNamesGenerator: "hexadecimal" + }); + + const content = shebang + ? `${shebang}\n${obfuscated.getObfuscatedCode()}` + : obfuscated.getObfuscatedCode(); + await fs.writeFile(filePath, content, "utf8"); +} + +function extractShebang(source) { + if (!source.startsWith("#!")) { + return { body: source }; + } + + const newlineIndex = source.indexOf("\n"); + if (newlineIndex === -1) { + return { shebang: source, body: "" }; + } + + return { + shebang: source.slice(0, newlineIndex), + body: source.slice(newlineIndex + 1) + }; +} + +main().catch(err => { + console.error("Build failed:"); + console.error(err); + process.exitCode = 1; +});