@centia-io/sdk 0.0.27 → 0.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +0,0 @@
1
- (function(a,h){typeof exports=="object"&&typeof module<"u"?h(exports):typeof define=="function"&&define.amd?define(["exports"],h):(a=typeof globalThis<"u"?globalThis:a||self,h(a.gc2={}))})(this,function(a){"use strict";class h extends Error{}h.prototype.name="InvalidTokenError";function E(s){return decodeURIComponent(atob(s).replace(/(.)/g,(e,t)=>{let o=t.charCodeAt(0).toString(16).toUpperCase();return o.length<2&&(o="0"+o),"%"+o}))}function O(s){let e=s.replace(/-/g,"+").replace(/_/g,"/");switch(e.length%4){case 0:break;case 2:e+="==";break;case 3:e+="=";break;default:throw new Error("base64 string is not of the correct length")}try{return E(e)}catch{return atob(e)}}function S(s,e){if(typeof s!="string")throw new h("Invalid token specified: must be a string");e||(e={});const t=e.header===!0?0:1,o=s.split(".")[t];if(typeof o!="string")throw new h(`Invalid token specified: missing part #${t+1}`);let r;try{r=O(o)}catch(n){throw new h(`Invalid token specified: invalid base64 for part #${t+1} (${n.message})`)}try{return JSON.parse(r)}catch(n){throw new h(`Invalid token specified: invalid json for part #${t+1} (${n.message})`)}}class P{constructor(){this.store=new Map}getItem(e){return this.store.has(e)?this.store.get(e):null}setItem(e,t){this.store.set(e,String(t))}removeItem(e){this.store.delete(e)}}let g=null;function l(){if(g)return g;try{const e=typeof globalThis<"u"?globalThis:window;if(e&&e.localStorage&&typeof e.localStorage.getItem=="function")return g=e.localStorage,g}catch{}const s=typeof globalThis<"u"?globalThis:{};return s.__gc2_memory_storage||(s.__gc2_memory_storage=new P),g=s.__gc2_memory_storage,g}const R=async()=>{const s=()=>{const c=new Uint32Array(28);return crypto.getRandomValues(c),Array.from(c,p=>("0"+p.toString(16)).substr(-2)).join("")},e=c=>{const f=new TextEncoder().encode(c);return crypto.subtle.digest("SHA-256",f)},t=c=>btoa(String.fromCharCode.apply(null,[...new Uint8Array(c)])).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"");async function o(c){const p=await e(c);return t(p)}const{state:r,codeVerifier:n}={state:s(),codeVerifier:s()},i=await o(n);return{state:r,codeVerifier:n,codeChallenge:i}},_=s=>{let e=!1;const{exp:t}=S(s),o=new Date().getTime()/1e3;return t&&o>t&&(e=!0),e},q=s=>S(s),U=async s=>{const{accessToken:e,refreshToken:t}=w();if(!e&&!t)return!1;if(!e||e&&_(e)){if(t&&_(t))throw T(),y(),new Error("Refresh token has expired. Please login again.");if(t)try{const o=await s.getRefreshToken(t);m({accessToken:o.access_token,refreshToken:t,idToken:o==null?void 0:o.id_token}),console.log("Access token refreshed")}catch{throw new Error("Could not get refresh token.")}}return!0},m=s=>{l().setItem("gc2_tokens",JSON.stringify({accessToken:s.accessToken,refreshToken:s.refreshToken,idToken:(s==null?void 0:s.idToken)||""}))},w=()=>{const s=l().getItem("gc2_tokens"),e=s?JSON.parse(s):{};return{accessToken:(e==null?void 0:e.accessToken)||"",refreshToken:(e==null?void 0:e.refreshToken)||"",idToken:(e==null?void 0:e.idToken)||""}},I=s=>{l().setItem("gc2_options",JSON.stringify({clientId:s.clientId,host:s.host,redirectUri:s.redirectUri}))},b=()=>{const s=l().getItem("gc2_options"),e=s?JSON.parse(s):{};return{clientId:(e==null?void 0:e.clientId)||"",host:(e==null?void 0:e.host)||"",redirectUri:(e==null?void 0:e.redirectUri)||""}},T=()=>{l().removeItem("gc2_tokens")},y=()=>{l().removeItem("gc2_options")},A=()=>l().getItem("gc2_nonce"),C=()=>{l().removeItem("gc2_nonce")};class k{constructor(e){this.options=e,this.host=e.host}isCodeFlowOptions(e){return"redirectUri"in e}isPasswordFlowOptions(e){return"username"in e}buildUrl(e){return e.startsWith("http://")||e.startsWith("https://")?e:`${this.host}${e}`}async request(e,t,o,r="application/json"){const n={"Content-Type":r};let i;r==="application/json"?i=JSON.stringify(o):i=new URLSearchParams(o).toString();const c=await fetch(e,{method:t,headers:n,body:i});if(!c.ok){const p=await c.text();throw new Error(`HTTP error ${c.status}: ${p}`)}return c.json()}async getDeviceCode(){const e=this.options.deviceUri??`${this.host}/api/v4/oauth/device`;return this.request(this.buildUrl(e),"POST",{client_id:this.options.clientId})}async pollToken(e,t){const o=this.options.tokenUri??`${this.host}/api/v4/oauth`,r=async()=>{try{return await this.request(this.buildUrl(o),"POST",{client_id:this.options.clientId,device_code:e,grant_type:"device_code"})}catch(i){const c=JSON.parse(i.message.split(": ")[1]);return c.error==="authorization_pending"?null:c.error_description}};let n=await r();for(;n===null;)await new Promise(i=>setTimeout(i,t*1100)),n=await r();if(typeof n=="string")throw new Error(n);return n}getAuthorizationCodeURL(e,t){let o;if(this.isCodeFlowOptions(this.options))o=this.options.redirectUri;else throw new Error("CodeFlow options required for this operation");const r=this.options.authUri??`${this.host}/auth/`,n=new URLSearchParams,i=A();return n.set("response_type","code"),n.set("client_id",this.options.clientId),n.set("redirect_uri",o),n.set("state",t),n.set("code_challenge",e),n.set("code_challenge_method","S256"),i&&n.set("nonce",i),this.options.scope&&n.set("scope",this.options.scope),`${r}?${n.toString()}`}async getAuthorizationCodeToken(e,t){let o;if(this.isCodeFlowOptions(this.options))o=this.options.redirectUri;else throw new Error("CodeFlow options required for this operation");const r=this.options.tokenUri??`${this.host}/api/v4/oauth`;return this.request(this.buildUrl(r),"POST",{client_id:this.options.clientId,redirect_uri:o,grant_type:"authorization_code",code:e,code_verifier:t},"application/x-www-form-urlencoded")}async getPasswordToken(){let e,t,o;if(this.isPasswordFlowOptions(this.options))e=this.options.username,t=this.options.password,o=this.options.database;else throw new Error("PasswordFlow options required for this operation");const r=`${this.host}/api/v4/oauth`;return this.request(this.buildUrl(r),"POST",{client_id:this.options.clientId,grant_type:"password",username:e,password:t,database:o})}async getRefreshToken(e){const t=this.options.tokenUri??`${this.host}/api/v4/oauth`;return this.request(this.buildUrl(t),"POST",{client_id:this.options.clientId,grant_type:"refresh_token",refresh_token:e})}getSignOutURL(){let e;if(this.isCodeFlowOptions(this.options))e=this.options.redirectUri;else throw new Error("CodeFlow options required for this operation");const t=new URLSearchParams({redirect_uri:e});return this.options.logoutUri??`${this.host}/signout?${t.toString()}`}}class F{constructor(e){this.options=e,this.service=new k(e)}async redirectHandle(){const e=window.location.search,t=new URLSearchParams(e);if(t.get("error"))throw new Error(`Failed to redirect: ${e}`);const r=t.get("code");if(r){if(t.get("state")!==l().getItem("state"))throw new Error("Possible CSRF attack. Aborting login!");try{const{access_token:i,refresh_token:c,id_token:p}=await this.service.getAuthorizationCodeToken(r,l().getItem("codeVerifier"));m({accessToken:i,refreshToken:c,idToken:p}),I({clientId:this.options.clientId,host:this.options.host,redirectUri:this.options.redirectUri}),l().removeItem("state"),l().removeItem("codeVerifier");const f=new URLSearchParams(window.location.search);f.delete("code"),f.delete("state");const $=window.location,B=$.origin+$.pathname+(f.size>0?"?"+f.toString():"");return history.pushState(null,"",B),Promise.resolve(!0)}catch(i){throw new Error(i.message)}}return await U(this.service)}async signIn(){const{state:e,codeVerifier:t,codeChallenge:o}=await R();l().setItem("state",e),l().setItem("codeVerifier",t),window.location=this.service.getAuthorizationCodeURL(o,e)}signOut(){this.clear(),window.location=this.service.getSignOutURL()}clear(){T(),y(),C()}}class j{constructor(e){this.options=e,this.service=new k(e)}async signIn(){const{access_token:e,refresh_token:t}=await this.service.getPasswordToken();m({accessToken:e,refreshToken:t}),I({clientId:this.options.clientId,host:this.options.host,redirectUri:""})}signOut(){this.clear()}clear(){T(),y(),C()}}/**
2
- * @author Martin Høgh <mh@mapcentia.com>
3
- * @copyright 2013-2024 MapCentia ApS
4
- * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3
5
- *
6
- */const L=async(s="application/json")=>{const e=b(),t=new k(e);if(!await U(t))return Promise.reject("Is not logged in");const{accessToken:o}=w(),r={Accept:"application/json",Cookie:"XDEBUG_SESSION=XDEBUG_ECLIPSE",Authorization:o?"Bearer "+o:null};return s&&(r["Content-Type"]=s),r};/**
7
- * @author Martin Høgh <mh@mapcentia.com>
8
- * @copyright 2013-2024 MapCentia ApS
9
- * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3
10
- *
11
- */const d=async(s,e,t,o,r="application/json")=>{const n=b(),i=await L(r);let c={method:t,headers:i,redirect:"manual"};return o&&(c.body=r==="application/json"?JSON.stringify(o):o),await fetch(n.host+`/api/v${s}/${e}`,c)},u=async(s,e)=>{let t=null,o="";try{o=await s.text()}catch{}if(o)try{t=JSON.parse(o)}catch{}if(s.status!==e){const r=t&&(t.message||t.error)||o||`Unexpected status ${s.status}`;throw new Error(r)}return t};class N{async exec(e){const t=await d("4","sql","POST",e);return await u(t,200)}}class v{async call(e){const t=await d("4","call","POST",e);return await u(t,200)}}class J{async query(e){const t=await d("3",`meta/${e}`,"GET",null);return await u(t,200)}}class z{isAuth(){const e=w();return!(!e.accessToken&&!e.refreshToken)}getTokens(){return w()}}class D{get(){const e=w().accessToken;return q(e)}}class V{async get(e){const t=await d("4",`users/${e}`,"GET",null);return await u(t,200)}}class W{constructor(e){this.options=e}connect(){const e=this,{accessToken:t}=w(),o=()=>{const r=new WebSocket(this.options.host+"/?token="+t);r.onopen=function(){console.log("WebSocket connected!")},r.onmessage=function(n){var i;(i=e.options)==null||i.callBack(n.data)},r.onclose=function(n){t!==""&&(console.log("WebSocket closed, reconnecting in 3 seconds...",n.reason),setTimeout(o,3e3))},r.onerror=function(n){console.error("WebSocket error observed:",n),r.close()}};t!==""&&o()}}class G{async get(){const e=await d("4","stats","GET",null);return await u(e,200)}}class x{async get(e,t){const o=await d("4",`schemas/${encodeURIComponent(e)}/tables/${encodeURIComponent(t)}`,"GET",null);return await u(o,200)}async create(e,t,o){const r=await d("4",`schemas/${encodeURIComponent(e)}/tables/${encodeURIComponent(t)}`,"POST",o);return await u(r,200)}async patch(e,t,o){const r=await d("4",`schemas/${encodeURIComponent(e)}/tables/${encodeURIComponent(t)}`,"PATCH",o);return await u(r,200)}async delete(e,t){const o=await d("4",`schemas/${encodeURIComponent(e)}/tables/${encodeURIComponent(t)}`,"DELETE",null);return await u(o,204)}}async function H(s,e){const t=new v,o={jsonrpc:"2.0",method:s,id:1,params:e};return(await t.call(o)).result.data}function M(){return new Proxy({},{get(s,e){if(typeof e=="string")return(...t)=>H(e,...t)}})}a.Claims=D,a.CodeFlow=F,a.Meta=J,a.PasswordFlow=j,a.Rpc=v,a.Sql=N,a.Stats=G,a.Status=z,a.Tables=x,a.Users=V,a.Ws=W,a.createApi=M,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})});
12
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VudGlhLWlvLXNkay5qcyIsInNvdXJjZXMiOlsiLi4vc3JjL3V0aWwvand0LWRlY29kZS50cyIsIi4uL3NyYy91dGlsL3N0b3JhZ2UudHMiLCIuLi9zcmMvdXRpbC91dGlscy50cyIsIi4uL3NyYy9zZXJ2aWNlcy9nYzIuc2VydmljZXMudHMiLCIuLi9zcmMvQ29kZUZsb3cudHMiLCIuLi9zcmMvUGFzc3dvcmRGbG93LnRzIiwiLi4vc3JjL3V0aWwvcmVxdWVzdC1oZWFkZXJzLnRzIiwiLi4vc3JjL3V0aWwvbWFrZS1yZXF1ZXN0LnRzIiwiLi4vc3JjL3V0aWwvZ2V0LXJlc3BvbnNlLnRzIiwiLi4vc3JjL1NxbC50cyIsIi4uL3NyYy9ScGMudHMiLCIuLi9zcmMvTWV0YS50cyIsIi4uL3NyYy9TdGF0dXMudHMiLCIuLi9zcmMvQ2xhaW1zLnRzIiwiLi4vc3JjL1VzZXJzLnRzIiwiLi4vc3JjL1dzLnRzIiwiLi4vc3JjL1N0YXRzLnRzIiwiLi4vc3JjL1RhYmxlcy50cyIsIi4uL3NyYy9BcGkudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIFRoZSBNSVQgTGljZW5zZSAoTUlUKVxyXG4gKlxyXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTUgQXV0aDAsIEluYy4gPHN1cHBvcnRAYXV0aDAuY29tPiAoaHR0cDovL2F1dGgwLmNvbSlcclxuICpcclxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxyXG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXHJcbiAqIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcclxuICogdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxyXG4gKiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcclxuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcclxuICpcclxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsXHJcbiAqIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXHJcbiAqXHJcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcclxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXHJcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxyXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXHJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXHJcbiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFXHJcbiAqIFNPRlRXQVJFLlxyXG4gKi9cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgSnd0RGVjb2RlT3B0aW9ucyB7XHJcbiAgICBoZWFkZXI/OiBib29sZWFuO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEp3dEhlYWRlciB7XHJcbiAgICB0eXA/OiBzdHJpbmc7XHJcbiAgICBhbGc/OiBzdHJpbmc7XHJcbiAgICBraWQ/OiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgSnd0UGF5bG9hZCB7XHJcbiAgICBpc3M/OiBzdHJpbmc7XHJcbiAgICBzdWI/OiBzdHJpbmc7XHJcbiAgICBhdWQ/OiBzdHJpbmdbXSB8IHN0cmluZztcclxuICAgIGV4cD86IG51bWJlcjtcclxuICAgIG5iZj86IG51bWJlcjtcclxuICAgIGlhdD86IG51bWJlcjtcclxuICAgIGp0aT86IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIEludmFsaWRUb2tlbkVycm9yIGV4dGVuZHMgRXJyb3Ige31cclxuXHJcbkludmFsaWRUb2tlbkVycm9yLnByb3RvdHlwZS5uYW1lID0gXCJJbnZhbGlkVG9rZW5FcnJvclwiO1xyXG5cclxuZnVuY3Rpb24gYjY0RGVjb2RlVW5pY29kZShzdHI6IHN0cmluZykge1xyXG4gICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChcclxuICAgICAgICBhdG9iKHN0cikucmVwbGFjZSgvKC4pL2csIChtLCBwKSA9PiB7XHJcbiAgICAgICAgICAgIGxldCBjb2RlID0gKHAgYXMgc3RyaW5nKS5jaGFyQ29kZUF0KDApLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xyXG4gICAgICAgICAgICBpZiAoY29kZS5sZW5ndGggPCAyKSB7XHJcbiAgICAgICAgICAgICAgICBjb2RlID0gXCIwXCIgKyBjb2RlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBcIiVcIiArIGNvZGU7XHJcbiAgICAgICAgfSksXHJcbiAgICApO1xyXG59XHJcblxyXG5mdW5jdGlvbiBiYXNlNjRVcmxEZWNvZGUoc3RyOiBzdHJpbmcpIHtcclxuICAgIGxldCBvdXRwdXQgPSBzdHIucmVwbGFjZSgvLS9nLCBcIitcIikucmVwbGFjZSgvXy9nLCBcIi9cIik7XHJcbiAgICBzd2l0Y2ggKG91dHB1dC5sZW5ndGggJSA0KSB7XHJcbiAgICAgICAgY2FzZSAwOlxyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgIG91dHB1dCArPSBcIj09XCI7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIGNhc2UgMzpcclxuICAgICAgICAgICAgb3V0cHV0ICs9IFwiPVwiO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJiYXNlNjQgc3RyaW5nIGlzIG5vdCBvZiB0aGUgY29ycmVjdCBsZW5ndGhcIik7XHJcbiAgICB9XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgICByZXR1cm4gYjY0RGVjb2RlVW5pY29kZShvdXRwdXQpO1xyXG4gICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgcmV0dXJuIGF0b2Iob3V0cHV0KTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGp3dERlY29kZTxUID0gSnd0SGVhZGVyPihcclxuICAgIHRva2VuOiBzdHJpbmcsXHJcbiAgICBvcHRpb25zOiBKd3REZWNvZGVPcHRpb25zICYgeyBoZWFkZXI6IHRydWUgfSxcclxuKTogVDtcclxuZXhwb3J0IGZ1bmN0aW9uIGp3dERlY29kZTxUID0gSnd0UGF5bG9hZD4odG9rZW46IHN0cmluZywgb3B0aW9ucz86IEp3dERlY29kZU9wdGlvbnMpOiBUO1xyXG5leHBvcnQgZnVuY3Rpb24gand0RGVjb2RlPFQgPSBKd3RIZWFkZXIgfCBKd3RQYXlsb2FkPihcclxuICAgIHRva2VuOiBzdHJpbmcsXHJcbiAgICBvcHRpb25zPzogSnd0RGVjb2RlT3B0aW9ucyxcclxuKTogVCB7XHJcbiAgICBpZiAodHlwZW9mIHRva2VuICE9PSBcInN0cmluZ1wiKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRUb2tlbkVycm9yKFwiSW52YWxpZCB0b2tlbiBzcGVjaWZpZWQ6IG11c3QgYmUgYSBzdHJpbmdcIik7XHJcbiAgICB9XHJcblxyXG4gICAgb3B0aW9ucyB8fD0ge307XHJcblxyXG4gICAgY29uc3QgcG9zID0gb3B0aW9ucy5oZWFkZXIgPT09IHRydWUgPyAwIDogMTtcclxuICAgIGNvbnN0IHBhcnQgPSB0b2tlbi5zcGxpdChcIi5cIilbcG9zXTtcclxuXHJcbiAgICBpZiAodHlwZW9mIHBhcnQgIT09IFwic3RyaW5nXCIpIHtcclxuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFRva2VuRXJyb3IoYEludmFsaWQgdG9rZW4gc3BlY2lmaWVkOiBtaXNzaW5nIHBhcnQgIyR7cG9zICsgMX1gKTtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgZGVjb2RlZDogc3RyaW5nO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICBkZWNvZGVkID0gYmFzZTY0VXJsRGVjb2RlKHBhcnQpO1xyXG4gICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkVG9rZW5FcnJvcihcclxuICAgICAgICAgICAgYEludmFsaWQgdG9rZW4gc3BlY2lmaWVkOiBpbnZhbGlkIGJhc2U2NCBmb3IgcGFydCAjJHtwb3MgKyAxfSAoJHsoZSBhcyBFcnJvcikubWVzc2FnZX0pYCxcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoZGVjb2RlZCkgYXMgVDtcclxuICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFRva2VuRXJyb3IoXHJcbiAgICAgICAgICAgIGBJbnZhbGlkIHRva2VuIHNwZWNpZmllZDogaW52YWxpZCBqc29uIGZvciBwYXJ0ICMke3BvcyArIDF9ICgkeyhlIGFzIEVycm9yKS5tZXNzYWdlfSlgLFxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcbn1cclxuIiwiZXhwb3J0IGludGVyZmFjZSBTdG9yYWdlTGlrZSB7XHJcbiAgZ2V0SXRlbShrZXk6IHN0cmluZyk6IHN0cmluZyB8IG51bGxcclxuICBzZXRJdGVtKGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKTogdm9pZFxyXG4gIHJlbW92ZUl0ZW0oa2V5OiBzdHJpbmcpOiB2b2lkXHJcbn1cclxuXHJcbmNsYXNzIE1lbW9yeVN0b3JhZ2UgaW1wbGVtZW50cyBTdG9yYWdlTGlrZSB7XHJcbiAgcHJpdmF0ZSBzdG9yZSA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KClcclxuXHJcbiAgZ2V0SXRlbShrZXk6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgcmV0dXJuIHRoaXMuc3RvcmUuaGFzKGtleSkgPyB0aGlzLnN0b3JlLmdldChrZXkpISA6IG51bGxcclxuICB9XHJcblxyXG4gIHNldEl0ZW0oa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIHRoaXMuc3RvcmUuc2V0KGtleSwgU3RyaW5nKHZhbHVlKSlcclxuICB9XHJcblxyXG4gIHJlbW92ZUl0ZW0oa2V5OiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIHRoaXMuc3RvcmUuZGVsZXRlKGtleSlcclxuICB9XHJcbn1cclxuXHJcbmxldCBjYWNoZWQ6IFN0b3JhZ2VMaWtlIHwgbnVsbCA9IG51bGxcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRTdG9yYWdlKCk6IFN0b3JhZ2VMaWtlIHtcclxuICBpZiAoY2FjaGVkKSByZXR1cm4gY2FjaGVkXHJcbiAgdHJ5IHtcclxuICAgIGNvbnN0IGc6IGFueSA9IHR5cGVvZiBnbG9iYWxUaGlzICE9PSAndW5kZWZpbmVkJyA/IChnbG9iYWxUaGlzIGFzIGFueSkgOiAod2luZG93IGFzIGFueSlcclxuICAgIGlmIChnICYmIGcubG9jYWxTdG9yYWdlICYmIHR5cGVvZiBnLmxvY2FsU3RvcmFnZS5nZXRJdGVtID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIGNhY2hlZCA9IGcubG9jYWxTdG9yYWdlIGFzIFN0b3JhZ2VMaWtlXHJcbiAgICAgIHJldHVybiBjYWNoZWRcclxuICAgIH1cclxuICB9IGNhdGNoIChlKSB7XHJcbiAgICAvLyBpZ25vcmUgYW5kIGZhbGwgYmFjayB0byBtZW1vcnkgc3RvcmFnZVxyXG4gIH1cclxuICBjb25zdCBnOiBhbnkgPSB0eXBlb2YgZ2xvYmFsVGhpcyAhPT0gJ3VuZGVmaW5lZCcgPyAoZ2xvYmFsVGhpcyBhcyBhbnkpIDoge31cclxuICBpZiAoIWcuX19nYzJfbWVtb3J5X3N0b3JhZ2UpIHtcclxuICAgIGcuX19nYzJfbWVtb3J5X3N0b3JhZ2UgPSBuZXcgTWVtb3J5U3RvcmFnZSgpXHJcbiAgfVxyXG4gIGNhY2hlZCA9IGcuX19nYzJfbWVtb3J5X3N0b3JhZ2UgYXMgU3RvcmFnZUxpa2VcclxuICByZXR1cm4gY2FjaGVkXHJcbn1cclxuIiwiaW1wb3J0IHtqd3REZWNvZGV9IGZyb20gJy4vand0LWRlY29kZSdcclxuaW1wb3J0IHtHYzJTZXJ2aWNlfSBmcm9tIFwiLi4vc2VydmljZXMvZ2MyLnNlcnZpY2VzXCI7XHJcbmltcG9ydCB7Z2V0U3RvcmFnZX0gZnJvbSAnLi9zdG9yYWdlJ1xyXG5cclxuZXhwb3J0IHR5cGUgVG9rZW5zID0ge1xyXG4gICAgYWNjZXNzVG9rZW46IHN0cmluZztcclxuICAgIHJlZnJlc2hUb2tlbjogc3RyaW5nO1xyXG4gICAgaWRUb2tlbj86IHN0cmluZztcclxufTtcclxuXHJcbmV4cG9ydCB0eXBlIE9wdGlvbnMgPSB7XHJcbiAgICBob3N0OiBzdHJpbmc7XHJcbiAgICB3c0hvc3Q/OiBzdHJpbmc7XHJcbiAgICB0b2tlblVyaT86IHN0cmluZztcclxuICAgIGF1dGhVcmk/OiBzdHJpbmc7XHJcbiAgICBsb2dvdXRVcmk/OiBzdHJpbmc7XHJcbiAgICBkZXZpY2VVcmk/OiBzdHJpbmc7XHJcbiAgICBzY29wZT86IHN0cmluZztcclxuICAgIGNsaWVudElkOiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCB0eXBlIENvZGVGbG93T3B0aW9ucyA9IE9wdGlvbnMgJiB7XHJcbiAgICByZWRpcmVjdFVyaTogc3RyaW5nO1xyXG59XHJcblxyXG5leHBvcnQgdHlwZSBQYXNzd29yZEZsb3dPcHRpb25zID0gT3B0aW9ucyAmIHtcclxuICAgIHVzZXJuYW1lOiBzdHJpbmc7XHJcbiAgICBwYXNzd29yZDogc3RyaW5nO1xyXG4gICAgZGF0YWJhc2U6IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IHR5cGUgV3NPcHRpb25zID0ge1xyXG4gICAgaG9zdDogc3RyaW5nO1xyXG4gICAgY2FsbEJhY2s/OiBhbnk7XHJcbn1cclxuXHJcbmV4cG9ydCB0eXBlIEdldERldmljZUNvZGVSZXNwb25zZSA9IHtcclxuICAgIGRldmljZV9jb2RlOiBzdHJpbmc7XHJcbiAgICB1c2VyX2NvZGU6IHN0cmluZztcclxuICAgIHZlcmlmaWNhdGlvbl91cmk6IHN0cmluZztcclxuICAgIHZlcmlmaWNhdGlvbl91cmlfY29tcGxldGU/OiBzdHJpbmc7XHJcbiAgICBleHBpcmVzX2luOiBudW1iZXI7XHJcbiAgICBpbnRlcnZhbDogbnVtYmVyO1xyXG59O1xyXG5cclxuZXhwb3J0IHR5cGUgR2V0VG9rZW5SZXNwb25zZSA9IHtcclxuICAgIGFjY2Vzc190b2tlbjogc3RyaW5nO1xyXG4gICAgZXhwaXJlc19pbjogbnVtYmVyO1xyXG4gICAgcmVmcmVzaF9leHBpcmVzX2luOiBudW1iZXI7XHJcbiAgICByZWZyZXNoX3Rva2VuOiBzdHJpbmc7XHJcbiAgICBpZF90b2tlbj86IHN0cmluZztcclxuICAgIHRva2VuX3R5cGU6IHN0cmluZztcclxuICAgICdub3QtYmVmb3JlLXBvbGljeSc6IG51bWJlcjtcclxuICAgIHNlc3Npb25fc3RhdGU6IHN0cmluZztcclxuICAgIHNjb3BlOiBzdHJpbmc7XHJcbn07XHJcblxyXG5cclxuZXhwb3J0IGNvbnN0IGdlbmVyYXRlUGtjZUNoYWxsZW5nZSA9IGFzeW5jICgpID0+IHtcclxuXHJcbiAgICBjb25zdCBnZW5lcmF0ZVJhbmRvbVN0cmluZyA9ICgpID0+IHtcclxuICAgICAgICBjb25zdCBhcnJheSA9IG5ldyBVaW50MzJBcnJheSgyOCk7XHJcbiAgICAgICAgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhhcnJheSk7XHJcbiAgICAgICAgcmV0dXJuIEFycmF5LmZyb20oYXJyYXksIGRlYyA9PiAoJzAnICsgZGVjLnRvU3RyaW5nKDE2KSkuc3Vic3RyKC0yKSkuam9pbignJyk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3Qgc2hhMjU2ID0gKHBsYWluOiBzdHJpbmcgfCB1bmRlZmluZWQpID0+IHtcclxuICAgICAgICBjb25zdCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7XHJcbiAgICAgICAgY29uc3QgZGF0YSA9IGVuY29kZXIuZW5jb2RlKHBsYWluKTtcclxuICAgICAgICByZXR1cm4gY3J5cHRvLnN1YnRsZS5kaWdlc3QoJ1NIQS0yNTYnLCBkYXRhKTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBiYXNlNjR1cmxFbmNvZGUgPSAoc3RyOiBBcnJheUJ1ZmZlcikgPT4ge1xyXG5cclxuICAgICAgICByZXR1cm4gYnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIFsuLi5uZXcgVWludDhBcnJheShzdHIpXSkpXHJcbiAgICAgICAgICAgIC5yZXBsYWNlKC9cXCsvZywgJy0nKS5yZXBsYWNlKC9cXC8vZywgJ18nKS5yZXBsYWNlKC89KyQvLCAnJyk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgZnVuY3Rpb24gcGtjZUNoYWxsZW5nZUZyb21WZXJpZmllcih2OiBzdHJpbmcgfCB1bmRlZmluZWQpIHtcclxuICAgICAgICBjb25zdCBoYXNoZWQgPSBhd2FpdCBzaGEyNTYodik7XHJcbiAgICAgICAgcmV0dXJuIGJhc2U2NHVybEVuY29kZShoYXNoZWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHtzdGF0ZSwgY29kZVZlcmlmaWVyfSA9IHtcclxuICAgICAgICBzdGF0ZTogZ2VuZXJhdGVSYW5kb21TdHJpbmcoKSxcclxuICAgICAgICBjb2RlVmVyaWZpZXI6IGdlbmVyYXRlUmFuZG9tU3RyaW5nKCksXHJcbiAgICB9O1xyXG4gICAgY29uc3QgY29kZUNoYWxsZW5nZSA9IGF3YWl0IHBrY2VDaGFsbGVuZ2VGcm9tVmVyaWZpZXIoY29kZVZlcmlmaWVyKTtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIHN0YXRlLFxyXG4gICAgICAgIGNvZGVWZXJpZmllcixcclxuICAgICAgICBjb2RlQ2hhbGxlbmdlLFxyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgaXNUb2tlbkV4cGlyZWQgPSAodG9rZW46IHN0cmluZyk6IGJvb2xlYW4gPT4ge1xyXG4gICAgbGV0IGlzSnd0RXhwaXJlZCA9IGZhbHNlXHJcbiAgICBjb25zdCB7ZXhwfSA9IGp3dERlY29kZSh0b2tlbilcclxuICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwXHJcblxyXG4gICAgaWYgKGV4cCkge1xyXG4gICAgICAgIGlmIChjdXJyZW50VGltZSA+IGV4cCkgaXNKd3RFeHBpcmVkID0gdHJ1ZVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGlzSnd0RXhwaXJlZFxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgY2xhaW1zID0gKHRva2VuOiBzdHJpbmcpOiBhbnkgPT4ge1xyXG4gICAgcmV0dXJuIGp3dERlY29kZSh0b2tlbilcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IHBhc3N3b3JkSXNTdHJvbmdFbm91Z2ggPSAocGFzc3dvcmQ6IHN0cmluZywgYWxsb3dOdWxsOiBib29sZWFuID0gZmFsc2UpID0+IHtcclxuICAgIGNvbnN0IG1lc3NhZ2UgPSAnRW50ZXJlZCBwYXNzd29yZCBpcyB0b28gd2VhaydcclxuICAgIGlmIChwYXNzd29yZCA9PT0gJycgJiYgYWxsb3dOdWxsKSByZXR1cm4gdHJ1ZVxyXG4gICAgaWYgKHBhc3N3b3JkLmxlbmd0aCA8IDgpIHJldHVybiBtZXNzYWdlXHJcbiAgICBpZiAoISgvW0EtWl0vLnRlc3QocGFzc3dvcmQpKSkgcmV0dXJuIG1lc3NhZ2VcclxuICAgIGlmICghKC9bYS16XS8udGVzdChwYXNzd29yZCkpKSByZXR1cm4gbWVzc2FnZVxyXG4gICAgaWYgKCEoL1xcZC8udGVzdChwYXNzd29yZCkpKSByZXR1cm4gbWVzc2FnZVxyXG4gICAgcmV0dXJuIHRydWVcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IGlzTG9naW4gPSBhc3luYyAoZ2MyOiBHYzJTZXJ2aWNlKTogUHJvbWlzZTxib29sZWFuPiA9PiB7XHJcbiAgICBjb25zdCB7YWNjZXNzVG9rZW4sIHJlZnJlc2hUb2tlbn0gPSBnZXRUb2tlbnMoKVxyXG4gICAgaWYgKCFhY2Nlc3NUb2tlbiAmJiAhcmVmcmVzaFRva2VuKSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlXHJcbiAgICB9XHJcbiAgICBpZiAoIWFjY2Vzc1Rva2VuIHx8IChhY2Nlc3NUb2tlbiAmJiBpc1Rva2VuRXhwaXJlZChhY2Nlc3NUb2tlbikpKSB7XHJcbiAgICAgICAgaWYgKHJlZnJlc2hUb2tlbiAmJiBpc1Rva2VuRXhwaXJlZChyZWZyZXNoVG9rZW4pKSB7XHJcbiAgICAgICAgICAgIGNsZWFyVG9rZW5zKClcclxuICAgICAgICAgICAgY2xlYXJPcHRpb25zKClcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZWZyZXNoIHRva2VuIGhhcyBleHBpcmVkLiBQbGVhc2UgbG9naW4gYWdhaW4uJylcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHJlZnJlc2hUb2tlbikge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IGdjMi5nZXRSZWZyZXNoVG9rZW4ocmVmcmVzaFRva2VuKVxyXG4gICAgICAgICAgICAgICAgc2V0VG9rZW5zKHthY2Nlc3NUb2tlbjogZGF0YS5hY2Nlc3NfdG9rZW4sIHJlZnJlc2hUb2tlbiwgaWRUb2tlbjogZGF0YT8uaWRfdG9rZW59KVxyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ0FjY2VzcyB0b2tlbiByZWZyZXNoZWQnKVxyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBnZXQgcmVmcmVzaCB0b2tlbi4nKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRydWVcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IHNldFRva2VucyA9ICh0b2tlbnM6IFRva2Vucyk6IHZvaWQgPT4ge1xyXG4gICAgZ2V0U3RvcmFnZSgpLnNldEl0ZW0oJ2djMl90b2tlbnMnLCBKU09OLnN0cmluZ2lmeSh7XHJcbiAgICAgICAgICAgICAgICAnYWNjZXNzVG9rZW4nOiB0b2tlbnMuYWNjZXNzVG9rZW4sXHJcbiAgICAgICAgICAgICAgICAncmVmcmVzaFRva2VuJzogdG9rZW5zLnJlZnJlc2hUb2tlbixcclxuICAgICAgICAgICAgICAgICdpZFRva2VuJzogdG9rZW5zPy5pZFRva2VuIHx8ICcnXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICApXHJcbiAgICApXHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBnZXRUb2tlbnMgPSAoKTogVG9rZW5zID0+IHtcclxuICAgIGNvbnN0IHN0cjogc3RyaW5nIHwgbnVsbCA9IGdldFN0b3JhZ2UoKS5nZXRJdGVtKCdnYzJfdG9rZW5zJylcclxuICAgIGNvbnN0IHRva2VuczogYW55ID0gc3RyID8gSlNPTi5wYXJzZShzdHIpIDoge31cclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgYWNjZXNzVG9rZW46IHRva2Vucz8uYWNjZXNzVG9rZW4gfHwgJycsXHJcbiAgICAgICAgcmVmcmVzaFRva2VuOiB0b2tlbnM/LnJlZnJlc2hUb2tlbiB8fCAnJyxcclxuICAgICAgICBpZFRva2VuOiB0b2tlbnM/LmlkVG9rZW4gfHwgJycsXHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBzZXRPcHRpb25zID0gKG9wdGlvbnM6IENvZGVGbG93T3B0aW9ucyk6IHZvaWQgPT4ge1xyXG4gICAgZ2V0U3RvcmFnZSgpLnNldEl0ZW0oJ2djMl9vcHRpb25zJywgSlNPTi5zdHJpbmdpZnkoe1xyXG4gICAgICAgICAgICAgICAgJ2NsaWVudElkJzogb3B0aW9ucy5jbGllbnRJZCxcclxuICAgICAgICAgICAgICAgICdob3N0Jzogb3B0aW9ucy5ob3N0LFxyXG4gICAgICAgICAgICAgICAgJ3JlZGlyZWN0VXJpJzogb3B0aW9ucy5yZWRpcmVjdFVyaVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgKVxyXG4gICAgKVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgZ2V0T3B0aW9ucyA9ICgpOiBDb2RlRmxvd09wdGlvbnMgPT4ge1xyXG4gICAgY29uc3Qgc3RyOiBzdHJpbmcgfCBudWxsID0gZ2V0U3RvcmFnZSgpLmdldEl0ZW0oJ2djMl9vcHRpb25zJylcclxuICAgIGNvbnN0IG9wdGlvbnM6IGFueSA9IHN0ciA/IEpTT04ucGFyc2Uoc3RyKSA6IHt9XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGNsaWVudElkOiBvcHRpb25zPy5jbGllbnRJZCB8fCAnJyxcclxuICAgICAgICBob3N0OiBvcHRpb25zPy5ob3N0IHx8ICcnLFxyXG4gICAgICAgIHJlZGlyZWN0VXJpOiBvcHRpb25zPy5yZWRpcmVjdFVyaSB8fCAnJyxcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IGJhc2U2NFVybEVuY29kZVN0cmluZyA9IChzdHI6IHN0cmluZyk6IHN0cmluZyA9PiB7XHJcbiAgICByZXR1cm4gYnRvYShuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoc3RyKS5yZWR1Y2UoKGFjYywgYnl0ZSkgPT4gYWNjICsgU3RyaW5nLmZyb21DaGFyQ29kZShieXRlKSwgJycpKVxyXG4gICAgICAgIC5yZXBsYWNlKC9cXCsvZywgJy0nKVxyXG4gICAgICAgIC5yZXBsYWNlKC9cXC8vZywgJ18nKVxyXG4gICAgICAgIC5yZXBsYWNlKC89KyQvLCAnJyk7XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBjbGVhclRva2VucyA9ICgpOiB2b2lkID0+IHtcclxuICAgIGdldFN0b3JhZ2UoKS5yZW1vdmVJdGVtKCdnYzJfdG9rZW5zJylcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IGNsZWFyT3B0aW9ucyA9ICgpOiB2b2lkID0+IHtcclxuICAgIGdldFN0b3JhZ2UoKS5yZW1vdmVJdGVtKCdnYzJfb3B0aW9ucycpXHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBnZXROb25jZSA9ICgpOiBzdHJpbmd8bnVsbCA9PiB7XHJcbiAgICByZXR1cm4gPHN0cmluZz5nZXRTdG9yYWdlKCkuZ2V0SXRlbSgnZ2MyX25vbmNlJylcclxufVxyXG5leHBvcnQgY29uc3QgY2xlYXJOb25jZSA9ICgpOiB2b2lkID0+IHtcclxuICAgIGdldFN0b3JhZ2UoKS5yZW1vdmVJdGVtKCdnYzJfbm9uY2UnKVxyXG59XHJcblxyXG4iLCJpbXBvcnQge0NvZGVGbG93T3B0aW9ucywgR2V0RGV2aWNlQ29kZVJlc3BvbnNlLCBnZXROb25jZSwgR2V0VG9rZW5SZXNwb25zZSwgUGFzc3dvcmRGbG93T3B0aW9uc30gZnJvbSAnLi4vdXRpbC91dGlscyc7XHJcblxyXG5leHBvcnQgY2xhc3MgR2MyU2VydmljZSB7XHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM6IENvZGVGbG93T3B0aW9ucyB8IFBhc3N3b3JkRmxvd09wdGlvbnM7XHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IGhvc3Q6IHN0cmluZztcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zOiBDb2RlRmxvd09wdGlvbnMgfCBQYXNzd29yZEZsb3dPcHRpb25zKSB7XHJcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcclxuICAgICAgICB0aGlzLmhvc3QgPSBvcHRpb25zLmhvc3Q7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVHlwZSBndWFyZHMgdG8gY2hlY2sgaWYgb3B0aW9ucyBpcyBDb2RlRmxvd09wdGlvbnMgb3IgUGFzc3dvcmRGbG93T3B0aW9uc1xyXG4gICAgcHJpdmF0ZSBpc0NvZGVGbG93T3B0aW9ucyhvcHRpb25zOiBDb2RlRmxvd09wdGlvbnMgfCBQYXNzd29yZEZsb3dPcHRpb25zKTogb3B0aW9ucyBpcyBDb2RlRmxvd09wdGlvbnMge1xyXG4gICAgICAgIHJldHVybiAncmVkaXJlY3RVcmknIGluIG9wdGlvbnM7XHJcbiAgICB9XHJcbiAgICBwcml2YXRlIGlzUGFzc3dvcmRGbG93T3B0aW9ucyhvcHRpb25zOiBDb2RlRmxvd09wdGlvbnMgfCBQYXNzd29yZEZsb3dPcHRpb25zKTogb3B0aW9ucyBpcyBQYXNzd29yZEZsb3dPcHRpb25zIHtcclxuICAgICAgICByZXR1cm4gJ3VzZXJuYW1lJyBpbiBvcHRpb25zO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYnVpbGRVcmwocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICBpZiAocGF0aC5zdGFydHNXaXRoKCdodHRwOi8vJykgfHwgcGF0aC5zdGFydHNXaXRoKCdodHRwczovLycpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBwYXRoO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYCR7dGhpcy5ob3N0fSR7cGF0aH1gO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYXN5bmMgcmVxdWVzdChcclxuICAgICAgICB1cmw6IHN0cmluZyxcclxuICAgICAgICBtZXRob2Q6ICdHRVQnIHwgJ1BPU1QnLFxyXG4gICAgICAgIGJvZHk/OiBhbnksXHJcbiAgICAgICAgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJyB8ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnID0gJ2FwcGxpY2F0aW9uL2pzb24nXHJcbiAgICApOiBQcm9taXNlPGFueT4ge1xyXG4gICAgICAgIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7J0NvbnRlbnQtVHlwZSc6IGNvbnRlbnRUeXBlfTtcclxuICAgICAgICBsZXQgcGF5bG9hZDogc3RyaW5nO1xyXG5cclxuICAgICAgICBpZiAoY29udGVudFR5cGUgPT09ICdhcHBsaWNhdGlvbi9qc29uJykge1xyXG4gICAgICAgICAgICBwYXlsb2FkID0gSlNPTi5zdHJpbmdpZnkoYm9keSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcGF5bG9hZCA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoYm9keSkudG9TdHJpbmcoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsLCB7XHJcbiAgICAgICAgICAgIG1ldGhvZCxcclxuICAgICAgICAgICAgaGVhZGVycyxcclxuICAgICAgICAgICAgYm9keTogcGF5bG9hZCxcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xyXG4gICAgICAgICAgICBjb25zdCBlcnJUZXh0ID0gYXdhaXQgcmVzcG9uc2UudGV4dCgpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEhUVFAgZXJyb3IgJHtyZXNwb25zZS5zdGF0dXN9OiAke2VyclRleHR9YCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGdldERldmljZUNvZGUoKTogUHJvbWlzZTxHZXREZXZpY2VDb2RlUmVzcG9uc2U+IHtcclxuICAgICAgICBjb25zdCBwYXRoID0gdGhpcy5vcHRpb25zLmRldmljZVVyaSA/PyBgJHt0aGlzLmhvc3R9L2FwaS92NC9vYXV0aC9kZXZpY2VgO1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QodGhpcy5idWlsZFVybChwYXRoKSwgJ1BPU1QnLCB7XHJcbiAgICAgICAgICAgIGNsaWVudF9pZDogdGhpcy5vcHRpb25zLmNsaWVudElkLFxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHBvbGxUb2tlbihkZXZpY2VDb2RlOiBzdHJpbmcsIGludGVydmFsOiBudW1iZXIpOiBQcm9taXNlPEdldFRva2VuUmVzcG9uc2U+IHtcclxuICAgICAgICBjb25zdCBwYXRoID0gdGhpcy5vcHRpb25zLnRva2VuVXJpID8/IGAke3RoaXMuaG9zdH0vYXBpL3Y0L29hdXRoYDtcclxuICAgICAgICBjb25zdCBnZXRUb2tlbiA9IGFzeW5jICgpOiBQcm9taXNlPEdldFRva2VuUmVzcG9uc2UgfCBudWxsIHwgc3RyaW5nPiA9PiB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5yZXF1ZXN0KFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYnVpbGRVcmwocGF0aCksXHJcbiAgICAgICAgICAgICAgICAgICAgJ1BPU1QnLFxyXG4gICAgICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50X2lkOiB0aGlzLm9wdGlvbnMuY2xpZW50SWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZV9jb2RlOiBkZXZpY2VDb2RlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBncmFudF90eXBlOiAnZGV2aWNlX2NvZGUnLFxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZXJyID0gSlNPTi5wYXJzZShlLm1lc3NhZ2Uuc3BsaXQoJzogJylbMV0pO1xyXG4gICAgICAgICAgICAgICAgaWYgKGVyci5lcnJvciA9PT0gJ2F1dGhvcml6YXRpb25fcGVuZGluZycpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiBlcnIuZXJyb3JfZGVzY3JpcHRpb247XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBsZXQgcmVzcG9uc2UgPSBhd2FpdCBnZXRUb2tlbigpO1xyXG4gICAgICAgIHdoaWxlIChyZXNwb25zZSA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgaW50ZXJ2YWwgKiAxMTAwKSk7XHJcbiAgICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgZ2V0VG9rZW4oKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0eXBlb2YgcmVzcG9uc2UgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihyZXNwb25zZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0QXV0aG9yaXphdGlvbkNvZGVVUkwoY29kZUNoYWxsZW5nZTogc3RyaW5nLCBzdGF0ZTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICBsZXQgcmVkaXJlY3RVcmk6IHN0cmluZ1xyXG4gICAgICAgIGlmICh0aGlzLmlzQ29kZUZsb3dPcHRpb25zKHRoaXMub3B0aW9ucykpIHtcclxuICAgICAgICAgICAgIHJlZGlyZWN0VXJpID0gdGhpcy5vcHRpb25zLnJlZGlyZWN0VXJpXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb2RlRmxvdyBvcHRpb25zIHJlcXVpcmVkIGZvciB0aGlzIG9wZXJhdGlvbicpXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGJhc2UgPSB0aGlzLm9wdGlvbnMuYXV0aFVyaSA/PyBgJHt0aGlzLmhvc3R9L2F1dGgvYFxyXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoKVxyXG4gICAgICAgIC8vIEdldCBub25jZSBmcm9tIGxvY2FsIHN0b3JhZ2UgaWYgaXQgZXhpc3RzXHJcbiAgICAgICAgY29uc3Qgbm9uY2UgPSBnZXROb25jZSgpXHJcbiAgICAgICAgLy8gQWRkIHBhcmFtZXRlcnMgY29uZGl0aW9uYWxseVxyXG4gICAgICAgIHBhcmFtcy5zZXQoJ3Jlc3BvbnNlX3R5cGUnLCAnY29kZScpO1xyXG4gICAgICAgIHBhcmFtcy5zZXQoJ2NsaWVudF9pZCcsIHRoaXMub3B0aW9ucy5jbGllbnRJZCk7XHJcbiAgICAgICAgcGFyYW1zLnNldCgncmVkaXJlY3RfdXJpJywgcmVkaXJlY3RVcmkpO1xyXG4gICAgICAgIHBhcmFtcy5zZXQoJ3N0YXRlJywgc3RhdGUpO1xyXG4gICAgICAgIHBhcmFtcy5zZXQoJ2NvZGVfY2hhbGxlbmdlJywgY29kZUNoYWxsZW5nZSk7XHJcbiAgICAgICAgcGFyYW1zLnNldCgnY29kZV9jaGFsbGVuZ2VfbWV0aG9kJywgJ1MyNTYnKTtcclxuICAgICAgICBpZiAobm9uY2UpIHtcclxuICAgICAgICAgICAgcGFyYW1zLnNldCgnbm9uY2UnLCBub25jZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIE9ubHkgYWRkIHNjb3BlIGlmIGl0J3MgZGVmaW5lZFxyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2NvcGUpIHtcclxuICAgICAgICAgICAgcGFyYW1zLnNldCgnc2NvcGUnLCB0aGlzLm9wdGlvbnMuc2NvcGUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYCR7YmFzZX0/JHtwYXJhbXMudG9TdHJpbmcoKX1gO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGdldEF1dGhvcml6YXRpb25Db2RlVG9rZW4oXHJcbiAgICAgICAgY29kZTogc3RyaW5nIHwgc3RyaW5nW10sXHJcbiAgICAgICAgY29kZVZlcmlmaWVyOiBzdHJpbmcgfCBudWxsXHJcbiAgICApOiBQcm9taXNlPEdldFRva2VuUmVzcG9uc2U+IHtcclxuICAgICAgICBsZXQgcmVkaXJlY3RVcmk6IHN0cmluZ1xyXG4gICAgICAgIGlmICh0aGlzLmlzQ29kZUZsb3dPcHRpb25zKHRoaXMub3B0aW9ucykpIHtcclxuICAgICAgICAgICAgcmVkaXJlY3RVcmkgPSB0aGlzLm9wdGlvbnMucmVkaXJlY3RVcmlcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvZGVGbG93IG9wdGlvbnMgcmVxdWlyZWQgZm9yIHRoaXMgb3BlcmF0aW9uJylcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgcGF0aCA9IHRoaXMub3B0aW9ucy50b2tlblVyaSA/PyBgJHt0aGlzLmhvc3R9L2FwaS92NC9vYXV0aGA7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdChcclxuICAgICAgICAgICAgdGhpcy5idWlsZFVybChwYXRoKSxcclxuICAgICAgICAgICAgJ1BPU1QnLFxyXG4gICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICBjbGllbnRfaWQ6IHRoaXMub3B0aW9ucy5jbGllbnRJZCxcclxuICAgICAgICAgICAgICAgIHJlZGlyZWN0X3VyaTogcmVkaXJlY3RVcmksXHJcbiAgICAgICAgICAgICAgICBncmFudF90eXBlOiAnYXV0aG9yaXphdGlvbl9jb2RlJyxcclxuICAgICAgICAgICAgICAgIGNvZGUsXHJcbiAgICAgICAgICAgICAgICBjb2RlX3ZlcmlmaWVyOiBjb2RlVmVyaWZpZXIsXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBnZXRQYXNzd29yZFRva2VuKCk6IFByb21pc2U8R2V0VG9rZW5SZXNwb25zZT4ge1xyXG4gICAgICAgIGxldCB1c2VybmFtZSwgcGFzc3dvcmQsIGRhdGFiYXNlXHJcbiAgICAgICAgaWYgKHRoaXMuaXNQYXNzd29yZEZsb3dPcHRpb25zKHRoaXMub3B0aW9ucykpIHtcclxuICAgICAgICAgICAgdXNlcm5hbWUgPSB0aGlzLm9wdGlvbnMudXNlcm5hbWVcclxuICAgICAgICAgICAgcGFzc3dvcmQgPSB0aGlzLm9wdGlvbnMucGFzc3dvcmRcclxuICAgICAgICAgICAgZGF0YWJhc2UgPSB0aGlzLm9wdGlvbnMuZGF0YWJhc2VcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Bhc3N3b3JkRmxvdyBvcHRpb25zIHJlcXVpcmVkIGZvciB0aGlzIG9wZXJhdGlvbicpXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHBhdGggPSBgJHt0aGlzLmhvc3R9L2FwaS92NC9vYXV0aGA7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdChcclxuICAgICAgICAgICAgdGhpcy5idWlsZFVybChwYXRoKSxcclxuICAgICAgICAgICAgJ1BPU1QnLFxyXG4gICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICBjbGllbnRfaWQ6IHRoaXMub3B0aW9ucy5jbGllbnRJZCxcclxuICAgICAgICAgICAgICAgIGdyYW50X3R5cGU6ICdwYXNzd29yZCcsXHJcbiAgICAgICAgICAgICAgICB1c2VybmFtZSxcclxuICAgICAgICAgICAgICAgIHBhc3N3b3JkLFxyXG4gICAgICAgICAgICAgICAgZGF0YWJhc2UsXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGdldFJlZnJlc2hUb2tlbih0b2tlbjogc3RyaW5nKTogUHJvbWlzZTxHZXRUb2tlblJlc3BvbnNlPiB7XHJcbiAgICAgICAgY29uc3QgcGF0aCA9IHRoaXMub3B0aW9ucy50b2tlblVyaSA/PyBgJHt0aGlzLmhvc3R9L2FwaS92NC9vYXV0aGA7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdChcclxuICAgICAgICAgICAgdGhpcy5idWlsZFVybChwYXRoKSxcclxuICAgICAgICAgICAgJ1BPU1QnLFxyXG4gICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICBjbGllbnRfaWQ6IHRoaXMub3B0aW9ucy5jbGllbnRJZCxcclxuICAgICAgICAgICAgICAgIGdyYW50X3R5cGU6ICdyZWZyZXNoX3Rva2VuJyxcclxuICAgICAgICAgICAgICAgIHJlZnJlc2hfdG9rZW46IHRva2VuLFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRTaWduT3V0VVJMKCk6IHN0cmluZyB7XHJcbiAgICAgICAgbGV0IHJlZGlyZWN0VXJpOiBzdHJpbmdcclxuICAgICAgICBpZiAodGhpcy5pc0NvZGVGbG93T3B0aW9ucyh0aGlzLm9wdGlvbnMpKSB7XHJcbiAgICAgICAgICAgIHJlZGlyZWN0VXJpID0gdGhpcy5vcHRpb25zLnJlZGlyZWN0VXJpXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb2RlRmxvdyBvcHRpb25zIHJlcXVpcmVkIGZvciB0aGlzIG9wZXJhdGlvbicpXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoe1xyXG4gICAgICAgICAgICByZWRpcmVjdF91cmk6IHJlZGlyZWN0VXJpLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMubG9nb3V0VXJpID8/IGAke3RoaXMuaG9zdH0vc2lnbm91dD8ke3BhcmFtcy50b1N0cmluZygpfWA7XHJcbiAgICB9XHJcbn1cclxuIiwiaW1wb3J0IHtHYzJTZXJ2aWNlfSBmcm9tICcuL3NlcnZpY2VzL2djMi5zZXJ2aWNlcydcclxuaW1wb3J0IHtnZW5lcmF0ZVBrY2VDaGFsbGVuZ2UsIGlzTG9naW4sIHNldFRva2Vucywgc2V0T3B0aW9ucywgY2xlYXJOb25jZX0gZnJvbSAnLi91dGlsL3V0aWxzJ1xyXG5pbXBvcnQge0NvZGVGbG93T3B0aW9ucywgY2xlYXJUb2tlbnMsIGNsZWFyT3B0aW9uc30gZnJvbSBcIi4vdXRpbC91dGlsc1wiO1xyXG5pbXBvcnQge2dldFN0b3JhZ2V9IGZyb20gJy4vdXRpbC9zdG9yYWdlJ1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ29kZUZsb3cge1xyXG4gICAgb3B0aW9uczogQ29kZUZsb3dPcHRpb25zXHJcbiAgICBzZXJ2aWNlOiBHYzJTZXJ2aWNlXHJcblxyXG4gICAgY29uc3RydWN0b3Iob3B0aW9uczogQ29kZUZsb3dPcHRpb25zKSB7XHJcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9uc1xyXG4gICAgICAgIHRoaXMuc2VydmljZSA9IG5ldyBHYzJTZXJ2aWNlKG9wdGlvbnMpXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIHJlZGlyZWN0SGFuZGxlKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG4gICAgICAgIGNvbnN0IHVybDogc3RyaW5nID0gd2luZG93LmxvY2F0aW9uLnNlYXJjaFxyXG4gICAgICAgIGNvbnN0IHF1ZXJ5UGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh1cmwpXHJcblxyXG4gICAgICAgIGNvbnN0IGVycm9yID0gcXVlcnlQYXJhbXMuZ2V0KCdlcnJvcicpXHJcbiAgICAgICAgaWYgKGVycm9yKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIHJlZGlyZWN0OiAke3VybH1gKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgY29kZSA9IHF1ZXJ5UGFyYW1zLmdldCgnY29kZScpXHJcbiAgICAgICAgaWYgKGNvZGUpIHtcclxuICAgICAgICAgICAgY29uc3Qgc3RhdGUgPSBxdWVyeVBhcmFtcy5nZXQoJ3N0YXRlJylcclxuICAgICAgICAgICAgaWYgKHN0YXRlICE9PSBnZXRTdG9yYWdlKCkuZ2V0SXRlbSgnc3RhdGUnKSkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQb3NzaWJsZSBDU1JGIGF0dGFjay4gQWJvcnRpbmcgbG9naW4hJylcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qge1xyXG4gICAgICAgICAgICAgICAgICAgIGFjY2Vzc190b2tlbixcclxuICAgICAgICAgICAgICAgICAgICByZWZyZXNoX3Rva2VuLFxyXG4gICAgICAgICAgICAgICAgICAgIGlkX3Rva2VuLFxyXG4gICAgICAgICAgICAgICAgfSA9IGF3YWl0IHRoaXMuc2VydmljZS5nZXRBdXRob3JpemF0aW9uQ29kZVRva2VuKGNvZGUsIGdldFN0b3JhZ2UoKS5nZXRJdGVtKCdjb2RlVmVyaWZpZXInKSlcclxuICAgICAgICAgICAgICAgIHNldFRva2Vucyh7YWNjZXNzVG9rZW46IGFjY2Vzc190b2tlbiwgcmVmcmVzaFRva2VuOiByZWZyZXNoX3Rva2VuLCBpZFRva2VuOiBpZF90b2tlbn0pXHJcbiAgICAgICAgICAgICAgICBzZXRPcHRpb25zKHtcclxuICAgICAgICAgICAgICAgICAgICBjbGllbnRJZDogdGhpcy5vcHRpb25zLmNsaWVudElkLFxyXG4gICAgICAgICAgICAgICAgICAgIGhvc3Q6IHRoaXMub3B0aW9ucy5ob3N0LFxyXG4gICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0VXJpOiB0aGlzLm9wdGlvbnMucmVkaXJlY3RVcmlcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICBnZXRTdG9yYWdlKCkucmVtb3ZlSXRlbSgnc3RhdGUnKVxyXG4gICAgICAgICAgICAgICAgZ2V0U3RvcmFnZSgpLnJlbW92ZUl0ZW0oJ2NvZGVWZXJpZmllcicpXHJcblxyXG4gICAgICAgICAgICAgICAgLy8gUmVtb3ZlIHN0YXRlIGFuZCBjb2RlIGZyb20gdGhlIHJlZGlyZWN0IHVybFxyXG4gICAgICAgICAgICAgICAgY29uc3QgcGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoKTtcclxuICAgICAgICAgICAgICAgIHBhcmFtcy5kZWxldGUoJ2NvZGUnKVxyXG4gICAgICAgICAgICAgICAgcGFyYW1zLmRlbGV0ZSgnc3RhdGUnKVxyXG4gICAgICAgICAgICAgICAgY29uc3QgbG9jID0gd2luZG93LmxvY2F0aW9uXHJcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdVcmwgPSBsb2Mub3JpZ2luICsgbG9jLnBhdGhuYW1lICsgKHBhcmFtcy5zaXplID4gMCA/ICc/JyArIHBhcmFtcy50b1N0cmluZygpIDogJycpXHJcbiAgICAgICAgICAgICAgICBoaXN0b3J5LnB1c2hTdGF0ZShudWxsLCAnJywgbmV3VXJsKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRydWUpXHJcblxyXG4gICAgICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlLm1lc3NhZ2UpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IGlzTG9naW4odGhpcy5zZXJ2aWNlKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgc2lnbkluKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGNvbnN0IHtzdGF0ZSwgY29kZVZlcmlmaWVyLCBjb2RlQ2hhbGxlbmdlfSA9IGF3YWl0IGdlbmVyYXRlUGtjZUNoYWxsZW5nZSgpXHJcbiAgICAgICAgZ2V0U3RvcmFnZSgpLnNldEl0ZW0oXCJzdGF0ZVwiLCBzdGF0ZSlcclxuICAgICAgICBnZXRTdG9yYWdlKCkuc2V0SXRlbShcImNvZGVWZXJpZmllclwiLCBjb2RlVmVyaWZpZXIpO1xyXG4gICAgICAgIC8vIEB0cy1pZ25vcmVcclxuICAgICAgICB3aW5kb3cubG9jYXRpb24gPSB0aGlzLnNlcnZpY2UuZ2V0QXV0aG9yaXphdGlvbkNvZGVVUkwoXHJcbiAgICAgICAgICAgIGNvZGVDaGFsbGVuZ2UsXHJcbiAgICAgICAgICAgIHN0YXRlLFxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHNpZ25PdXQoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5jbGVhcigpXHJcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxyXG4gICAgICAgIHdpbmRvdy5sb2NhdGlvbiA9IHRoaXMuc2VydmljZS5nZXRTaWduT3V0VVJMKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGNsZWFyKCk6IHZvaWQge1xyXG4gICAgICAgIGNsZWFyVG9rZW5zKClcclxuICAgICAgICBjbGVhck9wdGlvbnMoKVxyXG4gICAgICAgIGNsZWFyTm9uY2UoKVxyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCB7R2MyU2VydmljZSx9IGZyb20gJy4vc2VydmljZXMvZ2MyLnNlcnZpY2VzJ1xyXG5pbXBvcnQge2lzTG9naW4sIHNldFRva2Vucywgc2V0T3B0aW9ucywgUGFzc3dvcmRGbG93T3B0aW9ucywgY2xlYXJUb2tlbnMsIGNsZWFyT3B0aW9ucywgY2xlYXJOb25jZX0gZnJvbSAnLi91dGlsL3V0aWxzJ1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUGFzc3dvcmRGbG93IHtcclxuICAgIG9wdGlvbnM6IFBhc3N3b3JkRmxvd09wdGlvbnNcclxuICAgIHNlcnZpY2U6IEdjMlNlcnZpY2VcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zOiBQYXNzd29yZEZsb3dPcHRpb25zKSB7XHJcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9uc1xyXG4gICAgICAgIHRoaXMuc2VydmljZSA9IG5ldyBHYzJTZXJ2aWNlKG9wdGlvbnMpXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIHNpZ25JbigpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBjb25zdCB7YWNjZXNzX3Rva2VuLCByZWZyZXNoX3Rva2VufSA9IGF3YWl0IHRoaXMuc2VydmljZS5nZXRQYXNzd29yZFRva2VuKClcclxuICAgICAgICBzZXRUb2tlbnMoe2FjY2Vzc1Rva2VuOiBhY2Nlc3NfdG9rZW4sIHJlZnJlc2hUb2tlbjogcmVmcmVzaF90b2tlbn0pXHJcbiAgICAgICAgc2V0T3B0aW9ucyh7XHJcbiAgICAgICAgICAgIGNsaWVudElkOiB0aGlzLm9wdGlvbnMuY2xpZW50SWQsXHJcbiAgICAgICAgICAgIGhvc3Q6IHRoaXMub3B0aW9ucy5ob3N0LFxyXG4gICAgICAgICAgICByZWRpcmVjdFVyaTogJydcclxuICAgICAgICB9KVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBzaWduT3V0KCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuY2xlYXIoKVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBjbGVhcigpOiB2b2lkIHtcclxuICAgICAgICBjbGVhclRva2VucygpXHJcbiAgICAgICAgY2xlYXJPcHRpb25zKClcclxuICAgICAgICBjbGVhck5vbmNlKClcclxuICAgIH1cclxufVxyXG4iLCIvKipcclxuICogQGF1dGhvciAgICAgTWFydGluIEjDuGdoIDxtaEBtYXBjZW50aWEuY29tPlxyXG4gKiBAY29weXJpZ2h0ICAyMDEzLTIwMjQgTWFwQ2VudGlhIEFwU1xyXG4gKiBAbGljZW5zZSAgICBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvI0FHUEwgIEdOVSBBRkZFUk8gR0VORVJBTCBQVUJMSUMgTElDRU5TRSAzXHJcbiAqXHJcbiAqL1xyXG5cclxuaW1wb3J0IHtnZXRPcHRpb25zLCBnZXRUb2tlbnMsIGlzTG9naW59IGZyb20gXCIuL3V0aWxzXCI7XHJcbmltcG9ydCB7R2MyU2VydmljZX0gZnJvbSBcIi4uL3NlcnZpY2VzL2djMi5zZXJ2aWNlc1wiO1xyXG5cclxuY29uc3QgZ2V0SGVhZGVycyA9IGFzeW5jIChjb250ZW50VHlwZTogc3RyaW5nfG51bGwgPSAnYXBwbGljYXRpb24vanNvbicpOiBQcm9taXNlPGFueT49PiB7XHJcbiAgdHlwZSBoZWFkZXJzID0ge1xyXG4gICAgQWNjZXB0OiBzdHJpbmcsXHJcbiAgICBDb29raWU6IHN0cmluZyxcclxuICAgIEF1dGhvcml6YXRpb246IHN0cmluZ3xudWxsLFxyXG4gICAgJ0NvbnRlbnQtVHlwZSc/OiBzdHJpbmdcclxuICB9XHJcblxyXG4gIGNvbnN0IG9wdGlvbnMgPSBnZXRPcHRpb25zKClcclxuICBjb25zdCBzZXJ2aWNlID0gbmV3IEdjMlNlcnZpY2Uob3B0aW9ucylcclxuXHJcbiAgLy8gV2UgY2hlY2sgaXMgdG9rZW4gbmVlZHMgcmVmcmVzaGluZ1xyXG4gIGlmICghYXdhaXQgaXNMb2dpbihzZXJ2aWNlKSkge1xyXG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdJcyBub3QgbG9nZ2VkIGluJylcclxuICB9XHJcblxyXG4gIGNvbnN0IHthY2Nlc3NUb2tlbn0gPSBnZXRUb2tlbnMoKVxyXG5cclxuICBjb25zdCBoZWFkZXJzOiBoZWFkZXJzID0ge1xyXG4gICAgQWNjZXB0OiAnYXBwbGljYXRpb24vanNvbicsXHJcbiAgICBDb29raWU6ICdYREVCVUdfU0VTU0lPTj1YREVCVUdfRUNMSVBTRScsXHJcbiAgICBBdXRob3JpemF0aW9uOiBhY2Nlc3NUb2tlbiA/ICdCZWFyZXIgJyArIGFjY2Vzc1Rva2VuIDogbnVsbCxcclxuICB9XHJcbiAgaWYgKGNvbnRlbnRUeXBlKSB7XHJcbiAgICBoZWFkZXJzWydDb250ZW50LVR5cGUnXSA9IGNvbnRlbnRUeXBlXHJcbiAgfVxyXG4gIHJldHVybiBoZWFkZXJzXHJcbn1cclxuZXhwb3J0IGRlZmF1bHQgZ2V0SGVhZGVyc1xyXG5cclxuIiwiLyoqXHJcbiAqIEBhdXRob3IgICAgIE1hcnRpbiBIw7hnaCA8bWhAbWFwY2VudGlhLmNvbT5cclxuICogQGNvcHlyaWdodCAgMjAxMy0yMDI0IE1hcENlbnRpYSBBcFNcclxuICogQGxpY2Vuc2UgICAgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLyNBR1BMICBHTlUgQUZGRVJPIEdFTkVSQUwgUFVCTElDIExJQ0VOU0UgM1xyXG4gKlxyXG4gKi9cclxuXHJcbmltcG9ydCBnZXRIZWFkZXJzIGZyb20gJy4vcmVxdWVzdC1oZWFkZXJzJ1xyXG5pbXBvcnQgTWV0aG9kIGZyb20gJy4uL2NvbW1vbi9odHRwLXZlcmJzJ1xyXG5pbXBvcnQge2dldE9wdGlvbnN9IGZyb20gJy4vdXRpbHMnXHJcblxyXG5leHBvcnQgY29uc3QgbWFrZSA9IGFzeW5jICh2ZXJzaW9uOiBzdHJpbmcsIHJlc291cmNlOiBzdHJpbmcsIG1ldGhvZDogTWV0aG9kLCBwYXlsb2FkPzogYW55LCBjb250ZW50VHlwZTogc3RyaW5nIHwgbnVsbCA9ICdhcHBsaWNhdGlvbi9qc29uJyk6IFByb21pc2U8YW55PiA9PiB7XHJcbiAgY29uc3Qgb3B0aW9ucyA9IGdldE9wdGlvbnMoKVxyXG4gIGNvbnN0IGhlYWRlcnMgPSBhd2FpdCBnZXRIZWFkZXJzKGNvbnRlbnRUeXBlKVxyXG5cclxuICBsZXQgcmVxdWVzdDogUmVxdWVzdEluaXQgPSB7XHJcbiAgICBtZXRob2Q6IG1ldGhvZCxcclxuICAgIGhlYWRlcnM6IGhlYWRlcnMsXHJcbiAgICByZWRpcmVjdDogJ21hbnVhbCdcclxuICB9XHJcbiAgaWYgKHBheWxvYWQpIHtcclxuICAgIHJlcXVlc3QuYm9keSA9IGNvbnRlbnRUeXBlID09PSAnYXBwbGljYXRpb24vanNvbicgPyBKU09OLnN0cmluZ2lmeShwYXlsb2FkKSA6IHBheWxvYWRcclxuICB9XHJcbiAgcmV0dXJuIGF3YWl0IGZldGNoKG9wdGlvbnMuaG9zdCArIGAvYXBpL3Yke3ZlcnNpb259LyR7cmVzb3VyY2V9YCwgcmVxdWVzdClcclxufVxyXG5leHBvcnQgZGVmYXVsdCBtYWtlXHJcbiIsImNvbnN0IGdldCA9IGFzeW5jIChyZXNwb25zZTogUmVzcG9uc2UsIGV4cGVjdGVkQ29kZTogbnVtYmVyKTogUHJvbWlzZTxhbnk+ID0+IHtcclxuICBsZXQgcmVzOiBhbnkgPSBudWxsXHJcbiAgICBsZXQgYm9keVRleHQgPSAnJ1xyXG5cclxuICAgIC8vIFJlYWQgdGhlIGJvZHkgb25seSBvbmNlIGFzIHRleHQuIFRoaXMgYXZvaWRzIFwiYm9keSB1c2VkIGFscmVhZHlcIiB3aXRoIG5vZGUtZmV0Y2guXHJcbiAgICB0cnkge1xyXG4gICAgICAgIC8vIEV2ZW4gZm9yIDIwNC8zMDMsIHRleHQoKSBpcyBzYWZlIGFuZCB3aWxsIHJldHVybiAnJyBmb3IgZW1wdHkgYm9kaWVzXHJcbiAgICAgICAgYm9keVRleHQgPSBhd2FpdCByZXNwb25zZS50ZXh0KClcclxuICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAvLyBJZ25vcmUgYm9keSByZWFkIGVycm9yczsgd2UnbGwgcHJvY2VlZCB3aXRoIG51bGwvZW1wdHkgYm9keVxyXG4gICAgfVxyXG5cclxuICAgIC8vIFRyeSB0byBwYXJzZSBKU09OIGlmIHRoZXJlIGlzIGEgYm9keVxyXG4gICAgaWYgKGJvZHlUZXh0KSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgcmVzID0gSlNPTi5wYXJzZShib2R5VGV4dClcclxuICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIC8vIE5vdCBKU09OOyBrZWVwIHJlcyBhcyBudWxsIGFuZCB1c2UgYm9keVRleHQgZm9yIGVycm9yIG1lc3NhZ2VzXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChyZXNwb25zZS5zdGF0dXMgIT09IGV4cGVjdGVkQ29kZSkge1xyXG4gICAgICAgIGNvbnN0IG1zZyA9IChyZXMgJiYgKHJlcy5tZXNzYWdlIHx8IHJlcy5lcnJvcikpIHx8IGJvZHlUZXh0IHx8IGBVbmV4cGVjdGVkIHN0YXR1cyAke3Jlc3BvbnNlLnN0YXR1c31gXHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZylcclxuICAgIH1cclxuXHJcbiAgICAvLyBGb3IgMjA0LzMwMywgcmVzIHdpbGwgYmUgbnVsbCAobm8gYm9keSksIHdoaWNoIGlzIGZpbmUgZm9yIGNhbGxlcnMgZXhwZWN0aW5nIG5vIGNvbnRlbnRcclxuICAgIHJldHVybiByZXNcclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgZ2V0XHJcbiIsImltcG9ydCBtYWtlIGZyb20gXCIuL3V0aWwvbWFrZS1yZXF1ZXN0XCI7XHJcbmltcG9ydCBnZXQgZnJvbSBcIi4vdXRpbC9nZXQtcmVzcG9uc2VcIjtcclxuaW1wb3J0IHtTcWxSZXF1ZXN0LCBTUUxSZXNwb25zZX0gZnJvbSBcIi4vdHlwZXMvcGdUeXBlc1wiO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3FsIHtcclxuICAgIGFzeW5jIGV4ZWMocmVxdWVzdDogU3FsUmVxdWVzdCk6IFByb21pc2U8U1FMUmVzcG9uc2U+IHtcclxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IG1ha2UoJzQnLCBgc3FsYCwgJ1BPU1QnLCByZXF1ZXN0KVxyXG4gICAgICAgIHJldHVybiBhd2FpdCBnZXQocmVzcG9uc2UsIDIwMClcclxuICAgIH1cclxufVxyXG4iLCJpbXBvcnQgbWFrZSBmcm9tIFwiLi91dGlsL21ha2UtcmVxdWVzdFwiO1xyXG5pbXBvcnQgZ2V0IGZyb20gXCIuL3V0aWwvZ2V0LXJlc3BvbnNlXCI7XHJcbmltcG9ydCB7UnBjUmVxdWVzdCwgUnBjUmVzcG9uc2V9IGZyb20gXCIuL3R5cGVzL3BnVHlwZXNcIjtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJwYyB7XHJcbiAgICBhc3luYyBjYWxsKHJlcXVlc3Q6IFJwY1JlcXVlc3QpOiBQcm9taXNlPFJwY1Jlc3BvbnNlPiB7XHJcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBtYWtlKCc0JywgYGNhbGxgLCAnUE9TVCcsIHJlcXVlc3QpXHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IGdldChyZXNwb25zZSwgMjAwKVxyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCBtYWtlIGZyb20gXCIuL3V0aWwvbWFrZS1yZXF1ZXN0XCI7XHJcbmltcG9ydCBnZXQgZnJvbSBcIi4vdXRpbC9nZXQtcmVzcG9uc2VcIjtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1ldGEge1xyXG4gICAgYXN5bmMgcXVlcnkocmVsOiBzdHJpbmcpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgbWFrZSgnMycsIGBtZXRhLyR7cmVsfWAsICdHRVQnLCBudWxsKVxyXG4gICAgICAgIHJldHVybiBhd2FpdCBnZXQocmVzcG9uc2UsIDIwMClcclxuICAgIH1cclxufVxyXG4iLCJpbXBvcnQge2dldFRva2Vuc30gZnJvbSBcIi4vdXRpbC91dGlsc1wiO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3RhdHVzIHtcclxuICAgIGlzQXV0aCgpIHtcclxuICAgICAgICBjb25zdCB0b2tlbnMgPSBnZXRUb2tlbnMoKVxyXG4gICAgICAgIHJldHVybiAhKCF0b2tlbnMuYWNjZXNzVG9rZW4gJiYgIXRva2Vucy5yZWZyZXNoVG9rZW4pO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFRva2VucygpIHtcclxuICAgICAgICByZXR1cm4gZ2V0VG9rZW5zKClcclxuICAgIH1cclxufVxyXG4iLCJpbXBvcnQge2NsYWltcywgZ2V0VG9rZW5zfSBmcm9tIFwiLi91dGlsL3V0aWxzXCI7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDbGFpbXMge1xyXG4gICAgZ2V0KCkge1xyXG4gICAgICAgIGNvbnN0IHRva2VucyA9IGdldFRva2VucygpLmFjY2Vzc1Rva2VuXHJcbiAgICAgICAgcmV0dXJuIGNsYWltcyh0b2tlbnMpO1xyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCBtYWtlIGZyb20gXCIuL3V0aWwvbWFrZS1yZXF1ZXN0XCI7XHJcbmltcG9ydCBnZXQgZnJvbSBcIi4vdXRpbC9nZXQtcmVzcG9uc2VcIjtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFVzZXJzIHtcclxuICAgIGFzeW5jIGdldCh1c2VyOiBzdHJpbmcpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgbWFrZSgnNCcsIGB1c2Vycy8ke3VzZXJ9YCwgJ0dFVCcsIG51bGwpXHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IGdldChyZXNwb25zZSwgMjAwKVxyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCB7V3NPcHRpb25zLCBnZXRUb2tlbnN9IGZyb20gXCIuL3V0aWwvdXRpbHNcIjtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFdzIHtcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogV3NPcHRpb25zO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFdzT3B0aW9ucykge1xyXG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XHJcbiAgICB9XHJcblxyXG4gICAgY29ubmVjdCgpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBtZSA9IHRoaXM7XHJcbiAgICAgICAgY29uc3Qge2FjY2Vzc1Rva2VufSA9IGdldFRva2VucygpXHJcblxyXG4gICAgICAgIGNvbnN0IGNvbm5lY3QgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHdzID0gbmV3IFdlYlNvY2tldChcclxuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5ob3N0ICsgYC8/dG9rZW49YCArIGFjY2Vzc1Rva2VuLFxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB3cy5vbm9wZW4gPSBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdXZWJTb2NrZXQgY29ubmVjdGVkIScpO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgd3Mub25tZXNzYWdlID0gZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBpbmNvbWluZyBtZXNzYWdlc1xyXG4gICAgICAgICAgICAgICAgbWUub3B0aW9ucz8uY2FsbEJhY2soZXZlbnQuZGF0YSlcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHdzLm9uY2xvc2UgPSBmdW5jdGlvbihldmVudCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFjY2Vzc1Rva2VuICE9PSAnJykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdXZWJTb2NrZXQgY2xvc2VkLCByZWNvbm5lY3RpbmcgaW4gMyBzZWNvbmRzLi4uJywgZXZlbnQucmVhc29uKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGNvbm5lY3QsIDMwMDApOyAvLyBUcnkgdG8gcmVjb25uZWN0XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICB3cy5vbmVycm9yID0gZnVuY3Rpb24oZXJyKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdXZWJTb2NrZXQgZXJyb3Igb2JzZXJ2ZWQ6JywgZXJyKTtcclxuICAgICAgICAgICAgICAgIC8vIENsb3NlIHRoZSBzb2NrZXQgb24gZXJyb3IgdG8gZW5zdXJlIGNsZWFuIHJlY29ubmVjdGlvblxyXG4gICAgICAgICAgICAgICAgd3MuY2xvc2UoKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvLyBTdGFydCB0aGUgY29ubmVjdGlvblxyXG4gICAgICAgIGlmIChhY2Nlc3NUb2tlbiAhPT0gJycpIHtcclxuICAgICAgICAgICAgY29ubmVjdCgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iLCJpbXBvcnQgbWFrZSBmcm9tIFwiLi91dGlsL21ha2UtcmVxdWVzdFwiO1xyXG5pbXBvcnQgZ2V0IGZyb20gXCIuL3V0aWwvZ2V0LXJlc3BvbnNlXCI7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdGF0cyB7XHJcbiAgICBhc3luYyBnZXQoKTogUHJvbWlzZTxhbnk+IHtcclxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IG1ha2UoJzQnLCBgc3RhdHNgLCAnR0VUJywgbnVsbClcclxuICAgICAgICByZXR1cm4gYXdhaXQgZ2V0KHJlc3BvbnNlLCAyMDApXHJcbiAgICB9XHJcbn1cclxuIiwiaW1wb3J0IG1ha2UgZnJvbSBcIi4vdXRpbC9tYWtlLXJlcXVlc3RcIjtcclxuaW1wb3J0IGdldCBmcm9tIFwiLi91dGlsL2dldC1yZXNwb25zZVwiO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGFibGVzIHtcclxuICAgIGFzeW5jIGdldChzY2hlbWE6IHN0cmluZywgdGFibGU6IHN0cmluZyk6IFByb21pc2U8YW55PiB7XHJcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBtYWtlKCc0JywgYHNjaGVtYXMvJHtlbmNvZGVVUklDb21wb25lbnQoc2NoZW1hKX0vdGFibGVzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KHRhYmxlKX1gLCAnR0VUJywgbnVsbClcclxuICAgICAgICByZXR1cm4gYXdhaXQgZ2V0KHJlc3BvbnNlLCAyMDApXHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgY3JlYXRlKHNjaGVtYTogc3RyaW5nLCB0YWJsZTogc3RyaW5nLCBwYXlsb2FkOiBhbnkpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgbWFrZSgnNCcsIGBzY2hlbWFzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KHNjaGVtYSl9L3RhYmxlcy8ke2VuY29kZVVSSUNvbXBvbmVudCh0YWJsZSl9YCwgJ1BPU1QnLCBwYXlsb2FkKVxyXG4gICAgICAgIHJldHVybiBhd2FpdCBnZXQocmVzcG9uc2UsIDIwMClcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBwYXRjaChzY2hlbWE6IHN0cmluZywgdGFibGU6IHN0cmluZywgcGF5bG9hZDogYW55KTogUHJvbWlzZTxhbnk+IHtcclxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IG1ha2UoJzQnLCBgc2NoZW1hcy8ke2VuY29kZVVSSUNvbXBvbmVudChzY2hlbWEpfS90YWJsZXMvJHtlbmNvZGVVUklDb21wb25lbnQodGFibGUpfWAsICdQQVRDSCcsIHBheWxvYWQpXHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IGdldChyZXNwb25zZSwgMjAwKVxyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGRlbGV0ZShzY2hlbWE6IHN0cmluZywgdGFibGU6IHN0cmluZyk6IFByb21pc2U8YW55PiB7XHJcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBtYWtlKCc0JywgYHNjaGVtYXMvJHtlbmNvZGVVUklDb21wb25lbnQoc2NoZW1hKX0vdGFibGVzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KHRhYmxlKX1gLCAnREVMRVRFJywgbnVsbClcclxuICAgICAgICByZXR1cm4gYXdhaXQgZ2V0KHJlc3BvbnNlLCAyMDQpXHJcbiAgICB9XHJcbn1cclxuIiwiaW1wb3J0IFJwYyBmcm9tIFwiLi9ScGNcIlxyXG5pbXBvcnQge1JwY1JlcXVlc3R9IGZyb20gXCIuL3R5cGVzL3BnVHlwZXNcIlxyXG5cclxudHlwZSBNZXRob2RzT2Y8VD4gPSB7XHJcbiAgICBbSyBpbiBrZXlvZiBUXTogVFtLXSBleHRlbmRzICguLi5hcmdzOiBpbmZlciBBKSA9PiBpbmZlciBSID8gKC4uLmFyZ3M6IEEpID0+IFIgOiBuZXZlcjtcclxufTtcclxuXHJcbi8vIEltcGxlbWVudGF0aW9uIHNpZ25hdHVyZSAod2lkZSkg4oCUIG92ZXJsb2FkcyBhYm92ZSBjb250cm9sIHRoZSBwdWJsaWMgdHlwaW5nXHJcbmFzeW5jIGZ1bmN0aW9uIGRpc3BhdGNoPEsgZXh0ZW5kcyBrZXlvZiBhbnkgJiBzdHJpbmc+KG5hbWU6IEssIGFyZ3M6IG9iamVjdHxBcnJheTxvYmplY3Q+KTogUHJvbWlzZTxhbnk+IHtcclxuICAgIC8vY29uc29sZS5sb2coXCJEaXNwYXRjaDpcIiwgbmFtZSwgYXJncyk7XHJcbiAgICAvLyByb3V0ZSB0byByZWFsIGltcGxlbWVudGF0aW9uczpcclxuICAgIGNvbnN0IHJwYyA9IG5ldyBScGMoKVxyXG4gICAgY29uc3QgcmVxdWVzdDogUnBjUmVxdWVzdCA9IHtcclxuICAgICAgICBqc29ucnBjOiBcIjIuMFwiLFxyXG4gICAgICAgIG1ldGhvZDogbmFtZSxcclxuICAgICAgICBpZDogMSxcclxuICAgICAgICBwYXJhbXM6IGFyZ3MgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXHJcbiAgICB9XHJcbiAgICBjb25zdCByZXMgPSBhd2FpdCBycGMuY2FsbChyZXF1ZXN0KVxyXG4gICAgcmV0dXJuIHJlcy5yZXN1bHQuZGF0YVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBjcmVhdGVBcGk8VD4oKTogTWV0aG9kc09mPFQ+IHtcclxuICAgIHJldHVybiBuZXcgUHJveHkoXHJcbiAgICAgICAge30sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgICBnZXQoX3RhcmdldCwgcHJvcCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBwcm9wICE9PSBcInN0cmluZ1wiKSByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzOiBhbnlbXSkgPT4gKGRpc3BhdGNoIGFzIGFueSkocHJvcCwgLi4uYXJncyk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgfVxyXG4gICAgKSBhcyB1bmtub3duIGFzIE1ldGhvZHNPZjxUPjtcclxufVxyXG4iXSwibmFtZXMiOlsiSW52YWxpZFRva2VuRXJyb3IiLCJiNjREZWNvZGVVbmljb2RlIiwic3RyIiwibSIsInAiLCJjb2RlIiwiYmFzZTY0VXJsRGVjb2RlIiwib3V0cHV0Iiwiand0RGVjb2RlIiwidG9rZW4iLCJvcHRpb25zIiwicG9zIiwicGFydCIsImRlY29kZWQiLCJlIiwiTWVtb3J5U3RvcmFnZSIsImtleSIsInZhbHVlIiwiY2FjaGVkIiwiZ2V0U3RvcmFnZSIsImciLCJnZW5lcmF0ZVBrY2VDaGFsbGVuZ2UiLCJnZW5lcmF0ZVJhbmRvbVN0cmluZyIsImFycmF5IiwiZGVjIiwic2hhMjU2IiwicGxhaW4iLCJkYXRhIiwiYmFzZTY0dXJsRW5jb2RlIiwicGtjZUNoYWxsZW5nZUZyb21WZXJpZmllciIsInYiLCJoYXNoZWQiLCJzdGF0ZSIsImNvZGVWZXJpZmllciIsImNvZGVDaGFsbGVuZ2UiLCJpc1Rva2VuRXhwaXJlZCIsImlzSnd0RXhwaXJlZCIsImV4cCIsImN1cnJlbnRUaW1lIiwiY2xhaW1zIiwiaXNMb2dpbiIsImdjMiIsImFjY2Vzc1Rva2VuIiwicmVmcmVzaFRva2VuIiwiZ2V0VG9rZW5zIiwiY2xlYXJUb2tlbnMiLCJjbGVhck9wdGlvbnMiLCJzZXRUb2tlbnMiLCJ0b2tlbnMiLCJzZXRPcHRpb25zIiwiZ2V0T3B0aW9ucyIsImdldE5vbmNlIiwiY2xlYXJOb25jZSIsIkdjMlNlcnZpY2UiLCJwYXRoIiwidXJsIiwibWV0aG9kIiwiYm9keSIsImNvbnRlbnRUeXBlIiwiaGVhZGVycyIsInBheWxvYWQiLCJyZXNwb25zZSIsImVyclRleHQiLCJkZXZpY2VDb2RlIiwiaW50ZXJ2YWwiLCJnZXRUb2tlbiIsImVyciIsInJlc29sdmUiLCJyZWRpcmVjdFVyaSIsImJhc2UiLCJwYXJhbXMiLCJub25jZSIsInVzZXJuYW1lIiwicGFzc3dvcmQiLCJkYXRhYmFzZSIsIkNvZGVGbG93IiwicXVlcnlQYXJhbXMiLCJhY2Nlc3NfdG9rZW4iLCJyZWZyZXNoX3Rva2VuIiwiaWRfdG9rZW4iLCJsb2MiLCJuZXdVcmwiLCJQYXNzd29yZEZsb3ciLCJnZXRIZWFkZXJzIiwic2VydmljZSIsIm1ha2UiLCJ2ZXJzaW9uIiwicmVzb3VyY2UiLCJyZXF1ZXN0IiwiZ2V0IiwiZXhwZWN0ZWRDb2RlIiwicmVzIiwiYm9keVRleHQiLCJtc2ciLCJTcWwiLCJScGMiLCJNZXRhIiwicmVsIiwiU3RhdHVzIiwiQ2xhaW1zIiwiVXNlcnMiLCJ1c2VyIiwiV3MiLCJtZSIsImNvbm5lY3QiLCJ3cyIsImV2ZW50IiwiX2EiLCJTdGF0cyIsIlRhYmxlcyIsInNjaGVtYSIsInRhYmxlIiwiZGlzcGF0Y2giLCJuYW1lIiwiYXJncyIsInJwYyIsImNyZWF0ZUFwaSIsIl90YXJnZXQiLCJwcm9wIl0sIm1hcHBpbmdzIjoiMk5BNENP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
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/util/utils.ts","../src/services/gc2.services.ts","../src/CodeFlow.ts","../src/PasswordFlow.ts","../src/types/pgTypes.ts","../src/Sql.ts","../src/Rpc.ts","../src/Meta.ts","../src/Status.ts","../src/Claims.ts","../src/Users.ts","../src/Ws.ts","../src/Stats.ts","../src/Tables.ts","../src/Api.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":["decoded: string","cached: StorageLike | null","g: any","g","str: string | null","tokens: any","options: any","headers: Record<string, string>","payload: string","e: any","redirectUri: string","url: string","e: any","headers: headers","request: RequestInit","getHeaders","res: any","get","make","get","make","get","make","get","make","get","make","get","make","request: RpcRequest"],"sources":["../src/util/jwt-decode.ts","../src/util/storage.ts","../src/util/utils.ts","../src/services/gc2.services.ts","../src/CodeFlow.ts","../src/PasswordFlow.ts","../src/util/request-headers.ts","../src/util/make-request.ts","../src/util/get-response.ts","../src/Sql.ts","../src/Rpc.ts","../src/Meta.ts","../src/Status.ts","../src/Claims.ts","../src/Users.ts","../src/Ws.ts","../src/Stats.ts","../src/Tables.ts","../src/Api.ts"],"sourcesContent":["/**\r\n * The MIT License (MIT)\r\n *\r\n * Copyright (c) 2015 Auth0, Inc. <support@auth0.com> (http://auth0.com)\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to deal\r\n * in the Software without restriction, including without limitation the rights\r\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n * copies of the Software, and to permit persons to whom the Software is\r\n * furnished to do so, subject to the following conditions:\r\n *\r\n * The above copyright notice and this permission notice shall be included in all\r\n * copies or substantial portions of the Software.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n * SOFTWARE.\r\n */\r\n\r\nexport interface JwtDecodeOptions {\r\n header?: boolean;\r\n}\r\n\r\nexport interface JwtHeader {\r\n typ?: string;\r\n alg?: string;\r\n kid?: string;\r\n}\r\n\r\nexport interface JwtPayload {\r\n iss?: string;\r\n sub?: string;\r\n aud?: string[] | string;\r\n exp?: number;\r\n nbf?: number;\r\n iat?: number;\r\n jti?: string;\r\n}\r\n\r\nexport class InvalidTokenError extends Error {}\r\n\r\nInvalidTokenError.prototype.name = \"InvalidTokenError\";\r\n\r\nfunction b64DecodeUnicode(str: string) {\r\n return decodeURIComponent(\r\n atob(str).replace(/(.)/g, (m, p) => {\r\n let code = (p as string).charCodeAt(0).toString(16).toUpperCase();\r\n if (code.length < 2) {\r\n code = \"0\" + code;\r\n }\r\n return \"%\" + code;\r\n }),\r\n );\r\n}\r\n\r\nfunction base64UrlDecode(str: string) {\r\n let output = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\r\n switch (output.length % 4) {\r\n case 0:\r\n break;\r\n case 2:\r\n output += \"==\";\r\n break;\r\n case 3:\r\n output += \"=\";\r\n break;\r\n default:\r\n throw new Error(\"base64 string is not of the correct length\");\r\n }\r\n\r\n try {\r\n return b64DecodeUnicode(output);\r\n } catch (err) {\r\n return atob(output);\r\n }\r\n}\r\n\r\nexport function jwtDecode<T = JwtHeader>(\r\n token: string,\r\n options: JwtDecodeOptions & { header: true },\r\n): T;\r\nexport function jwtDecode<T = JwtPayload>(token: string, options?: JwtDecodeOptions): T;\r\nexport function jwtDecode<T = JwtHeader | JwtPayload>(\r\n token: string,\r\n options?: JwtDecodeOptions,\r\n): T {\r\n if (typeof token !== \"string\") {\r\n throw new InvalidTokenError(\"Invalid token specified: must be a string\");\r\n }\r\n\r\n options ||= {};\r\n\r\n const pos = options.header === true ? 0 : 1;\r\n const part = token.split(\".\")[pos];\r\n\r\n if (typeof part !== \"string\") {\r\n throw new InvalidTokenError(`Invalid token specified: missing part #${pos + 1}`);\r\n }\r\n\r\n let decoded: string;\r\n try {\r\n decoded = base64UrlDecode(part);\r\n } catch (e) {\r\n throw new InvalidTokenError(\r\n `Invalid token specified: invalid base64 for part #${pos + 1} (${(e as Error).message})`,\r\n );\r\n }\r\n\r\n try {\r\n return JSON.parse(decoded) as T;\r\n } catch (e) {\r\n throw new InvalidTokenError(\r\n `Invalid token specified: invalid json for part #${pos + 1} (${(e as Error).message})`,\r\n );\r\n }\r\n}\r\n","export interface StorageLike {\r\n getItem(key: string): string | null\r\n setItem(key: string, value: string): void\r\n removeItem(key: string): void\r\n}\r\n\r\nclass MemoryStorage implements StorageLike {\r\n private store = new Map<string, string>()\r\n\r\n getItem(key: string): string | null {\r\n return this.store.has(key) ? this.store.get(key)! : null\r\n }\r\n\r\n setItem(key: string, value: string): void {\r\n this.store.set(key, String(value))\r\n }\r\n\r\n removeItem(key: string): void {\r\n this.store.delete(key)\r\n }\r\n}\r\n\r\nlet cached: StorageLike | null = null\r\n\r\nexport function getStorage(): StorageLike {\r\n if (cached) return cached\r\n try {\r\n const g: any = typeof globalThis !== 'undefined' ? (globalThis as any) : (window as any)\r\n if (g && g.localStorage && typeof g.localStorage.getItem === 'function') {\r\n cached = g.localStorage as StorageLike\r\n return cached\r\n }\r\n } catch (e) {\r\n // ignore and fall back to memory storage\r\n }\r\n const g: any = typeof globalThis !== 'undefined' ? (globalThis as any) : {}\r\n if (!g.__gc2_memory_storage) {\r\n g.__gc2_memory_storage = new MemoryStorage()\r\n }\r\n cached = g.__gc2_memory_storage as StorageLike\r\n return cached\r\n}\r\n","import {jwtDecode} from './jwt-decode'\r\nimport {Gc2Service} from \"../services/gc2.services\";\r\nimport {getStorage} from './storage'\r\n\r\nexport type Tokens = {\r\n accessToken: string;\r\n refreshToken: string;\r\n idToken?: string;\r\n};\r\n\r\nexport type Options = {\r\n host: string;\r\n wsHost?: string;\r\n tokenUri?: string;\r\n authUri?: string;\r\n logoutUri?: string;\r\n deviceUri?: string;\r\n scope?: string;\r\n clientId: string;\r\n}\r\n\r\nexport type CodeFlowOptions = Options & {\r\n redirectUri: string;\r\n}\r\n\r\nexport type PasswordFlowOptions = Options & {\r\n username: string;\r\n password: string;\r\n database: string;\r\n}\r\n\r\nexport type WsOptions = {\r\n host: string;\r\n callBack?: any;\r\n}\r\n\r\nexport type GetDeviceCodeResponse = {\r\n device_code: string;\r\n user_code: string;\r\n verification_uri: string;\r\n verification_uri_complete?: string;\r\n expires_in: number;\r\n interval: number;\r\n};\r\n\r\nexport type GetTokenResponse = {\r\n access_token: string;\r\n expires_in: number;\r\n refresh_expires_in: number;\r\n refresh_token: string;\r\n id_token?: string;\r\n token_type: string;\r\n 'not-before-policy': number;\r\n session_state: string;\r\n scope: string;\r\n};\r\n\r\n\r\nexport const generatePkceChallenge = async () => {\r\n\r\n const generateRandomString = () => {\r\n const array = new Uint32Array(28);\r\n crypto.getRandomValues(array);\r\n return Array.from(array, dec => ('0' + dec.toString(16)).substr(-2)).join('');\r\n }\r\n\r\n const sha256 = (plain: string | undefined) => {\r\n const encoder = new TextEncoder();\r\n const data = encoder.encode(plain);\r\n return crypto.subtle.digest('SHA-256', data);\r\n }\r\n\r\n const base64urlEncode = (str: ArrayBuffer) => {\r\n\r\n return btoa(String.fromCharCode.apply(null, [...new Uint8Array(str)]))\r\n .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\r\n }\r\n\r\n async function pkceChallengeFromVerifier(v: string | undefined) {\r\n const hashed = await sha256(v);\r\n return base64urlEncode(hashed);\r\n }\r\n\r\n const {state, codeVerifier} = {\r\n state: generateRandomString(),\r\n codeVerifier: generateRandomString(),\r\n };\r\n const codeChallenge = await pkceChallengeFromVerifier(codeVerifier);\r\n\r\n return {\r\n state,\r\n codeVerifier,\r\n codeChallenge,\r\n }\r\n}\r\n\r\nexport const isTokenExpired = (token: string): boolean => {\r\n let isJwtExpired = false\r\n const {exp} = jwtDecode(token)\r\n const currentTime = new Date().getTime() / 1000\r\n\r\n if (exp) {\r\n if (currentTime > exp) isJwtExpired = true\r\n }\r\n return isJwtExpired\r\n}\r\n\r\nexport const claims = (token: string): any => {\r\n return jwtDecode(token)\r\n}\r\n\r\nexport const passwordIsStrongEnough = (password: string, allowNull: boolean = false) => {\r\n const message = 'Entered password is too weak'\r\n if (password === '' && allowNull) return true\r\n if (password.length < 8) return message\r\n if (!(/[A-Z]/.test(password))) return message\r\n if (!(/[a-z]/.test(password))) return message\r\n if (!(/\\d/.test(password))) return message\r\n return true\r\n}\r\n\r\nexport const isLogin = async (gc2: Gc2Service): Promise<boolean> => {\r\n const {accessToken, refreshToken} = getTokens()\r\n if (!accessToken && !refreshToken) {\r\n return false\r\n }\r\n if (!accessToken || (accessToken && isTokenExpired(accessToken))) {\r\n if (refreshToken && isTokenExpired(refreshToken)) {\r\n clearTokens()\r\n clearOptions()\r\n throw new Error('Refresh token has expired. Please login again.')\r\n }\r\n if (refreshToken) {\r\n try {\r\n const data = await gc2.getRefreshToken(refreshToken)\r\n setTokens({accessToken: data.access_token, refreshToken, idToken: data?.id_token})\r\n console.log('Access token refreshed')\r\n } catch (e) {\r\n throw new Error('Could not get refresh token.')\r\n }\r\n }\r\n }\r\n return true\r\n}\r\n\r\nexport const setTokens = (tokens: Tokens): void => {\r\n getStorage().setItem('gc2_tokens', JSON.stringify({\r\n 'accessToken': tokens.accessToken,\r\n 'refreshToken': tokens.refreshToken,\r\n 'idToken': tokens?.idToken || ''\r\n }\r\n )\r\n )\r\n}\r\n\r\nexport const getTokens = (): Tokens => {\r\n const str: string | null = getStorage().getItem('gc2_tokens')\r\n const tokens: any = str ? JSON.parse(str) : {}\r\n return {\r\n accessToken: tokens?.accessToken || '',\r\n refreshToken: tokens?.refreshToken || '',\r\n idToken: tokens?.idToken || '',\r\n }\r\n}\r\n\r\nexport const setOptions = (options: CodeFlowOptions): void => {\r\n getStorage().setItem('gc2_options', JSON.stringify({\r\n 'clientId': options.clientId,\r\n 'host': options.host,\r\n 'redirectUri': options.redirectUri\r\n }\r\n )\r\n )\r\n}\r\n\r\nexport const getOptions = (): CodeFlowOptions => {\r\n const str: string | null = getStorage().getItem('gc2_options')\r\n const options: any = str ? JSON.parse(str) : {}\r\n return {\r\n clientId: options?.clientId || '',\r\n host: options?.host || '',\r\n redirectUri: options?.redirectUri || '',\r\n }\r\n}\r\n\r\nexport const base64UrlEncodeString = (str: string): string => {\r\n return btoa(new TextEncoder().encode(str).reduce((acc, byte) => acc + String.fromCharCode(byte), ''))\r\n .replace(/\\+/g, '-')\r\n .replace(/\\//g, '_')\r\n .replace(/=+$/, '');\r\n}\r\n\r\nexport const clearTokens = (): void => {\r\n getStorage().removeItem('gc2_tokens')\r\n}\r\n\r\nexport const clearOptions = (): void => {\r\n getStorage().removeItem('gc2_options')\r\n}\r\n\r\nexport const getNonce = (): string|null => {\r\n return <string>getStorage().getItem('gc2_nonce')\r\n}\r\nexport const clearNonce = (): void => {\r\n getStorage().removeItem('gc2_nonce')\r\n}\r\n\r\n","import {CodeFlowOptions, GetDeviceCodeResponse, getNonce, GetTokenResponse, PasswordFlowOptions} from '../util/utils';\r\n\r\nexport class Gc2Service {\r\n private readonly options: CodeFlowOptions | PasswordFlowOptions;\r\n private readonly host: string;\r\n\r\n constructor(options: CodeFlowOptions | PasswordFlowOptions) {\r\n this.options = options;\r\n this.host = options.host;\r\n }\r\n\r\n // Type guards to check if options is CodeFlowOptions or PasswordFlowOptions\r\n private isCodeFlowOptions(options: CodeFlowOptions | PasswordFlowOptions): options is CodeFlowOptions {\r\n return 'redirectUri' in options;\r\n }\r\n private isPasswordFlowOptions(options: CodeFlowOptions | PasswordFlowOptions): options is PasswordFlowOptions {\r\n return 'username' in options;\r\n }\r\n\r\n private buildUrl(path: string): string {\r\n if (path.startsWith('http://') || path.startsWith('https://')) {\r\n return path;\r\n }\r\n return `${this.host}${path}`;\r\n }\r\n\r\n private async request(\r\n url: string,\r\n method: 'GET' | 'POST',\r\n body?: any,\r\n contentType: 'application/json' | 'application/x-www-form-urlencoded' = 'application/json'\r\n ): Promise<any> {\r\n const headers: Record<string, string> = {'Content-Type': contentType};\r\n let payload: string;\r\n\r\n if (contentType === 'application/json') {\r\n payload = JSON.stringify(body);\r\n } else {\r\n payload = new URLSearchParams(body).toString();\r\n }\r\n\r\n const response = await fetch(url, {\r\n method,\r\n headers,\r\n body: payload,\r\n });\r\n\r\n if (!response.ok) {\r\n const errText = await response.text();\r\n throw new Error(`HTTP error ${response.status}: ${errText}`);\r\n }\r\n\r\n return response.json();\r\n }\r\n\r\n async getDeviceCode(): Promise<GetDeviceCodeResponse> {\r\n const path = this.options.deviceUri ?? `${this.host}/api/v4/oauth/device`;\r\n return this.request(this.buildUrl(path), 'POST', {\r\n client_id: this.options.clientId,\r\n });\r\n }\r\n\r\n async pollToken(deviceCode: string, interval: number): Promise<GetTokenResponse> {\r\n const path = this.options.tokenUri ?? `${this.host}/api/v4/oauth`;\r\n const getToken = async (): Promise<GetTokenResponse | null | string> => {\r\n try {\r\n return await this.request(\r\n this.buildUrl(path),\r\n 'POST',\r\n {\r\n client_id: this.options.clientId,\r\n device_code: deviceCode,\r\n grant_type: 'device_code',\r\n }\r\n );\r\n } catch (e: any) {\r\n const err = JSON.parse(e.message.split(': ')[1]);\r\n if (err.error === 'authorization_pending') {\r\n return null;\r\n }\r\n return err.error_description;\r\n }\r\n };\r\n\r\n let response = await getToken();\r\n while (response === null) {\r\n await new Promise(resolve => setTimeout(resolve, interval * 1100));\r\n response = await getToken();\r\n }\r\n\r\n if (typeof response === 'string') {\r\n throw new Error(response);\r\n }\r\n\r\n return response;\r\n }\r\n\r\n getAuthorizationCodeURL(codeChallenge: string, state: string): string {\r\n let redirectUri: string\r\n if (this.isCodeFlowOptions(this.options)) {\r\n redirectUri = this.options.redirectUri\r\n } else {\r\n throw new Error('CodeFlow options required for this operation')\r\n }\r\n const base = this.options.authUri ?? `${this.host}/auth/`\r\n const params = new URLSearchParams()\r\n // Get nonce from local storage if it exists\r\n const nonce = getNonce()\r\n // Add parameters conditionally\r\n params.set('response_type', 'code');\r\n params.set('client_id', this.options.clientId);\r\n params.set('redirect_uri', redirectUri);\r\n params.set('state', state);\r\n params.set('code_challenge', codeChallenge);\r\n params.set('code_challenge_method', 'S256');\r\n if (nonce) {\r\n params.set('nonce', nonce);\r\n }\r\n // Only add scope if it's defined\r\n if (this.options.scope) {\r\n params.set('scope', this.options.scope);\r\n }\r\n return `${base}?${params.toString()}`;\r\n }\r\n\r\n async getAuthorizationCodeToken(\r\n code: string | string[],\r\n codeVerifier: string | null\r\n ): Promise<GetTokenResponse> {\r\n let redirectUri: string\r\n if (this.isCodeFlowOptions(this.options)) {\r\n redirectUri = this.options.redirectUri\r\n } else {\r\n throw new Error('CodeFlow options required for this operation')\r\n }\r\n const path = this.options.tokenUri ?? `${this.host}/api/v4/oauth`;\r\n return this.request(\r\n this.buildUrl(path),\r\n 'POST',\r\n {\r\n client_id: this.options.clientId,\r\n redirect_uri: redirectUri,\r\n grant_type: 'authorization_code',\r\n code,\r\n code_verifier: codeVerifier,\r\n },\r\n 'application/x-www-form-urlencoded'\r\n );\r\n }\r\n\r\n async getPasswordToken(): Promise<GetTokenResponse> {\r\n let username, password, database\r\n if (this.isPasswordFlowOptions(this.options)) {\r\n username = this.options.username\r\n password = this.options.password\r\n database = this.options.database\r\n } else {\r\n throw new Error('PasswordFlow options required for this operation')\r\n }\r\n const path = `${this.host}/api/v4/oauth`;\r\n return this.request(\r\n this.buildUrl(path),\r\n 'POST',\r\n {\r\n client_id: this.options.clientId,\r\n grant_type: 'password',\r\n username,\r\n password,\r\n database,\r\n }\r\n );\r\n }\r\n\r\n async getRefreshToken(token: string): Promise<GetTokenResponse> {\r\n const path = this.options.tokenUri ?? `${this.host}/api/v4/oauth`;\r\n return this.request(\r\n this.buildUrl(path),\r\n 'POST',\r\n {\r\n client_id: this.options.clientId,\r\n grant_type: 'refresh_token',\r\n refresh_token: token,\r\n }\r\n );\r\n }\r\n\r\n getSignOutURL(): string {\r\n let redirectUri: string\r\n if (this.isCodeFlowOptions(this.options)) {\r\n redirectUri = this.options.redirectUri\r\n } else {\r\n throw new Error('CodeFlow options required for this operation')\r\n }\r\n const params = new URLSearchParams({\r\n redirect_uri: redirectUri,\r\n });\r\n return this.options.logoutUri ?? `${this.host}/signout?${params.toString()}`;\r\n }\r\n}\r\n","import {Gc2Service} from './services/gc2.services'\r\nimport {generatePkceChallenge, isLogin, setTokens, setOptions, clearNonce} from './util/utils'\r\nimport {CodeFlowOptions, clearTokens, clearOptions} from \"./util/utils\";\r\nimport {getStorage} from './util/storage'\r\n\r\nexport default class CodeFlow {\r\n options: CodeFlowOptions\r\n service: Gc2Service\r\n\r\n constructor(options: CodeFlowOptions) {\r\n this.options = options\r\n this.service = new Gc2Service(options)\r\n }\r\n\r\n public async redirectHandle(): Promise<boolean> {\r\n const url: string = window.location.search\r\n const queryParams = new URLSearchParams(url)\r\n\r\n const error = queryParams.get('error')\r\n if (error) {\r\n throw new Error(`Failed to redirect: ${url}`)\r\n }\r\n\r\n const code = queryParams.get('code')\r\n if (code) {\r\n const state = queryParams.get('state')\r\n if (state !== getStorage().getItem('state')) {\r\n throw new Error('Possible CSRF attack. Aborting login!')\r\n }\r\n try {\r\n const {\r\n access_token,\r\n refresh_token,\r\n id_token,\r\n } = await this.service.getAuthorizationCodeToken(code, getStorage().getItem('codeVerifier'))\r\n setTokens({accessToken: access_token, refreshToken: refresh_token, idToken: id_token})\r\n setOptions({\r\n clientId: this.options.clientId,\r\n host: this.options.host,\r\n redirectUri: this.options.redirectUri\r\n })\r\n getStorage().removeItem('state')\r\n getStorage().removeItem('codeVerifier')\r\n\r\n // Remove state and code from the redirect url\r\n const params = new URLSearchParams(window.location.search);\r\n params.delete('code')\r\n params.delete('state')\r\n const loc = window.location\r\n const newUrl = loc.origin + loc.pathname + (params.size > 0 ? '?' + params.toString() : '')\r\n history.pushState(null, '', newUrl);\r\n\r\n return Promise.resolve(true)\r\n\r\n } catch (e: any) {\r\n throw new Error(e.message)\r\n }\r\n }\r\n return await isLogin(this.service);\r\n }\r\n\r\n public async signIn(): Promise<void> {\r\n const {state, codeVerifier, codeChallenge} = await generatePkceChallenge()\r\n getStorage().setItem(\"state\", state)\r\n getStorage().setItem(\"codeVerifier\", codeVerifier);\r\n // @ts-ignore\r\n window.location = this.service.getAuthorizationCodeURL(\r\n codeChallenge,\r\n state,\r\n );\r\n }\r\n\r\n public signOut(): void {\r\n this.clear()\r\n // @ts-ignore\r\n window.location = this.service.getSignOutURL();\r\n }\r\n\r\n public clear(): void {\r\n clearTokens()\r\n clearOptions()\r\n clearNonce()\r\n }\r\n}\r\n","import {Gc2Service,} from './services/gc2.services'\r\nimport {isLogin, setTokens, setOptions, PasswordFlowOptions, clearTokens, clearOptions, clearNonce} from './util/utils'\r\n\r\nexport default class PasswordFlow {\r\n options: PasswordFlowOptions\r\n service: Gc2Service\r\n\r\n constructor(options: PasswordFlowOptions) {\r\n this.options = options\r\n this.service = new Gc2Service(options)\r\n }\r\n\r\n public async signIn(): Promise<void> {\r\n const {access_token, refresh_token} = await this.service.getPasswordToken()\r\n setTokens({accessToken: access_token, refreshToken: refresh_token})\r\n setOptions({\r\n clientId: this.options.clientId,\r\n host: this.options.host,\r\n redirectUri: ''\r\n })\r\n }\r\n\r\n public signOut(): void {\r\n this.clear()\r\n }\r\n\r\n public clear(): void {\r\n clearTokens()\r\n clearOptions()\r\n clearNonce()\r\n }\r\n}\r\n","/**\r\n * @author Martin Høgh <mh@mapcentia.com>\r\n * @copyright 2013-2024 MapCentia ApS\r\n * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3\r\n *\r\n */\r\n\r\nimport {getOptions, getTokens, isLogin} from \"./utils\";\r\nimport {Gc2Service} from \"../services/gc2.services\";\r\n\r\nconst getHeaders = async (contentType: string|null = 'application/json'): Promise<any>=> {\r\n type headers = {\r\n Accept: string,\r\n Cookie: string,\r\n Authorization: string|null,\r\n 'Content-Type'?: string\r\n }\r\n\r\n const options = getOptions()\r\n const service = new Gc2Service(options)\r\n\r\n // We check is token needs refreshing\r\n if (!await isLogin(service)) {\r\n return Promise.reject('Is not logged in')\r\n }\r\n\r\n const {accessToken} = getTokens()\r\n\r\n const headers: headers = {\r\n Accept: 'application/json',\r\n Cookie: 'XDEBUG_SESSION=XDEBUG_ECLIPSE',\r\n Authorization: accessToken ? 'Bearer ' + accessToken : null,\r\n }\r\n if (contentType) {\r\n headers['Content-Type'] = contentType\r\n }\r\n return headers\r\n}\r\nexport default getHeaders\r\n\r\n","/**\r\n * @author Martin Høgh <mh@mapcentia.com>\r\n * @copyright 2013-2024 MapCentia ApS\r\n * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3\r\n *\r\n */\r\n\r\nimport getHeaders from './request-headers'\r\nimport Method from '../common/http-verbs'\r\nimport {getOptions} from './utils'\r\n\r\nexport const make = async (version: string, resource: string, method: Method, payload?: any, contentType: string | null = 'application/json'): Promise<any> => {\r\n const options = getOptions()\r\n const headers = await getHeaders(contentType)\r\n\r\n let request: RequestInit = {\r\n method: method,\r\n headers: headers,\r\n redirect: 'manual'\r\n }\r\n if (payload) {\r\n request.body = contentType === 'application/json' ? JSON.stringify(payload) : payload\r\n }\r\n return await fetch(options.host + `/api/v${version}/${resource}`, request)\r\n}\r\nexport default make\r\n","const get = async (response: Response, expectedCode: number): Promise<any> => {\r\n let res: any = null\r\n let bodyText = ''\r\n\r\n // Read the body only once as text. This avoids \"body used already\" with node-fetch.\r\n try {\r\n // Even for 204/303, text() is safe and will return '' for empty bodies\r\n bodyText = await response.text()\r\n } catch (e) {\r\n // Ignore body read errors; we'll proceed with null/empty body\r\n }\r\n\r\n // Try to parse JSON if there is a body\r\n if (bodyText) {\r\n try {\r\n res = JSON.parse(bodyText)\r\n } catch (e) {\r\n // Not JSON; keep res as null and use bodyText for error messages\r\n }\r\n }\r\n\r\n if (response.status !== expectedCode) {\r\n const msg = (res && (res.message || res.error)) || bodyText || `Unexpected status ${response.status}`\r\n throw new Error(msg)\r\n }\r\n\r\n // For 204/303, res will be null (no body), which is fine for callers expecting no content\r\n return res\r\n}\r\n\r\nexport default get\r\n","import make from \"./util/make-request\";\r\nimport get from \"./util/get-response\";\r\nimport {SqlRequest, SQLResponse} from \"./types/pgTypes\";\r\n\r\nexport default class Sql {\r\n async exec(request: SqlRequest): Promise<SQLResponse> {\r\n const response = await make('4', `sql`, 'POST', request)\r\n return await get(response, 200)\r\n }\r\n}\r\n","import make from \"./util/make-request\";\r\nimport get from \"./util/get-response\";\r\nimport {RpcRequest, RpcResponse} from \"./types/pgTypes\";\r\n\r\nexport default class Rpc {\r\n async call(request: RpcRequest): Promise<RpcResponse> {\r\n const response = await make('4', `call`, 'POST', request)\r\n return await get(response, 200)\r\n }\r\n}\r\n","import make from \"./util/make-request\";\r\nimport get from \"./util/get-response\";\r\n\r\nexport default class Meta {\r\n async query(rel: string): Promise<any> {\r\n const response = await make('3', `meta/${rel}`, 'GET', null)\r\n return await get(response, 200)\r\n }\r\n}\r\n","import {getTokens} from \"./util/utils\";\r\n\r\nexport default class Status {\r\n isAuth() {\r\n const tokens = getTokens()\r\n return !(!tokens.accessToken && !tokens.refreshToken);\r\n }\r\n\r\n getTokens() {\r\n return getTokens()\r\n }\r\n}\r\n","import {claims, getTokens} from \"./util/utils\";\r\n\r\nexport default class Claims {\r\n get() {\r\n const tokens = getTokens().accessToken\r\n return claims(tokens);\r\n }\r\n}\r\n","import make from \"./util/make-request\";\r\nimport get from \"./util/get-response\";\r\n\r\nexport default class Users {\r\n async get(user: string): Promise<any> {\r\n const response = await make('4', `users/${user}`, 'GET', null)\r\n return await get(response, 200)\r\n }\r\n}\r\n","import {WsOptions, getTokens} from \"./util/utils\";\r\n\r\nexport default class Ws {\r\n private readonly options: WsOptions;\r\n\r\n constructor(options: WsOptions) {\r\n this.options = options;\r\n }\r\n\r\n connect(): void {\r\n const me = this;\r\n const {accessToken} = getTokens()\r\n\r\n const connect = () => {\r\n const ws = new WebSocket(\r\n this.options.host + `/?token=` + accessToken,\r\n );\r\n ws.onopen = function() {\r\n console.log('WebSocket connected!');\r\n };\r\n\r\n ws.onmessage = function(event) {\r\n // Handle incoming messages\r\n me.options?.callBack(event.data)\r\n };\r\n\r\n ws.onclose = function(event) {\r\n if (accessToken !== '') {\r\n console.log('WebSocket closed, reconnecting in 3 seconds...', event.reason);\r\n setTimeout(connect, 3000); // Try to reconnect\r\n }\r\n };\r\n\r\n ws.onerror = function(err) {\r\n console.error('WebSocket error observed:', err);\r\n // Close the socket on error to ensure clean reconnection\r\n ws.close();\r\n };\r\n };\r\n\r\n // Start the connection\r\n if (accessToken !== '') {\r\n connect();\r\n }\r\n }\r\n}\r\n","import make from \"./util/make-request\";\r\nimport get from \"./util/get-response\";\r\n\r\nexport default class Stats {\r\n async get(): Promise<any> {\r\n const response = await make('4', `stats`, 'GET', null)\r\n return await get(response, 200)\r\n }\r\n}\r\n","import make from \"./util/make-request\";\r\nimport get from \"./util/get-response\";\r\n\r\nexport default class Tables {\r\n async get(schema: string, table: string): Promise<any> {\r\n const response = await make('4', `schemas/${encodeURIComponent(schema)}/tables/${encodeURIComponent(table)}`, 'GET', null)\r\n return await get(response, 200)\r\n }\r\n\r\n async create(schema: string, table: string, payload: any): Promise<any> {\r\n const response = await make('4', `schemas/${encodeURIComponent(schema)}/tables/${encodeURIComponent(table)}`, 'POST', payload)\r\n return await get(response, 200)\r\n }\r\n\r\n async patch(schema: string, table: string, payload: any): Promise<any> {\r\n const response = await make('4', `schemas/${encodeURIComponent(schema)}/tables/${encodeURIComponent(table)}`, 'PATCH', payload)\r\n return await get(response, 200)\r\n }\r\n\r\n async delete(schema: string, table: string): Promise<any> {\r\n const response = await make('4', `schemas/${encodeURIComponent(schema)}/tables/${encodeURIComponent(table)}`, 'DELETE', null)\r\n return await get(response, 204)\r\n }\r\n}\r\n","import Rpc from \"./Rpc\"\r\nimport {RpcRequest} from \"./types/pgTypes\"\r\n\r\ntype MethodsOf<T> = {\r\n [K in keyof T]: T[K] extends (...args: infer A) => infer R ? (...args: A) => R : never;\r\n};\r\n\r\n// Implementation signature (wide) — overloads above control the public typing\r\nasync function dispatch<K extends keyof any & string>(name: K, args: object|Array<object>): Promise<any> {\r\n //console.log(\"Dispatch:\", name, args);\r\n // route to real implementations:\r\n const rpc = new Rpc()\r\n const request: RpcRequest = {\r\n jsonrpc: \"2.0\",\r\n method: name,\r\n id: 1,\r\n params: args as Record<string, unknown>,\r\n }\r\n const res = await rpc.call(request)\r\n return res.result.data\r\n}\r\n\r\nexport default function createApi<T>(): MethodsOf<T> {\r\n return new Proxy(\r\n {},\r\n {\r\n get(_target, prop) {\r\n if (typeof prop !== \"string\") return undefined;\r\n return (...args: any[]) => (dispatch as any)(prop, ...args);\r\n },\r\n }\r\n ) as unknown as MethodsOf<T>;\r\n}\r\n"],"mappings":"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"}