@spinajs/telemetry 2.0.506 → 2.0.508

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.
@@ -2,9 +2,12 @@ import { BasePolicy, IController, IRoute, Request } from '@spinajs/http';
2
2
  import { Log } from '@spinajs/log';
3
3
  /**
4
4
  * Shared-token guard for the telemetry endpoints. Reads the expected token from
5
- * `telemetry.auth.token` and compares it against the `x-metrics-token` header.
6
- * The header name is deliberately unchanged from the retired
7
- * `@spinajs/metrics` package so existing scrape configs keep working.
5
+ * `telemetry.auth.token` and compares it against the `x-metrics-token` header,
6
+ * or equivalently against `Authorization: Bearer <token>`. The custom
7
+ * header name is deliberately unchanged from the retired `@spinajs/metrics`
8
+ * package so existing scrape configs keep working; the Bearer form exists
9
+ * because stock Prometheus / OTel-collector scrape configs can only send
10
+ * `authorization.credentials` (a Bearer header), not arbitrary headers.
8
11
  *
9
12
  * Bypassed entirely in development.
10
13
  */
@@ -15,5 +18,7 @@ export declare class TelemetryTokenPolicy extends BasePolicy {
15
18
  protected HEADER_TOKEN_FIELD: string;
16
19
  isEnabled(_action: IRoute, _instance: IController): boolean;
17
20
  execute(req: Request): Promise<void>;
21
+ /** The credentials of an `Authorization: Bearer <token>` header, if present. */
22
+ protected bearerToken(req: Request): string | undefined;
18
23
  }
19
24
  //# sourceMappingURL=TelemetryTokenPolicy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TelemetryTokenPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/TelemetryTokenPolicy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAE,GAAG,EAAU,MAAM,cAAc,CAAC;AAG3C;;;;;;;GAOG;AACH,qBACa,oBAAqB,SAAQ,UAAU;IAElD,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAGnB,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC;IAGxB,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC;IAEzB,SAAS,CAAC,kBAAkB,SAAqB;IAE1C,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,GAAG,OAAO,CAEjE;IAEY,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAehD;CACF"}
1
+ {"version":3,"file":"TelemetryTokenPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/TelemetryTokenPolicy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAE,GAAG,EAAU,MAAM,cAAc,CAAC;AAG3C;;;;;;;;;;GAUG;AACH,qBACa,oBAAqB,SAAQ,UAAU;IAElD,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAGnB,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC;IAGxB,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC;IAEzB,SAAS,CAAC,kBAAkB,SAAqB;IAE1C,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,GAAG,OAAO,CAEjE;IAEY,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAehD;IAED,gFAAgF;IAChF,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAOtD;CACF"}
@@ -17,9 +17,12 @@ const log_1 = require("@spinajs/log");
17
17
  const di_1 = require("@spinajs/di");
18
18
  /**
19
19
  * Shared-token guard for the telemetry endpoints. Reads the expected token from
20
- * `telemetry.auth.token` and compares it against the `x-metrics-token` header.
21
- * The header name is deliberately unchanged from the retired
22
- * `@spinajs/metrics` package so existing scrape configs keep working.
20
+ * `telemetry.auth.token` and compares it against the `x-metrics-token` header,
21
+ * or equivalently against `Authorization: Bearer <token>`. The custom
22
+ * header name is deliberately unchanged from the retired `@spinajs/metrics`
23
+ * package so existing scrape configs keep working; the Bearer form exists
24
+ * because stock Prometheus / OTel-collector scrape configs can only send
25
+ * `authorization.credentials` (a Bearer header), not arbitrary headers.
23
26
  *
24
27
  * Bypassed entirely in development.
25
28
  */
@@ -35,9 +38,9 @@ let TelemetryTokenPolicy = class TelemetryTokenPolicy extends http_1.BasePolicy
35
38
  if (this.isDev) {
36
39
  return;
37
40
  }
