{"version":3,"file":"ApprovalController.mjs","sourceRoot":"","sources":["../src/ApprovalController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAQ3D,OAAO,EAAE,SAAS,EAAE,6BAA6B;AAEjD,OAAO,EAAE,MAAM,EAAE,eAAe;AAGhC,OAAO,EACL,4BAA4B,EAC5B,mCAAmC,EACnC,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACzB,qBAAiB;AAElB,YAAY;AAEZ,0CAA0C;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAC;AAC1C,MAAM,CAAC,MAAM,0BAA0B,GAAG,cAAc,CAAC;AACzD,MAAM,CAAC,MAAM,4BAA4B,GAAG,gBAAgB,CAAC;AAE7D,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAE5C,MAAM,aAAa,GAA2C;IAC5D,gBAAgB,EAAE;QAChB,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,KAAK;QACd,sBAAsB,EAAE,IAAI;QAC5B,QAAQ,EAAE,IAAI;KACf;IACD,oBAAoB,EAAE;QACpB,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,KAAK;QACd,sBAAsB,EAAE,KAAK;QAC7B,QAAQ,EAAE,IAAI;KACf;IACD,aAAa,EAAE;QACb,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,KAAK;QACd,sBAAsB,EAAE,KAAK;QAC7B,QAAQ,EAAE,IAAI;KACf;CACF,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAAC,MAAc,EAAE,IAAY,EAAE,EAAE,CAChE,oBAAoB,IAAI,gCAAgC,MAAM,gBAAgB,CAAC;AAEjF,MAAM,eAAe,GAAG,GAA4B,EAAE;IACpD,OAAO;QACL,gBAAgB,EAAE,EAAE;QACpB,oBAAoB,EAAE,CAAC;QACvB,aAAa,EAAE,EAAE;KAClB,CAAC;AACJ,CAAC,CAAC;AAEF,oBAAoB;AAEpB,MAAM,yBAAyB,GAAG;IAChC,eAAe;IACf,KAAK;IACL,2BAA2B;IAC3B,YAAY;IACZ,eAAe;IACf,SAAS;IACT,KAAK;IACL,kBAAkB;IAClB,uBAAuB;IACvB,YAAY;IACZ,eAAe;IACf,oBAAoB;IACpB,WAAW;IACX,aAAa;IACb,WAAW;IACX,oBAAoB;CACZ,CAAC;AAoOX;;;;;;;;GAQG;AACH,MAAM,OAAO,kBAAmB,SAAQ,cAIvC;IASC;;;;;;;;;OASG;IACH,YAAY,EACV,SAAS,EACT,mBAAmB,EACnB,KAAK,GAAG,EAAE,EACV,6BAA6B,GAAG,EAAE,GACR;QAC1B,KAAK,CAAC;YACJ,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,aAAa;YACvB,SAAS;YACT,KAAK,EAAE,EAAE,GAAG,eAAe,EAAE,EAAE,GAAG,KAAK,EAAE;SAC1C,CAAC,CAAC;;QA7BI,gDAA2C;QAE3C,8CAA2C;QAE3C,0DAAiC;QAEjC,oEAAyC;QAyBhD,uBAAA,IAAI,iCAAc,IAAI,GAAG,EAAE,MAAA,CAAC;QAC5B,uBAAA,IAAI,+BAAY,IAAI,GAAG,EAAE,MAAA,CAAC;QAC1B,gFAAgF;QAChF,kEAAkE;QAClE,uBAAA,IAAI,2CAAwB,mBAAmB,MAAA,CAAC;QAChD,uBAAA,IAAI,qDAAkC,6BAA6B,MAAA,CAAC;QACpE,IAAI,CAAC,SAAS,CAAC,4BAA4B,CACzC,IAAI,EACJ,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,UAAU,CACR,IAAwB,EACxB,iBAA0B;QAE1B,IAAI,iBAAiB,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IA4CD,yBAAyB,CAAC,IAAwB;QAChD,MAAM,OAAO,GAAG,uBAAA,IAAI,8DAAK,MAAT,IAAI,EAClB,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,EAAE,EACP,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,aAAa,CACnB,CAAC;QACF,uBAAA,IAAI,+CAAqB,MAAzB,IAAI,CAAuB,CAAC;QAC5B,OAAO,OAAO,CAAC;IACjB,CAAC;IAsCD,GAAG,CAAC,IAAwB;QAC1B,OAAO,uBAAA,IAAI,8DAAK,MAAT,IAAI,EACT,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,EAAE,EACP,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,aAAa,CACnB,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,gBAAgB,CAAC,OAA2C,EAAE;QAC5D,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;QAErC,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;YACpB,OAAO,uBAAA,IAAI,mCAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,KAAK,CAAC,IAAI,CACf,CAAC,uBAAA,IAAI,mCAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAClD,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;QAC/C,CAAC;QAED,4BAA4B;QAC5B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAClE,IAAI,QAAQ,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBAC5B,KAAK,IAAI,CAAC,CAAC;YACb,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;OAIG;IACH,qBAAqB;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC;IACzC,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,UAAU,CACR,OAAwD,EAAE;QAE1D,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;QAEzC,IAAI,EAAE,EAAE,CAAC;YACP,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;YACpD,CAAC;YACD,OAAO,uBAAA,IAAI,qCAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACtD,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;YACxD,CAAC;YAED,oDAAoD;YACpD,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,OAAO,CAAC,uBAAA,IAAI,mCAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;YACxD,CAAC;YACD,OAAO,uBAAA,IAAI,mCAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;QAED,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAClE,IAAI,QAAQ,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;oBAC5B,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IAED;;;;;;;;;;OAUG;IACH,aAAa,CACX,EAAU,EACV,KAAe,EACf,OAAuB;QAEvB,4EAA4E;QAC5E,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAyC,CAAC;QACtE,MAAM,cAAc,GAAG,uBAAA,IAAI,uEAAc,MAAlB,IAAI,EAAe,EAAE,CAAC,CAAC;QAC9C,IAAI,cAAc,GAAG,KAAK,CAAC;QAE3B,IAAI,CAAC,OAAO,EAAE,iBAAiB,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YAC1D,uBAAA,IAAI,iEAAQ,MAAZ,IAAI,EAAS,EAAE,CAAC,CAAC;YACjB,cAAc,GAAG,IAAI,CAAC;QACxB,CAAC;QAED,OAAO,IAAI,OAAO,CAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnD,MAAM,eAAe,GAA0B;gBAC7C,OAAO,EAAE,CAAC,WAAqB,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;gBACnE,KAAK,EAAE,MAAM;aACd,CAAC;YAEF,IAAI,OAAO,EAAE,aAAa,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;gBACtD,MAAM,CAAC,IAAI,mCAAmC,CAAC,EAAE,CAAC,CAAC,CAAC;gBACpD,OAAO;YACT,CAAC;YAED,MAAM,WAAW,GAAG,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC;YAEzE,MAAM,YAAY,GAAG,QAAQ,CAAC,aAAa;gBACzC,CAAC,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE;gBACzC,CAAC,CAAC,KAAK,CAAC;YAEV,cAAc,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YAErC,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,CAAC;gBAC5B,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YAChC,CAAC;QACH,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,uBAAA,IAAI,iEAAQ,MAAZ,IAAI,EAAS,EAAE,CAAC,CAAC;YACnB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,aAAa,CAAC,EAAU,EAAE,KAAc;QACtC,MAAM,SAAS,GAAG,uBAAA,IAAI,uEAAc,MAAlB,IAAI,EAAe,EAAE,CAAC,CAAC;QACzC,uBAAA,IAAI,iEAAQ,MAAZ,IAAI,EAAS,EAAE,CAAC,CAAC;QACjB,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED;;;;;OAKG;IACH,aAAa,CAAC,cAAmD;QAC/D,KAAK,MAAM,EAAE,IAAI,uBAAA,IAAI,qCAAW,CAAC,IAAI,EAAE,EAAE,CAAC;YACxC,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;QACzC,CAAC;QACD,uBAAA,IAAI,mCAAS,CAAC,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE;YACzB,UAAU,CAAC,gBAAgB,GAAG,EAAE,CAAC;YACjC,UAAU,CAAC,oBAAoB,GAAG,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,kBAAkB,CAAC,IAA+B;QAChD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,4BAA4B,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClD,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE;YACzB,UAAU,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,YAAY;gBAC/C,IAAI,CAAC,YAAqB,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACH,SAAS,CAAC,OAAyB,EAAE;QACnC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,IAAI,MAAM,EAAE,CAAC;QAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC;QAE7C,IAAI,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE;YACzB,UAAU,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,yEAAyE;QACzE,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACxB,uBAAA,IAAI,+CAAqB,MAAzB,IAAI,CAAuB,CAAC;QAC9B,CAAC;QAED,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC;IAC7B,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,EAAE,EAAE,EAAkB;QAC5B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;YACrC,MAAM,IAAI,oBAAoB,EAAE,CAAC;QACnC,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE1D,IAAI,EAAE,KAAK,WAAW,CAAC,EAAE,EAAE,CAAC;YAC1B,MAAM,IAAI,mBAAmB,CAC3B,EAAE,EACF,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAChD,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE;YACzB,UAAU,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,EAAE,EAAE,WAAW,EAA6B;QAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAClD,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CACzB,CAAC;QAEF,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,wBAAwB,CAAC,EAAE,CAAC,CAAC;QACzC,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE;YACzB,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,WAAW,GAAG,WAAW,CAAC;QAChE,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,WAAW,CAAC,OAAuB,EAAE;QACzC,MAAM,uBAAA,IAAI,iEAAQ,MAAZ,IAAI,EAAS,4BAA4B,EAAE,IAAI,EAAE;YACrD,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,IAAI;SACQ,CAAC,CAAC;QAE3B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,SAAS,CAAC,OAAqB,EAAE;QACrC,MAAM,uBAAA,IAAI,iEAAQ,MAAZ,IAAI,EAAS,0BAA0B,EAAE,IAAI,EAAE;YACnD,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,IAAI;SACQ,CAAC,CAAC;QAE3B,OAAO,EAAE,CAAC;IACZ,CAAC;CAuNF;kUAzMG,MAAc,EACd,IAAY,EACZ,KAAa,MAAM,EAAE,EACrB,WAAkC,EAClC,YAAmC,EACnC,aAAuB;IAEvB,uBAAA,IAAI,4EAAmB,MAAvB,IAAI,EAAoB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;IAErE,IACE,CAAC,uBAAA,IAAI,yDAA+B,CAAC,QAAQ,CAAC,IAAI,CAAC;QACnD,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EACjC,CAAC;QACD,MAAM,SAAS,CAAC,mBAAmB,CACjC,wBAAwB,CAAC,MAAM,EAAE,IAAI,CAAC,CACvC,CAAC;IACJ,CAAC;IAED,uBAAuB;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,uBAAA,IAAI,qCAAW,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7C,uBAAA,IAAI,mFAA0B,MAA9B,IAAI,EAA2B,MAAM,EAAE,IAAI,CAAC,CAAC;QAE7C,uBAAA,IAAI,qEAAY,MAAhB,IAAI,EACF,EAAE,EACF,MAAM,EACN,IAAI,EACJ,WAAW,EACX,YAAY,EACZ,aAAa,CACd,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,yFAYC,EAAU,EACV,MAAc,EACd,IAAY,EACZ,WAAkC,EAClC,YAAmC;IAEnC,IAAI,YAAY,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;QAClC,YAAY,GAAG,mCAAmC,CAAC;IACrD,CAAC;SAAM,IAAI,uBAAA,IAAI,qCAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;QACnC,YAAY,GAAG,6BAA6B,EAAE,mBAAmB,CAAC;IACpE,CAAC;SAAM,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QACjD,YAAY,GAAG,uCAAuC,CAAC;IACzD,CAAC;SAAM,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7C,YAAY,GAAG,qCAAqC,CAAC;IACvD,CAAC;SAAM,IACL,WAAW;QACX,CAAC,OAAO,WAAW,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,EAC/D,CAAC;QACD,YAAY,GAAG,mDAAmD,CAAC;IACrE,CAAC;SAAM,IACL,YAAY;QACZ,CAAC,OAAO,YAAY,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,EACjE,CAAC;QACD,YAAY,GAAG,oDAAoD,CAAC;IACtE,CAAC;IAED,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IACzC,CAAC;AACH,CAAC,uGASyB,MAAc,EAAE,IAAY;IACpD,IAAI,SAAS,GAAG,uBAAA,IAAI,mCAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAE1C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;QACtB,uBAAA,IAAI,mCAAS,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,GAAG,CAAC,CAAC,CAAC;AACxC,CAAC,2EAcC,EAAU,EACV,MAAc,EACd,IAAY,EACZ,WAAkC,EAClC,YAAmC,EACnC,aAAuB;IAEvB,MAAM,QAAQ,GAAG;QACf,EAAE;QACF,MAAM;QACN,IAAI;QACJ,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;QAChB,WAAW,EAAE,WAAW,IAAI,IAAI;QAChC,YAAY,EAAE,YAAY,IAAI,IAAI;QAClC,aAAa,EAAE,aAAa,IAAI,KAAK;KACtC,CAAC;IAEF,IAAI,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE;QACzB,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC,GAAG,QAAiB,CAAC;QAEpD,UAAU,CAAC,oBAAoB,GAAG,MAAM,CAAC,IAAI,CAC3C,UAAU,CAAC,gBAAgB,CAC5B,CAAC,MAAM,CAAC;IACX,CAAC,CAAC,CAAC;AACL,CAAC,mEAUO,EAAU;IAChB,IAAI,CAAC,uBAAA,IAAI,qCAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,4BAA4B,CAAC,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,uBAAA,IAAI,qCAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAE3B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAEzD,MAAM,SAAS,GAAG,uBAAA,IAAI,mCAAS,CAAC,GAAG,CAAC,MAAM,CAAwB,CAAC;IACnE,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3D,MAAM,eAAe,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAW,CAAC;IAEtD,IAAI,gBAAgB,KAAK,CAAC,EAAE,CAAC;QAC3B,uBAAA,IAAI,mCAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,eAAe,GAAG,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE;QACzB,OAAO,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACvC,UAAU,CAAC,oBAAoB,GAAG,MAAM,CAAC,IAAI,CAC3C,UAAU,CAAC,gBAAgB,CAC5B,CAAC,MAAM,CAAC;IACX,CAAC,CAAC,CAAC;AACL,CAAC,+EAEa,EAAU;IACtB,MAAM,SAAS,GAAG,uBAAA,IAAI,qCAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAE1C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,4BAA4B,CAAC,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC,+BAED,KAAK,qCACH,IAAY,EACZ,IAAmB,EACnB,WAAiC;IAEjC,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,yBAAyB,CAAC;YACnC,MAAM,EAAE,eAAe;YACvB,IAAI;YACJ,WAAW;SACZ,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;IACvD,CAAC;YAAS,CAAC;QACT,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,IAAI,CAAC;gBACH,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;YACvC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;YACpE,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAGH,eAAe,kBAAkB,CAAC","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n  ControllerGetStateAction,\n  StateMetadata,\n} from '@metamask/base-controller';\nimport type { ControllerStateChangeEvent } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { JsonRpcError, DataWithOptionalCause } from '@metamask/rpc-errors';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type { Json, OptionalField } from '@metamask/utils';\nimport { nanoid } from 'nanoid';\n\nimport type { ApprovalControllerMethodActions } from './ApprovalController-method-action-types';\nimport {\n  ApprovalRequestNotFoundError,\n  ApprovalRequestNoResultSupportError,\n  EndInvalidFlowError,\n  NoApprovalFlowsError,\n  MissingApprovalFlowError,\n} from './errors';\n\n// Constants\n\n// Avoiding dependency on controller-utils\nexport const ORIGIN_METAMASK = 'metamask';\nexport const APPROVAL_TYPE_RESULT_ERROR = 'result_error';\nexport const APPROVAL_TYPE_RESULT_SUCCESS = 'result_success';\n\nconst controllerName = 'ApprovalController';\n\nconst stateMetadata: StateMetadata<ApprovalControllerState> = {\n  pendingApprovals: {\n    includeInStateLogs: true,\n    persist: false,\n    includeInDebugSnapshot: true,\n    usedInUi: true,\n  },\n  pendingApprovalCount: {\n    includeInStateLogs: true,\n    persist: false,\n    includeInDebugSnapshot: false,\n    usedInUi: true,\n  },\n  approvalFlows: {\n    includeInStateLogs: true,\n    persist: false,\n    includeInDebugSnapshot: false,\n    usedInUi: true,\n  },\n};\n\nconst getAlreadyPendingMessage = (origin: string, type: string) =>\n  `Request of type '${type}' already pending for origin ${origin}. Please wait.`;\n\nconst getDefaultState = (): ApprovalControllerState => {\n  return {\n    pendingApprovals: {},\n    pendingApprovalCount: 0,\n    approvalFlows: [],\n  };\n};\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n  'acceptRequest',\n  'add',\n  'addAndShowApprovalRequest',\n  'addRequest',\n  'clearRequests',\n  'endFlow',\n  'get',\n  'getApprovalCount',\n  'getTotalApprovalCount',\n  'hasRequest',\n  'rejectRequest',\n  'setFlowLoadingText',\n  'showError',\n  'showSuccess',\n  'startFlow',\n  'updateRequestState',\n] as const;\n\n// Internal Types\n\ntype ApprovalPromiseResolve = (value?: unknown | AddResult) => void;\n\ntype ApprovalPromiseReject = (error?: unknown) => void;\n\ntype ApprovalRequestData = Record<string, Json> | null;\n\ntype ApprovalRequestState = Record<string, Json> | null;\n\ntype ApprovalCallbacks = {\n  resolve: ApprovalPromiseResolve;\n  reject: ApprovalPromiseReject;\n};\n\ntype ApprovalFlow = {\n  id: string;\n  loadingText: string | null;\n};\n\ntype ResultOptions = {\n  flowToEnd?: string;\n  header?: (string | ResultComponent)[];\n  icon?: string | null;\n  title?: string | null;\n};\n\n// Miscellaneous Types\n\nexport type ApprovalRequest<RequestData extends ApprovalRequestData> = {\n  /**\n   * The ID of the approval request.\n   */\n  id: string;\n\n  /**\n   * The origin of the approval request.\n   */\n  origin: string;\n\n  /**\n   * The time that the request was received, per Date.now().\n   */\n  time: number;\n\n  /**\n   * The type of the approval request.\n   * Unfortunately, not all values will match the `ApprovalType` enum, so we are using `string` here.\n   * TODO: Replace `string` with `ApprovalType` when all `type` values used by the clients can be encompassed by the `ApprovalType` enum.\n   */\n  type: string;\n\n  /**\n   * Additional data associated with the request.\n   */\n  requestData: RequestData;\n\n  /**\n   * Additional mutable state associated with the request\n   */\n  requestState: ApprovalRequestState;\n\n  /**\n   * Whether the request expects a result object to be returned instead of just the approval value.\n   */\n  expectsResult: boolean;\n};\n\nexport type ApprovalFlowState = ApprovalFlow;\n\nexport type ApprovalControllerState = {\n  pendingApprovals: Record<string, ApprovalRequest<Record<string, Json>>>;\n  pendingApprovalCount: number;\n  approvalFlows: ApprovalFlowState[];\n};\n\nexport type ApprovalControllerMessenger = Messenger<\n  typeof controllerName,\n  ApprovalControllerActions,\n  ApprovalControllerEvents\n>;\n\n// Option Types\n\nexport type ShowApprovalRequest = () => void | Promise<void>;\n\nexport type ResultComponent = {\n  /**\n   * A unique identifier for this instance of the component.\n   */\n  key: string;\n\n  /**\n   * The name of the component to render.\n   */\n  name: string;\n\n  /**\n   * Any properties required by the component.\n   */\n  properties?: Record<string, unknown>;\n\n  /**\n   * Any child components to render inside the component.\n   */\n  children?: string | ResultComponent | (string | ResultComponent)[];\n};\n\nexport type ApprovalControllerOptions = {\n  messenger: ApprovalControllerMessenger;\n  showApprovalRequest: ShowApprovalRequest;\n  state?: Partial<ApprovalControllerState>;\n  typesExcludedFromRateLimiting?: string[];\n};\n\nexport type AddApprovalOptions = {\n  id?: string;\n  origin: string;\n  type: string;\n  requestData?: Record<string, Json>;\n  requestState?: Record<string, Json>;\n  expectsResult?: boolean;\n};\n\nexport type UpdateRequestStateOptions = {\n  id: string;\n  requestState: Record<string, Json>;\n};\n\nexport type AcceptOptions = {\n  /**\n   * Whether to resolve the returned promise only when the request creator indicates the success of the\n   * post-approval logic using the result callbacks.\n   * If false or unspecified, the promise will resolve immediately.\n   */\n  waitForResult?: boolean;\n\n  /**\n   * Whether to delete the approval request after a result callback is called.\n   * If false or unspecified, the approval request will be deleted immediately.\n   * Ignored if `waitForResult` is false or unspecified.\n   */\n  deleteAfterResult?: boolean;\n};\n\nexport type StartFlowOptions = OptionalField<\n  ApprovalFlow,\n  'id' | 'loadingText'\n> & { show?: boolean };\n\nexport type EndFlowOptions = Pick<ApprovalFlow, 'id'>;\n\nexport type SetFlowLoadingTextOptions = ApprovalFlow;\n\nexport type SuccessOptions = ResultOptions & {\n  message?: string | ResultComponent | (string | ResultComponent)[];\n};\n\nexport type ErrorOptions = ResultOptions & {\n  error?: string | ResultComponent | (string | ResultComponent)[];\n};\n\n// Result Types\n\nexport type AcceptResultCallbacks = {\n  /**\n   * Inform the request acceptor that the post-approval logic was successful.\n   *\n   * @param value - An optional value generated by the post-approval logic.\n   */\n  success: (value?: unknown) => void;\n\n  /**\n   * Inform the request acceptor that the post-approval logic failed.\n   *\n   * @param error - The reason for the failure.\n   */\n  error: (error: Error) => void;\n};\n\nexport type AddResult = {\n  /**\n   * An optional value provided by the request acceptor.\n   */\n  value?: unknown;\n\n  /**\n   * Callback functions that must be used to indicate to the request acceptor whether the post-approval logic was successful or not.\n   * Will be undefined if the request acceptor did not specify that they want to wait for a result.\n   */\n  resultCallbacks?: AcceptResultCallbacks;\n};\n\nexport type AcceptResult = {\n  /**\n   * An optional value provided by the request creator when indicating a successful result.\n   */\n  value?: unknown;\n};\n\nexport type ApprovalFlowStartResult = ApprovalFlow;\n\nexport type SuccessResult = Record<string, never>;\n\nexport type ErrorResult = Record<string, never>;\n\n// Event Types\n\nexport type ApprovalStateChange = ControllerStateChangeEvent<\n  typeof controllerName,\n  ApprovalControllerState\n>;\n\nexport type ApprovalControllerEvents = ApprovalStateChange;\n\n// Action Types\n\nexport type ApprovalControllerGetStateAction = ControllerGetStateAction<\n  typeof controllerName,\n  ApprovalControllerState\n>;\n\nexport type ApprovalControllerActions =\n  | ApprovalControllerGetStateAction\n  | ApprovalControllerMethodActions;\n\n/**\n * Controller for managing requests that require user approval.\n *\n * Enables limiting the number of pending requests by origin and type, counting\n * pending requests, and more.\n *\n * Adding a request returns a promise that resolves or rejects when the request\n * is approved or denied, respectively.\n */\nexport class ApprovalController extends BaseController<\n  typeof controllerName,\n  ApprovalControllerState,\n  ApprovalControllerMessenger\n> {\n  readonly #approvals: Map<string, ApprovalCallbacks>;\n\n  readonly #origins: Map<string, Map<string, number>>;\n\n  readonly #showApprovalRequest: () => void;\n\n  readonly #typesExcludedFromRateLimiting: string[];\n\n  /**\n   * Construct an Approval controller.\n   *\n   * @param options - The controller options.\n   * @param options.showApprovalRequest - Function for opening the UI such that\n   * the request can be displayed to the user.\n   * @param options.messenger - The restricted messenger for the Approval controller.\n   * @param options.state - The initial controller state.\n   * @param options.typesExcludedFromRateLimiting - Array of approval types which allow multiple pending approval requests from the same origin.\n   */\n  constructor({\n    messenger,\n    showApprovalRequest,\n    state = {},\n    typesExcludedFromRateLimiting = [],\n  }: ApprovalControllerOptions) {\n    super({\n      name: controllerName,\n      metadata: stateMetadata,\n      messenger,\n      state: { ...getDefaultState(), ...state },\n    });\n\n    this.#approvals = new Map();\n    this.#origins = new Map();\n    // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n    // eslint-disable-next-line @typescript-eslint/no-misused-promises\n    this.#showApprovalRequest = showApprovalRequest;\n    this.#typesExcludedFromRateLimiting = typesExcludedFromRateLimiting;\n    this.messenger.registerMethodActionHandlers(\n      this,\n      MESSENGER_EXPOSED_METHODS,\n    );\n  }\n\n  /**\n   * Adds an approval request per the given arguments, optionally showing\n   * the approval request to the user.\n   *\n   * @param opts - Options bag.\n   * @param opts.id - The id of the approval request. A random id will be\n   * generated if none is provided.\n   * @param opts.origin - The origin of the approval request.\n   * @param opts.type - The type associated with the approval request.\n   * @param opts.requestData - Additional data associated with the request,\n   * if any.\n   * @param opts.requestState - Additional state associated with the request,\n   * if any.\n   * @param shouldShowRequest - Whether to show the approval request to the user.\n   * @returns The approval promise.\n   */\n  addRequest(\n    opts: AddApprovalOptions,\n    shouldShowRequest: boolean,\n  ): Promise<unknown> {\n    if (shouldShowRequest) {\n      return this.addAndShowApprovalRequest(opts);\n    }\n    return this.add(opts);\n  }\n\n  /**\n   * Adds an approval request per the given arguments, calls the show approval\n   * request function, and returns the associated approval promise resolving to\n   * an AddResult object.\n   *\n   * There can only be one approval per origin and type. An error is thrown if\n   * attempting to add an invalid or duplicate request.\n   *\n   * @param opts - Options bag.\n   * @param opts.id - The id of the approval request. A random id will be\n   * generated if none is provided.\n   * @param opts.origin - The origin of the approval request.\n   * @param opts.type - The type associated with the approval request.\n   * @param opts.requestData - Additional data associated with the request,\n   * @param opts.requestState - Additional state associated with the request,\n   * if any.\n   * @returns The approval promise resolving to an AddResult object.\n   */\n  addAndShowApprovalRequest(\n    opts: AddApprovalOptions & { expectsResult: true },\n  ): Promise<AddResult>;\n\n  /**\n   * Adds an approval request per the given arguments, calls the show approval\n   * request function, and returns the associated approval promise resolving\n   * to a value provided during acceptance.\n   *\n   * There can only be one approval per origin and type. An error is thrown if\n   * attempting to add an invalid or duplicate request.\n   *\n   * @param opts - Options bag.\n   * @param opts.id - The id of the approval request. A random id will be\n   * generated if none is provided.\n   * @param opts.origin - The origin of the approval request.\n   * @param opts.type - The type associated with the approval request.\n   * @param opts.requestData - Additional data associated with the request,\n   * @param opts.requestState - Additional state associated with the request,\n   * if any.\n   * @returns The approval promise resolving to a value provided during acceptance.\n   */\n  addAndShowApprovalRequest(opts: AddApprovalOptions): Promise<unknown>;\n\n  addAndShowApprovalRequest(opts: AddApprovalOptions): Promise<unknown> {\n    const promise = this.#add(\n      opts.origin,\n      opts.type,\n      opts.id,\n      opts.requestData,\n      opts.requestState,\n      opts.expectsResult,\n    );\n    this.#showApprovalRequest();\n    return promise;\n  }\n\n  /**\n   * Adds an approval request per the given arguments and returns the approval\n   * promise resolving to an AddResult object.\n   *\n   * There can only be one approval per origin and type. An error is thrown if\n   * attempting to add an invalid or duplicate request.\n   *\n   * @param opts - Options bag.\n   * @param opts.id - The id of the approval request. A random id will be\n   * generated if none is provided.\n   * @param opts.origin - The origin of the approval request.\n   * @param opts.type - The type associated with the approval request.\n   * @param opts.requestData - Additional data associated with the request,\n   * if any.\n   * @returns The approval promise resolving to an AddResult object.\n   */\n  add(opts: AddApprovalOptions & { expectsResult: true }): Promise<AddResult>;\n\n  /**\n   * Adds an approval request per the given arguments and returns the approval\n   * promise resolving to a value provided during acceptance.\n   *\n   * There can only be one approval per origin and type. An error is thrown if\n   * attempting to add an invalid or duplicate request.\n   *\n   * @param opts - Options bag.\n   * @param opts.id - The id of the approval request. A random id will be\n   * generated if none is provided.\n   * @param opts.origin - The origin of the approval request.\n   * @param opts.type - The type associated with the approval request.\n   * @param opts.requestData - Additional data associated with the request,\n   * if any.\n   * @returns The approval promise resolving to a value provided during acceptance.\n   */\n  add(opts: AddApprovalOptions): Promise<unknown>;\n\n  add(opts: AddApprovalOptions): Promise<unknown | AddResult> {\n    return this.#add(\n      opts.origin,\n      opts.type,\n      opts.id,\n      opts.requestData,\n      opts.requestState,\n      opts.expectsResult,\n    );\n  }\n\n  /**\n   * Gets the info for the approval request with the given id.\n   *\n   * @param id - The id of the approval request.\n   * @returns The approval request data associated with the id.\n   */\n  get(id: string): ApprovalRequest<ApprovalRequestData> | undefined {\n    return this.state.pendingApprovals[id];\n  }\n\n  /**\n   * Gets the number of pending approvals, by origin and/or type.\n   *\n   * If only `origin` is specified, all approvals for that origin will be\n   * counted, regardless of type.\n   * If only `type` is specified, all approvals for that type will be counted,\n   * regardless of origin.\n   * If both `origin` and `type` are specified, 0 or 1 will be returned.\n   *\n   * @param opts - The approval count options.\n   * @param opts.origin - An approval origin.\n   * @param opts.type - The type of the approval request.\n   * @returns The current approval request count for the given origin and/or\n   * type.\n   */\n  getApprovalCount(opts: { origin?: string; type?: string } = {}): number {\n    if (!opts.origin && !opts.type) {\n      throw new Error('Must specify origin, type, or both.');\n    }\n    const { origin, type: _type } = opts;\n\n    if (origin && _type) {\n      return this.#origins.get(origin)?.get(_type) || 0;\n    }\n\n    if (origin) {\n      return Array.from(\n        (this.#origins.get(origin) || new Map()).values(),\n      ).reduce((total, value) => total + value, 0);\n    }\n\n    // Only \"type\" was specified\n    let count = 0;\n    for (const approval of Object.values(this.state.pendingApprovals)) {\n      if (approval.type === _type) {\n        count += 1;\n      }\n    }\n    return count;\n  }\n\n  /**\n   * Get the total count of all pending approval requests for all origins.\n   *\n   * @returns The total pending approval request count.\n   */\n  getTotalApprovalCount(): number {\n    return this.state.pendingApprovalCount;\n  }\n\n  /**\n   * Checks if there's a pending approval request per the given parameters.\n   * At least one parameter must be specified. An error will be thrown if the\n   * parameters are invalid.\n   *\n   * If `id` is specified, all other parameters will be ignored.\n   * If `id` is not specified, the method will check for requests that match\n   * all of the specified parameters.\n   *\n   * @param opts - Options bag.\n   * @param opts.id - The ID to check for.\n   * @param opts.origin - The origin to check for.\n   * @param opts.type - The type to check for.\n   * @returns `true` if a matching approval is found, and `false` otherwise.\n   */\n  hasRequest(\n    opts: { id?: string; origin?: string; type?: string } = {},\n  ): boolean {\n    const { id, origin, type: _type } = opts;\n\n    if (id) {\n      if (typeof id !== 'string') {\n        throw new Error('May not specify non-string id.');\n      }\n      return this.#approvals.has(id);\n    }\n\n    if (_type && typeof _type !== 'string') {\n      throw new Error('May not specify non-string type.');\n    }\n\n    if (origin) {\n      if (typeof origin !== 'string') {\n        throw new Error('May not specify non-string origin.');\n      }\n\n      // Check origin and type pair if type also specified\n      if (_type) {\n        return Boolean(this.#origins.get(origin)?.get(_type));\n      }\n      return this.#origins.has(origin);\n    }\n\n    if (_type) {\n      for (const approval of Object.values(this.state.pendingApprovals)) {\n        if (approval.type === _type) {\n          return true;\n        }\n      }\n      return false;\n    }\n    throw new Error(\n      'Must specify a valid combination of id, origin, and type.',\n    );\n  }\n\n  /**\n   * Resolves the promise of the approval with the given id, and deletes the\n   * approval. Throws an error if no such approval exists.\n   *\n   * @param id - The id of the approval request.\n   * @param value - The value to resolve the approval promise with.\n   * @param options - Options bag.\n   * @returns A promise that either resolves once a result is provided by\n   * the creator of the approval request, or immediately if `options.waitForResult`\n   * is `false` or `undefined`.\n   */\n  acceptRequest(\n    id: string,\n    value?: unknown,\n    options?: AcceptOptions,\n  ): Promise<AcceptResult> {\n    // Safe to cast as the delete method below will throw if the ID is not found\n    const approval = this.get(id) as ApprovalRequest<ApprovalRequestData>;\n    const requestPromise = this.#getCallbacks(id);\n    let requestDeleted = false;\n\n    if (!options?.deleteAfterResult || !options.waitForResult) {\n      this.#delete(id);\n      requestDeleted = true;\n    }\n\n    return new Promise<AcceptResult>((resolve, reject) => {\n      const resultCallbacks: AcceptResultCallbacks = {\n        success: (acceptValue?: unknown) => resolve({ value: acceptValue }),\n        error: reject,\n      };\n\n      if (options?.waitForResult && !approval.expectsResult) {\n        reject(new ApprovalRequestNoResultSupportError(id));\n        return;\n      }\n\n      const resultValue = options?.waitForResult ? resultCallbacks : undefined;\n\n      const resolveValue = approval.expectsResult\n        ? { value, resultCallbacks: resultValue }\n        : value;\n\n      requestPromise.resolve(resolveValue);\n\n      if (!options?.waitForResult) {\n        resolve({ value: undefined });\n      }\n    }).finally(() => {\n      if (!requestDeleted) {\n        this.#delete(id);\n      }\n    });\n  }\n\n  /**\n   * Rejects the promise of the approval with the given id, and deletes the\n   * approval. Throws an error if no such approval exists.\n   *\n   * @param id - The id of the approval request.\n   * @param error - The error to reject the approval promise with.\n   */\n  rejectRequest(id: string, error: unknown): void {\n    const callbacks = this.#getCallbacks(id);\n    this.#delete(id);\n    callbacks.reject(error);\n  }\n\n  /**\n   * Rejects and deletes all approval requests.\n   *\n   * @param rejectionError - The JsonRpcError to reject the approval\n   * requests with.\n   */\n  clearRequests(rejectionError: JsonRpcError<DataWithOptionalCause>): void {\n    for (const id of this.#approvals.keys()) {\n      this.rejectRequest(id, rejectionError);\n    }\n    this.#origins.clear();\n    this.update((draftState) => {\n      draftState.pendingApprovals = {};\n      draftState.pendingApprovalCount = 0;\n    });\n  }\n\n  /**\n   * Updates the request state of the approval with the given id.\n   *\n   * @param opts - Options bag.\n   * @param opts.id - The id of the approval request.\n   * @param opts.requestState - Additional data associated with the request\n   */\n  updateRequestState(opts: UpdateRequestStateOptions): void {\n    if (!this.state.pendingApprovals[opts.id]) {\n      throw new ApprovalRequestNotFoundError(opts.id);\n    }\n\n    this.update((draftState) => {\n      draftState.pendingApprovals[opts.id].requestState =\n        opts.requestState as never;\n    });\n  }\n\n  /**\n   * Starts a new approval flow.\n   *\n   * @param opts - Options bag.\n   * @param opts.id - The id of the approval flow.\n   * @param opts.loadingText - The loading text that will be associated to the approval flow.\n   * @param opts.show - A flag to determine whether the approval should show to the user.\n   * @returns The object containing the approval flow id.\n   */\n  startFlow(opts: StartFlowOptions = {}): ApprovalFlowStartResult {\n    const id = opts.id ?? nanoid();\n    const loadingText = opts.loadingText ?? null;\n\n    this.update((draftState) => {\n      draftState.approvalFlows.push({ id, loadingText });\n    });\n\n    // By default, if nothing else is specified, we always show the approval.\n    if (opts.show !== false) {\n      this.#showApprovalRequest();\n    }\n\n    return { id, loadingText };\n  }\n\n  /**\n   * Ends the current approval flow.\n   *\n   * @param opts - Options bag.\n   * @param opts.id - The id of the approval flow that will be finished.\n   */\n  endFlow({ id }: EndFlowOptions) {\n    if (!this.state.approvalFlows.length) {\n      throw new NoApprovalFlowsError();\n    }\n\n    const currentFlow = this.state.approvalFlows.slice(-1)[0];\n\n    if (id !== currentFlow.id) {\n      throw new EndInvalidFlowError(\n        id,\n        this.state.approvalFlows.map((flow) => flow.id),\n      );\n    }\n\n    this.update((draftState) => {\n      draftState.approvalFlows.pop();\n    });\n  }\n\n  /**\n   * Sets the loading text for the approval flow.\n   *\n   * @param opts - Options bag.\n   * @param opts.id - The approval flow loading text that will be displayed.\n   * @param opts.loadingText - The loading text that will be associated to the approval flow.\n   */\n  setFlowLoadingText({ id, loadingText }: SetFlowLoadingTextOptions) {\n    const flowIndex = this.state.approvalFlows.findIndex(\n      (flow) => flow.id === id,\n    );\n\n    if (flowIndex === -1) {\n      throw new MissingApprovalFlowError(id);\n    }\n\n    this.update((draftState) => {\n      draftState.approvalFlows[flowIndex].loadingText = loadingText;\n    });\n  }\n\n  /**\n   * Show a success page.\n   *\n   * @param opts - Options bag.\n   * @param opts.message - The message text or components to display in the page.\n   * @param opts.header - The text or components to display in the header of the page.\n   * @param opts.flowToEnd - The ID of the approval flow to end once the success page is approved.\n   * @param opts.title - The title to display above the message. Shown by default but can be hidden with `null`.\n   * @param opts.icon - The icon to display in the page. Shown by default but can be hidden with `null`.\n   * @returns Empty object to support future additions.\n   */\n  async showSuccess(opts: SuccessOptions = {}): Promise<SuccessResult> {\n    await this.#result(APPROVAL_TYPE_RESULT_SUCCESS, opts, {\n      message: opts.message,\n      header: opts.header,\n      title: opts.title,\n      icon: opts.icon,\n    } as Record<string, Json>);\n\n    return {};\n  }\n\n  /**\n   * Show an error page.\n   *\n   * @param opts - Options bag.\n   * @param opts.message - The message text or components to display in the page.\n   * @param opts.header - The text or components to display in the header of the page.\n   * @param opts.flowToEnd - The ID of the approval flow to end once the error page is approved.\n   * @param opts.title - The title to display above the message. Shown by default but can be hidden with `null`.\n   * @param opts.icon - The icon to display in the page. Shown by default but can be hidden with `null`.\n   * @returns Empty object to support future additions.\n   */\n  async showError(opts: ErrorOptions = {}): Promise<ErrorResult> {\n    await this.#result(APPROVAL_TYPE_RESULT_ERROR, opts, {\n      error: opts.error,\n      header: opts.header,\n      title: opts.title,\n      icon: opts.icon,\n    } as Record<string, Json>);\n\n    return {};\n  }\n\n  /**\n   * Implementation of add operation.\n   *\n   * @param origin - The origin of the approval request.\n   * @param type - The type associated with the approval request.\n   * @param id - The id of the approval request.\n   * @param requestData - The request data associated with the approval request.\n   * @param requestState - The request state associated with the approval request.\n   * @param expectsResult - Whether the approval request expects a result object to be returned.\n   * @returns The approval promise.\n   */\n  #add(\n    origin: string,\n    type: string,\n    id: string = nanoid(),\n    requestData?: Record<string, Json>,\n    requestState?: Record<string, Json>,\n    expectsResult?: boolean,\n  ): Promise<unknown | AddResult> {\n    this.#validateAddParams(id, origin, type, requestData, requestState);\n\n    if (\n      !this.#typesExcludedFromRateLimiting.includes(type) &&\n      this.hasRequest({ origin, type })\n    ) {\n      throw rpcErrors.resourceUnavailable(\n        getAlreadyPendingMessage(origin, type),\n      );\n    }\n\n    // add pending approval\n    return new Promise((resolve, reject) => {\n      this.#approvals.set(id, { resolve, reject });\n      this.#addPendingApprovalOrigin(origin, type);\n\n      this.#addToStore(\n        id,\n        origin,\n        type,\n        requestData,\n        requestState,\n        expectsResult,\n      );\n    });\n  }\n\n  /**\n   * Validates parameters to the add method.\n   *\n   * @param id - The id of the approval request.\n   * @param origin - The origin of the approval request.\n   * @param type - The type associated with the approval request.\n   * @param requestData - The request data associated with the approval request.\n   * @param requestState - The request state associated with the approval request.\n   */\n  #validateAddParams(\n    id: string,\n    origin: string,\n    type: string,\n    requestData?: Record<string, Json>,\n    requestState?: Record<string, Json>,\n  ): void {\n    let errorMessage = null;\n    if (!id || typeof id !== 'string') {\n      errorMessage = 'Must specify non-empty string id.';\n    } else if (this.#approvals.has(id)) {\n      errorMessage = `Approval request with id '${id}' already exists.`;\n    } else if (!origin || typeof origin !== 'string') {\n      errorMessage = 'Must specify non-empty string origin.';\n    } else if (!type || typeof type !== 'string') {\n      errorMessage = 'Must specify non-empty string type.';\n    } else if (\n      requestData &&\n      (typeof requestData !== 'object' || Array.isArray(requestData))\n    ) {\n      errorMessage = 'Request data must be a plain object if specified.';\n    } else if (\n      requestState &&\n      (typeof requestState !== 'object' || Array.isArray(requestState))\n    ) {\n      errorMessage = 'Request state must be a plain object if specified.';\n    }\n\n    if (errorMessage) {\n      throw rpcErrors.internal(errorMessage);\n    }\n  }\n\n  /**\n   * Adds an entry to _origins.\n   * Performs no validation.\n   *\n   * @param origin - The origin of the approval request.\n   * @param type - The type associated with the approval request.\n   */\n  #addPendingApprovalOrigin(origin: string, type: string): void {\n    let originMap = this.#origins.get(origin);\n\n    if (!originMap) {\n      originMap = new Map();\n      this.#origins.set(origin, originMap);\n    }\n\n    const currentValue = originMap.get(type) || 0;\n    originMap.set(type, currentValue + 1);\n  }\n\n  /**\n   * Adds an entry to the store.\n   * Performs no validation.\n   *\n   * @param id - The id of the approval request.\n   * @param origin - The origin of the approval request.\n   * @param type - The type associated with the approval request.\n   * @param requestData - The request data associated with the approval request.\n   * @param requestState - The request state associated with the approval request.\n   * @param expectsResult - Whether the request expects a result object to be returned.\n   */\n  #addToStore(\n    id: string,\n    origin: string,\n    type: string,\n    requestData?: Record<string, Json>,\n    requestState?: Record<string, Json>,\n    expectsResult?: boolean,\n  ): void {\n    const approval = {\n      id,\n      origin,\n      type,\n      time: Date.now(),\n      requestData: requestData || null,\n      requestState: requestState || null,\n      expectsResult: expectsResult || false,\n    };\n\n    this.update((draftState) => {\n      draftState.pendingApprovals[id] = approval as never;\n\n      draftState.pendingApprovalCount = Object.keys(\n        draftState.pendingApprovals,\n      ).length;\n    });\n  }\n\n  /**\n   * Deletes the approval with the given id.\n   *\n   * Deletion is an internal operation because approval state is solely\n   * managed by this controller.\n   *\n   * @param id - The id of the approval request to be deleted.\n   */\n  #delete(id: string): void {\n    if (!this.#approvals.has(id)) {\n      throw new ApprovalRequestNotFoundError(id);\n    }\n\n    this.#approvals.delete(id);\n\n    const { origin, type } = this.state.pendingApprovals[id];\n\n    const originMap = this.#origins.get(origin) as Map<string, number>;\n    const originTotalCount = this.getApprovalCount({ origin });\n    const originTypeCount = originMap.get(type) as number;\n\n    if (originTotalCount === 1) {\n      this.#origins.delete(origin);\n    } else {\n      originMap.set(type, originTypeCount - 1);\n    }\n\n    this.update((draftState) => {\n      delete draftState.pendingApprovals[id];\n      draftState.pendingApprovalCount = Object.keys(\n        draftState.pendingApprovals,\n      ).length;\n    });\n  }\n\n  #getCallbacks(id: string): ApprovalCallbacks {\n    const callbacks = this.#approvals.get(id);\n\n    if (!callbacks) {\n      throw new ApprovalRequestNotFoundError(id);\n    }\n\n    return callbacks;\n  }\n\n  async #result(\n    type: string,\n    opts: ResultOptions,\n    requestData: Record<string, Json>,\n  ) {\n    try {\n      await this.addAndShowApprovalRequest({\n        origin: ORIGIN_METAMASK,\n        type,\n        requestData,\n      });\n    } catch (error) {\n      console.info('Failed to display result page', error);\n    } finally {\n      if (opts.flowToEnd) {\n        try {\n          this.endFlow({ id: opts.flowToEnd });\n        } catch (error) {\n          console.info('Failed to end flow', { id: opts.flowToEnd, error });\n        }\n      }\n    }\n  }\n}\n\nexport default ApprovalController;\n"]}