@nodaro/prompts 1.50.1 → 1.51.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.
Files changed (73) hide show
  1. package/dist/{chunk-MJIKM4YZ.cjs → chunk-7BWDATUZ.cjs} +125 -125
  2. package/dist/{chunk-MJIKM4YZ.cjs.map → chunk-7BWDATUZ.cjs.map} +1 -1
  3. package/dist/{chunk-MUTUHJIV.js → chunk-CDTEETF3.js} +5 -2
  4. package/dist/chunk-CDTEETF3.js.map +1 -0
  5. package/dist/{chunk-WLN2MJ7F.cjs → chunk-E5EKWWOO.cjs} +3 -3
  6. package/dist/{chunk-3XSB5YDY.js.map → chunk-E5EKWWOO.cjs.map} +1 -1
  7. package/dist/{chunk-DB6A5I6V.js → chunk-ED47NNIN.js} +3 -3
  8. package/dist/{chunk-DB6A5I6V.js.map → chunk-ED47NNIN.js.map} +1 -1
  9. package/dist/{chunk-IXBTD2LW.js → chunk-EUU5W7XR.js} +4 -4
  10. package/dist/{chunk-IXBTD2LW.js.map → chunk-EUU5W7XR.js.map} +1 -1
  11. package/dist/{chunk-JGEBO6L6.cjs → chunk-F22GZF7T.cjs} +8 -8
  12. package/dist/{chunk-JGEBO6L6.cjs.map → chunk-F22GZF7T.cjs.map} +1 -1
  13. package/dist/{chunk-PLQFXCBU.cjs → chunk-GJV7KTDX.cjs} +5 -2
  14. package/dist/chunk-GJV7KTDX.cjs.map +1 -0
  15. package/dist/{chunk-RVBO63D5.cjs → chunk-GRSKB3P7.cjs} +2 -2
  16. package/dist/chunk-GRSKB3P7.cjs.map +1 -0
  17. package/dist/{chunk-3XSB5YDY.js → chunk-H322GC7M.js} +3 -3
  18. package/dist/chunk-H322GC7M.js.map +1 -0
  19. package/dist/{chunk-C5LP7DAQ.js → chunk-HETYHGGW.js} +6 -6
  20. package/dist/{chunk-C5LP7DAQ.js.map → chunk-HETYHGGW.js.map} +1 -1
  21. package/dist/{chunk-FEOVUTFC.js → chunk-HOZPYHRA.js} +5 -5
  22. package/dist/{chunk-FEOVUTFC.js.map → chunk-HOZPYHRA.js.map} +1 -1
  23. package/dist/{chunk-HR4TFBU2.cjs → chunk-KTNCB2IE.cjs} +35 -35
  24. package/dist/{chunk-HR4TFBU2.cjs.map → chunk-KTNCB2IE.cjs.map} +1 -1
  25. package/dist/{chunk-VYCTRGJ7.cjs → chunk-M6EXNY42.cjs} +39 -39
  26. package/dist/{chunk-VYCTRGJ7.cjs.map → chunk-M6EXNY42.cjs.map} +1 -1
  27. package/dist/{chunk-IADAATZK.cjs → chunk-OQ3J7OGR.cjs} +49 -49
  28. package/dist/{chunk-IADAATZK.cjs.map → chunk-OQ3J7OGR.cjs.map} +1 -1
  29. package/dist/{chunk-KYKCHOOS.cjs → chunk-P4BXE4OA.cjs} +13 -13
  30. package/dist/{chunk-KYKCHOOS.cjs.map → chunk-P4BXE4OA.cjs.map} +1 -1
  31. package/dist/{chunk-TYJCCODP.cjs → chunk-PWYASBX2.cjs} +18 -18
  32. package/dist/{chunk-TYJCCODP.cjs.map → chunk-PWYASBX2.cjs.map} +1 -1
  33. package/dist/{chunk-IWX3Q7NH.cjs → chunk-RPGJTLLF.cjs} +20 -11
  34. package/dist/chunk-RPGJTLLF.cjs.map +1 -0
  35. package/dist/{chunk-LJ5WW6KK.js → chunk-T4TZY5ST.js} +20 -11
  36. package/dist/chunk-T4TZY5ST.js.map +1 -0
  37. package/dist/{chunk-VJYKE6AY.js → chunk-VBCVQPQ4.js} +3 -3
  38. package/dist/{chunk-VJYKE6AY.js.map → chunk-VBCVQPQ4.js.map} +1 -1
  39. package/dist/{chunk-34JK2G34.js → chunk-WQ7FWGZ2.js} +2 -2
  40. package/dist/chunk-WQ7FWGZ2.js.map +1 -0
  41. package/dist/{chunk-ZZ6UOK2P.js → chunk-YAIPYPMM.js} +4 -4
  42. package/dist/{chunk-ZZ6UOK2P.js.map → chunk-YAIPYPMM.js.map} +1 -1
  43. package/dist/{chunk-BWDQEAX2.js → chunk-ZRORO6OM.js} +4 -4
  44. package/dist/{chunk-BWDQEAX2.js.map → chunk-ZRORO6OM.js.map} +1 -1
  45. package/dist/entries/assembly.cjs +28 -28
  46. package/dist/entries/assembly.js +5 -5
  47. package/dist/entries/doctrine.cjs +46 -46
  48. package/dist/entries/doctrine.js +1 -1
  49. package/dist/entries/picker-art.cjs +3 -3
  50. package/dist/entries/picker-art.js +1 -1
  51. package/dist/entries/picker-catalogs.cjs +56 -56
  52. package/dist/entries/picker-catalogs.js +4 -4
  53. package/dist/entries/pickers.cjs +382 -382
  54. package/dist/entries/pickers.js +2 -2
  55. package/dist/entries/presets.cjs +35 -35
  56. package/dist/entries/presets.js +1 -1
  57. package/dist/entries/prompt-builder.cjs +75 -75
  58. package/dist/entries/prompt-builder.js +4 -4
  59. package/dist/index.cjs +618 -618
  60. package/dist/index.js +11 -11
  61. package/package.json +2 -2
  62. package/src/__tests__/style-video-wording.test.ts +1 -1
  63. package/src/factory-presets/shared-image.ts +2 -2
  64. package/src/picker-art/restyle-previews.ts +3 -0
  65. package/src/prompt-wizard-categories.ts +18 -9
  66. package/src/style.ts +1 -1
  67. package/dist/chunk-34JK2G34.js.map +0 -1
  68. package/dist/chunk-IWX3Q7NH.cjs.map +0 -1
  69. package/dist/chunk-LJ5WW6KK.js.map +0 -1
  70. package/dist/chunk-MUTUHJIV.js.map +0 -1
  71. package/dist/chunk-PLQFXCBU.cjs.map +0 -1
  72. package/dist/chunk-RVBO63D5.cjs.map +0 -1
  73. package/dist/chunk-WLN2MJ7F.cjs.map +0 -1
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkHR4TFBU2_cjs = require('./chunk-HR4TFBU2.cjs');
4
- var chunkWLN2MJ7F_cjs = require('./chunk-WLN2MJ7F.cjs');
3
+ var chunkKTNCB2IE_cjs = require('./chunk-KTNCB2IE.cjs');
4
+ var chunkE5EKWWOO_cjs = require('./chunk-E5EKWWOO.cjs');
5
5
  var chunk3UEA3UHQ_cjs = require('./chunk-3UEA3UHQ.cjs');
6
6
  var chunkK6NT635Z_cjs = require('./chunk-K6NT635Z.cjs');
7
7
  var chunkFY4AMIDB_cjs = require('./chunk-FY4AMIDB.cjs');
@@ -14,7 +14,7 @@ function optionsOf(catalog) {
14
14
  return (catalog.dimensions ?? []).flatMap((d) => d.options);
15
15
  }
16
16
  function getAdultOnlyEntries() {
17
- const catalogEntries = chunkWLN2MJ7F_cjs.getRegisteredPickerCatalogs().filter((c) => ADULT_SWEPT_CATALOG_ID_SET.has(c.catalogId)).flatMap(optionsOf);
17
+ const catalogEntries = chunkE5EKWWOO_cjs.getRegisteredPickerCatalogs().filter((c) => ADULT_SWEPT_CATALOG_ID_SET.has(c.catalogId)).flatMap(optionsOf);
18
18
  const all = [...chunkK6NT635Z_cjs.getRegisteredPeople(), ...catalogEntries];
19
19
  return all.filter((e) => e.adultOnly === true);
20
20
  }
