pattapatta 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 (74) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +98 -0
  4. package/dist/circle-BDbKfrdR.d.ts +12 -0
  5. package/dist/circlePacking/index.d.ts +78 -0
  6. package/dist/circlePacking/index.js +381 -0
  7. package/dist/circlePacking/index.js.map +1 -0
  8. package/dist/cli.js +365 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/construction/index.d.ts +26 -0
  11. package/dist/construction/index.js +102 -0
  12. package/dist/construction/index.js.map +1 -0
  13. package/dist/contour/index.d.ts +20 -0
  14. package/dist/contour/index.js +118 -0
  15. package/dist/contour/index.js.map +1 -0
  16. package/dist/conversion/index.d.ts +31 -0
  17. package/dist/conversion/index.js +99 -0
  18. package/dist/conversion/index.js.map +1 -0
  19. package/dist/group-BNjVVYSQ.d.ts +13 -0
  20. package/dist/hatch/index.d.ts +41 -0
  21. package/dist/hatch/index.js +253 -0
  22. package/dist/hatch/index.js.map +1 -0
  23. package/dist/hull/index.d.ts +16 -0
  24. package/dist/hull/index.js +97 -0
  25. package/dist/hull/index.js.map +1 -0
  26. package/dist/index.d.ts +67 -0
  27. package/dist/index.js +3933 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/meshing/index.d.ts +125 -0
  30. package/dist/meshing/index.js +1333 -0
  31. package/dist/meshing/index.js.map +1 -0
  32. package/dist/morphology/index.d.ts +58 -0
  33. package/dist/morphology/index.js +268 -0
  34. package/dist/morphology/index.js.map +1 -0
  35. package/dist/optimisation/index.d.ts +43 -0
  36. package/dist/optimisation/index.js +400 -0
  37. package/dist/optimisation/index.js.map +1 -0
  38. package/dist/path-0RjhYjJs.d.ts +21 -0
  39. package/dist/pointSet/index.d.ts +24 -0
  40. package/dist/pointSet/index.js +139 -0
  41. package/dist/pointSet/index.js.map +1 -0
  42. package/dist/polygonisation/index.d.ts +44 -0
  43. package/dist/polygonisation/index.js +310 -0
  44. package/dist/polygonisation/index.js.map +1 -0
  45. package/dist/predicates/index.d.ts +35 -0
  46. package/dist/predicates/index.js +159 -0
  47. package/dist/predicates/index.js.map +1 -0
  48. package/dist/processing/index.d.ts +54 -0
  49. package/dist/processing/index.js +457 -0
  50. package/dist/processing/index.js.map +1 -0
  51. package/dist/segment-BKuIFMKD.d.ts +10 -0
  52. package/dist/segmentSet/index.d.ts +25 -0
  53. package/dist/segmentSet/index.js +109 -0
  54. package/dist/segmentSet/index.js.map +1 -0
  55. package/dist/shapeBoolean/index.d.ts +41 -0
  56. package/dist/shapeBoolean/index.js +211 -0
  57. package/dist/shapeBoolean/index.js.map +1 -0
  58. package/dist/svg/index.d.ts +38 -0
  59. package/dist/svg/index.js +317 -0
  60. package/dist/svg/index.js.map +1 -0
  61. package/dist/tiling/index.d.ts +32 -0
  62. package/dist/tiling/index.js +344 -0
  63. package/dist/tiling/index.js.map +1 -0
  64. package/dist/transformation/index.d.ts +37 -0
  65. package/dist/transformation/index.js +184 -0
  66. package/dist/transformation/index.js.map +1 -0
  67. package/dist/triangulation/index.d.ts +48 -0
  68. package/dist/triangulation/index.js +334 -0
  69. package/dist/triangulation/index.js.map +1 -0
  70. package/dist/vec2-CWyXN1Wj.d.ts +10 -0
  71. package/dist/voronoi/index.d.ts +31 -0
  72. package/dist/voronoi/index.js +211 -0
  73. package/dist/voronoi/index.js.map +1 -0
  74. package/package.json +165 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types/vec2.ts","../../src/types/segment.ts","../../src/types/path.ts","../../src/segmentSet/index.ts","../../src/clipper/convert.ts","../../src/predicates/index.ts","../../src/segmentSet/clip.ts","../../src/hatch/index.ts"],"names":["path"],"mappings":";;;AAMO,SAAS,IAAA,CAAK,GAAW,CAAA,EAAiB;AAC/C,EAAA,OAAO,EAAE,GAAG,CAAA,EAAE;AAChB;AAEO,SAAS,UAAU,CAAA,EAAe;AACvC,EAAA,OAAO,EAAE,CAAA,EAAG,CAAA,CAAE,CAAA,EAAG,CAAA,EAAG,EAAE,CAAA,EAAE;AAC1B;AAEO,SAAS,UAAA,CAAW,CAAA,EAAS,CAAA,EAAS,GAAA,GAAM,IAAA,EAAe;AAChE,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,EAAE,CAAC,CAAA,IAAK,GAAA,IAAO,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,IAAK,GAAA;AAC9D;;;ACRO,SAAS,OAAA,CAAQ,GAAS,CAAA,EAAkB;AACjD,EAAA,OAAO,EAAE,GAAG,CAAA,EAAE;AAChB;;;ACsBO,SAAS,aAAA,CAAc,IAAA,EAAY,GAAA,GAAM,IAAA,EAAY;AAC1D,EAAA,IAAI,KAAK,MAAA,GAAS,CAAA,EAAG,OAAO,IAAA,CAAK,IAAI,SAAS,CAAA;AAC9C,EAAA,MAAM,KAAA,GAAQ,KAAK,CAAC,CAAA;AACpB,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA;AACjC,EAAA,IAAI,SAAS,IAAA,IAAQ,UAAA,CAAW,KAAA,EAAO,IAAA,EAAM,GAAG,CAAA,EAAG;AACjD,IAAA,OAAO,KAAK,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,CAAE,IAAI,SAAS,CAAA;AAAA,EACxC;AACA,EAAA,OAAO,IAAA,CAAK,IAAI,SAAS,CAAA;AAC3B;;;ACpCA,SAAS,IAAI,CAAA,EAAmB;AAC9B,EAAA,OAAO,IAAA,CAAK,OAAO,CAAC,CAAA;AACtB;AAOO,SAAS,iBACd,OAAA,EACA,OAAA,EACA,MAAA,EACA,OAAA,EACA,OACA,CAAA,EACW;AACX,EAAA,MAAM,QAAmB,EAAC;AAC1B,EAAA,IAAI,CAAA,GAAI,GAAG,OAAO,KAAA;AAElB,EAAA,MAAM,SAAS,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA,EAAG,GAAA,CAAI,OAAO,CAAC,CAAA;AAC9C,EAAA,IAAI,EAAA,GAAK,IAAI,IAAA,CAAK,GAAA,CAAI,QAAQ,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA,GAAI,OAAO,CAAA;AACpD,EAAA,IAAI,EAAA,GAAK,IAAI,IAAA,CAAK,GAAA,CAAI,QAAQ,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA,GAAI,OAAO,CAAA;AACpD,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,KAAK,CAAC,CAAA;AAC/B,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,KAAK,CAAC,CAAA;AAC/B,EAAA,MAAM,CAAA,GAAI,IAAI,MAAM,CAAA;AAEpB,EAAA,IAAI,CAAA;AACJ,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,IAAI,IAAA,GAAO,CAAA;AAEX,EAAA,IAAI,CAAA,GAAI,MAAM,CAAA,EAAG;AACf,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,CAAA,GAAI,GAAA,GAAM,CAAC,CAAA,EAAG,GAAA,CAAI,MAAA,CAAO,CAAA,GAAI,GAAA,GAAM,CAAC,CAAC,CAAA;AAC/D,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,IAAI,GAAA,GAAM,CAAC,CAAC,CAAA,EAAG,IAAI,MAAA,CAAO,CAAA,GAAI,GAAA,GAAM,CAAC,CAAC,CAAC,CAAA;AACjE,IAAA,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,CAAA,EAAG,CAAC,CAAC,CAAA;AACxB,IAAA,CAAA,GAAI,CAAA;AAAA,EACN,CAAA,MAAO;AACL,IAAA,EAAA,GAAK,GAAA,CAAI,KAAK,CAAC,CAAA;AACf,IAAA,EAAA,GAAK,GAAA,CAAI,KAAK,CAAC,CAAA;AACf,IAAA,CAAA,GAAI,CAAA;AACJ,IAAA;AACE,MAAA,IAAI,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,CAAA,GAAI,EAAA,GAAK,CAAC,CAAA,EAAG,GAAA,CAAI,MAAA,CAAO,CAAA,GAAI,EAAA,GAAK,CAAC,CAAC,CAAA;AAC3D,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,GAAA,GAAM,CAAC,CAAA,EAAG,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,GAAA,GAAM,CAAC,CAAC,CAAA;AACrD,MAAA,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,MAAM,CAAC,CAAC,CAAA,EAAG,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,GAAA,GAAM,CAAC,CAAC,CAAC,CAAA;AACjD,MAAA,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IAC1B;AACA,IAAA;AACE,MAAA,IAAI,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,IAAI,EAAA,GAAK,CAAC,CAAC,CAAA,EAAG,IAAI,MAAA,CAAO,CAAA,GAAI,EAAA,GAAK,CAAC,CAAC,CAAC,CAAA;AAC7D,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,GAAA,GAAM,CAAC,CAAA,EAAG,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,GAAA,GAAM,CAAC,CAAC,CAAA;AACrD,MAAA,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,MAAM,CAAC,CAAC,CAAA,EAAG,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,GAAA,GAAM,CAAC,CAAC,CAAC,CAAA;AACjD,MAAA,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IAC1B;AACA,IAAA,CAAA,GAAI,CAAA;AACJ,IAAA,EAAA,GAAK,GAAA,CAAI,KAAK,CAAC,CAAA;AACf,IAAA,EAAA,GAAK,GAAA,CAAI,KAAK,CAAC,CAAA;AACf,IAAA,IAAA,GAAO,GAAA,CAAI,KAAK,CAAC,CAAA;AACjB,IAAA,IAAA,GAAO,GAAA,CAAI,KAAK,CAAC,CAAA;AAAA,EACnB;AAEA,EAAA,OAAO,IAAI,CAAA,GAAI,IAAA,CAAK,MAAM,CAAA,GAAI,CAAC,GAAG,CAAA,EAAA,EAAK;AACrC,IAAA;AACE,MAAA,IAAI,CAAA,GAAI,IAAA;AAAA,QACN,GAAA,CAAI,MAAA,CAAO,CAAA,GAAI,EAAA,GAAK,IAAI,IAAI,CAAA;AAAA,QAC5B,GAAA,CAAI,MAAA,CAAO,CAAA,GAAI,EAAA,GAAK,IAAI,IAAI;AAAA,OAC9B;AACA,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,GAAA,GAAM,CAAC,CAAA,EAAG,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,GAAA,GAAM,CAAC,CAAC,CAAA;AACrD,MAAA,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,MAAM,CAAC,CAAC,CAAA,EAAG,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,GAAA,GAAM,CAAC,CAAC,CAAC,CAAA;AACjD,MAAA,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IAC1B;AACA,IAAA;AACE,MAAA,IAAI,CAAA,GAAI,IAAA;AAAA,QACN,IAAI,MAAA,CAAO,CAAA,GAAI,EAAA,GAAK,CAAC,IAAI,IAAI,CAAA;AAAA,QAC7B,IAAI,MAAA,CAAO,CAAA,GAAI,EAAA,GAAK,CAAC,IAAI,IAAI;AAAA,OAC/B;AACA,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,GAAA,GAAM,CAAC,CAAA,EAAG,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,GAAA,GAAM,CAAC,CAAC,CAAA;AACrD,MAAA,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,MAAM,CAAC,CAAC,CAAA,EAAG,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,GAAA,GAAM,CAAC,CAAC,CAAC,CAAA;AACjD,MAAA,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IAC1B;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT;ACpEiC,QAAA,CAAS;AAEnC,SAAS,YAAY,IAAA,EAAmB;AAC7C,EAAA,MAAM,MAAgB,EAAC;AACvB,EAAA,KAAA,MAAW,CAAA,IAAK,aAAA,CAAc,IAAI,CAAA,EAAG;AACnC,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG,CAAA,CAAE,CAAA,EAAG,GAAG,CAAA,CAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA;AAAA,EACnC;AACA,EAAA,OAAO,GAAA;AACT;AAkDO,SAAS,WAAA,CAAY,OAAa,IAAA,EAAqB;AAC5D,EAAA,MAAM,MAAA,GAAS,eAAA;AAAA,IACb,EAAE,GAAG,KAAA,CAAM,CAAA,EAAG,GAAG,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA,EAAE;AAAA,IAC/B,YAAY,IAAI;AAAA,GAClB;AACA,EAAA,OACE,MAAA,KAAW,oBAAA,CAAqB,QAAA,IAChC,MAAA,KAAW,oBAAA,CAAqB,IAAA;AAEpC;;;ACnBO,SAAS,aAAA,CAAc,GAAS,KAAA,EAAsB;AAC3D,EAAA,IAAI,CAAC,EAAE,MAAA,IAAU,CAAC,EAAE,KAAA,CAAM,CAAC,GAAG,OAAO,KAAA;AACrC,EAAA,IAAI,CAAC,YAAY,KAAA,EAAO,CAAA,CAAE,MAAM,CAAC,CAAC,GAAG,OAAO,KAAA;AAC5C,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACvC,IAAA,MAAM,IAAA,GAAO,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA;AACtB,IAAA,IAAI,IAAA,IAAQ,WAAA,CAAY,KAAA,EAAO,IAAI,GAAG,OAAO,KAAA;AAAA,EAC/C;AACA,EAAA,OAAO,IAAA;AACT;;;AC/DO,SAAS,iBAAA,CAAkB,KAAc,IAAA,EAAuB;AACrE,EAAA,IAAI,CAAC,KAAK,MAAA,IAAU,CAAC,KAAK,KAAA,CAAM,CAAC,CAAA,EAAG,OAAO,EAAC;AAE5C,EAAA,MAAM,OAAc,EAAC;AACrB,EAAA,MAAM,OAAA,GAAU,CAAC,CAAA,EAAW,CAAA,KAAY;AACtC,IAAA,IAAI,CAAA,GAAI,KAAA,IAAS,CAAA,GAAI,CAAA,GAAI,IAAA,EAAM;AAC/B,IAAA,MAAM,EAAA,GAAK,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,CAAC,CAAC,CAAA;AACrC,IAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,MAAA,IAAI,KAAK,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,EAAE,IAAI,IAAA,EAAM;AAAA,IACjC;AACA,IAAA,IAAA,CAAK,IAAA,CAAK,EAAE,CAAA,EAAG,EAAA,EAAI,GAAG,CAAA;AAAA,EACxB,CAAA;AAEA,EAAA,IAAI,aAAA,CAAc,MAAM,GAAA,CAAI,CAAC,GAAG,OAAA,CAAQ,CAAA,EAAG,IAAI,CAAC,CAAA;AAChD,EAAA,IAAI,aAAA,CAAc,MAAM,GAAA,CAAI,CAAC,GAAG,OAAA,CAAQ,CAAA,EAAG,IAAI,CAAC,CAAA;AAEhD,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,KAAA,EAAO;AAC7B,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACpC,MAAA,MAAM,EAAA,GAAK,KAAK,CAAC,CAAA;AACjB,MAAA,MAAM,EAAA,GAAK,IAAA,CAAA,CAAM,CAAA,GAAI,CAAA,IAAK,KAAK,MAAM,CAAA;AACrC,MAAA,MAAM,MAAM,mBAAA,CAAoB,GAAA,CAAI,GAAG,GAAA,CAAI,CAAA,EAAG,IAAI,EAAE,CAAA;AACpD,MAAA,IAAI,GAAA,EAAK,OAAA,CAAQ,GAAA,CAAI,CAAA,EAAG,IAAI,CAAC,CAAA;AAAA,IAC/B;AAAA,EACF;AAEA,EAAA,IAAA,CAAK,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,CAAA,GAAI,EAAE,CAAC,CAAA;AAC7B,EAAA,IAAI,IAAA,CAAK,MAAA,GAAS,CAAA,EAAG,OAAO,EAAC;AAE7B,EAAA,MAAM,MAAiB,EAAC;AACxB,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACxC,IAAA,MAAM,EAAA,GAAK,KAAK,CAAC,CAAA;AACjB,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,CAAA,GAAI,CAAC,CAAA;AACrB,IAAA,IAAI,EAAA,CAAG,CAAA,GAAI,EAAA,CAAG,CAAA,GAAI,IAAA,EAAM;AACxB,IAAA,MAAM,GAAA,GAAM,IAAA,CAAA,CAAM,EAAA,CAAG,CAAA,CAAE,IAAI,EAAA,CAAG,CAAA,CAAE,CAAA,IAAK,CAAA,EAAA,CAAI,GAAG,CAAA,CAAE,CAAA,GAAI,EAAA,CAAG,CAAA,CAAE,KAAK,CAAC,CAAA;AAC7D,IAAA,IAAI,aAAA,CAAc,IAAA,EAAM,GAAG,CAAA,EAAG;AAC5B,MAAA,GAAA,CAAI,KAAK,OAAA,CAAQ,EAAA,CAAG,CAAA,EAAG,EAAA,CAAG,CAAC,CAAC,CAAA;AAAA,IAC9B;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,kBAAA,CACd,UACA,IAAA,EACW;AACX,EAAA,MAAM,MAAiB,EAAC;AACxB,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,GAAA,CAAI,IAAA,CAAK,GAAG,iBAAA,CAAkB,CAAA,EAAG,IAAI,CAAC,CAAA;AAAA,EACxC;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,mBAAA,CACP,CAAA,EACA,CAAA,EACA,CAAA,EACA,CAAA,EAC+B;AAC/B,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,EAAA,GAAK,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA;AACnB,EAAA,MAAM,EAAA,GAAK,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA;AACnB,EAAA,MAAM,KAAA,GAAQ,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,EAAA;AAC7B,EAAA,IAAI,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,GAAI,OAAO,OAAO,IAAA;AACpC,EAAA,MAAM,CAAA,GAAA,CAAA,CAAM,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA,IAAK,MAAM,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA,IAAK,EAAA,IAAM,KAAA;AAClD,EAAA,MAAM,CAAA,GAAA,CAAA,CAAM,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA,IAAK,MAAM,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA,IAAK,EAAA,IAAM,KAAA;AAClD,EAAA,IAAI,CAAA,GAAI,KAAA,IAAS,CAAA,GAAI,CAAA,GAAI,IAAA,IAAQ,IAAI,KAAA,IAAS,CAAA,GAAI,CAAA,GAAI,IAAA,EAAM,OAAO,IAAA;AACnE,EAAA,OAAO;AAAA,IACL,CAAA;AAAA,IACA,CAAA,EAAG,KAAK,CAAA,CAAE,CAAA,GAAI,IAAI,EAAA,EAAI,CAAA,CAAE,CAAA,GAAI,CAAA,GAAI,EAAE;AAAA,GACpC;AACF;;;ACnDO,SAAS,QAAA,CAASA,KAAAA,EAAY,OAAA,GAAgC,EAAC,EAAc;AAClF,EAAA,IAAI,CAACA,KAAAA,CAAK,MAAA,IAAU,CAACA,KAAAA,CAAK,KAAA,CAAM,CAAC,CAAA,EAAG;AAClC,IAAA,MAAM,IAAI,MAAM,uCAAuC,CAAA;AAAA,EACzD;AAEA,EAAA,MAAM,MAAA,GAAS,WAAWA,KAAI,CAAA;AAC9B,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU;AAAA,IAC/B,CAAA,EAAA,CAAI,MAAA,CAAO,IAAA,GAAO,MAAA,CAAO,IAAA,IAAQ,CAAA;AAAA,IACjC,CAAA,EAAA,CAAI,MAAA,CAAO,IAAA,GAAO,MAAA,CAAO,IAAA,IAAQ;AAAA,GACnC;AACA,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,IAAA,GAAO,OAAO,IAAA,EAAM,MAAA,CAAO,IAAA,GAAO,MAAA,CAAO,IAAI,CAAA;AAC5E,EAAA,MAAM,SAAS,OAAA,CAAQ,MAAA,IAAU,IAAA,CAAK,GAAA,CAAI,MAAM,IAAI,CAAA;AACpD,EAAA,MAAM,UAAU,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,OAAA,IAAW,MAAM,IAAI,CAAA;AACtD,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,IAAS,IAAA,CAAK,EAAA,GAAK,CAAA;AACzC,EAAA,MAAM,QAAQ,OAAA,CAAQ,KAAA,IAAS,cAAA,CAAe,MAAA,EAAQ,SAAS,KAAK,CAAA;AAEpE,EAAA,MAAM,GAAA,GAAM,gBAAA;AAAA,IACV,MAAA,CAAO,CAAA;AAAA,IACP,MAAA,CAAO,CAAA;AAAA,IACP,MAAA;AAAA,IACA,OAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,OAAO,kBAAA,CAAmB,KAAKA,KAAI,CAAA;AACrC;AAGO,SAAS,KAAA,CAAMA,KAAAA,EAAY,OAAA,GAAgC,EAAC,EAAc;AAC/E,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,IAAS,IAAA,CAAK,EAAA,GAAK,CAAA;AACzC,EAAA,MAAM,CAAA,GAAI,QAAA,CAASA,KAAAA,EAAM,OAAO,CAAA;AAChC,EAAA,MAAM,CAAA,GAAI,QAAA,CAASA,KAAAA,EAAM,EAAE,GAAG,OAAA,EAAS,KAAA,EAAO,KAAA,GAAQ,IAAA,CAAK,EAAA,GAAK,CAAA,EAAG,CAAA;AACnE,EAAA,OAAO,CAAC,GAAG,CAAA,EAAG,GAAG,CAAC,CAAA;AACpB;AAGA,SAAS,cAAA,CACP,MAAA,EACA,OAAA,EACA,KAAA,EACQ;AACR,EAAA,MAAM,KAAK,IAAA,CAAK,GAAA,CAAI,KAAA,GAAQ,IAAA,CAAK,KAAK,CAAC,CAAA;AACvC,EAAA,MAAM,KAAK,IAAA,CAAK,GAAA,CAAI,KAAA,GAAQ,IAAA,CAAK,KAAK,CAAC,CAAA;AACvC,EAAA,MAAM,OAAA,GAA8B;AAAA,IAClC,CAAC,MAAA,CAAO,IAAA,EAAM,MAAA,CAAO,IAAI,CAAA;AAAA,IACzB,CAAC,MAAA,CAAO,IAAA,EAAM,MAAA,CAAO,IAAI,CAAA;AAAA,IACzB,CAAC,MAAA,CAAO,IAAA,EAAM,MAAA,CAAO,IAAI,CAAA;AAAA,IACzB,CAAC,MAAA,CAAO,IAAA,EAAM,MAAA,CAAO,IAAI;AAAA,GAC3B;AACA,EAAA,IAAI,IAAA,GAAO,QAAA;AACX,EAAA,IAAI,IAAA,GAAO,CAAA,QAAA;AACX,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,CAAA,IAAK,OAAA,EAAS;AAC5B,IAAA,MAAM,CAAA,GAAI,CAAA,GAAI,EAAA,GAAK,CAAA,GAAI,EAAA;AACvB,IAAA,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,CAAC,CAAA;AACvB,IAAA,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,CAAC,CAAA;AAAA,EACzB;AACA,EAAA,MAAM,SAAS,IAAA,GAAO,IAAA;AACtB,EAAA,OAAO,IAAA,CAAK,IAAI,CAAA,EAAG,IAAA,CAAK,KAAK,MAAA,GAAS,OAAO,IAAI,CAAC,CAAA;AACpD;AAEA,SAAS,WAAWA,KAAAA,EAAY;AAC9B,EAAA,IAAI,IAAA,GAAO,QAAA;AACX,EAAA,IAAI,IAAA,GAAO,QAAA;AACX,EAAA,IAAI,IAAA,GAAO,CAAA,QAAA;AACX,EAAA,IAAI,IAAA,GAAO,CAAA,QAAA;AACX,EAAA,KAAA,MAAW,IAAA,IAAQA,MAAK,KAAA,EAAO;AAC7B,IAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,MAAA,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,CAAA,CAAE,CAAC,CAAA;AACzB,MAAA,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,CAAA,CAAE,CAAC,CAAA;AACzB,MAAA,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,CAAA,CAAE,CAAC,CAAA;AACzB,MAAA,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,CAAA,CAAE,CAAC,CAAA;AAAA,IAC3B;AAAA,EACF;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,IAAA,EAAK;AAClC;AAEO,IAAM,KAAA,GAAQ;AAAA,EACnB,QAAA;AAAA,EACA;AACF","file":"index.js","sourcesContent":["/** 2D point / vector. */\nexport type Vec2 = {\n x: number\n y: number\n}\n\nexport function vec2(x: number, y: number): Vec2 {\n return { x, y }\n}\n\nexport function cloneVec2(v: Vec2): Vec2 {\n return { x: v.x, y: v.y }\n}\n\nexport function equalsVec2(a: Vec2, b: Vec2, eps = 1e-9): boolean {\n return Math.abs(a.x - b.x) <= eps && Math.abs(a.y - b.y) <= eps\n}\n","import type { Vec2 } from './vec2.js'\n\n/** Line segment between two points. */\nexport type Segment = {\n a: Vec2\n b: Vec2\n}\n\nexport function segment(a: Vec2, b: Vec2): Segment {\n return { a, b }\n}\n","import type { Vec2 } from './vec2.js'\nimport { cloneVec2, equalsVec2 } from './vec2.js'\n\n/** Ordered ring of vertices (typically without repeating the closing vertex). */\nexport type Ring = Vec2[]\n\n/**\n * A path: one exterior ring plus optional holes, or an open polyline.\n * `rings[0]` is the exterior (or the open polyline when `closed` is false).\n * Additional rings are holes (only meaningful when `closed` is true).\n */\nexport type Path = {\n rings: Ring[]\n closed: boolean\n}\n\nexport function path(rings: Ring[], closed = true): Path {\n return {\n rings: rings.map((ring) => ring.map(cloneVec2)),\n closed,\n }\n}\n\nexport function polyline(points: Ring): Path {\n return path([points], false)\n}\n\nexport function polygon(exterior: Ring, holes: Ring[] = []): Path {\n return path([exterior, ...holes], true)\n}\n\n/** Drop a trailing vertex that duplicates the first (SVG often closes this way). */\nexport function normalizeRing(ring: Ring, eps = 1e-9): Ring {\n if (ring.length < 2) return ring.map(cloneVec2)\n const first = ring[0]\n const last = ring[ring.length - 1]\n if (first && last && equalsVec2(first, last, eps)) {\n return ring.slice(0, -1).map(cloneVec2)\n }\n return ring.map(cloneVec2)\n}\n\nexport function clonePath(p: Path): Path {\n return {\n closed: p.closed,\n rings: p.rings.map((ring) => ring.map(cloneVec2)),\n }\n}\n","import type { Segment, Vec2 } from '../types/index.js'\nimport { segment, vec2 } from '../types/index.js'\n\n/** Match Processing `float` for PGS parity on hatch fixtures. */\nfunction f32(n: number): number {\n return Math.fround(n)\n}\n\n/**\n * Parallel segments through a center point (PGS `parallelSegments` semantics).\n * `length` is the half-length along the segment direction; full span is `2 * length`.\n * `angle` is radians along the segment; spacing is perpendicular.\n */\nexport function parallelSegments(\n centerX: number,\n centerY: number,\n length: number,\n spacing: number,\n angle: number,\n n: number,\n): Segment[] {\n const edges: Segment[] = []\n if (n < 1) return edges\n\n const center = vec2(f32(centerX), f32(centerY))\n let dx = f32(Math.cos(angle + Math.PI / 2) * spacing)\n let dy = f32(Math.sin(angle + Math.PI / 2) * spacing)\n const cos = f32(Math.cos(angle))\n const sin = f32(Math.sin(angle))\n const l = f32(length)\n\n let i: number\n let offX = 0\n let offY = 0\n\n if (n % 2 === 1) {\n const a = vec2(f32(center.x + cos * l), f32(center.y + sin * l))\n const b = vec2(f32(center.x + cos * -l), f32(center.y + sin * -l))\n edges.push(segment(a, b))\n i = 1\n } else {\n dx = f32(dx / 2)\n dy = f32(dy / 2)\n i = 1\n {\n let a = vec2(f32(center.x + dx * i), f32(center.y + dy * i))\n const b = vec2(f32(a.x + cos * l), f32(a.y + sin * l))\n a = vec2(f32(a.x + cos * -l), f32(a.y + sin * -l))\n edges.push(segment(a, b))\n }\n {\n let a = vec2(f32(center.x + dx * -i), f32(center.y + dy * -i))\n const b = vec2(f32(a.x + cos * l), f32(a.y + sin * l))\n a = vec2(f32(a.x + cos * -l), f32(a.y + sin * -l))\n edges.push(segment(a, b))\n }\n i = 2\n dx = f32(dx * 2)\n dy = f32(dy * 2)\n offX = f32(dx / 2)\n offY = f32(dy / 2)\n }\n\n for (; i < 1 + Math.floor(n / 2); i++) {\n {\n let a = vec2(\n f32(center.x + dx * i - offX),\n f32(center.y + dy * i - offY),\n )\n const b = vec2(f32(a.x + cos * l), f32(a.y + sin * l))\n a = vec2(f32(a.x + cos * -l), f32(a.y + sin * -l))\n edges.push(segment(a, b))\n }\n {\n let a = vec2(\n f32(center.x + dx * -i + offX),\n f32(center.y + dy * -i + offY),\n )\n const b = vec2(f32(a.x + cos * l), f32(a.y + sin * l))\n a = vec2(f32(a.x + cos * -l), f32(a.y + sin * -l))\n edges.push(segment(a, b))\n }\n }\n\n return edges\n}\n\nexport function filterByMinLength(\n segments: Segment[],\n minLength: number,\n): Segment[] {\n return segments.filter((s) => segmentLength(s) >= minLength)\n}\n\nexport function filterAxisAligned(\n segments: Segment[],\n angleDelta: number,\n): Segment[] {\n return segments.filter((s) => {\n const ang = Math.abs(Math.atan2(s.b.y - s.a.y, s.b.x - s.a.x))\n const norm = Math.min(ang % Math.PI, Math.PI - (ang % Math.PI))\n const nearH = norm <= angleDelta || Math.abs(norm - Math.PI) <= angleDelta\n const nearV = Math.abs(norm - Math.PI / 2) <= angleDelta\n return !(nearH || nearV)\n })\n}\n\nexport function segmentLength(s: Segment): number {\n const dx = s.b.x - s.a.x\n const dy = s.b.y - s.a.y\n return Math.hypot(dx, dy)\n}\n\nexport function segmentsToOpenPaths(segments: Segment[]) {\n return segments.map((s) => ({\n rings: [[s.a, s.b]],\n closed: false as const,\n }))\n}\n\nexport const segmentSet = {\n parallelSegments,\n filterByMinLength,\n filterAxisAligned,\n segmentLength,\n segmentsToOpenPaths,\n}\n\nexport type { Vec2 }\n","import {\n FillRule,\n areaD,\n differenceD,\n intersectD,\n isPositiveD,\n pointInPolygonD,\n PointInPolygonResult,\n unionD,\n xorD,\n type PathD,\n type PathsD,\n type PointD,\n} from 'clipper2-ts'\nimport type { Group, Path, Ring, Vec2 } from '../types/index.js'\nimport { group, normalizeRing, path, vec2 } from '../types/index.js'\n\nexport const DEFAULT_FILL_RULE = FillRule.NonZero\n\nexport function ringToPathD(ring: Ring): PathD {\n const pts: PointD[] = []\n for (const v of normalizeRing(ring)) {\n pts.push({ x: v.x, y: v.y, z: 0 })\n }\n return pts\n}\n\n/** Closed path → Clipper subject/clip paths (exterior + holes). */\nexport function pathToPathsD(p: Path): PathsD {\n if (!p.closed || p.rings.length === 0) {\n throw new Error('Boolean ops require a closed path with at least one ring')\n }\n return p.rings.map((ring) => ringToPathD(ring))\n}\n\nexport function pathsDToGroup(paths: PathsD): Group {\n if (paths.length === 0) return group([])\n\n const outers: { ring: Ring; holes: Ring[] }[] = []\n const holes: Ring[] = []\n\n for (const pd of paths) {\n const ring = pathDToRing(pd)\n if (ring.length < 3) continue\n if (isPositiveD(pd)) {\n outers.push({ ring, holes: [] })\n } else {\n holes.push(ring)\n }\n }\n\n for (const hole of holes) {\n const sample = hole[0]\n if (!sample) continue\n let assigned = false\n for (const outer of outers) {\n if (pointInRing(sample, outer.ring)) {\n outer.holes.push(hole)\n assigned = true\n break\n }\n }\n if (!assigned) {\n // Treat unmatched negative rings as their own outers (orientation flip).\n outers.push({ ring: [...hole].reverse(), holes: [] })\n }\n }\n\n return group(outers.map((o) => path([o.ring, ...o.holes], true)))\n}\n\nexport function pathDToRing(pd: PathD): Ring {\n return normalizeRing(pd.map((p) => vec2(p.x, p.y)))\n}\n\nexport function pointInRing(point: Vec2, ring: Ring): boolean {\n const result = pointInPolygonD(\n { x: point.x, y: point.y, z: 0 },\n ringToPathD(ring),\n )\n return (\n result === PointInPolygonResult.IsInside ||\n result === PointInPolygonResult.IsOn\n )\n}\n\nexport function clipUnion(a: PathsD, b: PathsD): PathsD {\n return unionD(a, b, DEFAULT_FILL_RULE)\n}\n\nexport function clipIntersect(a: PathsD, b: PathsD): PathsD {\n return intersectD(a, b, DEFAULT_FILL_RULE)\n}\n\nexport function clipDifference(a: PathsD, b: PathsD): PathsD {\n return differenceD(a, b, DEFAULT_FILL_RULE)\n}\n\nexport function clipXor(a: PathsD, b: PathsD): PathsD {\n return xorD(a, b, DEFAULT_FILL_RULE)\n}\n\nexport function pathsArea(paths: PathsD): number {\n let sum = 0\n for (const p of paths) {\n sum += Math.abs(areaD(p))\n }\n return sum\n}\n","import type { Group, Path, Vec2 } from '../types/index.js'\nimport { vec2 } from '../types/index.js'\nimport {\n pathToPathsD,\n pathsArea,\n pointInRing,\n} from '../clipper/convert.js'\n\n/** Signed area of a closed ring (shoelace). */\nexport function ringArea(ring: Vec2[]): number {\n if (ring.length < 3) return 0\n let sum = 0\n for (let i = 0; i < ring.length; i++) {\n const a = ring[i]!\n const b = ring[(i + 1) % ring.length]!\n sum += a.x * b.y - b.x * a.y\n }\n return sum / 2\n}\n\n/** Absolute area of a closed path (exterior minus holes). */\nexport function area(p: Path): number {\n if (!p.closed || p.rings.length === 0) return 0\n try {\n return pathsArea(pathToPathsD(p))\n } catch {\n let total = 0\n for (let i = 0; i < p.rings.length; i++) {\n const a = Math.abs(ringArea(p.rings[i]!))\n total += i === 0 ? a : -a\n }\n return Math.max(0, total)\n }\n}\n\nexport function areaGroup(g: Group): number {\n return g.paths.reduce((sum, p) => sum + area(p), 0)\n}\n\n/** Centroid of a closed exterior ring (ignores holes for Phase 2). */\nexport function centroid(p: Path): Vec2 {\n const ring = p.rings[0]\n if (!ring || ring.length === 0) return vec2(0, 0)\n const a = ringArea(ring)\n if (Math.abs(a) < 1e-12) {\n let sx = 0\n let sy = 0\n for (const v of ring) {\n sx += v.x\n sy += v.y\n }\n return vec2(sx / ring.length, sy / ring.length)\n }\n let cx = 0\n let cy = 0\n for (let i = 0; i < ring.length; i++) {\n const p0 = ring[i]!\n const p1 = ring[(i + 1) % ring.length]!\n const cross = p0.x * p1.y - p1.x * p0.y\n cx += (p0.x + p1.x) * cross\n cy += (p0.y + p1.y) * cross\n }\n return vec2(cx / (6 * a), cy / (6 * a))\n}\n\nexport function containsPoint(p: Path, point: Vec2): boolean {\n if (!p.closed || !p.rings[0]) return false\n if (!pointInRing(point, p.rings[0])) return false\n for (let i = 1; i < p.rings.length; i++) {\n const hole = p.rings[i]\n if (hole && pointInRing(point, hole)) return false\n }\n return true\n}\n\nexport function bounds(p: Path): {\n minX: number\n minY: number\n maxX: number\n maxY: number\n} {\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (const ring of p.rings) {\n for (const v of ring) {\n minX = Math.min(minX, v.x)\n minY = Math.min(minY, v.y)\n maxX = Math.max(maxX, v.x)\n maxY = Math.max(maxY, v.y)\n }\n }\n if (!Number.isFinite(minX)) {\n return { minX: 0, minY: 0, maxX: 0, maxY: 0 }\n }\n return { minX, minY, maxX, maxY }\n}\n\nexport function width(p: Path): number {\n const b = bounds(p)\n return b.maxX - b.minX\n}\n\nexport function height(p: Path): number {\n const b = bounds(p)\n return b.maxY - b.minY\n}\n\n/** Rough polygon similarity via absolute area difference relative to max area. */\nexport function areaSimilarity(a: Path, b: Path): number {\n const aa = area(a)\n const bb = area(b)\n const denom = Math.max(aa, bb, 1e-12)\n return 1 - Math.abs(aa - bb) / denom\n}\n\nexport const predicates = {\n area,\n areaGroup,\n ringArea,\n centroid,\n containsPoint,\n bounds,\n width,\n height,\n areaSimilarity,\n}\n","import type { Path, Ring, Segment, Vec2 } from '../types/index.js'\nimport { segment, vec2 } from '../types/index.js'\nimport { containsPoint } from '../predicates/index.js'\n\ntype Hit = { t: number; p: Vec2 }\n\n/**\n * Clip an open segment to the interior of a closed path (exterior minus holes).\n * Returns zero or more interior sub-segments.\n */\nexport function clipSegmentToPath(seg: Segment, clip: Path): Segment[] {\n if (!clip.closed || !clip.rings[0]) return []\n\n const hits: Hit[] = []\n const pushHit = (t: number, p: Vec2) => {\n if (t < -1e-9 || t > 1 + 1e-9) return\n const tt = Math.min(1, Math.max(0, t))\n for (const h of hits) {\n if (Math.abs(h.t - tt) < 1e-9) return\n }\n hits.push({ t: tt, p })\n }\n\n if (containsPoint(clip, seg.a)) pushHit(0, seg.a)\n if (containsPoint(clip, seg.b)) pushHit(1, seg.b)\n\n for (const ring of clip.rings) {\n for (let i = 0; i < ring.length; i++) {\n const e0 = ring[i]!\n const e1 = ring[(i + 1) % ring.length]!\n const hit = segmentIntersection(seg.a, seg.b, e0, e1)\n if (hit) pushHit(hit.t, hit.p)\n }\n }\n\n hits.sort((a, b) => a.t - b.t)\n if (hits.length < 2) return []\n\n const out: Segment[] = []\n for (let i = 0; i + 1 < hits.length; i++) {\n const h0 = hits[i]!\n const h1 = hits[i + 1]!\n if (h1.t - h0.t < 1e-9) continue\n const mid = vec2((h0.p.x + h1.p.x) / 2, (h0.p.y + h1.p.y) / 2)\n if (containsPoint(clip, mid)) {\n out.push(segment(h0.p, h1.p))\n }\n }\n return out\n}\n\nexport function clipSegmentsToPath(\n segments: Segment[],\n clip: Path,\n): Segment[] {\n const out: Segment[] = []\n for (const s of segments) {\n out.push(...clipSegmentToPath(s, clip))\n }\n return out\n}\n\nfunction segmentIntersection(\n a: Vec2,\n b: Vec2,\n c: Vec2,\n d: Vec2,\n): { t: number; p: Vec2 } | null {\n const rX = b.x - a.x\n const rY = b.y - a.y\n const sX = d.x - c.x\n const sY = d.y - c.y\n const denom = rX * sY - rY * sX\n if (Math.abs(denom) < 1e-12) return null\n const t = ((c.x - a.x) * sY - (c.y - a.y) * sX) / denom\n const u = ((c.x - a.x) * rY - (c.y - a.y) * rX) / denom\n if (t < -1e-9 || t > 1 + 1e-9 || u < -1e-9 || u > 1 + 1e-9) return null\n return {\n t,\n p: vec2(a.x + t * rX, a.y + t * rY),\n }\n}\n\n/** @internal exported for tests */\nexport type { Ring }\n","import type { Path, Segment } from '../types/index.js'\nimport { parallelSegments } from '../segmentSet/index.js'\nimport { clipSegmentsToPath } from '../segmentSet/clip.js'\n\nexport type ParallelHatchOptions = {\n /** Hatch angle in radians (segment direction). Default `Math.PI / 4`. */\n angle?: number\n /** Perpendicular spacing between lines. Default `0.15`. */\n spacing?: number\n /**\n * Half-length of generated lines before clipping (PGS `length`).\n * Default: diagonal of path bounds.\n */\n length?: number\n /**\n * Number of parallel lines (PGS `n`).\n * Default: enough lines to cover the path AABB at the given spacing.\n */\n count?: number\n /** Hatch field center. Default: path centroid of exterior bounds center. */\n center?: { x: number; y: number }\n}\n\n/**\n * Fill a closed path with parallel hatch strokes (plotter-safe).\n * Composes `parallelSegments` + clip-to-path (PGS dysonHatching recipe).\n *\n * When `count` is omitted, line count is derived from `spacing` and the path\n * bounds so the hatch covers the whole region (no corner gaps).\n */\nexport function parallel(path: Path, options: ParallelHatchOptions = {}): Segment[] {\n if (!path.closed || !path.rings[0]) {\n throw new Error('hatch.parallel requires a closed path')\n }\n\n const bounds = pathBounds(path)\n const center = options.center ?? {\n x: (bounds.minX + bounds.maxX) / 2,\n y: (bounds.minY + bounds.maxY) / 2,\n }\n const diag = Math.hypot(bounds.maxX - bounds.minX, bounds.maxY - bounds.minY)\n const length = options.length ?? Math.max(diag, 1e-6)\n const spacing = Math.max(options.spacing ?? 0.15, 1e-9)\n const angle = options.angle ?? Math.PI / 4\n const count = options.count ?? hatchLineCount(bounds, spacing, angle)\n\n const raw = parallelSegments(\n center.x,\n center.y,\n length,\n spacing,\n angle,\n count,\n )\n return clipSegmentsToPath(raw, path)\n}\n\n/** Cross-hatch: two perpendicular parallel passes. */\nexport function cross(path: Path, options: ParallelHatchOptions = {}): Segment[] {\n const angle = options.angle ?? Math.PI / 4\n const a = parallel(path, options)\n const b = parallel(path, { ...options, angle: angle + Math.PI / 2 })\n return [...a, ...b]\n}\n\n/** Lines needed so perpendicular spacing covers the AABB at `angle`. */\nfunction hatchLineCount(\n bounds: { minX: number; minY: number; maxX: number; maxY: number },\n spacing: number,\n angle: number,\n): number {\n const nx = Math.cos(angle + Math.PI / 2)\n const ny = Math.sin(angle + Math.PI / 2)\n const corners: [number, number][] = [\n [bounds.minX, bounds.minY],\n [bounds.maxX, bounds.minY],\n [bounds.maxX, bounds.maxY],\n [bounds.minX, bounds.maxY],\n ]\n let minP = Infinity\n let maxP = -Infinity\n for (const [x, y] of corners) {\n const p = x * nx + y * ny\n minP = Math.min(minP, p)\n maxP = Math.max(maxP, p)\n }\n const extent = maxP - minP\n return Math.max(1, Math.ceil(extent / spacing) + 1)\n}\n\nfunction pathBounds(path: Path) {\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (const ring of path.rings) {\n for (const v of ring) {\n minX = Math.min(minX, v.x)\n minY = Math.min(minY, v.y)\n maxX = Math.max(maxX, v.x)\n maxY = Math.max(maxY, v.y)\n }\n }\n return { minX, minY, maxX, maxY }\n}\n\nexport const hatch = {\n parallel,\n cross,\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { V as Vec2 } from '../vec2-CWyXN1Wj.js';
2
+ import { P as Path } from '../path-0RjhYjJs.js';
3
+
4
+ /** Andrew's monotone-chain convex hull of a point set. */
5
+ declare function convexHull(points: Vec2[]): Path;
6
+ /** Convex hull of all vertices in a path (exterior + holes). */
7
+ declare function convexHullPath(p: Path): Path;
8
+ /** Axis-aligned bounding box of a path as a closed rectangle. */
9
+ declare function boundingBox(p: Path): Path;
10
+ declare const hull: {
11
+ convexHull: typeof convexHull;
12
+ convexHullPath: typeof convexHullPath;
13
+ boundingBox: typeof boundingBox;
14
+ };
15
+
16
+ export { boundingBox, convexHull, convexHullPath, hull };
@@ -0,0 +1,97 @@
1
+ // src/types/vec2.ts
2
+ function cloneVec2(v) {
3
+ return { x: v.x, y: v.y };
4
+ }
5
+
6
+ // src/types/path.ts
7
+ function path(rings, closed = true) {
8
+ return {
9
+ rings: rings.map((ring) => ring.map(cloneVec2)),
10
+ closed
11
+ };
12
+ }
13
+ function polygon(exterior, holes = []) {
14
+ return path([exterior, ...holes], true);
15
+ }
16
+
17
+ // src/predicates/index.ts
18
+ function bounds(p) {
19
+ let minX = Infinity;
20
+ let minY = Infinity;
21
+ let maxX = -Infinity;
22
+ let maxY = -Infinity;
23
+ for (const ring of p.rings) {
24
+ for (const v of ring) {
25
+ minX = Math.min(minX, v.x);
26
+ minY = Math.min(minY, v.y);
27
+ maxX = Math.max(maxX, v.x);
28
+ maxY = Math.max(maxY, v.y);
29
+ }
30
+ }
31
+ if (!Number.isFinite(minX)) {
32
+ return { minX: 0, minY: 0, maxX: 0, maxY: 0 };
33
+ }
34
+ return { minX, minY, maxX, maxY };
35
+ }
36
+
37
+ // src/hull/index.ts
38
+ function convexHull(points) {
39
+ const pts = uniquePoints(points);
40
+ if (pts.length < 3) return polygon(pts);
41
+ pts.sort((a, b) => a.x === b.x ? a.y - b.y : a.x - b.x);
42
+ const lower = [];
43
+ for (const p of pts) {
44
+ while (lower.length >= 2 && cross(lower[lower.length - 2], lower[lower.length - 1], p) <= 0) {
45
+ lower.pop();
46
+ }
47
+ lower.push(p);
48
+ }
49
+ const upper = [];
50
+ for (let i = pts.length - 1; i >= 0; i--) {
51
+ const p = pts[i];
52
+ while (upper.length >= 2 && cross(upper[upper.length - 2], upper[upper.length - 1], p) <= 0) {
53
+ upper.pop();
54
+ }
55
+ upper.push(p);
56
+ }
57
+ lower.pop();
58
+ upper.pop();
59
+ return polygon([...lower, ...upper]);
60
+ }
61
+ function convexHullPath(p) {
62
+ const pts = [];
63
+ for (const ring of p.rings) pts.push(...ring);
64
+ return convexHull(pts);
65
+ }
66
+ function boundingBox(p) {
67
+ const b = bounds(p);
68
+ return polygon([
69
+ { x: b.minX, y: b.minY },
70
+ { x: b.maxX, y: b.minY },
71
+ { x: b.maxX, y: b.maxY },
72
+ { x: b.minX, y: b.maxY }
73
+ ]);
74
+ }
75
+ function cross(o, a, b) {
76
+ return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
77
+ }
78
+ function uniquePoints(points) {
79
+ const seen = /* @__PURE__ */ new Set();
80
+ const out = [];
81
+ for (const p of points) {
82
+ const key = `${p.x},${p.y}`;
83
+ if (seen.has(key)) continue;
84
+ seen.add(key);
85
+ out.push({ x: p.x, y: p.y });
86
+ }
87
+ return out;
88
+ }
89
+ var hull = {
90
+ convexHull,
91
+ convexHullPath,
92
+ boundingBox
93
+ };
94
+
95
+ export { boundingBox, convexHull, convexHullPath, hull };
96
+ //# sourceMappingURL=index.js.map
97
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types/vec2.ts","../../src/types/path.ts","../../src/predicates/index.ts","../../src/hull/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/** 2D point / vector. */\nexport type Vec2 = {\n x: number\n y: number\n}\n\nexport function vec2(x: number, y: number): Vec2 {\n return { x, y }\n}\n\nexport function cloneVec2(v: Vec2): Vec2 {\n return { x: v.x, y: v.y }\n}\n\nexport function equalsVec2(a: Vec2, b: Vec2, eps = 1e-9): boolean {\n return Math.abs(a.x - b.x) <= eps && Math.abs(a.y - b.y) <= eps\n}\n","import type { Vec2 } from './vec2.js'\nimport { cloneVec2, equalsVec2 } from './vec2.js'\n\n/** Ordered ring of vertices (typically without repeating the closing vertex). */\nexport type Ring = Vec2[]\n\n/**\n * A path: one exterior ring plus optional holes, or an open polyline.\n * `rings[0]` is the exterior (or the open polyline when `closed` is false).\n * Additional rings are holes (only meaningful when `closed` is true).\n */\nexport type Path = {\n rings: Ring[]\n closed: boolean\n}\n\nexport function path(rings: Ring[], closed = true): Path {\n return {\n rings: rings.map((ring) => ring.map(cloneVec2)),\n closed,\n }\n}\n\nexport function polyline(points: Ring): Path {\n return path([points], false)\n}\n\nexport function polygon(exterior: Ring, holes: Ring[] = []): Path {\n return path([exterior, ...holes], true)\n}\n\n/** Drop a trailing vertex that duplicates the first (SVG often closes this way). */\nexport function normalizeRing(ring: Ring, eps = 1e-9): Ring {\n if (ring.length < 2) return ring.map(cloneVec2)\n const first = ring[0]\n const last = ring[ring.length - 1]\n if (first && last && equalsVec2(first, last, eps)) {\n return ring.slice(0, -1).map(cloneVec2)\n }\n return ring.map(cloneVec2)\n}\n\nexport function clonePath(p: Path): Path {\n return {\n closed: p.closed,\n rings: p.rings.map((ring) => ring.map(cloneVec2)),\n }\n}\n","import type { Group, Path, Vec2 } from '../types/index.js'\nimport { vec2 } from '../types/index.js'\nimport {\n pathToPathsD,\n pathsArea,\n pointInRing,\n} from '../clipper/convert.js'\n\n/** Signed area of a closed ring (shoelace). */\nexport function ringArea(ring: Vec2[]): number {\n if (ring.length < 3) return 0\n let sum = 0\n for (let i = 0; i < ring.length; i++) {\n const a = ring[i]!\n const b = ring[(i + 1) % ring.length]!\n sum += a.x * b.y - b.x * a.y\n }\n return sum / 2\n}\n\n/** Absolute area of a closed path (exterior minus holes). */\nexport function area(p: Path): number {\n if (!p.closed || p.rings.length === 0) return 0\n try {\n return pathsArea(pathToPathsD(p))\n } catch {\n let total = 0\n for (let i = 0; i < p.rings.length; i++) {\n const a = Math.abs(ringArea(p.rings[i]!))\n total += i === 0 ? a : -a\n }\n return Math.max(0, total)\n }\n}\n\nexport function areaGroup(g: Group): number {\n return g.paths.reduce((sum, p) => sum + area(p), 0)\n}\n\n/** Centroid of a closed exterior ring (ignores holes for Phase 2). */\nexport function centroid(p: Path): Vec2 {\n const ring = p.rings[0]\n if (!ring || ring.length === 0) return vec2(0, 0)\n const a = ringArea(ring)\n if (Math.abs(a) < 1e-12) {\n let sx = 0\n let sy = 0\n for (const v of ring) {\n sx += v.x\n sy += v.y\n }\n return vec2(sx / ring.length, sy / ring.length)\n }\n let cx = 0\n let cy = 0\n for (let i = 0; i < ring.length; i++) {\n const p0 = ring[i]!\n const p1 = ring[(i + 1) % ring.length]!\n const cross = p0.x * p1.y - p1.x * p0.y\n cx += (p0.x + p1.x) * cross\n cy += (p0.y + p1.y) * cross\n }\n return vec2(cx / (6 * a), cy / (6 * a))\n}\n\nexport function containsPoint(p: Path, point: Vec2): boolean {\n if (!p.closed || !p.rings[0]) return false\n if (!pointInRing(point, p.rings[0])) return false\n for (let i = 1; i < p.rings.length; i++) {\n const hole = p.rings[i]\n if (hole && pointInRing(point, hole)) return false\n }\n return true\n}\n\nexport function bounds(p: Path): {\n minX: number\n minY: number\n maxX: number\n maxY: number\n} {\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (const ring of p.rings) {\n for (const v of ring) {\n minX = Math.min(minX, v.x)\n minY = Math.min(minY, v.y)\n maxX = Math.max(maxX, v.x)\n maxY = Math.max(maxY, v.y)\n }\n }\n if (!Number.isFinite(minX)) {\n return { minX: 0, minY: 0, maxX: 0, maxY: 0 }\n }\n return { minX, minY, maxX, maxY }\n}\n\nexport function width(p: Path): number {\n const b = bounds(p)\n return b.maxX - b.minX\n}\n\nexport function height(p: Path): number {\n const b = bounds(p)\n return b.maxY - b.minY\n}\n\n/** Rough polygon similarity via absolute area difference relative to max area. */\nexport function areaSimilarity(a: Path, b: Path): number {\n const aa = area(a)\n const bb = area(b)\n const denom = Math.max(aa, bb, 1e-12)\n return 1 - Math.abs(aa - bb) / denom\n}\n\nexport const predicates = {\n area,\n areaGroup,\n ringArea,\n centroid,\n containsPoint,\n bounds,\n width,\n height,\n areaSimilarity,\n}\n","import type { Path, Vec2 } from '../types/index.js'\nimport { polygon } from '../types/index.js'\nimport { bounds } from '../predicates/index.js'\n\n/** Andrew's monotone-chain convex hull of a point set. */\nexport function convexHull(points: Vec2[]): Path {\n const pts = uniquePoints(points)\n if (pts.length < 3) return polygon(pts)\n\n pts.sort((a, b) => (a.x === b.x ? a.y - b.y : a.x - b.x))\n\n const lower: Vec2[] = []\n for (const p of pts) {\n while (\n lower.length >= 2 &&\n cross(lower[lower.length - 2]!, lower[lower.length - 1]!, p) <= 0\n ) {\n lower.pop()\n }\n lower.push(p)\n }\n\n const upper: Vec2[] = []\n for (let i = pts.length - 1; i >= 0; i--) {\n const p = pts[i]!\n while (\n upper.length >= 2 &&\n cross(upper[upper.length - 2]!, upper[upper.length - 1]!, p) <= 0\n ) {\n upper.pop()\n }\n upper.push(p)\n }\n\n lower.pop()\n upper.pop()\n return polygon([...lower, ...upper])\n}\n\n/** Convex hull of all vertices in a path (exterior + holes). */\nexport function convexHullPath(p: Path): Path {\n const pts: Vec2[] = []\n for (const ring of p.rings) pts.push(...ring)\n return convexHull(pts)\n}\n\n/** Axis-aligned bounding box of a path as a closed rectangle. */\nexport function boundingBox(p: Path): Path {\n const b = bounds(p)\n return polygon([\n { x: b.minX, y: b.minY },\n { x: b.maxX, y: b.minY },\n { x: b.maxX, y: b.maxY },\n { x: b.minX, y: b.maxY },\n ])\n}\n\nfunction cross(o: Vec2, a: Vec2, b: Vec2): number {\n return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x)\n}\n\nfunction uniquePoints(points: Vec2[]): Vec2[] {\n const seen = new Set<string>()\n const out: Vec2[] = []\n for (const p of points) {\n const key = `${p.x},${p.y}`\n if (seen.has(key)) continue\n seen.add(key)\n out.push({ x: p.x, y: p.y })\n }\n return out\n}\n\nexport const hull = {\n convexHull,\n convexHullPath,\n boundingBox,\n}\n"]}
@@ -0,0 +1,67 @@
1
+ export { V as Vec2, c as cloneVec2, e as equalsVec2, v as vec2 } from './vec2-CWyXN1Wj.js';
2
+ export { C as Circle, c as circle, a as circleCenter } from './circle-BDbKfrdR.js';
3
+ import { S as Segment } from './segment-BKuIFMKD.js';
4
+ export { s as segment } from './segment-BKuIFMKD.js';
5
+ import { P as Path } from './path-0RjhYjJs.js';
6
+ export { R as Ring, c as clonePath, n as normalizeRing, p as path, a as polygon, b as polyline } from './path-0RjhYjJs.js';
7
+ import { G as Group } from './group-BNjVVYSQ.js';
8
+ export { c as cloneGroup, g as group, a as groupFromPaths } from './group-BNjVVYSQ.js';
9
+ export { ToSvgOptions, parsePathData, parseSvg, serializePathData, toSvg } from './svg/index.js';
10
+ export { complement, intersect, occlusionSubtract, overlapRegions, shapeBoolean, subtract, subtractAll, symDifference, union, unionAll } from './shapeBoolean/index.js';
11
+ export { area, areaGroup, areaSimilarity, bounds, centroid, containsPoint, height, predicates, ringArea, width } from './predicates/index.js';
12
+ export { filterAxisAligned, filterByMinLength, parallelSegments, segmentLength, segmentSet, segmentsToOpenPaths } from './segmentSet/index.js';
13
+ export { ParallelHatchOptions, hatch, cross as hatchCross, parallel as hatchParallel } from './hatch/index.js';
14
+ export { LatticePackMode, circleContainedInPath, circleOverlapsPath, circlePacking, frontChainPack, hexLatticePack, maximumInscribedPack, maximumInscribedPackUntil, obstaclePack, repulsionPack, squareLatticePack, stochasticPack } from './circlePacking/index.js';
15
+ export { BufferOptions, buffer, chaikinCut, dilationErosion, erosionDilation, minkDifference, minkSum, morphology, radialWarp, reducePrecision, simplify, sineWarp, smooth } from './morphology/index.js';
16
+ export { flipHorizontal, flipVertical, originScale, resizeByHeight, resizeByWidth, rotate, rotateAroundCenter, scale, shear, transformation, translate, translateCentroidTo, translateCornerTo, translateToOrigin } from './transformation/index.js';
17
+ export { centroidSplit, densify, dissolve, extractBoundary, extractHoles, extractPerimeter, generateRandomGridPoints, generateRandomPoints, intersectionPoints, pointsOnExterior, processing, removeSmallHoles, segmentsOnExterior, slice } from './processing/index.js';
18
+ export { conversion, copy, flatten, fromArray, fromContours, roundVertexCoords, toArray, toContours } from './conversion/index.js';
19
+ export { contour, offsetCurvesInward, offsetCurvesOutward } from './contour/index.js';
20
+ export { boundingBox, convexHull, convexHullPath, hull } from './hull/index.js';
21
+ export { RefineOptions, delaunayTriangulation, delaunayTriangulationPoints, earCutTriangulation, poissonTriangulation, poissonTriangulationPoints, refine, triangulation } from './triangulation/index.js';
22
+ export { hexGrid, ring as pointRing, pointSet, poisson, prunePointsWithinDistance, random as randomPoints, squareGrid } from './pointSet/index.js';
23
+ export { closestPoint, closestPointPair, closestVertex, envelope, farthestPointPair, largestEmptyCircle, largestEmptyCircles, maximumInscribedAARectangle, maximumInscribedCircle, minimumBoundingCircle, optimisation } from './optimisation/index.js';
24
+ export { VoronoiOptions, compoundVoronoi, innerVoronoi, innerVoronoiRaw, voronoi } from './voronoi/index.js';
25
+ export { construction, createArc, createCircle, createKochSnowflake, createRect, createRegularPolygon, createRing, createStar } from './construction/index.js';
26
+ export { hatchSubdivision, hexTiling, quadSubdivision, rectSubdivision, sliceDivision, squareGrid as squareTiling, tiling, triangleSubdivision } from './tiling/index.js';
27
+ export { angular, circular, hilbert as hilbertPolygonise, maxArea, minArea, minPerimeter, onion, onionLayers, polygonisation, horizontal as polygoniseHorizontal, vertical as polygoniseVertical } from './polygonisation/index.js';
28
+ export { areaMerge, centroidQuadrangulation, centroidSortFaces, dualFaces, edgeCollapseQuadrangulation, extractInnerEdges, extractInnerVertices, findBreaks, findContainingFace, findIslands, fixBreaks, fixBrokenFaces, gabrielFaces, matchingQuadrangulation, meshing, radialSortFaces, relativeNeighborFaces, simplifyMesh, smoothMesh, spannerFaces, spiralQuadrangulation, splitEdges, splitQuadrangulation, stochasticMerge, subdivideMesh, urquhartFaces } from './meshing/index.js';
29
+
30
+ type OracleCase = {
31
+ id: string;
32
+ seed: number;
33
+ operation: string;
34
+ outputs: {
35
+ paths: {
36
+ rings: number[][][];
37
+ }[];
38
+ lines: number[][][];
39
+ circles: {
40
+ x: number;
41
+ y: number;
42
+ r: number;
43
+ }[];
44
+ scalars: {
45
+ area?: number;
46
+ [k: string]: number | undefined;
47
+ };
48
+ };
49
+ };
50
+ declare function ringsToPath(rings: number[][][]): Path;
51
+ declare function oraclePathsToGroup(paths: {
52
+ rings: number[][][];
53
+ }[]): Group;
54
+ /** Relative area error between two groups. */
55
+ declare function relativeAreaError(a: Group, b: Group): number;
56
+ declare function assertAreaClose(actual: Group, expectedArea: number, tol?: number): void;
57
+ /** Sample grid points: fraction of points with same containment in both groups. */
58
+ declare function containmentAgreement(a: Group, b: Group, samples?: number): number;
59
+
60
+ /**
61
+ * Clip an open segment to the interior of a closed path (exterior minus holes).
62
+ * Returns zero or more interior sub-segments.
63
+ */
64
+ declare function clipSegmentToPath(seg: Segment, clip: Path): Segment[];
65
+ declare function clipSegmentsToPath(segments: Segment[], clip: Path): Segment[];
66
+
67
+ export { Group, type OracleCase, Path, Segment, assertAreaClose, clipSegmentToPath, clipSegmentsToPath, containmentAgreement, oraclePathsToGroup, relativeAreaError, ringsToPath };