@lotics/cli 0.96.1 → 0.96.3
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/README.md +3 -1
- package/dist/render_page.js +6991 -6901
- package/dist/src/cli.js +213 -42
- package/package.json +1 -1
package/dist/src/cli.js
CHANGED
|
@@ -45219,23 +45219,23 @@ function setActiveOrg(orgId, scope) {
|
|
|
45219
45219
|
const config2 = loadGlobalConfig() ?? {};
|
|
45220
45220
|
saveGlobalConfig({ ...config2, active_org: orgId });
|
|
45221
45221
|
}
|
|
45222
|
-
function setSelectedWorkspace(workspaceId) {
|
|
45222
|
+
function setSelectedWorkspace(workspaceId, resolvedOrgId) {
|
|
45223
|
+
if (!resolvedOrgId) return null;
|
|
45223
45224
|
const local = loadLocalConfig();
|
|
45224
|
-
if (local?.active_org) {
|
|
45225
|
+
if (local?.active_org === resolvedOrgId) {
|
|
45225
45226
|
saveConfig({ ...local, workspace_id: workspaceId }, "auto");
|
|
45226
45227
|
return { scope: "local", orgId: local.active_org };
|
|
45227
45228
|
}
|
|
45228
45229
|
const config2 = loadGlobalConfig() ?? {};
|
|
45229
|
-
const
|
|
45230
|
-
|
|
45231
|
-
if (!orgId || !profile) {
|
|
45230
|
+
const profile = config2.profiles?.[resolvedOrgId];
|
|
45231
|
+
if (!profile) {
|
|
45232
45232
|
return null;
|
|
45233
45233
|
}
|
|
45234
45234
|
saveGlobalConfig({
|
|
45235
45235
|
...config2,
|
|
45236
|
-
profiles: { ...config2.profiles, [
|
|
45236
|
+
profiles: { ...config2.profiles, [resolvedOrgId]: { ...profile, workspace_id: workspaceId } }
|
|
45237
45237
|
});
|
|
45238
|
-
return { scope: "global", orgId };
|
|
45238
|
+
return { scope: "global", orgId: resolvedOrgId };
|
|
45239
45239
|
}
|
|
45240
45240
|
var UPDATE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
45241
45241
|
function checkForUpdate(currentVersion) {
|
|
@@ -79151,7 +79151,7 @@ function buildColumns(colDefs, colHidden, maxContentWidth, colCount, _defaultCol
|
|
|
79151
79151
|
const contentChars = maxContentWidth.get(c) ?? 0;
|
|
79152
79152
|
const hidden = colHidden.has(c);
|
|
79153
79153
|
let width;
|
|
79154
|
-
if (excelWidth && excelWidth >
|
|
79154
|
+
if (excelWidth !== void 0 && excelWidth > 0) {
|
|
79155
79155
|
width = excelWidth;
|
|
79156
79156
|
} else {
|
|
79157
79157
|
width = Math.max(8, Math.min(contentChars + 2, 40));
|
|
@@ -79374,8 +79374,9 @@ function parseImages(rels, zipEntries) {
|
|
|
79374
79374
|
const drawingRelsPath = drawingPath.replace(/([^/]+)$/, "_rels/$1.rels");
|
|
79375
79375
|
const drawingRelsEntry = findZipEntry(zipEntries, drawingRelsPath);
|
|
79376
79376
|
const drawingRels = drawingRelsEntry ? parseDrawingRels(decodeUtf8(drawingRelsEntry)) : /* @__PURE__ */ new Map();
|
|
79377
|
-
const
|
|
79378
|
-
|
|
79377
|
+
for (const key of ["xdr:twoCellAnchor", "xdr:oneCellAnchor", "xdr:absoluteAnchor"]) {
|
|
79378
|
+
const anchors = wsDr[key];
|
|
79379
|
+
if (!anchors) continue;
|
|
79379
79380
|
for (const anchor of anchors) {
|
|
79380
79381
|
if (images.length >= MAX_IMAGES) break;
|
|
79381
79382
|
const image = extractImageFromAnchor(anchor, drawingRels, zipEntries, drawingPath);
|
|
@@ -79401,18 +79402,42 @@ function parseDrawingRels(relsXml2) {
|
|
|
79401
79402
|
}
|
|
79402
79403
|
return map3;
|
|
79403
79404
|
}
|
|
79405
|
+
var MEDIA_MIME_TYPES = {
|
|
79406
|
+
png: "image/png",
|
|
79407
|
+
jpg: "image/jpeg",
|
|
79408
|
+
jpeg: "image/jpeg",
|
|
79409
|
+
gif: "image/gif",
|
|
79410
|
+
bmp: "image/bmp",
|
|
79411
|
+
tiff: "image/tiff",
|
|
79412
|
+
tif: "image/tiff",
|
|
79413
|
+
svg: "image/svg+xml",
|
|
79414
|
+
emf: "image/x-emf",
|
|
79415
|
+
wmf: "image/x-wmf"
|
|
79416
|
+
};
|
|
79417
|
+
function isSupportedMediaMime(mime) {
|
|
79418
|
+
return Object.values(MEDIA_MIME_TYPES).includes(mime);
|
|
79419
|
+
}
|
|
79404
79420
|
function extractImageFromAnchor(anchor, drawingRels, zipEntries, drawingPath) {
|
|
79405
|
-
const from = anchor["xdr:from"];
|
|
79421
|
+
const from = anchor["xdr:from"] ?? { "xdr:row": "0", "xdr:col": "0" };
|
|
79406
79422
|
const to = anchor["xdr:to"];
|
|
79407
|
-
|
|
79423
|
+
const posEl = anchor["xdr:pos"];
|
|
79424
|
+
if (!anchor["xdr:from"] && !posEl) return void 0;
|
|
79425
|
+
const extEl = anchor["xdr:ext"];
|
|
79426
|
+
const extent = extEl ? { cx: parseInt(extEl["@_cx"] ?? "0", 10), cy: parseInt(extEl["@_cy"] ?? "0", 10) } : void 0;
|
|
79427
|
+
const pos = posEl ? { x: parseInt(posEl["@_x"] ?? "0", 10), y: parseInt(posEl["@_y"] ?? "0", 10) } : void 0;
|
|
79428
|
+
const anchorKind = to ? "twoCell" : posEl ? "absolute" : "oneCell";
|
|
79408
79429
|
const tl = {
|
|
79409
79430
|
row: parseInt(from["xdr:row"] ?? "0", 10),
|
|
79410
|
-
col: parseInt(from["xdr:col"] ?? "0", 10)
|
|
79431
|
+
col: parseInt(from["xdr:col"] ?? "0", 10),
|
|
79432
|
+
rowOff: parseInt(from["xdr:rowOff"] ?? "0", 10),
|
|
79433
|
+
colOff: parseInt(from["xdr:colOff"] ?? "0", 10)
|
|
79411
79434
|
};
|
|
79412
|
-
const br = {
|
|
79435
|
+
const br = to ? {
|
|
79413
79436
|
row: parseInt(to["xdr:row"] ?? "0", 10) + 1,
|
|
79414
|
-
col: parseInt(to["xdr:col"] ?? "0", 10) + 1
|
|
79415
|
-
|
|
79437
|
+
col: parseInt(to["xdr:col"] ?? "0", 10) + 1,
|
|
79438
|
+
rowOff: parseInt(to["xdr:rowOff"] ?? "0", 10),
|
|
79439
|
+
colOff: parseInt(to["xdr:colOff"] ?? "0", 10)
|
|
79440
|
+
} : { row: tl.row + 1, col: tl.col + 1, rowOff: 0, colOff: 0 };
|
|
79416
79441
|
const pic = anchor["xdr:pic"];
|
|
79417
79442
|
if (!pic) return void 0;
|
|
79418
79443
|
const blipFill = pic["xdr:blipFill"];
|
|
@@ -79428,10 +79453,10 @@ function extractImageFromAnchor(anchor, drawingRels, zipEntries, drawingPath) {
|
|
|
79428
79453
|
const imageEntry = findZipEntry(zipEntries, imagePath);
|
|
79429
79454
|
if (!imageEntry) return void 0;
|
|
79430
79455
|
const ext = imagePath.split(".").pop()?.toLowerCase() ?? "png";
|
|
79431
|
-
const mimeType = ext
|
|
79456
|
+
const mimeType = MEDIA_MIME_TYPES[ext] ?? "application/octet-stream";
|
|
79432
79457
|
const base643 = uint8ToBase64(imageEntry);
|
|
79433
79458
|
const dataUrl = `data:${mimeType};base64,${base643}`;
|
|
79434
|
-
return { dataUrl, tl, br };
|
|
79459
|
+
return { dataUrl, tl, br, ext, anchorKind, extent, pos };
|
|
79435
79460
|
}
|
|
79436
79461
|
function parseConditionalFormats(worksheet, theme, indexedColors) {
|
|
79437
79462
|
const cfArr = worksheet["conditionalFormatting"];
|
|
@@ -81897,7 +81922,7 @@ function readWorkbookRels(originalZip) {
|
|
|
81897
81922
|
const bytes = originalZip["xl/_rels/workbook.xml.rels"];
|
|
81898
81923
|
if (!bytes) return out;
|
|
81899
81924
|
const xml = decode3(bytes);
|
|
81900
|
-
const re2 = /<Relationship\b([
|
|
81925
|
+
const re2 = /<Relationship\b([^>]*?)\/>/g;
|
|
81901
81926
|
let m;
|
|
81902
81927
|
while ((m = re2.exec(xml)) !== null) {
|
|
81903
81928
|
const attrs = m[1];
|
|
@@ -81931,7 +81956,7 @@ function readSheetPivotPaths(originalZip, sheetTarget) {
|
|
|
81931
81956
|
const bytes = originalZip[relsPath];
|
|
81932
81957
|
if (!bytes) return [];
|
|
81933
81958
|
const xml = decode3(bytes);
|
|
81934
|
-
const re2 = /<Relationship\b([
|
|
81959
|
+
const re2 = /<Relationship\b([^>]*?)\/>/g;
|
|
81935
81960
|
const out = [];
|
|
81936
81961
|
let m;
|
|
81937
81962
|
while ((m = re2.exec(xml)) !== null) {
|
|
@@ -81943,6 +81968,32 @@ function readSheetPivotPaths(originalZip, sheetTarget) {
|
|
|
81943
81968
|
}
|
|
81944
81969
|
return out;
|
|
81945
81970
|
}
|
|
81971
|
+
function extractLegacyHeaderFooterArt(originalZip, sheetTarget) {
|
|
81972
|
+
if (!originalZip || !sheetTarget) return null;
|
|
81973
|
+
const sheetPath = `xl/${sheetTarget}`;
|
|
81974
|
+
const sheetBytes = originalZip[sheetPath];
|
|
81975
|
+
if (!sheetBytes || !/<legacyDrawingHF\b/.test(decode3(sheetBytes))) return null;
|
|
81976
|
+
const relsPath = sheetPath.replace(/([^/]+)$/, "_rels/$1.rels");
|
|
81977
|
+
const relsBytes = originalZip[relsPath];
|
|
81978
|
+
if (!relsBytes) return null;
|
|
81979
|
+
const relsXml2 = decode3(relsBytes);
|
|
81980
|
+
const hfRel = [...relsXml2.matchAll(/<Relationship\b([^>]*?)\/>/g)].map((m) => m[1]).find((attrs) => (/\bType="([^"]+)"/.exec(attrs)?.[1] ?? "").includes("/vmlDrawing"));
|
|
81981
|
+
const target = hfRel ? /\bTarget="([^"]+)"/.exec(hfRel)?.[1] : void 0;
|
|
81982
|
+
if (!target) return null;
|
|
81983
|
+
const vmlPath = `xl/${target.replace(/^\.\.\//, "")}`;
|
|
81984
|
+
if (!originalZip[vmlPath]) return null;
|
|
81985
|
+
const parts = [vmlPath];
|
|
81986
|
+
const vmlRelsPath = vmlPath.replace(/([^/]+)$/, "_rels/$1.rels");
|
|
81987
|
+
const vmlRels = originalZip[vmlRelsPath];
|
|
81988
|
+
if (vmlRels) {
|
|
81989
|
+
parts.push(vmlRelsPath);
|
|
81990
|
+
for (const m of decode3(vmlRels).matchAll(/\bTarget="([^"]+)"/g)) {
|
|
81991
|
+
const mediaPath = `xl/${m[1].replace(/^\.\.\//, "")}`;
|
|
81992
|
+
if (originalZip[mediaPath]) parts.push(mediaPath);
|
|
81993
|
+
}
|
|
81994
|
+
}
|
|
81995
|
+
return { target, parts };
|
|
81996
|
+
}
|
|
81946
81997
|
function extractPivotRoundTripInfo(originalZip) {
|
|
81947
81998
|
const empty = {
|
|
81948
81999
|
cachesByWorkbook: /* @__PURE__ */ new Map(),
|
|
@@ -82056,6 +82107,7 @@ function exportWorkbook(workbook, originalZip) {
|
|
|
82056
82107
|
regeneratedPaths.add("_rels/.rels");
|
|
82057
82108
|
regeneratedPaths.add("docProps/core.xml");
|
|
82058
82109
|
regeneratedPaths.add("docProps/app.xml");
|
|
82110
|
+
regeneratedPaths.add("xl/calcChain.xml");
|
|
82059
82111
|
for (let i2 = 0; i2 < workbook.sheets.length + 10; i2++) {
|
|
82060
82112
|
regeneratedPaths.add(`xl/worksheets/sheet${i2 + 1}.xml`);
|
|
82061
82113
|
regeneratedPaths.add(`xl/worksheets/_rels/sheet${i2 + 1}.xml.rels`);
|
|
@@ -82066,7 +82118,10 @@ function exportWorkbook(workbook, originalZip) {
|
|
|
82066
82118
|
}
|
|
82067
82119
|
}
|
|
82068
82120
|
for (const [path8, data] of Object.entries(originalZip)) {
|
|
82069
|
-
if (
|
|
82121
|
+
if (regeneratedPaths.has(path8)) continue;
|
|
82122
|
+
const ext = path8.slice(path8.lastIndexOf(".") + 1).toLowerCase();
|
|
82123
|
+
if (!DECLARED_EXTENSIONS.includes(ext)) continue;
|
|
82124
|
+
entries2[path8] = data;
|
|
82070
82125
|
}
|
|
82071
82126
|
}
|
|
82072
82127
|
const sharedStrings = buildSharedStrings(workbook);
|
|
@@ -82074,6 +82129,7 @@ function exportWorkbook(workbook, originalZip) {
|
|
|
82074
82129
|
const stylesResult = stylesPassthrough ? { xml: "", xfMap: /* @__PURE__ */ new Map(), numFmtMap: /* @__PURE__ */ new Map(), dxfMap: /* @__PURE__ */ new Map() } : buildStylesXml(workbook);
|
|
82075
82130
|
if (!stylesPassthrough) entries2["xl/styles.xml"] = strToU8(stylesResult.xml);
|
|
82076
82131
|
const roundTripInfo = extractPivotRoundTripInfo(originalZip);
|
|
82132
|
+
const sheetTargets = originalZip ? readWorkbookSheetOrder(originalZip).map((rid) => readWorkbookRels(originalZip).get(rid)?.target) : [];
|
|
82077
82133
|
const authoredStartIndex = roundTripInfo.pivotXmlPaths.filter((p) => p.startsWith("xl/pivotTables/")).length + 1;
|
|
82078
82134
|
const pivotInfo = mergePivotInfo(roundTripInfo, emitAuthoredPivots(workbook, entries2, authoredStartIndex));
|
|
82079
82135
|
entries2["xl/workbook.xml"] = strToU8(buildWorkbookXml(workbook, pivotInfo));
|
|
@@ -82106,6 +82162,15 @@ function exportWorkbook(workbook, originalZip) {
|
|
|
82106
82162
|
sheetRels.push(`<Relationship Id="${rId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="${escapeXml(url2)}" TargetMode="External"/>`);
|
|
82107
82163
|
}
|
|
82108
82164
|
}
|
|
82165
|
+
let legacyHFRId = "";
|
|
82166
|
+
if (originalZip) {
|
|
82167
|
+
const hf = extractLegacyHeaderFooterArt(originalZip, sheetTargets[i2]);
|
|
82168
|
+
if (hf) {
|
|
82169
|
+
legacyHFRId = `rId${nextRId++}`;
|
|
82170
|
+
sheetRels.push(`<Relationship Id="${legacyHFRId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing" Target="${escapeXml(hf.target)}"/>`);
|
|
82171
|
+
for (const part of hf.parts) entries2[part] = originalZip[part];
|
|
82172
|
+
}
|
|
82173
|
+
}
|
|
82109
82174
|
let drawingRId = "";
|
|
82110
82175
|
if (needsDrawing) {
|
|
82111
82176
|
drawingRId = `rId${nextRId++}`;
|
|
@@ -82124,7 +82189,8 @@ function exportWorkbook(workbook, originalZip) {
|
|
|
82124
82189
|
}
|
|
82125
82190
|
for (const image of sheet.images) {
|
|
82126
82191
|
const imgRId = `rId${drawingRelId++}`;
|
|
82127
|
-
const ext = getImageExtension(image.dataUrl);
|
|
82192
|
+
const ext = getImageExtension(image.dataUrl, image.ext);
|
|
82193
|
+
while (entries2[`xl/media/image${globalImageIndex}.${ext}`]) globalImageIndex++;
|
|
82128
82194
|
const imgPath = `xl/media/image${globalImageIndex}.${ext}`;
|
|
82129
82195
|
const imgBytes = dataUrlToBytes(image.dataUrl);
|
|
82130
82196
|
if (imgBytes) {
|
|
@@ -82183,7 +82249,7 @@ ${sheetRels.join("\n")}
|
|
|
82183
82249
|
);
|
|
82184
82250
|
}
|
|
82185
82251
|
entries2[`xl/worksheets/sheet${i2 + 1}.xml`] = strToU8(
|
|
82186
|
-
buildSheetXml(sheet, workbook.styles, sharedStrings.index, i2 === workbook.activeSheetIndex, stylesResult.xfMap, stylesResult.numFmtMap, stylesResult.dxfMap, drawingRId, tableRIds, hyperlinkRIds)
|
|
82252
|
+
buildSheetXml(sheet, workbook.styles, sharedStrings.index, i2 === workbook.activeSheetIndex, stylesResult.xfMap, stylesResult.numFmtMap, stylesResult.dxfMap, drawingRId, tableRIds, hyperlinkRIds, legacyHFRId)
|
|
82187
82253
|
);
|
|
82188
82254
|
}
|
|
82189
82255
|
entries2["docProps/core.xml"] = strToU8(buildCoreProps());
|
|
@@ -82518,7 +82584,7 @@ function extractFillColors(css) {
|
|
|
82518
82584
|
}
|
|
82519
82585
|
return { fg: void 0, bg: void 0 };
|
|
82520
82586
|
}
|
|
82521
|
-
function buildSheetXml(sheet, styles, ssIndex, isActive, xfMap, numFmtMap, dxfMap, drawingRId, tableRIds, hyperlinkRIds) {
|
|
82587
|
+
function buildSheetXml(sheet, styles, ssIndex, isActive, xfMap, numFmtMap, dxfMap, drawingRId, tableRIds, hyperlinkRIds, legacyHFRId) {
|
|
82522
82588
|
const rows = [];
|
|
82523
82589
|
const rowMap = /* @__PURE__ */ new Map();
|
|
82524
82590
|
for (const [ref, cell] of sheet.cells) {
|
|
@@ -82568,10 +82634,22 @@ function buildSheetXml(sheet, styles, ssIndex, isActive, xfMap, numFmtMap, dxfMa
|
|
|
82568
82634
|
}
|
|
82569
82635
|
const cols = [];
|
|
82570
82636
|
const allCols = /* @__PURE__ */ new Set([...sheet.colWidths.keys(), ...sheet.hiddenCols]);
|
|
82571
|
-
|
|
82637
|
+
const sortedCols = Array.from(allCols).sort((a, b) => a - b);
|
|
82638
|
+
const colDef = (c) => {
|
|
82572
82639
|
const w = sheet.colWidths.get(c) ?? sheet.defaultColWidth;
|
|
82573
82640
|
const hidden = sheet.hiddenCols.has(c) ? ' hidden="1"' : "";
|
|
82574
|
-
|
|
82641
|
+
return `width="${w}" customWidth="1"${hidden}`;
|
|
82642
|
+
};
|
|
82643
|
+
for (let i2 = 0; i2 < sortedCols.length; ) {
|
|
82644
|
+
const start = sortedCols[i2];
|
|
82645
|
+
const def = colDef(start);
|
|
82646
|
+
let end = start;
|
|
82647
|
+
while (i2 + 1 < sortedCols.length && sortedCols[i2 + 1] === end + 1 && colDef(sortedCols[i2 + 1]) === def) {
|
|
82648
|
+
end = sortedCols[i2 + 1];
|
|
82649
|
+
i2++;
|
|
82650
|
+
}
|
|
82651
|
+
cols.push(`<col min="${start}" max="${end}" ${def}/>`);
|
|
82652
|
+
i2++;
|
|
82575
82653
|
}
|
|
82576
82654
|
let mergeXml = "";
|
|
82577
82655
|
if (sheet.mergedCells.length > 0) {
|
|
@@ -82627,6 +82705,7 @@ function buildSheetXml(sheet, styles, ssIndex, isActive, xfMap, numFmtMap, dxfMa
|
|
|
82627
82705
|
hyperlinksXml = `<hyperlinks>${hlEntries}</hyperlinks>`;
|
|
82628
82706
|
}
|
|
82629
82707
|
const drawingXml = drawingRId ? `<drawing r:id="${drawingRId}"/>` : "";
|
|
82708
|
+
const legacyHFXml = legacyHFRId ? `<legacyDrawingHF r:id="${legacyHFRId}"/>` : "";
|
|
82630
82709
|
let tablePartsXml = "";
|
|
82631
82710
|
if (tableRIds && tableRIds.length > 0) {
|
|
82632
82711
|
const parts = tableRIds.map((rId) => `<tablePart r:id="${rId}"/>`).join("");
|
|
@@ -82697,7 +82776,7 @@ ${cols.length > 0 ? `<cols>${cols.join("")}</cols>` : ""}
|
|
|
82697
82776
|
<sheetData>
|
|
82698
82777
|
${rows.join("\n")}
|
|
82699
82778
|
</sheetData>
|
|
82700
|
-
${autoFilterXml}${mergeXml}${cfXml}${dvXml}${hyperlinksXml}${marginsXml}${pageSetupXml}${headerFooterXml}${drawingXml}${tablePartsXml}
|
|
82779
|
+
${autoFilterXml}${mergeXml}${cfXml}${dvXml}${hyperlinksXml}${marginsXml}${pageSetupXml}${headerFooterXml}${drawingXml}${legacyHFXml}${tablePartsXml}
|
|
82701
82780
|
</worksheet>`;
|
|
82702
82781
|
}
|
|
82703
82782
|
function getCellType(cell, ssIndex) {
|
|
@@ -82794,19 +82873,30 @@ function buildWorkbookRels(workbook, pivotInfo) {
|
|
|
82794
82873
|
${rels.join("\n")}
|
|
82795
82874
|
</Relationships>`;
|
|
82796
82875
|
}
|
|
82876
|
+
var DECLARED_EXTENSIONS = ["rels", "xml", "png", "jpeg", "jpg", "gif", "vml", "emf", "wmf", "bmp", "tiff", "tif", "svg"];
|
|
82797
82877
|
function buildContentTypes(sheetCount, extraTypes = []) {
|
|
82878
|
+
const DEFAULT_CONTENT_TYPES = [
|
|
82879
|
+
`<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>`,
|
|
82880
|
+
`<Default Extension="xml" ContentType="application/xml"/>`,
|
|
82881
|
+
`<Default Extension="png" ContentType="image/png"/>`,
|
|
82882
|
+
`<Default Extension="jpeg" ContentType="image/jpeg"/>`,
|
|
82883
|
+
`<Default Extension="jpg" ContentType="image/jpeg"/>`,
|
|
82884
|
+
`<Default Extension="gif" ContentType="image/gif"/>`,
|
|
82885
|
+
`<Default Extension="vml" ContentType="application/vnd.openxmlformats-officedocument.vmlDrawing"/>`,
|
|
82886
|
+
`<Default Extension="emf" ContentType="image/x-emf"/>`,
|
|
82887
|
+
`<Default Extension="wmf" ContentType="image/x-wmf"/>`,
|
|
82888
|
+
`<Default Extension="bmp" ContentType="image/bmp"/>`,
|
|
82889
|
+
`<Default Extension="tiff" ContentType="image/tiff"/>`,
|
|
82890
|
+
`<Default Extension="tif" ContentType="image/tiff"/>`,
|
|
82891
|
+
`<Default Extension="svg" ContentType="image/svg+xml"/>`
|
|
82892
|
+
].join("\n");
|
|
82798
82893
|
const sheetTypes = Array.from(
|
|
82799
82894
|
{ length: sheetCount },
|
|
82800
82895
|
(_, i2) => `<Override PartName="/xl/worksheets/sheet${i2 + 1}.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>`
|
|
82801
82896
|
).join("\n");
|
|
82802
82897
|
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
82803
82898
|
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
|
|
82804
|
-
|
|
82805
|
-
<Default Extension="xml" ContentType="application/xml"/>
|
|
82806
|
-
<Default Extension="png" ContentType="image/png"/>
|
|
82807
|
-
<Default Extension="jpeg" ContentType="image/jpeg"/>
|
|
82808
|
-
<Default Extension="jpg" ContentType="image/jpeg"/>
|
|
82809
|
-
<Default Extension="gif" ContentType="image/gif"/>
|
|
82899
|
+
${DEFAULT_CONTENT_TYPES}
|
|
82810
82900
|
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
|
|
82811
82901
|
${sheetTypes}
|
|
82812
82902
|
<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
|
|
@@ -82981,15 +83071,37 @@ function buildChartAnchorXml(chart, rId) {
|
|
|
82981
83071
|
</xdr:twoCellAnchor>`;
|
|
82982
83072
|
}
|
|
82983
83073
|
function buildImageAnchorXml(image, rId) {
|
|
82984
|
-
|
|
82985
|
-
<xdr:from>${buildAnchorPosition(image.tl)}</xdr:from>
|
|
82986
|
-
<xdr:to>${buildAnchorPosition(image.br)}</xdr:to>
|
|
82987
|
-
<xdr:pic>
|
|
83074
|
+
const pic = `<xdr:pic>
|
|
82988
83075
|
<xdr:nvPicPr><xdr:cNvPr id="0" name="Image"/><xdr:cNvPicPr/></xdr:nvPicPr>
|
|
82989
83076
|
<xdr:blipFill><a:blip xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:embed="${rId}"/><a:stretch><a:fillRect/></a:stretch></xdr:blipFill>
|
|
82990
83077
|
<xdr:spPr><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></xdr:spPr>
|
|
82991
83078
|
</xdr:pic>
|
|
82992
|
-
<xdr:clientData
|
|
83079
|
+
<xdr:clientData/>`;
|
|
83080
|
+
const from = `<xdr:from>${buildAnchorPosition({ row: image.tl.row, col: image.tl.col, rowOffset: image.tl.rowOff, colOffset: image.tl.colOff })}</xdr:from>`;
|
|
83081
|
+
if (image.anchorKind === "oneCell" && image.extent) {
|
|
83082
|
+
return `<xdr:oneCellAnchor>
|
|
83083
|
+
${from}
|
|
83084
|
+
<xdr:ext cx="${image.extent.cx}" cy="${image.extent.cy}"/>
|
|
83085
|
+
${pic}
|
|
83086
|
+
</xdr:oneCellAnchor>`;
|
|
83087
|
+
}
|
|
83088
|
+
if (image.anchorKind === "absolute" && image.extent && image.pos) {
|
|
83089
|
+
return `<xdr:absoluteAnchor>
|
|
83090
|
+
<xdr:pos x="${image.pos.x}" y="${image.pos.y}"/>
|
|
83091
|
+
<xdr:ext cx="${image.extent.cx}" cy="${image.extent.cy}"/>
|
|
83092
|
+
${pic}
|
|
83093
|
+
</xdr:absoluteAnchor>`;
|
|
83094
|
+
}
|
|
83095
|
+
const to = {
|
|
83096
|
+
row: Math.max(image.tl.row, image.br.row - 1),
|
|
83097
|
+
col: Math.max(image.tl.col, image.br.col - 1),
|
|
83098
|
+
rowOffset: image.br.rowOff,
|
|
83099
|
+
colOffset: image.br.colOff
|
|
83100
|
+
};
|
|
83101
|
+
return `<xdr:twoCellAnchor editAs="oneCell">
|
|
83102
|
+
${from}
|
|
83103
|
+
<xdr:to>${buildAnchorPosition(to)}</xdr:to>
|
|
83104
|
+
${pic}
|
|
82993
83105
|
</xdr:twoCellAnchor>`;
|
|
82994
83106
|
}
|
|
82995
83107
|
function buildShapeAnchorXml(drawing) {
|
|
@@ -83088,10 +83200,16 @@ function buildDxfXml(style) {
|
|
|
83088
83200
|
}
|
|
83089
83201
|
return `<dxf>${inner}</dxf>`;
|
|
83090
83202
|
}
|
|
83091
|
-
function getImageExtension(dataUrl) {
|
|
83203
|
+
function getImageExtension(dataUrl, sourceExt) {
|
|
83204
|
+
if (sourceExt) return sourceExt.toLowerCase();
|
|
83092
83205
|
if (dataUrl.startsWith("data:image/png")) return "png";
|
|
83093
83206
|
if (dataUrl.startsWith("data:image/jpeg") || dataUrl.startsWith("data:image/jpg")) return "jpeg";
|
|
83094
83207
|
if (dataUrl.startsWith("data:image/gif")) return "gif";
|
|
83208
|
+
if (dataUrl.startsWith("data:image/x-emf")) return "emf";
|
|
83209
|
+
if (dataUrl.startsWith("data:image/x-wmf")) return "wmf";
|
|
83210
|
+
if (dataUrl.startsWith("data:image/bmp")) return "bmp";
|
|
83211
|
+
if (dataUrl.startsWith("data:image/tiff")) return "tiff";
|
|
83212
|
+
if (dataUrl.startsWith("data:image/svg+xml")) return "svg";
|
|
83095
83213
|
return "png";
|
|
83096
83214
|
}
|
|
83097
83215
|
function dataUrlToBytes(dataUrl) {
|
|
@@ -83306,6 +83424,46 @@ var SheetModel = class {
|
|
|
83306
83424
|
if (!rc) throw new Error(`Invalid cell reference: ${topLeftRef}`);
|
|
83307
83425
|
this.freeze = { row: rc.row - 1, col: rc.col - 1 };
|
|
83308
83426
|
}
|
|
83427
|
+
/**
|
|
83428
|
+
* Place a picture on the sheet, anchored to a cell range.
|
|
83429
|
+
*
|
|
83430
|
+
* The authoring counterpart to the parser: without it, adding an image meant
|
|
83431
|
+
* hand-constructing a ParsedImage (0-based anchors, an EXCLUSIVE `br`, a
|
|
83432
|
+
* dataUrl, an anchor kind) — enough hidden convention that every caller would
|
|
83433
|
+
* get one of them wrong. It lives on the model rather than in a tool so that
|
|
83434
|
+
* every surface reaches it: a sandbox code run, a workflow tool, the editor.
|
|
83435
|
+
*
|
|
83436
|
+
* `range` is an ordinary A1 range ("B3:F11"); a single ref ("B3") anchors a
|
|
83437
|
+
* one-cell box. The picture resizes with its cells (twoCell), which is what a
|
|
83438
|
+
* logo in a letterhead should do.
|
|
83439
|
+
*
|
|
83440
|
+
* @param dataUrl `data:image/png;base64,…` — the bytes to embed.
|
|
83441
|
+
* @param range Where it sits, e.g. "B3:F11".
|
|
83442
|
+
*/
|
|
83443
|
+
addImage(dataUrl, range2) {
|
|
83444
|
+
const mime = /^data:([^;,]+)[;,]/.exec(dataUrl)?.[1];
|
|
83445
|
+
if (!mime) throw new Error("addImage expects a data: URL, e.g. data:image/png;base64,\u2026");
|
|
83446
|
+
if (!isSupportedMediaMime(mime)) {
|
|
83447
|
+
throw new Error(`addImage cannot embed ${mime} \u2014 xl/media holds png, jpeg, gif, bmp, tiff, svg, emf or wmf`);
|
|
83448
|
+
}
|
|
83449
|
+
const [startRef, endRef] = range2.split(":");
|
|
83450
|
+
const start = refToRowCol(startRef ?? "");
|
|
83451
|
+
const end = endRef ? refToRowCol(endRef) : start;
|
|
83452
|
+
if (!start || !end) throw new Error(`Invalid cell range: ${range2}`);
|
|
83453
|
+
const image = {
|
|
83454
|
+
dataUrl,
|
|
83455
|
+
// refToRowCol is 1-based; anchors are 0-based, and `br` is EXCLUSIVE — one
|
|
83456
|
+
// past the last covered cell — so the end ref converts straight across
|
|
83457
|
+
// while the start ref loses one.
|
|
83458
|
+
// rowOff/colOff are pinned to 0 (not left undefined) so an authored image
|
|
83459
|
+
// is structurally identical to a parsed one — every reader handles one shape.
|
|
83460
|
+
tl: { row: Math.min(start.row, end.row) - 1, col: Math.min(start.col, end.col) - 1, rowOff: 0, colOff: 0 },
|
|
83461
|
+
br: { row: Math.max(start.row, end.row), col: Math.max(start.col, end.col), rowOff: 0, colOff: 0 },
|
|
83462
|
+
anchorKind: "twoCell"
|
|
83463
|
+
};
|
|
83464
|
+
this.images.push(image);
|
|
83465
|
+
return image;
|
|
83466
|
+
}
|
|
83309
83467
|
/** Get cell, returning undefined for empty cells. */
|
|
83310
83468
|
getCell(ref) {
|
|
83311
83469
|
return this.cells.get(ref);
|
|
@@ -91373,8 +91531,20 @@ var SOURCE_LABELS = {
|
|
|
91373
91531
|
local_pointer: "local .lotics/config.json (pin)",
|
|
91374
91532
|
global_profile: "global active profile"
|
|
91375
91533
|
};
|
|
91534
|
+
function announceTarget(ctx, workspaceId) {
|
|
91535
|
+
const org = ctx.orgName ?? ctx.orgId ?? "(org from key)";
|
|
91536
|
+
if (ctx.source === "global_profile") {
|
|
91537
|
+
console.error(
|
|
91538
|
+
`lotics \u2192 ${org} / ${workspaceId} [globally-active org \u2014 no directory pin, no LOTICS_ORG]`
|
|
91539
|
+
);
|
|
91540
|
+
console.error(` pin this directory: lotics org use ${JSON.stringify(org)} --local`);
|
|
91541
|
+
return;
|
|
91542
|
+
}
|
|
91543
|
+
console.error(`lotics \u2192 ${org} / ${workspaceId}`);
|
|
91544
|
+
}
|
|
91376
91545
|
async function resolveWorkspace(client, ctx) {
|
|
91377
91546
|
if (ctx.workspaceId) {
|
|
91547
|
+
announceTarget(ctx, ctx.workspaceId);
|
|
91378
91548
|
client.setWorkspaceId(ctx.workspaceId);
|
|
91379
91549
|
return;
|
|
91380
91550
|
}
|
|
@@ -91391,7 +91561,8 @@ async function resolveWorkspace(client, ctx) {
|
|
|
91391
91561
|
process.exit(1);
|
|
91392
91562
|
}
|
|
91393
91563
|
if (workspaces.length === 1) {
|
|
91394
|
-
setSelectedWorkspace(workspaces[0].id);
|
|
91564
|
+
setSelectedWorkspace(workspaces[0].id, ctx.orgId);
|
|
91565
|
+
announceTarget(ctx, workspaces[0].id);
|
|
91395
91566
|
client.setWorkspaceId(workspaces[0].id);
|
|
91396
91567
|
return;
|
|
91397
91568
|
}
|
|
@@ -91716,7 +91887,7 @@ Available workspaces:`);
|
|
|
91716
91887
|
printWorkspaceList(workspaces, currentWorkspaceId);
|
|
91717
91888
|
process.exit(1);
|
|
91718
91889
|
}
|
|
91719
|
-
const written = setSelectedWorkspace(target.id);
|
|
91890
|
+
const written = setSelectedWorkspace(target.id, ctx.orgId);
|
|
91720
91891
|
if (!written) {
|
|
91721
91892
|
console.error(`Switched to ${target.name} (${target.id}) for this command, but it could not be saved \u2014 credentials came from --api-key/LOTICS_API_KEY with no saved profile. Run "lotics auth api-key <key>" to persist a default.`);
|
|
91722
91893
|
return;
|
|
@@ -91733,7 +91904,7 @@ Available workspaces:`);
|
|
|
91733
91904
|
}
|
|
91734
91905
|
const timezone = flags.timezone;
|
|
91735
91906
|
const created = await client.createWorkspace({ name, timezone });
|
|
91736
|
-
setSelectedWorkspace(created.id);
|
|
91907
|
+
setSelectedWorkspace(created.id, ctx.orgId);
|
|
91737
91908
|
client.setWorkspaceId(created.id);
|
|
91738
91909
|
if (flags.json) {
|
|
91739
91910
|
console.log(JSON.stringify(created, null, 2));
|