@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
232 lines • 31.4 kB
JavaScript
import { Injectable } from '@angular/core';
import { ApplicationService, FetchClient, InventoryService } from '@c8y/client';
import { AppStateService, OptionsService, gettext } from '@c8y/ngx-components';
import { TranslateService } from '@ngx-translate/core';
import { some } from 'lodash-es';
import * as i0 from "@angular/core";
import * as i1 from "@c8y/client";
import * as i2 from "@ngx-translate/core";
import * as i3 from "@c8y/ngx-components";
export var ActilityErrorName;
(function (ActilityErrorName) {
ActilityErrorName["NoConnectivityPlansError"] = "NoConnectivityPlansError";
ActilityErrorName["NoFreeSlotsInConnectivityPlansError"] = "NoFreeSlotsInConnectivityPlansError";
ActilityErrorName["NoConnectivitySettingsError"] = "NoConnectivitySettingsError";
ActilityErrorName["ConnectivitySettingsError"] = "ConnectivitySettingsError";
ActilityErrorName["NoDeviceProfilesError"] = "NoDeviceProfilesError";
ActilityErrorName["DeviceProfilesFetchError"] = "DeviceProfilesFetchError";
ActilityErrorName["NoDeviceProtocolsError"] = "NoDeviceProtocolsError";
ActilityErrorName["DeviceProtocolsFetchError"] = "DeviceProtocolsFetchError";
ActilityErrorName["RegistrationError"] = "RegistrationError";
})(ActilityErrorName || (ActilityErrorName = {}));
export class ActilityDeviceRegistrationService {
constructor(inventoryService, client, translateService, applicationService, optionsService, appState) {
this.inventoryService = inventoryService;
this.client = client;
this.translateService = translateService;
this.applicationService = applicationService;
this.optionsService = optionsService;
this.appState = appState;
this.baseUrl = '/service/actility';
this.registrationUrl = `${this.baseUrl}/newDeviceRequest`;
this.connectivityPlansUrl = `${this.baseUrl}/connectivityPlans`;
this.deviceProfilesUrl = `${this.baseUrl}/deviceProfiles`;
this.headers = {
'Content-Type': 'application/json'
};
}
async getConnections() {
const options = {
method: 'GET',
headers: this.headers
};
const res = await this.client.fetch(`${this.baseUrl}/lns-connection`, options);
const data = await res.json();
if (res.status === 200) {
if (data.length === 0) {
await this.throwNoConnectivitySettingsError();
}
}
else {
await this.throwConnectivitySettingsError(data);
}
return { res, data };
}
/**
* Gets connectivity plans from LoRa platform.
* @param connectionName The name of connection for which connectivity plans will be retrieved
* @returns The result list with connectivity plans, or throws an error with exception.
*/
async getConnectivityPlans(connectionName) {
const options = {
method: 'GET',
headers: this.headers,
params: {
actilityConnectionName: connectionName
}
};
const res = await this.client.fetch(this.connectivityPlansUrl, options);
const data = await res.json();
if (res.status === 200) {
if (data.length === 0) {
this.throwNoConnectivityPlansError();
}
else {
if (!this.hasAvailableConnections(data)) {
this.throwNoFreeSlotsInConnectivityPlansError();
}
}
}
else {
await this.throwConnectivitySettingsError(data);
}
return { res, data };
}
/**
* Gets the device profiles from LoRa platform.
* @param connectionName The name of connection for which device profiles will be retrieved
* @returns The result list with device profiles, or throws an error with exception.
*/
async getDeviceProfiles(connectionName) {
const options = {
method: 'GET',
headers: this.headers,
params: {
actilityConnectionName: connectionName
}
};
const res = await this.client.fetch(this.deviceProfilesUrl, options);
const data = await res.json();
if (res.status === 200) {
if (data.length === 0) {
this.throwNoDeviceProfilesError();
}
}
else {
this.throwDeviceProfilesFetchError();
}
return { res, data };
}
/**
* Gets the device protocols
*/
async getDeviceProtocols(filter = { withTotalPages: true }) {
const query = {
__filter: {
__and: [
{ __has: 'c8y_IsDeviceType' },
{
type: { __in: ['c8y_ActilityDeviceType', 'c8y_LoraDeviceType', 'c8y_LpwanDeviceType'] }
}
]
},
__orderby: [{ name: 1 }]
};
const deviceProtocolsList = await this.inventoryService.listQuery(query, filter);
const { res, data } = deviceProtocolsList;
if (res.status === 200) {
if (data.length === 0) {
this.throwNoDeviceProtocolsError();
}
}
else {
this.throwDeviceProtocolsFetchError();
}
return deviceProtocolsList;
}
/**
* Creates device registration
*/
async register(registration) {
const options = {
method: 'POST',
headers: this.headers,
body: JSON.stringify(registration)
};
const res = await this.client.fetch(this.registrationUrl, options);
const data = await res.json();
if (res.status !== 201) {
this.throwRegistrationError(data);
}
return { res, data };
}
/**
* checks if used connections is less then granted connections
*/
hasAvailableConnections(connectivityPlans) {
return some(connectivityPlans, plan => parseInt(plan.grantedConnections, 10) > parseInt(plan.usedConnections, 10));
}
async throwNoConnectivitySettingsError() {
const error = new Error();
error.name = ActilityErrorName.NoConnectivitySettingsError;
if (await this.appState.isApplicationAvailable('administration')) {
error.message = this.translateService.instant(gettext(`Could not get connectivity plans from the LoRa platform. Verify the ThingPark credentials in the Administration application under <a href="{{ link }}">Settings</a>.`), {
link: '/apps/administration/index.html#/connectivitySettings/multiple_lns_connectors_actility'
});
}
else {
error.message = gettext('Could not get connectivity plans from the LoRa platform. Please contact the administrator.');
}
throw error;
}
throwConnectivitySettingsError(data) {
const error = new Error();
error.name = ActilityErrorName.ConnectivitySettingsError;
error.message = data.message;
throw error;
}
throwNoConnectivityPlansError() {
const error = new Error();
error.name = ActilityErrorName.NoConnectivityPlansError;
error.message = gettext('No connectivity plans found. New connectivity plans must be created via the LoRa platform.');
throw error;
}
throwNoFreeSlotsInConnectivityPlansError() {
const companyName = this.optionsService.get('companyName', 'Cumulocity IoT');
const error = new Error();
error.name = ActilityErrorName.NoFreeSlotsInConnectivityPlansError;
error.message = this.translateService.instant(gettext(`No connectivity plans with free slots available. Please contact ThingPark on the device quota limits for your connectivity plans or remove unused devices from ThingPark and retry registering the device in the {{companyName}} platform.`), {
companyName
});
throw error;
}
throwDeviceProfilesFetchError() {
const error = new Error();
error.name = ActilityErrorName.DeviceProfilesFetchError;
error.message = gettext('Could not load device profiles from the LoRa platform.');
throw error;
}
throwNoDeviceProfilesError() {
const error = new Error();
error.name = ActilityErrorName.NoDeviceProfilesError;
error.message = gettext('No device profiles found. Create a new device profile via the LoRa platform.');
throw error;
}
throwDeviceProtocolsFetchError() {
const error = new Error();
error.name = ActilityErrorName.DeviceProtocolsFetchError;
error.message = gettext('Could not load device protocols.');
throw error;
}
throwNoDeviceProtocolsError() {
const error = new Error();
error.name = ActilityErrorName.NoDeviceProtocolsError;
error.message = this.translateService.instant(gettext(`No device protocols configured. Create a LoRa device protocol in <a href="{{ link }}">Device protocols</a>.`), {
link: '/apps/devicemanagement/#/deviceprotocols'
});
throw error;
}
throwRegistrationError(data) {
const error = new Error();
error.name = ActilityErrorName.RegistrationError;
error.message = data.message;
throw error;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ActilityDeviceRegistrationService, deps: [{ token: i1.InventoryService }, { token: i1.FetchClient }, { token: i2.TranslateService }, { token: i1.ApplicationService }, { token: i3.OptionsService }, { token: i3.AppStateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ActilityDeviceRegistrationService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ActilityDeviceRegistrationService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [{ type: i1.InventoryService }, { type: i1.FetchClient }, { type: i2.TranslateService }, { type: i1.ApplicationService }, { type: i3.OptionsService }, { type: i3.AppStateService }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aWxpdHktZGV2aWNlLXJlZ2lzdHJhdGlvbi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vYWN0aWxpdHktZGV2aWNlLXJlZ2lzdHJhdGlvbi9hY3RpbGl0eS1kZXZpY2UtcmVnaXN0cmF0aW9uLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLFdBQVcsRUFJWCxnQkFBZ0IsRUFDakIsTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUFFLGVBQWUsRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDL0UsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQzs7Ozs7QUFPakMsTUFBTSxDQUFOLElBQVksaUJBVVg7QUFWRCxXQUFZLGlCQUFpQjtJQUMzQiwwRUFBcUQsQ0FBQTtJQUNyRCxnR0FBMkUsQ0FBQTtJQUMzRSxnRkFBMkQsQ0FBQTtJQUMzRCw0RUFBdUQsQ0FBQTtJQUN2RCxvRUFBK0MsQ0FBQTtJQUMvQywwRUFBcUQsQ0FBQTtJQUNyRCxzRUFBaUQsQ0FBQTtJQUNqRCw0RUFBdUQsQ0FBQTtJQUN2RCw0REFBdUMsQ0FBQTtBQUN6QyxDQUFDLEVBVlcsaUJBQWlCLEtBQWpCLGlCQUFpQixRQVU1QjtBQUdELE1BQU0sT0FBTyxpQ0FBaUM7SUFTNUMsWUFDVSxnQkFBa0MsRUFDbEMsTUFBbUIsRUFDbkIsZ0JBQWtDLEVBQ2xDLGtCQUFzQyxFQUN0QyxjQUE4QixFQUM5QixRQUF5QjtRQUx6QixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ2xDLFdBQU0sR0FBTixNQUFNLENBQWE7UUFDbkIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNsQyx1QkFBa0IsR0FBbEIsa0JBQWtCLENBQW9CO1FBQ3RDLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUM5QixhQUFRLEdBQVIsUUFBUSxDQUFpQjtRQWQzQixZQUFPLEdBQUcsbUJBQW1CLENBQUM7UUFDOUIsb0JBQWUsR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLG1CQUFtQixDQUFDO1FBQ3JELHlCQUFvQixHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sb0JBQW9CLENBQUM7UUFDM0Qsc0JBQWlCLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxpQkFBaUIsQ0FBQztRQUNyRCxZQUFPLEdBQVc7WUFDeEIsY0FBYyxFQUFFLGtCQUFrQjtTQUNuQyxDQUFDO0lBU0MsQ0FBQztJQUVKLEtBQUssQ0FBQyxjQUFjO1FBQ2xCLE1BQU0sT0FBTyxHQUFrQjtZQUM3QixNQUFNLEVBQUUsS0FBSztZQUNiLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztTQUN0QixDQUFDO1FBQ0YsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLGlCQUFpQixFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQy9FLE1BQU0sSUFBSSxHQUFHLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1FBRTlCLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUN2QixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3RCLE1BQU0sSUFBSSxDQUFDLGdDQUFnQyxFQUFFLENBQUM7WUFDaEQsQ0FBQztRQUNILENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxJQUFJLENBQUMsOEJBQThCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEQsQ0FBQztRQUNELE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUNEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsb0JBQW9CLENBQUMsY0FBc0I7UUFDL0MsTUFBTSxPQUFPLEdBQWtCO1lBQzdCLE1BQU0sRUFBRSxLQUFLO1lBQ2IsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQ3JCLE1BQU0sRUFBRTtnQkFDTixzQkFBc0IsRUFBRSxjQUFjO2FBQ3ZDO1NBQ0YsQ0FBQztRQUVGLE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3hFLE1BQU0sSUFBSSxHQUFHLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1FBRTlCLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUN2QixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3RCLElBQUksQ0FBQyw2QkFBNkIsRUFBRSxDQUFDO1lBQ3ZDLENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7b0JBQ3hDLElBQUksQ0FBQyx3Q0FBd0MsRUFBRSxDQUFDO2dCQUNsRCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxJQUFJLENBQUMsOEJBQThCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEQsQ0FBQztRQUVELE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsaUJBQWlCLENBQUMsY0FBc0I7UUFDNUMsTUFBTSxPQUFPLEdBQWtCO1lBQzdCLE1BQU0sRUFBRSxLQUFLO1lBQ2IsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQ3JCLE1BQU0sRUFBRTtnQkFDTixzQkFBc0IsRUFBRSxjQUFjO2FBQ3ZDO1NBQ0YsQ0FBQztRQUVGLE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3JFLE1BQU0sSUFBSSxHQUFHLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1FBRTlCLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUN2QixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3RCLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1lBQ3BDLENBQUM7UUFDSCxDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyw2QkFBNkIsRUFBRSxDQUFDO1FBQ3ZDLENBQUM7UUFFRCxPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxrQkFBa0IsQ0FDdEIsU0FBaUIsRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFO1FBRXpDLE1BQU0sS0FBSyxHQUFHO1lBQ1osUUFBUSxFQUFFO2dCQUNSLEtBQUssRUFBRTtvQkFDTCxFQUFFLEtBQUssRUFBRSxrQkFBa0IsRUFBRTtvQkFDN0I7d0JBQ0UsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUMsd0JBQXdCLEVBQUUsb0JBQW9CLEVBQUUscUJBQXFCLENBQUMsRUFBRTtxQkFDeEY7aUJBQ0Y7YUFDRjtZQUNELFNBQVMsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO1NBQ3pCLENBQUM7UUFDRixNQUFNLG1CQUFtQixHQUFHLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDakYsTUFBTSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQztRQUUxQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDdkIsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUN0QixJQUFJLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztZQUNyQyxDQUFDO1FBQ0gsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsOEJBQThCLEVBQUUsQ0FBQztRQUN4QyxDQUFDO1FBRUQsT0FBTyxtQkFBbUIsQ0FBQztJQUM3QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsUUFBUSxDQUFDLFlBQXdDO1FBQ3JELE1BQU0sT0FBTyxHQUFrQjtZQUM3QixNQUFNLEVBQUUsTUFBTTtZQUNkLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztZQUNyQixJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUM7U0FDbkMsQ0FBQztRQUVGLE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNuRSxNQUFNLElBQUksR0FBRyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUU5QixJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BDLENBQUM7UUFFRCxPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFRDs7T0FFRztJQUNLLHVCQUF1QixDQUFDLGlCQUFpQjtRQUMvQyxPQUFPLElBQUksQ0FDVCxpQkFBaUIsRUFDakIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLEVBQUUsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUNuRixDQUFDO0lBQ0osQ0FBQztJQUVPLEtBQUssQ0FBQyxnQ0FBZ0M7UUFDNUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUMxQixLQUFLLENBQUMsSUFBSSxHQUFHLGlCQUFpQixDQUFDLDJCQUEyQixDQUFDO1FBRTNELElBQUksTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLHNCQUFzQixDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztZQUNqRSxLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQzNDLE9BQU8sQ0FDTCxzS0FBc0ssQ0FDdkssRUFDRDtnQkFDRSxJQUFJLEVBQUUsd0ZBQXdGO2FBQy9GLENBQ0YsQ0FBQztRQUNKLENBQUM7YUFBTSxDQUFDO1lBQ04sS0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQ3JCLDRGQUE0RixDQUM3RixDQUFDO1FBQ0osQ0FBQztRQUVELE1BQU0sS0FBSyxDQUFDO0lBQ2QsQ0FBQztJQUVPLDhCQUE4QixDQUFDLElBQXlCO1FBQzlELE1BQU0sS0FBSyxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7UUFDMUIsS0FBSyxDQUFDLElBQUksR0FBRyxpQkFBaUIsQ0FBQyx5QkFBeUIsQ0FBQztRQUN6RCxLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDN0IsTUFBTSxLQUFLLENBQUM7SUFDZCxDQUFDO0lBRU8sNkJBQTZCO1FBQ25DLE1BQU0sS0FBSyxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7UUFDMUIsS0FBSyxDQUFDLElBQUksR0FBRyxpQkFBaUIsQ0FBQyx3QkFBd0IsQ0FBQztRQUN4RCxLQUFLLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FDckIsNEZBQTRGLENBQzdGLENBQUM7UUFDRixNQUFNLEtBQUssQ0FBQztJQUNkLENBQUM7SUFFTyx3Q0FBd0M7UUFDOUMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFDN0UsTUFBTSxLQUFLLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUMxQixLQUFLLENBQUMsSUFBSSxHQUFHLGlCQUFpQixDQUFDLG1DQUFtQyxDQUFDO1FBQ25FLEtBQUssQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FDM0MsT0FBTyxDQUNMLDRPQUE0TyxDQUM3TyxFQUNEO1lBQ0UsV0FBVztTQUNaLENBQ0YsQ0FBQztRQUNGLE1BQU0sS0FBSyxDQUFDO0lBQ2QsQ0FBQztJQUVPLDZCQUE2QjtRQUNuQyxNQUFNLEtBQUssR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQzFCLEtBQUssQ0FBQyxJQUFJLEdBQUcsaUJBQWlCLENBQUMsd0JBQXdCLENBQUM7UUFDeEQsS0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsd0RBQXdELENBQUMsQ0FBQztRQUNsRixNQUFNLEtBQUssQ0FBQztJQUNkLENBQUM7SUFFTywwQkFBMEI7UUFDaEMsTUFBTSxLQUFLLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUMxQixLQUFLLENBQUMsSUFBSSxHQUFHLGlCQUFpQixDQUFDLHFCQUFxQixDQUFDO1FBQ3JELEtBQUssQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUNyQiw4RUFBOEUsQ0FDL0UsQ0FBQztRQUNGLE1BQU0sS0FBSyxDQUFDO0lBQ2QsQ0FBQztJQUVPLDhCQUE4QjtRQUNwQyxNQUFNLEtBQUssR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQzFCLEtBQUssQ0FBQyxJQUFJLEdBQUcsaUJBQWlCLENBQUMseUJBQXlCLENBQUM7UUFDekQsS0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUM1RCxNQUFNLEtBQUssQ0FBQztJQUNkLENBQUM7SUFFTywyQkFBMkI7UUFDakMsTUFBTSxLQUFLLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUMxQixLQUFLLENBQUMsSUFBSSxHQUFHLGlCQUFpQixDQUFDLHNCQUFzQixDQUFDO1FBQ3RELEtBQUssQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FDM0MsT0FBTyxDQUNMLDZHQUE2RyxDQUM5RyxFQUNEO1lBQ0UsSUFBSSxFQUFFLDBDQUEwQztTQUNqRCxDQUNGLENBQUM7UUFDRixNQUFNLEtBQUssQ0FBQztJQUNkLENBQUM7SUFFTyxzQkFBc0IsQ0FBQyxJQUF5QjtRQUN0RCxNQUFNLEtBQUssR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQzFCLEtBQUssQ0FBQyxJQUFJLEdBQUcsaUJBQWlCLENBQUMsaUJBQWlCLENBQUM7UUFDakQsS0FBSyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1FBQzdCLE1BQU0sS0FBSyxDQUFDO0lBQ2QsQ0FBQzsrR0EzUFUsaUNBQWlDO21IQUFqQyxpQ0FBaUMsY0FEcEIsTUFBTTs7NEZBQ25CLGlDQUFpQztrQkFEN0MsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBBcHBsaWNhdGlvblNlcnZpY2UsXG4gIEZldGNoQ2xpZW50LFxuICBJRmV0Y2hPcHRpb25zLFxuICBJTWFuYWdlZE9iamVjdCxcbiAgSVJlc3VsdExpc3QsXG4gIEludmVudG9yeVNlcnZpY2Vcbn0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgQXBwU3RhdGVTZXJ2aWNlLCBPcHRpb25zU2VydmljZSwgZ2V0dGV4dCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgc29tZSB9IGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQge1xuICBBY3RpbGl0eURldmljZVByb2ZpbGUsXG4gIEFjdGlsaXR5RGV2aWNlUmVnaXN0cmF0aW9uLFxuICBDb25uZWN0aXZpdHlQbGFuXG59IGZyb20gJy4vYWN0aWxpdHktZGV2aWNlLXJlZ2lzdHJhdGlvbi5tb2RlbCc7XG5cbmV4cG9ydCBlbnVtIEFjdGlsaXR5RXJyb3JOYW1lIHtcbiAgTm9Db25uZWN0aXZpdHlQbGFuc0Vycm9yID0gJ05vQ29ubmVjdGl2aXR5UGxhbnNFcnJvcicsXG4gIE5vRnJlZVNsb3RzSW5Db25uZWN0aXZpdHlQbGFuc0Vycm9yID0gJ05vRnJlZVNsb3RzSW5Db25uZWN0aXZpdHlQbGFuc0Vycm9yJyxcbiAgTm9Db25uZWN0aXZpdHlTZXR0aW5nc0Vycm9yID0gJ05vQ29ubmVjdGl2aXR5U2V0dGluZ3NFcnJvcicsXG4gIENvbm5lY3Rpdml0eVNldHRpbmdzRXJyb3IgPSAnQ29ubmVjdGl2aXR5U2V0dGluZ3NFcnJvcicsXG4gIE5vRGV2aWNlUHJvZmlsZXNFcnJvciA9ICdOb0RldmljZVByb2ZpbGVzRXJyb3InLFxuICBEZXZpY2VQcm9maWxlc0ZldGNoRXJyb3IgPSAnRGV2aWNlUHJvZmlsZXNGZXRjaEVycm9yJyxcbiAgTm9EZXZpY2VQcm90b2NvbHNFcnJvciA9ICdOb0RldmljZVByb3RvY29sc0Vycm9yJyxcbiAgRGV2aWNlUHJvdG9jb2xzRmV0Y2hFcnJvciA9ICdEZXZpY2VQcm90b2NvbHNGZXRjaEVycm9yJyxcbiAgUmVnaXN0cmF0aW9uRXJyb3IgPSAnUmVnaXN0cmF0aW9uRXJyb3InXG59XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgQWN0aWxpdHlEZXZpY2VSZWdpc3RyYXRpb25TZXJ2aWNlIHtcbiAgcHJpdmF0ZSBiYXNlVXJsID0gJy9zZXJ2aWNlL2FjdGlsaXR5JztcbiAgcHJpdmF0ZSByZWdpc3RyYXRpb25VcmwgPSBgJHt0aGlzLmJhc2VVcmx9L25ld0RldmljZVJlcXVlc3RgO1xuICBwcml2YXRlIGNvbm5lY3Rpdml0eVBsYW5zVXJsID0gYCR7dGhpcy5iYXNlVXJsfS9jb25uZWN0aXZpdHlQbGFuc2A7XG4gIHByaXZhdGUgZGV2aWNlUHJvZmlsZXNVcmwgPSBgJHt0aGlzLmJhc2VVcmx9L2RldmljZVByb2ZpbGVzYDtcbiAgcHJpdmF0ZSBoZWFkZXJzOiBvYmplY3QgPSB7XG4gICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJ1xuICB9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgaW52ZW50b3J5U2VydmljZTogSW52ZW50b3J5U2VydmljZSxcbiAgICBwcml2YXRlIGNsaWVudDogRmV0Y2hDbGllbnQsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGVTZXJ2aWNlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgYXBwbGljYXRpb25TZXJ2aWNlOiBBcHBsaWNhdGlvblNlcnZpY2UsXG4gICAgcHJpdmF0ZSBvcHRpb25zU2VydmljZTogT3B0aW9uc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBhcHBTdGF0ZTogQXBwU3RhdGVTZXJ2aWNlXG4gICkge31cblxuICBhc3luYyBnZXRDb25uZWN0aW9ucygpIHtcbiAgICBjb25zdCBvcHRpb25zOiBJRmV0Y2hPcHRpb25zID0ge1xuICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgIGhlYWRlcnM6IHRoaXMuaGVhZGVyc1xuICAgIH07XG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5jbGllbnQuZmV0Y2goYCR7dGhpcy5iYXNlVXJsfS9sbnMtY29ubmVjdGlvbmAsIG9wdGlvbnMpO1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuXG4gICAgaWYgKHJlcy5zdGF0dXMgPT09IDIwMCkge1xuICAgICAgaWYgKGRhdGEubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGF3YWl0IHRoaXMudGhyb3dOb0Nvbm5lY3Rpdml0eVNldHRpbmdzRXJyb3IoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgdGhpcy50aHJvd0Nvbm5lY3Rpdml0eVNldHRpbmdzRXJyb3IoZGF0YSk7XG4gICAgfVxuICAgIHJldHVybiB7IHJlcywgZGF0YSB9O1xuICB9XG4gIC8qKlxuICAgKiBHZXRzIGNvbm5lY3Rpdml0eSBwbGFucyBmcm9tIExvUmEgcGxhdGZvcm0uXG4gICAqIEBwYXJhbSBjb25uZWN0aW9uTmFtZSBUaGUgbmFtZSBvZiBjb25uZWN0aW9uIGZvciB3aGljaCBjb25uZWN0aXZpdHkgcGxhbnMgd2lsbCBiZSByZXRyaWV2ZWRcbiAgICogQHJldHVybnMgVGhlIHJlc3VsdCBsaXN0IHdpdGggY29ubmVjdGl2aXR5IHBsYW5zLCBvciB0aHJvd3MgYW4gZXJyb3Igd2l0aCBleGNlcHRpb24uXG4gICAqL1xuICBhc3luYyBnZXRDb25uZWN0aXZpdHlQbGFucyhjb25uZWN0aW9uTmFtZTogc3RyaW5nKTogUHJvbWlzZTxJUmVzdWx0TGlzdDxDb25uZWN0aXZpdHlQbGFuPj4ge1xuICAgIGNvbnN0IG9wdGlvbnM6IElGZXRjaE9wdGlvbnMgPSB7XG4gICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgaGVhZGVyczogdGhpcy5oZWFkZXJzLFxuICAgICAgcGFyYW1zOiB7XG4gICAgICAgIGFjdGlsaXR5Q29ubmVjdGlvbk5hbWU6IGNvbm5lY3Rpb25OYW1lXG4gICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMuY2xpZW50LmZldGNoKHRoaXMuY29ubmVjdGl2aXR5UGxhbnNVcmwsIG9wdGlvbnMpO1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXMuanNvbigpO1xuXG4gICAgaWYgKHJlcy5zdGF0dXMgPT09IDIwMCkge1xuICAgICAgaWYgKGRhdGEubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMudGhyb3dOb0Nvbm5lY3Rpdml0eVBsYW5zRXJyb3IoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghdGhpcy5oYXNBdmFpbGFibGVDb25uZWN0aW9ucyhkYXRhKSkge1xuICAgICAgICAgIHRoaXMudGhyb3dOb0ZyZWVTbG90c0luQ29ubmVjdGl2aXR5UGxhbnNFcnJvcigpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHRoaXMudGhyb3dDb25uZWN0aXZpdHlTZXR0aW5nc0Vycm9yKGRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiB7IHJlcywgZGF0YSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGRldmljZSBwcm9maWxlcyBmcm9tIExvUmEgcGxhdGZvcm0uXG4gICAqIEBwYXJhbSBjb25uZWN0aW9uTmFtZSBUaGUgbmFtZSBvZiBjb25uZWN0aW9uIGZvciB3aGljaCBkZXZpY2UgcHJvZmlsZXMgd2lsbCBiZSByZXRyaWV2ZWRcbiAgICogQHJldHVybnMgVGhlIHJlc3VsdCBsaXN0IHdpdGggZGV2aWNlIHByb2ZpbGVzLCBvciB0aHJvd3MgYW4gZXJyb3Igd2l0aCBleGNlcHRpb24uXG4gICAqL1xuICBhc3luYyBnZXREZXZpY2VQcm9maWxlcyhjb25uZWN0aW9uTmFtZTogc3RyaW5nKTogUHJvbWlzZTxJUmVzdWx0TGlzdDxBY3RpbGl0eURldmljZVByb2ZpbGU+PiB7XG4gICAgY29uc3Qgb3B0aW9uczogSUZldGNoT3B0aW9ucyA9IHtcbiAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICBoZWFkZXJzOiB0aGlzLmhlYWRlcnMsXG4gICAgICBwYXJhbXM6IHtcbiAgICAgICAgYWN0aWxpdHlDb25uZWN0aW9uTmFtZTogY29ubmVjdGlvbk5hbWVcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5jbGllbnQuZmV0Y2godGhpcy5kZXZpY2VQcm9maWxlc1VybCwgb3B0aW9ucyk7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcy5qc29uKCk7XG5cbiAgICBpZiAocmVzLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy50aHJvd05vRGV2aWNlUHJvZmlsZXNFcnJvcigpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRocm93RGV2aWNlUHJvZmlsZXNGZXRjaEVycm9yKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgcmVzLCBkYXRhIH07XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgZGV2aWNlIHByb3RvY29sc1xuICAgKi9cbiAgYXN5bmMgZ2V0RGV2aWNlUHJvdG9jb2xzKFxuICAgIGZpbHRlcjogb2JqZWN0ID0geyB3aXRoVG90YWxQYWdlczogdHJ1ZSB9XG4gICk6IFByb21pc2U8SVJlc3VsdExpc3Q8SU1hbmFnZWRPYmplY3Q+PiB7XG4gICAgY29uc3QgcXVlcnkgPSB7XG4gICAgICBfX2ZpbHRlcjoge1xuICAgICAgICBfX2FuZDogW1xuICAgICAgICAgIHsgX19oYXM6ICdjOHlfSXNEZXZpY2VUeXBlJyB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IHsgX19pbjogWydjOHlfQWN0aWxpdHlEZXZpY2VUeXBlJywgJ2M4eV9Mb3JhRGV2aWNlVHlwZScsICdjOHlfTHB3YW5EZXZpY2VUeXBlJ10gfVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfSxcbiAgICAgIF9fb3JkZXJieTogW3sgbmFtZTogMSB9XVxuICAgIH07XG4gICAgY29uc3QgZGV2aWNlUHJvdG9jb2xzTGlzdCA9IGF3YWl0IHRoaXMuaW52ZW50b3J5U2VydmljZS5saXN0UXVlcnkocXVlcnksIGZpbHRlcik7XG4gICAgY29uc3QgeyByZXMsIGRhdGEgfSA9IGRldmljZVByb3RvY29sc0xpc3Q7XG5cbiAgICBpZiAocmVzLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy50aHJvd05vRGV2aWNlUHJvdG9jb2xzRXJyb3IoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50aHJvd0RldmljZVByb3RvY29sc0ZldGNoRXJyb3IoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGV2aWNlUHJvdG9jb2xzTGlzdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGRldmljZSByZWdpc3RyYXRpb25cbiAgICovXG4gIGFzeW5jIHJlZ2lzdGVyKHJlZ2lzdHJhdGlvbjogQWN0aWxpdHlEZXZpY2VSZWdpc3RyYXRpb24pIHtcbiAgICBjb25zdCBvcHRpb25zOiBJRmV0Y2hPcHRpb25zID0ge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBoZWFkZXJzOiB0aGlzLmhlYWRlcnMsXG4gICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShyZWdpc3RyYXRpb24pXG4gICAgfTtcblxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMuY2xpZW50LmZldGNoKHRoaXMucmVnaXN0cmF0aW9uVXJsLCBvcHRpb25zKTtcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcblxuICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDEpIHtcbiAgICAgIHRoaXMudGhyb3dSZWdpc3RyYXRpb25FcnJvcihkYXRhKTtcbiAgICB9XG5cbiAgICByZXR1cm4geyByZXMsIGRhdGEgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBjaGVja3MgaWYgdXNlZCBjb25uZWN0aW9ucyBpcyBsZXNzIHRoZW4gZ3JhbnRlZCBjb25uZWN0aW9uc1xuICAgKi9cbiAgcHJpdmF0ZSBoYXNBdmFpbGFibGVDb25uZWN0aW9ucyhjb25uZWN0aXZpdHlQbGFucykge1xuICAgIHJldHVybiBzb21lKFxuICAgICAgY29ubmVjdGl2aXR5UGxhbnMsXG4gICAgICBwbGFuID0+IHBhcnNlSW50KHBsYW4uZ3JhbnRlZENvbm5lY3Rpb25zLCAxMCkgPiBwYXJzZUludChwbGFuLnVzZWRDb25uZWN0aW9ucywgMTApXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdGhyb3dOb0Nvbm5lY3Rpdml0eVNldHRpbmdzRXJyb3IoKSB7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoKTtcbiAgICBlcnJvci5uYW1lID0gQWN0aWxpdHlFcnJvck5hbWUuTm9Db25uZWN0aXZpdHlTZXR0aW5nc0Vycm9yO1xuXG4gICAgaWYgKGF3YWl0IHRoaXMuYXBwU3RhdGUuaXNBcHBsaWNhdGlvbkF2YWlsYWJsZSgnYWRtaW5pc3RyYXRpb24nKSkge1xuICAgICAgZXJyb3IubWVzc2FnZSA9IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KFxuICAgICAgICBnZXR0ZXh0KFxuICAgICAgICAgIGBDb3VsZCBub3QgZ2V0IGNvbm5lY3Rpdml0eSBwbGFucyBmcm9tIHRoZSBMb1JhIHBsYXRmb3JtLiBWZXJpZnkgdGhlIFRoaW5nUGFyayBjcmVkZW50aWFscyBpbiB0aGUgQWRtaW5pc3RyYXRpb24gYXBwbGljYXRpb24gdW5kZXIgPGEgaHJlZj1cInt7IGxpbmsgfX1cIj5TZXR0aW5nczwvYT4uYFxuICAgICAgICApLFxuICAgICAgICB7XG4gICAgICAgICAgbGluazogJy9hcHBzL2FkbWluaXN0cmF0aW9uL2luZGV4Lmh0bWwjL2Nvbm5lY3Rpdml0eVNldHRpbmdzL211bHRpcGxlX2xuc19jb25uZWN0b3JzX2FjdGlsaXR5J1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBlcnJvci5tZXNzYWdlID0gZ2V0dGV4dChcbiAgICAgICAgJ0NvdWxkIG5vdCBnZXQgY29ubmVjdGl2aXR5IHBsYW5zIGZyb20gdGhlIExvUmEgcGxhdGZvcm0uIFBsZWFzZSBjb250YWN0IHRoZSBhZG1pbmlzdHJhdG9yLidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cblxuICBwcml2YXRlIHRocm93Q29ubmVjdGl2aXR5U2V0dGluZ3NFcnJvcihkYXRhOiB7IG1lc3NhZ2U6IHN0cmluZyB9KSB7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoKTtcbiAgICBlcnJvci5uYW1lID0gQWN0aWxpdHlFcnJvck5hbWUuQ29ubmVjdGl2aXR5U2V0dGluZ3NFcnJvcjtcbiAgICBlcnJvci5tZXNzYWdlID0gZGF0YS5tZXNzYWdlO1xuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgcHJpdmF0ZSB0aHJvd05vQ29ubmVjdGl2aXR5UGxhbnNFcnJvcigpIHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpO1xuICAgIGVycm9yLm5hbWUgPSBBY3RpbGl0eUVycm9yTmFtZS5Ob0Nvbm5lY3Rpdml0eVBsYW5zRXJyb3I7XG4gICAgZXJyb3IubWVzc2FnZSA9IGdldHRleHQoXG4gICAgICAnTm8gY29ubmVjdGl2aXR5IHBsYW5zIGZvdW5kLiBOZXcgY29ubmVjdGl2aXR5IHBsYW5zIG11c3QgYmUgY3JlYXRlZCB2aWEgdGhlIExvUmEgcGxhdGZvcm0uJ1xuICAgICk7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cblxuICBwcml2YXRlIHRocm93Tm9GcmVlU2xvdHNJbkNvbm5lY3Rpdml0eVBsYW5zRXJyb3IoKSB7XG4gICAgY29uc3QgY29tcGFueU5hbWUgPSB0aGlzLm9wdGlvbnNTZXJ2aWNlLmdldCgnY29tcGFueU5hbWUnLCAnQ3VtdWxvY2l0eSBJb1QnKTtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpO1xuICAgIGVycm9yLm5hbWUgPSBBY3RpbGl0eUVycm9yTmFtZS5Ob0ZyZWVTbG90c0luQ29ubmVjdGl2aXR5UGxhbnNFcnJvcjtcbiAgICBlcnJvci5tZXNzYWdlID0gdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoXG4gICAgICBnZXR0ZXh0KFxuICAgICAgICBgTm8gY29ubmVjdGl2aXR5IHBsYW5zIHdpdGggZnJlZSBzbG90cyBhdmFpbGFibGUuIFBsZWFzZSBjb250YWN0IFRoaW5nUGFyayBvbiB0aGUgZGV2aWNlIHF1b3RhIGxpbWl0cyBmb3IgeW91ciBjb25uZWN0aXZpdHkgcGxhbnMgb3IgcmVtb3ZlIHVudXNlZCBkZXZpY2VzIGZyb20gVGhpbmdQYXJrIGFuZCByZXRyeSByZWdpc3RlcmluZyB0aGUgZGV2aWNlIGluIHRoZSB7e2NvbXBhbnlOYW1lfX0gcGxhdGZvcm0uYFxuICAgICAgKSxcbiAgICAgIHtcbiAgICAgICAgY29tcGFueU5hbWVcbiAgICAgIH1cbiAgICApO1xuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgcHJpdmF0ZSB0aHJvd0RldmljZVByb2ZpbGVzRmV0Y2hFcnJvcigpIHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpO1xuICAgIGVycm9yLm5hbWUgPSBBY3RpbGl0eUVycm9yTmFtZS5EZXZpY2VQcm9maWxlc0ZldGNoRXJyb3I7XG4gICAgZXJyb3IubWVzc2FnZSA9IGdldHRleHQoJ0NvdWxkIG5vdCBsb2FkIGRldmljZSBwcm9maWxlcyBmcm9tIHRoZSBMb1JhIHBsYXRmb3JtLicpO1xuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgcHJpdmF0ZSB0aHJvd05vRGV2aWNlUHJvZmlsZXNFcnJvcigpIHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpO1xuICAgIGVycm9yLm5hbWUgPSBBY3RpbGl0eUVycm9yTmFtZS5Ob0RldmljZVByb2ZpbGVzRXJyb3I7XG4gICAgZXJyb3IubWVzc2FnZSA9IGdldHRleHQoXG4gICAgICAnTm8gZGV2aWNlIHByb2ZpbGVzIGZvdW5kLiBDcmVhdGUgYSBuZXcgZGV2aWNlIHByb2ZpbGUgdmlhIHRoZSBMb1JhIHBsYXRmb3JtLidcbiAgICApO1xuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgcHJpdmF0ZSB0aHJvd0RldmljZVByb3RvY29sc0ZldGNoRXJyb3IoKSB7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoKTtcbiAgICBlcnJvci5uYW1lID0gQWN0aWxpdHlFcnJvck5hbWUuRGV2aWNlUHJvdG9jb2xzRmV0Y2hFcnJvcjtcbiAgICBlcnJvci5tZXNzYWdlID0gZ2V0dGV4dCgnQ291bGQgbm90IGxvYWQgZGV2aWNlIHByb3RvY29scy4nKTtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuXG4gIHByaXZhdGUgdGhyb3dOb0RldmljZVByb3RvY29sc0Vycm9yKCkge1xuICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCk7XG4gICAgZXJyb3IubmFtZSA9IEFjdGlsaXR5RXJyb3JOYW1lLk5vRGV2aWNlUHJvdG9jb2xzRXJyb3I7XG4gICAgZXJyb3IubWVzc2FnZSA9IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KFxuICAgICAgZ2V0dGV4dChcbiAgICAgICAgYE5vIGRldmljZSBwcm90b2NvbHMgY29uZmlndXJlZC4gQ3JlYXRlIGEgTG9SYSBkZXZpY2UgcHJvdG9jb2wgaW4gPGEgaHJlZj1cInt7IGxpbmsgfX1cIj5EZXZpY2UgcHJvdG9jb2xzPC9hPi5gXG4gICAgICApLFxuICAgICAge1xuICAgICAgICBsaW5rOiAnL2FwcHMvZGV2aWNlbWFuYWdlbWVudC8jL2RldmljZXByb3RvY29scydcbiAgICAgIH1cbiAgICApO1xuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgcHJpdmF0ZSB0aHJvd1JlZ2lzdHJhdGlvbkVycm9yKGRhdGE6IHsgbWVzc2FnZTogc3RyaW5nIH0pIHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpO1xuICAgIGVycm9yLm5hbWUgPSBBY3RpbGl0eUVycm9yTmFtZS5SZWdpc3RyYXRpb25FcnJvcjtcbiAgICBlcnJvci5tZXNzYWdlID0gZGF0YS5tZXNzYWdlO1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG4iXX0=