@miragon/event-storming-dsl 0.1.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.
- package/README.md +60 -0
- package/dist/index.cjs +682 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +46 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +664 -0
- package/dist/index.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lexer.ts","../src/parser.ts","../src/serializer.ts"],"names":["ATTACHABLE_STICKY_KINDS","HOST_STICKY_KINDS","id","CURRENT_SCHEMA_VERSION","validateBoard","on","idp","al","sz","col"],"mappings":";;;;;;;AAUA,IAAM,SAAA,GAAY,qCAAA;AAGX,SAAS,YAAY,IAAA,EAAmC;AAC7D,EAAA,MAAM,CAAA,GAAI,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAC7B,EAAA,IAAI,CAAC,GAAG,OAAO,IAAA;AACf,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,CAAA,CAAE,CAAC,CAAC,CAAA;AACrB,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,CAAA,CAAE,CAAC,CAAC,CAAA;AACrB,EAAA,IAAI,MAAA,CAAO,MAAM,CAAC,CAAA,IAAK,OAAO,KAAA,CAAM,CAAC,GAAG,OAAO,IAAA;AAC/C,EAAA,OAAO,EAAE,GAAG,CAAA,EAAE;AAChB;AAOO,SAAS,cACd,IAAA,EAC+D;AAC/D,EAAA,MAAM,CAAA,GAAI,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAC7B,EAAA,IAAI,CAAC,GAAG,OAAO,IAAA;AACf,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,CAAA,CAAE,CAAC,CAAC,CAAA;AACrB,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,CAAA,CAAE,CAAC,CAAC,CAAA;AACrB,EAAA,IAAI,MAAA,CAAO,MAAM,CAAC,CAAA,IAAK,OAAO,KAAA,CAAM,CAAC,GAAG,OAAO,IAAA;AAC/C,EAAA,OAAO;AAAA,IACL,MAAM,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,KAAK,EAAE,IAAA,EAAK;AAAA,IAClC,MAAA,EAAQ,EAAE,CAAA,EAAG,CAAA,EAAE;AAAA,IACf,MAAA,EAAQ,KAAK,KAAA,CAAM,CAAA,CAAE,QAAQ,CAAA,CAAE,CAAC,EAAE,MAAM;AAAA,GAC1C;AACF;AAGA,IAAM,eAAA,GAAkB,gEAAA;AAGjB,SAAS,iBAAiB,IAAA,EAA+D;AAC9F,EAAA,MAAM,CAAA,GAAI,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA;AACnC,EAAA,IAAI,CAAC,GAAG,OAAO,IAAA;AACf,EAAA,MAAM,SAAyB,EAAC;AAChC,EAAA,MAAM,KAAA,GAAQ,sDAAA;AACd,EAAA,IAAI,CAAA;AACJ,EAAA,OAAQ,IAAI,KAAA,CAAM,IAAA,CAAK,CAAA,CAAE,CAAC,CAAE,CAAA,EAAI;AAC9B,IAAA,MAAM,CAAA,GAAI,MAAA,CAAO,CAAA,CAAE,CAAC,CAAC,CAAA;AACrB,IAAA,MAAM,CAAA,GAAI,MAAA,CAAO,CAAA,CAAE,CAAC,CAAC,CAAA;AACrB,IAAA,IAAI,CAAC,MAAA,CAAO,KAAA,CAAM,CAAC,KAAK,CAAC,MAAA,CAAO,KAAA,CAAM,CAAC,GAAG,MAAA,CAAO,IAAA,CAAK,EAAE,CAAA,EAAG,GAAG,CAAA;AAAA,EAChE;AACA,EAAA,IAAI,CAAC,MAAA,CAAO,MAAA,EAAQ,OAAO,IAAA;AAC3B,EAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,KAAK,OAAA,CAAQ,eAAA,EAAiB,GAAG,CAAA,EAAE;AAC5D;AAMO,SAAS,iBAAiB,IAAA,EAAwD;AACvF,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAA,GAAS,GAAG,CAAA,EAAA,EAAK;AACxC,IAAA,MAAM,EAAA,GAAK,KAAK,CAAC,CAAA;AACjB,IAAA,IAAI,EAAA,KAAO,GAAA,EAAK,OAAA,GAAU,CAAC,OAAA;AAAA,SAAA,IAClB,CAAC,OAAA,IAAW,EAAA,KAAO,GAAA,IAAO,IAAA,CAAK,CAAA,GAAI,CAAC,CAAA,KAAM,GAAA,IAAO,IAAA,CAAK,CAAA,GAAI,CAAC,MAAM,GAAA,EAAK;AAC7E,MAAA,OAAO,EAAE,IAAA,EAAM,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,EAAG,OAAA,EAAS,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,EAAE;AAAA,IAC1D;AAAA,EACF;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,OAAA,EAAS,IAAA,EAAK;AACrC;AAGO,SAAS,oBAAA,CAAqB,MAAc,MAAA,EAAwB;AACzE,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,OAAO,MAAA,IAAU,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACrD,IAAA,MAAM,EAAA,GAAK,KAAK,CAAC,CAAA;AACjB,IAAA,IAAI,OAAO,GAAA,EAAK;AACd,MAAA,OAAA,GAAU,CAAC,OAAA;AACX,MAAA;AAAA,IACF;AACA,IAAA,IAAI,CAAC,OAAA,IAAW,IAAA,CAAK,WAAW,MAAA,EAAQ,CAAC,GAAG,OAAO,CAAA;AAAA,EACrD;AACA,EAAA,OAAO,EAAA;AACT;AAKA,IAAM,QAAA,GAAW,uDAAA;AAEV,SAAS,WAAW,IAAA,EAAgD;AACzE,EAAA,MAAM,CAAA,GAAI,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA;AAC5B,EAAA,IAAI,CAAC,KAAK,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,OAAO,EAAE,IAAA,EAAM,IAAA,EAAK;AACrC,EAAA,OAAO,EAAE,KAAA,EAAO,CAAA,CAAE,CAAC,CAAA,EAAG,MAAM,IAAA,CAAK,OAAA,CAAQ,QAAA,EAAU,GAAG,CAAA,EAAE;AAC1D;AAMA,IAAM,KAAA,GAAQ,aAAA;AAEP,SAAS,QAAQ,IAAA,EAA+C;AACrE,EAAA,MAAM,CAAA,GAAI,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA;AACzB,EAAA,IAAI,CAAC,CAAA,EAAG,OAAO,EAAE,MAAM,IAAA,EAAK;AAC5B,EAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,CAAC,CAAA,CAAE,MAAA;AAC7B,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,WAAA,CAAY,GAAG,CAAA;AAClC,EAAA,IAAI,KAAA,GAAQ,KAAA,EAAO,OAAO,EAAE,MAAM,IAAA,EAAK;AACvC,EAAA,MAAM,OAAO,IAAA,CAAK,KAAA,CAAM,KAAA,EAAO,KAAK,EAAE,IAAA,EAAK;AAC3C,EAAA,IAAI,CAAC,IAAA,EAAM,OAAO,EAAE,MAAM,IAAA,EAAK;AAC/B,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA,EAAG,IAAA,CAAK,MAAM,CAAA,EAAG,CAAA,CAAE,KAAK,CAAC,IAAI,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,CAAC,CAAC,CAAA,CAAA,EAAG;AAC5E;AAKO,IAAM,aAAA,GAAgB,kBAAA;AAE7B,IAAM,KAAA,GAAQ,kCAAA;AAGd,IAAM,aAAA,GAAgB,mBAAA;AAEf,SAAS,QAAQ,IAAA,EAKtB;AACA,EAAA,MAAM,CAAA,GAAI,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA;AACzB,EAAA,IAAI,CAAA,GAAI,CAAC,CAAA,EAAG,OAAO,EAAE,EAAA,EAAI,CAAA,CAAE,CAAC,CAAA,EAAG,IAAA,EAAM,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,EAAE;AAC9D,EAAA,MAAM,CAAA,GAAI,aAAA,CAAc,IAAA,CAAK,IAAI,CAAA;AACjC,EAAA,IAAI,CAAC,CAAA,EAAG,OAAO,EAAE,MAAM,IAAA,EAAK;AAC5B,EAAA,OAAO,EAAE,OAAA,EAAS,CAAA,CAAE,CAAC,CAAA,EAAG,MAAM,IAAA,CAAK,OAAA,CAAQ,aAAA,EAAe,GAAG,CAAA,EAAE;AACjE;AAKA,IAAM,OAAA,GAAU,2CAAA;AAGhB,IAAM,eAAA,GAAkB,qBAAA;AAEjB,SAAS,UAAU,IAAA,EAKxB;AACA,EAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA;AAC3B,EAAA,IAAI,CAAA,EAAG;AACL,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,CAAA,CAAE,CAAC,CAAC,CAAA;AACzB,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,CAAA,CAAE,CAAC,CAAC,CAAA;AAE1B,IAAA,IAAI,KAAA,GAAQ,CAAA,IAAK,MAAA,GAAS,CAAA,EAAG;AAC3B,MAAA,OAAO,EAAE,IAAA,EAAM,EAAE,KAAA,EAAO,MAAA,EAAO,EAAG,IAAA,EAAM,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,GAAG,CAAA,EAAE;AAAA,IACrE;AAAA,EACF;AACA,EAAA,MAAM,CAAA,GAAI,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA;AACnC,EAAA,IAAI,CAAC,CAAA,EAAG,OAAO,EAAE,MAAM,IAAA,EAAK;AAC5B,EAAA,OAAO,EAAE,OAAA,EAAS,CAAA,CAAE,CAAC,CAAA,EAAG,MAAM,IAAA,CAAK,OAAA,CAAQ,eAAA,EAAiB,GAAG,CAAA,EAAE;AACnE;AAMA,IAAM,QAAA,GAAW,8DAAA;AAGjB,IAAM,gBAAA,GAAmB,sBAAA;AAElB,SAAS,WAAW,IAAA,EAQzB;AACA,EAAA,MAAM,CAAA,GAAI,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA;AAC5B,EAAA,IAAI,CAAA,EAAG;AACL,IAAA,OAAO;AAAA,MACL,KAAA,EAAO;AAAA,QACL,UAAA,EAAY,CAAA,CAAE,CAAC,CAAA,CAAG,WAAA,EAAY;AAAA,QAC9B,QAAA,EAAU,CAAA,CAAE,CAAC,CAAA,CAAG,WAAA;AAAY,OAC9B;AAAA,MACA,IAAA,EAAM,IAAA,CAAK,OAAA,CAAQ,QAAA,EAAU,GAAG;AAAA,KAClC;AAAA,EACF;AACA,EAAA,MAAM,CAAA,GAAI,gBAAA,CAAiB,IAAA,CAAK,IAAI,CAAA;AACpC,EAAA,IAAI,CAAC,CAAA,EAAG,OAAO,EAAE,MAAM,IAAA,EAAK;AAC5B,EAAA,OAAO,EAAE,OAAA,EAAS,CAAA,CAAE,CAAC,CAAA,EAAG,MAAM,IAAA,CAAK,OAAA,CAAQ,gBAAA,EAAkB,GAAG,CAAA,EAAE;AACpE;AAGO,SAAS,UAAU,IAAA,EAAsB;AAC9C,EAAA,MAAM,CAAA,GAAI,sBAAA,CAAuB,IAAA,CAAK,IAAI,CAAA;AAC1C,EAAA,OAAO,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,CAAG,aAAY,GAAI,EAAA;AACnC;AAEO,SAAS,KAAK,KAAA,EAAuB;AAC1C,EAAA,OACE,MACG,IAAA,EAAK,CACL,WAAA,EAAY,CACZ,QAAQ,aAAA,EAAe,GAAG,CAAA,CAC1B,OAAA,CAAQ,MAAM,EAAE,CAAA,CAChB,OAAA,CAAQ,IAAA,EAAM,EAAE,CAAA,IAAK,GAAA;AAE5B;;;ACvLA,SAAS,WAAW,IAAA,EAAsD;AACxE,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,OAAA,CAAQ,IAAI,CAAA;AAC/B,EAAA,IAAI,KAAA,IAAS,GAAG,OAAO,IAAA;AACvB,EAAA,MAAM,OAAO,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,KAAK,EAAE,IAAA,EAAK;AACvC,EAAA,MAAM,QAAQ,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,CAAC,EAAE,IAAA,EAAK;AACzC,EAAA,OAAO,IAAA,IAAQ,KAAA,GAAQ,EAAE,IAAA,EAAM,OAAM,GAAI,IAAA;AAC3C;AAEA,IAAM,+BAAoC,IAAI,GAAA,CAAI,CAAC,SAAA,EAAW,MAAM,CAAC,CAAA;AAErE,IAAM,gBAAA,GAAwC,IAAI,GAAA,CAAIA,gDAAuB,CAAA;AAE7E,IAAM,UAAA,GAAkC,IAAI,GAAA,CAAIC,0CAAiB,CAAA;AAEjE,IAAM,+BAAoC,IAAI,GAAA,CAAI,CAAC,aAAA,EAAe,SAAA,EAAW,QAAQ,CAAC,CAAA;AAGtF,SAAS,WAAW,IAAA,EAAsB;AACxC,EAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,IAAI,CAAA;AAClC;AAGA,IAAM,kBAAA,GAAqE;AAAA,EACzE,KAAA,EAAO,OAAA;AAAA,EACP,OAAA,EAAS,KAAA;AAAA,EACT,KAAA,EAAO,OAAA;AAAA,EACP,SAAA,EAAW,KAAA;AAAA,EACX,MAAA,EAAQ,QAAA;AAAA,EACR,SAAA,EAAW,MAAA;AAAA,EACX,QAAA,EAAU,KAAA;AAAA,EACV,OAAA,EAAS;AACX,CAAA;AAGA,IAAM,eAAoC,IAAI,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,kBAAkB,CAAC,CAAA;AAoBjF,SAAS,QAA2C,GAAA,EAAW;AAC7D,EAAA,MAAM,MAA+B,EAAC;AACtC,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,CAAA,IAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG,IAAI,CAAA,KAAM,MAAA,EAAW,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AACxE,EAAA,OAAO,GAAA;AACT;AAOA,SAAS,WACP,KAAA,EACuB;AACvB,EAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,EAAA,MAAM,MAAM,OAAA,CAAQ;AAAA,IAClB,UAAA,EAAY,KAAA,CAAM,UAAA,KAAe,MAAA,GAAS,SAAY,KAAA,CAAM,UAAA;AAAA,IAC5D,QAAA,EAAU,KAAA,CAAM,QAAA,KAAa,KAAA,GAAQ,SAAY,KAAA,CAAM;AAAA,GACxD,CAAA;AACD,EAAA,OAAO,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,CAAE,SAAS,GAAA,GAAM,MAAA;AACzC;AAcA,IAAM,cAAN,MAAkB;AAAA,EACC,IAAA,uBAAW,GAAA,EAAY;AAAA;AAAA,EAExC,MAAM,EAAA,EAAqB;AACzB,IAAA,IAAI,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,EAAE,GAAG,OAAO,KAAA;AAC9B,IAAA,IAAA,CAAK,IAAA,CAAK,IAAI,EAAE,CAAA;AAChB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EACA,KAAA,CAAM,QAAgB,KAAA,EAAuB;AAC3C,IAAA,MAAM,OAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,IAAA,CAAK,KAAK,CAAC,CAAA,CAAA;AACrC,IAAA,IAAI,EAAA,GAAK,IAAA;AACT,IAAA,IAAI,CAAA,GAAI,CAAA;AACR,IAAA,OAAO,IAAA,CAAK,KAAK,GAAA,CAAI,EAAE,GAAG,EAAA,GAAK,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,CAAA,EAAG,CAAA,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,CAAK,IAAI,EAAE,CAAA;AAChB,IAAA,OAAO,EAAA;AAAA,EACT;AACF,CAAA;AAMO,SAAS,SAAS,IAAA,EAAkC;AACzD,EAAA,OAAO,uBAAA,CAAwB,IAAI,CAAA,CAAE,KAAA;AACvC;AAMO,SAAS,wBAAwB,IAAA,EAA2B;AACjE,EAAA,MAAM,cAAiC,EAAC;AACxC,EAAA,MAAM,GAAA,GAAM,IAAI,WAAA,EAAY;AAC5B,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAoB;AACzC,EAAA,MAAM,WAA2B,EAAC;AAClC,EAAA,MAAM,iBAA2B,EAAC;AAClC,EAAA,MAAM,gBAAgC,EAAC;AACvC,EAAA,MAAM,qBAA0C,EAAC;AAEjD,EAAA,IAAI,MAAA,GAAsB,EAAE,KAAA,EAAO,gBAAA,EAAiB;AACpD,EAAA,IAAI,cAAA,GAAiB,KAAA;AAErB,EAAA,MAAM,QAAA,GAAW,CAAC,IAAA,EAAc,EAAA,KAAe;AAC7C,IAAA,IAAI,CAAC,SAAS,GAAA,CAAI,IAAI,GAAG,QAAA,CAAS,GAAA,CAAI,MAAM,EAAE,CAAA;AAAA,EAChD,CAAA;AAGA,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,IAAI,WAAA,GAAc,EAAA;AAGlB,EAAA,MAAM,SAAA,GAAY,CAAC,IAAA,KAA0B;AAE3C,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC7B,IAAA,MAAM,IAAA,GAAO,QAAQ,CAAA,GAAI,IAAA,CAAK,MAAM,CAAA,EAAG,IAAI,CAAA,CAAE,IAAA,EAAK,GAAI,IAAA;AACtD,IAAA,MAAM,UAAA,GAAa,QAAQ,CAAA,GAAI,IAAA,CAAK,MAAM,IAAA,GAAO,CAAC,CAAA,CAAE,IAAA,EAAK,GAAI,EAAA;AAC7D,IAAA,MAAM,KAAA,GAAQ,WAAW,IAAI,CAAA;AAC7B,IAAA,IAAI,CAAC,OAAO,OAAO,KAAA;AACnB,IAAA,aAAA,CAAc,IAAA,CAAK;AAAA,MACjB,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,OAAO,KAAA,CAAM,KAAA;AAAA,MACb,GAAI,UAAA,GAAa,EAAE,KAAA,EAAO,UAAA,KAAe,EAAC;AAAA,MAC1C,GAAA,EAAK,IAAA;AAAA,MACL;AAAA,KACD,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AACA,EAAA,MAAM,IAAA,GAAO,CAAC,OAAA,EAAiB,MAAA,GAAS,QAAQ,KAAA,GAAQ,WAAA,KACtD,WAAA,CAAY,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAM,OAAO,CAAA;AAEzD,EAAA,MAAM,MAAA,GAAS,CAAC,CAAA,KAAc;AAC5B,IAAA,cAAA,CAAe,KAAK,CAAC,CAAA;AACrB,IAAA,IAAA,CAAK,mEAAmE,CAAA;AAAA,EAC1E,CAAA;AAEA,EAAA,MAAM,MAAM,CAAC,CAAA,EAAW,CAAA,MAA2B,EAAE,GAAG,CAAA,EAAE,CAAA;AAE1D,EAAA,MAAM,WAAA,GAAc,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AACtC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,WAAA,CAAY,QAAQ,CAAA,EAAA,EAAK;AAC3C,IAAA,MAAM,GAAA,GAAM,YAAY,CAAC,CAAA;AACzB,IAAA,MAAA,GAAS,CAAA,GAAI,CAAA;AACb,IAAA,WAAA,GAAc,IAAI,IAAA,EAAK;AACvB,IAAA,IAAI,OAAA,GAAU,GAAA;AAGd,IAAA,IAAI,cAAA,EAAgB;AAClB,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA;AAClC,MAAA,IAAI,QAAQ,CAAA,EAAG;AACb,QAAA,cAAA,CAAe,KAAK,GAAG,CAAA;AACvB,QAAA;AAAA,MACF;AACA,MAAA,cAAA,CAAe,KAAK,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,KAAA,GAAQ,CAAC,CAAC,CAAA;AAC/C,MAAA,OAAA,GAAU,OAAA,CAAQ,KAAA,CAAM,KAAA,GAAQ,CAAC,CAAA;AACjC,MAAA,cAAA,GAAiB,KAAA;AAAA,IACnB;AACA,IAAA,IAAI,IAAA,GAAO,oBAAA,CAAqB,OAAA,EAAS,IAAI,CAAA;AAC7C,IAAA,OAAO,QAAQ,CAAA,EAAG;AAChB,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,OAAA,CAAQ,IAAA,EAAM,OAAO,CAAC,CAAA;AAC5C,MAAA,IAAI,QAAQ,CAAA,EAAG;AACb,QAAA,cAAA,CAAe,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAC,CAAA;AACvC,QAAA,OAAA,GAAU,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,IAAI,CAAA;AAC/B,QAAA,cAAA,GAAiB,IAAA;AACjB,QAAA;AAAA,MACF;AACA,MAAA,cAAA,CAAe,KAAK,OAAA,CAAQ,KAAA,CAAM,IAAA,EAAM,KAAA,GAAQ,CAAC,CAAC,CAAA;AAClD,MAAA,OAAA,GAAU,CAAA,EAAG,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,IAAI,CAAC,CAAA,CAAA,EAAI,OAAA,CAAQ,KAAA,CAAM,KAAA,GAAQ,CAAC,CAAC,CAAA,CAAA;AAC/D,MAAA,IAAA,GAAO,oBAAA,CAAqB,SAAS,IAAI,CAAA;AAAA,IAC3C;AACA,IAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAQ,GAAI,iBAAiB,OAAO,CAAA;AAClD,IAAA,IAAI,OAAA,KAAY,IAAA,EAAM,cAAA,CAAe,IAAA,CAAK,OAAO,CAAA;AACjD,IAAA,OAAA,GAAU,IAAA;AAEV,IAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,EAAK;AAC1B,IAAA,IAAI,CAAC,IAAA,EAAM;AAEX,IAAA,MAAM,EAAA,GAAK,UAAU,IAAI,CAAA;AACzB,IAAA,MAAM,QAAQ,IAAA,CAAK,KAAA,CAAM,EAAA,CAAG,MAAM,EAAE,IAAA,EAAK;AAWzC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC7B,IAAA,MAAM,mBAAmB,IAAA,IAAQ,CAAA,GAAI,KAAK,KAAA,CAAM,CAAA,EAAG,IAAI,CAAA,GAAI,IAAA;AAC3D,IAAA,MAAM,eAAe,MAAe;AAClC,MAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,gBAAA,CAAiB,IAAA,EAAM,CAAA;AAChD,MAAA,OAAO,UAAU,IAAA,IAAQ,QAAA,CAAS,IAAI,UAAA,CAAW,KAAA,CAAM,IAAI,CAAC,CAAA;AAAA,IAC9D,CAAA;AACA,IAAA,IAAA,CAAK,EAAA,KAAO,OAAA,IAAW,YAAA,EAAa,KAAM,CAAC,YAAY,gBAAgB,CAAA,IAAK,SAAA,CAAU,IAAI,CAAA,EAAG;AAC3F,MAAA;AAAA,IACF;AAEA,IAAA,QAAQ,EAAA;AAAI,MACV,KAAK,OAAA;AACH,QAAA,MAAA,GAAS,EAAE,GAAG,MAAA,EAAQ,KAAA,EAAO,KAAA,EAAM;AACnC,QAAA;AAAA,MAEF,KAAK,OAAA,EAAS;AACZ,QAAA,MAAM,CAAA,GAAI,MAAM,WAAA,EAAY;AAC5B,QAAA,IAAI,YAAA,CAAa,IAAI,CAAC,CAAA,WAAY,EAAE,GAAG,MAAA,EAAQ,KAAA,EAAO,CAAA,EAAwB;AAAA,oBAClE,IAAI,CAAA;AAChB,QAAA;AAAA,MACF;AAAA,MAEA,KAAK,OAAA,EAAS;AACZ,QAAA,MAAM,CAAA,GAAI,MAAM,WAAA,EAAY;AAC5B,QAAA,IAAI,YAAA,CAAa,IAAI,CAAC,CAAA,WAAY,EAAE,GAAG,MAAA,EAAQ,KAAA,EAAO,CAAA,EAAgB;AAAA,oBAC1D,IAAI,CAAA;AAChB,QAAA;AAAA,MACF;AAAA,MAEA,KAAK,OAAA;AAAA,MACL,KAAK,SAAA;AAAA,MACL,KAAK,OAAA;AAAA,MACL,KAAK,WAAA;AAAA,MACL,KAAK,QAAA;AAAA,MACL,KAAK,WAAA;AAAA,MACL,KAAK,UAAA;AAAA,MACL,KAAK,SAAA,EAAW;AACd,QAAA,MAAM,IAAA,GAAO,YAAY,KAAK,CAAA;AAC9B,QAAA,IAAI,CAAC,IAAA,EAAM;AACT,UAAA,MAAA,CAAO,IAAI,CAAA;AACX,UAAA;AAAA,QACF;AACA,QAAA,IAAI,KAAK,SAAA,EAAW;AAClB,UAAA,IAAA;AAAA,YACE,CAAA,oBAAA,EAAuB,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,CAAA,4DAAA;AAAA,WAC9C;AAAA,QACF;AACA,QAAA,MAAM,QAAA,GAAW,IAAA,CAAK,EAAA,KAAO,MAAA,IAAa,GAAA,CAAI,MAAM,IAAA,CAAK,EAAE,CAAA,GAAI,IAAA,CAAK,EAAA,GAAK,MAAA;AACzE,QAAA,IAAI,IAAA,CAAK,EAAA,KAAO,MAAA,IAAa,QAAA,KAAa,MAAA,EAAW;AACnD,UAAA,IAAA,CAAK,CAAA,KAAA,EAAQ,IAAA,CAAK,EAAE,CAAA,oDAAA,CAAiD,CAAA;AAAA,QACvE;AACA,QAAA,MAAM,EAAA,GAAK,YAAY,GAAA,CAAI,KAAA,CAAM,mBAAmB,EAAiB,CAAA,EAAI,KAAK,IAAI,CAAA;AAClF,QAAA,QAAA,CAAS,IAAA;AAAA,UACP,OAAA,CAAQ;AAAA,YACN,EAAA;AAAA,YACA,WAAA,EAAa,EAAA;AAAA,YACb,OAAO,IAAA,CAAK,IAAA;AAAA,YACZ,UAAU,GAAA,CAAI,IAAA,CAAK,OAAO,CAAA,EAAG,IAAA,CAAK,OAAO,CAAC,CAAA;AAAA,YAC1C,OAAO,IAAA,CAAK;AAAA,WACb;AAAA,SACH;AACA,QAAA,QAAA,CAAS,IAAA,CAAK,MAAM,EAAE,CAAA;AACtB,QAAA,IAAI,IAAA,CAAK,SAAS,MAAA,EAAW;AAC3B,UAAA,IAAI,gBAAA,CAAiB,GAAA,CAAI,EAAE,CAAA,EAAG;AAC5B,YAAA,kBAAA,CAAmB,IAAA,CAAK;AAAA,cACtB,KAAA,EAAO,SAAS,MAAA,GAAS,CAAA;AAAA,cACzB,MAAM,IAAA,CAAK,IAAA;AAAA,cACX,GAAA,EAAK,IAAA;AAAA,cACL;AAAA,aACD,CAAA;AAAA,UACH,CAAA,MAAO;AACL,YAAA,IAAA,CAAK,CAAA,cAAA,EAAiB,EAAE,CAAA,oEAAA,CAA4D,CAAA;AAAA,UACtF;AAAA,QACF;AACA,QAAA,IAAI,KAAK,UAAA,EAAY;AACnB,UAAA,IAAA,CAAK,CAAA,QAAA,EAAW,EAAE,CAAA,0DAAA,CAAkD,CAAA;AAAA,QACtE;AACA,QAAA,IAAI,KAAK,WAAA,EAAa;AACpB,UAAA,IAAA,CAAK,CAAA,SAAA,EAAY,EAAE,CAAA,2DAAA,CAAmD,CAAA;AAAA,QACxE;AACA,QAAA;AAAA,MACF;AAAA,MAEA,KAAK,MAAA,EAAQ;AACX,QAAA,MAAM,KAAA,GAAQ,cAAc,KAAK,CAAA;AACjC,QAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,QAAA,CAAS,GAAG,CAAA,EAAG;AACjC,UAAA,MAAA,CAAO,IAAI,CAAA;AACX,UAAA;AAAA,QACF;AAKA,QAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,KAAA,GAAQ,KAAA,CAAM,SAAS,KAAK,CAAA;AAC/C,QAAA,MAAM,EAAA,GAAK,UAAA,CAAW,EAAA,CAAG,IAAI,CAAA;AAC7B,QAAA,MAAM,EAAA,GAAK,SAAA,CAAU,EAAA,CAAG,IAAI,CAAA;AAC5B,QAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,EAAA,CAAG,IAAI,CAAA;AAC3B,QAAA,MAAM,GAAA,GAAM,UAAA,CAAW,GAAA,CAAI,IAAI,CAAA;AAC/B,QAAA,IAAI,GAAG,OAAA,EAAS;AACd,UAAA,IAAA;AAAA,YACE,CAAA,uBAAA,EAA0B,EAAA,CAAG,OAAA,CAAQ,IAAA,EAAM,CAAA,6DAAA;AAAA,WAC7C;AAAA,QACF;AACA,QAAA,IAAI,GAAG,OAAA,EAAS;AACd,UAAA,IAAA;AAAA,YACE,CAAA,sBAAA,EAAyB,EAAA,CAAG,OAAA,CAAQ,IAAA,EAAM,CAAA,sDAAA;AAAA,WAC5C;AAAA,QACF;AACA,QAAA,IAAI,GAAA,CAAI,EAAA,KAAO,MAAA,IAAa,GAAA,CAAI,OAAA,EAAS;AACvC,UAAA,IAAA,CAAK,8EAAoE,CAAA;AAAA,QAC3E;AAEA,QAAA,MAAM,QAAA,GAAW,YAAY,KAAA,GAAQ,KAAA,CAAM,OAAO,GAAA,CAAI,IAAA,EAAM,MAAM,CAAA;AAClE,QAAA,MAAM,EAAA,GAAK,GAAA,CAAI,KAAA,CAAM,MAAA,EAAQ,YAAY,MAAM,CAAA;AAC/C,QAAA,MAAM,OAAoB,OAAA,CAAQ;AAAA,UAChC,EAAA;AAAA,UACA,WAAA,EAAa,MAAA;AAAA,UACb,KAAA,EAAO,QAAA;AAAA,UACP,QAAA,EAAU,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,MAAA,CAAO,CAAA,EAAG,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,GAAI,GAAA,CAAI,CAAA,EAAG,CAAC,CAAA;AAAA,UAChE,OAAO,GAAA,CAAI,KAAA;AAAA,UACX,MAAM,EAAA,CAAG,IAAA;AAAA,UACT,KAAA,EAAO,UAAA,CAAW,EAAA,CAAG,KAAK;AAAA,SAC3B,CAAA;AACD,QAAA,QAAA,CAAS,KAAK,IAAI,CAAA;AAClB,QAAA,IAAI,EAAA,CAAG,SAAS,MAAA,EAAW;AACzB,UAAA,kBAAA,CAAmB,IAAA,CAAK,EAAE,KAAA,EAAO,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG,IAAA,EAAM,EAAA,CAAG,IAAA,EAAM,GAAA,EAAK,IAAA,EAAM,MAAA,EAAQ,CAAA;AAAA,QAC1F;AACA,QAAA;AAAA,MACF;AAAA,MAEA,KAAK,MAAA,EAAQ;AAEX,QAAA,MAAM,GAAA,GAAM,WAAW,KAAK,CAAA;AAC5B,QAAA,MAAM,KAAA,GAAQ,gBAAA,CAAiB,GAAA,CAAI,IAAI,CAAA;AACvC,QAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,MAAA,CAAO,SAAS,CAAA,EAAG;AACrC,UAAA,MAAA,CAAO,IAAI,CAAA;AACX,UAAA;AAAA,QACF;AACA,QAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA;AACpC,QAAA,IAAI,SAAA,CAAU,SAAS,MAAA,EAAW;AAChC,UAAA,IAAA,CAAK,2FAAiF,CAAA;AAAA,QACxF;AACA,QAAA,MAAM,SAAA,GAAY,SAAA,CAAU,SAAA,CAAU,IAAI,CAAA;AAC1C,QAAA,IAAI,SAAA,CAAU,IAAA,IAAQ,SAAA,CAAU,OAAA,EAAS;AACvC,UAAA,IAAA,CAAK,2EAAiE,CAAA;AAAA,QACxE;AACA,QAAA,MAAM,SAAA,GAAY,UAAA,CAAW,SAAA,CAAU,IAAI,CAAA;AAC3C,QAAA,IAAI,SAAA,CAAU,KAAA,IAAS,SAAA,CAAU,OAAA,EAAS;AACxC,UAAA,IAAA,CAAK,6EAAmE,CAAA;AAAA,QAC1E;AACA,QAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,SAAA,CAAU,IAAI,CAAA;AACxC,QAAA,IAAI,SAAA,CAAU,EAAA,KAAO,MAAA,IAAa,SAAA,CAAU,OAAA,EAAS;AACnD,UAAA,IAAA,CAAK,iFAAuE,CAAA;AAAA,QAC9E;AACA,QAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,IAAA,CAAK,WAAA,EAAY;AACzC,QAAA,MAAM,WAAA,GAA8C,KAAA,CAAM,QAAA,CAAS,UAAU,CAAA,GACzE,WACA,KAAA,CAAM,QAAA,CAAS,UAAU,CAAA,GACvB,QAAA,GACA,MAAA;AACN,QAAA,MAAM,MAAA,GAAS,KAAA,CAAM,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,GAAA,CAAI,CAAA,CAAE,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AACpD,QAAA,MAAM,OAAA,GAA0B;AAAA,UAC9B,EAAA,EAAI,GAAA,CAAI,KAAA,CAAM,MAAA,EAAQ,MAAM,CAAA;AAAA,UAC5B,WAAA,EAAa,SAAA;AAAA,UACb,KAAA,EAAO,EAAA;AAAA,UACP,QAAA,EAAU,OAAO,CAAC,CAAA;AAAA,UAClB,MAAA;AAAA,UACA,GAAI,MAAM,QAAA,CAAS,UAAU,IAAI,EAAE,MAAA,EAAQ,IAAA,EAAK,GAAI,EAAC;AAAA,UACrD,GAAI,WAAA,GAAc,EAAE,WAAA,KAAgB,EAAC;AAAA,UACrC,GAAI,IAAI,KAAA,GAAQ,EAAE,OAAO,GAAA,CAAI,KAAA,KAAU;AAAC,SAC1C;AACA,QAAA,QAAA,CAAS,KAAK,OAAO,CAAA;AACrB,QAAA;AAAA,MACF;AAAA,MAEA,SAAS;AAEP,QAAA,IAAI,CAAC,SAAA,CAAU,IAAI,CAAA,EAAG,cAAA,CAAe,KAAK,IAAI,CAAA;AAAA,MAChD;AAAA;AACF,EACF;AAKA,EAAA,MAAM,OAAA,GAAU,CAAC,KAAA,KAA4C;AAC3D,IAAA,IAAI,KAAA,CAAM,UAAA,CAAW,GAAG,CAAA,EAAG;AACzB,MAAA,MAAMC,GAAAA,GAAK,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA;AACxB,MAAA,OAAO,SAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAOA,GAAE,CAAA;AAAA,IACzC;AACA,IAAA,MAAM,EAAA,GAAK,QAAA,CAAS,GAAA,CAAI,UAAA,CAAW,KAAK,CAAC,CAAA;AACzC,IAAA,OAAO,EAAA,KAAO,SAAY,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,EAAE,CAAA,GAAI,MAAA;AAAA,EAChE,CAAA;AAKA,EAAA,KAAA,MAAW,OAAO,kBAAA,EAAoB;AACpC,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA;AAC7B,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,IAAA,CAAK,gBAAgB,GAAA,CAAI,IAAI,eAAe,GAAA,CAAI,MAAA,EAAQ,IAAI,GAAG,CAAA;AAC/D,MAAA;AAAA,IACF;AACA,IAAA,IAAI,CAAC,UAAA,CAAW,GAAA,CAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrC,MAAA,IAAA;AAAA,QACE,CAAA,aAAA,EAAgB,GAAA,CAAI,IAAI,CAAA,OAAA,EAAU,KAAK,WAAW,CAAA,8DAAA,CAAA;AAAA,QAClD,GAAA,CAAI,MAAA;AAAA,QACJ,GAAA,CAAI;AAAA,OACN;AACA,MAAA;AAAA,IACF;AACA,IAAA,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA,GAAI,EAAE,GAAG,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA,EAAI,UAAA,EAAY,IAAA,CAAK,EAAA,EAAG;AAAA,EACvE;AAEA,EAAA,IAAI,MAAA,GAAS,CAAA;AAGb,EAAA,MAAM,UAAA,GAAa,IAAI,GAAA,CAAI,QAAA,CAAS,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AACpD,EAAA,MAAM,cAAc,MAAc;AAChC,IAAA,IAAI,EAAA,GAAK,CAAA,MAAA,EAAS,EAAE,MAAM,CAAA,CAAA;AAC1B,IAAA,OAAO,WAAW,GAAA,CAAI,EAAE,GAAG,EAAA,GAAK,CAAA,MAAA,EAAS,EAAE,MAAM,CAAA,CAAA;AACjD,IAAA,OAAO,EAAA;AAAA,EACT,CAAA;AACA,EAAA,MAAM,QAAqB,EAAC;AAC5B,EAAA,KAAA,MAAW,SAAS,aAAA,EAAe;AACjC,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA;AAC/B,IAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA;AAC9B,IAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,EAAA,EAAI;AAChB,MAAA,cAAA,CAAe,IAAA,CAAK,MAAM,GAAG,CAAA;AAC7B,MAAA,IAAA;AAAA,QACE,CAAA,OAAA,EAAU,CAAC,IAAA,GAAO,CAAA,CAAA,EAAI,KAAA,CAAM,IAAI,CAAA,CAAA,CAAA,GAAM,CAAA,CAAA,EAAI,KAAA,CAAM,KAAK,CAAA,CAAA,CAAG,CAAA,UAAA,CAAA;AAAA,QACxD,KAAA,CAAM,MAAA;AAAA,QACN,KAAA,CAAM;AAAA,OACR;AACA,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,SAAA,GAAY,CAAC,YAAA,CAAa,GAAA,CAAI,KAAK,WAAW,CAAA,GAC/C,CAAC,KAAA,CAAM,IAAA,EAAM,IAAI,IAClB,CAAC,YAAA,CAAa,IAAI,EAAA,CAAG,WAAW,IAC7B,CAAC,KAAA,CAAM,KAAA,EAAO,EAAE,CAAA,GACjB,MAAA;AACN,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,cAAA,CAAe,IAAA,CAAK,MAAM,GAAG,CAAA;AAC7B,MAAA,IAAA;AAAA,QACE,CAAA,QAAA,EAAW,UAAU,CAAC,CAAC,UAAU,SAAA,CAAU,CAAC,EAAE,WAAW,CAAA,wCAAA,CAAA;AAAA,QACzD,KAAA,CAAM,MAAA;AAAA,QACN,KAAA,CAAM;AAAA,OACR;AACA,MAAA;AAAA,IACF;AACA,IAAA,KAAA,CAAM,IAAA;AAAA,MACJ,OAAA,CAAQ;AAAA,QACN,IAAI,WAAA,EAAY;AAAA,QAChB,QAAA,EAAU,OAAA;AAAA,QACV,MAAM,IAAA,CAAK,EAAA;AAAA,QACX,IAAI,EAAA,CAAG,EAAA;AAAA,QACP,OAAO,KAAA,CAAM;AAAA,OACd;AAAA,KACH;AAAA,EACF;AAEA,EAAA,MAAM,QAAQ,OAAA,CAAQ;AAAA,IACpB,aAAA,EAAeC,+CAAA;AAAA,IACf,MAAA;AAAA,IACA,QAAA;AAAA,IACA,KAAA;AAAA,IACA,cAAA,EAAgB,cAAA,CAAe,MAAA,GAAS,cAAA,GAAiB;AAAA,GAC1D,CAAA;AAED,EAAA,OAAO,EAAE,KAAA,EAAOC,sCAAA,CAAc,KAAK,GAAG,WAAA,EAAY;AACpD;AA2BA,SAAS,YAAY,KAAA,EAAoC;AACvD,EAAA,MAAM,KAAA,GAAQ,cAAc,KAAK,CAAA;AACjC,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,IAAI,CAAC,KAAA,CAAM,IAAA,EAAM,OAAO,IAAA;AACxB,IAAA,MAAMC,GAAAA,GAAK,OAAA,CAAQ,KAAA,CAAM,MAAM,CAAA;AAC/B,IAAA,MAAMC,IAAAA,GAAM,OAAA,CAAQD,GAAAA,CAAG,IAAI,CAAA;AAC3B,IAAA,MAAME,GAAAA,GAAK,UAAA,CAAWD,IAAAA,CAAI,IAAI,CAAA;AAC9B,IAAA,MAAME,GAAAA,GAAK,SAAA,CAAUD,GAAAA,CAAG,IAAI,CAAA;AAC5B,IAAA,MAAME,IAAAA,GAAM,UAAA,CAAWD,GAAAA,CAAG,IAAI,CAAA;AAC9B,IAAA,OAAO,OAAA,CAAQ;AAAA,MACb,IAAA,EAAM,UAAA,CAAW,KAAA,CAAM,IAAI,CAAA;AAAA,MAC3B,MAAA,EAAQ,EAAE,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,EAAG,CAAA,EAAG,KAAA,CAAM,MAAA,CAAO,CAAA,EAAE;AAAA,MAC/C,KAAA,EAAOC,KAAI,KAAA,IAAS,MAAA;AAAA,MACpB,MAAMJ,GAAAA,CAAG,IAAA;AAAA,MACT,IAAIC,IAAAA,CAAI,EAAA;AAAA,MACR,WAAWA,IAAAA,CAAI,OAAA;AAAA,MACf,UAAA,EAAYE,GAAAA,CAAG,IAAA,IAAQA,GAAAA,CAAG,UAAU,IAAA,GAAO,MAAA;AAAA,MAC3C,WAAA,EAAaD,GAAAA,CAAG,KAAA,IAASA,GAAAA,CAAG,UAAU,IAAA,GAAO;AAAA,KAC9C,CAAA;AAAA,EACH;AACA,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,GAAG,CAAA,EAAG,OAAO,IAAA;AAChC,EAAA,MAAM,EAAA,GAAK,QAAQ,KAAK,CAAA;AACxB,EAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,EAAA,CAAG,IAAI,CAAA;AAC3B,EAAA,MAAM,EAAA,GAAK,UAAA,CAAW,GAAA,CAAI,IAAI,CAAA;AAC9B,EAAA,MAAM,EAAA,GAAK,SAAA,CAAU,EAAA,CAAG,IAAI,CAAA;AAC5B,EAAA,MAAM,GAAA,GAAM,UAAA,CAAW,EAAA,CAAG,IAAI,CAAA;AAC9B,EAAA,MAAM,IAAA,GAAO,GAAA,CAAI,IAAA,CAAK,IAAA,EAAK;AAC3B,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,OAAO,OAAA,CAAQ;AAAA,IACb,IAAA,EAAM,WAAW,IAAI,CAAA;AAAA,IACrB,MAAA,EAAQ,EAAE,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAE;AAAA,IACrB,KAAA,EAAO,IAAI,KAAA,IAAS,MAAA;AAAA,IACpB,MAAM,EAAA,CAAG,IAAA;AAAA,IACT,IAAI,GAAA,CAAI,EAAA;AAAA,IACR,WAAW,GAAA,CAAI,OAAA;AAAA,IACf,UAAA,EAAY,EAAA,CAAG,IAAA,IAAQ,EAAA,CAAG,UAAU,IAAA,GAAO,MAAA;AAAA,IAC3C,WAAA,EAAa,EAAA,CAAG,KAAA,IAAS,EAAA,CAAG,UAAU,IAAA,GAAO;AAAA,GAC9C,CAAA;AACH;;;AC9jBA,SAAS,EAAE,CAAA,EAAmB;AAC5B,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,GAAI,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,GAAI,CAAA,GAAI,GAAA,GAAO,CAAA;AAC7D,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,GAAI,IAAA,GAAO,MAAA,CAAO,CAAC,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA,CAAE,QAAA,EAAS;AAC7D;AAQA,SAAS,WAAW,KAAA,EAAuB;AACzC,EAAA,OAAO,KAAA,CACJ,IAAA,EAAK,CACL,OAAA,CAAQ,KAAA,EAAO,KAAK,CAAA,CACpB,OAAA,CAAQ,aAAA,EAAe,cAAI,CAAA,CAC3B,OAAA,CAAQ,SAAS,SAAI,CAAA;AAC1B;AAGA,SAAS,WAAW,KAAA,EAAuB;AACzC,EAAA,OAAO,UAAA,CAAW,KAAK,CAAA,CAAE,OAAA,CAAQ,OAAO,QAAG,CAAA;AAC7C;AAGA,IAAM,WAAA,uBAAuC,GAAA,CAAI;AAAA,EAC/C,OAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAC,CAAA;AAED,IAAM,aAAA,GAAkD;AAAA,EACtD,KAAA,EAAO,cAAA;AAAA,EACP,OAAA,EAAS,SAAA;AAAA,EACT,KAAA,EAAO,OAAA;AAAA,EACP,SAAA,EAAW,WAAA;AAAA,EACX,MAAA,EAAQ,QAAA;AAAA,EACR,SAAA,EAAW,YAAA;AAAA,EACX,QAAA,EAAU,iBAAA;AAAA,EACV,OAAA,EAAS;AACX,CAAA;AAEA,SAAS,YAAY,IAAA,EAAsB;AACzC,EAAA,OAAO,aAAA,CAAc,IAAI,CAAA,IAAK,QAAA;AAChC;AAQA,SAAS,gBAAgB,KAAA,EAAgD;AACvE,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAoB;AACrC,EAAA,KAAA,MAAW,EAAA,IAAM,MAAM,QAAA,EAAU;AAC/B,IAAA,IAAI,CAAC,WAAA,CAAY,GAAA,CAAI,EAAA,CAAG,WAAW,CAAA,EAAG;AACtC,IAAA,IAAA,CAAK,GAAA,CAAI,EAAA,CAAG,EAAA,EAAI,UAAA,CAAW,EAAA,CAAG,KAAK,CAAA,IAAK,WAAA,CAAY,EAAA,CAAG,WAAW,CAAC,CAAA;AAAA,EACrE;AACA,EAAA,OAAO,IAAA;AACT;AAGA,SAAS,YAAY,EAAA,EAAgC;AACnD,EAAA,OAAO,EAAA,CAAG,KAAA,GAAQ,CAAA,QAAA,EAAW,EAAA,CAAG,KAAK,CAAA,CAAA,CAAA,GAAM,EAAA;AAC7C;AAOA,SAAS,YAAY,EAAA,EAAyB;AAC5C,EAAA,MAAM,UAAA,GAAa,EAAA,CAAG,KAAA,EAAO,UAAA,IAAc,MAAA;AAC3C,EAAA,MAAM,QAAA,GAAW,EAAA,CAAG,KAAA,EAAO,QAAA,IAAY,KAAA;AACvC,EAAA,OAAO,UAAA,KAAe,UAAU,QAAA,KAAa,KAAA,GAAQ,KAAK,CAAA,QAAA,EAAW,UAAU,IAAI,QAAQ,CAAA,CAAA,CAAA;AAC7F;AAOO,SAAS,aAAa,KAAA,EAAmC;AAC9D,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,MAAM,KAAA,GAAQ,gBAAgB,KAAK,CAAA;AACnC,EAAA,MAAM,MAAA,GAAS,CAAC,EAAA,KAA6B,KAAA,CAAM,IAAI,EAAA,CAAG,EAAE,KAAK,EAAA,CAAG,KAAA;AAMpE,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAoB;AAC1C,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,MAAA,EAAO,EAAG,SAAA,CAAU,GAAA,CAAI,IAAA,EAAA,CAAO,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA,IAAK,CAAA,IAAK,CAAC,CAAA;AACrF,EAAA,MAAM,OAAA,GAAU,CAAC,EAAA,KAAwB;AACvC,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,GAAA,CAAI,EAAE,CAAA;AACzB,IAAA,OAAO,IAAA,KAAS,WAAc,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA,GAAK,CAAA,IAAK,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,CAAA;AAAA,EAC/E,CAAA;AAKA,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAoB;AACxC,EAAA,MAAM,KAAA,GAAQ,IAAI,GAAA,CAAI,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AACrD,EAAA,KAAA,MAAW,EAAA,IAAM,MAAM,QAAA,EAAU;AAC/B,IAAA,IAAI,CAAC,QAAQ,EAAA,CAAG,EAAE,KAAK,aAAA,CAAc,IAAA,CAAK,EAAA,CAAG,EAAE,CAAA,EAAG;AAClD,IAAA,IAAI,SAAA,GAAY,IAAA,CAAK,EAAA,CAAG,EAAE,CAAA;AAC1B,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,KAAA,CAAM,GAAA,CAAI,SAAS,CAAA,EAAG,CAAA,EAAA,EAAK,SAAA,GAAY,CAAA,EAAG,IAAA,CAAK,EAAA,CAAG,EAAE,CAAC,IAAI,CAAC,CAAA,CAAA;AAC1E,IAAA,KAAA,CAAM,IAAI,SAAS,CAAA;AACnB,IAAA,OAAA,CAAQ,GAAA,CAAI,EAAA,CAAG,EAAA,EAAI,SAAS,CAAA;AAAA,EAC9B;AACA,EAAA,MAAM,OAAO,CAAC,EAAA,KAAuB,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA,IAAK,EAAA;AACxD,EAAA,MAAM,GAAA,GAAM,CAAC,EAAA,KAAwB,OAAA,CAAQ,EAAE,CAAA,GAAI,CAAA,CAAA,EAAI,IAAA,CAAK,EAAE,CAAC,CAAA,CAAA,GAAM,KAAA,CAAM,GAAA,CAAI,EAAE,CAAA,IAAK,EAAA;AAEtF,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,MAAA,EAAS,KAAA,CAAM,MAAA,CAAO,KAAK,CAAA,CAAE,CAAA;AACxC,EAAA,IAAI,KAAA,CAAM,OAAO,KAAA,EAAO,KAAA,CAAM,KAAK,CAAA,MAAA,EAAS,KAAA,CAAM,MAAA,CAAO,KAAK,CAAA,CAAE,CAAA;AAChE,EAAA,IAAI,KAAA,CAAM,OAAO,KAAA,EAAO,KAAA,CAAM,KAAK,CAAA,MAAA,EAAS,KAAA,CAAM,MAAA,CAAO,KAAK,CAAA,CAAE,CAAA;AAKhE,EAAA,MAAM,QAAA,GAAW,CAAC,EAAA,KAA6B;AAC7C,IAAA,MAAM,MAAA,GACJ,EAAA,CAAG,WAAA,KAAgB,OAAA,IAAW,EAAA,CAAG,WAAA,KAAgB,SAAA,IAAa,EAAA,CAAG,WAAA,KAAgB,MAAA,GAC7E,EAAA,CAAG,UAAA,GACH,MAAA;AACN,IAAA,OAAO,MAAA,GAAS,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,CAAC,CAAA,CAAA,CAAA,GAAM,EAAA;AAAA,EAC3C,CAAA;AAEA,EAAA,KAAA,MAAW,EAAA,IAAM,MAAM,QAAA,EAAU;AAC/B,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,EAAA,CAAG,EAAE,CAAA,GAAI,QAAQ,IAAA,CAAK,EAAA,CAAG,EAAE,CAAC,CAAA,CAAA,CAAA,GAAM,EAAA;AAC3D,IAAA,KAAA,CAAM,IAAA,CAAK,WAAA,CAAY,EAAA,EAAI,MAAA,CAAO,EAAE,GAAG,QAAA,EAAU,QAAA,CAAS,EAAE,CAAC,CAAC,CAAA;AAAA,EAChE;AAIA,EAAA,KAAA,MAAW,IAAA,IAAQ,MAAM,KAAA,EAAO;AAC9B,IAAA,MAAM,aAAa,IAAA,CAAK,KAAA,GAAQ,CAAA,EAAA,EAAK,IAAA,CAAK,KAAK,CAAA,CAAA,GAAK,EAAA;AACpD,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAG,GAAA,CAAI,IAAA,CAAK,IAAI,CAAC,CAAA,IAAA,EAAO,GAAA,CAAI,IAAA,CAAK,EAAE,CAAC,CAAA,EAAG,UAAU,CAAA,CAAE,CAAA;AAAA,EAChE;AAKA,EAAA,IAAI,MAAM,cAAA,EAAgB;AACxB,IAAA,MAAM,OAAA,mBAAU,IAAI,GAAA,CAAY,CAAC,OAAO,CAAC,CAAA;AACzC,IAAA,IAAI,KAAA,CAAM,MAAA,CAAO,KAAA,EAAO,OAAA,CAAQ,IAAI,OAAO,CAAA;AAC3C,IAAA,IAAI,KAAA,CAAM,MAAA,CAAO,KAAA,EAAO,OAAA,CAAQ,IAAI,OAAO,CAAA;AAC3C,IAAA,KAAA,MAAW,GAAA,IAAO,MAAM,cAAA,EAAgB;AACtC,MAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,IAAA,EAAK,CAAE,MAAM,KAAK,CAAA,CAAE,CAAC,CAAE,CAAA,EAAG;AAC9C,MAAA,KAAA,CAAM,KAAK,GAAG,CAAA;AAAA,IAChB;AAAA,EACF;AAEA,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA;AAC5B;AAEA,SAAS,WAAA,CAAY,EAAA,EAAkB,IAAA,EAAc,QAAA,EAAkB,MAAA,EAAwB;AAC7F,EAAA,MAAM,IAAI,EAAA,CAAG,QAAA;AACb,EAAA,QAAQ,GAAG,WAAA;AAAa,IACtB,KAAK,OAAA;AAAA,IACL,KAAK,SAAA;AAAA,IACL,KAAK,OAAA;AAAA,IACL,KAAK,WAAA;AAAA,IACL,KAAK,QAAA;AAAA,IACL,KAAK,WAAA;AAAA,IACL,KAAK,UAAA;AAAA,IACL,KAAK,SAAA;AAEH,MAAA,OAAO,CAAA,EAAG,GAAG,WAAW,CAAA,CAAA,EAAI,IAAI,CAAA,EAAA,EAAK,CAAA,CAAE,CAAA,CAAE,CAAC,CAAC,CAAA,EAAA,EAAK,EAAE,CAAA,CAAE,CAAC,CAAC,CAAA,CAAA,EAAI,WAAA,CAAY,EAAE,CAAC,CAAA,EAAG,QAAQ,CAAA,EAAG,MAAM,CAAA,CAAA;AAAA,IAC/F,KAAK,MAAA,EAAQ;AAMX,MAAA,MAAM,IAAA,GAAO,EAAA,CAAG,IAAA,GAAO,CAAA,OAAA,EAAU,EAAE,EAAA,CAAG,IAAA,CAAK,KAAK,CAAC,IAAI,CAAA,CAAE,EAAA,CAAG,IAAA,CAAK,MAAM,CAAC,CAAA,CAAA,CAAA,GAAM,EAAA;AAC5E,MAAA,OAAO,CAAA,KAAA,EAAQ,UAAA,CAAW,IAAI,CAAC,CAAA,EAAA,EAAK,EAAE,CAAA,CAAE,CAAC,CAAC,CAAA,EAAA,EAAK,CAAA,CAAE,CAAA,CAAE,CAAC,CAAC,CAAA,CAAA,EAAI,WAAA,CAAY,EAAE,CAAC,CAAA,EAAG,IAAI,CAAA,EAAG,WAAA,CAAY,EAAE,CAAC,CAAA,EAAG,MAAM,CAAA,CAAA;AAAA,IAC5G;AAAA,IACA,KAAK,SAAA,EAAW;AAEd,MAAA,MAAM,MAAM,EAAA,CAAG,MAAA,CAAO,IAAI,CAAC,CAAA,KAAM,IAAI,CAAA,CAAE,CAAA,CAAE,CAAC,CAAC,CAAA,EAAA,EAAK,EAAE,CAAA,CAAE,CAAC,CAAC,CAAA,CAAA,CAAG,CAAA,CAAE,KAAK,IAAI,CAAA;AACpE,MAAA,MAAM,MAAA,GAAS,EAAA,CAAG,MAAA,GAAS,WAAA,GAAc,EAAA;AACzC,MAAA,MAAM,MAAA,GAAS,GAAG,WAAA,IAAe,EAAA,CAAG,gBAAgB,OAAA,GAAU,CAAA,EAAA,EAAK,EAAA,CAAG,WAAW,CAAA,CAAA,CAAA,GAAM,EAAA;AACvF,MAAA,OAAO,CAAA,MAAA,EAAS,GAAG,CAAA,CAAA,EAAI,MAAM,GAAG,MAAM,CAAA,EAAG,WAAA,CAAY,EAAE,CAAC,CAAA,CAAA;AAAA,IAC1D;AAAA;AAEJ","file":"index.cjs","sourcesContent":["/**\n * Small, line-oriented helpers for the Event Storming `.storm` DSL.\n * The DSL is line-based; a full tokenizer/generator is not needed.\n */\n\nexport interface ParsedCoords {\n readonly a: number;\n readonly b: number;\n}\n\nconst COORDS_RE = /\\[\\s*([-\\d.]+)\\s*,\\s*([-\\d.]+)\\s*\\]/;\n\n/** Order stays raw (a, b). */\nexport function parseCoords(line: string): ParsedCoords | null {\n const m = COORDS_RE.exec(line);\n if (!m) return null;\n const a = Number(m[1]);\n const b = Number(m[2]);\n if (Number.isNaN(a) || Number.isNaN(b)) return null;\n return { a, b };\n}\n\n/**\n * Splits a line at the first `[a, b]` tuple: name before, suffix after.\n * Extras like `(color …)` may then only be looked up in the suffix — parentheses\n * inside the name stay untouched.\n */\nexport function splitAtCoords(\n line: string,\n): { name: string; coords: ParsedCoords; suffix: string } | null {\n const m = COORDS_RE.exec(line);\n if (!m) return null;\n const a = Number(m[1]);\n const b = Number(m[2]);\n if (Number.isNaN(a) || Number.isNaN(b)) return null;\n return {\n name: line.slice(0, m.index).trim(),\n coords: { a, b },\n suffix: line.slice(m.index + m[0].length),\n };\n}\n\n// `[^[\\]]` (tuples cannot contain '[') + bounded whitespace keep the scan linear (ReDoS-safe).\nconst MULTI_COORDS_RE = /\\[\\s{0,8}(\\[[^[\\]]*\\](?:\\s{0,8},\\s{0,8}\\[[^[\\]]*\\])+)\\s{0,8}\\]/;\n\n/** Extracts a tuple list `[[a,b],[c,d],…]` (freeform `line` drawing) — or null. */\nexport function parseMultiCoords(line: string): { tuples: ParsedCoords[]; rest: string } | null {\n const m = MULTI_COORDS_RE.exec(line);\n if (!m) return null;\n const tuples: ParsedCoords[] = [];\n const inner = /\\[\\s{0,8}([-\\d.]+)\\s{0,8},\\s{0,8}([-\\d.]+)\\s{0,8}\\]/g;\n let t: RegExpExecArray | null;\n while ((t = inner.exec(m[1]!))) {\n const a = Number(t[1]);\n const b = Number(t[2]);\n if (!Number.isNaN(a) && !Number.isNaN(b)) tuples.push({ a, b });\n }\n if (!tuples.length) return null;\n return { tuples, rest: line.replace(MULTI_COORDS_RE, ' ') };\n}\n\n/**\n * Splits off a `//` line comment. Quote-aware (`'//weird'` inside quotes stays untouched) and\n * URL-aware: `//` directly after `:` is a scheme separator (`https://…`), not a comment.\n */\nexport function splitLineComment(line: string): { code: string; comment: string | null } {\n let inQuote = false;\n for (let i = 0; i < line.length - 1; i++) {\n const ch = line[i];\n if (ch === \"'\") inQuote = !inQuote;\n else if (!inQuote && ch === '/' && line[i + 1] === '/' && line[i - 1] !== ':') {\n return { code: line.slice(0, i), comment: line.slice(i) };\n }\n }\n return { code: line, comment: null };\n}\n\n/** First occurrence of `needle` outside `'…'` quotes — or -1. */\nexport function indexOfOutsideQuotes(line: string, needle: string): number {\n let inQuote = false;\n for (let i = 0; i + needle.length <= line.length; i++) {\n const ch = line[i];\n if (ch === \"'\") {\n inQuote = !inQuote;\n continue;\n }\n if (!inQuote && line.startsWith(needle, i)) return i;\n }\n return -1;\n}\n\n// Color override extension: `(color #rrggbb)` OR `(color green)`. Deliberately placed after\n// the coordinates so parentheses inside sticky names are never mistaken for it.\n// Accepts hex or CSS color names.\nconst COLOR_RE = /\\(\\s*color\\s+(#[0-9a-fA-F]{3,8}|[a-zA-Z][\\w-]*)\\s*\\)/i;\n\nexport function parseColor(line: string): { color?: string; rest: string } {\n const m = COLOR_RE.exec(line);\n if (!m || !m[1]) return { rest: line };\n return { color: m[1], rest: line.replace(COLOR_RE, ' ') };\n}\n\n// Attachment extension: `(on <Host Name>)` — canonically the LAST suffix. The host name runs\n// up to the line's FINAL ')', so names may themselves contain parentheses (`Payment (retry)`).\n// Extracted BEFORE the other suffixes so a `(color …)` or `(size …)` inside a host name is\n// never mistaken for one.\nconst ON_RE = /\\(\\s*on\\s+/i;\n\nexport function parseOn(line: string): { host?: string; rest: string } {\n const m = ON_RE.exec(line);\n if (!m) return { rest: line };\n const start = m.index + m[0].length;\n const close = line.lastIndexOf(')');\n if (close < start) return { rest: line };\n const host = line.slice(start, close).trim();\n if (!host) return { rest: line };\n return { host, rest: `${line.slice(0, m.index)} ${line.slice(close + 1)}` };\n}\n\n// Internal-id extension: `(id <id>)` — emitted on sticky lines only when the name alone would\n// be ambiguous. The charset is deliberately tight (letters/digits/underscore/hyphen) so an id\n// can never collide with the line grammar (`)`/whitespace/`#` are all illegal).\nexport const ID_CHARSET_RE = /^[A-Za-z0-9_-]+$/;\n\nconst ID_RE = /\\(\\s*id\\s+([A-Za-z0-9_-]+)\\s*\\)/i;\n\n// Any `(id …)` group — catches malformed variants so the caller can report a diagnostic.\nconst ID_PRESENT_RE = /\\(\\s*id\\b[^)]*\\)/i;\n\nexport function parseId(line: string): {\n id?: string;\n /** The matched `(id …)` text when present but unreadable (illegal charset). */\n invalid?: string;\n rest: string;\n} {\n const m = ID_RE.exec(line);\n if (m?.[1]) return { id: m[1], rest: line.replace(ID_RE, ' ') };\n const p = ID_PRESENT_RE.exec(line);\n if (!p) return { rest: line };\n return { invalid: p[0], rest: line.replace(ID_PRESENT_RE, ' ') };\n}\n\n// Resize extension: `(size <w>x<h>)` — canonically the last suffix before `(on …)` on note\n// lines. The serializer emits no spaces around the `x`; the parser tolerates optional whitespace.\n// Deliberately looked up only after the coordinates so `(size 1x1)` inside note text survives.\nconst SIZE_RE = /\\(\\s*size\\s+([\\d.]+)\\s*x\\s*([\\d.]+)\\s*\\)/i;\n\n// Any `(size …)` group — catches malformed variants so the caller can report a diagnostic.\nconst SIZE_PRESENT_RE = /\\(\\s*size\\b[^)]*\\)/i;\n\nexport function parseSize(line: string): {\n size?: { width: number; height: number };\n /** The matched `(size …)` text when present but unreadable (malformed or non-positive). */\n invalid?: string;\n rest: string;\n} {\n const m = SIZE_RE.exec(line);\n if (m) {\n const width = Number(m[1]);\n const height = Number(m[2]);\n // Non-positive (or NaN from e.g. `1.2.3`) falls through to the malformed branch.\n if (width > 0 && height > 0) {\n return { size: { width, height }, rest: line.replace(SIZE_RE, ' ') };\n }\n }\n const p = SIZE_PRESENT_RE.exec(line);\n if (!p) return { rest: line };\n return { invalid: p[0], rest: line.replace(SIZE_PRESENT_RE, ' ') };\n}\n\n// Alignment extension: `(align <horizontal> <vertical>)` — canonically between `(size …)` and\n// `(on …)` on note lines, both words always present. Values are matched case-insensitively and\n// canonicalized to lowercase. Deliberately looked up only after the coordinates so an\n// `(align center middle)` inside note text survives.\nconst ALIGN_RE = /\\(\\s*align\\s+(left|center|right)\\s+(top|middle|bottom)\\s*\\)/i;\n\n// Any `(align …)` group — catches malformed variants so the caller can report a diagnostic.\nconst ALIGN_PRESENT_RE = /\\(\\s*align\\b[^)]*\\)/i;\n\nexport function parseAlign(line: string): {\n align?: {\n horizontal: 'left' | 'center' | 'right';\n vertical: 'top' | 'middle' | 'bottom';\n };\n /** The matched `(align …)` text when present but unreadable (unknown/missing axis words). */\n invalid?: string;\n rest: string;\n} {\n const m = ALIGN_RE.exec(line);\n if (m) {\n return {\n align: {\n horizontal: m[1]!.toLowerCase() as 'left' | 'center' | 'right',\n vertical: m[2]!.toLowerCase() as 'top' | 'middle' | 'bottom',\n },\n rest: line.replace(ALIGN_RE, ' '),\n };\n }\n const p = ALIGN_PRESENT_RE.exec(line);\n if (!p) return { rest: line };\n return { invalid: p[0], rest: line.replace(ALIGN_PRESENT_RE, ' ') };\n}\n\n/** First word (keyword) of a line, lowercased. */\nexport function keywordOf(line: string): string {\n const m = /^\\s*([A-Za-z][\\w-]*)/.exec(line);\n return m ? m[1]!.toLowerCase() : '';\n}\n\nexport function slug(label: string): string {\n return (\n label\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/^_/, '')\n .replace(/_$/, '') || 'x'\n );\n}\n","import {\n ATTACHABLE_STICKY_KINDS,\n CURRENT_SCHEMA_VERSION,\n HOST_STICKY_KINDS,\n validateBoard,\n type BoardConfig,\n type BoardEdge,\n type BoardLevel,\n type BoardElement,\n type Coordinate,\n type DrawingElement,\n type DrawingStrokeStyle,\n type ElementType,\n type EventStormingBoard,\n type NoteAlign,\n type NoteAlignHorizontal,\n type NoteAlignVertical,\n type NoteElement,\n} from '@miragon/event-storming-schema-model';\nimport {\n indexOfOutsideQuotes,\n keywordOf,\n parseAlign,\n parseColor,\n parseCoords,\n parseId,\n parseMultiCoords,\n parseOn,\n parseSize,\n slug,\n splitAtCoords,\n splitLineComment,\n} from './lexer.js';\n\n/** Splits `A -> B` at the FIRST arrow — plain indexOf, immune to regex backtracking. */\nfunction splitArrow(core: string): { left: string; right: string } | null {\n const arrow = core.indexOf('->');\n if (arrow <= 0) return null;\n const left = core.slice(0, arrow).trim();\n const right = core.slice(arrow + 2).trim();\n return left && right ? { left, right } : null;\n}\n\nconst KNOWN_STYLES: ReadonlySet<string> = new Set(['classic', 'dark']);\n\nconst ATTACHABLE_KINDS: ReadonlySet<string> = new Set(ATTACHABLE_STICKY_KINDS);\n\nconst HOST_KINDS: ReadonlySet<string> = new Set(HOST_STICKY_KINDS);\n\nconst KNOWN_LEVELS: ReadonlySet<string> = new Set(['big-picture', 'process', 'design']);\n\n/** Undoes the serializer's `\\n` name escaping (line-based DSL, multi-line labels). */\nfunction decodeName(name: string): string {\n return name.replace(/\\\\n/g, '\\n');\n}\n\n/** Sticky keywords double as `elementType` values; the value is the ID prefix. */\nconst STICKY_ID_PREFIXES: Readonly<Partial<Record<ElementType, string>>> = {\n event: 'event',\n command: 'cmd',\n actor: 'actor',\n aggregate: 'agg',\n policy: 'policy',\n readmodel: 'read',\n external: 'ext',\n hotspot: 'hot',\n};\n\n// The 8 sticky kinds — the only legal arrow endpoints (mirrors validateBoard's contract).\nconst STICKY_KINDS: ReadonlySet<string> = new Set(Object.keys(STICKY_ID_PREFIXES));\n\ninterface PendingArrow {\n readonly left: string;\n readonly right: string;\n /** Annotation text after `;`. */\n readonly label?: string;\n readonly raw: string;\n readonly lineNo: number;\n}\n\n/** `(on …)` attachment — host referenced BY NAME, resolution deferred like arrow endpoints. */\ninterface PendingAttachment {\n /** Index into `elements` of the attachable sticky. */\n readonly index: number;\n readonly host: string;\n readonly raw: string;\n readonly lineNo: number;\n}\n\nfunction compact<T extends Record<string, unknown>>(obj: T): T {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) if (v !== undefined) out[k] = v;\n return out as T;\n}\n\n/**\n * Text `(align <h> <v>)` pair -> model value: default axes (left/top) are dropped, both-default\n * collapses to absent — `(align left top)` and no suffix are the same board (the serializer\n * emits the suffix only when an axis differs from the default).\n */\nfunction modelAlign(\n align: { horizontal: NoteAlignHorizontal; vertical: NoteAlignVertical } | undefined,\n): NoteAlign | undefined {\n if (!align) return undefined;\n const out = compact({\n horizontal: align.horizontal === 'left' ? undefined : align.horizontal,\n vertical: align.vertical === 'top' ? undefined : align.vertical,\n }) as NoteAlign;\n return Object.keys(out).length ? out : undefined;\n}\n\n/** Finding produced while parsing — line is 1-based; `text` is the (comment-stripped) line. */\nexport interface ParseDiagnostic {\n readonly line: number;\n readonly message: string;\n readonly text: string;\n}\n\nexport interface ParseResult {\n readonly board: EventStormingBoard;\n readonly diagnostics: readonly ParseDiagnostic[];\n}\n\nclass IdAllocator {\n private readonly used = new Set<string>();\n /** Explicit `(id …)` — false when the id is already taken (caller reports + allocates). */\n claim(id: string): boolean {\n if (this.used.has(id)) return false;\n this.used.add(id);\n return true;\n }\n alloc(prefix: string, label: string): string {\n const base = `${prefix}_${slug(label)}`;\n let id = base;\n let i = 2;\n while (this.used.has(id)) id = `${base}_${i++}`;\n this.used.add(id);\n return id;\n }\n}\n\n/**\n * Line-based keyword parsing; coordinates are `[x, y]` in board pixels (x FIRST), unbounded,\n * optional (default `[0, 0]`). Unknown lines land in `rawPassthrough`.\n */\nexport function parseDSL(text: string): EventStormingBoard {\n return parseDSLWithDiagnostics(text).board;\n}\n\n/**\n * Like `parseDSL`, but additionally returns findings with line numbers (uninterpretable lines,\n * unresolved references) — for editor feedback instead of silent loss.\n */\nexport function parseDSLWithDiagnostics(text: string): ParseResult {\n const diagnostics: ParseDiagnostic[] = [];\n const ids = new IdAllocator();\n const nameToId = new Map<string, string>();\n const elements: BoardElement[] = [];\n const rawPassthrough: string[] = [];\n const pendingArrows: PendingArrow[] = [];\n const pendingAttachments: PendingAttachment[] = [];\n\n let config: BoardConfig = { title: 'Untitled Board' };\n let inBlockComment = false;\n\n const register = (name: string, id: string) => {\n if (!nameToId.has(name)) nameToId.set(name, id);\n };\n\n // Diagnostics helpers: read the current line/number from the loop state.\n let lineNo = 0;\n let currentLine = '';\n\n /** Tries to capture a line as an arrow. Returns true when consumed. */\n const pushArrow = (line: string): boolean => {\n // Split off an optional arrow annotation after ';' (e.g. `A -> B; async`).\n const semi = line.indexOf(';');\n const core = semi >= 0 ? line.slice(0, semi).trim() : line;\n const arrowLabel = semi >= 0 ? line.slice(semi + 1).trim() : '';\n const arrow = splitArrow(core);\n if (!arrow) return false;\n pendingArrows.push({\n left: arrow.left,\n right: arrow.right,\n ...(arrowLabel ? { label: arrowLabel } : {}),\n raw: line,\n lineNo,\n });\n return true;\n };\n const diag = (message: string, atLine = lineNo, text_ = currentLine) =>\n diagnostics.push({ line: atLine, message, text: text_ });\n /** Passthrough for a line that looks like a known construct but cannot be parsed. */\n const failed = (l: string) => {\n rawPassthrough.push(l);\n diag('Line could not be interpreted (kept losslessly in rawPassthrough)');\n };\n /** Board pixels, unbounded — no clamping on the free canvas. */\n const pos = (x: number, y: number): Coordinate => ({ x, y });\n\n const sourceLines = text.split(/\\r?\\n/);\n for (let i = 0; i < sourceLines.length; i++) {\n const raw = sourceLines[i]!;\n lineNo = i + 1;\n currentLine = raw.trim();\n let working = raw;\n\n // --- Comments (`//`, `/* */`): strip, but keep losslessly in rawPassthrough. ---\n if (inBlockComment) {\n const close = working.indexOf('*/');\n if (close < 0) {\n rawPassthrough.push(raw);\n continue;\n }\n rawPassthrough.push(working.slice(0, close + 2));\n working = working.slice(close + 2);\n inBlockComment = false;\n }\n let open = indexOfOutsideQuotes(working, '/*');\n while (open >= 0) {\n const close = working.indexOf('*/', open + 2);\n if (close < 0) {\n rawPassthrough.push(working.slice(open));\n working = working.slice(0, open);\n inBlockComment = true;\n break;\n }\n rawPassthrough.push(working.slice(open, close + 2));\n working = `${working.slice(0, open)} ${working.slice(close + 2)}`;\n open = indexOfOutsideQuotes(working, '/*');\n }\n const { code, comment } = splitLineComment(working);\n if (comment !== null) rawPassthrough.push(comment);\n working = code;\n\n const line = working.trim();\n if (!line) continue;\n\n const kw = keywordOf(line);\n const after = line.slice(kw.length).trim();\n\n // Arrows FIRST: sticky NAMES may begin with a keyword word (the default command is\n // named \"Command\" -> arrow `Command -> X`). Declarations carry coordinates `[...]`,\n // arrows never do — but only the part BEFORE the `;` annotation counts, the annotation\n // is free text and may contain a tuple. Without this pre-detection `Command -> X` would\n // be misread as a (broken) `command` declaration and vanish on re-import. `title` is\n // exempt (its content may itself use `->`) UNLESS the left side is an already-declared\n // sticky name (e.g. one named \"Title Page\" — declarations always precede arrows in\n // serialized DSL). `style`/`level`/`line` need no exemption: style and level values are\n // single words and drawings always carry coordinate tuples.\n const semi = line.indexOf(';');\n const beforeAnnotation = semi >= 0 ? line.slice(0, semi) : line;\n const titleAsArrow = (): boolean => {\n const arrow = splitArrow(beforeAnnotation.trim());\n return arrow !== null && nameToId.has(decodeName(arrow.left));\n };\n if ((kw !== 'title' || titleAsArrow()) && !parseCoords(beforeAnnotation) && pushArrow(line)) {\n continue;\n }\n\n switch (kw) {\n case 'title':\n config = { ...config, title: after };\n break;\n\n case 'style': {\n const s = after.toLowerCase();\n if (KNOWN_STYLES.has(s)) config = { ...config, style: s as 'classic' | 'dark' };\n else failed(line);\n break;\n }\n\n case 'level': {\n const l = after.toLowerCase();\n if (KNOWN_LEVELS.has(l)) config = { ...config, level: l as BoardLevel };\n else failed(line);\n break;\n }\n\n case 'event':\n case 'command':\n case 'actor':\n case 'aggregate':\n case 'policy':\n case 'readmodel':\n case 'external':\n case 'hotspot': {\n const node = parseSticky(after);\n if (!node) {\n failed(line);\n break;\n }\n if (node.idInvalid) {\n diag(\n `Id: could not read \"${node.idInvalid.trim()}\" — expected (id <id>) with letters, digits, '_' or '-'`,\n );\n }\n const explicit = node.id !== undefined && ids.claim(node.id) ? node.id : undefined;\n if (node.id !== undefined && explicit === undefined) {\n diag(`Id: \"${node.id}\" is already taken — the element got a fresh id`);\n }\n const id = explicit ?? ids.alloc(STICKY_ID_PREFIXES[kw as ElementType]!, node.name);\n elements.push(\n compact({\n id,\n elementType: kw as ElementType,\n label: node.name,\n position: pos(node.coords.x, node.coords.y),\n color: node.color,\n }) as BoardElement,\n );\n register(node.name, id);\n if (node.host !== undefined) {\n if (ATTACHABLE_KINDS.has(kw)) {\n pendingAttachments.push({\n index: elements.length - 1,\n host: node.host,\n raw: line,\n lineNo,\n });\n } else {\n diag(`Attachment: a ${kw} cannot be pinned — only actor/hotspot/note support (on …)`);\n }\n }\n if (node.sizeSuffix) {\n diag(`Size: a ${kw} cannot be resized — only notes support (size …)`);\n }\n if (node.alignSuffix) {\n diag(`Align: a ${kw} cannot be aligned — only notes support (align …)`);\n }\n break;\n }\n\n case 'note': {\n const split = splitAtCoords(after);\n if (!split && after.includes('[')) {\n failed(line);\n break;\n }\n // Suffixes ONLY after the coordinates (mirrors parseSticky) — notes are free text, so\n // `(on …)`, `(color …)` or `(size 1x1)` may legitimately appear inside it. `(on …)` is\n // stripped FIRST: it is always the last suffix and its host name runs to the final `)`,\n // so it may itself contain a `(color …)`, `(size …)` or `(align …)`.\n const on = parseOn(split ? split.suffix : after);\n const al = parseAlign(on.rest);\n const sz = parseSize(al.rest);\n const idp = parseId(sz.rest);\n const col = parseColor(idp.rest);\n if (al.invalid) {\n diag(\n `Align: could not read \"${al.invalid.trim()}\" — expected (align left|center|right top|middle|bottom)`,\n );\n }\n if (sz.invalid) {\n diag(\n `Size: could not read \"${sz.invalid.trim()}\" — expected (size <w>x<h>) with positive numbers`,\n );\n }\n if (idp.id !== undefined || idp.invalid) {\n diag('Id: a note cannot be referenced — only sticky kinds support (id …)');\n }\n // Literal `\\n` back into real line breaks (multi-line notes).\n const textPart = decodeName((split ? split.name : col.rest).trim());\n const id = ids.alloc('note', textPart || 'note');\n const note: NoteElement = compact({\n id,\n elementType: 'note',\n label: textPart,\n position: split ? pos(split.coords.a, split.coords.b) : pos(0, 0),\n color: col.color,\n size: sz.size,\n align: modelAlign(al.align),\n }) as NoteElement;\n elements.push(note);\n if (on.host !== undefined) {\n pendingAttachments.push({ index: elements.length - 1, host: on.host, raw: line, lineNo });\n }\n break;\n }\n\n case 'line': {\n // Project extension (freeform drawing): `line [[x,y], [x,y], …] (closed) (dashed) (color x)`.\n const col = parseColor(after);\n const multi = parseMultiCoords(col.rest);\n if (!multi || multi.tuples.length < 2) {\n failed(line);\n break;\n }\n const onDrawing = parseOn(multi.rest);\n if (onDrawing.host !== undefined) {\n diag('Attachment: a drawing cannot be pinned — only actor/hotspot/note support (on …)');\n }\n const szDrawing = parseSize(onDrawing.rest);\n if (szDrawing.size || szDrawing.invalid) {\n diag('Size: a drawing cannot be resized — only notes support (size …)');\n }\n const alDrawing = parseAlign(onDrawing.rest);\n if (alDrawing.align || alDrawing.invalid) {\n diag('Align: a drawing cannot be aligned — only notes support (align …)');\n }\n const idDrawing = parseId(onDrawing.rest);\n if (idDrawing.id !== undefined || idDrawing.invalid) {\n diag('Id: a drawing cannot be referenced — only sticky kinds support (id …)');\n }\n const flags = onDrawing.rest.toLowerCase();\n const strokeStyle: DrawingStrokeStyle | undefined = flags.includes('(dashed)')\n ? 'dashed'\n : flags.includes('(dotted)')\n ? 'dotted'\n : undefined;\n const points = multi.tuples.map((t) => pos(t.a, t.b));\n const drawing: DrawingElement = {\n id: ids.alloc('draw', 'line'),\n elementType: 'drawing',\n label: '',\n position: points[0]!,\n points,\n ...(flags.includes('(closed)') ? { closed: true } : {}),\n ...(strokeStyle ? { strokeStyle } : {}),\n ...(col.color ? { color: col.color } : {}),\n };\n elements.push(drawing);\n break;\n }\n\n default: {\n // Unknown keyword: try as an arrow (e.g. `A -> B; async`), otherwise keep raw.\n if (!pushArrow(line)) rawPassthrough.push(line);\n }\n }\n }\n\n // Reference resolution for arrow endpoints and `(on …)` hosts: a `#`-prefixed token is an id\n // reference (ids exist for EVERY element, not only those declared with `(id …)`); anything\n // else stays a label lookup. No fallback across the two — `#` always means id.\n const resolve = (token: string): BoardElement | undefined => {\n if (token.startsWith('#')) {\n const id = token.slice(1);\n return elements.find((e) => e.id === id);\n }\n const id = nameToId.get(decodeName(token));\n return id !== undefined ? elements.find((e) => e.id === id) : undefined;\n };\n\n // Deferred like arrows so a host may be declared after its attacher. On failure the sticky\n // stays WITHOUT attachedTo (it was already created above) — no rawPassthrough, the line is\n // otherwise fully represented.\n for (const att of pendingAttachments) {\n const host = resolve(att.host);\n if (!host) {\n diag(`Attachment: \"${att.host}\" not found`, att.lineNo, att.raw);\n continue;\n }\n if (!HOST_KINDS.has(host.elementType)) {\n diag(\n `Attachment: \"${att.host}\" is a ${host.elementType} — actors/hotspots/notes may only attach to host stickies`,\n att.lineNo,\n att.raw,\n );\n continue;\n }\n elements[att.index] = { ...elements[att.index]!, attachedTo: host.id } as BoardElement;\n }\n\n let arrowN = 0;\n // An explicit `(id arrow_N)` on a sticky may occupy an arrow-id slot — skip it (diagram-js\n // has ONE id namespace for shapes and connections; validateBoard rejects the collision).\n const elementIds = new Set(elements.map((e) => e.id));\n const nextArrowId = (): string => {\n let id = `arrow_${++arrowN}`;\n while (elementIds.has(id)) id = `arrow_${++arrowN}`;\n return id;\n };\n const edges: BoardEdge[] = [];\n for (const arrow of pendingArrows) {\n const from = resolve(arrow.left);\n const to = resolve(arrow.right);\n if (!from || !to) {\n rawPassthrough.push(arrow.raw);\n diag(\n `Arrow: ${!from ? `\"${arrow.left}\"` : `\"${arrow.right}\"`} not found`,\n arrow.lineNo,\n arrow.raw,\n );\n continue;\n }\n // Only reachable via `#id` refs (labels are registered for sticky kinds only) — an edge to\n // a note/drawing would make validateBoard throw, so it is dropped losslessly instead.\n const nonSticky = !STICKY_KINDS.has(from.elementType)\n ? ([arrow.left, from] as const)\n : !STICKY_KINDS.has(to.elementType)\n ? ([arrow.right, to] as const)\n : undefined;\n if (nonSticky) {\n rawPassthrough.push(arrow.raw);\n diag(\n `Arrow: \"${nonSticky[0]}\" is a ${nonSticky[1].elementType} — arrows may only connect stickies`,\n arrow.lineNo,\n arrow.raw,\n );\n continue;\n }\n edges.push(\n compact({\n id: nextArrowId(),\n edgeType: 'arrow',\n from: from.id,\n to: to.id,\n label: arrow.label,\n }) as BoardEdge,\n );\n }\n\n const board = compact({\n schemaVersion: CURRENT_SCHEMA_VERSION,\n config,\n elements,\n edges,\n rawPassthrough: rawPassthrough.length ? rawPassthrough : undefined,\n }) as EventStormingBoard;\n\n return { board: validateBoard(board), diagnostics };\n}\n\ninterface ParsedSticky {\n readonly name: string;\n readonly coords: { x: number; y: number };\n /** Color override `(color …)` — supported on every element line. */\n readonly color?: string;\n /** Attachment `(on <Host Name>)` — host name still undecoded, resolved by the caller. */\n readonly host?: string;\n /** Explicit `(id …)` — the caller claims it (duplicate ⇒ diagnostic + fresh id). */\n readonly id?: string;\n /** The matched `(id …)` text when present but unreadable (illegal charset). */\n readonly idInvalid?: string;\n /** A `(size …)` suffix appeared — only notes support it, the caller reports a diagnostic. */\n readonly sizeSuffix?: boolean;\n /** An `(align …)` suffix appeared — only notes support it, the caller reports a diagnostic. */\n readonly alignSuffix?: boolean;\n}\n\n/**\n * Parses `<name> [x, y] [(color …)] [(id …)] [(on …)]`. The suffixes are looked up ONLY AFTER\n * the coordinates — parentheses inside the name stay untouched. `(on …)` is extracted first\n * (its host name runs to the final `)` and may itself contain a `(color …)`, `(id …)` or\n * `(size …)`). Coordinates are optional and default to `[0, 0]`; a malformed tuple (bracket\n * present but unreadable) is rejected so the caller can report a diagnostic instead of\n * swallowing it into the name.\n */\nfunction parseSticky(after: string): ParsedSticky | null {\n const split = splitAtCoords(after);\n if (split) {\n if (!split.name) return null;\n const on = parseOn(split.suffix);\n const idp = parseId(on.rest);\n const al = parseAlign(idp.rest);\n const sz = parseSize(al.rest);\n const col = parseColor(sz.rest);\n return compact({\n name: decodeName(split.name),\n coords: { x: split.coords.a, y: split.coords.b },\n color: col.color ?? undefined,\n host: on.host,\n id: idp.id,\n idInvalid: idp.invalid,\n sizeSuffix: sz.size || sz.invalid ? true : undefined,\n alignSuffix: al.align || al.invalid ? true : undefined,\n }) as ParsedSticky;\n }\n if (after.includes('[')) return null;\n const on = parseOn(after);\n const idp = parseId(on.rest);\n const al = parseAlign(idp.rest);\n const sz = parseSize(al.rest);\n const col = parseColor(sz.rest);\n const name = col.rest.trim();\n if (!name) return null;\n return compact({\n name: decodeName(name),\n coords: { x: 0, y: 0 },\n color: col.color ?? undefined,\n host: on.host,\n id: idp.id,\n idInvalid: idp.invalid,\n sizeSuffix: sz.size || sz.invalid ? true : undefined,\n alignSuffix: al.align || al.invalid ? true : undefined,\n }) as ParsedSticky;\n}\n","import type {\n BoardElement,\n EventStormingBoard,\n NoteElement,\n} from '@miragon/event-storming-schema-model';\nimport { ID_CHARSET_RE, slug } from './lexer.js';\n\n/**\n * Coordinate formatter: 3-decimal rounding, NEVER exponent notation — `String(1e21)` yields\n * `\"1e+21\"`, which the coordinate regex cannot read back. Magnitudes >= 1e21 are always\n * integer-valued doubles, so BigInt expands them losslessly (the rounding step is skipped\n * there; it would be a no-op and could overflow to Infinity for huge values).\n */\nfunction r(n: number): string {\n const v = Math.abs(n) < 1e21 ? Math.round(n * 1000) / 1000 : n;\n return Math.abs(v) < 1e21 ? String(v) : BigInt(v).toString();\n}\n\n/**\n * Free text emitted into the line-based grammar: real line breaks become the literal `\\n`\n * escape (decoded on parse) and comment starters are defused with the Unicode division slash\n * — otherwise the parser would split the line or strip the rest as a comment. `//` directly\n * after `:` stays untouched (URL scheme separator, the comment splitter is URL-aware).\n */\nfunction escapeText(label: string): string {\n return label\n .trim()\n .replace(/\\n/g, '\\\\n')\n .replace(/(?<!:)\\/\\//g, '∕∕')\n .replace(/\\/\\*/g, '∕*');\n}\n\n/** Names are additionally arrow-safe: a literal `->` inside a name would break `A -> B` lines. */\nfunction escapeName(label: string): string {\n return escapeText(label).replace(/->/g, '→');\n}\n\n/** Types referenced BY THEIR NAME in the DSL (arrow endpoints + namespace) — all sticky kinds. */\nconst NAMED_TYPES: ReadonlySet<string> = new Set([\n 'event',\n 'command',\n 'actor',\n 'aggregate',\n 'policy',\n 'readmodel',\n 'external',\n 'hotspot',\n]);\n\nconst DEFAULT_NAMES: Readonly<Record<string, string>> = {\n event: 'Domain Event',\n command: 'Command',\n actor: 'Actor',\n aggregate: 'Aggregate',\n policy: 'Policy',\n readmodel: 'Read Model',\n external: 'External System',\n hotspot: 'Hotspot',\n};\n\nfunction defaultName(type: string): string {\n return DEFAULT_NAMES[type] ?? 'Sticky';\n}\n\n/**\n * Returns the DSL name per element ID for the referenceable types (the sticky kinds): the\n * escaped label, or the per-kind default for an empty one. Duplicate labels are legal — an\n * ambiguous name is disambiguated via an `(id …)` suffix plus `#id` references instead of\n * being silently renamed.\n */\nfunction serializedNames(board: EventStormingBoard): Map<string, string> {\n const byId = new Map<string, string>();\n for (const el of board.elements) {\n if (!NAMED_TYPES.has(el.elementType)) continue;\n byId.set(el.id, escapeName(el.label) || defaultName(el.elementType));\n }\n return byId;\n}\n\n/** Color override extension: `(color …)` after the coordinates. */\nfunction colorSuffix(el: { color?: string }): string {\n return el.color ? ` (color ${el.color})` : '';\n}\n\n/**\n * Alignment extension: `(align <horizontal> <vertical>)` — both words always emitted together\n * using the EFFECTIVE values, and only when at least one axis differs from the default\n * left/top, so existing boards serialize byte-identically.\n */\nfunction alignSuffix(el: NoteElement): string {\n const horizontal = el.align?.horizontal ?? 'left';\n const vertical = el.align?.vertical ?? 'top';\n return horizontal === 'left' && vertical === 'top' ? '' : ` (align ${horizontal} ${vertical})`;\n}\n\n/**\n * Serializes an EventStormingBoard into `.storm` text. Deterministic; writes only syntax the\n * parser reads back. `rawPassthrough` is appended unchanged. Coordinates are `[x, y]` in board\n * pixels (x FIRST), rounded to 3 decimals.\n */\nexport function serializeDSL(board: EventStormingBoard): string {\n const lines: string[] = [];\n const names = serializedNames(board);\n const nameOf = (el: BoardElement): string => names.get(el.id) ?? el.label;\n\n // A `#…` token in a reference position always reads as an id — so a sticky whose serialized\n // name is AMBIGUOUS (shared by >= 2 stickies) or literally starts with `#` is declared with\n // an `(id …)` suffix and referenced as `#id`. Everything else stays purely name-based, so\n // unambiguous boards serialize without any ids, byte-identical to before.\n const nameCount = new Map<string, number>();\n for (const name of names.values()) nameCount.set(name, (nameCount.get(name) ?? 0) + 1);\n const needsId = (id: string): boolean => {\n const name = names.get(id);\n return name !== undefined && (nameCount.get(name)! > 1 || name.startsWith('#'));\n };\n\n // Ids surface in the text only via needsId. An id outside the DSL id charset (possible in\n // JSON-authored boards) would emit unparsable syntax and lose the arrows on re-import — a\n // slug-based, collision-checked stand-in is substituted for the suffix AND every reference.\n const emitIds = new Map<string, string>();\n const taken = new Set(board.elements.map((e) => e.id));\n for (const el of board.elements) {\n if (!needsId(el.id) || ID_CHARSET_RE.test(el.id)) continue;\n let candidate = slug(el.id);\n for (let i = 2; taken.has(candidate); i++) candidate = `${slug(el.id)}_${i}`;\n taken.add(candidate);\n emitIds.set(el.id, candidate);\n }\n const idOf = (id: string): string => emitIds.get(id) ?? id;\n const ref = (id: string): string => (needsId(id) ? `#${idOf(id)}` : (names.get(id) ?? id));\n\n lines.push(`title ${board.config.title}`);\n if (board.config.style) lines.push(`style ${board.config.style}`);\n if (board.config.level) lines.push(`level ${board.config.level}`);\n\n // Pinning `(on …)` is ALWAYS the last suffix — the parser reads the host name up to the\n // line's final `)`, so host names containing parentheses survive. validateBoard guarantees\n // the host is a named sticky kind; `ref` falls back to the raw id purely defensively.\n const onSuffix = (el: BoardElement): string => {\n const hostId =\n el.elementType === 'actor' || el.elementType === 'hotspot' || el.elementType === 'note'\n ? el.attachedTo\n : undefined;\n return hostId ? ` (on ${ref(hostId)})` : '';\n };\n\n for (const el of board.elements) {\n const idSuffix = needsId(el.id) ? ` (id ${idOf(el.id)})` : '';\n lines.push(elementLine(el, nameOf(el), idSuffix, onSuffix(el)));\n }\n\n // validateBoard guarantees arrow endpoints are sticky kinds, so the name map always covers\n // them — `ref`'s raw-id fallback is purely defensive for unvalidated input.\n for (const edge of board.edges) {\n const annotation = edge.label ? `; ${edge.label}` : '';\n lines.push(`${ref(edge.from)} -> ${ref(edge.to)}${annotation}`);\n }\n\n // Config keywords were already emitted from the board above. A rawPassthrough entry with the\n // same keyword (e.g. an unparsable `style` line from externally-authored DSL) would otherwise\n // produce a contradictory duplicate line — drop it (config is the truth).\n if (board.rawPassthrough) {\n const emitted = new Set<string>(['title']);\n if (board.config.style) emitted.add('style');\n if (board.config.level) emitted.add('level');\n for (const raw of board.rawPassthrough) {\n if (emitted.has(raw.trim().split(/\\s+/)[0]!)) continue;\n lines.push(raw);\n }\n }\n\n return lines.join('\\n') + '\\n';\n}\n\nfunction elementLine(el: BoardElement, name: string, idSuffix: string, attach: string): string {\n const p = el.position;\n switch (el.elementType) {\n case 'event':\n case 'command':\n case 'actor':\n case 'aggregate':\n case 'policy':\n case 'readmodel':\n case 'external':\n case 'hotspot':\n // Canonical suffix order: `(color …) (id …) (on …)` — `(on …)` stays last (see above).\n return `${el.elementType} ${name} [${r(p.x)}, ${r(p.y)}]${colorSuffix(el)}${idSuffix}${attach}`;\n case 'note': {\n // Escape line breaks/comment starters -> the line-based DSL stays single-line. `->` is\n // fine in note text (notes are never arrow endpoints), so no `→` replacement here.\n // Canonical note suffix order: `(color …) (size WxH) (align h v) (on …)` — `(on …)`\n // stays last (final-paren rule, see above); size/align/attachment are only present when\n // set, so plain boards stay byte-identical.\n const size = el.size ? ` (size ${r(el.size.width)}x${r(el.size.height)})` : '';\n return `note ${escapeText(name)} [${r(p.x)}, ${r(p.y)}]${colorSuffix(el)}${size}${alignSuffix(el)}${attach}`;\n }\n case 'drawing': {\n // Project extension (freeform drawing): tuple list + style flags.\n const pts = el.points.map((q) => `[${r(q.x)}, ${r(q.y)}]`).join(', ');\n const closed = el.closed ? ' (closed)' : '';\n const stroke = el.strokeStyle && el.strokeStyle !== 'solid' ? ` (${el.strokeStyle})` : '';\n return `line [${pts}]${closed}${stroke}${colorSuffix(el)}`;\n }\n }\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { EventStormingBoard } from '@miragon/event-storming-schema-model';
|
|
2
|
+
export { parseBoardJSON as boardFromJSON, serializeBoard as boardToJSON, loadBoard } from '@miragon/event-storming-schema-model';
|
|
3
|
+
|
|
4
|
+
/** Finding produced while parsing — line is 1-based; `text` is the (comment-stripped) line. */
|
|
5
|
+
interface ParseDiagnostic {
|
|
6
|
+
readonly line: number;
|
|
7
|
+
readonly message: string;
|
|
8
|
+
readonly text: string;
|
|
9
|
+
}
|
|
10
|
+
interface ParseResult {
|
|
11
|
+
readonly board: EventStormingBoard;
|
|
12
|
+
readonly diagnostics: readonly ParseDiagnostic[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Line-based keyword parsing; coordinates are `[x, y]` in board pixels (x FIRST), unbounded,
|
|
16
|
+
* optional (default `[0, 0]`). Unknown lines land in `rawPassthrough`.
|
|
17
|
+
*/
|
|
18
|
+
declare function parseDSL(text: string): EventStormingBoard;
|
|
19
|
+
/**
|
|
20
|
+
* Like `parseDSL`, but additionally returns findings with line numbers (uninterpretable lines,
|
|
21
|
+
* unresolved references) — for editor feedback instead of silent loss.
|
|
22
|
+
*/
|
|
23
|
+
declare function parseDSLWithDiagnostics(text: string): ParseResult;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Serializes an EventStormingBoard into `.storm` text. Deterministic; writes only syntax the
|
|
27
|
+
* parser reads back. `rawPassthrough` is appended unchanged. Coordinates are `[x, y]` in board
|
|
28
|
+
* pixels (x FIRST), rounded to 3 decimals.
|
|
29
|
+
*/
|
|
30
|
+
declare function serializeDSL(board: EventStormingBoard): string;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Small, line-oriented helpers for the Event Storming `.storm` DSL.
|
|
34
|
+
* The DSL is line-based; a full tokenizer/generator is not needed.
|
|
35
|
+
*/
|
|
36
|
+
interface ParsedCoords {
|
|
37
|
+
readonly a: number;
|
|
38
|
+
readonly b: number;
|
|
39
|
+
}
|
|
40
|
+
/** Order stays raw (a, b). */
|
|
41
|
+
declare function parseCoords(line: string): ParsedCoords | null;
|
|
42
|
+
/** First word (keyword) of a line, lowercased. */
|
|
43
|
+
declare function keywordOf(line: string): string;
|
|
44
|
+
declare function slug(label: string): string;
|
|
45
|
+
|
|
46
|
+
export { type ParseDiagnostic, type ParseResult, type ParsedCoords, keywordOf, parseCoords, parseDSL, parseDSLWithDiagnostics, serializeDSL, slug };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { EventStormingBoard } from '@miragon/event-storming-schema-model';
|
|
2
|
+
export { parseBoardJSON as boardFromJSON, serializeBoard as boardToJSON, loadBoard } from '@miragon/event-storming-schema-model';
|
|
3
|
+
|
|
4
|
+
/** Finding produced while parsing — line is 1-based; `text` is the (comment-stripped) line. */
|
|
5
|
+
interface ParseDiagnostic {
|
|
6
|
+
readonly line: number;
|
|
7
|
+
readonly message: string;
|
|
8
|
+
readonly text: string;
|
|
9
|
+
}
|
|
10
|
+
interface ParseResult {
|
|
11
|
+
readonly board: EventStormingBoard;
|
|
12
|
+
readonly diagnostics: readonly ParseDiagnostic[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Line-based keyword parsing; coordinates are `[x, y]` in board pixels (x FIRST), unbounded,
|
|
16
|
+
* optional (default `[0, 0]`). Unknown lines land in `rawPassthrough`.
|
|
17
|
+
*/
|
|
18
|
+
declare function parseDSL(text: string): EventStormingBoard;
|
|
19
|
+
/**
|
|
20
|
+
* Like `parseDSL`, but additionally returns findings with line numbers (uninterpretable lines,
|
|
21
|
+
* unresolved references) — for editor feedback instead of silent loss.
|
|
22
|
+
*/
|
|
23
|
+
declare function parseDSLWithDiagnostics(text: string): ParseResult;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Serializes an EventStormingBoard into `.storm` text. Deterministic; writes only syntax the
|
|
27
|
+
* parser reads back. `rawPassthrough` is appended unchanged. Coordinates are `[x, y]` in board
|
|
28
|
+
* pixels (x FIRST), rounded to 3 decimals.
|
|
29
|
+
*/
|
|
30
|
+
declare function serializeDSL(board: EventStormingBoard): string;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Small, line-oriented helpers for the Event Storming `.storm` DSL.
|
|
34
|
+
* The DSL is line-based; a full tokenizer/generator is not needed.
|
|
35
|
+
*/
|
|
36
|
+
interface ParsedCoords {
|
|
37
|
+
readonly a: number;
|
|
38
|
+
readonly b: number;
|
|
39
|
+
}
|
|
40
|
+
/** Order stays raw (a, b). */
|
|
41
|
+
declare function parseCoords(line: string): ParsedCoords | null;
|
|
42
|
+
/** First word (keyword) of a line, lowercased. */
|
|
43
|
+
declare function keywordOf(line: string): string;
|
|
44
|
+
declare function slug(label: string): string;
|
|
45
|
+
|
|
46
|
+
export { type ParseDiagnostic, type ParseResult, type ParsedCoords, keywordOf, parseCoords, parseDSL, parseDSLWithDiagnostics, serializeDSL, slug };
|