{"version":3,"sources":["../src/utils/errors/LocalSaveEncryptionKeyError.ts","../src/utils/errors/LocalSaveError.ts","../src/utils/logger.ts","../src/utils/utils.ts","../src/internal/crypto.ts","../src/internal/transactions.ts","../src/utils/errors/LocalSaveConfigError.ts","../src/index.ts"],"names":["LocalSaveEncryptionKeyError","message","options","LocalSaveError","Logger","args","isEncryptionKeyDefined","key","isValidEncryptionKey","arrayBufferToBase64","buffer","binary","bytes","len","i","base64ToArrayBuffer","base64","binary_string","LocalSaveCrypto","config","sourceKey","keyBytes","importPromise","error","data","iv","generatedKey","dataBuffer","encryptedData","ivUint8","encryptedDataUint8","concatenatedArray","base64Data","encryptedBase64Data","arrayBuffer","decryptedBufferData","decryptedData","wrapRequestWithTransaction","request","transaction","onRequestError","onTransactionError","onTransactionAbort","onTransactionComplete","resolve","reject","settled","requestError","settleResolve","settleReject","LocalSaveConfigError","LocalSave","version","openRequest","blockedTimeout","db","category","stores","mode","currVersion","dbVersion","store","itemKey","payload","getRequest","result","clearError","keysRequest","keys","thresholdMs","checkDate","keysToDelete","scannedCount","cursorRequest","scanFinished","pendingDecryptions","decryptionError","maybeResolve","cursor","value","item","writeStore","settleTx","deleteRequest","index_default"],"mappings":"aAAA,IAAqBA,CAAAA,CAArB,cAAyD,KAAM,CAC3D,WAAA,CAAYC,EAAiBC,CAAAA,CAAwB,CACjD,KAAA,CAAMD,CAAAA,CAASC,CAAO,CAAA,CACtB,KAAK,IAAA,CAAO,8BAChB,CACJ,CAAA,CCLA,IAAqBC,CAAAA,CAArB,cAA4C,KAAM,CAC9C,WAAA,CAAYF,CAAAA,CAAiBC,CAAAA,CAAwB,CACjD,KAAA,CAAMD,EAASC,CAAO,CAAA,CACtB,IAAA,CAAK,IAAA,CAAO,iBAChB,CACJ,CAAA,CCLA,IAAqBE,CAAAA,CAArB,KAA4B,CACxB,WAAA,EAAc,CACV,MAAM,IAAI,KAAA,CAAM,oCAAoC,CACxD,CACA,OAAO,GAAA,CAAIH,CAAAA,CAAAA,GAAoBI,CAAAA,CAAiB,CAC5C,OAAA,CAAQ,GAAA,CAAI,CAAA,kBAAA,EAAqBJ,CAAO;AAAA,CAAA,CAAM,GAAGI,CAAI,EACzD,CACA,OAAO,IAAA,CAAKJ,CAAAA,CAAAA,GAAoBI,CAAAA,CAAiB,CAC7C,OAAA,CAAQ,IAAA,CAAK,CAAA,mBAAA,EAAsBJ,CAAO;AAAA,CAAA,CAAM,GAAGI,CAAI,EAC3D,CACA,OAAO,KAAA,CAAMJ,CAAAA,CAAAA,GAAoBI,CAAAA,CAAiB,CAC9C,OAAA,CAAQ,KAAA,CAAM,CAAA,oBAAA,EAAuBJ,CAAO;AAAA,CAAA,CAAM,GAAGI,CAAI,EAC7D,CACA,OAAO,IAAA,CAAKJ,CAAAA,CAAAA,GAAoBI,CAAAA,CAAiB,CAC7C,OAAA,CAAQ,IAAA,CAAK,CAAA,mBAAA,EAAsBJ,CAAO;AAAA,CAAA,CAAM,GAAGI,CAAI,EAC3D,CACA,OAAO,KAAA,CAAMJ,CAAAA,CAAAA,GAAoBI,CAAAA,CAAiB,CAC9C,OAAA,CAAQ,KAAA,CAAM,CAAA,oBAAA,EAAuBJ,CAAO;AAAA,CAAA,CAAM,GAAGI,CAAI,EAC7D,CACJ,CAAA,CCZO,SAASC,CAAAA,CAAuBC,CAAAA,CAA+C,CAClF,OAAO,OAAOA,CAAAA,EAAQ,QAAA,EAAYA,CAAAA,CAAI,MAAA,CAAS,CACnD,CAWO,SAASC,CAAAA,CAAqBD,CAAAA,CAAsB,CACvD,OAAOA,CAAAA,CAAI,MAAA,CAAS,CAAA,EAAK,CAAC,IAAA,CAAK,IAAA,CAAKA,CAAG,CAAA,EAAK,CAAC,EAAA,CAAI,EAAA,CAAI,EAAE,CAAA,CAAE,QAAA,CAASA,CAAAA,CAAI,MAAM,CAChF,CAWO,SAASE,CAAAA,CAAoBC,CAAAA,CAA6B,CAC7D,IAAIC,CAAAA,CAAS,EAAA,CACPC,CAAAA,CAAQ,IAAI,UAAA,CAAWF,CAAM,CAAA,CAC7BG,CAAAA,CAAMD,CAAAA,CAAM,UAAA,CAClB,IAAA,IAASE,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAID,CAAAA,CAAKC,IACrBH,CAAAA,EAAU,MAAA,CAAO,YAAA,CAAaC,CAAAA,CAAME,CAAC,CAAC,CAAA,CAE1C,OAAO,MAAA,CAAO,IAAA,CAAKH,CAAM,CAC7B,CAWO,SAASI,CAAAA,CAAoBC,CAAAA,CAA6B,CAC7D,IAAMC,CAAAA,CAAgB,MAAA,CAAO,IAAA,CAAKD,CAAM,CAAA,CAClCH,CAAAA,CAAMI,CAAAA,CAAc,MAAA,CACpBL,CAAAA,CAAQ,IAAI,UAAA,CAAWC,CAAG,CAAA,CAChC,IAAA,IAASC,EAAI,CAAA,CAAGA,CAAAA,CAAID,CAAAA,CAAKC,CAAAA,EAAAA,CACrBF,CAAAA,CAAME,CAAC,CAAA,CAAIG,CAAAA,CAAc,UAAA,CAAWH,CAAC,CAAA,CAEzC,OAAOF,CAAAA,CAAM,MACjB,CCrCO,IAAMM,CAAAA,CAAN,KAAsB,CACjB,WAAA,CACA,WAAA,CACA,sBAAA,CACA,qBAAA,CAES,gBAAA,CACA,gBAAA,CAOjB,WAAA,CAAYC,CAAAA,CAA+B,CACvC,IAAA,CAAK,gBAAA,CAAmBA,CAAAA,CAAO,gBAAA,CAC/B,KAAK,gBAAA,CAAmBA,CAAAA,CAAO,iBACnC,CAQQ,cAAA,EAA8B,CAClC,OAAK,IAAA,CAAK,WAAA,GACN,IAAA,CAAK,WAAA,CAAc,IAAI,WAAA,CAAA,CAEpB,IAAA,CAAK,WAChB,CAQQ,cAAA,EAA8B,CAClC,OAAK,IAAA,CAAK,WAAA,GACN,IAAA,CAAK,WAAA,CAAc,IAAI,WAAA,CAAA,CAEpB,IAAA,CAAK,WAChB,CAWA,MAAc,aAAA,EAAoC,CAC9C,IAAMC,CAAAA,CAAY,IAAA,CAAK,gBAAA,EAAiB,CACxC,GAAI,CAACd,CAAAA,CAAuBc,CAAS,CAAA,CACjC,MAAM,IAAIpB,CAAAA,CAA4B,kCAAkC,CAAA,CAE5E,GAAI,CAACQ,CAAAA,CAAqBY,CAAS,CAAA,CAC/B,MAAM,IAAIpB,CAAAA,CACN,2FACJ,CAAA,CAEJ,GAAI,IAAA,CAAK,sBAAA,EAA0B,IAAA,CAAK,qBAAA,GAA0BoB,CAAAA,CAC9D,OAAO,IAAA,CAAK,uBAGhB,IAAMC,CAAAA,CAAW,IAAA,CAAK,cAAA,EAAe,CAAE,MAAA,CAAOD,CAAS,CAAA,CACjDE,CAAAA,CAAgB,MAAA,CAAO,MAAA,CACxB,SAAA,CAAU,KAAA,CAAOD,CAAAA,CAAU,CAAE,IAAA,CAAM,SAAU,CAAA,CAAG,KAAA,CAAO,CAAC,SAAA,CAAW,SAAS,CAAC,CAAA,CAC7E,IAAA,CAAMd,CAAAA,GACC,IAAA,CAAK,gBAAA,EAAiB,EACtBH,CAAAA,CAAO,KAAA,CAAM,uCAAA,CAAyC,CAClD,SAAA,CAAWgB,CAAAA,CAAU,MAAA,CACrB,cAAA,CAAgBC,CAAAA,CAAS,MAC7B,CAAC,CAAA,CAEEd,CAAAA,CACV,CAAA,CACA,KAAA,CAAOgB,CAAAA,EAAU,CACd,MAAI,IAAA,CAAK,sBAAA,GAA2BD,CAAAA,GAChC,IAAA,CAAK,sBAAA,CAAyB,MAAA,CAC9B,IAAA,CAAK,qBAAA,CAAwB,MAAA,CAAA,CAE3BC,CACV,CAAC,CAAA,CAEL,OAAA,IAAA,CAAK,qBAAA,CAAwBH,CAAAA,CAC7B,IAAA,CAAK,sBAAA,CAAyBE,CAAAA,CAEvBA,CACX,CAcA,MAAM,WAAA,CAAYE,CAAAA,CAA8C,CAC5D,GAAI,CACA,GAAI,CAAClB,CAAAA,CAAuB,IAAA,CAAK,gBAAA,EAAkB,CAAA,CAC/C,MAAM,IAAIN,CAAAA,CAA4B,kCAAkC,CAAA,CAE5E,IAAMyB,CAAAA,CAAK,MAAA,CAAO,MAAA,CAAO,eAAA,CAAgB,IAAI,UAAA,CAAW,EAAE,CAAC,CAAA,CACrDC,CAAAA,CAAe,MAAM,IAAA,CAAK,aAAA,EAAc,CACxCC,CAAAA,CAAa,IAAA,CAAK,cAAA,EAAe,CAAE,MAAA,CAAO,IAAA,CAAK,SAAA,CAAUH,CAAI,CAAC,CAAA,CAC9DI,CAAAA,CAAgB,MAAM,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,OAAA,CAC7C,CACI,IAAA,CAAM,SAAA,CACN,EAAA,CAAIH,CACR,CAAA,CACAC,CAAAA,CACAC,CACJ,CAAA,CACME,CAAAA,CAAU,IAAI,UAAA,CAAWJ,CAAE,CAAA,CAC3BK,EAAqB,IAAI,UAAA,CAAWF,CAAa,CAAA,CACjDG,CAAAA,CAAoB,IAAI,UAAA,CAAWF,CAAAA,CAAQ,UAAA,CAAaC,CAAAA,CAAmB,UAAU,CAAA,CAC3FC,CAAAA,CAAkB,GAAA,CAAIF,CAAAA,CAAS,CAAC,CAAA,CAChCE,CAAAA,CAAkB,GAAA,CAAID,CAAAA,CAAoBD,CAAAA,CAAQ,UAAU,CAAA,CAC5D,IAAMG,CAAAA,CAAavB,CAAAA,CAAoBsB,CAAAA,CAAkB,MAAM,CAAA,CAC/D,OAAI,IAAA,CAAK,gBAAA,IACL3B,CAAAA,CAAO,KAAA,CAAM,6BAAA,CAA+B,CACxC,gBAAA,CAAkB4B,CAAAA,CAAW,MACjC,CAAC,CAAA,CAEEA,CACX,CAAA,MAAST,CAAAA,CAAO,CACZ,MAAI,IAAA,CAAK,gBAAA,EAAiB,EACtBnB,CAAAA,CAAO,KAAA,CAAM,wBAAA,CAA0BmB,CAAK,CAAA,CAE1CA,CACV,CACJ,CAWA,MAAM,WAAA,CAAYU,CAAAA,CAA8C,CAC5D,GAAI,CACA,GAAI,CAAC3B,CAAAA,CAAuB,IAAA,CAAK,gBAAA,EAAkB,CAAA,CAC/C,MAAM,IAAIN,CAAAA,CAA4B,kCAAkC,CAAA,CAE5E,IAAMkC,CAAAA,CAAcnB,CAAAA,CAAoBkB,CAAmB,CAAA,CACrDR,CAAAA,CAAK,IAAI,UAAA,CAAWS,CAAAA,CAAa,CAAA,CAAG,EAAE,CAAA,CACtCR,CAAAA,CAAe,MAAM,IAAA,CAAK,aAAA,EAAc,CACxCE,CAAAA,CAAgB,IAAI,UAAA,CAAWM,CAAAA,CAAa,EAAE,EAC9CC,CAAAA,CAAsB,MAAM,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,OAAA,CACnD,CACI,IAAA,CAAM,SAAA,CACN,EAAA,CAAAV,CACJ,CAAA,CACAC,CAAAA,CACAE,CACJ,CAAA,CACMQ,CAAAA,CAAgB,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,cAAA,EAAe,CAAE,MAAA,CAAOD,CAAmB,CAAC,CAAA,CAClF,OAAI,IAAA,CAAK,gBAAA,EAAiB,EACtB/B,CAAAA,CAAO,KAAA,CAAM,6BAAA,CAA+B,CACxC,SAAA,CAAWgC,CAAAA,CAAc,SAC7B,CAAC,CAAA,CAEEA,CACX,CAAA,MAASb,CAAAA,CAAO,CACZ,MAAI,IAAA,CAAK,gBAAA,EAAiB,EACtBnB,CAAAA,CAAO,KAAA,CAAM,wBAAA,CAA0BmB,CAAK,CAAA,CAE1C,IAAIpB,CAAAA,CAAe,wBAAA,CAA0B,CAC/C,KAAA,CAAOoB,CAAAA,YAAiB,KAAA,CAAQA,CAAAA,CAAQ,MAC5C,CAAC,CACL,CACJ,CACJ,CAAA,CC1LO,SAASc,CAAAA,CAA2B,CACvC,OAAA,CAAAC,CAAAA,CACA,WAAA,CAAAC,CAAAA,CACA,cAAA,CAAAC,CAAAA,CACA,kBAAA,CAAAC,CAAAA,CACA,kBAAA,CAAAC,CAAAA,CACA,qBAAA,CAAAC,CACJ,CAAA,CAOkB,CACd,OAAO,IAAI,OAAA,CAAc,CAACC,CAAAA,CAASC,CAAAA,GAAW,CAC1C,IAAIC,CAAAA,CAAU,KAAA,CACVC,CAAAA,CAEEC,CAAAA,CAAgB,IAAM,CACpBF,CAAAA,GACJA,CAAAA,CAAU,KACVF,CAAAA,CAAQ,IAAI,CAAA,EAChB,CAAA,CAEMK,CAAAA,CAAgB1B,CAAAA,EAA0B,CACxCuB,CAAAA,GACJA,CAAAA,CAAU,IAAA,CACVD,CAAAA,CAAOtB,CAAK,CAAA,EAChB,CAAA,CAEAe,CAAAA,CAAQ,gBAAA,CACJ,OAAA,CACA,IAAM,CACFS,CAAAA,CAAeP,CAAAA,CAAeF,CAAAA,CAAQ,KAAK,EAC/C,CAAA,CACA,CAAE,IAAA,CAAM,IAAK,CACjB,CAAA,CAEAC,CAAAA,CAAY,gBAAA,CACR,UAAA,CACA,IAAM,CACF,GAAI,CAAAO,CAAAA,CACJ,CAAA,GAAIC,CAAAA,CAAc,CACdE,CAAAA,CAAaF,CAAY,CAAA,CACzB,MACJ,CACAJ,CAAAA,IAAwB,CACxBK,CAAAA,GAAc,CAClB,CAAA,CACA,CAAE,IAAA,CAAM,IAAK,CACjB,CAAA,CAEAT,CAAAA,CAAY,gBAAA,CACR,OAAA,CACA,IAAM,CACEO,CAAAA,EACJG,CAAAA,CAAaF,CAAAA,EAAgBN,EAAmBF,CAAAA,CAAY,KAAK,CAAC,EACtE,CAAA,CACA,CAAE,IAAA,CAAM,IAAK,CACjB,CAAA,CAEAA,CAAAA,CAAY,gBAAA,CACR,OAAA,CACA,IAAM,CACEO,CAAAA,EACJG,CAAAA,CAAaF,CAAAA,EAAgBL,CAAAA,CAAmBH,CAAAA,CAAY,KAAK,CAAC,EACtE,CAAA,CACA,CAAE,IAAA,CAAM,IAAK,CACjB,EACJ,CAAC,CACL,CC5FA,IAAqBW,CAAAA,CAArB,cAAkD,KAAM,CACpD,WAAA,CAAYjD,CAAAA,CAAiBC,CAAAA,CAAwB,CACjD,KAAA,CAAMD,CAAAA,CAASC,CAAO,CAAA,CACtB,IAAA,CAAK,IAAA,CAAO,uBAChB,CACJ,CAAA,CCeA,IAAMiD,CAAAA,CAAN,KAAgB,CACZ,MAAA,CAAiB,WAAA,CACjB,aAAA,CACQ,MAAA,CACR,UAAA,CAAyB,CAAC,UAAU,CAAA,CACpC,eAAA,CAAkC,GAAA,CAAU,EAAA,CAAK,GAAK,GAAA,CACtD,uBAAA,CAA0C,EAAA,CAAK,GAAA,CAC/C,mBAAA,CAA+B,IAAA,CAC/B,SAAA,CAAqB,KAAA,CAsBrB,WAAA,CAAYhC,CAAAA,CAAiB,CAazB,GAZA,IAAA,CAAK,MAAA,CAASA,CAAAA,EAAQ,MAAA,EAAU,IAAA,CAAK,MAAA,CACrC,IAAA,CAAK,aAAA,CAAgBA,CAAAA,EAAQ,aAAA,CAC7B,IAAA,CAAK,UAAA,CAAaA,CAAAA,EAAQ,UAAA,EAAc,IAAA,CAAK,UAAA,CAC7C,IAAA,CAAK,mBAAA,CAAsBA,CAAAA,EAAQ,mBAAA,EAAuB,IAAA,CAAK,mBAAA,CAC/D,IAAA,CAAK,eAAA,CAAkBA,CAAAA,EAAQ,eAAA,EAAmB,IAAA,CAAK,eAAA,CACvD,IAAA,CAAK,uBAAA,CAA0BA,CAAAA,EAAQ,uBAAA,EAA2B,IAAA,CAAK,uBAAA,CACvE,IAAA,CAAK,SAAA,CAAYA,CAAAA,EAAQ,SAAA,EAAa,IAAA,CAAK,SAAA,CAC3C,IAAA,CAAK,MAAA,CAAS,IAAID,CAAAA,CAAgB,CAC9B,gBAAA,CAAkB,IAAM,IAAA,CAAK,aAAA,CAC7B,gBAAA,CAAkB,IAAM,IAAA,CAAK,SACjC,CAAC,CAAA,CAEGC,CAAAA,EAAQ,aAAA,GAAkB,MAAA,EAAa,CAACX,CAAAA,CAAqBW,CAAAA,CAAO,aAAa,CAAA,CACjF,MAAM,IAAI+B,CAAAA,CACN,2FACJ,CAAA,CACG,GACH,OAAO,IAAA,CAAK,eAAA,EAAoB,QAAA,EAChC,CAAC,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,eAAe,CAAA,EACrC,IAAA,CAAK,eAAA,EAAmB,CAAA,CAExB,MAAM,IAAIA,CAAAA,CAAqB,6CAA6C,CAAA,CACzE,GACH,OAAO,IAAA,CAAK,uBAAA,EAA4B,QAAA,EACxC,CAAC,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,uBAAuB,CAAA,EAC7C,IAAA,CAAK,uBAAA,EAA2B,CAAA,CAEhC,MAAM,IAAIA,CAAAA,CAAqB,qDAAqD,CAE5F,CAYQ,MAAA,CAAOE,CAAAA,CAAwC,CACnD,OAAO,IAAI,OAAA,CAAqB,CAACR,CAAAA,CAASC,CAAAA,GAAW,CACjD,IAAMQ,EAAc,SAAA,CAAU,IAAA,CAAK,IAAA,CAAK,MAAA,CAAQD,CAAO,CAAA,CACnDN,CAAAA,CAAU,KAAA,CACVQ,CAAAA,CAEEN,CAAAA,CAAiBO,CAAAA,EAAoB,CACvC,GAAIT,CAAAA,CAAS,CACTS,CAAAA,CAAG,KAAA,EAAM,CACT,MACJ,CACAT,CAAAA,CAAU,IAAA,CACNQ,CAAAA,EACA,YAAA,CAAaA,CAAc,CAAA,CAE/BV,CAAAA,CAAQW,CAAE,EACd,CAAA,CAEMN,CAAAA,CAAgB1B,CAAAA,EAA0B,CACxCuB,CAAAA,GACJA,CAAAA,CAAU,IAAA,CACNQ,CAAAA,EACA,YAAA,CAAaA,CAAc,CAAA,CAE/BT,CAAAA,CAAOtB,CAAK,CAAA,EAChB,CAAA,CAEA8B,CAAAA,CAAY,eAAA,CAAkB,IAAM,CAChC,IAAME,CAAAA,CAAKF,CAAAA,CAAY,MAAA,CACnB,IAAA,CAAK,SAAA,EACLjD,CAAAA,CAAO,KAAA,CAAM,4BAAA,CAA8B,CACvC,MAAA,CAAQ,IAAA,CAAK,MAAA,CACb,OAAA,CAASmD,CAAAA,CAAG,OAChB,CAAC,CAAA,CAEL,IAAA,IAAWC,CAAAA,IAAY,IAAA,CAAK,UAAA,CACnBD,CAAAA,CAAG,gBAAA,CAAiB,QAAA,CAASC,CAAQ,CAAA,GAClC,IAAA,CAAK,SAAA,EACLpD,CAAAA,CAAO,KAAA,CAAM,uBAAA,CAAyB,CAClC,QAAA,CAAAoD,CACJ,CAAC,CAAA,CAELD,CAAAA,CAAG,iBAAA,CAAkBC,CAAQ,CAAA,EAGzC,CAAA,CACAH,CAAAA,CAAY,SAAA,CAAY,IAAM,CAC1B,IAAME,CAAAA,CAAKF,CAAAA,CAAY,OACvBE,CAAAA,CAAG,eAAA,CAAkB,IAAM,CACnB,IAAA,CAAK,SAAA,EACLnD,CAAAA,CAAO,IAAA,CAAK,CAAA,4DAAA,EAA+D,IAAA,CAAK,MAAM,CAAA,CAAA,CAAG,CAAA,CAE7FmD,CAAAA,CAAG,KAAA,GACP,CAAA,CACI,IAAA,CAAK,SAAA,EACLnD,CAAAA,CAAO,KAAA,CAAM,8BAAA,CAAgC,CACzC,MAAA,CAAQ,IAAA,CAAK,MAAA,CACb,OAAA,CAASmD,CAAAA,CAAG,OAChB,CAAC,CAAA,CAELP,CAAAA,CAAcO,CAAE,EACpB,CAAA,CACAF,CAAAA,CAAY,OAAA,CAAU,IAAM,CACpB,IAAA,CAAK,SAAA,EACLjD,CAAAA,CAAO,KAAA,CAAM,CAAA,wCAAA,EAA2C,IAAA,CAAK,MAAM,CAAA,CAAA,CAAA,CAAKiD,CAAAA,CAAY,KAAK,CAAA,CAE7FJ,CAAAA,CAAa,IAAI9C,CAAAA,CAAekD,CAAAA,CAAY,KAAA,EAAO,OAAA,EAAW,wBAAwB,CAAC,EAC3F,CAAA,CACAA,CAAAA,CAAY,SAAA,CAAY,IAAM,CACtB,IAAA,CAAK,WACLjD,CAAAA,CAAO,IAAA,CACH,CAAA,kFAAA,EAAqF,IAAA,CAAK,uBAAuB,CAAA,8BAAA,EAAiC,IAAA,CAAK,MAAM,CAAA,CAAA,CACjK,CAAA,CAEA,EAAAkD,CAAAA,EAAkBR,CAAAA,CAAAA,GACtBQ,CAAAA,CAAiB,UAAA,CAAW,IAAM,CAC9BL,CAAAA,CACI,IAAI9C,CAAAA,CACA,CAAA,iCAAA,EAAoC,IAAA,CAAK,uBAAuB,CAAA,6CAAA,CACpE,CACJ,EACJ,CAAA,CAAG,IAAA,CAAK,uBAAuB,CAAA,EACnC,EACJ,CAAC,CACL,CASA,MAAc,UAAA,EAAkC,CAC5C,IAAMoD,CAAAA,CAAK,MAAM,IAAA,CAAK,MAAA,EAAO,CAC7B,GAAI,CACA,IAAME,CAAAA,CAAS,KAAA,CAAM,IAAA,CAAKF,CAAAA,CAAG,gBAAgB,CAAA,CAC7C,OAAI,IAAA,CAAK,SAAA,EACLnD,CAAAA,CAAO,KAAA,CAAM,mCAAA,CAAqC,CAC9C,MAAA,CAAAqD,CACJ,CAAC,CAAA,CAEEA,CACX,CAAA,OAAE,CACEF,CAAAA,CAAG,KAAA,GACP,CACJ,CAiBA,MAAc,QAAA,CAASC,CAAAA,CAAoBE,CAAAA,CAA2B,UAAA,CAAqC,CACvG,IAAIH,CAAAA,CAAK,MAAM,IAAA,CAAK,MAAA,EAAO,CAC3B,GAAI,CAACA,CAAAA,CAAG,gBAAA,CAAiB,QAAA,CAASC,CAAQ,CAAA,EAAK,IAAA,CAAK,UAAA,CAAW,QAAA,CAASA,CAAQ,CAAA,CAAG,CAC3E,IAAA,CAAK,SAAA,EACLpD,EAAO,KAAA,CACH,CAAA;AAAA,mDAAA,CAAA,CACA,CACI,QAAA,CAAAoD,CAAAA,CACA,OAAQ,IAAA,CAAK,MAAA,CACb,QAASD,CAAAA,CAAG,OAChB,CACJ,CAAA,CAEJ,IAAMI,CAAAA,CAAcJ,CAAAA,CAAG,QACvBA,CAAAA,CAAG,KAAA,GACHA,CAAAA,CAAK,MAAM,IAAA,CAAK,MAAA,CAAOI,EAAc,CAAC,EAC1C,SAAW,CAACJ,CAAAA,CAAG,iBAAiB,QAAA,CAASC,CAAQ,CAAA,CAAG,CAChD,IAAMI,CAAAA,CAAYL,CAAAA,CAAG,QACrB,MAAAA,CAAAA,CAAG,OAAM,CACH,IAAIpD,CAAAA,CACN,CAAA,uEAAA,EAA0EqD,CAAQ,CAAA,UAAA,EAAa,IAAA,CAAK,MAAM,CAAA,WAAA,EAAcI,CAAS,IACrI,CACJ,CACA,IAAIrB,CAAAA,CACJ,GAAI,CACAA,CAAAA,CAAcgB,EAAG,WAAA,CAAYC,CAAAA,CAAUE,CAAI,EAC/C,CAAA,MAASnC,CAAAA,CAAO,CACZ,MAAAgC,CAAAA,CAAG,KAAA,GACG,IAAIpD,CAAAA,CAAeoB,aAAiB,KAAA,CAAQA,CAAAA,CAAM,OAAA,CAAU,4BAA4B,CAClG,CACAgB,CAAAA,CAAY,WAAa,IAAM,CAC3BgB,EAAG,KAAA,GACP,CAAA,CACAhB,CAAAA,CAAY,QAAU,IAAM,CACxBgB,EAAG,KAAA,GACP,EACAhB,CAAAA,CAAY,OAAA,CAAU,IAAM,CACxBgB,EAAG,KAAA,GACP,EACA,IAAMM,CAAAA,CAAQtB,EAAY,WAAA,CAAYiB,CAAQ,CAAA,CAC9C,OAAI,KAAK,SAAA,EACLpD,CAAAA,CAAO,MAAM,sCAAA,CAAwC,CACjD,SAAAoD,CAAAA,CACA,IAAA,CAAAE,CAAAA,CACA,MAAA,CAAQ,KAAK,MAAA,CACb,OAAA,CAASH,EAAG,OAChB,CAAC,EAEEM,CACX,CAeA,MAAc,WAAA,CAAYrC,EAA8C,CACpE,OAAO,KAAK,MAAA,CAAO,WAAA,CAAYA,CAAI,CACvC,CAUA,MAAM,WAAA,CAAYS,EAA8C,CAC5D,OAAO,KAAK,MAAA,CAAO,WAAA,CAAYA,CAAmB,CACtD,CAcA,MAAM,GAAA,CAAIuB,EAAoBM,CAAAA,CAAiBtC,CAAAA,CAA8B,CACrE,IAAA,CAAK,SAAA,EACLpB,EAAO,KAAA,CAAM,iDAAA,CAAmD,CAC5D,QAAA,CAAAoD,CAAAA,CACA,QAAAM,CACJ,CAAC,EAEL,IAAIC,CAAAA,CAA0C,CAC1C,SAAA,CAAW,IAAA,CAAK,GAAA,EAAI,CACpB,KAAAvC,CACJ,CAAA,CACA,GAAI,CACI,IAAA,CAAK,gBACLuC,CAAAA,CAAU,MAAM,IAAA,CAAK,WAAA,CAAYA,CAAO,CAAA,CAAA,CAE5C,IAAMF,EAAQ,MAAM,IAAA,CAAK,SAASL,CAAAA,CAAU,WAAW,CAAA,CACvD,OAAOnB,EAA2B,CAC9B,OAAA,CAASwB,EAAM,GAAA,CAAIE,CAAAA,CAASD,CAAO,CAAA,CACnC,WAAA,CAAaD,CAAAA,CAAM,WAAA,CACnB,eAAiBtC,CAAAA,GACT,IAAA,CAAK,WACLnB,CAAAA,CAAO,KAAA,CAAM,yCAAyCoD,CAAQ,CAAA,OAAA,EAAUM,CAAO,CAAA,CAAA,CAAA,CAAKvC,CAAK,CAAA,CAEtF,IAAIpB,EAAeoB,CAAAA,EAAO,OAAA,EAAW,qBAAsB,CAC9D,KAAA,CAAOA,CAAAA,EAAS,KAAA,CACpB,CAAC,CAAA,CAAA,CAEL,kBAAA,CAAqBA,IACb,IAAA,CAAK,SAAA,EACLnB,EAAO,KAAA,CACH,CAAA,sEAAA,EAAyEoD,CAAQ,CAAA,OAAA,EAAUM,CAAO,CAAA,CAAA,CAAA,CAClGvC,CACJ,EAEG,IAAIpB,CAAAA,CAAeoB,GAAO,OAAA,EAAW,sCAAA,CAAwC,CAChF,KAAA,CAAOA,CAAAA,EAAS,MACpB,CAAC,CAAA,CAAA,CAEL,mBAAqBA,CAAAA,GACb,IAAA,CAAK,WACLnB,CAAAA,CAAO,IAAA,CACH,CAAA,iDAAA,EAAoDoD,CAAQ,UAAUM,CAAO,CAAA,CAAA,CAAA,CAC7EvC,CACJ,CAAA,CAEG,IAAIpB,EAAeoB,CAAAA,EAAO,OAAA,EAAW,wCAAA,CAA0C,CAClF,MAAOA,CAAAA,EAAS,KAAA,CACpB,CAAC,CAAA,CAAA,CAEL,qBAAA,CAAuB,IAAM,CACrB,IAAA,CAAK,SAAA,EACLnB,CAAAA,CAAO,MAAM,0BAAA,CAA4B,CACrC,SAAAoD,CAAAA,CACA,OAAA,CAAAM,CACJ,CAAC,EAET,CACJ,CAAC,CACL,CAAA,MAASvC,CAAAA,CAAO,CACZ,MAAI,IAAA,CAAK,WACLnB,CAAAA,CAAO,KAAA,CAAM,qBAAA,CAAuBmB,CAAK,EAEvCA,CACV,CACJ,CAeA,MAAM,GAAA,CAAIiC,EAAoBM,CAAAA,CAAyC,CAC/D,IAAA,CAAK,SAAA,EACL1D,EAAO,KAAA,CAAM,oDAAA,CAAsD,CAC/D,QAAA,CAAAoD,CAAAA,CACA,QAAAM,CACJ,CAAC,CAAA,CAEL,IAAMD,EAAQ,MAAM,IAAA,CAAK,SAASL,CAAQ,CAAA,CAC1C,OAAO,IAAI,OAAA,CAAuB,CAACZ,CAAAA,CAASC,CAAAA,GAAW,CACnD,IAAMmB,CAAAA,CAAaH,EAAM,GAAA,CAAIC,CAAO,EACpCE,CAAAA,CAAW,SAAA,CAAY,SAAY,CAC/B,IAAIC,CAAAA,CAASD,CAAAA,CAAW,OACxB,GAAI,CAACC,EACD,OAAI,IAAA,CAAK,SAAA,EACL7D,CAAAA,CAAO,MAAM,mBAAA,CAAqB,CAC9B,SAAAoD,CAAAA,CACA,OAAA,CAAAM,CACJ,CAAC,CAAA,CAEElB,CAAAA,CAAQ,IAAI,EAEvB,GAAI,OAAOqB,GAAW,QAAA,CAClB,GAAI,CACAA,CAAAA,CAAS,MAAM,IAAA,CAAK,WAAA,CAAYA,CAAM,EAC1C,CAAA,MAAS1C,EAAO,CAIZ,GAHI,KAAK,SAAA,EACLnB,CAAAA,CAAO,KAAA,CAAM,oBAAA,CAAsBmB,CAAK,CAAA,CAExC,IAAA,CAAK,oBAAqB,CACtB,IAAA,CAAK,WACLnB,CAAAA,CAAO,KAAA,CAAM,oEAAoE,CAAA,CAErF,GAAI,CACA,MAAM,KAAK,KAAA,CAAMoD,CAAQ,EAC7B,CAAA,MAASU,CAAAA,CAAY,CACjB,OAAI,KAAK,SAAA,EACL9D,CAAAA,CAAO,MAAM,+CAAA,CAAiD8D,CAAU,EAErErB,CAAAA,CACH,IAAI1C,CAAAA,CAAe,qDAAA,CAAuD,CACtE,KAAA,CAAO+D,CAAAA,YAAsB,MAAQA,CAAAA,CAAa,MACtD,CAAC,CACL,CACJ,CACJ,CACA,OAAOrB,CAAAA,CACH,IAAI1C,EAAeoB,CAAAA,YAAiB,KAAA,CAAQA,EAAM,OAAA,CAAU,wBAAwB,CACxF,CACJ,CAEJ,OAAI,IAAA,CAAK,WACLnB,CAAAA,CAAO,KAAA,CAAM,8BAA+B,CACxC,QAAA,CAAAoD,CAAAA,CACA,OAAA,CAAAM,EACA,SAAA,CAAWG,CAAAA,CAAO,SACtB,CAAC,CAAA,CAEErB,EAAQqB,CAAM,CACzB,CAAA,CACAD,CAAAA,CAAW,QAAU,IACVnB,CAAAA,CAAO,IAAI1C,CAAAA,CAAe6D,CAAAA,CAAW,OAAO,OAAA,EAAW,oBAAoB,CAAC,EAE3F,CAAC,CACL,CAOA,MAAM,cAAA,EAAsC,CACxC,OAAI,IAAA,CAAK,SAAA,EACL5D,CAAAA,CAAO,KAAA,CAAM,gDAAgD,CAAA,CAE1D,IAAA,CAAK,YAChB,CAWA,MAAM,QAAA,CAASoD,CAAAA,CAAuC,CAC9C,IAAA,CAAK,WACLpD,CAAAA,CAAO,KAAA,CAAM,kDAAmD,CAC5D,QAAA,CAAAoD,CACJ,CAAC,CAAA,CAEL,IAAMK,CAAAA,CAAQ,MAAM,KAAK,QAAA,CAASL,CAAQ,EAC1C,OAAO,IAAI,QAAkB,CAACZ,CAAAA,CAASC,CAAAA,GAAW,CAC9C,IAAMsB,CAAAA,CAAcN,CAAAA,CAAM,YAAW,CACrCM,CAAAA,CAAY,UAAY,IAAM,CAC1B,IAAMC,CAAAA,CAAOD,EAAY,MAAA,CACrB,IAAA,CAAK,WACL/D,CAAAA,CAAO,KAAA,CAAM,wCAAyC,CAClD,QAAA,CAAAoD,CAAAA,CACA,IAAA,CAAAY,CACJ,CAAC,CAAA,CAELxB,EAAQwB,CAAI,EAChB,EACAD,CAAAA,CAAY,OAAA,CAAU,IAAM,CACpB,KAAK,SAAA,EACL/D,CAAAA,CAAO,MAAM,CAAA,0CAAA,EAA6CoD,CAAQ,IAAKW,CAAAA,CAAY,KAAK,CAAA,CAE5FtB,CAAAA,CAAO,IAAI1C,CAAAA,CAAegE,CAAAA,CAAY,OAAO,OAAA,EAAW,oBAAoB,CAAC,EACjF,EACJ,CAAC,CACL,CAYA,MAAM,MAAA,CAAOX,EAAoBM,CAAAA,CAAgC,CACzD,KAAK,SAAA,EACL1D,CAAAA,CAAO,KAAA,CAAM,qDAAA,CAAuD,CAChE,QAAA,CAAAoD,CAAAA,CACA,QAAAM,CACJ,CAAC,EAEL,IAAMD,CAAAA,CAAQ,MAAM,IAAA,CAAK,QAAA,CAASL,EAAU,WAAW,CAAA,CACvD,OAAOnB,CAAAA,CAA2B,CAC9B,QAASwB,CAAAA,CAAM,MAAA,CAAOC,CAAO,CAAA,CAC7B,YAAaD,CAAAA,CAAM,WAAA,CACnB,eAAiBtC,CAAAA,GACT,IAAA,CAAK,WACLnB,CAAAA,CAAO,KAAA,CAAM,CAAA,qCAAA,EAAwCoD,CAAQ,UAAUM,CAAO,CAAA,CAAA,CAAA,CAAKvC,CAAK,CAAA,CAErF,IAAIpB,EAAeoB,CAAAA,EAAO,OAAA,EAAW,qBAAA,CAAuB,CAC/D,MAAOA,CAAAA,EAAS,MACpB,CAAC,CAAA,CAAA,CAEL,kBAAA,CAAqBA,IACb,IAAA,CAAK,SAAA,EACLnB,CAAAA,CAAO,KAAA,CACH,0EAA0EoD,CAAQ,CAAA,OAAA,EAAUM,CAAO,CAAA,CAAA,CAAA,CACnGvC,CACJ,EAEG,IAAIpB,CAAAA,CAAeoB,CAAAA,EAAO,OAAA,EAAW,uCAAwC,CAChF,KAAA,CAAOA,GAAS,MACpB,CAAC,GAEL,kBAAA,CAAqBA,CAAAA,GACb,IAAA,CAAK,SAAA,EACLnB,EAAO,IAAA,CACH,CAAA,kDAAA,EAAqDoD,CAAQ,CAAA,OAAA,EAAUM,CAAO,IAC9EvC,CACJ,CAAA,CAEG,IAAIpB,CAAAA,CAAeoB,GAAO,OAAA,EAAW,yCAAA,CAA2C,CACnF,KAAA,CAAOA,CAAAA,EAAS,MACpB,CAAC,CAAA,CAAA,CAEL,sBAAuB,IAAM,CACrB,KAAK,SAAA,EACLnB,CAAAA,CAAO,MAAM,2BAAA,CAA6B,CACtC,SAAAoD,CAAAA,CACA,OAAA,CAAAM,CACJ,CAAC,EAET,CACJ,CAAC,CACL,CAWA,MAAM,MAAMN,CAAAA,CAAmC,CACvC,IAAA,CAAK,SAAA,EACLpD,EAAO,KAAA,CAAM,CAAA,wCAAA,EAA2CoD,CAAQ,CAAA,UAAA,CAAY,CAAA,CAEhF,IAAMK,CAAAA,CAAQ,MAAM,IAAA,CAAK,QAAA,CAASL,EAAU,WAAW,CAAA,CACvD,OAAOnB,CAAAA,CAA2B,CAC9B,QAASwB,CAAAA,CAAM,KAAA,EAAM,CACrB,WAAA,CAAaA,EAAM,WAAA,CACnB,cAAA,CAAiBtC,IACT,IAAA,CAAK,SAAA,EACLnB,EAAO,KAAA,CACH,CAAA,uCAAA,EAA0CoD,CAAQ,CAAA,UAAA,EAAa,KAAK,MAAM,CAAA,WAAA,EAAcK,EAAM,WAAA,CAAY,EAAA,CAAG,OAAO,CAAA,CAAA,CAAA,CACpHtC,CACJ,CAAA,CAEG,IAAIpB,EAAeoB,CAAAA,EAAO,OAAA,EAAW,sBAAuB,CAC/D,KAAA,CAAOA,GAAS,MACpB,CAAC,CAAA,CAAA,CAEL,kBAAA,CAAqBA,IACb,IAAA,CAAK,SAAA,EACLnB,EAAO,KAAA,CACH,CAAA,uEAAA,EAA0EoD,CAAQ,CAAA,UAAA,EAAa,IAAA,CAAK,MAAM,CAAA,WAAA,EAAcK,EAAM,WAAA,CAAY,EAAA,CAAG,OAAO,CAAA,CAAA,CAAA,CACpJtC,CACJ,EAEG,IAAIpB,CAAAA,CAAeoB,CAAAA,EAAO,OAAA,EAAW,qCAAsC,CAC9E,KAAA,CAAOA,GAAS,MACpB,CAAC,GAEL,kBAAA,CAAqBA,CAAAA,GACb,IAAA,CAAK,SAAA,EACLnB,EAAO,IAAA,CAAK,CAAA,kDAAA,EAAqDoD,CAAQ,CAAA,CAAA,CAAA,CAAKjC,CAAK,EAEhF,IAAIpB,CAAAA,CAAeoB,CAAAA,EAAO,OAAA,EAAW,0CAA2C,CACnF,KAAA,CAAOA,GAAS,MACpB,CAAC,GAEL,qBAAA,CAAuB,IAAM,CACrB,IAAA,CAAK,WACLnB,CAAAA,CAAO,KAAA,CAAM,4BAA6B,CACtC,QAAA,CAAAoD,EACA,MAAA,CAAQ,IAAA,CAAK,MAAA,CACb,OAAA,CAASK,EAAM,WAAA,CAAY,EAAA,CAAG,OAClC,CAAC,EAET,CACJ,CAAC,CACL,CAmBA,MAAM,OAAOQ,CAAAA,CAAsB,IAAA,CAAK,gBAAgC,CAIpE,GAHI,KAAK,SAAA,EACLjE,CAAAA,CAAO,KAAA,CAAM,CAAA,0CAAA,EAA6CiE,CAAW,CAAA,GAAA,CAAK,CAAA,CAE1E,OAAOA,CAAAA,EAAgB,QAAA,EAAY,CAAC,MAAA,CAAO,QAAA,CAASA,CAAW,CAAA,EAAKA,CAAAA,EAAe,EACnF,MAAM,IAAIlE,EAAe,yCAAyC,CAAA,CAEtE,IAAMmE,CAAAA,CAAY,IAAA,CAAK,GAAA,EAAI,CAAID,EAC/B,IAAA,IAAWb,CAAAA,IAAY,KAAK,UAAA,CAAY,CACpC,IAAMK,CAAAA,CAAQ,MAAM,IAAA,CAAK,QAAA,CAASL,CAAQ,CAAA,CAC1C,GAAI,CACA,IAAMe,CAAAA,CAAyB,EAAC,CAC5BC,CAAAA,CAAe,CAAA,CAuGnB,GArGA,MAAM,IAAI,OAAA,CAAc,CAAC5B,CAAAA,CAASC,CAAAA,GAAW,CACzC,IAAM4B,CAAAA,CAAgBZ,CAAAA,CAAM,UAAA,GACxBf,CAAAA,CAAU,CAAA,CAAA,CACV4B,EAAe,CAAA,CAAA,CACfC,CAAAA,CAAqB,EACrBC,CAAAA,CAEE3B,CAAAA,CAAgB1B,CAAAA,EAA0B,CACxCuB,IACJA,CAAAA,CAAU,CAAA,CAAA,CACVD,EAAOtB,CAAK,CAAA,EAChB,EAEMsD,CAAAA,CAAe,IAAM,CACvB,GAAI,CAAA/B,CAAAA,CACJ,CAAA,GAAI8B,EAAiB,CACjB3B,CAAAA,CAAa2B,CAAe,CAAA,CAC5B,MACJ,CACIF,CAAAA,EAAgBC,IAAuB,CAAA,GACvC7B,CAAAA,CAAU,GACVF,CAAAA,EAAQ,EAAA,CAEhB,EAEA6B,CAAAA,CAAc,SAAA,CAAY,IAAM,CAC5B,GAAI3B,GAAW8B,CAAAA,CAAiB,OAChC,IAAME,CAAAA,CAASL,CAAAA,CAAc,OAC7B,GAAI,CAACK,CAAAA,CAAQ,CACTJ,EAAe,CAAA,CAAA,CACX,IAAA,CAAK,WACLtE,CAAAA,CAAO,KAAA,CAAM,iDAAkD,CAC3D,QAAA,CAAAoD,CAAAA,CACA,UAAA,CAAYgB,CAChB,CAAC,CAAA,CAELK,GAAa,CACb,MACJ,CAGA,GADAL,CAAAA,EAAgB,CAAA,CACZ,OAAOM,EAAO,GAAA,EAAQ,QAAA,CAAU,CAChC,IAAMvE,CAAAA,CAAMuE,EAAO,GAAA,CACbC,CAAAA,CAAQD,CAAAA,CAAO,KAAA,CAEjB,OAAOC,CAAAA,EAAU,QAAA,EACjBJ,GAAsB,CAAA,CACjB,IAAA,CAAK,YAAYI,CAAK,CAAA,CACtB,IAAA,CAAMC,CAAAA,EAAS,CACRA,CAAAA,CAAK,SAAA,CAAYV,GACjBC,CAAAA,CAAa,IAAA,CAAKhE,CAAG,EAE7B,CAAC,CAAA,CACA,KAAA,CAAOgB,GAAU,CAYd,GAXI,KAAK,SAAA,EACLnB,CAAAA,CAAO,MAAM,uCAAA,CAAyCmB,CAAK,CAAA,CAE3D,IAAA,CAAK,sBACD,IAAA,CAAK,SAAA,EACLnB,EAAO,KAAA,CACH,kFACJ,EAEC,IAAA,CAAK,KAAA,CAAMoD,CAAQ,CAAA,CAAA,CAExB,CAACoB,EAAiB,CAClBA,CAAAA,CAAkB,IAAIzE,CAAAA,CAClBoB,CAAAA,YAAiB,MAAQA,CAAAA,CAAM,OAAA,CAAU,wBAC7C,CAAA,CACA,GAAI,CACAsC,CAAAA,CAAM,YAAY,KAAA,GACtB,MAAQ,CAER,CACJ,CACJ,CAAC,EACA,OAAA,CAAQ,IAAM,CACXc,CAAAA,EAAsB,CAAA,CACtBE,IACJ,CAAC,CAAA,EACEE,CAAAA,CAAM,UAAYT,CAAAA,EACzBC,CAAAA,CAAa,KAAKhE,CAAG,EAE7B,CAEKqE,CAAAA,EACDE,CAAAA,CAAO,QAAA,GAEf,EAEAL,CAAAA,CAAc,OAAA,CAAU,IAAM,CACtB,IAAA,CAAK,WACLrE,CAAAA,CAAO,KAAA,CACH,CAAA,4DAAA,EAA+DoD,CAAQ,IACvEiB,CAAAA,CAAc,KAClB,EAEJxB,CAAAA,CAAa,IAAI9C,EAAesE,CAAAA,CAAc,KAAA,EAAO,OAAA,EAAW,wBAAwB,CAAC,EAC7F,EACJ,CAAC,CAAA,CAEGF,CAAAA,CAAa,SAAW,CAAA,CACxB,SAGJ,IAAMU,CAAAA,CAAa,MAAM,IAAA,CAAK,QAAA,CAASzB,EAAU,WAAW,CAAA,CAC5D,MAAM,IAAI,OAAA,CAAc,CAACZ,CAAAA,CAASC,CAAAA,GAAW,CACzC,IAAIC,CAAAA,CAAU,GAERG,CAAAA,CAAgB1B,CAAAA,EAA0B,CACxCuB,CAAAA,GACJA,CAAAA,CAAU,CAAA,CAAA,CACVD,CAAAA,CAAOtB,CAAK,CAAA,EAChB,CAAA,CAEM2D,EAAWD,CAAAA,CAAW,WAAA,CAE5BC,EAAS,gBAAA,CAAiB,UAAA,CAAY,IAAM,CACpCpC,IACJA,CAAAA,CAAU,CAAA,CAAA,CACN,KAAK,SAAA,EACL1C,CAAAA,CAAO,MAAM,mCAAA,CAAqC,CAC9C,QAAA,CAAAoD,CAAAA,CACA,aAAce,CAAAA,CAAa,MAC/B,CAAC,CAAA,CAEL3B,CAAAA,IACJ,CAAC,CAAA,CAEDsC,CAAAA,CAAS,gBAAA,CAAiB,QAAS,IAAM,CACjC,KAAK,SAAA,EACL9E,CAAAA,CAAO,MACH,CAAA,+EAAA,EAAkFoD,CAAQ,CAAA,CAAA,CAAA,CAC1F0B,CAAAA,CAAS,KACb,CAAA,CAEJjC,CAAAA,CACI,IAAI9C,CAAAA,CAAe+E,CAAAA,CAAS,OAAO,OAAA,EAAW,sCAAsC,CACxF,EACJ,CAAC,CAAA,CAEDA,CAAAA,CAAS,iBAAiB,OAAA,CAAS,IAAM,CACjC,IAAA,CAAK,SAAA,EACL9E,CAAAA,CAAO,IAAA,CAAK,6DAA6DoD,CAAQ,CAAA,CAAA,CAAG,EAExFP,CAAAA,CAAa,IAAI9C,EAAe,iDAAiD,CAAC,EACtF,CAAC,CAAA,CAED,QAAWI,CAAAA,IAAOgE,CAAAA,CAAc,CAC5B,IAAMY,CAAAA,CAAgBF,EAAW,MAAA,CAAO1E,CAAG,CAAA,CAC3C4E,CAAAA,CAAc,QAAU,IAAM,CACtB,KAAK,SAAA,EACL/E,CAAAA,CAAO,MACH,CAAA,+CAAA,EAAkDoD,CAAQ,CAAA,OAAA,EAAUjD,CAAG,IACvE4E,CAAAA,CAAc,KAClB,EAER,EACJ,CACJ,CAAC,EACL,CAAA,MAAS5D,CAAAA,CAAO,CACZ,MAAI,IAAA,CAAK,SAAA,EACLnB,EAAO,KAAA,CAAM,CAAA,0BAAA,EAA6BiE,CAAW,CAAA,WAAA,CAAA,CAAe9C,CAAK,CAAA,CAEvEA,CACV,CACJ,CACA,OAAO,KACX,CASA,MAAM,SAAyB,CAC3B,OAAI,IAAA,CAAK,SAAA,EACLnB,EAAO,KAAA,CAAM,wDAAwD,EAElE,IAAI,OAAA,CAAc,CAACwC,CAAAA,CAASC,CAAAA,GAAW,CAC1C,IAAMsC,EAAgB,SAAA,CAAU,cAAA,CAAe,KAAK,MAAM,CAAA,CACtDrC,EAAU,KAAA,CACVQ,CAAAA,CAEEN,CAAAA,CAAgB,IAAM,CACpBF,CAAAA,GACJA,CAAAA,CAAU,KACNQ,CAAAA,EACA,YAAA,CAAaA,CAAc,CAAA,CAE/BV,CAAAA,CAAQ,IAAI,CAAA,EAChB,CAAA,CAEMK,EAAgB1B,CAAAA,EAA0B,CACxCuB,IACJA,CAAAA,CAAU,IAAA,CACNQ,GACA,YAAA,CAAaA,CAAc,CAAA,CAE/BT,CAAAA,CAAOtB,CAAK,CAAA,EAChB,CAAA,CAEA4D,EAAc,SAAA,CAAY,IAAM,CACxB,IAAA,CAAK,SAAA,EACL/E,CAAAA,CAAO,KAAA,CAAM,gCAAiC,CAC1C,MAAA,CAAQ,KAAK,MACjB,CAAC,EAEL4C,CAAAA,GACJ,CAAA,CACAmC,CAAAA,CAAc,QAAU,IAAM,CACtB,KAAK,SAAA,EACL/E,CAAAA,CAAO,MAAM,CAAA,gCAAA,EAAmC,IAAA,CAAK,MAAM,CAAA,CAAA,CAAG,EAElE6C,CAAAA,CAAa,IAAI9C,EAAegF,CAAAA,CAAc,KAAA,EAAO,SAAW,yBAAyB,CAAC,EAC9F,CAAA,CACAA,EAAc,SAAA,CAAY,IAAM,CACxB,IAAA,CAAK,SAAA,EACL/E,EAAO,IAAA,CACH,CAAA,0EAAA,EAA6E,IAAA,CAAK,uBAAuB,iCAAiC,IAAA,CAAK,MAAM,GACzJ,CAAA,CAEA,EAAAkD,GAAkBR,CAAAA,CAAAA,GACtBQ,CAAAA,CAAiB,UAAA,CAAW,IAAM,CAC9BL,CAAAA,CACI,IAAI9C,EACA,CAAA,kCAAA,EAAqC,IAAA,CAAK,uBAAuB,CAAA,6CAAA,CACrE,CACJ,EACJ,CAAA,CAAG,IAAA,CAAK,uBAAuB,CAAA,EACnC,EACJ,CAAC,CACL,CACJ,EAEOiF,CAAAA,CAAQjC","file":"index.cjs","sourcesContent":["export default class LocalSaveEncryptionKeyError extends Error {\n    constructor(message: string, options?: ErrorOptions) {\n        super(message, options);\n        this.name = 'LocalSaveEncryptionKeyError';\n    }\n}\n","export default class LocalSaveError extends Error {\n    constructor(message: string, options?: ErrorOptions) {\n        super(message, options);\n        this.name = 'LocalSaveError';\n    }\n}\n","export default class Logger {\n    constructor() {\n        throw new Error('This class cannot be instantiated.');\n    }\n    static log(message: string, ...args: unknown[]) {\n        console.log(`[LocalSave | LOG] ${message}\\n`, ...args);\n    }\n    static warn(message: string, ...args: unknown[]) {\n        console.warn(`[LocalSave | WARN] ${message}\\n`, ...args);\n    }\n    static error(message: string, ...args: unknown[]) {\n        console.error(`[LocalSave | ERROR] ${message}\\n`, ...args);\n    }\n    static info(message: string, ...args: unknown[]) {\n        console.info(`[LocalSave | INFO] ${message}\\n`, ...args);\n    }\n    static debug(message: string, ...args: unknown[]) {\n        console.debug(`[LocalSave | DEBUG] ${message}\\n`, ...args);\n    }\n}\n","/**\n * Validates the encryption key.\n * This function checks if the provided key is a string and has a length.\n *\n * @param key - The encryption key to validate.\n * @returns `true` if the key is defined.\n */\nexport function isEncryptionKeyDefined(key: string | undefined | null): key is string {\n    return typeof key === 'string' && key.length > 0;\n}\n\n/**\n * Validates the encryption key.\n *\n * This function checks if the provided key has no whitespace and a valid length.\n * The valid lengths for the encryption key are 16, 24, or 32 characters.\n *\n * @param key - The encryption key to validate.\n * @returns `true` if the key has no whitespace and a valid length, otherwise `false`.\n */\nexport function isValidEncryptionKey(key: string): boolean {\n    return key.length > 0 && !/\\s/.test(key) && [16, 24, 32].includes(key.length);\n}\n\n/**\n * Converts an ArrayBuffer to a Base64 encoded string.\n *\n * @internal\n *\n * @param buffer - The ArrayBuffer to convert.\n *\n * @returns The Base64 encoded string representation of the ArrayBuffer.\n */\nexport function arrayBufferToBase64(buffer: ArrayBuffer): string {\n    let binary = '';\n    const bytes = new Uint8Array(buffer);\n    const len = bytes.byteLength;\n    for (let i = 0; i < len; i++) {\n        binary += String.fromCharCode(bytes[i]);\n    }\n    return window.btoa(binary);\n}\n\n/**\n * Converts a base64 encoded string to an ArrayBuffer.\n *\n * @internal\n *\n * @param base64 - The base64 encoded string to convert.\n *\n * @returns The resulting ArrayBuffer.\n */\nexport function base64ToArrayBuffer(base64: string): ArrayBuffer {\n    const binary_string = window.atob(base64);\n    const len = binary_string.length;\n    const bytes = new Uint8Array(len);\n    for (let i = 0; i < len; i++) {\n        bytes[i] = binary_string.charCodeAt(i);\n    }\n    return bytes.buffer;\n}\n","import type { DBItem, DBItemEncryptedBase64, EncryptionKey } from '@local-save/types';\nimport LocalSaveEncryptionKeyError from '@local-save/utils/errors/LocalSaveEncryptionKeyError';\nimport LocalSaveError from '@local-save/utils/errors/LocalSaveError';\nimport Logger from '@local-save/utils/logger';\nimport {\n    arrayBufferToBase64,\n    base64ToArrayBuffer,\n    isEncryptionKeyDefined,\n    isValidEncryptionKey,\n} from '@local-save/utils/utils';\n\ninterface LocalSaveCryptoConfig {\n    getEncryptionKey: () => EncryptionKey | undefined;\n    isLoggingEnabled: () => boolean;\n}\n\n/**\n * Handles AES-GCM encryption/decryption concerns for LocalSave.\n *\n * - Lazily initializes text encoder/decoder.\n * - Caches imported CryptoKey while the source key string remains unchanged.\n * - Preserves LocalSave error behavior for key validation and decrypt failures.\n */\nexport class LocalSaveCrypto {\n    private textEncoder?: TextEncoder;\n    private textDecoder?: TextDecoder;\n    private cachedCryptoKeyPromise?: Promise<CryptoKey>;\n    private cachedCryptoKeySource?: EncryptionKey;\n\n    private readonly getEncryptionKey: () => EncryptionKey | undefined;\n    private readonly isLoggingEnabled: () => boolean;\n\n    /**\n     * Creates a crypto helper bound to runtime callbacks from LocalSave.\n     *\n     * @param config Runtime callbacks for key retrieval and logging state.\n     */\n    constructor(config: LocalSaveCryptoConfig) {\n        this.getEncryptionKey = config.getEncryptionKey;\n        this.isLoggingEnabled = config.isLoggingEnabled;\n    }\n\n    /**\n     * Returns a lazily initialized TextEncoder instance.\n     *\n     * @internal\n     * @returns {TextEncoder} A reusable TextEncoder instance for UTF-8 encoding.\n     */\n    private getTextEncoder(): TextEncoder {\n        if (!this.textEncoder) {\n            this.textEncoder = new TextEncoder();\n        }\n        return this.textEncoder;\n    }\n\n    /**\n     * Returns a lazily initialized TextDecoder instance.\n     *\n     * @internal\n     * @returns {TextDecoder} A reusable TextDecoder instance for UTF-8 decoding.\n     */\n    private getTextDecoder(): TextDecoder {\n        if (!this.textDecoder) {\n            this.textDecoder = new TextDecoder();\n        }\n        return this.textDecoder;\n    }\n\n    /**\n     * Retrieves the encryption key as an imported CryptoKey object.\n     *\n     * @internal\n     * @returns {Promise<CryptoKey>} A promise that resolves to a CryptoKey object.\n     *\n     * @throws {LocalSaveEncryptionKeyError} If the encryption key is not configured.\n     * @throws {LocalSaveEncryptionKeyError} If the encryption key contains whitespace or has invalid length.\n     */\n    private async getEncryptKey(): Promise<CryptoKey> {\n        const sourceKey = this.getEncryptionKey();\n        if (!isEncryptionKeyDefined(sourceKey)) {\n            throw new LocalSaveEncryptionKeyError(`Encryption key is not configured`);\n        }\n        if (!isValidEncryptionKey(sourceKey)) {\n            throw new LocalSaveEncryptionKeyError(\n                'Encryption key should not contain spaces and should be of length 16, 24, or 32 characters',\n            );\n        }\n        if (this.cachedCryptoKeyPromise && this.cachedCryptoKeySource === sourceKey) {\n            return this.cachedCryptoKeyPromise;\n        }\n\n        const keyBytes = this.getTextEncoder().encode(sourceKey);\n        const importPromise = crypto.subtle\n            .importKey('raw', keyBytes, { name: 'AES-GCM' }, false, ['encrypt', 'decrypt'])\n            .then((key) => {\n                if (this.isLoggingEnabled()) {\n                    Logger.debug(`Encryption key retrieved successfully`, {\n                        keyLength: sourceKey.length,\n                        keyBytesLength: keyBytes.length,\n                    });\n                }\n                return key;\n            })\n            .catch((error) => {\n                if (this.cachedCryptoKeyPromise === importPromise) {\n                    this.cachedCryptoKeyPromise = undefined;\n                    this.cachedCryptoKeySource = undefined;\n                }\n                throw error;\n            });\n\n        this.cachedCryptoKeySource = sourceKey;\n        this.cachedCryptoKeyPromise = importPromise;\n\n        return importPromise;\n    }\n\n    /**\n     * Encrypts the provided data using AES-GCM.\n     *\n     * - Generates a random 12-byte IV for each encryption.\n     * - Returns a base64 payload containing IV + ciphertext bytes.\n     *\n     * @param data The record to encrypt.\n     * @returns {Promise<DBItemEncryptedBase64>} A promise that resolves to encrypted base64 payload.\n     *\n     * @throws {LocalSaveEncryptionKeyError} If encryption key is not configured.\n     * @throws {LocalSaveError} If encryption fails.\n     */\n    async encryptData(data: DBItem): Promise<DBItemEncryptedBase64> {\n        try {\n            if (!isEncryptionKeyDefined(this.getEncryptionKey())) {\n                throw new LocalSaveEncryptionKeyError(`Encryption key is not configured`);\n            }\n            const iv = window.crypto.getRandomValues(new Uint8Array(12));\n            const generatedKey = await this.getEncryptKey();\n            const dataBuffer = this.getTextEncoder().encode(JSON.stringify(data));\n            const encryptedData = await window.crypto.subtle.encrypt(\n                {\n                    name: 'AES-GCM',\n                    iv: iv,\n                },\n                generatedKey,\n                dataBuffer,\n            );\n            const ivUint8 = new Uint8Array(iv);\n            const encryptedDataUint8 = new Uint8Array(encryptedData);\n            const concatenatedArray = new Uint8Array(ivUint8.byteLength + encryptedDataUint8.byteLength);\n            concatenatedArray.set(ivUint8, 0);\n            concatenatedArray.set(encryptedDataUint8, ivUint8.byteLength);\n            const base64Data = arrayBufferToBase64(concatenatedArray.buffer);\n            if (this.isLoggingEnabled()) {\n                Logger.debug(`Data encrypted successfully`, {\n                    base64DataLength: base64Data.length,\n                });\n            }\n            return base64Data;\n        } catch (error) {\n            if (this.isLoggingEnabled()) {\n                Logger.error(`Data encryption failed`, error);\n            }\n            throw error;\n        }\n    }\n\n    /**\n     * Decrypts a base64 payload produced by LocalSave encryption format.\n     *\n     * @param encryptedBase64Data Data payload encoded as base64 string.\n     * @returns {Promise<DBItem>} A promise that resolves to the decrypted DBItem object.\n     *\n     * @throws {LocalSaveEncryptionKeyError} If encryption key is not configured.\n     * @throws {LocalSaveError} If decryption fails.\n     */\n    async decryptData(encryptedBase64Data: string): Promise<DBItem> {\n        try {\n            if (!isEncryptionKeyDefined(this.getEncryptionKey())) {\n                throw new LocalSaveEncryptionKeyError(`Encryption key is not configured`);\n            }\n            const arrayBuffer = base64ToArrayBuffer(encryptedBase64Data);\n            const iv = new Uint8Array(arrayBuffer, 0, 12);\n            const generatedKey = await this.getEncryptKey();\n            const encryptedData = new Uint8Array(arrayBuffer, 12);\n            const decryptedBufferData = await window.crypto.subtle.decrypt(\n                {\n                    name: 'AES-GCM',\n                    iv,\n                },\n                generatedKey,\n                encryptedData,\n            );\n            const decryptedData = JSON.parse(this.getTextDecoder().decode(decryptedBufferData)) as DBItem;\n            if (this.isLoggingEnabled()) {\n                Logger.debug(`Data decrypted successfully`, {\n                    timestamp: decryptedData.timestamp,\n                });\n            }\n            return decryptedData;\n        } catch (error) {\n            if (this.isLoggingEnabled()) {\n                Logger.error(`Data decryption failed`, error);\n            }\n            throw new LocalSaveError(`Data decryption failed`, {\n                cause: error instanceof Error ? error : undefined,\n            });\n        }\n    }\n}\n","import type LocalSaveError from '@local-save/utils/errors/LocalSaveError';\n\n/**\n * Wraps an IndexedDB request with transaction completion tracking.\n * Ensures the promise resolves/rejects only after the transaction settles.\n *\n * @param options Request and transaction handlers to track.\n * @param options.request IndexedDB request being tracked.\n * @param options.transaction IndexedDB transaction containing the request.\n * @param options.onRequestError Maps request-level errors to LocalSaveError.\n * @param options.onRequestError.error Request error payload.\n * @param options.onTransactionError Maps transaction-level errors to LocalSaveError.\n * @param options.onTransactionError.error Transaction error payload.\n * @param options.onTransactionAbort Maps transaction aborts to LocalSaveError.\n * @param options.onTransactionAbort.error Transaction abort error payload.\n * @param options.onTransactionComplete Optional callback executed after successful transaction completion.\n *\n * @returns {Promise<true>} A promise that resolves to `true` when the transaction completes successfully.\n *\n * @throws {LocalSaveError} Rejects when request, transaction error, or transaction abort handlers map failures.\n */\nexport function wrapRequestWithTransaction({\n    request,\n    transaction,\n    onRequestError,\n    onTransactionError,\n    onTransactionAbort,\n    onTransactionComplete,\n}: {\n    request: IDBRequest;\n    transaction: IDBTransaction;\n    onRequestError: (error: DOMException | null) => LocalSaveError;\n    onTransactionError: (error: DOMException | null) => LocalSaveError;\n    onTransactionAbort: (error: DOMException | null) => LocalSaveError;\n    onTransactionComplete?: () => void;\n}): Promise<true> {\n    return new Promise<true>((resolve, reject) => {\n        let settled = false;\n        let requestError: LocalSaveError | undefined;\n\n        const settleResolve = () => {\n            if (settled) return;\n            settled = true;\n            resolve(true);\n        };\n\n        const settleReject = (error: LocalSaveError) => {\n            if (settled) return;\n            settled = true;\n            reject(error);\n        };\n\n        request.addEventListener(\n            'error',\n            () => {\n                requestError = onRequestError(request.error);\n            },\n            { once: true },\n        );\n\n        transaction.addEventListener(\n            'complete',\n            () => {\n                if (settled) return;\n                if (requestError) {\n                    settleReject(requestError);\n                    return;\n                }\n                onTransactionComplete?.();\n                settleResolve();\n            },\n            { once: true },\n        );\n\n        transaction.addEventListener(\n            'error',\n            () => {\n                if (settled) return;\n                settleReject(requestError ?? onTransactionError(transaction.error));\n            },\n            { once: true },\n        );\n\n        transaction.addEventListener(\n            'abort',\n            () => {\n                if (settled) return;\n                settleReject(requestError ?? onTransactionAbort(transaction.error));\n            },\n            { once: true },\n        );\n    });\n}\n","export default class LocalSaveConfigError extends Error {\n    constructor(message: string, options?: ErrorOptions) {\n        super(message, options);\n        this.name = 'LocalSaveConfigError';\n    }\n}\n","import { LocalSaveCrypto } from '@local-save/internal/crypto';\nimport { wrapRequestWithTransaction } from '@local-save/internal/transactions';\nimport type {\n    Category,\n    Config,\n    DBItem,\n    DBItemEncryptedBase64,\n    DBName,\n    EncryptionKey,\n    PositiveNumber,\n} from '@local-save/types';\nimport LocalSaveConfigError from '@local-save/utils/errors/LocalSaveConfigError';\nimport LocalSaveError from '@local-save/utils/errors/LocalSaveError';\nimport Logger from '@local-save/utils/logger';\nimport { isValidEncryptionKey } from '@local-save/utils/utils';\n\n/**\n * LocalSave provides a small IndexedDB-backed key-value API with optional AES-GCM encryption,\n * category-based separation, and utility operations like key listing, expiration, and teardown.\n */\nclass LocalSave {\n    dbName: DBName = 'LocalSave';\n    encryptionKey?: EncryptionKey;\n    private crypto: LocalSaveCrypto;\n    categories: Category[] = ['userData'];\n    expiryThreshold: PositiveNumber = 30 * 24 * 60 * 60 * 1000;\n    blockedTimeoutThreshold: PositiveNumber = 10 * 1000;\n    clearOnDecryptError: boolean = true;\n    printLogs: boolean = false;\n\n    /**\n     * Creates a LocalSave instance and applies configuration defaults.\n     *\n     * - Persists constructor options into instance fields used by all operations.\n     * - Validates encryption key format when provided.\n     * - Validates numeric thresholds to fail fast for invalid runtime behavior.\n     *\n     * @param config Optional runtime configuration object.\n     * @param config.dbName Optional IndexedDB database name override.\n     * @param config.encryptionKey Optional AES-GCM key (no whitespace, length 16, 24, or 32).\n     * @param config.categories Optional list of object store categories to use.\n     * @param config.expiryThreshold Optional default expiration window in milliseconds.\n     * @param config.blockedTimeoutThreshold Optional timeout in milliseconds for blocked open/delete requests.\n     * @param config.clearOnDecryptError Optional flag to clear a category when decrypt fails.\n     * @param config.printLogs Optional flag to enable debug/error logging.\n     *\n     * @throws {LocalSaveConfigError} If encryption key contains whitespace or its length is invalid.\n     * @throws {LocalSaveConfigError} If expiryThreshold is not a positive finite number.\n     * @throws {LocalSaveConfigError} If blockedTimeoutThreshold is not a positive finite number.\n     */\n    constructor(config?: Config) {\n        this.dbName = config?.dbName ?? this.dbName;\n        this.encryptionKey = config?.encryptionKey;\n        this.categories = config?.categories ?? this.categories;\n        this.clearOnDecryptError = config?.clearOnDecryptError ?? this.clearOnDecryptError;\n        this.expiryThreshold = config?.expiryThreshold ?? this.expiryThreshold;\n        this.blockedTimeoutThreshold = config?.blockedTimeoutThreshold ?? this.blockedTimeoutThreshold;\n        this.printLogs = config?.printLogs ?? this.printLogs;\n        this.crypto = new LocalSaveCrypto({\n            getEncryptionKey: () => this.encryptionKey,\n            isLoggingEnabled: () => this.printLogs,\n        });\n\n        if (config?.encryptionKey !== undefined && !isValidEncryptionKey(config.encryptionKey)) {\n            throw new LocalSaveConfigError(\n                'Encryption key should not contain spaces and should be of length 16, 24, or 32 characters',\n            );\n        } else if (\n            typeof this.expiryThreshold !== 'number' ||\n            !Number.isFinite(this.expiryThreshold) ||\n            this.expiryThreshold <= 0\n        ) {\n            throw new LocalSaveConfigError('expiryThreshold should be a positive number');\n        } else if (\n            typeof this.blockedTimeoutThreshold !== 'number' ||\n            !Number.isFinite(this.blockedTimeoutThreshold) ||\n            this.blockedTimeoutThreshold <= 0\n        ) {\n            throw new LocalSaveConfigError('blockedTimeoutThreshold should be a positive number');\n        }\n    }\n\n    /**\n     * Opens a connection to the IndexedDB database.\n     * It handles the database versioning and ensures that the required object stores are created if they do not exist.\n     *\n     * @internal\n     *\n     * @param version - The version of the database to open. Optional.\n     *\n     * @returns {Promise<IDBDatabase>} A promise that resolves to the opened IDBDatabase instance.\n     */\n    private openDB(version?: number): Promise<IDBDatabase> {\n        return new Promise<IDBDatabase>((resolve, reject) => {\n            const openRequest = indexedDB.open(this.dbName, version);\n            let settled = false;\n            let blockedTimeout: ReturnType<typeof setTimeout> | undefined;\n\n            const settleResolve = (db: IDBDatabase) => {\n                if (settled) {\n                    db.close();\n                    return;\n                }\n                settled = true;\n                if (blockedTimeout) {\n                    clearTimeout(blockedTimeout);\n                }\n                resolve(db);\n            };\n\n            const settleReject = (error: LocalSaveError) => {\n                if (settled) return;\n                settled = true;\n                if (blockedTimeout) {\n                    clearTimeout(blockedTimeout);\n                }\n                reject(error);\n            };\n\n            openRequest.onupgradeneeded = () => {\n                const db = openRequest.result;\n                if (this.printLogs) {\n                    Logger.debug(`Database upgrade triggered`, {\n                        dbName: this.dbName,\n                        version: db.version,\n                    });\n                }\n                for (const category of this.categories) {\n                    if (!db.objectStoreNames.contains(category)) {\n                        if (this.printLogs) {\n                            Logger.debug(`Creating object store`, {\n                                category,\n                            });\n                        }\n                        db.createObjectStore(category);\n                    }\n                }\n            };\n            openRequest.onsuccess = () => {\n                const db = openRequest.result;\n                db.onversionchange = () => {\n                    if (this.printLogs) {\n                        Logger.warn(`Closing stale database connection on version change [dbName:${this.dbName}]`);\n                    }\n                    db.close();\n                };\n                if (this.printLogs) {\n                    Logger.debug(`Database opened successfully`, {\n                        dbName: this.dbName,\n                        version: db.version,\n                    });\n                }\n                settleResolve(db);\n            };\n            openRequest.onerror = () => {\n                if (this.printLogs) {\n                    Logger.error(`LocalSaveError opening database [dbName:${this.dbName}]`, openRequest.error);\n                }\n                settleReject(new LocalSaveError(openRequest.error?.message ?? 'Error opening database'));\n            };\n            openRequest.onblocked = () => {\n                if (this.printLogs) {\n                    Logger.warn(\n                        `Opening database is currently blocked by an existing open connection. Waiting for ${this.blockedTimeoutThreshold} ms before timing out [dbName:${this.dbName}]`,\n                    );\n                }\n                if (blockedTimeout || settled) return;\n                blockedTimeout = setTimeout(() => {\n                    settleReject(\n                        new LocalSaveError(\n                            `Opening database timed out after ${this.blockedTimeoutThreshold} ms because it is blocked by open connections`,\n                        ),\n                    );\n                }, this.blockedTimeoutThreshold);\n            };\n        });\n    }\n\n    /**\n     * Lists all object stores currently available in the configured database.\n     *\n     * @internal\n     *\n     * @returns {Promise<Category[]>} A promise that resolves to an array of object store names.\n     */\n    private async listStores(): Promise<Category[]> {\n        const db = await this.openDB();\n        try {\n            const stores = Array.from(db.objectStoreNames);\n            if (this.printLogs) {\n                Logger.debug(`Object stores listed successfully`, {\n                    stores,\n                });\n            }\n            return stores;\n        } finally {\n            db.close();\n        }\n    }\n\n    /**\n     * Retrieves an object store from the IndexedDB database.\n     * It handles the transaction mode and ensures that the requested object store is returned.\n     *\n     * If the object store does not exist in the database and the category is valid, it will create a new version of the database with the object store.\n     *\n     * @internal\n     *\n     * @param category - The name of the object store to retrieve.\n     * @param mode - The mode for the transaction (default is \"readonly\").\n     *\n     * @returns {Promise<IDBObjectStore>} A promise that resolves to the requested object store.\n     *\n     * @throws {LocalSaveError} Will throw an error if the object store does not exist in the database and the category is invalid\n     */\n    private async getStore(category: Category, mode: IDBTransactionMode = 'readonly'): Promise<IDBObjectStore> {\n        let db = await this.openDB();\n        if (!db.objectStoreNames.contains(category) && this.categories.includes(category)) {\n            if (this.printLogs) {\n                Logger.debug(\n                    `Requested object store not found in current database version.\\nTriggering database upgrade to create object store.`,\n                    {\n                        category,\n                        dbName: this.dbName,\n                        version: db.version,\n                    },\n                );\n            }\n            const currVersion = db.version;\n            db.close();\n            db = await this.openDB(currVersion + 1);\n        } else if (!db.objectStoreNames.contains(category)) {\n            const dbVersion = db.version;\n            db.close();\n            throw new LocalSaveError(\n                `Requested object store not found in current database version [category:${category} / dbName:${this.dbName} / version:${dbVersion}].`,\n            );\n        }\n        let transaction: IDBTransaction;\n        try {\n            transaction = db.transaction(category, mode);\n        } catch (error) {\n            db.close();\n            throw new LocalSaveError(error instanceof Error ? error.message : 'Error creating transaction');\n        }\n        transaction.oncomplete = () => {\n            db.close();\n        };\n        transaction.onerror = () => {\n            db.close();\n        };\n        transaction.onabort = () => {\n            db.close();\n        };\n        const store = transaction.objectStore(category);\n        if (this.printLogs) {\n            Logger.debug(`Object store retrieved from database`, {\n                category,\n                mode,\n                dbName: this.dbName,\n                version: db.version,\n            });\n        }\n        return store;\n    }\n\n    /**\n     * Encrypts a DBItem using the configured encryption key.\n     * Delegates to the extracted crypto helper.\n     *\n     * @internal\n     *\n     * @param data The item payload to encrypt.\n     *\n     * @returns {Promise<DBItemEncryptedBase64>} A promise that resolves to a base64 payload containing IV + ciphertext.\n     *\n     * @throws {LocalSaveEncryptionKeyError} If the encryption key is not configured or invalid.\n     * @throws {LocalSaveError} If encryption fails.\n     */\n    private async encryptData(data: DBItem): Promise<DBItemEncryptedBase64> {\n        return this.crypto.encryptData(data);\n    }\n\n    /**\n     * Decrypts data using the configured encryption key.\n     *\n     * @param encryptedBase64Data The data to decrypt, as a string.\n     * @returns {Promise<DBItem>} A promise that resolves to the decrypted data object.\n     *\n     * @throws {LocalSaveError} If decryption fails.\n     */\n    async decryptData(encryptedBase64Data: string): Promise<DBItem> {\n        return this.crypto.decryptData(encryptedBase64Data);\n    }\n\n    /**\n     * Stores data in the specified category with the given item key.\n     * If encryption key is configured, the data is encrypted first before being stored.\n     *\n     * @param category The category under which the data should be stored.\n     * @param itemKey The key to identify the stored data.\n     * @param data The data to be stored.\n     *\n     * @returns {Promise<true>} A promise that resolves to `true` if the operation was successful.\n     *\n     * @throws {LocalSaveError} Will reject the promise if an error occurs during the saving process.\n     */\n    async set(category: Category, itemKey: string, data: unknown): Promise<true> {\n        if (this.printLogs) {\n            Logger.debug(`set() called to store data with following props`, {\n                category,\n                itemKey,\n            });\n        }\n        let payload: DBItem | DBItemEncryptedBase64 = {\n            timestamp: Date.now(),\n            data,\n        };\n        try {\n            if (this.encryptionKey) {\n                payload = await this.encryptData(payload);\n            }\n            const store = await this.getStore(category, 'readwrite');\n            return wrapRequestWithTransaction({\n                request: store.put(payload, itemKey),\n                transaction: store.transaction,\n                onRequestError: (error) => {\n                    if (this.printLogs) {\n                        Logger.error(`LocalSaveError storing data [category:${category} / key:${itemKey}]`, error);\n                    }\n                    return new LocalSaveError(error?.message ?? 'Error storing data', {\n                        cause: error ?? undefined,\n                    });\n                },\n                onTransactionError: (error) => {\n                    if (this.printLogs) {\n                        Logger.error(\n                            `LocalSaveError during transaction commit while storing data [category:${category} / key:${itemKey}]`,\n                            error,\n                        );\n                    }\n                    return new LocalSaveError(error?.message ?? 'Error committing storage transaction', {\n                        cause: error ?? undefined,\n                    });\n                },\n                onTransactionAbort: (error: DOMException | null) => {\n                    if (this.printLogs) {\n                        Logger.warn(\n                            `Transaction aborted while storing data [category:${category} / key:${itemKey}]`,\n                            error,\n                        );\n                    }\n                    return new LocalSaveError(error?.message ?? 'Transaction aborted while storing data', {\n                        cause: error ?? undefined,\n                    });\n                },\n                onTransactionComplete: () => {\n                    if (this.printLogs) {\n                        Logger.debug(`Data stored successfully`, {\n                            category,\n                            itemKey,\n                        });\n                    }\n                },\n            });\n        } catch (error) {\n            if (this.printLogs) {\n                Logger.error(`Data storing failed`, error);\n            }\n            throw error;\n        }\n    }\n\n    /**\n     * Retrieves an item from the specified category in the IndexedDB.\n     * If the item is not found, the promise resolves to 'null'.\n     * If an encryption key is configured, the data is decrypted before being returned.\n     *\n     * @param category The category from which to retrieve the item.\n     * @param itemKey The key of the item to retrieve.\n     *\n     * @returns {Promise<DBItem | null>} A promise that resolves to the retrieved item or null if not found.\n     *\n     * @throws {LocalSaveError} Will reject the promise if an error occurs while decrypting the data. Depending on the 'clearOnDecryptError' configuration, all data for the category can be cleared.\n     * @throws {LocalSaveError} Will reject the promise if an error occurs during the retrieval process.\n     */\n    async get(category: Category, itemKey: string): Promise<DBItem | null> {\n        if (this.printLogs) {\n            Logger.debug(`get() called to retrieve data with following props`, {\n                category,\n                itemKey,\n            });\n        }\n        const store = await this.getStore(category);\n        return new Promise<DBItem | null>((resolve, reject) => {\n            const getRequest = store.get(itemKey);\n            getRequest.onsuccess = async () => {\n                let result = getRequest.result as DBItemEncryptedBase64 | DBItem | null;\n                if (!result) {\n                    if (this.printLogs) {\n                        Logger.debug(`No data was found`, {\n                            category,\n                            itemKey,\n                        });\n                    }\n                    return resolve(null);\n                }\n                if (typeof result === 'string') {\n                    try {\n                        result = await this.decryptData(result);\n                    } catch (error) {\n                        if (this.printLogs) {\n                            Logger.error(`Failed to get data`, error);\n                        }\n                        if (this.clearOnDecryptError) {\n                            if (this.printLogs) {\n                                Logger.error(`Triggering clear for all data for category since decryption failed`);\n                            }\n                            try {\n                                await this.clear(category);\n                            } catch (clearError) {\n                                if (this.printLogs) {\n                                    Logger.error(`Failed to clear data after decryption failure`, clearError);\n                                }\n                                return reject(\n                                    new LocalSaveError('Data decryption failed and category clearing failed', {\n                                        cause: clearError instanceof Error ? clearError : undefined,\n                                    }),\n                                );\n                            }\n                        }\n                        return reject(\n                            new LocalSaveError(error instanceof Error ? error.message : 'Failed to decrypt data'),\n                        );\n                    }\n                }\n                if (this.printLogs) {\n                    Logger.debug(`Data retrieved successfully`, {\n                        category,\n                        itemKey,\n                        timestamp: result.timestamp,\n                    });\n                }\n                return resolve(result);\n            };\n            getRequest.onerror = () => {\n                return reject(new LocalSaveError(getRequest.error?.message ?? 'Error getting data'));\n            };\n        });\n    }\n\n    /**\n     * Lists all categories (object stores) currently available in the database.\n     *\n     * @returns {Promise<Category[]>} A promise that resolves to an array of category names.\n     */\n    async listCategories(): Promise<Category[]> {\n        if (this.printLogs) {\n            Logger.debug(`listCategories() called to list all categories`);\n        }\n        return this.listStores();\n    }\n\n    /**\n     * Lists all item keys stored under the specified category.\n     *\n     * @param category The category from which item keys should be listed.\n     *\n     * @returns {Promise<string[]>} A promise that resolves to an array of item keys.\n     *\n     * @throws {LocalSaveError} Will reject the promise if an error occurs while listing keys.\n     */\n    async listKeys(category: Category): Promise<string[]> {\n        if (this.printLogs) {\n            Logger.debug(`listKeys() called to list all keys for category`, {\n                category,\n            });\n        }\n        const store = await this.getStore(category);\n        return new Promise<string[]>((resolve, reject) => {\n            const keysRequest = store.getAllKeys();\n            keysRequest.onsuccess = () => {\n                const keys = keysRequest.result as string[];\n                if (this.printLogs) {\n                    Logger.debug(`Keys listed successfully for category`, {\n                        category,\n                        keys,\n                    });\n                }\n                resolve(keys);\n            };\n            keysRequest.onerror = () => {\n                if (this.printLogs) {\n                    Logger.error(`Error listing keys for category [category:${category}]`, keysRequest.error);\n                }\n                reject(new LocalSaveError(keysRequest.error?.message ?? 'Error listing keys'));\n            };\n        });\n    }\n\n    /**\n     * Removes an entry from the specified category and the specific itemKey in the IndexedDB store.\n     *\n     * @param category The category from which the item should be removed.\n     * @param itemKey The key of the item to be removed.\n     *\n     * @returns {Promise<true>} A promise that resolves to `true` if the operation was successful.\n     *\n     * @throws {LocalSaveError} Will reject the promise if an error occurs during the removal process.\n     */\n    async remove(category: Category, itemKey: string): Promise<true> {\n        if (this.printLogs) {\n            Logger.debug(`remove() called to remove data with following props`, {\n                category,\n                itemKey,\n            });\n        }\n        const store = await this.getStore(category, 'readwrite');\n        return wrapRequestWithTransaction({\n            request: store.delete(itemKey),\n            transaction: store.transaction,\n            onRequestError: (error: DOMException | null) => {\n                if (this.printLogs) {\n                    Logger.error(`Failed to remove data from [category:${category} / key:${itemKey}]`, error);\n                }\n                return new LocalSaveError(error?.message ?? 'Error removing data', {\n                    cause: error ?? undefined,\n                });\n            },\n            onTransactionError: (error: DOMException | null) => {\n                if (this.printLogs) {\n                    Logger.error(\n                        `LocalSaveError during transaction commit while removing data [category:${category} / key:${itemKey}]`,\n                        error,\n                    );\n                }\n                return new LocalSaveError(error?.message ?? 'Error committing removal transaction', {\n                    cause: error ?? undefined,\n                });\n            },\n            onTransactionAbort: (error: DOMException | null) => {\n                if (this.printLogs) {\n                    Logger.warn(\n                        `Transaction aborted while removing data [category:${category} / key:${itemKey}]`,\n                        error,\n                    );\n                }\n                return new LocalSaveError(error?.message ?? 'Transaction aborted while removing data', {\n                    cause: error ?? undefined,\n                });\n            },\n            onTransactionComplete: () => {\n                if (this.printLogs) {\n                    Logger.debug(`Data removed successfully`, {\n                        category,\n                        itemKey,\n                    });\n                }\n            },\n        });\n    }\n\n    /**\n     * Clears all entries in the specified category.\n     *\n     * @param category - The category to clear.\n     *\n     * @returns {Promise<true>} A promise that resolves to `true` if the operation was successful.\n     *\n     * @throws {LocalSaveError} Will reject the promise if an error occurs during the clearing process.\n     */\n    async clear(category: Category): Promise<true> {\n        if (this.printLogs) {\n            Logger.debug(`clear() called to store all data under '${category}' category`);\n        }\n        const store = await this.getStore(category, 'readwrite');\n        return wrapRequestWithTransaction({\n            request: store.clear(),\n            transaction: store.transaction,\n            onRequestError: (error) => {\n                if (this.printLogs) {\n                    Logger.error(\n                        `LocalSaveError clearing data [category:${category} / dbName:${this.dbName} / version:${store.transaction.db.version}]`,\n                        error,\n                    );\n                }\n                return new LocalSaveError(error?.message ?? 'Error clearing data', {\n                    cause: error ?? undefined,\n                });\n            },\n            onTransactionError: (error) => {\n                if (this.printLogs) {\n                    Logger.error(\n                        `LocalSaveError during transaction commit while clearing data [category:${category} / dbName:${this.dbName} / version:${store.transaction.db.version}]`,\n                        error,\n                    );\n                }\n                return new LocalSaveError(error?.message ?? 'Error committing clear transaction', {\n                    cause: error ?? undefined,\n                });\n            },\n            onTransactionAbort: (error: DOMException | null) => {\n                if (this.printLogs) {\n                    Logger.warn(`Transaction aborted while clearing data [category:${category}]`, error);\n                }\n                return new LocalSaveError(error?.message ?? 'Transaction aborted while clearing data', {\n                    cause: error ?? undefined,\n                });\n            },\n            onTransactionComplete: () => {\n                if (this.printLogs) {\n                    Logger.debug(`Data cleared successfully`, {\n                        category,\n                        dbName: this.dbName,\n                        version: store.transaction.db.version,\n                    });\n                }\n            },\n        });\n    }\n\n    /**\n     * Expires data older than the specified threshold in milliseconds.\n     *\n     * For each category, this method performs a readonly cursor scan to identify candidate\n     * records, decrypts encrypted entries to inspect their timestamps, and then deletes the\n     * expired keys in a separate readwrite transaction.\n     *\n     * If decryption fails during expiration and `clearOnDecryptError` is enabled, the category\n     * is cleared before the error is rethrown.\n     *\n     * @param {number} [thresholdMs=this.expiryThreshold] The threshold in milliseconds to use for expiring data.\n     * Defaults to expiryThreshold from config if not provided.\n     *\n     * @returns {Promise<true>} A promise that resolves to `true` if the operation was successful.\n     *\n     * @throws {LocalSaveError} - Throws an error if there is an issue scanning entries, decrypting data, or removing expired items.\n     */\n    async expire(thresholdMs: number = this.expiryThreshold): Promise<true> {\n        if (this.printLogs) {\n            Logger.debug(`expire() called to expire data older than ${thresholdMs} ms`);\n        }\n        if (typeof thresholdMs !== 'number' || !Number.isFinite(thresholdMs) || thresholdMs <= 0) {\n            throw new LocalSaveError('thresholdMs should be a positive number');\n        }\n        const checkDate = Date.now() - thresholdMs;\n        for (const category of this.categories) {\n            const store = await this.getStore(category);\n            try {\n                const keysToDelete: string[] = [];\n                let scannedCount = 0;\n\n                await new Promise<void>((resolve, reject) => {\n                    const cursorRequest = store.openCursor();\n                    let settled = false;\n                    let scanFinished = false;\n                    let pendingDecryptions = 0;\n                    let decryptionError: LocalSaveError | undefined;\n\n                    const settleReject = (error: LocalSaveError) => {\n                        if (settled) return;\n                        settled = true;\n                        reject(error);\n                    };\n\n                    const maybeResolve = () => {\n                        if (settled) return;\n                        if (decryptionError) {\n                            settleReject(decryptionError);\n                            return;\n                        }\n                        if (scanFinished && pendingDecryptions === 0) {\n                            settled = true;\n                            resolve();\n                        }\n                    };\n\n                    cursorRequest.onsuccess = () => {\n                        if (settled || decryptionError) return;\n                        const cursor = cursorRequest.result;\n                        if (!cursor) {\n                            scanFinished = true;\n                            if (this.printLogs) {\n                                Logger.debug(`Entries scanned successfully for expiring data`, {\n                                    category,\n                                    entryCount: scannedCount,\n                                });\n                            }\n                            maybeResolve();\n                            return;\n                        }\n\n                        scannedCount += 1;\n                        if (typeof cursor.key === 'string') {\n                            const key = cursor.key;\n                            const value = cursor.value as DBItemEncryptedBase64 | DBItem;\n\n                            if (typeof value === 'string') {\n                                pendingDecryptions += 1;\n                                void this.decryptData(value)\n                                    .then((item) => {\n                                        if (item.timestamp < checkDate) {\n                                            keysToDelete.push(key);\n                                        }\n                                    })\n                                    .catch((error) => {\n                                        if (this.printLogs) {\n                                            Logger.error(`Failed to decrypt data while expiring`, error);\n                                        }\n                                        if (this.clearOnDecryptError) {\n                                            if (this.printLogs) {\n                                                Logger.error(\n                                                    `Triggering clear for all data for category since decryption failed during expire`,\n                                                );\n                                            }\n                                            void this.clear(category);\n                                        }\n                                        if (!decryptionError) {\n                                            decryptionError = new LocalSaveError(\n                                                error instanceof Error ? error.message : 'Failed to decrypt data',\n                                            );\n                                            try {\n                                                store.transaction.abort();\n                                            } catch {\n                                                // Ignore abort errors if the transaction is already finished.\n                                            }\n                                        }\n                                    })\n                                    .finally(() => {\n                                        pendingDecryptions -= 1;\n                                        maybeResolve();\n                                    });\n                            } else if (value.timestamp < checkDate) {\n                                keysToDelete.push(key);\n                            }\n                        }\n\n                        if (!decryptionError) {\n                            cursor.continue();\n                        }\n                    };\n\n                    cursorRequest.onerror = () => {\n                        if (this.printLogs) {\n                            Logger.error(\n                                `LocalSaveError scanning entries for expiring data [category:${category}]`,\n                                cursorRequest.error,\n                            );\n                        }\n                        settleReject(new LocalSaveError(cursorRequest.error?.message ?? 'Error scanning entries'));\n                    };\n                });\n\n                if (keysToDelete.length === 0) {\n                    continue;\n                }\n\n                const writeStore = await this.getStore(category, 'readwrite');\n                await new Promise<void>((resolve, reject) => {\n                    let settled = false;\n\n                    const settleReject = (error: LocalSaveError) => {\n                        if (settled) return;\n                        settled = true;\n                        reject(error);\n                    };\n\n                    const settleTx = writeStore.transaction;\n\n                    settleTx.addEventListener('complete', () => {\n                        if (settled) return;\n                        settled = true;\n                        if (this.printLogs) {\n                            Logger.debug(`Expired data removed successfully`, {\n                                category,\n                                removedCount: keysToDelete.length,\n                            });\n                        }\n                        resolve();\n                    });\n\n                    settleTx.addEventListener('error', () => {\n                        if (this.printLogs) {\n                            Logger.error(\n                                `LocalSaveError during transaction commit while removing expired data [category:${category}]`,\n                                settleTx.error,\n                            );\n                        }\n                        settleReject(\n                            new LocalSaveError(settleTx.error?.message ?? 'Error committing removal transaction'),\n                        );\n                    });\n\n                    settleTx.addEventListener('abort', () => {\n                        if (this.printLogs) {\n                            Logger.warn(`Transaction aborted while removing expired data [category:${category}]`);\n                        }\n                        settleReject(new LocalSaveError('Transaction aborted while removing expired data'));\n                    });\n\n                    for (const key of keysToDelete) {\n                        const deleteRequest = writeStore.delete(key);\n                        deleteRequest.onerror = () => {\n                            if (this.printLogs) {\n                                Logger.error(\n                                    `LocalSaveError removing expired data [category:${category} / key:${key}]`,\n                                    deleteRequest.error,\n                                );\n                            }\n                        };\n                    }\n                });\n            } catch (error) {\n                if (this.printLogs) {\n                    Logger.error(`Expiring data older than '${thresholdMs}' ms failed`, error);\n                }\n                throw error;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * Asynchronously destroys the database by deleting it from IndexedDB.\n     *\n     * @returns {Promise<true>} A promise that resolves to `true` if the operation was successful.\n     *\n     * @throws {LocalSaveError} Will reject the promise if an error occurs during the deletion process.\n     */\n    async destroy(): Promise<true> {\n        if (this.printLogs) {\n            Logger.debug(`destroy() called to wipe all data under all categories`);\n        }\n        return new Promise<true>((resolve, reject) => {\n            const deleteRequest = indexedDB.deleteDatabase(this.dbName);\n            let settled = false;\n            let blockedTimeout: ReturnType<typeof setTimeout> | undefined;\n\n            const settleResolve = () => {\n                if (settled) return;\n                settled = true;\n                if (blockedTimeout) {\n                    clearTimeout(blockedTimeout);\n                }\n                resolve(true);\n            };\n\n            const settleReject = (error: LocalSaveError) => {\n                if (settled) return;\n                settled = true;\n                if (blockedTimeout) {\n                    clearTimeout(blockedTimeout);\n                }\n                reject(error);\n            };\n\n            deleteRequest.onsuccess = () => {\n                if (this.printLogs) {\n                    Logger.debug(`Database deleted successfully`, {\n                        dbName: this.dbName,\n                    });\n                }\n                settleResolve();\n            };\n            deleteRequest.onerror = () => {\n                if (this.printLogs) {\n                    Logger.error(`Error deleting database [dbName:${this.dbName}]`);\n                }\n                settleReject(new LocalSaveError(deleteRequest.error?.message ?? 'Error deleting database'));\n            };\n            deleteRequest.onblocked = () => {\n                if (this.printLogs) {\n                    Logger.warn(\n                        `Deleting database is currently blocked by an open connection. Waiting for ${this.blockedTimeoutThreshold} ms before timing out [dbName:${this.dbName}]`,\n                    );\n                }\n                if (blockedTimeout || settled) return;\n                blockedTimeout = setTimeout(() => {\n                    settleReject(\n                        new LocalSaveError(\n                            `Deleting database timed out after ${this.blockedTimeoutThreshold} ms because it is blocked by open connections`,\n                        ),\n                    );\n                }, this.blockedTimeoutThreshold);\n            };\n        });\n    }\n}\nexport type { Category, Config, DBItem, DBItemEncryptedBase64, DBName, EncryptionKey, PositiveNumber };\nexport default LocalSave;\n"]}