UNPKG

@iotize/ionic

Version:

Iotize specific building blocks on top of @ionic/angular.

599 lines 69.6 kB
import { Validators } from '@angular/forms'; import { bufferToHexString, hexStringToBuffer, } from '@iotize/common/byte-converter'; import { FACTORY_RESET_MODE_VERSION, TapInfo, TAP_MANAGER_APP_ID, } from '@iotize/ionic'; import { HostProtocol, SpecialFeature, TapResponse, TargetProtocol, } from '@iotize/tap'; import { converters } from '@iotize/tap/service/core'; import { NfcConnectionPriority, NfcPairingMode, } from '@iotize/tap/service/impl/interface'; import { WifiKeyVisibility, WifiMode, WifiSSIDVisibility, } from '@iotize/tap/service/impl/wifi'; import { combineLatest } from 'rxjs'; import { map } from 'rxjs/operators'; import { enumToOptions } from './utility'; import { interfaceServiceGetAppPathResolved } from '@iotize/ionic'; const TAP_CONFIG_PATTERN = /^([0-9]+)\.([0-9]+)\.([0-9]+)$/; const IPV4_PATTERN = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/; const IPV4_MASK_PATTERN = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/; const SSID_PATTERN = /^[^ !#;+\]\/"\t][^+\]\/"\t]{0,30}[^ !#;+\]\/"\t]$|^[^ !#;+\]\/"\t]$/; function regexValidator(pattern, message) { return (control) => { const value = control.value; const valueMatchPattern = pattern.test(value); return !valueMatchPattern ? { invalidFormat: { value: control.value, message } } : null; }; } const validateTapVersion = regexValidator(TAP_CONFIG_PATTERN, `Must be a valid semantic version (Major.Minor.Patch).`); function enumFormatter(data) { return (value) => { if (Array.isArray(value)) { if (value.length === 0) { return '-'; } return value.map((key) => HostProtocol[key]).join(', '); } else { return data[value]; } }; } export function isTapConfigured(version) { return !(version.major === 0 && version.minor === 0 && version.patch === 0); } function stringToEnumArray(v, mapping) { return v .split(',') .map((item) => item.trim()) .map((item) => { if (!(item in mapping)) { throw new Error(`Invalid value "${item}". Must one of the following: ${Object.keys(mapping).join(', ')}`); } return mapping[item]; }); } var WifiTxPowerEnum; (function (WifiTxPowerEnum) { WifiTxPowerEnum[WifiTxPowerEnum["default"] = 0] = "default"; WifiTxPowerEnum[WifiTxPowerEnum["10 dBm"] = 40] = "10 dBm"; WifiTxPowerEnum[WifiTxPowerEnum["12.5 dBm"] = 50] = "12.5 dBm"; WifiTxPowerEnum[WifiTxPowerEnum["15 dBm"] = 60] = "15 dBm"; WifiTxPowerEnum[WifiTxPowerEnum["17.5 dBm"] = 70] = "17.5 dBm"; WifiTxPowerEnum[WifiTxPowerEnum["20 dBm"] = 80] = "20 dBm"; })(WifiTxPowerEnum || (WifiTxPowerEnum = {})); const IPV4_VALIDATOR = regexValidator(IPV4_PATTERN, `Not a valid IPv4 address (eg 192.168.20.1)`); export const defaultInfoResolverConfig = [ { key: TapInfo.HostProtocol, input: createEnumField('HostProtocol', HostProtocol), viewFormatter: enumFormatter(HostProtocol), }, { key: TapInfo.configVersion, input: { formValidators: [validateTapVersion], }, viewFormatter: (v) => { if (v === FACTORY_RESET_MODE_VERSION) { return 'FACTORY RESET'; } else if (v === '255.255.65535') { return 'CONFIGURATION MODE'; } else if (v) { return `v${v}`; } else { return 'UNKNOWN'; } }, editFormatter: { read: (input) => { return input; }, write: (v) => { return v || FACTORY_RESET_MODE_VERSION; }, }, }, { key: TapInfo.CloudEndpoint, getValue: async (tap) => { const hostname = (await tap.service.mqtt.getBrokerHostname()).body(); const port = (await tap.service.mqtt.getBrokerPort()).body(); return `${hostname}:${port}`; }, putValue: async (tap, value) => { const [hostname, port] = value.split(':'); const setPort = await tap.service.mqtt.putBrokerPort(port || '1883'); setPort.successful(); return tap.service.mqtt.putBrokerHostname(hostname); }, }, { key: TapInfo.TargetProtocolConfiguration, viewFormatter: (v) => `${bufferToHexString(v)}`, editFormatter: { read: (input) => { return input ? hexStringToBuffer(input) : new Uint8Array(); }, write: (v) => { return v ? bufferToHexString(v) : ''; }, }, getValue: async (tap) => { const result = await tap.service.target.getModbusTcpConfiguration(); result.successful(); return result.rawBody(); }, putValue: async (tap, value) => { return await tap.lwm2m.put('/1027//21', value); }, }, { input: { type: 'toggle', }, key: TapInfo.NFCConnectionPriority, getValue: async (tap) => { const value = (await tap.service.interface.getNfcConnectionPriority()).body(); return value === NfcConnectionPriority.NFC_PRIORITY; }, putValue: (tap, val) => { const mode = val ? NfcConnectionPriority.NFC_NON_PRIORITY : NfcConnectionPriority.NFC_PRIORITY; return tap.service.interface.putNfcConnectionPriority(mode); }, }, { key: TapInfo.NFCPairingMode, input: createEnumField('NfcPairingMode', NfcPairingMode), }, { key: TapInfo.DataLogMaxPacketCount, viewFormatter: (v) => { return v === 0 ? 'NO LIMIT' : v.toString(); }, input: { type: 'number', }, }, { key: TapInfo.IsTargetConnected, // viewFormatter: (v: boolean) => v ? 'YES' : 'NO', getValue: (tap) => tap.service.target.isConnected(), putValue: (tap, enabled) => { if (enabled) { return tap.service.target.connect(); } else { return tap.service.target.disconnect(); } }, input: { type: 'toggle', }, }, { key: TapInfo.universalLink, icon: 'link', }, { key: TapInfo.androidApplicationRecord, // TODO replace with getAndroidApplicationId() getValue: async (tap) => { const appPath = (await tap.service.interface.getAppPath()).body(); if (appPath.startsWith('$4/')) { return appPath.substring(3); } else { return TAP_MANAGER_APP_ID; } }, viewFormatter: (input) => { if (input === TAP_MANAGER_APP_ID) { return `${input} (Tap Manager)`; } return input; }, putValue: async (tap, value) => { return tap.service.interface.putAppPath(`$4/${value}`); }, }, { key: TapInfo.useEncryption, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return lockOptions.scramActivated; }, }, { key: TapInfo.lockFactoryReset, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return !lockOptions.disableHardwareFactoryReset; }, }, { key: TapInfo.InterfaceSecurityScramActivated, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return lockOptions.scramActivated; }, }, { key: TapInfo.InterfaceSecurityDisableHardwareFactoryReset, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return lockOptions.disableHardwareFactoryReset; }, }, { key: TapInfo.InterfaceSecurityDisabledResourceFactoryReset, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return lockOptions.disableResourceFactoryReset; }, }, { key: TapInfo.InterfaceSecurityDisabledLoginWithUID, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return lockOptions.disableLoginWithUID; }, }, { key: TapInfo.hashPassword, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return lockOptions.hashPassword; }, }, { key: TapInfo.isLoginWithUIDEnabled, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return !lockOptions.disableLoginWithUID; }, }, { key: TapInfo.isLWM2MFactoryResetEnabled, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return !lockOptions.disableResourceFactoryReset; }, }, { key: TapInfo.appPath, putValue: (tap, value) => { return tap.service.interface.putAppPath(value); }, getValue: (tap) => interfaceServiceGetAppPathResolved.call(tap.service.interface), }, { key: TapInfo.TargetProtocol, getValue: (tap) => { return tap.service.target.getProtocol(); }, putValue: (tap, protocol) => { return tap.service.target.putProtocol(protocol); }, setValue: (tap, protocol) => { return tap.service.target.setProtocol(protocol); }, viewFormatter: enumFormatter(TargetProtocol), input: { type: 'select', options: enumToOptions(TargetProtocol).filter((f) => { return f.key !== TargetProtocol.JTAG; }), }, }, { key: '/interface/available-host-protocols', viewFormatter: enumFormatter(HostProtocol), editFormatter: { write: (v) => { // console.log('Host protocols: ', v); if (!v || v.length === 0) { return 'NONE'; } return v.map((key) => HostProtocol[key]).join(', '); }, read: (v) => { return stringToEnumArray(v, HostProtocol); }, }, }, { key: TapInfo.authorizedHostProtocols, input: { type: 'select', multiple: true, options: [], }, viewFormatter: enumFormatter(HostProtocol), init: async (_service, config, infoResolver) => { const hostProtocols = await infoResolver.getValue(TapInfo.availableHostProtocols); if (config.input !== undefined) { config.input.options = hostProtocols.map((key) => { return { key: key, text: HostProtocol[key] }; }); } }, }, { key: TapInfo.AdpVersion, getValue: (tap) => tap.service.tapnpass.getStatus(), viewFormatter: (stats) => { const v = stats.header.version; return `${v.major}.${v.minor}.${v.patch}`; }, }, { key: TapInfo.WifiHostname, viewFormatter: (v) => { if (v === '0.0.0.0') { return 'NO IP'; } return v; }, }, { key: TapInfo.WifiSSID, input: { formValidators: [ regexValidator(SSID_PATTERN, `This is not a valid SSID. It can be any alphanumeric, case-sensitive entry from 1 to 32 characters. Trailing or leading spaces are not allowed.`), ], }, }, { key: TapInfo.WifiSSIDVisibility, input: createEnumField('WifiSSIDVisibility', WifiSSIDVisibility), viewFormatter: enumFormatter(WifiSSIDVisibility), }, { key: TapInfo.WifiKeyVisibility, input: createEnumField('WifiKeyVisibility', WifiKeyVisibility), viewFormatter: enumFormatter(WifiKeyVisibility), }, { key: TapInfo.WifiTxPower, viewFormatter: enumFormatter(WifiTxPowerEnum), input: createEnumField('WifiTxPowerEnum', WifiTxPowerEnum), }, { key: TapInfo.NetworkInfraIp, input: { formValidators: [IPV4_VALIDATOR], }, viewFormatter: (value) => { if (value === '0.0.0.0') { return 'Dynamic (DHCP)'; } return value; }, }, { key: TapInfo.NetworkIpMask, input: { formValidators: [ regexValidator(IPV4_MASK_PATTERN, `Not a valid IPv4 mask (eg 192.168.20.1)`), ], }, isDisplayed: ({ tapConfigItemStateService }) => { return combineLatest([ tapConfigItemStateService.valueChange(TapInfo.WifiMode), tapConfigItemStateService.valueChange(TapInfo.NetworkInfraIp), ]).pipe(map(([mode, ip]) => { return mode === WifiMode.NETWORK && ip !== '0.0.0.0'; })); }, }, { key: TapInfo.NetworkGatewayIp, input: { formValidators: [IPV4_VALIDATOR], }, isDisplayed: ({ tapConfigItemStateService }) => { return combineLatest([ tapConfigItemStateService.valueChange(TapInfo.WifiMode), tapConfigItemStateService.valueChange(TapInfo.NetworkInfraIp), ]).pipe(map(([mode, ip]) => { return mode === WifiMode.NETWORK && ip !== '0.0.0.0'; })); }, }, { key: TapInfo.NetworkDNSIp, input: { formValidators: [IPV4_VALIDATOR], }, isDisplayed: ({ tapConfigItemStateService }) => { return combineLatest([ tapConfigItemStateService.valueChange(TapInfo.WifiMode), tapConfigItemStateService.valueChange(TapInfo.NetworkInfraIp), ]).pipe(map(([mode, ip]) => { return mode === WifiMode.NETWORK && ip !== '0.0.0.0'; })); }, }, { key: TapInfo.WifiMode, input: createEnumField('WifiMode', WifiMode), }, { key: TapInfo.isHostProtocolAuthorized, input: { type: 'toggle', }, getValue: async (tap, protocol) => { if (protocol === undefined) { throw new Error('Illegal argument error: missing protocol'); } const protocols = (await tap.service.interface.getAuthorizedHostProtocol()).body(); return protocols.find((p) => p === protocol) !== undefined; }, putValue: async (tap, value, protocol) => { const protocols = (await tap.service.interface.getAuthorizedHostProtocol()).body(); if (protocol === undefined) { throw new Error('Illegal argument error: missing protocol'); } const indexOfProtocol = protocols.findIndex((p) => p === protocol); if (value) { if (indexOfProtocol === -1) { protocols.push(protocol); } } else { if (indexOfProtocol >= 0) { protocols.splice(indexOfProtocol, 1); } } return tap.service.interface.putAuthorizedHostProtocol(protocols); }, }, { key: TapInfo.WifiKey, input: { type: 'password', formValidators: [Validators.minLength(8), Validators.maxLength(128)], }, }, { key: TapInfo.variableMetaData, input: {}, getValue: async (tap, variableId) => { const metaData = (await tap.service.variable.getRawMeta(variableId)).body(); return converters.ascii.decode(metaData); }, putValue: (tap, value, bundleId) => { const data = converters.ascii.encode(value); return tap.service.variable.putRawMeta(bundleId, data); }, }, { key: TapInfo.profilePassword, input: { type: 'password', formValidators: [Validators.minLength(1), Validators.maxLength(16)], }, viewFormatter: () => { return '********'; }, putValue: async (tap, value, profileId) => { await tap.auth.changePassword(value, profileId); return TapResponse.SUCCESS(); }, }, { key: TapInfo.DeviceMemoryFree, viewFormatter(value) { return Math.floor((value / 1024) * 100) / 100 + ' KB'; }, }, { key: TapInfo.TimeLocalTime, viewFormatter(localTime) { if (!localTime) { return ''; } const date = new Date(Date.UTC(localTime.year, 0, localTime.dayOfYear)); date.setHours(localTime.hours); date.setMinutes(localTime.minutes); date.setSeconds(localTime.seconds); // {"seconds":54,"minutes":3,"hours":8,"dayOfMonth":8,"month":8,"year":122,"dayOfWeek":4,"dayOfYear":250,"isdst":0} return `${date.toUTCString()}`; }, }, { key: TapInfo.InterfaceSpecialFeatureSWDDirect, ...createSpecialFeatureDAO(SpecialFeature.SWD_DIRECT_ACCESS), }, { key: TapInfo.InterfaceSpecialFeatureSerial, ...createSpecialFeatureDAO(SpecialFeature.SERIAL_ACCESS), }, { key: TapInfo.InterfaceSpecialFeatureModbusDirect, ...createSpecialFeatureDAO(SpecialFeature.MODBUS_DIRECT_ACCESS), }, { key: '/wifi/enabled', input: { type: 'toggle', }, getValue: async (tap) => { const response = await tap.service.wifi.getDisabled(); return !response.body(); }, putValue: (tap, enabled) => { return tap.service.wifi.putDisabled(!enabled); }, }, ]; function createSpecialFeatureDAO(feature) { return { input: { type: 'number', formValidators: [Validators.min(0), Validators.max(65535)], }, getValue: async (tap) => { const result = (await tap.service.interface.getSpecialFeatureProfile(feature)).body(); if (result === 65535 - (feature - 100)) { return 'UNAUTHORIZED'; } else { return result; } }, putValue: async (tap, body) => { return await tap.service.interface.putSpecialFeatureProfile(feature, body); }, }; } function createEnumField(enumId, enumData) { return { type: 'select', enum: { id: enumId, data: enumData, }, }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW90aXplLWlvbmljL2NvbmZpZy9zcmMvbGliL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWdDLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzFFLE9BQU8sRUFDTCxpQkFBaUIsRUFDakIsaUJBQWlCLEdBQ2xCLE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUNMLDBCQUEwQixFQUUxQixPQUFPLEVBQ1Asa0JBQWtCLEdBQ25CLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFDTCxZQUFZLEVBQ1osY0FBYyxFQUVkLFdBQVcsRUFFWCxjQUFjLEdBQ2YsTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sRUFDTCxxQkFBcUIsRUFDckIsY0FBYyxHQUNmLE1BQU0sb0NBQW9DLENBQUM7QUFFNUMsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixRQUFRLEVBQ1Isa0JBQWtCLEdBQ25CLE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNyQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFckMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUMxQyxPQUFPLEVBQUUsa0NBQWtDLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFbkUsTUFBTSxrQkFBa0IsR0FBRyxnQ0FBZ0MsQ0FBQztBQUM1RCxNQUFNLFlBQVksR0FBRyxpQ0FBaUMsQ0FBQztBQUN2RCxNQUFNLGlCQUFpQixHQUFHLGlDQUFpQyxDQUFDO0FBQzVELE1BQU0sWUFBWSxHQUNoQixxRUFBcUUsQ0FBQztBQUV4RSxTQUFTLGNBQWMsQ0FBQyxPQUFlLEVBQUUsT0FBZTtJ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UUFDRCxRQUFRLEVBQUUsS0FBSyxFQUFFLEdBQVEsRUFBRSxFQUFFO1lBQzNCLE1BQU0sTUFBTSxHQUFHLENBQ2IsTUFBTSxHQUFHLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyx3QkFBd0IsQ0FBQyxPQUFPLENBQUMsQ0FDOUQsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNULElBQUksTUFBTSxLQUFLLEtBQUssR0FBRyxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUN2QyxPQUFPLGNBQWMsQ0FBQztZQUN4QixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sT0FBTyxNQUFNLENBQUM7WUFDaEIsQ0FBQztRQUNILENBQUM7UUFDRCxRQUFRLEVBQUUsS0FBSyxFQUFFLEdBQVEsRUFBRSxJQUFZLEVBQUUsRUFBRTtZQUN6QyxPQUFPLE1BQU0sR0FBRyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsd0JBQXdCLENBQ3pELE9BQU8sRUFDUCxJQUFJLENBQ0wsQ0FBQztRQUNKLENBQUM7S0FDRixDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsZUFBZSxDQUN0QixNQUFjLEVBQ2QsUUFBbUI7SUFFbkIsT0FBTztRQUNMLElBQUksRUFBRSxRQUFRO1FBQ2QsSUFBSSxFQUFFO1lBQ0osRUFBRSxFQUFFLE1BQU07WUFDVixJQUFJLEVBQUUsUUFBUTtTQUNmO0tBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIFZhbGlkYXRvckZuLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtcbiAgYnVmZmVyVG9IZXhTdHJpbmcsXG4gIGhleFN0cmluZ1RvQnVmZmVyLFxufSBmcm9tICdAaW90aXplL2NvbW1vbi9ieXRlLWNvbnZlcnRlcic7XG5pbXBvcnQge1xuICBGQUNUT1JZX1JFU0VUX01PREVfVkVSU0lPTixcbiAgTHdtMm1FbnVtLFxuICBUYXBJbmZvLFxuICBUQVBfTUFOQUdFUl9BUFBfSUQsXG59IGZyb20gJ0Bpb3RpemUvaW9uaWMnO1xuaW1wb3J0IHtcbiAgSG9zdFByb3RvY29sLFxuICBTcGVjaWFsRmVhdHVyZSxcbiAgVGFwLFxuICBUYXBSZXNwb25zZSxcbiAgVGFwVmVyc2lvbixcbiAgVGFyZ2V0UHJvdG9jb2wsXG59IGZyb20gJ0Bpb3RpemUvdGFwJztcbmltcG9ydCB7IGNvbnZlcnRlcnMgfSBmcm9tICdAaW90aXplL3RhcC9zZXJ2aWNlL2NvcmUnO1xuaW1wb3J0IHtcbiAgTmZjQ29ubmVjdGlvblByaW9yaXR5LFxuICBOZmNQYWlyaW5nTW9kZSxcbn0gZnJvbSAnQGlvdGl6ZS90YXAvc2VydmljZS9pbXBsL2ludGVyZmFjZSc7XG5pbXBvcnQgeyBBZHBTdGF0cyB9IGZyb20gJ0Bpb3RpemUvdGFwL3NlcnZpY2UvaW1wbC90YXBucGFzcyc7XG5pbXBvcnQge1xuICBXaWZpS2V5VmlzaWJpbGl0eSxcbiAgV2lmaU1vZGUsXG4gIFdpZmlTU0lEVmlzaWJpbGl0eSxcbn0gZnJvbSAnQGlvdGl6ZS90YXAvc2VydmljZS9pbXBsL3dpZmknO1xuaW1wb3J0IHsgY29tYmluZUxhdGVzdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGFwQ29uZmlnSXRlbUV4dGVuZGVkIH0gZnJvbSAnLi90YXAtY29uZmlnLWl0ZW0vdGFwLWNvbmZpZy1pdGVtLmRlZmluaXRpb24nO1xuaW1wb3J0IHsgZW51bVRvT3B0aW9ucyB9IGZyb20gJy4vdXRpbGl0eSc7XG5pbXBvcnQgeyBpbnRlcmZhY2VTZXJ2aWNlR2V0QXBwUGF0aFJlc29sdmVkIH0gZnJvbSAnQGlvdGl6ZS9pb25pYyc7XG5cbmNvbnN0IFRBUF9DT05GSUdfUEFUVEVSTiA9IC9eKFswLTldKylcXC4oWzAtOV0rKVxcLihbMC05XSspJC87XG5jb25zdCBJUFY0X1BBVFRFUk4gPSAvXig/OlswLTldezEsM31cXC4pezN9WzAtOV17MSwzfSQvO1xuY29uc3QgSVBWNF9NQVNLX1BBVFRFUk4gPSAvXig/OlswLTldezEsM31cXC4pezN9WzAtOV17MSwzfSQvO1xuY29uc3QgU1NJRF9QQVRURVJOID1cbiAgL15bXiAhIzsrXFxdXFwvXCJcXHRdW14rXFxdXFwvXCJcXHRdezAsMzB9W14gISM7K1xcXVxcL1wiXFx0XSR8XlteICEjOytcXF1cXC9cIlxcdF0kLztcblxuZnVuY3Rpb24gcmVnZXhWYWxpZGF0b3IocGF0dGVybjogUmVnRXhwLCBtZXNzYWdlOiBzdHJpbmcpOiBWYWxpZGF0b3JGbiB7XG4gIHJldHVybiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB8IG51bGwgPT4ge1xuICAgIGNvbnN0IHZhbHVlID0gY29udHJvbC52YWx1ZTtcbiAgICBjb25zdCB2YWx1ZU1hdGNoUGF0dGVybiA9IHBhdHRlcm4udGVzdCh2YWx1ZSk7XG4gICAgcmV0dXJuICF2YWx1ZU1hdGNoUGF0dGVyblxuICAgICAgPyB7IGludmFsaWRGb3JtYXQ6IHsgdmFsdWU6IGNvbnRyb2wudmFsdWUsIG1lc3NhZ2UgfSB9XG4gICAgICA6IG51bGw7XG4gIH07XG59XG5cbmNvbnN0IHZhbGlkYXRlVGFwVmVyc2lvbjogVmFsaWRhdG9yRm4gPSByZWdleFZhbGlkYXRvcihcbiAgVEFQX0NPTkZJR19QQVRURVJOLFxuICBgTXVzdCBiZSBhIHZhbGlkIHNlbWFudGljIHZlcnNpb24gKE1ham9yLk1pbm9yLlBhdGNoKS5gXG4pO1xuXG5mdW5jdGlvbiBlbnVtRm9ybWF0dGVyKGRhdGE6IGFueSk6ICh2YWx1ZTogYW55KSA9PiBzdHJpbmcge1xuICByZXR1cm4gKHZhbHVlOiBhbnkpID0+IHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuICctJztcbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWx1ZS5tYXAoKGtleSkgPT4gSG9zdFByb3RvY29sW2tleV0pLmpvaW4oJywgJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBkYXRhW3ZhbHVlXSBhcyBzdHJpbmc7XG4gICAgfVxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNUYXBDb25maWd1cmVkKHZlcnNpb246IFRhcFZlcnNpb24pIHtcbiAgcmV0dXJuICEodmVyc2lvbi5tYWpvciA9PT0gMCAmJiB2ZXJzaW9uLm1pbm9yID09PSAwICYmIHZlcnNpb24ucGF0Y2ggPT09IDApO1xufVxuXG5mdW5jdGlvbiBzdHJpbmdUb0VudW1BcnJheTxUPih2OiBzdHJpbmcsIG1hcHBpbmc6IGFueSk6IFRbXSB7XG4gIHJldHVybiB2XG4gICAgLnNwbGl0KCcsJylcbiAgICAubWFwKChpdGVtKSA9PiBpdGVtLnRyaW0oKSlcbiAgICAubWFwKChpdGVtKSA9PiB7XG4gICAgICBpZiAoIShpdGVtIGluIG1hcHBpbmcpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgSW52YWxpZCB2YWx1ZSBcIiR7aXRlbX1cIi4gTXVzdCBvbmUgb2YgdGhlIGZvbGxvd2luZzogJHtPYmplY3Qua2V5cyhcbiAgICAgICAgICAgIG1hcHBpbmdcbiAgICAgICAgICApLmpvaW4oJywgJyl9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1hcHBpbmdbaXRlbSBhcyBhbnldIGFzIHVua25vd24gYXMgVDtcbiAgICB9KTtcbn1cblxuZW51bSBXaWZpVHhQb3dlckVudW0ge1xuICAnZGVmYXVsdCcgPSAwLFxuICAnMTAgZEJtJyA9IDQwLFxuICAnMTIuNSBkQm0nID0gNTAsXG4gICcxNSBkQm0nID0gNjAsXG4gICcxNy41IGRCbScgPSA3MCxcbiAgJzIwIGRCbScgPSA4MCxcbn1cblxuY29uc3QgSVBWNF9WQUxJREFUT1IgPSByZWdleFZhbGlkYXRvcihcbiAgSVBWNF9QQVRURVJOLFxuICBgTm90IGEgdmFsaWQgSVB2NCBhZGRyZXNzIChlZyAxOTIuMTY4LjIwLjEpYFxuKTtcblxuZXhwb3J0IGNvbnN0IGRlZmF1bHRJbmZvUmVzb2x2ZXJDb25maWc6IFRhcENvbmZpZ0l0ZW1FeHRlbmRlZFtdID0gW1xuICB7XG4gICAga2V5OiBUYXBJbmZvLkhvc3RQcm90b2NvbCxcbiAgICBpbnB1dDogY3JlYXRlRW51bUZpZWxkKCdIb3N0UHJvdG9jb2wnLCBIb3N0UHJvdG9jb2wpLFxuICAgIHZpZXdGb3JtYXR0ZXI6IGVudW1Gb3JtYXR0ZXIoSG9zdFByb3RvY29sKSxcbiAgfSxcbiAge1xuICAgIGtleTogVGFwSW5mby5jb25maWdWZXJzaW9uLFxuICAgIGlucHV0OiB7XG4gICAgICBmb3JtVmFsaWRhdG9yczogW3ZhbGlkYXRlVGFwVmVyc2lvbl0sXG4gICAgfSxcbiAgICB2aWV3Rm9ybWF0dGVyOiAodjogc3RyaW5nKSA9PiB7XG4gICAgICBpZiAodiA9PT0gRkFDVE9SWV9SRVNFVF9NT0RFX1ZFUlNJT04pIHtcbiAgICAgICAgcmV0dXJuICdGQUNUT1JZIFJFU0VUJztcbiAgICAgIH0gZWxzZSBpZiAodiA9PT0gJzI1NS4yNTUuNjU1MzUnKSB7XG4gICAgICAgIHJldHVybiAnQ09ORklHVVJBVElPTiBNT0RFJztcbiAgICAgIH0gZWxzZSBpZiAodikge1xuICAgICAgICByZXR1cm4gYHYke3Z9YDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiAnVU5LTk9XTic7XG4gICAgICB9XG4gICAgfSxcbiAgICBlZGl0Rm9ybWF0dGVyOiB7XG4gICAgICByZWFkOiAoaW5wdXQ6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gICAgICAgIHJldHVybiBpbnB1dDtcbiAgICAgIH0sXG4gICAgICB3cml0ZTogKHY6IHN0cmluZyB8IHVuZGVmaW5lZCkgPT4ge1xuICAgICAgICByZXR1cm4gdiB8fCBGQUNUT1JZX1JFU0VUX01PREVfVkVSU0lPTjtcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbiAge1xuICAgIGtleTogVGFwSW5mby5DbG91ZEVuZHBvaW50LFxuICAgIGdldFZhbHVlOiBhc3luYyAodGFwKSA9PiB7XG4gICAgICBjb25zdCBob3N0bmFtZSA9IChhd2FpdCB0YXAuc2VydmljZS5tcXR0LmdldEJyb2tlckhvc3RuYW1lKCkpLmJvZHkoKTtcbiAgICAgIGNvbnN0IHBvcnQgPSAoYXdhaXQgdGFwLnNlcnZpY2UubXF0dC5nZXRCcm9rZXJQb3J0KCkpLmJvZHkoKTtcbiAgICAgIHJldHVybiBgJHtob3N0bmFtZX06JHtwb3J0fWA7XG4gICAgfSxcbiAgICBwdXRWYWx1ZTogYXN5bmMgKHRhcDogVGFwLCB2YWx1ZTogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBbaG9zdG5hbWUsIHBvcnRdID0gdmFsdWUuc3BsaXQoJzonKTtcbiAgICAgIGNvbnN0IHNldFBvcnQgPSBhd2FpdCB0YXAuc2VydmljZS5tcXR0LnB1dEJyb2tlclBvcnQocG9ydCB8fCAnMTg4MycpO1xuICAgICAgc2V0UG9ydC5zdWNjZXNzZnVsKCk7XG4gICAgICByZXR1cm4gdGFwLnNlcnZpY2UubXF0dC5wdXRCcm9rZXJIb3N0bmFtZShob3N0bmFtZSk7XG4gICAgfSxcbiAgfSxcbiAge1xuICAgIGtleTogVGFwSW5mby5UYXJnZXRQcm90b2NvbENvbmZpZ3VyYXRpb24sXG4gICAgdmlld0Zvcm1hdHRlcjogKHY6IFVpbnQ4QXJyYXkpID0+IGAke2J1ZmZlclRvSGV4U3RyaW5nKHYpfWAsXG4gICAgZWRpdEZvcm1hdHRlcjoge1xuICAgICAgcmVhZDogKGlucHV0OiBzdHJpbmcpOiBVaW50OEFycmF5ID0+IHtcbiAgICAgICAgcmV0dXJuIGlucHV0ID8gaGV4U3RyaW5nVG9CdWZmZXIoaW5wdXQpIDogbmV3IFVpbnQ4QXJyYXkoKTtcbiAgICAgIH0sXG4gICAgICB3cml0ZTogKHY6IFVpbnQ4QXJyYXkgfCB1bmRlZmluZWQpID0+IHtcbiAgICAgICAgcmV0dXJuIHYgPyBidWZmZXJUb0hleFN0cmluZyh2