UNPKG

fiscalapi

Version:

SDK de Node.js para FiscalAPI

306 lines 40.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FiscalapiHttpClient = void 0; /** * Cliente HTTP para FiscalAPI */ class FiscalapiHttpClient { /** * Crea una nueva instancia del cliente HTTP para FiscalAPI * @param {AxiosInstance} httpClient - Instancia de Axios configurada * @param {FiscalapiSettings} settings - Configuración para el cliente FiscalAPI */ constructor(httpClient, settings) { this.httpClient = httpClient; this.settings = settings; // Configurar interceptores para el logging en modo debug if (this.settings.debug) { this.setupDebugInterceptors(); } } /** * Configura los interceptores para logear las peticiones y respuestas en modo debug * @private */ setupDebugInterceptors() { // Interceptor para peticiones this.httpClient.interceptors.request.use((config) => { this.logRequest(config); return config; }); // Interceptor para respuestas this.httpClient.interceptors.response.use((response) => { this.logResponse(response); return response; }, (error) => { if (error.response) { this.logResponse(error.response); } return Promise.reject(error); }); } /** * Logea los detalles de una petición HTTP cuando el modo debug está activado * @param {InternalAxiosRequestConfig} config - Configuración de la petición * @private */ logRequest(config) { var _a; if (this.settings.debug) { console.log(''); console.log('********************** Raw Request **************************'); console.log('Method: ', (_a = config.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()); console.log('BaseURL: ', config.baseURL); console.log('PathURL: ', config.url); const resource = `${config.baseURL || ''}/${config.url || ''}`; console.log('FullURL: ', resource); if (config.data) { console.log('Body:', typeof config.data === 'string' ? config.data : JSON.stringify(config.data, null, 2)); } console.log(''); if (config.params) { console.log('Params:', config.params); } console.log(''); } } /** * Logea los detalles de una respuesta HTTP cuando el modo debug está activado * @param {AxiosResponse} response - Respuesta de la petición * @private */ logResponse(response) { if (this.settings.debug) { console.log(''); console.log('********************** Raw Response **************************'); console.log(''); console.log('Status:', response.status, response.statusText); //console.log('Headers:', response.headers); console.log('Data:', JSON.stringify(response.data, null, 2)); console.log(''); console.log('*************************************************************'); console.log(''); } } /** * Ejecuta una petición HTTP genérica con control completo sobre los parámetros * @param {HttpMethod} method - Método HTTP a utilizar * @param {string} endpoint - Punto final de la API * @param {RequestOptions<TData>} options - Opciones de la petición * @returns {Promise<ApiResponse<TResult>>} Respuesta de la API * @template TResult - Tipo de datos esperado en la respuesta * @template TData - Tipo de datos a enviar en la petición (opcional) */ async executeRequest(method, endpoint, options = {}) { try { // Extraer opciones const { data, queryParams, config = {}, responseTransformer } = options; // Construir configuración de la petición const requestConfig = { ...config, method, url: endpoint }; // Añadir parámetros de consulta si existen if (queryParams && Object.keys(queryParams).length > 0) { requestConfig.params = { ...(requestConfig.params || {}), ...queryParams }; } // Ejecutar la petición según el método let response; // Los métodos que no aceptan cuerpo en la petición if (method === 'GET' || method === 'HEAD' || method === 'OPTIONS' || method === 'DELETE') { // Para DELETE podríamos querer enviar datos en el cuerpo si es necesario if (method === 'DELETE' && data) { // Aunque no es estándar, algunas APIs aceptan body en DELETE requestConfig.data = data; } response = await this.httpClient.request(requestConfig); } else { // Métodos que aceptan cuerpo (POST, PUT, PATCH) requestConfig.data = data; response = await this.httpClient.request(requestConfig); } // Procesar la respuesta let processedResponse = await this.processResponse(response); // Aplicar transformador personalizado si se proporciona if (responseTransformer && processedResponse.succeeded) { try { const transformedData = responseTransformer(processedResponse.data); processedResponse = { ...processedResponse, data: transformedData }; } catch (transformError) { return { data: {}, succeeded: false, message: `Error al transformar la respuesta: ${transformError instanceof Error ? transformError.message : 'Error desconocido'}`, details: transformError instanceof Error ? transformError.stack || '' : '', httpStatusCode: processedResponse.httpStatusCode }; } } return processedResponse; } catch (error) { return this.handleRequestError(error); } } /** * Procesa la respuesta HTTP y la convierte en ApiResponse * @param {AxiosResponse} response - Respuesta HTTP original * @returns {ApiResponse<T>} Respuesta procesada * @template T - Tipo de datos esperado * @private */ async processResponse(response) { // Si la respuesta ya es un ApiResponse, lo retornamos con el tipo correcto if (response.data && typeof response.data === 'object' && 'succeeded' in response.data && 'data' in response.data) { // La respuesta es un ApiResponse<T> const apiResponse = response.data; // Aseguramos que el httpStatusCode refleje el status de la respuesta HTTP return { ...apiResponse, httpStatusCode: response.status }; } // La respuesta no es un ApiResponse, la encapsulamos return { data: response.data, succeeded: true, message: '', details: '', httpStatusCode: response.status }; } /** * Maneja los errores de las peticiones HTTP * @param {unknown} error - Error capturado * @returns {ApiResponse<T>} Respuesta de error estandarizada * @template T - Tipo de datos esperado * @private */ handleRequestError(error) { var _a, _b, _c, _d; const axiosError = error; // Extraer datos de respuesta const responseData = (_a = axiosError.response) === null || _a === void 0 ? void 0 : _a.data; // Revisar si es un ProblemDetails según RFC 9457 if (responseData && typeof responseData === 'object' && 'type' in responseData && 'title' in responseData && 'status' in responseData) { const problemDetails = responseData; return { data: {}, succeeded: false, message: problemDetails.title, details: problemDetails.detail || JSON.stringify(problemDetails), httpStatusCode: ((_b = axiosError.response) === null || _b === void 0 ? void 0 : _b.status) || 500 }; } // Revisar si es un ApiResponse<ValidationFailure[]> para errores 400 if (((_c = axiosError.response) === null || _c === void 0 ? void 0 : _c.status) === 400 && responseData && typeof responseData === 'object' && 'data' in responseData && Array.isArray(responseData.data)) { const apiResponse = responseData; // Si hay errores de validación, extraer el primer mensaje if (apiResponse.data && apiResponse.data.length > 0) { const firstFailure = apiResponse.data[0]; return { data: {}, succeeded: false, message: firstFailure.errorMessage, details: JSON.stringify(apiResponse.data), httpStatusCode: 400 }; } } // Respuesta de error genérica return { data: {}, succeeded: false, message: axiosError.message || 'Ocurrió un error en la comunicación con el servidor', details: JSON.stringify(responseData || {}), httpStatusCode: ((_d = axiosError.response) === null || _d === void 0 ? void 0 : _d.status) || 500 }; } /** * Realiza una petición GET a la API * @param {string} endpoint - Punto final de la API * @param {AxiosRequestConfig} [config] - Configuración adicional para la petición * @returns {Promise<ApiResponse<T>>} Respuesta de la API * @template T - Tipo de datos esperado en la respuesta */ async getAsync(endpoint, config) { return this.executeRequest('GET', endpoint, { config }); } /** * Realiza una petición GET por ID a la API * @param {string} endpoint - Punto final de la API con ID * @param {AxiosRequestConfig} [config] - Configuración adicional para la petición * @returns {Promise<ApiResponse<T>>} Respuesta de la API * @template T - Tipo de datos esperado en la respuesta */ async getByIdAsync(endpoint, config) { return this.executeRequest('GET', endpoint, { config }); } /** * Realiza una petición POST a la API * @param {string} endpoint - Punto final de la API * @param {TData} data - Datos a enviar en la petición * @param {AxiosRequestConfig} [config] - Configuración adicional para la petición * @returns {Promise<ApiResponse<T>>} Respuesta de la API * @template T - Tipo de datos esperado en la respuesta * @template TData - Tipo de datos a enviar en la petición */ async postAsync(endpoint, data, config) { return this.executeRequest('POST', endpoint, { data, config }); } /** * Realiza una petición PUT a la API * @param {string} endpoint - Punto final de la API * @param {TData} data - Datos a enviar en la petición * @param {AxiosRequestConfig} [config] - Configuración adicional para la petición * @returns {Promise<ApiResponse<T>>} Respuesta de la API * @template T - Tipo de datos esperado en la respuesta * @template TData - Tipo de datos a enviar en la petición */ async putAsync(endpoint, data, config) { return this.executeRequest('PUT', endpoint, { data, config }); } /** * Realiza una petición DELETE a la API * @param {string} endpoint - Punto final de la API * @param {AxiosRequestConfig} [config] - Configuración adicional para la petición * @returns {Promise<ApiResponse<boolean>>} Respuesta de la API */ async deleteAsync(endpoint, config) { return this.executeRequest('DELETE', endpoint, { config }); } /** * Realiza una petición PATCH a la API * @param {string} endpoint - Punto final de la API * @param {TData} data - Datos a enviar en la petición * @param {AxiosRequestConfig} [config] - Configuración adicional para la petición * @returns {Promise<ApiResponse<T>>} Respuesta de la API * @template T - Tipo de datos esperado en la respuesta * @template TData - Tipo de datos a enviar en la petición */ async patchAsync(endpoint, data, config) { return this.executeRequest('PATCH', endpoint, { data, config }); } } exports.FiscalapiHttpClient = FiscalapiHttpClient; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlzY2FsYXBpLWh0dHAtY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2h0dHAvZmlzY2FsYXBpLWh0dHAtY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQVdBOztHQUVHO0FBQ0gsTUFBYSxtQkFBbUI7SUFJOUI7Ozs7T0FJRztJQUNILFlBQVksVUFBeUIsRUFBRSxRQUEyQjtRQUNoRSxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM3QixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUV6Qix5REFBeUQ7UUFDekQsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1FBQ2hDLENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssc0JBQXNCO1FBQzVCLDhCQUE4QjtRQUM5QixJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBa0MsRUFBRSxFQUFFO1lBQzlFLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEIsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQyxDQUFDLENBQUM7UUFFSCw4QkFBOEI7UUFDOUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FDdkMsQ0FBQyxRQUF1QixFQUFFLEVBQUU7WUFDMUIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUMzQixPQUFPLFFBQVEsQ0FBQztRQUNsQixDQUFDLEVBQ0QsQ0FBQyxLQUFpQixFQUFFLEVBQUU7WUFDcEIsSUFBSSxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ25CLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ25DLENBQUM7WUFDRCxPQUFPLE9BQU8s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QUUsQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILEtBQUssQ0FBQyxTQUFTLENBQ2IsUUFBZ0IsRUFDaEIsSUFBVyxFQUNYLE1BQTJCO1FBRTNCLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBVyxNQUFNLEVBQUUsUUFBUSxFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDM0UsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLFFBQVEsQ0FDWixRQUFnQixFQUNoQixJQUFXLEVBQ1gsTUFBMkI7UUFFM0IsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFXLEtBQUssRUFBRSxRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUMxRSxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsV0FBVyxDQUNmLFFBQWdCLEVBQ2hCLE1BQTJCO1FBRTNCLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBVSxRQUFRLEVBQUUsUUFBUSxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSCxLQUFLLENBQUMsVUFBVSxDQUNkLFFBQWdCLEVBQ2hCLElBQVcsRUFDWCxNQUEyQjtRQUUzQixPQUFPLElBQUksQ0FBQyxjQUFjLENBQVcsT0FBTyxFQUFFLFFBQVEsRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQzVFLENBQUM7Q0FDRjtBQXRXRCxrREFzV0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBcbiAgQXhpb3NJbnN0YW5jZSwgXG4gIEF4aW9zRXJyb3IsIFxuICBBeGlvc1Jlc3BvbnNlLCBcbiAgQXhpb3NSZXF1ZXN0Q29uZmlnLFxuICBJbnRlcm5hbEF4aW9zUmVxdWVzdENvbmZpZ1xufSBmcm9tICdheGlvcyc7XG5pbXBvcnQgeyBGaXNjYWxhcGlTZXR0aW5ncyB9IGZyb20gJy4vLi4vY29tbW9uL2Zpc2NhbGFwaS1zZXR0aW5ncyc7XG5pbXBvcnQgeyBJRmlzY2FsYXBpSHR0cENsaWVudCwgSHR0cE1ldGhvZCwgUmVxdWVzdE9wdGlvbnMgfSBmcm9tICcuL2Zpc2NhbGFwaS1odHRwLWNsaWVudC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgQXBpUmVzcG9uc2UsIFByb2JsZW1EZXRhaWxzLCBWYWxpZGF0aW9uRmFpbHVyZSB9IGZyb20gJy4uL2NvbW1vbi9hcGktcmVzcG9uc2UnO1xuXG4vKipcbiAqIENsaWVudGUgSFRUUCBwYXJhIEZpc2NhbEFQSVxuICovXG5leHBvcnQgY2xhc3MgRmlzY2FsYXBpSHR0cENsaWVudCBpbXBsZW1lbnRzIElGaXNjYWxhcGlIdHRwQ2xpZW50IHtcbiAgcHJpdmF0ZSByZWFkb25seSBodHRwQ2xpZW50OiBBeGlvc0luc3RhbmNlO1xuICBwcml2YXRlIHJlYWRvbmx5IHNldHRpbmdzOiBGaXNjYWxhcGlTZXR0aW5ncztcblxuICAvKipcbiAgICogQ3JlYSB1bmEgbnVldmEgaW5zdGFuY2lhIGRlbCBjbGllbnRlIEhUVFAgcGFyYSBGaXNjYWxBUElcbiAgICogQHBhcmFtIHtBeGlvc0luc3RhbmNlfSBodHRwQ2xpZW50IC0gSW5zdGFuY2lhIGRlIEF4aW9zIGNvbmZpZ3VyYWRhXG4gICAqIEBwYXJhbSB7RmlzY2FsYXBpU2V0dGluZ3N9IHNldHRpbmdzIC0gQ29uZmlndXJhY2nDs24gcGFyYSBlbCBjbGllbnRlIEZpc2NhbEFQSVxuICAgKi9cbiAgY29uc3RydWN0b3IoaHR0cENsaWVudDogQXhpb3NJbnN0YW5jZSwgc2V0dGluZ3M6IEZpc2NhbGFwaVNldHRpbmdzKSB7XG4gICAgdGhpcy5odHRwQ2xpZW50ID0gaHR0cENsaWVudDtcbiAgICB0aGlzLnNldHRpbmdzID0gc2V0dGluZ3M7XG5cbiAgICAvLyBDb25maWd1cmFyIGludGVyY2VwdG9yZXMgcGFyYSBlbCBsb2dnaW5nIGVuIG1vZG8gZGVidWdcbiAgICBpZiAodGhpcy5zZXR0aW5ncy5kZWJ1Zykge1xuICAgICAgdGhpcy5zZXR1cERlYnVnSW50ZXJjZXB0b3JzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbmZpZ3VyYSBsb3MgaW50ZXJjZXB0b3JlcyBwYXJhIGxvZ2VhciBsYXMgcGV0aWNpb25lcyB5IHJlc3B1ZXN0YXMgZW4gbW9kbyBkZWJ1Z1xuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBzZXR1cERlYnVnSW50ZXJjZXB0b3JzKCk6IHZvaWQge1xuICAgIC8vIEludGVyY2VwdG9yIHBhcmEgcGV0aWNpb25lc1xuICAgIHRoaXMuaHR0cENsaWVudC5pbnRlcmNlcHRvcnMucmVxdWVzdC51c2UoKGNvbmZpZzogSW50ZXJuYWxBeGlvc1JlcXVlc3RDb25maWcpID0+IHtcbiAgICAgIHRoaXMubG9nUmVxdWVzdChjb25maWcpO1xuICAgICAgcmV0dXJuIGNvbmZpZztcbiAgICB9KTtcblxuICAgIC8vIEludGVyY2VwdG9yIHBhcmEgcmVzcHVlc3Rhc1xuICAgIHRoaXMuaHR0cENsaWVudC5pbnRlcmNlcHRvcnMucmVzcG9uc2UudXNlKFxuICAgICAgKHJlc3BvbnNlOiBBeGlvc1Jlc3BvbnNlKSA9PiB7XG4gICAgICAgIHRoaXMubG9nUmVzcG9uc2UocmVzcG9uc2UpO1xuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICB9LFxuICAgICAgKGVycm9yOiBBeGlvc0Vycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvci5yZXNwb25zZSkge1xuICAgICAgICAgIHRoaXMubG9nUmVzcG9uc2UoZXJyb3IucmVzcG9uc2UpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcik7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2dlYSBsb3MgZGV0YWxsZXMgZGUgdW5hIHBldGljacOzbiBIVFRQIGN1YW5kbyBlbCBtb2RvIGRlYnVnIGVzdMOhIGFjdGl2YWRvXG4gICAqIEBwYXJhbSB7SW50ZXJuYWxBeGlvc1JlcXVlc3RDb25maWd9IGNvbmZpZyAtIENvbmZpZ3VyYWNpw7NuIGRlIGxhIHBldGljacOzblxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBsb2dSZXF1ZXN0KGNvbmZpZzogSW50ZXJuYWxBeGlvc1JlcXVlc3RDb25maWcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zZXR0aW5ncy5kZWJ1Zykge1xuICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgY29uc29sZS5sb2coJyoqKioqKioqKioqKioqKioqKioqKiogUmF3IFJlcXVlc3QgKioqKioqKioqKioqKioqKioqKioqKioqKionKTtcbiAgICAgIFxuICAgICAgY29uc29sZS5sb2coJ01ldGhvZDogJywgIGNvbmZpZy5tZXRob2Q/LnRvVXBwZXJDYXNlKCkpO1xuICAgICAgY29uc29sZS5sb2coJ0Jhc2VVUkw6ICcsIGNvbmZpZy5iYXNlVVJMKTtcbiAgICAgIGNvbnNvbGUubG9nKCdQYXRoVVJMOiAnLCBjb25maWcudXJsKTtcbiAgICAgIGNvbnN0IHJlc291cmNlID0gYCR7Y29uZmlnLmJhc2VVUkwgfHwgJyd9LyR7Y29uZmlnLnVybCB8fCAnJ31gO1xuICAgICAgY29uc29sZS5sb2coJ0Z1bGxVUkw6ICcsIHJlc291cmNlKTtcbiAgICAgIFxuICAgICAgaWYgKGNvbmZpZy5kYXRhKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdCb2R5OicsIHR5cGVvZiBjb25maWcuZGF0YSA9PT0gJ3N0cmluZycgPyBjb25maWcuZGF0YSA6IEpTT04uc3RyaW5naWZ5KGNvbmZpZy5kYXRhLCBudWxsLCAyKSk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgIFxuICAgICAgaWYgKGNvbmZpZy5wYXJhbXMpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1BhcmFtczonLCBjb25maWcucGFyYW1zKTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgY29uc29sZS5sb2coJycpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBMb2dlYSBsb3MgZGV0YWxsZXMgZGUgdW5hIHJlc3B1ZXN0YSBIVFRQIGN1YW5kbyBlbCBtb2RvIGRlYnVnIGVzdMOhIGFjdGl2YWRvXG4gICAqIEBwYXJhbSB7QXhpb3NSZXNwb25zZX0gcmVzcG9uc2UgLSBSZXNwdWVzdGEgZGUgbGEgcGV0aWNpw7NuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGxvZ1Jlc3BvbnNlKHJlc3BvbnNlOiBBeGlvc1Jlc3BvbnNlKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2V0dGluZ3MuZGVidWcpIHtcbiAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgIGNvbnNvbGUubG9nKCcqKioqKioqKioqKioqKioqKioqKioqIFJhdyBSZXNwb25zZSAqKioqKioqKioqKioqKioqKioqKioqKioqKicpO1xuICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgY29uc29sZS5sb2coJ1N0YXR1czonLCByZXNwb25zZS5zdGF0dXMsIHJlc3BvbnNlLnN0YXR1c1RleHQpO1xuICAgICAgLy9jb25zb2xlLmxvZygnSGVhZGVyczonLCByZXNwb25zZS5oZWFkZXJzKTtcbiAgICAgIGNvbnNvbGUubG9nKCdEYXRhOicsIEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlLmRhdGEsIG51bGwsIDIpKTtcblxuICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgY29uc29sZS5sb2coJyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKionKTtcbiAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRWplY3V0YSB1bmEgcGV0aWNpw7NuIEhUVFAgZ2Vuw6lyaWNhIGNvbiBjb250cm9sIGNvbXBsZXRvIHNvYnJlIGxvcyBwYXLDoW1ldHJvc1xuICAgKiBAcGFyYW0ge0h0dHBNZXRob2R9IG1ldGhvZCAtIE3DqXRvZG8gSFRUUCBhIHV0aWxpemFyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBlbmRwb2ludCAtIFB1bnRvIGZpbmFsIGRlIGxhIEFQSVxuICAgKiBAcGFyYW0ge1JlcXVlc3RPcHRpb25zPFREYXRhPn0gb3B0aW9ucyAtIE9wY2lvbmVzIGRlIGxhIHBldGljacOzblxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxBcGlSZXNwb25zZTxUUmVzdWx0Pj59IFJlc3B1ZXN0YSBkZSBsYSBBUElcbiAgICogQHRlbXBsYXRlIFRSZXN1bHQgLSBUaXBvIGRlIGRhdG9zIGVzcGVyYWRvIGVuIGxhIHJlc3B1ZXN0YVxuICAgKiBAdGVtcGxhdGUgVERhdGEgLSBUaXBvIGRlIGRhdG9zIGEgZW52aWFyIGVuIGxhIHBldGljacOzbiAob3BjaW9uYWwpXG4gICAqL1xuICBhc3luYyBleGVjdXRlUmVxdWVzdDxUUmVzdWx0LCBURGF0YSA9IGFueT4oXG4gICAgbWV0aG9kOiBIdHRwTWV0aG9kLFxuICAgIGVuZHBvaW50OiBzdHJpbmcsXG4gICAgb3B0aW9uczogUmVxdWVzdE9wdGlvbnM8VERhdGE+ID0ge31cbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxUUmVzdWx0Pj4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBFeHRyYWVyIG9wY2lvbmVzXG4gICAgICBjb25zdCB7IGRhdGEsIHF1ZXJ5UGFyYW1zLCBjb25maWcgPSB7fSwgcmVzcG9uc2VUcmFuc2Zvcm1lciB9ID0gb3B0aW9ucztcbiAgICAgIFxuICAgICAgLy8gQ29uc3RydWlyIGNvbmZpZ3VyYWNpw7NuIGRlIGxhIHBldGljacOzblxuICAgICAgY29uc3QgcmVxdWVzdENvbmZpZzogQXhpb3NSZXF1ZXN0Q29uZmlnID0ge1xuICAgICAgICAuLi5jb25maWcsXG4gICAgICAgIG1ldGhvZCxcbiAgICAgICAgdXJsOiBlbmRwb2ludFxuICAgICAgfTtcbiAgICAgIFxuICAgICAgLy8gQcOxYWRpciBwYXLDoW1ldHJvcyBkZSBjb25zdWx0YSBzaSBleGlzdGVuXG4gICAgICBpZiAocXVlcnlQYXJhbXMgJiYgT2JqZWN0LmtleXMocXVlcnlQYXJhbXMpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmVxdWVzdENvbmZpZy5wYXJhbXMgPSB7XG4gICAgICAgICAgLi4uKHJlcXVlc3RDb25maWcucGFyYW1zIHx8IHt9KSxcbiAgICAgICAgICAuLi5xdWVyeVBhcmFtc1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBFamVjdXRhciBsYSBwZXRpY2nDs24gc2Vnw7puIGVsIG3DqXRvZG9cbiAgICAgIGxldCByZXNwb25zZTogQXhpb3NSZXNwb25zZTtcbiAgICAgIFxuICAgICAgLy8gTG9zIG3DqXRvZG9zIHF1ZSBubyBhY2VwdGFuIGN1ZXJwbyBlbiBsYSBwZXRpY2nDs25cbiAgICAgIGlmIChtZXRob2QgPT09ICdHRVQnIHx8IG1ldGhvZCA9PT0gJ0hFQUQnIHx8IG1ldGhvZCA9PT0gJ09QVElPTlMnIHx8IG1ldGhvZCA9PT0gJ0RFTEVURScpIHtcbiAgICAgICAgLy8gUGFyYSBERUxFVEUgcG9kcsOtYW1vcyBxdWVyZXIgZW52aWFyIGRhdG9zIGVuIGVsIGN1ZXJwbyBzaSBlcyBuZWNlc2FyaW9cbiAgICAgICAgaWYgKG1ldGhvZCA9PT0gJ0RFTEVURScgJiYgZGF0YSkge1xuICAgICAgICAgIC8vIEF1bnF1ZSBubyBlcyBlc3TDoW5kYXIsIGFsZ3VuYXMgQVBJcyBhY2VwdGFuIGJvZHkgZW4gREVMRVRFXG4gICAgICAgICAgcmVxdWVzdENvbmZpZy5kYXRhID0gZGF0YTtcbiAgICAgICAgfVxuICAgICAgICByZXNwb25zZSA9IGF3YWl0IHRoaXMuaHR0cENsaWVudC5yZXF1ZXN0KHJlcXVlc3RDb25maWcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gTcOpdG9kb3MgcXVlIGFjZXB0YW4gY3VlcnBvIChQT1NULCBQVVQsIFBBVENIKVxuICAgICAgICByZXF1ZXN0Q29uZmlnLmRhdGEgPSBkYXRhO1xuICAgICAgICByZXNwb25zZSA9IGF3YWl0IHRoaXMuaHR0cENsaWVudC5yZXF1ZXN0KHJlcXVlc3RDb25maWcpO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBQcm9jZXNhciBsYSByZXNwdWVzdGFcbiAgICAgIGxldCBwcm9jZXNzZWRSZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvY2Vzc1Jlc3BvbnNlPFRSZXN1bHQ+KHJlc3BvbnNlKTtcbiAgICAgIFxuICAgICAgLy8gQXBsaWNhciB0cmFuc2Zvcm1hZG9yIHBlcnNvbmFsaXphZG8gc2kgc2UgcHJvcG9yY2lvbmFcbiAgICAgIGlmIChyZXNwb25zZVRyYW5zZm9ybWVyICYmIHByb2Nlc3NlZFJlc3BvbnNlLnN1Y2NlZWRlZCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHRyYW5zZm9ybWVkRGF0YSA9IHJlc3BvbnNlVHJhbnNmb3JtZXIocHJvY2Vzc2VkUmVzcG9uc2UuZGF0YSk7XG4gICAgICAgICAgcHJvY2Vzc2VkUmVzcG9uc2UgPSB7XG4gICAgICAgICAgICAuLi5wcm9jZXNzZWRSZXNwb25zZSxcbiAgICAgICAgICAgIGRhdGE6IHRyYW5zZm9ybWVkRGF0YSBhcyBUUmVzdWx0XG4gICAgICAgICAgfTtcbiAgICAgICAgfSBjYXRjaCAodHJhbnNmb3JtRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZGF0YToge30gYXMgVFJlc3VsdCxcbiAgICAgICAgICAgIHN1Y2NlZWRlZDogZmFsc2UsXG4gICAgICAgICAgICBtZXNzYWdlOiBgRXJyb3IgYWwgdHJhbnNmb3JtYXIgbGEgcmVzcHVlc3RhOiAke3RyYW5zZm9ybUVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyB0cmFuc2Zvcm1FcnJvci5tZXNzYWdlIDogJ0Vycm9yIGRlc2Nvbm9jaWRvJ31gLFxuICAgICAgICAgICAgZGV0YWlsczogdHJhbnNmb3JtRXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IHRyYW5zZm9ybUVycm9yLnN0YWNrIHx8ICcnIDogJycsXG4gICAgICAgICAgICBodHRwU3RhdHVzQ29kZTogcHJvY2Vzc2VkUmVzcG9uc2UuaHR0cFN0YXR1c0NvZGVcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBcbiAgICAgIHJldHVybiBwcm9jZXNzZWRSZXNwb25zZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlUmVxdWVzdEVycm9yPFRSZXN1bHQ+KGVycm9yKTtcbiAgICB9XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBQcm9jZXNhIGxhIHJlc3B1ZXN0YSBIVFRQIHkgbGEgY29udmllcnRlIGVuIEFwaVJlc3BvbnNlXG4gICAqIEBwYXJhbSB7QXhpb3NSZXNwb25zZX0gcmVzcG9uc2UgLSBSZXNwdWVzdGEgSFRUUCBvcmlnaW5hbFxuICAgKiBAcmV0dXJucyB7QXBpUmVzcG9uc2U8VD59IFJlc3B1ZXN0YSBwcm9jZXNhZGFcbiAgICogQHRlbXBsYXRlIFQgLSBUaXBvIGRlIGRhdG9zIGVzcGVyYWRvXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHByb2Nlc3NSZXNwb25zZTxUPihyZXNwb25zZTogQXhpb3NSZXNwb25zZSk6IFByb21pc2U8QXBpUmVzcG9uc2U8VD4+IHtcbiAgICAvLyBTaSBsYSByZXNwdWVzdGEgeWEgZXMgdW4gQXBpUmVzcG9uc2UsIGxvIHJldG9ybmFtb3MgY29uIGVsIHRpcG8gY29ycmVjdG9cbiAgICBpZiAoXG4gICAgICByZXNwb25zZS5kYXRhICYmIFxuICAgICAgdHlwZW9mIHJlc3BvbnNlLmRhdGEgPT09ICdvYmplY3QnICYmIFxuICAgICAgJ3N1Y2NlZWRlZCcgaW4gcmVzcG9uc2UuZGF0YSAmJiBcbiAgICAgICdkYXRhJyBpbiByZXNwb25zZS5kYXRhXG4gICAgKSB7XG4gICAgICAvLyBMYSByZXNwdWVzdGEgZXMgdW4gQXBpUmVzcG9uc2U8VD5cbiAgICAgIGNvbnN0IGFwaVJlc3BvbnNlID0gcmVzcG9uc2UuZGF0YSBhcyB1bmtub3duIGFzIEFwaVJlc3BvbnNlPFQ+O1xuICAgICAgXG4gICAgICAvLyBBc2VndXJhbW9zIHF1ZSBlbCBodHRwU3RhdHVzQ29kZSByZWZsZWplIGVsIHN0YXR1cyBkZSBsYSByZXNwdWVzdGEgSFRUUFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uYXBpUmVzcG9uc2UsXG4gICAgICAgIGh0dHBTdGF0dXNDb2RlOiByZXNwb25zZS5zdGF0dXNcbiAgICAgIH07XG4gICAgfVxuICAgIFxuICAgIC8vIExhIHJlc3B1ZXN0YSBubyBlcyB1biBBcGlSZXNwb25zZSwgbGEgZW5jYXBzdWxhbW9zXG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGE6IHJlc3BvbnNlLmRhdGEgYXMgdW5rbm93biBhcyBULFxuICAgICAgc3VjY2VlZGVkOiB0cnVlLFxuICAgICAgbWVzc2FnZTogJycsXG4gICAgICBkZXRhaWxzOiAnJyxcbiAgICAgIGh0dHBTdGF0dXNDb2RlOiByZXNwb25zZS5zdGF0dXNcbiAgICB9O1xuICB9XG4gIFxuICAvKipcbiAgICogTWFuZWphIGxvcyBlcnJvcmVzIGRlIGxhcyBwZXRpY2lvbmVzIEhUVFBcbiAgICogQHBhcmFtIHt1bmtub3dufSBlcnJvciAtIEVycm9yIGNhcHR1cmFkb1xuICAgKiBAcmV0dXJucyB7QXBpUmVzcG9uc2U8VD59IFJlc3B1ZXN0YSBkZSBlcnJvciBlc3RhbmRhcml6YWRhXG4gICAqIEB0ZW1wbGF0ZSBUIC0gVGlwbyBkZSBkYXRvcyBlc3BlcmFkb1xuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBoYW5kbGVSZXF1ZXN0RXJyb3I8VD4oZXJyb3I6IHVua25vd24pOiBBcGlSZXNwb25zZTxUPiB7XG4gICAgY29uc3QgYXhpb3NFcnJvciA9IGVycm9yIGFzIEF4aW9zRXJyb3I7XG4gICAgXG4gICAgLy8gRXh0cmFlciBkYXRvcyBkZSByZXNwdWVzdGFcbiAgICBjb25zdCByZXNwb25zZURhdGEgPSBheGlvc0Vycm9yLnJlc3BvbnNlPy5kYXRhO1xuICAgIFxuICAgIC8vIFJldmlzYXIgc2kgZXMgdW4gUHJvYmxlbURldGFpbHMgc2Vnw7puIFJGQyA5NDU3XG4gICAgaWYgKFxuICAgICAgcmVzcG9uc2VEYXRhICYmIFxuICAgICAgdHlwZW9mIHJlc3BvbnNlRGF0YSA9PT0gJ29iamVjdCcgJiYgXG4gICAgICAndHlwZScgaW4gcmVzcG9uc2VEYXRhICYmIFxuICAgICAgJ3RpdGxlJyBpbiByZXNwb25zZURhdGEgJiZcbiAgICAgICdzdGF0dXMnIGluIHJlc3BvbnNlRGF0YVxuICAgICkge1xuICAgICAgY29uc3QgcHJvYmxlbURldGFpbHMgPSByZXNwb25zZURhdGEgYXMgUHJvYmxlbURldGFpbHM7XG4gICAgICBcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRhdGE6IHt9IGFzIFQsXG4gICAgICAgIHN1Y2NlZWRlZDogZmFsc2UsXG4gICAgICAgIG1lc3NhZ2U6IHByb2JsZW1EZXRhaWxzLnRpdGxlLFxuICAgICAgICBkZXRhaWxzOiBwcm9ibGVtRGV0YWlscy5kZXRhaWwgfHwgSlNPTi5zdHJpbmdpZnkocHJvYmxlbURldGFpbHMpLFxuICAgICAgICBodHRwU3RhdHVzQ29kZTogYXhpb3NFcnJvci5yZXNwb25zZT8uc3RhdHVzIHx8IDUwMFxuICAgICAgfTtcbiAgICB9XG4gICAgXG4gICAgLy8gUmV2aXNhciBzaSBlcyB1biBBcGlSZXNwb25zZTxWYWxpZGF0aW9uRmFpbHVyZVtdPiBwYXJhIGVycm9yZXMgNDAwXG4gICAgaWYgKFxuICAgICAgYXhpb3NFcnJvci5yZXNwb25zZT8uc3RhdHVzID09PSA0MDAgJiZcbiAgICAgIHJlc3BvbnNlRGF0YSAmJlxuICAgICAgdHlwZW9mIHJlc3BvbnNlRGF0YSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICdkYXRhJyBpbiByZXNwb25zZURhdGEgJiZcbiAgICAgIEFycmF5LmlzQXJyYXkocmVzcG9uc2VEYXRhLmRhdGEpXG4gICAgKSB7XG4gICAgICBjb25zdCBhcGlSZXNwb25zZSA9IHJlc3BvbnNlRGF0YSBhcyBBcGlSZXNwb25zZTxWYWxpZGF0aW9uRmFpbHVyZVtdPjtcbiAgICAgIFxuICAgICAgLy8gU2kgaGF5IGVycm9yZXMgZGUgdmFsaWRhY2nDs24sIGV4dHJhZXIgZWwgcHJpbWVyIG1lbnNhamVcbiAgICAgIGlmIChhcGlSZXNwb25zZS5kYXRhICYmIGFwaVJlc3BvbnNlLmRhdGEubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBmaXJzdEZhaWx1cmUgPSBhcGlSZXNwb25zZS5kYXRhWzBdO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGRhdGE6IHt9IGFzIFQsXG4gICAgICAgICAgc3VjY2VlZGVkOiBmYWxzZSxcbiAgICAgICAgICBtZXNzYWdlOiBmaXJzdEZhaWx1cmUuZXJyb3JNZXNzYWdlLFxuICAgICAgICAgIGRldGFpbHM6IEpTT04uc3RyaW5naWZ5KGFwaVJlc3BvbnNlLmRhdGEpLFxuICAgICAgICAgIGh0dHBTdGF0dXNDb2RlOiA0MDBcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgLy8gUmVzcHVlc3RhIGRlIGVycm9yIGdlbsOpcmljYVxuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiB7fSBhcyBULFxuICAgICAgc3VjY2VlZGVkOiBmYWxzZSxcbiAgICAgIG1lc3NhZ2U6IGF4aW9zRXJyb3IubWVzc2FnZSB8fCAnT2N1cnJpw7MgdW4gZXJyb3IgZW4gbGEgY29tdW5pY2FjacOzbiBjb24gZWwgc2Vydmlkb3InLFxuICAgICAgZGV0YWlsczogSlNPTi5zdHJpbmdpZnkocmVzcG9uc2VEYXRhIHx8IHt9KSxcbiAgICAgIGh0dHBTdGF0dXNDb2RlOiBheGlvc0Vycm9yLnJlc3BvbnNlPy5zdGF0dXMgfHwgNTAwXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFsaXphIHVuYSBwZXRpY2nDs24gR0VUIGEgbGEgQVBJXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBlbmRwb2ludCAtIFB1bnRvIGZpbmFsIGRlIGxhIEFQSVxuICAgKiBAcGFyYW0ge0F4aW9zUmVxdWVzdENvbmZpZ30gW2NvbmZpZ10gLSBDb25maWd1cmFjacOzbiBhZGljaW9uYWwgcGFyYSBsYSBwZXRpY2nDs25cbiAgICogQHJldHVybnMge1Byb21pc2U8QXBpUmVzcG9uc2U8VD4+fSBSZXNwdWVzdGEgZGUgbGEgQVBJXG4gICAqIEB0ZW1wbGF0ZSBUIC0gVGlwbyBkZSBkYXRvcyBlc3BlcmFkbyBlbiBsYSByZXNwdWVzdGFcbiAgICovXG4gIGFzeW5jIGdldEFzeW5jPFQ+KGVuZHBvaW50OiBzdHJpbmcsIGNvbmZpZz86IEF4aW9zUmVxdWVzdENvbmZpZyk6IFByb21pc2U8QXBpUmVzcG9uc2U8VD4+IHtcbiAgICByZXR1cm4gdGhpcy5leGVjdXRlUmVxdWVzdDxUPignR0VUJywgZW5kcG9pbnQsIHsgY29uZmlnIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWxpemEgdW5hIHBldGljacOzbiBHRVQgcG9yIElEIGEgbGEgQVBJXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBlbmRwb2ludCAtIFB1bnRvIGZpbmFsIGRlIGxhIEFQSSBjb24gSURcbiAgICogQHBhcmFtIHtBeGlvc1JlcXVlc3RDb25maWd9IFtjb25maWddIC0gQ29uZmlndXJhY2nDs24gYWRpY2lvbmFsIHBhcmEgbGEgcGV0aWNpw7NuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEFwaVJlc3BvbnNlPFQ+Pn0gUmVzcHVlc3RhIGRlIGxhIEFQSVxuICAgKiBAdGVtcGxhdGUgVCAtIFRpcG8gZGUgZGF0b3MgZXNwZXJhZG8gZW4gbGEgcmVzcHVlc3RhXG4gICAqL1xuICBhc3luYyBnZXRCeUlkQXN5bmM8VD4oZW5kcG9pbnQ6IHN0cmluZywgY29uZmlnPzogQXhpb3NSZXF1ZXN0Q29uZmlnKTogUHJvbWlzZTxBcGlSZXNwb25zZTxUPj4ge1xuICAgIHJldHVybiB0aGlzLmV4ZWN1dGVSZXF1ZXN0PFQ+KCdHRVQnLCBlbmRwb2ludCwgeyBjb25maWcgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVhbGl6YSB1bmEgcGV0aWNpw7NuIFBPU1QgYSBsYSBBUElcbiAgICogQHBhcmFtIHtzdHJpbmd9IGVuZHBvaW50IC0gUHVudG8gZmluYWwgZGUgbGEgQVBJXG4gICAqIEBwYXJhbSB7VERhdGF9IGRhdGEgLSBEYXRvcyBhIGVudmlhciBlbiBsYSBwZXRpY2nDs25cbiAgICogQHBhcmFtIHtBeGlvc1JlcXVlc3RDb25maWd9IFtjb25maWddIC0gQ29uZmlndXJhY2nDs24gYWRpY2lvbmFsIHBhcmEgbGEgcGV0aWNpw7NuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEFwaVJlc3BvbnNlPFQ+Pn0gUmVzcHVlc3RhIGRlIGxhIEFQSVxuICAgKiBAdGVtcGxhdGUgVCAtIFRpcG8gZGUgZGF0b3MgZXNwZXJhZG8gZW4gbGEgcmVzcHVlc3RhXG4gICAqIEB0ZW1wbGF0ZSBURGF0YSAtIFRpcG8gZGUgZGF0b3MgYSBlbnZpYXIgZW4gbGEgcGV0aWNpw7NuXG4gICAqL1xuICBhc3luYyBwb3N0QXN5bmM8VCwgVERhdGEgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oXG4gICAgZW5kcG9pbnQ6IHN0cmluZywgXG4gICAgZGF0YTogVERhdGEsIFxuICAgIGNvbmZpZz86IEF4aW9zUmVxdWVzdENvbmZpZ1xuICApOiBQcm9taXNlPEFwaVJlc3BvbnNlPFQ+PiB7XG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0ZVJlcXVlc3Q8VCwgVERhdGE+KCdQT1NUJywgZW5kcG9pbnQsIHsgZGF0YSwgY29uZmlnIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWxpemEgdW5hIHBldGljacOzbiBQVVQgYSBsYSBBUElcbiAgICogQHBhcmFtIHtzdHJpbmd9IGVuZHBvaW50IC0gUHVudG8gZmluYWwgZGUgbGEgQVBJXG4gICAqIEBwYXJhbSB7VERhdGF9IGRhdGEgLSBEYXRvcyBhIGVudmlhciBlbiBsYSBwZXRpY2nDs25cbiAgICogQHBhcmFtIHtBeGlvc1JlcXVlc3RDb25maWd9IFtjb25maWddIC0gQ29uZmlndXJhY2nDs24gYWRpY2lvbmFsIHBhcmEgbGEgcGV0aWNpw7NuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEFwaVJlc3BvbnNlPFQ+Pn0gUmVzcHVlc3RhIGRlIGxhIEFQSVxuICAgKiBAdGVtcGxhdGUgVCAtIFRpcG8gZGUgZGF0b3MgZXNwZXJhZG8gZW4gbGEgcmVzcHVlc3RhXG4gICAqIEB0ZW1wbGF0ZSBURGF0YSAtIFRpcG8gZGUgZGF0b3MgYSBlbnZpYXIgZW4gbGEgcGV0aWNpw7NuXG4gICAqL1xuICBhc3luYyBwdXRBc3luYzxULCBURGF0YSA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+PihcbiAgICBlbmRwb2ludDogc3RyaW5nLCBcbiAgICBkYXRhOiBURGF0YSwgXG4gICAgY29uZmlnPzogQXhpb3NSZXF1ZXN0Q29uZmlnXG4gICk6IFByb21pc2U8QXBpUmVzcG9uc2U8VD4+IHtcbiAgICByZXR1cm4gdGhpcy5leGVjdXRlUmVxdWVzdDxULCBURGF0YT4oJ1BVVCcsIGVuZHBvaW50LCB7IGRhdGEsIGNvbmZpZyB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFsaXphIHVuYSBwZXRpY2nDs24gREVMRVRFIGEgbGEgQVBJXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBlbmRwb2ludCAtIFB1bnRvIGZpbmFsIGRlIGxhIEFQSVxuICAgKiBAcGFyYW0ge0F4aW9zUmVxdWVzdENvbmZpZ30gW2NvbmZpZ10gLSBDb25maWd1cmFjacOzbiBhZGljaW9uYWwgcGFyYSBsYSBwZXRpY2nDs25cbiAgICogQHJldHVybnMge1Byb21pc2U8QXBpUmVzcG9uc2U8Ym9vbGVhbj4+fSBSZXNwdWVzdGEgZGUgbGEgQVBJXG4gICAqL1xuICBhc3luYyBkZWxldGVBc3luYyhcbiAgICBlbmRwb2ludDogc3RyaW5nLCBcbiAgICBjb25maWc/OiBBeGlvc1JlcXVlc3RDb25maWdcbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxib29sZWFuPj4ge1xuICAgIHJldHVybiB0aGlzLmV4ZWN1dGVSZXF1ZXN0PGJvb2xlYW4+KCdERUxFVEUnLCBlbmRwb2ludCwgeyBjb25maWcgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVhbGl6YSB1bmEgcGV0aWNpw7NuIFBBVENIIGEgbGEgQVBJXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBlbmRwb2ludCAtIFB1bnRvIGZpbmFsIGRlIGxhIEFQSVxuICAgKiBAcGFyYW0ge1REYXRhfSBkYXRhIC0gRGF0b3MgYSBlbnZpYXIgZW4gbGEgcGV0aWNpw7NuXG4gICAqIEBwYXJhbSB7QXhpb3NSZXF1ZXN0Q29uZmlnfSBbY29uZmlnXSAtIENvbmZpZ3VyYWNpw7NuIGFkaWNpb25hbCBwYXJhIGxhIHBldGljacOzblxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxBcGlSZXNwb25zZTxUPj59IFJlc3B1ZXN0YSBkZSBsYSBBUElcbiAgICogQHRlbXBsYXRlIFQgLSBUaXBvIGRlIGRhdG9zIGVzcGVyYWRvIGVuIGxhIHJlc3B1ZXN0YVxuICAgKiBAdGVtcGxhdGUgVERhdGEgLSBUaXBvIGRlIGRhdG9zIGEgZW52aWFyIGVuIGxhIHBldGljacOzblxuICAgKi9cbiAgYXN5bmMgcGF0Y2hBc3luYzxULCBURGF0YSA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+PihcbiAgICBlbmRwb2ludDogc3RyaW5nLCBcbiAgICBkYXRhOiBURGF0YSwgXG4gICAgY29uZmlnPzogQXhpb3NSZXF1ZXN0Q29uZmlnXG4gICk6IFByb21pc2U8QXBpUmVzcG9uc2U8VD4+IHtcbiAgICByZXR1cm4gdGhpcy5leGVjdXRlUmVxdWVzdDxULCBURGF0YT4oJ1BBVENIJywgZW5kcG9pbnQsIHsgZGF0YSwgY29uZmlnIH0pO1xuICB9XG59Il19