nextlove 2.3.0 → 2.4.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/dist/index.d.ts CHANGED
@@ -1,20 +1,30 @@
1
1
  export { BadRequestException, ExceptionHandlingOptions, HttpException, HttpExceptionMetadata, InternalServerErrorException, MethodNotAllowedException, NotFoundException, ThrowingOptions, UnauthorizedException, withExceptionHandling } from './nextjs-exception-middleware/index.js';
2
- import { Middleware as Middleware$2 } from 'nextjs-middleware-wrappers';
3
2
  import { NextApiRequest, NextApiResponse } from 'next';
4
3
  import { z } from 'zod';
5
4
  import { SecuritySchemeObject, SecurityRequirementObject } from 'openapi3-ts/oas31';
6
5
 
7
- declare type HTTPMethods = "GET" | "POST" | "DELETE" | "PUT" | "PATCH" | "HEAD" | "OPTIONS";
6
+ type Middleware$1<T, Dep = {}> = (next: (req: NextApiRequest & Dep & T, res: NextApiResponse) => any) => (req: NextApiRequest & Dep & T, res: NextApiResponse) => any;
7
+ type Wrappers1 = <Mw1RequestContext, Mw1Dep>(mw1: Middleware$1<Mw1RequestContext, Mw1Dep>, endpoint: (req: NextApiRequest & Mw1RequestContext, res: NextApiResponse) => any) => (req: NextApiRequest, res: NextApiResponse) => any;
8
+ type Wrappers2 = <Mw1RequestContext extends Mw2Dep, Mw1Dep, Mw2RequestContext, Mw2Dep>(mw1: Middleware$1<Mw1RequestContext, Mw1Dep>, mw2: Middleware$1<Mw2RequestContext, Mw2Dep>, endpoint: (req: NextApiRequest & Mw1RequestContext & Mw2RequestContext, res: NextApiResponse) => any) => (req: NextApiRequest, res: NextApiResponse) => any;
9
+ type Wrappers3 = <Mw1RequestContext extends Mw2Dep, Mw1Dep, Mw2RequestContext, Mw2Dep, Mw3RequestContext, Mw3Dep>(mw1: Middleware$1<Mw1RequestContext, Mw1Dep>, mw2: Middleware$1<Mw2RequestContext, Mw2Dep>, mw3: Middleware$1<Mw3RequestContext, Mw1RequestContext & Mw2RequestContext extends Mw3Dep ? Mw3Dep : never>, endpoint: (req: NextApiRequest & Mw1RequestContext & Mw2RequestContext & Mw3RequestContext, res: NextApiResponse) => any) => (req: NextApiRequest, res: NextApiResponse) => any;
10
+ type Wrappers4 = <Mw1RequestContext extends Mw2Dep, Mw1Dep, Mw2RequestContext, Mw2Dep, Mw3RequestContext, Mw3Dep, Mw4RequestContext, Mw4Dep>(mw1: Middleware$1<Mw1RequestContext, Mw1Dep>, mw2: Middleware$1<Mw2RequestContext, Mw2Dep>, mw3: Middleware$1<Mw3RequestContext, Mw1RequestContext & Mw2RequestContext extends Mw3Dep ? Mw3Dep : never>, mw4: Middleware$1<Mw4RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext extends Mw4Dep ? Mw4Dep : never>, endpoint: (req: NextApiRequest & Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext, res: NextApiResponse) => any) => (req: NextApiRequest, res: NextApiResponse) => any;
11
+ type Wrappers5 = <Mw1RequestContext extends Mw2Dep, Mw1Dep, Mw2RequestContext, Mw2Dep, Mw3RequestContext, Mw3Dep, Mw4RequestContext, Mw4Dep, Mw5RequestContext, Mw5Dep>(mw1: Middleware$1<Mw1RequestContext, Mw1Dep>, mw2: Middleware$1<Mw2RequestContext, Mw2Dep>, mw3: Middleware$1<Mw3RequestContext, Mw1RequestContext & Mw2RequestContext extends Mw3Dep ? Mw3Dep : never>, mw4: Middleware$1<Mw4RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext extends Mw4Dep ? Mw4Dep : never>, mw5: Middleware$1<Mw5RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext extends Mw5Dep ? Mw5Dep : never>, endpoint: (req: NextApiRequest & Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext & Mw5RequestContext, res: NextApiResponse) => any) => (req: NextApiRequest, res: NextApiResponse) => any;
12
+ type Wrappers6 = <Mw1RequestContext extends Mw2Dep, Mw1Dep, Mw2RequestContext, Mw2Dep, Mw3RequestContext, Mw3Dep, Mw4RequestContext, Mw4Dep, Mw5RequestContext, Mw5Dep, Mw6RequestContext, Mw6Dep>(mw1: Middleware$1<Mw1RequestContext, Mw1Dep>, mw2: Middleware$1<Mw2RequestContext, Mw2Dep>, mw3: Middleware$1<Mw3RequestContext, Mw1RequestContext & Mw2RequestContext extends Mw3Dep ? Mw3Dep : never>, mw4: Middleware$1<Mw4RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext extends Mw4Dep ? Mw4Dep : never>, mw5: Middleware$1<Mw5RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext extends Mw5Dep ? Mw5Dep : never>, mw6: Middleware$1<Mw6RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext & Mw5RequestContext extends Mw6Dep ? Mw6Dep : never>, endpoint: (req: NextApiRequest & Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext & Mw5RequestContext & Mw6RequestContext, res: NextApiResponse) => any) => (req: NextApiRequest, res: NextApiResponse) => any;
13
+ type Wrappers7 = <Mw1RequestContext extends Mw2Dep, Mw1Dep, Mw2RequestContext, Mw2Dep, Mw3RequestContext, Mw3Dep, Mw4RequestContext, Mw4Dep, Mw5RequestContext, Mw5Dep, Mw6RequestContext, Mw6Dep, Mw7RequestContext, Mw7Dep>(mw1: Middleware$1<Mw1RequestContext, Mw1Dep>, mw2: Middleware$1<Mw2RequestContext, Mw2Dep>, mw3: Middleware$1<Mw3RequestContext, Mw1RequestContext & Mw2RequestContext extends Mw3Dep ? Mw3Dep : never>, mw4: Middleware$1<Mw4RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext extends Mw4Dep ? Mw4Dep : never>, mw5: Middleware$1<Mw5RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext extends Mw5Dep ? Mw5Dep : never>, mw6: Middleware$1<Mw6RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext & Mw5RequestContext extends Mw6Dep ? Mw6Dep : never>, mw7: Middleware$1<Mw7RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext & Mw5RequestContext & Mw6RequestContext extends Mw7Dep ? Mw7Dep : never>, endpoint: (req: NextApiRequest & Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext & Mw5RequestContext & Mw6RequestContext & Mw7RequestContext, res: NextApiResponse) => any) => (req: NextApiRequest, res: NextApiResponse) => any;
14
+ type Wrappers = Wrappers1 & Wrappers2 & Wrappers3 & Wrappers4 & Wrappers5 & Wrappers6 & Wrappers7;
15
+ declare const wrappers: Wrappers;
16
+
17
+ type HTTPMethods = "GET" | "POST" | "DELETE" | "PUT" | "PATCH" | "HEAD" | "OPTIONS";
8
18
 