38
- const token = req.headers[this.HEADER_TOKEN_FIELD];
41
+ const token = req.headers[this.HEADER_TOKEN_FIELD] ?? this.bearerToken(req);
39
42
  if (!token) {
40
- this.Log.warn(`No token is set for restricted area, header field: ${this.HEADER_TOKEN_FIELD}, policy: TelemetryTokenPolicy, ip: ${req.storage.realIp}`);
43
+ this.Log.warn(`No token is set for restricted area, header field: ${this.HEADER_TOKEN_FIELD} (or Authorization: Bearer), policy: TelemetryTokenPolicy, ip: ${req.storage.realIp}`);
41
44
  throw new exceptions_1.Forbidden('access token is not set');
42
45
  }
43
46
  if (token !== this.Token) {
@@ -45,6 +48,15 @@ let TelemetryTokenPolicy = class TelemetryTokenPolicy extends http_1.BasePolicy
45
48
  throw new exceptions_1.Forbidden('invalid access token');
46
49
  }
47
50
  }
51
+ /** The credentials of an `Authorization: Bearer <token>` header, if present. */
52
+ bearerToken(req) {
53
+ const auth = req.headers.authorization;
54
+ if (typeof auth !== 'string' || !auth.startsWith('Bearer ')) {
55
+ return undefined;
56
+ }
57
+ const token = auth.slice('Bearer '.length).trim();
58
+ return token.length > 0 ? token : undefined;
59
+ }
48
60
  };
49
61
  exports.TelemetryTokenPolicy = TelemetryTokenPolicy;
50
62
  __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"TelemetryTokenPolicy.js","sourceRoot":"","sources":["../../../src/policies/TelemetryTokenPolicy.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,0DAAgD;AAChD,wCAAyE;AACzE,oDAAgD;AAChD,sCAA2C;AAC3C,oCAAyC;AAEzC;;;;;;;GAOG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,iBAAU;IAA7C;;QAUK,uBAAkB,GAAG,iBAAiB,CAAC;IAsBnD,CAAC;IApBQ,SAAS,CAAC,OAAe,EAAE,SAAsB;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,GAAY;QAC/B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACnD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,sDAAsD,IAAI,CAAC,kBAAkB,uCAAuC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YACxJ,MAAM,IAAI,sBAAS,CAAC,yBAAyB,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gDAAgD,IAAI,CAAC,kBAAkB,uCAAuC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAClJ,MAAM,IAAI,sBAAS,CAAC,sBAAsB,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;CACF,CAAA;;AA9BW;IADT,IAAA,YAAM,EAAC,UAAU,CAAC;8BACJ,SAAG;iDAAC;AAGT;IADT,IAAA,sBAAM,EAAC,sBAAsB,CAAC;;mDACP;AAGd;IADT,IAAA,sBAAM,EAAC,6BAA6B,CAAC;;mDACb;+BARd,oBAAoB;IADhC,IAAA,eAAU,EAAC,iBAAU,CAAC;GACV,oBAAoB,CAgChC"}
