@nodaro/shared 2.10.0 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +132 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +158 -1
- package/dist/index.d.ts +158 -1
- package/dist/index.js +121 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/catalog-projection.test.ts +14 -0
- package/src/__tests__/default-video-provider.test.ts +1 -1
- package/src/__tests__/pack-sidecar-localization.test.ts +21 -0
- package/src/__tests__/parameter-node-value.test.ts +18 -1
- package/src/__tests__/resolve-pipeline-model.test.ts +4 -4
- package/src/animals.ts +10 -0
- package/src/catalog-projection.ts +48 -0
- package/src/entity-node-fields.ts +147 -0
- package/src/furniture.ts +10 -0
- package/src/i18n/index.ts +33 -3
- package/src/i18n/transitions.ar.ts +6 -0
- package/src/i18n/transitions.de.ts +6 -0
- package/src/i18n/transitions.es.ts +6 -0
- package/src/i18n/transitions.fr.ts +6 -0
- package/src/i18n/transitions.he.ts +6 -0
- package/src/i18n/transitions.hi.ts +6 -0
- package/src/i18n/transitions.ja.ts +6 -0
- package/src/i18n/transitions.ko.ts +6 -0
- package/src/i18n/transitions.pt-BR.ts +6 -0
- package/src/i18n/transitions.ru.ts +6 -0
- package/src/i18n/transitions.zh-CN.ts +6 -0
- package/src/index.ts +19 -0
- package/src/parameter-node-value.ts +23 -3
- package/src/producer-types.ts +4 -0
- package/src/vehicles.ts +11 -1
- package/src/weapons.ts +11 -1
|
@@ -7,12 +7,15 @@ const map: LocaleCatalogMap = {
|
|
|
7
7
|
"cross-dissolve": { label: "クロスディゾルブ", description: "ショット間の緩やかなブレンド" },
|
|
8
8
|
"fade-to-black": { label: "暗転", description: "暗転後、次のシーンが浮かび上がる" },
|
|
9
9
|
"fade-to-white": { label: "ホワイトアウト", description: "白飛び後、次のシーンが現れる" },
|
|
10
|
+
"snap-to-black": { label: "黒への瞬間カット", description: "一瞬で真っ黒になり、間を置いて次のショットへ" },
|
|
10
11
|
"match-cut": { label: "マッチカット", description: "形や動きを合わせたカット" },
|
|
11
12
|
"smash-cut": { label: "スマッシュカット", description: "対照的なシーン間の衝撃的な急転" },
|
|
12
13
|
"iris": { label: "アイリス", description: "円形のアイリスが閉じ、次のシーンで開く" },
|
|
13
14
|
"wipe": { label: "ワイプ", description: "直線的なワイプで次のシーンへ" },
|
|
14
15
|
"roll-transition": { label: "ロール", description: "フレームが90〜180°回転して次のシーンへ" },
|
|
15
16
|
"seamless-match": { label: "シームレスカット", description: "動きと色で隠された完全なシームレスカット" },
|
|
17
|
+
"whip-pan": { label: "ホイップパン", description: "カメラが横に振り切れてブレ、次のショットも同じ方向に流れる" },
|
|
18
|
+
"jump-cut": { label: "ジャンプカット", description: "同じ画角のまま時間が前に飛ぶ" },
|
|
16
19
|
|
|
17
20
|
// ── Time ──
|
|
18
21
|
"fast-forward-day-night": { label: "日中→夜 早送り", description: "同じ場面の昼から夜へのタイムラプス" },
|
|
@@ -62,6 +65,8 @@ const map: LocaleCatalogMap = {
|
|
|
62
65
|
"zoom-into-mouth": { label: "口へのズーム", description: "開いた口へ接近し、内側に新しい世界が" },
|
|
63
66
|
"push-through-glass": { label: "ガラスをすり抜ける", description: "ガラス面をカメラが屈折しながら通り抜ける" },
|
|
64
67
|
"soul-jump": { label: "魂の跳躍", description: "半透明の魂が体を出て新しい体へ入る" },
|
|
68
|
+
"mask-transition": { label: "マスクトランジション", description: "手前の物体が画面を覆い、その暗闇をカメラが抜けて新しい場面へ" },
|
|
69
|
+
"zoom-through": { label: "ズームスルー", description: "細部を拡大し続け、その中から新しい場面が広がる" },
|
|
65
70
|
|
|
66
71
|
// ── Physics ──
|
|
67
72
|
"explosion-blast": { label: "爆発", description: "爆発がフレームを吹き飛ばし、新シーンへ" },
|
|
@@ -73,6 +78,7 @@ const map: LocaleCatalogMap = {
|
|
|
73
78
|
"vehicle-explosion": { label: "車両爆発", description: "前景の車両が爆発し、煙が晴れると新シーン" },
|
|
74
79
|
"jump-match": { label: "ジャンプマッチ", description: "被写体が跳び、着地が新しいシーンに合致" },
|
|
75
80
|
"hand-swipe": { label: "手のスワイプ", description: "手がレンズを横切り、遮蔽中にシーン転換" },
|
|
81
|
+
"action-relay": { label: "アクションつなぎ", description: "動作の途中でフレームから出て、新しい場面で同じ動きを続ける" },
|
|
76
82
|
|
|
77
83
|
// ── Light ──
|
|
78
84
|
"white-flash": { label: "ホワイトフラッシュ", description: "フレームが純白に膨らむ" },
|
|
@@ -7,12 +7,15 @@ const map: LocaleCatalogMap = {
|
|
|
7
7
|
"cross-dissolve": { label: "크로스 디졸브", description: "샷 간의 점진적인 블렌드" },
|
|
8
8
|
"fade-to-black": { label: "페이드 투 블랙", description: "화면이 어두워지고 두 번째 장면이 등장" },
|
|
9
9
|
"fade-to-white": { label: "페이드 투 화이트", description: "화면이 밝아지고 두 번째 장면이 등장" },
|
|
10
|
+
"snap-to-black": { label: "블랙 스냅 컷", description: "즉시 완전한 검은 화면으로 끊었다가 다음 샷으로 전환" },
|
|
10
11
|
"match-cut": { label: "매치 컷", description: "샷 간 형태나 동작의 시각적 운율" },
|
|
11
12
|
"smash-cut": { label: "스매시 컷", description: "대조적인 샷 사이의 충격적인 급전환" },
|
|
12
13
|
"iris": { label: "아이리스", description: "원형 조리개가 닫히고 두 번째 장면에서 열림" },
|
|
13
14
|
"wipe": { label: "와이프", description: "직선 와이프로 첫 번째 샷을 대체" },
|
|
14
15
|
"roll-transition": { label: "롤", description: "프레임이 90–180° 회전 후 두 번째 샷이 안정됨" },
|
|
15
16
|
"seamless-match": { label: "심리스 매치", description: "동작과 색상으로 위장한 보이지 않는 컷" },
|
|
17
|
+
"whip-pan": { label: "휩 팬", description: "카메라가 옆으로 휘몰아치며 흐려지고 다음 샷도 같은 방향으로 이어짐" },
|
|
18
|
+
"jump-cut": { label: "점프 컷", description: "같은 프레이밍에서 시간만 앞으로 건너뜀" },
|
|
16
19
|
|
|
17
20
|
// ── Time ──
|
|
18
21
|
"fast-forward-day-night": { label: "낮→밤 타임랩스", description: "같은 장면에서 낮에서 밤으로의 타임랩스" },
|
|
@@ -62,6 +65,8 @@ const map: LocaleCatalogMap = {
|
|
|
62
65
|
"zoom-into-mouth": { label: "입 속으로 줌", description: "열린 입 속으로 밀어 들어가 새 세계로" },
|
|
63
66
|
"push-through-glass": { label: "유리를 통과", description: "카메라가 유리 면을 굴절하며 통과해 새 세계로" },
|
|
64
67
|
"soul-jump": { label: "영혼 점프", description: "반투명한 영혼이 몸을 떠나 새 몸으로 들어감" },
|
|
68
|
+
"mask-transition": { label: "마스크 트랜지션", description: "전경의 물체가 화면을 가리고 카메라가 그 어둠을 통과함" },
|
|
69
|
+
"zoom-through": { label: "줌 스루", description: "카메라가 한 디테일을 확대해 그 안에서 새 장면이 펼쳐짐" },
|
|
65
70
|
|
|
66
71
|
// ── Physics ──
|
|
67
72
|
"explosion-blast": { label: "폭발", description: "폭발이 화면을 쓸어내고 새 장면이 드러남" },
|
|
@@ -73,6 +78,7 @@ const map: LocaleCatalogMap = {
|
|
|
73
78
|
"vehicle-explosion": { label: "차량 폭발", description: "전경의 차량이 폭발하고 연기 걷히면 새 장면" },
|
|
74
79
|
"jump-match": { label: "점프 매치", description: "피사체가 점프하고 착지가 새 장면과 연결" },
|
|
75
80
|
"hand-swipe": { label: "손 스와이프", description: "손이 렌즈를 가리는 사이 장면이 전환됨" },
|
|
81
|
+
"action-relay": { label: "액션 매치 컷", description: "피사체가 동작 중 프레임을 벗어나 새 장면에서 그 동작을 이어감" },
|
|
76
82
|
|
|
77
83
|
// ── Light ──
|
|
78
84
|
"white-flash": { label: "화이트 플래시", description: "화면이 순백으로 빛남" },
|
|
@@ -7,12 +7,15 @@ const map: LocaleCatalogMap = {
|
|
|
7
7
|
"cross-dissolve": { label: "Fusão Cruzada", description: "Mistura gradual entre cenas" },
|
|
8
8
|
"fade-to-black": { label: "Fade para Preto", description: "Escurece ao preto, segunda cena emerge" },
|
|
9
9
|
"fade-to-white": { label: "Fade para Branco", description: "Clareia ao branco, segunda cena emerge" },
|
|
10
|
+
"snap-to-black": { label: "Corte Seco para Preto", description: "Corte instantâneo ao preto por um instante, depois a próxima cena" },
|
|
10
11
|
"match-cut": { label: "Corte de Raccord", description: "Correspondência de forma ou movimento entre cenas" },
|
|
11
12
|
"smash-cut": { label: "Corte Brusco", description: "Corte abrupto entre cenas visualmente contrastantes" },
|
|
12
13
|
"iris": { label: "Íris", description: "Íris circular fecha e abre na segunda cena" },
|
|
13
14
|
"wipe": { label: "Varredura", description: "Varredura linear substitui a primeira cena" },
|
|
14
15
|
"roll-transition": { label: "Rolagem", description: "Quadro gira 90–180°, segunda cena estável" },
|
|
15
16
|
"seamless-match": { label: "Corte Invisível", description: "Corte oculto disfarçado por movimento e cor" },
|
|
17
|
+
"whip-pan": { label: "Chicote de Câmera", description: "Câmera varre de lado com borrão, a próxima cena segue a mesma direção" },
|
|
18
|
+
"jump-cut": { label: "Jump Cut", description: "Mesmo enquadramento, o tempo salta adiante" },
|
|
16
19
|
|
|
17
20
|
// ── Time ──
|
|
18
21
|
"fast-forward-day-night": { label: "Dia → Noite (Time-lapse)", description: "Time-lapse do dia para a noite na mesma cena" },
|
|
@@ -62,6 +65,8 @@ const map: LocaleCatalogMap = {
|
|
|
62
65
|
"zoom-into-mouth": { label: "Zoom na Boca", description: "Push na boca aberta, emerge em novo mundo" },
|
|
63
66
|
"push-through-glass": { label: "Atravessar o Vidro", description: "Câmera atravessa vidro com refração para nova cena" },
|
|
64
67
|
"soul-jump": { label: "Salto de Alma", description: "Alma translúcida sai do corpo, entra em novo corpo" },
|
|
68
|
+
"mask-transition": { label: "Transição de Máscara", description: "Objeto em primeiro plano cobre o quadro, câmera atravessa o escuro" },
|
|
69
|
+
"zoom-through": { label: "Zoom Atravessado", description: "Câmera amplia um detalhe até a nova cena surgir dentro dele" },
|
|
65
70
|
|
|
66
71
|
// ── Physics ──
|
|
67
72
|
"explosion-blast": { label: "Explosão", description: "Explosão limpa o quadro, nova cena emerge" },
|
|
@@ -73,6 +78,7 @@ const map: LocaleCatalogMap = {
|
|
|
73
78
|
"vehicle-explosion": { label: "Explosão de Veículo", description: "Veículo explode em primeiro plano, cena muda" },
|
|
74
79
|
"jump-match": { label: "Salto Combinado", description: "Sujeito pula, aterrissagem combina com nova cena" },
|
|
75
80
|
"hand-swipe": { label: "Varredura de Mão", description: "Mão passa pela lente, cena muda durante a oclusão" },
|
|
81
|
+
"action-relay": { label: "Corte na Ação", description: "Sujeito sai de quadro numa ação e continua o movimento na nova cena" },
|
|
76
82
|
|
|
77
83
|
// ── Light ──
|
|
78
84
|
"white-flash": { label: "Flash Branco", description: "Quadro clareia ao branco" },
|
|
@@ -7,12 +7,15 @@ const map: LocaleCatalogMap = {
|
|
|
7
7
|
"cross-dissolve": { label: "Перекрёстный наплыв", description: "Плавное смешение двух сцен" },
|
|
8
8
|
"fade-to-black": { label: "Затемнение", description: "Постепенное затемнение, затем новая сцена" },
|
|
9
9
|
"fade-to-white": { label: "Засветка", description: "Осветление до белого, затем новая сцена" },
|
|
10
|
+
"snap-to-black": { label: "Резкий уход в чёрное", description: "Мгновенный переход в чёрное на удар, затем следующий кадр" },
|
|
10
11
|
"match-cut": { label: "Монтаж по форме", description: "Совпадение формы или движения между сценами" },
|
|
11
12
|
"smash-cut": { label: "Резкий монтаж", description: "Резкий переход между контрастными сценами" },
|
|
12
13
|
"iris": { label: "Ирис", description: "Круг закрывается, затем открывается на новой сцене" },
|
|
13
14
|
"wipe": { label: "Шторка", description: "Линия пересекает кадр, открывая новую сцену" },
|
|
14
15
|
"roll-transition": { label: "Прокрутка", description: "Кадр вращается на 90-180°, останавливаясь на новой сцене" },
|
|
15
16
|
"seamless-match": { label: "Незаметный переход", description: "Скрытый монтаж, замаскированный движением и цветом" },
|
|
17
|
+
"whip-pan": { label: "Резкая панорама", description: "Камера резко уходит вбок в смазе, новый кадр движется в ту же сторону" },
|
|
18
|
+
"jump-cut": { label: "Джамп-кат", description: "Та же крупность, время скачком уходит вперёд" },
|
|
16
19
|
|
|
17
20
|
// ── Time ──
|
|
18
21
|
"fast-forward-day-night": { label: "Ускорение (день → ночь)", description: "Тайм-лапс от дня к ночи в той же сцене" },
|
|
@@ -62,6 +65,8 @@ const map: LocaleCatalogMap = {
|
|
|
62
65
|
"zoom-into-mouth": { label: "Зум в рот", description: "Камера входит в рот и оказывается в новом мире" },
|
|
63
66
|
"push-through-glass": { label: "Проход сквозь стекло", description: "Камера проходит сквозь стеклянную панель в другой мир" },
|
|
64
67
|
"soul-jump": { label: "Прыжок души", description: "Полупрозрачная душа покидает одно тело и входит в другое" },
|
|
68
|
+
"mask-transition": { label: "Переход через маску", description: "Объект на переднем плане перекрывает кадр, камера проходит сквозь темноту" },
|
|
69
|
+
"zoom-through": { label: "Наезд сквозь деталь", description: "Камера укрупняет деталь, пока внутри неё не раскроется новая сцена" },
|
|
65
70
|
|
|
66
71
|
// ── Physics ──
|
|
67
72
|
"explosion-blast": { label: "Взрывная волна", description: "Взрыв захлёстывает кадр, открывая новую сцену" },
|
|
@@ -73,6 +78,7 @@ const map: LocaleCatalogMap = {
|
|
|
73
78
|
"vehicle-explosion": { label: "Взрыв транспорта", description: "Машина взрывается, огонь захлёстывает кадр, открывается новая сцена" },
|
|
74
79
|
"jump-match": { label: "Совпадающий прыжок", description: "Персонаж прыгает и приземляется уже в новой сцене" },
|
|
75
80
|
"hand-swipe": { label: "Смахивание рукой", description: "Рука проходит перед объективом, сцена меняется" },
|
|
81
|
+
"action-relay": { label: "Монтаж по действию", description: "Герой уходит из кадра на движении и продолжает его в новой сцене" },
|
|
76
82
|
|
|
77
83
|
// ── Light ──
|
|
78
84
|
"white-flash": { label: "Белая вспышка", description: "Кадр заливается белым, затем появляется новая сцена" },
|
|
@@ -7,12 +7,15 @@ const map: LocaleCatalogMap = {
|
|
|
7
7
|
"cross-dissolve": { label: "交叉溶解", description: "两个镜头间的渐进融合" },
|
|
8
8
|
"fade-to-black": { label: "淡出至黑", description: "画面变暗至全黑,第二幕浮现" },
|
|
9
9
|
"fade-to-white": { label: "淡出至白", description: "画面泛白,第二幕从白光中显现" },
|
|
10
|
+
"snap-to-black": { label: "瞬切黑场", description: "瞬间切入全黑停顿一拍,随后切入下一镜头" },
|
|
10
11
|
"match-cut": { label: "匹配剪辑", description: "镜头间形状或动作的视觉呼应" },
|
|
11
12
|
"smash-cut": { label: "撞击剪辑", description: "对比强烈的镜头间的突兀硬切" },
|
|
12
13
|
"iris": { label: "虹膜转场", description: "圆形虹膜收缩后展开至第二幕" },
|
|
13
14
|
"wipe": { label: "划像", description: "直线划过替换第一个镜头" },
|
|
14
15
|
"roll-transition": { label: "滚动转场", description: "画面旋转90–180°,第二幕正立落定" },
|
|
15
16
|
"seamless-match": { label: "无缝匹配", description: "以运动与色调伪装的隐形剪辑" },
|
|
17
|
+
"whip-pan": { label: "甩镜", description: "镜头横向急甩带出模糊,下一镜头顺着同一方向接上" },
|
|
18
|
+
"jump-cut": { label: "跳切", description: "同一构图,时间向前跳跃" },
|
|
16
19
|
|
|
17
20
|
// ── Time ──
|
|
18
21
|
"fast-forward-day-night": { label: "快进(日→夜)", description: "同一场景日转夜的延时摄影" },
|
|
@@ -62,6 +65,8 @@ const map: LocaleCatalogMap = {
|
|
|
62
65
|
"zoom-into-mouth": { label: "推入口腔", description: "推入张开的嘴,进入内部新世界" },
|
|
63
66
|
"push-through-glass": { label: "穿越玻璃", description: "镜头推过玻璃折射进入新世界" },
|
|
64
67
|
"soul-jump": { label: "灵魂跃迁", description: "半透明灵魂离体,跃入新身体" },
|
|
68
|
+
"mask-transition": { label: "遮罩转场", description: "前景物体遮黑画面,镜头穿过黑暗进入新场景" },
|
|
69
|
+
"zoom-through": { label: "推进穿越", description: "镜头不断放大一处细节,新场景在其中展开" },
|
|
65
70
|
|
|
66
71
|
// ── Physics ──
|
|
67
72
|
"explosion-blast": { label: "爆炸", description: "爆炸席卷画面,新场景从烟尘中浮现" },
|
|
@@ -73,6 +78,7 @@ const map: LocaleCatalogMap = {
|
|
|
73
78
|
"vehicle-explosion": { label: "车辆爆炸", description: "前景车辆爆炸,火焰散去后新场景" },
|
|
74
79
|
"jump-match": { label: "跳跃匹配", description: "主体起跳,落地衔接新场景" },
|
|
75
80
|
"hand-swipe": { label: "手掌划过", description: "手掌扫过镜头,遮挡间场景切换" },
|
|
81
|
+
"action-relay": { label: "动作接力剪辑", description: "主体带着动作出画,在新场景中延续同一动作" },
|
|
76
82
|
|
|
77
83
|
// ── Light ──
|
|
78
84
|
"white-flash": { label: "白色闪光", description: "画面泛出纯白" },
|
package/src/index.ts
CHANGED
|
@@ -511,6 +511,7 @@ export {
|
|
|
511
511
|
PARAMETER_NODE_TYPES,
|
|
512
512
|
HINT_EXEMPT_PARAMETER_TYPES,
|
|
513
513
|
getParameterValue,
|
|
514
|
+
setRegisteredPersonPackFields,
|
|
514
515
|
} from "./parameter-node-value.js"
|
|
515
516
|
|
|
516
517
|
export {
|
|
@@ -746,6 +747,8 @@ export {
|
|
|
746
747
|
getLocaleDirection,
|
|
747
748
|
ensureLocaleCatalogLoaded,
|
|
748
749
|
registerSidecarLoaders,
|
|
750
|
+
registerCatalogSidecars,
|
|
751
|
+
resetCatalogSidecars,
|
|
749
752
|
resolveLabel,
|
|
750
753
|
resolveDescription,
|
|
751
754
|
entryMatchesQuery,
|
|
@@ -961,5 +964,21 @@ export * from "./smart-cut-windows.js"
|
|
|
961
964
|
export * from "./entity-asset-types.js"
|
|
962
965
|
export * from "./hint-graph-types.js"
|
|
963
966
|
|
|
967
|
+
// --- Tag-free /v1/catalogs projection wire shape (the ONLY catalog type in shared) ---
|
|
968
|
+
export * from "./catalog-projection.js"
|
|
969
|
+
|
|
964
970
|
// --- Organizations (second tenancy axis): wire contract only — enums, settings request schemas, error codes ---
|
|
965
971
|
export * from "./organizations/index.js"
|
|
972
|
+
|
|
973
|
+
export {
|
|
974
|
+
ENTITY_DB_ID_FIELD,
|
|
975
|
+
ENTITY_NAME_FIELD,
|
|
976
|
+
ENTITY_TABLE,
|
|
977
|
+
ENTITY_BUCKET_FIELDS,
|
|
978
|
+
ENTITY_KIND_SCALAR_FIELDS,
|
|
979
|
+
ENTITY_SCALAR_FIELDS,
|
|
980
|
+
entityScalarFields,
|
|
981
|
+
entityHydrationColumns,
|
|
982
|
+
} from "./entity-node-fields.js"
|
|
983
|
+
export { ENTITY_NODE_KINDS } from "./entity-node-fields.js"
|
|
984
|
+
export type { EntityNodeKind } from "./entity-node-fields.js"
|
|
@@ -77,6 +77,17 @@ export const HINT_EXEMPT_PARAMETER_TYPES: ReadonlySet<string> = new Set([
|
|
|
77
77
|
"aspect-ratio",
|
|
78
78
|
])
|
|
79
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Extra person-dimension data-field names contributed by registered person
|
|
82
|
+
* packs. Content-free (field-name strings only) — populated at runtime by
|
|
83
|
+
* `@nodaro/prompts`'s `registerPersonPack`; empty on mainline (identity).
|
|
84
|
+
* shared MUST NOT import prompts, so the field list is pushed in, not pulled.
|
|
85
|
+
*/
|
|
86
|
+
let registeredPersonPackFields: readonly string[] = []
|
|
87
|
+
export function setRegisteredPersonPackFields(fields: readonly string[]): void {
|
|
88
|
+
registeredPersonPackFields = [...fields]
|
|
89
|
+
}
|
|
90
|
+
|
|
80
91
|
export function getParameterValue(
|
|
81
92
|
data: Record<string, unknown>,
|
|
82
93
|
nodeType: string,
|
|
@@ -171,11 +182,11 @@ export function getParameterValue(
|
|
|
171
182
|
return trim(data.backdrop)
|
|
172
183
|
case "held-prop":
|
|
173
184
|
return trim(data.heldProp)
|
|
174
|
-
case "person":
|
|
185
|
+
case "person": {
|
|
175
186
|
// Multi-dimension: return the first set per-dimension value (used for
|
|
176
187
|
// single-string field-mapping resolution; full hint composition goes
|
|
177
188
|
// through buildPersonHints in the executors).
|
|
178
|
-
|
|
189
|
+
const base =
|
|
179
190
|
trim(data.type) ??
|
|
180
191
|
trim(data.age) ??
|
|
181
192
|
trim(data.ethnicity) ??
|
|
@@ -210,7 +221,16 @@ export function getParameterValue(
|
|
|
210
221
|
trim(data.distinctiveFeature) ??
|
|
211
222
|
trim(data.lipState) ??
|
|
212
223
|
trim(data.eyeState)
|
|
213
|
-
)
|
|
224
|
+
if (base !== undefined) return base
|
|
225
|
+
// Fall back to any registered person-pack dimension field (G4): a
|
|
226
|
+
// deployment overlay's extra person dimensions resolve in the
|
|
227
|
+
// `{PersonLabel}` field-mapping single-string path. Empty on mainline.
|
|
228
|
+
for (const field of registeredPersonPackFields) {
|
|
229
|
+
const v = trim(data[field])
|
|
230
|
+
if (v !== undefined) return v
|
|
231
|
+
}
|
|
232
|
+
return undefined
|
|
233
|
+
}
|
|
214
234
|
case "mood":
|
|
215
235
|
return trim(data.mood)
|
|
216
236
|
case "photographer":
|
package/src/producer-types.ts
CHANGED
|
@@ -85,6 +85,10 @@ export const VIDEO_PRODUCER_TYPES: ReadonlySet<string> = new Set([
|
|
|
85
85
|
// Slideshow: 2-100 stills + one optional audio track → MP4 (local FFmpeg,
|
|
86
86
|
// no provider). Same contract; images arrive via the image-collage lane.
|
|
87
87
|
"slideshow",
|
|
88
|
+
// GIF to Video: animated GIF → H.264 MP4 (local FFmpeg, no provider).
|
|
89
|
+
// Emits generatedVideoUrl so it connects to any downstream video consumer
|
|
90
|
+
// (e.g. a Seedance video-reference input) by an ordinary edge.
|
|
91
|
+
"gif-to-video",
|
|
88
92
|
])
|
|
89
93
|
|
|
90
94
|
/**
|
package/src/vehicles.ts
CHANGED
|
@@ -31,6 +31,16 @@ export interface Vehicle {
|
|
|
31
31
|
readonly label: string
|
|
32
32
|
readonly subcategory: VehicleSubcategory
|
|
33
33
|
readonly description: string
|
|
34
|
+
/**
|
|
35
|
+
* Optional authored compact term — the short phrase a professional would
|
|
36
|
+
* write in a prompt, as opposed to the user-facing `label` (see the `term`
|
|
37
|
+
* convention in `@nodaro/prompts`'s `term.ts`). Authored ONLY where the
|
|
38
|
+
* lowercased label is not that phrase — a UI compound naming two things at
|
|
39
|
+
* once ("Airship / Dirigible" -> "airship", "Plasma Sword / Lightsaber" ->
|
|
40
|
+
* "plasma sword"). Everywhere else the lowercased label IS the term for a
|
|
41
|
+
* concrete object ("golden retriever", "katana"), so nothing is authored.
|
|
42
|
+
*/
|
|
43
|
+
readonly term?: string
|
|
34
44
|
}
|
|
35
45
|
|
|
36
46
|
export const VEHICLES: ReadonlyArray<Vehicle> = [
|
|
@@ -117,7 +127,7 @@ export const VEHICLES: ReadonlyArray<Vehicle> = [
|
|
|
117
127
|
{ id: "seaplane", label: "Seaplane", subcategory: "aircraft", description: "Seaplane with twin pontoon floats instead of wheels, high wings and a propeller, resting on calm water" },
|
|
118
128
|
{ id: "hot-air-balloon", label: "Hot Air Balloon", subcategory: "aircraft", description: "Giant hot-air balloon with a colorful rainbow-striped fabric envelope, a roaring flame burner flaring upward into the mouth and a wicker passenger basket suspended below by braided cables" },
|
|
119
129
|
{ id: "blimp", label: "Blimp", subcategory: "aircraft", description: "Sausage-shaped blimp airship with a sleek silver envelope, small rear fins and a slung gondola beneath" },
|
|
120
|
-
{ id: "airship", label: "Airship / Dirigible", subcategory: "aircraft", description: "Massive rigid lighter-than-air dirigible with a long cigar-shaped fabric-covered metal frame, large rear stabilizer fins, multiple slung engine gondolas and a long passenger cabin running underneath the hull" },
|
|
130
|
+
{ id: "airship", label: "Airship / Dirigible", subcategory: "aircraft", description: "Massive rigid lighter-than-air dirigible with a long cigar-shaped fabric-covered metal frame, large rear stabilizer fins, multiple slung engine gondolas and a long passenger cabin running underneath the hull", term: "airship" },
|
|
121
131
|
{ id: "glider", label: "Glider", subcategory: "aircraft", description: "Elegant sailplane glider with ultra-long narrow wings, no engine and a teardrop cockpit pod" },
|
|
122
132
|
{ id: "paraglider", label: "Paraglider", subcategory: "aircraft", description: "Foot-launched paraglider with a wide elliptical soft-fabric ram-air wing arched overhead, dozens of slender suspension lines converging into a tandem harness with a seated pilot" },
|
|
123
133
|
{ id: "microlight", label: "Microlight Aircraft", subcategory: "aircraft", description: "Lightweight single-pilot microlight aircraft with an exposed tubular metal frame, fabric-covered high wings, a small pusher propeller engine behind the open seat and tricycle landing gear" },
|
package/src/weapons.ts
CHANGED
|
@@ -30,6 +30,16 @@ export interface Weapon {
|
|
|
30
30
|
readonly label: string
|
|
31
31
|
readonly subcategory: WeaponSubcategory
|
|
32
32
|
readonly description: string
|
|
33
|
+
/**
|
|
34
|
+
* Optional authored compact term — the short phrase a professional would
|
|
35
|
+
* write in a prompt, as opposed to the user-facing `label` (see the `term`
|
|
36
|
+
* convention in `@nodaro/prompts`'s `term.ts`). Authored ONLY where the
|
|
37
|
+
* lowercased label is not that phrase — a UI compound naming two things at
|
|
38
|
+
* once ("Airship / Dirigible" -> "airship", "Plasma Sword / Lightsaber" ->
|
|
39
|
+
* "plasma sword"). Everywhere else the lowercased label IS the term for a
|
|
40
|
+
* concrete object ("golden retriever", "katana"), so nothing is authored.
|
|
41
|
+
*/
|
|
42
|
+
readonly term?: string
|
|
33
43
|
}
|
|
34
44
|
|
|
35
45
|
export const WEAPONS: ReadonlyArray<Weapon> = [
|
|
@@ -131,7 +141,7 @@ export const WEAPONS: ReadonlyArray<Weapon> = [
|
|
|
131
141
|
{ id: "phaser", label: "Phaser", subcategory: "sci-fi", description: "Sleek sci-fi phaser with a minimalist curved grip, glowing emitter tip and a smooth panel controlling intensity" },
|
|
132
142
|
{ id: "rail-gun", label: "Rail Gun", subcategory: "sci-fi", description: "Heavy electromagnetic rail gun with parallel metal rails, massive capacitors along the body and a glowing projectile chamber" },
|
|
133
143
|
{ id: "emp-grenade", label: "EMP Grenade", subcategory: "sci-fi", description: "Spherical electromagnetic pulse grenade with exposed coils, glowing blue indicator lights and a holographic arming dial" },
|
|
134
|
-
{ id: "plasma-sword", label: "Plasma Sword / Lightsaber", subcategory: "sci-fi", description: "Sci-fi energy blade with a metallic ridged hilt projecting a tall column of saturated plasma energy, surrounded by a bright halo of glowing light, casting colored reflections on the wielder and humming softly with contained power" },
|
|
144
|
+
{ id: "plasma-sword", label: "Plasma Sword / Lightsaber", subcategory: "sci-fi", description: "Sci-fi energy blade with a metallic ridged hilt projecting a tall column of saturated plasma energy, surrounded by a bright halo of glowing light, casting colored reflections on the wielder and humming softly with contained power", term: "plasma sword" },
|
|
135
145
|
{ id: "gravity-gun", label: "Gravity Gun", subcategory: "sci-fi", description: "Sci-fi physics-manipulating ranged weapon with a chunky metallic body, three articulated prongs at the muzzle that crackle with blue gravitational energy, exposed power conduits along the barrel and a heavy two-handed grip with a glowing trigger assembly" },
|
|
136
146
|
|
|
137
147
|
// -------------------- Fantasy / Magical --------------------
|