@pixldocs/canvas-renderer 0.5.171 → 0.5.173

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.
Files changed (29) hide show
  1. package/dist/{index-Cq9sQGri.js → index-ChHYFk0E.js} +306 -79
  2. package/dist/index-ChHYFk0E.js.map +1 -0
  3. package/dist/{index-BgOzEKmN.cjs → index-ZehEOqUB.cjs} +291 -64
  4. package/dist/index-ZehEOqUB.cjs.map +1 -0
  5. package/dist/index.cjs +2 -1
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.ts +31 -0
  8. package/dist/index.js +16 -15
  9. package/dist/{pdfFonts-BTEVnYX8.cjs → pdfFonts-BTj2f465.cjs} +12 -3
  10. package/dist/pdfFonts-BTj2f465.cjs.map +1 -0
  11. package/dist/{pdfFonts-b3_bv7F0.js → pdfFonts-DhEaMTZl.js} +12 -3
  12. package/dist/pdfFonts-DhEaMTZl.js.map +1 -0
  13. package/dist/{svgTextToPath-IM1f6F-f.cjs → svgTextToPath-BLk_mcqi.cjs} +85 -3
  14. package/dist/svgTextToPath-BLk_mcqi.cjs.map +1 -0
  15. package/dist/{svgTextToPath-BXAzwaaR.js → svgTextToPath-ra4EhtBL.js} +86 -4
  16. package/dist/svgTextToPath-ra4EhtBL.js.map +1 -0
  17. package/dist/{vectorPdfExport-BrwXcGkA.cjs → vectorPdfExport-BWDj55kq.cjs} +36 -10
  18. package/dist/vectorPdfExport-BWDj55kq.cjs.map +1 -0
  19. package/dist/{vectorPdfExport--EtCdnlG.js → vectorPdfExport-CyTa-D1p.js} +36 -10
  20. package/dist/vectorPdfExport-CyTa-D1p.js.map +1 -0
  21. package/package.json +1 -1
  22. package/dist/index-BgOzEKmN.cjs.map +0 -1
  23. package/dist/index-Cq9sQGri.js.map +0 -1
  24. package/dist/pdfFonts-BTEVnYX8.cjs.map +0 -1
  25. package/dist/pdfFonts-b3_bv7F0.js.map +0 -1
  26. package/dist/svgTextToPath-BXAzwaaR.js.map +0 -1
  27. package/dist/svgTextToPath-IM1f6F-f.cjs.map +0 -1
  28. package/dist/vectorPdfExport--EtCdnlG.js.map +0 -1
  29. package/dist/vectorPdfExport-BrwXcGkA.cjs.map +0 -1
