@taloswork/ose-shared 0.1.2 → 0.1.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/package.json +3 -3
- package/skills/document/SKILL.md +29 -33
- package/skills/document/assets/fonts/Archivo-Regular.woff2 +0 -0
- package/skills/document/assets/fonts/Archivo-SemiBold.woff2 +0 -0
- package/skills/document/assets/fonts/BigShouldersDisplay-Bold.woff2 +0 -0
- package/skills/document/assets/fonts/BodoniModa-SemiBold.woff2 +0 -0
- package/skills/document/assets/fonts/CormorantGaramond-SemiBold.woff2 +0 -0
- package/skills/document/assets/fonts/Fraunces-SemiBold.woff2 +0 -0
- package/skills/document/assets/fonts/GochiHand-Regular.woff2 +0 -0
- package/skills/document/assets/fonts/IBMPlexSans-Regular.woff2 +0 -0
- package/skills/document/assets/fonts/IBMPlexSans-SemiBold.woff2 +0 -0
- package/skills/document/assets/fonts/Inter-Regular.woff2 +0 -0
- package/skills/document/assets/fonts/Jost-Regular.woff2 +0 -0
- package/skills/document/assets/fonts/Jost-SemiBold.woff2 +0 -0
- package/skills/document/assets/fonts/Karla-Regular.woff2 +0 -0
- package/skills/document/assets/fonts/Lora-Regular.woff2 +0 -0
- package/skills/document/assets/fonts/Manrope-Bold.woff2 +0 -0
- package/skills/document/assets/fonts/Manrope-Regular.woff2 +0 -0
- package/skills/document/assets/fonts/Marcellus-Regular.woff2 +0 -0
- package/skills/document/assets/fonts/PublicSans-Regular.woff2 +0 -0
- package/skills/document/assets/fonts/Sora-Regular.woff2 +0 -0
- package/skills/document/assets/fonts/Sora-SemiBold.woff2 +0 -0
- package/skills/document/assets/fonts/fonts.json +218 -0
- package/skills/document/bin/deck-build.cjs +273 -5
- package/skills/document/bin/doc-gen.cjs +108 -23
- package/skills/document/bin/html2pptx.cjs +280 -49
- package/skills/document/catalog.json +25 -0
- package/skills/document/deck-design.md +191 -0
- package/skills/document/layouts/README.md +32 -0
- package/skills/document/layouts/banner-columns.tpl +9 -9
- package/skills/document/layouts/bento.tpl +3 -3
- package/skills/document/layouts/big-stat.tpl +3 -3
- package/skills/document/layouts/blocks-2x2.tpl +12 -12
- package/skills/document/layouts/brand-values.tpl +5 -5
- package/skills/document/layouts/cards-3.tpl +3 -3
- package/skills/document/layouts/cards-grid.tpl +3 -3
- package/skills/document/layouts/chart-full.tpl +3 -3
- package/skills/document/layouts/chart-kpi.tpl +3 -3
- package/skills/document/layouts/color-palette.tpl +5 -5
- package/skills/document/layouts/comparison.tpl +3 -3
- package/skills/document/layouts/concept-hub.tpl +3 -3
- package/skills/document/layouts/cover-centered.tpl +1 -1
- package/skills/document/layouts/cover-image.tpl +1 -1
- package/skills/document/layouts/cover-minimal.tpl +3 -3
- package/skills/document/layouts/cover-statement.tpl +3 -3
- package/skills/document/layouts/cover.tpl +1 -1
- package/skills/document/layouts/data-table.tpl +3 -3
- package/skills/document/layouts/dos-donts.tpl +14 -14
- package/skills/document/layouts/editorial-panel.tpl +11 -11
- package/skills/document/layouts/ending-contact.tpl +1 -1
- package/skills/document/layouts/ending.tpl +1 -1
- package/skills/document/layouts/funnel.tpl +3 -3
- package/skills/document/layouts/gantt.tpl +3 -3
- package/skills/document/layouts/hero.tpl +3 -3
- package/skills/document/layouts/icon-row.tpl +3 -3
- package/skills/document/layouts/image-full.tpl +5 -5
- package/skills/document/layouts/image-grid.tpl +3 -3
- package/skills/document/layouts/image-left.tpl +3 -3
- package/skills/document/layouts/list.tpl +3 -3
- package/skills/document/layouts/logo-guidelines.tpl +8 -8
- package/skills/document/layouts/map-distribution.tpl +3 -3
- package/skills/document/layouts/map-quad.tpl +6 -6
- package/skills/document/layouts/matrix-2x2.tpl +3 -3
- package/skills/document/layouts/numbered-brief.tpl +12 -12
- package/skills/document/layouts/org-tree.tpl +3 -3
- package/skills/document/layouts/problem-solution-banner.tpl +7 -7
- package/skills/document/layouts/problem-solution.tpl +3 -3
- package/skills/document/layouts/pyramid.tpl +3 -3
- package/skills/document/layouts/quote.tpl +1 -1
- package/skills/document/layouts/radar.tpl +3 -3
- package/skills/document/layouts/ring-progress.tpl +3 -3
- package/skills/document/layouts/section-fullbleed.tpl +3 -3
- package/skills/document/layouts/section-image.tpl +1 -1
- package/skills/document/layouts/section-stat.tpl +1 -1
- package/skills/document/layouts/section.tpl +1 -1
- package/skills/document/layouts/slots.json +1 -1
- package/skills/document/layouts/split-two-col.tpl +3 -3
- package/skills/document/layouts/stats-chart.tpl +3 -3
- package/skills/document/layouts/steps-serpentine.tpl +11 -11
- package/skills/document/layouts/steps-vertical.tpl +3 -3
- package/skills/document/layouts/steps.tpl +3 -3
- package/skills/document/layouts/team-row.tpl +4 -4
- package/skills/document/layouts/three-kpi.tpl +3 -3
- package/skills/document/layouts/timeline.tpl +3 -3
- package/skills/document/layouts/title-meta.tpl +5 -5
- package/skills/document/layouts/title.tpl +2 -2
- package/skills/document/layouts/toc-agenda.tpl +3 -3
- package/skills/document/layouts/toc-editorial.tpl +15 -0
- package/skills/document/layouts/toc-panel.tpl +4 -4
- package/skills/document/layouts/toc.tpl +3 -3
- package/skills/document/layouts/transition.tpl +1 -1
- package/skills/document/layouts/two-kpi.tpl +3 -3
- package/skills/document/layouts/type-specimen.tpl +10 -10
- package/skills/document/layouts/versus.tpl +3 -3
- package/skills/document/motion/README.md +11 -0
- package/skills/document/packs/README.md +9 -0
- package/skills/document/styles/README.md +36 -15
- package/skills/document/styles/_contract-defaults.css +55 -0
- package/skills/document/styles/_samples/_groups/biz-premium.webp +0 -0
- package/skills/document/styles/_samples/_groups/creative.webp +0 -0
- package/skills/document/styles/_samples/_groups/editorial.webp +0 -0
- package/skills/document/styles/_samples/_groups/minimal.webp +0 -0
- package/skills/document/styles/_samples/_groups/natural.webp +0 -0
- package/skills/document/styles/_samples/_groups/tech-future.webp +0 -0
- package/skills/document/styles/_samples/anthropic.webp +0 -0
- package/skills/document/styles/_samples/apple.webp +0 -0
- package/skills/document/styles/_samples/black-gold.webp +0 -0
- package/skills/document/styles/_samples/branding.webp +0 -0
- package/skills/document/styles/_samples/cinereel.webp +0 -0
- package/skills/document/styles/_samples/cool.webp +0 -0
- package/skills/document/styles/_samples/hand-drawn.webp +0 -0
- package/skills/document/styles/_samples/ivory-gold.webp +0 -0
- package/skills/document/styles/_samples/magazine-ink.webp +0 -0
- package/skills/document/styles/_samples/mckinsey.webp +0 -0
- package/skills/document/styles/_samples/mono.webp +0 -0
- package/skills/document/styles/_samples/olive-gold.webp +0 -0
- package/skills/document/styles/_samples/swiss-grid.webp +0 -0
- package/skills/document/styles/anthropic/backdrop.html +4 -0
- package/skills/document/styles/anthropic/skin.css +15 -8
- package/skills/document/styles/apple/backdrop.html +4 -1
- package/skills/document/styles/apple/skin.css +5 -2
- package/skills/document/styles/black-gold/backdrop.html +3 -0
- package/skills/document/styles/black-gold/skin.css +15 -8
- package/skills/document/styles/branding/backdrop.html +4 -0
- package/skills/document/styles/branding/skin.css +14 -7
- package/skills/document/styles/cinereel/skin.css +28 -10
- package/skills/document/styles/cool/backdrop.html +3 -0
- package/skills/document/styles/cool/skin.css +5 -2
- package/skills/document/styles/hand-drawn/skin.css +14 -6
- package/skills/document/styles/ivory-gold/skin.css +19 -6
- package/skills/document/styles/magazine-ink/skin.css +6 -1
- package/skills/document/styles/mckinsey/backdrop.html +5 -0
- package/skills/document/styles/mckinsey/skin.css +5 -2
- package/skills/document/styles/mono/backdrop.html +6 -0
- package/skills/document/styles/mono/skin.css +5 -2
- package/skills/document/styles/olive-gold/backdrop.html +5 -0
- package/skills/document/styles/olive-gold/skin.css +15 -8
- package/skills/document/styles/swiss-grid/skin.css +6 -1
|
@@ -287,6 +287,214 @@ function assembleDeck(spec, readLayout) {
|
|
|
287
287
|
return { html: sections.join("\n"), warnings: problems.warnings, errors: problems.errors };
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
+
// packages/core/dist/document/deck-catalog.js
|
|
291
|
+
var KINDS = ["skin", "pack"];
|
|
292
|
+
var MODES = ["light", "dark"];
|
|
293
|
+
var ID_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
294
|
+
function isStr(v) {
|
|
295
|
+
return typeof v === "string" && v.length > 0;
|
|
296
|
+
}
|
|
297
|
+
function isStrArr(v) {
|
|
298
|
+
return Array.isArray(v) && v.every((x) => typeof x === "string");
|
|
299
|
+
}
|
|
300
|
+
function parseCatalog(raw) {
|
|
301
|
+
const errors = [];
|
|
302
|
+
const o = raw;
|
|
303
|
+
if (!o || typeof o !== "object")
|
|
304
|
+
return { catalog: null, errors: ["catalog is not an object"] };
|
|
305
|
+
const groups = [];
|
|
306
|
+
const rawGroups = Array.isArray(o.groups) ? o.groups : [];
|
|
307
|
+
if (!Array.isArray(o.groups))
|
|
308
|
+
errors.push("catalog.groups must be an array");
|
|
309
|
+
rawGroups.forEach((g, i) => {
|
|
310
|
+
const at = `group[${i}]`;
|
|
311
|
+
if (!isStr(g?.id) || !ID_RE.test(g.id))
|
|
312
|
+
errors.push(`${at}: bad id`);
|
|
313
|
+
if (!isStr(g?.name_cn))
|
|
314
|
+
errors.push(`${at}: missing name_cn`);
|
|
315
|
+
if (!isStr(g?.sample))
|
|
316
|
+
errors.push(`${at}: missing sample`);
|
|
317
|
+
if (!isStrArr(g?.scenarios))
|
|
318
|
+
errors.push(`${at}: scenarios must be a string array`);
|
|
319
|
+
if (isStr(g?.id) && isStr(g?.name_cn) && isStr(g?.sample) && isStrArr(g?.scenarios)) {
|
|
320
|
+
groups.push({ id: g.id, name_cn: g.name_cn, sample: g.sample, scenarios: g.scenarios });
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
const entries = [];
|
|
324
|
+
const rawEntries = Array.isArray(o.entries) ? o.entries : [];
|
|
325
|
+
if (!Array.isArray(o.entries))
|
|
326
|
+
errors.push("catalog.entries must be an array");
|
|
327
|
+
rawEntries.forEach((e, i) => {
|
|
328
|
+
const at = `entry[${i}]${isStr(e?.id) ? ` (${e.id})` : ""}`;
|
|
329
|
+
const before = errors.length;
|
|
330
|
+
if (!isStr(e?.id) || !ID_RE.test(e.id))
|
|
331
|
+
errors.push(`${at}: bad id`);
|
|
332
|
+
if (!isStr(e?.kind) || !KINDS.includes(e.kind))
|
|
333
|
+
errors.push(`${at}: kind must be "skin" or "pack"`);
|
|
334
|
+
if (!isStr(e?.group))
|
|
335
|
+
errors.push(`${at}: missing group`);
|
|
336
|
+
if (!isStr(e?.name_cn))
|
|
337
|
+
errors.push(`${at}: missing name_cn`);
|
|
338
|
+
if (!isStr(e?.oneliner))
|
|
339
|
+
errors.push(`${at}: missing oneliner`);
|
|
340
|
+
if (!isStrArr(e?.scenarios))
|
|
341
|
+
errors.push(`${at}: scenarios must be a string array`);
|
|
342
|
+
if (!isStr(e?.mode) || !MODES.includes(e.mode))
|
|
343
|
+
errors.push(`${at}: mode must be "light" or "dark"`);
|
|
344
|
+
if (!isStr(e?.sample))
|
|
345
|
+
errors.push(`${at}: missing sample`);
|
|
346
|
+
if (e?.motion !== void 0 && !isStr(e.motion))
|
|
347
|
+
errors.push(`${at}: motion must be a string when present`);
|
|
348
|
+
if (errors.length === before) {
|
|
349
|
+
entries.push({
|
|
350
|
+
id: e.id,
|
|
351
|
+
kind: e.kind,
|
|
352
|
+
group: e.group,
|
|
353
|
+
name_cn: e.name_cn,
|
|
354
|
+
oneliner: e.oneliner,
|
|
355
|
+
scenarios: e.scenarios,
|
|
356
|
+
mode: e.mode,
|
|
357
|
+
sample: e.sample,
|
|
358
|
+
...e.motion !== void 0 ? { motion: e.motion } : {}
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
return { catalog: errors.length ? null : { groups, entries }, errors };
|
|
363
|
+
}
|
|
364
|
+
function resolveEntry(catalog, id) {
|
|
365
|
+
return catalog.entries.find((e) => e.id === id) ?? null;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// packages/core/dist/document/deck-motion.js
|
|
369
|
+
var ANIM_EFFECTS = [
|
|
370
|
+
"fade",
|
|
371
|
+
"fade-up",
|
|
372
|
+
"float",
|
|
373
|
+
"appear",
|
|
374
|
+
"fly-up",
|
|
375
|
+
"fly-down",
|
|
376
|
+
"fly-left",
|
|
377
|
+
"fly-right"
|
|
378
|
+
];
|
|
379
|
+
var START_MODES = ["after", "with", "onclick"];
|
|
380
|
+
var SEL_RE = /^\.[a-z][a-z0-9-]*$/;
|
|
381
|
+
function validateMotionPreset(raw) {
|
|
382
|
+
const errors = [];
|
|
383
|
+
const p = raw;
|
|
384
|
+
if (!p || typeof p !== "object")
|
|
385
|
+
return ["motion preset is not an object"];
|
|
386
|
+
if (p.transition !== void 0) {
|
|
387
|
+
const t = p.transition;
|
|
388
|
+
if (!t || typeof t.effect !== "string" || !t.effect)
|
|
389
|
+
errors.push("transition.effect must be a non-empty string");
|
|
390
|
+
if (t?.durMs !== void 0 && typeof t.durMs !== "number")
|
|
391
|
+
errors.push("transition.durMs must be a number");
|
|
392
|
+
if (t?.dir !== void 0 && typeof t.dir !== "string")
|
|
393
|
+
errors.push("transition.dir must be a string");
|
|
394
|
+
}
|
|
395
|
+
if (p.entrance !== void 0) {
|
|
396
|
+
if (typeof p.entrance !== "object" || p.entrance === null) {
|
|
397
|
+
errors.push("entrance must be an object keyed by role");
|
|
398
|
+
} else {
|
|
399
|
+
for (const [role, steps] of Object.entries(p.entrance)) {
|
|
400
|
+
if (!Array.isArray(steps)) {
|
|
401
|
+
errors.push(`entrance.${role} must be an array`);
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
404
|
+
steps.forEach((s, i) => {
|
|
405
|
+
const at = `entrance.${role}[${i}]`;
|
|
406
|
+
if (typeof s?.sel !== "string" || !SEL_RE.test(s.sel))
|
|
407
|
+
errors.push(`${at}: sel must be a single class selector like ".card"`);
|
|
408
|
+
if (typeof s?.anim !== "string" || !ANIM_EFFECTS.includes(s.anim)) {
|
|
409
|
+
errors.push(`${at}: anim "${String(s?.anim)}" is not implemented by pptx-anim.ts`);
|
|
410
|
+
}
|
|
411
|
+
for (const k of ["delay", "dur", "stagger"]) {
|
|
412
|
+
if (s?.[k] !== void 0 && typeof s[k] !== "number")
|
|
413
|
+
errors.push(`${at}: ${k} must be a number`);
|
|
414
|
+
}
|
|
415
|
+
if (s?.start !== void 0 && !START_MODES.includes(s.start))
|
|
416
|
+
errors.push(`${at}: start must be one of ${START_MODES.join("/")}`);
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return errors;
|
|
422
|
+
}
|
|
423
|
+
var ROLE_OVERRIDES = {
|
|
424
|
+
transition: "section",
|
|
425
|
+
hero: "cover",
|
|
426
|
+
title: "cover",
|
|
427
|
+
"title-meta": "cover",
|
|
428
|
+
quote: "content",
|
|
429
|
+
bento: "cards",
|
|
430
|
+
list: "cards",
|
|
431
|
+
"icon-row": "cards",
|
|
432
|
+
"cards-grid": "cards",
|
|
433
|
+
"blocks-2x2": "cards",
|
|
434
|
+
"chart-kpi": "stat",
|
|
435
|
+
"two-kpi": "stat",
|
|
436
|
+
"three-kpi": "stat",
|
|
437
|
+
"big-stat": "stat",
|
|
438
|
+
"stats-chart": "stat"
|
|
439
|
+
};
|
|
440
|
+
function roleOfLayout(layoutId) {
|
|
441
|
+
if (ROLE_OVERRIDES[layoutId])
|
|
442
|
+
return ROLE_OVERRIDES[layoutId];
|
|
443
|
+
if (layoutId.startsWith("cover"))
|
|
444
|
+
return "cover";
|
|
445
|
+
if (layoutId.startsWith("toc"))
|
|
446
|
+
return "toc";
|
|
447
|
+
if (layoutId.startsWith("section"))
|
|
448
|
+
return "section";
|
|
449
|
+
if (layoutId.startsWith("ending"))
|
|
450
|
+
return "ending";
|
|
451
|
+
if (layoutId.startsWith("cards"))
|
|
452
|
+
return "cards";
|
|
453
|
+
return "content";
|
|
454
|
+
}
|
|
455
|
+
var num2 = (v) => typeof v === "number" && Number.isFinite(v) ? String(Math.round(v)) : null;
|
|
456
|
+
function addAttrs(tag, attrs) {
|
|
457
|
+
if (/\bdata-anim=/.test(tag))
|
|
458
|
+
return tag;
|
|
459
|
+
const extra = Object.entries(attrs).filter(([, v]) => v !== null).map(([k, v]) => ` ${k}="${v}"`).join("");
|
|
460
|
+
return tag.replace(/\s*\/?>$/, (end) => extra + end);
|
|
461
|
+
}
|
|
462
|
+
function applyMotion(html, layoutId, preset) {
|
|
463
|
+
let out = html;
|
|
464
|
+
const role = roleOfLayout(layoutId);
|
|
465
|
+
const steps = preset.entrance?.[role];
|
|
466
|
+
if (steps?.length) {
|
|
467
|
+
let seq = 0;
|
|
468
|
+
for (const step of steps) {
|
|
469
|
+
const cls = step.sel.slice(1);
|
|
470
|
+
const re = new RegExp(`<([a-z][a-z0-9]*)\\b([^>]*\\bclass="[^"]*(?<![\\w-])${cls}(?![\\w-])[^"]*"[^>]*)>`, "gi");
|
|
471
|
+
let nth = 0;
|
|
472
|
+
out = out.replace(re, (tag) => {
|
|
473
|
+
nth += 1;
|
|
474
|
+
seq += 1;
|
|
475
|
+
const delay = nth === 1 ? num2(step.delay) : num2(step.stagger ?? step.delay);
|
|
476
|
+
return addAttrs(tag, {
|
|
477
|
+
"data-anim": step.anim,
|
|
478
|
+
"data-anim-seq": String(seq),
|
|
479
|
+
"data-anim-delay": delay,
|
|
480
|
+
"data-anim-dur": num2(step.dur),
|
|
481
|
+
"data-anim-start": step.start ?? null
|
|
482
|
+
});
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
const t = preset.transition;
|
|
487
|
+
if (t?.effect) {
|
|
488
|
+
out = out.replace(/<section\b([^>]*\bclass="[^"]*(?<![\w-])slide(?![\w-])[^"]*"[^>]*)>/i, (tag) => {
|
|
489
|
+
if (/\bdata-transition=/.test(tag))
|
|
490
|
+
return tag;
|
|
491
|
+
const extra = ` data-transition="${t.effect}"` + (t.dir ? ` data-transition-dir="${t.dir}"` : "") + (num2(t.durMs) ? ` data-transition-dur="${num2(t.durMs)}"` : "");
|
|
492
|
+
return tag.replace(/\s*>$/, extra + ">");
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
return out;
|
|
496
|
+
}
|
|
497
|
+
|
|
290
498
|
// apps/admin/data/skills.lib/document/bin-src/deck-build.mjs
|
|
291
499
|
function die(msg, code = 1) {
|
|
292
500
|
process.stderr.write(`deck-build: ${msg}
|
|
@@ -303,11 +511,36 @@ async function main() {
|
|
|
303
511
|
} catch (e) {
|
|
304
512
|
die(`cannot read spec ${specPath}: ${e.message}`, 66);
|
|
305
513
|
}
|
|
306
|
-
const
|
|
514
|
+
const skillDir = (0, import_node_path.dirname)((0, import_node_path.dirname)(process.argv[1] || ""));
|
|
515
|
+
const layoutsDir = (0, import_node_path.join)(skillDir, "layouts");
|
|
516
|
+
let catalogEntry = null;
|
|
517
|
+
let packLayoutsDir = null;
|
|
518
|
+
const styleId = typeof spec?.style === "string" ? spec.style : null;
|
|
519
|
+
if (styleId) {
|
|
520
|
+
const catalogPath = (0, import_node_path.join)(skillDir, "catalog.json");
|
|
521
|
+
if ((0, import_node_fs.existsSync)(catalogPath)) {
|
|
522
|
+
try {
|
|
523
|
+
const { catalog } = parseCatalog(JSON.parse((0, import_node_fs.readFileSync)(catalogPath, "utf8")));
|
|
524
|
+
catalogEntry = catalog ? resolveEntry(catalog, styleId) : null;
|
|
525
|
+
if (catalogEntry?.kind === "pack") packLayoutsDir = (0, import_node_path.join)(skillDir, "packs", catalogEntry.id, "layouts");
|
|
526
|
+
} catch {
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
let fromPack = 0, fromShared = 0;
|
|
307
531
|
const readLayout = (id) => {
|
|
308
532
|
if (!/^[a-z0-9-]+$/i.test(id)) return null;
|
|
533
|
+
if (packLayoutsDir) {
|
|
534
|
+
const pp = (0, import_node_path.join)(packLayoutsDir, `${id}.tpl`);
|
|
535
|
+
if ((0, import_node_fs.existsSync)(pp)) {
|
|
536
|
+
fromPack++;
|
|
537
|
+
return (0, import_node_fs.readFileSync)(pp, "utf8");
|
|
538
|
+
}
|
|
539
|
+
}
|
|
309
540
|
const p = (0, import_node_path.join)(layoutsDir, `${id}.tpl`);
|
|
310
|
-
|
|
541
|
+
if (!(0, import_node_fs.existsSync)(p)) return null;
|
|
542
|
+
if (packLayoutsDir) fromShared++;
|
|
543
|
+
return (0, import_node_fs.readFileSync)(p, "utf8");
|
|
311
544
|
};
|
|
312
545
|
const { html, warnings, errors } = assembleDeck(spec, readLayout);
|
|
313
546
|
for (const w of warnings) process.stderr.write(`deck-build: ${w}
|
|
@@ -317,14 +550,49 @@ async function main() {
|
|
|
317
550
|
`);
|
|
318
551
|
die(`${errors.length} spec error(s) \u2014 nothing written (see layouts/slots.json for each layout's slots + rows)`, 1);
|
|
319
552
|
}
|
|
320
|
-
|
|
321
|
-
|
|
553
|
+
const resolved = fromPack + fromShared;
|
|
554
|
+
if (packLayoutsDir && resolved > 0) {
|
|
555
|
+
const ratio = fromShared / resolved;
|
|
556
|
+
if (ratio > 0.4) {
|
|
557
|
+
process.stderr.write(
|
|
558
|
+
`deck-build: pack-dilution \u2014 ${fromShared}/${resolved} \u9875\uFF08${Math.round(ratio * 100)}%\uFF09\u56DE\u843D\u5230\u5171\u4EAB\u7248\u5F0F\uFF0C\u8D85\u8FC7 40% \u9608\u503C\u3002\u5305 "${styleId}" \u7684\u9875\u9762\u6E05\u5355\u76F8\u5BF9\u672C\u6B21\u5185\u5BB9\u91CF\u504F\u8584\uFF0C\u8003\u8651\u6269\u5305\u6216\u6539\u7528 skin\u3002
|
|
559
|
+
`
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
let motionPreset = null;
|
|
564
|
+
if (catalogEntry?.motion) {
|
|
565
|
+
const mp = (0, import_node_path.join)(skillDir, catalogEntry.motion);
|
|
566
|
+
if (!(0, import_node_fs.existsSync)(mp)) die(`motion preset not found: ${catalogEntry.motion}`, 66);
|
|
567
|
+
let raw;
|
|
568
|
+
try {
|
|
569
|
+
raw = JSON.parse((0, import_node_fs.readFileSync)(mp, "utf8"));
|
|
570
|
+
} catch (e) {
|
|
571
|
+
die(`cannot parse motion preset ${catalogEntry.motion}: ${e.message}`, 66);
|
|
572
|
+
}
|
|
573
|
+
const mErrors = validateMotionPreset(raw);
|
|
574
|
+
if (mErrors.length) {
|
|
575
|
+
for (const m of mErrors) process.stderr.write(`deck-build: ERROR motion ${m}
|
|
576
|
+
`);
|
|
577
|
+
die(`${mErrors.length} motion preset error(s) \u2014 nothing written`, 1);
|
|
578
|
+
}
|
|
579
|
+
motionPreset = raw;
|
|
580
|
+
}
|
|
581
|
+
let finalHtml = html;
|
|
582
|
+
if (motionPreset) {
|
|
583
|
+
const perSlide = html.split(/(?=<section\b[^>]*\bclass="[^"]*(?<![\w-])slide(?![\w-]))/).filter(Boolean);
|
|
584
|
+
finalHtml = perSlide.map((sec) => {
|
|
585
|
+
const id = sec.match(/data-layout="([a-z0-9-]+)"/i)?.[1];
|
|
586
|
+
return id ? applyMotion(sec, id, motionPreset) : sec;
|
|
587
|
+
}).join("");
|
|
588
|
+
}
|
|
589
|
+
await (0, import_promises.writeFile)(outPath, finalHtml, "utf8");
|
|
322
590
|
process.stdout.write(JSON.stringify({
|
|
323
591
|
ok: true,
|
|
324
592
|
out: outPath,
|
|
325
593
|
slides: Array.isArray(spec?.slides) ? spec.slides.length : 0,
|
|
326
594
|
warnings,
|
|
327
|
-
next: `html2pptx ${outPath} out.pptx${
|
|
595
|
+
next: `html2pptx ${outPath} out.pptx${styleId ? ` --style ${styleId}` : " --style <skin>"}`
|
|
328
596
|
}, null, 1) + "\n");
|
|
329
597
|
}
|
|
330
598
|
main().catch((e) => die(e.message, 1));
|
|
@@ -13795,9 +13795,9 @@ var require_load = __commonJS({
|
|
|
13795
13795
|
var require_lib3 = __commonJS({
|
|
13796
13796
|
"node_modules/jszip/lib/index.js"(exports2, module2) {
|
|
13797
13797
|
"use strict";
|
|
13798
|
-
function
|
|
13799
|
-
if (!(this instanceof
|
|
13800
|
-
return new
|
|
13798
|
+
function JSZip5() {
|
|
13799
|
+
if (!(this instanceof JSZip5)) {
|
|
13800
|
+
return new JSZip5();
|
|
13801
13801
|
}
|
|
13802
13802
|
if (arguments.length) {
|
|
13803
13803
|
throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide.");
|
|
@@ -13806,7 +13806,7 @@ var require_lib3 = __commonJS({
|
|
|
13806
13806
|
this.comment = null;
|
|
13807
13807
|
this.root = "";
|
|
13808
13808
|
this.clone = function() {
|
|
13809
|
-
var newObj = new
|
|
13809
|
+
var newObj = new JSZip5();
|
|
13810
13810
|
for (var i in this) {
|
|
13811
13811
|
if (typeof this[i] !== "function") {
|
|
13812
13812
|
newObj[i] = this[i];
|
|
@@ -13815,16 +13815,16 @@ var require_lib3 = __commonJS({
|
|
|
13815
13815
|
return newObj;
|
|
13816
13816
|
};
|
|
13817
13817
|
}
|
|
13818
|
-
|
|
13819
|
-
|
|
13820
|
-
|
|
13821
|
-
|
|
13822
|
-
|
|
13823
|
-
|
|
13824
|
-
return new
|
|
13818
|
+
JSZip5.prototype = require_object();
|
|
13819
|
+
JSZip5.prototype.loadAsync = require_load();
|
|
13820
|
+
JSZip5.support = require_support();
|
|
13821
|
+
JSZip5.defaults = require_defaults();
|
|
13822
|
+
JSZip5.version = "3.10.1";
|
|
13823
|
+
JSZip5.loadAsync = function(content, options) {
|
|
13824
|
+
return new JSZip5().loadAsync(content, options);
|
|
13825
13825
|
};
|
|
13826
|
-
|
|
13827
|
-
module2.exports =
|
|
13826
|
+
JSZip5.external = require_external();
|
|
13827
|
+
module2.exports = JSZip5;
|
|
13828
13828
|
}
|
|
13829
13829
|
});
|
|
13830
13830
|
|
|
@@ -16738,7 +16738,7 @@ var require_browser_buffer_encode = __commonJS({
|
|
|
16738
16738
|
var require_zip_stream = __commonJS({
|
|
16739
16739
|
"node_modules/exceljs/lib/utils/zip-stream.js"(exports2, module2) {
|
|
16740
16740
|
var events = require("events");
|
|
16741
|
-
var
|
|
16741
|
+
var JSZip5 = require_lib3();
|
|
16742
16742
|
var StreamBuf = require_stream_buf();
|
|
16743
16743
|
var { stringToBuffer } = require_browser_buffer_encode();
|
|
16744
16744
|
var ZipWriter = class extends events.EventEmitter {
|
|
@@ -16751,7 +16751,7 @@ var require_zip_stream = __commonJS({
|
|
|
16751
16751
|
},
|
|
16752
16752
|
options
|
|
16753
16753
|
);
|
|
16754
|
-
this.zip = new
|
|
16754
|
+
this.zip = new JSZip5();
|
|
16755
16755
|
this.stream = new StreamBuf();
|
|
16756
16756
|
}
|
|
16757
16757
|
append(data, options) {
|
|
@@ -28431,7 +28431,7 @@ var require_theme1 = __commonJS({
|
|
|
28431
28431
|
var require_xlsx = __commonJS({
|
|
28432
28432
|
"node_modules/exceljs/lib/xlsx/xlsx.js"(exports2, module2) {
|
|
28433
28433
|
var fs = require("fs");
|
|
28434
|
-
var
|
|
28434
|
+
var JSZip5 = require_lib3();
|
|
28435
28435
|
var { PassThrough } = require_readable2();
|
|
28436
28436
|
var ZipStream = require_zip_stream();
|
|
28437
28437
|
var StreamBuf = require_stream_buf();
|
|
@@ -28670,7 +28670,7 @@ var require_xlsx = __commonJS({
|
|
|
28670
28670
|
tables: {},
|
|
28671
28671
|
vmlDrawings: {}
|
|
28672
28672
|
};
|
|
28673
|
-
const zip = await
|
|
28673
|
+
const zip = await JSZip5.loadAsync(buffer);
|
|
28674
28674
|
for (const entry of Object.values(zip.files)) {
|
|
28675
28675
|
if (!entry.dir) {
|
|
28676
28676
|
let entryName = entry.name;
|
|
@@ -72933,11 +72933,11 @@ var require_excel = __commonJS({
|
|
|
72933
72933
|
var require_pptxgen_cjs = __commonJS({
|
|
72934
72934
|
"node_modules/pptxgenjs/dist/pptxgen.cjs.js"(exports2, module2) {
|
|
72935
72935
|
"use strict";
|
|
72936
|
-
var
|
|
72936
|
+
var JSZip5 = require_lib3();
|
|
72937
72937
|
function _interopDefaultLegacy(e) {
|
|
72938
72938
|
return e && typeof e === "object" && "default" in e ? e : { "default": e };
|
|
72939
72939
|
}
|
|
72940
|
-
var JSZip__default = /* @__PURE__ */ _interopDefaultLegacy(
|
|
72940
|
+
var JSZip__default = /* @__PURE__ */ _interopDefaultLegacy(JSZip5);
|
|
72941
72941
|
var __assign2 = function() {
|
|
72942
72942
|
__assign2 = Object.assign || function __assign3(t) {
|
|
72943
72943
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
@@ -154406,7 +154406,7 @@ function contrastHex(hex) {
|
|
|
154406
154406
|
}
|
|
154407
154407
|
|
|
154408
154408
|
// packages/core/dist/document/html-pptx.js
|
|
154409
|
-
var
|
|
154409
|
+
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
154410
154410
|
|
|
154411
154411
|
// packages/core/dist/document/pptx-anim.js
|
|
154412
154412
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
@@ -154447,11 +154447,15 @@ function buildSlideTiming(steps, spidOf) {
|
|
|
154447
154447
|
return "";
|
|
154448
154448
|
let id = 100;
|
|
154449
154449
|
const next = () => id++;
|
|
154450
|
+
const beatOpened = /* @__PURE__ */ new Set();
|
|
154450
154451
|
const stepPars = resolved.map(({ s, spid }, i) => {
|
|
154451
154452
|
const { id: pid, sub } = presetOf(s.effect);
|
|
154452
154453
|
const dur = Math.max(1, Math.round(s.durMs ?? 500));
|
|
154453
|
-
const
|
|
154454
|
-
|
|
154454
|
+
const ridesAlong = s.group !== void 0 && beatOpened.has(s.group);
|
|
154455
|
+
if (s.group !== void 0)
|
|
154456
|
+
beatOpened.add(s.group);
|
|
154457
|
+
const delay = ridesAlong ? 0 : Math.max(0, Math.round(s.delayMs ?? (i === 0 ? 0 : 200)));
|
|
154458
|
+
const node = ridesAlong ? "withEffect" : i === 0 ? "clickEffect" : s.start === "with" ? "withEffect" : "afterEffect";
|
|
154455
154459
|
const effectCtnId = next();
|
|
154456
154460
|
const beh = behaviorsOf(s.effect, next, spid, dur);
|
|
154457
154461
|
return `<p:par><p:cTn id="${effectCtnId}" presetID="${pid}" presetClass="entr" presetSubtype="${sub}" fill="hold" grpId="0" nodeType="${node}"><p:stCondLst><p:cond delay="${delay}"/></p:stCondLst><p:childTnLst>${beh}</p:childTnLst></p:cTn></p:par>`;
|
|
@@ -154485,6 +154489,84 @@ async function injectAnimations(buf, perSlide) {
|
|
|
154485
154489
|
return await zip.generateAsync({ type: "nodebuffer", compression: "DEFLATE" });
|
|
154486
154490
|
}
|
|
154487
154491
|
|
|
154492
|
+
// packages/core/dist/document/pptx-transition.js
|
|
154493
|
+
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
154494
|
+
var MC_NS = "http://schemas.openxmlformats.org/markup-compatibility/2006";
|
|
154495
|
+
var P14_NS = "http://schemas.microsoft.com/office/powerpoint/2010/main";
|
|
154496
|
+
var P159_NS = "http://schemas.microsoft.com/office/powerpoint/2015/09/main";
|
|
154497
|
+
var STANDARD = {
|
|
154498
|
+
cut: { tag: "cut", dirs: null },
|
|
154499
|
+
fade: { tag: "fade", dirs: null },
|
|
154500
|
+
dissolve: { tag: "dissolve", dirs: null },
|
|
154501
|
+
wedge: { tag: "wedge", dirs: null },
|
|
154502
|
+
wipe: { tag: "wipe", dirs: ["l", "r", "u", "d"], defaultDir: "l" },
|
|
154503
|
+
push: { tag: "push", dirs: ["l", "r", "u", "d"], defaultDir: "l" },
|
|
154504
|
+
cover: { tag: "cover", dirs: ["l", "r", "u", "d"], defaultDir: "l" },
|
|
154505
|
+
zoom: { tag: "zoom", dirs: ["in", "out"], defaultDir: "in" },
|
|
154506
|
+
split: { tag: "split", dirs: ["in", "out"], dirAttr: "dir", defaultDir: "in" }
|
|
154507
|
+
};
|
|
154508
|
+
var MORPH = "morph";
|
|
154509
|
+
var TRANSITION_EFFECTS = [...Object.keys(STANDARD), MORPH];
|
|
154510
|
+
function speedOf(durMs) {
|
|
154511
|
+
if (durMs === void 0)
|
|
154512
|
+
return "med";
|
|
154513
|
+
if (durMs >= 1e3)
|
|
154514
|
+
return "slow";
|
|
154515
|
+
if (durMs >= 500)
|
|
154516
|
+
return "med";
|
|
154517
|
+
return "fast";
|
|
154518
|
+
}
|
|
154519
|
+
function effectElement(effect, dir) {
|
|
154520
|
+
const def = STANDARD[effect];
|
|
154521
|
+
if (!def)
|
|
154522
|
+
return "<p:fade/>";
|
|
154523
|
+
if (!def.dirs)
|
|
154524
|
+
return `<p:${def.tag}/>`;
|
|
154525
|
+
const chosen = dir && def.dirs.includes(dir) ? dir : def.defaultDir;
|
|
154526
|
+
return `<p:${def.tag} ${def.dirAttr ?? "dir"}="${chosen}"/>`;
|
|
154527
|
+
}
|
|
154528
|
+
function buildTransition(spec) {
|
|
154529
|
+
const effect = (spec.effect || "").trim();
|
|
154530
|
+
if (!effect || effect === "none")
|
|
154531
|
+
return "";
|
|
154532
|
+
const spd = speedOf(spec.durMs);
|
|
154533
|
+
const dur = spec.durMs !== void 0 ? Math.max(1, Math.round(spec.durMs)) : void 0;
|
|
154534
|
+
const isMorph = effect === MORPH;
|
|
154535
|
+
const plain = `<p:transition spd="${spd}">${effectElement(isMorph ? "fade" : effect, spec.dir)}</p:transition>`;
|
|
154536
|
+
if (!isMorph && dur === void 0)
|
|
154537
|
+
return plain;
|
|
154538
|
+
const choiceNs = isMorph ? ` xmlns:p14="${P14_NS}" xmlns:p159="${P159_NS}" Requires="p159"` : ` xmlns:p14="${P14_NS}" Requires="p14"`;
|
|
154539
|
+
const inner = isMorph ? `<p159:morph option="byObject"/>` : effectElement(effect, spec.dir);
|
|
154540
|
+
const durAttr = dur !== void 0 ? ` p14:dur="${dur}"` : "";
|
|
154541
|
+
return `<mc:AlternateContent xmlns:mc="${MC_NS}"><mc:Choice${choiceNs}><p:transition spd="${spd}"${durAttr}>${inner}</p:transition></mc:Choice><mc:Fallback>${plain}</mc:Fallback></mc:AlternateContent>`;
|
|
154542
|
+
}
|
|
154543
|
+
async function injectTransitions(buf, perSlide) {
|
|
154544
|
+
if (!perSlide.some((t) => t && t.effect && t.effect !== "none"))
|
|
154545
|
+
return buf;
|
|
154546
|
+
const zip = await import_jszip3.default.loadAsync(buf);
|
|
154547
|
+
const slidePaths = Object.keys(zip.files).filter((p) => /^ppt\/slides\/slide\d+\.xml$/.test(p)).sort((a, b) => parseInt(a.match(/(\d+)/)[1], 10) - parseInt(b.match(/(\d+)/)[1], 10));
|
|
154548
|
+
for (let i = 0; i < slidePaths.length; i++) {
|
|
154549
|
+
const spec = perSlide[i];
|
|
154550
|
+
if (!spec)
|
|
154551
|
+
continue;
|
|
154552
|
+
const xml0 = await zip.file(slidePaths[i]).async("string");
|
|
154553
|
+
if (xml0.includes("<p:transition") || xml0.includes("mc:AlternateContent"))
|
|
154554
|
+
continue;
|
|
154555
|
+
const frag = buildTransition(spec);
|
|
154556
|
+
if (!frag)
|
|
154557
|
+
continue;
|
|
154558
|
+
let xml;
|
|
154559
|
+
if (xml0.includes("</p:clrMapOvr>"))
|
|
154560
|
+
xml = xml0.replace("</p:clrMapOvr>", `</p:clrMapOvr>${frag}`);
|
|
154561
|
+
else if (xml0.includes("</p:cSld>"))
|
|
154562
|
+
xml = xml0.replace("</p:cSld>", `</p:cSld>${frag}`);
|
|
154563
|
+
else
|
|
154564
|
+
continue;
|
|
154565
|
+
zip.file(slidePaths[i], xml);
|
|
154566
|
+
}
|
|
154567
|
+
return await zip.generateAsync({ type: "nodebuffer", compression: "DEFLATE" });
|
|
154568
|
+
}
|
|
154569
|
+
|
|
154488
154570
|
// packages/core/dist/document/html-pptx.js
|
|
154489
154571
|
var DEFAULT_CHART_RAMP = ["2563EB", "10B981", "F59E0B", "EF4444", "8B5CF6", "06B6D4"];
|
|
154490
154572
|
var SLIDE_W_IN = 13.333;
|
|
@@ -154582,7 +154664,7 @@ function gradFillXml(g) {
|
|
|
154582
154664
|
return `<a:gradFill rotWithShape="1"><a:gsLst>${gs}</a:gsLst><a:lin ang="${Math.round(deg * 6e4)}" scaled="1"/></a:gradFill>`;
|
|
154583
154665
|
}
|
|
154584
154666
|
async function injectGradients(buf, grads) {
|
|
154585
|
-
const zip = await
|
|
154667
|
+
const zip = await import_jszip4.default.loadAsync(buf);
|
|
154586
154668
|
for (const path of Object.keys(zip.files).filter((p) => /^ppt\/slides\/slide\d+\.xml$/.test(p))) {
|
|
154587
154669
|
let xml = await zip.file(path).async("string");
|
|
154588
154670
|
let changed = false;
|
|
@@ -154650,6 +154732,7 @@ async function convertLayoutToPptx(snapshot) {
|
|
|
154650
154732
|
pptx.layout = "TALOS_HTML_WIDE";
|
|
154651
154733
|
const gradients = [];
|
|
154652
154734
|
const perSlideAnims = [];
|
|
154735
|
+
const perSlideTransitions = [];
|
|
154653
154736
|
for (const [slideNo, slideSpec] of snapshot.slides.entries()) {
|
|
154654
154737
|
const slide = pptx.addSlide();
|
|
154655
154738
|
const bg = cssColorToHex(slideSpec.background);
|
|
@@ -154857,10 +154940,12 @@ async function convertLayoutToPptx(snapshot) {
|
|
|
154857
154940
|
if (slideSpec.speakerNotes)
|
|
154858
154941
|
slide.addNotes(String(slideSpec.speakerNotes));
|
|
154859
154942
|
perSlideAnims.push(slideAnims);
|
|
154943
|
+
perSlideTransitions.push(slideSpec.transition);
|
|
154860
154944
|
}
|
|
154861
154945
|
let buf = await pptx.write("nodebuffer");
|
|
154862
154946
|
if (gradients.length)
|
|
154863
154947
|
buf = await injectGradients(buf, gradients);
|
|
154948
|
+
buf = await injectTransitions(buf, perSlideTransitions);
|
|
154864
154949
|
buf = await injectAnimations(buf, perSlideAnims);
|
|
154865
154950
|
return { bytes: await finalizePptx(new Uint8Array(buf)), warnings };
|
|
154866
154951
|
}
|