@openpresentation/opf 0.17.0 → 0.18.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 +4 -4
- package/dist/browser.js +38 -0
- package/dist/{catalog-refs-C4K4y-vh.d.ts → catalog-refs-BSfGELpt.d.ts} +1 -1
- package/dist/{catalog-schemas-g7RFQBdc.d.ts → catalog-schemas-CinPh5WA.d.ts} +1 -1
- package/dist/catalog.d.ts +2 -2
- package/dist/{chart-data-DTxdRRT1.d.ts → chart-data-BnNqgnC-.d.ts} +1 -1
- package/dist/{chunk-RA64UQKI.js → chunk-2PEWUUBR.js} +97 -73
- package/dist/{chunk-TCD2FB2K.js → chunk-ECP7QPGK.js} +5 -5
- package/dist/{chunk-O2CX5NEH.js → chunk-FO3WGS4R.js} +6 -5
- package/dist/{chunk-N4EVOFEA.js → chunk-GVOLSWAJ.js} +4 -4
- package/dist/{chunk-WWYWFVOI.js → chunk-IM337HP5.js} +151 -25
- package/dist/{chunk-YT7FMQER.js → chunk-JCOSZTOI.js} +1 -1
- package/dist/{chunk-IPW5BS3X.js → chunk-K5EG3UMS.js} +190 -172
- package/dist/{chunk-NLNYNBTS.js → chunk-KA3ZPFVT.js} +84 -26
- package/dist/{chunk-M4UR3NPN.js → chunk-L5YACLWK.js} +2 -2
- package/dist/{chunk-CW7GEAV3.js → chunk-MBU42S5Y.js} +291 -133
- package/dist/{chunk-BIC3SWPK.js → chunk-MSFE2HUK.js} +30 -5
- package/dist/{chunk-ESRYBYLY.js → chunk-PNINP5IF.js} +1 -1
- package/dist/{chunk-IS5H5JKH.js → chunk-R7KIASS4.js} +1 -1
- package/dist/{chunk-PPROJP2E.js → chunk-TRELE6I6.js} +1 -1
- package/dist/{chunk-O3CVNJTL.js → chunk-WHHLGDCQ.js} +1 -1
- package/dist/{chunk-O263APNI.js → chunk-ZCFSDSUX.js} +3 -3
- package/dist/{composition-BbZ_9C-c.d.ts → composition-C-OoqvAr.d.ts} +80 -40
- package/dist/composition.d.ts +3 -3
- package/dist/composition.js +1 -1
- package/dist/conversion-4CLOEG6O.js +21 -0
- package/dist/{conversion-SBpTOwdg.d.ts → conversion-BxZbBd_0.d.ts} +96 -38
- package/dist/convert.d.ts +4 -4
- package/dist/convert.js +7 -7
- package/dist/data.d.ts +7 -7
- package/dist/data.js +2 -2
- package/dist/{deck-report-Bx3naFlF.d.ts → deck-report-DiDf_Vew.d.ts} +5 -5
- package/dist/deck.d.ts +8 -8
- package/dist/deck.js +10 -10
- package/dist/diff.d.ts +1 -1
- package/dist/diff.js +5 -5
- package/dist/docs.js +35 -29
- package/dist/examples.d.ts +1 -1
- package/dist/examples.js +181 -214
- package/dist/{finding-CDQ_wH8j.d.ts → finding-CT_f_vbD.d.ts} +1 -1
- package/dist/format.js +2 -2
- package/dist/index.d.ts +153 -20
- package/dist/index.js +62 -15
- package/dist/markdown.d.ts +12 -8
- package/dist/markdown.js +7 -7
- package/dist/node-engine.d.ts +37 -17
- package/dist/node-engine.js +39 -16
- package/dist/{pagination-BhX4M48Y.d.ts → pagination-BaUjDrTz.d.ts} +7 -4
- package/dist/pagination.d.ts +4 -4
- package/dist/pagination.js +4 -4
- package/dist/patch.d.ts +1 -1
- package/dist/patch.js +4 -4
- package/dist/{presentation-fb8CZmRq.d.ts → presentation-81rNihF0.d.ts} +271 -384
- package/dist/repo-readme.js +1 -1
- package/dist/schemas.d.ts +4 -2
- package/dist/schemas.js +1 -1
- package/dist/spec/README.md +1 -1
- package/dist/spec/schemas/opf.schema.json +67 -72
- package/dist/types.d.ts +3 -3
- package/dist/{validation-types-iZbXfES6.d.ts → validation-types-PbGDrNUr.d.ts} +12 -7
- package/dist/validator.d.ts +8 -8
- package/dist/validator.js +3 -3
- package/dist/yaml.d.ts +6 -6
- package/dist/yaml.js +7 -7
- package/package.json +14 -12
- package/dist/node.d.ts +0 -60
- package/dist/node.js +0 -54
|
@@ -425,6 +425,109 @@ function primaryOrganization(presentation) {
|
|
|
425
425
|
return organizations.find((item) => item.role === "primary") ?? organizations[0];
|
|
426
426
|
}
|
|
427
427
|
|
|
428
|
+
// src/logos.ts
|
|
429
|
+
var LOGO_SHAPES = ["full", "stacked", "icon", "wordmark"];
|
|
430
|
+
function isLogoShape(value) {
|
|
431
|
+
return typeof value === "string" && LOGO_SHAPES.includes(value);
|
|
432
|
+
}
|
|
433
|
+
var NAME_PATTERN = /^(?:var:)?(organization(?:\.[A-Za-z0-9_-]+){1,3})$/;
|
|
434
|
+
function parseLogoName(name, presentation) {
|
|
435
|
+
const match = NAME_PATTERN.exec(name);
|
|
436
|
+
if (!match) return null;
|
|
437
|
+
const parts = match[1].split(".");
|
|
438
|
+
const shapes = LOGO_SHAPES.map((shape) => `'${shape}'`).join(", ");
|
|
439
|
+
if (parts.length === 2) return parts[1] === "logo" ? {} : null;
|
|
440
|
+
if (parts.length === 3) {
|
|
441
|
+
if (parts[2] === "logo") return { organization: parts[1] };
|
|
442
|
+
if (parts[1] !== "logo") return null;
|
|
443
|
+
if (isLogoShape(parts[2])) return { shape: parts[2] };
|
|
444
|
+
if (organizationIndex(presentation, "logo") >= 0) return null;
|
|
445
|
+
return { error: `'${parts.join(".")}' is not a built-in variable: '${parts[2]}' is not a logo shape; the shapes are ${shapes}.` };
|
|
446
|
+
}
|
|
447
|
+
if (parts[2] !== "logo") return null;
|
|
448
|
+
if (isLogoShape(parts[3])) return { organization: parts[1], shape: parts[3] };
|
|
449
|
+
return { error: `'${parts.join(".")}' is not a built-in variable: '${parts[3]}' is not a logo shape; the shapes are ${shapes}.` };
|
|
450
|
+
}
|
|
451
|
+
function logoReferenceName(reference, shape = reference.shape) {
|
|
452
|
+
return `organization${reference.organization !== void 0 ? `.${reference.organization}` : ""}.logo${shape && shape !== "full" ? `.${shape}` : ""}`;
|
|
453
|
+
}
|
|
454
|
+
function organizationIndex(presentation, id) {
|
|
455
|
+
if (!isRecord(presentation)) return -1;
|
|
456
|
+
const raw = presentation.organization;
|
|
457
|
+
const list = Array.isArray(raw) ? raw : [raw];
|
|
458
|
+
if (id !== void 0) return list.findIndex((entry) => isRecord(entry) && entry.id === id);
|
|
459
|
+
const primary = list.findIndex((entry) => isRecord(entry) && entry.role === "primary");
|
|
460
|
+
return primary >= 0 ? primary : list.findIndex((entry) => isRecord(entry));
|
|
461
|
+
}
|
|
462
|
+
var usable = (value) => {
|
|
463
|
+
const source = typeof value === "string" ? value : isRecord(value) ? value.src : void 0;
|
|
464
|
+
return typeof source === "string" && source.trim().length > 0;
|
|
465
|
+
};
|
|
466
|
+
var isAsset = (value) => typeof value === "string" || isRecord(value) && "src" in value;
|
|
467
|
+
function shapeChain(shape) {
|
|
468
|
+
const chain = [shape, "full", "wordmark", "stacked", "icon"];
|
|
469
|
+
return chain.filter((entry, index) => chain.indexOf(entry) === index);
|
|
470
|
+
}
|
|
471
|
+
function pickOrganizationLogo(logo, shape, onDark, root) {
|
|
472
|
+
if (logo === void 0 || logo === null) return null;
|
|
473
|
+
if (isAsset(logo)) return usable(logo) ? { source: logo, path: `${root}.logo`, variant: "default" } : null;
|
|
474
|
+
if (!isRecord(logo)) return null;
|
|
475
|
+
const tones = onDark ? ["onDark", "onLight"] : ["onLight", "onDark"];
|
|
476
|
+
for (const candidate of shapeChain(shape)) {
|
|
477
|
+
const entry = logo[candidate];
|
|
478
|
+
if (entry === void 0 || entry === null) continue;
|
|
479
|
+
if (isAsset(entry)) {
|
|
480
|
+
if (usable(entry)) return { source: entry, path: `${root}.logo.${candidate}`, variant: "default" };
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
if (!isRecord(entry)) continue;
|
|
484
|
+
for (const tone of tones) if (usable(entry[tone])) return { source: entry[tone], path: `${root}.logo.${candidate}.${tone}`, variant: tone };
|
|
485
|
+
}
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
function resolveOrganizationLogo(presentation, reference, options = {}) {
|
|
489
|
+
const shape = reference.shape ?? options.shape ?? "full";
|
|
490
|
+
const name = logoReferenceName(reference, shape);
|
|
491
|
+
const index = organizationIndex(presentation, reference.organization);
|
|
492
|
+
if (index < 0) {
|
|
493
|
+
if (reference.organization !== void 0) return { ok: false, reason: "unknown", message: `'${name}' names no organization with id '${reference.organization}'.` };
|
|
494
|
+
return { ok: false, reason: "missing", message: `'${name}' has no value: the deck has no organization with a logo.` };
|
|
495
|
+
}
|
|
496
|
+
const deck = presentation;
|
|
497
|
+
const root = Array.isArray(deck.organization) ? `organization.${index}` : "organization";
|
|
498
|
+
const organization = Array.isArray(deck.organization) ? deck.organization[index] : deck.organization;
|
|
499
|
+
const picked = pickOrganizationLogo(organization.logo, shape, options.onDark === true, root);
|
|
500
|
+
if (!picked) return { ok: false, reason: "missing", message: `'${name}' has no value: ${root} has no logo.` };
|
|
501
|
+
return { ok: true, logo: { ...picked, shape, reference: `var:${name}` } };
|
|
502
|
+
}
|
|
503
|
+
function resolveLogo(presentation, slide, options = {}) {
|
|
504
|
+
if (options.shape !== void 0 && !isLogoShape(options.shape)) throw new RangeError("Logo shape must be full, stacked, icon or wordmark.");
|
|
505
|
+
const onDark = options.onDark === true;
|
|
506
|
+
const resolve = (reference, designPath) => {
|
|
507
|
+
const result = resolveOrganizationLogo(presentation, reference, { ...options.shape ? { shape: options.shape } : {}, onDark });
|
|
508
|
+
if (!result.ok) return null;
|
|
509
|
+
return designPath ? { ...result.logo, designPath } : result.logo;
|
|
510
|
+
};
|
|
511
|
+
if (options.reference !== void 0) {
|
|
512
|
+
const parsed = typeof options.reference === "string" ? parseLogoName(options.reference, presentation) : null;
|
|
513
|
+
if (!parsed || "error" in parsed) throw new RangeError(`'${String(options.reference)}' is not a logo reference such as 'var:organization.logo.icon'.`);
|
|
514
|
+
return resolve(parsed);
|
|
515
|
+
}
|
|
516
|
+
const slideIndex = Number.isSafeInteger(options.slideIndex) && options.slideIndex >= 0 ? options.slideIndex : 0;
|
|
517
|
+
const levels = [
|
|
518
|
+
[isRecord(slide) && isRecord(slide.design) ? slide.design.logo : void 0, `slides.${slideIndex}.design.logo`],
|
|
519
|
+
[isRecord(presentation) && isRecord(presentation.design) ? presentation.design.logo : void 0, "design.logo"]
|
|
520
|
+
];
|
|
521
|
+
for (const [value, path] of levels) {
|
|
522
|
+
if (value === false) return null;
|
|
523
|
+
if (typeof value !== "string") continue;
|
|
524
|
+
const parsed = parseLogoName(value, presentation);
|
|
525
|
+
if (!parsed || "error" in parsed || !value.startsWith("var:")) continue;
|
|
526
|
+
return resolve(parsed, path);
|
|
527
|
+
}
|
|
528
|
+
return resolve({});
|
|
529
|
+
}
|
|
530
|
+
|
|
428
531
|
// src/slide-variables.ts
|
|
429
532
|
var SLIDE_SCOPED_BUILTINS = ["slide.number", "slide.section", "deck.slideCount"];
|
|
430
533
|
function isSlideScopedBuiltin(name) {
|
|
@@ -476,18 +579,34 @@ function slideTokenSpans(text2) {
|
|
|
476
579
|
return Array.from(text2.matchAll(slideTokenSpanPattern), (match) => [match.index, match.index + match[0].length]);
|
|
477
580
|
}
|
|
478
581
|
var skippedKeys = /* @__PURE__ */ new Set(["extensions"]);
|
|
479
|
-
|
|
582
|
+
var logoReferencePattern = /^var:organization(?:.[A-Za-z0-9_-]+){1,3}$/;
|
|
583
|
+
var OMIT = /* @__PURE__ */ Symbol("omit");
|
|
584
|
+
function clone(value) {
|
|
585
|
+
return typeof value === "object" && value !== null ? structuredClone(value) : value;
|
|
586
|
+
}
|
|
587
|
+
function substituteLogo(value, logos) {
|
|
588
|
+
if (logos.presentation === void 0 || !logoReferencePattern.test(value)) return value;
|
|
589
|
+
const reference = parseLogoName(value, logos.presentation);
|
|
590
|
+
if (!reference || "error" in reference) return value;
|
|
591
|
+
const result = resolveOrganizationLogo(logos.presentation, reference, { onDark: logos.darkBackground === true });
|
|
592
|
+
if (result.ok) return clone(result.logo.source);
|
|
593
|
+
return result.reason === "missing" ? OMIT : value;
|
|
594
|
+
}
|
|
595
|
+
function substitute(value, values, root, logos = {}) {
|
|
480
596
|
if (typeof value === "string") {
|
|
597
|
+
const logo = substituteLogo(value, logos);
|
|
598
|
+
if (logo !== value) return logo;
|
|
481
599
|
const result = substituteSlideTokens(value, values);
|
|
482
600
|
return result.changed ? result.text : value;
|
|
483
601
|
}
|
|
484
602
|
if (Array.isArray(value)) {
|
|
485
603
|
let changed2 = false;
|
|
486
|
-
const out2 =
|
|
487
|
-
|
|
604
|
+
const out2 = [];
|
|
605
|
+
for (const entry of value) {
|
|
606
|
+
const next = substitute(entry, values, false, logos);
|
|
488
607
|
if (next !== entry) changed2 = true;
|
|
489
|
-
|
|
490
|
-
}
|
|
608
|
+
if (next !== OMIT) out2.push(next);
|
|
609
|
+
}
|
|
491
610
|
return changed2 ? out2 : value;
|
|
492
611
|
}
|
|
493
612
|
if (!isRecord(value)) return value;
|
|
@@ -500,14 +619,14 @@ function substitute(value, values, root) {
|
|
|
500
619
|
const design = {};
|
|
501
620
|
let designChanged = false;
|
|
502
621
|
for (const [designKey, designEntry] of Object.entries(entry)) {
|
|
503
|
-
const designNext = designKey === "header" || designKey === "footer" ? designEntry : substitute(designEntry, values, false);
|
|
622
|
+
const designNext = designKey === "header" || designKey === "footer" || designKey === "logo" ? designEntry : substitute(designEntry, values, false, logos);
|
|
504
623
|
if (designNext !== designEntry) designChanged = true;
|
|
505
|
-
design[designKey] = designNext;
|
|
624
|
+
if (designNext !== OMIT) design[designKey] = designNext;
|
|
506
625
|
}
|
|
507
626
|
next = designChanged ? design : entry;
|
|
508
|
-
} else next = substitute(entry, values, false);
|
|
627
|
+
} else next = substitute(entry, values, false, logos);
|
|
509
628
|
if (next !== entry) changed = true;
|
|
510
|
-
out[key] = next;
|
|
629
|
+
if (next !== OMIT) out[key] = next;
|
|
511
630
|
}
|
|
512
631
|
return changed ? out : value;
|
|
513
632
|
}
|
|
@@ -515,8 +634,10 @@ function resolveSlideVariables(slide, values) {
|
|
|
515
634
|
if (!isRecord(slide)) return slide;
|
|
516
635
|
const full = { slideNumber: values?.slideNumber, ...values?.slideCount !== void 0 ? { slideCount: values.slideCount } : {}, section: slide.section };
|
|
517
636
|
checkValues(full);
|
|
518
|
-
|
|
519
|
-
|
|
637
|
+
const logos = values.presentation !== void 0 ? { presentation: values.presentation, darkBackground: values.darkBackground === true } : {};
|
|
638
|
+
const text2 = JSON.stringify(slide);
|
|
639
|
+
if (!quickCheck.test(text2) && !(logos.presentation !== void 0 && text2.includes('"var:organization.'))) return slide;
|
|
640
|
+
return substitute(slide, full, true, logos);
|
|
520
641
|
}
|
|
521
642
|
function usesSlideBuiltin(value, name) {
|
|
522
643
|
const pattern = new RegExp(String.raw`(?:^|[^\\])\{\{\s*${name.replace(".", String.raw`\.`)}\s*(?:\|[^{}]*)?\}\}`);
|
|
@@ -543,9 +664,9 @@ var OPFVariableError = class extends Error {
|
|
|
543
664
|
}
|
|
544
665
|
};
|
|
545
666
|
var idPattern = /^[a-z][a-z0-9-]*$/;
|
|
546
|
-
var nameSource = String.raw`[a-z][a-z0-9-]*|(?:deck|speaker|organization|slide)(?:\.[A-Za-z0-9_-]+){1,
|
|
667
|
+
var nameSource = String.raw`[a-z][a-z0-9-]*|(?:deck|speaker|organization|slide)(?:\.[A-Za-z0-9_-]+){1,3}`;
|
|
547
668
|
var referencePattern = new RegExp(String.raw`^var:(${nameSource})$`);
|
|
548
|
-
var builtinNamePattern = /^(?:speakers|(?:deck|speaker|organization|slide)(?:\.[A-Za-z0-9_-]+){1,
|
|
669
|
+
var builtinNamePattern = /^(?:speakers|(?:deck|speaker|organization|slide)(?:\.[A-Za-z0-9_-]+){1,3})$/;
|
|
549
670
|
var builtinUsePattern = /\{\{\s*(?:speakers\b|(?:deck|speaker|organization|slide)\.)|^var:(?:speakers$|(?:deck|speaker|organization|slide)\.)/;
|
|
550
671
|
var hexPattern = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
|
|
551
672
|
var urlPattern = /^(?:https?:\/\/|mailto:|tel:)\S+$/;
|
|
@@ -562,7 +683,7 @@ var SAMPLES = {
|
|
|
562
683
|
list: ["Sample item"]
|
|
563
684
|
};
|
|
564
685
|
var hasOwn = (value, key) => Object.hasOwn(value, key);
|
|
565
|
-
var
|
|
686
|
+
var clone2 = (value) => value === void 0 ? value : JSON.parse(JSON.stringify(value));
|
|
566
687
|
function isTemplate(presentation) {
|
|
567
688
|
return isRecord(presentation) && presentation.template === true;
|
|
568
689
|
}
|
|
@@ -578,7 +699,7 @@ function coerceVariableValue(kind2, raw) {
|
|
|
578
699
|
if (typeof raw === "string") return { ok: true, value: raw };
|
|
579
700
|
if (typeof raw === "number" && Number.isFinite(raw)) return { ok: true, value: String(raw) };
|
|
580
701
|
if (typeof raw === "boolean") return { ok: true, value: String(raw) };
|
|
581
|
-
if (Array.isArray(raw) && raw.every((run) => typeof run === "string" || isRecord(run) && typeof run.text === "string")) return { ok: true, value:
|
|
702
|
+
if (Array.isArray(raw) && raw.every((run) => typeof run === "string" || isRecord(run) && typeof run.text === "string")) return { ok: true, value: clone2(raw) };
|
|
582
703
|
return fail("expected text: a string or an array of text runs");
|
|
583
704
|
}
|
|
584
705
|
case "number": {
|
|
@@ -598,7 +719,7 @@ function coerceVariableValue(kind2, raw) {
|
|
|
598
719
|
}
|
|
599
720
|
case "image": {
|
|
600
721
|
if (typeof raw === "string" && raw.trim()) return { ok: true, value: raw.trim() };
|
|
601
|
-
if (isRecord(raw) && typeof raw.src === "string" && raw.src.trim()) return { ok: true, value:
|
|
722
|
+
if (isRecord(raw) && typeof raw.src === "string" && raw.src.trim()) return { ok: true, value: clone2(raw) };
|
|
602
723
|
return fail("expected an image source: a string or an object with src");
|
|
603
724
|
}
|
|
604
725
|
case "url":
|
|
@@ -744,7 +865,7 @@ function inlineText(effective, format, path, context) {
|
|
|
744
865
|
}
|
|
745
866
|
var DECK_FIELDS = { name: "text", description: "text", author: "text" };
|
|
746
867
|
var SPEAKER_FIELDS = { name: "text", title: "text", email: "text", phone: "text", bio: "text", photo: "image" };
|
|
747
|
-
var ORGANIZATION_FIELDS = { name: "text", legalName: "text", tagline: "text", domain: "text", email: "text", phone: "text"
|
|
868
|
+
var ORGANIZATION_FIELDS = { name: "text", legalName: "text", tagline: "text", domain: "text", email: "text", phone: "text" };
|
|
748
869
|
function isBuiltinName(name) {
|
|
749
870
|
return builtinNamePattern.test(name);
|
|
750
871
|
}
|
|
@@ -768,6 +889,11 @@ function builtinSource(name, doc) {
|
|
|
768
889
|
}
|
|
769
890
|
const parts = name.split(".");
|
|
770
891
|
const root = parts[0];
|
|
892
|
+
if (root === "organization") {
|
|
893
|
+
const logo = parseLogoName(name, doc);
|
|
894
|
+
if (logo && "error" in logo) return { ok: false, message: logo.error };
|
|
895
|
+
if (logo) return { ok: false, message: `'{{${name}}}' is not supported: '${name}' is an image, used only as a whole field, 'var:${name}', which resolves for each slide's background.` };
|
|
896
|
+
}
|
|
771
897
|
const fields2 = builtinFields(root);
|
|
772
898
|
if (root === "deck") {
|
|
773
899
|
const field2 = parts[1];
|
|
@@ -780,6 +906,7 @@ function builtinSource(name, doc) {
|
|
|
780
906
|
return { ok: false, message: `'${name}' is not a built-in variable: '${field}' is not a ${root} field; the fields are ${list(Object.keys(fields2))}.` };
|
|
781
907
|
}
|
|
782
908
|
let entity;
|
|
909
|
+
if (parts.length > 3) return { ok: false, message: `'${name}' is not a built-in variable.` };
|
|
783
910
|
if (parts.length === 2) entity = root === "speaker" ? primarySpeaker(doc) : primaryOrganization(doc);
|
|
784
911
|
else {
|
|
785
912
|
const id = parts[1];
|
|
@@ -864,7 +991,7 @@ function interpolate(text2, path, context) {
|
|
|
864
991
|
});
|
|
865
992
|
return { value, changed };
|
|
866
993
|
}
|
|
867
|
-
var
|
|
994
|
+
var OMIT2 = /* @__PURE__ */ Symbol("omit");
|
|
868
995
|
var Splice = class {
|
|
869
996
|
constructor(values) {
|
|
870
997
|
this.values = values;
|
|
@@ -875,6 +1002,8 @@ function reduceString(text2, path, parentIsArray, context) {
|
|
|
875
1002
|
const reference = referencePattern.exec(text2);
|
|
876
1003
|
if (reference) {
|
|
877
1004
|
const id = reference[1];
|
|
1005
|
+
const logo = id.startsWith("organization.") ? parseLogoName(id, context.doc) : null;
|
|
1006
|
+
if (logo) return reduceLogo(id, logo, path, context);
|
|
878
1007
|
const effective = lookupVariable(id, path, context);
|
|
879
1008
|
if (effective && effective.declaration.kind !== "color") {
|
|
880
1009
|
context.uses.push({ id, path, form: "reference" });
|
|
@@ -883,9 +1012,9 @@ function reduceString(text2, path, parentIsArray, context) {
|
|
|
883
1012
|
}
|
|
884
1013
|
const value = effective.status === "unfilled" ? sampleValue(effective.declaration) : effective.value;
|
|
885
1014
|
if (effective.declaration.kind === "list" && parentIsArray) {
|
|
886
|
-
return context.shape ? { kind: "replace", value: value[0] ?? "" } : { kind: "splice", values:
|
|
1015
|
+
return context.shape ? { kind: "replace", value: value[0] ?? "" } : { kind: "splice", values: clone2(value) };
|
|
887
1016
|
}
|
|
888
|
-
return { kind: "replace", value:
|
|
1017
|
+
return { kind: "replace", value: clone2(value) };
|
|
889
1018
|
}
|
|
890
1019
|
if (effective) {
|
|
891
1020
|
context.uses.push({ id, path, form: "reference" });
|
|
@@ -897,13 +1026,31 @@ function reduceString(text2, path, parentIsArray, context) {
|
|
|
897
1026
|
const result = interpolate(text2, path, context);
|
|
898
1027
|
return result.changed ? { kind: "replace", value: result.value } : { kind: "keep" };
|
|
899
1028
|
}
|
|
1029
|
+
function slideReachable(path) {
|
|
1030
|
+
return path.startsWith("/slides/") || path.startsWith("/design/header/") || path.startsWith("/design/footer/") || path === "/design/logo";
|
|
1031
|
+
}
|
|
1032
|
+
function reduceLogo(id, logo, path, context) {
|
|
1033
|
+
context.uses.push({ id, path, form: "reference" });
|
|
1034
|
+
if ("error" in logo) {
|
|
1035
|
+
diag(context, { code: "variable-unknown-builtin", severity: "error", path, id, message: logo.error }, `ubi:${id}:${path}`);
|
|
1036
|
+
return { kind: "keep" };
|
|
1037
|
+
}
|
|
1038
|
+
const result = resolveOrganizationLogo(context.doc, logo);
|
|
1039
|
+
if (!result.ok) {
|
|
1040
|
+
if (result.reason === "unknown") diag(context, { code: "variable-unknown-builtin", severity: "error", path, id, message: result.message }, `ubi:${id}:${path}`);
|
|
1041
|
+
else diag(context, missingBuiltin(id, path), `bim:${id}:${path}`);
|
|
1042
|
+
}
|
|
1043
|
+
if (slideReachable(path)) return { kind: "keep" };
|
|
1044
|
+
if (result.ok) return { kind: "replace", value: clone2(result.logo.source) };
|
|
1045
|
+
return context.shape ? { kind: "keep" } : { kind: "omit" };
|
|
1046
|
+
}
|
|
900
1047
|
var skippedKeys2 = /* @__PURE__ */ new Set(["extensions"]);
|
|
901
1048
|
var skippedRootKeys = /* @__PURE__ */ new Set(["variables", "catalogs", "$schema", "template"]);
|
|
902
1049
|
function walk(value, path, parentIsArray, context) {
|
|
903
1050
|
if (typeof value === "string") {
|
|
904
1051
|
const reduced = reduceString(value, path, parentIsArray, context);
|
|
905
1052
|
if (reduced.kind === "keep") return value;
|
|
906
|
-
if (reduced.kind === "omit") return
|
|
1053
|
+
if (reduced.kind === "omit") return OMIT2;
|
|
907
1054
|
if (reduced.kind === "splice") return new Splice(reduced.values);
|
|
908
1055
|
return reduced.value;
|
|
909
1056
|
}
|
|
@@ -912,7 +1059,7 @@ function walk(value, path, parentIsArray, context) {
|
|
|
912
1059
|
const out = [];
|
|
913
1060
|
value.forEach((entry, index) => {
|
|
914
1061
|
const next = walk(entry, `${path}/${index}`, true, context);
|
|
915
|
-
if (next ===
|
|
1062
|
+
if (next === OMIT2) {
|
|
916
1063
|
changed = true;
|
|
917
1064
|
return;
|
|
918
1065
|
}
|
|
@@ -935,7 +1082,7 @@ function walk(value, path, parentIsArray, context) {
|
|
|
935
1082
|
continue;
|
|
936
1083
|
}
|
|
937
1084
|
const next = walk(entry, pathFor(path || "/", key), false, context);
|
|
938
|
-
if (next ===
|
|
1085
|
+
if (next === OMIT2) {
|
|
939
1086
|
changed = true;
|
|
940
1087
|
continue;
|
|
941
1088
|
}
|
|
@@ -1131,6 +1278,15 @@ function listBuiltinVariables(presentation) {
|
|
|
1131
1278
|
const available = name !== "slide.section" || slides.some((slide) => isRecord(slide) && typeof slide.section === "string" && slide.section !== "");
|
|
1132
1279
|
out.push({ name, kind: "text", label: SLIDE_SCOPED_LABELS[name], scope: "slide", available, uses: built.context.uses.filter((use) => use.id === name) });
|
|
1133
1280
|
}
|
|
1281
|
+
const logoReferences = [{ reference: {}, label: "Organization" }];
|
|
1282
|
+
for (const entry of organizationsOf(presentation)) if (typeof entry.id === "string" && entry.id !== "") logoReferences.push({ reference: { organization: entry.id }, label: `Organization ${entry.id}` });
|
|
1283
|
+
for (const { reference, label } of logoReferences) {
|
|
1284
|
+
for (const shape of LOGO_SHAPES) {
|
|
1285
|
+
const name = logoReferenceName(reference, shape);
|
|
1286
|
+
const available = resolveOrganizationLogo(presentation, reference, { shape }).ok;
|
|
1287
|
+
out.push({ name, kind: "image", label: `${label} logo${shape === "full" ? "" : ` (${shape})`}`, scope: "slide", available, uses: built.context.uses.filter((use) => use.id === name || shape === "full" && use.id === `${name}.full`) });
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1134
1290
|
return out;
|
|
1135
1291
|
}
|
|
1136
1292
|
|
|
@@ -4108,7 +4264,6 @@ var imagePayload = (host) => {
|
|
|
4108
4264
|
for (const key of IMAGE_OPTION_KEYS) if (host[key] !== void 0) payload[key] = host[key];
|
|
4109
4265
|
return payload;
|
|
4110
4266
|
};
|
|
4111
|
-
var assetSource = (value) => typeof value === "string" ? value : record6(value).src;
|
|
4112
4267
|
var finite = (value, min, max) => typeof value === "number" && Number.isFinite(value) && value >= min && value <= max ? value : void 0;
|
|
4113
4268
|
var pathNumber = (value) => String(round2(value));
|
|
4114
4269
|
var IMAGE_SHAPES = { rectangle: "rect", rounded: "roundRect", circle: "ellipse", hexagon: "hexagon" };
|
|
@@ -4228,45 +4383,6 @@ function resolveBackgroundImage(slide, presentation, themeBackground, width, hei
|
|
|
4228
4383
|
if (aspect) result.picture = fitImage(box, background.fit, aspect, background.focus);
|
|
4229
4384
|
return result;
|
|
4230
4385
|
}
|
|
4231
|
-
var LOGO_LOCKUP_CHAINS = {
|
|
4232
|
-
dark: ["light", "default", "stackedLight", "stacked", "wordmarkLight", "wordmark", "iconLight", "icon", "dark", "stackedDark", "wordmarkDark", "iconDark"],
|
|
4233
|
-
light: ["dark", "default", "stackedDark", "stacked", "wordmarkDark", "wordmark", "iconDark", "icon", "light", "stackedLight", "wordmarkLight", "iconLight"]
|
|
4234
|
-
};
|
|
4235
|
-
var LOGO_SET_KEYS = new Set(LOGO_LOCKUP_CHAINS.dark);
|
|
4236
|
-
function resolveLogo(presentation, slide, options = {}) {
|
|
4237
|
-
const slot = options.slot === "icon" || options.slot === "stacked" ? options.slot : "lockup";
|
|
4238
|
-
if (options.slot !== void 0 && slot !== options.slot) throw new RangeError("Logo slot must be lockup, icon or stacked.");
|
|
4239
|
-
const tone = options.onDark === true ? "dark" : "light";
|
|
4240
|
-
const lockup = LOGO_LOCKUP_CHAINS[tone];
|
|
4241
|
-
const chain = slot === "icon" ? [tone === "dark" ? "iconLight" : "iconDark", "icon", ...lockup] : slot === "stacked" ? [tone === "dark" ? "stackedLight" : "stackedDark", "stacked", ...lockup] : lockup;
|
|
4242
|
-
const usable = (value) => {
|
|
4243
|
-
const source = assetSource(value);
|
|
4244
|
-
return typeof source === "string" && source.length > 0;
|
|
4245
|
-
};
|
|
4246
|
-
const pick = (value, path) => {
|
|
4247
|
-
if (value === void 0 || value === null || value === false) return null;
|
|
4248
|
-
if (typeof value === "string" || typeof value === "object" && !Array.isArray(value) && "src" in record6(value)) {
|
|
4249
|
-
return usable(value) ? { source: value, path, variant: "default", slot } : null;
|
|
4250
|
-
}
|
|
4251
|
-
const set2 = record6(value);
|
|
4252
|
-
if (!Object.keys(set2).some((key) => LOGO_SET_KEYS.has(key))) return null;
|
|
4253
|
-
for (const key of chain) {
|
|
4254
|
-
const variant = set2[key];
|
|
4255
|
-
if (variant !== void 0 && usable(variant)) return { source: variant, path: `${path}.${key}`, variant: key, slot };
|
|
4256
|
-
}
|
|
4257
|
-
return null;
|
|
4258
|
-
};
|
|
4259
|
-
const deck = record6(presentation), slideIndex = Number.isSafeInteger(options.slideIndex) && options.slideIndex >= 0 ? options.slideIndex : 0;
|
|
4260
|
-
const own2 = pick(record6(record6(slide).design).logo, `slides.${slideIndex}.design.logo`);
|
|
4261
|
-
if (own2) return own2;
|
|
4262
|
-
const shared = pick(record6(deck.design).logo, "design.logo");
|
|
4263
|
-
if (shared) return shared;
|
|
4264
|
-
const organizations = Array.isArray(deck.organization) ? deck.organization : [deck.organization];
|
|
4265
|
-
const primaryIndex = organizations.findIndex((item) => record6(item).role === "primary");
|
|
4266
|
-
const index = primaryIndex >= 0 ? primaryIndex : organizations.findIndex(Boolean);
|
|
4267
|
-
if (index < 0) return null;
|
|
4268
|
-
return pick(record6(organizations[index]).logo, Array.isArray(deck.organization) ? `organization.${index}.logo` : "organization.logo");
|
|
4269
|
-
}
|
|
4270
4386
|
var webUrl = /^https?:\/\/\S+$/i;
|
|
4271
4387
|
function resolveSocialProfile(platform, value, owner = "organization") {
|
|
4272
4388
|
const raw = String(value).trim().replace(/\s+/gu, " ");
|
|
@@ -4282,6 +4398,17 @@ function resolveSocialProfile(platform, value, owner = "organization") {
|
|
|
4282
4398
|
if (!webUrl.test(url)) return { text: raw, resolved: false };
|
|
4283
4399
|
return { text: display(url), href: encodeURI(url), resolved: true };
|
|
4284
4400
|
}
|
|
4401
|
+
var FURNITURE_GAP = 12;
|
|
4402
|
+
var FURNITURE_IMAGE_SHARE = 0.4;
|
|
4403
|
+
var SPACED_WORD_CHARACTER = /^[\p{L}\p{N}\p{M}]$/u;
|
|
4404
|
+
var UNSPACED_SCRIPT = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Thai}\p{Script=Lao}\p{Script=Khmer}\p{Script=Myanmar}\p{Script=Tibetan}]/u;
|
|
4405
|
+
function breaksInsideWord(text2, fit) {
|
|
4406
|
+
return fit.sourceLines.some((line) => {
|
|
4407
|
+
if (line.boundary !== "soft" || line.nextStart <= 0 || line.nextStart >= text2.length) return false;
|
|
4408
|
+
const before = [...text2.slice(0, line.nextStart)].at(-1) ?? "", after = [...text2.slice(line.nextStart, line.nextStart + 2)][0] ?? "";
|
|
4409
|
+
return SPACED_WORD_CHARACTER.test(before) && SPACED_WORD_CHARACTER.test(after) && !UNSPACED_SCRIPT.test(before) && !UNSPACED_SCRIPT.test(after);
|
|
4410
|
+
});
|
|
4411
|
+
}
|
|
4285
4412
|
function layoutFurniture(input, options = {}) {
|
|
4286
4413
|
const slide = record6(input), width = options.width ?? 1280, height = options.height ?? 720, scale = Math.min(width, height) / 720;
|
|
4287
4414
|
const settings = { ...record6(record6(options.layout).composition), ...record6(slide.composition) };
|
|
@@ -4296,8 +4423,8 @@ function layoutFurniture(input, options = {}) {
|
|
|
4296
4423
|
if (options.date !== void 0 && (typeof options.date !== "string" || !parseIsoDate(options.date))) throw new RangeError("The furniture date option must be an ISO YYYY-MM-DD calendar date.");
|
|
4297
4424
|
const outlines = options.textMeasurement?.outlineBounds !== void 0, parts = [], diagnostics = [];
|
|
4298
4425
|
const sourceRoot = `slides.${options.slideIndex ?? 0}`, organizations = Array.isArray(options.presentation?.organization) ? options.presentation.organization : [options.presentation?.organization];
|
|
4299
|
-
const primaryIndex = organizations.findIndex((item) => record6(item).role === "primary"),
|
|
4300
|
-
const organization = record6(organizations[
|
|
4426
|
+
const primaryIndex = organizations.findIndex((item) => record6(item).role === "primary"), organizationIndex2 = primaryIndex >= 0 ? primaryIndex : organizations.findIndex(Boolean);
|
|
4427
|
+
const organization = record6(organizations[organizationIndex2]), organizationRoot = Array.isArray(options.presentation?.organization) ? `organization.${organizationIndex2}` : "organization";
|
|
4301
4428
|
const fontFamily = options.fontFamilies?.body ?? "sans-serif";
|
|
4302
4429
|
let headerBottom = 0, footerTop = height, configured = false;
|
|
4303
4430
|
const error = (path, message, code = "text-overflow") => diagnostics.push({ code, path, message });
|
|
@@ -4310,58 +4437,27 @@ function layoutFurniture(input, options = {}) {
|
|
|
4310
4437
|
const zones = [];
|
|
4311
4438
|
for (const [index, zone] of ["left", "center", "right"].entries()) {
|
|
4312
4439
|
const side = furnitureRtl && zone !== "center" ? zone === "left" ? "right" : "left" : zone;
|
|
4313
|
-
const content = record6(record6(value)[zone]), path = `${root}.${zone}`, x = width * (0.07 + (furnitureRtl ? 2 - index : index) * 0.3), zoneWidth = width * 0.26
|
|
4314
|
-
|
|
4440
|
+
const content = record6(record6(value)[zone]), path = `${root}.${zone}`, x = width * (0.07 + (furnitureRtl ? 2 - index : index) * 0.3), zoneWidth = width * 0.26;
|
|
4441
|
+
const pending = [];
|
|
4315
4442
|
const add = (field, text2, generated = false, sourcePath, extras = {}) => {
|
|
4316
4443
|
if (text2 === void 0) return;
|
|
4317
4444
|
if (typeof text2 !== "string") throw new TypeError(`Furniture field ${path}.${field} requires string content.`);
|
|
4318
|
-
const partPath = `${path}.${field}
|
|
4319
|
-
|
|
4320
|
-
const ink = fit.sourceLines.map((line, index2) => {
|
|
4321
|
-
let outline = null;
|
|
4322
|
-
if (outlines) {
|
|
4323
|
-
for (const segment2 of line.segments) if (segment2.kind === "text") {
|
|
4324
|
-
const bounds = measureTextOutline(text2.slice(segment2.start, segment2.end), size, style, options.textMeasurement);
|
|
4325
|
-
if (bounds) {
|
|
4326
|
-
const next = { ...bounds, x: bounds.x + segment2.x };
|
|
4327
|
-
if (!outline) outline = next;
|
|
4328
|
-
else {
|
|
4329
|
-
const right = Math.max(outline.x + outline.width, next.x + next.width), bottom = Math.max(outline.y + outline.height, next.y + next.height);
|
|
4330
|
-
outline.x = Math.min(outline.x, next.x);
|
|
4331
|
-
outline.y = Math.min(outline.y, next.y);
|
|
4332
|
-
outline.width = right - outline.x;
|
|
4333
|
-
outline.height = bottom - outline.y;
|
|
4334
|
-
}
|
|
4335
|
-
}
|
|
4336
|
-
}
|
|
4337
|
-
}
|
|
4338
|
-
return { width: line.width, y: index2 * fit.lineHeight, baseline: size + index2 * fit.lineHeight, height: fit.lineHeight, outline };
|
|
4339
|
-
});
|
|
4340
|
-
const natural = outlines ? placeTextLines(ink, { x, y, width: zoneWidth, height: Number.MAX_VALUE }, side, padding) : void 0;
|
|
4341
|
-
const partHeight = natural?.height ?? fit.sourceLines.length * fit.lineHeight;
|
|
4342
|
-
if (!Number.isFinite(partHeight)) throw new RangeError("Furniture exceeds finite layout coordinates.");
|
|
4343
|
-
const box = { x, y, width: zoneWidth, height: Math.max(scale, partHeight) }, placement = outlines ? placeTextLines(ink, box, side, padding) : void 0;
|
|
4344
|
-
const accepted = { ...fit, ...placement ? { placement } : {}, overflow: fit.overflow || !!placement?.overflow };
|
|
4345
|
-
zoneParts.push({ type: "text", kind: kind2, zone, field, path: partPath, sourcePath: sourcePath ?? (!generated ? partPath : void 0), generated, text: text2, style, requestedFontSize: size, minFontSize: minimum, box, alignment: side, fit: accepted, ...extras.fields?.length ? { fields: extras.fields } : {}, ...extras.links?.length ? { links: extras.links } : {} });
|
|
4346
|
-
if (accepted.overflow) error(partPath, "Repeated text exceeds its zone at the selected readability floor; change the furniture or slide design.");
|
|
4347
|
-
y += box.height;
|
|
4445
|
+
const partPath = `${path}.${field}`;
|
|
4446
|
+
pending.push({ type: "text", field, text: text2, generated, sourcePath: sourcePath ?? (!generated ? partPath : void 0), extras, partPath, style: resolveTextStyle({ fontFamily, fontWeight: 400, italic: false, path: partPath }, options.textMeasurement) });
|
|
4348
4447
|
};
|
|
4349
|
-
const
|
|
4448
|
+
const addImage = (source, sourcePath, reference) => {
|
|
4350
4449
|
const imageHeight = Math.max(32 * scale, Math.min(height * 0.05, 72 * scale)), imageWidth = Math.min(zoneWidth, imageHeight * (intrinsicImageAspect(source, record6(options.presentation).assets) ?? 1));
|
|
4351
|
-
|
|
4450
|
+
pending.push({ type: "image", sourcePath, image: source, ...reference !== void 0 ? { reference } : {}, width: imageWidth, height: imageHeight });
|
|
4352
4451
|
};
|
|
4353
|
-
if (content.logo === true) {
|
|
4354
|
-
const resolved = resolveLogo(options.presentation, slide, { slot: "icon", onDark: options.darkBackground, slideIndex: options.slideIndex });
|
|
4355
|
-
if (resolved) {
|
|
4356
|
-
const box = imageBox(resolved.source);
|
|
4357
|
-
zoneParts.push({ type: "image", kind: kind2, zone, field: "logo", path: `${path}.logo`, sourcePath: resolved.path, generated: true, image: resolved.source, box, alignment: side });
|
|
4358
|
-
y += box.height;
|
|
4359
|
-
} else error(`${path}.logo`, "Generated logo needs design.logo or a primary organization logo.", "unresolved-content");
|
|
4360
|
-
}
|
|
4361
4452
|
if (content.image !== void 0) {
|
|
4362
|
-
const
|
|
4363
|
-
|
|
4364
|
-
|
|
4453
|
+
const logo = typeof content.image === "string" && content.image.startsWith("var:organization.") ? parseLogoName(content.image, options.presentation) : null;
|
|
4454
|
+
if (!logo) addImage(content.image, `${path}.image`);
|
|
4455
|
+
else if ("error" in logo) error(`${path}.image`, logo.error, "unresolved-content");
|
|
4456
|
+
else {
|
|
4457
|
+
const resolved = resolveOrganizationLogo(options.presentation, logo, { onDark: options.darkBackground === true });
|
|
4458
|
+
if (resolved.ok) addImage(resolved.logo.source, resolved.logo.path, content.image);
|
|
4459
|
+
else error(`${path}.image`, `${resolved.message} Give the organization a logo, or change the zone image.`, "unresolved-content");
|
|
4460
|
+
}
|
|
4365
4461
|
}
|
|
4366
4462
|
if (typeof content.text === "string") {
|
|
4367
4463
|
const resolved = substituteSlideTokens(content.text, { slideNumber: number, ...slideCount !== void 0 ? { slideCount } : {}, section: slide.section });
|
|
@@ -4390,9 +4486,71 @@ function layoutFurniture(input, options = {}) {
|
|
|
4390
4486
|
else add("date", resolved.text, true, `${path}.date`);
|
|
4391
4487
|
}
|
|
4392
4488
|
}
|
|
4489
|
+
const fitPart = (part, boxWidth) => {
|
|
4490
|
+
const fit = fitText(part.text, { width: Math.max(Number.MIN_VALUE, boxWidth - (outlines ? 2 * padding : 0)), height: Number.MAX_VALUE }, size, size, textWidthMeasurer(part.style, options.textMeasurement));
|
|
4491
|
+
const ink = fit.sourceLines.map((line, index2) => {
|
|
4492
|
+
let outline = null;
|
|
4493
|
+
if (outlines) {
|
|
4494
|
+
for (const segment2 of line.segments) if (segment2.kind === "text") {
|
|
4495
|
+
const bounds = measureTextOutline(part.text.slice(segment2.start, segment2.end), size, part.style, options.textMeasurement);
|
|
4496
|
+
if (bounds) {
|
|
4497
|
+
const next = { ...bounds, x: bounds.x + segment2.x };
|
|
4498
|
+
if (!outline) outline = next;
|
|
4499
|
+
else {
|
|
4500
|
+
const right = Math.max(outline.x + outline.width, next.x + next.width), bottom = Math.max(outline.y + outline.height, next.y + next.height);
|
|
4501
|
+
outline.x = Math.min(outline.x, next.x);
|
|
4502
|
+
outline.y = Math.min(outline.y, next.y);
|
|
4503
|
+
outline.width = right - outline.x;
|
|
4504
|
+
outline.height = bottom - outline.y;
|
|
4505
|
+
}
|
|
4506
|
+
}
|
|
4507
|
+
}
|
|
4508
|
+
}
|
|
4509
|
+
return { width: line.width, y: index2 * fit.lineHeight, baseline: size + index2 * fit.lineHeight, height: fit.lineHeight, outline };
|
|
4510
|
+
});
|
|
4511
|
+
const natural = outlines ? placeTextLines(ink, { x: 0, y: 0, width: boxWidth, height: Number.MAX_VALUE }, side, padding) : void 0;
|
|
4512
|
+
const partHeight = natural?.height ?? fit.sourceLines.length * fit.lineHeight;
|
|
4513
|
+
if (!Number.isFinite(partHeight)) throw new RangeError("Furniture exceeds finite layout coordinates.");
|
|
4514
|
+
return { fit, ink, height: Math.max(scale, partHeight) };
|
|
4515
|
+
};
|
|
4516
|
+
const gap = FURNITURE_GAP * scale, gaps = gap * Math.max(0, pending.length - 1);
|
|
4517
|
+
const widths = pending.map((part) => part.type === "image" ? pending.length > 1 ? Math.min(part.width, zoneWidth * FURNITURE_IMAGE_SHARE) : part.width : pending.length === 1 ? zoneWidth : Math.max(scale, ...fitPart(part, 1e7).ink.map((line) => Math.max(line.width + (outlines ? 2 * padding : 0), line.outline ? line.outline.width + 2 * padding : 0))));
|
|
4518
|
+
if (pending.length > 1 && widths.reduce((sum, entry) => sum + entry, 0) + gaps > zoneWidth + 0.01) {
|
|
4519
|
+
const texts = pending.map((_, index2) => index2).filter((index2) => pending[index2].type === "text").sort((a, b) => widths[a] - widths[b]);
|
|
4520
|
+
let remaining = zoneWidth - gaps - pending.reduce((sum, part, index2) => sum + (part.type === "image" ? widths[index2] : 0), 0), count = texts.length;
|
|
4521
|
+
if (remaining < scale * Math.max(1, count)) error(path, `The parts of this zone (${pending.map((part) => part.type === "image" ? "image" : part.field).join(", ")}) are wider side by side than the zone; remove a part or move one to another zone.`);
|
|
4522
|
+
for (const index2 of texts) {
|
|
4523
|
+
const share = Math.max(scale, remaining / count);
|
|
4524
|
+
widths[index2] = Math.min(widths[index2], share);
|
|
4525
|
+
remaining -= widths[index2];
|
|
4526
|
+
count--;
|
|
4527
|
+
}
|
|
4528
|
+
}
|
|
4529
|
+
const measured = pending.map((part, index2) => part.type === "image" ? { part, width: widths[index2], height: part.height } : { part, width: widths[index2], ...fitPart(part, widths[index2]) });
|
|
4530
|
+
const row = Math.max(0, ...measured.map((entry) => entry.height));
|
|
4531
|
+
const total = measured.reduce((sum, entry) => sum + entry.width, 0) + gaps;
|
|
4532
|
+
let cursor = side === "left" || total > zoneWidth + 0.01 ? x : side === "center" ? x + (zoneWidth - total) / 2 : x + zoneWidth - total;
|
|
4533
|
+
const placed = /* @__PURE__ */ new Map();
|
|
4534
|
+
for (const index2 of furnitureRtl ? [...measured.keys()].reverse() : [...measured.keys()]) {
|
|
4535
|
+
placed.set(index2, cursor);
|
|
4536
|
+
cursor += measured[index2].width + gap;
|
|
4537
|
+
}
|
|
4538
|
+
const zoneParts = measured.map((entry, index2) => {
|
|
4539
|
+
const box = { x: placed.get(index2), y: (row - entry.height) / 2, width: entry.width, height: entry.height };
|
|
4540
|
+
if (entry.part.type === "image") {
|
|
4541
|
+
const part2 = entry.part;
|
|
4542
|
+
return { type: "image", kind: kind2, zone, field: "image", path: `${path}.image`, sourcePath: part2.sourcePath, generated: false, image: part2.image, ...part2.reference !== void 0 ? { reference: part2.reference } : {}, box, alignment: side };
|
|
4543
|
+
}
|
|
4544
|
+
const part = entry.part, { fit, ink } = entry;
|
|
4545
|
+
const placement = outlines ? placeTextLines(ink, box, side, padding) : void 0;
|
|
4546
|
+
const accepted = { ...fit, ...placement ? { placement } : {}, overflow: fit.overflow || !!placement?.overflow };
|
|
4547
|
+
if (accepted.overflow) error(part.partPath, "Repeated text exceeds its zone at the selected readability floor; change the furniture or slide design.");
|
|
4548
|
+
else if (pending.length > 1 && breaksInsideWord(part.text, fit)) error(part.partPath, "A word of this repeated text is wider than its share of the zone row at the selected readability floor and would break inside the word; shorten the text, move a part to another zone, or widen the canvas.");
|
|
4549
|
+
return { type: "text", kind: kind2, zone, field: part.field, path: part.partPath, ...part.sourcePath !== void 0 ? { sourcePath: part.sourcePath } : {}, generated: part.generated, text: part.text, style: part.style, requestedFontSize: size, minFontSize: minimum, box, alignment: side, fit: accepted, ...part.extras.fields?.length ? { fields: part.extras.fields } : {}, ...part.extras.links?.length ? { links: part.extras.links } : {} };
|
|
4550
|
+
});
|
|
4393
4551
|
zones.push(zoneParts);
|
|
4394
4552
|
}
|
|
4395
|
-
const tallest = Math.max(0, ...zones.
|
|
4553
|
+
const tallest = Math.max(0, ...zones.flat().map((part) => part.box.y + part.box.height));
|
|
4396
4554
|
if (!tallest) continue;
|
|
4397
4555
|
const top = kind2 === "header" ? height * 0.025 : Math.max(height * 0.025, height - height * 0.04 - tallest);
|
|
4398
4556
|
if (kind2 === "header") headerBottom = top + tallest;
|
|
@@ -4522,13 +4680,13 @@ function layoutQuote(value, box, options = {}) {
|
|
|
4522
4680
|
path
|
|
4523
4681
|
) : void 0;
|
|
4524
4682
|
const footerRequested = attribution?.requestedFontSize ?? gridFontSize(17 * scale, minimum);
|
|
4525
|
-
const
|
|
4526
|
-
const fit = (part, area, size = part.requestedFontSize, floor = minimum) => !
|
|
4683
|
+
const usable2 = (area) => [area.x, area.y, area.width, area.height].every(Number.isFinite) && area.width > 0 && area.height > 0;
|
|
4684
|
+
const fit = (part, area, size = part.requestedFontSize, floor = minimum) => !usable2(area) ? void 0 : part.runs ? fitRichText(part.runs, area, size, floor, { style: part.style, textMeasurement: options.textMeasurement, ...options.citationMarker ? { citationMarker: options.citationMarker } : {}, ...options.direction ? { direction: options.direction } : {} }) : fitText(part.text, area, size, floor, textWidthMeasurer(part.style, options.textMeasurement), options.direction);
|
|
4527
4685
|
const heightOf = (fit2) => "richLines" in fit2 ? fit2.height : fit2.lines.length * fit2.lineHeight;
|
|
4528
4686
|
const inner = { x: box.x + 18, y: box.y + 18, width: box.width - 36, height: box.height - 36 };
|
|
4529
4687
|
let photo, photoFits = true;
|
|
4530
4688
|
if (!hasBlock) body.fit = fit(body, body.box);
|
|
4531
|
-
else if (
|
|
4689
|
+
else if (usable2(inner) && inner.height > 18) {
|
|
4532
4690
|
const available = inner.height - 18;
|
|
4533
4691
|
const preferredBody = fit(body, inner, body.requestedFontSize, body.requestedFontSize);
|
|
4534
4692
|
const minimumBody = body.requestedFontSize === minimum ? preferredBody : fit(body, inner, minimum, minimum);
|
|
@@ -4550,8 +4708,8 @@ function layoutQuote(value, box, options = {}) {
|
|
|
4550
4708
|
const bodyFit = fit(body, bodyBox);
|
|
4551
4709
|
const photoBox = hasPhoto ? { x: rtl ? inner.x + inner.width - diameter : inner.x, y: footerBox.y + (footerHeight - diameter) / 2, width: diameter, height: diameter } : void 0;
|
|
4552
4710
|
const textBox = attribution ? hasPhoto ? { ...textArea, y: footerBox.y + Math.max(0, footerHeight - naturalHeight) / 2, height: Math.min(naturalHeight, footerHeight) } : footerBox : void 0;
|
|
4553
|
-
const footerFit = attribution && natural &&
|
|
4554
|
-
const fitsPhoto = !hasPhoto || diameter <= footerHeight + 0.01 && (!attribution ||
|
|
4711
|
+
const footerFit = attribution && natural && usable2(footerBox) ? { ...natural, overflow: natural.overflow || naturalHeight > footerHeight + 0.01 } : void 0;
|
|
4712
|
+
const fitsPhoto = !hasPhoto || diameter <= footerHeight + 0.01 && (!attribution || usable2(textArea));
|
|
4555
4713
|
const overflow = !bodyFit || bodyFit.overflow || (attribution ? !footerFit || footerFit.overflow : false) || !fitsPhoto;
|
|
4556
4714
|
const score = (body.requestedFontSize - (bodyFit?.fontSize ?? minimum) + footerRequested - size) / scale;
|
|
4557
4715
|
if (!selected || !overflow && (selected.overflow || score < selected.score) || overflow && selected.overflow) {
|
|
@@ -4577,7 +4735,7 @@ function layoutQuote(value, box, options = {}) {
|
|
|
4577
4735
|
} else if (part.fit.overflow) {
|
|
4578
4736
|
report("text-fit", part.path, [part.role], `Quote ${part.role} exceeds its available space at the readability floor; increase its space or change the arrangement.`);
|
|
4579
4737
|
}
|
|
4580
|
-
if (
|
|
4738
|
+
if (usable2(area) && (area.x < box.x || area.y < box.y || area.x + area.width > box.x + box.width + 0.01 || area.y + area.height > box.y + box.height + 0.01)) {
|
|
4581
4739
|
report("part-outside-cell", part.path, [part.role], `Quote ${part.role} extends outside its cell; increase the cell size or change the arrangement.`);
|
|
4582
4740
|
}
|
|
4583
4741
|
}
|
|
@@ -4632,7 +4790,7 @@ function layoutMetric(value, box, options = {}) {
|
|
|
4632
4790
|
const primary = parts[0], metadata = parts.filter((part) => part !== primary && part.visible), unit = metadata.find((part) => part.role === "unit");
|
|
4633
4791
|
const metricDirection = options.direction === "rtl" ? paragraphDirection(["label", "description", "unit"].map((role) => parts.find((part) => part.role === role)?.text).find(Boolean) ?? primary.text, "rtl") : void 0;
|
|
4634
4792
|
const alignment = physicalAlignment(requestedAlignment, metricDirection);
|
|
4635
|
-
const
|
|
4793
|
+
const usable2 = (area) => [area.x, area.y, area.width, area.height, area.x + area.width, area.y + area.height].every(Number.isFinite) && area.width > 0 && area.height > 0;
|
|
4636
4794
|
const occupied = (fit) => fit.placement?.height ?? fit.lines.length * fit.lineHeight;
|
|
4637
4795
|
const gap = 8 * scale, primaryGap = 12 * scale;
|
|
4638
4796
|
const lineInk = (part, fit) => fit.sourceLines.map((line, index) => {
|
|
@@ -4676,7 +4834,7 @@ function layoutMetric(value, box, options = {}) {
|
|
|
4676
4834
|
return fit;
|
|
4677
4835
|
};
|
|
4678
4836
|
const fitValue = (area, singleLine) => {
|
|
4679
|
-
if (!
|
|
4837
|
+
if (!usable2(area)) return void 0;
|
|
4680
4838
|
for (let step = 0; step <= 76; step++) {
|
|
4681
4839
|
const size = gridFontSize(primary.requestedFontSize - step * scale, minimum);
|
|
4682
4840
|
const natural = measure(primary, size, area.width);
|
|
@@ -4717,7 +4875,7 @@ function layoutMetric(value, box, options = {}) {
|
|
|
4717
4875
|
allocations.push({ part, box: { ...box, y, height }, fit: { ...natural, overflow: !!natural.placement?.overflow || natural.sourceLines.some((line) => line.width > box.width + 0.01) } });
|
|
4718
4876
|
y += height + gap;
|
|
4719
4877
|
}
|
|
4720
|
-
const overflow = !valueFit || valueFit.overflow || arrangement === "inline-unit" && valueFit.lines.length !== 1 || primaryHeight > area.height + 0.01 || allocations.some(({ box: area2, fit }) => !fit || fit.overflow || !
|
|
4878
|
+
const overflow = !valueFit || valueFit.overflow || arrangement === "inline-unit" && valueFit.lines.length !== 1 || primaryHeight > area.height + 0.01 || allocations.some(({ box: area2, fit }) => !fit || fit.overflow || !usable2(area2) || area2.y + area2.height > box.y + box.height + 0.01);
|
|
4721
4879
|
const score = allocations.reduce((sum, { part, fit }) => sum + (part.requestedFontSize - (fit?.fontSize ?? minimum)) / scale, 0);
|
|
4722
4880
|
const candidate = { arrangement, allocations, score, overflow };
|
|
4723
4881
|
if (!selected || !overflow && (selected.overflow || score < selected.score) || overflow && selected.overflow) selected = candidate;
|
|
@@ -4745,9 +4903,9 @@ function layoutMetric(value, box, options = {}) {
|
|
|
4745
4903
|
}
|
|
4746
4904
|
const report = (reason, part, roles, message) => diagnostics.push({ code: "text-overflow", reason, path: part.path, parts: roles, message });
|
|
4747
4905
|
for (const part of parts.filter((part2) => part2.visible)) {
|
|
4748
|
-
if (!part.fit || !
|
|
4906
|
+
if (!part.fit || !usable2(part.box)) report("invalid-part-box", part, [part.role], `Metric ${part.role} has no usable space after metadata; increase the cell or change the arrangement.`);
|
|
4749
4907
|
else if (part.fit.overflow) report("text-fit", part, [part.role], `Metric ${part.role} exceeds its space at the readability floor; increase the cell or change the arrangement.`);
|
|
4750
|
-
if (
|
|
4908
|
+
if (usable2(part.box) && (part.box.x < box.x || part.box.y < box.y || part.box.x + part.box.width > box.x + box.width + 0.01 || part.box.y + part.box.height > box.y + box.height + 0.01)) {
|
|
4751
4909
|
report("part-outside-cell", part, [part.role], `Metric ${part.role} extends outside its cell; increase the cell or change the arrangement.`);
|
|
4752
4910
|
}
|
|
4753
4911
|
}
|
|
@@ -5019,9 +5177,9 @@ function layoutCode(value, box, options = {}) {
|
|
|
5019
5177
|
if (code.language) add("language", code.language, `${path}.language`);
|
|
5020
5178
|
if (!parts.length) add("language", "code", path, true);
|
|
5021
5179
|
const body = add("body", code.source, shorthand ? path : `${path}.source`), headers = parts.filter((part) => part !== body);
|
|
5022
|
-
const
|
|
5023
|
-
const fit = (part, area, size = part.requestedFontSize, floor = minimum) =>
|
|
5024
|
-
if (
|
|
5180
|
+
const usable2 = (area) => [area.x, area.y, area.width, area.height].every(Number.isFinite) && area.width > 0 && area.height > 0;
|
|
5181
|
+
const fit = (part, area, size = part.requestedFontSize, floor = minimum) => usable2(area) ? fitCodeText(part.text, area, size, floor, scale, textWidthMeasurer(part.style, options.textMeasurement)) : void 0;
|
|
5182
|
+
if (usable2(inner)) {
|
|
5025
5183
|
const combinations = headers.reduce((choices, part) => choices.flatMap((choice) => [.../* @__PURE__ */ new Set([part.requestedFontSize, minimum])].map((size) => [...choice, { part, size }])), [[]]);
|
|
5026
5184
|
let selected;
|
|
5027
5185
|
for (const combination of combinations) {
|
|
@@ -5030,12 +5188,12 @@ function layoutCode(value, box, options = {}) {
|
|
|
5030
5188
|
for (const [index, { part, size }] of combination.entries()) {
|
|
5031
5189
|
const measured = fitCodeText(part.text, inner, size, size, scale, textWidthMeasurer(part.style, options.textMeasurement));
|
|
5032
5190
|
const area2 = { ...inner, y, height: measured.lines.length * measured.lineHeight };
|
|
5033
|
-
allocations.push({ part, box: area2, fit:
|
|
5191
|
+
allocations.push({ part, box: area2, fit: usable2(area2) ? { ...measured, overflow: measured.sourceLines.some((line) => line.width > area2.width + 0.01) } : void 0 });
|
|
5034
5192
|
y += area2.height + (index < headers.length - 1 ? 8 : 12);
|
|
5035
5193
|
}
|
|
5036
5194
|
const area = { ...inner, y, height: inner.y + inner.height - y };
|
|
5037
5195
|
allocations.push({ part: body, box: area, fit: fit(body, area) });
|
|
5038
|
-
const overflow = allocations.some(({ box: box2, fit: fit2 }) => !fit2 || fit2.overflow || !
|
|
5196
|
+
const overflow = allocations.some(({ box: box2, fit: fit2 }) => !fit2 || fit2.overflow || !usable2(box2) || box2.y + box2.height > inner.y + inner.height + 0.01);
|
|
5039
5197
|
const score = allocations.reduce((sum, { part, fit: fit2 }) => sum + (part.requestedFontSize - (fit2?.fontSize ?? minimum)) / scale, 0);
|
|
5040
5198
|
if (!selected || !overflow && (selected.overflow || score < selected.score) || overflow && selected.overflow) selected = { allocations, score, overflow };
|
|
5041
5199
|
}
|
|
@@ -5049,7 +5207,7 @@ function layoutCode(value, box, options = {}) {
|
|
|
5049
5207
|
if (!part.fit) report("invalid-part-box", part, [part.role], `Code ${part.role} has no usable space after metadata and insets; increase the cell or change the arrangement.`);
|
|
5050
5208
|
else if (part.fit.overflow) report("text-fit", part, [part.role], `Code ${part.role} exceeds its space at the readability floor; increase its space or change the arrangement.`);
|
|
5051
5209
|
const area = part.box;
|
|
5052
|
-
if (
|
|
5210
|
+
if (usable2(area) && (area.x < box.x || area.y < box.y || area.x + area.width > box.x + box.width + 0.01 || area.y + area.height > box.y + box.height + 0.01)) {
|
|
5053
5211
|
report("part-outside-cell", part, [part.role], `Code ${part.role} extends outside its cell; increase the cell or change the arrangement.`);
|
|
5054
5212
|
}
|
|
5055
5213
|
}
|
|
@@ -5434,7 +5592,7 @@ function composeSlide(input, options = {}) {
|
|
|
5434
5592
|
}, options.textMeasurement);
|
|
5435
5593
|
const listBullet = hints.listBullet !== void 0 ? { value: hints.listBullet, path: hints.paths.listBullet } : void 0;
|
|
5436
5594
|
const bulletImage = listBullet?.value === "image" ? (() => {
|
|
5437
|
-
const resolved = resolveLogo(options.presentation, slide, {
|
|
5595
|
+
const resolved = resolveLogo(options.presentation, slide, { shape: "icon", onDark: options.darkBackground, slideIndex: options.slideIndex });
|
|
5438
5596
|
return resolved ? { source: resolved.source, path: resolved.path } : void 0;
|
|
5439
5597
|
})() : void 0;
|
|
5440
5598
|
const widthFor = (field, path2) => textWidthMeasurer(styleFor(field, path2), options.textMeasurement);
|
|
@@ -5549,12 +5707,12 @@ function composeSlide(input, options = {}) {
|
|
|
5549
5707
|
coverGroup = isCover;
|
|
5550
5708
|
let logo;
|
|
5551
5709
|
if (isCover) {
|
|
5552
|
-
const resolved = resolveLogo(options.presentation, slide, {
|
|
5710
|
+
const resolved = resolveLogo(options.presentation, slide, { shape: "full", onDark: options.darkBackground, slideIndex: options.slideIndex });
|
|
5553
5711
|
if (resolved) {
|
|
5554
5712
|
const logoHeight = 56 * scale;
|
|
5555
5713
|
const logoWidth = Math.max(scale, Math.min(4 * logoHeight, area.right - area.left - 2 * padding));
|
|
5556
5714
|
const box = { x: round2(rtl ? area.right - padding - logoWidth : area.left + padding), y: round2(headingTop), width: round2(logoWidth), height: round2(logoHeight) };
|
|
5557
|
-
logo = { box,
|
|
5715
|
+
logo = { box, shape: resolved.shape, path: resolved.path, source: resolved.source, variant: resolved.variant, reference: resolved.reference, anchor: rtl ? "right" : "left" };
|
|
5558
5716
|
}
|
|
5559
5717
|
}
|
|
5560
5718
|
let y = logo ? logo.box.y + logo.box.height + gap : headingTop;
|
|
@@ -5891,7 +6049,7 @@ function composeSlide(input, options = {}) {
|
|
|
5891
6049
|
slots.sort((a, b) => order.get(a.path) - order.get(b.path));
|
|
5892
6050
|
} else arrange(pending, contentBox, rootSettings, composition.mode ? 0 : placeholders.length);
|
|
5893
6051
|
if (listBullet?.value === "image" && !bulletImage && items.some((item) => (item.field === "items" || item.field === "bullets") && item.payload.numbering === void 0)) {
|
|
5894
|
-
diagnostics.push({ code: "unresolved-content", path: listBullet.path, message: "Picture bullets (listBullet: image) need
|
|
6052
|
+
diagnostics.push({ code: "unresolved-content", path: listBullet.path, message: "Picture bullets (listBullet: image) need an organization logo (the primary organization, or the one design.logo names); the marker glyph is drawn instead." });
|
|
5895
6053
|
}
|
|
5896
6054
|
const numberingDiagnostics = [];
|
|
5897
6055
|
for (const item of items) {
|
|
@@ -5953,4 +6111,4 @@ function resolveCanvasDimensions(input) {
|
|
|
5953
6111
|
return { width, height };
|
|
5954
6112
|
}
|
|
5955
6113
|
|
|
5956
|
-
export { CAPTIONABLE_FIELDS, CAPTION_FONT_RATIO, CAPTION_MAX_RATIO, CHART_HIGHLIGHT_MUTED_MIN_CONTRAST, CHART_HIGHLIGHT_MUTED_MIX, CHART_SERIES_MIN_DIFFERENCE, CHART_SERIES_MIN_LIGHTNESS_STEP, CHART_TYPES, CITATION_MARKER_RAISE, CITATION_MARKER_SCALE, CODE_HIGHLIGHT_LANGUAGES, CODE_HIGHLIGHT_MAX_LENGTH, CODE_PANEL_BACKGROUND, CODE_PANEL_FOREGROUND, CODE_SYNTAX_MIN_CONTRAST, DARK_BACKGROUND_LUMINANCE, DEFAULT_CHART_LABEL_SEPARATOR, DEFAULT_FURNITURE_DATE_FORMAT, DEFAULT_VARIABLE_DATE_FORMAT, DESIGN_HINT_KEYS, ENGINE_DEFAULT_CHART_TYPES, ENGINE_DEFAULT_COLOR_SCHEME, ENGINE_DEFAULT_FONT_SCHEME, ENGINE_DEFAULT_THEME, FONT_SIZE_GRID_PER_PX, FOOTNOTE_MAX_RATIO, LANGUAGES, LAYOUT_BODY_KINDS, MAX_COMPOSITION_DEPTH, MAX_NUMBERING_LEVELS, MAX_NUMBERING_VALUE, MAX_PLACEHOLDER_GROUP_DEPTH, MAX_ROMAN_VALUE, METRIC_TREND_MIN_CONTRAST, METRIC_TREND_SHAPES, NUMBERING_STYLES, NUMBERING_SUFFIXES, OPFCompositionError, OPFVariableError, PATTERN_PRESETS, PATTERN_PRESET_ALIASES, PATTERN_TILE_SIZE, PICTURE_BULLET_SCALE, SLIDE_SCOPED_BUILTINS, SOCIAL_PLATFORMS, SURFACE_ALT_MIN_CONTRAST, SURFACE_ALT_MIX, TIMELINE_OUTLINE_MIN_CONTRAST, TIMELINE_STATUSES, TIMELINE_TEXT_MIN_CONTRAST, VARIABLE_KINDS, annotationText, captionSettings, chartColorForFill, chartHighlightColors, chartHighlightMarks, chartLabelText, chartNumber, chartNumberFixesByCell, chartOptionSupport, chartOptionTarget, chartPaletteForFill, chartPrimaryLayout, citationMarkerText, codeHighlightBands, codeHighlightColors, codeHighlightLines, codeHighlightSlice, codeLineNumbers, codeLineRuns, codeSyntaxPalette, codeSyntaxPaletteForScheme, coerceVariableValue, collectCitations, colorContrast, composeSlide, datasetDiagnostics, defaultSlideBackground, fitImage, fitList, fitRichText, fitText, formatChartLabelNumber, formatChartLabelPercent, formatDataNumber, formatFurnitureDate, formatListNumber, formatVariableNumber, fromExcelNumberFormat, hasContentVariables, hasPlaceholderGroups, imageBackground, imageShape, inlineChartData, inlineDatasets, inlineTableData, instantiateForValidation, intrinsicImageAspect, intrinsicImageSize, isDarkColor, isDatasetRef, isPlaceholderGroup, isRecord, isTemplate, isXYChartType, layoutCaption, layoutCode, layoutContent, layoutFootnotes, layoutFurniture, layoutLeaves, layoutMetric, layoutQuote, layoutSlots, layoutStructure, layoutTable, layoutTimeline, layoutWatermark, listBuiltinVariables, listNumbers, listVariables, measureText, measureTextOutline, metricTrendColor, metricTrendMark, metricTrendPoints, normalizeHexColor, normalizeLanguageFamily, numberFormatError, numberingAtLevel, numberingFindings, numberingStyleDraws, paragraphDirection, paragraphDirectionAt, pathFor, patternBitmap, patternRuns, physicalAlignment, placeTextLines, promotedRegionKeys, readingRows, referencesSlide, resolveCanvasDimensions, resolveChartData, resolveChartOptions, resolveCodeLanguage, resolveColorRef, resolveColorRoles, resolveDesignHints, resolveDesignRecords, resolveFontFamilies, resolveFontScheme, resolveLogo, resolveNumbering, resolvePatternPreset, resolveScriptFonts, resolveSlideDirection, resolveSlideVariables, resolveSocialProfile, resolveTableData, resolveTextStyle, resolveVariables, scriptFontRole, sliceNumberedItems, slideCitations, slideTokenSpans, snapFontSizeDown, snapFontSizeUp, suggestChartNumberFix, surfaceAltColor, tableCellDisplayValue, tableGrid, tableRowBoundaries, textColorForFill, textWidthMeasurer, timelineMarkerShapes, timelineTextColor, toExcelNumberFormat, tokenizeCode, unusedDatasets, usesSlideBuiltin, variableDeclarations, visitContentPayloads, visualReadingOrder, walkCitationRuns, wrapText };
|
|
6114
|
+
export { CAPTIONABLE_FIELDS, CAPTION_FONT_RATIO, CAPTION_MAX_RATIO, CHART_HIGHLIGHT_MUTED_MIN_CONTRAST, CHART_HIGHLIGHT_MUTED_MIX, CHART_SERIES_MIN_DIFFERENCE, CHART_SERIES_MIN_LIGHTNESS_STEP, CHART_TYPES, CITATION_MARKER_RAISE, CITATION_MARKER_SCALE, CODE_HIGHLIGHT_LANGUAGES, CODE_HIGHLIGHT_MAX_LENGTH, CODE_PANEL_BACKGROUND, CODE_PANEL_FOREGROUND, CODE_SYNTAX_MIN_CONTRAST, DARK_BACKGROUND_LUMINANCE, DEFAULT_CHART_LABEL_SEPARATOR, DEFAULT_FURNITURE_DATE_FORMAT, DEFAULT_VARIABLE_DATE_FORMAT, DESIGN_HINT_KEYS, ENGINE_DEFAULT_CHART_TYPES, ENGINE_DEFAULT_COLOR_SCHEME, ENGINE_DEFAULT_FONT_SCHEME, ENGINE_DEFAULT_THEME, FONT_SIZE_GRID_PER_PX, FOOTNOTE_MAX_RATIO, FURNITURE_GAP, FURNITURE_IMAGE_SHARE, LANGUAGES, LAYOUT_BODY_KINDS, LOGO_SHAPES, MAX_COMPOSITION_DEPTH, MAX_NUMBERING_LEVELS, MAX_NUMBERING_VALUE, MAX_PLACEHOLDER_GROUP_DEPTH, MAX_ROMAN_VALUE, METRIC_TREND_MIN_CONTRAST, METRIC_TREND_SHAPES, NUMBERING_STYLES, NUMBERING_SUFFIXES, OPFCompositionError, OPFVariableError, PATTERN_PRESETS, PATTERN_PRESET_ALIASES, PATTERN_TILE_SIZE, PICTURE_BULLET_SCALE, SLIDE_SCOPED_BUILTINS, SOCIAL_PLATFORMS, SURFACE_ALT_MIN_CONTRAST, SURFACE_ALT_MIX, TIMELINE_OUTLINE_MIN_CONTRAST, TIMELINE_STATUSES, TIMELINE_TEXT_MIN_CONTRAST, VARIABLE_KINDS, annotationText, captionSettings, chartColorForFill, chartHighlightColors, chartHighlightMarks, chartLabelText, chartNumber, chartNumberFixesByCell, chartOptionSupport, chartOptionTarget, chartPaletteForFill, chartPrimaryLayout, citationMarkerText, codeHighlightBands, codeHighlightColors, codeHighlightLines, codeHighlightSlice, codeLineNumbers, codeLineRuns, codeSyntaxPalette, codeSyntaxPaletteForScheme, coerceVariableValue, collectCitations, colorContrast, composeSlide, datasetDiagnostics, defaultSlideBackground, fitImage, fitList, fitRichText, fitText, formatChartLabelNumber, formatChartLabelPercent, formatDataNumber, formatFurnitureDate, formatListNumber, formatVariableNumber, fromExcelNumberFormat, hasContentVariables, hasPlaceholderGroups, imageBackground, imageShape, inlineChartData, inlineDatasets, inlineTableData, instantiateForValidation, intrinsicImageAspect, intrinsicImageSize, isDarkColor, isDatasetRef, isPlaceholderGroup, isRecord, isTemplate, isXYChartType, layoutCaption, layoutCode, layoutContent, layoutFootnotes, layoutFurniture, layoutLeaves, layoutMetric, layoutQuote, layoutSlots, layoutStructure, layoutTable, layoutTimeline, layoutWatermark, listBuiltinVariables, listNumbers, listVariables, measureText, measureTextOutline, metricTrendColor, metricTrendMark, metricTrendPoints, normalizeHexColor, normalizeLanguageFamily, numberFormatError, numberingAtLevel, numberingFindings, numberingStyleDraws, paragraphDirection, paragraphDirectionAt, pathFor, patternBitmap, patternRuns, physicalAlignment, placeTextLines, promotedRegionKeys, readingRows, referencesSlide, resolveCanvasDimensions, resolveChartData, resolveChartOptions, resolveCodeLanguage, resolveColorRef, resolveColorRoles, resolveDesignHints, resolveDesignRecords, resolveFontFamilies, resolveFontScheme, resolveLogo, resolveNumbering, resolvePatternPreset, resolveScriptFonts, resolveSlideDirection, resolveSlideVariables, resolveSocialProfile, resolveTableData, resolveTextStyle, resolveVariables, scriptFontRole, sliceNumberedItems, slideCitations, slideTokenSpans, snapFontSizeDown, snapFontSizeUp, suggestChartNumberFix, surfaceAltColor, tableCellDisplayValue, tableGrid, tableRowBoundaries, textColorForFill, textWidthMeasurer, timelineMarkerShapes, timelineTextColor, toExcelNumberFormat, tokenizeCode, unusedDatasets, usesSlideBuiltin, variableDeclarations, visitContentPayloads, visualReadingOrder, walkCitationRuns, wrapText };
|