@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,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in Lottie Overlay catalog — single source of truth.
|
|
3
|
+
*
|
|
4
|
+
* The Lottie Overlay node ships a curated set of 12 animations the overlay LLM
|
|
5
|
+
* can pick from. They were originally served from the third-party lottie.host
|
|
6
|
+
* CDN, which went dead (origin returns 403) and broke every catalog-based
|
|
7
|
+
* overlay render in production. The replacements were authored with our own
|
|
8
|
+
* Lottie engine, baked (slots resolved, no `sid` refs), and are now self-hosted
|
|
9
|
+
* on the Nodaro CDN at `https://cdn.nodaro.ai/lottie-catalog/<slug>.json`.
|
|
10
|
+
*
|
|
11
|
+
* This module is the ONE place the catalog lives:
|
|
12
|
+
* - `LOTTIE_OVERLAY_CATALOG` feeds the overlay system prompt (the LLM's menu).
|
|
13
|
+
* - `LEGACY_LOTTIE_HOST_REMAP` + `resolveLottieOverlaySrc` heal saved overlay
|
|
14
|
+
* plans at render time — a plan authored before the cut-over still points at
|
|
15
|
+
* a dead lottie.host URL, so the renderer rewrites it to its self-hosted
|
|
16
|
+
* replacement before fetching.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export interface LottieOverlayCatalogEntry {
|
|
20
|
+
/** Stable system key — the R2 object is `lottie-catalog/<slug>.json`. */
|
|
21
|
+
readonly slug: string
|
|
22
|
+
/** Display name — mirrors the original prompt's catalog labels. */
|
|
23
|
+
readonly name: string
|
|
24
|
+
/** Catalog group (drives the grouped layout in the system prompt). */
|
|
25
|
+
readonly group:
|
|
26
|
+
| "Celebration"
|
|
27
|
+
| "Social / Reactions"
|
|
28
|
+
| "UI / Indicators"
|
|
29
|
+
| "Ambient / Decorative"
|
|
30
|
+
/** One placement-intent line for the overlay LLM. */
|
|
31
|
+
readonly description: string
|
|
32
|
+
/** Public CDN URL: `https://cdn.nodaro.ai/lottie-catalog/<slug>.json`. */
|
|
33
|
+
readonly url: string
|
|
34
|
+
/** Whether the animation is continuous (loop) or a one-shot effect. */
|
|
35
|
+
readonly loop: boolean
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const CDN_BASE = "https://cdn.nodaro.ai/lottie-catalog"
|
|
39
|
+
|
|
40
|
+
export const LOTTIE_OVERLAY_CATALOG: readonly LottieOverlayCatalogEntry[] = [
|
|
41
|
+
// ── Celebration ────────────────────────────────────────────────────────────
|
|
42
|
+
{
|
|
43
|
+
slug: "confetti-burst",
|
|
44
|
+
name: "Confetti burst",
|
|
45
|
+
group: "Celebration",
|
|
46
|
+
description: "Multicolor confetti shower — large coverage at a celebratory peak; one-shot.",
|
|
47
|
+
url: `${CDN_BASE}/confetti-burst.json`,
|
|
48
|
+
loop: false,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
slug: "fireworks",
|
|
52
|
+
name: "Fireworks",
|
|
53
|
+
group: "Celebration",
|
|
54
|
+
description: "Bursting fireworks against the sky — big-moment payoff over the upper frame; one-shot.",
|
|
55
|
+
url: `${CDN_BASE}/fireworks.json`,
|
|
56
|
+
loop: false,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
slug: "party-popper",
|
|
60
|
+
name: "Party popper",
|
|
61
|
+
group: "Celebration",
|
|
62
|
+
description: "Party popper streamers from a corner — a quick celebratory accent; one-shot.",
|
|
63
|
+
url: `${CDN_BASE}/party-popper.json`,
|
|
64
|
+
loop: false,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
slug: "stars-sparkle",
|
|
68
|
+
name: "Stars sparkle",
|
|
69
|
+
group: "Celebration",
|
|
70
|
+
description: "Twinkling stars/sparkles — small accent over a highlight; loops.",
|
|
71
|
+
url: `${CDN_BASE}/stars-sparkle.json`,
|
|
72
|
+
loop: true,
|
|
73
|
+
},
|
|
74
|
+
// ── Social / Reactions ──────────────────────────────────────────────────────
|
|
75
|
+
{
|
|
76
|
+
slug: "heart-pulse",
|
|
77
|
+
name: "Heart pulse",
|
|
78
|
+
group: "Social / Reactions",
|
|
79
|
+
description: "Pulsing heart reaction — medium size at a corner or edge; loops.",
|
|
80
|
+
url: `${CDN_BASE}/heart-pulse.json`,
|
|
81
|
+
loop: true,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
slug: "thumbs-up",
|
|
85
|
+
name: "Thumbs up",
|
|
86
|
+
group: "Social / Reactions",
|
|
87
|
+
description: "Thumbs-up approval reaction — medium size, pops in once; one-shot.",
|
|
88
|
+
url: `${CDN_BASE}/thumbs-up.json`,
|
|
89
|
+
loop: false,
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
slug: "fire-flame",
|
|
93
|
+
name: "Fire emoji",
|
|
94
|
+
group: "Social / Reactions",
|
|
95
|
+
description: "Flickering flame reaction (“this is fire”) — small size at an edge; loops.",
|
|
96
|
+
url: `${CDN_BASE}/fire-flame.json`,
|
|
97
|
+
loop: true,
|
|
98
|
+
},
|
|
99
|
+
// ── UI / Indicators ─────────────────────────────────────────────────────────
|
|
100
|
+
{
|
|
101
|
+
slug: "loading-spinner",
|
|
102
|
+
name: "Loading spinner",
|
|
103
|
+
group: "UI / Indicators",
|
|
104
|
+
description: "Circular loading spinner — small, centered, signals progress; loops.",
|
|
105
|
+
url: `${CDN_BASE}/loading-spinner.json`,
|
|
106
|
+
loop: true,
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
slug: "checkmark-success",
|
|
110
|
+
name: "Checkmark success",
|
|
111
|
+
group: "UI / Indicators",
|
|
112
|
+
description: "Animated success checkmark — small, marks a completed/correct moment; one-shot.",
|
|
113
|
+
url: `${CDN_BASE}/checkmark-success.json`,
|
|
114
|
+
loop: false,
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
slug: "arrow-pointer",
|
|
118
|
+
name: "Arrow pointer",
|
|
119
|
+
group: "UI / Indicators",
|
|
120
|
+
description: "Animated arrow drawing attention to a spot — small, timed to a key area; loops.",
|
|
121
|
+
url: `${CDN_BASE}/arrow-pointer.json`,
|
|
122
|
+
loop: true,
|
|
123
|
+
},
|
|
124
|
+
// ── Ambient / Decorative ────────────────────────────────────────────────────
|
|
125
|
+
{
|
|
126
|
+
slug: "floating-particles",
|
|
127
|
+
name: "Floating particles",
|
|
128
|
+
group: "Ambient / Decorative",
|
|
129
|
+
description: "Soft drifting particles — large coverage, low opacity, full-duration ambience; loops.",
|
|
130
|
+
url: `${CDN_BASE}/floating-particles.json`,
|
|
131
|
+
loop: true,
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
slug: "glowing-ring",
|
|
135
|
+
name: "Glowing ring",
|
|
136
|
+
group: "Ambient / Decorative",
|
|
137
|
+
description: "Pulsing glowing ring/halo — decorative accent around a focal point; loops.",
|
|
138
|
+
url: `${CDN_BASE}/glowing-ring.json`,
|
|
139
|
+
loop: true,
|
|
140
|
+
},
|
|
141
|
+
] as const
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Dead lottie.host URLs (origin returns 403) → their replacement catalog URLs.
|
|
145
|
+
* Heals saved plans at render time. The keys are copied EXACTLY from the
|
|
146
|
+
* original `lottie-overlay-system.ts` prompt — they are the literal `src`
|
|
147
|
+
* strings the overlay LLM emitted before the cut-over.
|
|
148
|
+
*/
|
|
149
|
+
export const LEGACY_LOTTIE_HOST_REMAP: Readonly<Record<string, string>> = {
|
|
150
|
+
// Celebration
|
|
151
|
+
"https://lottie.host/d7313e87-e4c9-4e0d-8e03-c3a59e87d8fb/TjHnrCGBjI.json": `${CDN_BASE}/confetti-burst.json`,
|
|
152
|
+
"https://lottie.host/d5cad0dd-4e93-4bbe-b023-e94a04bc1581/JHEZMrqfMk.json": `${CDN_BASE}/fireworks.json`,
|
|
153
|
+
"https://lottie.host/0060c9cd-75da-42d5-af7c-1a191fa8a8fd/c1xHMRnGTO.json": `${CDN_BASE}/party-popper.json`,
|
|
154
|
+
"https://lottie.host/c04a2758-a1d9-40a9-b81f-6f3e4e13a88c/xKCYDU2w0O.json": `${CDN_BASE}/stars-sparkle.json`,
|
|
155
|
+
// Social / Reactions
|
|
156
|
+
"https://lottie.host/44c9e8d1-856c-4641-bfbe-d0e2a5c9850e/GIBsMSIkkq.json": `${CDN_BASE}/heart-pulse.json`,
|
|
157
|
+
"https://lottie.host/9a611d56-1f35-4f51-9fa4-6a4daa6b8714/EH71MjHKPD.json": `${CDN_BASE}/thumbs-up.json`,
|
|
158
|
+
"https://lottie.host/66db1de9-c1a8-4d0b-bb03-47a8932a8a86/q5JBGQ8fxu.json": `${CDN_BASE}/fire-flame.json`,
|
|
159
|
+
// UI / Indicators
|
|
160
|
+
"https://lottie.host/b03d748c-3b4a-4c07-a10c-e9eb3c967349/eMVAVEnb5x.json": `${CDN_BASE}/loading-spinner.json`,
|
|
161
|
+
"https://lottie.host/3ffaab4a-58b0-4a72-9f1c-5eaa484d8c88/g27v7IPaJc.json": `${CDN_BASE}/checkmark-success.json`,
|
|
162
|
+
"https://lottie.host/6f831c6e-693a-4d1d-90a0-d7e2b3f00e68/PFj0MwSPrj.json": `${CDN_BASE}/arrow-pointer.json`,
|
|
163
|
+
// Ambient / Decorative
|
|
164
|
+
"https://lottie.host/9c8e1aef-f8e5-4ce8-bc80-1647ffb0724d/mNDClfKJVB.json": `${CDN_BASE}/floating-particles.json`,
|
|
165
|
+
"https://lottie.host/b5d3e7e7-40bc-44fa-9a53-78b98ad66e80/pQVdNsVDmQ.json": `${CDN_BASE}/glowing-ring.json`,
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Resolve an overlay `src` through the legacy remap: a dead lottie.host URL is
|
|
170
|
+
* rewritten to its self-hosted replacement; everything else (already-migrated
|
|
171
|
+
* catalog URLs, user-provided assets) passes through unchanged.
|
|
172
|
+
*/
|
|
173
|
+
export function resolveLottieOverlaySrc(src: string): string {
|
|
174
|
+
return LEGACY_LOTTIE_HOST_REMAP[src] ?? src
|
|
175
|
+
}
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lottie slot substitution — single source of truth (design §5).
|
|
3
|
+
*
|
|
4
|
+
* A slotted property is an object containing a `sid` key (canonically exactly
|
|
5
|
+
* `{"sid": "name"}`; tolerantly also the annotation form `{a, k, sid}`). The
|
|
6
|
+
* slot manifest maps sid → { p: <whatever belongs at the reference position> }.
|
|
7
|
+
* Overrides map sid → raw value (what UI controls write).
|
|
8
|
+
*
|
|
9
|
+
* KEY CONVENTION: a slot's `p` is, by design, EXACTLY what belongs at the
|
|
10
|
+
* reference position — and we substitute it VERBATIM, never auto-wrapping it in
|
|
11
|
+
* an `{a:0,k:...}` envelope. At a property position (a fill color, a shape size)
|
|
12
|
+
* that means `p` is a property object like `{"a":0,"k":[1,0,0,1]}`. At a RAW
|
|
13
|
+
* position inside a text document — `layers[].t.d.k[0].s.t`, where lottie-web's
|
|
14
|
+
* `buildFinalText` iterates string characters — `p` is a BARE string, e.g.
|
|
15
|
+
* `{ "nameText": { "p": "John Smith" } }` substitutes the string `"John Smith"`
|
|
16
|
+
* straight onto `s.t`. (Auto-wrapping there produced `{a:0,k:"John Smith"}` and
|
|
17
|
+
* broke text rendering — the defect this contract fixes.)
|
|
18
|
+
*
|
|
19
|
+
* An override is wrapped ONLY when it lands on a property-object default: the
|
|
20
|
+
* `{...p, k: override}` form preserves the default's envelope (animated/static
|
|
21
|
+
* flags). On a raw default (or a missing slot) the override is substituted
|
|
22
|
+
* verbatim too — so a raw text override stays a bare string.
|
|
23
|
+
*
|
|
24
|
+
* Substitution is renderer-agnostic: we replace every sid node ourselves and
|
|
25
|
+
* never rely on lottie-web's version-dependent native slot support.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
type JsonRecord = Record<string, unknown>
|
|
29
|
+
|
|
30
|
+
function isPlainObject(v: unknown): v is JsonRecord {
|
|
31
|
+
return typeof v === "object" && v !== null && !Array.isArray(v)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** True when `p` already looks like a lottie animated-property object. */
|
|
35
|
+
function isPropertyObject(v: unknown): v is JsonRecord {
|
|
36
|
+
return isPlainObject(v) && "k" in v
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function resolveSlotNode(
|
|
40
|
+
node: JsonRecord,
|
|
41
|
+
slots: JsonRecord,
|
|
42
|
+
overrides: JsonRecord,
|
|
43
|
+
): unknown {
|
|
44
|
+
const sid = node.sid as string
|
|
45
|
+
const slot = slots[sid]
|
|
46
|
+
const slotP = isPlainObject(slot) ? (slot as JsonRecord).p : undefined
|
|
47
|
+
const override = overrides[sid]
|
|
48
|
+
|
|
49
|
+
if (override !== undefined) {
|
|
50
|
+
// Wrap into the default's property-object envelope when the default IS one
|
|
51
|
+
// (preserves animated/static flags); otherwise substitute the raw override
|
|
52
|
+
// verbatim — a raw text override must stay a bare string at `s.t`.
|
|
53
|
+
if (isPropertyObject(slotP)) return { ...slotP, k: structuredClone(override) }
|
|
54
|
+
return structuredClone(override)
|
|
55
|
+
}
|
|
56
|
+
if (slotP !== undefined) {
|
|
57
|
+
// `p` is by convention exactly what belongs at the reference position —
|
|
58
|
+
// substitute it verbatim, never auto-wrap (a bare string stays a string).
|
|
59
|
+
return structuredClone(slotP)
|
|
60
|
+
}
|
|
61
|
+
// No slot, no override — leave the node as-is (validator rule #6 should
|
|
62
|
+
// prevent this; belt-and-braces for hand-fed documents).
|
|
63
|
+
return node
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function walk(value: unknown, slots: JsonRecord, overrides: JsonRecord): unknown {
|
|
67
|
+
if (Array.isArray(value)) {
|
|
68
|
+
return value.map((item) => walk(item, slots, overrides))
|
|
69
|
+
}
|
|
70
|
+
if (isPlainObject(value)) {
|
|
71
|
+
if (typeof value.sid === "string") {
|
|
72
|
+
const resolved = resolveSlotNode(value, slots, overrides)
|
|
73
|
+
// The original node comes back only in the missing-slot case; replacements
|
|
74
|
+
// are leaf property objects and need no further walking.
|
|
75
|
+
if (resolved === value) {
|
|
76
|
+
const copy: JsonRecord = {}
|
|
77
|
+
for (const [k, v] of Object.entries(value)) copy[k] = walk(v, slots, overrides)
|
|
78
|
+
return copy
|
|
79
|
+
}
|
|
80
|
+
return resolved
|
|
81
|
+
}
|
|
82
|
+
const copy: JsonRecord = {}
|
|
83
|
+
for (const [k, v] of Object.entries(value)) copy[k] = walk(v, slots, overrides)
|
|
84
|
+
return copy
|
|
85
|
+
}
|
|
86
|
+
return value
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Pure: returns a new document; never mutates inputs. */
|
|
90
|
+
export function applySlots(
|
|
91
|
+
lottie: JsonRecord,
|
|
92
|
+
slots: JsonRecord | undefined,
|
|
93
|
+
overrides: JsonRecord | undefined,
|
|
94
|
+
): JsonRecord {
|
|
95
|
+
return walk(lottie, slots ?? {}, overrides ?? {}) as JsonRecord
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ── Playback normalization ───────────────────────────────────────────────────
|
|
99
|
+
//
|
|
100
|
+
// lottie-web computes a layer's local time as `frame - layer.st` and gates the
|
|
101
|
+
// layer on `local >= ip && local < op`. A layer missing `st` yields NaN, fails
|
|
102
|
+
// the gate, and stays `display:none` forever — the document "loads" (DOMLoaded
|
|
103
|
+
// fires) but every frame renders blank (prod incident 2026-06-12: all authored
|
|
104
|
+
// lottie renders came out as empty frames in headless Chrome). `st` and `sr`
|
|
105
|
+
// are spec-optional with defaults, so documents routinely omit them; complete
|
|
106
|
+
// them at the playback boundary so any source — authored plan, baked export,
|
|
107
|
+
// catalog asset, external URL — renders. Mutates `doc` in place and returns it
|
|
108
|
+
// (callers pass freshly fetched or freshly copied documents).
|
|
109
|
+
|
|
110
|
+
export function normalizeLottieLayers<T>(doc: T): T {
|
|
111
|
+
if (!isPlainObject(doc)) return doc
|
|
112
|
+
const fix = (layers: unknown): void => {
|
|
113
|
+
if (!Array.isArray(layers)) return
|
|
114
|
+
for (const layer of layers) {
|
|
115
|
+
if (!isPlainObject(layer)) continue
|
|
116
|
+
if (typeof layer.st !== "number") layer.st = 0
|
|
117
|
+
if (typeof layer.sr !== "number") layer.sr = 1
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
fix((doc as JsonRecord).layers)
|
|
121
|
+
const assets = (doc as JsonRecord).assets
|
|
122
|
+
if (Array.isArray(assets)) {
|
|
123
|
+
for (const asset of assets) {
|
|
124
|
+
if (isPlainObject(asset)) fix(asset.layers)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return doc
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// ── Slot control descriptors (Phase 2 — UI mapping) ──────────────────────────
|
|
131
|
+
//
|
|
132
|
+
// A slot manifest entry is `{ p: <whatever belongs at the reference position> }`
|
|
133
|
+
// (Amendment 1). `describeSlotControl` unwraps that envelope to the editable raw
|
|
134
|
+
// value and classifies it into the control kind the config panel should render.
|
|
135
|
+
// `p` is either a property object `{a, k}` (colors, sizes, scalars) whose `k`
|
|
136
|
+
// holds the value, or a bare raw value (text strings live unwrapped at `s.t`).
|
|
137
|
+
|
|
138
|
+
export type SlotControlKind = "color" | "text" | "number" | "point"
|
|
139
|
+
export interface SlotControlDescriptor {
|
|
140
|
+
kind: SlotControlKind
|
|
141
|
+
value: unknown
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Unwraps a slot entry to its editable raw value and classifies it:
|
|
146
|
+
* {p:{a:0,k:[1,0,0,1]}} → { kind:"color", value:[1,0,0,1] }
|
|
147
|
+
* {p:"John"} → { kind:"text", value:"John" }
|
|
148
|
+
* {p:{a:0,k:42}} → { kind:"number", value:42 }
|
|
149
|
+
* {p:{a:0,k:[10,20]}} → { kind:"point", value:[10,20] }
|
|
150
|
+
* Animated property objects (`a:1`) and anything that doesn't map to a known
|
|
151
|
+
* control kind return null (no editable control).
|
|
152
|
+
*/
|
|
153
|
+
export function describeSlotControl(slot: unknown): SlotControlDescriptor | null {
|
|
154
|
+
if (!isPlainObject(slot)) return null
|
|
155
|
+
const p = (slot as JsonRecord).p
|
|
156
|
+
let value: unknown = p
|
|
157
|
+
if (isPropertyObject(p)) {
|
|
158
|
+
if ((p as JsonRecord).a === 1) return null
|
|
159
|
+
value = (p as JsonRecord).k
|
|
160
|
+
}
|
|
161
|
+
if (typeof value === "string") return { kind: "text", value }
|
|
162
|
+
if (typeof value === "number") return { kind: "number", value }
|
|
163
|
+
if (
|
|
164
|
+
Array.isArray(value) &&
|
|
165
|
+
value.length === 4 &&
|
|
166
|
+
value.every((n) => typeof n === "number" && n >= 0 && n <= 1)
|
|
167
|
+
) {
|
|
168
|
+
return { kind: "color", value }
|
|
169
|
+
}
|
|
170
|
+
if (Array.isArray(value) && value.length === 2 && value.every((n) => typeof n === "number")) {
|
|
171
|
+
return { kind: "point", value }
|
|
172
|
+
}
|
|
173
|
+
return null
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function clamp01(n: number): number {
|
|
177
|
+
if (Number.isNaN(n)) return 0
|
|
178
|
+
return n < 0 ? 0 : n > 1 ? 1 : n
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function toHexByte(component: number): string {
|
|
182
|
+
return Math.round(clamp01(component) * 255)
|
|
183
|
+
.toString(16)
|
|
184
|
+
.padStart(2, "0")
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* RGBA array (components 0..1) → hex string. The alpha component is omitted
|
|
189
|
+
* when it is exactly 1 (`[1,0,0,1]` → `"#ff0000"`); otherwise an 8-digit hex is
|
|
190
|
+
* emitted (`[0,1,0,0.5]` → `"#00ff0080"`). Output is always lowercase.
|
|
191
|
+
*/
|
|
192
|
+
export function rgbaArrayToHex(rgba: number[]): string {
|
|
193
|
+
const [r = 0, g = 0, b = 0, a = 1] = rgba
|
|
194
|
+
const base = `#${toHexByte(r)}${toHexByte(g)}${toHexByte(b)}`
|
|
195
|
+
return a >= 1 ? base : `${base}${toHexByte(a)}`
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Hex string → RGBA array (components 0..1). Accepts `#rgb`, `#rrggbb`, and
|
|
200
|
+
* `#rrggbbaa`; alpha defaults to 1 when absent. Leading `#` is optional.
|
|
201
|
+
*/
|
|
202
|
+
export function hexToRgbaArray(hex: string): number[] {
|
|
203
|
+
let h = hex.trim().replace(/^#/, "")
|
|
204
|
+
if (h.length === 3) {
|
|
205
|
+
h = h
|
|
206
|
+
.split("")
|
|
207
|
+
.map((c) => c + c)
|
|
208
|
+
.join("")
|
|
209
|
+
}
|
|
210
|
+
const r = parseInt(h.slice(0, 2), 16) / 255
|
|
211
|
+
const g = parseInt(h.slice(2, 4), 16) / 255
|
|
212
|
+
const b = parseInt(h.slice(4, 6), 16) / 255
|
|
213
|
+
const a = h.length >= 8 ? parseInt(h.slice(6, 8), 16) / 255 : 1
|
|
214
|
+
return [r, g, b, a]
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** Manifest sids in insertion order (drives the slot-control list ordering). */
|
|
218
|
+
export function listSlotSids(slots: Record<string, unknown>): string[] {
|
|
219
|
+
return Object.keys(slots ?? {})
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// ── Slot → app-field derivation (Phase 3 — single source of truth) ────────────
|
|
223
|
+
//
|
|
224
|
+
// `deriveLottieSlotFields` turns a lottie-graphic plan's slot manifest into
|
|
225
|
+
// ExposableField-shaped descriptors. ONE function feeds three surfaces: the
|
|
226
|
+
// editor's publish picker, the published-app runtime, and the backend MCP
|
|
227
|
+
// schema extractor — so the set of slots an app exposes can never drift between
|
|
228
|
+
// them. It deliberately mirrors `describeSlotControl`'s classification (the
|
|
229
|
+
// editor's live slot controls use the same source of truth).
|
|
230
|
+
|
|
231
|
+
/** Prefix for the synthetic field key of a derived slot field: `slot:<sid>`. */
|
|
232
|
+
export const LOTTIE_SLOT_FIELD_PREFIX = "slot:"
|
|
233
|
+
|
|
234
|
+
/** "primaryColor" → "Primary Color"; "bar_size" → "Bar Size". */
|
|
235
|
+
export function humanizeSlotSid(sid: string): string {
|
|
236
|
+
return sid
|
|
237
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
238
|
+
.replace(/[_-]+/g, " ")
|
|
239
|
+
.replace(/\s+/g, " ")
|
|
240
|
+
.trim()
|
|
241
|
+
.replace(/\b\w/g, (c) => c.toUpperCase())
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/** ExposableField-shaped descriptor derived from one slot. */
|
|
245
|
+
export interface LottieSlotField {
|
|
246
|
+
/** Synthetic field key: `slot:<sid>`. */
|
|
247
|
+
key: string
|
|
248
|
+
/** Humanized sid (camelCase / snake_case → Title Case). */
|
|
249
|
+
label: string
|
|
250
|
+
/** Maps onto the `ExposableField.type` members used in apps. */
|
|
251
|
+
type: "color" | "text" | "slider"
|
|
252
|
+
min?: number
|
|
253
|
+
max?: number
|
|
254
|
+
step?: number
|
|
255
|
+
/** Hex string for color; raw value for text/number. */
|
|
256
|
+
defaultValue?: unknown
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Derive ExposableField-shaped descriptors from a motion-graphics node's plan.
|
|
261
|
+
*
|
|
262
|
+
* Returns [] unless `motionPlan.planType === "lottie-graphic"` and `slots` is a
|
|
263
|
+
* non-empty object — the elements engine and absent plans expose nothing.
|
|
264
|
+
*
|
|
265
|
+
* Per slot, via `describeSlotControl`:
|
|
266
|
+
* - color → `{ type: "color", defaultValue: rgbaArrayToHex(value) }`
|
|
267
|
+
* - text → `{ type: "text", defaultValue: value }`
|
|
268
|
+
* - number → `{ type: "slider", min, max, step, defaultValue: value }`
|
|
269
|
+
* (0–1 values → 0..1 step 0.01; larger → 0..ceil(value*2) step 1)
|
|
270
|
+
* - point / null → SKIPPED. Point-kind slots are intentionally not exposed in
|
|
271
|
+
* apps (no paired-number card; positions are rarely end-user-meaningful).
|
|
272
|
+
*/
|
|
273
|
+
export function deriveLottieSlotFields(
|
|
274
|
+
motionPlan: Record<string, unknown> | undefined,
|
|
275
|
+
): LottieSlotField[] {
|
|
276
|
+
if (!motionPlan || motionPlan.planType !== "lottie-graphic") return []
|
|
277
|
+
const slots = motionPlan.slots
|
|
278
|
+
if (!isPlainObject(slots)) return []
|
|
279
|
+
|
|
280
|
+
const fields: LottieSlotField[] = []
|
|
281
|
+
for (const [sid, slot] of Object.entries(slots)) {
|
|
282
|
+
const control = describeSlotControl(slot)
|
|
283
|
+
if (!control) continue
|
|
284
|
+
const base = { key: `${LOTTIE_SLOT_FIELD_PREFIX}${sid}`, label: humanizeSlotSid(sid) }
|
|
285
|
+
|
|
286
|
+
if (control.kind === "color") {
|
|
287
|
+
fields.push({
|
|
288
|
+
...base,
|
|
289
|
+
type: "color",
|
|
290
|
+
defaultValue: rgbaArrayToHex(control.value as number[]),
|
|
291
|
+
})
|
|
292
|
+
} else if (control.kind === "text") {
|
|
293
|
+
fields.push({ ...base, type: "text", defaultValue: control.value })
|
|
294
|
+
} else if (control.kind === "number") {
|
|
295
|
+
const value = Number(control.value)
|
|
296
|
+
const isUnit = value <= 1
|
|
297
|
+
fields.push({
|
|
298
|
+
...base,
|
|
299
|
+
type: "slider",
|
|
300
|
+
min: 0,
|
|
301
|
+
max: isUnit ? 1 : Math.ceil(value * 2) || 100,
|
|
302
|
+
step: isUnit ? 0.01 : 1,
|
|
303
|
+
defaultValue: control.value,
|
|
304
|
+
})
|
|
305
|
+
}
|
|
306
|
+
// point / unrecognized kinds are intentionally not exposed.
|
|
307
|
+
}
|
|
308
|
+
return fields
|
|
309
|
+
}
|