@nodaro/shared 2.10.0 → 2.12.1
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 +142 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +209 -1
- package/dist/index.d.ts +209 -1
- package/dist/index.js +129 -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/__tests__/video-analysis-shot-craft.test.ts +38 -0
- 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/framing.ar.ts +0 -1
- package/src/i18n/framing.de.ts +0 -1
- package/src/i18n/framing.es.ts +0 -1
- package/src/i18n/framing.fr.ts +0 -1
- package/src/i18n/framing.he.ts +0 -1
- package/src/i18n/framing.hi.ts +0 -1
- package/src/i18n/framing.ja.ts +0 -1
- package/src/i18n/framing.ko.ts +0 -1
- package/src/i18n/framing.pt-BR.ts +0 -1
- package/src/i18n/framing.ru.ts +0 -1
- package/src/i18n/framing.zh-CN.ts +0 -1
- 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/video-analysis.ts +21 -0
- package/src/weapons.ts +11 -1
|
@@ -7,12 +7,15 @@ const map: LocaleCatalogMap = {
|
|
|
7
7
|
"cross-dissolve": { label: "Disolvencia Cruzada", description: "Mezcla gradual entre planos" },
|
|
8
8
|
"fade-to-black": { label: "Fundido a Negro", description: "Oscurece a negro, emerge el segundo plano" },
|
|
9
9
|
"fade-to-white": { label: "Fundido a Blanco", description: "Estalla en blanco, emerge el segundo plano" },
|
|
10
|
+
"snap-to-black": { label: "Corte a Negro", description: "Corte instantáneo a negro por un instante, luego el siguiente plano" },
|
|
10
11
|
"match-cut": { label: "Corte de Raccord", description: "Coincidencia de forma o movimiento entre planos" },
|
|
11
12
|
"smash-cut": { label: "Corte Brusco", description: "Corte abrupto entre planos contrastados" },
|
|
12
13
|
"iris": { label: "Iris", description: "Iris circular cierra y abre en el segundo plano" },
|
|
13
14
|
"wipe": { label: "Barrido", description: "Barrido lineal reemplaza el primer plano" },
|
|
14
15
|
"roll-transition": { label: "Rotación", description: "Cuadro gira 90-180°, segundo plano al aterrizar" },
|
|
15
16
|
"seamless-match": { label: "Corte Invisible", description: "Corte oculto por movimiento y color sincronizados" },
|
|
17
|
+
"whip-pan": { label: "Barrido Rápido", description: "La cámara barre de lado con desenfoque, el siguiente plano sigue esa dirección" },
|
|
18
|
+
"jump-cut": { label: "Corte de Salto", description: "Mismo encuadre, el tiempo salta hacia adelante" },
|
|
16
19
|
|
|
17
20
|
// ── Time ──
|
|
18
21
|
"fast-forward-day-night": { label: "Time-lapse Día → Noche", description: "Time-lapse de día a noche en la misma escena" },
|
|
@@ -62,6 +65,8 @@ const map: LocaleCatalogMap = {
|
|
|
62
65
|
"zoom-into-mouth": { label: "Zoom a la Boca", description: "La cámara entra en la boca abierta hacia el nuevo mundo" },
|
|
63
66
|
"push-through-glass": { label: "Atravesar el Cristal", description: "La cámara atraviesa el cristal hacia el nuevo mundo" },
|
|
64
67
|
"soul-jump": { label: "Salto del Alma", description: "Un alma translúcida sale del cuerpo y entra en el nuevo" },
|
|
68
|
+
"mask-transition": { label: "Transición de Máscara", description: "Un objeto en primer plano tapa el cuadro y la cámara lo atraviesa" },
|
|
69
|
+
"zoom-through": { label: "Zoom Atravesado", description: "La cámara amplía un detalle hasta que la nueva escena surge dentro" },
|
|
65
70
|
|
|
66
71
|
// ── Physics ──
|
|
67
72
|
"explosion-blast": { label: "Explosión", description: "Explosión barre el cuadro, emerge la nueva escena" },
|
|
@@ -73,6 +78,7 @@ const map: LocaleCatalogMap = {
|
|
|
73
78
|
"vehicle-explosion": { label: "Explosión de Vehículo", description: "Vehículo explota en primer plano, la escena cambia" },
|
|
74
79
|
"jump-match": { label: "Salto Raccord", description: "El sujeto salta, el aterrizaje enlaza con la nueva escena" },
|
|
75
80
|
"hand-swipe": { label: "Barrido de Mano", description: "Una mano barre la lente, la escena cambia al descubrirse" },
|
|
81
|
+
"action-relay": { label: "Corte por Acción", description: "El sujeto sale de cuadro en una acción y la continúa en la nueva escena" },
|
|
76
82
|
|
|
77
83
|
// ── Light ──
|
|
78
84
|
"white-flash": { label: "Destello Blanco", description: "El cuadro estalla en blanco puro" },
|
|
@@ -7,12 +7,15 @@ const map: LocaleCatalogMap = {
|
|
|
7
7
|
"cross-dissolve": { label: "Fondu Enchaîné", description: "Mélange progressif entre les plans" },
|
|
8
8
|
"fade-to-black": { label: "Fondu au Noir", description: "S'assombrit, le second plan émerge du noir" },
|
|
9
9
|
"fade-to-white": { label: "Fondu au Blanc", description: "Sature de blanc, le second plan en émerge" },
|
|
10
|
+
"snap-to-black": { label: "Coupe au Noir", description: "Coupe instantanée au noir pendant un temps, puis le plan suivant" },
|
|
10
11
|
"match-cut": { label: "Coupe sur Raccord", description: "Correspondance de forme ou mouvement entre plans" },
|
|
11
12
|
"smash-cut": { label: "Coupe Violente", description: "Coupe abrupte entre plans contrastés" },
|
|
12
13
|
"iris": { label: "Cache Iris", description: "L'iris ferme puis ouvre sur le second plan" },
|
|
13
14
|
"wipe": { label: "Balayage", description: "Balayage linéaire remplace le premier plan" },
|
|
14
15
|
"roll-transition": { label: "Rotation", description: "Le cadre pivote 90-180°, second plan à l'arrivée" },
|
|
15
16
|
"seamless-match": { label: "Coupe Invisible", description: "Coupe masquée par mouvement et couleur synchronisés" },
|
|
17
|
+
"whip-pan": { label: "Filé Panoramique", description: "La caméra file latéralement en flou, le plan suivant garde la direction" },
|
|
18
|
+
"jump-cut": { label: "Jump Cut", description: "Même cadrage, le temps saute en avant" },
|
|
16
19
|
|
|
17
20
|
// ── Time ──
|
|
18
21
|
"fast-forward-day-night": { label: "Accéléré Jour → Nuit", description: "Accéléré de jour à nuit sur la même scène" },
|
|
@@ -62,6 +65,8 @@ const map: LocaleCatalogMap = {
|
|
|
62
65
|
"zoom-into-mouth": { label: "Zoom dans la Bouche", description: "La caméra pénètre la bouche ouverte vers le nouveau monde" },
|
|
63
66
|
"push-through-glass": { label: "Traversée du Verre", description: "La caméra traverse le verre vers le nouveau monde" },
|
|
64
67
|
"soul-jump": { label: "Saut d'Âme", description: "Une âme translucide quitte le corps et entre dans le nouveau" },
|
|
68
|
+
"mask-transition": { label: "Transition Masquée", description: "Un objet au premier plan masque le cadre, la caméra le traverse" },
|
|
69
|
+
"zoom-through": { label: "Zoom Traversant", description: "La caméra grossit un détail jusqu'à ce que la nouvelle scène s'y déploie" },
|
|
65
70
|
|
|
66
71
|
// ── Physics ──
|
|
67
72
|
"explosion-blast": { label: "Souffle d'Explosion", description: "L'explosion balaie le cadre, la nouvelle scène émerge" },
|
|
@@ -73,6 +78,7 @@ const map: LocaleCatalogMap = {
|
|
|
73
78
|
"vehicle-explosion": { label: "Explosion de Véhicule", description: "Le véhicule explose au premier plan, la scène change" },
|
|
74
79
|
"jump-match": { label: "Raccord de Saut", description: "Le sujet saute, l'atterrissage enchaîne sur la nouvelle scène" },
|
|
75
80
|
"hand-swipe": { label: "Balayage de Main", description: "Une main balaie l'objectif, la scène change en se dégageant" },
|
|
81
|
+
"action-relay": { label: "Raccord dans le Mouvement", description: "Le sujet sort du cadre sur une action et la poursuit dans la nouvelle scène" },
|
|
76
82
|
|
|
77
83
|
// ── Light ──
|
|
78
84
|
"white-flash": { label: "Flash Blanc", description: "Le cadre sature en blanc pur" },
|
|
@@ -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: "クロスディゾルブ", 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/video-analysis.ts
CHANGED
|
@@ -88,6 +88,21 @@ export type VideoAnalysisVisualEffect = (typeof VIDEO_ANALYSIS_VISUAL_EFFECTS)[n
|
|
|
88
88
|
export const VIDEO_ANALYSIS_TRANSITIONS = ["cut", "fade", "dissolve", "wipe", "whip"] as const
|
|
89
89
|
export type VideoAnalysisTransition = (typeof VIDEO_ANALYSIS_TRANSITIONS)[number]
|
|
90
90
|
|
|
91
|
+
/**
|
|
92
|
+
* What burned-in text IS (2026-08-28, recast shot craft). Decides render-vs-omit
|
|
93
|
+
* downstream: a `subtitle` is a transcription of the piece's own speech — a
|
|
94
|
+
* recreation re-speaks it and must not render it — while a `title`, `caption`,
|
|
95
|
+
* `lower-third` or `logo` is picture content. Absent when a scene carries no
|
|
96
|
+
* text. A new KEY on the scene: strip-mode readers drop it harmlessly.
|
|
97
|
+
*/
|
|
98
|
+
export const VIDEO_ANALYSIS_TEXT_KINDS = ["title", "caption", "lower-third", "subtitle", "logo", "other"] as const
|
|
99
|
+
export type VideoAnalysisTextKind = (typeof VIDEO_ANALYSIS_TEXT_KINDS)[number]
|
|
100
|
+
|
|
101
|
+
/** How the CLIP opens (clip-level, not per scene — a window's first scene is
|
|
102
|
+
* not the clip's). Absent ⇒ a hard open. Only `fade` today. */
|
|
103
|
+
export const VIDEO_ANALYSIS_CLIP_TRANSITIONS_IN = ["fade"] as const
|
|
104
|
+
export type VideoAnalysisClipTransitionIn = (typeof VIDEO_ANALYSIS_CLIP_TRANSITIONS_IN)[number]
|
|
105
|
+
|
|
91
106
|
/**
|
|
92
107
|
* Time manipulation — slow motion, ramps, timelapse, freeze, reverse.
|
|
93
108
|
*
|
|
@@ -302,6 +317,8 @@ const windowSceneBase = z.object({
|
|
|
302
317
|
* earlier scene's speech means the shot is replayed footage under a voice-over.
|
|
303
318
|
*/
|
|
304
319
|
onScreenText: z.string().optional(),
|
|
320
|
+
/** What the on-screen text IS. Meaningful only when `onScreenText` is non-empty. */
|
|
321
|
+
onScreenTextKind: z.enum(VIDEO_ANALYSIS_TEXT_KINDS).optional(),
|
|
305
322
|
/** Effects on this shot's PICTURE. Absent ⇒ a clean image. */
|
|
306
323
|
effects: z.array(z.enum(VIDEO_ANALYSIS_VISUAL_EFFECTS)).optional(),
|
|
307
324
|
transitionOut: z.enum(VIDEO_ANALYSIS_TRANSITIONS).optional(),
|
|
@@ -323,6 +340,8 @@ export const windowAnalysisSchema = z.object({
|
|
|
323
340
|
/** The clip-level look as read from THIS window. Merge folds the windows
|
|
324
341
|
* field-by-field (first non-empty wins), like `language`. */
|
|
325
342
|
look: clipLookSchema.optional(),
|
|
343
|
+
/** The clip opens with a fade-in. Folded from window 0 only. */
|
|
344
|
+
transitionIn: z.enum(VIDEO_ANALYSIS_CLIP_TRANSITIONS_IN).optional(),
|
|
326
345
|
slots: z.array(entitySlotSchema),
|
|
327
346
|
scenes: z.array(windowSceneSchema),
|
|
328
347
|
})
|
|
@@ -349,6 +368,8 @@ export const videoAnalysisResultSchema = z.object({
|
|
|
349
368
|
* rather than a member: `meta` is probed fact (ffprobe dimensions, probed
|
|
350
369
|
* duration), while this is the model's reading of the photography. */
|
|
351
370
|
look: clipLookSchema.optional(),
|
|
371
|
+
/** The clip opens with a fade-in. Folded from window 0 only. */
|
|
372
|
+
transitionIn: z.enum(VIDEO_ANALYSIS_CLIP_TRANSITIONS_IN).optional(),
|
|
352
373
|
slots: z.array(entitySlotSchema),
|
|
353
374
|
scenes: z.array(analyzedSceneSchema).min(1),
|
|
354
375
|
/** CAST VARIATIONS (§4 cap handling): looks the analyzer's merge FOLDED into
|
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 --------------------
|