compasso 0.1.0 → 0.2.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 (55) hide show
  1. package/README.md +63 -8
  2. package/dist/{chunk-E456YKAJ.js → chunk-5B453C4P.js} +40 -10
  3. package/dist/chunk-5B453C4P.js.map +1 -0
  4. package/dist/{chunk-5RRRE2GF.js → chunk-5PGOL2KR.js} +3 -3
  5. package/dist/{chunk-5RRRE2GF.js.map → chunk-5PGOL2KR.js.map} +1 -1
  6. package/dist/{chunk-L5CYESBI.js → chunk-EHQMKVDM.js} +3 -3
  7. package/dist/{chunk-L5CYESBI.js.map → chunk-EHQMKVDM.js.map} +1 -1
  8. package/dist/chunk-P2S7AUOL.js +703 -0
  9. package/dist/chunk-P2S7AUOL.js.map +1 -0
  10. package/dist/chunk-TP3JOOJW.js +252 -0
  11. package/dist/chunk-TP3JOOJW.js.map +1 -0
  12. package/dist/core/index.cjs +44 -7
  13. package/dist/core/index.cjs.map +1 -1
  14. package/dist/core/index.d.cts +30 -30
  15. package/dist/core/index.d.ts +30 -30
  16. package/dist/core/index.js +1 -1
  17. package/dist/ecomap/index.cjs +11 -7
  18. package/dist/ecomap/index.cjs.map +1 -1
  19. package/dist/ecomap/index.js +2 -2
  20. package/dist/fault-tree/index.cjs +782 -0
  21. package/dist/fault-tree/index.cjs.map +1 -0
  22. package/dist/fault-tree/index.d.cts +148 -0
  23. package/dist/fault-tree/index.d.ts +148 -0
  24. package/dist/fault-tree/index.js +4 -0
  25. package/dist/fault-tree/index.js.map +1 -0
  26. package/dist/fishbone/index.cjs +314 -0
  27. package/dist/fishbone/index.cjs.map +1 -0
  28. package/dist/fishbone/index.d.cts +91 -0
  29. package/dist/fishbone/index.d.ts +91 -0
  30. package/dist/fishbone/index.js +4 -0
  31. package/dist/fishbone/index.js.map +1 -0
  32. package/dist/genogram/index.cjs +11 -7
  33. package/dist/genogram/index.cjs.map +1 -1
  34. package/dist/genogram/index.d.cts +3 -2
  35. package/dist/genogram/index.d.ts +3 -2
  36. package/dist/genogram/index.js +2 -2
  37. package/dist/index.cjs +1040 -36
  38. package/dist/index.cjs.map +1 -1
  39. package/dist/index.d.cts +6 -1
  40. package/dist/index.d.ts +6 -1
  41. package/dist/index.js +5 -3
  42. package/dist/labels-CYbM5XV7.d.cts +83 -0
  43. package/dist/labels-CYbM5XV7.d.ts +83 -0
  44. package/dist/locales/pt-br.cjs +36 -0
  45. package/dist/locales/pt-br.cjs.map +1 -1
  46. package/dist/locales/pt-br.d.cts +6 -1
  47. package/dist/locales/pt-br.d.ts +6 -1
  48. package/dist/locales/pt-br.js +34 -1
  49. package/dist/locales/pt-br.js.map +1 -1
  50. package/dist/text-DuO_PwYw.d.cts +45 -0
  51. package/dist/text-DuO_PwYw.d.ts +45 -0
  52. package/dist/xml-DDae1eUr.d.cts +4 -0
  53. package/dist/xml-DDae1eUr.d.ts +4 -0
  54. package/package.json +70 -18
  55. package/dist/chunk-E456YKAJ.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/genogram/types.ts","../src/genogram/labels.ts","../src/genogram/kinship.ts","../src/genogram/layout.ts","../src/genogram/svg.ts","../src/genogram/render.ts"],"names":[],"mappings":";;;AA0BO,IAAM,cAAA,GAAiB;AAAA,EAC5B,SAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF;;;ACpBO,IAAM,wBAAA,GAAgD;AAAA,EAC3D,WAAA,EAAa;AAAA,IACX,OAAA,EAAS,SAAA;AAAA,IACT,UAAA,EAAY,YAAA;AAAA,IACZ,MAAA,EAAQ,QAAA;AAAA,IACR,SAAA,EAAW,WAAA;AAAA,IACX,QAAA,EAAU,UAAA;AAAA,IACV,UAAA,EAAY,6BAAA;AAAA,IACZ,OAAA,EAAS;AAAA,GACX;AAAA,EACA,SAAA,EAAW;AACb;AAYO,IAAM,sBAAA,GAA4C;AAAA,EACvD,MAAA,EAAQ;AAAA,IACN,MAAA,EAAQ,KAAA;AAAA,IACR,MAAA,EAAQ,OAAA;AAAA,IACR,OAAA,EAAS;AAAA,GACX;AAAA,EACA,QAAA,EAAU,UAAA;AAAA,EACV,UAAA,EAAY;AAAA,IACV,KAAA,EAAO,OAAA;AAAA,IACP,OAAA,EAAS,SAAA;AAAA,IACT,QAAA,EAAU,aAAA;AAAA,IACV,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,QAAA,EAAU,sBAAA;AAAA,EACV,SAAA,EAAW;AACb;;;ACnBO,IAAM,UAAA,GAA6B;AAAA,EACxC,OAAA,sBAAa,GAAA,CAAI;AAAA,IACf,SAAA;AAAA,IAAW,UAAA;AAAA,IAAY,QAAA;AAAA,IAAU,SAAA;AAAA,IAAW,SAAA;AAAA,IAAW,UAAA;AAAA,IACvD,aAAA;AAAA,IAAe,aAAA;AAAA,IAAe,SAAA;AAAA,IAAW,SAAA;AAAA,IAAW,QAAA;AAAA,IAAU,SAAA;AAAA,IAC9D,UAAA;AAAA,IAAY,aAAA;AAAA,IAAe,cAAA;AAAA,IAC3B,UAAA;AAAA,IAAY,eAAA;AAAA,IAAiB,YAAA;AAAA,IAAc,eAAA;AAAA,IAC3C,OAAA;AAAA,IAAS,QAAA;AAAA,IAAU,MAAA;AAAA,IAAQ,OAAA;AAAA,IAAS,QAAA;AAAA,IACpC,QAAA;AAAA,IAAU,SAAA;AAAA,IACV,QAAA;AAAA,IAAU,SAAA;AAAA,IAAW,OAAA;AAAA,IAAS;AAAA,GAC/B,CAAA;AAAA,EACD,SAAA,sBAAe,GAAA,CAAI;AAAA,IACjB,QAAA;AAAA,IAAU,SAAA;AAAA,IAAW,KAAA;AAAA,IAAO,KAAA;AAAA,IAAO,QAAA;AAAA,IAAU,SAAA;AAAA,IAAW,KAAA;AAAA,IACxD,QAAA;AAAA,IAAU,SAAA;AAAA,IACV,KAAA;AAAA,IAAO,MAAA;AAAA,IAAQ,UAAA;AAAA,IAAY;AAAA,GAC5B,CAAA;AAAA,EACD,UAAA,sBAAgB,GAAA,CAAI,CAAC,OAAO,MAAA,EAAQ,UAAA,EAAY,WAAW,CAAC;AAC9D;AAGO,SAAS,uBAAuB,IAAA,EAAwB;AAC7D,EAAA,OAAO,aAAA,CAAc,IAAI,CAAA,CAAE,KAAA,CAAM,YAAY,EAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,KAAM,EAAE,CAAA;AACvE;AAQO,SAAS,wBAAA,CACd,IAAA,EACA,OAAA,GAA0B,UAAA,EACJ;AACtB,EAAA,MAAM,IAAA,GAAO,uBAAuB,IAAI,CAAA;AACxC,EAAA,IAAI,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,KAAM,OAAA,CAAQ,QAAQ,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,OAAO,SAAA;AACrD,EAAA,IAAI,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,KAAM,OAAA,CAAQ,UAAU,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,OAAO,WAAA;AACvD,EAAA,OAAO,MAAA;AACT;;;ACHO,IAAM,SAAA,GAAY;AACzB,IAAM,OAAA,GAAU,EAAA;AAEhB,IAAM,OAAA,GAAU,EAAA;AAEhB,IAAM,aAAA,GAAgB,CAAA;AAEtB,IAAM,aAAA,GAAgB,EAAA;AAEtB,IAAM,MAAA,GAAS,CAAA;AAGf,IAAM,aAAA,GAAgB,EAAA;AAGtB,IAAM,UAAA,GAAa,EAAA;AAEnB,IAAM,wBAAwB,CAAA,GAAI,OAAA;AAI3B,IAAM,UAAA,GAAa;AAEnB,IAAM,YAAA,GAAe;AAErB,IAAM,SAAA,GAAY;AAUlB,IAAM,iBAAA,GAAoB;AAC1B,IAAM,kBAAA,GAAqB;AAC3B,IAAM,oBAAA,GAAuB;AAGpC,SAAS,YAAY,GAAA,EAA2B;AAC9C,EAAA,IAAI,GAAA,KAAQ,QAAQ,OAAO,QAAA;AAC3B,EAAA,IAAI,GAAA,KAAQ,UAAU,OAAO,QAAA;AAC7B,EAAA,OAAO,SAAA;AACT;AA2BA,SAAS,cAAc,YAAA,EAAgC;AACrD,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,KAAK,GAAA,CAAI,EAAA,EAAI,IAAA,CAAK,IAAA,CAAK,YAAA,CAAa,MAAA,GAAS,CAAC,CAAA,GAAI,CAAC,CAAC,CAAA;AACjF,EAAA,OAAO,SAAA,CAAU,cAAc,OAAO,CAAA;AACxC;AAGA,SAAS,UAAA,CAAW,OAAe,QAAA,EAAsC;AACvE,EAAA,IAAI,QAAA,KAAa,MAAA,IAAa,KAAA,CAAM,MAAA,IAAU,UAAU,OAAO,KAAA;AAC/D,EAAA,OAAO,KAAA,CAAM,MAAM,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAG,QAAA,GAAW,CAAC,CAAC,CAAA,GAAI,QAAA;AACrD;AA6HA,IAAM,eAAe,CAAC,CAAA,EAAG,IAAI,EAAA,EAAI,GAAA,EAAK,IAAI,GAAG,CAAA;AAE7C,IAAM,YAAA,GAAe,YAAY,CAAA,GAAI,CAAA;AAErC,SAAS,WAAW,IAAA,EAAsB;AACxC,EAAA,OAAO,aAAa,IAAA,CAAK,GAAA,CAAI,MAAM,YAAA,CAAa,MAAA,GAAS,CAAC,CAAC,CAAA;AAC7D;AAIA,SAAS,aAAA,CAAc,MAAc,KAAA,EAAuB;AAC1D,EAAA,IAAI,IAAA,KAAS,CAAA,IAAK,KAAA,IAAS,CAAA,EAAG,OAAO,CAAA;AACrC,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,eAAe,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAA,CAAA,CAAM,KAAA,GAAQ,CAAA,IAAK,CAAC,CAAC,CAAC,CAAA;AAChF,EAAA,MAAM,IAAA,GAAO,IAAA,GAAO,CAAA,KAAM,CAAA,GAAI,EAAA,GAAK,CAAA;AACnC,EAAA,OAAO,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,IAAA,GAAO,CAAC,CAAA,GAAI,IAAA;AACtC;AAIA,SAAS,cAAc,KAAA,EAA0E;AAC/F,EAAA,MAAM,QAAwC,EAAC;AAC/C,EAAA,KAAA,MAAW,MAAM,KAAA,EAAO;AACtB,IAAA,IAAI,MAAA,GAAS,EAAA;AACb,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,MAAA,IAAI,KAAA,CAAM,CAAC,CAAA,CAAG,KAAA,CAAM,CAAC,CAAA,KAAM,EAAA,CAAG,EAAA,IAAM,CAAA,CAAE,EAAA,IAAM,EAAA,CAAG,EAAA,IAAM,CAAA,CAAE,EAAE,CAAA,EAAG;AAC1D,QAAA,MAAA,GAAS,CAAA;AACT,QAAA;AAAA,MACF;AAAA,IACF;AACA,IAAA,IAAI,WAAW,EAAA,EAAI;AACjB,MAAA,MAAA,GAAS,KAAA,CAAM,MAAA;AACf,MAAA,KAAA,CAAM,IAAA,CAAK,EAAE,CAAA;AAAA,IACf;AACA,IAAA,KAAA,CAAM,MAAM,CAAA,CAAG,IAAA,CAAK,EAAE,EAAA,EAAI,GAAG,EAAA,EAAI,EAAA,EAAI,EAAA,CAAG,EAAA,EAAI,CAAA;AAC5C,IAAA,EAAA,CAAG,IAAI,MAAM,CAAA;AAAA,EACf;AACA,EAAA,OAAO,KAAA,CAAM,MAAA;AACf;AAyBO,SAAS,sBACd,MAAA,EACA,MAAA,EACA,aACA,aAAA,EACA,IAAA,GAA8B,EAAC,EACf;AAChB,EAAA,MAAM,OAAA,GAAU,KAAK,OAAA,IAAW,UAAA;AAChC,EAAA,MAAM,WAAA,GAAc,KAAK,WAAA,IAAe,wBAAA;AACxC,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,IAAA,OAAO,EAAE,KAAA,EAAO,OAAA,GAAU,CAAA,EAAG,QAAQ,OAAA,GAAU,CAAA,EAAG,KAAA,EAAO,IAAI,QAAA,EAAU,EAAC,EAAG,iBAAA,EAAmB,EAAC,EAAE;AAAA,EACnG;AAEA,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,MAAA,CAAO,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AAC3C,EAAA,MAAM,OAAA,GAAU,CAAC,CAAA,EAAW,CAAA,KAAsB,GAAG,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AACrF,EAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAA2B,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,EAAA,EAAI,CAAA,CAAE,UAAU,CAAC,CAAC,CAAA;AAGtF,EAAA,MAAM,WAAA,GAAc,MAAA,CACjB,MAAA,CAAO,CAAC,CAAA,KAAM,GAAA,CAAI,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA,IAAK,GAAA,CAAI,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA,IAAK,CAAA,CAAE,SAAA,KAAc,CAAA,CAAE,SAAS,CAAA,CACzF,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,EAAA,GAAK,CAAA,CAAE,EAAE,CAAA;AAC7B,EAAA,MAAM,eAAe,WAAA,CAAY,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,YAAY,CAAA;AACxE,EAAA,MAAM,UAAA,GAAa,WAAA,CAChB,MAAA,CAAO,CAAC,CAAA,KAAM,GAAA,CAAI,GAAA,CAAI,CAAA,CAAE,QAAQ,CAAA,IAAK,GAAA,CAAI,GAAA,CAAI,CAAA,CAAE,OAAO,CAAA,IAAK,CAAA,CAAE,QAAA,KAAa,CAAA,CAAE,OAAO,CAAA,CACnF,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,EAAA,GAAK,CAAA,CAAE,EAAE,CAAA;AAC7B,EAAA,MAAM,SAAA,GAAY,aAAA,CACf,MAAA,CAAO,CAAC,CAAA,KAAM,GAAA,CAAI,GAAA,CAAI,CAAA,CAAE,YAAY,CAAA,IAAK,GAAA,CAAI,GAAA,CAAI,CAAA,CAAE,UAAU,CAAA,IAAK,CAAA,CAAE,YAAA,KAAiB,CAAA,CAAE,UAAU,CAAA,CACjG,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,EAAA,GAAK,CAAA,CAAE,EAAE,CAAA;AAS7B,EAAA,MAAM,WAAW,IAAI,GAAA;AAAA,IACnB,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,EAAA,EAAI,wBAAA,CAAyB,CAAA,CAAE,IAAA,EAAM,OAAO,CAAC,CAAC;AAAA,GACxE;AACA,EAAA,MAAM,QAAA,GAAW,SAAA,CAAU,MAAA,CAAO,CAAC,CAAA,KAAM,SAAS,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA,KAAM,MAAM,CAAA;AACtE,EAAA,MAAM,aAAA,GAAgB,SAAA,CAAU,MAAA,CAAO,CAAC,CAAA,KAAM,SAAS,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA,KAAM,WAAW,CAAA;AAGhF,EAAA,MAAM,SAAA,GAA0B,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,IACrD,UAAU,CAAA,CAAE,QAAA;AAAA,IACZ,SAAS,CAAA,CAAE,OAAA;AAAA,IACX,SAAS,CAAA,CAAE,OAAA;AAAA,IACX,MAAA,EAAQ,qBAAqB,CAAA,CAAE;AAAA,GACjC,CAAE,CAAA;AACF,EAAA,MAAM,aAAA,GAAgB,IAAI,GAAA,CAAI,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,KAAM,OAAA,CAAQ,CAAA,CAAE,QAAA,EAAU,CAAA,CAAE,OAAO,CAAC,CAAC,CAAA;AACnF,EAAA,MAAM,cAAA,uBAAqB,GAAA,EAAwB;AACnD,EAAA,KAAA,MAAW,KAAK,aAAA,EAAe;AAC7B,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,CAAA,CAAE,YAAA,EAAc,EAAE,UAAU,CAAA;AAChD,IAAA,IAAI,aAAA,CAAc,GAAA,CAAI,GAAG,CAAA,EAAG;AAC5B,IAAA,IAAI,cAAA,CAAe,GAAA,CAAI,GAAG,CAAA,EAAG;AAK7B,IAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,YAAY,CAAA,IAAK,IAAA;AAC1C,IAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,UAAU,CAAA,IAAK,IAAA;AACxC,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI,EAAA,KAAO,IAAA,IAAQ,EAAA,KAAO,IAAA,IAAQ,OAAO,EAAA,EAAI;AAC3C,MAAA,CAAC,QAAA,EAAU,OAAO,CAAA,GAAI,EAAA,GAAK,KAAK,CAAC,CAAA,CAAE,YAAA,EAAc,CAAA,CAAE,UAAU,CAAA,GAAI,CAAC,CAAA,CAAE,UAAA,EAAY,EAAE,YAAY,CAAA;AAAA,IAChG,CAAA,MAAO;AACL,MAAA,MAAM,WAAA,GAAc,sBAAA,CAAuB,CAAA,CAAE,IAAI,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,KAAM,OAAA,CAAQ,UAAA,CAAW,GAAA,CAAI,CAAC,CAAC,CAAA;AACxF,MAAA,CAAC,QAAA,EAAU,OAAO,CAAA,GAAI,WAAA,GAAc,CAAC,CAAA,CAAE,UAAA,EAAY,CAAA,CAAE,YAAY,CAAA,GAAI,CAAC,CAAA,CAAE,YAAA,EAAc,EAAE,UAAU,CAAA;AAAA,IACpG;AACA,IAAA,IAAI,aAAa,OAAA,EAAS;AAC1B,IAAA,cAAA,CAAe,GAAA,CAAI,GAAA,EAAK,EAAE,QAAA,EAAU,OAAA,EAAS,OAAA,EAAS,CAAA,CAAE,OAAA,EAAS,MAAA,EAAQ,oBAAA,GAAuB,CAAA,CAAE,EAAA,EAAI,CAAA;AAAA,EACxG;AACA,EAAA,MAAM,WAAyB,CAAC,GAAG,SAAA,EAAW,GAAG,eAAe,MAAA,EAAQ,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,MAAA,GAAS,EAAE,MAAM,CAAA;AAG5G,EAAA,MAAM,YAAA,uBAAmB,GAAA,EAAmB;AAC5C,EAAA,KAAA,MAAW,CAAA,IAAK,YAAA,EAAc,YAAA,CAAa,GAAA,CAAI,OAAA,CAAQ,EAAE,SAAA,EAAW,CAAA,CAAE,SAAS,CAAA,EAAG,CAAC,CAAA;AAGnF,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAsB;AAC5C,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAwB;AAC3C,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,MAAM,MAAM,SAAA,CAAU,GAAA,CAAI,CAAA,CAAE,OAAO,KAAK,EAAC;AACzC,IAAA,IAAI,CAAC,IAAI,QAAA,CAAS,CAAA,CAAE,QAAQ,CAAA,EAAG,GAAA,CAAI,IAAA,CAAK,CAAA,CAAE,QAAQ,CAAA;AAClD,IAAA,SAAA,CAAU,GAAA,CAAI,CAAA,CAAE,OAAA,EAAS,GAAG,CAAA;AAC5B,IAAA,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA,CAAE,QAAQ,IAAI,CAAA,CAAE,OAAO,IAAI,CAAC,CAAA;AAAA,EAC5C;AAMA,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAY;AAC/B,EAAA,KAAA,MAAW,KAAK,WAAA,EAAa;AAC3B,IAAA,MAAA,CAAO,GAAA,CAAI,EAAE,SAAS,CAAA;AACtB,IAAA,MAAA,CAAO,GAAA,CAAI,EAAE,SAAS,CAAA;AAAA,EACxB;AACA,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,MAAA,CAAO,GAAA,CAAI,EAAE,QAAQ,CAAA;AACrB,IAAA,MAAA,CAAO,GAAA,CAAI,EAAE,OAAO,CAAA;AAAA,EACtB;AACA,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,MAAA,CAAO,GAAA,CAAI,EAAE,YAAY,CAAA;AACzB,IAAA,MAAA,CAAO,GAAA,CAAI,EAAE,UAAU,CAAA;AAAA,EACzB;AACA,EAAA,MAAM,aAAa,CAAC,EAAA,KAAwB,CAAC,MAAA,CAAO,IAAI,EAAE,CAAA;AAG1D,EAAA,MAAM,KAAA,uBAAY,GAAA,EAA6B;AAC/C,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,GAAA,CAAI,CAAA,CAAE,UAAU,CAAA;AACrC,IAAA,IAAI,MAAA,KAAW,QAAW,KAAA,CAAM,GAAA,CAAI,EAAE,UAAA,EAAY,CAAC,CAAC,CAAC,CAAA;AAAA,SAChD,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,EACpB;AACA,EAAA,MAAM,OAAA,GAAU,CAAC,GAAG,KAAA,CAAM,IAAA,EAAM,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM;AAC/C,IAAA,IAAI,CAAA,KAAM,MAAM,OAAO,CAAA;AACvB,IAAA,IAAI,CAAA,KAAM,MAAM,OAAO,EAAA;AACvB,IAAA,OAAO,CAAA,GAAI,CAAA;AAAA,EACb,CAAC,CAAA;AACD,EAAA,MAAM,WAAW,OAAA,CAAQ,MAAA;AACzB,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAAoB;AAC5C,EAAA,OAAA,CAAQ,QAAQ,CAAC,CAAA,EAAG,CAAA,KAAM,KAAA,CAAM,IAAI,CAAC,CAAA,CAAG,OAAA,CAAQ,CAAC,MAAM,WAAA,CAAY,GAAA,CAAI,EAAE,EAAA,EAAI,CAAC,CAAC,CAAC,CAAA;AAKhF,EAAA,MAAM,SAAA,GAAuB,OAAA,CAAQ,GAAA,CAAI,CAAC,GAAG,CAAA,KAAM;AACjD,IAAA,MAAM,OAAA,GAAU,MAAM,GAAA,CAAI,CAAC,EAAG,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAA;AAE7C,IAAA,MAAM,GAAA,uBAAU,GAAA,EAAsB;AACtC,IAAA,KAAA,MAAW,MAAM,OAAA,EAAS,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,EAAE,CAAA;AACxC,IAAA,KAAA,MAAW,KAAK,YAAA,EAAc;AAC5B,MAAA,IAAI,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA,KAAM,CAAA,IAAK,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA,KAAM,CAAA,EAAG;AAC5E,QAAA,GAAA,CAAI,IAAI,CAAA,CAAE,SAAS,CAAA,CAAG,IAAA,CAAK,EAAE,SAAS,CAAA;AACtC,QAAA,GAAA,CAAI,IAAI,CAAA,CAAE,SAAS,CAAA,CAAG,IAAA,CAAK,EAAE,SAAS,CAAA;AAAA,MACxC;AAAA,IACF;AACA,IAAA,KAAA,MAAW,EAAA,IAAM,OAAA,EAAS,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA,CAAG,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,CAAC,CAAA;AAE3D,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,IAAA,MAAM,SAAkB,EAAC;AACzB,IAAA,KAAA,MAAW,KAAA,IAAS,CAAC,GAAG,OAAO,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,CAAC,CAAA,EAAG;AACtD,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,EAAG;AACrB,MAAA,MAAM,OAAiB,EAAC;AACxB,MAAA,MAAM,KAAA,GAAQ,CAAC,KAAK,CAAA;AACpB,MAAA,IAAA,CAAK,IAAI,KAAK,CAAA;AACd,MAAA,OAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACvB,QAAA,MAAM,CAAA,GAAI,MAAM,GAAA,EAAI;AACpB,QAAA,IAAA,CAAK,KAAK,CAAC,CAAA;AACX,QAAA,KAAA,MAAW,CAAA,IAAK,GAAA,CAAI,GAAA,CAAI,CAAC,CAAA,MAAQ,CAAC,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG;AAAE,UAAA,IAAA,CAAK,IAAI,CAAC,CAAA;AAAG,UAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,QAAG;AAAA,MAC/E;AACA,MAAA,MAAA,CAAO,IAAA,CAAK,cAAA,CAAe,IAAA,EAAM,GAAG,CAAC,CAAA;AAAA,IACvC;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAC,CAAA;AAID,EAAA,MAAM,YAAY,MAA2B;AAC3C,IAAA,MAAM,GAAA,uBAAU,GAAA,EAAoB;AACpC,IAAA,KAAA,MAAW,UAAU,SAAA,EAAW;AAC9B,MAAA,IAAI,CAAA,GAAI,CAAA;AACR,MAAA,KAAA,MAAW,CAAA,IAAK,QAAQ,KAAA,MAAW,EAAA,IAAM,GAAG,GAAA,CAAI,GAAA,CAAI,IAAI,CAAA,EAAG,CAAA;AAAA,IAC7D;AACA,IAAA,OAAO,GAAA;AAAA,EACT,CAAA;AACA,EAAA,MAAM,mBAAA,GAAsB,CAAC,EAAA,KAAyB;AACpD,IAAA,MAAM,MAAmC,EAAC;AAG1C,IAAA,KAAA,MAAW,KAAK,YAAA,EAAc;AAC5B,MAAA,IAAI,CAAA,CAAE,SAAA,KAAc,EAAA,EAAI,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,CAAA,CAAE,SAAA,EAAW,CAAA,EAAG,CAAA,EAAG,CAAA;AAAA,WAAA,IACjD,CAAA,CAAE,SAAA,KAAc,EAAA,EAAI,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,CAAA,CAAE,SAAA,EAAW,CAAA,EAAG,CAAA,EAAG,CAAA;AAAA,IACjE;AACA,IAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,MAAA,IAAI,CAAA,CAAE,OAAA,KAAY,EAAA,EAAI,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,CAAA,CAAE,QAAA,EAAU,CAAA,EAAG,CAAA,EAAG,CAAA;AAAA,WAAA,IAC9C,CAAA,CAAE,QAAA,KAAa,EAAA,EAAI,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,CAAA,CAAE,OAAA,EAAS,CAAA,EAAG,CAAA,EAAG,CAAA;AAAA,IAC9D;AACA,IAAA,KAAA,MAAW,MAAM,QAAA,EAAU;AACzB,MAAA,IAAI,EAAA,CAAG,YAAA,KAAiB,EAAA,EAAI,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,EAAA,CAAG,UAAA,EAAY,CAAA,EAAG,GAAA,EAAK,CAAA;AAAA,WAAA,IACzD,EAAA,CAAG,UAAA,KAAe,EAAA,EAAI,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,EAAA,CAAG,YAAA,EAAc,CAAA,EAAG,GAAA,EAAK,CAAA;AAAA,IACzE;AACA,IAAA,OAAO,GAAA,CAAI,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AAAA,EAC5B,CAAA;AACA,EAAA,MAAM,cAAA,GAAiB,CAAC,EAAA,EAAY,KAAA,KAA0B;AAC5D,IAAA,IAAI,CAAA,GAAI,CAAA;AAER,IAAA,KAAA,MAAW,KAAK,YAAA,EAAc,IAAK,EAAE,SAAA,KAAc,EAAA,IAAM,EAAE,SAAA,KAAc,KAAA,IAAW,EAAE,SAAA,KAAc,EAAA,IAAM,EAAE,SAAA,KAAc,KAAA,MAAY,IAAA,CAAK,GAAA,CAAI,GAAG,CAAC,CAAA;AACnJ,IAAA,KAAA,MAAW,KAAK,QAAA,EAAU,IAAK,EAAE,OAAA,KAAY,EAAA,IAAM,EAAE,QAAA,KAAa,KAAA,IAAW,EAAE,QAAA,KAAa,EAAA,IAAM,EAAE,OAAA,KAAY,KAAA,MAAY,IAAA,CAAK,GAAA,CAAI,GAAG,CAAC,CAAA;AACzI,IAAA,KAAA,MAAW,MAAM,QAAA,EAAU,IAAK,GAAG,YAAA,KAAiB,EAAA,IAAM,GAAG,UAAA,KAAe,KAAA,IAAW,GAAG,UAAA,KAAe,EAAA,IAAM,GAAG,YAAA,KAAiB,KAAA,MAAY,IAAA,CAAK,GAAA,CAAI,GAAG,GAAG,CAAA;AAC9J,IAAA,OAAO,CAAA;AAAA,EACT,CAAA;AACA,EAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,EAAW,GAAA,KAAsB;AAC9C,IAAA,MAAM,MAAM,SAAA,EAAU;AACtB,IAAA,MAAM,MAAA,GAAS,UAAU,CAAC,CAAA;AAC1B,IAAA,MAAM,IAAA,GAAO,CAAC,CAAA,KAAqB;AACjC,MAAA,IAAI,GAAA,GAAM,CAAA;AACV,MAAA,IAAI,IAAA,GAAO,CAAA;AACX,MAAA,KAAA,MAAW,MAAM,CAAA,EAAG;AAClB,QAAA,KAAA,MAAW,EAAA,IAAM,mBAAA,CAAoB,EAAE,CAAA,EAAG;AACxC,UAAA,IAAI,WAAA,CAAY,GAAA,CAAI,EAAE,CAAA,KAAM,GAAA,EAAK;AACjC,UAAA,MAAM,CAAA,GAAI,cAAA,CAAe,EAAA,EAAI,EAAE,CAAA;AAC/B,UAAA,GAAA,IAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA,IAAK,CAAA,IAAK,CAAA;AAC5B,UAAA,IAAA,IAAQ,CAAA;AAAA,QACV;AAAA,MACF;AACA,MAAA,OAAO,IAAA,KAAS,CAAA,GAAI,MAAA,CAAO,iBAAA,GAAoB,GAAA,GAAM,IAAA;AAAA,IACvD,CAAA;AACA,IAAA,MAAM,QAAQ,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,CAAA,EAAG,EAAA,EAAI,IAAA,CAAK,CAAC,GAAG,KAAA,EAAO,IAAA,CAAK,IAAI,GAAG,CAAC,GAAE,CAAE,CAAA;AAC3E,IAAA,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAO,EAAE,EAAA,KAAO,CAAA,CAAE,EAAA,GAAK,CAAA,CAAE,KAAK,CAAA,CAAE,EAAA,GAAK,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAM,CAAA;AACtE,IAAA,SAAA,CAAU,CAAC,CAAA,GAAI,KAAA,CAAM,IAAI,CAAC,CAAA,KAAM,EAAE,CAAC,CAAA;AAAA,EACrC,CAAA;AACA,EAAA,IAAI,YAAY,CAAA,EAAG;AACjB,IAAA,KAAA,IAAS,CAAA,GAAI,GAAG,CAAA,GAAI,QAAA,EAAU,KAAK,KAAA,CAAM,CAAA,EAAG,IAAI,CAAC,CAAA;AACjD,IAAA,KAAA,IAAS,CAAA,GAAI,WAAW,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,CAAC,CAAA;AAAA,EACxD;AAIA,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,EAAU,CAAA,EAAA,EAAK;AACjC,IAAA,MAAM,MAAA,GAAS,UAAU,CAAC,CAAA;AAC1B,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM,EAAE,CAAA,CAAE,MAAA,KAAW,CAAA,IAAK,UAAA,CAAW,CAAA,CAAE,CAAC,CAAE,CAAA,CAAE,CAAA;AAC7E,IAAA,MAAM,QAAA,GAAW,OAAO,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,MAAA,KAAW,CAAA,IAAK,UAAA,CAAW,CAAA,CAAE,CAAC,CAAE,CAAC,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,CAAC,CAAA,GAAK,CAAA,CAAE,CAAC,CAAE,CAAA;AACvG,IAAA,SAAA,CAAU,CAAC,CAAA,GAAI,CAAC,GAAG,SAAA,EAAW,GAAG,QAAQ,CAAA;AAAA,EAC3C;AAGA,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAoB;AACtC,EAAA,IAAI,QAAA,GAAW,CAAA;AACf,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,EAAU,CAAA,EAAA,EAAK;AACjC,IAAA,IAAI,CAAA,GAAI,CAAA;AACR,IAAA,KAAA,MAAW,CAAA,IAAK,SAAA,CAAU,CAAC,CAAA,EAAI,KAAA,MAAW,MAAM,CAAA,EAAG,KAAA,CAAM,GAAA,CAAI,EAAA,EAAI,CAAA,EAAG,CAAA;AACpE,IAAA,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,CAAC,CAAA;AAAA,EACjC;AACA,EAAA,MAAM,UAAA,GAAa,CAAC,EAAA,KAAuB,KAAA,CAAM,IAAI,EAAE,CAAA;AAGvD,EAAA,IAAI,eAAA,GAAkB,QAAA;AACtB,EAAA;AACE,IAAA,MAAM,WAAA,GAA0B,MAAM,IAAA,CAAK,EAAE,QAAQ,QAAA,EAAS,EAAG,MAAM,EAAE,CAAA;AACzE,IAAA,KAAA,MAAW,CAAA,IAAK,MAAA,EAAQ,WAAA,CAAY,UAAA,CAAW,CAAA,CAAE,EAAE,CAAC,CAAA,CAAG,IAAA,CAAK,CAAA,CAAE,EAAE,CAAA;AAChE,IAAA,KAAA,IAAS,CAAA,GAAI,QAAA,GAAW,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AACtC,MAAA,MAAM,GAAA,GAAM,YAAY,CAAC,CAAA;AACzB,MAAA,IAAI,GAAA,CAAI,MAAA,GAAS,CAAA,IAAK,GAAA,CAAI,KAAA,CAAM,CAAC,EAAA,KAAO,UAAA,CAAW,EAAE,CAAC,CAAA,EAAG,eAAA,GAAkB,CAAA;AAAA,WACtE;AAAA,IACP;AAAA,EACF;AAGA,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAsB;AAC3C,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,MAAM,QAAQ,aAAA,CAAc,UAAA,CAAW,EAAE,KAAA,EAAO,IAAA,CAAK,aAAa,CAAC,CAAA;AACnE,IAAA,MAAM,WAAW,IAAA,CAAK,GAAA,CAAI,WAAW,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,KAAM,IAAA,CAAK,GAAA,CAAI,GAAG,iBAAA,CAAkB,CAAA,EAAG,UAAU,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAC7G,IAAA,QAAA,CAAS,GAAA,CAAI,EAAE,EAAA,EAAI,EAAE,QAAQ,CAAA,EAAG,KAAA,EAAO,UAAU,CAAA;AAAA,EACnD;AACA,EAAA,MAAM,QAAA,GAAqB,MAAM,IAAA,CAAK,EAAE,QAAQ,QAAA,EAAS,EAAG,MAAM,SAAS,CAAA;AAC3E,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,MAAM,CAAA,GAAI,UAAA,CAAW,CAAA,CAAE,EAAE,CAAA;AACzB,IAAA,QAAA,CAAS,CAAC,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,QAAA,CAAS,CAAC,CAAA,EAAI,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA,CAAG,QAAQ,CAAA;AAAA,EACnE;AACA,EAAA,MAAM,WAAA,GAAwB,MAAM,IAAA,CAAK,EAAE,QAAQ,QAAA,EAAS,EAAG,MAAM,CAAC,CAAA;AACtE,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,MAAM,CAAA,GAAI,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA;AAC9B,IAAA,WAAA,CAAY,CAAC,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,WAAA,CAAY,CAAC,CAAA,EAAI,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA,CAAG,MAAM,MAAM,CAAA;AAAA,EAC7E;AAGA,EAAA,MAAM,UAA4B,EAAC;AACnC,EAAA,MAAM,aAA0B,EAAC;AACjC,EAAA,MAAM,eAA8B,EAAC;AACrC,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAoB;AAC1C,EAAA,MAAM,YAAA,uBAAmB,GAAA,EAAoB;AAE7C,EAAA,MAAM,OAAA,GAAU,CAAC,QAAA,EAAkB,IAAA,KAA0B;AAC3D,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AAC/B,IAAA,MAAM,IAAA,GAAO,SAAA,CAAU,GAAA,CAAI,GAAG,CAAA,IAAK,CAAA;AACnC,IAAA,SAAA,CAAU,GAAA,CAAI,GAAA,EAAK,IAAA,GAAO,CAAC,CAAA;AAC3B,IAAA,OAAO,EAAE,QAAA,EAAU,IAAA,EAAM,IAAA,EAAK;AAAA,EAChC,CAAA;AACA,EAAA,MAAM,UAAA,GAAa,CAAC,QAAA,KAAiC;AACnD,IAAA,MAAM,IAAA,GAAO,YAAA,CAAa,GAAA,CAAI,QAAQ,CAAA,IAAK,CAAA;AAC3C,IAAA,YAAA,CAAa,GAAA,CAAI,QAAA,EAAU,IAAA,GAAO,CAAC,CAAA;AACnC,IAAA,OAAO,EAAE,UAAU,IAAA,EAAK;AAAA,EAC1B,CAAA;AACA,EAAA,MAAM,UAAA,GAAa,CAAC,KAAA,EAAe,KAAA,KAA0B;AAC3D,IAAA,MAAM,EAAA,GAAK,WAAW,KAAK,CAAA;AAC3B,IAAA,MAAM,EAAA,GAAK,WAAW,KAAK,CAAA;AAC3B,IAAA,IAAI,EAAA,GAAK,IAAI,OAAO,CAAA;AACpB,IAAA,IAAI,EAAA,GAAK,IAAI,OAAO,EAAA;AACpB,IAAA,OAAO,EAAA,GAAK,QAAA,GAAW,CAAA,GAAI,CAAA,GAAI,EAAA;AAAA,EACjC,CAAA;AAEA,EAAA,MAAM,YAAY,CAAC,MAAA,EAAgB,IAAA,KACjC,IAAA,KAAS,IACL,EAAE,MAAA,EAAQ,MAAA,EAAQ,KAAA,EAAO,IAAG,GAC5B,EAAE,QAAQ,MAAA,GAAS,CAAA,EAAG,OAAO,CAAA,EAAE;AASrC,EAAA,MAAM,aAAA,GAAgB,CACpB,KAAA,EACA,KAAA,EACA,eAAA,KACoB;AACpB,IAAA,MAAM,MAAA,GAAS,WAAA,CAAY,GAAA,CAAI,KAAK,CAAA;AACpC,IAAA,MAAM,MAAA,GAAS,WAAA,CAAY,GAAA,CAAI,KAAK,CAAA;AAEpC,IAAA,MAAM,CAAC,OAAA,EAAS,OAAO,CAAA,GAAI,MAAA,IAAU,MAAA,GAAS,CAAC,KAAA,EAAO,KAAK,CAAA,GAAI,CAAC,KAAA,EAAO,KAAK,CAAA;AAC5E,IAAA,MAAM,QAAA,GAAW,WAAA,CAAY,GAAA,CAAI,OAAO,CAAA;AACxC,IAAA,MAAM,QAAA,GAAW,WAAA,CAAY,GAAA,CAAI,OAAO,CAAA;AACxC,IAAA,MAAM,IAAA,GAAO,UAAA,CAAW,OAAA,EAAS,OAAO,CAAA;AACxC,IAAA,MAAM,EAAE,QAAQ,KAAA,EAAM,GAAI,UAAU,UAAA,CAAW,OAAO,GAAG,IAAI,CAAA;AAC7D,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,OAAA,EAAS,IAAI,CAAA;AAElC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,QAAA,GAAW,CAAA,EAAG,QAAA,GAAW,CAAC,CAAC,CAAA;AACjE,IAAA,MAAM,IAAA,GAAkB;AAAA,MACtB,MAAA;AAAA,MACA,IAAA,EAAM,KAAA;AAAA,MACN,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,WAAW,GAAG,CAAA;AAAA,MACxC,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,WAAW,GAAG,CAAA;AAAA,MACxC,IAAA,EAAM;AAAA,KACR;AACA,IAAA,UAAA,CAAW,KAAK,IAAI,CAAA;AACpB,IAAA,MAAM,OAAA,GAAmC,UAAA,CAAW,OAAO,CAAA;AAC3D,IAAA,MAAM,WAAW,MACf,GAAA,CAAI,EAAA,CAAG,UAAA,CAAW,OAAO,CAAC,CAAA,IAAK,OAAA,GAAU,aAAA,CAAc,QAAQ,IAAA,EAAM,YAAA,CAAa,IAAI,OAAO,CAAA,IAAK,CAAC,CAAA,GAAI,CAAA,CAAA;AACzG,IAAA,MAAM,IAAA,GAAoB;AAAA,MACxB,QAAA;AAAA,MACA,QAAQ,MAAM;AACZ,QAAA,MAAM,EAAA,GAAK,GAAA,CAAI,WAAA,CAAY,IAAI,CAAA;AAC/B,QAAA,MAAM,KAAK,QAAA,EAAS;AACpB,QAAA,OAAO,CAAC,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,EAAE,GAAG,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,EAAE,CAAC,CAAA;AAAA,MAC5C,CAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACR;AACA,IAAA,YAAA,CAAa,KAAK,IAAI,CAAA;AACtB,IAAA,OAAO,MAAM;AACX,MAAA,MAAM,KAAK,GAAA,CAAI,EAAA,CAAG,QAAQ,CAAA,GAAI,UAAA,CAAW,KAAK,IAAI,CAAA;AAClD,MAAA,MAAM,KAAA,GAAQ,SAAS,CAAA,GAAI,GAAA,CAAI,WAAW,OAAO,CAAA,GAAI,GAAA,CAAI,SAAA,CAAU,OAAO,CAAA;AAC1E,MAAA,MAAM,EAAA,GAAK,GAAA,CAAI,WAAA,CAAY,IAAI,CAAA;AAC/B,MAAA,MAAM,MAAA,GAAS,GAAA,CAAI,aAAA,CAAc,IAAI,CAAA;AACrC,MAAA,MAAM,KAAK,QAAA,EAAS;AACpB,MAAA,MAAM,IAAA,GAAO,GAAA,CAAI,EAAA,CAAG,QAAQ,IAAI,SAAA,GAAY,CAAA;AAC5C,MAAA,OAAO;AAAA,QACL,EAAE,CAAA,EAAG,KAAA,EAAO,CAAA,EAAG,EAAA,EAAG;AAAA,QAClB,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,EAAA,EAAG;AAAA,QACf,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,MAAA,EAAO;AAAA,QACnB,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,MAAA,EAAO;AAAA,QACnB,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,IAAA;AAAK,OACnB;AAAA,IACF,CAAA;AAAA,EACF,CAAA;AAIA,EAAA,MAAM,cAAA,GAAiB,CAAC,GAAA,EAAa,GAAA,KAAiC;AACpE,IAAA,MAAM,GAAA,GAAM,WAAA,CAAY,GAAA,CAAI,GAAG,CAAA;AAC/B,IAAA,MAAM,CAAC,MAAA,EAAQ,OAAO,CAAA,GAAI,UAAA,CAAW,GAAG,CAAA,IAAK,UAAA,CAAW,GAAG,CAAA,GAAI,CAAC,GAAA,EAAK,GAAG,CAAA,GAAI,CAAC,KAAK,GAAG,CAAA;AACrF,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,MAAA,EAAQ,CAAC,CAAA;AAC/B,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,OAAA,EAAS,EAAE,CAAA;AACjC,IAAA,MAAM,EAAA,GAAK,SAAA,CAAU,UAAA,CAAW,MAAM,GAAG,CAAC,CAAA;AAC1C,IAAA,MAAM,EAAA,GAAK,SAAA,CAAU,UAAA,CAAW,OAAO,GAAG,EAAE,CAAA;AAC5C,IAAA,MAAM,KAAA,GAAmB,EAAE,MAAA,EAAQ,EAAA,CAAG,QAAQ,IAAA,EAAM,EAAA,CAAG,KAAA,EAAO,KAAA,EAAO,GAAA,EAAK,KAAA,EAAO,GAAA,GAAM,GAAA,EAAK,MAAM,CAAA,EAAE;AACpG,IAAA,MAAM,KAAA,GAAmB,EAAE,MAAA,EAAQ,EAAA,CAAG,QAAQ,IAAA,EAAM,EAAA,CAAG,KAAA,EAAO,KAAA,EAAO,GAAA,EAAK,KAAA,EAAO,GAAA,GAAM,GAAA,EAAK,MAAM,CAAA,EAAE;AACpG,IAAA,UAAA,CAAW,IAAA,CAAK,OAAO,KAAK,CAAA;AAC5B,IAAA,MAAM,IAAA,GAAoB;AAAA,MACxB,QAAA,EAAU,GAAA;AAAA,MACV,QAAQ,MAAM;AACZ,QAAA,MAAM,EAAA,GAAK,GAAA,CAAI,WAAA,CAAY,KAAK,CAAA;AAChC,QAAA,MAAM,EAAA,GAAK,GAAA,CAAI,WAAA,CAAY,KAAK,CAAA;AAChC,QAAA,OAAO,CAAC,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,EAAE,GAAG,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,EAAE,CAAC,CAAA;AAAA,MAC5C,CAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACR;AACA,IAAA,YAAA,CAAa,KAAK,IAAI,CAAA;AACtB,IAAA,OAAO,MAAM;AACX,MAAA,MAAM,KAAK,GAAA,CAAI,EAAA,CAAG,GAAG,CAAA,GAAI,UAAA,CAAW,MAAM,IAAI,CAAA;AAC9C,MAAA,MAAM,KAAK,GAAA,CAAI,EAAA,CAAG,GAAG,CAAA,GAAI,UAAA,CAAW,MAAM,IAAI,CAAA;AAC9C,MAAA,MAAM,EAAA,GAAK,GAAA,CAAI,WAAA,CAAY,KAAK,CAAA;AAChC,MAAA,MAAM,EAAA,GAAK,GAAA,CAAI,WAAA,CAAY,KAAK,CAAA;AAChC,MAAA,MAAM,MAAA,GAAS,GAAA,CAAI,aAAA,CAAc,IAAI,CAAA;AACrC,MAAA,OAAO;AAAA,QACL,EAAE,CAAA,EAAG,GAAA,CAAI,WAAW,MAAM,CAAA,EAAG,GAAG,EAAA,EAAG;AAAA,QACnC,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,EAAA,EAAG;AAAA,QACf,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,MAAA,EAAO;AAAA,QACnB,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,MAAA,EAAO;AAAA,QACnB,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,EAAA,EAAG;AAAA,QACf,EAAE,CAAA,EAAG,GAAA,CAAI,UAAU,OAAO,CAAA,EAAG,GAAG,EAAA;AAAG,OACrC;AAAA,IACF,CAAA;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,aAAa,CAAC,CAAA,KAClB,EAAE,OAAA,KAAY,IAAA,GACV,GAAG,WAAA,CAAY,WAAA,CAAY,EAAE,MAAM,CAAC,SAAM,CAAA,CAAE,OAAO,KACnD,WAAA,CAAY,WAAA,CAAY,EAAE,MAAM,CAAA;AACtC,EAAA,MAAM,SAAA,GAAY,CAAC,CAAA,KACjB,CAAA,CAAE,OAAA,KAAY,IAAA,GAAO,CAAA,EAAG,WAAA,CAAY,SAAS,CAAA,MAAA,EAAM,CAAA,CAAE,OAAO,KAAK,WAAA,CAAY,SAAA;AAU/E,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAqB;AAC5C,EAAA,MAAM,YAAY,YAAA,CAAa,MAAA;AAAA,IAC7B,CAAC,MACC,WAAA,CAAY,GAAA,CAAI,EAAE,SAAS,CAAA,KAAM,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,SAAS,KAC5D,IAAA,CAAK,GAAA,CAAI,WAAW,CAAA,CAAE,SAAS,IAAI,UAAA,CAAW,CAAA,CAAE,SAAS,CAAC,CAAA,KAAM;AAAA,GACpE;AAGA,EAAA,MAAM,aAAA,uBAAoB,GAAA,EAAoB;AAC9C,EAAA,MAAM,YAAA,GAAyB,MAAM,IAAA,CAAK,EAAE,QAAQ,QAAA,EAAS,EAAG,MAAM,CAAC,CAAA;AACvE,EAAA;AACE,IAAA,MAAM,KAAA,uBAAY,GAAA,EAAqB;AACvC,IAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,MAAA,MAAM,CAAA,GAAI,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA;AACrC,MAAA,CAAC,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,IAAK,MAAM,GAAA,CAAI,CAAA,EAAG,EAAE,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,EAAI,KAAK,CAAC,CAAA;AAAA,IACnD;AACA,IAAA,KAAA,MAAW,CAAC,CAAA,EAAG,SAAS,CAAA,IAAK,KAAA,EAAO;AAElC,MAAA,MAAM,cAAA,uBAAqB,GAAA,EAAqB;AAChD,MAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,QAAA,CAAC,eAAe,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA,IAAK,eAAe,GAAA,CAAI,CAAA,CAAE,SAAA,EAAW,EAAE,CAAA,CAAE,GAAA,CAAI,EAAE,SAAS,CAAA,EAAI,KAAK,CAAC,CAAA;AACjG,QAAA,CAAC,eAAe,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA,IAAK,eAAe,GAAA,CAAI,CAAA,CAAE,SAAA,EAAW,EAAE,CAAA,CAAE,GAAA,CAAI,EAAE,SAAS,CAAA,EAAI,KAAK,CAAC,CAAA;AAAA,MACnG;AACA,MAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAE7B,MAAA,KAAA,MAAW,KAAA,IAAS,CAAC,GAAG,SAAS,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,EAAA,GAAK,CAAA,CAAE,EAAE,CAAA,EAAG;AAC9D,QAAA,IAAI,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,EAAE,CAAA,EAAG;AACxB,QAAA,MAAM,OAAgB,EAAC;AACvB,QAAA,MAAM,KAAA,GAAQ,CAAC,KAAK,CAAA;AACpB,QAAA,IAAA,CAAK,GAAA,CAAI,MAAM,EAAE,CAAA;AACjB,QAAA,OAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACvB,UAAA,MAAM,CAAA,GAAI,MAAM,GAAA,EAAI;AACpB,UAAA,IAAA,CAAK,KAAK,CAAC,CAAA;AACX,UAAA,KAAA,MAAW,OAAO,CAAC,CAAA,CAAE,SAAA,EAAW,CAAA,CAAE,SAAS,CAAA,EAAG;AAC5C,YAAA,KAAA,MAAW,MAAM,cAAA,CAAe,GAAA,CAAI,GAAG,CAAA,IAAK,EAAC,EAAG;AAC9C,cAAA,IAAI,CAAC,IAAA,CAAK,GAAA,CAAI,EAAA,CAAG,EAAE,CAAA,EAAG;AACpB,gBAAA,IAAA,CAAK,GAAA,CAAI,GAAG,EAAE,CAAA;AACd,gBAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,cACf;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,QAAA,IAAA,CAAK,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,EAAA,GAAK,EAAE,EAAE,CAAA;AAC/B,QAAA,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM,cAAc,GAAA,CAAI,CAAA,CAAE,EAAA,EAAI,CAAC,CAAC,CAAA;AACjD,QAAA,YAAA,CAAa,CAAC,IAAI,IAAA,CAAK,GAAA,CAAI,aAAa,CAAC,CAAA,EAAI,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,KAAK,YAAA,EAAc;AAC5B,IAAA,MAAM,IAAA,GAAO,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA;AACxC,IAAA,MAAM,IAAA,GAAO,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA;AACxC,IAAA,MAAM,QAAA,GACJ,IAAA,KAAS,IAAA,IAAQ,IAAA,CAAK,GAAA,CAAI,UAAA,CAAW,CAAA,CAAE,SAAS,CAAA,GAAI,UAAA,CAAW,CAAA,CAAE,SAAS,CAAC,CAAA,KAAM,CAAA;AACnF,IAAA,UAAA,CAAW,GAAA,CAAI,CAAA,CAAE,EAAA,EAAI,QAAQ,CAAA;AAC7B,IAAA,MAAM,MAAA,GAAS,oBAAoB,CAAA,CAAE,EAAA;AACrC,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,MAAM,CAAC,QAAQ,OAAO,CAAA,GAAI,WAAW,CAAA,CAAE,SAAS,CAAA,GAAI,UAAA,CAAW,CAAA,CAAE,SAAS,IACtE,CAAC,CAAA,CAAE,WAAW,CAAA,CAAE,SAAS,IACzB,CAAC,CAAA,CAAE,SAAA,EAAW,CAAA,CAAE,SAAS,CAAA;AAC7B,MAAA,MAAM,QAAA,GAAW,aAAA,CAAc,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA,IAAK,CAAA;AAC5C,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACX,IAAA,EAAM,WAAA;AAAA,QACN,MAAA,EAAQ,CAAC,MAAM,CAAA;AAAA,QACf,MAAA;AAAA,QACA,cAAc,CAAA,CAAE,SAAA;AAAA,QAChB,YAAY,CAAA,CAAE,SAAA;AAAA,QACd,MAAA,EAAQ,CAAC,UAAA,CAAW,CAAC,CAAC,CAAA;AAAA,QACtB,SAAA,EAAW,OAAA;AAAA,QACX,OAAO,MAAM;AACX,UAAA,MAAM,KAAK,GAAA,CAAI,EAAA,CAAG,WAAA,CAAY,GAAA,CAAI,MAAM,CAAE,CAAA;AAC1C,UAAA,IAAI,aAAa,CAAA,EAAG;AAElB,YAAA,OAAO;AAAA,cACL,EAAE,CAAA,EAAG,GAAA,CAAI,WAAW,MAAM,CAAA,EAAG,GAAG,EAAA,EAAG;AAAA,cACnC,EAAE,CAAA,EAAG,GAAA,CAAI,UAAU,OAAO,CAAA,EAAG,GAAG,EAAA;AAAG,aACrC;AAAA,UACF;AAKA,UAAA,MAAM,IAAI,GAAA,CAAI,SAAA,CAAU,YAAY,GAAA,CAAI,MAAM,GAAI,QAAQ,CAAA;AAC1D,UAAA,MAAM,MAAA,GAAS,KAAK,SAAA,GAAY,CAAA;AAChC,UAAA,MAAM,KAAK,GAAA,CAAI,EAAA,CAAG,UAAA,CAAW,MAAM,CAAC,CAAA,GAAI,UAAA;AACxC,UAAA,MAAM,KAAK,GAAA,CAAI,EAAA,CAAG,UAAA,CAAW,OAAO,CAAC,CAAA,GAAI,UAAA;AACzC,UAAA,OAAO;AAAA,YACL,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,MAAA,EAAO;AAAA,YACnB,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAE;AAAA,YACX,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAE;AAAA,YACX,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,MAAA;AAAO,WACrB;AAAA,QACF;AAAA,OACD,CAAA;AAAA,IACH,CAAA,MAAO;AACL,MAAA,MAAM,UAAU,IAAA,KAAS,IAAA;AACzB,MAAA,MAAM,KAAA,GAAQ,UACV,cAAA,CAAe,CAAA,CAAE,WAAW,CAAA,CAAE,SAAS,KACtC,MAAM;AACL,QAAA,MAAM,CAAC,EAAA,EAAI,EAAE,CAAA,GAAI,IAAA,GAAO,OAAO,CAAC,CAAA,CAAE,SAAA,EAAW,CAAA,CAAE,SAAS,CAAA,GAAI,CAAC,CAAA,CAAE,SAAA,EAAW,EAAE,SAAS,CAAA;AACrF,QAAA,OAAO,aAAA,CAAc,EAAA,EAAI,EAAS,CAAA;AAAA,MACpC,CAAA,GAAG;AACP,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACX,IAAA,EAAM,aAAA;AAAA,QACN,MAAA,EAAQ,CAAC,MAAM,CAAA;AAAA,QACf,MAAA;AAAA,QACA,cAAc,CAAA,CAAE,SAAA;AAAA,QAChB,YAAY,CAAA,CAAE,SAAA;AAAA,QACd,MAAA,EAAQ,CAAC,UAAA,CAAW,CAAC,CAAC,CAAA;AAAA,QACtB,SAAA,EAAW,OAAA;AAAA,QACX;AAAA,OACD,CAAA;AAAA,IACH;AAAA,EACF;AAMA,EAAA,MAAM,qBAAA,uBAA4B,GAAA,EAAsB;AACxD,EAAA,MAAM,YAA0B,EAAC;AACjC,EAAA,KAAA,MAAW,OAAA,IAAW,CAAC,GAAG,SAAA,CAAU,IAAA,EAAM,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,CAAC,CAAA,EAAG;AACjE,IAAA,MAAM,OAAA,GAAU,CAAC,GAAG,SAAA,CAAU,GAAA,CAAI,OAAO,CAAE,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,IAAI,CAAC,CAAA;AACjE,IAAA,MAAM,gBAAA,GAAmB,OAAA,CACtB,OAAA,CAAQ,CAAC,GAAG,CAAA,KAAM,OAAA,CAAQ,KAAA,CAAM,CAAA,GAAI,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,MAAM,YAAA,CAAa,GAAA,CAAI,OAAA,CAAQ,CAAA,EAAG,CAAC,CAAC,CAAC,CAAC,EAClF,MAAA,CAAO,CAAC,CAAA,KAAkB,CAAA,KAAM,UAAa,UAAA,CAAW,GAAA,CAAI,CAAA,CAAE,EAAE,MAAM,IAAI,CAAA;AAC7E,IAAA,IAAI,gBAAA,CAAiB,WAAW,CAAA,EAAG;AACjC,MAAA,MAAM,CAAA,GAAI,iBAAiB,CAAC,CAAA;AAC5B,MAAA,MAAM,MAAM,qBAAA,CAAsB,GAAA,CAAI,CAAA,CAAE,EAAE,KAAK,EAAC;AAChD,MAAA,GAAA,CAAI,KAAK,OAAO,CAAA;AAChB,MAAA,qBAAA,CAAsB,GAAA,CAAI,CAAA,CAAE,EAAA,EAAI,GAAG,CAAA;AACnC,MAAA,MAAM,YAAA,uBAAmB,GAAA,CAAI,CAAC,EAAE,SAAA,EAAW,CAAA,CAAE,SAAS,CAAC,CAAA;AACvD,MAAA,KAAA,MAAW,KAAK,OAAA,EAAS,IAAI,CAAC,YAAA,CAAa,IAAI,CAAC,CAAA,EAAG,SAAA,CAAU,IAAA,CAAK,OAAO,GAAA,CAAI,CAAA,EAAG,CAAC,CAAA,CAAA,EAAI,OAAO,EAAE,CAAE,CAAA;AAAA,IAClG,CAAA,MAAO;AACL,MAAA,KAAA,MAAW,CAAA,IAAK,OAAA,EAAS,SAAA,CAAU,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,CAAA,EAAG,CAAC,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE,CAAE,CAAA;AAAA,IACxE;AAAA,EACF;AAIA,EAAA,KAAA,MAAW,KAAK,YAAA,EAAc;AAC5B,IAAA,MAAM,QAAA,GAAW,qBAAA,CAAsB,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA;AAC/C,IAAA,IAAI,QAAA,KAAa,MAAA,IAAa,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG;AACrD,IAAA,MAAM,MAAA,GAAS,UAAA,CAAW,CAAA,CAAE,SAAS,CAAA,GAAI,UAAA,CAAW,CAAA,CAAE,SAAS,CAAA,GAAI,CAAA,CAAE,SAAA,GAAY,CAAA,CAAE,SAAA;AACnF,IAAA,MAAM,WAAA,GAAc,WAAW,MAAM,CAAA;AACrC,IAAA,MAAM,SAAA,GAAY,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA;AAG7C,IAAA,MAAM,SAAA,GAAY,aAAA,CAAc,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA,IAAK,CAAA;AAC7C,IAAA,MAAM,WAAA,GAAc,MAClB,SAAA,KAAc,CAAA,GAAI,GAAA,CAAI,EAAA,CAAG,SAAS,CAAA,GAAI,GAAA,CAAI,SAAA,CAAU,SAAA,EAAW,SAAS,CAAA;AAE1E,IAAA,MAAM,UAAA,uBAAiB,GAAA,EAAsB;AAC7C,IAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,MAAA,MAAM,EAAA,GAAK,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA;AAC5B,MAAA,CAAC,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,IAAK,WAAW,GAAA,CAAI,EAAA,EAAI,EAAE,CAAA,CAAE,GAAA,CAAI,EAAE,CAAA,EAAI,KAAK,CAAC,CAAA;AAAA,IAChE;AACA,IAAA,KAAA,MAAW,QAAA,IAAY,CAAC,GAAG,UAAA,CAAW,IAAA,EAAM,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,CAAC,CAAA,EAAG;AACnE,MAAA,MAAM,SAAA,GAAY,UAAA,CAAW,GAAA,CAAI,QAAQ,EAAG,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,UAAA,CAAW,CAAC,CAAA,GAAI,UAAA,CAAW,CAAC,CAAC,CAAA;AAIxF,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,QAAA,GAAW,CAAA,EAAG,QAAA,GAAW,CAAC,CAAC,CAAA;AAGjE,MAAA,MAAM,UAAU,MAAgB,CAAC,IAAI,aAAA,CAAc,WAAW,GAAG,GAAG,SAAA,CAAU,GAAA,CAAI,CAAC,MAAM,GAAA,CAAI,EAAA,CAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;AAC/G,MAAA,MAAM,MAAA,GAAsB;AAAA,QAC1B,QAAA;AAAA,QACA,QAAQ,MAAM;AACZ,UAAA,MAAM,KAAK,OAAA,EAAQ;AACnB,UAAA,OAAO,CAAC,IAAA,CAAK,GAAA,CAAI,GAAG,EAAE,GAAG,IAAA,CAAK,GAAA,CAAI,GAAG,EAAE,CAAC,CAAA;AAAA,QAC1C,CAAA;AAAA,QACA,IAAA,EAAM;AAAA,OACR;AACA,MAAA,YAAA,CAAa,KAAK,MAAM,CAAA;AACxB,MAAA,MAAM,QAAA,GAAsB;AAAA,QAC1B,MAAA,EAAQ,WAAA;AAAA,QACR,IAAA,EAAM,CAAA;AAAA,QACN,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,SAAA,EAAW,WAAW,GAAG,CAAA;AAAA;AAAA,QACzC,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,SAAA,EAAW,WAAW,GAAG,CAAA;AAAA,QACzC,IAAA,EAAM;AAAA,OACR;AACA,MAAA,UAAA,CAAW,KAAK,QAAQ,CAAA;AACxB,MAAA,MAAM,GAAA,GAAM,CAAC,CAAA,KAAsB,MAAA,CAAO,GAAA,CAAI,CAAA,EAAG,CAAA,CAAE,SAAS,CAAA,CAAA,EAAI,CAAC,CAAA,CAAE,CAAA,CAAG,MAAA;AAKtE,MAAA,MAAM,SAAA,GAAY,CAAC,CAAA,EAAW,QAAA,KAA2B;AACvD,QAAA,MAAM,OAAO,MAAA,CAAO,GAAA,CAAI,GAAG,QAAQ,CAAA,CAAA,EAAI,CAAC,CAAA,CAAE,CAAA;AAC1C,QAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AACpB,QAAA,MAAM,GAAA,GAAM,WAAW,CAAC,CAAA;AACxB,QAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,UACX,IAAA,EAAM,SAAA;AAAA,UACN,MAAA,EAAQ,CAAC,MAAM,CAAA;AAAA,UACf,MAAA;AAAA,UACA,YAAA,EAAc,IAAA;AAAA,UACd,UAAA,EAAY,CAAA;AAAA,UACZ,MAAA,EAAQ,CAAC,SAAA,CAAU,IAAI,CAAC,CAAA;AAAA,UACxB,SAAA,EAAW,OAAA;AAAA,UACX,OAAO,MAAM;AACX,YAAA,MAAM,CAAA,GAAI,GAAA,CAAI,aAAA,CAAc,MAAM,CAAA;AAClC,YAAA,MAAM,CAAA,GAAI,GAAA,CAAI,EAAA,CAAG,UAAA,CAAW,CAAC,CAAC,CAAA,GAAI,aAAA,CAAc,GAAA,CAAI,IAAA,EAAM,YAAA,CAAa,GAAA,CAAI,CAAC,KAAK,CAAC,CAAA;AAClF,YAAA,OAAO;AAAA,cACL,EAAE,GAAG,CAAA,EAAE;AAAA,cACP,EAAE,CAAA,EAAG,CAAA,EAAG,GAAA,CAAI,EAAA,CAAG,WAAA,CAAY,GAAA,CAAI,CAAC,CAAE,CAAA,GAAI,SAAA,GAAY,CAAA;AAAE,aACtD;AAAA,UACF;AAAA,SACD,CAAA;AAAA,MACH,CAAA;AAEA,MAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAI1B,QAAA,MAAM,CAAA,GAAI,UAAU,CAAC,CAAA;AACrB,QAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,UACX,IAAA,EAAM,SAAA;AAAA,UACN,MAAA,EAAQ,CAAC,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,UACf,MAAA,EAAQ,IAAI,CAAC,CAAA;AAAA,UACb,YAAA,EAAc,IAAA;AAAA,UACd,UAAA,EAAY,IAAA;AAAA,UACZ,MAAA,EAAQ,CAAC,SAAA,CAAU,MAAA,CAAO,GAAA,CAAI,CAAA,EAAG,CAAA,CAAE,SAAS,CAAA,CAAA,EAAI,CAAC,CAAA,CAAE,CAAE,CAAC,CAAA;AAAA,UACtD,SAAA,EAAW,OAAA;AAAA,UACX,OAAO,MAAM;AACX,YAAA,MAAM,EAAA,GAAK,GAAA,CAAI,aAAA,CAAc,MAAM,CAAA;AACnC,YAAA,MAAM,EAAA,GAAK,GAAA,CAAI,aAAA,CAAc,WAAW,CAAA;AACxC,YAAA,MAAM,EAAA,GAAK,GAAA,CAAI,EAAA,CAAG,UAAA,CAAW,CAAC,CAAC,CAAA;AAC/B,YAAA,OAAO;AAAA,cACL,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,aAAY,EAAE;AAAA,cAC1B,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,EAAA,EAAG;AAAA,cACf,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,EAAA;AAAG,aACjB;AAAA,UACF;AAAA,SACD,CAAA;AACD,QAAA,SAAA,CAAU,CAAA,EAAG,EAAE,SAAS,CAAA;AAAA,MAC1B,CAAA,MAAO;AAKL,QAAA,MAAM,SAAS,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,KAAM,GAAA,CAAI,CAAC,CAAC,CAAA;AAE1C,QAAA,MAAM,UAAA,GAAa,CAAC,CAAA,KAAsB,SAAA,CAAU,MAAA,CAAO,GAAA,CAAI,CAAA,EAAG,CAAA,CAAE,SAAS,CAAA,CAAA,EAAI,CAAC,CAAA,CAAE,CAAE,CAAA;AACtF,QAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,UACX,IAAA,EAAM,aAAA;AAAA,UACN,MAAA,EAAQ,CAAC,MAAA,CAAO,CAAC,GAAI,GAAG,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,UACvC,MAAA,EAAQ,OAAO,CAAC,CAAA;AAAA,UAChB,YAAA,EAAc,IAAA;AAAA,UACd,UAAA,EAAY,IAAA;AAAA;AAAA;AAAA,UAGZ,MAAA,EAAQ,CAAC,UAAA,CAAW,SAAA,CAAU,CAAC,CAAE,CAAA,EAAG,GAAG,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,GAAA,CAAI,UAAU,CAAC,CAAA;AAAA,UACzE,SAAA,EAAW,OAAA;AAAA,UACX,OAAO,MAAM;AACX,YAAA,MAAM,CAAA,GAAI,GAAA,CAAI,aAAA,CAAc,MAAM,CAAA;AAClC,YAAA,MAAM,KAAK,OAAA,EAAQ;AACnB,YAAA,OAAO;AAAA,cACL,EAAE,CAAA,EAAG,IAAA,CAAK,IAAI,GAAG,EAAE,GAAG,CAAA,EAAE;AAAA,cACxB,EAAE,CAAA,EAAG,IAAA,CAAK,IAAI,GAAG,EAAE,GAAG,CAAA;AAAE,aAC1B;AAAA,UACF;AAAA,SACD,CAAA;AACD,QAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,UACX,IAAA,EAAM,SAAA;AAAA,UACN,MAAA,EAAQ,CAAC,MAAA,CAAO,CAAC,CAAE,CAAA;AAAA,UACnB,MAAA,EAAQ,OAAO,CAAC,CAAA;AAAA,UAChB,YAAA,EAAc,IAAA;AAAA,UACd,UAAA,EAAY,IAAA;AAAA,UACZ,QAAQ,CAAC,UAAA,CAAW,SAAA,CAAU,CAAC,CAAE,CAAC,CAAA;AAAA;AAAA,UAClC,SAAA,EAAW,OAAA;AAAA,UACX,OAAO,MAAM;AACX,YAAA,MAAM,EAAA,GAAK,GAAA,CAAI,aAAA,CAAc,MAAM,CAAA;AACnC,YAAA,MAAM,CAAA,GAAI,GAAA,CAAI,aAAA,CAAc,WAAW,CAAA;AACvC,YAAA,OAAO;AAAA,cACL,EAAE,CAAA,EAAG,CAAA,EAAG,WAAA,EAAY,EAAE;AAAA,cACtB,EAAE,CAAA,EAAG,CAAA,EAAG,EAAA;AAAG,aACb;AAAA,UACF;AAAA,SACD,CAAA;AACD,QAAA,KAAA,MAAW,CAAA,IAAK,SAAA,EAAW,SAAA,CAAU,CAAA,EAAG,EAAE,SAAS,CAAA;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AAGA,EAAA,KAAA,MAAW,CAAA,IAAK,CAAC,GAAG,SAAS,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,MAAA,GAAS,CAAA,CAAE,MAAM,CAAA,EAAG;AAClE,IAAA,MAAM,SAAS,CAAA,CAAE,MAAA;AACjB,IAAA,MAAM,IAAA,GAAO,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,QAAQ,CAAA;AACvC,IAAA,MAAM,IAAA,GAAO,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,OAAO,CAAA;AACtC,IAAA,MAAM,KAAA,GAAQ,IAAA,KAAS,IAAA,GACnB,cAAA,CAAe,EAAE,QAAA,EAAU,CAAA,CAAE,OAAO,CAAA,GACpC,aAAA,CAAc,CAAA,CAAE,QAAA,EAAU,CAAA,CAAE,OAAc,CAAA;AAC9C,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,MACX,IAAA,EAAM,SAAA;AAAA,MACN,MAAA,EAAQ,CAAC,MAAM,CAAA;AAAA,MACf,MAAA;AAAA,MACA,cAAc,CAAA,CAAE,QAAA;AAAA,MAChB,YAAY,CAAA,CAAE,OAAA;AAAA,MACd,MAAA,EAAQ,CAAC,SAAA,CAAU,CAAC,CAAC,CAAA;AAAA,MACrB,SAAA,EAAW,OAAA;AAAA,MACX,MAAA,EAAQ,IAAA;AAAA,MACR;AAAA,KACD,CAAA;AAAA,EACH;AAKA,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAoG;AAC3H,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,MAAM,KAAA,GAAQ,gBAAA,CAAiB,CAAA,CAAE,OAAA,EAAS,KAAK,cAAc,CAAA;AAC7D,IAAA,MAAM,KAAK,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,YAAA,EAAc,EAAE,UAAU,CAAA;AAChD,IAAA,MAAM,KAAK,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,YAAA,EAAc,EAAE,UAAU,CAAA;AAChD,IAAA,MAAM,MAAM,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,EAAE,IAAI,KAAK,CAAA,CAAA;AAChC,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,OAAA,KAAY,IAAA,GAAO,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,MAAA,EAAM,CAAA,CAAE,OAAO,CAAA,CAAA,GAAK,CAAA,CAAE,IAAA;AAClE,IAAA,MAAM,CAAA,GAAI,UAAA,CAAW,GAAA,CAAI,GAAG,CAAA;AAC5B,IAAA,IAAI,MAAM,MAAA,EAAW;AACnB,MAAA,UAAA,CAAW,IAAI,GAAA,EAAK,EAAE,QAAQ,CAAC,CAAA,CAAE,EAAE,CAAA,EAAG,MAAA,EAAQ,CAAC,KAAK,CAAA,EAAG,OAAO,GAAA,EAAK,CAAA,CAAE,cAAc,GAAA,EAAK,CAAA,CAAE,YAAY,CAAA;AAAA,IACxG,CAAA,MAAO;AACL,MAAA,CAAA,CAAE,MAAA,CAAO,IAAA,CAAK,CAAA,CAAE,EAAE,CAAA;AAClB,MAAA,CAAA,CAAE,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA,IACrB;AAAA,EACF;AACA,EAAA,MAAM,QAAA,GAAW,CAAC,GAAG,UAAA,CAAW,QAAQ,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,KAAK,GAAA,CAAI,GAAG,EAAE,MAAM,CAAA,GAAI,KAAK,GAAA,CAAI,GAAG,CAAA,CAAE,MAAM,CAAC,CAAA;AACtG,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,MAAM,IAAA,GAAO,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,GAAG,CAAA;AAClC,IAAA,MAAM,IAAA,GAAO,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,GAAG,CAAA;AAClC,IAAA,MAAM,KAAA,GAAQ,SAAS,IAAA,GACnB,cAAA,CAAe,EAAE,GAAA,EAAK,CAAA,CAAE,GAAG,CAAA,GAAA,CAC1B,MAAM;AACL,MAAA,MAAM,CAAC,EAAA,EAAI,EAAE,CAAA,GAAI,IAAA,GAAO,OAAO,CAAC,CAAA,CAAE,GAAA,EAAK,CAAA,CAAE,GAAG,CAAA,GAAI,CAAC,CAAA,CAAE,GAAA,EAAK,EAAE,GAAG,CAAA;AAC7D,MAAA,OAAO,aAAA,CAAc,EAAA,EAAI,EAAS,CAAA;AAAA,IACpC,CAAA,GAAG;AACP,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,MACX,IAAA,EAAM,MAAA;AAAA,MACN,QAAQ,CAAA,CAAE,MAAA;AAAA,MACV,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,GAAG,EAAE,MAAM,CAAA;AAAA,MAC5B,cAAc,CAAA,CAAE,GAAA;AAAA,MAChB,YAAY,CAAA,CAAE,GAAA;AAAA,MACd,QAAQ,CAAA,CAAE,MAAA;AAAA,MACV,WAAW,CAAA,CAAE,KAAA;AAAA,MACb;AAAA,KACD,CAAA;AAAA,EACH;AAKA,EAAA,MAAM,aAAuB,EAAC;AAC9B,EAAA,MAAM,WAAqB,EAAC;AAC5B,EAAA,MAAM,YAAsB,EAAC;AAC7B,EAAA,MAAM,aAAuB,EAAC;AAC9B,EAAA,MAAM,eAAyB,EAAC;AAChC,EAAA,MAAM,eAAyB,EAAC;AAChC,EAAA,MAAM,IAAA,GAAO,EAAE,KAAA,EAAO,CAAA,EAAE;AACxB,EAAA,MAAM,eAAA,uBAAsB,GAAA,EAAoB;AAChD,EAAA,MAAM,iBAAA,GAA8B,MAAM,IAAA,CAAK,EAAE,QAAQ,QAAA,EAAS,EAAG,MAAM,CAAC,CAAA;AAC5E,EAAA,MAAM,SAAA,GAAY,CAAC,MAAA,EAAgB,IAAA,KAA6B,eAAA,CAAgB,GAAA,CAAI,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,CAAA,IAAK,CAAA;AAE5G,EAAA,MAAM,GAAA,GAAM;AAAA,IACV,EAAA,EAAI,CAAC,CAAA,KAAsB,UAAA,CAAW,CAAC,CAAA;AAAA,IACvC,EAAA,EAAI,CAAC,CAAA,KAAsB,UAAA,CAAW,CAAC,CAAA;AAAA,IACvC,UAAA,EAAY,CAAC,EAAA,KAAuB,UAAA,CAAW,WAAW,EAAE,CAAC,IAAK,SAAA,GAAY,CAAA;AAAA,IAC9E,SAAA,EAAW,CAAC,EAAA,KAAuB,UAAA,CAAW,WAAW,EAAE,CAAC,IAAK,SAAA,GAAY,CAAA;AAAA,IAC7E,aAAA,EAAe,CAAC,CAAA,KAAsB;AACpC,MAAA,MAAM,IAAA,GAAO,CAAA,GAAI,CAAA,GAAI,OAAA,GAAU,UAAU,CAAC,CAAA;AAC1C,MAAA,MAAM,KAAA,GAAQ,KAAK,QAAA,GAAW,CAAA,GAAI,KAAK,KAAA,GAAQ,OAAA,GAAU,QAAA,CAAS,CAAA,GAAI,CAAC,CAAA;AACvE,MAAA,OAAA,CAAQ,OAAO,KAAA,IAAS,CAAA;AAAA,IAC1B,CAAA;AAAA,IACA,WAAA,EAAa,CAAC,GAAA,KAA2B;AACvC,MAAA,MAAM,OAAO,GAAA,CAAI,MAAA,GAAS,IAAI,OAAA,GAAU,SAAA,CAAU,IAAI,MAAM,CAAA;AAC5D,MAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,MAAA,IAAU,QAAA,GAAW,CAAA,GAAI,IAAA,CAAK,KAAA,GAAQ,OAAA,GAAU,QAAA,CAAS,GAAA,CAAI,MAAA,GAAS,CAAC,CAAA;AACzF,MAAA,MAAM,MAAA,GAAS,SAAA,CAAU,GAAA,CAAI,MAAA,EAAQ,EAAE,CAAA;AACvC,MAAA,IAAI,IAAI,IAAA,KAAS,EAAA,SAAW,IAAA,GAAA,CAAQ,GAAA,CAAI,OAAO,CAAA,IAAK,MAAA;AACpD,MAAA,IAAI,GAAA,CAAI,SAAS,CAAA,EAAG,OAAO,QAAQ,MAAA,GAAS,GAAA,CAAI,OAAO,CAAA,IAAK,MAAA;AAC5D,MAAA,OAAO,KAAA,GAAA,CAAS,GAAA,CAAI,IAAA,GAAO,CAAA,IAAK,MAAA;AAAA,IAClC,CAAA;AAAA,IACA,aAAA,EAAe,CAAC,GAAA,KACd,YAAA,CAAa,GAAA,CAAI,QAAQ,CAAA,GAAK,aAAA,GAAgB,CAAA,GAAI,GAAA,CAAI,IAAA,GAAO,MAAA;AAAA;AAAA,IAE/D,SAAA,EAAW,CAAC,CAAA,EAAW,KAAA,KACrB,WAAW,CAAC,CAAA,GAAK,SAAA,GAAY,CAAA,GAAI,KAAA,GAAQ;AAAA,GAC7C;AAIA,EAAA,MAAM,YAAA,uBAAmB,GAAA,EAAyB;AAClD,EAAA,KAAA,MAAW,OAAO,UAAA,EAAY;AAC5B,IAAA,MAAM,IAAI,CAAA,EAAG,GAAA,CAAI,MAAM,CAAA,CAAA,EAAI,IAAI,IAAI,CAAA,CAAA;AACnC,IAAA,CAAC,YAAA,CAAa,GAAA,CAAI,CAAC,CAAA,IAAK,aAAa,GAAA,CAAI,CAAA,EAAG,EAAE,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,EAAI,KAAK,GAAG,CAAA;AAAA,EACnE;AACA,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,IAAI,CAAA,IAAK,YAAA,EAAc;AACpC,IAAA,eAAA,CAAgB,GAAA;AAAA,MACd,CAAA;AAAA,MACA,cAAc,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,MAAS,EAAE,IAAI,GAAA,CAAI,KAAA,EAAO,IAAI,GAAA,CAAI,KAAA,EAAO,KAAK,CAAC,IAAA,KAAkB,IAAI,IAAA,GAAO,IAAA,GAAQ,CAAC;AAAA,KAC/G;AAAA,EACF;AAGA,EAAA,MAAM,WAAA,GAAc,CAAC,CAAA,KAAsB;AACzC,IAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,CAAA,EAAG,EAAE,CAAA,GAAI,SAAA,CAAU,CAAA,EAAG,CAAC,CAAA,GAAI,SAAA,CAAU,CAAA,EAAG,CAAC,CAAA;AACjE,IAAA,MAAM,KAAA,GAAQ,CAAA,KAAM,eAAA,GAAkB,CAAA,GAAI,qBAAA,GAAwB,CAAA;AAClE,IAAA,IAAI,CAAA,KAAM,EAAA,IAAM,CAAA,KAAM,QAAA,GAAW,CAAA,EAAG,OAAO,KAAA,GAAQ,CAAA,GAAI,OAAA,GAAU,KAAA,GAAQ,MAAA,GAAS,KAAA,GAAQ,KAAA;AAC1F,IAAA,OAAO,OAAA,GAAU,QAAQ,MAAA,GAAS,KAAA;AAAA,EACpC,CAAA;AACA,EAAA,IAAI,OAAA,GAAU,OAAA,GAAU,WAAA,CAAY,EAAE,CAAA;AACtC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,EAAU,CAAA,EAAA,EAAK;AACjC,IAAA,QAAA,CAAS,CAAC,CAAA,GAAI,OAAA;AACd,IAAA,UAAA,CAAW,CAAC,CAAA,GAAI,OAAA,GAAU,QAAA,CAAS,CAAC,CAAA,GAAK,CAAA;AACzC,IAAA,OAAA,IAAW,SAAS,CAAC,CAAA;AACrB,IAAA,SAAA,CAAU,CAAC,CAAA,GAAI,OAAA;AACf,IAAA,OAAA,IAAW,YAAY,CAAC,CAAA;AAAA,EAC1B;AACA,EAAA,IAAA,CAAK,QAAQ,OAAA,GAAU,OAAA;AAIvB,EAAA,MAAM,cAAA,uBAAqB,GAAA,EAA2B;AACtD,EAAA,KAAA,MAAW,GAAA,IAAO,cAAc,CAAC,cAAA,CAAe,IAAI,GAAA,CAAI,QAAQ,KAAK,cAAA,CAAe,GAAA,CAAI,IAAI,QAAA,EAAU,EAAE,CAAA,CAAE,GAAA,CAAI,IAAI,QAAQ,CAAA,EAAI,KAAK,GAAG,CAAA;AACtI,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,IAAI,CAAA,IAAK,cAAA,EAAgB;AACtC,IAAA,iBAAA,CAAkB,CAAC,CAAA,GAAI,aAAA;AAAA,MACrB,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,KAAQ;AAChB,QAAA,MAAM,CAAC,EAAA,EAAI,EAAE,CAAA,GAAI,IAAI,MAAA,EAAO;AAC5B,QAAA,OAAO,EAAE,IAAI,EAAA,EAAI,GAAA,EAAK,CAAC,IAAA,KAAkB,GAAA,CAAI,OAAO,IAAA,EAAM;AAAA,MAC5D,CAAC;AAAA,KACH;AAAA,EACF;AAGA,EAAA,MAAM,cAAA,GAAiB,CAAC,CAAA,KAAsB;AAC5C,IAAA,MAAM,KAAA,GAAQ,iBAAA,CAAkB,CAAC,CAAA,IAAK,CAAA;AACtC,IAAA,IAAI,KAAA,GAAQ,CAAA,EAAG,OAAO,aAAA,GAAgB,KAAA,GAAQ,MAAA;AAC9C,IAAA,OAAO,CAAA,GAAI,QAAA,GAAW,CAAA,GAAI,aAAA,GAAgB,CAAA;AAAA,EAC5C,CAAA;AAGA,EAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KACrB,YAAA,CAAa,CAAC,CAAA,GAAK,CAAA,GAAI,YAAA,CAAa,CAAC,CAAA,GAAK,aAAA,GAAgB,CAAA,GAAI,CAAA;AAChE,EAAA,IAAI,OAAA,GAAU,OAAA;AACd,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,EAAU,CAAA,EAAA,EAAK;AACjC,IAAA,UAAA,CAAW,CAAC,CAAA,GAAI,OAAA,GAAU,SAAA,GAAY,CAAA;AACtC,IAAA,YAAA,CAAa,CAAC,CAAA,GAAI,OAAA,GAAU,SAAA,GAAY,aAAA,CAAc,CAAC,CAAA,GAAI,aAAA;AAC3D,IAAA,OAAA,GAAU,YAAA,CAAa,CAAC,CAAA,GAAK,WAAA,CAAY,CAAC,CAAA,GAAK,YAAA;AAC/C,IAAA,YAAA,CAAa,CAAC,CAAA,GAAI,OAAA;AAClB,IAAA,OAAA,IAAW,eAAe,CAAC,CAAA;AAAA,EAC7B;AACA,EAAA,MAAM,QAAQ,IAAA,CAAK,KAAA;AACnB,EAAA,MAAM,SAAS,OAAA,GAAU,OAAA;AAGzB,EAAA,MAAM,QAAwB,CAAC,GAAG,MAAM,CAAA,CACrC,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,KAAK,CAAA,CAAE,EAAE,CAAA,CAC1B,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,MAAM,CAAA,GAAI,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA;AAC3B,IAAA,MAAM,CAAA,GAAI,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA;AAC9B,IAAA,MAAM,CAAA,GAAI,UAAA,CAAW,CAAA,CAAE,EAAE,CAAA;AACzB,IAAA,OAAO;AAAA,MACL,UAAU,CAAA,CAAE,EAAA;AAAA,MACZ,OAAO,CAAA,CAAE,KAAA;AAAA,MACT,KAAA,EAAO,WAAA,CAAY,CAAA,CAAE,GAAG,CAAA;AAAA,MACxB,UAAU,CAAA,CAAE,QAAA;AAAA,MACZ,EAAA,EAAI,WAAW,CAAC,CAAA;AAAA,MAChB,EAAA,EAAI,WAAW,CAAC,CAAA;AAAA,MAChB,IAAA,EAAM,SAAA;AAAA,MACN,YAAY,CAAA,CAAE,KAAA;AAAA,MACd,QAAA,EAAU,aAAa,CAAC;AAAA,KAC1B;AAAA,EACF,CAAC,CAAA;AAEH,EAAA,MAAM,QAAA,GAA8B,OAAA,CAAQ,GAAA,CAAI,CAAC,EAAA,MAAQ;AAAA,IACvD,MAAM,EAAA,CAAG,IAAA;AAAA,IACT,QAAQ,EAAA,CAAG,MAAA;AAAA,IACX,QAAQ,EAAA,CAAG,MAAA;AAAA,IACX,cAAc,EAAA,CAAG,YAAA;AAAA,IACjB,YAAY,EAAA,CAAG,UAAA;AAAA,IACf,MAAA,EAAQ,GAAG,KAAA,EAAM;AAAA,IACjB,QAAQ,EAAA,CAAG,MAAA;AAAA,IACX,WAAW,EAAA,CAAG,SAAA;AAAA,IACd,GAAI,GAAG,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,EAAY,EAAA,CAAG,UAAA,EAAW,GAAI,EAAC;AAAA,IACnE,GAAI,EAAA,CAAG,MAAA,GAAS,EAAE,MAAA,EAAQ,IAAA,KAAS;AAAC,GACtC,CAAE,CAAA;AAGF,EAAA,MAAM,iBAAA,GAAoB,OACvB,MAAA,CAAO,CAAC,MAAM,UAAA,CAAW,CAAA,CAAE,EAAE,CAAC,CAAA,CAC9B,IAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA,CACf,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,CAAC,CAAA;AAEvB,EAAA,OAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAO,UAAU,iBAAA,EAAkB;AAC7D;AAKA,SAAS,cAAA,CAAe,MAAgB,GAAA,EAAsC;AAC5E,EAAA,IAAI,KAAK,MAAA,IAAU,CAAA,EAAG,OAAO,CAAC,GAAG,IAAI,CAAA;AACrC,EAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,IAAI,CAAA;AAC3B,EAAA,MAAM,MAAA,GAAS,CAAC,EAAA,KAAuB,GAAA,CAAI,IAAI,EAAE,CAAA,CAAG,MAAA,CAAO,CAAC,CAAA,KAAM,MAAA,CAAO,GAAA,CAAI,CAAC,CAAC,CAAA,CAAE,MAAA;AACjF,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,MAAA,CAAO,CAAC,OAAO,MAAA,CAAO,EAAE,CAAA,KAAM,CAAC,EAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,IAAI,CAAC,CAAA;AAC5E,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,EAAG,EAAA,KAAO,CAAA,GAAI,MAAA,CAAO,EAAE,CAAA,EAAG,CAAC,CAAA,GAAI,CAAA;AAC9D,EAAA,MAAM,SAAS,SAAA,KAAc,IAAA,CAAK,MAAA,GAAS,CAAA,IAAK,UAAU,MAAA,KAAW,CAAA;AACrE,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,IAAI,GAAA,GAA0B,UAAU,CAAC,CAAA;AACzC,IAAA,OAAO,QAAQ,MAAA,EAAW;AACxB,MAAA,KAAA,CAAM,KAAK,GAAG,CAAA;AACd,MAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACZ,MAAA,GAAA,GAAM,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA,CAAG,MAAA,CAAO,CAAC,CAAA,KAAM,MAAA,CAAO,GAAA,CAAI,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,CAAC,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAC,IAAA,CAAK,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,IACjG;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,MAAM,QAAQ,CAAC,IAAA,CAAK,GAAA,CAAI,GAAG,IAAI,CAAC,CAAA;AAChC,EAAA,OAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACvB,IAAA,MAAM,CAAA,GAAI,MAAM,GAAA,EAAI;AACpB,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG;AACjB,IAAA,IAAA,CAAK,IAAI,CAAC,CAAA;AACV,IAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AACZ,IAAA,KAAA,MAAW,KAAK,GAAA,CAAI,GAAA,CAAI,CAAC,CAAA,CAAG,MAAA,CAAO,CAAC,CAAA,KAAM,MAAA,CAAO,IAAI,CAAC,CAAC,EAAE,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM,CAAA,GAAI,CAAC,CAAA,EAAG;AAC9E,MAAA,IAAI,CAAC,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,IAChC;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;;;AC3sCA,IAAM,YAAA,GAAe,SAAA;AACrB,IAAM,eAAA,GAAkB,SAAA;AACxB,IAAM,QAAA,GAAW,SAAA;AAGjB,IAAM,YAAA,GAAe,GAAA;AACrB,IAAM,cAAA,GAAiB,IAAA;AAEvB,IAAM,WAAA,GAAyC,CAAC,CAAA,EAAG,CAAC,CAAA;AACpD,IAAM,cAAA,GAAiB,IAAA;AAGvB,IAAM,YAAA,GAAe,EAAA;AACrB,IAAM,UAAA,GAAa,EAAA;AACnB,IAAM,eAAA,GAAkB,EAAA;AACxB,IAAM,UAAA,GAAa,EAAA;AACnB,IAAM,WAAA,GAAc,EAAA;AAgBpB,SAAS,QAAA,CAAS,KAAA,EAAkB,EAAA,EAAY,EAAA,EAAY,IAAA,EAAsB;AAChF,EAAA,MAAM,MAAA,GAAS,8BAA8B,YAAY,CAAA,kBAAA,CAAA;AACzD,EAAA,IAAI,UAAU,QAAA,EAAU;AACtB,IAAA,OAAO,CAAA,SAAA,EAAY,EAAA,GAAK,IAAI,CAAA,KAAA,EAAQ,EAAA,GAAK,IAAI,CAAA,SAAA,EAAY,IAAA,GAAO,CAAC,CAAA,UAAA,EAAa,IAAA,GAAO,CAAC,YAAY,MAAM,CAAA,EAAA,CAAA;AAAA,EAC1G;AACA,EAAA,IAAI,UAAU,QAAA,EAAU;AACtB,IAAA,OAAO,eAAe,EAAE,CAAA,MAAA,EAAS,EAAE,CAAA,KAAA,EAAQ,IAAI,KAAK,MAAM,CAAA,EAAA,CAAA;AAAA,EAC5D;AACA,EAAA,OAAO,CAAA,iBAAA,EAAoB,EAAE,CAAA,CAAA,EAAI,EAAA,GAAK,IAAI,CAAA,CAAA,EAAI,EAAA,GAAK,IAAI,CAAA,CAAA,EAAI,EAAE,IAAI,EAAE,CAAA,CAAA,EAAI,KAAK,IAAI,CAAA,CAAA,EAAI,KAAK,IAAI,CAAA,CAAA,EAAI,EAAE,CAAA,EAAA,EAAK,MAAM,CAAA,EAAA,CAAA;AAChH;AAGA,SAAS,SAAS,MAAA,EAAyB;AACzC,EAAA,OAAO,OAAO,GAAA,CAAI,CAAC,GAAG,CAAA,KAAM,CAAA,EAAG,MAAM,CAAA,GAAI,GAAA,GAAM,GAAG,CAAA,CAAA,EAAI,CAAA,CAAE,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,CAAC,CAAA,CAAE,CAAA,CAAE,KAAK,GAAG,CAAA;AAC9E;AAGA,SAAS,gBAAgB,MAAA,EAAiC;AACxD,EAAA,IAAI,IAAA,GAAuB,CAAC,MAAA,CAAO,CAAC,GAAI,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAC,CAAE,CAAA;AAClE,EAAA,IAAI,OAAA,GAAU,EAAA;AACd,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,CAAA,GAAI,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AAC1C,IAAA,MAAM,CAAA,GAAI,OAAO,CAAC,CAAA;AAClB,IAAA,MAAM,CAAA,GAAI,MAAA,CAAO,CAAA,GAAI,CAAC,CAAA;AACtB,IAAA,IAAI,CAAA,CAAE,CAAA,KAAM,CAAA,CAAE,CAAA,EAAG;AACf,MAAA,MAAM,MAAM,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,EAAE,CAAC,CAAA;AAC9B,MAAA,IAAI,MAAM,OAAA,EAAS;AACjB,QAAA,OAAA,GAAU,GAAA;AACV,QAAA,IAAA,GAAO,CAAC,GAAG,CAAC,CAAA;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAOA,SAAS,UAAA,CAAW,CAAA,EAAU,CAAA,EAAU,KAAA,EAAc,KAAA,EAAuB;AAC3E,EAAA,MAAM,EAAA,GAAA,CAAM,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA,IAAK,CAAA;AACzB,EAAA,MAAM,EAAA,GAAA,CAAM,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA,IAAK,CAAA;AACzB,EAAA,MAAM,EAAA,GAAK,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA;AACnB,EAAA,MAAM,EAAA,GAAK,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA;AACnB,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,EAAA,EAAI,EAAE,CAAA,IAAK,CAAA;AAClC,EAAA,MAAM,KAAK,EAAA,GAAK,GAAA;AAChB,EAAA,MAAM,KAAK,EAAA,GAAK,GAAA;AAChB,EAAA,MAAM,IAAA,GAAO,CAAA;AACb,EAAA,MAAM,IAAA,GAAO,CAAA;AACb,EAAA,MAAM,OAAA,GAAU,UAAU,CAAA,GAAI,CAAC,CAAC,CAAA,GAAI,CAAC,CAAC,IAAA,EAAM,IAAI,CAAA;AAChD,EAAA,OAAO,OAAA,CACJ,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,MAAM,EAAA,GAAK,KAAK,EAAA,GAAK,CAAA;AACrB,IAAA,MAAM,EAAA,GAAK,KAAK,EAAA,GAAK,CAAA;AACrB,IAAA,OAAO,CAAA,UAAA,EAAa,EAAA,GAAK,IAAI,CAAA,MAAA,EAAS,KAAK,IAAI,CAAA,MAAA,EAAS,EAAA,GAAK,IAAI,SAAS,EAAA,GAAK,IAAI,CAAA,UAAA,EAAa,QAAQ,mBAAmB,KAAK,CAAA,GAAA,CAAA;AAAA,EAClI,CAAC,CAAA,CACA,IAAA,CAAK,EAAE,CAAA;AACZ;AAGA,SAAS,iBAAA,CACP,IACA,QAAA,EACgB;AAChB,EAAA,OAAO,SAAS,GAAA,CAAI,EAAA,CAAG,MAAM,CAAA,IAAK,EAAA,CAAG,cAAc,EAAC;AACtD;AAIA,SAAS,UAAA,CAAW,IAAqB,QAAA,EAAuD;AAC9F,EAAA,MAAM,KAAA,GAAQ,UAAU,SAAA,CAAU,EAAA,CAAG,OAAO,IAAA,CAAK,IAAI,CAAC,CAAC,CAAA,QAAA,CAAA;AACvD,EAAA,MAAM,MAAM,EAAA,CAAG,MAAA;AACf,EAAA,MAAM,QAAA,GAAW,CAAC,IAAA,EAAwC,KAAA,EAAe,OAAA,KAA4B;AACnG,IAAA,MAAM,QAAA,GAAW,IAAA,KAAS,IAAA,GAAO,EAAA,GAAK,CAAA,mBAAA,EAAsB,IAAA,CAAK,CAAC,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,CAAC,CAAC,CAAA,CAAA,CAAA;AAC9E,IAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACpB,MAAA,OAAO,CAAA,UAAA,EAAa,GAAA,CAAI,CAAC,CAAA,CAAG,CAAC,CAAA,MAAA,EAAS,GAAA,CAAI,CAAC,CAAA,CAAG,CAAC,CAAA,MAAA,EAAS,GAAA,CAAI,CAAC,CAAA,CAAG,CAAC,CAAA,MAAA,EAAS,GAAA,CAAI,CAAC,CAAA,CAAG,CAAC,CAAA,UAAA,EAAa,QAAQ,CAAA,gBAAA,EAAmB,KAAK,CAAA,kBAAA,EAAqB,OAAO,CAAA,CAAA,EAAI,QAAQ,CAAA,EAAA,CAAA;AAAA,IAC1K;AACA,IAAA,OAAO,CAAA,SAAA,EAAY,QAAA,CAAS,GAAG,CAAC,CAAA,sBAAA,EAAyB,QAAQ,CAAA,gBAAA,EAAmB,KAAK,CAAA,kBAAA,EAAqB,OAAO,CAAA,CAAA,EAAI,QAAQ,CAAA,EAAA,CAAA;AAAA,EACnI,CAAA;AAEA,EAAA,IAAI,EAAA,CAAG,IAAA,KAAS,WAAA,IAAe,EAAA,CAAG,SAAS,aAAA,EAAe;AACxD,IAAA,MAAM,KAAA,GAAQ,iBAAA,CAAkB,EAAA,EAAI,QAAQ,CAAA;AAC5C,IAAA,MAAM,IAAA,GAAiB,CAAC,QAAA,CAAS,KAAA,CAAM,QAAQ,IAAA,EAAM,YAAA,EAAc,cAAc,CAAC,CAAA;AAClF,IAAA,MAAM,OAAA,GAAU,MAAM,OAAA,IAAW,CAAA;AACjC,IAAA,IAAI,OAAA,KAAY,CAAA,IAAK,OAAA,KAAY,CAAA,EAAG;AAIlC,MAAA,MAAM,CAAC,CAAA,EAAG,CAAC,CAAA,GAAI,GAAA,CAAI,WAAW,CAAA,GAAI,CAAC,GAAA,CAAI,CAAC,GAAI,GAAA,CAAI,CAAC,CAAE,CAAA,GAAI,gBAAgB,GAAG,CAAA;AAC1E,MAAA,IAAA,CAAK,KAAK,UAAA,CAAW,CAAA,EAAG,CAAA,EAAG,OAAA,EAAS,YAAY,CAAC,CAAA;AAAA,IACnD;AACA,IAAA,OAAO,CAAA,iBAAA,EAAoB,GAAG,MAAM,CAAA,EAAA,EAAK,KAAK,CAAA,EAAG,IAAA,CAAK,IAAA,CAAK,EAAE,CAAC,CAAA,IAAA,CAAA;AAAA,EAChE;AAEA,EAAA,IAAI,EAAA,CAAG,IAAA,KAAS,SAAA,IAAa,EAAA,CAAG,SAAS,aAAA,EAAe;AACtD,IAAA,MAAM,IAAA,GAAO,EAAA,CAAG,MAAA,GAAS,WAAA,GAAc,IAAA;AACvC,IAAA,MAAM,OAAA,GAAU,EAAA,CAAG,MAAA,GAAS,cAAA,GAAiB,cAAA;AAC7C,IAAA,OAAO,CAAA,iBAAA,EAAoB,EAAA,CAAG,MAAM,CAAA,EAAA,EAAK,KAAK,GAAG,QAAA,CAAS,IAAA,EAAM,YAAA,EAAc,OAAO,CAAC,CAAA,IAAA,CAAA;AAAA,EACxF;AAGA,EAAA,MAAM,GAAA,GAAM,WAAA,CAAY,EAAA,CAAG,SAAS,CAAA;AACpC,EAAA,OAAO,CAAA,iBAAA,EAAoB,EAAA,CAAG,MAAM,CAAA,EAAA,EAAK,KAAK,CAAA,EAAG,QAAA,CAAS,GAAA,CAAI,IAAA,EAAM,GAAA,CAAI,KAAA,EAAO,GAAA,CAAI,OAAO,CAAC,CAAA,IAAA,CAAA;AAC7F;AAOO,SAAS,iBAAA,CAAkB,MAAA,EAAwB,IAAA,GAA2B,EAAC,EAAW;AAC/F,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,iBAAA,oBAAqB,IAAI,GAAA,EAA4B;AAC3E,EAAA,MAAM,MAAA,GAAS,KAAK,MAAA,IAAU,sBAAA;AAC9B,EAAA,MAAM,QAAkB,EAAC;AAGzB,EAAA,KAAA,MAAW,EAAA,IAAM,OAAO,QAAA,EAAU,KAAA,CAAM,KAAK,UAAA,CAAW,EAAA,EAAI,QAAQ,CAAC,CAAA;AAGrE,EAAA,KAAA,MAAW,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/B,IAAA,MAAM,IAAA,GAAO,KAAK,IAAA,GAAO,CAAA;AACzB,IAAA,MAAM,MAAA,GAAmB;AAAA,MACvB,CAAA,OAAA,EAAU,SAAA,CAAU,IAAA,CAAK,KAAK,CAAC,CAAA,QAAA,CAAA;AAAA,MAC/B,SAAS,IAAA,CAAK,KAAA,EAAO,KAAK,EAAA,EAAI,IAAA,CAAK,IAAI,IAAI;AAAA,KAC7C;AACA,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,aAAa,IAAA,CAAK,EAAA,GAAK,IAAI,CAAA,MAAA,EAAS,KAAK,EAAA,GAAK,IAAI,CAAA,MAAA,EAAS,IAAA,CAAK,KAAK,IAAI,CAAA,MAAA,EAAS,KAAK,EAAA,GAAK,IAAI,aAAa,YAAY,CAAA,oBAAA;AAAA,OAC3H;AAAA,IACF;AACA,IAAA,MAAM,MAAA,GAAS,KAAK,UAAA,CACjB,GAAA;AAAA,MACC,CAAC,IAAA,EAAM,CAAA,KACL,CAAA,UAAA,EAAa,KAAK,EAAE,CAAA,KAAA,EAAQ,IAAA,CAAK,QAAA,GAAW,KAAK,CAAA,GAAI,YAAY,CAAA,EAAA,EAAK,SAAA,CAAU,IAAI,CAAC,CAAA,QAAA;AAAA,KACzF,CACC,KAAK,EAAE,CAAA;AACV,IAAA,MAAA,CAAO,IAAA;AAAA,MACL,2CAA2C,WAAW,CAAA,aAAA,EAAgB,UAAU,CAAA,QAAA,EAAW,eAAe,KAAK,MAAM,CAAA,OAAA;AAAA,KACvH;AACA,IAAA,KAAA,CAAM,IAAA,CAAK,2BAA2B,IAAA,CAAK,QAAQ,KAAK,MAAA,CAAO,IAAA,CAAK,EAAE,CAAC,CAAA,IAAA,CAAM,CAAA;AAAA,EAC/E;AAGA,EAAA,IAAI,QAAQ,MAAA,CAAO,KAAA;AACnB,EAAA,IAAI,SAAS,MAAA,CAAO,MAAA;AACpB,EAAA,IAAI,KAAK,MAAA,KAAW,KAAA,IAAS,MAAA,CAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACpD,IAAA,MAAM,UAAyE,EAAC;AAEhF,IAAA,MAAM,UAAA,GAAa,IAAI,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,KAAK,CAAC,CAAA;AAC3D,IAAA,KAAA,MAAW,KAAA,IAAS,CAAC,QAAA,EAAU,QAAA,EAAU,SAAS,CAAA,EAAY;AAC5D,MAAA,IAAI,CAAC,UAAA,CAAW,GAAA,CAAI,KAAK,CAAA,EAAG;AAC5B,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACX,MAAA,EAAQ,CAAC,CAAA,EAAG,CAAA,KAAM,QAAA,CAAS,OAAO,CAAA,GAAI,eAAA,GAAkB,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,QAC/D,KAAA,EAAO,MAAA,CAAO,MAAA,CAAO,KAAK;AAAA,OAC3B,CAAA;AAAA,IACH;AACA,IAAA,IAAI,OAAO,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,QAAQ,CAAA,EAAG;AACxC,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACX,MAAA,EAAQ,CAAC,CAAA,EAAG,CAAA,KACV,QAAA,CAAS,QAAA,EAAU,CAAA,GAAI,eAAA,GAAkB,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAChD,CAAA,UAAA,EAAa,CAAA,GAAI,eAAA,GAAkB,CAAA,GAAI,CAAC,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,CAAA,MAAA,EAAS,CAAA,GAAI,eAAA,GAAkB,CAAA,GAAI,CAAC,CAAA,MAAA,EAAS,CAAA,GAAI,CAAC,aAAa,YAAY,CAAA,oBAAA,CAAA;AAAA,QACnI,OAAO,MAAA,CAAO;AAAA,OACf,CAAA;AAAA,IACH;AAUA,IAAA,MAAM,aAAa,IAAI,GAAA,CAAI,MAAA,CAAO,QAAA,CAAS,OAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,MAAM,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,CAAC,CAAA;AACnG,IAAA,KAAA,MAAW,SAAS,CAAC,OAAA,EAAS,SAAA,EAAW,UAAA,EAAY,QAAQ,CAAA,EAAY;AACvE,MAAA,IAAI,CAAC,UAAA,CAAW,GAAA,CAAI,KAAK,CAAA,EAAG;AAC5B,MAAA,MAAM,GAAA,GAAM,YAAY,KAAK,CAAA;AAC7B,MAAA,MAAM,QAAA,GAAW,GAAA,CAAI,IAAA,KAAS,IAAA,GAAO,KAAK,CAAA,mBAAA,EAAsB,GAAA,CAAI,IAAA,CAAK,CAAC,CAAC,CAAA,CAAA,EAAI,GAAA,CAAI,IAAA,CAAK,CAAC,CAAC,CAAA,CAAA,CAAA;AAC1F,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACX,MAAA,EAAQ,CAAC,CAAA,EAAG,CAAA,KACV,aAAa,CAAC,CAAA,MAAA,EAAS,CAAC,CAAA,MAAA,EAAS,CAAA,GAAI,eAAe,SAAS,CAAC,CAAA,UAAA,EAAa,QAAQ,CAAA,gBAAA,EAAmB,GAAA,CAAI,KAAK,CAAA,kBAAA,EAAqB,GAAA,CAAI,OAAO,CAAA,CAAA,EAAI,QAAQ,CAAA,EAAA,CAAA;AAAA,QAC7J,KAAA,EAAO,MAAA,CAAO,UAAA,CAAW,KAAK;AAAA,OAC/B,CAAA;AAAA,IACH;AAMA,IAAA,IAAI,MAAA,CAAO,iBAAA,CAAkB,MAAA,GAAS,CAAA,EAAG;AACvC,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACX,MAAA,EAAQ,CAAC,CAAA,EAAG,CAAA,KAAM,QAAA,CAAS,UAAU,CAAA,GAAI,eAAA,GAAkB,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,QAClE,OAAO,MAAA,CAAO;AAAA,OACf,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,MAAA,MAAM,SAAS,MAAA,CAAO,MAAA;AACtB,MAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,OAAO,CAAA,KAAM;AACrC,QAAA,MAAM,UAAA,GAAa,MAAA,GAAS,CAAA,GAAI,YAAA,GAAe,YAAA,GAAe,CAAA;AAC9D,QAAA,MAAM,KAAA,GAAQ,aAAa,eAAA,GAAkB,UAAA;AAC7C,QAAA,OACE,KAAA,CAAM,OAAO,UAAA,EAAY,UAAU,IACnC,CAAA,SAAA,EAAY,KAAK,QAAQ,UAAA,GAAa,WAAA,GAAc,IAAI,CAAA,eAAA,EAAkB,WAAW,gBAAgB,WAAW,CAAA,QAAA,EAAW,YAAY,CAAA,EAAA,EAAK,SAAA,CAAU,KAAA,CAAM,KAAK,CAAC,CAAA,OAAA,CAAA;AAAA,MAEtK,CAAC,CAAA;AACD,MAAA,KAAA,CAAM,KAAK,CAAA,+BAAA,EAAkC,IAAA,CAAK,IAAA,CAAK,EAAE,CAAC,CAAA,IAAA,CAAM,CAAA;AAChE,MAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,MAAA,CAAO,CAAC,GAAG,CAAA,KAAM,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,kBAAkB,CAAA,CAAE,KAAA,EAAO,WAAW,CAAC,GAAG,CAAC,CAAA;AACpG,MAAA,KAAA,GAAQ,KAAK,GAAA,CAAI,KAAA,EAAO,aAAa,eAAA,GAAkB,UAAA,GAAa,cAAc,UAAU,CAAA;AAC5F,MAAA,MAAA,GAAS,MAAA,GAAS,OAAA,CAAQ,MAAA,GAAS,YAAA,GAAe,UAAA,GAAa,CAAA;AAAA,IACjE;AAAA,EACF;AAEA,EAAA,OACE,wDAAwD,KAAK,CAAA,CAAA,EAAI,MAAM,CAAA,SAAA,EAAY,KAAK,CAAA,UAAA,EAAa,MAAM,CAAA,yBAAA,EAA4B,SAAA,CAAU,OAAO,SAAS,CAAC,OAClK,KAAA,CAAM,IAAA,CAAK,EAAE,CAAA,GACb,CAAA,MAAA,CAAA;AAEJ;;;ACnRA,IAAM,WAAA,GAAc,CAAC,CAAA,EAAG,CAAC,CAAA;AAQlB,IAAM,cAAA,GAA6E;AAAA,EACxF,SAAS,EAAC;AAAA;AAAA,EACV,UAAA,EAAY,EAAE,IAAA,EAAM,WAAA,EAAY;AAAA,EAChC,MAAA,EAAQ,EAAE,IAAA,EAAM,WAAA,EAAY;AAAA,EAC5B,OAAA,EAAS,EAAE,IAAA,EAAM,WAAA,EAAY;AAAA,EAC7B,SAAA,EAAW,EAAE,OAAA,EAAS,CAAA,EAAE;AAAA;AAAA,EACxB,QAAA,EAAU,EAAE,OAAA,EAAS,CAAA;AAAE;AACzB;AAOO,SAAS,mBAAmB,MAAA,EAA0B;AAC3D,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAmB;AACtC,EAAA,KAAA,MAAW,CAAA,IAAK,CAAC,GAAG,MAAM,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,EAAA,GAAK,CAAA,CAAE,EAAE,CAAA,EAAG;AACvD,IAAA,MAAM,MAAM,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,WAAW,CAAA,CAAE,SAAS,CAAC,CAAA,CAAA,EAAI,KAAK,GAAA,CAAI,CAAA,CAAE,SAAA,EAAW,CAAA,CAAE,SAAS,CAAC,CAAA,CAAA;AACvF,IAAA,MAAA,CAAO,GAAA,CAAI,KAAK,CAAC,CAAA;AAAA,EACnB;AACA,EAAA,OAAO,CAAC,GAAG,MAAA,CAAO,MAAA,EAAQ,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,EAAA,GAAK,EAAE,EAAE,CAAA;AACxD;AAqBO,SAAS,WAAA,CACd,KAAA,EACA,IAAA,GAA8B,EAAC,EACT;AACtB,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,KAAA,CAAM,MAAA,CAAO,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AACjD,EAAA,MAAM,aAAA,GAAgB,kBAAA,CAAmB,KAAA,CAAM,MAAM,CAAA,CAAE,MAAA;AAAA,IACrD,CAAC,CAAA,KAAM,GAAA,CAAI,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA,IAAK,GAAA,CAAI,GAAA,CAAI,CAAA,CAAE,SAAS;AAAA,GACpD;AAEA,EAAA,MAAM,MAAA,GAAS,qBAAA;AAAA,IACb,KAAA,CAAM,MAAA;AAAA,IACN,aAAA;AAAA,IACA,KAAA,CAAM,WAAA;AAAA,IACN,KAAA,CAAM,aAAA;AAAA,IACN;AAAA,GACF;AAEA,EAAA,MAAM,iBAAA,uBAAwB,GAAA,EAA4B;AAC1D,EAAA,KAAA,MAAW,KAAK,aAAA,EAAe;AAC7B,IAAA,IAAI,CAAA,CAAE,WAAW,YAAA,EAAc;AAC/B,IAAA,iBAAA,CAAkB,IAAI,iBAAA,GAAoB,CAAA,CAAE,IAAI,cAAA,CAAe,CAAA,CAAE,MAAM,CAAC,CAAA;AAAA,EAC1E;AAEA,EAAA,MAAM,GAAA,GAAM,kBAAkB,MAAA,EAAQ;AAAA,IACpC,iBAAA;AAAA,IACA,GAAI,KAAK,MAAA,KAAW,KAAA,GAAQ,EAAE,MAAA,EAAQ,KAAA,KAAU,EAAC;AAAA,IACjD,GAAI,KAAK,SAAA,KAAc,MAAA,GAAY,EAAE,MAAA,EAAQ,IAAA,CAAK,SAAA,EAAU,GAAI;AAAC,GAClE,CAAA;AACD,EAAA,OAAO,EAAE,KAAK,MAAA,EAAO;AACvB","file":"chunk-5RRRE2GF.js","sourcesContent":["// Genogram input model — declared facts only. compasso draws EXACTLY what the caller\n// declares and NEVER synthesizes structure: two declared parents without a declared\n// union never merge into a couple; a \"coparental\" union draws no couple element; a\n// free-text relationship never silently becomes kinship. Collection doctrine (who may\n// assert a fact, how it was captured) is the caller's concern — this is a renderer.\n\n/** Sex marker for a genogram node (standard notation: square/circle/diamond). */\nexport type PersonSex = \"male\" | \"female\" | \"unknown\";\n\n/** A genogram node. `generation` is relative (0 = index person; negative = older). */\nexport interface Person {\n id: number;\n label: string;\n sex: PersonSex;\n deceased: boolean;\n generation: number | null;\n}\n\n/**\n * CLOSED status vocabulary for a declared union. Notable semantics:\n * - \"coparental\": the two were NEVER a couple and have child(ren) together;\n * - \"unknown\": a union was declared, but its type was not;\n * - widowhood is NOT a status — death lives on Person.deceased and never\n * alters the declared status;\n * - no value for \"not stated\": the union simply is not passed in.\n */\nexport const UNION_STATUSES = [\n \"married\",\n \"cohabiting\",\n \"dating\",\n \"separated\",\n \"divorced\",\n \"coparental\",\n \"unknown\",\n] as const;\n\nexport type UnionStatus = (typeof UNION_STATUSES)[number];\n\n/**\n * A declared couple bond between two people. The pair is unordered and expected\n * normalized to personAId < personBId with ONE union per pair (duplicates are the\n * caller's to resolve). `quality` is the author's verbatim wording about the bond.\n */\nexport interface Union {\n id: number;\n /** Always the smaller person id (normalized pair). */\n personAId: number;\n personBId: number;\n status: UnionStatus;\n quality: string | null;\n}\n\n/**\n * A declared parentage link: parent → child, one row PER DECLARED genitor (two\n * genitors = two links, each individually stated — never promoted from a union).\n */\nexport interface ParentLink {\n id: number;\n parentId: number;\n childId: number;\n quality: string | null;\n}\n\n/**\n * A typed free-text edge between two people. `type` and `quality` are verbatim\n * labels. This carries NON-STRUCTURAL ties only (closeness, conflict…) — unions\n * and parentage are first-class above.\n */\nexport interface Relationship {\n id: number;\n fromPersonId: number;\n toPersonId: number;\n type: string;\n quality: string | null;\n}\n\n/** Input to the genogram render pipeline. */\nexport interface GenogramInput {\n people: Person[];\n unions: Union[];\n parentLinks: ParentLink[];\n relationships: Relationship[];\n}\n\n/** Node glyph shapes (standard notation: square = male, circle = female, diamond = unknown). */\nexport type NodeShape = \"square\" | \"circle\" | \"diamond\";\n","// Display vocabularies — every human-readable string the genogram emits, gathered in\n// overridable packs so the diagram localizes without touching the engine. English\n// defaults here; `compasso/locales/pt-br` ships a Brazilian Portuguese pack.\n\nimport type { EdgeLineStyle } from \"../core\";\nimport type { NodeShape, UnionStatus } from \"./types\";\n\n/** Labels woven into element <title>s by the LAYOUT (verbatim-preserving). */\nexport interface GenogramTitleLabels {\n unionStatus: Record<UnionStatus, string>;\n /** Title prefix for a parent→child descent (\"parent of\"). */\n parentage: string;\n}\n\nexport const GENOGRAM_TITLE_LABELS_EN: GenogramTitleLabels = {\n unionStatus: {\n married: \"married\",\n cohabiting: \"cohabiting\",\n dating: \"dating\",\n separated: \"separated\",\n divorced: \"divorced\",\n coparental: \"co-parents (never a couple)\",\n unknown: \"union (type not stated)\",\n },\n parentage: \"parent of\",\n};\n\n/** Labels drawn by the SVG EMITTER (legend entries, accessibility text). */\nexport interface GenogramSvgLabels {\n shapes: Record<NodeShape, string>;\n deceased: string;\n bondStyles: Record<Exclude<EdgeLineStyle, \"plain\">, string>;\n /** Legend label for the group of people with no drawn connection. */\n isolated: string;\n ariaLabel: string;\n}\n\nexport const GENOGRAM_SVG_LABELS_EN: GenogramSvgLabels = {\n shapes: {\n square: \"Man\",\n circle: \"Woman\",\n diamond: \"Sex not stated\",\n },\n deceased: \"Deceased\",\n bondStyles: {\n close: \"Close\",\n distant: \"Distant\",\n conflict: \"Conflictual\",\n cutoff: \"Cut off (no contact)\",\n },\n isolated: \"No recorded ancestry\",\n ariaLabel: \"Family map (genogram)\",\n};\n","// Relationship → MAP class (presentation only). A genogram draws only the structural\n// SKELETON: declared unions + parent links. A free-text `relationship` becomes a map\n// LINE only when it is NON-parentage. Kinship that is READ FROM THE TREE (grandparent/\n// sibling/uncle/cousin/nephew…) draws NOTHING — it is already implied by the descent/\n// union structure, so a dedicated line would only duplicate and clutter. A DIRECT\n// parentage word (mother/father/child) with no declared parent link is PROMOTED to a\n// descent (oriented by declared generation) so the person is not orphaned. NOTHING here\n// synthesizes undeclared structure: derived kinship draws nothing at all, and promotion\n// only ORIENTS an already-declared parent-child word. The verbatim \"type · quality\" of\n// EVERY relationship is the caller's to keep showing in its own lists.\n\nimport { normalizeText } from \"../core\";\n\nexport type RelationshipMapClass = \"derived\" | \"parentage\" | \"bond\";\n\n/**\n * A pluggable kinship vocabulary. Tokens are diacritic-free, lowercase, matched WHOLE\n * (so a token never matches inside another word) after splitting the type on\n * non-alphanumerics (\"half-brother\" → [\"half\",\"brother\"]). Checked DERIVED-first, so\n * \"brother on my father's side\" reads as a sibling, never as a parent. These lists are\n * closed and conservative — an unrecognized word stays a non-structural bond (the\n * honest default). Locale packs (e.g. `compasso/locales/pt-br`) ship alternates.\n */\nexport interface KinshipLexicon {\n /** Kinship read from the tree (sibling/grandparent/uncle/cousin…): never a line. */\n derived: ReadonlySet<string>;\n /** Direct parentage words (mother/father/son…): promotable to a descent. */\n parentage: ReadonlySet<string>;\n /** Parentage words whose FROM endpoint is the CHILD — used only to orient a\n * promotion when declared generations do not decide it. */\n childWords: ReadonlySet<string>;\n}\n\nexport const KINSHIP_EN: KinshipLexicon = {\n derived: new Set([\n \"brother\", \"brothers\", \"sister\", \"sisters\", \"sibling\", \"siblings\",\n \"grandmother\", \"grandfather\", \"grandma\", \"grandpa\", \"granny\", \"grandad\",\n \"granddad\", \"grandparent\", \"grandparents\",\n \"grandson\", \"granddaughter\", \"grandchild\", \"grandchildren\",\n \"uncle\", \"uncles\", \"aunt\", \"aunts\", \"auntie\",\n \"cousin\", \"cousins\",\n \"nephew\", \"nephews\", \"niece\", \"nieces\",\n ]),\n parentage: new Set([\n \"mother\", \"mothers\", \"mom\", \"mum\", \"father\", \"fathers\", \"dad\",\n \"parent\", \"parents\",\n \"son\", \"sons\", \"daughter\", \"daughters\",\n ]),\n childWords: new Set([\"son\", \"sons\", \"daughter\", \"daughters\"]),\n};\n\n/** Lowercase + accent-stripped tokens of a free-text relationship type. */\nexport function relationshipTypeTokens(type: string): string[] {\n return normalizeText(type).split(/[^a-z0-9]+/).filter((t) => t !== \"\");\n}\n\n/**\n * Classifies a free-text relationship `type` for the MAP. Pure + deterministic.\n * Derived kinship is checked first so a compound like \"brother on my father's side\"\n * is read as a sibling (derived), never promoted as a parent. The verbatim word is\n * unaffected — this decides only whether the tie becomes a line, and which kind.\n */\nexport function classifyRelationshipType(\n type: string,\n kinship: KinshipLexicon = KINSHIP_EN,\n): RelationshipMapClass {\n const toks = relationshipTypeTokens(type);\n if (toks.some((t) => kinship.derived.has(t))) return \"derived\";\n if (toks.some((t) => kinship.parentage.has(t))) return \"parentage\";\n return \"bond\";\n}\n","// PURE genogram layout — the single source of truth for positioning and glyph/edge\n// routing. The emitter (./svg.ts) draws EXACTLY what this computes, so any number of\n// surfaces (web, PDF, image pipelines) can never drift from each other.\n//\n// It is deliberately PURE — no DOM, no Node APIs, no clock, no randomness — so it loads\n// identically in browsers, server runtimes and test environments, and the same input\n// always yields the same layout. Anything with a side effect belongs elsewhere.\n//\n// HONESTY RULE: this module only POSITIONS and ROUTES the facts the caller declared. It\n// computes NO score, interpretation, prognosis or diagnosis, and it NEVER synthesizes\n// undeclared structure: a `coparental` union draws no couple element; two declared\n// parents WITHOUT a declared union never merge into a couple-bar descent (each gets its\n// own descent); free-text `relationships` stay non-structural bonds. Shapes follow the\n// standard genogram convention (square = male, circle = female, diamond = unknown; a\n// diagonal stroke marks deceased). The verbatim \"type · quality\" / status label is\n// ALWAYS kept on every routed element's <title>, so a style never replaces what was said.\n//\n// LAYOUT — orthogonal (McGoldrick) and overlap-proof BY CONSTRUCTION (not by luck). The\n// diagram is a grid: people sit in COLUMNS inside generation ROWS; the empty bands\n// BETWEEN columns (GUTTERS) and BETWEEN rows (CORRIDORS) are the only places routing\n// segments live, each in a numbered LANE allocated by interval-overlap so two segments\n// in the same lane can never overlap. Every consecutive pair of waypoints is axis-aligned\n// (horizontal or vertical) — there are NO diagonals and NO text on map edges (the\n// verbatim text rides the <title> and the caller's side lists). Glyphs and their labels\n// live entirely inside their columns; gutters and corridors are content-free by\n// construction, so a routed segment can never cross a glyph or a label box.\n//\n// PROVENANCE: descends from the production genogram renderer the author wrote for the\n// Ventory project (same copyright holder); developed independently of any third-party\n// diagram engine.\nimport {\n CHAR_W,\n estimateTextWidth,\n qualityLineStyle,\n wrapLabel,\n EDGE_STROKE,\n type EdgeLineStyle,\n type EdgeStroke,\n type Point,\n type QualityLexicon,\n} from \"../core\";\nimport { GENOGRAM_TITLE_LABELS_EN, type GenogramTitleLabels } from \"./labels\";\nimport {\n classifyRelationshipType,\n relationshipTypeTokens,\n KINSHIP_EN,\n type KinshipLexicon,\n type RelationshipMapClass,\n} from \"./kinship\";\nimport type {\n NodeShape,\n ParentLink,\n Person,\n PersonSex,\n Relationship,\n Union,\n} from \"./types\";\n\n// Re-exports so callers (and the emitter) can reach the full vocabulary through this\n// module, mirroring the original single-file layout.\nexport { CHAR_W, estimateTextWidth, qualityLineStyle, wrapLabel, EDGE_STROKE };\nexport type { EdgeLineStyle, EdgeStroke, Point, QualityLexicon };\nexport { classifyRelationshipType, relationshipTypeTokens, KINSHIP_EN };\nexport type { KinshipLexicon, RelationshipMapClass };\nexport type { NodeShape };\n\n// ── Geometry ──────────────────────────────────────────────────────────────────\nexport const NODE_SIZE = 56;\nconst PADDING = 32;\n/** Min horizontal gap between two adjacent columns' content boxes (a gutter's base). */\nconst COL_PAD = 30;\n/** Gap from a glyph's bottom to the top of its first label line. */\nconst LABEL_GAP_TOP = 8;\n/** Base height of a routing corridor (before lanes widen it). */\nconst CORRIDOR_BASE = 24;\n/** Vertical/horizontal spacing between two routing lanes in a corridor/gutter. */\nconst LANE_H = 8;\n/** Vertical drop between successive serial-union (remarriage) bars below the glyph row,\n * so 2+ unions on one person never read as one continuous rail (McGoldrick, FIX B). */\nconst UNION_STAGGER = 12;\n/** Horizontal offset (from glyph center, toward the partner) of a dipped union-bar's stub,\n * so a person in two serial unions gets two distinct stub columns (FIX B). < NODE_SIZE/2. */\nconst STUB_X_OFF = 14;\n/** Extra horizontal separation placed before an isolated-people group (SPEC). */\nconst ISOLATED_GUTTER_EXTRA = 2 * COL_PAD;\n\n// ── Type metrics (shared by layout AND both renderers, so geometry == render) ──\n/** Node label font size (px). The live SVG renders at this size; the PDF scales it. */\nexport const LABEL_FONT = 12;\n/** Line height for stacked node-label lines (px). */\nexport const LABEL_LINE_H = 14;\n/** Edge label font size (px) — kept for the shared metrics contract (invariant #9). */\nexport const EDGE_FONT = 11;\n// CHAR_W / estimateTextWidth live in ../core (re-exported above): the overlap-proof\n// guarantee depends on layout and emitters sharing these exact metrics.\n\n// ── Namespaced element ids (kept stable so data-edge-id stays traceable, §7.2) ──\n// relationships keep their own id; unions live at 1_000_000+id; parent links at\n// 2_000_000+id; PROMOTED descents (a direct-parentage free-text relationship drawn as a\n// descent — see classifyRelationshipType) at 3_000_000+rel id. Four disjoint blocks, so a\n// promoted descent never collides with a real parent link and every edge stays traceable\n// to its source. Deterministic, and visible in the overlap harness / data-edge-id.\nexport const UNION_REL_ID_BASE = 1_000_000;\nexport const PARENT_REL_ID_BASE = 2_000_000;\nexport const PROMOTED_REL_ID_BASE = 3_000_000;\n\n// ── Node glyphs ──────────────────────────────────────────────────────────────\nfunction shapeForSex(sex: PersonSex): NodeShape {\n if (sex === \"male\") return \"square\";\n if (sex === \"female\") return \"circle\";\n return \"diamond\";\n}\n\n// ── Edge line styles ─────────────────────────────────────────────────────────\n// EdgeLineStyle / EDGE_STROKE / qualityLineStyle live in ../core (re-exported above):\n// a neutral, presentation-only style for a NON-STRUCTURAL bond line, lexically hinted\n// from the author's own quality word — never a judgment, verbatim word always kept.\n\n/**\n * Per-edge VISUAL union style applied at emission (§7.2 / FIX 3) — the McGoldrick\n * notation for a declared union TYPE, WITHOUT touching the layout or the patient's\n * words. `coparental` never gets one (it draws no edge). Defined here (not in\n * fallback-svg) so a routed element can carry it and the emitter stays free of layout\n * cycles; fallback-svg re-exports it for the existing call sites.\n */\nexport interface UnionEdgeStyle {\n /** Inline stroke-dasharray [dash, gap] on the bar; absent = solid (e.g. casado). */\n dash?: readonly [number, number];\n /** Diagonal status slashes at the midpoint: 1 = separação, 2 = divórcio. */\n slashes?: 0 | 1 | 2;\n}\n\n// ── Relationship → MAP class ───────────────────────────────────────────────────\n// classifyRelationshipType / relationshipTypeTokens / KinshipLexicon live in ./kinship\n// (re-exported above): derived kinship draws NOTHING, direct parentage may be PROMOTED\n// to a descent, everything else stays a non-structural bond. wrapLabel lives in ../core.\n\n/** Wrap policy: split a label into roughly-balanced lines bounded to a sane width. */\nfunction wrapNodeLabel(displayLabel: string): string[] {\n const perLine = Math.min(26, Math.max(14, Math.ceil(displayLabel.length / 2) + 2));\n return wrapLabel(displayLabel, perLine);\n}\n\n/** Caps a verbatim label for a COMPACT render (preview); full text kept in `label`. */\nfunction clampLabel(label: string, maxChars: number | undefined): string {\n if (maxChars === undefined || label.length <= maxChars) return label;\n return label.slice(0, Math.max(1, maxChars - 1)) + \"…\";\n}\n\n// ── Positioned layout ────────────────────────────────────────────────────────\n\nexport interface GenogramNode {\n personId: number;\n /** Full, verbatim label (used for tooltips/aria — never truncated). */\n label: string;\n shape: NodeShape;\n deceased: boolean;\n /** Center of the node. */\n cx: number;\n cy: number;\n /** Side length (square) / diameter (circle) / width (diamond). */\n size: number;\n /** Pre-wrapped display lines (already capped for the requested density). */\n labelLines: string[];\n /** Y of the TOP of the first label line's box (each next line is +LABEL_LINE_H). */\n labelTop: number;\n}\n\n/** A routed map element — the orthogonal replacement for the old straight `GenogramEdge`. */\nexport type GenogramElementKind =\n | \"union-bar\" // adjacent same-row partners: straight H bar, glyph-edge to glyph-edge\n | \"union-elbow\" // non-adjacent / cross-row partners: orthogonal route\n | \"descent\" // parent(s) → child plumbing segment(s)\n | \"sibling-bar\" // one shared H bar per union child-group (≥1 children)\n | \"bond\"; // non-structural relationship, orthogonal route\n\nexport interface GenogramElement {\n kind: GenogramElementKind;\n /** Source row ids for traceability; merged bonds carry every merged rel id. */\n relIds: number[];\n /** data-edge-id value: highest relId (matches latestUnionPerPair's highest-wins). */\n edgeId: number;\n fromPersonId: number | null;\n toPersonId: number | null;\n /** Polyline; EVERY consecutive pair is axis-aligned (H or V). */\n points: Point[];\n /** Verbatim titles (one per source row), joined for the <title>. */\n titles: string[];\n lineStyle: EdgeLineStyle; // bonds only; structural elements are \"plain\"\n unionStyle?: UnionEdgeStyle; // union-bar / union-elbow: dash + slashes\n dotted?: boolean; // lone-parent / coparental descents\n}\n\nexport interface GenogramLayout {\n width: number;\n height: number;\n nodes: GenogramNode[];\n elements: GenogramElement[];\n /** People with NO drawn structural/bond connection — grouped to the side and labeled\n * \"Sem ascendência registrada\" so a loose glyph is never left unexplained. */\n isolatedPersonIds: number[];\n}\n\n// ── Internal working types ─────────────────────────────────────────────────────\n\n/**\n * A parent→child descent to draw — either a DECLARED parent_link (real) or a PROMOTED\n * direct-parentage relationship (no declared link existed for the pair). `edgeId` is\n * pre-namespaced (real: PARENT_REL_ID_BASE+link id; promoted: PROMOTED_REL_ID_BASE+rel id),\n * so both flow through the same descent machinery and stay traceable in data-edge-id.\n */\ninterface LayoutLink {\n parentId: number;\n childId: number;\n quality: string | null;\n edgeId: number;\n}\n\ninterface Measured {\n person: Person;\n lines: string[];\n /** max(NODE_SIZE, widest wrapped line) — the horizontal footprint. */\n contentW: number;\n}\n\n/** A vertical segment living in a gutter, awaiting a lane. */\ninterface GutterReq {\n gutter: number; // gutter index g in [-1, colCount-1]\n side: -1 | 0 | 1; // -1 hug left column, +1 hug right column, 0 center (union spine)\n rowLo: number; // continuous row coordinate (row r → r; corridor k → k+0.5)\n rowHi: number;\n lane: number; // filled by the allocator\n}\n\n/** A horizontal segment living in a corridor, awaiting a lane. Its pixel x-interval is\n * resolved AFTER the column/gutter geometry is fixed, so the lane allocator can use the\n * EXACT extent (a u-index proxy collapses for within-one-gutter spans). */\ninterface CorridorReq {\n corridor: number; // corridor index k in [0, rowCount-1] (k = below row k)\n xRange: () => [number, number]; // pixel [xMin, xMax], resolved post-column-geometry\n lane: number;\n}\n\n/** A sideways glyph departure stub, awaiting a height slot. */\ninterface StubReq {\n personId: number;\n side: -1 | 1;\n slot: number; // height slot index, filled below\n}\n\n/** An arrival into a glyph TOP, awaiting an x-offset slot. */\ninterface ArrivalReq {\n personId: number;\n slot: number;\n}\n\n/** A planned element: its kind/metadata + a builder that resolves to pixel points. */\ninterface PlannedElement {\n kind: GenogramElementKind;\n relIds: number[];\n edgeId: number;\n fromPersonId: number | null;\n toPersonId: number | null;\n titles: string[];\n lineStyle: EdgeLineStyle;\n unionStyle?: UnionEdgeStyle;\n dotted?: boolean;\n build: () => Point[];\n}\n\n// Height slots for stacked departures from one glyph side (avoid y=cy so a union bar at\n// cy is never crossed). Within ±(NODE_SIZE/2 − 4) so the stub stays on the glyph edge.\nconst STUB_OFFSETS = [9, -9, 18, -18, 26, -26] as const;\n/** Max |x-offset| for an arrival into a glyph TOP (kept inside the top edge half-width). */\nconst ARRIVAL_HALF = NODE_SIZE / 2 - 8;\n\nfunction stubOffset(slot: number): number {\n return STUB_OFFSETS[Math.min(slot, STUB_OFFSETS.length - 1)]!;\n}\n/** Spread arrivals across a glyph TOP so each lands on a distinct x — slot 0 stays\n * CENTERED (the primary descent), later arrivals alternate to either side. For any\n * fan-in count, no two verticals share a column (overlap-proof). */\nfunction arrivalOffset(slot: number, total: number): number {\n if (slot === 0 || total <= 1) return 0;\n const step = Math.min(12, ARRIVAL_HALF / Math.max(1, Math.ceil((total - 1) / 2)));\n const sign = slot % 2 === 1 ? -1 : 1;\n return sign * Math.ceil(slot / 2) * step;\n}\n\n/** Allocate lanes for a set of intervals: each takes the lowest lane free over its span\n * (touching at an endpoint does NOT count as overlap, so collinear segments may abut). */\nfunction allocateLanes(items: { lo: number; hi: number; set: (lane: number) => void }[]): number {\n const lanes: { lo: number; hi: number }[][] = [];\n for (const it of items) {\n let chosen = -1;\n for (let l = 0; l < lanes.length; l++) {\n if (lanes[l]!.every((o) => it.hi <= o.lo || it.lo >= o.hi)) {\n chosen = l;\n break;\n }\n }\n if (chosen === -1) {\n chosen = lanes.length;\n lanes.push([]);\n }\n lanes[chosen]!.push({ lo: it.lo, hi: it.hi });\n it.set(chosen);\n }\n return lanes.length;\n}\n\n/**\n * Deterministic, overlap-proof ORTHOGONAL layout (pure function of the inputs — same\n * data always yields the same geometry). People are grouped by `generation` (null trails\n * as a bottom row), rows ordered oldest-on-top. Declared structure is drawn as McGoldrick\n * elements: same-row adjacent unions as straight bars, couples-with-children as a shared\n * sibling bar, lone/co-parental genitors as dotted descents, and free-text relationships\n * as orthogonally-routed bonds — NEVER promoting a bond into structure.\n *\n * @param unions caller-deduped (one per pair) declared couple bonds.\n * @param parentLinks declared parent→child links (one row per declared genitor).\n * @param relationships non-structural ties (drawn as bonds).\n * @param opts.maxLabelChars cap each node's DISPLAY label to this many chars (compact\n * preview); the full verbatim text is still exposed on `node.label`.\n * @param opts.kinship / opts.qualityLexicon / opts.titleLabels — locale packs (English\n * defaults; see `compasso/locales/pt-br`).\n */\nexport interface GenogramLayoutOptions {\n maxLabelChars?: number;\n kinship?: KinshipLexicon;\n qualityLexicon?: QualityLexicon;\n titleLabels?: GenogramTitleLabels;\n}\n\nexport function computeGenogramLayout(\n people: Person[],\n unions: Union[],\n parentLinks: ParentLink[],\n relationships: Relationship[],\n opts: GenogramLayoutOptions = {},\n): GenogramLayout {\n const kinship = opts.kinship ?? KINSHIP_EN;\n const titleLabels = opts.titleLabels ?? GENOGRAM_TITLE_LABELS_EN;\n if (people.length === 0) {\n return { width: PADDING * 2, height: PADDING * 2, nodes: [], elements: [], isolatedPersonIds: [] };\n }\n\n const ids = new Set(people.map((p) => p.id));\n const pairKey = (a: number, b: number): string => `${Math.min(a, b)}|${Math.max(a, b)}`;\n const genById = new Map<number, number | null>(people.map((p) => [p.id, p.generation]));\n\n // Sanitize structural inputs (drop self/missing endpoints — keep declared facts only).\n const validUnions = unions\n .filter((u) => ids.has(u.personAId) && ids.has(u.personBId) && u.personAId !== u.personBId)\n .sort((a, b) => a.id - b.id);\n const coupleUnions = validUnions.filter((u) => u.status !== \"coparental\");\n const validLinks = parentLinks\n .filter((l) => ids.has(l.parentId) && ids.has(l.childId) && l.parentId !== l.childId)\n .sort((a, b) => a.id - b.id);\n const validRels = relationships\n .filter((r) => ids.has(r.fromPersonId) && ids.has(r.toPersonId) && r.fromPersonId !== r.toPersonId)\n .sort((a, b) => a.id - b.id);\n\n // ── SKELETON-ONLY (presentation): classify each free-text relationship for the MAP ─────\n // - \"derived\" (avó/irmão/tio/…): READ from the tree → draws NOTHING here.\n // - \"parentage\" (mãe/pai/filho/…): a declared parent-child word → PROMOTED to a descent\n // when no parent_link already declares the pair (else a duplicate, dropped\n // from the map); never a bond.\n // - \"bond\" (everything else): a non-structural tie → drawn as a bond, as before.\n // The verbatim \"type · quality\" of EVERY relationship still rides the dossier side lists.\n const relClass = new Map<number, RelationshipMapClass>(\n validRels.map((r) => [r.id, classifyRelationshipType(r.type, kinship)]),\n );\n const bondRels = validRels.filter((r) => relClass.get(r.id) === \"bond\");\n const parentageRels = validRels.filter((r) => relClass.get(r.id) === \"parentage\");\n\n // Effective descents = declared parent_links (real) + promoted parentage relationships.\n const realLinks: LayoutLink[] = validLinks.map((l) => ({\n parentId: l.parentId,\n childId: l.childId,\n quality: l.quality,\n edgeId: PARENT_REL_ID_BASE + l.id,\n }));\n const declaredPairs = new Set(validLinks.map((l) => pairKey(l.parentId, l.childId)));\n const promotedByPair = new Map<string, LayoutLink>();\n for (const r of parentageRels) {\n const key = pairKey(r.fromPersonId, r.toPersonId);\n if (declaredPairs.has(key)) continue; // already a declared parent_link → no double-draw\n if (promotedByPair.has(key)) continue; // same pair stated twice → one descent (id-order)\n // Orient parent→child by DECLARED generation (older = parent). When generations do not\n // decide (equal or null), fall back to the parentage WORD + the declared from/to:\n // mãe/pai → from is the parent; filho/filha → from is the child. Either way nothing is\n // invented — both endpoints and the parent-child nature were declared; only the arrow.\n const ga = genById.get(r.fromPersonId) ?? null;\n const gb = genById.get(r.toPersonId) ?? null;\n let parentId: number;\n let childId: number;\n if (ga !== null && gb !== null && ga !== gb) {\n [parentId, childId] = ga < gb ? [r.fromPersonId, r.toPersonId] : [r.toPersonId, r.fromPersonId];\n } else {\n const fromIsChild = relationshipTypeTokens(r.type).some((t) => kinship.childWords.has(t));\n [parentId, childId] = fromIsChild ? [r.toPersonId, r.fromPersonId] : [r.fromPersonId, r.toPersonId];\n }\n if (parentId === childId) continue;\n promotedByPair.set(key, { parentId, childId, quality: r.quality, edgeId: PROMOTED_REL_ID_BASE + r.id });\n }\n const allLinks: LayoutLink[] = [...realLinks, ...promotedByPair.values()].sort((a, b) => a.edgeId - b.edgeId);\n\n // Declared (non-coparental) union lookup by unordered pair → union.\n const coupleByPair = new Map<string, Union>();\n for (const u of coupleUnions) coupleByPair.set(pairKey(u.personAId, u.personBId), u);\n\n // Parents per child and links per (parent,child) — real links + promoted descents.\n const parentsOf = new Map<number, number[]>();\n const linkOf = new Map<string, LayoutLink>();\n for (const l of allLinks) {\n const arr = parentsOf.get(l.childId) ?? [];\n if (!arr.includes(l.parentId)) arr.push(l.parentId);\n parentsOf.set(l.childId, arr);\n linkOf.set(`${l.parentId}>${l.childId}`, l);\n }\n\n // A person is ISOLATED when they have NO drawn connection: no union, no descent (real or\n // promoted), and no bond. A relationship suppressed from the map (derived kinship like\n // \"minha tia\", read from the tree) does NOT count as a tie — so such a person is grouped\n // to the side and labeled \"Sem ascendência registrada\", never left as a loose glyph.\n const hasTie = new Set<number>();\n for (const u of validUnions) {\n hasTie.add(u.personAId);\n hasTie.add(u.personBId);\n }\n for (const l of allLinks) {\n hasTie.add(l.parentId);\n hasTie.add(l.childId);\n }\n for (const r of bondRels) {\n hasTie.add(r.fromPersonId);\n hasTie.add(r.toPersonId);\n }\n const isIsolated = (id: number): boolean => !hasTie.has(id);\n\n // ── Pass 1a: rows by declared generation (null last), oldest on top ──────────────\n const byGen = new Map<number | null, Person[]>();\n for (const p of people) {\n const bucket = byGen.get(p.generation);\n if (bucket === undefined) byGen.set(p.generation, [p]);\n else bucket.push(p);\n }\n const genKeys = [...byGen.keys()].sort((a, b) => {\n if (a === null) return 1;\n if (b === null) return -1;\n return a - b;\n });\n const rowCount = genKeys.length;\n const rowOfPerson = new Map<number, number>();\n genKeys.forEach((g, r) => byGen.get(g)!.forEach((p) => rowOfPerson.set(p.id, r)));\n\n // ── Pass 1b: couple BLOCKS per row (connected components of same-row couple unions),\n // linearized so partners land adjacent; then barycenter ordering; isolated rightmost.\n type Block = number[]; // person ids, left-to-right\n const rowBlocks: Block[][] = genKeys.map((g, r) => {\n const members = byGen.get(g)!.map((p) => p.id);\n // adjacency from same-row couple unions\n const adj = new Map<number, number[]>();\n for (const id of members) adj.set(id, []);\n for (const u of coupleUnions) {\n if (rowOfPerson.get(u.personAId) === r && rowOfPerson.get(u.personBId) === r) {\n adj.get(u.personAId)!.push(u.personBId);\n adj.get(u.personBId)!.push(u.personAId);\n }\n }\n for (const id of members) adj.get(id)!.sort((a, b) => a - b);\n // connected components\n const seen = new Set<number>();\n const blocks: Block[] = [];\n for (const start of [...members].sort((a, b) => a - b)) {\n if (seen.has(start)) continue;\n const comp: number[] = [];\n const stack = [start];\n seen.add(start);\n while (stack.length > 0) {\n const n = stack.pop()!;\n comp.push(n);\n for (const m of adj.get(n)!) if (!seen.has(m)) { seen.add(m); stack.push(m); }\n }\n blocks.push(linearizeBlock(comp, adj));\n }\n return blocks;\n });\n\n // Barycenter sweeps (downward then upward), gated on rowCount ≥ 2. Aesthetic only —\n // it reorders blocks to align children under parents; it never moves anyone off a row.\n const flattened = (): Map<number, number> => {\n const pos = new Map<number, number>();\n for (const blocks of rowBlocks) {\n let c = 0;\n for (const b of blocks) for (const id of b) pos.set(id, c++);\n }\n return pos;\n };\n const structuralNeighbors = (id: number): number[] => {\n const out: { id: number; w: number }[] = [];\n // Barycenter ordering uses NON-coparental unions only (SPEC Pass 1 / FIX E): a\n // coparental pair draws no couple bar, so it must exert no ordering attraction either.\n for (const u of coupleUnions) {\n if (u.personAId === id) out.push({ id: u.personBId, w: 1 });\n else if (u.personBId === id) out.push({ id: u.personAId, w: 1 });\n }\n for (const l of allLinks) {\n if (l.childId === id) out.push({ id: l.parentId, w: 1 });\n else if (l.parentId === id) out.push({ id: l.childId, w: 1 });\n }\n for (const rl of bondRels) {\n if (rl.fromPersonId === id) out.push({ id: rl.toPersonId, w: 0.5 });\n else if (rl.toPersonId === id) out.push({ id: rl.fromPersonId, w: 0.5 });\n }\n return out.map((o) => o.id);\n };\n const neighborWeight = (id: number, other: number): number => {\n let w = 0;\n // NON-coparental unions only — same FIX E rationale as structuralNeighbors.\n for (const u of coupleUnions) if ((u.personAId === id && u.personBId === other) || (u.personBId === id && u.personAId === other)) w = Math.max(w, 1);\n for (const l of allLinks) if ((l.childId === id && l.parentId === other) || (l.parentId === id && l.childId === other)) w = Math.max(w, 1);\n for (const rl of bondRels) if ((rl.fromPersonId === id && rl.toPersonId === other) || (rl.toPersonId === id && rl.fromPersonId === other)) w = Math.max(w, 0.5);\n return w;\n };\n const sweep = (r: number, ref: number): void => {\n const pos = flattened();\n const blocks = rowBlocks[r]!;\n const bcOf = (b: Block): number => {\n let sum = 0;\n let wsum = 0;\n for (const id of b) {\n for (const nb of structuralNeighbors(id)) {\n if (rowOfPerson.get(nb) !== ref) continue;\n const w = neighborWeight(id, nb);\n sum += (pos.get(nb) ?? 0) * w;\n wsum += w;\n }\n }\n return wsum === 0 ? Number.POSITIVE_INFINITY : sum / wsum;\n };\n const keyed = blocks.map((b) => ({ b, bc: bcOf(b), minId: Math.min(...b) }));\n keyed.sort((x, y) => (x.bc !== y.bc ? x.bc - y.bc : x.minId - y.minId));\n rowBlocks[r] = keyed.map((k) => k.b);\n };\n if (rowCount >= 2) {\n for (let r = 1; r < rowCount; r++) sweep(r, r - 1);\n for (let r = rowCount - 2; r >= 0; r--) sweep(r, r + 1);\n }\n\n // Isolated people drift fully right: stable-partition each row so isolated singleton\n // blocks trail the connected ones (ordered by id). No connector is ever drawn for them.\n for (let r = 0; r < rowCount; r++) {\n const blocks = rowBlocks[r]!;\n const connected = blocks.filter((b) => !(b.length === 1 && isIsolated(b[0]!)));\n const isolated = blocks.filter((b) => b.length === 1 && isIsolated(b[0]!)).sort((a, b) => a[0]! - b[0]!);\n rowBlocks[r] = [...connected, ...isolated];\n }\n\n // ── Pass 1c: assign (row, col) to every person via the global column grid ─────────\n const colOf = new Map<number, number>();\n let colCount = 0;\n for (let r = 0; r < rowCount; r++) {\n let c = 0;\n for (const b of rowBlocks[r]!) for (const id of b) colOf.set(id, c++);\n colCount = Math.max(colCount, c);\n }\n const colOrThrow = (id: number): number => colOf.get(id)!;\n\n // Column where the isolated-only tail begins (extra gutter sits just before it).\n let isolatedTailCol = colCount; // none by default\n {\n const peopleAtCol: number[][] = Array.from({ length: colCount }, () => []);\n for (const p of people) peopleAtCol[colOrThrow(p.id)]!.push(p.id);\n for (let c = colCount - 1; c >= 1; c--) {\n const all = peopleAtCol[c]!;\n if (all.length > 0 && all.every((id) => isIsolated(id))) isolatedTailCol = c;\n else break;\n }\n }\n\n // ── Pass 2 prep: measure labels; column widths; per-row label heights ─────────────\n const measured = new Map<number, Measured>();\n for (const p of people) {\n const lines = wrapNodeLabel(clampLabel(p.label, opts.maxLabelChars));\n const contentW = Math.max(NODE_SIZE, lines.reduce((m, l) => Math.max(m, estimateTextWidth(l, LABEL_FONT)), 0));\n measured.set(p.id, { person: p, lines, contentW });\n }\n const colWidth: number[] = Array.from({ length: colCount }, () => NODE_SIZE);\n for (const p of people) {\n const c = colOrThrow(p.id);\n colWidth[c] = Math.max(colWidth[c]!, measured.get(p.id)!.contentW);\n }\n const rowMaxLines: number[] = Array.from({ length: rowCount }, () => 1);\n for (const p of people) {\n const r = rowOfPerson.get(p.id)!;\n rowMaxLines[r] = Math.max(rowMaxLines[r]!, measured.get(p.id)!.lines.length);\n }\n\n // ── Pass 2: route every element symbolically and register lane/slot requests ──────\n const planned: PlannedElement[] = [];\n const gutterReqs: GutterReq[] = [];\n const corridorReqs: CorridorReq[] = [];\n const stubCount = new Map<string, number>(); // `${id}:${side}` → slots used\n const arrivalCount = new Map<number, number>(); // id → arrival slots used\n\n const newStub = (personId: number, side: -1 | 1): StubReq => {\n const key = `${personId}:${side}`;\n const slot = stubCount.get(key) ?? 0;\n stubCount.set(key, slot + 1);\n return { personId, side, slot };\n };\n const newArrival = (personId: number): ArrivalReq => {\n const slot = arrivalCount.get(personId) ?? 0;\n arrivalCount.set(personId, slot + 1);\n return { personId, slot };\n };\n const departSide = (srcId: number, dstId: number): -1 | 1 => {\n const sc = colOrThrow(srcId);\n const dc = colOrThrow(dstId);\n if (dc > sc) return 1;\n if (dc < sc) return -1;\n return sc < colCount - 1 ? 1 : -1;\n };\n // The gutter a connector departs INTO, and which side of it the departing column is on.\n const gutterFor = (srcCol: number, side: -1 | 1): { gutter: number; gSide: -1 | 1 } =>\n side === 1\n ? { gutter: srcCol, gSide: -1 } // depart right → gutter to the right; src is its LEFT column\n : { gutter: srcCol - 1, gSide: 1 }; // depart left → gutter to the left; src is its RIGHT column\n\n // A cross-row connector: sideways stub from the UPPER node, gutter drop, corridor cross,\n // arrival into the LOWER glyph TOP. Returns a builder closure over the resolved geo.\n // Robust to either argument order: it routes from whichever node is in the SHALLOWER\n // (upper) declared generation, so a parent declared in a YOUNGER generation than the\n // child (srcRow > dstRow) still gets a valid, non-negative, in-range corridor and an\n // ordered gutter span instead of a negative index (FIX D-1). Normal upper→lower calls\n // are unchanged: the upper node is the source and corridor = lowerRow − 1 as before.\n const planConnector = (\n srcId: number,\n dstId: number,\n arrivalAtCenter: boolean,\n ): (() => Point[]) => {\n const srcRow = rowOfPerson.get(srcId)!;\n const dstRow = rowOfPerson.get(dstId)!;\n // Departure is always from the upper node; arrival into the lower node's TOP edge.\n const [upperId, lowerId] = srcRow <= dstRow ? [srcId, dstId] : [dstId, srcId];\n const upperRow = rowOfPerson.get(upperId)!;\n const lowerRow = rowOfPerson.get(lowerId)!;\n const side = departSide(upperId, lowerId);\n const { gutter, gSide } = gutterFor(colOrThrow(upperId), side);\n const stub = newStub(upperId, side);\n // Corridor just above the lower row, clamped in-range (degenerate same-row → band 0).\n const corridor = Math.max(0, Math.min(rowCount - 1, lowerRow - 1));\n const gReq: GutterReq = {\n gutter,\n side: gSide,\n rowLo: Math.min(upperRow, corridor + 0.5),\n rowHi: Math.max(upperRow, corridor + 0.5),\n lane: 0,\n };\n gutterReqs.push(gReq);\n const arrival = arrivalAtCenter ? null : newArrival(lowerId);\n const arrivalX = (): number =>\n geo.cx(colOrThrow(lowerId)) + (arrival ? arrivalOffset(arrival.slot, arrivalCount.get(lowerId) ?? 1) : 0);\n const cReq: CorridorReq = {\n corridor,\n xRange: () => {\n const gx = geo.gutterLaneX(gReq);\n const ax = arrivalX();\n return [Math.min(gx, ax), Math.max(gx, ax)];\n },\n lane: 0,\n };\n corridorReqs.push(cReq);\n return () => {\n const sy = geo.cy(upperRow) + stubOffset(stub.slot);\n const sEdge = side === 1 ? geo.glyphRight(upperId) : geo.glyphLeft(upperId);\n const gx = geo.gutterLaneX(gReq);\n const cyCorr = geo.corridorLaneY(cReq);\n const ax = arrivalX();\n const topY = geo.cy(lowerRow) - NODE_SIZE / 2;\n return [\n { x: sEdge, y: sy },\n { x: gx, y: sy },\n { x: gx, y: cyCorr },\n { x: ax, y: cyCorr },\n { x: ax, y: topY },\n ];\n };\n };\n\n // A same-row connector (U under the row): both endpoints leave sideways toward each\n // other, drop into the corridor below the row, and cross there.\n const planUConnector = (aId: number, bId: number): (() => Point[]) => {\n const row = rowOfPerson.get(aId)!;\n const [leftId, rightId] = colOrThrow(aId) <= colOrThrow(bId) ? [aId, bId] : [bId, aId];\n const stubL = newStub(leftId, 1);\n const stubR = newStub(rightId, -1);\n const gL = gutterFor(colOrThrow(leftId), 1);\n const gR = gutterFor(colOrThrow(rightId), -1);\n const gReqL: GutterReq = { gutter: gL.gutter, side: gL.gSide, rowLo: row, rowHi: row + 0.5, lane: 0 };\n const gReqR: GutterReq = { gutter: gR.gutter, side: gR.gSide, rowLo: row, rowHi: row + 0.5, lane: 0 };\n gutterReqs.push(gReqL, gReqR);\n const cReq: CorridorReq = {\n corridor: row,\n xRange: () => {\n const xL = geo.gutterLaneX(gReqL);\n const xR = geo.gutterLaneX(gReqR);\n return [Math.min(xL, xR), Math.max(xL, xR)];\n },\n lane: 0,\n };\n corridorReqs.push(cReq);\n return () => {\n const yL = geo.cy(row) + stubOffset(stubL.slot);\n const yR = geo.cy(row) + stubOffset(stubR.slot);\n const xL = geo.gutterLaneX(gReqL);\n const xR = geo.gutterLaneX(gReqR);\n const cyCorr = geo.corridorLaneY(cReq);\n return [\n { x: geo.glyphRight(leftId), y: yL },\n { x: xL, y: yL },\n { x: xL, y: cyCorr },\n { x: xR, y: cyCorr },\n { x: xR, y: yR },\n { x: geo.glyphLeft(rightId), y: yR },\n ];\n };\n };\n\n const unionTitle = (u: Union): string =>\n u.quality !== null\n ? `${titleLabels.unionStatus[u.status]} · ${u.quality}`\n : titleLabels.unionStatus[u.status];\n const linkTitle = (l: { quality: string | null }): string =>\n l.quality !== null ? `${titleLabels.parentage} · ${l.quality}` : titleLabels.parentage;\n\n // 2a. Unions: same-row adjacent → bar; otherwise → elbow. (coparental drew nothing.)\n // McGoldrick SERIAL-UNION staggering (FIX B): when a person is in 2+ same-row union-bars\n // (remarriage), the bars would all sit at glyph-center cy and read as ONE continuous\n // rail. So within each connected chain of adjacent bars (components sharing a person),\n // the LOWEST union id stays at cy (level 0) and every other bar DIPS to a distinct depth\n // below the row's glyphs (level k → glyph bottom + k·UNION_STAGGER), drawn as a 3-seg\n // elbow (stub-down from each partner's glyph bottom → across → stub-up). The dip depth\n // is reserved in the row band (`rowDipDepth`) so labels never collide.\n const unionIsBar = new Map<number, boolean>();\n const barUnions = coupleUnions.filter(\n (u) =>\n rowOfPerson.get(u.personAId) === rowOfPerson.get(u.personBId) &&\n Math.abs(colOrThrow(u.personAId) - colOrThrow(u.personBId)) === 1,\n );\n // Per row, connected components of adjacent bar-unions (sharing a person), each ordered\n // by union id; index 0 → level 0 (cy), index k → dip level k. Deterministic.\n const unionDipLevel = new Map<number, number>(); // union id → dip level (0 = at cy)\n const rowDipLevels: number[] = Array.from({ length: rowCount }, () => 0);\n {\n const byRow = new Map<number, Union[]>();\n for (const u of barUnions) {\n const r = rowOfPerson.get(u.personAId)!;\n (byRow.get(r) ?? byRow.set(r, []).get(r)!).push(u);\n }\n for (const [r, rowUnions] of byRow) {\n // person → adjacent bar-unions on this row\n const unionsOfPerson = new Map<number, Union[]>();\n for (const u of rowUnions) {\n (unionsOfPerson.get(u.personAId) ?? unionsOfPerson.set(u.personAId, []).get(u.personAId)!).push(u);\n (unionsOfPerson.get(u.personBId) ?? unionsOfPerson.set(u.personBId, []).get(u.personBId)!).push(u);\n }\n const seen = new Set<number>();\n // Stable component discovery: walk unions in ascending id; BFS the shared-person graph.\n for (const start of [...rowUnions].sort((a, b) => a.id - b.id)) {\n if (seen.has(start.id)) continue;\n const comp: Union[] = [];\n const stack = [start];\n seen.add(start.id);\n while (stack.length > 0) {\n const u = stack.pop()!;\n comp.push(u);\n for (const pid of [u.personAId, u.personBId]) {\n for (const nb of unionsOfPerson.get(pid) ?? []) {\n if (!seen.has(nb.id)) {\n seen.add(nb.id);\n stack.push(nb);\n }\n }\n }\n }\n comp.sort((a, b) => a.id - b.id);\n comp.forEach((u, i) => unionDipLevel.set(u.id, i));\n rowDipLevels[r] = Math.max(rowDipLevels[r]!, comp.length - 1);\n }\n }\n }\n\n for (const u of coupleUnions) {\n const aRow = rowOfPerson.get(u.personAId)!;\n const bRow = rowOfPerson.get(u.personBId)!;\n const adjacent =\n aRow === bRow && Math.abs(colOrThrow(u.personAId) - colOrThrow(u.personBId)) === 1;\n unionIsBar.set(u.id, adjacent);\n const edgeId = UNION_REL_ID_BASE + u.id;\n if (adjacent) {\n const [leftId, rightId] = colOrThrow(u.personAId) < colOrThrow(u.personBId)\n ? [u.personAId, u.personBId]\n : [u.personBId, u.personAId];\n const dipLevel = unionDipLevel.get(u.id) ?? 0;\n planned.push({\n kind: \"union-bar\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: u.personAId,\n toPersonId: u.personBId,\n titles: [unionTitle(u)],\n lineStyle: \"plain\",\n build: () => {\n const cy = geo.cy(rowOfPerson.get(leftId)!);\n if (dipLevel === 0) {\n // First bar of the chain: the classic straight bar at glyph-center cy.\n return [\n { x: geo.glyphRight(leftId), y: cy },\n { x: geo.glyphLeft(rightId), y: cy },\n ];\n }\n // Dipped bar: stub-down from each partner's glyph BOTTOM to the dipped Y, across.\n // The stubs leave the glyph bottom OFFSET toward the partner (left partner →\n // right-of-center, right partner → left-of-center), so a person in two serial\n // unions (one on each side) gets two distinct stub columns that never overlap.\n const y = geo.unionDipY(rowOfPerson.get(leftId)!, dipLevel);\n const bottom = cy + NODE_SIZE / 2;\n const lx = geo.cx(colOrThrow(leftId)) + STUB_X_OFF; // partner is to the right\n const rx = geo.cx(colOrThrow(rightId)) - STUB_X_OFF; // partner is to the left\n return [\n { x: lx, y: bottom },\n { x: lx, y },\n { x: rx, y },\n { x: rx, y: bottom },\n ];\n },\n });\n } else {\n const sameRow = aRow === bRow;\n const build = sameRow\n ? planUConnector(u.personAId, u.personBId)\n : (() => {\n const [up, lo] = aRow < bRow ? [u.personAId, u.personBId] : [u.personBId, u.personAId];\n return planConnector(up, lo, false);\n })();\n planned.push({\n kind: \"union-elbow\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: u.personAId,\n toPersonId: u.personBId,\n titles: [unionTitle(u)],\n lineStyle: \"plain\",\n build,\n });\n }\n }\n\n // 2b. Descents. Decide, per child, the single declared COUPLE pair (if any) whose\n // union is an adjacent bar; that pair gets the shared sibling-bar descent, every\n // other declared genitor gets a dotted lone descent. No declared couple → all\n // dotted (Caso B / co-parental): each genitor its own descent, never a bar.\n const coupleChildrenByUnion = new Map<number, number[]>(); // union id → children\n const loneLinks: LayoutLink[] = [];\n for (const childId of [...parentsOf.keys()].sort((a, b) => a - b)) {\n const parents = [...parentsOf.get(childId)!].sort((a, b) => a - b);\n const couplePairUnions = parents\n .flatMap((p, i) => parents.slice(i + 1).map((q) => coupleByPair.get(pairKey(p, q))))\n .filter((u): u is Union => u !== undefined && unionIsBar.get(u.id) === true);\n if (couplePairUnions.length === 1) {\n const u = couplePairUnions[0]!;\n const arr = coupleChildrenByUnion.get(u.id) ?? [];\n arr.push(childId);\n coupleChildrenByUnion.set(u.id, arr);\n const couplePeople = new Set([u.personAId, u.personBId]);\n for (const p of parents) if (!couplePeople.has(p)) loneLinks.push(linkOf.get(`${p}>${childId}`)!);\n } else {\n for (const p of parents) loneLinks.push(linkOf.get(`${p}>${childId}`)!);\n }\n }\n\n // Couple descents (processed first, by union id): one shared sibling-bar per child-row\n // group, a center spine from the bar, and a vertical drop to each child's glyph TOP.\n for (const u of coupleUnions) {\n const children = coupleChildrenByUnion.get(u.id);\n if (children === undefined || children.length === 0) continue;\n const leftId = colOrThrow(u.personAId) < colOrThrow(u.personBId) ? u.personAId : u.personBId;\n const interGutter = colOrThrow(leftId); // gutter between the two adjacent partners\n const parentRow = rowOfPerson.get(u.personAId)!;\n // A couple descent must leave the union BAR, so on a dipped (serial-union) bar the\n // spine starts at the dipped bar's Y, not the glyph-center cy (FIX B).\n const uDipLevel = unionDipLevel.get(u.id) ?? 0;\n const spineStartY = (): number =>\n uDipLevel === 0 ? geo.cy(parentRow) : geo.unionDipY(parentRow, uDipLevel);\n // Group children by their row (almost always one row).\n const byChildRow = new Map<number, number[]>();\n for (const c of children) {\n const cr = rowOfPerson.get(c)!;\n (byChildRow.get(cr) ?? byChildRow.set(cr, []).get(cr)!).push(c);\n }\n for (const childRow of [...byChildRow.keys()].sort((a, b) => a - b)) {\n const groupKids = byChildRow.get(childRow)!.sort((a, b) => colOrThrow(a) - colOrThrow(b));\n // Corridor just above the child row; clamped in-range so a degenerate \"couple + child\n // all on generation 0\" (childRow === 0) routes in band 0 instead of corridor[-1]\n // (undefined) — defensive, no fixture triggers it (FIX D-2).\n const corridor = Math.max(0, Math.min(rowCount - 1, childRow - 1));\n // The descent lives in ONE corridor lane shared by the spine, sibling bar and the\n // child drops, spanning the spine column and every child column.\n const sibSpan = (): number[] => [geo.gutterCenterX(interGutter), ...groupKids.map((c) => geo.cx(colOrThrow(c)))];\n const sibReq: CorridorReq = {\n corridor,\n xRange: () => {\n const xs = sibSpan();\n return [Math.min(...xs), Math.max(...xs)];\n },\n lane: 0,\n };\n corridorReqs.push(sibReq);\n const spineReq: GutterReq = {\n gutter: interGutter,\n side: 0,\n rowLo: Math.min(parentRow, corridor + 0.5), // ordered (FIX D-2): never inverted\n rowHi: Math.max(parentRow, corridor + 0.5),\n lane: 0,\n };\n gutterReqs.push(spineReq);\n const aId = (c: number): number => linkOf.get(`${u.personAId}>${c}`)!.edgeId;\n // A child drop represents ONE declared parentage link (the given parent → c). Its\n // data-edge-id AND its <title> both come from THAT link, so the verbatim parentage\n // (incl. any quality word) matches what the drop's id declares (FIX C-1) — never a\n // hardcoded B-side title under an A-side id.\n const childDrop = (c: number, parentId: number): void => {\n const link = linkOf.get(`${parentId}>${c}`)!;\n const edgeId = link.edgeId;\n const arr = newArrival(c); // couples are processed first → claims the CENTER slot\n planned.push({\n kind: \"descent\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: null,\n toPersonId: c,\n titles: [linkTitle(link)],\n lineStyle: \"plain\",\n build: () => {\n const y = geo.corridorLaneY(sibReq);\n const x = geo.cx(colOrThrow(c)) + arrivalOffset(arr.slot, arrivalCount.get(c) ?? 1);\n return [\n { x, y },\n { x, y: geo.cy(rowOfPerson.get(c)!) - NODE_SIZE / 2 },\n ];\n },\n });\n };\n\n if (groupKids.length === 1) {\n // Single child: spine + bar-to-child is ONE elbow (parent A's link), the drop is\n // the other (parent B's link) — exactly two data-edge-id groups, one per declared\n // parentage (the verify-sweep 1:1 traceability contract), same pixels as a bar.\n const c = groupKids[0]!;\n planned.push({\n kind: \"descent\",\n relIds: [aId(c)],\n edgeId: aId(c),\n fromPersonId: null,\n toPersonId: null,\n titles: [linkTitle(linkOf.get(`${u.personAId}>${c}`)!)],\n lineStyle: \"plain\",\n build: () => {\n const sy = geo.corridorLaneY(sibReq);\n const sx = geo.gutterCenterX(interGutter);\n const cx = geo.cx(colOrThrow(c));\n return [\n { x: sx, y: spineStartY() },\n { x: sx, y: sy },\n { x: cx, y: sy },\n ];\n },\n });\n childDrop(c, u.personBId);\n } else {\n // ≥2 children: one shared sibling bar + one spine + a drop per child. Each child's\n // drop carries its B-side parentage id; the sibling bar carries A[0] (and traces\n // every remaining A-side link in relIds), the spine carries A[1] — distinct\n // data-edge-id per group, every declared link present in relIds.\n const aLinks = groupKids.map((c) => aId(c));\n // The verbatim A-side parentage title for child c (incl. any quality word).\n const aLinkTitle = (c: number): string => linkTitle(linkOf.get(`${u.personAId}>${c}`)!);\n planned.push({\n kind: \"sibling-bar\",\n relIds: [aLinks[0]!, ...aLinks.slice(2)],\n edgeId: aLinks[0]!,\n fromPersonId: null,\n toPersonId: null,\n // Carry the verbatim title of EVERY A-side link this bar represents, so no\n // declared quality word is dropped from the drawn element (FIX C-2 / SPEC inv #4).\n titles: [aLinkTitle(groupKids[0]!), ...groupKids.slice(2).map(aLinkTitle)],\n lineStyle: \"plain\",\n build: () => {\n const y = geo.corridorLaneY(sibReq);\n const xs = sibSpan();\n return [\n { x: Math.min(...xs), y },\n { x: Math.max(...xs), y },\n ];\n },\n });\n planned.push({\n kind: \"descent\",\n relIds: [aLinks[1]!],\n edgeId: aLinks[1]!,\n fromPersonId: null,\n toPersonId: null,\n titles: [aLinkTitle(groupKids[1]!)], // the A-side link this spine carries, verbatim\n lineStyle: \"plain\",\n build: () => {\n const sy = geo.corridorLaneY(sibReq);\n const x = geo.gutterCenterX(interGutter);\n return [\n { x, y: spineStartY() },\n { x, y: sy },\n ];\n },\n });\n for (const c of groupKids) childDrop(c, u.personBId);\n }\n }\n }\n\n // Lone / co-parental descents (dotted), by edge id (real before promoted, deterministic).\n for (const l of [...loneLinks].sort((a, b) => a.edgeId - b.edgeId)) {\n const edgeId = l.edgeId;\n const pRow = rowOfPerson.get(l.parentId)!;\n const cRow = rowOfPerson.get(l.childId)!;\n const build = pRow === cRow\n ? planUConnector(l.parentId, l.childId)\n : planConnector(l.parentId, l.childId, false);\n planned.push({\n kind: \"descent\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: l.parentId,\n toPersonId: l.childId,\n titles: [linkTitle(l)],\n lineStyle: \"plain\",\n dotted: true,\n build,\n });\n }\n\n // 2c. Bonds (free-text relationships), with the honesty-safe merge: same unordered\n // pair AND same computed lineStyle merge into one drawn element; different styles\n // draw separately (merging would have to pick one side's style).\n const bondGroups = new Map<string, { relIds: number[]; titles: string[]; style: EdgeLineStyle; aId: number; bId: number }>();\n for (const r of bondRels) {\n const style = qualityLineStyle(r.quality, opts.qualityLexicon);\n const lo = Math.min(r.fromPersonId, r.toPersonId);\n const hi = Math.max(r.fromPersonId, r.toPersonId);\n const key = `${lo}|${hi}|${style}`;\n const title = r.quality !== null ? `${r.type} · ${r.quality}` : r.type;\n const g = bondGroups.get(key);\n if (g === undefined) {\n bondGroups.set(key, { relIds: [r.id], titles: [title], style, aId: r.fromPersonId, bId: r.toPersonId });\n } else {\n g.relIds.push(r.id);\n g.titles.push(title);\n }\n }\n const bondList = [...bondGroups.values()].sort((a, b) => Math.max(...a.relIds) - Math.max(...b.relIds));\n for (const g of bondList) {\n const aRow = rowOfPerson.get(g.aId)!;\n const bRow = rowOfPerson.get(g.bId)!;\n const build = aRow === bRow\n ? planUConnector(g.aId, g.bId)\n : (() => {\n const [up, lo] = aRow < bRow ? [g.aId, g.bId] : [g.bId, g.aId];\n return planConnector(up, lo, false);\n })();\n planned.push({\n kind: \"bond\",\n relIds: g.relIds,\n edgeId: Math.max(...g.relIds),\n fromPersonId: g.aId,\n toPersonId: g.bId,\n titles: g.titles,\n lineStyle: g.style,\n build,\n });\n }\n\n // ── Pass 3: staged geometry so corridor lanes are allocated on EXACT pixel x ───────\n // Mutable geometry state, filled stage by stage; the build/xRange closures (created in\n // Pass 2) read it through `geo` at call time only — never before its stage fills it.\n const colCenterX: number[] = [];\n const colLeftX: number[] = [];\n const colRightX: number[] = [];\n const rowCenterY: number[] = [];\n const rowLabelTopY: number[] = [];\n const corridorTopY: number[] = [];\n const dims = { width: 0 };\n const gutterLaneCount = new Map<string, number>(); // `${gutter}:${side}` → count\n const corridorLaneCount: number[] = Array.from({ length: rowCount }, () => 0);\n const laneCount = (gutter: number, side: -1 | 0 | 1): number => gutterLaneCount.get(`${gutter}:${side}`) ?? 0;\n\n const geo = {\n cx: (c: number): number => colCenterX[c]!,\n cy: (r: number): number => rowCenterY[r]!,\n glyphRight: (id: number): number => colCenterX[colOrThrow(id)]! + NODE_SIZE / 2,\n glyphLeft: (id: number): number => colCenterX[colOrThrow(id)]! - NODE_SIZE / 2,\n gutterCenterX: (g: number): number => {\n const left = g < 0 ? PADDING : colRightX[g]!;\n const right = g >= colCount - 1 ? dims.width - PADDING : colLeftX[g + 1]!;\n return (left + right) / 2;\n },\n gutterLaneX: (req: GutterReq): number => {\n const left = req.gutter < 0 ? PADDING : colRightX[req.gutter]!;\n const right = req.gutter >= colCount - 1 ? dims.width - PADDING : colLeftX[req.gutter + 1]!;\n const lCount = laneCount(req.gutter, -1);\n if (req.side === -1) return left + (req.lane + 1) * LANE_H; // hug left, stack rightward\n if (req.side === 0) return left + (lCount + req.lane + 1) * LANE_H; // center group (spine)\n return right - (req.lane + 1) * LANE_H; // hug right, stack leftward\n },\n corridorLaneY: (req: CorridorReq): number =>\n corridorTopY[req.corridor]! + CORRIDOR_BASE / 2 + req.lane * LANE_H,\n /** Y of a dipped serial-union bar (level ≥ 1): below the row's glyph bottom edge. */\n unionDipY: (r: number, level: number): number =>\n rowCenterY[r]! + NODE_SIZE / 2 + level * UNION_STAGGER,\n };\n\n // Stage 1 — gutter lanes: per (gutter, side), by row-span interval. Left-hug and\n // right-hug stacks sit on opposite sides; the center group is the union spine.\n const gutterGroups = new Map<string, GutterReq[]>();\n for (const req of gutterReqs) {\n const k = `${req.gutter}:${req.side}`;\n (gutterGroups.get(k) ?? gutterGroups.set(k, []).get(k)!).push(req);\n }\n for (const [k, reqs] of gutterGroups) {\n gutterLaneCount.set(\n k,\n allocateLanes(reqs.map((req) => ({ lo: req.rowLo, hi: req.rowHi, set: (lane: number) => (req.lane = lane) }))),\n );\n }\n\n // Stage 2 — column geometry from gutter lane counts (+ the isolated extra gutter).\n const gutterWidth = (g: number): number => {\n const lanes = laneCount(g, -1) + laneCount(g, 0) + laneCount(g, 1);\n const extra = g === isolatedTailCol - 1 ? ISOLATED_GUTTER_EXTRA : 0;\n if (g === -1 || g === colCount - 1) return lanes > 0 ? COL_PAD + lanes * LANE_H + extra : extra;\n return COL_PAD + lanes * LANE_H + extra;\n };\n let cursorX = PADDING + gutterWidth(-1);\n for (let c = 0; c < colCount; c++) {\n colLeftX[c] = cursorX;\n colCenterX[c] = cursorX + colWidth[c]! / 2;\n cursorX += colWidth[c]!;\n colRightX[c] = cursorX;\n cursorX += gutterWidth(c);\n }\n dims.width = cursorX + PADDING;\n\n // Stage 3 — corridor lanes on EXACT pixel x-ranges (columns are now placed, so a\n // within-one-gutter span is measured precisely — no collapsing u-index proxy).\n const corridorGroups = new Map<number, CorridorReq[]>();\n for (const req of corridorReqs) (corridorGroups.get(req.corridor) ?? corridorGroups.set(req.corridor, []).get(req.corridor)!).push(req);\n for (const [k, reqs] of corridorGroups) {\n corridorLaneCount[k] = allocateLanes(\n reqs.map((req) => {\n const [lo, hi] = req.xRange();\n return { lo, hi, set: (lane: number) => (req.lane = lane) };\n }),\n );\n }\n\n // Stage 4 — row geometry from corridor lane counts.\n const corridorHeight = (k: number): number => {\n const lanes = corridorLaneCount[k] ?? 0;\n if (lanes > 0) return CORRIDOR_BASE + lanes * LANE_H;\n return k < rowCount - 1 ? CORRIDOR_BASE : 0; // interior rows always keep a gap\n };\n // Reserve a band BELOW each row's glyphs for its dipped serial-union bars (FIX B), so\n // labels sit below the deepest dip and never collide. 0 when the row has no remarriage.\n const rowDipReserve = (r: number): number =>\n rowDipLevels[r]! > 0 ? rowDipLevels[r]! * UNION_STAGGER + 6 : 0;\n let cursorY = PADDING;\n for (let r = 0; r < rowCount; r++) {\n rowCenterY[r] = cursorY + NODE_SIZE / 2;\n rowLabelTopY[r] = cursorY + NODE_SIZE + rowDipReserve(r) + LABEL_GAP_TOP;\n cursorY = rowLabelTopY[r]! + rowMaxLines[r]! * LABEL_LINE_H;\n corridorTopY[r] = cursorY;\n cursorY += corridorHeight(r);\n }\n const width = dims.width;\n const height = cursorY + PADDING;\n\n // ── Build nodes + finalize elements ──────────────────────────────────────────────\n const nodes: GenogramNode[] = [...people]\n .sort((a, b) => a.id - b.id)\n .map((p) => {\n const m = measured.get(p.id)!;\n const r = rowOfPerson.get(p.id)!;\n const c = colOrThrow(p.id);\n return {\n personId: p.id,\n label: p.label,\n shape: shapeForSex(p.sex),\n deceased: p.deceased,\n cx: colCenterX[c]!,\n cy: rowCenterY[r]!,\n size: NODE_SIZE,\n labelLines: m.lines,\n labelTop: rowLabelTopY[r]!,\n };\n });\n\n const elements: GenogramElement[] = planned.map((pl) => ({\n kind: pl.kind,\n relIds: pl.relIds,\n edgeId: pl.edgeId,\n fromPersonId: pl.fromPersonId,\n toPersonId: pl.toPersonId,\n points: pl.build(),\n titles: pl.titles,\n lineStyle: pl.lineStyle,\n ...(pl.unionStyle !== undefined ? { unionStyle: pl.unionStyle } : {}),\n ...(pl.dotted ? { dotted: true } : {}),\n }));\n\n // People with no drawn connection (only-suppressed/derived ties, or none at all).\n const isolatedPersonIds = people\n .filter((p) => isIsolated(p.id))\n .map((p) => p.id)\n .sort((a, b) => a - b);\n\n return { width, height, nodes, elements, isolatedPersonIds };\n}\n\n/** Linearize a connected couple-component so partners land adjacent. A simple path is\n * walked from its lowest-id endpoint (→ a clean chain); anything else is DFS-ordered\n * from the lowest id (hub gets two adjacent partners; the rest become union-elbows). */\nfunction linearizeBlock(comp: number[], adj: Map<number, number[]>): number[] {\n if (comp.length <= 1) return [...comp];\n const inComp = new Set(comp);\n const degree = (id: number): number => adj.get(id)!.filter((n) => inComp.has(n)).length;\n const endpoints = comp.filter((id) => degree(id) === 1).sort((a, b) => a - b);\n const edgeCount = comp.reduce((s, id) => s + degree(id), 0) / 2;\n const isPath = edgeCount === comp.length - 1 && endpoints.length === 2;\n const order: number[] = [];\n const seen = new Set<number>();\n if (isPath) {\n let cur: number | undefined = endpoints[0]!;\n while (cur !== undefined) {\n order.push(cur);\n seen.add(cur);\n cur = adj.get(cur)!.filter((n) => inComp.has(n)).sort((a, b) => a - b).find((n) => !seen.has(n));\n }\n return order;\n }\n const stack = [Math.min(...comp)];\n while (stack.length > 0) {\n const n = stack.pop()!;\n if (seen.has(n)) continue;\n seen.add(n);\n order.push(n);\n for (const m of adj.get(n)!.filter((x) => inComp.has(x)).sort((a, b) => b - a)) {\n if (!seen.has(m)) stack.push(m);\n }\n }\n return order;\n}\n","// Genogram SVG emitter — turns a computed GenogramLayout (./layout.ts, the pure\n// orthogonal declared-generation layout) into a SELF-CONTAINED SVG string.\n//\n// Two hard requirements:\n// - XML-ESCAPING of EVERY interpolated text. Labels are author-controlled and the\n// SVG string may be injected via innerHTML in a browser or embedded as vectors in\n// a PDF — an unescaped label is an XSS/`</svg>`-breakout vector on every surface.\n// - LITERAL presentation attributes (hex colors, inline stroke-dasharray, an explicit\n// font-family). A standalone SVG inside a PDF has no stylesheet, no `currentColor`.\n//\n// It is deliberately PURE (string in, string out) and DETERMINISTIC (same layout → same\n// SVG), and it draws EXACTLY what the layout computed: node centers and the routed\n// orthogonal polylines are consumed verbatim, never recomputed (the overlap harness\n// proves the layout; this emitter is pinned to it). Decoration hooks for callers: one\n// `<g data-individual-id=\"p<id>\">` per person with a direct-child `<title>` and bare\n// rect/circle/polygon glyph; `data-edge-id` on every routed group.\n//\n// HONESTY RULE: presentation only. There is ZERO text on map edges — the verbatim\n// \"type · quality\" / status label lives in each routed group's <title> (and the\n// caller's side lists). The one styling decision the CALLER may make is\n// `unionStyleByRelId`: a per-edge VISUAL override applied at emission — a\n// stroke-dasharray and/or McGoldrick status slashes — giving each declared union TYPE\n// the full notation (married solid, cohabiting/dating dashed, separated one slash,\n// divorced two) without the layout fabricating any quality text.\nimport { FONT_FAMILY, xmlEscape } from \"../core\";\nimport {\n EDGE_STROKE,\n LABEL_FONT,\n LABEL_LINE_H,\n estimateTextWidth,\n type GenogramElement,\n type GenogramLayout,\n type NodeShape,\n type Point,\n type UnionEdgeStyle,\n} from \"./layout\";\nimport { GENOGRAM_SVG_LABELS_EN, type GenogramSvgLabels } from \"./labels\";\n\n// Re-export so callers can reach the union-notation type through the emitter module.\nexport type { UnionEdgeStyle } from \"./layout\";\nexport { xmlEscape };\n\n// Literal ink colors (zinc ramp, matching the app shell on white — the PDF page).\nconst GLYPH_STROKE = \"#52525b\";\nconst NODE_LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\n\n// Structural (union / descent / sibling-bar) stroke — neutral, solid.\nconst STRUCT_WIDTH = 1.5;\nconst STRUCT_OPACITY = 0.75;\n// Dotted descent (lone-parent / co-parental): the visual kin of schematex's secondary.\nconst DOTTED_DASH: readonly [number, number] = [2, 3];\nconst DOTTED_OPACITY = 0.55;\n\n// Legend metrics (own, minimal — pt-BR only).\nconst LEGEND_ROW_H = 18;\nconst LEGEND_PAD = 16;\nconst LEGEND_SWATCH_W = 22;\nconst LEGEND_GAP = 14; // swatch → label gap (the \"Boxo\" fix: was 8, too tight)\nconst LEGEND_FONT = 11;\n\nexport interface GenogramSvgOptions {\n /**\n * Per-edge VISUAL union style (edgeId → {dash?, slashes?}), applied at emission.\n * Gives each declared union TYPE its own McGoldrick notation. Overrides any\n * `unionStyle` already on the element.\n */\n unionStyleByRelId?: ReadonlyMap<number, UnionEdgeStyle>;\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary (legend/accessibility) — English default; see locale packs. */\n labels?: GenogramSvgLabels;\n}\n\n/** Glyph markup for one shape centered at (cx, cy) with the given half-size. */\nfunction glyphSvg(shape: NodeShape, cx: number, cy: number, half: number): string {\n const stroke = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"`;\n if (shape === \"square\") {\n return `<rect x=\"${cx - half}\" y=\"${cy - half}\" width=\"${half * 2}\" height=\"${half * 2}\" rx=\"4\" ${stroke}/>`;\n }\n if (shape === \"circle\") {\n return `<circle cx=\"${cx}\" cy=\"${cy}\" r=\"${half}\" ${stroke}/>`;\n }\n return `<polygon points=\"${cx},${cy - half} ${cx + half},${cy} ${cx},${cy + half} ${cx - half},${cy}\" ${stroke}/>`;\n}\n\n/** \"M x y L x y …\" path data from an orthogonal polyline. */\nfunction pathData(points: Point[]): string {\n return points.map((p, i) => `${i === 0 ? \"M\" : \"L\"} ${p.x} ${p.y}`).join(\" \");\n}\n\n/** The longest horizontal segment of a polyline (for placing union-elbow slashes). */\nfunction longestHSegment(points: Point[]): [Point, Point] {\n let best: [Point, Point] = [points[0]!, points[points.length - 1]!];\n let bestLen = -1;\n for (let i = 0; i + 1 < points.length; i++) {\n const a = points[i]!;\n const b = points[i + 1]!;\n if (a.y === b.y) {\n const len = Math.abs(b.x - a.x);\n if (len > bestLen) {\n bestLen = len;\n best = [a, b];\n }\n }\n }\n return best;\n}\n\n/**\n * McGoldrick status slashes at the midpoint of a segment (1 = separação, 2 = divórcio),\n * drawn in screen-space \"/\" orientation and offset along the segment for the two divorce\n * strokes. Same ink/width as the bar so the mark reads as part of it.\n */\nfunction slashMarks(a: Point, b: Point, count: 1 | 2, width: number): string {\n const mx = (a.x + b.x) / 2;\n const my = (a.y + b.y) / 2;\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const len = Math.hypot(dx, dy) || 1;\n const ux = dx / len;\n const uy = dy / len;\n const HALF = 7; // slash half-length\n const STEP = 4; // along-segment offset between the two divorce slashes\n const offsets = count === 1 ? [0] : [-STEP, STEP];\n return offsets\n .map((o) => {\n const px = mx + ux * o;\n const py = my + uy * o;\n return `<line x1=\"${px - HALF}\" y1=\"${py + HALF}\" x2=\"${px + HALF}\" y2=\"${py - HALF}\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\"/>`;\n })\n .join(\"\");\n}\n\n/** Resolve a union element's effective McGoldrick style (override wins over element). */\nfunction resolveUnionStyle(\n el: GenogramElement,\n override: ReadonlyMap<number, UnionEdgeStyle>,\n): UnionEdgeStyle {\n return override.get(el.edgeId) ?? el.unionStyle ?? {};\n}\n\n/** Emits one routed element as a `<g data-edge-id>` group (≥3 points → path, else line),\n * with the verbatim titles in a <title> and ZERO text. */\nfunction elementSvg(el: GenogramElement, override: ReadonlyMap<number, UnionEdgeStyle>): string {\n const title = `<title>${xmlEscape(el.titles.join(\"\\n\"))}</title>`;\n const pts = el.points;\n const drawLine = (dash: readonly [number, number] | null, width: number, opacity: number): string => {\n const dashAttr = dash === null ? \"\" : ` stroke-dasharray=\"${dash[0]} ${dash[1]}\"`;\n if (pts.length === 2) {\n return `<line x1=\"${pts[0]!.x}\" y1=\"${pts[0]!.y}\" x2=\"${pts[1]!.x}\" y2=\"${pts[1]!.y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\" stroke-opacity=\"${opacity}\"${dashAttr}/>`;\n }\n return `<path d=\"${pathData(pts)}\" fill=\"none\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\" stroke-opacity=\"${opacity}\"${dashAttr}/>`;\n };\n\n if (el.kind === \"union-bar\" || el.kind === \"union-elbow\") {\n const style = resolveUnionStyle(el, override);\n const body: string[] = [drawLine(style.dash ?? null, STRUCT_WIDTH, STRUCT_OPACITY)];\n const slashes = style.slashes ?? 0;\n if (slashes === 1 || slashes === 2) {\n // A straight 2-point bar uses its own segment; a dipped serial-union bar (3-seg\n // elbow, FIX B) and any union-elbow ride the LONGEST horizontal segment so the\n // separado/divorciado slashes land on the across part, never on a vertical stub.\n const [a, b] = pts.length === 2 ? [pts[0]!, pts[1]!] : longestHSegment(pts);\n body.push(slashMarks(a, b, slashes, STRUCT_WIDTH));\n }\n return `<g data-edge-id=\"${el.edgeId}\">${title}${body.join(\"\")}</g>`;\n }\n\n if (el.kind === \"descent\" || el.kind === \"sibling-bar\") {\n const dash = el.dotted ? DOTTED_DASH : null;\n const opacity = el.dotted ? DOTTED_OPACITY : STRUCT_OPACITY;\n return `<g data-edge-id=\"${el.edgeId}\">${title}${drawLine(dash, STRUCT_WIDTH, opacity)}</g>`;\n }\n\n // bond\n const ink = EDGE_STROKE[el.lineStyle];\n return `<g data-edge-id=\"${el.edgeId}\">${title}${drawLine(ink.dash, ink.width, ink.opacity)}</g>`;\n}\n\n/**\n * Emits a self-contained SVG for a computed genogram layout. Pure + deterministic.\n * Coordinates come straight from the layout; all interpolated text is XML-escaped; all\n * presentation attributes are literal; there is NO text on map edges.\n */\nexport function genogramLayoutSvg(layout: GenogramLayout, opts: GenogramSvgOptions = {}): string {\n const override = opts.unionStyleByRelId ?? new Map<number, UnionEdgeStyle>();\n const labels = opts.labels ?? GENOGRAM_SVG_LABELS_EN;\n const parts: string[] = [];\n\n // ── Routed elements first so nodes sit on top (same stacking as the JSX render). ───\n for (const el of layout.elements) parts.push(elementSvg(el, override));\n\n // ── Nodes: glyph + deceased mark + wrapped label, hook-compatible with schematex. ─\n for (const node of layout.nodes) {\n const half = node.size / 2;\n const pieces: string[] = [\n `<title>${xmlEscape(node.label)}</title>`,\n glyphSvg(node.shape, node.cx, node.cy, half),\n ];\n if (node.deceased) {\n pieces.push(\n `<line x1=\"${node.cx - half}\" y1=\"${node.cy - half}\" x2=\"${node.cx + half}\" y2=\"${node.cy + half}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"/>`,\n );\n }\n const tspans = node.labelLines\n .map(\n (line, i) =>\n `<tspan x=\"${node.cx}\" y=\"${node.labelTop + 10 + i * LABEL_LINE_H}\">${xmlEscape(line)}</tspan>`,\n )\n .join(\"\");\n pieces.push(\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${LABEL_FONT}\" fill=\"${NODE_LABEL_FILL}\">${tspans}</text>`,\n );\n parts.push(`<g data-individual-id=\"p${node.personId}\">${pieces.join(\"\")}</g>`);\n }\n\n // ── Minimal pt-BR legend: only entries actually used. ──────────────────────────────\n let width = layout.width;\n let height = layout.height;\n if (opts.legend !== false && layout.nodes.length > 0) {\n const entries: { swatch: (x: number, y: number) => string; label: string }[] = [];\n\n const shapesUsed = new Set(layout.nodes.map((n) => n.shape));\n for (const shape of [\"square\", \"circle\", \"diamond\"] as const) {\n if (!shapesUsed.has(shape)) continue;\n entries.push({\n swatch: (x, y) => glyphSvg(shape, x + LEGEND_SWATCH_W / 2, y, 6),\n label: labels.shapes[shape],\n });\n }\n if (layout.nodes.some((n) => n.deceased)) {\n entries.push({\n swatch: (x, y) =>\n glyphSvg(\"square\", x + LEGEND_SWATCH_W / 2, y, 6) +\n `<line x1=\"${x + LEGEND_SWATCH_W / 2 - 6}\" y1=\"${y - 6}\" x2=\"${x + LEGEND_SWATCH_W / 2 + 6}\" y2=\"${y + 6}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"/>`,\n label: labels.deceased,\n });\n }\n\n // NOTE (deliberate, gate-tested): the fallback legend carries NO union-TYPE or\n // dotted-descent entry. Each declared union's type and each co-parenthood fact lives\n // VERBATIM in the element's <title> and in the dossier's structured side lists (the\n // psychologist's authoritative reading) — duplicating it as a legend key is the\n // \"known, documented gap\" pinned by test/verify-pdf.test.ts §(e). The dash/slash\n // notation itself stays on the drawn bars; only the legend stays minimal.\n\n // Bond styles actually used.\n const stylesUsed = new Set(layout.elements.filter((e) => e.kind === \"bond\").map((e) => e.lineStyle));\n for (const style of [\"close\", \"distant\", \"conflict\", \"cutoff\"] as const) {\n if (!stylesUsed.has(style)) continue;\n const ink = EDGE_STROKE[style];\n const dashAttr = ink.dash === null ? \"\" : ` stroke-dasharray=\"${ink.dash[0]} ${ink.dash[1]}\"`;\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${ink.width}\" stroke-opacity=\"${ink.opacity}\"${dashAttr}/>`,\n label: labels.bondStyles[style],\n });\n }\n\n // Unconnected glyphs (a person whose only declared tie is derived kinship like \"minha\n // tia\" — read from the tree, never a line — or who was mentioned with no tie at all)\n // sit grouped to the side with NO connector. This entry labels that group so a loose\n // glyph is never left unexplained; the verbatim tie still lives in the dossier list.\n if (layout.isolatedPersonIds.length > 0) {\n entries.push({\n swatch: (x, y) => glyphSvg(\"square\", x + LEGEND_SWATCH_W / 2, y, 6),\n label: labels.isolated,\n });\n }\n\n if (entries.length > 0) {\n const startY = layout.height;\n const rows = entries.map((entry, i) => {\n const rowCenterY = startY + i * LEGEND_ROW_H + LEGEND_ROW_H / 2;\n const textX = LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP;\n return (\n entry.swatch(LEGEND_PAD, rowCenterY) +\n `<text x=\"${textX}\" y=\"${rowCenterY + LEGEND_FONT * 0.32}\" font-family=\"${FONT_FAMILY}\" font-size=\"${LEGEND_FONT}\" fill=\"${GLYPH_STROKE}\">${xmlEscape(entry.label)}</text>`\n );\n });\n parts.push(`<g data-compasso-legend=\"true\">${rows.join(\"\")}</g>`);\n const widestLabel = entries.reduce((m, e) => Math.max(m, estimateTextWidth(e.label, LEGEND_FONT)), 0);\n width = Math.max(width, LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP + widestLabel + LEGEND_PAD);\n height = startY + entries.length * LEGEND_ROW_H + LEGEND_PAD / 2;\n }\n }\n\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\" width=\"${width}\" height=\"${height}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// One-call genogram render: input → self-contained SVG string. Thin, honest wiring:\n// dedupe unions per pair, compute the pure layout, give each declared union TYPE its\n// McGoldrick notation as a per-edge visual override, emit. Callers needing finer\n// control use computeGenogramLayout + genogramLayoutSvg directly.\n\nimport {\n UNION_REL_ID_BASE,\n computeGenogramLayout,\n type GenogramLayout,\n type GenogramLayoutOptions,\n type UnionEdgeStyle,\n} from \"./layout\";\nimport { genogramLayoutSvg } from \"./svg\";\nimport type { GenogramSvgLabels } from \"./labels\";\nimport type { GenogramInput, Union, UnionStatus } from \"./types\";\n\n/** Shared 6,4 dash for every cohabiting-flavoured union (cohabiting / dating /\n * type-not-stated), so non-marital couples read consistently. */\nconst COUPLE_DASH = [6, 4] as const;\n\n/**\n * McGoldrick notation per declared union TYPE — a per-edge VISUAL override applied at\n * emission, never a synthesized quality. `coparental` is ABSENT on purpose: it draws\n * NO couple element at all; the co-parenthood shows only on the descents converging\n * on the child(ren).\n */\nexport const UNION_NOTATION: Record<Exclude<UnionStatus, \"coparental\">, UnionEdgeStyle> = {\n married: {}, // solid bar\n cohabiting: { dash: COUPLE_DASH },\n dating: { dash: COUPLE_DASH },\n unknown: { dash: COUPLE_DASH },\n separated: { slashes: 1 }, // solid + one diagonal slash\n divorced: { slashes: 2 }, // solid + two parallel slashes\n};\n\n/**\n * Duplicate unions for the same unordered pair should not exist (callers are expected\n * to normalize), but if they do, the HIGHEST id wins — the most recent statement.\n * NEVER a status-rank heuristic: recency is a fact, ranking would be an interpretation.\n */\nexport function latestUnionPerPair(unions: Union[]): Union[] {\n const byPair = new Map<string, Union>();\n for (const u of [...unions].sort((a, b) => a.id - b.id)) {\n const key = `${Math.min(u.personAId, u.personBId)}|${Math.max(u.personAId, u.personBId)}`;\n byPair.set(key, u);\n }\n return [...byPair.values()].sort((a, b) => a.id - b.id);\n}\n\nexport interface GenogramRenderOptions extends GenogramLayoutOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary for the emitter (legend/accessibility) — English default. */\n svgLabels?: GenogramSvgLabels;\n}\n\nexport interface GenogramRenderResult {\n /** Self-contained SVG (numeric width/height + matching viewBox — PDF-embedder safe). */\n svg: string;\n /** The computed layout, for callers that decorate or hit-test the diagram. */\n layout: GenogramLayout;\n}\n\n/**\n * Renders a genogram input to a self-contained SVG string. Deterministic: same data →\n * same SVG. Empty `people` yields an empty-but-valid SVG; callers decide their own\n * empty state before calling.\n */\nexport function genogramSvg(\n input: GenogramInput,\n opts: GenogramRenderOptions = {},\n): GenogramRenderResult {\n const ids = new Set(input.people.map((p) => p.id));\n const dedupedUnions = latestUnionPerPair(input.unions).filter(\n (u) => ids.has(u.personAId) && ids.has(u.personBId),\n );\n\n const layout = computeGenogramLayout(\n input.people,\n dedupedUnions,\n input.parentLinks,\n input.relationships,\n opts,\n );\n\n const unionStyleByRelId = new Map<number, UnionEdgeStyle>();\n for (const u of dedupedUnions) {\n if (u.status === \"coparental\") continue; // no element — nothing to style\n unionStyleByRelId.set(UNION_REL_ID_BASE + u.id, UNION_NOTATION[u.status]);\n }\n\n const svg = genogramLayoutSvg(layout, {\n unionStyleByRelId,\n ...(opts.legend === false ? { legend: false } : {}),\n ...(opts.svgLabels !== undefined ? { labels: opts.svgLabels } : {}),\n });\n return { svg, layout };\n}\n"]}
