xvai-loi 0.1.43 → 0.1.45

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 (3) hide show
  1. package/co.txt +1 -1
  2. package/package.json +1 -1
  3. package/xvai-loi.js +251 -30
package/co.txt CHANGED
@@ -1 +1 @@
1
- xvaiLoi100752
1
+ xvaiLoi100906
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xvai-loi",
3
- "version": "0.1.43",
3
+ "version": "0.1.45",
4
4
  "description": "Loi dung video (Edit Video Tu Dong) nap vao tool Google Flow qua o cam engine/oCam.ts",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
package/xvai-loi.js CHANGED
@@ -9508,18 +9508,37 @@ function hop4(g, lop, x0, y0, x1, y1, them) {
9508
9508
  } catch (e) {
9509
9509
  }
9510
9510
  }
9511
+ var kcCache = null;
9512
+ var kcLuc = 0;
9513
+ function kieuChu() {
9514
+ const now = Date.now();
9515
+ if (kcCache && now - kcLuc < 1e3) return kcCache;
9516
+ kcLuc = now;
9517
+ let k = globalThis.__xvaiKieuChu || null;
9518
+ if (!k) {
9519
+ try {
9520
+ const t = localStorage.getItem("xvaiKieuChu");
9521
+ if (t) k = JSON.parse(t);
9522
+ } catch (e) {
9523
+ }
9524
+ }
9525
+ kcCache = k || {};
9526
+ return kcCache;
9527
+ }
9511
9528
  function chu2(g, txt, x, y, px, kieu, a = 1, maxW = 0) {
9512
9529
  if (!txt || a <= 0) return;
9513
9530
  g.save();
9514
9531
  g.globalAlpha = a;
9515
- const ng = kieu === "brand" || kieu === "cam" ? "" : "italic ";
9516
- g.font = ng + "900 " + px.toFixed(1) + "px " + FB;
9532
+ const KC = kieu === "brand" || kieu === "cam" ? {} : kieuChu();
9533
+ const ng = kieu === "brand" || kieu === "cam" || KC.nghieng === false ? "" : "italic ";
9534
+ const FBc = KC.font ? "'" + KC.font + "', " + FB : FB;
9535
+ g.font = ng + "900 " + px.toFixed(1) + "px " + FBc;
9517
9536
  g.textAlign = "center";
9518
9537
  g.textBaseline = "middle";
9519
9538
  const dong = String(txt).split("\n"), w = Math.max(...dong.map((s) => g.measureText(s).width));
9520
9539
  if (maxW && w > maxW) {
9521
9540
  px *= maxW / w;
9522
- g.font = ng + "900 " + px.toFixed(1) + "px " + FB;
9541
+ g.font = ng + "900 " + px.toFixed(1) + "px " + FBc;
9523
9542
  }
9524
9543
  const lh = px * (kieu === "giant" ? 1.12 : 1.15), y0 = y - (dong.length - 1) * lh / 2;
9525
9544
  g.lineJoin = "round";
@@ -9556,7 +9575,7 @@ function chu2(g, txt, x, y, px, kieu, a = 1, maxW = 0) {
9556
9575
  g.fillText(s, x, yy);
9557
9576
  return;
9558
9577
  }
9559
- const mauChu = kieu === "do" ? "rgb(255,52,52)" : kieu === "vang" ? "rgb(255,214,60)" : "#fff", vien2 = kieu === "do" ? "rgb(60,0,0)" : kieu === "giant" ? "rgb(40,20,10)" : "rgb(15,15,20)";
9578
+ const mauChu = kieu === "do" ? "rgb(255,52,52)" : kieu === "vang" ? KC.nhan || "rgb(255,214,60)" : KC.mau || "#fff", vien2 = kieu === "do" ? "rgb(60,0,0)" : KC.vien ? KC.vien : kieu === "giant" ? "rgb(40,20,10)" : "rgb(15,15,20)";
9560
9579
  if (kieu === "do") {
9561
9580
  g.shadowColor = "rgba(255,30,30,0.85)";
9562
9581
  g.shadowBlur = px * 0.17;
@@ -9566,7 +9585,7 @@ function chu2(g, txt, x, y, px, kieu, a = 1, maxW = 0) {
9566
9585
  g.shadowColor = kieu === "giant" ? "rgba(60,20,0,0.75)" : "rgba(0,0,0,0.9)";
9567
9586
  g.shadowBlur = px * 0.08;
9568
9587
  g.shadowOffsetY = px * 0.06;
9569
- g.lineWidth = px * (kieu === "giant" ? 0.06 : kieu === "vang" ? 0.14 : 0.09);
9588
+ g.lineWidth = px * (kieu === "giant" ? 0.06 : kieu === "vang" ? 0.14 : 0.09) * (+KC.day || 1);
9570
9589
  g.strokeStyle = vien2;
9571
9590
  g.strokeText(s, x, yy);
9572
9591
  g.shadowColor = "transparent";
@@ -10085,8 +10104,9 @@ dangKy("cmAnh", (g, d, tuoi, W4, H2, _n, _s, dai2) => {
10085
10104
  g.fillStyle = "rgba(0,0,0," + (0.22 * kc).toFixed(3) + ")";
10086
10105
  g.fillRect(0, 0, W4, H2);
10087
10106
  const k = eOut(tuoi / 0.28);
10088
- chu2(g, d.chu, W4 / 2, 0.6 * H2 + (1 - k) * 70 * H2 / 1920, 112 * H2 / 1920, d.do1 ? "do" : "kw", kep12(tuoi / 0.15) * kc, 0.88 * W4);
10089
- if (d.chu2) chu2(g, d.chu2, W4 / 2, 0.6 * H2 + 125 * H2 / 1920 + (1 - k) * 70 * H2 / 1920, 96 * H2 / 1920, d.do2 ? "do" : "vang", kep12((tuoi - 0.35) / 0.15) * kc, 0.88 * W4);
10107
+ const cxK = d.pip && _n ? 0.68 * W4 : W4 / 2, wK = d.pip && _n ? 0.56 * W4 : 0.88 * W4;
10108
+ chu2(g, d.chu, cxK, 0.6 * H2 + (1 - k) * 70 * H2 / 1920, 112 * H2 / 1920, d.do1 ? "do" : "kw", kep12(tuoi / 0.15) * kc, wK);
10109
+ if (d.chu2) chu2(g, d.chu2, cxK, 0.6 * H2 + 125 * H2 / 1920 + (1 - k) * 70 * H2 / 1920, 96 * H2 / 1920, d.do2 ? "do" : "vang", kep12((tuoi - 0.35) / 0.15) * kc, wK);
10090
10110
  }
10091
10111
  if (d.pip && _n) {
10092
10112
  const bw = 0.36 * W4, bh = bw * 1.2, bx = 0.06 * W4, by = 0.555 * H2 + (1 - eOut(Math.min(1, tuoi / 0.5))) * 0.35 * H2, F = d.F, s = 1.7 * bw / W4, cx = F ? (F[0] + F[2]) / 2 : 0.5, top = F ? F[1] : 0.2;
@@ -10515,6 +10535,10 @@ function lapCuongMe(o) {
10515
10535
  }
10516
10536
  }
10517
10537
  const { tl, cs, ws, kb, fm, zc, tong, the: the0, keu: keu0, anh, moi, ms } = o;
10538
+ try {
10539
+ globalThis.__fTu = typeof o.fTu === "function" ? o.fTu : null;
10540
+ } catch (e) {
10541
+ }
10518
10542
  let fKeu = -9;
10519
10543
  const keu = (f2, L) => {
10520
10544
  let cach = 0;
@@ -11650,6 +11674,22 @@ function lapCuongMe(o) {
11650
11674
  const bo4 = (i, ly) => {
11651
11675
  const x = sp[i];
11652
11676
  if (x.khoa) return false;
11677
+ if ((x.bo === "cut" || x.bo === "tron") && (x.giant || x.chu)) {
11678
+ ghiL("doi", x, "nhip cham: " + x.bo + " -> depth (" + ly + ")");
11679
+ x.bo = "depth";
11680
+ x.giant = x.giant || x.chu;
11681
+ x.haCap = 1;
11682
+ nBo++;
11683
+ return false;
11684
+ }
11685
+ if (x.bo === "chia" && x.ten) {
11686
+ ghiL("doi", x, "nhip cham: chia -> anh (" + ly + ")");
11687
+ x.bo = "anh";
11688
+ x.chu = x.chu || x.giant || "";
11689
+ x.haCap = 1;
11690
+ nBo++;
11691
+ return false;
11692
+ }
11653
11693
  ghiL("bo", { bo: x.bo, f: x.f, d: x.d }, "nhip cham: " + ly);
11654
11694
  sp.splice(i, 1);
11655
11695
  nBo++;
@@ -11661,13 +11701,13 @@ function lapCuongMe(o) {
11661
11701
  }
11662
11702
  for (let i = sp.length - 1; i >= 1; i--) {
11663
11703
  const x = sp[i], tr = sp[i - 1];
11664
- if (x.d < 1.4 && !x.khoa && (x.bo === "cut" || x.bo === "tron" || x.bo === "chia") && x.f - (tr.f + tr.d) < 0.3 && ut(x) <= ut(tr)) bo4(i, "ngan < 1,4 s noi sat (" + x.d.toFixed(2) + " s)");
11704
+ if (x.d < 1.4 && !x.khoa && !x.haCap && (x.bo === "cut" || x.bo === "tron" || x.bo === "chia") && x.f - (tr.f + tr.d) < 0.3 && ut(x) <= ut(tr)) bo4(i, "ngan < 1,4 s noi sat (" + x.d.toFixed(2) + " s)");
11665
11705
  }
11666
11706
  for (let i = 1; i < sp.length; i++) {
11667
11707
  const x = sp[i], tr = sp[i - 1];
11668
11708
  const khe = x.f - (tr.f + tr.d);
11669
- if (khe > -0.05 && khe < 0.9 && (x.bo === "cut" || x.bo === "tron" || x.bo === "chia") && !x.khoa) {
11670
- bo4(i, "chua giu khung goc 0,9 s sau canh truoc (khe " + khe.toFixed(2) + ")");
11709
+ if (khe > -0.05 && khe < 0.9 && (x.bo === "cut" || x.bo === "tron" || x.bo === "chia") && !x.khoa && !x.haCap) {
11710
+ if (!bo4(i, "chua giu khung goc 0,9 s sau canh truoc (khe " + khe.toFixed(2) + ")")) continue;
11671
11711
  i--;
11672
11712
  }
11673
11713
  }
@@ -11718,26 +11758,67 @@ function lapCuongMe(o) {
11718
11758
  }
11719
11759
  if (chuoi) {
11720
11760
  sp.sort((p, q) => p.f - q.f);
11721
- const daDung = new Set(sp.map((x) => x.ten).filter(Boolean));
11722
- const kho6 = dsTenTaiSan().filter((t) => !daDung.has(t) && (t.indexOf("trang:") === 0 || t.indexOf("anh:") === 0));
11761
+ const lanCuoi = {};
11762
+ sp.forEach((x) => {
11763
+ if (x.ten) lanCuoi[x.ten] = Math.max(lanCuoi[x.ten] ?? -99, x.f);
11764
+ });
11765
+ const tatCa = dsTenTaiSan().filter((t) => t.indexOf("trang:") === 0 || t.indexOf("anh:") === 0);
11766
+ const kho6 = tatCa.filter((t) => lanCuoi[t] == null);
11723
11767
  let kI = 0, nThem = 0;
11724
11768
  const spans = [];
11769
+ const layAnh = (f2) => {
11770
+ if (kI < kho6.length) return kho6[kI++];
11771
+ const cu = tatCa.filter((t) => (lanCuoi[t] ?? -99) < f2 - 20).sort((a, b) => (lanCuoi[a] ?? -99) - (lanCuoi[b] ?? -99))[0];
11772
+ return cu || null;
11773
+ };
11725
11774
  for (let i = 0; i + 1 < sp.length; i++) {
11726
11775
  const a = sp[i].f + sp[i].d, b = sp[i + 1].f;
11727
- if (b - a >= 6) spans.push([a + 0.6, b - 0.4]);
11776
+ if (b - a >= 4.5) spans.push([a + 0.5, b - 0.3]);
11728
11777
  }
11729
11778
  for (const [a, b] of spans) {
11730
11779
  let f2 = a, n = 0;
11731
- while (f2 + 2.2 <= b && n < 2 && kI < kho6.length) {
11732
- const ten2 = kho6[kI];
11733
- if (dat(+f2.toFixed(2), 2.2, { uuTien: UT.anh, bo: "anh", ten: ten2, chu: "", keu: n === 0 ? "whoosh-nhanh" : "", chuoi: 1 }, 0, 0.01)) {
11734
- ghiL("them", { bo: "anh", f: f2, d: 2.2 }, "chuoi tram " + ten2);
11735
- kI++;
11780
+ while (f2 + 2 <= b && n < 2) {
11781
+ const ten2 = layAnh(f2);
11782
+ if (!ten2) break;
11783
+ if (dat(+f2.toFixed(2), 2, { uuTien: UT.anh, bo: "anh", ten: ten2, chu: "", keu: n === 0 ? "whoosh-nhanh" : "", chuoi: 1 }, 0, 0.01)) {
11784
+ ghiL("them", { bo: "anh", f: f2, d: 2 }, "chuoi tram " + ten2);
11785
+ lanCuoi[ten2] = f2;
11736
11786
  n++;
11737
11787
  nThem++;
11738
11788
  }
11739
- f2 += 2.3;
11789
+ f2 += 2.1;
11790
+ }
11791
+ }
11792
+ const tongDai = sp.length ? sp[sp.length - 1].f + sp[sp.length - 1].d : 1;
11793
+ const tramGiay = () => sp.filter((x) => x.bo === "anh" || x.bo === "chia" || x.bo === "kinh").reduce((a, x) => a + x.d, 0);
11794
+ const chuaDung = tatCa.filter((t) => lanCuoi[t] == null);
11795
+ G2.__khoTen = tatCa.slice();
11796
+ G2.__khoChuaDung = chuaDung.slice();
11797
+ const boDau2 = (t) => t.normalize("NFD").replace(/[̀-ͯ]/g, "").replace(/đ/g, "d");
11798
+ const tu = (t) => boDau2(String(t).toLocaleLowerCase("vi")).split(/[^a-z0-9]+/).filter((w) => w.length >= 3);
11799
+ for (const x of sp) {
11800
+ if (tramGiay() / tongDai >= 0.3) break;
11801
+ if (x.bo !== "depth" || x.khoa || x.f < 3 || x.d < 1.5) continue;
11802
+ const tg = tu(x.giant || x.chu || "");
11803
+ if (!tg.length) continue;
11804
+ let ten2 = "";
11805
+ const j = chuaDung.findIndex((t) => tu(t.slice(t.indexOf(":") + 1)).some((w) => tg.indexOf(w) >= 0));
11806
+ if (j >= 0) ten2 = chuaDung.splice(j, 1)[0];
11807
+ else {
11808
+ const mm = muc.find((m) => x.f >= m.f && x.f < (m.b ?? 1e9));
11809
+ if (mm) {
11810
+ const tk = "trang:" + String(mm.ten).toLocaleLowerCase("vi").replace(/[^\p{L}\p{N}]+/gu, "");
11811
+ if (taiSan(tk) && !sp.some((y) => y.ten === tk && Math.abs(y.f - x.f) < 12)) ten2 = tk;
11812
+ }
11740
11813
  }
11814
+ if (!ten2) continue;
11815
+ ghiL("doi", x, "chuoi tram: depth -> anh " + ten2);
11816
+ x.bo = "anh";
11817
+ x.ten = ten2;
11818
+ x.chu = String(x.giant || x.chu || "").split(String.fromCharCode(10)).join(" ");
11819
+ x.giant = "";
11820
+ lanCuoi[ten2] = x.f;
11821
+ nThem++;
11741
11822
  }
11742
11823
  G2.__chuoiTramThem = nThem;
11743
11824
  ghiL("bo", { bo: "chuoi-tram" }, "chuoi tram: them " + nThem + " anh trong " + spans.length + " khoang trong");
@@ -12876,6 +12957,13 @@ async function doRung(M, tr, lo, hi) {
12876
12957
  }), rung = B.length ? B.slice().sort((p, q) => p - q)[Math.floor((B.length - 1) / 2)] : 0;
12877
12958
  return rung < 8e-4 ? null : { cx: muot(X), cy: muot(Y), o: new Map(ts2.map((t, i) => [Math.round(t * 1e4), i])) };
12878
12959
  }
12960
+ function amCua(fx) {
12961
+ return fx && fx.amLuong || globalThis.__xvaiAm || {};
12962
+ }
12963
+ function amFx(fx) {
12964
+ const am = amCua(fx);
12965
+ return am && am.on != null ? { ...fx || {}, voice: +am.on } : fx;
12966
+ }
12879
12967
  async function tiengFf(ff, clips, files, audio, dai2, total, nen2, options) {
12880
12968
  const a = [], fc = [], voices = options?.voiceChunks || [];
12881
12969
  let n = 0, main = "original";
@@ -12885,7 +12973,7 @@ async function tiengFf(ff, clips, files, audio, dai2, total, nen2, options) {
12885
12973
  fc.push("[" + n++ + ":a]asetpts=PTS-STARTPTS,aresample=48000,aformat=channel_layouts=stereo,apad,atrim=duration=" + f(dai2[i]) + "[a" + i + "]");
12886
12974
  } else fc.push("anullsrc=r=48000:cl=stereo:d=" + f(dai2[i]) + "[a" + i + "]");
12887
12975
  });
12888
- fc.push(clips.map((_, i) => "[a" + i + "]").join("") + "concat=n=" + clips.length + ":v=0:a=1," + voiceChain(options?.studioFx) + "volume=" + (options?.videoVol ?? 1) + "[original]");
12976
+ fc.push(clips.map((_, i) => "[a" + i + "]").join("") + "concat=n=" + clips.length + ":v=0:a=1," + voiceChain(amFx(options?.studioFx)) + "volume=" + ((options?.videoVol ?? 1) * (+amCua(options?.studioFx).loi || 1)).toFixed(3) + "[original]");
12889
12977
  for (let i = 0; i < voices.length; i++) {
12890
12978
  await ff.writeFile("voice" + i + ".dat", bytesFrom64(voices[i].base64));
12891
12979
  a.push("-i", "voice" + i + ".dat");
@@ -12898,7 +12986,7 @@ async function tiengFf(ff, clips, files, audio, dai2, total, nen2, options) {
12898
12986
  if (nen2?.base64) {
12899
12987
  await ff.writeFile("music.dat", bytesFrom64(nen2.base64));
12900
12988
  a.push("-i", "music.dat");
12901
- fc.push("[" + n++ + ":a]aresample=48000,aformat=channel_layouts=stereo,apad,atrim=duration=" + f(total) + ",volume=" + nen2.vol + "[music]", "[" + main + "]asplit=2[direct][side]", "[music][side]sidechaincompress=threshold=0.05:ratio=2.5:attack=25:release=350[ducked]", "[direct][ducked]amix=inputs=2:duration=first:normalize=0[mixed]");
12989
+ fc.push("[" + n++ + ":a]aresample=48000,aformat=channel_layouts=stereo,apad,atrim=duration=" + f(total) + ",volume=" + ((+nen2.vol || 0.2) * (+amCua(options?.studioFx).nhac || 1)).toFixed(3) + "[music]", "[" + main + "]asplit=2[direct][side]", "[music][side]sidechaincompress=threshold=0.05:ratio=2.5:attack=25:release=350[ducked]", "[direct][ducked]amix=inputs=2:duration=first:normalize=0[mixed]");
12902
12990
  main = "mixed";
12903
12991
  }
12904
12992
  fc.push("[" + main + "]loudnorm=I=-14:TP=-1.5:LRA=11,alimiter=level=false:limit=0.80:attack=5:release=50[out]");
@@ -19272,7 +19360,7 @@ async function napLoi(d) {
19272
19360
  return "LOI: " + String(e && e.message || e).slice(0, 300);
19273
19361
  }
19274
19362
  }
19275
- var LOI_URL = "https://cdn.jsdelivr.net/npm/xvai-loi@0.1.42/nap.js";
19363
+ var LOI_URL = "https://cdn.jsdelivr.net/npm/xvai-loi@0.1.44/nap.js";
19276
19364
  var TRONG_LOI = !!globalThis.__xvaiReact;
19277
19365
  try {
19278
19366
  if (!TRONG_LOI) setTimeout(() => {
@@ -19302,7 +19390,7 @@ function datCauLenh(a) {
19302
19390
  on2 = true;
19303
19391
  window.addEventListener("message", async (ev) => {
19304
19392
  const d = ev.data;
19305
- if (!d || d.xvaiLoi100752 !== true) return;
19393
+ if (!d || d.xvaiLoi100906 !== true) return;
19306
19394
  const o = String(ev.origin || "");
19307
19395
  if (!(o.indexOf("https://flow.google.com") === 0 || o.indexOf("https://labs.google") === 0)) return;
19308
19396
  const tra = (kq) => {
@@ -19524,7 +19612,11 @@ var SuaLich = ({ ten, onDong }) => {
19524
19612
  const taiSrt = () => {
19525
19613
  const p = G.__loiApp && G.__loiApp.p;
19526
19614
  const cues = [];
19527
- for (const sc of p && p.timeline || []) for (const m of sc.text_moments || []) if (m && m.kind === "sub" && m.text) cues.push({ t0: +m.t0 - (+sc.trimStart || 0), t1: +m.t1 - (+sc.trimStart || 0), text: String(m.text) });
19615
+ for (const sc of p && p.timeline || []) for (const m of sc.text_moments || []) if (m && m.kind === "sub" && m.text) {
19616
+ const fT = G.__fTu;
19617
+ const a0 = fT ? fT(+m.t0) : +m.t0 - (+sc.trimStart || 0), a1 = fT ? fT(+m.t1) : +m.t1 - (+sc.trimStart || 0);
19618
+ if (a1 > a0 && a0 >= 0) cues.push({ t0: a0, t1: a1, text: String(m.text) });
19619
+ }
19528
19620
  cues.sort((a, b) => a.t0 - b.t0);
19529
19621
  const hh = (t) => {
19530
19622
  t = Math.max(0, t);
@@ -19605,8 +19697,8 @@ var SuaLich = ({ ten, onDong }) => {
19605
19697
  }
19606
19698
  };
19607
19699
  useEffect(() => {
19608
- const kc = G.__khungCanh || {};
19609
- if (Object.keys(kc).length) setKhung((kh) => ({ ...kc, ...kh }));
19700
+ const kc2 = G.__khungCanh || {};
19701
+ if (Object.keys(kc2).length) setKhung((kh) => ({ ...kc2, ...kh }));
19610
19702
  else (ds2 || []).slice(0, 60).forEach((s) => layKhung(+s.f));
19611
19703
  }, [ds2.length, !!(G.__loiApp && G.__loiApp.b)]);
19612
19704
  const [khungTo, setKhungTo] = useState("");
@@ -19619,6 +19711,119 @@ var SuaLich = ({ ten, onDong }) => {
19619
19711
  const cu = fxCua(s);
19620
19712
  dat(s.id || String(s.i), "fx", { ...cu, [k]: v });
19621
19713
  };
19714
+ let am0 = fx0 && fx0.amLuong || G.__xvaiAm || {};
19715
+ try {
19716
+ if (!Object.keys(am0).length) {
19717
+ const t = localStorage.getItem("xvaiAm");
19718
+ if (t) am0 = JSON.parse(t);
19719
+ }
19720
+ } catch (e) {
19721
+ }
19722
+ const [am, setAm] = useState({ loi: +am0.loi || 1, nhac: +am0.nhac || 1, on: am0.on ?? "" });
19723
+ const datAm = (k, v) => {
19724
+ const n = { ...am, [k]: v };
19725
+ setAm(n);
19726
+ G.__xvaiAm = n;
19727
+ try {
19728
+ localStorage.setItem("xvaiAm", JSON.stringify(n));
19729
+ } catch (e) {
19730
+ }
19731
+ if (typeof G.__loiSetP === "function") G.__loiSetP((c) => c ? { ...c, studioFx: { ...c.studioFx || {}, amLuong: n } } : c);
19732
+ setBao("\xC2m thanh: l\u1EDDi \xD7" + (+n.loi).toFixed(2) + " \xB7 nh\u1EA1c+SFX \xD7" + (+n.nhac).toFixed(2) + (n.on !== "" ? " \xB7 ch\u1ED1ng \u1ED3n " + n.on : "") + " \u2192 b\u1EA5m Xu\u1EA5t l\u1EA1i");
19733
+ };
19734
+ const [nKho, setNKho] = useState(0);
19735
+ const taiKho = async (fs) => {
19736
+ if (!fs || !fs.length) return;
19737
+ const ds3 = [...fs];
19738
+ let n = 0;
19739
+ const ten2 = [];
19740
+ for (const f2 of ds3) {
19741
+ const t = "anh:" + f2.name.replace(/\.[^.]+$/, "").toLocaleLowerCase("vi").replace(/[^\p{L}\p{N}]+/gu, "-").slice(0, 30);
19742
+ try {
19743
+ if (f2.type.indexOf("video") === 0) {
19744
+ const v = await napVideo(f2);
19745
+ if (v) {
19746
+ datTaiSan(t, v);
19747
+ n++;
19748
+ ten2.push(t);
19749
+ }
19750
+ } else {
19751
+ const bm = await createImageBitmap(f2);
19752
+ datTaiSan(t, bm);
19753
+ n++;
19754
+ ten2.push(t);
19755
+ }
19756
+ } catch (e) {
19757
+ }
19758
+ }
19759
+ try {
19760
+ await themKho(ds3);
19761
+ } catch (e) {
19762
+ }
19763
+ setNKho((x) => x + n);
19764
+ setBao("\u0110\xE3 th\xEAm " + n + " v\xE0o kho: " + ten2.join(", ") + " \xB7 ch\u1ECDn \u1EDF c\u1ED9t \u1EA3nh ho\u1EB7c h\xE0ng Th\xEAm c\u1EA3nh");
19765
+ };
19766
+ const KIEU_CHU = { "M\u1EB7c \u0111\u1ECBnh (nghi\xEAng, tr\u1EAFng/v\xE0ng)": {}, "Th\u1EB3ng hi\u1EC7n \u0111\u1EA1i": { nghieng: false }, "V\xE0ng neon nh\u1EA5n": { nhan: "rgb(214,255,60)" }, "Tr\u1EAFng vi\u1EC1n \u0111en d\xE0y": { vien: "rgb(0,0,0)", day: 1.8, nghieng: false }, "Cam th\u01B0\u01A1ng hi\u1EC7u": { mau: "rgb(255,236,220)", nhan: "rgb(255,140,60)" }, "Arial Black th\u1EB3ng": { font: "Arial Black", nghieng: false }, "Georgia c\u1ED5 \u0111i\u1EC3n": { font: "Georgia", nghieng: false } };
19767
+ const [kc, setKc] = useState(() => {
19768
+ try {
19769
+ return localStorage.getItem("xvaiKieuChuTen") || "M\u1EB7c \u0111\u1ECBnh (nghi\xEAng, tr\u1EAFng/v\xE0ng)";
19770
+ } catch (e) {
19771
+ return "M\u1EB7c \u0111\u1ECBnh (nghi\xEAng, tr\u1EAFng/v\xE0ng)";
19772
+ }
19773
+ });
19774
+ const datKc = (t) => {
19775
+ setKc(t);
19776
+ const v = KIEU_CHU[t] || {};
19777
+ G.__xvaiKieuChu = v;
19778
+ try {
19779
+ localStorage.setItem("xvaiKieuChu", JSON.stringify(v));
19780
+ localStorage.setItem("xvaiKieuChuTen", t);
19781
+ } catch (e) {
19782
+ }
19783
+ setBao("Ki\u1EC3u ch\u1EEF c\u1EA3 b\xE0i: " + t + " \u2192 V\u1EBD l\u1EA1i / Xu\u1EA5t");
19784
+ };
19785
+ const tlRef = useState({ el: null })[0];
19786
+ const [keo, setKeo] = useState(null);
19787
+ const tongS = Math.max(1, ...(ds2 || []).map((x) => +x.f + +x.d));
19788
+ const MAUBO = { depth: "#E87034", cut: "#B5651D", anh: "#2E86DE", chia: "#16A085", card: "#8E44AD", kinh: "#F6D178", tron: "#E74C3C", phong: "#555" };
19789
+ const giaTri = (x, k) => {
19790
+ const e = sua[x.id] || sua[x.i] || {};
19791
+ return typeof e[k] === "number" ? e[k] : +x[k];
19792
+ };
19793
+ const batDauKeo = (ev, x, mep3) => {
19794
+ ev.preventDefault();
19795
+ ev.stopPropagation();
19796
+ setKeo({ x, mep: mep3, x0: ev.clientX, f0: giaTri(x, "f"), d0: giaTri(x, "d") });
19797
+ };
19798
+ useEffect(() => {
19799
+ if (!keo) return;
19800
+ const mv = (ev) => {
19801
+ const el = tlRef.el;
19802
+ if (!el) return;
19803
+ const dt = (ev.clientX - keo.x0) / el.clientWidth * tongS;
19804
+ const id = keo.x.id || String(keo.x.i);
19805
+ if (keo.mep) dat(id, "d", Math.max(0.4, Math.round((keo.d0 + dt) * 10) / 10));
19806
+ else dat(id, "f", Math.max(0, Math.round((keo.f0 + dt) * 10) / 10));
19807
+ };
19808
+ const up = () => {
19809
+ setKeo(null);
19810
+ setBao("\u0110\xE3 k\xE9o c\u1EA3nh \xB7 L\u01B0u r\u1ED3i V\u1EBD l\u1EA1i");
19811
+ };
19812
+ window.addEventListener("pointermove", mv);
19813
+ window.addEventListener("pointerup", up);
19814
+ return () => {
19815
+ window.removeEventListener("pointermove", mv);
19816
+ window.removeEventListener("pointerup", up);
19817
+ };
19818
+ }, [keo]);
19819
+ const boSuaCanh = (s) => {
19820
+ ghiHoan(sua);
19821
+ const n = { ...sua };
19822
+ delete n[s.id];
19823
+ delete n[String(s.i)];
19824
+ apSua(n);
19825
+ setBao("C\u1EA3nh " + s.i + " tr\u1EA3 v\u1EC1 cho AI (b\u1ECF s\u1EEDa tay) \xB7 L\u01B0u r\u1ED3i V\u1EBD l\u1EA1i");
19826
+ };
19622
19827
  const themCanh = () => {
19623
19828
  if (!(them.d > 0.3)) return;
19624
19829
  ghiHoan(sua);
@@ -19648,20 +19853,36 @@ var SuaLich = ({ ten, onDong }) => {
19648
19853
  setDs(G.__lichSp || []);
19649
19854
  } }, "N\u1EA1p l\u1EA1i"), /* @__PURE__ */ shim_react_default.createElement("button", { className: nut3, onClick: onDong }, "\u0110\xF3ng"), ls.length ? /* @__PURE__ */ shim_react_default.createElement("select", { className: "bg-[#0B1A2D] border border-[#2C4A73] rounded px-1 text-[11px]", value: "", onChange: (ev) => {
19650
19855
  if (ev.target.value) napBan(+ev.target.value);
19651
- } }, /* @__PURE__ */ shim_react_default.createElement("option", { value: "" }, "b\u1EA3n c\u0169\u2026"), ls.map((t) => /* @__PURE__ */ shim_react_default.createElement("option", { key: t, value: t }, new Date(t).toLocaleString("vi")))) : null), /* @__PURE__ */ shim_react_default.createElement("div", { className: "flex items-center gap-2 mb-2 text-[11px] flex-wrap" }, /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[#A2B2C9]" }, "M\xE0u c\u1EA3 b\xE0i:"), /* @__PURE__ */ shim_react_default.createElement("label", { className: "flex items-center gap-1" }, "s\xE1ng ", /* @__PURE__ */ shim_react_default.createElement("input", { type: "range", min: "0.7", max: "1.4", step: "0.05", value: fx.sang, onChange: (ev) => datFx("sang", +ev.target.value), className: "w-20" }), " ", (+fx.sang).toFixed(2)), /* @__PURE__ */ shim_react_default.createElement("label", { className: "flex items-center gap-1" }, "t\u01B0\u01A1ng ph\u1EA3n ", /* @__PURE__ */ shim_react_default.createElement("input", { type: "range", min: "0.7", max: "1.4", step: "0.05", value: fx.tuongPhan, onChange: (ev) => datFx("tuongPhan", +ev.target.value), className: "w-20" }), " ", (+fx.tuongPhan).toFixed(2)), /* @__PURE__ */ shim_react_default.createElement("label", { className: "flex items-center gap-1" }, "t\u01B0\u01A1i ", /* @__PURE__ */ shim_react_default.createElement("input", { type: "range", min: "0.5", max: "1.6", step: "0.05", value: fx.baoHoa, onChange: (ev) => datFx("baoHoa", +ev.target.value), className: "w-20" }), " ", (+fx.baoHoa).toFixed(2)), /* @__PURE__ */ shim_react_default.createElement("label", { className: "flex items-center gap-1" }, "\u1EA5m ", /* @__PURE__ */ shim_react_default.createElement("input", { type: "range", min: "0", max: "0.4", step: "0.05", value: fx.am, onChange: (ev) => datFx("am", +ev.target.value), className: "w-20" }), " ", (+fx.am).toFixed(2)), /* @__PURE__ */ shim_react_default.createElement("button", { className: nut3, onClick: () => {
19856
+ } }, /* @__PURE__ */ shim_react_default.createElement("option", { value: "" }, "b\u1EA3n c\u0169\u2026"), ls.map((t) => /* @__PURE__ */ shim_react_default.createElement("option", { key: t, value: t }, new Date(t).toLocaleString("vi")))) : null), /* @__PURE__ */ shim_react_default.createElement("div", { className: "flex items-center gap-2 mb-2 text-[11px] flex-wrap" }, /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[#A2B2C9]" }, "Ki\u1EC3u ch\u1EEF c\u1EA3 b\xE0i:"), /* @__PURE__ */ shim_react_default.createElement("select", { className: "bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", value: kc, onChange: (ev) => datKc(ev.target.value) }, Object.keys(KIEU_CHU).map((t) => /* @__PURE__ */ shim_react_default.createElement("option", { key: t, value: t }, t)))), /* @__PURE__ */ shim_react_default.createElement("div", { className: "flex items-center gap-2 mb-2 text-[11px] flex-wrap" }, /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[#A2B2C9]" }, "\xC2m thanh:"), /* @__PURE__ */ shim_react_default.createElement("label", { className: "flex items-center gap-1" }, "l\u1EDDi ", /* @__PURE__ */ shim_react_default.createElement("input", { type: "range", min: "0.5", max: "2", step: "0.05", value: am.loi, onChange: (ev) => datAm("loi", +ev.target.value), className: "w-20" }), " \xD7", (+am.loi).toFixed(2)), /* @__PURE__ */ shim_react_default.createElement("label", { className: "flex items-center gap-1" }, "nh\u1EA1c + SFX ", /* @__PURE__ */ shim_react_default.createElement("input", { type: "range", min: "0", max: "2.5", step: "0.05", value: am.nhac, onChange: (ev) => datAm("nhac", +ev.target.value), className: "w-20" }), " \xD7", (+am.nhac).toFixed(2)), /* @__PURE__ */ shim_react_default.createElement("label", { className: "flex items-center gap-1" }, "ch\u1ED1ng \u1ED3n ", /* @__PURE__ */ shim_react_default.createElement("select", { className: "bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", value: am.on, onChange: (ev) => datAm("on", ev.target.value === "" ? "" : +ev.target.value) }, /* @__PURE__ */ shim_react_default.createElement("option", { value: "" }, "theo b\u1EA3ng L\xE0m pro"), /* @__PURE__ */ shim_react_default.createElement("option", { value: "0" }, "t\u1EAFt"), /* @__PURE__ */ shim_react_default.createElement("option", { value: "1" }, "nh\u1EB9"), /* @__PURE__ */ shim_react_default.createElement("option", { value: "2" }, "m\u1EA1nh"))), /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[#A2B2C9]" }, "(t\u1EF1 c\xE2n \u221214 LUFS, nh\u1EA1c t\u1EF1 h\u1EA1 khi n\xF3i)")), /* @__PURE__ */ shim_react_default.createElement("div", { className: "flex items-center gap-2 mb-2 text-[11px] flex-wrap" }, /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[#A2B2C9]" }, "M\xE0u c\u1EA3 b\xE0i:"), /* @__PURE__ */ shim_react_default.createElement("label", { className: "flex items-center gap-1" }, "s\xE1ng ", /* @__PURE__ */ shim_react_default.createElement("input", { type: "range", min: "0.7", max: "1.4", step: "0.05", value: fx.sang, onChange: (ev) => datFx("sang", +ev.target.value), className: "w-20" }), " ", (+fx.sang).toFixed(2)), /* @__PURE__ */ shim_react_default.createElement("label", { className: "flex items-center gap-1" }, "t\u01B0\u01A1ng ph\u1EA3n ", /* @__PURE__ */ shim_react_default.createElement("input", { type: "range", min: "0.7", max: "1.4", step: "0.05", value: fx.tuongPhan, onChange: (ev) => datFx("tuongPhan", +ev.target.value), className: "w-20" }), " ", (+fx.tuongPhan).toFixed(2)), /* @__PURE__ */ shim_react_default.createElement("label", { className: "flex items-center gap-1" }, "t\u01B0\u01A1i ", /* @__PURE__ */ shim_react_default.createElement("input", { type: "range", min: "0.5", max: "1.6", step: "0.05", value: fx.baoHoa, onChange: (ev) => datFx("baoHoa", +ev.target.value), className: "w-20" }), " ", (+fx.baoHoa).toFixed(2)), /* @__PURE__ */ shim_react_default.createElement("label", { className: "flex items-center gap-1" }, "\u1EA5m ", /* @__PURE__ */ shim_react_default.createElement("input", { type: "range", min: "0", max: "0.4", step: "0.05", value: fx.am, onChange: (ev) => datFx("am", +ev.target.value), className: "w-20" }), " ", (+fx.am).toFixed(2)), [["T\u1EF1 c\xE2n", { sang: 1.05, tuongPhan: 1.05, baoHoa: 1, am: 0 }], ["\u1EA4m", { sang: 1.03, tuongPhan: 1.03, baoHoa: 1.08, am: 0.12 }], ["L\u1EA1nh s\u1EA1ch", { sang: 1.06, tuongPhan: 1.08, baoHoa: 0.92, am: 0 }], ["Phim", { sang: 0.97, tuongPhan: 1.12, baoHoa: 0.85, am: 0.08 }], ["R\u1EF1c", { sang: 1.04, tuongPhan: 1.1, baoHoa: 1.25, am: 0 }]].map(([t, v]) => /* @__PURE__ */ shim_react_default.createElement("button", { key: t, className: nut3, onClick: () => {
19857
+ const n = { ...v };
19858
+ setFx(n);
19859
+ G.__xvaiMau = n;
19860
+ try {
19861
+ localStorage.setItem("xvaiMau", JSON.stringify(n));
19862
+ } catch (e) {
19863
+ }
19864
+ if (typeof G.__loiSetP === "function") G.__loiSetP((c) => c ? { ...c, studioFx: { ...c.studioFx || {}, mau: n } } : c);
19865
+ setBao("M\xE0u c\u1EA3 b\xE0i: " + t + " \u2192 Xu\u1EA5t l\u1EA1i");
19866
+ } }, t)), /* @__PURE__ */ shim_react_default.createElement("button", { className: nut3, onClick: () => {
19652
19867
  setFx({ sang: 1, tuongPhan: 1, baoHoa: 1, am: 0 });
19653
19868
  datFx("sang", 1);
19654
- } }, "V\u1EC1 g\u1ED1c"), /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[#A2B2C9]" }, "(ch\u1ED1ng rung \xB7 l\xE0m \u0111\u1EB9p \xB7 ti\u1EBFng \xB7 r\u0103ng: 4 c\xF4ng t\u1EAFc \u1EDF b\u1EA3ng L\xE0m pro)")), /* @__PURE__ */ shim_react_default.createElement("div", { className: "flex items-center gap-1 mb-2 text-[11px] flex-wrap" }, /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[#A2B2C9]" }, "Th\xEAm c\u1EA3nh:"), /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-12 bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", type: "number", step: "0.1", value: them.f, onChange: (ev) => setThem({ ...them, f: ev.target.value }), title: "gi\xE2y \u0111\u1EA7u" }), /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-12 bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", type: "number", step: "0.1", value: them.d, onChange: (ev) => setThem({ ...them, d: ev.target.value }), title: "d\xE0i (s)" }), /* @__PURE__ */ shim_react_default.createElement("select", { className: "bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", value: them.bo, onChange: (ev) => setThem({ ...them, bo: ev.target.value }) }, /* @__PURE__ */ shim_react_default.createElement("option", { value: "depth" }, "ch\u1EEF nh\u1EA5n"), /* @__PURE__ */ shim_react_default.createElement("option", { value: "anh" }, "\u1EA3nh to\xE0n khung"), /* @__PURE__ */ shim_react_default.createElement("option", { value: "cut" }, "c\u1EAFt ch\u1EEF"), /* @__PURE__ */ shim_react_default.createElement("option", { value: "tron" }, "\xF4 tr\xF2n")), /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-28 bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", placeholder: "ch\u1EEF nh\u1EA5n", value: them.giant, onChange: (ev) => setThem({ ...them, giant: ev.target.value }) }), /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-24 bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", placeholder: "\u1EA3nh: trang:\u2026", value: them.ten, onChange: (ev) => setThem({ ...them, ten: ev.target.value }) }), /* @__PURE__ */ shim_react_default.createElement("button", { className: nut3, onClick: themCanh }, "+ Th\xEAm"), /* @__PURE__ */ shim_react_default.createElement("button", { className: nut3, onClick: taiLich }, "T\u1EA3i l\u1ECBch .json"), /* @__PURE__ */ shim_react_default.createElement("button", { className: nut3, onClick: taiSrt, title: "b\u1EA3n \u0111\u1EA7u: ch\u01B0a tr\u1EEB \u0111o\u1EA1n l\u1EB7ng b\u1ECB c\u1EAFt" }, "T\u1EA3i SRT"), /* @__PURE__ */ shim_react_default.createElement("label", { className: nut3 + " cursor-pointer" }, "M\u1EDF d\u1EF1 \xE1n .json", /* @__PURE__ */ shim_react_default.createElement("input", { type: "file", accept: ".json,application/json", className: "hidden", onChange: (ev) => moDuAn(ev.target.files && ev.target.files[0]) })), (sua.them || []).length ? /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[#F6D178]" }, (sua.them || []).length, " c\u1EA3nh th\xEAm") : null), /* @__PURE__ */ shim_react_default.createElement("datalist", { id: "xvai-kho-anh" }, dsTenTaiSan().map((t) => /* @__PURE__ */ shim_react_default.createElement("option", { key: t, value: t }))), /* @__PURE__ */ shim_react_default.createElement("div", { className: "max-h-[60vh] overflow-auto" }, /* @__PURE__ */ shim_react_default.createElement("table", { className: "w-full text-[11px]" }, /* @__PURE__ */ shim_react_default.createElement("thead", null, /* @__PURE__ */ shim_react_default.createElement("tr", { className: "text-[#A2B2C9]" }, /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "#"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "khung"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "gi\xE2y"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "b\u1ED1 c\u1EE5c"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "\u0111\u1EA7u/d\xE0i (s)"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "ch\u1EEF nh\u1EA5n"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "y / c\u1EE1"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "ch\u1EEF ph\u1EE5"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "icon"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "\u1EA3nh (t\xEAn kho)"), /* @__PURE__ */ shim_react_default.createElement("th", null, "fx"), /* @__PURE__ */ shim_react_default.createElement("th", null, "xo\xE1"))), /* @__PURE__ */ shim_react_default.createElement("tbody", null, ds2.map((s) => {
19869
+ } }, "V\u1EC1 g\u1ED1c"), /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[#A2B2C9]" }, "(ch\u1ED1ng rung \xB7 l\xE0m \u0111\u1EB9p \xB7 ti\u1EBFng \xB7 r\u0103ng: 4 c\xF4ng t\u1EAFc \u1EDF b\u1EA3ng L\xE0m pro)")), /* @__PURE__ */ shim_react_default.createElement("div", { className: "flex items-center gap-1 mb-2 text-[11px] flex-wrap" }, /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[#A2B2C9]" }, "Th\xEAm c\u1EA3nh:"), /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-12 bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", type: "number", step: "0.1", value: them.f, onChange: (ev) => setThem({ ...them, f: ev.target.value }), title: "gi\xE2y \u0111\u1EA7u" }), /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-12 bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", type: "number", step: "0.1", value: them.d, onChange: (ev) => setThem({ ...them, d: ev.target.value }), title: "d\xE0i (s)" }), /* @__PURE__ */ shim_react_default.createElement("select", { className: "bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", value: them.bo, onChange: (ev) => setThem({ ...them, bo: ev.target.value }) }, /* @__PURE__ */ shim_react_default.createElement("option", { value: "depth" }, "ch\u1EEF nh\u1EA5n"), /* @__PURE__ */ shim_react_default.createElement("option", { value: "anh" }, "\u1EA3nh to\xE0n khung"), /* @__PURE__ */ shim_react_default.createElement("option", { value: "cut" }, "c\u1EAFt ch\u1EEF"), /* @__PURE__ */ shim_react_default.createElement("option", { value: "tron" }, "\xF4 tr\xF2n")), /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-28 bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", placeholder: "ch\u1EEF nh\u1EA5n", value: them.giant, onChange: (ev) => setThem({ ...them, giant: ev.target.value }) }), /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-24 bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", placeholder: "\u1EA3nh: trang:\u2026", value: them.ten, onChange: (ev) => setThem({ ...them, ten: ev.target.value }) }), /* @__PURE__ */ shim_react_default.createElement("button", { className: nut3, onClick: themCanh }, "+ Th\xEAm"), /* @__PURE__ */ shim_react_default.createElement("button", { className: nut3, onClick: taiLich }, "T\u1EA3i l\u1ECBch .json"), /* @__PURE__ */ shim_react_default.createElement("button", { className: nut3, onClick: taiSrt, title: "gi\u1EDD theo phim (\u0111\xE3 tr\u1EEB l\u1EB7ng c\u1EAFt)" }, "T\u1EA3i SRT"), /* @__PURE__ */ shim_react_default.createElement("label", { className: nut3 + " cursor-pointer" }, "T\u1EA3i \u1EA3nh/clip v\xE0o kho", /* @__PURE__ */ shim_react_default.createElement("input", { type: "file", multiple: true, accept: "image/*,video/*", className: "hidden", onChange: (ev) => taiKho(ev.target.files) })), nKho ? /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[#F6D178]" }, "+", nKho, " kho") : null, /* @__PURE__ */ shim_react_default.createElement("label", { className: nut3 + " cursor-pointer" }, "M\u1EDF d\u1EF1 \xE1n .json", /* @__PURE__ */ shim_react_default.createElement("input", { type: "file", accept: ".json,application/json", className: "hidden", onChange: (ev) => moDuAn(ev.target.files && ev.target.files[0]) })), (sua.them || []).length ? /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[#F6D178]" }, (sua.them || []).length, " c\u1EA3nh th\xEAm") : null), /* @__PURE__ */ shim_react_default.createElement("div", { className: "mb-2" }, /* @__PURE__ */ shim_react_default.createElement("div", { className: "text-[#A2B2C9] text-[11px] mb-1" }, "Timeline (", tongS.toFixed(1), " s) \u2014 k\xE9o kh\u1ED1i \u0111\u1EC3 d\u1EDDi, k\xE9o m\xE9p ph\u1EA3i \u0111\u1EC3 \u0111\u1ED5i d\xE0i"), /* @__PURE__ */ shim_react_default.createElement("div", { ref: (el) => {
19870
+ tlRef.el = el;
19871
+ }, className: "relative h-9 bg-[#0B1A2D] border border-[#2C4A73] rounded select-none", style: { touchAction: "none" } }, [...Array(Math.floor(tongS / 10) + 1)].map((_, k) => /* @__PURE__ */ shim_react_default.createElement("div", { key: "v" + k, className: "absolute top-0 bottom-0 border-l border-[#2C4A73]/60 text-[9px] text-[#A2B2C9] pl-0.5", style: { left: k * 10 / tongS * 100 + "%" } }, k * 10)), (ds2 || []).map((x) => {
19872
+ const f2 = giaTri(x, "f"), d = giaTri(x, "d"), e = sua[x.id] || sua[x.i] || {};
19873
+ if (e.xoa) return null;
19874
+ return /* @__PURE__ */ shim_react_default.createElement("div", { key: "k" + (x.id || x.i), title: x.bo + " " + f2.toFixed(1) + "\u2013" + (f2 + d).toFixed(1) + " " + (x.giant || x.chu || ""), onPointerDown: (ev) => batDauKeo(ev, x, false), className: "absolute top-3 h-5 rounded-sm cursor-grab text-[8px] text-white overflow-hidden whitespace-nowrap px-0.5", style: { left: f2 / tongS * 100 + "%", width: Math.max(0.4, d / tongS * 100) + "%", background: MAUBO[x.bo] || "#777", outline: e.f != null || e.d != null ? "1px solid #fff" : "none" } }, String(x.giant || x.chu || x.bo).split(String.fromCharCode(10))[0].slice(0, 12), /* @__PURE__ */ shim_react_default.createElement("span", { onPointerDown: (ev) => batDauKeo(ev, x, true), className: "absolute right-0 top-0 bottom-0 w-1.5 bg-white/60 cursor-ew-resize" }));
19875
+ }))), /* @__PURE__ */ shim_react_default.createElement("datalist", { id: "xvai-kho-anh" }, dsTenTaiSan().map((t) => /* @__PURE__ */ shim_react_default.createElement("option", { key: t, value: t }))), /* @__PURE__ */ shim_react_default.createElement("div", { className: "max-h-[60vh] overflow-auto" }, /* @__PURE__ */ shim_react_default.createElement("table", { className: "w-full text-[11px]" }, /* @__PURE__ */ shim_react_default.createElement("thead", null, /* @__PURE__ */ shim_react_default.createElement("tr", { className: "text-[#A2B2C9]" }, /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "#"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "khung"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "gi\xE2y"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "b\u1ED1 c\u1EE5c"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "\u0111\u1EA7u/d\xE0i (s)"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "ch\u1EEF nh\u1EA5n"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "y / c\u1EE1"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "ch\u1EEF ph\u1EE5"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "icon"), /* @__PURE__ */ shim_react_default.createElement("th", { className: "text-left" }, "\u1EA3nh (t\xEAn kho)"), /* @__PURE__ */ shim_react_default.createElement("th", null, "fx"), /* @__PURE__ */ shim_react_default.createElement("th", null, "xo\xE1"))), /* @__PURE__ */ shim_react_default.createElement("tbody", null, ds2.map((s) => {
19655
19876
  const e = sua[s.id] || sua[s.i] || {};
19656
19877
  const v = (k) => (typeof e[k] === "string" ? e[k] : s[k]) || "";
19657
19878
  return /* @__PURE__ */ shim_react_default.createElement("tr", { key: s.id || s.i, className: e.xoa ? "opacity-40" : s.khoa ? "bg-[#1E3A5F]/40" : "" }, /* @__PURE__ */ shim_react_default.createElement("td", null, s.i), /* @__PURE__ */ shim_react_default.createElement("td", null, khung[(+s.f).toFixed(1)] ? /* @__PURE__ */ shim_react_default.createElement("img", { src: khung[(+s.f).toFixed(1)], width: 45, height: 80, className: "rounded cursor-zoom-in", onClick: () => setKhungTo(khung[(+s.f).toFixed(1)]) }) : /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[#A2B2C9]" }, "\u2026")), /* @__PURE__ */ shim_react_default.createElement("td", null, s.f.toFixed(1), "\u2013", (s.f + s.d).toFixed(1)), /* @__PURE__ */ shim_react_default.createElement("td", null, s.bo), /* @__PURE__ */ shim_react_default.createElement("td", { className: "whitespace-nowrap" }, /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-12 bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", value: typeof e.f === "number" ? e.f : s.f, onChange: (ev) => dat(s.id || String(s.i), "f", +ev.target.value), type: "number", step: "0.1" }), " ", /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-12 bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", value: typeof e.d === "number" ? e.d : s.d, onChange: (ev) => dat(s.id || String(s.i), "d", +ev.target.value), type: "number", step: "0.1", min: "0.4" })), /* @__PURE__ */ shim_react_default.createElement("td", null, /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-full bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", value: v("giant"), onChange: (ev) => dat(s.id || String(s.i), "giant", ev.target.value) })), /* @__PURE__ */ shim_react_default.createElement("td", { className: "whitespace-nowrap" }, /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-12 bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", type: "number", step: "0.02", min: "0.05", max: "0.6", placeholder: "y", value: typeof e.yChu === "number" ? e.yChu : s.yChu ?? "", onChange: (ev) => dat(s.id || String(s.i), "yChu", +ev.target.value), title: "v\u1ECB tr\xED ch\u1EEF nh\u1EA5n (0,05 tr\xEAn \u2013 0,6 d\u01B0\u1EDBi)" }), " ", /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-12 bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", type: "number", step: "0.1", min: "0.5", max: "1.6", placeholder: "\xD71", value: typeof e.coChu === "number" ? e.coChu : s.coChu ?? "", onChange: (ev) => dat(s.id || String(s.i), "coChu", +ev.target.value), title: "c\u1EE1 ch\u1EEF nh\u1EA5n \xD70,5\u20131,6" })), /* @__PURE__ */ shim_react_default.createElement("td", null, /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-full bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", value: v("chu2") || v("chu"), onChange: (ev) => dat(s.id || String(s.i), s.chu2 || !s.chu ? "chu2" : "chu", ev.target.value) })), /* @__PURE__ */ shim_react_default.createElement("td", null, /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-20 bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", value: v("st"), onChange: (ev) => dat(s.id || String(s.i), "st", ev.target.value), placeholder: "tich/luu\u2026" }), " ", /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-10 bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", type: "number", step: "0.05", min: "0.05", max: "0.95", placeholder: "x", title: "v\u1ECB tr\xED icon ngang 0,05\u20130,95", value: typeof e.stX === "number" ? e.stX : s.stX ?? "", onChange: (ev) => dat(s.id || String(s.i), "stX", +ev.target.value) }), /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-10 bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", type: "number", step: "0.05", min: "0.05", max: "0.95", placeholder: "y", title: "v\u1ECB tr\xED icon d\u1ECDc", value: typeof e.stY === "number" ? e.stY : s.stY ?? "", onChange: (ev) => dat(s.id || String(s.i), "stY", +ev.target.value) })), /* @__PURE__ */ shim_react_default.createElement("td", null, /* @__PURE__ */ shim_react_default.createElement("input", { className: "w-24 bg-[#0B1A2D] border border-[#2C4A73] rounded px-1", list: "xvai-kho-anh", value: v("ten"), onChange: (ev) => dat(s.id || String(s.i), "ten", ev.target.value), placeholder: "trang:\u2026 / anh:\u2026" })), /* @__PURE__ */ shim_react_default.createElement("td", { className: "text-center" }, /* @__PURE__ */ shim_react_default.createElement("button", { className: nut3 + (Object.keys(fxCua(s)).length ? " bg-[#F6D178] text-[#122238]" : ""), onClick: () => setFxMo(fxMo === (s.id || String(s.i)) ? "" : s.id || String(s.i)) }, "fx"), fxMo === (s.id || String(s.i)) ? /* @__PURE__ */ shim_react_default.createElement("div", { className: "absolute z-40 bg-[#0B1A2D] border border-[#F6D178] rounded p-2 text-[11px] w-56 text-left", onClick: (ev) => ev.stopPropagation() }, [["sang", "s\xE1ng", 0.5, 1.6, 1], ["tuongPhan", "t\u01B0\u01A1ng ph\u1EA3n", 0.5, 1.6, 1], ["baoHoa", "t\u01B0\u01A1i", 0, 1.8, 1], ["am", "\u1EA5m", 0, 0.6, 0], ["mo", "m\u1EDD (px)", 0, 10, 0], ["xam", "\u0111en tr\u1EAFng", 0, 1, 0]].map((r) => /* @__PURE__ */ shim_react_default.createElement("label", { key: r[0], className: "flex items-center gap-1" }, r[1], " ", /* @__PURE__ */ shim_react_default.createElement("input", { type: "range", min: r[2], max: r[3], step: r[0] === "mo" ? 0.5 : 0.05, value: fxCua(s)[r[0]] ?? r[4], onChange: (ev) => datFxCanh(s, r[0], +ev.target.value), className: "flex-1" }), " ", (+(fxCua(s)[r[0]] ?? r[4])).toFixed(2))), /* @__PURE__ */ shim_react_default.createElement("div", { className: "flex gap-1 mt-1" }, /* @__PURE__ */ shim_react_default.createElement("button", { className: nut3, onClick: () => {
19658
19879
  dat(s.id || String(s.i), "fx", {});
19659
- } }, "V\u1EC1 g\u1ED1c"), /* @__PURE__ */ shim_react_default.createElement("button", { className: nut3, onClick: () => setFxMo("") }, "\u0110\xF3ng"))) : null), /* @__PURE__ */ shim_react_default.createElement("td", { className: "text-center" }, /* @__PURE__ */ shim_react_default.createElement("input", { type: "checkbox", checked: !!e.xoa, onChange: (ev) => dat(s.id || String(s.i), "xoa", ev.target.checked ? 1 : 0) })));
19880
+ } }, "V\u1EC1 g\u1ED1c"), /* @__PURE__ */ shim_react_default.createElement("button", { className: nut3, onClick: () => setFxMo("") }, "\u0110\xF3ng"))) : null), /* @__PURE__ */ shim_react_default.createElement("td", { className: "text-center" }, /* @__PURE__ */ shim_react_default.createElement("input", { type: "checkbox", checked: !!e.xoa, onChange: (ev) => dat(s.id || String(s.i), "xoa", ev.target.checked ? 1 : 0) }), " ", sua[s.id] || sua[s.i] ? /* @__PURE__ */ shim_react_default.createElement("button", { className: nut3, title: "AI l\xE0m l\u1EA1i c\u1EA3nh n\xE0y (b\u1ECF s\u1EEDa tay)", onClick: () => boSuaCanh(s) }, "\u21BA") : null));
19660
19881
  })))), khungTo ? /* @__PURE__ */ shim_react_default.createElement("div", { className: "fixed inset-0 bg-black/70 flex items-center justify-center z-50", onClick: () => setKhungTo("") }, /* @__PURE__ */ shim_react_default.createElement("img", { src: khungTo, style: { height: "80vh" }, className: "rounded" })) : null, /* @__PURE__ */ shim_react_default.createElement("div", { className: "text-[#A2B2C9] mt-2" }, "Ch\u1EEF nh\u1EA5n xu\u1ED1ng d\xF2ng: g\xF5 \\n. Icon: tich, luu, chuot, sao, tim, dong-ho\u2026 (t\xEAn trong veSticker). S\u1EEDa xong b\u1EA5m V\u1EBD l\u1EA1i (~2\u20135 ph\xFAt)."));
19661
19882
  };
19662
19883
 
19663
19884
  // loi/vo-flow.tsx
19664
- var PHIEN_BAN = "loi-1010AA";
19885
+ var PHIEN_BAN = "loi-1010AM";
19665
19886
  var TRONG = () => migrateProject({ id: crypto.randomUUID(), name: "D\u1EF1 \xE1n m\u1EDBi", scenes: [], timeline: [], images: [null, null, null] });
19666
19887
  var nut4 = "px-3 py-1.5 rounded-lg border border-[#2C4A73] text-[11px] font-bold text-[#A2B2C9] hover:text-[#F6D178] hover:border-[#F6D178]/60";
19667
19888
  var Vo = () => {