UNPKG

presta

Version:

Hyper minimal framework for the modern web.

82 lines (78 loc) 110 kB
#!/usr/bin/env node var Re=Object.create;var F=Object.defineProperty,Ce=Object.defineProperties,De=Object.getOwnPropertyDescriptor,Fe=Object.getOwnPropertyDescriptors,_e=Object.getOwnPropertyNames,J=Object.getOwnPropertySymbols,Oe=Object.getPrototypeOf,N=Object.prototype.hasOwnProperty,je=Object.prototype.propertyIsEnumerable;var W=(t,e,s)=>e in t?F(t,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[e]=s,y=(t,e)=>{for(var s in e||(e={}))N.call(e,s)&&W(t,s,e[s]);if(J)for(var s of J(e))je.call(e,s)&&W(t,s,e[s]);return t},b=(t,e)=>Ce(t,Fe(e)),ke=t=>F(t,"__esModule",{value:!0});var Le=(t,e,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of _e(e))!N.call(t,r)&&r!=="default"&&F(t,r,{get:()=>e[r],enumerable:!(s=De(e,r))||s.enumerable});return t},l=t=>Le(ke(F(t!=null?Re(Oe(t)):{},"default",t&&t.__esModule&&"default"in t?{get:()=>t.default,enumerable:!0}:{value:t,enumerable:!0})),t);var Pe=l(require("sade")),we=l(require("esbuild-register/dist/node"));var He="presta",$e="0.46.2",Me="Hyper minimal framework for the modern web.",Te="./index.js",Be="./index.d.ts",Ve={presta:"./bin.js"},ze=["utils","runtime","bin.js","index.js","html.js","serialize.js","bin.d.ts","index.d.ts","core.d.ts","html.d.ts","serialize.d.ts"],qe={build:`node scripts/build && tsc --emitDeclarationOnly && echo ' \u26A1\uFE0E Types generated'`,test:"c8 uvu -r esbuild-register lib/__tests__ -i ^_ && pnpm typecheck && echo '\u26A1\uFE0E Types checked'",cloc:"pnpm dlx cloc './lib/*.ts'",typecheck:"tsc --noEmit"},Ae={type:"git",url:"git+ssh://git@github.com/sure-thing/presta.git"},Ie="estrattonbailey",Qe="MIT",Ue={url:"https://github.com/sure-thing/presta/issues"},Je="https://github.com/sure-thing/presta#readme",Ne={chokidar:"^3.4.3","deep-extend":"^0.6.0",deepmerge:"^4.2.2",dotenv:"^10.0.0",esbuild:"^0.12.28","esbuild-register":"^2.6.0",filewatcher:"^3.0.1","fs-extra":"^9.0.1","get-port":"^5.1.1",kleur:"^4.1.4","lambda-types":"^1.0.0","mime-types":"^2.1.31","module-alias":"^2.2.2",ms:"^2.1.2",picomatch:"^2.3.0","query-string":"^6.14.1","raw-body":"^2.4.1",regexparam:"^1.3.0","route-sort":"^1.0.0",sade:"^1.7.3",sirv:"^1.0.7",smitter:"^1.1.1",statues:"^1.0.0-alpha1",statuses:"^2.0.1","tiny-glob":"^0.2.9","watch-dependency-graph":"^3.0.1",ws:"^8.4.0"},We={"@netlify/functions":"^0.7.2","@types/deep-extend":"^0.4.32","@types/fs-extra":"^9.0.12","@types/mime-types":"^2.1.0","@types/module-alias":"^2.0.1","@types/node":"^18.6.3","@types/picomatch":"^2.2.4","@types/sade":"^1.7.3","@types/statuses":"^2.0.0","@types/ws":"^8.2.2",c8:"^7.11.0",proxyquire:"^2.1.3","supertest-fetch":"^1.4.3",typescript:"^4.5.2",uvu:"^0.5.6"},G={name:He,version:$e,description:Me,main:Te,types:Be,bin:Ve,files:ze,scripts:qe,repository:Ae,author:Ie,license:Qe,bugs:Ue,homepage:Je,dependencies:Ne,devDependencies:We};var ce=l(require("http")),pe=l(require("regexparam")),ue=l(require("statuses")),de=l(require("ws")),d=l(require("path")),me=l(require("get-port")),fe=l(require("dotenv")),ge=l(require("module-alias")),p=l(require("fs-extra")),he=l(require("tiny-glob/sync")),M=l(require("mime-types")),ve=l(require("watch-dependency-graph")),T=l(require("chokidar")),ye=l(require("picomatch")),be=l(require("esbuild")),A=l(require("smitter")),B=l(require("kleur")),xe=l(require("route-sort"));function E(t){return delete require.cache[t],require(t)}function x(){let t=process.hrtime();return()=>{let[e,s]=process.hrtime(t),r=s/1e6;return e<1?(r>=1?r.toFixed(0):r.toFixed(2))+"ms":e+"."+r.toFixed(0)+"s"}}function Z(t){for(var e=5381,s=t.length;s;)e=e*33^t.charCodeAt(--s);return(e>>>0).toString(36)}var Y=l(require("url")),ee=l(require("raw-body")),te=l(require("mime-types"));var X=l(require("query-string"));function _(t){let e=(0,X.parse)(t,{arrayFormat:"comma"}),s={},r={};for(let o of Object.keys(e)){let i=e[o];Array.isArray(i)?r[o]=i:i&&(s[o]=i)}return{queryStringParameters:s,multiValueQueryStringParameters:r}}var Ge=/image|audio|video|application\/pdf|application\/zip|applicaton\/octet-stream/i;function O(t){return Boolean(t)&&Ge.test(t)}function P(t){var i,n;let e=t.rawQuery||t.path.split("?")[1],{queryStringParameters:s,multiValueQueryStringParameters:r}=_(e),o=(n=t.isBase64Encoded)!=null?n:O(((i=t==null?void 0:t.headers)==null?void 0:i["content-type"])||"");return{rawUrl:t.rawUrl||t.path,rawQuery:e,path:t.path,httpMethod:t.httpMethod||"GET",headers:t.headers||{},multiValueHeaders:t.multiValueHeaders||{},queryStringParameters:t.queryStringParameters||s,multiValueQueryStringParameters:t.multiValueQueryStringParameters||r,pathParameters:t.pathParameters||{},body:t.body||null,isBase64Encoded:o!=null?o:!1,requestContext:t.requestContext||{},resource:t.resource||""}}function K(t){let e={},s={};for(let r of Object.keys(t)){let o=r.toLowerCase(),i=t[r];!i||(Array.isArray(i)?s[o]=i:e[o]=i)}return{headers:e,multiValueHeaders:s}}async function re(t){let{url:e="",method:s}=t,{headers:r,multiValueHeaders:o}=K(t.headers),i=O(r["content-type"]||""),a=r["content-length"]?await(0,ee.default)(t,{limit:"1mb",encoding:r["content-type"]&&te.default.charset(r["content-type"])||!0}):void 0,c=(0,Y.parse)(e).query||"",{queryStringParameters:m,multiValueQueryStringParameters:u}=_(c);return P({rawUrl:e,path:e,httpMethod:s,headers:r,multiValueHeaders:o,rawQuery:c,queryStringParameters:m,multiValueQueryStringParameters:u,body:a?Buffer.from(a).toString(i?"base64":"utf8"):null,isBase64Encoded:i,pathParameters:void 0,requestContext:{},resource:""})}var V=l(require("statuses"));function se({statusCode:t}){return`<!-- built with presta https://npm.im/presta --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width,initial-scale=1" /> <title>${t} \u2014\xA0${V.default.message[t]}</title> <link rel="icon" type="image/png" href="https://presta.run/favicon.png"> <link rel="icon" type="image/svg" href="https://presta.run/favicon.svg"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;900&display=swap" rel="stylesheet"> <link rel='stylesheet' href='https://unpkg.com/svbstrate@5.1.0/svbstrate.css' /> <style> html,body { font-family: 'Inter', 'sans-serif'; color: #23283D; background-color: #DADEF0; } #favicon { fill: #23283D; } @media (prefers-color-scheme: dark) { html,body { color: #DADEF0; background-color: #23283D; } #favicon { fill: #DADEF0; } } </style> </head> <body class='w f aic jcc' style='height: 100vh'> <div class='p12 tac'> <h1>${t}</h1> <p class='mb1'>${V.default.message[t]}</p> <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> <g clip-path="url(#a)"> <path id="favicon" fill-rule="evenodd" clip-rule="evenodd" d="M10.4 7c-.3 0-.8.2-1 .5L1.1 22.1c-.2.3 0 .6.3.6l4 .3-2.1 2.6c-.2.3-.1.6.2.6l16.8 1.3c.4 0 .8-.2 1-.4L32 13.9c.2-.2.1-.5-.2-.5l-6.4-.5 2.2-4c.2-.3 0-.5-.3-.6L10.4 7ZM24 12.8l1.9-3.4-15.5-1.2-7.7 13.4 3.6.3 7.5-9.4c.3-.3.7-.5 1-.4l9.2.7ZM7.6 22l7.1-8.9 8.7.7-5.2 9L7.6 22Zm-1 1.1 11.6 1c.3 0 .8-.3 1-.6l5.5-9.6 5.5.5-9.7 12L5 25.2l1.7-2Z" fill="#23283D"/> </g> <defs> <clipPath id="a"> <path fill="#fff" d="M0 0h32v32H0z"/> </clipPath> </defs> </svg> </div> </body> </html> `}var ie=l(require("regexparam"));function j(t,e){let[s]=t.split("?"),r=(0,ie.default)(e),o=0,i={},n=r.pattern.exec(s)||[];for(;o<r.keys.length;)i[r.keys[o]]=n[++o];return i}function k(t,e){if(e.multiValueHeaders)for(let s of Object.keys(e.multiValueHeaders))t.setHeader(s,e.multiValueHeaders[s].map(r=>String(r)));if(e.headers)for(let s of Object.keys(e.headers))t.setHeader(s,String(e.headers[s]));t.statusCode=e.statusCode,t.end(e.body)}function z(t){for(let e of Object.keys(t))t[e.toLowerCase()]=t[e]||"";return t}var L;(function(r){r.Html="text/html; charset=utf-8",r.Json="application/json; charset=utf-8",r.Xml="application/xml; charset=utf-8"})(L||(L={}));function oe(t){return typeof t=="object"?JSON.stringify(t):t}function ne(t,e){let s=e.statusCode||200,r=e.headers?z(e.headers):{};return s>299&&s<399||(r["content-type"]=t),{isBase64Encoded:e.isBase64Encoded||!1,statusCode:s,headers:r,multiValueHeaders:e.multiValueHeaders?z(e.multiValueHeaders):{},body:oe(e.body||"")}}function H(t){return ne(L.Html,t)}function ae(t){return ne(L.Json,b(y({},t),{body:oe(t.body)}))}function $(t){return typeof t=="string"?H({body:t}):b(y({},t),{statusCode:t.statusCode||200})}function le(t){return async(e,s)=>{let r=P(e);return Object.keys(r.pathParameters||{}).length||(r.pathParameters=j(e.path,t.route)),$(await t.handler(r,s))}}var h;(function(r){r.Dev="dev",r.Build="build",r.Serve="serve"})(h||(h={}));var q=class extends Error{constructor(e,s=500){super(e);this.name="HttpError",this.statusCode=s}};var v="presta.config.js",I="presta.config.ts",Ze="./.presta",Xe="./.presta/functions",Ke="./.presta/static";function Ye({port:t}){return` <script> (function (global) { var socket = new WebSocket('ws://localhost:${t}'); socket.addEventListener('open', function (event) { console.log('[presta] connected on port ${t}') }); socket.addEventListener('message', function (event) { console.log(\`'[presta] received \${event.data}\`) if (event.data === 'refresh') { global.location.reload(); } }); socket.addEventListener('close', function () { console.log('[presta] disconnected') }); })(this); <\/script> `}function et(t,e){return t.replace(e,"").split(".").reverse().slice(1).reverse().join("-").split("/").filter(Boolean).join("-")}function tt(t){let e=Object.values(t);return(0,xe.default)(e.map(r=>r.route)).reduce((r,o)=>{let i=e.find(n=>n.route===o);return i?b(y({},r),{[i.src]:i}):r},{})}function R(t){if(t)return E(d.default.resolve(t));try{return E(d.default.resolve(v))}catch(e){if(p.default.existsSync(v))throw e;try{return E(d.default.resolve(I))}catch(s){if(p.default.existsSync(I))throw s}}return{}}function w(t,e={}){var o,i,n;let r={cwd:t.cwd||process.cwd(),files:t.files||[],assets:t.assets||"public",plugins:t.plugins||[],port:t.port||4e3,serve:(o=t.serve)!=null?o:!0,debug:!!t.debug,__unsafe_bundle_everything:(i=t.__unsafe_bundle_everything)!=null?i:!1,rawCliArgs:e};return((n=e._)==null?void 0:n.length)&&(r.files=e._),e.assets&&(r.assets=e.assets),e.port&&(r.port=e.port),e.serve&&(r.serve=e.serve==="true"),e.debug&&(r.debug=e.debug===!0),r.files&&(r.files=[].concat(r.files).map(a=>d.default.resolve(r.cwd,a))),r.assets&&(r.assets=d.default.resolve(r.cwd,r.assets)),r}function rt(t,e="html"){return d.default.extname(t)?t:e==="html"?`${t}/index.html`:`${t}.${e}`}function st(t){let e=((t==null?void 0:t.headers)||{})["content-type"];return M.default.extension(e)||"html"}function it(t,e){let s=Object.entries(e.functions).map(([r,{route:o}])=>({matcher:(0,pe.default)(o),file:r})).filter(({matcher:r})=>r.pattern.test(t.split("?")[0])).map(({file:r})=>r)[0];return{filepath:s,exports:s?E(s):void 0}}var C=class{constructor(e){this.cwd=process.cwd();this.mode=h.Dev;this.debug=!1;this.manifest={statics:{},functions:{}};this.files=[];this.events={internal:(0,A.smitter)(),external:(0,A.smitter)()};this.liveReloadScript="";this.cwd=e.cwd||process.cwd(),(0,fe.config)({path:d.default.join(this.cwd,".env")}),(0,ge.addAliases)({"@":this.cwd}),this.config=w(e),this.debug=!!this.config.debug,this.logger={debug:(s,r)=>this._log("debug",s,r),info:(s,r)=>this._log("info",s,r),warn:(s,r)=>this._log("warn",s,r),error:(s,r)=>this._log("error",s,r)},this.logger.debug(`initialized with config ${JSON.stringify(e,null," ")}`)}async build(){if(this.mode=h.Build,this._init(),!this.files.length){this.logger.warn("no files were found, nothing to build");return}let e=x(),s=require(d.default.join(this.cwd,"package.json"));await p.default.remove(this.staticOutputDir),await p.default.remove(this.functionsOutputDir),p.default.existsSync(this.config.assets)&&await p.default.copy(this.config.assets,this.staticOutputDir),await this.buildFiles(this.files),await(0,be.build)({entryPoints:Object.values(this.manifest.functions).map(({dest:r})=>r),outdir:this.functionsOutputDir,platform:"node",target:["node12"],minify:!0,allowOverwrite:!0,external:this.config.__unsafe_bundle_everything?[]:Object.keys(s.dependencies||{}),bundle:!0,define:{"process.env.PRESTA_SERVERLESS_RUNTIME":"true"}}),this.logger.info("presta build complete",{duration:e()}),this.events.external.emit("buildComplete")}async dev(){this.mode=h.Dev,this._init(),this.config.serve&&(await this._getPort(),this.liveReloadScript=this.config.serve?Ye({port:this.port}):"");let e=!1,s=await this._initDev(),r=async()=>{if(!e){e=!0;try{await s.cleanup(),this.debug||console.clear(),this.logger.info("\u267A restarting"),this.config=w(R(this.config.rawCliArgs.config),this.config.rawCliArgs),this._init(),s=await this._initDev(),this.events.internal.emit("devServerRestarted")}catch(i){this.logger.error(i)}e=!1}},o=T.default.watch([this.config.rawCliArgs.config&&d.default.resolve(this.config.rawCliArgs.config),v,I].filter(Boolean),{ignoreInitial:!0}).on("all",r);return this.events.internal.on("requestRestartDevServer",r),{async cleanup(){await s.cleanup(),await o.close()}}}serve(){this.mode=h.Serve,this._init(),this._serve()}restartDevServer(){if(this.mode!==h.Dev)throw new Error(`Requested a dev server restart in ${this.mode} mode`);this.events.internal.emit("requestRestartDevServer")}async buildFile(e){try{let{route:s,getStaticPaths:r,handler:o}=require(e);if(r){let i=await r(),n=[],a=this.manifest.statics[e]||[];if(!i.length){for(let c of a)await p.default.remove(c);this.manifest.statics[e]=[],this.logger.debug(`no built files detected, removing all previous artifacts for ${e}`);return}for(let c of i){let m=x(),u=P({path:c,pathParameters:s?j(c,s):{}}),f=$(await o(u,{})),S=((f==null?void 0:f.headers)||{})["content-type"],Se=M.default.extension(S)||"html",Ee=rt(c,Se),Q=f.body,U=d.default.join(this.staticOutputDir,Ee);Q?(p.default.outputFileSync(U,Q,"utf-8"),n.push(U),this.logger.info(`\u25CF ${c}`,{duration:m()})):this.logger.warn(`Nothing to build for ${c}, response.body is undefined`)}for(let c of a)n.includes(c)||(await p.default.remove(c),this.logger.debug(`detected removed file, cleaning up ${e}`));this.manifest.statics[e]=n}if(s){let i=x(),n=et(e,this.cwd),a="";this.mode===h.Build&&(a=d.default.join(this.functionsOutputDir,this.mode===h.Build?n+"-"+Z(p.default.readFileSync(e,"utf8"))+".js":n+".js"),p.default.outputFileSync(a,`import { wrapHandler } from 'presta/runtime/wrapHandler'; import * as file from '${e}'; const mod = Object.assign({ config: {} }, file) export const route = mod.route export const config = mod.config export const handler = wrapHandler(mod)`)),this.manifest.functions=tt(b(y({},this.manifest.functions),{[e]:{route:s,src:e,dest:a}})),this.logger.info(`\u03BB ${s}`,{duration:i()})}this._commitManifestToFile()}catch(s){this.logger.error(s)}}async buildFiles(e){await Promise.all(e.map(s=>this.buildFile(s)))}_init(){var e;((e=this.plugins)==null?void 0:e.length)&&this.plugins.forEach(s=>{s.cleanup&&(this._log("debug",`cleaning up ${s.name} plugin`),s.cleanup())}),this.prestaOutputDir=d.default.join(this.cwd,Ze),this.staticOutputDir=d.default.join(this.cwd,Ke),this.functionsOutputDir=d.default.join(this.cwd,Xe),this.manifestFilepath=d.default.join(this.prestaOutputDir,"manifest.json"),this.files=[].concat(this.config.files).map(s=>(0,he.default)(s)).flat().map(s=>d.default.resolve(this.cwd,s)),this.plugins=this.config.plugins.map(s=>{let r=s({mode:this.mode,cwd:this.cwd,events:{on:this.events.external.on},logger:this.logger,getManifest:()=>this.manifest,getOutputDir:()=>this.prestaOutputDir,getStaticOutputDir:()=>this.staticOutputDir,getFunctionsOutputDir:()=>this.functionsOutputDir,restartDevServer:this.restartDevServer.bind(this)});return this.logger.debug(`${r.name} initialized`),r}),this.logger.debug(`presta start ${JSON.stringify(this,null," ")}`)}async _serve(){this.mode===h.Serve&&await this._getPort(),this.logger.info(`\u26A1\uFE0Ehttp://localhost:${this.port}`);let e=ce.default.createServer((n,a)=>this._httpServerHandler(n,a)).listen(this.port),s=new de.WebSocketServer({server:e}),r=[];e.on("connection",n=>{r.push(n),n.on("close",()=>r.splice(r.indexOf(n),1))});let o=()=>{this.logger.debug("refreshing browser"),s.clients.forEach(n=>n.send("refresh"))},i=[this.events.internal.on("devServerRestarted",()=>o()),this.events.internal.on("devFileAdded",()=>o()),this.events.internal.on("devFileRemoved",()=>o()),this.events.internal.on("devFileChanged",()=>o())];return{cleanup(){return new Promise(n=>{i.map(a=>a()),e.close(()=>n(1)),r.forEach(a=>a.destroy())})}}}_log(e,s,{duration:r}={}){if(!this.debug&&e==="debug")return;let i=B.default[{debug:"magenta",info:"reset",warn:"yellow",error:"red"}[e]];console[e]([B.default.gray(this.mode),i(String(s)),r&&`${B.default.gray(r)}`].filter(Boolean).join(" ")),e==="error"&&s instanceof Error&&console.error(s)}async _initDev(){let e=(0,ve.create)({alias:{"@":this.cwd}}),s=T.default.watch(this.cwd,{ignoreInitial:!0,ignored:[this.staticOutputDir,this.functionsOutputDir,this.config.assets]}),r,o;return this.config.serve&&(r=await this._serve(),o=T.default.watch(this.config.assets,{ignoreInitial:!0}).on("all",(i,n)=>{this.logger.debug(`static asset ${n} changed`),this.events.internal.emit("devFileChanged")})),e.onChange(async i=>{this.logger.debug(`file ${i[0]} changed`),await this.buildFiles(i),this.events.internal.emit("devFileChanged")}),e.onRemove(async([i])=>{this.logger.debug(`file ${i} was removed`),this.files.splice(this.files.indexOf(i),1);let n=this.manifest.statics[i]||[],a=this.manifest.functions[i],c=n.map(m=>p.default.remove(m));a&&c.push(p.default.remove(a.dest)),await Promise.all(c),delete this.manifest.statics[i],delete this.manifest.functions[i],this.events.internal.emit("devFileRemoved")}),e.onError(i=>{this.logger.error(typeof i=="string"?new Error(i):i)}),await e.add(this.files),s.on("add",async i=>{!p.default.existsSync(i)||p.default.lstatSync(i).isDirectory()||!(0,ye.default)(this.config.files)(i)||this.files.includes(i)||(this.logger.debug(`${i} added`),this.files.push(i),await e.add(i),await this.buildFile(i),this.events.internal.emit("devFileAdded"))}),await p.default.remove(this.staticOutputDir),await p.default.remove(this.functionsOutputDir),await this.buildFiles(this.files),{async cleanup(){await Promise.all([e.close(),s.close(),o&&o.close(),r&&r.cleanup()].filter(Boolean))}}}async _getPort(){let e=this.config.port||4e3;this.port=await(0,me.default)({port:e}),this.port!==e&&this.logger.debug(`desired port ${e} not available, assigning ${this.port}`)}async _commitManifestToFile(){return p.default.outputFileSync(this.manifestFilepath,JSON.stringify(this.manifest,null," "))}async _httpServerHandler(e,s){let r=x();this.logger.debug(`handling ${e.url}`),this._httpTryServeFile(e,s,async o=>{o?this.logger.info(`\u26A1\uFE0E${e.url} ${s.statusCode}`,{duration:r()}):await this._httpTryServeLambda(e,s)})}async _httpTryServeFile(e,s,r){let{pathname:o}=new URL(e.url,"https://presta.dev"),i=M.default.lookup(o)||"text/html",n=i==="text/html",a=d.default.join(this.config.assets,o),c=d.default.join(this.staticOutputDir,o),m=!1,u=[a,c,d.default.join(a,"index.html"),d.default.join(c,"index.html")];for(let f of u)if(this.logger.debug(`attempting to serve ${f} as ${i}`),p.default.existsSync(f)){if(p.default.statSync(f).isDirectory())continue;if(s.writeHead(200,{"content-type":i}),n){let S=p.default.readFileSync(f,"utf8");S+=this.liveReloadScript,s.end(S)}else p.default.createReadStream(f).pipe(s);m=!0;break}r(m)}async _httpTryServeLambda(e,s){var a;let r=x(),o=await re(e),i=o.headers.Accept||o.headers.accept,n=i&&i.includes("json");this.logger.debug(`handling function request ${o.path}`);try{let{filepath:c,exports:m}=it(o.path,this.manifest);if(!m){this.logger.error(`\u26A1\uFE0E${o.path} ${404}`,{duration:r()}),k(s,{statusCode:404});return}if(!m.handler)throw new q(`file ${c} does not export a \`handler\``,404);let u=await le(m)(o,{}),f=u.statusCode>299&&u.statusCode<399;(f?void 0:st(u))==="html"&&(u.body=(u.body||"").split("</body>")[0]+this.liveReloadScript),k(s,u),this.logger.info(`\u26A1\uFE0E${f&&((a=u==null?void 0:u.headers)==null?void 0:a.Location)||o.path} ${u.statusCode}`,{duration:r()})}catch(c){let m=c,{statusCode:u=500}=m;u>499&&this.logger.error(m);let f=n?ae({statusCode:u,body:{detail:ue.default.message[u]}}):H({statusCode:u,body:se({statusCode:u})});this.logger.error(m),this.logger.error(`\u26A1\uFE0E${o.path} ${f.statusCode}`,{duration:r()}),k(s,f)}}};(0,we.register)();var D=(0,Pe.default)("presta");D.version(G.version).option("--config, -c",`Path to a config file. (default ${v})`).option("--staticOutputDir","Specify output directory for built static files. (default ./.presta/static/)").option("--functionsOutputDir","Specify output directory for built serverless functions. (default ./.presta/functions/)").option("--assets, -a","Specify static asset directory. (default ./public)").option("--debug, -d","Enable debug mode (prints more logs)").example("dev index.jsx -o dist").example("dev 'pages/*.tsx' -o static").example("'pages/*.tsx'").example("-c site.json").example("serve -p 8080");D.command("build","Build project to output directory.",{default:!0}).example("").example("files/**/*.js").example(`-c ${v}`).action(async t=>{process.env.PRESTA_ENV="Production",process.env.PRESTA_DEBUG=t.debug?"debug":"",console.clear();let e=w(R(t.config),t);await new C(e).build()});D.command("dev","Start Presta dev server and watch files",{alias:"watch"}).option("--port, -p","Port to run the local server. (default 4000)").option("--serve, -s","Run local dev server. (default true)").describe("Watch project and build to output directory.").example("dev").example("dev ./files/**/*.js").example("dev ./files/**/*.js -o ./out").example(`dev -c ${v}`).action(async t=>{process.env.PRESTA_ENV="Development",process.env.PRESTA_DEBUG=t.debug?"debug":"",console.clear();let e=w(R(t.config),t);new C(e).dev()});D.command("serve").option("--port, -p","Port to run the local server. (default 4000)").describe("Serve built files, lambdas, and static assets.").example("serve").example("serve -o ./out -p 8080").example(`serve -c ${v}`).action(async t=>{process.env.PRESTA_ENV="Development",process.env.PRESTA_DEBUG=t.debug?"debug":"",console.clear();let e=w(R(t.config),t);new C(e).serve()});D.parse(process.argv); //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibGliL2Jpbi50cyIsICJsaWIvY29yZS50cyIsICJsaWIvdXRpbHMvcmVxdWlyZUZyZXNoLnRzIiwgImxpYi91dGlscy90aW1lci50cyIsICJsaWIvdXRpbHMvaGFzaENvbnRlbnQudHMiLCAibGliL3V0aWxzL3JlcXVlc3RUb0V2ZW50LnRzIiwgImxpYi9ydW50aW1lL3BhcnNlUXVlcnlTdHJpbmdQYXJhbWV0ZXJzLnRzIiwgImxpYi9ydW50aW1lL2lzQmFzZTY0RW5jb2RlZENvbnRlbnRUeXBlLnRzIiwgImxpYi9ydW50aW1lL25vcm1hbGl6ZUV2ZW50LnRzIiwgImxpYi9ydW50aW1lL25vcm1hbGl6ZVJlcXVlc3RIZWFkZXJzLnRzIiwgImxpYi91dGlscy9jcmVhdGVEZWZhdWx0SHRtbFJlc3BvbnNlLnRzIiwgImxpYi9ydW50aW1lL3BhcnNlUGF0aFBhcmFtZXRlcnMudHMiLCAibGliL3J1bnRpbWUvc2VuZFNlcnZlcmxlc3NSZXNwb25zZS50cyIsICJsaWIvcnVudGltZS9ub3JtYWxpemVSZXNwb25zZUhlYWRlcnMudHMiLCAibGliL3NlcmlhbGl6ZS50cyIsICJsaWIvcnVudGltZS9ub3JtYWxpemVSZXNwb25zZS50cyIsICJsaWIvcnVudGltZS93cmFwSGFuZGxlci50cyIsICJsaWIvaW5kZXgudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIiMhL3Vzci9iaW4vZW52IG5vZGVcblxuaW1wb3J0IHNhZGUgZnJvbSAnc2FkZSdcbmltcG9ydCB7IHJlZ2lzdGVyIGFzIGVzYnVpbGQgfSBmcm9tICdlc2J1aWxkLXJlZ2lzdGVyL2Rpc3Qvbm9kZSdcblxuLy8gQHRzLWlnbm9yZVxuaW1wb3J0IHBrZyBmcm9tICcuLi9wYWNrYWdlLmpzb24nXG5pbXBvcnQgeyBkZWZhdWx0SlNDb25maWdGaWxlcGF0aCwgZmluZEFuZFBhcnNlQ29uZmlnRmlsZSwgbWVyZ2VDb25maWcsIFByZXN0YUNsaUFyZ3MsIFByZXN0YSB9IGZyb20gJy4vY29yZSdcblxuZXNidWlsZCgpXG5cbmNvbnN0IHByb2dyYW0gPSBzYWRlKCdwcmVzdGEnKVxuXG5wcm9ncmFtXG4gIC52ZXJzaW9uKHBrZy52ZXJzaW9uKVxuICAvLyBkbyBub3QgcHJvdmlkZSBkZWZhdWx0IGNvbmZpZyBoZXJlXG4gIC5vcHRpb24oJy0tY29uZmlnLCAtYycsIGBQYXRoIHRvIGEgY29uZmlnIGZpbGUuICAoZGVmYXVsdCAke2RlZmF1bHRKU0NvbmZpZ0ZpbGVwYXRofSlgKVxuICAub3B0aW9uKCctLXN0YXRpY091dHB1dERpcicsIGBTcGVjaWZ5IG91dHB1dCBkaXJlY3RvcnkgZm9yIGJ1aWx0IHN0YXRpYyBmaWxlcy4gIChkZWZhdWx0IC4vLnByZXN0YS9zdGF0aWMvKWApXG4gIC5vcHRpb24oXG4gICAgJy0tZnVuY3Rpb25zT3V0cHV0RGlyJyxcbiAgICBgU3BlY2lmeSBvdXRwdXQgZGlyZWN0b3J5IGZvciBidWlsdCBzZXJ2ZXJsZXNzIGZ1bmN0aW9ucy4gIChkZWZhdWx0IC4vLnByZXN0YS9mdW5jdGlvbnMvKWBcbiAgKVxuICAub3B0aW9uKCctLWFzc2V0cywgLWEnLCBgU3BlY2lmeSBzdGF0aWMgYXNzZXQgZGlyZWN0b3J5LiAgKGRlZmF1bHQgLi9wdWJsaWMpYClcbiAgLm9wdGlvbignLS1kZWJ1ZywgLWQnLCBgRW5hYmxlIGRlYnVnIG1vZGUgKHByaW50cyBtb3JlIGxvZ3MpYClcbiAgLmV4YW1wbGUoYGRldiBpbmRleC5qc3ggLW8gZGlzdGApXG4gIC5leGFtcGxlKGBkZXYgJ3BhZ2VzLyoudHN4JyAtbyBzdGF0aWNgKVxuICAuZXhhbXBsZShgJ3BhZ2VzLyoudHN4J2ApXG4gIC5leGFtcGxlKGAtYyBzaXRlLmpzb25gKVxuICAuZXhhbXBsZShgc2VydmUgLXAgODA4MGApXG5cbnByb2dyYW1cbiAgLmNvbW1hbmQoJ2J1aWxkJywgJ0J1aWxkIHByb2plY3QgdG8gb3V0cHV0IGRpcmVjdG9yeS4nLCB7IGRlZmF1bHQ6IHRydWUgfSlcbiAgLmV4YW1wbGUoYGApXG4gIC5leGFtcGxlKGBmaWxlcy8qKi8qLmpzYClcbiAgLmV4YW1wbGUoYC1jICR7ZGVmYXVsdEpTQ29uZmlnRmlsZXBhdGh9YClcbiAgLmFjdGlvbihhc3luYyAoY2xpQXJnczogUHJlc3RhQ2xpQXJncykgPT4ge1xuICAgIHByb2Nlc3MuZW52LlBSRVNUQV9FTlYgPSAnUHJvZHVjdGlvbicgLy8gVE9ET1xuICAgIHByb2Nlc3MuZW52LlBSRVNUQV9ERUJVRyA9IGNsaUFyZ3MuZGVidWcgPyAnZGVidWcnIDogJydcbiAgICBjb25zb2xlLmNsZWFyKClcbiAgICBjb25zdCBjb25maWcgPSBtZXJnZUNvbmZpZyhmaW5kQW5kUGFyc2VDb25maWdGaWxlKGNsaUFyZ3MuY29uZmlnKSwgY2xpQXJncylcbiAgICBhd2FpdCBuZXcgUHJlc3RhKGNvbmZpZykuYnVpbGQoKVxuICB9KVxuXG5wcm9ncmFtXG4gIC5jb21tYW5kKCdkZXYnLCAnU3RhcnQgUHJlc3RhIGRldiBzZXJ2ZXIgYW5kIHdhdGNoIGZpbGVzJywgeyBhbGlhczogJ3dhdGNoJyB9KVxuICAub3B0aW9uKCctLXBvcnQsIC1wJywgYFBvcnQgdG8gcnVuIHRoZSBsb2NhbCBzZXJ2ZXIuICAoZGVmYXVsdCA0MDAwKWApXG4gIC5vcHRpb24oJy0tc2VydmUsIC1zJywgYFJ1biBsb2NhbCBkZXYgc2VydmVyLiAgKGRlZmF1bHQgdHJ1ZSlgKVxuICAuZGVzY3JpYmUoJ1dhdGNoIHByb2plY3QgYW5kIGJ1aWxkIHRvIG91dHB1dCBkaXJlY3RvcnkuJylcbiAgLmV4YW1wbGUoYGRldmApXG4gIC5leGFtcGxlKGBkZXYgLi9maWxlcy8qKi8qLmpzYClcbiAgLmV4YW1wbGUoYGRldiAuL2ZpbGVzLyoqLyouanMgLW8gLi9vdXRgKVxuICAuZXhhbXBsZShgZGV2IC1jICR7ZGVmYXVsdEpTQ29uZmlnRmlsZXBhdGh9YClcbiAgLmFjdGlvbihhc3luYyAoY2xpQXJnczogUHJlc3RhQ2xpQXJncykgPT4ge1xuICAgIHByb2Nlc3MuZW52LlBSRVNUQV9FTlYgPSAnRGV2ZWxvcG1lbnQnIC8vIFRPRE9cbiAgICBwcm9jZXNzLmVudi5QUkVTVEFfREVCVUcgPSBjbGlBcmdzLmRlYnVnID8gJ2RlYnVnJyA6ICcnXG4gICAgY29uc29sZS5jbGVhcigpXG4gICAgY29uc3QgY29uZmlnID0gbWVyZ2VDb25maWcoZmluZEFuZFBhcnNlQ29uZmlnRmlsZShjbGlBcmdzLmNvbmZpZyksIGNsaUFyZ3MpXG4gICAgbmV3IFByZXN0YShjb25maWcpLmRldigpXG4gIH0pXG5cbnByb2dyYW1cbiAgLmNvbW1hbmQoJ3NlcnZlJylcbiAgLm9wdGlvbignLS1wb3J0LCAtcCcsIGBQb3J0IHRvIHJ1biB0aGUgbG9jYWwgc2VydmVyLiAgKGRlZmF1bHQgNDAwMClgKVxuICAuZGVzY3JpYmUoJ1NlcnZlIGJ1aWx0IGZpbGVzLCBsYW1iZGFzLCBhbmQgc3RhdGljIGFzc2V0cy4nKVxuICAuZXhhbXBsZShgc2VydmVgKVxuICAuZXhhbXBsZShgc2VydmUgLW8gLi9vdXQgLXAgODA4MGApXG4gIC5leGFtcGxlKGBzZXJ2ZSAtYyAke2RlZmF1bHRKU0NvbmZpZ0ZpbGVwYXRofWApXG4gIC5hY3Rpb24oYXN5bmMgKGNsaUFyZ3M6IFByZXN0YUNsaUFyZ3MpID0+IHtcbiAgICBwcm9jZXNzLmVudi5QUkVTVEFfRU5WID0gJ0RldmVsb3BtZW50JyAvLyBUT0RPXG4gICAgcHJvY2Vzcy5lbnYuUFJFU1RBX0RFQlVHID0gY2xpQXJncy5kZWJ1ZyA/ICdkZWJ1ZycgOiAnJ1xuICAgIGNvbnNvbGUuY2xlYXIoKVxuICAgIGNvbnN0IGNvbmZpZyA9IG1lcmdlQ29uZmlnKGZpbmRBbmRQYXJzZUNvbmZpZ0ZpbGUoY2xpQXJncy5jb25maWcpLCBjbGlBcmdzKVxuICAgIG5ldyBQcmVzdGEoY29uZmlnKS5zZXJ2ZSgpXG4gIH0pXG5cbnByb2dyYW0ucGFyc2UocHJvY2Vzcy5hcmd2KVxuIiwgImltcG9ydCB7IFNvY2tldCB9IGZyb20gJ25ldCdcbmltcG9ydCBodHRwIGZyb20gJ2h0dHAnXG5pbXBvcnQgdG9SZWdFeHAgZnJvbSAncmVnZXhwYXJhbSdcbmltcG9ydCBzdGF0dXMgZnJvbSAnc3RhdHVzZXMnXG5pbXBvcnQgeyBXZWJTb2NrZXRTZXJ2ZXIgfSBmcm9tICd3cydcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnXG5pbXBvcnQgZ2V0UG9ydCBmcm9tICdnZXQtcG9ydCdcbmltcG9ydCB7IGNvbmZpZyBhcyBkb3RlbnYgfSBmcm9tICdkb3RlbnYnXG5pbXBvcnQgeyBhZGRBbGlhc2VzIH0gZnJvbSAnbW9kdWxlLWFsaWFzJ1xuaW1wb3J0IGZzIGZyb20gJ2ZzLWV4dHJhJ1xuaW1wb3J0IGdsb2JTeW5jIGZyb20gJ3RpbnktZ2xvYi9zeW5jJ1xuaW1wb3J0IG1pbWUgZnJvbSAnbWltZS10eXBlcydcbmltcG9ydCB7IGNyZWF0ZSB9IGZyb20gJ3dhdGNoLWRlcGVuZGVuY3ktZ3JhcGgnXG5pbXBvcnQgY2hva2lkYXIgZnJvbSAnY2hva2lkYXInXG5pbXBvcnQgbWF0Y2ggZnJvbSAncGljb21hdGNoJ1xuaW1wb3J0IHsgYnVpbGQgYXMgZXNidWlsZCB9IGZyb20gJ2VzYnVpbGQnXG5pbXBvcnQgeyBzbWl0dGVyLCBTbWl0dGVyIH0gZnJvbSAnc21pdHRlcidcbmltcG9ydCBrbGV1ciwgeyBLbGV1ciB9IGZyb20gJ2tsZXVyJ1xuaW1wb3J0IHJzb3J0IGZyb20gJ3JvdXRlLXNvcnQnXG5pbXBvcnQge1xuICBQYXJhbXMsXG4gIE11bHRpVmFsdWVQYXJhbXMsXG4gIEV2ZW50IGFzIExhbWJkYUV2ZW50LFxuICBDb250ZXh0IGFzIExhbWJkYUNvbnRleHQsXG4gIFJlc3BvbnNlIGFzIExhbWJkYVJlc3BvbnNlLFxufSBmcm9tICdsYW1iZGEtdHlwZXMnXG5cbmltcG9ydCB7IHJlcXVpcmVGcmVzaCB9IGZyb20gJy4vdXRpbHMvcmVxdWlyZUZyZXNoJ1xuaW1wb3J0IHsgdGltZXIgfSBmcm9tICcuL3V0aWxzL3RpbWVyJ1xuaW1wb3J0IHsgaGFzaENvbnRlbnQgfSBmcm9tICcuL3V0aWxzL2hhc2hDb250ZW50J1xuaW1wb3J0IHsgcmVxdWVzdFRvRXZlbnQgfSBmcm9tICcuL3V0aWxzL3JlcXVlc3RUb0V2ZW50J1xuaW1wb3J0IHsgY3JlYXRlRGVmYXVsdEh0bWxSZXNwb25zZSB9IGZyb20gJy4vdXRpbHMvY3JlYXRlRGVmYXVsdEh0bWxSZXNwb25zZSdcblxuaW1wb3J0IHsgcGFyc2VQYXRoUGFyYW1ldGVycyB9IGZyb20gJy4vcnVudGltZS9wYXJzZVBhdGhQYXJhbWV0ZXJzJ1xuaW1wb3J0IHsgc2VuZFNlcnZlcmxlc3NSZXNwb25zZSB9IGZyb20gJy4vcnVudGltZS9zZW5kU2VydmVybGVzc1Jlc3BvbnNlJ1xuaW1wb3J0IHsgbm9ybWFsaXplRXZlbnQgfSBmcm9tICcuL3J1bnRpbWUvbm9ybWFsaXplRXZlbnQnXG5pbXBvcnQgeyBub3JtYWxpemVSZXNwb25zZSB9IGZyb20gJy4vcnVudGltZS9ub3JtYWxpemVSZXNwb25zZSdcbmltcG9ydCB7IHdyYXBIYW5kbGVyIH0gZnJvbSAnLi9ydW50aW1lL3dyYXBIYW5kbGVyJ1xuXG5pbXBvcnQgeyBIdHRwRXJyb3IsIE1vZGUgfSBmcm9tICcuLydcbmltcG9ydCAqIGFzIHNlcmlhbGl6ZSBmcm9tICcuL3NlcmlhbGl6ZSdcblxuLy8gVE9ETyBhZGQgb3B0aW9uIG5vdCB0byBidWlsZCBldmVyeXRoaW5nIG9uIHN0YXJ0dXBcbi8vIFRPRE8gb3V0cHV0dGluZyBkaXJlY3RseSB0byBwbGF0Zm9ybSBkaXJzIG1lYW5zIG5vIHJlYWRpbmcgb2YgZXhwb3J0ZWQgeyBjb25maWcgfSBieSBwbHVnaW5zLCBtYXliZSBJIG5lZWQgYSBsaWZlY3ljbGUgaG9vayB0byBwcm9jZXNzIGluIHNpdHVcblxuZXhwb3J0IHR5cGUgUHJlc3RhQ29uZmlnID0ge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5IChkZWZhdWx0IGBwcm9jZXNzLmN3ZCgpYClcbiAgICovXG4gIGN3ZDogc3RyaW5nXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gZmlsZSBnbG9icyB0byBpbmNsdWRlIGluIGJ1aWxkIHByb2Nlc3NcbiAgICovXG4gIGZpbGVzOiBzdHJpbmdbXVxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIHBhdGggdG8gc3RhdGljIGFzc2V0IGRpcmVjdG9yeSAoZGVmYXVsdCBgLi9wdWJsaWNgKVxuICAgKi9cbiAgYXNzZXRzOiBzdHJpbmdcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBhcnJheSBvZiBQcmVzdGEgcGx1Z2luc1xuICAgKi9cbiAgcGx1Z2luczogUGx1Z2luW11cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiB1c2VyIHJlcXVlc3RlZCBwb3J0IChkZWZhdWx0IGA0MDAwYClcbiAgICovXG4gIHBvcnQ6IG51bWJlclxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIHdoZXRoZXIgb3Igbm90IHRvIHJ1biB0aGUgbG9jYWwgZGV2IEhUVFAgc2VydmVyIChkZWZhdWx0IGBmYWxzZWApXG4gICAqL1xuICBzZXJ2ZTogYm9vbGVhblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIG9wdGlvbiB0byBvdXRwdXQgZGVidWcgbG9ncyBkdXJpbmcgZGV2IChkZWZhdWx0IGBmYWxzZWApXG4gICAqL1xuICBkZWJ1Zz86IGJvb2xlYW5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiB0aGUgcmF3IGFyZ3MgcGFzc2VkIGluIHZpYSB0aGUgUHJlc3RhIENMSVxuICAgKi9cbiAgcmF3Q2xpQXJnczogUHJlc3RhQ2xpQXJnc1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIGluY2x1ZXMgYWxsIGRlcGVuZGVuY2llcyBpbiB0aGUgZmluYWwgYnVuZGxlIGluc3RlYWQgb2ZcbiAgICogZXh0ZXJuYWxpemluZyB0aGVtXG4gICAqL1xuICBfX3Vuc2FmZV9idW5kbGVfZXZlcnl0aGluZzogYm9vbGVhblxufVxuXG5leHBvcnQgdHlwZSBQcmVzdGFDbGlBcmdzID0ge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIHZhcmlhZGljIENMSSBhcmdzIChQcmVzdGEgZmlsZXMpXG4gICAqL1xuICBfPzogc3RyaW5nW10gLy8gZmlsZXNcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiB1c2VyIHByb3ZpZGVkIGNvbmZpZyBmaWxlcGF0aFxuICAgKi9cbiAgY29uZmlnPzogc3RyaW5nXG4gIC8qKlxuICAgKiBSZS1kZWNsYXJlZCBiZWNhdXNlIENMSSBhcmcgY29tZXMgaW4gYXMgYSBzdHJpbmdcbiAgICpcbiAgICogQGRlc2NyaXB0aW9uIHdoZXRoZXIgb3Igbm90IHRvIHJ1biB0aGUgbG9jYWwgZGV2IEhUVFAgc2VydmVyIChkZWZhdWx0IGBmYWxzZWApXG4gICAqL1xuICBzZXJ2ZT86IHN0cmluZ1xuICAvKipcbiAgICogUmUtZGVjbGFyZWQgYmVjYXVzZSBDTEkgYXJnIGNvbWVzIGluIGFzIGEgc3RyaW5nXG4gICAqXG4gICAqIEBkZXNjcmlwdGlvbiBvcHRpb24gdG8gb3V0cHV0IGRlYnVnIGxvZ3MgZHVyaW5nIGRldiAoZGVmYXVsdCBgZmFsc2VgKVxuICAgKi9cbiAgZGVidWc/OiBzdHJpbmdcbn0gJiBQYXJ0aWFsPE9taXQ8UHJlc3RhQ29uZmlnLCAnZmlsZXMnIHwgJ3BsdWdpbnMnIHwgJ3Jhd0NsaUFyZ3MnIHwgJ3NlcnZlJz4+XG5cbmV4cG9ydCB0eXBlIEhlYWRlcnMgPSBQYXJhbXNcbmV4cG9ydCB0eXBlIE11bHRpVmFsdWVIZWFkZXJzID0gTXVsdGlWYWx1ZVBhcmFtc1xuZXhwb3J0IHR5cGUgUXVlcnlTdHJpbmdQYXJhbWV0ZXJzID0gUGFyYW1zXG5leHBvcnQgdHlwZSBNdWx0aVZhbHVlUXVlcnlTdHJpbmdQYXJhbWV0ZXJzID0gTXVsdGlWYWx1ZVBhcmFtc1xuZXhwb3J0IHR5cGUgUGF0aFBhcmFtZXRlcnMgPSBQYXJhbXNcblxuZXhwb3J0IHR5cGUgRXZlbnQgPSBPbWl0PFxuICBMYW1iZGFFdmVudCxcbiAgJ3F1ZXJ5U3RyaW5nUGFyYW1ldGVycycgfCAnbXVsdGlWYWx1ZVF1ZXJ5U3RyaW5nUGFyYW1ldGVycycgfCAncGF0aFBhcmFtZXRlcnMnXG4+ICYge1xuICBxdWVyeVN0cmluZ1BhcmFtZXRlcnM6IFBhcmFtc1xuICBtdWx0aVZhbHVlUXVlcnlTdHJpbmdQYXJhbWV0ZXJzOiBNdWx0aVZhbHVlUGFyYW1zXG4gIHBhdGhQYXJhbWV0ZXJzOiBQYXJhbXNcbn1cbmV4cG9ydCB0eXBlIENvbnRleHQgPSBMYW1iZGFDb250ZXh0ICYge1xuICBba2V5OiBzdHJpbmddOiB1bmtub3duXG59XG5leHBvcnQgdHlwZSBSZXNwb25zZSA9IE9taXQ8TGFtYmRhUmVzcG9uc2UsICdzdGF0dXNDb2RlJz4gJiB7XG4gIHN0YXR1c0NvZGU/OiBudW1iZXJcbn1cblxuZXhwb3J0IHR5cGUgSGFuZGxlciA9IChldmVudDogRXZlbnQsIGNvbnRleHQ6IENvbnRleHQpID0+IFByb21pc2U8UmVzcG9uc2UgfCBzdHJpbmc+IHwgUmVzcG9uc2UgfCBzdHJpbmdcbmV4cG9ydCB0eXBlIEFXU0xhbWJkYSA9IChldmVudDogRXZlbnQsIGNvbnRleHQ6IENvbnRleHQpID0+IFByb21pc2U8TGFtYmRhUmVzcG9uc2U+XG5cbmV4cG9ydCB0eXBlIFByZXN0YUZpbGUgPSB7XG4gIHJvdXRlPzogc3RyaW5nXG4gIGdldFN0YXRpY1BhdGhzPzogKCkgPT4gUHJvbWlzZTxzdHJpbmdbXT5cbiAgaGFuZGxlcjogSGFuZGxlclxufVxuXG5leHBvcnQgdHlwZSBQcmVzdGFGdW5jdGlvbkZpbGUgPSBQcmVzdGFGaWxlICYge1xuICByb3V0ZTogc3RyaW5nXG59XG5cbmV4cG9ydCB0eXBlIFByZXN0YVN0YXRpY0ZpbGUgPSBQcmVzdGFGaWxlICYge1xuICBnZXRTdGF0aWNQYXRoczogKCkgPT4gUHJvbWlzZTxzdHJpbmdbXT5cbn1cblxuZXhwb3J0IHR5cGUgTWFuaWZlc3QgPSB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIGJ1aWx0IHBhZ2VzIGFuZCBmaWxlcyBmcm9tIHRoZSBQcmVzdGEgcHJvY2Vzcy4gVGhlc2UgYXJlXG4gICAqIG91dHB1dCB0byB0aGUgc2FtZSBkaXJlY3RvcnkgYXMgdGhlIGBjb25maWcuYXNzZXRzYCBzdGF0aWMgYXNzZXRzLlxuICAgKi9cbiAgc3RhdGljczogeyBbZmlsZXBhdGg6IHN0cmluZ106IHN0cmluZ1tdIH1cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgYnVpbHQgQVdTIExhbWJkYS1mbGF2b3JlZCBzZXJ2ZXJsZXNzIGZ1bmN0aW9uc1xuICAgKi9cbiAgZnVuY3Rpb25zOiB7IFtmaWxlcGF0aDogc3RyaW5nXTogeyByb3V0ZTogc3RyaW5nOyBzcmM6IHN0cmluZzsgZGVzdDogc3RyaW5nIH0gfVxufVxuXG5leHBvcnQgdHlwZSBJbnRlcm5hbEV2ZW50cyA9IHtcbiAgZGV2U2VydmVyUmVzdGFydGVkOiB1bmRlZmluZWRcbiAgcmVxdWVzdFJlc3RhcnREZXZTZXJ2ZXI6IHVuZGVmaW5lZFxuICBkZXZGaWxlQWRkZWQ6IHVuZGVmaW5lZFxuICBkZXZGaWxlUmVtb3ZlZDogdW5kZWZpbmVkXG4gIGRldkZpbGVDaGFuZ2VkOiB1bmRlZmluZWRcbn1cblxuZXhwb3J0IHR5cGUgRXh0ZXJuYWxFdmVudHMgPSB7XG4gIGJ1aWxkQ29tcGxldGU6IHVuZGVmaW5lZFxufVxuXG5leHBvcnQgdHlwZSBMb2dnZXJNZXRhZGF0YSA9IHtcbiAgZHVyYXRpb24/OiBzdHJpbmdcbn1cblxuZXhwb3J0IHR5cGUgTG9nZ2VyID0ge1xuICBkZWJ1ZyhtZXNzYWdlOiBzdHJpbmcsIG1ldGFkYXRhPzogTG9nZ2VyTWV0YWRhdGEpOiB2b2lkXG4gIGluZm8obWVzc2FnZTogc3RyaW5nLCBtZXRhZGF0YT86IExvZ2dlck1ldGFkYXRhKTogdm9pZFxuICB3YXJuKG1lc3NhZ2U6IHN0cmluZywgbWV0YWRhdGE/OiBMb2dnZXJNZXRhZGF0YSk6IHZvaWRcbiAgZXJyb3IoZXJyb3I6IEVycm9yIHwgc3RyaW5nLCBtZXRhZGF0YT86IExvZ2dlck1ldGFkYXRhKTogdm9pZFxufVxuXG5leHBvcnQgdHlwZSBQbHVnaW5JbnRlcmZhY2UgPSB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIHBhY2thZ2UgbmFtZSBvZiB0aGUgUHJlc3RhIHBsdWdpbiBlLmcuXG4gICAqIGBAcHJlc3RhL2FkYXB0ZXItbmV0bGlmeWBcbiAgICovXG4gIG5hbWU6IHN0cmluZ1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENhbGxlZCB3aGVuIGRldiBzZXJ2ZXIgcmVzdGFydHMsIGxpa2UgYWZ0ZXIgYW4gZWRpdCBpcyBtYWRlXG4gICAqIHRvIHRoZSBjb25maWcgZmlsZS4gQ2xlYW4gdXAgYW55IGFuZCBhbGwgbGlzdGVuZXJzIGFuZCBzaWRlLWVmZmVjdHMgd2l0aGluXG4gICAqIHRoaXMgbWV0aG9kLlxuICAgKi9cbiAgY2xlYW51cD8oKTogdm9pZFxufVxuXG5leHBvcnQgdHlwZSBQbHVnaW5Db250ZXh0ID0ge1xuICBtb2RlOiBNb2RlXG4gIGN3ZDogc3RyaW5nXG4gIGV2ZW50czogeyBvbjogU21pdHRlcjxFeHRlcm5hbEV2ZW50cz5bJ29uJ10gfVxuICBsb2dnZXI6IExvZ2dlclxuICBnZXRNYW5pZmVzdCgpOiBNYW5pZmVzdFxuICBnZXRPdXRwdXREaXIoKTogc3RyaW5nXG4gIGdldFN0YXRpY091dHB1dERpcigpOiBzdHJpbmdcbiAgZ2V0RnVuY3Rpb25zT3V0cHV0RGlyKCk6IHN0cmluZ1xuICByZXN0YXJ0RGV2U2VydmVyKCk6IHZvaWRcbn1cblxuZXhwb3J0IHR5cGUgUGx1Z2luID0gKGNvbnRleHQ6IFBsdWdpbkNvbnRleHQpID0+IFBsdWdpbkludGVyZmFjZVxuXG5leHBvcnQgdHlwZSBMb2dMZXZlbCA9ICdkZWJ1ZycgfCAnaW5mbycgfCAnd2FybicgfCAnZXJyb3InXG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0SlNDb25maWdGaWxlcGF0aCA9ICdwcmVzdGEuY29uZmlnLmpzJ1xuZXhwb3J0IGNvbnN0IGRlZmF1bHRUU0NvbmZpZ0ZpbGVwYXRoID0gJ3ByZXN0YS5jb25maWcudHMnXG5leHBvcnQgY29uc3Qgcm9vdE91dHB1dERpciA9ICcuLy5wcmVzdGEnXG5leHBvcnQgY29uc3QgZnVuY3Rpb25zT3V0cHV0RGlyID0gJy4vLnByZXN0YS9mdW5jdGlvbnMnXG5leHBvcnQgY29uc3Qgc3RhdGljT3V0cHV0RGlyID0gJy4vLnByZXN0YS9zdGF0aWMnXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVMaXZlUmVsb2FkU2NyaXB0KHsgcG9ydCB9OiB7IHBvcnQ6IG51bWJlciB9KSB7XG4gIHJldHVybiBgXG4gICAgPHNjcmlwdD5cbiAgICAgIChmdW5jdGlvbiAoZ2xvYmFsKSB7XG4gICAgICAgIHZhciBzb2NrZXQgPSBuZXcgV2ViU29ja2V0KCd3czovL2xvY2FsaG9zdDoke3BvcnR9Jyk7XG5cbiAgICAgICAgc29ja2V0LmFkZEV2ZW50TGlzdGVuZXIoJ29wZW4nLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnW3ByZXN0YV0gY29ubmVjdGVkIG9uIHBvcnQgJHtwb3J0fScpXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNvY2tldC5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXFxgJ1twcmVzdGFdIHJlY2VpdmVkIFxcJFxce2V2ZW50LmRhdGFcXH1cXGApXG4gICAgICAgICAgaWYgKGV2ZW50LmRhdGEgPT09ICdyZWZyZXNoJykge1xuICAgICAgICAgICAgZ2xvYmFsLmxvY2F0aW9uLnJlbG9hZCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgc29ja2V0LmFkZEV2ZW50TGlzdGVuZXIoJ2Nsb3NlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdbcHJlc3RhXSBkaXNjb25uZWN0ZWQnKVxuICAgICAgICB9KTtcbiAgICAgIH0pKHRoaXMpO1xuICAgIDwvc2NyaXB0PlxuICBgXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzbHVnaWZ5KGZpbGVuYW1lOiBzdHJpbmcsIGN3ZDogc3RyaW5nKSB7XG4gIHJldHVybiBmaWxlbmFtZVxuICAgIC5yZXBsYWNlKGN3ZCwgJycpIC8vIC9wYWdlcy9GaWxlLnBhZ2UuanNcbiAgICAuc3BsaXQoJy4nKSAvLyBleHRlbnNpb24sIFsvcGFnZXMvRmlsZSwgcGFnZSwganNdXG4gICAgLnJldmVyc2UoKVxuICAgIC5zbGljZSgxKVxuICAgIC5yZXZlcnNlKClcbiAgICAuam9pbignLScpIC8vIC9wYWdlcy9GaWxlLnBhZ2VcbiAgICAuc3BsaXQoJy8nKVxuICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAuam9pbignLScpIC8vIHBhZ2VzLUZpbGUtcGFnZVxufVxuXG4vKipcbiAqIEFjY2VwdHMgdGhlIE1hbmlmZXN0J3MgZnVuY3Rpb25zIG9iamVjdCBhbmQgc29ydHMgaXQgYWNjb3JkaW5nIHRvIHJvdXRlXG4gKiBwcmlvcml0eSwgcmV0dXJuaW5nIHRoZSBmdWxsIG9iamVjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gc29ydE1hbmlmZXN0RnVuY3Rpb25zKGZ1bmN0aW9uczogTWFuaWZlc3RbJ2Z1bmN0aW9ucyddKSB7XG4gIGNvbnN0IGZpbGVzID0gT2JqZWN0LnZhbHVlcyhmdW5jdGlvbnMpXG4gIGNvbnN0IHNvcnRlZFJvdXRlcyA9IHJzb3J0KGZpbGVzLm1hcCgoZikgPT4gZi5yb3V0ZSkpXG4gIHJldHVybiBzb3J0ZWRSb3V0ZXMucmVkdWNlKChmbnMsIHJvdXRlKSA9PiB7XG4gICAgY29uc3QgZmlsZSA9IGZpbGVzLmZpbmQoKGYpID0+IGYucm91dGUgPT09IHJvdXRlKVxuICAgIGlmICghZmlsZSkgcmV0dXJuIGZuc1xuICAgIHJldHVybiB7XG4gICAgICAuLi5mbnMsXG4gICAgICBbZmlsZS5zcmNdOiBmaWxlLFxuICAgIH1cbiAgfSwge30pXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmaW5kQW5kUGFyc2VDb25maWdGaWxlKHVzZXJQcm92aWRlZENvbmZpZ0ZpbGVwYXRoPzogc3RyaW5nKTogUGFydGlhbDxQcmVzdGFDb25maWc+IHtcbiAgaWYgKHVzZXJQcm92aWRlZENvbmZpZ0ZpbGVwYXRoKSB7XG4gICAgcmV0dXJuIHJlcXVpcmVGcmVzaChwYXRoLnJlc29sdmUodXNlclByb3ZpZGVkQ29uZmlnRmlsZXBhdGgpKVxuICB9IGVsc2Uge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gcmVxdWlyZUZyZXNoKHBhdGgucmVzb2x2ZShkZWZhdWx0SlNDb25maWdGaWxlcGF0aCkpXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoZGVmYXVsdEpTQ29uZmlnRmlsZXBhdGgpKSB7XG4gICAgICAgIHRocm93IGVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIHJlcXVpcmVGcmVzaChwYXRoLnJlc29sdmUoZGVmYXVsdFRTQ29uZmlnRmlsZXBhdGgpKVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoZGVmYXVsdFRTQ29uZmlnRmlsZXBhdGgpKSB7XG4gICAgICAgICAgICB0aHJvdyBlXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHt9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlQ29uZmlnKGNvbmZpZ0ZpbGU6IFBhcnRpYWw8UHJlc3RhQ29uZmlnPiwgY2xpQXJnczogUHJlc3RhQ2xpQXJncyA9IHt9KTogUHJlc3RhQ29uZmlnIHtcbiAgLy8gVE9ETyBtYWtlIHN1cmUgY3dkIGlzIGFic29sdXRlXG4gIGNvbnN0IGN3ZCA9IGNvbmZpZ0ZpbGUuY3dkIHx8IHByb2Nlc3MuY3dkKClcblxuICBjb25zdCBtZXJnZWQ6IFByZXN0YUNvbmZpZyA9IHtcbiAgICBjd2QsXG4gICAgZmlsZXM6IGNvbmZpZ0ZpbGUuZmlsZXMgfHwgW10sIC8vIFRPRE8gd2hlcmUgZG8gd2UgdmFsaWRhdGVcbiAgICBhc3NldHM6IGNvbmZpZ0ZpbGUuYXNzZXRzIHx8ICdwdWJsaWMnLFxuICAgIHBsdWdpbnM6IGNvbmZpZ0ZpbGUucGx1Z2lucyB8fCBbXSxcbiAgICBwb3J0OiBjb25maWdGaWxlLnBvcnQgfHwgNDAwMCxcbiAgICBzZXJ2ZTogY29uZmlnRmlsZS5zZXJ2ZSA/PyB0cnVlLFxuICAgIGRlYnVnOiAhIWNvbmZpZ0ZpbGUuZGVidWcsXG4gICAgX191bnNhZmVfYnVuZGxlX2V2ZXJ5dGhpbmc6IGNvbmZpZ0ZpbGUuX191bnNhZmVfYnVuZGxlX2V2ZXJ5dGhpbmcgPz8gZmFsc2UsXG4gICAgcmF3Q2xpQXJnczogY2xpQXJncyxcbiAgfVxuXG4gIC8qKlxuICAgKiBPdmVycmlkZSBjb25maWcgZmlsZSBvcHRpb25zIHdpdGggQ0xJXG4gICAqL1xuICBpZiAoY2xpQXJncy5fPy5sZW5ndGgpIG1lcmdlZC5maWxlcyA9IGNsaUFyZ3MuX1xuICBpZiAoY2xpQXJncy5hc3NldHMpIG1lcmdlZC5hc3NldHMgPSBjbGlBcmdzLmFzc2V0c1xuICBpZiAoY2xpQXJncy5wb3J0KSBtZXJnZWQucG9ydCA9IGNsaUFyZ3MucG9ydFxuICBpZiAoY2xpQXJncy5zZXJ2ZSkgbWVyZ2VkLnNlcnZlID0gY2xpQXJncy5zZXJ2ZSA9PT0gJ3RydWUnXG4gIGlmIChjbGlBcmdzLmRlYnVnKSBtZXJnZWQuZGVidWcgPSBjbGlBcmdzLmRlYnVnID09PSB0cnVlXG5cbiAgLyoqXG4gICAqIFJlc29sdmUgYWJzb2x1dGUgcGF0aHNcbiAgICovXG4gIGlmIChtZXJnZWQuZmlsZXMpIG1lcmdlZC5maWxlcyA9IChbXSBhcyBzdHJpbmdbXSkuY29uY2F0KG1lcmdlZC5maWxlcykubWFwKChwKSA9PiBwYXRoLnJlc29sdmUobWVyZ2VkLmN3ZCwgcCkpXG4gIGlmIChtZXJnZWQuYXNzZXRzKSBtZXJnZWQuYXNzZXRzID0gcGF0aC5yZXNvbHZlKG1lcmdlZC5jd2QsIG1lcmdlZC5hc3NldHMpXG5cbiAgcmV0dXJuIG1lcmdlZFxufVxuXG5leHBvcnQgZnVuY3Rpb24gcGF0aG5hbWVUb0ZpbGUocGF0aG5hbWU6IHN0cmluZywgZXh0ID0gJ2h0bWwnKSB7XG4gIHJldHVybiAhIXBhdGguZXh0bmFtZShwYXRobmFtZSlcbiAgICA/IHBhdGhuYW1lIC8vIGlmIHBhdGggaGFzIGV4dGVuc2lvbiwgdXNlIGl0XG4gICAgOiBleHQgPT09ICdodG1sJ1xuICAgID8gYCR7cGF0aG5hbWV9L2luZGV4Lmh0bWxgIC8vIGlmIEhUTUwgaXMgaW5mZXJyZWQsIGNyZWF0ZSBpbmRleFxuICAgIDogYCR7cGF0aG5hbWV9LiR7ZXh0fWAgLy8gYW55dGhpbmcgYnV0IEhUTUwgd2lsbCBuZWVkIGFuIGV4dGVuc2lvbiwgb3RoZXJ3aXNlIGJyb3dzZXJzIHdpbGwgcmVuZGVyIGFzIHRleHRcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1pbWVUeXBlKHJlc3BvbnNlOiBMYW1iZGFSZXNwb25zZSkge1xuICBjb25zdCB0eXBlID0gKHJlc3BvbnNlPy5oZWFkZXJzIHx8IHt9KVsnY29udGVudC10eXBlJ11cbiAgcmV0dXJuIG1pbWUuZXh0ZW5zaW9uKHR5cGUgYXMgc3RyaW5nKSB8fCAnaHRtbCdcbn1cblxuLyoqXG4gKiBMb2FkcyB0aGUgX3NvdXJjZV8gZmlsZSwgbm90IHRoZSBidWlsdCBmaWxlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2FkU291cmNlRnVuY3Rpb25GaWxlRnJvbU1hbmlmZXN0KFxuICB1cmw6IHN0cmluZyxcbiAgbWFuaWZlc3Q6IE1hbmlmZXN0XG4pOiB7XG4gIGZpbGVwYXRoOiBzdHJpbmdcbiAgZXhwb3J0czogUHJlc3RhRnVuY3Rpb25GaWxlXG59IHtcbiAgY29uc3QgcHJlc3RhRmlsZSA9IE9iamVjdC5lbnRyaWVzKG1hbmlmZXN0LmZ1bmN0aW9ucylcbiAgICAubWFwKChbZmlsZXBhdGgsIHsgcm91dGUgfV0pID0+ICh7XG4gICAgICBtYXRjaGVyOiB0b1JlZ0V4cChyb3V0ZSksXG4gICAgICBmaWxlOiBmaWxlcGF0aCxcbiAgICB9KSlcbiAgICAuZmlsdGVyKCh7IG1hdGNoZXIgfSkgPT4ge1xuICAgICAgcmV0dXJuIG1hdGNoZXIucGF0dGVybi50ZXN0KHVybC5zcGxpdCgnPycpWzBdKVxuICAgIH0pXG4gICAgLm1hcCgoeyBmaWxlIH0pID0+IGZpbGUpWzBdXG5cbiAgcmV0dXJuIHtcbiAgICBmaWxlcGF0aDogcHJlc3RhRmlsZSxcbiAgICBleHBvcnRzOiBwcmVzdGFGaWxlID8gcmVxdWlyZUZyZXNoKHByZXN0YUZpbGUpIDogdW5kZWZpbmVkLFxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQcmVzdGEge1xuICBjd2Q6IHN0cmluZyA9IHByb2Nlc3MuY3dkKClcblxuICAvKipcbiAgICogRnVsbCBjb25maWcsIHdpdGggQ0xJIGFyZ3VtZW50cyBtZXJnZWQgaW5cbiAgICovXG4gIGNvbmZpZzogUHJlc3RhQ29uZmlnXG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgaW4gcHJvZHVjdGlvbiBvciBkZXZlbG9wbWVudFxuICAgKi9cbiAgbW9kZTogTW9kZSA9IE1vZGUuRGV2XG5cbiAgLyoqXG4gICAqIFRoZSBwb3J0IHByZXN0YSB3aWxsIHNlcnZlIGZpbGVzIGZyb20gaW4gZGV2IG1vZGVcbiAgICovXG4gIHBvcnQ6IG51bWJlclxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gb3B0aW9uIHRvIG91dHB1dCBkZWJ1ZyBsb2dzIGR1cmluZyBkZXYgKGRlZmF1bHQgYGZhbHNlYClcbiAgICovXG4gIGRlYnVnID0gZmFsc2VcblxuICAvKipcbiAgICogT3V0cHV0IGRpcmVjdG9yeSBmb3Igc3RhdGljIGFzc2V0cyBhbmQgZ2VuZXJhdGVkIGZpbGVzXG4gICAqL1xuICBzdGF0aWNPdXRwdXREaXI6IHN0cmluZ1xuXG4gIC8qKlxuICAgKiBPdXRwdXQgZGlyZWN0b3J5IGZvciBzZXJ2ZXJsZXNzIGZ1bmN0aW9ucy4gVGhpcyBpcyBwcm9iYWJseSBzZXBhcmF0ZSBmcm9tXG4gICAqIHdoZXJlIGFkYXB0ZXJzIG91dHB1dCBmaWxlcy5cbiAgICovXG4gIGZ1bmN0aW9uc091dHB1dERpcjogc3RyaW5nXG5cbiAgLyoqXG4gICAqIEhpZGRlbiAucHJlc3RhIGRpciBmb3IgaW50ZXJuYWwgZmlsZXNcbiAgICovXG4gIHByZXN0YU91dHB1dERpcjogc3RyaW5nXG5cbiAgLyoqXG4gICAqIEZpbGVwYXRoIHRvIG91dHB1dCBidWlsZCBtYW5pZmVzdCB0bywgd2l0aGluIGBjb25maWcub3V0cHV0YCBkaXJlY3RvcnlcbiAgICovXG4gIG1hbmlmZXN0RmlsZXBhdGg6IHN0cmluZ1xuXG4gIC8qKlxuICAgKiBGdWxsIGJ1aWxkIG1hbmlmZXN0LiBTaG91bGQgYmUga2VwdCB1cCB0byBkYXRlIGFzIGZpbGVzIGFyZSBhZGRlZC9yZW1vdmVkL2J1aWx0LlxuICAgKi9cbiAgbWFuaWZlc3Q6IE1hbmlmZXN0ID0ge1xuICAgIHN0YXRpY3M6IHt9LFxuICAgIGZ1bmN0aW9uczoge30sXG4gIH1cblxuICAvKipcbiAgICogQWxsIHdhdGNoZWQgZmlsZXMsIGNvbXB1dGVkIGZyb20gYGNvbmZpZy5maWxlc2Agb3IgQ0xJIGFyZ3MuXG4gICAqL1xuICBmaWxlczogc3RyaW5nW10gPSBbXVxuXG4gIC8qKlxuICAgKiBFdmVudCBlbWl0dGVycyBmb3IgYm90aCBpbnRlcm5hbCBldmVudHMgYW5kIGV4dGVybmFsIGV2ZW50cyBjb25zdW1lZCBieVxuICAgKiB1c2VycyBhbmQgcGx1Z2luc1xuICAgKi9cbiAgZXZlbnRzID0ge1xuICAgIGludGVybmFsOiBzbWl0dGVyPEludGVybmFsRXZlbnRzPigpLFxuICAgIGV4dGVybmFsOiBzbWl0dGVyPEV4dGVybmFsRXZlbnRzPigpLFxuICB9XG5cbiAgLyoqXG4gICAqIDxzY3JpcHQ+IHRhZyBhZGRlZCB0byBhbGwgSFRNTCByZXNwb25zZXMsIGRlcGVuZHMgb24gYHRoaXMuY29uZmlnLnBvcnRgXG4gICAqL1xuICBsaXZlUmVsb2FkU2NyaXB0ID0gJydcblxuICBwbHVnaW5zOiBQbHVnaW5JbnRlcmZhY2VbXVxuXG4gIGxvZ2dlcjogTG9nZ2VyXG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBQYXJ0aWFsPFByZXN0YUNvbmZpZz4pIHtcbiAgICB0aGlzLmN3ZCA9IGNvbmZpZy5jd2QgfHwgcHJvY2Vzcy5jd2QoKVxuXG4gICAgZG90ZW52KHsgcGF0aDogcGF0aC5qb2luKHRoaXMuY3dkLCAnLmVudicpIH0pXG4gICAgYWRkQWxpYXNlcyh7ICdAJzogdGhpcy5jd2QgfSlcblxuICAgIC8vIG1lcmdlIGRlZmF1bHRzIGFnYWluIGluIGNhc2Ugb2YgcHJvZ3JhbW1hdGljIHVzYWdlIGFuZCBwYXJ0aWFsIG9wdGlvbnNcbiAgICB0aGlzLmNvbmZpZyA9IG1lcmdlQ29uZmlnKGNvbmZpZylcbiAgICB0aGlzLmRlYnVnID0gISF0aGlzLmNvbmZpZy5kZWJ1Z1xuICAgIHRoaXMubG9nZ2VyID0ge1xuICAgICAgZGVidWc6IChtZXNzYWdlLCBtZXRhZGF0YSkgPT4gdGhpcy5fbG9nKCdkZWJ1ZycsIG1lc3NhZ2UsIG1ldGFkYXRhKSxcbiAgICAgIGluZm86IChtZXNzYWdlLCBtZXRhZGF0YSkgPT4gdGhpcy5fbG9nKCdpbmZvJywgbWVzc2FnZSwgbWV0YWRhdGEpLFxuICAgICAgd2FybjogKG1lc3NhZ2UsIG1ldGFkYXRhKSA9PiB0aGlzLl9sb2coJ3dhcm4nLCBtZXNzYWdlLCBtZXRhZGF0YSksXG4gICAgICBlcnJvcjogKGVycm9yLCBtZXRhZGF0YSkgPT4gdGhpcy5fbG9nKCdlcnJvcicsIGVycm9yLCBtZXRhZGF0YSksXG4gICAgfVxuXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoYGluaXRpYWxpemVkIHdpdGggY29uZmlnICR7SlNPTi5zdHJpbmdpZnkoY29uZmlnLCBudWxsLCAnICAnKX1gKVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGFsbCBmaWxlcyBhbmQgY29weSBzdGF0aWMgYXNzZXRzIHRvIGBjb25maWcub3V0cHV0YC5cbiAgICovXG4gIGFzeW5jIGJ1aWxkKCkge1xuICAgIHRoaXMubW9kZSA9IE1vZGUuQnVpbGRcblxuICAgIHRoaXMuX2luaXQoKVxuXG4gICAgaWYgKCF0aGlzLmZpbGVzLmxlbmd0aCkge1xuICAgICAgdGhpcy5sb2dnZXIud2Fybihgbm8gZmlsZXMgd2VyZSBmb3VuZCwgbm90aGluZyB0byBidWlsZGApXG5cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHRpbWUgPSB0aW1lcigpXG4gICAgY29uc3QgcGtnID0gcmVxdWlyZShwYXRoLmpvaW4odGhpcy5jd2QsICdwYWNrYWdlLmpzb24nKSlcblxuICAgIC8vIGNsZWFuIHNsYXRlXG4gICAgYXdhaXQgZnMucmVtb3ZlKHRoaXMuc3RhdGljT3V0cHV0RGlyKSAvLyBjb3VsZCBiZSBvdmVycmlkZGVuIGJ5IGEgcGx1Z2luXG4gICAgYXdhaXQgZnMucmVtb3ZlKHRoaXMuZnVuY3Rpb25zT3V0cHV0RGlyKSAvLyBjb3VsZCBiZSBvdmVycmlkZGVuIGJ5IGEgcGx1Z2luXG5cbiAgICAvLyBjb3B5IHN0YXRpYyBhc3NldHNcbiAgICBpZiAoZnMuZXhpc3RzU3luYyh0aGlzLmNvbmZpZy5hc3NldHMpKSBhd2FpdCBmcy5jb3B5KHRoaXMuY29uZmlnLmFzc2V0cywgdGhpcy5zdGF0aWNPdXRwdXREaXIpXG5cbiAgICAvLyBidWlsZCBhbGwgZmlsZXMsIGdlbmVyYXRlIG1hbmlmZXNldFxuICAgIGF3YWl0IHRoaXMuYnVpbGRGaWxlcyh0aGlzLmZpbGVzKVxuXG4gICAgLy8gdXNlIG1hbmlmZXN0IHRvIGNvbXBpbGUgcHJvZHVjdGlvbiBzZXJ2ZXJsZXNzIGZ1bmN0aW9uc1xuICAgIGF3YWl0IGVzYnVpbGQoe1xuICAgICAgZW50cnlQb2ludHM6IE9iamVjdC52YWx1ZXModGhpcy5tYW5pZmVzdC5mdW5jdGlvbnMpLm1hcCgoeyBkZXN0IH0pID0+IGRlc3QpLFxuICAgICAgb3V0ZGlyOiB0aGlzLmZ1bmN0aW9uc091dHB1dERpcixcbiAgICAgIHBsYXRmb3JtOiAnbm9kZScsXG4gICAgICB0YXJnZXQ6IFsnbm9kZTEyJ10sXG4gICAgICBtaW5pZnk6IHRydWUsXG4gICAgICBhbGxvd092ZXJ3cml0ZTogdHJ1ZSxcbiAgICAgIGV4dGVybmFsOiB0aGlzLmNvbmZpZy5fX3Vuc2FmZV9idW5kbGVfZXZlcnl0aGluZyA/IFtdIDogT2JqZWN0LmtleXMocGtnLmRlcGVuZGVuY2llcyB8fCB7fSksXG4gICAgICBidW5kbGU6IHRydWUsXG4gICAgICBkZWZpbmU6IHtcbiAgICAgICAgJ3Byb2Nlc3MuZW52LlBSRVNUQV9TRVJWRVJMRVNTX1JVTlRJTUUnOiAndHJ1ZScsXG4gICAgICB9LFxuICAgIH0pXG5cbiAgICB0aGlzLmxvZ2dlci5pbmZvKGBwcmVzdGEgYnVpbGQgY29tcGxldGVgLCB7IGR1cmF0aW9uOiB0aW1lKCkgfSlcblxuICAgIHRoaXMuZXZlbnRzLmV4dGVybmFsLmVtaXQoJ2J1aWxkQ29tcGxldGUnKVxuICB9XG5cbiAgYXN5bmMgZGV2KCkge1xuICAgIHRoaXMubW9kZSA9IE1vZGUuRGV2XG5cbiAgICB0aGlzLl9pbml0KClcblxuICAgIGlmICh0aGlzLmNvbmZpZy5zZXJ2ZSkge1xuICAgICAgYXdhaXQgdGhpcy5fZ2V0UG9ydCgpXG4gICAgICB0aGlzLmxpdmVSZWxvYWRTY3JpcHQgPSB0aGlzLmNvbmZpZy5zZXJ2ZSA/IGNyZWF0ZUxpdmVSZWxvYWRTY3JpcHQoeyBwb3J0OiB0aGlzLnBvcnQgfSkgOiAnJ1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlYm91bmNlIHJlc3RhcnRzIGlmIG11bHRpcGxlIGFyZSB0cmlnZ2VyZWQgaW4gcXVpY2sgc3VjY2Vzc2lvblxuICAgICAqL1xuICAgIGxldCByZXN0YXJ0aW5nID0gZmFsc2VcblxuICAgIC8qKlxuICAgICAqIFRoZSBtYWluIGRldiBwcm9jZXNzLlxuICAgICAqL1xuICAgIGxldCB3YXRjaGVyID0gYXdhaXQgdGhpcy5faW5pdERldigpXG5cbiAgICAvKipcbiAgICAgKiBMb2NhbCBmdW5jdGlvbiB0byBoYW5kbGUgcmVzZXR0aW5nIGV2ZXJ5dGhpbmcgYWZ0ZXIgYSBjb25maWcgZmlsZSBjaGFuZ2UuXG4gICAgICogQWxzbyBjYWxsZWQgcHJvZ3JhbW1hdGljYWxseSBmcm9tIHBsdWdpbnMgd2hlbiB0aGVpciBjb25maWdzIGNoYW5nZS5cbiAgICAgKi9cbiAgICBjb25zdCByZXN0YXJ0ID0gYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gZGVib3VuY2VcbiAgICAgIGlmIChyZXN0YXJ0aW5nKSByZXR1cm5cbiAgICAgIHJlc3RhcnRpbmcgPSB0cnVlXG5cbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIGRlc3Ryb3kgb2xkIHdhdGNoIHByb2Nlc3NcbiAgICAgICAgYXdhaXQgd2F0Y2hlci5jbGVhbnVwKClcblxuICAgICAgICBpZiAoIXRoaXMuZGVidWcpIGNvbnNvbGUuY2xlYXIoKVxuXG4gICAgICAgIHRoaXMubG9nZ2VyLmluZm8oYFx1MjY3QSByZXN0YXJ0aW5nYClcblxuICAgICAgICAvLyByZXNldCBjb25maWcgaW4gY2FzZSBvZiBjaGFuZ2VzXG4gICAgICAgIHRoaXMuY29uZmlnID0gbWVyZ2VDb25maWcoZmluZEFuZFBhcnNlQ29uZmlnRmlsZSh0aGlzLmNvbmZpZy5yYXdDbGlBcmdzLmNvbmZpZyksIHRoaXMuY29uZmlnLnJhd0NsaUFyZ3MpXG5cbiAgICAgICAgLy8gcnVuIF9pbml0IGFnYWluIHRvIHJlY29tcHV0ZSBpbnN0YW5jZSB2YWx1ZXMgYW5kIGNsZWFudXAgcGx1Z2luc1xuICAgICAgICB0aGlzLl9pbml0KClcblxuICAgICAgICAvLyBzdGFydCBhIG5ldyB3YXRjaCBwcm9jZXNzXG4gICAgICAgIHdhdGNoZXIgPSBhd2FpdCB0aGlzLl9pbml0RGV2KClcblxuICAgICAgICB0aGlzLmV2ZW50cy5pbnRlcm5hbC5lbWl0KCdkZXZTZXJ2ZXJSZXN0YXJ0ZWQnKVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihlIGFzIEVycm9yKVxuICAgICAgfVxuXG4gICAgICAvLyBkb24ndCBmb3JnZXQgdG8gcmVzZXQhXG4gICAgICByZXN0YXJ0aW5nID0gZmFsc2VcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXYXRjaGVzIGZvciBjb25maWcgZmlsZXMgY2hhbmdlcyBhbmQgcmVzdGFydHMgdGhlIHdhdGNoIHByb2Nlc3Mgb24gY2hhbmdlcy5cbiAgICAgKi9cbiAgICBjb25zdCBjb25maWdXYXRjaGVyID0gY2hva2lkYXJcbiAgICAgIC53YXRjaChcbiAgICAgICAgW1xuICAgICAgICAgIHRoaXMuY29uZmlnLnJhd0NsaUFyZ3MuY29uZmlnICYmIHBhdGgucmVzb2x2ZSh0aGlzLmNvbmZpZy5yYXdDbGlBcmdzLmNvbmZpZyksXG4gICAgICAgICAgZGVmYXVsdEpTQ29uZmlnRmlsZXBhdGgsXG4gICAgICAgICAgZGVmYXVsdFRTQ29uZmlnRmlsZXBhdGgsXG4gICAgICAgIF0uZmlsdGVyKEJvb2xlYW4pIGFzIHN0cmluZ1tdLFxuICAgICAgICB7IGlnbm9yZUluaXRpYWw6IHRydWUgfVxuICAgICAgKVxuICAgICAgLm9uKCdhbGwnLCByZXN0YXJ0KVxuXG4gICAgdGhpcy5