otplib 13.3.0 → 13.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -24
- package/dist/index.global.js +7 -0
- package/dist/index.global.js.map +1 -0
- package/dist/metafile-iife.json +1 -0
- package/package.json +11 -8
package/README.md
CHANGED
|
@@ -2,32 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
TypeScript-first library for HOTP and TOTP / Authenticator with multi-runtime (Node, Bun, Deno, Browser) support via plugins.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> [!TIP]
|
|
6
|
+
>
|
|
7
|
+
> A web based demo is available at [https://otplib.yeojz.dev](https://otplib.yeojz.dev).
|
|
8
|
+
>
|
|
9
|
+
> You can scan the TOTP / HOTP QR Code samples with your chosen authenticator app to test.
|
|
6
10
|
|
|
7
11
|
## Features
|
|
8
12
|
|
|
9
13
|
- **Zero Configuration** - Works out of the box with sensible defaults
|
|
10
|
-
- **RFC Compliant** - RFC 6238 (TOTP) and RFC 4226 (HOTP)
|
|
14
|
+
- **RFC Compliant** - RFC 6238 (TOTP) and RFC 4226 (HOTP) + Google Authenticator Compatible
|
|
11
15
|
- **TypeScript-First** - Full type definitions
|
|
12
|
-
- **Google Authenticator Compatible** - Full otpauth:// URI support
|
|
13
16
|
- **Plugin Interface** - Flexible plugin system for customising your cryptographic and base32 requirements (if you want to deviate from the defaults)
|
|
14
17
|
- **Cross-platform** - Tested against Node.js, Bun, Deno, and browsers
|
|
18
|
+
- **Security-audited plugins** — Default crypto uses `@noble/hashes` and `@scure/base`, both independently audited
|
|
19
|
+
- **Async-first API** — All operations are async by default; sync variants available for compatible plugins
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
> [!IMPORTANT]
|
|
19
|
-
> v13 is a complete rewrite with breaking changes:
|
|
21
|
+
> [!IMPORTANT]
|
|
20
22
|
>
|
|
21
|
-
>
|
|
22
|
-
> - **Security-audited plugins** — Default crypto uses `@noble/hashes` and `@scure/base`, both independently audited
|
|
23
|
-
> - **Cross-platform defaults** — Works out-of-the-box in Node.js, Bun, Deno, and browsers
|
|
24
|
-
> - **Full type safety** — Comprehensive TypeScript types with strict mode from the ground up
|
|
25
|
-
> - **Async-first API** — All operations are async by default; sync variants available for compatible plugins
|
|
26
|
-
> - **Removed**
|
|
27
|
-
> - **Separate authenticator package** — TOTP now covers all authenticator functionality
|
|
28
|
-
> - **Outdated plugins** — Legacy crypto adapters removed in favor of modern, audited alternatives
|
|
23
|
+
> v13 is a complete rewrite with breaking changes. For example:
|
|
29
24
|
>
|
|
30
|
-
>
|
|
25
|
+
> - **(Removed) Separate authenticator package** — TOTP now covers all authenticator functionality with default plugins
|
|
26
|
+
> - **(Removed) Outdated plugins** — Legacy crypto adapters removed in favor of modern, audited alternatives
|
|
27
|
+
>
|
|
28
|
+
> See [Migration Guide](https://otplib.yeojz.dev/guide/v12-adapter.html) for details.
|
|
31
29
|
|
|
32
30
|
## Installation
|
|
33
31
|
|
|
@@ -44,6 +42,27 @@ bun add otplib
|
|
|
44
42
|
deno install npm:otplib
|
|
45
43
|
```
|
|
46
44
|
|
|
45
|
+
### CDN / Script Tag
|
|
46
|
+
|
|
47
|
+
A self-contained IIFE build is available for use directly in browsers via a `<script>` tag:
|
|
48
|
+
|
|
49
|
+
```html
|
|
50
|
+
<!-- unpkg -->
|
|
51
|
+
<script src="https://unpkg.com/otplib/dist/index.global.js"></script>
|
|
52
|
+
|
|
53
|
+
<!-- or jsdelivr -->
|
|
54
|
+
<script src="https://cdn.jsdelivr.net/npm/otplib/dist/index.global.js"></script>
|
|
55
|
+
|
|
56
|
+
<script>
|
|
57
|
+
const { generateSecret, generate, verify } = otplib;
|
|
58
|
+
|
|
59
|
+
const secret = generateSecret();
|
|
60
|
+
generate({ secret }).then((token) => console.log("Token:", token));
|
|
61
|
+
</script>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The IIFE build bundles all dependencies (including crypto and base32 plugins) into a single file and exposes everything under the `otplib` global.
|
|
65
|
+
|
|
47
66
|
## Quick Start
|
|
48
67
|
|
|
49
68
|
### Functional API (Recommended)
|
|
@@ -57,8 +76,9 @@ const secret = generateSecret();
|
|
|
57
76
|
// Generate a TOTP token
|
|
58
77
|
const token = await generate({ secret });
|
|
59
78
|
|
|
60
|
-
// Verify a token
|
|
61
|
-
const
|
|
79
|
+
// Verify a token — returns VerifyResult, not a boolean
|
|
80
|
+
const result = await verify({ secret, token });
|
|
81
|
+
console.log(result.valid); // true or false
|
|
62
82
|
|
|
63
83
|
// Generate QR code URI for authenticator apps
|
|
64
84
|
const uri = generateURI({
|
|
@@ -68,12 +88,14 @@ const uri = generateURI({
|
|
|
68
88
|
});
|
|
69
89
|
```
|
|
70
90
|
|
|
91
|
+
Sync variants (`generateSync`, `verifySync`) are available when using a sync-compatible crypto plugin such as `@otplib/plugin-crypto-node` or `@otplib/plugin-crypto-noble`.
|
|
92
|
+
|
|
71
93
|
### Class API
|
|
72
94
|
|
|
73
95
|
```typescript
|
|
74
96
|
import { OTP } from "otplib";
|
|
75
97
|
|
|
76
|
-
// Create OTP instance (defaults to TOTP)
|
|
98
|
+
// Create OTP instance (defaults to TOTP strategy)
|
|
77
99
|
const otp = new OTP();
|
|
78
100
|
|
|
79
101
|
// Generate a secret
|
|
@@ -82,8 +104,9 @@ const secret = otp.generateSecret();
|
|
|
82
104
|
// Generate a TOTP token
|
|
83
105
|
const token = await otp.generate({ secret });
|
|
84
106
|
|
|
85
|
-
// Verify a token
|
|
86
|
-
const
|
|
107
|
+
// Verify a token — returns VerifyResult, not a boolean
|
|
108
|
+
const result = await otp.verify({ secret, token });
|
|
109
|
+
console.log(result.valid); // true or false
|
|
87
110
|
|
|
88
111
|
// Generate QR code URI for authenticator apps
|
|
89
112
|
const uri = otp.generateURI({
|
|
@@ -93,11 +116,30 @@ const uri = otp.generateURI({
|
|
|
93
116
|
});
|
|
94
117
|
```
|
|
95
118
|
|
|
96
|
-
|
|
119
|
+
The class also exposes `generateSync` and `verifySync` for use with sync-compatible crypto plugins.
|
|
120
|
+
|
|
121
|
+
#### HOTP (counter-based) with the Class API
|
|
122
|
+
|
|
123
|
+
Pass `strategy: 'hotp'` to switch to counter-based OTP. A `counter` value is required for generation and verification.
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { OTP } from "otplib";
|
|
127
|
+
|
|
128
|
+
const otp = new OTP({ strategy: "hotp" });
|
|
129
|
+
const secret = otp.generateSecret();
|
|
130
|
+
|
|
131
|
+
const token = await otp.generate({ secret, counter: 0 });
|
|
132
|
+
const result = await otp.verify({ secret, token, counter: 0 });
|
|
133
|
+
console.log(result.valid); // true or false
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Compatibility with Authenticator Apps
|
|
97
137
|
|
|
98
138
|
### Secret Format
|
|
99
139
|
|
|
100
|
-
By default, otplib expects secrets to be in **Base32** format.
|
|
140
|
+
By default, otplib expects secrets to be in **Base32** format. This is the ensure broader compatiblity as it the standard format used by authenticator applications and QR code URIs.
|
|
141
|
+
|
|
142
|
+
While the core HOTP (RFC 4226) and TOTP (RFC 6238) specifications work with raw binary data and don't mandate Base32 encoding, Base32
|
|
101
143
|
|
|
102
144
|
```typescript
|
|
103
145
|
// Base32 secret (standard format for authenticator compatibility)
|
|
@@ -106,7 +148,35 @@ const secret = "GEZDGNBVGY3TQOJQGEZDGNBVGY";
|
|
|
106
148
|
|
|
107
149
|
However, if you need to use secrets in other formats, you can either use the `plugin-base32-alt` plugin for raw strings or pass a byte array (using `stringToBytes` helper) for binary data.
|
|
108
150
|
|
|
109
|
-
|
|
151
|
+
> [!IMPORTANT]
|
|
152
|
+
>
|
|
153
|
+
> Following RFC 4226's recommendation, secrets must be at least **16 bytes (128 bits)** after Base32 decoding — anything shorter throws `SecretTooShortError`. Many tutorials and RFC test vectors use shorter secrets that fall outside this minimum (for example, the canonical `JBSWY3DPEHPK3PXP` decodes to only 10 bytes). To interoperate with these, override the `MIN_SECRET_BYTES` guardrail:
|
|
154
|
+
>
|
|
155
|
+
> ```typescript
|
|
156
|
+
> import { generate, createGuardrails } from "otplib";
|
|
157
|
+
>
|
|
158
|
+
> const token = await generate({
|
|
159
|
+
> secret: "JBSWY3DPEHPK3PXP",
|
|
160
|
+
> guardrails: createGuardrails({ MIN_SECRET_BYTES: 10 }),
|
|
161
|
+
> });
|
|
162
|
+
> ```
|
|
163
|
+
>
|
|
164
|
+
> See [Troubleshooting — SecretTooShortError](https://otplib.yeojz.dev/guide/troubleshooting#secrettooshorterror) and [Danger Zone — Guardrails](https://otplib.yeojz.dev/guide/danger-zone#guardrails) for the security trade-offs.
|
|
165
|
+
|
|
166
|
+
### Configuration Defaults
|
|
167
|
+
|
|
168
|
+
RFC 4226 (HOTP) and RFC 6238 (TOTP) define flexible algorithms that allow different hash functions, digit lengths, and time steps. However, most authenticator apps (Google Authenticator, Authy, Microsoft Authenticator, 1Password, etc.) and services offering 2 factor authentication use the following defaults:
|
|
169
|
+
|
|
170
|
+
| Parameter | Value |
|
|
171
|
+
| ----------- | ------------- |
|
|
172
|
+
| `algorithm` | `sha1` |
|
|
173
|
+
| `digits` | `6` |
|
|
174
|
+
| `period` | `30` |
|
|
175
|
+
| `secret` | Base32 string |
|
|
176
|
+
|
|
177
|
+
If you are deviating from these values, do validate that it is supported by the target application.
|
|
178
|
+
|
|
179
|
+
If you need to provision an authenticator app via QR code, use [`@otplib/uri`](https://www.npmjs.com/package/@otplib/uri) to generate an `otpauth://totp/` URI.
|
|
110
180
|
|
|
111
181
|
## Documentation
|
|
112
182
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";var otplib=(()=>{var It=Object.defineProperty;var Nr=Object.getOwnPropertyDescriptor;var $r=Object.getOwnPropertyNames;var jr=Object.prototype.hasOwnProperty;var Fr=(t,e)=>{for(var r in e)It(t,r,{get:e[r],enumerable:!0})},qr=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of $r(e))!jr.call(t,n)&&n!==r&&It(t,n,{get:()=>e[n],enumerable:!(o=Nr(e,n))||o.enumerable});return t};var Wr=t=>qr(It({},"__esModule",{value:!0}),t);var un={};Fr(un,{HOTP:()=>Ve,NobleCryptoPlugin:()=>Ke,OTP:()=>At,ScureBase32Plugin:()=>Fe,TOTP:()=>$e,createGuardrails:()=>b,generate:()=>Ot,generateSecret:()=>Gr,generateSync:()=>Et,generateURI:()=>Tt,stringToBytes:()=>Ue,verify:()=>wt,verifySync:()=>Pt,wrapResult:()=>kt,wrapResultAsync:()=>Lt});var w=class extends Error{constructor(e,r){super(e,r),this.name="OTPError"}},ne=class extends w{constructor(e){super(e),this.name="SecretError"}},oe=class extends ne{constructor(e,r){super(`Secret must be at least ${e} bytes (${e*8} bits), got ${r} bytes`),this.name="SecretTooShortError"}},se=class extends ne{constructor(e,r){super(`Secret must not exceed ${e} bytes, got ${r} bytes`),this.name="SecretTooLongError"}},K=class extends w{constructor(e){super(e),this.name="CounterError"}},ie=class extends K{constructor(){super("Counter must be non-negative"),this.name="CounterNegativeError"}},J=class extends K{constructor(){super("Counter exceeds maximum safe integer value"),this.name="CounterOverflowError"}},ae=class extends K{constructor(){super("Counter must be a finite integer"),this.name="CounterNotIntegerError"}},ce=class extends w{constructor(e){super(e),this.name="TimeError"}},ue=class extends ce{constructor(){super("Time must be non-negative"),this.name="TimeNegativeError"}},fe=class extends ce{constructor(){super("Time must be a finite number"),this.name="TimeNotFiniteError"}},le=class extends w{constructor(e){super(e),this.name="PeriodError"}},pe=class extends le{constructor(e){super(`Period must be at least ${e} second(s)`),this.name="PeriodTooSmallError"}},de=class extends le{constructor(e){super(`Period must not exceed ${e} seconds`),this.name="PeriodTooLargeError"}};var he=class extends w{constructor(e){super(e),this.name="TokenError"}},ge=class extends he{constructor(e,r){super(`Token must be ${e} digits, got ${r}`),this.name="TokenLengthError"}},xe=class extends he{constructor(){super("Token must contain only digits"),this.name="TokenFormatError"}},ye=class extends w{constructor(e,r){super(e,r),this.name="CryptoError"}},U=class extends ye{constructor(e,r){super(`HMAC computation failed: ${e}`,r),this.name="HMACError"}},be=class extends ye{constructor(e,r){super(`Random byte generation failed: ${e}`,r),this.name="RandomBytesError"}};var V=class extends w{constructor(e){super(e),this.name="CounterToleranceError"}},me=class extends V{constructor(e,r){super(`Counter tolerance validation failed: total checks (${r}) exceeds MAX_WINDOW (${e})`),this.name="CounterToleranceTooLargeError"}},Te=class extends V{constructor(){super("Counter tolerance cannot contain negative values"),this.name="CounterToleranceNegativeError"}},N=class extends w{constructor(e){super(e),this.name="EpochToleranceError"}},Oe=class extends N{constructor(){super("Epoch tolerance cannot contain negative values"),this.name="EpochToleranceNegativeError"}},Ee=class extends N{constructor(e,r){super(`Epoch tolerance must not exceed ${e} seconds, got ${r}. Large tolerances can cause performance issues.`),this.name="EpochToleranceTooLargeError"}},we=class extends w{constructor(e){super(e),this.name="PluginError"}},Pe=class extends we{constructor(){super("Crypto plugin is required."),this.name="CryptoPluginMissingError"}},Ae=class extends we{constructor(){super("Base32 plugin is required."),this.name="Base32PluginMissingError"}},T=class extends w{constructor(e){super(e),this.name="ConfigurationError"}},Se=class extends T{constructor(){super("Secret is required. Use generateSecret() to create one, or provide via { secret: 'YOUR_BASE32_SECRET' }"),this.name="SecretMissingError"}},Ce=class extends T{constructor(){super("Label is required for URI generation. Example: { label: 'user@example.com' }"),this.name="LabelMissingError"}},Re=class extends T{constructor(){super("Issuer is required for URI generation. Example: { issuer: 'MyApp' }"),this.name="IssuerMissingError"}},Be=class extends T{constructor(){super("Class API requires secret to be a Base32 string, not Uint8Array. Use generateSecret() or provide a Base32-encoded string."),this.name="SecretTypeError"}},Q=class extends w{constructor(e){super(e),this.name="AfterTimeStepError"}},Ie=class extends Q{constructor(){super("afterTimeStep must be >= 0"),this.name="AfterTimeStepNegativeError"}},He=class extends Q{constructor(){super("Invalid afterTimeStep: non-integer value"),this.name="AfterTimeStepNotIntegerError"}},_e=class extends Q{constructor(){super("Invalid afterTimeStep: cannot be greater than current time step plus window"),this.name="AfterTimeStepRangeExceededError"}};var Xr=new TextEncoder,hn=new TextDecoder,rr=16,nr=64,or=20,sr=1,ir=3600,ar=30,cr=Number.MAX_SAFE_INTEGER,ur=99,fr=Symbol("otplib.guardrails.override");function Z(t,e,r){if(typeof e!="number"||!Number.isSafeInteger(e))throw new T(`Guardrail '${t}' must be a safe integer`);if(e<r)throw new T(`Guardrail '${t}' must be >= ${r}`)}var $=Object.freeze({MIN_SECRET_BYTES:rr,MAX_SECRET_BYTES:nr,MIN_PERIOD:sr,MAX_PERIOD:ir,MAX_COUNTER:cr,MAX_WINDOW:ur,[fr]:!1});function b(t){if(!t)return $;t.MIN_SECRET_BYTES!==void 0&&Z("MIN_SECRET_BYTES",t.MIN_SECRET_BYTES,1),t.MAX_SECRET_BYTES!==void 0&&Z("MAX_SECRET_BYTES",t.MAX_SECRET_BYTES,1),t.MIN_PERIOD!==void 0&&Z("MIN_PERIOD",t.MIN_PERIOD,1),t.MAX_PERIOD!==void 0&&Z("MAX_PERIOD",t.MAX_PERIOD,1),t.MAX_COUNTER!==void 0&&Z("MAX_COUNTER",t.MAX_COUNTER,0),t.MAX_WINDOW!==void 0&&Z("MAX_WINDOW",t.MAX_WINDOW,1);let e={...$,...t};if(e.MIN_SECRET_BYTES>e.MAX_SECRET_BYTES)throw new T("Guardrail 'MIN_SECRET_BYTES' must be <= 'MAX_SECRET_BYTES'");if(e.MIN_PERIOD>e.MAX_PERIOD)throw new T("Guardrail 'MIN_PERIOD' must be <= 'MAX_PERIOD'");return Object.freeze({...e,[fr]:!0})}function j(t,e=$){if(t.length<e.MIN_SECRET_BYTES)throw new oe(e.MIN_SECRET_BYTES,t.length);if(t.length>e.MAX_SECRET_BYTES)throw new se(e.MAX_SECRET_BYTES,t.length)}function et(t,e=$){if(typeof t=="number"){if(!Number.isFinite(t)||!Number.isInteger(t))throw new ae;if(!Number.isSafeInteger(t))throw new J}let r=typeof t=="bigint"?t:BigInt(t);if(r<0n)throw new ie;if(r>BigInt(e.MAX_COUNTER))throw new J}function tt(t){if(!Number.isFinite(t))throw new fe;if(t<0)throw new ue}function rt(t,e=$){if(!Number.isInteger(t)||t<e.MIN_PERIOD)throw new pe(e.MIN_PERIOD);if(t>e.MAX_PERIOD)throw new de(e.MAX_PERIOD)}function ve(t,e){if(t.length!==e)throw new ge(e,t.length);if(!/^\d+$/.test(t))throw new xe}function Ht(t,e=$){let[r,o]=st(t);if(!Number.isSafeInteger(r)||!Number.isSafeInteger(o))throw new V("Counter tolerance values must be safe integers");if(r<0||o<0)throw new Te;let n=r+o+1;if(n>e.MAX_WINDOW)throw new me(e.MAX_WINDOW,n)}function _t(t,e=ar,r=$){let[o,n]=Array.isArray(t)?t:[t,t];if(!Number.isSafeInteger(o)||!Number.isSafeInteger(n))throw new N("Epoch tolerance values must be safe integers");if(o<0||n<0)throw new Oe;let s=(r.MAX_WINDOW-1)*e,i=o+n;if(i>s)throw new Ee(s,i)}function Ut(t){let e=typeof t=="bigint"?t:BigInt(t),r=new ArrayBuffer(8);return new DataView(r).setBigUint64(0,e,!1),new Uint8Array(r)}function nt(t){let e=t[t.length-1]&15;return(t[e]&127)<<24|t[e+1]<<16|t[e+2]<<8|t[e+3]}function ot(t,e){let r=10**e;return(t%r).toString().padStart(e,"0")}function lr(t,e){return t.length===e.length}function vt(t,e){let r=Ue(t),o=Ue(e);if(!lr(r,o))return!1;let n=0;for(let s=0;s<r.length;s++)n|=r[s]^o[s];return n===0}function Ue(t){return typeof t=="string"?Xr.encode(t):t}function F(t,e){return typeof t=="string"?(q(e),e.decode(t)):t}function I(t){let{crypto:e,base32:r,length:o=or}=t;m(e),q(r);let n=e.randomBytes(o);return r.encode(n,{padding:!1})}function st(t=0){return Array.isArray(t)?t:[0,t]}function Dt(t=0){return Array.isArray(t)?t:[t,t]}function m(t){if(!t)throw new Pe}function q(t){if(!t)throw new Ae}function O(t){if(!t)throw new Se}function De(t){if(!t)throw new Ce}function ke(t){if(!t)throw new Re}function Le(t){if(typeof t!="string")throw new Be}function pr(t){return{ok:!0,value:t}}function dr(t){return{ok:!1,error:t}}function kt(t){return(...e)=>{try{return pr(t(...e))}catch(r){return dr(r)}}}function Lt(t){return async(...e)=>{try{return pr(await t(...e))}catch(r){return dr(r)}}}var it=class{constructor(e){this.crypto=e}get plugin(){return this.crypto}async hmac(e,r,o){try{let n=this.crypto.hmac(e,r,o);return n instanceof Promise?await n:n}catch(n){let s=n instanceof Error?n.message:String(n);throw new U(s,{cause:n})}}hmacSync(e,r,o){try{let n=this.crypto.hmac(e,r,o);if(n instanceof Promise)throw new U("Crypto plugin does not support synchronous HMAC operations");return n}catch(n){if(n instanceof U)throw n;let s=n instanceof Error?n.message:String(n);throw new U(s,{cause:n})}}randomBytes(e){try{return this.crypto.randomBytes(e)}catch(r){let o=r instanceof Error?r.message:String(r);throw new be(o,{cause:r})}}};function Mt(t){return new it(t)}function Gt(t){let{type:e,label:r,params:o}=t,n=r.split(":").map(a=>encodeURIComponent(a)).join(":"),s=`otpauth://${e}/${n}?`,i=[];return o.secret&&i.push(`secret=${encodeURIComponent(o.secret)}`),o.issuer&&i.push(`issuer=${encodeURIComponent(o.issuer)}`),o.algorithm&&o.algorithm!=="sha1"&&i.push(`algorithm=${o.algorithm.toUpperCase()}`),o.digits&&o.digits!==6&&i.push(`digits=${o.digits}`),e==="hotp"&&o.counter!==void 0&&i.push(`counter=${o.counter}`),e==="totp"&&o.period!==void 0&&o.period!==30&&i.push(`period=${o.period}`),s+=i.join("&"),s}function Me(t){let{issuer:e,label:r,secret:o,algorithm:n="sha1",digits:s=6,period:i=30}=t,a=e?`${e}:${r}`:r;return Gt({type:"totp",label:a,params:{secret:o,issuer:e,algorithm:n,digits:s,period:i}})}function Ge(t){let{issuer:e,label:r,secret:o,counter:n=0,algorithm:s="sha1",digits:i=6}=t,a=e?`${e}:${r}`:r;return Gt({type:"hotp",label:a,params:{secret:o,issuer:e,algorithm:s,digits:i,counter:n}})}var Ve=class{options;guardrails;constructor(e={}){this.options=e,this.guardrails=b(e.guardrails)}generateSecret(){let{crypto:e,base32:r}=this.options;return m(e),q(r),I({crypto:e,base32:r})}async generate(e,r){let o={...this.options,...r},{secret:n,crypto:s,base32:i,algorithm:a="sha1",digits:c=6}=o;O(n),m(s);let u=r?.guardrails??this.guardrails;return W({secret:n,counter:e,algorithm:a,digits:c,crypto:s,base32:i,guardrails:u,hooks:o.hooks})}async verify(e,r){let o={...this.options,...r},{secret:n,crypto:s,base32:i,algorithm:a="sha1",digits:c=6,counterTolerance:u=0}=o;O(n),m(s);let f=r?.guardrails??this.guardrails;return at({secret:n,token:e.token,counter:e.counter,algorithm:a,digits:c,counterTolerance:u,crypto:s,base32:i,guardrails:f,hooks:o.hooks})}toURI(e=0){let{issuer:r,label:o,secret:n,algorithm:s="sha1",digits:i=6}=this.options;return O(n),De(o),ke(r),Le(n),Ge({issuer:r,label:o,secret:n,algorithm:s,digits:i,counter:e})}};function hr(t){let{secret:e,counter:r,algorithm:o="sha1",digits:n=6,crypto:s,base32:i,guardrails:a,hooks:c}=t;O(e),m(s);let u=F(e,i);j(u,a),et(r,a);let f=Mt(s),l=Ut(r);return{ctx:f,algorithm:o,digits:n,secretBytes:u,counterBytes:l,hooks:c}}async function W(t){let{ctx:e,algorithm:r,digits:o,secretBytes:n,counterBytes:s,hooks:i}=hr(t),a=await e.hmac(r,n,s),c=i?.truncateDigest?i.truncateDigest(a):nt(a);return i?.encodeToken?i.encodeToken(c,o):ot(c,o)}function Ne(t){let{ctx:e,algorithm:r,digits:o,secretBytes:n,counterBytes:s,hooks:i}=hr(t),a=e.hmacSync(r,n,s),c=i?.truncateDigest?i.truncateDigest(a):nt(a);return i?.encodeToken?i.encodeToken(c,o):ot(c,o)}function gr(t){let{secret:e,counter:r,token:o,algorithm:n="sha1",digits:s=6,crypto:i,base32:a,counterTolerance:c=0,guardrails:u=b(),hooks:f}=t;O(e),m(i);let l=F(e,a);j(l,u),et(r,u),f?.validateToken?f.validateToken(o,s):ve(o,s),Ht(c,u);let p=typeof r=="bigint"?Number(r):r,[h,g]=st(c),x=h+g+1;return{token:o,counterNum:p,past:h,future:g,totalChecks:x,crypto:i,getGenerateOptions:E=>({secret:l,counter:E,algorithm:n,digits:s,crypto:i,guardrails:u,hooks:f})}}async function at(t){let{token:e,counterNum:r,past:o,totalChecks:n,crypto:s,getGenerateOptions:i}=gr(t),a=Math.max(0,o-r);for(let c=a;c<n;c++){let u=c-o,f=r+u,l=await W(i(f));if(s.constantTimeEqual(l,e))return{valid:!0,delta:u|0}}return{valid:!1}}function xr(t){let{token:e,counterNum:r,past:o,totalChecks:n,crypto:s,getGenerateOptions:i}=gr(t),a=Math.max(0,o-r);for(let c=a;c<n;c++){let u=c-o,f=r+u,l=Ne(i(f));if(s.constantTimeEqual(l,e))return{valid:!0,delta:u|0}}return{valid:!1}}var $e=class{options;guardrails;constructor(e={}){this.options=e,this.guardrails=b(e.guardrails)}generateSecret(){let{crypto:e,base32:r}=this.options;return m(e),q(r),I({crypto:e,base32:r})}async generate(e){let r={...this.options,...e},{secret:o,crypto:n,base32:s,algorithm:i="sha1",digits:a=6,period:c=30,epoch:u,t0:f=0}=r;O(o),m(n);let l=e?.guardrails??this.guardrails;return je({secret:o,algorithm:i,digits:a,period:c,epoch:u??Math.floor(Date.now()/1e3),t0:f,crypto:n,base32:s,guardrails:l,hooks:r.hooks})}async verify(e,r){let o={...this.options,...r},{secret:n,crypto:s,base32:i,algorithm:a="sha1",digits:c=6,period:u=30,epoch:f,t0:l=0,epochTolerance:p=0,afterTimeStep:h}=o;O(n),m(s);let g=r?.guardrails??this.guardrails;return ct({secret:n,token:e,algorithm:a,digits:c,period:u,epoch:f??Math.floor(Date.now()/1e3),t0:l,epochTolerance:p,afterTimeStep:h,crypto:s,base32:i,guardrails:g,hooks:o.hooks})}toURI(e){let{issuer:r,label:o,secret:n,algorithm:s="sha1",digits:i=6,period:a=30}=this.options,c=e?.label??o,u=e?.issuer??r,f=e?.secret??n;return O(f),De(c),ke(u),Le(f),Me({issuer:u,label:c,secret:f,algorithm:s,digits:i,period:a})}};function yr(t){let{secret:e,epoch:r=Math.floor(Date.now()/1e3),t0:o=0,period:n=30,algorithm:s="sha1",digits:i=6,crypto:a,base32:c,guardrails:u=b(),hooks:f}=t;O(e),m(a);let l=F(e,c);j(l,u),tt(r),rt(n,u);let p=Math.floor((r-o)/n);return{secret:l,counter:p,algorithm:s,digits:i,crypto:a,guardrails:u,hooks:f}}async function je(t){let e=yr(t);return W(e)}function Vt(t){let e=yr(t);return Ne(e)}function zr(t,e){if(t!==void 0){if(t<0)throw new Ie;if(!Number.isSafeInteger(t))throw new He;if(t>e)throw new _e}}function br(t,e){return e!==void 0&&t<=e}function mr(t){let{secret:e,token:r,epoch:o=Math.floor(Date.now()/1e3),t0:n=0,period:s=30,algorithm:i="sha1",digits:a=6,crypto:c,base32:u,epochTolerance:f=0,afterTimeStep:l,guardrails:p=b(),hooks:h}=t;O(e),m(c);let g=F(e,u);j(g,p),tt(o),rt(s,p),h?.validateToken?h.validateToken(r,a):ve(r,a),_t(f,s,p);let x=Math.floor((o-n)/s),[E,M]=Dt(f),G=Math.max(0,Math.floor((o-E-n)/s)),d=Math.floor((o+M-n)/s);return zr(l,d),{token:r,crypto:c,minCounter:G,maxCounter:d,currentCounter:x,t0:n,period:s,afterTimeStep:l,getGenerateOptions:S=>({secret:g,epoch:S*s+n,t0:n,period:s,algorithm:i,digits:a,crypto:c,guardrails:p,hooks:h})}}async function ct(t){let{token:e,crypto:r,minCounter:o,maxCounter:n,currentCounter:s,t0:i,period:a,afterTimeStep:c,getGenerateOptions:u}=mr(t);for(let f=o;f<=n;f++){if(br(f,c))continue;let l=await je(u(f));if(r.constantTimeEqual(l,e))return{valid:!0,delta:f-s,epoch:f*a+i,timeStep:f}}return{valid:!1}}function Tr(t){let{token:e,crypto:r,minCounter:o,maxCounter:n,currentCounter:s,t0:i,period:a,afterTimeStep:c,getGenerateOptions:u}=mr(t);for(let f=o;f<=n;f++){if(br(f,c))continue;let l=Vt(u(f));if(r.constantTimeEqual(l,e))return{valid:!0,delta:f-s,epoch:f*a+i,timeStep:f}}return{valid:!1}}function Yr(t){return t instanceof Uint8Array||ArrayBuffer.isView(t)&&t.constructor.name==="Uint8Array"&&"BYTES_PER_ELEMENT"in t&&t.BYTES_PER_ELEMENT===1}function Er(t,e){return Array.isArray(e)?e.length===0?!0:t?e.every(r=>typeof r=="string"):e.every(r=>Number.isSafeInteger(r)):!1}function ut(t,e){if(typeof e!="string")throw new TypeError(`${t}: string expected`);return!0}function jt(t){if(typeof t!="number")throw new TypeError(`number expected, got ${typeof t}`);if(!Number.isSafeInteger(t))throw new RangeError(`invalid integer: ${t}`)}function $t(t){if(!Array.isArray(t))throw new TypeError("array expected")}function ft(t,e){if(!Er(!0,e))throw new TypeError(`${t}: array of strings expected`)}function Kr(t,e){if(!Er(!1,e))throw new TypeError(`${t}: array of numbers expected`)}function Jr(...t){let e=s=>s,r=(s,i)=>a=>s(i(a)),o=t.map(s=>s.encode).reduceRight(r,e),n=t.map(s=>s.decode).reduce(r,e);return{encode:o,decode:n}}function Qr(t){let e=typeof t=="string"?t.split(""):t,r=e.length;ft("alphabet",e);let o=new Map(e.map((n,s)=>[n,s]));return{encode:n=>($t(n),n.map(s=>{if(!Number.isSafeInteger(s)||s<0||s>=r)throw new Error(`alphabet.encode: digit index outside alphabet "${s}". Allowed: ${t}`);return e[s]})),decode:n=>($t(n),n.map(s=>{ut("alphabet.decode",s);let i=o.get(s);if(i===void 0)throw new Error(`Unknown letter: "${s}". Allowed: ${t}`);return i}))}}function Zr(t=""){return ut("join",t),{encode:e=>(ft("join.decode",e),e.join(t)),decode:e=>(ut("join.decode",e),e.split(t))}}function en(t,e="="){return jt(t),ut("padding",e),{encode(r){for(ft("padding.encode",r);r.length*t%8;)r.push(e);return r},decode(r){ft("padding.decode",r);let o=r.length;if(o*t%8)throw new Error("padding: invalid, string should have whole number of bytes");for(;o>0&&r[o-1]===e;o--)if((o-1)*t%8===0)throw new Error("padding: invalid, string has too much padding");return r.slice(0,o)}}}var wr=(t,e)=>e===0?t:wr(e,t%e),lt=(t,e)=>t+(e-wr(t,e)),Nt=(()=>{let t=[];for(let e=0;e<40;e++)t.push(2**e);return t})();function Or(t,e,r,o){if($t(t),e<=0||e>32)throw new RangeError(`convertRadix2: wrong from=${e}`);if(r<=0||r>32)throw new RangeError(`convertRadix2: wrong to=${r}`);if(lt(e,r)>32)throw new Error(`convertRadix2: carry overflow from=${e} to=${r} carryBits=${lt(e,r)}`);let n=0,s=0,i=Nt[e],a=Nt[r]-1,c=[];for(let u of t){if(jt(u),u>=i)throw new Error(`convertRadix2: invalid data word=${u} from=${e}`);if(n=n<<e|u,s+e>32)throw new Error(`convertRadix2: carry overflow pos=${s} from=${e}`);for(s+=e;s>=r;s-=r)c.push((n>>s-r&a)>>>0);let f=Nt[s];if(f===void 0)throw new Error("invalid carry");n&=f-1}if(n=n<<r-s&a,!o&&s>=e)throw new Error("Excess padding");if(!o&&n>0)throw new Error(`Non-zero padding: ${n}`);return o&&s>0&&c.push(n>>>0),c}function tn(t,e=!1){if(jt(t),t<=0||t>32)throw new RangeError("radix2: bits should be in (0..32]");if(lt(8,t)>32||lt(t,8)>32)throw new RangeError("radix2: carry overflow");return{encode:r=>{if(!Yr(r))throw new TypeError("radix2.encode input should be Uint8Array");return Or(Array.from(r),8,t,!e)},decode:r=>(Kr("radix2.decode",r),Uint8Array.from(Or(r,t,8,e)))}}var Ft=Object.freeze(Jr(tn(5),Qr("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"),en(5),Zr("")));var Fe=class{name="scure";encode(e,r={}){let{padding:o=!1}=r,n=Ft.encode(e);return o?n:n.replace(/=+$/,"")}decode(e){try{let r=e.toUpperCase(),o=r.padEnd(Math.ceil(r.length/8)*8,"=");return Ft.decode(o)}catch(r){throw new Error(`Invalid Base32 string: ${r.message}`)}}},ee=Object.freeze(new Fe);function rn(t){return t instanceof Uint8Array||ArrayBuffer.isView(t)&&t.constructor.name==="Uint8Array"&&"BYTES_PER_ELEMENT"in t&&t.BYTES_PER_ELEMENT===1}function qt(t,e=""){if(typeof t!="number"){let r=e&&`"${e}" `;throw new TypeError(`${r}expected number, got ${typeof t}`)}if(!Number.isSafeInteger(t)||t<0){let r=e&&`"${e}" `;throw new RangeError(`${r}expected integer >= 0, got ${t}`)}}function qe(t,e,r=""){let o=rn(t),n=t?.length,s=e!==void 0;if(!o||s&&n!==e){let i=r&&`"${r}" `,a=s?` of length ${e}`:"",c=o?`length=${n}`:`type=${typeof t}`,u=i+"expected Uint8Array"+a+", got "+c;throw o?new RangeError(u):new TypeError(u)}return t}function Pr(t){if(typeof t!="function"||typeof t.create!="function")throw new TypeError("Hash must wrapped by utils.createHasher");if(qt(t.outputLen),qt(t.blockLen),t.outputLen<1)throw new Error('"outputLen" must be >= 1');if(t.blockLen<1)throw new Error('"blockLen" must be >= 1')}function te(t,e=!0){if(t.destroyed)throw new Error("Hash instance has been destroyed");if(e&&t.finished)throw new Error("Hash#digest() has already been called")}function pt(t,e){qe(t,void 0,"digestInto() output");let r=e.outputLen;if(t.length<r)throw new RangeError('"digestInto() output" expected to be of length >='+r)}function P(...t){for(let e=0;e<t.length;e++)t[e].fill(0)}function dt(t){return new DataView(t.buffer,t.byteOffset,t.byteLength)}function A(t,e){return t<<32-e|t>>>e}function ht(t,e){return t<<e|t>>>32-e>>>0}function We(t,e={}){let r=(n,s)=>t(s).update(n).digest(),o=t(void 0);return r.outputLen=o.outputLen,r.blockLen=o.blockLen,r.canXOF=o.canXOF,r.create=n=>t(n),Object.assign(r,e),Object.freeze(r)}function Ar(t=32){qt(t,"bytesLength");let e=typeof globalThis=="object"?globalThis.crypto:null;if(typeof e?.getRandomValues!="function")throw new Error("crypto.getRandomValues must be defined");if(t>65536)throw new RangeError(`"bytesLength" expected <= 65536, got ${t}`);return e.getRandomValues(new Uint8Array(t))}var Wt=t=>({oid:Uint8Array.from([6,9,96,134,72,1,101,3,4,2,t])});var gt=class{oHash;iHash;blockLen;outputLen;canXOF=!1;finished=!1;destroyed=!1;constructor(e,r){if(Pr(e),qe(r,void 0,"key"),this.iHash=e.create(),typeof this.iHash.update!="function")throw new Error("Expected instance of class which extends utils.Hash");this.blockLen=this.iHash.blockLen,this.outputLen=this.iHash.outputLen;let o=this.blockLen,n=new Uint8Array(o);n.set(r.length>o?e.create().update(r).digest():r);for(let s=0;s<n.length;s++)n[s]^=54;this.iHash.update(n),this.oHash=e.create();for(let s=0;s<n.length;s++)n[s]^=106;this.oHash.update(n),P(n)}update(e){return te(this),this.iHash.update(e),this}digestInto(e){te(this),pt(e,this),this.finished=!0;let r=e.subarray(0,this.outputLen);this.iHash.digestInto(r),this.oHash.update(r),this.oHash.digestInto(r),this.destroy()}digest(){let e=new Uint8Array(this.oHash.outputLen);return this.digestInto(e),e}_cloneInto(e){e||=Object.create(Object.getPrototypeOf(this),{});let{oHash:r,iHash:o,finished:n,destroyed:s,blockLen:i,outputLen:a}=this;return e=e,e.finished=n,e.destroyed=s,e.blockLen=i,e.outputLen=a,e.oHash=r._cloneInto(e.oHash),e.iHash=o._cloneInto(e.iHash),e}clone(){return this._cloneInto()}destroy(){this.destroyed=!0,this.oHash.destroy(),this.iHash.destroy()}},Sr=(()=>{let t=((e,r,o)=>new gt(e,r).update(o).digest());return t.create=(e,r)=>new gt(e,r),t})();function xt(t,e,r){return t&e^~t&r}function yt(t,e,r){return t&e^t&r^e&r}var X=class{blockLen;outputLen;canXOF=!1;padOffset;isLE;buffer;view;finished=!1;length=0;pos=0;destroyed=!1;constructor(e,r,o,n){this.blockLen=e,this.outputLen=r,this.padOffset=o,this.isLE=n,this.buffer=new Uint8Array(e),this.view=dt(this.buffer)}update(e){te(this),qe(e);let{view:r,buffer:o,blockLen:n}=this,s=e.length;for(let i=0;i<s;){let a=Math.min(n-this.pos,s-i);if(a===n){let c=dt(e);for(;n<=s-i;i+=n)this.process(c,i);continue}o.set(e.subarray(i,i+a),this.pos),this.pos+=a,i+=a,this.pos===n&&(this.process(r,0),this.pos=0)}return this.length+=e.length,this.roundClean(),this}digestInto(e){te(this),pt(e,this),this.finished=!0;let{buffer:r,view:o,blockLen:n,isLE:s}=this,{pos:i}=this;r[i++]=128,P(this.buffer.subarray(i)),this.padOffset>n-i&&(this.process(o,0),i=0);for(let l=i;l<n;l++)r[l]=0;o.setBigUint64(n-8,BigInt(this.length*8),s),this.process(o,0);let a=dt(e),c=this.outputLen;if(c%4)throw new Error("_sha2: outputLen must be aligned to 32bit");let u=c/4,f=this.get();if(u>f.length)throw new Error("_sha2: outputLen bigger than state");for(let l=0;l<u;l++)a.setUint32(4*l,f[l],s)}digest(){let{buffer:e,outputLen:r}=this;this.digestInto(e);let o=e.slice(0,r);return this.destroy(),o}_cloneInto(e){e||=new this.constructor,e.set(...this.get());let{blockLen:r,buffer:o,length:n,finished:s,destroyed:i,pos:a}=this;return e.destroyed=i,e.finished=s,e.length=n,e.pos=a,n%r&&e.buffer.set(o),e}clone(){return this._cloneInto()}},H=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);var y=Uint32Array.from([1779033703,4089235720,3144134277,2227873595,1013904242,4271175723,2773480762,1595750129,1359893119,2917565137,2600822924,725511199,528734635,4215389547,1541459225,327033209]);var Xe=Uint32Array.from([1732584193,4023233417,2562383102,271733878,3285377520]),v=new Uint32Array(80),Xt=class extends X{A=Xe[0]|0;B=Xe[1]|0;C=Xe[2]|0;D=Xe[3]|0;E=Xe[4]|0;constructor(){super(64,20,8,!1)}get(){let{A:e,B:r,C:o,D:n,E:s}=this;return[e,r,o,n,s]}set(e,r,o,n,s){this.A=e|0,this.B=r|0,this.C=o|0,this.D=n|0,this.E=s|0}process(e,r){for(let c=0;c<16;c++,r+=4)v[c]=e.getUint32(r,!1);for(let c=16;c<80;c++)v[c]=ht(v[c-3]^v[c-8]^v[c-14]^v[c-16],1);let{A:o,B:n,C:s,D:i,E:a}=this;for(let c=0;c<80;c++){let u,f;c<20?(u=xt(n,s,i),f=1518500249):c<40?(u=n^s^i,f=1859775393):c<60?(u=yt(n,s,i),f=2400959708):(u=n^s^i,f=3395469782);let l=ht(o,5)+u+a+f+v[c]|0;a=i,i=s,s=ht(n,30),n=o,o=l}o=o+this.A|0,n=n+this.B|0,s=s+this.C|0,i=i+this.D|0,a=a+this.E|0,this.set(o,n,s,i,a)}roundClean(){P(v)}destroy(){this.destroyed=!0,this.set(0,0,0,0,0),P(this.buffer)}},Cr=We(()=>new Xt);var bt=BigInt(4294967295),Rr=BigInt(32);function nn(t,e=!1){return e?{h:Number(t&bt),l:Number(t>>Rr&bt)}:{h:Number(t>>Rr&bt)|0,l:Number(t&bt)|0}}function Br(t,e=!1){let r=t.length,o=new Uint32Array(r),n=new Uint32Array(r);for(let s=0;s<r;s++){let{h:i,l:a}=nn(t[s],e);[o[s],n[s]]=[i,a]}return[o,n]}var zt=(t,e,r)=>t>>>r,Yt=(t,e,r)=>t<<32-r|e>>>r,z=(t,e,r)=>t>>>r|e<<32-r,Y=(t,e,r)=>t<<32-r|e>>>r,ze=(t,e,r)=>t<<64-r|e>>>r-32,Ye=(t,e,r)=>t>>>r-32|e<<64-r;function C(t,e,r,o){let n=(e>>>0)+(o>>>0);return{h:t+r+(n/2**32|0)|0,l:n|0}}var Ir=(t,e,r)=>(t>>>0)+(e>>>0)+(r>>>0),Hr=(t,e,r,o)=>e+r+o+(t/2**32|0)|0,_r=(t,e,r,o)=>(t>>>0)+(e>>>0)+(r>>>0)+(o>>>0),Ur=(t,e,r,o,n)=>e+r+o+n+(t/2**32|0)|0,vr=(t,e,r,o,n)=>(t>>>0)+(e>>>0)+(r>>>0)+(o>>>0)+(n>>>0),Dr=(t,e,r,o,n,s)=>e+r+o+n+s+(t/2**32|0)|0;var sn=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),D=new Uint32Array(64),Kt=class extends X{constructor(e){super(64,e,8,!1)}get(){let{A:e,B:r,C:o,D:n,E:s,F:i,G:a,H:c}=this;return[e,r,o,n,s,i,a,c]}set(e,r,o,n,s,i,a,c){this.A=e|0,this.B=r|0,this.C=o|0,this.D=n|0,this.E=s|0,this.F=i|0,this.G=a|0,this.H=c|0}process(e,r){for(let l=0;l<16;l++,r+=4)D[l]=e.getUint32(r,!1);for(let l=16;l<64;l++){let p=D[l-15],h=D[l-2],g=A(p,7)^A(p,18)^p>>>3,x=A(h,17)^A(h,19)^h>>>10;D[l]=x+D[l-7]+g+D[l-16]|0}let{A:o,B:n,C:s,D:i,E:a,F:c,G:u,H:f}=this;for(let l=0;l<64;l++){let p=A(a,6)^A(a,11)^A(a,25),h=f+p+xt(a,c,u)+sn[l]+D[l]|0,x=(A(o,2)^A(o,13)^A(o,22))+yt(o,n,s)|0;f=u,u=c,c=a,a=i+h|0,i=s,s=n,n=o,o=h+x|0}o=o+this.A|0,n=n+this.B|0,s=s+this.C|0,i=i+this.D|0,a=a+this.E|0,c=c+this.F|0,u=u+this.G|0,f=f+this.H|0,this.set(o,n,s,i,a,c,u,f)}roundClean(){P(D)}destroy(){this.destroyed=!0,this.set(0,0,0,0,0,0,0,0),P(this.buffer)}},Jt=class extends Kt{A=H[0]|0;B=H[1]|0;C=H[2]|0;D=H[3]|0;E=H[4]|0;F=H[5]|0;G=H[6]|0;H=H[7]|0;constructor(){super(32)}};var kr=Br(["0x428a2f98d728ae22","0x7137449123ef65cd","0xb5c0fbcfec4d3b2f","0xe9b5dba58189dbbc","0x3956c25bf348b538","0x59f111f1b605d019","0x923f82a4af194f9b","0xab1c5ed5da6d8118","0xd807aa98a3030242","0x12835b0145706fbe","0x243185be4ee4b28c","0x550c7dc3d5ffb4e2","0x72be5d74f27b896f","0x80deb1fe3b1696b1","0x9bdc06a725c71235","0xc19bf174cf692694","0xe49b69c19ef14ad2","0xefbe4786384f25e3","0x0fc19dc68b8cd5b5","0x240ca1cc77ac9c65","0x2de92c6f592b0275","0x4a7484aa6ea6e483","0x5cb0a9dcbd41fbd4","0x76f988da831153b5","0x983e5152ee66dfab","0xa831c66d2db43210","0xb00327c898fb213f","0xbf597fc7beef0ee4","0xc6e00bf33da88fc2","0xd5a79147930aa725","0x06ca6351e003826f","0x142929670a0e6e70","0x27b70a8546d22ffc","0x2e1b21385c26c926","0x4d2c6dfc5ac42aed","0x53380d139d95b3df","0x650a73548baf63de","0x766a0abb3c77b2a8","0x81c2c92e47edaee6","0x92722c851482353b","0xa2bfe8a14cf10364","0xa81a664bbc423001","0xc24b8b70d0f89791","0xc76c51a30654be30","0xd192e819d6ef5218","0xd69906245565a910","0xf40e35855771202a","0x106aa07032bbd1b8","0x19a4c116b8d2d0c8","0x1e376c085141ab53","0x2748774cdf8eeb99","0x34b0bcb5e19b48a8","0x391c0cb3c5c95a63","0x4ed8aa4ae3418acb","0x5b9cca4f7763e373","0x682e6ff3d6b2b8a3","0x748f82ee5defb2fc","0x78a5636f43172f60","0x84c87814a1f0ab72","0x8cc702081a6439ec","0x90befffa23631e28","0xa4506cebde82bde9","0xbef9a3f7b2c67915","0xc67178f2e372532b","0xca273eceea26619c","0xd186b8c721c0c207","0xeada7dd6cde0eb1e","0xf57d4f7fee6ed178","0x06f067aa72176fba","0x0a637dc5a2c898a6","0x113f9804bef90dae","0x1b710b35131c471b","0x28db77f523047d84","0x32caab7b40c72493","0x3c9ebe0a15c9bebc","0x431d67c49c100d4c","0x4cc5d4becb3e42b6","0x597f299cfc657e2a","0x5fcb6fab3ad6faec","0x6c44198c4a475817"].map(t=>BigInt(t))),an=kr[0],cn=kr[1],k=new Uint32Array(80),L=new Uint32Array(80),Qt=class extends X{constructor(e){super(128,e,16,!1)}get(){let{Ah:e,Al:r,Bh:o,Bl:n,Ch:s,Cl:i,Dh:a,Dl:c,Eh:u,El:f,Fh:l,Fl:p,Gh:h,Gl:g,Hh:x,Hl:E}=this;return[e,r,o,n,s,i,a,c,u,f,l,p,h,g,x,E]}set(e,r,o,n,s,i,a,c,u,f,l,p,h,g,x,E){this.Ah=e|0,this.Al=r|0,this.Bh=o|0,this.Bl=n|0,this.Ch=s|0,this.Cl=i|0,this.Dh=a|0,this.Dl=c|0,this.Eh=u|0,this.El=f|0,this.Fh=l|0,this.Fl=p|0,this.Gh=h|0,this.Gl=g|0,this.Hh=x|0,this.Hl=E|0}process(e,r){for(let d=0;d<16;d++,r+=4)k[d]=e.getUint32(r),L[d]=e.getUint32(r+=4);for(let d=16;d<80;d++){let S=k[d-15]|0,_=L[d-15]|0,St=z(S,_,1)^z(S,_,8)^zt(S,_,7),Ct=Y(S,_,1)^Y(S,_,8)^Yt(S,_,7),R=k[d-2]|0,B=L[d-2]|0,Qe=z(R,B,19)^ze(R,B,61)^zt(R,B,6),Rt=Y(R,B,19)^Ye(R,B,61)^Yt(R,B,6),Ze=_r(Ct,Rt,L[d-7],L[d-16]),Bt=Ur(Ze,St,Qe,k[d-7],k[d-16]);k[d]=Bt|0,L[d]=Ze|0}let{Ah:o,Al:n,Bh:s,Bl:i,Ch:a,Cl:c,Dh:u,Dl:f,Eh:l,El:p,Fh:h,Fl:g,Gh:x,Gl:E,Hh:M,Hl:G}=this;for(let d=0;d<80;d++){let S=z(l,p,14)^z(l,p,18)^ze(l,p,41),_=Y(l,p,14)^Y(l,p,18)^Ye(l,p,41),St=l&h^~l&x,Ct=p&g^~p&E,R=vr(G,_,Ct,cn[d],L[d]),B=Dr(R,M,S,St,an[d],k[d]),Qe=R|0,Rt=z(o,n,28)^ze(o,n,34)^ze(o,n,39),Ze=Y(o,n,28)^Ye(o,n,34)^Ye(o,n,39),Bt=o&s^o&a^s&a,Vr=n&i^n&c^i&c;M=x|0,G=E|0,x=h|0,E=g|0,h=l|0,g=p|0,{h:l,l:p}=C(u|0,f|0,B|0,Qe|0),u=a|0,f=c|0,a=s|0,c=i|0,s=o|0,i=n|0;let tr=Ir(Qe,Ze,Vr);o=Hr(tr,B,Rt,Bt),n=tr|0}({h:o,l:n}=C(this.Ah|0,this.Al|0,o|0,n|0)),{h:s,l:i}=C(this.Bh|0,this.Bl|0,s|0,i|0),{h:a,l:c}=C(this.Ch|0,this.Cl|0,a|0,c|0),{h:u,l:f}=C(this.Dh|0,this.Dl|0,u|0,f|0),{h:l,l:p}=C(this.Eh|0,this.El|0,l|0,p|0),{h,l:g}=C(this.Fh|0,this.Fl|0,h|0,g|0),{h:x,l:E}=C(this.Gh|0,this.Gl|0,x|0,E|0),{h:M,l:G}=C(this.Hh|0,this.Hl|0,M|0,G|0),this.set(o,n,s,i,a,c,u,f,l,p,h,g,x,E,M,G)}roundClean(){P(k,L)}destroy(){this.destroyed=!0,P(this.buffer),this.set(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)}},Zt=class extends Qt{Ah=y[0]|0;Al=y[1]|0;Bh=y[2]|0;Bl=y[3]|0;Ch=y[4]|0;Cl=y[5]|0;Dh=y[6]|0;Dl=y[7]|0;Eh=y[8]|0;El=y[9]|0;Fh=y[10]|0;Fl=y[11]|0;Gh=y[12]|0;Gl=y[13]|0;Hh=y[14]|0;Hl=y[15]|0;constructor(){super(64)}};var Lr=We(()=>new Jt,Wt(1));var Mr=We(()=>new Zt,Wt(3));var Ke=class{name="noble";hmac(e,r,o){return Sr(e==="sha1"?Cr:e==="sha256"?Lr:Mr,r,o)}randomBytes(e){return Ar(e)}constantTimeEqual(e,r){return vt(e,r)}},re=Object.freeze(new Ke);function mt(t){return{secret:t.secret,strategy:t.strategy??"totp",crypto:t.crypto??re,base32:t.base32??ee,algorithm:t.algorithm??"sha1",digits:t.digits??6,period:t.period??30,epoch:t.epoch??Math.floor(Date.now()/1e3),t0:t.t0??0,counter:t.counter,guardrails:t.guardrails??b(),hooks:t.hooks}}function er(t){return{...mt(t),token:t.token,epochTolerance:t.epochTolerance??0,counterTolerance:t.counterTolerance??0,afterTimeStep:t.afterTimeStep}}function Je(t,e,r){if(t==="totp")return r.totp();if(t==="hotp"){if(e===void 0)throw new T("Counter is required for HOTP strategy. Example: { strategy: 'hotp', counter: 0 }");return r.hotp(e)}throw new T(`Unknown OTP strategy: ${t}. Valid strategies are 'totp' or 'hotp'.`)}function Gr(t){let{crypto:e=re,base32:r=ee,length:o=20}=t||{};return I({crypto:e,base32:r,length:o})}function Tt(t){let{strategy:e="totp",issuer:r,label:o,secret:n,algorithm:s="sha1",digits:i=6,period:a=30,counter:c}=t;return Je(e,c,{totp:()=>Me({issuer:r,label:o,secret:n,algorithm:s,digits:i,period:a}),hotp:u=>Ge({issuer:r,label:o,secret:n,algorithm:s,digits:i,counter:u})})}async function Ot(t){let e=mt(t),{secret:r,crypto:o,base32:n,algorithm:s,digits:i,hooks:a}=e,c={secret:r,crypto:o,base32:n,algorithm:s,digits:i,hooks:a};return Je(e.strategy,e.counter,{totp:()=>je({...c,period:e.period,epoch:e.epoch,t0:e.t0,guardrails:e.guardrails}),hotp:u=>W({...c,counter:u,guardrails:e.guardrails})})}function Et(t){let e=mt(t),{secret:r,crypto:o,base32:n,algorithm:s,digits:i}=e,a={secret:r,crypto:o,base32:n,algorithm:s,digits:i};return Je(e.strategy,e.counter,{totp:()=>Vt({...a,period:e.period,epoch:e.epoch,t0:e.t0,guardrails:e.guardrails}),hotp:c=>Ne({...a,counter:c,guardrails:e.guardrails})})}async function wt(t){let e=er(t),{secret:r,token:o,crypto:n,base32:s,algorithm:i,digits:a,hooks:c}=e,u={secret:r,token:o,crypto:n,base32:s,algorithm:i,digits:a,hooks:c};return Je(e.strategy,e.counter,{totp:()=>ct({...u,period:e.period,epoch:e.epoch,t0:e.t0,epochTolerance:e.epochTolerance,afterTimeStep:e.afterTimeStep,guardrails:e.guardrails}),hotp:f=>at({...u,counter:f,counterTolerance:e.counterTolerance,guardrails:e.guardrails})})}function Pt(t){let e=er(t),{secret:r,token:o,crypto:n,base32:s,algorithm:i,digits:a,hooks:c}=e,u={secret:r,token:o,crypto:n,base32:s,algorithm:i,digits:a,hooks:c};return Je(e.strategy,e.counter,{totp:()=>Tr({...u,period:e.period,epoch:e.epoch,t0:e.t0,epochTolerance:e.epochTolerance,afterTimeStep:e.afterTimeStep,guardrails:e.guardrails}),hotp:f=>xr({...u,counter:f,counterTolerance:e.counterTolerance,guardrails:e.guardrails})})}var At=class{strategy;crypto;base32;guardrails;constructor(e={}){let{strategy:r="totp",crypto:o=re,base32:n=ee,guardrails:s}=e;this.strategy=r,this.crypto=o,this.base32=n,this.guardrails=b(s)}getStrategy(){return this.strategy}generateSecret(e=20){return I({crypto:this.crypto,base32:this.base32,length:e})}async generate(e){return Ot({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}generateSync(e){return Et({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}async verify(e){return wt({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}verifySync(e){return Pt({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}generateURI(e){return Tt({...e,strategy:this.strategy})}};return Wr(un);})();
|
|
2
|
+
/*! Bundled license information:
|
|
3
|
+
|
|
4
|
+
@scure/base/index.js:
|
|
5
|
+
(*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
6
|
+
*/
|
|
7
|
+
//# sourceMappingURL=index.global.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../../core/src/errors.ts","../../core/src/utils.ts","../../core/src/crypto-context.ts","../../uri/src/generate.ts","../../hotp/src/class.ts","../../hotp/src/index.ts","../../totp/src/class.ts","../../totp/src/index.ts","../../../node_modules/.pnpm/@scure+base@2.2.0/node_modules/@scure/base/index.ts","../../plugin-base32-scure/src/index.ts","../../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/src/utils.ts","../../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/src/hmac.ts","../../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/src/_md.ts","../../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/src/legacy.ts","../../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/src/_u64.ts","../../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/src/sha2.ts","../../plugin-crypto-noble/src/index.ts","../src/defaults.ts","../src/functional.ts","../src/class.ts"],"sourcesContent":["export type {\n OTPAuthOptions,\n TOTPOptions,\n OTPGenerateOptions as OTPFunctionalOptions,\n OTPVerifyOptions as OTPVerifyFunctionalOptions,\n} from \"./types.js\";\n\nexport {\n generateSecret,\n generateURI,\n generate,\n generateSync,\n verify,\n verifySync,\n type OTPStrategy,\n} from \"./functional.js\";\n\nexport {\n OTP,\n type OTPClassOptions,\n type OTPGenerateOptions,\n type OTPVerifyOptions,\n type OTPURIGenerateOptions,\n} from \"./class.js\";\n\nexport type {\n Base32Plugin,\n CryptoPlugin,\n HashAlgorithm,\n OTPResult,\n OTPGuardrails,\n OTPGuardrailsConfig,\n} from \"@otplib/core\";\nexport type { VerifyResult } from \"@otplib/totp\";\n\nexport { HOTP } from \"@otplib/hotp\";\nexport { TOTP } from \"@otplib/totp\";\n\nexport { createGuardrails, stringToBytes, wrapResult, wrapResultAsync } from \"@otplib/core\";\n\n// Default Plugins\nexport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nexport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\n","/**\n * Options for OTPError construction\n */\nexport type OTPErrorOptions = {\n /**\n * The underlying error that caused this error.\n * Useful for error chaining and debugging.\n */\n cause?: unknown;\n};\n\n/**\n * Base error class for all otplib errors\n *\n * Supports ES2022 error chaining via the `cause` property.\n *\n * @example\n * ```typescript\n * try {\n * // ... operation that throws\n * } catch (error) {\n * throw new OTPError('Operation failed', { cause: error });\n * }\n * ```\n */\nexport class OTPError extends Error {\n constructor(message: string, options?: OTPErrorOptions) {\n super(message, options);\n this.name = \"OTPError\";\n }\n}\n\n/**\n * Error thrown when secret validation fails\n */\nexport class SecretError extends OTPError {\n constructor(message: string) {\n super(message);\n this.name = \"SecretError\";\n }\n}\n\n/**\n * Error thrown when secret is too short (< 128 bits)\n */\nexport class SecretTooShortError extends SecretError {\n constructor(minBytes: number, actualBytes: number) {\n super(\n `Secret must be at least ${minBytes} bytes (${minBytes * 8} bits), got ${actualBytes} bytes`,\n );\n this.name = \"SecretTooShortError\";\n }\n}\n\n/**\n * Error thrown when secret is unreasonably large (> 64 bytes)\n */\nexport class SecretTooLongError extends SecretError {\n constructor(maxBytes: number, actualBytes: number) {\n super(`Secret must not exceed ${maxBytes} bytes, got ${actualBytes} bytes`);\n this.name = \"SecretTooLongError\";\n }\n}\n\n/**\n * Error thrown when counter is invalid\n */\nexport class CounterError extends OTPError {\n constructor(message: string) {\n super(message);\n this.name = \"CounterError\";\n }\n}\n\n/**\n * Error thrown when counter is negative\n */\nexport class CounterNegativeError extends CounterError {\n constructor() {\n super(\"Counter must be non-negative\");\n this.name = \"CounterNegativeError\";\n }\n}\n\n/**\n * Error thrown when counter exceeds maximum value (2^53 - 1 for safe integer)\n */\nexport class CounterOverflowError extends CounterError {\n constructor() {\n super(\"Counter exceeds maximum safe integer value\");\n this.name = \"CounterOverflowError\";\n }\n}\n\n/**\n * Error thrown when counter is not an integer\n */\nexport class CounterNotIntegerError extends CounterError {\n constructor() {\n super(\"Counter must be a finite integer\");\n this.name = \"CounterNotIntegerError\";\n }\n}\n\n/**\n * Error thrown when time is invalid\n */\nexport class TimeError extends OTPError {\n constructor(message: string) {\n super(message);\n this.name = \"TimeError\";\n }\n}\n\n/**\n * Error thrown when time is negative\n */\nexport class TimeNegativeError extends TimeError {\n constructor() {\n super(\"Time must be non-negative\");\n this.name = \"TimeNegativeError\";\n }\n}\n\n/**\n * Error thrown when time is not a finite number\n */\nexport class TimeNotFiniteError extends TimeError {\n constructor() {\n super(\"Time must be a finite number\");\n this.name = \"TimeNotFiniteError\";\n }\n}\n\n/**\n * Error thrown when period is invalid\n */\nexport class PeriodError extends OTPError {\n constructor(message: string) {\n super(message);\n this.name = \"PeriodError\";\n }\n}\n\n/**\n * Error thrown when period is too small\n */\nexport class PeriodTooSmallError extends PeriodError {\n constructor(minPeriod: number) {\n super(`Period must be at least ${minPeriod} second(s)`);\n this.name = \"PeriodTooSmallError\";\n }\n}\n\n/**\n * Error thrown when period is too large\n */\nexport class PeriodTooLargeError extends PeriodError {\n constructor(maxPeriod: number) {\n super(`Period must not exceed ${maxPeriod} seconds`);\n this.name = \"PeriodTooLargeError\";\n }\n}\n\n/**\n * Error thrown when digits value is invalid\n */\nexport class DigitsError extends OTPError {\n constructor(message: string) {\n super(message);\n this.name = \"DigitsError\";\n }\n}\n\n/**\n * Error thrown when hash algorithm is invalid\n */\nexport class AlgorithmError extends OTPError {\n constructor(message: string) {\n super(message);\n this.name = \"AlgorithmError\";\n }\n}\n\n/**\n * Error thrown when token is invalid\n */\nexport class TokenError extends OTPError {\n constructor(message: string) {\n super(message);\n this.name = \"TokenError\";\n }\n}\n\n/**\n * Error thrown when token has incorrect length\n */\nexport class TokenLengthError extends TokenError {\n constructor(expected: number, actual: number) {\n super(`Token must be ${expected} digits, got ${actual}`);\n this.name = \"TokenLengthError\";\n }\n}\n\n/**\n * Error thrown when token contains non-digit characters\n */\nexport class TokenFormatError extends TokenError {\n constructor() {\n super(\"Token must contain only digits\");\n this.name = \"TokenFormatError\";\n }\n}\n\n/**\n * Error thrown when crypto operation fails\n */\nexport class CryptoError extends OTPError {\n constructor(message: string, options?: OTPErrorOptions) {\n super(message, options);\n this.name = \"CryptoError\";\n }\n}\n\n/**\n * Error thrown when HMAC computation fails\n *\n * The original error from the crypto plugin is available via `cause`.\n *\n * @example\n * ```typescript\n * try {\n * await cryptoContext.hmac('sha1', key, data);\n * } catch (error) {\n * if (error instanceof HMACError) {\n * console.log('HMAC failed:', error.message);\n * console.log('Original error:', error.cause);\n * }\n * }\n * ```\n */\nexport class HMACError extends CryptoError {\n constructor(message: string, options?: OTPErrorOptions) {\n super(`HMAC computation failed: ${message}`, options);\n this.name = \"HMACError\";\n }\n}\n\n/**\n * Error thrown when random byte generation fails\n *\n * The original error from the crypto plugin is available via `cause`.\n */\nexport class RandomBytesError extends CryptoError {\n constructor(message: string, options?: OTPErrorOptions) {\n super(`Random byte generation failed: ${message}`, options);\n this.name = \"RandomBytesError\";\n }\n}\n\n/**\n * Error thrown when Base32 operation fails\n */\nexport class Base32Error extends OTPError {\n constructor(message: string, options?: OTPErrorOptions) {\n super(message, options);\n this.name = \"Base32Error\";\n }\n}\n\n/**\n * Error thrown when Base32 encoding fails\n *\n * The original error from the Base32 plugin is available via `cause`.\n *\n * @example\n * ```typescript\n * try {\n * base32Context.encode(data);\n * } catch (error) {\n * if (error instanceof Base32EncodeError) {\n * console.log('Encoding failed:', error.message);\n * console.log('Original error:', error.cause);\n * }\n * }\n * ```\n */\nexport class Base32EncodeError extends Base32Error {\n constructor(message: string, options?: OTPErrorOptions) {\n super(`Base32 encoding failed: ${message}`, options);\n this.name = \"Base32EncodeError\";\n }\n}\n\n/**\n * Error thrown when Base32 decoding fails\n *\n * The original error from the Base32 plugin is available via `cause`.\n *\n * @example\n * ```typescript\n * try {\n * base32Context.decode(invalidString);\n * } catch (error) {\n * if (error instanceof Base32DecodeError) {\n * console.log('Decoding failed:', error.message);\n * console.log('Original error:', error.cause);\n * }\n * }\n * ```\n */\nexport class Base32DecodeError extends Base32Error {\n constructor(message: string, options?: OTPErrorOptions) {\n super(`Base32 decoding failed: ${message}`, options);\n this.name = \"Base32DecodeError\";\n }\n}\n\n/**\n * Error thrown when counter tolerance is invalid\n */\nexport class CounterToleranceError extends OTPError {\n constructor(message: string) {\n super(message);\n this.name = \"CounterToleranceError\";\n }\n}\n\n/**\n * Error thrown when counter tolerance is too large\n */\nexport class CounterToleranceTooLargeError extends CounterToleranceError {\n constructor(maxWindow: number, totalChecks: number) {\n super(\n `Counter tolerance validation failed: total checks (${totalChecks}) exceeds MAX_WINDOW (${maxWindow})`,\n );\n this.name = \"CounterToleranceTooLargeError\";\n }\n}\n\n/**\n * Error thrown when counter tolerance contains negative values\n */\nexport class CounterToleranceNegativeError extends CounterToleranceError {\n constructor() {\n super(\"Counter tolerance cannot contain negative values\");\n this.name = \"CounterToleranceNegativeError\";\n }\n}\n\n/**\n * Error thrown when epoch tolerance is invalid\n */\nexport class EpochToleranceError extends OTPError {\n constructor(message: string) {\n super(message);\n this.name = \"EpochToleranceError\";\n }\n}\n\n/**\n * Error thrown when epoch tolerance contains negative values\n */\nexport class EpochToleranceNegativeError extends EpochToleranceError {\n constructor() {\n super(\"Epoch tolerance cannot contain negative values\");\n this.name = \"EpochToleranceNegativeError\";\n }\n}\n\n/**\n * Error thrown when epoch tolerance is too large\n */\nexport class EpochToleranceTooLargeError extends EpochToleranceError {\n constructor(maxTolerance: number, actualValue: number) {\n super(\n `Epoch tolerance must not exceed ${maxTolerance} seconds, got ${actualValue}. ` +\n `Large tolerances can cause performance issues.`,\n );\n this.name = \"EpochToleranceTooLargeError\";\n }\n}\n\n/**\n * Error thrown when a required plugin is missing\n */\nexport class PluginError extends OTPError {\n constructor(message: string) {\n super(message);\n this.name = \"PluginError\";\n }\n}\n\n/**\n * Error thrown when crypto plugin is not configured\n */\nexport class CryptoPluginMissingError extends PluginError {\n constructor() {\n super(\"Crypto plugin is required.\");\n this.name = \"CryptoPluginMissingError\";\n }\n}\n\n/**\n * Error thrown when Base32 plugin is not configured\n */\nexport class Base32PluginMissingError extends PluginError {\n constructor() {\n super(\"Base32 plugin is required.\");\n this.name = \"Base32PluginMissingError\";\n }\n}\n\n/**\n * Error thrown when required configuration is missing\n */\nexport class ConfigurationError extends OTPError {\n constructor(message: string) {\n super(message);\n this.name = \"ConfigurationError\";\n }\n}\n\n/**\n * Error thrown when secret is not configured\n */\nexport class SecretMissingError extends ConfigurationError {\n constructor() {\n super(\n \"Secret is required. \" +\n \"Use generateSecret() to create one, or provide via { secret: 'YOUR_BASE32_SECRET' }\",\n );\n this.name = \"SecretMissingError\";\n }\n}\n\n/**\n * Error thrown when label is not configured (required for URI generation)\n */\nexport class LabelMissingError extends ConfigurationError {\n constructor() {\n super(\"Label is required for URI generation. Example: { label: 'user@example.com' }\");\n this.name = \"LabelMissingError\";\n }\n}\n\n/**\n * Error thrown when issuer is not configured (required for URI generation)\n */\nexport class IssuerMissingError extends ConfigurationError {\n constructor() {\n super(\"Issuer is required for URI generation. Example: { issuer: 'MyApp' }\");\n this.name = \"IssuerMissingError\";\n }\n}\n\n/**\n * Error thrown when secret must be a Base32 string but is provided as bytes\n */\nexport class SecretTypeError extends ConfigurationError {\n constructor() {\n super(\n \"Class API requires secret to be a Base32 string, not Uint8Array. \" +\n \"Use generateSecret() or provide a Base32-encoded string.\",\n );\n this.name = \"SecretTypeError\";\n }\n}\n\n/**\n * Error thrown when afterTimeStep parameter is invalid\n */\nexport class AfterTimeStepError extends OTPError {\n constructor(message: string) {\n super(message);\n this.name = \"AfterTimeStepError\";\n }\n}\n\n/**\n * Error thrown when afterTimeStep is negative\n */\nexport class AfterTimeStepNegativeError extends AfterTimeStepError {\n constructor() {\n super(\"afterTimeStep must be >= 0\");\n this.name = \"AfterTimeStepNegativeError\";\n }\n}\n\n/**\n * Error thrown when afterTimeStep is not an integer\n */\nexport class AfterTimeStepNotIntegerError extends AfterTimeStepError {\n constructor() {\n super(\"Invalid afterTimeStep: non-integer value\");\n this.name = \"AfterTimeStepNotIntegerError\";\n }\n}\n\n/**\n * Error thrown when afterTimeStep exceeds the verification range\n */\nexport class AfterTimeStepRangeExceededError extends AfterTimeStepError {\n constructor() {\n super(\"Invalid afterTimeStep: cannot be greater than current time step plus window\");\n this.name = \"AfterTimeStepRangeExceededError\";\n }\n}\n","import {\n OTPError,\n SecretTooShortError,\n SecretTooLongError,\n CounterNegativeError,\n CounterOverflowError,\n CounterNotIntegerError,\n TimeNegativeError,\n TimeNotFiniteError,\n PeriodTooSmallError,\n PeriodTooLargeError,\n TokenLengthError,\n TokenFormatError,\n CounterToleranceError,\n CounterToleranceTooLargeError,\n CounterToleranceNegativeError,\n EpochToleranceError,\n EpochToleranceNegativeError,\n EpochToleranceTooLargeError,\n CryptoPluginMissingError,\n Base32PluginMissingError,\n ConfigurationError,\n SecretMissingError,\n LabelMissingError,\n IssuerMissingError,\n SecretTypeError,\n} from \"./errors.js\";\n\nimport type {\n HashAlgorithm,\n SecretOptions,\n OTPResultOk,\n OTPResultError,\n OTPResult,\n} from \"./types.js\";\n\n/**\n * Singleton TextEncoder instance to avoid repeated allocations\n */\nconst textEncoder = new TextEncoder();\n\n/**\n * Singleton TextDecoder instance to avoid repeated allocations\n */\nconst textDecoder = new TextDecoder();\n\n/**\n * Minimum secret length in bytes (128 bits as per RFC 4226)\n */\nexport const MIN_SECRET_BYTES = 16;\n\n/**\n * Maximum secret length in bytes (512 bits)\n *\n * The 64-byte maximum is not part of the RFCs.\n * This is to prevent excessive memory usage in HMAC operations.\n */\nexport const MAX_SECRET_BYTES = 64;\n\n/**\n * Recommended secret length in bytes (160 bits as per RFC 4226)\n */\nexport const RECOMMENDED_SECRET_BYTES = 20;\n\n/**\n * Minimum period in seconds\n */\nexport const MIN_PERIOD = 1;\n\n/**\n * Maximum period in seconds (1 hour)\n */\nexport const MAX_PERIOD = 3600;\n\n/**\n * Default period in seconds (30 seconds as per RFC 6238)\n */\nexport const DEFAULT_PERIOD = 30;\n\n/**\n * Maximum safe integer for counter (2^53 - 1)\n */\nexport const MAX_COUNTER = Number.MAX_SAFE_INTEGER;\n\n/**\n * Maximum verification window size\n *\n * Limits the number of HMAC computations during verification to prevent DoS attacks.\n * A window of 99 means up to 99 HMAC computations (total checks including current counter).\n * Odd number to cater for equal distribution of time drift + current.\n *\n * For TOTP: window=1 is typically sufficient (allows +-30 seconds clock drift)\n * For HOTP: window=10-50 handles reasonable counter desynchronization\n */\nexport const MAX_WINDOW = 99;\n\n/**\n * Configurable guardrails for OTP validation\n *\n * Allows overriding default safety limits for non-standard production requirements.\n * Use with caution - custom guardrails can weaken security.\n */\nexport type OTPGuardrailsConfig = {\n MIN_SECRET_BYTES: number;\n MAX_SECRET_BYTES: number;\n MIN_PERIOD: number;\n MAX_PERIOD: number;\n MAX_COUNTER: number;\n MAX_WINDOW: number;\n};\n\n/**\n * Module-private symbol to track guardrail override status\n *\n * This symbol is used as a property key to store whether guardrails contain custom values.\n * Being module-private and a symbol ensures:\n * - Cannot be accessed outside this module (not exported)\n * - Cannot be recreated (each Symbol() call is unique)\n * - Hidden from normal enumeration (Object.keys, JSON.stringify, for-in)\n * - Minimal memory overhead (~1 byte per object)\n * - No garbage collection concerns\n *\n * @internal\n */\nconst OVERRIDE_SYMBOL = Symbol(\"otplib.guardrails.override\");\n\n/**\n * Complete guardrails configuration\n *\n * This represents the final, immutable configuration used by validation functions.\n * Internally tracks whether any values were overridden from RFC recommendations,\n * enabling security auditing and compliance monitoring without exposing implementation\n * details in the public API.\n *\n * The override status is stored using a module-private Symbol that cannot be accessed\n * or recreated outside this module, providing true encapsulation.\n *\n * @see {@link OTPGuardrailsConfig} for the base configuration structure\n * @see {@link createGuardrails} for creating guardrails instances\n * @see {@link hasGuardrailOverrides} to check if guardrails were customized\n */\nexport type OTPGuardrails = Readonly<OTPGuardrailsConfig> & {\n [OVERRIDE_SYMBOL]?: boolean;\n};\n\n/**\n * Validate guardrail numeric field\n */\nfunction assertGuardrailSafeInteger(\n name: string,\n value: unknown,\n min: number,\n): asserts value is number {\n if (typeof value !== \"number\" || !Number.isSafeInteger(value)) {\n throw new ConfigurationError(`Guardrail '${name}' must be a safe integer`);\n }\n if (value < min) {\n throw new ConfigurationError(`Guardrail '${name}' must be >= ${min}`);\n }\n}\n\n/**\n * Default guardrails matching RFC recommendations\n *\n * Frozen to ensure immutability. Used as default parameter for validation functions.\n * For custom guardrails, use the createGuardrails() factory function.\n */\nconst DEFAULT_GUARDRAILS: OTPGuardrails = Object.freeze({\n MIN_SECRET_BYTES,\n MAX_SECRET_BYTES,\n MIN_PERIOD,\n MAX_PERIOD,\n MAX_COUNTER,\n MAX_WINDOW,\n [OVERRIDE_SYMBOL]: false,\n});\n\n/**\n * Create guardrails configuration object\n *\n * Factory function that merges custom guardrails with defaults and returns\n * an immutable (frozen) object. Validates custom guardrails to ensure they\n * maintain basic safety invariants.\n *\n * When called without arguments or with `undefined`, returns the default guardrails\n * singleton (optimized to avoid unnecessary allocations). When called with custom\n * values, creates a new frozen object and internally marks it as overridden.\n *\n * @param custom - Optional partial guardrails to override defaults\n * @returns Frozen guardrails object\n * @throws {ConfigurationError} If custom guardrails violate safety invariants\n *\n * @example Basic usage\n * ```ts\n * import { createGuardrails, hasGuardrailOverrides } from '@otplib/core'\n *\n * // Returns default singleton (no overrides)\n * const defaults = createGuardrails();\n * hasGuardrailOverrides(defaults); // false\n *\n * // Creates new object with overrides\n * const custom = createGuardrails({\n * MIN_SECRET_BYTES: 8,\n * MAX_WINDOW: 200\n * });\n * hasGuardrailOverrides(custom); // true\n * ```\n *\n * @example Monitoring custom guardrails\n * ```ts\n * import { createGuardrails, hasGuardrailOverrides } from '@otplib/core';\n *\n * const guardrails = createGuardrails({ MAX_WINDOW: 20 });\n *\n * if (hasGuardrailOverrides(guardrails)) {\n * logger.warn('Non-default guardrails in use', { guardrails });\n * }\n * ```\n *\n * @see {@link hasGuardrailOverrides} to check if guardrails were customized\n */\nexport function createGuardrails(custom?: Partial<OTPGuardrailsConfig>): OTPGuardrails {\n if (!custom) {\n return DEFAULT_GUARDRAILS;\n }\n\n if (custom.MIN_SECRET_BYTES !== undefined) {\n assertGuardrailSafeInteger(\"MIN_SECRET_BYTES\", custom.MIN_SECRET_BYTES, 1);\n }\n\n if (custom.MAX_SECRET_BYTES !== undefined) {\n assertGuardrailSafeInteger(\"MAX_SECRET_BYTES\", custom.MAX_SECRET_BYTES, 1);\n }\n\n if (custom.MIN_PERIOD !== undefined) {\n assertGuardrailSafeInteger(\"MIN_PERIOD\", custom.MIN_PERIOD, 1);\n }\n\n if (custom.MAX_PERIOD !== undefined) {\n assertGuardrailSafeInteger(\"MAX_PERIOD\", custom.MAX_PERIOD, 1);\n }\n\n if (custom.MAX_COUNTER !== undefined) {\n assertGuardrailSafeInteger(\"MAX_COUNTER\", custom.MAX_COUNTER, 0);\n }\n\n if (custom.MAX_WINDOW !== undefined) {\n assertGuardrailSafeInteger(\"MAX_WINDOW\", custom.MAX_WINDOW, 1);\n }\n\n const merged = {\n ...DEFAULT_GUARDRAILS,\n ...custom,\n };\n\n if (merged.MIN_SECRET_BYTES > merged.MAX_SECRET_BYTES) {\n throw new ConfigurationError(\"Guardrail 'MIN_SECRET_BYTES' must be <= 'MAX_SECRET_BYTES'\");\n }\n\n if (merged.MIN_PERIOD > merged.MAX_PERIOD) {\n throw new ConfigurationError(\"Guardrail 'MIN_PERIOD' must be <= 'MAX_PERIOD'\");\n }\n\n return Object.freeze({\n ...merged,\n [OVERRIDE_SYMBOL]: true,\n });\n}\n\n/**\n * Check if guardrails contain custom overrides\n *\n * Returns `true` if the guardrails object was created with custom values,\n * `false` if using RFC-recommended defaults. Useful for security auditing,\n * compliance monitoring, and development warnings.\n *\n * This function accesses a module-private Symbol property that cannot be\n * accessed or modified outside this module, ensuring reliable detection.\n *\n * @param guardrails - The guardrails object to check\n * @returns `true` if guardrails were customized, `false` if using defaults\n *\n * @example Security monitoring\n * ```ts\n * import { createGuardrails, hasGuardrailOverrides } from '@otplib/core';\n *\n * const guardrails = createGuardrails({ MAX_WINDOW: 20 });\n *\n * if (hasGuardrailOverrides(guardrails)) {\n * console.warn('Custom guardrails detected:', guardrails);\n * // Log to security audit system\n * }\n * ```\n *\n * @example Compliance check\n * ```ts\n * function validateGuardrails(guardrails: OTPGuardrails) {\n * if (hasGuardrailOverrides(guardrails)) {\n * throw new Error('Custom guardrails not allowed in production');\n * }\n * }\n * ```\n */\nexport function hasGuardrailOverrides(guardrails: OTPGuardrails): boolean {\n return guardrails[OVERRIDE_SYMBOL] ?? false;\n}\n\n/**\n * Validate secret key\n *\n * @param secret - The secret to validate\n * @param guardrails - Validation guardrails (defaults to RFC recommendations)\n * @throws {SecretTooShortError} If secret is too short\n * @throws {SecretTooLongError} If secret is too long\n */\nexport function validateSecret(\n secret: Uint8Array,\n guardrails: OTPGuardrails = DEFAULT_GUARDRAILS,\n): void {\n if (secret.length < guardrails.MIN_SECRET_BYTES) {\n throw new SecretTooShortError(guardrails.MIN_SECRET_BYTES, secret.length);\n }\n\n if (secret.length > guardrails.MAX_SECRET_BYTES) {\n throw new SecretTooLongError(guardrails.MAX_SECRET_BYTES, secret.length);\n }\n}\n\n/**\n * Validate counter value\n *\n * @param counter - The counter to validate\n * @param guardrails - Validation guardrails (defaults to RFC recommendations)\n * @throws {CounterNegativeError} If counter is negative\n * @throws {CounterOverflowError} If counter exceeds safe integer\n */\nexport function validateCounter(\n counter: number | bigint,\n guardrails: OTPGuardrails = DEFAULT_GUARDRAILS,\n): void {\n if (typeof counter === \"number\") {\n if (!Number.isFinite(counter) || !Number.isInteger(counter)) {\n throw new CounterNotIntegerError();\n }\n\n if (!Number.isSafeInteger(counter)) {\n // Numbers outside the safe integer range cannot be reliably converted to bigint\n throw new CounterOverflowError();\n }\n }\n\n const value = typeof counter === \"bigint\" ? counter : BigInt(counter);\n\n if (value < 0n) {\n throw new CounterNegativeError();\n }\n\n if (value > BigInt(guardrails.MAX_COUNTER)) {\n throw new CounterOverflowError();\n }\n}\n\n/**\n * Validate time value\n *\n * @param time - The time in seconds to validate\n * @throws {TimeNegativeError} If time is negative\n */\nexport function validateTime(time: number): void {\n if (!Number.isFinite(time)) {\n throw new TimeNotFiniteError();\n }\n\n if (time < 0) {\n throw new TimeNegativeError();\n }\n}\n\n/**\n * Validate period value\n *\n * @param period - The period in seconds to validate\n * @param guardrails - Validation guardrails (defaults to RFC recommendations)\n * @throws {PeriodTooSmallError} If period is too small\n * @throws {PeriodTooLargeError} If period is too large\n */\nexport function validatePeriod(\n period: number,\n guardrails: OTPGuardrails = DEFAULT_GUARDRAILS,\n): void {\n if (!Number.isInteger(period) || period < guardrails.MIN_PERIOD) {\n throw new PeriodTooSmallError(guardrails.MIN_PERIOD);\n }\n\n if (period > guardrails.MAX_PERIOD) {\n throw new PeriodTooLargeError(guardrails.MAX_PERIOD);\n }\n}\n\n/**\n * Validate token\n *\n * @param token - The token string to validate\n * @param digits - Expected number of digits\n * @throws {TokenLengthError} If token has incorrect length\n * @throws {TokenFormatError} If token contains non-digit characters\n */\nexport function validateToken(token: string, digits: number): void {\n if (token.length !== digits) {\n throw new TokenLengthError(digits, token.length);\n }\n\n if (!/^\\d+$/.test(token)) {\n throw new TokenFormatError();\n }\n}\n\n/**\n * Validate counter tolerance for HOTP verification\n *\n * Prevents DoS attacks by limiting the number of counter values checked.\n *\n * @param counterTolerance - Counter tolerance specification (number or array of offsets)\n * @param guardrails - Validation guardrails (defaults to RFC recommendations)\n * @throws {CounterToleranceTooLargeError} If tolerance size exceeds MAX_WINDOW\n *\n * @example\n * ```ts\n * validateCounterTolerance(1); // OK: [0, 1] = 2 checks\n * validateCounterTolerance(98); // OK: [0, 98] = 99 checks\n * validateCounterTolerance(99); // Throws: exceeds MAX_WINDOW\n * validateCounterTolerance([0, 1]); // OK: 2 offsets\n * ```\n */\nexport function validateCounterTolerance(\n counterTolerance: number | [number, number],\n guardrails: OTPGuardrails = DEFAULT_GUARDRAILS,\n): void {\n const [past, future] = normalizeCounterTolerance(counterTolerance);\n\n if (!Number.isSafeInteger(past) || !Number.isSafeInteger(future)) {\n throw new CounterToleranceError(\"Counter tolerance values must be safe integers\");\n }\n\n if (past < 0 || future < 0) {\n throw new CounterToleranceNegativeError();\n }\n\n const totalChecks = past + future + 1;\n\n if (totalChecks > guardrails.MAX_WINDOW) {\n throw new CounterToleranceTooLargeError(guardrails.MAX_WINDOW, totalChecks);\n }\n}\n\n/**\n * Validate epoch tolerance for TOTP verification\n *\n * Prevents DoS attacks by limiting the time range checked.\n * Also validates that tolerance values are non-negative.\n *\n * @param epochTolerance - Epoch tolerance specification (number or tuple [past, future])\n * @param period - The TOTP period in seconds (default: 30). Used to calculate max tolerance.\n * @param guardrails - Validation guardrails (defaults to RFC recommendations)\n * @throws {EpochToleranceNegativeError} If tolerance contains negative values\n * @throws {EpochToleranceTooLargeError} If tolerance exceeds MAX_WINDOW periods\n *\n * @example\n * ```ts\n * validateEpochTolerance(30); // OK: 30 seconds symmetric\n * validateEpochTolerance([5, 0]); // OK: 5 seconds past only\n * validateEpochTolerance([-5, 0]); // Throws: negative values not allowed\n * validateEpochTolerance(1471); // Throws with default guardrails (30s period)\n * validateEpochTolerance(2940, 60); // OK with 60s period\n * ```\n */\nexport function validateEpochTolerance(\n epochTolerance: number | [number, number],\n period: number = DEFAULT_PERIOD,\n guardrails: OTPGuardrails = DEFAULT_GUARDRAILS,\n): void {\n const [pastTolerance, futureTolerance] = Array.isArray(epochTolerance)\n ? epochTolerance\n : [epochTolerance, epochTolerance];\n\n if (!Number.isSafeInteger(pastTolerance) || !Number.isSafeInteger(futureTolerance)) {\n throw new EpochToleranceError(\"Epoch tolerance values must be safe integers\");\n }\n\n // Check for negative values\n if (pastTolerance < 0 || futureTolerance < 0) {\n throw new EpochToleranceNegativeError();\n }\n\n // MAX_WINDOW checks means at most MAX_WINDOW - 1 periods of tolerance\n // (the current time step always consumes one check).\n const maxToleranceSeconds = (guardrails.MAX_WINDOW - 1) * period;\n const totalToleranceSeconds = pastTolerance + futureTolerance;\n\n if (totalToleranceSeconds > maxToleranceSeconds) {\n throw new EpochToleranceTooLargeError(maxToleranceSeconds, totalToleranceSeconds);\n }\n}\n\n/**\n * Convert counter to 8-byte big-endian array\n *\n * Per RFC 4226 Section 5.1, the counter value is represented as an 8-byte\n * big-endian (network byte order) unsigned integer.\n *\n * @see {@link https://tools.ietf.org/html/rfc4226#section-5.1 | RFC 4226 Section 5.1 - Symbol Descriptions}\n *\n * @param value - The counter value to convert\n * @returns 8-byte big-endian array\n */\nexport function counterToBytes(value: number | bigint): Uint8Array {\n const bigintValue = typeof value === \"bigint\" ? value : BigInt(value);\n const buffer = new ArrayBuffer(8);\n const view = new DataView(buffer);\n\n view.setBigUint64(0, bigintValue, false);\n\n return new Uint8Array(buffer);\n}\n\n/**\n * Perform Dynamic Truncation as per RFC 4226 Section 5.3\n *\n * The algorithm:\n * 1. Take the low-order 4 bits of the last byte as offset\n * 2. Extract 4 bytes starting at offset\n * 3. Mask the most significant bit to get a 31-bit unsigned integer\n *\n * This ensures consistent extraction across different HMAC output sizes\n * while producing a value that fits in a signed 32-bit integer.\n *\n * @see {@link https://tools.ietf.org/html/rfc4226#section-5.3 | RFC 4226 Section 5.3 - Generating an HOTP Value}\n *\n * @param hmacResult - HMAC result (at least 20 bytes for SHA-1)\n * @returns Truncated 31-bit unsigned integer\n */\nexport function dynamicTruncate(hmacResult: Uint8Array): number {\n const offset = hmacResult[hmacResult.length - 1] & 0x0f;\n\n const binary =\n ((hmacResult[offset] & 0x7f) << 24) |\n (hmacResult[offset + 1] << 16) |\n (hmacResult[offset + 2] << 8) |\n hmacResult[offset + 3];\n\n return binary;\n}\n\n/**\n * Convert truncated integer to OTP string with specified digits\n *\n * Computes: Snum mod 10^Digit (RFC 4226 Section 5.3)\n *\n * The result is zero-padded to ensure consistent length,\n * as required for proper token comparison.\n *\n * @see {@link https://tools.ietf.org/html/rfc4226#section-5.3 | RFC 4226 Section 5.3 - Generating an HOTP Value}\n *\n * @param value - The truncated integer value (Snum)\n * @param digits - Number of digits for the OTP (Digit, typically 6-8)\n * @returns OTP string with leading zeros if necessary\n */\nexport function truncateDigits(value: number, digits: number): string {\n const maxOtp = 10 ** digits;\n const otp = value % maxOtp;\n return otp.toString().padStart(digits, \"0\");\n}\n\n/**\n * Validate that two byte arrays have equal length\n *\n * Useful as a preliminary check before performing byte-by-byte comparisons.\n *\n * @param a - First byte array\n * @param b - Second byte array\n * @returns true if arrays have equal length, false otherwise\n */\nexport function validateByteLengthEqual(a: Uint8Array, b: Uint8Array): boolean {\n return a.length === b.length;\n}\n\n/**\n * Constant-time comparison to prevent timing attacks\n *\n * This implements a timing-safe equality check as recommended in\n * RFC 4226 Section 7.2 for token validation to prevent\n * timing side-channel attacks.\n *\n * @see {@link https://tools.ietf.org/html/rfc4226#section-7.2 | RFC 4226 Section 7.2 - Validation and Verification}\n *\n * @param a - First value to compare\n * @param b - Second value to compare\n * @returns true if values are equal, false otherwise\n */\nexport function constantTimeEqual(a: string | Uint8Array, b: string | Uint8Array): boolean {\n const bufA = stringToBytes(a);\n const bufB = stringToBytes(b);\n\n if (!validateByteLengthEqual(bufA, bufB)) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < bufA.length; i++) {\n result |= bufA[i] ^ bufB[i];\n }\n\n return result === 0;\n}\n\n/**\n * Get HMAC digest size in bytes for a given algorithm\n *\n * @param algorithm - The hash algorithm\n * @returns Digest size in bytes\n */\nexport function getDigestSize(algorithm: HashAlgorithm): number {\n switch (algorithm) {\n case \"sha1\":\n return 20;\n case \"sha256\":\n return 32;\n case \"sha512\":\n return 64;\n }\n}\n\n/**\n * Convert a string or Uint8Array to Uint8Array\n *\n * This utility function normalizes input to Uint8Array, converting strings\n * using UTF-8 encoding. Uint8Array inputs are returned as-is.\n *\n * Use this to convert raw secret strings (passphrases) to Uint8Array\n * before passing them to generation or verification functions.\n *\n * @param value - The value to convert (string or Uint8Array)\n * @returns The value as a Uint8Array (UTF-8 encoded for strings)\n *\n * @example\n * ```ts\n * import { stringToBytes } from '@otplib/core'\n *\n * const bytes1 = stringToBytes('1234567890123456')\n * // Returns: Uint8Array([49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53, 54])\n *\n * const bytes2 = stringToBytes(new Uint8Array([1, 2, 3]))\n * // Returns: Uint8Array([1, 2, 3]) - returned as-is\n * ```\n */\nexport function stringToBytes(value: string | Uint8Array): Uint8Array {\n return typeof value === \"string\" ? textEncoder.encode(value) : value;\n}\n\n/**\n * Convert bytes to UTF-8 string\n *\n * Uses TextDecoder for proper UTF-8 handling.\n *\n * @param bytes - Uint8Array to convert\n * @returns UTF-8 string\n *\n * @example\n * ```ts\n * const str = bytesToString(new Uint8Array([104, 101, 108, 108, 111]));\n * // str === \"hello\"\n * ```\n */\nexport function bytesToString(bytes: Uint8Array): string {\n return textDecoder.decode(bytes);\n}\n\n/**\n * Normalize secret input to Uint8Array\n *\n * Accepts either a Base32-encoded string or Uint8Array and returns Uint8Array.\n * If a Base32Plugin is provided, string secrets will be automatically decoded.\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string secret (e.g. a passphrase), you must convert it\n * to a Uint8Array using {@link stringToBytes} before calling this function.\n *\n * @param secret - The secret to normalize (Base32 string or Uint8Array)\n * @param base32 - Optional Base32Plugin to decode string secrets\n * @returns The secret as Uint8Array\n * @throws {Error} If secret is a string but no Base32Plugin is provided\n *\n * @example\n * ```ts\n * import { normalizeSecret } from '@otplib/core'\n * import { ScureBase32Plugin } from '@otplib/plugin-base32-scure'\n *\n * const base32 = new ScureBase32Plugin()\n *\n * // Uint8Array - returned as-is\n * const secret1 = normalizeSecret(new Uint8Array([1, 2, 3]))\n *\n * // Base32 string - automatically decoded\n * const secret2 = normalizeSecret('JBSWY3DPEHPK3PXP', base32)\n * ```\n */\nexport function normalizeSecret(\n secret: string | Uint8Array,\n base32?: { decode: (str: string) => Uint8Array },\n): Uint8Array {\n if (typeof secret === \"string\") {\n requireBase32Plugin(base32);\n return base32.decode(secret);\n }\n return secret;\n}\n\n/**\n * Generate a random Base32-encoded secret\n *\n * Creates a cryptographically secure random secret suitable for OTP generation.\n * The default length of 20 bytes (160 bits) matches RFC 4226 recommendations\n * and provides good security margin.\n *\n * @param options - Secret generation options\n * @returns Base32-encoded secret string (without padding for Google Authenticator compatibility)\n *\n * @example\n * ```ts\n * import { generateSecret } from '@otplib/core';\n * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';\n * import { ScureBase32Plugin } from '@otplib/plugin-base32-scure';\n *\n * const secret = generateSecret({\n * crypto: new NodeCryptoPlugin(),\n * base32: new ScureBase32Plugin(),\n * });\n * // Returns: 'JBSWY3DPEHPK3PXP...' (32 characters)\n * ```\n *\n * @example Custom length\n * ```ts\n * const secret = generateSecret({\n * crypto: new NodeCryptoPlugin(),\n * base32: new ScureBase32Plugin(),\n * length: 32, // 256 bits for SHA-256\n * });\n * ```\n */\nexport function generateSecret(options: SecretOptions): string {\n const { crypto, base32, length = RECOMMENDED_SECRET_BYTES } = options;\n\n requireCryptoPlugin(crypto);\n requireBase32Plugin(base32);\n\n const randomBytes = crypto.randomBytes(length);\n return base32.encode(randomBytes, { padding: false });\n}\n\n/**\n * Normalize counter tolerance to [past, future] tuple\n *\n * Converts a number or tuple counter tolerance specification into a [past, future] tuple\n * - Number: creates look-ahead only tolerance [0, tolerance] (default for security)\n * - Tuple: uses the tuple as-is (past, future)\n *\n * The default behavior (number → look-ahead only) improves security by preventing\n * replay attacks. HOTP counters should only move forward in normal operation.\n *\n * @param counterTolerance - Counter tolerance specification (number or tuple [past, future])\n * @returns Tuple [past, future] representing counters to check\n *\n * @example\n * ```ts\n * normalizeCounterTolerance(0) // [0, 0]\n * normalizeCounterTolerance(5) // [0, 5] - look-ahead only (secure default)\n * normalizeCounterTolerance([10, 5]) // [10, 5] - explicit past/future\n * normalizeCounterTolerance([5, 5]) // [5, 5] - explicit symmetric (use with caution)\n * ```\n */\nexport function normalizeCounterTolerance(\n counterTolerance: number | [number, number] = 0,\n): [number, number] {\n return Array.isArray(counterTolerance) ? counterTolerance : [0, counterTolerance];\n}\n\n/**\n * Normalize epoch tolerance to [past, future] tuple\n *\n * Converts a number or tuple epoch tolerance specification into a [past, future] tuple\n * - Number: creates symmetric tolerance [tolerance, tolerance]\n * - Tuple: uses the tuple as-is\n *\n * @param epochTolerance - Epoch tolerance specification (number or tuple [past, future])\n * @returns Tuple [pastTolerance, futureTolerance] in seconds\n *\n * @example\n * ```ts\n * normalizeEpochTolerance(0) // [0, 0]\n * normalizeEpochTolerance(30) // [30, 30]\n * normalizeEpochTolerance([5, 0]) // [5, 0]\n * normalizeEpochTolerance([10, 5]) // [10, 5]\n * ```\n */\nexport function normalizeEpochTolerance(\n epochTolerance: number | [number, number] = 0,\n): [number, number] {\n return Array.isArray(epochTolerance) ? epochTolerance : [epochTolerance, epochTolerance];\n}\n\n/**\n * Require crypto plugin to be configured\n *\n * @param crypto - The crypto plugin\n * @throws {CryptoPluginMissingError} If crypto plugin is not set\n */\nexport function requireCryptoPlugin<T>(crypto: T | undefined): asserts crypto is T {\n if (!crypto) {\n throw new CryptoPluginMissingError();\n }\n}\n\n/**\n * Require Base32 plugin to be configured\n *\n * @param base32 - The Base32 plugin\n * @throws {Base32PluginMissingError} If Base32 plugin is not set\n */\nexport function requireBase32Plugin<T>(base32: T | undefined): asserts base32 is T {\n if (!base32) {\n throw new Base32PluginMissingError();\n }\n}\n\n/**\n * Require secret to be configured\n *\n * @param secret - The secret value\n * @throws {SecretMissingError} If secret is not set\n */\nexport function requireSecret<T>(secret: T | undefined): asserts secret is T {\n if (!secret) {\n throw new SecretMissingError();\n }\n}\n\n/**\n * Require label to be configured (for URI generation)\n *\n * @param label - The label value\n * @throws {LabelMissingError} If label is not set\n */\nexport function requireLabel(label: string | undefined): asserts label is string {\n if (!label) {\n throw new LabelMissingError();\n }\n}\n\n/**\n * Require issuer to be configured (for URI generation)\n *\n * @param issuer - The issuer value\n * @throws {IssuerMissingError} If issuer is not set\n */\nexport function requireIssuer(issuer: string | undefined): asserts issuer is string {\n if (!issuer) {\n throw new IssuerMissingError();\n }\n}\n\n/**\n * Require secret to be a Base32 string (for URI generation)\n *\n * @param secret - The secret value\n * @throws {SecretTypeError} If secret is not a string\n */\nexport function requireBase32String(secret: string | Uint8Array): asserts secret is string {\n if (typeof secret !== \"string\") {\n throw new SecretTypeError();\n }\n}\n\n/**\n * Create a success result\n * @internal\n */\nfunction ok<T>(value: T): OTPResultOk<T> {\n return { ok: true, value };\n}\n\n/**\n * Create a failure result\n * @internal\n */\nfunction err<E>(error: E): OTPResultError<E> {\n return { ok: false, error };\n}\n\n/**\n * Wrap a synchronous function to return OTPResult instead of throwing\n *\n * Preserves the original OTPError subclass so users can access\n * specific error information via instanceof checks.\n *\n * @internal\n */\nexport function wrapResult<T, Args extends unknown[]>(\n fn: (...args: Args) => T,\n): (...args: Args) => OTPResult<T, OTPError> {\n return (...args: Args): OTPResult<T, OTPError> => {\n try {\n return ok(fn(...args));\n } catch (error) {\n return err(error as OTPError);\n }\n };\n}\n\n/**\n * Wrap an async function to return OTPResult instead of throwing\n *\n * Preserves the original OTPError subclass so users can access\n * specific error information via instanceof checks.\n *\n * @internal\n */\nexport function wrapResultAsync<T, Args extends unknown[]>(\n fn: (...args: Args) => Promise<T>,\n): (...args: Args) => Promise<OTPResult<T, OTPError>> {\n return async (...args: Args): Promise<OTPResult<T, OTPError>> => {\n try {\n return ok(await fn(...args));\n } catch (error) {\n return err(error as OTPError);\n }\n };\n}\n","import { HMACError, RandomBytesError } from \"./errors.js\";\n\nimport type { CryptoPlugin, HashAlgorithm } from \"./types.js\";\n\n/**\n * CryptoContext provides a unified interface for crypto operations\n * using a pluggable crypto backend\n */\nexport class CryptoContext {\n /**\n * Create a new CryptoContext with the given crypto plugin\n *\n * @param crypto - The crypto plugin to use\n */\n constructor(private readonly crypto: CryptoPlugin) {}\n\n /**\n * Get the underlying crypto plugin\n */\n get plugin(): CryptoPlugin {\n return this.crypto;\n }\n\n /**\n * Compute HMAC using the configured crypto plugin\n *\n * @param algorithm - The hash algorithm to use\n * @param key - The secret key as a byte array\n * @param data - The data to authenticate as a byte array\n * @returns HMAC digest as a byte array\n * @throws {HMACError} If HMAC computation fails\n */\n async hmac(algorithm: HashAlgorithm, key: Uint8Array, data: Uint8Array): Promise<Uint8Array> {\n try {\n const result = this.crypto.hmac(algorithm, key, data);\n return result instanceof Promise ? await result : result;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new HMACError(message, { cause: error });\n }\n }\n\n /**\n * Synchronous HMAC computation\n *\n * @param algorithm - The hash algorithm to use\n * @param key - The secret key as a byte array\n * @param data - The data to authenticate as a byte array\n * @returns HMAC digest as a byte array\n * @throws {HMACError} If HMAC computation fails or if crypto plugin doesn't support sync operations\n */\n hmacSync(algorithm: HashAlgorithm, key: Uint8Array, data: Uint8Array): Uint8Array {\n try {\n const result = this.crypto.hmac(algorithm, key, data);\n if (result instanceof Promise) {\n throw new HMACError(\"Crypto plugin does not support synchronous HMAC operations\");\n }\n return result;\n } catch (error) {\n if (error instanceof HMACError) {\n throw error;\n }\n const message = error instanceof Error ? error.message : String(error);\n throw new HMACError(message, { cause: error });\n }\n }\n\n /**\n * Generate cryptographically secure random bytes\n *\n * @param length - Number of random bytes to generate\n * @returns Random bytes\n * @throws {RandomBytesError} If random byte generation fails\n */\n randomBytes(length: number): Uint8Array {\n try {\n return this.crypto.randomBytes(length);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new RandomBytesError(message, { cause: error });\n }\n }\n}\n\n/**\n * Create a CryptoContext from a crypto plugin\n *\n * @param crypto - The crypto plugin to use\n * @returns A new CryptoContext instance\n */\nexport function createCryptoContext(crypto: CryptoPlugin): CryptoContext {\n return new CryptoContext(crypto);\n}\n","import type { OTPAuthURI } from \"./types.js\";\nimport type { HashAlgorithm, Digits } from \"@otplib/core\";\n\n/**\n * Base options for URI generation\n */\nexport type URIOptions = {\n /**\n * Service/provider name (e.g., 'ACME Co', 'GitHub', 'AWS')\n */\n issuer?: string;\n\n /**\n * Account identifier (e.g., email, username)\n */\n label?: string;\n\n /**\n * Base32-encoded secret key\n */\n secret: string;\n\n /**\n * Hash algorithm (default: 'sha1')\n * Note: Google Authenticator only supports sha1\n */\n algorithm?: HashAlgorithm;\n\n /**\n * Number of digits (default: 6)\n * Google Authenticator supports 6 or 8, RFC also allows 7\n */\n digits?: Digits;\n\n /**\n * Time step in seconds for TOTP (default: 30)\n */\n period?: number;\n\n /**\n * Counter value for HOTP\n */\n counter?: number;\n};\n\n/**\n * TOTP-specific URI options\n */\nexport type TOTPURIOptions = URIOptions & {\n period?: number;\n counter?: never;\n};\n\n/**\n * HOTP-specific URI options\n */\nexport type HOTPURIOptions = URIOptions & {\n period?: never;\n counter?: number;\n};\n\n/**\n * Generate an otpauth:// URI\n *\n * @param uri - The URI components\n * @returns The otpauth:// URI string\n *\n * @example\n * ```ts\n * import { generate } from '@otplib/uri';\n * import { base32 } from '@otplib/plugin-base32-scure';\n *\n * const secret = base32.encode(new Uint8Array([1, 2, 3, 4, 5]));\n *\n * const uri = generate({\n * type: 'totp',\n * label: 'ACME:john@example.com',\n * params: {\n * secret,\n * issuer: 'ACME',\n * algorithm: 'sha1',\n * digits: 6,\n * },\n * });\n * // Returns: 'otpauth://totp/ACME:john%40example.com?secret=...'\n * ```\n */\nexport function generate(uri: OTPAuthURI): string {\n const { type, label, params } = uri;\n\n // Encode label parts while preserving ':' as the issuer/account separator\n const encodedLabel = label\n .split(\":\")\n .map((part) => encodeURIComponent(part))\n .join(\":\");\n\n let result = `otpauth://${type}/${encodedLabel}?`;\n\n const queryParams: string[] = [];\n\n if (params.secret) {\n queryParams.push(`secret=${encodeURIComponent(params.secret)}`);\n }\n\n if (params.issuer) {\n queryParams.push(`issuer=${encodeURIComponent(params.issuer)}`);\n }\n\n if (params.algorithm && params.algorithm !== \"sha1\") {\n queryParams.push(`algorithm=${params.algorithm.toUpperCase()}`);\n }\n\n if (params.digits && params.digits !== 6) {\n queryParams.push(`digits=${params.digits}`);\n }\n\n if (type === \"hotp\" && params.counter !== undefined) {\n queryParams.push(`counter=${params.counter}`);\n }\n\n if (type === \"totp\" && params.period !== undefined && params.period !== 30) {\n queryParams.push(`period=${params.period}`);\n }\n\n result += queryParams.join(\"&\");\n\n return result;\n}\n\n/**\n * Generate a TOTP otpauth:// URI with simplified parameters\n *\n * @param options - TOTP URI generation options\n * @returns The otpauth:// URI string\n */\nexport function generateTOTP(options: TOTPURIOptions & { issuer: string; label: string }): string {\n const { issuer, label: account, secret, algorithm = \"sha1\", digits = 6, period = 30 } = options;\n\n const fullLabel = issuer ? `${issuer}:${account}` : account;\n\n return generate({\n type: \"totp\",\n label: fullLabel,\n params: {\n secret,\n issuer,\n algorithm,\n digits,\n period,\n },\n });\n}\n\n/**\n * Generate a HOTP otpauth:// URI with simplified parameters\n *\n * @param options - HOTP URI generation options\n * @returns The otpauth:// URI string\n */\nexport function generateHOTP(options: HOTPURIOptions & { issuer: string; label: string }): string {\n const { issuer, label: account, secret, counter = 0, algorithm = \"sha1\", digits = 6 } = options;\n\n const fullLabel = issuer ? `${issuer}:${account}` : account;\n\n return generate({\n type: \"hotp\",\n label: fullLabel,\n params: {\n secret,\n issuer,\n algorithm,\n digits,\n counter,\n },\n });\n}\n","/**\n * @otplib/hotp\n *\n * HOTP class wrapper for convenient API\n */\n\nimport {\n generateSecret as generateSecretCore,\n requireCryptoPlugin,\n requireBase32Plugin,\n requireSecret,\n requireLabel,\n requireIssuer,\n requireBase32String,\n createGuardrails,\n} from \"@otplib/core\";\nimport { generateHOTP as generateHOTPURI } from \"@otplib/uri\";\n\nimport { generate as generateCode, verify as verifyCode } from \"./index.js\";\n\nimport type { VerifyResult, HOTPOptions } from \"./types.js\";\nimport type { OTPGuardrails } from \"@otplib/core\";\n\n/**\n * HOTP class for HMAC-based one-time password generation\n *\n * @example\n * ```typescript\n * import { HOTP } from '@otplib/hotp';\n * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';\n * import { ScureBase32Plugin } from '@otplib/plugin-base32-scure';\n *\n * const hotp = new HOTP({\n * issuer: 'MyApp',\n * label: 'user@example.com',\n * counter: 0,\n * crypto: new NodeCryptoPlugin(),\n * base32: new ScureBase32Plugin(),\n * });\n *\n * const secret = hotp.generateSecret();\n * const token = await hotp.generate(0);\n * const isValid = await hotp.verify({ token, counter: 0 });\n * ```\n */\nexport class HOTP {\n private readonly options: HOTPOptions;\n private readonly guardrails: OTPGuardrails;\n\n constructor(options: HOTPOptions = {}) {\n this.options = options;\n this.guardrails = createGuardrails(options.guardrails);\n }\n\n /**\n * Generate a random Base32-encoded secret\n *\n * @returns Base32-encoded secret\n */\n generateSecret(): string {\n const { crypto, base32 } = this.options;\n\n requireCryptoPlugin(crypto);\n requireBase32Plugin(base32);\n\n return generateSecretCore({ crypto, base32 });\n }\n\n /**\n * Generate an HOTP code for a specific counter\n *\n * @param counter - The counter value\n * @param options - Optional overrides\n * @returns The HOTP code\n */\n async generate(counter: number, options?: Partial<HOTPOptions>): Promise<string> {\n const mergedOptions = { ...this.options, ...options };\n const { secret, crypto, base32, algorithm = \"sha1\", digits = 6 } = mergedOptions;\n\n requireSecret(secret);\n requireCryptoPlugin(crypto);\n\n // Use class guardrails, or override if provided in options\n const guardrails = options?.guardrails ?? this.guardrails;\n\n return generateCode({\n secret,\n counter,\n algorithm,\n digits,\n crypto,\n base32,\n guardrails,\n hooks: mergedOptions.hooks,\n });\n }\n\n /**\n * Verify an HOTP code\n *\n * @param params - Verification parameters\n * @param options - Optional verification options\n * @returns Verification result with validity and optional delta\n */\n async verify(\n params: { token: string; counter: number },\n options?: Partial<HOTPOptions & { counterTolerance?: number | [number, number] }>,\n ): Promise<VerifyResult> {\n const mergedOptions = { ...this.options, ...options };\n const {\n secret,\n crypto,\n base32,\n algorithm = \"sha1\",\n digits = 6,\n counterTolerance = 0,\n } = mergedOptions;\n\n requireSecret(secret);\n requireCryptoPlugin(crypto);\n\n // Use class guardrails, or override if provided in options\n const guardrails = options?.guardrails ?? this.guardrails;\n\n return verifyCode({\n secret,\n token: params.token,\n counter: params.counter,\n algorithm,\n digits,\n counterTolerance,\n crypto,\n base32,\n guardrails,\n hooks: mergedOptions.hooks,\n });\n }\n\n /**\n * Generate an otpauth:// URI for QR codes\n *\n * @param counter - The counter value\n * @returns The otpauth:// URI\n */\n toURI(counter: number = 0): string {\n const { issuer, label, secret, algorithm = \"sha1\", digits = 6 } = this.options;\n\n requireSecret(secret);\n requireLabel(label);\n requireIssuer(issuer);\n requireBase32String(secret);\n\n return generateHOTPURI({\n issuer,\n label,\n secret,\n algorithm,\n digits,\n counter,\n });\n }\n}\n","/**\n * @otplib/hotp\n *\n * RFC 4226 HOTP (HMAC-Based One-Time Password) implementation.\n *\n * @see {@link https://tools.ietf.org/html/rfc4226 | RFC 4226}\n */\n\nimport {\n counterToBytes,\n createCryptoContext,\n createGuardrails,\n dynamicTruncate,\n truncateDigits,\n validateCounter,\n validateSecret,\n validateToken,\n validateCounterTolerance,\n normalizeSecret,\n normalizeCounterTolerance,\n requireSecret,\n requireCryptoPlugin,\n} from \"@otplib/core\";\n\nimport type { HOTPGenerateOptions, HOTPVerifyOptions, VerifyResult } from \"./types.js\";\nimport type { CryptoContext } from \"@otplib/core\";\nimport type { Digits, HashAlgorithm, CryptoPlugin, OTPHooks } from \"@otplib/core\";\n\n/**\n * Normalized options for HOTP generation\n * @internal\n */\ntype HOTPGenerateOptionsInternal = {\n ctx: CryptoContext;\n algorithm: HashAlgorithm;\n digits: Digits;\n secretBytes: Uint8Array;\n counterBytes: Uint8Array;\n hooks?: OTPHooks;\n};\n\n/**\n * Prepare and validate HOTP generation options\n *\n * Extracts defaults, normalizes the secret, validates parameters,\n * and creates the crypto context.\n *\n * @param options - HOTP generation options\n * @returns Normalized options with crypto context and counter bytes\n * @internal\n */\nfunction getHOTPGenerateOptions(options: HOTPGenerateOptions): HOTPGenerateOptionsInternal {\n const {\n secret,\n counter,\n algorithm = \"sha1\",\n digits = 6,\n crypto,\n base32,\n guardrails,\n hooks,\n } = options;\n\n requireSecret(secret);\n requireCryptoPlugin(crypto);\n\n const secretBytes = normalizeSecret(secret, base32);\n validateSecret(secretBytes, guardrails);\n validateCounter(counter, guardrails);\n\n const ctx = createCryptoContext(crypto);\n const counterBytes = counterToBytes(counter);\n\n return { ctx, algorithm, digits, secretBytes, counterBytes, hooks };\n}\n\n/**\n * Generate an HMAC-based One-Time Password (HOTP)\n *\n * Implements the HOTP algorithm as specified in RFC 4226 Section 5.3:\n *\n * 1. Convert counter to 8-byte big-endian array (RFC 4226 Section 5.1)\n * 2. Compute HMAC-SHA-1 using the secret key and counter (RFC 4226 Section 5.2)\n * 3. Apply dynamic truncation to extract 4-byte code (RFC 4226 Section 5.3)\n * 4. Reduce modulo 10^digits to get final OTP (RFC 4226 Section 5.3)\n *\n * @see {@link https://tools.ietf.org/html/rfc4226#section-5.3 | RFC 4226 Section 5.3 - Generating an HOTP Value}\n *\n * @param options - HOTP generation options\n * @returns The HOTP code as a string\n *\n * @example\n * ```ts\n * import { generate } from '@otplib/hotp';\n * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';\n *\n * const hotp = generate({\n * secret: new Uint8Array([1, 2, 3, 4, 5]),\n * counter: 0,\n * digits: 6,\n * crypto: new NodeCryptoPlugin(),\n * });\n * // Returns: '123456'\n * ```\n */\nexport async function generate(options: HOTPGenerateOptions): Promise<string> {\n const { ctx, algorithm, digits, secretBytes, counterBytes, hooks } =\n getHOTPGenerateOptions(options);\n const hmac = await ctx.hmac(algorithm, secretBytes, counterBytes);\n const dt = hooks?.truncateDigest ? hooks.truncateDigest(hmac) : dynamicTruncate(hmac);\n\n return hooks?.encodeToken ? hooks.encodeToken(dt, digits) : truncateDigits(dt, digits);\n}\n\n/**\n * Generate an HMAC-based One-Time Password (HOTP) synchronously\n *\n * This is the synchronous version of {@link generate}. It requires a crypto\n * plugin that supports synchronous HMAC operations (e.g., NodeCryptoPlugin\n * or NobleCryptoPlugin). Using this with WebCryptoPlugin will throw an error.\n *\n * @see {@link generate} for the async version\n * @see {@link https://tools.ietf.org/html/rfc4226#section-5.3 | RFC 4226 Section 5.3}\n *\n * @param options - HOTP generation options\n * @returns The HOTP code as a string\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n *\n * @example\n * ```ts\n * import { generateSync } from '@otplib/hotp';\n * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';\n *\n * const hotp = generateSync({\n * secret: new Uint8Array([1, 2, 3, 4, 5]),\n * counter: 0,\n * digits: 6,\n * crypto: new NodeCryptoPlugin(),\n * });\n * // Returns: '123456'\n * ```\n */\nexport function generateSync(options: HOTPGenerateOptions): string {\n const { ctx, algorithm, digits, secretBytes, counterBytes, hooks } =\n getHOTPGenerateOptions(options);\n const hmac = ctx.hmacSync(algorithm, secretBytes, counterBytes);\n const dt = hooks?.truncateDigest ? hooks.truncateDigest(hmac) : dynamicTruncate(hmac);\n\n return hooks?.encodeToken ? hooks.encodeToken(dt, digits) : truncateDigits(dt, digits);\n}\n\n/**\n * Normalized options for HOTP verification\n * @internal\n */\ntype HOTPVerifyOptionsInternal = {\n token: string;\n counterNum: number;\n past: number;\n future: number;\n totalChecks: number;\n crypto: CryptoPlugin;\n\n getGenerateOptions: (counter: number) => HOTPGenerateOptions;\n};\n\n/**\n * Prepare and validate HOTP verification options\n *\n * Extracts defaults, normalizes the secret, validates parameters,\n * and calculates the counter offsets based on tolerance.\n *\n * @param options - HOTP verification options\n * @returns Normalized options with calculated counter offsets\n * @internal\n */\nfunction getHOTPVerifyOptions(options: HOTPVerifyOptions): HOTPVerifyOptionsInternal {\n const {\n secret,\n counter,\n token,\n algorithm = \"sha1\",\n digits = 6,\n crypto,\n base32,\n counterTolerance = 0,\n guardrails = createGuardrails(),\n hooks,\n } = options;\n\n requireSecret(secret);\n requireCryptoPlugin(crypto);\n\n const secretBytes = normalizeSecret(secret, base32);\n validateSecret(secretBytes, guardrails);\n validateCounter(counter, guardrails);\n\n // Use custom validator if provided, otherwise default digit-only check\n if (hooks?.validateToken) {\n hooks.validateToken(token, digits);\n } else {\n validateToken(token, digits);\n }\n\n validateCounterTolerance(counterTolerance, guardrails);\n\n const counterNum = typeof counter === \"bigint\" ? Number(counter) : counter;\n const [past, future] = normalizeCounterTolerance(counterTolerance);\n const totalChecks = past + future + 1;\n\n return {\n token,\n counterNum,\n past,\n future,\n totalChecks,\n crypto,\n getGenerateOptions: (cnt: number) => ({\n secret: secretBytes,\n counter: cnt,\n algorithm,\n digits,\n crypto,\n guardrails,\n hooks,\n }),\n };\n}\n\n/**\n * Verify an HOTP code\n *\n * Compares the provided token against the expected HOTP value\n * using constant-time comparison to prevent timing attacks.\n *\n * @see {@link https://tools.ietf.org/html/rfc4226#section-7.2 | RFC 4226 Section 7.2 - Validation and Verification}\n * @see {@link https://tools.ietf.org/html/rfc4226#section-7.4 | RFC 4226 Section 7.4 - Resynchronization}\n *\n * ## Counter Resynchronization (RFC 4226 Section 7.4)\n *\n * When using a verification window, the `delta` value in the result indicates\n * how many counter steps ahead the token was found. After successful verification,\n * you should update the stored counter to prevent replay attacks:\n *\n * ```ts\n * const nextCounter = counter + result.delta + 1;\n * ```\n *\n * This ensures that the same token cannot be reused.\n *\n * @param options - HOTP verification options\n * @returns Verification result with validity and optional delta\n *\n * @example Basic verification\n * ```ts\n * import { verify } from '@otplib/hotp';\n * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';\n *\n * const result = await verify({\n * secret: new Uint8Array([1, 2, 3, 4, 5]),\n * counter: 0,\n * token: '123456',\n * crypto: new NodeCryptoPlugin(),\n * });\n * // Returns: { valid: true, delta: 0 }\n * ```\n *\n * @example Counter resynchronization with counterTolerance\n * ```ts\n * // User's token was generated at counter 5, but server expects counter 3\n * const result = await verify({\n * secret,\n * counter: 3, // Server's stored counter\n * token: userToken,\n * counterTolerance: 5, // Allow up to 5 counters ahead\n * crypto: new NodeCryptoPlugin(),\n * });\n *\n * if (result.valid) {\n * // Token matched at counter 3 + delta\n * // Update stored counter to prevent replay attacks\n * const nextCounter = 3 + result.delta + 1; // = 6\n * await saveCounter(userId, nextCounter);\n * }\n * ```\n */\nexport async function verify(options: HOTPVerifyOptions): Promise<VerifyResult> {\n const { token, counterNum, past, totalChecks, crypto, getGenerateOptions } =\n getHOTPVerifyOptions(options);\n\n // Optimization: Skip iterations that would produce negative counters\n // If counterNum=2 and past=5: startI = 3 (skip first 3 iterations)\n // If counterNum=10 and past=5: startI = 0 (no skip needed)\n const startI = Math.max(0, past - counterNum);\n\n // Use positive loop index to avoid -0 edge cases and negative loop variables\n // Map index [startI...totalChecks-1] to offset [startI-past...future]\n for (let i = startI; i < totalChecks; i++) {\n const offset = i - past;\n const currentCounter = counterNum + offset;\n // currentCounter is guaranteed >= 0 due to startI optimization\n\n const expected = await generate(getGenerateOptions(currentCounter));\n if (crypto.constantTimeEqual(expected, token)) {\n return { valid: true, delta: offset | 0 }; // Bitwise OR converts -0 to +0\n }\n }\n\n return { valid: false };\n}\n\n/**\n * Verify an HOTP code synchronously\n *\n * This is the synchronous version of {@link verify}. It requires a crypto\n * plugin that supports synchronous HMAC operations (e.g., NodeCryptoPlugin\n * or NobleCryptoPlugin). Using this with WebCryptoPlugin will throw an error.\n *\n * @see {@link verify} for the async version\n * @see {@link https://tools.ietf.org/html/rfc4226#section-7.2 | RFC 4226 Section 7.2}\n *\n * @param options - HOTP verification options\n * @returns Verification result with validity and optional delta\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n *\n * @example\n * ```ts\n * import { verifySync } from '@otplib/hotp';\n * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';\n *\n * const result = verifySync({\n * secret: new Uint8Array([1, 2, 3, 4, 5]),\n * counter: 0,\n * token: '123456',\n * crypto: new NodeCryptoPlugin(),\n * });\n * // Returns: { valid: true, delta: 0 }\n * ```\n */\nexport function verifySync(options: HOTPVerifyOptions): VerifyResult {\n const { token, counterNum, past, totalChecks, crypto, getGenerateOptions } =\n getHOTPVerifyOptions(options);\n\n // Optimization: Skip iterations that would produce negative counters\n // If counterNum=2 and past=5: startI = 3 (skip first 3 iterations)\n // If counterNum=10 and past=5: startI = 0 (no skip needed)\n const startI = Math.max(0, past - counterNum);\n\n // Use positive loop index to avoid -0 edge cases and negative loop variables\n // Map index [startI...totalChecks-1] to offset [startI-past...future]\n for (let i = startI; i < totalChecks; i++) {\n const offset = i - past;\n const currentCounter = counterNum + offset;\n // currentCounter is guaranteed >= 0 due to startI optimization\n\n const expected = generateSync(getGenerateOptions(currentCounter));\n if (crypto.constantTimeEqual(expected, token)) {\n return { valid: true, delta: offset | 0 }; // Bitwise OR converts -0 to +0\n }\n }\n\n return { valid: false };\n}\n\nexport type { CryptoPlugin, Digits, HashAlgorithm, OTPResult } from \"@otplib/core\";\nexport type {\n HOTPOptions,\n HOTPGenerateOptions,\n HOTPVerifyOptions,\n VerifyResult,\n VerifyResultValid,\n VerifyResultInvalid,\n} from \"./types.js\";\n\nexport { HOTP } from \"./class.js\";\n\n// Result wrapping utilities for users who want safe variants\nexport { wrapResult, wrapResultAsync } from \"@otplib/core\";\n","/**\n * @otplib/totp\n *\n * TOTP class wrapper for convenient API\n */\n\nimport {\n generateSecret as generateSecretCore,\n requireCryptoPlugin,\n requireBase32Plugin,\n requireSecret,\n requireLabel,\n requireIssuer,\n requireBase32String,\n createGuardrails,\n} from \"@otplib/core\";\nimport { generateTOTP as generateTOTPURI } from \"@otplib/uri\";\n\nimport { generate as generateCode, verify as verifyCode } from \"./index.js\";\n\nimport type { VerifyResult, TOTPOptions, TOTPVerifyOptions } from \"./types.js\";\nimport type { OTPGuardrails } from \"@otplib/core\";\n\n/**\n * TOTP class for time-based one-time password generation\n *\n * @example\n * ```typescript\n * import { TOTP } from '@otplib/totp';\n * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';\n * import { ScureBase32Plugin } from '@otplib/plugin-base32-scure';\n *\n * const totp = new TOTP({\n * issuer: 'MyApp',\n * label: 'user@example.com',\n * crypto: new NodeCryptoPlugin(),\n * base32: new ScureBase32Plugin(),\n * });\n *\n * const secret = totp.generateSecret();\n * const token = await totp.generate();\n * const isValid = await totp.verify(token);\n * ```\n */\nexport class TOTP {\n private readonly options: TOTPOptions;\n private readonly guardrails: OTPGuardrails;\n\n constructor(options: TOTPOptions = {}) {\n this.options = options;\n this.guardrails = createGuardrails(options.guardrails);\n }\n\n /**\n * Generate a random Base32-encoded secret\n *\n * @returns Base32-encoded secret\n */\n generateSecret(): string {\n const { crypto, base32 } = this.options;\n\n requireCryptoPlugin(crypto);\n requireBase32Plugin(base32);\n\n return generateSecretCore({ crypto, base32 });\n }\n\n /**\n * Generate a TOTP code\n *\n * @param options - Optional overrides\n * @returns The TOTP code\n */\n async generate(options?: Partial<TOTPOptions>): Promise<string> {\n const mergedOptions = { ...this.options, ...options };\n const {\n secret,\n crypto,\n base32,\n algorithm = \"sha1\",\n digits = 6,\n period = 30,\n epoch,\n t0 = 0,\n } = mergedOptions;\n\n requireSecret(secret);\n requireCryptoPlugin(crypto);\n\n // Use class guardrails, or override if provided in options\n const guardrails = options?.guardrails ?? this.guardrails;\n\n return generateCode({\n secret,\n algorithm,\n digits,\n period,\n epoch: epoch ?? Math.floor(Date.now() / 1000),\n t0,\n crypto,\n base32,\n guardrails,\n hooks: mergedOptions.hooks,\n });\n }\n\n /**\n * Verify a TOTP code\n *\n * @param token - The token to verify\n * @param options - Optional verification options\n * @returns Verification result with validity and optional delta\n */\n async verify(\n token: string,\n options?: Partial<Omit<TOTPVerifyOptions, \"token\">>,\n ): Promise<VerifyResult> {\n const mergedOptions = { ...this.options, ...options };\n const {\n secret,\n crypto,\n base32,\n algorithm = \"sha1\",\n digits = 6,\n period = 30,\n epoch,\n t0 = 0,\n epochTolerance = 0,\n afterTimeStep,\n } = mergedOptions;\n\n requireSecret(secret);\n requireCryptoPlugin(crypto);\n\n // Use class guardrails, or override if provided in options\n const guardrails = options?.guardrails ?? this.guardrails;\n\n return verifyCode({\n secret,\n token,\n algorithm,\n digits,\n period,\n epoch: epoch ?? Math.floor(Date.now() / 1000),\n t0,\n epochTolerance,\n afterTimeStep,\n crypto,\n base32,\n guardrails,\n hooks: mergedOptions.hooks,\n });\n }\n\n /**\n * Generate an otpauth:// URI for QR codes\n *\n * When called with parameters, merges them with instance options.\n * This preserves algorithm, digits, and period settings from the instance\n * while allowing label, issuer, and secret to be overridden.\n *\n * @param options - Optional overrides for label, issuer, and secret\n * @returns The otpauth:// URI\n *\n * @example Without parameters (uses instance settings)\n * ```typescript\n * const totp = new TOTP({\n * label: 'user@example.com',\n * issuer: 'MyApp',\n * secret: 'JBSWY3DPEHPK3PXP',\n * crypto: new NodeCryptoPlugin(),\n * base32: new ScureBase32Plugin(),\n * });\n * const uri = totp.toURI();\n * ```\n *\n * @example With parameters (overrides instance settings)\n * ```typescript\n * const totp = new TOTP({\n * algorithm: 'sha256',\n * digits: 8,\n * crypto: new NodeCryptoPlugin(),\n * base32: new ScureBase32Plugin(),\n * });\n * // Uses instance's algorithm and digits with provided label/issuer/secret\n * const uri = totp.toURI({\n * label: 'user@example.com',\n * issuer: 'MyApp',\n * secret: 'JBSWY3DPEHPK3PXP',\n * });\n * ```\n */\n toURI(options?: { label?: string; issuer?: string; secret?: string }): string {\n const {\n issuer: instanceIssuer,\n label: instanceLabel,\n secret: instanceSecret,\n algorithm = \"sha1\",\n digits = 6,\n period = 30,\n } = this.options;\n\n // Merge provided parameters with instance options\n const finalLabel = options?.label ?? instanceLabel;\n const finalIssuer = options?.issuer ?? instanceIssuer;\n const finalSecret = options?.secret ?? instanceSecret;\n\n requireSecret(finalSecret);\n requireLabel(finalLabel);\n requireIssuer(finalIssuer);\n requireBase32String(finalSecret);\n\n return generateTOTPURI({\n issuer: finalIssuer,\n label: finalLabel,\n secret: finalSecret,\n algorithm,\n digits,\n period,\n });\n }\n}\n","/**\n * @otplib/totp\n *\n * RFC 6238 TOTP (Time-Based One-Time Password) implementation.\n *\n * TOTP extends HOTP (RFC 4226) by using time as the moving factor\n * instead of an event counter.\n *\n * @see {@link https://tools.ietf.org/html/rfc6238 | RFC 6238}\n * @see {@link https://tools.ietf.org/html/rfc4226 | RFC 4226 (HOTP base algorithm)}\n */\n\nimport {\n createGuardrails,\n normalizeSecret,\n normalizeEpochTolerance,\n validateEpochTolerance,\n validatePeriod,\n validateSecret,\n validateTime,\n validateToken,\n requireSecret,\n requireCryptoPlugin,\n AfterTimeStepNegativeError,\n AfterTimeStepNotIntegerError,\n AfterTimeStepRangeExceededError,\n} from \"@otplib/core\";\nimport { generate as generateHOTP, generateSync as generateHOTPSync } from \"@otplib/hotp\";\n\nimport type { TOTPGenerateOptions, TOTPVerifyOptions, VerifyResult } from \"./types.js\";\nimport type { CryptoPlugin, Digits, HashAlgorithm, OTPGuardrails, OTPHooks } from \"@otplib/core\";\n\n/**\n * Normalized options for TOTP generation\n * @internal\n */\ntype TOTPGenerateOptionsInternal = {\n secret: Uint8Array;\n counter: number;\n algorithm: HashAlgorithm;\n digits: Digits;\n crypto: CryptoPlugin;\n guardrails: OTPGuardrails;\n hooks?: OTPHooks;\n};\n\n/**\n * Prepare and validate TOTP generation options\n *\n * Extracts defaults, normalizes the secret, validates parameters,\n * and calculates the HOTP counter from the epoch.\n *\n * @param options - TOTP generation options\n * @returns Normalized options ready for HOTP generation\n * @internal\n */\nfunction getTOTPGenerateOptions(options: TOTPGenerateOptions): TOTPGenerateOptionsInternal {\n const {\n secret,\n epoch = Math.floor(Date.now() / 1000),\n t0 = 0,\n period = 30,\n algorithm = \"sha1\",\n digits = 6,\n crypto,\n base32,\n guardrails = createGuardrails(),\n hooks,\n } = options;\n\n requireSecret(secret);\n requireCryptoPlugin(crypto);\n\n const secretBytes = normalizeSecret(secret, base32);\n validateSecret(secretBytes, guardrails);\n validateTime(epoch);\n validatePeriod(period, guardrails);\n\n const counter = Math.floor((epoch - t0) / period);\n\n return {\n secret: secretBytes,\n counter,\n algorithm,\n digits,\n crypto,\n guardrails,\n hooks,\n };\n}\n\n/**\n * Generate a Time-based One-Time Password (TOTP)\n *\n * Implements the TOTP algorithm as specified in RFC 6238 Section 4:\n *\n * ```\n * T = (Current Unix time - T0) / X\n * TOTP = HOTP(K, T)\n * ```\n *\n * Where:\n * - T0 is the Unix time to start counting time steps (default 0, per RFC 6238 Section 4.1)\n * - X is the time step in seconds (default 30, per RFC 6238 Section 4.1)\n * - K is the shared secret key\n *\n * @see {@link https://tools.ietf.org/html/rfc6238#section-4 | RFC 6238 Section 4 - TOTP Algorithm}\n * @see {@link https://tools.ietf.org/html/rfc6238#section-4.1 | RFC 6238 Section 4.1 - Parameters}\n *\n * @param options - TOTP generation options\n * @returns The TOTP code as a string\n *\n * @example\n * ```ts\n * import { generate } from '@otplib/totp';\n * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';\n *\n * const totp = generate({\n * secret: new Uint8Array([1, 2, 3, 4, 5]),\n * time: Date.now() / 1000,\n * period: 30,\n * digits: 6,\n * crypto: new NodeCryptoPlugin(),\n * });\n * // Returns: '123456'\n * ```\n */\nexport async function generate(options: TOTPGenerateOptions): Promise<string> {\n const opt = getTOTPGenerateOptions(options);\n return generateHOTP(opt);\n}\n\n/**\n * Generate a Time-based One-Time Password (TOTP) synchronously\n *\n * This is the synchronous version of {@link generate}. It requires a crypto\n * plugin that supports synchronous HMAC operations (e.g., NodeCryptoPlugin\n * or NobleCryptoPlugin). Using this with WebCryptoPlugin will throw an error.\n *\n * @see {@link generate} for the async version\n * @see {@link https://tools.ietf.org/html/rfc6238#section-4 | RFC 6238 Section 4}\n *\n * @param options - TOTP generation options\n * @returns The TOTP code as a string\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n *\n * @example\n * ```ts\n * import { generateSync } from '@otplib/totp';\n * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';\n *\n * const totp = generateSync({\n * secret: new Uint8Array([1, 2, 3, 4, 5]),\n * epoch: Math.floor(Date.now() / 1000),\n * period: 30,\n * digits: 6,\n * crypto: new NodeCryptoPlugin(),\n * });\n * // Returns: '123456'\n * ```\n */\nexport function generateSync(options: TOTPGenerateOptions): string {\n const opt = getTOTPGenerateOptions(options);\n return generateHOTPSync(opt);\n}\n\n/**\n * Validate afterTimeStep parameter for replay protection\n *\n * Ensures afterTimeStep is a valid non-negative integer and doesn't make\n * verification impossible by exceeding the valid counter range.\n *\n * @param afterTimeStep - The afterTimeStep value to validate (undefined is valid)\n * @param maxCounter - The maximum counter in the verification window\n * @throws {AfterTimeStepNegativeError} If afterTimeStep is negative\n * @throws {AfterTimeStepNotIntegerError} If afterTimeStep is not an integer\n * @throws {AfterTimeStepRangeExceededError} If afterTimeStep exceeds maxCounter\n *\n * @internal\n */\nfunction validateAfterTimeStep(afterTimeStep: number | undefined, maxCounter: number): void {\n if (afterTimeStep === undefined) {\n return;\n }\n\n if (afterTimeStep < 0) {\n throw new AfterTimeStepNegativeError();\n }\n\n if (!Number.isSafeInteger(afterTimeStep)) {\n throw new AfterTimeStepNotIntegerError();\n }\n\n if (afterTimeStep > maxCounter) {\n throw new AfterTimeStepRangeExceededError();\n }\n}\n\n/**\n * Check if a counter should be skipped based on afterTimeStep\n * @internal\n */\nfunction shouldSkipAfterTimeStep(counter: number, afterTimeStep: number | undefined): boolean {\n return afterTimeStep !== undefined && counter <= afterTimeStep;\n}\n\n/**\n * Normalized options for TOTP verification\n * @internal\n */\ntype TOTPVerifyOptionsInternal = {\n token: string;\n crypto: CryptoPlugin;\n minCounter: number;\n maxCounter: number;\n currentCounter: number;\n t0: number;\n period: number;\n afterTimeStep?: number;\n\n getGenerateOptions: (counter: number) => TOTPGenerateOptions;\n};\n\n/**\n * Prepare and validate TOTP verification options\n *\n * Extracts defaults, normalizes the secret, validates parameters,\n * and calculates the counter range based on epoch tolerance.\n *\n * @param options - TOTP verification options\n * @returns Normalized options with calculated counter range\n * @internal\n */\nfunction getTOTPVerifyOptions(options: TOTPVerifyOptions): TOTPVerifyOptionsInternal {\n const {\n secret,\n token,\n epoch = Math.floor(Date.now() / 1000),\n t0 = 0,\n period = 30,\n algorithm = \"sha1\",\n digits = 6,\n crypto,\n base32,\n epochTolerance = 0,\n afterTimeStep,\n guardrails = createGuardrails(),\n hooks,\n } = options;\n\n requireSecret(secret);\n requireCryptoPlugin(crypto);\n\n const secretBytes = normalizeSecret(secret, base32);\n validateSecret(secretBytes, guardrails);\n validateTime(epoch);\n validatePeriod(period, guardrails);\n\n // Use custom validator if provided, otherwise default digit-only check\n if (hooks?.validateToken) {\n hooks.validateToken(token, digits);\n } else {\n validateToken(token, digits);\n }\n\n validateEpochTolerance(epochTolerance, period, guardrails);\n\n const currentCounter = Math.floor((epoch - t0) / period);\n\n // Normalize epochTolerance to [pastTolerance, futureTolerance]\n const [pastTolerance, futureTolerance] = normalizeEpochTolerance(epochTolerance);\n\n // Calculate the range of counters that could have valid tokens\n // Valid time range is [epoch - pastTolerance, epoch + futureTolerance]\n const minCounter = Math.max(0, Math.floor((epoch - pastTolerance - t0) / period));\n const maxCounter = Math.floor((epoch + futureTolerance - t0) / period);\n\n // Validate afterTimeStep against the calculated maxCounter\n validateAfterTimeStep(afterTimeStep, maxCounter);\n\n return {\n token,\n crypto,\n minCounter,\n maxCounter,\n currentCounter,\n t0,\n period,\n afterTimeStep,\n getGenerateOptions: (counter: number) => ({\n secret: secretBytes,\n epoch: counter * period + t0,\n t0,\n period,\n algorithm,\n digits,\n crypto,\n guardrails,\n hooks,\n }),\n };\n}\n\n/**\n * Verify a TOTP code\n *\n * Compares the provided token against the expected TOTP value\n * using constant-time comparison to prevent timing attacks.\n *\n * The verification window allows for clock drift between client and server,\n * as recommended in RFC 6238 Section 5.2.\n *\n * @see {@link https://tools.ietf.org/html/rfc6238#section-5.2 | RFC 6238 Section 5.2 - Validation and Time-Step Size}\n *\n * @param options - TOTP verification options\n * @returns Verification result with validity and optional delta\n *\n * @example Using epochTolerance\n * ```ts\n * import { verify } from '@otplib/totp';\n * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';\n *\n * // Accept tokens valid within ±30 seconds\n * const result = await verify({\n * secret: mySecret,\n * token: '123456',\n * epochTolerance: 30,\n * crypto: new NodeCryptoPlugin(),\n * });\n * if (result.valid) {\n * console.log(`Token matched at epoch: ${result.epoch}`);\n * }\n * ```\n */\nexport async function verify(options: TOTPVerifyOptions): Promise<VerifyResult> {\n const {\n token,\n crypto,\n minCounter,\n maxCounter,\n currentCounter,\n t0,\n period,\n afterTimeStep,\n getGenerateOptions,\n } = getTOTPVerifyOptions(options);\n\n for (let counter = minCounter; counter <= maxCounter; counter++) {\n // Early rejection: skip counters that don't meet afterTimeStep constraint\n if (shouldSkipAfterTimeStep(counter, afterTimeStep)) {\n continue;\n }\n\n const expected = await generate(getGenerateOptions(counter));\n if (crypto.constantTimeEqual(expected, token)) {\n return {\n valid: true,\n delta: counter - currentCounter,\n epoch: counter * period + t0,\n timeStep: counter,\n };\n }\n }\n\n return { valid: false };\n}\n\n/**\n * Verify a TOTP code synchronously\n *\n * This is the synchronous version of {@link verify}. It requires a crypto\n * plugin that supports synchronous HMAC operations (e.g., NodeCryptoPlugin\n * or NobleCryptoPlugin). Using this with WebCryptoPlugin will throw an error.\n *\n * @see {@link verify} for the async version\n * @see {@link https://tools.ietf.org/html/rfc6238#section-5.2 | RFC 6238 Section 5.2}\n *\n * @param options - TOTP verification options\n * @returns Verification result with validity and optional delta\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n *\n * @example\n * ```ts\n * import { verifySync } from '@otplib/totp';\n * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';\n *\n * const result = verifySync({\n * secret: mySecret,\n * token: '123456',\n * epochTolerance: 30,\n * crypto: new NodeCryptoPlugin(),\n * });\n * if (result.valid) {\n * console.log(`Token matched at epoch: ${result.epoch}`);\n * }\n * ```\n */\nexport function verifySync(options: TOTPVerifyOptions): VerifyResult {\n const {\n token,\n crypto,\n minCounter,\n maxCounter,\n currentCounter,\n t0,\n period,\n afterTimeStep,\n getGenerateOptions,\n } = getTOTPVerifyOptions(options);\n\n for (let counter = minCounter; counter <= maxCounter; counter++) {\n // Early rejection: skip counters that don't meet afterTimeStep constraint\n if (shouldSkipAfterTimeStep(counter, afterTimeStep)) {\n continue;\n }\n\n const expected = generateSync(getGenerateOptions(counter));\n if (crypto.constantTimeEqual(expected, token)) {\n return {\n valid: true,\n delta: counter - currentCounter,\n epoch: counter * period + t0,\n timeStep: counter,\n };\n }\n }\n\n return { valid: false };\n}\n\n/**\n * Get the remaining time until the next TOTP period\n *\n * @param time - Current Unix timestamp in seconds (default: now)\n * @param period - Time step in seconds (default: 30)\n * @param t0 - Initial Unix time to start counting time steps (default: 0)\n * @returns Remaining seconds until next period\n *\n * @example\n * ```ts\n * import { getRemainingTime } from '@otplib/totp';\n *\n * const remaining = getRemainingTime();\n * // Returns: 15 (seconds remaining in current 30-second window)\n * ```\n */\nexport function getRemainingTime(\n time: number = Math.floor(Date.now() / 1000),\n period: number = 30,\n t0: number = 0,\n guardrails: OTPGuardrails = createGuardrails(),\n): number {\n validateTime(time);\n validatePeriod(period, guardrails);\n\n const counter = Math.floor((time - t0) / period);\n const nextCounter = counter + 1;\n const nextTime = nextCounter * period + t0;\n\n return nextTime - time;\n}\n\n/**\n * Get the current TOTP counter value\n *\n * @param time - Current Unix timestamp in seconds (default: now)\n * @param period - Time step in seconds (default: 30)\n * @param t0 - Initial Unix time to start counting time steps (default: 0)\n * @returns Current counter value\n *\n * @example\n * ```ts\n * import { getTimeStepUsed } from '@otplib/totp';\n *\n * const counter = getTimeStepUsed();\n * // Returns: 12345 (current counter value)\n * ```\n */\nexport function getTimeStepUsed(\n time: number = Math.floor(Date.now() / 1000),\n period: number = 30,\n t0: number = 0,\n guardrails: OTPGuardrails = createGuardrails(),\n): number {\n validateTime(time);\n validatePeriod(period, guardrails);\n\n return Math.floor((time - t0) / period);\n}\n\nexport type { CryptoPlugin, Digits, HashAlgorithm, OTPResult } from \"@otplib/core\";\nexport type {\n TOTPOptions,\n TOTPGenerateOptions,\n TOTPVerifyOptions,\n VerifyResult,\n VerifyResultValid,\n VerifyResultInvalid,\n} from \"./types\";\n\nexport { TOTP } from \"./class\";\n\n// Result wrapping utilities for users who want safe variants\nexport { wrapResult, wrapResultAsync } from \"@otplib/core\";\n","/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n\n/** Transforms values between two representations. */\nexport interface Coder<F, T> {\n /**\n * Converts a value from the input representation to the output representation.\n * @param from - Value in the source representation.\n * @returns Converted value.\n */\n encode(from: F): T;\n /**\n * Converts a value from the output representation back to the input representation.\n * @param to - Value in the target representation.\n * @returns Converted value.\n */\n decode(to: T): F;\n}\n\n/** Coder that works with byte arrays and strings. */\nexport interface BytesCoder extends Coder<Uint8Array, string> {\n /**\n * Encodes bytes into a string representation.\n * @param data - Bytes to encode.\n * @returns Encoded string.\n */\n encode: (data: Uint8Array) => string;\n /**\n * Decodes a string representation into raw bytes.\n * @param str - Encoded string.\n * @returns Decoded bytes.\n */\n decode: (str: string) => Uint8Array;\n}\n\n/**\n * Bytes API type helpers for old + new TypeScript.\n *\n * TS 5.6 has `Uint8Array`, while TS 5.9+ made it generic `Uint8Array<ArrayBuffer>`.\n * We can't use specific return type, because TS 5.6 will error.\n * We can't use generic return type, because most TS 5.9 software will expect specific type.\n *\n * Maps typed-array input leaves to broad forms.\n * These are compatibility adapters, not ownership guarantees.\n *\n * - `TArg` keeps byte inputs broad.\n * - `TRet` marks byte outputs for TS 5.6 and TS 5.9+ compatibility.\n */\nexport type TypedArg<T> = T extends BigInt64Array\n ? BigInt64Array\n : T extends BigUint64Array\n ? BigUint64Array\n : T extends Float32Array\n ? Float32Array\n : T extends Float64Array\n ? Float64Array\n : T extends Int16Array\n ? Int16Array\n : T extends Int32Array\n ? Int32Array\n : T extends Int8Array\n ? Int8Array\n : T extends Uint16Array\n ? Uint16Array\n : T extends Uint32Array\n ? Uint32Array\n : T extends Uint8ClampedArray\n ? Uint8ClampedArray\n : T extends Uint8Array\n ? Uint8Array\n : never;\n/** Maps typed-array output leaves to narrow TS-compatible forms. */\nexport type TypedRet<T> = T extends BigInt64Array\n ? ReturnType<typeof BigInt64Array.of>\n : T extends BigUint64Array\n ? ReturnType<typeof BigUint64Array.of>\n : T extends Float32Array\n ? ReturnType<typeof Float32Array.of>\n : T extends Float64Array\n ? ReturnType<typeof Float64Array.of>\n : T extends Int16Array\n ? ReturnType<typeof Int16Array.of>\n : T extends Int32Array\n ? ReturnType<typeof Int32Array.of>\n : T extends Int8Array\n ? ReturnType<typeof Int8Array.of>\n : T extends Uint16Array\n ? ReturnType<typeof Uint16Array.of>\n : T extends Uint32Array\n ? ReturnType<typeof Uint32Array.of>\n : T extends Uint8ClampedArray\n ? ReturnType<typeof Uint8ClampedArray.of>\n : T extends Uint8Array\n ? ReturnType<typeof Uint8Array.of>\n : never;\n/** Recursively adapts byte-carrying API input types. See {@link TypedArg}. */\nexport type TArg<T> =\n | T\n | ([TypedArg<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TRet<A[K]> }) => TArg<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TArg<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends (infer A)[]\n ? TArg<A>[]\n : T extends readonly (infer A)[]\n ? readonly TArg<A>[]\n : T extends Promise<infer A>\n ? Promise<TArg<A>>\n : T extends object\n ? { [K in keyof T]: TArg<T[K]> }\n : T\n : TypedArg<T>);\n/** Recursively adapts byte-carrying API output types. See {@link TypedArg}. */\nexport type TRet<T> = T extends unknown\n ? T &\n ([TypedRet<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TArg<A[K]> }) => TRet<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TRet<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends (infer A)[]\n ? TRet<A>[]\n : T extends readonly (infer A)[]\n ? readonly TRet<A>[]\n : T extends Promise<infer A>\n ? Promise<TRet<A>>\n : T extends object\n ? { [K in keyof T]: TRet<T[K]> }\n : T\n : TypedRet<T>)\n : never;\n\nfunction isBytes(a: unknown): a is Uint8Array {\n // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / cross-realm cases. The\n // fallback still requires a real ArrayBuffer view, so plain JSON-deserialized\n // `{ constructor: ... }` spoofing is rejected. `BYTES_PER_ELEMENT === 1` keeps the\n // fallback on byte-oriented views.\n return (\n a instanceof Uint8Array ||\n (ArrayBuffer.isView(a) &&\n a.constructor.name === 'Uint8Array' &&\n 'BYTES_PER_ELEMENT' in a &&\n a.BYTES_PER_ELEMENT === 1)\n );\n}\n/** Asserts something is Uint8Array. */\nfunction abytes(b: TArg<Uint8Array | undefined>): void {\n if (!isBytes(b)) throw new TypeError('Uint8Array expected');\n}\n\nfunction isArrayOf(isString: boolean, arr: any[]) {\n if (!Array.isArray(arr)) return false;\n if (arr.length === 0) return true;\n if (isString) {\n return arr.every((item) => typeof item === 'string');\n } else {\n return arr.every((item) => Number.isSafeInteger(item));\n }\n}\n\nfunction afn(input: Function): input is Function {\n if (typeof input !== 'function') throw new TypeError('function expected');\n return true;\n}\n\nfunction astr(label: string, input: unknown): input is string {\n if (typeof input !== 'string') throw new TypeError(`${label}: string expected`);\n return true;\n}\n\nfunction anumber(n: number): void {\n if (typeof n !== 'number') throw new TypeError(`number expected, got ${typeof n}`);\n if (!Number.isSafeInteger(n)) throw new RangeError(`invalid integer: ${n}`);\n}\n\nfunction aArr(input: any[]) {\n if (!Array.isArray(input)) throw new TypeError('array expected');\n}\nfunction astrArr(label: string, input: string[]) {\n if (!isArrayOf(true, input)) throw new TypeError(`${label}: array of strings expected`);\n}\nfunction anumArr(label: string, input: number[]) {\n if (!isArrayOf(false, input)) throw new TypeError(`${label}: array of numbers expected`);\n}\n\n// TODO: some recusive type inference so it would check correct order of input/output inside rest?\n// like <string, number>, <number, bytes>, <bytes, float>\ntype Chain = [Coder<any, any>, ...Coder<any, any>[]];\n// Extract info from Coder type\ntype Input<F> = F extends Coder<infer T, any> ? T : never;\ntype Output<F> = F extends Coder<any, infer T> ? T : never;\n// Generic function for arrays\ntype First<T> = T extends [infer U, ...any[]] ? U : never;\ntype Last<T> = T extends [...any[], infer U] ? U : never;\ntype Tail<T> = T extends [any, ...infer U] ? U : never;\n\ntype AsChain<C extends Chain, Rest = Tail<C>> = {\n // C[K] = Coder<Input<C[K]>, Input<Rest[k]>>\n [K in keyof C]: Coder<Input<C[K]>, Input<K extends keyof Rest ? Rest[K] : any>>;\n};\n\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction chain<T extends Chain & AsChain<T>>(...args: T): Coder<Input<First<T>>, Output<Last<T>>> {\n const id = (a: any) => a;\n // Wrap call in closure so JIT can inline calls\n const wrap = (a: any, b: any) => (c: any) => a(b(c));\n // Construct chain of args[-1].encode(args[-2].encode([...]))\n const encode = args.map((x) => x.encode).reduceRight(wrap, id);\n // Construct chain of args[0].decode(args[1].decode(...))\n const decode = args.map((x) => x.decode).reduce(wrap, id);\n return { encode, decode };\n}\n\n/**\n * Encodes integer radix representation to array of strings using alphabet and back.\n * Could also be array of strings.\n * @__NO_SIDE_EFFECTS__\n */\nfunction alphabet(letters: string | string[]): Coder<number[], string[]> {\n // mapping 1 to \"b\"\n const lettersA = typeof letters === 'string' ? letters.split('') : letters;\n const len = lettersA.length;\n astrArr('alphabet', lettersA);\n\n // mapping \"b\" to 1\n const indexes = new Map(lettersA.map((l, i) => [l, i]));\n return {\n encode: (digits: number[]) => {\n aArr(digits);\n return digits.map((i) => {\n if (!Number.isSafeInteger(i) || i < 0 || i >= len)\n throw new Error(\n `alphabet.encode: digit index outside alphabet \"${i}\". Allowed: ${letters}`\n );\n return lettersA[i]!;\n });\n },\n decode: (input: string[]): number[] => {\n aArr(input);\n return input.map((letter) => {\n astr('alphabet.decode', letter);\n const i = indexes.get(letter);\n if (i === undefined) throw new Error(`Unknown letter: \"${letter}\". Allowed: ${letters}`);\n return i;\n });\n },\n };\n}\n\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction join(separator = ''): Coder<string[], string> {\n astr('join', separator);\n // join('') is only lossless when each chunk is already unambiguous, such as single-symbol alphabets.\n // Multi-character tokens need a separator that cannot appear inside the chunks.\n return {\n encode: (from) => {\n astrArr('join.decode', from);\n return from.join(separator);\n },\n decode: (to) => {\n astr('join.decode', to);\n return to.split(separator);\n },\n };\n}\n\n/**\n * Pad strings array so it has integer number of bits\n * @__NO_SIDE_EFFECTS__\n */\nfunction padding(bits: number, chr = '='): Coder<string[], string[]> {\n anumber(bits);\n astr('padding', chr);\n return {\n encode(data: string[]): string[] {\n astrArr('padding.encode', data);\n // Mutates the intermediate token array in place while appending pad chars.\n // utils.padding callers that need to preserve their input should pass a copy.\n while ((data.length * bits) % 8) data.push(chr);\n return data;\n },\n decode(input: string[]): string[] {\n astrArr('padding.decode', input);\n let end = input.length;\n if ((end * bits) % 8)\n throw new Error('padding: invalid, string should have whole number of bytes');\n for (; end > 0 && input[end - 1] === chr; end--) {\n const last = end - 1;\n const byte = last * bits;\n if (byte % 8 === 0) throw new Error('padding: invalid, string has too much padding');\n }\n return input.slice(0, end);\n },\n };\n}\n\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction normalize<T>(fn: (val: T) => T): Coder<T, T> {\n afn(fn);\n return { encode: (from: T) => from, decode: (to: T) => fn(to) };\n}\n\n/**\n * Slow: O(n^2) time complexity\n */\nfunction convertRadix(data: number[], from: number, to: number): number[] {\n // base 1 is impossible\n if (from < 2)\n throw new RangeError(`convertRadix: invalid from=${from}, base cannot be less than 2`);\n if (to < 2) throw new RangeError(`convertRadix: invalid to=${to}, base cannot be less than 2`);\n aArr(data);\n if (!data.length) return [];\n let pos = 0;\n const res = [];\n const digits = Array.from(data, (d) => {\n anumber(d);\n if (d < 0 || d >= from) throw new Error(`invalid integer: ${d}`);\n return d;\n });\n const dlen = digits.length;\n while (true) {\n let carry = 0;\n let done = true;\n for (let i = pos; i < dlen; i++) {\n const digit = digits[i]!;\n const fromCarry = from * carry;\n const digitBase = fromCarry + digit;\n if (\n !Number.isSafeInteger(digitBase) ||\n fromCarry / from !== carry ||\n digitBase - digit !== fromCarry\n ) {\n throw new Error('convertRadix: carry overflow');\n }\n const div = digitBase / to;\n carry = digitBase % to;\n const rounded = Math.floor(div);\n digits[i] = rounded;\n if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)\n throw new Error('convertRadix: carry overflow');\n if (!done) continue;\n else if (!rounded) pos = i;\n else done = false;\n }\n res.push(carry);\n if (done) break;\n }\n // Preserve explicit leading zero digits so callers like base58 keep zero-prefix semantics.\n for (let i = 0; i < data.length - 1 && data[i] === 0; i++) res.push(0);\n return res.reverse();\n}\n\nconst gcd = (a: number, b: number): number => (b === 0 ? a : gcd(b, a % b));\n// Maximum carry width before the `pos` cycle repeats.\n// Residues advance in gcd(from, to) steps, so the largest pre-drain width is from + (to - gcd).\nconst radix2carry = /* @__NO_SIDE_EFFECTS__ */ (from: number, to: number) =>\n from + (to - gcd(from, to));\nconst powers: number[] = /* @__PURE__ */ (() => {\n let res = [];\n for (let i = 0; i < 40; i++) res.push(2 ** i);\n return res;\n})();\n/**\n * Implemented with numbers, because BigInt is 5x slower\n */\nfunction convertRadix2(data: number[], from: number, to: number, padding: boolean): number[] {\n aArr(data);\n if (from <= 0 || from > 32) throw new RangeError(`convertRadix2: wrong from=${from}`);\n if (to <= 0 || to > 32) throw new RangeError(`convertRadix2: wrong to=${to}`);\n if (radix2carry(from, to) > 32) {\n throw new Error(\n `convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`\n );\n }\n let carry = 0;\n let pos = 0; // bitwise position in current element\n const max = powers[from]!;\n const mask = powers[to]! - 1;\n const res: number[] = [];\n for (const n of data) {\n anumber(n);\n if (n >= max) throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);\n carry = (carry << from) | n;\n if (pos + from > 32) throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);\n pos += from;\n for (; pos >= to; pos -= to) res.push(((carry >> (pos - to)) & mask) >>> 0);\n const pow = powers[pos];\n if (pow === undefined) throw new Error('invalid carry');\n carry &= pow - 1; // clean carry, otherwise it will cause overflow\n }\n carry = (carry << (to - pos)) & mask;\n // Canonical decode paths reject leftover whole input words and non-zero pad bits.\n // For Bech32 5->8 regrouping, this is the \"4 bits or less, all zeroes\" tail rule.\n if (!padding && pos >= from) throw new Error('Excess padding');\n if (!padding && carry > 0) throw new Error(`Non-zero padding: ${carry}`);\n if (padding && pos > 0) res.push(carry >>> 0);\n return res;\n}\n\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction radix(num: number): TRet<Coder<Uint8Array, number[]>> {\n anumber(num);\n const _256 = 2 ** 8;\n // Base-range and carry-overflow checks live in convertRadix so encode/decode reject unsupported bases symmetrically.\n return {\n encode: (bytes: TArg<Uint8Array>) => {\n if (!isBytes(bytes)) throw new TypeError('radix.encode input should be Uint8Array');\n return convertRadix(Array.from(bytes), _256, num);\n },\n decode: (digits: number[]) => {\n anumArr('radix.decode', digits);\n return Uint8Array.from(convertRadix(digits, num, _256));\n },\n };\n}\n\n/**\n * If both bases are power of same number (like `2**8 <-> 2**64`),\n * there is a linear algorithm. For now we have implementation for power-of-two bases only.\n * @__NO_SIDE_EFFECTS__\n */\nfunction radix2(bits: number, revPadding = false): TRet<Coder<Uint8Array, number[]>> {\n anumber(bits);\n if (bits <= 0 || bits > 32) throw new RangeError('radix2: bits should be in (0..32]');\n if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)\n throw new RangeError('radix2: carry overflow');\n // revPadding flips which direction allows a partial zero tail.\n // Default pads 8->bits and rejects extra bits on bits->8; `true` does the opposite.\n return {\n encode: (bytes: TArg<Uint8Array>) => {\n if (!isBytes(bytes)) throw new TypeError('radix2.encode input should be Uint8Array');\n return convertRadix2(Array.from(bytes), 8, bits, !revPadding);\n },\n decode: (digits: number[]) => {\n anumArr('radix2.decode', digits);\n return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));\n },\n };\n}\n\ntype ArgumentTypes<F extends Function> = F extends (...args: infer A) => any ? A : never;\ntype BytesFn = (data: TArg<Uint8Array>) => TRet<Uint8Array>;\nfunction unsafeWrapper<T extends (...args: any) => any>(fn: T) {\n afn(fn);\n return function (...args: ArgumentTypes<T>): ReturnType<T> | void {\n // Only for *Unsafe APIs that intentionally collapse validation failures to `undefined`.\n // Do not wrap code that needs to preserve exception details.\n try {\n return fn.apply(null, args);\n } catch (e) {}\n };\n}\n\nfunction checksum(len: number, fn: TArg<BytesFn>): TRet<Coder<Uint8Array, Uint8Array>> {\n anumber(len);\n // Reject degenerate zero-byte checksums up front so callers don't accidentally\n // build a no-op checksum stage.\n if (len <= 0) throw new RangeError(`checksum length must be positive: ${len}`);\n afn(fn);\n const _fn = fn as BytesFn;\n // Uses the first `len` bytes of fn(data) in both directions.\n // Current call sites rely on `len > 0` and checksum functions that return at least that many bytes.\n return {\n encode(data: TArg<Uint8Array>) {\n if (!isBytes(data)) throw new TypeError('checksum.encode: input should be Uint8Array');\n const sum = _fn(data).slice(0, len);\n const res = new Uint8Array(data.length + len);\n res.set(data);\n res.set(sum, data.length);\n return res;\n },\n decode(data: TArg<Uint8Array>) {\n if (!isBytes(data)) throw new TypeError('checksum.decode: input should be Uint8Array');\n const payload = data.slice(0, -len);\n const oldChecksum = data.slice(-len);\n const newChecksum = _fn(payload).slice(0, len);\n for (let i = 0; i < len; i++)\n if (newChecksum[i] !== oldChecksum[i]) throw new Error('Invalid checksum');\n return payload;\n },\n };\n}\n\n// prettier-ignore\n/**\n * Low-level building blocks used by the exported codecs.\n * @example\n * Build a radix-32 coder from the low-level helpers.\n * ```ts\n * import { utils } from '@scure/base';\n * utils.radix2(5).encode(Uint8Array.from([1, 2, 3]));\n * ```\n */\nexport const utils: { alphabet: typeof alphabet; chain: typeof chain; checksum: typeof checksum; convertRadix: typeof convertRadix; convertRadix2: typeof convertRadix2; radix: typeof radix; radix2: typeof radix2; join: typeof join; padding: typeof padding; } = /* @__PURE__ */ Object.freeze({\n alphabet, chain, checksum, convertRadix, convertRadix2, radix, radix2, join, padding,\n});\n\n// RFC 4648 aka RFC 3548\n// ---------------------\n\n/**\n * base16 encoding from RFC 4648.\n * This codec uses RFC 4648 Table 5's uppercase alphabet directly.\n * RFC 4648 §8 calls base16 \"case-insensitive hex encoding\", but we intentionally do not case-fold decode input here.\n * Use `hex` for case-insensitive hex decoding.\n * @example\n * ```js\n * base16.encode(Uint8Array.from([0x12, 0xab]));\n * // => '12AB'\n * ```\n */\nexport const base16: BytesCoder = /* @__PURE__ */ Object.freeze(\n chain(radix2(4), alphabet('0123456789ABCDEF'), join(''))\n);\n\n/**\n * base32 encoding from RFC 4648. Has padding.\n * RFC 4648 §6 Table 3 uses uppercase letters, and RFC 4648 §3.4 allows applications to choose\n * upper- or lowercase alphabets. We keep the published uppercase table and do not case-fold decode input.\n * Use `base32nopad` for unpadded version.\n * Also check out `base32hex`, `base32hexnopad`, `base32crockford`.\n * @example\n * ```js\n * base32.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'CKVQ===='\n * base32.decode('CKVQ====');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32: BytesCoder = /* @__PURE__ */ Object.freeze(\n chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''))\n);\n\n/**\n * base32 encoding from RFC 4648. No padding.\n * This variant inherits RFC 4648 base32's uppercase table and intentionally does not case-fold decode input.\n * Use `base32` for padded version.\n * Also check out `base32hex`, `base32hexnopad`, `base32crockford`.\n * @example\n * ```js\n * base32nopad.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'CKVQ'\n * base32nopad.decode('CKVQ');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32nopad: BytesCoder = /* @__PURE__ */ Object.freeze(\n chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), join(''))\n);\n/**\n * base32 encoding from RFC 4648. Padded. Compared to ordinary `base32`, slightly different alphabet.\n * RFC 4648 §7 Table 4 uses uppercase letters, and we intentionally keep that table without case-folding decode input.\n * Use `base32hexnopad` for unpadded version.\n * @example\n * ```js\n * base32hex.encode(Uint8Array.from([0x12, 0xab]));\n * // => '2ALG===='\n * base32hex.decode('2ALG====');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32hex: BytesCoder = /* @__PURE__ */ Object.freeze(\n chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join(''))\n);\n\n/**\n * base32 encoding from RFC 4648. No padding. Compared to ordinary `base32`, slightly different alphabet.\n * This variant inherits RFC 4648 base32hex's uppercase table and intentionally does not case-fold decode input.\n * Use `base32hex` for padded version.\n * @example\n * ```js\n * base32hexnopad.encode(Uint8Array.from([0x12, 0xab]));\n * // => '2ALG'\n * base32hexnopad.decode('2ALG');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32hexnopad: BytesCoder = /* @__PURE__ */ Object.freeze(\n chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), join(''))\n);\n/**\n * base32 encoding from RFC 4648. Doug Crockford's version.\n * See {@link https://www.crockford.com/base32.html | Douglas Crockford's Base32}.\n * @example\n * ```js\n * base32crockford.encode(Uint8Array.from([0x12, 0xab]));\n * // => '2ANG'\n * base32crockford.decode('2ANG');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32crockford: BytesCoder = /* @__PURE__ */ Object.freeze(\n chain(\n radix2(5),\n alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'),\n join(''),\n normalize((s: string) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1'))\n )\n);\n\n// Built-in base64 conversion https://caniuse.com/mdn-javascript_builtins_uint8array_frombase64\n// Require both directions before taking the native fast path, so base64/base64url don't mix native and JS behavior.\n// prettier-ignore\nconst hasBase64Builtin: boolean = /* @__PURE__ */ (() =>\n typeof (Uint8Array as any).from([]).toBase64 === 'function' &&\n typeof (Uint8Array as any).fromBase64 === 'function')();\n\n// Native `Uint8Array.fromBase64()` accepts these ASCII whitespace chars.\n// Reject them first so the native base64 path still follows RFC 4648 §3.3.\n// ASCII whitespace is U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, or U+0020 SPACE\nconst ASCII_WHITESPACE = /[\\t\\n\\f\\r ]/;\n\nconst decodeBase64Builtin = (s: string, isUrl: boolean) => {\n astr('base64', s);\n const alphabet = isUrl ? 'base64url' : 'base64';\n // Per spec, .fromBase64 already throws on any other non-alphabet symbols except ASCII whitespace\n // And checking just for whitespace makes decoding about 3x faster than a full range check.\n // lastChunkHandling: 'strict' rejects loose tails and non-zero pad bits so native decoding stays canonical.\n if (s.length > 0 && ASCII_WHITESPACE.test(s)) throw new Error('invalid base64');\n return (Uint8Array as any).fromBase64(s, { alphabet, lastChunkHandling: 'strict' });\n};\n\n/**\n * base64 from RFC 4648. Padded.\n * Use `base64nopad` for unpadded version.\n * Also check out `base64url`, `base64urlnopad`.\n * Falls back to built-in function, when available.\n * @example\n * ```js\n * base64.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'Eqs='\n * base64.decode('Eqs=');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\n// prettier-ignore\nexport const base64: BytesCoder = /* @__PURE__ */ Object.freeze(hasBase64Builtin ? {\n encode(b) { abytes(b); return (b as any).toBase64(); },\n decode(s) { return decodeBase64Builtin(s, false); },\n} : chain(\n radix2(6),\n alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'),\n padding(6),\n join('')\n));\n/**\n * base64 from RFC 4648. No padding.\n * Use `base64` for padded version.\n * @example\n * ```js\n * base64nopad.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'Eqs'\n * base64nopad.decode('Eqs');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base64nopad: BytesCoder = /* @__PURE__ */ Object.freeze(\n chain(\n radix2(6),\n alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'),\n join('')\n )\n);\n\n/**\n * base64 from RFC 4648, using URL-safe alphabet. Padded.\n * Use `base64urlnopad` for unpadded version.\n * Falls back to built-in function, when available.\n * @example\n * ```js\n * base64url.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'Eqs='\n * base64url.decode('Eqs=');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\n// prettier-ignore\nexport const base64url: BytesCoder = /* @__PURE__ */ Object.freeze(hasBase64Builtin ? {\n encode(b) { abytes(b); return (b as any).toBase64({ alphabet: 'base64url' }); },\n decode(s) { return decodeBase64Builtin(s, true); },\n} : chain(\n radix2(6),\n alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'),\n padding(6),\n join('')\n));\n\n/**\n * base64 from RFC 4648, using URL-safe alphabet. No padding.\n * Use `base64url` for padded version.\n * @example\n * ```js\n * base64urlnopad.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'Eqs'\n * base64urlnopad.decode('Eqs');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base64urlnopad: BytesCoder = /* @__PURE__ */ Object.freeze(\n chain(\n radix2(6),\n alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'),\n join('')\n )\n);\n\n// base58 code\n// -----------\nconst genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc: string) =>\n chain(radix(58), alphabet(abc), join(''));\n\n/**\n * base58: base64 without ambigous characters +, /, 0, O, I, l.\n * Quadratic (O(n^2)) - so, can't be used on large inputs.\n * @example\n * ```js\n * const text = base58.encode(Uint8Array.from([0, 1, 2]));\n * base58.decode(text);\n * // => Uint8Array.from([0, 1, 2])\n * ```\n */\nexport const base58: BytesCoder = /* @__PURE__ */ Object.freeze(\n genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz')\n);\n/**\n * base58: flickr version. Check out `base58`.\n * @example\n * Round-trip bytes with the Flickr alphabet.\n * ```ts\n * const text = base58flickr.encode(Uint8Array.from([0, 1, 2]));\n * base58flickr.decode(text);\n * ```\n */\nexport const base58flickr: BytesCoder = /* @__PURE__ */ Object.freeze(\n genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ')\n);\n/**\n * base58: XRP version. Check out `base58`.\n * @example\n * Round-trip bytes with the XRP alphabet.\n * ```ts\n * const text = base58xrp.encode(Uint8Array.from([0, 1, 2]));\n * base58xrp.decode(text);\n * ```\n */\nexport const base58xrp: BytesCoder = /* @__PURE__ */ Object.freeze(\n genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz')\n);\n\n// Data len (index) -> encoded block len.\n// Monero pads each 1..8-byte block to this fixed base58 width so decode can recover the tail length.\nconst XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];\n\n/**\n * base58: XMR version. Check out `base58`.\n * Done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.\n * Block encoding significantly reduces quadratic complexity of base58.\n * @example\n * Round-trip bytes with the Monero block codec.\n * ```ts\n * const text = base58xmr.encode(Uint8Array.from([0, 1, 2]));\n * base58xmr.decode(text);\n * ```\n */\nexport const base58xmr: BytesCoder = /* @__PURE__ */ Object.freeze({\n encode(data: TArg<Uint8Array>) {\n abytes(data);\n let res = '';\n for (let i = 0; i < data.length; i += 8) {\n const block = data.subarray(i, i + 8);\n res += base58.encode(block).padStart(XMR_BLOCK_LEN[block.length]!, '1');\n }\n return res;\n },\n decode(str: string) {\n astr('base58xmr.decode', str);\n let res: number[] = [];\n for (let i = 0; i < str.length; i += 11) {\n const slice = str.slice(i, i + 11);\n const blockLen = XMR_BLOCK_LEN.indexOf(slice.length);\n const block = base58.decode(slice);\n for (let j = 0; j < block.length - blockLen; j++) {\n if (block[j] !== 0) throw new Error('base58xmr: wrong padding');\n }\n res = res.concat(Array.from(block.slice(block.length - blockLen)));\n }\n return Uint8Array.from(res);\n },\n});\n\n/**\n * Method, which creates base58check encoder.\n * Requires function, calculating sha256.\n * Callers must include any version bytes in `data`; this helper only applies the\n * 4-byte double-SHA256 checksum used by Bitcoin Base58Check.\n * @param sha256 - Function used to calculate the checksum hash.\n * @returns base58check codec using 4 checksum bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Create a base58check codec from a SHA-256 implementation.\n * ```ts\n * import { createBase58check } from '@scure/base';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const coder = createBase58check(sha256);\n * coder.encode(Uint8Array.from([1, 2, 3]));\n * ```\n */\nexport const createBase58check = (sha256: TArg<BytesFn>): BytesCoder => {\n // Validate the hash function at construction time so wrong inputs fail before returning a coder.\n afn(sha256);\n const _sha256 = sha256 as BytesFn;\n return chain(\n checksum(4, (data: TArg<Uint8Array>) => _sha256(_sha256(data))),\n base58\n );\n};\n\n/**\n * Use `createBase58check` instead.\n * @deprecated Use {@link createBase58check} instead.\n * Callers must include any version bytes in `data`; this alias keeps the same\n * 4-byte double-SHA256 checksum behavior as `createBase58check`.\n * @param sha256 - Function used to calculate the checksum hash.\n * @returns base58check codec using 4 checksum bytes.\n * @example\n * Create a base58check codec with the deprecated alias.\n * ```ts\n * import { base58check } from '@scure/base';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const coder = base58check(sha256);\n * coder.encode(Uint8Array.from([1, 2, 3]));\n * ```\n */\nexport const base58check: (sha256: TArg<BytesFn>) => BytesCoder = createBase58check;\n\n// Bech32 code\n// -----------\n/** Result of bech32 decoding. */\nexport interface Bech32Decoded<Prefix extends string = string> {\n /** Human-readable bech32 prefix. */\n prefix: Prefix;\n /** Decoded 5-bit word payload. */\n words: number[];\n}\n/** Result of bech32 decoding with original bytes attached. */\nexport interface Bech32DecodedWithArray<Prefix extends string = string> {\n /** Human-readable bech32 prefix. */\n prefix: Prefix;\n /** Decoded 5-bit word payload. */\n words: number[];\n /** Decoded payload converted back into raw bytes. */\n bytes: Uint8Array;\n}\n\n// BIP 173 character table: data values 0..31 map to `qpzry9x8gf2tvdw0s3jn54khce6mua7l`.\nconst BECH_ALPHABET: Coder<number[], string> = chain(\n alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'),\n join('')\n);\n\n// BIP 173 `bech32_polymod` GEN coefficients.\nconst POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];\n// BIP 173 step split: this applies the polymod state transition before callers xor in the next 5-bit value.\nfunction bech32Polymod(pre: number): number {\n const b = pre >> 25;\n let chk = (pre & 0x1ffffff) << 5;\n for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {\n if (((b >> i) & 1) === 1) chk ^= POLYMOD_GENERATORS[i]!;\n }\n return chk;\n}\n\nfunction bechChecksum(prefix: string, words: number[], encodingConst = 1): string {\n const len = prefix.length;\n let chk = 1;\n for (let i = 0; i < len; i++) {\n const c = prefix.charCodeAt(i);\n if (c < 33 || c > 126) throw new Error(`Invalid prefix (${prefix})`);\n chk = bech32Polymod(chk) ^ (c >> 5);\n }\n chk = bech32Polymod(chk);\n for (let i = 0; i < len; i++) chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);\n for (let v of words) chk = bech32Polymod(chk) ^ v;\n for (let i = 0; i < 6; i++) chk = bech32Polymod(chk);\n // BIP 173/BIP 350: xor the final checksum constant, then emit the 30-bit state as six 5-bit symbols.\n chk ^= encodingConst;\n return BECH_ALPHABET.encode(convertRadix2([chk % powers[30]!], 30, 5, false));\n}\n\n/** bech32 codec surface. */\nexport interface Bech32 {\n /**\n * Encodes a human-readable prefix and 5-bit words into a bech32 string.\n * @param prefix - Human-readable prefix.\n * @param words - 5-bit words or raw bytes.\n * @param limit - Maximum accepted output length, or `false` to disable the limit.\n * @returns Encoded bech32 string.\n */\n encode<Prefix extends string>(\n prefix: Prefix,\n words: number[] | Uint8Array,\n limit?: number | false\n ): `${Lowercase<Prefix>}1${string}`;\n /**\n * Decodes a bech32 string into prefix and words.\n * @param str - Encoded bech32 string.\n * @param limit - Maximum accepted input length, or `false` to disable the limit.\n * @returns Decoded prefix and 5-bit words.\n */\n decode<Prefix extends string>(\n str: `${Prefix}1${string}`,\n limit?: number | false\n ): Bech32Decoded<Prefix>;\n decode(str: string, limit?: number | false): Bech32Decoded;\n /**\n * Encodes raw bytes by first converting them to 5-bit words.\n * @param prefix - Human-readable prefix.\n * @param bytes - Raw bytes to encode.\n * @returns Encoded bech32 string.\n */\n encodeFromBytes(prefix: string, bytes: Uint8Array): string;\n /**\n * Decodes a bech32 string and converts the payload back into bytes.\n * @param str - Encoded bech32 string.\n * @returns Decoded prefix, words, and bytes.\n */\n decodeToBytes(str: string): Bech32DecodedWithArray;\n /**\n * Decodes a bech32 string, returning `undefined` instead of throwing on invalid input.\n * @param str - Encoded bech32 string.\n * @param limit - Maximum accepted input length, or `false` to disable the limit.\n * @returns Decoded prefix and words, or `undefined` for invalid input.\n */\n decodeUnsafe(str: string, limit?: number | false): void | Bech32Decoded<string>;\n /**\n * Converts 5-bit words back into raw bytes.\n * @param to - 5-bit words to decode.\n * @returns Decoded bytes.\n */\n fromWords(to: number[]): Uint8Array;\n /**\n * Converts 5-bit words back into raw bytes, returning `undefined` instead of throwing.\n * @param to - 5-bit words to decode.\n * @returns Decoded bytes, or `undefined` for invalid input.\n */\n fromWordsUnsafe(to: number[]): void | Uint8Array;\n /**\n * Converts raw bytes into 5-bit words for bech32 encoding.\n * @param from - Raw bytes to convert.\n * @returns 5-bit words.\n */\n toWords(from: Uint8Array): number[];\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction genBech32(encoding: 'bech32' | 'bech32m'): TRet<Bech32> {\n // BIP 173 uses final xor constant 1; BIP 350 swaps in 0x2bc830a3 for Bech32m.\n const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;\n const _words = radix2(5);\n const fromWords = _words.decode;\n const toWords = _words.encode;\n const fromWordsUnsafe = unsafeWrapper(fromWords);\n\n function encode<Prefix extends string>(\n prefix: Prefix,\n words: TArg<number[] | Uint8Array>,\n limit: number | false = 90\n ): `${Lowercase<Prefix>}1${string}` {\n astr('bech32.encode prefix', prefix);\n if (isBytes(words)) words = Array.from(words);\n anumArr('bech32.encode', words);\n const plen = prefix.length;\n if (plen === 0) throw new TypeError(`Invalid prefix length ${plen}`);\n // Total output is hrp + `1` separator + payload words + 6 checksum chars.\n const actualLength = plen + 7 + words.length;\n if (limit !== false && actualLength > limit)\n throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);\n const lowered = prefix.toLowerCase();\n const sum = bechChecksum(lowered, words, ENCODING_CONST);\n return `${lowered}1${BECH_ALPHABET.encode(words)}${sum}` as `${Lowercase<Prefix>}1${string}`;\n }\n\n function decode<Prefix extends string>(\n str: `${Prefix}1${string}`,\n limit?: number | false\n ): Bech32Decoded<Prefix>;\n function decode(str: string, limit?: number | false): Bech32Decoded;\n function decode(str: string, limit: number | false = 90): Bech32Decoded {\n astr('bech32.decode input', str);\n const slen = str.length;\n // Minimum length is 1-char hrp + `1` separator + 6-char checksum.\n if (slen < 8 || (limit !== false && slen > limit))\n throw new TypeError(`invalid string length: ${slen} (${str}). Expected (8..${limit})`);\n // don't allow mixed case\n const lowered = str.toLowerCase();\n if (str !== lowered && str !== str.toUpperCase())\n throw new Error(`String must be lowercase or uppercase`);\n const sepIndex = lowered.lastIndexOf('1');\n if (sepIndex === 0 || sepIndex === -1)\n throw new Error(`Letter \"1\" must be present between prefix and data only`);\n const prefix = lowered.slice(0, sepIndex);\n const data = lowered.slice(sepIndex + 1);\n if (data.length < 6) throw new Error('Data must be at least 6 characters long');\n const words = BECH_ALPHABET.decode(data).slice(0, -6);\n const sum = bechChecksum(prefix, words, ENCODING_CONST);\n if (!data.endsWith(sum)) throw new Error(`Invalid checksum in ${str}: expected \"${sum}\"`);\n return { prefix, words };\n }\n\n const decodeUnsafe = unsafeWrapper(decode);\n\n function decodeToBytes(str: string): TRet<Bech32DecodedWithArray> {\n // Keep the byte helper unbounded; callers that need the default BIP 173 length cap should use decode(str).\n const { prefix, words } = decode(str, false);\n return {\n prefix,\n words,\n bytes: fromWords(words) as TRet<Uint8Array>,\n } as TRet<Bech32DecodedWithArray>;\n }\n\n function encodeFromBytes(prefix: string, bytes: TArg<Uint8Array>) {\n // Keep the convenience wrapper on encode()'s default 90-char cap; custom limits should call encode(prefix, toWords(bytes), limit).\n return encode(prefix, toWords(bytes));\n }\n\n return {\n encode,\n decode,\n encodeFromBytes,\n decodeToBytes,\n decodeUnsafe,\n fromWords,\n fromWordsUnsafe,\n toWords,\n };\n}\n\n/**\n * bech32 from BIP 173. Operates on words.\n * For high-level helpers, check out {@link https://github.com/paulmillr/scure-btc-signer | scure-btc-signer}.\n * @example\n * Convert bytes to words, encode them, then decode back.\n * ```ts\n * const words = bech32.toWords(Uint8Array.from([1, 2, 3]));\n * const text = bech32.encode('bc', words);\n * bech32.decode(text);\n * ```\n */\nexport const bech32: TRet<Bech32> = /* @__PURE__ */ Object.freeze(genBech32('bech32'));\n\n/**\n * bech32m from BIP 350. Operates on words.\n * It was to mitigate `bech32` weaknesses.\n * For high-level helpers, check out {@link https://github.com/paulmillr/scure-btc-signer | scure-btc-signer}.\n * @example\n * Convert bytes to words, encode them with bech32m, then decode back.\n * ```ts\n * const words = bech32m.toWords(Uint8Array.from([1, 2, 3]));\n * const text = bech32m.encode('bc', words);\n * bech32m.decode(text);\n * ```\n */\nexport const bech32m: TRet<Bech32> = /* @__PURE__ */ Object.freeze(genBech32('bech32m'));\n\ndeclare const TextEncoder: any;\ndeclare const TextDecoder: any;\n\n/**\n * ASCII-to-byte decoder. Rejects non-ASCII text and bytes instead of doing UTF-8 replacement.\n * Method names follow `BytesCoder`, so `encode(bytes)` returns a string and `decode(string)` returns bytes.\n * @example\n * ```js\n * const b = ascii.decode(\"ABC\"); // => new Uint8Array([ 65, 66, 67 ])\n * const str = ascii.encode(b); // \"ABC\"\n * ```\n */\nexport const ascii: TRet<BytesCoder> = /* @__PURE__ */ Object.freeze({\n encode(data: TArg<Uint8Array>) {\n abytes(data);\n let res = '';\n for (let i = 0; i < data.length; i++) {\n const byte = data[i]!;\n // ASCII is 7-bit; reject bytes outside 0x00..0x7f instead of silently widening to\n // Latin-1/UTF-8.\n if (byte > 127) throw new RangeError(`bytes contain non-ASCII byte ${byte} at position ${i}`);\n res += String.fromCharCode(byte);\n }\n return res;\n },\n decode(str: string) {\n if (typeof str !== 'string') throw new TypeError('ascii string expected, got ' + typeof str);\n const res = new Uint8Array(str.length);\n for (let i = 0; i < str.length; i++) {\n // Indexed access is much faster than Uint8Array.from(str, mapFn) here and keeps\n // exact error positions.\n const charCode = str.charCodeAt(i);\n if (charCode > 127) {\n throw new RangeError(\n `string contains non-ASCII character \"${str[i]}\" with code ${charCode} at position ${i}`\n );\n }\n res[i] = charCode;\n }\n return res;\n },\n});\n\nconst _isWellFormedShim = (str: string): boolean => {\n // encodeURI rejects malformed UTF-16, giving a compact fallback that matches native\n // isWellFormed on our tests/fuzz corpus.\n try {\n return encodeURI(str) !== null;\n } catch {\n return false;\n }\n};\nconst _isWellFormed: (str: string) => boolean = /* @__PURE__ */ (() =>\n // Pick the native check once so utf8.decode doesn't re-probe String.prototype on every call.\n typeof ('' as any).isWellFormed === 'function'\n ? (str) => (str as any).isWellFormed()\n : _isWellFormedShim)();\n// This fallback stays small because strict UTF-8 only needs fatal decoding plus well-formed\n// UTF-16 checks, not the replacement, streaming, or legacy-encoding behavior of full platform\n// text codecs.\nconst utf8Fallback: BytesCoder = /* @__PURE__ */ Object.freeze({\n encode(data: TArg<Uint8Array>) {\n abytes(data);\n let res = '';\n for (let i = 0; i < data.length; ) {\n const a = data[i++]!;\n if (a < 0b1000_0000) {\n res += String.fromCharCode(a);\n continue;\n }\n if (a < 0b1100_0010 || i >= data.length) throw new TypeError(`invalid utf8 at byte ${i - 1}`);\n const b = data[i++]!;\n if ((b & 0b1100_0000) !== 0b1000_0000) throw new TypeError(`invalid utf8 at byte ${i - 1}`);\n let cp = ((a & 0b0001_1111) << 6) | (b & 0b0011_1111);\n if (a >= 0b1110_0000) {\n if (i >= data.length) throw new TypeError(`invalid utf8 at byte ${i - 1}`);\n const c = data[i++]!;\n if (\n (c & 0b1100_0000) !== 0b1000_0000 ||\n (a === 0b1110_0000 && b < 0b1010_0000) ||\n (a === 0xed && b >= 0b1010_0000)\n )\n throw new TypeError(`invalid utf8 at byte ${i - 1}`);\n cp = ((a & 0b0000_1111) << 12) | ((b & 0b0011_1111) << 6) | (c & 0b0011_1111);\n if (a >= 0b1111_0000) {\n if (i >= data.length) throw new TypeError(`invalid utf8 at byte ${i - 1}`);\n const d = data[i++]!;\n if (\n a > 0b1111_0100 ||\n (d & 0b1100_0000) !== 0b1000_0000 ||\n (a === 0b1111_0000 && b < 0b1001_0000) ||\n (a === 0b1111_0100 && b >= 0b1001_0000)\n )\n throw new TypeError(`invalid utf8 at byte ${i - 1}`);\n cp =\n ((a & 7) << 18) |\n ((b & 0b0011_1111) << 12) |\n ((c & 0b0011_1111) << 6) |\n (d & 0b0011_1111);\n }\n }\n if (cp < 0x10000) res += String.fromCharCode(cp);\n else {\n cp -= 0x10000;\n res += String.fromCharCode((cp >> 10) + 0xd800, (cp & 0x3ff) + 0xdc00);\n }\n }\n return res;\n },\n decode(str: string) {\n astr('utf8', str);\n if (!_isWellFormed(str)) throw new TypeError('utf8 expected well-formed string');\n // Direct Uint8Array writes are much faster than number[] + Uint8Array.from on Hermes and\n // large Node inputs.\n const res = new Uint8Array(str.length * 3);\n let pos = 0;\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i);\n if (c < 0b1000_0000) {\n res[pos++] = c;\n continue;\n }\n if (c >= 0xd800 && c <= 0xdfff) {\n const d = str.charCodeAt(++i);\n c = 0x10000 + ((c - 0xd800) << 10) + d - 0xdc00;\n }\n if (c >= 0x10000) {\n res[pos++] = (c >> 18) | 0b1111_0000;\n res[pos++] = ((c >> 12) & 0b0011_1111) | 0b1000_0000;\n } else if (c >= 0x800) res[pos++] = (c >> 12) | 0b1110_0000;\n else res[pos++] = (c >> 6) | 0b1100_0000;\n if (c >= 0x800) res[pos++] = ((c >> 6) & 0b0011_1111) | 0b1000_0000;\n res[pos++] = (c & 0b0011_1111) | 0b1000_0000;\n }\n return res.subarray(0, pos);\n },\n});\n\n/**\n * Strict UTF-8-to-byte decoder. Uses built-in TextDecoder / TextEncoder when available.\n * Method names follow `BytesCoder`, so `encode(bytes)` returns a string and\n * `decode(string)` returns bytes.\n * `encode(bytes)` requires Uint8Array input, preserves an explicit leading BOM, and\n * throws on invalid UTF-8 bytes.\n * `decode(string)` requires a primitive string and throws on malformed UTF-16 strings with\n * lone surrogates.\n * @example\n * ```js\n * const b = utf8.decode(\"hey\"); // => new Uint8Array([ 104, 101, 121 ])\n * const str = utf8.encode(b); // \"hey\"\n * ```\n */\nexport const utf8: BytesCoder = /* @__PURE__ */ (() => {\n let _utf8Encoder: any;\n let _utf8Decoder: any;\n const utf8Builtin: BytesCoder = {\n // ignoreBOM preserves an explicit leading U+FEFF;\n // fatal rejects invalid UTF-8 bytes instead of replacing them.\n encode(data) {\n abytes(data);\n return (\n _utf8Decoder || (_utf8Decoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }))\n ).decode(data);\n },\n decode(str) {\n astr('utf8', str);\n if (!_isWellFormed(str)) throw new TypeError('utf8 expected well-formed string');\n return (_utf8Encoder || (_utf8Encoder = new TextEncoder())).encode(str);\n },\n };\n return Object.freeze({\n // Select each direction once at module init, since\n // TextEncoder and TextDecoder can exist independently.\n encode: typeof TextDecoder === 'function' ? utf8Builtin.encode : utf8Fallback.encode,\n decode: typeof TextEncoder === 'function' ? utf8Builtin.decode : utf8Fallback.decode,\n });\n})();\n// Keep fallback parity probes behind a test-only export until runtime fallback behavior is decided.\nexport const __TESTS: {\n utf8Fallback: BytesCoder;\n _isWellFormedShim: (str: string) => boolean;\n} = /* @__PURE__ */ Object.freeze({\n utf8Fallback: utf8Fallback,\n _isWellFormedShim: _isWellFormedShim,\n});\n\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\n// prettier-ignore\nconst hasHexBuiltin: boolean = /* @__PURE__ */ (() =>\n // Require both directions before enabling the native hex path so encode/decode stay symmetric.\n typeof (Uint8Array as any).from([]).toHex === 'function' &&\n typeof (Uint8Array as any).fromHex === 'function')();\n// prettier-ignore\nconst hexBuiltin: BytesCoder = {\n // Keep local type guards so the native path preserves library-level input errors.\n // Native toHex emits lowercase hex, matching the fallback alphabet and Node's hex strings.\n encode(data) { abytes(data); return (data as any).toHex(); },\n // Native fromHex accepts either hex case and rejects odd-length / non-hex syntax.\n decode(s) { astr('hex', s); return (Uint8Array as any).fromHex(s); },\n};\n/**\n * hex string decoder. Uses built-in function, when available.\n * Lowercase codec; unlike `base16`, this variant accepts either hex case and emits lowercase.\n * @example\n * ```js\n * const b = hex.decode(\"0102ff\"); // => new Uint8Array([ 1, 2, 255 ])\n * const str = hex.encode(b); // \"0102ff\"\n * ```\n */\nexport const hex: BytesCoder = /* @__PURE__ */ Object.freeze(\n hasHexBuiltin\n ? hexBuiltin\n : chain(\n radix2(4),\n alphabet('0123456789abcdef'),\n join(''),\n normalize((s: string) => {\n if (typeof s !== 'string' || s.length % 2 !== 0)\n throw new TypeError(\n `hex.decode: expected string, got ${typeof s} with length ${s.length}`\n );\n return s.toLowerCase();\n })\n )\n);\n\n/** Built-in codecs exposed through the deprecated string conversion helpers. */\nexport type SomeCoders = {\n /** UTF-8 string codec. */\n utf8: BytesCoder;\n /** Hex codec. */\n hex: BytesCoder;\n /** Uppercase RFC 4648 base16 codec. */\n base16: BytesCoder;\n /** RFC 4648 base32 codec with padding. */\n base32: BytesCoder;\n /** RFC 4648 base64 codec with padding. */\n base64: BytesCoder;\n /** URL-safe base64 codec without `+` or `/`. */\n base64url: BytesCoder;\n /** Bitcoin-style base58 codec. */\n base58: BytesCoder;\n /** Monero-style base58 codec. */\n base58xmr: BytesCoder;\n};\n// prettier-ignore\n// Keep this registry aligned with CoderType/coderTypeError; only byte<->string codecs belong here.\nconst CODERS: SomeCoders = {\n utf8, hex, base16, base32, base64, base64url, base58, base58xmr\n};\ntype CoderType = keyof SomeCoders;\nconst coderTypeError =\n 'Invalid encoding type. Available types: utf8, hex, base16, base32, base64, base64url, base58, base58xmr';\n\n/**\n * Encodes bytes with one of the built-in codecs.\n * @deprecated Use the codec directly, for example `hex.encode(bytes)`.\n * @param type - Codec name.\n * @param bytes - Bytes to encode.\n * @returns Encoded string.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * ```ts\n * bytesToString('hex', Uint8Array.from([1, 2, 255]));\n * ```\n */\nexport const bytesToString = (type: CoderType, bytes: TArg<Uint8Array>): string => {\n if (typeof type !== 'string' || !CODERS.hasOwnProperty(type)) throw new TypeError(coderTypeError);\n if (!isBytes(bytes)) throw new TypeError('bytesToString() expects Uint8Array');\n return CODERS[type].encode(bytes);\n};\n\n/**\n * Alias for `bytesToString`.\n * @deprecated Use {@link bytesToString} or the codec directly instead.\n * @param type - Codec name.\n * @param bytes - Bytes to encode.\n * @returns Encoded string.\n * @example\n * ```ts\n * str('hex', Uint8Array.from([1, 2, 255]));\n * ```\n */\nexport const str: (type: CoderType, bytes: TArg<Uint8Array>) => string = bytesToString; // as in python, but for bytes only\n\n/**\n * Decodes a string with one of the built-in codecs.\n * @deprecated Use the codec directly, for example `hex.decode(text)`.\n * @param type - Codec name.\n * @param str - Encoded string.\n * @returns Decoded bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * ```ts\n * stringToBytes('hex', '0102ff');\n * ```\n */\nexport const stringToBytes = (type: CoderType, str: string): TRet<Uint8Array> => {\n // Match bytesToString's selector validation so hostile `toString()` coercions can't leak custom errors.\n if (typeof type !== 'string' || !CODERS.hasOwnProperty(type)) throw new TypeError(coderTypeError);\n if (typeof str !== 'string') throw new TypeError('stringToBytes() expects string');\n return CODERS[type].decode(str) as TRet<Uint8Array>;\n};\n/**\n * Alias for `stringToBytes`.\n * @deprecated Use {@link stringToBytes} or the codec directly instead.\n * @param type - Codec name.\n * @param str - Encoded string.\n * @returns Decoded bytes.\n * @example\n * ```ts\n * bytes('hex', '0102ff');\n * ```\n */\nexport const bytes: (type: CoderType, str: string) => TRet<Uint8Array> = stringToBytes;\n","/**\n * @otplib/plugin-base32-scure\n *\n * Base32 plugin for otplib using @scure/base.\n * Works universally across all JavaScript runtimes.\n */\n\nimport { base32 as scureBase32 } from \"@scure/base\";\n\nimport type { Base32EncodeOptions } from \"@otplib/core\";\nimport type { Base32Plugin } from \"@otplib/core\";\n\n/**\n * Scure Base32 plugin\n *\n * This implementation uses @scure/base for Base32 encoding/decoding.\n * @scure/base is a modern, audited cryptography library with zero dependencies.\n *\n * @example\n * ```ts\n * import { ScureBase32Plugin } from '@otplib/plugin-base32-scure';\n *\n * const plugin = new ScureBase32Plugin();\n * const encoded = plugin.encode(data);\n * const decoded = plugin.decode(encoded);\n * ```\n */\nexport class ScureBase32Plugin implements Base32Plugin {\n readonly name = \"scure\";\n\n /**\n * Encode binary data to Base32 string\n *\n * @param data - Uint8Array to encode\n * @param options - Encoding options\n * @returns Base32 encoded string\n */\n encode(data: Uint8Array, options: Base32EncodeOptions = {}): string {\n const { padding = false } = options;\n\n const encoded = scureBase32.encode(data);\n return padding ? encoded : encoded.replace(/=+$/, \"\");\n }\n\n /**\n * Decode Base32 string to binary data\n *\n * @param str - Base32 string to decode\n * @returns Decoded Uint8Array\n * @throws {Error} If string contains invalid characters\n */\n decode(str: string): Uint8Array {\n try {\n const uppercased = str.toUpperCase();\n const padded = uppercased.padEnd(Math.ceil(uppercased.length / 8) * 8, \"=\");\n return scureBase32.decode(padded);\n } catch (error) {\n // @scure/base always throws Error instances; cast keeps the catch branchless.\n throw new Error(`Invalid Base32 string: ${(error as Error).message}`);\n }\n }\n}\n\n/**\n * Default singleton instance for convenience\n *\n * @example\n * ```ts\n * import { base32 } from '@otplib/plugin-base32-scure';\n *\n * const encoded = base32.encode(data);\n * ```\n */\nexport const base32: Base32Plugin = Object.freeze(new ScureBase32Plugin());\n\nexport default ScureBase32Plugin;\n","/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n/**\n * Bytes API type helpers for old + new TypeScript.\n *\n * TS 5.6 has `Uint8Array`, while TS 5.9+ made it generic `Uint8Array<ArrayBuffer>`.\n * We can't use specific return type, because TS 5.6 will error.\n * We can't use generic return type, because most TS 5.9 software will expect specific type.\n *\n * Maps typed-array input leaves to broad forms.\n * These are compatibility adapters, not ownership guarantees.\n *\n * - `TArg` keeps byte inputs broad.\n * - `TRet` marks byte outputs for TS 5.6 and TS 5.9+ compatibility.\n */\nexport type TypedArg<T> = T extends BigInt64Array\n ? BigInt64Array\n : T extends BigUint64Array\n ? BigUint64Array\n : T extends Float32Array\n ? Float32Array\n : T extends Float64Array\n ? Float64Array\n : T extends Int16Array\n ? Int16Array\n : T extends Int32Array\n ? Int32Array\n : T extends Int8Array\n ? Int8Array\n : T extends Uint16Array\n ? Uint16Array\n : T extends Uint32Array\n ? Uint32Array\n : T extends Uint8ClampedArray\n ? Uint8ClampedArray\n : T extends Uint8Array\n ? Uint8Array\n : never;\n/** Maps typed-array output leaves to narrow TS-compatible forms. */\nexport type TypedRet<T> = T extends BigInt64Array\n ? ReturnType<typeof BigInt64Array.of>\n : T extends BigUint64Array\n ? ReturnType<typeof BigUint64Array.of>\n : T extends Float32Array\n ? ReturnType<typeof Float32Array.of>\n : T extends Float64Array\n ? ReturnType<typeof Float64Array.of>\n : T extends Int16Array\n ? ReturnType<typeof Int16Array.of>\n : T extends Int32Array\n ? ReturnType<typeof Int32Array.of>\n : T extends Int8Array\n ? ReturnType<typeof Int8Array.of>\n : T extends Uint16Array\n ? ReturnType<typeof Uint16Array.of>\n : T extends Uint32Array\n ? ReturnType<typeof Uint32Array.of>\n : T extends Uint8ClampedArray\n ? ReturnType<typeof Uint8ClampedArray.of>\n : T extends Uint8Array\n ? ReturnType<typeof Uint8Array.of>\n : never;\n/** Recursively adapts byte-carrying API input types. See {@link TypedArg}. */\nexport type TArg<T> =\n | T\n | ([TypedArg<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TRet<A[K]> }) => TArg<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TArg<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends (infer A)[]\n ? TArg<A>[]\n : T extends readonly (infer A)[]\n ? readonly TArg<A>[]\n : T extends Promise<infer A>\n ? Promise<TArg<A>>\n : T extends object\n ? { [K in keyof T]: TArg<T[K]> }\n : T\n : TypedArg<T>);\n/** Recursively adapts byte-carrying API output types. See {@link TypedArg}. */\nexport type TRet<T> = T extends unknown\n ? T &\n ([TypedRet<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TArg<A[K]> }) => TRet<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TRet<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends (infer A)[]\n ? TRet<A>[]\n : T extends readonly (infer A)[]\n ? readonly TRet<A>[]\n : T extends Promise<infer A>\n ? Promise<TRet<A>>\n : T extends object\n ? { [K in keyof T]: TRet<T[K]> }\n : T\n : TypedRet<T>)\n : never;\n/**\n * Checks if something is Uint8Array. Be careful: nodejs Buffer will return true.\n * @param a - value to test\n * @returns `true` when the value is a Uint8Array-compatible view.\n * @example\n * Check whether a value is a Uint8Array-compatible view.\n * ```ts\n * isBytes(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport function isBytes(a: unknown): a is Uint8Array {\n // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / cross-realm cases.\n // The fallback still requires a real ArrayBuffer view, so plain\n // JSON-deserialized `{ constructor: ... }` spoofing is rejected, and\n // `BYTES_PER_ELEMENT === 1` keeps the fallback on byte-oriented views.\n return (\n a instanceof Uint8Array ||\n (ArrayBuffer.isView(a) &&\n a.constructor.name === 'Uint8Array' &&\n 'BYTES_PER_ELEMENT' in a &&\n a.BYTES_PER_ELEMENT === 1)\n );\n}\n\n/**\n * Asserts something is a non-negative integer.\n * @param n - number to validate\n * @param title - label included in thrown errors\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validate a non-negative integer option.\n * ```ts\n * anumber(32, 'length');\n * ```\n */\nexport function anumber(n: number, title: string = ''): void {\n if (typeof n !== 'number') {\n const prefix = title && `\"${title}\" `;\n throw new TypeError(`${prefix}expected number, got ${typeof n}`);\n }\n if (!Number.isSafeInteger(n) || n < 0) {\n const prefix = title && `\"${title}\" `;\n throw new RangeError(`${prefix}expected integer >= 0, got ${n}`);\n }\n}\n\n/**\n * Asserts something is Uint8Array.\n * @param value - value to validate\n * @param length - optional exact length constraint\n * @param title - label included in thrown errors\n * @returns The validated byte array.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validate that a value is a byte array.\n * ```ts\n * abytes(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport function abytes(\n value: TArg<Uint8Array>,\n length?: number,\n title: string = ''\n): TRet<Uint8Array> {\n const bytes = isBytes(value);\n const len = value?.length;\n const needsLen = length !== undefined;\n if (!bytes || (needsLen && len !== length)) {\n const prefix = title && `\"${title}\" `;\n const ofLen = needsLen ? ` of length ${length}` : '';\n const got = bytes ? `length=${len}` : `type=${typeof value}`;\n const message = prefix + 'expected Uint8Array' + ofLen + ', got ' + got;\n if (!bytes) throw new TypeError(message);\n throw new RangeError(message);\n }\n return value as TRet<Uint8Array>;\n}\n\n/**\n * Copies bytes into a fresh Uint8Array.\n * Buffer-style slices can alias the same backing store, so callers that need ownership should copy.\n * @param bytes - source bytes to clone\n * @returns Freshly allocated copy of `bytes`.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Clone a byte array before mutating it.\n * ```ts\n * const copy = copyBytes(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport function copyBytes(bytes: TArg<Uint8Array>): TRet<Uint8Array> {\n // `Uint8Array.from(...)` would also accept arrays / other typed arrays. Keep this helper strict\n // because callers use it at byte-validation boundaries before mutating the detached copy.\n return Uint8Array.from(abytes(bytes)) as TRet<Uint8Array>;\n}\n\n/**\n * Asserts something is a wrapped hash constructor.\n * @param h - hash constructor to validate\n * @throws On wrong argument types or invalid hash wrapper shape. {@link TypeError}\n * @throws On invalid hash metadata ranges or values. {@link RangeError}\n * @throws If the hash metadata allows empty outputs or block sizes. {@link Error}\n * @example\n * Validate a callable hash wrapper.\n * ```ts\n * import { ahash } from '@noble/hashes/utils.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * ahash(sha256);\n * ```\n */\nexport function ahash(h: TArg<CHash>): void {\n if (typeof h !== 'function' || typeof h.create !== 'function')\n throw new TypeError('Hash must wrapped by utils.createHasher');\n anumber(h.outputLen);\n anumber(h.blockLen);\n // HMAC and KDF callers treat these as real byte lengths; allowing zero lets fake wrappers pass\n // validation and can produce empty outputs instead of failing fast.\n if (h.outputLen < 1) throw new Error('\"outputLen\" must be >= 1');\n if (h.blockLen < 1) throw new Error('\"blockLen\" must be >= 1');\n}\n\n/**\n * Asserts a hash instance has not been destroyed or finished.\n * @param instance - hash instance to validate\n * @param checkFinished - whether to reject finalized instances\n * @throws If the hash instance has already been destroyed or finalized. {@link Error}\n * @example\n * Validate that a hash instance is still usable.\n * ```ts\n * import { aexists } from '@noble/hashes/utils.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const hash = sha256.create();\n * aexists(hash);\n * ```\n */\nexport function aexists(instance: any, checkFinished = true): void {\n if (instance.destroyed) throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');\n}\n\n/**\n * Asserts output is a sufficiently-sized byte array.\n * @param out - destination buffer\n * @param instance - hash instance providing output length\n * Oversized buffers are allowed; downstream code only promises to fill the first `outputLen` bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validate a caller-provided digest buffer.\n * ```ts\n * import { aoutput } from '@noble/hashes/utils.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const hash = sha256.create();\n * aoutput(new Uint8Array(hash.outputLen), hash);\n * ```\n */\nexport function aoutput(out: any, instance: any): void {\n abytes(out, undefined, 'digestInto() output');\n const min = instance.outputLen;\n if (out.length < min) {\n throw new RangeError('\"digestInto() output\" expected to be of length >=' + min);\n }\n}\n\n/** Generic type encompassing 8/16/32-byte array views, but not 64-bit variants. */\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\n/**\n * Casts a typed array view to Uint8Array.\n * @param arr - source typed array\n * @returns Uint8Array view over the same buffer.\n * @example\n * Reinterpret a typed array as bytes.\n * ```ts\n * u8(new Uint32Array([1, 2]));\n * ```\n */\nexport function u8(arr: TArg<TypedArray>): TRet<Uint8Array> {\n return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength) as TRet<Uint8Array>;\n}\n\n/**\n * Casts a typed array view to Uint32Array.\n * `arr.byteOffset` must already be 4-byte aligned or the platform\n * Uint32Array constructor will throw.\n * @param arr - source typed array\n * @returns Uint32Array view over the same buffer.\n * @example\n * Reinterpret a byte array as 32-bit words.\n * ```ts\n * u32(new Uint8Array(8));\n * ```\n */\nexport function u32(arr: TArg<TypedArray>): TRet<Uint32Array> {\n return new Uint32Array(\n arr.buffer,\n arr.byteOffset,\n Math.floor(arr.byteLength / 4)\n ) as TRet<Uint32Array>;\n}\n\n/**\n * Zeroizes typed arrays in place. Warning: JS provides no guarantees.\n * @param arrays - arrays to overwrite with zeros\n * @example\n * Zeroize sensitive buffers in place.\n * ```ts\n * clean(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport function clean(...arrays: TArg<TypedArray[]>): void {\n for (let i = 0; i < arrays.length; i++) {\n arrays[i].fill(0);\n }\n}\n\n/**\n * Creates a DataView for byte-level manipulation.\n * @param arr - source typed array\n * @returns DataView over the same buffer region.\n * @example\n * Create a DataView over an existing buffer.\n * ```ts\n * createView(new Uint8Array(4));\n * ```\n */\nexport function createView(arr: TArg<TypedArray>): DataView {\n return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/**\n * Rotate-right operation for uint32 values.\n * @param word - source word\n * @param shift - shift amount in bits\n * @returns Rotated word.\n * @example\n * Rotate a 32-bit word to the right.\n * ```ts\n * rotr(0x12345678, 8);\n * ```\n */\nexport function rotr(word: number, shift: number): number {\n return (word << (32 - shift)) | (word >>> shift);\n}\n\n/**\n * Rotate-left operation for uint32 values.\n * @param word - source word\n * @param shift - shift amount in bits\n * @returns Rotated word.\n * @example\n * Rotate a 32-bit word to the left.\n * ```ts\n * rotl(0x12345678, 8);\n * ```\n */\nexport function rotl(word: number, shift: number): number {\n return (word << shift) | ((word >>> (32 - shift)) >>> 0);\n}\n\n/** Whether the current platform is little-endian. */\nexport const isLE: boolean = /* @__PURE__ */ (() =>\n new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n\n/**\n * Byte-swap operation for uint32 values.\n * @param word - source word\n * @returns Word with reversed byte order.\n * @example\n * Reverse the byte order of a 32-bit word.\n * ```ts\n * byteSwap(0x11223344);\n * ```\n */\nexport function byteSwap(word: number): number {\n return (\n ((word << 24) & 0xff000000) |\n ((word << 8) & 0xff0000) |\n ((word >>> 8) & 0xff00) |\n ((word >>> 24) & 0xff)\n );\n}\n/**\n * Conditionally byte-swaps one 32-bit word on big-endian platforms.\n * @param n - source word\n * @returns Original or byte-swapped word depending on platform endianness.\n * @example\n * Normalize a 32-bit word for host endianness.\n * ```ts\n * swap8IfBE(0x11223344);\n * ```\n */\nexport const swap8IfBE: (n: number) => number = isLE\n ? (n: number) => n\n : (n: number) => byteSwap(n) >>> 0;\n\n/**\n * Byte-swaps every word of a Uint32Array in place.\n * @param arr - array to mutate\n * @returns The same array after mutation; callers pass live state arrays here.\n * @example\n * Reverse the byte order of every word in place.\n * ```ts\n * byteSwap32(new Uint32Array([0x11223344]));\n * ```\n */\nexport function byteSwap32(arr: TArg<Uint32Array>): TRet<Uint32Array> {\n for (let i = 0; i < arr.length; i++) {\n arr[i] = byteSwap(arr[i]);\n }\n return arr as TRet<Uint32Array>;\n}\n\n/**\n * Conditionally byte-swaps a Uint32Array on big-endian platforms.\n * @param u - array to normalize for host endianness\n * @returns Original or byte-swapped array depending on platform endianness.\n * On big-endian runtimes this mutates `u` in place via `byteSwap32(...)`.\n * @example\n * Normalize a word array for host endianness.\n * ```ts\n * swap32IfBE(new Uint32Array([0x11223344]));\n * ```\n */\nexport const swap32IfBE: (u: TArg<Uint32Array>) => TRet<Uint32Array> = isLE\n ? (u: TArg<Uint32Array>) => u as TRet<Uint32Array>\n : byteSwap32;\n\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\nconst hasHexBuiltin: boolean = /* @__PURE__ */ (() =>\n // @ts-ignore\n typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n\n/**\n * Convert byte array to hex string.\n * Uses the built-in function when available and assumes it matches the tested\n * fallback semantics.\n * @param bytes - bytes to encode\n * @returns Lowercase hexadecimal string.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Convert bytes to lowercase hexadecimal.\n * ```ts\n * bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // 'cafe0123'\n * ```\n */\nexport function bytesToHex(bytes: TArg<Uint8Array>): string {\n abytes(bytes);\n // @ts-ignore\n if (hasHexBuiltin) return bytes.toHex();\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n\n/**\n * Convert hex string to byte array. Uses built-in function, when available.\n * @param hex - hexadecimal string to decode\n * @returns Decoded bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Decode lowercase hexadecimal into bytes.\n * ```ts\n * hexToBytes('cafe0123'); // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n * ```\n */\nexport function hexToBytes(hex: string): TRet<Uint8Array> {\n if (typeof hex !== 'string') throw new TypeError('hex string expected, got ' + typeof hex);\n if (hasHexBuiltin) {\n try {\n return (Uint8Array as any).fromHex(hex);\n } catch (error) {\n if (error instanceof SyntaxError) throw new RangeError(error.message);\n throw error;\n }\n }\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2) throw new RangeError('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new RangeError(\n 'hex string expected, got non-hex character \"' + char + '\" at index ' + hi\n );\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array;\n}\n\n/**\n * There is no setImmediate in browser and setTimeout is slow.\n * This yields to the Promise/microtask scheduler queue, not to timers or the\n * full macrotask event loop.\n * @example\n * Yield to the next scheduler tick.\n * ```ts\n * await nextTick();\n * ```\n */\nexport const nextTick = async (): Promise<void> => {};\n\n/**\n * Returns control to the Promise/microtask scheduler every `tick`\n * milliseconds to avoid blocking long loops.\n * @param iters - number of loop iterations to run\n * @param tick - maximum time slice in milliseconds\n * @param cb - callback executed on each iteration\n * @example\n * Run a loop that periodically yields back to the event loop.\n * ```ts\n * await asyncLoop(2, 0, () => {});\n * ```\n */\nexport async function asyncLoop(\n iters: number,\n tick: number,\n cb: (i: number) => void\n): Promise<void> {\n let ts = Date.now();\n for (let i = 0; i < iters; i++) {\n cb(i);\n // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n const diff = Date.now() - ts;\n if (diff >= 0 && diff < tick) continue;\n await nextTick();\n ts += diff;\n }\n}\n\n// Global symbols, but ts doesn't see them: https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\n\n/**\n * Converts string to bytes using UTF8 encoding.\n * Built-in doesn't validate input to be string: we do the check.\n * Non-ASCII details are delegated to the platform `TextEncoder`.\n * @param str - string to encode\n * @returns UTF-8 encoded bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Encode a string as UTF-8 bytes.\n * ```ts\n * utf8ToBytes('abc'); // Uint8Array.from([97, 98, 99])\n * ```\n */\nexport function utf8ToBytes(str: string): TRet<Uint8Array> {\n if (typeof str !== 'string') throw new TypeError('string expected');\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\n/** KDFs can accept string or Uint8Array for user convenience. */\nexport type KDFInput = string | Uint8Array;\n\n/**\n * Helper for KDFs: consumes Uint8Array or string.\n * String inputs are UTF-8 encoded; byte-array inputs stay aliased to the caller buffer.\n * @param data - user-provided KDF input\n * @param errorTitle - label included in thrown errors\n * @returns Byte representation of the input.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Normalize KDF input to bytes.\n * ```ts\n * kdfInputToBytes('password');\n * ```\n */\nexport function kdfInputToBytes(data: TArg<KDFInput>, errorTitle = ''): TRet<Uint8Array> {\n if (typeof data === 'string') return utf8ToBytes(data);\n return abytes(data, undefined, errorTitle);\n}\n\n/**\n * Copies several Uint8Arrays into one.\n * @param arrays - arrays to concatenate\n * @returns Concatenated byte array.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Concatenate multiple byte arrays.\n * ```ts\n * concatBytes(new Uint8Array([1]), new Uint8Array([2]));\n * ```\n */\nexport function concatBytes(...arrays: TArg<Uint8Array[]>): TRet<Uint8Array> {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res;\n}\n\ntype EmptyObj = {};\n/**\n * Merges default options and passed options.\n * @param defaults - base option object\n * @param opts - user overrides\n * @returns Merged option object. The merge mutates `defaults` in place.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Merge user overrides onto default options.\n * ```ts\n * checkOpts({ dkLen: 32 }, { asyncTick: 10 });\n * ```\n */\nexport function checkOpts<T1 extends EmptyObj, T2 extends EmptyObj>(\n defaults: T1,\n opts?: T2\n): T1 & T2 {\n if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')\n throw new TypeError('options must be object or undefined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\n/** Common interface for all hash instances. */\nexport interface Hash<T> {\n /** Bytes processed per compression block. */\n blockLen: number;\n /** Bytes produced by `digest()`. */\n outputLen: number;\n /** Whether the instance supports XOF-style variable-length output via `xof()` / `xofInto()`. */\n canXOF: boolean;\n /**\n * Absorbs more message bytes into the running hash state.\n * @param buf - message chunk to absorb\n * @returns The same hash instance for chaining.\n */\n update(buf: TArg<Uint8Array>): this;\n /**\n * Finalizes the hash into a caller-provided buffer.\n * @param buf - destination buffer\n * @returns Nothing. Implementations write into `buf` in place.\n */\n digestInto(buf: TArg<Uint8Array>): void;\n /**\n * Finalizes the hash and returns a freshly allocated digest.\n * @returns Digest bytes.\n */\n digest(): TRet<Uint8Array>;\n /** Wipes internal state and makes the instance unusable. */\n destroy(): void;\n /**\n * Copies the current hash state into an existing or new instance.\n * @param to - Optional destination instance to reuse.\n * @returns Cloned hash state.\n */\n _cloneInto(to?: T): T;\n /**\n * Creates an independent copy of the current hash state.\n * @returns Cloned hash instance.\n */\n clone(): T;\n}\n\n/** Pseudorandom generator interface. */\nexport interface PRG {\n /**\n * Mixes more entropy into the generator state.\n * @param seed - fresh entropy bytes\n * @returns Nothing. Implementations update internal state in place.\n */\n addEntropy(seed: TArg<Uint8Array>): void;\n /**\n * Generates pseudorandom output bytes.\n * @param length - number of bytes to generate\n * @returns Generated pseudorandom bytes.\n */\n randomBytes(length: number): TRet<Uint8Array>;\n /** Wipes generator state and makes the instance unusable. */\n clean(): void;\n}\n\n/**\n * XOF: streaming API to read digest in chunks.\n * Same as 'squeeze' in keccak/k12 and 'seek' in blake3, but more generic name.\n * When hash used in XOF mode it is up to user to call '.destroy' afterwards, since we cannot\n * destroy state, next call can require more bytes.\n */\nexport type HashXOF<T extends Hash<T>> = Hash<T> & {\n /**\n * Reads more bytes from the XOF stream.\n * @param bytes - number of bytes to read\n * @returns Requested digest bytes.\n */\n xof(bytes: number): TRet<Uint8Array>;\n /**\n * Reads more bytes from the XOF stream into a caller-provided buffer.\n * @param buf - destination buffer\n * @returns Filled output buffer.\n */\n xofInto(buf: TArg<Uint8Array>): TRet<Uint8Array>;\n};\n\n/** Hash constructor or factory type. */\nexport type HasherCons<T, Opts = undefined> = Opts extends undefined ? () => T : (opts?: Opts) => T;\n/** Optional hash metadata. */\nexport type HashInfo = {\n /** DER-encoded object identifier bytes for the hash algorithm. */\n oid?: TRet<Uint8Array>;\n};\n/** Callable hash function type. */\nexport type CHash<T extends Hash<T> = Hash<any>, Opts = undefined> = {\n /** Digest size in bytes. */\n outputLen: number;\n /** Input block size in bytes. */\n blockLen: number;\n /** Whether `.create()` returns a hash instance that can be used as an XOF stream. */\n canXOF: boolean;\n} & HashInfo &\n (Opts extends undefined\n ? {\n (msg: TArg<Uint8Array>): TRet<Uint8Array>;\n create(): T;\n }\n : {\n (msg: TArg<Uint8Array>, opts?: TArg<Opts>): TRet<Uint8Array>;\n create(opts?: Opts): T;\n });\n/** Callable extendable-output hash function type. */\nexport type CHashXOF<T extends HashXOF<T> = HashXOF<any>, Opts = undefined> = CHash<T, Opts>;\n\n/**\n * Creates a callable hash function from a stateful class constructor.\n * @param hashCons - hash constructor or factory\n * @param info - optional metadata such as DER OID\n * @returns Frozen callable hash wrapper with `.create()`.\n * Wrapper construction eagerly calls `hashCons(undefined)` once to read\n * `outputLen` / `blockLen`, so constructor side effects happen at module\n * init time.\n * @example\n * Wrap a stateful hash constructor into a callable helper.\n * ```ts\n * import { createHasher } from '@noble/hashes/utils.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const wrapped = createHasher(sha256.create, { oid: sha256.oid });\n * wrapped(new Uint8Array([1]));\n * ```\n */\nexport function createHasher<T extends Hash<T>, Opts = undefined>(\n hashCons: HasherCons<T, Opts>,\n info: TArg<HashInfo> = {}\n): TRet<CHash<T, Opts>> {\n const hashC: any = (msg: TArg<Uint8Array>, opts?: TArg<Opts>) =>\n hashCons(opts as Opts)\n .update(msg)\n .digest();\n const tmp = hashCons(undefined);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.canXOF = tmp.canXOF;\n hashC.create = (opts?: Opts) => hashCons(opts);\n Object.assign(hashC, info);\n return Object.freeze(hashC) as TRet<CHash<T, Opts>>;\n}\n\n/**\n * Cryptographically secure PRNG backed by `crypto.getRandomValues`.\n * @param bytesLength - number of random bytes to generate\n * @returns Random bytes.\n * The platform `getRandomValues()` implementation still defines any\n * single-call length cap, and this helper rejects oversize requests\n * with a stable library `RangeError` instead of host-specific errors.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @throws If the current runtime does not provide `crypto.getRandomValues`. {@link Error}\n * @example\n * Generate a fresh random key or nonce.\n * ```ts\n * const key = randomBytes(16);\n * ```\n */\nexport function randomBytes(bytesLength = 32): TRet<Uint8Array> {\n // Match the repo's other length-taking helpers instead of relying on Uint8Array coercion.\n anumber(bytesLength, 'bytesLength');\n const cr = typeof globalThis === 'object' ? (globalThis as any).crypto : null;\n if (typeof cr?.getRandomValues !== 'function')\n throw new Error('crypto.getRandomValues must be defined');\n // Web Cryptography API Level 2 §10.1.1:\n // if `byteLength > 65536`, throw `QuotaExceededError`.\n // Keep the guard explicit so callers can see the quota in code\n // instead of discovering it by reading the spec or host errors.\n // This wrapper surfaces the same quota as a stable library RangeError.\n if (bytesLength > 65536)\n throw new RangeError(`\"bytesLength\" expected <= 65536, got ${bytesLength}`);\n return cr.getRandomValues(new Uint8Array(bytesLength));\n}\n\n/**\n * Creates OID metadata for NIST hashes with prefix `06 09 60 86 48 01 65 03 04 02`.\n * @param suffix - final OID byte for the selected hash.\n * The helper accepts any byte even though only the documented NIST hash\n * suffixes are meaningful downstream.\n * @returns Object containing the DER-encoded OID.\n * @example\n * Build OID metadata for a NIST hash.\n * ```ts\n * oidNist(0x01);\n * ```\n */\nexport const oidNist = (suffix: number): TRet<Required<HashInfo>> => ({\n // Current NIST hashAlgs suffixes used here fit in one DER subidentifier octet.\n // Larger suffix values would need base-128 OID encoding and a different length byte.\n oid: Uint8Array.from([0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, suffix]),\n});\n","/**\n * HMAC: RFC2104 message authentication code.\n * @module\n */\nimport {\n abytes,\n aexists,\n ahash,\n aoutput,\n clean,\n type CHash,\n type Hash,\n type TArg,\n type TRet,\n} from './utils.ts';\n\n/**\n * Internal class for HMAC.\n * Accepts any byte key, although RFC 2104 §3 recommends keys at least\n * `HashLen` bytes long.\n */\nexport class _HMAC<T extends Hash<T>> implements Hash<_HMAC<T>> {\n oHash: T;\n iHash: T;\n blockLen: number;\n outputLen: number;\n canXOF = false;\n private finished = false;\n private destroyed = false;\n\n constructor(hash: TArg<CHash>, key: TArg<Uint8Array>) {\n ahash(hash);\n abytes(key, undefined, 'key');\n this.iHash = hash.create() as T;\n if (typeof this.iHash.update !== 'function')\n throw new Error('Expected instance of class which extends utils.Hash');\n this.blockLen = this.iHash.blockLen;\n this.outputLen = this.iHash.outputLen;\n const blockLen = this.blockLen;\n const pad = new Uint8Array(blockLen);\n // blockLen can be bigger than outputLen\n pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);\n for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36;\n this.iHash.update(pad);\n // By doing update (processing of the first block) of the outer hash here,\n // we can re-use it between multiple calls via clone.\n this.oHash = hash.create() as T;\n // Undo internal XOR && apply outer XOR\n for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36 ^ 0x5c;\n this.oHash.update(pad);\n clean(pad);\n }\n update(buf: TArg<Uint8Array>): this {\n aexists(this);\n this.iHash.update(buf);\n return this;\n }\n digestInto(out: TArg<Uint8Array>): void {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n const buf = out.subarray(0, this.outputLen);\n // Reuse the first outputLen bytes for the inner digest; the outer hash consumes them before\n // overwriting that same prefix with the final tag, leaving any oversized tail untouched.\n this.iHash.digestInto(buf);\n this.oHash.update(buf);\n this.oHash.digestInto(buf);\n this.destroy();\n }\n digest(): TRet<Uint8Array> {\n const out = new Uint8Array(this.oHash.outputLen);\n this.digestInto(out);\n return out as TRet<Uint8Array>;\n }\n _cloneInto(to?: _HMAC<T>): _HMAC<T> {\n // Create new instance without calling constructor since the key\n // is already in state and we don't know it.\n to ||= Object.create(Object.getPrototypeOf(this), {});\n const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;\n to = to as this;\n to.finished = finished;\n to.destroyed = destroyed;\n to.blockLen = blockLen;\n to.outputLen = outputLen;\n to.oHash = oHash._cloneInto(to.oHash);\n to.iHash = iHash._cloneInto(to.iHash);\n return to;\n }\n clone(): _HMAC<T> {\n return this._cloneInto();\n }\n destroy(): void {\n this.destroyed = true;\n this.oHash.destroy();\n this.iHash.destroy();\n }\n}\n\n/**\n * HMAC: RFC2104 message authentication code.\n * @param hash - function that would be used e.g. sha256\n * @param key - authentication key bytes\n * @param message - message bytes to authenticate\n * @returns Authentication tag bytes.\n * @example\n * Compute an RFC 2104 HMAC.\n * ```ts\n * import { hmac } from '@noble/hashes/hmac.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const mac = hmac(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]));\n * ```\n */\ntype HmacFn = {\n (hash: TArg<CHash>, key: TArg<Uint8Array>, message: TArg<Uint8Array>): TRet<Uint8Array>;\n create(hash: TArg<CHash>, key: TArg<Uint8Array>): TRet<_HMAC<any>>;\n};\nexport const hmac: TRet<HmacFn> = /* @__PURE__ */ (() => {\n const hmac_ = ((\n hash: TArg<CHash>,\n key: TArg<Uint8Array>,\n message: TArg<Uint8Array>\n ): TRet<Uint8Array> => new _HMAC<any>(hash, key).update(message).digest()) as TRet<HmacFn>;\n hmac_.create = (hash: TArg<CHash>, key: TArg<Uint8Array>): TRet<_HMAC<any>> =>\n new _HMAC<any>(hash, key) as TRet<_HMAC<any>>;\n return hmac_;\n})();\n","/**\n * Internal Merkle-Damgard hash utils.\n * @module\n */\nimport {\n abytes,\n aexists,\n aoutput,\n clean,\n createView,\n type Hash,\n type TArg,\n type TRet,\n} from './utils.ts';\n\n/**\n * Shared 32-bit conditional boolean primitive reused by SHA-256, SHA-1, and MD5 `F`.\n * Returns bits from `b` when `a` is set, otherwise from `c`.\n * The XOR form is equivalent to MD5's `F(X,Y,Z) = XY v not(X)Z` because the masked terms never\n * set the same bit.\n * @param a - selector word\n * @param b - word chosen when selector bit is set\n * @param c - word chosen when selector bit is clear\n * @returns Mixed 32-bit word.\n * @example\n * Combine three words with the shared 32-bit choice primitive.\n * ```ts\n * Chi(0xffffffff, 0x12345678, 0x87654321);\n * ```\n */\nexport function Chi(a: number, b: number, c: number): number {\n return (a & b) ^ (~a & c);\n}\n\n/**\n * Shared 32-bit majority primitive reused by SHA-256 and SHA-1.\n * Returns bits shared by at least two inputs.\n * @param a - first input word\n * @param b - second input word\n * @param c - third input word\n * @returns Mixed 32-bit word.\n * @example\n * Combine three words with the shared 32-bit majority primitive.\n * ```ts\n * Maj(0xffffffff, 0x12345678, 0x87654321);\n * ```\n */\nexport function Maj(a: number, b: number, c: number): number {\n return (a & b) ^ (a & c) ^ (b & c);\n}\n\n/**\n * Merkle-Damgard hash construction base class.\n * Could be used to create MD5, RIPEMD, SHA1, SHA2.\n * Accepts only byte-aligned `Uint8Array` input, even when the underlying spec describes bit\n * strings with partial-byte tails.\n * @param blockLen - internal block size in bytes\n * @param outputLen - digest size in bytes\n * @param padOffset - trailing length field size in bytes\n * @param isLE - whether length and state words are encoded in little-endian\n * @example\n * Use a concrete subclass to get the shared Merkle-Damgard update/digest flow.\n * ```ts\n * import { _SHA1 } from '@noble/hashes/legacy.js';\n * const hash = new _SHA1();\n * hash.update(new Uint8Array([97, 98, 99]));\n * hash.digest();\n * ```\n */\nexport abstract class HashMD<T extends HashMD<T>> implements Hash<T> {\n // Subclasses must treat `buf` as read-only: `update()` may pass a direct view over caller input\n // when it can process whole blocks without buffering first.\n protected abstract process(buf: DataView, offset: number): void;\n protected abstract get(): number[];\n protected abstract set(...args: number[]): void;\n abstract destroy(): void;\n protected abstract roundClean(): void;\n\n readonly blockLen: number;\n readonly outputLen: number;\n readonly canXOF = false;\n readonly padOffset: number;\n readonly isLE: boolean;\n\n // For partial updates less than block size\n protected buffer: Uint8Array;\n protected view: DataView;\n protected finished = false;\n protected length = 0;\n protected pos = 0;\n protected destroyed = false;\n\n constructor(blockLen: number, outputLen: number, padOffset: number, isLE: boolean) {\n this.blockLen = blockLen;\n this.outputLen = outputLen;\n this.padOffset = padOffset;\n this.isLE = isLE;\n this.buffer = new Uint8Array(blockLen);\n this.view = createView(this.buffer);\n }\n update(data: TArg<Uint8Array>): this {\n aexists(this);\n abytes(data);\n const { view, buffer, blockLen } = this;\n const len = data.length;\n for (let pos = 0; pos < len; ) {\n const take = Math.min(blockLen - this.pos, len - pos);\n // Fast path only when there is no buffered partial block: `take === blockLen` implies\n // `this.pos === 0`, so we can process full blocks directly from the input view.\n if (take === blockLen) {\n const dataView = createView(data);\n for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, pos);\n continue;\n }\n buffer.set(data.subarray(pos, pos + take), this.pos);\n this.pos += take;\n pos += take;\n if (this.pos === blockLen) {\n this.process(view, 0);\n this.pos = 0;\n }\n }\n this.length += data.length;\n this.roundClean();\n return this;\n }\n digestInto(out: TArg<Uint8Array>): void {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n // Padding\n // We can avoid allocation of buffer for padding completely if it\n // was previously not allocated here. But it won't change performance.\n const { buffer, view, blockLen, isLE } = this;\n let { pos } = this;\n // append the bit '1' to the message\n buffer[pos++] = 0b10000000;\n clean(this.buffer.subarray(pos));\n // we have less than padOffset left in buffer, so we cannot put length in\n // current block, need process it and pad again\n if (this.padOffset > blockLen - pos) {\n this.process(view, 0);\n pos = 0;\n }\n // Pad until full block byte with zeros\n for (let i = pos; i < blockLen; i++) buffer[i] = 0;\n // `padOffset` reserves the whole length field. For SHA-384/512 the high 64 bits stay zero from\n // the padding fill above, and JS will overflow before user input can make that half non-zero.\n // So we only need to write the low 64 bits here.\n view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);\n this.process(view, 0);\n const oview = createView(out);\n const len = this.outputLen;\n // NOTE: we do division by 4 later, which must be fused in single op with modulo by JIT\n if (len % 4) throw new Error('_sha2: outputLen must be aligned to 32bit');\n const outLen = len / 4;\n const state = this.get();\n if (outLen > state.length) throw new Error('_sha2: outputLen bigger than state');\n for (let i = 0; i < outLen; i++) oview.setUint32(4 * i, state[i], isLE);\n }\n digest(): TRet<Uint8Array> {\n const { buffer, outputLen } = this;\n this.digestInto(buffer);\n // Copy before destroy(): subclasses wipe `buffer` during cleanup, but `digest()` must return\n // fresh bytes to the caller.\n const res = buffer.slice(0, outputLen);\n this.destroy();\n return res as TRet<Uint8Array>;\n }\n _cloneInto(to?: T): T {\n to ||= new (this.constructor as any)() as T;\n to.set(...this.get());\n const { blockLen, buffer, length, finished, destroyed, pos } = this;\n to.destroyed = destroyed;\n to.finished = finished;\n to.length = length;\n to.pos = pos;\n // Only partial-block bytes need copying: when `length % blockLen === 0`, `pos === 0` and\n // later `update()` / `digestInto()` overwrite `to.buffer` from the start before reading it.\n if (length % blockLen) to.buffer.set(buffer);\n return to as unknown as any;\n }\n clone(): T {\n return this._cloneInto();\n }\n}\n\n/**\n * Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.\n * Check out `test/misc/sha2-gen-iv.js` for recomputation guide.\n */\n\n/** Initial SHA256 state from RFC 6234 §6.1: the first 32 bits of the fractional parts of the\n * square roots of the first eight prime numbers. Exported as a shared table; callers must treat\n * it as read-only because constructors copy words from it by index. */\nexport const SHA256_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n]);\n\n/** Initial SHA224 state `H(0)` from RFC 6234 §6.1. Exported as a shared table; callers must\n * treat it as read-only because constructors copy words from it by index. */\nexport const SHA224_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,\n]);\n\n/** Initial SHA384 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen\n * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the ninth\n * through sixteenth prime numbers. Exported as a shared table; callers must treat it as read-only\n * because constructors copy halves from it by index. */\nexport const SHA384_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0xcbbb9d5d, 0xc1059ed8, 0x629a292a, 0x367cd507, 0x9159015a, 0x3070dd17, 0x152fecd8, 0xf70e5939,\n 0x67332667, 0xffc00b31, 0x8eb44a87, 0x68581511, 0xdb0c2e0d, 0x64f98fa7, 0x47b5481d, 0xbefa4fa4,\n]);\n\n/** Initial SHA512 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen\n * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the first\n * eight prime numbers. Exported as a shared table; callers must treat it as read-only because\n * constructors copy halves from it by index. */\nexport const SHA512_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1,\n 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,\n]);\n","/**\n\nSHA1 (RFC 3174), MD5 (RFC 1321), and RIPEMD160 legacy, weak hash functions.\nRFC 2286 only covers HMAC-RIPEMD160 wrapper material and test vectors,\nnot the base RIPEMD-160 compression spec.\nDon't use them in a new protocol. What \"weak\" means:\n\n- Collisions can be made with 2^18 effort in MD5, 2^60 in SHA1, 2^80 in RIPEMD160.\n- No practical pre-image attacks (only theoretical, 2^123.4)\n- HMAC seems kinda ok: https://www.rfc-editor.org/rfc/rfc6151\n * @module\n */\nimport { Chi, HashMD, Maj } from './_md.ts';\nimport { type CHash, clean, createHasher, rotl, type TRet } from './utils.ts';\n\n/** Initial SHA-1 state from RFC 3174 §6.1. */\nconst SHA1_IV = /* @__PURE__ */ Uint32Array.from([\n 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0,\n]);\n\n// Reusable 80-word SHA-1 message schedule buffer.\nconst SHA1_W = /* @__PURE__ */ new Uint32Array(80);\n\n/** Internal SHA1 legacy hash class. */\nexport class _SHA1 extends HashMD<_SHA1> {\n private A = SHA1_IV[0] | 0;\n private B = SHA1_IV[1] | 0;\n private C = SHA1_IV[2] | 0;\n private D = SHA1_IV[3] | 0;\n private E = SHA1_IV[4] | 0;\n\n constructor() {\n super(64, 20, 8, false);\n }\n protected get(): [number, number, number, number, number] {\n const { A, B, C, D, E } = this;\n return [A, B, C, D, E];\n }\n protected set(A: number, B: number, C: number, D: number, E: number): void {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n this.E = E | 0;\n }\n protected process(view: DataView, offset: number): void {\n for (let i = 0; i < 16; i++, offset += 4) SHA1_W[i] = view.getUint32(offset, false);\n for (let i = 16; i < 80; i++)\n SHA1_W[i] = rotl(SHA1_W[i - 3] ^ SHA1_W[i - 8] ^ SHA1_W[i - 14] ^ SHA1_W[i - 16], 1);\n // Compression function main loop, 80 rounds\n let { A, B, C, D, E } = this;\n for (let i = 0; i < 80; i++) {\n let F, K;\n if (i < 20) {\n F = Chi(B, C, D);\n K = 0x5a827999;\n } else if (i < 40) {\n F = B ^ C ^ D;\n K = 0x6ed9eba1;\n } else if (i < 60) {\n F = Maj(B, C, D);\n K = 0x8f1bbcdc;\n } else {\n F = B ^ C ^ D;\n K = 0xca62c1d6;\n }\n const T = (rotl(A, 5) + F + E + K + SHA1_W[i]) | 0;\n E = D;\n D = C;\n C = rotl(B, 30);\n B = A;\n A = T;\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n E = (E + this.E) | 0;\n this.set(A, B, C, D, E);\n }\n protected roundClean(): void {\n clean(SHA1_W);\n }\n destroy(): void {\n // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves\n // update()/digest() callable on reused instances.\n this.destroyed = true;\n this.set(0, 0, 0, 0, 0);\n clean(this.buffer);\n }\n}\n\n/**\n * SHA1 (RFC 3174) legacy hash function. It was cryptographically broken.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA1.\n * ```ts\n * sha1(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha1: TRet<CHash> = /* @__PURE__ */ createHasher(() => new _SHA1());\n\n/** RFC 1321 `T[i]` uses `floor(2^32 * abs(sin(i)))`; this is the shared `2^32` scale factor. */\nconst p32 = /* @__PURE__ */ Math.pow(2, 32);\n/** RFC 1321 `T[1..64]` table. */\nconst K = /* @__PURE__ */ Array.from({ length: 64 }, (_, i) =>\n Math.floor(p32 * Math.abs(Math.sin(i + 1)))\n);\n\n/** MD5 initial state from RFC 1321, stored as 4 u32 words. */\nconst MD5_IV = /* @__PURE__ */ SHA1_IV.slice(0, 4);\n\n// Reusable 16-word MD5 message block buffer.\nconst MD5_W = /* @__PURE__ */ new Uint32Array(16);\n/** Internal MD5 legacy hash class. */\nexport class _MD5 extends HashMD<_MD5> {\n private A = MD5_IV[0] | 0;\n private B = MD5_IV[1] | 0;\n private C = MD5_IV[2] | 0;\n private D = MD5_IV[3] | 0;\n\n constructor() {\n super(64, 16, 8, true);\n }\n protected get(): [number, number, number, number] {\n const { A, B, C, D } = this;\n return [A, B, C, D];\n }\n protected set(A: number, B: number, C: number, D: number): void {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n }\n protected process(view: DataView, offset: number): void {\n for (let i = 0; i < 16; i++, offset += 4) MD5_W[i] = view.getUint32(offset, true);\n // Compression function main loop, 64 rounds\n let { A, B, C, D } = this;\n for (let i = 0; i < 64; i++) {\n let F, g, s;\n if (i < 16) {\n F = Chi(B, C, D);\n g = i;\n s = [7, 12, 17, 22];\n } else if (i < 32) {\n // RFC 1321 round 2 uses G(B,C,D) = (B & D) | (C & ~D), which is `Chi(D, B, C)`.\n F = Chi(D, B, C);\n g = (5 * i + 1) % 16;\n s = [5, 9, 14, 20];\n } else if (i < 48) {\n F = B ^ C ^ D;\n g = (3 * i + 5) % 16;\n s = [4, 11, 16, 23];\n } else {\n F = C ^ (B | ~D);\n g = (7 * i) % 16;\n s = [6, 10, 15, 21];\n }\n F = F + A + K[i] + MD5_W[g];\n A = D;\n D = C;\n C = B;\n B = B + rotl(F, s[i % 4]);\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n this.set(A, B, C, D);\n }\n protected roundClean(): void {\n clean(MD5_W);\n }\n destroy(): void {\n // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves\n // update()/digest() callable on reused instances.\n this.destroyed = true;\n this.set(0, 0, 0, 0);\n clean(this.buffer);\n }\n}\n\n/**\n * MD5 (RFC 1321) legacy hash function. It was cryptographically broken.\n * MD5 architecture is similar to SHA1, with some differences:\n * - Reduced output length: 16 bytes (128 bit) instead of 20\n * - 64 rounds, instead of 80\n * - Little-endian: could be faster, but will require more code\n * - Non-linear index selection: huge speed-up for unroll\n * - Per round constants: more memory accesses, additional speed-up for unroll\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with MD5.\n * ```ts\n * md5(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const md5: TRet<CHash> = /* @__PURE__ */ createHasher(() => new _MD5());\n\n// RIPEMD-160\n\n// Permutation repeatedly applied to derive the later RIPEMD-160 message-order tables.\nconst Rho160 = /* @__PURE__ */ Uint8Array.from([\n 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,\n]);\nconst Id160 = /* @__PURE__ */ (() => Uint8Array.from(new Array(16).fill(0).map((_, i) => i)))();\nconst Pi160 = /* @__PURE__ */ (() => Id160.map((i) => (9 * i + 5) % 16))();\n// Five left/right message-word orderings for the RIPEMD-160 dual-lane rounds.\nconst idxLR = /* @__PURE__ */ (() => {\n const L = [Id160];\n const R = [Pi160];\n const res = [L, R];\n for (let i = 0; i < 4; i++) for (let j of res) j.push(j[i].map((k) => Rho160[k]));\n return res;\n})();\nconst idxL = /* @__PURE__ */ (() => idxLR[0])();\nconst idxR = /* @__PURE__ */ (() => idxLR[1])();\n// const [idxL, idxR] = idxLR;\n\n// Base per-group shift table before the left/right message-order permutations are applied.\nconst shifts160 = /* @__PURE__ */ [\n [11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8],\n [12, 13, 11, 15, 6, 9, 9, 7, 12, 15, 11, 13, 7, 8, 7, 7],\n [13, 15, 14, 11, 7, 7, 6, 8, 13, 14, 13, 12, 5, 5, 6, 9],\n [14, 11, 12, 14, 8, 6, 5, 5, 15, 12, 15, 14, 9, 9, 8, 6],\n [15, 12, 13, 13, 9, 5, 8, 6, 14, 11, 12, 11, 8, 6, 5, 5],\n].map((i) => Uint8Array.from(i));\nconst shiftsL160 = /* @__PURE__ */ idxL.map((idx, i) => idx.map((j) => shifts160[i][j]));\nconst shiftsR160 = /* @__PURE__ */ idxR.map((idx, i) => idx.map((j) => shifts160[i][j]));\n// Five left-lane additive constants for RIPEMD-160.\nconst Kl160 = /* @__PURE__ */ Uint32Array.from([\n 0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e,\n]);\n// Five right-lane additive constants for RIPEMD-160.\nconst Kr160 = /* @__PURE__ */ Uint32Array.from([\n 0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000,\n]);\n// Called `f()` in the spec; valid `group` values are 0..4, and out-of-range\n// inputs currently fall through to the group-4 branch.\nfunction ripemd_f(group: number, x: number, y: number, z: number): number {\n if (group === 0) return x ^ y ^ z;\n if (group === 1) return (x & y) | (~x & z);\n if (group === 2) return (x | ~y) ^ z;\n if (group === 3) return (x & z) | (y & ~z);\n return x ^ (y | ~z);\n}\n// Reusable 16-word RIPEMD-160 message block buffer.\nconst BUF_160 = /* @__PURE__ */ new Uint32Array(16);\n/**\n * Internal RIPEMD-160 legacy hash class.\n * RFC 2286 only adds HMAC-RIPEMD160 material, not the core hash specification.\n */\nexport class _RIPEMD160 extends HashMD<_RIPEMD160> {\n private h0 = 0x67452301 | 0;\n private h1 = 0xefcdab89 | 0;\n private h2 = 0x98badcfe | 0;\n private h3 = 0x10325476 | 0;\n private h4 = 0xc3d2e1f0 | 0;\n\n constructor() {\n super(64, 20, 8, true);\n }\n protected get(): [number, number, number, number, number] {\n const { h0, h1, h2, h3, h4 } = this;\n return [h0, h1, h2, h3, h4];\n }\n protected set(h0: number, h1: number, h2: number, h3: number, h4: number): void {\n this.h0 = h0 | 0;\n this.h1 = h1 | 0;\n this.h2 = h2 | 0;\n this.h3 = h3 | 0;\n this.h4 = h4 | 0;\n }\n protected process(view: DataView, offset: number): void {\n for (let i = 0; i < 16; i++, offset += 4) BUF_160[i] = view.getUint32(offset, true);\n // prettier-ignore\n let al = this.h0 | 0, ar = al,\n bl = this.h1 | 0, br = bl,\n cl = this.h2 | 0, cr = cl,\n dl = this.h3 | 0, dr = dl,\n el = this.h4 | 0, er = el;\n\n // Instead of iterating 0 to 80, we split it into 5 groups\n // And use the groups in constants, functions, etc. Much simpler\n for (let group = 0; group < 5; group++) {\n const rGroup = 4 - group;\n const hbl = Kl160[group], hbr = Kr160[group]; // prettier-ignore\n const rl = idxL[group], rr = idxR[group]; // prettier-ignore\n const sl = shiftsL160[group], sr = shiftsR160[group]; // prettier-ignore\n for (let i = 0; i < 16; i++) {\n const tl = (rotl(al + ripemd_f(group, bl, cl, dl) + BUF_160[rl[i]] + hbl, sl[i]) + el) | 0;\n al = el, el = dl, dl = rotl(cl, 10) | 0, cl = bl, bl = tl; // prettier-ignore\n }\n // 2 loops are 10% faster\n for (let i = 0; i < 16; i++) {\n const tr = (rotl(ar + ripemd_f(rGroup, br, cr, dr) + BUF_160[rr[i]] + hbr, sr[i]) + er) | 0;\n ar = er, er = dr, dr = rotl(cr, 10) | 0, cr = br, br = tr; // prettier-ignore\n }\n }\n // Add the compressed chunk to the current hash value\n // Final recombination cross-adds the left/right lane accumulators into the next h0..h4 order.\n this.set(\n (this.h1 + cl + dr) | 0,\n (this.h2 + dl + er) | 0,\n (this.h3 + el + ar) | 0,\n (this.h4 + al + br) | 0,\n (this.h0 + bl + cr) | 0\n );\n }\n protected roundClean(): void {\n clean(BUF_160);\n }\n destroy(): void {\n this.destroyed = true;\n clean(this.buffer);\n this.set(0, 0, 0, 0, 0);\n }\n}\n\n/**\n * RIPEMD-160 - a legacy hash function from 1990s.\n * RFC 2286 only covers HMAC-RIPEMD160 test material; the links below point\n * at the base RIPEMD-160 references.\n * * {@link https://homes.esat.kuleuven.be/~bosselae/ripemd160.html}\n * * {@link https://homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf}\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with RIPEMD-160.\n * ```ts\n * ripemd160(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const ripemd160: TRet<CHash> = /* @__PURE__ */ createHasher(() => new _RIPEMD160());\n","/**\n * Internal helpers for u64.\n * BigUint64Array is too slow as per 2026, so we implement it using\n * Uint32Array.\n * @privateRemarks TODO: re-check {@link https://issues.chromium.org/issues/42212588}\n * @module\n */\nimport type { TRet } from './utils.ts';\n\nconst U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);\nconst _32n = /* @__PURE__ */ BigInt(32);\n\n// Split bigint into two 32-bit halves. With `le=true`, returned fields become `{ h: low, l: high\n// }` to match little-endian word order rather than the property names.\nfunction fromBig(\n n: bigint,\n le = false\n): {\n h: number;\n l: number;\n} {\n if (le) return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };\n return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };\n}\n\n// Split bigint list into `[highWords, lowWords]` when `le=false`; with `le=true`, the first array\n// holds the low halves because `fromBig(...)` swaps the semantic meaning of `h` and `l`.\nfunction split(lst: bigint[], le = false): TRet<Uint32Array[]> {\n const len = lst.length;\n let Ah = new Uint32Array(len);\n let Al = new Uint32Array(len);\n for (let i = 0; i < len; i++) {\n const { h, l } = fromBig(lst[i], le);\n [Ah[i], Al[i]] = [h, l];\n }\n return [Ah, Al] as TRet<Uint32Array[]>;\n}\n\n// Combine explicit `(high, low)` 32-bit halves into a bigint; `>>> 0` normalizes signed JS\n// bitwise results back to uint32 first, and little-endian callers must swap.\nconst toBig = (h: number, l: number): bigint => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0);\n// High 32-bit half of a 64-bit logical right shift for `s` in `0..31`.\nconst shrSH = (h: number, _l: number, s: number): number => h >>> s;\n// Low 32-bit half of a 64-bit logical right shift, valid for `s` in `1..31`.\nconst shrSL = (h: number, l: number, s: number): number => (h << (32 - s)) | (l >>> s);\n// High 32-bit half of a 64-bit right rotate, valid for `s` in `1..31`.\nconst rotrSH = (h: number, l: number, s: number): number => (h >>> s) | (l << (32 - s));\n// Low 32-bit half of a 64-bit right rotate, valid for `s` in `1..31`.\nconst rotrSL = (h: number, l: number, s: number): number => (h << (32 - s)) | (l >>> s);\n// High 32-bit half of a 64-bit right rotate, valid for `s` in `33..63`; `32` uses `rotr32*`.\nconst rotrBH = (h: number, l: number, s: number): number => (h << (64 - s)) | (l >>> (s - 32));\n// Low 32-bit half of a 64-bit right rotate, valid for `s` in `33..63`; `32` uses `rotr32*`.\nconst rotrBL = (h: number, l: number, s: number): number => (h >>> (s - 32)) | (l << (64 - s));\n// High 32-bit half of a 64-bit right rotate for `s === 32`; this is just the swapped low half.\nconst rotr32H = (_h: number, l: number): number => l;\n// Low 32-bit half of a 64-bit right rotate for `s === 32`; this is just the swapped high half.\nconst rotr32L = (h: number, _l: number): number => h;\n// High 32-bit half of a 64-bit left rotate, valid for `s` in `1..31`.\nconst rotlSH = (h: number, l: number, s: number): number => (h << s) | (l >>> (32 - s));\n// Low 32-bit half of a 64-bit left rotate, valid for `s` in `1..31`.\nconst rotlSL = (h: number, l: number, s: number): number => (l << s) | (h >>> (32 - s));\n// High 32-bit half of a 64-bit left rotate, valid for `s` in `33..63`; `32` uses `rotr32*`.\nconst rotlBH = (h: number, l: number, s: number): number => (l << (s - 32)) | (h >>> (64 - s));\n// Low 32-bit half of a 64-bit left rotate, valid for `s` in `33..63`; `32` uses `rotr32*`.\nconst rotlBL = (h: number, l: number, s: number): number => (h << (s - 32)) | (l >>> (64 - s));\n\n// Add two split 64-bit words and return the split `{ h, l }` sum.\n// JS uses 32-bit signed integers for bitwise operations, so we cannot simply shift the carry out\n// of the low sum and instead use division.\nfunction add(\n Ah: number,\n Al: number,\n Bh: number,\n Bl: number\n): {\n h: number;\n l: number;\n} {\n const l = (Al >>> 0) + (Bl >>> 0);\n return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };\n}\n// Addition with more than 2 elements\n// Unmasked low-word accumulator for 3-way addition; pass the raw result into `add3H(...)`.\nconst add3L = (Al: number, Bl: number, Cl: number): number => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);\n// High-word finalize step for 3-way addition; `low` must be the untruncated output of `add3L(...)`.\nconst add3H = (low: number, Ah: number, Bh: number, Ch: number): number =>\n (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;\n// Unmasked low-word accumulator for 4-way addition; pass the raw result into `add4H(...)`.\nconst add4L = (Al: number, Bl: number, Cl: number, Dl: number): number =>\n (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);\n// High-word finalize step for 4-way addition; `low` must be the untruncated output of `add4L(...)`.\nconst add4H = (low: number, Ah: number, Bh: number, Ch: number, Dh: number): number =>\n (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;\n// Unmasked low-word accumulator for 5-way addition; pass the raw result into `add5H(...)`.\nconst add5L = (Al: number, Bl: number, Cl: number, Dl: number, El: number): number =>\n (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);\n// High-word finalize step for 5-way addition; `low` must be the untruncated output of `add5L(...)`.\nconst add5H = (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number): number =>\n (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;\n\n// prettier-ignore\nexport {\n add, add3H, add3L, add4H, add4L, add5H, add5L, fromBig, rotlBH, rotlBL, rotlSH, rotlSL, rotr32H, rotr32L, rotrBH, rotrBL, rotrSH, rotrSL, shrSH, shrSL, split, toBig\n};\n// Canonical grouped namespace for callers that prefer one object.\n// Named exports stay for direct imports.\n// prettier-ignore\nconst u64: { fromBig: typeof fromBig; split: typeof split; toBig: (h: number, l: number) => bigint; shrSH: (h: number, _l: number, s: number) => number; shrSL: (h: number, l: number, s: number) => number; rotrSH: (h: number, l: number, s: number) => number; rotrSL: (h: number, l: number, s: number) => number; rotrBH: (h: number, l: number, s: number) => number; rotrBL: (h: number, l: number, s: number) => number; rotr32H: (_h: number, l: number) => number; rotr32L: (h: number, _l: number) => number; rotlSH: (h: number, l: number, s: number) => number; rotlSL: (h: number, l: number, s: number) => number; rotlBH: (h: number, l: number, s: number) => number; rotlBL: (h: number, l: number, s: number) => number; add: typeof add; add3L: (Al: number, Bl: number, Cl: number) => number; add3H: (low: number, Ah: number, Bh: number, Ch: number) => number; add4L: (Al: number, Bl: number, Cl: number, Dl: number) => number; add4H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number) => number; add5H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number) => number; add5L: (Al: number, Bl: number, Cl: number, Dl: number, El: number) => number; } = {\n fromBig, split, toBig,\n shrSH, shrSL,\n rotrSH, rotrSL, rotrBH, rotrBL,\n rotr32H, rotr32L,\n rotlSH, rotlSL, rotlBH, rotlBL,\n add, add3L, add3H, add4L, add4H, add5H, add5L,\n};\n// Default export mirrors named `u64` for compatibility with object-style imports.\nexport default u64;\n","/**\n * SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.\n * SHA256 is the fastest hash implementable in JS, even faster than Blake3.\n * Check out {@link https://www.rfc-editor.org/rfc/rfc4634 | RFC 4634} and\n * {@link https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf | FIPS 180-4}.\n * @module\n */\nimport { Chi, HashMD, Maj, SHA224_IV, SHA256_IV, SHA384_IV, SHA512_IV } from './_md.ts';\nimport * as u64 from './_u64.ts';\nimport { type CHash, clean, createHasher, oidNist, rotr, type TRet } from './utils.ts';\n\n/**\n * SHA-224 / SHA-256 round constants from RFC 6234 §5.1: the first 32 bits\n * of the cube roots of the first 64 primes (2..311).\n */\n// prettier-ignore\nconst SHA256_K = /* @__PURE__ */ Uint32Array.from([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n]);\n\n/** Reusable SHA-224 / SHA-256 message schedule buffer `W_t` from RFC 6234 §6.2 step 1. */\nconst SHA256_W = /* @__PURE__ */ new Uint32Array(64);\n\n/** Internal SHA-224 / SHA-256 compression engine from RFC 6234 §6.2. */\nabstract class SHA2_32B<T extends SHA2_32B<T>> extends HashMD<T> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n protected abstract A: number;\n protected abstract B: number;\n protected abstract C: number;\n protected abstract D: number;\n protected abstract E: number;\n protected abstract F: number;\n protected abstract G: number;\n protected abstract H: number;\n\n constructor(outputLen: number) {\n super(64, outputLen, 8, false);\n }\n protected get(): [number, number, number, number, number, number, number, number] {\n const { A, B, C, D, E, F, G, H } = this;\n return [A, B, C, D, E, F, G, H];\n }\n // prettier-ignore\n protected set(\n A: number, B: number, C: number, D: number, E: number, F: number, G: number, H: number\n ): void {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n this.E = E | 0;\n this.F = F | 0;\n this.G = G | 0;\n this.H = H | 0;\n }\n protected process(view: DataView, offset: number): void {\n // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4) SHA256_W[i] = view.getUint32(offset, false);\n for (let i = 16; i < 64; i++) {\n const W15 = SHA256_W[i - 15];\n const W2 = SHA256_W[i - 2];\n const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);\n const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);\n SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;\n }\n // Compression function main loop, 64 rounds\n let { A, B, C, D, E, F, G, H } = this;\n for (let i = 0; i < 64; i++) {\n const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);\n const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);\n const T2 = (sigma0 + Maj(A, B, C)) | 0;\n H = G;\n G = F;\n F = E;\n E = (D + T1) | 0;\n D = C;\n C = B;\n B = A;\n A = (T1 + T2) | 0;\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n E = (E + this.E) | 0;\n F = (F + this.F) | 0;\n G = (G + this.G) | 0;\n H = (H + this.H) | 0;\n this.set(A, B, C, D, E, F, G, H);\n }\n protected roundClean(): void {\n clean(SHA256_W);\n }\n destroy(): void {\n // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves\n // update()/digest() callable on reused instances.\n this.destroyed = true;\n this.set(0, 0, 0, 0, 0, 0, 0, 0);\n clean(this.buffer);\n }\n}\n\n/** Internal SHA-256 hash class grounded in RFC 6234 §6.2. */\nexport class _SHA256 extends SHA2_32B<_SHA256> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n protected A: number = SHA256_IV[0] | 0;\n protected B: number = SHA256_IV[1] | 0;\n protected C: number = SHA256_IV[2] | 0;\n protected D: number = SHA256_IV[3] | 0;\n protected E: number = SHA256_IV[4] | 0;\n protected F: number = SHA256_IV[5] | 0;\n protected G: number = SHA256_IV[6] | 0;\n protected H: number = SHA256_IV[7] | 0;\n constructor() {\n super(32);\n }\n}\n\n/** Internal SHA-224 hash class grounded in RFC 6234 §6.2 and §8.5. */\nexport class _SHA224 extends SHA2_32B<_SHA224> {\n protected A: number = SHA224_IV[0] | 0;\n protected B: number = SHA224_IV[1] | 0;\n protected C: number = SHA224_IV[2] | 0;\n protected D: number = SHA224_IV[3] | 0;\n protected E: number = SHA224_IV[4] | 0;\n protected F: number = SHA224_IV[5] | 0;\n protected G: number = SHA224_IV[6] | 0;\n protected H: number = SHA224_IV[7] | 0;\n constructor() {\n super(28);\n }\n}\n\n// SHA2-512 is slower than sha256 in js because u64 operations are slow.\n\n// SHA-384 / SHA-512 round constants from RFC 6234 §5.2:\n// 80 full 64-bit words split into high/low halves.\n// prettier-ignore\nconst K512 = /* @__PURE__ */ (() => u64.split([\n '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',\n '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',\n '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',\n '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',\n '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',\n '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',\n '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',\n '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',\n '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',\n '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',\n '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',\n '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',\n '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',\n '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',\n '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',\n '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',\n '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',\n '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',\n '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',\n '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'\n].map(n => BigInt(n))))();\nconst SHA512_Kh = /* @__PURE__ */ (() => K512[0])();\nconst SHA512_Kl = /* @__PURE__ */ (() => K512[1])();\n\n// Reusable high-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words.\nconst SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);\n// Reusable low-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words.\nconst SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);\n\n/** Internal SHA-384 / SHA-512 compression engine from RFC 6234 §6.4. */\nabstract class SHA2_64B<T extends SHA2_64B<T>> extends HashMD<T> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n // h -- high 32 bits, l -- low 32 bits\n protected abstract Ah: number;\n protected abstract Al: number;\n protected abstract Bh: number;\n protected abstract Bl: number;\n protected abstract Ch: number;\n protected abstract Cl: number;\n protected abstract Dh: number;\n protected abstract Dl: number;\n protected abstract Eh: number;\n protected abstract El: number;\n protected abstract Fh: number;\n protected abstract Fl: number;\n protected abstract Gh: number;\n protected abstract Gl: number;\n protected abstract Hh: number;\n protected abstract Hl: number;\n\n constructor(outputLen: number) {\n super(128, outputLen, 16, false);\n }\n // prettier-ignore\n protected get(): [\n number, number, number, number, number, number, number, number,\n number, number, number, number, number, number, number, number\n ] {\n const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];\n }\n // prettier-ignore\n protected set(\n Ah: number, Al: number, Bh: number, Bl: number, Ch: number, Cl: number, Dh: number, Dl: number,\n Eh: number, El: number, Fh: number, Fl: number, Gh: number, Gl: number, Hh: number, Hl: number\n ): void {\n this.Ah = Ah | 0;\n this.Al = Al | 0;\n this.Bh = Bh | 0;\n this.Bl = Bl | 0;\n this.Ch = Ch | 0;\n this.Cl = Cl | 0;\n this.Dh = Dh | 0;\n this.Dl = Dl | 0;\n this.Eh = Eh | 0;\n this.El = El | 0;\n this.Fh = Fh | 0;\n this.Fl = Fl | 0;\n this.Gh = Gh | 0;\n this.Gl = Gl | 0;\n this.Hh = Hh | 0;\n this.Hl = Hl | 0;\n }\n protected process(view: DataView, offset: number): void {\n // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4) {\n SHA512_W_H[i] = view.getUint32(offset);\n SHA512_W_L[i] = view.getUint32((offset += 4));\n }\n for (let i = 16; i < 80; i++) {\n // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)\n const W15h = SHA512_W_H[i - 15] | 0;\n const W15l = SHA512_W_L[i - 15] | 0;\n const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^ u64.shrSH(W15h, W15l, 7);\n const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^ u64.shrSL(W15h, W15l, 7);\n // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)\n const W2h = SHA512_W_H[i - 2] | 0;\n const W2l = SHA512_W_L[i - 2] | 0;\n const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^ u64.shrSH(W2h, W2l, 6);\n const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^ u64.shrSL(W2h, W2l, 6);\n // SHA512_W[i] = s0 + s1 + SHA512_W[i - 7] + SHA512_W[i - 16];\n const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);\n const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);\n SHA512_W_H[i] = SUMh | 0;\n SHA512_W_L[i] = SUMl | 0;\n }\n let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n // Compression function main loop, 80 rounds\n for (let i = 0; i < 80; i++) {\n // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)\n const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^ u64.rotrBH(Eh, El, 41);\n const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^ u64.rotrBL(Eh, El, 41);\n //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const CHIh = (Eh & Fh) ^ (~Eh & Gh);\n const CHIl = (El & Fl) ^ (~El & Gl);\n // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]\n // prettier-ignore\n const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);\n const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);\n const T1l = T1ll | 0;\n // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)\n const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^ u64.rotrBH(Ah, Al, 39);\n const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^ u64.rotrBL(Ah, Al, 39);\n const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);\n const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);\n Hh = Gh | 0;\n Hl = Gl | 0;\n Gh = Fh | 0;\n Gl = Fl | 0;\n Fh = Eh | 0;\n Fl = El | 0;\n ({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));\n Dh = Ch | 0;\n Dl = Cl | 0;\n Ch = Bh | 0;\n Cl = Bl | 0;\n Bh = Ah | 0;\n Bl = Al | 0;\n const All = u64.add3L(T1l, sigma0l, MAJl);\n Ah = u64.add3H(All, T1h, sigma0h, MAJh);\n Al = All | 0;\n }\n // Add the compressed chunk to the current hash value\n ({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));\n ({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));\n ({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));\n ({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));\n ({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));\n ({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));\n ({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));\n ({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));\n this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);\n }\n protected roundClean(): void {\n clean(SHA512_W_H, SHA512_W_L);\n }\n destroy(): void {\n // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves\n // update()/digest() callable on reused instances.\n this.destroyed = true;\n clean(this.buffer);\n this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);\n }\n}\n\n/** Internal SHA-512 hash class grounded in RFC 6234 §6.3 and §6.4. */\nexport class _SHA512 extends SHA2_64B<_SHA512> {\n protected Ah: number = SHA512_IV[0] | 0;\n protected Al: number = SHA512_IV[1] | 0;\n protected Bh: number = SHA512_IV[2] | 0;\n protected Bl: number = SHA512_IV[3] | 0;\n protected Ch: number = SHA512_IV[4] | 0;\n protected Cl: number = SHA512_IV[5] | 0;\n protected Dh: number = SHA512_IV[6] | 0;\n protected Dl: number = SHA512_IV[7] | 0;\n protected Eh: number = SHA512_IV[8] | 0;\n protected El: number = SHA512_IV[9] | 0;\n protected Fh: number = SHA512_IV[10] | 0;\n protected Fl: number = SHA512_IV[11] | 0;\n protected Gh: number = SHA512_IV[12] | 0;\n protected Gl: number = SHA512_IV[13] | 0;\n protected Hh: number = SHA512_IV[14] | 0;\n protected Hl: number = SHA512_IV[15] | 0;\n\n constructor() {\n super(64);\n }\n}\n\n/** Internal SHA-384 hash class grounded in RFC 6234 §6.3 and §6.4. */\nexport class _SHA384 extends SHA2_64B<_SHA384> {\n protected Ah: number = SHA384_IV[0] | 0;\n protected Al: number = SHA384_IV[1] | 0;\n protected Bh: number = SHA384_IV[2] | 0;\n protected Bl: number = SHA384_IV[3] | 0;\n protected Ch: number = SHA384_IV[4] | 0;\n protected Cl: number = SHA384_IV[5] | 0;\n protected Dh: number = SHA384_IV[6] | 0;\n protected Dl: number = SHA384_IV[7] | 0;\n protected Eh: number = SHA384_IV[8] | 0;\n protected El: number = SHA384_IV[9] | 0;\n protected Fh: number = SHA384_IV[10] | 0;\n protected Fl: number = SHA384_IV[11] | 0;\n protected Gh: number = SHA384_IV[12] | 0;\n protected Gl: number = SHA384_IV[13] | 0;\n protected Hh: number = SHA384_IV[14] | 0;\n protected Hl: number = SHA384_IV[15] | 0;\n\n constructor() {\n super(48);\n }\n}\n\n/**\n * Truncated SHA512/256 and SHA512/224.\n * SHA512_IV is XORed with 0xa5a5a5a5a5a5a5a5, then used as \"intermediary\" IV of SHA512/t.\n * Then t hashes string to produce result IV.\n * See the repo-side derivation recipe in `test/misc/sha2-gen-iv.js`.\n * These IV literals are checked against that script rather than a dedicated\n * local RFC section.\n */\n\n/** SHA-512/224 IV derived by the SHA-512/t recipe in `test/misc/sha2-gen-iv.js` and\n * stored as sixteen big-endian 32-bit halves. */\nconst T224_IV = /* @__PURE__ */ Uint32Array.from([\n 0x8c3d37c8, 0x19544da2, 0x73e19966, 0x89dcd4d6, 0x1dfab7ae, 0x32ff9c82, 0x679dd514, 0x582f9fcf,\n 0x0f6d2b69, 0x7bd44da8, 0x77e36f73, 0x04c48942, 0x3f9d85a8, 0x6a1d36c8, 0x1112e6ad, 0x91d692a1,\n]);\n\n/** SHA-512/256 IV derived by the SHA-512/t recipe in `test/misc/sha2-gen-iv.js` and\n * stored as sixteen big-endian 32-bit halves. */\nconst T256_IV = /* @__PURE__ */ Uint32Array.from([\n 0x22312194, 0xfc2bf72c, 0x9f555fa3, 0xc84c64c2, 0x2393b86b, 0x6f53b151, 0x96387719, 0x5940eabd,\n 0x96283ee2, 0xa88effe3, 0xbe5e1e25, 0x53863992, 0x2b0199fc, 0x2c85b8aa, 0x0eb72ddc, 0x81c52ca2,\n]);\n\n/** Internal SHA-512/224 hash class using the derived `T224_IV` and the shared\n * RFC 6234 §6.4 compression engine. */\nexport class _SHA512_224 extends SHA2_64B<_SHA512_224> {\n protected Ah: number = T224_IV[0] | 0;\n protected Al: number = T224_IV[1] | 0;\n protected Bh: number = T224_IV[2] | 0;\n protected Bl: number = T224_IV[3] | 0;\n protected Ch: number = T224_IV[4] | 0;\n protected Cl: number = T224_IV[5] | 0;\n protected Dh: number = T224_IV[6] | 0;\n protected Dl: number = T224_IV[7] | 0;\n protected Eh: number = T224_IV[8] | 0;\n protected El: number = T224_IV[9] | 0;\n protected Fh: number = T224_IV[10] | 0;\n protected Fl: number = T224_IV[11] | 0;\n protected Gh: number = T224_IV[12] | 0;\n protected Gl: number = T224_IV[13] | 0;\n protected Hh: number = T224_IV[14] | 0;\n protected Hl: number = T224_IV[15] | 0;\n\n constructor() {\n super(28);\n }\n}\n\n/** Internal SHA-512/256 hash class using the derived `T256_IV` and the shared\n * RFC 6234 §6.4 compression engine. */\nexport class _SHA512_256 extends SHA2_64B<_SHA512_256> {\n protected Ah: number = T256_IV[0] | 0;\n protected Al: number = T256_IV[1] | 0;\n protected Bh: number = T256_IV[2] | 0;\n protected Bl: number = T256_IV[3] | 0;\n protected Ch: number = T256_IV[4] | 0;\n protected Cl: number = T256_IV[5] | 0;\n protected Dh: number = T256_IV[6] | 0;\n protected Dl: number = T256_IV[7] | 0;\n protected Eh: number = T256_IV[8] | 0;\n protected El: number = T256_IV[9] | 0;\n protected Fh: number = T256_IV[10] | 0;\n protected Fl: number = T256_IV[11] | 0;\n protected Gh: number = T256_IV[12] | 0;\n protected Gl: number = T256_IV[13] | 0;\n protected Hh: number = T256_IV[14] | 0;\n protected Hl: number = T256_IV[15] | 0;\n\n constructor() {\n super(32);\n }\n}\n\n/**\n * SHA2-256 hash function from RFC 4634. In JS it's the fastest: even faster than Blake3. Some info:\n *\n * - Trying 2^128 hashes would get 50% chance of collision, using birthday attack.\n * - BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.\n * - Each sha256 hash is executing 2^18 bit operations.\n * - Good 2024 ASICs can do 200Th/sec with 3500 watts of power, corresponding to 2^36 hashes/joule.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-256.\n * ```ts\n * sha256(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha256: TRet<CHash<_SHA256>> = /* @__PURE__ */ createHasher(\n () => new _SHA256(),\n /* @__PURE__ */ oidNist(0x01)\n);\n/**\n * SHA2-224 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-224.\n * ```ts\n * sha224(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha224: TRet<CHash<_SHA224>> = /* @__PURE__ */ createHasher(\n () => new _SHA224(),\n /* @__PURE__ */ oidNist(0x04)\n);\n\n/**\n * SHA2-512 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512.\n * ```ts\n * sha512(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512: TRet<CHash<_SHA512>> = /* @__PURE__ */ createHasher(\n () => new _SHA512(),\n /* @__PURE__ */ oidNist(0x03)\n);\n/**\n * SHA2-384 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-384.\n * ```ts\n * sha384(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha384: TRet<CHash<_SHA384>> = /* @__PURE__ */ createHasher(\n () => new _SHA384(),\n /* @__PURE__ */ oidNist(0x02)\n);\n\n/**\n * SHA2-512/256 \"truncated\" hash function, with improved resistance to length extension attacks.\n * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512/256.\n * ```ts\n * sha512_256(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512_256: TRet<CHash<_SHA512_256>> = /* @__PURE__ */ createHasher(\n () => new _SHA512_256(),\n /* @__PURE__ */ oidNist(0x06)\n);\n/**\n * SHA2-512/224 \"truncated\" hash function, with improved resistance to length extension attacks.\n * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512/224.\n * ```ts\n * sha512_224(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512_224: TRet<CHash<_SHA512_224>> = /* @__PURE__ */ createHasher(\n () => new _SHA512_224(),\n /* @__PURE__ */ oidNist(0x05)\n);\n","import { hmac } from \"@noble/hashes/hmac.js\";\nimport { sha1 } from \"@noble/hashes/legacy.js\";\nimport { sha256, sha512 } from \"@noble/hashes/sha2.js\";\nimport { randomBytes } from \"@noble/hashes/utils.js\";\nimport { constantTimeEqual as constantTimeEqualUtil } from \"@otplib/core\";\n\nimport type { CryptoPlugin } from \"@otplib/core\";\n\n/**\n * Pure JavaScript implementation of CryptoPlugin\n *\n * This plugin uses @noble/hashes which provides:\n * - Pure JavaScript implementations of hash functions\n * - Zero dependencies and audited code\n * - Cross-platform compatibility (Node.js, browser, edge)\n * - Fallback for environments without native crypto APIs\n *\n * @example\n * ```ts\n * import { NobleCryptoPlugin } from '@otplib/plugin-crypto-noble';\n *\n * const crypto = new NobleCryptoPlugin();\n * const hmac = crypto.hmac('sha1', key, data);\n * const random = crypto.randomBytes(20);\n * ```\n */\nexport class NobleCryptoPlugin implements CryptoPlugin {\n /**\n * Plugin name for identification\n */\n readonly name = \"noble\";\n\n /**\n * Compute HMAC using @noble/hashes\n *\n * Synchronous implementation using pure JS.\n *\n * @param algorithm - Hash algorithm to use\n * @param key - Secret key\n * @param data - Data to authenticate\n * @returns HMAC digest\n */\n hmac(algorithm: \"sha1\" | \"sha256\" | \"sha512\", key: Uint8Array, data: Uint8Array): Uint8Array {\n const hashFn = algorithm === \"sha1\" ? sha1 : algorithm === \"sha256\" ? sha256 : sha512;\n return hmac(hashFn, key, data);\n }\n\n /**\n * Generate cryptographically secure random bytes\n *\n * Uses @noble/hashes' randomBytes which is backed by:\n * - Node.js crypto.randomBytes in Node.js\n * - crypto.getRandomValues in browsers\n * - A PRNG as fallback\n *\n * @param length - Number of bytes to generate\n * @returns Random bytes\n */\n randomBytes(length: number): Uint8Array {\n return randomBytes(length);\n }\n\n /**\n * Constant-time comparison to prevent timing side-channel attacks\n *\n * @noble/hashes doesn't provide a constant-time comparison,\n * so we Use the core utility implementation.\n *\n * @param a - First value to compare\n * @param b - Second value to compare\n * @returns true if values are equal, false otherwise\n */\n constantTimeEqual(a: string | Uint8Array, b: string | Uint8Array): boolean {\n return constantTimeEqualUtil(a, b);\n }\n}\n\n/**\n * Default singleton instance for convenience\n *\n * @example\n * ```ts\n * import { crypto } from '@otplib/plugin-crypto-noble';\n *\n * const hmac = crypto.hmac('sha1', key, data);\n * ```\n */\nexport const crypto: CryptoPlugin = Object.freeze(new NobleCryptoPlugin());\n\nexport default NobleCryptoPlugin;\n","/**\n * Default plugin instances\n *\n * Shared across functional and class APIs to ensure singleton behavior\n * and reduce memory overhead. Uses pre-instantiated frozen singletons\n * from the plugin packages.\n */\nimport { createGuardrails } from \"@otplib/core\";\nimport { base32 as defaultBase32 } from \"@otplib/plugin-base32-scure\";\nimport { crypto as defaultCrypto } from \"@otplib/plugin-crypto-noble\";\n\nimport type {\n OTPGenerateOptions,\n OTPVerifyOptions,\n OTPGenerateOptionsWithDefaults,\n OTPVerifyOptionsWithDefaults,\n} from \"./types.js\";\n\nexport { defaultCrypto, defaultBase32 };\n\nexport function normalizeGenerateOptions(\n options: OTPGenerateOptions,\n): OTPGenerateOptionsWithDefaults {\n return {\n secret: options.secret,\n strategy: options.strategy ?? \"totp\",\n crypto: options.crypto ?? defaultCrypto,\n base32: options.base32 ?? defaultBase32,\n algorithm: options.algorithm ?? \"sha1\",\n digits: options.digits ?? 6,\n period: options.period ?? 30,\n epoch: options.epoch ?? Math.floor(Date.now() / 1000),\n t0: options.t0 ?? 0,\n counter: options.counter,\n guardrails: options.guardrails ?? createGuardrails(),\n hooks: options.hooks,\n };\n}\n\nexport function normalizeVerifyOptions(options: OTPVerifyOptions): OTPVerifyOptionsWithDefaults {\n return {\n ...normalizeGenerateOptions(options),\n token: options.token,\n epochTolerance: options.epochTolerance ?? 0,\n counterTolerance: options.counterTolerance ?? 0,\n afterTimeStep: options.afterTimeStep,\n };\n}\n","import { generateSecret as generateSecretCore, ConfigurationError } from \"@otplib/core\";\nimport {\n generate as generateHOTP,\n generateSync as generateHOTPSync,\n verify as verifyHOTP,\n verifySync as verifyHOTPSync,\n} from \"@otplib/hotp\";\nimport {\n generate as generateTOTP,\n generateSync as generateTOTPSync,\n verify as verifyTOTP,\n verifySync as verifyTOTPSync,\n} from \"@otplib/totp\";\nimport { generateTOTP as generateTOTPURI, generateHOTP as generateHOTURI } from \"@otplib/uri\";\n\nimport {\n defaultCrypto,\n defaultBase32,\n normalizeGenerateOptions,\n normalizeVerifyOptions,\n} from \"./defaults.js\";\n\nimport type {\n OTPGenerateOptions,\n OTPVerifyOptions,\n OTPStrategy,\n StrategyHandlers,\n} from \"./types.js\";\nimport type { CryptoPlugin, Base32Plugin, Digits, HashAlgorithm } from \"@otplib/core\";\nimport type { VerifyResult as HOTPVerifyResult } from \"@otplib/hotp\";\nimport type { VerifyResult as TOTPVerifyResult } from \"@otplib/totp\";\n\nexport type { OTPStrategy };\n\nexport type VerifyResult = TOTPVerifyResult | HOTPVerifyResult;\n\nfunction executeByStrategy<T>(\n strategy: OTPStrategy,\n counter: number | undefined,\n handlers: StrategyHandlers<T>,\n): T {\n if (strategy === \"totp\") {\n return handlers.totp();\n }\n if (strategy === \"hotp\") {\n if (counter === undefined) {\n throw new ConfigurationError(\n \"Counter is required for HOTP strategy. Example: { strategy: 'hotp', counter: 0 }\",\n );\n }\n return handlers.hotp(counter);\n }\n throw new ConfigurationError(\n `Unknown OTP strategy: ${strategy}. Valid strategies are 'totp' or 'hotp'.`,\n );\n}\n\n/**\n * Generate a random secret key for use with OTP\n *\n * The secret is encoded in Base32 format for compatibility with\n * Google Authenticator and other authenticator apps.\n *\n * @param options - Secret generation options\n * @returns Base32-encoded secret key\n *\n * @example\n * ```ts\n * import { generateSecret } from 'otplib';\n *\n * const secret = generateSecret();\n * // Returns: 'JBSWY3DPEHPK3PXP'\n * ```\n *\n * @example With custom plugins\n * ```ts\n * import { generateSecret, NodeCryptoPlugin } from 'otplib';\n *\n * const secret = generateSecret({\n * crypto: new NodeCryptoPlugin(),\n * });\n * ```\n */\nexport function generateSecret(options?: {\n /**\n * Number of random bytes to generate (default: 20)\n * 20 bytes = 160 bits, which provides a good security margin\n */\n length?: number;\n\n /**\n * Crypto plugin to use (default: NobleCryptoPlugin)\n */\n crypto?: CryptoPlugin;\n\n /**\n * Base32 plugin to use (default: ScureBase32Plugin)\n */\n base32?: Base32Plugin;\n}): string {\n const { crypto = defaultCrypto, base32 = defaultBase32, length = 20 } = options || {};\n\n return generateSecretCore({ crypto, base32, length });\n}\n\n/**\n * Generate an otpauth:// URI for QR code generation\n *\n * This URI can be used to generate a QR code that can be scanned\n * by Google Authenticator and other authenticator apps.\n *\n * @param options - URI generation options\n * @returns otpauth:// URI string\n *\n * @example TOTP\n * ```ts\n * import { generateURI } from 'otplib';\n *\n * const uri = generateURI({\n * issuer: 'ACME Co',\n * label: 'john@example.com',\n * secret: 'JBSWY3DPEHPK3PXP',\n * });\n * // Returns: 'otpauth://totp/ACME%20Co:john%40example.com?secret=...'\n * ```\n *\n * @example HOTP\n * ```ts\n * import { generateURI } from 'otplib';\n *\n * const uri = generateURI({\n * strategy: 'hotp',\n * issuer: 'ACME Co',\n * label: 'john@example.com',\n * secret: 'JBSWY3DPEHPK3PXP',\n * counter: 5,\n * });\n * // Returns: 'otpauth://hotp/ACME%20Co:john%40example.com?secret=...&counter=5'\n * ```\n */\nexport function generateURI(options: {\n /**\n * OTP strategy to use (default: 'totp')\n */\n strategy?: OTPStrategy;\n issuer: string;\n label: string;\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string;\n algorithm?: HashAlgorithm;\n digits?: Digits;\n period?: number;\n counter?: number;\n}): string {\n const {\n strategy = \"totp\",\n issuer,\n label,\n secret,\n algorithm = \"sha1\",\n digits = 6,\n period = 30,\n counter,\n } = options;\n\n return executeByStrategy(strategy, counter, {\n totp: () => generateTOTPURI({ issuer, label, secret, algorithm, digits, period }),\n hotp: (counter) => generateHOTURI({ issuer, label, secret, algorithm, digits, counter }),\n });\n}\n\n/**\n * Generate an OTP code\n *\n * Generates a one-time password based on the specified strategy.\n * - 'totp': Time-based OTP (default)\n * - 'hotp': HMAC-based OTP\n *\n * @param options - OTP generation options\n * @returns OTP code\n *\n * @example TOTP\n * ```ts\n * import { generate } from 'otplib';\n *\n * const token = await generate({\n * secret: 'JBSWY3DPEHPK3PXP',\n * });\n * // Returns: '123456'\n * ```\n *\n * @example HOTP\n * ```ts\n * import { generate } from 'otplib';\n *\n * const token = await generate({\n * secret: 'JBSWY3DPEHPK3PXP',\n * strategy: 'hotp',\n * counter: 0,\n * });\n * ```\n *\n * @example With custom plugins\n * ```ts\n * import { generate, NodeCryptoPlugin } from 'otplib';\n *\n * const token = await generate({\n * secret: 'JBSWY3DPEHPK3PXP',\n * crypto: new NodeCryptoPlugin(),\n * });\n * ```\n */\nexport async function generate(options: OTPGenerateOptions): Promise<string> {\n const opts = normalizeGenerateOptions(options);\n const { secret, crypto, base32, algorithm, digits, hooks } = opts;\n const commonOptions = { secret, crypto, base32, algorithm, digits, hooks };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n generateTOTP({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n generateHOTP({\n ...commonOptions,\n counter,\n guardrails: opts.guardrails,\n }),\n });\n}\n\n/**\n * Generate an OTP code synchronously\n *\n * This is the synchronous version of {@link generate}. It requires a crypto\n * plugin that supports synchronous HMAC operations.\n *\n * @param options - OTP generation options\n * @returns OTP code\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n *\n * @example\n * ```ts\n * import { generateSync } from 'otplib';\n *\n * const token = generateSync({\n * secret: 'JBSWY3DPEHPK3PXP',\n * });\n * ```\n */\nexport function generateSync(options: OTPGenerateOptions): string {\n const opts = normalizeGenerateOptions(options);\n const { secret, crypto, base32, algorithm, digits } = opts;\n const commonOptions = { secret, crypto, base32, algorithm, digits };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n generateTOTPSync({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n generateHOTPSync({\n ...commonOptions,\n counter,\n guardrails: opts.guardrails,\n }),\n });\n}\n\n/**\n * Verify an OTP code\n *\n * Verifies a provided OTP code against the expected value based on the strategy.\n * - 'totp': Time-based OTP (default, Google Authenticator compatible)\n * - 'hotp': HMAC-based OTP\n *\n * Uses constant-time comparison to prevent timing attacks.\n *\n * @param options - OTP verification options\n * @returns Verification result with validity and optional delta\n *\n * @example TOTP\n * ```ts\n * import { verify } from 'otplib';\n *\n * const result = await verify({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * });\n * // Returns: { valid: true, delta: 0 }\n * ```\n *\n * @example HOTP\n * ```ts\n * import { verify } from 'otplib';\n *\n * const result = await verify({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * strategy: 'hotp',\n * counter: 0,\n * });\n * ```\n *\n * @example With epochTolerance for TOTP\n * ```ts\n * import { verify, NodeCryptoPlugin } from 'otplib';\n *\n * const result = await verify({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * epochTolerance: 30,\n * crypto: new NodeCryptoPlugin(),\n * });\n * ```\n */\nexport async function verify(options: OTPVerifyOptions): Promise<VerifyResult> {\n const opts = normalizeVerifyOptions(options);\n const { secret, token, crypto, base32, algorithm, digits, hooks } = opts;\n const commonOptions = { secret, token, crypto, base32, algorithm, digits, hooks };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n verifyTOTP({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n epochTolerance: opts.epochTolerance,\n afterTimeStep: opts.afterTimeStep,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n verifyHOTP({\n ...commonOptions,\n counter,\n counterTolerance: opts.counterTolerance,\n guardrails: opts.guardrails,\n }),\n });\n}\n\n/**\n * Verify an OTP code synchronously\n *\n * This is the synchronous version of {@link verify}. It requires a crypto\n * plugin that supports synchronous HMAC operations.\n *\n * @param options - OTP verification options\n * @returns Verification result with validity and optional delta\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n *\n * @example\n * ```ts\n * import { verifySync } from 'otplib';\n *\n * const result = verifySync({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * });\n * ```\n */\nexport function verifySync(options: OTPVerifyOptions): VerifyResult {\n const opts = normalizeVerifyOptions(options);\n const { secret, token, crypto, base32, algorithm, digits, hooks } = opts;\n const commonOptions = { secret, token, crypto, base32, algorithm, digits, hooks };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n verifyTOTPSync({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n epochTolerance: opts.epochTolerance,\n afterTimeStep: opts.afterTimeStep,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n verifyHOTPSync({\n ...commonOptions,\n counter,\n counterTolerance: opts.counterTolerance,\n guardrails: opts.guardrails,\n }),\n });\n}\n","/**\n * OTP Wrapper Class\n *\n * A unified class that dynamically handles TOTP and HOTP strategies.\n */\n\nimport { createGuardrails, generateSecret as generateSecretCore } from \"@otplib/core\";\n\nimport { defaultCrypto, defaultBase32 } from \"./defaults.js\";\nimport {\n generate as functionalGenerate,\n generateSync as functionalGenerateSync,\n verify as functionalVerify,\n verifySync as functionalVerifySync,\n generateURI as functionalGenerateURI,\n} from \"./functional.js\";\n\nimport type { OTPStrategy } from \"./functional.js\";\nimport type {\n CryptoPlugin,\n Digits,\n HashAlgorithm,\n Base32Plugin,\n OTPGuardrails,\n OTPHooks,\n} from \"@otplib/core\";\nimport type { VerifyResult as HOTPVerifyResult } from \"@otplib/hotp\";\nimport type { VerifyResult as TOTPVerifyResult } from \"@otplib/totp\";\n\n/**\n * Combined verify result that works for both TOTP and HOTP\n */\nexport type VerifyResult = TOTPVerifyResult | HOTPVerifyResult;\n\n/**\n * Options for the OTP class\n */\nexport type OTPClassOptions = {\n /**\n * OTP strategy to use\n * - 'totp': Time-based OTP (default)\n * - 'hotp': HMAC-based OTP\n */\n strategy?: OTPStrategy;\n\n /**\n * Crypto plugin to use (default: NobleCryptoPlugin)\n */\n crypto?: CryptoPlugin;\n\n /**\n * Base32 plugin to use (default: ScureBase32Plugin)\n */\n base32?: Base32Plugin;\n\n /**\n * Validation guardrails\n */\n guardrails?: OTPGuardrails;\n};\n\n/**\n * Options for generating a token with the OTP class\n */\nexport type OTPGenerateOptions = {\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string | Uint8Array;\n\n /**\n * Hash algorithm (default: 'sha1')\n */\n algorithm?: HashAlgorithm;\n\n /**\n * Number of digits (default: 6)\n */\n digits?: Digits;\n\n /**\n * Current Unix epoch timestamp in seconds (default: now)\n * Used by TOTP strategy\n */\n epoch?: number;\n\n /**\n * Initial Unix time to start counting time steps (default: 0)\n * Used by TOTP strategy\n */\n t0?: number;\n\n /**\n * Time step in seconds (default: 30)\n * Used by TOTP strategy\n */\n period?: number;\n\n /**\n * Counter value\n * Used by HOTP strategy (required)\n */\n counter?: number;\n\n /**\n * Validation guardrails\n */\n guardrails?: OTPGuardrails;\n\n /**\n * Hooks for customizing token encoding and validation\n */\n hooks?: OTPHooks;\n};\n\n/**\n * Options for verifying a token with the OTP class\n */\nexport type OTPVerifyOptions = {\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string | Uint8Array;\n\n /**\n * OTP code to verify\n */\n token: string;\n\n /**\n * Hash algorithm (default: 'sha1')\n */\n algorithm?: HashAlgorithm;\n\n /**\n * Number of digits (default: 6)\n */\n digits?: Digits;\n\n /**\n * Current Unix epoch timestamp in seconds (default: now)\n * Used by TOTP strategy\n */\n epoch?: number;\n\n /**\n * Initial Unix time to start counting time steps (default: 0)\n * Used by TOTP strategy\n */\n t0?: number;\n\n /**\n * Time step in seconds (default: 30)\n * Used by TOTP strategy\n */\n period?: number;\n\n /**\n * Counter value\n * Used by HOTP strategy (required)\n */\n counter?: number;\n\n /**\n * Time tolerance in seconds for TOTP verification (default: 0)\n * - Number: symmetric tolerance (same for past and future)\n * - Tuple [past, future]: asymmetric tolerance\n * Use [5, 0] for RFC-compliant past-only verification.\n */\n epochTolerance?: number | [number, number];\n\n /**\n * Counter tolerance for HOTP verification (default: 0)\n * - Number: creates look-ahead only tolerance [0, n]\n * - Tuple [past, future]: explicit window control\n */\n counterTolerance?: number | [number, number];\n\n /**\n * Minimum allowed TOTP time step for replay protection (optional)\n *\n * Rejects tokens with timeStep <= afterTimeStep.\n * Only used by TOTP strategy.\n */\n afterTimeStep?: number;\n\n /**\n * Validation guardrails\n */\n guardrails?: OTPGuardrails;\n\n /**\n * Hooks for customizing token encoding and validation\n */\n hooks?: OTPHooks;\n};\n\n/**\n * Options for generating URI with the OTP class\n */\nexport type OTPURIGenerateOptions = {\n /**\n * Issuer name (e.g., 'ACME Co')\n */\n issuer: string;\n\n /**\n * Label/Account name (e.g., 'john@example.com')\n */\n label: string;\n\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string;\n\n /**\n * Hash algorithm (default: 'sha1')\n */\n algorithm?: HashAlgorithm;\n\n /**\n * Number of digits (default: 6)\n */\n digits?: Digits;\n\n /**\n * Time step in seconds (default: 30)\n * Used by TOTP strategy\n */\n period?: number;\n\n /**\n * Counter value (default: 0)\n * Used by HOTP strategy\n */\n counter?: number;\n};\n\n/**\n * OTP Class\n *\n * A wrapper class that dynamically handles TOTP and HOTP strategies.\n *\n * @example\n * ```ts\n * import { OTP } from 'otplib';\n *\n * // Create OTP instance with TOTP strategy (default)\n * const otp = new OTP({ strategy: 'totp' });\n *\n * // Generate and verify\n * const secret = otp.generateSecret();\n * const token = await otp.generate({ secret });\n * const result = await otp.verify({ secret, token });\n * ```\n *\n * @example With HOTP strategy\n * ```ts\n * import { OTP } from 'otplib';\n *\n * const otp = new OTP({ strategy: 'hotp' });\n * const token = await otp.generate({ secret: 'ABC123', counter: 0 });\n * ```\n *\n * @example Generating otpauth:// URI for authenticator apps\n * ```ts\n * import { OTP } from 'otplib';\n *\n * const otp = new OTP({ strategy: 'totp' });\n * const uri = otp.generateURI({\n * issuer: 'MyApp',\n * label: 'user@example.com',\n * secret: 'ABC123',\n * });\n * ```\n */\nexport class OTP {\n private readonly strategy: OTPStrategy;\n private readonly crypto: CryptoPlugin;\n private readonly base32: Base32Plugin;\n private readonly guardrails: OTPGuardrails;\n\n constructor(options: OTPClassOptions = {}) {\n const {\n strategy = \"totp\",\n crypto = defaultCrypto,\n base32 = defaultBase32,\n guardrails,\n } = options;\n\n this.strategy = strategy;\n this.crypto = crypto;\n this.base32 = base32;\n this.guardrails = createGuardrails(guardrails);\n }\n\n /**\n * Get the current strategy\n */\n getStrategy(): OTPStrategy {\n return this.strategy;\n }\n\n /**\n * Generate a random secret key\n *\n * @param length - Number of random bytes (default: 20)\n * @returns Base32-encoded secret key\n */\n generateSecret(length: number = 20): string {\n return generateSecretCore({ crypto: this.crypto, base32: this.base32, length });\n }\n\n /**\n * Generate an OTP token based on the configured strategy\n *\n * @param options - Generation options\n * @returns OTP code\n */\n async generate(options: OTPGenerateOptions): Promise<string> {\n return functionalGenerate({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Generate an OTP token based on the configured strategy synchronously\n *\n * @param options - Generation options\n * @returns OTP code\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n */\n generateSync(options: OTPGenerateOptions): string {\n return functionalGenerateSync({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Verify an OTP token based on the configured strategy\n *\n * @param options - Verification options\n * @returns Verification result with validity and optional delta\n */\n async verify(options: OTPVerifyOptions): Promise<VerifyResult> {\n return functionalVerify({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Verify an OTP token based on the configured strategy synchronously\n *\n * @param options - Verification options\n * @returns Verification result with validity and optional delta\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n */\n verifySync(options: OTPVerifyOptions): VerifyResult {\n return functionalVerifySync({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Generate an otpauth:// URI for QR code generation\n *\n * Supports both TOTP and HOTP strategies.\n *\n * @param options - URI generation options\n * @returns otpauth:// URI string\n */\n generateURI(options: OTPURIGenerateOptions): string {\n return functionalGenerateURI({\n ...options,\n strategy: this.strategy,\n });\n }\n}\n"],"mappings":"wcAAA,IAAAA,GAAA,GAAAC,GAAAD,GAAA,UAAAE,GAAA,sBAAAC,GAAA,QAAAC,GAAA,sBAAAC,GAAA,SAAAC,GAAA,qBAAAC,EAAA,aAAAC,GAAA,mBAAAC,GAAA,iBAAAC,GAAA,gBAAAC,GAAA,kBAAAC,GAAA,WAAAC,GAAA,eAAAC,GAAA,eAAAC,GAAA,oBAAAC,KCyBO,IAAMC,EAAN,cAAuB,KAAM,CAClC,YAAYC,EAAiBC,EAA2B,CACtD,MAAMD,EAASC,CAAO,EACtB,KAAK,KAAO,UACd,CACF,EAKaC,GAAN,cAA0BH,CAAS,CACxC,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,aACd,CACF,EAKaG,GAAN,cAAkCD,EAAY,CACnD,YAAYE,EAAkBC,EAAqB,CACjD,MACE,2BAA2BD,CAAQ,WAAWA,EAAW,CAAC,eAAeC,CAAW,QACtF,EACA,KAAK,KAAO,qBACd,CACF,EAKaC,GAAN,cAAiCJ,EAAY,CAClD,YAAYK,EAAkBF,EAAqB,CACjD,MAAM,0BAA0BE,CAAQ,eAAeF,CAAW,QAAQ,EAC1E,KAAK,KAAO,oBACd,CACF,EAKaG,EAAN,cAA2BT,CAAS,CACzC,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,cACd,CACF,EAKaS,GAAN,cAAmCD,CAAa,CACrD,aAAc,CACZ,MAAM,8BAA8B,EACpC,KAAK,KAAO,sBACd,CACF,EAKaE,EAAN,cAAmCF,CAAa,CACrD,aAAc,CACZ,MAAM,4CAA4C,EAClD,KAAK,KAAO,sBACd,CACF,EAKaG,GAAN,cAAqCH,CAAa,CACvD,aAAc,CACZ,MAAM,kCAAkC,EACxC,KAAK,KAAO,wBACd,CACF,EAKaI,GAAN,cAAwBb,CAAS,CACtC,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,WACd,CACF,EAKaa,GAAN,cAAgCD,EAAU,CAC/C,aAAc,CACZ,MAAM,2BAA2B,EACjC,KAAK,KAAO,mBACd,CACF,EAKaE,GAAN,cAAiCF,EAAU,CAChD,aAAc,CACZ,MAAM,8BAA8B,EACpC,KAAK,KAAO,oBACd,CACF,EAKaG,GAAN,cAA0BhB,CAAS,CACxC,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,aACd,CACF,EAKagB,GAAN,cAAkCD,EAAY,CACnD,YAAYE,EAAmB,CAC7B,MAAM,2BAA2BA,CAAS,YAAY,EACtD,KAAK,KAAO,qBACd,CACF,EAKaC,GAAN,cAAkCH,EAAY,CACnD,YAAYI,EAAmB,CAC7B,MAAM,0BAA0BA,CAAS,UAAU,EACnD,KAAK,KAAO,qBACd,CACF,EAyBO,IAAMC,GAAN,cAAyBC,CAAS,CACvC,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,YACd,CACF,EAKaC,GAAN,cAA+BH,EAAW,CAC/C,YAAYI,EAAkBC,EAAgB,CAC5C,MAAM,iBAAiBD,CAAQ,gBAAgBC,CAAM,EAAE,EACvD,KAAK,KAAO,kBACd,CACF,EAKaC,GAAN,cAA+BN,EAAW,CAC/C,aAAc,CACZ,MAAM,gCAAgC,EACtC,KAAK,KAAO,kBACd,CACF,EAKaO,GAAN,cAA0BN,CAAS,CACxC,YAAYC,EAAiBM,EAA2B,CACtD,MAAMN,EAASM,CAAO,EACtB,KAAK,KAAO,aACd,CACF,EAmBaC,EAAN,cAAwBF,EAAY,CACzC,YAAYL,EAAiBM,EAA2B,CACtD,MAAM,4BAA4BN,CAAO,GAAIM,CAAO,EACpD,KAAK,KAAO,WACd,CACF,EAOaE,GAAN,cAA+BH,EAAY,CAChD,YAAYL,EAAiBM,EAA2B,CACtD,MAAM,kCAAkCN,CAAO,GAAIM,CAAO,EAC1D,KAAK,KAAO,kBACd,CACF,EA+DO,IAAMG,EAAN,cAAoCC,CAAS,CAClD,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,uBACd,CACF,EAKaC,GAAN,cAA4CH,CAAsB,CACvE,YAAYI,EAAmBC,EAAqB,CAClD,MACE,sDAAsDA,CAAW,yBAAyBD,CAAS,GACrG,EACA,KAAK,KAAO,+BACd,CACF,EAKaE,GAAN,cAA4CN,CAAsB,CACvE,aAAc,CACZ,MAAM,kDAAkD,EACxD,KAAK,KAAO,+BACd,CACF,EAKaO,EAAN,cAAkCN,CAAS,CAChD,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,qBACd,CACF,EAKaM,GAAN,cAA0CD,CAAoB,CACnE,aAAc,CACZ,MAAM,gDAAgD,EACtD,KAAK,KAAO,6BACd,CACF,EAKaE,GAAN,cAA0CF,CAAoB,CACnE,YAAYG,EAAsBC,EAAqB,CACrD,MACE,mCAAmCD,CAAY,iBAAiBC,CAAW,kDAE7E,EACA,KAAK,KAAO,6BACd,CACF,EAKaC,GAAN,cAA0BX,CAAS,CACxC,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,aACd,CACF,EAKaW,GAAN,cAAuCD,EAAY,CACxD,aAAc,CACZ,MAAM,4BAA4B,EAClC,KAAK,KAAO,0BACd,CACF,EAKaE,GAAN,cAAuCF,EAAY,CACxD,aAAc,CACZ,MAAM,4BAA4B,EAClC,KAAK,KAAO,0BACd,CACF,EAKaG,EAAN,cAAiCd,CAAS,CAC/C,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,oBACd,CACF,EAKac,GAAN,cAAiCD,CAAmB,CACzD,aAAc,CACZ,MACE,yGAEF,EACA,KAAK,KAAO,oBACd,CACF,EAKaE,GAAN,cAAgCF,CAAmB,CACxD,aAAc,CACZ,MAAM,8EAA8E,EACpF,KAAK,KAAO,mBACd,CACF,EAKaG,GAAN,cAAiCH,CAAmB,CACzD,aAAc,CACZ,MAAM,qEAAqE,EAC3E,KAAK,KAAO,oBACd,CACF,EAKaI,GAAN,cAA8BJ,CAAmB,CACtD,aAAc,CACZ,MACE,2HAEF,EACA,KAAK,KAAO,iBACd,CACF,EAKaK,EAAN,cAAiCnB,CAAS,CAC/C,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,oBACd,CACF,EAKamB,GAAN,cAAyCD,CAAmB,CACjE,aAAc,CACZ,MAAM,4BAA4B,EAClC,KAAK,KAAO,4BACd,CACF,EAKaE,GAAN,cAA2CF,CAAmB,CACnE,aAAc,CACZ,MAAM,0CAA0C,EAChD,KAAK,KAAO,8BACd,CACF,EAKaG,GAAN,cAA8CH,CAAmB,CACtE,aAAc,CACZ,MAAM,6EAA6E,EACnF,KAAK,KAAO,iCACd,CACF,ECpdA,IAAMI,GAAc,IAAI,YAKlBC,GAAc,IAAI,YAKXC,GAAmB,GAQnBC,GAAmB,GAKnBC,GAA2B,GAK3BC,GAAa,EAKbC,GAAa,KAKbC,GAAiB,GAKjBC,GAAc,OAAO,iBAYrBC,GAAa,GA8BpBC,GAAkB,OAAO,4BAA4B,EAwB3D,SAASC,EACPC,EACAC,EACAC,EACyB,CACzB,GAAI,OAAOD,GAAU,UAAY,CAAC,OAAO,cAAcA,CAAK,EAC1D,MAAM,IAAIE,EAAmB,cAAcH,CAAI,0BAA0B,EAE3E,GAAIC,EAAQC,EACV,MAAM,IAAIC,EAAmB,cAAcH,CAAI,gBAAgBE,CAAG,EAAE,CAExE,CAQA,IAAME,EAAoC,OAAO,OAAO,CACtD,iBAAAd,GACA,iBAAAC,GACA,WAAAE,GACA,WAAAC,GACA,YAAAE,GACA,WAAAC,GACA,CAACC,EAAe,EAAG,EACrB,CAAC,EA8CM,SAASO,EAAiBC,EAAsD,CACrF,GAAI,CAACA,EACH,OAAOF,EAGLE,EAAO,mBAAqB,QAC9BP,EAA2B,mBAAoBO,EAAO,iBAAkB,CAAC,EAGvEA,EAAO,mBAAqB,QAC9BP,EAA2B,mBAAoBO,EAAO,iBAAkB,CAAC,EAGvEA,EAAO,aAAe,QACxBP,EAA2B,aAAcO,EAAO,WAAY,CAAC,EAG3DA,EAAO,aAAe,QACxBP,EAA2B,aAAcO,EAAO,WAAY,CAAC,EAG3DA,EAAO,cAAgB,QACzBP,EAA2B,cAAeO,EAAO,YAAa,CAAC,EAG7DA,EAAO,aAAe,QACxBP,EAA2B,aAAcO,EAAO,WAAY,CAAC,EAG/D,IAAMC,EAAS,CACb,GAAGH,EACH,GAAGE,CACL,EAEA,GAAIC,EAAO,iBAAmBA,EAAO,iBACnC,MAAM,IAAIJ,EAAmB,4DAA4D,EAG3F,GAAII,EAAO,WAAaA,EAAO,WAC7B,MAAM,IAAIJ,EAAmB,gDAAgD,EAG/E,OAAO,OAAO,OAAO,CACnB,GAAGI,EACH,CAACT,EAAe,EAAG,EACrB,CAAC,CACH,CAgDO,SAASU,EACdC,EACAC,EAA4BC,EACtB,CACN,GAAIF,EAAO,OAASC,EAAW,iBAC7B,MAAM,IAAIE,GAAoBF,EAAW,iBAAkBD,EAAO,MAAM,EAG1E,GAAIA,EAAO,OAASC,EAAW,iBAC7B,MAAM,IAAIG,GAAmBH,EAAW,iBAAkBD,EAAO,MAAM,CAE3E,CAUO,SAASK,GACdC,EACAL,EAA4BC,EACtB,CACN,GAAI,OAAOI,GAAY,SAAU,CAC/B,GAAI,CAAC,OAAO,SAASA,CAAO,GAAK,CAAC,OAAO,UAAUA,CAAO,EACxD,MAAM,IAAIC,GAGZ,GAAI,CAAC,OAAO,cAAcD,CAAO,EAE/B,MAAM,IAAIE,CAEd,CAEA,IAAMC,EAAQ,OAAOH,GAAY,SAAWA,EAAU,OAAOA,CAAO,EAEpE,GAAIG,EAAQ,GACV,MAAM,IAAIC,GAGZ,GAAID,EAAQ,OAAOR,EAAW,WAAW,EACvC,MAAM,IAAIO,CAEd,CAQO,SAASG,GAAaC,EAAoB,CAC/C,GAAI,CAAC,OAAO,SAASA,CAAI,EACvB,MAAM,IAAIC,GAGZ,GAAID,EAAO,EACT,MAAM,IAAIE,EAEd,CAUO,SAASC,GACdC,EACAf,EAA4BC,EACtB,CACN,GAAI,CAAC,OAAO,UAAUc,CAAM,GAAKA,EAASf,EAAW,WACnD,MAAM,IAAIgB,GAAoBhB,EAAW,UAAU,EAGrD,GAAIe,EAASf,EAAW,WACtB,MAAM,IAAIiB,GAAoBjB,EAAW,UAAU,CAEvD,CAUO,SAASkB,GAAcC,EAAeC,EAAsB,CACjE,GAAID,EAAM,SAAWC,EACnB,MAAM,IAAIC,GAAiBD,EAAQD,EAAM,MAAM,EAGjD,GAAI,CAAC,QAAQ,KAAKA,CAAK,EACrB,MAAM,IAAIG,EAEd,CAmBO,SAASC,GACdC,EACAxB,EAA4BC,EACtB,CACN,GAAM,CAACwB,EAAMC,CAAM,EAAIC,GAA0BH,CAAgB,EAEjE,GAAI,CAAC,OAAO,cAAcC,CAAI,GAAK,CAAC,OAAO,cAAcC,CAAM,EAC7D,MAAM,IAAIE,EAAsB,gDAAgD,EAGlF,GAAIH,EAAO,GAAKC,EAAS,EACvB,MAAM,IAAIG,GAGZ,IAAMC,EAAcL,EAAOC,EAAS,EAEpC,GAAII,EAAc9B,EAAW,WAC3B,MAAM,IAAI+B,GAA8B/B,EAAW,WAAY8B,CAAW,CAE9E,CAuBO,SAASE,GACdC,EACAlB,EAAiBmB,GACjBlC,EAA4BC,EACtB,CACN,GAAM,CAACkC,EAAeC,CAAe,EAAI,MAAM,QAAQH,CAAc,EACjEA,EACA,CAACA,EAAgBA,CAAc,EAEnC,GAAI,CAAC,OAAO,cAAcE,CAAa,GAAK,CAAC,OAAO,cAAcC,CAAe,EAC/E,MAAM,IAAIC,EAAoB,8CAA8C,EAI9E,GAAIF,EAAgB,GAAKC,EAAkB,EACzC,MAAM,IAAIE,GAKZ,IAAMC,GAAuBvC,EAAW,WAAa,GAAKe,EACpDyB,EAAwBL,EAAgBC,EAE9C,GAAII,EAAwBD,EAC1B,MAAM,IAAIE,GAA4BF,EAAqBC,CAAqB,CAEpF,CAaO,SAASE,GAAelC,EAAoC,CACjE,IAAMmC,EAAc,OAAOnC,GAAU,SAAWA,EAAQ,OAAOA,CAAK,EAC9DoC,EAAS,IAAI,YAAY,CAAC,EAGhC,OAFa,IAAI,SAASA,CAAM,EAE3B,aAAa,EAAGD,EAAa,EAAK,EAEhC,IAAI,WAAWC,CAAM,CAC9B,CAkBO,SAASC,GAAgBC,EAAgC,CAC9D,IAAMC,EAASD,EAAWA,EAAW,OAAS,CAAC,EAAI,GAQnD,OALIA,EAAWC,CAAM,EAAI,MAAS,GAC/BD,EAAWC,EAAS,CAAC,GAAK,GAC1BD,EAAWC,EAAS,CAAC,GAAK,EAC3BD,EAAWC,EAAS,CAAC,CAGzB,CAgBO,SAASC,GAAexC,EAAeY,EAAwB,CACpE,IAAM6B,EAAS,IAAM7B,EAErB,OADYZ,EAAQyC,GACT,SAAS,EAAE,SAAS7B,EAAQ,GAAG,CAC5C,CAWO,SAAS8B,GAAwBC,EAAeC,EAAwB,CAC7E,OAAOD,EAAE,SAAWC,EAAE,MACxB,CAeO,SAASC,GAAkBF,EAAwBC,EAAiC,CACzF,IAAME,EAAOC,GAAcJ,CAAC,EACtBK,EAAOD,GAAcH,CAAC,EAE5B,GAAI,CAACF,GAAwBI,EAAME,CAAI,EACrC,MAAO,GAGT,IAAIC,EAAS,EACb,QAASC,EAAI,EAAGA,EAAIJ,EAAK,OAAQI,IAC/BD,GAAUH,EAAKI,CAAC,EAAIF,EAAKE,CAAC,EAG5B,OAAOD,IAAW,CACpB,CA0CO,SAASE,GAAcC,EAAwC,CACpE,OAAO,OAAOA,GAAU,SAAWC,GAAY,OAAOD,CAAK,EAAIA,CACjE,CAiDO,SAASE,EACdC,EACAC,EACY,CACZ,OAAI,OAAOD,GAAW,UACpBE,EAAoBD,CAAM,EACnBA,EAAO,OAAOD,CAAM,GAEtBA,CACT,CAkCO,SAASG,EAAeC,EAAgC,CAC7D,GAAM,CAAE,OAAAC,EAAQ,OAAAJ,EAAQ,OAAAK,EAASC,EAAyB,EAAIH,EAE9DI,EAAoBH,CAAM,EAC1BH,EAAoBD,CAAM,EAE1B,IAAMQ,EAAcJ,EAAO,YAAYC,CAAM,EAC7C,OAAOL,EAAO,OAAOQ,EAAa,CAAE,QAAS,EAAM,CAAC,CACtD,CAuBO,SAASC,GACdC,EAA8C,EAC5B,CAClB,OAAO,MAAM,QAAQA,CAAgB,EAAIA,EAAmB,CAAC,EAAGA,CAAgB,CAClF,CAoBO,SAASC,GACdC,EAA4C,EAC1B,CAClB,OAAO,MAAM,QAAQA,CAAc,EAAIA,EAAiB,CAACA,EAAgBA,CAAc,CACzF,CAQO,SAASL,EAAuBH,EAA4C,CACjF,GAAI,CAACA,EACH,MAAM,IAAIS,EAEd,CAQO,SAASZ,EAAuBD,EAA4C,CACjF,GAAI,CAACA,EACH,MAAM,IAAIc,EAEd,CAQO,SAASC,EAAiBhB,EAA4C,CAC3E,GAAI,CAACA,EACH,MAAM,IAAIiB,EAEd,CAQO,SAASC,GAAaC,EAAoD,CAC/E,GAAI,CAACA,EACH,MAAM,IAAIC,EAEd,CAQO,SAASC,GAAcC,EAAsD,CAClF,GAAI,CAACA,EACH,MAAM,IAAIC,EAEd,CAQO,SAASC,GAAoBxB,EAAuD,CACzF,GAAI,OAAOA,GAAW,SACpB,MAAM,IAAIyB,EAEd,CAMA,SAASC,GAAMC,EAA0B,CACvC,MAAO,CAAE,GAAI,GAAM,MAAAA,CAAM,CAC3B,CAMA,SAASC,GAAOC,EAA6B,CAC3C,MAAO,CAAE,GAAI,GAAO,MAAAA,CAAM,CAC5B,CAUO,SAASC,GACdC,EAC2C,CAC3C,MAAO,IAAIC,IAAuC,CAChD,GAAI,CACF,OAAON,GAAGK,EAAG,GAAGC,CAAI,CAAC,CACvB,OAASH,EAAO,CACd,OAAOD,GAAIC,CAAiB,CAC9B,CACF,CACF,CAUO,SAASI,GACdF,EACoD,CACpD,MAAO,UAAUC,IAAgD,CAC/D,GAAI,CACF,OAAON,GAAG,MAAMK,EAAG,GAAGC,CAAI,CAAC,CAC7B,OAASH,EAAO,CACd,OAAOD,GAAIC,CAAiB,CAC9B,CACF,CACF,CCh6BO,IAAMK,GAAN,KAAoB,CAMzB,YAA6BC,EAAsB,CAAtB,YAAAA,CAAuB,CAKpD,IAAI,QAAuB,CACzB,OAAO,KAAK,MACd,CAWA,MAAM,KAAKC,EAA0BC,EAAiBC,EAAuC,CAC3F,GAAI,CACF,IAAMC,EAAS,KAAK,OAAO,KAAKH,EAAWC,EAAKC,CAAI,EACpD,OAAOC,aAAkB,QAAU,MAAMA,EAASA,CACpD,OAASC,EAAO,CACd,IAAMC,EAAUD,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,EACrE,MAAM,IAAIE,EAAUD,EAAS,CAAE,MAAOD,CAAM,CAAC,CAC/C,CACF,CAWA,SAASJ,EAA0BC,EAAiBC,EAA8B,CAChF,GAAI,CACF,IAAMC,EAAS,KAAK,OAAO,KAAKH,EAAWC,EAAKC,CAAI,EACpD,GAAIC,aAAkB,QACpB,MAAM,IAAIG,EAAU,4DAA4D,EAElF,OAAOH,CACT,OAASC,EAAO,CACd,GAAIA,aAAiBE,EACnB,MAAMF,EAER,IAAMC,EAAUD,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,EACrE,MAAM,IAAIE,EAAUD,EAAS,CAAE,MAAOD,CAAM,CAAC,CAC/C,CACF,CASA,YAAYG,EAA4B,CACtC,GAAI,CACF,OAAO,KAAK,OAAO,YAAYA,CAAM,CACvC,OAASH,EAAO,CACd,IAAMC,EAAUD,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,EACrE,MAAM,IAAII,GAAiBH,EAAS,CAAE,MAAOD,CAAM,CAAC,CACtD,CACF,CACF,EAQO,SAASK,GAAoBV,EAAqC,CACvE,OAAO,IAAID,GAAcC,CAAM,CACjC,CCLO,SAASW,GAASC,EAAyB,CAChD,GAAM,CAAE,KAAAC,EAAM,MAAAC,EAAO,OAAAC,CAAO,EAAIH,EAG1BI,EAAeF,EAClB,MAAM,GAAG,EACT,IAAKG,GAAS,mBAAmBA,CAAI,CAAC,EACtC,KAAK,GAAG,EAEPC,EAAS,aAAaL,CAAI,IAAIG,CAAY,IAExCG,EAAwB,CAAC,EAE/B,OAAIJ,EAAO,QACTI,EAAY,KAAK,UAAU,mBAAmBJ,EAAO,MAAM,CAAC,EAAE,EAG5DA,EAAO,QACTI,EAAY,KAAK,UAAU,mBAAmBJ,EAAO,MAAM,CAAC,EAAE,EAG5DA,EAAO,WAAaA,EAAO,YAAc,QAC3CI,EAAY,KAAK,aAAaJ,EAAO,UAAU,YAAY,CAAC,EAAE,EAG5DA,EAAO,QAAUA,EAAO,SAAW,GACrCI,EAAY,KAAK,UAAUJ,EAAO,MAAM,EAAE,EAGxCF,IAAS,QAAUE,EAAO,UAAY,QACxCI,EAAY,KAAK,WAAWJ,EAAO,OAAO,EAAE,EAG1CF,IAAS,QAAUE,EAAO,SAAW,QAAaA,EAAO,SAAW,IACtEI,EAAY,KAAK,UAAUJ,EAAO,MAAM,EAAE,EAG5CG,GAAUC,EAAY,KAAK,GAAG,EAEvBD,CACT,CAQO,SAASE,GAAaC,EAAqE,CAChG,GAAM,CAAE,OAAAC,EAAQ,MAAOC,EAAS,OAAAC,EAAQ,UAAAC,EAAY,OAAQ,OAAAC,EAAS,EAAG,OAAAC,EAAS,EAAG,EAAIN,EAElFO,EAAYN,EAAS,GAAGA,CAAM,IAAIC,CAAO,GAAKA,EAEpD,OAAOZ,GAAS,CACd,KAAM,OACN,MAAOiB,EACP,OAAQ,CACN,OAAAJ,EACA,OAAAF,EACA,UAAAG,EACA,OAAAC,EACA,OAAAC,CACF,CACF,CAAC,CACH,CAQO,SAASE,GAAaR,EAAqE,CAChG,GAAM,CAAE,OAAAC,EAAQ,MAAOC,EAAS,OAAAC,EAAQ,QAAAM,EAAU,EAAG,UAAAL,EAAY,OAAQ,OAAAC,EAAS,CAAE,EAAIL,EAElFO,EAAYN,EAAS,GAAGA,CAAM,IAAIC,CAAO,GAAKA,EAEpD,OAAOZ,GAAS,CACd,KAAM,OACN,MAAOiB,EACP,OAAQ,CACN,OAAAJ,EACA,OAAAF,EACA,UAAAG,EACA,OAAAC,EACA,QAAAI,CACF,CACF,CAAC,CACH,CClIO,IAAMC,GAAN,KAAW,CACC,QACA,WAEjB,YAAYC,EAAuB,CAAC,EAAG,CACrC,KAAK,QAAUA,EACf,KAAK,WAAaC,EAAiBD,EAAQ,UAAU,CACvD,CAOA,gBAAyB,CACvB,GAAM,CAAE,OAAAE,EAAQ,OAAAC,CAAO,EAAI,KAAK,QAEhC,OAAAC,EAAoBF,CAAM,EAC1BG,EAAoBF,CAAM,EAEnBG,EAAmB,CAAE,OAAAJ,EAAQ,OAAAC,CAAO,CAAC,CAC9C,CASA,MAAM,SAASI,EAAiBP,EAAiD,CAC/E,IAAMQ,EAAgB,CAAE,GAAG,KAAK,QAAS,GAAGR,CAAQ,EAC9C,CAAE,OAAAS,EAAQ,OAAAP,EAAQ,OAAAC,EAAQ,UAAAO,EAAY,OAAQ,OAAAC,EAAS,CAAE,EAAIH,EAEnEI,EAAcH,CAAM,EACpBL,EAAoBF,CAAM,EAG1B,IAAMW,EAAab,GAAS,YAAc,KAAK,WAE/C,OAAOc,EAAa,CAClB,OAAAL,EACA,QAAAF,EACA,UAAAG,EACA,OAAAC,EACA,OAAAT,EACA,OAAAC,EACA,WAAAU,EACA,MAAOL,EAAc,KACvB,CAAC,CACH,CASA,MAAM,OACJO,EACAf,EACuB,CACvB,IAAMQ,EAAgB,CAAE,GAAG,KAAK,QAAS,GAAGR,CAAQ,EAC9C,CACJ,OAAAS,EACA,OAAAP,EACA,OAAAC,EACA,UAAAO,EAAY,OACZ,OAAAC,EAAS,EACT,iBAAAK,EAAmB,CACrB,EAAIR,EAEJI,EAAcH,CAAM,EACpBL,EAAoBF,CAAM,EAG1B,IAAMW,EAAab,GAAS,YAAc,KAAK,WAE/C,OAAOiB,GAAW,CAChB,OAAAR,EACA,MAAOM,EAAO,MACd,QAASA,EAAO,QAChB,UAAAL,EACA,OAAAC,EACA,iBAAAK,EACA,OAAAd,EACA,OAAAC,EACA,WAAAU,EACA,MAAOL,EAAc,KACvB,CAAC,CACH,CAQA,MAAMD,EAAkB,EAAW,CACjC,GAAM,CAAE,OAAAW,EAAQ,MAAAC,EAAO,OAAAV,EAAQ,UAAAC,EAAY,OAAQ,OAAAC,EAAS,CAAE,EAAI,KAAK,QAEvE,OAAAC,EAAcH,CAAM,EACpBW,GAAaD,CAAK,EAClBE,GAAcH,CAAM,EACpBI,GAAoBb,CAAM,EAEnBc,GAAgB,CACrB,OAAAL,EACA,MAAAC,EACA,OAAAV,EACA,UAAAC,EACA,OAAAC,EACA,QAAAJ,CACF,CAAC,CACH,CACF,EC9GA,SAASiB,GAAuBC,EAA2D,CACzF,GAAM,CACJ,OAAAC,EACA,QAAAC,EACA,UAAAC,EAAY,OACZ,OAAAC,EAAS,EACT,OAAAC,EACA,OAAAC,EACA,WAAAC,EACA,MAAAC,CACF,EAAIR,EAEJS,EAAcR,CAAM,EACpBS,EAAoBL,CAAM,EAE1B,IAAMM,EAAcC,EAAgBX,EAAQK,CAAM,EAClDO,EAAeF,EAAaJ,CAAU,EACtCO,GAAgBZ,EAASK,CAAU,EAEnC,IAAMQ,EAAMC,GAAoBX,CAAM,EAChCY,EAAeC,GAAehB,CAAO,EAE3C,MAAO,CAAE,IAAAa,EAAK,UAAAZ,EAAW,OAAAC,EAAQ,YAAAO,EAAa,aAAAM,EAAc,MAAAT,CAAM,CACpE,CA+BA,eAAsBW,EAASnB,EAA+C,CAC5E,GAAM,CAAE,IAAAe,EAAK,UAAAZ,EAAW,OAAAC,EAAQ,YAAAO,EAAa,aAAAM,EAAc,MAAAT,CAAM,EAC/DT,GAAuBC,CAAO,EAC1BoB,EAAO,MAAML,EAAI,KAAKZ,EAAWQ,EAAaM,CAAY,EAC1DI,EAAKb,GAAO,eAAiBA,EAAM,eAAeY,CAAI,EAAIE,GAAgBF,CAAI,EAEpF,OAAOZ,GAAO,YAAcA,EAAM,YAAYa,EAAIjB,CAAM,EAAImB,GAAeF,EAAIjB,CAAM,CACvF,CA8BO,SAASoB,GAAaxB,EAAsC,CACjE,GAAM,CAAE,IAAAe,EAAK,UAAAZ,EAAW,OAAAC,EAAQ,YAAAO,EAAa,aAAAM,EAAc,MAAAT,CAAM,EAC/DT,GAAuBC,CAAO,EAC1BoB,EAAOL,EAAI,SAASZ,EAAWQ,EAAaM,CAAY,EACxDI,EAAKb,GAAO,eAAiBA,EAAM,eAAeY,CAAI,EAAIE,GAAgBF,CAAI,EAEpF,OAAOZ,GAAO,YAAcA,EAAM,YAAYa,EAAIjB,CAAM,EAAImB,GAAeF,EAAIjB,CAAM,CACvF,CA2BA,SAASqB,GAAqBzB,EAAuD,CACnF,GAAM,CACJ,OAAAC,EACA,QAAAC,EACA,MAAAwB,EACA,UAAAvB,EAAY,OACZ,OAAAC,EAAS,EACT,OAAAC,EACA,OAAAC,EACA,iBAAAqB,EAAmB,EACnB,WAAApB,EAAaqB,EAAiB,EAC9B,MAAApB,CACF,EAAIR,EAEJS,EAAcR,CAAM,EACpBS,EAAoBL,CAAM,EAE1B,IAAMM,EAAcC,EAAgBX,EAAQK,CAAM,EAClDO,EAAeF,EAAaJ,CAAU,EACtCO,GAAgBZ,EAASK,CAAU,EAG/BC,GAAO,cACTA,EAAM,cAAckB,EAAOtB,CAAM,EAEjCyB,GAAcH,EAAOtB,CAAM,EAG7B0B,GAAyBH,EAAkBpB,CAAU,EAErD,IAAMwB,EAAa,OAAO7B,GAAY,SAAW,OAAOA,CAAO,EAAIA,EAC7D,CAAC8B,EAAMC,CAAM,EAAIC,GAA0BP,CAAgB,EAC3DQ,EAAcH,EAAOC,EAAS,EAEpC,MAAO,CACL,MAAAP,EACA,WAAAK,EACA,KAAAC,EACA,OAAAC,EACA,YAAAE,EACA,OAAA9B,EACA,mBAAqB+B,IAAiB,CACpC,OAAQzB,EACR,QAASyB,EACT,UAAAjC,EACA,OAAAC,EACA,OAAAC,EACA,WAAAE,EACA,MAAAC,CACF,EACF,CACF,CA2DA,eAAsB6B,GAAOrC,EAAmD,CAC9E,GAAM,CAAE,MAAA0B,EAAO,WAAAK,EAAY,KAAAC,EAAM,YAAAG,EAAa,OAAA9B,EAAQ,mBAAAiC,CAAmB,EACvEb,GAAqBzB,CAAO,EAKxBuC,EAAS,KAAK,IAAI,EAAGP,EAAOD,CAAU,EAI5C,QAASS,EAAID,EAAQC,EAAIL,EAAaK,IAAK,CACzC,IAAMC,EAASD,EAAIR,EACbU,EAAiBX,EAAaU,EAG9BE,EAAW,MAAMxB,EAASmB,EAAmBI,CAAc,CAAC,EAClE,GAAIrC,EAAO,kBAAkBsC,EAAUjB,CAAK,EAC1C,MAAO,CAAE,MAAO,GAAM,MAAOe,EAAS,CAAE,CAE5C,CAEA,MAAO,CAAE,MAAO,EAAM,CACxB,CA8BO,SAASG,GAAW5C,EAA0C,CACnE,GAAM,CAAE,MAAA0B,EAAO,WAAAK,EAAY,KAAAC,EAAM,YAAAG,EAAa,OAAA9B,EAAQ,mBAAAiC,CAAmB,EACvEb,GAAqBzB,CAAO,EAKxBuC,EAAS,KAAK,IAAI,EAAGP,EAAOD,CAAU,EAI5C,QAASS,EAAID,EAAQC,EAAIL,EAAaK,IAAK,CACzC,IAAMC,EAASD,EAAIR,EACbU,EAAiBX,EAAaU,EAG9BE,EAAWnB,GAAac,EAAmBI,CAAc,CAAC,EAChE,GAAIrC,EAAO,kBAAkBsC,EAAUjB,CAAK,EAC1C,MAAO,CAAE,MAAO,GAAM,MAAOe,EAAS,CAAE,CAE5C,CAEA,MAAO,CAAE,MAAO,EAAM,CACxB,CC9TO,IAAMI,GAAN,KAAW,CACC,QACA,WAEjB,YAAYC,EAAuB,CAAC,EAAG,CACrC,KAAK,QAAUA,EACf,KAAK,WAAaC,EAAiBD,EAAQ,UAAU,CACvD,CAOA,gBAAyB,CACvB,GAAM,CAAE,OAAAE,EAAQ,OAAAC,CAAO,EAAI,KAAK,QAEhC,OAAAC,EAAoBF,CAAM,EAC1BG,EAAoBF,CAAM,EAEnBG,EAAmB,CAAE,OAAAJ,EAAQ,OAAAC,CAAO,CAAC,CAC9C,CAQA,MAAM,SAASH,EAAiD,CAC9D,IAAMO,EAAgB,CAAE,GAAG,KAAK,QAAS,GAAGP,CAAQ,EAC9C,CACJ,OAAAQ,EACA,OAAAN,EACA,OAAAC,EACA,UAAAM,EAAY,OACZ,OAAAC,EAAS,EACT,OAAAC,EAAS,GACT,MAAAC,EACA,GAAAC,EAAK,CACP,EAAIN,EAEJO,EAAcN,CAAM,EACpBJ,EAAoBF,CAAM,EAG1B,IAAMa,EAAaf,GAAS,YAAc,KAAK,WAE/C,OAAOgB,GAAa,CAClB,OAAAR,EACA,UAAAC,EACA,OAAAC,EACA,OAAAC,EACA,MAAOC,GAAS,KAAK,MAAM,KAAK,IAAI,EAAI,GAAI,EAC5C,GAAAC,EACA,OAAAX,EACA,OAAAC,EACA,WAAAY,EACA,MAAOR,EAAc,KACvB,CAAC,CACH,CASA,MAAM,OACJU,EACAjB,EACuB,CACvB,IAAMO,EAAgB,CAAE,GAAG,KAAK,QAAS,GAAGP,CAAQ,EAC9C,CACJ,OAAAQ,EACA,OAAAN,EACA,OAAAC,EACA,UAAAM,EAAY,OACZ,OAAAC,EAAS,EACT,OAAAC,EAAS,GACT,MAAAC,EACA,GAAAC,EAAK,EACL,eAAAK,EAAiB,EACjB,cAAAC,CACF,EAAIZ,EAEJO,EAAcN,CAAM,EACpBJ,EAAoBF,CAAM,EAG1B,IAAMa,EAAaf,GAAS,YAAc,KAAK,WAE/C,OAAOoB,GAAW,CAChB,OAAAZ,EACA,MAAAS,EACA,UAAAR,EACA,OAAAC,EACA,OAAAC,EACA,MAAOC,GAAS,KAAK,MAAM,KAAK,IAAI,EAAI,GAAI,EAC5C,GAAAC,EACA,eAAAK,EACA,cAAAC,EACA,OAAAjB,EACA,OAAAC,EACA,WAAAY,EACA,MAAOR,EAAc,KACvB,CAAC,CACH,CAwCA,MAAMP,EAAwE,CAC5E,GAAM,CACJ,OAAQqB,EACR,MAAOC,EACP,OAAQC,EACR,UAAAd,EAAY,OACZ,OAAAC,EAAS,EACT,OAAAC,EAAS,EACX,EAAI,KAAK,QAGHa,EAAaxB,GAAS,OAASsB,EAC/BG,EAAczB,GAAS,QAAUqB,EACjCK,EAAc1B,GAAS,QAAUuB,EAEvC,OAAAT,EAAcY,CAAW,EACzBC,GAAaH,CAAU,EACvBI,GAAcH,CAAW,EACzBI,GAAoBH,CAAW,EAExBI,GAAgB,CACrB,OAAQL,EACR,MAAOD,EACP,OAAQE,EACR,UAAAjB,EACA,OAAAC,EACA,OAAAC,CACF,CAAC,CACH,CACF,ECrKA,SAASoB,GAAuBC,EAA2D,CACzF,GAAM,CACJ,OAAAC,EACA,MAAAC,EAAQ,KAAK,MAAM,KAAK,IAAI,EAAI,GAAI,EACpC,GAAAC,EAAK,EACL,OAAAC,EAAS,GACT,UAAAC,EAAY,OACZ,OAAAC,EAAS,EACT,OAAAC,EACA,OAAAC,EACA,WAAAC,EAAaC,EAAiB,EAC9B,MAAAC,CACF,EAAIX,EAEJY,EAAcX,CAAM,EACpBY,EAAoBN,CAAM,EAE1B,IAAMO,EAAcC,EAAgBd,EAAQO,CAAM,EAClDQ,EAAeF,EAAaL,CAAU,EACtCQ,GAAaf,CAAK,EAClBgB,GAAed,EAAQK,CAAU,EAEjC,IAAMU,EAAU,KAAK,OAAOjB,EAAQC,GAAMC,CAAM,EAEhD,MAAO,CACL,OAAQU,EACR,QAAAK,EACA,UAAAd,EACA,OAAAC,EACA,OAAAC,EACA,WAAAE,EACA,MAAAE,CACF,CACF,CAsCA,eAAsBS,GAASpB,EAA+C,CAC5E,IAAMqB,EAAMtB,GAAuBC,CAAO,EAC1C,OAAOoB,EAAaC,CAAG,CACzB,CA+BO,SAASC,GAAatB,EAAsC,CACjE,IAAMqB,EAAMtB,GAAuBC,CAAO,EAC1C,OAAOsB,GAAiBD,CAAG,CAC7B,CAgBA,SAASE,GAAsBC,EAAmCC,EAA0B,CAC1F,GAAID,IAAkB,OAItB,IAAIA,EAAgB,EAClB,MAAM,IAAIE,GAGZ,GAAI,CAAC,OAAO,cAAcF,CAAa,EACrC,MAAM,IAAIG,GAGZ,GAAIH,EAAgBC,EAClB,MAAM,IAAIG,GAEd,CAMA,SAASC,GAAwBV,EAAiBK,EAA4C,CAC5F,OAAOA,IAAkB,QAAaL,GAAWK,CACnD,CA6BA,SAASM,GAAqB9B,EAAuD,CACnF,GAAM,CACJ,OAAAC,EACA,MAAA8B,EACA,MAAA7B,EAAQ,KAAK,MAAM,KAAK,IAAI,EAAI,GAAI,EACpC,GAAAC,EAAK,EACL,OAAAC,EAAS,GACT,UAAAC,EAAY,OACZ,OAAAC,EAAS,EACT,OAAAC,EACA,OAAAC,EACA,eAAAwB,EAAiB,EACjB,cAAAR,EACA,WAAAf,EAAaC,EAAiB,EAC9B,MAAAC,CACF,EAAIX,EAEJY,EAAcX,CAAM,EACpBY,EAAoBN,CAAM,EAE1B,IAAMO,EAAcC,EAAgBd,EAAQO,CAAM,EAClDQ,EAAeF,EAAaL,CAAU,EACtCQ,GAAaf,CAAK,EAClBgB,GAAed,EAAQK,CAAU,EAG7BE,GAAO,cACTA,EAAM,cAAcoB,EAAOzB,CAAM,EAEjC2B,GAAcF,EAAOzB,CAAM,EAG7B4B,GAAuBF,EAAgB5B,EAAQK,CAAU,EAEzD,IAAM0B,EAAiB,KAAK,OAAOjC,EAAQC,GAAMC,CAAM,EAGjD,CAACgC,EAAeC,CAAe,EAAIC,GAAwBN,CAAc,EAIzEO,EAAa,KAAK,IAAI,EAAG,KAAK,OAAOrC,EAAQkC,EAAgBjC,GAAMC,CAAM,CAAC,EAC1EqB,EAAa,KAAK,OAAOvB,EAAQmC,EAAkBlC,GAAMC,CAAM,EAGrE,OAAAmB,GAAsBC,EAAeC,CAAU,EAExC,CACL,MAAAM,EACA,OAAAxB,EACA,WAAAgC,EACA,WAAAd,EACA,eAAAU,EACA,GAAAhC,EACA,OAAAC,EACA,cAAAoB,EACA,mBAAqBL,IAAqB,CACxC,OAAQL,EACR,MAAOK,EAAUf,EAASD,EAC1B,GAAAA,EACA,OAAAC,EACA,UAAAC,EACA,OAAAC,EACA,OAAAC,EACA,WAAAE,EACA,MAAAE,CACF,EACF,CACF,CAiCA,eAAsB6B,GAAOxC,EAAmD,CAC9E,GAAM,CACJ,MAAA+B,EACA,OAAAxB,EACA,WAAAgC,EACA,WAAAd,EACA,eAAAU,EACA,GAAAhC,EACA,OAAAC,EACA,cAAAoB,EACA,mBAAAiB,CACF,EAAIX,GAAqB9B,CAAO,EAEhC,QAASmB,EAAUoB,EAAYpB,GAAWM,EAAYN,IAAW,CAE/D,GAAIU,GAAwBV,EAASK,CAAa,EAChD,SAGF,IAAMkB,EAAW,MAAMtB,GAASqB,EAAmBtB,CAAO,CAAC,EAC3D,GAAIZ,EAAO,kBAAkBmC,EAAUX,CAAK,EAC1C,MAAO,CACL,MAAO,GACP,MAAOZ,EAAUgB,EACjB,MAAOhB,EAAUf,EAASD,EAC1B,SAAUgB,CACZ,CAEJ,CAEA,MAAO,CAAE,MAAO,EAAM,CACxB,CAgCO,SAASwB,GAAW3C,EAA0C,CACnE,GAAM,CACJ,MAAA+B,EACA,OAAAxB,EACA,WAAAgC,EACA,WAAAd,EACA,eAAAU,EACA,GAAAhC,EACA,OAAAC,EACA,cAAAoB,EACA,mBAAAiB,CACF,EAAIX,GAAqB9B,CAAO,EAEhC,QAASmB,EAAUoB,EAAYpB,GAAWM,EAAYN,IAAW,CAE/D,GAAIU,GAAwBV,EAASK,CAAa,EAChD,SAGF,IAAMkB,EAAWpB,GAAamB,EAAmBtB,CAAO,CAAC,EACzD,GAAIZ,EAAO,kBAAkBmC,EAAUX,CAAK,EAC1C,MAAO,CACL,MAAO,GACP,MAAOZ,EAAUgB,EACjB,MAAOhB,EAAUf,EAASD,EAC1B,SAAUgB,CACZ,CAEJ,CAEA,MAAO,CAAE,MAAO,EAAM,CACxB,CChSA,SAASyB,GAAQC,EAAU,CAKzB,OACEA,aAAa,YACZ,YAAY,OAAOA,CAAC,GACnBA,EAAE,YAAY,OAAS,cACvB,sBAAuBA,GACvBA,EAAE,oBAAsB,CAE9B,CAMA,SAASC,GAAUC,EAAmBC,EAAU,CAC9C,OAAK,MAAM,QAAQA,CAAG,EAClBA,EAAI,SAAW,EAAU,GACzBD,EACKC,EAAI,MAAOC,GAAS,OAAOA,GAAS,QAAQ,EAE5CD,EAAI,MAAOC,GAAS,OAAO,cAAcA,CAAI,CAAC,EALvB,EAOlC,CAOA,SAASC,GAAKC,EAAeC,EAAc,CACzC,GAAI,OAAOA,GAAU,SAAU,MAAM,IAAI,UAAU,GAAGD,CAAK,mBAAmB,EAC9E,MAAO,EACT,CAEA,SAASE,GAAQC,EAAS,CACxB,GAAI,OAAOA,GAAM,SAAU,MAAM,IAAI,UAAU,wBAAwB,OAAOA,CAAC,EAAE,EACjF,GAAI,CAAC,OAAO,cAAcA,CAAC,EAAG,MAAM,IAAI,WAAW,oBAAoBA,CAAC,EAAE,CAC5E,CAEA,SAASC,GAAKH,EAAY,CACxB,GAAI,CAAC,MAAM,QAAQA,CAAK,EAAG,MAAM,IAAI,UAAU,gBAAgB,CACjE,CACA,SAASI,GAAQL,EAAeC,EAAe,CAC7C,GAAI,CAACK,GAAU,GAAML,CAAK,EAAG,MAAM,IAAI,UAAU,GAAGD,CAAK,6BAA6B,CACxF,CACA,SAASO,GAAQP,EAAeC,EAAe,CAC7C,GAAI,CAACK,GAAU,GAAOL,CAAK,EAAG,MAAM,IAAI,UAAU,GAAGD,CAAK,6BAA6B,CACzF,CAqBA,SAASQ,MAAuCC,EAAO,CACrD,IAAMC,EAAMC,GAAWA,EAEjBC,EAAO,CAACD,EAAQE,IAAYC,GAAWH,EAAEE,EAAEC,CAAC,CAAC,EAE7CC,EAASN,EAAK,IAAKO,GAAMA,EAAE,MAAM,EAAE,YAAYJ,EAAMF,CAAE,EAEvDO,EAASR,EAAK,IAAKO,GAAMA,EAAE,MAAM,EAAE,OAAOJ,EAAMF,CAAE,EACxD,MAAO,CAAE,OAAAK,EAAQ,OAAAE,CAAM,CACzB,CAOA,SAASC,GAASC,EAA0B,CAE1C,IAAMC,EAAW,OAAOD,GAAY,SAAWA,EAAQ,MAAM,EAAE,EAAIA,EAC7DE,EAAMD,EAAS,OACrBf,GAAQ,WAAYe,CAAQ,EAG5B,IAAME,EAAU,IAAI,IAAIF,EAAS,IAAI,CAACG,EAAGC,IAAM,CAACD,EAAGC,CAAC,CAAC,CAAC,EACtD,MAAO,CACL,OAASC,IACPrB,GAAKqB,CAAM,EACJA,EAAO,IAAKD,GAAK,CACtB,GAAI,CAAC,OAAO,cAAcA,CAAC,GAAKA,EAAI,GAAKA,GAAKH,EAC5C,MAAM,IAAI,MACR,kDAAkDG,CAAC,eAAeL,CAAO,EAAE,EAE/E,OAAOC,EAASI,CAAC,CACnB,CAAC,GAEH,OAASvB,IACPG,GAAKH,CAAK,EACHA,EAAM,IAAKyB,GAAU,CAC1B3B,GAAK,kBAAmB2B,CAAM,EAC9B,IAAM,EAAIJ,EAAQ,IAAII,CAAM,EAC5B,GAAI,IAAM,OAAW,MAAM,IAAI,MAAM,oBAAoBA,CAAM,eAAeP,CAAO,EAAE,EACvF,OAAO,CACT,CAAC,GAGP,CAKA,SAASQ,GAAKC,EAAY,GAAE,CAC1B,OAAA7B,GAAK,OAAQ6B,CAAS,EAGf,CACL,OAASC,IACPxB,GAAQ,cAAewB,CAAI,EACpBA,EAAK,KAAKD,CAAS,GAE5B,OAASE,IACP/B,GAAK,cAAe+B,CAAE,EACfA,EAAG,MAAMF,CAAS,GAG/B,CAMA,SAASG,GAAQC,EAAcC,EAAM,IAAG,CACtC,OAAA/B,GAAQ8B,CAAI,EACZjC,GAAK,UAAWkC,CAAG,EACZ,CACL,OAAOC,EAAc,CAInB,IAHA7B,GAAQ,iBAAkB6B,CAAI,EAGtBA,EAAK,OAASF,EAAQ,GAAGE,EAAK,KAAKD,CAAG,EAC9C,OAAOC,CACT,EACA,OAAOjC,EAAe,CACpBI,GAAQ,iBAAkBJ,CAAK,EAC/B,IAAIkC,EAAMlC,EAAM,OAChB,GAAKkC,EAAMH,EAAQ,EACjB,MAAM,IAAI,MAAM,4DAA4D,EAC9E,KAAOG,EAAM,GAAKlC,EAAMkC,EAAM,CAAC,IAAMF,EAAKE,IAGxC,IAFaA,EAAM,GACCH,EACT,IAAM,EAAG,MAAM,IAAI,MAAM,+CAA+C,EAErF,OAAO/B,EAAM,MAAM,EAAGkC,CAAG,CAC3B,EAEJ,CA4DA,IAAMC,GAAM,CAACC,EAAWC,IAAuBA,IAAM,EAAID,EAAID,GAAIE,EAAGD,EAAIC,CAAC,EAGnEC,GAAyC,CAACC,EAAcC,IAC5DD,GAAQC,EAAKL,GAAII,EAAMC,CAAE,GACrBC,IAAoC,IAAK,CAC7C,IAAIC,EAAM,CAAA,EACV,QAASC,EAAI,EAAGA,EAAI,GAAIA,IAAKD,EAAI,KAAK,GAAKC,CAAC,EAC5C,OAAOD,CACT,GAAE,EAIF,SAASE,GAAcC,EAAgBN,EAAcC,EAAYM,EAAgB,CAE/E,GADAC,GAAKF,CAAI,EACLN,GAAQ,GAAKA,EAAO,GAAI,MAAM,IAAI,WAAW,6BAA6BA,CAAI,EAAE,EACpF,GAAIC,GAAM,GAAKA,EAAK,GAAI,MAAM,IAAI,WAAW,2BAA2BA,CAAE,EAAE,EAC5E,GAAIF,GAAYC,EAAMC,CAAE,EAAI,GAC1B,MAAM,IAAI,MACR,sCAAsCD,CAAI,OAAOC,CAAE,cAAcF,GAAYC,EAAMC,CAAE,CAAC,EAAE,EAG5F,IAAIQ,EAAQ,EACRC,EAAM,EACJC,EAAMT,GAAOF,CAAI,EACjBY,EAAOV,GAAOD,CAAE,EAAK,EACrBE,EAAgB,CAAA,EACtB,QAAWU,KAAKP,EAAM,CAEpB,GADAQ,GAAQD,CAAC,EACLA,GAAKF,EAAK,MAAM,IAAI,MAAM,oCAAoCE,CAAC,SAASb,CAAI,EAAE,EAElF,GADAS,EAASA,GAAST,EAAQa,EACtBH,EAAMV,EAAO,GAAI,MAAM,IAAI,MAAM,qCAAqCU,CAAG,SAASV,CAAI,EAAE,EAE5F,IADAU,GAAOV,EACAU,GAAOT,EAAIS,GAAOT,EAAIE,EAAI,MAAOM,GAAUC,EAAMT,EAAOW,KAAU,CAAC,EAC1E,IAAMG,EAAMb,GAAOQ,CAAG,EACtB,GAAIK,IAAQ,OAAW,MAAM,IAAI,MAAM,eAAe,EACtDN,GAASM,EAAM,CACjB,CAIA,GAHAN,EAASA,GAAUR,EAAKS,EAAQE,EAG5B,CAACL,GAAWG,GAAOV,EAAM,MAAM,IAAI,MAAM,gBAAgB,EAC7D,GAAI,CAACO,GAAWE,EAAQ,EAAG,MAAM,IAAI,MAAM,qBAAqBA,CAAK,EAAE,EACvE,OAAIF,GAAWG,EAAM,GAAGP,EAAI,KAAKM,IAAU,CAAC,EACrCN,CACT,CA0BA,SAASa,GAAOC,EAAcC,EAAa,GAAK,CAE9C,GADAC,GAAQF,CAAI,EACRA,GAAQ,GAAKA,EAAO,GAAI,MAAM,IAAI,WAAW,mCAAmC,EACpF,GAAIG,GAAY,EAAGH,CAAI,EAAI,IAAMG,GAAYH,EAAM,CAAC,EAAI,GACtD,MAAM,IAAI,WAAW,wBAAwB,EAG/C,MAAO,CACL,OAASI,GAA2B,CAClC,GAAI,CAACC,GAAQD,CAAK,EAAG,MAAM,IAAI,UAAU,0CAA0C,EACnF,OAAOE,GAAc,MAAM,KAAKF,CAAK,EAAG,EAAGJ,EAAM,CAACC,CAAU,CAC9D,EACA,OAASM,IACPC,GAAQ,gBAAiBD,CAAM,EACxB,WAAW,KAAKD,GAAcC,EAAQP,EAAM,EAAGC,CAAU,CAAC,GAGvE,CA2FO,IAAMQ,GAAqC,OAAO,OACvDC,GAAMC,GAAO,CAAC,EAAGC,GAAS,kCAAkC,EAAGC,GAAQ,CAAC,EAAGC,GAAK,EAAE,CAAC,CAAC,ECvgB/E,IAAMC,GAAN,KAAgD,CAC5C,KAAO,QAShB,OAAOC,EAAkBC,EAA+B,CAAC,EAAW,CAClE,GAAM,CAAE,QAAAC,EAAU,EAAM,EAAID,EAEtBE,EAAUC,GAAY,OAAOJ,CAAI,EACvC,OAAOE,EAAUC,EAAUA,EAAQ,QAAQ,MAAO,EAAE,CACtD,CASA,OAAOE,EAAyB,CAC9B,GAAI,CACF,IAAMC,EAAaD,EAAI,YAAY,EAC7BE,EAASD,EAAW,OAAO,KAAK,KAAKA,EAAW,OAAS,CAAC,EAAI,EAAG,GAAG,EAC1E,OAAOF,GAAY,OAAOG,CAAM,CAClC,OAASC,EAAO,CAEd,MAAM,IAAI,MAAM,0BAA2BA,EAAgB,OAAO,EAAE,CACtE,CACF,CACF,EAYaJ,GAAuB,OAAO,OAAO,IAAIL,EAAmB,EC+CnE,SAAUU,GAAQC,EAAU,CAKhC,OACEA,aAAa,YACZ,YAAY,OAAOA,CAAC,GACnBA,EAAE,YAAY,OAAS,cACvB,sBAAuBA,GACvBA,EAAE,oBAAsB,CAE9B,CAcM,SAAUC,GAAQC,EAAWC,EAAgB,GAAE,CACnD,GAAI,OAAOD,GAAM,SAAU,CACzB,IAAME,EAASD,GAAS,IAAIA,CAAK,KACjC,MAAM,IAAI,UAAU,GAAGC,CAAM,wBAAwB,OAAOF,CAAC,EAAE,CACjE,CACA,GAAI,CAAC,OAAO,cAAcA,CAAC,GAAKA,EAAI,EAAG,CACrC,IAAME,EAASD,GAAS,IAAIA,CAAK,KACjC,MAAM,IAAI,WAAW,GAAGC,CAAM,8BAA8BF,CAAC,EAAE,CACjE,CACF,CAgBM,SAAUG,GACdC,EACAC,EACAJ,EAAgB,GAAE,CAElB,IAAMK,EAAQT,GAAQO,CAAK,EACrBG,EAAMH,GAAO,OACbI,EAAWH,IAAW,OAC5B,GAAI,CAACC,GAAUE,GAAYD,IAAQF,EAAS,CAC1C,IAAMH,EAASD,GAAS,IAAIA,CAAK,KAC3BQ,EAAQD,EAAW,cAAcH,CAAM,GAAK,GAC5CK,EAAMJ,EAAQ,UAAUC,CAAG,GAAK,QAAQ,OAAOH,CAAK,GACpDO,EAAUT,EAAS,sBAAwBO,EAAQ,SAAWC,EACpE,MAAKJ,EACC,IAAI,WAAWK,CAAO,EADV,IAAI,UAAUA,CAAO,CAEzC,CACA,OAAOP,CACT,CAkCM,SAAUQ,GAAMC,EAAc,CAClC,GAAI,OAAOA,GAAM,YAAc,OAAOA,EAAE,QAAW,WACjD,MAAM,IAAI,UAAU,yCAAyC,EAK/D,GAJAC,GAAQD,EAAE,SAAS,EACnBC,GAAQD,EAAE,QAAQ,EAGdA,EAAE,UAAY,EAAG,MAAM,IAAI,MAAM,0BAA0B,EAC/D,GAAIA,EAAE,SAAW,EAAG,MAAM,IAAI,MAAM,yBAAyB,CAC/D,CAgBM,SAAUE,GAAQC,EAAeC,EAAgB,GAAI,CACzD,GAAID,EAAS,UAAW,MAAM,IAAI,MAAM,kCAAkC,EAC1E,GAAIC,GAAiBD,EAAS,SAAU,MAAM,IAAI,MAAM,uCAAuC,CACjG,CAkBM,SAAUE,GAAQC,EAAUH,EAAa,CAC7CI,GAAOD,EAAK,OAAW,qBAAqB,EAC5C,IAAME,EAAML,EAAS,UACrB,GAAIG,EAAI,OAASE,EACf,MAAM,IAAI,WAAW,oDAAsDA,CAAG,CAElF,CAkDM,SAAUC,KAASC,EAA0B,CACjD,QAASC,EAAI,EAAGA,EAAID,EAAO,OAAQC,IACjCD,EAAOC,CAAC,EAAE,KAAK,CAAC,CAEpB,CAYM,SAAUC,GAAWC,EAAqB,CAC9C,OAAO,IAAI,SAASA,EAAI,OAAQA,EAAI,WAAYA,EAAI,UAAU,CAChE,CAaM,SAAUC,EAAKC,EAAcC,EAAa,CAC9C,OAAQD,GAAS,GAAKC,EAAWD,IAASC,CAC5C,CAaM,SAAUC,GAAKF,EAAcC,EAAa,CAC9C,OAAQD,GAAQC,EAAWD,IAAU,GAAKC,IAAY,CACxD,CA0ZM,SAAUE,GACdC,EACAC,EAAuB,CAAA,EAAE,CAEzB,IAAMC,EAAa,CAACC,EAAuBC,IACzCJ,EAASI,CAAY,EAClB,OAAOD,CAAG,EACV,OAAM,EACLE,EAAML,EAAS,MAAS,EAC9B,OAAAE,EAAM,UAAYG,EAAI,UACtBH,EAAM,SAAWG,EAAI,SACrBH,EAAM,OAASG,EAAI,OACnBH,EAAM,OAAUE,GAAgBJ,EAASI,CAAI,EAC7C,OAAO,OAAOF,EAAOD,CAAI,EAClB,OAAO,OAAOC,CAAK,CAC5B,CAkBM,SAAUI,GAAYC,EAAc,GAAE,CAE1CC,GAAQD,EAAa,aAAa,EAClC,IAAME,EAAK,OAAO,YAAe,SAAY,WAAmB,OAAS,KACzE,GAAI,OAAOA,GAAI,iBAAoB,WACjC,MAAM,IAAI,MAAM,wCAAwC,EAM1D,GAAIF,EAAc,MAChB,MAAM,IAAI,WAAW,wCAAwCA,CAAW,EAAE,EAC5E,OAAOE,EAAG,gBAAgB,IAAI,WAAWF,CAAW,CAAC,CACvD,CAcO,IAAMG,GAAWC,IAA8C,CAGpE,IAAK,WAAW,KAAK,CAAC,EAAM,EAAM,GAAM,IAAM,GAAM,EAAM,IAAM,EAAM,EAAM,EAAMA,CAAM,CAAC,ICzzBrF,IAAOC,GAAP,KAAY,CAChB,MACA,MACA,SACA,UACA,OAAS,GACD,SAAW,GACX,UAAY,GAEpB,YAAYC,EAAmBC,EAAqB,CAIlD,GAHAC,GAAMF,CAAI,EACVG,GAAOF,EAAK,OAAW,KAAK,EAC5B,KAAK,MAAQD,EAAK,OAAM,EACpB,OAAO,KAAK,MAAM,QAAW,WAC/B,MAAM,IAAI,MAAM,qDAAqD,EACvE,KAAK,SAAW,KAAK,MAAM,SAC3B,KAAK,UAAY,KAAK,MAAM,UAC5B,IAAMI,EAAW,KAAK,SAChBC,EAAM,IAAI,WAAWD,CAAQ,EAEnCC,EAAI,IAAIJ,EAAI,OAASG,EAAWJ,EAAK,OAAM,EAAG,OAAOC,CAAG,EAAE,OAAM,EAAKA,CAAG,EACxE,QAASK,EAAI,EAAGA,EAAID,EAAI,OAAQC,IAAKD,EAAIC,CAAC,GAAK,GAC/C,KAAK,MAAM,OAAOD,CAAG,EAGrB,KAAK,MAAQL,EAAK,OAAM,EAExB,QAASM,EAAI,EAAGA,EAAID,EAAI,OAAQC,IAAKD,EAAIC,CAAC,GAAK,IAC/C,KAAK,MAAM,OAAOD,CAAG,EACrBE,EAAMF,CAAG,CACX,CACA,OAAOG,EAAqB,CAC1B,OAAAC,GAAQ,IAAI,EACZ,KAAK,MAAM,OAAOD,CAAG,EACd,IACT,CACA,WAAWE,EAAqB,CAC9BD,GAAQ,IAAI,EACZE,GAAQD,EAAK,IAAI,EACjB,KAAK,SAAW,GAChB,IAAMF,EAAME,EAAI,SAAS,EAAG,KAAK,SAAS,EAG1C,KAAK,MAAM,WAAWF,CAAG,EACzB,KAAK,MAAM,OAAOA,CAAG,EACrB,KAAK,MAAM,WAAWA,CAAG,EACzB,KAAK,QAAO,CACd,CACA,QAAM,CACJ,IAAME,EAAM,IAAI,WAAW,KAAK,MAAM,SAAS,EAC/C,YAAK,WAAWA,CAAG,EACZA,CACT,CACA,WAAWE,EAAa,CAGtBA,IAAO,OAAO,OAAO,OAAO,eAAe,IAAI,EAAG,CAAA,CAAE,EACpD,GAAM,CAAE,MAAAC,EAAO,MAAAC,EAAO,SAAAC,EAAU,UAAAC,EAAW,SAAAZ,EAAU,UAAAa,CAAS,EAAK,KACnE,OAAAL,EAAKA,EACLA,EAAG,SAAWG,EACdH,EAAG,UAAYI,EACfJ,EAAG,SAAWR,EACdQ,EAAG,UAAYK,EACfL,EAAG,MAAQC,EAAM,WAAWD,EAAG,KAAK,EACpCA,EAAG,MAAQE,EAAM,WAAWF,EAAG,KAAK,EAC7BA,CACT,CACA,OAAK,CACH,OAAO,KAAK,WAAU,CACxB,CACA,SAAO,CACL,KAAK,UAAY,GACjB,KAAK,MAAM,QAAO,EAClB,KAAK,MAAM,QAAO,CACpB,GAqBWM,IAAsC,IAAK,CACtD,IAAMC,GAAS,CACbnB,EACAC,EACAmB,IACqB,IAAIrB,GAAWC,EAAMC,CAAG,EAAE,OAAOmB,CAAO,EAAE,OAAM,GACvE,OAAAD,EAAM,OAAS,CAACnB,EAAmBC,IACjC,IAAIF,GAAWC,EAAMC,CAAG,EACnBkB,CACT,GAAE,EC/FI,SAAUE,GAAIC,EAAWC,EAAWC,EAAS,CACjD,OAAQF,EAAIC,EAAM,CAACD,EAAIE,CACzB,CAeM,SAAUC,GAAIH,EAAWC,EAAWC,EAAS,CACjD,OAAQF,EAAIC,EAAMD,EAAIE,EAAMD,EAAIC,CAClC,CAoBM,IAAgBE,EAAhB,KAAsB,CASjB,SACA,UACA,OAAS,GACT,UACA,KAGC,OACA,KACA,SAAW,GACX,OAAS,EACT,IAAM,EACN,UAAY,GAEtB,YAAYC,EAAkBC,EAAmBC,EAAmBC,EAAa,CAC/E,KAAK,SAAWH,EAChB,KAAK,UAAYC,EACjB,KAAK,UAAYC,EACjB,KAAK,KAAOC,EACZ,KAAK,OAAS,IAAI,WAAWH,CAAQ,EACrC,KAAK,KAAOI,GAAW,KAAK,MAAM,CACpC,CACA,OAAOC,EAAsB,CAC3BC,GAAQ,IAAI,EACZC,GAAOF,CAAI,EACX,GAAM,CAAE,KAAAG,EAAM,OAAAC,EAAQ,SAAAT,CAAQ,EAAK,KAC7BU,EAAML,EAAK,OACjB,QAASM,EAAM,EAAGA,EAAMD,GAAO,CAC7B,IAAME,EAAO,KAAK,IAAIZ,EAAW,KAAK,IAAKU,EAAMC,CAAG,EAGpD,GAAIC,IAASZ,EAAU,CACrB,IAAMa,EAAWT,GAAWC,CAAI,EAChC,KAAOL,GAAYU,EAAMC,EAAKA,GAAOX,EAAU,KAAK,QAAQa,EAAUF,CAAG,EACzE,QACF,CACAF,EAAO,IAAIJ,EAAK,SAASM,EAAKA,EAAMC,CAAI,EAAG,KAAK,GAAG,EACnD,KAAK,KAAOA,EACZD,GAAOC,EACH,KAAK,MAAQZ,IACf,KAAK,QAAQQ,EAAM,CAAC,EACpB,KAAK,IAAM,EAEf,CACA,YAAK,QAAUH,EAAK,OACpB,KAAK,WAAU,EACR,IACT,CACA,WAAWS,EAAqB,CAC9BR,GAAQ,IAAI,EACZS,GAAQD,EAAK,IAAI,EACjB,KAAK,SAAW,GAIhB,GAAM,CAAE,OAAAL,EAAQ,KAAAD,EAAM,SAAAR,EAAU,KAAAG,CAAI,EAAK,KACrC,CAAE,IAAAQ,CAAG,EAAK,KAEdF,EAAOE,GAAK,EAAI,IAChBK,EAAM,KAAK,OAAO,SAASL,CAAG,CAAC,EAG3B,KAAK,UAAYX,EAAWW,IAC9B,KAAK,QAAQH,EAAM,CAAC,EACpBG,EAAM,GAGR,QAASM,EAAIN,EAAKM,EAAIjB,EAAUiB,IAAKR,EAAOQ,CAAC,EAAI,EAIjDT,EAAK,aAAaR,EAAW,EAAG,OAAO,KAAK,OAAS,CAAC,EAAGG,CAAI,EAC7D,KAAK,QAAQK,EAAM,CAAC,EACpB,IAAMU,EAAQd,GAAWU,CAAG,EACtBJ,EAAM,KAAK,UAEjB,GAAIA,EAAM,EAAG,MAAM,IAAI,MAAM,2CAA2C,EACxE,IAAMS,EAAST,EAAM,EACfU,EAAQ,KAAK,IAAG,EACtB,GAAID,EAASC,EAAM,OAAQ,MAAM,IAAI,MAAM,oCAAoC,EAC/E,QAASH,EAAI,EAAGA,EAAIE,EAAQF,IAAKC,EAAM,UAAU,EAAID,EAAGG,EAAMH,CAAC,EAAGd,CAAI,CACxE,CACA,QAAM,CACJ,GAAM,CAAE,OAAAM,EAAQ,UAAAR,CAAS,EAAK,KAC9B,KAAK,WAAWQ,CAAM,EAGtB,IAAMY,EAAMZ,EAAO,MAAM,EAAGR,CAAS,EACrC,YAAK,QAAO,EACLoB,CACT,CACA,WAAWC,EAAM,CACfA,IAAO,IAAK,KAAK,YACjBA,EAAG,IAAI,GAAG,KAAK,IAAG,CAAE,EACpB,GAAM,CAAE,SAAAtB,EAAU,OAAAS,EAAQ,OAAAc,EAAQ,SAAAC,EAAU,UAAAC,EAAW,IAAAd,CAAG,EAAK,KAC/D,OAAAW,EAAG,UAAYG,EACfH,EAAG,SAAWE,EACdF,EAAG,OAASC,EACZD,EAAG,IAAMX,EAGLY,EAASvB,GAAUsB,EAAG,OAAO,IAAIb,CAAM,EACpCa,CACT,CACA,OAAK,CACH,OAAO,KAAK,WAAU,CACxB,GAWWI,EAA+C,YAAY,KAAK,CAC3E,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,UAAY,WACrF,EAqBM,IAAMC,EAA+C,YAAY,KAAK,CAC3E,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WACpF,WAAY,WAAY,WAAY,UAAY,UAAY,WAAY,WAAY,UACrF,EC7MD,IAAMC,GAA0B,YAAY,KAAK,CAC/C,WAAY,WAAY,WAAY,UAAY,WACjD,EAGKC,EAAyB,IAAI,YAAY,EAAE,EAGpCC,GAAP,cAAqBC,CAAa,CAC9B,EAAIH,GAAQ,CAAC,EAAI,EACjB,EAAIA,GAAQ,CAAC,EAAI,EACjB,EAAIA,GAAQ,CAAC,EAAI,EACjB,EAAIA,GAAQ,CAAC,EAAI,EACjB,EAAIA,GAAQ,CAAC,EAAI,EAEzB,aAAA,CACE,MAAM,GAAI,GAAI,EAAG,EAAK,CACxB,CACU,KAAG,CACX,GAAM,CAAE,EAAAI,EAAG,EAAAC,EAAG,EAAAC,EAAG,EAAAC,EAAG,EAAAC,CAAC,EAAK,KAC1B,MAAO,CAACJ,EAAGC,EAAGC,EAAGC,EAAGC,CAAC,CACvB,CACU,IAAIJ,EAAWC,EAAWC,EAAWC,EAAWC,EAAS,CACjE,KAAK,EAAIJ,EAAI,EACb,KAAK,EAAIC,EAAI,EACb,KAAK,EAAIC,EAAI,EACb,KAAK,EAAIC,EAAI,EACb,KAAK,EAAIC,EAAI,CACf,CACU,QAAQC,EAAgBC,EAAc,CAC9C,QAASC,EAAI,EAAGA,EAAI,GAAIA,IAAKD,GAAU,EAAGT,EAAOU,CAAC,EAAIF,EAAK,UAAUC,EAAQ,EAAK,EAClF,QAASC,EAAI,GAAIA,EAAI,GAAIA,IACvBV,EAAOU,CAAC,EAAIC,GAAKX,EAAOU,EAAI,CAAC,EAAIV,EAAOU,EAAI,CAAC,EAAIV,EAAOU,EAAI,EAAE,EAAIV,EAAOU,EAAI,EAAE,EAAG,CAAC,EAErF,GAAI,CAAE,EAAAP,EAAG,EAAAC,EAAG,EAAAC,EAAG,EAAAC,EAAG,EAAAC,CAAC,EAAK,KACxB,QAASG,EAAI,EAAGA,EAAI,GAAIA,IAAK,CAC3B,IAAIE,EAAGC,EACHH,EAAI,IACNE,EAAIE,GAAIV,EAAGC,EAAGC,CAAC,EACfO,EAAI,YACKH,EAAI,IACbE,EAAIR,EAAIC,EAAIC,EACZO,EAAI,YACKH,EAAI,IACbE,EAAIG,GAAIX,EAAGC,EAAGC,CAAC,EACfO,EAAI,aAEJD,EAAIR,EAAIC,EAAIC,EACZO,EAAI,YAEN,IAAMG,EAAKL,GAAKR,EAAG,CAAC,EAAIS,EAAIL,EAAIM,EAAIb,EAAOU,CAAC,EAAK,EACjDH,EAAID,EACJA,EAAID,EACJA,EAAIM,GAAKP,EAAG,EAAE,EACdA,EAAID,EACJA,EAAIa,CACN,CAEAb,EAAKA,EAAI,KAAK,EAAK,EACnBC,EAAKA,EAAI,KAAK,EAAK,EACnBC,EAAKA,EAAI,KAAK,EAAK,EACnBC,EAAKA,EAAI,KAAK,EAAK,EACnBC,EAAKA,EAAI,KAAK,EAAK,EACnB,KAAK,IAAIJ,EAAGC,EAAGC,EAAGC,EAAGC,CAAC,CACxB,CACU,YAAU,CAClBU,EAAMjB,CAAM,CACd,CACA,SAAO,CAGL,KAAK,UAAY,GACjB,KAAK,IAAI,EAAG,EAAG,EAAG,EAAG,CAAC,EACtBiB,EAAM,KAAK,MAAM,CACnB,GAaWC,GAAoCC,GAAa,IAAM,IAAIlB,EAAO,EC9F/E,IAAMmB,GAA6B,OAAO,UAAW,EAC/CC,GAAuB,OAAO,EAAE,EAItC,SAASC,GACPC,EACAC,EAAK,GAAK,CAKV,OAAIA,EAAW,CAAE,EAAG,OAAOD,EAAIH,EAAU,EAAG,EAAG,OAAQG,GAAKF,GAAQD,EAAU,CAAC,EACxE,CAAE,EAAG,OAAQG,GAAKF,GAAQD,EAAU,EAAI,EAAG,EAAG,OAAOG,EAAIH,EAAU,EAAI,CAAC,CACjF,CAIA,SAASK,GAAMC,EAAeF,EAAK,GAAK,CACtC,IAAMG,EAAMD,EAAI,OACZE,EAAK,IAAI,YAAYD,CAAG,EACxBE,EAAK,IAAI,YAAYF,CAAG,EAC5B,QAASG,EAAI,EAAGA,EAAIH,EAAKG,IAAK,CAC5B,GAAM,CAAE,EAAAC,EAAG,EAAAC,CAAC,EAAKV,GAAQI,EAAII,CAAC,EAAGN,CAAE,EACnC,CAACI,EAAGE,CAAC,EAAGD,EAAGC,CAAC,CAAC,EAAI,CAACC,EAAGC,CAAC,CACxB,CACA,MAAO,CAACJ,EAAIC,CAAE,CAChB,CAMA,IAAMI,GAAQ,CAACC,EAAWC,EAAYC,IAAsBF,IAAME,EAE5DC,GAAQ,CAACH,EAAWI,EAAWF,IAAuBF,GAAM,GAAKE,EAAOE,IAAMF,EAE9EG,EAAS,CAACL,EAAWI,EAAWF,IAAuBF,IAAME,EAAME,GAAM,GAAKF,EAE9EI,EAAS,CAACN,EAAWI,EAAWF,IAAuBF,GAAM,GAAKE,EAAOE,IAAMF,EAE/EK,GAAS,CAACP,EAAWI,EAAWF,IAAuBF,GAAM,GAAKE,EAAOE,IAAOF,EAAI,GAEpFM,GAAS,CAACR,EAAWI,EAAWF,IAAuBF,IAAOE,EAAI,GAAQE,GAAM,GAAKF,EAiB3F,SAASO,EACPC,EACAC,EACAC,EACAC,EAAU,CAKV,IAAMC,GAAKH,IAAO,IAAME,IAAO,GAC/B,MAAO,CAAE,EAAIH,EAAKE,GAAOE,EAAI,GAAK,GAAM,GAAM,EAAG,EAAGA,EAAI,CAAC,CAC3D,CAGA,IAAMC,GAAQ,CAACJ,EAAYE,EAAYG,KAAwBL,IAAO,IAAME,IAAO,IAAMG,IAAO,GAE1FC,GAAQ,CAACC,EAAaR,EAAYE,EAAYO,IACjDT,EAAKE,EAAKO,GAAOD,EAAM,GAAK,GAAM,GAAM,EAErCE,GAAQ,CAACT,EAAYE,EAAYG,EAAYK,KAChDV,IAAO,IAAME,IAAO,IAAMG,IAAO,IAAMK,IAAO,GAE3CC,GAAQ,CAACJ,EAAaR,EAAYE,EAAYO,EAAYI,IAC7Db,EAAKE,EAAKO,EAAKI,GAAOL,EAAM,GAAK,GAAM,GAAM,EAE1CM,GAAQ,CAACb,EAAYE,EAAYG,EAAYK,EAAYI,KAC5Dd,IAAO,IAAME,IAAO,IAAMG,IAAO,IAAMK,IAAO,IAAMI,IAAO,GAExDC,GAAQ,CAACR,EAAaR,EAAYE,EAAYO,EAAYI,EAAYI,IACzEjB,EAAKE,EAAKO,EAAKI,EAAKI,GAAOT,EAAM,GAAK,GAAM,GAAM,EClFrD,IAAMU,GAA2B,YAAY,KAAK,CAChD,WAAY,WAAY,WAAY,WAAY,UAAY,WAAY,WAAY,WACpF,WAAY,UAAY,UAAY,WAAY,WAAY,WAAY,WAAY,WACpF,WAAY,WAAY,UAAY,UAAY,UAAY,WAAY,WAAY,WACpF,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,UAAY,UACpF,UAAY,UAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WACpF,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,UACpF,UAAY,UAAY,UAAY,UAAY,UAAY,WAAY,WAAY,WACpF,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WACrF,EAGKC,EAA2B,IAAI,YAAY,EAAE,EAGpCC,GAAf,cAAuDC,CAAS,CAY9D,YAAYC,EAAiB,CAC3B,MAAM,GAAIA,EAAW,EAAG,EAAK,CAC/B,CACU,KAAG,CACX,GAAM,CAAE,EAAAC,EAAG,EAAAC,EAAG,EAAAC,EAAG,EAAAC,EAAG,EAAAC,EAAG,EAAAC,EAAG,EAAAC,EAAG,EAAAC,CAAC,EAAK,KACnC,MAAO,CAACP,EAAGC,EAAGC,EAAGC,EAAGC,EAAGC,EAAGC,EAAGC,CAAC,CAChC,CAEU,IACRP,EAAWC,EAAWC,EAAWC,EAAWC,EAAWC,EAAWC,EAAWC,EAAS,CAEtF,KAAK,EAAIP,EAAI,EACb,KAAK,EAAIC,EAAI,EACb,KAAK,EAAIC,EAAI,EACb,KAAK,EAAIC,EAAI,EACb,KAAK,EAAIC,EAAI,EACb,KAAK,EAAIC,EAAI,EACb,KAAK,EAAIC,EAAI,EACb,KAAK,EAAIC,EAAI,CACf,CACU,QAAQC,EAAgBC,EAAc,CAE9C,QAASC,EAAI,EAAGA,EAAI,GAAIA,IAAKD,GAAU,EAAGb,EAASc,CAAC,EAAIF,EAAK,UAAUC,EAAQ,EAAK,EACpF,QAASC,EAAI,GAAIA,EAAI,GAAIA,IAAK,CAC5B,IAAMC,EAAMf,EAASc,EAAI,EAAE,EACrBE,EAAKhB,EAASc,EAAI,CAAC,EACnBG,EAAKC,EAAKH,EAAK,CAAC,EAAIG,EAAKH,EAAK,EAAE,EAAKA,IAAQ,EAC7CI,EAAKD,EAAKF,EAAI,EAAE,EAAIE,EAAKF,EAAI,EAAE,EAAKA,IAAO,GACjDhB,EAASc,CAAC,EAAKK,EAAKnB,EAASc,EAAI,CAAC,EAAIG,EAAKjB,EAASc,EAAI,EAAE,EAAK,CACjE,CAEA,GAAI,CAAE,EAAAV,EAAG,EAAAC,EAAG,EAAAC,EAAG,EAAAC,EAAG,EAAAC,EAAG,EAAAC,EAAG,EAAAC,EAAG,EAAAC,CAAC,EAAK,KACjC,QAASG,EAAI,EAAGA,EAAI,GAAIA,IAAK,CAC3B,IAAMM,EAASF,EAAKV,EAAG,CAAC,EAAIU,EAAKV,EAAG,EAAE,EAAIU,EAAKV,EAAG,EAAE,EAC9Ca,EAAMV,EAAIS,EAASE,GAAId,EAAGC,EAAGC,CAAC,EAAIX,GAASe,CAAC,EAAId,EAASc,CAAC,EAAK,EAE/DS,GADSL,EAAKd,EAAG,CAAC,EAAIc,EAAKd,EAAG,EAAE,EAAIc,EAAKd,EAAG,EAAE,GAC/BoB,GAAIpB,EAAGC,EAAGC,CAAC,EAAK,EACrCK,EAAID,EACJA,EAAID,EACJA,EAAID,EACJA,EAAKD,EAAIc,EAAM,EACfd,EAAID,EACJA,EAAID,EACJA,EAAID,EACJA,EAAKiB,EAAKE,EAAM,CAClB,CAEAnB,EAAKA,EAAI,KAAK,EAAK,EACnBC,EAAKA,EAAI,KAAK,EAAK,EACnBC,EAAKA,EAAI,KAAK,EAAK,EACnBC,EAAKA,EAAI,KAAK,EAAK,EACnBC,EAAKA,EAAI,KAAK,EAAK,EACnBC,EAAKA,EAAI,KAAK,EAAK,EACnBC,EAAKA,EAAI,KAAK,EAAK,EACnBC,EAAKA,EAAI,KAAK,EAAK,EACnB,KAAK,IAAIP,EAAGC,EAAGC,EAAGC,EAAGC,EAAGC,EAAGC,EAAGC,CAAC,CACjC,CACU,YAAU,CAClBc,EAAMzB,CAAQ,CAChB,CACA,SAAO,CAGL,KAAK,UAAY,GACjB,KAAK,IAAI,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,CAAC,EAC/ByB,EAAM,KAAK,MAAM,CACnB,GAIWC,GAAP,cAAuBzB,EAAiB,CAGlC,EAAY0B,EAAU,CAAC,EAAI,EAC3B,EAAYA,EAAU,CAAC,EAAI,EAC3B,EAAYA,EAAU,CAAC,EAAI,EAC3B,EAAYA,EAAU,CAAC,EAAI,EAC3B,EAAYA,EAAU,CAAC,EAAI,EAC3B,EAAYA,EAAU,CAAC,EAAI,EAC3B,EAAYA,EAAU,CAAC,EAAI,EAC3B,EAAYA,EAAU,CAAC,EAAI,EACrC,aAAA,CACE,MAAM,EAAE,CACV,GAuBF,IAAMC,GAAkCC,GAAM,CAC5C,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,qBAClE,qBAAsB,qBAAsB,qBAAsB,sBAClE,IAAIC,GAAK,OAAOA,CAAC,CAAC,CAAC,EACfC,GAAmCH,GAAK,CAAC,EACzCI,GAAmCJ,GAAK,CAAC,EAGzCK,EAA6B,IAAI,YAAY,EAAE,EAE/CC,EAA6B,IAAI,YAAY,EAAE,EAGtCC,GAAf,cAAuDC,CAAS,CAqB9D,YAAYC,EAAiB,CAC3B,MAAM,IAAKA,EAAW,GAAI,EAAK,CACjC,CAEU,KAAG,CAIX,GAAM,CAAE,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,CAAE,EAAK,KAC3E,MAAO,CAACf,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,CAAE,CACxE,CAEU,IACRf,EAAYC,EAAYC,EAAYC,EAAYC,EAAYC,EAAYC,EAAYC,EACpFC,EAAYC,EAAYC,EAAYC,EAAYC,EAAYC,EAAYC,EAAYC,EAAU,CAE9F,KAAK,GAAKf,EAAK,EACf,KAAK,GAAKC,EAAK,EACf,KAAK,GAAKC,EAAK,EACf,KAAK,GAAKC,EAAK,EACf,KAAK,GAAKC,EAAK,EACf,KAAK,GAAKC,EAAK,EACf,KAAK,GAAKC,EAAK,EACf,KAAK,GAAKC,EAAK,EACf,KAAK,GAAKC,EAAK,EACf,KAAK,GAAKC,EAAK,EACf,KAAK,GAAKC,EAAK,EACf,KAAK,GAAKC,EAAK,EACf,KAAK,GAAKC,EAAK,EACf,KAAK,GAAKC,EAAK,EACf,KAAK,GAAKC,EAAK,EACf,KAAK,GAAKC,EAAK,CACjB,CACU,QAAQC,EAAgBC,EAAc,CAE9C,QAASC,EAAI,EAAGA,EAAI,GAAIA,IAAKD,GAAU,EACrCtB,EAAWuB,CAAC,EAAIF,EAAK,UAAUC,CAAM,EACrCrB,EAAWsB,CAAC,EAAIF,EAAK,UAAWC,GAAU,CAAE,EAE9C,QAASC,EAAI,GAAIA,EAAI,GAAIA,IAAK,CAE5B,IAAMC,EAAOxB,EAAWuB,EAAI,EAAE,EAAI,EAC5BE,EAAOxB,EAAWsB,EAAI,EAAE,EAAI,EAC5BG,GAAUC,EAAOH,EAAMC,EAAM,CAAC,EAAQE,EAAOH,EAAMC,EAAM,CAAC,EAAQG,GAAMJ,EAAMC,EAAM,CAAC,EACrFI,GAAUC,EAAON,EAAMC,EAAM,CAAC,EAAQK,EAAON,EAAMC,EAAM,CAAC,EAAQM,GAAMP,EAAMC,EAAM,CAAC,EAErFO,EAAMhC,EAAWuB,EAAI,CAAC,EAAI,EAC1BU,EAAMhC,EAAWsB,EAAI,CAAC,EAAI,EAC1BW,GAAUP,EAAOK,EAAKC,EAAK,EAAE,EAAQE,GAAOH,EAAKC,EAAK,EAAE,EAAQL,GAAMI,EAAKC,EAAK,CAAC,EACjFG,GAAUN,EAAOE,EAAKC,EAAK,EAAE,EAAQI,GAAOL,EAAKC,EAAK,EAAE,EAAQF,GAAMC,EAAKC,EAAK,CAAC,EAEjFK,GAAWC,GAAMV,GAAKO,GAAKnC,EAAWsB,EAAI,CAAC,EAAGtB,EAAWsB,EAAI,EAAE,CAAC,EAChEiB,GAAWC,GAAMH,GAAMZ,GAAKQ,GAAKlC,EAAWuB,EAAI,CAAC,EAAGvB,EAAWuB,EAAI,EAAE,CAAC,EAC5EvB,EAAWuB,CAAC,EAAIiB,GAAO,EACvBvC,EAAWsB,CAAC,EAAIe,GAAO,CACzB,CACA,GAAI,CAAE,GAAAjC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,CAAE,EAAK,KAEzE,QAASG,EAAI,EAAGA,EAAI,GAAIA,IAAK,CAE3B,IAAMmB,EAAcf,EAAOd,EAAIC,EAAI,EAAE,EAAQa,EAAOd,EAAIC,EAAI,EAAE,EAAQqB,GAAOtB,EAAIC,EAAI,EAAE,EACjF6B,EAAcb,EAAOjB,EAAIC,EAAI,EAAE,EAAQgB,EAAOjB,EAAIC,EAAI,EAAE,EAAQuB,GAAOxB,EAAIC,EAAI,EAAE,EAEjF8B,GAAQ/B,EAAKE,EAAO,CAACF,EAAKI,EAC1B4B,GAAQ/B,EAAKE,EAAO,CAACF,EAAKI,EAG1B4B,EAAWC,GAAM3B,EAAIuB,EAASE,GAAM9C,GAAUwB,CAAC,EAAGtB,EAAWsB,CAAC,CAAC,EAC/DyB,EAAUC,GAAMH,EAAM3B,EAAIuB,EAASE,GAAM9C,GAAUyB,CAAC,EAAGvB,EAAWuB,CAAC,CAAC,EACpE2B,GAAMJ,EAAO,EAEbK,GAAcxB,EAAOtB,EAAIC,EAAI,EAAE,EAAQ6B,GAAO9B,EAAIC,EAAI,EAAE,EAAQ6B,GAAO9B,EAAIC,EAAI,EAAE,EACjF8C,GAActB,EAAOzB,EAAIC,EAAI,EAAE,EAAQ+B,GAAOhC,EAAIC,EAAI,EAAE,EAAQ+B,GAAOhC,EAAIC,EAAI,EAAE,EACjF+C,GAAQhD,EAAKE,EAAOF,EAAKI,EAAOF,EAAKE,EACrC6C,GAAQhD,EAAKE,EAAOF,EAAKI,EAAOF,EAAKE,EAC3CS,EAAKF,EAAK,EACVG,EAAKF,EAAK,EACVD,EAAKF,EAAK,EACVG,EAAKF,EAAK,EACVD,EAAKF,EAAK,EACVG,EAAKF,EAAK,EACT,CAAE,EAAGD,EAAI,EAAGC,CAAE,EAASyC,EAAI5C,EAAK,EAAGC,EAAK,EAAGoC,EAAM,EAAGE,GAAM,CAAC,EAC5DvC,EAAKF,EAAK,EACVG,EAAKF,EAAK,EACVD,EAAKF,EAAK,EACVG,EAAKF,EAAK,EACVD,EAAKF,EAAK,EACVG,EAAKF,EAAK,EACV,IAAMkD,GAAUC,GAAMP,GAAKE,GAASE,EAAI,EACxCjD,EAASqD,GAAMF,GAAKR,EAAKG,GAASE,EAAI,EACtC/C,EAAKkD,GAAM,CACb,EAEC,CAAE,EAAGnD,EAAI,EAAGC,CAAE,EAASiD,EAAI,KAAK,GAAK,EAAG,KAAK,GAAK,EAAGlD,EAAK,EAAGC,EAAK,CAAC,GACnE,CAAE,EAAGC,EAAI,EAAGC,CAAE,EAAS+C,EAAI,KAAK,GAAK,EAAG,KAAK,GAAK,EAAGhD,EAAK,EAAGC,EAAK,CAAC,EACnE,CAAE,EAAGC,EAAI,EAAGC,CAAE,EAAS6C,EAAI,KAAK,GAAK,EAAG,KAAK,GAAK,EAAG9C,EAAK,EAAGC,EAAK,CAAC,EACnE,CAAE,EAAGC,EAAI,EAAGC,CAAE,EAAS2C,EAAI,KAAK,GAAK,EAAG,KAAK,GAAK,EAAG5C,EAAK,EAAGC,EAAK,CAAC,EACnE,CAAE,EAAGC,EAAI,EAAGC,CAAE,EAASyC,EAAI,KAAK,GAAK,EAAG,KAAK,GAAK,EAAG1C,EAAK,EAAGC,EAAK,CAAC,EACnE,CAAEC,EAAO,EAAGC,CAAE,EAASuC,EAAI,KAAK,GAAK,EAAG,KAAK,GAAK,EAAGxC,EAAK,EAAGC,EAAK,CAAC,EACnE,CAAE,EAAGC,EAAI,EAAGC,CAAE,EAASqC,EAAI,KAAK,GAAK,EAAG,KAAK,GAAK,EAAGtC,EAAK,EAAGC,EAAK,CAAC,EACnE,CAAE,EAAGC,EAAI,EAAGC,CAAE,EAASmC,EAAI,KAAK,GAAK,EAAG,KAAK,GAAK,EAAGpC,EAAK,EAAGC,EAAK,CAAC,EACpE,KAAK,IAAIf,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,EAAIC,CAAE,CACzE,CACU,YAAU,CAClBuC,EAAM3D,EAAYC,CAAU,CAC9B,CACA,SAAO,CAGL,KAAK,UAAY,GACjB0D,EAAM,KAAK,MAAM,EACjB,KAAK,IAAI,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,CAAC,CACzD,GAIWC,GAAP,cAAuB1D,EAAiB,CAClC,GAAa2D,EAAU,CAAC,EAAI,EAC5B,GAAaA,EAAU,CAAC,EAAI,EAC5B,GAAaA,EAAU,CAAC,EAAI,EAC5B,GAAaA,EAAU,CAAC,EAAI,EAC5B,GAAaA,EAAU,CAAC,EAAI,EAC5B,GAAaA,EAAU,CAAC,EAAI,EAC5B,GAAaA,EAAU,CAAC,EAAI,EAC5B,GAAaA,EAAU,CAAC,EAAI,EAC5B,GAAaA,EAAU,CAAC,EAAI,EAC5B,GAAaA,EAAU,CAAC,EAAI,EAC5B,GAAaA,EAAU,EAAE,EAAI,EAC7B,GAAaA,EAAU,EAAE,EAAI,EAC7B,GAAaA,EAAU,EAAE,EAAI,EAC7B,GAAaA,EAAU,EAAE,EAAI,EAC7B,GAAaA,EAAU,EAAE,EAAI,EAC7B,GAAaA,EAAU,EAAE,EAAI,EAEvC,aAAA,CACE,MAAM,EAAE,CACV,GAmHK,IAAMC,GAA+CC,GAC1D,IAAM,IAAIC,GACMC,GAAQ,CAAI,CAAC,EA2BxB,IAAMC,GAA+CC,GAC1D,IAAM,IAAIC,GACMC,GAAQ,CAAI,CAAC,ECzcxB,IAAMC,GAAN,KAAgD,CAI5C,KAAO,QAYhB,KAAKC,EAAyCC,EAAiBC,EAA8B,CAE3F,OAAOC,GADQH,IAAc,OAASI,GAAOJ,IAAc,SAAWK,GAASC,GAC3DL,EAAKC,CAAI,CAC/B,CAaA,YAAYK,EAA4B,CACtC,OAAOC,GAAYD,CAAM,CAC3B,CAYA,kBAAkBE,EAAwBC,EAAiC,CACzE,OAAOC,GAAsBF,EAAGC,CAAC,CACnC,CACF,EAYaE,GAAuB,OAAO,OAAO,IAAIb,EAAmB,ECnElE,SAASc,GACdC,EACgC,CAChC,MAAO,CACL,OAAQA,EAAQ,OAChB,SAAUA,EAAQ,UAAY,OAC9B,OAAQA,EAAQ,QAAUC,GAC1B,OAAQD,EAAQ,QAAUE,GAC1B,UAAWF,EAAQ,WAAa,OAChC,OAAQA,EAAQ,QAAU,EAC1B,OAAQA,EAAQ,QAAU,GAC1B,MAAOA,EAAQ,OAAS,KAAK,MAAM,KAAK,IAAI,EAAI,GAAI,EACpD,GAAIA,EAAQ,IAAM,EAClB,QAASA,EAAQ,QACjB,WAAYA,EAAQ,YAAcG,EAAiB,EACnD,MAAOH,EAAQ,KACjB,CACF,CAEO,SAASI,GAAuBJ,EAAyD,CAC9F,MAAO,CACL,GAAGD,GAAyBC,CAAO,EACnC,MAAOA,EAAQ,MACf,eAAgBA,EAAQ,gBAAkB,EAC1C,iBAAkBA,EAAQ,kBAAoB,EAC9C,cAAeA,EAAQ,aACzB,CACF,CCXA,SAASK,GACPC,EACAC,EACAC,EACG,CACH,GAAIF,IAAa,OACf,OAAOE,EAAS,KAAK,EAEvB,GAAIF,IAAa,OAAQ,CACvB,GAAIC,IAAY,OACd,MAAM,IAAIE,EACR,kFACF,EAEF,OAAOD,EAAS,KAAKD,CAAO,CAC9B,CACA,MAAM,IAAIE,EACR,yBAAyBH,CAAQ,0CACnC,CACF,CA4BO,SAASI,GAAeC,EAgBpB,CACT,GAAM,CAAE,OAAAC,EAASA,GAAe,OAAAC,EAASA,GAAe,OAAAC,EAAS,EAAG,EAAIH,GAAW,CAAC,EAEpF,OAAOD,EAAmB,CAAE,OAAAE,EAAQ,OAAAC,EAAQ,OAAAC,CAAO,CAAC,CACtD,CAqCO,SAASC,GAAYJ,EAkBjB,CACT,GAAM,CACJ,SAAAL,EAAW,OACX,OAAAU,EACA,MAAAC,EACA,OAAAC,EACA,UAAAC,EAAY,OACZ,OAAAC,EAAS,EACT,OAAAC,EAAS,GACT,QAAAd,CACF,EAAII,EAEJ,OAAON,GAAkBC,EAAUC,EAAS,CAC1C,KAAM,IAAMe,GAAgB,CAAE,OAAAN,EAAQ,MAAAC,EAAO,OAAAC,EAAQ,UAAAC,EAAW,OAAAC,EAAQ,OAAAC,CAAO,CAAC,EAChF,KAAOd,GAAYgB,GAAe,CAAE,OAAAP,EAAQ,MAAAC,EAAO,OAAAC,EAAQ,UAAAC,EAAW,OAAAC,EAAQ,QAAAb,CAAQ,CAAC,CACzF,CAAC,CACH,CA2CA,eAAsBiB,GAASb,EAA8C,CAC3E,IAAMc,EAAOC,GAAyBf,CAAO,EACvC,CAAE,OAAAO,EAAQ,OAAAN,EAAQ,OAAAC,EAAQ,UAAAM,EAAW,OAAAC,EAAQ,MAAAO,CAAM,EAAIF,EACvDG,EAAgB,CAAE,OAAAV,EAAQ,OAAAN,EAAQ,OAAAC,EAAQ,UAAAM,EAAW,OAAAC,EAAQ,MAAAO,CAAM,EAEzE,OAAOtB,GAAkBoB,EAAK,SAAUA,EAAK,QAAS,CACpD,KAAM,IACJD,GAAa,CACX,GAAGI,EACH,OAAQH,EAAK,OACb,MAAOA,EAAK,MACZ,GAAIA,EAAK,GACT,WAAYA,EAAK,UACnB,CAAC,EACH,KAAOlB,GACLiB,EAAa,CACX,GAAGI,EACH,QAAArB,EACA,WAAYkB,EAAK,UACnB,CAAC,CACL,CAAC,CACH,CAqBO,SAASI,GAAalB,EAAqC,CAChE,IAAMc,EAAOC,GAAyBf,CAAO,EACvC,CAAE,OAAAO,EAAQ,OAAAN,EAAQ,OAAAC,EAAQ,UAAAM,EAAW,OAAAC,CAAO,EAAIK,EAChDG,EAAgB,CAAE,OAAAV,EAAQ,OAAAN,EAAQ,OAAAC,EAAQ,UAAAM,EAAW,OAAAC,CAAO,EAElE,OAAOf,GAAkBoB,EAAK,SAAUA,EAAK,QAAS,CACpD,KAAM,IACJI,GAAiB,CACf,GAAGD,EACH,OAAQH,EAAK,OACb,MAAOA,EAAK,MACZ,GAAIA,EAAK,GACT,WAAYA,EAAK,UACnB,CAAC,EACH,KAAOlB,GACLsB,GAAiB,CACf,GAAGD,EACH,QAAArB,EACA,WAAYkB,EAAK,UACnB,CAAC,CACL,CAAC,CACH,CAiDA,eAAsBK,GAAOnB,EAAkD,CAC7E,IAAMc,EAAOM,GAAuBpB,CAAO,EACrC,CAAE,OAAAO,EAAQ,MAAAc,EAAO,OAAApB,EAAQ,OAAAC,EAAQ,UAAAM,EAAW,OAAAC,EAAQ,MAAAO,CAAM,EAAIF,EAC9DG,EAAgB,CAAE,OAAAV,EAAQ,MAAAc,EAAO,OAAApB,EAAQ,OAAAC,EAAQ,UAAAM,EAAW,OAAAC,EAAQ,MAAAO,CAAM,EAEhF,OAAOtB,GAAkBoB,EAAK,SAAUA,EAAK,QAAS,CACpD,KAAM,IACJK,GAAW,CACT,GAAGF,EACH,OAAQH,EAAK,OACb,MAAOA,EAAK,MACZ,GAAIA,EAAK,GACT,eAAgBA,EAAK,eACrB,cAAeA,EAAK,cACpB,WAAYA,EAAK,UACnB,CAAC,EACH,KAAOlB,GACLuB,GAAW,CACT,GAAGF,EACH,QAAArB,EACA,iBAAkBkB,EAAK,iBACvB,WAAYA,EAAK,UACnB,CAAC,CACL,CAAC,CACH,CAsBO,SAASQ,GAAWtB,EAAyC,CAClE,IAAMc,EAAOM,GAAuBpB,CAAO,EACrC,CAAE,OAAAO,EAAQ,MAAAc,EAAO,OAAApB,EAAQ,OAAAC,EAAQ,UAAAM,EAAW,OAAAC,EAAQ,MAAAO,CAAM,EAAIF,EAC9DG,EAAgB,CAAE,OAAAV,EAAQ,MAAAc,EAAO,OAAApB,EAAQ,OAAAC,EAAQ,UAAAM,EAAW,OAAAC,EAAQ,MAAAO,CAAM,EAEhF,OAAOtB,GAAkBoB,EAAK,SAAUA,EAAK,QAAS,CACpD,KAAM,IACJQ,GAAe,CACb,GAAGL,EACH,OAAQH,EAAK,OACb,MAAOA,EAAK,MACZ,GAAIA,EAAK,GACT,eAAgBA,EAAK,eACrB,cAAeA,EAAK,cACpB,WAAYA,EAAK,UACnB,CAAC,EACH,KAAOlB,GACL0B,GAAe,CACb,GAAGL,EACH,QAAArB,EACA,iBAAkBkB,EAAK,iBACvB,WAAYA,EAAK,UACnB,CAAC,CACL,CAAC,CACH,CCjHO,IAAMS,GAAN,KAAU,CACE,SACA,OACA,OACA,WAEjB,YAAYC,EAA2B,CAAC,EAAG,CACzC,GAAM,CACJ,SAAAC,EAAW,OACX,OAAAC,EAASA,GACT,OAAAC,EAASA,GACT,WAAAC,CACF,EAAIJ,EAEJ,KAAK,SAAWC,EAChB,KAAK,OAASC,EACd,KAAK,OAASC,EACd,KAAK,WAAaE,EAAiBD,CAAU,CAC/C,CAKA,aAA2B,CACzB,OAAO,KAAK,QACd,CAQA,eAAeE,EAAiB,GAAY,CAC1C,OAAOC,EAAmB,CAAE,OAAQ,KAAK,OAAQ,OAAQ,KAAK,OAAQ,OAAAD,CAAO,CAAC,CAChF,CAQA,MAAM,SAASN,EAA8C,CAC3D,OAAOQ,GAAmB,CACxB,GAAGR,EACH,SAAU,KAAK,SACf,OAAQ,KAAK,OACb,OAAQ,KAAK,OACb,WAAYA,EAAQ,YAAc,KAAK,UACzC,CAAC,CACH,CASA,aAAaA,EAAqC,CAChD,OAAOS,GAAuB,CAC5B,GAAGT,EACH,SAAU,KAAK,SACf,OAAQ,KAAK,OACb,OAAQ,KAAK,OACb,WAAYA,EAAQ,YAAc,KAAK,UACzC,CAAC,CACH,CAQA,MAAM,OAAOA,EAAkD,CAC7D,OAAOU,GAAiB,CACtB,GAAGV,EACH,SAAU,KAAK,SACf,OAAQ,KAAK,OACb,OAAQ,KAAK,OACb,WAAYA,EAAQ,YAAc,KAAK,UACzC,CAAC,CACH,CASA,WAAWA,EAAyC,CAClD,OAAOW,GAAqB,CAC1B,GAAGX,EACH,SAAU,KAAK,SACf,OAAQ,KAAK,OACb,OAAQ,KAAK,OACb,WAAYA,EAAQ,YAAc,KAAK,UACzC,CAAC,CACH,CAUA,YAAYA,EAAwC,CAClD,OAAOY,GAAsB,CAC3B,GAAGZ,EACH,SAAU,KAAK,QACjB,CAAC,CACH,CACF","names":["src_exports","__export","HOTP","NobleCryptoPlugin","OTP","ScureBase32Plugin","TOTP","createGuardrails","generate","generateSecret","generateSync","generateURI","stringToBytes","verify","verifySync","wrapResult","wrapResultAsync","OTPError","message","options","SecretError","SecretTooShortError","minBytes","actualBytes","SecretTooLongError","maxBytes","CounterError","CounterNegativeError","CounterOverflowError","CounterNotIntegerError","TimeError","TimeNegativeError","TimeNotFiniteError","PeriodError","PeriodTooSmallError","minPeriod","PeriodTooLargeError","maxPeriod","TokenError","OTPError","message","TokenLengthError","expected","actual","TokenFormatError","CryptoError","options","HMACError","RandomBytesError","CounterToleranceError","OTPError","message","CounterToleranceTooLargeError","maxWindow","totalChecks","CounterToleranceNegativeError","EpochToleranceError","EpochToleranceNegativeError","EpochToleranceTooLargeError","maxTolerance","actualValue","PluginError","CryptoPluginMissingError","Base32PluginMissingError","ConfigurationError","SecretMissingError","LabelMissingError","IssuerMissingError","SecretTypeError","AfterTimeStepError","AfterTimeStepNegativeError","AfterTimeStepNotIntegerError","AfterTimeStepRangeExceededError","textEncoder","textDecoder","MIN_SECRET_BYTES","MAX_SECRET_BYTES","RECOMMENDED_SECRET_BYTES","MIN_PERIOD","MAX_PERIOD","DEFAULT_PERIOD","MAX_COUNTER","MAX_WINDOW","OVERRIDE_SYMBOL","assertGuardrailSafeInteger","name","value","min","ConfigurationError","DEFAULT_GUARDRAILS","createGuardrails","custom","merged","validateSecret","secret","guardrails","DEFAULT_GUARDRAILS","SecretTooShortError","SecretTooLongError","validateCounter","counter","CounterNotIntegerError","CounterOverflowError","value","CounterNegativeError","validateTime","time","TimeNotFiniteError","TimeNegativeError","validatePeriod","period","PeriodTooSmallError","PeriodTooLargeError","validateToken","token","digits","TokenLengthError","TokenFormatError","validateCounterTolerance","counterTolerance","past","future","normalizeCounterTolerance","CounterToleranceError","CounterToleranceNegativeError","totalChecks","CounterToleranceTooLargeError","validateEpochTolerance","epochTolerance","DEFAULT_PERIOD","pastTolerance","futureTolerance","EpochToleranceError","EpochToleranceNegativeError","maxToleranceSeconds","totalToleranceSeconds","EpochToleranceTooLargeError","counterToBytes","bigintValue","buffer","dynamicTruncate","hmacResult","offset","truncateDigits","maxOtp","validateByteLengthEqual","a","b","constantTimeEqual","bufA","stringToBytes","bufB","result","i","stringToBytes","value","textEncoder","normalizeSecret","secret","base32","requireBase32Plugin","generateSecret","options","crypto","length","RECOMMENDED_SECRET_BYTES","requireCryptoPlugin","randomBytes","normalizeCounterTolerance","counterTolerance","normalizeEpochTolerance","epochTolerance","CryptoPluginMissingError","Base32PluginMissingError","requireSecret","SecretMissingError","requireLabel","label","LabelMissingError","requireIssuer","issuer","IssuerMissingError","requireBase32String","SecretTypeError","ok","value","err","error","wrapResult","fn","args","wrapResultAsync","CryptoContext","crypto","algorithm","key","data","result","error","message","HMACError","length","RandomBytesError","createCryptoContext","generate","uri","type","label","params","encodedLabel","part","result","queryParams","generateTOTP","options","issuer","account","secret","algorithm","digits","period","fullLabel","generateHOTP","counter","HOTP","options","createGuardrails","crypto","base32","requireCryptoPlugin","requireBase32Plugin","generateSecret","counter","mergedOptions","secret","algorithm","digits","requireSecret","guardrails","generate","params","counterTolerance","verify","issuer","label","requireLabel","requireIssuer","requireBase32String","generateHOTP","getHOTPGenerateOptions","options","secret","counter","algorithm","digits","crypto","base32","guardrails","hooks","requireSecret","requireCryptoPlugin","secretBytes","normalizeSecret","validateSecret","validateCounter","ctx","createCryptoContext","counterBytes","counterToBytes","generate","hmac","dt","dynamicTruncate","truncateDigits","generateSync","getHOTPVerifyOptions","token","counterTolerance","createGuardrails","validateToken","validateCounterTolerance","counterNum","past","future","normalizeCounterTolerance","totalChecks","cnt","verify","getGenerateOptions","startI","i","offset","currentCounter","expected","verifySync","TOTP","options","createGuardrails","crypto","base32","requireCryptoPlugin","requireBase32Plugin","generateSecret","mergedOptions","secret","algorithm","digits","period","epoch","t0","requireSecret","guardrails","generate","token","epochTolerance","afterTimeStep","verify","instanceIssuer","instanceLabel","instanceSecret","finalLabel","finalIssuer","finalSecret","requireLabel","requireIssuer","requireBase32String","generateTOTP","getTOTPGenerateOptions","options","secret","epoch","t0","period","algorithm","digits","crypto","base32","guardrails","createGuardrails","hooks","requireSecret","requireCryptoPlugin","secretBytes","normalizeSecret","validateSecret","validateTime","validatePeriod","counter","generate","opt","generateSync","validateAfterTimeStep","afterTimeStep","maxCounter","AfterTimeStepNegativeError","AfterTimeStepNotIntegerError","AfterTimeStepRangeExceededError","shouldSkipAfterTimeStep","getTOTPVerifyOptions","token","epochTolerance","validateToken","validateEpochTolerance","currentCounter","pastTolerance","futureTolerance","normalizeEpochTolerance","minCounter","verify","getGenerateOptions","expected","verifySync","isBytes","a","isArrayOf","isString","arr","item","astr","label","input","anumber","n","aArr","astrArr","isArrayOf","anumArr","chain","args","id","a","wrap","b","c","encode","x","decode","alphabet","letters","lettersA","len","indexes","l","i","digits","letter","join","separator","from","to","padding","bits","chr","data","end","gcd","a","b","radix2carry","from","to","powers","res","i","convertRadix2","data","padding","aArr","carry","pos","max","mask","n","anumber","pow","radix2","bits","revPadding","anumber","radix2carry","bytes","isBytes","convertRadix2","digits","anumArr","base32","chain","radix2","alphabet","padding","join","ScureBase32Plugin","data","options","padding","encoded","base32","str","uppercased","padded","error","isBytes","a","anumber","n","title","prefix","abytes","value","length","bytes","len","needsLen","ofLen","got","message","ahash","h","anumber","aexists","instance","checkFinished","aoutput","out","abytes","min","clean","arrays","i","createView","arr","rotr","word","shift","rotl","createHasher","hashCons","info","hashC","msg","opts","tmp","randomBytes","bytesLength","anumber","cr","oidNist","suffix","_HMAC","hash","key","ahash","abytes","blockLen","pad","i","clean","buf","aexists","out","aoutput","to","oHash","iHash","finished","destroyed","outputLen","hmac","hmac_","message","Chi","a","b","c","Maj","HashMD","blockLen","outputLen","padOffset","isLE","createView","data","aexists","abytes","view","buffer","len","pos","take","dataView","out","aoutput","clean","i","oview","outLen","state","res","to","length","finished","destroyed","SHA256_IV","SHA512_IV","SHA1_IV","SHA1_W","_SHA1","HashMD","A","B","C","D","E","view","offset","i","rotl","F","K","Chi","Maj","T","clean","sha1","createHasher","U32_MASK64","_32n","fromBig","n","le","split","lst","len","Ah","Al","i","h","l","shrSH","h","_l","s","shrSL","l","rotrSH","rotrSL","rotrBH","rotrBL","add","Ah","Al","Bh","Bl","l","add3L","Cl","add3H","low","Ch","add4L","Dl","add4H","Dh","add5L","El","add5H","Eh","SHA256_K","SHA256_W","SHA2_32B","HashMD","outputLen","A","B","C","D","E","F","G","H","view","offset","i","W15","W2","s0","rotr","s1","sigma1","T1","Chi","T2","Maj","clean","_SHA256","SHA256_IV","K512","split","n","SHA512_Kh","SHA512_Kl","SHA512_W_H","SHA512_W_L","SHA2_64B","HashMD","outputLen","Ah","Al","Bh","Bl","Ch","Cl","Dh","Dl","Eh","El","Fh","Fl","Gh","Gl","Hh","Hl","view","offset","i","W15h","W15l","s0h","rotrSH","shrSH","s0l","rotrSL","shrSL","W2h","W2l","s1h","rotrBH","s1l","rotrBL","SUMl","add4L","SUMh","add4H","sigma1h","sigma1l","CHIh","CHIl","T1ll","add5L","T1h","add5H","T1l","sigma0h","sigma0l","MAJh","MAJl","add","All","add3L","add3H","clean","_SHA512","SHA512_IV","sha256","createHasher","_SHA256","oidNist","sha512","createHasher","_SHA512","oidNist","NobleCryptoPlugin","algorithm","key","data","hmac","sha1","sha256","sha512","length","randomBytes","a","b","constantTimeEqual","crypto","normalizeGenerateOptions","options","crypto","base32","createGuardrails","normalizeVerifyOptions","executeByStrategy","strategy","counter","handlers","ConfigurationError","generateSecret","options","crypto","base32","length","generateURI","issuer","label","secret","algorithm","digits","period","generateTOTP","generateHOTP","generate","opts","normalizeGenerateOptions","hooks","commonOptions","generateSync","verify","normalizeVerifyOptions","token","verifySync","OTP","options","strategy","crypto","base32","guardrails","createGuardrails","length","generateSecret","generate","generateSync","verify","verifySync","generateURI"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"inputs":{"../core/src/errors.ts":{"bytes":12228,"imports":[],"format":"esm"},"../core/src/utils.ts":{"bytes":28254,"imports":[{"path":"../core/src/errors.ts","kind":"import-statement","original":"./errors.js"}],"format":"esm"},"../core/src/crypto-context.ts":{"bytes":2926,"imports":[{"path":"../core/src/errors.ts","kind":"import-statement","original":"./errors.js"}],"format":"esm"},"../core/src/base32-context.ts":{"bytes":2029,"imports":[{"path":"../core/src/errors.ts","kind":"import-statement","original":"./errors.js"}],"format":"esm"},"../core/src/plugin-factories.ts":{"bytes":3523,"imports":[{"path":"../core/src/errors.ts","kind":"import-statement","original":"./errors.js"},{"path":"../core/src/utils.ts","kind":"import-statement","original":"./utils.js"}],"format":"esm"},"../core/src/utility-types.ts":{"bytes":4869,"imports":[],"format":"esm"},"../core/src/index.ts":{"bytes":2658,"imports":[{"path":"../core/src/errors.ts","kind":"import-statement","original":"./errors.js"},{"path":"../core/src/utils.ts","kind":"import-statement","original":"./utils.js"},{"path":"../core/src/crypto-context.ts","kind":"import-statement","original":"./crypto-context.js"},{"path":"../core/src/base32-context.ts","kind":"import-statement","original":"./base32-context.js"},{"path":"../core/src/plugin-factories.ts","kind":"import-statement","original":"./plugin-factories.js"},{"path":"../core/src/utility-types.ts","kind":"import-statement","original":"./utility-types.js"}],"format":"esm"},"../uri/src/types.ts":{"bytes":2038,"imports":[],"format":"esm"},"../uri/src/parse.ts":{"bytes":5830,"imports":[{"path":"../uri/src/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"../uri/src/generate.ts":{"bytes":3904,"imports":[],"format":"esm"},"../uri/src/index.ts":{"bytes":395,"imports":[{"path":"../uri/src/parse.ts","kind":"import-statement","original":"./parse.js"},{"path":"../uri/src/generate.ts","kind":"import-statement","original":"./generate.js"},{"path":"../uri/src/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"../hotp/src/class.ts":{"bytes":3988,"imports":[{"path":"../core/src/index.ts","kind":"import-statement","original":"@otplib/core"},{"path":"../uri/src/index.ts","kind":"import-statement","original":"@otplib/uri"},{"path":"../hotp/src/index.ts","kind":"import-statement","original":"./index.js"}],"format":"esm"},"../hotp/src/index.ts":{"bytes":11684,"imports":[{"path":"../core/src/index.ts","kind":"import-statement","original":"@otplib/core"},{"path":"../hotp/src/class.ts","kind":"import-statement","original":"./class.js"},{"path":"../core/src/index.ts","kind":"import-statement","original":"@otplib/core"}],"format":"esm"},"../totp/src/class.ts":{"bytes":5562,"imports":[{"path":"../core/src/index.ts","kind":"import-statement","original":"@otplib/core"},{"path":"../uri/src/index.ts","kind":"import-statement","original":"@otplib/uri"},{"path":"../totp/src/index.ts","kind":"import-statement","original":"./index.js"}],"format":"esm"},"../totp/src/index.ts":{"bytes":13872,"imports":[{"path":"../core/src/index.ts","kind":"import-statement","original":"@otplib/core"},{"path":"../hotp/src/index.ts","kind":"import-statement","original":"@otplib/hotp"},{"path":"../totp/src/class.ts","kind":"import-statement","original":"./class"},{"path":"../core/src/index.ts","kind":"import-statement","original":"@otplib/core"}],"format":"esm"},"../../node_modules/.pnpm/@scure+base@2.2.0/node_modules/@scure/base/index.js":{"bytes":41474,"imports":[],"format":"esm"},"../plugin-base32-scure/src/index.ts":{"bytes":2099,"imports":[{"path":"../../node_modules/.pnpm/@scure+base@2.2.0/node_modules/@scure/base/index.js","kind":"import-statement","original":"@scure/base"}],"format":"esm"},"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/utils.js":{"bytes":20182,"imports":[],"format":"esm"},"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/hmac.js":{"bytes":3143,"imports":[{"path":"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/utils.js","kind":"import-statement","original":"./utils.js"}],"format":"esm"},"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/_md.js":{"bytes":8372,"imports":[{"path":"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/utils.js","kind":"import-statement","original":"./utils.js"}],"format":"esm"},"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/legacy.js":{"bytes":11867,"imports":[{"path":"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/_md.js","kind":"import-statement","original":"./_md.js"},{"path":"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/utils.js","kind":"import-statement","original":"./utils.js"}],"format":"esm"},"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/_u64.js":{"bytes":4972,"imports":[],"format":"esm"},"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/sha2.js":{"bytes":19112,"imports":[{"path":"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/_md.js","kind":"import-statement","original":"./_md.js"},{"path":"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/_u64.js","kind":"import-statement","original":"./_u64.js"},{"path":"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/utils.js","kind":"import-statement","original":"./utils.js"}],"format":"esm"},"../plugin-crypto-noble/src/index.ts":{"bytes":2667,"imports":[{"path":"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/hmac.js","kind":"import-statement","original":"@noble/hashes/hmac.js"},{"path":"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/legacy.js","kind":"import-statement","original":"@noble/hashes/legacy.js"},{"path":"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/sha2.js","kind":"import-statement","original":"@noble/hashes/sha2.js"},{"path":"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/utils.js","kind":"import-statement","original":"@noble/hashes/utils.js"},{"path":"../core/src/index.ts","kind":"import-statement","original":"@otplib/core"}],"format":"esm"},"src/defaults.ts":{"bytes":1514,"imports":[{"path":"../core/src/index.ts","kind":"import-statement","original":"@otplib/core"},{"path":"../plugin-base32-scure/src/index.ts","kind":"import-statement","original":"@otplib/plugin-base32-scure"},{"path":"../plugin-crypto-noble/src/index.ts","kind":"import-statement","original":"@otplib/plugin-crypto-noble"}],"format":"esm"},"src/functional.ts":{"bytes":10325,"imports":[{"path":"../core/src/index.ts","kind":"import-statement","original":"@otplib/core"},{"path":"../hotp/src/index.ts","kind":"import-statement","original":"@otplib/hotp"},{"path":"../totp/src/index.ts","kind":"import-statement","original":"@otplib/totp"},{"path":"../uri/src/index.ts","kind":"import-statement","original":"@otplib/uri"},{"path":"src/defaults.ts","kind":"import-statement","original":"./defaults.js"}],"format":"esm"},"src/class.ts":{"bytes":9168,"imports":[{"path":"../core/src/index.ts","kind":"import-statement","original":"@otplib/core"},{"path":"src/defaults.ts","kind":"import-statement","original":"./defaults.js"},{"path":"src/functional.ts","kind":"import-statement","original":"./functional.js"}],"format":"esm"},"src/index.ts":{"bytes":958,"imports":[{"path":"src/functional.ts","kind":"import-statement","original":"./functional.js"},{"path":"src/class.ts","kind":"import-statement","original":"./class.js"},{"path":"../hotp/src/index.ts","kind":"import-statement","original":"@otplib/hotp"},{"path":"../totp/src/index.ts","kind":"import-statement","original":"@otplib/totp"},{"path":"../core/src/index.ts","kind":"import-statement","original":"@otplib/core"},{"path":"../plugin-crypto-noble/src/index.ts","kind":"import-statement","original":"@otplib/plugin-crypto-noble"},{"path":"../plugin-base32-scure/src/index.ts","kind":"import-statement","original":"@otplib/plugin-base32-scure"}],"format":"esm"}},"outputs":{"dist/index.global.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":308567},"dist/index.global.js":{"imports":[],"exports":[],"entryPoint":"src/index.ts","inputs":{"src/index.ts":{"bytesInOutput":298},"../core/src/errors.ts":{"bytesInOutput":4268},"../core/src/index.ts":{"bytesInOutput":0},"../core/src/utils.ts":{"bytesInOutput":3533},"../core/src/crypto-context.ts":{"bytesInOutput":675},"../uri/src/generate.ts":{"bytesInOutput":945},"../uri/src/index.ts":{"bytesInOutput":0},"../hotp/src/class.ts":{"bytesInOutput":939},"../hotp/src/index.ts":{"bytesInOutput":1596},"../totp/src/class.ts":{"bytesInOutput":1139},"../totp/src/index.ts":{"bytesInOutput":1754},"../../node_modules/.pnpm/@scure+base@2.2.0/node_modules/@scure/base/index.js":{"bytesInOutput":3184},"../plugin-base32-scure/src/index.ts":{"bytesInOutput":295},"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/utils.js":{"bytesInOutput":2021},"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/hmac.js":{"bytesInOutput":1326},"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/_md.js":{"bytesInOutput":1816},"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/legacy.js":{"bytesInOutput":868},"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/_u64.js":{"bytesInOutput":785},"../../node_modules/.pnpm/@noble+hashes@2.2.0/node_modules/@noble/hashes/sha2.js":{"bytesInOutput":5498},"../plugin-crypto-noble/src/index.ts":{"bytesInOutput":179},"src/defaults.ts":{"bytesInOutput":440},"src/functional.ts":{"bytesInOutput":2138},"src/class.ts":{"bytesInOutput":909}},"bytes":35212}}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "otplib",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.4.1",
|
|
4
4
|
"description": "TypeScript-first library for TOTP and HOTP with multi-runtime and plugin support",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Gerald Yeo <support@yeojz.dev>",
|
|
@@ -31,6 +31,9 @@
|
|
|
31
31
|
"main": "./dist/index.cjs",
|
|
32
32
|
"module": "./dist/index.js",
|
|
33
33
|
"types": "./dist/index.d.ts",
|
|
34
|
+
"browser": "./dist/index.global.js",
|
|
35
|
+
"unpkg": "./dist/index.global.js",
|
|
36
|
+
"jsdelivr": "./dist/index.global.js",
|
|
34
37
|
"exports": {
|
|
35
38
|
".": {
|
|
36
39
|
"import": {
|
|
@@ -69,17 +72,17 @@
|
|
|
69
72
|
"LICENSE"
|
|
70
73
|
],
|
|
71
74
|
"dependencies": {
|
|
72
|
-
"@otplib/uri": "13.
|
|
73
|
-
"@otplib/
|
|
74
|
-
"@otplib/
|
|
75
|
-
"@otplib/
|
|
76
|
-
"@otplib/plugin-
|
|
77
|
-
"@otplib/
|
|
75
|
+
"@otplib/uri": "13.4.1",
|
|
76
|
+
"@otplib/core": "13.4.1",
|
|
77
|
+
"@otplib/hotp": "13.4.1",
|
|
78
|
+
"@otplib/totp": "13.4.1",
|
|
79
|
+
"@otplib/plugin-crypto-noble": "13.4.1",
|
|
80
|
+
"@otplib/plugin-base32-scure": "13.4.1"
|
|
78
81
|
},
|
|
79
82
|
"devDependencies": {
|
|
80
83
|
"tsup": "^8.5.1",
|
|
81
84
|
"typescript": "^5.9.3",
|
|
82
|
-
"vitest": "^4.
|
|
85
|
+
"vitest": "^4.1.5",
|
|
83
86
|
"@repo/testing": "13.0.1"
|
|
84
87
|
},
|
|
85
88
|
"publishConfig": {
|