{"version":3,"sources":["../src/loop-adapter.ts"],"names":[],"mappings":";;;;AA+DA,SAAS,sBAAA,CACP,KACA,OAAA,EACwB;AACxB,EAAA,MAAM,SAAS,OAAA,CAAQ,IAAA,GAAO,CAAA,CAAA,EAAI,OAAA,CAAQ,IAAI,CAAA,CAAA,GAAK,EAAA;AACnD,EAAA,MAAM,IAAA,GAAO,CAAC,OAAA,EAAiB,IAAA,EAAiB,YAC9C,IAAI,eAAA,CAAgB,SAAS,IAAA,EAAM,EAAE,OAAO,GAAA,EAAK,OAAA,EAAS,EAAE,SAAA,EAAW,OAAA,CAAQ,WAAW,GAAG,OAAA,IAAW,CAAA;AAE1G,EAAA,IAAI,eAAe,mBAAA,EAAqB;AACtC,IAAA,OAAO,IAAA,CAAK,CAAA,KAAA,EAAQ,OAAA,CAAQ,SAAS,CAAA,YAAA,EAAe,IAAI,OAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,SAAS,CAAA;AAAA,EACvF;AACA,EAAA,IAAI,eAAe,iBAAA,EAAmB;AAEpC,IAAA,OAAO,IAAA;AAAA,MACL,CAAA,cAAA,EAAiB,OAAA,CAAQ,SAAS,CAAA,2CAAA,EAA8C,MAAM,CAAA,CAAA;AAAA,MACtF,iBAAA;AAAA,MACA,EAAE,MAAA,EAAQ,GAAA,EAAK,QAAA,EAAU,IAAI,IAAA;AAAK,KACpC;AAAA,EACF;AACA,EAAA,IAAI,eAAe,oBAAA,EAAsB;AAGvC,IAAA,OAAO,IAAA;AAAA,MACL,QAAQ,OAAA,CAAQ,SAAS,kDAAkD,GAAA,CAAI,OAAO,GAAG,MAAM,CAAA,CAAA;AAAA,MAC/F,sBAAA;AAAA,MACA,EAAE,MAAA,EAAQ,GAAA,EAAK,QAAA,EAAU,IAAI,IAAA,EAAM,SAAA,EAAW,GAAA,CAAI,SAAA,EAAW,UAAA,EAAY,GAAA,CAAI,UAAA,EAAY,UAAA,EAAY,IAAI,MAAA;AAAO,KAClH;AAAA,EACF;AACA,EAAA,IAAI,GAAA,YAAe,kBAAA,IAAsB,GAAA,YAAe,gBAAA,EAAkB;AACxE,IAAA,OAAO,IAAA,CAAK,sBAAsB,OAAA,CAAQ,SAAS,KAAK,GAAA,CAAI,OAAO,IAAI,eAAA,EAAiB;AAAA,MACtF,QAAA,EAAU,GAAA,YAAe,kBAAA,GAAqB,GAAA,CAAI,IAAA,GAAO;AAAA,KAC1D,CAAA;AAAA,EACH;AACA,EAAA,OAAO,IAAA;AACT;AAYO,IAAM,cAAN,MAA2C;AAAA,EACvC,QAAA,GAAW,WAAW,MAAM,CAAA;AAAA,EAC5B,IAAA,GAAO,SAAA;AAAA,EAER,eAAA,GAAuC,IAAA;AAAA,EAE/C,eAAA,GAAmC;AACjC,IAAA,OAAO;AAAA,MACL,SAAA;AAAA,MACA,YAAA;AAAA,MACA,SAAA;AAAA,MACA,aAAA;AAAA,MACA,mBAAA;AAAA,MACA,WAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,eAAA,GAAgD;AACpD,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,MAAA,OAAO;AAAA,QACL,SAAA,EAAW,KAAA;AAAA,QACX,MAAA,EAAQ;AAAA,OACV;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,SAAA,EAAW,IAAA;AAAA,MACX,MAAA,EAAQ;AAAA,KACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,OAAA,CACJ,GAAA,EACA,IAAA,EAI+B;AAC/B,IAAA,IAAI;AACF,MAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,QAAA,MAAM,IAAI,uBAAA;AAAA,UACR,IAAA,CAAK,QAAA;AAAA,UACL;AAAA,SACF;AAAA,MACF;AAEA,MAAA,GAAA,CAAI,MAAA,CAAO,MAAM,2BAAA,EAA6B;AAAA,QAC5C,SAAS,GAAA,CAAI,OAAA;AAAA,QACb,QAAQ,GAAA,CAAI,MAAA;AAAA,QACZ,SAAS,GAAA,CAAI;AAAA,OACd,CAAA;AAGD,MAAA,MAAM,WAAA,GAAc,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,OAAO,CAAA;AAErD,MAAA,OAAO,IAAI,OAAA,CAA8B,CAAC,OAAA,EAAS,MAAA,KAAW;AAC5D,QAAA,IAAI,QAAA,GAAW,KAAA;AACf,QAAA,MAAM,OAAA,GAAU,MAAM,SAAA,IAAa,GAAA;AAEnC,QAAA,MAAM,SAAA,GAAY,WAAW,MAAM;AACjC,UAAA,IAAI,CAAC,QAAA,EAAU;AACb,YAAA,QAAA,GAAW,IAAA;AACX,YAAA,MAAA;AAAA,cACE,IAAI,KAAA;AAAA,gBACF;AAAA;AACF,aACF;AAAA,UACF;AAAA,QACF,GAAG,OAAO,CAAA;AAGV,QAAA,IAAA,CAAK,IAAA,CAAK;AAAA,UACR,SAAS,GAAA,CAAI,OAAA;AAAA,UACb,OAAA,EAAS,WAAA;AAAA,UACT,mBAAA,EAAqB,CAAC,OAAA,KAAY;AAChC,YAAA,GAAA,CAAI,MAAA,CAAO,KAAA,CAAM,yBAAA,EAA2B,OAAO,CAAA;AAAA,UACrD,CAAA;AAAA,UACA,OAAA,EAAS;AAAA,YACP,QAAA,EAAU,OAAA;AAAA,YACV,kBAAA,EAAoB;AAAA,WACtB;AAAA,UACA,QAAA,EAAU,OAAO,QAAA,KAA2B;AAC1C,YAAA,IAAI,QAAA,EAAU;AACd,YAAA,QAAA,GAAW,IAAA;AACX,YAAA,YAAA,CAAa,SAAS,CAAA;AAEtB,YAAA,IAAA,CAAK,eAAA,GAAkB,QAAA;AACvB,YAAA,MAAM,OAAA,GAAU,SAAA,CAAU,QAAA,CAAS,QAAQ,CAAA;AAE3C,YAAA,GAAA,CAAI,MAAA,CAAO,KAAK,0BAAA,EAA4B;AAAA,cAC1C,SAAS,QAAA,CAAS;AAAA,aACnB,CAAA;AAMD,YAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,eAAA,CAAgB,UAAU,GAAG,CAAA;AAE5D,YAAA,OAAA,CAAQ;AAAA,cACN,OAAA;AAAA,cACA,OAAA,EAAS;AAAA,gBACP,UAAU,IAAA,CAAK,QAAA;AAAA;AAAA;AAAA;AAAA,gBAIf,SAAS,GAAA,CAAI,OAAA;AAAA,gBACb,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,gBACpB,GAAG;AAAA,eACL;AAAA,cACA,YAAA,EAAc,KAAK,eAAA;AAAgB,aACpC,CAAA;AAAA,UACH,CAAA;AAAA,UACA,UAAU,MAAM;AACd,YAAA,IAAI,QAAA,EAAU;AACd,YAAA,QAAA,GAAW,IAAA;AACX,YAAA,YAAA,CAAa,SAAS,CAAA;AACtB,YAAA,MAAA,CAAO,IAAI,KAAA,CAAM,0BAA0B,CAAC,CAAA;AAAA,UAC9C;AAAA,SACD,CAAA;AAGD,QAAA,IAAA,CAAK,OAAA,EAAQ,CAAE,KAAA,CAAM,CAAC,GAAA,KAAQ;AAC5B,UAAA,IAAI,QAAA,EAAU;AACd,UAAA,QAAA,GAAW,IAAA;AACX,UAAA,YAAA,CAAa,SAAS,CAAA;AACtB,UAAA,MAAA,CAAO,GAAG,CAAA;AAAA,QACZ,CAAC,CAAA;AAAA,MACH,CAAC,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,iCAAiC,GAAA,EAAK;AAAA,QAC1C,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,KAAA,EAAO,SAAA;AAAA,QACP,SAAA,EAAW,OAAA;AAAA,QACX,OAAA,EAAS;AAAA,UACP,QAAQ,GAAA,CAAI,MAAA;AAAA,UACZ,SAAS,GAAA,CAAI;AAAA;AACf,OACD,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,eAAA,CACZ,QAAA,EACA,GAAA,EACuE;AACvE,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,QAAA,CAAS,UAAA,EAAW;AAC1C,MAAA,OAAO;AAAA,QACL,gBAAgB,OAAA,CAAQ,eAAA;AAAA,QACxB,0BAA0B,OAAA,CAAQ;AAAA,OACpC;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,GAAA,CAAI,MAAA,CAAO,MAAM,0DAAA,EAA4D;AAAA,QAC3E,OAAQ,GAAA,EAAe;AAAA,OACxB,CAAA;AACD,MAAA,OAAO,EAAC;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,UAAA,CAAW,IAAA,EAAsB,QAAA,EAAkC;AACvE,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,MAAA,EAAO;AAAA,IACd,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,IAAA,CAAK,eAAA,GAAkB,IAAA;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAA,CACJ,GAAA,EACA,SAAA,EACyB;AACzB,IAAA,IAAI;AACF,MAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,IAAA;AAE1C,MAAA,IAAI,UAAU,SAAA,IAAa,IAAA,CAAK,GAAA,EAAI,IAAK,UAAU,SAAA,EAAW;AAC5D,QAAA,OAAO,IAAA;AAAA,MACT;AAGA,MAAA,MAAM,cAAc,IAAA,CAAK,gBAAA,CAAiB,SAAA,CAAU,OAAA,IAAW,IAAI,OAAO,CAAA;AAE1E,MAAA,OAAO,IAAI,OAAA,CAAwB,CAAC,OAAA,KAAY;AAC9C,QAAA,IAAI,QAAA,GAAW,KAAA;AAGf,QAAA,MAAM,SAAA,GAAY,WAAW,MAAM;AACjC,UAAA,IAAI,CAAC,QAAA,EAAU;AACb,YAAA,QAAA,GAAW,IAAA;AACX,YAAA,GAAA,CAAI,MAAA,CAAO,KAAA;AAAA,cACT;AAAA,aACF;AACA,YAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,UACd;AAAA,QACF,GAAG,GAAI,CAAA;AAEP,QAAA,IAAA,CAAK,IAAA,CAAK;AAAA,UACR,SAAS,GAAA,CAAI,OAAA;AAAA,UACb,OAAA,EAAS,WAAA;AAAA,UACT,QAAA,EAAU,CAAC,QAAA,KAA2B;AACpC,YAAA,IAAI,QAAA,EAAU;AACd,YAAA,QAAA,GAAW,IAAA;AACX,YAAA,YAAA,CAAa,SAAS,CAAA;AAEtB,YAAA,IAAA,CAAK,eAAA,GAAkB,QAAA;AACvB,YAAA,GAAA,CAAI,MAAA,CAAO,MAAM,+CAAA,EAAiD;AAAA,cAChE,SAAS,QAAA,CAAS;AAAA,aACnB,CAAA;AAED,YAAA,OAAA,CAAQ,EAAE,GAAG,SAAA,EAAW,QAAA,EAAU,IAAA,CAAK,UAAU,CAAA;AAAA,UACnD,CAAA;AAAA,UACA,UAAU,MAAM;AACd,YAAA,IAAI,QAAA,EAAU;AACd,YAAA,QAAA,GAAW,IAAA;AACX,YAAA,YAAA,CAAa,SAAS,CAAA;AACtB,YAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,UACd;AAAA,SACD,CAAA;AAGD,QAAA,IAAA,CAAK,WAAA,EAAY,CAAE,KAAA,CAAM,MAAM;AAC7B,UAAA,IAAI,CAAC,QAAA,EAAU;AACb,YAAA,QAAA,GAAW,IAAA;AACX,YAAA,YAAA,CAAa,SAAS,CAAA;AACtB,YAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,UACd;AAAA,QACF,CAAC,CAAA;AAAA,MACH,CAAC,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,uCAAA,EAAyC,GAAG,CAAA;AAC5D,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAA,CACJ,GAAA,EACA,OAAA,EACA,MAAA,EACwB;AACxB,IAAA,IAAI;AACF,MAAA,IAAI,CAAC,KAAK,eAAA,EAAiB;AACzB,QAAA,MAAM,IAAI,MAAM,8BAA8B,CAAA;AAAA,MAChD;AAEA,MAAA,GAAA,CAAI,MAAA,CAAO,MAAM,kCAAA,EAAoC;AAAA,QACnD,WAAW,OAAA,CAAQ,SAAA;AAAA,QACnB,aAAA,EAAe,OAAO,OAAA,CAAQ;AAAA,OAC/B,CAAA;AAED,MAAA,MAAM,YAAY,MAAM,IAAA,CAAK,eAAA,CAAgB,WAAA,CAAY,OAAO,OAAO,CAAA;AAEvE,MAAA,OAAO;AAAA,QACL,SAAA,EAAW,YAAY,SAAS,CAAA;AAAA,QAChC,SAAS,OAAA,CAAQ,OAAA;AAAA,QACjB,SAAS,MAAA,CAAO,OAAA;AAAA,QAChB,OAAO,MAAA,CAAO,KAAA;AAAA,QACd,QAAQ,MAAA,CAAO;AAAA,OACjB;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,iCAAiC,GAAA,EAAK;AAAA,QAC1C,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,KAAA,EAAO,aAAA;AAAA,QACP,SAAA,EAAW,OAAA;AAAA,QACX,OAAA,EAAS;AAAA,UACP,WAAW,OAAA,CAAQ;AAAA;AACrB,OACD,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAA,CACJ,IAAA,EACA,QAAA,EACA,OAAA,EAC4B;AAC5B,IAAA,MAAM,IAAI,2BAAA;AAAA,MACR,IAAA,CAAK,QAAA;AAAA,MACL;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,iBAAA,CACJ,GAAA,EACA,OAAA,EACA,MAAA,EACoB;AACpB,IAAA,IAAI;AACF,MAAA,IAAI,CAAC,KAAK,eAAA,EAAiB;AACzB,QAAA,MAAM,IAAI,MAAM,8BAA8B,CAAA;AAAA,MAChD;AAEA,MAAA,GAAA,CAAI,MAAA,CAAO,MAAM,yCAAA,EAA2C;AAAA,QAC1D,WAAW,OAAA,CAAQ;AAAA,OACpB,CAAA;AAED,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,eAAA,CAAgB,iBAAA;AAAA;AAAA,QAExC,MAAA,CAAO,QAAA;AAAA,QACP;AAAA,UACE,OAAA,EAAS;AAAA;AACX,OACF;AAQA,MAAA,MAAM,CAAA,GAAI,MAAA;AACV,MAAA,IAAI,CAAC,CAAA,IAAK,OAAO,CAAA,CAAE,eAAe,QAAA,EAAU;AAI1C,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,yHAAA,EACyD,WAAA,CAAY,CAAC,CAAC,CAAA,wQAAA;AAAA,SAIzE;AAAA,MACF;AAEA,MAAA,OAAO;AAAA,QACL,eAAA,EAAiB,iBAAA,CAAkB,CAAA,CAAE,UAAU,CAAA;AAAA,QAC/C,WAAA,EAAa,KAAK,GAAA,EAAI;AAAA,QACtB,WAAW,CAAA,CAAE,UAAA;AAAA,QACb,QAAA,EAAU,CAAA,CAAE,aAAA,IAAiB,CAAA,CAAE;AAAA,OACjC;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,iCAAiC,GAAA,EAAK;AAAA,QAC1C,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,KAAA,EAAO,mBAAA;AAAA,QACP,SAAA,EAAW,OAAA;AAAA,QACX,OAAA,EAAS;AAAA,UACP,WAAW,OAAA,CAAQ;AAAA;AACrB,OACD,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,MAAM,SAAA,CACJ,GAAA,EACA,OAAA,EACA,MAAA,EAC0B;AAC1B,IAAA,IAAI;AACF,MAAA,IAAI,CAAC,KAAK,eAAA,EAAiB;AACzB,QAAA,MAAM,IAAI,MAAM,8BAA8B,CAAA;AAAA,MAChD;AAEA,MAAA,MAAM,EAAE,aAAA,EAAe,QAAA,EAAS,GAAI,MAAA;AAGpC,MAAA,MAAM,IAAA,GAAO,qBAAA,CAAsB,MAAA,CAAO,IAAI,CAAA;AAC9C,MAAA,MAAM,QAAQ,CAAA,EAAG,aAAA,CAAc,WAAA,EAAa,IAAI,QAAQ,CAAA,CAAA;AAExD,MAAA,GAAA,CAAI,MAAA,CAAO,MAAM,wBAAA,EAA0B;AAAA,QACzC,WAAW,OAAA,CAAQ,SAAA;AAAA,QACnB;AAAA,OACD,CAAA;AAGD,MAAA,IAAI,IAAA,CAAK,UAAA,CAAW,aAAA,EAAe,QAAQ,CAAA,EAAG;AAC5C,QAAA,OAAO,IAAA,CAAK,eAAe,IAAI,CAAA;AAAA,MACjC;AAEA,MAAA,IAAI,IAAA,CAAK,aAAA,CAAc,aAAA,EAAe,QAAQ,CAAA,EAAG;AAC/C,QAAA,OAAO,IAAA,CAAK,mBAAA,CAAoB,QAAA,EAAU,IAAI,CAAA;AAAA,MAChD;AAGA,MAAA,MAAM,IAAI,2BAAA;AAAA,QACR,IAAA,CAAK,QAAA;AAAA,QACL,uBAAuB,KAAK,CAAA,6NAAA;AAAA,OAI9B;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,iCAAiC,GAAA,EAAK;AAAA,QAC1C,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,KAAA,EAAO,WAAA;AAAA,QACP,SAAA,EAAW,OAAA;AAAA,QACX,OAAA,EAAS,EAAE,SAAA,EAAW,OAAA,CAAQ,SAAA;AAAU,OACzC,CAAA;AAAA,IACH;AAAA,EACF;AAAA;AAAA,EAGQ,UAAA,CAAW,QAAgB,QAAA,EAA2B;AAC5D,IAAA,MAAM,CAAA,GAAI,OAAO,WAAA,EAAY;AAC7B,IAAA,MAAM,UAAA,GAAa,QAAA,CAAS,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAI9C,IAAA,IAAI,MAAM,MAAA,EAAQ;AAChB,MAAA,OAAO,UAAA,KAAe,mBACjB,UAAA,KAAe,4BAAA;AAAA,IACtB;AACA,IAAA,IAAI,MAAM,KAAA,EAAO;AACf,MAAA,OAAO,UAAA,KAAe,gCAAA;AAAA,IACxB;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA,EAGQ,aAAA,CAAc,QAAgB,QAAA,EAA2B;AAC/D,IAAA,IAAI,MAAA,CAAO,WAAA,EAAY,KAAM,MAAA,EAAQ,OAAO,KAAA;AAC5C,IAAA,MAAM,UAAA,GAAa,QAAA,CAAS,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAC9C,IAAA,OAAO,UAAA,KAAe,qBAAA,IACjB,UAAA,KAAe,8BAAA,IACf,UAAA,KAAe,8CAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAc,eAAe,IAAA,EAAyC;AACpE,IAAA,MAAM,WAAW,IAAA,CAAK,eAAA;AAGtB,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI,WAAA;AAEJ,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAa9B,QAAA,IAAI,MAAA,CAAO,QAAQ,cAAA,EAAgB;AACjC,UAAA,MAAM,YAAA,GAAe,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,OAAO,cAAc,CAAA;AAC/D,UAAA,KAAA,MAAW,MAAM,YAAA,EAAc;AAC7B,YAAA,MAAM,SAAA,GAAY,GAAG,SAAA,EAAW,eAAA;AAChC,YAAA,IAAI,SAAA,IAAa,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG;AACrC,cAAA,UAAA,GAAa,SAAA,CAAU,CAAC,CAAA,CAAE,UAAA;AAC1B,cAAA,WAAA,GAAc,SAAA,CAAU,CAAC,CAAA,CAAE,WAAA;AAC3B,cAAA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,QAAA,IAAI,CAAC,UAAA,IAAc,MAAA,CAAO,UAAA,EAAY;AACpC,UAAA,UAAA,GAAa,MAAA,CAAO,UAAA;AAAA,QACtB;AACA,QAAA,IAAI,CAAC,WAAA,IAAe,MAAA,CAAO,WAAA,EAAa;AACtC,UAAA,WAAA,GAAc,MAAA,CAAO,WAAA;AAAA,QACvB;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAGA,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,MAAM,SAAS,kBAAA,CAAmB;AAAA,QACzC,UAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,UAAA,GAAa,aACf,CAAA,YAAA,EAAe,UAAU,MACzB,WAAA,GACE,CAAA,aAAA,EAAgB,WAAW,CAAA,CAAA,CAAA,GAC3B,8BAAA;AACN,MAAA,MAAM,IAAA,GAAO,CAAC,UAAA,IAAc,CAAC,WAAA,GACzB,uGAAA,GACA,UAAA,IAAc,CAAC,UAAA,CAAW,UAAA,CAAW,GAAG,CAAA,GACtC,CAAA,sLAAA,CAAA,GAGA,EAAA;AAGN,MAAA,MAAM,UAAA,GAAa,uBAAuB,GAAA,EAAK,EAAE,WAAW,CAAA,oBAAA,EAAuB,UAAU,KAAK,CAAA;AAClG,MAAA,IAAI,YAAY,MAAM,UAAA;AACtB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,qCAAA,EAAwC,UAAU,CAAA,CAAA,EAAI,IAAI,CAAA,iBAAA,EACpC,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA,CAAA;AAAA,QACtE,EAAE,OAAO,GAAA;AAAa,OACxB;AAAA,IACF;AAIA,IAAA,MAAM,SAAA,GAAY,iBAAiB,MAAM,CAAA;AACzC,IAAA,MAAM,WAAA,GAAc;AAAA,MAClB,eAAA,EAAiB,SAAA;AAAA,MACjB,UAAA,EAAY;AAAA,KACd;AAEA,IAAA,OAAO,EAAE,QAAA,EAAU,IAAA,CAAK,SAAA,CAAU,WAAW,CAAA,EAAE;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,mBAAA,CAAoB,QAAA,EAAkB,IAAA,EAAyC;AAC3F,IAAA,MAAM,WAAW,IAAA,CAAK,eAAA;AAItB,IAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,IAAA,EAAK,CAAE,WAAW,CAAA,EAAG;AACrC,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,oIAAA;AAAA,OAEF;AAAA,IACF;AAEA,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAA,GAAU,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,IAC3B,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,OAAA,GAAU,KAAK,MAAA,GAAS,GAAA,GAAM,KAAK,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA,GAAI,KAAA,GAAQ,IAAA;AACjE,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,8CAA+C,GAAA,CAAc,OAAO,sCAC9B,IAAA,CAAK,SAAA,CAAU,OAAO,CAAC,CAAA,qDAAA;AAAA,OAE/D;AAAA,IACF;AAEA,IAAA,MAAM,UAAA,GAAa,QAAA,CAAS,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAC9C,IAAA,MAAM,aAAA,GAAgB,UAAA,CAAW,QAAA,CAAS,MAAM,CAAA;AAIhD,IAAA,MAAM,aAAA,GAAgB,OAAA;AACtB,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,aAAA,GACL,MAAM,QAAA,CAAS,2BAAA,CAA4B,aAAa,CAAA,GACxD,MAAM,QAAA,CAAS,iBAAA,CAAkB,aAAa,CAAA;AAAA,IACpD,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,EAAA,GAAK,gBAAgB,6BAAA,GAAgC,mBAAA;AAC3D,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,cAAA,CAAe,OAAO,CAAA;AAIxC,MAAA,MAAM,UAAA,GAAa,uBAAuB,GAAA,EAAK,EAAE,WAAW,CAAA,YAAA,EAAe,EAAE,CAAA,CAAA,EAAI,IAAA,EAAM,CAAA;AACvF,MAAA,IAAI,YAAY,MAAM,UAAA;AACtB,MAAA,MAAM,OAAA,GAAW,KAAe,OAAA,IAAW,qDAAA;AAC3C,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,YAAA,EAAe,EAAE,CAAA,SAAA,EAAY,OAAO,IAAI,IAAI,CAAA,mCAAA,CAAA;AAAA,QAE5C,EAAE,OAAO,GAAA;AAAa,OACxB;AAAA,IACF;AASA,IAAA,IAAI,MAAA,KAAW,MAAA,IAAa,MAAA,KAAW,IAAA,EAAM;AAC3C,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,cAAA,CAAe,OAAO,CAAA;AAGxC,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,YAAA,EAAe,aAAA,GAAgB,6BAAA,GAAgC,mBAAmB,sIAEhD,IAAI,CAAA;AAAA,OACxC;AAAA,IACF;AAEA,IAAA,OAAO,EAAE,QAAA,EAAU,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA,EAAE;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,eAAe,OAAA,EAA0C;AAC/D,IAAA,IAAI;AACF,MAAA,MAAM,WAAW,OAAA,CAAQ,QAAA;AACzB,MAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,QAAQ,GAAG,OAAO,EAAA;AACrC,MAAA,KAAA,MAAW,OAAO,QAAA,EAA4C;AAI5D,QAAA,MAAM,QAAA,GAAa,GAAA,EAAK,eAAA,IAAmB,GAAA,EAAK,mBAAmB,GAAA,EAAK,QAAA;AAGxE,QAAA,MAAM,MAAA,GAAW,GAAA,EAAK,aAAA,IAAiB,GAAA,EAAK,iBAAiB,GAAA,EAAK,MAAA;AAGlE,QAAA,MAAM,GAAA,GAAO,QAAA,EAAU,UAAA,IAAc,MAAA,EAAQ,UAAA;AAC7C,QAAA,MAAM,SAAS,QAAA,EAAU,MAAA;AAIzB,QAAA,IACE,MAAA,KAAW,qBACR,OAAO,GAAA,KAAQ,YACf,GAAA,CAAI,QAAA,CAAS,sBAAsB,CAAA,EACtC;AACA,UAAA,OACE,CAAA,qfAAA,CAAA;AAAA,QAOJ;AAEA,QAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,IAAY,GAAA,CAAI,MAAA,GAAS,KAAK,CAAC,GAAA,CAAI,UAAA,CAAW,GAAG,CAAA,EAAG;AACrE,UAAA,OACE,iCAAiC,GAAG,CAAA,2HAAA,CAAA;AAAA,QAGxC;AAAA,MACF;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,OAAO,EAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,iBAAiB,OAAA,EAAiD;AACxE,IAAA,IAAI,OAAA,KAAY,SAAS,OAAO,OAAA;AAChC,IAAA,IAAI,OAAA,KAAY,UAAU,OAAO,QAAA;AACjC,IAAA,IAAI,OAAA,KAAY,WAAW,OAAO,SAAA;AAClC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,qCAAqC,OAAO,CAAA,8CAAA;AAAA,KAC9C;AAAA,EACF;AACF;AAgBA,SAAS,YAAY,KAAA,EAAwB;AAC3C,EAAA,IAAI,KAAA,KAAU,QAAW,OAAO,WAAA;AAChC,EAAA,IAAI,KAAA,KAAU,MAAM,OAAO,MAAA;AAC3B,EAAA,IAAI;AACF,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AAC9B,IAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,OAAO,KAAK,CAAA;AAC9C,IAAA,OAAO,CAAA,CAAE,SAAS,GAAA,GAAM,CAAA,CAAE,MAAM,CAAA,EAAG,GAAG,IAAI,KAAA,GAAQ,CAAA;AAAA,EACpD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,OAAO,KAAK,CAAA;AAAA,EACrB;AACF;AAEA,SAAS,iBAAiB,MAAA,EAA4B;AACpD,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AACzB,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,EAAU;AACxC,IAAA,MAAM,GAAA,GAAM,MAAA;AAEZ,IAAA,KAAA,MAAW,OAAO,CAAC,kBAAA,EAAoB,iBAAA,EAAmB,WAAA,EAAa,QAAQ,CAAA,EAAG;AAChF,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAC,CAAA,EAAG;AAC3B,QAAA,OAAO,IAAI,GAAG,CAAA;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,EAAC;AACV","file":"index.mjs","sourcesContent":["/**\n * 5N Loop Wallet adapter implementation\n *\n * Uses the official @fivenorth/loop-sdk NPM package which communicates\n * with Loop wallet via QR code / popup flow over WebSocket.\n *\n * Reference: https://github.com/fivenorth-io/loop-sdk\n * Wallet Integration Guide: https://docs.digitalasset.com/integrate/devnet/index.html\n */\n\nimport type {\n  WalletAdapter,\n  AdapterContext,\n  AdapterDetectResult,\n  AdapterConnectResult,\n  SignMessageParams,\n  SignTransactionParams,\n  SubmitTransactionParams,\n  SignedMessage,\n  SignedTransaction,\n  TxReceipt,\n  LedgerApiParams,\n  LedgerApiResult,\n  Session,\n  PersistedSession,\n  CapabilityKey,\n  PartyId,\n} from '@partylayer/core';\nimport {\n  toWalletId,\n  toPartyId,\n  toTransactionHash,\n  toSignature,\n  PartyLayerError,\n  WalletNotInstalledError,\n  CapabilityNotSupportedError,\n  mapUnknownErrorToPartyLayerError,\n  ledgerApiBodyToString,\n} from '@partylayer/core';\nimport type { ErrorCode } from '@partylayer/core';\nimport {\n  loop,\n  RequestTimeoutError,\n  UnauthorizedError,\n  PaymentRequiredError,\n  RejectRequestError,\n  PopupClosedError,\n} from '@fivenorth/loop-sdk';\n\n// The SDK does not re-export its `Provider` type by name from the package root,\n// so derive it from `loop.init`'s `onAccept` parameter. This is the REAL 0.13.x\n// provider (with getAccount, signMessage, submitTransaction, getActiveContracts).\ntype LoopProvider = Parameters<NonNullable<Parameters<typeof loop.init>[0]['onAccept']>>[0];\ntype LoopSubmitPayload = Parameters<LoopProvider['submitTransaction']>[0];\n\n/**\n * Map a Loop SDK 0.13 structured error onto the PartyLayer error taxonomy so a\n * consumer can distinguish auth from rate-limit from timeout from a user\n * rejection by a stable `code` (plus `details.status` where the SDK reports one),\n * rather than parsing a message string. Returns `null` when `err` is not one of\n * the SDK's structured errors, so callers keep their existing descriptive\n * wrapping for everything else. The original error is always preserved as `cause`.\n */\nfunction mapLoopStructuredError(\n  err: unknown,\n  context: { operation: string; hint?: string },\n): PartyLayerError | null {\n  const suffix = context.hint ? ` ${context.hint}` : '';\n  const make = (message: string, code: ErrorCode, details?: Record<string, unknown>) =>\n    new PartyLayerError(message, code, { cause: err, details: { operation: context.operation, ...details } });\n\n  if (err instanceof RequestTimeoutError) {\n    return make(`Loop ${context.operation} timed out. ${err.message}${suffix}`, 'TIMEOUT');\n  }\n  if (err instanceof UnauthorizedError) {\n    // A 401 from Loop means the auth token is no longer valid; the user must reconnect.\n    return make(\n      `Loop rejected ${context.operation}: unauthorized. Reconnect your Loop wallet.${suffix}`,\n      'SESSION_EXPIRED',\n      { status: 401, loopCode: err.code },\n    );\n  }\n  if (err instanceof PaymentRequiredError) {\n    // 402/limit-class: the traffic allowance is exhausted (payment/gas required or a\n    // request limit was hit). This is the one real traffic signal reaching the kit.\n    return make(\n      `Loop ${context.operation} needs payment or gas, or hit a request limit. ${err.message}${suffix}`,\n      'INSUFFICIENT_TRAFFIC',\n      { status: 402, loopCode: err.code, gasAmount: err.gasAmount, trackingId: err.trackingId, loopStatus: err.status },\n    );\n  }\n  if (err instanceof RejectRequestError || err instanceof PopupClosedError) {\n    return make(`User rejected Loop ${context.operation}. ${err.message}`, 'USER_REJECTED', {\n      loopCode: err instanceof RejectRequestError ? err.code : undefined,\n    });\n  }\n  return null;\n}\n\n/**\n * Loop Wallet adapter\n *\n * Implements WalletAdapter interface for 5N Loop Wallet using the official\n * Loop SDK. The SDK handles QR code display, WebSocket communication, and\n * popup/tab-based signing flows.\n *\n * Note: Loop sessions use WebSocket + localStorage for persistence.\n * The SDK's autoConnect() can restore sessions if the auth token is still valid.\n */\nexport class LoopAdapter implements WalletAdapter {\n  readonly walletId = toWalletId('loop');\n  readonly name = '5N Loop';\n\n  private currentProvider: LoopProvider | null = null;\n\n  getCapabilities(): CapabilityKey[] {\n    return [\n      'connect',\n      'disconnect',\n      'restore',\n      'signMessage',\n      'submitTransaction',\n      'ledgerApi',\n      'events',\n      'popup',\n    ];\n  }\n\n  /**\n   * Detect if Loop SDK is available.\n   *\n   * Loop uses QR code / popup flow — no browser extension needed.\n   * Always returns true in browser environments since the SDK is\n   * bundled as a dependency.\n   */\n  async detectInstalled(): Promise<AdapterDetectResult> {\n    if (typeof window === 'undefined') {\n      return {\n        installed: false,\n        reason: 'Browser environment required',\n      };\n    }\n\n    return {\n      installed: true,\n      reason: 'Loop Wallet available via QR code scan or popup.',\n    };\n  }\n\n  /**\n   * Connect to Loop Wallet.\n   *\n   * Flow:\n   * 1. Initialize Loop SDK with app name and network\n   * 2. Call connect() which first tries autoConnect (session restore)\n   * 3. If no cached session, opens QR code overlay for user to scan\n   * 4. User scans QR with Loop mobile app or approves in popup\n   * 5. onAccept callback receives provider with party_id\n   */\n  async connect(\n    ctx: AdapterContext,\n    opts?: {\n      timeoutMs?: number;\n      partyId?: PartyId;\n    },\n  ): Promise<AdapterConnectResult> {\n    try {\n      if (typeof window === 'undefined') {\n        throw new WalletNotInstalledError(\n          this.walletId,\n          'Browser environment required',\n        );\n      }\n\n      ctx.logger.debug('Connecting to Loop Wallet', {\n        appName: ctx.appName,\n        origin: ctx.origin,\n        network: ctx.network,\n      });\n\n      // Map network to Loop format\n      const loopNetwork = this.mapNetworkToLoop(ctx.network);\n\n      return new Promise<AdapterConnectResult>((resolve, reject) => {\n        let resolved = false;\n        const timeout = opts?.timeoutMs || 300000; // 5 min default for QR scan\n\n        const timeoutId = setTimeout(() => {\n          if (!resolved) {\n            resolved = true;\n            reject(\n              new Error(\n                'Connection timeout — user did not complete QR scan',\n              ),\n            );\n          }\n        }, timeout);\n\n        // Initialize and connect via the official SDK\n        loop.init({\n          appName: ctx.appName,\n          network: loopNetwork,\n          onTransactionUpdate: (payload) => {\n            ctx.logger.debug('Loop transaction update', payload);\n          },\n          options: {\n            openMode: 'popup',\n            requestSigningMode: 'popup',\n          },\n          onAccept: async (provider: LoopProvider) => {\n            if (resolved) return;\n            resolved = true;\n            clearTimeout(timeoutId);\n\n            this.currentProvider = provider;\n            const partyId = toPartyId(provider.party_id);\n\n            ctx.logger.info('Connected to Loop Wallet', {\n              partyId: provider.party_id,\n            });\n\n            // Fund-safety passthrough: read the wallet's payout-preapproval signal\n            // so consumers can tell whether a payout to this party lands directly\n            // or may strand as an unaccepted offer. Best-effort: getAccount()\n            // failing must NOT break connect; proceed with the fields absent.\n            const preapproval = await this.readPreapproval(provider, ctx);\n\n            resolve({\n              partyId,\n              session: {\n                walletId: this.walletId,\n                // Loop's connect callback does not report the connected network\n                // → not wallet-reported, so network-mismatch detection is\n                // limited for this adapter (echoes the requested ctx.network).\n                network: ctx.network,\n                createdAt: Date.now(),\n                ...preapproval,\n              },\n              capabilities: this.getCapabilities(),\n            });\n          },\n          onReject: () => {\n            if (resolved) return;\n            resolved = true;\n            clearTimeout(timeoutId);\n            reject(new Error('User rejected connection'));\n          },\n        });\n\n        // Initiate connection (opens QR code overlay or auto-connects)\n        loop.connect().catch((err) => {\n          if (resolved) return;\n          resolved = true;\n          clearTimeout(timeoutId);\n          reject(err);\n        });\n      });\n    } catch (err) {\n      throw mapUnknownErrorToPartyLayerError(err, {\n        walletId: this.walletId,\n        phase: 'connect',\n        transport: 'popup',\n        details: {\n          origin: ctx.origin,\n          network: ctx.network,\n        },\n      });\n    }\n  }\n\n  /**\n   * Read the wallet's payout-preapproval signal via the SDK's getAccount(),\n   * mapping the SDK's snake_case fields to our camelCase session fields. Purely\n   * a passthrough of what the wallet reports; nothing is inferred. Best-effort:\n   * any failure is logged and yields an empty object so connect still succeeds.\n   */\n  private async readPreapproval(\n    provider: LoopProvider,\n    ctx: AdapterContext,\n  ): Promise<Pick<Session, 'hasPreapproval' | 'utilityPreapprovalAdmins'>> {\n    try {\n      const account = await provider.getAccount();\n      return {\n        hasPreapproval: account.has_preapproval,\n        utilityPreapprovalAdmins: account.utility_preapproval_admins,\n      };\n    } catch (err) {\n      ctx.logger.debug('Loop getAccount() failed; preapproval signal unavailable', {\n        error: (err as Error)?.message,\n      });\n      return {};\n    }\n  }\n\n  /**\n   * Disconnect from Loop Wallet.\n   *\n   * Calls the SDK's logout() which clears the session, closes\n   * the WebSocket, and removes the QR overlay if visible.\n   */\n  async disconnect(_ctx: AdapterContext, _session: Session): Promise<void> {\n    try {\n      loop.logout();\n    } catch {\n      // Ignore logout errors\n    }\n    this.currentProvider = null;\n  }\n\n  /**\n   * Restore session.\n   *\n   * Loop SDK persists sessions in localStorage. We can attempt\n   * autoConnect() to restore a valid session without showing the QR code.\n   */\n  async restore(\n    ctx: AdapterContext,\n    persisted: PersistedSession,\n  ): Promise<Session | null> {\n    try {\n      if (typeof window === 'undefined') return null;\n\n      if (persisted.expiresAt && Date.now() >= persisted.expiresAt) {\n        return null;\n      }\n\n      // Try auto-connect — the SDK checks localStorage for a valid auth token\n      const loopNetwork = this.mapNetworkToLoop(persisted.network || ctx.network);\n\n      return new Promise<Session | null>((resolve) => {\n        let resolved = false;\n\n        // 5 second timeout for auto-connect\n        const timeoutId = setTimeout(() => {\n          if (!resolved) {\n            resolved = true;\n            ctx.logger.debug(\n              'Loop Wallet auto-connect timed out, session not restorable',\n            );\n            resolve(null);\n          }\n        }, 5000);\n\n        loop.init({\n          appName: ctx.appName,\n          network: loopNetwork,\n          onAccept: (provider: LoopProvider) => {\n            if (resolved) return;\n            resolved = true;\n            clearTimeout(timeoutId);\n\n            this.currentProvider = provider;\n            ctx.logger.debug('Restored Loop Wallet session via auto-connect', {\n              partyId: provider.party_id,\n            });\n\n            resolve({ ...persisted, walletId: this.walletId });\n          },\n          onReject: () => {\n            if (resolved) return;\n            resolved = true;\n            clearTimeout(timeoutId);\n            resolve(null);\n          },\n        });\n\n        // autoConnect checks localStorage and reconnects if valid\n        loop.autoConnect().catch(() => {\n          if (!resolved) {\n            resolved = true;\n            clearTimeout(timeoutId);\n            resolve(null);\n          }\n        });\n      });\n    } catch (err) {\n      ctx.logger.warn('Failed to restore Loop Wallet session', err);\n      return null;\n    }\n  }\n\n  /**\n   * Sign a message.\n   */\n  async signMessage(\n    ctx: AdapterContext,\n    session: Session,\n    params: SignMessageParams,\n  ): Promise<SignedMessage> {\n    try {\n      if (!this.currentProvider) {\n        throw new Error('Not connected to Loop Wallet');\n      }\n\n      ctx.logger.debug('Signing message with Loop Wallet', {\n        sessionId: session.sessionId,\n        messageLength: params.message.length,\n      });\n\n      const signature = await this.currentProvider.signMessage(params.message);\n\n      return {\n        signature: toSignature(signature),\n        partyId: session.partyId,\n        message: params.message,\n        nonce: params.nonce,\n        domain: params.domain,\n      };\n    } catch (err) {\n      throw mapUnknownErrorToPartyLayerError(err, {\n        walletId: this.walletId,\n        phase: 'signMessage',\n        transport: 'popup',\n        details: {\n          sessionId: session.sessionId,\n        },\n      });\n    }\n  }\n\n  /**\n   * Sign a transaction.\n   *\n   * Loop SDK combines signing and submission. For sign-only,\n   * throw CapabilityNotSupportedError.\n   */\n  async signTransaction(\n    _ctx: AdapterContext,\n    _session: Session,\n    _params: SignTransactionParams,\n  ): Promise<SignedTransaction> {\n    throw new CapabilityNotSupportedError(\n      this.walletId,\n      'signTransaction — Loop SDK combines signing and submission. Use submitTransaction instead.',\n    );\n  }\n\n  /**\n   * Submit a transaction.\n   *\n   * Loop SDK's submitTransaction signs and submits the DAML command.\n   * Returns command_id and submission_id.\n   */\n  async submitTransaction(\n    ctx: AdapterContext,\n    session: Session,\n    params: SubmitTransactionParams,\n  ): Promise<TxReceipt> {\n    try {\n      if (!this.currentProvider) {\n        throw new Error('Not connected to Loop Wallet');\n      }\n\n      ctx.logger.debug('Submitting transaction with Loop Wallet', {\n        sessionId: session.sessionId,\n      });\n\n      const result = await this.currentProvider.submitTransaction(\n        // Passthrough: signedTx is opaque, the caller owns its shape.\n        params.signedTx as unknown as LoopSubmitPayload,\n        {\n          message: 'Submit transaction via PartyLayer',\n        },\n      );\n\n      // Loop SDK resolves with whatever the wallet server sent back in\n      // the response payload. On success it's `{ command_id, submission_id }`,\n      // but empty or rejected responses can come through as undefined / {}.\n      // Guard before dereferencing so consumers don't see an opaque\n      // \"Cannot read properties of undefined\" or \"Unexpected end of JSON\n      // input\" — give them an actionable error instead.\n      const r = result as { command_id?: string; submission_id?: string } | null | undefined;\n      if (!r || typeof r.command_id !== 'string') {\n        // Do not use words like \"rejected\"/\"denied\"/\"cancelled\" here — the\n        // core error mapper auto-classifies those as UserRejectedError and\n        // replaces the message, which would hide the actionable hint below.\n        throw new Error(\n          `Loop Wallet submitTransaction returned an unexpected response shape. `\n          + `Expected { command_id, submission_id } but received ${safePreview(r)}. `\n          + `Likely the popup closed before confirmation or the wallet server returned an error payload. `\n          + `Ensure the Daml template ID uses the fully-qualified package-prefixed form `\n          + `(e.g. '#splice-amulet:Splice.Amulet:Amulet') — Loop does not accept the short Canton form.`,\n        );\n      }\n\n      return {\n        transactionHash: toTransactionHash(r.command_id),\n        submittedAt: Date.now(),\n        commandId: r.command_id,\n        updateId: r.submission_id ?? r.command_id,\n      };\n    } catch (err) {\n      throw mapUnknownErrorToPartyLayerError(err, {\n        walletId: this.walletId,\n        phase: 'submitTransaction',\n        transport: 'popup',\n        details: {\n          sessionId: session.sessionId,\n        },\n      });\n    }\n  }\n\n  /**\n   * Ledger API endpoints that Loop SDK can fulfill via native methods.\n   *\n   * Loop SDK does not expose a generic Ledger API proxy. Instead, it\n   * provides purpose-built methods (getActiveContracts, getHolding,\n   * submitTransaction, etc.) that we map to Canton Ledger API endpoints.\n   *\n   * Supported endpoints:\n   * - POST /v2/state/acs — via getActiveContracts()\n   * - POST /v2/state/active-contracts — alias for /v2/state/acs\n   * - GET  /v2/state/acs/active-contracts — unfiltered, via getActiveContracts()\n   * - POST /v2/commands/submit — via submitTransaction()\n   * - POST /v2/commands/submit-and-wait — via submitAndWaitForTransaction()\n   * - POST /v2/commands/submit-and-wait-for-transaction — alias\n   *\n   * Unsupported endpoints throw CapabilityNotSupportedError with a\n   * message listing the supported routes.\n   */\n  async ledgerApi(\n    ctx: AdapterContext,\n    session: Session,\n    params: LedgerApiParams,\n  ): Promise<LedgerApiResult> {\n    try {\n      if (!this.currentProvider) {\n        throw new Error('Not connected to Loop Wallet');\n      }\n\n      const { requestMethod, resource } = params;\n      // Loop's SDK handlers parse a JSON string body; the SDK boundary now also\n      // accepts an object, so coerce to the string form Loop expects.\n      const body = ledgerApiBodyToString(params.body);\n      const route = `${requestMethod.toUpperCase()} ${resource}`;\n\n      ctx.logger.debug('Loop ledgerApi request', {\n        sessionId: session.sessionId,\n        route,\n      });\n\n      // Route to the appropriate Loop SDK method\n      if (this.isAcsRoute(requestMethod, resource)) {\n        return this.handleAcsQuery(body);\n      }\n\n      if (this.isSubmitRoute(requestMethod, resource)) {\n        return this.handleSubmitCommand(resource, body);\n      }\n\n      // Unsupported endpoint\n      throw new CapabilityNotSupportedError(\n        this.walletId,\n        `ledgerApi endpoint \"${route}\" is not supported by Loop wallet. ` +\n          'Supported: POST /v2/state/acs, GET /v2/state/acs/active-contracts, ' +\n          'POST /v2/commands/submit, POST /v2/commands/submit-and-wait. ' +\n          'For full Ledger API access, use Console or Nightly wallet.',\n      );\n    } catch (err) {\n      throw mapUnknownErrorToPartyLayerError(err, {\n        walletId: this.walletId,\n        phase: 'ledgerApi',\n        transport: 'popup',\n        details: { sessionId: session.sessionId },\n      });\n    }\n  }\n\n  /** Check if the request targets the ACS query endpoint */\n  private isAcsRoute(method: string, resource: string): boolean {\n    const m = method.toUpperCase();\n    const normalized = resource.replace(/\\/+$/, '');\n    // POST /v2/state/acs — filtered query (Canton Ledger API standard)\n    // POST /v2/state/active-contracts — alias\n    // GET  /v2/state/acs/active-contracts — unfiltered fetch of all contracts\n    if (m === 'POST') {\n      return normalized === '/v2/state/acs'\n        || normalized === '/v2/state/active-contracts';\n    }\n    if (m === 'GET') {\n      return normalized === '/v2/state/acs/active-contracts';\n    }\n    return false;\n  }\n\n  /** Check if the request targets a command submission endpoint */\n  private isSubmitRoute(method: string, resource: string): boolean {\n    if (method.toUpperCase() !== 'POST') return false;\n    const normalized = resource.replace(/\\/+$/, '');\n    return normalized === '/v2/commands/submit'\n      || normalized === '/v2/commands/submit-and-wait'\n      || normalized === '/v2/commands/submit-and-wait-for-transaction';\n  }\n\n  /**\n   * Handle POST /v2/state/acs via Loop SDK's getActiveContracts().\n   *\n   * The Canton Ledger API ACS request body contains a filter with template IDs.\n   * We extract the first templateId from the filter and pass it to the Loop SDK.\n   * The response is wrapped to match the Canton Ledger API shape.\n   *\n   * Important: Loop SDK expects fully-qualified Daml template IDs that include\n   * the package name prefix (e.g., '#splice-amulet:Splice.Amulet:Amulet'),\n   * not the short Canton Ledger API format ('Splice.Amulet:Amulet').\n   */\n  private async handleAcsQuery(body?: string): Promise<LedgerApiResult> {\n    const provider = this.currentProvider!;\n\n    // Parse the request body to extract template filter\n    let templateId: string | undefined;\n    let interfaceId: string | undefined;\n\n    if (body) {\n      try {\n        const parsed = JSON.parse(body) as {\n          filter?: {\n            filtersByParty?: Record<string, {\n              inclusive?: {\n                templateFilters?: Array<{ templateId?: string; interfaceId?: string }>;\n              };\n            }>;\n          };\n          templateId?: string;\n          interfaceId?: string;\n        };\n\n        // Extract from Canton Ledger API filter format\n        if (parsed.filter?.filtersByParty) {\n          const partyFilters = Object.values(parsed.filter.filtersByParty);\n          for (const pf of partyFilters) {\n            const templates = pf.inclusive?.templateFilters;\n            if (templates && templates.length > 0) {\n              templateId = templates[0].templateId;\n              interfaceId = templates[0].interfaceId;\n              break;\n            }\n          }\n        }\n\n        // Also accept direct templateId/interfaceId (simplified format)\n        if (!templateId && parsed.templateId) {\n          templateId = parsed.templateId;\n        }\n        if (!interfaceId && parsed.interfaceId) {\n          interfaceId = parsed.interfaceId;\n        }\n      } catch {\n        // If body is not valid JSON, call without filters\n      }\n    }\n\n    // Call Loop SDK's getActiveContracts() with descriptive error context\n    let result: unknown;\n    try {\n      result = await provider.getActiveContracts({\n        templateId,\n        interfaceId,\n      });\n    } catch (err) {\n      const filterDesc = templateId\n        ? `templateId=\"${templateId}\"`\n        : interfaceId\n          ? `interfaceId=\"${interfaceId}\"`\n          : 'no filter (unfiltered query)';\n      const hint = !templateId && !interfaceId\n        ? ' Loop wallet may not support unfiltered ACS queries — try providing a templateId or interfaceId.'\n        : templateId && !templateId.startsWith('#')\n          ? ` Loop wallet expects fully-qualified Daml template IDs with a package name prefix`\n            + ` (e.g., '#splice-amulet:Splice.Amulet:Amulet'), not the short Canton format`\n            + ` ('Splice.Amulet:Amulet').`\n          : '';\n      // Structured Loop errors (timeout/auth/limit) get a stable code; everything\n      // else keeps the descriptive query context. Original error preserved as cause.\n      const structured = mapLoopStructuredError(err, { operation: `getActiveContracts (${filterDesc})` });\n      if (structured) throw structured;\n      throw new Error(\n        `Loop getActiveContracts() failed for ${filterDesc}.${hint}`\n        + ` Original error: ${err instanceof Error ? err.message : String(err)}`,\n        { cause: err as Error },\n      );\n    }\n\n    // Normalize the Loop SDK response — it may be a plain array or an\n    // object with a known contracts key.\n    const contracts = extractContracts(result);\n    const acsResponse = {\n      activeContracts: contracts,\n      workflowId: '',\n    };\n\n    return { response: JSON.stringify(acsResponse) };\n  }\n\n  /**\n   * Handle POST /v2/commands/submit[-and-wait] via Loop SDK's\n   * submitTransaction() or submitAndWaitForTransaction().\n   */\n  private async handleSubmitCommand(resource: string, body?: string): Promise<LedgerApiResult> {\n    const provider = this.currentProvider!;\n\n    // Validate body. Empty or whitespace-only body used to hit JSON.parse\n    // directly and produce \"Unexpected end of JSON input\" with no context.\n    if (!body || body.trim().length === 0) {\n      throw new Error(\n        `Command submission requires a request body with at least a 'commands' field. `\n        + `Example: { commands: [...], commandId, actAs, readAs }.`,\n      );\n    }\n\n    let payload: Record<string, unknown>;\n    try {\n      payload = JSON.parse(body) as Record<string, unknown>;\n    } catch (err) {\n      const preview = body.length > 120 ? body.slice(0, 120) + '...' : body;\n      throw new Error(\n        `Command submission body is not valid JSON: ${(err as Error).message}. `\n        + `Received body (first 120 chars): ${JSON.stringify(preview)}. `\n        + `Use JSON.stringify(payload) when calling ledgerApi.`,\n      );\n    }\n\n    const normalized = resource.replace(/\\/+$/, '');\n    const waitForResult = normalized.includes('wait');\n\n    // The adapter is a passthrough: `payload` is opaque JSON whose shape is the\n    // caller's responsibility, so cast to the SDK's payload type at the boundary.\n    const submitPayload = payload as unknown as LoopSubmitPayload;\n    let result: unknown;\n    try {\n      result = waitForResult\n        ? await provider.submitAndWaitForTransaction(submitPayload)\n        : await provider.submitTransaction(submitPayload);\n    } catch (err) {\n      const op = waitForResult ? 'submitAndWaitForTransaction' : 'submitTransaction';\n      const hint = this.templateIdHint(payload);\n      // Structured Loop errors (timeout/auth/limit/reject) get a stable code so a\n      // consumer can react (retry vs reconnect vs top-up); everything else keeps\n      // the descriptive message. Original error preserved as cause in both paths.\n      const structured = mapLoopStructuredError(err, { operation: `Loop Wallet ${op}`, hint });\n      if (structured) throw structured;\n      const message = (err as Error)?.message || 'Loop SDK submission failed without an error message';\n      throw new Error(\n        `Loop Wallet ${op} failed: ${message}.${hint} `\n        + `Original error preserved as cause.`,\n        { cause: err as Error },\n      );\n    }\n\n    // Loop resolves sendRequest with response.payload — which can be\n    // undefined / null when the wallet sends a malformed or empty\n    // TRANSACTION_COMPLETED frame. JSON.stringify(undefined) returns the\n    // VALUE undefined (not \"undefined\"), so a naive `response: JSON.stringify(result)`\n    // leaves the response key missing from the returned object. Downstream\n    // consumers then do JSON.parse(result.response) which blows up with\n    // \"Unexpected token u\" / \"Unexpected end of JSON input\". Normalize.\n    if (result === undefined || result === null) {\n      const hint = this.templateIdHint(payload);\n      // Avoid \"rejected\"/\"denied\"/\"cancelled\" here so the core error\n      // mapper doesn't classify this as UserRejectedError and drop the hint.\n      throw new Error(\n        `Loop Wallet ${waitForResult ? 'submitAndWaitForTransaction' : 'submitTransaction'} `\n        + `resolved with an empty response. The popup may have closed before confirmation, or the wallet server `\n        + `returned an unexpected frame.${hint}`,\n      );\n    }\n\n    return { response: JSON.stringify(result) };\n  }\n\n  /**\n   * Build a hint string if the developer passed a short-form Canton\n   * template ID OR used the legacy pre-Token-Standard Amulet_Transfer\n   * choice. Both patterns produce \"Execute Unknown on Unknown\" in Loop's\n   * UI because Canton moved transfers to CIP-56 TransferFactory in 2025/2026.\n   */\n  private templateIdHint(payload: Record<string, unknown>): string {\n    try {\n      const commands = payload.commands;\n      if (!Array.isArray(commands)) return '';\n      for (const cmd of commands as Array<Record<string, unknown>>) {\n        // v2 JSON Ledger API uses PascalCase ExerciseCommand; legacy shape used lowercase.\n        // Interface exercises still go through ExerciseCommand with the interfaceId\n        // in the templateId field — we don't need to distinguish, just inspect.\n        const exercise = ((cmd?.ExerciseCommand || cmd?.exerciseCommand || cmd?.exercise) as\n          | Record<string, unknown>\n          | undefined);\n        const create = ((cmd?.CreateCommand || cmd?.createCommand || cmd?.create) as\n          | Record<string, unknown>\n          | undefined);\n        const raw = (exercise?.templateId ?? create?.templateId) as string | undefined;\n        const choice = exercise?.choice as string | undefined;\n\n        // CIP-56 migration hint: Amulet_Transfer exercised directly on the\n        // Amulet template is the legacy path and is rejected by Canton today.\n        if (\n          choice === 'Amulet_Transfer'\n          && typeof raw === 'string'\n          && raw.includes('Splice.Amulet:Amulet')\n        ) {\n          return (\n            ` The command exercises 'Amulet_Transfer' directly on the Amulet template — that's the `\n            + `legacy (pre-CIP-56) path and Canton no longer accepts it, which is why Loop's UI shows `\n            + `\"Execute Unknown on Unknown\". Use the Token Standard flow: exercise `\n            + `'TransferFactory_Transfer' by interface on a TransferFactory contract `\n            + `(interfaceId '#splice-api-token-transfer-instruction-v1:Splice.Api.Token.TransferInstructionV1:TransferFactory'). `\n            + `See https://partylayer.xyz/docs/token-transfers for the canonical flow.`\n          );\n        }\n\n        if (typeof raw === 'string' && raw.length > 0 && !raw.startsWith('#')) {\n          return (\n            ` The command uses templateId=\"${raw}\" which is the short Canton form; Loop requires `\n            + `the fully-qualified Daml form (e.g. '#splice-amulet:Splice.Amulet:Amulet').`\n          );\n        }\n      }\n    } catch {\n      // best-effort; never throw from a hint helper\n    }\n    return '';\n  }\n\n  /**\n   * Map a PartyLayer network ID to the Loop SDK network format.\n   *\n   * Loop serves only local / devnet / mainnet. Unsupported networks (e.g.\n   * testnet — Loop has none) throw a clear error at connect (via the adapter's\n   * existing error path) instead of being silently substituted to the wrong\n   * network.\n   */\n  private mapNetworkToLoop(network: string): 'local' | 'devnet' | 'mainnet' {\n    if (network === 'local') return 'local';\n    if (network === 'devnet') return 'devnet';\n    if (network === 'mainnet') return 'mainnet';\n    throw new Error(\n      `Loop wallet does not support the \"${network}\" network (supported: local, devnet, mainnet).`,\n    );\n  }\n}\n\n/**\n * Extract a contracts array from the Loop SDK response.\n *\n * The SDK's getActiveContracts() may return:\n *   - A plain array of contract objects (most common)\n *   - An object with a known key containing the array\n *\n * This helper normalizes all shapes to a flat array.\n */\n/**\n * Format an unknown value into a short human-readable preview for\n * inclusion in error messages. Keeps output small so long payloads\n * don't flood the console.\n */\nfunction safePreview(value: unknown): string {\n  if (value === undefined) return 'undefined';\n  if (value === null) return 'null';\n  try {\n    const s = JSON.stringify(value);\n    if (typeof s !== 'string') return String(value);\n    return s.length > 200 ? s.slice(0, 200) + '...' : s;\n  } catch {\n    return String(value);\n  }\n}\n\nfunction extractContracts(result: unknown): unknown[] {\n  if (Array.isArray(result)) {\n    return result;\n  }\n  if (result && typeof result === 'object') {\n    const obj = result as Record<string, unknown>;\n    // Try common response wrapper keys\n    for (const key of ['active_contracts', 'activeContracts', 'contracts', 'result']) {\n      if (Array.isArray(obj[key])) {\n        return obj[key] as unknown[];\n      }\n    }\n  }\n  return [];\n}\n"]}