@spartacus/core
Version:
Spartacus - the core framework
237 lines • 32.4 kB
JavaScript
import { Injectable } from '@angular/core';
import { select } from '@ngrx/store';
import { combineLatest, iif } from 'rxjs';
import { filter, map, switchMap, tap, withLatestFrom } from 'rxjs/operators';
import { ANONYMOUS_CONSENT_STATUS, } from '../../model/index';
import { AnonymousConsentsActions } from '../store/actions/index';
import { AnonymousConsentsSelectors } from '../store/selectors/index';
import * as i0 from "@angular/core";
import * as i1 from "@ngrx/store";
import * as i2 from "../../auth/user-auth/facade/auth.service";
export class AnonymousConsentsService {
constructor(store, authService) {
this.store = store;
this.authService = authService;
}
/**
* Retrieves the anonymous consent templates.
*/
loadTemplates() {
this.store.dispatch(new AnonymousConsentsActions.LoadAnonymousConsentTemplates());
}
/**
* Conditionally triggers the load of the anonymous consent templates if:
* - `loadIfMissing` parameter is set to `true`
* - the `templates` in the store are `undefined`
*
* Otherwise it just returns the value from the store.
*
* @param loadIfMissing setting to `true` will trigger the load of the templates if the currently stored templates are `undefined`
*/
getTemplates(loadIfMissing = false) {
return iif(() => loadIfMissing, this.store.pipe(select(AnonymousConsentsSelectors.getAnonymousConsentTemplatesValue), withLatestFrom(this.getLoadTemplatesLoading()), filter(([_templates, loading]) => !loading), tap(([templates, _loading]) => {
if (!Boolean(templates)) {
this.loadTemplates();
}
}), filter(([templates, _loading]) => Boolean(templates)), map(([templates, _loading]) => templates)), this.store.pipe(select(AnonymousConsentsSelectors.getAnonymousConsentTemplatesValue)));
}
/**
* Returns the anonymous consent templates with the given template code.
* @param templateCode a template code by which to filter anonymous consent templates.
*/
getTemplate(templateCode) {
return this.store.pipe(select(AnonymousConsentsSelectors.getAnonymousConsentTemplate(templateCode)));
}
/**
* Returns an indicator for the loading status for the anonymous consent templates.
*/
getLoadTemplatesLoading() {
return this.store.pipe(select(AnonymousConsentsSelectors.getAnonymousConsentTemplatesLoading));
}
/**
* Returns an indicator for the success status for the anonymous consent templates.
*/
getLoadTemplatesSuccess() {
return this.store.pipe(select(AnonymousConsentsSelectors.getAnonymousConsentTemplatesSuccess));
}
/**
* Returns an indicator for the error status for the anonymous consent templates.
*/
getLoadTemplatesError() {
return this.store.pipe(select(AnonymousConsentsSelectors.getAnonymousConsentTemplatesError));
}
/**
* Resets the loading, success and error indicators for the anonymous consent templates.
*/
resetLoadTemplatesState() {
this.store.dispatch(new AnonymousConsentsActions.ResetLoadAnonymousConsentTemplates());
}
/**
* Returns all the anonymous consents.
*/
getConsents() {
return this.store.pipe(select(AnonymousConsentsSelectors.getAnonymousConsents));
}
/**
* Puts the provided anonymous consents into the store.
*/
setConsents(consents) {
return this.store.dispatch(new AnonymousConsentsActions.SetAnonymousConsents(consents));
}
/**
* Returns the anonymous consent for the given template ID.
*
* As a side-effect, the method will call `getTemplates(true)` to load the templates if those are not present.
*
* @param templateId a template ID by which to filter anonymous consent templates.
*/
getConsent(templateId) {
return this.authService.isUserLoggedIn().pipe(filter((authenticated) => !authenticated), tap(() => this.getTemplates(true)), switchMap(() => this.store.pipe(select(AnonymousConsentsSelectors.getAnonymousConsentByTemplateCode(templateId)))));
}
/**
* Give a consent for the given `templateCode`
* @param templateCode for which to give the consent
*/
giveConsent(templateCode) {
this.store.dispatch(new AnonymousConsentsActions.GiveAnonymousConsent(templateCode));
}
/**
* Sets all the anonymous consents' state to given.
*/
giveAllConsents() {
return this.getTemplates(true).pipe(tap((templates) => templates.forEach((template) => this.giveConsent(template.id))));
}
/**
* Returns `true` if the provided `consent` is given.
* @param consent a consent to test
*/
isConsentGiven(consent) {
return consent && consent.consentState === ANONYMOUS_CONSENT_STATUS.GIVEN;
}
/**
* Withdraw a consent for the given `templateCode`
* @param templateCode for which to withdraw the consent
*/
withdrawConsent(templateCode) {
this.store.dispatch(new AnonymousConsentsActions.WithdrawAnonymousConsent(templateCode));
}
/**
* Sets all the anonymous consents' state to withdrawn.
*/
withdrawAllConsents() {
return this.getTemplates(true).pipe(tap((templates) => templates.forEach((template) => this.withdrawConsent(template.id))));
}
/**
* Returns `true` if the provided `consent` is withdrawn.
* @param consent a consent to test
*/
isConsentWithdrawn(consent) {
return (consent && consent.consentState === ANONYMOUS_CONSENT_STATUS.WITHDRAWN);
}
/**
* Toggles the dismissed state of the anonymous consents banner.
* @param dismissed the banner will be dismissed if `true` is passed, otherwise it will be visible.
*/
toggleBannerDismissed(dismissed) {
this.store.dispatch(new AnonymousConsentsActions.ToggleAnonymousConsentsBannerDissmissed(dismissed));
if (dismissed) {
this.toggleTemplatesUpdated(false);
}
}
/**
* Returns `true` if the banner was dismissed, `false` otherwise.
*/
isBannerDismissed() {
return this.store.pipe(select(AnonymousConsentsSelectors.getAnonymousConsentsBannerDismissed));
}
/**
* Returns `true` if the consent templates were updated on the back-end.
* If the templates are not present in the store, it triggers the load.
*/
getTemplatesUpdated() {
return this.getTemplates(true).pipe(switchMap(() => this.store.pipe(select(AnonymousConsentsSelectors.getAnonymousConsentTemplatesUpdate))));
}
/**
* Toggles the `updated` slice of the state
* @param updated
*/
toggleTemplatesUpdated(updated) {
this.store.dispatch(new AnonymousConsentsActions.ToggleAnonymousConsentTemplatesUpdated(updated));
}
/**
* Returns `true` if either the banner is not dismissed or if the templates were updated on the back-end.
* Otherwise, it returns `false`.
*/
isBannerVisible() {
return combineLatest([
this.isBannerDismissed(),
this.getTemplatesUpdated(),
]).pipe(tap(() => this.checkConsentVersions()), map(([dismissed, updated]) => !dismissed || updated));
}
/**
* Dispatches an action to trigger the check
* whether the anonymous consent version have been updated
*/
checkConsentVersions() {
this.store.dispatch(new AnonymousConsentsActions.AnonymousConsentCheckUpdatedVersions());
}
/**
* Returns `true` if there's a mismatch in template versions between the provided `currentTemplates` and `newTemplates`
* @param currentTemplates current templates to check
* @param newTemplates new templates to check
*/
detectUpdatedTemplates(currentTemplates, newTemplates) {
if (newTemplates.length !== currentTemplates.length) {
return true;
}
for (let i = 0; i < newTemplates.length; i++) {
const newTemplate = newTemplates[i];
const currentTemplate = currentTemplates[i];
if (newTemplate.version !== currentTemplate.version) {
return true;
}
}
return false;
}
/**
* Serializes using `JSON.stringify()` and encodes using `encodeURIComponent()` methods
* @param consents to serialize and encode
*/
serializeAndEncode(consents) {
if (!consents) {
return '';
}
const serialized = JSON.stringify(consents);
const encoded = encodeURIComponent(serialized);
return encoded;
}
/**
* Decodes using `decodeURIComponent()` and deserializes using `JSON.parse()`
* @param rawConsents to decode an deserialize
*/
decodeAndDeserialize(rawConsents) {
const decoded = decodeURIComponent(rawConsents);
const unserialized = JSON.parse(decoded);
return unserialized;
}
/**
*
* Compares the given `newConsents` and `previousConsents` and returns `true` if there are differences (the `newConsents` are updates).
* Otherwise it returns `false`.
*
* @param newConsents new consents to compare
* @param previousConsents old consents to compare
*/
consentsUpdated(newConsents, previousConsents) {
const newRawConsents = this.serializeAndEncode(newConsents);
const previousRawConsents = this.serializeAndEncode(previousConsents);
return newRawConsents !== previousRawConsents;
}
}
AnonymousConsentsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: AnonymousConsentsService, deps: [{ token: i1.Store }, { token: i2.AuthService }], target: i0.ɵɵFactoryTarget.Injectable });
AnonymousConsentsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: AnonymousConsentsService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: AnonymousConsentsService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: function () { return [{ type: i1.Store }, { type: i2.AuthService }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5vbnltb3VzLWNvbnNlbnRzLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3NyYy9hbm9ueW1vdXMtY29uc2VudHMvZmFjYWRlL2Fub255bW91cy1jb25zZW50cy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLE1BQU0sRUFBUyxNQUFNLGFBQWEsQ0FBQztBQUM1QyxPQUFPLEVBQUUsYUFBYSxFQUFFLEdBQUcsRUFBYyxNQUFNLE1BQU0sQ0FBQztBQUN0RCxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTdFLE9BQU8sRUFFTCx3QkFBd0IsR0FFekIsTUFBTSxtQkFBbUIsQ0FBQztBQUMzQixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUVsRSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQzs7OztBQUd0RSxNQUFNLE9BQU8sd0JBQXdCO0lBQ25DLFlBQ1ksS0FBd0MsRUFDeEMsV0FBd0I7UUFEeEIsVUFBSyxHQUFMLEtBQUssQ0FBbUM7UUFDeEMsZ0JBQVcsR0FBWCxXQUFXLENBQWE7SUFDakMsQ0FBQztJQUVKOztPQUVHO0lBQ0gsYUFBYTtRQUNYLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUNqQixJQUFJLHdCQUF3QixDQUFDLDZCQUE2QixFQUFFLENBQzdELENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSCxZQUFZLENBQUMsYUFBYSxHQUFHLEtBQUs7UUFDaEMsT0FBTyxHQUFHLENBQ1IsR0FBRyxFQUFFLENBQUMsYUFBYSxFQUNuQixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FDYixN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QUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQXVCLENBQUM7UUFDL0QsT0FBTyxZQUFZLENBQUM7SUFDdEIsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxlQUFlLENBQ2IsV0FBK0IsRUFDL0IsZ0JBQW9DO1FBRXBDLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUM1RCxNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3RFLE9BQU8sY0FBYyxLQUFLLG1CQUFtQixDQUFDO0lBQ2hELENBQUM7O3FIQTFVVSx3QkFBd0I7eUhBQXhCLHdCQUF3QixjQURYLE1BQU07MkZBQ25CLHdCQUF3QjtrQkFEcEMsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBzZWxlY3QsIFN0b3JlIH0gZnJvbSAnQG5ncngvc3RvcmUnO1xuaW1wb3J0IHsgY29tYmluZUxhdGVzdCwgaWlmLCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBmaWx0ZXIsIG1hcCwgc3dpdGNoTWFwLCB0YXAsIHdpdGhMYXRlc3RGcm9tIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQXV0aFNlcnZpY2UgfSBmcm9tICcuLi8uLi9hdXRoL3VzZXItYXV0aC9mYWNhZGUvYXV0aC5zZXJ2aWNlJztcbmltcG9ydCB7XG4gIEFub255bW91c0NvbnNlbnQsXG4gIEFOT05ZTU9VU19DT05TRU5UX1NUQVRVUyxcbiAgQ29uc2VudFRlbXBsYXRlLFxufSBmcm9tICcuLi8uLi9tb2RlbC9pbmRleCc7XG5pbXBvcnQgeyBBbm9ueW1vdXNDb25zZW50c0FjdGlvbnMgfSBmcm9tICcuLi9zdG9yZS9hY3Rpb25zL2luZGV4JztcbmltcG9ydCB7IFN0YXRlV2l0aEFub255bW91c0NvbnNlbnRzIH0gZnJvbSAnLi4vc3RvcmUvYW5vbnltb3VzLWNvbnNlbnRzLXN0YXRlJztcbmltcG9ydCB7IEFub255bW91c0NvbnNlbnRzU2VsZWN0b3JzIH0gZnJvbSAnLi4vc3RvcmUvc2VsZWN0b3JzL2luZGV4JztcblxuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBBbm9ueW1vdXNDb25zZW50c1NlcnZpY2Uge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgc3RvcmU6IFN0b3JlPFN0YXRlV2l0aEFub255bW91c0NvbnNlbnRzPixcbiAgICBwcm90ZWN0ZWQgYXV0aFNlcnZpY2U6IEF1dGhTZXJ2aWNlXG4gICkge31cblxuICAvKipcbiAgICogUmV0cmlldmVzIHRoZSBhbm9ueW1vdXMgY29uc2VudCB0ZW1wbGF0ZXMuXG4gICAqL1xuICBsb2FkVGVtcGxhdGVzKCk6IHZvaWQge1xuICAgIHRoaXMuc3RvcmUuZGlzcGF0Y2goXG4gICAgICBuZXcgQW5vbnltb3VzQ29uc2VudHNBY3Rpb25zLkxvYWRBbm9ueW1vdXNDb25zZW50VGVtcGxhdGVzKClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbmRpdGlvbmFsbHkgdHJpZ2dlcnMgdGhlIGxvYWQgb2YgdGhlIGFub255bW91cyBjb25zZW50IHRlbXBsYXRlcyBpZjpcbiAgICogICAtIGBsb2FkSWZNaXNzaW5nYCBwYXJhbWV0ZXIgaXMgc2V0IHRvIGB0cnVlYFxuICAgKiAgIC0gdGhlIGB0ZW1wbGF0ZXNgIGluIHRoZSBzdG9yZSBhcmUgYHVuZGVmaW5lZGBcbiAgICpcbiAgICogT3RoZXJ3aXNlIGl0IGp1c3QgcmV0dXJucyB0aGUgdmFsdWUgZnJvbSB0aGUgc3RvcmUuXG4gICAqXG4gICAqIEBwYXJhbSBsb2FkSWZNaXNzaW5nIHNldHRpbmcgdG8gYHRydWVgIHdpbGwgdHJpZ2dlciB0aGUgbG9hZCBvZiB0aGUgdGVtcGxhdGVzIGlmIHRoZSBjdXJyZW50bHkgc3RvcmVkIHRlbXBsYXRlcyBhcmUgYHVuZGVmaW5lZGBcbiAgICovXG4gIGdldFRlbXBsYXRlcyhsb2FkSWZNaXNzaW5nID0gZmFsc2UpOiBPYnNlcnZhYmxlPENvbnNlbnRUZW1wbGF0ZVtdPiB7XG4gICAgcmV0dXJuIGlpZihcbiAgICAgICgpID0+IGxvYWRJZk1pc3NpbmcsXG4gICAgICB0aGlzLnN0b3JlLnBpcGUoXG4gICAgICAgIHNlbGVjdChBbm9ueW1vdXNDb25zZW50c1NlbGVjdG9ycy5nZXRBbm9ueW1vdXNDb25zZW50VGVtcGxhdGVzVmFsdWUpLFxuICAgICAgICB3aXRoTGF0ZXN0RnJvbSh0aGlzLmdldExvYWRUZW1wbGF0ZXNMb2FkaW5nKCkpLFxuICAgICAgICBmaWx0ZXIoKFtfdGVtcGxhdGVzLCBsb2FkaW5nXSkgPT4gIWxvYWRpbmcpLFxuICAgICAgICB0YXAoKFt0ZW1wbGF0ZXMsIF9sb2FkaW5nXSkgPT4ge1xuICAgICAgICAgIGlmICghQm9vbGVhbih0ZW1wbGF0ZXMpKSB7XG4gICAgICAgICAgICB0aGlzLmxvYWRUZW1wbGF0ZXMoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLFxuICAgICAgICBmaWx0ZXIoKFt0ZW1wbGF0ZXMsIF9sb2FkaW5nXSkgPT4gQm9vbGVhbih0ZW1wbGF0ZXMpKSxcbiAgICAgICAgbWFwKChbdGVtcGxhdGVzLCBfbG9hZGluZ10pID0+IHRlbXBsYXRlcylcbiAgICAgICksXG4gICAgICB0aGlzLnN0b3JlLnBpcGUoXG4gICAgICAgIHNlbGVjdChBbm9ueW1vdXNDb25zZW50c1NlbGVjdG9ycy5nZXRBbm9ueW1vdXNDb25zZW50VGVtcGxhdGVzVmFsdWUpXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBhbm9ueW1vdXMgY29uc2VudCB0ZW1wbGF0ZXMgd2l0aCB0aGUgZ2l2ZW4gdGVtcGxhdGUgY29kZS5cbiAgICogQHBhcmFtIHRlbXBsYXRlQ29kZSBhIHRlbXBsYXRlIGNvZGUgYnkgd2hpY2ggdG8gZmlsdGVyIGFub255bW91cyBjb25zZW50IHRlbXBsYXRlcy5cbiAgICovXG4gIGdldFRlbXBsYXRlKHRlbXBsYXRlQ29kZTogc3RyaW5nKTogT2JzZXJ2YWJsZTxDb25zZW50VGVtcGxhdGU+IHtcbiAgICByZXR1cm4gdGhpcy5zdG9yZS5waXBlKFxuICAgICAgc2VsZWN0KFxuICAgICAgICBBbm9ueW1vdXNDb25zZW50c1NlbGVjdG9ycy5nZXRBbm9ueW1vdXNDb25zZW50VGVtcGxhdGUodGVtcGxhdGVDb2RlKVxuICAgICAgKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBpbmRpY2F0b3IgZm9yIHRoZSBsb2FkaW5nIHN0YXR1cyBmb3IgdGhlIGFub255bW91cyBjb25zZW50IHRlbXBsYXRlcy5cbiAgICovXG4gIGdldExvYWRUZW1wbGF0ZXNMb2FkaW5nKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnN0b3JlLnBpcGUoXG4gICAgICBzZWxlY3QoQW5vbnltb3VzQ29uc2VudHNTZWxlY3RvcnMuZ2V0QW5vbnltb3VzQ29uc2VudFRlbXBsYXRlc0xvYWRpbmcpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIGluZGljYXRvciBmb3IgdGhlIHN1Y2Nlc3Mgc3RhdHVzIGZvciB0aGUgYW5vbnltb3VzIGNvbnNlbnQgdGVtcGxhdGVzLlxuICAgKi9cbiAgZ2V0TG9hZFRlbXBsYXRlc1N1Y2Nlc3MoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuc3RvcmUucGlwZShcbiAgICAgIHNlbGVjdChBbm9ueW1vdXNDb25zZW50c1NlbGVjdG9ycy5nZXRBbm9ueW1vdXNDb25zZW50VGVtcGxhdGVzU3VjY2VzcylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gaW5kaWNhdG9yIGZvciB0aGUgZXJyb3Igc3RhdHVzIGZvciB0aGUgYW5vbnltb3VzIGNvbnNlbnQgdGVtcGxhdGVzLlxuICAgKi9cbiAgZ2V0TG9hZFRlbXBsYXRlc0Vycm9yKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnN0b3JlLnBpcGUoXG4gICAgICBzZWxlY3QoQW5vbnltb3VzQ29uc2VudHNTZWxlY3RvcnMuZ2V0QW5vbnltb3VzQ29uc2VudFRlbXBsYXRlc0Vycm9yKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXRzIHRoZSBsb2FkaW5nLCBzdWNjZXNzIGFuZCBlcnJvciBpbmRpY2F0b3JzIGZvciB0aGUgYW5vbnltb3VzIGNvbnNlbnQgdGVtcGxhdGVzLlxuICAgKi9cbiAgcmVzZXRMb2FkVGVtcGxhdGVzU3RhdGUoKTogdm9pZCB7XG4gICAgdGhpcy5zdG9yZS5kaXNwYXRjaChcbiAgICAgIG5ldyBBbm9ueW1vdXNDb25zZW50c0FjdGlvbnMuUmVzZXRMb2FkQW5vbnltb3VzQ29uc2VudFRlbXBsYXRlcygpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFsbCB0aGUgYW5vbnltb3VzIGNvbnNlbnRzLlxuICAgKi9cbiAgZ2V0Q29uc2VudHMoKTogT2JzZXJ2YWJsZTxBbm9ueW1vdXNDb25zZW50W10+IHtcbiAgICByZXR1cm4gdGhpcy5zdG9yZS5waXBlKFxuICAgICAgc2VsZWN0KEFub255bW91c0NvbnNlbnRzU2VsZWN0b3JzLmdldEFub255bW91c0NvbnNlbnRzKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUHV0cyB0aGUgcHJvdmlkZWQgYW5vbnltb3VzIGNvbnNlbnRzIGludG8gdGhlIHN0b3JlLlxuICAgKi9cbiAgc2V0Q29uc2VudHMoY29uc2VudHM6IEFub255bW91c0NvbnNlbnRbXSk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLnN0b3JlLmRpc3BhdGNoKFxuICAgICAgbmV3IEFub255bW91c0NvbnNlbnRzQWN0aW9ucy5TZXRBbm9ueW1vdXNDb25zZW50cyhjb25zZW50cylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGFub255bW91cyBjb25zZW50IGZvciB0aGUgZ2l2ZW4gdGVtcGxhdGUgSUQuXG4gICAqXG4gICAqIEFzIGEgc2lkZS1lZmZlY3QsIHRoZSBtZXRob2Qgd2lsbCBjYWxsIGBnZXRUZW1wbGF0ZXModHJ1ZSlgIHRvIGxvYWQgdGhlIHRlbXBsYXRlcyBpZiB0aG9zZSBhcmUgbm90IHByZXNlbnQuXG4gICAqXG4gICAqIEBwYXJhbSB0ZW1wbGF0ZUlkIGEgdGVtcGxhdGUgSUQgYnkgd2hpY2ggdG8gZmlsdGVyIGFub255bW91cyBjb25zZW50IHRlbXBsYXRlcy5cbiAgICovXG4gIGdldENvbnNlbnQodGVtcGxhdGVJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxBbm9ueW1vdXNDb25zZW50PiB7XG4gICAgcmV0dXJuIHRoaXMuYXV0aFNlcnZpY2UuaXNVc2VyTG9nZ2VkSW4oKS5waXBlKFxuICAgICAgZmlsdGVyKChhdXRoZW50aWNhdGVkKSA9PiAhYXV0aGVudGljYXRlZCksXG4gICAgICB0YXAoKCkgPT4gdGhpcy5nZXRUZW1wbGF0ZXModHJ1ZSkpLFxuICAgICAgc3dpdGNoTWFwKCgpID0+XG4gICAgICAgIHRoaXMuc3RvcmUucGlwZShcbiAgICAgICAgICBzZWxlY3QoXG4gICAgICAgICAgICBBbm9ueW1vdXNDb25zZW50c1NlbGVjdG9ycy5nZXRBbm9ueW1vdXNDb25zZW50QnlUZW1wbGF0ZUNvZGUoXG4gICAgICAgICAgICAgIHRlbXBsYXRlSWRcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgIClcbiAgICAgIClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdpdmUgYSBjb25zZW50IGZvciB0aGUgZ2l2ZW4gYHRlbXBsYXRlQ29kZWBcbiAgICogQHBhcmFtIHRlbXBsYXRlQ29kZSBmb3Igd2hpY2ggdG8gZ2l2ZSB0aGUgY29uc2VudFxuICAgKi9cbiAgZ2l2ZUNvbnNlbnQodGVtcGxhdGVDb2RlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnN0b3JlLmRpc3BhdGNoKFxuICAgICAgbmV3IEFub255bW91c0NvbnNlbnRzQWN0aW9ucy5HaXZlQW5vbnltb3VzQ29uc2VudCh0ZW1wbGF0ZUNvZGUpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGFsbCB0aGUgYW5vbnltb3VzIGNvbnNlbnRzJyBzdGF0ZSB0byBnaXZlbi5cbiAgICovXG4gIGdpdmVBbGxDb25zZW50cygpOiBPYnNlcnZhYmxlPENvbnNlbnRUZW1wbGF0ZVtdPiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VGVtcGxhdGVzKHRydWUpLnBpcGUoXG4gICAgICB0YXAoKHRlbXBsYXRlcykgPT5cbiAgICAgICAgdGVtcGxhdGVzLmZvckVhY2goKHRlbXBsYXRlKSA9PiB0aGlzLmdpdmVDb25zZW50KHRlbXBsYXRlLmlkKSlcbiAgICAgIClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYHRydWVgIGlmIHRoZSBwcm92aWRlZCBgY29uc2VudGAgaXMgZ2l2ZW4uXG4gICAqIEBwYXJhbSBjb25zZW50IGEgY29uc2VudCB0byB0ZXN0XG4gICAqL1xuICBpc0NvbnNlbnRHaXZlbihjb25zZW50OiBBbm9ueW1vdXNDb25zZW50KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGNvbnNlbnQgJiYgY29uc2VudC5jb25zZW50U3RhdGUgPT09IEFOT05ZTU9VU19DT05TRU5UX1NUQVRVUy5HSVZFTjtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaXRoZHJhdyBhIGNvbnNlbnQgZm9yIHRoZSBnaXZlbiBgdGVtcGxhdGVDb2RlYFxuICAgKiBAcGFyYW0gdGVtcGxhdGVDb2RlIGZvciB3aGljaCB0byB3aXRoZHJhdyB0aGUgY29uc2VudFxuICAgKi9cbiAgd2l0aGRyYXdDb25zZW50KHRlbXBsYXRlQ29kZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5zdG9yZS5kaXNwYXRjaChcbiAgICAgIG5ldyBBbm9ueW1vdXNDb25zZW50c0FjdGlvbnMuV2l0aGRyYXdBbm9ueW1vdXNDb25zZW50KHRlbXBsYXRlQ29kZSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgYWxsIHRoZSBhbm9ueW1vdXMgY29uc2VudHMnIHN0YXRlIHRvIHdpdGhkcmF3bi5cbiAgICovXG4gIHdpdGhkcmF3QWxsQ29uc2VudHMoKTogT2JzZXJ2YWJsZTxDb25zZW50VGVtcGxhdGVbXT4ge1xuICAgIHJldHVybiB0aGlzLmdldFRlbXBsYXRlcyh0cnVlKS5waXBlKFxuICAgICAgdGFwKCh0ZW1wbGF0ZXMpID0+XG4gICAgICAgIHRlbXBsYXRlcy5mb3JFYWNoKCh0ZW1wbGF0ZSkgPT4gdGhpcy53aXRoZHJhd0NvbnNlbnQodGVtcGxhdGUuaWQpKVxuICAgICAgKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHByb3ZpZGVkIGBjb25zZW50YCBpcyB3aXRoZHJhd24uXG4gICAqIEBwYXJhbSBjb25zZW50IGEgY29uc2VudCB0byB0ZXN0XG4gICAqL1xuICBpc0NvbnNlbnRXaXRoZHJhd24oY29uc2VudDogQW5vbnltb3VzQ29uc2VudCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICBjb25zZW50ICYmIGNvbnNlbnQuY29uc2VudFN0YXRlID09PSBBTk9OWU1PVVNfQ09OU0VOVF9TVEFUVVMuV0lUSERSQVdOXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUb2dnbGVzIHRoZSBkaXNtaXNzZWQgc3RhdGUgb2YgdGhlIGFub255bW91cyBjb25zZW50cyBiYW5uZXIuXG4gICAqIEBwYXJhbSBkaXNtaXNzZWQgdGhlIGJhbm5lciB3aWxsIGJlIGRpc21pc3NlZCBpZiBgdHJ1ZWAgaXMgcGFzc2VkLCBvdGhlcndpc2UgaXQgd2lsbCBiZSB2aXNpYmxlLlxuICAgKi9cbiAgdG9nZ2xlQmFubmVyRGlzbWlzc2VkKGRpc21pc3NlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuc3RvcmUuZGlzcGF0Y2goXG4gICAgICBuZXcgQW5vbnltb3VzQ29uc2VudHNBY3Rpb25zLlRvZ2dsZUFub255bW91c0NvbnNlbnRzQmFubmVyRGlzc21pc3NlZChcbiAgICAgICAgZGlzbWlzc2VkXG4gICAgICApXG4gICAgKTtcbiAgICBpZiAoZGlzbWlzc2VkKSB7XG4gICAgICB0aGlzLnRvZ2dsZVRlbXBsYXRlc1VwZGF0ZWQoZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYmFubmVyIHdhcyBkaXNtaXNzZWQsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICAgKi9cbiAgaXNCYW5uZXJEaXNtaXNzZWQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuc3RvcmUucGlwZShcbiAgICAgIHNlbGVjdChBbm9ueW1vdXNDb25zZW50c1NlbGVjdG9ycy5nZXRBbm9ueW1vdXNDb25zZW50c0Jhbm5lckRpc21pc3NlZClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYHRydWVgIGlmIHRoZSBjb25zZW50IHRlbXBsYXRlcyB3ZXJlIHVwZGF0ZWQgb24gdGhlIGJhY2stZW5kLlxuICAgKiBJZiB0aGUgdGVtcGxhdGVzIGFyZSBub3QgcHJlc2VudCBpbiB0aGUgc3RvcmUsIGl0IHRyaWdnZXJzIHRoZSBsb2FkLlxuICAgKi9cbiAgZ2V0VGVtcGxhdGVzVXBkYXRlZCgpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5nZXRUZW1wbGF0ZXModHJ1ZSkucGlwZShcbiAgICAgIHN3aXRjaE1hcCgoKSA9PlxuICAgICAgICB0aGlzLnN0b3JlLnBpcGUoXG4gICAgICAgICAgc2VsZWN0KEFub255bW91c0NvbnNlbnRzU2VsZWN0b3JzLmdldEFub255bW91c0NvbnNlbnRUZW1wbGF0ZXNVcGRhdGUpXG4gICAgICAgIClcbiAgICAgIClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFRvZ2dsZXMgdGhlIGB1cGRhdGVkYCBzbGljZSBvZiB0aGUgc3RhdGVcbiAgICogQHBhcmFtIHVwZGF0ZWRcbiAgICovXG4gIHRvZ2dsZVRlbXBsYXRlc1VwZGF0ZWQodXBkYXRlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuc3RvcmUuZGlzcGF0Y2goXG4gICAgICBuZXcgQW5vbnltb3VzQ29uc2VudHNBY3Rpb25zLlRvZ2dsZUFub255bW91c0NvbnNlbnRUZW1wbGF0ZXNVcGRhdGVkKFxuICAgICAgICB1cGRhdGVkXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGB0cnVlYCBpZiBlaXRoZXIgdGhlIGJhbm5lciBpcyBub3QgZGlzbWlzc2VkIG9yIGlmIHRoZSB0ZW1wbGF0ZXMgd2VyZSB1cGRhdGVkIG9uIHRoZSBiYWNrLWVuZC5cbiAgICogT3RoZXJ3aXNlLCBpdCByZXR1cm5zIGBmYWxzZWAuXG4gICAqL1xuICBpc0Jhbm5lclZpc2libGUoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIGNvbWJpbmVMYXRlc3QoW1xuICAgICAgdGhpcy5pc0Jhbm5lckRpc21pc3NlZCgpLFxuICAgICAgdGhpcy5nZXRUZW1wbGF0ZXNVcGRhdGVkKCksXG4gICAgXSkucGlwZShcbiAgICAgIHRhcCgoKSA9PiB0aGlzLmNoZWNrQ29uc2VudFZlcnNpb25zKCkpLFxuICAgICAgbWFwKChbZGlzbWlzc2VkLCB1cGRhdGVkXSkgPT4gIWRpc21pc3NlZCB8fCB1cGRhdGVkKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRGlzcGF0Y2hlcyBhbiBhY3Rpb24gdG8gdHJpZ2dlciB0aGUgY2hlY2tcbiAgICogd2hldGhlciB0aGUgYW5vbnltb3VzIGNvbnNlbnQgdmVyc2lvbiBoYXZlIGJlZW4gdXBkYXRlZFxuICAgKi9cbiAgcHJpdmF0ZSBjaGVja0NvbnNlbnRWZXJzaW9ucygpOiB2b2lkIHtcbiAgICB0aGlzLnN0b3JlLmRpc3BhdGNoKFxuICAgICAgbmV3IEFub255bW91c0NvbnNlbnRzQWN0aW9ucy5Bbm9ueW1vdXNDb25zZW50Q2hlY2tVcGRhdGVkVmVyc2lvbnMoKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBgdHJ1ZWAgaWYgdGhlcmUncyBhIG1pc21hdGNoIGluIHRlbXBsYXRlIHZlcnNpb25zIGJldHdlZW4gdGhlIHByb3ZpZGVkIGBjdXJyZW50VGVtcGxhdGVzYCBhbmQgYG5ld1RlbXBsYXRlc2BcbiAgICogQHBhcmFtIGN1cnJlbnRUZW1wbGF0ZXMgY3VycmVudCB0ZW1wbGF0ZXMgdG8gY2hlY2tcbiAgICogQHBhcmFtIG5ld1RlbXBsYXRlcyBuZXcgdGVtcGxhdGVzIHRvIGNoZWNrXG4gICAqL1xuICBkZXRlY3RVcGRhdGVkVGVtcGxhdGVzKFxuICAgIGN1cnJlbnRUZW1wbGF0ZXM6IENvbnNlbnRUZW1wbGF0ZVtdLFxuICAgIG5ld1RlbXBsYXRlczogQ29uc2VudFRlbXBsYXRlW11cbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKG5ld1RlbXBsYXRlcy5sZW5ndGggIT09IGN1cnJlbnRUZW1wbGF0ZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5ld1RlbXBsYXRlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgbmV3VGVtcGxhdGUgPSBuZXdUZW1wbGF0ZXNbaV07XG4gICAgICBjb25zdCBjdXJyZW50VGVtcGxhdGUgPSBjdXJyZW50VGVtcGxhdGVzW2ldO1xuICAgICAgaWYgKG5ld1RlbXBsYXRlLnZlcnNpb24gIT09IGN1cnJlbnRUZW1wbGF0ZS52ZXJzaW9uKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXJpYWxpemVzIHVzaW5nIGBKU09OLnN0cmluZ2lmeSgpYCBhbmQgZW5jb2RlcyB1c2luZyBgZW5jb2RlVVJJQ29tcG9uZW50KClgIG1ldGhvZHNcbiAgICogQHBhcmFtIGNvbnNlbnRzIHRvIHNlcmlhbGl6ZSBhbmQgZW5jb2RlXG4gICAqL1xuICBzZXJpYWxpemVBbmRFbmNvZGUoY29uc2VudHM6IEFub255bW91c0NvbnNlbnRbXSk6IHN0cmluZyB7XG4gICAgaWYgKCFjb25zZW50cykge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICBjb25zdCBzZXJpYWxpemVkID0gSlNPTi5zdHJpbmdpZnkoY29uc2VudHMpO1xuICAgIGNvbnN0IGVuY29kZWQgPSBlbmNvZGVVUklDb21wb25lbnQoc2VyaWFsaXplZCk7XG4gICAgcmV0dXJuIGVuY29kZWQ7XG4gIH1cblxuICAvKipcbiAgICogRGVjb2RlcyB1c2luZyBgZGVjb2RlVVJJQ29tcG9uZW50KClgIGFuZCBkZXNlcmlhbGl6ZXMgdXNpbmcgYEpTT04ucGFyc2UoKWBcbiAgICogQHBhcmFtIHJhd0NvbnNlbnRzIHRvIGRlY29kZSBhbiBkZXNlcmlhbGl6ZVxuICAgKi9cbiAgZGVjb2RlQW5kRGVzZXJpYWxpemUocmF3Q29uc2VudHM6IHN0cmluZyk6IEFub255bW91c0NvbnNlbnRbXSB7XG4gICAgY29uc3QgZGVjb2RlZCA9IGRlY29kZVVSSUNvbXBvbmVudChyYXdDb25zZW50cyk7XG4gICAgY29uc3QgdW5zZXJpYWxpemVkID0gSlNPTi5wYXJzZShkZWNvZGVkKSBhcyBBbm9ueW1vdXNDb25zZW50W107XG4gICAgcmV0dXJuIHVuc2VyaWFsaXplZDtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBDb21wYXJlcyB0aGUgZ2l2ZW4gYG5ld0NvbnNlbnRzYCBhbmQgYHByZXZpb3VzQ29uc2VudHNgIGFuZCByZXR1cm5zIGB0cnVlYCBpZiB0aGVyZSBhcmUgZGlmZmVyZW5jZXMgKHRoZSBgbmV3Q29uc2VudHNgIGFyZSB1cGRhdGVzKS5cbiAgICogT3RoZXJ3aXNlIGl0IHJldHVybnMgYGZhbHNlYC5cbiAgICpcbiAgICogQHBhcmFtIG5ld0NvbnNlbnRzIG5ldyBjb25zZW50cyB0byBjb21wYXJlXG4gICAqIEBwYXJhbSBwcmV2aW91c0NvbnNlbnRzIG9sZCBjb25zZW50cyB0byBjb21wYXJlXG4gICAqL1xuICBjb25zZW50c1VwZGF0ZWQoXG4gICAgbmV3Q29uc2VudHM6IEFub255bW91c0NvbnNlbnRbXSxcbiAgICBwcmV2aW91c0NvbnNlbnRzOiBBbm9ueW1vdXNDb25zZW50W11cbiAgKTogYm9vbGVhbiB7XG4gICAgY29uc3QgbmV3UmF3Q29uc2VudHMgPSB0aGlzLnNlcmlhbGl6ZUFuZEVuY29kZShuZXdDb25zZW50cyk7XG4gICAgY29uc3QgcHJldmlvdXNSYXdDb25zZW50cyA9IHRoaXMuc2VyaWFsaXplQW5kRW5jb2RlKHByZXZpb3VzQ29uc2VudHMpO1xuICAgIHJldHVybiBuZXdSYXdDb25zZW50cyAhPT0gcHJldmlvdXNSYXdDb25zZW50cztcbiAgfVxufVxuIl19