UNPKG

minio

Version:

S3 Compatible Cloud Storage client

230 lines (217 loc) 25.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _eventemitter = require("eventemitter3"); var _Parser = require("stream-json/jsonl/Parser.js"); var _helpers = require("./helpers.js"); var _helper = require("./internal/helper.js"); /* * 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. */ // TODO: type this // Base class for three supported configs. 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) exports.TargetConfig = TargetConfig; class TopicConfig extends TargetConfig { constructor(arn) { super(); this.Topic = arn; } } // 2. Queue (simple queue service) exports.TopicConfig = TopicConfig; class QueueConfig extends TargetConfig { constructor(arn) { super(); this.Queue = arn; } } // 3. CloudFront (lambda function) exports.QueueConfig = QueueConfig; 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) exports.CloudFunctionConfig = CloudFunctionConfig; 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); } } } exports.NotificationConfig = NotificationConfig; const buildARN = (partition, service, region, accountId, resource) => { return 'arn:' + partition + ':' + service + ':' + region + ':' + accountId + ':' + resource; }; exports.buildARN = buildARN; const ObjectCreatedAll = 's3:ObjectCreated:*'; exports.ObjectCreatedAll = ObjectCreatedAll; const ObjectCreatedPut = 's3:ObjectCreated:Put'; exports.ObjectCreatedPut = ObjectCreatedPut; const ObjectCreatedPost = 's3:ObjectCreated:Post'; exports.ObjectCreatedPost = ObjectCreatedPost; const ObjectCreatedCopy = 's3:ObjectCreated:Copy'; exports.ObjectCreatedCopy = ObjectCreatedCopy; const ObjectCreatedCompleteMultipartUpload = 's3:ObjectCreated:CompleteMultipartUpload'; exports.ObjectCreatedCompleteMultipartUpload = ObjectCreatedCompleteMultipartUpload; const ObjectRemovedAll = 's3:ObjectRemoved:*'; exports.ObjectRemovedAll = ObjectRemovedAll; const ObjectRemovedDelete = 's3:ObjectRemoved:Delete'; exports.ObjectRemovedDelete = ObjectRemovedDelete; const ObjectRemovedDeleteMarkerCreated = 's3:ObjectRemoved:DeleteMarkerCreated'; exports.ObjectRemovedDeleteMarkerCreated = ObjectRemovedDeleteMarkerCreated; const ObjectReducedRedundancyLostObject = 's3:ReducedRedundancyLostObject'; // put string at least so auto-complete could work // TODO: type this exports.ObjectReducedRedundancyLostObject = ObjectReducedRedundancyLostObject; // Poll for notifications, used in #listenBucketNotification. // Listening constitutes repeatedly requesting s3 whether or not any // changes have occurred. class NotificationPoller extends _eventemitter.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 = (0, _helper.uriEscape)(this.prefix); queries.push(`prefix=${prefix}`); } if (this.suffix) { const suffix = (0, _helper.uriEscape)(this.suffix); queries.push(`suffix=${suffix}`); } if (this.events) { this.events.forEach(s3event => queries.push('events=' + (0, _helper.uriEscape)(s3event))); } queries.sort(); let query = ''; if (queries.length > 0) { query = `${queries.join('&')}`; } const region = this.client.region || _helpers.DEFAULT_REGION; this.client.makeRequestAsync({ method, bucketName: this.bucketName, query }, '', [200], region).then(response => { const asm = _Parser.make(); (0, _helper.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); }); } } exports.NotificationPoller = NotificationPoller; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZXZlbnRlbWl0dGVyIiwicmVxdWlyZSIsIl9QYXJzZXIiLCJfaGVscGVycyIsIl9oZWxwZXIiLCJUYXJnZXRDb25maWciLCJzZXRJZCIsImlkIiwiSWQiLCJhZGRFdmVudCIsIm5ld2V2ZW50IiwiRXZlbnQiLCJwdXNoIiwiYWRkRmlsdGVyU3VmZml4Iiwic3VmZml4IiwiRmlsdGVyIiwiUzNLZXkiLCJGaWx0ZXJSdWxlIiwiTmFtZSIsIlZhbHVlIiwiYWRkRmlsdGVyUHJlZml4IiwicHJlZml4IiwiZXhwb3J0cyIsIlRvcGljQ29uZmlnIiwiY29uc3RydWN0b3IiLCJhcm4iLCJUb3BpYyIsIlF1ZXVlQ29uZmlnIiwiUXVldWUiLCJDbG91ZEZ1bmN0aW9uQ29uZmlnIiwiQ2xvdWRGdW5jdGlvbiIsIk5vdGlmaWNhdGlvbkNvbmZpZyIsImFkZCIsInRhcmdldCIsImluc3RhbmNlIiwiVG9waWNDb25maWd1cmF0aW9uIiwiUXVldWVDb25maWd1cmF0aW9uIiwiQ2xvdWRGdW5jdGlvbkNvbmZpZ3VyYXRpb24iLCJidWlsZEFSTiIsInBhcnRpdGlvbiIsInNlcnZpY2UiLCJyZWdpb24iLCJhY2NvdW50SWQiLCJyZXNvdXJjZSIsIk9iamVjdENyZWF0ZWRBbGwiLCJPYmplY3RDcmVhdGVkUHV0IiwiT2JqZWN0Q3JlYXRlZFBvc3QiLCJPYmplY3RDcmVhdGVkQ29weSIsIk9iamVjdENyZWF0ZWRDb21wbGV0ZU11bHRpcGFydFVwbG9hZCIsIk9iamVjdFJlbW92ZWRBbGwiLCJPYmplY3RSZW1vdmVkRGVsZXRlIiwiT2JqZWN0UmVtb3ZlZERlbGV0ZU1hcmtlckNyZWF0ZWQiLCJPYmplY3RSZWR1Y2VkUmVkdW5kYW5jeUxvc3RPYmplY3QiLCJOb3RpZmljYXRpb25Qb2xsZXIiLCJFdmVudEVtaXR0ZXIiLCJjbGllbnQiLCJidWNrZXROYW1lIiwiZXZlbnRzIiwiZW5kaW5nIiwic3RhcnQiLCJwcm9jZXNzIiwibmV4dFRpY2siLCJjaGVja0ZvckNoYW5nZXMiLCJzdG9wIiwibWV0aG9kIiwicXVlcmllcyIsInVyaUVzY2FwZSIsImZvckVhY2giLCJzM2V2ZW50Iiwic29ydCIsInF1ZXJ5IiwibGVuZ3RoIiwiam9pbiIsIkRFRkFVTFRfUkVHSU9OIiwibWFrZVJlcXVlc3RBc3luYyIsInRoZW4iLCJyZXNwb25zZSIsImFzbSIsImpzb25MaW5lUGFyc2VyIiwibWFrZSIsInBpcGVzZXR1cCIsIm9uIiwiZGF0YSIsInJlY29yZHMiLCJ2YWx1ZSIsIlJlY29yZHMiLCJyZWNvcmQiLCJlbWl0IiwiZGVzdHJveSIsImUiXSwic291cmNlcyI6WyJub3RpZmljYXRpb24udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIE1pbklPIEphdmFzY3JpcHQgTGlicmFyeSBmb3IgQW1hem9uIFMzIENvbXBhdGlibGUgQ2xvdWQgU3RvcmFnZSwgKEMpIDIwMTYgTWluSU8sIEluYy5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnZXZlbnRlbWl0dGVyMydcbmltcG9ydCBqc29uTGluZVBhcnNlciBmcm9tICdzdHJlYW0tanNvbi9qc29ubC9QYXJzZXIuanMnXG5cbmltcG9ydCB7IERFRkFVTFRfUkVHSU9OIH0gZnJvbSAnLi9oZWxwZXJzLnRzJ1xuaW1wb3J0IHR5cGUgeyBUeXBlZENsaWVudCB9IGZyb20gJy4vaW50ZXJuYWwvY2xpZW50LnRzJ1xuaW1wb3J0IHsgcGlwZXNldHVwLCB1cmlFc2NhcGUgfSBmcm9tICcuL2ludGVybmFsL2hlbHBlci50cydcblxuLy8gVE9ETzogdHlwZSB0aGlzXG5cbnR5cGUgRXZlbnQgPSB1bmtub3duXG5cbi8vIEJhc2UgY2xhc3MgZm9yIHRocmVlIHN1cHBvcnRlZCBjb25maWdzLlxuZXhwb3J0IGNsYXNzIFRhcmdldENvbmZpZyB7XG4gIHByaXZhdGUgRmlsdGVyPzogeyBTM0tleTogeyBGaWx0ZXJSdWxlOiB7IE5hbWU6IHN0cmluZzsgVmFsdWU6IHN0cmluZyB9W10gfSB9XG4gIHByaXZhdGUgRXZlbnQ/OiBFdmVudFtdXG4gIHByaXZhdGUgSWQ6IHVua25vd25cblxuICBzZXRJZChpZDogdW5rbm93bikge1xuICAgIHRoaXMuSWQgPSBpZFxuICB9XG5cbiAgYWRkRXZlbnQobmV3ZXZlbnQ6IEV2ZW50KSB7XG4gICAgaWYgKCF0aGlzLkV2ZW50KSB7XG4gICAgICB0aGlzLkV2ZW50ID0gW11cbiAgICB9XG4gICAgdGhpcy5FdmVudC5wdXNoKG5ld2V2ZW50KVxuICB9XG5cbiAgYWRkRmlsdGVyU3VmZml4KHN1ZmZpeDogc3RyaW5nKSB7XG4gICAgaWYgKCF0aGlzLkZpbHRlcikge1xuICAgICAgdGhpcy5GaWx0ZXIgPSB7IFMzS2V5OiB7IEZpbHRlclJ1bGU6IFtdIH0gfVxuICAgIH1cbiAgICB0aGlzLkZpbHRlci5TM0tleS5GaWx0ZXJSdWxlLnB1c2goeyBOYW1lOiAnc3VmZml4JywgVmFsdWU6IHN1ZmZpeCB9KVxuICB9XG5cbiAgYWRkRmlsdGVyUHJlZml4KHByZWZpeDogc3RyaW5nKSB7XG4gICAgaWYgKCF0aGlzLkZpbHRlcikge1xuICAgICAgdGhpcy5GaWx0ZXIgPSB7IFMzS2V5OiB7IEZpbHRlclJ1bGU6IFtdIH0gfVxuICAgIH1cbiAgICB0aGlzLkZpbHRlci5TM0tleS5GaWx0ZXJSdWxlLnB1c2goeyBOYW1lOiAncHJlZml4JywgVmFsdWU6IHByZWZpeCB9KVxuICB9XG59XG5cbi8vIDEuIFRvcGljIChzaW1wbGUgbm90aWZpY2F0aW9uIHNlcnZpY2UpXG5leHBvcnQgY2xhc3MgVG9waWNDb25maWcgZXh0ZW5kcyBUYXJnZXRDb25maWcge1xuICBwcml2YXRlIFRvcGljOiBzdHJpbmdcblxuICBjb25zdHJ1Y3Rvcihhcm46IHN0cmluZykge1xuICAgIHN1cGVyKClcbiAgICB0aGlzLlRvcGljID0gYXJuXG4gIH1cbn1cblxuLy8gMi4gUXVldWUgKHNpbXBsZSBxdWV1ZSBzZXJ2aWNlKVxuZXhwb3J0IGNsYXNzIFF1ZXVlQ29uZmlnIGV4dGVuZHMgVGFyZ2V0Q29uZmlnIHtcbiAgcHJpdmF0ZSBRdWV1ZTogc3RyaW5nXG5cbiAgY29uc3RydWN0b3IoYXJuOiBzdHJpbmcpIHtcbiAgICBzdXBlcigpXG4gICAgdGhpcy5RdWV1ZSA9IGFyblxuICB9XG59XG5cbi8vIDMuIENsb3VkRnJvbnQgKGxhbWJkYSBmdW5jdGlvbilcbmV4cG9ydCBjbGFzcyBDbG91ZEZ1bmN0aW9uQ29uZmlnIGV4dGVuZHMgVGFyZ2V0Q29uZmlnIHtcbiAgcHJpdmF0ZSBDbG91ZEZ1bmN0aW9uOiBzdHJpbmdcblxuICBjb25zdHJ1Y3Rvcihhcm46IHN0cmluZykge1xuICAgIHN1cGVyKClcbiAgICB0aGlzLkNsb3VkRnVuY3Rpb24gPSBhcm5cbiAgfVxufVxuXG4vLyBOb3RpZmljYXRpb24gY29uZmlnIC0gYXJyYXkgb2YgdGFyZ2V0IGNvbmZpZ3MuXG4vLyBUYXJnZXQgY29uZmlncyBjYW4gYmVcbi8vIDEuIFRvcGljIChzaW1wbGUgbm90aWZpY2F0aW9uIHNlcnZpY2UpXG4vLyAyLiBRdWV1ZSAoc2ltcGxlIHF1ZXVlIHNlcnZpY2UpXG4vLyAzLiBDbG91ZEZyb250IChsYW1iZGEgZnVuY3Rpb24pXG5leHBvcnQgY2xhc3MgTm90aWZpY2F0aW9uQ29uZmlnIHtcbiAgcHJpdmF0ZSBUb3BpY0NvbmZpZ3VyYXRpb24/OiBUYXJnZXRDb25maWdbXVxuICBwcml2YXRlIENsb3VkRnVuY3Rpb25Db25maWd1cmF0aW9uPzogVGFyZ2V0Q29uZmlnW11cbiAgcHJpdmF0ZSBRdWV1ZUNvbmZpZ3VyYXRpb24/OiBUYXJnZXRDb25maWdbXVxuXG4gIGFkZCh0YXJnZXQ6IFRhcmdldENvbmZpZykge1xuICAgIGxldCBpbnN0YW5jZTogVGFyZ2V0Q29uZmlnW10gfCB1bmRlZmluZWRcbiAgICBpZiAodGFyZ2V0IGluc3RhbmNlb2YgVG9waWNDb25maWcpIHtcbiAgICAgIGluc3RhbmNlID0gdGhpcy5Ub3BpY0NvbmZpZ3VyYXRpb24gPz89IFtdXG4gICAgfVxuICAgIGlmICh0YXJnZXQgaW5zdGFuY2VvZiBRdWV1ZUNvbmZpZykge1xuICAgICAgaW5zdGFuY2UgPSB0aGlzLlF1ZXVlQ29uZmlndXJhdGlvbiA/Pz0gW11cbiAgICB9XG4gICAgaWYgKHRhcmdldCBpbnN0YW5jZW9mIENsb3VkRnVuY3Rpb25Db25maWcpIHtcbiAgICAgIGluc3RhbmNlID0gdGhpcy5DbG91ZEZ1bmN0aW9uQ29uZmlndXJhdGlvbiA/Pz0gW11cbiAgICB9XG4gICAgaWYgKGluc3RhbmNlKSB7XG4gICAgICBpbnN0YW5jZS5wdXNoKHRhcmdldClcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGJ1aWxkQVJOID0gKHBhcnRpdGlvbjogc3RyaW5nLCBzZXJ2aWNlOiBzdHJpbmcsIHJlZ2lvbjogc3RyaW5nLCBhY2NvdW50SWQ6IHN0cmluZywgcmVzb3VyY2U6IHN0cmluZykgPT4ge1xuICByZXR1cm4gJ2FybjonICsgcGFydGl0aW9uICsgJzonICsgc2VydmljZSArICc6JyArIHJlZ2lvbiArICc6JyArIGFjY291bnRJZCArICc6JyArIHJlc291cmNlXG59XG5leHBvcnQgY29uc3QgT2JqZWN0Q3JlYXRlZEFsbCA9ICdzMzpPYmplY3RDcmVhdGVkOionXG5leHBvcnQgY29uc3QgT2JqZWN0Q3JlYXRlZFB1dCA9ICdzMzpPYmplY3RDcmVhdGVkOlB1dCdcbmV4cG9ydCBjb25zdCBPYmplY3RDcmVhdGVkUG9zdCA9ICdzMzpPYmplY3RDcmVhdGVkOlBvc3QnXG5leHBvcnQgY29uc3QgT2JqZWN0Q3JlYXRlZENvcHkgPSAnczM6T2JqZWN0Q3JlYXRlZDpDb3B5J1xuZXhwb3J0IGNvbnN0IE9iamVjdENyZWF0ZWRDb21wbGV0ZU11bHRpcGFydFVwbG9hZCA9ICdzMzpPYmplY3RDcmVhdGVkOkNvbXBsZXRlTXVsdGlwYXJ0VXBsb2FkJ1xuZXhwb3J0IGNvbnN0IE9iamVjdFJlbW92ZWRBbGwgPSAnczM6T2JqZWN0UmVtb3ZlZDoqJ1xuZXhwb3J0IGNvbnN0IE9iamVjdFJlbW92ZWREZWxldGUgPSAnczM6T2JqZWN0UmVtb3ZlZDpEZWxldGUnXG5leHBvcnQgY29uc3QgT2JqZWN0UmVtb3ZlZERlbGV0ZU1hcmtlckNyZWF0ZWQgPSAnczM6T2JqZWN0UmVtb3ZlZDpEZWxldGVNYXJrZXJDcmVhdGVkJ1xuZXhwb3J0IGNvbnN0IE9iamVjdFJlZHVjZWRSZWR1bmRhbmN5TG9zdE9iamVjdCA9ICdzMzpSZWR1Y2VkUmVkdW5kYW5jeUxvc3RPYmplY3QnXG5leHBvcnQgdHlwZSBOb3RpZmljYXRpb25FdmVudCA9XG4gIHwgJ3MzOk9iamVjdENyZWF0ZWQ6KidcbiAgfCAnczM6T2JqZWN0Q3JlYXRlZDpQdXQnXG4gIHwgJ3MzOk9iamVjdENyZWF0ZWQ6UG9zdCdcbiAgfCAnczM6T2JqZWN0Q3JlYXRlZDpDb3B5J1xuICB8ICdzMzpPYmplY3RDcmVhdGVkOkNvbXBsZXRlTXVsdGlwYXJ0VXBsb2FkJ1xuICB8ICdzMzpPYmplY3RSZW1vdmVkOionXG4gIHwgJ3MzOk9iamVjdFJlbW92ZWQ6RGVsZXRlJ1xuICB8ICdzMzpPYmplY3RSZW1vdmVkOkRlbGV0ZU1hcmtlckNyZWF0ZWQnXG4gIHwgJ3MzOlJlZHVjZWRSZWR1bmRhbmN5TG9zdE9iamVjdCdcbiAgfCAnczM6VGVzdEV2ZW50J1xuICB8ICdzMzpPYmplY3RSZXN0b3JlOlBvc3QnXG4gIHwgJ3MzOk9iamVjdFJlc3RvcmU6Q29tcGxldGVkJ1xuICB8ICdzMzpSZXBsaWNhdGlvbjpPcGVyYXRpb25GYWlsZWRSZXBsaWNhdGlvbidcbiAgfCAnczM6UmVwbGljYXRpb246T3BlcmF0aW9uTWlzc2VkVGhyZXNob2xkJ1xuICB8ICdzMzpSZXBsaWNhdGlvbjpPcGVyYXRpb25SZXBsaWNhdGVkQWZ0ZXJUaHJlc2hvbGQnXG4gIHwgJ3MzOlJlcGxpY2F0aW9uOk9wZXJhdGlvbk5vdFRyYWNrZWQnXG4gIHwgc3RyaW5nIC8vIHB1dCBzdHJpbmcgYXQgbGVhc3Qgc28gYXV0by1jb21wbGV0ZSBjb3VsZCB3b3JrXG5cbi8vIFRPRE86IHR5cGUgdGhpc1xuZXhwb3J0IHR5cGUgTm90aWZpY2F0aW9uUmVjb3JkID0gdW5rbm93blxuLy8gUG9sbCBmb3Igbm90aWZpY2F0aW9ucywgdXNlZCBpbiAjbGlzdGVuQnVja2V0Tm90aWZpY2F0aW9uLlxuLy8gTGlzdGVuaW5nIGNvbnN0aXR1dGVzIHJlcGVhdGVkbHkgcmVxdWVzdGluZyBzMyB3aGV0aGVyIG9yIG5vdCBhbnlcbi8vIGNoYW5nZXMgaGF2ZSBvY2N1cnJlZC5cbmV4cG9ydCBjbGFzcyBOb3RpZmljYXRpb25Qb2xsZXIgZXh0ZW5kcyBFdmVudEVtaXR0ZXI8e1xuICBub3RpZmljYXRpb246IChldmVudDogTm90aWZpY2F0aW9uUmVjb3JkKSA9PiB2b2lkXG4gIGVycm9yOiAoZXJyb3I6IHVua25vd24pID0+IHZvaWRcbn0+IHtcbiAgcHJpdmF0ZSBjbGllbnQ6IFR5cGVkQ2xpZW50XG4gIHByaXZhdGUgYnVja2V0TmFtZTogc3RyaW5nXG4gIHByaXZhdGUgcHJlZml4OiBzdHJpbmdcbiAgcHJpdmF0ZSBzdWZmaXg6IHN0cmluZ1xuICBwcml2YXRlIGV2ZW50czogTm90aWZpY2F0aW9uRXZlbnRbXVxuICBwcml2YXRlIGVuZGluZzogYm9vbGVhblxuXG4gIGNvbnN0cnVjdG9yKGNsaWVudDogVHlwZWRDbGllbnQsIGJ1Y2tldE5hbWU6IHN0cmluZywgcHJlZml4OiBzdHJpbmcsIHN1ZmZpeDogc3RyaW5nLCBldmVudHM6IE5vdGlmaWNhdGlvbkV2ZW50W10pIHtcbiAgICBzdXBlcigpXG5cbiAgICB0aGlzLmNsaWVudCA9IGNsaWVudFxuICAgIHRoaXMuYnVja2V0TmFtZSA9IGJ1Y2tldE5hbWVcbiAgICB0aGlzLnByZWZpeCA9IHByZWZpeFxuICAgIHRoaXMuc3VmZml4ID0gc3VmZml4XG4gICAgdGhpcy5ldmVudHMgPSBldmVudHNcblxuICAgIHRoaXMuZW5kaW5nID0gZmFsc2VcbiAgfVxuXG4gIC8vIFN0YXJ0cyB0aGUgcG9sbGluZy5cbiAgc3RhcnQoKSB7XG4gICAgdGhpcy5lbmRpbmcgPSBmYWxzZVxuXG4gICAgcHJvY2Vzcy5uZXh0VGljaygoKSA9PiB7XG4gICAgICB0aGlzLmNoZWNrRm9yQ2hhbmdlcygpXG4gICAgfSlcbiAgfVxuXG4gIC8vIFN0b3BzIHRoZSBwb2xsaW5nLlxuICBzdG9wKCkge1xuICAgIHRoaXMuZW5kaW5nID0gdHJ1ZVxuICB9XG5cbiAgY2hlY2tGb3JDaGFuZ2VzKCkge1xuICAgIC8vIERvbid0IGNvbnRpbnVlIGlmIHdlJ3JlIGxvb3BpbmcgYWdhaW4gYnV0IGFyZSBjYW5jZWxsZWQuXG4gICAgaWYgKHRoaXMuZW5kaW5nKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBtZXRob2QgPSAnR0VUJ1xuICAgIGNvbnN0IHF1ZXJpZXMgPSBbXVxuICAgIGlmICh0aGlzLnByZWZpeCkge1xuICAgICAgY29uc3QgcHJlZml4ID0gdXJpRXNjYXBlKHRoaXMucHJlZml4KVxuICAgICAgcXVlcmllcy5wdXNoKGBwcmVmaXg9JHtwcmVmaXh9YClcbiAgICB9XG4gICAgaWYgKHRoaXMuc3VmZml4KSB7XG4gICAgICBjb25zdCBzdWZmaXggPSB1cmlFc2NhcGUodGhpcy5zdWZmaXgpXG4gICAgICBxdWVyaWVzLnB1c2goYHN1ZmZpeD0ke3N1ZmZpeH1gKVxuICAgIH1cbiAgICBpZiAodGhpcy5ldmVudHMpIHtcbiAgICAgIHRoaXMuZXZlbnRzLmZvckVhY2goKHMzZXZlbnQpID0+IHF1ZXJpZXMucHVzaCgnZXZlbnRzPScgKyB1cmlFc2NhcGUoczNldmVudCkpKVxuICAgIH1cbiAgICBxdWVyaWVzLnNvcnQoKVxuXG4gICAgbGV0IHF1ZXJ5ID0gJydcbiAgICBpZiAocXVlcmllcy5sZW5ndGggPiAwKSB7XG4gICAgICBxdWVyeSA9IGAke3F1ZXJpZXMuam9pbignJicpfWBcbiAgICB9XG4gICAgY29uc3QgcmVnaW9uID0gdGhpcy5jbGllbnQucmVnaW9uIHx8IERFRkFVTFRfUkVHSU9OXG5cbiAgICB0aGlzLmNsaWVudC5tYWtlUmVxdWVzdEFzeW5jKHsgbWV0aG9kLCBidWNrZXROYW1lOiB0aGlzLmJ1Y2tldE5hbWUsIHF1ZXJ5IH0sICcnLCBbMjAwXSwgcmVnaW9uKS50aGVuKFxuICAgICAgKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgIGNvbnN0IGFzbSA9IGpzb25MaW5lUGFyc2VyLm1ha2UoKVxuXG4gICAgICAgIHBpcGVzZXR1cChyZXNwb25zZSwgYXNtKVxuICAgICAgICAgIC5vbignZGF0YScsIChkYXRhKSA9PiB7XG4gICAgICAgICAgICAvLyBEYXRhIGlzIGZsdXNoZWQgcGVyaW9kaWNhbGx5IChldmVyeSA1IHNlY29uZHMpLCBzbyB3ZSBzaG91bGRcbiAgICAgICAgICAgIC8vIGhhbmRsZSBpdCBhZnRlciBmbHVzaGluZyBmcm9tIHRoZSBKU09OIHBhcnNlci5cbiAgICAgICAgICAgIGxldCByZWNvcmRzID0gZGF0YS52YWx1ZS5SZWNvcmRzXG4gICAgICAgICAgICAvLyBJZiBudWxsICg9IG5vIHJlY29yZHMpLCBjaGFuZ2UgdG8gYW4gZW1wdHkgYXJyYXkuXG4gICAgICAgICAgICBpZiAoIXJlY29yZHMpIHtcbiAgICAgICAgICAgICAgcmVjb3JkcyA9IFtdXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEl0ZXJhdGUgb3ZlciB0aGUgbm90aWZpY2F0aW9ucyBhbmQgZW1pdCB0aGVtIGluZGl2aWR1YWxseS5cbiAgICAgICAgICAgIHJlY29yZHMuZm9yRWFjaCgocmVjb3JkOiBOb3RpZmljYXRpb25SZWNvcmQpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5lbWl0KCdub3RpZmljYXRpb24nLCByZWNvcmQpXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAvLyBJZiB3ZSdyZSBkb25lLCBzdG9wLlxuICAgICAgICAgICAgaWYgKHRoaXMuZW5kaW5nKSB7XG4gICAgICAgICAgICAgIHJlc3BvbnNlPy5kZXN0cm95KClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICAgIC5vbignZXJyb3InLCAoZSkgPT4gdGhpcy5lbWl0KCdlcnJvcicsIGUpKVxuICAgICAgICAgIC5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICAgICAgLy8gRG8gaXQgYWdhaW4sIGlmIHdlIGhhdmVuJ3QgY2FuY2VsbGVkIHlldC5cbiAgICAgICAgICAgIHByb2Nlc3MubmV4dFRpY2soKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLmNoZWNrRm9yQ2hhbmdlcygpXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH0pXG4gICAgICB9LFxuICAgICAgKGUpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBlKVxuICAgICAgfSxcbiAgICApXG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFnQkEsSUFBQUEsYUFBQSxHQUFBQyxPQUFBO0FBQ0EsSUFBQUMsT0FBQSxHQUFBRCxPQUFB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