numbl 0.4.12 → 0.4.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-browser/browser.js +1 -1
- package/dist-browser/numbl-core/fileIOAdapter.d.ts +4 -0
- package/dist-browser/numbl-core/native/lapack-bridge.d.ts +1 -1
- package/dist-browser/numbl-core/native/wasm-lapack-bridge.d.ts +114 -0
- package/dist-browser/numbl-core/native/wasm-lapack-browser.d.ts +34 -0
- package/dist-browser/numbl-core/runtime/datetime-format.d.ts +10 -0
- package/dist-browser/numbl-core/runtime/display.d.ts +5 -1
- package/dist-browser/numbl-core/runtime/index.d.ts +1 -1
- package/dist-browser/numbl-core/version.d.ts +1 -1
- package/dist-browser/vfs/BrowserFileIOAdapter.d.ts +1 -0
- package/dist-cli/cli.js +433 -130
- package/dist-lib/cli-fileio.d.ts +62 -0
- package/dist-lib/cli-scan.d.ts +6 -0
- package/dist-lib/cli-system.d.ts +13 -0
- package/dist-lib/lib.js +367 -72
- package/dist-lib/node.d.ts +30 -0
- package/dist-lib/node.js +829 -0
- package/dist-lib/numbl-core/fileIOAdapter.d.ts +4 -0
- package/dist-lib/numbl-core/native/lapack-bridge.d.ts +1 -1
- package/dist-lib/numbl-core/native/wasm-lapack-bridge.d.ts +114 -0
- package/dist-lib/numbl-core/native/wasm-lapack-browser.d.ts +34 -0
- package/dist-lib/numbl-core/runtime/datetime-format.d.ts +10 -0
- package/dist-lib/numbl-core/runtime/display.d.ts +5 -1
- package/dist-lib/numbl-core/runtime/index.d.ts +1 -1
- package/dist-lib/numbl-core/version.d.ts +1 -1
- package/dist-lib/vfs/BrowserFileIOAdapter.d.ts +1 -0
- package/dist-site-viewer/assets/{index-CGE1_vZ-.js → index-C2ItFYSf.js} +322 -322
- package/dist-site-viewer/assets/{numbl-worker-DddtCPW_.js → numbl-worker-CtfdLxJh.js} +114 -102
- package/dist-site-viewer/index.html +1 -1
- package/package.json +6 -2
package/dist-lib/lib.js
CHANGED
|
@@ -819,6 +819,114 @@ var valuesAreEqual = (a, b) => {
|
|
|
819
819
|
}
|
|
820
820
|
};
|
|
821
821
|
|
|
822
|
+
// src/numbl-core/runtime/datetime-format.ts
|
|
823
|
+
var MONTH_ABBR = [
|
|
824
|
+
"Jan",
|
|
825
|
+
"Feb",
|
|
826
|
+
"Mar",
|
|
827
|
+
"Apr",
|
|
828
|
+
"May",
|
|
829
|
+
"Jun",
|
|
830
|
+
"Jul",
|
|
831
|
+
"Aug",
|
|
832
|
+
"Sep",
|
|
833
|
+
"Oct",
|
|
834
|
+
"Nov",
|
|
835
|
+
"Dec"
|
|
836
|
+
];
|
|
837
|
+
var MONTH_FULL = [
|
|
838
|
+
"January",
|
|
839
|
+
"February",
|
|
840
|
+
"March",
|
|
841
|
+
"April",
|
|
842
|
+
"May",
|
|
843
|
+
"June",
|
|
844
|
+
"July",
|
|
845
|
+
"August",
|
|
846
|
+
"September",
|
|
847
|
+
"October",
|
|
848
|
+
"November",
|
|
849
|
+
"December"
|
|
850
|
+
];
|
|
851
|
+
function pad(n, width) {
|
|
852
|
+
return String(n).padStart(width, "0");
|
|
853
|
+
}
|
|
854
|
+
function formatDatetimePattern(pattern, year, month, day, hour, minute, second) {
|
|
855
|
+
const wholeSec = Math.floor(second);
|
|
856
|
+
const frac = second - wholeSec;
|
|
857
|
+
const monthIdx = Math.max(0, Math.min(11, Math.floor(month) - 1));
|
|
858
|
+
const formatToken = (c, n) => {
|
|
859
|
+
switch (c) {
|
|
860
|
+
case "y":
|
|
861
|
+
case "u":
|
|
862
|
+
if (n === 2) return pad(Math.floor(year) % 100, 2);
|
|
863
|
+
return pad(Math.floor(year), n);
|
|
864
|
+
case "M":
|
|
865
|
+
if (n === 1) return String(Math.floor(month));
|
|
866
|
+
if (n === 2) return pad(Math.floor(month), 2);
|
|
867
|
+
if (n === 3) return MONTH_ABBR[monthIdx];
|
|
868
|
+
return MONTH_FULL[monthIdx];
|
|
869
|
+
case "d":
|
|
870
|
+
return pad(Math.floor(day), n);
|
|
871
|
+
case "H":
|
|
872
|
+
return pad(Math.floor(hour), n);
|
|
873
|
+
case "h":
|
|
874
|
+
return pad(Math.floor(hour) % 12 || 12, n);
|
|
875
|
+
case "m":
|
|
876
|
+
return pad(Math.floor(minute), n);
|
|
877
|
+
case "s":
|
|
878
|
+
return pad(wholeSec, n);
|
|
879
|
+
case "S":
|
|
880
|
+
return pad(Math.floor(frac * Math.pow(10, n)), n);
|
|
881
|
+
case "a":
|
|
882
|
+
return hour < 12 ? "AM" : "PM";
|
|
883
|
+
default:
|
|
884
|
+
throw new RuntimeError(
|
|
885
|
+
`datetime: unsupported format token '${c.repeat(n)}' in '${pattern}'`
|
|
886
|
+
);
|
|
887
|
+
}
|
|
888
|
+
};
|
|
889
|
+
let out = "";
|
|
890
|
+
let i = 0;
|
|
891
|
+
while (i < pattern.length) {
|
|
892
|
+
const c = pattern[i];
|
|
893
|
+
if (c === "'") {
|
|
894
|
+
i++;
|
|
895
|
+
let lit = "";
|
|
896
|
+
let closed = false;
|
|
897
|
+
while (i < pattern.length) {
|
|
898
|
+
if (pattern[i] === "'") {
|
|
899
|
+
if (pattern[i + 1] === "'") {
|
|
900
|
+
lit += "'";
|
|
901
|
+
i += 2;
|
|
902
|
+
continue;
|
|
903
|
+
}
|
|
904
|
+
i++;
|
|
905
|
+
closed = true;
|
|
906
|
+
break;
|
|
907
|
+
}
|
|
908
|
+
lit += pattern[i++];
|
|
909
|
+
}
|
|
910
|
+
if (!closed && lit !== "")
|
|
911
|
+
throw new RuntimeError(
|
|
912
|
+
`datetime: unterminated quoted literal in format '${pattern}'`
|
|
913
|
+
);
|
|
914
|
+
out += lit === "" ? "'" : lit;
|
|
915
|
+
continue;
|
|
916
|
+
}
|
|
917
|
+
if (!/[a-zA-Z]/.test(c)) {
|
|
918
|
+
out += c;
|
|
919
|
+
i++;
|
|
920
|
+
continue;
|
|
921
|
+
}
|
|
922
|
+
let j = i;
|
|
923
|
+
while (j < pattern.length && pattern[j] === c) j++;
|
|
924
|
+
out += formatToken(c, j - i);
|
|
925
|
+
i = j;
|
|
926
|
+
}
|
|
927
|
+
return out;
|
|
928
|
+
}
|
|
929
|
+
|
|
822
930
|
// src/numbl-core/runtime/display.ts
|
|
823
931
|
function displayValue(v) {
|
|
824
932
|
if (isRuntimeNumber(v)) {
|
|
@@ -1093,6 +1201,13 @@ function formatDatetimeOrDuration(v) {
|
|
|
1093
1201
|
if (v.className === "duration") return formatDurationInstance(v);
|
|
1094
1202
|
return null;
|
|
1095
1203
|
}
|
|
1204
|
+
function textField(v, name) {
|
|
1205
|
+
const fv = v.fields.get(name);
|
|
1206
|
+
if (fv === void 0) return null;
|
|
1207
|
+
if (isRuntimeString(fv)) return fv;
|
|
1208
|
+
if (isRuntimeChar(fv)) return fv.value;
|
|
1209
|
+
return null;
|
|
1210
|
+
}
|
|
1096
1211
|
function formatDatetimeInstance(v) {
|
|
1097
1212
|
const year = numField(v, "Year");
|
|
1098
1213
|
const month = numField(v, "Month");
|
|
@@ -1102,6 +1217,10 @@ function formatDatetimeInstance(v) {
|
|
|
1102
1217
|
const second = numField(v, "Second");
|
|
1103
1218
|
if (year === null || month === null || day === null || hour === null || minute === null || second === null)
|
|
1104
1219
|
return null;
|
|
1220
|
+
const fmt = textField(v, "Format");
|
|
1221
|
+
if (fmt !== null && fmt !== "") {
|
|
1222
|
+
return formatDatetimePattern(fmt, year, month, day, hour, minute, second);
|
|
1223
|
+
}
|
|
1105
1224
|
const mIdx = Math.max(0, Math.min(11, Math.floor(month) - 1));
|
|
1106
1225
|
const mon = DATETIME_MONTH_ABBR[mIdx];
|
|
1107
1226
|
const dd = String(Math.floor(day)).padStart(2, "0");
|
|
@@ -22321,8 +22440,8 @@ function sprintfFormat(fmt, args) {
|
|
|
22321
22440
|
if (width > 0) {
|
|
22322
22441
|
const padChar = zeroPad ? "0" : " ";
|
|
22323
22442
|
const padLen = Math.max(0, width - sign.length - s.length);
|
|
22324
|
-
const
|
|
22325
|
-
result += leftAlign ? sign + s + " ".repeat(padLen) : zeroPad ? sign +
|
|
22443
|
+
const pad2 = padChar.repeat(padLen);
|
|
22444
|
+
result += leftAlign ? sign + s + " ".repeat(padLen) : zeroPad ? sign + pad2 + s : pad2 + sign + s;
|
|
22326
22445
|
} else {
|
|
22327
22446
|
result += sign + s;
|
|
22328
22447
|
}
|
|
@@ -25046,6 +25165,17 @@ function indexIntoRTValue(base, indices) {
|
|
|
25046
25165
|
return base.elements[i];
|
|
25047
25166
|
}
|
|
25048
25167
|
if (isRuntimeTensor(idx)) {
|
|
25168
|
+
if (idx._isLogical) {
|
|
25169
|
+
const newElements2 = [];
|
|
25170
|
+
for (let k = 0; k < idx.data.length; k++) {
|
|
25171
|
+
if (idx.data[k] !== 0) {
|
|
25172
|
+
if (k >= base.elements.length)
|
|
25173
|
+
throw new RuntimeError("Index exceeds struct array bounds");
|
|
25174
|
+
newElements2.push(base.elements[k]);
|
|
25175
|
+
}
|
|
25176
|
+
}
|
|
25177
|
+
return RTV.structArray(base.fieldNames, newElements2);
|
|
25178
|
+
}
|
|
25049
25179
|
const newElements = [];
|
|
25050
25180
|
for (let k = 0; k < idx.data.length; k++) {
|
|
25051
25181
|
const i = Math.round(idx.data[k]) - 1;
|
|
@@ -38167,13 +38297,19 @@ registerIBuiltin({
|
|
|
38167
38297
|
resolve: (argTypes) => {
|
|
38168
38298
|
if (argTypes.length !== 1) return null;
|
|
38169
38299
|
const a = argTypes[0];
|
|
38170
|
-
if (a.kind !== "char" && a.kind !== "string" && a.kind !== "number" && a.kind !== "tensor" && a.kind !== "cell" && a.kind !== "unknown"
|
|
38300
|
+
if (a.kind !== "char" && a.kind !== "string" && a.kind !== "number" && a.kind !== "tensor" && a.kind !== "cell" && a.kind !== "unknown" && // datetime/duration only — other classes keep their own char methods
|
|
38301
|
+
// (or the generic "does not support these argument types" error).
|
|
38302
|
+
!(a.kind === "class_instance" && (a.className === "datetime" || a.className === "duration")))
|
|
38171
38303
|
return null;
|
|
38172
38304
|
return {
|
|
38173
38305
|
outputTypes: [{ kind: "char" }],
|
|
38174
38306
|
apply: (args) => {
|
|
38175
38307
|
const v = args[0];
|
|
38176
38308
|
if (isRuntimeChar(v)) return v;
|
|
38309
|
+
if (isRuntimeClassInstance(v)) {
|
|
38310
|
+
const s = formatDatetimeOrDuration(v);
|
|
38311
|
+
if (s !== null) return RTV.char(s);
|
|
38312
|
+
}
|
|
38177
38313
|
if (isRuntimeString(v)) return RTV.char(v);
|
|
38178
38314
|
if (isRuntimeNumber(v))
|
|
38179
38315
|
return RTV.char(String.fromCharCode(Math.round(v)));
|
|
@@ -40561,7 +40697,7 @@ defineBuiltin({
|
|
|
40561
40697
|
const result = invComplexJS(A.data, A.imag, n);
|
|
40562
40698
|
return RTV.tensor(result.re, [n, n], result.im);
|
|
40563
40699
|
}
|
|
40564
|
-
const bridge = getEffectiveBridge("inv");
|
|
40700
|
+
const bridge = getEffectiveBridge("inv", "inv");
|
|
40565
40701
|
return RTV.tensor(bridge.inv(toF64(A.data), n), [n, n]);
|
|
40566
40702
|
}
|
|
40567
40703
|
}
|
|
@@ -42908,6 +43044,16 @@ defineBuiltin({
|
|
|
42908
43044
|
parseReshapeDims(args, 1);
|
|
42909
43045
|
return v;
|
|
42910
43046
|
}
|
|
43047
|
+
if (isRuntimeCell(v)) {
|
|
43048
|
+
const total = v.data.length;
|
|
43049
|
+
const s = parseReshapeDims(args, total);
|
|
43050
|
+
while (s.length > 2 && s[s.length - 1] === 1) s.pop();
|
|
43051
|
+
if (s.length > 2)
|
|
43052
|
+
throw new RuntimeError("reshape: cell arrays must be 2-D");
|
|
43053
|
+
const nr = s[0];
|
|
43054
|
+
const nc = s.length >= 2 ? s[1] : 1;
|
|
43055
|
+
return RTV.cell(v.data.slice(), [nr, nc]);
|
|
43056
|
+
}
|
|
42911
43057
|
if (isRuntimeClassInstanceArray(v)) {
|
|
42912
43058
|
const total = v.elements.length;
|
|
42913
43059
|
const s = parseReshapeDims(args, total);
|
|
@@ -48654,6 +48800,32 @@ function datetimeFromUtcMs(ms) {
|
|
|
48654
48800
|
function datetimeFromDatenum(dn) {
|
|
48655
48801
|
return datetimeFromUtcMs((dn - MATLAB_EPOCH_DAYS) * 864e5);
|
|
48656
48802
|
}
|
|
48803
|
+
function withTimeZoneFormat(dt, timeZone, format) {
|
|
48804
|
+
if (timeZone === void 0 && format === void 0) return dt;
|
|
48805
|
+
const fields = new Map(dt.fields);
|
|
48806
|
+
if (timeZone !== void 0) fields.set("TimeZone", RTV.char(timeZone));
|
|
48807
|
+
if (format !== void 0) fields.set("Format", RTV.char(format));
|
|
48808
|
+
return new RuntimeClassInstance("datetime", fields, false);
|
|
48809
|
+
}
|
|
48810
|
+
function todayParts(offsetDays, utc) {
|
|
48811
|
+
const now = /* @__PURE__ */ new Date();
|
|
48812
|
+
if (utc) {
|
|
48813
|
+
const d2 = new Date(
|
|
48814
|
+
Date.UTC(
|
|
48815
|
+
now.getUTCFullYear(),
|
|
48816
|
+
now.getUTCMonth(),
|
|
48817
|
+
now.getUTCDate() + offsetDays
|
|
48818
|
+
)
|
|
48819
|
+
);
|
|
48820
|
+
return [d2.getUTCFullYear(), d2.getUTCMonth() + 1, d2.getUTCDate()];
|
|
48821
|
+
}
|
|
48822
|
+
const d = new Date(
|
|
48823
|
+
now.getFullYear(),
|
|
48824
|
+
now.getMonth(),
|
|
48825
|
+
now.getDate() + offsetDays
|
|
48826
|
+
);
|
|
48827
|
+
return [d.getFullYear(), d.getMonth() + 1, d.getDate()];
|
|
48828
|
+
}
|
|
48657
48829
|
function makeDuration(totalSeconds) {
|
|
48658
48830
|
const fields = /* @__PURE__ */ new Map([
|
|
48659
48831
|
["Seconds", RTV.num(totalSeconds)]
|
|
@@ -48703,9 +48875,10 @@ registerIBuiltin({
|
|
|
48703
48875
|
"t = datetime('now' | 'today' | 'yesterday' | 'tomorrow')",
|
|
48704
48876
|
"t = datetime(Y, M, D)",
|
|
48705
48877
|
"t = datetime(Y, M, D, H, MI, S)",
|
|
48706
|
-
"t = datetime(X, 'ConvertFrom', dateType)"
|
|
48878
|
+
"t = datetime(X, 'ConvertFrom', dateType)",
|
|
48879
|
+
"t = datetime(..., 'TimeZone', tz, 'Format', fmt)"
|
|
48707
48880
|
],
|
|
48708
|
-
description: "Create a datetime value. Supported dateType values for ConvertFrom: 'datenum', 'posixtime', 'excel', 'excel1904'."
|
|
48881
|
+
description: "Create a datetime value. Supported dateType values for ConvertFrom: 'datenum', 'posixtime', 'excel', 'excel1904'. Trailing 'TimeZone' (only '', 'local', 'UTC') and 'Format' name-value pairs are supported; the Format pattern is used by char() and display."
|
|
48709
48882
|
},
|
|
48710
48883
|
resolve: () => ({
|
|
48711
48884
|
outputTypes: [
|
|
@@ -48717,75 +48890,83 @@ registerIBuiltin({
|
|
|
48717
48890
|
}
|
|
48718
48891
|
],
|
|
48719
48892
|
apply: (args) => {
|
|
48720
|
-
|
|
48721
|
-
|
|
48893
|
+
let timeZone;
|
|
48894
|
+
let format;
|
|
48895
|
+
let positional = args;
|
|
48896
|
+
while (positional.length >= 2) {
|
|
48897
|
+
const name = argToString(positional[positional.length - 2]);
|
|
48898
|
+
if (name === null) break;
|
|
48899
|
+
const lc = name.toLowerCase();
|
|
48900
|
+
if (lc !== "timezone" && lc !== "format") break;
|
|
48901
|
+
const value = argToString(positional[positional.length - 1]);
|
|
48902
|
+
if (value === null)
|
|
48903
|
+
throw new RuntimeError(`datetime: ${name} value must be text`);
|
|
48904
|
+
if (lc === "timezone") timeZone = value;
|
|
48905
|
+
else format = value;
|
|
48906
|
+
positional = positional.slice(0, -2);
|
|
48907
|
+
}
|
|
48908
|
+
const tzLc = timeZone?.toLowerCase();
|
|
48909
|
+
if (tzLc !== void 0 && tzLc !== "" && tzLc !== "local" && tzLc !== "utc") {
|
|
48910
|
+
throw new RuntimeError(
|
|
48911
|
+
`datetime: unsupported TimeZone '${timeZone}' (supported: '', 'local', 'UTC')`
|
|
48912
|
+
);
|
|
48722
48913
|
}
|
|
48723
|
-
|
|
48724
|
-
|
|
48914
|
+
const utc = tzLc === "utc";
|
|
48915
|
+
const finish = (dt) => withTimeZoneFormat(dt, timeZone, format);
|
|
48916
|
+
if (positional.length === 0) {
|
|
48917
|
+
return finish(
|
|
48918
|
+
utc ? datetimeFromUtcMs(Date.now()) : datetimeFromDate(/* @__PURE__ */ new Date())
|
|
48919
|
+
);
|
|
48920
|
+
}
|
|
48921
|
+
if (positional.length === 1) {
|
|
48922
|
+
const s = argToString(positional[0]);
|
|
48725
48923
|
if (s !== null) {
|
|
48726
|
-
const now = /* @__PURE__ */ new Date();
|
|
48727
48924
|
const lc = s.toLowerCase();
|
|
48728
|
-
if (lc === "now")
|
|
48729
|
-
|
|
48730
|
-
|
|
48731
|
-
now.getFullYear(),
|
|
48732
|
-
now.getMonth() + 1,
|
|
48733
|
-
now.getDate(),
|
|
48734
|
-
0,
|
|
48735
|
-
0,
|
|
48736
|
-
0
|
|
48925
|
+
if (lc === "now") {
|
|
48926
|
+
return finish(
|
|
48927
|
+
utc ? datetimeFromUtcMs(Date.now()) : datetimeFromDate(/* @__PURE__ */ new Date())
|
|
48737
48928
|
);
|
|
48738
48929
|
}
|
|
48739
|
-
if (lc === "yesterday" || lc === "tomorrow") {
|
|
48740
|
-
const
|
|
48741
|
-
|
|
48742
|
-
|
|
48743
|
-
now.getDate() + (lc === "tomorrow" ? 1 : -1)
|
|
48744
|
-
);
|
|
48745
|
-
return makeDatetime(
|
|
48746
|
-
d.getFullYear(),
|
|
48747
|
-
d.getMonth() + 1,
|
|
48748
|
-
d.getDate(),
|
|
48749
|
-
0,
|
|
48750
|
-
0,
|
|
48751
|
-
0
|
|
48752
|
-
);
|
|
48930
|
+
if (lc === "today" || lc === "yesterday" || lc === "tomorrow") {
|
|
48931
|
+
const offset = lc === "tomorrow" ? 1 : lc === "yesterday" ? -1 : 0;
|
|
48932
|
+
const [Y, M, D] = todayParts(offset, utc);
|
|
48933
|
+
return finish(makeDatetime(Y, M, D, 0, 0, 0));
|
|
48753
48934
|
}
|
|
48754
48935
|
throw new RuntimeError(
|
|
48755
48936
|
`datetime: unrecognized relative-day string '${s}'`
|
|
48756
48937
|
);
|
|
48757
48938
|
}
|
|
48758
48939
|
}
|
|
48759
|
-
if (
|
|
48760
|
-
const flag = argToString(
|
|
48761
|
-
const kind = argToString(
|
|
48940
|
+
if (positional.length === 3) {
|
|
48941
|
+
const flag = argToString(positional[1]);
|
|
48942
|
+
const kind = argToString(positional[2]);
|
|
48762
48943
|
if (flag !== null && flag.toLowerCase() === "convertfrom") {
|
|
48763
48944
|
if (kind === null)
|
|
48764
48945
|
throw new RuntimeError("datetime: dateType must be text");
|
|
48765
|
-
const x = toNumber(
|
|
48946
|
+
const x = toNumber(positional[0]);
|
|
48766
48947
|
const k = kind.toLowerCase();
|
|
48767
|
-
if (k === "datenum") return datetimeFromDatenum(x);
|
|
48768
|
-
if (k === "posixtime") return datetimeFromUtcMs(x * 1e3);
|
|
48948
|
+
if (k === "datenum") return finish(datetimeFromDatenum(x));
|
|
48949
|
+
if (k === "posixtime") return finish(datetimeFromUtcMs(x * 1e3));
|
|
48769
48950
|
if (k === "excel") {
|
|
48770
|
-
return datetimeFromUtcMs((x - 25569) * 864e5);
|
|
48951
|
+
return finish(datetimeFromUtcMs((x - 25569) * 864e5));
|
|
48771
48952
|
}
|
|
48772
48953
|
if (k === "excel1904") {
|
|
48773
|
-
return datetimeFromUtcMs((x - 24107) * 864e5);
|
|
48954
|
+
return finish(datetimeFromUtcMs((x - 24107) * 864e5));
|
|
48774
48955
|
}
|
|
48775
48956
|
throw new RuntimeError(
|
|
48776
48957
|
`datetime: unsupported ConvertFrom type '${kind}'`
|
|
48777
48958
|
);
|
|
48778
48959
|
}
|
|
48779
48960
|
}
|
|
48780
|
-
if (
|
|
48781
|
-
const Y = toNumber(
|
|
48782
|
-
const M = toNumber(
|
|
48783
|
-
const D = toNumber(
|
|
48784
|
-
const H2 =
|
|
48785
|
-
const MI =
|
|
48786
|
-
const S =
|
|
48787
|
-
const MS =
|
|
48788
|
-
return makeDatetime(Y, M, D, H2, MI, S + MS / 1e3);
|
|
48961
|
+
if (positional.length === 3 || positional.length === 6 || positional.length === 7) {
|
|
48962
|
+
const Y = toNumber(positional[0]);
|
|
48963
|
+
const M = toNumber(positional[1]);
|
|
48964
|
+
const D = toNumber(positional[2]);
|
|
48965
|
+
const H2 = positional.length >= 6 ? toNumber(positional[3]) : 0;
|
|
48966
|
+
const MI = positional.length >= 6 ? toNumber(positional[4]) : 0;
|
|
48967
|
+
const S = positional.length >= 6 ? toNumber(positional[5]) : 0;
|
|
48968
|
+
const MS = positional.length >= 7 ? toNumber(positional[6]) : 0;
|
|
48969
|
+
return finish(makeDatetime(Y, M, D, H2, MI, S + MS / 1e3));
|
|
48789
48970
|
}
|
|
48790
48971
|
throw new RuntimeError(
|
|
48791
48972
|
`datetime: unsupported argument pattern (nargin=${args.length})`
|
|
@@ -56090,6 +56271,7 @@ var SPECIAL_BUILTIN_NAMES = [
|
|
|
56090
56271
|
"copyfile",
|
|
56091
56272
|
"fileattrib",
|
|
56092
56273
|
"unzip",
|
|
56274
|
+
"zip",
|
|
56093
56275
|
"dir",
|
|
56094
56276
|
"warning",
|
|
56095
56277
|
"input",
|
|
@@ -57202,6 +57384,26 @@ function registerSpecialBuiltins(rt) {
|
|
|
57202
57384
|
}
|
|
57203
57385
|
return void 0;
|
|
57204
57386
|
});
|
|
57387
|
+
registerSpecial("zip", (nargout, args) => {
|
|
57388
|
+
const io = requireFileIO();
|
|
57389
|
+
if (!io.zip)
|
|
57390
|
+
throw new RuntimeError("zip is not available in this environment");
|
|
57391
|
+
const margs = args.map((a) => ensureRuntimeValue(a));
|
|
57392
|
+
if (margs.length < 2)
|
|
57393
|
+
throw new RuntimeError("zip requires at least 2 arguments");
|
|
57394
|
+
let zipfilename = toString(margs[0]);
|
|
57395
|
+
const base = zipfilename.split(/[/\\]/).pop() ?? zipfilename;
|
|
57396
|
+
if (!base.includes(".")) zipfilename += ".zip";
|
|
57397
|
+
const fnames = margs[1];
|
|
57398
|
+
const filenames = isRuntimeCell(fnames) ? fnames.data.map((v) => toString(ensureRuntimeValue(v))) : [toString(fnames)];
|
|
57399
|
+
const rootdir = margs.length >= 3 ? toString(margs[2]) : ".";
|
|
57400
|
+
const entryNames = io.zip(zipfilename, filenames, rootdir);
|
|
57401
|
+
if (nargout >= 1) {
|
|
57402
|
+
const cellData = entryNames.map((f) => RTV.char(f));
|
|
57403
|
+
return RTV.cell(cellData, [1, cellData.length]);
|
|
57404
|
+
}
|
|
57405
|
+
return void 0;
|
|
57406
|
+
});
|
|
57205
57407
|
registerSpecial("dir", (nargout, args) => {
|
|
57206
57408
|
const io = requireFileIO();
|
|
57207
57409
|
if (!io.listDir)
|
|
@@ -61069,8 +61271,8 @@ function padExtent(e, tight) {
|
|
|
61069
61271
|
return [min2, max2];
|
|
61070
61272
|
}
|
|
61071
61273
|
if (tight) return [min2, max2];
|
|
61072
|
-
const
|
|
61073
|
-
return [min2 -
|
|
61274
|
+
const pad2 = (max2 - min2) * 0.05;
|
|
61275
|
+
return [min2 - pad2, max2 + pad2];
|
|
61074
61276
|
}
|
|
61075
61277
|
function applyExplicit(auto, explicit) {
|
|
61076
61278
|
if (!explicit) return auto;
|
|
@@ -65895,6 +66097,12 @@ function evalMember(expr, nargout) {
|
|
|
65895
66097
|
}
|
|
65896
66098
|
}
|
|
65897
66099
|
const base = this.evalExpr(expr.base);
|
|
66100
|
+
const baseRv = ensureRuntimeValue(base);
|
|
66101
|
+
if (isRuntimeStructArray(baseRv) && baseRv.elements.length !== 1) {
|
|
66102
|
+
return baseRv.elements.map(
|
|
66103
|
+
(el) => ensureRuntimeValue(this.rt.getMember(el, expr.name))
|
|
66104
|
+
);
|
|
66105
|
+
}
|
|
65898
66106
|
return this.rt.getMember(base, expr.name);
|
|
65899
66107
|
}
|
|
65900
66108
|
function tryExtractDottedName(expr) {
|
|
@@ -66106,12 +66314,31 @@ function evalCellLiteral(expr) {
|
|
|
66106
66314
|
}
|
|
66107
66315
|
return RTV.cell(elements2, [1, elements2.length]);
|
|
66108
66316
|
}
|
|
66109
|
-
const
|
|
66110
|
-
|
|
66317
|
+
const rowValues = expr.rows.map((row) => {
|
|
66318
|
+
const vals = [];
|
|
66319
|
+
for (const e of row) {
|
|
66320
|
+
const v = this.evalExpr(e);
|
|
66321
|
+
if (Array.isArray(v)) {
|
|
66322
|
+
for (const elem of v) vals.push(ensureRuntimeValue(elem));
|
|
66323
|
+
} else {
|
|
66324
|
+
vals.push(ensureRuntimeValue(v));
|
|
66325
|
+
}
|
|
66326
|
+
}
|
|
66327
|
+
return vals;
|
|
66328
|
+
});
|
|
66329
|
+
const numRows = rowValues.length;
|
|
66330
|
+
const numCols = rowValues[0].length;
|
|
66331
|
+
for (const rv of rowValues) {
|
|
66332
|
+
if (rv.length !== numCols) {
|
|
66333
|
+
throw new RuntimeError(
|
|
66334
|
+
"Cell array rows must have the same number of columns"
|
|
66335
|
+
);
|
|
66336
|
+
}
|
|
66337
|
+
}
|
|
66111
66338
|
const elements = [];
|
|
66112
66339
|
for (let c = 0; c < numCols; c++) {
|
|
66113
66340
|
for (let r = 0; r < numRows; r++) {
|
|
66114
|
-
elements.push(
|
|
66341
|
+
elements.push(rowValues[r][c]);
|
|
66115
66342
|
}
|
|
66116
66343
|
}
|
|
66117
66344
|
return RTV.cell(elements, [numRows, numCols]);
|
|
@@ -70586,8 +70813,8 @@ function mtoc2_sprintf_format(fmt, args) {
|
|
|
70586
70813
|
if (width > 0) {
|
|
70587
70814
|
const padChar = zeroPad ? "0" : " ";
|
|
70588
70815
|
const padLen = Math.max(0, width - sign.length - s.length);
|
|
70589
|
-
const
|
|
70590
|
-
result += leftAlign ? sign + s + " ".repeat(padLen) : zeroPad ? sign +
|
|
70816
|
+
const pad2 = padChar.repeat(padLen);
|
|
70817
|
+
result += leftAlign ? sign + s + " ".repeat(padLen) : zeroPad ? sign + pad2 + s : pad2 + sign + s;
|
|
70591
70818
|
} else {
|
|
70592
70819
|
result += sign + s;
|
|
70593
70820
|
}
|
|
@@ -70872,8 +71099,8 @@ function disp_complex_slice(re, im, offset, rows, cols) {
|
|
|
70872
71099
|
for (let c = 0; c < cols; c++) {
|
|
70873
71100
|
const idx = r + c * rows;
|
|
70874
71101
|
const cell = cells[idx];
|
|
70875
|
-
const
|
|
70876
|
-
for (let i = 0; i <
|
|
71102
|
+
const pad2 = colWidths[c] - cell.length;
|
|
71103
|
+
for (let i = 0; i < pad2; i++) line += " ";
|
|
70877
71104
|
line += cell;
|
|
70878
71105
|
if (c < cols - 1) line += " ";
|
|
70879
71106
|
}
|
|
@@ -72285,6 +72512,14 @@ function mtoc2_tensor_mtimes_real(a, b) {
|
|
|
72285
72512
|
`mtoc2_tensor_mtimes_real: inner dimensions disagree (${k} vs ${k2})`
|
|
72286
72513
|
);
|
|
72287
72514
|
}
|
|
72515
|
+
if (typeof $matmulAccel === "function") {
|
|
72516
|
+
const accel = $matmulAccel(a.data, m, k, b.data, n);
|
|
72517
|
+
if (accel) {
|
|
72518
|
+
const acc = mtoc2_tensor_alloc(m, n);
|
|
72519
|
+
acc.data.set(accel);
|
|
72520
|
+
return acc;
|
|
72521
|
+
}
|
|
72522
|
+
}
|
|
72288
72523
|
const r = mtoc2_tensor_alloc(m, n);
|
|
72289
72524
|
for (let j = 0; j < n; j++) {
|
|
72290
72525
|
for (let i = 0; i < m; i++) {
|
|
@@ -73496,7 +73731,7 @@ var JS_SNIPPETS = {
|
|
|
73496
73731
|
"tensor_logspace.js": "// JS sibling of `tensor_logspace.h`. Build a 1\xD7n row tensor of n\n// logarithmically-spaced values from 10^a to 10^b. Byte-for-byte with\n// numbl's interpreter `logspace`, including the MATLAB special case\n// where an upper limit of exactly `pi` makes the last point `pi`.\n\n\nfunction mtoc2_tensor_logspace(a, b, n) {\n if (n <= 0) return mtoc2_tensor_alloc(1, 0);\n const isPi = b === Math.PI;\n const endVal = isPi ? Math.PI : Math.pow(10, b);\n const out = mtoc2_tensor_alloc(1, n);\n if (n === 1) {\n out.data[0] = endVal;\n return out;\n }\n if (isPi) {\n const logStart = Math.log10(Math.pow(10, a));\n const logEnd = Math.log10(Math.PI);\n for (let i = 0; i < n; i++) {\n const t = logStart + ((logEnd - logStart) * i) / (n - 1);\n out.data[i] = Math.pow(10, t);\n }\n } else {\n for (let i = 0; i < n; i++) {\n const t = a + ((b - a) * i) / (n - 1);\n out.data[i] = Math.pow(10, t);\n }\n }\n return out;\n}\n",
|
|
73497
73732
|
"tensor_meshgrid.js": "// JS sibling of `tensor_meshgrid.h`. MATLAB-style coordinate grid.\n\n\nfunction numel(t) {\n let n = 1;\n for (const s of t.shape) n *= s;\n return n;\n}\n\nfunction mtoc2_meshgrid_x(x, y) {\n const M = numel(x);\n const N = numel(y);\n const X = mtoc2_tensor_alloc(N, M);\n for (let j = 0; j < M; j++) {\n const xj = x.data[j];\n for (let i = 0; i < N; i++) X.data[i + j * N] = xj;\n }\n return X;\n}\n\nfunction mtoc2_meshgrid(x, y) {\n const M = numel(x);\n const N = numel(y);\n const X = mtoc2_tensor_alloc(N, M);\n const Y = mtoc2_tensor_alloc(N, M);\n for (let j = 0; j < M; j++) {\n const xj = x.data[j];\n for (let i = 0; i < N; i++) {\n X.data[i + j * N] = xj;\n Y.data[i + j * N] = y.data[i];\n }\n }\n return { X, Y };\n}\n\nfunction mtoc2_meshgrid_1arg(x) {\n return mtoc2_meshgrid(x, x);\n}\n",
|
|
73498
73733
|
"tensor_mtimes_complex.js": '// JS sibling of `tensor_mtimes_complex.h`. 2-D matrix multiplication\n// producing a complex result. Handles all three mixed cases\n// (complex \xD7 complex, complex \xD7 real, real \xD7 complex) by treating an\n// undefined imag lane as implicit zeros.\n\n\nfunction mtoc2_tensor_mtimes_complex_scalar(a, b) {\n if (a.shape.length !== 2 || b.shape.length !== 2) {\n throw new Error("mtoc2_tensor_mtimes_complex_scalar: inputs must be 2-D");\n }\n if (a.shape[0] !== 1 || b.shape[1] !== 1) {\n throw new Error("mtoc2_tensor_mtimes_complex_scalar: requires 1\xD7k * k\xD71");\n }\n if (a.shape[1] !== b.shape[0]) {\n throw new Error("mtoc2_tensor_mtimes_complex_scalar: inner-dim mismatch");\n }\n const k = a.shape[1];\n const aim = a.imag;\n const bim = b.imag;\n let accR = 0;\n let accI = 0;\n for (let p = 0; p < k; p++) {\n const ar = a.data[p];\n const ai = aim !== undefined ? aim[p] : 0;\n const br = b.data[p];\n const bi = bim !== undefined ? bim[p] : 0;\n accR += ar * br - ai * bi;\n accI += ar * bi + ai * br;\n }\n return { re: accR, im: accI };\n}\n\nfunction mtoc2_tensor_mtimes_complex(a, b) {\n if (a.shape.length !== 2 || b.shape.length !== 2) {\n throw new Error("mtoc2_tensor_mtimes_complex: inputs must be 2-D");\n }\n const m = a.shape[0];\n const k = a.shape[1];\n const k2 = b.shape[0];\n const n = b.shape[1];\n if (k !== k2) {\n throw new Error(\n `mtoc2_tensor_mtimes_complex: inner-dim mismatch (${m}\xD7${k} * ${k2}\xD7${n})`\n );\n }\n const out = mtoc2_tensor_alloc_complex(m, n);\n const aim = a.imag;\n const bim = b.imag;\n for (let j = 0; j < n; j++) {\n for (let i = 0; i < m; i++) {\n let accR = 0;\n let accI = 0;\n for (let p = 0; p < k; p++) {\n const ar = a.data[i + p * m];\n const ai = aim !== undefined ? aim[i + p * m] : 0;\n const br = b.data[p + j * k];\n const bi = bim !== undefined ? bim[p + j * k] : 0;\n accR += ar * br - ai * bi;\n accI += ar * bi + ai * br;\n }\n out.data[i + j * m] = accR;\n out.imag[i + j * m] = accI;\n }\n }\n return out;\n}\n',
|
|
73499
|
-
"tensor_mtimes_real.js": '// JS sibling of `tensor_mtimes_real.h`. Real 2-D matrix\n// multiplication A * B. Column-major in, column-major out.\n// `mtoc2_tensor_mtimes_real_scalar` mirrors the C 1\xD7k * k\xD71\n// inner-product path that returns a bare number instead of a\n// freshly-allocated 1\xD71 tensor.\n\n\nfunction mtoc2_tensor_mtimes_real(a, b) {\n if (a.shape.length !== 2 || b.shape.length !== 2) {\n throw new Error("mtoc2_tensor_mtimes_real: inputs must be 2-D");\n }\n const m = a.shape[0];\n const k = a.shape[1];\n const k2 = b.shape[0];\n const n = b.shape[1];\n if (k !== k2) {\n throw new Error(\n `mtoc2_tensor_mtimes_real: inner dimensions disagree (${k} vs ${k2})`\n );\n }\n const r = mtoc2_tensor_alloc(m, n);\n for (let j = 0; j < n; j++) {\n for (let i = 0; i < m; i++) {\n let s = 0;\n for (let p = 0; p < k; p++) {\n s += a.data[i + p * m] * b.data[p + j * k];\n }\n r.data[i + j * m] = s;\n }\n }\n return r;\n}\n\nfunction mtoc2_tensor_mtimes_real_scalar(a, b) {\n if (a.shape.length !== 2 || b.shape.length !== 2) {\n throw new Error("mtoc2_tensor_mtimes_real_scalar: inputs must be 2-D");\n }\n // The translate-time type system has already proven a is 1\xD7k and b\n // is k\xD71; this helper trusts that and just runs the inner product.\n const k = a.shape[1];\n let s = 0;\n for (let p = 0; p < k; p++) {\n s += a.data[p * a.shape[0]] * b.data[p];\n }\n return s;\n}\n',
|
|
73734
|
+
"tensor_mtimes_real.js": '// JS sibling of `tensor_mtimes_real.h`. Real 2-D matrix\n// multiplication A * B. Column-major in, column-major out.\n// `mtoc2_tensor_mtimes_real_scalar` mirrors the C 1\xD7k * k\xD71\n// inner-product path that returns a bare number instead of a\n// freshly-allocated 1\xD71 tensor.\n\n\nfunction mtoc2_tensor_mtimes_real(a, b) {\n if (a.shape.length !== 2 || b.shape.length !== 2) {\n throw new Error("mtoc2_tensor_mtimes_real: inputs must be 2-D");\n }\n const m = a.shape[0];\n const k = a.shape[1];\n const k2 = b.shape[0];\n const n = b.shape[1];\n if (k !== k2) {\n throw new Error(\n `mtoc2_tensor_mtimes_real: inner dimensions disagree (${k} vs ${k2})`\n );\n }\n // Optional WASM LAPACK accelerator. When a host installs `$matmulAccel`\n // (browser worker, after loading a bridge), delegate the multiply; a\n // falsy return means "declined" (too small / error) and we fall through\n // to the JS loop below. `typeof` guard is safe even when unset.\n if (typeof $matmulAccel === "function") {\n const accel = $matmulAccel(a.data, m, k, b.data, n);\n if (accel) {\n const acc = mtoc2_tensor_alloc(m, n);\n acc.data.set(accel);\n return acc;\n }\n }\n const r = mtoc2_tensor_alloc(m, n);\n for (let j = 0; j < n; j++) {\n for (let i = 0; i < m; i++) {\n let s = 0;\n for (let p = 0; p < k; p++) {\n s += a.data[i + p * m] * b.data[p + j * k];\n }\n r.data[i + j * m] = s;\n }\n }\n return r;\n}\n\nfunction mtoc2_tensor_mtimes_real_scalar(a, b) {\n if (a.shape.length !== 2 || b.shape.length !== 2) {\n throw new Error("mtoc2_tensor_mtimes_real_scalar: inputs must be 2-D");\n }\n // The translate-time type system has already proven a is 1\xD7k and b\n // is k\xD71; this helper trusts that and just runs the inner product.\n const k = a.shape[1];\n let s = 0;\n for (let p = 0; p < k; p++) {\n s += a.data[p * a.shape[0]] * b.data[p];\n }\n return s;\n}\n',
|
|
73500
73735
|
"tensor_norm.js": "// JS sibling of `tensor_norm.h`. Vector norms for real and complex\n// tensors. The complex variants tolerate a missing imag lane (real\n// tensor flowing through a complex-typed norm route) by treating it\n// as zero.\n\nfunction mtoc2_norm2_real(a) {\n let acc = 0;\n for (let i = 0; i < a.data.length; i++) {\n const x = a.data[i];\n acc += x * x;\n }\n return Math.sqrt(acc);\n}\n\nfunction mtoc2_norm2_complex(a) {\n let acc = 0;\n const im = a.imag;\n for (let i = 0; i < a.data.length; i++) {\n const re = a.data[i];\n const imv = im !== undefined ? im[i] : 0;\n acc += re * re + imv * imv;\n }\n return Math.sqrt(acc);\n}\n\nfunction mtoc2_norm_p_real(a, p) {\n const n = a.data.length;\n if (n === 0) return 0;\n if (p === Infinity) {\n let m = 0;\n for (let i = 0; i < n; i++) {\n const x = Math.abs(a.data[i]);\n if (x > m) m = x;\n }\n return m;\n }\n if (p === -Infinity) {\n let m = Math.abs(a.data[0]);\n for (let i = 1; i < n; i++) {\n const x = Math.abs(a.data[i]);\n if (x < m) m = x;\n }\n return m;\n }\n if (p === 1) {\n let acc = 0;\n for (let i = 0; i < n; i++) acc += Math.abs(a.data[i]);\n return acc;\n }\n if (p === 2) return mtoc2_norm2_real(a);\n let acc = 0;\n for (let i = 0; i < n; i++) acc += Math.pow(Math.abs(a.data[i]), p);\n return Math.pow(acc, 1 / p);\n}\n\nfunction mtoc2_norm_p_complex(a, p) {\n const n = a.data.length;\n if (n === 0) return 0;\n const im = a.imag;\n const abs = i => {\n const re = a.data[i];\n const imv = im !== undefined ? im[i] : 0;\n return Math.hypot(re, imv);\n };\n if (p === Infinity) {\n let m = 0;\n for (let i = 0; i < n; i++) {\n const x = abs(i);\n if (x > m) m = x;\n }\n return m;\n }\n if (p === -Infinity) {\n let m = abs(0);\n for (let i = 1; i < n; i++) {\n const x = abs(i);\n if (x < m) m = x;\n }\n return m;\n }\n if (p === 2) return mtoc2_norm2_complex(a);\n if (p === 1) {\n let acc = 0;\n for (let i = 0; i < n; i++) acc += abs(i);\n return acc;\n }\n let acc = 0;\n for (let i = 0; i < n; i++) acc += Math.pow(abs(i), p);\n return Math.pow(acc, 1 / p);\n}\n",
|
|
73501
73736
|
"tensor_ones_nd.js": "// JS sibling of `tensor_ones_nd.h`. Fill the freshly-allocated\n// tensor with `1.0`.\n\n\nfunction mtoc2_tensor_ones_nd(ndim, dims) {\n const t = mtoc2_tensor_alloc_nd(ndim, dims);\n t.data.fill(1);\n return t;\n}\n",
|
|
73502
73737
|
"tensor_ones_square.js": "// JS sibling of `tensor_ones_square.h`. See `tensor_zeros_square.js`\n// for the rationale.\n\n\nfunction mtoc2_tensor_ones_square(n) {\n return mtoc2_tensor_ones_nd(2, [n, n]);\n}\n",
|
|
@@ -82065,9 +82300,9 @@ function tileExact(src, padShape2, padReps) {
|
|
|
82065
82300
|
}
|
|
82066
82301
|
return out;
|
|
82067
82302
|
}
|
|
82068
|
-
function padTo(arr,
|
|
82303
|
+
function padTo(arr, pad2, len) {
|
|
82069
82304
|
const out = arr.slice();
|
|
82070
|
-
while (out.length < len) out.push(
|
|
82305
|
+
while (out.length < len) out.push(pad2);
|
|
82071
82306
|
return out;
|
|
82072
82307
|
}
|
|
82073
82308
|
function trimTrailingOnes(shape) {
|
|
@@ -93152,7 +93387,7 @@ var VirtualFileSystem = class {
|
|
|
93152
93387
|
};
|
|
93153
93388
|
|
|
93154
93389
|
// src/vfs/BrowserFileIOAdapter.ts
|
|
93155
|
-
import { unzipSync } from "fflate";
|
|
93390
|
+
import { unzipSync, zipSync } from "fflate";
|
|
93156
93391
|
var TEXT_DECODER = new TextDecoder("utf-8");
|
|
93157
93392
|
var TEXT_ENCODER = new TextEncoder();
|
|
93158
93393
|
var READ_CHUNK_SIZE = 8192;
|
|
@@ -93470,6 +93705,57 @@ var BrowserFileIOAdapter = class {
|
|
|
93470
93705
|
}
|
|
93471
93706
|
return extracted;
|
|
93472
93707
|
}
|
|
93708
|
+
zip(zipfilename, filenames, rootDir) {
|
|
93709
|
+
const root = this.vfs.normalizePath(rootDir);
|
|
93710
|
+
const dest = this.vfs.normalizePath(zipfilename);
|
|
93711
|
+
const entries = {};
|
|
93712
|
+
const names = [];
|
|
93713
|
+
const toEntryName = (abs2) => {
|
|
93714
|
+
const prefix = root === "/" ? "/" : root + "/";
|
|
93715
|
+
if (!abs2.startsWith(prefix)) return abs2.slice(abs2.lastIndexOf("/") + 1);
|
|
93716
|
+
return abs2.slice(prefix.length);
|
|
93717
|
+
};
|
|
93718
|
+
const addFile = (abs2) => {
|
|
93719
|
+
const name = toEntryName(abs2);
|
|
93720
|
+
entries[name] = this.vfs.readFile(abs2);
|
|
93721
|
+
names.push(name);
|
|
93722
|
+
};
|
|
93723
|
+
const addDir = (absDir) => {
|
|
93724
|
+
for (const entry of this.vfs.listDir(absDir)) {
|
|
93725
|
+
if (entry.name === "." || entry.name === "..") continue;
|
|
93726
|
+
const abs2 = absDir + "/" + entry.name;
|
|
93727
|
+
if (entry.isdir) addDir(abs2);
|
|
93728
|
+
else addFile(abs2);
|
|
93729
|
+
}
|
|
93730
|
+
};
|
|
93731
|
+
const addPath = (abs2) => {
|
|
93732
|
+
const type = this.vfs.exists(abs2);
|
|
93733
|
+
if (type === null) throw new Error(`zip: cannot find '${abs2}'`);
|
|
93734
|
+
if (type === "dir") addDir(abs2);
|
|
93735
|
+
else addFile(abs2);
|
|
93736
|
+
};
|
|
93737
|
+
for (const f of filenames) {
|
|
93738
|
+
const p2 = f.replace(/\\/g, "/");
|
|
93739
|
+
const abs2 = p2.startsWith("/") ? this.vfs.normalizePath(p2) : this.vfs.normalizePath(root + "/" + p2);
|
|
93740
|
+
const last = p2.split("/").pop() ?? p2;
|
|
93741
|
+
if (last.includes("*") || last.includes("?")) {
|
|
93742
|
+
const lastSlash = abs2.lastIndexOf("/");
|
|
93743
|
+
const dir = lastSlash > 0 ? abs2.slice(0, lastSlash) : "/";
|
|
93744
|
+
const re = new RegExp(
|
|
93745
|
+
"^" + last.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".") + "$"
|
|
93746
|
+
);
|
|
93747
|
+
if (this.vfs.exists(dir) !== "dir") continue;
|
|
93748
|
+
for (const entry of this.vfs.listDir(dir)) {
|
|
93749
|
+
if (entry.name === "." || entry.name === "..") continue;
|
|
93750
|
+
if (re.test(entry.name)) addPath(dir + "/" + entry.name);
|
|
93751
|
+
}
|
|
93752
|
+
} else {
|
|
93753
|
+
addPath(abs2);
|
|
93754
|
+
}
|
|
93755
|
+
}
|
|
93756
|
+
this.vfs.writeFile(dest, zipSync(entries));
|
|
93757
|
+
return names;
|
|
93758
|
+
}
|
|
93473
93759
|
/** Get the VFS changes for syncing back to the main thread. */
|
|
93474
93760
|
getChanges() {
|
|
93475
93761
|
for (const [, entry] of this.openFiles) {
|
|
@@ -93552,21 +93838,30 @@ var BrowserFileIOAdapter = class {
|
|
|
93552
93838
|
);
|
|
93553
93839
|
}
|
|
93554
93840
|
listDirRecursive(pattern) {
|
|
93555
|
-
const
|
|
93556
|
-
|
|
93841
|
+
const norm2 = pattern.replace(/\\/g, "/");
|
|
93842
|
+
const idx = norm2.indexOf("**");
|
|
93843
|
+
let baseDir = norm2.slice(0, idx);
|
|
93557
93844
|
if (baseDir.endsWith("/")) baseDir = baseDir.slice(0, -1);
|
|
93558
93845
|
if (!baseDir) baseDir = ".";
|
|
93846
|
+
const absBase = this.vfs.normalizePath(baseDir);
|
|
93847
|
+
if (this.vfs.exists(absBase) !== "dir") return [];
|
|
93848
|
+
const suffix = norm2.slice(idx);
|
|
93849
|
+
const DIRS = "\0";
|
|
93850
|
+
const ANY = "";
|
|
93851
|
+
const re = new RegExp(
|
|
93852
|
+
"^" + suffix.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*\//g, DIRS).replace(/\*\*/g, ANY).replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]").replace(new RegExp(DIRS, "g"), "(?:.*/)?").replace(new RegExp(ANY, "g"), ".*") + "$"
|
|
93853
|
+
);
|
|
93559
93854
|
const results = [];
|
|
93560
|
-
const walkDir = (dir) => {
|
|
93561
|
-
const
|
|
93562
|
-
|
|
93563
|
-
|
|
93855
|
+
const walkDir = (dir, rel) => {
|
|
93856
|
+
const relPrefix = rel ? rel + "/" : "";
|
|
93857
|
+
for (const entry of this.vfs.listDir(dir)) {
|
|
93858
|
+
if (re.test(relPrefix + entry.name)) results.push(entry);
|
|
93564
93859
|
if (entry.isdir && entry.name !== "." && entry.name !== "..") {
|
|
93565
|
-
walkDir(entry.folder + "/" + entry.name);
|
|
93860
|
+
walkDir(entry.folder + "/" + entry.name, relPrefix + entry.name);
|
|
93566
93861
|
}
|
|
93567
93862
|
}
|
|
93568
93863
|
};
|
|
93569
|
-
walkDir(
|
|
93864
|
+
walkDir(absBase, "");
|
|
93570
93865
|
return results;
|
|
93571
93866
|
}
|
|
93572
93867
|
};
|