"""Charging path diagram: top view of tray front (left) + side section (right)."""
S = 3.0
# ---- top view: X -50..50 (mm) -> px, Y 0..60 front at bottom
TX, TY = 60, 40
def t(x, y): return TX + (x + 50) * S, TY + (60 - y) * S
def trect(x0, x1, y0, y1, cls, rx=0):
    ax, ay = t(x0, y1); bx, by = t(x1, y0)
    return f'<rect x="{ax:.1f}" y="{ay:.1f}" width="{bx-ax:.1f}" height="{by-ay:.1f}" rx="{rx}" class="{cls}"/>'
def tpath(pts, cls):
    return '<path d="' + " ".join(("M" if i == 0 else "L") + "%.1f %.1f" % t(*p) for i, p in enumerate(pts)) + f'" class="{cls}"/>'
def tcirc(x, y, r, cls):
    cx, cy = t(x, y); return f'<circle cx="{cx:.1f}" cy="{cy:.1f}" r="{r}" class="{cls}"/>'
def txt(x, y, s, cls="d-s", anchor="start"):
    return f'<text x="{x:.1f}" y="{y:.1f}" class="{cls}" text-anchor="{anchor}">{s}</text>'

o = [txt(TX, 24, "俯视 · 托盘前端 60 mm（手机槽内）", "d-t")]
o += [
    trect(-55, 55, -2, 0, "p-dark"),                 # tray face lip
    trect(-48, 48, 0, 60, "p-tray", 3),
    trect(-40, 40, 6, 60, "p-pocket", 4),
    trect(-40, -8, 2, 6, "p-small"), trect(8, 40, 2, 6, "p-small"),   # 卡托 front bar with gap
    trect(-42, -38, 6, 60, "p-small"), trect(38, 42, 6, 60, "p-small"),
    trect(-37.5, 37.5, 7, 60, "p-mod", 3),           # phone
    trect(-4.5, 4.5, 7, 9.5, "p-dark"),              # port
    trect(-7, 7, 1.5, 6.5, "p-bracket", 1),          # cradle
    trect(-4, 4, 2, 8, "p-dark", 1),                 # plug
    tpath([(4, 4.5), (20, 4.5), (20, 9)], "p-fpc"),
    trect(18, 22, 8, 10.5, "p-dark"),                # slot
    trect(14, 26, 8, 20, "p-conn", 1),               # pads (underside)
]
o += [tcirc(x, y, 3.2, "p-lens") for x, y in ((17.5, 11), (22.5, 11), (17.5, 17), (22.5, 17))]
# labels (top view)
def lead(p_mm, px_to, s):
    x0, y0 = t(*p_mm)
    return f'<path d="M{x0:.1f} {y0:.1f} L{px_to[0]:.1f} {px_to[1]:.1f}" class="d-a"/>' + txt(px_to[0] + 4, px_to[1] + 4, s)
o += [
    lead((0, 40), (TX + 310, TY + 40), "手机，屏幕朝上、充电口朝前"),
    lead((0, 8), (TX + 310, TY + 100), "充电口"),
    lead((-4, 4), (TX - 50, TY + 120), ""),
    txt(TX - 52, TY + 140, "USB-C 插头停在卡座里，", "d-s", "end"),
    txt(TX - 52, TY + 156, "放手机时插进去", "d-s", "end"),
    lead((12, 4.5), (TX + 310, TY + 150), "短线约 25 mm，藏在卡托前条后面的线槽"),
    lead((20, 9), (TX + 310, TY + 176), "从槽口穿到托盘底面"),
    lead((26, 14), (TX + 310, TY + 200), "铜片 ×2（托盘底面，虚线位置）"),
    lead((22.5, 17), (TX + 310, TY + 224), "弹簧顶针 ×4（在底壳，托盘锁住才顶上）"),
    lead((40, 4), (TX + 310, TY + 250), "卡托前条，中间留 16 mm 缺口给插头"),
    txt(TX + 20, TY + 60 * S + 22, "← 托盘进出方向 →", "d-l"),
]

# ---- side section: horizontal = Y (front at left), vertical = Z
OX, OY = 480, 270
def s_(y, z): return OX + (y + 10) * S, OY - z * S
def srect(y0, y1, z0, z1, cls, rx=0):
    ax, ay = s_(y0, z1); bx, by = s_(y1, z0)
    return f'<rect x="{ax:.1f}" y="{ay:.1f}" width="{bx-ax:.1f}" height="{by-ay:.1f}" rx="{rx}" class="{cls}"/>'
def spath(pts, cls):
    return '<path d="' + " ".join(("M" if i == 0 else "L") + "%.1f %.1f" % s_(*p) for i, p in enumerate(pts)) + f'" class="{cls}"/>'
o += [txt(OX, 24, "侧剖面 · 托盘锁住时", "d-t")]
o += [
    srect(-10, 70, 0, 3, "p-house"),                  # bottom shell floor
    srect(-10, -7, 0, 13, "p-house"), srect(-10, -7, 31, 60, "p-house"),   # front panel with opening
    srect(8, 20, 3, 9, "p-dark"),                     # pogo block
    srect(9.5, 11, 9, 14.7, "p-lens"), srect(15.5, 17, 9, 14.7, "p-lens"),
    srect(8, 20, 14.6, 15.2, "p-conn"),               # pads
    srect(0, 70, 15, 18, "p-tray"),                   # tray floor
    srect(-2, 0, 13, 31, "p-dark"),                   # tray face
    srect(2, 6, 18, 24, "p-small"),                   # cradle
    srect(7, 70, 18, 26, "p-mod"),                    # phone
    srect(3, 9, 20, 24, "p-dark"),                    # plug into port
    spath([(5, 20), (5, 18.5), (18, 18.5), (19, 15.3)], "p-fpc"),
]
def slead(p, px_to, s, anchor="start"):
    x0, y0 = s_(*p)
    return f'<path d="M{x0:.1f} {y0:.1f} L{px_to[0]:.1f} {px_to[1]:.1f}" class="d-a"/>' + txt(px_to[0] + (4 if anchor == "start" else -4), px_to[1] + 4, s, "d-s", anchor)
o += [
    slead((-8.5, 22), (OX - 40, OY - 120), "前面板开口 19 mm，", "end"),
    txt(OX - 44, OY - 100, "托盘面板盖住", "d-s", "end"),
    slead((40, 22), (OX + 250, OY - 110), "手机"),
    slead((6, 22), (OX + 250, OY - 80), "插头高度 = 充电口高度，随卡托换"),
    slead((40, 16.5), (OX + 250, OY - 50), "托盘底 3 mm"),
    slead((14, 15), (OX + 250, OY - 28), "铜片，镀镍"),
    slead((16, 11), (OX + 250, OY - 6), "顶针压缩约 1.5 mm，只在锁住时接触"),
    slead((40, 1.5), (OX + 250, OY + 20), "底壳，5 V 从集线板经 W7 到顶针座"),
    txt(OX + 10, OY + 44, "托盘弹出时顶针和铜片分开，手机那一路自动断电", "d-l"),
]
svg = '<svg viewBox="0 0 780 330" role="img" aria-label="充电插头和短线的走线示意">' + "".join(o) + "</svg>"
open("/tmp/claude-0/charge.svg", "w").write(svg)
print(len(svg))