1
+ {"version":3,"file":"TelemetryTokenPolicy.js","sourceRoot":"","sources":["../../../src/policies/TelemetryTokenPolicy.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,0DAAgD;AAChD,wCAAyE;AACzE,oDAAgD;AAChD,sCAA2C;AAC3C,oCAAyC;AAEzC;;;;;;;;;;GAUG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,iBAAU;IAA7C;;QAUK,uBAAkB,GAAG,iBAAiB,CAAC;IAgCnD,CAAC;IA9BQ,SAAS,CAAC,OAAe,EAAE,SAAsB;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,GAAY;QAC/B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAC5E,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,sDAAsD,IAAI,CAAC,kBAAkB,kEAAkE,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YACnL,MAAM,IAAI,sBAAS,CAAC,yBAAyB,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gDAAgD,IAAI,CAAC,kBAAkB,uCAAuC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAClJ,MAAM,IAAI,sBAAS,CAAC,sBAAsB,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,gFAAgF;IACtE,WAAW,CAAC,GAAY;QAChC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC;QACvC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5D,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9C,CAAC;CACF,CAAA;;AAxCW;IADT,IAAA,YAAM,EAAC,UAAU,CAAC;8BACJ,SAAG;iDAAC;AAGT;IADT,IAAA,sBAAM,EAAC,sBAAsB,CAAC;;mDACP;AAGd;IADT,IAAA,sBAAM,EAAC,6BAA6B,CAAC;;mDACb;+BARd,oBAAoB;IADhC,IAAA,eAAU,EAAC,iBAAU,CAAC;GACV,oBAAoB,CA0ChC"}
@@ -2,9 +2,12 @@ import { BasePolicy, IController, IRoute, Request } from '@spinajs/http';
2
2
  import { Log } from '@spinajs/log';
3
3
  /**
4
4
  * Shared-token guard for the telemetry endpoints. Reads the expected token from
5
- * `telemetry.auth.token` and compares it against the `x-metrics-token` header.
6
- * The header name is deliberately unchanged from the retired
7
- * `@spinajs/metrics` package so existing scrape configs keep working.
5
+ * `telemetry.auth.token` and compares it against the `x-metrics-token` header,
6
+ * or equivalently against `Authorization: Bearer <token>`. The custom
7
+ * header name is deliberately unchanged from the retired `@spinajs/metrics`
8
+ * package so existing scrape configs keep working; the Bearer form exists
9
+ * because stock Prometheus / OTel-collector scrape configs can only send
10
+ * `authorization.credentials` (a Bearer header), not arbitrary headers.
8
11
  *
9
12
  * Bypassed entirely in development.
10
13
  */
@@ -15,5 +18,7 @@ export declare class TelemetryTokenPolicy extends BasePolicy {
15
18
  protected HEADER_TOKEN_FIELD: string;
16
19
  isEnabled(_action: IRoute, _instance: IController): boolean;
17
20
  execute(req: Request): Promise<void>;
21
+ /** The credentials of an `Authorization: Bearer <token>` header, if present. */
22
+ protected bearerToken(req: Request): string | undefined;
18
23
  }
19
24
  //# sourceMappingURL=TelemetryTokenPolicy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TelemetryTokenPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/TelemetryTokenPolicy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAE,GAAG,EAAU,MAAM,cAAc,CAAC;AAG3C;;;;;;;GAOG;AACH,qBACa,oBAAqB,SAAQ,UAAU;IAElD,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAGnB,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC;IAGxB,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC;IAEzB,SAAS,CAAC,kBAAkB,SAAqB;IAE1C,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,GAAG,OAAO,CAEjE;IAEY,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAehD;CACF"}
1
+ {"version":3,"file":"TelemetryTokenPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/TelemetryTokenPolicy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAE,GAAG,EAAU,MAAM,cAAc,CAAC;AAG3C;;;;;;;;;;GAUG;AACH,qBACa,oBAAqB,SAAQ,UAAU;IAElD,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAGnB,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC;IAGxB,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC;IAEzB,SAAS,CAAC,kBAAkB,SAAqB;IAE1C,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,GAAG,OAAO,CAEjE;IAEY,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAehD;IAED,gFAAgF;IAChF,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAOtD;CACF"}
@@ -14,9 +14,12 @@ import { Log, Logger } from '@spinajs/log';
14
14
  import { Injectable } from '@spinajs/di';
15
15
  /**
16
16
  * Shared-token guard for the telemetry endpoints. Reads the expected token from
17
- * `telemetry.auth.token` and compares it against the `x-metrics-token` header.
18
- * The header name is deliberately unchanged from the retired
19
- * `@spinajs/metrics` package so existing scrape configs keep working.
17
+ * `telemetry.auth.token` and compares it against the `x-metrics-token` header,
18
+ * or equivalently against `Authorization: Bearer <token>`. The custom
19
+ * header name is deliberately unchanged from the retired `@spinajs/metrics`
20
+ * package so existing scrape configs keep working; the Bearer form exists
21
+ * because stock Prometheus / OTel-collector scrape configs can only send
22
+ * `authorization.credentials` (a Bearer header), not arbitrary headers.
20
23
  *
21
24
  * Bypassed entirely in development.
22
25
  */
@@ -32,9 +35,9 @@ let TelemetryTokenPolicy = class TelemetryTokenPolicy extends BasePolicy {
32
35
  if (this.isDev) {
33
36
  return;
34
37
  }
35
- const token = req.headers[this.HEADER_TOKEN_FIELD];
38
+ const token = req.headers[this.HEADER_TOKEN_FIELD] ?? this.bearerToken(req);
36
39
  if (!token) {
37
- this.Log.warn(`No token is set for restricted area, header field: ${this.HEADER_TOKEN_FIELD}, policy: TelemetryTokenPolicy, ip: ${req.storage.realIp}`);
40
+ this.Log.warn(`No token is set for restricted area, header field: ${this.HEADER_TOKEN_FIELD} (or Authorization: Bearer), policy: TelemetryTokenPolicy, ip: ${req.storage.realIp}`);
38
41
  throw new Forbidden('access token is not set');
39
42
  }
40
43
  if (token !== this.Token) {
@@ -42,6 +45,15 @@ let TelemetryTokenPolicy = class TelemetryTokenPolicy extends BasePolicy {
42
45
  throw new Forbidden('invalid access token');
43
46
  }
44
47
  }
48
+ /** The credentials of an `Authorization: Bearer <token>` header, if present. */
49
+ bearerToken(req) {
50
+ const auth = req.headers.authorization;
51
+ if (typeof auth !== 'string' || !auth.startsWith('Bearer ')) {
52
+ return undefined;
53
+ }
54
+ const token = auth.slice('Bearer '.length).trim();
55
+ return token.length > 0 ? token : undefined;
56
+ }
45
57
  };
46
58
  __decorate([
47
59
  Logger('Security'),
@@ -1 +1 @@
1
- {"version":3,"file":"TelemetryTokenPolicy.js","sourceRoot":"","sources":["../../../src/policies/TelemetryTokenPolicy.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAgC,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;;;GAOG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,UAAU;IAA7C;;QAUK,uBAAkB,GAAG,iBAAiB,CAAC;IAsBnD,CAAC;IApBQ,SAAS,CAAC,OAAe,EAAE,SAAsB;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,GAAY;QAC/B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACnD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,sDAAsD,IAAI,CAAC,kBAAkB,uCAAuC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YACxJ,MAAM,IAAI,SAAS,CAAC,yBAAyB,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gDAAgD,IAAI,CAAC,kBAAkB,uCAAuC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAClJ,MAAM,IAAI,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;CACF,CAAA;AA9BW;IADT,MAAM,CAAC,UAAU,CAAC;8BACJ,GAAG;iDAAC;AAGT;IADT,MAAM,CAAC,sBAAsB,CAAC;;mDACP;AAGd;IADT,MAAM,CAAC,6BAA6B,CAAC;;mDACb;AARd,oBAAoB;IADhC,UAAU,CAAC,UAAU,CAAC;GACV,oBAAoB,CAgChC"}
1
+ {"version":3,"file":"TelemetryTokenPolicy.js","sourceRoot":"","sources":["../../../src/policies/TelemetryTokenPolicy.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAgC,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;;;;;;GAUG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,UAAU;IAA7C;;QAUK,uBAAkB,GAAG,iBAAiB,CAAC;IAgCnD,CAAC;IA9BQ,SAAS,CAAC,OAAe,EAAE,SAAsB;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,GAAY;QAC/B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAC5E,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,sDAAsD,IAAI,CAAC,kBAAkB,kEAAkE,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YACnL,MAAM,IAAI,SAAS,CAAC,yBAAyB,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gDAAgD,IAAI,CAAC,kBAAkB,uCAAuC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAClJ,MAAM,IAAI,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,gFAAgF;IACtE,WAAW,CAAC,GAAY;QAChC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC;QACvC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5D,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9C,CAAC;CACF,CAAA;AAxCW;IADT,MAAM,CAAC,UAAU,CAAC;8BACJ,GAAG;iDAAC;AAGT;IADT,MAAM,CAAC,sBAAsB,CAAC;;mDACP;AAGd;IADT,MAAM,CAAC,6BAA6B,CAAC;;mDACb;AARd,oBAAoB;IADhC,UAAU,CAAC,UAAU,CAAC;GACV,oBAAoB,CA0ChC"}