@koda-sl/baker-cli 0.419.0 → 0.420.0

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.
@@ -14634,6 +14634,7 @@ var ROLE_WORDS = {
14634
14634
  discount: "the discount",
14635
14635
  cta: "the button",
14636
14636
  button: "the button",
14637
+ call_to_action: "the button",
14637
14638
  caption: "a caption",
14638
14639
  fine_print: "the fine print",
14639
14640
  legal: "the fine print",
@@ -14674,7 +14675,8 @@ function textNotes(copy, profile) {
14674
14675
  notes.push(`Keep every accent and mark exactly: ${marks.join(" ")}.`);
14675
14676
  return notes;
14676
14677
  }
14677
- var isButton = (l) => l.role?.toLowerCase() === "cta" || /button/i.test(l.look ?? "");
14678
+ var BUTTON_ROLES = /* @__PURE__ */ new Set(["cta", "button", "call_to_action"]);
14679
+ var isButton = (l) => BUTTON_ROLES.has(roleKey(l.role)) || /button/i.test(l.look ?? "");
14678
14680
  var FIGURE_ROLES = /* @__PURE__ */ new Set(["price", "stat", "figure", "number", "discount"]);
14679
14681
  var HEADLINE_ROLES = /* @__PURE__ */ new Set(["headline", "title"]);
14680
14682
  var FINE_PRINT_ROLES = /* @__PURE__ */ new Set(["fine_print", "legal", "disclaimer", "footnote"]);
@@ -14781,10 +14783,10 @@ function variantDirection(c) {
14781
14783
  }
14782
14784
  var DEPARTS = "It leads where it differs from the scene and line notes above.";
14783
14785
  var DEPARTS_SHORT = "It leads over the notes above.";
14784
- var SUPPORT_ROLE = /\b(?:cta|fine[_ ]?print|legal|footnote|attribution|disclaimer)\b/i;
14786
+ var isSupport = (l) => isButton(l) || FINE_PRINT_ROLES.has(roleKey(l.role)) || roleKey(l.role) === "attribution";
14785
14787
  function hookDirection(c) {
14786
14788
  const hooks = c.spec.copy.flatMap(
14787
- (l, i) => l.lettering === "designed" && !isButton(l) && !SUPPORT_ROLE.test(l.role ?? "") ? [{ n: i + 1, text: l.text }] : []
14789
+ (l, i) => l.lettering === "designed" && !isSupport(l) ? [{ n: i + 1, text: l.text }] : []
14788
14790
  );
14789
14791
  const [first, ...rest] = hooks;
14790
14792
  const lead = rest.find((l) => /\d/.test(l.text)) ?? rest[0];
@@ -15351,24 +15353,26 @@ function logoSlot(frame, safe, opts = {}) {
15351
15353
  var STATIC_ADAPT_FORMAT_ROLE = "static_adapt_format";
15352
15354
  function adaptPlan(model, format, placements) {
15353
15355
  const renderRatio = nearestSupportedAspectRatio("image_generate", model, format);
15356
+ return {
15357
+ format,
15358
+ ...placements && placements.length > 0 ? { placements: [...placements] } : {},
15359
+ renderRatio,
15360
+ size: deliveredSize(format),
15361
+ safe: safeAreaOnFrame(renderRatio, format, placements)
15362
+ };
15363
+ }
15364
+ function safeAreaOnFrame(frame, format, placements) {
15354
15365
  const own = staticSafeArea(format, placements);
15355
- const rendered = ratioValue2(renderRatio);
15366
+ const rendered = ratioValue2(frame);
15356
15367
  const delivered = ratioValue2(format);
15357
15368
  const keepH = rendered < delivered ? rendered / delivered : 1;
15358
15369
  const keepW = rendered > delivered ? delivered / rendered : 1;
15359
- const safe = {
15370
+ return {
15360
15371
  top: (1 - keepH) / 2 + own.top * keepH,
15361
15372
  bottom: (1 - keepH) / 2 + own.bottom * keepH,
15362
15373
  left: (1 - keepW) / 2 + own.left * keepW,
15363
15374
  right: (1 - keepW) / 2 + own.right * keepW
15364
15375
  };
15365
- return {
15366
- format,
15367
- ...placements && placements.length > 0 ? { placements: [...placements] } : {},
15368
- renderRatio,
15369
- size: deliveredSize(format),
15370
- safe
15371
- };
15372
15376
  }
15373
15377
  function trimmedRenderBand(plan) {
15374
15378
  const own = staticSafeArea(plan.format, plan.placements);
@@ -15498,6 +15502,9 @@ function adaptBrief(spec, profile, opts) {
15498
15502
  scaleText(plan, spec, flowing, zoned, short)
15499
15503
  ];
15500
15504
  paragraphs.splice(textAt + 1, 0, ...added);
15505
+ } else if (zoned) {
15506
+ const layoutAt = paragraphs.findIndex((p) => p.startsWith("Layout:"));
15507
+ paragraphs.splice(layoutAt > 0 ? layoutAt : 1, 0, zonesText(plan, flowing, ground, short));
15501
15508
  }
15502
15509
  return paragraphs.join("\n\n");
15503
15510
  };
@@ -15565,9 +15572,17 @@ function formatOfSize(size) {
15565
15572
  const g = gcd(size.width, size.height);
15566
15573
  return `${size.width / g}:${size.height / g}`;
15567
15574
  }
15568
- function safeAreaOf(format) {
15569
- const { top, bottom, left, right } = staticSafeArea(format);
15570
- return { top, bottom, left, right };
15575
+ function safeAreaOf(adaptFormat, delivered) {
15576
+ const { top, bottom, left, right } = staticSafeArea(adaptFormat);
15577
+ return delivered.map((f) => safeAreaOnFrame(adaptFormat, f)).reduce(
15578
+ (a, b) => ({
15579
+ top: Math.max(a.top, b.top),
15580
+ bottom: Math.max(a.bottom, b.bottom),
15581
+ left: Math.max(a.left, b.left),
15582
+ right: Math.max(a.right, b.right)
15583
+ }),
15584
+ { top, bottom, left, right }
15585
+ );
15571
15586
  }
15572
15587
  function magick(id, role, image, args, extra = {}) {
15573
15588
  return {
@@ -15636,7 +15651,15 @@ function staticRenderNodes(g) {
15636
15651
  model: g.adaptModel,
15637
15652
  formats: adaptFormats,
15638
15653
  image_size: ADAPT_IMAGE_SIZE,
15639
- safe_areas: Object.fromEntries(adaptFormats.map((f) => [f, safeAreaOf(f)]))
15654
+ safe_areas: Object.fromEntries(
15655
+ adaptFormats.map((f) => [
15656
+ f,
15657
+ safeAreaOf(
15658
+ f,
15659
+ adapted.filter((s) => (s.adaptFormat ?? s.format) === f).map((s) => s.format)
15660
+ )
15661
+ ])
15662
+ )
15640
15663
  },
15641
15664
  tags: { role: STATIC_ADAPT_ROLE }
15642
15665
  });
@@ -21188,11 +21211,25 @@ function assign(targets, words, claimed, threshold) {
21188
21211
  }
21189
21212
  return matches;
21190
21213
  }
21191
- function joinHyphenBreaks(texts) {
21214
+ function hyphenatedCompounds(texts) {
21215
+ const out = /* @__PURE__ */ new Set();
21216
+ for (const text of texts) {
21217
+ for (const [compound] of text.normalize("NFKC").toLowerCase().matchAll(new RegExp("\\p{L}+(?:[-\u2010\u2011]\\p{L}+)+", "gu"))) {
21218
+ const words = compound.split(/[-‐‑]/u);
21219
+ for (let i = 1; i < words.length; i++) out.add(`${words[i - 1]}-${words[i]}`);
21220
+ }
21221
+ }
21222
+ return out;
21223
+ }
21224
+ function joinHyphenBreaks(texts, compounds) {
21192
21225
  const out = [];
21193
21226
  let carry = "";
21194
21227
  for (const text of texts) {
21195
- const line = carry + text.trim();
21228
+ const next = text.trim();
21229
+ const before = carry.match(new RegExp("\\p{L}+$", "u"))?.[0] ?? "";
21230
+ const after = next.match(new RegExp("^\\p{L}+", "u"))?.[0] ?? "";
21231
+ const own = carry !== "" && compounds.has(`${before}-${after}`.normalize("NFKC").toLowerCase());
21232
+ const line = carry + (own ? "-" : "") + next;
21196
21233
  const broken = line.match(new RegExp("^(.*\\p{L})[-\u2010\u2011]$", "u"));
21197
21234
  if (broken) carry = broken[1] ?? "";
21198
21235
  else {
@@ -21208,7 +21245,9 @@ function lineParts(text) {
21208
21245
  return parts.length > 0 ? parts : [text];
21209
21246
  }
21210
21247
  function textMismatch(expected, boxes, opts = {}) {
21211
- const words = joinHyphenBreaks(boxes.filter((b) => b.kind === "text").map((b) => b.text)).flatMap(
21248
+ const compounds = hyphenatedCompounds(expected.map((line) => line.text));
21249
+ const texts = boxes.filter((b) => b.kind === "text").map((b) => b.text);
21250
+ const words = joinHyphenBreaks(texts, compounds).flatMap(
21212
21251
  (text, box) => normalizeCopy(text).split(" ").filter((word) => word.length > 0).map((word) => ({ word, box }))
21213
21252
  );
21214
21253
  const claimed = /* @__PURE__ */ new Set();
@@ -21223,7 +21262,10 @@ function textMismatch(expected, boxes, opts = {}) {
21223
21262
  );
21224
21263
  assign((opts.allowed ?? []).map(normalizeCopy), words, claimed, ALLOWED_MATCH);
21225
21264
  const lines = expected.flatMap((line, index) => {
21226
- const lineMatches = parts.flatMap((part, partIndex) => part.lineIndex === index ? [matches.get(partIndex)] : []);
21265
+ const lineMatches = parts.flatMap(
21266
+ (part, partIndex) => part.lineIndex === index && part.text.length > 0 ? [matches.get(partIndex)] : []
21267
+ );
21268
+ if (lineMatches.length === 0) return [];
21227
21269
  const score = Math.min(...lineMatches.map((match) => match?.similarity ?? 0));
21228
21270
  if (score >= 1 - MAX_LINE_DISTANCE) return [];
21229
21271
  const read = lineMatches.flatMap((match) => match ? [match.span.text] : []).join(" ");
@@ -22268,7 +22310,7 @@ function rankOf(boxes, blocking, want) {
22268
22310
  const logoFound = boxes.some((b) => b.kind === "logo" || brand !== null && normalizeCopy(b.text) === brand);
22269
22311
  const noLogo = want.logo && !logoFound ? 1 : 0;
22270
22312
  const noButton = off.some((l) => want.buttons.has(l.text)) ? 1 : 0;
22271
- const outOfBand = bandViolations(boxes, want.format, { band: want.band }).length;
22313
+ const outOfBand = bandViolations(boxes, want.format, want.grade).length;
22272
22314
  return {
22273
22315
  rank: [blocking.length, off.length, noLogo, noButton, outOfBand],
22274
22316
  shortfalls: noLogo ? [NO_LOGO] : []
@@ -22303,6 +22345,7 @@ async function prefilterVariants(variants, spec, formats, opts = {}) {
22303
22345
  ...opts.placements ? { placements: opts.placements } : {}
22304
22346
  });
22305
22347
  const format = plan.master.format;
22348
+ const grade = plan.masterShape === "relayout" ? plan.placements ? { placements: plan.placements } : {} : { band: plan.band };
22306
22349
  const checked = await Promise.all(
22307
22350
  variants.map(async (variant) => {
22308
22351
  const source = variant.path ?? variant.url;
@@ -22314,7 +22357,7 @@ async function prefilterVariants(variants, spec, formats, opts = {}) {
22314
22357
  format,
22315
22358
  lines,
22316
22359
  allowed: brand ? [brand] : [],
22317
- band: plan.band,
22360
+ ...grade,
22318
22361
  toFrame: (boxes) => coverFitBoxes(boxes, { width, height }, plan.master.size),
22319
22362
  ...opts.read ? { read: opts.read } : {},
22320
22363
  ...opts.onSpend ? { onSpend: opts.onSpend } : {}
@@ -22322,7 +22365,7 @@ async function prefilterVariants(variants, spec, formats, opts = {}) {
22322
22365
  if (check.status === "not_checked") return { index: variant.index, blocking: null };
22323
22366
  const prefix = `${format}: `;
22324
22367
  const blocking = check.findings.filter((f) => f.severity === "blocking").map((f) => f.what.startsWith(prefix) ? f.what.slice(prefix.length) : f.what);
22325
- const want = { lines, buttons, ...brand ? { brand } : {}, logo, format, band: plan.band };
22368
+ const want = { lines, buttons, ...brand ? { brand } : {}, logo, format, grade };
22326
22369
  return { index: variant.index, blocking, ...rankOf(check.boxes, blocking, want) };
22327
22370
  } catch {
22328
22371
  return { index: variant.index, blocking: null };
@@ -24386,4 +24429,4 @@ export {
24386
24429
  defaultRegistry,
24387
24430
  createEngineFromEnv
24388
24431
  };
24389
- //# sourceMappingURL=chunk-IS5ERYGR.js.map
24432
+ //# sourceMappingURL=chunk-M2E2OYY6.js.map