@dismissible/nestjs-jwt-auth-hook 2.0.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -105,6 +105,27 @@ export class AppModule {}
105
105
 
106
106
  \*\* `userIdMatchRegex` is required when `userIdMatchType` is `regex`.
107
107
 
108
+ ### User ID Match Types
109
+
110
+ The `userIdMatchType` option controls how the user ID from the JWT token claim is compared to the `userId` in the request URL path:
111
+
112
+ - **`exact`** (default): The token claim value must exactly match the URL user ID.
113
+ - **`substring`**: The URL user ID must be contained within the token claim value.
114
+ - **`regex`**: The regex pattern is applied to the token claim value. If a capture group is present, the **first capture group** is extracted and compared to the URL user ID. If no capture group is present, the **full match** is used.
115
+
116
+ #### Regex Matching Examples
117
+
118
+ For a token with `sub` claim value `FfXHGud25MDOUGjQyBZnCWkkWlFDCS0Y@clients`:
119
+
120
+ | Pattern | Extracted Value | URL userId | Result |
121
+ | ----------------- | ---------------------------------- | ---------------------------------- | -------- |
122
+ | `^(.+)@clients$` | `FfXHGud25MDOUGjQyBZnCWkkWlFDCS0Y` | `FfXHGud25MDOUGjQyBZnCWkkWlFDCS0Y` | Match |
123
+ | `^(\w+)@clients$` | `FfXHGud25MDOUGjQyBZnCWkkWlFDCS0Y` | `FfXHGud25MDOUGjQyBZnCWkkWlFDCS0Y` | Match |
124
+ | `clients$` | `clients` | `clients` | Match |
125
+ | `@clients$` | `@clients` | `FfXHGud25MDOUGjQyBZnCWkkWlFDCS0Y` | No Match |
126
+
127
+ > **Tip:** Use capture groups to extract the meaningful part of the token claim value for comparison with the URL user ID.
128
+
108
129
  ## Environment Variables
109
130
 
110
131
  When using the Dismissible API Docker image or the standalone API, these environment variables configure JWT authentication:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dismissible/nestjs-jwt-auth-hook",
3
- "version": "2.0.3",
3
+ "version": "3.0.0",
4
4
  "description": "JWT authentication hook for Dismissible applications using OIDC well-known discovery",
5
5
  "main": "./src/index.js",
6
6
  "types": "./src/index.d.ts",
@@ -18,10 +18,10 @@
18
18
  ],
19
19
  "dependencies": {
20
20
  "@nestjs/axios": "^4.0.1",
21
- "@dismissible/nestjs-hooks": "^2.0.3",
22
- "@dismissible/nestjs-request": "^2.0.3",
23
- "@dismissible/nestjs-logger": "^2.0.3",
24
- "@dismissible/nestjs-validation": "^2.0.3",
21
+ "@dismissible/nestjs-hooks": "^3.0.0",
22
+ "@dismissible/nestjs-request": "^3.0.0",
23
+ "@dismissible/nestjs-logger": "^3.0.0",
24
+ "@dismissible/nestjs-validation": "^3.0.0",
25
25
  "jwks-rsa": "^3.2.0",
26
26
  "jsonwebtoken": "^9.0.3"
27
27
  },
@@ -74,7 +74,13 @@ export declare class JwtAuthHookConfig {
74
74
  /**
75
75
  * Optional: Regex pattern for user ID matching.
76
76
  * Required when userIdMatchType is 'regex'.
77
- * The pattern is tested against the tokenUserId from the JWT claim.
77
+ *
78
+ * The pattern is matched against the tokenUserId from the JWT claim.
79
+ * If the pattern contains a capture group, the first captured group is
80
+ * extracted and compared against the URL's userId.
81
+ * If no capture group exists, the full match is compared.
82
+ *
83
+ * Example: "^(.+)@clients$" extracts everything before "@clients"
78
84
  */
79
85
  readonly userIdMatchRegex?: string;
80
86
  }
