homebridge-config-ui-x
Version:
A web based management, configuration and control platform for Homebridge.
19 lines • 52.7 kB
JavaScript
import{a as E,i as D,o as w,s as x,t as A}from"./chunk-D39XL-zh.js";import{$ as Le,Ct as Qo,E as Dy,Fr as se$1,Gr as uy,It as TT,Jr as ve,Kr as v3,Ln as db,M as Fe,Pr as sc,Q as Ko,Rt as Te,Tn as ac,Un as g,Vt as U3,Yr as vy,Yt as Va,br as pb,d as Ay,dt as Nf,hn as _T,hr as nc,jt as S_,kt as ST,li as yr,nn as WS,pt as Ot,ri as x_,rr as jd,sr as kt,tt as Ln,ui as z0,ut as N_,vt as Py,wr as q,x as Cr}from"./chunk-D96TCRAL.js";import{a as W,l as le$1}from"./chunk-DZYp0NQB.js";import{n as zt}from"./chunk-CdJ3i4Aq.js";import{A as Jf,B as Hn,H as Jn,U as Kn,Y as Ye,a as Q$1,f as B,i as $,lt as fe,m as f,o as U,p as k,r as Y,s as re$1,t as m,tt as ln,ut as si}from"./main-E3N63CH7.js";import{E as w$1,n as C,t as A$1}from"./chunk-nWnpef0a.js";import{t as O}from"./chunk-C-2fYS21.js";import{E as n}from"./chunk-BuXBmaui.js";import"./chunk-BinBJ-zk2.js";import{a as oe$1,i as jt,n as Fe$1,o as qt$1,r as ce$1,s as se$2,t as Dt}from"./chunk-Bwmof_W-2.js";import{t as N}from"./chunk-MQWddKEg2.js";import{t as L}from"./chunk-tTuB-TjV2.js";var Q=D(Dt(),1);var Ut=D(L(),1);function Xt(s,v){s&1&&(Va(0,`div`,15),Dy(1,`i`,22),jd())}function Zt(s,v){if(s&1){let t=sc();Va(0,`li`,9)(1,`span`),Ot(2),S_(3,`date`),Dy(4,`br`),Va(5,`span`,23),Ot(6),S_(7,`date`),jd()(),Va(8,`span`,27),S_(9,`translate`),Va(10,`button`,28),S_(11,`translate`),S_(12,`translate`),ac(`click`,function(){let i=Ko(t).$implicit;return Qo(ve(2).restore(i.id))}),Dy(13,`i`,29),jd(),Va(14,`button`,30),S_(15,`translate`),S_(16,`translate`),ac(`click`,function(){let i=Ko(t).$implicit;return Qo(ve(2).download(i.id))}),Dy(17,`i`,31),jd(),Va(18,`button`,25),S_(19,`translate`),S_(20,`translate`),ac(`click`,function(){let i=Ko(t).$implicit;return Qo(ve(2).delete(i.id))}),Dy(21,`i`,26),jd()()()}if(s&2){let t=v.$implicit,e=ve(2);se$1(2),kt(` `,x_(3,21,t.timestamp,`mediumDate`)),se$1(4),Py(x_(7,24,t.timestamp,`shortTime`)),se$1(2),Cr(`aria-label`,N_(9,27,`backup.aria_actions`)),se$1(2),vy(`disabled`,e.clicked()||e.deleting())(`ngbTooltip`,N_(11,29,`config.restore.copy_to_editor`))(`openDelay`,150),Cr(`aria-label`,N_(12,31,`config.restore.copy_to_editor`)),se$1(4),vy(`disabled`,e.clicked()||e.deleting())(`ngbTooltip`,N_(15,33,`form.button_download`))(`openDelay`,150),Cr(`aria-label`,N_(16,35,`form.button_download`)),se$1(4),vy(`disabled`,e.clicked()||e.deleting())(`ngbTooltip`,N_(19,37,`form.button_delete`))(`openDelay`,150),Cr(`aria-label`,N_(20,39,`form.button_delete`)),se$1(3),Ay(`fa-trash`,t.id!==e.deleting())(`fa-circle-notch`,t.id===e.deleting())(`fa-spin`,t.id===e.deleting())}}function te(s,v){if(s&1){let t=sc();Va(0,`ul`,16),_T(1,Zt,22,41,`li`,9,TT),Va(3,`li`,9)(4,`span`),Ot(5),S_(6,`translate`),Dy(7,`br`),Va(8,`span`,23),Ot(9),S_(10,`translate`),jd()(),Va(11,`span`,24)(12,`button`,25),S_(13,`translate`),S_(14,`translate`),ac(`click`,function(){Ko(t);return Qo(ve().deleteAllBackups())}),Dy(15,`i`,26),jd()()()()}if(s&2){let t=ve();se$1(),ST(t.backupList()),se$1(4),kt(` `,N_(6,12,`form.button_delete_all`)),se$1(4),Py(N_(10,14,`common.labels.no_confirmation`)),se$1(3),vy(`disabled`,t.clicked()||t.deleting())(`ngbTooltip`,N_(13,16,`form.button_delete_all`))(`openDelay`,150),Cr(`aria-label`,N_(14,18,`form.button_delete_all`)),se$1(3),Ay(`fa-trash`,t.deleting()!==`all`)(`fa-circle-notch`,t.deleting()===`all`)(`fa-spin`,t.deleting()===`all`)}}var qt=(()=>{class s{$activeModal=g(fe);$api=g(U3);$errors=g(m);$router=g(le$1);$toastr=g(z0);$translate=g(Nf);modalData=g(w$1);currentConfig=this.modalData.currentConfig;fromSettings=this.modalData.fromSettings??!1;loading=q(!0);backupList=q([]);clicked=q(!1);deleting=q(null);ngOnInit(){this.getConfigBackups()}getConfigBackups(){return E(this,null,function*(){try{let t=yield this.$api.get(`/config-editor/backups`);this.loading.set(!1),this.backupList.set(t)}catch(t){this.loading.set(!1),console.error(t),this.$toastr.error(this.$errors.toToastMessage(t),this.$translate.instant(`toast.title_error`)),this.dismissModal()}})}restore(t){return this.$activeModal.close(t)}download(t){return E(this,null,function*(){this.clicked.set(!0);try{let e=yield this.$api.get(`/config-editor/backups/${t}`),i=JSON.stringify(e,null,4),n=new Blob([i],{type:`application/json`}),f=`config-backup-${t}.json`;(0,Ut.saveAs)(n,f),this.clicked.set(!1)}catch(e){this.clicked.set(!1),this.$toastr.error(this.$errors.toToastMessage(e),this.$translate.instant(`toast.title_error`)),console.error(e)}})}downloadCurrentConfig(){let t=`data:text/json;charset=utf-8,${encodeURIComponent(this.currentConfig)}`,e=document.createElement(`a`);e.setAttribute(`href`,t),e.setAttribute(`download`,`config.json`),document.body.appendChild(e),e.click(),e.remove()}delete(t){return E(this,null,function*(){this.deleting.set(t);try{yield this.$api.delete(`/config-editor/backups/${t}`),yield this.getConfigBackups(),this.deleting.set(null)}catch(e){this.deleting.set(null),this.$toastr.error(this.$errors.toToastMessage(e),this.$translate.instant(`toast.title_error`)),console.error(e)}})}deleteAllBackups(){return E(this,null,function*(){this.deleting.set(`all`);try{yield this.$api.delete(`/config-editor/backups`),this.$toastr.success(this.$translate.instant(`config.restore.toast_backups_deleted`),this.$translate.instant(`toast.title_success`)),this.backupList.set([]),this.deleting.set(null)}catch(t){this.$toastr.error(this.$errors.toToastMessage(t),this.$translate.instant(`toast.title_error`)),console.error(t),this.deleting.set(null)}})}dismissModal(){this.fromSettings&&this.$router.navigate([`/settings`]),this.$activeModal.dismiss(`Dismiss`)}static ɵfac=function(e){return new(e||s)};static ɵcmp=nc({type:s,selectors:[[`app-config-restore`]],decls:43,vars:34,consts:[[1,`modal-content`],[1,`modal-header`],[1,`modal-title`],[`type`,`button`,`data-bs-dismiss`,`modal`,1,`btn-close`,3,`click`,`disabled`],[1,`modal-body`],[1,`text-center`,`mb-3`],[`aria-hidden`,`true`,1,`fas`,`fa-history`,`primary-text`,`icon-xl`],[1,`mb-3`],[1,`list-group`,`list-group-box`,`mb-0`],[1,`list-group-item`,`d-flex`,`justify-content-between`,`align-items-center`],[`aria-hidden`,`true`],[1,`grey-text`],[`type`,`button`,1,`btn`,`btn-primary`,`m-0`,`ms-3`,`py-1`,3,`click`,`disabled`],[`aria-hidden`,`true`,1,`visually-hidden`],[`aria-hidden`,`true`,1,`fas`,`fa-arrow-right`],[1,`text-center`,`primary-text`],[1,`list-group`,`list-group-box`,`mt-3`],[1,`modal-footer`,`justify-content-between`],[1,`text-start`],[1,`text-center`],[`type`,`button`,`data-bs-dismiss`,`modal`,1,`btn`,`btn-elegant`,3,`click`,`disabled`],[1,`text-end`],[`aria-hidden`,`true`,1,`fas`,`fa-circle-notch`,`fa-spin`,`mt-3`,`icon-xl`],[1,`grey-text`,`small`],[1,`d-flex`,`flex-nowrap`],[`type`,`button`,`placement`,`bottom`,`container`,`modal`,`triggers`,`hover`,1,`btn`,`btn-danger`,`m-0`,`ms-2`,3,`click`,`disabled`,`ngbTooltip`,`openDelay`],[`aria-hidden`,`true`,1,`fas`],[`role`,`group`,1,`d-flex`,`flex-nowrap`],[`type`,`button`,`placement`,`bottom`,`container`,`modal`,`triggers`,`hover`,1,`btn`,`btn-primary`,`m-0`,`ms-3`,`py-1`,3,`click`,`disabled`,`ngbTooltip`,`openDelay`],[`aria-hidden`,`true`,1,`fas`,`fa-history`],[`type`,`button`,`placement`,`bottom`,`container`,`modal`,`triggers`,`hover`,1,`btn`,`btn-primary`,`m-0`,`ms-2`,3,`click`,`disabled`,`ngbTooltip`,`openDelay`],[`aria-hidden`,`true`,1,`fas`,`fa-download`]],template:function(e,i){e&1&&(Va(0,`div`,0)(1,`div`,1)(2,`h5`,2),Ot(3),S_(4,`translate`),jd(),Va(5,`button`,3),S_(6,`translate`),ac(`click`,function(){return i.dismissModal()}),jd()(),Va(7,`div`,4)(8,`div`,5),Dy(9,`i`,6),jd(),Va(10,`ul`,7)(11,`li`),Ot(12),S_(13,`translate`),jd(),Va(14,`li`),Ot(15),S_(16,`translate`),jd()(),Va(17,`ul`,8)(18,`li`,9)(19,`div`,10)(20,`span`),Ot(21),S_(22,`translate`),jd(),Dy(23,`br`),Va(24,`small`,11),Ot(25),S_(26,`translate`),jd()(),Va(27,`button`,12),S_(28,`translate`),ac(`click`,function(){return i.downloadCurrentConfig()}),Va(29,`span`,13),Ot(30),S_(31,`translate`),jd(),Dy(32,`i`,14),jd()()(),Fe(33,Xt,2,0,`div`,15)(34,te,16,20,`ul`,16),jd(),Va(35,`div`,17),Dy(36,`div`,18),Va(37,`div`,19)(38,`button`,20),S_(39,`translate`),ac(`click`,function(){return i.dismissModal()}),Ot(40),S_(41,`translate`),jd()(),Dy(42,`div`,21),jd()()),e&2&&(se$1(3),Py(N_(4,14,`config.restore.title`)),se$1(2),vy(`disabled`,i.clicked()||i.deleting()),Cr(`aria-label`,N_(6,16,`form.button_close`)),se$1(7),Py(N_(13,18,`config.restore.help_1`)),se$1(3),Py(N_(16,20,`config.restore.help_2`)),se$1(6),Py(N_(22,22,`form.button_download`)),se$1(4),Py(N_(26,24,`config.restore.download`)),se$1(2),vy(`disabled`,i.clicked()||i.deleting()),Cr(`aria-label`,N_(28,26,`form.button_download`)),se$1(3),Py(N_(31,28,`form.button_download`)),se$1(3),Le(i.loading()?33:i.backupList().length?34:-1),se$1(5),vy(`disabled`,i.clicked()||i.deleting()),Cr(`aria-label`,N_(39,30,`form.button_close`)),se$1(2),kt(` `,N_(41,32,`form.button_close`),` `))},dependencies:[Y,Jn,WS,v3],encapsulation:2})}return s})();function ee(s,v){s&1&&Dy(0,`i`,11)}function ie(s,v){s&1&&Dy(0,`i`,11)}function ne(s,v){if(s&1){let t=sc();Va(0,`button`,20),S_(1,`translate`),S_(2,`translate`),ac(`click`,function(){Ko(t);return Qo(ve().onCancelRestore())}),Dy(3,`i`,21),jd()}if(s&2)vy(`disabled`,ve().saveInProgress())(`openDelay`,150)(`ngbTooltip`,N_(1,4,`form.button_cancel`)),Cr(`aria-label`,N_(2,6,`form.button_cancel`))}function se(s,v){if(s&1){let t=sc();Va(0,`button`,22),S_(1,`translate`),S_(2,`translate`),ac(`click`,function(){Ko(t);return Qo(ve().onRestore())}),Dy(3,`i`,23),jd()}s&2&&(vy(`openDelay`,150)(`ngbTooltip`,N_(1,3,`form.button_restore`)),Cr(`aria-label`,N_(2,5,`form.button_restore`)))}function oe(s,v){if(s&1){let t=sc();Va(0,`button`,22),S_(1,`translate`),S_(2,`translate`),ac(`click`,function(){Ko(t);return Qo(ve().toggleSideBySide())}),Dy(3,`i`,24),jd()}if(s&2){let t=ve();vy(`openDelay`,150)(`ngbTooltip`,N_(1,7,t.renderSideBySide()?`config.restore.view_inline`:`config.restore.view_side_by_side`)),Cr(`aria-label`,N_(2,9,t.renderSideBySide()?`config.restore.view_inline`:`config.restore.view_side_by_side`)),se$1(3),Ay(`fa-columns`,!t.renderSideBySide())(`fa-bars`,t.renderSideBySide())}}function re(s,v){s&1&&Dy(0,`i`,15)}function ae(s,v){s&1&&Dy(0,`i`,16)}function le(s,v){if(s&1){let t=sc();Va(0,`ngx-monaco-editor`,25),ac(`onInit`,function(i){Ko(t);return Qo(ve().onEditorInit(i))})(`keydown.control.s`,function(i){Ko(t);let n=ve();return i.preventDefault(),Qo(n.onSave())})(`keydown.meta.s`,function(i){Ko(t);let n=ve();return i.preventDefault(),Qo(n.onSave())}),jd()}if(s&2){let t=ve();vy(`options`,t.editorOptions)(`model`,t.monacoEditorModel)}}function de(s,v){if(s&1){let t=sc();Va(0,`ngx-monaco-diff-editor`,26),ac(`onInit`,function(i){Ko(t);return Qo(ve().onInitDiffEditor(i))})(`keydown.control.s`,function(i){Ko(t);let n=ve();return i.preventDefault(),Qo(n.onSave())})(`keydown.meta.s`,function(i){Ko(t);let n=ve();return i.preventDefault(),Qo(n.onSave())}),jd()}if(s&2){let t=ve();vy(`options`,t.editorOptions)(`originalModel`,t.diffOriginalModel)(`modifiedModel`,t.diffModifiedModel)}}function ce(s,v){if(s&1){let t=sc();Va(0,`textarea`,27),S_(1,`translate`),ac(`ngModelChange`,function(i){Ko(t);return Qo(ve().homebridgeConfig.set(i))}),Ot(2,` `),jd(),db()}if(s&2)vy(`ngModel`,ve().homebridgeConfig()),Cr(`aria-label`,N_(1,2,`menu.config_json_editor`)),pb()}var ei=(()=>{class s{injector=g(Te);$api=g(U3);$childBridges=g(jt);$md=g(N);$modal=g(si);$monacoEditor=g(f);$renderer=g(yr);$route=g(W);$router=g(le$1);$settings=g(zt);$toastr=g(z0);$translate=g(Nf);editorDecorations=[];lastHeight;visualViewPortEventCallback;latestSavedConfig;childBridgesToRestart=[];hbPendingRestart=!1;isDebugModeEnabled=this.$settings.isFeatureEnabled(`childBridgeDebugMode`);isMatterSupported=this.$settings.isFeatureEnabled(`matterSupport`);isProtocolExternalsOnlyEnabled=this.$settings.isFeatureEnabled(`protocolExternalsOnly`);isMatterDisableIpv4Enabled=this.$settings.isFeatureEnabled(`matterDisableIpv4`);isHapDisableIdentifyingMaterialEnabled=this.$settings.isFeatureEnabled(`hapDisableIdentifyingMaterial`);homebridgeConfig=q(``);originalConfig=q(``);saveInProgress=q(!1);isMobile=q(!1);preferPlainTextEditor=q(typeof localStorage<`u`&&localStorage.getItem(`hb_config_editor_plaintext`)===`true`);monacoEditor;editorOptions;monacoEditorModel;diffOriginalModel;diffModifiedModel;renderSideBySide=q(!1);constructor(){this.isMobile.set(!!this.$md.detect.mobile())}get isMonacoActive(){return!this.isMobile()&&!this.preferPlainTextEditor()&&!!this.monacoEditor}ngOnInit(){let t=this.$translate.instant(`menu.config_json_editor`);this.$settings.setPageTitle(t),this.editorOptions={language:`json`,theme:this.$settings.actualLightingMode===`dark`?`vs-dark`:`vs-light`,renderSideBySide:this.renderSideBySide(),renderIndicators:!0,ignoreTrimWhitespace:!1,glyphMargin:!0};let e=document.querySelector(`.content`);this.$renderer.setStyle(e,`height`,`100%`),this.visualViewPortEventCallback=()=>this.visualViewPortChanged(),this.lastHeight=window.innerHeight,window.visualViewport&&!this.isMobile()&&(window.visualViewport.addEventListener(`resize`,this.visualViewPortEventCallback,!0),this.$md.disableTouchMove()),this.$route.data.subscribe(n=>{this.homebridgeConfig.set(n.config),this.latestSavedConfig=JSON.parse(n.config),this.diffModifiedModel&&this.updateDiffModels()}),this.monacoEditorModel={value:`{}`,language:`json`,uri:window.monaco?window.monaco.Uri.parse(`a://homebridge/config.json`):void 0},this.diffOriginalModel={code:``,language:`json`},this.diffModifiedModel={code:this.homebridgeConfig()||`{}`,language:`json`},window.monaco?this.setMonacoEditorModel():this.waitForMonaco();let{action:i}=this.$router.parseUrl(this.$router.url).queryParams;i&&(i===`restore`&&this.onRestore(!0),this.$router.navigate([],{queryParams:{},replaceUrl:!0,queryParamsHandling:``}))}waitForMonaco(){return E(this,null,function*(){try{yield Ln(this.$monacoEditor.readyEvent),this.setMonacoEditorModel()}catch(t){console.error(`Failed to wait for monaco ready event:`,t)}})}onEditorInit(t){window.editor=t,this.monacoEditor=t;let e=this.monacoEditor.getModel();e&&e.setValue(this.homebridgeConfig())}onInitDiffEditor(t){this.monacoEditor=t.getModifiedEditor(),this.updateDiffModels(),window.editor=t}setPlainTextEditor(t){if(!!t!==this.preferPlainTextEditor()){if(t&&this.isMonacoActive)try{let e=this.monacoEditor.getModel()?.getValue();typeof e==`string`&&this.homebridgeConfig.set(e)}catch(e){console.error(`Failed to read monaco editor value:`,e)}this.preferPlainTextEditor.set(!!t);try{localStorage.setItem(`hb_config_editor_plaintext`,t?`true`:`false`)}catch(e){}t||setTimeout(()=>{try{this.monacoEditor&&this.homebridgeConfig()&&(this.monacoEditor.getModel()?.setValue(this.homebridgeConfig()),this.monacoEditor.focus())}catch(e){console.error(`Failed to refocus monaco editor:`,e)}},0)}}updateDiffModels(){if(this.diffOriginalModel&&(this.diffOriginalModel.code=this.originalConfig()||``),this.diffModifiedModel&&(this.diffModifiedModel.code=this.homebridgeConfig()||`{}`),window.editor&&window.editor.getOriginalEditor){let t=window.editor.getOriginalEditor(),e=window.editor.getModifiedEditor();if(t&&e){let i=t.getModel(),n=e.getModel();i&&i.setValue(this.originalConfig()||``),n&&n.setValue(this.homebridgeConfig()||`{}`)}}}onSave(){return E(this,null,function*(){if(!this.saveInProgress()){this.isMonacoActive&&(this.editorDecorations=this.monacoEditor.deltaDecorations(this.editorDecorations,[])),this.saveInProgress.set(!0);try{if(this.isMonacoActive){yield this.monacoEditor.getAction(`editor.action.formatDocument`).run();let e=window.monaco.editor.getModelMarkers({owner:`json`});for(let i of e)if(i.message===`Duplicate object key`){this.saveInProgress.set(!1),this.$toastr.error(this.$translate.instant(`config.config_invalid_json`),this.$translate.instant(`toast.title_error`));return}this.homebridgeConfig.set(this.monacoEditor.getModel().getValue())}let t=this.parseConfigFromEditor();this.homebridgeConfig.set(JSON.stringify(t,null,4)),typeof t.bridge!=`object`?this.$toastr.error(this.$translate.instant(`config.config_bridge_missing`),this.$translate.instant(`toast.title_error`)):n.test(t.bridge.username)?t.accessories&&!Array.isArray(t.accessories)?this.$toastr.error(this.$translate.instant(`config.config_accessory_must_be_array`),this.$translate.instant(`toast.title_error`)):t.platforms&&!Array.isArray(t.platforms)?this.$toastr.error(this.$translate.instant(`config.config_platform_must_be_array`),this.$translate.instant(`toast.title_error`)):t.platforms&&Array.isArray(t.platforms)&&!this.validateSection(t.platforms,`platform`)||t.accessories&&Array.isArray(t.accessories)&&!this.validateSection(t.accessories,`accessory`)||t.plugins&&Array.isArray(t.plugins)&&!this.validatePlugins(t.plugins,`plugins`)||t.disabledPlugins&&Array.isArray(t.disabledPlugins)&&!this.validatePlugins(t.disabledPlugins,`disabledPlugins`)||(yield this.saveConfig(t),this.originalConfig.set(``)):this.$toastr.error(this.$translate.instant(`config.config_username_error`),this.$translate.instant(`toast.title_error`))}catch(t){console.error(t),this.$toastr.error(this.$translate.instant(`config.config_invalid_json`),this.$translate.instant(`toast.title_error`))}this.saveInProgress.set(!1)}})}onRestore(t=!1){return E(this,null,function*(){let e=uy([{provide:w$1,useValue:{currentConfig:this.homebridgeConfig(),fromSettings:t}}],this.injector),i=this.$modal.open(qt,{size:`lg`,backdrop:`static`,injector:e});try{let n=yield i.result;try{this.originalConfig()||(this.originalConfig.set(this.homebridgeConfig()),this.updateDiffModels());let f=yield this.$api.get(`/config-editor/backups/${n}`);this.$toastr.info(this.$translate.instant(`config.restore.confirm`),this.$translate.instant(`config.title_backup_loaded`)),this.homebridgeConfig.set(JSON.stringify(f,null,4)),this.updateDiffModels(),this.monacoEditor&&window.editor.modifiedEditor&&(this.editorDecorations=this.monacoEditor.deltaDecorations(this.editorDecorations,[]),this.monacoEditor.executeEdits(`beautifier`,[{identifier:`delete`,range:new monaco.Range(1,1,this.monacoEditor.getModel().getLineCount()+10,1),text:``,forceMoveMarkers:!0}]),this.monacoEditor.executeEdits(`beautifier`,[{identifier:`insert`,range:new monaco.Range(1,1,1,1),text:this.homebridgeConfig(),forceMoveMarkers:!0}]))}catch(f){console.error(f);let k=f?.error?.message||this.$translate.instant(`backup.load_error`);this.$toastr.error(k,this.$translate.instant(`toast.title_error`))}}catch(n){}})}onCancelRestore(){if(window.editor&&window.editor.dispose)try{window.editor.dispose(),window.editor=void 0}catch(t){}this.homebridgeConfig.set(this.originalConfig()),this.originalConfig.set(``),this.renderSideBySide()&&this.toggleSideBySide(),this.updateDiffModels(),this.onRestore()}toggleSideBySide(){this.renderSideBySide.set(!this.renderSideBySide()),this.editorOptions=x(w({},this.editorOptions),{renderSideBySide:this.renderSideBySide()})}canDeactivate(){if(!this.latestSavedConfig)return!0;let t=this.isMonacoActive?this.monacoEditor.getModel().getValue():this.homebridgeConfig(),e;try{e=Q.default.parse(t)}catch(i){return this.confirmDiscardChanges()}return Jf(e,this.latestSavedConfig)?!0:this.confirmDiscardChanges()}confirmDiscardChanges(){let t=uy([{provide:A$1,useValue:{title:this.$translate.instant(`config.label_unsaved_changes`),message:this.$translate.instant(`config.message_unsaved_changes`),confirmButtonLabel:this.$translate.instant(`form.button_discard`),confirmButtonClass:`btn-danger`,faIconClass:`fas fa-triangle-exclamation orange-text`}}],this.injector);return this.$modal.open(O,{size:`lg`,backdrop:`static`,injector:t}).result.then(()=>!0,()=>!1)}ngOnDestroy(){let t=document.querySelector(`.content`);this.$renderer.removeStyle(t,`height`),window.visualViewport&&(window.visualViewport.removeEventListener(`resize`,this.visualViewPortEventCallback,!0),this.$md.enableTouchMove());try{if(window.editor&&window.editor.dispose&&(window.editor.dispose(),window.editor=void 0),window.monaco){let e=window.monaco.Uri.parse(`file:///original.json`),i=window.monaco.Uri.parse(`file:///modified.json`),n=window.monaco.Uri.parse(`a://homebridge/config.json`),f=window.monaco.editor.getModel(e);f&&f.dispose();let k=window.monaco.editor.getModel(i);k&&k.dispose();let R=window.monaco.editor.getModel(n);R&&R.dispose();let P=(window.monaco.languages.json.jsonDefaults.diagnosticsOptions.schemas||[]).filter(A=>A.uri!==`http://homebridge/config.json`);window.monaco.languages.json.jsonDefaults.setDiagnosticsOptions({validate:!0,allowComments:!1,schemas:P})}this.monacoEditor&&this.monacoEditor.dispose()}catch(e){}}validateSection(t,e){for(let i of t){if(typeof i!=`object`||i===null||Array.isArray(i))return this.$toastr.error(this.$translate.instant(`config.error_blocks_objects`,{type:e}),this.$translate.instant(`toast.title_error`)),this.highlightOffendingArrayItem(JSON.stringify(i)),!1;if(!(e in i))return this.$toastr.error(this.$translate.instant(`config.error_blocks_type`,{type:e}),this.$translate.instant(`toast.title_error`)),this.highlightOffendingArrayItem(JSON.stringify(i)),!1;if(typeof i[e]!=`string`)return this.$toastr.error(this.$translate.instant(`config.error_string_type`,{type:e}),this.$translate.instant(`toast.title_error`)),this.highlightOffendingArrayItem(JSON.stringify(i)),!1}return!0}validatePlugins(t,e){for(let i of t)if(typeof i!=`string`)return this.$toastr.error(this.$translate.instant(`config.error_string_array`,{key:e}),this.$translate.instant(`toast.title_error`)),!1;return!0}highlightOffendingArrayItem(t){this.isMonacoActive&&(t=JSON.stringify(t,null,4).split(`
`).map(e=>` ${e}`).join(`
`),requestAnimationFrame(()=>{let e=this.monacoEditor.getModel().findMatches(t);if(e.length){let i=e[0].range,n=new monaco.Range(i.startLineNumber,i.startColumn,i.endLineNumber,i.endColumn);this.editorDecorations=this.monacoEditor.deltaDecorations(this.editorDecorations,[{range:n,options:{isWholeLine:!0,linesDecorationsClassName:`hb-monaco-editor-line-error`}}])}}))}setMonacoEditorModel(){if(window.monaco.languages.json.jsonDefaults.diagnosticsOptions.schemas.some(i=>i.uri===`http://homebridge/config.json`))return;let t=monaco.Uri.parse(`a://homebridge/config.json`),e=qt$1(this.$translate,{isDebugModeEnabled:this.isDebugModeEnabled,isMatterSupported:this.isMatterSupported,isProtocolExternalsOnlyEnabled:this.isProtocolExternalsOnlyEnabled,isMatterDisableIpv4Enabled:this.isMatterDisableIpv4Enabled,isHapDisableIdentifyingMaterialEnabled:this.isHapDisableIdentifyingMaterialEnabled});window.monaco.languages.json.jsonDefaults.setDiagnosticsOptions({allowComments:!1,validate:!0,schemas:[{uri:`http://homebridge/config.json`,fileMatch:[t.toString()],schema:{type:`object`,additionalProperties:!1,required:[`bridge`],properties:{bridge:{type:`object`,additionalProperties:!1,required:[`name`,`username`,`port`,`pin`],properties:w({name:{type:`string`,title:this.$translate.instant(`settings.name`),description:`The Homebridge instance name.
This should be unique if you are running multiple instances of Homebridge.`,default:`Homebridge`},username:{type:`string`,title:this.$translate.instant(`users.label_username`),description:`Homebridge username must be 6 pairs of colon-separated hexadecimal characters (A-F 0-9).
You should change this pin if you need to re-pair your instance with HomeKit.
Example: 0E:89:49:64:91:86.`,default:`0E:89:49:64:91:86`,pattern:`^([A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}$`},port:{type:`number`,title:this.$translate.instant(`settings.network.port_hb`),description:`The port Homebridge listens on.
If running more than one instance of Homebridge on the same server make sure each instance is given a unique port.`,default:51173,minimum:1025,maximum:65534},pin:{type:`string`,description:`The Homebridge instance pin.
This is used when pairing Homebridge to HomeKit.
Example: 630-27-655.`,default:`630-27-655`,pattern:`^([0-9]{3}-[0-9]{2}-[0-9]{3})$`},manufacturer:{type:`string`,title:this.$translate.instant(`child_bridge.config.manufacturer`),description:`The bridge manufacturer to be displayed in HomeKit.`},firmwareRevision:{type:`string`,title:this.$translate.instant(`child_bridge.config.firmware`),description:`The bridge firmware version to be displayed in HomeKit.`},model:{type:`string`,title:this.$translate.instant(`child_bridge.config.model`),description:`The bridge model to be displayed in HomeKit.`},advertiser:{type:`string`,title:this.$translate.instant(`settings.mdns_advertiser`),description:this.$translate.instant(`settings.mdns_advertiser_help`),oneOf:[{title:`Avahi`,enum:[`avahi`]},{title:`Bonjour HAP`,enum:[`bonjour-hap`]},{title:`Ciao`,enum:[`ciao`]},{title:`Resolved`,enum:[`resolved`]}]},bind:{title:this.$translate.instant(`settings.network.title_network_interfaces`),description:`A string or an array of strings with the name(s) of the network interface(s) Homebridge should bind to.
Requires Homebridge v1.3 or later.`,type:[`string`,`array`],items:{type:`string`,description:this.$translate.instant(`status.widget.network.network_interface`)}},hap:Fe$1(this.$translate,this.isProtocolExternalsOnlyEnabled,`main`,this.isHapDisableIdentifyingMaterialEnabled)},this.isMatterSupported?{matter:ce$1(this.$translate,this.isProtocolExternalsOnlyEnabled,`main`,this.isMatterDisableIpv4Enabled)}:{}),default:{name:`Homebridge`,username:`0E:89:49:64:91:86`,port:51173,pin:`6302-7655`}},mdns:{type:`object`,additionalProperties:!1,properties:{interface:{type:`string`,title:this.$translate.instant(`status.widget.network.network_interface`),description:`The interface or IP address of the interface you want Homebridge to listen on.
This is useful if your server has multiple interfaces.
Deprecated as of Homebridge v1.3.0 - use bridge.bind instead.`},legacyAdvertiser:{type:`boolean`,title:`Legacy mDNS Advertiser`,description:`Set to false to use the new mdns library, ciao.`}},default:{legacyAdvertiser:!1}},ports:{type:`object`,additionalProperties:!1,title:`Port Range`,description:`The range of ports that should be used for external accessories like cameras and TVs.`,required:[`start`,`end`],properties:{start:{type:`number`,default:52100,minimum:1025,maximum:65534,title:this.$translate.instant(`settings.network.port_range`),description:this.$translate.instant(`settings.network.port_range_desc`)},end:{type:`number`,default:52150,minimum:1025,maximum:65534,title:this.$translate.instant(`settings.network.port_end`),description:this.$translate.instant(`settings.network.port_end_desc`)}},default:{start:52100,end:52150}},platforms:{type:`array`,title:`Platforms`,description:`Any plugin that exposes a platform should have its config entered in this array.
Separate each plugin config block using a comma.`,items:{type:`object`,required:[`platform`],anyOf:[{type:`object`,required:[`platform`],title:this.$translate.instant(`plugins.button_settings`),properties:{platform:{type:`string`,title:`Platform Name`,description:`This is used by Homebridge to identify which plugin this platform belongs to.`,not:{enum:[`config`]}},name:{type:`string`,title:this.$translate.instant(`accessories.name`),description:`The name of the platform.`},_bridge:e}},{type:`object`,additionalProperties:!1,properties:{platform:{type:`string`,title:`Platform Name`,description:`Homebridge UI platform name must be set to "config".
Do not change!`,const:`config`},name:{title:this.$translate.instant(`accessories.name`),type:`string`,default:`Homebridge UI`,minLength:1,description:`The name of the Homebridge instance.`},port:{title:this.$translate.instant(`settings.network.port_ui`),type:`integer`,default:8080,minimum:1025,maximum:65535,description:this.$translate.instant(`settings.network.port_ui_desc`)},auth:{type:`string`,default:`form`,title:this.$translate.instant(`settings.security.auth`),description:this.$translate.instant(`settings.security.auth_desc`),oneOf:[{title:`Require Authentication`,enum:[`form`]},{title:`None`,enum:[`none`]}]},theme:{title:this.$translate.instant(`settings.display.theme`),description:`The theme used for the UI.`,type:`string`,default:`orange`,oneOf:[{title:this.$translate.instant(`settings.display.orange`),enum:[`orange`]},{title:this.$translate.instant(`settings.display.red`),enum:[`red`]},{title:this.$translate.instant(`settings.display.pink`),enum:[`pink`]},{title:this.$translate.instant(`settings.display.purple`),enum:[`purple`]},{title:this.$translate.instant(`settings.display.deep_purple`),enum:[`deep-purple`]},{title:this.$translate.instant(`settings.display.indigo`),enum:[`indigo`]},{title:this.$translate.instant(`settings.display.blue`),enum:[`blue`]},{title:this.$translate.instant(`settings.display.bluegrey`),enum:[`blue-grey`]},{title:this.$translate.instant(`settings.display.cyan`),enum:[`cyan`]},{title:this.$translate.instant(`settings.display.green`),enum:[`green`]},{title:this.$translate.instant(`settings.display.teal`),enum:[`teal`]},{title:this.$translate.instant(`settings.display.grey`),enum:[`grey`]},{title:this.$translate.instant(`settings.display.brown`),enum:[`brown`]}]},lightingMode:{title:this.$translate.instant(`settings.display.lighting_mode`),description:`The lighting mode used for the UI.`,type:`string`,default:`auto`,oneOf:[{title:this.$translate.instant(`accessories.control.auto`),enum:[`auto`]},{title:this.$translate.instant(`settings.display.light`),enum:[`light`]},{title:this.$translate.instant(`settings.display.dark`),enum:[`dark`]}]},menuMode:{title:this.$translate.instant(`settings.display.menu_mode`),description:`Modes for the UI side menu.`,type:`string`,default:`default`,oneOf:[{title:this.$translate.instant(`settings.display.menu_default`),enum:[`default`]},{title:this.$translate.instant(`settings.display.menu_freeze`),enum:[`freeze`]}]},temp:{title:this.$translate.instant(`settings.linux.temp`),type:`string`,description:this.$translate.instant(`settings.linux.temp_desc`)},tempUnits:{title:this.$translate.instant(`settings.display.temp_units`),description:`The units used to display the temperature.`,type:`string`,default:`c`,oneOf:[{title:this.$translate.instant(`settings.display.temp_units.c`),enum:[`c`]},{title:this.$translate.instant(`settings.display.temp_units.f`),enum:[`f`]}]},lang:{title:this.$translate.instant(`settings.display.lang`),type:`string`,default:`auto`,description:`The language used for the UI.`,oneOf:[{title:this.$translate.instant(`form.select.auto`),enum:[`auto`]},{title:`Bulgarian (bg)`,enum:[`bg`]},{title:`Catalan (ca)`,enum:[`ca`]},{title:`Chinese - Simplified (zh-CN)`,enum:[`zh-CN`]},{title:`Chinese - Traditional (zh-TW)`,enum:[`zh-TW`]},{title:`Czech (cs)`,enum:[`cs`]},{title:`Dutch (nl)`,enum:[`nl`]},{title:`English (en)`,enum:[`en`]},{title:`Finnish (fi)`,enum:[`fi`]},{title:`French (fr)`,enum:[`fr`]},{title:`German (de)`,enum:[`de`]},{title:`Hebrew (he)`,enum:[`he`]},{title:`Hungarian (hu)`,enum:[`hu`]},{title:`Indonesian (id)`,enum:[`id`]},{title:`Italian (it)`,enum:[`it`]},{title:`Japanese (ja)`,enum:[`ja`]},{title:`Korean (ko)`,enum:[`ko`]},{title:`Macedonian (mk)`,enum:[`mk`]},{title:`Norwegian (no)`,enum:[`no`]},{title:`Polish (pl)`,enum:[`pl`]},{title:`Portuguese (Brazil)`,enum:[`pt-BR`]},{title:`Portuguese (Portugal)`,enum:[`pt`]},{title:`Russian (ru)`,enum:[`ru`]},{title:`Slovenian (sl)`,enum:[`sl`]},{title:`Spanish (es)`,enum:[`es`]},{title:`Swedish (sv)`,enum:[`sv`]},{title:`Thai (th)`,enum:[`th`]},{title:`Turkish (tr)`,enum:[`tr`]},{title:`Ukrainian (uk)`,enum:[`uk`]}]},wallpaper:{title:this.$translate.instant(`settings.display.wallpaper`),description:`The full path to the .jpg file.`,type:`string`},homebridgePackagePath:{title:this.$translate.instant(`settings.network.hb_package`),type:`string`,description:this.$translate.instant(`settings.network.hb_package_desc`)},host:{type:`string`,pattern:`^[^{}/ :\\\\]+(?::\\d+)?$`,title:this.$translate.instant(`settings.network.host`),description:this.$translate.instant(`settings.network.host_desc`)},sessionTimeoutInactivityBased:{type:`boolean`,title:this.$translate.instant(`settings.startup.session_inactivity_based`),description:this.$translate.instant(`settings.startup.session_inactivity_based_desc`)},sessionTimeout:{type:`integer`,minimum:600,maximum:864e5,title:this.$translate.instant(`settings.startup.session`),description:this.$translate.instant(`settings.startup.session_desc`)},log:{type:`object`,additionalProperties:!1,title:`Log Settings`,description:`The log settings for the Homebridge UI.`,properties:{maxSize:{type:`integer`,title:this.$translate.instant(`settings.terminal.log_max`),description:this.$translate.instant(`settings.terminal.log_max_desc`),minimum:-1},truncateSize:{type:`integer`,title:this.$translate.instant(`settings.terminal.log_truncate`),description:this.$translate.instant(`settings.terminal.log_truncate_desc`),minimum:0}}},ssl:{type:`object`,additionalProperties:!1,title:this.$translate.instant(`settings.security.https`),description:this.$translate.instant(`settings.security.https_desc`),properties:{key:{type:`string`,title:this.$translate.instant(`settings.security.key`),description:`The full path to the private key file.`},cert:{type:`string`,title:this.$translate.instant(`settings.security.cert`),description:`The full path to the certificate file.`},pfx:{title:this.$translate.instant(`settings.security.pfx`),type:`string`,description:`The full path to the PKCS#12 certificate file.`},passphrase:{title:this.$translate.instant(`settings.security.pass`),type:`string`,description:`The passphrase for the PKCS#12 certificate file.`}}},accessoryControl:{title:`Accessory Control Setup`,type:`object`,additionalProperties:!1,description:`The accessory control settings for the Homebridge UI.`,properties:{debug:{title:this.$translate.instant(`settings.accessory.debug`),type:`boolean`,description:this.$translate.instant(`settings.accessory.debug_desc`)},instanceBlacklist:{title:this.$translate.instant(`settings.security.ui_control`),type:`array`,description:this.$translate.instant(`settings.security.ui_control_desc`),items:{title:this.$translate.instant(`users.label_username`),type:`string`,pattern:`^([A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}$`}}}},linux:{title:`Linux Server Commands`,type:`object`,additionalProperties:!1,description:`The Linux server commands for the Homebridge UI.`,properties:{shutdown:{title:this.$translate.instant(`settings.linux.shutdown`),type:`string`,description:this.$translate.instant(`settings.linux.shutdown_desc`)},restart:{title:this.$translate.instant(`settings.linux.restart`),type:`string`,description:this.$translate.instant(`settings.linux.restart_desc`)}}},proxyHost:{title:this.$translate.instant(`settings.network.proxy`),type:`string`,pattern:`^[^{}/ :\\\\]+(?::\\d+)?$`,description:this.$translate.instant(`settings.network.proxy_desc`)},scheduledBackupPath:{title:this.$translate.instant(`backup.settings_path`),description:`The full path to where the service should save daily scheduled backups archives.`,type:`string`},scheduledBackupDisable:{title:`Disable Scheduled Backups`,type:`boolean`,description:`When enabled, the Homebridge UI will not create daily scheduled backups.`},scheduledRestartCron:{type:`string`,title:this.$translate.instant(`settings.startup.scheduled_restart`),description:this.$translate.instant(`settings.startup.scheduled_restart_desc`)},disableServerMetricsMonitoring:{title:`Disable Server Metrics Monitoring`,type:`boolean`,description:`When enabled, the Homebridge UI will not collect or report CPU or memory stats.`},enableMdnsAdvertise:{title:this.$translate.instant(`settings.network.mdns_advertise`),type:`boolean`,description:this.$translate.instant(`settings.network.mdns_advertise_help`)},plugins:{title:this.$translate.instant(`menu.label_plugins`),type:`object`,additionalProperties:!1,description:`Settings surrounding plugins that are used by the Homebridge UI.`,properties:{hideUpdatesFor:{type:`array`,title:this.$translate.instant(`config.hide_plugin_updates`),description:`A list of plugin names for which frontend update notifications will be hidden.`,items:{type:`string`,title:this.$translate.instant(`accessories.plugin`),pattern:`^(?:@[\\w-]+(?:\\.[\\w-]+)*/)?homebridge-[\\w-]+$`}},showBetasFor:{type:`array`,title:`Prefer Beta Versions For`,description:`A list of plugin names that should prefer beta releases.`,items:{type:`string`,title:this.$translate.instant(`accessories.plugin`),pattern:`^(?:@[\\w-]+(?:\\.[\\w-]+)*/)?homebridge-[\\w-]+$`}},hideChildBridgeSetupFor:{type:`array`,title:this.$translate.instant(`config.hide_child_bridge_setup`),description:`A list of plugin names for which the "set up child bridge" recommendation icon will be hidden.`,items:{type:`string`,title:this.$translate.instant(`accessories.plugin`),pattern:`^(?:@[\\w-]+(?:\\.[\\w-]+)*/)?homebridge-[\\w-]+$`}}}},nodeUpdatePolicy:{type:`string`,title:`${this.$translate.instant(`plugins.manage.notifications`)} (Node.js)`,description:this.$translate.instant(`plugins.manage.notifications_desc`,{pluginName:`Node.js`}),default:`all`,enum:[`all`,`major`,`none`],oneOf:[{title:this.$translate.instant(`plugins.manage.notifications_all`),description:this.$translate.instant(`plugins.manage.notifications_all_desc_for`,{pluginName:`Node.js`}),const:`all`},{title:this.$translate.instant(`plugins.manage.notifications_major`),description:this.$translate.instant(`plugins.manage.notifications_major_desc_for`,{pluginName:`Node.js`}),const:`major`},{title:this.$translate.instant(`plugins.manage.notifications_none`),description:this.$translate.instant(`plugins.manage.notifications_none_desc_for`,{pluginName:`Node.js`}),const:`none`}]},homebridgeUpdatePolicy:{type:`string`,title:`${this.$translate.instant(`plugins.manage.notifications`)} (Homebridge)`,description:this.$translate.instant(`plugins.manage.notifications_desc`,{pluginName:`Homebridge`}),default:`all`,enum:[`all`,`beta`,`major`,`none`],oneOf:[{title:this.$translate.instant(`plugins.manage.notifications_all`),description:this.$translate.instant(`plugins.manage.notifications_all_desc_for`,{pluginName:`Homebridge`}),const:`all`},{title:this.$translate.instant(`plugins.manage.notifications_beta`),description:this.$translate.instant(`plugins.manage.notifications_beta_desc_for`,{pluginName:`Homebridge`}),const:`beta`},{title:this.$translate.instant(`plugins.manage.notifications_major`),description:this.$translate.instant(`plugins.manage.notifications_major_desc_for`,{pluginName:`Homebridge`}),const:`major`},{title:this.$translate.instant(`plugins.manage.notifications_none`),description:this.$translate.instant(`plugins.manage.notifications_none_desc_for`,{pluginName:`Homebridge`}),const:`none`}]},homebridgeUiUpdatePolicy:{type:`string`,title:`${this.$translate.instant(`plugins.manage.notifications`)} (Homebridge UI)`,description:this.$translate.instant(`plugins.manage.notifications_desc`,{pluginName:`Homebridge UI`}),default:`all`,enum:[`all`,`beta`,`major`,`none`],oneOf:[{title:this.$translate.instant(`plugins.manage.notifications_all`),description:this.$translate.instant(`plugins.manage.notifications_all_desc_for`,{pluginName:`Homebridge UI`}),const:`all`},{title:this.$translate.instant(`plugins.manage.notifications_beta`),description:this.$translate.instant(`plugins.manage.notifications_beta_desc_for`,{pluginName:`Homebridge UI`}),const:`beta`},{title:this.$translate.instant(`plugins.manage.notifications_major`),description:this.$translate.instant(`plugins.manage.notifications_major_desc_for`,{pluginName:`Homebridge UI`}),const:`major`},{title:this.$translate.instant(`plugins.manage.notifications_none`),description:this.$translate.instant(`plugins.manage.notifications_none_desc_for`,{pluginName:`Homebridge UI`}),const:`none`}]},bridges:{type:`array`,title:this.$translate.instant(`child_bridge.bridges`),description:`Settings surrounding bridges that are used by the Homebridge UI.`,items:{type:`object`,additionalProperties:!1,required:[`username`],properties:{username:{type:`string`,title:this.$translate.instant(`users.label_username`),description:`The MAC address of the bridge (e.g., "0E:02:9A:9D:44:45").`,pattern:`^[0-9A-F]{2}(?::[0-9A-F]{2}){5}$`},hideHapAlert:{type:`boolean`,title:this.$translate.instant(`config.hide_hap_pairing`),description:`Hide the HAP pairing alert for this bridge.`},hideMatterAlert:{type:`boolean`,title:this.$translate.instant(`config.hide_matter_pairing`),description:`Hide the Matter pairing alert for this bridge.`},scheduledRestartCron:{type:`string`,title:this.$translate.instant(`settings.startup.scheduled_restart`),description:this.$translate.instant(`settings.startup.scheduled_restart_desc`)}}}},terminal:{type:`object`,additionalProperties:!1,title:`Terminal Settings`,description:`The terminal settings for the Homebridge UI.`,properties:{persistence:{title:this.$translate.instant(`settings.terminal.persistence`),type:`boolean`,description:this.$translate.instant(`settings.terminal.persistence_help`),default:!1},hideWarning:{title:this.$translate.instant(`settings.terminal.warning`),type:`boolean`,description:this.$translate.instant(`settings.terminal.warning_help`),default:!1},bufferSize:{title:this.$translate.instant(`settings.terminal.buffer_size`),type:`integer`,description:this.$translate.instant(`settings.terminal.buffer_size_help`),default:5e4,minimum:0},fontSize:{title:this.$translate.instant(`settings.terminal.font_size`),type:[`string`,`number`],description:this.$translate.instant(`settings.terminal.font_size_desc`),default:13,minimum:10,maximum:20},fontWeight:{title:this.$translate.instant(`settings.terminal.font_weight`),type:[`string`,`number`],description:this.$translate.instant(`settings.terminal.font_weight_desc`),default:`400`,enum:[`100`,`200`,`300`,`400`,`500`,`600`,`700`,`800`,`900`,`bold`,`normal`]},lightingMode:{title:this.$translate.instant(`settings.display.lighting_mode`),type:`string`,description:this.$translate.instant(`settings.terminal.font_lighting_desc`),default:`dark`,enum:[`light`,`dark`]}}}}}]}},accessories:{type:`array`,title:this.$translate.instant(`menu.label_accessories`),description:`Any plugin that exposes an accessory should have its config entered in this array.
Separate each plugin config block using a comma.`,items:{type:`object`,required:[`accessory`,`name`],title:this.$translate.instant(`plugins.button_settings`),properties:{accessory:{type:`string`,title:this.$translate.instant(`child_bridge.config.accessory`),description:`This is used by Homebridge to identify which plugin this accessory belongs to.`},name:{type:`string`,title:this.$translate.instant(`accessories.name`),description:`The name of the accessory.`},_bridge:e}}},plugins:{type:`array`,title:this.$translate.instant(`menu.label_plugins`),description:`An array of plugins that should be selectively enabled.
Remove this array to enable all plugins.`,items:{type:`string`,title:this.$translate.instant(`accessories.plugin`),description:`The full plugin npm package name.
Example: homebridge-dummy.`},default:[`homebridge-config-ui-x`]},disabledPlugins:{type:`array`,description:`An array of plugins that should be disabled.
Requires Homebridge v1.3 or later.`,items:{type:`string`,title:this.$translate.instant(`accessories.plugin`),description:`The full plugin npm package name.
Example: homebridge-dummy.`},default:[]}}}}]}),this.monacoEditorModel.uri=monaco.Uri.parse(`a://homebridge/config.json`)}visualViewPortChanged(){this.lastHeight<window.visualViewport.height&&document.activeElement.blur(),window.visualViewport.height<window.innerHeight?(this.$md.enableTouchMove(),this.lastHeight=window.visualViewport.height):window.visualViewport.height===window.innerHeight&&(this.$md.disableTouchMove(),this.lastHeight=window.visualViewport.height)}saveConfig(t){return E(this,null,function*(){try{let e=yield this.$api.post(`/config-editor?include=restart-info`,t);this.homebridgeConfig.set(JSON.stringify(e.config,null,4)),this.isMonacoActive&&this.monacoEditor.getModel()?.setValue(this.homebridgeConfig()),yield this.detectSavesChangesForRestart(e.affectedBridges)}catch(e){console.error(e),this.$toastr.error(this.$translate.instant(`config.failed_to_save_config`),this.$translate.instant(`toast.title_error`))}})}validateArraysEqual(t,e){if(t.length!==e.length)return!1;let i=t.toSorted(),n=e.toSorted();return i.every((f,k)=>f===n[k])}removePlatformsAndAccessories(t){let f=t,{accessories:e,platforms:i}=f;return A(f,[`accessories`,`platforms`])}removeEmptyBridges(t){return t.filter(e=>e._bridge&&Object.keys(e._bridge).length>0).map(e=>e._bridge)}validateBridgesEqual(t,e){return t.length!==e.length?!1:t.every(i=>e.some(n=>Jf(i,n)))}detectConfigPlatformChanges(){try{let t=this.latestSavedConfig,e=JSON.parse(this.homebridgeConfig()),i=(t.platforms||[]).find(f=>f.platform===`config`),n=(e.platforms||[]).find(f=>f.platform===`config`);return!i&&n||i&&!n?!0:!i&&!n?!1:!Jf(i,n)}catch(t){return console.error(`Error detecting config platform changes:`,t),!1}}detectSavesChangesForRestart(t){return E(this,null,function*(){let e=yield this.determineRestartType(t);if(e===`full`){let i=this.detectConfigPlatformChanges();yield this.performFullRestart(i)}else e===`child`&&(yield this.performChildBridgeRestart());this.latestSavedConfig=JSON.parse(this.homebridgeConfig())})}determineRestartType(t){return E(this,null,function*(){if(this.hbPendingRestart)return`full`;let e=this.latestSavedConfig,i=JSON.stringify(e,null,4),n=JSON.parse(this.homebridgeConfig());if(i===this.homebridgeConfig()&&!this.childBridgesToRestart.length)return this.$toastr.info(this.$translate.instant(`config.no_restart`),this.$translate.instant(`config.config_saved`)),`none`;if(!this.validateArraysEqual(Object.keys(e),Object.keys(n))||[...n.platforms||[],...n.accessories||[]].every(c=>!c._bridge||!Object.keys(c._bridge).length))return`full`;if(!Jf(this.removePlatformsAndAccessories(e),this.removePlatformsAndAccessories(n)))return`full`;let P=e.platforms||[],A=n.platforms||[],zt=P.map(c=>c.platform),Lt=A.map(c=>c.platform);if(!this.validateArraysEqual(zt,Lt))return`full`;let J=e.accessories||[],K=n.accessories||[],Jt=J.map(c=>c.accessory),Kt=K.map(c=>c.accessory);if(!this.validateArraysEqual(Jt,Kt)||!this.validateBridgesEqual(this.removeEmptyBridges(P),this.removeEmptyBridges(A))||!this.validateBridgesEqual(this.removeEmptyBridges(J),this.removeEmptyBridges(K)))return`full`;let Z=P.filter(c=>!Jf(c,A.find(j=>j.platform===c.platform))),Wt=J.filter(c=>!Jf(c,K.find(j=>j.accessory===c.accessory))),tt=[...Z,...Wt];if(Z.some(c=>c.platform===`config`)||tt.some(c=>c.platform===`config`?!1:!c._bridge||Object.keys(c._bridge).length===0))return`full`;try{let c=t??(yield this.$childBridges.getAll());for(let j of tt){let et=j._bridge?.username?.toUpperCase();if(!et)return`full`;let I=c.find(({username:W})=>W===et);if(I)this.childBridgesToRestart.some(W=>W.username===I.username)||this.childBridgesToRestart.push({name:I.name,username:I.username,matterSerialNumber:I.matterSerialNumber});else return`full`}return`child`}catch(c){return console.error(`Error fetching child bridges:`,c),`full`}})}performChildBridgeRestart(){return E(this,null,function*(){if(!this.childBridgesToRestart.length){yield this.performFullRestart(!1);return}let t=uy([{provide:C,useValue:{bridges:this.childBridgesToRestart}}],this.injector),e=this.$modal.open(se$2,{size:`lg`,backdrop:`static`,injector:t});try{yield e.result,this.childBridgesToRestart=[]}catch(i){}})}performFullRestart(t){return E(this,null,function*(){t&&(yield this.$api.put(`/platform-tools/hb-service/set-full-service-restart-flag`,{}));let e=this.$modal.open(oe$1,{size:`lg`,backdrop:`static`});try{yield e.result,this.hbPendingRestart=!1,this.childBridgesToRestart=[]}catch(i){this.hbPendingRestart=!0}})}parseConfigFromEditor(){try{return JSON.parse(this.homebridgeConfig())}catch(t){let e=Q.default.parse(this.homebridgeConfig());return this.homebridgeConfig.set(JSON.stringify(e,null,4)),this.isMonacoActive&&this.monacoEditor.getModel().setValue(this.homebridgeConfig()),e}}static ɵfac=function(e){return new(e||s)};static ɵcmp=nc({type:s,selectors:[[`app-config-editor`]],decls:35,vars:42,consts:[[1,`flex-column`,`d-flex`,`align-items-stretch`,`h-100`],[1,`row`],[1,`col-6`],[1,`primary-text`,`m-0`],[1,`col-6`,`text-end`],[`ngbDropdown`,``,`placement`,`bottom-end`,1,`d-none`,`d-sm-inline-block`,`me-2`],[`id`,`hb-editor-mode-toggle`,`type`,`button`,`ngbDropdownToggle`,``,`container`,`body`,`placement`,`bottom`,`triggers`,`hover`,1,`btn`,`btn-elegant`,`my-0`,3,`openDelay`,`ngbTooltip`],[`aria-hidden`,`true`,1,`far`,`fa-pen-to-square`],[`ngbDropdownMenu`,``,`role`,`menu`],[`type`,`button`,`ngbDropdownItem`,``,`role`,`menuitemradio`,3,`click`],[1,`hb-editor-mode-check`],[`aria-hidden`,`true`,1,`fas`,`fa-check`,`primary-text`],[`type`,`button`,`container`,`body`,`placement`,`bottom`,`triggers`,`hover`,1,`btn`,`btn-danger`,`waves-effect`,`my-0`,`me-2`,3,`disabled`,`openDelay`,`ngbTooltip`],[`type`,`button`,`container`,`body`,`placement`,`bottom`,`triggers`,`hover`,1,`btn`,`btn-elegant`,`waves-effect`,`my-0`,`me-2`,3,`openDelay`,`ngbTooltip`],[`type`,`button`,`container`,`body`,`placement`,`bottom`,`triggers`,`hover`,1,`btn`,`btn-elegant`,`waves-effect`,`my-0`,`me-0`,3,`click`,`disabled`,`openDelay`,`ngbTooltip`],[`aria-hidden`,`true`,1,`fas`,`fa-floppy-disk`],[`aria-hidden`,`true`,1,`fas`,`fa-circle-notch`,`fa-spin`],[1,`flex-grow-1`,`h-100`,`w-100`,`mt-3`,`mb-0`,3,`options`,`model`],[1,`flex-grow-1`,`h-100`,`w-100`,`mt-3`,`mb-0`,3,`options`,`originalModel`,`modifiedModel`],[`wrap`,`off`,`autocomplete`,`off`,`autocorrect`,`off`,`autocapitalize`,`off`,`spellcheck`,`false`,1,`hb-plain-text-editor`,`align-self-end`,`h-100`,`w-100`,`my-3`,3,`ngModel`],[`type`,`button`,`container`,`body`,`placement`,`bottom`,`triggers`,`hover`,1,`btn`,`btn-danger`,`waves-effect`,`my-0`,`me-2`,3,`click`,`disabled`,`openDelay`,`ngbTooltip`],[`aria-hidden`,`true`,1,`fas`,`fa-times`],[`type`,`button`,`container`,`body`,`placement`,`bottom`,`triggers`,`hover`,1,`btn`,`btn-elegant`,`waves-effect`,`my-0`,`me-2`,3,`click`,`openDelay`,`ngbTooltip`],[`aria-hidden`,`true`,1,`fas`,`fa-history`],[`aria-hidden`,`true`,1,`fas`],[1,`flex-grow-1`,`h-100`,`w-100`,`mt-3`,`mb-0`,3,`onInit`,`keydown.control.s`,`keydown.meta.s`,`options`,`model`],[1,`flex-grow-1`,`h-100`,`w-100`,`mt-3`,`mb-0`,3,`onInit`,`keydown.control.s`,`keydown.meta.s`,`options`,`originalModel`,`modifiedModel`],[`wrap`,`off`,`autocomplete`,`off`,`autocorrect`,`off`,`autocapitalize`,`off`,`spellcheck`,`false`,1,`hb-plain-text-editor`,`align-self-end`,`h-100`,`w-100`,`my-3`,3,`ngModelChange`,`ngModel`]],template:function(e,i){e&1&&(Va(0,`div`,0)(1,`div`,1)(2,`div`,2)(3,`h3`,3),Ot(4),S_(5,`translate`),jd()(),Va(6,`div`,4)(7,`div`,5)(8,`button`,6),S_(9,`translate`),S_(10,`translate`),Dy(11,`i`,7),jd(),Va(12,`div`,8),S_(13,`translate`),Va(14,`button`,9),ac(`click`,function(){return i.setPlainTextEditor(!1)}),Va(15,`span`,10),Fe(16,ee,1,0,`i`,11),jd(),Ot(17),S_(18,`translate`),jd(),Va(19,`button`,9),ac(`click`,function(){return i.setPlainTextEditor(!0)}),Va(20,`span`,10),Fe(21,ie,1,0,`i`,11),jd(),Ot(22),S_(23,`translate`),jd()()(),Fe(24,ne,4,8,`button`,12)(25,se,4,7,`button`,13),Fe(26,oe,4,11,`button`,13),Va(27,`button`,14),S_(28,`translate`),S_(29,`translate`),ac(`click`,function(){return i.onSave()}),Fe(30,re,1,0,`i`,15)(31,ae,1,0,`i`,16),jd()()(),Fe(32,le,1,2,`ngx-monaco-editor`,17),Fe(33,de,1,3,`ngx-monaco-diff-editor`,18),Fe(34,ce,3,4,`textarea`,19),jd()),e&2&&(se$1(4),Py(N_(5,26,`menu.config_json_editor`)),se$1(4),vy(`openDelay`,150)(`ngbTooltip`,N_(9,28,`config.editor_mode`)),Cr(`aria-label`,N_(10,30,`config.editor_mode`)),se$1(4),Cr(`aria-label`,N_(13,32,`config.editor_mode`))(`aria-labelledby`,`hb-editor-mode-toggle`),se$1(2),Ay(`active`,!i.preferPlainTextEditor()),Cr(`aria-checked`,!i.preferPlainTextEditor()),se$1(2),Le(i.preferPlainTextEditor()?-1:16),se$1(),kt(` `,N_(18,34,`config.editor_mode_default`),` `),se$1(2),Ay(`active`,i.preferPlainTextEditor()),Cr(`aria-checked`,i.preferPlainTextEditor()),se$1(2),Le(i.preferPlainTextEditor()?21:-1),se$1(),kt(` `,N_(23,36,`config.editor_mode_plain`),` `),se$1(2),Le(i.originalConfig()?24:25),se$1(2),Le(!i.isMobile()&&i.originalConfig()?26:-1),se$1(),vy(`disabled`,i.saveInProgress())(`openDelay`,150)(`ngbTooltip`,N_(28,38,`form.button_save`)),Cr(`aria-label`,N_(29,40,`form.button_save`)),se$1(3),Le(i.saveInProgress()?31:30),se$1(2),Le(!i.preferPlainTextEditor()&&!i.isMobile()&&!i.originalConfig()?32:-1),se$1(),Le(!i.preferPlainTextEditor()&&!i.isMobile()&&i.originalConfig()?33:-1),se$1(),Le(i.preferPlainTextEditor()||i.isMobile()?34:-1))},dependencies:[U,re$1,$,Q$1,Y,k,B,Kn,Ye,Hn,ln,v3],encapsulation:2})}return s})();export{ei as ConfigEditorComponent};