@@ -2782,6 +2782,19 @@ const EXTENDED_FONT_LIST = [
2782
2782
  { name: "Petrona", category: "Serif", local: false },
2783
2783
  { name: "Rozha One", category: "Serif", local: false },
2784
2784
  { name: "Tiro Devanagari Hindi", category: "Serif", local: false },
2785
+ // ── Newly added popular serif families ──
2786
+ { name: "Roboto Serif", category: "Serif", local: false, popular: true },
2787
+ { name: "Roboto Slab", category: "Serif", local: false, popular: true },
2788
+ { name: "Inria Serif", category: "Serif", local: false },
2789
+ { name: "Instrument Serif", category: "Serif", local: false, popular: true },
2790
+ { name: "Young Serif", category: "Serif", local: false },
2791
+ { name: "Gloock", category: "Serif", local: false },
2792
+ { name: "Castoro", category: "Serif", local: false },
2793
+ { name: "Source Serif 4", category: "Serif", local: false },
2794
+ { name: "IBM Plex Serif", category: "Serif", local: false },
2795
+ { name: "Pridi", category: "Serif", local: false },
2796
+ { name: "Eczar", category: "Serif", local: false },
2797
+ { name: "Faustina", category: "Serif", local: false },
2785
2798
  // ═══════════════════════════════════════════════════════════════════
2786
2799
  // SANS-SERIF — clean, modern, workhorse
2787
2800
  // ═══════════════════════════════════════════════════════════════════
@@ -2837,6 +2850,43 @@ const EXTENDED_FONT_LIST = [
2837
2850
  { name: "Anek Devanagari", category: "Sans-Serif", local: false },
2838
2851
  { name: "Hind", category: "Sans-Serif", local: true },
2839
2852
  { name: "Hind Vadodara", category: "Sans-Serif", local: false },
2853
+ // ── Newly added popular sans-serif families (Google Fonts; loaded on demand) ──
2854
+ { name: "Ubuntu", category: "Sans-Serif", local: false, popular: true },
2855
+ { name: "Ubuntu Condensed", category: "Sans-Serif", local: false },
2856
+ { name: "Ubuntu Sans", category: "Sans-Serif", local: false },
2857
+ { name: "Roboto Condensed", category: "Sans-Serif", local: false, popular: true },
2858
+ { name: "Roboto Flex", category: "Sans-Serif", local: false },
2859
+ { name: "Jost", category: "Sans-Serif", local: false, popular: true },
2860
+ { name: "Inter Tight", category: "Sans-Serif", local: false },
2861
+ { name: "Mona Sans", category: "Sans-Serif", local: false },
2862
+ { name: "Hubot Sans", category: "Sans-Serif", local: false },
2863
+ { name: "Funnel Sans", category: "Sans-Serif", local: false },
2864
+ { name: "Funnel Display", category: "Sans-Serif", local: false },
2865
+ { name: "Geologica", category: "Sans-Serif", local: false },
2866
+ { name: "Bricolage Grotesque", category: "Sans-Serif", local: false, popular: true },
2867
+ { name: "Familjen Grotesk", category: "Sans-Serif", local: false },
2868
+ { name: "Wix Madefor Display", category: "Sans-Serif", local: false },
2869
+ { name: "Wix Madefor Text", category: "Sans-Serif", local: false },
2870
+ { name: "Atkinson Hyperlegible", category: "Sans-Serif", local: false },
2871
+ { name: "Maven Pro", category: "Sans-Serif", local: false },
2872
+ { name: "Asap", category: "Sans-Serif", local: false },
2873
+ { name: "Asap Condensed", category: "Sans-Serif", local: false },
2874
+ { name: "Saira", category: "Sans-Serif", local: false },
2875
+ { name: "Saira Condensed", category: "Sans-Serif", local: false },
2876
+ { name: "Saira Semi Condensed", category: "Sans-Serif", local: false },
2877
+ { name: "Yanone Kaffeesatz", category: "Sans-Serif", local: false },
2878
+ { name: "Sarabun", category: "Sans-Serif", local: false },
2879
+ { name: "Prompt", category: "Sans-Serif", local: false },
2880
+ { name: "Kanit", category: "Sans-Serif", local: false, popular: true },
2881
+ { name: "Chivo", category: "Sans-Serif", local: false },
2882
+ { name: "Commissioner", category: "Sans-Serif", local: false },
2883
+ { name: "Inria Sans", category: "Sans-Serif", local: false },
2884
+ { name: "Tomorrow", category: "Sans-Serif", local: false },
2885
+ { name: "Catamaran", category: "Sans-Serif", local: false },
2886
+ { name: "Heebo", category: "Sans-Serif", local: false },
2887
+ { name: "Assistant", category: "Sans-Serif", local: false },
2888
+ { name: "Cairo", category: "Sans-Serif", local: false },
2889
+ { name: "Tajawal", category: "Sans-Serif", local: false },
2840
2890
  // ═══════════════════════════════════════════════════════════════════
2841
2891
  // DISPLAY — bold, attention-grabbing headlines
2842
2892
  // ═══════════════════════════════════════════════════════════════════
@@ -2891,6 +2941,12 @@ const EXTENDED_FONT_LIST = [
2891
2941
  { name: "Audiowide", category: "Display", local: false },
2892
2942
  { name: "Orbitron", category: "Display", local: false },
2893
2943
  { name: "Plaster", category: "Display", local: false },
2944
+ // ── Newly added display families ──
2945
+ { name: "Black Han Sans", category: "Display", local: false },
2946
+ { name: "Bungee Spice", category: "Display", local: false },
2947
+ { name: "Sansita Swashed", category: "Display", local: false },
2948
+ { name: "Honk", category: "Display", local: false },
2949
+ { name: "Sixtyfour", category: "Display", local: false },
2894
2950
  // ═══════════════════════════════════════════════════════════════════
2895
2951
  // HANDWRITING / SCRIPT — fluid, personal, calligraphic
2896
2952
  // ═══════════════════════════════════════════════════════════════════
@@ -2980,7 +3036,13 @@ const EXTENDED_FONT_LIST = [
2980
3036
  { name: "Cutive Mono", category: "Monospace", local: false },
2981
3037
  { name: "Major Mono Display", category: "Monospace", local: false },
2982
3038
  { name: "VT323", category: "Monospace", local: false },
2983
- { name: "Share Tech Mono", category: "Monospace", local: false }
3039
+ { name: "Share Tech Mono", category: "Monospace", local: false },
3040
+ // ── Newly added monospace families ──
3041
+ { name: "Ubuntu Mono", category: "Monospace", local: false, popular: true },
3042
+ { name: "Ubuntu Sans Mono", category: "Monospace", local: false },
3043
+ { name: "Noto Sans Mono", category: "Monospace", local: false },
3044
+ { name: "Martian Mono", category: "Monospace", local: false },
3045
+ { name: "Atkinson Hyperlegible Mono", category: "Monospace", local: false }
2984
3046
  ];
2985
3047
  const _fontLookupCache = /* @__PURE__ */ new Map();
2986
3048
  function findFontEntry(name) {
@@ -6206,6 +6268,87 @@ function parseTextMarkdown(input, themeColors) {
6206
6268
  }
6207
6269
  return { plainText: plain, styles, hasFormatting };
6208
6270
  }
6271
+ function angleToCoords(angleDeg) {
6272
+ const rad = angleDeg * Math.PI / 180;
6273
+ const x1 = 0.5 - Math.sin(rad) * 0.5;
6274
+ const y1 = 0.5 + Math.cos(rad) * 0.5;
6275
+ const x2 = 0.5 + Math.sin(rad) * 0.5;
6276
+ const y2 = 0.5 - Math.cos(rad) * 0.5;
6277
+ return { x1, y1, x2, y2 };
6278
+ }
6279
+ function normalizeGradientStops(stops) {
6280
+ const normalized = stops.map((stop) => ({
6281
+ color: stop.color,
6282
+ offset: Math.max(0, Math.min(1, Number(stop.offset) || 0))
6283
+ })).sort((a, b) => a.offset - b.offset);
6284
+ if (normalized.length === 0) return normalized;
6285
+ if (normalized[0].offset > 0) {
6286
+ normalized.unshift({ color: normalized[0].color, offset: 0 });
6287
+ }
6288
+ if (normalized[normalized.length - 1].offset < 1) {
6289
+ normalized.push({ color: normalized[normalized.length - 1].color, offset: 1 });
6290
+ }
6291
+ return normalized;
6292
+ }
6293
+ function gradientToFabric(gradient, width, height) {
6294
+ const colorStops = normalizeGradientStops(gradient.stops).map((s) => ({
6295
+ offset: s.offset,
6296
+ color: s.color
6297
+ }));
6298
+ if (gradient.type === "linear" || gradient.type === "conic") {
6299
+ const coords = angleToCoords(gradient.angle ?? 90);
6300
+ return new fabric.Gradient({
6301
+ type: "linear",
6302
+ coords: {
6303
+ x1: coords.x1 * width,
6304
+ y1: coords.y1 * height,
6305
+ x2: coords.x2 * width,
6306
+ y2: coords.y2 * height
6307
+ },
6308
+ colorStops
6309
+ });
6310
+ }
6311
+ const cx = (gradient.cx ?? 0.5) * width;
6312
+ const cy = (gradient.cy ?? 0.5) * height;
6313
+ const r = (gradient.r ?? 0.5) * Math.max(width, height);
6314
+ return new fabric.Gradient({
6315
+ type: "radial",
6316
+ coords: {
6317
+ x1: cx,
6318
+ y1: cy,
6319
+ r1: 0,
6320
+ x2: cx,
6321
+ y2: cy,
6322
+ r2: r
6323
+ },
6324
+ colorStops
6325
+ });
6326
+ }
6327
+ function applyInitialGradients(obj, element) {
6328
+ const w = typeof obj.width === "number" && obj.width > 0 ? obj.width : Number(element.width) || 0;
6329
+ const h = typeof obj.height === "number" && obj.height > 0 ? obj.height : Number(element.height) || 0;
6330
+ if (w <= 0 || h <= 0) return;
6331
+ const fg = element.fillGradient;
6332
+ if (fg && isGradientConfig(fg)) {
6333
+ try {
6334
+ obj.set({ fill: gradientToFabric(fg, w, h), objectCaching: false });
6335
+ obj.__lastFillGradientJson = JSON.stringify(fg);
6336
+ obj.dirty = true;
6337
+ } catch (e) {
6338
+ console.warn("[fabricObjectCreators] fillGradient apply failed:", e);
6339
+ }
6340
+ }
6341
+ const sg = element.strokeGradient;
6342
+ if (sg && isGradientConfig(sg)) {
6343
+ try {
6344
+ obj.set({ stroke: gradientToFabric(sg, w, h), objectCaching: false });
6345
+ obj.__lastStrokeGradientJson = JSON.stringify(sg);
6346
+ obj.dirty = true;
6347
+ } catch (e) {
6348
+ console.warn("[fabricObjectCreators] strokeGradient apply failed:", e);
6349
+ }
6350
+ }
6351
+ }
6209
6352
  const roundDiag = (value) => {
6210
6353
  if (typeof value !== "number") return value;
6211
6354
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -6605,6 +6748,9 @@ function createFabricObject(element) {
6605
6748
  flipY: element.flipY ?? false
6606
6749
  });
6607
6750
  setObjectData(obj, element.id);
6751
+ if (element.type === "shape" || element.type === "line" || element.type === "text") {
6752
+ applyInitialGradients(obj, element);
6753
+ }
6608
6754
  }
6609
6755
  return obj;
6610
6756
  }
@@ -6651,6 +6797,9 @@ function createFabricObjectForGroupMember(element) {
6651
6797
  flipY: element.flipY ?? false
6652
6798
  });