1
+ {"version":3,"sources":["../src/genogram/types.ts","../src/genogram/labels.ts","../src/genogram/kinship.ts","../src/genogram/layout.ts","../src/genogram/svg.ts","../src/genogram/render.ts"],"names":[],"mappings":"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","file":"chunk-5PGOL2KR.js","sourcesContent":["// Genogram input model — declared facts only. compasso draws EXACTLY what the caller\n// declares and NEVER synthesizes structure: two declared parents without a declared\n// union never merge into a couple; a \"coparental\" union draws no couple element; a\n// free-text relationship never silently becomes kinship. Collection doctrine (who may\n// assert a fact, how it was captured) is the caller's concern — this is a renderer.\n\n/** Sex marker for a genogram node (standard notation: square/circle/diamond). */\nexport type PersonSex = \"male\" | \"female\" | \"unknown\";\n\n/** A genogram node. `generation` is relative (0 = index person; negative = older). */\nexport interface Person {\n id: number;\n label: string;\n sex: PersonSex;\n deceased: boolean;\n generation: number | null;\n}\n\n/**\n * CLOSED status vocabulary for a declared union. Notable semantics:\n * - \"coparental\": the two were NEVER a couple and have child(ren) together;\n * - \"unknown\": a union was declared, but its type was not;\n * - widowhood is NOT a status — death lives on Person.deceased and never\n * alters the declared status;\n * - no value for \"not stated\": the union simply is not passed in.\n */\nexport const UNION_STATUSES = [\n \"married\",\n \"cohabiting\",\n \"dating\",\n \"separated\",\n \"divorced\",\n \"coparental\",\n \"unknown\",\n] as const;\n\nexport type UnionStatus = (typeof UNION_STATUSES)[number];\n\n/**\n * A declared couple bond between two people. The pair is unordered and expected\n * normalized to personAId < personBId with ONE union per pair (duplicates are the\n * caller's to resolve). `quality` is the author's verbatim wording about the bond.\n */\nexport interface Union {\n id: number;\n /** Always the smaller person id (normalized pair). */\n personAId: number;\n personBId: number;\n status: UnionStatus;\n quality: string | null;\n}\n\n/**\n * A declared parentage link: parent → child, one row PER DECLARED genitor (two\n * genitors = two links, each individually stated — never promoted from a union).\n */\nexport interface ParentLink {\n id: number;\n parentId: number;\n childId: number;\n quality: string | null;\n}\n\n/**\n * A typed free-text edge between two people. `type` and `quality` are verbatim\n * labels. This carries NON-STRUCTURAL ties only (closeness, conflict…) — unions\n * and parentage are first-class above.\n */\nexport interface Relationship {\n id: number;\n fromPersonId: number;\n toPersonId: number;\n type: string;\n quality: string | null;\n}\n\n/** Input to the genogram render pipeline. */\nexport interface GenogramInput {\n people: Person[];\n unions: Union[];\n parentLinks: ParentLink[];\n relationships: Relationship[];\n}\n\n/** Node glyph shapes (standard notation: square = male, circle = female, diamond = unknown). */\nexport type NodeShape = \"square\" | \"circle\" | \"diamond\";\n","// Display vocabularies — every human-readable string the genogram emits, gathered in\n// overridable packs so the diagram localizes without touching the engine. English\n// defaults here; `compasso/locales/pt-br` ships a Brazilian Portuguese pack.\n\nimport type { EdgeLineStyle } from \"../core\";\nimport type { NodeShape, UnionStatus } from \"./types\";\n\n/** Labels woven into element <title>s by the LAYOUT (verbatim-preserving). */\nexport interface GenogramTitleLabels {\n unionStatus: Record<UnionStatus, string>;\n /** Title prefix for a parent→child descent (\"parent of\"). */\n parentage: string;\n}\n\nexport const GENOGRAM_TITLE_LABELS_EN: GenogramTitleLabels = {\n unionStatus: {\n married: \"married\",\n cohabiting: \"cohabiting\",\n dating: \"dating\",\n separated: \"separated\",\n divorced: \"divorced\",\n coparental: \"co-parents (never a couple)\",\n unknown: \"union (type not stated)\",\n },\n parentage: \"parent of\",\n};\n\n/** Labels drawn by the SVG EMITTER (legend entries, accessibility text). */\nexport interface GenogramSvgLabels {\n shapes: Record<NodeShape, string>;\n deceased: string;\n bondStyles: Record<Exclude<EdgeLineStyle, \"plain\">, string>;\n /** Legend label for the group of people with no drawn connection. */\n isolated: string;\n ariaLabel: string;\n}\n\nexport const GENOGRAM_SVG_LABELS_EN: GenogramSvgLabels = {\n shapes: {\n square: \"Man\",\n circle: \"Woman\",\n diamond: \"Sex not stated\",\n },\n deceased: \"Deceased\",\n bondStyles: {\n close: \"Close\",\n distant: \"Distant\",\n conflict: \"Conflictual\",\n cutoff: \"Cut off (no contact)\",\n },\n isolated: \"No recorded ancestry\",\n ariaLabel: \"Family map (genogram)\",\n};\n","// Relationship → MAP class (presentation only). A genogram draws only the structural\n// SKELETON: declared unions + parent links. A free-text `relationship` becomes a map\n// LINE only when it is NON-parentage. Kinship that is READ FROM THE TREE (grandparent/\n// sibling/uncle/cousin/nephew…) draws NOTHING — it is already implied by the descent/\n// union structure, so a dedicated line would only duplicate and clutter. A DIRECT\n// parentage word (mother/father/child) with no declared parent link is PROMOTED to a\n// descent (oriented by declared generation) so the person is not orphaned. NOTHING here\n// synthesizes undeclared structure: derived kinship draws nothing at all, and promotion\n// only ORIENTS an already-declared parent-child word. The verbatim \"type · quality\" of\n// EVERY relationship is the caller's to keep showing in its own lists.\n\nimport { normalizeText } from \"../core\";\n\nexport type RelationshipMapClass = \"derived\" | \"parentage\" | \"bond\";\n\n/**\n * A pluggable kinship vocabulary. Tokens are diacritic-free, lowercase, matched WHOLE\n * (so a token never matches inside another word) after splitting the type on\n * non-alphanumerics (\"half-brother\" → [\"half\",\"brother\"]). Checked DERIVED-first, so\n * \"brother on my father's side\" reads as a sibling, never as a parent. These lists are\n * closed and conservative — an unrecognized word stays a non-structural bond (the\n * honest default). Locale packs (e.g. `compasso/locales/pt-br`) ship alternates.\n */\nexport interface KinshipLexicon {\n /** Kinship read from the tree (sibling/grandparent/uncle/cousin…): never a line. */\n derived: ReadonlySet<string>;\n /** Direct parentage words (mother/father/son…): promotable to a descent. */\n parentage: ReadonlySet<string>;\n /** Parentage words whose FROM endpoint is the CHILD — used only to orient a\n * promotion when declared generations do not decide it. */\n childWords: ReadonlySet<string>;\n}\n\nexport const KINSHIP_EN: KinshipLexicon = {\n derived: new Set([\n \"brother\", \"brothers\", \"sister\", \"sisters\", \"sibling\", \"siblings\",\n \"grandmother\", \"grandfather\", \"grandma\", \"grandpa\", \"granny\", \"grandad\",\n \"granddad\", \"grandparent\", \"grandparents\",\n \"grandson\", \"granddaughter\", \"grandchild\", \"grandchildren\",\n \"uncle\", \"uncles\", \"aunt\", \"aunts\", \"auntie\",\n \"cousin\", \"cousins\",\n \"nephew\", \"nephews\", \"niece\", \"nieces\",\n ]),\n parentage: new Set([\n \"mother\", \"mothers\", \"mom\", \"mum\", \"father\", \"fathers\", \"dad\",\n \"parent\", \"parents\",\n \"son\", \"sons\", \"daughter\", \"daughters\",\n ]),\n childWords: new Set([\"son\", \"sons\", \"daughter\", \"daughters\"]),\n};\n\n/** Lowercase + accent-stripped tokens of a free-text relationship type. */\nexport function relationshipTypeTokens(type: string): string[] {\n return normalizeText(type).split(/[^a-z0-9]+/).filter((t) => t !== \"\");\n}\n\n/**\n * Classifies a free-text relationship `type` for the MAP. Pure + deterministic.\n * Derived kinship is checked first so a compound like \"brother on my father's side\"\n * is read as a sibling (derived), never promoted as a parent. The verbatim word is\n * unaffected — this decides only whether the tie becomes a line, and which kind.\n */\nexport function classifyRelationshipType(\n type: string,\n kinship: KinshipLexicon = KINSHIP_EN,\n): RelationshipMapClass {\n const toks = relationshipTypeTokens(type);\n if (toks.some((t) => kinship.derived.has(t))) return \"derived\";\n if (toks.some((t) => kinship.parentage.has(t))) return \"parentage\";\n return \"bond\";\n}\n","// PURE genogram layout — the single source of truth for positioning and glyph/edge\n// routing. The emitter (./svg.ts) draws EXACTLY what this computes, so any number of\n// surfaces (web, PDF, image pipelines) can never drift from each other.\n//\n// It is deliberately PURE — no DOM, no Node APIs, no clock, no randomness — so it loads\n// identically in browsers, server runtimes and test environments, and the same input\n// always yields the same layout. Anything with a side effect belongs elsewhere.\n//\n// HONESTY RULE: this module only POSITIONS and ROUTES the facts the caller declared. It\n// computes NO score, interpretation, prognosis or diagnosis, and it NEVER synthesizes\n// undeclared structure: a `coparental` union draws no couple element; two declared\n// parents WITHOUT a declared union never merge into a couple-bar descent (each gets its\n// own descent); free-text `relationships` stay non-structural bonds. Shapes follow the\n// standard genogram convention (square = male, circle = female, diamond = unknown; a\n// diagonal stroke marks deceased). The verbatim \"type · quality\" / status label is\n// ALWAYS kept on every routed element's <title>, so a style never replaces what was said.\n//\n// LAYOUT — orthogonal (McGoldrick) and overlap-proof BY CONSTRUCTION (not by luck). The\n// diagram is a grid: people sit in COLUMNS inside generation ROWS; the empty bands\n// BETWEEN columns (GUTTERS) and BETWEEN rows (CORRIDORS) are the only places routing\n// segments live, each in a numbered LANE allocated by interval-overlap so two segments\n// in the same lane can never overlap. Every consecutive pair of waypoints is axis-aligned\n// (horizontal or vertical) — there are NO diagonals and NO text on map edges (the\n// verbatim text rides the <title> and the caller's side lists). Glyphs and their labels\n// live entirely inside their columns; gutters and corridors are content-free by\n// construction, so a routed segment can never cross a glyph or a label box.\n//\n// PROVENANCE: descends from the production genogram renderer the author wrote for the\n// Ventory project (same copyright holder); developed independently of any third-party\n// diagram engine.\nimport {\n CHAR_W,\n estimateTextWidth,\n qualityLineStyle,\n wrapLabel,\n EDGE_STROKE,\n type EdgeLineStyle,\n type EdgeStroke,\n type Point,\n type QualityLexicon,\n} from \"../core\";\nimport { GENOGRAM_TITLE_LABELS_EN, type GenogramTitleLabels } from \"./labels\";\nimport {\n classifyRelationshipType,\n relationshipTypeTokens,\n KINSHIP_EN,\n type KinshipLexicon,\n type RelationshipMapClass,\n} from \"./kinship\";\nimport type {\n NodeShape,\n ParentLink,\n Person,\n PersonSex,\n Relationship,\n Union,\n} from \"./types\";\n\n// Re-exports so callers (and the emitter) can reach the full vocabulary through this\n// module, mirroring the original single-file layout.\nexport { CHAR_W, estimateTextWidth, qualityLineStyle, wrapLabel, EDGE_STROKE };\nexport type { EdgeLineStyle, EdgeStroke, Point, QualityLexicon };\nexport { classifyRelationshipType, relationshipTypeTokens, KINSHIP_EN };\nexport type { KinshipLexicon, RelationshipMapClass };\nexport type { NodeShape };\n\n// ── Geometry ──────────────────────────────────────────────────────────────────\nexport const NODE_SIZE = 56;\nconst PADDING = 32;\n/** Min horizontal gap between two adjacent columns' content boxes (a gutter's base). */\nconst COL_PAD = 30;\n/** Gap from a glyph's bottom to the top of its first label line. */\nconst LABEL_GAP_TOP = 8;\n/** Base height of a routing corridor (before lanes widen it). */\nconst CORRIDOR_BASE = 24;\n/** Vertical/horizontal spacing between two routing lanes in a corridor/gutter. */\nconst LANE_H = 8;\n/** Vertical drop between successive serial-union (remarriage) bars below the glyph row,\n * so 2+ unions on one person never read as one continuous rail (McGoldrick, FIX B). */\nconst UNION_STAGGER = 12;\n/** Horizontal offset (from glyph center, toward the partner) of a dipped union-bar's stub,\n * so a person in two serial unions gets two distinct stub columns (FIX B). < NODE_SIZE/2. */\nconst STUB_X_OFF = 14;\n/** Extra horizontal separation placed before an isolated-people group (SPEC). */\nconst ISOLATED_GUTTER_EXTRA = 2 * COL_PAD;\n\n// ── Type metrics (shared by layout AND both renderers, so geometry == render) ──\n/** Node label font size (px). The live SVG renders at this size; the PDF scales it. */\nexport const LABEL_FONT = 12;\n/** Line height for stacked node-label lines (px). */\nexport const LABEL_LINE_H = 14;\n/** Edge label font size (px) — kept for the shared metrics contract (invariant #9). */\nexport const EDGE_FONT = 11;\n// CHAR_W / estimateTextWidth live in ../core (re-exported above): the overlap-proof\n// guarantee depends on layout and emitters sharing these exact metrics.\n\n// ── Namespaced element ids (kept stable so data-edge-id stays traceable, §7.2) ──\n// relationships keep their own id; unions live at 1_000_000+id; parent links at\n// 2_000_000+id; PROMOTED descents (a direct-parentage free-text relationship drawn as a\n// descent — see classifyRelationshipType) at 3_000_000+rel id. Four disjoint blocks, so a\n// promoted descent never collides with a real parent link and every edge stays traceable\n// to its source. Deterministic, and visible in the overlap harness / data-edge-id.\nexport const UNION_REL_ID_BASE = 1_000_000;\nexport const PARENT_REL_ID_BASE = 2_000_000;\nexport const PROMOTED_REL_ID_BASE = 3_000_000;\n\n// ── Node glyphs ──────────────────────────────────────────────────────────────\nfunction shapeForSex(sex: PersonSex): NodeShape {\n if (sex === \"male\") return \"square\";\n if (sex === \"female\") return \"circle\";\n return \"diamond\";\n}\n\n// ── Edge line styles ─────────────────────────────────────────────────────────\n// EdgeLineStyle / EDGE_STROKE / qualityLineStyle live in ../core (re-exported above):\n// a neutral, presentation-only style for a NON-STRUCTURAL bond line, lexically hinted\n// from the author's own quality word — never a judgment, verbatim word always kept.\n\n/**\n * Per-edge VISUAL union style applied at emission (§7.2 / FIX 3) — the McGoldrick\n * notation for a declared union TYPE, WITHOUT touching the layout or the patient's\n * words. `coparental` never gets one (it draws no edge). Defined here (not in\n * fallback-svg) so a routed element can carry it and the emitter stays free of layout\n * cycles; fallback-svg re-exports it for the existing call sites.\n */\nexport interface UnionEdgeStyle {\n /** Inline stroke-dasharray [dash, gap] on the bar; absent = solid (e.g. casado). */\n dash?: readonly [number, number];\n /** Diagonal status slashes at the midpoint: 1 = separação, 2 = divórcio. */\n slashes?: 0 | 1 | 2;\n}\n\n// ── Relationship → MAP class ───────────────────────────────────────────────────\n// classifyRelationshipType / relationshipTypeTokens / KinshipLexicon live in ./kinship\n// (re-exported above): derived kinship draws NOTHING, direct parentage may be PROMOTED\n// to a descent, everything else stays a non-structural bond. wrapLabel lives in ../core.\n\n/** Wrap policy: split a label into roughly-balanced lines bounded to a sane width. */\nfunction wrapNodeLabel(displayLabel: string): string[] {\n const perLine = Math.min(26, Math.max(14, Math.ceil(displayLabel.length / 2) + 2));\n return wrapLabel(displayLabel, perLine);\n}\n\n/** Caps a verbatim label for a COMPACT render (preview); full text kept in `label`. */\nfunction clampLabel(label: string, maxChars: number | undefined): string {\n if (maxChars === undefined || label.length <= maxChars) return label;\n return label.slice(0, Math.max(1, maxChars - 1)) + \"…\";\n}\n\n// ── Positioned layout ────────────────────────────────────────────────────────\n\nexport interface GenogramNode {\n personId: number;\n /** Full, verbatim label (used for tooltips/aria — never truncated). */\n label: string;\n shape: NodeShape;\n deceased: boolean;\n /** Center of the node. */\n cx: number;\n cy: number;\n /** Side length (square) / diameter (circle) / width (diamond). */\n size: number;\n /** Pre-wrapped display lines (already capped for the requested density). */\n labelLines: string[];\n /** Y of the TOP of the first label line's box (each next line is +LABEL_LINE_H). */\n labelTop: number;\n}\n\n/** A routed map element — the orthogonal replacement for the old straight `GenogramEdge`. */\nexport type GenogramElementKind =\n | \"union-bar\" // adjacent same-row partners: straight H bar, glyph-edge to glyph-edge\n | \"union-elbow\" // non-adjacent / cross-row partners: orthogonal route\n | \"descent\" // parent(s) → child plumbing segment(s)\n | \"sibling-bar\" // one shared H bar per union child-group (≥1 children)\n | \"bond\"; // non-structural relationship, orthogonal route\n\nexport interface GenogramElement {\n kind: GenogramElementKind;\n /** Source row ids for traceability; merged bonds carry every merged rel id. */\n relIds: number[];\n /** data-edge-id value: highest relId (matches latestUnionPerPair's highest-wins). */\n edgeId: number;\n fromPersonId: number | null;\n toPersonId: number | null;\n /** Polyline; EVERY consecutive pair is axis-aligned (H or V). */\n points: Point[];\n /** Verbatim titles (one per source row), joined for the <title>. */\n titles: string[];\n lineStyle: EdgeLineStyle; // bonds only; structural elements are \"plain\"\n unionStyle?: UnionEdgeStyle; // union-bar / union-elbow: dash + slashes\n dotted?: boolean; // lone-parent / coparental descents\n}\n\nexport interface GenogramLayout {\n width: number;\n height: number;\n nodes: GenogramNode[];\n elements: GenogramElement[];\n /** People with NO drawn structural/bond connection — grouped to the side and labeled\n * \"Sem ascendência registrada\" so a loose glyph is never left unexplained. */\n isolatedPersonIds: number[];\n}\n\n// ── Internal working types ─────────────────────────────────────────────────────\n\n/**\n * A parent→child descent to draw — either a DECLARED parent_link (real) or a PROMOTED\n * direct-parentage relationship (no declared link existed for the pair). `edgeId` is\n * pre-namespaced (real: PARENT_REL_ID_BASE+link id; promoted: PROMOTED_REL_ID_BASE+rel id),\n * so both flow through the same descent machinery and stay traceable in data-edge-id.\n */\ninterface LayoutLink {\n parentId: number;\n childId: number;\n quality: string | null;\n edgeId: number;\n}\n\ninterface Measured {\n person: Person;\n lines: string[];\n /** max(NODE_SIZE, widest wrapped line) — the horizontal footprint. */\n contentW: number;\n}\n\n/** A vertical segment living in a gutter, awaiting a lane. */\ninterface GutterReq {\n gutter: number; // gutter index g in [-1, colCount-1]\n side: -1 | 0 | 1; // -1 hug left column, +1 hug right column, 0 center (union spine)\n rowLo: number; // continuous row coordinate (row r → r; corridor k → k+0.5)\n rowHi: number;\n lane: number; // filled by the allocator\n}\n\n/** A horizontal segment living in a corridor, awaiting a lane. Its pixel x-interval is\n * resolved AFTER the column/gutter geometry is fixed, so the lane allocator can use the\n * EXACT extent (a u-index proxy collapses for within-one-gutter spans). */\ninterface CorridorReq {\n corridor: number; // corridor index k in [0, rowCount-1] (k = below row k)\n xRange: () => [number, number]; // pixel [xMin, xMax], resolved post-column-geometry\n lane: number;\n}\n\n/** A sideways glyph departure stub, awaiting a height slot. */\ninterface StubReq {\n personId: number;\n side: -1 | 1;\n slot: number; // height slot index, filled below\n}\n\n/** An arrival into a glyph TOP, awaiting an x-offset slot. */\ninterface ArrivalReq {\n personId: number;\n slot: number;\n}\n\n/** A planned element: its kind/metadata + a builder that resolves to pixel points. */\ninterface PlannedElement {\n kind: GenogramElementKind;\n relIds: number[];\n edgeId: number;\n fromPersonId: number | null;\n toPersonId: number | null;\n titles: string[];\n lineStyle: EdgeLineStyle;\n unionStyle?: UnionEdgeStyle;\n dotted?: boolean;\n build: () => Point[];\n}\n\n// Height slots for stacked departures from one glyph side (avoid y=cy so a union bar at\n// cy is never crossed). Within ±(NODE_SIZE/2 − 4) so the stub stays on the glyph edge.\nconst STUB_OFFSETS = [9, -9, 18, -18, 26, -26] as const;\n/** Max |x-offset| for an arrival into a glyph TOP (kept inside the top edge half-width). */\nconst ARRIVAL_HALF = NODE_SIZE / 2 - 8;\n\nfunction stubOffset(slot: number): number {\n return STUB_OFFSETS[Math.min(slot, STUB_OFFSETS.length - 1)]!;\n}\n/** Spread arrivals across a glyph TOP so each lands on a distinct x — slot 0 stays\n * CENTERED (the primary descent), later arrivals alternate to either side. For any\n * fan-in count, no two verticals share a column (overlap-proof). */\nfunction arrivalOffset(slot: number, total: number): number {\n if (slot === 0 || total <= 1) return 0;\n const step = Math.min(12, ARRIVAL_HALF / Math.max(1, Math.ceil((total - 1) / 2)));\n const sign = slot % 2 === 1 ? -1 : 1;\n return sign * Math.ceil(slot / 2) * step;\n}\n\n/** Allocate lanes for a set of intervals: each takes the lowest lane free over its span\n * (touching at an endpoint does NOT count as overlap, so collinear segments may abut). */\nfunction allocateLanes(items: { lo: number; hi: number; set: (lane: number) => void }[]): number {\n const lanes: { lo: number; hi: number }[][] = [];\n for (const it of items) {\n let chosen = -1;\n for (let l = 0; l < lanes.length; l++) {\n if (lanes[l]!.every((o) => it.hi <= o.lo || it.lo >= o.hi)) {\n chosen = l;\n break;\n }\n }\n if (chosen === -1) {\n chosen = lanes.length;\n lanes.push([]);\n }\n lanes[chosen]!.push({ lo: it.lo, hi: it.hi });\n it.set(chosen);\n }\n return lanes.length;\n}\n\n/**\n * Deterministic, overlap-proof ORTHOGONAL layout (pure function of the inputs — same\n * data always yields the same geometry). People are grouped by `generation` (null trails\n * as a bottom row), rows ordered oldest-on-top. Declared structure is drawn as McGoldrick\n * elements: same-row adjacent unions as straight bars, couples-with-children as a shared\n * sibling bar, lone/co-parental genitors as dotted descents, and free-text relationships\n * as orthogonally-routed bonds — NEVER promoting a bond into structure.\n *\n * @param unions caller-deduped (one per pair) declared couple bonds.\n * @param parentLinks declared parent→child links (one row per declared genitor).\n * @param relationships non-structural ties (drawn as bonds).\n * @param opts.maxLabelChars cap each node's DISPLAY label to this many chars (compact\n * preview); the full verbatim text is still exposed on `node.label`.\n * @param opts.kinship / opts.qualityLexicon / opts.titleLabels — locale packs (English\n * defaults; see `compasso/locales/pt-br`).\n */\nexport interface GenogramLayoutOptions {\n maxLabelChars?: number;\n kinship?: KinshipLexicon;\n qualityLexicon?: QualityLexicon;\n titleLabels?: GenogramTitleLabels;\n}\n\nexport function computeGenogramLayout(\n people: Person[],\n unions: Union[],\n parentLinks: ParentLink[],\n relationships: Relationship[],\n opts: GenogramLayoutOptions = {},\n): GenogramLayout {\n const kinship = opts.kinship ?? KINSHIP_EN;\n const titleLabels = opts.titleLabels ?? GENOGRAM_TITLE_LABELS_EN;\n if (people.length === 0) {\n return { width: PADDING * 2, height: PADDING * 2, nodes: [], elements: [], isolatedPersonIds: [] };\n }\n\n const ids = new Set(people.map((p) => p.id));\n const pairKey = (a: number, b: number): string => `${Math.min(a, b)}|${Math.max(a, b)}`;\n const genById = new Map<number, number | null>(people.map((p) => [p.id, p.generation]));\n\n // Sanitize structural inputs (drop self/missing endpoints — keep declared facts only).\n const validUnions = unions\n .filter((u) => ids.has(u.personAId) && ids.has(u.personBId) && u.personAId !== u.personBId)\n .sort((a, b) => a.id - b.id);\n const coupleUnions = validUnions.filter((u) => u.status !== \"coparental\");\n const validLinks = parentLinks\n .filter((l) => ids.has(l.parentId) && ids.has(l.childId) && l.parentId !== l.childId)\n .sort((a, b) => a.id - b.id);\n const validRels = relationships\n .filter((r) => ids.has(r.fromPersonId) && ids.has(r.toPersonId) && r.fromPersonId !== r.toPersonId)\n .sort((a, b) => a.id - b.id);\n\n // ── SKELETON-ONLY (presentation): classify each free-text relationship for the MAP ─────\n // - \"derived\" (avó/irmão/tio/…): READ from the tree → draws NOTHING here.\n // - \"parentage\" (mãe/pai/filho/…): a declared parent-child word → PROMOTED to a descent\n // when no parent_link already declares the pair (else a duplicate, dropped\n // from the map); never a bond.\n // - \"bond\" (everything else): a non-structural tie → drawn as a bond, as before.\n // The verbatim \"type · quality\" of EVERY relationship still rides the dossier side lists.\n const relClass = new Map<number, RelationshipMapClass>(\n validRels.map((r) => [r.id, classifyRelationshipType(r.type, kinship)]),\n );\n const bondRels = validRels.filter((r) => relClass.get(r.id) === \"bond\");\n const parentageRels = validRels.filter((r) => relClass.get(r.id) === \"parentage\");\n\n // Effective descents = declared parent_links (real) + promoted parentage relationships.\n const realLinks: LayoutLink[] = validLinks.map((l) => ({\n parentId: l.parentId,\n childId: l.childId,\n quality: l.quality,\n edgeId: PARENT_REL_ID_BASE + l.id,\n }));\n const declaredPairs = new Set(validLinks.map((l) => pairKey(l.parentId, l.childId)));\n const promotedByPair = new Map<string, LayoutLink>();\n for (const r of parentageRels) {\n const key = pairKey(r.fromPersonId, r.toPersonId);\n if (declaredPairs.has(key)) continue; // already a declared parent_link → no double-draw\n if (promotedByPair.has(key)) continue; // same pair stated twice → one descent (id-order)\n // Orient parent→child by DECLARED generation (older = parent). When generations do not\n // decide (equal or null), fall back to the parentage WORD + the declared from/to:\n // mãe/pai → from is the parent; filho/filha → from is the child. Either way nothing is\n // invented — both endpoints and the parent-child nature were declared; only the arrow.\n const ga = genById.get(r.fromPersonId) ?? null;\n const gb = genById.get(r.toPersonId) ?? null;\n let parentId: number;\n let childId: number;\n if (ga !== null && gb !== null && ga !== gb) {\n [parentId, childId] = ga < gb ? [r.fromPersonId, r.toPersonId] : [r.toPersonId, r.fromPersonId];\n } else {\n const fromIsChild = relationshipTypeTokens(r.type).some((t) => kinship.childWords.has(t));\n [parentId, childId] = fromIsChild ? [r.toPersonId, r.fromPersonId] : [r.fromPersonId, r.toPersonId];\n }\n if (parentId === childId) continue;\n promotedByPair.set(key, { parentId, childId, quality: r.quality, edgeId: PROMOTED_REL_ID_BASE + r.id });\n }\n const allLinks: LayoutLink[] = [...realLinks, ...promotedByPair.values()].sort((a, b) => a.edgeId - b.edgeId);\n\n // Declared (non-coparental) union lookup by unordered pair → union.\n const coupleByPair = new Map<string, Union>();\n for (const u of coupleUnions) coupleByPair.set(pairKey(u.personAId, u.personBId), u);\n\n // Parents per child and links per (parent,child) — real links + promoted descents.\n const parentsOf = new Map<number, number[]>();\n const linkOf = new Map<string, LayoutLink>();\n for (const l of allLinks) {\n const arr = parentsOf.get(l.childId) ?? [];\n if (!arr.includes(l.parentId)) arr.push(l.parentId);\n parentsOf.set(l.childId, arr);\n linkOf.set(`${l.parentId}>${l.childId}`, l);\n }\n\n // A person is ISOLATED when they have NO drawn connection: no union, no descent (real or\n // promoted), and no bond. A relationship suppressed from the map (derived kinship like\n // \"minha tia\", read from the tree) does NOT count as a tie — so such a person is grouped\n // to the side and labeled \"Sem ascendência registrada\", never left as a loose glyph.\n const hasTie = new Set<number>();\n for (const u of validUnions) {\n hasTie.add(u.personAId);\n hasTie.add(u.personBId);\n }\n for (const l of allLinks) {\n hasTie.add(l.parentId);\n hasTie.add(l.childId);\n }\n for (const r of bondRels) {\n hasTie.add(r.fromPersonId);\n hasTie.add(r.toPersonId);\n }\n const isIsolated = (id: number): boolean => !hasTie.has(id);\n\n // ── Pass 1a: rows by declared generation (null last), oldest on top ──────────────\n const byGen = new Map<number | null, Person[]>();\n for (const p of people) {\n const bucket = byGen.get(p.generation);\n if (bucket === undefined) byGen.set(p.generation, [p]);\n else bucket.push(p);\n }\n const genKeys = [...byGen.keys()].sort((a, b) => {\n if (a === null) return 1;\n if (b === null) return -1;\n return a - b;\n });\n const rowCount = genKeys.length;\n const rowOfPerson = new Map<number, number>();\n genKeys.forEach((g, r) => byGen.get(g)!.forEach((p) => rowOfPerson.set(p.id, r)));\n\n // ── Pass 1b: couple BLOCKS per row (connected components of same-row couple unions),\n // linearized so partners land adjacent; then barycenter ordering; isolated rightmost.\n type Block = number[]; // person ids, left-to-right\n const rowBlocks: Block[][] = genKeys.map((g, r) => {\n const members = byGen.get(g)!.map((p) => p.id);\n // adjacency from same-row couple unions\n const adj = new Map<number, number[]>();\n for (const id of members) adj.set(id, []);\n for (const u of coupleUnions) {\n if (rowOfPerson.get(u.personAId) === r && rowOfPerson.get(u.personBId) === r) {\n adj.get(u.personAId)!.push(u.personBId);\n adj.get(u.personBId)!.push(u.personAId);\n }\n }\n for (const id of members) adj.get(id)!.sort((a, b) => a - b);\n // connected components\n const seen = new Set<number>();\n const blocks: Block[] = [];\n for (const start of [...members].sort((a, b) => a - b)) {\n if (seen.has(start)) continue;\n const comp: number[] = [];\n const stack = [start];\n seen.add(start);\n while (stack.length > 0) {\n const n = stack.pop()!;\n comp.push(n);\n for (const m of adj.get(n)!) if (!seen.has(m)) { seen.add(m); stack.push(m); }\n }\n blocks.push(linearizeBlock(comp, adj));\n }\n return blocks;\n });\n\n // Barycenter sweeps (downward then upward), gated on rowCount ≥ 2. Aesthetic only —\n // it reorders blocks to align children under parents; it never moves anyone off a row.\n const flattened = (): Map<number, number> => {\n const pos = new Map<number, number>();\n for (const blocks of rowBlocks) {\n let c = 0;\n for (const b of blocks) for (const id of b) pos.set(id, c++);\n }\n return pos;\n };\n const structuralNeighbors = (id: number): number[] => {\n const out: { id: number; w: number }[] = [];\n // Barycenter ordering uses NON-coparental unions only (SPEC Pass 1 / FIX E): a\n // coparental pair draws no couple bar, so it must exert no ordering attraction either.\n for (const u of coupleUnions) {\n if (u.personAId === id) out.push({ id: u.personBId, w: 1 });\n else if (u.personBId === id) out.push({ id: u.personAId, w: 1 });\n }\n for (const l of allLinks) {\n if (l.childId === id) out.push({ id: l.parentId, w: 1 });\n else if (l.parentId === id) out.push({ id: l.childId, w: 1 });\n }\n for (const rl of bondRels) {\n if (rl.fromPersonId === id) out.push({ id: rl.toPersonId, w: 0.5 });\n else if (rl.toPersonId === id) out.push({ id: rl.fromPersonId, w: 0.5 });\n }\n return out.map((o) => o.id);\n };\n const neighborWeight = (id: number, other: number): number => {\n let w = 0;\n // NON-coparental unions only — same FIX E rationale as structuralNeighbors.\n for (const u of coupleUnions) if ((u.personAId === id && u.personBId === other) || (u.personBId === id && u.personAId === other)) w = Math.max(w, 1);\n for (const l of allLinks) if ((l.childId === id && l.parentId === other) || (l.parentId === id && l.childId === other)) w = Math.max(w, 1);\n for (const rl of bondRels) if ((rl.fromPersonId === id && rl.toPersonId === other) || (rl.toPersonId === id && rl.fromPersonId === other)) w = Math.max(w, 0.5);\n return w;\n };\n const sweep = (r: number, ref: number): void => {\n const pos = flattened();\n const blocks = rowBlocks[r]!;\n const bcOf = (b: Block): number => {\n let sum = 0;\n let wsum = 0;\n for (const id of b) {\n for (const nb of structuralNeighbors(id)) {\n if (rowOfPerson.get(nb) !== ref) continue;\n const w = neighborWeight(id, nb);\n sum += (pos.get(nb) ?? 0) * w;\n wsum += w;\n }\n }\n return wsum === 0 ? Number.POSITIVE_INFINITY : sum / wsum;\n };\n const keyed = blocks.map((b) => ({ b, bc: bcOf(b), minId: Math.min(...b) }));\n keyed.sort((x, y) => (x.bc !== y.bc ? x.bc - y.bc : x.minId - y.minId));\n rowBlocks[r] = keyed.map((k) => k.b);\n };\n if (rowCount >= 2) {\n for (let r = 1; r < rowCount; r++) sweep(r, r - 1);\n for (let r = rowCount - 2; r >= 0; r--) sweep(r, r + 1);\n }\n\n // Isolated people drift fully right: stable-partition each row so isolated singleton\n // blocks trail the connected ones (ordered by id). No connector is ever drawn for them.\n for (let r = 0; r < rowCount; r++) {\n const blocks = rowBlocks[r]!;\n const connected = blocks.filter((b) => !(b.length === 1 && isIsolated(b[0]!)));\n const isolated = blocks.filter((b) => b.length === 1 && isIsolated(b[0]!)).sort((a, b) => a[0]! - b[0]!);\n rowBlocks[r] = [...connected, ...isolated];\n }\n\n // ── Pass 1c: assign (row, col) to every person via the global column grid ─────────\n const colOf = new Map<number, number>();\n let colCount = 0;\n for (let r = 0; r < rowCount; r++) {\n let c = 0;\n for (const b of rowBlocks[r]!) for (const id of b) colOf.set(id, c++);\n colCount = Math.max(colCount, c);\n }\n const colOrThrow = (id: number): number => colOf.get(id)!;\n\n // Column where the isolated-only tail begins (extra gutter sits just before it).\n let isolatedTailCol = colCount; // none by default\n {\n const peopleAtCol: number[][] = Array.from({ length: colCount }, () => []);\n for (const p of people) peopleAtCol[colOrThrow(p.id)]!.push(p.id);\n for (let c = colCount - 1; c >= 1; c--) {\n const all = peopleAtCol[c]!;\n if (all.length > 0 && all.every((id) => isIsolated(id))) isolatedTailCol = c;\n else break;\n }\n }\n\n // ── Pass 2 prep: measure labels; column widths; per-row label heights ─────────────\n const measured = new Map<number, Measured>();\n for (const p of people) {\n const lines = wrapNodeLabel(clampLabel(p.label, opts.maxLabelChars));\n const contentW = Math.max(NODE_SIZE, lines.reduce((m, l) => Math.max(m, estimateTextWidth(l, LABEL_FONT)), 0));\n measured.set(p.id, { person: p, lines, contentW });\n }\n const colWidth: number[] = Array.from({ length: colCount }, () => NODE_SIZE);\n for (const p of people) {\n const c = colOrThrow(p.id);\n colWidth[c] = Math.max(colWidth[c]!, measured.get(p.id)!.contentW);\n }\n const rowMaxLines: number[] = Array.from({ length: rowCount }, () => 1);\n for (const p of people) {\n const r = rowOfPerson.get(p.id)!;\n rowMaxLines[r] = Math.max(rowMaxLines[r]!, measured.get(p.id)!.lines.length);\n }\n\n // ── Pass 2: route every element symbolically and register lane/slot requests ──────\n const planned: PlannedElement[] = [];\n const gutterReqs: GutterReq[] = [];\n const corridorReqs: CorridorReq[] = [];\n const stubCount = new Map<string, number>(); // `${id}:${side}` → slots used\n const arrivalCount = new Map<number, number>(); // id → arrival slots used\n\n const newStub = (personId: number, side: -1 | 1): StubReq => {\n const key = `${personId}:${side}`;\n const slot = stubCount.get(key) ?? 0;\n stubCount.set(key, slot + 1);\n return { personId, side, slot };\n };\n const newArrival = (personId: number): ArrivalReq => {\n const slot = arrivalCount.get(personId) ?? 0;\n arrivalCount.set(personId, slot + 1);\n return { personId, slot };\n };\n const departSide = (srcId: number, dstId: number): -1 | 1 => {\n const sc = colOrThrow(srcId);\n const dc = colOrThrow(dstId);\n if (dc > sc) return 1;\n if (dc < sc) return -1;\n return sc < colCount - 1 ? 1 : -1;\n };\n // The gutter a connector departs INTO, and which side of it the departing column is on.\n const gutterFor = (srcCol: number, side: -1 | 1): { gutter: number; gSide: -1 | 1 } =>\n side === 1\n ? { gutter: srcCol, gSide: -1 } // depart right → gutter to the right; src is its LEFT column\n : { gutter: srcCol - 1, gSide: 1 }; // depart left → gutter to the left; src is its RIGHT column\n\n // A cross-row connector: sideways stub from the UPPER node, gutter drop, corridor cross,\n // arrival into the LOWER glyph TOP. Returns a builder closure over the resolved geo.\n // Robust to either argument order: it routes from whichever node is in the SHALLOWER\n // (upper) declared generation, so a parent declared in a YOUNGER generation than the\n // child (srcRow > dstRow) still gets a valid, non-negative, in-range corridor and an\n // ordered gutter span instead of a negative index (FIX D-1). Normal upper→lower calls\n // are unchanged: the upper node is the source and corridor = lowerRow − 1 as before.\n const planConnector = (\n srcId: number,\n dstId: number,\n arrivalAtCenter: boolean,\n ): (() => Point[]) => {\n const srcRow = rowOfPerson.get(srcId)!;\n const dstRow = rowOfPerson.get(dstId)!;\n // Departure is always from the upper node; arrival into the lower node's TOP edge.\n const [upperId, lowerId] = srcRow <= dstRow ? [srcId, dstId] : [dstId, srcId];\n const upperRow = rowOfPerson.get(upperId)!;\n const lowerRow = rowOfPerson.get(lowerId)!;\n const side = departSide(upperId, lowerId);\n const { gutter, gSide } = gutterFor(colOrThrow(upperId), side);\n const stub = newStub(upperId, side);\n // Corridor just above the lower row, clamped in-range (degenerate same-row → band 0).\n const corridor = Math.max(0, Math.min(rowCount - 1, lowerRow - 1));\n const gReq: GutterReq = {\n gutter,\n side: gSide,\n rowLo: Math.min(upperRow, corridor + 0.5),\n rowHi: Math.max(upperRow, corridor + 0.5),\n lane: 0,\n };\n gutterReqs.push(gReq);\n const arrival = arrivalAtCenter ? null : newArrival(lowerId);\n const arrivalX = (): number =>\n geo.cx(colOrThrow(lowerId)) + (arrival ? arrivalOffset(arrival.slot, arrivalCount.get(lowerId) ?? 1) : 0);\n const cReq: CorridorReq = {\n corridor,\n xRange: () => {\n const gx = geo.gutterLaneX(gReq);\n const ax = arrivalX();\n return [Math.min(gx, ax), Math.max(gx, ax)];\n },\n lane: 0,\n };\n corridorReqs.push(cReq);\n return () => {\n const sy = geo.cy(upperRow) + stubOffset(stub.slot);\n const sEdge = side === 1 ? geo.glyphRight(upperId) : geo.glyphLeft(upperId);\n const gx = geo.gutterLaneX(gReq);\n const cyCorr = geo.corridorLaneY(cReq);\n const ax = arrivalX();\n const topY = geo.cy(lowerRow) - NODE_SIZE / 2;\n return [\n { x: sEdge, y: sy },\n { x: gx, y: sy },\n { x: gx, y: cyCorr },\n { x: ax, y: cyCorr },\n { x: ax, y: topY },\n ];\n };\n };\n\n // A same-row connector (U under the row): both endpoints leave sideways toward each\n // other, drop into the corridor below the row, and cross there.\n const planUConnector = (aId: number, bId: number): (() => Point[]) => {\n const row = rowOfPerson.get(aId)!;\n const [leftId, rightId] = colOrThrow(aId) <= colOrThrow(bId) ? [aId, bId] : [bId, aId];\n const stubL = newStub(leftId, 1);\n const stubR = newStub(rightId, -1);\n const gL = gutterFor(colOrThrow(leftId), 1);\n const gR = gutterFor(colOrThrow(rightId), -1);\n const gReqL: GutterReq = { gutter: gL.gutter, side: gL.gSide, rowLo: row, rowHi: row + 0.5, lane: 0 };\n const gReqR: GutterReq = { gutter: gR.gutter, side: gR.gSide, rowLo: row, rowHi: row + 0.5, lane: 0 };\n gutterReqs.push(gReqL, gReqR);\n const cReq: CorridorReq = {\n corridor: row,\n xRange: () => {\n const xL = geo.gutterLaneX(gReqL);\n const xR = geo.gutterLaneX(gReqR);\n return [Math.min(xL, xR), Math.max(xL, xR)];\n },\n lane: 0,\n };\n corridorReqs.push(cReq);\n return () => {\n const yL = geo.cy(row) + stubOffset(stubL.slot);\n const yR = geo.cy(row) + stubOffset(stubR.slot);\n const xL = geo.gutterLaneX(gReqL);\n const xR = geo.gutterLaneX(gReqR);\n const cyCorr = geo.corridorLaneY(cReq);\n return [\n { x: geo.glyphRight(leftId), y: yL },\n { x: xL, y: yL },\n { x: xL, y: cyCorr },\n { x: xR, y: cyCorr },\n { x: xR, y: yR },\n { x: geo.glyphLeft(rightId), y: yR },\n ];\n };\n };\n\n const unionTitle = (u: Union): string =>\n u.quality !== null\n ? `${titleLabels.unionStatus[u.status]} · ${u.quality}`\n : titleLabels.unionStatus[u.status];\n const linkTitle = (l: { quality: string | null }): string =>\n l.quality !== null ? `${titleLabels.parentage} · ${l.quality}` : titleLabels.parentage;\n\n // 2a. Unions: same-row adjacent → bar; otherwise → elbow. (coparental drew nothing.)\n // McGoldrick SERIAL-UNION staggering (FIX B): when a person is in 2+ same-row union-bars\n // (remarriage), the bars would all sit at glyph-center cy and read as ONE continuous\n // rail. So within each connected chain of adjacent bars (components sharing a person),\n // the LOWEST union id stays at cy (level 0) and every other bar DIPS to a distinct depth\n // below the row's glyphs (level k → glyph bottom + k·UNION_STAGGER), drawn as a 3-seg\n // elbow (stub-down from each partner's glyph bottom → across → stub-up). The dip depth\n // is reserved in the row band (`rowDipDepth`) so labels never collide.\n const unionIsBar = new Map<number, boolean>();\n const barUnions = coupleUnions.filter(\n (u) =>\n rowOfPerson.get(u.personAId) === rowOfPerson.get(u.personBId) &&\n Math.abs(colOrThrow(u.personAId) - colOrThrow(u.personBId)) === 1,\n );\n // Per row, connected components of adjacent bar-unions (sharing a person), each ordered\n // by union id; index 0 → level 0 (cy), index k → dip level k. Deterministic.\n const unionDipLevel = new Map<number, number>(); // union id → dip level (0 = at cy)\n const rowDipLevels: number[] = Array.from({ length: rowCount }, () => 0);\n {\n const byRow = new Map<number, Union[]>();\n for (const u of barUnions) {\n const r = rowOfPerson.get(u.personAId)!;\n (byRow.get(r) ?? byRow.set(r, []).get(r)!).push(u);\n }\n for (const [r, rowUnions] of byRow) {\n // person → adjacent bar-unions on this row\n const unionsOfPerson = new Map<number, Union[]>();\n for (const u of rowUnions) {\n (unionsOfPerson.get(u.personAId) ?? unionsOfPerson.set(u.personAId, []).get(u.personAId)!).push(u);\n (unionsOfPerson.get(u.personBId) ?? unionsOfPerson.set(u.personBId, []).get(u.personBId)!).push(u);\n }\n const seen = new Set<number>();\n // Stable component discovery: walk unions in ascending id; BFS the shared-person graph.\n for (const start of [...rowUnions].sort((a, b) => a.id - b.id)) {\n if (seen.has(start.id)) continue;\n const comp: Union[] = [];\n const stack = [start];\n seen.add(start.id);\n while (stack.length > 0) {\n const u = stack.pop()!;\n comp.push(u);\n for (const pid of [u.personAId, u.personBId]) {\n for (const nb of unionsOfPerson.get(pid) ?? []) {\n if (!seen.has(nb.id)) {\n seen.add(nb.id);\n stack.push(nb);\n }\n }\n }\n }\n comp.sort((a, b) => a.id - b.id);\n comp.forEach((u, i) => unionDipLevel.set(u.id, i));\n rowDipLevels[r] = Math.max(rowDipLevels[r]!, comp.length - 1);\n }\n }\n }\n\n for (const u of coupleUnions) {\n const aRow = rowOfPerson.get(u.personAId)!;\n const bRow = rowOfPerson.get(u.personBId)!;\n const adjacent =\n aRow === bRow && Math.abs(colOrThrow(u.personAId) - colOrThrow(u.personBId)) === 1;\n unionIsBar.set(u.id, adjacent);\n const edgeId = UNION_REL_ID_BASE + u.id;\n if (adjacent) {\n const [leftId, rightId] = colOrThrow(u.personAId) < colOrThrow(u.personBId)\n ? [u.personAId, u.personBId]\n : [u.personBId, u.personAId];\n const dipLevel = unionDipLevel.get(u.id) ?? 0;\n planned.push({\n kind: \"union-bar\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: u.personAId,\n toPersonId: u.personBId,\n titles: [unionTitle(u)],\n lineStyle: \"plain\",\n build: () => {\n const cy = geo.cy(rowOfPerson.get(leftId)!);\n if (dipLevel === 0) {\n // First bar of the chain: the classic straight bar at glyph-center cy.\n return [\n { x: geo.glyphRight(leftId), y: cy },\n { x: geo.glyphLeft(rightId), y: cy },\n ];\n }\n // Dipped bar: stub-down from each partner's glyph BOTTOM to the dipped Y, across.\n // The stubs leave the glyph bottom OFFSET toward the partner (left partner →\n // right-of-center, right partner → left-of-center), so a person in two serial\n // unions (one on each side) gets two distinct stub columns that never overlap.\n const y = geo.unionDipY(rowOfPerson.get(leftId)!, dipLevel);\n const bottom = cy + NODE_SIZE / 2;\n const lx = geo.cx(colOrThrow(leftId)) + STUB_X_OFF; // partner is to the right\n const rx = geo.cx(colOrThrow(rightId)) - STUB_X_OFF; // partner is to the left\n return [\n { x: lx, y: bottom },\n { x: lx, y },\n { x: rx, y },\n { x: rx, y: bottom },\n ];\n },\n });\n } else {\n const sameRow = aRow === bRow;\n const build = sameRow\n ? planUConnector(u.personAId, u.personBId)\n : (() => {\n const [up, lo] = aRow < bRow ? [u.personAId, u.personBId] : [u.personBId, u.personAId];\n return planConnector(up, lo, false);\n })();\n planned.push({\n kind: \"union-elbow\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: u.personAId,\n toPersonId: u.personBId,\n titles: [unionTitle(u)],\n lineStyle: \"plain\",\n build,\n });\n }\n }\n\n // 2b. Descents. Decide, per child, the single declared COUPLE pair (if any) whose\n // union is an adjacent bar; that pair gets the shared sibling-bar descent, every\n // other declared genitor gets a dotted lone descent. No declared couple → all\n // dotted (Caso B / co-parental): each genitor its own descent, never a bar.\n const coupleChildrenByUnion = new Map<number, number[]>(); // union id → children\n const loneLinks: LayoutLink[] = [];\n for (const childId of [...parentsOf.keys()].sort((a, b) => a - b)) {\n const parents = [...parentsOf.get(childId)!].sort((a, b) => a - b);\n const couplePairUnions = parents\n .flatMap((p, i) => parents.slice(i + 1).map((q) => coupleByPair.get(pairKey(p, q))))\n .filter((u): u is Union => u !== undefined && unionIsBar.get(u.id) === true);\n if (couplePairUnions.length === 1) {\n const u = couplePairUnions[0]!;\n const arr = coupleChildrenByUnion.get(u.id) ?? [];\n arr.push(childId);\n coupleChildrenByUnion.set(u.id, arr);\n const couplePeople = new Set([u.personAId, u.personBId]);\n for (const p of parents) if (!couplePeople.has(p)) loneLinks.push(linkOf.get(`${p}>${childId}`)!);\n } else {\n for (const p of parents) loneLinks.push(linkOf.get(`${p}>${childId}`)!);\n }\n }\n\n // Couple descents (processed first, by union id): one shared sibling-bar per child-row\n // group, a center spine from the bar, and a vertical drop to each child's glyph TOP.\n for (const u of coupleUnions) {\n const children = coupleChildrenByUnion.get(u.id);\n if (children === undefined || children.length === 0) continue;\n const leftId = colOrThrow(u.personAId) < colOrThrow(u.personBId) ? u.personAId : u.personBId;\n const interGutter = colOrThrow(leftId); // gutter between the two adjacent partners\n const parentRow = rowOfPerson.get(u.personAId)!;\n // A couple descent must leave the union BAR, so on a dipped (serial-union) bar the\n // spine starts at the dipped bar's Y, not the glyph-center cy (FIX B).\n const uDipLevel = unionDipLevel.get(u.id) ?? 0;\n const spineStartY = (): number =>\n uDipLevel === 0 ? geo.cy(parentRow) : geo.unionDipY(parentRow, uDipLevel);\n // Group children by their row (almost always one row).\n const byChildRow = new Map<number, number[]>();\n for (const c of children) {\n const cr = rowOfPerson.get(c)!;\n (byChildRow.get(cr) ?? byChildRow.set(cr, []).get(cr)!).push(c);\n }\n for (const childRow of [...byChildRow.keys()].sort((a, b) => a - b)) {\n const groupKids = byChildRow.get(childRow)!.sort((a, b) => colOrThrow(a) - colOrThrow(b));\n // Corridor just above the child row; clamped in-range so a degenerate \"couple + child\n // all on generation 0\" (childRow === 0) routes in band 0 instead of corridor[-1]\n // (undefined) — defensive, no fixture triggers it (FIX D-2).\n const corridor = Math.max(0, Math.min(rowCount - 1, childRow - 1));\n // The descent lives in ONE corridor lane shared by the spine, sibling bar and the\n // child drops, spanning the spine column and every child column.\n const sibSpan = (): number[] => [geo.gutterCenterX(interGutter), ...groupKids.map((c) => geo.cx(colOrThrow(c)))];\n const sibReq: CorridorReq = {\n corridor,\n xRange: () => {\n const xs = sibSpan();\n return [Math.min(...xs), Math.max(...xs)];\n },\n lane: 0,\n };\n corridorReqs.push(sibReq);\n const spineReq: GutterReq = {\n gutter: interGutter,\n side: 0,\n rowLo: Math.min(parentRow, corridor + 0.5), // ordered (FIX D-2): never inverted\n rowHi: Math.max(parentRow, corridor + 0.5),\n lane: 0,\n };\n gutterReqs.push(spineReq);\n const aId = (c: number): number => linkOf.get(`${u.personAId}>${c}`)!.edgeId;\n // A child drop represents ONE declared parentage link (the given parent → c). Its\n // data-edge-id AND its <title> both come from THAT link, so the verbatim parentage\n // (incl. any quality word) matches what the drop's id declares (FIX C-1) — never a\n // hardcoded B-side title under an A-side id.\n const childDrop = (c: number, parentId: number): void => {\n const link = linkOf.get(`${parentId}>${c}`)!;\n const edgeId = link.edgeId;\n const arr = newArrival(c); // couples are processed first → claims the CENTER slot\n planned.push({\n kind: \"descent\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: null,\n toPersonId: c,\n titles: [linkTitle(link)],\n lineStyle: \"plain\",\n build: () => {\n const y = geo.corridorLaneY(sibReq);\n const x = geo.cx(colOrThrow(c)) + arrivalOffset(arr.slot, arrivalCount.get(c) ?? 1);\n return [\n { x, y },\n { x, y: geo.cy(rowOfPerson.get(c)!) - NODE_SIZE / 2 },\n ];\n },\n });\n };\n\n if (groupKids.length === 1) {\n // Single child: spine + bar-to-child is ONE elbow (parent A's link), the drop is\n // the other (parent B's link) — exactly two data-edge-id groups, one per declared\n // parentage (the verify-sweep 1:1 traceability contract), same pixels as a bar.\n const c = groupKids[0]!;\n planned.push({\n kind: \"descent\",\n relIds: [aId(c)],\n edgeId: aId(c),\n fromPersonId: null,\n toPersonId: null,\n titles: [linkTitle(linkOf.get(`${u.personAId}>${c}`)!)],\n lineStyle: \"plain\",\n build: () => {\n const sy = geo.corridorLaneY(sibReq);\n const sx = geo.gutterCenterX(interGutter);\n const cx = geo.cx(colOrThrow(c));\n return [\n { x: sx, y: spineStartY() },\n { x: sx, y: sy },\n { x: cx, y: sy },\n ];\n },\n });\n childDrop(c, u.personBId);\n } else {\n // ≥2 children: one shared sibling bar + one spine + a drop per child. Each child's\n // drop carries its B-side parentage id; the sibling bar carries A[0] (and traces\n // every remaining A-side link in relIds), the spine carries A[1] — distinct\n // data-edge-id per group, every declared link present in relIds.\n const aLinks = groupKids.map((c) => aId(c));\n // The verbatim A-side parentage title for child c (incl. any quality word).\n const aLinkTitle = (c: number): string => linkTitle(linkOf.get(`${u.personAId}>${c}`)!);\n planned.push({\n kind: \"sibling-bar\",\n relIds: [aLinks[0]!, ...aLinks.slice(2)],\n edgeId: aLinks[0]!,\n fromPersonId: null,\n toPersonId: null,\n // Carry the verbatim title of EVERY A-side link this bar represents, so no\n // declared quality word is dropped from the drawn element (FIX C-2 / SPEC inv #4).\n titles: [aLinkTitle(groupKids[0]!), ...groupKids.slice(2).map(aLinkTitle)],\n lineStyle: \"plain\",\n build: () => {\n const y = geo.corridorLaneY(sibReq);\n const xs = sibSpan();\n return [\n { x: Math.min(...xs), y },\n { x: Math.max(...xs), y },\n ];\n },\n });\n planned.push({\n kind: \"descent\",\n relIds: [aLinks[1]!],\n edgeId: aLinks[1]!,\n fromPersonId: null,\n toPersonId: null,\n titles: [aLinkTitle(groupKids[1]!)], // the A-side link this spine carries, verbatim\n lineStyle: \"plain\",\n build: () => {\n const sy = geo.corridorLaneY(sibReq);\n const x = geo.gutterCenterX(interGutter);\n return [\n { x, y: spineStartY() },\n { x, y: sy },\n ];\n },\n });\n for (const c of groupKids) childDrop(c, u.personBId);\n }\n }\n }\n\n // Lone / co-parental descents (dotted), by edge id (real before promoted, deterministic).\n for (const l of [...loneLinks].sort((a, b) => a.edgeId - b.edgeId)) {\n const edgeId = l.edgeId;\n const pRow = rowOfPerson.get(l.parentId)!;\n const cRow = rowOfPerson.get(l.childId)!;\n const build = pRow === cRow\n ? planUConnector(l.parentId, l.childId)\n : planConnector(l.parentId, l.childId, false);\n planned.push({\n kind: \"descent\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: l.parentId,\n toPersonId: l.childId,\n titles: [linkTitle(l)],\n lineStyle: \"plain\",\n dotted: true,\n build,\n });\n }\n\n // 2c. Bonds (free-text relationships), with the honesty-safe merge: same unordered\n // pair AND same computed lineStyle merge into one drawn element; different styles\n // draw separately (merging would have to pick one side's style).\n const bondGroups = new Map<string, { relIds: number[]; titles: string[]; style: EdgeLineStyle; aId: number; bId: number }>();\n for (const r of bondRels) {\n const style = qualityLineStyle(r.quality, opts.qualityLexicon);\n const lo = Math.min(r.fromPersonId, r.toPersonId);\n const hi = Math.max(r.fromPersonId, r.toPersonId);\n const key = `${lo}|${hi}|${style}`;\n const title = r.quality !== null ? `${r.type} · ${r.quality}` : r.type;\n const g = bondGroups.get(key);\n if (g === undefined) {\n bondGroups.set(key, { relIds: [r.id], titles: [title], style, aId: r.fromPersonId, bId: r.toPersonId });\n } else {\n g.relIds.push(r.id);\n g.titles.push(title);\n }\n }\n const bondList = [...bondGroups.values()].sort((a, b) => Math.max(...a.relIds) - Math.max(...b.relIds));\n for (const g of bondList) {\n const aRow = rowOfPerson.get(g.aId)!;\n const bRow = rowOfPerson.get(g.bId)!;\n const build = aRow === bRow\n ? planUConnector(g.aId, g.bId)\n : (() => {\n const [up, lo] = aRow < bRow ? [g.aId, g.bId] : [g.bId, g.aId];\n return planConnector(up, lo, false);\n })();\n planned.push({\n kind: \"bond\",\n relIds: g.relIds,\n edgeId: Math.max(...g.relIds),\n fromPersonId: g.aId,\n toPersonId: g.bId,\n titles: g.titles,\n lineStyle: g.style,\n build,\n });\n }\n\n // ── Pass 3: staged geometry so corridor lanes are allocated on EXACT pixel x ───────\n // Mutable geometry state, filled stage by stage; the build/xRange closures (created in\n // Pass 2) read it through `geo` at call time only — never before its stage fills it.\n const colCenterX: number[] = [];\n const colLeftX: number[] = [];\n const colRightX: number[] = [];\n const rowCenterY: number[] = [];\n const rowLabelTopY: number[] = [];\n const corridorTopY: number[] = [];\n const dims = { width: 0 };\n const gutterLaneCount = new Map<string, number>(); // `${gutter}:${side}` → count\n const corridorLaneCount: number[] = Array.from({ length: rowCount }, () => 0);\n const laneCount = (gutter: number, side: -1 | 0 | 1): number => gutterLaneCount.get(`${gutter}:${side}`) ?? 0;\n\n const geo = {\n cx: (c: number): number => colCenterX[c]!,\n cy: (r: number): number => rowCenterY[r]!,\n glyphRight: (id: number): number => colCenterX[colOrThrow(id)]! + NODE_SIZE / 2,\n glyphLeft: (id: number): number => colCenterX[colOrThrow(id)]! - NODE_SIZE / 2,\n gutterCenterX: (g: number): number => {\n const left = g < 0 ? PADDING : colRightX[g]!;\n const right = g >= colCount - 1 ? dims.width - PADDING : colLeftX[g + 1]!;\n return (left + right) / 2;\n },\n gutterLaneX: (req: GutterReq): number => {\n const left = req.gutter < 0 ? PADDING : colRightX[req.gutter]!;\n const right = req.gutter >= colCount - 1 ? dims.width - PADDING : colLeftX[req.gutter + 1]!;\n const lCount = laneCount(req.gutter, -1);\n if (req.side === -1) return left + (req.lane + 1) * LANE_H; // hug left, stack rightward\n if (req.side === 0) return left + (lCount + req.lane + 1) * LANE_H; // center group (spine)\n return right - (req.lane + 1) * LANE_H; // hug right, stack leftward\n },\n corridorLaneY: (req: CorridorReq): number =>\n corridorTopY[req.corridor]! + CORRIDOR_BASE / 2 + req.lane * LANE_H,\n /** Y of a dipped serial-union bar (level ≥ 1): below the row's glyph bottom edge. */\n unionDipY: (r: number, level: number): number =>\n rowCenterY[r]! + NODE_SIZE / 2 + level * UNION_STAGGER,\n };\n\n // Stage 1 — gutter lanes: per (gutter, side), by row-span interval. Left-hug and\n // right-hug stacks sit on opposite sides; the center group is the union spine.\n const gutterGroups = new Map<string, GutterReq[]>();\n for (const req of gutterReqs) {\n const k = `${req.gutter}:${req.side}`;\n (gutterGroups.get(k) ?? gutterGroups.set(k, []).get(k)!).push(req);\n }\n for (const [k, reqs] of gutterGroups) {\n gutterLaneCount.set(\n k,\n allocateLanes(reqs.map((req) => ({ lo: req.rowLo, hi: req.rowHi, set: (lane: number) => (req.lane = lane) }))),\n );\n }\n\n // Stage 2 — column geometry from gutter lane counts (+ the isolated extra gutter).\n const gutterWidth = (g: number): number => {\n const lanes = laneCount(g, -1) + laneCount(g, 0) + laneCount(g, 1);\n const extra = g === isolatedTailCol - 1 ? ISOLATED_GUTTER_EXTRA : 0;\n if (g === -1 || g === colCount - 1) return lanes > 0 ? COL_PAD + lanes * LANE_H + extra : extra;\n return COL_PAD + lanes * LANE_H + extra;\n };\n let cursorX = PADDING + gutterWidth(-1);\n for (let c = 0; c < colCount; c++) {\n colLeftX[c] = cursorX;\n colCenterX[c] = cursorX + colWidth[c]! / 2;\n cursorX += colWidth[c]!;\n colRightX[c] = cursorX;\n cursorX += gutterWidth(c);\n }\n dims.width = cursorX + PADDING;\n\n // Stage 3 — corridor lanes on EXACT pixel x-ranges (columns are now placed, so a\n // within-one-gutter span is measured precisely — no collapsing u-index proxy).\n const corridorGroups = new Map<number, CorridorReq[]>();\n for (const req of corridorReqs) (corridorGroups.get(req.corridor) ?? corridorGroups.set(req.corridor, []).get(req.corridor)!).push(req);\n for (const [k, reqs] of corridorGroups) {\n corridorLaneCount[k] = allocateLanes(\n reqs.map((req) => {\n const [lo, hi] = req.xRange();\n return { lo, hi, set: (lane: number) => (req.lane = lane) };\n }),\n );\n }\n\n // Stage 4 — row geometry from corridor lane counts.\n const corridorHeight = (k: number): number => {\n const lanes = corridorLaneCount[k] ?? 0;\n if (lanes > 0) return CORRIDOR_BASE + lanes * LANE_H;\n return k < rowCount - 1 ? CORRIDOR_BASE : 0; // interior rows always keep a gap\n };\n // Reserve a band BELOW each row's glyphs for its dipped serial-union bars (FIX B), so\n // labels sit below the deepest dip and never collide. 0 when the row has no remarriage.\n const rowDipReserve = (r: number): number =>\n rowDipLevels[r]! > 0 ? rowDipLevels[r]! * UNION_STAGGER + 6 : 0;\n let cursorY = PADDING;\n for (let r = 0; r < rowCount; r++) {\n rowCenterY[r] = cursorY + NODE_SIZE / 2;\n rowLabelTopY[r] = cursorY + NODE_SIZE + rowDipReserve(r) + LABEL_GAP_TOP;\n cursorY = rowLabelTopY[r]! + rowMaxLines[r]! * LABEL_LINE_H;\n corridorTopY[r] = cursorY;\n cursorY += corridorHeight(r);\n }\n const width = dims.width;\n const height = cursorY + PADDING;\n\n // ── Build nodes + finalize elements ──────────────────────────────────────────────\n const nodes: GenogramNode[] = [...people]\n .sort((a, b) => a.id - b.id)\n .map((p) => {\n const m = measured.get(p.id)!;\n const r = rowOfPerson.get(p.id)!;\n const c = colOrThrow(p.id);\n return {\n personId: p.id,\n label: p.label,\n shape: shapeForSex(p.sex),\n deceased: p.deceased,\n cx: colCenterX[c]!,\n cy: rowCenterY[r]!,\n size: NODE_SIZE,\n labelLines: m.lines,\n labelTop: rowLabelTopY[r]!,\n };\n });\n\n const elements: GenogramElement[] = planned.map((pl) => ({\n kind: pl.kind,\n relIds: pl.relIds,\n edgeId: pl.edgeId,\n fromPersonId: pl.fromPersonId,\n toPersonId: pl.toPersonId,\n points: pl.build(),\n titles: pl.titles,\n lineStyle: pl.lineStyle,\n ...(pl.unionStyle !== undefined ? { unionStyle: pl.unionStyle } : {}),\n ...(pl.dotted ? { dotted: true } : {}),\n }));\n\n // People with no drawn connection (only-suppressed/derived ties, or none at all).\n const isolatedPersonIds = people\n .filter((p) => isIsolated(p.id))\n .map((p) => p.id)\n .sort((a, b) => a - b);\n\n return { width, height, nodes, elements, isolatedPersonIds };\n}\n\n/** Linearize a connected couple-component so partners land adjacent. A simple path is\n * walked from its lowest-id endpoint (→ a clean chain); anything else is DFS-ordered\n * from the lowest id (hub gets two adjacent partners; the rest become union-elbows). */\nfunction linearizeBlock(comp: number[], adj: Map<number, number[]>): number[] {\n if (comp.length <= 1) return [...comp];\n const inComp = new Set(comp);\n const degree = (id: number): number => adj.get(id)!.filter((n) => inComp.has(n)).length;\n const endpoints = comp.filter((id) => degree(id) === 1).sort((a, b) => a - b);\n const edgeCount = comp.reduce((s, id) => s + degree(id), 0) / 2;\n const isPath = edgeCount === comp.length - 1 && endpoints.length === 2;\n const order: number[] = [];\n const seen = new Set<number>();\n if (isPath) {\n let cur: number | undefined = endpoints[0]!;\n while (cur !== undefined) {\n order.push(cur);\n seen.add(cur);\n cur = adj.get(cur)!.filter((n) => inComp.has(n)).sort((a, b) => a - b).find((n) => !seen.has(n));\n }\n return order;\n }\n const stack = [Math.min(...comp)];\n while (stack.length > 0) {\n const n = stack.pop()!;\n if (seen.has(n)) continue;\n seen.add(n);\n order.push(n);\n for (const m of adj.get(n)!.filter((x) => inComp.has(x)).sort((a, b) => b - a)) {\n if (!seen.has(m)) stack.push(m);\n }\n }\n return order;\n}\n","// Genogram SVG emitter — turns a computed GenogramLayout (./layout.ts, the pure\n// orthogonal declared-generation layout) into a SELF-CONTAINED SVG string.\n//\n// Two hard requirements:\n// - XML-ESCAPING of EVERY interpolated text. Labels are author-controlled and the\n// SVG string may be injected via innerHTML in a browser or embedded as vectors in\n// a PDF — an unescaped label is an XSS/`</svg>`-breakout vector on every surface.\n// - LITERAL presentation attributes (hex colors, inline stroke-dasharray, an explicit\n// font-family). A standalone SVG inside a PDF has no stylesheet, no `currentColor`.\n//\n// It is deliberately PURE (string in, string out) and DETERMINISTIC (same layout → same\n// SVG), and it draws EXACTLY what the layout computed: node centers and the routed\n// orthogonal polylines are consumed verbatim, never recomputed (the overlap harness\n// proves the layout; this emitter is pinned to it). Decoration hooks for callers: one\n// `<g data-individual-id=\"p<id>\">` per person with a direct-child `<title>` and bare\n// rect/circle/polygon glyph; `data-edge-id` on every routed group.\n//\n// HONESTY RULE: presentation only. There is ZERO text on map edges — the verbatim\n// \"type · quality\" / status label lives in each routed group's <title> (and the\n// caller's side lists). The one styling decision the CALLER may make is\n// `unionStyleByRelId`: a per-edge VISUAL override applied at emission — a\n// stroke-dasharray and/or McGoldrick status slashes — giving each declared union TYPE\n// the full notation (married solid, cohabiting/dating dashed, separated one slash,\n// divorced two) without the layout fabricating any quality text.\nimport { FONT_FAMILY, xmlEscape } from \"../core\";\nimport {\n EDGE_STROKE,\n LABEL_FONT,\n LABEL_LINE_H,\n estimateTextWidth,\n type GenogramElement,\n type GenogramLayout,\n type NodeShape,\n type Point,\n type UnionEdgeStyle,\n} from \"./layout\";\nimport { GENOGRAM_SVG_LABELS_EN, type GenogramSvgLabels } from \"./labels\";\n\n// Re-export so callers can reach the union-notation type through the emitter module.\nexport type { UnionEdgeStyle } from \"./layout\";\nexport { xmlEscape };\n\n// Literal ink colors (zinc ramp, matching the app shell on white — the PDF page).\nconst GLYPH_STROKE = \"#52525b\";\nconst NODE_LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\n\n// Structural (union / descent / sibling-bar) stroke — neutral, solid.\nconst STRUCT_WIDTH = 1.5;\nconst STRUCT_OPACITY = 0.75;\n// Dotted descent (lone-parent / co-parental): the visual kin of schematex's secondary.\nconst DOTTED_DASH: readonly [number, number] = [2, 3];\nconst DOTTED_OPACITY = 0.55;\n\n// Legend metrics (own, minimal — pt-BR only).\nconst LEGEND_ROW_H = 18;\nconst LEGEND_PAD = 16;\nconst LEGEND_SWATCH_W = 22;\nconst LEGEND_GAP = 14; // swatch → label gap (the \"Boxo\" fix: was 8, too tight)\nconst LEGEND_FONT = 11;\n\nexport interface GenogramSvgOptions {\n /**\n * Per-edge VISUAL union style (edgeId → {dash?, slashes?}), applied at emission.\n * Gives each declared union TYPE its own McGoldrick notation. Overrides any\n * `unionStyle` already on the element.\n */\n unionStyleByRelId?: ReadonlyMap<number, UnionEdgeStyle>;\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary (legend/accessibility) — English default; see locale packs. */\n labels?: GenogramSvgLabels;\n}\n\n/** Glyph markup for one shape centered at (cx, cy) with the given half-size. */\nfunction glyphSvg(shape: NodeShape, cx: number, cy: number, half: number): string {\n const stroke = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"`;\n if (shape === \"square\") {\n return `<rect x=\"${cx - half}\" y=\"${cy - half}\" width=\"${half * 2}\" height=\"${half * 2}\" rx=\"4\" ${stroke}/>`;\n }\n if (shape === \"circle\") {\n return `<circle cx=\"${cx}\" cy=\"${cy}\" r=\"${half}\" ${stroke}/>`;\n }\n return `<polygon points=\"${cx},${cy - half} ${cx + half},${cy} ${cx},${cy + half} ${cx - half},${cy}\" ${stroke}/>`;\n}\n\n/** \"M x y L x y …\" path data from an orthogonal polyline. */\nfunction pathData(points: Point[]): string {\n return points.map((p, i) => `${i === 0 ? \"M\" : \"L\"} ${p.x} ${p.y}`).join(\" \");\n}\n\n/** The longest horizontal segment of a polyline (for placing union-elbow slashes). */\nfunction longestHSegment(points: Point[]): [Point, Point] {\n let best: [Point, Point] = [points[0]!, points[points.length - 1]!];\n let bestLen = -1;\n for (let i = 0; i + 1 < points.length; i++) {\n const a = points[i]!;\n const b = points[i + 1]!;\n if (a.y === b.y) {\n const len = Math.abs(b.x - a.x);\n if (len > bestLen) {\n bestLen = len;\n best = [a, b];\n }\n }\n }\n return best;\n}\n\n/**\n * McGoldrick status slashes at the midpoint of a segment (1 = separação, 2 = divórcio),\n * drawn in screen-space \"/\" orientation and offset along the segment for the two divorce\n * strokes. Same ink/width as the bar so the mark reads as part of it.\n */\nfunction slashMarks(a: Point, b: Point, count: 1 | 2, width: number): string {\n const mx = (a.x + b.x) / 2;\n const my = (a.y + b.y) / 2;\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const len = Math.hypot(dx, dy) || 1;\n const ux = dx / len;\n const uy = dy / len;\n const HALF = 7; // slash half-length\n const STEP = 4; // along-segment offset between the two divorce slashes\n const offsets = count === 1 ? [0] : [-STEP, STEP];\n return offsets\n .map((o) => {\n const px = mx + ux * o;\n const py = my + uy * o;\n return `<line x1=\"${px - HALF}\" y1=\"${py + HALF}\" x2=\"${px + HALF}\" y2=\"${py - HALF}\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\"/>`;\n })\n .join(\"\");\n}\n\n/** Resolve a union element's effective McGoldrick style (override wins over element). */\nfunction resolveUnionStyle(\n el: GenogramElement,\n override: ReadonlyMap<number, UnionEdgeStyle>,\n): UnionEdgeStyle {\n return override.get(el.edgeId) ?? el.unionStyle ?? {};\n}\n\n/** Emits one routed element as a `<g data-edge-id>` group (≥3 points → path, else line),\n * with the verbatim titles in a <title> and ZERO text. */\nfunction elementSvg(el: GenogramElement, override: ReadonlyMap<number, UnionEdgeStyle>): string {\n const title = `<title>${xmlEscape(el.titles.join(\"\\n\"))}</title>`;\n const pts = el.points;\n const drawLine = (dash: readonly [number, number] | null, width: number, opacity: number): string => {\n const dashAttr = dash === null ? \"\" : ` stroke-dasharray=\"${dash[0]} ${dash[1]}\"`;\n if (pts.length === 2) {\n return `<line x1=\"${pts[0]!.x}\" y1=\"${pts[0]!.y}\" x2=\"${pts[1]!.x}\" y2=\"${pts[1]!.y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\" stroke-opacity=\"${opacity}\"${dashAttr}/>`;\n }\n return `<path d=\"${pathData(pts)}\" fill=\"none\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\" stroke-opacity=\"${opacity}\"${dashAttr}/>`;\n };\n\n if (el.kind === \"union-bar\" || el.kind === \"union-elbow\") {\n const style = resolveUnionStyle(el, override);\n const body: string[] = [drawLine(style.dash ?? null, STRUCT_WIDTH, STRUCT_OPACITY)];\n const slashes = style.slashes ?? 0;\n if (slashes === 1 || slashes === 2) {\n // A straight 2-point bar uses its own segment; a dipped serial-union bar (3-seg\n // elbow, FIX B) and any union-elbow ride the LONGEST horizontal segment so the\n // separado/divorciado slashes land on the across part, never on a vertical stub.\n const [a, b] = pts.length === 2 ? [pts[0]!, pts[1]!] : longestHSegment(pts);\n body.push(slashMarks(a, b, slashes, STRUCT_WIDTH));\n }\n return `<g data-edge-id=\"${el.edgeId}\">${title}${body.join(\"\")}</g>`;\n }\n\n if (el.kind === \"descent\" || el.kind === \"sibling-bar\") {\n const dash = el.dotted ? DOTTED_DASH : null;\n const opacity = el.dotted ? DOTTED_OPACITY : STRUCT_OPACITY;\n return `<g data-edge-id=\"${el.edgeId}\">${title}${drawLine(dash, STRUCT_WIDTH, opacity)}</g>`;\n }\n\n // bond\n const ink = EDGE_STROKE[el.lineStyle];\n return `<g data-edge-id=\"${el.edgeId}\">${title}${drawLine(ink.dash, ink.width, ink.opacity)}</g>`;\n}\n\n/**\n * Emits a self-contained SVG for a computed genogram layout. Pure + deterministic.\n * Coordinates come straight from the layout; all interpolated text is XML-escaped; all\n * presentation attributes are literal; there is NO text on map edges.\n */\nexport function genogramLayoutSvg(layout: GenogramLayout, opts: GenogramSvgOptions = {}): string {\n const override = opts.unionStyleByRelId ?? new Map<number, UnionEdgeStyle>();\n const labels = opts.labels ?? GENOGRAM_SVG_LABELS_EN;\n const parts: string[] = [];\n\n // ── Routed elements first so nodes sit on top (same stacking as the JSX render). ───\n for (const el of layout.elements) parts.push(elementSvg(el, override));\n\n // ── Nodes: glyph + deceased mark + wrapped label, hook-compatible with schematex. ─\n for (const node of layout.nodes) {\n const half = node.size / 2;\n const pieces: string[] = [\n `<title>${xmlEscape(node.label)}</title>`,\n glyphSvg(node.shape, node.cx, node.cy, half),\n ];\n if (node.deceased) {\n pieces.push(\n `<line x1=\"${node.cx - half}\" y1=\"${node.cy - half}\" x2=\"${node.cx + half}\" y2=\"${node.cy + half}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"/>`,\n );\n }\n const tspans = node.labelLines\n .map(\n (line, i) =>\n `<tspan x=\"${node.cx}\" y=\"${node.labelTop + 10 + i * LABEL_LINE_H}\">${xmlEscape(line)}</tspan>`,\n )\n .join(\"\");\n pieces.push(\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${LABEL_FONT}\" fill=\"${NODE_LABEL_FILL}\">${tspans}</text>`,\n );\n parts.push(`<g data-individual-id=\"p${node.personId}\">${pieces.join(\"\")}</g>`);\n }\n\n // ── Minimal pt-BR legend: only entries actually used. ──────────────────────────────\n let width = layout.width;\n let height = layout.height;\n if (opts.legend !== false && layout.nodes.length > 0) {\n const entries: { swatch: (x: number, y: number) => string; label: string }[] = [];\n\n const shapesUsed = new Set(layout.nodes.map((n) => n.shape));\n for (const shape of [\"square\", \"circle\", \"diamond\"] as const) {\n if (!shapesUsed.has(shape)) continue;\n entries.push({\n swatch: (x, y) => glyphSvg(shape, x + LEGEND_SWATCH_W / 2, y, 6),\n label: labels.shapes[shape],\n });\n }\n if (layout.nodes.some((n) => n.deceased)) {\n entries.push({\n swatch: (x, y) =>\n glyphSvg(\"square\", x + LEGEND_SWATCH_W / 2, y, 6) +\n `<line x1=\"${x + LEGEND_SWATCH_W / 2 - 6}\" y1=\"${y - 6}\" x2=\"${x + LEGEND_SWATCH_W / 2 + 6}\" y2=\"${y + 6}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"/>`,\n label: labels.deceased,\n });\n }\n\n // NOTE (deliberate, gate-tested): the fallback legend carries NO union-TYPE or\n // dotted-descent entry. Each declared union's type and each co-parenthood fact lives\n // VERBATIM in the element's <title> and in the dossier's structured side lists (the\n // psychologist's authoritative reading) — duplicating it as a legend key is the\n // \"known, documented gap\" pinned by test/verify-pdf.test.ts §(e). The dash/slash\n // notation itself stays on the drawn bars; only the legend stays minimal.\n\n // Bond styles actually used.\n const stylesUsed = new Set(layout.elements.filter((e) => e.kind === \"bond\").map((e) => e.lineStyle));\n for (const style of [\"close\", \"distant\", \"conflict\", \"cutoff\"] as const) {\n if (!stylesUsed.has(style)) continue;\n const ink = EDGE_STROKE[style];\n const dashAttr = ink.dash === null ? \"\" : ` stroke-dasharray=\"${ink.dash[0]} ${ink.dash[1]}\"`;\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${ink.width}\" stroke-opacity=\"${ink.opacity}\"${dashAttr}/>`,\n label: labels.bondStyles[style],\n });\n }\n\n // Unconnected glyphs (a person whose only declared tie is derived kinship like \"minha\n // tia\" — read from the tree, never a line — or who was mentioned with no tie at all)\n // sit grouped to the side with NO connector. This entry labels that group so a loose\n // glyph is never left unexplained; the verbatim tie still lives in the dossier list.\n if (layout.isolatedPersonIds.length > 0) {\n entries.push({\n swatch: (x, y) => glyphSvg(\"square\", x + LEGEND_SWATCH_W / 2, y, 6),\n label: labels.isolated,\n });\n }\n\n if (entries.length > 0) {\n const startY = layout.height;\n const rows = entries.map((entry, i) => {\n const rowCenterY = startY + i * LEGEND_ROW_H + LEGEND_ROW_H / 2;\n const textX = LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP;\n return (\n entry.swatch(LEGEND_PAD, rowCenterY) +\n `<text x=\"${textX}\" y=\"${rowCenterY + LEGEND_FONT * 0.32}\" font-family=\"${FONT_FAMILY}\" font-size=\"${LEGEND_FONT}\" fill=\"${GLYPH_STROKE}\">${xmlEscape(entry.label)}</text>`\n );\n });\n parts.push(`<g data-compasso-legend=\"true\">${rows.join(\"\")}</g>`);\n const widestLabel = entries.reduce((m, e) => Math.max(m, estimateTextWidth(e.label, LEGEND_FONT)), 0);\n width = Math.max(width, LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP + widestLabel + LEGEND_PAD);\n height = startY + entries.length * LEGEND_ROW_H + LEGEND_PAD / 2;\n }\n }\n\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\" width=\"${width}\" height=\"${height}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// One-call genogram render: input → self-contained SVG string. Thin, honest wiring:\n// dedupe unions per pair, compute the pure layout, give each declared union TYPE its\n// McGoldrick notation as a per-edge visual override, emit. Callers needing finer\n// control use computeGenogramLayout + genogramLayoutSvg directly.\n\nimport {\n UNION_REL_ID_BASE,\n computeGenogramLayout,\n type GenogramLayout,\n type GenogramLayoutOptions,\n type UnionEdgeStyle,\n} from \"./layout\";\nimport { genogramLayoutSvg } from \"./svg\";\nimport type { GenogramSvgLabels } from \"./labels\";\nimport type { GenogramInput, Union, UnionStatus } from \"./types\";\n\n/** Shared 6,4 dash for every cohabiting-flavoured union (cohabiting / dating /\n * type-not-stated), so non-marital couples read consistently. */\nconst COUPLE_DASH = [6, 4] as const;\n\n/**\n * McGoldrick notation per declared union TYPE — a per-edge VISUAL override applied at\n * emission, never a synthesized quality. `coparental` is ABSENT on purpose: it draws\n * NO couple element at all; the co-parenthood shows only on the descents converging\n * on the child(ren).\n */\nexport const UNION_NOTATION: Record<Exclude<UnionStatus, \"coparental\">, UnionEdgeStyle> = {\n married: {}, // solid bar\n cohabiting: { dash: COUPLE_DASH },\n dating: { dash: COUPLE_DASH },\n unknown: { dash: COUPLE_DASH },\n separated: { slashes: 1 }, // solid + one diagonal slash\n divorced: { slashes: 2 }, // solid + two parallel slashes\n};\n\n/**\n * Duplicate unions for the same unordered pair should not exist (callers are expected\n * to normalize), but if they do, the HIGHEST id wins — the most recent statement.\n * NEVER a status-rank heuristic: recency is a fact, ranking would be an interpretation.\n */\nexport function latestUnionPerPair(unions: Union[]): Union[] {\n const byPair = new Map<string, Union>();\n for (const u of [...unions].sort((a, b) => a.id - b.id)) {\n const key = `${Math.min(u.personAId, u.personBId)}|${Math.max(u.personAId, u.personBId)}`;\n byPair.set(key, u);\n }\n return [...byPair.values()].sort((a, b) => a.id - b.id);\n}\n\nexport interface GenogramRenderOptions extends GenogramLayoutOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary for the emitter (legend/accessibility) — English default. */\n svgLabels?: GenogramSvgLabels;\n}\n\nexport interface GenogramRenderResult {\n /** Self-contained SVG (numeric width/height + matching viewBox — PDF-embedder safe). */\n svg: string;\n /** The computed layout, for callers that decorate or hit-test the diagram. */\n layout: GenogramLayout;\n}\n\n/**\n * Renders a genogram input to a self-contained SVG string. Deterministic: same data →\n * same SVG. Empty `people` yields an empty-but-valid SVG; callers decide their own\n * empty state before calling.\n */\nexport function genogramSvg(\n input: GenogramInput,\n opts: GenogramRenderOptions = {},\n): GenogramRenderResult {\n const ids = new Set(input.people.map((p) => p.id));\n const dedupedUnions = latestUnionPerPair(input.unions).filter(\n (u) => ids.has(u.personAId) && ids.has(u.personBId),\n );\n\n const layout = computeGenogramLayout(\n input.people,\n dedupedUnions,\n input.parentLinks,\n input.relationships,\n opts,\n );\n\n const unionStyleByRelId = new Map<number, UnionEdgeStyle>();\n for (const u of dedupedUnions) {\n if (u.status === \"coparental\") continue; // no element — nothing to style\n unionStyleByRelId.set(UNION_REL_ID_BASE + u.id, UNION_NOTATION[u.status]);\n }\n\n const svg = genogramLayoutSvg(layout, {\n unionStyleByRelId,\n ...(opts.legend === false ? { legend: false } : {}),\n ...(opts.svgLabels !== undefined ? { labels: opts.svgLabels } : {}),\n });\n return { svg, layout };\n}\n"]}