@@ -1 +1 @@
1
- {"version":3,"file":"jwt-auth-hook.config.js","sourceRoot":"","sources":["../../../../libs/jwt-auth-hook/src/jwt-auth-hook.config.ts"],"names":[],"mappings":";;;;AAAA,qDASyB;AACzB,yDAAyC;AACzC,sEAA2F;AAE3F;;GAEG;AACU,QAAA,gCAAgC,GAAG,MAAM,CAAC,kCAAkC,CAAC,CAAC;AAE3F;;GAEG;AACH,IAAY,eAOX;AAPD,WAAY,eAAe;IACzB,mCAAmC;IACnC,kCAAe,CAAA;IACf,wDAAwD;IACxD,0CAAuB,CAAA;IACvB,kEAAkE;IAClE,kCAAe,CAAA;AACjB,CAAC,EAPW,eAAe,+BAAf,eAAe,QAO1B;AAED;;GAEG;AACH,MAAa,iBAAiB;CAwG7B;AAxGD,8CAwGC;AArGiB;IAFf,IAAA,2BAAS,GAAE;IACX,IAAA,oCAAgB,GAAE;;kDACe;AAQlB;IAFf,IAAA,4BAAU,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC;IACrC,IAAA,uBAAK,GAAE;;uDAC8B;AAYtB;IAJf,IAAA,4BAAU,GAAE;IACZ,IAAA,yBAAO,GAAE;IACT,IAAA,0BAAQ,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,IAAA,2CAAuB,GAAE;;iDACQ;AAQlB;IAFf,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;mDACuB;AAWlB;IAJf,IAAA,4BAAU,GAAE;IACZ,IAAA,yBAAO,GAAE;IACT,IAAA,0BAAQ,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,IAAA,2CAAuB,GAAE;;qDACY;AAStB;IAHf,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,MAAM,CAAC;;4DACwB;AAS3B;IAHf,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,MAAM,CAAC;;yDACqB;AASxB;IAHf,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,MAAM,CAAC;;mDACe;AASlB;IAHf,IAAA,4BAAU,GAAE;IACZ,IAAA,2BAAS,GAAE;IACX,IAAA,oCAAgB,EAAC,IAAI,CAAC,CAAC,kCAAkC;;;sDACpB;AAQtB;IAFf,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;sDAC0B;AAQrB;IAFf,IAAA,4BAAU,GAAE;IACZ,IAAA,wBAAM,EAAC,eAAe,CAAC;;0DAC0B;AASlC;IAFf,IAAA,4BAAU,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,KAAK,eAAe,CAAC,KAAK,CAAC;IAC9D,IAAA,0BAAQ,GAAE;;2DAC+B"}
1
+ {"version":3,"file":"jwt-auth-hook.config.js","sourceRoot":"","sources":["../../../../libs/jwt-auth-hook/src/jwt-auth-hook.config.ts"],"names":[],"mappings":";;;;AAAA,qDASyB;AACzB,yDAAyC;AACzC,sEAA2F;AAE3F;;GAEG;AACU,QAAA,gCAAgC,GAAG,MAAM,CAAC,kCAAkC,CAAC,CAAC;AAE3F;;GAEG;AACH,IAAY,eAOX;AAPD,WAAY,eAAe;IACzB,mCAAmC;IACnC,kCAAe,CAAA;IACf,wDAAwD;IACxD,0CAAuB,CAAA;IACvB,kEAAkE;IAClE,kCAAe,CAAA;AACjB,CAAC,EAPW,eAAe,+BAAf,eAAe,QAO1B;AAED;;GAEG;AACH,MAAa,iBAAiB;CA8G7B;AA9GD,8CA8GC;AA3GiB;IAFf,IAAA,2BAAS,GAAE;IACX,IAAA,oCAAgB,GAAE;;kDACe;AAQlB;IAFf,IAAA,4BAAU,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC;IACrC,IAAA,uBAAK,GAAE;;uDAC8B;AAYtB;IAJf,IAAA,4BAAU,GAAE;IACZ,IAAA,yBAAO,GAAE;IACT,IAAA,0BAAQ,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,IAAA,2CAAuB,GAAE;;iDACQ;AAQlB;IAFf,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;mDACuB;AAWlB;IAJf,IAAA,4BAAU,GAAE;IACZ,IAAA,yBAAO,GAAE;IACT,IAAA,0BAAQ,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,IAAA,2CAAuB,GAAE;;qDACY;AAStB;IAHf,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,MAAM,CAAC;;4DACwB;AAS3B;IAHf,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,MAAM,CAAC;;yDACqB;AASxB;IAHf,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,MAAM,CAAC;;mDACe;AASlB;IAHf,IAAA,4BAAU,GAAE;IACZ,IAAA,2BAAS,GAAE;IACX,IAAA,oCAAgB,EAAC,IAAI,CAAC,CAAC,kCAAkC;;;sDACpB;AAQtB;IAFf,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;sDAC0B;AAQrB;IAFf,IAAA,4BAAU,GAAE;IACZ,IAAA,wBAAM,EAAC,eAAe,CAAC;;0DAC0B;AAelC;IAFf,IAAA,4BAAU,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,KAAK,eAAe,CAAC,KAAK,CAAC;IAC9D,IAAA,0BAAQ,GAAE;;2DAC+B"}
@@ -1,4 +1,4 @@
1
- import { IDismissibleLifecycleHook, IHookResult } from '@dismissible/nestjs-hooks';
1
+ import { IDismissibleLifecycleHook, IHookResult, IBatchHookResult } from '@dismissible/nestjs-hooks';
2
2
  import { IRequestContext } from '@dismissible/nestjs-request';