9
- declare type Middleware$1<T, Dep = {}> = Middleware$2<T, Dep> & {
19
+ type Middleware<T, Dep = {}> = Middleware$1<T, Dep> & {
10
20
  /**
11
21
  * @deprecated moved to setupParams
12
22
  */
13
23
  securitySchema?: SecuritySchemeObject;
14
24
  securityObjects?: SecurityRequirementObject[];
15
25
  };
16
- declare type ParamDef$1 = z.ZodTypeAny | z.ZodEffects<z.ZodTypeAny>;
17
- interface RouteSpec<Auth extends string = string, Methods extends HTTPMethods[] = any, JsonBody extends ParamDef$1 = z.ZodObject<any, any, any, any, any>, QueryParams extends ParamDef$1 = z.ZodObject<any, any, any, any, any>, CommonParams extends ParamDef$1 = z.ZodObject<any, any, any, any, any>, Middlewares extends readonly Middleware$1<any, any>[] = any[], JsonResponse extends ParamDef$1 = z.ZodObject<any, any, any, any, any>, FormData extends ParamDef$1 = z.ZodTypeAny> {
26
+ type ParamDef$1 = z.ZodTypeAny | z.ZodEffects<z.ZodTypeAny>;
27
+ interface RouteSpec<Auth extends string = string, Methods extends HTTPMethods[] = any, JsonBody extends ParamDef$1 = z.ZodObject<any, any, any, any, any>, QueryParams extends ParamDef$1 = z.ZodObject<any, any, any, any, any>, CommonParams extends ParamDef$1 = z.ZodObject<any, any, any, any, any>, Middlewares extends readonly Middleware<any, any>[] = any[], JsonResponse extends ParamDef$1 = z.ZodObject<any, any, any, any, any>, FormData extends ParamDef$1 = z.ZodTypeAny> {
18
28
  methods: Methods;
19
29
  auth: Auth;
20
30
  jsonBody?: JsonBody;
@@ -24,11 +34,12 @@ interface RouteSpec<Auth extends string = string, Methods extends HTTPMethods[]
24
34
  jsonResponse?: JsonResponse;
25
35
  formData?: FormData;
26
36
  }
27
- declare type MiddlewareChainOutput<MWChain extends readonly Middleware$1<any, any>[]> = MWChain extends readonly [] ? {} : MWChain extends readonly [infer First, ...infer Rest] ? First extends Middleware$1<infer T, any> ? T & (Rest extends readonly Middleware$1<any, any>[] ? MiddlewareChainOutput<Rest> : never) : never : never;
28
- declare type AuthMiddlewares = {
29
- [auth_type: string]: Middleware$1<any, any>;
37
+ type MiddlewareChainOutput<MWChain extends readonly Middleware<any, any>[]> = MWChain extends readonly [] ? {} : MWChain extends readonly [infer First, ...infer Rest] ? First extends Middleware<infer T, any> ? T & (Rest extends readonly Middleware<any, any>[] ? MiddlewareChainOutput<Rest> : never) : never : never;
38
+ type AuthMiddlewares = {
39
+ [auth_type: string]: Middleware<any, any>;
30
40
  };
31
- interface SetupParams<AuthMW extends AuthMiddlewares = AuthMiddlewares, GlobalMW extends Middleware$1<any, any>[] = any[]> {
41
+ type QueryArrayFormat = "brackets" | "comma" | "repeat";
42
+ interface SetupParams<AuthMW extends AuthMiddlewares = AuthMiddlewares, GlobalMW extends Middleware<any, any>[] = any[]> {
32
43
  authMiddlewareMap: AuthMW;
33
44
  globalMiddlewares: GlobalMW;
34
45
  exceptionHandlingMiddleware?: ((next: Function) => Function) | null;
@@ -39,44 +50,35 @@ interface SetupParams<AuthMW extends AuthMiddlewares = AuthMiddlewares, GlobalMW
39
50
  shouldValidateGetRequestBody?: boolean;
40
51
  securitySchemas?: Record<string, SecuritySchemeObject>;
41
52
  globalSchemas?: Record<string, z.ZodTypeAny>;
53
+ supportedArrayFormats?: QueryArrayFormat[];
42
54
  }
43
55
  declare const defaultMiddlewareMap: {
44
56
  readonly none: (next: any) => any;
45
57
  };
46
- declare type Send<T> = (body: T) => void;
47
- declare type NextApiResponseWithoutJsonAndStatusMethods = Omit<NextApiResponse, "json" | "status">;
48
- declare type SuccessfulNextApiResponseMethods<T> = {
58
+ type Send<T> = (body: T) => void;
59
+ type NextApiResponseWithoutJsonAndStatusMethods = Omit<NextApiResponse, "json" | "status">;
60
+ type SuccessfulNextApiResponseMethods<T> = {
49
61
  status: (statusCode: 200 | 201) => NextApiResponseWithoutJsonAndStatusMethods & {
50
62
  json: Send<T>;
51
63
  };
52
64
  json: Send<T>;
53
65
  };
54
- declare type ErrorNextApiResponseMethods = {
66
+ type ErrorNextApiResponseMethods = {
55
67
  status: (statusCode: number) => NextApiResponseWithoutJsonAndStatusMethods & {
56
68
  json: Send<any>;
57
69
  };
58
70
  json: Send<any>;
59
71
  };
60
- declare type RouteFunction<SP extends SetupParams<AuthMiddlewares>, RS extends RouteSpec> = (req: (SP["authMiddlewareMap"] & typeof defaultMiddlewareMap)[RS["auth"]] extends Middleware$1<infer AuthMWOut, any> ? Omit<NextApiRequest, "query" | "body"> & AuthMWOut & MiddlewareChainOutput<RS["middlewares"] extends readonly Middleware$1<any, any>[] ? [...SP["globalMiddlewares"], ...RS["middlewares"]] : SP["globalMiddlewares"]> & {
72
+ type RouteFunction<SP extends SetupParams<AuthMiddlewares>, RS extends RouteSpec> = (req: (SP["authMiddlewareMap"] & typeof defaultMiddlewareMap)[RS["auth"]] extends Middleware<infer AuthMWOut, any> ? Omit<NextApiRequest, "query" | "body"> & AuthMWOut & MiddlewareChainOutput<RS["middlewares"] extends readonly Middleware<any, any>[] ? [...SP["globalMiddlewares"], ...RS["middlewares"]] : SP["globalMiddlewares"]> & {
61
73
  body: RS["formData"] extends z.ZodTypeAny ? z.infer<RS["formData"]> : RS["jsonBody"] extends z.ZodTypeAny ? z.infer<RS["jsonBody"]> : {};
62
74
  query: RS["queryParams"] extends z.ZodTypeAny ? z.infer<RS["queryParams"]> : {};
63
75
  commonParams: RS["commonParams"] extends z.ZodTypeAny ? z.infer<RS["commonParams"]> : {};
64
76
  } : `unknown auth type: ${RS["auth"]}. You should configure this auth type in your auth_middlewares w/ createWithRouteSpec, or maybe you need to add "as const" to your route spec definition.`, res: NextApiResponseWithoutJsonAndStatusMethods & SuccessfulNextApiResponseMethods<RS["jsonResponse"] extends z.ZodTypeAny ? z.infer<RS["jsonResponse"]> : any> & ErrorNextApiResponseMethods) => Promise<void>;
65
- declare type CreateWithRouteSpecFunction = <SP extends SetupParams<AuthMiddlewares, any>>(setupParams: SP) => <RS extends RouteSpec<string, any, any, any, any, any, z.ZodObject<any, any, any, any, any>, any>>(route_spec: RS) => (next: RouteFunction<SP, RS>) => any;
77
+ type CreateWithRouteSpecFunction = <SP extends SetupParams<AuthMiddlewares, any>>(setupParams: SP) => <RS extends RouteSpec<string, any, any, any, any, any, z.ZodObject<any, any, any, any, any>, any>>(route_spec: RS) => (next: RouteFunction<SP, RS>) => any;
66
78
 
67
- declare type ParamDef = z.ZodTypeAny | z.ZodEffects<z.ZodTypeAny>;
68
- declare const checkRouteSpec: <AuthType extends string = string, Methods extends HTTPMethods[] = HTTPMethods[], JsonBody extends ParamDef = z.ZodTypeAny, QueryParams extends ParamDef = z.ZodTypeAny, CommonParams extends ParamDef = z.ZodTypeAny, Middlewares extends readonly Middleware$2<any, any>[] = readonly Middleware$2<any, any>[], FormData_1 extends ParamDef = z.ZodTypeAny, Spec extends RouteSpec<AuthType, Methods, JsonBody, QueryParams, CommonParams, Middlewares, FormData_1, z.ZodTypeAny> = RouteSpec<AuthType, Methods, JsonBody, QueryParams, CommonParams, Middlewares, FormData_1, z.ZodTypeAny>>(spec: Spec) => string extends Spec["auth"] ? "your route spec is underspecified, add \"as const\"" : Spec;
79
+ type ParamDef = z.ZodTypeAny | z.ZodEffects<z.ZodTypeAny>;
80
+ declare const checkRouteSpec: <AuthType extends string = string, Methods extends HTTPMethods[] = HTTPMethods[], JsonBody extends ParamDef = z.ZodTypeAny, QueryParams extends ParamDef = z.ZodTypeAny, CommonParams extends ParamDef = z.ZodTypeAny, Middlewares extends readonly Middleware$1<any, any>[] = readonly Middleware$1<any, any>[], FormData_1 extends ParamDef = z.ZodTypeAny, Spec extends RouteSpec<AuthType, Methods, JsonBody, QueryParams, CommonParams, Middlewares, FormData_1, z.ZodTypeAny> = RouteSpec<AuthType, Methods, JsonBody, QueryParams, CommonParams, Middlewares, FormData_1, z.ZodTypeAny>>(spec: Spec) => string extends Spec["auth"] ? "your route spec is underspecified, add \"as const\"" : Spec;
81
+ declare const DEFAULT_ARRAY_FORMATS: QueryArrayFormat[];
69
82
  declare const createWithRouteSpec: CreateWithRouteSpecFunction;
70
83
 
71
- declare type Middleware<T, Dep = {}> = (next: (req: NextApiRequest & Dep & T, res: NextApiResponse) => any) => (req: NextApiRequest & Dep & T, res: NextApiResponse) => any;
72
- declare type Wrappers1 = <Mw1RequestContext, Mw1Dep>(mw1: Middleware<Mw1RequestContext, Mw1Dep>, endpoint: (req: NextApiRequest & Mw1RequestContext, res: NextApiResponse) => any) => (req: NextApiRequest, res: NextApiResponse) => any;
73
- declare type Wrappers2 = <Mw1RequestContext extends Mw2Dep, Mw1Dep, Mw2RequestContext, Mw2Dep>(mw1: Middleware<Mw1RequestContext, Mw1Dep>, mw2: Middleware<Mw2RequestContext, Mw2Dep>, endpoint: (req: NextApiRequest & Mw1RequestContext & Mw2RequestContext, res: NextApiResponse) => any) => (req: NextApiRequest, res: NextApiResponse) => any;
74
- declare type Wrappers3 = <Mw1RequestContext extends Mw2Dep, Mw1Dep, Mw2RequestContext, Mw2Dep, Mw3RequestContext, Mw3Dep>(mw1: Middleware<Mw1RequestContext, Mw1Dep>, mw2: Middleware<Mw2RequestContext, Mw2Dep>, mw3: Middleware<Mw3RequestContext, Mw1RequestContext & Mw2RequestContext extends Mw3Dep ? Mw3Dep : never>, endpoint: (req: NextApiRequest & Mw1RequestContext & Mw2RequestContext & Mw3RequestContext, res: NextApiResponse) => any) => (req: NextApiRequest, res: NextApiResponse) => any;
75
- declare type Wrappers4 = <Mw1RequestContext extends Mw2Dep, Mw1Dep, Mw2RequestContext, Mw2Dep, Mw3RequestContext, Mw3Dep, Mw4RequestContext, Mw4Dep>(mw1: Middleware<Mw1RequestContext, Mw1Dep>, mw2: Middleware<Mw2RequestContext, Mw2Dep>, mw3: Middleware<Mw3RequestContext, Mw1RequestContext & Mw2RequestContext extends Mw3Dep ? Mw3Dep : never>, mw4: Middleware<Mw4RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext extends Mw4Dep ? Mw4Dep : never>, endpoint: (req: NextApiRequest & Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext, res: NextApiResponse) => any) => (req: NextApiRequest, res: NextApiResponse) => any;
76
- declare type Wrappers5 = <Mw1RequestContext extends Mw2Dep, Mw1Dep, Mw2RequestContext, Mw2Dep, Mw3RequestContext, Mw3Dep, Mw4RequestContext, Mw4Dep, Mw5RequestContext, Mw5Dep>(mw1: Middleware<Mw1RequestContext, Mw1Dep>, mw2: Middleware<Mw2RequestContext, Mw2Dep>, mw3: Middleware<Mw3RequestContext, Mw1RequestContext & Mw2RequestContext extends Mw3Dep ? Mw3Dep : never>, mw4: Middleware<Mw4RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext extends Mw4Dep ? Mw4Dep : never>, mw5: Middleware<Mw5RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext extends Mw5Dep ? Mw5Dep : never>, endpoint: (req: NextApiRequest & Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext & Mw5RequestContext, res: NextApiResponse) => any) => (req: NextApiRequest, res: NextApiResponse) => any;
77
- declare type Wrappers6 = <Mw1RequestContext extends Mw2Dep, Mw1Dep, Mw2RequestContext, Mw2Dep, Mw3RequestContext, Mw3Dep, Mw4RequestContext, Mw4Dep, Mw5RequestContext, Mw5Dep, Mw6RequestContext, Mw6Dep>(mw1: Middleware<Mw1RequestContext, Mw1Dep>, mw2: Middleware<Mw2RequestContext, Mw2Dep>, mw3: Middleware<Mw3RequestContext, Mw1RequestContext & Mw2RequestContext extends Mw3Dep ? Mw3Dep : never>, mw4: Middleware<Mw4RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext extends Mw4Dep ? Mw4Dep : never>, mw5: Middleware<Mw5RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext extends Mw5Dep ? Mw5Dep : never>, mw6: Middleware<Mw6RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext & Mw5RequestContext extends Mw6Dep ? Mw6Dep : never>, endpoint: (req: NextApiRequest & Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext & Mw5RequestContext & Mw6RequestContext, res: NextApiResponse) => any) => (req: NextApiRequest, res: NextApiResponse) => any;
78
- declare type Wrappers7 = <Mw1RequestContext extends Mw2Dep, Mw1Dep, Mw2RequestContext, Mw2Dep, Mw3RequestContext, Mw3Dep, Mw4RequestContext, Mw4Dep, Mw5RequestContext, Mw5Dep, Mw6RequestContext, Mw6Dep, Mw7RequestContext, Mw7Dep>(mw1: Middleware<Mw1RequestContext, Mw1Dep>, mw2: Middleware<Mw2RequestContext, Mw2Dep>, mw3: Middleware<Mw3RequestContext, Mw1RequestContext & Mw2RequestContext extends Mw3Dep ? Mw3Dep : never>, mw4: Middleware<Mw4RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext extends Mw4Dep ? Mw4Dep : never>, mw5: Middleware<Mw5RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext extends Mw5Dep ? Mw5Dep : never>, mw6: Middleware<Mw6RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext & Mw5RequestContext extends Mw6Dep ? Mw6Dep : never>, mw7: Middleware<Mw7RequestContext, Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext & Mw5RequestContext & Mw6RequestContext extends Mw7Dep ? Mw7Dep : never>, endpoint: (req: NextApiRequest & Mw1RequestContext & Mw2RequestContext & Mw3RequestContext & Mw4RequestContext & Mw5RequestContext & Mw6RequestContext & Mw7RequestContext, res: NextApiResponse) => any) => (req: NextApiRequest, res: NextApiResponse) => any;
79
- declare type Wrappers = Wrappers1 & Wrappers2 & Wrappers3 & Wrappers4 & Wrappers5 & Wrappers6 & Wrappers7;
80
- declare const wrappers: Wrappers;
81
-
82
- export { AuthMiddlewares, CreateWithRouteSpecFunction, Middleware$1 as Middleware, MiddlewareChainOutput, RouteFunction, RouteSpec, SetupParams, checkRouteSpec, createWithRouteSpec, wrappers };
84
+ export { AuthMiddlewares, CreateWithRouteSpecFunction, DEFAULT_ARRAY_FORMATS, Middleware, MiddlewareChainOutput, QueryArrayFormat, RouteFunction, RouteSpec, SetupParams, checkRouteSpec, createWithRouteSpec, wrappers };
package/dist/index.js CHANGED
@@ -27,6 +27,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
27
27
  var src_exports = {};
28
28
  __export(src_exports, {
29
29
  BadRequestException: () => BadRequestException,
30
+ DEFAULT_ARRAY_FORMATS: () => DEFAULT_ARRAY_FORMATS,
30
31
  HttpException: () => HttpException,
31
32
  InternalServerErrorException: () => InternalServerErrorException,
32
33
  MethodNotAllowedException: () => MethodNotAllowedException,
@@ -35,7 +36,7 @@ __export(src_exports, {
35
36
  checkRouteSpec: () => checkRouteSpec,
36
37
  createWithRouteSpec: () => createWithRouteSpec,
37
38
  withExceptionHandling: () => withExceptionHandling2,
38
- wrappers: () => wrappers2
39
+ wrappers: () => wrappers
39
40
  });
40
41
  module.exports = __toCommonJS(src_exports);
41
42
 
@@ -161,8 +162,17 @@ var withExceptionHandling2 = ({
161
162
  );
162
163
  };
163
164
 
164
- // src/with-route-spec/index.ts
165
- var import_nextjs_middleware_wrappers = __toESM(require("nextjs-middleware-wrappers"));
165
+ // src/wrappers/index.ts
166
+ var wrappers = (...wrappersArgs) => {
167
+ const wrappedFunction = wrappersArgs[wrappersArgs.length - 1];
168
+ const mws = wrappersArgs.slice(0, -1);
169
+ let lastWrappedFunction = wrappedFunction;
170
+ for (let i = mws.length - 1; i >= 0; i--) {
171
+ lastWrappedFunction = mws[i](lastWrappedFunction);
172
+ }
173
+ return lastWrappedFunction;
174
+ };
175
+ var wrappers_default = wrappers;
166
176
 
167
177
  // src/with-route-spec/middlewares/with-methods.ts
168
178
  var withMethods = (methods) => (next) => (req, res) => {
@@ -178,7 +188,7 @@ var with_methods_default = withMethods;
178
188
 
179
189
  // src/with-route-spec/middlewares/with-validation.ts
180
190
  var import_zod = require("zod");
181
- var import_lodash = require("lodash");
191
+ var import_lodash = __toESM(require("lodash"));
182
192
  var getZodObjectSchemaFromZodEffectSchema = (isZodEffect, schema) => {
183
193
  if (!isZodEffect) {
184
194
  return schema;
@@ -207,33 +217,44 @@ var getZodDefFromZodSchemaHelpers = (schema) => {
207
217
  }
208
218
  return schema._def;
209
219
  };
210
- var parseQueryParams = (schema, input) => {
211
- const parsed_input = Object.assign({}, input);
220
+ var tryGetZodSchemaAsObject = (schema) => {
212
221
  const isZodEffect = schema._def.typeName === import_zod.ZodFirstPartyTypeKind.ZodEffects;
213
222
  const safe_schema = getZodObjectSchemaFromZodEffectSchema(isZodEffect, schema);
214
223
  const isZodObject = safe_schema._def.typeName === import_zod.ZodFirstPartyTypeKind.ZodObject;
215
- if (isZodObject) {
216
- const obj_schema = safe_schema;
224
+ if (!isZodObject) {
225
+ return void 0;
226
+ }
227
+ return safe_schema;
228
+ };
229
+ var isZodSchemaArray = (schema) => {
230
+ const def = getZodDefFromZodSchemaHelpers(schema);
231
+ return def.typeName === import_zod.ZodFirstPartyTypeKind.ZodArray;
232
+ };
233
+ var isZodSchemaBoolean = (schema) => {
234
+ const def = getZodDefFromZodSchemaHelpers(schema);
235
+ return def.typeName === import_zod.ZodFirstPartyTypeKind.ZodBoolean;
236
+ };
237
+ var parseQueryParams = (schema, input, supportedArrayFormats) => {
238
+ const parsed_input = Object.assign({}, input);
239
+ const obj_schema = tryGetZodSchemaAsObject(schema);
240
+ if (obj_schema) {
217
241
  for (const [key, value] of Object.entries(obj_schema.shape)) {
218
- const def = getZodDefFromZodSchemaHelpers(value);
219
- const isArray = def.typeName === import_zod.ZodFirstPartyTypeKind.ZodArray;
220
- if (isArray) {
242
+ if (isZodSchemaArray(value)) {
221
243
  const array_input = input[key];
222
- if (typeof array_input === "string") {
244
+ if (typeof array_input === "string" && supportedArrayFormats.includes("comma")) {
223
245
  parsed_input[key] = array_input.split(",");
224
246
  }
225
247
  const bracket_syntax_array_input = input[`${key}[]`];
226
- if (typeof bracket_syntax_array_input === "string") {
248
+ if (typeof bracket_syntax_array_input === "string" && supportedArrayFormats.includes("brackets")) {
227
249
  const pre_split_array = bracket_syntax_array_input;
228
250
  parsed_input[key] = pre_split_array.split(",");
229
251
  }
230
- if (Array.isArray(bracket_syntax_array_input)) {
252
+ if (Array.isArray(bracket_syntax_array_input) && supportedArrayFormats.includes("brackets")) {
231
253
  parsed_input[key] = bracket_syntax_array_input;
232
254
  }
233
255
  continue;
234
256
  }
235
- const isBoolean = def.typeName === import_zod.ZodFirstPartyTypeKind.ZodBoolean;
236
- if (isBoolean) {
257
+ if (isZodSchemaBoolean(value)) {
237
258
  const boolean_input = input[key];
238
259
  if (typeof boolean_input === "string") {
239
260
  parsed_input[key] = boolean_input === "true";
@@ -243,6 +264,38 @@ var parseQueryParams = (schema, input) => {
243
264
  }
244
265
  return schema.parse(parsed_input);
245
266
  };
267
+ var validateQueryParams = (inputUrl, schema, supportedArrayFormats) => {
268
+ const url = new URL(inputUrl, "http://dummy.com");
269
+ const seenKeys = /* @__PURE__ */ new Set();
270
+ const obj_schema = tryGetZodSchemaAsObject(schema);
271
+ if (!obj_schema) {
272
+ return;
273
+ }
274
+ for (const key of url.searchParams.keys()) {
275
+ for (const [schemaKey, value] of Object.entries(obj_schema.shape)) {
276
+ if (isZodSchemaArray(value)) {
277
+ if (key === `${schemaKey}[]` && !supportedArrayFormats.includes("brackets")) {
278
+ throw new BadRequestException({
279
+ type: "invalid_query_params",
280
+ message: `Bracket syntax not supported for query param "${schemaKey}"`
281
+ });
282
+ }
283
+ }
284
+ }
285
+ const key_schema = obj_schema.shape[key];
286
+ if (key_schema) {
287
+ if (isZodSchemaArray(key_schema)) {
288
+ if (seenKeys.has(key) && !supportedArrayFormats.includes("repeat")) {
289
+ throw new BadRequestException({
290
+ type: "invalid_query_params",
291
+ message: `Repeated parameters not supported for duplicate query param "${key}"`
292
+ });
293
+ }
294
+ }
295
+ }
296
+ seenKeys.add(key);
297
+ }
298
+ };
246
299
  var zodIssueToString = (issue) => {
247
300
  if (issue.path.join(".") === "") {
248
301
  return issue.message;
@@ -274,10 +327,11 @@ function validateJsonResponse(jsonResponse, res) {
274
327
  }
275
328
  var withValidation = (input) => (next) => async (req, res) => {
276
329
  var _a, _b, _c, _d;
330
+ const { supportedArrayFormats = DEFAULT_ARRAY_FORMATS } = input;
277
331
  if (input.formData && input.jsonBody || input.formData && input.commonParams) {
278
332
  throw new Error("Cannot use formData with jsonBody or commonParams");
279
333
  }
280
- if ((req.method === "POST" || req.method === "PATCH") && (input.jsonBody || input.commonParams) && !((_a = req.headers["content-type"]) == null ? void 0 : _a.includes("application/json")) && !(0, import_lodash.isEmpty)(req.body)) {
334
+ if ((req.method === "POST" || req.method === "PATCH") && (input.jsonBody || input.commonParams) && !((_a = req.headers["content-type"]) == null ? void 0 : _a.includes("application/json")) && !import_lodash.default.isEmpty(req.body)) {
281
335
  throw new BadRequestException({
282
336
  type: "invalid_content_type",
283
337
  message: `${req.method} requests must have Content-Type header with "application/json"`
@@ -302,16 +356,28 @@ var withValidation = (input) => (next) => async (req, res) => {
302
356
  req.body = (_d = input.jsonBody) == null ? void 0 : _d.parse(req.body);
303
357
  }
304
358
  if (input.queryParams) {
305
- req.query = parseQueryParams(input.queryParams, req.query);
359
+ if (!req.url) {
360
+ throw new Error("req.url is undefined");
361
+ }
362
+ validateQueryParams(req.url, input.queryParams, supportedArrayFormats);
363
+ req.query = parseQueryParams(
364
+ input.queryParams,
365
+ req.query,
366
+ supportedArrayFormats
367
+ );
306
368
  }
307
369
  if (input.commonParams) {
308
370
  ;
309
371
  req.commonParams = parseQueryParams(
310
372
  input.commonParams,
311
- original_combined_params
373
+ original_combined_params,
374
+ supportedArrayFormats
312
375
  );
313
376
  }
314
377
  } catch (error) {
378
+ if (error instanceof BadRequestException) {
379
+ throw error;
380
+ }
315
381
  if (error.name === "ZodError") {
316
382
  let message;
317
383
  if (error.issues.length === 1) {
@@ -345,6 +411,11 @@ var with_validation_default = withValidation;
345
411
  // src/with-route-spec/index.ts
346
412
  var import_zod2 = require("zod");
347
413
  var checkRouteSpec = (spec) => spec;
414
+ var DEFAULT_ARRAY_FORMATS = [
415
+ "brackets",
416
+ "comma",
417
+ "repeat"
418
+ ];
348
419
  var createWithRouteSpec = (setupParams) => {
349
420
  const {
350
421
  authMiddlewareMap = {},
@@ -364,7 +435,8 @@ var createWithRouteSpec = (setupParams) => {
364
435
  }),
365
436
  globalSchemas = setupParams.addOkStatus ? {
366
437
  ok: import_zod2.z.boolean()
367
- } : {}
438
+ } : {},
439
+ supportedArrayFormats = DEFAULT_ARRAY_FORMATS
368
440
  } = setupParams;
369
441
  const withRouteSpec = (spec) => {
370
442
  const createRouteExport = (userDefinedRouteFn) => {
@@ -373,7 +445,7 @@ var createWithRouteSpec = (setupParams) => {
373
445
  const auth_middleware = authMiddlewareMap[spec.auth];
374
446
  if (!auth_middleware)
375
447
  throw new Error(`Unknown auth type: ${spec.auth}`);
376
- return (0, import_nextjs_middleware_wrappers.default)(
448
+ return wrappers_default(
377
449
  ...exceptionHandlingMiddleware ? [exceptionHandlingMiddleware] : [],
378
450
  ...globalMiddlewares || [],
379
451
  auth_middleware,
@@ -386,7 +458,8 @@ var createWithRouteSpec = (setupParams) => {
386
458
  formData: spec.formData,
387
459
  jsonResponse: spec.jsonResponse,
388
460
  shouldValidateResponses,
389
- shouldValidateGetRequestBody
461
+ shouldValidateGetRequestBody,
462
+ supportedArrayFormats
390
463
  }),
391
464
  userDefinedRouteFn
392
465
  )(req, res);
@@ -402,20 +475,10 @@ var createWithRouteSpec = (setupParams) => {
402
475
  withRouteSpec._setupParams = setupParams;
403
476
  return withRouteSpec;
404
477
  };
405
-
406
- // src/wrappers/index.ts
407
- var wrappers2 = (...wrappersArgs) => {
408
- const wrappedFunction = wrappersArgs[wrappersArgs.length - 1];
409
- const mws = wrappersArgs.slice(0, -1);
410
- let lastWrappedFunction = wrappedFunction;
411
- for (let i = mws.length - 1; i >= 0; i--) {
412
- lastWrappedFunction = mws[i](lastWrappedFunction);
413
- }
414
- return lastWrappedFunction;
415
- };
416
478
  // Annotate the CommonJS export names for ESM import in node:
417
479
  0 && (module.exports = {
418
480
  BadRequestException,
481
+ DEFAULT_ARRAY_FORMATS,
419
482
  HttpException,
420
483
  InternalServerErrorException,
421
484
  MethodNotAllowedException,
@@ -426,4 +489,4 @@ var wrappers2 = (...wrappersArgs) => {
426
489
  withExceptionHandling,
427
490
  wrappers
428
491
  });
429
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzIiwgIi4uL3NyYy9uZXh0anMtZXhjZXB0aW9uLW1pZGRsZXdhcmUvaHR0cC1leGNlcHRpb25zLnRzIiwgIi4uL3NyYy9uZXh0anMtZXhjZXB0aW9uLW1pZGRsZXdhcmUvd2l0aC1leGNlcHRpb24taGFuZGxpbmcudHMiLCAiLi4vc3JjL25leHRqcy1leGNlcHRpb24tbWlkZGxld2FyZS93aXRoLW9rLXN0YXR1cy50cyIsICIuLi9zcmMvbmV4dGpzLWV4Y2VwdGlvbi1taWRkbGV3YXJlL2luZGV4LnRzIiwgIi4uL3NyYy93aXRoLXJvdXRlLXNwZWMvaW5kZXgudHMiLCAiLi4vc3JjL3dpdGgtcm91dGUtc3BlYy9taWRkbGV3YXJlcy93aXRoLW1ldGhvZHMudHMiLCAiLi4vc3JjL3dpdGgtcm91dGUtc3BlYy9taWRkbGV3YXJlcy93aXRoLXZhbGlkYXRpb24udHMiLCAiLi4vc3JjL3dyYXBwZXJzL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJleHBvcnQgKiBmcm9tIFwiLi9uZXh0anMtZXhjZXB0aW9uLW1pZGRsZXdhcmVcIlxuZXhwb3J0ICogZnJvbSBcIi4vd2l0aC1yb3V0ZS1zcGVjXCJcbmV4cG9ydCB7IHdyYXBwZXJzIH0gZnJvbSBcIi4vd3JhcHBlcnNcIlxuZXhwb3J0ICogZnJvbSBcIi4vdHlwZXNcIlxuIiwgImV4cG9ydCB0eXBlIEh0dHBFeGNlcHRpb25NZXRhZGF0YSA9IHtcbiAgdHlwZTogc3RyaW5nXG4gIG1lc3NhZ2U6IHN0cmluZ1xuICBkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbn0gJiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuXG5leHBvcnQgaW50ZXJmYWNlIFRocm93aW5nT3B0aW9ucyB7XG4gIGpzb24/OiBib29sZWFuXG59XG5cbi8qKlxuICogVGhyb3cgSHR0cEV4Y2VwdGlvbnMgaW5zaWRlIEFQSSBlbmRwb2ludHMgdG8gZ2VuZXJhdGUgbmljZSBlcnJvciBtZXNzYWdlc1xuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBcbiAqIGlmIChiYWRfc291cHMuaW5jbHVkZXMoc291cF9wYXJhbSkpIHtcbiAqICAgdGhyb3cgbmV3IEh0dHBFeGNlcHRpb24oNDAwLCB7XG4gKiAgICAgIHR5cGU6IFwiY2FudF9tYWtlX3NvdXBcIixcbiAqICAgICAgbWVzc2FnZTogXCJTb3VwIHdhcyB0b28gZGlmZmljdWx0LCBwbGVhc2Ugc3BlY2lmeSBhIGRpZmZlcmVudCBzb3VwXCJcbiAqICAgIH0pXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiovXG5leHBvcnQgY2xhc3MgSHR0cEV4Y2VwdGlvbiBleHRlbmRzIEVycm9yIHtcbiAgb3B0aW9uczogVGhyb3dpbmdPcHRpb25zXG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHN0YXR1czogbnVtYmVyLFxuICAgIHB1YmxpYyBtZXRhZGF0YTogSHR0cEV4Y2VwdGlvbk1ldGFkYXRhLFxuICAgIG9wdGlvbnM/OiBUaHJvd2luZ09wdGlvbnNcbiAgKSB7XG4gICAgc3VwZXIobWV0YWRhdGEubWVzc2FnZSlcblxuICAgIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgdGhpcy5jb25zdHJ1Y3RvcilcbiAgICB9XG5cbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zID8/IHsganNvbjogdHJ1ZSB9XG4gIH1cblxuICB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gYEh0dHBFeGNlcHRpb246ICR7dGhpcy5zdGF0dXN9LCAke3RoaXMubWV0YWRhdGEubWVzc2FnZX0gKCR7dGhpcy5tZXRhZGF0YS50eXBlfSlgXG4gIH1cbn1cblxuLyoqXG4gKiBUaHJvdyBCYWRSZXF1ZXN0RXhjZXB0aW9uIGluc2lkZSBBUEkgZW5kcG9pbnRzIHRoYXQgd2VyZSBwcm92aWRlZCBpbmNvcnJlY3RcbiAqIHBhcmFtZXRlcnMgb3IgYm9keVxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBcbiAqIGlmIChiYWRfc291cHMuaW5jbHVkZXMoc291cF9wYXJhbSkpIHtcbiAqICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oe1xuICogICAgIHR5cGU6IFwiY2FudF9tYWtlX3NvdXBcIixcbiAqICAgICBtZXNzYWdlOiBcIlNvdXAgd2FzIHRvbyBkaWZmaWN1bHQsIHBsZWFzZSBzcGVjaWZ5IGEgZGlmZmVyZW50IHNvdXBcIixcbiAqICAgfSlcbiAqIH1cbiAqIGBgYFxuICpcbiAqKi9cbmV4cG9ydCBjbGFzcyBCYWRSZXF1ZXN0RXhjZXB0aW9uIGV4dGVuZHMgSHR0cEV4Y2VwdGlvbiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBtZXRhZGF0YTogSHR0cEV4Y2VwdGlvbk1ldGFkYXRhLFxuICAgIG9wdGlvbnM/OiBUaHJvd2luZ09wdGlvbnNcbiAgKSB7XG4gICAgc3VwZXIoNDAwLCBtZXRhZGF0YSwgb3B0aW9ucylcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgVW5hdXRob3JpemVkRXhjZXB0aW9uIGV4dGVuZHMgSHR0cEV4Y2VwdGlvbiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBtZXRhZGF0YTogSHR0cEV4Y2VwdGlvbk1ldGFkYXRhLFxuICAgIG9wdGlvbnM/OiBUaHJvd2luZ09wdGlvbnNcbiAgKSB7XG4gICAgc3VwZXIoNDAxLCBtZXRhZGF0YSwgb3B0aW9ucylcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTm90Rm91bmRFeGNlcHRpb24gZXh0ZW5kcyBIdHRwRXhjZXB0aW9uIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIG1ldGFkYXRhOiBIdHRwRXhjZXB0aW9uTWV0YWRhdGEsXG4gICAgb3B0aW9ucz86IFRocm93aW5nT3B0aW9uc1xuICApIHtcbiAgICBzdXBlcig0MDQsIG1ldGFkYXRhLCBvcHRpb25zKVxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBNZXRob2ROb3RBbGxvd2VkRXhjZXB0aW9uIGV4dGVuZHMgSHR0cEV4Y2VwdGlvbiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBtZXRhZGF0YTogSHR0cEV4Y2VwdGlvbk1ldGFkYXRhLFxuICAgIG9wdGlvbnM/OiBUaHJvd2luZ09wdGlvbnNcbiAgKSB7XG4gICAgc3VwZXIoNDA1LCBtZXRhZGF0YSwgb3B0aW9ucylcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgSW50ZXJuYWxTZXJ2ZXJFcnJvckV4Y2VwdGlvbiBleHRlbmRzIEh0dHBFeGNlcHRpb24ge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgbWV0YWRhdGE6IEh0dHBFeGNlcHRpb25NZXRhZGF0YSxcbiAgICBvcHRpb25zPzogVGhyb3dpbmdPcHRpb25zXG4gICkge1xuICAgIHN1cGVyKDUwMCwgbWV0YWRhdGEsIG9wdGlvbnMpXG4gIH1cbn1cbiIsICJpbXBvcnQgeyBOZXh0QXBpUmVxdWVzdCwgTmV4dEFwaVJlc3BvbnNlIH0gZnJvbSBcIm5leHRcIlxuaW1wb3J0IHsgSHR0cEV4Y2VwdGlvbiB9IGZyb20gXCIuL2h0dHAtZXhjZXB0aW9uc1wiXG5cbmV4cG9ydCBpbnRlcmZhY2UgV2l0aEV4Y2VwdGlvbkhhbmRsaW5nT3B0aW9ucyB7XG4gIGdldEVycm9yQ29udGV4dD86IChcbiAgICByZXE6IE5leHRBcGlSZXF1ZXN0LFxuICAgIGVycm9yOiBFcnJvclxuICApID0+IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG59XG5cbmNvbnN0IHdpdGhFeGNlcHRpb25IYW5kbGluZyA9XG4gIChvcHRpb25zOiBXaXRoRXhjZXB0aW9uSGFuZGxpbmdPcHRpb25zID0ge30pID0+XG4gIChuZXh0OiAocmVxOiBOZXh0QXBpUmVxdWVzdCwgcmVzOiBOZXh0QXBpUmVzcG9uc2UpID0+IFByb21pc2U8dm9pZD4pID0+XG4gIGFzeW5jIChyZXE6IE5leHRBcGlSZXF1ZXN0LCByZXM6IE5leHRBcGlSZXNwb25zZSkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBuZXh0KHJlcSwgcmVzKVxuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICBsZXQgZXJyb3JDb250ZXh0OiBhbnkgPSB7fVxuXG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICBlcnJvckNvbnRleHQuc3RhY2sgPSBlcnJvci5zdGFja1xuICAgICAgfVxuXG4gICAgICBlcnJvckNvbnRleHQgPSBvcHRpb25zLmdldEVycm9yQ29udGV4dFxuICAgICAgICA/IG9wdGlvbnMuZ2V0RXJyb3JDb250ZXh0KHJlcSwgZXJyb3JDb250ZXh0KVxuICAgICAgICA6IGVycm9yQ29udGV4dFxuXG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBIdHRwRXhjZXB0aW9uKSB7XG4gICAgICAgIGlmIChlcnJvci5vcHRpb25zLmpzb24pIHtcbiAgICAgICAgICByZXMuc3RhdHVzKGVycm9yLnN0YXR1cykuanNvbih7XG4gICAgICAgICAgICBlcnJvcjoge1xuICAgICAgICAgICAgICAuLi5lcnJvci5tZXRhZGF0YSxcbiAgICAgICAgICAgICAgLi4uZXJyb3JDb250ZXh0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlcy5zdGF0dXMoZXJyb3Iuc3RhdHVzKS5lbmQoZXJyb3IubWV0YWRhdGEubWVzc2FnZSlcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgZm9ybWF0dGVkRXJyb3IgPSBuZXcgSHR0cEV4Y2VwdGlvbig1MDAsIHtcbiAgICAgICAgICB0eXBlOiBcImludGVybmFsX3NlcnZlcl9lcnJvclwiLFxuICAgICAgICAgIG1lc3NhZ2U6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogXCJVbmtub3duIGVycm9yXCIsXG4gICAgICAgIH0pXG5cbiAgICAgICAgcmVzLnN0YXR1cyg1MDApLmpzb24oe1xuICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICAuLi5mb3JtYXR0ZWRFcnJvci5tZXRhZGF0YSxcbiAgICAgICAgICAgIC4uLmVycm9yQ29udGV4dCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuZXhwb3J0IGRlZmF1bHQgd2l0aEV4Y2VwdGlvbkhhbmRsaW5nXG4iLCAiaW1wb3J0IHsgTmV4dEFwaVJlcXVlc3QsIE5leHRBcGlSZXNwb25zZSB9IGZyb20gXCJuZXh0XCJcblxuZXhwb3J0IGludGVyZmFjZSBXaXRoT2tTdGF0dXNPcHRpb25zIHtcbiAgYWRkSWY/OiAocmVxOiBOZXh0QXBpUmVxdWVzdCkgPT4gYm9vbGVhblxufVxuXG5jb25zdCB3aXRoT2tTdGF0dXMgPVxuICAob3B0aW9uczogV2l0aE9rU3RhdHVzT3B0aW9ucyA9IHt9KSA9PlxuICAobmV4dDogKHJlcTogTmV4dEFwaVJlcXVlc3QsIHJlczogTmV4dEFwaVJlc3BvbnNlKSA9PiBQcm9taXNlPHZvaWQ+KSA9PlxuICBhc3luYyAocmVxOiBOZXh0QXBpUmVxdWVzdCwgcmVzOiBOZXh0QXBpUmVzcG9uc2UpID0+IHtcbiAgICAvLyBQYXRjaCAuanNvbigpXG4gICAgY29uc3Qgb3JpZ2luYWxKc29uID0gcmVzLmpzb25cblxuICAgIHJlcy5qc29uID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgIGNvbnN0IG9rID0gcmVzLnN0YXR1c0NvZGUgPj0gMjAwICYmIHJlcy5zdGF0dXNDb2RlIDwgMzAwXG4gICAgICBjb25zdCBzaG91bGRJbmNsdWRlU3RhdHVzID0gb3B0aW9ucy5hZGRJZiA/IG9wdGlvbnMuYWRkSWYocmVxKSA6IHRydWVcblxuICAgICAgaWYgKHNob3VsZEluY2x1ZGVTdGF0dXMpIHtcbiAgICAgICAgb3JpZ2luYWxKc29uLmNhbGwodGhpcywge1xuICAgICAgICAgIC4uLmRhdGEsXG4gICAgICAgICAgb2ssXG4gICAgICAgIH0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcmlnaW5hbEpzb24uY2FsbCh0aGlzLCBkYXRhKVxuICAgICAgfVxuICAgIH1cblxuICAgIGF3YWl0IG5leHQocmVxLCByZXMpXG4gIH1cblxuZXhwb3J0IGRlZmF1bHQgd2l0aE9rU3RhdHVzXG4iLCAiaW1wb3J0IHsgTmV4dEFwaVJlcXVlc3QsIE5leHRBcGlSZXNwb25zZSB9IGZyb20gXCJuZXh0XCJcbmltcG9ydCB1bndyYXBwZWRXaXRoRXhjZXB0aW9uSGFuZGxpbmcsIHtcbiAgV2l0aEV4Y2VwdGlvbkhhbmRsaW5nT3B0aW9ucyxcbn0gZnJvbSBcIi4vd2l0aC1leGNlcHRpb24taGFuZGxpbmdcIlxuaW1wb3J0IHdpdGhPa1N0YXR1cywgeyBXaXRoT2tTdGF0dXNPcHRpb25zIH0gZnJvbSBcIi4vd2l0aC1vay1zdGF0dXNcIlxuXG5leHBvcnQgaW50ZXJmYWNlIEV4Y2VwdGlvbkhhbmRsaW5nT3B0aW9ucyB7XG4gIGFkZE9rU3RhdHVzPzogYm9vbGVhblxuICBva1N0YXR1c09wdGlvbnM/OiBXaXRoT2tTdGF0dXNPcHRpb25zXG4gIGV4Y2VwdGlvbkhhbmRsaW5nT3B0aW9ucz86IFdpdGhFeGNlcHRpb25IYW5kbGluZ09wdGlvbnNcbn1cblxuZXhwb3J0IGNvbnN0IHdpdGhFeGNlcHRpb25IYW5kbGluZyA9XG4gICh7XG4gICAgYWRkT2tTdGF0dXMgPSBmYWxzZSxcbiAgICBva1N0YXR1c09wdGlvbnMsXG4gICAgZXhjZXB0aW9uSGFuZGxpbmdPcHRpb25zLFxuICB9OiBFeGNlcHRpb25IYW5kbGluZ09wdGlvbnMgPSB7fSkgPT5cbiAgKG5leHQ6IChyZXE6IE5leHRBcGlSZXF1ZXN0LCByZXM6IE5leHRBcGlSZXNwb25zZSkgPT4gUHJvbWlzZTx2b2lkPikgPT5cbiAgKHJlcTogTmV4dEFwaVJlcXVlc3QsIHJlczogTmV4dEFwaVJlc3BvbnNlKSA9PiB7XG4gICAgaWYgKGFkZE9rU3RhdHVzKSB7XG4gICAgICByZXR1cm4gd2l0aE9rU3RhdHVzKG9rU3RhdHVzT3B0aW9ucykoXG4gICAgICAgIHVud3JhcHBlZFdpdGhFeGNlcHRpb25IYW5kbGluZyhleGNlcHRpb25IYW5kbGluZ09wdGlvbnMpKG5leHQpXG4gICAgICApKHJlcSwgcmVzKVxuICAgIH1cblxuICAgIHJldHVybiB1bndyYXBwZWRXaXRoRXhjZXB0aW9uSGFuZGxpbmcoZXhjZXB0aW9uSGFuZGxpbmdPcHRpb25zKShuZXh0KShcbiAgICAgIHJlcSxcbiAgICAgIHJlc1xuICAgIClcbiAgfVxuXG5leHBvcnQgKiBmcm9tIFwiLi9odHRwLWV4Y2VwdGlvbnNcIlxuIiwgImltcG9ydCB7IE5leHRBcGlSZXNwb25zZSwgTmV4dEFwaVJlcXVlc3QgfSBmcm9tIFwibmV4dFwiXG5pbXBvcnQgeyB3aXRoRXhjZXB0aW9uSGFuZGxpbmcgfSBmcm9tIFwiLi4vbmV4dGpzLWV4Y2VwdGlvbi1taWRkbGV3YXJlXCJcbmltcG9ydCB3cmFwcGVycywgeyBNaWRkbGV3YXJlIH0gZnJvbSBcIm5leHRqcy1taWRkbGV3YXJlLXdyYXBwZXJzXCJcbmltcG9ydCB7IENyZWF0ZVdpdGhSb3V0ZVNwZWNGdW5jdGlvbiwgUm91dGVTcGVjIH0gZnJvbSBcIi4uL3R5cGVzXCJcbmltcG9ydCB3aXRoTWV0aG9kcywgeyBIVFRQTWV0aG9kcyB9IGZyb20gXCIuL21pZGRsZXdhcmVzL3dpdGgtbWV0aG9kc1wiXG5pbXBvcnQgd2l0aFZhbGlkYXRpb24gZnJvbSBcIi4vbWlkZGxld2FyZXMvd2l0aC12YWxpZGF0aW9uXCJcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCJcblxudHlwZSBQYXJhbURlZiA9IHouWm9kVHlwZUFueSB8IHouWm9kRWZmZWN0czx6LlpvZFR5cGVBbnk+XG5cbmV4cG9ydCBjb25zdCBjaGVja1JvdXRlU3BlYyA9IDxcbiAgQXV0aFR5cGUgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmcsXG4gIE1ldGhvZHMgZXh0ZW5kcyBIVFRQTWV0aG9kc1tdID0gSFRUUE1ldGhvZHNbXSxcbiAgSnNvbkJvZHkgZXh0ZW5kcyBQYXJhbURlZiA9IHouWm9kVHlwZUFueSxcbiAgUXVlcnlQYXJhbXMgZXh0ZW5kcyBQYXJhbURlZiA9IHouWm9kVHlwZUFueSxcbiAgQ29tbW9uUGFyYW1zIGV4dGVuZHMgUGFyYW1EZWYgPSB6LlpvZFR5cGVBbnksXG4gIE1pZGRsZXdhcmVzIGV4dGVuZHMgcmVhZG9ubHkgTWlkZGxld2FyZTxhbnksIGFueT5bXSA9IHJlYWRvbmx5IE1pZGRsZXdhcmU8XG4gICAgYW55LFxuICAgIGFueVxuICA+W10sXG4gIEZvcm1EYXRhIGV4dGVuZHMgUGFyYW1EZWYgPSB6LlpvZFR5cGVBbnksXG4gIFNwZWMgZXh0ZW5kcyBSb3V0ZVNwZWM8XG4gICAgQXV0aFR5cGUsXG4gICAgTWV0aG9kcyxcbiAgICBKc29uQm9keSxcbiAgICBRdWVyeVBhcmFtcyxcbiAgICBDb21tb25QYXJhbXMsXG4gICAgTWlkZGxld2FyZXMsXG4gICAgRm9ybURhdGFcbiAgPiA9IFJvdXRlU3BlYzxcbiAgICBBdXRoVHlwZSxcbiAgICBNZXRob2RzLFxuICAgIEpzb25Cb2R5LFxuICAgIFF1ZXJ5UGFyYW1zLFxuICAgIENvbW1vblBhcmFtcyxcbiAgICBNaWRkbGV3YXJlcyxcbiAgICBGb3JtRGF0YVxuICA+XG4+KFxuICBzcGVjOiBTcGVjXG4pOiBzdHJpbmcgZXh0ZW5kcyBTcGVjW1wiYXV0aFwiXVxuICA/IGB5b3VyIHJvdXRlIHNwZWMgaXMgdW5kZXJzcGVjaWZpZWQsIGFkZCBcImFzIGNvbnN0XCJgXG4gIDogU3BlYyA9PiBzcGVjIGFzIGFueVxuXG5leHBvcnQgY29uc3QgY3JlYXRlV2l0aFJvdXRlU3BlYzogQ3JlYXRlV2l0aFJvdXRlU3BlY0Z1bmN0aW9uID0gKChcbiAgc2V0dXBQYXJhbXNcbikgPT4ge1xuICBjb25zdCB7XG4gICAgYXV0aE1pZGRsZXdhcmVNYXAgPSB7fSxcbiAgICBnbG9iYWxNaWRkbGV3YXJlcyA9IFtdLFxuICAgIHNob3VsZFZhbGlkYXRlUmVzcG9uc2VzLFxuICAgIHNob3VsZFZhbGlkYXRlR2V0UmVxdWVzdEJvZHkgPSB0cnVlLFxuICAgIGV4Y2VwdGlvbkhhbmRsaW5nTWlkZGxld2FyZSA9IHdpdGhFeGNlcHRpb25IYW5kbGluZyh7XG4gICAgICBhZGRPa1N0YXR1czogc2V0dXBQYXJhbXMuYWRkT2tTdGF0dXMsXG4gICAgICBleGNlcHRpb25IYW5kbGluZ09wdGlvbnM6IHtcbiAgICAgICAgZ2V0RXJyb3JDb250ZXh0OiAocmVxLCBlcnJvcikgPT4ge1xuICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgICAgICAgICAgIHJldHVybiB7fVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBlcnJvclxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KSBhcyBhbnksXG4gICAgZ2xvYmFsU2NoZW1hcyA9IHNldHVwUGFyYW1zLmFkZE9rU3RhdHVzXG4gICAgICA/IHtcbiAgICAgICAgICBvazogei5ib29sZWFuKCksXG4gICAgICAgIH1cbiAgICAgIDoge30sXG4gIH0gPSBzZXR1cFBhcmFtc1xuXG4gIGNvbnN0IHdpdGhSb3V0ZVNwZWMgPSAoc3BlYzogUm91dGVTcGVjKSA9PiB7XG4gICAgY29uc3QgY3JlYXRlUm91dGVFeHBvcnQgPSAodXNlckRlZmluZWRSb3V0ZUZuKSA9PiB7XG4gICAgICBjb25zdCByb290UmVxdWVzdEhhbmRsZXIgPSBhc3luYyAoXG4gICAgICAgIHJlcTogTmV4dEFwaVJlcXVlc3QsXG4gICAgICAgIHJlczogTmV4dEFwaVJlc3BvbnNlXG4gICAgICApID0+IHtcbiAgICAgICAgYXV0aE1pZGRsZXdhcmVNYXBbXCJub25lXCJdID0gKG5leHQpID0+IG5leHRcblxuICAgICAgICBjb25zdCBhdXRoX21pZGRsZXdhcmUgPSBhdXRoTWlkZGxld2FyZU1hcFtzcGVjLmF1dGhdXG4gICAgICAgIGlmICghYXV0aF9taWRkbGV3YXJlKSB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gYXV0aCB0eXBlOiAke3NwZWMuYXV0aH1gKVxuXG4gICAgICAgIHJldHVybiB3cmFwcGVycyhcbiAgICAgICAgICAuLi4oKGV4Y2VwdGlvbkhhbmRsaW5nTWlkZGxld2FyZVxuICAgICAgICAgICAgPyBbZXhjZXB0aW9uSGFuZGxpbmdNaWRkbGV3YXJlXVxuICAgICAgICAgICAgOiBbXSkgYXMgW2FueV0pLFxuICAgICAgICAgIC4uLigoZ2xvYmFsTWlkZGxld2FyZXMgfHwgW10pIGFzIFtdKSxcbiAgICAgICAgICBhdXRoX21pZGRsZXdhcmUsXG4gICAgICAgICAgLi4uKChzcGVjLm1pZGRsZXdhcmVzIHx8IFtdKSBhcyBbXSksXG4gICAgICAgICAgd2l0aE1ldGhvZHMoc3BlYy5tZXRob2RzKSxcbiAgICAgICAgICB3aXRoVmFsaWRhdGlvbih7XG4gICAgICAgICAgICBqc29uQm9keTogc3BlYy5qc29uQm9keSxcbiAgICAgICAgICAgIHF1ZXJ5UGFyYW1zOiBzcGVjLnF1ZXJ5UGFyYW1zLFxuICAgICAgICAgICAgY29tbW9uUGFyYW1zOiBzcGVjLmNvbW1vblBhcmFtcyxcbiAgICAgICAgICAgIGZvcm1EYXRhOiBzcGVjLmZvcm1EYXRhLFxuICAgICAgICAgICAganNvblJlc3BvbnNlOiBzcGVjLmpzb25SZXNwb25zZSxcbiAgICAgICAgICAgIHNob3VsZFZhbGlkYXRlUmVzcG9uc2VzLFxuICAgICAgICAgICAgc2hvdWxkVmFsaWRhdGVHZXRSZXF1ZXN0Qm9keSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICB1c2VyRGVmaW5lZFJvdXRlRm5cbiAgICAgICAgKShyZXEgYXMgYW55LCByZXMpXG4gICAgICB9XG5cbiAgICAgIHJvb3RSZXF1ZXN0SGFuZGxlci5fc2V0dXBQYXJhbXMgPSBzZXR1cFBhcmFtc1xuICAgICAgcm9vdFJlcXVlc3RIYW5kbGVyLl9yb3V0ZVNwZWMgPSBzcGVjXG5cbiAgICAgIHJldHVybiByb290UmVxdWVzdEhhbmRsZXJcbiAgICB9XG5cbiAgICBjcmVhdGVSb3V0ZUV4cG9ydC5fc2V0dXBQYXJhbXMgPSBzZXR1cFBhcmFtc1xuICAgIGNyZWF0ZVJvdXRlRXhwb3J0Ll9yb3V0ZVNwZWMgPSBzcGVjXG5cbiAgICByZXR1cm4gY3JlYXRlUm91dGVFeHBvcnRcbiAgfVxuXG4gIHdpdGhSb3V0ZVNwZWMuX3NldHVwUGFyYW1zID0gc2V0dXBQYXJhbXNcblxuICByZXR1cm4gd2l0aFJvdXRlU3BlY1xufSkgYXMgYW55XG4iLCAiaW1wb3J0IHsgTWV0aG9kTm90QWxsb3dlZEV4Y2VwdGlvbiB9IGZyb20gXCIuLi8uLi9uZXh0anMtZXhjZXB0aW9uLW1pZGRsZXdhcmVcIlxuXG5leHBvcnQgdHlwZSBIVFRQTWV0aG9kcyA9XG4gIHwgXCJHRVRcIlxuICB8IFwiUE9TVFwiXG4gIHwgXCJERUxFVEVcIlxuICB8IFwiUFVUXCJcbiAgfCBcIlBBVENIXCJcbiAgfCBcIkhFQURcIlxuICB8IFwiT1BUSU9OU1wiXG5cbmV4cG9ydCBjb25zdCB3aXRoTWV0aG9kcyA9IChtZXRob2RzOiBIVFRQTWV0aG9kc1tdKSA9PiAobmV4dCkgPT4gKHJlcSwgcmVzKSA9PiB7XG4gIGlmICghbWV0aG9kcy5pbmNsdWRlcyhyZXEubWV0aG9kKSkge1xuICAgIHRocm93IG5ldyBNZXRob2ROb3RBbGxvd2VkRXhjZXB0aW9uKHtcbiAgICAgIHR5cGU6IFwibWV0aG9kX25vdF9hbGxvd2VkXCIsXG4gICAgICBtZXNzYWdlOiBgb25seSAke21ldGhvZHMuam9pbihcIixcIil9IGFjY2VwdGVkYCxcbiAgICB9KVxuICB9XG4gIHJldHVybiBuZXh0KHJlcSwgcmVzKVxufVxuXG5leHBvcnQgZGVmYXVsdCB3aXRoTWV0aG9kc1xuIiwgImltcG9ydCB0eXBlIHsgTmV4dEFwaVJlcXVlc3QsIE5leHRBcGlSZXNwb25zZSB9IGZyb20gXCJuZXh0XCJcbmltcG9ydCB7IHosIFpvZEZpcnN0UGFydHlUeXBlS2luZCB9IGZyb20gXCJ6b2RcIlxuaW1wb3J0IHtcbiAgQmFkUmVxdWVzdEV4Y2VwdGlvbixcbiAgSW50ZXJuYWxTZXJ2ZXJFcnJvckV4Y2VwdGlvbixcbn0gZnJvbSBcIi4uLy4uL25leHRqcy1leGNlcHRpb24tbWlkZGxld2FyZVwiXG5pbXBvcnQgeyBpc0VtcHR5IH0gZnJvbSBcImxvZGFzaFwiXG5cbmNvbnN0IGdldFpvZE9iamVjdFNjaGVtYUZyb21ab2RFZmZlY3RTY2hlbWEgPSAoXG4gIGlzWm9kRWZmZWN0OiBib29sZWFuLFxuICBzY2hlbWE6IHouWm9kVHlwZUFueVxuKTogei5ab2RUeXBlQW55IHwgei5ab2RPYmplY3Q8YW55PiA9PiB7XG4gIGlmICghaXNab2RFZmZlY3QpIHtcbiAgICByZXR1cm4gc2NoZW1hIGFzIHouWm9kT2JqZWN0PGFueT5cbiAgfVxuXG4gIGxldCBjdXJyZW50U2NoZW1hID0gc2NoZW1hXG5cbiAgd2hpbGUgKGN1cnJlbnRTY2hlbWEgaW5zdGFuY2VvZiB6LlpvZEVmZmVjdHMpIHtcbiAgICBjdXJyZW50U2NoZW1hID0gY3VycmVudFNjaGVtYS5fZGVmLnNjaGVtYVxuICB9XG5cbiAgcmV0dXJuIGN1cnJlbnRTY2hlbWEgYXMgei5ab2RPYmplY3Q8YW55PlxufVxuXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBnZXQgdGhlIGNvcnJlY3Qgc2NoZW1hIGZyb20gYSBab2RFZmZlY3QgfCBab2REZWZhdWx0IHwgWm9kT3B0aW9uYWwgc2NoZW1hLlxuICogVE9ETzogdGhpcyBmdW5jdGlvbiBzaG91bGQgaGFuZGxlIGFsbCBzcGVjaWFsIGNhc2VzIG9mIFpvZFNjaGVtYSBhbmQgbm90IGp1c3QgWm9kRWZmZWN0IHwgWm9kRGVmYXVsdCB8IFpvZE9wdGlvbmFsXG4gKi9cbmNvbnN0IGdldFpvZERlZkZyb21ab2RTY2hlbWFIZWxwZXJzID0gKHNjaGVtYTogei5ab2RUeXBlQW55KSA9PiB7XG4gIGNvbnN0IHNwZWNpYWxfem9kX3R5cGVzID0gW1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPcHRpb25hbCxcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRGVmYXVsdCxcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRWZmZWN0cyxcbiAgXVxuXG4gIHdoaWxlIChzcGVjaWFsX3pvZF90eXBlcy5pbmNsdWRlcyhzY2hlbWEuX2RlZi50eXBlTmFtZSkpIHtcbiAgICBpZiAoXG4gICAgICBzY2hlbWEuX2RlZi50eXBlTmFtZSA9PT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE9wdGlvbmFsIHx8XG4gICAgICBzY2hlbWEuX2RlZi50eXBlTmFtZSA9PT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZERlZmF1bHRcbiAgICApIHtcbiAgICAgIHNjaGVtYSA9IHNjaGVtYS5fZGVmLmlubmVyVHlwZVxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBpZiAoc2NoZW1hLl9kZWYudHlwZU5hbWUgPT09IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RFZmZlY3RzKSB7XG4gICAgICBzY2hlbWEgPSBzY2hlbWEuX2RlZi5zY2hlbWFcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICB9XG4gIHJldHVybiBzY2hlbWEuX2RlZlxufVxuXG5jb25zdCBwYXJzZVF1ZXJ5UGFyYW1zID0gKFxuICBzY2hlbWE6IHouWm9kVHlwZUFueSxcbiAgaW5wdXQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4pID0+IHtcbiAgY29uc3QgcGFyc2VkX2lucHV0ID0gT2JqZWN0LmFzc2lnbih7fSwgaW5wdXQpXG4gIGNvbnN0IGlzWm9kRWZmZWN0ID0gc2NoZW1hLl9kZWYudHlwZU5hbWUgPT09IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RFZmZlY3RzXG4gIGNvbnN0IHNhZmVfc2NoZW1hID0gZ2V0Wm9kT2JqZWN0U2NoZW1hRnJvbVpvZEVmZmVjdFNjaGVtYShpc1pvZEVmZmVjdCwgc2NoZW1hKVxuICBjb25zdCBpc1pvZE9iamVjdCA9XG4gICAgc2FmZV9zY2hlbWEuX2RlZi50eXBlTmFtZSA9PT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE9iamVjdFxuXG4gIGlmIChpc1pvZE9iamVjdCkge1xuICAgIGNvbnN0IG9ial9zY2hlbWEgPSBzYWZlX3NjaGVtYSBhcyB6LlpvZE9iamVjdDxhbnk+XG5cbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhvYmpfc2NoZW1hLnNoYXBlKSkge1xuICAgICAgY29uc3QgZGVmID0gZ2V0Wm9kRGVmRnJvbVpvZFNjaGVtYUhlbHBlcnModmFsdWUgYXMgei5ab2RUeXBlQW55KVxuICAgICAgY29uc3QgaXNBcnJheSA9IGRlZi50eXBlTmFtZSA9PT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEFycmF5XG4gICAgICBpZiAoaXNBcnJheSkge1xuICAgICAgICBjb25zdCBhcnJheV9pbnB1dCA9IGlucHV0W2tleV1cblxuICAgICAgICBpZiAodHlwZW9mIGFycmF5X2lucHV0ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgcGFyc2VkX2lucHV0W2tleV0gPSBhcnJheV9pbnB1dC5zcGxpdChcIixcIilcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGJyYWNrZXRfc3ludGF4X2FycmF5X2lucHV0ID0gaW5wdXRbYCR7a2V5fVtdYF1cbiAgICAgICAgaWYgKHR5cGVvZiBicmFja2V0X3N5bnRheF9hcnJheV9pbnB1dCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIGNvbnN0IHByZV9zcGxpdF9hcnJheSA9IGJyYWNrZXRfc3ludGF4X2FycmF5X2lucHV0XG4gICAgICAgICAgcGFyc2VkX2lucHV0W2tleV0gPSBwcmVfc3BsaXRfYXJyYXkuc3BsaXQoXCIsXCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShicmFja2V0X3N5bnRheF9hcnJheV9pbnB1dCkpIHtcbiAgICAgICAgICBwYXJzZWRfaW5wdXRba2V5XSA9IGJyYWNrZXRfc3ludGF4X2FycmF5X2lucHV0XG4gICAgICAgIH1cblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBjb25zdCBpc0Jvb2xlYW4gPSBkZWYudHlwZU5hbWUgPT09IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RCb29sZWFuXG4gICAgICBpZiAoaXNCb29sZWFuKSB7XG4gICAgICAgIGNvbnN0IGJvb2xlYW5faW5wdXQgPSBpbnB1dFtrZXldXG5cbiAgICAgICAgaWYgKHR5cGVvZiBib29sZWFuX2lucHV0ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgcGFyc2VkX2lucHV0W2tleV0gPSBib29sZWFuX2lucHV0ID09PSBcInRydWVcIlxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHNjaGVtYS5wYXJzZShwYXJzZWRfaW5wdXQpXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVxdWVzdElucHV0PFxuICBKc29uQm9keSBleHRlbmRzIHouWm9kVHlwZUFueSxcbiAgUXVlcnlQYXJhbXMgZXh0ZW5kcyB6LlpvZFR5cGVBbnksXG4gIENvbW1vblBhcmFtcyBleHRlbmRzIHouWm9kVHlwZUFueSxcbiAgRm9ybURhdGEgZXh0ZW5kcyB6LlpvZFR5cGVBbnksXG4gIEpzb25SZXNwb25zZSBleHRlbmRzIHouWm9kVHlwZUFueVxuPiB7XG4gIGpzb25Cb2R5PzogSnNvbkJvZHlcbiAgcXVlcnlQYXJhbXM/OiBRdWVyeVBhcmFtc1xuICBjb21tb25QYXJhbXM/OiBDb21tb25QYXJhbXNcbiAgZm9ybURhdGE/OiBGb3JtRGF0YVxuICBqc29uUmVzcG9uc2U/OiBKc29uUmVzcG9uc2VcbiAgc2hvdWxkVmFsaWRhdGVSZXNwb25zZXM/OiBib29sZWFuXG4gIHNob3VsZFZhbGlkYXRlR2V0UmVxdWVzdEJvZHk/OiBib29sZWFuXG59XG5cbmNvbnN0IHpvZElzc3VlVG9TdHJpbmcgPSAoaXNzdWU6IHouWm9kSXNzdWUpID0+IHtcbiAgaWYgKGlzc3VlLnBhdGguam9pbihcIi5cIikgPT09IFwiXCIpIHtcbiAgICByZXR1cm4gaXNzdWUubWVzc2FnZVxuICB9XG4gIGlmIChpc3N1ZS5tZXNzYWdlID09PSBcIlJlcXVpcmVkXCIpIHtcbiAgICByZXR1cm4gYCR7aXNzdWUucGF0aC5qb2luKFwiLlwiKX0gaXMgcmVxdWlyZWRgXG4gIH1cbiAgcmV0dXJuIGAke2lzc3VlLm1lc3NhZ2V9IGZvciBcIiR7aXNzdWUucGF0aC5qb2luKFwiLlwiKX1cImBcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVKc29uUmVzcG9uc2U8SnNvblJlc3BvbnNlIGV4dGVuZHMgei5ab2RUeXBlQW55PihcbiAganNvblJlc3BvbnNlOiBKc29uUmVzcG9uc2UgfCB1bmRlZmluZWQsXG4gIHJlczogTmV4dEFwaVJlc3BvbnNlXG4pIHtcbiAgY29uc3Qgb3JpZ2luYWxfcmVzX2pzb24gPSByZXMuanNvblxuICBjb25zdCBvdmVycmlkZV9yZXNfanNvbiA9IChqc29uOiBhbnkpID0+IHtcbiAgICBjb25zdCBpc19zdWNjZXNzID0gcmVzLnN0YXR1c0NvZGUgPj0gMjAwICYmIHJlcy5zdGF0dXNDb2RlIDwgMzAwXG4gICAgaWYgKCFpc19zdWNjZXNzKSB7XG4gICAgICByZXR1cm4gb3JpZ2luYWxfcmVzX2pzb24oanNvbilcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAganNvblJlc3BvbnNlPy5wYXJzZShqc29uKVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhyb3cgbmV3IEludGVybmFsU2VydmVyRXJyb3JFeGNlcHRpb24oe1xuICAgICAgICB0eXBlOiBcImludmFsaWRfcmVzcG9uc2VcIixcbiAgICAgICAgbWVzc2FnZTogXCJ0aGUgcmVzcG9uc2UgZG9lcyBub3QgbWF0Y2ggd2l0aCBqc29uUmVzcG9uc2VcIixcbiAgICAgICAgem9kRXJyb3I6IGVycixcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgcmV0dXJuIG9yaWdpbmFsX3Jlc19qc29uKGpzb24pXG4gIH1cbiAgcmVzLmpzb24gPSBvdmVycmlkZV9yZXNfanNvblxufVxuXG5leHBvcnQgY29uc3Qgd2l0aFZhbGlkYXRpb24gPVxuICA8XG4gICAgSnNvbkJvZHkgZXh0ZW5kcyB6LlpvZFR5cGVBbnksXG4gICAgUXVlcnlQYXJhbXMgZXh0ZW5kcyB6LlpvZFR5cGVBbnksXG4gICAgQ29tbW9uUGFyYW1zIGV4dGVuZHMgei5ab2RUeXBlQW55LFxuICAgIEZvcm1EYXRhIGV4dGVuZHMgei5ab2RUeXBlQW55LFxuICAgIEpzb25SZXNwb25zZSBleHRlbmRzIHouWm9kVHlwZUFueVxuICA+KFxuICAgIGlucHV0OiBSZXF1ZXN0SW5wdXQ8XG4gICAgICBKc29uQm9keSxcbiAgICAgIFF1ZXJ5UGFyYW1zLFxuICAgICAgQ29tbW9uUGFyYW1zLFxuICAgICAgRm9ybURhdGEsXG4gICAgICBKc29uUmVzcG9uc2VcbiAgICA+XG4gICkgPT5cbiAgKG5leHQpID0+XG4gIGFzeW5jIChyZXE6IE5leHRBcGlSZXF1ZXN0LCByZXM6IE5leHRBcGlSZXNwb25zZSkgPT4ge1xuICAgIGlmIChcbiAgICAgIChpbnB1dC5mb3JtRGF0YSAmJiBpbnB1dC5qc29uQm9keSkgfHxcbiAgICAgIChpbnB1dC5mb3JtRGF0YSAmJiBpbnB1dC5jb21tb25QYXJhbXMpXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgdXNlIGZvcm1EYXRhIHdpdGgganNvbkJvZHkgb3IgY29tbW9uUGFyYW1zXCIpXG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgKHJlcS5tZXRob2QgPT09IFwiUE9TVFwiIHx8IHJlcS5tZXRob2QgPT09IFwiUEFUQ0hcIikgJiZcbiAgICAgIChpbnB1dC5qc29uQm9keSB8fCBpbnB1dC5jb21tb25QYXJhbXMpICYmXG4gICAgICAhcmVxLmhlYWRlcnNbXCJjb250ZW50LXR5cGVcIl0/LmluY2x1ZGVzKFwiYXBwbGljYXRpb24vanNvblwiKSAmJlxuICAgICAgIWlzRW1wdHkocmVxLmJvZHkpXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbih7XG4gICAgICAgIHR5cGU6IFwiaW52YWxpZF9jb250ZW50X3R5cGVcIixcbiAgICAgICAgbWVzc2FnZTogYCR7cmVxLm1ldGhvZH0gcmVxdWVzdHMgbXVzdCBoYXZlIENvbnRlbnQtVHlwZSBoZWFkZXIgd2l0aCBcImFwcGxpY2F0aW9uL2pzb25cImAsXG4gICAgICB9KVxuICAgIH1cblxuICAgIGlmIChcbiAgICAgIGlucHV0LmZvcm1EYXRhICYmXG4gICAgICByZXEubWV0aG9kICE9PSBcIkdFVFwiICYmXG4gICAgICAhcmVxLmhlYWRlcnNbXCJjb250ZW50LXR5cGVcIl0/LmluY2x1ZGVzKFxuICAgICAgICBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiXG4gICAgICApXG4gICAgICAvLyBUT0RPIGV2ZW50dWFsbHkgd2Ugc2hvdWxkIHN1cHBvcnQgbXVsdGlwYXJ0L2Zvcm0tZGF0YVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oe1xuICAgICAgICB0eXBlOiBcImludmFsaWRfY29udGVudF90eXBlXCIsXG4gICAgICAgIG1lc3NhZ2U6IGBNdXN0IGhhdmUgQ29udGVudC1UeXBlIGhlYWRlciB3aXRoIFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkXCJgLFxuICAgICAgfSlcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3Qgb3JpZ2luYWxfY29tYmluZWRfcGFyYW1zID0geyAuLi5yZXEucXVlcnksIC4uLnJlcS5ib2R5IH1cblxuICAgICAgY29uc3Qgd2lsbFZhbGlkYXRlUmVxdWVzdEJvZHkgPSBpbnB1dC5zaG91bGRWYWxpZGF0ZUdldFJlcXVlc3RCb2R5XG4gICAgICAgID8gdHJ1ZVxuICAgICAgICA6IHJlcS5tZXRob2QgIT09IFwiR0VUXCJcblxuICAgICAgY29uc3QgaXNGb3JtRGF0YSA9IEJvb2xlYW4oaW5wdXQuZm9ybURhdGEpXG5cbiAgICAgIGlmIChpc0Zvcm1EYXRhICYmIHdpbGxWYWxpZGF0ZVJlcXVlc3RCb2R5KSB7XG4gICAgICAgIHJlcS5ib2R5ID0gaW5wdXQuZm9ybURhdGE/LnBhcnNlKHJlcS5ib2R5KVxuICAgICAgfVxuXG4gICAgICBpZiAoIWlzRm9ybURhdGEgJiYgd2lsbFZhbGlkYXRlUmVxdWVzdEJvZHkpIHtcbiAgICAgICAgcmVxLmJvZHkgPSBpbnB1dC5qc29uQm9keT8ucGFyc2UocmVxLmJvZHkpXG4gICAgICB9XG5cbiAgICAgIGlmIChpbnB1dC5xdWVyeVBhcmFtcykge1xuICAgICAgICByZXEucXVlcnkgPSBwYXJzZVF1ZXJ5UGFyYW1zKGlucHV0LnF1ZXJ5UGFyYW1zLCByZXEucXVlcnkpXG4gICAgICB9XG5cbiAgICAgIGlmIChpbnB1dC5jb21tb25QYXJhbXMpIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGFzIGNvbW1vblBhcmFtcyBpbmNsdWRlcyBxdWVyeSBwYXJhbXMsIHdlIGNhbiB1c2UgdGhlIHBhcnNlUXVlcnlQYXJhbXMgZnVuY3Rpb25cbiAgICAgICAgICovXG4gICAgICAgIDsocmVxIGFzIGFueSkuY29tbW9uUGFyYW1zID0gcGFyc2VRdWVyeVBhcmFtcyhcbiAgICAgICAgICBpbnB1dC5jb21tb25QYXJhbXMsXG4gICAgICAgICAgb3JpZ2luYWxfY29tYmluZWRfcGFyYW1zXG4gICAgICAgIClcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBpZiAoZXJyb3IubmFtZSA9PT0gXCJab2RFcnJvclwiKSB7XG4gICAgICAgIGxldCBtZXNzYWdlXG4gICAgICAgIGlmIChlcnJvci5pc3N1ZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgY29uc3QgaXNzdWUgPSBlcnJvci5pc3N1ZXNbMF1cbiAgICAgICAgICBtZXNzYWdlID0gem9kSXNzdWVUb1N0cmluZyhpc3N1ZSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBtZXNzYWdlX2NvbXBvbmVudHM6IHN0cmluZ1tdID0gW11cbiAgICAgICAgICBmb3IgKGNvbnN0IGlzc3VlIG9mIGVycm9yLmlzc3Vlcykge1xuICAgICAgICAgICAgbWVzc2FnZV9jb21wb25lbnRzLnB1c2goem9kSXNzdWVUb1N0cmluZyhpc3N1ZSkpXG4gICAgICAgICAgfVxuICAgICAgICAgIG1lc3NhZ2UgPVxuICAgICAgICAgICAgYCR7ZXJyb3IuaXNzdWVzLmxlbmd0aH0gSW5wdXQgRXJyb3JzOiBgICtcbiAgICAgICAgICAgIG1lc3NhZ2VfY29tcG9uZW50cy5qb2luKFwiLCBcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKHtcbiAgICAgICAgICB0eXBlOiBcImludmFsaWRfaW5wdXRcIixcbiAgICAgICAgICBtZXNzYWdlLFxuICAgICAgICAgIHZhbGlkYXRpb25fZXJyb3JzOiBlcnJvci5mb3JtYXQoKSxcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oe1xuICAgICAgICB0eXBlOiBcImludmFsaWRfaW5wdXRcIixcbiAgICAgICAgbWVzc2FnZTogXCJFcnJvciB3aGlsZSBwYXJzaW5nIGlucHV0XCIsXG4gICAgICB9KVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHRoaXMgd2lsbCBvdmVycmlkZSB0aGUgcmVzLmpzb24gbWV0aG9kIHRvIHZhbGlkYXRlIHRoZSByZXNwb25zZVxuICAgICAqL1xuICAgIGlmIChpbnB1dC5zaG91bGRWYWxpZGF0ZVJlc3BvbnNlcykge1xuICAgICAgdmFsaWRhdGVKc29uUmVzcG9uc2UoaW5wdXQuanNvblJlc3BvbnNlLCByZXMpXG4gICAgfVxuXG4gICAgcmV0dXJuIG5leHQocmVxLCByZXMpXG4gIH1cblxuZXhwb3J0IGRlZmF1bHQgd2l0aFZhbGlkYXRpb25cbiIsICJpbXBvcnQgdHlwZSB7IE5leHRBcGlSZXF1ZXN0IGFzIFJlcSwgTmV4dEFwaVJlc3BvbnNlIGFzIFJlcyB9IGZyb20gXCJuZXh0XCJcbi8qXG5cbldyYXBzIGEgZnVuY3Rpb24gaW4gbGF5ZXJzIG9mIG90aGVyIGZ1bmN0aW9ucywgd2hpbGUgcHJlc2VydmluZyB0aGUgaW5wdXQvb3V0cHV0XG50eXBlLiBUaGUgb3V0cHV0IG9mIHdyYXBwZXJzIHdpbGwgYWx3YXlzIGhhdmUgdGhlIHR5cGUgb2YgaXQncyBsYXN0IHBhcmFtZXRlclxuKHRoZSB3cmFwcGVkIGZ1bmN0aW9uKVxuXG5UaGlzIGZ1bmN0aW9uIHR1cm5zIHRoaXMgdHlwZSBvZiBjb21wb3NpdGlvbi4uLlxuXG5sb2dnZXIud2l0aENvbnRleHQoXCJzb21lY29udGV4dFwiKShcbiAgYXN5bmMgKGEsIGIpID0+IHtcbiAgICByZXR1cm4gYVxuICB9XG4pXG5cbkludG8uLi5cblxud3JhcHBlcnMoXG4gIGxvZ2dlci53aXRoQ29udGV4dChcInNvbWVjb250ZXh0XCIpLFxuICBhc3luYyAoYSwgYikgPT4ge1xuICAgIHJldHVybiBhXG4gIH1cbilcblxuSGF2aW5nIHRoaXMgYXMgYSB1dGlsaXR5IG1ldGhvZCBoZWxwcyBwcmVzZXJ2ZSB0eXBlcywgd2hpY2ggb3RoZXJ3aXNlIGNhbiBnZXRcbm1lc3NlZCB1cCBieSB0aGUgbWlkZGxld2FyZXMuIEl0IGFsc28gY2FuIG1ha2UgdGhlIGNvZGUgY2xlYW5lciB3aGVyZSB0aGVyZSBhcmVcbm11bHRpcGxlIHdyYXBwZXJzLlxuXG4jIyBFWEFNUExFU1xuXG5JbiB0aGUgY29udGV4dCBvZiByZXF1ZXN0IG1pZGRsZXdhcmUgeW91IG1pZ2h0IHdyaXRlIHNvbWV0aGluZyBsaWtlIHRoaXMuLi5cblxuY29uc3Qgd2l0aFJlcXVlc3RMb2dnaW5nTWlkZGxld2FyZSA9IChuZXh0KSA9PiBhc3luYyAocmVxLCByZXMpID0+IHtcbiAgY29uc29sZS5sb2coYEdPVCBSRVFVRVNUICR7cmVxLm1ldGhvZH0gJHtyZXEucGF0aH1gKVxuICByZXR1cm4gbmV4dChyZXEsIHJlcylcbn1cblxuSGVyZSdzIGFuIGV4YW1wbGUgb2YgYSB3cmFwcGVyIHRoYXQgdGFrZXMgc29tZSBwYXJhbWV0ZXJzLi4uXG5cbmNvbnN0IHdpdGhMb2dnZWRBcmd1bWVudHMgPVxuICAgIChsb2dQcmVmaXg6IHN0cmluZykgPT5cbiAgICAobmV4dCkgPT5cbiAgICBhc3luYyAoLi4uZnVuY0FyZ3MpID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKGxvZ1ByZWZpeCwgLi4uZnVuY0FyZ3MpXG4gICAgICByZXR1cm4gbmV4dCguLi5mdW5jQXJncylcbiAgICB9XG5cbiovXG5cbmV4cG9ydCB0eXBlIE1pZGRsZXdhcmU8VCwgRGVwID0ge30+ID0gKFxuICBuZXh0OiAocmVxOiBSZXEgJiBEZXAgJiBULCByZXM6IFJlcykgPT4gYW55XG4pID0+IChyZXE6IFJlcSAmIERlcCAmIFQsIHJlczogUmVzKSA9PiBhbnlcblxuLy8gU2FmZXIgTWlkZGxld2FyZSByZXF1aXJlcyB0aGUgdXNlIG9mIGV4dGVuZFJlcXVlc3QgdG8gZW5zdXJlIHRoYXQgdGhlXG4vLyBuZXcgY29udGV4dCAoVCkgd2FzIGFjdHVhbGx5IGFkZGVkIHRvIHRoZSByZXF1ZXN0LiBJdCdzIGtpbmQgb2YgYW5ub3lpbmdcbi8vIHRvIHVzZSBpbiBwcmFjdGljZSwgc28gd2UgZG9uJ3QgdXNlIGl0IGZvciBvdXIgV3JhcHBlcnMgKHlldClcbmV4cG9ydCB0eXBlIFNhZmVyTWlkZGxld2FyZTxULCBEZXAgPSB7fT4gPSAoXG4gIG5leHQ6IChyZXE6IFJlcSAmIERlcCAmIFQsIHJlczogUmVzKSA9PiBhbnlcbikgPT4gKHJlcTogUmVxICYgRGVwLCByZXM6IFJlcykgPT4gYW55XG5cbmV4cG9ydCBjb25zdCBleHRlbmRSZXF1ZXN0ID0gPFQgZXh0ZW5kcyBSZXEsIEsgZXh0ZW5kcyB7fT4oXG4gIHJlcTogVCxcbiAgbWVyZ2U6IEtcbik6IFQgJiBLID0+IHtcbiAgZm9yIChjb25zdCBba2V5LCB2XSBvZiBPYmplY3QuZW50cmllcyhtZXJnZSkpIHtcbiAgICA7KHJlcSBhcyBhbnkpW2tleV0gPSB2XG4gIH1cbiAgcmV0dXJuIHJlcSBhcyBhbnlcbn1cblxudHlwZSBXcmFwcGVyczEgPSA8TXcxUmVxdWVzdENvbnRleHQsIE13MURlcD4oXG4gIG13MTogTWlkZGxld2FyZTxNdzFSZXF1ZXN0Q29udGV4dCwgTXcxRGVwPixcbiAgZW5kcG9pbnQ6IChyZXE6IFJlcSAmIE13MVJlcXVlc3RDb250ZXh0LCByZXM6IFJlcykgPT4gYW55XG4pID0+IChyZXE6IFJlcSwgcmVzOiBSZXMpID0+IGFueVxuXG50eXBlIFdyYXBwZXJzMiA9IDxcbiAgTXcxUmVxdWVzdENvbnRleHQgZXh0ZW5kcyBNdzJEZXAsXG4gIE13MURlcCxcbiAgTXcyUmVxdWVzdENvbnRleHQsXG4gIE13MkRlcFxuPihcbiAgbXcxOiBNaWRkbGV3YXJlPE13MVJlcXVlc3RDb250ZXh0LCBNdzFEZXA+LFxuICBtdzI6IE1pZGRsZXdhcmU8TXcyUmVxdWVzdENvbnRleHQsIE13MkRlcD4sXG4gIGVuZHBvaW50OiAocmVxOiBSZXEgJiBNdzFSZXF1ZXN0Q29udGV4dCAmIE13MlJlcXVlc3RDb250ZXh0LCByZXM6IFJlcykgPT4gYW55XG4pID0+IChyZXE6IFJlcSwgcmVzOiBSZXMpID0+IGFueVxuXG4vLyBUT0RPIGZpZ3VyZSBvdXQgaG93IHRvIGRvIGEgcmVjdXJzaXZlIGRlZmluaXRpb24sIG9yIG9uZSB0aGF0IHNpbXBsaWZpZXNcbi8vIHRoZXNlIHJlZHVuZGFudCB3cmFwcGVyc1xuXG50eXBlIFdyYXBwZXJzMyA9IDxcbiAgTXcxUmVxdWVzdENvbnRleHQgZXh0ZW5kcyBNdzJEZXAsXG4gIE13MURlcCxcbiAgTXcyUmVxdWVzdENvbnRleHQsXG4gIE13MkRlcCxcbiAgTXczUmVxdWVzdENvbnRleHQsXG4gIE13M0RlcFxuPihcbiAgbXcxOiBNaWRkbGV3YXJlPE13MVJlcXVlc3RDb250ZXh0LCBNdzFEZXA+LFxuICBtdzI6IE1pZGRsZXdhcmU8TXcyUmVxdWVzdENvbnRleHQsIE13MkRlcD4sXG4gIG13MzogTWlkZGxld2FyZTxcbiAgICBNdzNSZXF1ZXN0Q29udGV4dCxcbiAgICBNdzFSZXF1ZXN0Q29udGV4dCAmIE13MlJlcXVlc3RDb250ZXh0IGV4dGVuZHMgTXczRGVwID8gTXczRGVwIDogbmV2ZXJcbiAgPixcbiAgZW5kcG9pbnQ6IChcbiAgICByZXE6IFJlcSAmIE13MVJlcXVlc3RDb250ZXh0ICYgTXcyUmVxdWVzdENvbnRleHQgJiBNdzNSZXF1ZXN0Q29udGV4dCxcbiAgICByZXM6IFJlc1xuICApID0+IGFueVxuKSA9PiAocmVxOiBSZXEsIHJlczogUmVzKSA9PiBhbnlcblxudHlwZSBXcmFwcGVyczQgPSA8XG4gIE13MVJlcXVlc3RDb250ZXh0IGV4dGVuZHMgTXcyRGVwLFxuICBNdzFEZXAsXG4gIE13MlJlcXVlc3RDb250ZXh0LFxuICBNdzJEZXAsXG4gIE13M1JlcXVlc3RDb250ZXh0LFxuICBNdzNEZXAsXG4gIE13NFJlcXVlc3RDb250ZXh0LFxuICBNdzREZXBcbj4oXG4gIG13MTogTWlkZGxld2FyZTxNdzFSZXF1ZXN0Q29udGV4dCwgTXcxRGVwPixcbiAgbXcyOiBNaWRkbGV3YXJlPE13MlJlcXVlc3RDb250ZXh0LCBNdzJEZXA+LFxuICBtdzM6IE1pZGRsZXdhcmU8XG4gICAgTXczUmVxdWVzdENvbnRleHQsXG4gICAgTXcxUmVxdWVzdENvbnRleHQgJiBNdzJSZXF1ZXN0Q29udGV4dCBleHRlbmRzIE13M0RlcCA/IE13M0RlcCA6IG5ldmVyXG4gID4sXG4gIG13NDogTWlkZGxld2FyZTxcbiAgICBNdzRSZXF1ZXN0Q29udGV4dCxcbiAgICBNdzFSZXF1ZXN0Q29udGV4dCAmIE13MlJlcXVlc3RDb250ZXh0ICYgTXczUmVxdWVzdENvbnRleHQgZXh0ZW5kcyBNdzREZXBcbiAgICAgID8gTXc0RGVwXG4gICAgICA6IG5ldmVyXG4gID4sXG4gIGVuZHBvaW50OiAoXG4gICAgcmVxOiBSZXEgJlxuICAgICAgTXcxUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXcyUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXczUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXc0UmVxdWVzdENvbnRleHQsXG4gICAgcmVzOiBSZXNcbiAgKSA9PiBhbnlcbikgPT4gKHJlcTogUmVxLCByZXM6IFJlcykgPT4gYW55XG5cbnR5cGUgV3JhcHBlcnM1ID0gPFxuICBNdzFSZXF1ZXN0Q29udGV4dCBleHRlbmRzIE13MkRlcCxcbiAgTXcxRGVwLFxuICBNdzJSZXF1ZXN0Q29udGV4dCxcbiAgTXcyRGVwLFxuICBNdzNSZXF1ZXN0Q29udGV4dCxcbiAgTXczRGVwLFxuICBNdzRSZXF1ZXN0Q29udGV4dCxcbiAgTXc0RGVwLFxuICBNdzVSZXF1ZXN0Q29udGV4dCxcbiAgTXc1RGVwXG4+KFxuICBtdzE6IE1pZGRsZXdhcmU8TXcxUmVxdWVzdENvbnRleHQsIE13MURlcD4sXG4gIG13MjogTWlkZGxld2FyZTxNdzJSZXF1ZXN0Q29udGV4dCwgTXcyRGVwPixcbiAgbXczOiBNaWRkbGV3YXJlPFxuICAgIE13M1JlcXVlc3RDb250ZXh0LFxuICAgIE13MVJlcXVlc3RDb250ZXh0ICYgTXcyUmVxdWVzdENvbnRleHQgZXh0ZW5kcyBNdzNEZXAgPyBNdzNEZXAgOiBuZXZlclxuICA+LFxuICBtdzQ6IE1pZGRsZXdhcmU8XG4gICAgTXc0UmVxdWVzdENvbnRleHQsXG4gICAgTXcxUmVxdWVzdENvbnRleHQgJiBNdzJSZXF1ZXN0Q29udGV4dCAmIE13M1JlcXVlc3RDb250ZXh0IGV4dGVuZHMgTXc0RGVwXG4gICAgICA/IE13NERlcFxuICAgICAgOiBuZXZlclxuICA+LFxuICBtdzU6IE1pZGRsZXdhcmU8XG4gICAgTXc1UmVxdWVzdENvbnRleHQsXG4gICAgTXcxUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXcyUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXczUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXc0UmVxdWVzdENvbnRleHQgZXh0ZW5kcyBNdzVEZXBcbiAgICAgID8gTXc1RGVwXG4gICAgICA6IG5ldmVyXG4gID4sXG4gIGVuZHBvaW50OiAoXG4gICAgcmVxOiBSZXEgJlxuICAgICAgTXcxUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXcyUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXczUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXc0UmVxdWVzdENvbnRleHQgJlxuICAgICAgTXc1UmVxdWVzdENvbnRleHQsXG4gICAgcmVzOiBSZXNcbiAgKSA9PiBhbnlcbikgPT4gKHJlcTogUmVxLCByZXM6IFJlcykgPT4gYW55XG5cbnR5cGUgV3JhcHBlcnM2ID0gPFxuICBNdzFSZXF1ZXN0Q29udGV4dCBleHRlbmRzIE13MkRlcCxcbiAgTXcxRGVwLFxuICBNdzJSZXF1ZXN0Q29udGV4dCxcbiAgTXcyRGVwLFxuICBNdzNSZXF1ZXN0Q29udGV4dCxcbiAgTXczRGVwLFxuICBNdzRSZXF1ZXN0Q29udGV4dCxcbiAgTXc0RGVwLFxuICBNdzVSZXF1ZXN0Q29udGV4dCxcbiAgTXc1RGVwLFxuICBNdzZSZXF1ZXN0Q29udGV4dCxcbiAgTXc2RGVwXG4+KFxuICBtdzE6IE1pZGRsZXdhcmU8TXcxUmVxdWVzdENvbnRleHQsIE13MURlcD4sXG4gIG13MjogTWlkZGxld2FyZTxNdzJSZXF1ZXN0Q29udGV4dCwgTXcyRGVwPixcbiAgbXczOiBNaWRkbGV3YXJlPFxuICAgIE13M1JlcXVlc3RDb250ZXh0LFxuICAgIE13MVJlcXVlc3RDb250ZXh0ICYgTXcyUmVxdWVzdENvbnRleHQgZXh0ZW5kcyBNdzNEZXAgPyBNdzNEZXAgOiBuZXZlclxuICA+LFxuICBtdzQ6IE1pZGRsZXdhcmU8XG4gICAgTXc0UmVxdWVzdENvbnRleHQsXG4gICAgTXcxUmVxdWVzdENvbnRleHQgJiBNdzJSZXF1ZXN0Q29udGV4dCAmIE13M1JlcXVlc3RDb250ZXh0IGV4dGVuZHMgTXc0RGVwXG4gICAgICA/IE13NERlcFxuICAgICAgOiBuZXZlclxuICA+LFxuICBtdzU6IE1pZGRsZXdhcmU8XG4gICAgTXc1UmVxdWVzdENvbnRleHQsXG4gICAgTXcxUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXcyUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXczUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXc0UmVxdWVzdENvbnRleHQgZXh0ZW5kcyBNdzVEZXBcbiAgICAgID8gTXc1RGVwXG4gICAgICA6IG5ldmVyXG4gID4sXG4gIG13NjogTWlkZGxld2FyZTxcbiAgICBNdzZSZXF1ZXN0Q29udGV4dCxcbiAgICBNdzFSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzJSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzNSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzRSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzVSZXF1ZXN0Q29udGV4dCBleHRlbmRzIE13NkRlcFxuICAgICAgPyBNdzZEZXBcbiAgICAgIDogbmV2ZXJcbiAgPixcbiAgZW5kcG9pbnQ6IChcbiAgICByZXE6IFJlcSAmXG4gICAgICBNdzFSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzJSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzNSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzRSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzVSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzZSZXF1ZXN0Q29udGV4dCxcbiAgICByZXM6IFJlc1xuICApID0+IGFueVxuKSA9PiAocmVxOiBSZXEsIHJlczogUmVzKSA9PiBhbnlcblxudHlwZSBXcmFwcGVyczcgPSA8XG4gIE13MVJlcXVlc3RDb250ZXh0IGV4dGVuZHMgTXcyRGVwLFxuICBNdzFEZXAsXG4gIE13MlJlcXVlc3RDb250ZXh0LFxuICBNdzJEZXAsXG4gIE13M1JlcXVlc3RDb250ZXh0LFxuICBNdzNEZXAsXG4gIE13NFJlcXVlc3RDb250ZXh0LFxuICBNdzREZXAsXG4gIE13NVJlcXVlc3RDb250ZXh0LFxuICBNdzVEZXAsXG4gIE13NlJlcXVlc3RDb250ZXh0LFxuICBNdzZEZXAsXG4gIE13N1JlcXVlc3RDb250ZXh0LFxuICBNdzdEZXBcbj4oXG4gIG13MTogTWlkZGxld2FyZTxNdzFSZXF1ZXN0Q29udGV4dCwgTXcxRGVwPixcbiAgbXcyOiBNaWRkbGV3YXJlPE13MlJlcXVlc3RDb250ZXh0LCBNdzJEZXA+LFxuICBtdzM6IE1pZGRsZXdhcmU8XG4gICAgTXczUmVxdWVzdENvbnRleHQsXG4gICAgTXcxUmVxdWVzdENvbnRleHQgJiBNdzJSZXF1ZXN0Q29udGV4dCBleHRlbmRzIE13M0RlcCA/IE13M0RlcCA6IG5ldmVyXG4gID4sXG4gIG13NDogTWlkZGxld2FyZTxcbiAgICBNdzRSZXF1ZXN0Q29udGV4dCxcbiAgICBNdzFSZXF1ZXN0Q29udGV4dCAmIE13MlJlcXVlc3RDb250ZXh0ICYgTXczUmVxdWVzdENvbnRleHQgZXh0ZW5kcyBNdzREZXBcbiAgICAgID8gTXc0RGVwXG4gICAgICA6IG5ldmVyXG4gID4sXG4gIG13NTogTWlkZGxld2FyZTxcbiAgICBNdzVSZXF1ZXN0Q29udGV4dCxcbiAgICBNdzFSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzJSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzNSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzRSZXF1ZXN0Q29udGV4dCBleHRlbmRzIE13NURlcFxuICAgICAgPyBNdzVEZXBcbiAgICAgIDogbmV2ZXJcbiAgPixcbiAgbXc2OiBNaWRkbGV3YXJlPFxuICAgIE13NlJlcXVlc3RDb250ZXh0LFxuICAgIE13MVJlcXVlc3RDb250ZXh0ICZcbiAgICAgIE13MlJlcXVlc3RDb250ZXh0ICZcbiAgICAgIE13M1JlcXVlc3RDb250ZXh0ICZcbiAgICAgIE13NFJlcXVlc3RDb250ZXh0ICZcbiAgICAgIE13NVJlcXVlc3RDb250ZXh0IGV4dGVuZHMgTXc2RGVwXG4gICAgICA/IE13NkRlcFxuICAgICAgOiBuZXZlclxuICA+LFxuICBtdzc6IE1pZGRsZXdhcmU8XG4gICAgTXc3UmVxdWVzdENvbnRleHQsXG4gICAgTXcxUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXcyUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXczUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXc0UmVxdWVzdENvbnRleHQgJlxuICAgICAgTXc1UmVxdWVzdENvbnRleHQgJlxuICAgICAgTXc2UmVxdWVzdENvbnRleHQgZXh0ZW5kcyBNdzdEZXBcbiAgICAgID8gTXc3RGVwXG4gICAgICA6IG5ldmVyXG4gID4sXG4gIGVuZHBvaW50OiAoXG4gICAgcmVxOiBSZXEgJlxuICAgICAgTXcxUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXcyUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXczUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXc0UmVxdWVzdENvbnRleHQgJlxuICAgICAgTXc1UmVxdWVzdENvbnRleHQgJlxuICAgICAgTXc2UmVxdWVzdENvbnRleHQgJlxuICAgICAgTXc3UmVxdWVzdENvbnRleHQsXG4gICAgcmVzOiBSZXNcbiAgKSA9PiBhbnlcbikgPT4gKHJlcTogUmVxLCByZXM6IFJlcykgPT4gYW55XG5cbnR5cGUgV3JhcHBlcnMgPSBXcmFwcGVyczEgJlxuICBXcmFwcGVyczIgJlxuICBXcmFwcGVyczMgJlxuICBXcmFwcGVyczQgJlxuICBXcmFwcGVyczUgJlxuICBXcmFwcGVyczYgJlxuICBXcmFwcGVyczdcblxuZXhwb3J0IGNvbnN0IHdyYXBwZXJzOiBXcmFwcGVycyA9ICguLi53cmFwcGVyc0FyZ3M6IGFueVtdKSA9PiB7XG4gIGNvbnN0IHdyYXBwZWRGdW5jdGlvbiA9IHdyYXBwZXJzQXJnc1t3cmFwcGVyc0FyZ3MubGVuZ3RoIC0gMV1cbiAgY29uc3QgbXdzID0gd3JhcHBlcnNBcmdzLnNsaWNlKDAsIC0xKVxuXG4gIGxldCBsYXN0V3JhcHBlZEZ1bmN0aW9uID0gd3JhcHBlZEZ1bmN0aW9uXG4gIGZvciAobGV0IGkgPSBtd3MubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBsYXN0V3JhcHBlZEZ1bmN0aW9uID0gKG13c1tpXSBhcyBhbnkpKGxhc3RXcmFwcGVkRnVuY3Rpb24pXG4gIH1cblxuICByZXR1cm4gbGFzdFdyYXBwZWRGdW5jdGlvblxufVxuXG5leHBvcnQgZGVmYXVsdCB3cmFwcGVyc1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FB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QVk7QUFBQSxNQUN6QiwwQkFBMEI7QUFBQSxRQUN4QixpQkFBaUIsQ0FBQyxLQUFLLFVBQVU7QUFDL0IsY0FBSSxRQUFRLElBQUksYUFBYSxjQUFjO0FBQ3pDLG1CQUFPLENBQUM7QUFBQSxVQUNWO0FBRUEsaUJBQU87QUFBQSxRQUNUO0FBQUEsTUFDRjtBQUFBLElBQ0YsQ0FBQztBQUFBLElBQ0QsZ0JBQWdCLFlBQVksY0FDeEI7QUFBQSxNQUNFLElBQUksY0FBRSxRQUFRO0FBQUEsSUFDaEIsSUFDQSxDQUFDO0FBQUEsRUFDUCxJQUFJO0FBRUosUUFBTSxnQkFBZ0IsQ0FBQyxTQUFvQjtBQUN6QyxVQUFNLG9CQUFvQixDQUFDLHVCQUF1QjtBQUNoRCxZQUFNLHFCQUFxQixPQUN6QixLQUNBLFFBQ0c7QUFDSCwwQkFBa0IsVUFBVSxDQUFDLFNBQVM7QUFFdEMsY0FBTSxrQkFBa0Isa0JBQWtCLEtBQUs7QUFDL0MsWUFBSSxDQUFDO0FBQWlCLGdCQUFNLElBQUksTUFBTSxzQkFBc0IsS0FBSyxNQUFNO0FBRXZFLG1CQUFPLGtDQUFBQztBQUFBLFVBQ0wsR0FBSyw4QkFDRCxDQUFDLDJCQUEyQixJQUM1QixDQUFDO0FBQUEsVUFDTCxHQUFLLHFCQUFxQixDQUFDO0FBQUEsVUFDM0I7QUFBQSxVQUNBLEdBQUssS0FBSyxlQUFlLENBQUM7QUFBQSxVQUMxQixxQkFBWSxLQUFLLE9BQU87QUFBQSxVQUN4Qix3QkFBZTtBQUFBLFlBQ2IsVUFBVSxLQUFLO0FBQUEsWUFDZixhQUFhLEtBQUs7QUFBQSxZQUNsQixjQUFjLEtBQUs7QUFBQSxZQUNuQixVQUFVLEtBQUs7QUFBQSxZQUNmLGNBQWMsS0FBSztBQUFBLFlBQ25CO0FBQUEsWUFDQTtBQUFBLFVBQ0YsQ0FBQztBQUFBLFVBQ0Q7QUFBQSxRQUNGLEVBQUUsS0FBWSxHQUFHO0FBQUEsTUFDbkI7QUFFQSx5QkFBbUIsZUFBZTtBQUNsQyx5QkFBbUIsYUFBYTtBQUVoQyxhQUFPO0FBQUEsSUFDVDtBQUVBLHNCQUFrQixlQUFlO0FBQ2pDLHNCQUFrQixhQUFhO0FBRS9CLFdBQU87QUFBQSxFQUNUO0FBRUEsZ0JBQWMsZUFBZTtBQUU3QixTQUFPO0FBQ1Q7OztBRzJNTyxJQUFNQyxZQUFxQixJQUFJLGlCQUF3QjtBQUM1RCxRQUFNLGtCQUFrQixhQUFhLGFBQWEsU0FBUztBQUMzRCxRQUFNLE1BQU0sYUFBYSxNQUFNLEdBQUcsRUFBRTtBQUVwQyxNQUFJLHNCQUFzQjtBQUMxQixXQUFTLElBQUksSUFBSSxTQUFTLEdBQUcsS0FBSyxHQUFHLEtBQUs7QUFDeEMsMEJBQXVCLElBQUksR0FBVyxtQkFBbUI7QUFBQSxFQUMzRDtBQUVBLFNBQU87QUFDVDsiLAogICJuYW1lcyI6IFsid2l0aEV4Y2VwdGlvbkhhbmRsaW5nIiwgIndyYXBwZXJzIiwgIndpdGhFeGNlcHRpb25IYW5kbGluZyIsICJpbXBvcnRfem9kIiwgIndpdGhFeGNlcHRpb25IYW5kbGluZyIsICJ3cmFwcGVycyIsICJ3cmFwcGVycyJdCn0K
492
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzIiwgIi4uL3NyYy9uZXh0anMtZXhjZXB0aW9uLW1pZGRsZXdhcmUvaHR0cC1leGNlcHRpb25zLnRzIiwgIi4uL3NyYy9uZXh0anMtZXhjZXB0aW9uLW1pZGRsZXdhcmUvd2l0aC1leGNlcHRpb24taGFuZGxpbmcudHMiLCAiLi4vc3JjL25leHRqcy1leGNlcHRpb24tbWlkZGxld2FyZS93aXRoLW9rLXN0YXR1cy50cyIsICIuLi9zcmMvbmV4dGpzLWV4Y2VwdGlvbi1taWRkbGV3YXJlL2luZGV4LnRzIiwgIi4uL3NyYy93cmFwcGVycy9pbmRleC50cyIsICIuLi9zcmMvd2l0aC1yb3V0ZS1zcGVjL21pZGRsZXdhcmVzL3dpdGgtbWV0aG9kcy50cyIsICIuLi9zcmMvd2l0aC1yb3V0ZS1zcGVjL21pZGRsZXdhcmVzL3dpdGgtdmFsaWRhdGlvbi50cyIsICIuLi9zcmMvd2l0aC1yb3V0ZS1zcGVjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJleHBvcnQgKiBmcm9tIFwiLi9uZXh0anMtZXhjZXB0aW9uLW1pZGRsZXdhcmVcIlxuZXhwb3J0ICogZnJvbSBcIi4vd2l0aC1yb3V0ZS1zcGVjXCJcbmV4cG9ydCB7IHdyYXBwZXJzIH0gZnJvbSBcIi4vd3JhcHBlcnNcIlxuZXhwb3J0ICogZnJvbSBcIi4vdHlwZXNcIlxuIiwgImV4cG9ydCB0eXBlIEh0dHBFeGNlcHRpb25NZXRhZGF0YSA9IHtcbiAgdHlwZTogc3RyaW5nXG4gIG1lc3NhZ2U6IHN0cmluZ1xuICBkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbn0gJiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuXG5leHBvcnQgaW50ZXJmYWNlIFRocm93aW5nT3B0aW9ucyB7XG4gIGpzb24/OiBib29sZWFuXG59XG5cbi8qKlxuICogVGhyb3cgSHR0cEV4Y2VwdGlvbnMgaW5zaWRlIEFQSSBlbmRwb2ludHMgdG8gZ2VuZXJhdGUgbmljZSBlcnJvciBtZXNzYWdlc1xuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBcbiAqIGlmIChiYWRfc291cHMuaW5jbHVkZXMoc291cF9wYXJhbSkpIHtcbiAqICAgdGhyb3cgbmV3IEh0dHBFeGNlcHRpb24oNDAwLCB7XG4gKiAgICAgIHR5cGU6IFwiY2FudF9tYWtlX3NvdXBcIixcbiAqICAgICAgbWVzc2FnZTogXCJTb3VwIHdhcyB0b28gZGlmZmljdWx0LCBwbGVhc2Ugc3BlY2lmeSBhIGRpZmZlcmVudCBzb3VwXCJcbiAqICAgIH0pXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiovXG5leHBvcnQgY2xhc3MgSHR0cEV4Y2VwdGlvbiBleHRlbmRzIEVycm9yIHtcbiAgb3B0aW9uczogVGhyb3dpbmdPcHRpb25zXG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHN0YXR1czogbnVtYmVyLFxuICAgIHB1YmxpYyBtZXRhZGF0YTogSHR0cEV4Y2VwdGlvbk1ldGFkYXRhLFxuICAgIG9wdGlvbnM/OiBUaHJvd2luZ09wdGlvbnNcbiAgKSB7XG4gICAgc3VwZXIobWV0YWRhdGEubWVzc2FnZSlcblxuICAgIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgdGhpcy5jb25zdHJ1Y3RvcilcbiAgICB9XG5cbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zID8/IHsganNvbjogdHJ1ZSB9XG4gIH1cblxuICB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gYEh0dHBFeGNlcHRpb246ICR7dGhpcy5zdGF0dXN9LCAke3RoaXMubWV0YWRhdGEubWVzc2FnZX0gKCR7dGhpcy5tZXRhZGF0YS50eXBlfSlgXG4gIH1cbn1cblxuLyoqXG4gKiBUaHJvdyBCYWRSZXF1ZXN0RXhjZXB0aW9uIGluc2lkZSBBUEkgZW5kcG9pbnRzIHRoYXQgd2VyZSBwcm92aWRlZCBpbmNvcnJlY3RcbiAqIHBhcmFtZXRlcnMgb3IgYm9keVxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBcbiAqIGlmIChiYWRfc291cHMuaW5jbHVkZXMoc291cF9wYXJhbSkpIHtcbiAqICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oe1xuICogICAgIHR5cGU6IFwiY2FudF9tYWtlX3NvdXBcIixcbiAqICAgICBtZXNzYWdlOiBcIlNvdXAgd2FzIHRvbyBkaWZmaWN1bHQsIHBsZWFzZSBzcGVjaWZ5IGEgZGlmZmVyZW50IHNvdXBcIixcbiAqICAgfSlcbiAqIH1cbiAqIGBgYFxuICpcbiAqKi9cbmV4cG9ydCBjbGFzcyBCYWRSZXF1ZXN0RXhjZXB0aW9uIGV4dGVuZHMgSHR0cEV4Y2VwdGlvbiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBtZXRhZGF0YTogSHR0cEV4Y2VwdGlvbk1ldGFkYXRhLFxuICAgIG9wdGlvbnM/OiBUaHJvd2luZ09wdGlvbnNcbiAgKSB7XG4gICAgc3VwZXIoNDAwLCBtZXRhZGF0YSwgb3B0aW9ucylcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgVW5hdXRob3JpemVkRXhjZXB0aW9uIGV4dGVuZHMgSHR0cEV4Y2VwdGlvbiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBtZXRhZGF0YTogSHR0cEV4Y2VwdGlvbk1ldGFkYXRhLFxuICAgIG9wdGlvbnM/OiBUaHJvd2luZ09wdGlvbnNcbiAgKSB7XG4gICAgc3VwZXIoNDAxLCBtZXRhZGF0YSwgb3B0aW9ucylcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTm90Rm91bmRFeGNlcHRpb24gZXh0ZW5kcyBIdHRwRXhjZXB0aW9uIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIG1ldGFkYXRhOiBIdHRwRXhjZXB0aW9uTWV0YWRhdGEsXG4gICAgb3B0aW9ucz86IFRocm93aW5nT3B0aW9uc1xuICApIHtcbiAgICBzdXBlcig0MDQsIG1ldGFkYXRhLCBvcHRpb25zKVxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBNZXRob2ROb3RBbGxvd2VkRXhjZXB0aW9uIGV4dGVuZHMgSHR0cEV4Y2VwdGlvbiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBtZXRhZGF0YTogSHR0cEV4Y2VwdGlvbk1ldGFkYXRhLFxuICAgIG9wdGlvbnM/OiBUaHJvd2luZ09wdGlvbnNcbiAgKSB7XG4gICAgc3VwZXIoNDA1LCBtZXRhZGF0YSwgb3B0aW9ucylcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgSW50ZXJuYWxTZXJ2ZXJFcnJvckV4Y2VwdGlvbiBleHRlbmRzIEh0dHBFeGNlcHRpb24ge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgbWV0YWRhdGE6IEh0dHBFeGNlcHRpb25NZXRhZGF0YSxcbiAgICBvcHRpb25zPzogVGhyb3dpbmdPcHRpb25zXG4gICkge1xuICAgIHN1cGVyKDUwMCwgbWV0YWRhdGEsIG9wdGlvbnMpXG4gIH1cbn1cbiIsICJpbXBvcnQgeyBOZXh0QXBpUmVxdWVzdCwgTmV4dEFwaVJlc3BvbnNlIH0gZnJvbSBcIm5leHRcIlxuaW1wb3J0IHsgSHR0cEV4Y2VwdGlvbiB9IGZyb20gXCIuL2h0dHAtZXhjZXB0aW9uc1wiXG5cbmV4cG9ydCBpbnRlcmZhY2UgV2l0aEV4Y2VwdGlvbkhhbmRsaW5nT3B0aW9ucyB7XG4gIGdldEVycm9yQ29udGV4dD86IChcbiAgICByZXE6IE5leHRBcGlSZXF1ZXN0LFxuICAgIGVycm9yOiBFcnJvclxuICApID0+IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG59XG5cbmNvbnN0IHdpdGhFeGNlcHRpb25IYW5kbGluZyA9XG4gIChvcHRpb25zOiBXaXRoRXhjZXB0aW9uSGFuZGxpbmdPcHRpb25zID0ge30pID0+XG4gIChuZXh0OiAocmVxOiBOZXh0QXBpUmVxdWVzdCwgcmVzOiBOZXh0QXBpUmVzcG9uc2UpID0+IFByb21pc2U8dm9pZD4pID0+XG4gIGFzeW5jIChyZXE6IE5leHRBcGlSZXF1ZXN0LCByZXM6IE5leHRBcGlSZXNwb25zZSkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBuZXh0KHJlcSwgcmVzKVxuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICBsZXQgZXJyb3JDb250ZXh0OiBhbnkgPSB7fVxuXG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICBlcnJvckNvbnRleHQuc3RhY2sgPSBlcnJvci5zdGFja1xuICAgICAgfVxuXG4gICAgICBlcnJvckNvbnRleHQgPSBvcHRpb25zLmdldEVycm9yQ29udGV4dFxuICAgICAgICA/IG9wdGlvbnMuZ2V0RXJyb3JDb250ZXh0KHJlcSwgZXJyb3JDb250ZXh0KVxuICAgICAgICA6IGVycm9yQ29udGV4dFxuXG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBIdHRwRXhjZXB0aW9uKSB7XG4gICAgICAgIGlmIChlcnJvci5vcHRpb25zLmpzb24pIHtcbiAgICAgICAgICByZXMuc3RhdHVzKGVycm9yLnN0YXR1cykuanNvbih7XG4gICAgICAgICAgICBlcnJvcjoge1xuICAgICAgICAgICAgICAuLi5lcnJvci5tZXRhZGF0YSxcbiAgICAgICAgICAgICAgLi4uZXJyb3JDb250ZXh0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlcy5zdGF0dXMoZXJyb3Iuc3RhdHVzKS5lbmQoZXJyb3IubWV0YWRhdGEubWVzc2FnZSlcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgZm9ybWF0dGVkRXJyb3IgPSBuZXcgSHR0cEV4Y2VwdGlvbig1MDAsIHtcbiAgICAgICAgICB0eXBlOiBcImludGVybmFsX3NlcnZlcl9lcnJvclwiLFxuICAgICAgICAgIG1lc3NhZ2U6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogXCJVbmtub3duIGVycm9yXCIsXG4gICAgICAgIH0pXG5cbiAgICAgICAgcmVzLnN0YXR1cyg1MDApLmpzb24oe1xuICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICAuLi5mb3JtYXR0ZWRFcnJvci5tZXRhZGF0YSxcbiAgICAgICAgICAgIC4uLmVycm9yQ29udGV4dCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuZXhwb3J0IGRlZmF1bHQgd2l0aEV4Y2VwdGlvbkhhbmRsaW5nXG4iLCAiaW1wb3J0IHsgTmV4dEFwaVJlcXVlc3QsIE5leHRBcGlSZXNwb25zZSB9IGZyb20gXCJuZXh0XCJcblxuZXhwb3J0IGludGVyZmFjZSBXaXRoT2tTdGF0dXNPcHRpb25zIHtcbiAgYWRkSWY/OiAocmVxOiBOZXh0QXBpUmVxdWVzdCkgPT4gYm9vbGVhblxufVxuXG5jb25zdCB3aXRoT2tTdGF0dXMgPVxuICAob3B0aW9uczogV2l0aE9rU3RhdHVzT3B0aW9ucyA9IHt9KSA9PlxuICAobmV4dDogKHJlcTogTmV4dEFwaVJlcXVlc3QsIHJlczogTmV4dEFwaVJlc3BvbnNlKSA9PiBQcm9taXNlPHZvaWQ+KSA9PlxuICBhc3luYyAocmVxOiBOZXh0QXBpUmVxdWVzdCwgcmVzOiBOZXh0QXBpUmVzcG9uc2UpID0+IHtcbiAgICAvLyBQYXRjaCAuanNvbigpXG4gICAgY29uc3Qgb3JpZ2luYWxKc29uID0gcmVzLmpzb25cblxuICAgIHJlcy5qc29uID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgIGNvbnN0IG9rID0gcmVzLnN0YXR1c0NvZGUgPj0gMjAwICYmIHJlcy5zdGF0dXNDb2RlIDwgMzAwXG4gICAgICBjb25zdCBzaG91bGRJbmNsdWRlU3RhdHVzID0gb3B0aW9ucy5hZGRJZiA/IG9wdGlvbnMuYWRkSWYocmVxKSA6IHRydWVcblxuICAgICAgaWYgKHNob3VsZEluY2x1ZGVTdGF0dXMpIHtcbiAgICAgICAgb3JpZ2luYWxKc29uLmNhbGwodGhpcywge1xuICAgICAgICAgIC4uLmRhdGEsXG4gICAgICAgICAgb2ssXG4gICAgICAgIH0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcmlnaW5hbEpzb24uY2FsbCh0aGlzLCBkYXRhKVxuICAgICAgfVxuICAgIH1cblxuICAgIGF3YWl0IG5leHQocmVxLCByZXMpXG4gIH1cblxuZXhwb3J0IGRlZmF1bHQgd2l0aE9rU3RhdHVzXG4iLCAiaW1wb3J0IHsgTmV4dEFwaVJlcXVlc3QsIE5leHRBcGlSZXNwb25zZSB9IGZyb20gXCJuZXh0XCJcbmltcG9ydCB1bndyYXBwZWRXaXRoRXhjZXB0aW9uSGFuZGxpbmcsIHtcbiAgV2l0aEV4Y2VwdGlvbkhhbmRsaW5nT3B0aW9ucyxcbn0gZnJvbSBcIi4vd2l0aC1leGNlcHRpb24taGFuZGxpbmdcIlxuaW1wb3J0IHdpdGhPa1N0YXR1cywgeyBXaXRoT2tTdGF0dXNPcHRpb25zIH0gZnJvbSBcIi4vd2l0aC1vay1zdGF0dXNcIlxuXG5leHBvcnQgaW50ZXJmYWNlIEV4Y2VwdGlvbkhhbmRsaW5nT3B0aW9ucyB7XG4gIGFkZE9rU3RhdHVzPzogYm9vbGVhblxuICBva1N0YXR1c09wdGlvbnM/OiBXaXRoT2tTdGF0dXNPcHRpb25zXG4gIGV4Y2VwdGlvbkhhbmRsaW5nT3B0aW9ucz86IFdpdGhFeGNlcHRpb25IYW5kbGluZ09wdGlvbnNcbn1cblxuZXhwb3J0IGNvbnN0IHdpdGhFeGNlcHRpb25IYW5kbGluZyA9XG4gICh7XG4gICAgYWRkT2tTdGF0dXMgPSBmYWxzZSxcbiAgICBva1N0YXR1c09wdGlvbnMsXG4gICAgZXhjZXB0aW9uSGFuZGxpbmdPcHRpb25zLFxuICB9OiBFeGNlcHRpb25IYW5kbGluZ09wdGlvbnMgPSB7fSkgPT5cbiAgKG5leHQ6IChyZXE6IE5leHRBcGlSZXF1ZXN0LCByZXM6IE5leHRBcGlSZXNwb25zZSkgPT4gUHJvbWlzZTx2b2lkPikgPT5cbiAgKHJlcTogTmV4dEFwaVJlcXVlc3QsIHJlczogTmV4dEFwaVJlc3BvbnNlKSA9PiB7XG4gICAgaWYgKGFkZE9rU3RhdHVzKSB7XG4gICAgICByZXR1cm4gd2l0aE9rU3RhdHVzKG9rU3RhdHVzT3B0aW9ucykoXG4gICAgICAgIHVud3JhcHBlZFdpdGhFeGNlcHRpb25IYW5kbGluZyhleGNlcHRpb25IYW5kbGluZ09wdGlvbnMpKG5leHQpXG4gICAgICApKHJlcSwgcmVzKVxuICAgIH1cblxuICAgIHJldHVybiB1bndyYXBwZWRXaXRoRXhjZXB0aW9uSGFuZGxpbmcoZXhjZXB0aW9uSGFuZGxpbmdPcHRpb25zKShuZXh0KShcbiAgICAgIHJlcSxcbiAgICAgIHJlc1xuICAgIClcbiAgfVxuXG5leHBvcnQgKiBmcm9tIFwiLi9odHRwLWV4Y2VwdGlvbnNcIlxuIiwgImltcG9ydCB0eXBlIHsgTmV4dEFwaVJlcXVlc3QgYXMgUmVxLCBOZXh0QXBpUmVzcG9uc2UgYXMgUmVzIH0gZnJvbSBcIm5leHRcIlxuLypcblxuV3JhcHMgYSBmdW5jdGlvbiBpbiBsYXllcnMgb2Ygb3RoZXIgZnVuY3Rpb25zLCB3aGlsZSBwcmVzZXJ2aW5nIHRoZSBpbnB1dC9vdXRwdXRcbnR5cGUuIFRoZSBvdXRwdXQgb2Ygd3JhcHBlcnMgd2lsbCBhbHdheXMgaGF2ZSB0aGUgdHlwZSBvZiBpdCdzIGxhc3QgcGFyYW1ldGVyXG4odGhlIHdyYXBwZWQgZnVuY3Rpb24pXG5cblRoaXMgZnVuY3Rpb24gdHVybnMgdGhpcyB0eXBlIG9mIGNvbXBvc2l0aW9uLi4uXG5cbmxvZ2dlci53aXRoQ29udGV4dChcInNvbWVjb250ZXh0XCIpKFxuICBhc3luYyAoYSwgYikgPT4ge1xuICAgIHJldHVybiBhXG4gIH1cbilcblxuSW50by4uLlxuXG53cmFwcGVycyhcbiAgbG9nZ2VyLndpdGhDb250ZXh0KFwic29tZWNvbnRleHRcIiksXG4gIGFzeW5jIChhLCBiKSA9PiB7XG4gICAgcmV0dXJuIGFcbiAgfVxuKVxuXG5IYXZpbmcgdGhpcyBhcyBhIHV0aWxpdHkgbWV0aG9kIGhlbHBzIHByZXNlcnZlIHR5cGVzLCB3aGljaCBvdGhlcndpc2UgY2FuIGdldFxubWVzc2VkIHVwIGJ5IHRoZSBtaWRkbGV3YXJlcy4gSXQgYWxzbyBjYW4gbWFrZSB0aGUgY29kZSBjbGVhbmVyIHdoZXJlIHRoZXJlIGFyZVxubXVsdGlwbGUgd3JhcHBlcnMuXG5cbiMjIEVYQU1QTEVTXG5cbkluIHRoZSBjb250ZXh0IG9mIHJlcXVlc3QgbWlkZGxld2FyZSB5b3UgbWlnaHQgd3JpdGUgc29tZXRoaW5nIGxpa2UgdGhpcy4uLlxuXG5jb25zdCB3aXRoUmVxdWVzdExvZ2dpbmdNaWRkbGV3YXJlID0gKG5leHQpID0+IGFzeW5jIChyZXEsIHJlcykgPT4ge1xuICBjb25zb2xlLmxvZyhgR09UIFJFUVVFU1QgJHtyZXEubWV0aG9kfSAke3JlcS5wYXRofWApXG4gIHJldHVybiBuZXh0KHJlcSwgcmVzKVxufVxuXG5IZXJlJ3MgYW4gZXhhbXBsZSBvZiBhIHdyYXBwZXIgdGhhdCB0YWtlcyBzb21lIHBhcmFtZXRlcnMuLi5cblxuY29uc3Qgd2l0aExvZ2dlZEFyZ3VtZW50cyA9XG4gICAgKGxvZ1ByZWZpeDogc3RyaW5nKSA9PlxuICAgIChuZXh0KSA9PlxuICAgIGFzeW5jICguLi5mdW5jQXJncykgPT4ge1xuICAgICAgY29uc29sZS5sb2cobG9nUHJlZml4LCAuLi5mdW5jQXJncylcbiAgICAgIHJldHVybiBuZXh0KC4uLmZ1bmNBcmdzKVxuICAgIH1cblxuKi9cblxuZXhwb3J0IHR5cGUgTWlkZGxld2FyZTxULCBEZXAgPSB7fT4gPSAoXG4gIG5leHQ6IChyZXE6IFJlcSAmIERlcCAmIFQsIHJlczogUmVzKSA9PiBhbnlcbikgPT4gKHJlcTogUmVxICYgRGVwICYgVCwgcmVzOiBSZXMpID0+IGFueVxuXG4vLyBTYWZlciBNaWRkbGV3YXJlIHJlcXVpcmVzIHRoZSB1c2Ugb2YgZXh0ZW5kUmVxdWVzdCB0byBlbnN1cmUgdGhhdCB0aGVcbi8vIG5ldyBjb250ZXh0IChUKSB3YXMgYWN0dWFsbHkgYWRkZWQgdG8gdGhlIHJlcXVlc3QuIEl0J3Mga2luZCBvZiBhbm5veWluZ1xuLy8gdG8gdXNlIGluIHByYWN0aWNlLCBzbyB3ZSBkb24ndCB1c2UgaXQgZm9yIG91ciBXcmFwcGVycyAoeWV0KVxuZXhwb3J0IHR5cGUgU2FmZXJNaWRkbGV3YXJlPFQsIERlcCA9IHt9PiA9IChcbiAgbmV4dDogKHJlcTogUmVxICYgRGVwICYgVCwgcmVzOiBSZXMpID0+IGFueVxuKSA9PiAocmVxOiBSZXEgJiBEZXAsIHJlczogUmVzKSA9PiBhbnlcblxuZXhwb3J0IGNvbnN0IGV4dGVuZFJlcXVlc3QgPSA8VCBleHRlbmRzIFJlcSwgSyBleHRlbmRzIHt9PihcbiAgcmVxOiBULFxuICBtZXJnZTogS1xuKTogVCAmIEsgPT4ge1xuICBmb3IgKGNvbnN0IFtrZXksIHZdIG9mIE9iamVjdC5lbnRyaWVzKG1lcmdlKSkge1xuICAgIDsocmVxIGFzIGFueSlba2V5XSA9IHZcbiAgfVxuICByZXR1cm4gcmVxIGFzIGFueVxufVxuXG50eXBlIFdyYXBwZXJzMSA9IDxNdzFSZXF1ZXN0Q29udGV4dCwgTXcxRGVwPihcbiAgbXcxOiBNaWRkbGV3YXJlPE13MVJlcXVlc3RDb250ZXh0LCBNdzFEZXA+LFxuICBlbmRwb2ludDogKHJlcTogUmVxICYgTXcxUmVxdWVzdENvbnRleHQsIHJlczogUmVzKSA9PiBhbnlcbikgPT4gKHJlcTogUmVxLCByZXM6IFJlcykgPT4gYW55XG5cbnR5cGUgV3JhcHBlcnMyID0gPFxuICBNdzFSZXF1ZXN0Q29udGV4dCBleHRlbmRzIE13MkRlcCxcbiAgTXcxRGVwLFxuICBNdzJSZXF1ZXN0Q29udGV4dCxcbiAgTXcyRGVwXG4+KFxuICBtdzE6IE1pZGRsZXdhcmU8TXcxUmVxdWVzdENvbnRleHQsIE13MURlcD4sXG4gIG13MjogTWlkZGxld2FyZTxNdzJSZXF1ZXN0Q29udGV4dCwgTXcyRGVwPixcbiAgZW5kcG9pbnQ6IChyZXE6IFJlcSAmIE13MVJlcXVlc3RDb250ZXh0ICYgTXcyUmVxdWVzdENvbnRleHQsIHJlczogUmVzKSA9PiBhbnlcbikgPT4gKHJlcTogUmVxLCByZXM6IFJlcykgPT4gYW55XG5cbi8vIFRPRE8gZmlndXJlIG91dCBob3cgdG8gZG8gYSByZWN1cnNpdmUgZGVmaW5pdGlvbiwgb3Igb25lIHRoYXQgc2ltcGxpZmllc1xuLy8gdGhlc2UgcmVkdW5kYW50IHdyYXBwZXJzXG5cbnR5cGUgV3JhcHBlcnMzID0gPFxuICBNdzFSZXF1ZXN0Q29udGV4dCBleHRlbmRzIE13MkRlcCxcbiAgTXcxRGVwLFxuICBNdzJSZXF1ZXN0Q29udGV4dCxcbiAgTXcyRGVwLFxuICBNdzNSZXF1ZXN0Q29udGV4dCxcbiAgTXczRGVwXG4+KFxuICBtdzE6IE1pZGRsZXdhcmU8TXcxUmVxdWVzdENvbnRleHQsIE13MURlcD4sXG4gIG13MjogTWlkZGxld2FyZTxNdzJSZXF1ZXN0Q29udGV4dCwgTXcyRGVwPixcbiAgbXczOiBNaWRkbGV3YXJlPFxuICAgIE13M1JlcXVlc3RDb250ZXh0LFxuICAgIE13MVJlcXVlc3RDb250ZXh0ICYgTXcyUmVxdWVzdENvbnRleHQgZXh0ZW5kcyBNdzNEZXAgPyBNdzNEZXAgOiBuZXZlclxuICA+LFxuICBlbmRwb2ludDogKFxuICAgIHJlcTogUmVxICYgTXcxUmVxdWVzdENvbnRleHQgJiBNdzJSZXF1ZXN0Q29udGV4dCAmIE13M1JlcXVlc3RDb250ZXh0LFxuICAgIHJlczogUmVzXG4gICkgPT4gYW55XG4pID0+IChyZXE6IFJlcSwgcmVzOiBSZXMpID0+IGFueVxuXG50eXBlIFdyYXBwZXJzNCA9IDxcbiAgTXcxUmVxdWVzdENvbnRleHQgZXh0ZW5kcyBNdzJEZXAsXG4gIE13MURlcCxcbiAgTXcyUmVxdWVzdENvbnRleHQsXG4gIE13MkRlcCxcbiAgTXczUmVxdWVzdENvbnRleHQsXG4gIE13M0RlcCxcbiAgTXc0UmVxdWVzdENvbnRleHQsXG4gIE13NERlcFxuPihcbiAgbXcxOiBNaWRkbGV3YXJlPE13MVJlcXVlc3RDb250ZXh0LCBNdzFEZXA+LFxuICBtdzI6IE1pZGRsZXdhcmU8TXcyUmVxdWVzdENvbnRleHQsIE13MkRlcD4sXG4gIG13MzogTWlkZGxld2FyZTxcbiAgICBNdzNSZXF1ZXN0Q29udGV4dCxcbiAgICBNdzFSZXF1ZXN0Q29udGV4dCAmIE13MlJlcXVlc3RDb250ZXh0IGV4dGVuZHMgTXczRGVwID8gTXczRGVwIDogbmV2ZXJcbiAgPixcbiAgbXc0OiBNaWRkbGV3YXJlPFxuICAgIE13NFJlcXVlc3RDb250ZXh0LFxuICAgIE13MVJlcXVlc3RDb250ZXh0ICYgTXcyUmVxdWVzdENvbnRleHQgJiBNdzNSZXF1ZXN0Q29udGV4dCBleHRlbmRzIE13NERlcFxuICAgICAgPyBNdzREZXBcbiAgICAgIDogbmV2ZXJcbiAgPixcbiAgZW5kcG9pbnQ6IChcbiAgICByZXE6IFJlcSAmXG4gICAgICBNdzFSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzJSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzNSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzRSZXF1ZXN0Q29udGV4dCxcbiAgICByZXM6IFJlc1xuICApID0+IGFueVxuKSA9PiAocmVxOiBSZXEsIHJlczogUmVzKSA9PiBhbnlcblxudHlwZSBXcmFwcGVyczUgPSA8XG4gIE13MVJlcXVlc3RDb250ZXh0IGV4dGVuZHMgTXcyRGVwLFxuICBNdzFEZXAsXG4gIE13MlJlcXVlc3RDb250ZXh0LFxuICBNdzJEZXAsXG4gIE13M1JlcXVlc3RDb250ZXh0LFxuICBNdzNEZXAsXG4gIE13NFJlcXVlc3RDb250ZXh0LFxuICBNdzREZXAsXG4gIE13NVJlcXVlc3RDb250ZXh0LFxuICBNdzVEZXBcbj4oXG4gIG13MTogTWlkZGxld2FyZTxNdzFSZXF1ZXN0Q29udGV4dCwgTXcxRGVwPixcbiAgbXcyOiBNaWRkbGV3YXJlPE13MlJlcXVlc3RDb250ZXh0LCBNdzJEZXA+LFxuICBtdzM6IE1pZGRsZXdhcmU8XG4gICAgTXczUmVxdWVzdENvbnRleHQsXG4gICAgTXcxUmVxdWVzdENvbnRleHQgJiBNdzJSZXF1ZXN0Q29udGV4dCBleHRlbmRzIE13M0RlcCA/IE13M0RlcCA6IG5ldmVyXG4gID4sXG4gIG13NDogTWlkZGxld2FyZTxcbiAgICBNdzRSZXF1ZXN0Q29udGV4dCxcbiAgICBNdzFSZXF1ZXN0Q29udGV4dCAmIE13MlJlcXVlc3RDb250ZXh0ICYgTXczUmVxdWVzdENvbnRleHQgZXh0ZW5kcyBNdzREZXBcbiAgICAgID8gTXc0RGVwXG4gICAgICA6IG5ldmVyXG4gID4sXG4gIG13NTogTWlkZGxld2FyZTxcbiAgICBNdzVSZXF1ZXN0Q29udGV4dCxcbiAgICBNdzFSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzJSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzNSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzRSZXF1ZXN0Q29udGV4dCBleHRlbmRzIE13NURlcFxuICAgICAgPyBNdzVEZXBcbiAgICAgIDogbmV2ZXJcbiAgPixcbiAgZW5kcG9pbnQ6IChcbiAgICByZXE6IFJlcSAmXG4gICAgICBNdzFSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzJSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzNSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzRSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzVSZXF1ZXN0Q29udGV4dCxcbiAgICByZXM6IFJlc1xuICApID0+IGFueVxuKSA9PiAocmVxOiBSZXEsIHJlczogUmVzKSA9PiBhbnlcblxudHlwZSBXcmFwcGVyczYgPSA8XG4gIE13MVJlcXVlc3RDb250ZXh0IGV4dGVuZHMgTXcyRGVwLFxuICBNdzFEZXAsXG4gIE13MlJlcXVlc3RDb250ZXh0LFxuICBNdzJEZXAsXG4gIE13M1JlcXVlc3RDb250ZXh0LFxuICBNdzNEZXAsXG4gIE13NFJlcXVlc3RDb250ZXh0LFxuICBNdzREZXAsXG4gIE13NVJlcXVlc3RDb250ZXh0LFxuICBNdzVEZXAsXG4gIE13NlJlcXVlc3RDb250ZXh0LFxuICBNdzZEZXBcbj4oXG4gIG13MTogTWlkZGxld2FyZTxNdzFSZXF1ZXN0Q29udGV4dCwgTXcxRGVwPixcbiAgbXcyOiBNaWRkbGV3YXJlPE13MlJlcXVlc3RDb250ZXh0LCBNdzJEZXA+LFxuICBtdzM6IE1pZGRsZXdhcmU8XG4gICAgTXczUmVxdWVzdENvbnRleHQsXG4gICAgTXcxUmVxdWVzdENvbnRleHQgJiBNdzJSZXF1ZXN0Q29udGV4dCBleHRlbmRzIE13M0RlcCA/IE13M0RlcCA6IG5ldmVyXG4gID4sXG4gIG13NDogTWlkZGxld2FyZTxcbiAgICBNdzRSZXF1ZXN0Q29udGV4dCxcbiAgICBNdzFSZXF1ZXN0Q29udGV4dCAmIE13MlJlcXVlc3RDb250ZXh0ICYgTXczUmVxdWVzdENvbnRleHQgZXh0ZW5kcyBNdzREZXBcbiAgICAgID8gTXc0RGVwXG4gICAgICA6IG5ldmVyXG4gID4sXG4gIG13NTogTWlkZGxld2FyZTxcbiAgICBNdzVSZXF1ZXN0Q29udGV4dCxcbiAgICBNdzFSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzJSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzNSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzRSZXF1ZXN0Q29udGV4dCBleHRlbmRzIE13NURlcFxuICAgICAgPyBNdzVEZXBcbiAgICAgIDogbmV2ZXJcbiAgPixcbiAgbXc2OiBNaWRkbGV3YXJlPFxuICAgIE13NlJlcXVlc3RDb250ZXh0LFxuICAgIE13MVJlcXVlc3RDb250ZXh0ICZcbiAgICAgIE13MlJlcXVlc3RDb250ZXh0ICZcbiAgICAgIE13M1JlcXVlc3RDb250ZXh0ICZcbiAgICAgIE13NFJlcXVlc3RDb250ZXh0ICZcbiAgICAgIE13NVJlcXVlc3RDb250ZXh0IGV4dGVuZHMgTXc2RGVwXG4gICAgICA/IE13NkRlcFxuICAgICAgOiBuZXZlclxuICA+LFxuICBlbmRwb2ludDogKFxuICAgIHJlcTogUmVxICZcbiAgICAgIE13MVJlcXVlc3RDb250ZXh0ICZcbiAgICAgIE13MlJlcXVlc3RDb250ZXh0ICZcbiAgICAgIE13M1JlcXVlc3RDb250ZXh0ICZcbiAgICAgIE13NFJlcXVlc3RDb250ZXh0ICZcbiAgICAgIE13NVJlcXVlc3RDb250ZXh0ICZcbiAgICAgIE13NlJlcXVlc3RDb250ZXh0LFxuICAgIHJlczogUmVzXG4gICkgPT4gYW55XG4pID0+IChyZXE6IFJlcSwgcmVzOiBSZXMpID0+IGFueVxuXG50eXBlIFdyYXBwZXJzNyA9IDxcbiAgTXcxUmVxdWVzdENvbnRleHQgZXh0ZW5kcyBNdzJEZXAsXG4gIE13MURlcCxcbiAgTXcyUmVxdWVzdENvbnRleHQsXG4gIE13MkRlcCxcbiAgTXczUmVxdWVzdENvbnRleHQsXG4gIE13M0RlcCxcbiAgTXc0UmVxdWVzdENvbnRleHQsXG4gIE13NERlcCxcbiAgTXc1UmVxdWVzdENvbnRleHQsXG4gIE13NURlcCxcbiAgTXc2UmVxdWVzdENvbnRleHQsXG4gIE13NkRlcCxcbiAgTXc3UmVxdWVzdENvbnRleHQsXG4gIE13N0RlcFxuPihcbiAgbXcxOiBNaWRkbGV3YXJlPE13MVJlcXVlc3RDb250ZXh0LCBNdzFEZXA+LFxuICBtdzI6IE1pZGRsZXdhcmU8TXcyUmVxdWVzdENvbnRleHQsIE13MkRlcD4sXG4gIG13MzogTWlkZGxld2FyZTxcbiAgICBNdzNSZXF1ZXN0Q29udGV4dCxcbiAgICBNdzFSZXF1ZXN0Q29udGV4dCAmIE13MlJlcXVlc3RDb250ZXh0IGV4dGVuZHMgTXczRGVwID8gTXczRGVwIDogbmV2ZXJcbiAgPixcbiAgbXc0OiBNaWRkbGV3YXJlPFxuICAgIE13NFJlcXVlc3RDb250ZXh0LFxuICAgIE13MVJlcXVlc3RDb250ZXh0ICYgTXcyUmVxdWVzdENvbnRleHQgJiBNdzNSZXF1ZXN0Q29udGV4dCBleHRlbmRzIE13NERlcFxuICAgICAgPyBNdzREZXBcbiAgICAgIDogbmV2ZXJcbiAgPixcbiAgbXc1OiBNaWRkbGV3YXJlPFxuICAgIE13NVJlcXVlc3RDb250ZXh0LFxuICAgIE13MVJlcXVlc3RDb250ZXh0ICZcbiAgICAgIE13MlJlcXVlc3RDb250ZXh0ICZcbiAgICAgIE13M1JlcXVlc3RDb250ZXh0ICZcbiAgICAgIE13NFJlcXVlc3RDb250ZXh0IGV4dGVuZHMgTXc1RGVwXG4gICAgICA/IE13NURlcFxuICAgICAgOiBuZXZlclxuICA+LFxuICBtdzY6IE1pZGRsZXdhcmU8XG4gICAgTXc2UmVxdWVzdENvbnRleHQsXG4gICAgTXcxUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXcyUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXczUmVxdWVzdENvbnRleHQgJlxuICAgICAgTXc0UmVxdWVzdENvbnRleHQgJlxuICAgICAgTXc1UmVxdWVzdENvbnRleHQgZXh0ZW5kcyBNdzZEZXBcbiAgICAgID8gTXc2RGVwXG4gICAgICA6IG5ldmVyXG4gID4sXG4gIG13NzogTWlkZGxld2FyZTxcbiAgICBNdzdSZXF1ZXN0Q29udGV4dCxcbiAgICBNdzFSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzJSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzNSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzRSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzVSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzZSZXF1ZXN0Q29udGV4dCBleHRlbmRzIE13N0RlcFxuICAgICAgPyBNdzdEZXBcbiAgICAgIDogbmV2ZXJcbiAgPixcbiAgZW5kcG9pbnQ6IChcbiAgICByZXE6IFJlcSAmXG4gICAgICBNdzFSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzJSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzNSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzRSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzVSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzZSZXF1ZXN0Q29udGV4dCAmXG4gICAgICBNdzdSZXF1ZXN0Q29udGV4dCxcbiAgICByZXM6IFJlc1xuICApID0+IGFueVxuKSA9PiAocmVxOiBSZXEsIHJlczogUmVzKSA9PiBhbnlcblxudHlwZSBXcmFwcGVycyA9IFdyYXBwZXJzMSAmXG4gIFdyYXBwZXJzMiAmXG4gIFdyYXBwZXJzMyAmXG4gIFdyYXBwZXJzNCAmXG4gIFdyYXBwZXJzNSAmXG4gIFdyYXBwZXJzNiAmXG4gIFdyYXBwZXJzN1xuXG5leHBvcnQgY29uc3Qgd3JhcHBlcnM6IFdyYXBwZXJzID0gKC4uLndyYXBwZXJzQXJnczogYW55W10pID0+IHtcbiAgY29uc3Qgd3JhcHBlZEZ1bmN0aW9uID0gd3JhcHBlcnNBcmdzW3dyYXBwZXJzQXJncy5sZW5ndGggLSAxXVxuICBjb25zdCBtd3MgPSB3cmFwcGVyc0FyZ3Muc2xpY2UoMCwgLTEpXG5cbiAgbGV0IGxhc3RXcmFwcGVkRnVuY3Rpb24gPSB3cmFwcGVkRnVuY3Rpb25cbiAgZm9yIChsZXQgaSA9IG13cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGxhc3RXcmFwcGVkRnVuY3Rpb24gPSAobXdzW2ldIGFzIGFueSkobGFzdFdyYXBwZWRGdW5jdGlvbilcbiAgfVxuXG4gIHJldHVybiBsYXN0V3JhcHBlZEZ1bmN0aW9uXG59XG5cbmV4cG9ydCBkZWZhdWx0IHdyYXBwZXJzXG4iLCAiaW1wb3J0IHsgTWV0aG9kTm90QWxsb3dlZEV4Y2VwdGlvbiB9IGZyb20gXCIuLi8uLi9uZXh0anMtZXhjZXB0aW9uLW1pZGRsZXdhcmVcIlxuXG5leHBvcnQgdHlwZSBIVFRQTWV0aG9kcyA9XG4gIHwgXCJHRVRcIlxuICB8IFwiUE9TVFwiXG4gIHwgXCJERUxFVEVcIlxuICB8IFwiUFVUXCJcbiAgfCBcIlBBVENIXCJcbiAgfCBcIkhFQURcIlxuICB8IFwiT1BUSU9OU1wiXG5cbmV4cG9ydCBjb25zdCB3aXRoTWV0aG9kcyA9IChtZXRob2RzOiBIVFRQTWV0aG9kc1tdKSA9PiAobmV4dCkgPT4gKHJlcSwgcmVzKSA9PiB7XG4gIGlmICghbWV0aG9kcy5pbmNsdWRlcyhyZXEubWV0aG9kKSkge1xuICAgIHRocm93IG5ldyBNZXRob2ROb3RBbGxvd2VkRXhjZXB0aW9uKHtcbiAgICAgIHR5cGU6IFwibWV0aG9kX25vdF9hbGxvd2VkXCIsXG4gICAgICBtZXNzYWdlOiBgb25seSAke21ldGhvZHMuam9pbihcIixcIil9IGFjY2VwdGVkYCxcbiAgICB9KVxuICB9XG4gIHJldHVybiBuZXh0KHJlcSwgcmVzKVxufVxuXG5leHBvcnQgZGVmYXVsdCB3aXRoTWV0aG9kc1xuIiwgImltcG9ydCB0eXBlIHsgTmV4dEFwaVJlcXVlc3QsIE5leHRBcGlSZXNwb25zZSB9IGZyb20gXCJuZXh0XCJcbmltcG9ydCB7IHosIFpvZEZpcnN0UGFydHlUeXBlS2luZCB9IGZyb20gXCJ6b2RcIlxuaW1wb3J0IF8gZnJvbSBcImxvZGFzaFwiXG5cbmltcG9ydCB7XG4gIEJhZFJlcXVlc3RFeGNlcHRpb24sXG4gIEludGVybmFsU2VydmVyRXJyb3JFeGNlcHRpb24sXG59IGZyb20gXCIuLi8uLi9uZXh0anMtZXhjZXB0aW9uLW1pZGRsZXdhcmVcIlxuaW1wb3J0IHsgUXVlcnlBcnJheUZvcm1hdCB9IGZyb20gXCIuLi8uLi90eXBlc1wiXG5pbXBvcnQgeyBERUZBVUxUX0FSUkFZX0ZPUk1BVFMgfSBmcm9tIFwiLi5cIlxuXG5jb25zdCBnZXRab2RPYmplY3RTY2hlbWFGcm9tWm9kRWZmZWN0U2NoZW1hID0gKFxuICBpc1pvZEVmZmVjdDogYm9vbGVhbixcbiAgc2NoZW1hOiB6LlpvZFR5cGVBbnlcbik6IHouWm9kVHlwZUFueSB8IHouWm9kT2JqZWN0PGFueT4gPT4ge1xuICBpZiAoIWlzWm9kRWZmZWN0KSB7XG4gICAgcmV0dXJuIHNjaGVtYSBhcyB6LlpvZE9iamVjdDxhbnk+XG4gIH1cblxuICBsZXQgY3VycmVudFNjaGVtYSA9IHNjaGVtYVxuXG4gIHdoaWxlIChjdXJyZW50U2NoZW1hIGluc3RhbmNlb2Ygei5ab2RFZmZlY3RzKSB7XG4gICAgY3VycmVudFNjaGVtYSA9IGN1cnJlbnRTY2hlbWEuX2RlZi5zY2hlbWFcbiAgfVxuXG4gIHJldHVybiBjdXJyZW50U2NoZW1hIGFzIHouWm9kT2JqZWN0PGFueT5cbn1cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZ2V0IHRoZSBjb3JyZWN0IHNjaGVtYSBmcm9tIGEgWm9kRWZmZWN0IHwgWm9kRGVmYXVsdCB8IFpvZE9wdGlvbmFsIHNjaGVtYS5cbiAqIFRPRE86IHRoaXMgZnVuY3Rpb24gc2hvdWxkIGhhbmRsZSBhbGwgc3BlY2lhbCBjYXNlcyBvZiBab2RTY2hlbWEgYW5kIG5vdCBqdXN0IFpvZEVmZmVjdCB8IFpvZERlZmF1bHQgfCBab2RPcHRpb25hbFxuICovXG5jb25zdCBnZXRab2REZWZGcm9tWm9kU2NoZW1hSGVscGVycyA9IChzY2hlbWE6IHouWm9kVHlwZUFueSkgPT4ge1xuICBjb25zdCBzcGVjaWFsX3pvZF90eXBlcyA9IFtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kT3B0aW9uYWwsXG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZERlZmF1bHQsXG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMsXG4gIF1cblxuICB3aGlsZSAoc3BlY2lhbF96b2RfdHlwZXMuaW5jbHVkZXMoc2NoZW1hLl9kZWYudHlwZU5hbWUpKSB7XG4gICAgaWYgKFxuICAgICAgc2NoZW1hLl9kZWYudHlwZU5hbWUgPT09IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPcHRpb25hbCB8fFxuICAgICAgc2NoZW1hLl9kZWYudHlwZU5hbWUgPT09IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2REZWZhdWx0XG4gICAgKSB7XG4gICAgICBzY2hlbWEgPSBzY2hlbWEuX2RlZi5pbm5lclR5cGVcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgaWYgKHNjaGVtYS5fZGVmLnR5cGVOYW1lID09PSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRWZmZWN0cykge1xuICAgICAgc2NoZW1hID0gc2NoZW1hLl9kZWYuc2NoZW1hXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgfVxuICByZXR1cm4gc2NoZW1hLl9kZWZcbn1cblxuY29uc3QgdHJ5R2V0Wm9kU2NoZW1hQXNPYmplY3QgPSAoXG4gIHNjaGVtYTogei5ab2RUeXBlQW55XG4pOiB6LlpvZE9iamVjdDxhbnk+IHwgdW5kZWZpbmVkID0+IHtcbiAgY29uc3QgaXNab2RFZmZlY3QgPSBzY2hlbWEuX2RlZi50eXBlTmFtZSA9PT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHNcbiAgY29uc3Qgc2FmZV9zY2hlbWEgPSBnZXRab2RPYmplY3RTY2hlbWFGcm9tWm9kRWZmZWN0U2NoZW1hKGlzWm9kRWZmZWN0LCBzY2hlbWEpXG4gIGNvbnN0IGlzWm9kT2JqZWN0ID1cbiAgICBzYWZlX3NjaGVtYS5fZGVmLnR5cGVOYW1lID09PSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kT2JqZWN0XG5cbiAgaWYgKCFpc1pvZE9iamVjdCkge1xuICAgIHJldHVybiB1bmRlZmluZWRcbiAgfVxuXG4gIHJldHVybiBzYWZlX3NjaGVtYSBhcyB6LlpvZE9iamVjdDxhbnk+XG59XG5cbmNvbnN0IGlzWm9kU2NoZW1hQXJyYXkgPSAoc2NoZW1hOiB6LlpvZFR5cGVBbnkpID0+IHtcbiAgY29uc3QgZGVmID0gZ2V0Wm9kRGVmRnJvbVpvZFNjaGVtYUhlbHBlcnMoc2NoZW1hKVxuICByZXR1cm4gZGVmLnR5cGVOYW1lID09PSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQXJyYXlcbn1cblxuY29uc3QgaXNab2RTY2hlbWFCb29sZWFuID0gKHNjaGVtYTogei5ab2RUeXBlQW55KSA9PiB7XG4gIGNvbnN0IGRlZiA9IGdldFpvZERlZkZyb21ab2RTY2hlbWFIZWxwZXJzKHNjaGVtYSlcbiAgcmV0dXJuIGRlZi50eXBlTmFtZSA9PT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEJvb2xlYW5cbn1cblxuY29uc3QgcGFyc2VRdWVyeVBhcmFtcyA9IChcbiAgc2NoZW1hOiB6LlpvZFR5cGVBbnksXG4gIGlucHV0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgc3VwcG9ydGVkQXJyYXlGb3JtYXRzOiBRdWVyeUFycmF5Rm9ybWF0W11cbikgPT4ge1xuICBjb25zdCBwYXJzZWRfaW5wdXQgPSBPYmplY3QuYXNzaWduKHt9LCBpbnB1dClcbiAgY29uc3Qgb2JqX3NjaGVtYSA9IHRyeUdldFpvZFNjaGVtYUFzT2JqZWN0KHNjaGVtYSlcblxuICBpZiAob2JqX3NjaGVtYSkge1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKG9ial9zY2hlbWEuc2hhcGUpKSB7XG4gICAgICBpZiAoaXNab2RTY2hlbWFBcnJheSh2YWx1ZSBhcyB6LlpvZFR5cGVBbnkpKSB7XG4gICAgICAgIGNvbnN0IGFycmF5X2lucHV0ID0gaW5wdXRba2V5XVxuXG4gICAgICAgIGlmIChcbiAgICAgICAgICB0eXBlb2YgYXJyYXlfaW5wdXQgPT09IFwic3RyaW5nXCIgJiZcbiAgICAgICAgICBzdXBwb3J0ZWRBcnJheUZvcm1hdHMuaW5jbHVkZXMoXCJjb21tYVwiKVxuICAgICAgICApIHtcbiAgICAgICAgICBwYXJzZWRfaW5wdXRba2V5XSA9IGFycmF5X2lucHV0LnNwbGl0KFwiLFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYnJhY2tldF9zeW50YXhfYXJyYXlfaW5wdXQgPSBpbnB1dFtgJHtrZXl9W11gXVxuICAgICAgICBpZiAoXG4gICAgICAgICAgdHlwZW9mIGJyYWNrZXRfc3ludGF4X2FycmF5X2lucHV0ID09PSBcInN0cmluZ1wiICYmXG4gICAgICAgICAgc3VwcG9ydGVkQXJyYXlGb3JtYXRzLmluY2x1ZGVzKFwiYnJhY2tldHNcIilcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgcHJlX3NwbGl0X2FycmF5ID0gYnJhY2tldF9zeW50YXhfYXJyYXlfaW5wdXRcbiAgICAgICAgICBwYXJzZWRfaW5wdXRba2V5XSA9IHByZV9zcGxpdF9hcnJheS5zcGxpdChcIixcIilcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChcbiAgICAgICAgICBBcnJheS5pc0FycmF5KGJyYWNrZXRfc3ludGF4X2FycmF5X2lucHV0KSAmJlxuICAgICAgICAgIHN1cHBvcnRlZEFycmF5Rm9ybWF0cy5pbmNsdWRlcyhcImJyYWNrZXRzXCIpXG4gICAgICAgICkge1xuICAgICAgICAgIHBhcnNlZF9pbnB1dFtrZXldID0gYnJhY2tldF9zeW50YXhfYXJyYXlfaW5wdXRcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChpc1pvZFNjaGVtYUJvb2xlYW4odmFsdWUgYXMgei5ab2RUeXBlQW55KSkge1xuICAgICAgICBjb25zdCBib29sZWFuX2lucHV0ID0gaW5wdXRba2V5XVxuXG4gICAgICAgIGlmICh0eXBlb2YgYm9vbGVhbl9pbnB1dCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIHBhcnNlZF9pbnB1dFtrZXldID0gYm9vbGVhbl9pbnB1dCA9PT0gXCJ0cnVlXCJcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzY2hlbWEucGFyc2UocGFyc2VkX2lucHV0KVxufVxuXG5jb25zdCB2YWxpZGF0ZVF1ZXJ5UGFyYW1zID0gKFxuICBpbnB1dFVybDogc3RyaW5nLFxuICBzY2hlbWE6IHouWm9kVHlwZUFueSxcbiAgc3VwcG9ydGVkQXJyYXlGb3JtYXRzOiBRdWVyeUFycmF5Rm9ybWF0W11cbikgPT4ge1xuICBjb25zdCB1cmwgPSBuZXcgVVJMKGlucHV0VXJsLCBcImh0dHA6Ly9kdW1teS5jb21cIilcblxuICBjb25zdCBzZWVuS2V5cyA9IG5ldyBTZXQ8c3RyaW5nPigpXG5cbiAgY29uc3Qgb2JqX3NjaGVtYSA9IHRyeUdldFpvZFNjaGVtYUFzT2JqZWN0KHNjaGVtYSlcbiAgaWYgKCFvYmpfc2NoZW1hKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBmb3IgKGNvbnN0IGtleSBvZiB1cmwuc2VhcmNoUGFyYW1zLmtleXMoKSkge1xuICAgIGZvciAoY29uc3QgW3NjaGVtYUtleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKG9ial9zY2hlbWEuc2hhcGUpKSB7XG4gICAgICBpZiAoaXNab2RTY2hlbWFBcnJheSh2YWx1ZSBhcyB6LlpvZFR5cGVBbnkpKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBrZXkgPT09IGAke3NjaGVtYUtleX1bXWAgJiZcbiAgICAgICAgICAhc3VwcG9ydGVkQXJyYXlGb3JtYXRzLmluY2x1ZGVzKFwiYnJhY2tldHNcIilcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oe1xuICAgICAgICAgICAgdHlwZTogXCJpbnZhbGlkX3F1ZXJ5X3BhcmFtc1wiLFxuICAgICAgICAgICAgbWVzc2FnZTogYEJyYWNrZXQgc3ludGF4IG5vdCBzdXBwb3J0ZWQgZm9yIHF1ZXJ5IHBhcmFtIFwiJHtzY2hlbWFLZXl9XCJgLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBrZXlfc2NoZW1hID0gb2JqX3NjaGVtYS5zaGFwZVtrZXldXG5cbiAgICBpZiAoa2V5X3NjaGVtYSkge1xuICAgICAgaWYgKGlzWm9kU2NoZW1hQXJyYXkoa2V5X3NjaGVtYSkpIHtcbiAgICAgICAgaWYgKHNlZW5LZXlzLmhhcyhrZXkpICYmICFzdXBwb3J0ZWRBcnJheUZvcm1hdHMuaW5jbHVkZXMoXCJyZXBlYXRcIikpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbih7XG4gICAgICAgICAgICB0eXBlOiBcImludmFsaWRfcXVlcnlfcGFyYW1zXCIsXG4gICAgICAgICAgICBtZXNzYWdlOiBgUmVwZWF0ZWQgcGFyYW1ldGVycyBub3Qgc3VwcG9ydGVkIGZvciBkdXBsaWNhdGUgcXVlcnkgcGFyYW0gXCIke2tleX1cImAsXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHNlZW5LZXlzLmFkZChrZXkpXG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXF1ZXN0SW5wdXQ8XG4gIEpzb25Cb2R5IGV4dGVuZHMgei5ab2RUeXBlQW55LFxuICBRdWVyeVBhcmFtcyBleHRlbmRzIHouWm9kVHlwZUFueSxcbiAgQ29tbW9uUGFyYW1zIGV4dGVuZHMgei5ab2RUeXBlQW55LFxuICBGb3JtRGF0YSBleHRlbmRzIHouWm9kVHlwZUFueSxcbiAgSnNvblJlc3BvbnNlIGV4dGVuZHMgei5ab2RUeXBlQW55XG4+IHtcbiAganNvbkJvZHk/OiBKc29uQm9keVxuICBxdWVyeVBhcmFtcz86IFF1ZXJ5UGFyYW1zXG4gIGNvbW1vblBhcmFtcz86IENvbW1vblBhcmFtc1xuICBmb3JtRGF0YT86IEZvcm1EYXRhXG4gIGpzb25SZXNwb25zZT86IEpzb25SZXNwb25zZVxuICBzaG91bGRWYWxpZGF0ZVJlc3BvbnNlcz86IGJvb2xlYW5cbiAgc2hvdWxkVmFsaWRhdGVHZXRSZXF1ZXN0Qm9keT86IGJvb2xlYW5cbiAgc3VwcG9ydGVkQXJyYXlGb3JtYXRzPzogUXVlcnlBcnJheUZvcm1hdFtdXG59XG5cbmNvbnN0IHpvZElzc3VlVG9TdHJpbmcgPSAoaXNzdWU6IHouWm9kSXNzdWUpID0+IHtcbiAgaWYgKGlzc3VlLnBhdGguam9pbihcIi5cIikgPT09IFwiXCIpIHtcbiAgICByZXR1cm4gaXNzdWUubWVzc2FnZVxuICB9XG4gIGlmIChpc3N1ZS5tZXNzYWdlID09PSBcIlJlcXVpcmVkXCIpIHtcbiAgICByZXR1cm4gYCR7aXNzdWUucGF0aC5qb2luKFwiLlwiKX0gaXMgcmVxdWlyZWRgXG4gIH1cbiAgcmV0dXJuIGAke2lzc3VlLm1lc3NhZ2V9IGZvciBcIiR7aXNzdWUucGF0aC5qb2luKFwiLlwiKX1cImBcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVKc29uUmVzcG9uc2U8SnNvblJlc3BvbnNlIGV4dGVuZHMgei5ab2RUeXBlQW55PihcbiAganNvblJlc3BvbnNlOiBKc29uUmVzcG9uc2UgfCB1bmRlZmluZWQsXG4gIHJlczogTmV4dEFwaVJlc3BvbnNlXG4pIHtcbiAgY29uc3Qgb3JpZ2luYWxfcmVzX2pzb24gPSByZXMuanNvblxuICBjb25zdCBvdmVycmlkZV9yZXNfanNvbiA9IChqc29uOiBhbnkpID0+IHtcbiAgICBjb25zdCBpc19zdWNjZXNzID0gcmVzLnN0YXR1c0NvZGUgPj0gMjAwICYmIHJlcy5zdGF0dXNDb2RlIDwgMzAwXG4gICAgaWYgKCFpc19zdWNjZXNzKSB7XG4gICAgICByZXR1cm4gb3JpZ2luYWxfcmVzX2pzb24oanNvbilcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAganNvblJlc3BvbnNlPy5wYXJzZShqc29uKVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhyb3cgbmV3IEludGVybmFsU2VydmVyRXJyb3JFeGNlcHRpb24oe1xuICAgICAgICB0eXBlOiBcImludmFsaWRfcmVzcG9uc2VcIixcbiAgICAgICAgbWVzc2FnZTogXCJ0aGUgcmVzcG9uc2UgZG9lcyBub3QgbWF0Y2ggd2l0aCBqc29uUmVzcG9uc2VcIixcbiAgICAgICAgem9kRXJyb3I6IGVycixcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgcmV0dXJuIG9yaWdpbmFsX3Jlc19qc29uKGpzb24pXG4gIH1cbiAgcmVzLmpzb24gPSBvdmVycmlkZV9yZXNfanNvblxufVxuXG5leHBvcnQgY29uc3Qgd2l0aFZhbGlkYXRpb24gPVxuICA8XG4gICAgSnNvbkJvZHkgZXh0ZW5kcyB6LlpvZFR5cGVBbnksXG4gICAgUXVlcnlQYXJhbXMgZXh0ZW5kcyB6LlpvZFR5cGVBbnksXG4gICAgQ29tbW9uUGFyYW1zIGV4dGVuZHMgei5ab2RUeXBlQW55LFxuICAgIEZvcm1EYXRhIGV4dGVuZHMgei5ab2RUeXBlQW55LFxuICAgIEpzb25SZXNwb25zZSBleHRlbmRzIHouWm9kVHlwZUFueVxuICA+KFxuICAgIGlucHV0OiBSZXF1ZXN0SW5wdXQ8XG4gICAgICBKc29uQm9keSxcbiAgICAgIFF1ZXJ5UGFyYW1zLFxuICAgICAgQ29tbW9uUGFyYW1zLFxuICAgICAgRm9ybURhdGEsXG4gICAgICBKc29uUmVzcG9uc2VcbiAgICA+XG4gICkgPT5cbiAgKG5leHQpID0+XG4gIGFzeW5jIChyZXE6IE5leHRBcGlSZXF1ZXN0LCByZXM6IE5leHRBcGlSZXNwb25zZSkgPT4ge1xuICAgIGNvbnN0IHsgc3VwcG9ydGVkQXJyYXlGb3JtYXRzID0gREVGQVVMVF9BUlJBWV9GT1JNQVRTIH0gPSBpbnB1dFxuXG4gICAgaWYgKFxuICAgICAgKGlucHV0LmZvcm1EYXRhICYmIGlucHV0Lmpzb25Cb2R5KSB8fFxuICAgICAgKGlucHV0LmZvcm1EYXRhICYmIGlucHV0LmNvbW1vblBhcmFtcylcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCB1c2UgZm9ybURhdGEgd2l0aCBqc29uQm9keSBvciBjb21tb25QYXJhbXNcIilcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAocmVxLm1ldGhvZCA9PT0gXCJQT1NUXCIgfHwgcmVxLm1ldGhvZCA9PT0gXCJQQVRDSFwiKSAmJlxuICAgICAgKGlucHV0Lmpzb25Cb2R5IHx8IGlucHV0LmNvbW1vblBhcmFtcykgJiZcbiAgICAgICFyZXEuaGVhZGVyc1tcImNvbnRlbnQtdHlwZVwiXT8uaW5jbHVkZXMoXCJhcHBsaWNhdGlvbi9qc29uXCIpICYmXG4gICAgICAhXy5pc0VtcHR5KHJlcS5ib2R5KVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oe1xuICAgICAgICB0eXBlOiBcImludmFsaWRfY29udGVudF90eXBlXCIsXG4gICAgICAgIG1lc3NhZ2U6IGAke3JlcS5tZXRob2R9IHJlcXVlc3RzIG11c3QgaGF2ZSBDb250ZW50LVR5cGUgaGVhZGVyIHdpdGggXCJhcHBsaWNhdGlvbi9qc29uXCJgLFxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBpbnB1dC5mb3JtRGF0YSAmJlxuICAgICAgcmVxLm1ldGhvZCAhPT0gXCJHRVRcIiAmJlxuICAgICAgIXJlcS5oZWFkZXJzW1wiY29udGVudC10eXBlXCJdPy5pbmNsdWRlcyhcbiAgICAgICAgXCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRcIlxuICAgICAgKVxuICAgICAgLy8gVE9ETyBldmVudHVhbGx5IHdlIHNob3VsZCBzdXBwb3J0IG11bHRpcGFydC9mb3JtLWRhdGFcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKHtcbiAgICAgICAgdHlwZTogXCJpbnZhbGlkX2NvbnRlbnRfdHlwZVwiLFxuICAgICAgICBtZXNzYWdlOiBgTXVzdCBoYXZlIENvbnRlbnQtVHlwZSBoZWFkZXIgd2l0aCBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiYCxcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG9yaWdpbmFsX2NvbWJpbmVkX3BhcmFtcyA9IHsgLi4ucmVxLnF1ZXJ5LCAuLi5yZXEuYm9keSB9XG5cbiAgICAgIGNvbnN0IHdpbGxWYWxpZGF0ZVJlcXVlc3RCb2R5ID0gaW5wdXQuc2hvdWxkVmFsaWRhdGVHZXRSZXF1ZXN0Qm9keVxuICAgICAgICA/IHRydWVcbiAgICAgICAgOiByZXEubWV0aG9kICE9PSBcIkdFVFwiXG5cbiAgICAgIGNvbnN0IGlzRm9ybURhdGEgPSBCb29sZWFuKGlucHV0LmZvcm1EYXRhKVxuXG4gICAgICBpZiAoaXNGb3JtRGF0YSAmJiB3aWxsVmFsaWRhdGVSZXF1ZXN0Qm9keSkge1xuICAgICAgICByZXEuYm9keSA9IGlucHV0LmZvcm1EYXRhPy5wYXJzZShyZXEuYm9keSlcbiAgICAgIH1cblxuICAgICAgaWYgKCFpc0Zvcm1EYXRhICYmIHdpbGxWYWxpZGF0ZVJlcXVlc3RCb2R5KSB7XG4gICAgICAgIHJlcS5ib2R5ID0gaW5wdXQuanNvbkJvZHk/LnBhcnNlKHJlcS5ib2R5KVxuICAgICAgfVxuXG4gICAgICBpZiAoaW5wdXQucXVlcnlQYXJhbXMpIHtcbiAgICAgICAgaWYgKCFyZXEudXJsKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwicmVxLnVybCBpcyB1bmRlZmluZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHZhbGlkYXRlUXVlcnlQYXJhbXMocmVxLnVybCwgaW5wdXQucXVlcnlQYXJhbXMsIHN1cHBvcnRlZEFycmF5Rm9ybWF0cylcblxuICAgICAgICByZXEucXVlcnkgPSBwYXJzZVF1ZXJ5UGFyYW1zKFxuICAgICAgICAgIGlucHV0LnF1ZXJ5UGFyYW1zLFxuICAgICAgICAgIHJlcS5xdWVyeSxcbiAgICAgICAgICBzdXBwb3J0ZWRBcnJheUZvcm1hdHNcbiAgICAgICAgKVxuICAgICAgfVxuXG4gICAgICBpZiAoaW5wdXQuY29tbW9uUGFyYW1zKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBhcyBjb21tb25QYXJhbXMgaW5jbHVkZXMgcXVlcnkgcGFyYW1zLCB3ZSBjYW4gdXNlIHRoZSBwYXJzZVF1ZXJ5UGFyYW1zIGZ1bmN0aW9uXG4gICAgICAgICAqL1xuICAgICAgICA7KHJlcSBhcyBhbnkpLmNvbW1vblBhcmFtcyA9IHBhcnNlUXVlcnlQYXJhbXMoXG4gICAgICAgICAgaW5wdXQuY29tbW9uUGFyYW1zLFxuICAgICAgICAgIG9yaWdpbmFsX2NvbWJpbmVkX3BhcmFtcyxcbiAgICAgICAgICBzdXBwb3J0ZWRBcnJheUZvcm1hdHNcbiAgICAgICAgKVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEJhZFJlcXVlc3RFeGNlcHRpb24pIHtcbiAgICAgICAgdGhyb3cgZXJyb3JcbiAgICAgIH1cblxuICAgICAgaWYgKGVycm9yLm5hbWUgPT09IFwiWm9kRXJyb3JcIikge1xuICAgICAgICBsZXQgbWVzc2FnZVxuICAgICAgICBpZiAoZXJyb3IuaXNzdWVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIGNvbnN0IGlzc3VlID0gZXJyb3IuaXNzdWVzWzBdXG4gICAgICAgICAgbWVzc2FnZSA9IHpvZElzc3VlVG9TdHJpbmcoaXNzdWUpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgbWVzc2FnZV9jb21wb25lbnRzOiBzdHJpbmdbXSA9IFtdXG4gICAgICAgICAgZm9yIChjb25zdCBpc3N1ZSBvZiBlcnJvci5pc3N1ZXMpIHtcbiAgICAgICAgICAgIG1lc3NhZ2VfY29tcG9uZW50cy5wdXNoKHpvZElzc3VlVG9TdHJpbmcoaXNzdWUpKVxuICAgICAgICAgIH1cbiAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICAgIGAke2Vycm9yLmlzc3Vlcy5sZW5ndGh9IElucHV0IEVycm9yczogYCArXG4gICAgICAgICAgICBtZXNzYWdlX2NvbXBvbmVudHMuam9pbihcIiwgXCIpXG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbih7XG4gICAgICAgICAgdHlwZTogXCJpbnZhbGlkX2lucHV0XCIsXG4gICAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgICB2YWxpZGF0aW9uX2Vycm9yczogZXJyb3IuZm9ybWF0KCksXG4gICAgICAgIH0pXG4gICAgICB9XG5cbiAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKHtcbiAgICAgICAgdHlwZTogXCJpbnZhbGlkX2lucHV0XCIsXG4gICAgICAgIG1lc3NhZ2U6IFwiRXJyb3Igd2hpbGUgcGFyc2luZyBpbnB1dFwiLFxuICAgICAgfSlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB0aGlzIHdpbGwgb3ZlcnJpZGUgdGhlIHJlcy5qc29uIG1ldGhvZCB0byB2YWxpZGF0ZSB0aGUgcmVzcG9uc2VcbiAgICAgKi9cbiAgICBpZiAoaW5wdXQuc2hvdWxkVmFsaWRhdGVSZXNwb25zZXMpIHtcbiAgICAgIHZhbGlkYXRlSnNvblJlc3BvbnNlKGlucHV0Lmpzb25SZXNwb25zZSwgcmVzKVxuICAgIH1cblxuICAgIHJldHVybiBuZXh0KHJlcSwgcmVzKVxuICB9XG5cbmV4cG9ydCBkZWZhdWx0IHdpdGhWYWxpZGF0aW9uXG4iLCAiaW1wb3J0IHsgTmV4dEFwaVJlc3BvbnNlLCBOZXh0QXBpUmVxdWVzdCB9IGZyb20gXCJuZXh0XCJcbmltcG9ydCB7IHdpdGhFeGNlcHRpb25IYW5kbGluZyB9IGZyb20gXCIuLi9uZXh0anMtZXhjZXB0aW9uLW1pZGRsZXdhcmVcIlxuaW1wb3J0IHdyYXBwZXJzLCB7IE1pZGRsZXdhcmUgfSBmcm9tIFwiLi4vd3JhcHBlcnNcIlxuaW1wb3J0IHtcbiAgQ3JlYXRlV2l0aFJvdXRlU3BlY0Z1bmN0aW9uLFxuICBRdWVyeUFycmF5Rm9ybWF0LFxuICBSb3V0ZVNwZWMsXG59IGZyb20gXCIuLi90eXBlc1wiXG5pbXBvcnQgd2l0aE1ldGhvZHMsIHsgSFRUUE1ldGhvZHMgfSBmcm9tIFwiLi9taWRkbGV3YXJlcy93aXRoLW1ldGhvZHNcIlxuaW1wb3J0IHdpdGhWYWxpZGF0aW9uIGZyb20gXCIuL21pZGRsZXdhcmVzL3dpdGgtdmFsaWRhdGlvblwiXG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiXG5cbnR5cGUgUGFyYW1EZWYgPSB6LlpvZFR5cGVBbnkgfCB6LlpvZEVmZmVjdHM8ei5ab2RUeXBlQW55PlxuXG5leHBvcnQgY29uc3QgY2hlY2tSb3V0ZVNwZWMgPSA8XG4gIEF1dGhUeXBlIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nLFxuICBNZXRob2RzIGV4dGVuZHMgSFRUUE1ldGhvZHNbXSA9IEhUVFBNZXRob2RzW10sXG4gIEpzb25Cb2R5IGV4dGVuZHMgUGFyYW1EZWYgPSB6LlpvZFR5cGVBbnksXG4gIFF1ZXJ5UGFyYW1zIGV4dGVuZHMgUGFyYW1EZWYgPSB6LlpvZFR5cGVBbnksXG4gIENvbW1vblBhcmFtcyBleHRlbmRzIFBhcmFtRGVmID0gei5ab2RUeXBlQW55LFxuICBNaWRkbGV3YXJlcyBleHRlbmRzIHJlYWRvbmx5IE1pZGRsZXdhcmU8YW55LCBhbnk+W10gPSByZWFkb25seSBNaWRkbGV3YXJlPFxuICAgIGFueSxcbiAgICBhbnlcbiAgPltdLFxuICBGb3JtRGF0YSBleHRlbmRzIFBhcmFtRGVmID0gei5ab2RUeXBlQW55LFxuICBTcGVjIGV4dGVuZHMgUm91dGVTcGVjPFxuICAgIEF1dGhUeXBlLFxuICAgIE1ldGhvZHMsXG4gICAgSnNvbkJvZHksXG4gICAgUXVlcnlQYXJhbXMsXG4gICAgQ29tbW9uUGFyYW1zLFxuICAgIE1pZGRsZXdhcmVzLFxuICAgIEZvcm1EYXRhXG4gID4gPSBSb3V0ZVNwZWM8XG4gICAgQXV0aFR5cGUsXG4gICAgTWV0aG9kcyxcbiAgICBKc29uQm9keSxcbiAgICBRdWVyeVBhcmFtcyxcbiAgICBDb21tb25QYXJhbXMsXG4gICAgTWlkZGxld2FyZXMsXG4gICAgRm9ybURhdGFcbiAgPlxuPihcbiAgc3BlYzogU3BlY1xuKTogc3RyaW5nIGV4dGVuZHMgU3BlY1tcImF1dGhcIl1cbiAgPyBgeW91ciByb3V0ZSBzcGVjIGlzIHVuZGVyc3BlY2lmaWVkLCBhZGQgXCJhcyBjb25zdFwiYFxuICA6IFNwZWMgPT4gc3BlYyBhcyBhbnlcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfQVJSQVlfRk9STUFUUzogUXVlcnlBcnJheUZvcm1hdFtdID0gW1xuICBcImJyYWNrZXRzXCIsXG4gIFwiY29tbWFcIixcbiAgXCJyZXBlYXRcIixcbl1cblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVdpdGhSb3V0ZVNwZWM6IENyZWF0ZVdpdGhSb3V0ZVNwZWNGdW5jdGlvbiA9ICgoXG4gIHNldHVwUGFyYW1zXG4pID0+IHtcbiAgY29uc3Qge1xuICAgIGF1dGhNaWRkbGV3YXJlTWFwID0ge30sXG4gICAgZ2xvYmFsTWlkZGxld2FyZXMgPSBbXSxcbiAgICBzaG91bGRWYWxpZGF0ZVJlc3BvbnNlcyxcbiAgICBzaG91bGRWYWxpZGF0ZUdldFJlcXVlc3RCb2R5ID0gdHJ1ZSxcbiAgICBleGNlcHRpb25IYW5kbGluZ01pZGRsZXdhcmUgPSB3aXRoRXhjZXB0aW9uSGFuZGxpbmcoe1xuICAgICAgYWRkT2tTdGF0dXM6IHNldHVwUGFyYW1zLmFkZE9rU3RhdHVzLFxuICAgICAgZXhjZXB0aW9uSGFuZGxpbmdPcHRpb25zOiB7XG4gICAgICAgIGdldEVycm9yQ29udGV4dDogKHJlcSwgZXJyb3IpID0+IHtcbiAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgICAgICByZXR1cm4ge31cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZXJyb3JcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSkgYXMgYW55LFxuICAgIGdsb2JhbFNjaGVtYXMgPSBzZXR1cFBhcmFtcy5hZGRPa1N0YXR1c1xuICAgICAgPyB7XG4gICAgICAgICAgb2s6IHouYm9vbGVhbigpLFxuICAgICAgICB9XG4gICAgICA6IHt9LFxuICAgIHN1cHBvcnRlZEFycmF5Rm9ybWF0cyA9IERFRkFVTFRfQVJSQVlfRk9STUFUUyxcbiAgfSA9IHNldHVwUGFyYW1zXG5cbiAgY29uc3Qgd2l0aFJvdXRlU3BlYyA9IChzcGVjOiBSb3V0ZVNwZWMpID0+IHtcbiAgICBjb25zdCBjcmVhdGVSb3V0ZUV4cG9ydCA9ICh1c2VyRGVmaW5lZFJvdXRlRm4pID0+IHtcbiAgICAgIGNvbnN0IHJvb3RSZXF1ZXN0SGFuZGxlciA9IGFzeW5jIChcbiAgICAgICAgcmVxOiBOZXh0QXBpUmVxdWVzdCxcbiAgICAgICAgcmVzOiBOZXh0QXBpUmVzcG9uc2VcbiAgICAgICkgPT4ge1xuICAgICAgICBhdXRoTWlkZGxld2FyZU1hcFtcIm5vbmVcIl0gPSAobmV4dCkgPT4gbmV4dFxuXG4gICAgICAgIGNvbnN0IGF1dGhfbWlkZGxld2FyZSA9IGF1dGhNaWRkbGV3YXJlTWFwW3NwZWMuYXV0aF1cbiAgICAgICAgaWYgKCFhdXRoX21pZGRsZXdhcmUpIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBhdXRoIHR5cGU6ICR7c3BlYy5hdXRofWApXG5cbiAgICAgICAgcmV0dXJuIHdyYXBwZXJzKFxuICAgICAgICAgIC4uLigoZXhjZXB0aW9uSGFuZGxpbmdNaWRkbGV3YXJlXG4gICAgICAgICAgICA/IFtleGNlcHRpb25IYW5kbGluZ01pZGRsZXdhcmVdXG4gICAgICAgICAgICA6IFtdKSBhcyBbYW55XSksXG4gICAgICAgICAgLi4uKChnbG9iYWxNaWRkbGV3YXJlcyB8fCBbXSkgYXMgW10pLFxuICAgICAgICAgIGF1dGhfbWlkZGxld2FyZSxcbiAgICAgICAgICAuLi4oKHNwZWMubWlkZGxld2FyZXMgfHwgW10pIGFzIFtdKSxcbiAgICAgICAgICB3aXRoTWV0aG9kcyhzcGVjLm1ldGhvZHMpLFxuICAgICAgICAgIHdpdGhWYWxpZGF0aW9uKHtcbiAgICAgICAgICAgIGpzb25Cb2R5OiBzcGVjLmpzb25Cb2R5LFxuICAgICAgICAgICAgcXVlcnlQYXJhbXM6IHNwZWMucXVlcnlQYXJhbXMsXG4gICAgICAgICAgICBjb21tb25QYXJhbXM6IHNwZWMuY29tbW9uUGFyYW1zLFxuICAgICAgICAgICAgZm9ybURhdGE6IHNwZWMuZm9ybURhdGEsXG4gICAgICAgICAgICBqc29uUmVzcG9uc2U6IHNwZWMuanNvblJlc3BvbnNlLFxuICAgICAgICAgICAgc2hvdWxkVmFsaWRhdGVSZXNwb25zZXMsXG4gICAgICAgICAgICBzaG91bGRWYWxpZGF0ZUdldFJlcXVlc3RCb2R5LFxuICAgICAgICAgICAgc3VwcG9ydGVkQXJyYXlGb3JtYXRzLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHVzZXJEZWZpbmVkUm91dGVGblxuICAgICAgICApKHJlcSBhcyBhbnksIHJlcylcbiAgICAgIH1cblxuICAgICAgcm9vdFJlcXVlc3RIYW5kbGVyLl9zZXR1cFBhcmFtcyA9IHNldHVwUGFyYW1zXG4gICAgICByb290UmVxdWVzdEhhbmRsZXIuX3JvdXRlU3BlYyA9IHNwZWNcblxuICAgICAgcmV0dXJuIHJvb3RSZXF1ZXN0SGFuZGxlclxuICAgIH1cblxuICAgIGNyZWF0ZVJvdXRlRXhwb3J0Ll9zZXR1cFBhcmFtcyA9IHNldHVwUGFyYW1zXG4gICAgY3JlYXRlUm91dGVFeHBvcnQuX3JvdXRlU3BlYyA9IHNwZWNcblxuICAgIHJldHVybiBjcmVhdGVSb3V0ZUV4cG9ydFxuICB9XG5cbiAgd2l0aFJvdXRlU3BlYy5fc2V0dXBQYXJhbXMgPSBzZXR1cFBhcmFtc1xuXG4gIHJldHVybiB3aXRoUm91dGVTcGVjXG59KSBhcyBhbnlcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FB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SUFBSTtBQUVKLFFBQU0sZ0JBQWdCLENBQUMsU0FBb0I7QUFDekMsVUFBTSxvQkFBb0IsQ0FBQyx1QkFBdUI7QUFDaEQsWUFBTSxxQkFBcUIsT0FDekIsS0FDQSxRQUNHO0FBQ0gsMEJBQWtCLFVBQVUsQ0FBQyxTQUFTO0FBRXRDLGNBQU0sa0JBQWtCLGtCQUFrQixLQUFLO0FBQy9DLFlBQUksQ0FBQztBQUFpQixnQkFBTSxJQUFJLE1BQU0sc0JBQXNCLEtBQUssTUFBTTtBQUV2RSxlQUFPO0FBQUEsVUFDTCxHQUFLLDhCQUNELENBQUMsMkJBQTJCLElBQzVCLENBQUM7QUFBQSxVQUNMLEdBQUsscUJBQXFCLENBQUM7QUFBQSxVQUMzQjtBQUFBLFVBQ0EsR0FBSyxLQUFLLGVBQWUsQ0FBQztBQUFBLFVBQzFCLHFCQUFZLEtBQUssT0FBTztBQUFBLFVBQ3hCLHdCQUFlO0FBQUEsWUFDYixVQUFVLEtBQUs7QUFBQSxZQUNmLGFBQWEsS0FBSztBQUFBLFlBQ2xCLGNBQWMsS0FBSztBQUFBLFlBQ25CLFVBQVUsS0FBSztBQUFBLFlBQ2YsY0FBYyxLQUFLO0FBQUEsWUFDbkI7QUFBQSxZQUNBO0FBQUEsWUFDQTtBQUFBLFVBQ0YsQ0FBQztBQUFBLFVBQ0Q7QUFBQSxRQUNGLEVBQUUsS0FBWSxHQUFHO0FBQUEsTUFDbkI7QUFFQSx5QkFBbUIsZUFBZTtBQUNsQyx5QkFBbUIsYUFBYTtBQUVoQyxhQUFPO0FBQUEsSUFDVDtBQUVBLHNCQUFrQixlQUFlO0FBQ2pDLHNCQUFrQixhQUFhO0FBRS9CLFdBQU87QUFBQSxFQUNUO0FBRUEsZ0JBQWMsZUFBZTtBQUU3QixTQUFPO0FBQ1Q7IiwKICAibmFtZXMiOiBbIndpdGhFeGNlcHRpb25IYW5kbGluZyIsICJ3aXRoRXhjZXB0aW9uSGFuZGxpbmciLCAiXyIsICJpbXBvcnRfem9kIiwgIndpdGhFeGNlcHRpb25IYW5kbGluZyJdCn0K