File: /volume1/@appstore/ContainerManager/ui/docker.js
/* Copyright (c) 2025 Synology Inc. All rights reserved. */
Ext.ns("SYNO.SDS.Docker.Utils");SYNO.SDS.Docker.Utils.Helper={containerNameRegex:/^[a-zA-Z0-9][a-zA-Z0-9_.-]+$/,containerNameValidator:function(b){var a=SYNO.SDS.Docker.Utils.Helper;if(b.length>=2&&b.length<=64&&b.match(a.containerNameRegex)){return true}return a.T("common","alphanumeric")},repositoryNameValidator:function(a){if(a.length>=2&&a.length<=63&&a.match(/^[a-zA-Z0-9]([a-zA-Z0-9._-]*\/)?[a-zA-Z0-9._-]+$/)){return true}return SYNO.SDS.Docker.Utils.Helper.T("common","image_repository_naming_spec")},tagNameValidator:function(a){if(a.length>=2&&a.length<=64&&a.match(/^[a-zA-Z0-9][a-zA-Z0-9._-]+$/)){return true}return SYNO.SDS.Docker.Utils.Helper.T("common","repository_tag_naming_spec")},networkNameValidator:function(a){if(a.match(/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/)){return true}return SYNO.SDS.Docker.Utils.Helper.T("network","naming_rule")},networkIpv4CIDRValidator:function(a){if(a===""){return true}if(a.match(/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$/)){return true}return SYNO.SDS.Docker.Utils.Helper.T("network","ipv4_cidr_rule")},networkIpv6CIDRValidator:function(a){if(a===""){return true}if(a.match(/^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$/)){return true}return SYNO.SDS.Docker.Utils.Helper.T("network","ipv6_cidr_rule")},T:function(c,a){try{return(_TT("SYNO.SDS.ContainerManager.Application",c,a)||_T(c,a)||c+":"+a)}catch(b){return _T(c,a)}},getRealMemory:function(){var a=_D("mem_default_mb");SYNO.API.Request({api:"SYNO.Core.System",method:"info",version:1,callback:function(c,b){if(c){a=b.ram_size}}});return function(){return a}}(),getErrorTemplate:function(a){return this.errorMapping[a]||this.T("error","error_error_system")},logError:function(a){this.getError.apply(this,arguments)},getError:function(d){var c=this.getErrorTemplate(d),a=[c].concat(Array.prototype.slice.call(arguments,1)),b=String.format.apply(null,a);SYNO.Debug("error[",d,"]: ",b);return b},mask:function(a,b){if(undefined!==b){a.getEl().mask(b,"syno-ux-mask-info")}else{a.getEl().mask()}},maskLoading:function(a){a.getEl().mask(_T("common","loading"),"x-mask-loading")},maskLoadingOnce:function(b,a){if(a.maskLoaded===undefined){this.maskLoading(b);a.maskLoaded=true}},unmask:function(a){a.getEl().unmask()},relativeTime:function(c){var b=new Date(c),a=new Date();if(a<b){c=a.getTime()-1}return Ext.util.Format.relativeTime(c)},getContainerUpTimeStr:function(b){var d=Math.round((new Date()).getTime()/1000)-b,a,c;if(3600>d){d=(60>d)?60:d;a=Math.floor(d/60);c=String.format("Up for {0} min{1}",a,(1<a)?"s":"")}else{if(86400>d){a=Math.floor(d/3600);c=String.format("Up for {0} hour{1}",a,(1<a)?"s":"")}else{a=Math.floor(d/86400);c=String.format("Up for {0} day{1}",a,(1<a)?"s":"")}}return c},shortFileSize:function(b,a){a=a||false;if(a){if(b<1000){return b+" B"}else{if(b<1000000){return(Math.round(b/1000))+" KB"}else{if(b<1000000000){return(Math.round(b/1000000))+" MB"}else{if(b<1000000000000){return(Math.round(b/1000000000))+" GB"}else{if(b<1000000000000000){return(Math.round(b/1000000000000))+" TB"}else{return(Math.round(b/1000000000000000))+" PB"}}}}}}else{if(b<1024){return b+" B"}else{if(b<1048576){return(Math.round(((b*10)/1024))/10)+" KB"}else{if(b<1073741824){return Math.round(((b)/1048576))+" MB"}else{if(b<1099511627776){return(Math.round(((b*100)/1073741824))/100)+" GB"}else{if(b<1125899906842624){return(Math.round(((b*100)/1099511627776))/100)+" TB"}else{return(Math.round(((b*100)/1125899906842624))/100)+" PB"}}}}}}},shortNum:function(a){if(a<1000){return a}else{if(a<1000000){return(Math.round(a/1000))+"K"}else{if(a<1000000000){return(Math.round(a/1000000))+"M"}else{if(a<1000000000000){return(Math.round(a/1000000000))+"G"}else{if(a<1000000000000000){return(Math.round(a/1000000000000))+"T"}else{return(Math.round(a/1000000000000000))+"P"}}}}}},getUniqArray:function(a){return a.filter(function(d,c,b){return b.indexOf(d)===c})},resizePanel:function(b,e){var d=240;var a=e?40:33;var c=d;var f=a;if(e){b.container.setStyle("padding","0 0 0 0")}else{b.container.setStyle("padding","16px 16px 0 16px");c+=32;f+=32}b.container.setSize(b.appWin.getWidth()-d,b.appWin.getHeight()-a);b.setSize(b.appWin.getWidth()-c,b.appWin.getHeight()-f);b.doLayout()}};(function(){var a=function(b){return SYNO.SDS.Docker.Utils.Helper.T("error",b)};SYNO.SDS.Docker.Utils.Helper.errorMapping={WEBAPI_ERR_NOT_ALLOW_DEMO:116,116:SYNO.SDS.Docker.Utils.Helper.T("common","error_demo"),WEBAPI_ERR_DOCKER_FILE_EXIST:1000,1000:a("container_exist"),WEBAPI_ERR_CONTAINER_RUNNING:1001,1001:a("error_error_system"),WEBAPI_ERR_BROKEN_PROFILE:1002,1002:a("invalid_files_format"),WEBAPI_ERR_DOCKER_API_HELPER_FAIL:1003,1003:a("error_error_system"),WEBAPI_ERR_DOCKER_API_FAIL_LOG:1004,1004:a("docker_api_fail_log"),WEBAPI_ERR_ILLEGAL_FILE:1005,1005:a("invalid_files_format"),WEBAPI_ERR_LICENSE_API_TIMEOUT:1025,1025:a("ddsm_license_check_fail"),WEBAPI_ERR_LICENSE_API_BAD_URL:1026,1026:a("ddsm_license_check_fail"),WEBAPI_ERR_REGISTRY_GET_ERR:1050,1050:a("error_error_system"),WEBAPI_ERR_REGISTRY_MANAGER_FAIL:1051,1051:a("error_error_system"),WEBAPI_ERR_REGISTRY_REMOTE_FAIL:1052,1052:a("registry_remote_fail"),WEBAPI_ERR_REGISTRY_BAD_RESULT:1053,1053:a("registry_bad_result"),WEBAPI_DOCKER_SUCCESS:1200,1200:"",WEBAPI_ERR_DOCKER_BAD_PARAMETER:1201,1201:a("error_error_system"),WEBAPI_ERR_DOCKER_UNKOWN:1202,1202:a("error_error_system"),WEBAPI_ERR_CONTAINER_FAIL_ATTACH:1300,1300:a("error_error_system"),WEBAPI_ERR_CONTAINER_NOT_EXIST:1301,1301:a("container_not_exist"),WEBAPI_ERR_CONTAINER_CONFLICT:1302,1302:a("error_error_system"),WEBAPI_ERR_CONTAINER_PORT_CONFLICT:1303,1303:a("container_port_conflict"),WEBAPI_ERR_CONTAINER_BAD_CMD_PARAM:1304,1304:a("bad_cmd_param"),WEBAPI_ERR_CONTAINER_IMPORT_IMAGE_ONLY:1305,1305:a("error_error_system"),WEBAPI_ERR_CONTAINER_NAME_CONFLICT:1306,1306:a("container_name_conflict"),WEBAPI_ERR_CONTAINER_NO_CONNECTED_NETWORK:1307,1307:a("container_no_connected_network"),WEBAPI_ERR_CONTAINER_CIRCULAR_LINK:1308,1308:a("container_circular_link"),WEBAPI_ERR_CONTAINER_NONSUPPORTED_C2_BINDS:1309,1309:a("c2_share_volume_binds"),WEBAPI_ERR_CONTAINER_UNKNOWN_CAPABILITY:1310,1310:a("unknown_capability"),WEBAPI_ERR_IMAGE_CONFLICT:1400,1400:a("image_delete_depend_error"),WEBAPI_ERR_IMAGE_NOT_EXIST:1401,1401:a("image_not_exist"),WEBAPI_ERR_IMAGE_CREATE_PARSE_FAIL:1402,1402:a("invalid_files_format"),WEBAPI_ERR_IMAGE_LOAD_PARSE_FAIL:1403,1403:a("invalid_files_format"),WS_ERR_CLIENT_ATTACH:1500,1500:a("ws_client_attach"),WS_ERR_EXEC_END:1501,1501:a("ws_exec_end"),WS_ERR_UNKNOWN:1502,1502:a("ws_close"),WS_ATTACH_SUCC:1503,1503:"",WS_ATTACH_CLIENT:1504,1504:a("term_attach_fail"),WS_ATTACH_FAIL_TTY:1505,1505:a("term_attach_fail_tty"),WEBAPI_ERR_DDSM_IMPORTING:1600,1600:a("ddsm_importing"),WEBAPI_ERR_DDSM_UPDATING:1601,1601:a("ddsm_updating"),WEBAPI_ERR_DDSM_RESTORING:1602,1602:a("ddsm_restoring"),WEBAPI_ERR_DDSM_DOWNLOAD_FAIL:1610,1610:a("ddsm_download_failed"),WEBAPI_ERR_DDSM_NO_RELEASE:1611,1611:a("ddsm_no_release"),WEBAPI_ERR_DDSM_IMPORT_BAD_VERSION:1612,1612:a("ddsm_import_bad_version"),WEBAPI_ERR_DDSM_IMPORT_BAD_IMAGE:1613,1613:a("ddsm_import_bad_image"),WEBAPI_ERR_DDSM_IMPORT_WRONG_IMAGE:1614,1614:a("ddsm_import_wrong_image"),WEBAPI_ERR_DDSM_UPDATE_NO_TARGET:1615,1615:a("ddsm_update_no_target"),WEBAPI_ERR_DDSM_RESTORE_LOST_CONFIG:1616,1616:a("ddsm_restore_lost_config"),WEBAPI_ERR_DDSM_UPDATE_FAILED:1617,1617:a("ddsm_update_failed"),WEBAPI_ERR_DDSM_UPDATE_REQUIRED:1618,1618:a("ddsm_update_required"),WEBAPI_ERR_DDSM_INCOMPATIBLE_VERSION:1619,1619:a("ddsm_incompatible_version"),WEBAPI_ERR_DDSM_NETWORK_CHECK_FAIL:1650,1650:a("network_check_failed"),WEBAPI_ERR_DDSM_NETWORK_SETUP_FAIL:1651,1651:a("network_setup_failed"),WEBAPI_ERR_DDSM_NETWORK_IP_CONFLICT:1652,1652:_T("tcpip","tcpip_ip_used"),WEBAPI_ERR_DDSM_NETWORK_IFACE_ABNORMAL:1653,1653:a("network_interface_abnormal"),WEBAPI_ERR_DDSM_NETWORK_REQUIRE_OVS_MODE:1654,1654:a("require_ovs_network"),WEBAPI_ERR_DDSM_SHARE_NOT_EXIST:1700,1700:a("ddsm_share_not_exist"),WEBAPI_ERR_DDSM_SHARE_REQUIRE_BTRFS:1701,1701:a("ddsm_share_not_btrfs"),WEBAPI_ERR_DDSM_SHARE_ERROR_UNKNOW:1702,1702:a("ddsm_share_abnormal"),WEBAPI_ERR_DDSM_SHARE_ENCRYPTED:1703,1703:a("ddsm_share_encrypted"),WEBAPI_ERR_DDSM_LICENSE_LIMIT_REACHED:1720,1720:a("ddsm_license_limit_reached"),WEBAPI_ERR_NETWORK_NAME_CONFLCT:1800,1800:a("network_exist"),WEBAPI_ERR_NETWORK_CONNECT_DISCONNECT_FAIL:1801,1801:a("network_connect_disconnect_fail"),WEBAPI_ERR_NETWORK_CREATE_FAIL:1802,1802:a("network_create_fail"),WEBAPI_ERR_NETWORK_SUBNET4_DUPLICATE:1803,1803:a("network_ipv4_subnet_duplicate"),WEBAPI_ERR_NETWORK_SUBNET6_DUPLICATE:1804,1804:a("network_ipv6_subnet_duplicate"),WEBAPI_ERR_NETWORK_GATEWAY4_DUPLICATE:1805,1805:a("network_ipv4_gateway_duplicate"),WEBAPI_ERR_NETWORK_GATEWAY6_DUPLICATE:1806,1806:a("network_ipv6_gateway_duplicate"),WEBAPI_ERR_NETWORK_GATEWAY4_OUTOFRANGE:1807,1807:a("network_ipv4_gateway_outofrange"),WEBAPI_ERR_NETWORK_GATEWAY6_OUTOFRANGE:1808,1808:a("network_ipv6_gateway_outofrange"),WEBAPI_ERR_NETWORK_SUBNET_OVERLAP:1809,1809:a("network_subnet_overlap"),WEBAPI_CORE_ERR_SHARE_SPACE_NOT_ENOUGH:3320,3320:a("space_not_enough")}})();Ext.define("SYNO.SDS.Docker.Registry.TagDialog",{extend:"SYNO.SDS.ModalWindow",helper:SYNO.SDS.Docker.Utils.Helper,constructor:function(a){this.callParent([this.fillConfig(a)])},fillConfig:function(a){this.store=this.createTagStore(a);this.formPanel=this.createFormPanel(a);var b={title:this.helper.T("registry","choose_tag"),width:450,height:170,buttons:[{xtype:"syno_button",text:this.helper.T("common","cancel"),scope:this,handler:this.onCancel},{xtype:"syno_button",btnStyle:"blue",text:this.helper.T("common","choose"),scope:this,handler:this.onChoose}],items:[this.formPanel],listeners:{scope:this,beforeshow:{single:true,fn:this.onBeforeShow}},scope:this};Ext.apply(b,a);return b},createTagStore:function(a){return new SYNO.API.JsonStore({appWindow:a.owner,autoDestroy:true,fields:[{name:"tag",mapping:"tag"}],api:"SYNO.Docker.Registry",method:"tags",version:1,scope:this,baseParams:a.query,timeout:5*60,listeners:{scope:this,load:this.onLoad,exception:this.onException}})},createFormPanel:function(a){return new SYNO.ux.FormPanel({padding:0,items:[{xtype:"syno_combobox",typeAhead:true,forceSelection:true,allowBlank:false,triggerAction:"all",displayField:"tag",name:"tag",store:this.store,fieldLabel:this.helper.T("registry","choose_tag_instruction")}]})},onChoose:function(a){this.chooseHandler.call(this.scope,this.query,this.formPanel.getForm().getValues().tag);this.close()},onCancel:function(a){this.close()},onBeforeShow:function(){this.store.load();return false},onLoad:function(a){if(this.owner._isVue?this.owner._isDestroyed:this.owner.isDestroyed){this.close();return}if(_S("demo_mode")){this.owner.getMsgBox().alert(this.helper.T("error","error_error"),this.helper.T("registry","demo_cannot_download"));this.close();return}if(this.store.data.length===0){this.owner.getMsgBox().alert(this.helper.T("error","error_error"),this.helper.T("error","image_no_tag"));this.close();return}this.formPanel.getForm().setValues(this.store.getAt(0).data);if(this.store.data.length===1){this.onChoose()}else{this.show()}},onException:function(d,a,e,b,c){if(true===c.isTimeout){this.owner.getMsgBox().alert("",this.helper.T("error","session_expired"))}else{this.owner.getMsgBox().alert(this.helper.T("error","error_error"),this.helper.getError(c.code))}this.close()}});Ext.define("SYNO.SDS.Docker.Utils.Socket",{extend:Object,constructor:function(b,a){if(a){this._socket=new WebSocket(b,a)}else{this._socket=new WebSocket(b)}this._handlers={};this._open=this._open.bind(this);this._message=this._message.bind(this);this._close=this._close.bind(this);this._socket.addEventListener("open",this._open);this._socket.addEventListener("message",this._message);this._socket.addEventListener("close",this._close);Object.defineProperties(this,{connecting:{get:function(){return this._socket.readyState===0}},connected:{get:function(){return this._socket.readyState===1}},disconnecting:{get:function(){return this._socket.readyState===2}},disconnected:{get:function(){return this._socket.readyState===3}}})},_open:function(a){this._apply("connect",[a])},_message:function(b){var a=JSON.parse(b.data);this._apply(a[0],a.slice(1))},_close:function(a){this._apply("disconnect",[a]);this._handlers=null;this._open=null;this._message=null;this._close=null},_apply:function(b,a){if(!this._handlers[b]){return}for(var c=0;c<this._handlers[b].length;++c){this._handlers[b][c].apply(this,a)}},on:function(a,b){if(!this._handlers[a]){this._handlers[a]=[]}this._handlers[a].push(b)},emit:function(){var a=Array.prototype.map.call(arguments,function(b){return b});if(this.connected){this._socket.send(Ext.encode(a))}},destroy:function(){this._socket.close()}});SYNO.SDS.Docker.Utils.Socket.browserSupported=function(){return typeof(window.WebSocket)!=="undefined"};Ext.define("SYNO.SDS.Docker.ContainerDetail.TermSocket",{extend:"SYNO.SDS.Docker.Utils.Socket",constructor:function(a){var b=(window.location.protocol==="http:")?"ws://":"wss://";this.callParent([[b,window.location.hostname,":",window.location.port,"/docker/ws"].join("")]);this.role=a?"monitor":"terminal"},enter:function(a){this.container=a;this.emit("enter",a,this.role)},attach:function(a,b){b=b||false;this.tty_id=a;this.emit("attach",this.tty_id,b)}});Ext.define("SYNO.SDS.Docker.ContainerDetail.Term",{extend:"SYNO.ux.Panel",helper:SYNO.SDS.Docker.Utils.Helper,constructor:function(a){this.callParent([this.fillConfig(a)])},fillConfig:function(a){this.socket=this.createSocket(a);this.term=this.createTerm();var b={cls:"syno-sds-docker-term",layout:"fit",items:[{xtype:"container",cls:"syno-sds-docker-term-outline",layout:"fit",items:[{type:"box",cls:"syno-sds-docker-term-wrapper selectabletext",listeners:{scope:this,afterrender:this.onAfterRender}}]}],listeners:{scope:this,activate:this.onActivate,beforedestroy:this.onBeforeDestroy}};Ext.apply(b,a);return b},createSocket:function(b){var a=new SYNO.SDS.Docker.ContainerDetail.TermSocket();a.on("connect",function(c){a.enter(b.container)}.bind(this));a.on("enter",function(c){if(c){a.attach(b.tty_id)}else{b.appWin.getMsgBox().alert("error",this.helper.T("error","term_enter_fail"))}}.bind(this));a.on("attach",function(c){switch(c){case SYNO.SDS.Docker.Utils.Helper.errorMapping.WS_ATTACH_SUCC:this.attached=true;a.emit("resize",this.term.rows,this.term.cols);break;case SYNO.SDS.Docker.Utils.Helper.errorMapping.WS_ATTACH_CLIENT:if(!b.appWin._isVue){b.appWin.getMsgBox().confirm("attach",this.helper.getError(c),function(d){if(d==="yes"){a.attach(b.tty_id,true)}else{this.closeByDetached=true;this.socketClosing=true;this.socket.destroy()}},this)}else{b.appWin.getMsgBox().confirm("",this.helper.getError(c)).then((function(d){if(d==="confirm"){a.attach(b.tty_id,true)}else{this.closeByDetached=true;this.socketClosing=true;this.socket.destroy()}}).bind(this))}break;case SYNO.SDS.Docker.Utils.Helper.errorMapping.WS_ATTACH_FAIL_TTY:b.appWin.getMsgBox().alert("error",this.helper.getError(c));this.socketClosing=true;this.socket.destroy();break}}.bind(this));a.on("data",function(c){this.term.write(c)}.bind(this));a.on("close",function(c){if(c===SYNO.SDS.Docker.Utils.Helper.errorMapping.WS_ERR_CLIENT_ATTACH){this.closeByDetached=true}if(c!==SYNO.SDS.Docker.Utils.Helper.errorMapping.WS_ERR_EXEC_END){b.appWin.getMsgBox().alert("error",this.helper.getError(c,Ext.util.Format.htmlEncode(this.name)))}this.socketClosing=true}.bind(this));a.on("disconnect",function(c){if(!this.isDestroyed&&!this.destroying&&!this.socketClosing){b.appWin.getMsgBox().alert("error",this.helper.T("error","ws_close"));this.helper.logError(c.code)}if(!this.isDestroyed&&!this.destroying){this.helper.mask(this)}this.socketClosing=false;this.attached=false;this.fireEvent("termclose",this)}.bind(this));return a},createTerm:function(a){var b=new Terminal({cols:80,rows:24,screenKeys:true,useFocus:true,cursorBlink:true});b.on("data",function(c){this.socket.emit("data",c)}.bind(this));return b},onAfterRender:function(){var a=this.items.items[0];var b=a.items.items[0];this.term.open(b.getEl().query(".x-panel-body")[0]);this.termOpened=true},onBeforeDestroy:function(){this.socket.destroy();this.term.destroy()},onActivate:function(){if(this.termOpened){this.term.element.focus()}},onResize:function(c,j){this.callParent(arguments);var d=5;var m=8;var i=16;var e=6+1;var f=1;var h=16;var a=16;var b=c-(d+e+f)*2-h;var k=j-(d+e+f)*2-a;var g=Math.floor(b/m);var l=Math.floor(k/i);this.term.resize(g,l);if(this.attached){this.socket.emit("resize",l,g)}}});Ext.define("SYNO.SDS.Docker.ContainerDetail.HotKeys",{extend:"SYNO.SDS.AppWindow",helper:SYNO.SDS.Docker.Utils.Helper,constructor:function(a){var b=this.fillConfig(a);this.callParent([b])},fillConfig:function(a){var b={width:520,height:740,minWidth:520,minHeight:200,constrainHeader:true,showHelp:false,minimizable:false,maximizable:false,title:this.helper.T("hotkey","title"),layout:"fit",items:[new SYNO.SDS.Docker.ContainerDetail.HotKeyForm({dialog:this})],buttons:[{text:_T("common","apply"),btnStyle:"blue",scope:this,handler:this.onClose}]};Ext.apply(b,a||{});return b},onClose:function(){this.hide();return false}});Ext.define("SYNO.SDS.Docker.ContainerDetail.HotKeyForm",{extend:"SYNO.SDS.Utils.FormPanel",helper:SYNO.SDS.Docker.Utils.Helper,constructor:function(b){var a={items:this.getItems()};this.callParent([Ext.apply(a,b)])},getItems:function(){return[{xtype:"syno_fieldset",title:this.helper.T("hotkey","prefix_mode"),items:[{xtype:"syno_displayfield",value:this.getPrefixTable(),htmlEncode:false}]},{xtype:"syno_fieldset",title:this.helper.T("hotkey","selection_mode"),items:[{xtype:"syno_displayfield",value:this.getSelectionTable(),htmlEncode:false}]},{xtype:"syno_fieldset",title:this.helper.T("hotkey","visual_mode"),items:[{xtype:"syno_displayfield",value:this.getVisualTable(),htmlEncode:false}]}]},getPrefixTable:function(){var a=['<table border="0" cellpadding="5" cellspacing="10" role="presentation">','<tr><td valign="left"><b>Ctrl + A</b></td><td>',String.format(this.helper.T("hotkey","cmd_ctrl_a"),"<b>"+this.helper.T("hotkey","prefix_mode")+"</b>"),"</td></tr>",'<tr><td valign="left"><b>Ctrl + C</b></td><td>',this.helper.T("hotkey","cmd_ctrl_c"),"</td></tr>",'<tr><td valign="left"><b>Ctrl + V</b></td><td>',this.helper.T("hotkey","cmd_ctrl_v"),"</td></tr>","</table>"];return a.join("")},getSelectionTable:function(){var a=['<table border="0" cellpadding="5" cellspacing="10" role="presentation">','<tr><td valign="left"><b>[</b></td><td>',String.format(this.helper.T("hotkey","cmd_open_bracket"),"<b>"+this.helper.T("hotkey","selection_mode")+"</b>","<b>"+this.helper.T("hotkey","prefix_mode")+"</b>"),"</td></tr>",'<tr><td valign="left"><b>/</b></td><td>',this.helper.T("hotkey","cmd_slash"),"</td></tr>",'<tr><td valign="left"><b>g</b></td><td>',this.helper.T("hotkey","cmd_g"),"</td></tr>",'<tr><td valign="left"><b>G</b></td><td>',this.helper.T("hotkey","cmd_capital_g"),"</td></tr>",'<tr><td valign="left"><b>0</b></td><td>',this.helper.T("hotkey","cmd_zero"),"</td></tr>",'<tr><td valign="left"><b>$</b></td><td>',this.helper.T("hotkey","cmd_dollar_sign"),"</td></tr>",'<tr><td valign="left"><b>w</b></td><td>',this.helper.T("hotkey","cmd_w"),"</td></tr>",'<tr><td valign="left"><b>b</b></td><td>',this.helper.T("hotkey","cmd_b"),"</td></tr>","</table>"];return a.join("")},getVisualTable:function(){var a=['<table border="0" cellpadding="5" cellspacing="10" role="presentation">','<tr><td valign="left"><b>v</b></td><td>',String.format(this.helper.T("hotkey","cmd_v"),"<b>"+this.helper.T("hotkey","visual_mode")+"</b>","<b>"+this.helper.T("hotkey","selection_mode")+"</b>"),"</td></tr>",'<tr><td valign="left"><b>hjkl</b></td><td>',String.format(this.helper.T("hotkey","cmd_hjkl"),"<b>"+this.helper.T("hotkey","visual_mode")+"</b>"),"</td></tr>","</table>"];return a.join("")}});Ext.define("SYNO.SDS.Docker.Utils.PromptDialog",{extend:"SYNO.SDS.ModalWindow",constructor:function(a){this.callParent([this.fillConfig(a)])},fillConfig:function(a){this.panel=this.initPanel(a);this.scope=a.scope||this;this.closeHandler=(a.closeHandler||Ext.emptyFn);this.okHandler=(a.okHandler||Ext.emptyFn);var b={owner:a.owner,width:450,height:180,shadow:true,minWidth:500,minHeight:150,collapsible:false,autoScroll:false,constrainHeader:true,title:a.title||"title",layout:"fit",items:[this.panel],buttons:[{text:_T("common","common_cancel"),scope:this,handler:this._closeHandler},{btnStyle:"blue",text:_T("common","common_submit"),scope:this,handler:this._okHandler}]};Ext.apply(b,a);return b},initPanel:function(a){var b={labelAlign:"top",border:false,items:[{xtype:"syno_textfield",itemId:"value",fieldLabel:a.textFieldLabel||"fieldLabel",name:"name",width:400,maxlength:255}]};return new Ext.form.FormPanel(b)},_okHandler:function(){this.okHandler.createDelegate(this.scope,[this.panel.form.findField("value").getValue()],false)();this.close()},_closeHandler:function(){this.closeHandler.createDelegate(this.scope)();this.close()}});Ext.define("SYNO.SDS.Docker.ContainerDetail.PanelTerm",{extend:"SYNO.ux.Panel",helper:SYNO.SDS.Docker.Utils.Helper,constructor:function(a){this.callParent([this.fillConfig(a)])},fillConfig:function(a){this.ttyList={};this.actionGroup=this.createActionGroup();this.toolBar=this.createTBar();this.termContainer=this.createTermContainer();this.treePanel=this.createTreePanel();this.socket=null;this.keyTable=null;var b={title:this.helper.T("container_detail","terminal"),tbar:this.toolBar,layout:"border",border:false,cls:"docker-container-term-panel",items:[this.treePanel,this.termContainer],listeners:{scope:this,containerchange:this.onContainerChange,infochange:this.onInfoChange,activate:this.onActivate,beforedestroy:this.onBeforeDestroy}};Ext.apply(b,a);return b},createTreePanel:function(){return new SYNO.ux.TreePanel({width:200,region:"west",bodyStyle:"padding: 0px 20px 0px 0px",border:false,collapsable:true,split:true,useArrows:true,rootVisible:false,root:new Ext.tree.TreeNode(),selModel:new Ext.tree.DefaultSelectionModel({listeners:{scope:this,selectionchange:{fn:this.onTermSelectChange,scope:this,buffer:100}}}),listeners:{scope:this,click:this.onTermClick}})},createActionGroup:function(){var a=new SYNO.ux.Menu({items:[{text:this.helper.T("container_detail","create_with_cmd"),scope:this,handler:this.onCreateTerm,itemId:"create_with_cmd"}]});return new SYNO.ux.Utils.ActionGroup([new SYNO.ux.SplitButton({text:this.helper.T("common","create"),scope:this,handler:this.doCreateTerm.bind(this,""),itemId:"create",menu:a}),new Ext.Action({itemId:"rename",text:this.helper.T("container_detail","rename"),scope:this,handler:this.onRename,disabled:true}),new Ext.Action({itemId:"delete",text:this.helper.T("common","delete"),scope:this,handler:this.onDeleteTerm,disabled:true}),"->",new Ext.Action({itemId:"hotkey",text:this.helper.T("hotkey","title"),scope:this,handler:this.onHotKey})])},createTBar:function(){return new SYNO.ux.Toolbar({defaultType:"syno_button",items:[this.actionGroup.getArray()]})},createMonitorSocket:function(){var a=new SYNO.SDS.Docker.ContainerDetail.TermSocket(true);a.on("connect",function(b){a.enter(this.appWin.getContainerName())}.bind(this));a.on("enter",function(b){if(!b){if(!this.owner._isVue){this.appWin.getMsgBox().alert("error",this.helper.T("error","term_enter_fail"))}else{this.owner.getMsgBox().alert("error",this.helper.T("error","term_enter_fail"))}}}.bind(this));a.on("list",function(d){for(var c=0;c<d.length;c+=2){this.ttyList[d[c]]=d[c+1]}var b=this.reloadTree();if(this.termContainer.items.length===0&&b.length>0){this.doRename(b[0],this.appWin.getContainerName());this.selectTerm(b[0])}}.bind(this));a.on("title",function(b,d){if(this.ttyList[b]){this.ttyList[b]=d;var c=this.termContainer.getComponent(b);if(c){c.name=d}this.reloadTree()}}.bind(this));a.on("disconnect",function(b){if(!this.isDestroyed&&!this.destroying&&!this.socketClosing){if(!this.owner._isVue){this.appWin.getMsgBox().alert("error",this.helper.T("error","ws_close"))}else{this.owner.getMsgBox().alert("error",this.helper.T("error","ws_close"))}this.helper.logError(b.code)}this.socketClosing=false}.bind(this));return a},createTermContainer:function(){return new SYNO.ux.Panel({region:"center",layout:"card",defaults:{border:false},listeners:{scope:this,afterrender:this.onTermAfterRender}})},resetPanel:function(){this.treePanel.setRootNode(new Ext.tree.TreeNode());this.ttyList={};this.termContainer.removeAll();if(this.socket){this.socketClosing=true;this.socket.destroy();this.socket=null}},selectTerm:function(a){var b=this.treePanel.root.findChild("id",a);if(!b){return}this.treePanel.selectPath(b.getPath())},openTerm:function(a){var b=new SYNO.SDS.Docker.ContainerDetail.Term({appWin:!this.owner._isVue?this.appWin:this.owner,container:this.appWin.getContainerName(),name:this.ttyList[a],tty_id:a,itemId:a});this.mon(b,"termclose",this.updateActionGroup,this);return b},reopenTerm:function(a){var c=this.termContainer.layout.activeItem;var b=this.termContainer.getComponent(a);if(b){this.termContainer.remove(b)}b=this.openTerm(a);this.termContainer.add(b);this.termContainer.doLayout();if(c){this.termContainer.layout.setActiveItem(c.tty_id)}},switchTerm:function(a){if(a===null){if(this.termContainer.layout.activeItem){this.termContainer.layout.activeItem.hide()}return}var b=this.termContainer.getComponent(a);if(!b){b=this.openTerm(a);this.termContainer.add(b);this.termContainer.doLayout()}this.termContainer.layout.setActiveItem(a);if(this.termContainer.layout.activeItem.hidden){this.termContainer.layout.activeItem.show()}},closeTerm:function(a){var b=this.termContainer.getComponent(a);if(!b){return}this.termContainer.remove(b);delete this.ttyList[a];this.reloadTree();this.selectTerm(this.appWin.getContainerName())},isNeedShowCloseConfirm:function(){if(!this.socket||this.treePanel.root.childNodes.length<2){return false}return true},closeAllTerm:function(){var a=this.appWin.getContainerName();Object.keys(this.ttyList).forEach(function(b){if(b===a){return}this.socket.emit("delete",b)},this)},reloadTree:function(){var e=this.treePanel.getSelectionModel().getSelectedNode();var b=this.appWin.getContainerName();var d=Object.keys(this.ttyList).sort(function(g,f){if(g===b){return -1}if(f===b){return 1}if(g<f){return -1}if(g>f){return 1}return 0});var c=d.map(function(f){return new Ext.tree.TreeNode({id:f,text:Ext.util.Format.htmlEncode(this.ttyList[f]),leaf:true})},this);var a=new Ext.tree.TreeNode({expanded:true});c.forEach(function(f){a.appendChild(f)});this.treePanel.setRootNode(a);if(e){this.selectTerm(e.id)}return d},updateActionGroup:function(){this.actionGroup.disable("rename");this.actionGroup.disable("delete");if(!this.termContainer.layout.activeItem){return}var a=this.termContainer.layout.activeItem;if(a.tty_id!==this.appWin.getContainerName()&&!a.closeByDetached){this.actionGroup.enable("delete")}if(a.socket.connecting||a.socket.connected){this.actionGroup.enable("rename")}if(!a.socket.connecting&&!a.socket.connected){this.actionGroup.enable("delete")}},isContainerChanged:function(){var a=this.containerName;this.containerName=this.appWin.getContainerName();return a!==this.containerName},onCreateTerm:function(){var a=new SYNO.SDS.Docker.Utils.PromptDialog({owner:!this.owner._isVue?this.appWin:this.owner,title:this.helper.T("container_detail","create_with_cmd"),textFieldLabel:this.helper.T("container_detail","term_command_no_colon"),scope:this,okHandler:this.doCreateTerm});a.show()},doCreateTerm:function(a){var b="/bin/bash";a=a||b;this.socket.emit("create",a)},onRename:function(){var b=this.treePanel.getSelectionModel().getSelectedNode();if(!b){return}var a=new SYNO.SDS.Docker.Utils.PromptDialog({owner:!this.owner._isVue?this.appWin:this.owner,title:this.helper.T("container_detail","rename"),textFieldLabel:this.helper.T("container_detail","terminal_title"),scope:this,okHandler:this.doRename.createDelegate(this,[b.id],0)});a.show()},onHotKey:function(){if(!this.keyTable){this.keyTable=new SYNO.SDS.Docker.ContainerDetail.HotKeys({appInstance:{getUserSettings:function(){},setUserSettings:function(){}}});this.keyTable.setTitle(this.helper.T("hotkey","title"))}this.keyTable.show()},doRename:function(b,a){this.socket.emit("title",b,a)},onDeleteTerm:function(){var b=this.treePanel.getSelectionModel().getSelectedNode();if(!b){return}var a=this.termContainer.getComponent(b.id);if(a&&!a.attached&&!a.closeByDetached){this.doDeleteTerm(b.id,true);return}var c=String.format(this.helper.T("container_detail","term_delete_confirm"),b.text);if(!this.owner._isVue){this.appWin.getMsgBox().confirm("Delete",c,function(d){if(d==="yes"){this.doDeleteTerm(b.id)}}.bind(this))}else{this.owner.getMsgBox().confirm("",c).then(function(d){if(d==="confirm"){this.doDeleteTerm(b.id)}}.bind(this))}},doDeleteTerm:function(a,b){if(!b){this.socket.emit("delete",a)}this.closeTerm(a)},onTermClick:function(b){var a=this.termContainer.getComponent(b.id);if(!a){return}if(a.closeByDetached){if(!this.owner._iVue){this.appWin.getMsgBox().confirm("reopen",this.helper.T("container_detail","term_reopen_confirm"),function(c){if(c==="yes"){this.reopenTerm(b.id)}},this)}else{this.owner.getMsgBox().confirm("reopen",this.helper.T("container_detail","term_reopen_confirm")).then(function(c){if(c==="confirm"){this.reopenTerm(b.id)}})}}},onTermSelectChange:function(){var a=this.treePanel.getSelectionModel().getSelectedNode();if(a===null){this.switchTerm(null)}else{this.switchTerm(a.id)}this.updateActionGroup()},onContainerChange:function(){if(!SYNO.SDS.Docker.Utils.Socket.browserSupported()){this.helper.mask(this,this.helper.T("container_detail","browser_not_supported_ws"));return}if(!this.owner.isRunning()){this.helper.mask(this,this.helper.T("container_detail","container_stopped"));return}this.helper.unmask(this);this.resetPanel();this.socket=this.createMonitorSocket()},onInfoChange:function(){if(!SYNO.SDS.Docker.Utils.Socket.browserSupported()){this.helper.mask(this,this.helper.T("container_detail","browser_not_supported_ws"));return}if(!this.owner.isRunning()){this.helper.mask(this,this.helper.T("container_detail","container_stopped"));this.resetPanel();return}this.helper.unmask(this);if(!this.socket){this.socket=this.createMonitorSocket()}},onActivate:function(){this.onInfoChange();if(this.isContainerChanged()){this.onContainerChange()}else{if(this.termContainer.layout.activeItem){this.termContainer.layout.activeItem.fireEvent("activate")}}},onBeforeDestroy:function(){if(this.socket){this.socket.destroy()}if(this.keyTable){this.keyTable.close()}},onTermAfterRender:function(){var a=this.termContainer.body.dom;a.addEventListener("keydown",function(b){b.stopPropagation()})}});Ext.define("SYNO.SDS.Docker.Utils.SearchField",{extend:"SYNO.ux.SearchField",filter:function(){var b=this.getValue();var a=this.baseParams||{};if(!this.store){return}if(this.localFilter===true){if(b){this.store.filter(this.localFilterField,b,true)}else{this.store.clearFilter(false)}return}Ext.apply(a,{start:0,limit:this.pageSize});if(b){a.action=this.queryAction;a[this.queryParam]=b}else{a.action=this.enumAction}this.store.load({params:a})}});Ext.namespace("SYNO.SDS.Docker.Utils");Ext.define("SYNO.SDS.Docker.Utils.FileChooser",{extend:"SYNO.SDS.Utils.FileChooser.Chooser",helper:SYNO.SDS.Docker.Utils.Helper,constructor:function(a){this.callParent([Ext.apply({minHeight:500,minWidth:700,scope:this,superuser:true,title:this.helper.T("common","choose_file"),treeFilter:function(c,b){if(b&&(b.spath==="/home")){return false}return true}},a)]);this.cardview=this.findBy(function(b){return b.getItemId()==="cardview"})[0];this.mon(this,"choose",this.onChoose,this)},initTreeConfig:function(a){var c=this.callParent([a]);var b=[];b.push({cls:"root_node",text:_T("filebrowser","filetable_upload"),draggable:false,allowDrop:false,expanded:false,allowChildren:false,expandable:false,leaf:true,id:"upload_from_computer"});c.root.attributes.children=b.concat(c.root.attributes.children);return c},onTreeSelectionChange:function(b,a){if("upload_from_computer"===a.id){this.cardview.layout.setActiveItem("form");return}this.cardview.layout.setActiveItem("grid");this.callParent(arguments)},initFormConfig:function(a){this.fileUploadButton=new SYNO.ux.FileButton({fieldLabel:this.helper.T("common","file"),name:"filename"});this.formpanel=new SYNO.SDS.Utils.FormPanel({itemId:"form",webapi:a.webapi.uploader,fileUpload:true,trackResetOnLoad:true,frame:false,border:false,labelWidth:125,style:{padding:"3px 10px 0px 16px"},items:[{xtype:"syno_fieldset",title:_T("itunes","itunes_path"),items:[this.fileUploadButton]}]});return this.formpanel},initGridConfig:function(a){var b=this.callParent([a]);var d=this.initFormConfig(a);var c={itemId:"cardview",layout:"card",region:"center",border:false,activeItem:0,items:[b,d]};return c},applyHandler:function(){if(this.grid.isVisible()){this.callParent(arguments);return}this.getProgressInstance();this.formpanel.getForm().submit({clientValidation:false,progress:this.onProgrss,scope:this,callback:this.onUploadCallback})},getProgressInstance:function(){if(!this.progress||!this.progress.isVisible()){this.progress=this.getMsgBox().progress("",this.helper.T("common","status_uploading"),"")}return this.progress},onProgress:function(a){},onChoose:function(b,a){b.close();this.sendWebAPI(Ext.apply({params:{path:a.path},scope:b,callback:b.onChooseCallback},b.webapi.chooser))},onUploadCallback:function(d,a,c,b){this.getProgressInstance().updateProgress(1);this.getProgressInstance().close();this.close();if(this.callback){this.callback.call(this.scope||{},d,a,c,b)}},onChooseCallback:function(d,a,c,b){if(this.callback){this.callback.call(this.scope,d,a,c,b)}}});Ext.define("SYNO.SDS.Docker.Utils.Shortcut",{extend:"Ext.util.Observable",helper:SYNO.SDS.Docker.Utils.Helper,clsName:"",constructor:function(a){Ext.apply(this,a);this.addEvents("exception")},getClsName:function(){return this.clsName},getInstanceAPI:function(a){return{}},getInstancesListAPI:function(){return{}},getIconitemsName:function(a){return""},getIconParam:function(a){return{}},getIconLaunchParms:function(a){return{}},getIconConfig:function(a,b){return{}},create:function(c,b){var d=this.getIconParam(c);var a=this.getIconConfig(c.name,d);Ext.apply(a,{launchParams:this.getIconLaunchParms(d)});Ext.apply(a,b);SYNO.SDS.Desktop.addLaunchItem(a,-1,{saveState:true})},createStatusShortcut:function(a){return this.create(a)},createUrlShortcut:function(b,a){return this.create(b,{type:"url",url:a})}});Ext.namespace("SYNO.SDS.Docker.Utils");SYNO.SDS.Docker.Utils.AliyunHub={shortname:"Aliyun Hub",domain:"dev.aliyun.com",linkUrl:"dev.aliyun.com/detail.html?&repoId=",repoDomainSuffix:"aliyuncs.com",isAliyunHubShortName:function(a){return this.shortname===a},isAliyunHub:function(a){return("https://"+this.domain)===a},isAliyunRelated:function(a){return(-1===a.indexOf(this.repoDomainSuffix))?false:true},toAliyunUrl:function(b){var a=b.split(this.repoDomainSuffix);return(this.domain+a[1])},formAliyunHubUrl:function(a){if(!a||0===a.length){return null}return String.format("https://{0}{1}",this.linkUrl,a)}};Ext.define("SYNO.SDS.Docker.Utils.WelcomeDialog",{extend:"SYNO.SDS.ModalWindow",helper:SYNO.SDS.Docker.Utils.Helper,constructor:function(a){this.callParent([this.fillConfig(a)]);this.mon(this,"beforeshow",this.onBeforeShow,this)},fillConfig:function(a){SYNO.Assert(a.userSettingKey!==undefined);this.userSettingKey="WelcomDialog-"+a.userSettingKey;var b={title:"",layout:"fit",width:550,height:350,useStatusBar:false,footerStyle:"padding: 0 0 20px 0",fbar:{buttonAlign:"center",items:[{xtype:"syno_button",text:this.helper.T("common","ok"),scope:this,handler:function(){this.close()}}]},items:[{xtype:"syno_panel",style:"padding: 16px 20px 0 20px",layout:"border",items:[{xtype:"syno_panel",region:"center",layout:"fit",items:a.items},{xtype:"syno_panel",region:"south",layout:"fit",height:40,items:[{xtype:"syno_checkbox",boxLabel:this.helper.T("common","dont_alert_again"),listeners:{scope:this,check:this.onChecked}}]}]}]};delete a.userSettingKey;delete a.items;Ext.apply(b,a);return b},onBeforeShow:function(){if(this.appWin.appInstance.getUserSettings(this.userSettingKey)){this.close.defer(100,this);return false}},onChecked:function(a,b){this.appWin.appInstance.setUserSettings(this.userSettingKey,b)}});Ext.define("SYNO.SDS.Docker.Utils.APILoadingDialog",{extend:"SYNO.SDS.ModalWindow",constructor:function(a){this.callParent([this.fillConfig(a)])},fillConfig:function(a){if(!a.APIRequest){SYNO.Debug("APILoadingDialog should specify monitoring APIRequest")}this.progressBar=this.createProgressBar();var b={title:"Loading",width:450,height:100,scope:this,fbar:new Ext.Toolbar({items:[{xtype:"syno_button",text:"Cancel",scope:this,handler:this.onCancel}],enableOverflow:false}),items:[this.progressBar]};Ext.apply(b,a);return b},createProgressBar:function(){return new Ext.ProgressBar({cls:"syno-sds-docker-waiting-progress",width:440,value:1})},onCancel:function(){Ext.Ajax.abort(this.APIRequest);if(Ext.isFunction(this.abortHandler)){this.abortHandler.call(this.scope,this.transaction)}this.close()}});Ext.namespace("SYNO.SDS.Docker.Utils");SYNO.SDS.Docker.Utils.DockerHub={domain:"registry.hub.docker.com",domainRegex:/^(https?:\/\/)?registry.hub.docker.com/,repoRegex:/^(https:\/\/registry.hub.docker.com)\/(?:[A-Za-z]\/)?([A-Za-z0-9_-]+\/[A-Za-z0-9_.-]+)\/?$/,shortname:"Docker Hub",isDockerHubShortName:function(a){return this.shortname===a},isDockerHub:function(a){return this.domainRegex.test(a)},formDockerHubUrl:function(a){var c=/^([^\/]*\/)?([^\/]*)$/;var b=c.exec(a);if(!b){return null}return String.format("https://{0}/{1}/{2}/",this.domain,(b[1])?"r":"_",(a))}};Ext.define("SYNO.SDS.Docker.Utils.PreserveStates",{extend:Object,constructor:function(a){Ext.apply(this,a);this.cachedStoreData={}},init:function(a){this.dataview=a;var b=a.store;this.cacheStoreData(b);a.mon(b,"load",this.onStoreLoad,this);a.mon(b,"update",this.onStoreUpdate,this)},onStoreLoad:function(a){a.each(function(b){b.states=b.states||{};b.states.isNew=this.isNew(b);b.states.oldRecord=this.cachedStoreData[b.id]?this.cachedStoreData[b.id].data:{}},this);this.cacheStoreData(a)},onStoreUpdate:function(c,a,b){if(b===Ext.data.Record.COMMIT){this.cachedStoreData[a.id]=a}},cacheStoreData:function(a){this.cachedStoreData={};a.each(function(b){this.cachedStoreData[b.id]=b},this)},isNew:function(a){return this.cachedStoreData[a.id]===undefined}});