minio
Version:
S3 Compatible Cloud Storage client
209 lines (197 loc) • 24.3 kB
JavaScript
/*
* MinIO Javascript Library for Amazon S3 Compatible Cloud Storage, (C) 2016 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { EventEmitter } from 'eventemitter3';
import jsonLineParser from 'stream-json/jsonl/Parser.js';
import { DEFAULT_REGION } from "./helpers.mjs";
import { pipesetup, uriEscape } from "./internal/helper.mjs";
// TODO: type this
// Base class for three supported configs.
export class TargetConfig {
setId(id) {
this.Id = id;
}
addEvent(newevent) {
if (!this.Event) {
this.Event = [];
}
this.Event.push(newevent);
}
addFilterSuffix(suffix) {
if (!this.Filter) {
this.Filter = {
S3Key: {
FilterRule: []
}
};
}
this.Filter.S3Key.FilterRule.push({
Name: 'suffix',
Value: suffix
});
}
addFilterPrefix(prefix) {
if (!this.Filter) {
this.Filter = {
S3Key: {
FilterRule: []
}
};
}
this.Filter.S3Key.FilterRule.push({
Name: 'prefix',
Value: prefix
});
}
}
// 1. Topic (simple notification service)
export class TopicConfig extends TargetConfig {
constructor(arn) {
super();
this.Topic = arn;
}
}
// 2. Queue (simple queue service)
export class QueueConfig extends TargetConfig {
constructor(arn) {
super();
this.Queue = arn;
}
}
// 3. CloudFront (lambda function)
export class CloudFunctionConfig extends TargetConfig {
constructor(arn) {
super();
this.CloudFunction = arn;
}
}
// Notification config - array of target configs.
// Target configs can be
// 1. Topic (simple notification service)
// 2. Queue (simple queue service)
// 3. CloudFront (lambda function)
export class NotificationConfig {
add(target) {
let instance;
if (target instanceof TopicConfig) {
instance = this.TopicConfiguration ?? (this.TopicConfiguration = []);
}
if (target instanceof QueueConfig) {
instance = this.QueueConfiguration ?? (this.QueueConfiguration = []);
}
if (target instanceof CloudFunctionConfig) {
instance = this.CloudFunctionConfiguration ?? (this.CloudFunctionConfiguration = []);
}
if (instance) {
instance.push(target);
}
}
}
export const buildARN = (partition, service, region, accountId, resource) => {
return 'arn:' + partition + ':' + service + ':' + region + ':' + accountId + ':' + resource;
};
export const ObjectCreatedAll = 's3:ObjectCreated:*';
export const ObjectCreatedPut = 's3:ObjectCreated:Put';
export const ObjectCreatedPost = 's3:ObjectCreated:Post';
export const ObjectCreatedCopy = 's3:ObjectCreated:Copy';
export const ObjectCreatedCompleteMultipartUpload = 's3:ObjectCreated:CompleteMultipartUpload';
export const ObjectRemovedAll = 's3:ObjectRemoved:*';
export const ObjectRemovedDelete = 's3:ObjectRemoved:Delete';
export const ObjectRemovedDeleteMarkerCreated = 's3:ObjectRemoved:DeleteMarkerCreated';
export const ObjectReducedRedundancyLostObject = 's3:ReducedRedundancyLostObject';
// put string at least so auto-complete could work
// TODO: type this
// Poll for notifications, used in #listenBucketNotification.
// Listening constitutes repeatedly requesting s3 whether or not any
// changes have occurred.
export class NotificationPoller extends EventEmitter {
constructor(client, bucketName, prefix, suffix, events) {
super();
this.client = client;
this.bucketName = bucketName;
this.prefix = prefix;
this.suffix = suffix;
this.events = events;
this.ending = false;
}
// Starts the polling.
start() {
this.ending = false;
process.nextTick(() => {
this.checkForChanges();
});
}
// Stops the polling.
stop() {
this.ending = true;
}
checkForChanges() {
// Don't continue if we're looping again but are cancelled.
if (this.ending) {
return;
}
const method = 'GET';
const queries = [];
if (this.prefix) {
const prefix = uriEscape(this.prefix);
queries.push(`prefix=${prefix}`);
}
if (this.suffix) {
const suffix = uriEscape(this.suffix);
queries.push(`suffix=${suffix}`);
}
if (this.events) {
this.events.forEach(s3event => queries.push('events=' + uriEscape(s3event)));
}
queries.sort();
let query = '';
if (queries.length > 0) {
query = `${queries.join('&')}`;
}
const region = this.client.region || DEFAULT_REGION;
this.client.makeRequestAsync({
method,
bucketName: this.bucketName,
query
}, '', [200], region).then(response => {
const asm = jsonLineParser.make();
pipesetup(response, asm).on('data', data => {
// Data is flushed periodically (every 5 seconds), so we should
// handle it after flushing from the JSON parser.
let records = data.value.Records;
// If null (= no records), change to an empty array.
if (!records) {
records = [];
}
// Iterate over the notifications and emit them individually.
records.forEach(record => {
this.emit('notification', record);
});
// If we're done, stop.
if (this.ending) {
response === null || response === void 0 ? void 0 : response.destroy();
}
}).on('error', e => this.emit('error', e)).on('end', () => {
// Do it again, if we haven't cancelled yet.
process.nextTick(() => {
this.checkForChanges();
});
});
}, e => {
return this.emit('error', e);
});
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJFdmVudEVtaXR0ZXIiLCJqc29uTGluZVBhcnNlciIsIkRFRkFVTFRfUkVHSU9OIiwicGlwZXNldHVwIiwidXJpRXNjYXBlIiwiVGFyZ2V0Q29uZmlnIiwic2V0SWQiLCJpZCIsIklkIiwiYWRkRXZlbnQiLCJuZXdldmVudCIsIkV2ZW50IiwicHVzaCIsImFkZEZpbHRlclN1ZmZpeCIsInN1ZmZpeCIsIkZpbHRlciIsIlMzS2V5IiwiRmlsdGVyUnVsZSIsIk5hbWUiLCJWYWx1ZSIsImFkZEZpbHRlclByZWZpeCIsInByZWZpeCIsIlRvcGljQ29uZmlnIiwiY29uc3RydWN0b3IiLCJhcm4iLCJUb3BpYyIsIlF1ZXVlQ29uZmlnIiwiUXVldWUiLCJDbG91ZEZ1bmN0aW9uQ29uZmlnIiwiQ2xvdWRGdW5jdGlvbiIsIk5vdGlmaWNhdGlvbkNvbmZpZyIsImFkZCIsInRhcmdldCIsImluc3RhbmNlIiwiVG9waWNDb25maWd1cmF0aW9uIiwiUXVldWVDb25maWd1cmF0aW9uIiwiQ2xvdWRGdW5jdGlvbkNvbmZpZ3VyYXRpb24iLCJidWlsZEFSTiIsInBhcnRpdGlvbiIsInNlcnZpY2UiLCJyZWdpb24iLCJhY2NvdW50SWQiLCJyZXNvdXJjZSIsIk9iamVjdENyZWF0ZWRBbGwiLCJPYmplY3RDcmVhdGVkUHV0IiwiT2JqZWN0Q3JlYXRlZFBvc3QiLCJPYmplY3RDcmVhdGVkQ29weSIsIk9iamVjdENyZWF0ZWRDb21wbGV0ZU11bHRpcGFydFVwbG9hZCIsIk9iamVjdFJlbW92ZWRBbGwiLCJPYmplY3RSZW1vdmVkRGVsZXRlIiwiT2JqZWN0UmVtb3ZlZERlbGV0ZU1hcmtlckNyZWF0ZWQiLCJPYmplY3RSZWR1Y2VkUmVkdW5kYW5jeUxvc3RPYmplY3QiLCJOb3RpZmljYXRpb25Qb2xsZXIiLCJjbGllbnQiLCJidWNrZXROYW1lIiwiZXZlbnRzIiwiZW5kaW5nIiwic3RhcnQiLCJwcm9jZXNzIiwibmV4dFRpY2siLCJjaGVja0ZvckNoYW5nZXMiLCJzdG9wIiwibWV0aG9kIiwicXVlcmllcyIsImZvckVhY2giLCJzM2V2ZW50Iiwic29ydCIsInF1ZXJ5IiwibGVuZ3RoIiwiam9pbiIsIm1ha2VSZXF1ZXN0QXN5bmMiLCJ0aGVuIiwicmVzcG9uc2UiLCJhc20iLCJtYWtlIiwib24iLCJkYXRhIiwicmVjb3JkcyIsInZhbHVlIiwiUmVjb3JkcyIsInJlY29yZCIsImVtaXQiLCJkZXN0cm95IiwiZSJdLCJzb3VyY2VzIjpbIm5vdGlmaWNhdGlvbi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogTWluSU8gSmF2YXNjcmlwdCBMaWJyYXJ5IGZvciBBbWF6b24gUzMgQ29tcGF0aWJsZSBDbG91ZCBTdG9yYWdlLCAoQykgMjAxNiBNaW5JTywgSW5jLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tICdldmVudGVtaXR0ZXIzJ1xuaW1wb3J0IGpzb25MaW5lUGFyc2VyIGZyb20gJ3N0cmVhbS1qc29uL2pzb25sL1BhcnNlci5qcydcblxuaW1wb3J0IHsgREVGQVVMVF9SRUdJT04gfSBmcm9tICcuL2hlbHBlcnMudHMnXG5pbXBvcnQgdHlwZSB7IFR5cGVkQ2xpZW50IH0gZnJvbSAnLi9pbnRlcm5hbC9jbGllbnQudHMnXG5pbXBvcnQgeyBwaXBlc2V0dXAsIHVyaUVzY2FwZSB9IGZyb20gJy4vaW50ZXJuYWwvaGVscGVyLnRzJ1xuXG4vLyBUT0RPOiB0eXBlIHRoaXNcblxudHlwZSBFdmVudCA9IHVua25vd25cblxuLy8gQmFzZSBjbGFzcyBmb3IgdGhyZWUgc3VwcG9ydGVkIGNvbmZpZ3MuXG5leHBvcnQgY2xhc3MgVGFyZ2V0Q29uZmlnIHtcbiAgcHJpdmF0ZSBGaWx0ZXI/OiB7IFMzS2V5OiB7IEZpbHRlclJ1bGU6IHsgTmFtZTogc3RyaW5nOyBWYWx1ZTogc3RyaW5nIH1bXSB9IH1cbiAgcHJpdmF0ZSBFdmVudD86IEV2ZW50W11cbiAgcHJpdmF0ZSBJZDogdW5rbm93blxuXG4gIHNldElkKGlkOiB1bmtub3duKSB7XG4gICAgdGhpcy5JZCA9IGlkXG4gIH1cblxuICBhZGRFdmVudChuZXdldmVudDogRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMuRXZlbnQpIHtcbiAgICAgIHRoaXMuRXZlbnQgPSBbXVxuICAgIH1cbiAgICB0aGlzLkV2ZW50LnB1c2gobmV3ZXZlbnQpXG4gIH1cblxuICBhZGRGaWx0ZXJTdWZmaXgoc3VmZml4OiBzdHJpbmcpIHtcbiAgICBpZiAoIXRoaXMuRmlsdGVyKSB7XG4gICAgICB0aGlzLkZpbHRlciA9IHsgUzNLZXk6IHsgRmlsdGVyUnVsZTogW10gfSB9XG4gICAgfVxuICAgIHRoaXMuRmlsdGVyLlMzS2V5LkZpbHRlclJ1bGUucHVzaCh7IE5hbWU6ICdzdWZmaXgnLCBWYWx1ZTogc3VmZml4IH0pXG4gIH1cblxuICBhZGRGaWx0ZXJQcmVmaXgocHJlZml4OiBzdHJpbmcpIHtcbiAgICBpZiAoIXRoaXMuRmlsdGVyKSB7XG4gICAgICB0aGlzLkZpbHRlciA9IHsgUzNLZXk6IHsgRmlsdGVyUnVsZTogW10gfSB9XG4gICAgfVxuICAgIHRoaXMuRmlsdGVyLlMzS2V5LkZpbHRlclJ1bGUucHVzaCh7IE5hbWU6ICdwcmVmaXgnLCBWYWx1ZTogcHJlZml4IH0pXG4gIH1cbn1cblxuLy8gMS4gVG9waWMgKHNpbXBsZSBub3RpZmljYXRpb24gc2VydmljZSlcbmV4cG9ydCBjbGFzcyBUb3BpY0NvbmZpZyBleHRlbmRzIFRhcmdldENvbmZpZyB7XG4gIHByaXZhdGUgVG9waWM6IHN0cmluZ1xuXG4gIGNvbnN0cnVjdG9yKGFybjogc3RyaW5nKSB7XG4gICAgc3VwZXIoKVxuICAgIHRoaXMuVG9waWMgPSBhcm5cbiAgfVxufVxuXG4vLyAyLiBRdWV1ZSAoc2ltcGxlIHF1ZXVlIHNlcnZpY2UpXG5leHBvcnQgY2xhc3MgUXVldWVDb25maWcgZXh0ZW5kcyBUYXJnZXRDb25maWcge1xuICBwcml2YXRlIFF1ZXVlOiBzdHJpbmdcblxuICBjb25zdHJ1Y3Rvcihhcm46IHN0cmluZykge1xuICAgIHN1cGVyKClcbiAgICB0aGlzLlF1ZXVlID0gYXJuXG4gIH1cbn1cblxuLy8gMy4gQ2xvdWRGcm9udCAobGFtYmRhIGZ1bmN0aW9uKVxuZXhwb3J0IGNsYXNzIENsb3VkRnVuY3Rpb25Db25maWcgZXh0ZW5kcyBUYXJnZXRDb25maWcge1xuICBwcml2YXRlIENsb3VkRnVuY3Rpb246IHN0cmluZ1xuXG4gIGNvbnN0cnVjdG9yKGFybjogc3RyaW5nKSB7XG4gICAgc3VwZXIoKVxuICAgIHRoaXMuQ2xvdWRGdW5jdGlvbiA9IGFyblxuICB9XG59XG5cbi8vIE5vdGlmaWNhdGlvbiBjb25maWcgLSBhcnJheSBvZiB0YXJnZXQgY29uZmlncy5cbi8vIFRhcmdldCBjb25maWdzIGNhbiBiZVxuLy8gMS4gVG9waWMgKHNpbXBsZSBub3RpZmljYXRpb24gc2VydmljZSlcbi8vIDIuIFF1ZXVlIChzaW1wbGUgcXVldWUgc2VydmljZSlcbi8vIDMuIENsb3VkRnJvbnQgKGxhbWJkYSBmdW5jdGlvbilcbmV4cG9ydCBjbGFzcyBOb3RpZmljYXRpb25Db25maWcge1xuICBwcml2YXRlIFRvcGljQ29uZmlndXJhdGlvbj86IFRhcmdldENvbmZpZ1tdXG4gIHByaXZhdGUgQ2xvdWRGdW5jdGlvbkNvbmZpZ3VyYXRpb24/OiBUYXJnZXRDb25maWdbXVxuICBwcml2YXRlIFF1ZXVlQ29uZmlndXJhdGlvbj86IFRhcmdldENvbmZpZ1tdXG5cbiAgYWRkKHRhcmdldDogVGFyZ2V0Q29uZmlnKSB7XG4gICAgbGV0IGluc3RhbmNlOiBUYXJnZXRDb25maWdbXSB8IHVuZGVmaW5lZFxuICAgIGlmICh0YXJnZXQgaW5zdGFuY2VvZiBUb3BpY0NvbmZpZykge1xuICAgICAgaW5zdGFuY2UgPSB0aGlzLlRvcGljQ29uZmlndXJhdGlvbiA/Pz0gW11cbiAgICB9XG4gICAgaWYgKHRhcmdldCBpbnN0YW5jZW9mIFF1ZXVlQ29uZmlnKSB7XG4gICAgICBpbnN0YW5jZSA9IHRoaXMuUXVldWVDb25maWd1cmF0aW9uID8/PSBbXVxuICAgIH1cbiAgICBpZiAodGFyZ2V0IGluc3RhbmNlb2YgQ2xvdWRGdW5jdGlvbkNvbmZpZykge1xuICAgICAgaW5zdGFuY2UgPSB0aGlzLkNsb3VkRnVuY3Rpb25Db25maWd1cmF0aW9uID8/PSBbXVxuICAgIH1cbiAgICBpZiAoaW5zdGFuY2UpIHtcbiAgICAgIGluc3RhbmNlLnB1c2godGFyZ2V0KVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgYnVpbGRBUk4gPSAocGFydGl0aW9uOiBzdHJpbmcsIHNlcnZpY2U6IHN0cmluZywgcmVnaW9uOiBzdHJpbmcsIGFjY291bnRJZDogc3RyaW5nLCByZXNvdXJjZTogc3RyaW5nKSA9PiB7XG4gIHJldHVybiAnYXJuOicgKyBwYXJ0aXRpb24gKyAnOicgKyBzZXJ2aWNlICsgJzonICsgcmVnaW9uICsgJzonICsgYWNjb3VudElkICsgJzonICsgcmVzb3VyY2Vcbn1cbmV4cG9ydCBjb25zdCBPYmplY3RDcmVhdGVkQWxsID0gJ3MzOk9iamVjdENyZWF0ZWQ6KidcbmV4cG9ydCBjb25zdCBPYmplY3RDcmVhdGVkUHV0ID0gJ3MzOk9iamVjdENyZWF0ZWQ6UHV0J1xuZXhwb3J0IGNvbnN0IE9iamVjdENyZWF0ZWRQb3N0ID0gJ3MzOk9iamVjdENyZWF0ZWQ6UG9zdCdcbmV4cG9ydCBjb25zdCBPYmplY3RDcmVhdGVkQ29weSA9ICdzMzpPYmplY3RDcmVhdGVkOkNvcHknXG5leHBvcnQgY29uc3QgT2JqZWN0Q3JlYXRlZENvbXBsZXRlTXVsdGlwYXJ0VXBsb2FkID0gJ3MzOk9iamVjdENyZWF0ZWQ6Q29tcGxldGVNdWx0aXBhcnRVcGxvYWQnXG5leHBvcnQgY29uc3QgT2JqZWN0UmVtb3ZlZEFsbCA9ICdzMzpPYmplY3RSZW1vdmVkOionXG5leHBvcnQgY29uc3QgT2JqZWN0UmVtb3ZlZERlbGV0ZSA9ICdzMzpPYmplY3RSZW1vdmVkOkRlbGV0ZSdcbmV4cG9ydCBjb25zdCBPYmplY3RSZW1vdmVkRGVsZXRlTWFya2VyQ3JlYXRlZCA9ICdzMzpPYmplY3RSZW1vdmVkOkRlbGV0ZU1hcmtlckNyZWF0ZWQnXG5leHBvcnQgY29uc3QgT2JqZWN0UmVkdWNlZFJlZHVuZGFuY3lMb3N0T2JqZWN0ID0gJ3MzOlJlZHVjZWRSZWR1bmRhbmN5TG9zdE9iamVjdCdcbmV4cG9ydCB0eXBlIE5vdGlmaWNhdGlvbkV2ZW50ID1cbiAgfCAnczM6T2JqZWN0Q3JlYXRlZDoqJ1xuICB8ICdzMzpPYmplY3RDcmVhdGVkOlB1dCdcbiAgfCAnczM6T2JqZWN0Q3JlYXRlZDpQb3N0J1xuICB8ICdzMzpPYmplY3RDcmVhdGVkOkNvcHknXG4gIHwgJ3MzOk9iamVjdENyZWF0ZWQ6Q29tcGxldGVNdWx0aXBhcnRVcGxvYWQnXG4gIHwgJ3MzOk9iamVjdFJlbW92ZWQ6KidcbiAgfCAnczM6T2JqZWN0UmVtb3ZlZDpEZWxldGUnXG4gIHwgJ3MzOk9iamVjdFJlbW92ZWQ6RGVsZXRlTWFya2VyQ3JlYXRlZCdcbiAgfCAnczM6UmVkdWNlZFJlZHVuZGFuY3lMb3N0T2JqZWN0J1xuICB8ICdzMzpUZXN0RXZlbnQnXG4gIHwgJ3MzOk9iamVjdFJlc3RvcmU6UG9zdCdcbiAgfCAnczM6T2JqZWN0UmVzdG9yZTpDb21wbGV0ZWQnXG4gIHwgJ3MzOlJlcGxpY2F0aW9uOk9wZXJhdGlvbkZhaWxlZFJlcGxpY2F0aW9uJ1xuICB8ICdzMzpSZXBsaWNhdGlvbjpPcGVyYXRpb25NaXNzZWRUaHJlc2hvbGQnXG4gIHwgJ3MzOlJlcGxpY2F0aW9uOk9wZXJhdGlvblJlcGxpY2F0ZWRBZnRlclRocmVzaG9sZCdcbiAgfCAnczM6UmVwbGljYXRpb246T3BlcmF0aW9uTm90VHJhY2tlZCdcbiAgfCBzdHJpbmcgLy8gcHV0IHN0cmluZyBhdCBsZWFzdCBzbyBhdXRvLWNvbXBsZXRlIGNvdWxkIHdvcmtcblxuLy8gVE9ETzogdHlwZSB0aGlzXG5leHBvcnQgdHlwZSBOb3RpZmljYXRpb25SZWNvcmQgPSB1bmtub3duXG4vLyBQb2xsIGZvciBub3RpZmljYXRpb25zLCB1c2VkIGluICNsaXN0ZW5CdWNrZXROb3RpZmljYXRpb24uXG4vLyBMaXN0ZW5pbmcgY29uc3RpdHV0ZXMgcmVwZWF0ZWRseSByZXF1ZXN0aW5nIHMzIHdoZXRoZXIgb3Igbm90IGFueVxuLy8gY2hhbmdlcyBoYXZlIG9jY3VycmVkLlxuZXhwb3J0IGNsYXNzIE5vdGlmaWNhdGlvblBvbGxlciBleHRlbmRzIEV2ZW50RW1pdHRlcjx7XG4gIG5vdGlmaWNhdGlvbjogKGV2ZW50OiBOb3RpZmljYXRpb25SZWNvcmQpID0+IHZvaWRcbiAgZXJyb3I6IChlcnJvcjogdW5rbm93bikgPT4gdm9pZFxufT4ge1xuICBwcml2YXRlIGNsaWVudDogVHlwZWRDbGllbnRcbiAgcHJpdmF0ZSBidWNrZXROYW1lOiBzdHJpbmdcbiAgcHJpdmF0ZSBwcmVmaXg6IHN0cmluZ1xuICBwcml2YXRlIHN1ZmZpeDogc3RyaW5nXG4gIHByaXZhdGUgZXZlbnRzOiBOb3RpZmljYXRpb25FdmVudFtdXG4gIHByaXZhdGUgZW5kaW5nOiBib29sZWFuXG5cbiAgY29uc3RydWN0b3IoY2xpZW50OiBUeXBlZENsaWVudCwgYnVja2V0TmFtZTogc3RyaW5nLCBwcmVmaXg6IHN0cmluZywgc3VmZml4OiBzdHJpbmcsIGV2ZW50czogTm90aWZpY2F0aW9uRXZlbnRbXSkge1xuICAgIHN1cGVyKClcblxuICAgIHRoaXMuY2xpZW50ID0gY2xpZW50XG4gICAgdGhpcy5idWNrZXROYW1lID0gYnVja2V0TmFtZVxuICAgIHRoaXMucHJlZml4ID0gcHJlZml4XG4gICAgdGhpcy5zdWZmaXggPSBzdWZmaXhcbiAgICB0aGlzLmV2ZW50cyA9IGV2ZW50c1xuXG4gICAgdGhpcy5lbmRpbmcgPSBmYWxzZVxuICB9XG5cbiAgLy8gU3RhcnRzIHRoZSBwb2xsaW5nLlxuICBzdGFydCgpIHtcbiAgICB0aGlzLmVuZGluZyA9IGZhbHNlXG5cbiAgICBwcm9jZXNzLm5leHRUaWNrKCgpID0+IHtcbiAgICAgIHRoaXMuY2hlY2tGb3JDaGFuZ2VzKClcbiAgICB9KVxuICB9XG5cbiAgLy8gU3RvcHMgdGhlIHBvbGxpbmcuXG4gIHN0b3AoKSB7XG4gICAgdGhpcy5lbmRpbmcgPSB0cnVlXG4gIH1cblxuICBjaGVja0ZvckNoYW5nZXMoKSB7XG4gICAgLy8gRG9uJ3QgY29udGludWUgaWYgd2UncmUgbG9vcGluZyBhZ2FpbiBidXQgYXJlIGNhbmNlbGxlZC5cbiAgICBpZiAodGhpcy5lbmRpbmcpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IG1ldGhvZCA9ICdHRVQnXG4gICAgY29uc3QgcXVlcmllcyA9IFtdXG4gICAgaWYgKHRoaXMucHJlZml4KSB7XG4gICAgICBjb25zdCBwcmVmaXggPSB1cmlFc2NhcGUodGhpcy5wcmVmaXgpXG4gICAgICBxdWVyaWVzLnB1c2goYHByZWZpeD0ke3ByZWZpeH1gKVxuICAgIH1cbiAgICBpZiAodGhpcy5zdWZmaXgpIHtcbiAgICAgIGNvbnN0IHN1ZmZpeCA9IHVyaUVzY2FwZSh0aGlzLnN1ZmZpeClcbiAgICAgIHF1ZXJpZXMucHVzaChgc3VmZml4PSR7c3VmZml4fWApXG4gICAgfVxuICAgIGlmICh0aGlzLmV2ZW50cykge1xuICAgICAgdGhpcy5ldmVudHMuZm9yRWFjaCgoczNldmVudCkgPT4gcXVlcmllcy5wdXNoKCdldmVudHM9JyArIHVyaUVzY2FwZShzM2V2ZW50KSkpXG4gICAgfVxuICAgIHF1ZXJpZXMuc29ydCgpXG5cbiAgICBsZXQgcXVlcnkgPSAnJ1xuICAgIGlmIChxdWVyaWVzLmxlbmd0aCA+IDApIHtcbiAgICAgIHF1ZXJ5ID0gYCR7cXVlcmllcy5qb2luKCcmJyl9YFxuICAgIH1cbiAgICBjb25zdCByZWdpb24gPSB0aGlzLmNsaWVudC5yZWdpb24gfHwgREVGQVVMVF9SRUdJT05cblxuICAgIHRoaXMuY2xpZW50Lm1ha2VSZXF1ZXN0QXN5bmMoeyBtZXRob2QsIGJ1Y2tldE5hbWU6IHRoaXMuYnVja2V0TmFtZSwgcXVlcnkgfSwgJycsIFsyMDBdLCByZWdpb24pLnRoZW4oXG4gICAgICAocmVzcG9uc2UpID0+IHtcbiAgICAgICAgY29uc3QgYXNtID0ganNvbkxpbmVQYXJzZXIubWFrZSgpXG5cbiAgICAgICAgcGlwZXNldHVwKHJlc3BvbnNlLCBhc20pXG4gICAgICAgICAgLm9uKCdkYXRhJywgKGRhdGEpID0+IHtcbiAgICAgICAgICAgIC8vIERhdGEgaXMgZmx1c2hlZCBwZXJpb2RpY2FsbHkgKGV2ZXJ5IDUgc2Vjb25kcyksIHNvIHdlIHNob3VsZFxuICAgICAgICAgICAgLy8gaGFuZGxlIGl0IGFmdGVyIGZsdXNoaW5nIGZyb20gdGhlIEpTT04gcGFyc2VyLlxuICAgICAgICAgICAgbGV0IHJlY29yZHMgPSBkYXRhLnZhbHVlLlJlY29yZHNcbiAgICAgICAgICAgIC8vIElmIG51bGwgKD0gbm8gcmVjb3JkcyksIGNoYW5nZSB0byBhbiBlbXB0eSBhcnJheS5cbiAgICAgICAgICAgIGlmICghcmVjb3Jkcykge1xuICAgICAgICAgICAgICByZWNvcmRzID0gW11cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSXRlcmF0ZSBvdmVyIHRoZSBub3RpZmljYXRpb25zIGFuZCBlbWl0IHRoZW0gaW5kaXZpZHVhbGx5LlxuICAgICAgICAgICAgcmVjb3Jkcy5mb3JFYWNoKChyZWNvcmQ6IE5vdGlmaWNhdGlvblJlY29yZCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLmVtaXQoJ25vdGlmaWNhdGlvbicsIHJlY29yZClcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIC8vIElmIHdlJ3JlIGRvbmUsIHN0b3AuXG4gICAgICAgICAgICBpZiAodGhpcy5lbmRpbmcpIHtcbiAgICAgICAgICAgICAgcmVzcG9uc2U/LmRlc3Ryb3koKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG4gICAgICAgICAgLm9uKCdlcnJvcicsIChlKSA9PiB0aGlzLmVtaXQoJ2Vycm9yJywgZSkpXG4gICAgICAgICAgLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICAgICAgICAvLyBEbyBpdCBhZ2FpbiwgaWYgd2UgaGF2ZW4ndCBjYW5jZWxsZWQgeWV0LlxuICAgICAgICAgICAgcHJvY2Vzcy5uZXh0VGljaygoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuY2hlY2tGb3JDaGFuZ2VzKClcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfSlcbiAgICAgIH0sXG4gICAgICAoZSkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIGUpXG4gICAgICB9LFxuICAgIClcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsU0FBU0EsWUFBWSxRQUFRLGVBQWU7QUFDNUMsT0FBT0MsY0FBYyxNQUFNLDZC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