@jufab/opentelemetry-angular-interceptor
Version:
@jufab/opentelemetry-angular-interceptor is an Angular Library to deploy [OpenTelemetry](https://opentelemetry.io/) in your Angular application
151 lines • 17.6 kB
JavaScript
import { Inject, Injectable } from '@angular/core';
import { ZoneContextManager } from '@opentelemetry/context-zone-peer-dep';
import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { AlwaysOffSampler, AlwaysOnSampler, ParentBasedSampler, TraceIdRatioBasedSampler, WebTracerProvider } from '@opentelemetry/sdk-trace-web';
import { ConsoleSpanExporter, SimpleSpanProcessor, BatchSpanProcessor, NoopSpanProcessor } from '@opentelemetry/sdk-trace-base';
// eslint-disable-next-line max-len
import { OTEL_CONFIG, OTEL_INSTRUMENTATION_PLUGINS } from '../../configuration/opentelemetry-config';
import { OTEL_EXPORTER } from '../exporter/exporter.interface';
import { OTEL_PROPAGATOR } from '../propagator/propagator.interface';
import { resourceFromAttributes } from '@opentelemetry/resources';
import * as i0 from "@angular/core";
/**
* InstrumentationService.
* Service for component to add instrumentation.
*/
export class InstrumentationService {
/**
* Constructor
*
* @param config
* @param exporterService
* @param propagatorService
*/
constructor(config, exporterService, propagatorService, instrumentation) {
this.config = config;
this.exporterService = exporterService;
this.propagatorService = propagatorService;
this.instrumentation = instrumentation;
/**
* contextManager
*/
this.contextManager = new ZoneContextManager();
this.tracerProvider = new WebTracerProvider({
sampler: this.defineProbabilitySampler(this.convertStringToNumber(this.config.commonConfig.probabilitySampler)),
resource: this.loadResourceAttributes(this.config.commonConfig),
spanProcessors: this.insertOrNotSpanExporter(this.config.commonConfig.production, this.exporterService, this.config.commonConfig.console),
});
}
/**
* Init instrumentation on init
*/
initInstrumentation() {
this.tracerProvider.register({
contextManager: this.contextManager,
propagator: this.propagatorService.getPropagator(),
});
registerInstrumentations({
instrumentations: this.instrumentation,
tracerProvider: this.tracerProvider,
});
}
/**
* Generate Resource Attributes
* @param commonConfig common configuration
* @returns Resource
*/
loadResourceAttributes(commonConfig) {
return resourceFromAttributes({
[ATTR_SERVICE_NAME]: commonConfig?.serviceName,
...commonConfig?.resourceAttributes,
});
}
/**
* Verify to insert or not a Span Exporter
* @param console config to insert console span
* @param production production mode
* @param exporter exporter
* @returns Array of SpanProcessor
*/
insertOrNotSpanExporter(production, exporter, console) {
if (this.exporterService.getExporter() !== undefined) {
return Array.of(this.insertSpanProcessorProductionMode(production, exporter), this.insertConsoleSpanExporter(console));
}
else {
return Array.of(new NoopSpanProcessor());
}
}
/**
* Insert in tracer the console span if config is true
*
* @param console config to insert console span
* @returns SpanProcessor
*/
insertConsoleSpanExporter(console) {
if (console) {
return new SimpleSpanProcessor(new ConsoleSpanExporter());
}
}
/**
* Insert BatchSpanProcessor in production mode
* SimpleSpanProcessor otherwise
*
* @param boolean production
* @param IExporter exporter
* @returns SpanProcessor
*/
insertSpanProcessorProductionMode(production, exporter) {
return production
? new BatchSpanProcessor(exporter.getExporter())
: new SimpleSpanProcessor(exporter.getExporter());
}
/**
* convert String to Number (or undefined)
*
* @param value
* @returns number or undefined
*/
convertStringToNumber(value) {
return value !== undefined ? Number(value) : undefined;
}
/**
* define the Probability Sampler
* By Default, it's always (or 1)
*
* @param sampleConfig the sample configuration
* @returns Sampler
*/
defineProbabilitySampler(sampleConfig) {
if (sampleConfig >= 1) {
return new ParentBasedSampler({ root: new AlwaysOnSampler() });
}
else if (sampleConfig <= 0 || sampleConfig === undefined) {
return new ParentBasedSampler({ root: new AlwaysOffSampler() });
}
else {
return new ParentBasedSampler({ root: new TraceIdRatioBasedSampler(sampleConfig) });
}
}
}
InstrumentationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: InstrumentationService, deps: [{ token: OTEL_CONFIG }, { token: OTEL_EXPORTER }, { token: OTEL_PROPAGATOR }, { token: OTEL_INSTRUMENTATION_PLUGINS }], target: i0.ɵɵFactoryTarget.Injectable });
InstrumentationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: InstrumentationService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: InstrumentationService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [OTEL_CONFIG]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [OTEL_EXPORTER]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [OTEL_PROPAGATOR]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [OTEL_INSTRUMENTATION_PLUGINS]
}] }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdHJ1bWVudGF0aW9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9vcGVudGVsZW1ldHJ5LWludGVyY2VwdG9yL3NyYy9saWIvc2VydmljZXMvaW5zdHJ1bWVudGF0aW9uL2luc3RydW1lbnRhdGlvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQ3hFLE9BQU8sRUFBbUIsd0JBQXdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRixPQUFPLEVBQ0wsZ0JBQWdCLEVBQ2hCLGVBQWUsRUFDZixrQkFBa0IsRUFFbEIsd0JBQXdCLEVBQ3hCLGlCQUFpQixFQUNsQixNQUFNLDhCQUE4QixDQUFDO0FBQ3RDLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsbUJBQW1CLEVBQ25CLGtCQUFrQixFQUNsQixpQkFBaUIsRUFFbEIsTUFBTSwrQkFBK0IsQ0FBQztBQUN2QyxtQ0FBbUM7QUFDbkMsT0FBTyxFQUFFLFdBQVcsRUFBdUIsNEJBQTRCLEVBQXlCLE1BQU0sMENBQTBDLENBQUM7QUFDakosT0FBTyxFQUFFLGFBQWEsRUFBYSxNQUFNLGdDQUFnQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxlQUFlLEVBQWUsTUFBTSxvQ0FBb0MsQ0FBQztBQUNsRixPQUFPLEVBQVksc0JBQXNCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQzs7QUFFNUU7OztHQUdHO0FBSUgsTUFBTSxPQUFPLHNCQUFzQjtJQVlqQzs7Ozs7O09BTUc7SUFDSCxZQUF5QyxNQUEyQixFQUUxRCxlQUEwQixFQUUxQixpQkFBOEIsRUFFOUIsZUFBa0M7UUFOSCxXQUFNLEdB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QUU7WUFDckIsT0FBTyxJQUFJLGtCQUFrQixDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1NBQ2hFO2FBQ0ksSUFBSSxZQUFZLElBQUksQ0FBQyxJQUFJLFlBQVksS0FBSyxTQUFTLEVBQUU7WUFDeEQsT0FBTyxJQUFJLGtCQUFrQixDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksZ0JBQWdCLEVBQUUsRUFBRSxDQUFDLENBQUM7U0FDakU7YUFBTTtZQUNMLE9BQU8sSUFBSSxrQkFBa0IsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLHdCQUF3QixDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUNyRjtJQUNILENBQUM7O21IQXRJVSxzQkFBc0Isa0JBbUJiLFdBQVcsYUFDckIsYUFBYSxhQUViLGVBQWUsYUFFZiw0QkFBNEI7dUhBeEIzQixzQkFBc0IsY0FGckIsTUFBTTsyRkFFUCxzQkFBc0I7a0JBSGxDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25COzswQkFvQmMsTUFBTTsyQkFBQyxXQUFXOzswQkFDNUIsTUFBTTsyQkFBQyxhQUFhOzswQkFFcEIsTUFBTTsyQkFBQyxlQUFlOzswQkFFdEIsTUFBTTsyQkFBQyw0QkFBNEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFpvbmVDb250ZXh0TWFuYWdlciB9IGZyb20gJ0BvcGVudGVsZW1ldHJ5L2NvbnRleHQtem9uZS1wZWVyLWRlcCc7XG5pbXBvcnQgeyBBVFRSX1NFUlZJQ0VfTkFNRSB9IGZyb20gJ0BvcGVudGVsZW1ldHJ5L3NlbWFudGljLWNvbnZlbnRpb25zJztcbmltcG9ydCB7IEluc3RydW1lbnRhdGlvbiwgcmVnaXN0ZXJJbnN0cnVtZW50YXRpb25zIH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvaW5zdHJ1bWVudGF0aW9uJztcbmltcG9ydCB7XG4gIEFsd2F5c09mZlNhbXBsZXIsXG4gIEFsd2F5c09uU2FtcGxlcixcbiAgUGFyZW50QmFzZWRTYW1wbGVyLFxuICBTYW1wbGVyLFxuICBUcmFjZUlkUmF0aW9CYXNlZFNhbXBsZXIsXG4gIFdlYlRyYWNlclByb3ZpZGVyXG59IGZyb20gJ0BvcGVudGVsZW1ldHJ5L3Nkay10cmFjZS13ZWInO1xuaW1wb3J0IHtcbiAgQ29uc29sZVNwYW5FeHBvcnRlcixcbiAgU2ltcGxlU3BhblByb2Nlc3NvcixcbiAgQmF0Y2hTcGFuUHJvY2Vzc29yLFxuICBOb29wU3BhblByb2Nlc3NvcixcbiAgU3BhblByb2Nlc3NvclxufSBmcm9tICdAb3BlbnRlbGVtZXRyeS9zZGstdHJhY2UtYmFzZSc7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuaW1wb3J0IHsgT1RFTF9DT05GSUcsIE9wZW5UZWxlbWV0cnlDb25maWcsIE9URUxfSU5TVFJVTUVOVEFUSU9OX1BMVUdJTlMsIENvbW1vbkNvbGxlY3RvckNvbmZpZyB9IGZyb20gJy4uLy4uL2NvbmZpZ3VyYXRpb24vb3BlbnRlbGVtZXRyeS1jb25maWcnO1xuaW1wb3J0IHsgT1RFTF9FWFBPUlRFUiwgSUV4cG9ydGVyIH0gZnJvbSAnLi4vZXhwb3J0ZXIvZXhwb3J0ZXIuaW50ZXJmYWNlJztcbmltcG9ydCB7IE9URUxfUFJPUEFHQVRPUiwgSVByb3BhZ2F0b3IgfSBmcm9tICcuLi9wcm9wYWdhdG9yL3Byb3BhZ2F0b3IuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJlc291cmNlLCByZXNvdXJjZUZyb21BdHRyaWJ1dGVzIH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvcmVzb3VyY2VzJztcblxuLyoqXG4gKiBJbnN0cnVtZW50YXRpb25TZXJ2aWNlLlxuICogU2VydmljZSBmb3IgY29tcG9uZW50IHRvIGFkZCBpbnN0cnVtZW50YXRpb24uXG4gKi9cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEluc3RydW1lbnRhdGlvblNlcnZpY2Uge1xuXG4gIC8qKlxuICAgKiB0cmFjZXJQcm92aWRlclxuICAgKi9cbiAgcHJpdmF0ZSB0cmFjZXJQcm92aWRlcjogV2ViVHJhY2VyUHJvdmlkZXI7XG5cbiAgLyoqXG4gICAqIGNvbnRleHRNYW5hZ2VyXG4gICAqL1xuICBwcml2YXRlIGNvbnRleHRNYW5hZ2VyID0gbmV3IFpvbmVDb250ZXh0TWFuYWdlcigpO1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RvclxuICAgKlxuICAgKiBAcGFyYW0gY29uZmlnXG4gICAqIEBwYXJhbSBleHBvcnRlclNlcnZpY2VcbiAgICogQHBhcmFtIHByb3BhZ2F0b3JTZXJ2aWNlXG4gICAqL1xuICBjb25zdHJ1Y3RvcihASW5qZWN0KE9URUxfQ09ORklHKSBwcml2YXRlIGNvbmZpZzogT3BlblRlbGVtZXRyeUNvbmZpZyxcbiAgICBASW5qZWN0KE9URUxfRVhQT1JURVIpXG4gICAgcHJpdmF0ZSBleHBvcnRlclNlcnZpY2U6IElFeHBvcnRlcixcbiAgICBASW5qZWN0KE9URUxfUFJPUEFHQVRPUilcbiAgICBwcml2YXRlIHByb3BhZ2F0b3JTZXJ2aWNlOiBJUHJvcGFnYXRvcixcbiAgICBASW5qZWN0KE9URUxfSU5TVFJVTUVOVEFUSU9OX1BMVUdJTlMpXG4gICAgcHJpdmF0ZSBpbnN0cnVtZW50YXRpb246IEluc3RydW1lbnRhdGlvbltdKSB7XG4gICAgdGhpcy50cmFjZXJQcm92aWRlciA9IG5ldyBXZWJUcmFjZXJQcm92aWRlcih7XG4gICAgICBzYW1wbGVyOiB0aGlzLmRlZmluZVByb2JhYmlsaXR5U2FtcGxlcih0aGlzLmNvbnZlcnRTdHJpbmdUb051bWJlcih0aGlzLmNvbmZpZy5jb21tb25Db25maWcucHJvYmFiaWxpdHlTYW1wbGVyKSksXG4gICAgICByZXNvdXJjZTogdGhpcy5sb2FkUmVzb3VyY2VBdHRyaWJ1dGVzKHRoaXMuY29uZmlnLmNvbW1vbkNvbmZpZyksXG4gICAgICBzcGFuUHJvY2Vzc29yczogdGhpcy5pbnNlcnRPck5vdFNwYW5FeHBvcnRlcih0aGlzLmNvbmZpZy5jb21tb25Db25maWcucHJvZHVjdGlvbixcbiAgICAgICAgdGhpcy5leHBvcnRlclNlcnZpY2UsIHRoaXMuY29uZmlnLmNvbW1vbkNvbmZpZy5jb25zb2xlKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0IGluc3RydW1lbnRhdGlvbiBvbiBpbml0XG4gICAqL1xuICBwdWJsaWMgaW5pdEluc3RydW1lbnRhdGlvbigpIHtcbiAgICB0aGlzLnRyYWNlclByb3ZpZGVyLnJlZ2lzdGVyKHtcbiAgICAgIGNvbnRleHRNYW5hZ2VyOiB0aGlzLmNvbnRleHRNYW5hZ2VyLFxuICAgICAgcHJvcGFnYXRvcjogdGhpcy5wcm9wYWdhdG9yU2VydmljZS5nZXRQcm9wYWdhdG9yKCksXG4gICAgfSk7XG5cbiAgICByZWdpc3Rlckluc3RydW1lbnRhdGlvbnMoe1xuICAgICAgaW5zdHJ1bWVudGF0aW9uczogdGhpcy5pbnN0cnVtZW50YXRpb24sXG4gICAgICB0cmFjZXJQcm92aWRlcjogdGhpcy50cmFjZXJQcm92aWRlcixcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBSZXNvdXJjZSBBdHRyaWJ1dGVzXG4gICAqIEBwYXJhbSBjb21tb25Db25maWcgY29tbW9uIGNvbmZpZ3VyYXRpb25cbiAgICogQHJldHVybnMgUmVzb3VyY2VcbiAgICovXG4gIHByaXZhdGUgbG9hZFJlc291cmNlQXR0cmlidXRlcyhcbiAgICBjb21tb25Db25maWc6IENvbW1vbkNvbGxlY3RvckNvbmZpZ1xuICApOiBSZXNvdXJjZSB7XG4gICAgcmV0dXJuIHJlc291cmNlRnJvbUF0dHJpYnV0ZXMoe1xuICAgICAgW0FUVFJfU0VSVklDRV9OQU1FXTogY29tbW9uQ29uZmlnPy5zZXJ2aWNlTmFtZSxcbiAgICAgIC4uLmNvbW1vbkNvbmZpZz8ucmVzb3VyY2VBdHRyaWJ1dGVzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmeSB0byBpbnNlcnQgb3Igbm90IGEgU3BhbiBFeHBvcnRlclxuICAgKiBAcGFyYW0gY29uc29sZSBjb25maWcgdG8gaW5zZXJ0IGNvbnNvbGUgc3BhblxuICAgKiBAcGFyYW0gcHJvZHVjdGlvbiBwcm9kdWN0aW9uIG1vZGVcbiAgICogQHBhcmFtIGV4cG9ydGVyIGV4cG9ydGVyXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIFNwYW5Qcm9jZXNzb3JcbiAgICovXG4gIHByaXZhdGUgaW5zZXJ0T3JOb3RTcGFuRXhwb3J0ZXIocHJvZHVjdGlvbjogYm9vbGVhbiwgZXhwb3J0ZXI6IElFeHBvcnRlciwgY29uc29sZTogYm9vbGVhbik6IEFycmF5PFNwYW5Qcm9jZXNzb3I+IHtcbiAgICBpZiAodGhpcy5leHBvcnRlclNlcnZpY2UuZ2V0RXhwb3J0ZXIoKSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gQXJyYXkub2YodGhpcy5pbnNlcnRTcGFuUHJvY2Vzc29yUHJvZHVjdGlvbk1vZGUocHJvZHVjdGlvbiwgZXhwb3J0ZXIpLFxuICAgICAgICB0aGlzLmluc2VydENvbnNvbGVTcGFuRXhwb3J0ZXIoY29uc29sZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gQXJyYXkub2YobmV3IE5vb3BTcGFuUHJvY2Vzc29yKCkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbnNlcnQgaW4gdHJhY2VyIHRoZSBjb25zb2xlIHNwYW4gaWYgY29uZmlnIGlzIHRydWVcbiAgICpcbiAgICogQHBhcmFtIGNvbnNvbGUgY29uZmlnIHRvIGluc2VydCBjb25zb2xlIHNwYW5cbiAgICogQHJldHVybnMgU3BhblByb2Nlc3NvclxuICAgKi9cbiAgcHJpdmF0ZSBpbnNlcnRDb25zb2xlU3BhbkV4cG9ydGVyKGNvbnNvbGU6IGJvb2xlYW4pOiBTcGFuUHJvY2Vzc29yIHtcbiAgICBpZiAoY29uc29sZSkge1xuICAgICAgcmV0dXJuIG5ldyBTaW1wbGVTcGFuUHJvY2Vzc29yKG5ldyBDb25zb2xlU3BhbkV4cG9ydGVyKCkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbnNlcnQgQmF0Y2hTcGFuUHJvY2Vzc29yIGluIHByb2R1Y3Rpb24gbW9kZVxuICAgKiBTaW1wbGVTcGFuUHJvY2Vzc29yIG90aGVyd2lzZVxuICAgKlxuICAgKiBAcGFyYW0gYm9vbGVhbiBwcm9kdWN0aW9uXG4gICAqIEBwYXJhbSBJRXhwb3J0ZXIgZXhwb3J0ZXJcbiAgICogQHJldHVybnMgU3BhblByb2Nlc3NvclxuICAgKi9cbiAgcHJpdmF0ZSBpbnNlcnRTcGFuUHJvY2Vzc29yUHJvZHVjdGlvbk1vZGUoXG4gICAgcHJvZHVjdGlvbjogYm9vbGVhbixcbiAgICBleHBvcnRlcjogSUV4cG9ydGVyXG4gICk6IFNwYW5Qcm9jZXNzb3Ige1xuICAgIHJldHVybiBwcm9kdWN0aW9uXG4gICAgICA/IG5ldyBCYXRjaFNwYW5Qcm9jZXNzb3IoZXhwb3J0ZXIuZ2V0RXhwb3J0ZXIoKSlcbiAgICAgIDogbmV3IFNpbXBsZVNwYW5Qcm9jZXNzb3IoZXhwb3J0ZXIuZ2V0RXhwb3J0ZXIoKSk7XG4gIH1cblxuICAvKipcbiAgICogY29udmVydCBTdHJpbmcgdG8gTnVtYmVyIChvciB1bmRlZmluZWQpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZVxuICAgKiBAcmV0dXJucyBudW1iZXIgb3IgdW5kZWZpbmVkXG4gICAqL1xuICBwcml2YXRlIGNvbnZlcnRTdHJpbmdUb051bWJlcih2YWx1ZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZCA/IE51bWJlcih2YWx1ZSkgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogZGVmaW5lIHRoZSBQcm9iYWJpbGl0eSBTYW1wbGVyXG4gICAqIEJ5IERlZmF1bHQsIGl0J3MgYWx3YXlzIChvciAxKVxuICAgKlxuICAgKiBAcGFyYW0gc2FtcGxlQ29uZmlnIHRoZSBzYW1wbGUgY29uZmlndXJhdGlvblxuICAgKiBAcmV0dXJucyBTYW1wbGVyXG4gICAqL1xuICBwcml2YXRlIGRlZmluZVByb2JhYmlsaXR5U2FtcGxlcihzYW1wbGVDb25maWc6IG51bWJlcik6IFNhbXBsZXIge1xuICAgIGlmIChzYW1wbGVDb25maWcgPj0gMSkge1xuICAgICAgcmV0dXJuIG5ldyBQYXJlbnRCYXNlZFNhbXBsZXIoeyByb290OiBuZXcgQWx3YXlzT25TYW1wbGVyKCkgfSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHNhbXBsZUNvbmZpZyA8PSAwIHx8IHNhbXBsZUNvbmZpZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gbmV3IFBhcmVudEJhc2VkU2FtcGxlcih7IHJvb3Q6IG5ldyBBbHdheXNPZmZTYW1wbGVyKCkgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgUGFyZW50QmFzZWRTYW1wbGVyKHsgcm9vdDogbmV3IFRyYWNlSWRSYXRpb0Jhc2VkU2FtcGxlcihzYW1wbGVDb25maWcpIH0pO1xuICAgIH1cbiAgfVxufVxuIl19