6653
6799
  setObjectData(obj, element.id);
6800
+ if (element.type === "shape" || element.type === "line" || element.type === "text") {
6801
+ applyInitialGradients(obj, element);
6802
+ }
6654
6803
  }
6655
6804
  return obj;
6656
6805
  }
@@ -7190,62 +7339,6 @@ function bakeEdgeFade(source, fade) {
7190
7339
  }
7191
7340
  return canvas;
7192
7341
  }
7193
- function angleToCoords(angleDeg) {
7194
- const rad = angleDeg * Math.PI / 180;
7195
- const x1 = 0.5 - Math.sin(rad) * 0.5;
7196
- const y1 = 0.5 + Math.cos(rad) * 0.5;
7197
- const x2 = 0.5 + Math.sin(rad) * 0.5;
7198
- const y2 = 0.5 - Math.cos(rad) * 0.5;
7199
- return { x1, y1, x2, y2 };
7200
- }
7201
- function normalizeGradientStops(stops) {
7202
- const normalized = stops.map((stop) => ({
7203
- color: stop.color,
7204
- offset: Math.max(0, Math.min(1, Number(stop.offset) || 0))
7205
- })).sort((a, b) => a.offset - b.offset);
7206
- if (normalized.length === 0) return normalized;
7207
- if (normalized[0].offset > 0) {
7208
- normalized.unshift({ color: normalized[0].color, offset: 0 });
7209
- }
7210
- if (normalized[normalized.length - 1].offset < 1) {
7211
- normalized.push({ color: normalized[normalized.length - 1].color, offset: 1 });
7212
- }
7213
- return normalized;
7214
- }
7215
- function gradientToFabric(gradient, width, height) {
7216
- const colorStops = normalizeGradientStops(gradient.stops).map((s) => ({
7217
- offset: s.offset,
7218
- color: s.color
7219
- }));
7220
- if (gradient.type === "linear" || gradient.type === "conic") {
7221
- const coords = angleToCoords(gradient.angle ?? 90);
7222
- return new fabric.Gradient({
7223
- type: "linear",
7224
- coords: {
7225
- x1: coords.x1 * width,
7226
- y1: coords.y1 * height,
7227
- x2: coords.x2 * width,
7228
- y2: coords.y2 * height
7229
- },
7230
- colorStops
7231
- });
7232
- }
7233
- const cx = (gradient.cx ?? 0.5) * width;
7234
- const cy = (gradient.cy ?? 0.5) * height;
7235
- const r = (gradient.r ?? 0.5) * Math.max(width, height);
7236
- return new fabric.Gradient({
7237
- type: "radial",
7238
- coords: {
7239
- x1: cx,
7240
- y1: cy,
7241
- r1: 0,
7242
- x2: cx,
7243
- y2: cy,
7244
- r2: r
7245
- },
7246
- colorStops
7247
- });
7248
- }
7249
7342
  const PageCanvas = forwardRef(
7250
7343
  ({
7251
7344
  pageId,
@@ -12001,6 +12094,59 @@ const DEFAULT_DATA_V2_VERSION = 2;
12001
12094
  function isDefaultDataV2(data) {
12002
12095
  return typeof data === "object" && data !== null && !Array.isArray(data) && data.version === DEFAULT_DATA_V2_VERSION && typeof data.sectionState === "object" && data.sectionState !== null;
12003
12096
  }
12097
+ function defaultSectionState(sections) {
12098
+ const state = {};
12099
+ const repeatables = sections.filter((s) => s.type === "repeatable");
12100
+ const childrenByParent = /* @__PURE__ */ new Map();
12101
+ for (const section of repeatables) {
12102
+ if (!section.parentId) continue;
12103
+ if (!childrenByParent.has(section.parentId)) childrenByParent.set(section.parentId, []);
12104
+ childrenByParent.get(section.parentId).push(section);
12105
+ }
12106
+ const createEmptyEntry = (section) => {
12107
+ const entry = {};
12108
+ for (const field of section.entryFields) {
12109
+ entry[field.key] = field.type === "list" ? [] : field.type === "toggle" ? "false" : "";
12110
+ }
12111
+ return entry;
12112
+ };
12113
+ const createInitialEntries = (section) => {
12114
+ const count = Math.max(0, section.initialEntryCount ?? 1);
12115
+ return Array.from({ length: count }, () => createEmptyEntry(section));
12116
+ };
12117
+ const seedNested = (parentSection, parentStateKey, parentEntryIndex) => {
12118
+ const children = childrenByParent.get(parentSection.id) ?? [];
12119
+ for (const child of children) {
12120
+ const childStateKey = `${parentStateKey}_${parentEntryIndex}_${child.id}`;
12121
+ const childEntries = createInitialEntries(child);
12122
+ state[childStateKey] = childEntries;
12123
+ childEntries.forEach((_, childEntryIndex) => seedNested(child, childStateKey, childEntryIndex));
12124
+ }
12125
+ };
12126
+ for (const section of sections) {
12127
+ if (section.type !== "single") continue;
12128
+ const obj = {};
12129
+ for (const f of section.fields) {
12130
+ obj[f.key] = f.type === "list" ? [] : f.type === "toggle" ? "false" : "";
12131
+ }
12132
+ state[section.id] = obj;
12133
+ }
12134
+ const topLevelRepeatables = repeatables.filter((s) => !s.parentId);
12135
+ for (const section of topLevelRepeatables) {
12136
+ const entries = createInitialEntries(section);
12137
+ state[section.id] = entries;
12138
+ entries.forEach((_, entryIndex) => seedNested(section, section.id, entryIndex));
12139
+ }
12140
+ const singleSectionIds = new Set(sections.filter((s) => s.type === "single").map((s) => s.id));
12141
+ for (const section of repeatables) {
12142
+ if (section.parentId && singleSectionIds.has(section.parentId)) {
12143
+ const entries = createInitialEntries(section);
12144
+ state[section.id] = entries;
12145
+ entries.forEach((_, entryIndex) => seedNested(section, section.id, entryIndex));
12146
+ }
12147
+ }
12148
+ return state;
12149
+ }
12004
12150
  function flattenSectionStateToFormData(sectionState, sections) {
12005
12151
  const flat = {};
12006
12152
  const repeatables = sections.filter((s) => s.type === "repeatable");
@@ -15751,6 +15897,74 @@ function paintRepeatableSections(config, repeatableSections) {
15751
15897
  }
15752
15898
  }
15753
15899
  }
15900
+ async function getTemplateForm(options) {
15901
+ var _a, _b;
15902
+ const { templateId, supabaseUrl, supabaseAnonKey } = options;
15903
+ if (!supabaseUrl || !supabaseAnonKey) {
15904
+ throw new Error("[getTemplateForm] supabaseUrl and supabaseAnonKey are required");
15905
+ }
15906
+ const templateRow = await fetchRow(supabaseUrl, supabaseAnonKey, "templates", templateId);
15907
+ const templateConfig = templateRow.config;
15908
+ const templateFormSchema = templateRow.form_schema;
15909
+ const boundFormSchemaId = options.formSchemaId ?? (typeof templateRow.form_schema_id === "string" ? templateRow.form_schema_id : null);
15910
+ if (templateFormSchema) {
15911
+ if (!Array.isArray(templateConfig.dynamicFields) && Array.isArray(templateFormSchema.dynamicFields)) {
15912
+ templateConfig.dynamicFields = templateFormSchema.dynamicFields;
15913
+ }
15914
+ if (!Array.isArray(templateConfig.fieldGroups) && Array.isArray(templateFormSchema.fieldGroups)) {
15915
+ templateConfig.fieldGroups = templateFormSchema.fieldGroups;
15916
+ }
15917
+ }
15918
+ let formSchema;
15919
+ let defaultForm = null;
15920
+ if (boundFormSchemaId) {
15921
+ const [schemaRow, defForm] = await Promise.all([
15922
+ fetchRow(supabaseUrl, supabaseAnonKey, "form_schemas", boundFormSchemaId).catch(() => null),
15923
+ fetchDefaultForm(supabaseUrl, supabaseAnonKey, boundFormSchemaId)
15924
+ ]);
15925
+ formSchema = schemaRow == null ? void 0 : schemaRow.schema;
15926
+ defaultForm = defForm;
15927
+ }
15928
+ const repeatableNodeMap = /* @__PURE__ */ new Map();
15929
+ const repeatableFromSchema = templateFormSchema == null ? void 0 : templateFormSchema.repeatableSections;
15930
+ if (repeatableFromSchema) {
15931
+ for (const r of repeatableFromSchema) {
15932
+ if (!repeatableNodeMap.has(r.label)) repeatableNodeMap.set(r.label, r.nodeId);
15933
+ const labelKey = r.label.trim().toLowerCase();
15934
+ if (!repeatableNodeMap.has(labelKey)) repeatableNodeMap.set(labelKey, r.nodeId);
15935
+ }
15936
+ }
15937
+ const schemaSections = getRenderableFormSections(formSchema);
15938
+ let sections;
15939
+ if (schemaSections == null ? void 0 : schemaSections.length) {
15940
+ sections = formDefSectionsToInferred(schemaSections, repeatableNodeMap);
15941
+ } else if ((_a = templateConfig.dynamicFields) == null ? void 0 : _a.length) {
15942
+ sections = inferFormSchemaFromTemplate(
15943
+ templateConfig.dynamicFields,
15944
+ templateConfig.fieldGroups || [],
15945
+ ((_b = templateConfig.pages) == null ? void 0 : _b.length) ? { pages: templateConfig.pages } : void 0
15946
+ );
15947
+ } else {
15948
+ sections = [];
15949
+ }
15950
+ const seeded = defaultSectionState(sections);
15951
+ const templateDefaultData = templateRow.default_data;
15952
+ let overlay = null;
15953
+ if (templateDefaultData && isDefaultDataV2(templateDefaultData)) {
15954
+ overlay = templateDefaultData.sectionState;
15955
+ } else {
15956
+ overlay = extractSectionStateCandidate(defaultForm == null ? void 0 : defaultForm.values, sections) ?? extractSectionStateCandidate(defaultForm == null ? void 0 : defaultForm.saved_data, sections) ?? null;
15957
+ }
15958
+ const initialSectionState = overlay ? { ...seeded, ...overlay } : seeded;
15959
+ return {
15960
+ templateId,
15961
+ templateName: templateRow.name || "Untitled",
15962
+ price: templateRow.price ?? 0,
15963
+ formSchemaId: boundFormSchemaId,
15964
+ sections,
15965
+ initialSectionState
15966
+ };
15967
+ }
15754
15968
  const PREVIEW_DEBUG_PREFIX = "[canvas-renderer][preview-debug]";
15755
15969
  function computeFontSignature(config) {
15756
15970
  var _a;
@@ -16117,9 +16331,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
16117
16331
  }
16118
16332
  return svgString;
16119
16333
  }
16120
- const resolvedPackageVersion = "0.5.171";
16334
+ const resolvedPackageVersion = "0.5.173";
16121
16335
  const PACKAGE_VERSION = resolvedPackageVersion;
16122
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.171";
16336
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.173";
16123
16337
  const roundParityValue = (value) => {
16124
16338
  if (typeof value !== "number") return value;
16125
16339
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -16553,6 +16767,7 @@ class PixldocsRenderer {
16553
16767
  * same fonts, same gradients, same draw order, same selectable text.
16554
16768
  */
16555
16769
  async renderPdfViaClientExport(templateConfig, options = {}) {
16770
+ var _a;
16556
16771
  await ensureFontsForResolvedConfig(templateConfig);
16557
16772
  const hasAutoShrink = configHasAutoShrinkText(templateConfig);
16558
16773
  await this.awaitFontsForConfig(templateConfig, hasAutoShrink ? 4e3 : 1800);
@@ -16617,7 +16832,7 @@ class PixldocsRenderer {
16617
16832
  await this.waitForCanvasScene(container, cloned, i);
16618
16833
  }
16619
16834
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
16620
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport--EtCdnlG.js");
16835
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-CyTa-D1p.js");
16621
16836
  const prepared = preparePagesForExport(
16622
16837
  cloned.pages,
16623
16838
  canvasWidth,
@@ -16626,7 +16841,8 @@ class PixldocsRenderer {
16626
16841
  const result = await exportMultiPagePdf(prepared, {
16627
16842
  title: options.title,
16628
16843
  watermark: !!options.watermark,
16629
- returnBlob: true
16844
+ returnBlob: true,
16845
+ pdfTextMode: ((_a = cloned.canvas) == null ? void 0 : _a.n) ?? "selectable"
16630
16846
  });
16631
16847
  if (!result || typeof result === "undefined") {
16632
16848
  throw new Error("exportMultiPagePdf returned no blob (returnBlob path failed)");
@@ -18752,7 +18968,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
18752
18968
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
18753
18969
  sanitizeSvgTreeForPdf(svgToDraw);
18754
18970
  try {
18755
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport--EtCdnlG.js");
18971
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-CyTa-D1p.js");
18756
18972
  try {
18757
18973
  await logTextMeasurementDiagnostic(svgToDraw);
18758
18974
  } catch {
@@ -18887,7 +19103,7 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
18887
19103
  }
18888
19104
  if (shouldOutlineText) {
18889
19105
  try {
18890
- const { convertAllTextToPath } = await import("./svgTextToPath-BXAzwaaR.js");
19106
+ const { convertAllTextToPath } = await import("./svgTextToPath-ra4EhtBL.js");
18891
19107
  pageSvg = await convertAllTextToPath(pageSvg, fontBaseUrl, { mode: outlineSubMode });
18892
19108
  try {
18893
19109
  dumpSvgTextDiagnostics(pageSvg, i, PARITY_TAG, "STAGE-1b-after-text-to-path-raw");
@@ -18899,6 +19115,16 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
18899
19115
  outlineErr
18900
19116
  );
18901
19117
  }
19118
+ } else {
19119
+ try {
19120
+ const { replaceGradientTextFillsWithFirstStop } = await import("./svgTextToPath-ra4EhtBL.js");
19121
+ pageSvg = replaceGradientTextFillsWithFirstStop(pageSvg);
19122
+ } catch (gradErr) {
19123
+ console.warn(
19124
+ "[canvas-renderer][pdf] gradient-text fill resolution failed:",
19125
+ gradErr
19126
+ );
19127
+ }
18902
19128
  }
18903
19129
  let processedSvg = await prepareLiveCanvasSvgForPdf(pageSvg, page.width, page.height, `page-${i + 1}`, {
18904
19130
  stripPageBackground: shouldStripBg
@@ -19097,7 +19323,7 @@ function setAutoShrinkDebug(enabled) {
19097
19323
  }
19098
19324
  }
19099
19325
  export {
19100
- warmResolvedTemplateForPreview as $,
19326
+ setBundledAssetPrefixes as $,
19101
19327
  API_URL as A,
19102
19328
  collectImageUrls as B,
19103
19329
  configHasAutoShrinkText$1 as C,
@@ -19111,23 +19337,24 @@ export {
19111
19337
  extractFontFamiliesFromSvgs as K,
19112
19338
  getEmbeddedJsPDFFontName as L,
19113
19339
  getPublishedTemplate as M,
19114
- isBundledAssetUrl as N,
19115
- isFontAvailable as O,
19340
+ getTemplateForm as N,
19341
+ isBundledAssetUrl as O,
19116
19342
  PACKAGE_VERSION as P,
19117
- isPrivateUrl as Q,
19118
- listPublishedTemplates as R,
19119
- loadGoogleFontCSS as S,
19343
+ isFontAvailable as Q,
19344
+ isPrivateUrl as R,
19345
+ listPublishedTemplates as S,
19120
19346
  TRIANGLE_STROKE_MITER_LIMIT as T,
19121
- normalizeFontFamily as U,
19122
- resolveFontWeight as V,
19123
- resolveFromForm as W,
19124
- resolveTemplateData as X,
19125
- rewriteSvgFontsForJsPDF as Y,
19126
- setAutoShrinkDebug as Z,
19127
- setBundledAssetPrefixes as _,
19347
+ loadGoogleFontCSS as U,
19348
+ normalizeFontFamily as V,
19349
+ resolveFontWeight as W,
19350
+ resolveFromForm as X,
19351
+ resolveTemplateData as Y,
19352
+ rewriteSvgFontsForJsPDF as Z,
19353
+ setAutoShrinkDebug as _,
19128
19354
  getAbsoluteBounds as a,
19129
- warmTemplateFromForm as a0,
19130
- canvasImageLoader as a1,
19355
+ warmResolvedTemplateForPreview as a0,
19356
+ warmTemplateFromForm as a1,
19357
+ canvasImageLoader as a2,
19131
19358
  getProxiedImageUrl as b,
19132
19359
  captureFabricCanvasSvgForPdf as c,
19133
19360
  bakeEdgeFade as d,
@@ -19154,4 +19381,4 @@ export {
19154
19381
  collectFontDescriptorsFromConfig as y,
19155
19382
  collectFontsFromConfig as z
19156
19383
  };
19157
- //# sourceMappingURL=index-Cq9sQGri.js.map
19384
+ //# sourceMappingURL=index-ChHYFk0E.js.map