@nodaro/shared 1.4.2
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/LICENSE +202 -0
- package/README.md +32 -0
- package/dist/index.cjs +12506 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +12269 -0
- package/dist/index.d.ts +12269 -0
- package/dist/index.js +11831 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
- package/src/__tests__/__snapshots__/prompt-builder-segments.test.ts.snap +65 -0
- package/src/__tests__/ai-avatar-pricing.test.ts +321 -0
- package/src/__tests__/apply-video-negative-prompt.test.ts +76 -0
- package/src/__tests__/attach-columns.test.ts +28 -0
- package/src/__tests__/audio-crossfade-curves.test.ts +33 -0
- package/src/__tests__/build-model-menu.test.ts +58 -0
- package/src/__tests__/character-aspect-defaults.test.ts +142 -0
- package/src/__tests__/character-mention-slug.test.ts +199 -0
- package/src/__tests__/character-reference-photo-kinds.test.ts +32 -0
- package/src/__tests__/character-usage-mode.test.ts +147 -0
- package/src/__tests__/character-variant-assets.test.ts +142 -0
- package/src/__tests__/character-voice.test.ts +130 -0
- package/src/__tests__/cinematic-avatar-pricing.test.ts +119 -0
- package/src/__tests__/combine-transitions.test.ts +137 -0
- package/src/__tests__/component-types.test.ts +87 -0
- package/src/__tests__/condition-variables.test.ts +98 -0
- package/src/__tests__/credit-identifiers.test.ts +811 -0
- package/src/__tests__/default-video-provider.test.ts +63 -0
- package/src/__tests__/entity-image-handle.test.ts +43 -0
- package/src/__tests__/entity-variants.test.ts +33 -0
- package/src/__tests__/fal-lip-sync-sets.test.ts +31 -0
- package/src/__tests__/featured-entities.test.ts +33 -0
- package/src/__tests__/film-pricing.test.ts +64 -0
- package/src/__tests__/filter-condition.test.ts +285 -0
- package/src/__tests__/freecut-protocol.test.ts +35 -0
- package/src/__tests__/generate-text-items.test.ts +19 -0
- package/src/__tests__/generated-results.test.ts +50 -0
- package/src/__tests__/graph-utils.test.ts +618 -0
- package/src/__tests__/group-aggregation.test.ts +83 -0
- package/src/__tests__/i18n-locale-completeness.test.ts +156 -0
- package/src/__tests__/image-critic-node.test.ts +86 -0
- package/src/__tests__/image-mask-mode.test.ts +16 -0
- package/src/__tests__/image-ref-limit.test.ts +78 -0
- package/src/__tests__/inpaint-region.test.ts +24 -0
- package/src/__tests__/input-field-map-parity.test.ts +30 -0
- package/src/__tests__/json-evaluator.test.ts +289 -0
- package/src/__tests__/json-path.test.ts +64 -0
- package/src/__tests__/lip-sync-pricing.test.ts +142 -0
- package/src/__tests__/list-merge.test.ts +96 -0
- package/src/__tests__/list-sort.test.ts +134 -0
- package/src/__tests__/llm-models.test.ts +445 -0
- package/src/__tests__/location-mention-slug.test.ts +246 -0
- package/src/__tests__/locations-coverage-critic-schema.test.ts +92 -0
- package/src/__tests__/loop-delimiter.test.ts +39 -0
- package/src/__tests__/lottie-slots.test.ts +245 -0
- package/src/__tests__/model-catalog-flux2-resolutions.test.ts +21 -0
- package/src/__tests__/model-constants-location.test.ts +20 -0
- package/src/__tests__/model-constants.test.ts +122 -0
- package/src/__tests__/model-tree.test.ts +86 -0
- package/src/__tests__/no-internal-imports.test.ts +25 -0
- package/src/__tests__/node-default-mappings.test.ts +175 -0
- package/src/__tests__/node-mappable-fields.test.ts +7 -0
- package/src/__tests__/node-preset-export.test.ts +46 -0
- package/src/__tests__/node-preset-extract.test.ts +166 -0
- package/src/__tests__/node-refs-canonical.test.ts +54 -0
- package/src/__tests__/node-refs-combine.test.ts +54 -0
- package/src/__tests__/node-refs.test.ts +187 -0
- package/src/__tests__/node-runtime-keys.test.ts +99 -0
- package/src/__tests__/object-aspect-defaults.test.ts +59 -0
- package/src/__tests__/parameter-node-value.test.ts +137 -0
- package/src/__tests__/pinterest-url.test.ts +35 -0
- package/src/__tests__/pipeline-chat.test.ts +110 -0
- package/src/__tests__/pipeline-validation.test.ts +98 -0
- package/src/__tests__/presentation-utils.test.ts +1137 -0
- package/src/__tests__/producer-types.test.ts +47 -0
- package/src/__tests__/prompt-length-limits.test.ts +156 -0
- package/src/__tests__/provider-directive-defaults.test.ts +46 -0
- package/src/__tests__/reduce-strategy-registry.test.ts +43 -0
- package/src/__tests__/reference-board-templates.test.ts +33 -0
- package/src/__tests__/reference-roles.test.ts +36 -0
- package/src/__tests__/resolve-field-mappings.test.ts +110 -0
- package/src/__tests__/resolve-pipeline-model.test.ts +76 -0
- package/src/__tests__/scene-node-types.test.ts +80 -0
- package/src/__tests__/scraper-actors.test.ts +67 -0
- package/src/__tests__/seedance-2-catalog.test.ts +18 -0
- package/src/__tests__/seedance-2-credit-id.test.ts +23 -0
- package/src/__tests__/seedance-aspects.test.ts +52 -0
- package/src/__tests__/selector.test.ts +1151 -0
- package/src/__tests__/settled-with-limit.test.ts +214 -0
- package/src/__tests__/social-media-specs.test.ts +129 -0
- package/src/__tests__/sub-workflow-validation.test.ts +88 -0
- package/src/__tests__/switchx-pricing.test.ts +28 -0
- package/src/__tests__/to-connected-references.test.ts +153 -0
- package/src/__tests__/utilities.test.ts +541 -0
- package/src/__tests__/video-analysis-pricing.test.ts +58 -0
- package/src/__tests__/video-analysis.test.ts +63 -0
- package/src/__tests__/video-audio-capability.test.ts +204 -0
- package/src/__tests__/video-gen-providers.test.ts +28 -0
- package/src/__tests__/video-mode-aliases.test.ts +150 -0
- package/src/__tests__/video-ref-limits.test.ts +72 -0
- package/src/__tests__/video-utils.test.ts +303 -0
- package/src/__tests__/voice-changer-models.test.ts +33 -0
- package/src/__tests__/workflow-export-strip.test.ts +46 -0
- package/src/ai-avatar-pricing.ts +213 -0
- package/src/ancestor-refs.ts +48 -0
- package/src/animals.ts +231 -0
- package/src/audio-crossfade-curves.ts +73 -0
- package/src/audio-fx-presets.ts +64 -0
- package/src/avatar-payload-validators.ts +214 -0
- package/src/caption-styles.ts +31 -0
- package/src/character-aspect-defaults.ts +102 -0
- package/src/character-facets.ts +37 -0
- package/src/character-mention-slug.ts +166 -0
- package/src/character-usage-mode.ts +109 -0
- package/src/character-variant-assets.ts +121 -0
- package/src/character-voice.ts +151 -0
- package/src/cinematic-avatar-pricing.ts +111 -0
- package/src/clone-utils.ts +46 -0
- package/src/combine-transitions.ts +482 -0
- package/src/community.ts +112 -0
- package/src/component-types.ts +127 -0
- package/src/condition-variables.ts +65 -0
- package/src/credit-estimators/index.ts +15 -0
- package/src/credit-estimators/video-utils.ts +165 -0
- package/src/credit-identifiers.ts +304 -0
- package/src/entity-approval-types.ts +31 -0
- package/src/entity-aspect-defaults.ts +82 -0
- package/src/entity-asset-types.ts +296 -0
- package/src/entity-image-handle.ts +36 -0
- package/src/extra-refs.ts +139 -0
- package/src/featured-entities.ts +136 -0
- package/src/film-pricing.ts +117 -0
- package/src/filter-condition.ts +250 -0
- package/src/flux2-pricing.ts +18 -0
- package/src/freecut-protocol.ts +52 -0
- package/src/furniture.ts +167 -0
- package/src/generate-text-items.ts +15 -0
- package/src/generated-results.ts +63 -0
- package/src/group-aggregation.ts +75 -0
- package/src/hint-graph-types.ts +18 -0
- package/src/i18n/action-fx.ar.ts +89 -0
- package/src/i18n/action-fx.de.ts +89 -0
- package/src/i18n/action-fx.es.ts +89 -0
- package/src/i18n/action-fx.fr.ts +89 -0
- package/src/i18n/action-fx.he.ts +89 -0
- package/src/i18n/action-fx.hi.ts +89 -0
- package/src/i18n/action-fx.ja.ts +89 -0
- package/src/i18n/action-fx.ko.ts +89 -0
- package/src/i18n/action-fx.pt-BR.ts +89 -0
- package/src/i18n/action-fx.ru.ts +89 -0
- package/src/i18n/action-fx.zh-CN.ts +89 -0
- package/src/i18n/aesthetic.ar.ts +170 -0
- package/src/i18n/aesthetic.de.ts +48 -0
- package/src/i18n/aesthetic.es.ts +169 -0
- package/src/i18n/aesthetic.fr.ts +52 -0
- package/src/i18n/aesthetic.he.ts +169 -0
- package/src/i18n/aesthetic.hi.ts +55 -0
- package/src/i18n/aesthetic.ja.ts +165 -0
- package/src/i18n/aesthetic.ko.ts +169 -0
- package/src/i18n/aesthetic.pt-BR.ts +148 -0
- package/src/i18n/aesthetic.ru.ts +155 -0
- package/src/i18n/aesthetic.zh-CN.ts +172 -0
- package/src/i18n/animals.ar.ts +145 -0
- package/src/i18n/animals.de.ts +144 -0
- package/src/i18n/animals.es.ts +158 -0
- package/src/i18n/animals.fr.ts +144 -0
- package/src/i18n/animals.he.ts +155 -0
- package/src/i18n/animals.hi.ts +157 -0
- package/src/i18n/animals.ja.ts +159 -0
- package/src/i18n/animals.ko.ts +159 -0
- package/src/i18n/animals.pt-BR.ts +157 -0
- package/src/i18n/animals.ru.ts +155 -0
- package/src/i18n/animals.zh-CN.ts +155 -0
- package/src/i18n/atmosphere.ar.ts +49 -0
- package/src/i18n/atmosphere.de.ts +47 -0
- package/src/i18n/atmosphere.es.ts +50 -0
- package/src/i18n/atmosphere.fr.ts +47 -0
- package/src/i18n/atmosphere.he.ts +47 -0
- package/src/i18n/atmosphere.hi.ts +49 -0
- package/src/i18n/atmosphere.ja.ts +49 -0
- package/src/i18n/atmosphere.ko.ts +49 -0
- package/src/i18n/atmosphere.pt-BR.ts +49 -0
- package/src/i18n/atmosphere.ru.ts +47 -0
- package/src/i18n/atmosphere.zh-CN.ts +152 -0
- package/src/i18n/backdrop.ar.ts +53 -0
- package/src/i18n/backdrop.de.ts +46 -0
- package/src/i18n/backdrop.es.ts +54 -0
- package/src/i18n/backdrop.fr.ts +52 -0
- package/src/i18n/backdrop.he.ts +51 -0
- package/src/i18n/backdrop.hi.ts +59 -0
- package/src/i18n/backdrop.ja.ts +61 -0
- package/src/i18n/backdrop.ko.ts +59 -0
- package/src/i18n/backdrop.pt-BR.ts +59 -0
- package/src/i18n/backdrop.ru.ts +57 -0
- package/src/i18n/backdrop.zh-CN.ts +57 -0
- package/src/i18n/camera-format.ar.ts +40 -0
- package/src/i18n/camera-format.de.ts +37 -0
- package/src/i18n/camera-format.es.ts +41 -0
- package/src/i18n/camera-format.fr.ts +37 -0
- package/src/i18n/camera-format.he.ts +37 -0
- package/src/i18n/camera-format.hi.ts +42 -0
- package/src/i18n/camera-format.ja.ts +37 -0
- package/src/i18n/camera-format.ko.ts +37 -0
- package/src/i18n/camera-format.pt-BR.ts +46 -0
- package/src/i18n/camera-format.ru.ts +42 -0
- package/src/i18n/camera-format.zh-CN.ts +42 -0
- package/src/i18n/camera-motions.ar.ts +86 -0
- package/src/i18n/camera-motions.de.ts +74 -0
- package/src/i18n/camera-motions.es.ts +86 -0
- package/src/i18n/camera-motions.fr.ts +86 -0
- package/src/i18n/camera-motions.he.ts +86 -0
- package/src/i18n/camera-motions.hi.ts +99 -0
- package/src/i18n/camera-motions.ja.ts +99 -0
- package/src/i18n/camera-motions.ko.ts +99 -0
- package/src/i18n/camera-motions.pt-BR.ts +99 -0
- package/src/i18n/camera-motions.ru.ts +99 -0
- package/src/i18n/camera-motions.zh-CN.ts +99 -0
- package/src/i18n/character-fx.ar.ts +72 -0
- package/src/i18n/character-fx.de.ts +72 -0
- package/src/i18n/character-fx.es.ts +72 -0
- package/src/i18n/character-fx.fr.ts +72 -0
- package/src/i18n/character-fx.he.ts +72 -0
- package/src/i18n/character-fx.hi.ts +72 -0
- package/src/i18n/character-fx.ja.ts +72 -0
- package/src/i18n/character-fx.ko.ts +72 -0
- package/src/i18n/character-fx.pt-BR.ts +72 -0
- package/src/i18n/character-fx.ru.ts +72 -0
- package/src/i18n/character-fx.zh-CN.ts +72 -0
- package/src/i18n/color-look.ar.ts +50 -0
- package/src/i18n/color-look.de.ts +47 -0
- package/src/i18n/color-look.es.ts +50 -0
- package/src/i18n/color-look.fr.ts +50 -0
- package/src/i18n/color-look.he.ts +49 -0
- package/src/i18n/color-look.hi.ts +52 -0
- package/src/i18n/color-look.ja.ts +54 -0
- package/src/i18n/color-look.ko.ts +54 -0
- package/src/i18n/color-look.pt-BR.ts +54 -0
- package/src/i18n/color-look.ru.ts +52 -0
- package/src/i18n/color-look.zh-CN.ts +53 -0
- package/src/i18n/composition-effects.ar.ts +26 -0
- package/src/i18n/composition-effects.de.ts +25 -0
- package/src/i18n/composition-effects.es.ts +27 -0
- package/src/i18n/composition-effects.fr.ts +25 -0
- package/src/i18n/composition-effects.he.ts +25 -0
- package/src/i18n/composition-effects.hi.ts +27 -0
- package/src/i18n/composition-effects.ja.ts +27 -0
- package/src/i18n/composition-effects.ko.ts +27 -0
- package/src/i18n/composition-effects.pt-BR.ts +25 -0
- package/src/i18n/composition-effects.ru.ts +82 -0
- package/src/i18n/composition-effects.zh-CN.ts +25 -0
- package/src/i18n/era.ar.ts +37 -0
- package/src/i18n/era.de.ts +34 -0
- package/src/i18n/era.es.ts +37 -0
- package/src/i18n/era.fr.ts +37 -0
- package/src/i18n/era.he.ts +36 -0
- package/src/i18n/era.hi.ts +39 -0
- package/src/i18n/era.ja.ts +41 -0
- package/src/i18n/era.ko.ts +39 -0
- package/src/i18n/era.pt-BR.ts +41 -0
- package/src/i18n/era.ru.ts +121 -0
- package/src/i18n/era.zh-CN.ts +39 -0
- package/src/i18n/exposure-settings.ar.ts +28 -0
- package/src/i18n/exposure-settings.de.ts +26 -0
- package/src/i18n/exposure-settings.es.ts +28 -0
- package/src/i18n/exposure-settings.fr.ts +29 -0
- package/src/i18n/exposure-settings.he.ts +28 -0
- package/src/i18n/exposure-settings.hi.ts +31 -0
- package/src/i18n/exposure-settings.ja.ts +31 -0
- package/src/i18n/exposure-settings.ko.ts +31 -0
- package/src/i18n/exposure-settings.pt-BR.ts +31 -0
- package/src/i18n/exposure-settings.ru.ts +31 -0
- package/src/i18n/exposure-settings.zh-CN.ts +31 -0
- package/src/i18n/framing.ar.ts +78 -0
- package/src/i18n/framing.de.ts +73 -0
- package/src/i18n/framing.es.ts +78 -0
- package/src/i18n/framing.fr.ts +78 -0
- package/src/i18n/framing.he.ts +77 -0
- package/src/i18n/framing.hi.ts +82 -0
- package/src/i18n/framing.ja.ts +84 -0
- package/src/i18n/framing.ko.ts +82 -0
- package/src/i18n/framing.pt-BR.ts +84 -0
- package/src/i18n/framing.ru.ts +82 -0
- package/src/i18n/framing.zh-CN.ts +82 -0
- package/src/i18n/furniture.ar.ts +92 -0
- package/src/i18n/furniture.de.ts +93 -0
- package/src/i18n/furniture.es.ts +101 -0
- package/src/i18n/furniture.fr.ts +93 -0
- package/src/i18n/furniture.he.ts +101 -0
- package/src/i18n/furniture.hi.ts +101 -0
- package/src/i18n/furniture.ja.ts +101 -0
- package/src/i18n/furniture.ko.ts +101 -0
- package/src/i18n/furniture.pt-BR.ts +101 -0
- package/src/i18n/furniture.ru.ts +101 -0
- package/src/i18n/furniture.zh-CN.ts +101 -0
- package/src/i18n/held-prop.ar.ts +74 -0
- package/src/i18n/held-prop.de.ts +65 -0
- package/src/i18n/held-prop.es.ts +83 -0
- package/src/i18n/held-prop.fr.ts +74 -0
- package/src/i18n/held-prop.he.ts +73 -0
- package/src/i18n/held-prop.hi.ts +82 -0
- package/src/i18n/held-prop.ja.ts +84 -0
- package/src/i18n/held-prop.ko.ts +84 -0
- package/src/i18n/held-prop.pt-BR.ts +84 -0
- package/src/i18n/held-prop.ru.ts +82 -0
- package/src/i18n/held-prop.zh-CN.ts +82 -0
- package/src/i18n/index.ts +208 -0
- package/src/i18n/instrumentation.ar.ts +195 -0
- package/src/i18n/instrumentation.de.ts +195 -0
- package/src/i18n/instrumentation.es.ts +195 -0
- package/src/i18n/instrumentation.fr.ts +195 -0
- package/src/i18n/instrumentation.he.ts +195 -0
- package/src/i18n/instrumentation.hi.ts +195 -0
- package/src/i18n/instrumentation.ja.ts +195 -0
- package/src/i18n/instrumentation.ko.ts +195 -0
- package/src/i18n/instrumentation.pt-BR.ts +195 -0
- package/src/i18n/instrumentation.ru.ts +195 -0
- package/src/i18n/instrumentation.zh-CN.ts +195 -0
- package/src/i18n/lens.ar.ts +24 -0
- package/src/i18n/lens.de.ts +24 -0
- package/src/i18n/lens.es.ts +24 -0
- package/src/i18n/lens.fr.ts +24 -0
- package/src/i18n/lens.he.ts +24 -0
- package/src/i18n/lens.hi.ts +24 -0
- package/src/i18n/lens.ja.ts +24 -0
- package/src/i18n/lens.ko.ts +24 -0
- package/src/i18n/lens.pt-BR.ts +24 -0
- package/src/i18n/lens.ru.ts +25 -0
- package/src/i18n/lens.zh-CN.ts +24 -0
- package/src/i18n/lighting.ar.ts +86 -0
- package/src/i18n/lighting.de.ts +84 -0
- package/src/i18n/lighting.es.ts +89 -0
- package/src/i18n/lighting.fr.ts +84 -0
- package/src/i18n/lighting.he.ts +88 -0
- package/src/i18n/lighting.hi.ts +90 -0
- package/src/i18n/lighting.ja.ts +90 -0
- package/src/i18n/lighting.ko.ts +90 -0
- package/src/i18n/lighting.pt-BR.ts +90 -0
- package/src/i18n/lighting.ru.ts +88 -0
- package/src/i18n/lighting.zh-CN.ts +92 -0
- package/src/i18n/loop-subject.ar.ts +39 -0
- package/src/i18n/loop-subject.de.ts +39 -0
- package/src/i18n/loop-subject.es.ts +39 -0
- package/src/i18n/loop-subject.fr.ts +39 -0
- package/src/i18n/loop-subject.he.ts +39 -0
- package/src/i18n/loop-subject.hi.ts +39 -0
- package/src/i18n/loop-subject.ja.ts +39 -0
- package/src/i18n/loop-subject.ko.ts +39 -0
- package/src/i18n/loop-subject.pt-BR.ts +39 -0
- package/src/i18n/loop-subject.ru.ts +39 -0
- package/src/i18n/loop-subject.zh-CN.ts +39 -0
- package/src/i18n/materials.ar.ts +80 -0
- package/src/i18n/materials.de.ts +80 -0
- package/src/i18n/materials.es.ts +87 -0
- package/src/i18n/materials.fr.ts +80 -0
- package/src/i18n/materials.he.ts +86 -0
- package/src/i18n/materials.hi.ts +86 -0
- package/src/i18n/materials.ja.ts +88 -0
- package/src/i18n/materials.ko.ts +88 -0
- package/src/i18n/materials.pt-BR.ts +88 -0
- package/src/i18n/materials.ru.ts +86 -0
- package/src/i18n/materials.zh-CN.ts +86 -0
- package/src/i18n/mood.ar.ts +61 -0
- package/src/i18n/mood.de.ts +61 -0
- package/src/i18n/mood.es.ts +66 -0
- package/src/i18n/mood.fr.ts +61 -0
- package/src/i18n/mood.he.ts +64 -0
- package/src/i18n/mood.hi.ts +66 -0
- package/src/i18n/mood.ja.ts +66 -0
- package/src/i18n/mood.ko.ts +66 -0
- package/src/i18n/mood.pt-BR.ts +64 -0
- package/src/i18n/mood.ru.ts +64 -0
- package/src/i18n/mood.zh-CN.ts +64 -0
- package/src/i18n/music-genre.ar.ts +302 -0
- package/src/i18n/music-genre.de.ts +302 -0
- package/src/i18n/music-genre.es.ts +302 -0
- package/src/i18n/music-genre.fr.ts +302 -0
- package/src/i18n/music-genre.he.ts +302 -0
- package/src/i18n/music-genre.hi.ts +302 -0
- package/src/i18n/music-genre.ja.ts +302 -0
- package/src/i18n/music-genre.ko.ts +302 -0
- package/src/i18n/music-genre.pt-BR.ts +302 -0
- package/src/i18n/music-genre.ru.ts +302 -0
- package/src/i18n/music-genre.zh-CN.ts +302 -0
- package/src/i18n/music-mood.ar.ts +75 -0
- package/src/i18n/music-mood.de.ts +75 -0
- package/src/i18n/music-mood.es.ts +75 -0
- package/src/i18n/music-mood.fr.ts +75 -0
- package/src/i18n/music-mood.he.ts +75 -0
- package/src/i18n/music-mood.hi.ts +75 -0
- package/src/i18n/music-mood.ja.ts +75 -0
- package/src/i18n/music-mood.ko.ts +75 -0
- package/src/i18n/music-mood.pt-BR.ts +75 -0
- package/src/i18n/music-mood.ru.ts +75 -0
- package/src/i18n/music-mood.zh-CN.ts +75 -0
- package/src/i18n/person.ar.ts +638 -0
- package/src/i18n/person.de.ts +629 -0
- package/src/i18n/person.es.ts +645 -0
- package/src/i18n/person.fr.ts +621 -0
- package/src/i18n/person.he.ts +656 -0
- package/src/i18n/person.hi.ts +654 -0
- package/src/i18n/person.ja.ts +662 -0
- package/src/i18n/person.ko.ts +662 -0
- package/src/i18n/person.pt-BR.ts +656 -0
- package/src/i18n/person.ru.ts +656 -0
- package/src/i18n/person.zh-CN.ts +656 -0
- package/src/i18n/photo-genre.ar.ts +58 -0
- package/src/i18n/photo-genre.de.ts +52 -0
- package/src/i18n/photo-genre.es.ts +64 -0
- package/src/i18n/photo-genre.fr.ts +58 -0
- package/src/i18n/photo-genre.he.ts +62 -0
- package/src/i18n/photo-genre.hi.ts +63 -0
- package/src/i18n/photo-genre.ja.ts +65 -0
- package/src/i18n/photo-genre.ko.ts +63 -0
- package/src/i18n/photo-genre.pt-BR.ts +65 -0
- package/src/i18n/photo-genre.ru.ts +63 -0
- package/src/i18n/photo-genre.zh-CN.ts +63 -0
- package/src/i18n/photographer.ar.ts +75 -0
- package/src/i18n/photographer.de.ts +74 -0
- package/src/i18n/photographer.es.ts +77 -0
- package/src/i18n/photographer.fr.ts +77 -0
- package/src/i18n/photographer.he.ts +78 -0
- package/src/i18n/photographer.hi.ts +80 -0
- package/src/i18n/photographer.ja.ts +84 -0
- package/src/i18n/photographer.ko.ts +84 -0
- package/src/i18n/photographer.pt-BR.ts +83 -0
- package/src/i18n/photographer.ru.ts +78 -0
- package/src/i18n/photographer.zh-CN.ts +78 -0
- package/src/i18n/pose.ar.ts +95 -0
- package/src/i18n/pose.de.ts +96 -0
- package/src/i18n/pose.es.ts +104 -0
- package/src/i18n/pose.fr.ts +96 -0
- package/src/i18n/pose.he.ts +104 -0
- package/src/i18n/pose.hi.ts +104 -0
- package/src/i18n/pose.ja.ts +104 -0
- package/src/i18n/pose.ko.ts +104 -0
- package/src/i18n/pose.pt-BR.ts +104 -0
- package/src/i18n/pose.ru.ts +104 -0
- package/src/i18n/pose.zh-CN.ts +104 -0
- package/src/i18n/post-process-effects.ar.ts +25 -0
- package/src/i18n/post-process-effects.de.ts +24 -0
- package/src/i18n/post-process-effects.es.ts +26 -0
- package/src/i18n/post-process-effects.fr.ts +24 -0
- package/src/i18n/post-process-effects.he.ts +24 -0
- package/src/i18n/post-process-effects.hi.ts +26 -0
- package/src/i18n/post-process-effects.ja.ts +26 -0
- package/src/i18n/post-process-effects.ko.ts +26 -0
- package/src/i18n/post-process-effects.pt-BR.ts +24 -0
- package/src/i18n/post-process-effects.ru.ts +24 -0
- package/src/i18n/post-process-effects.zh-CN.ts +24 -0
- package/src/i18n/render-quality.ar.ts +34 -0
- package/src/i18n/render-quality.de.ts +30 -0
- package/src/i18n/render-quality.es.ts +35 -0
- package/src/i18n/render-quality.fr.ts +34 -0
- package/src/i18n/render-quality.he.ts +33 -0
- package/src/i18n/render-quality.hi.ts +39 -0
- package/src/i18n/render-quality.ja.ts +39 -0
- package/src/i18n/render-quality.ko.ts +39 -0
- package/src/i18n/render-quality.pt-BR.ts +37 -0
- package/src/i18n/render-quality.ru.ts +37 -0
- package/src/i18n/render-quality.zh-CN.ts +37 -0
- package/src/i18n/seasons.ar.ts +10 -0
- package/src/i18n/seasons.de.ts +10 -0
- package/src/i18n/seasons.es.ts +10 -0
- package/src/i18n/seasons.fr.ts +10 -0
- package/src/i18n/seasons.he.ts +10 -0
- package/src/i18n/seasons.hi.ts +10 -0
- package/src/i18n/seasons.ja.ts +10 -0
- package/src/i18n/seasons.ko.ts +10 -0
- package/src/i18n/seasons.pt-BR.ts +10 -0
- package/src/i18n/seasons.ru.ts +10 -0
- package/src/i18n/seasons.zh-CN.ts +10 -0
- package/src/i18n/setting.ar.ts +73 -0
- package/src/i18n/setting.de.ts +73 -0
- package/src/i18n/setting.es.ts +77 -0
- package/src/i18n/setting.fr.ts +73 -0
- package/src/i18n/setting.he.ts +76 -0
- package/src/i18n/setting.hi.ts +76 -0
- package/src/i18n/setting.ja.ts +78 -0
- package/src/i18n/setting.ko.ts +76 -0
- package/src/i18n/setting.pt-BR.ts +78 -0
- package/src/i18n/setting.ru.ts +76 -0
- package/src/i18n/setting.zh-CN.ts +76 -0
- package/src/i18n/style.ar.ts +55 -0
- package/src/i18n/style.de.ts +54 -0
- package/src/i18n/style.es.ts +54 -0
- package/src/i18n/style.fr.ts +54 -0
- package/src/i18n/style.he.ts +54 -0
- package/src/i18n/style.hi.ts +54 -0
- package/src/i18n/style.ja.ts +54 -0
- package/src/i18n/style.ko.ts +54 -0
- package/src/i18n/style.pt-BR.ts +56 -0
- package/src/i18n/style.ru.ts +54 -0
- package/src/i18n/style.zh-CN.ts +54 -0
- package/src/i18n/styling.ar.ts +295 -0
- package/src/i18n/styling.de.ts +285 -0
- package/src/i18n/styling.es.ts +317 -0
- package/src/i18n/styling.fr.ts +285 -0
- package/src/i18n/styling.he.ts +307 -0
- package/src/i18n/styling.hi.ts +323 -0
- package/src/i18n/styling.ja.ts +317 -0
- package/src/i18n/styling.ko.ts +311 -0
- package/src/i18n/styling.pt-BR.ts +301 -0
- package/src/i18n/styling.ru.ts +301 -0
- package/src/i18n/styling.zh-CN.ts +307 -0
- package/src/i18n/temporal.ar.ts +31 -0
- package/src/i18n/temporal.de.ts +24 -0
- package/src/i18n/temporal.es.ts +27 -0
- package/src/i18n/temporal.fr.ts +28 -0
- package/src/i18n/temporal.he.ts +31 -0
- package/src/i18n/temporal.hi.ts +31 -0
- package/src/i18n/temporal.ja.ts +31 -0
- package/src/i18n/temporal.ko.ts +31 -0
- package/src/i18n/temporal.pt-BR.ts +31 -0
- package/src/i18n/temporal.ru.ts +31 -0
- package/src/i18n/temporal.zh-CN.ts +31 -0
- package/src/i18n/transitions.ar.ts +97 -0
- package/src/i18n/transitions.de.ts +97 -0
- package/src/i18n/transitions.es.ts +97 -0
- package/src/i18n/transitions.fr.ts +97 -0
- package/src/i18n/transitions.he.ts +97 -0
- package/src/i18n/transitions.hi.ts +97 -0
- package/src/i18n/transitions.ja.ts +97 -0
- package/src/i18n/transitions.ko.ts +97 -0
- package/src/i18n/transitions.pt-BR.ts +97 -0
- package/src/i18n/transitions.ru.ts +97 -0
- package/src/i18n/transitions.zh-CN.ts +97 -0
- package/src/i18n/types.ts +158 -0
- package/src/i18n/vehicles.ar.ts +137 -0
- package/src/i18n/vehicles.de.ts +125 -0
- package/src/i18n/vehicles.es.ts +138 -0
- package/src/i18n/vehicles.fr.ts +125 -0
- package/src/i18n/vehicles.he.ts +136 -0
- package/src/i18n/vehicles.hi.ts +138 -0
- package/src/i18n/vehicles.ja.ts +138 -0
- package/src/i18n/vehicles.ko.ts +138 -0
- package/src/i18n/vehicles.pt-BR.ts +136 -0
- package/src/i18n/vehicles.ru.ts +136 -0
- package/src/i18n/vehicles.zh-CN.ts +136 -0
- package/src/i18n/voice-character.ar.ts +126 -0
- package/src/i18n/voice-character.de.ts +126 -0
- package/src/i18n/voice-character.es.ts +126 -0
- package/src/i18n/voice-character.fr.ts +126 -0
- package/src/i18n/voice-character.he.ts +126 -0
- package/src/i18n/voice-character.hi.ts +126 -0
- package/src/i18n/voice-character.ja.ts +126 -0
- package/src/i18n/voice-character.ko.ts +126 -0
- package/src/i18n/voice-character.pt-BR.ts +126 -0
- package/src/i18n/voice-character.ru.ts +126 -0
- package/src/i18n/voice-character.zh-CN.ts +126 -0
- package/src/i18n/voice-delivery.ar.ts +77 -0
- package/src/i18n/voice-delivery.de.ts +77 -0
- package/src/i18n/voice-delivery.es.ts +77 -0
- package/src/i18n/voice-delivery.fr.ts +77 -0
- package/src/i18n/voice-delivery.he.ts +77 -0
- package/src/i18n/voice-delivery.hi.ts +77 -0
- package/src/i18n/voice-delivery.ja.ts +77 -0
- package/src/i18n/voice-delivery.ko.ts +77 -0
- package/src/i18n/voice-delivery.pt-BR.ts +77 -0
- package/src/i18n/voice-delivery.ru.ts +77 -0
- package/src/i18n/voice-delivery.zh-CN.ts +77 -0
- package/src/i18n/weapons.ar.ts +115 -0
- package/src/i18n/weapons.de.ts +114 -0
- package/src/i18n/weapons.es.ts +116 -0
- package/src/i18n/weapons.fr.ts +103 -0
- package/src/i18n/weapons.he.ts +114 -0
- package/src/i18n/weapons.hi.ts +116 -0
- package/src/i18n/weapons.ja.ts +116 -0
- package/src/i18n/weapons.ko.ts +116 -0
- package/src/i18n/weapons.pt-BR.ts +114 -0
- package/src/i18n/weapons.ru.ts +114 -0
- package/src/i18n/weapons.zh-CN.ts +114 -0
- package/src/image-critic-node.ts +61 -0
- package/src/image-critic-types.ts +40 -0
- package/src/index.ts +866 -0
- package/src/inject-upstream.ts +15 -0
- package/src/inpaint-region.ts +51 -0
- package/src/json-evaluator.ts +732 -0
- package/src/json-path.ts +52 -0
- package/src/lip-sync-pricing.ts +90 -0
- package/src/list-merge.ts +40 -0
- package/src/list-sort.ts +122 -0
- package/src/list-source-resolver.ts +50 -0
- package/src/llm-models.ts +245 -0
- package/src/location-mention-slug.ts +291 -0
- package/src/location-preset-catalog-map.ts +128 -0
- package/src/loop-delimiter.ts +73 -0
- package/src/lora-routing.ts +95 -0
- package/src/lottie-overlay-catalog.ts +175 -0
- package/src/lottie-slots.ts +309 -0
- package/src/model-catalog.ts +2386 -0
- package/src/model-constants.ts +1910 -0
- package/src/model-tree.ts +120 -0
- package/src/monetization.ts +15 -0
- package/src/multi-pick.ts +42 -0
- package/src/node-default-mappings.ts +262 -0
- package/src/node-mappable-fields.ts +70 -0
- package/src/node-preset-export.ts +56 -0
- package/src/node-preset-extract.ts +147 -0
- package/src/node-refs.ts +253 -0
- package/src/node-runtime-keys.ts +117 -0
- package/src/object-aspect-defaults.ts +72 -0
- package/src/object-picker-types.ts +22 -0
- package/src/parameter-node-value.ts +284 -0
- package/src/pinterest-url.ts +28 -0
- package/src/pipeline-chat.ts +72 -0
- package/src/pipeline-defaults.ts +318 -0
- package/src/pipeline-events.ts +162 -0
- package/src/pipeline-state-types.ts +196 -0
- package/src/pipeline-types.ts +647 -0
- package/src/pipeline-validation.ts +87 -0
- package/src/presentation-types.ts +23 -0
- package/src/presentation-utils.ts +397 -0
- package/src/producer-types.ts +188 -0
- package/src/progress-curve.ts +99 -0
- package/src/provider-directive-defaults.ts +69 -0
- package/src/reduce-strategy-registry.ts +121 -0
- package/src/reference-board-templates.ts +81 -0
- package/src/reference-roles.ts +153 -0
- package/src/reference-sheet/__tests__/board-to-column.test.ts +20 -0
- package/src/reference-sheet/__tests__/catalog.test.ts +50 -0
- package/src/reference-sheet/__tests__/cost.test.ts +38 -0
- package/src/reference-sheet/__tests__/no-drift.test.ts +28 -0
- package/src/reference-sheet/__tests__/panel-plan.test.ts +61 -0
- package/src/reference-sheet/__tests__/panel-prompts.test.ts +17 -0
- package/src/reference-sheet/__tests__/plan-generation.test.ts +72 -0
- package/src/reference-sheet/__tests__/presets.test.ts +54 -0
- package/src/reference-sheet/__tests__/types.test.ts +24 -0
- package/src/reference-sheet/catalog.ts +144 -0
- package/src/reference-sheet/cost.ts +37 -0
- package/src/reference-sheet/credit-id.ts +7 -0
- package/src/reference-sheet/index.ts +8 -0
- package/src/reference-sheet/panel-plan.ts +65 -0
- package/src/reference-sheet/panel-prompts.ts +14 -0
- package/src/reference-sheet/plan-generation.ts +79 -0
- package/src/reference-sheet/presets.ts +77 -0
- package/src/reference-sheet/types.ts +92 -0
- package/src/repeat-types.ts +97 -0
- package/src/resolve-field-mappings.ts +119 -0
- package/src/route-filter.ts +80 -0
- package/src/scene-helper-types.ts +249 -0
- package/src/scene-node-types.ts +281 -0
- package/src/scraper-actors.ts +57 -0
- package/src/scraper-output-schemas.ts +25 -0
- package/src/seasons.ts +45 -0
- package/src/selector.ts +864 -0
- package/src/settled-with-limit.ts +42 -0
- package/src/shot-element.ts +43 -0
- package/src/social-media-specs.ts +121 -0
- package/src/social-post.ts +24 -0
- package/src/sub-workflow-validation.ts +78 -0
- package/src/supported-fonts.ts +40 -0
- package/src/surround.ts +113 -0
- package/src/switchx-pricing.ts +33 -0
- package/src/text-separators.ts +59 -0
- package/src/to-connected-references.ts +77 -0
- package/src/types.ts +272 -0
- package/src/variant-job-id.ts +17 -0
- package/src/vehicles.ts +213 -0
- package/src/video-analysis-pricing.ts +74 -0
- package/src/video-analysis.ts +127 -0
- package/src/video-duration.ts +25 -0
- package/src/voice-changer-models.ts +36 -0
- package/src/voice-matcher-types.ts +37 -0
- package/src/voices.ts +92 -0
- package/src/weapons.ts +190 -0
- package/src/workflow-export.ts +153 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { SheetSection, SheetEntry, SheetType, SheetSkin, SheetAspect, SheetPresetId } from "./types.js"
|
|
2
|
+
|
|
3
|
+
export type { SheetPresetId }
|
|
4
|
+
|
|
5
|
+
/** Build ordered preset entries from a variant list (a curated board subset). */
|
|
6
|
+
export const presetEntries = (vs: readonly string[]): SheetEntry[] =>
|
|
7
|
+
vs.map((variant) => ({ kind: "preset", variant }))
|
|
8
|
+
|
|
9
|
+
export interface SheetPreset {
|
|
10
|
+
id: SheetPresetId
|
|
11
|
+
label: string
|
|
12
|
+
description: string
|
|
13
|
+
/** Carrier for the route's required `type` enum; the layout comes from `baseSections`. */
|
|
14
|
+
type: SheetType
|
|
15
|
+
baseSections: SheetSection[]
|
|
16
|
+
skin: SheetSkin
|
|
17
|
+
aspect: SheetAspect
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Studio sheet presets (character only). Each bundles a curated head+body
|
|
22
|
+
* turnaround (via `entries`) + a default skin/aspect + a carrier `type`. The
|
|
23
|
+
* à-la-carte boards below layer optional extra bands on top.
|
|
24
|
+
*
|
|
25
|
+
* `studio-main` is the clean screenshot format (head: front, profiles, back-of-
|
|
26
|
+
* head; body: front, side, back). `studio-extended` adds above/below + 3/4
|
|
27
|
+
* angles for fuller coverage.
|
|
28
|
+
*/
|
|
29
|
+
export const SHEET_PRESETS: readonly SheetPreset[] = [
|
|
30
|
+
{
|
|
31
|
+
id: "studio-main",
|
|
32
|
+
label: "Studio · Main",
|
|
33
|
+
description: "Clean turnaround for AI video reference — head (front, profiles, back) + body (front, side, back).",
|
|
34
|
+
type: "turnaround",
|
|
35
|
+
skin: "studio",
|
|
36
|
+
aspect: "landscape",
|
|
37
|
+
baseSections: [
|
|
38
|
+
{ kind: "head-turnaround", entries: presetEntries(["front", "left profile", "right profile", "back"]) },
|
|
39
|
+
{ kind: "body-turnaround", entries: presetEntries(["front", "left profile", "back"]) },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: "studio-extended",
|
|
44
|
+
label: "Studio · Extended",
|
|
45
|
+
description: "Full turnaround — adds above/below and 3/4 angles for maximum coverage.",
|
|
46
|
+
type: "full-reference",
|
|
47
|
+
skin: "studio",
|
|
48
|
+
aspect: "landscape",
|
|
49
|
+
baseSections: [
|
|
50
|
+
{ kind: "head-turnaround", entries: presetEntries(["front", "3/4 left", "left profile", "right profile", "3/4 right", "above", "below", "back"]) },
|
|
51
|
+
{ kind: "body-turnaround", entries: presetEntries(["front", "3/4 left", "left profile", "right profile", "back", "above", "below"]) },
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
export const PRESET_LABELS: Record<SheetPresetId, string> = {
|
|
57
|
+
"studio-main": "Studio · Main",
|
|
58
|
+
"studio-extended": "Studio · Extended",
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface AlaCarteBoard {
|
|
62
|
+
id: string
|
|
63
|
+
label: string
|
|
64
|
+
/** UI hint: panels this board adds (the board's default slice). Free boards are 0. */
|
|
65
|
+
panelCount: number
|
|
66
|
+
section: SheetSection
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Optional boards layered on a base preset. No `entries` → the planner uses the
|
|
70
|
+
* board's default slice (`min(4, board length)`). Palette is structural (free). */
|
|
71
|
+
export const ALA_CARTE_BOARDS: readonly AlaCarteBoard[] = [
|
|
72
|
+
{ id: "expressions", label: "Expressions", panelCount: 4, section: { kind: "expression-board" } },
|
|
73
|
+
{ id: "poses", label: "Poses", panelCount: 4, section: { kind: "pose-board" } },
|
|
74
|
+
{ id: "wardrobe", label: "Wardrobe", panelCount: 3, section: { kind: "wardrobe-board" } },
|
|
75
|
+
{ id: "detail", label: "Detail", panelCount: 3, section: { kind: "detail-board" } },
|
|
76
|
+
{ id: "palette", label: "Palette", panelCount: 0, section: { kind: "palette" } },
|
|
77
|
+
]
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export type EntityKind = "character" | "object" | "location"
|
|
2
|
+
|
|
3
|
+
export const SHEET_TYPES = ["turnaround", "variation-board", "detail", "full-reference"] as const
|
|
4
|
+
export type SheetType = (typeof SHEET_TYPES)[number]
|
|
5
|
+
|
|
6
|
+
export const SHEET_SKINS = ["studio", "cinematic", "blueprint", "illustrated"] as const
|
|
7
|
+
export type SheetSkin = (typeof SHEET_SKINS)[number]
|
|
8
|
+
|
|
9
|
+
export const SHEET_ASPECTS = ["landscape", "square", "story"] as const
|
|
10
|
+
export type SheetAspect = (typeof SHEET_ASPECTS)[number]
|
|
11
|
+
|
|
12
|
+
/** Studio sheet presets (character only). Declared here so SheetFlavour can carry
|
|
13
|
+
* it without a cycle (`presets.ts` re-exports it alongside the registry). */
|
|
14
|
+
export type SheetPresetId = "studio-main" | "studio-extended"
|
|
15
|
+
|
|
16
|
+
export const OUTPUT_FORMATS = ["still", "motion"] as const
|
|
17
|
+
export type OutputFormat = (typeof OUTPUT_FORMATS)[number]
|
|
18
|
+
|
|
19
|
+
export const SECTION_KINDS = [
|
|
20
|
+
"header",
|
|
21
|
+
"head-turnaround", "body-turnaround", "turnaround", "coverage",
|
|
22
|
+
"expression-board", "pose-board", "material-board", "variation-board", "environment-board",
|
|
23
|
+
"detail-board", "wardrobe-board",
|
|
24
|
+
"palette", "scale", "notes",
|
|
25
|
+
] as const
|
|
26
|
+
export type SectionKind = (typeof SECTION_KINDS)[number]
|
|
27
|
+
|
|
28
|
+
export const SHEET_BACKGROUNDS = ["grey", "white", "transparent", "in-context"] as const
|
|
29
|
+
export type SheetBackground = (typeof SHEET_BACKGROUNDS)[number]
|
|
30
|
+
|
|
31
|
+
/** A board entry is either a catalog preset (by variant) or a user-authored custom panel. */
|
|
32
|
+
export interface PresetEntry { kind: "preset"; variant: string }
|
|
33
|
+
export interface CustomEntry { kind: "custom"; label: string; prompt: string }
|
|
34
|
+
export type SheetEntry = PresetEntry | CustomEntry
|
|
35
|
+
|
|
36
|
+
/** One band in the sheet. `board` disambiguates kinds that map to several buckets (environment-board). */
|
|
37
|
+
export interface SheetSection {
|
|
38
|
+
kind: SectionKind
|
|
39
|
+
board?: string
|
|
40
|
+
subtitle?: string
|
|
41
|
+
panelCount?: number
|
|
42
|
+
entries?: SheetEntry[] // omitted => planner fills the default preset set
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface SheetFlavour {
|
|
46
|
+
outputFormat: OutputFormat
|
|
47
|
+
withText: boolean
|
|
48
|
+
showLabels: boolean
|
|
49
|
+
aspect: SheetAspect
|
|
50
|
+
background: SheetBackground
|
|
51
|
+
sections?: SheetSection[] // explicit stack for `full-reference`; other types derive defaults
|
|
52
|
+
presetId?: SheetPresetId // labels studio preset sheets; inert to pricing/composition
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** A single panel the planner says must exist (reused or generated). */
|
|
56
|
+
export interface PanelRequest {
|
|
57
|
+
section: SectionKind
|
|
58
|
+
board: string // logical board key (maps to a DB column via the backend adapter, Plan 04)
|
|
59
|
+
variant: string // preset variant string, or the custom label
|
|
60
|
+
label: string
|
|
61
|
+
custom: boolean
|
|
62
|
+
prompt?: string // present iff custom
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface Swatch { hex: string; label: string }
|
|
66
|
+
export interface PanelSource { board: string; variant: string; assetId?: string; url: string }
|
|
67
|
+
export interface SheetTextData {
|
|
68
|
+
title?: string
|
|
69
|
+
metadata?: Record<string, string>
|
|
70
|
+
notes?: string
|
|
71
|
+
sectionLabels?: Record<string, string>
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface ReferenceSheet {
|
|
75
|
+
id: string
|
|
76
|
+
type: SheetType
|
|
77
|
+
skin: SheetSkin
|
|
78
|
+
flavour: SheetFlavour
|
|
79
|
+
source: "studio" | "node"
|
|
80
|
+
url: string
|
|
81
|
+
panelUrls: string[]
|
|
82
|
+
panelSources: PanelSource[]
|
|
83
|
+
sectionsSnapshot: SheetSection[]
|
|
84
|
+
metadataSnapshot: SheetTextData
|
|
85
|
+
paletteSnapshot: Swatch[]
|
|
86
|
+
sourceImageUrlAtGen: string
|
|
87
|
+
createdAt: string
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Hard ceilings (also re-asserted in the route Zod schema, Plan 04). */
|
|
91
|
+
export const MAX_PANELS_PER_SHEET = 24
|
|
92
|
+
export const MAX_CUSTOM_ENTRIES_PER_BOARD = 12
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/** AI generation node types that support repeat-N execution.
|
|
2
|
+
* Excludes deterministic nodes, FFmpeg, social, render, and utility nodes. */
|
|
3
|
+
export const REPEATABLE_NODE_TYPES = new Set([
|
|
4
|
+
"generate-image", "edit-image", "image-to-image",
|
|
5
|
+
"image-to-video", "video-to-video", "text-to-video",
|
|
6
|
+
"text-to-speech", "generate-music", "text-to-audio", "text-to-dialogue",
|
|
7
|
+
"ai-writer", "llm-chat", "generate-script",
|
|
8
|
+
"suno-generate", "suno-cover", "suno-extend", "suno-lyrics",
|
|
9
|
+
"lip-sync", "speech-to-video",
|
|
10
|
+
"motion-transfer", "extend-video",
|
|
11
|
+
"video-composer", "after-effects", "lottie-overlay", "3d-title", "motion-graphics",
|
|
12
|
+
"voice-changer", "dubbing", "voice-remix", "voice-design",
|
|
13
|
+
"component",
|
|
14
|
+
])
|
|
15
|
+
|
|
16
|
+
/** Sentinel value used as list item for repeat-only execution (no list fan-out input).
|
|
17
|
+
* executeNodeForList skips the overridePrompt/overrideMediaUrl when it sees this. */
|
|
18
|
+
export const REPEAT_PLACEHOLDER = "__repeat__"
|
|
19
|
+
|
|
20
|
+
/** Sentinel prefix for per-iteration provider override.
|
|
21
|
+
* An item like `__provider:nano-banana__` tells executeNodeForList to clone the
|
|
22
|
+
* node with `data.provider = "nano-banana"` for that iteration and otherwise
|
|
23
|
+
* behave like REPEAT_PLACEHOLDER (no prompt/media override). */
|
|
24
|
+
export const PROVIDER_PLACEHOLDER_PREFIX = "__provider:"
|
|
25
|
+
const PROVIDER_PLACEHOLDER_SUFFIX = "__"
|
|
26
|
+
|
|
27
|
+
export function encodeProviderItem(provider: string): string {
|
|
28
|
+
return `${PROVIDER_PLACEHOLDER_PREFIX}${provider}${PROVIDER_PLACEHOLDER_SUFFIX}`
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function decodeProviderItem(item: string): string | undefined {
|
|
32
|
+
if (!item.startsWith(PROVIDER_PLACEHOLDER_PREFIX)) return undefined
|
|
33
|
+
if (!item.endsWith(PROVIDER_PLACEHOLDER_SUFFIX)) return undefined
|
|
34
|
+
const inner = item.slice(
|
|
35
|
+
PROVIDER_PLACEHOLDER_PREFIX.length,
|
|
36
|
+
item.length - PROVIDER_PLACEHOLDER_SUFFIX.length,
|
|
37
|
+
)
|
|
38
|
+
return inner.length > 0 ? inner : undefined
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Read repeatCount from node data, clamped to 1-20. Returns 1 if unset/invalid. */
|
|
42
|
+
export function getEffectiveRepeatCount(nodeData: Record<string, unknown>): number {
|
|
43
|
+
const raw = nodeData.repeatCount as number | undefined
|
|
44
|
+
if (!raw || raw <= 1) return 1
|
|
45
|
+
return Math.min(Math.max(Math.floor(raw), 1), 20)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Read providers array from node data. Returns the array only when it has 2+
|
|
49
|
+
* entries; one provider is equivalent to single-provider mode. */
|
|
50
|
+
function getEffectiveProviders(nodeData: Record<string, unknown>): readonly string[] | undefined {
|
|
51
|
+
const raw = nodeData.providers as readonly unknown[] | undefined
|
|
52
|
+
if (!raw || raw.length < 2) return undefined
|
|
53
|
+
const cleaned = raw.filter((p): p is string => typeof p === "string" && p.length > 0)
|
|
54
|
+
return cleaned.length >= 2 ? cleaned : undefined
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Expand list items by repeatCount, or create synthetic repeat / provider items.
|
|
59
|
+
*
|
|
60
|
+
* Resolution order:
|
|
61
|
+
* 1. If an upstream list exists, the list drives expansion (repeatCount multiplies).
|
|
62
|
+
* 2. Else if `data.providers` has 2+ entries, emit `providers.length × repeatCount`
|
|
63
|
+
* items — each provider runs `repeatCount` times consecutively.
|
|
64
|
+
* 3. Else if repeatCount > 1, emit `repeatCount` synthetic items.
|
|
65
|
+
* 4. Otherwise return null — single execution, no fan-out.
|
|
66
|
+
*/
|
|
67
|
+
export function expandItemsWithRepeat(
|
|
68
|
+
listItems: string[] | undefined,
|
|
69
|
+
nodeType: string,
|
|
70
|
+
nodeData: Record<string, unknown>,
|
|
71
|
+
): string[] | null {
|
|
72
|
+
const repeatCount = REPEATABLE_NODE_TYPES.has(nodeType)
|
|
73
|
+
? getEffectiveRepeatCount(nodeData)
|
|
74
|
+
: 1
|
|
75
|
+
|
|
76
|
+
if (listItems && listItems.length > 1) {
|
|
77
|
+
const expanded = repeatCount > 1
|
|
78
|
+
? listItems.flatMap(item => Array(repeatCount).fill(item) as string[])
|
|
79
|
+
: listItems
|
|
80
|
+
return expanded
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const providers = getEffectiveProviders(nodeData)
|
|
84
|
+
if (providers) {
|
|
85
|
+
// Cross-product: each provider runs `repeatCount` times. Same provider's
|
|
86
|
+
// iterations are grouped (better for UI progress + caching).
|
|
87
|
+
return providers.flatMap(p =>
|
|
88
|
+
Array(Math.max(repeatCount, 1)).fill(encodeProviderItem(p)) as string[],
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (repeatCount > 1) {
|
|
93
|
+
return Array(repeatCount).fill(REPEAT_PLACEHOLDER) as string[]
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return null
|
|
97
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { injectUpstream } from "./inject-upstream.js"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolve fieldMappings + {} injection for all text fields on a node.
|
|
5
|
+
*
|
|
6
|
+
* Three resolution mechanisms, in precedence order per field:
|
|
7
|
+
* 1. edge source: a live edge into the field's handle → use that node's
|
|
8
|
+
* output. Prefix-agnostic — the caller decides which edges map to which
|
|
9
|
+
* field (e.g. FE/BE wrappers match `field-<key>` handles). Wins over both
|
|
10
|
+
* fieldMappings and {} injection.
|
|
11
|
+
* 2. fieldMappings: field mapped to source node → use that node's output
|
|
12
|
+
* 3. {} injection: manual field contains {} → replace with upstreamText
|
|
13
|
+
*
|
|
14
|
+
* Does NOT inject upstream into empty unmapped fields — that stays in
|
|
15
|
+
* per-node execution code (e.g., d.prompt || inputs.prompt).
|
|
16
|
+
*
|
|
17
|
+
* The `getSourceOutput` callback abstracts how source node output is
|
|
18
|
+
* extracted — frontend reads from live React Flow state, backend reads
|
|
19
|
+
* from NodeExecutionState.output. Same pattern as ancestor-refs.ts.
|
|
20
|
+
*
|
|
21
|
+
* `edgeSourceForField` is optional: when omitted, behaviour is identical to
|
|
22
|
+
* the prior fieldMappings-only resolver (existing callers stay valid).
|
|
23
|
+
*/
|
|
24
|
+
export function resolveFieldMappings(
|
|
25
|
+
data: Record<string, unknown>,
|
|
26
|
+
upstreamText: string | undefined,
|
|
27
|
+
mappableFieldNames: ReadonlyArray<string>,
|
|
28
|
+
getSourceOutput: (sourceNodeId: string) => string | undefined,
|
|
29
|
+
edgeSourceForField?: (field: string) => string | undefined,
|
|
30
|
+
): Record<string, unknown> {
|
|
31
|
+
const fm = data.fieldMappings as Record<string, { sourceNodeId: string }> | undefined
|
|
32
|
+
const resolved = { ...data }
|
|
33
|
+
|
|
34
|
+
for (const field of mappableFieldNames) {
|
|
35
|
+
const sourceNodeId = edgeSourceForField?.(field) ?? fm?.[field]?.sourceNodeId
|
|
36
|
+
|
|
37
|
+
if (sourceNodeId) {
|
|
38
|
+
const output = getSourceOutput(sourceNodeId)
|
|
39
|
+
if (output != null) resolved[field] = output
|
|
40
|
+
} else {
|
|
41
|
+
const current = resolved[field]
|
|
42
|
+
if (typeof current === "string") {
|
|
43
|
+
const injected = injectUpstream(current, upstreamText)
|
|
44
|
+
if (injected !== current) resolved[field] = injected
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return resolved
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Location buckets that may carry generated/uploaded variants. Mirrors the
|
|
54
|
+
* full set of attachable buckets in `entity-prompts.ts::LOCATION_ATTACH_COLUMNS`,
|
|
55
|
+
* but in camelCase (matching the in-memory location object and the
|
|
56
|
+
* `WorkflowExportLocation` export shape).
|
|
57
|
+
*/
|
|
58
|
+
const LOCATION_BUCKETS = [
|
|
59
|
+
"timeOfDay",
|
|
60
|
+
"weather",
|
|
61
|
+
"seasons",
|
|
62
|
+
"angles",
|
|
63
|
+
"lighting",
|
|
64
|
+
"atmosphereMotions",
|
|
65
|
+
] as const
|
|
66
|
+
|
|
67
|
+
interface LocationFieldEntry {
|
|
68
|
+
/** Stable key — `sourceImageUrl` or `<bucket>[<index>]`. */
|
|
69
|
+
key: string
|
|
70
|
+
/** Human-readable label — `Main image` or `<bucket> / <variant.name>`. */
|
|
71
|
+
label: string
|
|
72
|
+
/** R2 URL of the image. */
|
|
73
|
+
url: string
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Flatten a location's anchor image and every variant bucket into a single
|
|
78
|
+
* ordered list of `{ key, label, url }` entries. Used by picker UIs and
|
|
79
|
+
* ref-resolvers that need a stable, position-keyed view of every image
|
|
80
|
+
* attached to a location.
|
|
81
|
+
*
|
|
82
|
+
* Bucket iteration order is fixed (see `LOCATION_BUCKETS`) so frontend and
|
|
83
|
+
* backend produce identical lists from the same fixture. Missing buckets and
|
|
84
|
+
* non-array values are treated as empty — the helper never throws.
|
|
85
|
+
*
|
|
86
|
+
* Mirrors the future character/object variants of this helper; same shape
|
|
87
|
+
* (`key`, `label`, `url`) so callers can be polymorphic over entity kind.
|
|
88
|
+
*/
|
|
89
|
+
export function resolveLocationFields(
|
|
90
|
+
loc: Record<string, unknown>,
|
|
91
|
+
): LocationFieldEntry[] {
|
|
92
|
+
const out: LocationFieldEntry[] = []
|
|
93
|
+
|
|
94
|
+
if (typeof loc.sourceImageUrl === "string" && loc.sourceImageUrl.length > 0) {
|
|
95
|
+
out.push({
|
|
96
|
+
key: "sourceImageUrl",
|
|
97
|
+
label: "Main image",
|
|
98
|
+
url: loc.sourceImageUrl,
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
for (const bucket of LOCATION_BUCKETS) {
|
|
103
|
+
const raw = loc[bucket]
|
|
104
|
+
if (!Array.isArray(raw)) continue
|
|
105
|
+
raw.forEach((item, i) => {
|
|
106
|
+
if (!item || typeof item !== "object") return
|
|
107
|
+
const variant = item as { name?: unknown; url?: unknown }
|
|
108
|
+
if (typeof variant.url !== "string" || variant.url.length === 0) return
|
|
109
|
+
const name = typeof variant.name === "string" ? variant.name : ""
|
|
110
|
+
out.push({
|
|
111
|
+
key: `${bucket}[${i}]`,
|
|
112
|
+
label: `${bucket} / ${name}`,
|
|
113
|
+
url: variant.url,
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return out
|
|
119
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared BFS utility for computing reachable node IDs along a route.
|
|
3
|
+
* Used by both frontend (RunTargetSelector stale guard) and backend
|
|
4
|
+
* (presentation.ts, app-runner.ts, sub-workflow-handler.ts).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export interface MinimalNode {
|
|
8
|
+
id: string
|
|
9
|
+
type?: string
|
|
10
|
+
data: Record<string, unknown>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface MinimalEdge {
|
|
14
|
+
source: string
|
|
15
|
+
target: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* BFS in one direction from a start node.
|
|
20
|
+
*/
|
|
21
|
+
function bfs(
|
|
22
|
+
startId: string,
|
|
23
|
+
edges: readonly MinimalEdge[],
|
|
24
|
+
direction: "forward" | "backward",
|
|
25
|
+
): Set<string> {
|
|
26
|
+
const visited = new Set<string>()
|
|
27
|
+
const queue = [startId]
|
|
28
|
+
|
|
29
|
+
while (queue.length > 0) {
|
|
30
|
+
const current = queue.shift()!
|
|
31
|
+
if (visited.has(current)) continue
|
|
32
|
+
visited.add(current)
|
|
33
|
+
|
|
34
|
+
for (const edge of edges) {
|
|
35
|
+
if (direction === "forward" && edge.source === current && !visited.has(edge.target)) {
|
|
36
|
+
queue.push(edge.target)
|
|
37
|
+
} else if (direction === "backward" && edge.target === current && !visited.has(edge.source)) {
|
|
38
|
+
queue.push(edge.source)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return visited
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Compute the set of node IDs reachable along a route.
|
|
48
|
+
* 1. Finds the sub-workflow-input node with matching routeId
|
|
49
|
+
* 2. Finds the sub-workflow-output node with matching routeId
|
|
50
|
+
* 3. BFS forward from input, BFS backward from output, intersect
|
|
51
|
+
* Returns empty set if input or output node not found (stale routeId).
|
|
52
|
+
*/
|
|
53
|
+
export function getRouteReachableNodeIds(
|
|
54
|
+
nodes: readonly MinimalNode[],
|
|
55
|
+
edges: readonly MinimalEdge[],
|
|
56
|
+
routeId: string,
|
|
57
|
+
): Set<string> {
|
|
58
|
+
const inputNode = nodes.find(
|
|
59
|
+
(n) => n.type === "sub-workflow-input" && (n.data as Record<string, unknown>).routeId === routeId,
|
|
60
|
+
)
|
|
61
|
+
const outputNode = nodes.find(
|
|
62
|
+
(n) => n.type === "sub-workflow-output" && (n.data as Record<string, unknown>).routeId === routeId,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
if (!inputNode || !outputNode) return new Set()
|
|
66
|
+
|
|
67
|
+
const forwardReachable = bfs(inputNode.id, edges, "forward")
|
|
68
|
+
const backwardReachable = bfs(outputNode.id, edges, "backward")
|
|
69
|
+
|
|
70
|
+
const reachable = new Set<string>()
|
|
71
|
+
for (const id of forwardReachable) {
|
|
72
|
+
if (backwardReachable.has(id)) reachable.add(id)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Always include input and output
|
|
76
|
+
reachable.add(inputNode.id)
|
|
77
|
+
reachable.add(outputNode.id)
|
|
78
|
+
|
|
79
|
+
return reachable
|
|
80
|
+
}
|