@nodaro/shared 2.16.0 → 2.18.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.
package/dist/index.cjs CHANGED
@@ -2053,9 +2053,9 @@ var AUDIO_MODELS = {
2053
2053
  family: "ElevenLabs",
2054
2054
  label: "ElevenLabs Dubbing",
2055
2055
  series: "ElevenLabs",
2056
- description: "Translate + dub a video into a new language. Async.",
2056
+ description: "Translate + dub audio or a whole video into a new language \u2014 video in, dubbed video out. Async.",
2057
2057
  useCases: ["dubbing", "multilingual"],
2058
- pricing: [{ identifier: "elevenlabs-dubbing", credits: 80 }]
2058
+ pricing: [{ identifier: "elevenlabs-dubbing", credits: 40, note: "per minute of the dubbed span (min 1)" }]
2059
2059
  },
2060
2060
  "elevenlabs-forced-alignment": {
2061
2061
  id: "elevenlabs-forced-alignment",
@@ -2590,6 +2590,13 @@ var NATIVE_NEGATIVE_VIDEO_PROVIDERS = /* @__PURE__ */ new Set([
2590
2590
  // Wan speech-to-video
2591
2591
  "wan-s2v"
2592
2592
  ]);
2593
+ var STYLE_SECTION_HEADER_LINE = "[style]:\n";
2594
+ function videoNegativeSuffix(negativePrompt, base) {
2595
+ const gapAt = base?.lastIndexOf("\n\n") ?? -1;
2596
+ const lastBlock = base === void 0 ? void 0 : gapAt >= 0 ? base.slice(gapAt + 2) : base;
2597
+ const separator = lastBlock === void 0 || lastBlock.startsWith(STYLE_SECTION_HEADER_LINE) ? "\n\n" : "\n";
2598
+ return `${separator}Avoid: ${negativePrompt}`;
2599
+ }
2593
2600
  function applyVideoNegativePrompt(prompt, negativePrompt, provider) {
2594
2601
  const promptMax = getMaxVideoPromptChars(provider);
2595
2602
  const clamp = (p) => p != null && p.length > promptMax ? p.slice(0, promptMax) : p;
@@ -2600,8 +2607,7 @@ function applyVideoNegativePrompt(prompt, negativePrompt, provider) {
2600
2607
  }
2601
2608
  const base = prompt && prompt.trim().length > 0 ? prompt : "";
2602
2609
  if (!base) return { prompt: `Avoid: ${neg}`.slice(0, promptMax), nativeNegativePrompt: void 0 };
2603
- const avoid = `
2604
- Avoid: ${neg}`;
2610
+ const avoid = videoNegativeSuffix(neg, base);
2605
2611
  const room = Math.max(0, promptMax - avoid.length);
2606
2612
  const injected = `${base.slice(0, room)}${avoid}`.slice(0, promptMax);
2607
2613
  return { prompt: injected, nativeNegativePrompt: void 0 };
@@ -8857,6 +8863,18 @@ function getAnimalLabel(id, fallback) {
8857
8863
  if (fallback !== void 0) return fallback;
8858
8864
  return (id ?? "").replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
8859
8865
  }
8866
+ function getAnimalPromptHint(id) {
8867
+ const a = getAnimal(id);
8868
+ return a ? `featuring a ${a.label.toLowerCase()}, ${a.description}` : "";
8869
+ }
8870
+ var PARENTHETICAL = /\([^)]*\)/g;
8871
+ function deriveAnimalTerm(label) {
8872
+ return label.replace(PARENTHETICAL, " ").toLowerCase().replace(/\s+/g, " ").trim();
8873
+ }
8874
+ function getAnimalTerm(id) {
8875
+ const a = getAnimal(id);
8876
+ return a ? a.term ?? deriveAnimalTerm(a.label) : "";
8877
+ }
8860
8878
  ANIMALS.map((a) => a.id);
8861
8879
  var ANIMAL_SUBCATEGORY_LABELS = {
8862
8880
  cats: "Cats",
@@ -9916,12 +9934,12 @@ function findLocationMentionTokens(prompt, knownLocationSlugs) {
9916
9934
  return tokens;
9917
9935
  }
9918
9936
 
9919
- // src/image-mention-slug.ts
9920
- var IMAGE_SLUG_PATTERN = /^[a-z][a-z0-9-]*$/;
9921
- function imageMentionSlug(name) {
9937
+ // src/mention-token-grammar.ts
9938
+ var MENTION_SLUG_PATTERN = /^[a-z][a-z0-9-]*$/;
9939
+ function mentionNameSlug(name) {
9922
9940
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
9923
9941
  }
9924
- function parseImageMentionToken(text) {
9942
+ function parseMentionToken(text) {
9925
9943
  if (!text.startsWith("@")) return null;
9926
9944
  let rest = text.slice(1);
9927
9945
  if (rest.length === 0 || !/^[a-z]/.test(rest)) return null;
@@ -9935,36 +9953,62 @@ function parseImageMentionToken(text) {
9935
9953
  }
9936
9954
  const parts = rest.split(":");
9937
9955
  if (parts.length < 2 || parts.length > 3) return null;
9938
- const [imageSlug, indexStr, third] = parts;
9939
- if (!IMAGE_SLUG_PATTERN.test(imageSlug)) return null;
9956
+ const [slug, indexStr, third] = parts;
9957
+ if (!MENTION_SLUG_PATTERN.test(slug)) return null;
9940
9958
  if (!/^\d+$/.test(indexStr)) return null;
9941
- const imageIndex = parseInt(indexStr, 10);
9942
- if (!Number.isInteger(imageIndex) || imageIndex < 1) return null;
9943
- if (parts.length === 2) return { imageSlug, imageIndex, ...lockField };
9944
- if (!IMAGE_SLUG_PATTERN.test(third)) return null;
9945
- return { imageSlug, imageIndex, role: third, ...lockField };
9946
- }
9947
- function findImageMentionTokens(prompt, knownImageSlugs) {
9959
+ const index = parseInt(indexStr, 10);
9960
+ if (!Number.isInteger(index) || index < 1) return null;
9961
+ if (parts.length === 2) return { slug, index, ...lockField };
9962
+ if (!MENTION_SLUG_PATTERN.test(third)) return null;
9963
+ return { slug, index, role: third, ...lockField };
9964
+ }
9965
+ var MENTION_TOKEN_REGEX = /(?:^|[^a-zA-Z0-9])(@[a-z][a-z0-9-]*:\d+(?::[a-z][a-z0-9-]*)?(?:~(?:no)?lock(?![a-z0-9-]))?)(?![:a-z0-9-])/g;
9966
+ function findMentionTokens(prompt, knownSlugs) {
9948
9967
  const tokens = [];
9949
- const regex = /(?:^|[^a-zA-Z0-9])(@[a-z][a-z0-9-]*:\d+(?::[a-z][a-z0-9-]*)?(?:~(?:no)?lock(?![a-z0-9-]))?)(?![:a-z0-9-])/g;
9950
- const knownSet = new Set(knownImageSlugs);
9968
+ const regex = new RegExp(MENTION_TOKEN_REGEX.source, "g");
9969
+ const knownSet = new Set(knownSlugs);
9951
9970
  for (const match of prompt.matchAll(regex)) {
9952
9971
  const token = match[1];
9953
9972
  const offset = (match.index ?? 0) + (match[0].length - token.length);
9954
9973
  if (/^\/[a-z]/.test(prompt.slice(offset + token.length))) continue;
9955
- const parsed = parseImageMentionToken(token);
9956
- if (parsed && knownSet.has(parsed.imageSlug)) {
9974
+ const parsed = parseMentionToken(token);
9975
+ if (parsed && knownSet.has(parsed.slug)) {
9957
9976
  tokens.push({ token, ...parsed, offset });
9958
9977
  }
9959
9978
  }
9960
9979
  return tokens;
9961
9980
  }
9981
+
9982
+ // src/image-mention-slug.ts
9983
+ function imageMentionSlug(name) {
9984
+ return mentionNameSlug(name);
9985
+ }
9986
+ function parseImageMentionToken(text) {
9987
+ const parsed = parseMentionToken(text);
9988
+ if (!parsed) return null;
9989
+ return {
9990
+ imageSlug: parsed.slug,
9991
+ imageIndex: parsed.index,
9992
+ ...parsed.role !== void 0 ? { role: parsed.role } : {},
9993
+ ...parsed.lock !== void 0 ? { lock: parsed.lock } : {}
9994
+ };
9995
+ }
9996
+ function findImageMentionTokens(prompt, knownImageSlugs) {
9997
+ return findMentionTokens(prompt, knownImageSlugs).map((t2) => ({
9998
+ token: t2.token,
9999
+ imageSlug: t2.slug,
10000
+ imageIndex: t2.index,
10001
+ ...t2.role !== void 0 ? { role: t2.role } : {},
10002
+ ...t2.lock !== void 0 ? { lock: t2.lock } : {},
10003
+ offset: t2.offset
10004
+ }));
10005
+ }
9962
10006
  function imageMentionSlugForRef(r) {
9963
10007
  if (r.source !== "wired-image" && r.source !== "manual") return null;
9964
10008
  if (r.isExtraRef === true) return null;
9965
10009
  if (!r.url || !r.defaultName) return null;
9966
10010
  const slug = imageMentionSlug(r.defaultName);
9967
- return IMAGE_SLUG_PATTERN.test(slug) ? slug : null;
10011
+ return MENTION_SLUG_PATTERN.test(slug) ? slug : null;
9968
10012
  }
9969
10013
  function knownImageSlugsFromRefs(refs) {
9970
10014
  const out = /* @__PURE__ */ new Set();
@@ -9975,6 +10019,46 @@ function knownImageSlugsFromRefs(refs) {
9975
10019
  return [...out];
9976
10020
  }
9977
10021
 
10022
+ // src/entity-mention-slug.ts
10023
+ function entityMentionSlug(name) {
10024
+ return mentionNameSlug(name);
10025
+ }
10026
+ function parseEntityMentionToken(text) {
10027
+ const parsed = parseMentionToken(text);
10028
+ if (!parsed) return null;
10029
+ return {
10030
+ entitySlug: parsed.slug,
10031
+ entityIndex: parsed.index,
10032
+ ...parsed.role !== void 0 ? { role: parsed.role } : {},
10033
+ ...parsed.lock !== void 0 ? { lock: parsed.lock } : {}
10034
+ };
10035
+ }
10036
+ function findEntityMentionTokens(prompt, knownEntitySlugs) {
10037
+ return findMentionTokens(prompt, knownEntitySlugs).map((t2) => ({
10038
+ token: t2.token,
10039
+ entitySlug: t2.slug,
10040
+ entityIndex: t2.index,
10041
+ ...t2.role !== void 0 ? { role: t2.role } : {},
10042
+ ...t2.lock !== void 0 ? { lock: t2.lock } : {},
10043
+ offset: t2.offset
10044
+ }));
10045
+ }
10046
+ function entityMentionSlugForRef(r) {
10047
+ if (r.source !== "wired-creature" && r.source !== "wired-object") return null;
10048
+ if (r.isExtraRef === true) return null;
10049
+ if (!r.url || !r.defaultName) return null;
10050
+ const slug = entityMentionSlug(r.defaultName);
10051
+ return MENTION_SLUG_PATTERN.test(slug) ? slug : null;
10052
+ }
10053
+ function knownEntitySlugsFromRefs(refs) {
10054
+ const out = /* @__PURE__ */ new Set();
10055
+ for (const r of refs) {
10056
+ const slug = entityMentionSlugForRef(r);
10057
+ if (slug) out.add(slug);
10058
+ }
10059
+ return [...out];
10060
+ }
10061
+
9978
10062
  // src/to-connected-references.ts
9979
10063
  function toConnectedReference(entity) {
9980
10064
  if (entity.kind === "character") {
@@ -12132,6 +12216,12 @@ var DYNAMIC_PRODUCER_TYPES = /* @__PURE__ */ new Set([
12132
12216
  // EVERY producer set or its outputs can't connect (was the "cannot connect
12133
12217
  // the outputs of voice-changer-pro" bug). Guarded by producer-types.test.ts.
12134
12218
  "voice-changer-pro",
12219
+ // Dubbing joined the dual-mode family with the full-surface upgrade:
12220
+ // audio in → dubbed audio; video in (or a video sourceUrl) → dubbed VIDEO
12221
+ // (+ audio sidecar). Same wiring contract as voice-changer; stays in
12222
+ // AUDIO_PRODUCER_TYPES as its default. Explicitly asserted in
12223
+ // producer-types.test.ts (the suite does not fail on omission).
12224
+ "dubbing",
12135
12225
  "reduce",
12136
12226
  // Dual-output time chunker (UI label "Split into Chunks"; type id stays
12137
12227
  // "split-media"): video in → video chunks, audio in → audio chunks — two
@@ -14278,6 +14368,8 @@ exports.effectiveReasoningEffort = effectiveReasoningEffort;
14278
14368
  exports.encodeProviderItem = encodeProviderItem;
14279
14369
  exports.ensureLocaleCatalogLoaded = ensureLocaleCatalogLoaded;
14280
14370
  exports.entityHydrationColumns = entityHydrationColumns;
14371
+ exports.entityMentionSlug = entityMentionSlug;
14372
+ exports.entityMentionSlugForRef = entityMentionSlugForRef;
14281
14373
  exports.entityScalarFields = entityScalarFields;
14282
14374
  exports.entitySlotSchema = entitySlotSchema;
14283
14375
  exports.entryMatchesQuery = entryMatchesQuery;
@@ -14303,6 +14395,7 @@ exports.extractVideoDurationFromNode = extractVideoDurationFromNode;
14303
14395
  exports.fieldKeyFromHandle = fieldKeyFromHandle;
14304
14396
  exports.filterCloneNodes = filterCloneNodes;
14305
14397
  exports.findCharacterMentionTokens = findCharacterMentionTokens;
14398
+ exports.findEntityMentionTokens = findEntityMentionTokens;
14306
14399
  exports.findImageMentionTokens = findImageMentionTokens;
14307
14400
  exports.findLocationMentionTokens = findLocationMentionTokens;
14308
14401
  exports.findSeedance2AudioOverLimit = findSeedance2AudioOverLimit;
@@ -14310,6 +14403,8 @@ exports.firstSightExtraRole = firstSightExtraRole;
14310
14403
  exports.flattenItems = flattenItems;
14311
14404
  exports.getAnimal = getAnimal;
14312
14405
  exports.getAnimalLabel = getAnimalLabel;
14406
+ exports.getAnimalPromptHint = getAnimalPromptHint;
14407
+ exports.getAnimalTerm = getAnimalTerm;
14313
14408
  exports.getAspectRatioOptions = getAspectRatioOptions;
14314
14409
  exports.getAudioCrossfadeCurve = getAudioCrossfadeCurve;
14315
14410
  exports.getCharacterFacet = getCharacterFacet;
@@ -14385,6 +14480,7 @@ exports.isVeoProvider = isVeoProvider;
14385
14480
  exports.isVideoAnalysisMixedTier = isVideoAnalysisMixedTier;
14386
14481
  exports.isVideoAnalysisTier = isVideoAnalysisTier;
14387
14482
  exports.jsonResultToList = jsonResultToList;
14483
+ exports.knownEntitySlugsFromRefs = knownEntitySlugsFromRefs;
14388
14484
  exports.knownImageSlugsFromRefs = knownImageSlugsFromRefs;
14389
14485
  exports.listBoardTemplates = listBoardTemplates;
14390
14486
  exports.listModels = listModels;
@@ -14418,6 +14514,7 @@ exports.normalizeRoleSlug = normalizeRoleSlug;
14418
14514
  exports.orderedLlmModels = orderedLlmModels;
14419
14515
  exports.parseAttributedDialogue = parseAttributedDialogue;
14420
14516
  exports.parseCharacterMentionToken = parseCharacterMentionToken;
14517
+ exports.parseEntityMentionToken = parseEntityMentionToken;
14421
14518
  exports.parseGroupHandle = parseGroupHandle;
14422
14519
  exports.parseHandleId = parseHandleId;
14423
14520
  exports.parseImageMentionToken = parseImageMentionToken;
@@ -14542,6 +14639,7 @@ exports.videoAnalysisResultSchema = videoAnalysisResultSchema;
14542
14639
  exports.videoAuditCreditsForBucket = videoAuditCreditsForBucket;
14543
14640
  exports.videoModelCanSpeakDialogue = videoModelCanSpeakDialogue;
14544
14641
  exports.videoModelSupportsAudio = videoModelSupportsAudio;
14642
+ exports.videoNegativeSuffix = videoNegativeSuffix;
14545
14643
  exports.videoProviderRequiresImage = videoProviderRequiresImage;
14546
14644
  exports.windowAnalysisSchema = windowAnalysisSchema;
14547
14645
  exports.zipMergeLists = zipMergeLists;