davinci-resolve-mcp 2.57.4 → 2.58.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.
Files changed (328) hide show
  1. package/AGENTS.md +20 -0
  2. package/CHANGELOG.md +197 -2
  3. package/LICENSE +1 -1
  4. package/README.md +73 -1
  5. package/bin/davinci-resolve-advanced-mcp.mjs +20 -0
  6. package/docs/README.md +19 -0
  7. package/docs/SKILL.md +62 -1
  8. package/docs/contributing.md +1 -1
  9. package/docs/guides/control-panel.md +9 -0
  10. package/docs/kernels/README.md +21 -0
  11. package/docs/kernels/audio-fairlight-kernel.md +22 -0
  12. package/docs/kernels/color-grade-kernel.md +51 -0
  13. package/docs/kernels/fusion-composition-kernel.md +17 -0
  14. package/docs/kernels/media-pool-ingest-kernel.md +20 -0
  15. package/docs/kernels/render-deliver-kernel.md +32 -0
  16. package/docs/kernels/timeline-conform-interchange-kernel.md +39 -0
  17. package/docs/kernels/timeline-edit-kernel.md +17 -0
  18. package/docs/process/release-process.md +29 -7
  19. package/docs/reference/api-coverage.md +1 -1
  20. package/docs/reference/api-limitations.md +38 -1
  21. package/install.py +27 -4
  22. package/package.json +23 -2
  23. package/resolve-advanced/README.md +194 -0
  24. package/resolve-advanced/package.json +50 -0
  25. package/resolve-advanced/server/black-balance.mjs +92 -0
  26. package/resolve-advanced/server/capabilities.mjs +86 -0
  27. package/resolve-advanced/server/cdl-io.mjs +76 -0
  28. package/resolve-advanced/server/contrast-normalize.mjs +180 -0
  29. package/resolve-advanced/server/db-patch.mjs +91 -0
  30. package/resolve-advanced/server/deliverable-entities.mjs +86 -0
  31. package/resolve-advanced/server/deliverable-qc.mjs +270 -0
  32. package/resolve-advanced/server/editorial.mjs +370 -0
  33. package/resolve-advanced/server/exposure-level.mjs +129 -0
  34. package/resolve-advanced/server/extract-frames.mjs +196 -0
  35. package/resolve-advanced/server/ffprobe-media.mjs +88 -0
  36. package/resolve-advanced/server/gamut-legal.mjs +112 -0
  37. package/resolve-advanced/server/grade-body-patch.mjs +246 -0
  38. package/resolve-advanced/server/grade-transfer.mjs +66 -0
  39. package/resolve-advanced/server/group-grade-read.mjs +137 -0
  40. package/resolve-advanced/server/index.mjs +105 -0
  41. package/resolve-advanced/server/lib.mjs +84 -0
  42. package/resolve-advanced/server/libs.mjs +65 -0
  43. package/resolve-advanced/server/lineage-db.mjs +479 -0
  44. package/resolve-advanced/server/lut-apply.mjs +61 -0
  45. package/resolve-advanced/server/match-to-reference.mjs +173 -0
  46. package/resolve-advanced/server/media-inventory.mjs +169 -0
  47. package/resolve-advanced/server/media-ops.mjs +243 -0
  48. package/resolve-advanced/server/node-meta-db.mjs +62 -0
  49. package/resolve-advanced/server/node-provenance.mjs +102 -0
  50. package/resolve-advanced/server/offline-ref-db.mjs +420 -0
  51. package/resolve-advanced/server/offline-ref.mjs +179 -0
  52. package/resolve-advanced/server/project-db.mjs +233 -0
  53. package/resolve-advanced/server/provenance-audit.mjs +210 -0
  54. package/resolve-advanced/server/qc-frame.mjs +224 -0
  55. package/resolve-advanced/server/qc-sampler.mjs +67 -0
  56. package/resolve-advanced/server/readback.mjs +77 -0
  57. package/resolve-advanced/server/render-manifest.mjs +93 -0
  58. package/resolve-advanced/server/reverse-clip-db.mjs +270 -0
  59. package/resolve-advanced/server/runner-apply-contract.mjs +64 -0
  60. package/resolve-advanced/server/runner.mjs +244 -0
  61. package/resolve-advanced/server/saturation-match.mjs +108 -0
  62. package/resolve-advanced/server/scope-read.mjs +257 -0
  63. package/resolve-advanced/server/season-look.mjs +96 -0
  64. package/resolve-advanced/server/shot-intent.mjs +82 -0
  65. package/resolve-advanced/server/shot-match.mjs +147 -0
  66. package/resolve-advanced/server/skin-match.mjs +205 -0
  67. package/resolve-advanced/server/spec-compile.mjs +217 -0
  68. package/resolve-advanced/server/tone-curve-transfer.mjs +184 -0
  69. package/resolve-advanced/server/tool-catalog.mjs +265 -0
  70. package/resolve-advanced/server/tools/audio.mjs +54 -0
  71. package/resolve-advanced/server/tools/audio_plan.mjs +58 -0
  72. package/resolve-advanced/server/tools/capabilities.mjs +16 -0
  73. package/resolve-advanced/server/tools/color_trace.mjs +165 -0
  74. package/resolve-advanced/server/tools/conform.mjs +291 -0
  75. package/resolve-advanced/server/tools/deliverable.mjs +105 -0
  76. package/resolve-advanced/server/tools/drp.mjs +232 -0
  77. package/resolve-advanced/server/tools/drt.mjs +200 -0
  78. package/resolve-advanced/server/tools/drx.mjs +943 -0
  79. package/resolve-advanced/server/tools/editorial.mjs +69 -0
  80. package/resolve-advanced/server/tools/fairlight.mjs +108 -0
  81. package/resolve-advanced/server/tools/fusion.mjs +64 -0
  82. package/resolve-advanced/server/tools/media.mjs +102 -0
  83. package/resolve-advanced/server/tools/offline_ref.mjs +123 -0
  84. package/resolve-advanced/server/tools/pipeline.mjs +137 -0
  85. package/resolve-advanced/server/tools/project_db.mjs +200 -0
  86. package/resolve-advanced/server/tools/project_read.mjs +212 -0
  87. package/resolve-advanced/server/tools/provenance.mjs +73 -0
  88. package/resolve-advanced/server/verify-grade.mjs +113 -0
  89. package/resolve-advanced/server/white-balance-match.mjs +122 -0
  90. package/resolve-advanced/vendor/audio/format-converter.js +330 -0
  91. package/resolve-advanced/vendor/audio/split.js +173 -0
  92. package/resolve-advanced/vendor/audio/trim.js +188 -0
  93. package/resolve-advanced/vendor/audio-fairlight/index.js +391 -0
  94. package/resolve-advanced/vendor/conform-qc/adapters/frame-sampler.js +56 -0
  95. package/resolve-advanced/vendor/conform-qc/adapters/local-ffmpeg-sampler.js +65 -0
  96. package/resolve-advanced/vendor/conform-qc/adapters/rendernode-ffmpeg-sampler.js +50 -0
  97. package/resolve-advanced/vendor/conform-qc/adapters/resolve/driver.py +176 -0
  98. package/resolve-advanced/vendor/conform-qc/adapters/resolve-driver.js +61 -0
  99. package/resolve-advanced/vendor/conform-qc/adapters/resolve-headless-driver.js +86 -0
  100. package/resolve-advanced/vendor/conform-qc/adapters/vision-validator.js +75 -0
  101. package/resolve-advanced/vendor/conform-qc/cli.js +63 -0
  102. package/resolve-advanced/vendor/conform-qc/compare/advisory.js +106 -0
  103. package/resolve-advanced/vendor/conform-qc/compare/decode.js +36 -0
  104. package/resolve-advanced/vendor/conform-qc/compare/index.js +61 -0
  105. package/resolve-advanced/vendor/conform-qc/compare/locate.js +70 -0
  106. package/resolve-advanced/vendor/conform-qc/compare/metrics.js +409 -0
  107. package/resolve-advanced/vendor/conform-qc/docs/runbook.md +72 -0
  108. package/resolve-advanced/vendor/conform-qc/index.js +49 -0
  109. package/resolve-advanced/vendor/conform-qc/knowledge/index.js +110 -0
  110. package/resolve-advanced/vendor/conform-qc/ops/conform-core.js +137 -0
  111. package/resolve-advanced/vendor/conform-qc/ops/conform-diff.js +109 -0
  112. package/resolve-advanced/vendor/conform-qc/ops/insert.js +108 -0
  113. package/resolve-advanced/vendor/conform-qc/ops/local-conform.js +61 -0
  114. package/resolve-advanced/vendor/conform-qc/ops/patch.js +80 -0
  115. package/resolve-advanced/vendor/conform-qc/ops/trigger.js +32 -0
  116. package/resolve-advanced/vendor/conform-qc/ops/verify.js +105 -0
  117. package/resolve-advanced/vendor/conform-qc/ops/workflow.js +30 -0
  118. package/resolve-advanced/vendor/conform-qc/oracle/emulate.js +155 -0
  119. package/resolve-advanced/vendor/conform-qc/oracle/index.js +38 -0
  120. package/resolve-advanced/vendor/conform-qc/oracle/resolve.js +196 -0
  121. package/resolve-advanced/vendor/conform-qc/package.json +16 -0
  122. package/resolve-advanced/vendor/conform-qc/packaging/emit-aaf.js +30 -0
  123. package/resolve-advanced/vendor/conform-qc/packaging/emit-fcp7.js +64 -0
  124. package/resolve-advanced/vendor/conform-qc/packaging/index.js +169 -0
  125. package/resolve-advanced/vendor/conform-qc/packaging/media-ops.js +56 -0
  126. package/resolve-advanced/vendor/conform-qc/packaging/otio.js +50 -0
  127. package/resolve-advanced/vendor/conform-qc/packaging/relink.js +50 -0
  128. package/resolve-advanced/vendor/conform-qc/packaging/surgical-relink.js +195 -0
  129. package/resolve-advanced/vendor/conform-qc/parse/index.js +54 -0
  130. package/resolve-advanced/vendor/conform-qc/parse/merge-dto.js +27 -0
  131. package/resolve-advanced/vendor/conform-qc/parse/xmeml-geometry.js +256 -0
  132. package/resolve-advanced/vendor/conform-qc/reference/burnin-ocr.js +100 -0
  133. package/resolve-advanced/vendor/conform-qc/reference/sidecar.js +37 -0
  134. package/resolve-advanced/vendor/conform-qc/repair/analysis.js +62 -0
  135. package/resolve-advanced/vendor/conform-qc/repair/index.js +78 -0
  136. package/resolve-advanced/vendor/conform-qc/repair/media-analysis.js +139 -0
  137. package/resolve-advanced/vendor/conform-qc/repair/media-index.js +135 -0
  138. package/resolve-advanced/vendor/conform-qc/repair/strategies.js +250 -0
  139. package/resolve-advanced/vendor/conform-qc/report/index.js +133 -0
  140. package/resolve-advanced/vendor/conform-qc/roles/index.js +96 -0
  141. package/resolve-advanced/vendor/conform-qc/synthetic/generate.js +233 -0
  142. package/resolve-advanced/vendor/conform-qc/test/advisory.test.js +85 -0
  143. package/resolve-advanced/vendor/conform-qc/test/cli.test.js +39 -0
  144. package/resolve-advanced/vendor/conform-qc/test/compare.test.js +152 -0
  145. package/resolve-advanced/vendor/conform-qc/test/conform-diff.test.js +70 -0
  146. package/resolve-advanced/vendor/conform-qc/test/emulate.test.js +51 -0
  147. package/resolve-advanced/vendor/conform-qc/test/frame-sampler.test.js +30 -0
  148. package/resolve-advanced/vendor/conform-qc/test/geometry.test.js +112 -0
  149. package/resolve-advanced/vendor/conform-qc/test/knowledge.test.js +56 -0
  150. package/resolve-advanced/vendor/conform-qc/test/lifecycle.test.js +110 -0
  151. package/resolve-advanced/vendor/conform-qc/test/local-ffmpeg-sampler.test.js +66 -0
  152. package/resolve-advanced/vendor/conform-qc/test/locate.test.js +63 -0
  153. package/resolve-advanced/vendor/conform-qc/test/media-analysis.test.js +63 -0
  154. package/resolve-advanced/vendor/conform-qc/test/media-index-normalized.test.js +65 -0
  155. package/resolve-advanced/vendor/conform-qc/test/media-index-origin.test.js +53 -0
  156. package/resolve-advanced/vendor/conform-qc/test/metrics-fast.test.js +91 -0
  157. package/resolve-advanced/vendor/conform-qc/test/oracle-reverse.test.js +86 -0
  158. package/resolve-advanced/vendor/conform-qc/test/oracle.test.js +136 -0
  159. package/resolve-advanced/vendor/conform-qc/test/p0-acceptance.test.js +60 -0
  160. package/resolve-advanced/vendor/conform-qc/test/p1-acceptance.test.js +75 -0
  161. package/resolve-advanced/vendor/conform-qc/test/p45-patch-acceptance.test.js +102 -0
  162. package/resolve-advanced/vendor/conform-qc/test/packaging.test.js +133 -0
  163. package/resolve-advanced/vendor/conform-qc/test/parse-stubs.test.js +28 -0
  164. package/resolve-advanced/vendor/conform-qc/test/repair-strategies.test.js +128 -0
  165. package/resolve-advanced/vendor/conform-qc/test/repair.test.js +84 -0
  166. package/resolve-advanced/vendor/conform-qc/test/report.test.js +52 -0
  167. package/resolve-advanced/vendor/conform-qc/test/resolve-readback.test.js +71 -0
  168. package/resolve-advanced/vendor/conform-qc/test/roles.test.js +107 -0
  169. package/resolve-advanced/vendor/conform-qc/test/runbook.test.js +30 -0
  170. package/resolve-advanced/vendor/conform-qc/test/scale-residual.test.js +40 -0
  171. package/resolve-advanced/vendor/conform-qc/test/sidecar.test.js +51 -0
  172. package/resolve-advanced/vendor/conform-qc/test/smoke.test.js +87 -0
  173. package/resolve-advanced/vendor/conform-qc/test/surgical-relink.test.js +73 -0
  174. package/resolve-advanced/vendor/conform-qc/test/synthetic.test.js +98 -0
  175. package/resolve-advanced/vendor/conform-qc/test/verify.test.js +93 -0
  176. package/resolve-advanced/vendor/conform-qc/test/vision-validator.test.js +43 -0
  177. package/resolve-advanced/vendor/conform-qc/test/workflow-driver.test.js +46 -0
  178. package/resolve-advanced/vendor/conform-qc/toolset/index.js +53 -0
  179. package/resolve-advanced/vendor/drp-format/README.md +116 -0
  180. package/resolve-advanced/vendor/drp-format/__tests__/_resolve-verify.js +39 -0
  181. package/resolve-advanced/vendor/drp-format/__tests__/add-media-clip.test.js +30 -0
  182. package/resolve-advanced/vendor/drp-format/__tests__/assemble-timeline.test.js +68 -0
  183. package/resolve-advanced/vendor/drp-format/__tests__/author-project.test.js +57 -0
  184. package/resolve-advanced/vendor/drp-format/__tests__/composition-text.test.js +98 -0
  185. package/resolve-advanced/vendor/drp-format/__tests__/diff.test.js +272 -0
  186. package/resolve-advanced/vendor/drp-format/__tests__/effect-filters-compressed.test.js +143 -0
  187. package/resolve-advanced/vendor/drp-format/__tests__/fixtures/p0-3-session30-empty-effectfilters.drp +0 -0
  188. package/resolve-advanced/vendor/drp-format/__tests__/fixtures/retimed-timemap-50pct.hex +1 -0
  189. package/resolve-advanced/vendor/drp-format/__tests__/fixtures/retimed-timemap-dynamic.hex +1 -0
  190. package/resolve-advanced/vendor/drp-format/__tests__/inject-grades.test.js +238 -0
  191. package/resolve-advanced/vendor/drp-format/__tests__/keyed-dict.test.js +85 -0
  192. package/resolve-advanced/vendor/drp-format/__tests__/lut-refs.test.js +119 -0
  193. package/resolve-advanced/vendor/drp-format/__tests__/media-blobs.test.js +25 -0
  194. package/resolve-advanced/vendor/drp-format/__tests__/media-timemap.test.js +119 -0
  195. package/resolve-advanced/vendor/drp-format/__tests__/place-fusion-title.test.js +52 -0
  196. package/resolve-advanced/vendor/drp-format/__tests__/place-generator.test.js +40 -0
  197. package/resolve-advanced/vendor/drp-format/__tests__/place-transition.test.js +48 -0
  198. package/resolve-advanced/vendor/drp-format/__tests__/protobuf-wire.test.js +64 -0
  199. package/resolve-advanced/vendor/drp-format/__tests__/relink-media.test.js +106 -0
  200. package/resolve-advanced/vendor/drp-format/__tests__/splice-clips.test.js +256 -0
  201. package/resolve-advanced/vendor/drp-format/assemble-timeline.js +65 -0
  202. package/resolve-advanced/vendor/drp-format/author-project.js +118 -0
  203. package/resolve-advanced/vendor/drp-format/composition-text.js +213 -0
  204. package/resolve-advanced/vendor/drp-format/curves-encoder.js +763 -0
  205. package/resolve-advanced/vendor/drp-format/diff.js +310 -0
  206. package/resolve-advanced/vendor/drp-format/drp-packager.js +201 -0
  207. package/resolve-advanced/vendor/drp-format/drp-validator.js +809 -0
  208. package/resolve-advanced/vendor/drp-format/effect-encoder.js +640 -0
  209. package/resolve-advanced/vendor/drp-format/extract-lut-refs.js +119 -0
  210. package/resolve-advanced/vendor/drp-format/grade-encoder.example.js +133 -0
  211. package/resolve-advanced/vendor/drp-format/grade-encoder.js +401 -0
  212. package/resolve-advanced/vendor/drp-format/grade-encoder.test.js +171 -0
  213. package/resolve-advanced/vendor/drp-format/grade-encoder.verify.js +249 -0
  214. package/resolve-advanced/vendor/drp-format/grade-node-extractor.js +495 -0
  215. package/resolve-advanced/vendor/drp-format/grade-parameter-decoder.js +774 -0
  216. package/resolve-advanced/vendor/drp-format/index.js +174 -0
  217. package/resolve-advanced/vendor/drp-format/inject-grades.js +219 -0
  218. package/resolve-advanced/vendor/drp-format/keyed-dict.js +227 -0
  219. package/resolve-advanced/vendor/drp-format/marker-encoder.js +532 -0
  220. package/resolve-advanced/vendor/drp-format/media-blobs.js +53 -0
  221. package/resolve-advanced/vendor/drp-format/media-timemap.js +164 -0
  222. package/resolve-advanced/vendor/drp-format/mp-folder-builder.js +293 -0
  223. package/resolve-advanced/vendor/drp-format/node-tree-encoder.js +1246 -0
  224. package/resolve-advanced/vendor/drp-format/package.json +18 -0
  225. package/resolve-advanced/vendor/drp-format/place-fusion-title.js +131 -0
  226. package/resolve-advanced/vendor/drp-format/place-generator.js +77 -0
  227. package/resolve-advanced/vendor/drp-format/place-transition.js +91 -0
  228. package/resolve-advanced/vendor/drp-format/power-window-encoder.js +776 -0
  229. package/resolve-advanced/vendor/drp-format/protobuf-wire.js +111 -0
  230. package/resolve-advanced/vendor/drp-format/qualifier-encoder.js +706 -0
  231. package/resolve-advanced/vendor/drp-format/relink-media.js +218 -0
  232. package/resolve-advanced/vendor/drp-format/rich-title-encoder.js +447 -0
  233. package/resolve-advanced/vendor/drp-format/seq-container-builder.js +572 -0
  234. package/resolve-advanced/vendor/drp-format/seq-surgery.js +155 -0
  235. package/resolve-advanced/vendor/drp-format/splice-clips.js +445 -0
  236. package/resolve-advanced/vendor/drp-format/templates/empty-project.drp +0 -0
  237. package/resolve-advanced/vendor/drp-format/templates/fusion-title.xml +56 -0
  238. package/resolve-advanced/vendor/drp-format/templates/generator-solid-color.xml +21 -0
  239. package/resolve-advanced/vendor/drp-format/templates/media-clip-h264.drp +0 -0
  240. package/resolve-advanced/vendor/drp-format/templates/transition-cross-dissolve.xml +22 -0
  241. package/resolve-advanced/vendor/drp-format/tool-registry.descriptor.js +80 -0
  242. package/resolve-advanced/vendor/drp-format/utils/safe-archive.js +54 -0
  243. package/resolve-advanced/vendor/drp-format/xml-builder.js +759 -0
  244. package/resolve-advanced/vendor/drt-format/__tests__/_resolve-verify.js +21 -0
  245. package/resolve-advanced/vendor/drt-format/__tests__/build.test.js +113 -0
  246. package/resolve-advanced/vendor/drt-format/__tests__/multi-format.test.js +93 -0
  247. package/resolve-advanced/vendor/drt-format/__tests__/parse-real-resolve21.test.js +51 -0
  248. package/resolve-advanced/vendor/drt-format/__tests__/parse.test.js +134 -0
  249. package/resolve-advanced/vendor/drt-format/__tests__/resolve-versions.test.js +120 -0
  250. package/resolve-advanced/vendor/drt-format/__tests__/schema-fingerprint.test.js +62 -0
  251. package/resolve-advanced/vendor/drt-format/__tests__/smoke.test.js +27 -0
  252. package/resolve-advanced/vendor/drt-format/__tests__/validate.test.js +109 -0
  253. package/resolve-advanced/vendor/drt-format/capabilities.js +69 -0
  254. package/resolve-advanced/vendor/drt-format/capability-domains.js +56 -0
  255. package/resolve-advanced/vendor/drt-format/drt-builder.js +42 -0
  256. package/resolve-advanced/vendor/drt-format/drt-parser.js +164 -0
  257. package/resolve-advanced/vendor/drt-format/drt-validator.js +98 -0
  258. package/resolve-advanced/vendor/drt-format/index.js +45 -0
  259. package/resolve-advanced/vendor/drt-format/package.json +17 -0
  260. package/resolve-advanced/vendor/drt-format/resolve-versions.js +153 -0
  261. package/resolve-advanced/vendor/drt-format/schema-fingerprint.js +74 -0
  262. package/resolve-advanced/vendor/drt-format/templates/drt-project-shell.xml +124 -0
  263. package/resolve-advanced/vendor/drx-codec/__tests__/curves-roundtrip.test.js +148 -0
  264. package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-1-face-refinement.drx +58 -0
  265. package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-1-filmgrain.drx +58 -0
  266. package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-1-glow.drx +58 -0
  267. package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-1-lens-flare.drx +58 -0
  268. package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-3-beauty-25.drx +58 -0
  269. package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-3-beauty-75.drx +58 -0
  270. package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p5-1-node-no-lut.drx +58 -0
  271. package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p5-1-node-with-lut.drx +58 -0
  272. package/resolve-advanced/vendor/drx-codec/__tests__/hsl-curves-roundtrip.test.js +117 -0
  273. package/resolve-advanced/vendor/drx-codec/__tests__/lut-refs-roundtrip.test.js +112 -0
  274. package/resolve-advanced/vendor/drx-codec/__tests__/matte-roundtrip.test.js +167 -0
  275. package/resolve-advanced/vendor/drx-codec/__tests__/ofx-roundtrip.test.js +215 -0
  276. package/resolve-advanced/vendor/drx-codec/__tests__/ofx-slugs-discovery.test.js +149 -0
  277. package/resolve-advanced/vendor/drx-codec/__tests__/power-window-roundtrip.test.js +230 -0
  278. package/resolve-advanced/vendor/drx-codec/__tests__/qualifier-roundtrip.test.js +226 -0
  279. package/resolve-advanced/vendor/drx-codec/cdl-exporter.js +470 -0
  280. package/resolve-advanced/vendor/drx-codec/color-nlp-parser.js +833 -0
  281. package/resolve-advanced/vendor/drx-codec/data/color-nlp-action-mappings.json +2232 -0
  282. package/resolve-advanced/vendor/drx-codec/drx-generator.js +4123 -0
  283. package/resolve-advanced/vendor/drx-codec/drx-merger.js +320 -0
  284. package/resolve-advanced/vendor/drx-codec/drx-parser.js +1808 -0
  285. package/resolve-advanced/vendor/drx-codec/extract-custom-curves.js +215 -0
  286. package/resolve-advanced/vendor/drx-codec/extract-hsl-curves.js +180 -0
  287. package/resolve-advanced/vendor/drx-codec/extract-lut-refs.js +158 -0
  288. package/resolve-advanced/vendor/drx-codec/extract-matte-finesse.js +83 -0
  289. package/resolve-advanced/vendor/drx-codec/extract-ofx-params.js +226 -0
  290. package/resolve-advanced/vendor/drx-codec/extract-power-window.js +184 -0
  291. package/resolve-advanced/vendor/drx-codec/extract-qualifier.js +99 -0
  292. package/resolve-advanced/vendor/drx-codec/index.js +109 -0
  293. package/resolve-advanced/vendor/drx-codec/node-layout.js +249 -0
  294. package/resolve-advanced/vendor/drx-codec/resolved-drx-generator.js +393 -0
  295. package/resolve-advanced/vendor/drx-codec/tool-resolver.js +974 -0
  296. package/resolve-advanced/vendor/drx-codec/training-examples.js +548 -0
  297. package/resolve-advanced/vendor/drx-codec/vocabulary-intents.js +539 -0
  298. package/resolve-advanced/vendor/drx-parameters/CALIBRATION-STATUS.md +319 -0
  299. package/resolve-advanced/vendor/drx-parameters/DRX-VALUE-SCALING.md +251 -0
  300. package/resolve-advanced/vendor/drx-parameters/calibrated-ranges.json +17737 -0
  301. package/resolve-advanced/vendor/drx-parameters/corrector-types.js +120 -0
  302. package/resolve-advanced/vendor/drx-parameters/index.js +193 -0
  303. package/resolve-advanced/vendor/drx-parameters/parameter-codec.js +451 -0
  304. package/resolve-advanced/vendor/drx-parameters/parameter-ids.js +1292 -0
  305. package/resolve-advanced/vendor/drx-parameters/parameter-ranges.js +570 -0
  306. package/resolve-advanced/vendor/drx-parameters/parameter-validator.js +392 -0
  307. package/resolve-advanced/vendor/drx-parameters/resolvefx-registry.json +14973 -0
  308. package/resolve-advanced/vendor/drx-parameters/tool-registry.descriptor.js +38 -0
  309. package/resolve-advanced/vendor/drx-parameters/tools/drx-analyzer.js +371 -0
  310. package/resolve-advanced/vendor/fairlight/index.js +833 -0
  311. package/resolve-advanced/vendor/fusion-codec/composition-generator.js +401 -0
  312. package/resolve-advanced/vendor/fusion-codec/templates/blur-region.js +103 -0
  313. package/resolve-advanced/vendor/fusion-codec/templates/color-correct.js +87 -0
  314. package/resolve-advanced/vendor/fusion-codec/templates/film-grain.js +106 -0
  315. package/resolve-advanced/vendor/fusion-codec/templates/lower-third.js +241 -0
  316. package/resolve-advanced/vendor/fusion-codec/templates/picture-in-picture.js +188 -0
  317. package/resolve-advanced/vendor/fusion-codec/templates/text-overlay.js +161 -0
  318. package/resolve-advanced/vendor/fusion-codec/templates/title-card.js +184 -0
  319. package/resolve-advanced/vendor/fusion-codec/templates/vignette.js +107 -0
  320. package/resolve-advanced/vendor/fusion-codec/templates/watermark.js +101 -0
  321. package/scripts/agent-rules/README.md +68 -0
  322. package/src/analysis_dashboard.py +233 -1
  323. package/src/granular/common.py +1 -1
  324. package/src/server.py +479 -29
  325. package/src/utils/api_truth.py +117 -0
  326. package/src/utils/cut_ir.py +1 -1
  327. package/src/utils/failure_tracker.py +0 -2
  328. package/src/utils/timeline_xml.py +405 -0
