UNPKG

ng-dynami-social-login

Version:

This is social login API for Angular 7.0.3 (Facebook, Google and Linkedin)

563 lines 64.5 kB
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('rxjs'), require('@angular/common')) :
    typeof define === 'function' && define.amd ? define('ng-dynami-social-login', ['exports', '@angular/core', 'rxjs', '@angular/common'], factory) :
    (factory((global['ng-dynami-social-login'] = {}),global.ng.core,global.rxjs,global.ng.common));
}(this, (function (exports,core,rxjs,common) { 'use strict';

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
     */
    /**
     * @abstract
     */
    var /**
     * @abstract
     */ BaseLoginProvider = /** @class */ (function () {
        function BaseLoginProvider() {
        }
        /**
         * @param {?} obj
         * @param {?} onload
         * @return {?}
         */
        BaseLoginProvider.prototype.loadScript = /**
         * @param {?} obj
         * @param {?} onload
         * @return {?}
         */
            function (obj, onload) {
                if (document.getElementById(obj.name)) {
                    return;
                }
                /** @type {?} */
                var signInJS = document.createElement('script');
                signInJS.async = true;
                signInJS.src = obj.url;
                signInJS.onload = onload;
                if (obj.name === 'LINKEDIN') {
                    signInJS.async = false;
                    signInJS.text = ('api_key: ' + obj.id).replace('\'', '');
                }
                document.head.appendChild(signInJS);
            };
        return BaseLoginProvider;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
     */
    var LinkedInResponseModel = /** @class */ (function () {
        function LinkedInResponseModel() {
        }
        return LinkedInResponseModel;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
     */
    var LoginProviderClassModel = /** @class */ (function () {
        function LoginProviderClassModel() {
        }
        return LoginProviderClassModel;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
     */
    var SocialUserModel = /** @class */ (function () {
        function SocialUserModel() {
        }
        return SocialUserModel;
    }());

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation. All rights reserved.
    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
    this file except in compliance with the License. You may obtain a copy of the
    License at http://www.apache.org/licenses/LICENSE-2.0

    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
    MERCHANTABLITY OR NON-INFRINGEMENT.

    See the Apache Version 2.0 License for specific language governing permissions
    and limitations under the License.
    ***************************************************************************** */
    /* global Reflect, Promise */
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b)
                if (b.hasOwnProperty(p))
                    d[p] = b[p]; };
        return extendStatics(d, b);
    };
    function __extends(d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
     */
    var FacebookLoginProvider = /** @class */ (function (_super) {
        __extends(FacebookLoginProvider, _super);
        function FacebookLoginProvider(clientId) {
            var _this = _super.call(this) || this;
            _this.clientId = clientId;
            _this.loginProviderObj = new LoginProviderClassModel();
            _this.loginProviderObj.id = clientId;
            _this.loginProviderObj.name = 'facebook';
            _this.loginProviderObj.url = 'https://connect.facebook.net/en_US/sdk.js';
            return _this;
        }
        /**
         * @return {?}
         */
        FacebookLoginProvider.prototype.initialize = /**
         * @return {?}
         */
            function () {
                var _this = this;
                return new Promise(function (resolve, reject) {
                    _this.loadScript(_this.loginProviderObj, function () {
                        FB.init({
                            appId: _this.clientId,
                            autoLogAppEvents: true,
                            cookie: true,
                            xfbml: true,
                            version: 'v2.10'
                        });
                        FB.AppEvents.logPageView();
                        FB.getLoginStatus(function (response) {
                            if (response.status === 'connected') {
                                /** @type {?} */
                                var accessToken_1 = FB.getAuthResponse()['accessToken'];
                                FB.api('/me?fields=name,email,picture', function (res) {
                                    resolve(FacebookLoginProvider.drawUser(Object.assign({}, { token: accessToken_1 }, res)));
                                });
                            }
                        });
                    });
                });
            };
        /**
         * @param {?} response
         * @return {?}
         */
        FacebookLoginProvider.drawUser = /**
         * @param {?} response
         * @return {?}
         */
            function (response) {
                /** @type {?} */
                var user = new SocialUserModel();
                user.id = response.id;
                user.name = response.name;
                user.email = response.email;
                user.token = response.token;
                user.image = 'https://graph.facebook.com/' + response.id + '/picture?type=normal';
                return user;
            };
        /**
         * @return {?}
         */
        FacebookLoginProvider.prototype.signIn = /**
         * @return {?}
         */
            function () {
                return new Promise(function (resolve, reject) {
                    FB.login(function (response) {
                        if (response.authResponse) {
                            /** @type {?} */
                            var accessToken_2 = FB.getAuthResponse()['accessToken'];
                            FB.api('/me?fields=name,email,picture', function (res) {
                                resolve(FacebookLoginProvider.drawUser(Object.assign({}, { token: accessToken_2 }, res)));
                            });
                        }
                    }, { scope: 'email,public_profile' });
                });
            };
        /**
         * @return {?}
         */
        FacebookLoginProvider.prototype.signOut = /**
         * @return {?}
         */
            function () {
                return new Promise(function (resolve, reject) {
                    FB.logout(function (response) {
                        resolve();
                    });
                });
            };
        FacebookLoginProvider.PROVIDER_ID = 'facebook';
        return FacebookLoginProvider;
    }(BaseLoginProvider));

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
     */
    var GoogleLoginProvider = /** @class */ (function (_super) {
        __extends(GoogleLoginProvider, _super);
        function GoogleLoginProvider(clientId) {
            var _this = _super.call(this) || this;
            _this.clientId = clientId;
            _this.loginProviderObj = new LoginProviderClassModel();
            _this.loginProviderObj.id = clientId;
            _this.loginProviderObj.name = 'google';
            _this.loginProviderObj.url = 'https://apis.google.com/js/platform.js';
            return _this;
        }
        /**
         * @return {?}
         */
        GoogleLoginProvider.prototype.initialize = /**
         * @return {?}
         */
            function () {
                var _this = this;
                return new Promise(function (resolve, reject) {
                    _this.loadScript(_this.loginProviderObj, function () {
                        gapi.load('auth2', function () {
                            _this.auth2 = gapi.auth2.init({
                                client_id: _this.clientId,
                                scope: 'email'
                            });
                            _this.auth2.then(function () {
                                if (_this.auth2.isSignedIn.get()) {
                                    resolve(_this.drawUser());
                                }
                            });
                        });
                    });
                });
            };
        /**
         * @return {?}
         */
        GoogleLoginProvider.prototype.drawUser = /**
         * @return {?}
         */
            function () {
                /** @type {?} */
                var user = new SocialUserModel();
                /** @type {?} */
                var profile = this.auth2.currentUser.get().getBasicProfile();
                /** @type {?} */
                var authResponseObj = this.auth2.currentUser.get().getAuthResponse(true);
                user.id = profile.getId();
                user.name = profile.getName();
                user.email = profile.getEmail();
                user.image = profile.getImageUrl();
                user.token = authResponseObj.access_token;
                user.idToken = authResponseObj.id_token;
                return user;
            };
        /**
         * @return {?}
         */
        GoogleLoginProvider.prototype.signIn = /**
         * @return {?}
         */
            function () {
                var _this = this;
                return new Promise(function (resolve, reject) {
                    /** @type {?} */
                    var promise = _this.auth2.signIn();
                    promise.then(function () {
                        resolve(_this.drawUser());
                    });
                });
            };
        /**
         * @return {?}
         */
        GoogleLoginProvider.prototype.signOut = /**
         * @return {?}
         */
            function () {
                var _this = this;
                return new Promise(function (resolve, reject) {
                    _this.auth2.signOut().then(function (err) {
                        if (err) {
                            reject(err);
                        }
                        else {
                            resolve();
                        }
                    });
                });
            };
        GoogleLoginProvider.PROVIDER_ID = 'google';
        return GoogleLoginProvider;
    }(BaseLoginProvider));

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
     */
    var LinkedinLoginProvider = /** @class */ (function (_super) {
        __extends(LinkedinLoginProvider, _super);
        function LinkedinLoginProvider(clientId) {
            var _this = _super.call(this) || this;
            _this.clientId = clientId;
            _this.loginProviderObj = new LoginProviderClassModel();
            _this.loginProviderObj.id = clientId;
            _this.loginProviderObj.name = 'linkedin';
            _this.loginProviderObj.url = 'https://platform.linkedin.com/in.js';
            return _this;
        }
        /**
         * @return {?}
         */
        LinkedinLoginProvider.prototype.initialize = /**
         * @return {?}
         */
            function () {
                var _this = this;
                return new Promise(function (resolve, reject) {
                    _this.loadScript(_this.loginProviderObj, function () {
                        IN.init({
                            api_key: _this.clientId,
                            authorize: true,
                            onLoad: _this.onLinkedInLoad()
                        });
                        IN.Event.on(IN, 'auth', function () {
                            if (IN.User.isAuthorized()) {
                                IN.API.Raw('/people/~:(id,first-name,last-name,email-address,picture-url)').result(function (res) {
                                    resolve(_this.drawUser(res));
                                });
                            }
                        });
                    });
                });
            };
        /**
         * @return {?}
         */
        LinkedinLoginProvider.prototype.onLinkedInLoad = /**
         * @return {?}
         */
            function () {
                IN.Event.on(IN, 'systemReady', function () {
                    IN.User.refresh();
                });
            };
        /**
         * @param {?} response
         * @return {?}
         */
        LinkedinLoginProvider.prototype.drawUser = /**
         * @param {?} response
         * @return {?}
         */
            function (response) {
                /** @type {?} */
                var user = new SocialUserModel();
                user.id = response.emailAddress;
                user.name = response.firstName + ' ' + response.lastName;
                user.email = response.emailAddress;
                user.image = response.pictureUrl;
                user.token = IN.ENV.auth.oauth_token;
                return user;
            };
        /**
         * @return {?}
         */
        LinkedinLoginProvider.prototype.signIn = /**
         * @return {?}
         */
            function () {
                var _this = this;
                return new Promise(function (resolve, reject) {
                    IN.User.authorize(function () {
                        IN.API.Raw('/people/~:(id,first-name,last-name,email-address,picture-url)').result(function (res) {
                            resolve(_this.drawUser(res));
                        });
                    });
                });
            };
        /**
         * @return {?}
         */
        LinkedinLoginProvider.prototype.signOut = /**
         * @return {?}
         */
            function () {
                return new Promise(function (resolve, reject) {
                    IN.User.logout(function (response) {
                        resolve();
                    }, function (err) {
                        reject(err);
                    });
                });
            };
        LinkedinLoginProvider.PROVIDER_ID = 'linkedin';
        return LinkedinLoginProvider;
    }(BaseLoginProvider));

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
     */
    var AuthServiceConfig = /** @class */ (function () {
        function AuthServiceConfig(providers) {
            this.providers = new Map();
            for (var i = 0; i < providers.length; i++) {
                /** @type {?} */
                var element = providers[i];
                this.providers.set(element.id, element.provider);
            }
        }
        return AuthServiceConfig;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
     */
    var AuthService = /** @class */ (function () {
        function AuthService(config) {
            var _this = this;
            this._user = null;
            this._authState = new rxjs.BehaviorSubject(null);
            this.providers = config.providers;
            this.providers.forEach(function (provider, key) {
                provider.initialize().then(function (user) {
                    user.provider = key;
                    _this._user = user;
                    _this._authState.next(user);
                }).catch(function (err) {
                    // this._authState.next(null);
                });
            });
        }
        Object.defineProperty(AuthService.prototype, "authState", {
            get: /**
             * @return {?}
             */ function () {
                return this._authState.asObservable();
            },
            enumerable: true,
            configurable: true
        });
        /**
         * @param {?} providerId
         * @return {?}
         */
        AuthService.prototype.signIn = /**
         * @param {?} providerId
         * @return {?}
         */
            function (providerId) {
                var _this = this;
                return new Promise(function (resolve, reject) {
                    /** @type {?} */
                    var providerObject = _this.providers.get(providerId);
                    if (providerObject) {
                        providerObject.signIn().then(function (user) {
                            user.provider = providerId;
                            resolve(user);
                            _this._user = user;
                            _this._authState.next(user);
                        });
                    }
                    else {
                        reject(AuthService.LOGIN_PROVIDER_NOT_FOUND);
                    }
                });
            };
        /**
         * @return {?}
         */
        AuthService.prototype.signOut = /**
         * @return {?}
         */
            function () {
                var _this = this;
                return new Promise(function (resolve, reject) {
                    if (_this._user && _this._user.provider) {
                        /** @type {?} */
                        var providerId = _this._user.provider;
                        /** @type {?} */
                        var providerObject = _this.providers.get(providerId);
                        providerObject.signOut().then(function () {
                            _this._user = null;
                            _this._authState.next(null);
                            resolve();
                        }).catch(function (err) {
                            _this._authState.next(null);
                        });
                    }
                    else {
                        reject(AuthService.LOGIN_PROVIDER_NOT_FOUND);
                    }
                });
            };
        AuthService.LOGIN_PROVIDER_NOT_FOUND = 'Login provider not found';
        AuthService.decorators = [
            { type: core.Injectable }
        ];
        /** @nocollapse */
        AuthService.ctorParameters = function () {
            return [
                { type: AuthServiceConfig }
            ];
        };
        return AuthService;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
     */
    var DynamiSocialLoginModule = /** @class */ (function () {
        function DynamiSocialLoginModule() {
        }
        DynamiSocialLoginModule.decorators = [
            { type: core.NgModule, args: [{
                        imports: [
                            common.CommonModule
                        ],
                        declarations: [],
                        providers: [AuthService],
                    },] }
        ];
        return DynamiSocialLoginModule;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
     */

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
     */

    exports.BaseLoginProvider = BaseLoginProvider;
    exports.LinkedInResponseModel = LinkedInResponseModel;
    exports.LoginProviderClassModel = LoginProviderClassModel;
    exports.SocialUserModel = SocialUserModel;
    exports.FacebookLoginProvider = FacebookLoginProvider;
    exports.GoogleLoginProvider = GoogleLoginProvider;
    exports.LinkedinLoginProvider = LinkedinLoginProvider;
    exports.AuthServiceConfig = AuthServiceConfig;
    exports.AuthService = AuthService;
    exports.DynamiSocialLoginModule = DynamiSocialLoginModule;

    Object.defineProperty(exports, '__esModule', { value: true });

})));

//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctZHluYW1pLXNvY2lhbC1sb2dpbi51bWQuanMubWFwIiwic291cmNlcyI6WyJuZzovL25nLWR5bmFtaS1zb2NpYWwtbG9naW4vbGliL2R5bmFtaS1zb2NpYWwtbG9naW4vbW9kZWxzL2Jhc2UubG9naW4ucHJvdmlkZXIudHMiLCJuZzovL25nLWR5bmFtaS1zb2NpYWwtbG9naW4vbGliL2R5bmFtaS1zb2NpYWwtbG9naW4vbW9kZWxzL2xpbmtlZGluLnJlc3BvbnNlLm1vZGVsLnRzIiwibmc6Ly9uZy1keW5hbWktc29jaWFsLWxvZ2luL2xpYi9keW5hbWktc29jaWFsLWxvZ2luL21vZGVscy9sb2dpbi5wcm92aWRlci5jbGFzcy5tb2RlbC50cyIsIm5nOi8vbmctZHluYW1pLXNvY2lhbC1sb2dpbi9saWIvZHluYW1pLXNvY2lhbC1sb2dpbi9tb2RlbHMvc29jaWFsLnVzZXIubW9kZWwudHMiLCJub2RlX21vZHVsZXMvdHNsaWIvdHNsaWIuZXM2LmpzIiwibmc6Ly9uZy1keW5hbWktc29jaWFsLWxvZ2luL2xpYi9keW5hbWktc29jaWFsLWxvZ2luL3Byb3ZpZGVycy9mYWNlYm9vay5sb2dpbi5wcm92aWRlci50cyIsIm5nOi8vbmctZHluYW1pLXNvY2lhbC1sb2dpbi9saWIvZHluYW1pLXNvY2lhbC1sb2dpbi9wcm92aWRlcnMvZ29vZ2xlLmxvZ2luLnByb3ZpZGVyLnRzIiwibmc6Ly9uZy1keW5hbWktc29jaWFsLWxvZ2luL2xpYi9keW5hbWktc29jaWFsLWxvZ2luL3Byb3ZpZGVycy9saW5rZWRpbi5sb2dpbi5wcm92aWRlci50cyIsIm5nOi8vbmctZHluYW1pLXNvY2lhbC1sb2dpbi9saWIvZHluYW1pLXNvY2lhbC1sb2dpbi9zZXJ2aWNlcy9hdXRoLnNlcnZpY2UuY29uZmlnLnRzIiwibmc6Ly9uZy1keW5hbWktc29jaWFsLWxvZ2luL2xpYi9keW5hbWktc29jaWFsLWxvZ2luL3NlcnZpY2VzL2F1dGguc2VydmljZS50cyIsIm5nOi8vbmctZHluYW1pLXNvY2lhbC1sb2dpbi9saWIvZHluYW1pLXNvY2lhbC1sb2dpbi9keW5hbWktc29jaWFsLWxvZ2luLm1vZHVsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTb2NpYWxVc2VyTW9kZWwgfSBmcm9tIFwiLi9zb2NpYWwudXNlci5tb2RlbFwiO1xyXG5pbXBvcnQgeyBMb2dpblByb3ZpZGVyIH0gZnJvbSBcIi4vbG9naW4ucHJvdmlkZXJcIjtcclxuaW1wb3J0IHsgTG9naW5Qcm92aWRlckNsYXNzTW9kZWwgfSBmcm9tIFwiLi9sb2dpbi5wcm92aWRlci5jbGFzcy5tb2RlbFwiO1xyXG5cclxuXHJcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBCYXNlTG9naW5Qcm92aWRlciBpbXBsZW1lbnRzIExvZ2luUHJvdmlkZXIge1xyXG4gIGNvbnN0cnVjdG9yKCkge31cclxuXHJcbiAgYWJzdHJhY3QgaW5pdGlhbGl6ZSgpOiBQcm9taXNlPFNvY2lhbFVzZXJNb2RlbD47XHJcbiAgYWJzdHJhY3Qgc2lnbkluKCk6IFByb21pc2U8U29jaWFsVXNlck1vZGVsPjtcclxuICBhYnN0cmFjdCBzaWduT3V0KCk6IFByb21pc2U8YW55PjtcclxuXHJcbiAgbG9hZFNjcmlwdChvYmo6IExvZ2luUHJvdmlkZXJDbGFzc01vZGVsLCBvbmxvYWQ6IGFueSk6IHZvaWQge1xyXG4gICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKG9iai5uYW1lKSkgeyByZXR1cm47IH1cclxuICAgIGxldCBzaWduSW5KUyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xyXG4gICAgc2lnbkluSlMuYXN5bmMgPSB0cnVlO1xyXG4gICAgc2lnbkluSlMuc3JjID0gb2JqLnVybDtcclxuICAgIHNpZ25JbkpTLm9ubG9hZCA9IG9ubG9hZDtcclxuICAgIGlmIChvYmoubmFtZSA9PT0gJ0xJTktFRElOJykge1xyXG4gICAgICBzaWduSW5KUy5hc3luYyA9IGZhbHNlO1xyXG4gICAgICBzaWduSW5KUy50ZXh0ID0gKCdhcGlfa2V5OiAnICsgb2JqLmlkKS5yZXBsYWNlKCdcXCcnLCAnJyk7XHJcbiAgICB9XHJcbiAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHNpZ25JbkpTKTtcclxuICB9XHJcbn0iLCJleHBvcnQgY2xhc3MgTGlua2VkSW5SZXNwb25zZU1vZGVsIHtcclxuICAgIGVtYWlsQWRkcmVzczogc3RyaW5nO1xyXG4gICAgZmlyc3ROYW1lOiBzdHJpbmc7XHJcbiAgICBpZDogc3RyaW5nO1xyXG4gICAgbGFzdE5hbWU6IHN0cmluZztcclxuICAgIHBpY3R1cmVVcmw6IHN0cmluZztcclxuICB9IiwiZXhwb3J0IGNsYXNzIExvZ2luUHJvdmlkZXJDbGFzc01vZGVsIHtcclxuICAgIG5hbWU6IHN0cmluZztcclxuICAgIGlkOiBzdHJpbmc7XHJcbiAgICB1cmw6IHN0cmluZztcclxuICB9IiwiZXhwb3J0IGNsYXNzIFNvY2lhbFVzZXJNb2RlbCB7XHJcbiAgICBwcm92aWRlcjogc3RyaW5nO1xyXG4gICAgaWQ6IHN0cmluZztcclxuICAgIGVtYWlsOiBzdHJpbmc7XHJcbiAgICBuYW1lOiBzdHJpbmc7XHJcbiAgICBpbWFnZTogc3RyaW5nO1xyXG4gICAgdG9rZW4/OiBzdHJpbmc7XHJcbiAgICBpZFRva2VuPzogc3RyaW5nXHJcbiAgfVxyXG4gIFxyXG5cclxuICBcclxuIiwiLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2VcclxudGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGVcclxuTGljZW5zZSBhdCBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcclxuXHJcblRISVMgQ09ERSBJUyBQUk9WSURFRCBPTiBBTiAqQVMgSVMqIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcclxuS0lORCwgRUlUSEVSIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIFdJVEhPVVQgTElNSVRBVElPTiBBTlkgSU1QTElFRFxyXG5XQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgVElUTEUsIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLFxyXG5NRVJDSEFOVEFCTElUWSBPUiBOT04tSU5GUklOR0VNRU5ULlxyXG5cclxuU2VlIHRoZSBBcGFjaGUgVmVyc2lvbiAyLjAgTGljZW5zZSBmb3Igc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zXHJcbmFuZCBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19hc3NpZ24gPSBmdW5jdGlvbigpIHtcclxuICAgIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiBfX2Fzc2lnbih0KSB7XHJcbiAgICAgICAgZm9yICh2YXIgcywgaSA9IDEsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSkgdFtwXSA9IHNbcF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIF9fYXNzaWduLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Jlc3QocywgZSkge1xyXG4gICAgdmFyIHQgPSB7fTtcclxuICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxyXG4gICAgICAgIHRbcF0gPSBzW3BdO1xyXG4gICAgaWYgKHMgIT0gbnVsbCAmJiB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gXCJmdW5jdGlvblwiKVxyXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIGlmIChlLmluZGV4T2YocFtpXSkgPCAwKVxyXG4gICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5tZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0ZXIodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHJlc3VsdC52YWx1ZSk7IH0pLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHBvcnRTdGFyKG0sIGV4cG9ydHMpIHtcclxuICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKCFleHBvcnRzLmhhc093blByb3BlcnR5KHApKSBleHBvcnRzW3BdID0gbVtwXTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXSwgaSA9IDA7XHJcbiAgICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVhZChvLCBuKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZCgpIHtcclxuICAgIGZvciAodmFyIGFyID0gW10sIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaWYgKGdbbl0pIGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBuID09PSBcInJldHVyblwiIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0U3Rhcihtb2QpIHtcclxuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XHJcbiAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgaW4gbW9kKSBpZiAoT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobW9kLCBrKSkgcmVzdWx0W2tdID0gbW9kW2tdO1xyXG4gICAgcmVzdWx0LmRlZmF1bHQgPSBtb2Q7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnREZWZhdWx0KG1vZCkge1xyXG4gICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBkZWZhdWx0OiBtb2QgfTtcclxufVxyXG4iLCJpbXBvcnQgeyBCYXNlTG9naW5Qcm92aWRlciB9IGZyb20gXCIuLi9tb2RlbHMvYmFzZS5sb2dpbi5wcm92aWRlclwiO1xyXG5pbXBvcnQgeyBMb2dpblByb3ZpZGVyQ2xhc3NNb2RlbCB9IGZyb20gXCIuLi9tb2RlbHMvbG9naW4ucHJvdmlkZXIuY2xhc3MubW9kZWxcIjtcclxuaW1wb3J0IHsgU29jaWFsVXNlck1vZGVsIH0gZnJvbSBcIi4uL21vZGVscy9zb2NpYWwudXNlci5tb2RlbFwiO1xyXG5cclxuXHJcbmRlY2xhcmUgbGV0IEZCOiBhbnk7XHJcblxyXG5leHBvcnQgY2xhc3MgRmFjZWJvb2tMb2dpblByb3ZpZGVyIGV4dGVuZHMgQmFzZUxvZ2luUHJvdmlkZXIge1xyXG5cclxuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFBST1ZJREVSX0lEID0gJ2ZhY2Vib29rJztcclxuICBwdWJsaWMgbG9naW5Qcm92aWRlck9iajogTG9naW5Qcm92aWRlckNsYXNzTW9kZWwgPSBuZXcgTG9naW5Qcm92aWRlckNsYXNzTW9kZWwoKTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjbGllbnRJZDogc3RyaW5nKSB7XHJcbiAgICBzdXBlcigpO1xyXG4gICAgdGhpcy5sb2dpblByb3ZpZGVyT2JqLmlkID0gY2xpZW50SWQ7XHJcbiAgICB0aGlzLmxvZ2luUHJvdmlkZXJPYmoubmFtZSA9ICdmYWNlYm9vayc7XHJcbiAgICB0aGlzLmxvZ2luUHJvdmlkZXJPYmoudXJsID0gJ2h0dHBzOi8vY29ubmVjdC5mYWNlYm9vay5uZXQvZW5fVVMvc2RrLmpzJztcclxuICB9XHJcblxyXG4gIGluaXRpYWxpemUoKTogUHJvbWlzZTxTb2NpYWxVc2VyTW9kZWw+IHtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgIHRoaXMubG9hZFNjcmlwdCh0aGlzLmxvZ2luUHJvdmlkZXJPYmosICgpID0+IHtcclxuICAgICAgICAgIEZCLmluaXQoe1xyXG4gICAgICAgICAgICBhcHBJZDogdGhpcy5jbGllbnRJZCxcclxuICAgICAgICAgICAgYXV0b0xvZ0FwcEV2ZW50czogdHJ1ZSxcclxuICAgICAgICAgICAgY29va2llOiB0cnVlLFxyXG4gICAgICAgICAgICB4ZmJtbDogdHJ1ZSxcclxuICAgICAgICAgICAgdmVyc2lvbjogJ3YyLjEwJ1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgICBGQi5BcHBFdmVudHMubG9nUGFnZVZpZXcoKTtcclxuXHJcbiAgICAgICAgICBGQi5nZXRMb2dpblN0YXR1cyhmdW5jdGlvbiAocmVzcG9uc2U6IGFueSkge1xyXG4gICAgICAgICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSAnY29ubmVjdGVkJykge1xyXG4gICAgICAgICAgICAgIGNvbnN0IGFjY2Vzc1Rva2VuID0gRkIuZ2V0QXV0aFJlc3BvbnNlKClbJ2FjY2Vzc1Rva2VuJ107XHJcbiAgICAgICAgICAgICAgRkIuYXBpKCcvbWU/ZmllbGRzPW5hbWUsZW1haWwscGljdHVyZScsIChyZXM6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShGYWNlYm9va0xvZ2luUHJvdmlkZXIuZHJhd1VzZXIoT2JqZWN0LmFzc2lnbih7fSwge3Rva2VuOiBhY2Nlc3NUb2tlbn0sIHJlcykpKTtcclxuICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHN0YXRpYyBkcmF3VXNlcihyZXNwb25zZTogYW55KTogU29jaWFsVXNlck1vZGVsIHtcclxuICAgIGxldCB1c2VyOiBTb2NpYWxVc2VyTW9kZWwgPSBuZXcgU29jaWFsVXNlck1vZGVsKCk7XHJcbiAgICB1c2VyLmlkID0gcmVzcG9uc2UuaWQ7XHJcbiAgICB1c2VyLm5hbWUgPSByZXNwb25zZS5uYW1lO1xyXG4gICAgdXNlci5lbWFpbCA9IHJlc3BvbnNlLmVtYWlsO1xyXG4gICAgdXNlci50b2tlbiA9IHJlc3BvbnNlLnRva2VuO1xyXG4gICAgdXNlci5pbWFnZSA9ICdodHRwczovL2dyYXBoLmZhY2Vib29rLmNvbS8nICsgcmVzcG9uc2UuaWQgKyAnL3BpY3R1cmU/dHlwZT1ub3JtYWwnO1xyXG4gICAgcmV0dXJuIHVzZXI7XHJcbiAgfVxyXG5cclxuICBzaWduSW4oKTogUHJvbWlzZTxTb2NpYWxVc2VyTW9kZWw+IHtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgIEZCLmxvZ2luKChyZXNwb25zZTogYW55KSA9PiB7XHJcbiAgICAgICAgaWYgKHJlc3BvbnNlLmF1dGhSZXNwb25zZSkge1xyXG4gICAgICAgICAgY29uc3QgYWNjZXNzVG9rZW4gPSBGQi5nZXRBdXRoUmVzcG9uc2UoKVsnYWNjZXNzVG9rZW4nXTtcclxuICAgICAgICAgIEZCLmFwaSgnL21lP2ZpZWxkcz1uYW1lLGVtYWlsLHBpY3R1cmUnLCAocmVzOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgcmVzb2x2ZShGYWNlYm9va0xvZ2luUHJvdmlkZXIuZHJhd1VzZXIoT2JqZWN0LmFzc2lnbih7fSwge3Rva2VuOiBhY2Nlc3NUb2tlbn0sIHJlcykpKTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgfSwgeyBzY29wZTogJ2VtYWlsLHB1YmxpY19wcm9maWxlJyB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgc2lnbk91dCgpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgRkIubG9nb3V0KChyZXNwb25zZTogYW55KSA9PiB7XHJcbiAgICAgICAgcmVzb2x2ZSgpO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbn1cclxuIiwiaW1wb3J0IHsgQmFzZUxvZ2luUHJvdmlkZXIgfSBmcm9tIFwiLi4vbW9kZWxzL2Jhc2UubG9naW4ucHJvdmlkZXJcIjtcclxuaW1wb3J0IHsgTG9naW5Qcm92aWRlckNsYXNzTW9kZWwgfSBmcm9tIFwiLi4vbW9kZWxzL2xvZ2luLnByb3ZpZGVyLmNsYXNzLm1vZGVsXCI7XHJcbmltcG9ydCB7IFNvY2lhbFVzZXJNb2RlbCB9IGZyb20gXCIuLi9tb2RlbHMvc29jaWFsLnVzZXIubW9kZWxcIjtcclxuXHJcblxyXG5kZWNsYXJlIGxldCBnYXBpOiBhbnk7XHJcblxyXG5leHBvcnQgY2xhc3MgR29vZ2xlTG9naW5Qcm92aWRlciBleHRlbmRzIEJhc2VMb2dpblByb3ZpZGVyIHtcclxuXHJcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBQUk9WSURFUl9JRCA9ICdnb29nbGUnO1xyXG4gIHB1YmxpYyBsb2dpblByb3ZpZGVyT2JqOiBMb2dpblByb3ZpZGVyQ2xhc3NNb2RlbCA9IG5ldyBMb2dpblByb3ZpZGVyQ2xhc3NNb2RlbCgpO1xyXG4gIHByaXZhdGUgYXV0aDI6IGFueTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjbGllbnRJZDogc3RyaW5nKSB7XHJcbiAgICBzdXBlcigpO1xyXG4gICAgdGhpcy5sb2dpblByb3ZpZGVyT2JqLmlkID0gY2xpZW50SWQ7XHJcbiAgICB0aGlzLmxvZ2luUHJvdmlkZXJPYmoubmFtZSA9ICdnb29nbGUnO1xyXG4gICAgdGhpcy5sb2dpblByb3ZpZGVyT2JqLnVybCA9ICdodHRwczovL2FwaXMuZ29vZ2xlLmNvbS9qcy9wbGF0Zm9ybS5qcyc7XHJcbiAgfVxyXG5cclxuICBpbml0aWFsaXplKCk6IFByb21pc2U8U29jaWFsVXNlck1vZGVsPiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICB0aGlzLmxvYWRTY3JpcHQodGhpcy5sb2dpblByb3ZpZGVyT2JqLCAoKSA9PiB7XHJcbiAgICAgICAgICBnYXBpLmxvYWQoJ2F1dGgyJywgKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmF1dGgyID0gZ2FwaS5hdXRoMi5pbml0KHtcclxuICAgICAgICAgICAgICBjbGllbnRfaWQ6IHRoaXMuY2xpZW50SWQsXHJcbiAgICAgICAgICAgICAgc2NvcGU6ICdlbWFpbCdcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmF1dGgyLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgIGlmICh0aGlzLmF1dGgyLmlzU2lnbmVkSW4uZ2V0KCkpIHtcclxuICAgICAgICAgICAgICAgIHJlc29sdmUodGhpcy5kcmF3VXNlcigpKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBkcmF3VXNlcigpOiBTb2NpYWxVc2VyTW9kZWwge1xyXG4gICAgbGV0IHVzZXI6IFNvY2lhbFVzZXJNb2RlbCA9IG5ldyBTb2NpYWxVc2VyTW9kZWwoKTtcclxuICAgIGxldCBwcm9maWxlID0gdGhpcy5hdXRoMi5jdXJyZW50VXNlci5nZXQoKS5nZXRCYXNpY1Byb2ZpbGUoKTtcclxuICAgIGxldCBhdXRoUmVzcG9uc2VPYmogPSB0aGlzLmF1dGgyLmN1cnJlbnRVc2VyLmdldCgpLmdldEF1dGhSZXNwb25zZSh0cnVlKTtcclxuICAgIHVzZXIuaWQgPSBwcm9maWxlLmdldElkKCk7XHJcbiAgICB1c2VyLm5hbWUgPSBwcm9maWxlLmdldE5hbWUoKTtcclxuICAgIHVzZXIuZW1haWwgPSBwcm9maWxlLmdldEVtYWlsKCk7XHJcbiAgICB1c2VyLmltYWdlID0gcHJvZmlsZS5nZXRJbWFnZVVybCgpO1xyXG4gICAgdXNlci50b2tlbiA9IGF1dGhSZXNwb25zZU9iai5hY2Nlc3NfdG9rZW47XHJcbiAgICB1c2VyLmlkVG9rZW4gPSBhdXRoUmVzcG9uc2VPYmouaWRfdG9rZW47XHJcbiAgICByZXR1cm4gdXNlcjtcclxuICB9XHJcblxyXG4gIHNpZ25JbigpOiBQcm9taXNlPFNvY2lhbFVzZXJNb2RlbD4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgbGV0IHByb21pc2UgPSB0aGlzLmF1dGgyLnNpZ25JbigpO1xyXG4gICAgICBwcm9taXNlLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgIHJlc29sdmUodGhpcy5kcmF3VXNlcigpKTtcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHNpZ25PdXQoKTogUHJvbWlzZTxhbnk+IHtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgIHRoaXMuYXV0aDIuc2lnbk91dCgpLnRoZW4oKGVycjogYW55KSA9PiB7XHJcbiAgICAgICAgaWYgKGVycikge1xyXG4gICAgICAgICAgcmVqZWN0KGVycik7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxufVxyXG4iLCJpbXBvcnQgeyBCYXNlTG9naW5Qcm92aWRlciB9IGZyb20gXCIuLi9tb2RlbHMvYmFzZS5sb2dpbi5wcm92aWRlclwiO1xyXG5pbXBvcnQgeyBMb2dpblByb3ZpZGVyQ2xhc3NNb2RlbCB9IGZyb20gXCIuLi9tb2RlbHMvbG9naW4ucHJvdmlkZXIuY2xhc3MubW9kZWxcIjtcclxuaW1wb3J0IHsgU29jaWFsVXNlck1vZGVsIH0gZnJvbSBcIi4uL21vZGVscy9zb2NpYWwudXNlci5tb2RlbFwiO1xyXG5pbXBvcnQgeyBMaW5rZWRJblJlc3BvbnNlTW9kZWwgfSBmcm9tIFwiLi4vbW9kZWxzL2xpbmtlZGluLnJlc3BvbnNlLm1vZGVsXCI7XHJcblxyXG5cclxuZGVjbGFyZSBsZXQgSU46IGFueTtcclxuXHJcbmV4cG9ydCBjbGFzcyBMaW5rZWRpbkxvZ2luUHJvdmlkZXIgZXh0ZW5kcyBCYXNlTG9naW5Qcm92aWRlciB7XHJcblxyXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgUFJPVklERVJfSUQgPSAnbGlua2VkaW4nO1xyXG4gIHB1YmxpYyBsb2dpblByb3ZpZGVyT2JqOiBMb2dpblByb3ZpZGVyQ2xhc3NNb2RlbCA9IG5ldyBMb2dpblByb3ZpZGVyQ2xhc3NNb2RlbCgpO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNsaWVudElkOiBzdHJpbmcpIHtcclxuICAgIHN1cGVyKCk7XHJcbiAgICB0aGlzLmxvZ2luUHJvdmlkZXJPYmouaWQgPSBjbGllbnRJZDtcclxuICAgIHRoaXMubG9naW5Qcm92aWRlck9iai5uYW1lID0gJ2xpbmtlZGluJztcclxuICAgIHRoaXMubG9naW5Qcm92aWRlck9iai51cmwgPSAnaHR0cHM6Ly9wbGF0Zm9ybS5saW5rZWRpbi5jb20vaW4uanMnO1xyXG4gIH1cclxuXHJcbiAgaW5pdGlhbGl6ZSgpOiBQcm9taXNlPFNvY2lhbFVzZXJNb2RlbD4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgdGhpcy5sb2FkU2NyaXB0KHRoaXMubG9naW5Qcm92aWRlck9iaiwgKCkgPT4ge1xyXG4gICAgICAgICAgSU4uaW5pdCh7XHJcbiAgICAgICAgICAgIGFwaV9rZXk6IHRoaXMuY2xpZW50SWQsXHJcbiAgICAgICAgICAgIGF1dGhvcml6ZTogdHJ1ZSxcclxuICAgICAgICAgICAgb25Mb2FkOiB0aGlzLm9uTGlua2VkSW5Mb2FkKClcclxuICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgIElOLkV2ZW50Lm9uKElOLCAnYXV0aCcsICgpID0+IHtcclxuICAgICAgICAgICAgaWYgKElOLlVzZXIuaXNBdXRob3JpemVkKCkpIHtcclxuICAgICAgICAgICAgICBJTi5BUEkuUmF3KFxyXG4gICAgICAgICAgICAgICAgJy9wZW9wbGUvfjooaWQsZmlyc3QtbmFtZSxsYXN0LW5hbWUsZW1haWwtYWRkcmVzcyxwaWN0dXJlLXVybCknXHJcbiAgICAgICAgICAgICAgKS5yZXN1bHQoIChyZXM6IExpbmtlZEluUmVzcG9uc2VNb2RlbCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh0aGlzLmRyYXdVc2VyKHJlcykpO1xyXG4gICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIG9uTGlua2VkSW5Mb2FkKCkge1xyXG4gICAgSU4uRXZlbnQub24oSU4sICdzeXN0ZW1SZWFkeScsICgpID0+IHtcclxuICAgICAgSU4uVXNlci5yZWZyZXNoKCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGRyYXdVc2VyKHJlc3BvbnNlOiBMaW5rZWRJblJlc3BvbnNlTW9kZWwpOiBTb2NpYWxVc2VyTW9kZWwge1xyXG4gICAgbGV0IHVzZXI6IFNvY2lhbFVzZXJNb2RlbCA9IG5ldyBTb2NpYWxVc2VyTW9kZWwoKTtcclxuICAgIHVzZXIuaWQgPSByZXNwb25zZS5lbWFpbEFkZHJlc3M7XHJcbiAgICB1c2VyLm5hbWUgPSByZXNwb25zZS5maXJzdE5hbWUgKyAnICcgKyByZXNwb25zZS5sYXN0TmFtZTtcclxuICAgIHVzZXIuZW1haWwgPSByZXNwb25zZS5lbWFpbEFkZHJlc3M7XHJcbiAgICB1c2VyLmltYWdlID0gcmVzcG9uc2UucGljdHVyZVVybDtcclxuICAgIHVzZXIudG9rZW4gPSBJTi5FTlYuYXV0aC5vYXV0aF90b2tlbjtcclxuICAgIHJldHVybiB1c2VyO1xyXG4gIH1cclxuXHJcbiAgc2lnbkluKCk6IFByb21pc2U8U29jaWFsVXNlck1vZGVsPiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICBJTi5Vc2VyLmF1dGhvcml6ZSggKCkgPT4ge1xyXG4gICAgICAgIElOLkFQSS5SYXcoJy9wZW9wbGUvfjooaWQsZmlyc3QtbmFtZSxsYXN0LW5hbWUsZW1haWwtYWRkcmVzcyxwaWN0dXJlLXVybCknKS5yZXN1bHQoIChyZXM6IExpbmtlZEluUmVzcG9uc2VNb2RlbCkgPT4ge1xyXG4gICAgICAgICAgcmVzb2x2ZSh0aGlzLmRyYXdVc2VyKHJlcykpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgc2lnbk91dCgpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgSU4uVXNlci5sb2dvdXQoKHJlc3BvbnNlOiBhbnkpID0+IHtcclxuICAgICAgICByZXNvbHZlKCk7XHJcbiAgICAgIH0sIChlcnI6IGFueSkgPT4ge1xyXG4gICAgICAgIHJlamVjdChlcnIpO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbn1cclxuIiwiaW1wb3J0IHsgTG9naW5Qcm92aWRlciB9IGZyb20gXCIuLi9tb2RlbHMvbG9naW4ucHJvdmlkZXJcIjtcclxuaW1wb3J0IHsgQXV0aFNlcnZpY2VDb25maWdJdGVtIH0gZnJvbSBcIi4vYXV0aC5zZXJ2aWNlLmNvbmZpZy5pdGVtXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgQXV0aFNlcnZpY2VDb25maWcge1xyXG4gICAgcHJvdmlkZXJzOiBNYXA8c3RyaW5nLCBMb2dpblByb3ZpZGVyPiA9IG5ldyBNYXA8c3RyaW5nLCBMb2dpblByb3ZpZGVyPigpO1xyXG4gIFxyXG4gICAgY29uc3RydWN0b3IocHJvdmlkZXJzOiBBdXRoU2VydmljZUNvbmZpZ0l0ZW1bXSkge1xyXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByb3ZpZGVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGxldCBlbGVtZW50ID0gcHJvdmlkZXJzW2ldO1xyXG4gICAgICAgIHRoaXMucHJvdmlkZXJzLnNldChlbGVtZW50LmlkLCBlbGVtZW50LnByb3ZpZGVyKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0iLCJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlIH0gZnJvbSBcInJ4anNcIjtcclxuaW1wb3J0IHsgTG9naW5Qcm92aWRlciB9IGZyb20gXCIuLi9tb2RlbHMvbG9naW4ucHJvdmlkZXJcIjtcclxuaW1wb3J0IHsgU29jaWFsVXNlck1vZGVsIH0gZnJvbSBcIi4uL21vZGVscy9zb2NpYWwudXNlci5tb2RlbFwiO1xyXG5pbXBvcnQgeyBBdXRoU2VydmljZUNvbmZpZyB9IGZyb20gXCIuL2F1dGguc2VydmljZS5jb25maWdcIjtcclxuXHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBBdXRoU2VydmljZSB7XHJcblxyXG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IExPR0lOX1BST1ZJREVSX05PVF9GT1VORCA9ICdMb2dpbiBwcm92aWRlciBub3QgZm91bmQnO1xyXG5cclxuICBwcml2YXRlIHByb3ZpZGVyczogTWFwPHN0cmluZywgTG9naW5Qcm92aWRlcj47XHJcblxyXG4gIHByaXZhdGUgX3VzZXI6IFNvY2lhbFVzZXJNb2RlbCA9IG51bGw7XHJcbiAgcHJpdmF0ZSBfYXV0aFN0YXRlOiBCZWhhdmlvclN1YmplY3Q8U29jaWFsVXNlck1vZGVsPiA9IG5ldyBCZWhhdmlvclN1YmplY3QobnVsbCk7XHJcblxyXG4gIGdldCBhdXRoU3RhdGUoKTogT2JzZXJ2YWJsZTxTb2NpYWxVc2VyTW9kZWw+IHtcclxuICAgIHJldHVybiB0aGlzLl9hdXRoU3RhdGUuYXNPYnNlcnZhYmxlKCk7XHJcbiAgfVxyXG5cclxuICBjb25zdHJ1Y3Rvcihjb25maWc6IEF1dGhTZXJ2aWNlQ29uZmlnKSB7XHJcbiAgICB0aGlzLnByb3ZpZGVycyA9IGNvbmZpZy5wcm92aWRlcnM7XHJcbiAgICB0aGlzLnByb3ZpZGVycy5mb3JFYWNoKChwcm92aWRlcjogTG9naW5Qcm92aWRlciwga2V5OiBzdHJpbmcpID0+IHtcclxuICAgICAgcHJvdmlkZXIuaW5pdGlhbGl6ZSgpLnRoZW4oKHVzZXI6IFNvY2lhbFVzZXJNb2RlbCkgPT4ge1xyXG4gICAgICAgIHVzZXIucHJvdmlkZXIgPSBrZXk7XHJcbiAgICAgICAgdGhpcy5fdXNlciA9IHVzZXI7XHJcbiAgICAgICAgdGhpcy5fYXV0aFN0YXRlLm5leHQodXNlcik7XHJcbiAgICAgIH0pLmNhdGNoKChlcnIpID0+IHtcclxuICAgICAgICAvLyB0aGlzLl9hdXRoU3RhdGUubmV4dChudWxsKTtcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHNpZ25Jbihwcm92aWRlcklkOiBzdHJpbmcpOiBQcm9taXNlPFNvY2lhbFVzZXJNb2RlbD4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgbGV0IHByb3ZpZGVyT2JqZWN0ID0gdGhpcy5wcm92aWRlcnMuZ2V0KHByb3ZpZGVySWQpO1xyXG4gICAgICBpZiAocHJvdmlkZXJPYmplY3QpIHtcclxuICAgICAgICBwcm92aWRlck9iamVjdC5zaWduSW4oKS50aGVuKCh1c2VyOiBTb2NpYWxVc2VyTW9kZWwpID0+IHtcclxuICAgICAgICAgIHVzZXIucHJvdmlkZXIgPSBwcm92aWRlcklkO1xyXG4gICAgICAgICAgcmVzb2x2ZSh1c2VyKTtcclxuICAgICAgICAgIHRoaXMuX3VzZXIgPSB1c2VyO1xyXG4gICAgICAgICAgdGhpcy5fYXV0aFN0YXRlLm5leHQodXNlcik7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmVqZWN0KEF1dGhTZXJ2aWNlLkxPR0lOX1BST1ZJREVSX05PVF9GT1VORCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgc2lnbk91dCgpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgaWYgKHRoaXMuX3VzZXIgJiYgdGhpcy5fdXNlci5wcm92aWRlcikge1xyXG4gICAgICAgIGxldCBwcm92aWRlcklkID0gdGhpcy5fdXNlci5wcm92aWRlcjtcclxuICAgICAgICBsZXQgcHJvdmlkZXJPYmplY3QgPSB0aGlzLnByb3ZpZGVycy5nZXQocHJvdmlkZXJJZCk7XHJcbiAgICAgICAgcHJvdmlkZXJPYmplY3Quc2lnbk91dCgpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgdGhpcy5fdXNlciA9IG51bGw7XHJcbiAgICAgICAgICB0aGlzLl9hdXRoU3RhdGUubmV4dChudWxsKTtcclxuICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICB9KS5jYXRjaCgoZXJyKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLl9hdXRoU3RhdGUubmV4dChudWxsKTtcclxuICAgICAgICB9KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICByZWplY3QoQXV0aFNlcnZpY2UuTE9HSU5fUFJPVklERVJfTk9UX0ZPVU5EKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxufSIsImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQXV0aFNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL2F1dGguc2VydmljZSc7XG5cbkBOZ01vZHVsZSh7XG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGVcbiAgXSxcbiAgZGVjbGFyYXRpb25zOiBbXSxcbiAgcHJvdmlkZXJzOiBbQXV0aFNlcnZpY2VdLFxufSlcbmV4cG9ydCBjbGFzcyBEeW5hbWlTb2NpYWxMb2dpbk1vZHVsZSB7IH1cbiJdLCJuYW1lcyI6WyJ0c2xpYl8xLl9fZXh0ZW5kcyIsIkJlaGF2aW9yU3ViamVjdCIsIkluamVjdGFibGUiLCJOZ01vZHVsZSIsIkNvbW1vbk1vZHVsZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQUtBOzs7UUFDRTtTQUFnQjs7Ozs7O1FBTWhCLHNDQUFVOzs7OztZQUFWLFVBQVcsR0FBNEIsRUFBRSxNQUFXO2dCQUNsRCxJQUFJLFFBQVEsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFO29CQUFFLE9BQU87aUJBQUU7O29CQUM5QyxRQUFRLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUM7Z0JBQy9DLFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO2dCQUN0QixRQUFRLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUM7Z0JBQ3ZCLFFBQVEsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO2dCQUN6QixJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFO29CQUMzQixRQUFRLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztvQkFDdkIsUUFBUSxDQUFDLElBQUksR0FBRyxDQUFDLFdBQVcsR0FBRyxHQUFHLENBQUMsRUFBRSxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7aUJBQzFEO2dCQUNELFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQ3JDO1FBQ0gsd0JBQUM7SUFBRCxDQUFDOzs7Ozs7QUN4QkQ7UUFBQTtTQU1HO1FBQUQsNEJBQUM7SUFBRCxDQUFDOzs7Ozs7QUNOSDtRQUFBO1NBSUc7UUFBRCw4QkFBQztJQUFELENBQUM7Ozs7OztBQ0pIO1FBQUE7U0FRRztRQUFELHNCQUFDO0lBQUQsQ0FBQzs7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