UNPKG

rehiver

Version:

Super-charge your S3 hive partitioned based file operations with intelligent pattern matching, change detection, optimized data-fetching, and out-of-the-box time series support.

2 lines 160 kB
"use strict";var _=Object.create;var $=Object.defineProperty;var N=Object.getOwnPropertyDescriptor;var ee=Object.getOwnPropertyNames;var te=Object.getPrototypeOf,ne=Object.prototype.hasOwnProperty;var re=(o,e)=>{for(var t in e)$(o,t,{get:e[t],enumerable:!0})},H=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of ee(e))!ne.call(o,n)&&n!==t&&$(o,n,{get:()=>e[n],enumerable:!(r=N(e,n))||r.enumerable});return o};var T=(o,e,t)=>(t=o!=null?_(te(o)):{},H(e||!o||!o.__esModule?$(t,"default",{value:o,enumerable:!0}):t,o)),se=o=>H($({},"__esModule",{value:!0}),o);var ge={};re(ge,{ChangeDetectionEngine:()=>j,ChangeType:()=>Y,ConsoleLogger:()=>D,ContentType:()=>q,HivePartitionParser:()=>E,LogLevel:()=>W,NoopLogger:()=>F,PathMatcher:()=>z,Rehiver:()=>A,S3PathMatcher:()=>O,TimeGranularity:()=>J,TimePartitionGenerator:()=>C,decodeS3Key:()=>M,default:()=>le,encodeS3Key:()=>ce,getGlobalLogger:()=>ae,isValidBucketName:()=>B,setGlobalLogger:()=>ie});module.exports=se(ge);var L=T(require("fs/promises")),U=T(require("path")),h=require("@aws-sdk/client-s3"),V=require("lru-cache"),v=T(require("micromatch")),K=T(require("mime-types")),I=T(require("p-limit"));function B(o){return!(!o||o.length<3||o.length>63||!/^[a-z0-9].*[a-z0-9]$/i.test(o)||!/^[a-z0-9.-]+$/i.test(o)||o.includes("..")||/^\d+\.\d+\.\d+\.\d+$/.test(o)||o.startsWith("xn--")||o.endsWith("-s3alias"))}var W=(s=>(s[s.Debug=0]="Debug",s[s.Info=1]="Info",s[s.Warn=2]="Warn",s[s.Error=3]="Error",s[s.None=100]="None",s))(W||{}),q={detect(o){return K.default.lookup(o)||"application/octet-stream"},charset(o){return K.default.charset(o)||null},extension(o){return K.default.extension(o)},isText(o){return o.startsWith("text/")||o==="application/json"||o==="application/xml"||o==="application/javascript"||o==="application/typescript"},isBinary(o){return!this.isText(o)}},D=class{level=1;constructor(e){e!==void 0&&(this.level=e)}debug(e,...t){this.level<=0&&console.debug(`[DEBUG] ${e}`,...t)}info(e,...t){this.level<=1&&console.info(`[INFO] ${e}`,...t)}warn(e,...t){this.level<=2&&console.warn(`[WARN] ${e}`,...t)}error(e,...t){this.level<=3&&console.error(`[ERROR] ${e}`,...t)}setLevel(e){this.level=e}getLevel(){return this.level}},F=class{debug(){}info(){}warn(){}error(){}setLevel(){}getLevel(){return 100}},S=new D;function ie(o){S=o}function ae(){return S}var oe=o=>new Promise(e=>setTimeout(e,o));async function R(o,e=5,t=100,r=3e4,n=S){let s;for(let i=0;i<e;i++)try{return await o()}catch(a){s=a;let c=(a==null?void 0:a.Code)||(a==null?void 0:a.code),l=(a==null?void 0:a.message)||"";if(!(c==="ThrottlingException"||c==="RequestTimeout"||c==="NetworkingError"||c==="TimeoutError"||c==="RequestTimeTooSkewed"||c==="ProvisionedThroughputExceededException"||c==="SlowDown"||c==="InternalError"||c==="ServiceUnavailable"||c==="429"||c==="500"||c==="503"||l.includes("timeout")||l.includes("throttl")||l.includes("network")||l.includes("connection")))throw a;let f=Math.min(r,t*2**i*(.8+Math.random()*.4));n.debug(`S3 operation failed (attempt ${i+1}/${e}), retrying in ${Math.round(f)}ms: ${c||l}`),await oe(f)}throw s}function ce(o){return o.split("/").map(e=>encodeURIComponent(e)).join("/")}function M(o){return o.split("/").map(e=>decodeURIComponent(e)).join("/")}var Y=(n=>(n.Added="added",n.Modified="modified",n.Deleted="deleted",n.Unchanged="unchanged",n))(Y||{}),j=class{previousState=new Map;currentState=new Map;options;constructor(e={}){this.options={stateFilePath:"change-detection-state.json",compareMode:"full",ignoreEtagOnSize:!1,trackDeleted:!0,...e}}async loadPreviousState(){if(this.options.stateFilePath)try{let e=await L.default.readFile(this.options.stateFilePath,"utf-8"),t=JSON.parse(e);this.previousState=new Map(Object.entries(t).map(([r,n])=>{let s=n;return s.lastModified&&typeof s.lastModified=="string"&&(s.lastModified=new Date(s.lastModified)),[r,s]}))}catch{this.previousState=new Map}}async saveCurrentState(){if(!this.options.stateFilePath)return;let e=Object.fromEntries(this.currentState),t=JSON.stringify(e,null,2),r=U.default.dirname(this.options.stateFilePath);await L.default.mkdir(r,{recursive:!0}),await L.default.writeFile(this.options.stateFilePath,t,"utf-8")}addObject(e){this.currentState.set(e.key,e)}addObjects(e){for(let t of e)this.addObject(t)}static fromS3Object(e){return{key:e.key||"",size:e.size||0,etag:(e.etag||"").replace(/"/g,""),lastModified:e.lastModified||new Date}}hasObjectChanged(e,t){return this.options.compareMode==="quick"?e.size!==t.size||e.lastModified.getTime()!==t.lastModified.getTime():this.options.ignoreEtagOnSize&&e.size===t.size?e.lastModified.getTime()!==t.lastModified.getTime():e.size!==t.size||e.etag!==t.etag||e.lastModified.getTime()!==t.lastModified.getTime()}detectChanges(){let e=[];return this.currentState.forEach((t,r)=>{let n=this.previousState.get(r);n?this.hasObjectChanged(t,n)?e.push({changeType:"modified",object:t,previousVersion:n}):e.push({changeType:"unchanged",object:t,previousVersion:n}):e.push({changeType:"added",object:t})}),this.options.trackDeleted&&this.previousState.forEach((t,r)=>{this.currentState.has(r)||e.push({changeType:"deleted",object:t})}),e}static filterChangesByType(e,t){return e.filter(r=>t.includes(r.changeType))}commitChanges(){this.previousState=new Map(this.currentState)}resetCurrentState(){this.currentState=new Map}resetAllState(){this.previousState=new Map,this.currentState=new Map}},z=class{constructor(e={}){this.options=e}patternCache=new Map;isMatch(e,t,r){return v.default.isMatch(e,t,{...this.options,...r})}match(e,t,r){return(0,v.default)(e,t,{...this.options,...r})}getRegex(e,t){let r=`${e}:${JSON.stringify({...this.options,...t})}`;if(!this.patternCache.has(r)){let s=v.default.makeRe(e,{...this.options,...t});this.patternCache.set(r,s)}let n=this.patternCache.get(r);if(!n)throw new Error(`Failed to create or retrieve regex for pattern: ${e}`);return n}matchFast(e,t,r){let s=(Array.isArray(t)?t:[t]).map(i=>this.getRegex(i,r));return e.filter(i=>s.some(a=>a.test(i)))}not(e,t,r){return v.default.not(e,t,{...this.options,...r})}all(e,t,r){return v.default.all(e,t,{...this.options,...r})}capture(e,t,r){let n=/:[^\/\.]+/g,s=e.match(n)||[],i=e.replace(/\//g,"\\/");i=i.replace(/\./g,"\\.");for(let l of s)i=i.replace(l,"([^/\\.]+)");i=i.replace(/\*/g,"([^/]+)");let a=new RegExp(`^${i}$`,r!=null&&r.nocase?"i":""),c=t.match(a);return c?c.slice(1):null}},O=class extends z{s3Client;metadataCache;cacheConfig;pendingRefreshes=new Set;logger;constructor(e={},t={},r={},n=S){super(e),this.logger=n,t.client?this.s3Client=t.client:this.s3Client=new h.S3Client({region:t.region||"us-east-1",endpoint:t.endpoint,credentials:t.credentials,forcePathStyle:t.forcePathStyle,maxAttempts:t.maxRetries||3}),this.cacheConfig={enabled:r.enabled??!0,maxSize:r.maxSize??1e3,ttl:r.ttl??5*60*1e3,refreshThreshold:r.refreshThreshold??80},this.metadataCache=new V.LRUCache({max:this.cacheConfig.maxSize,ttl:this.cacheConfig.ttl})}validateBucket(e){if(!B(e))throw new Error(`Invalid bucket name: ${e}. S3 bucket names must be 3-63 characters, contain only lowercase letters, numbers, periods, and hyphens, and cannot be formatted as an IP address.`)}async getObjectMetadata(e,t){this.validateBucket(e);let r=t.includes("%")?M(t):t,n=`${e}:${r}`;if(this.cacheConfig.enabled){let s=this.metadataCache.get(n);if(s){let i=Date.now()-(this.metadataCache.getRemainingTTL(n)||0),a=this.cacheConfig.ttl*(this.cacheConfig.refreshThreshold/100);return i>a&&!this.pendingRefreshes.has(n)&&(this.pendingRefreshes.add(n),this.refreshMetadataInBackground(e,r,n)),s}}try{let s=await R(async()=>{var i;try{let a=new h.HeadObjectCommand({Bucket:e,Key:r}),c=await this.s3Client.send(a);return{key:r,size:c.ContentLength||0,etag:c.ETag?c.ETag.replace(/^"(.+)"$/,"$1"):"",lastModified:c.LastModified||new Date,contentType:c.ContentType||q.detect(r)}}catch(a){if(typeof a=="object"&&a!==null&&(a.name==="NotFound"||((i=a.$metadata)==null?void 0:i.httpStatusCode)===404))return null;throw a}},5,100,3e4,this.logger);return s&&this.cacheConfig.enabled&&this.metadataCache.set(n,s),s}catch(s){return this.logger.error(`Error fetching S3 object metadata: ${s}`),null}finally{this.pendingRefreshes.delete(n)}}async refreshMetadataInBackground(e,t,r){try{let n=new h.HeadObjectCommand({Bucket:e,Key:t}),s=await this.s3Client.send(n),i={key:t,size:s.ContentLength||0,etag:s.ETag?s.ETag.replace(/^"(.+)"$/,"$1"):"",lastModified:s.LastModified||new Date,contentType:s.ContentType||q.detect(t)};this.metadataCache.set(r,i)}catch(n){this.logger.debug(`Background refresh failed for ${r}: ${n}`)}finally{this.pendingRefreshes.delete(r)}}invalidateCache(e,t){if(this.cacheConfig.enabled){let r=t.includes("%")?M(t):t;this.metadataCache.delete(`${e}:${r}`)}}clearCache(){this.cacheConfig.enabled&&(this.metadataCache.clear(),this.pendingRefreshes.clear())}async listObjects(e,t="",r={}){this.validateBucket(e);let{maxConcurrentRequests:n=5,maxKeysPerRequest:s=1e3,abortSignal:i}=r,a=new Set,c=[void 0],l=(0,I.default)(n),g=[],f=async(x,P)=>{try{let m=await R(()=>x.send(new h.ListObjectsV2Command(P)),5,100,3e4,this.logger),d=[];if(m.Contents){for(let u of m.Contents)if(u.Key){let y=u.Key.includes("%")?M(u.Key):u.Key;d.push(y)}}return{objects:d,nextToken:m.NextContinuationToken}}catch(m){throw this.logger.error(`Error listing S3 objects: ${m}`),m}};for(;c.length>0&&!(i!=null&&i.aborted);){let x=c.shift(),P=l(async()=>{if(i!=null&&i.aborted)return;let m={Bucket:e,Prefix:t,MaxKeys:s};x&&(m.ContinuationToken=x);try{let{objects:d,nextToken:u}=await f(this.s3Client,m);for(let y of d)a.add(y);u&&c.push(u)}catch(d){this.logger.error(`Error processing page: ${d}`)}});g.push(P)}if(await Promise.all(g),i!=null&&i.aborted)throw new Error("S3 object listing was aborted");return Array.from(a)}async putObject(e,t,r,n={}){this.validateBucket(e);let s=n.contentType||q.detect(t);try{let i=new h.PutObjectCommand({Bucket:e,Key:t,Body:r,ContentType:s,ContentEncoding:n.contentEncoding,ContentDisposition:n.contentDisposition,CacheControl:n.cacheControl,Metadata:n.metadata,Tagging:n.tagging}),a=await R(()=>this.s3Client.send(i),5,100,3e4,this.logger);return this.invalidateCache(e,t),a.ETag?a.ETag.replace(/^"(.+)"$/,"$1"):""}catch(i){throw this.logger.error(`Error uploading object to S3: ${i}`),i}}async findMatchingObjects(e,t,r){let n,s,i={};typeof e=="string"?(n=e,s=t||"**",i=r||{}):(n=e.bucket,s=e.patterns,i={prefix:e.prefix,maxConcurrentRequests:e.maxConcurrentRequests,maxKeysPerRequest:e.maxKeysPerRequest,matchOptions:e.matchOptions,useNegation:e.useNegation,abortSignal:e.abortSignal,onProgress:e.onProgress,concurrency:e.concurrency,localCache:e.localCache,handleSpecialChars:e.handleSpecialChars}),this.validateBucket(n);let{prefix:a="",maxConcurrentRequests:c=5,maxKeysPerRequest:l=1e3,matchOptions:g={},useNegation:f=!1,abortSignal:x,onProgress:P,concurrency:m={},localCache:d={enabled:!1,basePath:""},handleSpecialChars:u=!0}=i,y=await this.listObjects(n,a,{maxConcurrentRequests:m.requestLimit||c,maxKeysPerRequest:l,abortSignal:x});u&&(y=y.map(b=>b.includes("%")?M(b):b));let w;return f?w=this.not(y,s,g):w=this.match(y,s,g),P&&P({processed:y.length,total:y.length,matched:w.length,skippedExisting:0}),w}async streamMatchingObjects(e,t,r,n){let s,i,a,c={};typeof e=="string"?(s=e,i=t||"**",a=r||(async()=>{}),c=n||{}):(s=e.bucket,i=e.patterns,a=e.processor,c={prefix:e.prefix,batchSize:e.batchSize,maxConcurrentRequests:e.maxConcurrentRequests,maxKeysPerRequest:e.maxKeysPerRequest,matchOptions:e.matchOptions,maxConcurrentProcessing:e.maxConcurrentProcessing,abortSignal:e.abortSignal,onProgress:e.onProgress,localCache:e.localCache,handleSpecialChars:e.handleSpecialChars}),this.validateBucket(s);let{prefix:l="",batchSize:g=100,maxConcurrentRequests:f=5,maxKeysPerRequest:x=1e3,matchOptions:P={},maxConcurrentProcessing:m=10,abortSignal:d,onProgress:u,localCache:y={enabled:!1,basePath:""},handleSpecialChars:w=!0}=c,b=await this.findMatchingObjects({bucket:s,patterns:i,prefix:l,maxConcurrentRequests:f,maxKeysPerRequest:x,matchOptions:P,abortSignal:d,handleSpecialChars:w}),Z=(0,I.default)(m),p={processed:0,matched:b.length,skipped:0,skippedExisting:0};for(let k=0;k<b.length&&!(d!=null&&d.aborted);k+=g){let Q=b.slice(k,k+g).map(G=>Z(async()=>{if(!(d!=null&&d.aborted)){try{await a(G),p.processed++}catch(X){console.warn(`Error processing object ${G}: ${X}`),p.skipped++}u&&(p.processed+p.skipped)%100===0&&u({processed:p.processed+p.skipped,total:b.length,matched:p.matched,skippedExisting:p.skippedExisting})}}));await Promise.all(Q),u&&u({processed:p.processed+p.skipped,total:b.length,matched:p.matched,skippedExisting:p.skippedExisting})}return p}getS3Client(){return this.s3Client}},E=class{schema;partitionKeys;constructor(e){this.schema=e,this.partitionKeys=Object.keys(e.shape||{})}parse(e){let t=e.split("/").filter(n=>n.length>0),r={};for(let n of t)if(n.includes("=")){let[s,i]=n.split("=",2);s&&i!==void 0&&(r[s]=i)}return this.schema.parse(r)}safeParse(e){let t=e.split("/").filter(n=>n.length>0),r={};for(let n of t)if(n.includes("=")){let[s,i]=n.split("=",2);s&&i!==void 0&&(r[s]=i)}return this.schema.safeParse(r)}format(e){let t=this.schema.parse(e),r=[];for(let n of this.partitionKeys){let s=t[n];s!==void 0&&r.push(`${n}=${s}`)}return r.join("/")}createGlobPattern(e){let t=[];for(let r of this.partitionKeys){let n=r;n in e&&e[n]!==void 0?t.push(`${r}=${e[n]}`):t.push(`${r}=*`)}return t.join("/")}isValid(e){return this.safeParse(e).success}getValidationErrors(e){let t=this.safeParse(e);return t.success?[]:t.error.errors.map(r=>`${r.path.join(".")}: ${r.message}`)}getMissingKeys(e){let t=e.split("/").filter(n=>n.length>0),r=new Set;for(let n of t)if(n.includes("=")){let[s]=n.split("=",1);s&&r.add(s)}return this.partitionKeys.filter(n=>!r.has(n))}extractKeys(e,t){let r=this.safeParse(e);if(!r.success)throw new Error(`Invalid partition path: ${e}`);let n={};for(let s of t)s in r.data&&(n[s]=r.data[s]);return n}transform(e,t){let r=this.parse(e),n={...r,...t(r)};return this.format(n)}matchesGlob(e,t){let r=e.split("/").filter(s=>s.length>0),n=t.split("/").filter(s=>s.length>0);if(r.length!==n.length)return!1;for(let s=0;s<r.length;s++){let i=r[s],a=n[s];if(!this.segmentMatchesPattern(i,a))return!1}return!0}segmentMatchesPattern(e,t){if(e===t)return!0;if(t.includes("=*")){let[n]=t.split("=",1),[s]=e.split("=",1);return n===s}return new RegExp(`^${t.replace(/\*/g,".*").replace(/\?/g,".")}$`).test(e)}},J=(n=>(n.Hourly="hourly",n.Daily="daily",n.Monthly="monthly",n.Yearly="yearly",n))(J||{}),C=class{config;constructor(e){this.config={includeHour:!1,includeMinute:!1,format:"hive",prefix:"",dateFormat:{year:"yyyy",month:"MM",day:"dd",hour:"HH",minute:"mm"},...e},this.config.granularity!=="hourly"&&this.config.includeMinute&&(this.config.includeHour=!0),this.config.granularity==="hourly"&&(this.config.includeHour=!0)}generatePath(e=new Date){let t=e.getFullYear().toString(),r=(e.getMonth()+1).toString().padStart(2,"0"),n=e.getDate().toString().padStart(2,"0"),s=e.getHours().toString().padStart(2,"0"),i=e.getMinutes().toString().padStart(2,"0"),a=[],{format:c,prefix:l,granularity:g}=this.config;return l&&l.length>0&&a.push(l),c==="hive"?a.push(`year=${t}`):a.push(t),(g==="monthly"||g==="daily"||g==="hourly")&&(c==="hive"?a.push(`month=${r}`):a.push(r)),(g==="daily"||g==="hourly")&&(c==="hive"?a.push(`day=${n}`):a.push(n)),this.config.includeHour&&(c==="hive"?a.push(`hour=${s}`):a.push(s)),this.config.includeMinute&&(c==="hive"?a.push(`minute=${i}`):a.push(i)),a.join("/")}generatePathsForRange(e,t){let r=[],n=new Date(e);for(;n<=t;)switch(r.push(this.generatePath(n)),this.config.granularity){case"yearly":n.setFullYear(n.getFullYear()+1);break;case"monthly":n.setMonth(n.getMonth()+1);break;case"daily":n.setDate(n.getDate()+1);break;case"hourly":n.setHours(n.getHours()+1);break;default:n.setDate(n.getDate()+1)}return r}generateCurrentPath(){return this.generatePath(new Date)}},A=class o extends O{static partition={create:e=>new E(e)};static time={daily:e=>new C({granularity:"daily",...e}),hourly:e=>new C({granularity:"hourly",...e}),monthly:e=>new C({granularity:"monthly",...e}),yearly:e=>new C({granularity:"yearly",...e}),custom:e=>new C(e)};static changes={detect:e=>new j(e)};async createBucketIfNotExists(e,t={}){var i,a,c;if(!B(e))throw new Error(`Invalid bucket name: ${e}. S3 bucket names must be 3-63 characters, contain only lowercase letters, numbers, periods, and hyphens, and cannot be formatted as an IP address.`);let r=t.logger||S,n,s=!1;t.client?n=t.client:(n=new h.S3Client({region:t.region||"us-east-1",endpoint:t.endpoint,credentials:t.credentials,forcePathStyle:t.forcePathStyle,maxAttempts:t.maxRetries||3}),s=!0);try{try{return await n.send(new h.HeadBucketCommand({Bucket:e})),r.debug(`Bucket ${e} already exists`),!1}catch(g){let f=(i=g==null?void 0:g.$metadata)==null?void 0:i.httpStatusCode;if(f!==404&&f!==403)throw g;r.info(`Bucket ${e} does not exist, creating it`)}let l={Bucket:e};return(a=t.bucketOptions)!=null&&a.locationConstraint&&t.bucketOptions.locationConstraint!=="us-east-1"&&(l.CreateBucketConfiguration={LocationConstraint:t.bucketOptions.locationConstraint}),(c=t.bucketOptions)!=null&&c.acl&&(l.ACL=t.bucketOptions.acl),await R(async()=>n.send(new h.CreateBucketCommand(l)),5,100,3e4,r),r.info(`Successfully created bucket ${e}`),!0}finally{s&&n.destroy()}}partition=o.partition;time=o.time;changes=o.changes;logger;s3ConfigOptions;constructor(e={}){var r,n,s,i,a,c,l,g;let t=((r=e.loggerOptions)==null?void 0:r.logger)||S;super(e.matchOptions||{},e.s3Options||{},e.cacheOptions||{},t),this.logger=t,this.s3ConfigOptions=e.s3Options||{},((n=e.loggerOptions)==null?void 0:n.level)!==void 0&&this.logger.setLevel(e.loggerOptions.level),this.s3Client=((s=e.s3Options)==null?void 0:s.client)||new h.S3Client({region:((i=e.s3Options)==null?void 0:i.region)||"us-east-1",endpoint:(a=e.s3Options)==null?void 0:a.endpoint,credentials:(c=e.s3Options)==null?void 0:c.credentials,forcePathStyle:(l=e.s3Options)==null?void 0:l.forcePathStyle,maxAttempts:((g=e.s3Options)==null?void 0:g.maxRetries)||3})}setLogger(e){Object.defineProperty(this,"logger",{value:e,writable:!0,configurable:!0})}getLogger(){return this.logger}partitionParser(e){return new E(e)}timePartitioner(e){return new C(e)}changeDetector(e={}){return new j(e)}isMatch(e,t,r){return super.isMatch(e,t,r)}match(e,t,r){return super.match(e,t,r)}matchFast(e,t,r){return super.matchFast(e,t,r)}not(e,t,r){return super.not(e,t,r)}capture(e,t,r){return super.capture(e,t,r)}async findMatchingObjects(e,t,r){if(typeof e=="object"){let{bucket:s,patterns:i,...a}=e;this.validateBucket(s);let c={handleSpecialChars:!0,...a};return super.findMatchingObjects(s,i,c)}this.validateBucket(e);let n={handleSpecialChars:!0,...r};return super.findMatchingObjects(e,t||"",n)}async streamMatchingObjects(e,t,r,n){if(typeof e=="object"){let{bucket:s,patterns:i,processor:a,...c}=e;return super.streamMatchingObjects(s,i,a,c)}if(!r)throw new Error("Processor function is required when using positional parameters");return super.streamMatchingObjects(e,t||"",r,n||{})}async createBucket(e,t){var i;let r={region:this.s3ConfigOptions.region,endpoint:this.s3ConfigOptions.endpoint,credentials:this.s3ConfigOptions.credentials,forcePathStyle:this.s3ConfigOptions.forcePathStyle,maxRetries:this.s3ConfigOptions.maxRetries,bucketOptions:t,logger:this.logger,client:this.getS3Client()};if(!B(e))throw new Error(`Invalid bucket name: ${e}. S3 bucket names must be 3-63 characters, contain only lowercase letters, numbers, periods, and hyphens, and cannot be formatted as an IP address.`);let n=r.logger||S,s=r.client||this.getS3Client();try{try{return await s.send(new h.HeadBucketCommand({Bucket:e})),n.debug(`Bucket ${e} already exists`),!1}catch(c){let l=(i=c==null?void 0:c.$metadata)==null?void 0:i.httpStatusCode;if(l!==404&&l!==403)throw c;n.info(`Bucket ${e} does not exist, creating it`)}let a={Bucket:e};return t!=null&&t.locationConstraint&&t.locationConstraint!=="us-east-1"&&(a.CreateBucketConfiguration={LocationConstraint:t.locationConstraint}),t!=null&&t.acl&&(a.ACL=t.acl),await R(async()=>s.send(new h.CreateBucketCommand(a)),5,100,3e4,n),n.info(`Successfully created bucket ${e}`),!0}catch(a){throw n.error(`Failed to create bucket ${e}: ${a}`),a}}},le=A;0&&(module.exports={ChangeDetectionEngine,ChangeType,ConsoleLogger,ContentType,HivePartitionParser,LogLevel,NoopLogger,PathMatcher,Rehiver,S3PathMatcher,TimeGranularity,TimePartitionGenerator,decodeS3Key,encodeS3Key,getGlobalLogger,isValidBucketName,setGlobalLogger}); //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgZnMgZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7XG5cdHR5cGUgQnVja2V0TG9jYXRpb25Db25zdHJhaW50LFxuXHRDcmVhdGVCdWNrZXRDb21tYW5kLFxuXHR0eXBlIENyZWF0ZUJ1Y2tldENvbW1hbmRJbnB1dCxcblx0SGVhZEJ1Y2tldENvbW1hbmQsXG5cdEhlYWRPYmplY3RDb21tYW5kLFxuXHRMaXN0T2JqZWN0c1YyQ29tbWFuZCxcblx0dHlwZSBMaXN0T2JqZWN0c1YyQ29tbWFuZElucHV0LFxuXHRQdXRPYmplY3RDb21tYW5kLFxuXHRTM0NsaWVudCxcbn0gZnJvbSBcIkBhd3Mtc2RrL2NsaWVudC1zM1wiO1xuaW1wb3J0IHsgTFJVQ2FjaGUgfSBmcm9tIFwibHJ1LWNhY2hlXCI7XG5pbXBvcnQgbWljcm9tYXRjaCBmcm9tIFwibWljcm9tYXRjaFwiO1xuaW1wb3J0IG1pbWUgZnJvbSBcIm1pbWUtdHlwZXNcIjtcbmltcG9ydCBwTGltaXQgZnJvbSBcInAtbGltaXRcIjtcbmltcG9ydCB0eXBlIHsgeiB9IGZyb20gXCJ6b2RcIjtcblxuLy8gSGVscGVyIGZ1bmN0aW9uIHRvIGNoZWNrIGlmIGEgZmlsZSBleGlzdHNcbmNvbnN0IHBhdGhFeGlzdHMgPSBhc3luYyAoZmlsZVBhdGg6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuXHR0cnkge1xuXHRcdGF3YWl0IGZzLmFjY2VzcyhmaWxlUGF0aCk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn07XG5cbi8qKlxuICogVmFsaWRhdGUgUzMgYnVja2V0IG5hbWUgYWNjb3JkaW5nIHRvIEFXUyBuYW1pbmcgcnVsZXNcbiAqIEBwYXJhbSBidWNrZXROYW1lIE5hbWUgb2YgdGhlIGJ1Y2tldCB0byB2YWxpZGF0ZVxuICogQHJldHVybnMgVHJ1ZSBpZiB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkQnVja2V0TmFtZShidWNrZXROYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcblx0Ly8gQVdTIGJ1Y2tldCBuYW1pbmcgcnVsZXNcblx0Ly8gLSAzLTYzIGNoYXJhY3RlcnMgbG9uZ1xuXHQvLyAtIENhbiBjb250YWluIGxvd2VyY2FzZSBsZXR0ZXJzLCBudW1iZXJzLCBkb3RzLCBhbmQgaHlwaGVuc1xuXHQvLyAtIE11c3Qgc3RhcnQgYW5kIGVuZCB3aXRoIGEgbGV0dGVyIG9yIG51bWJlclxuXHQvLyAtIENhbm5vdCBjb250YWluIHR3byBhZGphY2VudCBwZXJpb2RzXG5cdC8vIC0gQ2Fubm90IGJlIGZvcm1hdHRlZCBhcyBhbiBJUCBhZGRyZXNzIChlLmcuLCAxOTIuMTY4LjUuNClcblx0Ly8gLSBDYW5ub3Qgc3RhcnQgd2l0aCB0aGUgcHJlZml4ICd4bi0tJ1xuXHQvLyAtIENhbm5vdCBlbmQgd2l0aCB0aGUgc3VmZml4ICctczNhbGlhcydcblxuXHRpZiAoIWJ1Y2tldE5hbWUgfHwgYnVja2V0TmFtZS5sZW5ndGggPCAzIHx8IGJ1Y2tldE5hbWUubGVuZ3RoID4gNjMpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHQvLyBDaGVjayBpZiBzdGFydHMvZW5kcyB3aXRoIGxldHRlciBvciBudW1iZXJcblx0aWYgKCEvXlthLXowLTldLipbYS16MC05XSQvaS50ZXN0KGJ1Y2tldE5hbWUpKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0Ly8gQ2hlY2sgZm9yIHZhbGlkIGNoYXJhY3RlcnNcblx0aWYgKCEvXlthLXowLTkuLV0rJC9pLnRlc3QoYnVja2V0TmFtZSkpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHQvLyBDaGVjayBmb3IgYWRqYWNlbnQgcGVyaW9kc1xuXHRpZiAoYnVja2V0TmFtZS5pbmNsdWRlcyhcIi4uXCIpKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0Ly8gQ2hlY2sgZm9yIElQIGFkZHJlc3MgZm9ybWF0XG5cdGlmICgvXlxcZCtcXC5cXGQrXFwuXFxkK1xcLlxcZCskLy50ZXN0KGJ1Y2tldE5hbWUpKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0Ly8gQ2hlY2sgZm9yIGZvcmJpZGRlbiBwcmVmaXhlcy9zdWZmaXhlc1xuXHRpZiAoYnVja2V0TmFtZS5zdGFydHNXaXRoKFwieG4tLVwiKSB8fCBidWNrZXROYW1lLmVuZHNXaXRoKFwiLXMzYWxpYXNcIikpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRyZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBMb2cgbGV2ZWxzIGZvciB0aGUgbG9nZ2VyXG4gKi9cbmV4cG9ydCBlbnVtIExvZ0xldmVsIHtcblx0RGVidWcgPSAwLFxuXHRJbmZvID0gMSxcblx0V2FybiA9IDIsXG5cdEVycm9yID0gMyxcblx0Tm9uZSA9IDEwMCxcbn1cblxuLyoqXG4gKiBMb2dnZXIgaW50ZXJmYWNlIGZvciBjdXN0b20gbG9nZ2luZyBpbXBsZW1lbnRhdGlvbnNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMb2dnZXIge1xuXHRkZWJ1ZyhtZXNzYWdlOiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSk6IHZvaWQ7XG5cdGluZm8obWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiB2b2lkO1xuXHR3YXJuKG1lc3NhZ2U6IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKTogdm9pZDtcblx0ZXJyb3IobWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiB2b2lkO1xuXHRzZXRMZXZlbChsZXZlbDogTG9nTGV2ZWwpOiB2b2lkO1xuXHRnZXRMZXZlbCgpOiBMb2dMZXZlbDtcbn1cblxuLyoqXG4gKiBDb250ZW50IHR5cGUgZGV0ZWN0aW9uIGFuZCBoYW5kbGluZyB1dGlsaXRpZXNcbiAqL1xuZXhwb3J0IGNvbnN0IENvbnRlbnRUeXBlID0ge1xuXHQvKipcblx0ICogRGV0ZWN0IGNvbnRlbnQgdHlwZSBmcm9tIGEgZmlsZSBwYXRoIG9yIGtleVxuXHQgKiBAcGFyYW0gcGF0aCBQYXRoIG9yIGtleSB0byBkZXRlcm1pbmUgY29udGVudCB0eXBlIGZyb21cblx0ICogQHJldHVybnMgVGhlIGRldGVjdGVkIE1JTUUgdHlwZSBvciBhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0gaWYgdW5rbm93blxuXHQgKi9cblx0ZGV0ZWN0KHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG5cdFx0Y29uc3QgY29udGVudFR5cGUgPSBtaW1lLmxvb2t1cChwYXRoKTtcblx0XHRyZXR1cm4gY29udGVudFR5cGUgfHwgXCJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1cIjtcblx0fSxcblxuXHQvKipcblx0ICogR2V0IGNoYXJzZXQgZm9yIGEgZ2l2ZW4gY29udGVudCB0eXBlXG5cdCAqIEBwYXJhbSBjb250ZW50VHlwZSBNSU1FIHR5cGUgdG8gZ2V0IGNoYXJzZXQgZm9yXG5cdCAqIEByZXR1cm5zIENoYXJzZXQgc3RyaW5nIG9yIG51bGwgaWYgbm90IGFwcGxpY2FibGVcblx0ICovXG5cdGNoYXJzZXQoY29udGVudFR5cGU6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuXHRcdHJldHVybiBtaW1lLmNoYXJzZXQoY29udGVudFR5cGUpIHx8IG51bGw7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEdldCBmaWxlIGV4dGVuc2lvbiBmb3IgYSBjb250ZW50IHR5cGVcblx0ICogQHBhcmFtIGNvbnRlbnRUeXBlIE1JTUUgdHlwZVxuXHQgKiBAcmV0dXJucyBGaWxlIGV4dGVuc2lvbiAod2l0aCBkb3QpIG9yIGZhbHNlIGlmIG5vdCBmb3VuZFxuXHQgKi9cblx0ZXh0ZW5zaW9uKGNvbnRlbnRUeXBlOiBzdHJpbmcpOiBzdHJpbmcgfCBmYWxzZSB7XG5cdFx0cmV0dXJuIG1pbWUuZXh0ZW5zaW9uKGNvbnRlbnRUeXBlKTtcblx0fSxcblxuXHQvKipcblx0ICogQ2hlY2sgaWYgYSBjb250ZW50IHR5cGUgcmVwcmVzZW50cyB0ZXh0IGRhdGFcblx0ICogQHBhcmFtIGNvbnRlbnRUeXBlIE1JTUUgdHlwZSB0byBjaGVja1xuXHQgKiBAcmV0dXJucyBUcnVlIGlmIGNvbnRlbnQgdHlwZSBpcyB0ZXh0LWJhc2VkXG5cdCAqL1xuXHRpc1RleHQoY29udGVudFR5cGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiAoXG5cdFx0XHRjb250ZW50VHlwZS5zdGFydHNXaXRoKFwidGV4dC9cIikgfHxcblx0XHRcdGNvbnRlbnRUeXBlID09PSBcImFwcGxpY2F0aW9uL2pzb25cIiB8fFxuXHRcdFx0Y29udGVudFR5cGUgPT09IFwiYXBwbGljYXRpb24veG1sXCIgfHxcblx0XHRcdGNvbnRlbnRUeXBlID09PSBcImFwcGxpY2F0aW9uL2phdmFzY3JpcHRcIiB8fFxuXHRcdFx0Y29udGVudFR5cGUgPT09IFwiYXBwbGljYXRpb24vdHlwZXNjcmlwdFwiXG5cdFx0KTtcblx0fSxcblxuXHQvKipcblx0ICogQ2hlY2sgaWYgYSBjb250ZW50IHR5cGUgcmVwcmVzZW50cyBiaW5hcnkgZGF0YVxuXHQgKiBAcGFyYW0gY29udGVudFR5cGUgTUlNRSB0eXBlIHRvIGNoZWNrXG5cdCAqIEByZXR1cm5zIFRydWUgaWYgY29udGVudCB0eXBlIGlzIGJpbmFyeVxuXHQgKi9cblx0aXNCaW5hcnkoY29udGVudFR5cGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiAhdGhpcy5pc1RleHQoY29udGVudFR5cGUpO1xuXHR9LFxufTtcblxuLyoqXG4gKiBEZWZhdWx0IGxvZ2dlciBpbXBsZW1lbnRhdGlvbiB1c2luZyBjb25zb2xlXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25zb2xlTG9nZ2VyIGltcGxlbWVudHMgTG9nZ2VyIHtcblx0cHJpdmF0ZSBsZXZlbDogTG9nTGV2ZWwgPSBMb2dMZXZlbC5JbmZvO1xuXG5cdGNvbnN0cnVjdG9yKGxldmVsPzogTG9nTGV2ZWwpIHtcblx0XHRpZiAobGV2ZWwgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0dGhpcy5sZXZlbCA9IGxldmVsO1xuXHRcdH1cblx0fVxuXG5cdGRlYnVnKG1lc3NhZ2U6IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKTogdm9pZCB7XG5cdFx0aWYgKHRoaXMubGV2ZWwgPD0gTG9nTGV2ZWwuRGVidWcpIHtcblx0XHRcdGNvbnNvbGUuZGVidWcoYFtERUJVR10gJHttZXNzYWdlfWAsIC4uLmFyZ3MpO1xuXHRcdH1cblx0fVxuXG5cdGluZm8obWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiB2b2lkIHtcblx0XHRpZiAodGhpcy5sZXZlbCA8PSBMb2dMZXZlbC5JbmZvKSB7XG5cdFx0XHRjb25zb2xlLmluZm8oYFtJTkZPXSAke21lc3NhZ2V9YCwgLi4uYXJncyk7XG5cdFx0fVxuXHR9XG5cblx0d2FybihtZXNzYWdlOiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSk6IHZvaWQge1xuXHRcdGlmICh0aGlzLmxldmVsIDw9IExvZ0xldmVsLldhcm4pIHtcblx0XHRcdGNvbnNvbGUud2FybihgW1dBUk5dICR7bWVzc2FnZX1gLCAuLi5hcmdzKTtcblx0XHR9XG5cdH1cblxuXHRlcnJvcihtZXNzYWdlOiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSk6IHZvaWQge1xuXHRcdGlmICh0aGlzLmxldmVsIDw9IExvZ0xldmVsLkVycm9yKSB7XG5cdFx0XHRjb25zb2xlLmVycm9yKGBbRVJST1JdICR7bWVzc2FnZX1gLCAuLi5hcmdzKTtcblx0XHR9XG5cdH1cblxuXHRzZXRMZXZlbChsZXZlbDogTG9nTGV2ZWwpOiB2b2lkIHtcblx0XHR0aGlzLmxldmVsID0gbGV2ZWw7XG5cdH1cblxuXHRnZXRMZXZlbCgpOiBMb2dMZXZlbCB7XG5cdFx0cmV0dXJuIHRoaXMubGV2ZWw7XG5cdH1cbn1cblxuLyoqXG4gKiBOby1vcCBsb2dnZXIgdGhhdCBkaXNjYXJkcyBhbGwgbG9nIG1lc3NhZ2VzXG4gKi9cbmV4cG9ydCBjbGFzcyBOb29wTG9nZ2VyIGltcGxlbWVudHMgTG9nZ2VyIHtcblx0ZGVidWcoKTogdm9pZCB7fVxuXHRpbmZvKCk6IHZvaWQge31cblx0d2FybigpOiB2b2lkIHt9XG5cdGVycm9yKCk6IHZvaWQge31cblx0c2V0TGV2ZWwoKTogdm9pZCB7fVxuXHRnZXRMZXZlbCgpOiBMb2dMZXZlbCB7XG5cdFx0cmV0dXJuIExvZ0xldmVsLk5vbmU7XG5cdH1cbn1cblxuLy8gR2xvYmFsIGxvZ2dlciBpbnN0YW5jZVxubGV0IGdsb2JhbExvZ2dlcjogTG9nZ2VyID0gbmV3IENvbnNvbGVMb2dnZXIoKTtcblxuLyoqXG4gKiBTZXQgdGhlIGdsb2JhbCBsb2dnZXIgaW5zdGFuY2VcbiAqIEBwYXJhbSBsb2dnZXIgVGhlIGxvZ2dlciBpbnN0YW5jZSB0byB1c2UgZ2xvYmFsbHlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldEdsb2JhbExvZ2dlcihsb2dnZXI6IExvZ2dlcik6IHZvaWQge1xuXHRnbG9iYWxMb2dnZXIgPSBsb2dnZXI7XG59XG5cbi8qKlxuICogR2V0IHRoZSBjdXJyZW50IGdsb2JhbCBsb2dnZXIgaW5zdGFuY2VcbiAqIEByZXR1cm5zIFRoZSBjdXJyZW50IGdsb2JhbCBsb2dnZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEdsb2JhbExvZ2dlcigpOiBMb2dnZXIge1xuXHRyZXR1cm4gZ2xvYmFsTG9nZ2VyO1xufVxuXG4vKipcbiAqIFNsZWVwIGZ1bmN0aW9uIGZvciByZXRyeSBkZWxheXNcbiAqIEBwYXJhbSBtcyBNaWxsaXNlY29uZHMgdG8gc2xlZXBcbiAqL1xuY29uc3Qgc2xlZXAgPSAobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4gPT5cblx0bmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcblxuLyoqXG4gKiBSZXRyeSBhIGZ1bmN0aW9uIHdpdGggZXhwb25lbnRpYWwgYmFja29mZlxuICogQHBhcmFtIGZuIEZ1bmN0aW9uIHRvIHJldHJ5XG4gKiBAcGFyYW0gcmV0cmllcyBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzXG4gKiBAcGFyYW0gYmFzZURlbGF5IEJhc2UgZGVsYXkgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcGFyYW0gbWF4RGVsYXkgTWF4aW11bSBkZWxheSBpbiBtaWxsaXNlY29uZHNcbiAqIEBwYXJhbSBsb2dnZXIgT3B0aW9uYWwgbG9nZ2VyIHRvIHVzZSBpbnN0ZWFkIG9mIGdsb2JhbCBsb2dnZXJcbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmV0cnlXaXRoQmFja29mZjxUPihcblx0Zm46ICgpID0+IFByb21pc2U8VD4sXG5cdHJldHJpZXMgPSA1LFxuXHRiYXNlRGVsYXkgPSAxMDAsXG5cdG1heERlbGF5ID0gMzAwMDAsXG5cdGxvZ2dlcjogTG9nZ2VyID0gZ2xvYmFsTG9nZ2VyLFxuKTogUHJvbWlzZTxUPiB7XG5cdGxldCBsYXN0RXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkO1xuXG5cdGZvciAobGV0IGkgPSAwOyBpIDwgcmV0cmllczsgaSsrKSB7XG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiBhd2FpdCBmbigpO1xuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRsYXN0RXJyb3IgPSBlcnJvciBhcyBFcnJvcjtcblxuXHRcdFx0Ly8gT25seSByZXRyeSBvbiB0aHJvdHRsaW5nLCB0aW1lb3V0LCBvciBuZXR3b3JrIGVycm9yc1xuXHRcdFx0Y29uc3QgZXJyb3JDb2RlID1cblx0XHRcdFx0KGVycm9yIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KT8uQ29kZSB8fFxuXHRcdFx0XHQoZXJyb3IgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pPy5jb2RlO1xuXHRcdFx0Y29uc3QgZXJyb3JNZXNzYWdlID0gKGVycm9yIGFzIEVycm9yKT8ubWVzc2FnZSB8fCBcIlwiO1xuXHRcdFx0Y29uc3QgaXNSZXRyeWFibGUgPVxuXHRcdFx0XHRlcnJvckNvZGUgPT09IFwiVGhyb3R0bGluZ0V4Y2VwdGlvblwiIHx8XG5cdFx0XHRcdGVycm9yQ29kZSA9PT0gXCJSZXF1ZXN0VGltZW91dFwiIHx8XG5cdFx0XHRcdGVycm9yQ29kZSA9PT0gXCJOZXR3b3JraW5nRXJyb3JcIiB8fFxuXHRcdFx0XHRlcnJvckNvZGUgPT09IFwiVGltZW91dEVycm9yXCIgfHxcblx0XHRcdFx0ZXJyb3JDb2RlID09PSBcIlJlcXVlc3RUaW1lVG9vU2tld2VkXCIgfHxcblx0XHRcdFx0ZXJyb3JDb2RlID09PSBcIlByb3Zpc2lvbmVkVGhyb3VnaHB1dEV4Y2VlZGVkRXhjZXB0aW9uXCIgfHxcblx0XHRcdFx0ZXJyb3JDb2RlID09PSBcIlNsb3dEb3duXCIgfHxcblx0XHRcdFx0ZXJyb3JDb2RlID09PSBcIkludGVybmFsRXJyb3JcIiB8fFxuXHRcdFx0XHRlcnJvckNvZGUgPT09IFwiU2VydmljZVVuYXZhaWxhYmxlXCIgfHxcblx0XHRcdFx0ZXJyb3JDb2RlID09PSBcIjQyOVwiIHx8XG5cdFx0XHRcdGVycm9yQ29kZSA9PT0gXCI1MDBcIiB8fFxuXHRcdFx0XHRlcnJvckNvZGUgPT09IFwiNTAzXCIgfHxcblx0XHRcdFx0ZXJyb3JNZXNzYWdlLmluY2x1ZGVzKFwidGltZW91dFwiKSB8fFxuXHRcdFx0XHRlcnJvck1lc3NhZ2UuaW5jbHVkZXMoXCJ0aHJvdHRsXCIpIHx8XG5cdFx0XHRcdGVycm9yTWVzc2FnZS5pbmNsdWRlcyhcIm5ldHdvcmtcIikgfHxcblx0XHRcdFx0ZXJyb3JNZXNzYWdlLmluY2x1ZGVzKFwiY29ubmVjdGlvblwiKTtcblxuXHRcdFx0aWYgKCFpc1JldHJ5YWJsZSkge1xuXHRcdFx0XHR0aHJvdyBlcnJvcjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ2FsY3VsYXRlIGV4cG9uZW50aWFsIGJhY2tvZmYgd2l0aCBqaXR0ZXJcblx0XHRcdGNvbnN0IGRlbGF5ID0gTWF0aC5taW4oXG5cdFx0XHRcdG1heERlbGF5LFxuXHRcdFx0XHRiYXNlRGVsYXkgKiAyICoqIGkgKiAoMC44ICsgTWF0aC5yYW5kb20oKSAqIDAuNCksXG5cdFx0XHQpO1xuXG5cdFx0XHQvLyBMb2cgcmV0cnkgYXR0ZW1wdFxuXHRcdFx0bG9nZ2VyLmRlYnVnKFxuXHRcdFx0XHRgUzMgb3BlcmF0aW9uIGZhaWxlZCAoYXR0ZW1wdCAke2kgKyAxfS8ke3JldHJpZXN9KSwgcmV0cnlpbmcgaW4gJHtNYXRoLnJvdW5kKGRlbGF5KX1tczogJHtlcnJvckNvZGUgfHwgZXJyb3JNZXNzYWdlfWAsXG5cdFx0XHQpO1xuXG5cdFx0XHRhd2FpdCBzbGVlcChkZWxheSk7XG5cdFx0fVxuXHR9XG5cblx0dGhyb3cgbGFzdEVycm9yO1xufVxuXG4vKipcbiAqIFNhZmVseSBlbmNvZGVzIFMzIGtleXMgZm9yIHVzZSBpbiBVUkxzIGFuZCBoYW5kbGluZyBzcGVjaWFsIGNoYXJhY3RlcnNcbiAqIEBwYXJhbSBrZXkgUzMga2V5IHRvIGVuY29kZVxuICogQHJldHVybnMgVVJMLWVuY29kZWQga2V5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmNvZGVTM0tleShrZXk6IHN0cmluZyk6IHN0cmluZyB7XG5cdC8vIEVuY29kZSBhbGwgc3BlY2lhbCBjaGFyYWN0ZXJzIGV4Y2VwdCBmb3J3YXJkIHNsYXNoZXNcblx0Ly8gVGhpcyBtYWtlcyB0aGUga2V5IHNhZmUgZm9yIFVSTCB1c2UgYW5kIGZpbGUgb3BlcmF0aW9uc1xuXHRyZXR1cm4ga2V5XG5cdFx0LnNwbGl0KFwiL1wiKVxuXHRcdC5tYXAoKHNlZ21lbnQpID0+IGVuY29kZVVSSUNvbXBvbmVudChzZWdtZW50KSlcblx0XHQuam9pbihcIi9cIik7XG59XG5cbi8qKlxuICogU2FmZWx5IGRlY29kZXMgUzMga2V5cyBmcm9tIFVSTHNcbiAqIEBwYXJhbSBlbmNvZGVkS2V5IFVSTC1lbmNvZGVkIFMzIGtleVxuICogQHJldHVybnMgRGVjb2RlZCBrZXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZVMzS2V5KGVuY29kZWRLZXk6IHN0cmluZyk6IHN0cmluZyB7XG5cdC8vIERlY29kZSBhbGwgVVJMLWVuY29kZWQgY29tcG9uZW50c1xuXHRyZXR1cm4gZW5jb2RlZEtleVxuXHRcdC5zcGxpdChcIi9cIilcblx0XHQubWFwKChzZWdtZW50KSA9PiBkZWNvZGVVUklDb21wb25lbnQoc2VnbWVudCkpXG5cdFx0LmpvaW4oXCIvXCIpO1xufVxuXG4vKipcbiAqIEludGVyZmFjZSBmb3Igb2JqZWN0IG1ldGFkYXRhXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT2JqZWN0TWV0YWRhdGEge1xuXHRrZXk6IHN0cmluZztcblx0c2l6ZTogbnVtYmVyO1xuXHRldGFnOiBzdHJpbmc7XG5cdGxhc3RNb2RpZmllZDogRGF0ZTtcblx0Y29udGVudFR5cGU/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogUzMgb2JqZWN0IGludGVyZmFjZSBtYXRjaGluZyBBV1MgU0RLIHN0cnVjdHVyZSB3aXRoIGNhbWVsQ2FzZSBwcm9wZXJ0aWVzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUzNPYmplY3Qge1xuXHRrZXk/OiBzdHJpbmc7XG5cdHNpemU/OiBudW1iZXI7XG5cdGV0YWc/OiBzdHJpbmc7XG5cdGxhc3RNb2RpZmllZD86IERhdGU7XG59XG5cbi8qKlxuICogQ2hhbmdlIHR5cGVzIGZvciB0cmFja2luZyBvYmplY3QgbW9kaWZpY2F0aW9uc1xuICovXG5leHBvcnQgZW51bSBDaGFuZ2VUeXBlIHtcblx0QWRkZWQgPSBcImFkZGVkXCIsXG5cdE1vZGlmaWVkID0gXCJtb2RpZmllZFwiLFxuXHREZWxldGVkID0gXCJkZWxldGVkXCIsXG5cdFVuY2hhbmdlZCA9IFwidW5jaGFuZ2VkXCIsXG59XG5cbi8qKlxuICogUmVzdWx0IG9mIGEgY2hhbmdlIGRldGVjdGlvbiBjb21wYXJpc29uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2hhbmdlUmVzdWx0IHtcblx0Y2hhbmdlVHlwZTogQ2hhbmdlVHlwZTtcblx0b2JqZWN0OiBPYmplY3RNZXRhZGF0YTtcblx0cHJldmlvdXNWZXJzaW9uPzogT2JqZWN0TWV0YWRhdGE7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgY2hhbmdlIGRldGVjdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIENoYW5nZURldGVjdGlvbk9wdGlvbnMge1xuXHRzdGF0ZUZpbGVQYXRoPzogc3RyaW5nO1xuXHRjb21wYXJlTW9kZT86IFwicXVpY2tcIiB8IFwiZnVsbFwiO1xuXHRpZ25vcmVFdGFnT25TaXplPzogYm9vbGVhbjtcblx0dHJhY2tEZWxldGVkPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBFbmdpbmUgZm9yIGRldGVjdGluZyBjaGFuZ2VzIGluIFMzIG9iamVjdHMgYmV0d2VlbiBydW5zXG4gKi9cbmV4cG9ydCBjbGFzcyBDaGFuZ2VEZXRlY3Rpb25FbmdpbmUge1xuXHRwcml2YXRlIHByZXZpb3VzU3RhdGU6IE1hcDxzdHJpbmcsIE9iamVjdE1ldGFkYXRhPiA9IG5ldyBNYXAoKTtcblx0cHJpdmF0ZSBjdXJyZW50U3RhdGU6IE1hcDxzdHJpbmcsIE9iamVjdE1ldGFkYXRhPiA9IG5ldyBNYXAoKTtcblx0cHJpdmF0ZSBvcHRpb25zOiBDaGFuZ2VEZXRlY3Rpb25PcHRpb25zO1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IENoYW5nZURldGVjdGlvbkVuZ2luZVxuXHQgKiBAcGFyYW0gb3B0aW9ucyBFbmdpbmUgY29uZmlndXJhdGlvbiBvcHRpb25zXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcihvcHRpb25zOiBDaGFuZ2VEZXRlY3Rpb25PcHRpb25zID0ge30pIHtcblx0XHR0aGlzLm9wdGlvbnMgPSB7XG5cdFx0XHRzdGF0ZUZpbGVQYXRoOiBcImNoYW5nZS1kZXRlY3Rpb24tc3RhdGUuanNvblwiLFxuXHRcdFx0Y29tcGFyZU1vZGU6IFwiZnVsbFwiLFxuXHRcdFx0aWdub3JlRXRhZ09uU2l6ZTogZmFsc2UsXG5cdFx0XHR0cmFja0RlbGV0ZWQ6IHRydWUsXG5cdFx0XHQuLi5vcHRpb25zLFxuXHRcdH07XG5cdH1cblxuXHQvKipcblx0ICogTG9hZHMgdGhlIHByZXZpb3VzIHN0YXRlIGZyb20gYSBKU09OIGZpbGUgb3IgY3JlYXRlcyBhIG5ldyBzdGF0ZSBpZiBub25lIGV4aXN0c1xuXHQgKi9cblx0YXN5bmMgbG9hZFByZXZpb3VzU3RhdGUoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKCF0aGlzLm9wdGlvbnMuc3RhdGVGaWxlUGF0aCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHRyeSB7XG5cdFx0XHRjb25zdCBzdGF0ZURhdGEgPSBhd2FpdCBmcy5yZWFkRmlsZSh0aGlzLm9wdGlvbnMuc3RhdGVGaWxlUGF0aCwgXCJ1dGYtOFwiKTtcblx0XHRcdGNvbnN0IHBhcnNlZFN0YXRlID0gSlNPTi5wYXJzZShzdGF0ZURhdGEpO1xuXG5cdFx0XHQvLyBDb252ZXJ0IHRoZSBhcnJheSBiYWNrIHRvIGEgTWFwXG5cdFx0XHR0aGlzLnByZXZpb3VzU3RhdGUgPSBuZXcgTWFwKFxuXHRcdFx0XHRPYmplY3QuZW50cmllcyhwYXJzZWRTdGF0ZSkubWFwKChba2V5LCB2YWx1ZV0pID0+IHtcblx0XHRcdFx0XHRjb25zdCBtZXRhZGF0YSA9IHZhbHVlIGFzIE9iamVjdE1ldGFkYXRhO1xuXHRcdFx0XHRcdC8vIENvbnZlcnQgSVNPIHN0cmluZyBiYWNrIHRvIERhdGUgb2JqZWN0XG5cdFx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdFx0bWV0YWRhdGEubGFzdE1vZGlmaWVkICYmXG5cdFx0XHRcdFx0XHR0eXBlb2YgbWV0YWRhdGEubGFzdE1vZGlmaWVkID09PSBcInN0cmluZ1wiXG5cdFx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0XHRtZXRhZGF0YS5sYXN0TW9kaWZpZWQgPSBuZXcgRGF0ZShtZXRhZGF0YS5sYXN0TW9kaWZpZWQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gW2tleSwgbWV0YWRhdGFdO1xuXHRcdFx0XHR9KSxcblx0XHRcdCk7XG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdC8vIElmIGZpbGUgZG9lc24ndCBleGlzdCBvciBpcyBpbnZhbGlkLCBzdGFydCB3aXRoIGFuIGVtcHR5IHN0YXRlXG5cdFx0XHR0aGlzLnByZXZpb3VzU3RhdGUgPSBuZXcgTWFwKCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNhdmVzIHRoZSBjdXJyZW50IHN0YXRlIHRvIGEgSlNPTiBmaWxlXG5cdCAqL1xuXHRhc3luYyBzYXZlQ3VycmVudFN0YXRlKCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGlmICghdGhpcy5vcHRpb25zLnN0YXRlRmlsZVBhdGgpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBDb252ZXJ0IE1hcCB0byBhIHBsYWluIG9iamVjdCBmb3Igc2VyaWFsaXphdGlvblxuXHRcdGNvbnN0IHN0YXRlT2JqZWN0ID0gT2JqZWN0LmZyb21FbnRyaWVzKHRoaXMuY3VycmVudFN0YXRlKTtcblx0XHRjb25zdCBzdGF0ZURhdGEgPSBKU09OLnN0cmluZ2lmeShzdGF0ZU9iamVjdCwgbnVsbCwgMik7XG5cblx0XHQvLyBFbnN1cmUgZGlyZWN0b3J5IGV4aXN0c1xuXHRcdGNvbnN0IGRpciA9IHBhdGguZGlybmFtZSh0aGlzLm9wdGlvbnMuc3RhdGVGaWxlUGF0aCk7XG5cdFx0YXdhaXQgZnMubWtkaXIoZGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuXHRcdC8vIFdyaXRlIHN0YXRlIGZpbGVcblx0XHRhd2FpdCBmcy53cml0ZUZpbGUodGhpcy5vcHRpb25zLnN0YXRlRmlsZVBhdGgsIHN0YXRlRGF0YSwgXCJ1dGYtOFwiKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGFuIG9iamVjdCB0byB0aGUgY3VycmVudCBzdGF0ZVxuXHQgKiBAcGFyYW0gb2JqZWN0IE9iamVjdCBtZXRhZGF0YSB0byB0cmFja1xuXHQgKi9cblx0YWRkT2JqZWN0KG9iamVjdDogT2JqZWN0TWV0YWRhdGEpOiB2b2lkIHtcblx0XHR0aGlzLmN1cnJlbnRTdGF0ZS5zZXQob2JqZWN0LmtleSwgb2JqZWN0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIG11bHRpcGxlIG9iamVjdHMgdG8gdGhlIGN1cnJlbnQgc3RhdGVcblx0ICogQHBhcmFtIG9iamVjdHMgQXJyYXkgb2Ygb2JqZWN0IG1ldGFkYXRhXG5cdCAqL1xuXHRhZGRPYmplY3RzKG9iamVjdHM6IE9iamVjdE1ldGFkYXRhW10pOiB2b2lkIHtcblx0XHRmb3IgKGNvbnN0IG9iamVjdCBvZiBvYmplY3RzKSB7XG5cdFx0XHR0aGlzLmFkZE9iamVjdChvYmplY3QpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhbiBTMyBvYmplY3QgdG8gb3VyIG1ldGFkYXRhIGZvcm1hdFxuXHQgKiBAcGFyYW0gczNPYmplY3QgUzMgb2JqZWN0IGZyb20gQVdTIFNES1xuXHQgKiBAcmV0dXJucyBOb3JtYWxpemVkIG9iamVjdCBtZXRhZGF0YVxuXHQgKi9cblx0c3RhdGljIGZyb21TM09iamVjdChzM09iamVjdDogUzNPYmplY3QpOiBPYmplY3RNZXRhZGF0YSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdGtleTogczNPYmplY3Qua2V5IHx8IFwiXCIsXG5cdFx0XHRzaXplOiBzM09iamVjdC5zaXplIHx8IDAsXG5cdFx0XHRldGFnOiAoczNPYmplY3QuZXRhZyB8fCBcIlwiKS5yZXBsYWNlKC9cIi9nLCBcIlwiKSwgLy8gUmVtb3ZlIHF1b3RlcyBmcm9tIEVUYWdcblx0XHRcdGxhc3RNb2RpZmllZDogczNPYmplY3QubGFzdE1vZGlmaWVkIHx8IG5ldyBEYXRlKCksXG5cdFx0fTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZXRlcm1pbmVzIGlmIGFuIG9iamVjdCBoYXMgY2hhbmdlZCBiZXR3ZWVuIHN0YXRlc1xuXHQgKiBAcGFyYW0gY3VycmVudCBDdXJyZW50IG9iamVjdCBtZXRhZGF0YVxuXHQgKiBAcGFyYW0gcHJldmlvdXMgUHJldmlvdXMgb2JqZWN0IG1ldGFkYXRhXG5cdCAqIEByZXR1cm5zIFRydWUgaWYgdGhlIG9iamVjdCBoYXMgY2hhbmdlZFxuXHQgKi9cblx0cHJpdmF0ZSBoYXNPYmplY3RDaGFuZ2VkKFxuXHRcdGN1cnJlbnQ6IE9iamVjdE1ldGFkYXRhLFxuXHRcdHByZXZpb3VzOiBPYmplY3RNZXRhZGF0YSxcblx0KTogYm9vbGVhbiB7XG5cdFx0aWYgKHRoaXMub3B0aW9ucy5jb21wYXJlTW9kZSA9PT0gXCJxdWlja1wiKSB7XG5cdFx0XHQvLyBRdWljayBjb21wYXJpc29uIC0gb25seSBjaGVjayBzaXplIGFuZCBsYXN0IG1vZGlmaWVkIGRhdGVcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdGN1cnJlbnQuc2l6ZSAhPT0gcHJldmlvdXMuc2l6ZSB8fFxuXHRcdFx0XHRjdXJyZW50Lmxhc3RNb2RpZmllZC5nZXRUaW1lKCkgIT09IHByZXZpb3VzLmxhc3RNb2RpZmllZC5nZXRUaW1lKClcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0Ly8gRnVsbCBjb21wYXJpc29uIC0gY2hlY2sgRVRhZyAoaGFzaCkgYXMgd2VsbFxuXHRcdC8vIElmIGlnbm9yZUV0YWdPblNpemUgaXMgdHJ1ZSwgc2tpcCBFVGFnIGNoZWNrIHdoZW4gc2l6ZXMgbWF0Y2hcblx0XHRpZiAodGhpcy5vcHRpb25zLmlnbm9yZUV0YWdPblNpemUgJiYgY3VycmVudC5zaXplID09PSBwcmV2aW91cy5zaXplKSB7XG5cdFx0XHRyZXR1cm4gY3VycmVudC5sYXN0TW9kaWZpZWQuZ2V0VGltZSgpICE9PSBwcmV2aW91cy5sYXN0TW9kaWZpZWQuZ2V0VGltZSgpO1xuXHRcdH1cblxuXHRcdHJldHVybiAoXG5cdFx0XHRjdXJyZW50LnNpemUgIT09IHByZXZpb3VzLnNpemUgfHxcblx0XHRcdGN1cnJlbnQuZXRhZyAhPT0gcHJldmlvdXMuZXRhZyB8fFxuXHRcdFx0Y3VycmVudC5sYXN0TW9kaWZpZWQuZ2V0VGltZSgpICE9PSBwcmV2aW91cy5sYXN0TW9kaWZpZWQuZ2V0VGltZSgpXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb21wYXJlcyBjdXJyZW50IHN0YXRlIHdpdGggcHJldmlvdXMgc3RhdGUgdG8gZGV0ZWN0IGNoYW5nZXNcblx0ICogQHJldHVybnMgQXJyYXkgb2YgY2hhbmdlIHJlc3VsdHNcblx0ICovXG5cdGRldGVjdENoYW5nZXMoKTogQ2hhbmdlUmVzdWx0W10ge1xuXHRcdGNvbnN0IGNoYW5nZXM6IENoYW5nZVJlc3VsdFtdID0gW107XG5cblx0XHQvLyBDaGVjayBmb3IgbmV3IGFuZCBtb2RpZmllZCBvYmplY3RzXG5cdFx0dGhpcy5jdXJyZW50U3RhdGUuZm9yRWFjaCgoY3VycmVudE9iamVjdCwga2V5KSA9PiB7XG5cdFx0XHRjb25zdCBwcmV2aW91c09iamVjdCA9IHRoaXMucHJldmlvdXNTdGF0ZS5nZXQoa2V5KTtcblxuXHRcdFx0aWYgKCFwcmV2aW91c09iamVjdCkge1xuXHRcdFx0XHQvLyBOZXcgb2JqZWN0XG5cdFx0XHRcdGNoYW5nZXMucHVzaCh7XG5cdFx0XHRcdFx0Y2hhbmdlVHlwZTogQ2hhbmdlVHlwZS5BZGRlZCxcblx0XHRcdFx0XHRvYmplY3Q6IGN1cnJlbnRPYmplY3QsXG5cdFx0XHRcdH0pO1xuXHRcdFx0fSBlbHNlIGlmICh0aGlzLmhhc09iamVjdENoYW5nZWQoY3VycmVudE9iamVjdCwgcHJldmlvdXNPYmplY3QpKSB7XG5cdFx0XHRcdC8vIE1vZGlmaWVkIG9iamVjdFxuXHRcdFx0XHRjaGFuZ2VzLnB1c2goe1xuXHRcdFx0XHRcdGNoYW5nZVR5cGU6IENoYW5nZVR5cGUuTW9kaWZpZWQsXG5cdFx0XHRcdFx0b2JqZWN0OiBjdXJyZW50T2JqZWN0LFxuXHRcdFx0XHRcdHByZXZpb3VzVmVyc2lvbjogcHJldmlvdXNPYmplY3QsXG5cdFx0XHRcdH0pO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gVW5jaGFuZ2VkIG9iamVjdFxuXHRcdFx0XHRjaGFuZ2VzLnB1c2goe1xuXHRcdFx0XHRcdGNoYW5nZVR5cGU6IENoYW5nZVR5cGUuVW5jaGFuZ2VkLFxuXHRcdFx0XHRcdG9iamVjdDogY3VycmVudE9iamVjdCxcblx0XHRcdFx0XHRwcmV2aW91c1ZlcnNpb246IHByZXZpb3VzT2JqZWN0LFxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIENoZWNrIGZvciBkZWxldGVkIG9iamVjdHMgaWYgZW5hYmxlZFxuXHRcdGlmICh0aGlzLm9wdGlvbnMudHJhY2tEZWxldGVkKSB7XG5cdFx0XHR0aGlzLnByZXZpb3VzU3RhdGUuZm9yRWFjaCgocHJldmlvdXNPYmplY3QsIGtleSkgPT4ge1xuXHRcdFx0XHRpZiAoIXRoaXMuY3VycmVudFN0YXRlLmhhcyhrZXkpKSB7XG5cdFx0XHRcdFx0Y2hhbmdlcy5wdXNoKHtcblx0XHRcdFx0XHRcdGNoYW5nZVR5cGU6IENoYW5nZVR5cGUuRGVsZXRlZCxcblx0XHRcdFx0XHRcdG9iamVjdDogcHJldmlvdXNPYmplY3QsXG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdHJldHVybiBjaGFuZ2VzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEZpbHRlciBjaGFuZ2VzIGJ5IHR5cGVcblx0ICogQHBhcmFtIGNoYW5nZXMgQXJyYXkgb2YgY2hhbmdlIHJlc3VsdHNcblx0ICogQHBhcmFtIHR5cGVzIFR5cGVzIG9mIGNoYW5nZXMgdG8gaW5jbHVkZVxuXHQgKiBAcmV0dXJucyBGaWx0ZXJlZCBhcnJheSBvZiBjaGFuZ2UgcmVzdWx0c1xuXHQgKi9cblx0c3RhdGljIGZpbHRlckNoYW5nZXNCeVR5cGUoXG5cdFx0Y2hhbmdlczogQ2hhbmdlUmVzdWx0W10sXG5cdFx0dHlwZXM6IENoYW5nZVR5cGVbXSxcblx0KTogQ2hhbmdlUmVzdWx0W10ge1xuXHRcdHJldHVybiBjaGFuZ2VzLmZpbHRlcigoY2hhbmdlKSA9PiB0eXBlcy5pbmNsdWRlcyhjaGFuZ2UuY2hhbmdlVHlwZSkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgc3RhdGUgZnJvbSB0aGUgY3VycmVudCBzdGF0ZVxuXHQgKi9cblx0Y29tbWl0Q2hhbmdlcygpOiB2b2lkIHtcblx0XHR0aGlzLnByZXZpb3VzU3RhdGUgPSBuZXcgTWFwKHRoaXMuY3VycmVudFN0YXRlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDbGVhcnMgdGhlIGN1cnJlbnQgc3RhdGVcblx0ICovXG5cdHJlc2V0Q3VycmVudFN0YXRlKCk6IHZvaWQge1xuXHRcdHRoaXMuY3VycmVudFN0YXRlID0gbmV3IE1hcCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENsZWFycyBhbGwgc3RhdGUgKHByZXZpb3VzIGFuZCBjdXJyZW50KVxuXHQgKi9cblx0cmVzZXRBbGxTdGF0ZSgpOiB2b2lkIHtcblx0XHR0aGlzLnByZXZpb3VzU3RhdGUgPSBuZXcgTWFwKCk7XG5cdFx0dGhpcy5jdXJyZW50U3RhdGUgPSBuZXcgTWFwKCk7XG5cdH1cbn1cblxuLyoqXG4gKiBBIHV0aWxpdHkgY2xhc3MgZm9yIGVmZmljaWVudCBwYXRoIGxvb2t1cHMgdXNpbmcgbWljcm9tYXRjaFxuICovXG5leHBvcnQgY2xhc3MgUGF0aE1hdGNoZXIge1xuXHQvLyBDYWNoZSBmb3IgY29tcGlsZWQgcGF0dGVybnMgdG8gYXZvaWQgcmUtY29tcGlsYXRpb25cblx0cHJpdmF0ZSByZWFkb25seSBwYXR0ZXJuQ2FjaGU6IE1hcDxzdHJpbmcsIFJlZ0V4cD4gPSBuZXcgTWFwKCk7XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgUGF0aE1hdGNoZXIgaW5zdGFuY2Vcblx0ICogQHBhcmFtIG9wdGlvbnMgRGVmYXVsdCBvcHRpb25zIHRvIHVzZSBmb3IgYWxsIG1hdGNoZXNcblx0ICovXG5cdGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogbWljcm9tYXRjaC5PcHRpb25zID0ge30pIHt9XG5cblx0LyoqXG5cdCAqIENoZWNrIGlmIGEgcGF0aCBtYXRjaGVzIGEgZ2xvYiBwYXR0ZXJuXG5cdCAqIEBwYXJhbSBwYXRoIFBhdGggdG8gY2hlY2tcblx0ICogQHBhcmFtIHBhdHRlcm4gR2xvYiBwYXR0ZXJuIHRvIG1hdGNoIGFnYWluc3Rcblx0ICogQHBhcmFtIG9wdGlvbnMgQWRkaXRpb25hbCBvcHRpb25zIHRvIG92ZXJyaWRlIGRlZmF1bHRzXG5cdCAqIEByZXR1cm5zIFRydWUgaWYgdGhlIHBhdGggbWF0Y2hlcyB0aGUgcGF0dGVyblxuXHQgKi9cblx0aXNNYXRjaChcblx0XHRwYXRoOiBzdHJpbmcsXG5cdFx0cGF0dGVybjogc3RyaW5nIHwgc3RyaW5nW10sXG5cdFx0b3B0aW9ucz86IG1pY3JvbWF0Y2guT3B0aW9ucyxcblx0KTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIG1pY3JvbWF0Y2guaXNNYXRjaChwYXRoLCBwYXR0ZXJuLCB7IC4uLnRoaXMub3B0aW9ucywgLi4ub3B0aW9ucyB9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBGaWx0ZXIgYW4gYXJyYXkgb2YgcGF0aHMgYmFzZWQgb24gb25lIG9yIG1vcmUgZ2xvYiBwYXR0ZXJuc1xuXHQgKiBAcGFyYW0gcGF0aHMgQXJyYXkgb2YgcGF0aHMgdG8gZmlsdGVyXG5cdCAqIEBwYXJhbSBwYXR0ZXJucyBPbmUgb3IgbW9yZSBnbG9iIHBhdHRlcm5zXG5cdCAqIEBwYXJhbSBvcHRpb25zIEFkZGl0aW9uYWwgb3B0aW9ucyB0byBvdmVycmlkZSBkZWZhdWx0c1xuXHQgKiBAcmV0dXJucyBGaWx0ZXJlZCBhcnJheSBvZiBwYXRocyB0aGF0IG1hdGNoIHRoZSBwYXR0ZXJuc1xuXHQgKi9cblx0bWF0Y2goXG5cdFx0cGF0aHM6IHN0cmluZ1tdLFxuXHRcdHBhdHRlcm5zOiBzdHJpbmcgfCBzdHJpbmdbXSxcblx0XHRvcHRpb25zPzogbWljcm9tYXRjaC5PcHRpb25zLFxuXHQpOiBzdHJpbmdbXSB7XG5cdFx0cmV0dXJuIG1pY3JvbWF0Y2gocGF0aHMsIHBhdHRlcm5zLCB7IC4uLnRoaXMub3B0aW9ucywgLi4ub3B0aW9ucyB9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGUgYW5kIGNhY2hlIGEgcmVndWxhciBleHByZXNzaW9uIGZvciBhIGdsb2IgcGF0dGVyblxuXHQgKiBAcGFyYW0gcGF0dGVybiBHbG9iIHBhdHRlcm4gdG8gY29udmVydCB0byByZWdleFxuXHQgKiBAcGFyYW0gb3B0aW9ucyBBZGRpdGlvbmFsIG9wdGlvbnMgdG8gb3ZlcnJpZGUgZGVmYXVsdHNcblx0ICogQHJldHVybnMgUmVndWxhciBleHByZXNzaW9uIGZvciB0aGUgcGF0dGVyblxuXHQgKi9cblx0Z2V0UmVnZXgocGF0dGVybjogc3RyaW5nLCBvcHRpb25zPzogbWljcm9tYXRjaC5PcHRpb25zKTogUmVnRXhwIHtcblx0XHRjb25zdCBjYWNoZUtleSA9IGAke3BhdHRlcm59OiR7SlNPTi5zdHJpbmdpZnkoeyAuLi50aGlzLm9wdGlvbnMsIC4uLm9wdGlvbnMgfSl9YDtcblxuXHRcdGlmICghdGhpcy5wYXR0ZXJuQ2FjaGUuaGFzKGNhY2hlS2V5KSkge1xuXHRcdFx0Y29uc3QgcmVnZXggPSBtaWNyb21hdGNoLm1ha2VSZShwYXR0ZXJuLCB7IC4uLnRoaXMub3B0aW9ucywgLi4ub3B0aW9ucyB9KTtcblx0XHRcdHRoaXMucGF0dGVybkNhY2hlLnNldChjYWNoZUtleSwgcmVnZXgpO1xuXHRcdH1cblxuXHRcdGNvbnN0IGNhY2hlZFJlZ2V4ID0gdGhpcy5wYXR0ZXJuQ2FjaGUuZ2V0KGNhY2hlS2V5KTtcblx0XHRpZiAoIWNhY2hlZFJlZ2V4KSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXG5cdFx0XHRcdGBGYWlsZWQgdG8gY3JlYXRlIG9yIHJldHJpZXZlIHJlZ2V4IGZvciBwYXR0ZXJuOiAke3BhdHRlcm59YCxcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGNhY2hlZFJlZ2V4O1xuXHR9XG5cblx0LyoqXG5cdCAqIEZpbHRlciBwYXRocyB1c2luZyBwcmUtY29tcGlsZWQgcmVnZXggcGF0dGVybnMgZm9yIG1heGltdW0gcGVyZm9ybWFuY2Vcblx0ICogQHBhcmFtIHBhdGhzIEFycmF5IG9mIHBhdGhzIHRvIGZpbHRlclxuXHQgKiBAcGFyYW0gcGF0dGVybnMgT25lIG9yIG1vcmUgZ2xvYiBwYXR0ZXJuc1xuXHQgKiBAcGFyYW0gb3B0aW9ucyBBZGRpdGlvbmFsIG9wdGlvbnMgdG8gb3ZlcnJpZGUgZGVmYXVsdHNcblx0ICogQHJldHVybnMgRmlsdGVyZWQgYXJyYXkgb2YgcGF0aHMgdGhhdCBtYXRjaCB0aGUgcGF0dGVybnNcblx0ICovXG5cdG1hdGNoRmFzdChcblx0XHRwYXRoczogc3RyaW5nW10sXG5cdFx0cGF0dGVybnM6IHN0cmluZyB8IHN0cmluZ1tdLFxuXHRcdG9wdGlvbnM/OiBtaWNyb21hdGNoLk9wdGlvbnMsXG5cdCk6IHN0cmluZ1tdIHtcblx0XHRjb25zdCBwYXR0ZXJuQXJyYXkgPSBBcnJheS5pc0FycmF5KHBhdHRlcm5zKSA/IHBhdHRlcm5zIDogW3BhdHRlcm5zXTtcblx0XHRjb25zdCByZWdleGVzID0gcGF0dGVybkFycmF5Lm1hcCgocGF0dGVybikgPT5cblx0XHRcdHRoaXMuZ2V0UmVnZXgocGF0dGVybiwgb3B0aW9ucyksXG5cdFx0KTtcblxuXHRcdHJldHVybiBwYXRocy5maWx0ZXIoKHBhdGgpID0+IHJlZ2V4ZXMuc29tZSgocmVnZXgpID0+IHJlZ2V4LnRlc3QocGF0aCkpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBGaWx0ZXIgcGF0aHMgdGhhdCBkb24ndCBtYXRjaCBhbnkgb2YgdGhlIHByb3ZpZGVkIHBhdHRlcm5zXG5cdCAqIEBwYXJhbSBwYXRocyBBcnJheSBvZiBwYXRocyB0byBmaWx0ZXJcblx0ICogQHBhcmFtIHBhdHRlcm5zIE9uZSBvciBtb3JlIGdsb2IgcGF0dGVybnMgdG8gZXhjbHVkZVxuXHQgKiBAcGFyYW0gb3B0aW9ucyBBZGRpdGlvbmFsIG9wdGlvbnMgdG8gb3ZlcnJpZGUgZGVmYXVsdHNcblx0ICogQHJldHVybnMgRmlsdGVyZWQgYXJyYXkgb2YgcGF0aHMgdGhhdCBkb24ndCBtYXRjaCBhbnkgcGF0dGVyblxuXHQgKi9cblx0bm90KFxuXHRcdHBhdGhzOiBzdHJpbmdbXSxcblx0XHRwYXR0ZXJuczogc3RyaW5nIHwgc3RyaW5nW10sXG5cdFx0b3B0aW9ucz86IG1pY3JvbWF0Y2guT3B0aW9ucyxcblx0KTogc3RyaW5nW10ge1xuXHRcdHJldHVybiBtaWNyb21hdGNoLm5vdChwYXRocywgcGF0dGVybnMsIHsgLi4udGhpcy5vcHRpb25zLCAuLi5vcHRpb25zIH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrIGlmIGFsbCBvZiB0aGUgcHJvdmlkZWQgcGF0dGVybnMgbWF0Y2ggdGhlIHBhdGhcblx0ICogQHBhcmFtIHBhdGggUGF0aCB0byBjaGVja1xuXHQgKiBAcGFyYW0gcGF0dGVybnMgT25lIG9yIG1vcmUgZ2xvYiBwYXR0ZXJuc1xuXHQgKiBAcGFyYW0gb3B0aW9ucyBBZGRpdGlvbmFsIG9wdGlvbnMgdG8gb3ZlcnJpZGUgZGVmYXVsdHNcblx0ICogQHJldHVybnMgVHJ1ZSBpZiBhbGwgcGF0dGVybnMgbWF0Y2ggdGhlIHBhdGhcblx0ICovXG5cdGFsbChcblx0XHRwYXRoOiBzdHJpbmcsXG5cdFx0cGF0dGVybnM6IHN0cmluZyB8IHN0cmluZ1tdLFxuXHRcdG9wdGlvbnM/OiBtaWNyb21hdGNoLk9wdGlvbnMsXG5cdCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiBtaWNyb21hdGNoLmFsbChwYXRoLCBwYXR0ZXJucywgeyAuLi50aGlzLm9wdGlvbnMsIC4uLm9wdGlvbnMgfSk7XG5cdH1cblxuXHQvKipcblx0ICogQ2FwdHVyZSB2YWx1ZXMgZnJvbSBhIHBhdGggYmFzZWQgb24gYSBnbG9iIHBhdHRlcm5cblx0ICogQHBhcmFtIHBhdHRlcm4gR2xvYiBwYXR0ZXJuIHdpdGggY2FwdHVyZSBncm91cHNcblx0ICogQHBhcmFtIHBhdGggUGF0aCB0byBleHRyYWN0IHZhbHVlcyBmcm9tXG5cdCAqIEBwYXJhbSBvcHRpb25zIEFkZGl0aW9uYWwgb3B0aW9ucyB0byBvdmVycmlkZSBkZWZhdWx0c1xuXHQgKiBAcmV0dXJucyBBcnJheSBvZiBjYXB0dXJlZCB2YWx1ZXMgb3IgbnVsbCBpZiBubyBtYXRjaFxuXHQgKi9cblx0Y2FwdHVyZShcblx0XHRwYXR0ZXJuOiBzdHJpbmcsXG5cdFx0cGF0aDogc3RyaW5nLFxuXHRcdG9wdGlvbnM/OiBtaWNyb21hdGNoLk9wdGlvbnMsXG5cdCk6IHN0cmluZ1tdIHwgbnVsbCB7XG5cdFx0Ly8gSW1wbGVtZW50YXRpb24gdGhhdCBtaW1pY3MgbWljcm9tYXRjaC5jYXB0dXJlXG5cdFx0Ly8gUGFyc2UgdGhlIHBhdHRlcm4gYW5kIGV4dHJhY3QgY2FwdHVyZSBncm91cHMgZnJvbSB0aGUgcGF0aFxuXHRcdGNvbnN0IHBsYWNlaG9sZGVyUmVnZXggPSAvOlteXFwvXFwuXSsvZztcblx0XHRjb25zdCBwbGFjZWhvbGRlcnMgPSBwYXR0ZXJuLm1hdGNoKHBsYWNlaG9sZGVyUmVnZXgpIHx8IFtdO1xuXG5cdFx0Ly8gUmVwbGFjZSBwbGFjZWhvbGRlcnMgd2l0aCBjYXB0dXJlIGdyb3Vwc1xuXHRcdGxldCByZWdleFBhdHRlcm4gPSBwYXR0ZXJuLnJlcGxhY2UoL1xcLy9nLCBcIlxcXFwvXCIpO1xuXHRcdHJlZ2V4UGF0dGVybiA9IHJlZ2V4UGF0dGVybi5yZXBsYWNlKC9cXC4vZywgXCJcXFxcLlwiKTtcblxuXHRcdGZvciAoY29uc3QgcGxhY2Vob2xkZXIgb2YgcGxhY2Vob2xkZXJzKSB7XG5cdFx0XHQvLyBSZXBsYWNlIDpuYW1lIHdpdGggY2FwdHVyaW5nIGdyb3VwXG5cdFx0XHRyZWdleFBhdHRlcm4gPSByZWdleFBhdHRlcm4ucmVwbGFjZShwbGFjZWhvbGRlciwgXCIoW14vXFxcXC5dKylcIik7XG5cdFx0fVxuXG5cdFx0Ly8gUmVwbGFjZSBhc3Rlcmlza3Mgd2l0aCBjYXB0dXJpbmcgZ3JvdXBzIGZvciBmaWxlbmFtZXNcblx0XHRyZWdleFBhdHRlcm4gPSByZWdleFBhdHRlcm4ucmVwbGFjZSgvXFwqL2csIFwiKFteL10rKVwiKTtcblxuXHRcdC8vIENyZWF0ZSBhIHJlZ2V4IHdpdGggdGhlIHBhdHRlcm5cblx0XHRjb25zdCByZWdleCA9IG5ldyBSZWdFeHAoYF4ke3JlZ2V4UGF0dGVybn0kYCwgb3B0aW9ucz8ubm9jYXNlID8gXCJpXCIgOiBcIlwiKTtcblx0XHRjb25zdCBtYXRjaCA9IHBhdGgubWF0Y2gocmVnZXgpO1xuXG5cdFx0aWYgKCFtYXRjaCkge1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXG5cdFx0Ly8gUmV0dXJuIHRoZSBjYXB0dXJlZCB2YWx1ZXMgKHNraXAgdGhlIGZpcnN0IGVsZW1lbnQgd2hpY2ggaXMgdGhlIGZ1bGwgbWF0Y2gpXG5cdFx0cmV0dXJuIG1hdGNoLnNsaWNlKDEpO1xuXHR9XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBpbnRlcmZhY2UgZm9yIFMzIGNsaWVudFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFMzQ2xpZW50Q29uZmlnIHtcblx0cmVnaW9uPzogc3RyaW5nO1xuXHRlbmRwb2ludD86IHN0cmluZztcblx0Y3JlZGVudGlhbHM/OiB7XG5cdFx0YWNjZXNzS2V5SWQ6IHN0cmluZztcblx0XHRzZWNyZXRBY2Nlc3NLZXk6IHN0cmluZztcblx0X