/* diagram.jsx — 構成図(正面から見た模式図。形・縮尺は目安)
* 画像は data/images.js(UW_IMG)。キーは将来の差し替え用に分けている:
* housing / port_dg(構成図用ポート) / light_side(左右用ストロボ) / light_top(シュー用ストロボ) / arm / clamp
* ※ light_side / light_top / port_dg が未用意の間は light / port を流用
*/
const ED = window.UWEngine;
const IMG0 = window.UW_IMG || {};
/* 構成図用の画像:img/diagram/ に置き、data/diagram_images.js に「製品ID/ファミリー/カテゴリ → ファイル」を書く。
* 未登録の間は従来の画像(data/images.js)を使う。*/
const DGI = window.UW_DG_IMAGES || {};
const dg = (key, fb) => DGI[key] || fb;
const IMGS = { housing: dg('default:housing', IMG0.housing), port: dg('default:port', IMG0.port_dg || IMG0.port), lightSide: dg('default:light_side', IMG0.light_side || IMG0.light),
lightTop: dg('default:light_top', IMG0.light_top || IMG0.light), arm: dg('default:arm', IMG0.arm), clamp: dg('default:clamp', IMG0.clamp), shoeBall: dg('default:shoeBall', null) };
/* 画像の登録値は「パス文字列」か、取付点つきの {src, ax, ay, w, h}(ストロボ用)。
* ax, ay … 画像内の取付点(ボール中心/YSベースの下端)。画像の幅・高さに対する 0〜1 の比率
* w, h … 構成図上での画像の大きさ(px)。大きさを変えたいときは w と h を同じ比率で変える
* 探す順番:製品ID:スロット → family:ファミリー:スロット → 製品ID/family/cat → default:スロット */
const rawFor = (id, slot) => { const i = id ? ED.info(id) : null; if (!i) return IMGS[slot]; const f = ED.FAM_OF && ED.FAM_OF[id];
const m = DGI[id + ':' + slot] || (f && DGI['family:' + f + ':' + slot]) || (slot === 'lightYs' ? null : i.dgImg); return m || IMGS[slot]; };
const imgFor = (id, slot) => { const v = rawFor(id, slot); return v && v.src ? v.src : v; };
/* ストロボ・ライト:YSベースは lightYs、シュー上は lightTop、左右は lightSide。YSベース用の画像がなければ従来の汎用画像を使う */
const lightFor = (id, slot) => { const v = slot === 'lightYs' && !rawFor(id, 'lightYs') ? rawFor(id, 'lightTop') : rawFor(id, slot); return v && v.src ? { src: v.src, a: v } : { src: v, a: null }; }; // YSベース用の画像がなければ、そのストロボの正面向きの画像(取付点つき)をCUBeeと同じ位置に貼る
const ARM_LEN = { S: 70, M: 88, L: 112 }; // 有効長が分からないときの目安
/* 大きさの基準=ボール(25.4mm)。アームのボール・ストロボのボール・ハウジングのハンドルのボールを、すべて BALL px にそろえる。
* TG の完成写真は、もともとこの大きさ(ハウジング幅約200px)。 */
const BALL = 33;
const PX_MM = BALL / 25.4; // 構成図上のpx/mm(アームの長さ・フロートの寸法もこの縮尺)
const HS_ALPHA = 491,HS_OLD = 550;
const PREF = { x: 0.521, y: 0.537 }; // αU系の画像でのマウントリング中心(ポート画像の位置はこれを基準に登録してある)
// // ミラーレスのハウジング画像(正方形)の一辺。ハンドルのボールが BALL になる大きさ
const armLen = (id) => { const d = (ED.DIM || {})[id]; return d && d.effective_mm ? d.effective_mm * PX_MM : ARM_LEN[ED.armSize(id)] * 1.5 || 130; };
/* ミラーレスのシューベース(アクセサリーシューボールベースII)。透過画像(599×530)をハウジングの大きさ(hs)に対する比率で配置。
* x,y,w,h = 画像の左上と大きさ / bx,by = ボール中心(ここからアーム・ストロボが伸びる)。画像は img/diagram/ に置き、diagram_images.js の 'ACC_SHOE_BALLBASE2' に登録。 */
/* TG のシュー部品(OM SYSTEM PTSA-02/アクセサリーシューボールベースII)。画像は製品IDに {src, ax, ay, tx, ty, w, h} で登録。
* ax,ay=ハウジングのシューに載せる点(下端) / tx,ty=ストロボ・アームを載せる点(PTSA-02はツメの付け根、ボールベースはボール中心)
* 直付け(RSメインフレームなし)のときは、PT-059 のシューがレンズ中心より右にあるため TG_SHOE_DX だけ右へ寄せる。
* 実機の写真(直付け・RIG経由の両方)から算出:レンズ中心から +173px/ハウジング幅938px → 構成図の幅200で約37px。RIG経由はほぼ中央。*/
const TG_SHOE_DX = 37;
const TG_SHOE_PARTS = ['OM_PTSA02', 'ACC_SHOE_BALLBASE2'];
/* TG の構成ごとの完成写真(data/diagram_images.js の UW_DG_TG)。構成が match に当てはまる写真があれば四角の模式図の代わりに使う */
const DGTG = window.UW_DG_TG || [];
/* 前面の置き場所:何もなければ正面、正面がふさがっていれば上部(RSバヨネットレンズホルダー)。リングライトは常に正面(engine.js の tgFrontLayout) */
const tgLay = (t) => ED.tgFrontLayout(t);
const tgHeld = (t) => t.top === 'holder' ? tgLay(t).top : null; // ホルダー(上部)に付けるレンズ
const tgKey = (t) => { const lay = tgLay(t);
return { rig: t.rig, grips: t.rig === 'frame' && t.multi ? 0 : t.grips, multi: t.rig === 'frame' && !!t.multi, ballBase: t.ballBase, top: t.top === 'holder' ? 'none' : t.top, shoeConv: t.shoeConv,
ring: t.ringLight || '', lens: t.ringLight ? '' : lay.front || '', recv: '' }; }; // 受け側(バヨネットマウントベース)は構成図に出さないので、完成写真の選択にも使わない
/* 構成に合う完成写真がないときは、素材(土台・グリップ・ボールベース・シュー部品)を重ねて作る(data/diagram_images.js の UW_DG_TGPARTS)。作れないときは null */
const DGP = window.UW_DG_TGPARTS;
const tgCompose = (t) => {
if (!DGP) return null;
const L = t.lenses || [],lay = tgLay(t),frontId = lay.front;
const none = t.rig === 'none',multi = t.rig === 'frame' && !!t.multi,key = none ? 'none' : multi ? (t.ballBase === 2 ? 'multib' : t.ballBase === 1 ? 'multib1' : 'multi') : 'frame',base = DGP.base[key];
const g = none || multi ? 0 : t.rig === 'single' ? Math.max(1, t.grips || 1) : t.grips || 0,nb = none ? 0 : t.ballBase || 0;
if (!base) return null;
const MB = key === 'multib' || key === 'multib1'; // 土台の写真にボールベースが写っている(マルチアングル+ボールベース1個/2個)
const gR = g >= 1,gL = g >= 2,bR = !gR && nb >= 1,bL = !gL && nb >= (gR ? 1 : 2);
const layers = [{ ...base, open: none ? 'camera' : 'rig' }],A = {};
const add = (p, side) => {layers.push({ src: p.src, x: p.x, y: p.y, w: p.w, h: p.h, open: 'rig' });A[side] = { x: p.bx, y: p.by };};
if (MB) {if (base.R) A.R = Object.assign({}, base.R);if (base.L) A.L = Object.assign({}, base.L);}
else if (gR) add(DGP.gripR, 'R');else if (bR) add(DGP.ballR, 'R');
if (!MB) {if (gL) add(DGP.gripL, 'L');else if (bL) add(DGP.ballL, 'L');}
// 上部に RSボールベース(UW_DG_TGPARTS.ballT:軸が真上の画像)。台座を上部の取付位置(seat)に載せ、ボール中心を上の取付点にする
if (!none && t.top === 'ballbase' && DGP.ballT) {
const p = DGP.ballT,st = DGP.seat[key],x = st.x - p.ax * p.w,y = st.y - p.ay * p.h;
layers.push({ src: p.src, x, y, w: p.w, h: p.h, open: 'top' });A.T = { x: x + p.bx * p.w, y: y + p.by * p.h };
}
const sp = DGP.shoe[t.shoeConv];
// RIG 使用時で上部に何も付いていないとき:上部の取付位置に「+」(押すとシューベースの画面)
if (!none && !A.T && !(sp && t.top === 'shoemount')) A.T = { x: DGP.seat[key].x, y: DGP.seat[key].y };
if (sp && (none || t.top === 'shoemount')) {
const st = DGP.seat[key],x = st.x - sp.ax * sp.w,y = st.y - sp.ay * sp.h;
layers.push({ src: sp.src, x, y, w: sp.w, h: sp.h, open: 'top' });A.T = { x: x + sp.tx * sp.w, y: y + sp.ty * sp.h };
}
// 正面:リングライト・レンズの画像(UW_DG_FRONT)。レンズ中心を (400,328) に合わせる
const fi = frontId && (window.UW_DG_FRONT || {})[frontId];
if (fi) { const x = 400 - fi.lx * fi.w,y = 328 - fi.ly * fi.h;layers.push({ src: fi.src, x, y, w: fi.w, h: fi.h, clip: fi.clip, open: t.ringLight ? 'ring' : 'lensTg' }); }
const bay = t.receiver && t.receiver !== 'screw';
const bayId = (L.indexOf(ED.BY_INCLUDED) >= 0 ? t.receiver === 'RS_BAYBASE' ? 'RS_BAYBASE' : ED.BY_BASE : t.receiver) || '';
const marker = fi || !frontId ? null : { label: t.ringLight ? 'RL1500' : T("レンズ"), open: t.ringLight ? 'ring' : 'lensTg', ring: false }; // バヨネットマウントベース(RS/FIX)は構成図に表示しない
return { layers, A, marker };
};
const tgMatch = (t) => { const k = tgKey(t);
return DGTG.find((e) => Object.keys(e.match).every((f) => e.match[f] === '*' || e.match[f] === k[f])) || null; };
const SHOE_ID = 'ACC_SHOE_BALLBASE2';
const SHOE_IMG = { x: 0.397, y: 0.097, w: 0.2317, h: 0.205, bx: 0.512, by: 0.15 };
const newB = () => ({ x0: 1e9, y0: 1e9, x1: -1e9, y1: -1e9 });
function bb(b, x, y, w = 0, h = 0) {b.x0 = Math.min(b.x0, x);b.y0 = Math.min(b.y0, y);b.x1 = Math.max(b.x1, x + w);b.y1 = Math.max(b.y1, y + h);}
/* 取付点つきのストロボ・ライト画像。split があるときは、本体(境目より上)だけを s 倍に縮小して、ベース(ボール・YS)はそのままの大きさで描く */
function LightImg({ a, src, x, y }) {
const w = a.w,h = a.h,sp = a.split;
if (!sp) return ;
const sy = sp.y,s = sp.s,px = x + sp.cx * w,py = y + sy * h;
return
;
}
function chain({ k, m, start, dir, floats, box, res, onOpen, noRect }) {
const out = [],clamps = [];
let x = start.x,y = start.y;
const up = k === 'T',ysTop = up && res.topMode === 'ys',pts = [{ x, y }];
m.arms.forEach((a, i) => {
const Ls = armLen(a);
const deg = up ? -90 : dir < 0 ? i % 2 ? 140 : -160 : i % 2 ? 40 : -20; // 上は真上、左右の2本目は斜め下
const th = deg * Math.PI / 180,vx = Math.cos(th),vy = Math.sin(th);
const cx = x + vx * Ls / 2,cy = y + vy * Ls / 2,s = Ls / 1.14,rot = deg + 52.3;
const am = rawFor(a, 'arm'); // アームごとの画像(S/M/L)。ボール中心 A→B がこの区間の両端にぴったり合うように、拡大・回転して置く
if (am && am.src && am.iw) {
const k = Ls / Math.hypot(am.bx - am.ax, am.by - am.ay),th0 = Math.atan2(am.by - am.ay, am.bx - am.ax) * 180 / Math.PI;
out.push( onOpen('arms')} />);
} else out.push( onOpen('arms')} />);
const fl = floats && floats[i];
if (fl && fl.length) {
const tot = fl.reduce((t, f) => t + ED.floatLen(f) * PX_MM + 2, -2);let px = -tot / 2;
out.push( onOpen('floats')}>
{fl.map((f, j) => {const l = ED.floatLen(f) * PX_MM,w = ((ED.U[f] || {}).float_width || 70) * PX_MM;const r = ;px += l + 2;return r;})}
);
}
x += vx * Ls;y += vy * Ls;pts.push({ x, y });bb(box, x - 20, y - 20, 40, 40);bb(box, cx - 24, cy - 24, 48, 48);
});
if (m.pid) {
const w = up ? 70 : 78,h = w * 166 / 168,bx = 0.32 * w,flip = dir < 0;
const lx = flip ? x - (w - bx) : x - bx,ly = y - h + 4;
const L = lightFor(m.pid, ysTop ? 'lightYs' : up ? 'lightTop' : 'lightSide'); // 新形式(取付点つき)か従来形式か
const flipV = !up && m.arms.length >= 1; // 左右でアームがあるときは、ボールの位置はそのままで上下反転(ボールの下にストロボ)
out.push( onOpen(ED.isStrobe(m.pid) ? 'strobe' : 'light')} transform={flipV ? `translate(0 ${2 * y}) scale(1 -1)` : undefined}>
{ysTop && !noRect && }
{L.a ? :
}
);
if (L.a) bb(box, x - L.a.ax * L.a.w - 4, (flipV ? y - (1 - L.a.ay) * L.a.h : y - L.a.ay * L.a.h) - 4, L.a.w + 8, L.a.h + 8);
else bb(box, Math.min(lx, 2 * x - lx - w), (flipV ? 2 * y - ly - h : ly) - 6, w + 10, h + 8);
} else {
out.push( onOpen('strobe')}>{T("+")});
bb(box, x - 20, y - 40, 40, 44);
}
const n = ED.mountUsed(m) ? ysTop ? m.arms.length : m.arms.length + (m.pid ? 1 : 0) : 0;
(ysTop ? pts.slice(1) : pts).slice(0, n).forEach((p, i) => clamps.push( onOpen('clamp')} />));
return {out}{clamps};
}
function Diagram({ st, res, onOpen }) {
const tg = st.system === 'tg',t = st.tg,M = res.st.mounts;
const B = { L: newB(), R: newB(), H: newB() },els = [],S = {};
const newHs = !tg && res.housing && DGI[res.housing.housing_id + ':housing'],hx = 250,hy = 230,hsc = !tg && newHs && newHs.src ? newHs : null,hs = tg ? 300 : hsc ? hsc.hs : newHs ? HS_ALPHA : HS_OLD; // hsc=取付点つきで登録したハウジング(Nikon/Canon など。diagram_images.js) // ハウジングの大きさ(ハンドルのボール基準)
const ptsa = tg && TG_SHOE_PARTS.includes(t.shoeConv) ? rawFor(t.shoeConv, 'shoeBase') : null,ptImg = ptsa && ptsa.src ? ptsa : null; // シュー部品の画像(登録がなければ従来の四角)
const tgm = tg ? tgMatch(t) : null,tgc = tg && !tgm ? tgCompose(t) : null; // 構成に合う完成写真(なければ null → 従来の模式図)
if (tgm || tgc) { // TG:完成写真(tgm)か、素材を重ねたもの(tgc)。写真のレンズ中心を模式図のレンズ位置(400,328)に合わせ、ボールの位置は写真から
if (tgm) {
const W = tgm.w,Hh = tgm.h,x0 = 400 - tgm.lx * W,y0 = 328 - tgm.ly * Hh;
els.push( onOpen(t.rig === 'none' ? 'camera' : 'rig')} />);
bb(B.H, x0, y0, W, Hh);
const P = (a, d) => a ? { x: x0 + a.x * W, y: y0 + a.y * Hh } : Object.assign({ none: true }, d);
S.R = P(tgm.R, { x: x0 + W - 10, y: y0 + 0.2 * Hh });S.L = P(tgm.L, { x: x0 + 10, y: y0 + 0.2 * Hh });
const seat = DGP && t.rig !== 'none' ? DGP.seat[t.rig === 'frame' && t.multi ? 'multi' : 'frame'] : null; // RIG の上部(完成写真に何も写っていないとき)
S.T = tgm.T ? P(tgm.T) : seat ? { x: seat.x, y: seat.y } : P(null, { x: 400, y: y0 + 4 });
} else {
tgc.layers.forEach((l, i) => {
if (l.clip) { const id = 'tgclip' + i; // 画像の一部(楕円)だけを使う
els.push( onOpen(l.open)}>{[].concat(l.clip).map((c, j) => c.rx ? : )}
);
} else els.push( onOpen(l.open)} transform={l.rot ? `rotate(${l.rot} ${l.rx} ${l.ry})` : undefined} />);
bb(B.H, l.x, l.y, l.w, l.h);});
const b0 = tgc.layers[0],D = (side, fx, fy) => tgc.A[side] ? Object.assign({}, tgc.A[side]) : { none: true, x: fx, y: fy };
S.R = D('R', b0.x + b0.w - 10, b0.y + 0.2 * b0.h);S.L = D('L', b0.x + 10, b0.y + 0.2 * b0.h);S.T = D('T', 400, b0.y + 4);
if (tgc.marker) els.push(tgc.marker.ring ? // バヨネットマウントベース:レンズの外側に黒いリング
onOpen(tgc.marker.open)}>
{tgc.marker.label} :
onOpen(tgc.marker.open)}>
{tgc.marker.label});
}
const hd = (window.UW_DG_HOLD || {})[tgHeld(t)]; // ホルダーで保持しているレンズ(レンズ中心の真上、フレーム上部)
if (hd) { const hx0 = 400 + hd.dx - hd.w / 2,hy0 = 328 + hd.dyb - hd.h;
els.push( onOpen('top')} />);bb(B.H, hx0, hy0, hd.w, hd.h); }
} else if (tg) {
const bx = 300,by = 250,bw = 200,bh = 130;
const fronts = (t.ringLight ? 1 : 0) + (t.lenses || []).length;
els.push( onOpen('camera')}>
PT-059);
els.push( onOpen(t.ringLight ? 'ring' : 'lensTg')}>
{fronts ? t.ringLight ? 'RL1500' : T("レンズ") : 'M52'});
bb(B.H, bx, by, bw, bh);S.T = { x: bx + bw / 2, y: by - 2 };
if (t.rig !== 'none') {
const fy = by + bh + 6,fx0 = bx - 90,fx1 = bx + bw + 90,grips = t.multi ? 2 : t.grips;
const gripR = grips >= 1,gripL = grips >= 2;
const ballR = !gripR && t.ballBase >= 1,ballL = !gripL && t.ballBase >= (gripR ? 1 : 2);
els.push( onOpen('rig')}>
{gripR && }
{gripL && }
{ballR && }
{ballL && }
);
bb(B.H, fx0, fy - 160, fx1 - fx0, 180);
S.R = { x: fx1 - 15, y: gripR ? fy - 158 : fy - 26, none: !gripR && !ballR };S.L = { x: fx0 + 15, y: gripL ? fy - 158 : fy - 26, none: !gripL && !ballL };
} else {S.R = { x: bx + bw + 10, y: by + 30, none: true };S.L = { x: bx - 10, y: by + 30, none: true };}
} else {
els.push( onOpen('camera')} />);
const hasPort = res.items.some((i) => i.group === T("レンズ・ポート") && ED.info(i.id).cat === 'port');
const pcx = hx + 0.52 * hs,pcy = hy + 0.57 * hs,ps = 0.42 * hs;
const portId = (res.items.find((i) => i.group === T("レンズ・ポート") && ED.info(i.id).cat === 'port') || {}).id;
const pm = hasPort ? rawFor(portId, 'port') : null,pNew = pm && pm.src && pm.w ? pm : null; // ポートは実物の大きさが決まっているので、ハウジングによらず同じ大きさ(ドームは直径ごとに違う)
const pw = pNew ? pNew.w * HS_ALPHA : 0,ph = pNew ? pNew.h * HS_ALPHA : 0;
els.push(pNew ? newHs ? onOpen('lens')} /> :
onOpen('lens')} /> :
hasPort ? onOpen('lens')} /> :
onOpen('lens')}>{T("+")});
bb(B.H, hx, hy + 0.2 * hs, hs, 0.62 * hs);
if (hsc) {S.R = { x: hx + hsc.R.x * hs, y: hy + hsc.R.y * hs };S.L = { x: hx + hsc.L.x * hs, y: hy + hsc.L.y * hs };S.T = { x: hx + hsc.T.x * hs, y: hy + hsc.T.y * hs };} else {
S.R = { x: hx + (newHs ? 0.883 : 0.9) * hs, y: hy + (newHs ? 0.285 : 0.28) * hs };S.L = { x: hx + (newHs ? 0.117 : 0.1) * hs, y: hy + (newHs ? 0.285 : 0.28) * hs };S.T = { x: hx + 0.52 * hs, y: hy + 0.3 * hs };}
}
// シューベース:使っていないときも「+」を表示(押すとシューベース/TGはシューベース、ミラーレスはストロボの「上に追加」)
if (tgm || tgc) { // 写真・素材にシュー部品が写っている。使っていないときは「+」だけ
if (!S.T.none && !ED.mountUsed(M.T) && t.top !== 'holder') { els.push( onOpen(t.rig !== 'none' && t.top !== 'shoemount' && t.top !== 'ballbase' && t.shoeConv === 'none' ? 'top' : 'strobeTop')}>+); bb(B.H, S.T.x - 20, S.T.y - 40, 40, 44); }
} else if (ED.mountUsed(M.T) || res.topMode) {
const p = S.T;
const sImg = !tg && ED.mountUsed(M.T) ? imgFor(SHOE_ID, 'shoeBall') : null;
if (ptImg) { // TG:シュー部品の画像。ハウジングのシューに載せ、ストロボ・アームは取付点(tx,ty)から
const px = p.x + (t.rig === 'none' ? TG_SHOE_DX : 0),w = ptImg.w,h = ptImg.h,ix = px - ptImg.ax * w,iy = p.y - ptImg.ay * h;
els.push( onOpen('top')} />);
bb(B.H, ix, iy, w, h);
S.T = { x: ix + ptImg.tx * w, y: iy + ptImg.ty * h };
} else if (sImg) { // ミラーレス:シューベースの画像を表示し、チェーンの始点をボール中心にする
const w = SHOE_IMG.w * hs, h = SHOE_IMG.h * hs, ix = hx + SHOE_IMG.x * hs, iy = hy + SHOE_IMG.y * hs;
els.push( onOpen('strobeTop')} />);
bb(B.H, ix, iy, w, h);
S.T = { x: hx + SHOE_IMG.bx * hs, y: hy + SHOE_IMG.by * hs };
} else {
els.push( onOpen(tg ? 'top' : 'strobeTop')} />);
S.T = { x: p.x, y: p.y - 16 };
}
if (!ED.mountUsed(M.T)) { els.push( onOpen('strobeTop')}>+); bb(B.H, S.T.x - 20, S.T.y - 40, 40, 44); }
} else {
const p = S.T;
els.push( onOpen(tg ? 'top' : 'strobeTop')}>
+);
bb(B.H, p.x - 20, p.y - 48, 40, 50);
}
let ai = 0;const fl = {};
ED.MOUNTS.forEach((k) => {fl[k] = M[k].arms.map(() => (res.floatAsg || [])[ai++] || []);});
['R', 'L', 'T'].forEach((k) => {
const m = M[k],box = k === 'T' ? B.H : B[k];
if (!ED.mountUsed(m)) {
if (k !== 'T' && !S[k].none) {els.push( onOpen('strobe')}>{T("+")});bb(box, S[k].x - 20, S[k].y - 40, 40, 44);}
return;
}
if (S[k].none) els.push();
bb(box, S[k].x - 10, S[k].y - 10, 20, 20);
els.push({chain({ k, m, start: S[k], dir: k === 'L' ? -1 : 1, floats: fl[k], box, res, onOpen, noRect: !!ptImg || !!tgm || !!tgc })});
});
// 表示範囲:全体は余白を大きめに取り、小さく全体が見えるように
const U0 = newB();[B.L, B.R, B.H].forEach((b) => {if (b.x0 < 1e9) {bb(U0, b.x0, b.y0);bb(U0, b.x1, b.y1);}});
const vb = (b, pad) => {
if (b.x0 >= 1e9) return null;
let w = b.x1 - b.x0 + pad * 2,h = b.y1 - b.y0 + pad * 2;const cx = (b.x0 + b.x1) / 2,cy = (b.y0 + b.y1) / 2;
const ar = 2.1;if (w / h < ar) w = h * ar;else h = w / ar; // 横長に揃える
return `${cx - w / 2} ${cy - h / 2} ${w} ${h}`;
};
const box = vb(U0, 50) || '0 0 800 380';
return (
);
}
Object.assign(window, { Diagram });