@@ -221,7 +221,7 @@ function resolveParameterHint(node, ctx, inherited, surface = "image") {
221
221
  const mode = readHintMode(data) ?? inherited ?? "full";
222
222
  if (node.type === "camera-motion") {
223
223
  const motionId = asStr(data.cameraMotion) || void 0;
224
- if (!ctx) return withCustomText(data, chunkWLN2MJ7F_cjs.composeCameraMotionHintFromConnections(motionId, [], [], mode));
224
+ if (!ctx) return withCustomText(data, chunkE5EKWWOO_cjs.composeCameraMotionHintFromConnections(motionId, [], [], mode));
225
225
  const startHints = [];
226
226
  const endHints = [];
227
227
  for (const edge of ctx.edges) {
@@ -233,7 +233,7 @@ function resolveParameterHint(node, ctx, inherited, surface = "image") {
233
233
  if (edge.targetHandle === "startState") startHints.push(hint);
234
234
  else if (edge.targetHandle === "endState") endHints.push(hint);
235
235
  }
236
- return withCustomText(data, chunkWLN2MJ7F_cjs.composeCameraMotionHintFromConnections(motionId, startHints, endHints, mode));
236
+ return withCustomText(data, chunkE5EKWWOO_cjs.composeCameraMotionHintFromConnections(motionId, startHints, endHints, mode));
237
237
  }
238
238
  if (node.type === "transition") {
239
239
  const raw = data.transition;
@@ -243,10 +243,10 @@ function resolveParameterHint(node, ctx, inherited, surface = "image") {
243
243
  duration: asStr(data.duration),
244
244
  intensity: asStr(data.intensity)
245
245
  };
246
- const optionValues = chunkWLN2MJ7F_cjs.readTransitionOptionValues(data);
246
+ const optionValues = chunkE5EKWWOO_cjs.readTransitionOptionValues(data);
247
247
  const hintOptions = optionValues ? { optionValues } : void 0;
248
248
  if (!ctx) {
249
- return withCustomText(data, chunkWLN2MJ7F_cjs.composeTransitionHintFromConnections(transitionId, [], [], timing, mode, hintOptions));
249
+ return withCustomText(data, chunkE5EKWWOO_cjs.composeTransitionHintFromConnections(transitionId, [], [], timing, mode, hintOptions));
250
250
  }
251
251
  const startHints = [];
252
252
  const endHints = [];
@@ -259,7 +259,7 @@ function resolveParameterHint(node, ctx, inherited, surface = "image") {
259
259
  if (edge.targetHandle === "startState") startHints.push(hint);
260
260
  else if (edge.targetHandle === "endState") endHints.push(hint);
261
261
  }
262
- return withCustomText(data, chunkWLN2MJ7F_cjs.composeTransitionHintFromConnections(transitionId, startHints, endHints, timing, mode, hintOptions));
262
+ return withCustomText(data, chunkE5EKWWOO_cjs.composeTransitionHintFromConnections(transitionId, startHints, endHints, timing, mode, hintOptions));
263
263
  }
264
264
  if (node.type === "character-fx") {
265
265
  const raw = data.characterFx;
@@ -270,7 +270,7 @@ function resolveParameterHint(node, ctx, inherited, surface = "image") {
270
270
  intensity: asStr(data.intensity)
271
271
  };
272
272
  if (!ctx) {
273
- return withCustomText(data, chunkWLN2MJ7F_cjs.composeCharacterFxHintFromConnections(effectId, [], timing, mode));
273
+ return withCustomText(data, chunkE5EKWWOO_cjs.composeCharacterFxHintFromConnections(effectId, [], timing, mode));
274
274
  }
275
275
  const targetNames = [];
276
276
  for (const edge of ctx.edges) {
@@ -281,7 +281,7 @@ function resolveParameterHint(node, ctx, inherited, surface = "image") {
281
281
  const name = extractCharacterRefName(src);
282
282
  if (name) targetNames.push(name);
283
283
  }
284
- return withCustomText(data, chunkWLN2MJ7F_cjs.composeCharacterFxHintFromConnections(effectId, targetNames, timing, mode));
284
+ return withCustomText(data, chunkE5EKWWOO_cjs.composeCharacterFxHintFromConnections(effectId, targetNames, timing, mode));
285
285
  }
286
286
  if (node.type === "character-motion") {
287
287
  const raw = data.characterMotion;
@@ -291,17 +291,17 @@ function resolveParameterHint(node, ctx, inherited, surface = "image") {
291
291
  pace: asStr(data.pace)
292
292
  };
293
293
  if (!ctx) {
294
- return withCustomText(data, chunkWLN2MJ7F_cjs.composeCharacterMotionHintFromConnections(motionId, [], [], timing, mode));
294
+ return withCustomText(data, chunkE5EKWWOO_cjs.composeCharacterMotionHintFromConnections(motionId, [], [], timing, mode));
295
295
  }
296
296
  const { targetNames, partnerNames, subjectMinor } = getCharacterMotionBindings(node, ctx);
297
297
  return withCustomText(
298
298
  data,
299
- chunkWLN2MJ7F_cjs.composeCharacterMotionHintFromConnections(motionId, targetNames, partnerNames, timing, mode, { subjectMinor })
299
+ chunkE5EKWWOO_cjs.composeCharacterMotionHintFromConnections(motionId, targetNames, partnerNames, timing, mode, { subjectMinor })
300
300
  );
301
301
  }
302
302
  const base = resolveBaseHint(node.type, data, mode, surface);
303
303
  if (base) return base;
304
- const cat = chunkWLN2MJ7F_cjs.getPickerCatalog(node.type);
304
+ const cat = chunkE5EKWWOO_cjs.getPickerCatalog(node.type);
305
305
  if (cat?.kind === "single" && cat.valueField) {
306
306
  const id = typeof data[cat.valueField] === "string" ? data[cat.valueField] : "";
307
307
  const opt = cat.options?.find((o) => o.id === id);
@@ -312,88 +312,88 @@ function resolveParameterHint(node, ctx, inherited, surface = "image") {
312
312
  function resolveBaseHint(type, data, mode = "full", surface = "image") {
313
313
  switch (type) {
314
314
  case "framing":
315
- return withCustomText(data, chunkWLN2MJ7F_cjs.buildFramingHints(data, false, mode).join(", "));
315
+ return withCustomText(data, chunkE5EKWWOO_cjs.buildFramingHints(data, false, mode).join(", "));
316
316
  case "lighting":
317
- return withCustomText(data, chunkWLN2MJ7F_cjs.buildLightingHints(data, mode).join(", "));
317
+ return withCustomText(data, chunkE5EKWWOO_cjs.buildLightingHints(data, mode).join(", "));
318
318
  case "lens":
319
- return withCustomText(data, byMode(mode, chunkWLN2MJ7F_cjs.getLensPromptHint, chunkWLN2MJ7F_cjs.getLensTerm)(asStr(data.lens)));
319
+ return withCustomText(data, byMode(mode, chunkE5EKWWOO_cjs.getLensPromptHint, chunkE5EKWWOO_cjs.getLensTerm)(asStr(data.lens)));
320
320
  case "camera-format":
321
- return withCustomText(data, byMode(mode, chunkWLN2MJ7F_cjs.getCameraFormatPromptHint, chunkWLN2MJ7F_cjs.getCameraFormatTerm)(asStr(data.cameraFormat)));
321
+ return withCustomText(data, byMode(mode, chunkE5EKWWOO_cjs.getCameraFormatPromptHint, chunkE5EKWWOO_cjs.getCameraFormatTerm)(asStr(data.cameraFormat)));
322
322
  case "color-look":
323
- return withCustomText(data, byMode(mode, chunkWLN2MJ7F_cjs.getColorLookPromptHint, chunkWLN2MJ7F_cjs.getColorLookTerm)(asStr(data.colorLook)));
323
+ return withCustomText(data, byMode(mode, chunkE5EKWWOO_cjs.getColorLookPromptHint, chunkE5EKWWOO_cjs.getColorLookTerm)(asStr(data.colorLook)));
324
324
  // build*Hints in music-* / voice-* / mood / person / etc. compose
325
325
  // preText/postText internally — bypass the wrapper to avoid double-
326
326
  // composition.
327
327
  case "music-genre":
328
- return chunkWLN2MJ7F_cjs.buildMusicGenreHints(data ?? {}, mode);
328
+ return chunkE5EKWWOO_cjs.buildMusicGenreHints(data ?? {}, mode);
329
329
  case "music-mood":
330
- return chunkWLN2MJ7F_cjs.buildMusicMoodHints(data ?? {}, mode);
330
+ return chunkE5EKWWOO_cjs.buildMusicMoodHints(data ?? {}, mode);
331
331
  case "instrumentation":
332
- return chunkWLN2MJ7F_cjs.buildInstrumentationHints(data ?? {}, mode);
332
+ return chunkE5EKWWOO_cjs.buildInstrumentationHints(data ?? {}, mode);
333
333
  case "voice-character":
334
- return chunkWLN2MJ7F_cjs.buildVoiceCharacterHints(data ?? {}, mode);
334
+ return chunkE5EKWWOO_cjs.buildVoiceCharacterHints(data ?? {}, mode);
335
335
  case "voice-delivery":
336
- return chunkWLN2MJ7F_cjs.buildVoiceDeliveryHints(data ?? {}, mode);
336
+ return chunkE5EKWWOO_cjs.buildVoiceDeliveryHints(data ?? {}, mode);
337
337
  case "person":
338
338
  return chunkK6NT635Z_cjs.buildPersonHints(data, mode).join(", ");
339
339
  case "mood":
340
- return chunkWLN2MJ7F_cjs.buildMoodHints(data, mode).join(", ");
340
+ return chunkE5EKWWOO_cjs.buildMoodHints(data, mode).join(", ");
341
341
  case "pose":
342
- return chunkWLN2MJ7F_cjs.buildPoseHints(data, mode).join(", ");
342
+ return chunkE5EKWWOO_cjs.buildPoseHints(data, mode).join(", ");
343
343
  case "styling":
344
- return chunkWLN2MJ7F_cjs.buildStylingHints(data, mode).join(", ");
344
+ return chunkE5EKWWOO_cjs.buildStylingHints(data, mode).join(", ");
345
345
  case "atmosphere":
346
- return withCustomText(data, chunkWLN2MJ7F_cjs.buildAtmosphereHints(data.atmosphere, mode).join(", "));
346
+ return withCustomText(data, chunkE5EKWWOO_cjs.buildAtmosphereHints(data.atmosphere, mode).join(", "));
347
347
  case "action-fx":
348
- return withCustomText(data, chunkWLN2MJ7F_cjs.buildActionFxHints(data.actionFx, mode).join(", "));
348
+ return withCustomText(data, chunkE5EKWWOO_cjs.buildActionFxHints(data.actionFx, mode).join(", "));
349
349
  case "style":
350
- return withCustomText(data, byMode(mode, surface === "video" ? chunkWLN2MJ7F_cjs.getStyleVideoPromptHint : chunkWLN2MJ7F_cjs.getStylePromptHint, chunkWLN2MJ7F_cjs.getStyleTerm)(asStr(data.style)));
350
+ return withCustomText(data, byMode(mode, surface === "video" ? chunkE5EKWWOO_cjs.getStyleVideoPromptHint : chunkE5EKWWOO_cjs.getStylePromptHint, chunkE5EKWWOO_cjs.getStyleTerm)(asStr(data.style)));
351
351
  case "setting":
352
- return withCustomText(data, byMode(mode, chunkWLN2MJ7F_cjs.getSettingPromptHint, chunkWLN2MJ7F_cjs.getSettingTerm)(asStr(data.setting)));
352
+ return withCustomText(data, byMode(mode, chunkE5EKWWOO_cjs.getSettingPromptHint, chunkE5EKWWOO_cjs.getSettingTerm)(asStr(data.setting)));
353
353
  case "loop-subject":
354
- return withCustomText(data, byMode(mode, chunkWLN2MJ7F_cjs.getLoopSubjectPromptHint, chunkWLN2MJ7F_cjs.getLoopSubjectTerm)(asStr(data.loopSubject)));
354
+ return withCustomText(data, byMode(mode, chunkE5EKWWOO_cjs.getLoopSubjectPromptHint, chunkE5EKWWOO_cjs.getLoopSubjectTerm)(asStr(data.loopSubject)));
355
355
  case "material":
356
- return withCustomText(data, chunkWLN2MJ7F_cjs.buildMaterialHints(data.material, mode));
356
+ return withCustomText(data, chunkE5EKWWOO_cjs.buildMaterialHints(data.material, mode));
357
357
  // The four object-entity catalogs are owned by @nodaro/shared and overlaid
358
358
  // in shared-catalog-overlay.ts — the ONE module every prompt-text read of
359
359
  // them goes through (the subject fold uses it too). Each returns "" on a
360
360
  // miss, so the entry lookup is the module's job, not this switch's.
361
361
  case "animal":
362
- return withCustomText(data, byMode(mode, chunkHR4TFBU2_cjs.curatedAnimalPromptHint, chunkHR4TFBU2_cjs.curatedAnimalTerm)(asStr(data.animal)));
362
+ return withCustomText(data, byMode(mode, chunkKTNCB2IE_cjs.curatedAnimalPromptHint, chunkKTNCB2IE_cjs.curatedAnimalTerm)(asStr(data.animal)));
363
363
  case "vehicle": {
364
- const t = chunkHR4TFBU2_cjs.curatedVehicleText(asStr(data.vehicle));
364
+ const t = chunkKTNCB2IE_cjs.curatedVehicleText(asStr(data.vehicle));
365
365
  return withCustomText(data, byMode(mode, t.hint, t.term));
366
366
  }
367
367
  case "weapon": {
368
- const t = chunkHR4TFBU2_cjs.curatedWeaponText(asStr(data.weapon));
368
+ const t = chunkKTNCB2IE_cjs.curatedWeaponText(asStr(data.weapon));
369
369
  return withCustomText(data, byMode(mode, t.hint, t.term));
370
370
  }
371
371
  case "furniture": {
372
- const t = chunkHR4TFBU2_cjs.curatedFurnitureText(asStr(data.furniture));
372
+ const t = chunkKTNCB2IE_cjs.curatedFurnitureText(asStr(data.furniture));
373
373
  return withCustomText(data, byMode(mode, t.hint, t.term));
374
374
  }
375
375
  case "photo-genre":
376
- return withCustomText(data, byMode(mode, chunkWLN2MJ7F_cjs.getPhotoGenrePromptHint, chunkWLN2MJ7F_cjs.getPhotoGenreTerm)(asStr(data.photoGenre)));
376
+ return withCustomText(data, byMode(mode, chunkE5EKWWOO_cjs.getPhotoGenrePromptHint, chunkE5EKWWOO_cjs.getPhotoGenreTerm)(asStr(data.photoGenre)));
377
377
  case "backdrop":
378
- return withCustomText(data, byMode(mode, chunkWLN2MJ7F_cjs.getBackdropPromptHint, chunkWLN2MJ7F_cjs.getBackdropTerm)(asStr(data.backdrop)));
378
+ return withCustomText(data, byMode(mode, chunkE5EKWWOO_cjs.getBackdropPromptHint, chunkE5EKWWOO_cjs.getBackdropTerm)(asStr(data.backdrop)));
379
379
  case "held-prop":
380
- return withCustomText(data, chunkWLN2MJ7F_cjs.buildHeldPropHints(data.heldProp, mode).join(", "));
380
+ return withCustomText(data, chunkE5EKWWOO_cjs.buildHeldPropHints(data.heldProp, mode).join(", "));
381
381
  case "photographer":
382
- return withCustomText(data, chunkWLN2MJ7F_cjs.buildPhotographerHints(data.photographer, mode));
382
+ return withCustomText(data, chunkE5EKWWOO_cjs.buildPhotographerHints(data.photographer, mode));
383
383
  case "aesthetic":
384
- return withCustomText(data, chunkWLN2MJ7F_cjs.buildAestheticHints(data.aesthetic, mode));
384
+ return withCustomText(data, chunkE5EKWWOO_cjs.buildAestheticHints(data.aesthetic, mode));
385
385
  case "era":
386
- return withCustomText(data, byMode(mode, chunkWLN2MJ7F_cjs.getEraPromptHint, chunkWLN2MJ7F_cjs.getEraTerm)(asStr(data.era)));
386
+ return withCustomText(data, byMode(mode, chunkE5EKWWOO_cjs.getEraPromptHint, chunkE5EKWWOO_cjs.getEraTerm)(asStr(data.era)));
387
387
  case "temporal":
388
- return withCustomText(data, chunkWLN2MJ7F_cjs.buildTemporalHints(data, mode).join(", "));
388
+ return withCustomText(data, chunkE5EKWWOO_cjs.buildTemporalHints(data, mode).join(", "));
389
389
  case "exposure-settings":
390
- return withCustomText(data, chunkWLN2MJ7F_cjs.buildExposureHints(data, mode).join(", "));
390
+ return withCustomText(data, chunkE5EKWWOO_cjs.buildExposureHints(data, mode).join(", "));
391
391
  case "render-quality":
392
- return withCustomText(data, byMode(mode, chunkWLN2MJ7F_cjs.getRenderQualityPromptHint, chunkWLN2MJ7F_cjs.getRenderQualityTerm)(asStr(data.renderQuality)));
392
+ return withCustomText(data, byMode(mode, chunkE5EKWWOO_cjs.getRenderQualityPromptHint, chunkE5EKWWOO_cjs.getRenderQualityTerm)(asStr(data.renderQuality)));
393
393
  case "composition-effects":
394
- return withCustomText(data, byMode(mode, chunkWLN2MJ7F_cjs.getCompositionEffectPromptHint, chunkWLN2MJ7F_cjs.getCompositionEffectTerm)(asStr(data.compositionEffect)));
394
+ return withCustomText(data, byMode(mode, chunkE5EKWWOO_cjs.getCompositionEffectPromptHint, chunkE5EKWWOO_cjs.getCompositionEffectTerm)(asStr(data.compositionEffect)));
395
395
  case "post-process-effects":
396
- return withCustomText(data, chunkWLN2MJ7F_cjs.buildPostProcessHints(data.postProcess, mode).join(", "));
396
+ return withCustomText(data, chunkE5EKWWOO_cjs.buildPostProcessHints(data.postProcess, mode).join(", "));
397
397
  // Motion intensity: a Generation Settings node that a video node's
398
398
  // Settings input takes as a prompt fragment (video only).
399
399
  case "motion": {
@@ -425,5 +425,5 @@ exports.getAdultOnlyIds = getAdultOnlyIds;
425
425
  exports.getCharacterMotionBindings = getCharacterMotionBindings;
426
426
  exports.getMinorAgeHintStrings = getMinorAgeHintStrings;
427
427
  exports.getParameterPromptHint = getParameterPromptHint;
428
- //# sourceMappingURL=chunk-IADAATZK.cjs.map
429
- //# sourceMappingURL=chunk-IADAATZK.cjs.map
428
+ //# sourceMappingURL=chunk-OQ3J7OGR.cjs.map
429
+ //# sourceMappingURL=chunk-OQ3J7OGR.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/age-floor.ts","../src/parameter-prompt-hint.ts"],"names":["getRegisteredPickerCatalogs","getRegisteredPeople","ADULT_AGE_IDS","MINOR_IMPLYING_TYPE_IDS","isMinorAge","joinHintFragments","composeCameraMotionHintFromConnections","readTransitionOptionValues","composeTransitionHintFromConnections","composeCharacterFxHintFromConnections","composeCharacterMotionHintFromConnections","getPickerCatalog","resolveTerm","buildFramingHints","buildLightingHints","getLensPromptHint","getLensTerm","getCameraFormatPromptHint","getCameraFormatTerm","getColorLookPromptHint","getColorLookTerm","buildMusicGenreHints","buildMusicMoodHints","buildInstrumentationHints","buildVoiceCharacterHints","buildVoiceDeliveryHints","buildPersonHints","buildMoodHints","buildPoseHints","buildStylingHints","buildAtmosphereHints","buildActionFxHints","getStyleVideoPromptHint","getStylePromptHint","getStyleTerm","getSettingPromptHint","getSettingTerm","getLoopSubjectPromptHint","getLoopSubjectTerm","buildMaterialHints","curatedAnimalPromptHint","curatedAnimalTerm","curatedVehicleText","curatedWeaponText","curatedFurnitureText","getPhotoGenrePromptHint","getPhotoGenreTerm","getBackdropPromptHint","getBackdropTerm","buildHeldPropHints","buildPhotographerHints","buildAestheticHints","getEraPromptHint","getEraTerm","buildTemporalHints","buildExposureHints","getRenderQualityPromptHint","getRenderQualityTerm","getCompositionEffectPromptHint","getCompositionEffectTerm","buildPostProcessHints"],"mappings":"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","file":"chunk-IADAATZK.cjs","sourcesContent":["/**\n * The minor-age floor — Layer 1 of spec 2026-09-01-app-reports-triage-design.md\n * §3.3 (W1-a). Content-free: this module decides WHICH catalog entries a minor\n * subject may not carry; the clause a deployment appends lives in its\n * registered PromptPolicy (backend/src/lib/prompt-policies/), never here.\n *\n * `ADULT_ONLY_FLAG`, `ADULT_AGE_IDS`, `MINOR_IMPLYING_TYPE_IDS` and\n * `isMinorAge` live in the import-free leaf `age-signal.ts` and are\n * re-exported here unchanged — this module's own catalog-funnel imports\n * (`person-packs.js`, `picker-catalogs.js`) are exactly what `person.ts` /\n * `styling.ts` must NOT reach through, on pain of reopening the\n * person → age-floor → picker-catalogs load-time cycle (see `age-signal.ts`'s\n * header). `person.ts` / `styling.ts` import `isMinorAge` from\n * `age-signal.ts` directly instead of from here.\n */\n\nimport { getRegisteredPeople } from \"./person-packs.js\"\nimport { getRegisteredPickerCatalogs, type PickerCatalog, type PickerOption } from \"./picker-catalogs.js\"\nimport { isMinorAge, ADULT_AGE_IDS, MINOR_IMPLYING_TYPE_IDS } from \"./age-signal.js\"\n\nexport { ADULT_ONLY_FLAG, ADULT_AGE_IDS, MINOR_IMPLYING_TYPE_IDS, isMinorAge } from \"./age-signal.js\"\n\n/** Shape shared by every catalog entry the floor reads. */\nexport interface AdultOnlyEntry {\n readonly id: string\n readonly promptHint: string\n readonly term?: string\n readonly adultOnly?: true\n}\n\n/** The picker catalogs (by `catalogId`) this floor sweeps beside person.\n * Exported because it is the SINGLE source of truth for two things that used\n * to be maintained by hand and drifted: which catalogs `getAdultOnlyEntries`\n * sweeps for the flag, and which analyzer keys `FLOORED_PICKER_KEYS` strips\n * flagged ids out of (a `photo-genre` swept for the flag but absent from the\n * strip list let `glamour-portrait` survive on a minor). */\nexport const ADULT_SWEPT_CATALOG_IDS = [\"styling\", \"mood\", \"pose\", \"photo-genre\", \"character-motion\"] as const\n\n/** Membership form of the list above (the sweep does one lookup per catalog). */\nconst ADULT_SWEPT_CATALOG_ID_SET: ReadonlySet<string> = new Set(ADULT_SWEPT_CATALOG_IDS)\n\n/** Flatten a catalog's options regardless of shape: single-dim catalogs carry\n * `options` directly, multi-dim ones carry `dimensions[].options` (mirrors\n * `applyDeny` in catalog-packs.ts, the other consumer that has to handle\n * both shapes). */\nfunction optionsOf(catalog: PickerCatalog): ReadonlyArray<PickerOption> {\n if (catalog.kind === \"single\") return catalog.options ?? []\n return (catalog.dimensions ?? []).flatMap((d) => d.options)\n}\n\n/** Every entry, across the swept catalogs, that carries the flag. Reads every\n * catalog through the pack-composed funnel — `getRegisteredPeople()` for\n * person, `getRegisteredPickerCatalogs()` for styling/mood/pose/photo-genre —\n * so a pack-added or pack-replaced entry is included. */\nexport function getAdultOnlyEntries(): ReadonlyArray<AdultOnlyEntry> {\n const catalogEntries = getRegisteredPickerCatalogs()\n .filter((c) => ADULT_SWEPT_CATALOG_ID_SET.has(c.catalogId))\n .flatMap(optionsOf)\n const all: ReadonlyArray<AdultOnlyEntry> = [...getRegisteredPeople(), ...catalogEntries]\n return all.filter((e) => e.adultOnly === true)\n}\n\n/** The set of flagged ids (fast membership for the collectors). */\nexport function getAdultOnlyIds(): ReadonlySet<string> {\n return new Set(getAdultOnlyEntries().map((e) => e.id))\n}\n\n/**\n * The pre-rework `promptHint` of every `adultOnly` entry the spec\n * (2026-09-01-app-reports-triage-design §3.3) listed for rewording — including\n * `eye-state-half-lidded` and `feature-collarbone-visible`, which the W1-b\n * harness initially left byte-identical (0/10 and 0/22 render rate under\n * either wording) and a 2026-09-03 replay then found renderable wordings for\n * — plus the hard-coded midriff+navel fold clause. These strings are permanently part of the strip\n * set: a consumer that has not bumped `@nodaro/prompts` still emits them, and\n * the client-assembled `seedPrompt` path is exactly how the 2026-07-30\n * minor-age prompts reached a provider. Retiring can only ever cause an EXTRA\n * strip, and only for a subject `isMinorAge` has already judged a minor — so\n * the list only grows, never shrinks.\n *\n * `promptHint` ONLY, for the same reason `getAdultOnlyHintStrings` gives:\n * `term` is short display vocabulary and the composed-catalog projection\n * back-fills a derived `term` for every option, so terms collide with benign\n * everyday text. Assembled prompts and client seedPrompts are built from\n * hints, never from terms. The three W1-b entries that are NOT flagged —\n * `texture-dewy`, `texture-baby-soft`, `eye-state-staring-camera` (spec\n * §3.3's \"deliberately not flagged\" list) — are absent: their old wording\n * never belonged to the floor.\n *\n * 15 flagged hints + the fold literal = 16.\n */\nexport const RETIRED_ADULT_ONLY_HINT_STRINGS: ReadonlyArray<string> = [\n // bust-very-full\n \"very full bust\",\n // silhouette-hourglass\n \"hourglass silhouette\",\n // waist-defined\n \"defined waist\",\n // lip-state-glossy\n \"with high-shine glossy wet-look lips\",\n // lip-state-parted\n \"with lips slightly parted, taking a soft breath\",\n // lip-state-bitten\n \"playfully biting the lower lip\",\n // eye-state-half-lidded\n \"with heavy half-lidded sleepy eyes\",\n // texture-glistening\n \"with glistening skin, sweat or oil catching the light\",\n // texture-shower-fresh-wet\n \"with just-out-of-the-shower wet skin, water beading on the surface and rolling in slow droplets down the curves of the body\",\n // feature-bare-shoulders\n \"with bare shoulders exposed, the line of the collarbone and shoulder muscles uncovered\",\n // feature-collarbone-visible\n \"with a prominent collarbone clearly defined and catching the light\",\n // feature-midriff-visible\n \"wearing a cropped style with the midriff visible\",\n // state-fitted — the 2026-07-30 incident clause\n \"the clothing fitted and form-conscious, hugging the contours of the body\",\n // state-wet\n \"the clothing soaked and wet, the fabric clinging to the body and dripping water\",\n // pose `biting-lip` (the lip-state-bitten twin)\n \"biting the lower lip with a subtle playful expression\",\n // the hard-coded midriff+navel fold in emitIndependentFragments — not any\n // entry's hint, so retiring it ADDS a needle for a clause that really is\n // emitted verbatim.\n \"wearing a cropped style, midriff and navel visible\",\n]\n\n/** Every full prompt-hint string a flagged entry can inject, lower-cased,\n * longest first — the backend policy strips text that contains any of them\n * (Layer 2), which is how flagged wording arriving inside free text (a\n * client-assembled seedPrompt) is caught. Seeded with\n * `RETIRED_ADULT_ONLY_HINT_STRINGS` so a catalog rewording can never narrow\n * the strip set for a consumer still shipping the pre-rephrase wording.\n *\n * `promptHint` ONLY, deliberately — `term` is analyzer/UI vocabulary\n * (compact-mode display), and `picker-catalogs.ts`'s composed-catalog\n * projection back-fills a `term` for EVERY option via `deriveTerm(label)`\n * when no explicit term was authored (e.g. \"lounging\", \"cropped top\",\n * \"school uniform\", \"lying down\"). Those short, generic derived terms are\n * exactly the kind of everyday word that collides with unrelated, benign\n * text and over-strips it. Assembled prompts and client seedPrompts are\n * built from HINTS, never from terms, so hints are the only strings that\n * can actually arrive verbatim in free text — terms don't need to be (and\n * must not be) swept here. */\nexport function getAdultOnlyHintStrings(): ReadonlyArray<string> {\n const out = new Set<string>(RETIRED_ADULT_ONLY_HINT_STRINGS)\n for (const e of getAdultOnlyEntries()) {\n if (e.promptHint) out.add(e.promptHint.toLowerCase())\n }\n return [...out].filter((s) => s.length >= 8).sort((a, b) => b.length - a.length)\n}\n\n/**\n * Every full prompt-hint string that DESCRIBES A MINOR — the mirror of\n * `getAdultOnlyHintStrings`, and the needle list for the TEXT signal below.\n *\n * Why a text signal exists at all: `isMinorAge` reads the structured picker\n * value, and the P0 arrival path does not have one. A thin client can create a\n * character row carrying only `{nodeId, name, projectId}` and send the picker\n * selection as an already-assembled `seedPrompt`, so `row.person === null`\n * while the prompt itself says \"a young child around 5 years old\". That client\n * assembles the text FROM THESE HINTS, which is exactly why the catalog is the\n * drift-proof needle list: a new minor age entry is swept the day it is added,\n * with no second list to remember.\n *\n * Selection is DERIVED, never hand-listed: an `age` entry is a minor unless its\n * id is in the `ADULT_AGE_IDS` allow-list (so a new age id is inside the floor\n * by default — same ratchet as `isMinorAge`), plus every `type` entry named by\n * `MINOR_IMPLYING_TYPE_IDS`. Read through the pack-composed funnel\n * (`getRegisteredPeople()`), so a deployment pack's entries are swept too.\n *\n * `promptHint` ONLY — never `term` and never `label`, for the same reason\n * `getAdultOnlyHintStrings` gives: `term` is short display vocabulary\n * (\"in their teens\" as a compact chip) and the composed-catalog projection\n * back-fills a derived `term` for every option, so terms collide with benign\n * text. The `>= 8` filter drops `age-custom`'s empty hint (`\"\"`), which would\n * otherwise match every string ever written.\n */\nlet cachedMinorHints: ReadonlyArray<string> | null = null\nlet cachedMinorHintSourceCount = -1\nexport function getMinorAgeHintStrings(): ReadonlyArray<string> {\n const people = getRegisteredPeople()\n if (cachedMinorHints && cachedMinorHintSourceCount === people.length) return cachedMinorHints\n const out = new Set<string>()\n for (const e of people) {\n const minorAge = e.dimension === \"age\" && !ADULT_AGE_IDS.has(e.id)\n const minorType = e.dimension === \"type\" && MINOR_IMPLYING_TYPE_IDS.has(e.id)\n if (!minorAge && !minorType) continue\n if (e.promptHint) out.add(e.promptHint.toLowerCase())\n }\n cachedMinorHintSourceCount = people.length\n cachedMinorHints = [...out].filter((s) => s.length >= 8).sort((a, b) => b.length - a.length)\n return cachedMinorHints\n}\n\nfunction escapeReSource(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n}\n\n/** One needle's regex source: the phrase's tokens — split on whitespace AND\n * hyphens — escaped and rejoined by `[\\s-]+`, so it matches however the text\n * that carries it happened to be spaced or hyphenated. */\nfunction needleTokenSource(needle: string): string {\n return needle\n .trim()\n .split(/[\\s-]+/)\n .filter((t) => t.length > 0)\n .map(escapeReSource)\n .join(\"[\\\\s-]+\")\n}\n\n/**\n * The word-bounded alternation SOURCE for a needle list — the one place both\n * layers of the floor build their matcher, so they can never disagree about\n * what \"the same phrase\" means.\n *\n * Two properties, both load-bearing:\n * - **Separator tolerance.** A catalog hint is authored with single spaces\n * (\"very full bust\"), but the free text that carries it is written by a\n * human or an LLM and arrives as \"very-full bust\" or \"very full bust\".\n * A literal alternation misses those, and a miss is a flagged phrase\n * reaching the provider on a minor's prompt. Each needle's tokens are\n * joined by `[\\s-]+`, which requires AT LEAST one separator — so\n * \"very fullbust\" (no separator at all) is still not a match, and the\n * phrase can't silently widen into a substring rule.\n * - **Word boundaries.** `(?<![\\w-])` / `(?![\\w-])` keep a needle from\n * gluing onto an adjacent word's characters (\"mesh tops\" must survive a\n * \"mesh top\" needle).\n *\n * Ordering is the CALLER's: pass needles longest-first so the alternation\n * consumes the longest match at a given position instead of leaving debris.\n * Returns `null` when there is nothing to match (an empty list would otherwise\n * compile to `(?:)`, which matches everywhere). Flags are the caller's too —\n * `\"i\"` for a `.test()` instance, `\"gi\"` for one used with `String.replace`.\n */\nexport function buildNeedleAlternationSource(needles: ReadonlyArray<string>): string | null {\n const alts = needles.map(needleTokenSource).filter((s) => s.length > 0)\n if (alts.length === 0) return null\n return `(?<![\\\\w-])(?:${alts.join(\"|\")})(?![\\\\w-])`\n}\n\n/** Needle alternation over `getMinorAgeHintStrings()`, word-bounded on both\n * sides so a hint can only match a whole phrase. Deliberately NOT global:\n * this instance is only ever `.test()`ed, and a `/g` regex would carry\n * `lastIndex` across calls. Cached by needle count (packs are registered\n * before the first prompt is assembled). */\nlet cachedMinorNeedleRe: RegExp | null = null\nlet cachedMinorNeedleCount = -1\nfunction minorNeedleRegex(): RegExp | null {\n const needles = getMinorAgeHintStrings()\n if (cachedMinorNeedleRe && cachedMinorNeedleCount === needles.length) return cachedMinorNeedleRe\n cachedMinorNeedleCount = needles.length\n const src = buildNeedleAlternationSource(needles)\n cachedMinorNeedleRe = src === null ? null : new RegExp(src, \"i\")\n return cachedMinorNeedleRe\n}\n\n/**\n * NUMBER-FIRST age shapes: the ones `buildAgeFragment` (person.ts) emits for a\n * CUSTOM age (\"N years old\", \"N year old\", \"N-year-old\") and the catalog's own\n * \"2-3 years old\" range (the FIRST number decides), plus the colloquial tails a\n * human or an LLM writes instead — \"12yo\", \"12 yo\", \"12 y.o.\", \"12 y/o\",\n * \"12 yr old\", \"12-yr-old\", \"12yrs old\", \"12 years of age\". The cut is `< 20`,\n * the same boundary `isMinorAge` uses for `customAge` and the same one\n * `buildAgeFragment` switches to \"in their teens\" at.\n *\n * Both boundaries are load-bearing. The LEADING one stops a match inside a\n * larger token; the TRAILING one is what makes \"a 5 year older sibling\" a\n * non-hit (\"old\" may not glue onto \"older\") and what stops \"yo\" from firing\n * inside \"12 young\" or \"12 yoga\". Used via `matchAll`, which clones the regex\n * rather than advancing this instance's `lastIndex`.\n */\nconst NUMERIC_AGE_RE =\n /(?<![\\w-])(\\d{1,3})(?:\\s*-\\s*\\d{1,3})?\\s*-?\\s*(?:years?\\s*-?\\s*old|yrs?\\s*-?\\s*old|y(?:\\.\\s*o\\.?|\\/o|o)|years?\\s+of\\s+age)(?![\\w-])/gi\n\n/**\n * AGE-FIRST shapes, where the number trails the word instead of leading it:\n * \"age 12\", \"aged 12\", \"at the age of 12\". The leading boundary is what keeps\n * \"image 12\" / \"page 12\" out (the `age` there is glued to a preceding word\n * character), and the trailing one keeps \"aged 12th\" out.\n */\nconst PREFIXED_AGE_RE = /(?<![\\w-])aged?\\s+(?:of\\s+)?(\\d{1,3})(?![\\w-])/gi\n\n/** Every rule that reads a NUMBER out of the text, each capturing the age in\n * group 1. Iterated together below so a new shape is one array entry. */\nconst AGE_NUMBER_RULES: ReadonlyArray<RegExp> = [NUMERIC_AGE_RE, PREFIXED_AGE_RE]\n\n/** The one NON-numeric shape `buildAgeFragment` emits below 20 (`${n} years\n * old, in their teens`). Kept as its own rule rather than as a catalog term.\n * Separator-tolerant on the same terms as the needle alternation, so\n * \"in their teens\" and \"in-their-teens\" are the same phrase. */\nconst IN_THEIR_TEENS_RE = /(?<![\\w-])in[\\s-]+their[\\s-]+teens(?![\\w-])/i\n\n/**\n * True when free text describes a MINOR subject. Three rules, in order:\n * 1. any minor-age / minor-implying-type prompt hint, word-bounded;\n * 2. a numeric age below 20 in any shape `buildAgeFragment` emits;\n * 3. the literal \"in their teens\".\n *\n * Deliberately NOT a bare-word check: \"child\", \"teen\", \"kid\" alone must never\n * fire, or an adult prompt that merely MENTIONS a child (\"a mother holding her\n * child\") would be floored — the spec's \"adults are byte-identical\" is a hard\n * requirement, so every rule here is a full phrase or a bounded number.\n *\n * Pairs with `isMinorAge`, never replaces it: the structured picker value is\n * the primary signal; this catches the same subject when only the assembled\n * text survives.\n */\nexport function containsMinorAgeHint(text: string | null | undefined): boolean {\n if (typeof text !== \"string\" || text.trim().length === 0) return false\n const re = minorNeedleRegex()\n if (re && re.test(text)) return true\n for (const rule of AGE_NUMBER_RULES) {\n for (const m of text.matchAll(rule)) {\n const n = Number(m[1])\n if (Number.isFinite(n) && n < 20) return true\n }\n }\n return IN_THEIR_TEENS_RE.test(text)\n}\n\n/** The analyzer/import value keys the floor strips flagged ids out of:\n * `person` plus EVERY catalog the flag sweep reads. DERIVED, never\n * hand-listed — the hand-written version omitted `photo-genre` while the\n * sweep included it, so a minor kept `glamour-portrait`. The analyzer JSON is\n * keyed by picker type id (`describe-to-picker.ts`), which is the same string\n * as the catalog id, so this list IS the set of keys to visit. */\nexport const FLOORED_PICKER_KEYS = [\"person\", ...ADULT_SWEPT_CATALOG_IDS] as const\n\nfunction stripIds(obj: Record<string, unknown>, drop: ReadonlySet<string>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(obj)) {\n if (typeof v === \"string\") {\n if (!drop.has(v)) out[k] = v\n } else if (Array.isArray(v)) {\n const kept = v.filter((x) => !(typeof x === \"string\" && drop.has(x)))\n if (kept.length > 0) out[k] = kept\n } else {\n out[k] = v\n }\n }\n return out\n}\n\n/** Analyzer / import post-filter: when the person value describes a minor,\n * remove every flagged id from the person, styling, pose and mood values.\n * Identity (same reference) for an adult. */\nexport function applyMinorAgeFloorToPickerValues<T extends Record<string, unknown>>(values: T): T {\n const person = values.person\n if (!person || typeof person !== \"object\" || !isMinorAge(person as { age?: string; customAge?: number; type?: string })) return values\n const drop = getAdultOnlyIds()\n const out: Record<string, unknown> = { ...values }\n for (const key of FLOORED_PICKER_KEYS) {\n const v = out[key]\n if (v && typeof v === \"object\" && !Array.isArray(v)) out[key] = stripIds(v as Record<string, unknown>, drop)\n }\n return out as T\n}\n","import type { HintNodeLike, HintEdgeLike, HintGraphContext } from \"@nodaro/shared/types\"\nexport type { HintNodeLike, HintEdgeLike, HintGraphContext }\n/**\n * Single source of truth for parameter-node prompt-hint text.\n *\n * Every parameter node (framing, lens, camera-format, lighting, color-look,\n * atmosphere, style, setting, person, mood, pose, styling, temporal, tone,\n * text-prompt, camera-motion) dispatches through `getParameterPromptHint` to\n * produce the descriptive clause it contributes to a consumer's prompt.\n *\n * The frontend DAG executor and backend workflow orchestrator both call this,\n * so the text injected via the `cinematography` handle is identical to the\n * text injected when the node is wired directly into a Text Prompt / LLM Chat\n * / Combine Text input.\n *\n * Camera-motion is graph-aware: when `ctx` is provided the function walks the\n * node's `startState`/`endState` incoming edges and composes a fully formed\n * sentence via `composeCameraMotionHintFromConnections`. Without `ctx` only\n * the bare motion description is returned.\n */\n\nimport { buildFramingHints } from \"./framing.js\"\nimport { buildLightingHints } from \"./lighting.js\"\nimport { getLensPromptHint, getLensTerm } from \"./lens.js\"\nimport { getCameraFormatPromptHint, getCameraFormatTerm } from \"./camera-format.js\"\nimport { getColorLookPromptHint, getColorLookTerm } from \"./color-look.js\"\nimport { buildAtmosphereHints } from \"./atmosphere.js\"\nimport { buildActionFxHints } from \"./action-fx.js\"\nimport { getStylePromptHint, getStyleTerm, getStyleVideoPromptHint } from \"./style.js\"\nimport { getSettingPromptHint, getSettingTerm } from \"./setting.js\"\nimport { getLoopSubjectPromptHint, getLoopSubjectTerm } from \"./loop-subject.js\"\nimport { buildPersonHints } from \"./person.js\"\nimport { buildMoodHints } from \"./mood.js\"\nimport { buildPoseHints } from \"./pose.js\"\nimport { buildStylingHints } from \"./styling.js\"\nimport { buildTemporalHints } from \"./temporal.js\"\nimport { composeCameraMotionHintFromConnections } from \"./camera-motions.js\"\nimport { joinHintFragments } from \"./hint-join.js\"\nimport { composeTransitionHintFromConnections, readTransitionOptionValues, type TransitionDuration, type TransitionIntensity, type TransitionPosition, type TransitionTiming } from \"./transitions.js\"\nimport { composeCharacterFxHintFromConnections, type CharacterFxDuration, type CharacterFxIntensity, type CharacterFxPosition, type CharacterFxTiming } from \"./character-fx.js\"\nimport { composeCharacterMotionHintFromConnections, type CharacterMotionPace, type CharacterMotionPosition, type CharacterMotionTiming } from \"./character-motion.js\"\nimport { containsMinorAgeHint, isMinorAge } from \"./age-floor.js\"\nimport { buildMaterialHints } from \"./materials.js\"\nimport { curatedAnimalPromptHint, curatedAnimalTerm, curatedVehicleText, curatedWeaponText, curatedFurnitureText } from \"./shared-catalog-overlay.js\"\nimport { getPhotoGenrePromptHint, getPhotoGenreTerm } from \"./photo-genre.js\"\nimport { getBackdropPromptHint, getBackdropTerm } from \"./backdrop.js\"\nimport { buildHeldPropHints } from \"./held-prop.js\"\nimport { buildPhotographerHints } from \"./photographer.js\"\nimport { buildAestheticHints } from \"./aesthetic.js\"\nimport { getEraPromptHint, getEraTerm } from \"./era.js\"\nimport { buildExposureHints } from \"./exposure-settings.js\"\nimport { getRenderQualityPromptHint, getRenderQualityTerm } from \"./render-quality.js\"\nimport { getCompositionEffectPromptHint, getCompositionEffectTerm } from \"./composition-effects.js\"\nimport { buildPostProcessHints } from \"./post-process-effects.js\"\nimport { buildMusicGenreHints } from \"./music-genre.js\"\nimport { buildMusicMoodHints } from \"./music-mood.js\"\nimport { buildInstrumentationHints } from \"./instrumentation.js\"\nimport { buildVoiceCharacterHints } from \"./voice-character.js\"\nimport { buildVoiceDeliveryHints } from \"./voice-delivery.js\"\nimport { getPickerCatalog } from \"./picker-catalogs.js\"\nimport { resolveTerm, type PickerHintMode } from \"./term.js\"\n\n\nfunction asStr(v: unknown): string {\n return typeof v === \"string\" ? v : \"\"\n}\n\n/** Extract the display name from a character / face / object / location ref node. */\nfunction extractCharacterRefName(node: HintNodeLike): string | undefined {\n const d = (node.data ?? {}) as Record<string, unknown>\n const candidates = [d.characterName, d.faceName, d.objectName, d.locationName]\n for (const v of candidates) {\n if (typeof v === \"string\" && v.trim().length > 0) return v.trim()\n }\n return undefined\n}\n\n/** Character Motion's name read: the shared character / face / object / location\n * read, then a creature's `creatureName`. Local to Character Motion so the\n * Character FX prompt, which shares `extractCharacterRefName`, stays unchanged. */\nfunction extractCharacterMotionRefName(node: HintNodeLike): string | undefined {\n const name = extractCharacterRefName(node)\n if (name) return name\n const creatureName = asStr(((node.data ?? {}) as Record<string, unknown>).creatureName).trim()\n return creatureName.length > 0 ? creatureName : undefined\n}\n\n/** Free-text fields a character / face / object / location ref node describes its subject in.\n * A creature ref uses the same `description` / `canonicalDescription` names. */\nconst REF_DESCRIPTION_FIELDS = [\"description\", \"seedPrompt\", \"canonicalDescription\"] as const\n\n/** True when a character / face / object / location ref node describes a minor:\n * its structured `person` age (the primary signal) or an age phrase in its\n * free-text description. Feeds the Character Motion floor (adult-only moves\n * dropped) — errs toward flooring, never toward letting an adult-only move through. */\nfunction extractCharacterRefMinor(node: HintNodeLike): boolean {\n const d = (node.data ?? {}) as Record<string, unknown>\n const person = d.person\n if (person && typeof person === \"object\" && !Array.isArray(person) && isMinorAge(person as Parameters<typeof isMinorAge>[0])) {\n return true\n }\n return REF_DESCRIPTION_FIELDS.some((field) => containsMinorAgeHint(asStr(d[field])))\n}\n\n/** The preview, diagnostics and execution use identical graph bindings. */\nexport function getCharacterMotionBindings(node: HintNodeLike, ctx?: HintGraphContext) {\n const targetNames: string[] = []\n const partnerNames: string[] = []\n const targetIds = new Set<string>()\n const partnerIds = new Set<string>()\n let subjectMinor = false\n for (const edge of ctx?.edges ?? []) {\n if (edge.target !== node.id || (edge.targetHandle !== \"target\" && edge.targetHandle !== \"partner\")) continue\n const src = ctx?.nodes.find(n => n.id === edge.source)\n if (!src) continue\n if (edge.targetHandle === \"target\") targetIds.add(src.id)\n else partnerIds.add(src.id)\n if (extractCharacterRefMinor(src)) subjectMinor = true\n const name = extractCharacterMotionRefName(src)\n if (!name) continue\n const names = edge.targetHandle === \"target\" ? targetNames : partnerNames\n if (!names.includes(name)) names.push(name)\n }\n return { targetNames, partnerNames, subjectMinor, selfPairing: [...targetIds].some(id => partnerIds.has(id)) }\n}\n\n/** Compose `[preText, mainHint, postText]` into a comma-joined string,\n * honoring the user's free-text fragments around the structured hint.\n * Helpers like `getStylePromptHint` that already include preText/postText\n * composition (build*Hints in mood/person/etc.) bypass this — they\n * return the fully-composed string directly. */\nfunction withCustomText(data: Record<string, unknown>, mainHint: string): string {\n const fragments: string[] = []\n const pre = typeof data.preText === \"string\" ? data.preText.trim() : \"\"\n if (pre) fragments.push(pre)\n if (mainHint) fragments.push(mainHint)\n const post = typeof data.postText === \"string\" ? data.postText.trim() : \"\"\n if (post) fragments.push(post)\n return joinHintFragments(fragments)\n}\n\n/**\n * The node-level hint mode a picker declares via `data.hintMode`.\n *\n * Only the two documented values count; anything else (a stale value, a typo,\n * a non-string) is treated as UNDECLARED and falls back — to the inherited\n * mode when the node is resolved as an upstream input, and to `\"full\"`\n * otherwise. Compact is opt-in, so an unrecognized value can never silently\n * shorten a prompt.\n */\nfunction readHintMode(data: Record<string, unknown>): PickerHintMode | undefined {\n const raw = data.hintMode\n return raw === \"compact\" || raw === \"full\" ? raw : undefined\n}\n\n/** Pick the full-hint or the compact-term getter for the active mode. */\nfunction byMode<T>(mode: PickerHintMode, full: T, compact: T): T {\n return mode === \"compact\" ? compact : full\n}\n\n/** How much a shot moves (the Motion node's three steps), as the clause it\n * adds to a video prompt; the compact form is the bare term. */\nconst MOTION_INTENSITY_HINTS: Readonly<Record<string, { readonly full: string; readonly compact: string }>> = {\n subtle: { full: \"subtle, gentle motion with slow, minimal movement\", compact: \"subtle motion\" },\n moderate: { full: \"moderate, natural motion at an even pace\", compact: \"moderate motion\" },\n dynamic: { full: \"dynamic, energetic motion with fast, pronounced movement\", compact: \"dynamic motion\" },\n}\n\n/**\n * Dispatch by parameter-node type to its prompt-hint string. For camera-motion,\n * pass `ctx` to include the composed start/end clauses; otherwise only the\n * bare motion description is returned.\n *\n * VERBOSITY — a picker node may set `data.hintMode` to `\"compact\"` to inject\n * its short professional `term` (\"whip pan left\", \"hard cut\") instead of the\n * long `promptHint`. Absent, or any unrecognized value, means `\"full\"`, whose\n * output is byte-identical to what this function returned before hint modes\n * existed. ONLY the base catalog fragment swaps: `preText`/`postText`, the\n * transition / camera-motion / character-fx timing and start-state/end-state\n * clauses, multi-pick joining and multi-dimension composition are emitted the\n * same way in both modes.\n *\n * SURFACE — `opts.surface: \"video\"` is for a caller folding the hint into ONE\n * video consumer's prompt (the canvas's video nodes): a Style node then injects\n * its video wording (`getStyleVideoPromptHint`). Absent (or `\"image\"`) is the\n * output this function always returned — what a still, a `{Label}` reference\n * and every preview of the node's own text read, since a node's own output\n * text has no single consumer. Every other node type ignores it.\n */\nexport function getParameterPromptHint(\n node: HintNodeLike | undefined,\n ctx?: HintGraphContext,\n opts?: ParameterHintOptions,\n): string {\n return resolveParameterHint(node, ctx, undefined, opts?.surface === \"video\" ? \"video\" : \"image\")\n}\n\n/** How `getParameterPromptHint` resolves a node. */\nexport interface ParameterHintOptions {\n /** The stage the hint is folded into. Absent = `\"image\"`. */\n readonly surface?: \"image\" | \"video\"\n}\n\n/**\n * The dispatch body. `inherited` carries the mode DOWN into the nodes wired to\n * a composer's `startState` / `endState` handles, so a compact transition\n * composes compact start/end clauses rather than mixing a term with two\n * paragraphs. A node that declares its own `hintMode` still wins over what it\n * inherits.\n */\nfunction resolveParameterHint(\n node: HintNodeLike | undefined,\n ctx?: HintGraphContext,\n inherited?: PickerHintMode,\n surface: \"image\" | \"video\" = \"image\",\n): string {\n if (!node?.type) return \"\"\n const data = (node.data ?? {}) as Record<string, unknown>\n const mode: PickerHintMode = readHintMode(data) ?? inherited ?? \"full\"\n\n if (node.type === \"camera-motion\") {\n const motionId = asStr(data.cameraMotion) || undefined\n if (!ctx) return withCustomText(data, composeCameraMotionHintFromConnections(motionId, [], [], mode))\n const startHints: string[] = []\n const endHints: string[] = []\n for (const edge of ctx.edges) {\n if (edge.target !== node.id) continue\n const src = ctx.nodes.find((n) => n.id === edge.source)\n if (!src) continue\n // Pass no ctx for nested resolution: startState/endState inputs are\n // themselves parameter nodes (framing/tone/etc.) that don't need graph\n // context, and avoiding recursion keeps the walk cycle-safe. The mode\n // rides down so the composed clause stays at one level of detail.\n const hint = resolveParameterHint(src, undefined, mode, surface)\n if (!hint) continue\n if (edge.targetHandle === \"startState\") startHints.push(hint)\n else if (edge.targetHandle === \"endState\") endHints.push(hint)\n }\n return withCustomText(data, composeCameraMotionHintFromConnections(motionId, startHints, endHints, mode))\n }\n\n if (node.type === \"transition\") {\n const raw = data.transition\n const transitionId: string | string[] | undefined =\n Array.isArray(raw)\n ? raw.filter((s): s is string => typeof s === \"string\" && s.length > 0)\n : (asStr(raw) || undefined)\n const timing: TransitionTiming = {\n position: asStr(data.position) as TransitionPosition | undefined,\n duration: asStr(data.duration) as TransitionDuration | undefined,\n intensity: asStr(data.intensity) as TransitionIntensity | undefined,\n }\n // A picked row's own options (a wipe's `wipeDirection`), off the same node data.\n const optionValues = readTransitionOptionValues(data)\n const hintOptions = optionValues ? { optionValues } : undefined\n if (!ctx) {\n return withCustomText(data, composeTransitionHintFromConnections(transitionId, [], [], timing, mode, hintOptions))\n }\n const startHints: string[] = []\n const endHints: string[] = []\n for (const edge of ctx.edges) {\n if (edge.target !== node.id) continue\n const src = ctx.nodes.find((n) => n.id === edge.source)\n if (!src) continue\n const hint = resolveParameterHint(src, undefined, mode, surface) // no ctx — cycle-safe\n if (!hint) continue\n if (edge.targetHandle === \"startState\") startHints.push(hint)\n else if (edge.targetHandle === \"endState\") endHints.push(hint)\n }\n return withCustomText(data, composeTransitionHintFromConnections(transitionId, startHints, endHints, timing, mode, hintOptions))\n }\n\n if (node.type === \"character-fx\") {\n const raw = data.characterFx\n const effectId: string | string[] | undefined =\n Array.isArray(raw)\n ? raw.filter((s): s is string => typeof s === \"string\" && s.length > 0)\n : (asStr(raw) || undefined)\n const timing: CharacterFxTiming = {\n position: asStr(data.position) as CharacterFxPosition | undefined,\n duration: asStr(data.duration) as CharacterFxDuration | undefined,\n intensity: asStr(data.intensity) as CharacterFxIntensity | undefined,\n }\n if (!ctx) {\n return withCustomText(data, composeCharacterFxHintFromConnections(effectId, [], timing, mode))\n }\n const targetNames: string[] = []\n for (const edge of ctx.edges) {\n if (edge.target !== node.id) continue\n if (edge.targetHandle !== \"target\") continue\n const src = ctx.nodes.find((n) => n.id === edge.source)\n if (!src) continue\n const name = extractCharacterRefName(src)\n if (name) targetNames.push(name)\n }\n return withCustomText(data, composeCharacterFxHintFromConnections(effectId, targetNames, timing, mode))\n }\n\n if (node.type === \"character-motion\") {\n const raw = data.characterMotion\n const motionId: string | string[] | undefined =\n Array.isArray(raw)\n ? raw.filter((s): s is string => typeof s === \"string\" && s.length > 0)\n : (asStr(raw) || undefined)\n const timing: CharacterMotionTiming = {\n position: asStr(data.position) as CharacterMotionPosition | undefined,\n pace: asStr(data.pace) as CharacterMotionPace | undefined,\n }\n if (!ctx) {\n return withCustomText(data, composeCharacterMotionHintFromConnections(motionId, [], [], timing, mode))\n }\n const { targetNames, partnerNames, subjectMinor } = getCharacterMotionBindings(node, ctx)\n return withCustomText(\n data,\n composeCharacterMotionHintFromConnections(motionId, targetNames, partnerNames, timing, mode, { subjectMinor }),\n )\n }\n\n const base = resolveBaseHint(node.type, data, mode, surface)\n if (base) return base\n // Pack-extend fallback: a single-dim pack entry the per-catalog getter (which\n // reads the frozen base array) can't resolve. Resolve it against the\n // registered (pack-composed) catalog's options. Composition already resolved\n // `PickerOption.term`; `resolveTerm` is idempotent over a resolved option and\n // is called anyway so a pack option that reached this array by some other\n // route still injects SOMETHING in compact mode rather than `undefined`.\n const cat = getPickerCatalog(node.type)\n if (cat?.kind === \"single\" && cat.valueField) {\n const id = typeof data[cat.valueField] === \"string\" ? (data[cat.valueField] as string) : \"\"\n const opt = cat.options?.find((o) => o.id === id)\n if (opt) return byMode(mode, surface === \"video\" ? (opt.videoPromptHint ?? opt.promptHint) : opt.promptHint, resolveTerm(opt))\n }\n return base\n}\n\n/**\n * Base (upstream) hint dispatch by node type — the per-catalog getters read the\n * frozen base arrays. Pack-added single-dim ids are resolved by the caller\n * against the registered (pack-composed) catalog.\n *\n * `mode` selects the base fragment only: the compact `get<Name>Term` getter /\n * `build<Name>Terms` builder instead of the verbose one. The `withCustomText`\n * wrapper, the builders' own pre/post composition, and the free-text node\n * types (tone / style-guide / text-prompt — user prose, not catalog copy) are\n * identical in both modes.\n */\nfunction resolveBaseHint(\n type: string,\n data: Record<string, unknown>,\n mode: PickerHintMode = \"full\",\n surface: \"image\" | \"video\" = \"image\",\n): string {\n switch (type) {\n case \"framing\":\n return withCustomText(data, buildFramingHints(data, false, mode).join(\", \"))\n case \"lighting\":\n return withCustomText(data, buildLightingHints(data, mode).join(\", \"))\n case \"lens\":\n return withCustomText(data, byMode(mode, getLensPromptHint, getLensTerm)(asStr(data.lens)))\n case \"camera-format\":\n return withCustomText(data, byMode(mode, getCameraFormatPromptHint, getCameraFormatTerm)(asStr(data.cameraFormat)))\n case \"color-look\":\n return withCustomText(data, byMode(mode, getColorLookPromptHint, getColorLookTerm)(asStr(data.colorLook)))\n\n // build*Hints in music-* / voice-* / mood / person / etc. compose\n // preText/postText internally — bypass the wrapper to avoid double-\n // composition.\n case \"music-genre\":\n return buildMusicGenreHints((data ?? {}) as Parameters<typeof buildMusicGenreHints>[0], mode)\n case \"music-mood\":\n return buildMusicMoodHints((data ?? {}) as Parameters<typeof buildMusicMoodHints>[0], mode)\n case \"instrumentation\":\n return buildInstrumentationHints((data ?? {}) as Parameters<typeof buildInstrumentationHints>[0], mode)\n case \"voice-character\":\n return buildVoiceCharacterHints((data ?? {}) as Parameters<typeof buildVoiceCharacterHints>[0], mode)\n case \"voice-delivery\":\n return buildVoiceDeliveryHints((data ?? {}) as Parameters<typeof buildVoiceDeliveryHints>[0], mode)\n case \"person\":\n return buildPersonHints(data, mode).join(\", \")\n case \"mood\":\n return buildMoodHints(data, mode).join(\", \")\n case \"pose\":\n return buildPoseHints(data, mode).join(\", \")\n case \"styling\":\n return buildStylingHints(data, mode).join(\", \")\n\n case \"atmosphere\":\n return withCustomText(data, buildAtmosphereHints(data.atmosphere, mode).join(\", \"))\n case \"action-fx\":\n return withCustomText(data, buildActionFxHints(data.actionFx, mode).join(\", \"))\n case \"style\":\n return withCustomText(data, byMode(mode, surface === \"video\" ? getStyleVideoPromptHint : getStylePromptHint, getStyleTerm)(asStr(data.style)))\n case \"setting\":\n return withCustomText(data, byMode(mode, getSettingPromptHint, getSettingTerm)(asStr(data.setting)))\n case \"loop-subject\":\n return withCustomText(data, byMode(mode, getLoopSubjectPromptHint, getLoopSubjectTerm)(asStr(data.loopSubject)))\n case \"material\":\n return withCustomText(data, buildMaterialHints(data.material, mode))\n // The four object-entity catalogs are owned by @nodaro/shared and overlaid\n // in shared-catalog-overlay.ts — the ONE module every prompt-text read of\n // them goes through (the subject fold uses it too). Each returns \"\" on a\n // miss, so the entry lookup is the module's job, not this switch's.\n case \"animal\":\n return withCustomText(data, byMode(mode, curatedAnimalPromptHint, curatedAnimalTerm)(asStr(data.animal)))\n case \"vehicle\": {\n const t = curatedVehicleText(asStr(data.vehicle))\n return withCustomText(data, byMode(mode, t.hint, t.term))\n }\n case \"weapon\": {\n const t = curatedWeaponText(asStr(data.weapon))\n return withCustomText(data, byMode(mode, t.hint, t.term))\n }\n case \"furniture\": {\n const t = curatedFurnitureText(asStr(data.furniture))\n return withCustomText(data, byMode(mode, t.hint, t.term))\n }\n case \"photo-genre\":\n return withCustomText(data, byMode(mode, getPhotoGenrePromptHint, getPhotoGenreTerm)(asStr(data.photoGenre)))\n case \"backdrop\":\n return withCustomText(data, byMode(mode, getBackdropPromptHint, getBackdropTerm)(asStr(data.backdrop)))\n case \"held-prop\":\n return withCustomText(data, buildHeldPropHints(data.heldProp, mode).join(\", \"))\n case \"photographer\":\n return withCustomText(data, buildPhotographerHints(data.photographer, mode))\n case \"aesthetic\":\n return withCustomText(data, buildAestheticHints(data.aesthetic, mode))\n case \"era\":\n return withCustomText(data, byMode(mode, getEraPromptHint, getEraTerm)(asStr(data.era)))\n case \"temporal\":\n return withCustomText(data, buildTemporalHints(data, mode).join(\", \"))\n case \"exposure-settings\":\n return withCustomText(data, buildExposureHints(data, mode).join(\", \"))\n case \"render-quality\":\n return withCustomText(data, byMode(mode, getRenderQualityPromptHint, getRenderQualityTerm)(asStr(data.renderQuality)))\n case \"composition-effects\":\n return withCustomText(data, byMode(mode, getCompositionEffectPromptHint, getCompositionEffectTerm)(asStr(data.compositionEffect)))\n case \"post-process-effects\":\n return withCustomText(data, buildPostProcessHints(data.postProcess, mode).join(\", \"))\n // Motion intensity: a Generation Settings node that a video node's\n // Settings input takes as a prompt fragment (video only).\n case \"motion\": {\n const hint = MOTION_INTENSITY_HINTS[asStr(data.motion)]\n return hint ? byMode(mode, hint.full, hint.compact) : \"\"\n }\n\n // Free text authored by the user, not catalog copy — there is no shorter\n // professional form to swap in, so these are identical in both modes.\n case \"tone\":\n return asStr(data.tone).trim()\n case \"style-guide\":\n // The node's whole purpose is injecting its style text into consumer\n // prompts; without this case, {Style Guide} refs stayed as literal\n // brace text and direct wires injected nothing (only fieldMappings\n // worked, via getParameterValue).\n return asStr(data.text).trim()\n case \"text-prompt\":\n return asStr(data.text).trim()\n default:\n return \"\"\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/age-floor.ts","../src/parameter-prompt-hint.ts"],"names":["getRegisteredPickerCatalogs","getRegisteredPeople","ADULT_AGE_IDS","MINOR_IMPLYING_TYPE_IDS","isMinorAge","joinHintFragments","composeCameraMotionHintFromConnections","readTransitionOptionValues","composeTransitionHintFromConnections","composeCharacterFxHintFromConnections","composeCharacterMotionHintFromConnections","getPickerCatalog","resolveTerm","buildFramingHints","buildLightingHints","getLensPromptHint","getLensTerm","getCameraFormatPromptHint","getCameraFormatTerm","getColorLookPromptHint","getColorLookTerm","buildMusicGenreHints","buildMusicMoodHints","buildInstrumentationHints","buildVoiceCharacterHints","buildVoiceDeliveryHints","buildPersonHints","buildMoodHints","buildPoseHints","buildStylingHints","buildAtmosphereHints","buildActionFxHints","getStyleVideoPromptHint","getStylePromptHint","getStyleTerm","getSettingPromptHint","getSettingTerm","getLoopSubjectPromptHint","getLoopSubjectTerm","buildMaterialHints","curatedAnimalPromptHint","curatedAnimalTerm","curatedVehicleText","curatedWeaponText","curatedFurnitureText","getPhotoGenrePromptHint","getPhotoGenreTerm","getBackdropPromptHint","getBackdropTerm","buildHeldPropHints","buildPhotographerHints","buildAestheticHints","getEraPromptHint","getEraTerm","buildTemporalHints","buildExposureHints","getRenderQualityPromptHint","getRenderQualityTerm","getCompositionEffectPromptHint","getCompositionEffectTerm","buildPostProcessHints"],"mappings":"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","file":"chunk-OQ3J7OGR.cjs","sourcesContent":["/**\n * The minor-age floor — Layer 1 of spec 2026-09-01-app-reports-triage-design.md\n * §3.3 (W1-a). Content-free: this module decides WHICH catalog entries a minor\n * subject may not carry; the clause a deployment appends lives in its\n * registered PromptPolicy (backend/src/lib/prompt-policies/), never here.\n *\n * `ADULT_ONLY_FLAG`, `ADULT_AGE_IDS`, `MINOR_IMPLYING_TYPE_IDS` and\n * `isMinorAge` live in the import-free leaf `age-signal.ts` and are\n * re-exported here unchanged — this module's own catalog-funnel imports\n * (`person-packs.js`, `picker-catalogs.js`) are exactly what `person.ts` /\n * `styling.ts` must NOT reach through, on pain of reopening the\n * person → age-floor → picker-catalogs load-time cycle (see `age-signal.ts`'s\n * header). `person.ts` / `styling.ts` import `isMinorAge` from\n * `age-signal.ts` directly instead of from here.\n */\n\nimport { getRegisteredPeople } from \"./person-packs.js\"\nimport { getRegisteredPickerCatalogs, type PickerCatalog, type PickerOption } from \"./picker-catalogs.js\"\nimport { isMinorAge, ADULT_AGE_IDS, MINOR_IMPLYING_TYPE_IDS } from \"./age-signal.js\"\n\nexport { ADULT_ONLY_FLAG, ADULT_AGE_IDS, MINOR_IMPLYING_TYPE_IDS, isMinorAge } from \"./age-signal.js\"\n\n/** Shape shared by every catalog entry the floor reads. */\nexport interface AdultOnlyEntry {\n readonly id: string\n readonly promptHint: string\n readonly term?: string\n readonly adultOnly?: true\n}\n\n/** The picker catalogs (by `catalogId`) this floor sweeps beside person.\n * Exported because it is the SINGLE source of truth for two things that used\n * to be maintained by hand and drifted: which catalogs `getAdultOnlyEntries`\n * sweeps for the flag, and which analyzer keys `FLOORED_PICKER_KEYS` strips\n * flagged ids out of (a `photo-genre` swept for the flag but absent from the\n * strip list let `glamour-portrait` survive on a minor). */\nexport const ADULT_SWEPT_CATALOG_IDS = [\"styling\", \"mood\", \"pose\", \"photo-genre\", \"character-motion\"] as const\n\n/** Membership form of the list above (the sweep does one lookup per catalog). */\nconst ADULT_SWEPT_CATALOG_ID_SET: ReadonlySet<string> = new Set(ADULT_SWEPT_CATALOG_IDS)\n\n/** Flatten a catalog's options regardless of shape: single-dim catalogs carry\n * `options` directly, multi-dim ones carry `dimensions[].options` (mirrors\n * `applyDeny` in catalog-packs.ts, the other consumer that has to handle\n * both shapes). */\nfunction optionsOf(catalog: PickerCatalog): ReadonlyArray<PickerOption> {\n if (catalog.kind === \"single\") return catalog.options ?? []\n return (catalog.dimensions ?? []).flatMap((d) => d.options)\n}\n\n/** Every entry, across the swept catalogs, that carries the flag. Reads every\n * catalog through the pack-composed funnel — `getRegisteredPeople()` for\n * person, `getRegisteredPickerCatalogs()` for styling/mood/pose/photo-genre —\n * so a pack-added or pack-replaced entry is included. */\nexport function getAdultOnlyEntries(): ReadonlyArray<AdultOnlyEntry> {\n const catalogEntries = getRegisteredPickerCatalogs()\n .filter((c) => ADULT_SWEPT_CATALOG_ID_SET.has(c.catalogId))\n .flatMap(optionsOf)\n const all: ReadonlyArray<AdultOnlyEntry> = [...getRegisteredPeople(), ...catalogEntries]\n return all.filter((e) => e.adultOnly === true)\n}\n\n/** The set of flagged ids (fast membership for the collectors). */\nexport function getAdultOnlyIds(): ReadonlySet<string> {\n return new Set(getAdultOnlyEntries().map((e) => e.id))\n}\n\n/**\n * The pre-rework `promptHint` of every `adultOnly` entry the spec\n * (2026-09-01-app-reports-triage-design §3.3) listed for rewording — including\n * `eye-state-half-lidded` and `feature-collarbone-visible`, which the W1-b\n * harness initially left byte-identical (0/10 and 0/22 render rate under\n * either wording) and a 2026-09-03 replay then found renderable wordings for\n * — plus the hard-coded midriff+navel fold clause. These strings are permanently part of the strip\n * set: a consumer that has not bumped `@nodaro/prompts` still emits them, and\n * the client-assembled `seedPrompt` path is exactly how the 2026-07-30\n * minor-age prompts reached a provider. Retiring can only ever cause an EXTRA\n * strip, and only for a subject `isMinorAge` has already judged a minor — so\n * the list only grows, never shrinks.\n *\n * `promptHint` ONLY, for the same reason `getAdultOnlyHintStrings` gives:\n * `term` is short display vocabulary and the composed-catalog projection\n * back-fills a derived `term` for every option, so terms collide with benign\n * everyday text. Assembled prompts and client seedPrompts are built from\n * hints, never from terms. The three W1-b entries that are NOT flagged —\n * `texture-dewy`, `texture-baby-soft`, `eye-state-staring-camera` (spec\n * §3.3's \"deliberately not flagged\" list) — are absent: their old wording\n * never belonged to the floor.\n *\n * 15 flagged hints + the fold literal = 16.\n */\nexport const RETIRED_ADULT_ONLY_HINT_STRINGS: ReadonlyArray<string> = [\n // bust-very-full\n \"very full bust\",\n // silhouette-hourglass\n \"hourglass silhouette\",\n // waist-defined\n \"defined waist\",\n // lip-state-glossy\n \"with high-shine glossy wet-look lips\",\n // lip-state-parted\n \"with lips slightly parted, taking a soft breath\",\n // lip-state-bitten\n \"playfully biting the lower lip\",\n // eye-state-half-lidded\n \"with heavy half-lidded sleepy eyes\",\n // texture-glistening\n \"with glistening skin, sweat or oil catching the light\",\n // texture-shower-fresh-wet\n \"with just-out-of-the-shower wet skin, water beading on the surface and rolling in slow droplets down the curves of the body\",\n // feature-bare-shoulders\n \"with bare shoulders exposed, the line of the collarbone and shoulder muscles uncovered\",\n // feature-collarbone-visible\n \"with a prominent collarbone clearly defined and catching the light\",\n // feature-midriff-visible\n \"wearing a cropped style with the midriff visible\",\n // state-fitted — the 2026-07-30 incident clause\n \"the clothing fitted and form-conscious, hugging the contours of the body\",\n // state-wet\n \"the clothing soaked and wet, the fabric clinging to the body and dripping water\",\n // pose `biting-lip` (the lip-state-bitten twin)\n \"biting the lower lip with a subtle playful expression\",\n // the hard-coded midriff+navel fold in emitIndependentFragments — not any\n // entry's hint, so retiring it ADDS a needle for a clause that really is\n // emitted verbatim.\n \"wearing a cropped style, midriff and navel visible\",\n]\n\n/** Every full prompt-hint string a flagged entry can inject, lower-cased,\n * longest first — the backend policy strips text that contains any of them\n * (Layer 2), which is how flagged wording arriving inside free text (a\n * client-assembled seedPrompt) is caught. Seeded with\n * `RETIRED_ADULT_ONLY_HINT_STRINGS` so a catalog rewording can never narrow\n * the strip set for a consumer still shipping the pre-rephrase wording.\n *\n * `promptHint` ONLY, deliberately — `term` is analyzer/UI vocabulary\n * (compact-mode display), and `picker-catalogs.ts`'s composed-catalog\n * projection back-fills a `term` for EVERY option via `deriveTerm(label)`\n * when no explicit term was authored (e.g. \"lounging\", \"cropped top\",\n * \"school uniform\", \"lying down\"). Those short, generic derived terms are\n * exactly the kind of everyday word that collides with unrelated, benign\n * text and over-strips it. Assembled prompts and client seedPrompts are\n * built from HINTS, never from terms, so hints are the only strings that\n * can actually arrive verbatim in free text — terms don't need to be (and\n * must not be) swept here. */\nexport function getAdultOnlyHintStrings(): ReadonlyArray<string> {\n const out = new Set<string>(RETIRED_ADULT_ONLY_HINT_STRINGS)\n for (const e of getAdultOnlyEntries()) {\n if (e.promptHint) out.add(e.promptHint.toLowerCase())\n }\n return [...out].filter((s) => s.length >= 8).sort((a, b) => b.length - a.length)\n}\n\n/**\n * Every full prompt-hint string that DESCRIBES A MINOR — the mirror of\n * `getAdultOnlyHintStrings`, and the needle list for the TEXT signal below.\n *\n * Why a text signal exists at all: `isMinorAge` reads the structured picker\n * value, and the P0 arrival path does not have one. A thin client can create a\n * character row carrying only `{nodeId, name, projectId}` and send the picker\n * selection as an already-assembled `seedPrompt`, so `row.person === null`\n * while the prompt itself says \"a young child around 5 years old\". That client\n * assembles the text FROM THESE HINTS, which is exactly why the catalog is the\n * drift-proof needle list: a new minor age entry is swept the day it is added,\n * with no second list to remember.\n *\n * Selection is DERIVED, never hand-listed: an `age` entry is a minor unless its\n * id is in the `ADULT_AGE_IDS` allow-list (so a new age id is inside the floor\n * by default — same ratchet as `isMinorAge`), plus every `type` entry named by\n * `MINOR_IMPLYING_TYPE_IDS`. Read through the pack-composed funnel\n * (`getRegisteredPeople()`), so a deployment pack's entries are swept too.\n *\n * `promptHint` ONLY — never `term` and never `label`, for the same reason\n * `getAdultOnlyHintStrings` gives: `term` is short display vocabulary\n * (\"in their teens\" as a compact chip) and the composed-catalog projection\n * back-fills a derived `term` for every option, so terms collide with benign\n * text. The `>= 8` filter drops `age-custom`'s empty hint (`\"\"`), which would\n * otherwise match every string ever written.\n */\nlet cachedMinorHints: ReadonlyArray<string> | null = null\nlet cachedMinorHintSourceCount = -1\nexport function getMinorAgeHintStrings(): ReadonlyArray<string> {\n const people = getRegisteredPeople()\n if (cachedMinorHints && cachedMinorHintSourceCount === people.length) return cachedMinorHints\n const out = new Set<string>()\n for (const e of people) {\n const minorAge = e.dimension === \"age\" && !ADULT_AGE_IDS.has(e.id)\n const minorType = e.dimension === \"type\" && MINOR_IMPLYING_TYPE_IDS.has(e.id)\n if (!minorAge && !minorType) continue\n if (e.promptHint) out.add(e.promptHint.toLowerCase())\n }\n cachedMinorHintSourceCount = people.length\n cachedMinorHints = [...out].filter((s) => s.length >= 8).sort((a, b) => b.length - a.length)\n return cachedMinorHints\n}\n\nfunction escapeReSource(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n}\n\n/** One needle's regex source: the phrase's tokens — split on whitespace AND\n * hyphens — escaped and rejoined by `[\\s-]+`, so it matches however the text\n * that carries it happened to be spaced or hyphenated. */\nfunction needleTokenSource(needle: string): string {\n return needle\n .trim()\n .split(/[\\s-]+/)\n .filter((t) => t.length > 0)\n .map(escapeReSource)\n .join(\"[\\\\s-]+\")\n}\n\n/**\n * The word-bounded alternation SOURCE for a needle list — the one place both\n * layers of the floor build their matcher, so they can never disagree about\n * what \"the same phrase\" means.\n *\n * Two properties, both load-bearing:\n * - **Separator tolerance.** A catalog hint is authored with single spaces\n * (\"very full bust\"), but the free text that carries it is written by a\n * human or an LLM and arrives as \"very-full bust\" or \"very full bust\".\n * A literal alternation misses those, and a miss is a flagged phrase\n * reaching the provider on a minor's prompt. Each needle's tokens are\n * joined by `[\\s-]+`, which requires AT LEAST one separator — so\n * \"very fullbust\" (no separator at all) is still not a match, and the\n * phrase can't silently widen into a substring rule.\n * - **Word boundaries.** `(?<![\\w-])` / `(?![\\w-])` keep a needle from\n * gluing onto an adjacent word's characters (\"mesh tops\" must survive a\n * \"mesh top\" needle).\n *\n * Ordering is the CALLER's: pass needles longest-first so the alternation\n * consumes the longest match at a given position instead of leaving debris.\n * Returns `null` when there is nothing to match (an empty list would otherwise\n * compile to `(?:)`, which matches everywhere). Flags are the caller's too —\n * `\"i\"` for a `.test()` instance, `\"gi\"` for one used with `String.replace`.\n */\nexport function buildNeedleAlternationSource(needles: ReadonlyArray<string>): string | null {\n const alts = needles.map(needleTokenSource).filter((s) => s.length > 0)\n if (alts.length === 0) return null\n return `(?<![\\\\w-])(?:${alts.join(\"|\")})(?![\\\\w-])`\n}\n\n/** Needle alternation over `getMinorAgeHintStrings()`, word-bounded on both\n * sides so a hint can only match a whole phrase. Deliberately NOT global:\n * this instance is only ever `.test()`ed, and a `/g` regex would carry\n * `lastIndex` across calls. Cached by needle count (packs are registered\n * before the first prompt is assembled). */\nlet cachedMinorNeedleRe: RegExp | null = null\nlet cachedMinorNeedleCount = -1\nfunction minorNeedleRegex(): RegExp | null {\n const needles = getMinorAgeHintStrings()\n if (cachedMinorNeedleRe && cachedMinorNeedleCount === needles.length) return cachedMinorNeedleRe\n cachedMinorNeedleCount = needles.length\n const src = buildNeedleAlternationSource(needles)\n cachedMinorNeedleRe = src === null ? null : new RegExp(src, \"i\")\n return cachedMinorNeedleRe\n}\n\n/**\n * NUMBER-FIRST age shapes: the ones `buildAgeFragment` (person.ts) emits for a\n * CUSTOM age (\"N years old\", \"N year old\", \"N-year-old\") and the catalog's own\n * \"2-3 years old\" range (the FIRST number decides), plus the colloquial tails a\n * human or an LLM writes instead — \"12yo\", \"12 yo\", \"12 y.o.\", \"12 y/o\",\n * \"12 yr old\", \"12-yr-old\", \"12yrs old\", \"12 years of age\". The cut is `< 20`,\n * the same boundary `isMinorAge` uses for `customAge` and the same one\n * `buildAgeFragment` switches to \"in their teens\" at.\n *\n * Both boundaries are load-bearing. The LEADING one stops a match inside a\n * larger token; the TRAILING one is what makes \"a 5 year older sibling\" a\n * non-hit (\"old\" may not glue onto \"older\") and what stops \"yo\" from firing\n * inside \"12 young\" or \"12 yoga\". Used via `matchAll`, which clones the regex\n * rather than advancing this instance's `lastIndex`.\n */\nconst NUMERIC_AGE_RE =\n /(?<![\\w-])(\\d{1,3})(?:\\s*-\\s*\\d{1,3})?\\s*-?\\s*(?:years?\\s*-?\\s*old|yrs?\\s*-?\\s*old|y(?:\\.\\s*o\\.?|\\/o|o)|years?\\s+of\\s+age)(?![\\w-])/gi\n\n/**\n * AGE-FIRST shapes, where the number trails the word instead of leading it:\n * \"age 12\", \"aged 12\", \"at the age of 12\". The leading boundary is what keeps\n * \"image 12\" / \"page 12\" out (the `age` there is glued to a preceding word\n * character), and the trailing one keeps \"aged 12th\" out.\n */\nconst PREFIXED_AGE_RE = /(?<![\\w-])aged?\\s+(?:of\\s+)?(\\d{1,3})(?![\\w-])/gi\n\n/** Every rule that reads a NUMBER out of the text, each capturing the age in\n * group 1. Iterated together below so a new shape is one array entry. */\nconst AGE_NUMBER_RULES: ReadonlyArray<RegExp> = [NUMERIC_AGE_RE, PREFIXED_AGE_RE]\n\n/** The one NON-numeric shape `buildAgeFragment` emits below 20 (`${n} years\n * old, in their teens`). Kept as its own rule rather than as a catalog term.\n * Separator-tolerant on the same terms as the needle alternation, so\n * \"in their teens\" and \"in-their-teens\" are the same phrase. */\nconst IN_THEIR_TEENS_RE = /(?<![\\w-])in[\\s-]+their[\\s-]+teens(?![\\w-])/i\n\n/**\n * True when free text describes a MINOR subject. Three rules, in order:\n * 1. any minor-age / minor-implying-type prompt hint, word-bounded;\n * 2. a numeric age below 20 in any shape `buildAgeFragment` emits;\n * 3. the literal \"in their teens\".\n *\n * Deliberately NOT a bare-word check: \"child\", \"teen\", \"kid\" alone must never\n * fire, or an adult prompt that merely MENTIONS a child (\"a mother holding her\n * child\") would be floored — the spec's \"adults are byte-identical\" is a hard\n * requirement, so every rule here is a full phrase or a bounded number.\n *\n * Pairs with `isMinorAge`, never replaces it: the structured picker value is\n * the primary signal; this catches the same subject when only the assembled\n * text survives.\n */\nexport function containsMinorAgeHint(text: string | null | undefined): boolean {\n if (typeof text !== \"string\" || text.trim().length === 0) return false\n const re = minorNeedleRegex()\n if (re && re.test(text)) return true\n for (const rule of AGE_NUMBER_RULES) {\n for (const m of text.matchAll(rule)) {\n const n = Number(m[1])\n if (Number.isFinite(n) && n < 20) return true\n }\n }\n return IN_THEIR_TEENS_RE.test(text)\n}\n\n/** The analyzer/import value keys the floor strips flagged ids out of:\n * `person` plus EVERY catalog the flag sweep reads. DERIVED, never\n * hand-listed — the hand-written version omitted `photo-genre` while the\n * sweep included it, so a minor kept `glamour-portrait`. The analyzer JSON is\n * keyed by picker type id (`describe-to-picker.ts`), which is the same string\n * as the catalog id, so this list IS the set of keys to visit. */\nexport const FLOORED_PICKER_KEYS = [\"person\", ...ADULT_SWEPT_CATALOG_IDS] as const\n\nfunction stripIds(obj: Record<string, unknown>, drop: ReadonlySet<string>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(obj)) {\n if (typeof v === \"string\") {\n if (!drop.has(v)) out[k] = v\n } else if (Array.isArray(v)) {\n const kept = v.filter((x) => !(typeof x === \"string\" && drop.has(x)))\n if (kept.length > 0) out[k] = kept\n } else {\n out[k] = v\n }\n }\n return out\n}\n\n/** Analyzer / import post-filter: when the person value describes a minor,\n * remove every flagged id from the person, styling, pose and mood values.\n * Identity (same reference) for an adult. */\nexport function applyMinorAgeFloorToPickerValues<T extends Record<string, unknown>>(values: T): T {\n const person = values.person\n if (!person || typeof person !== \"object\" || !isMinorAge(person as { age?: string; customAge?: number; type?: string })) return values\n const drop = getAdultOnlyIds()\n const out: Record<string, unknown> = { ...values }\n for (const key of FLOORED_PICKER_KEYS) {\n const v = out[key]\n if (v && typeof v === \"object\" && !Array.isArray(v)) out[key] = stripIds(v as Record<string, unknown>, drop)\n }\n return out as T\n}\n","import type { HintNodeLike, HintEdgeLike, HintGraphContext } from \"@nodaro/shared/types\"\nexport type { HintNodeLike, HintEdgeLike, HintGraphContext }\n/**\n * Single source of truth for parameter-node prompt-hint text.\n *\n * Every parameter node (framing, lens, camera-format, lighting, color-look,\n * atmosphere, style, setting, person, mood, pose, styling, temporal, tone,\n * text-prompt, camera-motion) dispatches through `getParameterPromptHint` to\n * produce the descriptive clause it contributes to a consumer's prompt.\n *\n * The frontend DAG executor and backend workflow orchestrator both call this,\n * so the text injected via the `cinematography` handle is identical to the\n * text injected when the node is wired directly into a Text Prompt / LLM Chat\n * / Combine Text input.\n *\n * Camera-motion is graph-aware: when `ctx` is provided the function walks the\n * node's `startState`/`endState` incoming edges and composes a fully formed\n * sentence via `composeCameraMotionHintFromConnections`. Without `ctx` only\n * the bare motion description is returned.\n */\n\nimport { buildFramingHints } from \"./framing.js\"\nimport { buildLightingHints } from \"./lighting.js\"\nimport { getLensPromptHint, getLensTerm } from \"./lens.js\"\nimport { getCameraFormatPromptHint, getCameraFormatTerm } from \"./camera-format.js\"\nimport { getColorLookPromptHint, getColorLookTerm } from \"./color-look.js\"\nimport { buildAtmosphereHints } from \"./atmosphere.js\"\nimport { buildActionFxHints } from \"./action-fx.js\"\nimport { getStylePromptHint, getStyleTerm, getStyleVideoPromptHint } from \"./style.js\"\nimport { getSettingPromptHint, getSettingTerm } from \"./setting.js\"\nimport { getLoopSubjectPromptHint, getLoopSubjectTerm } from \"./loop-subject.js\"\nimport { buildPersonHints } from \"./person.js\"\nimport { buildMoodHints } from \"./mood.js\"\nimport { buildPoseHints } from \"./pose.js\"\nimport { buildStylingHints } from \"./styling.js\"\nimport { buildTemporalHints } from \"./temporal.js\"\nimport { composeCameraMotionHintFromConnections } from \"./camera-motions.js\"\nimport { joinHintFragments } from \"./hint-join.js\"\nimport { composeTransitionHintFromConnections, readTransitionOptionValues, type TransitionDuration, type TransitionIntensity, type TransitionPosition, type TransitionTiming } from \"./transitions.js\"\nimport { composeCharacterFxHintFromConnections, type CharacterFxDuration, type CharacterFxIntensity, type CharacterFxPosition, type CharacterFxTiming } from \"./character-fx.js\"\nimport { composeCharacterMotionHintFromConnections, type CharacterMotionPace, type CharacterMotionPosition, type CharacterMotionTiming } from \"./character-motion.js\"\nimport { containsMinorAgeHint, isMinorAge } from \"./age-floor.js\"\nimport { buildMaterialHints } from \"./materials.js\"\nimport { curatedAnimalPromptHint, curatedAnimalTerm, curatedVehicleText, curatedWeaponText, curatedFurnitureText } from \"./shared-catalog-overlay.js\"\nimport { getPhotoGenrePromptHint, getPhotoGenreTerm } from \"./photo-genre.js\"\nimport { getBackdropPromptHint, getBackdropTerm } from \"./backdrop.js\"\nimport { buildHeldPropHints } from \"./held-prop.js\"\nimport { buildPhotographerHints } from \"./photographer.js\"\nimport { buildAestheticHints } from \"./aesthetic.js\"\nimport { getEraPromptHint, getEraTerm } from \"./era.js\"\nimport { buildExposureHints } from \"./exposure-settings.js\"\nimport { getRenderQualityPromptHint, getRenderQualityTerm } from \"./render-quality.js\"\nimport { getCompositionEffectPromptHint, getCompositionEffectTerm } from \"./composition-effects.js\"\nimport { buildPostProcessHints } from \"./post-process-effects.js\"\nimport { buildMusicGenreHints } from \"./music-genre.js\"\nimport { buildMusicMoodHints } from \"./music-mood.js\"\nimport { buildInstrumentationHints } from \"./instrumentation.js\"\nimport { buildVoiceCharacterHints } from \"./voice-character.js\"\nimport { buildVoiceDeliveryHints } from \"./voice-delivery.js\"\nimport { getPickerCatalog } from \"./picker-catalogs.js\"\nimport { resolveTerm, type PickerHintMode } from \"./term.js\"\n\n\nfunction asStr(v: unknown): string {\n return typeof v === \"string\" ? v : \"\"\n}\n\n/** Extract the display name from a character / face / object / location ref node. */\nfunction extractCharacterRefName(node: HintNodeLike): string | undefined {\n const d = (node.data ?? {}) as Record<string, unknown>\n const candidates = [d.characterName, d.faceName, d.objectName, d.locationName]\n for (const v of candidates) {\n if (typeof v === \"string\" && v.trim().length > 0) return v.trim()\n }\n return undefined\n}\n\n/** Character Motion's name read: the shared character / face / object / location\n * read, then a creature's `creatureName`. Local to Character Motion so the\n * Character FX prompt, which shares `extractCharacterRefName`, stays unchanged. */\nfunction extractCharacterMotionRefName(node: HintNodeLike): string | undefined {\n const name = extractCharacterRefName(node)\n if (name) return name\n const creatureName = asStr(((node.data ?? {}) as Record<string, unknown>).creatureName).trim()\n return creatureName.length > 0 ? creatureName : undefined\n}\n\n/** Free-text fields a character / face / object / location ref node describes its subject in.\n * A creature ref uses the same `description` / `canonicalDescription` names. */\nconst REF_DESCRIPTION_FIELDS = [\"description\", \"seedPrompt\", \"canonicalDescription\"] as const\n\n/** True when a character / face / object / location ref node describes a minor:\n * its structured `person` age (the primary signal) or an age phrase in its\n * free-text description. Feeds the Character Motion floor (adult-only moves\n * dropped) — errs toward flooring, never toward letting an adult-only move through. */\nfunction extractCharacterRefMinor(node: HintNodeLike): boolean {\n const d = (node.data ?? {}) as Record<string, unknown>\n const person = d.person\n if (person && typeof person === \"object\" && !Array.isArray(person) && isMinorAge(person as Parameters<typeof isMinorAge>[0])) {\n return true\n }\n return REF_DESCRIPTION_FIELDS.some((field) => containsMinorAgeHint(asStr(d[field])))\n}\n\n/** The preview, diagnostics and execution use identical graph bindings. */\nexport function getCharacterMotionBindings(node: HintNodeLike, ctx?: HintGraphContext) {\n const targetNames: string[] = []\n const partnerNames: string[] = []\n const targetIds = new Set<string>()\n const partnerIds = new Set<string>()\n let subjectMinor = false\n for (const edge of ctx?.edges ?? []) {\n if (edge.target !== node.id || (edge.targetHandle !== \"target\" && edge.targetHandle !== \"partner\")) continue\n const src = ctx?.nodes.find(n => n.id === edge.source)\n if (!src) continue\n if (edge.targetHandle === \"target\") targetIds.add(src.id)\n else partnerIds.add(src.id)\n if (extractCharacterRefMinor(src)) subjectMinor = true\n const name = extractCharacterMotionRefName(src)\n if (!name) continue\n const names = edge.targetHandle === \"target\" ? targetNames : partnerNames\n if (!names.includes(name)) names.push(name)\n }\n return { targetNames, partnerNames, subjectMinor, selfPairing: [...targetIds].some(id => partnerIds.has(id)) }\n}\n\n/** Compose `[preText, mainHint, postText]` into a comma-joined string,\n * honoring the user's free-text fragments around the structured hint.\n * Helpers like `getStylePromptHint` that already include preText/postText\n * composition (build*Hints in mood/person/etc.) bypass this — they\n * return the fully-composed string directly. */\nfunction withCustomText(data: Record<string, unknown>, mainHint: string): string {\n const fragments: string[] = []\n const pre = typeof data.preText === \"string\" ? data.preText.trim() : \"\"\n if (pre) fragments.push(pre)\n if (mainHint) fragments.push(mainHint)\n const post = typeof data.postText === \"string\" ? data.postText.trim() : \"\"\n if (post) fragments.push(post)\n return joinHintFragments(fragments)\n}\n\n/**\n * The node-level hint mode a picker declares via `data.hintMode`.\n *\n * Only the two documented values count; anything else (a stale value, a typo,\n * a non-string) is treated as UNDECLARED and falls back — to the inherited\n * mode when the node is resolved as an upstream input, and to `\"full\"`\n * otherwise. Compact is opt-in, so an unrecognized value can never silently\n * shorten a prompt.\n */\nfunction readHintMode(data: Record<string, unknown>): PickerHintMode | undefined {\n const raw = data.hintMode\n return raw === \"compact\" || raw === \"full\" ? raw : undefined\n}\n\n/** Pick the full-hint or the compact-term getter for the active mode. */\nfunction byMode<T>(mode: PickerHintMode, full: T, compact: T): T {\n return mode === \"compact\" ? compact : full\n}\n\n/** How much a shot moves (the Motion node's three steps), as the clause it\n * adds to a video prompt; the compact form is the bare term. */\nconst MOTION_INTENSITY_HINTS: Readonly<Record<string, { readonly full: string; readonly compact: string }>> = {\n subtle: { full: \"subtle, gentle motion with slow, minimal movement\", compact: \"subtle motion\" },\n moderate: { full: \"moderate, natural motion at an even pace\", compact: \"moderate motion\" },\n dynamic: { full: \"dynamic, energetic motion with fast, pronounced movement\", compact: \"dynamic motion\" },\n}\n\n/**\n * Dispatch by parameter-node type to its prompt-hint string. For camera-motion,\n * pass `ctx` to include the composed start/end clauses; otherwise only the\n * bare motion description is returned.\n *\n * VERBOSITY — a picker node may set `data.hintMode` to `\"compact\"` to inject\n * its short professional `term` (\"whip pan left\", \"hard cut\") instead of the\n * long `promptHint`. Absent, or any unrecognized value, means `\"full\"`, whose\n * output is byte-identical to what this function returned before hint modes\n * existed. ONLY the base catalog fragment swaps: `preText`/`postText`, the\n * transition / camera-motion / character-fx timing and start-state/end-state\n * clauses, multi-pick joining and multi-dimension composition are emitted the\n * same way in both modes.\n *\n * SURFACE — `opts.surface: \"video\"` is for a caller folding the hint into ONE\n * video consumer's prompt (the canvas's video nodes): a Style node then injects\n * its video wording (`getStyleVideoPromptHint`). Absent (or `\"image\"`) is the\n * output this function always returned — what a still, a `{Label}` reference\n * and every preview of the node's own text read, since a node's own output\n * text has no single consumer. Every other node type ignores it.\n */\nexport function getParameterPromptHint(\n node: HintNodeLike | undefined,\n ctx?: HintGraphContext,\n opts?: ParameterHintOptions,\n): string {\n return resolveParameterHint(node, ctx, undefined, opts?.surface === \"video\" ? \"video\" : \"image\")\n}\n\n/** How `getParameterPromptHint` resolves a node. */\nexport interface ParameterHintOptions {\n /** The stage the hint is folded into. Absent = `\"image\"`. */\n readonly surface?: \"image\" | \"video\"\n}\n\n/**\n * The dispatch body. `inherited` carries the mode DOWN into the nodes wired to\n * a composer's `startState` / `endState` handles, so a compact transition\n * composes compact start/end clauses rather than mixing a term with two\n * paragraphs. A node that declares its own `hintMode` still wins over what it\n * inherits.\n */\nfunction resolveParameterHint(\n node: HintNodeLike | undefined,\n ctx?: HintGraphContext,\n inherited?: PickerHintMode,\n surface: \"image\" | \"video\" = \"image\",\n): string {\n if (!node?.type) return \"\"\n const data = (node.data ?? {}) as Record<string, unknown>\n const mode: PickerHintMode = readHintMode(data) ?? inherited ?? \"full\"\n\n if (node.type === \"camera-motion\") {\n const motionId = asStr(data.cameraMotion) || undefined\n if (!ctx) return withCustomText(data, composeCameraMotionHintFromConnections(motionId, [], [], mode))\n const startHints: string[] = []\n const endHints: string[] = []\n for (const edge of ctx.edges) {\n if (edge.target !== node.id) continue\n const src = ctx.nodes.find((n) => n.id === edge.source)\n if (!src) continue\n // Pass no ctx for nested resolution: startState/endState inputs are\n // themselves parameter nodes (framing/tone/etc.) that don't need graph\n // context, and avoiding recursion keeps the walk cycle-safe. The mode\n // rides down so the composed clause stays at one level of detail.\n const hint = resolveParameterHint(src, undefined, mode, surface)\n if (!hint) continue\n if (edge.targetHandle === \"startState\") startHints.push(hint)\n else if (edge.targetHandle === \"endState\") endHints.push(hint)\n }\n return withCustomText(data, composeCameraMotionHintFromConnections(motionId, startHints, endHints, mode))\n }\n\n if (node.type === \"transition\") {\n const raw = data.transition\n const transitionId: string | string[] | undefined =\n Array.isArray(raw)\n ? raw.filter((s): s is string => typeof s === \"string\" && s.length > 0)\n : (asStr(raw) || undefined)\n const timing: TransitionTiming = {\n position: asStr(data.position) as TransitionPosition | undefined,\n duration: asStr(data.duration) as TransitionDuration | undefined,\n intensity: asStr(data.intensity) as TransitionIntensity | undefined,\n }\n // A picked row's own options (a wipe's `wipeDirection`), off the same node data.\n const optionValues = readTransitionOptionValues(data)\n const hintOptions = optionValues ? { optionValues } : undefined\n if (!ctx) {\n return withCustomText(data, composeTransitionHintFromConnections(transitionId, [], [], timing, mode, hintOptions))\n }\n const startHints: string[] = []\n const endHints: string[] = []\n for (const edge of ctx.edges) {\n if (edge.target !== node.id) continue\n const src = ctx.nodes.find((n) => n.id === edge.source)\n if (!src) continue\n const hint = resolveParameterHint(src, undefined, mode, surface) // no ctx — cycle-safe\n if (!hint) continue\n if (edge.targetHandle === \"startState\") startHints.push(hint)\n else if (edge.targetHandle === \"endState\") endHints.push(hint)\n }\n return withCustomText(data, composeTransitionHintFromConnections(transitionId, startHints, endHints, timing, mode, hintOptions))\n }\n\n if (node.type === \"character-fx\") {\n const raw = data.characterFx\n const effectId: string | string[] | undefined =\n Array.isArray(raw)\n ? raw.filter((s): s is string => typeof s === \"string\" && s.length > 0)\n : (asStr(raw) || undefined)\n const timing: CharacterFxTiming = {\n position: asStr(data.position) as CharacterFxPosition | undefined,\n duration: asStr(data.duration) as CharacterFxDuration | undefined,\n intensity: asStr(data.intensity) as CharacterFxIntensity | undefined,\n }\n if (!ctx) {\n return withCustomText(data, composeCharacterFxHintFromConnections(effectId, [], timing, mode))\n }\n const targetNames: string[] = []\n for (const edge of ctx.edges) {\n if (edge.target !== node.id) continue\n if (edge.targetHandle !== \"target\") continue\n const src = ctx.nodes.find((n) => n.id === edge.source)\n if (!src) continue\n const name = extractCharacterRefName(src)\n if (name) targetNames.push(name)\n }\n return withCustomText(data, composeCharacterFxHintFromConnections(effectId, targetNames, timing, mode))\n }\n\n if (node.type === \"character-motion\") {\n const raw = data.characterMotion\n const motionId: string | string[] | undefined =\n Array.isArray(raw)\n ? raw.filter((s): s is string => typeof s === \"string\" && s.length > 0)\n : (asStr(raw) || undefined)\n const timing: CharacterMotionTiming = {\n position: asStr(data.position) as CharacterMotionPosition | undefined,\n pace: asStr(data.pace) as CharacterMotionPace | undefined,\n }\n if (!ctx) {\n return withCustomText(data, composeCharacterMotionHintFromConnections(motionId, [], [], timing, mode))\n }\n const { targetNames, partnerNames, subjectMinor } = getCharacterMotionBindings(node, ctx)\n return withCustomText(\n data,\n composeCharacterMotionHintFromConnections(motionId, targetNames, partnerNames, timing, mode, { subjectMinor }),\n )\n }\n\n const base = resolveBaseHint(node.type, data, mode, surface)\n if (base) return base\n // Pack-extend fallback: a single-dim pack entry the per-catalog getter (which\n // reads the frozen base array) can't resolve. Resolve it against the\n // registered (pack-composed) catalog's options. Composition already resolved\n // `PickerOption.term`; `resolveTerm` is idempotent over a resolved option and\n // is called anyway so a pack option that reached this array by some other\n // route still injects SOMETHING in compact mode rather than `undefined`.\n const cat = getPickerCatalog(node.type)\n if (cat?.kind === \"single\" && cat.valueField) {\n const id = typeof data[cat.valueField] === \"string\" ? (data[cat.valueField] as string) : \"\"\n const opt = cat.options?.find((o) => o.id === id)\n if (opt) return byMode(mode, surface === \"video\" ? (opt.videoPromptHint ?? opt.promptHint) : opt.promptHint, resolveTerm(opt))\n }\n return base\n}\n\n/**\n * Base (upstream) hint dispatch by node type — the per-catalog getters read the\n * frozen base arrays. Pack-added single-dim ids are resolved by the caller\n * against the registered (pack-composed) catalog.\n *\n * `mode` selects the base fragment only: the compact `get<Name>Term` getter /\n * `build<Name>Terms` builder instead of the verbose one. The `withCustomText`\n * wrapper, the builders' own pre/post composition, and the free-text node\n * types (tone / style-guide / text-prompt — user prose, not catalog copy) are\n * identical in both modes.\n */\nfunction resolveBaseHint(\n type: string,\n data: Record<string, unknown>,\n mode: PickerHintMode = \"full\",\n surface: \"image\" | \"video\" = \"image\",\n): string {\n switch (type) {\n case \"framing\":\n return withCustomText(data, buildFramingHints(data, false, mode).join(\", \"))\n case \"lighting\":\n return withCustomText(data, buildLightingHints(data, mode).join(\", \"))\n case \"lens\":\n return withCustomText(data, byMode(mode, getLensPromptHint, getLensTerm)(asStr(data.lens)))\n case \"camera-format\":\n return withCustomText(data, byMode(mode, getCameraFormatPromptHint, getCameraFormatTerm)(asStr(data.cameraFormat)))\n case \"color-look\":\n return withCustomText(data, byMode(mode, getColorLookPromptHint, getColorLookTerm)(asStr(data.colorLook)))\n\n // build*Hints in music-* / voice-* / mood / person / etc. compose\n // preText/postText internally — bypass the wrapper to avoid double-\n // composition.\n case \"music-genre\":\n return buildMusicGenreHints((data ?? {}) as Parameters<typeof buildMusicGenreHints>[0], mode)\n case \"music-mood\":\n return buildMusicMoodHints((data ?? {}) as Parameters<typeof buildMusicMoodHints>[0], mode)\n case \"instrumentation\":\n return buildInstrumentationHints((data ?? {}) as Parameters<typeof buildInstrumentationHints>[0], mode)\n case \"voice-character\":\n return buildVoiceCharacterHints((data ?? {}) as Parameters<typeof buildVoiceCharacterHints>[0], mode)\n case \"voice-delivery\":\n return buildVoiceDeliveryHints((data ?? {}) as Parameters<typeof buildVoiceDeliveryHints>[0], mode)\n case \"person\":\n return buildPersonHints(data, mode).join(\", \")\n case \"mood\":\n return buildMoodHints(data, mode).join(\", \")\n case \"pose\":\n return buildPoseHints(data, mode).join(\", \")\n case \"styling\":\n return buildStylingHints(data, mode).join(\", \")\n\n case \"atmosphere\":\n return withCustomText(data, buildAtmosphereHints(data.atmosphere, mode).join(\", \"))\n case \"action-fx\":\n return withCustomText(data, buildActionFxHints(data.actionFx, mode).join(\", \"))\n case \"style\":\n return withCustomText(data, byMode(mode, surface === \"video\" ? getStyleVideoPromptHint : getStylePromptHint, getStyleTerm)(asStr(data.style)))\n case \"setting\":\n return withCustomText(data, byMode(mode, getSettingPromptHint, getSettingTerm)(asStr(data.setting)))\n case \"loop-subject\":\n return withCustomText(data, byMode(mode, getLoopSubjectPromptHint, getLoopSubjectTerm)(asStr(data.loopSubject)))\n case \"material\":\n return withCustomText(data, buildMaterialHints(data.material, mode))\n // The four object-entity catalogs are owned by @nodaro/shared and overlaid\n // in shared-catalog-overlay.ts — the ONE module every prompt-text read of\n // them goes through (the subject fold uses it too). Each returns \"\" on a\n // miss, so the entry lookup is the module's job, not this switch's.\n case \"animal\":\n return withCustomText(data, byMode(mode, curatedAnimalPromptHint, curatedAnimalTerm)(asStr(data.animal)))\n case \"vehicle\": {\n const t = curatedVehicleText(asStr(data.vehicle))\n return withCustomText(data, byMode(mode, t.hint, t.term))\n }\n case \"weapon\": {\n const t = curatedWeaponText(asStr(data.weapon))\n return withCustomText(data, byMode(mode, t.hint, t.term))\n }\n case \"furniture\": {\n const t = curatedFurnitureText(asStr(data.furniture))\n return withCustomText(data, byMode(mode, t.hint, t.term))\n }\n case \"photo-genre\":\n return withCustomText(data, byMode(mode, getPhotoGenrePromptHint, getPhotoGenreTerm)(asStr(data.photoGenre)))\n case \"backdrop\":\n return withCustomText(data, byMode(mode, getBackdropPromptHint, getBackdropTerm)(asStr(data.backdrop)))\n case \"held-prop\":\n return withCustomText(data, buildHeldPropHints(data.heldProp, mode).join(\", \"))\n case \"photographer\":\n return withCustomText(data, buildPhotographerHints(data.photographer, mode))\n case \"aesthetic\":\n return withCustomText(data, buildAestheticHints(data.aesthetic, mode))\n case \"era\":\n return withCustomText(data, byMode(mode, getEraPromptHint, getEraTerm)(asStr(data.era)))\n case \"temporal\":\n return withCustomText(data, buildTemporalHints(data, mode).join(\", \"))\n case \"exposure-settings\":\n return withCustomText(data, buildExposureHints(data, mode).join(\", \"))\n case \"render-quality\":\n return withCustomText(data, byMode(mode, getRenderQualityPromptHint, getRenderQualityTerm)(asStr(data.renderQuality)))\n case \"composition-effects\":\n return withCustomText(data, byMode(mode, getCompositionEffectPromptHint, getCompositionEffectTerm)(asStr(data.compositionEffect)))\n case \"post-process-effects\":\n return withCustomText(data, buildPostProcessHints(data.postProcess, mode).join(\", \"))\n // Motion intensity: a Generation Settings node that a video node's\n // Settings input takes as a prompt fragment (video only).\n case \"motion\": {\n const hint = MOTION_INTENSITY_HINTS[asStr(data.motion)]\n return hint ? byMode(mode, hint.full, hint.compact) : \"\"\n }\n\n // Free text authored by the user, not catalog copy — there is no shorter\n // professional form to swap in, so these are identical in both modes.\n case \"tone\":\n return asStr(data.tone).trim()\n case \"style-guide\":\n // The node's whole purpose is injecting its style text into consumer\n // prompts; without this case, {Style Guide} refs stayed as literal\n // brace text and direct wires injected nothing (only fieldMappings\n // worked, via getParameterValue).\n return asStr(data.text).trim()\n case \"text-prompt\":\n return asStr(data.text).trim()\n default:\n return \"\"\n }\n}\n"]}
@@ -1,22 +1,22 @@
1
1
  'use strict';
2
2
 
3
- var chunkTYJCCODP_cjs = require('./chunk-TYJCCODP.cjs');
4
- var chunkHR4TFBU2_cjs = require('./chunk-HR4TFBU2.cjs');
3
+ var chunkPWYASBX2_cjs = require('./chunk-PWYASBX2.cjs');
4
+ var chunkKTNCB2IE_cjs = require('./chunk-KTNCB2IE.cjs');
5
5
 
6
6
  // src/read-node-direction.ts
7
7
  function readDirectionFields(value) {
8
8
  if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
9
9
  const src = value;
10
10
  const out = {};
11
- for (const spec of chunkHR4TFBU2_cjs.DIRECTION_FIELDS) {
11
+ for (const spec of chunkKTNCB2IE_cjs.DIRECTION_FIELDS) {
12
12
  const v = src[spec.key];
13
13
  if (typeof v === "string") {
14
- if (v.length > 0 && v.length <= chunkHR4TFBU2_cjs.DIRECTION_ID_MAX_CHARS) out[spec.key] = v;
14
+ if (v.length > 0 && v.length <= chunkKTNCB2IE_cjs.DIRECTION_ID_MAX_CHARS) out[spec.key] = v;
15
15
  } else if (Array.isArray(v)) {
16
16
  const kept = [];
17
17
  for (const x of v) {
18
- if (kept.length >= chunkHR4TFBU2_cjs.DIRECTION_ARRAY_CEILING) break;
19
- if (typeof x === "string" && x.length > 0 && x.length <= chunkHR4TFBU2_cjs.DIRECTION_ID_MAX_CHARS) {
18
+ if (kept.length >= chunkKTNCB2IE_cjs.DIRECTION_ARRAY_CEILING) break;
19
+ if (typeof x === "string" && x.length > 0 && x.length <= chunkKTNCB2IE_cjs.DIRECTION_ID_MAX_CHARS) {
20
20
  kept.push(x);
21
21
  }
22
22
  }
@@ -29,19 +29,19 @@ function readSubjectFields(value) {
29
29
  if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
30
30
  const src = value;
31
31
  const out = {};
32
- for (const key of chunkTYJCCODP_cjs.getRegisteredSubjectKeys()) {
32
+ for (const key of chunkPWYASBX2_cjs.getRegisteredSubjectKeys()) {
33
33
  const v = src[key];
34
- if (key === chunkTYJCCODP_cjs.SUBJECT_CUSTOM_AGE_KEY) {
34
+ if (key === chunkPWYASBX2_cjs.SUBJECT_CUSTOM_AGE_KEY) {
35
35
  if (typeof v === "number" && Number.isFinite(v)) out[key] = v;
36
36
  continue;
37
37
  }
38
38
  if (typeof v === "string") {
39
- if (v.length > 0 && v.length <= chunkTYJCCODP_cjs.SUBJECT_ID_MAX_CHARS) out[key] = v;
39
+ if (v.length > 0 && v.length <= chunkPWYASBX2_cjs.SUBJECT_ID_MAX_CHARS) out[key] = v;
40
40
  } else if (Array.isArray(v)) {
41
41
  const kept = [];
42
42
  for (const x of v) {
43
- if (kept.length >= chunkTYJCCODP_cjs.SUBJECT_ARRAY_CEILING) break;
44
- if (typeof x === "string" && x.length > 0 && x.length <= chunkTYJCCODP_cjs.SUBJECT_ID_MAX_CHARS) {
43
+ if (kept.length >= chunkPWYASBX2_cjs.SUBJECT_ARRAY_CEILING) break;
44
+ if (typeof x === "string" && x.length > 0 && x.length <= chunkPWYASBX2_cjs.SUBJECT_ID_MAX_CHARS) {
45
45
  kept.push(x);
46
46
  }
47
47
  }
@@ -118,5 +118,5 @@ function readStructuredFields(value) {
118
118
  exports.readDirectionFields = readDirectionFields;
119
119
  exports.readStructuredFields = readStructuredFields;
120
120
  exports.readSubjectFields = readSubjectFields;
121
- //# sourceMappingURL=chunk-KYKCHOOS.cjs.map
122
- //# sourceMappingURL=chunk-KYKCHOOS.cjs.map
121
+ //# sourceMappingURL=chunk-P4BXE4OA.cjs.map
122
+ //# sourceMappingURL=chunk-P4BXE4OA.cjs.map