angular-simple-oidc
Version:
Angular Library implementing Open Id Connect specification. Code Flow, Refresh Tokens, Session Management, Discovery Document.
86 lines • 17.9 kB
JavaScript
import { Injectable, Inject } from '@angular/core';
import { take, map, tap, withLatestFrom, switchMap, filter, takeUntil } from 'rxjs/operators';
import { TokenUrlService } from 'angular-simple-oidc/core';
import { Subject, fromEvent, interval } from 'rxjs';
import { EventsService, SimpleOidcInfoEvent } from 'angular-simple-oidc/events';
import { ConfigService } from 'angular-simple-oidc/config';
import { urlJoin } from '../utils/url-join';
import { WINDOW_REF, AUTH_CONFIG_SERVICE } from '../providers';
import { OidcCodeFlowClient } from '../oidc-code-flow-client.service';
import { TokenStorageService } from '../token-storage.service';
import { ChildWindowClosedError } from './errors';
import { POPUP_AUTHORIZATION_CONFIG_SERVICE } from './providers';
import * as i0 from "@angular/core";
import * as i1 from "../providers";
import * as i2 from "../token-storage.service";
import * as i3 from "./providers";
import * as i4 from "angular-simple-oidc/events";
import * as i5 from "../oidc-code-flow-client.service";
import * as i6 from "angular-simple-oidc/core";
// @dynamic
export class AuthorizeEndpointPopupClientService {
constructor(window, tokenStorage, authConfig, popupConfig, events, oidcClient, tokenUrl) {
this.window = window;
this.tokenStorage = tokenStorage;
this.authConfig = authConfig;
this.popupConfig = popupConfig;
this.events = events;
this.oidcClient = oidcClient;
this.tokenUrl = tokenUrl;
this.destroyedSubject = new Subject();
}
startCodeFlowInPopup(options = {}) {
const redirectUri$ = this.authConfig.current$
.pipe(withLatestFrom(this.popupConfig.current$), map(([authConfig, sessionConfig]) => urlJoin(authConfig.baseUrl, sessionConfig.childWindowPath)), take(1));
return redirectUri$
.pipe(tap(() => this.events.dispatch(new SimpleOidcInfoEvent(`Starting Code Flow in child window`))), switchMap((redirectUri) => this.oidcClient.generateCodeFlowMetadata({ redirectUri, display: 'popup', })
.pipe(map(metadata => ({ metadata, redirectUri })))), take(1), switchMap(({ metadata, redirectUri }) => {
this.events.dispatch(new SimpleOidcInfoEvent(`Creating window`, metadata));
const handle = this.window.open(metadata.url, '_blank', this.calculatePopupFeatures(options));
const handleClosed$ = interval(500)
.pipe(tap(() => console.info('polling')), filter(() => handle.closed), tap(() => this.events.dispatch(new SimpleOidcInfoEvent(`Child Window has been closed`))), tap(() => {
throw new ChildWindowClosedError({ metadata, redirectUri });
}), take(1));
return fromEvent(this.window, 'message')
.pipe(map((event) => ({ event, handle, metadata, redirectUri })), filter(({ event }) => event.data && typeof (event.data) === 'string'), filter(({ event }) => event.data.startsWith(redirectUri)), take(1), takeUntil(handleClosed$));
}), map(({ event, handle, metadata, redirectUri }) => {
const href = event.data;
this.events.dispatch(new SimpleOidcInfoEvent(`Obtained data from window`, { event, href }));
handle.close();
return {
href,
metadata,
redirectUri
};
}), switchMap(({ href, redirectUri, metadata }) => this.oidcClient.codeFlowCallback(href, redirectUri, metadata)), takeUntil(this.destroyedSubject));
}
ngOnDestroy() {
this.destroyedSubject.next();
this.destroyedSubject.complete();
}
calculatePopupFeatures(options) {
// Specify an static height and width and calculate centered position
const height = options.height || 660;
const width = options.width || 500;
const screen = this.window.screen;
const left = (screen.width / 2) - (width / 2);
const top = (screen.height / 2) - (height / 2);
return `location=no,toolbar=no,width=${width},height=${height},top=${top},left=${left}`;
}
}
AuthorizeEndpointPopupClientService.ɵprov = i0.ɵɵdefineInjectable({ factory: function AuthorizeEndpointPopupClientService_Factory() { return new AuthorizeEndpointPopupClientService(i0.ɵɵinject(i1.WINDOW_REF), i0.ɵɵinject(i2.TokenStorageService), i0.ɵɵinject(i1.AUTH_CONFIG_SERVICE), i0.ɵɵinject(i3.POPUP_AUTHORIZATION_CONFIG_SERVICE), i0.ɵɵinject(i4.EventsService), i0.ɵɵinject(i5.OidcCodeFlowClient), i0.ɵɵinject(i6.TokenUrlService)); }, token: AuthorizeEndpointPopupClientService, providedIn: "root" });
AuthorizeEndpointPopupClientService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] }
];
AuthorizeEndpointPopupClientService.ctorParameters = () => [
{ type: Window, decorators: [{ type: Inject, args: [WINDOW_REF,] }] },
{ type: TokenStorageService },
{ type: ConfigService, decorators: [{ type: Inject, args: [AUTH_CONFIG_SERVICE,] }] },
{ type: ConfigService, decorators: [{ type: Inject, args: [POPUP_AUTHORIZATION_CONFIG_SERVICE,] }] },
{ type: EventsService },
{ type: OidcCodeFlowClient },
{ type: TokenUrlService }
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aG9yaXplLWVuZHBvaW50LXBvcHVwLWNsaWVudC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1zaW1wbGUtb2lkYy9zcmMvbGliL3BvcHVwLWF1dGhvcml6YXRpb24vYXV0aG9yaXplLWVuZHBvaW50LXBvcHVwLWNsaWVudC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFhLE1BQU0sZUFBZSxDQUFDO0FBQzlELE9BQU8sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxjQUFjLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5RixPQUFPLEVBQUUsZUFBZSxFQUFzQixNQUFNLDBCQUEwQixDQUFDO0FBQy9FLE9BQU8sRUFBRSxPQUFPLEVBQWMsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNoRSxPQUFPLEVBQUUsYUFBYSxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDaEYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzNELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM1QyxPQUFPLEVBQUUsVUFBVSxFQUFFLG1CQUFtQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRS9ELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQy9ELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUVsRCxPQUFPLEVBQUUsa0NBQWtDLEVBQUUsTUFBTSxhQUFhLENBQUM7Ozs7Ozs7O0FBRWpFLFdBQVc7QUFJWCxNQUFNLE9BQU8sbUNBQW1D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QUM7SUFDckMsQ0FBQztJQUVTLHNCQUFzQixDQUFDLE9BQTRDO1FBQ3pFLHFFQUFxRTtRQUNyRSxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLEdBQUcsQ0FBQztRQUNyQyxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxJQUFJLEdBQUcsQ0FBQztRQUNuQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUNsQyxNQUFNLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDOUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQy9DLE9BQU8sZ0NBQWdDLEtBQUssV0FBVyxNQUFNLFFBQVEsR0FBRyxTQUFTLElBQUksRUFBRSxDQUFDO0lBQzVGLENBQUM7Ozs7WUF2RkosVUFBVSxTQUFDO2dCQUNSLFVBQVUsRUFBRSxNQUFNO2FBQ3JCOzs7WUFPa0MsTUFBTSx1QkFEaEMsTUFBTSxTQUFDLFVBQVU7WUFkakIsbUJBQW1CO1lBTG5CLGFBQWEsdUJBc0JiLE1BQU0sU0FBQyxtQkFBbUI7WUF0QjFCLGFBQWEsdUJBd0JiLE1BQU0sU0FBQyxrQ0FBa0M7WUF6QnpDLGFBQWE7WUFLYixrQkFBa0I7WUFQbEIsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIEluamVjdCwgT25EZXN0cm95IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlLCBtYXAsIHRhcCwgd2l0aExhdGVzdEZyb20sIHN3aXRjaE1hcCwgZmlsdGVyLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUb2tlblVybFNlcnZpY2UsIFRva2VuUmVxdWVzdFJlc3VsdCB9IGZyb20gJ2FuZ3VsYXItc2ltcGxlLW9pZGMvY29yZSc7XG5pbXBvcnQgeyBTdWJqZWN0LCBPYnNlcnZhYmxlLCBmcm9tRXZlbnQsIGludGVydmFsIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBFdmVudHNTZXJ2aWNlLCBTaW1wbGVPaWRjSW5mb0V2ZW50IH0gZnJvbSAnYW5ndWxhci1zaW1wbGUtb2lkYy9ldmVudHMnO1xuaW1wb3J0IHsgQ29uZmlnU2VydmljZSB9IGZyb20gJ2FuZ3VsYXItc2ltcGxlLW9pZGMvY29uZmlnJztcbmltcG9ydCB7IHVybEpvaW4gfSBmcm9tICcuLi91dGlscy91cmwtam9pbic7XG5pbXBvcnQgeyBXSU5ET1dfUkVGLCBBVVRIX0NPTkZJR19TRVJWSUNFIH0gZnJvbSAnLi4vcHJvdmlkZXJzJztcbmltcG9ydCB7IEF1dGhDb25maWcgfSBmcm9tICcuLi9jb25maWcvbW9kZWxzJztcbmltcG9ydCB7IE9pZGNDb2RlRmxvd0NsaWVudCB9IGZyb20gJy4uL29pZGMtY29kZS1mbG93LWNsaWVudC5zZXJ2aWNlJztcbmltcG9ydCB7IFRva2VuU3RvcmFnZVNlcnZpY2UgfSBmcm9tICcuLi90b2tlbi1zdG9yYWdlLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ2hpbGRXaW5kb3dDbG9zZWRFcnJvciB9IGZyb20gJy4vZXJyb3JzJztcbmltcG9ydCB7IFBvcHVwQXV0aG9yaXphdGlvbkNvbmZpZyB9IGZyb20gJy4vbW9kZWxzJztcbmltcG9ydCB7IFBPUFVQX0FVVEhPUklaQVRJT05fQ09ORklHX1NFUlZJQ0UgfSBmcm9tICcuL3Byb3ZpZGVycyc7XG5cbi8vIEBkeW5hbWljXG5ASW5qZWN0YWJsZSh7XG4gICAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEF1dGhvcml6ZUVuZHBvaW50UG9wdXBDbGllbnRTZXJ2aWNlIGltcGxlbWVudHMgT25EZXN0cm95IHtcblxuICAgIHByb3RlY3RlZCBkZXN0cm95ZWRTdWJqZWN0ID0gbmV3IFN1YmplY3QoKTtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBASW5qZWN0KFdJTkRPV19SRUYpXG4gICAgICAgIHByb3RlY3RlZCByZWFkb25seSB3aW5kb3c6IFdpbmRvdyxcbiAgICAgICAgcHJvdGVjdGVkIHJlYWRvbmx5IHRva2VuU3RvcmFnZTogVG9rZW5TdG9yYWdlU2VydmljZSxcbiAgICAgICAgQEluamVjdChBVVRIX0NPTkZJR19TRVJWSUNFKVxuICAgICAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgYXV0aENvbmZpZzogQ29uZmlnU2VydmljZTxBdXRoQ29uZmlnPixcbiAgICAgICAgQEluamVjdChQT1BVUF9BVVRIT1JJWkFUSU9OX0NPTkZJR19TRVJWSUNFKVxuICAgICAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgcG9wdXBDb25maWc6IENvbmZpZ1NlcnZpY2U8UG9wdXBBdXRob3JpemF0aW9uQ29uZmlnPixcbiAgICAgICAgcHJvdGVjdGVkIHJlYWRvbmx5IGV2ZW50czogRXZlbnRzU2VydmljZSxcbiAgICAgICAgcHJvdGVjdGVkIHJlYWRvbmx5IG9pZGNDbGllbnQ6IE9pZGNDb2RlRmxvd0NsaWVudCxcbiAgICAgICAgcHJvdGVjdGVkIHJlYWRvbmx5IHRva2VuVXJsOiBUb2tlblVybFNlcnZpY2UsXG4gICAgKSB7IH1cblxuICAgIHB1YmxpYyBzdGFydENvZGVGbG93SW5Qb3B1cChvcHRpb25zOiB7IGhlaWdodD86IG51bWJlciwgd2lkdGg/OiBudW1iZXIgfSA9IHt9KTogT2JzZXJ2YWJsZTxUb2tlblJlcXVlc3RSZXN1bHQ+IHtcbiAgICAgICAgY29uc3QgcmVkaXJlY3RVcmkkID0gdGhpcy5hdXRoQ29uZmlnLmN1cnJlbnQkXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICB3aXRoTGF0ZXN0RnJvbSh0aGlzLnBvcHVwQ29uZmlnLmN1cnJlbnQkKSxcbiAgICAgICAgICAgICAgICBtYXAoKFthdXRoQ29uZmlnLCBzZXNzaW9uQ29uZmlnXSkgPT4gdXJsSm9pbihhdXRoQ29uZmlnLmJhc2VVcmwsIHNlc3Npb25Db25maWcuY2hpbGRXaW5kb3dQYXRoKSksXG4gICAgICAgICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIHJlZGlyZWN0VXJpJFxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgdGFwKCgpID0+IHRoaXMuZXZlbnRzLmRpc3BhdGNoKG5ldyBTaW1wbGVPaWRjSW5mb0V2ZW50KGBTdGFydGluZyBDb2RlIEZsb3cgaW4gY2hpbGQgd2luZG93YCkpKSxcbiAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKHJlZGlyZWN0VXJpKSA9PlxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9pZGNDbGllbnQuZ2VuZXJhdGVDb2RlRmxvd01ldGFkYXRhKHsgcmVkaXJlY3RVcmksIGRpc3BsYXk6ICdwb3B1cCcsIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAucGlwZShtYXAobWV0YWRhdGEgPT4gKHsgbWV0YWRhdGEsIHJlZGlyZWN0VXJpIH0pKSlcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIHRha2UoMSksXG4gICAgICAgICAgICAgICAgc3dpdGNoTWFwKCh7IG1ldGFkYXRhLCByZWRpcmVjdFVyaSB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzLmRpc3BhdGNoKG5ldyBTaW1wbGVPaWRjSW5mb0V2ZW50KGBDcmVhdGluZyB3aW5kb3dgLCBtZXRhZGF0YSkpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBoYW5kbGUgPSB0aGlzLndpbmRvdy5vcGVuKG1ldGFkYXRhLnVybCwgJ19ibGFuaycsIHRoaXMuY2FsY3VsYXRlUG9wdXBGZWF0dXJlcyhvcHRpb25zKSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZUNsb3NlZCQgPSBpbnRlcnZhbCg1MDApXG4gICAgICAgICAgICAgICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXAoKCkgPT4gY29uc29sZS5pbmZvKCdwb2xsaW5nJykpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcigoKSA9PiBoYW5kbGUuY2xvc2VkKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXAoKCkgPT4gdGhpcy5ldmVudHMuZGlzcGF0Y2gobmV3IFNpbXBsZU9pZGNJbmZvRXZlbnQoYENoaWxkIFdpbmRvdyBoYXMgYmVlbiBjbG9zZWRgKSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDaGlsZFdpbmRvd0Nsb3NlZEVycm9yKHsgbWV0YWRhdGEsIHJlZGlyZWN0VXJpIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRha2UoMSlcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZyb21FdmVudCh0aGlzLndpbmRvdywgJ21lc3NhZ2UnKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwKChldmVudDogTWVzc2FnZUV2ZW50KSA9PiAoeyBldmVudCwgaGFuZGxlLCBtZXRhZGF0YSwgcmVkaXJlY3RVcmkgfSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcigoeyBldmVudCB9KSA9PiBldmVudC5kYXRhICYmIHR5cGVvZiAoZXZlbnQuZGF0YSkgPT09ICdzdHJpbmcnKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoKHsgZXZlbnQgfSkgPT4gKGV2ZW50LmRhdGEgYXMgc3RyaW5nKS5zdGFydHNXaXRoKHJlZGlyZWN0VXJpKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWtlVW50aWwoaGFuZGxlQ2xvc2VkJCksXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIG1hcCgoeyBldmVudCwgaGFuZGxlLCBtZXRhZGF0YSwgcmVkaXJlY3RVcmkgfSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBocmVmID0gZXZlbnQuZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudHMuZGlzcGF0Y2gobmV3IFNpbXBsZU9pZGNJbmZvRXZlbnQoYE9idGFpbmVkIGRhdGEgZnJvbSB3aW5kb3dgLCB7IGV2ZW50LCBocmVmIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlLmNsb3NlKCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBocmVmLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICByZWRpcmVjdFVyaVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoeyBocmVmLCByZWRpcmVjdFVyaSwgbWV0YWRhdGEgfSkgPT4gdGhpcy5vaWRjQ2xpZW50LmNvZGVGbG93Q2FsbGJhY2soaHJlZiwgcmVkaXJlY3RVcmksIG1ldGFkYXRhKSksXG4gICAgICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveWVkU3ViamVjdClcbiAgICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIG5nT25EZXN0cm95KCkge1xuICAgICAgICB0aGlzLmRlc3Ryb3llZFN1YmplY3QubmV4dCgpO1xuICAgICAgICB0aGlzLmRlc3Ryb3llZFN1YmplY3QuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgY2FsY3VsYXRlUG9wdXBGZWF0dXJlcyhvcHRpb25zOiB7IGhlaWdodD86IG51bWJlciwgd2lkdGg/OiBudW1iZXIgfSkge1xuICAgICAgICAvLyBTcGVjaWZ5IGFuIHN0YXRpYyBoZWlnaHQgYW5kIHdpZHRoIGFuZCBjYWxjdWxhdGUgY2VudGVyZWQgcG9zaXRpb25cbiAgICAgICAgY29uc3QgaGVpZ2h0ID0gb3B0aW9ucy5oZWlnaHQgfHwgNjYwO1xuICAgICAgICBjb25zdCB3aWR0aCA9IG9wdGlvbnMud2lkdGggfHwgNTAwO1xuICAgICAgICBjb25zdCBzY3JlZW4gPSB0aGlzLndpbmRvdy5zY3JlZW47XG4gICAgICAgIGNvbnN0IGxlZnQgPSAoc2NyZWVuLndpZHRoIC8gMikgLSAod2lkdGggLyAyKTtcbiAgICAgICAgY29uc3QgdG9wID0gKHNjcmVlbi5oZWlnaHQgLyAyKSAtIChoZWlnaHQgLyAyKTtcbiAgICAgICAgcmV0dXJuIGBsb2NhdGlvbj1ubyx0b29sYmFyPW5vLHdpZHRoPSR7d2lkdGh9LGhlaWdodD0ke2hlaWdodH0sdG9wPSR7dG9wfSxsZWZ0PSR7bGVmdH1gO1xuICAgIH1cbn1cbiJdfQ==