@aligent/cdk-prerender-proxy 2.1.5 → 2.2.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.
|
@@ -2,9 +2,13 @@ import "source-map-support/register";
|
|
|
2
2
|
import { CloudFrontRequest, CloudFrontRequestEvent } from "aws-lambda";
|
|
3
3
|
|
|
4
4
|
const IS_BOT =
|
|
5
|
-
/googlebot|Google-InspectionTool|Schema-Markup-Validator|SchemaBot|chrome-lighthouse|
|
|
5
|
+
/googlebot|bingbot|yandex|baiduspider|facebookexternalhit|facebookbot|twitterbot|linkedinbot|embedly|showyoubot|outbrain|pinterestbot|slackbot|vkShare|W3C_Validator|whatsapp|ImgProxy|flipboard|tumblr|bitlybot|skype|nuzzel|discordbot|google|qwantify|pinterest|lighthouse|telegrambo|Google-InspectionTool|Schema-Markup-Validator|SchemaBot|chrome-lighthouse|adsbot-google|Feedfetcher-Google|Facebot|rogerbot|quora link preview|SiteAuditBot|Storebot|Mediapartners-Google|AdIdxBot|BingPreview|Yahoo! Slurp|duckduckbot|applebot|gptbot/i;
|
|
6
|
+
|
|
6
7
|
const IS_FILE =
|
|
7
|
-
/\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|
|
|
8
|
+
/\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|woff|ttf|svg|webmanifest|eot|torrent)$/;
|
|
9
|
+
|
|
10
|
+
// Allow passing a custom bot detection regex string
|
|
11
|
+
const IS_BOT_CUSTOM = new RegExp(process.env.CUSTOM_BOT_CHECK || "[]", "i");
|
|
8
12
|
|
|
9
13
|
export const handler = async (
|
|
10
14
|
event: CloudFrontRequestEvent
|
|
@@ -14,7 +18,8 @@ export const handler = async (
|
|
|
14
18
|
// If the request is from a bot, is not a file and is not from prerender
|
|
15
19
|
// then set the x-request-prerender header so the origin-request lambda function
|
|
16
20
|
// alters the origin to prerender.io
|
|
17
|
-
|
|
21
|
+
const userAgent = request.headers["user-agent"][0].value;
|
|
22
|
+
if (IS_BOT.test(userAgent) || IS_BOT_CUSTOM.test(userAgent)) {
|
|
18
23
|
if (!IS_FILE.test(request.uri) && !request.headers["x-prerender"]) {
|
|
19
24
|
request.headers["x-request-prerender"] = [
|
|
20
25
|
{
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import { experimental } from "aws-cdk-lib/aws-cloudfront";
|
|
2
2
|
import { IVersion } from "aws-cdk-lib/aws-lambda";
|
|
3
3
|
import { Construct } from "constructs";
|
|
4
|
+
export interface PrerenderCheckOptions {
|
|
5
|
+
/**
|
|
6
|
+
* A custom regex string to detect bots. Will be used in addition
|
|
7
|
+
* to the existing bot check regex to determine if a user-agent is a bot.
|
|
8
|
+
*
|
|
9
|
+
* @type string
|
|
10
|
+
*/
|
|
11
|
+
customBotCheckRegex: string;
|
|
12
|
+
}
|
|
4
13
|
export declare class PrerenderCheckFunction extends Construct {
|
|
5
14
|
readonly edgeFunction: experimental.EdgeFunction;
|
|
6
|
-
constructor(scope: Construct, id: string);
|
|
15
|
+
constructor(scope: Construct, id: string, options?: PrerenderCheckOptions);
|
|
7
16
|
getFunctionVersion(): IVersion;
|
|
8
17
|
}
|
|
@@ -8,7 +8,8 @@ const constructs_1 = require("constructs");
|
|
|
8
8
|
const path_1 = require("path");
|
|
9
9
|
const cdk_esbuild_1 = require("@aligent/cdk-esbuild");
|
|
10
10
|
class PrerenderCheckFunction extends constructs_1.Construct {
|
|
11
|
-
constructor(scope, id) {
|
|
11
|
+
constructor(scope, id, options) {
|
|
12
|
+
var _a;
|
|
12
13
|
super(scope, id);
|
|
13
14
|
const command = [
|
|
14
15
|
"sh",
|
|
@@ -23,6 +24,9 @@ class PrerenderCheckFunction extends constructs_1.Construct {
|
|
|
23
24
|
image: aws_cdk_lib_1.DockerImage.fromRegistry("busybox"),
|
|
24
25
|
local: new cdk_esbuild_1.Esbuild({
|
|
25
26
|
entryPoints: [(0, path_1.join)(__dirname, "handlers/prerender-check.ts")],
|
|
27
|
+
define: {
|
|
28
|
+
"process.env.CUSTOM_BOT_CHECK": JSON.stringify((_a = options === null || options === void 0 ? void 0 : options.customBotCheckRegex) !== null && _a !== void 0 ? _a : "[]"),
|
|
29
|
+
},
|
|
26
30
|
}),
|
|
27
31
|
},
|
|
28
32
|
}),
|
|
@@ -35,4 +39,4 @@ class PrerenderCheckFunction extends constructs_1.Construct {
|
|
|
35
39
|
}
|
|
36
40
|
}
|
|
37
41
|
exports.PrerenderCheckFunction = PrerenderCheckFunction;
|
|
38
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
42
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJlcmVuZGVyLWNoZWNrLWNvbnN0cnVjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInByZXJlbmRlci1jaGVjay1jb25zdHJ1Y3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkNBQXlEO0FBQ3pELCtEQUEwRDtBQUMxRCx1REFBMEU7QUFDMUUsMkNBQXVDO0FBQ3ZDLCtCQUE0QjtBQUM1QixzREFBK0M7QUFZL0MsTUFBYSxzQkFBdUIsU0FBUSxzQkFBUztJQUduRCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLE9BQStCOztRQUN2RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLE1BQU0sT0FBTyxHQUFHO1lBQ2QsSUFBSTtZQUNKLElBQUk7WUFDSiw0REFBNEQ7U0FDN0QsQ0FBQztRQUVGLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSw2QkFBWSxDQUFDLFlBQVksQ0FDL0MsSUFBSSxFQUNKLEdBQUcsRUFBRSxxQkFBcUIsRUFDMUI7WUFDRSxJQUFJLEVBQUUsaUJBQUksQ0FBQyxTQUFTLENBQUMsSUFBQSxXQUFJLEVBQUMsU0FBUyxFQUFFLFVBQVUsQ0FBQyxFQUFFO2dCQUNoRCxhQUFhLEVBQUUsMkJBQWEsQ0FBQyxNQUFNO2dCQUNuQyxRQUFRLEVBQUU7b0JBQ1IsT0FBTztvQkFDUCxLQUFLLEVBQUUseUJBQVcsQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDO29CQUMxQyxLQUFLLEVBQUUsSUFBSSxxQkFBTyxDQUFDO3dCQUNqQixXQUFXLEVBQUUsQ0FBQyxJQUFBLFdBQUksRUFBQyxTQUFTLEVBQUUsNkJBQTZCLENBQUMsQ0FBQzt3QkFDN0QsTUFBTSxFQUFFOzRCQUNOLDhCQUE4QixFQUFFLElBQUksQ0FBQyxTQUFTLENBQzVDLE1BQUEsT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLG1CQUFtQixtQ0FBSSxJQUFJLENBQ3JDO3lCQUNGO3FCQUNGLENBQUM7aUJBQ0g7YUFDRixDQUFDO1lBQ0YsT0FBTyxFQUFFLG9CQUFPLENBQUMsV0FBVztZQUM1QixPQUFPLEVBQUUseUJBQXlCO1NBQ25DLENBQ0YsQ0FBQztJQUNKLENBQUM7SUFFTSxrQkFBa0I7UUFDdkIsT0FBTyxvQkFBTyxDQUFDLGNBQWMsQ0FDM0IsSUFBSSxFQUNKLDRCQUE0QixFQUM1QixJQUFJLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQ3pDLENBQUM7SUFDSixDQUFDO0NBQ0Y7QUE1Q0Qsd0RBNENDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXNzZXRIYXNoVHlwZSwgRG9ja2VySW1hZ2UgfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCB7IGV4cGVyaW1lbnRhbCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWRmcm9udFwiO1xuaW1wb3J0IHsgQ29kZSwgSVZlcnNpb24sIFJ1bnRpbWUsIFZlcnNpb24gfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxhbWJkYVwiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgRXNidWlsZCB9IGZyb20gXCJAYWxpZ2VudC9jZGstZXNidWlsZFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFByZXJlbmRlckNoZWNrT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBBIGN1c3RvbSByZWdleCBzdHJpbmcgdG8gZGV0ZWN0IGJvdHMuIFdpbGwgYmUgdXNlZCBpbiBhZGRpdGlvblxuICAgKiB0byB0aGUgZXhpc3RpbmcgYm90IGNoZWNrIHJlZ2V4IHRvIGRldGVybWluZSBpZiBhIHVzZXItYWdlbnQgaXMgYSBib3QuXG4gICAqXG4gICAqIEB0eXBlIHN0cmluZ1xuICAgKi9cbiAgY3VzdG9tQm90Q2hlY2tSZWdleDogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgUHJlcmVuZGVyQ2hlY2tGdW5jdGlvbiBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHJlYWRvbmx5IGVkZ2VGdW5jdGlvbjogZXhwZXJpbWVudGFsLkVkZ2VGdW5jdGlvbjtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBvcHRpb25zPzogUHJlcmVuZGVyQ2hlY2tPcHRpb25zKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGNvbnN0IGNvbW1hbmQgPSBbXG4gICAgICBcInNoXCIsXG4gICAgICBcIi1jXCIsXG4gICAgICAnZWNobyBcIkRvY2tlciBidWlsZCBub3Qgc3VwcG9ydGVkLiBQbGVhc2UgaW5zdGFsbCBlc2J1aWxkLlwiJyxcbiAgICBdO1xuXG4gICAgdGhpcy5lZGdlRnVuY3Rpb24gPSBuZXcgZXhwZXJpbWVudGFsLkVkZ2VGdW5jdGlvbihcbiAgICAgIHRoaXMsXG4gICAgICBgJHtpZH0tcHJlcmVuZGVyLWNoZWNrLWZuYCxcbiAgICAgIHtcbiAgICAgICAgY29kZTogQ29kZS5mcm9tQXNzZXQoam9pbihfX2Rpcm5hbWUsIFwiaGFuZGxlcnNcIiksIHtcbiAgICAgICAgICBhc3NldEhhc2hUeXBlOiBBc3NldEhhc2hUeXBlLk9VVFBVVCxcbiAgICAgICAgICBidW5kbGluZzoge1xuICAgICAgICAgICAgY29tbWFuZCxcbiAgICAgICAgICAgIGltYWdlOiBEb2NrZXJJbWFnZS5mcm9tUmVnaXN0cnkoXCJidXN5Ym94XCIpLFxuICAgICAgICAgICAgbG9jYWw6IG5ldyBFc2J1aWxkKHtcbiAgICAgICAgICAgICAgZW50cnlQb2ludHM6IFtqb2luKF9fZGlybmFtZSwgXCJoYW5kbGVycy9wcmVyZW5kZXItY2hlY2sudHNcIildLFxuICAgICAgICAgICAgICBkZWZpbmU6IHtcbiAgICAgICAgICAgICAgICBcInByb2Nlc3MuZW52LkNVU1RPTV9CT1RfQ0hFQ0tcIjogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICAgICAgICBvcHRpb25zPy5jdXN0b21Cb3RDaGVja1JlZ2V4ID8/IFwiW11cIlxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMThfWCxcbiAgICAgICAgaGFuZGxlcjogXCJwcmVyZW5kZXItY2hlY2suaGFuZGxlclwiLFxuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgZ2V0RnVuY3Rpb25WZXJzaW9uKCk6IElWZXJzaW9uIHtcbiAgICByZXR1cm4gVmVyc2lvbi5mcm9tVmVyc2lvbkFybihcbiAgICAgIHRoaXMsXG4gICAgICBcInByZXJlbmRlci1jaGVjay1mbi12ZXJzaW9uXCIsXG4gICAgICB0aGlzLmVkZ2VGdW5jdGlvbi5jdXJyZW50VmVyc2lvbi5lZGdlQXJuXG4gICAgKTtcbiAgfVxufVxuIl19
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Construct } from "constructs";
|
|
2
2
|
import { CloudFrontCacheControl, CloudFrontCacheControlOptions } from "./prerender-cf-cache-control-construct";
|
|
3
|
-
import { PrerenderCheckFunction } from "./prerender-check-construct";
|
|
3
|
+
import { PrerenderCheckFunction, PrerenderCheckOptions } from "./prerender-check-construct";
|
|
4
4
|
import { PrerenderFunction, PrerenderFunctionOptions } from "./prerender-construct";
|
|
5
5
|
import { ErrorResponseFunction, ErrorResponseFunctionOptions } from "./error-response-construct";
|
|
6
6
|
export interface PrerenderLambdaProps {
|
|
7
7
|
prerenderProps: PrerenderFunctionOptions;
|
|
8
8
|
errorResponseProps: ErrorResponseFunctionOptions;
|
|
9
|
+
prerenderCheckOptions?: PrerenderCheckOptions;
|
|
9
10
|
cacheControlProps?: CloudFrontCacheControlOptions;
|
|
10
11
|
}
|
|
11
12
|
export declare class PrerenderLambda extends Construct {
|
|
@@ -9,11 +9,11 @@ const error_response_construct_1 = require("./error-response-construct");
|
|
|
9
9
|
class PrerenderLambda extends constructs_1.Construct {
|
|
10
10
|
constructor(scope, id, props) {
|
|
11
11
|
super(scope, id);
|
|
12
|
-
this.prerenderCheckFunction = new prerender_check_construct_1.PrerenderCheckFunction(this, "PrerenderViewerRequest");
|
|
12
|
+
this.prerenderCheckFunction = new prerender_check_construct_1.PrerenderCheckFunction(this, "PrerenderViewerRequest", props.prerenderCheckOptions);
|
|
13
13
|
this.prerenderFunction = new prerender_construct_1.PrerenderFunction(this, "PrerenderOriginRequest", props.prerenderProps);
|
|
14
14
|
this.errorResponseFunction = new error_response_construct_1.ErrorResponseFunction(this, "ErrorResponse", props.errorResponseProps);
|
|
15
15
|
this.cacheControlFunction = new prerender_cf_cache_control_construct_1.CloudFrontCacheControl(this, "PrerenderCloudFrontCacheControl", props.cacheControlProps);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
exports.PrerenderLambda = PrerenderLambda;
|
|
19
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
19
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJlcmVuZGVyLWxhbWJkYS1jb25zdHJ1Y3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJwcmVyZW5kZXItbGFtYmRhLWNvbnN0cnVjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwyQ0FBdUM7QUFDdkMsaUdBR2dEO0FBQ2hELDJFQUdxQztBQUNyQywrREFHK0I7QUFDL0IseUVBR29DO0FBU3BDLE1BQWEsZUFBZ0IsU0FBUSxzQkFBUztJQU01QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQTJCO1FBQ25FLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksa0RBQXNCLENBQ3RELElBQUksRUFDSix3QkFBd0IsRUFDeEIsS0FBSyxDQUFDLHFCQUFxQixDQUM1QixDQUFDO1FBRUYsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksdUNBQWlCLENBQzVDLElBQUksRUFDSix3QkFBd0IsRUFDeEIsS0FBSyxDQUFDLGNBQWMsQ0FDckIsQ0FBQztRQUVGLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLGdEQUFxQixDQUNwRCxJQUFJLEVBQ0osZUFBZSxFQUNmLEtBQUssQ0FBQyxrQkFBa0IsQ0FDekIsQ0FBQztRQUVGLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLDZEQUFzQixDQUNwRCxJQUFJLEVBQ0osaUNBQWlDLEVBQ2pDLEtBQUssQ0FBQyxpQkFBaUIsQ0FDeEIsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQWpDRCwwQ0FpQ0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHtcbiAgQ2xvdWRGcm9udENhY2hlQ29udHJvbCxcbiAgQ2xvdWRGcm9udENhY2hlQ29udHJvbE9wdGlvbnMsXG59IGZyb20gXCIuL3ByZXJlbmRlci1jZi1jYWNoZS1jb250cm9sLWNvbnN0cnVjdFwiO1xuaW1wb3J0IHtcbiAgUHJlcmVuZGVyQ2hlY2tGdW5jdGlvbixcbiAgUHJlcmVuZGVyQ2hlY2tPcHRpb25zLFxufSBmcm9tIFwiLi9wcmVyZW5kZXItY2hlY2stY29uc3RydWN0XCI7XG5pbXBvcnQge1xuICBQcmVyZW5kZXJGdW5jdGlvbixcbiAgUHJlcmVuZGVyRnVuY3Rpb25PcHRpb25zLFxufSBmcm9tIFwiLi9wcmVyZW5kZXItY29uc3RydWN0XCI7XG5pbXBvcnQge1xuICBFcnJvclJlc3BvbnNlRnVuY3Rpb24sXG4gIEVycm9yUmVzcG9uc2VGdW5jdGlvbk9wdGlvbnMsXG59IGZyb20gXCIuL2Vycm9yLXJlc3BvbnNlLWNvbnN0cnVjdFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFByZXJlbmRlckxhbWJkYVByb3BzIHtcbiAgcHJlcmVuZGVyUHJvcHM6IFByZXJlbmRlckZ1bmN0aW9uT3B0aW9ucztcbiAgZXJyb3JSZXNwb25zZVByb3BzOiBFcnJvclJlc3BvbnNlRnVuY3Rpb25PcHRpb25zO1xuICBwcmVyZW5kZXJDaGVja09wdGlvbnM/OiBQcmVyZW5kZXJDaGVja09wdGlvbnM7XG4gIGNhY2hlQ29udHJvbFByb3BzPzogQ2xvdWRGcm9udENhY2hlQ29udHJvbE9wdGlvbnM7XG59XG5cbmV4cG9ydCBjbGFzcyBQcmVyZW5kZXJMYW1iZGEgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICByZWFkb25seSBwcmVyZW5kZXJDaGVja0Z1bmN0aW9uOiBQcmVyZW5kZXJDaGVja0Z1bmN0aW9uO1xuICByZWFkb25seSBwcmVyZW5kZXJGdW5jdGlvbjogUHJlcmVuZGVyRnVuY3Rpb247XG4gIHJlYWRvbmx5IGVycm9yUmVzcG9uc2VGdW5jdGlvbjogRXJyb3JSZXNwb25zZUZ1bmN0aW9uO1xuICByZWFkb25seSBjYWNoZUNvbnRyb2xGdW5jdGlvbjogQ2xvdWRGcm9udENhY2hlQ29udHJvbDtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogUHJlcmVuZGVyTGFtYmRhUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgdGhpcy5wcmVyZW5kZXJDaGVja0Z1bmN0aW9uID0gbmV3IFByZXJlbmRlckNoZWNrRnVuY3Rpb24oXG4gICAgICB0aGlzLFxuICAgICAgXCJQcmVyZW5kZXJWaWV3ZXJSZXF1ZXN0XCIsXG4gICAgICBwcm9wcy5wcmVyZW5kZXJDaGVja09wdGlvbnNcbiAgICApO1xuXG4gICAgdGhpcy5wcmVyZW5kZXJGdW5jdGlvbiA9IG5ldyBQcmVyZW5kZXJGdW5jdGlvbihcbiAgICAgIHRoaXMsXG4gICAgICBcIlByZXJlbmRlck9yaWdpblJlcXVlc3RcIixcbiAgICAgIHByb3BzLnByZXJlbmRlclByb3BzXG4gICAgKTtcblxuICAgIHRoaXMuZXJyb3JSZXNwb25zZUZ1bmN0aW9uID0gbmV3IEVycm9yUmVzcG9uc2VGdW5jdGlvbihcbiAgICAgIHRoaXMsXG4gICAgICBcIkVycm9yUmVzcG9uc2VcIixcbiAgICAgIHByb3BzLmVycm9yUmVzcG9uc2VQcm9wc1xuICAgICk7XG5cbiAgICB0aGlzLmNhY2hlQ29udHJvbEZ1bmN0aW9uID0gbmV3IENsb3VkRnJvbnRDYWNoZUNvbnRyb2woXG4gICAgICB0aGlzLFxuICAgICAgXCJQcmVyZW5kZXJDbG91ZEZyb250Q2FjaGVDb250cm9sXCIsXG4gICAgICBwcm9wcy5jYWNoZUNvbnRyb2xQcm9wc1xuICAgICk7XG4gIH1cbn1cbiJdfQ==
|