@@ -0,0 +1,241 @@
1
+ /**
2
+ * Lower Third Template — Name/title overlay
3
+ *
4
+ * Generates a lower third with primary text, subtitle,
5
+ * background bar with mask, and Merge chain back to MediaIn/MediaOut.
6
+ */
7
+
8
+ module.exports = {
9
+ label: 'Lower Third',
10
+ description: 'Animated lower third with name and title text over a semi-transparent bar.',
11
+ parameters: {
12
+ text: { type: 'string', default: 'Name', description: 'Primary text (name)' },
13
+ subtitle: { type: 'string', default: 'Title', description: 'Secondary text (title/role)' },
14
+ font: { type: 'string', default: 'Open Sans', description: 'Font family' },
15
+ fontSize: { type: 'number', default: 0.065, description: 'Primary text size (0-1 relative)' },
16
+ position: { type: 'string', default: 'bottom-left', description: 'Preset position: bottom-left, bottom-center, bottom-right' },
17
+ textColor: { type: 'object', default: { r: 1, g: 1, b: 1 }, description: 'Text color RGB (0-1)' },
18
+ barColor: { type: 'object', default: { r: 0.08, g: 0.08, b: 0.12 }, description: 'Bar background color RGB (0-1)' },
19
+ barOpacity: { type: 'number', default: 0.75, description: 'Bar opacity (0-1)' },
20
+ accentColor: { type: 'object', default: { r: 0.9, g: 0.65, b: 0.2 }, description: 'Accent line color RGB (0-1)' },
21
+ width: { type: 'number', default: 1920, description: 'Frame width' },
22
+ height: { type: 'number', default: 1080, description: 'Frame height' },
23
+ },
24
+
25
+ generate(params = {}) {
26
+ const {
27
+ text = 'Name',
28
+ subtitle = 'Title',
29
+ font = 'Open Sans',
30
+ fontSize = 0.065,
31
+ position = 'bottom-left',
32
+ textColor = { r: 1, g: 1, b: 1 },
33
+ barColor = { r: 0.08, g: 0.08, b: 0.12 },
34
+ barOpacity = 0.75,
35
+ accentColor = { r: 0.9, g: 0.65, b: 0.2 },
36
+ width = 1920,
37
+ height = 1080,
38
+ } = params;
39
+
40
+ // Position presets
41
+ const positions = {
42
+ 'bottom-left': { barX: 0.22, barY: 0.12, textX: 0.06, nameY: 0.145, subtitleY: 0.095 },
43
+ 'bottom-center': { barX: 0.5, barY: 0.12, textX: 0.35, nameY: 0.145, subtitleY: 0.095 },
44
+ 'bottom-right': { barX: 0.78, barY: 0.12, textX: 0.63, nameY: 0.145, subtitleY: 0.095 },
45
+ };
46
+ const pos = positions[position] || positions['bottom-left'];
47
+
48
+ return {
49
+ nodes: [
50
+ // MediaIn — auto-created by Resolve, but we reference it
51
+ {
52
+ type: 'MediaIn',
53
+ name: 'MediaIn1',
54
+ inputs: {},
55
+ viewX: 0, viewY: 0,
56
+ },
57
+
58
+ // Background bar
59
+ {
60
+ type: 'Background',
61
+ name: 'BG_Bar',
62
+ inputs: {
63
+ TopLeftRed: barColor.r,
64
+ TopLeftGreen: barColor.g,
65
+ TopLeftBlue: barColor.b,
66
+ TopLeftAlpha: barOpacity,
67
+ Width: width,
68
+ Height: height,
69
+ UseFrameFormatSettings: 0,
70
+ Type: 'Solid',
71
+ },
72
+ viewX: 110, viewY: -33,
73
+ },
74
+
75
+ // Rectangle mask for the bar
76
+ {
77
+ type: 'RectangleMask',
78
+ name: 'Mask_Bar',
79
+ inputs: {
80
+ Center: { x: pos.barX, y: pos.barY },
81
+ Width: 0.4,
82
+ Height: 0.07,
83
+ CornerRadius: 0.003,
84
+ SoftEdge: 0.002,
85
+ MaskWidth: width,
86
+ MaskHeight: height,
87
+ },
88
+ viewX: 220, viewY: -66,
89
+ },
90
+
91
+ // Accent line (thin colored bar on left edge)
92
+ {
93
+ type: 'Background',
94
+ name: 'BG_Accent',
95
+ inputs: {
96
+ TopLeftRed: accentColor.r,
97
+ TopLeftGreen: accentColor.g,
98
+ TopLeftBlue: accentColor.b,
99
+ TopLeftAlpha: 1,
100
+ Width: width,
101
+ Height: height,
102
+ UseFrameFormatSettings: 0,
103
+ },
104
+ viewX: 110, viewY: -99,
105
+ },
106
+
107
+ // Thin accent line mask
108
+ {
109
+ type: 'RectangleMask',
110
+ name: 'Mask_Accent',
111
+ inputs: {
112
+ Center: { x: pos.barX - 0.195, y: pos.barY },
113
+ Width: 0.004,
114
+ Height: 0.06,
115
+ SoftEdge: 0.001,
116
+ MaskWidth: width,
117
+ MaskHeight: height,
118
+ },
119
+ viewX: 220, viewY: -132,
120
+ },
121
+
122
+ // Primary text (name)
123
+ {
124
+ type: 'TextPlus',
125
+ name: 'Text_Name',
126
+ inputs: {
127
+ StyledText: text,
128
+ Font: font,
129
+ Style: 'Bold',
130
+ Size: fontSize,
131
+ Center: { x: pos.textX, y: pos.nameY },
132
+ Red1: textColor.r,
133
+ Green1: textColor.g,
134
+ Blue1: textColor.b,
135
+ HorizontalJustificationNew: 0, // left-aligned
136
+ VerticalJustificationNew: 1, // center
137
+ Width: width,
138
+ Height: height,
139
+ },
140
+ viewX: 110, viewY: 33,
141
+ },
142
+
143
+ // Subtitle text (title/role)
144
+ {
145
+ type: 'TextPlus',
146
+ name: 'Text_Subtitle',
147
+ inputs: {
148
+ StyledText: subtitle,
149
+ Font: font,
150
+ Style: 'Regular',
151
+ Size: fontSize * 0.6,
152
+ Center: { x: pos.textX, y: pos.subtitleY },
153
+ Red1: textColor.r * 0.7,
154
+ Green1: textColor.g * 0.7,
155
+ Blue1: textColor.b * 0.7,
156
+ HorizontalJustificationNew: 0,
157
+ VerticalJustificationNew: 1,
158
+ Width: width,
159
+ Height: height,
160
+ },
161
+ viewX: 110, viewY: 66,
162
+ },
163
+
164
+ // Merge bar over source
165
+ {
166
+ type: 'Merge',
167
+ name: 'Merge_Bar',
168
+ inputs: {},
169
+ connections: {
170
+ Background: 'MediaIn1.Output',
171
+ Foreground: 'BG_Bar.Output',
172
+ },
173
+ effectMask: 'Mask_Bar.Mask',
174
+ viewX: 330, viewY: 0,
175
+ },
176
+
177
+ // Merge accent over bar
178
+ {
179
+ type: 'Merge',
180
+ name: 'Merge_Accent',
181
+ inputs: {},
182
+ connections: {
183
+ Background: 'Merge_Bar.Output',
184
+ Foreground: 'BG_Accent.Output',
185
+ },
186
+ effectMask: 'Mask_Accent.Mask',
187
+ viewX: 440, viewY: 0,
188
+ },
189
+
190
+ // Merge name text
191
+ {
192
+ type: 'Merge',
193
+ name: 'Merge_Name',
194
+ inputs: {},
195
+ connections: {
196
+ Background: 'Merge_Accent.Output',
197
+ Foreground: 'Text_Name.Output',
198
+ },
199
+ viewX: 550, viewY: 0,
200
+ },
201
+
202
+ // Merge subtitle text
203
+ {
204
+ type: 'Merge',
205
+ name: 'Merge_Subtitle',
206
+ inputs: {},
207
+ connections: {
208
+ Background: 'Merge_Name.Output',
209
+ Foreground: 'Text_Subtitle.Output',
210
+ },
211
+ viewX: 660, viewY: 0,
212
+ },
213
+
214
+ // MediaOut
215
+ {
216
+ type: 'MediaOut',
217
+ name: 'MediaOut1',
218
+ inputs: {},
219
+ connections: {
220
+ Input: 'Merge_Subtitle.Output',
221
+ },
222
+ viewX: 770, viewY: 0,
223
+ },
224
+ ],
225
+
226
+ keyframes: [
227
+ // Bar width animates in (wipe from left)
228
+ { tool: 'Mask_Bar', input: 'Width', time: 0, value: 0 },
229
+ { tool: 'Mask_Bar', input: 'Width', time: 12, value: 0.4 },
230
+ // Accent fades in slightly after bar
231
+ { tool: 'Merge_Accent', input: 'Blend', time: 0, value: 0 },
232
+ { tool: 'Merge_Accent', input: 'Blend', time: 8, value: 1 },
233
+ // Text fades in after bar reveals
234
+ { tool: 'Merge_Name', input: 'Blend', time: 6, value: 0 },
235
+ { tool: 'Merge_Name', input: 'Blend', time: 14, value: 1 },
236
+ { tool: 'Merge_Subtitle', input: 'Blend', time: 10, value: 0 },
237
+ { tool: 'Merge_Subtitle', input: 'Blend', time: 18, value: 1 },
238
+ ],
239
+ };
240
+ },
241
+ };
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Picture-in-Picture Template — Scaled inset with border
3
+ *
4
+ * Creates a PiP overlay by transforming the foreground (MediaIn)
5
+ * scaled and positioned as an inset. Requires two clips composited
6
+ * via a Merge — designed to work with Fusion's multi-input system.
7
+ *
8
+ * Note: In practice, the "background" connection would need to be
9
+ * wired to a second input (Loader or another MediaIn). This template
10
+ * generates the node structure — the user connects the second source.
11
+ */
12
+
13
+ module.exports = {
14
+ label: 'Picture in Picture',
15
+ description: 'Scaled inset overlay with optional border/shadow for PiP layouts.',
16
+ parameters: {
17
+ scale: { type: 'number', default: 0.3, description: 'PiP scale (0-1, e.g. 0.3 = 30%)' },
18
+ position: { type: 'string', default: 'bottom-right', description: 'Preset: top-left, top-right, bottom-left, bottom-right' },
19
+ borderWidth: { type: 'number', default: 3, description: 'Border width in pixels (0 for none)' },
20
+ borderColor: { type: 'object', default: { r: 1, g: 1, b: 1 }, description: 'Border color RGB' },
21
+ shadowEnabled: { type: 'boolean', default: true, description: 'Add drop shadow' },
22
+ shadowOffset: { type: 'number', default: 5, description: 'Shadow offset pixels' },
23
+ shadowOpacity: { type: 'number', default: 0.5, description: 'Shadow opacity (0-1)' },
24
+ cornerRadius: { type: 'number', default: 0.008, description: 'Corner radius (0 for square)' },
25
+ width: { type: 'number', default: 1920, description: 'Frame width' },
26
+ height: { type: 'number', default: 1080, description: 'Frame height' },
27
+ },
28
+
29
+ generate(params = {}) {
30
+ const {
31
+ scale = 0.3,
32
+ position = 'bottom-right',
33
+ borderWidth = 3,
34
+ borderColor = { r: 1, g: 1, b: 1 },
35
+ shadowEnabled = true,
36
+ shadowOffset = 5,
37
+ shadowOpacity = 0.5,
38
+ cornerRadius = 0.008,
39
+ width = 1920,
40
+ height = 1080,
41
+ } = params;
42
+
43
+ const margin = 0.03;
44
+ const halfScale = scale / 2;
45
+ const posMap = {
46
+ 'top-left': { x: margin + halfScale, y: 1 - margin - halfScale },
47
+ 'top-right': { x: 1 - margin - halfScale, y: 1 - margin - halfScale },
48
+ 'bottom-left': { x: margin + halfScale, y: margin + halfScale },
49
+ 'bottom-right': { x: 1 - margin - halfScale, y: margin + halfScale },
50
+ };
51
+ const pos = posMap[position] || posMap['bottom-right'];
52
+
53
+ const nodes = [
54
+ {
55
+ type: 'MediaIn',
56
+ name: 'MediaIn1',
57
+ inputs: {},
58
+ viewX: 0, viewY: 0,
59
+ },
60
+
61
+ // Transform to scale and position the PiP
62
+ {
63
+ type: 'Transform',
64
+ name: 'Transform_PiP',
65
+ inputs: {
66
+ Center: { x: pos.x, y: pos.y },
67
+ Size: scale,
68
+ },
69
+ connections: {
70
+ Input: 'MediaIn1.Output',
71
+ },
72
+ viewX: 110, viewY: 0,
73
+ },
74
+
75
+ // Background (this is where the "main" video would connect)
76
+ // Using a black BG as placeholder — user replaces with their source
77
+ {
78
+ type: 'Background',
79
+ name: 'BG_Main',
80
+ inputs: {
81
+ TopLeftRed: 0,
82
+ TopLeftGreen: 0,
83
+ TopLeftBlue: 0,
84
+ TopLeftAlpha: 1,
85
+ Width: width,
86
+ Height: height,
87
+ UseFrameFormatSettings: 0,
88
+ },
89
+ viewX: 0, viewY: -66,
90
+ },
91
+ ];
92
+
93
+ let lastMerge;
94
+
95
+ // Border (optional)
96
+ if (borderWidth > 0) {
97
+ const borderScale = scale + (borderWidth * 2 / width);
98
+ nodes.push({
99
+ type: 'Background',
100
+ name: 'BG_Border',
101
+ inputs: {
102
+ TopLeftRed: borderColor.r,
103
+ TopLeftGreen: borderColor.g,
104
+ TopLeftBlue: borderColor.b,
105
+ TopLeftAlpha: 1,
106
+ Width: width,
107
+ Height: height,
108
+ UseFrameFormatSettings: 0,
109
+ },
110
+ viewX: 110, viewY: -33,
111
+ });
112
+
113
+ nodes.push({
114
+ type: 'RectangleMask',
115
+ name: 'Mask_Border',
116
+ inputs: {
117
+ Center: { x: pos.x, y: pos.y },
118
+ Width: borderScale * (width / height), // adjust for aspect
119
+ Height: borderScale,
120
+ CornerRadius: cornerRadius,
121
+ SoftEdge: 0.001,
122
+ MaskWidth: width,
123
+ MaskHeight: height,
124
+ },
125
+ viewX: 220, viewY: -66,
126
+ });
127
+
128
+ nodes.push({
129
+ type: 'Merge',
130
+ name: 'Merge_Border',
131
+ inputs: {},
132
+ connections: {
133
+ Background: 'BG_Main.Output',
134
+ Foreground: 'BG_Border.Output',
135
+ },
136
+ effectMask: 'Mask_Border.Mask',
137
+ viewX: 330, viewY: -33,
138
+ });
139
+
140
+ lastMerge = 'Merge_Border';
141
+ } else {
142
+ lastMerge = 'BG_Main';
143
+ }
144
+
145
+ // Merge PiP over background
146
+ nodes.push({
147
+ type: 'Merge',
148
+ name: 'Merge_PiP',
149
+ inputs: {},
150
+ connections: {
151
+ Background: `${lastMerge}.Output`,
152
+ Foreground: 'Transform_PiP.Output',
153
+ },
154
+ viewX: 440, viewY: 0,
155
+ });
156
+
157
+ // Shadow (optional)
158
+ if (shadowEnabled) {
159
+ nodes.push({
160
+ type: 'Shadow',
161
+ name: 'Shadow_PiP',
162
+ inputs: {
163
+ ShadowOffset: shadowOffset / width,
164
+ Softness: 0.01,
165
+ ShadowAlpha: shadowOpacity,
166
+ },
167
+ connections: {
168
+ Input: 'Merge_PiP.Output',
169
+ },
170
+ viewX: 550, viewY: 0,
171
+ });
172
+ }
173
+
174
+ const finalNode = shadowEnabled ? 'Shadow_PiP' : 'Merge_PiP';
175
+
176
+ nodes.push({
177
+ type: 'MediaOut',
178
+ name: 'MediaOut1',
179
+ inputs: {},
180
+ connections: {
181
+ Input: `${finalNode}.Output`,
182
+ },
183
+ viewX: 660, viewY: 0,
184
+ });
185
+
186
+ return { nodes, keyframes: [] };
187
+ },
188
+ };
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Text Overlay Template — Simple text burn-in
3
+ *
4
+ * Timecode, date, watermark text, or any simple text overlay.
5
+ * Single TextPlus merged over source.
6
+ */
7
+
8
+ module.exports = {
9
+ label: 'Text Overlay',
10
+ description: 'Simple text burn-in for timecode, dates, labels, or any overlay text.',
11
+ parameters: {
12
+ text: { type: 'string', default: 'OVERLAY TEXT', description: 'Text to display' },
13
+ font: { type: 'string', default: 'Courier New', description: 'Font family' },
14
+ fontSize: { type: 'number', default: 0.04, description: 'Font size (0-1)' },
15
+ position: { type: 'string', default: 'top-left', description: 'Preset: top-left, top-center, top-right, bottom-left, bottom-center, bottom-right, center' },
16
+ textColor: { type: 'object', default: { r: 1, g: 1, b: 1 }, description: 'Text color RGB' },
17
+ opacity: { type: 'number', default: 0.6, description: 'Text opacity (0-1)' },
18
+ bgEnabled: { type: 'boolean', default: false, description: 'Add background box behind text' },
19
+ bgColor: { type: 'object', default: { r: 0, g: 0, b: 0 }, description: 'Background box color' },
20
+ bgOpacity: { type: 'number', default: 0.5, description: 'Background box opacity' },
21
+ width: { type: 'number', default: 1920, description: 'Frame width' },
22
+ height: { type: 'number', default: 1080, description: 'Frame height' },
23
+ },
24
+
25
+ generate(params = {}) {
26
+ const {
27
+ text = 'OVERLAY TEXT',
28
+ font = 'Courier New',
29
+ fontSize = 0.04,
30
+ position = 'top-left',
31
+ textColor = { r: 1, g: 1, b: 1 },
32
+ opacity = 0.6,
33
+ bgEnabled = false,
34
+ bgColor = { r: 0, g: 0, b: 0 },
35
+ bgOpacity = 0.5,
36
+ width = 1920,
37
+ height = 1080,
38
+ } = params;
39
+
40
+ const positionMap = {
41
+ 'top-left': { x: 0.08, y: 0.92, hJust: 0 },
42
+ 'top-center': { x: 0.5, y: 0.92, hJust: 1 },
43
+ 'top-right': { x: 0.92, y: 0.92, hJust: 2 },
44
+ 'bottom-left': { x: 0.08, y: 0.08, hJust: 0 },
45
+ 'bottom-center': { x: 0.5, y: 0.08, hJust: 1 },
46
+ 'bottom-right': { x: 0.92, y: 0.08, hJust: 2 },
47
+ 'center': { x: 0.5, y: 0.5, hJust: 1 },
48
+ };
49
+ const pos = positionMap[position] || positionMap['top-left'];
50
+
51
+ const nodes = [
52
+ {
53
+ type: 'MediaIn',
54
+ name: 'MediaIn1',
55
+ inputs: {},
56
+ viewX: 0, viewY: 0,
57
+ },
58
+ {
59
+ type: 'TextPlus',
60
+ name: 'Text_Overlay',
61
+ inputs: {
62
+ StyledText: text,
63
+ Font: font,
64
+ Style: 'Bold',
65
+ Size: fontSize,
66
+ Center: { x: pos.x, y: pos.y },
67
+ Red1: textColor.r,
68
+ Green1: textColor.g,
69
+ Blue1: textColor.b,
70
+ HorizontalJustificationNew: pos.hJust,
71
+ VerticalJustificationNew: 1,
72
+ Width: width,
73
+ Height: height,
74
+ },
75
+ viewX: 110, viewY: 33,
76
+ },
77
+ {
78
+ type: 'Merge',
79
+ name: 'Merge_Text',
80
+ inputs: {
81
+ Blend: opacity,
82
+ },
83
+ connections: {
84
+ Background: 'MediaIn1.Output',
85
+ Foreground: 'Text_Overlay.Output',
86
+ },
87
+ viewX: 220, viewY: 0,
88
+ },
89
+ ];
90
+
91
+ let lastMerge = 'Merge_Text';
92
+
93
+ // Optional background box
94
+ if (bgEnabled) {
95
+ // Insert background elements before the text merge
96
+ nodes.splice(1, 0,
97
+ {
98
+ type: 'Background',
99
+ name: 'BG_TextBox',
100
+ inputs: {
101
+ TopLeftRed: bgColor.r,
102
+ TopLeftGreen: bgColor.g,
103
+ TopLeftBlue: bgColor.b,
104
+ TopLeftAlpha: bgOpacity,
105
+ Width: width,
106
+ Height: height,
107
+ UseFrameFormatSettings: 0,
108
+ },
109
+ viewX: 110, viewY: -33,
110
+ },
111
+ {
112
+ type: 'RectangleMask',
113
+ name: 'Mask_TextBox',
114
+ inputs: {
115
+ Center: { x: pos.x, y: pos.y },
116
+ Width: 0.25,
117
+ Height: 0.05,
118
+ CornerRadius: 0.003,
119
+ SoftEdge: 0.002,
120
+ MaskWidth: width,
121
+ MaskHeight: height,
122
+ },
123
+ viewX: 220, viewY: -66,
124
+ }
125
+ );
126
+
127
+ // Insert box merge before text merge
128
+ const textMergeIdx = nodes.findIndex(n => n.name === 'Merge_Text');
129
+ nodes.splice(textMergeIdx, 0, {
130
+ type: 'Merge',
131
+ name: 'Merge_Box',
132
+ inputs: {},
133
+ connections: {
134
+ Background: 'MediaIn1.Output',
135
+ Foreground: 'BG_TextBox.Output',
136
+ },
137
+ effectMask: 'Mask_TextBox.Mask',
138
+ viewX: 330, viewY: 0,
139
+ });
140
+
141
+ // Update text merge to use box output as background
142
+ const textMerge = nodes.find(n => n.name === 'Merge_Text');
143
+ textMerge.connections.Background = 'Merge_Box.Output';
144
+ textMerge.viewX = 440;
145
+ }
146
+
147
+ // MediaOut
148
+ nodes.push({
149
+ type: 'MediaOut',
150
+ name: 'MediaOut1',
151
+ inputs: {},
152
+ connections: {
153
+ Input: `${lastMerge}.Output`,
154
+ },
155
+ viewX: nodes[nodes.length - 1].viewX + 110,
156
+ viewY: 0,
157
+ });
158
+
159
+ return { nodes, keyframes: [] };
160
+ },
161
+ };