3
3
  import { IDismissibleLogger } from '@dismissible/nestjs-logger';
4
4
  import { JwtAuthService } from './jwt-auth.service';
@@ -18,6 +18,15 @@ export declare class JwtAuthHook implements IDismissibleLifecycleHook {
18
18
  * Runs before any dismissible operation.
19
19
  */
20
20
  onBeforeRequest(itemId: string, userId: string, context?: IRequestContext): Promise<IHookResult>;
21
+ /**
22
+ * Validates the JWT bearer token from the Authorization header for batch requests.
23
+ * Runs before any batch dismissible operation.
24
+ */
25
+ onBeforeBatchRequest(itemIds: string[], userId: string, context?: IRequestContext): Promise<IBatchHookResult>;
26
+ /**
27
+ * Core JWT validation logic shared by both single and batch request handlers.
28
+ */
29
+ private validateJwtToken;
21
30
  /**
22
31
  * Matches the token user ID against the request user ID based on the configured match type.
23
32
  */
@@ -22,14 +22,39 @@ let JwtAuthHook = class JwtAuthHook {
22
22
  * Runs before any dismissible operation.
23
23
  */
24
24
  async onBeforeRequest(itemId, userId, context) {
25
+ this.logger.debug('onBeforeRequest', {
26
+ itemId,
27
+ userId,
28
+ requestId: context?.requestId,
29
+ });
30
+ return this.validateJwtToken(userId, context);
31
+ }
32
+ /**
33
+ * Validates the JWT bearer token from the Authorization header for batch requests.
34
+ * Runs before any batch dismissible operation.
35
+ */
36
+ async onBeforeBatchRequest(itemIds, userId, context) {
37
+ this.logger.debug('onBeforeBatchRequest', {
38
+ itemIds,
39
+ userId,
40
+ requestId: context?.requestId,
41
+ });
42
+ return this.validateJwtToken(userId, context);
43
+ }
44
+ /**
45
+ * Core JWT validation logic shared by both single and batch request handlers.
46
+ */
47
+ async validateJwtToken(userId, context) {
25
48
  if (!this.config.enabled) {
26
49
  return { proceed: true };
27
50
  }
51
+ this.logger.debug('validating JWT token', {
52
+ config: this.config,
53
+ });
28
54
  const authorizationHeader = context?.headers['authorization'];
29
55
  const token = this.jwtAuthService.extractBearerToken(authorizationHeader);
30
56
  if (!token) {
31
- this.logger.debug('JWT auth hook: No bearer token provided', {
32
- itemId,
57
+ this.logger.debug('No bearer token provided', {
33
58
  userId,
34
59
  requestId: context?.requestId,
35
60
  });
@@ -37,8 +62,7 @@ let JwtAuthHook = class JwtAuthHook {
37
62
  }
38
63
  const result = await this.jwtAuthService.validateToken(token);
39
64
  if (!result.valid) {
40
- this.logger.debug('JWT auth hook: Token validation failed', {
41
- itemId,
65
+ this.logger.debug('Token validation failed', {
42
66
  userId,
43
67
  requestId: context?.requestId,
44
68
  error: result.error,
@@ -50,8 +74,7 @@ let JwtAuthHook = class JwtAuthHook {
50
74
  const tokenUserId = result.payload?.[userIdClaim];
51
75
  if (matchUserId && tokenUserId) {
52
76
  if (!this.matchUserIdValue(tokenUserId, userId)) {
53
- this.logger.debug('JWT auth hook: User ID mismatch', {
54
- itemId,
77
+ this.logger.debug('User ID mismatch', {
55
78
  userId,
56
79
  requestId: context?.requestId,
57
80
  tokenSubject: tokenUserId,
@@ -59,15 +82,12 @@ let JwtAuthHook = class JwtAuthHook {
59
82
  throw new common_1.ForbiddenException('User ID in request does not match authenticated user');
60
83
  }
61
84
  }
62
- this.logger.debug('JWT auth hook: Token validated successfully', {
63
- itemId,
85
+ this.logger.debug('Token validated successfully', {
64
86
  userId,
65
87
  requestId: context?.requestId,
66
88
  subject: tokenUserId,
67
89
  });
68
- return {
69
- proceed: true,
70
- };
90
+ return { proceed: true };
71
91
  }
72
92
  /**
73
93
  * Matches the token user ID against the request user ID based on the configured match type.
@@ -75,13 +95,47 @@ let JwtAuthHook = class JwtAuthHook {
75
95
  matchUserIdValue(tokenUserId, userId) {
76
96
  const matchType = this.config.userIdMatchType ?? jwt_auth_hook_config_1.UserIdMatchType.EXACT;
77
97
  switch (matchType) {
78
- case jwt_auth_hook_config_1.UserIdMatchType.EXACT:
98
+ case jwt_auth_hook_config_1.UserIdMatchType.EXACT: {
99
+ this.logger.debug('matching user ID value via exact value', {
100
+ tokenUserId,
101
+ userId,
102
+ matchType,
103
+ });
79
104
  return tokenUserId === userId;
80
- case jwt_auth_hook_config_1.UserIdMatchType.SUBSTRING:
81
- return tokenUserId.includes(userId) || userId.includes(tokenUserId);
105
+ }
106
+ case jwt_auth_hook_config_1.UserIdMatchType.SUBSTRING: {
107
+ const result = tokenUserId.includes(userId) || userId.includes(tokenUserId);
108
+ this.logger.debug('matching user ID value via substring', {
109
+ tokenUserId,
110
+ userId,
111
+ matchType,
112
+ result,
113
+ });
114
+ return result;
115
+ }
82
116
  case jwt_auth_hook_config_1.UserIdMatchType.REGEX: {
83
117
  const regex = new RegExp(this.config.userIdMatchRegex);
84
- return regex.test(tokenUserId);
118
+ const match = regex.exec(tokenUserId);
119
+ if (!match) {
120
+ this.logger.debug('regex did not match token user ID', {
121
+ tokenUserId,
122
+ userId,
123
+ matchType,
124
+ pattern: this.config.userIdMatchRegex,
125
+ });
126
+ return false;
127
+ }
128
+ // Use first capture group if present, otherwise use full match
129
+ const extractedUserId = match[1] ?? match[0];
130
+ const result = extractedUserId === userId;
131
+ this.logger.debug('matching user ID value via regex', {
132
+ tokenUserId,
133
+ userId,
134
+ extractedUserId,
135
+ matchType,
136
+ result,
137
+ });
138
+ return result;
85
139
  }
86
140
  }
87
141
  }
@@ -1 +1 @@
1
- {"version":3,"file":"jwt-auth.hook.js","sourceRoot":"","sources":["../../../../libs/jwt-auth-hook/src/jwt-auth.hook.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"jwt-auth.hook.js","sourceRoot":"","sources":["../../../../libs/jwt-auth-hook/src/jwt-auth.hook.ts"],"names":[],"mappings":";;;;AAAA,2CAA+F;AAO/F,8DAAoF;AACpF,yDAAoD;AACpD,iEAIgC;AAEhC;;;GAGG;AAEI,IAAM,WAAW,GAAjB,MAAM,WAAW;IAGtB,YACmB,cAA8B,EAE9B,MAAyB,EAEzB,MAA0B;QAJ1B,mBAAc,GAAd,cAAc,CAAgB;QAE9B,WAAM,GAAN,MAAM,CAAmB;QAEzB,WAAM,GAAN,MAAM,CAAoB;QAE3C,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC;IAC1C,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe,CACnB,MAAc,EACd,MAAc,EACd,OAAyB;QAEzB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,EAAE;YACnC,MAAM;YACN,MAAM;YACN,SAAS,EAAE,OAAO,EAAE,SAAS;SAC9B,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,oBAAoB,CACxB,OAAiB,EACjB,MAAc,EACd,OAAyB;QAEzB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE;YACxC,OAAO;YACP,MAAM;YACN,SAAS,EAAE,OAAO,EAAE,SAAS;SAC9B,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,gBAAgB,CAC5B,MAAc,EACd,OAAoC;QAEpC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACzB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE;YACxC,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QAEH,MAAM,mBAAmB,GAAG,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;QAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,mBAAmB,CAAC,CAAC;QAE1E,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE;gBAC5C,MAAM;gBACN,SAAS,EAAE,OAAO,EAAE,SAAS;aAC9B,CAAC,CAAC;YAEH,MAAM,IAAI,8BAAqB,CAAC,iCAAiC,CAAC,CAAC;QACrE,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAE9D,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE;gBAC3C,MAAM;gBACN,SAAS,EAAE,OAAO,EAAE,SAAS;gBAC7B,KAAK,EAAE,MAAM,CAAC,KAAK;aACpB,CAAC,CAAC;YAEH,MAAM,IAAI,8BAAqB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC;QACpD,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,KAAK,CAAC;QACrD,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,WAAW,CAAuB,CAAC;QAExE,IAAI,WAAW,IAAI,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,CAAC;gBAChD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,EAAE;oBACpC,MAAM;oBACN,SAAS,EAAE,OAAO,EAAE,SAAS;oBAC7B,YAAY,EAAE,WAAW;iBAC1B,CAAC,CAAC;gBAEH,MAAM,IAAI,2BAAkB,CAAC,sDAAsD,CAAC,CAAC;YACvF,CAAC;QACH,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE;YAChD,MAAM;YACN,SAAS,EAAE,OAAO,EAAE,SAAS;YAC7B,OAAO,EAAE,WAAW;SACrB,CAAC,CAAC;QAEH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,WAAmB,EAAE,MAAc;QAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,sCAAe,CAAC,KAAK,CAAC;QAEvE,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,sCAAe,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC3B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,EAAE;oBAC1D,WAAW;oBACX,MAAM;oBACN,SAAS;iBACV,CAAC,CAAC;gBACH,OAAO,WAAW,KAAK,MAAM,CAAC;YAChC,CAAC;YACD,KAAK,sCAAe,CAAC,SAAS,CAAC,CAAC,CAAC;gBAC/B,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;gBAC5E,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE;oBACxD,WAAW;oBACX,MAAM;oBACN,SAAS;oBACT,MAAM;iBACP,CAAC,CAAC;gBACH,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,KAAK,sCAAe,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC3B,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,gBAA0B,CAAC,CAAC;gBACjE,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBAEtC,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE;wBACrD,WAAW;wBACX,MAAM;wBACN,SAAS;wBACT,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB;qBACtC,CAAC,CAAC;oBACH,OAAO,KAAK,CAAC;gBACf,CAAC;gBAED,+DAA+D;gBAC/D,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC7C,MAAM,MAAM,GAAG,eAAe,KAAK,MAAM,CAAC;gBAE1C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE;oBACpD,WAAW;oBACX,MAAM;oBACN,eAAe;oBACf,SAAS;oBACT,MAAM;iBACP,CAAC,CAAC;gBACH,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;IACH,CAAC;CACF,CAAA;AArKY,kCAAW;sBAAX,WAAW;IADvB,IAAA,mBAAU,GAAE;IAMR,mBAAA,IAAA,eAAM,EAAC,uDAAgC,CAAC,CAAA;IAExC,mBAAA,IAAA,eAAM,EAAC,kCAAkB,CAAC,CAAA;6CAHM,iCAAc;QAEtB,wCAAiB;GANjC,WAAW,CAqKvB"}