Merge ~ack/maas:backport-pools-as-machines-tab into maas:2.4

Proposed by Alberto Donato
Status: Merged
Approved by: Alberto Donato
Approved revision: 7fd80d4e6d67141e22fe89dbb9a554d558761f16
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~ack/maas:backport-pools-as-machines-tab
Merge into: maas:2.4
Diff against target: 121 lines (+24/-17)
6 files modified
src/maasserver/static/js/angular/controllers/nodes_list.js (+2/-1)
src/maasserver/static/js/bundle/maas-min.js (+1/-1)
src/maasserver/static/js/bundle/maas-min.js.map (+1/-1)
src/maasserver/static/partials/nodes-list.html (+18/-3)
src/maasserver/templates/maasserver/base.html (+1/-4)
src/maasserver/templates/maasserver/index.html (+1/-7)
Reviewer Review Type Date Requested Status
Björn Tillenius Approve
MAAS Lander Approve
Review via email: mp+347258@code.launchpad.net

Commit message

backport 26b56f4a7 - LP: #1774024 - Top-level navigation for 'Pools' should be moved to 'Machines' tab

To post a comment you must log in.
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b backport-pools-as-machines-tab lp:~ack/maas/+git/maas into -b 2.4 lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 7fd80d4e6d67141e22fe89dbb9a554d558761f16

review: Approve
Revision history for this message
Björn Tillenius (bjornt) wrote :

Hmm. Did you regenerate maas-min.js? If this is to land with the lander, i guess it doesn't matter. But if we manually fast-forward it, we will have to regenerate it manually.

review: Needs Information
Revision history for this message
Andres Rodriguez (andreserl) wrote :

I guess it’s ok to let his land on its own?

On Fri, Jun 1, 2018 at 10:43 AM Björn Tillenius <email address hidden> wrote:

> Review: Needs Information
>
> Hmm. Did you regenerate maas-min.js? If this is to land with the lander, i
> guess it doesn't matter. But if we manually fast-forward it, we will have
> to regenerate it manually.
> --
> https://code.launchpad.net/~ack/maas/+git/maas/+merge/347258
> You are reviewing the proposed merge of
> ~ack/maas:backport-pools-as-machines-tab into maas:2.4.
>
--
Andres Rodriguez
Engineering Manager, MAAS
Canonical USA, Inc.

Revision history for this message
Björn Tillenius (bjornt) wrote :

Actually, I guess either you re-generated, or the diff apply cleanly. Either case is fine.

review: Approve

There was an error fetching revisions from git servers. Please try again in a few minutes. If the problem persists, contact Launchpad support.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/static/js/angular/controllers/nodes_list.js b/src/maasserver/static/js/angular/controllers/nodes_list.js
2index 1022f90..f3c2352 100644
3--- a/src/maasserver/static/js/angular/controllers/nodes_list.js
4+++ b/src/maasserver/static/js/angular/controllers/nodes_list.js
5@@ -98,7 +98,8 @@ angular.module('MAAS').controller('NodesListController', [
6
7 // Pools tab.
8 $scope.tabs.pools = {};
9- $scope.tabs.pools.pagetitle = "Pools";
10+ // The Pools tab is actually a sub tab of Machines.
11+ $scope.tabs.pools.pagetitle = "Machines";
12 $scope.tabs.pools.currentpage = "pools";
13 $scope.tabs.pools.manager = ResourcePoolsManager;
14 $scope.tabs.pools.actionOption = false;
15diff --git a/src/maasserver/static/js/bundle/maas-min.js b/src/maasserver/static/js/bundle/maas-min.js
16index 0509d72..6c4ad25 100644
17--- a/src/maasserver/static/js/bundle/maas-min.js
18+++ b/src/maasserver/static/js/bundle/maas-min.js
19@@ -1,2 +1,2 @@
20-!function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={i:moduleId,l:!1,exports:{}};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.l=!0,module.exports}__webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.d=function(exports,name,getter){__webpack_require__.o(exports,name)||Object.defineProperty(exports,name,{configurable:!1,enumerable:!0,get:getter})},__webpack_require__.r=function(exports){Object.defineProperty(exports,"__esModule",{value:!0})},__webpack_require__.n=function(module){var getter=module&&module.__esModule?function(){return module.default}:function(){return module};return __webpack_require__.d(getter,"a",getter),getter},__webpack_require__.o=function(object,property){return Object.prototype.hasOwnProperty.call(object,property)},__webpack_require__.p="",__webpack_require__(__webpack_require__.s=1)}({"./src/maasserver/static/js/angular/controllers/add_device.js":function(module,exports){angular.module("MAAS").controller("AddDeviceController",["$scope","DevicesManager","SubnetsManager","DomainsManager","ManagerHelperService","ValidationService",function($scope,DevicesManager,SubnetsManager,DomainsManager,ManagerHelperService,ValidationService){function newDevice(cloneDevice){return angular.isObject(cloneDevice)?{name:"",domain:cloneDevice.domain,interfaces:[{mac:"",ipAssignment:null,subnetId:null,ipAddress:""}]}:{name:"",domain:DomainsManager.getDefaultDomain(),interfaces:[{mac:"",ipAssignment:null,subnetId:null,ipAddress:""}]}}$scope.$parent.addDeviceScope=$scope,$scope.subnets=SubnetsManager.getItems(),$scope.domains=DomainsManager.getItems(),$scope.viewable=!1,$scope.error=null,$scope.ipAssignments=[{name:"external",title:"External"},{name:"dynamic",title:"Dynamic"},{name:"static",title:"Static"}],$scope.device=null,$scope.show=function(){$scope.viewable||ManagerHelperService.loadManagers($scope,[SubnetsManager,DomainsManager]).then(function(){$scope.device=newDevice($scope.device),$scope.viewable=!0})},$scope.hide=function(){$scope.viewable=!1,ManagerHelperService.unloadManagers($scope,[SubnetsManager,DomainsManager]),$scope.$emit("addDeviceHidden")},$scope.nameHasError=function(){return null!==$scope.device&&0!==$scope.device.name.length&&!ValidationService.validateHostname($scope.device.name)},$scope.macHasError=function(deviceInterface){if(0===deviceInterface.mac.length)return!1;if(!ValidationService.validateMAC(deviceInterface.mac))return!0;var i;for(i=0;i<$scope.device.interfaces.length;i++){if(!($scope.device.interfaces[i]===deviceInterface)&&$scope.device.interfaces[i].mac===deviceInterface.mac)return!0}return!1},$scope.ipHasError=function(deviceInterface){if(0===deviceInterface.ipAddress.length)return!1;if(!ValidationService.validateIP(deviceInterface.ipAddress))return!0;var i;if(angular.isObject(deviceInterface.ipAssignment))if("external"===deviceInterface.ipAssignment.name){for(i=0;i<$scope.subnets.length;i++)if(ValidationService.validateIPInNetwork(deviceInterface.ipAddress,$scope.subnets[i].cidr))return!0}else if("static"===deviceInterface.ipAssignment.name&&angular.isNumber(deviceInterface.subnetId)){var subnet=SubnetsManager.getItemFromList(deviceInterface.subnetId);if(!ValidationService.validateIPInNetwork(deviceInterface.ipAddress,subnet.cidr))return!0}return!1},$scope.deviceHasError=function(){if(null===$scope.device||""===$scope.device.name||$scope.nameHasError())return!0;var i;for(i=0;i<$scope.device.interfaces.length;i++){var deviceInterface=$scope.device.interfaces[i];if(""===deviceInterface.mac||$scope.macHasError(deviceInterface)||!angular.isObject(deviceInterface.ipAssignment))return!0;var externalIpError="external"===deviceInterface.ipAssignment.name&&(""===deviceInterface.ipAddress||$scope.ipHasError(deviceInterface)),staticIpError="static"===deviceInterface.ipAssignment.name&&(!angular.isNumber(deviceInterface.subnetId)||$scope.ipHasError(deviceInterface));if(externalIpError||staticIpError)return!0}return!1},$scope.addInterface=function(){$scope.device.interfaces.push({mac:"",ipAssignment:null,subnetId:null,ipAddress:""})},$scope.isPrimaryInterface=function(deviceInterface){return 0===$scope.device.interfaces.indexOf(deviceInterface)},$scope.deleteInterface=function(deviceInterface){$scope.isPrimaryInterface(deviceInterface)||$scope.device.interfaces.splice($scope.device.interfaces.indexOf(deviceInterface),1)},$scope.cancel=function(){$scope.error=null,$scope.device=newDevice(),$scope.hide()},$scope.save=function(addAnother){if(!$scope.deviceHasError()){$scope.error=null;var device=function(device){var i,convertedDevice={hostname:device.name,domain:device.domain,primary_mac:device.interfaces[0].mac,extra_macs:[],interfaces:[]};for(i=1;i<device.interfaces.length;i++)convertedDevice.extra_macs.push(device.interfaces[i].mac);return angular.forEach(device.interfaces,function(nic){convertedDevice.interfaces.push({mac:nic.mac,ip_assignment:nic.ipAssignment.name,ip_address:nic.ipAddress,subnet:nic.subnetId})}),convertedDevice}($scope.device);DevicesManager.create(device).then(function(device){addAnother?$scope.device=newDevice($scope.device):($scope.device=newDevice(),$scope.hide())},function(error){$scope.error=ManagerHelperService.parseValidationError(error)})}}}])},"./src/maasserver/static/js/angular/controllers/add_domain.js":function(module,exports){angular.module("MAAS").controller("AddDomainController",["$scope","DomainsManager","ManagerHelperService","ValidationService",function($scope,DomainsManager,ManagerHelperService,ValidationService){$scope.$parent.addDomainScope=$scope,$scope.viewable=!1,$scope.error=null,$scope.domain={name:"",authoritative:!0},$scope.show=function(){$scope.viewable||($scope.domain={name:"",authoritative:!0},$scope.viewable=!0)},$scope.hide=function(){$scope.viewable=!1,$scope.$emit("addDomainHidden")},$scope.nameHasError=function(){return 0!==$scope.domain.name.length&&!ValidationService.validateDomainName($scope.domain.name)},$scope.domainHasError=function(){return!(""!==$scope.domain.name&&!$scope.nameHasError())},$scope.cancel=function(){$scope.error=null,$scope.domain={name:"",authoritative:!0},$scope.hide()},$scope.save=function(addAnother){if(!$scope.domainHasError()){$scope.error=null;var domain=function(domain){return angular.copy(domain)}($scope.domain);DomainsManager.create(domain).then(function(){$scope.domain={name:"",authoritative:!0},addAnother||$scope.hide()},function(error){$scope.error=ManagerHelperService.parseValidationError(error)})}}}])},"./src/maasserver/static/js/angular/controllers/add_hardware.js":function(module,exports){angular.module("MAAS").controller("AddHardwareController",["$q","$scope","$http","ZonesManager","ResourcePoolsManager","MachinesManager","GeneralManager","DomainsManager","RegionConnection","ManagerHelperService","ValidationService",function($q,$scope,$http,ZonesManager,ResourcePoolsManager,MachinesManager,GeneralManager,DomainsManager,RegionConnection,ManagerHelperService,ValidationService){$scope.$parent.addHardwareScope=$scope,$scope.viewable=!1,$scope.model="machine",$scope.zones=ZonesManager.getItems(),$scope.pools=ResourcePoolsManager.getItems(),$scope.domains=DomainsManager.getItems(),$scope.architectures=GeneralManager.getData("architectures"),$scope.hwe_kernels=GeneralManager.getData("hwe_kernels"),$scope.default_min_hwe_kernel=GeneralManager.getData("default_min_hwe_kernel"),$scope.power_types=GeneralManager.getData("power_types"),$scope.error=null,$scope.macAddressRegex=/^([0-9A-F]{2}[::]){5}([0-9A-F]{2})$/gim,$scope.machine=null,$scope.chassis=null;var virshFields=[{name:"hostname",label:"Address",field_type:"string",default:"",choices:[],required:!0},{name:"password",label:"Password",field_type:"string",default:"",choices:[],required:!1},{name:"prefix_filter",label:"Prefix filter",field_type:"string",default:"",choices:[],required:!1}];function defaultArchitecture(){if(0===$scope.architectures.length)return"";var i;for(i=0;i<$scope.architectures.length;i++)if("amd64/generic"===$scope.architectures[i])return $scope.architectures[i];return $scope.architectures[0]}function newMachine(cloneMachine){return angular.isObject(cloneMachine)?{name:"",domain:cloneMachine.domain,macs:[{mac:"",error:!1}],zone:cloneMachine.zone,pool:cloneMachine.pool,architecture:cloneMachine.architecture,min_hwe_kernel:cloneMachine.min_hwe_kernel,power:{type:cloneMachine.power.type,parameters:{}}}:{name:"",domain:DomainsManager.getDefaultDomain(),macs:[{mac:"",error:!1}],zone:0===$scope.zones.length?null:$scope.zones[0],pool:0===$scope.pools.length?null:$scope.pools[0],architecture:defaultArchitecture(),min_hwe_kernel:$scope.default_min_hwe_kernel.text,power:{type:null,parameters:{}}}}function newChassis(cloneChassis){return angular.isObject(cloneChassis)?{domain:cloneChassis.domain,power:{type:null,parameters:{}}}:{domain:DomainsManager.getDefaultDomain(),power:{type:null,parameters:{}}}}$scope.chassisPowerTypes=[{name:"mscm",description:"Moonshot Chassis Manager",fields:[{name:"hostname",label:"Host",field_type:"string",default:"",choices:[],required:!0},{name:"username",label:"Username",field_type:"string",default:"",choices:[],required:!0},{name:"password",label:"Password",field_type:"string",default:"",choices:[],required:!0}]},{name:"powerkvm",description:"PowerKVM",fields:virshFields},{name:"recs_box",description:"Christmann RECS|Box",fields:[{name:"hostname",label:"Hostname",field_type:"string",default:"",choices:[],required:!0},{name:"port",label:"Port",field_type:"string",default:"80",choices:[],required:!1},{name:"username",label:"Username",field_type:"string",default:"",choices:[],required:!0},{name:"password",label:"Password",field_type:"string",default:"",choices:[],required:!0}]},{name:"seamicro15k",description:"SeaMicro 15000",fields:[{name:"hostname",label:"Hostname",field_type:"string",default:"",choices:[],required:!0},{name:"username",label:"Username",field_type:"string",default:"",choices:[],required:!0},{name:"password",label:"Password",field_type:"string",default:"",choices:[],required:!0},{name:"power_control",label:"Power Control",field_type:"choice",default:"restapi2",choices:[["restapi2","REST API V2.0"],["restapi","REST API V0.9"],["ipmi","IPMI"]],required:!0}]},{name:"ucsm",description:"UCS Chassis Manager",fields:[{name:"hostname",label:"URL",field_type:"string",default:"",choices:[],required:!0},{name:"username",label:"Username",field_type:"string",default:"",choices:[],required:!0},{name:"password",label:"Password",field_type:"string",default:"",choices:[],required:!0}]},{name:"virsh",description:"Virsh (virtual systems)",fields:virshFields},{name:"vmware",description:"VMware",fields:[{name:"hostname",label:"Host",field_type:"string",default:"",choices:[],required:!0},{name:"username",label:"Username",field_type:"string",default:"",choices:[],required:!0},{name:"password",label:"Password",field_type:"string",default:"",choices:[],required:!0},{name:"prefix_filter",label:"Prefix filter",field_type:"string",default:"",choices:[],required:!1}]}],$scope.show=function(mode){if(!$scope.viewable){$scope.mode=mode;var loadedItems=!1,loadedManagers=!1,defer=$q.defer();defer.promise.then(function(){$scope.machine=newMachine($scope.machine),$scope.chassis=newChassis($scope.chassis),$scope.error=null,angular.isObject($scope.machine)&&""===$scope.machine.architecture&&($scope.machine.architecture=defaultArchitecture()),$scope.viewable=!0}),GeneralManager.loadItems(["architectures","hwe_kernels","default_min_hwe_kernel"]).then(function(){loadedItems=!0,loadedManagers&&defer.resolve()}),ManagerHelperService.loadManagers($scope,[ZonesManager,DomainsManager]).then(function(){loadedManagers=!0,loadedItems&&defer.resolve()})}},$scope.hide=function(){$scope.viewable=!1,ManagerHelperService.unloadManagers($scope,[ZonesManager,DomainsManager]),$scope.$emit("addHardwareHidden")},$scope.showMachine=function(){return 0!==$scope.architectures.length&&"machine"===$scope.mode},$scope.showChassis=function(){return 0!==$scope.architectures.length&&"chassis"===$scope.mode},$scope.addMac=function(){$scope.machine.macs.push({mac:"",error:!1})},$scope.removeMac=function(mac){var idx=$scope.machine.macs.indexOf(mac);idx>-1&&$scope.machine.macs.splice(idx,1)},$scope.invalidName=function(){return 0!==$scope.machine.name.length&&!ValidationService.validateHostname($scope.machine.name)},$scope.validateMac=function(mac){""===mac.mac?mac.error=!1:mac.error=!ValidationService.validateMAC(mac.mac)},$scope.machineHasError=function(){if(in_error=null===$scope.machine||null===$scope.machine.zone||null===$scope.machine.pool||""===$scope.machine.architecture||null===$scope.machine.power.type||$scope.invalidName($scope.machine),in_error)return in_error;if(""===$scope.machine.macs[0].mac||$scope.machine.macs[0].error)return!0;var i;for(i=1;i<$scope.machine.macs.length;i++){var mac=$scope.machine.macs[i];if(""!==mac.mac&&mac.error)return!0}return!1},$scope.chassisHasErrors=function(){return in_error=null===$scope.chassis||null===$scope.chassis.power.type,in_error||function(power_type,parameters){var i;for(i=0;i<power_type.fields.length;i++){var field=power_type.fields[i],value=parameters[field.name];if(field.required&&(angular.isUndefined(value)||""===value))return!0}return!1}($scope.chassis.power.type,$scope.chassis.power.parameters)},$scope.cancel=function(){$scope.error=null,$scope.machine=newMachine(),$scope.chassis=newChassis(),$scope.hide()},$scope.saveMachine=function(addAnother){var machine,macs,pxe_mac,extra_macs;$scope.machineHasError()||($scope.error=null,MachinesManager.create((machine=$scope.machine,macs=angular.copy(machine.macs),pxe_mac=macs.shift().mac,extra_macs=macs.map(function(mac){return mac.mac}),{hostname:machine.name,domain:machine.domain,architecture:machine.architecture,min_hwe_kernel:machine.min_hwe_kernel,pxe_mac:pxe_mac,extra_macs:extra_macs,power_type:machine.power.type.name,power_parameters:angular.copy(machine.power.parameters),zone:{id:machine.zone.id,name:machine.zone.name},pool:{id:machine.pool.id,name:machine.pool.name}})).then(function(){addAnother?$scope.machine=newMachine($scope.machine):($scope.machine=newMachine(),$scope.hide())},function(error){$scope.error=ManagerHelperService.parseValidationError(error)}))},$scope.saveChassis=function(addAnother){if(!$scope.chassisHasErrors()){$scope.error=null;var params=angular.copy($scope.chassis.power.parameters);params.chassis_type=$scope.chassis.power.type.name,params.domain=$scope.chassis.domain.name,"powerkvm"!==params.chassis_type&&"virsh"!==params.chassis_type||delete params.username,$http({method:"POST",url:"api/2.0/machines/?op=add_chassis",data:$.param(params),headers:{"Content-Type":"application/x-www-form-urlencoded"}}).then(function(){addAnother?$scope.chassis=newChassis($scope.chassis):($scope.chassis=newChassis(),$scope.hide())},function(error){$scope.error=ManagerHelperService.parseValidationError(error.data)})}}}])},"./src/maasserver/static/js/angular/controllers/dashboard.js":function(module,exports){angular.module("MAAS").controller("DashboardController",["$scope","$window","$rootScope","$routeParams","$location","DiscoveriesManager","DomainsManager","MachinesManager","DevicesManager","SubnetsManager","VLANsManager","ConfigsManager","ManagerHelperService",function($scope,$window,$rootScope,$routeParams,$location,DiscoveriesManager,DomainsManager,MachinesManager,DevicesManager,SubnetsManager,VLANsManager,ConfigsManager,ManagerHelperService){var deviceIPOptions=[["static","Static"],["dynamic","Dynamic"],["external","External"]];$rootScope.title="Dashboard",$rootScope.page="dashboard",$scope.loaded=!1,$scope.discoveredDevices=DiscoveriesManager.getItems(),$scope.domains=DomainsManager.getItems(),$scope.machines=MachinesManager.getItems(),$scope.devices=DevicesManager.getItems(),$scope.configManager=ConfigsManager,$scope.networkDiscovery=null,$scope.column="mac",$scope.selectedDevice=null,$scope.convertTo=null,$scope.predicate=$scope.last_seen,$scope.sortTable=function(predicate){$scope.predicate=predicate,$scope.reverse=!$scope.reverse},$scope.proxyManager={updateItem:function(params){if("device"===$scope.convertTo.type)return DevicesManager.createItem(params);if("interface"===$scope.convertTo.type)return DevicesManager.createInterface(params);throw new Error("Unknown type: "+$scope.convertTo.type)}},$scope.getDiscoveryName=function(discovery){return null===discovery.hostname?"unknown":discovery.hostname},$scope.getSubnetName=function(subnetId){var subnet=SubnetsManager.getItemFromList(subnetId);return SubnetsManager.getName(subnet)},$scope.getVLANName=function(vlanId){var vlan=VLANsManager.getItemFromList(vlanId);return VLANsManager.getName(vlan)},$scope.toggleSelected=function(deviceId){if($scope.selectedDevice===deviceId)$scope.selectedDevice=null;else{var domain,discovered=DiscoveriesManager.getItemFromList(deviceId),hostname=$scope.getDiscoveryName(discovered);"unknown"===hostname&&(hostname=""),hostname.indexOf(".")>0?(domain=DomainsManager.getDomainByName(hostname.slice(hostname.indexOf(".")+1)),hostname=hostname.split(".",1)[0],null===domain&&(domain=DomainsManager.getDefaultDomain())):domain=DomainsManager.getDefaultDomain(),$scope.convertTo={type:"device",hostname:hostname,domain:domain,parent:null,ip_assignment:"dynamic",goTo:!1,saved:!1,deviceIPOptions:deviceIPOptions.filter(function(option){return!("static"===option[0]&&!angular.isNumber(discovered.subnet))})},$scope.selectedDevice=deviceId}},$scope.preProcess=function(item){var discovered=DiscoveriesManager.getItemFromList($scope.selectedDevice);return item=angular.copy(item),"device"===$scope.convertTo.type?(item.primary_mac=discovered.mac_address,item.extra_macs=[],item.interfaces=[{mac:discovered.mac_address,ip_assignment:item.ip_assignment,ip_address:discovered.ip,subnet:discovered.subnet}]):"interface"===$scope.convertTo.type&&(item.mac_address=discovered.mac_address,item.ip_address=discovered.ip,item.subnet=discovered.subnet),item},$scope.afterSave=function(obj){DiscoveriesManager._removeItem($scope.selectedDevice),$scope.selectedDevice=null,$scope.convertTo.hostname=obj.hostname,$scope.convertTo.parent=obj.parent,$scope.convertTo.saved=!0,$scope.convertTo.goTo&&(angular.isString(obj.parent)?$location.path("/device/"+obj.parent):$location.path("/devices/"))},ManagerHelperService.loadManagers($scope,[DiscoveriesManager,DomainsManager,MachinesManager,DevicesManager,SubnetsManager,VLANsManager,ConfigsManager]).then(function(){$scope.loaded=!0,$scope.networkDiscovery=ConfigsManager.getItemFromList("network_discovery")})}])},"./src/maasserver/static/js/angular/controllers/domain_details.js":function(module,exports){angular.module("MAAS").controller("DomainDetailsController",["$scope","$rootScope","$routeParams","$location","DomainsManager","UsersManager","ManagerHelperService","ErrorService",function($scope,$rootScope,$routeParams,$location,DomainsManager,UsersManager,ManagerHelperService,ErrorService){function domainLoaded(domain){$scope.domain=domain,$scope.loaded=!0,$rootScope.title=$scope.domain.displayname}$rootScope.title="Loading...",$rootScope.page="domains",$scope.loaded=!1,$scope.domain=null,$scope.editSummary=!1,$scope.predicate="name",$scope.reverse=!1,$scope.action=null,$scope.editRow=null,$scope.deleteRow=null,$scope.domainsManager=DomainsManager,$scope.newObject={},$scope.supportedRecordTypes=["A","AAAA","CNAME","MX","NS","SRV","SSHFP","TXT"],$scope.predicate="name",$scope.sortTable=function(predicate){$scope.predicate=predicate,$scope.reverse=!$scope.reverse},$scope.enterEditSummary=function(){$scope.editSummary=!0},$scope.exitEditSummary=function(){$scope.editSummary=!1},$scope.isRecordAutogenerated=function(row){return!row.dnsresource_id},$scope.editRecord=function(row){$scope.editRow=row,row.previous_rrdata=row.rrdata,row.previous_rrtype=row.rrtype,row.previous_name=row.name,row.previous_ttl=row.ttl,$scope.deleteRow=null},$scope.removeRecord=function(row){$scope.deleteRow=row,$scope.editRow=null},$scope.confirmRemoveRecord=function(row){row.domain=$scope.domain.id,$scope.domainsManager.deleteDNSRecord(row),$scope.stopEditingRow()},$scope.stopEditingRow=function(){$scope.editRow=null,$scope.deleteRow=null},$scope.isSuperUser=function(){return UsersManager.isSuperUser()},$scope.isDefaultDomain=function(){return!!angular.isObject($scope.domain)&&0===$scope.domain.id},$scope.canBeDeleted=function(){return!!angular.isObject($scope.domain)&&0===$scope.domain.rrsets.length},$scope.deleteButton=function(){$scope.error=null,$scope.actionInProgress=!0,$scope.action="delete"},$scope.addRecordButton=function(){$scope.error=null,$scope.actionInProgress=!0,$scope.action="add_record"},$scope.cancelAction=function(){$scope.actionInProgress=!1},$scope.deleteConfirmButton=function(){DomainsManager.deleteDomain($scope.domain).then(function(){$scope.actionInProgress=!1,$location.path("/domains")},function(error){$scope.error=ManagerHelperService.parseValidationError(error)})},ManagerHelperService.loadManagers($scope,[DomainsManager,UsersManager]).then(function(){var activeDomain=DomainsManager.getActiveItem(),requestedDomain=parseInt($routeParams.domain_id,10);isNaN(requestedDomain)?ErrorService.raiseError("Invalid domain identifier."):angular.isObject(activeDomain)&&activeDomain.id===requestedDomain?domainLoaded(activeDomain):DomainsManager.setActiveItem(requestedDomain).then(function(domain){domainLoaded(domain)},function(error){ErrorService.raiseError(error)})})}])},"./src/maasserver/static/js/angular/controllers/domains_list.js":function(module,exports){angular.module("MAAS").controller("DomainsListController",["$scope","$rootScope","$routeParams","$filter","DomainsManager","UsersManager","ManagerHelperService",function($scope,$rootScope,$routeParams,$filter,DomainsManager,UsersManager,ManagerHelperService){$rootScope.title="DNS",$rootScope.page="domains",$scope.domains=DomainsManager.getItems(),$scope.currentpage="domains",$scope.predicate="name",$scope.reverse=!1,$scope.loading=!0,$scope.addDomainScope=null,$scope.addDomain=function(){$scope.addDomainScope.show()},$scope.cancelAddDomain=function(){$scope.addDomainScope.cancel()},$scope.isSuperUser=function(){return UsersManager.isSuperUser()},ManagerHelperService.loadManagers($scope,[DomainsManager,UsersManager]).then(function(){$scope.loading=!1})}])},"./src/maasserver/static/js/angular/controllers/fabric_details.js":function(module,exports){angular.module("MAAS").controller("FabricDetailsController",["$scope","$rootScope","$routeParams","$filter","$location","FabricsManager","VLANsManager","SubnetsManager","SpacesManager","ControllersManager","UsersManager","ManagerHelperService","ErrorService",function($scope,$rootScope,$routeParams,$filter,$location,FabricsManager,VLANsManager,SubnetsManager,SpacesManager,ControllersManager,UsersManager,ManagerHelperService,ErrorService){function fabricLoaded(fabric){angular.isObject(fabric)&&($scope.fabric=fabric,$rootScope.title=$scope.fabric.name,$scope.$watch("vlans",updateVLANs,!0),$scope.$watch("subnets",updateVLANs,!0),$scope.$watch("controllers",updateVLANs,!0),$scope.loaded=!0,$scope.predicate="['vlan_name', 'vlan.id', 'subnet_name']")}function updateVLANs(){var rows=[],racks={};angular.forEach($filter("filter")($scope.vlans,{fabric:$scope.fabric.id},!0),function(vlan){var subnets=$filter("filter")($scope.subnets,{vlan:vlan.id},!0);if(subnets.length>0)angular.forEach(subnets,function(subnet){var space=SpacesManager.getItemFromList(subnet.space),space_name=null===space?"(undefined)":space.name,row={vlan:vlan,vlan_name:VLANsManager.getName(vlan),subnet:subnet,subnet_name:SubnetsManager.getName(subnet),space:space,space_name:space_name};rows.push(row)});else{var row={vlan:vlan,vlan_name:VLANsManager.getName(vlan),subnet:null,subnet_name:null,space:null,space_name:null};rows.push(row)}angular.forEach(vlan.rack_sids,function(rack_sid){var rack=ControllersManager.getItemFromList(rack_sid);angular.isObject(rack)&&(racks[rack.system_id]=rack)})}),$scope.rows=rows,$scope.racks=Object.keys(racks).map(function(key){return racks[key]})}$rootScope.title="Loading...",$rootScope.page="networks",$scope.fabric=null,$scope.fabricManager=FabricsManager,$scope.editSummary=!1,$scope.vlans=VLANsManager.getItems(),$scope.subnets=SubnetsManager.getItems(),$scope.controllers=ControllersManager.getItems(),$scope.loaded=!1,$scope.enterEditSummary=function(){$scope.editSummary=!0},$scope.exitEditSummary=function(){$scope.editSummary=!1},$scope.isSuperUser=function(){return UsersManager.isSuperUser()},$scope.isDefaultFabric=function(){return!!angular.isObject($scope.fabric)&&0===$scope.fabric.id},$scope.canBeDeleted=function(){return!!angular.isObject($scope.fabric)&&0!==$scope.fabric.id},$scope.deleteButton=function(){$scope.error=null,$scope.confirmingDelete=!0},$scope.cancelDeleteButton=function(){$scope.confirmingDelete=!1},$scope.deleteConfirmButton=function(){FabricsManager.deleteFabric($scope.fabric).then(function(){$scope.confirmingDelete=!1,$location.path("/networks"),$location.search("by","fabric")},function(reply){$scope.error=ManagerHelperService.parseValidationError(reply.error)})},ManagerHelperService.loadManagers($scope,[FabricsManager,VLANsManager,SubnetsManager,SpacesManager,ControllersManager,UsersManager]).then(function(){var activeFabric=FabricsManager.getActiveItem(),requestedFabric=parseInt($routeParams.fabric_id,10);isNaN(requestedFabric)?ErrorService.raiseError("Invalid fabric identifier."):angular.isObject(activeFabric)&&activeFabric.id===requestedFabric?fabricLoaded(activeFabric):FabricsManager.setActiveItem(requestedFabric).then(function(fabric){fabricLoaded(fabric)},function(error){ErrorService.raiseError(error)})})}])},"./src/maasserver/static/js/angular/controllers/images.js":function(module,exports){angular.module("MAAS").controller("ImagesController",["$rootScope","$scope","BootResourcesManager","ConfigsManager","UsersManager","ManagerHelperService",function($rootScope,$scope,BootResourcesManager,ConfigsManager,UsersManager,ManagerHelperService){$rootScope.page="images",$rootScope.title="Loading...",$scope.loading=!0,$scope.bootResources=BootResourcesManager.getData(),$scope.configManager=ConfigsManager,$scope.autoImport=null,$scope.isSuperUser=function(){return UsersManager.isSuperUser()},ManagerHelperService.loadManagers($scope,[ConfigsManager,UsersManager]).then(function(){$scope.autoImport=ConfigsManager.getItemFromList("boot_images_auto_import")}),$scope.$watch("bootResources.resources",function(){angular.isArray($scope.bootResources.resources)&&($scope.loading=!1,$rootScope.title="Images")})}])},"./src/maasserver/static/js/angular/controllers/intro.js":function(module,exports){angular.module("MAAS").controller("IntroController",["$rootScope","$scope","$window","$location","ConfigsManager","PackageRepositoriesManager","BootResourcesManager","ManagerHelperService",function($rootScope,$scope,$window,$location,ConfigsManager,PackageRepositoriesManager,BootResourcesManager,ManagerHelperService){if($rootScope.page="intro",$rootScope.title="Welcome",$scope.loading=!0,$scope.configManager=ConfigsManager,$scope.repoManager=PackageRepositoriesManager,$scope.bootResources=BootResourcesManager.getData(),$scope.hasImages=!1,$scope.maasName=null,$scope.upstreamDNS=null,$scope.mainArchive=null,$scope.portsArchive=null,$scope.httpProxy=null,$rootScope.skip=function(){$scope.clickContinue(!0)},$scope.welcomeInError=function(){var form=$scope.maasName.$maasForm;return!!angular.isObject(form)&&form.hasErrors()},$scope.networkInError=function(){var inError=!1,objs=[$scope.upstreamDNS,$scope.mainArchive,$scope.portsArchive,$scope.httpProxy];return angular.forEach(objs,function(obj){var form=obj.$maasForm;angular.isObject(form)&&form.hasErrors()&&(inError=!0)}),inError},$scope.canContinue=function(){return!$scope.welcomeInError()&&!$scope.networkInError()&&$scope.hasImages},$scope.clickContinue=function(force){angular.isUndefined(force)&&(force=!1),(force||$scope.canContinue())&&ConfigsManager.updateItem({name:"completed_intro",value:!0}).then(function(){$window.location.reload()})},MAAS_config.completed_intro)$location.path("/");else{var managers=[ConfigsManager,PackageRepositoriesManager];ManagerHelperService.loadManagers($scope,managers).then(function(){$scope.loading=!1,$scope.maasName=ConfigsManager.getItemFromList("maas_name"),$scope.upstreamDNS=ConfigsManager.getItemFromList("upstream_dns"),$scope.httpProxy=ConfigsManager.getItemFromList("http_proxy"),$scope.mainArchive=PackageRepositoriesManager.getItems().filter(function(repo){return repo.default&&"main_archive"===repo.name})[0],$scope.portsArchive=PackageRepositoriesManager.getItems().filter(function(repo){return repo.default&&"ports_archive"===repo.name})[0]}),$scope.$watch("bootResources.resources",function(){angular.isArray($scope.bootResources.resources)&&$scope.bootResources.resources.length>0?$scope.hasImages=!0:$scope.hasImages=!1})}}])},"./src/maasserver/static/js/angular/controllers/intro_user.js":function(module,exports){angular.module("MAAS").controller("IntroUserController",["$rootScope","$scope","$window","$location","UsersManager","ManagerHelperService",function($rootScope,$scope,$window,$location,UsersManager,ManagerHelperService){$rootScope.page="intro",$rootScope.title="Welcome",$scope.loading=!0,$scope.user=null,$rootScope.skip=function(){$scope.clickContinue(!0)},$scope.isSuperUser=function(){return UsersManager.isSuperUser()},$scope.canContinue=function(){return $scope.user.sshkeys_count>0},$scope.clickContinue=function(force){angular.isUndefined(force)&&(force=!1),(force||$scope.canContinue())&&UsersManager.markIntroComplete().then(function(){$window.location.reload()})},MAAS_config.user_completed_intro?$location.path("/"):ManagerHelperService.loadManager($scope,UsersManager).then(function(){$scope.loading=!1,$scope.user=UsersManager.getAuthUser()})}])},"./src/maasserver/static/js/angular/controllers/networks_list.js":function(module,exports){angular.module("MAAS").controller("NetworksListController",["$scope","$rootScope","$routeParams","$filter","$location","SubnetsManager","FabricsManager","SpacesManager","VLANsManager","UsersManager","ManagerHelperService",function($scope,$rootScope,$routeParams,$filter,$location,SubnetsManager,FabricsManager,SpacesManager,VLANsManager,UsersManager,ManagerHelperService){var filterByVLAN=$filter("filterByVLAN"),filterByFabric=$filter("filterByFabric"),filterBySpace=$filter("filterBySpace"),filterByNullSpace=$filter("filterByNullSpace");$rootScope.title="Subnets",$rootScope.page="networks",$scope.getURLParameters=function(){angular.isString($location.search().by)?$scope.groupBy=$location.search().by:$scope.groupBy="fabric"},$scope.ADD_FABRIC_ACTION={name:"add_fabric",title:"Fabric",selectedTitle:"Add fabric",objectName:"fabric"},$scope.ADD_VLAN_ACTION={name:"add_vlan",title:"VLAN",selectedTitle:"Add VLAN",objectName:"vlan"},$scope.ADD_SPACE_ACTION={name:"add_space",title:"Space",selectedTitle:"Add space",objectName:"space"},$scope.ADD_SUBNET_ACTION={name:"add_subnet",title:"Subnet",selectedTitle:"Add subnet",objectName:"subnet"},$scope.getURLParameters(),$scope.subnetManager=SubnetsManager,$scope.subnets=SubnetsManager.getItems(),$scope.fabricManager=FabricsManager,$scope.fabrics=FabricsManager.getItems(),$scope.spaceManager=SpacesManager,$scope.spaces=SpacesManager.getItems(),$scope.vlanManager=VLANsManager,$scope.vlans=VLANsManager.getItems(),$scope.loading=!0,$scope.group={},$scope.group.fabrics={},$scope.group.spaces={},$scope.group.spaces.orphanVLANs=[];var actionObjectInitializers={fabric:function(){return{}},vlan:function(){return{fabric:$scope.fabrics[0].id}},space:function(){return{}},subnet:function(){return{vlan:$scope.fabrics[0].vlan_ids[0]}}};function getSubnetName(subnet){return SubnetsManager.getName(subnet)}$scope.updateGroupBy=function(){var rows,spaces,previous_space;"space"===$scope.groupBy?($location.search("by","space"),rows=[],spaces=$filter("orderBy")($scope.spaces,["name"]),previous_space={id:-1},angular.forEach(spaces,function(space){var subnets=filterBySpace($scope.subnets,space);subnets=$filter("orderBy")(subnets,["cidr"]);var index=0;angular.forEach(subnets,function(subnet){index++;var vlan=VLANsManager.getItemFromList(subnet.vlan),row={fabric:FabricsManager.getItemFromList(vlan.fabric),vlan:vlan,vlan_name:$scope.getVLANName(vlan),subnet:subnet,subnet_name:getSubnetName(subnet),space:space,space_name:""};space.id!==previous_space.id&&(previous_space.id=space.id,row.space_name=space.name),rows.push(row)}),0===index&&rows.push({space:space,space_name:space.name})}),$scope.group.spaces.rows=rows,function(){var rows=[],subnets=filterByNullSpace($scope.subnets);subnets=$filter("orderBy")(subnets,["cidr"]),angular.forEach(subnets,function(subnet){var vlan=VLANsManager.getItemFromList(subnet.vlan),row={fabric:FabricsManager.getItemFromList(vlan.fabric),vlan:vlan,vlan_name:$scope.getVLANName(vlan),subnet:subnet,subnet_name:getSubnetName(subnet),space:null};rows.push(row)}),$scope.group.spaces.orphanVLANs=rows}()):($location.search("by","fabric"),function(){var rows=[],previous_fabric={id:-1},previous_vlan={id:-1},fabrics=$filter("orderBy")($scope.fabrics,["name"]);angular.forEach(fabrics,function(fabric){var vlans=filterByFabric($scope.vlans,fabric);vlans=$filter("orderBy")(vlans,["vid"]),angular.forEach(vlans,function(vlan){var subnets=filterByVLAN($scope.subnets,vlan);if(subnets.length>0)angular.forEach(subnets,function(subnet){var space=SpacesManager.getItemFromList(subnet.space),row={fabric:fabric,fabric_name:"",vlan:vlan,vlan_name:"",space:space,subnet:subnet,subnet_name:getSubnetName(subnet)};fabric.id!==previous_fabric.id&&(previous_fabric.id=fabric.id,row.fabric_name=fabric.name),vlan.id!==previous_vlan.id&&(previous_vlan.id=vlan.id,row.vlan_name=$scope.getVLANName(vlan)),rows.push(row)});else{var row={fabric:fabric,fabric_name:"",vlan:vlan,vlan_name:$scope.getVLANName(vlan)};fabric.id!==previous_fabric.id&&(previous_fabric.id=fabric.id,row.fabric_name=fabric.name),rows.push(row)}})}),$scope.group.fabrics.rows=rows}())},$scope.updateActions=function(){UsersManager.isSuperUser()?$scope.actionOptions=[$scope.ADD_FABRIC_ACTION,$scope.ADD_VLAN_ACTION,$scope.ADD_SPACE_ACTION,$scope.ADD_SUBNET_ACTION]:$scope.actionOptions=[]},$scope.actionChanged=function(){$scope.newObject=actionObjectInitializers[$scope.actionOption.objectName]()},$scope.cancelAction=function(){$scope.actionOption=null,$scope.newObject=null},$scope.getVLANName=function(vlan){return VLANsManager.getName(vlan)},$scope.getFabricNameById=function(fabricId){return FabricsManager.getName(FabricsManager.getItemFromList(fabricId))},$scope.actionSubnetPreSave=function(obj){return obj.fabric=VLANsManager.getItemFromList(obj.vlan).fabric,obj},ManagerHelperService.loadManagers($scope,[SubnetsManager,FabricsManager,SpacesManager,VLANsManager,UsersManager]).then(function(){$scope.loading=!1,$scope.updateActions(),$scope.$watch("[subnets, fabrics, spaces, vlans]",$scope.updateGroupBy,!0),$scope.$on("$routeUpdate",function(){$scope.getURLParameters(),$scope.updateGroupBy()}),$scope.updateGroupBy()})}])},"./src/maasserver/static/js/angular/controllers/node_details.js":function(module,exports){angular.module("MAAS").controller("NodeDetailsController",["$scope","$rootScope","$routeParams","$location","$interval","DevicesManager","MachinesManager","ControllersManager","ZonesManager","GeneralManager","UsersManager","TagsManager","DomainsManager","ManagerHelperService","ServicesManager","ErrorService","ValidationService","ScriptsManager","ResourcePoolsManager",function($scope,$rootScope,$routeParams,$location,$interval,DevicesManager,MachinesManager,ControllersManager,ZonesManager,GeneralManager,UsersManager,TagsManager,DomainsManager,ManagerHelperService,ServicesManager,ErrorService,ValidationService,ScriptsManager,ResourcePoolsManager){var page_managers,DEVICE_IP_ASSIGNMENT={external:"External",dynamic:"Dynamic",static:"Static"};function updateTitle(){$scope.node&&$scope.node.fqdn&&($rootScope.title=$scope.node.fqdn)}function updateHeader(){var i;if(!$scope.header.editing&&!$scope.header.editing_domain)for($scope.header.hostname.value=$scope.node.fqdn,i=0;i<$scope.header.domain.options.length;i++){var option=$scope.header.domain.options[i];if(option.id===$scope.node.domain.id){$scope.header.domain.selected=option;break}}}function updateAvailableActionOptions(){if(angular.isObject($scope.node)){var actionTypeForNodeType={0:"machine_actions",1:"device_actions",2:"rack_controller_actions",3:"region_controller_actions",4:"region_and_rack_controller_actions"};if(GeneralManager.isDataLoaded(actionTypeForNodeType[$scope.node.node_type]))$scope.action.allOptions=GeneralManager.getData(actionTypeForNodeType[$scope.node.node_type]),$scope.action.availableOptions.length=0,angular.forEach($scope.action.allOptions,function(option){$scope.node.actions.indexOf(option.name)>=0&&"set-zone"!==option.name&&"set-pool"!==option.name&&$scope.action.availableOptions.push(option)});else{GeneralManager.loadItems([actionTypeForNodeType[$scope.node.node_type]]).then(updateAvailableActionOptions)}}}function updatePower(){if(!$scope.power.editing){var i;for($scope.power.type=null,i=0;i<$scope.power_types.length;i++)if($scope.node.power_type===$scope.power_types[i].name){$scope.power.type=$scope.power_types[i];break}$scope.power.bmc_node_count=$scope.node.power_bmc_node_count,$scope.power.parameters=angular.copy($scope.node.power_parameters),angular.isObject($scope.power.parameters)||($scope.power.parameters={}),$scope.canEdit()&&""===$scope.node.power_type&&0===$scope.node.node_type&&($scope.power.editing=!0),$scope.power.in_pod=angular.isDefined($scope.node.pod)}}function updateSummary(){$scope.summary.editing||(angular.isObject($scope.node.zone)&&($scope.summary.zone.selected=ZonesManager.getItemFromList($scope.node.zone.id)),angular.isObject($scope.node.pool)&&($scope.summary.pool.selected=ResourcePoolsManager.getItemFromList($scope.node.pool.id)),$scope.summary.architecture.selected=$scope.node.architecture,$scope.summary.min_hwe_kernel.selected=$scope.node.min_hwe_kernel,$scope.summary.tags=angular.copy($scope.node.tags),$scope.canEdit()&&$scope.hasUsableArchitectures()&&$scope.hasInvalidArchitecture()&&($scope.summary.editing=!0))}function updateServices(){$scope.isController&&($scope.services={},angular.forEach(ControllersManager.getServices($scope.node),function(service){$scope.services[service.name]=service}))}function updateDevices(){$scope.devices=[],angular.forEach($scope.node.devices,function(child){var device={name:child.fqdn};angular.isArray(child.interfaces)&&child.interfaces.length>0?angular.forEach(child.interfaces,function(nic,nicIdx){var deviceWithMAC=angular.copy(device);deviceWithMAC.mac_address=nic.mac_address,nicIdx>0&&(deviceWithMAC.name=""),angular.isArray(nic.links)&&nic.links.length>0?angular.forEach(nic.links,function(link,lIdx){var deviceWithLink=angular.copy(deviceWithMAC);deviceWithLink.ip_address=link.ip_address,lIdx>0&&(deviceWithLink.mac_address=""),$scope.devices.push(deviceWithLink)}):$scope.devices.push(deviceWithMAC)}):$scope.devices.push(device)})}function nodeLoaded(node){$scope.node=node,$scope.loaded=!0,updateTitle(),updateSummary(),updateServices(),$scope.$watch("node.fqdn",function(){updateTitle(),updateHeader()}),$scope.$watch("node.devices",updateDevices),$scope.$watch("node.actions",updateAvailableActionOptions),$scope.$watch("node.architecture",updateSummary),$scope.$watchCollection($scope.summary.architecture.options,updateSummary),$scope.$watch("node.min_hwe_kernel",updateSummary),$scope.$watchCollection($scope.summary.min_hwe_kernel.options,updateSummary),$scope.$watch("node.zone.id",updateSummary),$scope.$watchCollection($scope.summary.zone.options,updateSummary),$scope.$watch("node.pool.id",updateSummary),$scope.$watchCollection($scope.summary.pool.options,updateSummary),$scope.$watch("node.power_type",updatePower),$scope.$watch("node.power_parameters",updatePower),$scope.$watchCollection("power_types",updatePower),$scope.$watch("node.service_ids",updateServices),angular.isObject($scope.storageController)&&$scope.storageController.nodeLoaded(),angular.isObject($scope.networkingController)&&$scope.networkingController.nodeLoaded()}$rootScope.title="Loading...",$scope.MAAS_config=MAAS_config,$scope.loaded=!1,$scope.node=null,$scope.action={option:null,allOptions:null,availableOptions:[],error:null,showing_confirmation:!1},$scope.power_types=GeneralManager.getData("power_types"),$scope.osinfo=GeneralManager.getData("osinfo"),$scope.section={area:angular.isString($routeParams.area)?$routeParams.area:"summary"},$scope.osSelection={osystem:null,release:null,hwe_kernel:null},$scope.commissionOptions={enableSSH:!1,skipNetworking:!1,skipStorage:!1,updateFirmware:!1,configureHBA:!1},$scope.commissioningSelection=[],$scope.testSelection=[],$scope.releaseOptions={},$scope.checkingPower=!1,$scope.devices=[],$scope.scripts=ScriptsManager.getItems(),$scope.header={editing:!1,editing_domain:!1,hostname:{value:""},domain:{selected:null,options:DomainsManager.getItems()}},$scope.summary={editing:!1,architecture:{selected:null,options:GeneralManager.getData("architectures")},min_hwe_kernel:{selected:null,options:GeneralManager.getData("min_hwe_kernels")},zone:{selected:null,options:ZonesManager.getItems()},pool:{selected:null,options:ResourcePoolsManager.getItems()},tags:[]},$scope.services={},$scope.power={editing:!1,type:null,bmc_node_count:0,parameters:{},in_pod:!1},$scope.getDeviceIPAssignment=function(ipAssignment){return DEVICE_IP_ASSIGNMENT[ipAssignment]},$scope.events={limit:10},$scope.updateNode=function(node,queryPower){return angular.isUndefined(queryPower)&&(queryPower=!1),$scope.nodesManager.updateItem(node).then(function(node){updateHeader(),updateSummary(),queryPower&&$scope.checkPowerState()},function(error){console.log(error),updateHeader(),updateSummary()})},$scope.tagsAutocomplete=function(query){return TagsManager.autocomplete(query)},$scope.getPowerStateClass=function(){return angular.isObject($scope.node)?$scope.checkingPower?"checking":$scope.node.power_state:""},$scope.getPowerStateText=function(){return angular.isObject($scope.node)?$scope.checkingPower?"Checking power":"unknown"===$scope.node.power_state?"":"Power "+$scope.node.power_state:""},$scope.canCheckPowerState=function(){return!!angular.isObject($scope.node)&&("unknown"!==$scope.node.power_state&&!$scope.checkingPower)},$scope.checkPowerState=function(){$scope.checkingPower=!0,$scope.nodesManager.checkPowerState($scope.node).then(function(){$scope.checkingPower=!1})},$scope.isUbuntuOS=function(){return!!angular.isObject($scope.node)&&"ubuntu"===$scope.node.osystem},$scope.isUbuntuCoreOS=function(){return!!angular.isObject($scope.node)&&"ubuntu-core"===$scope.node.osystem},$scope.isCustomOS=function(){return!!angular.isObject($scope.node)&&"custom"===$scope.node.osystem},$scope.isActionError=function(){return null!==$scope.action.error},$scope.isDeployError=function(){if($scope.isActionError())return!1;var missing_osinfo=angular.isUndefined($scope.osinfo.osystems)||0===$scope.osinfo.osystems.length;return!(!angular.isObject($scope.action.option)||"deploy"!==$scope.action.option.name||!missing_osinfo)},$scope.isSSHKeyError=function(){return!$scope.isActionError()&&!(!angular.isObject($scope.action.option)||"deploy"!==$scope.action.option.name||0!==UsersManager.getSSHKeyCount())},$scope.action.optionChanged=function(){$scope.action.error=null,$scope.action.showing_confirmation=!1},$scope.actionCancel=function(){$scope.action.option=null,$scope.action.error=null,$scope.action.showing_confirmation=!1},$scope.actionGo=function(){var i,extra={};if("deploy"===$scope.action.option.name&&angular.isString($scope.osSelection.osystem)&&angular.isString($scope.osSelection.release)){extra.osystem=$scope.osSelection.osystem;var release=$scope.osSelection.release;release=(release=release.split("/"))[release.length-1],extra.distro_series=release,angular.isString($scope.osSelection.hwe_kernel)&&($scope.osSelection.hwe_kernel.indexOf("hwe-")>=0||$scope.osSelection.hwe_kernel.indexOf("ga-")>=0)&&(extra.hwe_kernel=$scope.osSelection.hwe_kernel)}else if("commission"===$scope.action.option.name){for(extra.enable_ssh=$scope.commissionOptions.enableSSH,extra.skip_networking=$scope.commissionOptions.skipNetworking,extra.skip_storage=$scope.commissionOptions.skipStorage,extra.commissioning_scripts=[],i=0;i<$scope.commissioningSelection.length;i++)extra.commissioning_scripts.push($scope.commissioningSelection[i].id);for($scope.commissionOptions.updateFirmware&&extra.commissioning_scripts.push("update_firmware"),$scope.commissionOptions.configureHBA&&extra.commissioning_scripts.push("configure_hba"),0===extra.commissioning_scripts.length&&extra.commissioning_scripts.push("none"),extra.testing_scripts=[],i=0;i<$scope.testSelection.length;i++)extra.testing_scripts.push($scope.testSelection[i].id);0===extra.testing_scripts.length&&extra.testing_scripts.push("none")}else if("test"===$scope.action.option.name){if(6===$scope.node.status_code&&!$scope.action.showing_confirmation)return void($scope.action.showing_confirmation=!0);for(extra.enable_ssh=$scope.commissionOptions.enableSSH,extra.testing_scripts=[],i=0;i<$scope.testSelection.length;i++)extra.testing_scripts.push($scope.testSelection[i].id);0===extra.testing_scripts.length&&extra.testing_scripts.push("none")}else"release"===$scope.action.option.name&&(extra.erase=$scope.releaseOptions.erase,extra.secure_erase=$scope.releaseOptions.secureErase,extra.quick_erase=$scope.releaseOptions.quickErase);$scope.nodesManager.performAction($scope.node,$scope.action.option.name,extra).then(function(){"delete"===$scope.action.option.name&&$location.path("/machines"),$scope.action.option=null,$scope.action.error=null,$scope.action.showing_confirmation=!1,$scope.osSelection.$reset(),$scope.commissionOptions.enableSSH=!1,$scope.commissionOptions.skipNetworking=!1,$scope.commissionOptions.skipStorage=!1,$scope.commissionOptions.updateFirmware=!1,$scope.commissionOptions.configureHBA=!1,$scope.commissioningSelection=[],$scope.testSelection=[]},function(error){$scope.action.error=error})},$scope.isSuperUser=function(){return UsersManager.isSuperUser()},$scope.hasUsableArchitectures=function(){return $scope.summary.architecture.options.length>0},$scope.getArchitecturePlaceholder=function(){return $scope.hasUsableArchitectures()?"Choose an architecture":"-- No usable architectures --"},$scope.hasInvalidArchitecture=function(){return!!angular.isObject($scope.node)&&(!$scope.isDevice&&(""===$scope.node.architecture||-1===$scope.summary.architecture.options.indexOf($scope.node.architecture)))},$scope.invalidArchitecture=function(){return!($scope.isDevice||$scope.isController||""!==$scope.summary.architecture.selected&&-1!==$scope.summary.architecture.options.indexOf($scope.summary.architecture.selected))},$scope.isRackControllerConnected=function(){return $scope.power_types.length>0},$scope.isLocked=function(){return null!==$scope.node&&$scope.node.locked},$scope.canEdit=function(){return!!$scope.isDevice||$scope.isRackControllerConnected()&&$scope.isSuperUser()&&!$scope.isLocked()},$scope.editHeaderDomain=function(){$scope.canEdit()||$scope.header.editing_domain||($scope.header.editing=!1,$scope.header.editing_domain=!0,$scope.header.hostname.value=$scope.node.hostname)},$scope.editHeader=function(){$scope.canEdit()&&($scope.header.editing||($scope.header.editing=!0,$scope.header.editing_domain=!1,$scope.header.hostname.value=$scope.node.hostname))},$scope.editHeaderInvalid=function(){if(!$scope.header.editing&&!$scope.header.editing_domain)return!1;var value=$scope.header.hostname.value;return 0===value.length||!ValidationService.validateHostname(value)},$scope.cancelEditHeader=function(){$scope.header.editing=!1,$scope.header.editing_domain=!1,updateHeader()},$scope.saveEditHeader=function(){if(!$scope.editHeaderInvalid()){$scope.header.editing=!1,$scope.header.editing_domain=!1;var node=angular.copy($scope.node);node.hostname=$scope.header.hostname.value,node.domain=$scope.header.domain.selected,$scope.updateNode(node)}},$scope.editSummary=function(){$scope.canEdit()&&($scope.summary.editing=!0)},$scope.cancelEditSummary=function(){$scope.isDevice||$scope.isController?$scope.summary.editing=!1:$scope.hasInvalidArchitecture()||($scope.summary.editing=!1),updateSummary()},$scope.saveEditSummary=function(){if(!$scope.invalidArchitecture()){$scope.summary.editing=!1;var node=angular.copy($scope.node);node.zone=angular.copy($scope.summary.zone.selected),node.pool=angular.copy($scope.summary.pool.selected),node.architecture=$scope.summary.architecture.selected,null===$scope.summary.min_hwe_kernel.selected?node.min_hwe_kernel="":node.min_hwe_kernel=$scope.summary.min_hwe_kernel.selected,node.tags=[],angular.forEach($scope.summary.tags,function(tag){node.tags.push(tag.text)}),$scope.updateNode(node)}},$scope.invalidPowerType=function(){return!angular.isObject($scope.power.type)},$scope.editPower=function(){$scope.canEdit()&&($scope.power.editing=!0)},$scope.cancelEditPower=function(){0===$scope.node.node_type&&""===$scope.node.power_type||($scope.power.editing=!1),updatePower()},$scope.saveEditPower=function(){if(!$scope.invalidPowerType()){$scope.power.editing=!1;var node=angular.copy($scope.node);node.power_type=$scope.power.type.name,node.power_parameters=angular.copy($scope.power.parameters),$scope.updateNode(node,!0)}},$scope.allowShowMoreEvents=function(){return!!angular.isObject($scope.node)&&(!!angular.isArray($scope.node.events)&&($scope.node.events.length>0&&$scope.node.events.length>$scope.events.limit&&$scope.events.limit<50))},$scope.showMoreEvents=function(){$scope.events.limit+=10},$scope.getEventText=function(event){var text=event.type.description;return angular.isString(event.description)&&event.description.length>0&&(text+=" - "+event.description),text},$scope.getPowerEventError=function(){var i;if(angular.isObject($scope.node)&&angular.isArray($scope.node.events))for(i=0;i<$scope.node.events.length;i++){var event=$scope.node.events[i];if("warning"===event.type.level&&"Failed to query node's BMC"===event.type.description)return event;if("info"===event.type.level&&"Queried node's BMC"===event.type.description)return}},$scope.hasPowerEventError=function(){var event=$scope.getPowerEventError();return angular.isObject(event)},$scope.getPowerEventErrorText=function(){var event=$scope.getPowerEventError();return angular.isObject(event)?event.description:""},$scope.hasActionPowerError=function(actionName){if(!$scope.hasPowerError())return!1;return!!(actionName&&["commission","deploy","on","off","release"].indexOf(actionName)>-1)},$scope.hasPowerError=function(){return!!angular.isObject($scope.power.type)&&$scope.power.type.missing_packages.length>0},$scope.getPowerErrors=function(){var i,result="";if(angular.isObject($scope.power.type)){var packages=$scope.power.type.missing_packages;for(packages.sort(),i=0;i<packages.length;i++)result+=packages[i],i+2<packages.length?result+=", ":i+1<packages.length&&(result+=" and ");result+=packages.length>1?" packages":" package"}return result},$scope.getServiceClass=function(service){return angular.isObject(service)?"running"===service.status?"success":"dead"===service.status?"error":"degraded"===service.status?"warning":"none":"none"},$scope.hasCustomCommissioningScripts=function(){var i;for(i=0;i<$scope.scripts.length;i++)if(0===$scope.scripts[i].script_type)return!0;return!1},$scope.controllerLoaded=function(name,scope){$scope[name]=scope,angular.isObject(scope.node)&&scope.nodeLoaded()},$scope.showFailedTestWarning=function(){if(1===$scope.node.node_type||!$scope.node.status_code)return!1;switch($scope.node.status_code){case 0:case 1:case 2:case 21:case 22:return!1}switch($scope.node.testing_status){case-1:case 2:return!1}return!0},$scope.getCPUSubtext=function(){var label=$scope.node.cpu_count+" cores";return $scope.node.cpu_speed&&0!==$scope.node.cpu_speed?$scope.node.cpu_speed<1e3?label+" @ "+$scope.node.cpu_speed+" Mhz":label+" @ "+$scope.node.cpu_speed/1e3+" Ghz":label},$scope.$on("$routeUpdate",function(){GeneralManager.loadItems(["osinfo","architectures","min_hwe_kernels"])}),-1!==$location.path().indexOf("/controller")?($scope.nodesManager=ControllersManager,page_managers=[ControllersManager,ScriptsManager],$scope.isController=!0,$scope.isDevice=!1,$scope.type_name="controller",$scope.type_name_title="Controller",$rootScope.page="controllers"):-1!==$location.path().indexOf("/device")?($scope.nodesManager=DevicesManager,page_managers=[DevicesManager],$scope.isController=!1,$scope.isDevice=!0,$scope.type_name="device",$scope.type_name_title="Device",$rootScope.page="devices"):($scope.nodesManager=MachinesManager,page_managers=[MachinesManager,ScriptsManager],$scope.isController=!1,$scope.isDevice=!1,$scope.type_name="machine",$scope.type_name_title="Machine",$rootScope.page="machines"),ManagerHelperService.loadManagers($scope,[ZonesManager,GeneralManager,UsersManager,TagsManager,DomainsManager,ServicesManager,ResourcePoolsManager].concat(page_managers)).then(function(){var activeNode=$scope.nodesManager.getActiveItem();angular.isObject(activeNode)&&activeNode.system_id===$routeParams.system_id?nodeLoaded(activeNode):($scope.nodesManager.setActiveItem($routeParams.system_id).then(function(node){nodeLoaded(node)},function(error){ErrorService.raiseError(error)}),activeNode=$scope.nodesManager.getActiveItem()),$scope.isDevice&&($scope.ip_assignment=activeNode.ip_assignment)})}])},"./src/maasserver/static/js/angular/controllers/node_details_networking.js":function(module,exports){angular.module("MAAS").filter("filterByUnusedForInterface",function(){return function(vlans,nic,originalInterfaces){var filtered=[];if(!angular.isObject(nic)||!angular.isObject(originalInterfaces))return filtered;var usedVLANs=[];return angular.forEach(originalInterfaces,function(inter){"vlan"===inter.type&&(inter.parents[0]===nic.id&&usedVLANs.push(inter.vlan_id))}),angular.forEach(vlans,function(vlan){-1===usedVLANs.indexOf(vlan.id)&&filtered.push(vlan)}),filtered}}),angular.module("MAAS").filter("removeInterfaceParents",function(){return function(interfaces,childInterface,skip){if(skip||!angular.isObject(childInterface)||!angular.isArray(childInterface.parents))return interfaces;var filtered=[];return angular.forEach(interfaces,function(nic){var i,parent,found=!1;for(i=0;i<childInterface.parents.length;i++)if((parent=childInterface.parents[i]).id===nic.id&&parent.link_id===nic.link_id){found=!0;break}found||filtered.push(nic)}),filtered}}),angular.module("MAAS").filter("removeDefaultVLANIfVLAN",function(){return function(vlans,interfaceType){if(!angular.isString(interfaceType))return vlans;var filtered=[];return angular.forEach(vlans,function(vlan){"vlan"!==interfaceType?filtered.push(vlan):0!==vlan.vid&&filtered.push(vlan)}),filtered}}),angular.module("MAAS").filter("filterLinkModes",function(){return function(modes,nic){if(!angular.isObject(nic))return modes;var filtered=[];if(angular.isFunction(nic.getValue)||(nic.getValue=function(name){return this[name]}),angular.isObject(nic.getValue("subnet"))){var links=nic.getValue("links"),nicType=nic.getValue("type"),allowLinkUp=angular.isObject(links)&&links.length>1||"alias"===nicType;angular.forEach(modes,function(mode){allowLinkUp&&"link_up"===mode.mode||"alias"===nicType&&"dhcp"===mode.mode||filtered.push(mode)})}else angular.forEach(modes,function(mode){"link_up"===mode.mode&&filtered.push(mode)});return filtered}}),angular.module("MAAS").controller("NodeNetworkingController",["$scope","$filter","FabricsManager","VLANsManager","SubnetsManager","MachinesManager","ControllersManager","DevicesManager","GeneralManager","UsersManager","ManagerHelperService","ValidationService","JSONService",function($scope,$filter,FabricsManager,VLANsManager,SubnetsManager,MachinesManager,ControllersManager,DevicesManager,GeneralManager,UsersManager,ManagerHelperService,ValidationService,JSONService){var INTERFACE_TYPE={PHYSICAL:"physical",BOND:"bond",BRIDGE:"bridge",VLAN:"vlan",ALIAS:"alias"},INTERFACE_TYPE_TEXTS={physical:"Physical",bond:"Bond",bridge:"Bridge",vlan:"VLAN",alias:"Alias"},LINK_MODE={AUTO:"auto",STATIC:"static",DHCP:"dhcp",LINK_UP:"link_up"},LINK_MODE_TEXTS={auto:"Auto assign",static:"Static assign",dhcp:"DHCP",link_up:"Unconfigured"},SELECTION_MODE={NONE:null,SINGLE:"single",MULTI:"multi",DELETE:"delete",ADD:"add",CREATE_BOND:"create-bond",CREATE_BRIDGE:"create-bridge",CREATE_PHYSICAL:"create-physical",EDIT:"edit"},IP_ASSIGNMENT_DYNAMIC="dynamic",IP_ASSIGNMENT_EXTERNAL="external",IP_ASSIGNMENT_STATIC="static";function updateLoaded(){$scope.loaded=$scope.nodeHasLoaded&&$scope.managersHaveLoaded,$scope.loaded&&updateInterfaces()}function updateInterfaces(){$scope.originalInterfaces={},angular.forEach($scope.node.interfaces,function(nic){$scope.originalInterfaces[nic.id]=nic});var interfaces=[],vlanTable=[],addedVlans={};if(angular.forEach($scope.node.interfaces,function(nic){if(1===nic.children.length){var child=$scope.originalInterfaces[nic.children[0]];if(child.type===INTERFACE_TYPE.BOND||child.type===INTERFACE_TYPE.BRIDGE)return void(angular.isObject($scope.editInterface)&&$scope.editInterface.id===nic.id&&($scope.editInterface=null,$scope.selectedMode=SELECTION_MODE.NONE))}var tags,formatted;if(nic.type!==INTERFACE_TYPE.BOND&&nic.type!==INTERFACE_TYPE.BRIDGE||(nic.members=[],angular.forEach(nic.parents,function(parent){nic.members.push(angular.copy($scope.originalInterfaces[parent]))})),angular.isArray(nic.tags)&&nic.tags.length>0&&!angular.isString(nic.tags[0].text)&&(nic.tags=(tags=nic.tags,formatted=[],angular.forEach(tags,function(tag){formatted.push({text:tag})}),formatted)),nic.vlan=VLANsManager.getItemFromList(nic.vlan_id),angular.isObject(nic.vlan)&&(nic.fabric=FabricsManager.getItemFromList(nic.vlan.fabric),$scope.$parent.isController)){if(!Object.prototype.hasOwnProperty.call(addedVlans,nic.vlan.id)){addedVlans[nic.vlan.id]=!0;var vlanRecord={fabric:nic.fabric,vlan:nic.vlan,subnets:$filter("filter")($scope.subnets,{vlan:nic.vlan.id},!0),primary_rack:null,secondary_rack:null,sort_key:nic.fabric.name+"|"+$scope.getVLANText(nic.vlan)};nic.vlan.primary_rack&&(vlanRecord.primary_rack=ControllersManager.getItemFromList(nic.vlan.primary_rack)),nic.vlan.secondary_rack&&(vlanRecord.secondary_rack=ControllersManager.getItemFromList(nic.vlan.secondary_rack)),vlanTable.push(vlanRecord)}vlanTable.sort(function(a,b){return a.sort_key.localeCompare(b.sort_key)})}if(0===nic.links.length)nic.link_id=-1,nic.subnet=null,nic.mode=LINK_MODE.LINK_UP,nic.ip_address="",interfaces.push(nic);else{var idx=0;angular.forEach(nic.links,function(link){var nic_copy=angular.copy(nic);nic_copy.link_id=link.id,nic_copy.subnet=SubnetsManager.getItemFromList(link.subnet_id),nic_copy.mode=link.mode,nic_copy.ip_address=link.ip_address,angular.isUndefined(nic_copy.ip_address)&&(nic_copy.ip_address=""),nic_copy.vlan=nic.vlan,nic_copy.fabric=nic.fabric,idx>0&&(nic_copy.type=INTERFACE_TYPE.ALIAS,nic_copy.name+=":"+idx),idx++,interfaces.push(nic_copy)})}}),$scope.interfaces=interfaces,$scope.vlanTable=vlanTable,$scope.interfaceLinksMap={},angular.forEach($scope.interfaces,function(nic){var linkMaps=$scope.interfaceLinksMap[nic.id];angular.isUndefined(linkMaps)&&(linkMaps={},$scope.interfaceLinksMap[nic.id]=linkMaps),linkMaps[nic.link_id]=nic}),angular.isObject($scope.editInterface)){var links=$scope.interfaceLinksMap[$scope.editInterface.id];if(angular.isUndefined(links))$scope.editInterface=null,$scope.selectedMode=SELECTION_MODE.NONE;else{var link=links[$scope.editInterface.link_id];angular.isUndefined(link)&&($scope.editInterface=null,$scope.selectedMode=SELECTION_MODE.NONE)}}!function(){if(angular.isObject($scope.newInterface.parent)){var parentId=$scope.newInterface.parent.id,linkId=$scope.newInterface.parent.link_id,links=$scope.interfaceLinksMap[parentId];if(angular.isObject(links)){var newParent=links[linkId];if(angular.isObject(newParent)){$scope.newInterface.parent=newParent;var iType=$scope.newInterface.type,isAlias=iType===INTERFACE_TYPE.ALIAS,isVLAN=iType===INTERFACE_TYPE.VLAN,canAddAlias=$scope.canAddAlias(newParent),canAddVLAN=$scope.canAddVLAN(newParent);return void(canAddAlias||canAddVLAN?isAlias&&!canAddAlias&&canAddVLAN?($scope.newInterface.type="vlan",$scope.addTypeChanged()):isVLAN&&!canAddVLAN&&canAddAlias&&($scope.newInterface.type="alias",$scope.addTypeChanged()):($scope.newInterface={},leaveSingleSelectionMode()))}}$scope.newInterface={},leaveSingleSelectionMode()}}()}function mapNICToOriginalLink(nic_id,link_id){var originalInteface=$scope.originalInterfaces[nic_id];if(angular.isObject(originalInteface)){var i,link=null;for(i=0;i<originalInteface.links.length&&(link=originalInteface.links[i]).id!==link_id;i++);return link}return null}function leaveSingleSelectionMode(){$scope.selectedMode!==SELECTION_MODE.SINGLE&&$scope.selectedMode!==SELECTION_MODE.ADD&&$scope.selectedMode!==SELECTION_MODE.DELETE||($scope.selectedMode=SELECTION_MODE.NONE)}function getDefaultVLAN(fabric){return VLANsManager.getItemFromList(fabric.default_vlan_id)}function getUnusedVLANs(nic,ignoreVLANs){var vlans=$filter("removeDefaultVLAN")($scope.vlans);return vlans=$filter("filterByFabric")(vlans,nic.fabric),vlans=$filter("filterByUnusedForInterface")(vlans,nic,$scope.originalInterfaces),angular.isUndefined(ignoreVLANs)&&(ignoreVLANs=[]),angular.forEach(ignoreVLANs,function(vlan){var i;for(i=0;i<vlans.length;i++)if(vlans[i].id===vlan.id){vlans.splice(i,1);break}}),vlans}function getSelectedInterfaces(){var interfaces=[];return angular.forEach($scope.selectedInterfaces,function(key){var splitKey=key.split("/"),links=$scope.interfaceLinksMap[splitKey[0]];if(angular.isObject(links)){var nic=links[splitKey[1]];angular.isObject(nic)&&interfaces.push(nic)}}),interfaces}function getNextName(prefix){var idx=0;return angular.forEach($scope.originalInterfaces,function(nic){nic.name===prefix+idx&&idx++}),prefix+idx}$scope.ipAssignments=[{name:IP_ASSIGNMENT_EXTERNAL,text:"External"},{name:IP_ASSIGNMENT_DYNAMIC,text:"Dynamic"},{name:IP_ASSIGNMENT_STATIC,text:"Static"}],$scope.loaded=!1,$scope.nodeHasLoaded=!1,$scope.managersHaveLoaded=!1,$scope.tableInfo={column:"name"},$scope.fabrics=FabricsManager.getItems(),$scope.vlans=VLANsManager.getItems(),$scope.subnets=SubnetsManager.getItems(),$scope.interfaces=[],$scope.interfaceLinksMap={},$scope.interfaceErrorsByLinkId={},$scope.originalInterfaces={},$scope.selectedInterfaces=[],$scope.selectedMode=null,$scope.newInterface={},$scope.newBondInterface={},$scope.newBridgeInterface={},$scope.editInterface=null,$scope.bondOptions=GeneralManager.getData("bond_options"),$scope.modes=[{mode:LINK_MODE.AUTO,text:LINK_MODE_TEXTS[LINK_MODE.AUTO]},{mode:LINK_MODE.STATIC,text:LINK_MODE_TEXTS[LINK_MODE.STATIC]},{mode:LINK_MODE.DHCP,text:LINK_MODE_TEXTS[LINK_MODE.DHCP]},{mode:LINK_MODE.LINK_UP,text:LINK_MODE_TEXTS[LINK_MODE.LINK_UP]}],$scope.nodeLoaded=function(){$scope.$watch("node.interfaces",updateInterfaces),$scope.$parent.isController&&$scope.$watch("subnets",updateInterfaces,!0),$scope.nodeHasLoaded=!0,updateLoaded()},$scope.isLimitedEditingAllowed=function(nic){return!!$scope.isSuperUser()&&(!$scope.$parent.isController&&!$scope.$parent.isDevice&&(angular.isObject($scope.node)&&"Deployed"===$scope.node.status&&"vlan"!==nic.type))},$scope.isAllNetworkingDisabled=function(){return!$scope.isSuperUser()&&!$scope.$parent.isDevice||!$scope.$parent.isController&&!$scope.$parent.isDevice&&!(!angular.isObject($scope.node)||-1!==["New","Ready","Allocated","Broken"].indexOf($scope.node.status))},$scope.isBootInterface=function(nic){if(!angular.isObject(nic))return!1;if(nic.is_boot&&nic.type!==INTERFACE_TYPE.ALIAS)return!0;var i;if(nic.type===INTERFACE_TYPE.BOND||nic.type===INTERFACE_TYPE.BRIDGE)for(i=0;i<nic.members.length;i++)if(nic.members[i].is_boot)return!0;return!1},$scope.getInterfaceTypeText=function(nic){var text=INTERFACE_TYPE_TEXTS[nic.type];return angular.isDefined(text)?text:nic.type},$scope.getLinkModeText=function(nic){var text=LINK_MODE_TEXTS[nic.mode];return angular.isDefined(text)?text:nic.mode},$scope.getVLANText=function(vlan){return angular.isObject(vlan)?0===vlan.vid?"untagged":angular.isString(vlan.name)&&vlan.name.length>0?vlan.vid+" ("+vlan.name+")":vlan.vid:""},$scope.getSubnetText=function(subnet){return angular.isObject(subnet)?angular.isString(subnet.name)&&subnet.name.length>0&&subnet.cidr!==subnet.name?subnet.cidr+" ("+subnet.name+")":subnet.cidr:"Unconfigured"},$scope.getSubnet=function(subnetId){return SubnetsManager.getItemFromList(subnetId)},$scope.isInterfaceNameInvalid=function(nic){if(!angular.isObject(nic)||!nic.hasOwnProperty("name")||0===nic.name.length)return!0;var i;if(angular.isArray($scope.node.interfaces))for(i=0;i<$scope.node.interfaces.length;i++){var otherNic=$scope.node.interfaces[i];if(otherNic.name===nic.name&&otherNic.id!==nic.id)return!0}return!1},$scope.isLinkModeDisabled=function(nic){return angular.isFunction(nic.getValue)?!angular.isObject(nic.getValue("subnet")):!angular.isObject(nic.subnet)},$scope.getInterfaceError=function(nic){return angular.isDefined(nic.link_id)&&nic.link_id>=0?$scope.interfaceErrorsByLinkId[nic.link_id]:null},$scope.isIPAddressInvalid=function(nic){return!(!angular.isString(nic.ip_address)||"static"!==nic.mode)&&(!ValidationService.validateIP(nic.ip_address)||!ValidationService.validateIPInNetwork(nic.ip_address,nic.subnet.cidr))},$scope.getUniqueKey=function(nic){return nic.id+"/"+nic.link_id},$scope.toggleInterfaceSelect=function(nic){var key=$scope.getUniqueKey(nic),idx=$scope.selectedInterfaces.indexOf(key);idx>-1?$scope.selectedInterfaces.splice(idx,1):$scope.selectedInterfaces.push(key),$scope.selectedInterfaces.length>1?$scope.selectedMode!==SELECTION_MODE.BOND&&($scope.selectedMode=SELECTION_MODE.MULTI):1===$scope.selectedInterfaces.length?$scope.selectedMode=SELECTION_MODE.SINGLE:$scope.selectedMode=SELECTION_MODE.NONE},$scope.isInterfaceSelected=function(nic){return $scope.selectedInterfaces.indexOf($scope.getUniqueKey(nic))>-1},$scope.cannotEditInterface=function(nic){return $scope.selectedMode!==SELECTION_MODE.NONE&&($scope.selectedMode===SELECTION_MODE.MULTI||!$scope.isInterfaceSelected(nic))},$scope.isEditing=function(nic){return $scope.selectedMode===SELECTION_MODE.EDIT&&$scope.editInterface.id===nic.id},$scope.edit=function(nic){$scope.selectedInterfaces=[$scope.getUniqueKey(nic)],$scope.selectedMode=SELECTION_MODE.EDIT,$scope.$parent.isDevice?($scope.editInterface={id:nic.id,name:nic.name,mac_address:nic.mac_address,tags:nic.tags.map(function(tag){return tag.text}),subnet:nic.subnet,ip_address:nic.ip_address,ip_assignment:nic.ip_assignment,link_id:nic.link_id},void 0!==nic.subnet&&null!==nic.subnet?$scope.editInterface.defaultSubnet=nic.subnet:$scope.editInterface.defaultSubnet=$scope.subnets[0]):$scope.editInterface={id:nic.id,name:nic.name,mac_address:nic.mac_address,tags:nic.tags.map(function(tag){return tag.text}),fabric:nic.fabric,vlan:nic.vlan,subnet:nic.subnet,mode:nic.mode,ip_address:nic.ip_address,link_id:nic.link_id}},$scope.fabricChanged=function(nic){null!==nic.fabric?nic.vlan=getDefaultVLAN(nic.fabric):nic.vlan=null,$scope.vlanChanged(nic)},$scope.fabricChangedForm=function(key,value,form){var vlan;vlan=null!==value?getDefaultVLAN(value):null,form.updateValue("vlan",vlan),$scope.vlanChangedForm("vlan",vlan,form)},$scope.vlanChanged=function(nic){nic.subnet=null,$scope.subnetChanged(nic)},$scope.vlanChangedForm=function(key,value,form){form.updateValue("subnet",null),$scope.subnetChangedForm("subnet",null,form)},$scope.subnetChanged=function(nic){angular.isObject(nic.subnet)||(nic.mode=LINK_MODE.LINK_UP),$scope.$parent.isDevice&&(nic.ip_address=null),$scope.modeChanged(nic)},$scope.subnetChangedForm=function(key,value,form){angular.isObject(value)||form.updateValue("mode",LINK_MODE.LINK_UP),mode=form.getValue("mode"),form.updateValue("ip_address",null),$scope.modeChangedForm("mode",mode,form)},$scope.modeChanged=function(nic){if(nic.ip_address="","static"===nic.mode){var originalLink=mapNICToOriginalLink(nic.id,nic.link_id);angular.isObject(originalLink)&&nic.subnet.id===originalLink.subnet_id&&(nic.ip_address=originalLink.ip_address)}},$scope.modeChangedForm=function(key,value,form){if(form.updateValue("ip_address",""),"static"===value){var originalLink=mapNICToOriginalLink(form.getValue("id"),form.getValue("link_id"));angular.isObject(originalLink)&&form.getValue("subnet").id===originalLink.subnet_id&&form.updateValue("ip_address",originalLink.ip_address)}},$scope.editCancel=function(nic){$scope.selectedInterfaces=[],$scope.selectedMode=SELECTION_MODE.NONE,$scope.editInterface=null},$scope.preProcessInterface=function(nic){var params=angular.copy(nic);return delete params.id,params.system_id=$scope.node.system_id,params.interface_id=nic.id,void 0!==nic.fabric&&null!==nic.fabric?params.fabric=nic.fabric.id:params.fabric=null,void 0!==nic.vlan&&null!==nic.vlan?params.vlan=nic.vlan.id:params.vlan=null,void 0!==nic.subnet&&null!==nic.subnet?params.subnet=params.subnet.id:delete params.subnet,angular.isDefined(nic.link_id)&&nic.link_id>=0?(params.link_id=nic.link_id,delete $scope.interfaceErrorsByLinkId[nic.link_id]):delete params.link_id,(nic.mode===LINK_MODE.STATIC||nic.ip_assignment!==IP_ASSIGNMENT_DYNAMIC)&&angular.isString(nic.ip_address)&&nic.ip_address.length>0?params.ip_address=nic.ip_address:delete params.ip_address,params},$scope.saveInterface=function(nic){var params;return params=$scope.$parent.isDevice?{name:nic.name,mac_address:nic.mac_address,ip_assignment:nic.ip_assignment,ip_address:nic.ip_address}:{name:nic.name,mac_address:nic.mac_address,mode:nic.mode,tags:nic.tags.map(function(tag){return tag.text})},void 0!==nic.fabric&&null!==nic.fabric?params.fabric=nic.fabric.id:params.fabric=null,void 0!==nic.vlan&&null!==nic.vlan?params.vlan=nic.vlan.id:params.vlan=null,void 0!==nic.subnet&&null!==nic.subnet?params.subnet=nic.subnet.id:params.subnet=null,angular.isDefined(nic.link_id)&&nic.link_id>=0&&(params.link_id=nic.link_id,delete $scope.interfaceErrorsByLinkId[nic.link_id]),angular.isString(nic.ip_address)&&nic.ip_address.length>0&&(params.ip_address=nic.ip_address),$scope.$parent.nodesManager.updateInterface($scope.node,nic.id,params).then(null,function(error){console.log(error),updateInterfaces()})},$scope.saveInterfaceLink=function(nic){var params={mode:nic.mode};return $scope.$parent.isDevice&&(params.ip_assignment=nic.ip_assignment),angular.isObject(nic.subnet)&&(params.subnet=nic.subnet.id),angular.isDefined(nic.link_id)&&nic.link_id>=0&&(params.link_id=nic.link_id,delete $scope.interfaceErrorsByLinkId[nic.link_id]),nic.mode===LINK_MODE.STATIC&&angular.isString(nic.ip_address)&&nic.ip_address.length>0&&(params.ip_address=nic.ip_address),$scope.$parent.nodesManager.linkSubnet($scope.node,nic.id,params).then(null,function(error){throw console.log(error),angular.isDefined(nic.link_id)&&nic.link_id>=0&&($scope.interfaceErrorsByLinkId[nic.link_id]=error),updateInterfaces(),error})},$scope.editSave=function(editInterface){return $scope.editCancel(),editInterface},$scope.isShowingDeleteConfirm=function(){return $scope.selectedMode===SELECTION_MODE.DELETE},$scope.isShowingAdd=function(){return $scope.selectedMode===SELECTION_MODE.ADD},$scope.canAddAliasOrVLAN=function(nic){return!$scope.$parent.isController&&(!$scope.isAllNetworkingDisabled()&&($scope.canAddAlias(nic)||$scope.canAddVLAN(nic)))},$scope.canAddAlias=function(nic){return!!angular.isObject(nic)&&(nic.type!==INTERFACE_TYPE.ALIAS&&(0!==nic.links.length&&nic.links[0].mode!==LINK_MODE.LINK_UP))},$scope.canAddVLAN=function(nic){return!!angular.isObject(nic)&&(nic.type!==INTERFACE_TYPE.ALIAS&&nic.type!==INTERFACE_TYPE.VLAN&&getUnusedVLANs(nic).length>0)},$scope.canAddAnotherVLAN=function(nic){return!!$scope.canAddVLAN(nic)&&getUnusedVLANs(nic).length>1},$scope.getRemoveTypeText=function(nic){return nic.type===INTERFACE_TYPE.PHYSICAL?"interface":nic.type===INTERFACE_TYPE.VLAN?"VLAN":nic.type},$scope.canBeRemoved=function(){return!$scope.$parent.isController&&!$scope.isAllNetworkingDisabled()},$scope.remove=function(){$scope.selectedMode=SELECTION_MODE.DELETE},$scope.quickRemove=function(nic){$scope.selectedInterfaces=[$scope.getUniqueKey(nic)],$scope.remove()},$scope.cancel=function(){$scope.newInterface={},$scope.newBondInterface={},$scope.newBridgeInterface={},$scope.selectedMode===SELECTION_MODE.CREATE_BOND?$scope.selectedMode=SELECTION_MODE.MULTI:$scope.selectedMode===SELECTION_MODE.CREATE_PHYSICAL?$scope.selectedMode=SELECTION_MODE.NONE:$scope.selectedMode=SELECTION_MODE.SINGLE},$scope.confirmRemove=function(nic){$scope.selectedMode=SELECTION_MODE.NONE,$scope.selectedInterfaces=[],nic.type!==INTERFACE_TYPE.ALIAS?$scope.$parent.nodesManager.deleteInterface($scope.node,nic.id):$scope.$parent.nodesManager.unlinkSubnet($scope.node,nic.id,nic.link_id);var idx=$scope.interfaces.indexOf(nic);idx>-1&&$scope.interfaces.splice(idx,1)},$scope.add=function(type,nic){var ignoreVLANs=[];angular.isObject($scope.newInterface.vlan)&&ignoreVLANs.push($scope.newInterface.vlan);var vlans=getUnusedVLANs(nic,ignoreVLANs),defaultVLAN=null;vlans.length>0&&(defaultVLAN=vlans[0]);var defaultSubnet=null,defaultMode=LINK_MODE.LINK_UP;type===INTERFACE_TYPE.ALIAS&&(defaultVLAN=nic.vlan,defaultSubnet=$filter("filter")($scope.subnets,{vlan:defaultVLAN.id},!0)[0],defaultMode=LINK_MODE.AUTO),$scope.newInterface={type:type,vlan:defaultVLAN,subnet:defaultSubnet,mode:defaultMode,parent:nic,tags:[]},$scope.selectedMode=SELECTION_MODE.ADD},$scope.quickAdd=function(nic){$scope.selectedInterfaces=[$scope.getUniqueKey(nic)];var type="alias";$scope.canAddAlias(nic)||(type="vlan"),$scope.add(type,nic)},$scope.getAddName=function(){if($scope.newInterface.type===INTERFACE_TYPE.ALIAS){var aliasIdx=$scope.newInterface.parent.links.length;return $scope.newInterface.parent.name+":"+aliasIdx}if($scope.newInterface.type===INTERFACE_TYPE.VLAN)return $scope.newInterface.parent.name+"."+$scope.newInterface.vlan.vid},$scope.addTypeChanged=function(){if($scope.newInterface.type===INTERFACE_TYPE.ALIAS)$scope.newInterface.vlan=$scope.newInterface.parent.vlan,$scope.newInterface.subnet=$filter("filter")($scope.subnets,{vlan:$scope.newInterface.vlan.id},!0)[0],$scope.newInterface.mode=LINK_MODE.AUTO;else if($scope.newInterface.type===INTERFACE_TYPE.VLAN){var vlans=getUnusedVLANs($scope.newInterface.parent);$scope.newInterface.vlan=null,vlans.length>0&&($scope.newInterface.vlan=vlans[0]),$scope.newInterface.subnet=null,$scope.newInterface.mode=LINK_MODE.LINK_UP}},$scope.addInterface=function(type){var nic;if($scope.$parent.isDevice)nic={id:$scope.newInterface.parent.id,tags:$scope.newInterface.tags.map(function(tag){return tag.text}),ip_assignment:$scope.newInterface.ip_assignment,subnet:$scope.newInterface.subnet,ip_address:$scope.newInterface.ip_address},$scope.saveInterfaceLink(nic);else if($scope.newInterface.type===INTERFACE_TYPE.ALIAS)nic={id:$scope.newInterface.parent.id,mode:$scope.newInterface.mode,subnet:$scope.newInterface.subnet,ip_address:$scope.newInterface.ip_address},$scope.saveInterfaceLink(nic);else if($scope.newInterface.type===INTERFACE_TYPE.VLAN){var params={parent:$scope.newInterface.parent.id,vlan:$scope.newInterface.vlan.id,mode:$scope.newInterface.mode,tags:$scope.newInterface.tags.map(function(tag){return tag.text})};angular.isObject($scope.newInterface.subnet)&&(params.subnet=$scope.newInterface.subnet.id,params.ip_address=$scope.newInterface.ip_address),$scope.$parent.nodesManager.createVLANInterface($scope.node,params).then(null,function(error){console.log(error)})}angular.isString(type)?$scope.add(type,$scope.newInterface.parent):($scope.selectedMode=SELECTION_MODE.NONE,$scope.selectedInterfaces=[],$scope.newInterface={})},$scope.isDisabled=function(){return!!$scope.isAllNetworkingDisabled()||$scope.selectedMode!==SELECTION_MODE.NONE&&$scope.selectedMode!==SELECTION_MODE.SINGLE&&$scope.selectedMode!==SELECTION_MODE.MULTI},$scope.canCreateBond=function(){if($scope.selectedMode!==SELECTION_MODE.MULTI)return!1;var i,vlan,interfaces=getSelectedInterfaces();for(i=0;i<interfaces.length;i++){var nic=interfaces[i];if(nic.type===INTERFACE_TYPE.ALIAS||nic.type===INTERFACE_TYPE.BOND)return!1;if(angular.isObject(vlan)){if(vlan!==nic.vlan)return!1}else vlan=nic.vlan}return!0},$scope.isShowingCreateBond=function(){return $scope.selectedMode===SELECTION_MODE.CREATE_BOND},$scope.showCreateBond=function(){if($scope.selectedMode===SELECTION_MODE.MULTI&&$scope.canCreateBond()){$scope.selectedMode=SELECTION_MODE.CREATE_BOND;var parents=getSelectedInterfaces();$scope.newBondInterface={name:getNextName("bond"),tags:[],parents:parents,primary:parents[0],mac_address:"",mode:"active-backup",lacpRate:"slow",xmitHashPolicy:"layer2"}}},$scope.hasBootInterface=function(nic){if(!angular.isArray(nic.parents))return!1;var i;for(i=0;i<nic.parents.length;i++)if(nic.parents[i].is_boot)return!0;return!1},$scope.getInterfacePlaceholderMACAddress=function(nic){return angular.isObject(nic.primary)?nic.primary.mac_address:""},$scope.isMACAddressInvalid=function(mac_address,invalidEmpty){return angular.isUndefined(invalidEmpty)&&(invalidEmpty=!1),angular.isString(mac_address)&&""!==mac_address?!ValidationService.validateMAC(mac_address):invalidEmpty},$scope.showLACPRate=function(){return"802.3ad"===$scope.newBondInterface.mode},$scope.showXMITHashPolicy=function(){return"balance-xor"===$scope.newBondInterface.mode||"802.3ad"===$scope.newBondInterface.mode||"balance-tlb"===$scope.newBondInterface.mode},$scope.cannotAddBond=function(){return $scope.isInterfaceNameInvalid($scope.newBondInterface)||$scope.isMACAddressInvalid($scope.newBondInterface.mac_address)},$scope.addBond=function(){if(!$scope.cannotAddBond()){var parents=$scope.newBondInterface.parents.map(function(nic){return nic.id}),mac_address=$scope.newBondInterface.mac_address;""===mac_address&&(mac_address=$scope.newBondInterface.primary.mac_address);var vlan_id,vlan=$scope.newBondInterface.primary.vlan;vlan_id=angular.isObject(vlan)?vlan.id:null;var params={name:$scope.newBondInterface.name,mac_address:mac_address,tags:$scope.newBondInterface.tags.map(function(tag){return tag.text}),parents:parents,vlan:vlan_id,bond_mode:$scope.newBondInterface.mode,bond_lacp_rate:$scope.newBondInterface.lacpRate,bond_xmit_hash_policy:$scope.newBondInterface.xmitHashPolicy};$scope.$parent.nodesManager.createBondInterface($scope.node,params).then(null,function(error){console.log(error)}),angular.forEach($scope.newBondInterface.parents,function(parent){var idx=$scope.interfaces.indexOf(parent);idx>-1&&$scope.interfaces.splice(idx,1)}),$scope.newBondInterface={},$scope.selectedInterfaces=[],$scope.selectedMode=SELECTION_MODE.NONE}},$scope.canCreateBridge=function(){if($scope.selectedMode!==SELECTION_MODE.SINGLE)return!1;var nic=getSelectedInterfaces()[0];return nic.type!==INTERFACE_TYPE.ALIAS&&nic.type!==INTERFACE_TYPE.BRIDGE},$scope.isShowingCreateBridge=function(){return $scope.selectedMode===SELECTION_MODE.CREATE_BRIDGE},$scope.showCreateBridge=function(){if($scope.selectedMode===SELECTION_MODE.SINGLE&&$scope.canCreateBridge()){$scope.selectedMode=SELECTION_MODE.CREATE_BRIDGE;var parents=getSelectedInterfaces();$scope.newBridgeInterface={name:getNextName("br"),tags:[],parents:parents,primary:parents[0],mac_address:"",bridge_stp:!1,bridge_fd:15}}},$scope.cannotAddBridge=function(){return $scope.isInterfaceNameInvalid($scope.newBridgeInterface)||$scope.isMACAddressInvalid($scope.newBridgeInterface.mac_address)},$scope.addBridge=function(){if(!$scope.cannotAddBridge()){var parents=[$scope.newBridgeInterface.primary.id],mac_address=$scope.newBridgeInterface.mac_address;""===mac_address&&(mac_address=$scope.newBridgeInterface.primary.mac_address);var params={name:$scope.newBridgeInterface.name,mac_address:mac_address,tags:$scope.newBridgeInterface.tags.map(function(tag){return tag.text}),parents:parents,vlan:$scope.newBridgeInterface.primary.vlan.id,bridge_stp:$scope.newBridgeInterface.bridge_stp,bridge_fd:$scope.newBridgeInterface.bridge_fd};$scope.$parent.nodesManager.createBridgeInterface($scope.node,params).then(null,function(error){console.log(error)});var idx=$scope.interfaces.indexOf($scope.newBridgeInterface.primary);idx>-1&&$scope.interfaces.splice(idx,1),$scope.newBridgeInterface={},$scope.selectedInterfaces=[],$scope.selectedMode=SELECTION_MODE.NONE}},$scope.isShowingCreatePhysical=function(){return $scope.selectedMode===SELECTION_MODE.CREATE_PHYSICAL},$scope.showCreatePhysical=function(){$scope.selectedMode===SELECTION_MODE.NONE&&($scope.selectedMode=SELECTION_MODE.CREATE_PHYSICAL,$scope.$parent.isDevice?$scope.newInterface={name:getNextName("eth"),mac_address:"",macError:!1,tags:[],errorMsg:null,subnet:null,ip_assignment:IP_ASSIGNMENT_DYNAMIC}:$scope.newInterface={name:getNextName("eth"),mac_address:"",macError:!1,tags:[],errorMsg:null,fabric:$scope.fabrics[0],vlan:getDefaultVLAN($scope.fabrics[0]),subnet:null,mode:LINK_MODE.LINK_UP})},$scope.cannotAddPhysicalInterface=function(){return $scope.isInterfaceNameInvalid($scope.newInterface)||$scope.isMACAddressInvalid($scope.newInterface.mac_address,!0)},$scope.addPhysicalInterface=function(){var params;$scope.cannotAddPhysicalInterface()||(params=$scope.$parent.isDevice?{name:$scope.newInterface.name,mac_address:$scope.newInterface.mac_address,tags:$scope.newInterface.tags.map(function(tag){return tag.text}),ip_assignment:$scope.newInterface.ip_assignment,ip_address:$scope.newInterface.ip_address}:{name:$scope.newInterface.name,tags:$scope.newInterface.tags.map(function(tag){return tag.text}),mac_address:$scope.newInterface.mac_address,vlan:$scope.newInterface.vlan.id,mode:$scope.newInterface.mode},angular.isObject($scope.newInterface.subnet)&&(params.subnet=$scope.newInterface.subnet.id),$scope.newInterface.macError=!1,$scope.newInterface.errorMsg=null,$scope.$parent.nodesManager.createPhysicalInterface($scope.node,params).then(function(){$scope.newInterface={},$scope.selectedMode=SELECTION_MODE.NONE},function(errorStr){error=JSONService.tryParse(errorStr),angular.isObject(error)?(macError=error.mac_address,angular.isArray(macError)&&($scope.newInterface.macError=!0,$scope.newInterface.errorMsg=macError[0])):console.log(errorStr)}))},ManagerHelperService.loadManagers($scope,[FabricsManager,VLANsManager,SubnetsManager,UsersManager,ControllersManager]).then(function(){$scope.managersHaveLoaded=!0,updateLoaded()}),$scope.$parent.controllerLoaded("networkingController",$scope)}])},"./src/maasserver/static/js/angular/controllers/node_details_storage.js":function(module,exports){angular.module("MAAS").filter("removeAvailableByNew",function(){return function(disks,availableNew){if(!angular.isObject(availableNew)||!angular.isObject(availableNew.device)&&!angular.isArray(availableNew.devices))return disks;var filtered=[],single=!0;return angular.isArray(availableNew.devices)&&(single=!1),angular.forEach(disks,function(disk){if(single)disk!==availableNew.device&&filtered.push(disk);else{var i,found=!1;for(i=0;i<availableNew.devices.length;i++)if(disk===availableNew.devices[i]){found=!0;break}found||filtered.push(disk)}}),filtered}}),angular.module("MAAS").controller("NodeStorageController",["$scope","MachinesManager","ConverterService","UsersManager",function($scope,MachinesManager,ConverterService,UsersManager){var MIN_PARTITION_SIZE=4194304,SELECTION_MODE={NONE:null,SINGLE:"single",MUTLI:"multi",UNMOUNT:"unmount",UNFORMAT:"unformat",EDIT:"edit",DELETE:"delete",FORMAT_AND_MOUNT:"format-mount",PARTITION:"partition",BCACHE:"bcache",RAID:"raid",VOLUME_GROUP:"volume-group",LOGICAL_VOLUME:"logical-volume"},RAID_MODES=[{level:"raid-0",title:"RAID 0",min_disks:2,allows_spares:!1,calculateSize:function(minSize,numDisks){return minSize*numDisks}},{level:"raid-1",title:"RAID 1",min_disks:2,allows_spares:!0,calculateSize:function(minSize,numDisks){return minSize}},{level:"raid-5",title:"RAID 5",min_disks:3,allows_spares:!0,calculateSize:function(minSize,numDisks){return minSize*(numDisks-1)}},{level:"raid-6",title:"RAID 6",min_disks:4,allows_spares:!0,calculateSize:function(minSize,numDisks){return minSize*(numDisks-2)}},{level:"raid-10",title:"RAID 10",min_disks:3,allows_spares:!0,calculateSize:function(minSize,numDisks){return minSize*numDisks/2}}];function hasMountedFilesystem(item){return angular.isObject(item)&&(filesystem=item.filesystem,angular.isObject(filesystem)&&angular.isString(filesystem.mount_point)&&""!==filesystem.mount_point);var filesystem}function hasFormattedUnmountedFilesystem(item){return angular.isObject(item.filesystem)&&angular.isString(item.filesystem.fstype)&&""!==item.filesystem.fstype&&(!1===angular.isString(item.filesystem.mount_point)||""===item.filesystem.mount_point)?item.filesystem.fstype:null}function isInUse(item){return"cache-set"===item.type||(angular.isObject(item.filesystem)?!(!item.filesystem.is_format_fstype||!angular.isString(item.filesystem.mount_point)||""===item.filesystem.mount_point)||!item.filesystem.is_format_fstype:item.available_size<MIN_PARTITION_SIZE)}function getTags(disk){var tags=[];return angular.forEach(disk.tags,function(tag){tags.push({text:tag})}),tags}function getUniqueKey(disk){if("cache-set"===disk.type)return"cache-set-"+disk.cache_set_id;var key=disk.type+"-"+disk.block_id;return angular.isNumber(disk.partition_id)&&(key+="-"+disk.partition_id),key}function updateDisks(){var used,cachesets,filesystems;angular.isArray($scope.node.disks)?($scope.has_disks=$scope.node.disks.length>0,filesystems=[],angular.forEach($scope.node.disks,function(disk){if(hasMountedFilesystem(disk)){var data={type:"filesystem",name:disk.name,size_human:disk.size_human,fstype:disk.filesystem.fstype,mount_point:disk.filesystem.mount_point,mount_options:disk.filesystem.mount_options,block_id:disk.id,partition_id:null,filesystem_id:disk.filesystem.id,original_type:disk.type,original:disk};"virtual"===disk.type&&(disk.parent_type=disk.parent.type),filesystems.push(data)}angular.forEach(disk.partitions,function(partition){hasMountedFilesystem(partition)&&filesystems.push({type:"filesystem",name:partition.name,size_human:partition.size_human,fstype:partition.filesystem.fstype,mount_point:partition.filesystem.mount_point,mount_options:partition.filesystem.mount_options,block_id:disk.id,partition_id:partition.id,filesystem_id:partition.filesystem.id,original_type:"partition",original:partition})})}),angular.forEach($scope.node.special_filesystems,function(filesystem){filesystems.push({type:"filesystem",name:"—",size_human:"—",fstype:filesystem.fstype,mount_point:filesystem.mount_point,mount_options:filesystem.mount_options,block_id:null,partition_id:null,original_type:"special"})}),angular.forEach(filesystems,function(filesystem){var key=getUniqueKey(filesystem),oldFilesystem=$scope.filesystemsMap[key];angular.isObject(oldFilesystem)?filesystem.$selected=oldFilesystem.$selected:filesystem.$selected=!1}),$scope.filesystems=filesystems,$scope.filesystemsMap={},angular.forEach(filesystems,function(filesystem){$scope.filesystemsMap[getUniqueKey(filesystem)]=filesystem}),$scope.updateFilesystemSelection(!1),cachesets=[],angular.forEach($scope.node.disks,function(disk){"cache-set"===disk.type&&cachesets.push({type:"cache-set",name:disk.name,size_human:disk.size_human,cache_set_id:disk.id,used_by:disk.used_for})}),angular.forEach(cachesets,function(cacheset){var key=getUniqueKey(cacheset),oldCacheSet=$scope.cachesetsMap[key];angular.isObject(oldCacheSet)?cacheset.$selected=oldCacheSet.$selected:cacheset.$selected=!1}),$scope.cachesets=cachesets,$scope.cachesetsMap={},angular.forEach(cachesets,function(cacheset){$scope.cachesetsMap[getUniqueKey(cacheset)]=cacheset}),$scope.updateCacheSetsSelection(!1),function(){var available=[];if(angular.forEach($scope.node.disks,function(disk){if(!isInUse(disk)){var has_partitions=!1;angular.isArray(disk.partitions)&&disk.partitions.length>0&&(has_partitions=!0);var data={name:disk.name,size_human:disk.size_human,available_size_human:disk.available_size_human,used_size_human:disk.used_size_human,type:disk.type,model:disk.model,serial:disk.serial,tags:getTags(disk),fstype:hasFormattedUnmountedFilesystem(disk),mount_point:null,mount_options:null,block_id:disk.id,partition_id:null,has_partitions:has_partitions,is_boot:disk.is_boot,original:disk,test_status:disk.test_status,firmware_version:disk.firmware_version};"virtual"===disk.type&&(data.parent_type=disk.parent.type),available.push(data)}angular.forEach(disk.partitions,function(partition){isInUse(partition)||available.push({name:partition.name,size_human:partition.size_human,available_size_human:partition.available_size_human,used_size_human:partition.used_size_human,type:"partition",model:"",serial:"",tags:[],fstype:hasFormattedUnmountedFilesystem(partition),mount_point:null,mount_options:null,block_id:disk.id,partition_id:partition.id,has_partitions:!1,is_boot:!1,original:partition})})}),angular.forEach(available,function(disk){var key=getUniqueKey(disk),oldDisk=$scope.availableMap[key];angular.isObject(oldDisk)?(disk.$selected=oldDisk.$selected,disk.$options=oldDisk.$options):(disk.$selected=!1,disk.$options={})}),$scope.available=available,$scope.availableMap={},angular.forEach(available,function(disk){$scope.availableMap[getUniqueKey(disk)]=disk}),angular.isObject($scope.availableNew))if(angular.isObject($scope.availableNew.device)){var key=getUniqueKey($scope.availableNew.device);$scope.availableNew.device=$scope.availableMap[key]}else if(angular.isArray($scope.availableNew.devices)){var newDevices=[];angular.forEach($scope.availableNew.devices,function(device){var key=getUniqueKey(device),newDevice=$scope.availableMap[key];angular.isObject(newDevice)&&newDevices.push(newDevice)}),$scope.availableNew.devices=newDevices}$scope.updateAvailableSelection(!1)}(),used=[],angular.forEach($scope.node.disks,function(disk){if(isInUse(disk)&&"cache-set"!==disk.type){var has_partitions=!1;angular.isArray(disk.partitions)&&disk.partitions.length>0&&(has_partitions=!0);var data={name:disk.name,type:disk.type,model:disk.model,serial:disk.serial,tags:getTags(disk),used_for:disk.used_for,is_boot:disk.is_boot,has_partitions:has_partitions,test_status:disk.test_status,firmware_version:disk.firmware_version};"virtual"===disk.type&&(data.parent_type=disk.parent.type),used.push(data)}angular.forEach(disk.partitions,function(partition){isInUse(partition)&&"cache-set"!==partition.type&&used.push({name:partition.name,type:"partition",model:"",serial:"",tags:[],used_for:partition.used_for,is_boot:!1})})}),$scope.used=used):($scope.has_disks=!1,$scope.filesystems=[],$scope.filesystemsMap={},$scope.filesystemMode=SELECTION_MODE.NONE,$scope.filesystemAllSelected=!1,$scope.cachesets=[],$scope.cachesetsMap={},$scope.cachesetsMode=SELECTION_MODE.NONE,$scope.cachesetsAllSelected=!1,$scope.available=[],$scope.availableMap={},$scope.availableMode=SELECTION_MODE.NONE,$scope.availableAllSelected=!1,$scope.availableNew={},$scope.used=[])}function deselectAll(items){angular.forEach(items,function(item){item.$selected=!1})}function capitalizeFirstLetter(string){return string.charAt(0).toUpperCase()+string.slice(1)}function getIndexFromName(prefix,name){var match=new RegExp("^"+prefix+"([0-9]+)$").exec(name);if(angular.isArray(match)&&2===match.length)return parseInt(match[1],10)}function getNextName(prefix){var idx=-1;return angular.forEach($scope.node.disks,function(disk){var dIdx=getIndexFromName(prefix,disk.name);angular.isNumber(dIdx)&&(idx=Math.max(idx,dIdx)),angular.forEach(disk.partitions,function(partition){dIdx=getIndexFromName(prefix,partition.name),angular.isNumber(dIdx)&&(idx=Math.max(idx,dIdx))})}),prefix+(idx+1)}function isNameAlreadyInUse(name,exclude_disk){if(!angular.isArray($scope.node.disks))return!1;var i,j;for(i=0;i<$scope.node.disks.length;i++){var disk=$scope.node.disks[i];if(disk.name===name&&(!angular.isObject(exclude_disk)||"partition"===exclude_disk.type||exclude_disk.block_id!==disk.id))return!0;if(angular.isArray(disk.partitions))for(j=0;j<disk.partitions.length;j++){var partition=disk.partitions[j];if(partition.name===name&&(!angular.isObject(exclude_disk)||"partition"!==exclude_disk.type||exclude_disk.partition_id!==partition.id))return!0}}return!1}function isLogicalVolume(disk){return"virtual"===disk.type&&"lvm-vg"===disk.parent_type}$scope.tableInfo={column:"name"},$scope.has_disks=!1,$scope.filesystems=[],$scope.filesystemsMap={},$scope.filesystemMode=SELECTION_MODE.NONE,$scope.filesystemAllSelected=!1,$scope.cachesets=[],$scope.cachesetsMap={},$scope.cachesetsMode=SELECTION_MODE.NONE,$scope.cachesetsAllSelected=!1,$scope.available=[],$scope.availableMap={},$scope.availableMode=SELECTION_MODE.NONE,$scope.availableAllSelected=!1,$scope.availableNew={},$scope.used=[],$scope.showMembers=[],$scope.nodeLoaded=function(){$scope.$watch("node.disks",updateDisks)},$scope.isBootDiskDisabled=function(item,section){return!$scope.isSuperUser()||(!(!angular.isObject($scope.node)||-1!==["Ready","Allocated"].indexOf($scope.node.status))||("physical"!==item.type||"used"===section&&!item.has_partitions))},$scope.setAsBootDisk=function(item){item.is_boot||$scope.isBootDiskDisabled(item)||MachinesManager.setBootDisk($scope.node,item.block_id)},$scope.getSelectedFilesystems=function(){var filesystems=[];return angular.forEach($scope.filesystems,function(filesystem){filesystem.$selected&&filesystems.push(filesystem)}),filesystems},$scope.updateFilesystemSelection=function(force){angular.isUndefined(force)&&(force=!1);var filesystems=$scope.getSelectedFilesystems();0===filesystems.length?$scope.filesystemMode=SELECTION_MODE.NONE:1===filesystems.length&&force?$scope.filesystemMode=SELECTION_MODE.SINGLE:force&&($scope.filesystemMode=SELECTION_MODE.MUTLI),0===$scope.filesystems.length?$scope.filesystemAllSelected=!1:filesystems.length===$scope.filesystems.length?$scope.filesystemAllSelected=!0:$scope.filesystemAllSelected=!1},$scope.toggleFilesystemSelect=function(filesystem){filesystem.$selected=!filesystem.$selected,$scope.updateFilesystemSelection(!0)},$scope.toggleFilesystemAllSelect=function(){angular.forEach($scope.filesystems,function(filesystem){$scope.filesystemAllSelected?filesystem.$selected=!1:filesystem.$selected=!0}),$scope.updateFilesystemSelection(!0)},$scope.isFilesystemsDisabled=function(){return $scope.filesystemMode!==SELECTION_MODE.NONE&&$scope.filesystemMode!==SELECTION_MODE.SINGLE&&$scope.filesystemMode!==SELECTION_MODE.MUTLI||$scope.isAllStorageDisabled()},$scope.filesystemCancel=function(){deselectAll($scope.filesystems),$scope.updateFilesystemSelection(!0)},$scope.filesystemUnmount=function(){$scope.filesystemMode=SELECTION_MODE.UNMOUNT},$scope.quickFilesystemUnmount=function(filesystem){deselectAll($scope.filesystems),filesystem.$selected=!0,$scope.updateFilesystemSelection(!0),$scope.filesystemUnmount()},$scope.filesystemConfirmUnmount=function(filesystem){MachinesManager.updateFilesystem($scope.node,filesystem.block_id,filesystem.partition_id,filesystem.fstype,null,null);var idx=$scope.filesystems.indexOf(filesystem);$scope.filesystems.splice(idx,1),$scope.updateFilesystemSelection()},$scope.filesystemDelete=function(){$scope.filesystemMode=SELECTION_MODE.DELETE},$scope.quickFilesystemDelete=function(filesystem){deselectAll($scope.filesystems),filesystem.$selected=!0,$scope.updateFilesystemSelection(!0),$scope.filesystemDelete()},$scope.filesystemConfirmDelete=function(filesystem){"special"===filesystem.original_type?MachinesManager.unmountSpecialFilesystem($scope.node,filesystem.mount_point):"partition"===filesystem.original_type?MachinesManager.deletePartition($scope.node,filesystem.original.id):MachinesManager.deleteFilesystem($scope.node,filesystem.block_id,filesystem.partition_id,filesystem.filesystem_id);var idx=$scope.filesystems.indexOf(filesystem);$scope.filesystems.splice(idx,1),$scope.updateFilesystemSelection()},$scope.hasUnmountedFilesystem=function(disk){return!(!angular.isString(disk.fstype)||""===disk.fstype||angular.isString(disk.mount_point)&&""!==disk.mount_point)},$scope.showFreeSpace=function(disk){return"lvm-vg"===disk.type||("physical"===disk.type||"virtual"===disk.type)&&disk.has_partitions},$scope.getDeviceType=function(disk){return angular.isUndefined(disk)?"":"virtual"===disk.type?"lvm-vg"===disk.parent_type?"Logical volume":0===disk.parent_type.indexOf("raid-")?"RAID "+disk.parent_type.split("-")[1]:capitalizeFirstLetter(disk.parent_type):"lvm-vg"===disk.type?"Volume group":capitalizeFirstLetter(disk.type)},$scope.getSelectedAvailable=function(){var available=[];return angular.forEach($scope.available,function(disk){disk.$selected&&available.push(disk)}),available},$scope.updateAvailableSelection=function(force){angular.isUndefined(force)&&(force=!1);var available=$scope.getSelectedAvailable();0===available.length?$scope.availableMode=SELECTION_MODE.NONE:1===available.length&&force?$scope.availableMode=SELECTION_MODE.SINGLE:force&&($scope.availableMode=SELECTION_MODE.MUTLI),0===$scope.available.length?$scope.availableAllSelected=!1:available.length===$scope.available.length?$scope.availableAllSelected=!0:$scope.availableAllSelected=!1},$scope.toggleAvailableSelect=function(disk){disk.$selected=!disk.$selected,$scope.updateAvailableSelection(!0)},$scope.toggleAvailableAllSelect=function(){angular.forEach($scope.available,function(disk){$scope.availableAllSelected?disk.$selected=!1:disk.$selected=!0}),$scope.updateAvailableSelection(!0)},$scope.isAvailableDisabled=function(){return $scope.availableMode!==SELECTION_MODE.NONE&&$scope.availableMode!==SELECTION_MODE.SINGLE&&$scope.availableMode!==SELECTION_MODE.MUTLI||$scope.isAllStorageDisabled()},$scope.canFormatAndMount=function(disk){return!$scope.isAllStorageDisabled()&&("lvm-vg"!==disk.type&&!disk.has_partitions&&("physical"!==disk.type||!disk.original.is_boot))},$scope.getPartitionButtonText=function(disk){return disk.has_partitions?"Add partition":"Partition"},$scope.availablePartitionSpace=function(disk){var space_to_reserve=0;return angular.isString(disk.original.partition_table_type)&&""!==disk.original.partition_table_type||(space_to_reserve=5242880,0===$scope.node.architecture.indexOf("ppc64el")&&(space_to_reserve+=8388608)),ConverterService.roundByBlockSize(disk.original.available_size-space_to_reserve,4194304)},$scope.canAddPartition=function(disk){return!(!$scope.isSuperUser()||$scope.isAllStorageDisabled())&&("partition"!==disk.type&&"lvm-vg"!==disk.type&&(("virtual"!==disk.type||"lvm-vg"!==disk.parent_type&&"bcache"!==disk.parent_type)&&((!angular.isString(disk.fstype)||""===disk.fstype)&&$scope.availablePartitionSpace(disk)-MIN_PARTITION_SIZE>=0)))},$scope.isNameInvalid=function(disk){return""!==disk.name&&!!isNameAlreadyInUse(disk.name,disk)},$scope.nameHasChanged=function(disk){if(isLogicalVolume(disk)){var parentName=disk.original.name.split("-")[0]+"-";0!==disk.name.indexOf(parentName)&&(disk.name=parentName)}},$scope.availableCancel=function(disk){$scope.updateAvailableSelection(!0),$scope.availableNew={}},$scope.usesMountPoint=function(fstype){return angular.isString(fstype)&&"swap"!==fstype},$scope.usesStorage=function(fstype){return angular.isString(fstype)&&"tmpfs"!==fstype&&"ramfs"!==fstype},$scope.isMountPointInvalid=function(mountPoint){return!angular.isUndefined(mountPoint)&&""!==mountPoint&&("none"!==mountPoint&&"/"!==mountPoint[0])},$scope.canDelete=function(disk){return!(!$scope.isSuperUser()||$scope.isAllStorageDisabled())&&("lvm-vg"===disk.type?0===disk.original.used_size:!disk.has_partitions)},$scope.availableDelete=function(){$scope.availableMode=SELECTION_MODE.DELETE},$scope.availableQuickDelete=function(disk){deselectAll($scope.available),disk.$selected=!0,$scope.updateAvailableSelection(!0),$scope.availableDelete()},$scope.canEdit=function(disk){return!(!$scope.isSuperUser()||$scope.isAllStorageDisabled())},$scope.availableEdit=function(disk){$scope.availableMode=SELECTION_MODE.EDIT,"lvm-vg"===disk.type?disk.$options={editingTags:!1,editingFilesystem:!1}:"partition"===disk.type?disk.$options={editingTags:!1,editingFilesystem:!0,fstype:disk.fstype}:(disk.$options={editingFilesystem:!0,editingTags:!0,tags:angular.copy(disk.tags),fstype:disk.fstype},$scope.canFormatAndMount(disk)||(disk.$options.editingFilesystem=!1))},$scope.availableQuickEdit=function(disk){deselectAll($scope.available),disk.$selected=!0,$scope.updateAvailableSelection(!0),$scope.availableEdit(disk)},$scope.availableConfirmEdit=function(disk){var params={name:disk.name};if(!$scope.isNameInvalid(disk)&&!$scope.isMountPointInvalid(disk.$options.mountPoint)){if(""===disk.name&&(disk.name=disk.original.name),isLogicalVolume(disk)){var parentName=disk.original.name.split("-")[0]+"-";params.name=disk.name.slice(parentName.length)}if(angular.isDefined(disk.$options.fstype)&&(params.fstype=disk.$options.fstype,params.mount_point=disk.$options.mountPoint||"",params.mount_options=disk.$options.mountOptions||""),angular.isArray(disk.$options.tags)&&(params.tags=disk.$options.tags.map(function(tag){return tag.text})),"partition"===disk.type?MachinesManager.updateFilesystem($scope.node,disk.block_id,disk.partition_id,params.fstype,params.mount_point,params.mount_options,params.tags):MachinesManager.updateDisk($scope.node,disk.block_id,params),disk.fstype=disk.$options.fstype,disk.mount_point=disk.$options.mountPoint,disk.mount_options=disk.$options.mountOptions,disk.tags=disk.$options.tags,disk.$options={},angular.isString(disk.mount_point)&&""!==disk.mount_point){$scope.filesystems.push({name:disk.name,size_human:disk.size_human,fstype:disk.fstype,mount_point:disk.mount_point,mount_options:disk.mount_options,block_id:disk.block_id,partition_id:disk.partition_id});var idx=$scope.available.indexOf(disk);$scope.available.splice(idx,1)}disk.$selected=!1,$scope.updateAvailableSelection(!0)}},$scope.getRemoveTypeText=function(disk){if("filesystem"===disk.type){if(!angular.isObject(disk.original))return"special filesystem";disk=disk.original}return"physical"===disk.type?"physical disk":"partition"===disk.type?"partition":"lvm-vg"===disk.type?"volume group":"virtual"===disk.type?"lvm-vg"===disk.parent_type?"logical volume":0===disk.parent_type.indexOf("raid-")?"RAID "+disk.parent_type.split("-")[1]+" disk":disk.parent_type+" disk":void 0},$scope.availableConfirmDelete=function(disk){"lvm-vg"===disk.type?MachinesManager.deleteVolumeGroup($scope.node,disk.block_id):"partition"===disk.type?MachinesManager.deletePartition($scope.node,disk.partition_id):MachinesManager.deleteDisk($scope.node,disk.block_id);var idx=$scope.available.indexOf(disk);$scope.available.splice(idx,1),$scope.updateAvailableSelection(!0)},$scope.availablePartition=function(disk){$scope.availableMode=SELECTION_MODE.PARTITION;var size_and_units=disk.available_size_human.split(" ");disk.$options={size:size_and_units[0],sizeUnits:size_and_units[1],fstype:null,mountPoint:"",mountOptions:""}},$scope.availableQuickPartition=function(disk){deselectAll($scope.available),disk.$selected=!0,$scope.updateAvailableSelection(!0),$scope.availablePartition(disk)},$scope.getAddPartitionName=function(disk){var length,partitions=disk.original.partitions;return length=angular.isArray(partitions)?partitions.length:0,"mbr"===disk.original.partition_table_type&&length>2?disk.name+"-part"+(length+2):0===$scope.node.architecture.indexOf("ppc64el")&&disk.original.is_boot?disk.name+"-part"+(length+2):disk.name+"-part"+(length+1)},$scope.isAddPartitionSizeInvalid=function(disk){if(""!==disk.$options.size&&(string=disk.$options.size,/^-?\d+\.?\d*$/.test(string))){var bytes=ConverterService.unitsToBytes(disk.$options.size,disk.$options.sizeUnits);return bytes<MIN_PARTITION_SIZE||bytes>disk.original.available_size&&ConverterService.roundUnits(disk.$options.size,disk.$options.sizeUnits)>disk.original.available_size}return!0;var string},$scope.availableConfirmPartition=function(disk){if(!$scope.isAddPartitionSizeInvalid(disk)&&!$scope.isMountPointInvalid(disk.$options.mountPoint)){var bytes=ConverterService.unitsToBytes(disk.$options.size,disk.$options.sizeUnits),size_and_units=disk.original.available_size_human.split(" ");disk.$options.size===size_and_units[0]&&disk.$options.sizeUnits===size_and_units[1]&&(bytes=disk.original.available_size);var removeDisk=!1,available_space=$scope.availablePartitionSpace(disk);bytes>=available_space&&(bytes=available_space,removeDisk=!0);var params={};if(angular.isString(disk.$options.fstype)&&""!==disk.$options.fstype&&(params.fstype=disk.$options.fstype,""!==disk.$options.mountPoint&&(params.mount_point=disk.$options.mountPoint,params.mount_options=disk.$options.mountOptions)),MachinesManager.createPartition($scope.node,disk.block_id,bytes,params),removeDisk){var idx=$scope.available.indexOf(disk);$scope.available.splice(idx,1)}$scope.updateAvailableSelection(!0)}},$scope.getSelectedCacheSets=function(){var cachesets=[];return angular.forEach($scope.cachesets,function(cacheset){cacheset.$selected&&cachesets.push(cacheset)}),cachesets},$scope.updateCacheSetsSelection=function(force){angular.isUndefined(force)&&(force=!1);var cachesets=$scope.getSelectedCacheSets();0===cachesets.length?$scope.cachesetsMode=SELECTION_MODE.NONE:1===cachesets.length&&force?$scope.cachesetsMode=SELECTION_MODE.SINGLE:force&&($scope.cachesetsMode=SELECTION_MODE.MUTLI),0===$scope.cachesets.length?$scope.cachesetsAllSelected=!1:cachesets.length===$scope.cachesets.length?$scope.cachesetsAllSelected=!0:$scope.cachesetsAllSelected=!1},$scope.toggleCacheSetSelect=function(cacheset){cacheset.$selected=!cacheset.$selected,$scope.updateCacheSetsSelection(!0)},$scope.toggleCacheSetAllSelect=function(){angular.forEach($scope.cachesets,function(cacheset){$scope.cachesetsAllSelected?cacheset.$selected=!1:cacheset.$selected=!0}),$scope.updateCacheSetsSelection(!0)},$scope.isCacheSetsDisabled=function(){return $scope.isAllStorageDisabled()&&!$scope.isSuperUser()||$scope.cachesetsMode!==SELECTION_MODE.NONE&&$scope.cachesetsMode!==SELECTION_MODE.SINGLE&&$scope.cachesetsMode!==SELECTION_MODE.MUTLI},$scope.cacheSetCancel=function(){deselectAll($scope.cachesets),$scope.updateCacheSetsSelection(!0)},$scope.canDeleteCacheSet=function(cacheset){return""===cacheset.used_by&&!$scope.isAllStorageDisabled()&&$scope.isSuperUser()},$scope.cacheSetDelete=function(){$scope.cachesetsMode=SELECTION_MODE.DELETE},$scope.quickCacheSetDelete=function(cacheset){deselectAll($scope.cachesets),cacheset.$selected=!0,$scope.updateCacheSetsSelection(!0),$scope.cacheSetDelete()},$scope.cacheSetConfirmDelete=function(cacheset){MachinesManager.deleteCacheSet($scope.node,cacheset.cache_set_id);var idx=$scope.cachesets.indexOf(cacheset);$scope.cachesets.splice(idx,1),$scope.updateCacheSetsSelection()},$scope.canCreateCacheSet=function(){if($scope.isAvailableDisabled()||!$scope.isSuperUser())return!1;var selected=$scope.getSelectedAvailable();return 1===selected.length&&(!selected[0].has_partitions&&!$scope.hasUnmountedFilesystem(selected[0])&&"lvm-vg"!==selected[0].type)},$scope.createCacheSet=function(){if($scope.canCreateCacheSet()){var disk=$scope.getSelectedAvailable()[0];MachinesManager.createCacheSet($scope.node,disk.block_id,disk.partition_id);var idx=$scope.available.indexOf(disk);$scope.available.splice(idx,1)}},$scope.getCannotCreateBcacheMsg=function(){if(0===$scope.cachesets.length)return"Create at least one cache set to create bcache";var selected=$scope.getSelectedAvailable();return 1===selected.length?$scope.hasUnmountedFilesystem(selected[0])?"Device is formatted; unformat the device to create bcache":"lvm-vg"===selected[0].type?"Cannot use a logical volume as a backing device for bcache.":selected[0].has_partitions?"Device has already been partitioned; create a new partition to use as the bcache backing device":null:"Select only one available device to create bcache"},$scope.canCreateBcache=function(){return!($scope.isAvailableDisabled()||!$scope.isSuperUser())&&null===$scope.getCannotCreateBcacheMsg()},$scope.createBcache=function(){$scope.canCreateBcache()&&($scope.availableMode=SELECTION_MODE.BCACHE,$scope.availableNew={name:getNextName("bcache"),device:$scope.getSelectedAvailable()[0],cacheset:$scope.cachesets[0],cacheMode:"writeback",fstype:null,mountPoint:"",mountOptions:"",tags:[]})},$scope.fstypeChanged=function(options){null===options.fstype?(options.mountPoint="",options.mountOptions=""):$scope.usesMountPoint(options.fstype)?"none"===options.mountPoint&&(options.mountPoint=""):options.mountPoint="none"},$scope.isNewDiskNameInvalid=function(){if(!angular.isObject($scope.node)||!angular.isArray($scope.node.disks))return!0;if(""===$scope.availableNew.name)return!0;var i,j;for(i=0;i<$scope.node.disks.length;i++){var disk=$scope.node.disks[i];if($scope.availableNew.name===disk.name)return!0;if(angular.isArray(disk.partitions))for(j=0;j<disk.partitions.length;j++){var partition=disk.partitions[j];if($scope.availableNew.name===partition.name)return!0}}return!1},$scope.createBcacheCanSave=function(){return!$scope.isNewDiskNameInvalid()&&!$scope.isMountPointInvalid($scope.availableNew.mountPoint)},$scope.availableConfirmCreateBcache=function(){if($scope.createBcacheCanSave()){var params={name:$scope.availableNew.name,cache_set:$scope.availableNew.cacheset.cache_set_id,cache_mode:$scope.availableNew.cacheMode};"partition"===$scope.availableNew.device.type?params.partition_id=$scope.availableNew.device.partition_id:params.block_id=$scope.availableNew.device.block_id,angular.isString($scope.availableNew.fstype)&&""!==$scope.availableNew.fstype&&(params.fstype=$scope.availableNew.fstype,""!==$scope.availableNew.mountPoint&&(params.mount_point=$scope.availableNew.mountPoint,params.mount_options=$scope.availableNew.mountOptions)),angular.isArray($scope.availableNew.tags)&&$scope.availableNew.tags.length>0&&(params.tags=$scope.availableNew.tags.map(function(tag){return tag.text})),MachinesManager.createBcache($scope.node,params);var idx=$scope.available.indexOf($scope.availableNew.device);$scope.available.splice(idx,1),$scope.availableNew={},$scope.updateAvailableSelection(!0)}},$scope.canCreateRAID=function(){if($scope.isAvailableDisabled()||!$scope.isSuperUser())return!1;var selected=$scope.getSelectedAvailable();if(selected.length>1){var i;for(i=0;i<selected.length;i++){if($scope.hasUnmountedFilesystem(selected[i]))return!1;if("lvm-vg"===selected[i].type)return!1}return!0}return!1},$scope.createRAID=function(){$scope.canCreateRAID()&&($scope.availableMode=SELECTION_MODE.RAID,$scope.availableNew={name:getNextName("md"),devices:$scope.getSelectedAvailable(),mode:null,spares:[],fstype:null,mountPoint:"",mountOptions:"",tags:[]},$scope.availableNew.mode=$scope.getAvailableRAIDModes()[0])},$scope.getAvailableRAIDModes=function(){if(!angular.isObject($scope.availableNew)||!angular.isArray($scope.availableNew.devices))return[];var modes=[];return angular.forEach(RAID_MODES,function(mode){$scope.availableNew.devices.length>=mode.min_disks&&modes.push(mode)}),modes},$scope.getTotalNumberOfAvailableSpares=function(){var mode=$scope.availableNew.mode;if(angular.isUndefined(mode)||!mode.allows_spares)return 0;var diff=$scope.availableNew.devices.length-mode.min_disks;return diff<0&&(diff=0),diff},$scope.getNumberOfRemainingSpares=function(){var allowed=$scope.getTotalNumberOfAvailableSpares();return allowed<=0?0:allowed-$scope.availableNew.spares.length},$scope.showSparesColumn=function(){return $scope.getTotalNumberOfAvailableSpares()>0},$scope.RAIDModeChanged=function(){$scope.availableNew.spares=[]},$scope.isActiveRAIDMember=function(disk){return!angular.isArray($scope.availableNew.spares)||-1===$scope.availableNew.spares.indexOf(getUniqueKey(disk))},$scope.isSpareRAIDMember=function(disk){return!$scope.isActiveRAIDMember(disk)},$scope.setAsActiveRAIDMember=function(disk){var idx=$scope.availableNew.spares.indexOf(getUniqueKey(disk));idx>-1&&$scope.availableNew.spares.splice(idx,1)},$scope.setAsSpareRAIDMember=function(disk){var key=getUniqueKey(disk);-1===$scope.availableNew.spares.indexOf(key)&&$scope.availableNew.spares.push(key)},$scope.getNewRAIDSize=function(){if(angular.isUndefined($scope.availableNew.mode))return"";var calculateSize=$scope.availableNew.mode.calculateSize;if(!angular.isFunction(calculateSize))return"";var numDisks=$scope.availableNew.devices.length-$scope.availableNew.spares.length,minSize=Number.MAX_VALUE;angular.forEach($scope.availableNew.devices,function(device){var deviceSize=device.original.available_size||device.original.size;minSize=Math.min(minSize,deviceSize)});var size=calculateSize(minSize,numDisks);return ConverterService.bytesToUnits(size).string},$scope.createRAIDCanSave=function(){return!$scope.isNewDiskNameInvalid()&&!$scope.isMountPointInvalid($scope.availableNew.mountPoint)},$scope.availableConfirmCreateRAID=function(){if($scope.createRAIDCanSave()){var params={name:$scope.availableNew.name,level:$scope.availableNew.mode.level,block_devices:[],partitions:[],spare_devices:[],spare_partitions:[]};angular.forEach($scope.availableNew.devices,function(device){$scope.isActiveRAIDMember(device)?"partition"===device.type?params.partitions.push(device.partition_id):params.block_devices.push(device.block_id):"partition"===device.type?params.spare_partitions.push(device.partition_id):params.spare_devices.push(device.block_id)}),angular.isString($scope.availableNew.fstype)&&""!==$scope.availableNew.fstype&&(params.fstype=$scope.availableNew.fstype,""!==$scope.availableNew.mountPoint&&(params.mount_point=$scope.availableNew.mountPoint,params.mount_options=$scope.availableNew.mountOptions)),angular.isArray($scope.availableNew.tags)&&$scope.availableNew.tags.length>0&&(params.tags=$scope.availableNew.tags.map(function(tag){return tag.text})),MachinesManager.createRAID($scope.node,params),angular.forEach($scope.availableNew.devices,function(device){var idx=$scope.available.indexOf($scope.availableNew.device);$scope.available.splice(idx,1)}),$scope.availableNew={},$scope.updateAvailableSelection(!0)}},$scope.canCreateVolumeGroup=function(){if($scope.isAvailableDisabled()||!$scope.isSuperUser())return!1;var selected=$scope.getSelectedAvailable();if(selected.length>0){var i;for(i=0;i<selected.length;i++){if(selected[i].has_partitions)return!1;if($scope.hasUnmountedFilesystem(selected[i]))return!1;if("lvm-vg"===selected[i].type)return!1}return!0}return!1},$scope.createVolumeGroup=function(){$scope.canCreateVolumeGroup()&&($scope.availableMode=SELECTION_MODE.VOLUME_GROUP,$scope.availableNew={name:getNextName("vg"),devices:$scope.getSelectedAvailable()})},$scope.getNewVolumeGroupSize=function(){var total=0;return angular.forEach($scope.availableNew.devices,function(device){total+=device.original.available_size||device.original.size}),ConverterService.bytesToUnits(total).string},$scope.createVolumeGroupCanSave=function(){return!$scope.isNewDiskNameInvalid()},$scope.availableConfirmCreateVolumeGroup=function(){if($scope.createVolumeGroupCanSave()){var params={name:$scope.availableNew.name,block_devices:[],partitions:[]};angular.forEach($scope.availableNew.devices,function(device){"partition"===device.type?params.partitions.push(device.partition_id):params.block_devices.push(device.block_id)}),MachinesManager.createVolumeGroup($scope.node,params),angular.forEach($scope.availableNew.devices,function(device){var idx=$scope.available.indexOf($scope.availableNew.device);$scope.available.splice(idx,1)}),$scope.availableNew={},$scope.updateAvailableSelection(!0)}},$scope.canAddLogicalVolume=function(disk){return"lvm-vg"===disk.type&&!(disk.original.available_size<MIN_PARTITION_SIZE)},$scope.availableLogicalVolume=function(disk){$scope.availableMode=SELECTION_MODE.LOGICAL_VOLUME,disk.$selected=!0;var size_and_units=disk.available_size_human.split(" "),namePrefix=disk.name+"-lv";disk.$options={name:getNextName(namePrefix),size:size_and_units[0],sizeUnits:size_and_units[1],fstype:null,tags:[]}},$scope.isLogicalVolumeNameInvalid=function(disk){return!!angular.isString(disk.$options.name)&&(0!==disk.$options.name.indexOf(disk.name+"-")||disk.$options.name.length<=disk.name.length+1||isNameAlreadyInUse(disk.$options.name))},$scope.newLogicalVolumeNameChanged=function(disk){angular.isString(disk.$options.name)&&(0!==disk.$options.name.indexOf(disk.name+"-")&&(disk.$options.name=disk.name+"-"))},$scope.isAddLogicalVolumeSizeInvalid=function(disk){return $scope.isAddPartitionSizeInvalid(disk)},$scope.availableConfirmLogicalVolume=function(disk){if(!($scope.isLogicalVolumeNameInvalid(disk)||$scope.isAddLogicalVolumeSizeInvalid(disk)||$scope.isMountPointInvalid(disk.$options.mountPoint))){var bytes=ConverterService.unitsToBytes(disk.$options.size,disk.$options.sizeUnits),size_and_units=disk.original.available_size_human.split(" ");disk.$options.size===size_and_units[0]&&disk.$options.sizeUnits===size_and_units[1]&&(bytes=disk.original.available_size),bytes>disk.original.available_size&&(bytes=disk.original.available_size);var removeDisk=!1;bytes===disk.original.available_size&&(removeDisk=!0);var name=disk.$options.name.slice(disk.name.length+1),params={};if(angular.isString(disk.$options.fstype)&&""!==disk.$options.fstype&&(params.fstype=disk.$options.fstype,""!==disk.$options.mountPoint&&(params.mount_point=disk.$options.mountPoint,params.mount_options=disk.$options.mountOptions)),angular.isArray(disk.$options.tags)&&disk.$options.tags.length>0&&(params.tags=disk.$options.tags.map(function(tag){return tag.text})),MachinesManager.createLogicalVolume($scope.node,disk.block_id,name,bytes,params),removeDisk){var idx=$scope.available.indexOf(disk);$scope.available.splice(idx,1)}$scope.updateAvailableSelection(!0)}},$scope.isAllStorageDisabled=function(){var authUser=UsersManager.getAuthUser();return!angular.isObject(authUser)||!angular.isObject($scope.node)||!authUser.is_superuser&&authUser.username!==$scope.node.owner||!(!angular.isObject($scope.node)||-1!==["Ready","Allocated"].indexOf($scope.node.status))},$scope.hasStorageLayoutIssues=function(){return!(!angular.isObject($scope.node)||!angular.isArray($scope.node.storage_layout_issues))&&$scope.node.storage_layout_issues.length>0},$scope.$parent.controllerLoaded("storageController",$scope)}])},"./src/maasserver/static/js/angular/controllers/node_details_storage_filesystems.js":function(module,exports){!function(){function SpecialFilesystem(){this.fstype="tmpfs",this.mountPoint="",this.mountOptions=""}SpecialFilesystem.prototype.isValid=function(){return this.mountPoint.startsWith("/")},SpecialFilesystem.prototype.describe=function(){var parts=[this.fstype];switch(this.mountPoint.startsWith("/")&&parts.push("at "+this.mountPoint),this.fstype){case"tmpfs":var size=this.mountOptions.match(/\bsize=(\d+)(%?)/);null!==size&&("%"===size[2]?parts.push("limited to "+size[1]+"% of memory"):parts.push("limited to "+size[1]+" bytes"))}return parts.join(" ")},angular.module("MAAS").controller("NodeFilesystemsController",["$scope",function($scope){$scope.dropdown=null,$scope.addSpecialFilesystem=function(){$scope.dropdown="special"},$scope.addSpecialFilesystemFinished=function(){"special"===$scope.dropdown&&($scope.dropdown=null)}}]),angular.module("MAAS").controller("NodeAddSpecialFilesystemController",["$scope","MachinesManager",function($scope,MachinesManager){$scope.filesystem=new SpecialFilesystem,$scope.description=null,$scope.$watch("filesystem",function(filesystem){$scope.description=filesystem.describe()},!0),$scope.canMount=function(){return $scope.filesystem.isValid()},$scope.mount=function(){MachinesManager.mountSpecialFilesystem($scope.node,$scope.filesystem.fstype,$scope.filesystem.mountPoint,$scope.filesystem.mountOptions),$scope.addSpecialFilesystemFinished()},$scope.cancel=function(){$scope.filesystem=new SpecialFilesystem,$scope.addSpecialFilesystemFinished()}}])}()},"./src/maasserver/static/js/angular/controllers/node_events.js":function(module,exports){angular.module("MAAS").controller("NodeEventsController",["$scope","$rootScope","$routeParams","$location","MachinesManager","ControllersManager","EventsManagerFactory","ManagerHelperService","ErrorService",function($scope,$rootScope,$routeParams,$location,MachinesManager,ControllersManager,EventsManagerFactory,ManagerHelperService,ErrorService){var eventsManager=null;function nodeLoaded(node){$scope.node=node,$scope.loaded=!0,eventsManager=EventsManagerFactory.getManager(node.id),$scope.events=eventsManager.getItems(),$scope.days=eventsManager.getMaximumDays(),eventsManager.loadItems().then(function(){$scope.eventsLoaded=!0}),$scope.$watch("node.fqdn",function(){$rootScope.title=$scope.node.fqdn+" - events"})}$rootScope.title="Loading...",$scope.loaded=!1,$scope.node=null,$scope.events=[],$scope.eventsLoaded=!1,$scope.days=1,$scope.getEventText=function(event){var text=event.type.description;return angular.isString(event.description)&&event.description.length>0&&(text+=" - "+event.description),text},$scope.loadMore=function(){$scope.days+=1,eventsManager.loadMaximumDays($scope.days)},-1!==$location.path().indexOf("/controller")?($scope.nodesManager=ControllersManager,$scope.type_name="controller",$rootScope.page="controllers"):($scope.nodesManager=MachinesManager,$scope.type_name="machine",$rootScope.page="machines"),ManagerHelperService.loadManager($scope,$scope.nodesManager).then(function(){var activeNode=$scope.nodesManager.getActiveItem();angular.isObject(activeNode)&&activeNode.system_id===$routeParams.system_id?nodeLoaded(activeNode):$scope.nodesManager.setActiveItem($routeParams.system_id).then(function(node){nodeLoaded(node)},function(error){ErrorService.raiseError(error)})}),$scope.$on("$destroy",function(){angular.isObject(eventsManager)&&eventsManager.destroy()})}])},"./src/maasserver/static/js/angular/controllers/node_result.js":function(module,exports){angular.module("MAAS").controller("NodeResultController",["$scope","$rootScope","$routeParams","$location","MachinesManager","ControllersManager","NodeResultsManagerFactory","ManagerHelperService","ErrorService",function($scope,$rootScope,$routeParams,$location,MachinesManager,ControllersManager,NodeResultsManagerFactory,ManagerHelperService,ErrorService){function nodeLoaded(node){$scope.node=node,$scope.loaded=!0;var nodeResultsManager=NodeResultsManagerFactory.getManager($scope.node),requestedResult=parseInt($routeParams.id,10);nodeResultsManager.getItem(requestedResult).then(function(result){$scope.result=result,$scope.get_result_data($scope.output),$scope.resultLoaded=!0,$rootScope.title=$scope.node.fqdn+" - "+$scope.result.name})}$rootScope.title="Loading...",$scope.loaded=!1,$scope.resultLoaded=!1,$scope.node=null,$scope.output="combined",$scope.result=null,$scope.get_result_data=function(output){$scope.output=output,$scope.data="Loading...",NodeResultsManagerFactory.getManager($scope.node).get_result_data($scope.result.id,$scope.output).then(function(data){$scope.data=""===data?"Empty file.":data})},$scope.$watch("node.fqdn",function(){angular.isObject($scope.node)&&angular.isObject($scope.result)&&($rootScope.title=$scope.node.fqdn+" - "+$scope.result.name)}),-1!==$location.path().indexOf("/controller")?($scope.nodesManager=ControllersManager,$scope.type_name="controller",$rootScope.page="controllers"):($scope.nodesManager=MachinesManager,$scope.type_name="machine",$rootScope.page="machines"),ManagerHelperService.loadManager($scope,$scope.nodesManager).then(function(){var activeNode=$scope.nodesManager.getActiveItem();angular.isObject(activeNode)&&activeNode.system_id===$routeParams.system_id?nodeLoaded(activeNode):$scope.nodesManager.setActiveItem($routeParams.system_id).then(function(node){nodeLoaded(node)},function(error){ErrorService.raiseError(error)})}),$scope.$on("$destroy",function(){var nodeResultsManager=NodeResultsManagerFactory.getManager($scope.node);angular.isObject(nodeResultsManager)&&nodeResultsManager.destroy()})}])},"./src/maasserver/static/js/angular/controllers/node_results.js":function(module,exports){angular.module("MAAS").controller("NodeResultsController",["$scope","$routeParams","$location","MachinesManager","ControllersManager","NodeResultsManagerFactory","ManagerHelperService","ErrorService",function($scope,$routeParams,$location,MachinesManager,ControllersManager,NodeResultsManagerFactory,ManagerHelperService,ErrorService){function updateLogs(){var i,had_installation=3===$scope.logs.availableOptions.length;if($scope.logs.availableOptions.length=0,$scope.installation_results&&$scope.installation_results.length>0&&(6===$scope.node.status_code||9===$scope.node.status_code||11===$scope.node.status_code))for(i=0;i<$scope.installation_results.length;i++)if("/tmp/install.log"===$scope.installation_results[i].name){$scope.logs.availableOptions.push({title:"Installation output",id:$scope.installation_results[i].id});break}$scope.logs.availableOptions.push({title:"Machine output (YAML)",id:"summary_yaml"}),$scope.logs.availableOptions.push({title:"Machine output (XML)",id:"summary_xml"}),had_installation||3!==$scope.logs.availableOptions.length?(!$scope.selectedLog||had_installation&&2===$scope.logs.length)&&($scope.logs.option=$scope.logs.availableOptions[0]):$scope.logs.option=$scope.logs.availableOptions[0]}function nodeLoaded(node){$scope.node=node,$scope.loaded=!0,$scope.nodeResultsManager=NodeResultsManagerFactory.getManager(node,$scope.section.area),$scope.nodeResultsManager.loadItems().then(function(){$scope.commissioning_results=$scope.nodeResultsManager.commissioning_results,$scope.testing_results=$scope.nodeResultsManager.testing_results,$scope.installation_results=$scope.nodeResultsManager.installation_results,$scope.results=$scope.nodeResultsManager.results,"logs"===$scope.section.area&&(updateLogs(),$scope.$watch("installation_results",updateLogs,!0),$scope.$watch("installation_results",$scope.updateLogOutput,!0)),$scope.resultsLoaded=!0})}$scope.nodeResultsManager=null,$scope.commissioning_results=null,$scope.testing_results=null,$scope.installation_results=null,$scope.results=null,$scope.logs={option:null,availableOptions:[]},$scope.logOutput="Loading...",$scope.loaded=!1,$scope.resultsLoaded=!1,$scope.node=null,-1!==$location.path().indexOf("/controller")?$scope.nodesManager=ControllersManager:$scope.nodesManager=MachinesManager,ManagerHelperService.loadManager($scope,$scope.nodesManager).then(function(){var activeNode=$scope.nodesManager.getActiveItem();angular.isObject(activeNode)&&activeNode.system_id===$routeParams.system_id?nodeLoaded(activeNode):$scope.nodesManager.setActiveItem($routeParams.system_id).then(function(node){nodeLoaded(node)},function(error){ErrorService.raiseError(error)})}),$scope.updateLogOutput=function(){if($scope.logOutput="Loading...",$scope.node)if("summary_xml"===$scope.logs.option.id)$scope.nodesManager.getSummaryXML($scope.node).then(function(output){$scope.logOutput=output});else if("summary_yaml"===$scope.logs.option.id)$scope.nodesManager.getSummaryYAML($scope.node).then(function(output){$scope.logOutput=output});else{var i,result=null;for(i=0;i<$scope.installation_results.length;i++)if($scope.installation_results[i].id===$scope.logs.option.id){result=$scope.installation_results[i];break}switch(result.status){case 0:$scope.logOutput="System is booting...";break;case 1:$scope.logOutput="Installation has begun!";break;case 2:$scope.nodeResultsManager.get_result_data(result.id,"combined").then(function(output){$scope.logOutput=""===output?"Installation has succeeded but no output was given.":output});break;case 3:$scope.nodeResultsManager.get_result_data(result.id,"combined").then(function(output){$scope.logOutput=""===output?"Installation has failed and no output was given.":output});break;case 4:$scope.logOutput="Installation failed after 40 minutes.";break;case 5:$scope.logOutput="Installation was aborted.";break;default:$scope.logOutput="BUG: Unknown log status "+result.status}}},$scope.loadHistory=function(result){result.showing_results=!1,angular.isArray(result.history_list)?result.showing_history=!0:(result.loading_history=!0,$scope.nodeResultsManager.get_history(result.id).then(function(history){result.history_list=history,result.loading_history=!1,result.showing_history=!0}))},$scope.$on("$destroy",function(){angular.isObject($scope.nodeResultsManager)&&$scope.nodeResultsManager.destroy()})}])},"./src/maasserver/static/js/angular/controllers/nodes_list.js":function(module,exports){angular.module("MAAS").controller("NodesListController",["$q","$scope","$interval","$rootScope","$routeParams","$location","MachinesManager","DevicesManager","ControllersManager","GeneralManager","ManagerHelperService","SearchService","ZonesManager","UsersManager","ServicesManager","ScriptsManager","SwitchesManager","ResourcePoolsManager",function($q,$scope,$interval,$rootScope,$routeParams,$location,MachinesManager,DevicesManager,ControllersManager,GeneralManager,ManagerHelperService,SearchService,ZonesManager,UsersManager,ServicesManager,ScriptsManager,SwitchesManager,ResourcePoolsManager){var DEVICE_IP_ASSIGNMENT={external:"External",dynamic:"Dynamic",static:"Static"};function isViewingSelected(tab){var search=$scope.tabs[tab].search.toLowerCase();return"in:(selected)"===search||"in:selected"===search}function enterViewSelected(tab){$scope.tabs[tab].previous_search=$scope.tabs[tab].search,$scope.tabs[tab].search="in:(Selected)"}function leaveViewSelected(tab){isViewingSelected(tab)&&($scope.tabs[tab].search=$scope.tabs[tab].previous_search,$scope.updateFilters(tab))}function updateAllViewableChecked(tab){if(0!==$scope.tabs[tab].filtered_items.length){var i;for(i=0;i<$scope.tabs[tab].filtered_items.length;i++)if(!$scope.tabs[tab].filtered_items[i].$selected)return void($scope.tabs[tab].allViewableChecked=!1);$scope.tabs[tab].allViewableChecked=!0}else $scope.tabs[tab].allViewableChecked=!1}function clearAction(tab){resetActionProgress(tab),leaveViewSelected(tab),$scope.tabs[tab].actionOption=null,$scope.tabs[tab].zoneSelection=null,$scope.tabs[tab].poolSelection=null,$scope.tabs[tab].poolAction="select-pool",$scope.tabs[tab].newPool={},"machines"!==tab&&"switches"!==tab||(angular.isFunction($scope.tabs[tab].osSelection.$reset)&&$scope.tabs[tab].osSelection.$reset(),$scope.tabs[tab].commissionOptions.enableSSH=!1,$scope.tabs[tab].commissionOptions.skipNetworking=!1,$scope.tabs[tab].commissionOptions.skipStorage=!1,$scope.tabs[tab].commissionOptions.updateFirmware=!1,$scope.tabs[tab].commissionOptions.configureHBA=!1),$scope.tabs[tab].commissioningSelection=[],$scope.tabs[tab].testSelection=[]}function shouldClearAction(tab){0===$scope.tabs[tab].selectedItems.length&&clearAction(tab),$scope.tabs[tab].actionOption&&!isViewingSelected(tab)&&($scope.tabs[tab].actionOption=null)}function removeEmptyFilter(tab){0===$scope.tabs[tab].filtered_items.length&&""!==$scope.tabs[tab].search&&$scope.tabs[tab].search===$scope.tabs[tab].previous_search&&($scope.tabs[tab].search="",$scope.updateFilters(tab))}function updateActionErrorCount(tab){var i;for($scope.tabs[tab].actionErrorCount=0,i=0;i<$scope.tabs[tab].selectedItems.length;i++){$scope.supportsAction($scope.tabs[tab].selectedItems[i],tab)||($scope.tabs[tab].actionErrorCount+=1),$scope.tabs[tab].selectedItems[i].action_failed=!1}}function resetActionProgress(tab){var progress=$scope.tabs[tab].actionProgress;progress.completed=progress.total=0,progress.errors={},progress.showing_confirmation=!1,progress.affected_nodes=0}function addErrorToActionProgress(tab,error,node){var progress=$scope.tabs[tab].actionProgress;progress.completed+=1;var nodes=progress.errors[error];angular.isUndefined(nodes)?progress.errors[error]=[node]:nodes.push(node)}function updateSelectedItems(tab){$scope.hasActionsFailed(tab)?angular.forEach($scope.tabs[tab].manager.getItems(),function(node){!1===node.action_failed&&$scope.tabs[tab].manager.unselectItem(node.system_id)}):$scope.hasActionsInProgress(tab)||(clearAction(tab),enterViewSelected(tab))}$rootScope.title="Machines",$rootScope.page="machines",$scope.MAAS_config=MAAS_config,$scope.machines=MachinesManager.getItems(),$scope.zones=ZonesManager.getItems(),$scope.pools=ResourcePoolsManager.getItems(),$scope.devices=DevicesManager.getItems(),$scope.controllers=ControllersManager.getItems(),$scope.switches=SwitchesManager.getItems(),$scope.showswitches="on"===$routeParams.switches,$scope.currentpage="machines",$scope.osinfo={},$scope.scripts=ScriptsManager.getItems(),$scope.loading=!0,$scope.tabs={},$scope.pluralize=function(tab){var verb={machines:"machine",switches:"switch",devices:"device",controllers:"controller"}[tab];return $scope.tabs[tab].selectedItems.length>1&&(verb=tab),verb},$scope.tabs.machines={},$scope.tabs.machines.pagetitle="Machines",$scope.tabs.machines.currentpage="machines",$scope.tabs.machines.manager=MachinesManager,$scope.tabs.machines.previous_search="",$scope.tabs.machines.search="",$scope.tabs.machines.searchValid=!0,$scope.tabs.machines.selectedItems=MachinesManager.getSelectedItems(),$scope.tabs.machines.metadata=MachinesManager.getMetadata(),$scope.tabs.machines.filters=SearchService.getEmptyFilter(),$scope.tabs.machines.actionOption=null,$scope.tabs.machines.takeActionOptions=[],$scope.tabs.machines.actionErrorCount=0,$scope.tabs.machines.actionProgress={total:0,completed:0,errors:{},showing_confirmation:!1,affected_nodes:0},$scope.tabs.machines.osSelection={osystem:null,release:null,hwe_kernel:null},$scope.tabs.machines.zoneSelection=null,$scope.tabs.machines.poolSelection=null,$scope.tabs.machines.poolAction="select-pool",$scope.tabs.machines.newPool={},$scope.tabs.machines.commissionOptions={enableSSH:!1,skipNetworking:!1,skipStorage:!1,updateFirmware:!1,configureHBA:!1},$scope.tabs.machines.releaseOptions={},$scope.tabs.machines.commissioningSelection=[],$scope.tabs.machines.testSelection=[],$scope.tabs.pools={},$scope.tabs.pools.pagetitle="Pools",$scope.tabs.pools.currentpage="pools",$scope.tabs.pools.manager=ResourcePoolsManager,$scope.tabs.pools.actionOption=!1,$scope.tabs.pools.newPool={name:null,description:null},$scope.tabs.pools.addPool=function(){$scope.tabs.pools.actionOption=!0},$scope.tabs.pools.cancelAddPool=function(){$scope.tabs.pools.actionOption=!1,$scope.tabs.pools.newPool={}},$scope.tabs.pools.activeTarget=null,$scope.tabs.pools.activeTargetAction=null,$scope.tabs.pools.actionErrorMessage=null,$scope.tabs.pools.initiatePoolAction=function(pool,action){var tab=$scope.tabs.pools;tab.cancelPoolAction(),tab.activeTargetAction=action,tab.activeTarget=pool,tab.editingPool=pool},$scope.tabs.pools.cancelPoolAction=function(){var tab=$scope.tabs.pools;tab.activeTargetAction=null,tab.activeTarget=null,tab.actionErrorMessage=null},$scope.tabs.pools.isPoolAction=function(pool,action){var tab=$scope.tabs.pools;return(void 0===action||tab.activeTargetAction===action)&&null!==tab.activeTarget&&tab.activeTarget.id===pool.id},$scope.tabs.pools.actionConfirmEditPool=function(){$scope.tabs.pools.cancelPoolAction()},$scope.tabs.pools.actionConfirmDeletePool=function(){var tab=$scope.tabs.pools;tab.manager.deleteItem(tab.activeTarget).then(tab.cancelPoolAction,function(error){$scope.tabs.pools.actionErrorMessage=error})},$scope.tabs.pools.goToPoolMachines=function(pool){$scope.clearSearch("machines"),$scope.toggleFilter("pool",pool.name,"machines"),$scope.toggleTab("machines"),$location.path("/machines")},$scope.tabs.pools.isDefaultPool=function(pool){return 0===pool.id},$scope.tabs.devices={},$scope.tabs.devices.pagetitle="Devices",$scope.tabs.devices.currentpage="devices",$scope.tabs.devices.manager=DevicesManager,$scope.tabs.devices.previous_search="",$scope.tabs.devices.search="",$scope.tabs.devices.searchValid=!0,$scope.tabs.devices.selectedItems=DevicesManager.getSelectedItems(),$scope.tabs.devices.filtered_items=[],$scope.tabs.devices.predicate="fqdn",$scope.tabs.devices.allViewableChecked=!1,$scope.tabs.devices.metadata=DevicesManager.getMetadata(),$scope.tabs.devices.filters=SearchService.getEmptyFilter(),$scope.tabs.devices.column="fqdn",$scope.tabs.devices.actionOption=null,$scope.tabs.devices.takeActionOptions=[],$scope.tabs.devices.actionErrorCount=0,$scope.tabs.devices.actionProgress={total:0,completed:0,errors:{},showing_confirmation:!1,affected_nodes:0},$scope.tabs.devices.zoneSelection=null,$scope.tabs.devices.poolSelection=null,$scope.tabs.devices.poolAction="select-pool",$scope.tabs.devices.newPool={},$scope.tabs.controllers={},$scope.tabs.controllers.pagetitle="Controllers",$scope.tabs.controllers.currentpage="controllers",$scope.tabs.controllers.manager=ControllersManager,$scope.tabs.controllers.previous_search="",$scope.tabs.controllers.search="",$scope.tabs.controllers.searchValid=!0,$scope.tabs.controllers.selectedItems=ControllersManager.getSelectedItems(),$scope.tabs.controllers.filtered_items=[],$scope.tabs.controllers.predicate="fqdn",$scope.tabs.controllers.allViewableChecked=!1,$scope.tabs.controllers.metadata=ControllersManager.getMetadata(),$scope.tabs.controllers.filters=SearchService.getEmptyFilter(),$scope.tabs.controllers.column="fqdn",$scope.tabs.controllers.actionOption=null,$scope.tabs.controllers.takeActionOptions=[],$scope.tabs.controllers.actionErrorCount=0,$scope.tabs.controllers.actionProgress={total:0,completed:0,errors:{},showing_confirmation:!1,affected_nodes:0},$scope.tabs.controllers.zoneSelection=null,$scope.tabs.controllers.poolSelection=null,$scope.tabs.controllers.poolAction="select-pool",$scope.tabs.controllers.newPool={},$scope.tabs.controllers.syncStatuses={},$scope.tabs.controllers.addController=!1,$scope.tabs.controllers.registerUrl=MAAS_config.register_url,$scope.tabs.controllers.registerSecret=MAAS_config.register_secret,$scope.tabs.switches={},$scope.tabs.switches.pagetitle="Switches",$scope.tabs.switches.currentpage="switches",$scope.tabs.switches.manager=SwitchesManager,$scope.tabs.switches.previous_search="",$scope.tabs.switches.search="",$scope.tabs.switches.searchValid=!0,$scope.tabs.switches.selectedItems=SwitchesManager.getSelectedItems(),$scope.tabs.switches.predicate="fqdn",$scope.tabs.switches.allViewableChecked=!1,$scope.tabs.switches.metadata=SwitchesManager.getMetadata(),$scope.tabs.switches.filters=SearchService.getEmptyFilter(),$scope.tabs.switches.column="fqdn",$scope.tabs.switches.actionOption=null,$scope.tabs.switches.takeActionOptions=[],$scope.tabs.switches.actionErrorCount=0,$scope.tabs.switches.actionProgress={total:0,completed:0,errors:{},showing_confirmation:!1,affected_nodes:0},$scope.tabs.switches.osSelection={osystem:null,release:null,hwe_kernel:null},$scope.tabs.switches.zoneSelection=null,$scope.tabs.switches.poolSelection=null,$scope.tabs.switches.poolAction="select-pool",$scope.tabs.switches.newPool={},$scope.tabs.switches.commissioningSelection=[],$scope.tabs.switches.commissionOptions={enableSSH:!1,skipNetworking:!1,skipStorage:!1,updateFirmware:!1,configureHBA:!1},$scope.tabs.switches.releaseOptions={},$scope.addHardwareOption=null,$scope.addHardwareOptions=[{name:"machine",title:"Machine"},{name:"chassis",title:"Chassis"}],$scope.addHardwareScope=null,$scope.addDeviceScope=null,$scope.$on("addHardwareHidden",function(){$scope.addHardwareOption=null}),$scope.toggleTab=function(tab){switch($rootScope.title=$scope.tabs[tab].pagetitle,$rootScope.page=tab,$scope.currentpage=tab,tab){case"machines":$scope.osinfo=GeneralManager.getData("osinfo"),$scope.tabs.machines.takeActionOptions=GeneralManager.getData("machine_actions");break;case"devices":$scope.tabs.devices.takeActionOptions=GeneralManager.getData("device_actions");break;case"controllers":$scope.tabs.controllers.takeActionOptions=GeneralManager.getData("rack_controller_actions");break;case"switches":$scope.tabs.switches.takeActionOptions=GeneralManager.getData("machine_actions")}},$scope.clearSearch=function(tab){$scope.tabs[tab].search="",$scope.updateFilters(tab)},$scope.toggleChecked=function(node,tab){"machines"!==tab&&"switches"!==tab&&($scope.tabs[tab].manager.isSelected(node.system_id)?$scope.tabs[tab].manager.unselectItem(node.system_id):$scope.tabs[tab].manager.selectItem(node.system_id),updateAllViewableChecked(tab)),updateActionErrorCount(tab),shouldClearAction(tab)},$scope.toggleCheckAll=function(tab){"machines"!==tab&&"switches"!==tab&&($scope.tabs[tab].allViewableChecked?angular.forEach($scope.tabs[tab].filtered_items,function(node){$scope.tabs[tab].manager.unselectItem(node.system_id)}):angular.forEach($scope.tabs[tab].filtered_items,function(node){$scope.tabs[tab].manager.selectItem(node.system_id)}),updateAllViewableChecked(tab)),updateActionErrorCount(tab),shouldClearAction(tab)},$scope.onNodeListingChanged=function(nodes,tab){0===nodes.length&&""!==$scope.tabs[tab].search&&$scope.tabs[tab].search===$scope.tabs[tab].previous_search&&($scope.tabs[tab].search="",$scope.updateFilters(tab))},$scope.$watchCollection("tabs.devices.filtered_items",function(){updateAllViewableChecked("devices"),removeEmptyFilter("devices")}),$scope.$watchCollection("tabs.controllers.filtered_items",function(){updateAllViewableChecked("controllers"),removeEmptyFilter("controllers")}),$scope.showSelected=function(tab){enterViewSelected(tab),$scope.updateFilters(tab)},$scope.toggleFilter=function(type,value,tab){angular.isObject($scope.tabs[tab].actionOption)||($scope.tabs[tab].filters=SearchService.toggleFilter($scope.tabs[tab].filters,type,value,!0),$scope.tabs[tab].search=SearchService.filtersToString($scope.tabs[tab].filters))},$scope.isFilterActive=function(type,value,tab){return SearchService.isFilterActive($scope.tabs[tab].filters,type,value,!0)},$scope.updateFilters=function(tab){var filters=SearchService.getCurrentFilters($scope.tabs[tab].search);null===filters?($scope.tabs[tab].filters=SearchService.getEmptyFilter(),$scope.tabs[tab].searchValid=!1):($scope.tabs[tab].filters=filters,$scope.tabs[tab].searchValid=!0),shouldClearAction(tab)},$scope.sortTable=function(predicate,tab){$scope.tabs[tab].predicate=predicate,$scope.tabs[tab].reverse=!$scope.tabs[tab].reverse},$scope.selectColumnOrSort=function(predicate,tab){$scope.tabs[tab].column!==predicate?$scope.tabs[tab].column=predicate:$scope.sortTable(predicate,tab)},$scope.supportsAction=function(node,tab){return!$scope.tabs[tab].actionOption||node.actions.indexOf($scope.tabs[tab].actionOption.name)>=0},$scope.actionOptionSelected=function(tab){updateActionErrorCount(tab),enterViewSelected(tab),"machines"===tab?angular.isObject($scope.addHardwareScope)&&$scope.addHardwareScope.hide():"devices"===tab&&angular.isObject($scope.addDeviceScope)&&$scope.addDeviceScope.hide()},$scope.isActionError=function(tab){return!(!angular.isObject($scope.tabs[tab].actionOption)||"deploy"!==$scope.tabs[tab].actionOption.name||0!==$scope.tabs[tab].actionErrorCount||0!==$scope.osinfo.osystems.length&&0!==UsersManager.getSSHKeyCount())||0!==$scope.tabs[tab].actionErrorCount},$scope.isDeployError=function(tab){return 0===$scope.tabs[tab].actionErrorCount&&!(!angular.isObject($scope.tabs[tab].actionOption)||"deploy"!==$scope.tabs[tab].actionOption.name||0!==$scope.osinfo.osystems.length)},$scope.isSSHKeyError=function(tab){return 0===$scope.tabs[tab].actionErrorCount&&!(!angular.isObject($scope.tabs[tab].actionOption)||"deploy"!==$scope.tabs[tab].actionOption.name||0!==UsersManager.getSSHKeyCount())},$scope.actionCancel=function(tab){resetActionProgress(tab),leaveViewSelected(tab),$scope.tabs[tab].actionOption=null},$scope.actionGo=function(tabName){var i,tab=$scope.tabs[tabName],extra={},deferred=$q.defer(),preAction=deferred.promise;if(deferred.resolve(),"deploy"===tab.actionOption.name&&angular.isString(tab.osSelection.osystem)&&angular.isString(tab.osSelection.release)){extra.osystem=tab.osSelection.osystem;var release=tab.osSelection.release;release=(release=release.split("/"))[release.length-1],extra.distro_series=release,angular.isString(tab.osSelection.hwe_kernel)&&(tab.osSelection.hwe_kernel.indexOf("hwe-")>=0||tab.osSelection.hwe_kernel.indexOf("ga-")>=0)&&(extra.hwe_kernel=tab.osSelection.hwe_kernel)}else if("set-zone"===tab.actionOption.name&&angular.isNumber(tab.zoneSelection.id))extra.zone_id=tab.zoneSelection.id;else if("set-pool"===tab.actionOption.name)"create-pool"===tab.poolAction&&void 0!==tab.newPool.name?preAction=ResourcePoolsManager.createItem({name:tab.newPool.name}).then(function(newPool){extra.pool_id=newPool.id}):angular.isNumber(tab.poolSelection.id)&&(extra.pool_id=tab.poolSelection.id);else if("commission"===tab.actionOption.name){for(extra.enable_ssh=tab.commissionOptions.enableSSH,extra.skip_networking=tab.commissionOptions.skipNetworking,extra.skip_storage=tab.commissionOptions.skipStorage,extra.commissioning_scripts=[],i=0;i<tab.commissioningSelection.length;i++)extra.commissioning_scripts.push(tab.commissioningSelection[i].id);for(tab.commissionOptions.updateFirmware&&extra.commissioning_scripts.push("update_firmware"),tab.commissionOptions.configureHBA&&extra.commissioning_scripts.push("configure_hba"),0===extra.commissioning_scripts.length&&extra.commissioning_scripts.push("none"),extra.testing_scripts=[],i=0;i<tab.testSelection.length;i++)extra.testing_scripts.push(tab.testSelection[i].id);0===extra.testing_scripts.length&&extra.testing_scripts.push("none")}else if("test"===tab.actionOption.name){if(!tab.actionProgress.showing_confirmation){var progress=tab.actionProgress;for(i=0;i<tab.selectedItems.length;i++)6===tab.selectedItems[i].status_code&&(progress.showing_confirmation=!0,progress.affected_nodes++);if(0!=tab.actionProgress.affected_nodes)return}for(extra.enable_ssh=tab.commissionOptions.enableSSH,extra.testing_scripts=[],i=0;i<tab.testSelection.length;i++)extra.testing_scripts.push(tab.testSelection[i].id);0===extra.testing_scripts.length&&extra.testing_scripts.push("none")}else"release"===tab.actionOption.name&&(extra.erase=tab.releaseOptions.erase,extra.secure_erase=tab.releaseOptions.secureErase,extra.quick_erase=tab.releaseOptions.quickErase);preAction.then(function(){resetActionProgress(tabName),tab.actionProgress.total=tab.selectedItems.length,angular.forEach(tab.selectedItems,function(node){tab.manager.performAction(node,tab.actionOption.name,extra).then(function(){tab.actionProgress.completed+=1,node.action_failed=!1,updateSelectedItems(tabName)},function(error){addErrorToActionProgress(tabName,error,node),node.action_failed=!0,updateSelectedItems(tabName)})})},function(error){addErrorToActionProgress(tabName,error)})},$scope.hasActionsInProgress=function(tab){var progress=$scope.tabs[tab].actionProgress;return progress.total>0&&progress.completed!==progress.total},$scope.hasActionsFailed=function(tab){return Object.keys($scope.tabs[tab].actionProgress.errors).length>0},$scope.addHardwareOptionChanged=function(){$scope.addHardwareOption&&$scope.addHardwareScope.show($scope.addHardwareOption.name)},$scope.addDevice=function(){$scope.addDeviceScope.show()},$scope.cancelAddDevice=function(){$scope.addDeviceScope.cancel()},$scope.getDeviceIPAssignment=function(ipAssignment){return DEVICE_IP_ASSIGNMENT[ipAssignment]},$scope.isSuperUser=function(){return UsersManager.isSuperUser()},$scope.hasCustomCommissioningScripts=function(){var i;for(i=0;i<$scope.scripts.length;i++)if(0===$scope.scripts[i].script_type)return!0;return!1},$scope.$on("$routeUpdate",function(){GeneralManager.loadItems(["osinfo"])}),angular.forEach(["machines","pools","devices","controllers","switches"],function(node_type){-1!==$location.path().indexOf("/"+node_type)&&$scope.toggleTab(node_type)});var page_managers=[$scope.tabs[$scope.currentpage].manager];"machines"!==$scope.currentpage&&"controllers"!==$scope.currentpage||page_managers.push(ScriptsManager),ManagerHelperService.loadManagers($scope,[GeneralManager,ZonesManager,UsersManager,ResourcePoolsManager,ServicesManager].concat(page_managers)).then(function(){$scope.loading=!1}),$scope.$on("$destroy",function(){$interval.cancel($scope.statusPoll),SearchService.storeFilters("machines",$scope.tabs.machines.filters),SearchService.storeFilters("devices",$scope.tabs.devices.filters),SearchService.storeFilters("controllers",$scope.tabs.controllers.filters),SearchService.storeFilters("switches",$scope.tabs.switches.filters)});var machinesFilter=SearchService.retrieveFilters("machines");angular.isObject(machinesFilter)&&($scope.tabs.machines.search=SearchService.filtersToString(machinesFilter),$scope.updateFilters("machines"));var devicesFilter=SearchService.retrieveFilters("devices");angular.isObject(devicesFilter)&&($scope.tabs.devices.search=SearchService.filtersToString(devicesFilter),$scope.updateFilters("devices"));var controllersFilter=SearchService.retrieveFilters("controllers");angular.isObject(controllersFilter)&&($scope.tabs.controllers.search=SearchService.filtersToString(controllersFilter),$scope.updateFilters("controllers"));var switchesFilter=SearchService.retrieveFilters("switches");angular.isObject(switchesFilter)&&($scope.tabs.switches.search=SearchService.filtersToString(switchesFilter),$scope.updateFilters("switches"));var query=$routeParams.query;angular.isString(query)&&($scope.tabs[$scope.currentpage].search=query,$scope.updateFilters($scope.currentpage))}])},"./src/maasserver/static/js/angular/controllers/pod_details.js":function(module,exports){angular.module("MAAS").controller("PodDetailsController",["$scope","$rootScope","$location","$routeParams","PodsManager","GeneralManager","UsersManager","DomainsManager","ZonesManager","MachinesManager","ManagerHelperService","ErrorService","ResourcePoolsManager",function($scope,$rootScope,$location,$routeParams,PodsManager,GeneralManager,UsersManager,DomainsManager,ZonesManager,MachinesManager,ManagerHelperService,ErrorService,ResourcePoolsManager){$rootScope.title="Loading...",$rootScope.page="pods",$scope.loaded=!1,$scope.pod=null,$scope.podManager=PodsManager,$scope.action={option:null,options:[{name:"refresh",title:"Refresh",sentence:"refresh",operation:angular.bind(PodsManager,PodsManager.refresh)},{name:"delete",title:"Delete",sentence:"delete",operation:angular.bind(PodsManager,PodsManager.deleteItem)}],inProgress:!1,error:null},$scope.compose={action:{name:"compose",title:"Compose",sentence:"compose"},obj:{storage:[{type:"local",size:8,tags:[],boot:!0}]}},$scope.power_types=GeneralManager.getData("power_types"),$scope.domains=DomainsManager.getItems(),$scope.zones=ZonesManager.getItems(),$scope.pools=ResourcePoolsManager.getItems(),$scope.section={area:"summary"},$scope.machinesSearch="pod-id:=invalid",$scope.editing=!1,$scope.isSuperUser=function(){return UsersManager.isSuperUser()},$scope.isRackControllerConnected=function(){return $scope.power_types.length>0},$scope.canEdit=function(){return $scope.isRackControllerConnected()&&$scope.isSuperUser()},$scope.editPodConfiguration=function(){$scope.canEdit()&&($scope.editing=!0)},$scope.exitEditPodConfiguration=function(){$scope.editing=!1},$scope.isActionError=function(){return null!==$scope.action.error},$scope.actionOptionChanged=function(){$scope.action.error=null},$scope.actionCancel=function(){$scope.action.option=null,$scope.action.error=null},$scope.actionGo=function(){$scope.action.inProgress=!0,$scope.action.option.operation($scope.pod).then(function(){"delete"===$scope.action.option.name&&$location.path("/pods"),$scope.action.inProgress=!1,$scope.action.option=null,$scope.action.error=null},function(error){$scope.action.inProgress=!1,$scope.action.error=error})},$scope.getPodTypeTitle=function(){var i;for(i=0;i<$scope.power_types.length;i++){var power_type=$scope.power_types[i];if(power_type.name===$scope.pod.type)return power_type.description}return $scope.pod.type},$scope.canCompose=function(){return!!angular.isObject($scope.pod)&&($scope.isSuperUser()&&$scope.pod.capabilities.indexOf("composable")>=0)},$scope.composeMachine=function(){$scope.action.option=$scope.compose.action},$scope.composePreProcess=function(params){(params=angular.copy(params)).id=$scope.pod.id;var sorted=$scope.compose.obj.storage.sort(function(a,b){return a.boot===b.boot?0:a.boot&&!b.boot?-1:1}),storage=[];return angular.forEach(sorted,function(disk,idx){var constraint=idx+":"+disk.size,tags=disk.tags.map(function(tag){return tag.text});tags.splice(0,0,disk.type),constraint+="("+tags.join(",")+")",storage.push(constraint)}),params.storage=storage.join(","),params},$scope.cancelCompose=function(){$scope.compose.obj={storage:[{type:"local",size:8,tags:[],boot:!0}]},$scope.action.option=null},$scope.composeAddStorage=function(){var storage={type:"local",size:8,tags:[],boot:!1};$scope.pod.capabilities.indexOf("iscsi_storage")>=0&&(storage.type="iscsi"),$scope.compose.obj.storage.push(storage)},$scope.composeSetBootDisk=function(storage){angular.forEach($scope.compose.obj.storage,function(disk){disk.boot=!1}),storage.boot=!0},$scope.composeRemoveDisk=function(storage){var idx=$scope.compose.obj.storage.indexOf(storage);idx>=0&&$scope.compose.obj.storage.splice(idx,1)},$scope.startWatching=function(){$scope.$watch("pod.name",function(){$rootScope.title="Pod "+$scope.pod.name}),$scope.$watch("pod.capabilities",function(){var idx=$scope.action.options.indexOf($scope.compose.action);$scope.canCompose()?-1===idx&&$scope.action.options.splice(0,0,$scope.compose.action):idx>=0&&$scope.action.options.splice(idx,1)}),$scope.$watch("action.option",function(now,then){now&&"compose"===now.name&&(then&&"compose"===then.name||($scope.compose.obj.domain=DomainsManager.getDefaultDomain().id,$scope.compose.obj.zone=ZonesManager.getDefaultZone().id,$scope.compose.obj.pool=$scope.pod.default_pool))})},ManagerHelperService.loadManagers($scope,[PodsManager,GeneralManager,UsersManager,DomainsManager,ZonesManager,MachinesManager,ResourcePoolsManager]).then(function(){var activePod=PodsManager.getActiveItem();angular.isObject(activePod)&&activePod.id===parseInt($routeParams.id,10)?($scope.pod=activePod,$scope.loaded=!0,$scope.machinesSearch="pod-id:="+$scope.pod.id,$scope.startWatching()):PodsManager.setActiveItem(parseInt($routeParams.id,10)).then(function(pod){$scope.pod=pod,$scope.loaded=!0,$scope.machinesSearch="pod-id:="+$scope.pod.id,$scope.startWatching()},function(error){ErrorService.raiseError(error)})})}])},"./src/maasserver/static/js/angular/controllers/pods_list.js":function(module,exports){angular.module("MAAS").controller("PodsListController",["$scope","$rootScope","PodsManager","UsersManager","GeneralManager","ZonesManager","ManagerHelperService","ResourcePoolsManager",function($scope,$rootScope,PodsManager,UsersManager,GeneralManager,ZonesManager,ManagerHelperService,ResourcePoolsManager){function updateAllViewableChecked(){if(0!==$scope.pods.length){var i;for(i=0;i<$scope.pods.length;i++)if(!$scope.pods[i].$selected)return void($scope.allViewableChecked=!1);$scope.allViewableChecked=!0}else $scope.allViewableChecked=!1}function clearAction(){resetActionProgress(),$scope.action.option=null}function shouldClearAction(){0===$scope.selectedItems.length&&(clearAction(),$scope.action.option&&($scope.action.option=null))}function resetActionProgress(){var progress=$scope.action.progress;progress.completed=progress.total=progress.errors=0,angular.forEach($scope.pods,function(pod){delete pod.action_failed})}function updateSelectedItems(){$scope.hasActionsFailed()?(angular.forEach($scope.pods,function(pod){!1===pod.action_failed&&PodsManager.unselectItem(pod.id)}),shouldClearAction()):$scope.hasActionsInProgress()||clearAction()}$rootScope.title="Pods",$rootScope.page="pods",$scope.podManager=PodsManager,$scope.pods=PodsManager.getItems(),$scope.loading=!0,$scope.filteredItems=[],$scope.selectedItems=PodsManager.getSelectedItems(),$scope.predicate="name",$scope.allViewableChecked=!1,$scope.action={option:null,options:[{name:"refresh",title:"Refresh",sentence:"refresh",operation:angular.bind(PodsManager,PodsManager.refresh)},{name:"delete",title:"Delete",sentence:"delete",operation:angular.bind(PodsManager,PodsManager.deleteItem)}],progress:{total:0,completed:0,errors:0}},$scope.add={open:!1,obj:{cpu_over_commit_ratio:1,memory_over_commit_ratio:1}},$scope.powerTypes=GeneralManager.getData("power_types"),$scope.zones=ZonesManager.getItems(),$scope.pools=ResourcePoolsManager.getItems(),$scope.toggleChecked=function(pod){PodsManager.isSelected(pod.id)?PodsManager.unselectItem(pod.id):PodsManager.selectItem(pod.id),updateAllViewableChecked(),shouldClearAction()},$scope.toggleCheckAll=function(){$scope.allViewableChecked?angular.forEach($scope.pods,function(pod){PodsManager.unselectItem(pod.id)}):angular.forEach($scope.pods,function(pod){PodsManager.selectItem(pod.id)}),updateAllViewableChecked(),shouldClearAction()},$scope.$watchCollection("pods",function(){updateAllViewableChecked()}),$scope.sortTable=function(predicate){$scope.predicate=predicate,$scope.reverse=!$scope.reverse},$scope.actionCancel=function(){resetActionProgress(),$scope.action.option=null},$scope.actionGo=function(){resetActionProgress(),$scope.action.progress.total=$scope.selectedItems.length;var operation=$scope.action.option.operation;angular.forEach($scope.selectedItems,function(pod){operation(pod).then(function(){$scope.action.progress.completed+=1,pod.action_failed=!1,updateSelectedItems()},function(error){$scope.action.progress.errors+=1,pod.action_error=error,pod.action_failed=!0,updateSelectedItems()})})},$scope.hasActionsInProgress=function(){var progress=$scope.action.progress;return progress.total>0&&progress.completed+progress.errors!==progress.total},$scope.hasActionsFailed=function(){return $scope.action.progress.errors>0},$scope.addPod=function(){$scope.add.open=!0,$scope.add.obj.zone=ZonesManager.getDefaultZone().id,$scope.add.obj.default_pool=ResourcePoolsManager.getDefaultPool().id,$scope.add.obj.cpu_over_commit_ratio=1,$scope.add.obj.memory_over_commit_ratio=1},$scope.cancelAddPod=function(){$scope.add.open=!1,$scope.add.obj={}},$scope.isSuperUser=function(){return UsersManager.isSuperUser()},$scope.isRackControllerConnected=function(){return $scope.powerTypes.length>0},$scope.canAddPod=function(){return $scope.isRackControllerConnected()&&$scope.isSuperUser()},$scope.getPowerTypeTitle=function(power_type){var i;for(i=0;i<$scope.powerTypes.length;i++){var powerType=$scope.powerTypes[i];if(powerType.name===power_type)return powerType.description}return power_type},ManagerHelperService.loadManagers($scope,[PodsManager,UsersManager,GeneralManager,ZonesManager,ResourcePoolsManager]).then(function(){$scope.loading=!1})}])},"./src/maasserver/static/js/angular/controllers/prefs.js":function(module,exports){angular.module("MAAS").controller("PreferencesController",["$scope","UsersManager","ManagerHelperService",function($scope,UsersManager,ManagerHelperService){$scope.loading=!0,ManagerHelperService.loadManager($scope,UsersManager).then(function(){$scope.loading=!1})}])},"./src/maasserver/static/js/angular/controllers/settings.js":function(module,exports){angular.module("MAAS").controller("SettingsController",["$scope","$rootScope","$routeParams","PackageRepositoriesManager","DHCPSnippetsManager","MachinesManager","ControllersManager","DevicesManager","SubnetsManager","GeneralManager","ManagerHelperService",function($scope,$rootScope,$routeParams,PackageRepositoriesManager,DHCPSnippetsManager,MachinesManager,ControllersManager,DevicesManager,SubnetsManager,GeneralManager,ManagerHelperService){$rootScope.title="Loading...",$rootScope.page="settings",$scope.loading=!0,$scope.snippetsManager=DHCPSnippetsManager,$scope.snippets=DHCPSnippetsManager.getItems(),$scope.subnets=SubnetsManager.getItems(),$scope.machines=MachinesManager.getItems(),$scope.devices=DevicesManager.getItems(),$scope.controllers=ControllersManager.getItems(),$scope.known_architectures=GeneralManager.getData("known_architectures"),$scope.pockets_to_disable=GeneralManager.getData("pockets_to_disable"),$scope.components_to_disable=GeneralManager.getData("components_to_disable"),$scope.packageRepositoriesManager=PackageRepositoriesManager,$scope.repositories=PackageRepositoriesManager.getItems(),$scope.newSnippet=null,$scope.editSnippet=null,$scope.deleteSnippet=null,$scope.snippetTypes=["Global","Subnet","Node"],$scope.newRepository=null,$scope.editRepository=null,$scope.deleteRepository=null,$scope.repositoryEnabledToggle=function(repository){PackageRepositoriesManager.updateItem(repository)},$scope.repositoryEnterRemove=function(repository){$scope.newRepository=null,$scope.editRepository=null,$scope.deleteRepository=repository},$scope.repositoryExitRemove=function(){$scope.deleteRepository=null},$scope.repositoryConfirmRemove=function(){PackageRepositoriesManager.deleteItem($scope.deleteRepository).then(function(){$scope.repositoryExitRemove()})},$scope.isPPA=function(data){return!!angular.isObject(data)&&(!!angular.isString(data.url)&&(0===data.url.indexOf("ppa:")||data.url.indexOf("ppa.launchpad.net")>-1))},$scope.isMirror=function(data){return!!angular.isObject(data)&&(!!angular.isString(data.name)&&("main_archive"===data.name||"ports_archive"===data.name))},$scope.repositoryEnterEdit=function(repository){$scope.newRepository=null,$scope.deleteRepository=null,$scope.editRepository=repository},$scope.repositoryExitEdit=function(){$scope.editRepository=null},$scope.repositoryAdd=function(isPPA){var repo={name:"",enabled:!0,url:"",key:"",arches:["i386","amd64"],distributions:[],components:[]};isPPA&&(repo.url="ppa:"),$scope.newRepository=repo},$scope.repositoryAddCancel=function(){$scope.newRepository=null},$scope.getSubnetName=function(subnet){return SubnetsManager.getName(subnet)},$scope.getSnippetTypeText=function(snippet){return angular.isString(snippet.node)?"Node":angular.isNumber(snippet.subnet)?"Subnet":"Global"},$scope.getSnippetAppliesToObject=function(snippet){return angular.isString(snippet.node)?(system_id=snippet.node,node=MachinesManager.getItemFromList(system_id),angular.isObject(node)?node:(node=DevicesManager.getItemFromList(system_id),angular.isObject(node)?node:(node=ControllersManager.getItemFromList(system_id),angular.isObject(node)?node:void 0))):angular.isNumber(snippet.subnet)?SubnetsManager.getItemFromList(snippet.subnet):void 0;var system_id,node},$scope.getSnippetAppliesToText=function(snippet){var obj=$scope.getSnippetAppliesToObject(snippet);return angular.isString(snippet.node)&&angular.isObject(obj)?obj.fqdn:angular.isNumber(snippet.subnet)&&angular.isObject(obj)?SubnetsManager.getName(obj):""},$scope.snippetEnterRemove=function(snippet){$scope.newSnippet=null,$scope.editSnippet=null,$scope.deleteSnippet=snippet},$scope.snippetExitRemove=function(){$scope.deleteSnippet=null},$scope.snippetConfirmRemove=function(){DHCPSnippetsManager.deleteItem($scope.deleteSnippet).then(function(){$scope.snippetExitRemove()})},$scope.snippetEnterEdit=function(snippet){$scope.newSnippet=null,$scope.deleteSnippet=null,$scope.editSnippet=snippet,$scope.editSnippet.type=$scope.getSnippetTypeText(snippet)},$scope.snippetExitEdit=function(){$scope.editSnippet=null},$scope.snippetToggle=function(snippet){DHCPSnippetsManager.updateItem(snippet).then(null,function(error){snippet.enabled=!snippet.enabled,console.log(error)})},$scope.snippetAdd=function(){$scope.editSnippet=null,$scope.deleteSnippet=null,$scope.newSnippet={name:"",type:"Global",enabled:!0}},$scope.snippetAddCancel=function(){$scope.newSnippet=null},"dhcp"===$routeParams.section?($rootScope.title="DHCP snippets",$scope.currentpage="dhcp"):"repositories"===$routeParams.section&&($rootScope.title="Package repositories",$scope.currentpage="repositories"),ManagerHelperService.loadManagers($scope,[PackageRepositoriesManager,DHCPSnippetsManager,MachinesManager,DevicesManager,ControllersManager,SubnetsManager,GeneralManager]).then(function(){$scope.loading=!1})}])},"./src/maasserver/static/js/angular/controllers/space_details.js":function(module,exports){angular.module("MAAS").controller("SpaceDetailsController",["$scope","$rootScope","$routeParams","$filter","$location","SpacesManager","VLANsManager","SubnetsManager","FabricsManager","UsersManager","ManagerHelperService","ErrorService",function($scope,$rootScope,$routeParams,$filter,$location,SpacesManager,VLANsManager,SubnetsManager,FabricsManager,UsersManager,ManagerHelperService,ErrorService){function spaceLoaded(space){$scope.space=space,$rootScope.title=$scope.space.name,$scope.predicate="[subnet_name, vlan_name]",$scope.$watch("subnets",updateSubnets,!0),updateSubnets(),$scope.loaded=!0}function updateSubnets(){var rows=[];angular.forEach($filter("filter")($scope.subnets,{space:$scope.space.id},!0),function(subnet){var vlan=VLANsManager.getItemFromList(subnet.vlan),fabric=FabricsManager.getItemFromList(vlan.fabric),row={vlan:vlan,vlan_name:VLANsManager.getName(vlan),subnet:subnet,subnet_name:SubnetsManager.getName(subnet),fabric:fabric,fabric_name:fabric.name};rows.push(row)}),$scope.rows=rows}$rootScope.title="Loading...",$rootScope.page="networks",$scope.space=null,$scope.spaceManager=SpacesManager,$scope.subnets=SubnetsManager.getItems(),$scope.loaded=!1,$scope.editSummary=!1,$scope.isSuperUser=function(){return UsersManager.isSuperUser()},$scope.enterEditSummary=function(){$scope.editSummary=!0},$scope.exitEditSummary=function(){$scope.editSummary=!1},$scope.isDefaultSpace=function(){return!!angular.isObject($scope.space)&&0===$scope.space.id},$scope.canBeDeleted=function(){return!!angular.isObject($scope.space)&&0===$scope.space.subnet_ids.length},$scope.deleteButton=function(){$scope.error=null,$scope.confirmingDelete=!0},$scope.cancelDeleteButton=function(){$scope.confirmingDelete=!1},$scope.deleteConfirmButton=function(){SpacesManager.deleteSpace($scope.space).then(function(){$scope.confirmingDelete=!1,$location.path("/networks"),$location.search("by","space")},function(error){$scope.error=ManagerHelperService.parseValidationError(error)})},ManagerHelperService.loadManagers($scope,[SpacesManager,SubnetsManager,VLANsManager,FabricsManager,UsersManager]).then(function(){var activeSpace=SpacesManager.getActiveItem(),requestedSpace=parseInt($routeParams.space_id,10);isNaN(requestedSpace)?ErrorService.raiseError("Invalid space identifier."):angular.isObject(activeSpace)&&activeSpace.id===requestedSpace?spaceLoaded(activeSpace):SpacesManager.setActiveItem(requestedSpace).then(function(space){spaceLoaded(space)},function(error){ErrorService.raiseError(error)})})}])},"./src/maasserver/static/js/angular/controllers/subnet_details.js":function(module,exports){angular.module("MAAS").filter("filterSource",["ValidationService",function(){return function(subnets,source){var filtered=[];return angular.forEach(subnets,function(subnet){subnet.id!==source.id&&subnet.version===source.version&&filtered.push(subnet)}),filtered}}]),angular.module("MAAS").controller("SubnetDetailsController",["$scope","$rootScope","$routeParams","$filter","$location","ConfigsManager","SubnetsManager","SpacesManager","VLANsManager","UsersManager","FabricsManager","StaticRoutesManager","ManagerHelperService","ErrorService","ConverterService",function($scope,$rootScope,$routeParams,$filter,$location,ConfigsManager,SubnetsManager,SpacesManager,VLANsManager,UsersManager,FabricsManager,StaticRoutesManager,ManagerHelperService,ErrorService,ConverterService){$rootScope.title="Loading...",$rootScope.page="networks",$scope.loaded=!1,$scope.subnet=null,$scope.editSummary=!1,$scope.active_discovery_data=null,$scope.active_discovery_interval=null,$scope.subnets=SubnetsManager.getItems(),$scope.subnetManager=SubnetsManager,$scope.staticRoutes=StaticRoutesManager.getItems(),$scope.staticRoutesManager=StaticRoutesManager,$scope.space=null,$scope.vlans=VLANsManager.getItems(),$scope.fabrics=FabricsManager.getItems(),$scope.actionError=null,$scope.actionOption=null,$scope.actionOptions=[],$scope.reverse=!1,$scope.newStaticRoute=null,$scope.editStaticRoute=null,$scope.deleteStaticRoute=null,$scope.MAP_SUBNET_ACTION={name:"map_subnet",title:"Map subnet"},$scope.DELETE_ACTION={name:"delete",title:"Delete"};var ALLOC_TYPES={0:"Automatic",1:"Static",4:"User reserved",5:"DHCP",6:"Observed"},NODE_TYPES={0:"Machine",1:"Device",2:"Rack controller",3:"Region controller",4:"Rack and region controller",5:"Chassis",6:"Storage"};function updateTitle(){subnet=$scope.subnet,subnet&&subnet.cidr&&($rootScope.title=subnet.cidr,subnet.name&&subnet.cidr!==subnet.name&&($rootScope.title+=" ("+subnet.name+")"))}function updateIPVersion(){-1===$scope.subnet.cidr.split("/")[0].indexOf(":")?$scope.ipVersion=4:$scope.ipVersion=6}function subnetLoaded(subnet){$scope.subnet=subnet,$scope.loaded=!0,updateTitle();var updateFabric=function(){$scope.subnet.fabric=VLANsManager.getItemFromList($scope.subnet.vlan).fabric,$scope.subnet.fabric_name=FabricsManager.getItemFromList(subnet.fabric).name};$scope.$watch("subnet.fabric",updateFabric),$scope.$watch("subnet.fabric_name",updateFabric),$scope.$watch("subnet.vlan",updateFabric),$scope.$watch("subnet.vlan_name",function(){var vlan=VLANsManager.getItemFromList($scope.subnet.vlan);$scope.subnet.vlan_name=VLANsManager.getName(vlan)}),$scope.$watch("subnet.space",function(){$scope.space=SpacesManager.getItemFromList($scope.subnet.space)}),$scope.$watch("subnet.cidr",updateIPVersion)}$scope.ipSort=function(ipAddress){return 4===$scope.ipVersion?ConverterService.ipv4ToInteger(ipAddress.ip):ConverterService.ipv6Expand(ipAddress.ip)},$scope.predicate=$scope.ipSort,$scope.getAllocType=function(allocType){var str=ALLOC_TYPES[allocType];return angular.isString(str)?str:"Unknown"},$scope.getSubnetCIDR=function(destId){return SubnetsManager.getItemFromList(destId).cidr},$scope.allocTypeSort=function(ipAddress){return $scope.getAllocType(ipAddress.alloc_type)},$scope.getUsageForIP=function(ip){if(angular.isObject(ip.node_summary)){var isContainer=ip.node_summary.is_container,nodeType=ip.node_summary.node_type;if(1===nodeType&&!0===isContainer)return"Container";var str=NODE_TYPES[nodeType];return angular.isString(str)?str:"Unknown"}return angular.isObject(ip.bmcs)?"BMC":angular.isObject(ip.dns_records)?"DNS":"Unknown"},$scope.nodeTypeSort=function(ipAddress){return $scope.getUsageForIP(ipAddress)},$scope.ownerSort=function(ipAddress){var owner=ipAddress.user;return angular.isString(owner)&&owner.length>0?owner:"MAAS"},$scope.sortIPTable=function(predicate){$scope.predicate=predicate,$scope.reverse=!$scope.reverse},$scope.getVLANName=function(vlan){return VLANsManager.getName(vlan)},$scope.isSuperUser=function(){return UsersManager.isSuperUser()},$scope.actionRetry=function(){$scope.actionError=null},$scope.actionGo=function(){"map_subnet"===$scope.actionOption.name?SubnetsManager.scanSubnet($scope.subnet).then(function(result){result&&0===result.scan_started_on.length?$scope.actionError=ManagerHelperService.parseValidationError(result.result):($scope.actionOption=null,$scope.actionError=null)},function(error){$scope.actionError=ManagerHelperService.parseValidationError(error)}):"delete"===$scope.actionOption.name&&SubnetsManager.deleteSubnet($scope.subnet).then(function(result){$scope.actionOption=null,$scope.actionError=null,$location.path("/networks")},function(error){$scope.actionError=ManagerHelperService.parseValidationError(error)})},$scope.actionChanged=function(){$scope.actionError=null},$scope.cancelAction=function(){$scope.actionOption=null,$scope.actionError=null},$scope.updateActions=function(){UsersManager.isSuperUser()?$scope.actionOptions=[$scope.MAP_SUBNET_ACTION,$scope.DELETE_ACTION]:$scope.actionOptions=[]},$scope.enterEditSummary=function(){$scope.editSummary=!0},$scope.exitEditSummary=function(){$scope.editSummary=!1},$scope.subnetPreSave=function(subnet,changedFields){return-1!==changedFields.indexOf("fabric")&&(subnet.vlan=FabricsManager.getItemFromList(subnet.fabric).default_vlan_id),subnet},$scope.addStaticRoute=function(){$scope.editStaticRoute=null,$scope.deleteStaticRoute=null,$scope.newStaticRoute={source:$scope.subnet.id,gateway_ip:"",destination:null,metric:0}},$scope.cancelAddStaticRoute=function(){$scope.newStaticRoute=null},$scope.isStaticRouteInEditMode=function(route){return $scope.editStaticRoute===route},$scope.staticRouteToggleEditMode=function(route){$scope.newStaticRoute=null,$scope.deleteStaticRoute=null,$scope.isStaticRouteInEditMode(route)?$scope.editStaticRoute=null:$scope.editStaticRoute=route},$scope.isStaticRouteInDeleteMode=function(route){return $scope.deleteStaticRoute===route},$scope.staticRouteEnterDeleteMode=function(route){$scope.newStaticRoute=null,$scope.editStaticRoute=null,$scope.deleteStaticRoute=route},$scope.staticRouteCancelDelete=function(){$scope.deleteStaticRoute=null},$scope.staticRouteConfirmDelete=function(){StaticRoutesManager.deleteItem($scope.deleteStaticRoute).then(function(){$scope.deleteStaticRoute=null})},ManagerHelperService.loadManagers($scope,[ConfigsManager,SubnetsManager,SpacesManager,VLANsManager,UsersManager,FabricsManager,StaticRoutesManager]).then(function(){$scope.updateActions(),$scope.active_discovery_data=ConfigsManager.getItemFromList("active_discovery_interval"),angular.forEach($scope.active_discovery_data.choices,function(choice){choice[0]===$scope.active_discovery_data.value&&($scope.active_discovery_interval=choice[1])});var activeSubnet=SubnetsManager.getActiveItem(),requestedSubnet=parseInt($routeParams.subnet_id,10);isNaN(requestedSubnet)?ErrorService.raiseError("Invalid subnet identifier."):angular.isObject(activeSubnet)&&activeSubnet.id===requestedSubnet?subnetLoaded(activeSubnet):SubnetsManager.setActiveItem(requestedSubnet).then(function(subnet){subnetLoaded(subnet)},function(error){ErrorService.raiseError(error)})})}])},"./src/maasserver/static/js/angular/controllers/vlan_details.js":function(module,exports){angular.module("MAAS").filter("ignoreSelf",function(){return function(objects,self){var filtered=[];return angular.forEach(objects,function(obj){obj!==self&&filtered.push(obj)}),filtered}}),angular.module("MAAS").controller("VLANDetailsController",["$scope","$rootScope","$routeParams","$filter","$location","VLANsManager","SubnetsManager","SpacesManager","FabricsManager","ControllersManager","UsersManager","ManagerHelperService","ErrorService","ValidationService",function($scope,$rootScope,$routeParams,$filter,$location,VLANsManager,SubnetsManager,SpacesManager,FabricsManager,ControllersManager,UsersManager,ManagerHelperService,ErrorService,ValidationService){var vm=this,filterByVLAN=$filter("filterByVLAN");$filter("filterControllersByVLAN");function updateTitle(){var vlan=vm.vlan,fabric=vm.fabric;angular.isObject(vlan)&&angular.isObject(fabric)&&(vlan.name?vm.title=vlan.name:0===vlan.vid?vm.title="Default VLAN":vm.title="VLAN "+vlan.vid,vm.title+=" in "+fabric.name,$rootScope.title=vm.title)}function updateManagementRacks(){var vlan=vm.vlan;angular.isObject(vlan)&&(vlan.primary_rack?vm.primaryRack=ControllersManager.getItemFromList(vlan.primary_rack):vm.primaryRack=null,vlan.secondary_rack?vm.secondaryRack=ControllersManager.getItemFromList(vlan.secondary_rack):vm.secondaryRack=null)}function updateRelatedControllers(){var vlan=vm.vlan;if(angular.isObject(vlan)){var racks=[];angular.forEach(vlan.rack_sids,function(rack_sid){var rack=ControllersManager.getItemFromList(rack_sid);angular.isObject(rack)&&racks.push(rack)}),vm.relatedControllers=racks}}function updateRelatedSubnets(){var vlan=vm.vlan;if(angular.isObject(vlan)){var subnets=[];angular.forEach(filterByVLAN(vm.subnets,vlan),function(subnet){var space=SpacesManager.getItemFromList(subnet.space);angular.isObject(space)||(space={name:"(undefined)"});var row={subnet:subnet,space:space};subnets.push(row)}),vm.relatedSubnets=subnets}}function updatePossibleActions(){var vlan=vm.vlan;angular.isObject(vlan)&&(vm.actionOptions.length=0,UsersManager.isSuperUser()&&(vlan.relay_vlan?(vm.actionOptions.push(vm.RELAY_DHCP_ACTION),vm.actionOptions.push(vm.DISABLE_DHCP_ACTION),vm.RELAY_DHCP_ACTION.title="Reconfigure DHCP relay"):!0===vlan.dhcp_on?(vm.PROVIDE_DHCP_ACTION.title="Reconfigure DHCP",vm.actionOptions.push(vm.PROVIDE_DHCP_ACTION),vm.actionOptions.push(vm.DISABLE_DHCP_ACTION)):(vm.PROVIDE_DHCP_ACTION.title="Provide DHCP",vm.RELAY_DHCP_ACTION.title="Relay DHCP",vm.actionOptions.push(vm.PROVIDE_DHCP_ACTION),vm.actionOptions.push(vm.RELAY_DHCP_ACTION)),vm.isFabricDefault||vm.actionOptions.push(vm.DELETE_ACTION)))}function vlanLoaded(vlan){vm.vlan=vlan,vm.fabric=FabricsManager.getItemFromList(vlan.fabric),vm.isFabricDefault=vm.fabric.default_vlan_id===vm.vlan.id,vm.loaded=!0,updateTitle(),updateManagementRacks(),updateRelatedControllers(),updateRelatedSubnets(),updatePossibleActions()}$rootScope.title="Loading...",$rootScope.page="networks",vm.PROVIDE_DHCP_ACTION={name:"enable_dhcp"},vm.RELAY_DHCP_ACTION={name:"relay_dhcp"},vm.DISABLE_DHCP_ACTION={name:"disable_dhcp",title:"Disable DHCP"},vm.DELETE_ACTION={name:"delete",title:"Delete"},vm.loaded=!1,vm.vlan=null,vm.title=null,vm.actionOption=null,vm.actionOptions=[],vm.vlanManager=VLANsManager,vm.vlans=VLANsManager.getItems(),vm.subnets=SubnetsManager.getItems(),vm.spaces=SpacesManager.getItems(),vm.fabrics=FabricsManager.getItems(),vm.controllers=ControllersManager.getItems(),vm.actionError=null,vm.relatedSubnets=[],vm.relatedControllers=[],vm.provideDHCPAction={},vm.primaryRack=null,vm.secondaryRack=null,vm.editSummary=!1,vm.isSuperUser=function(){return UsersManager.isSuperUser()},vm.enterEditSummary=function(){vm.editSummary=!0},vm.exitEditSummary=function(){vm.editSummary=!1},vm.getSpaceName=function(){var space=SpacesManager.getItemFromList(vm.vlan.space);return space?space.name:"(undefined)"},vm.getActionByName=function(name){var i;for(i=0;i<vm.actionOptions.length;i++)if(vm.actionOptions[i].name===name)return vm.actionOptions[i];return null},vm.initProvideDHCP=function(forRelay){vm.provideDHCPAction={};var dhcp=vm.provideDHCPAction;if(dhcp.subnet=null,dhcp.relayVLAN=null,angular.isNumber(vm.vlan.relay_vlan)&&(dhcp.relayVLAN=VLANsManager.getItemFromList(vm.vlan.relay_vlan)),angular.isObject(vm.primaryRack)?dhcp.primaryRack=vm.primaryRack.system_id:vm.relatedControllers.length>0&&(dhcp.primaryRack=vm.relatedControllers[0].system_id),angular.isObject(vm.secondaryRack)?dhcp.secondaryRack=vm.secondaryRack.system_id:vm.relatedControllers.length>1&&(dhcp.secondaryRack=vm.relatedControllers[1].system_id),dhcp.maxIPs=0,dhcp.startIP=null,dhcp.endIP=null,dhcp.gatewayIP="",angular.isObject(vm.relatedSubnets)){var i,subnet;for(vm.relatedSubnets.length>0&&angular.isObject(vm.relatedSubnets[0].subnet)&&(dhcp.subnet=vm.relatedSubnets[0].subnet.id),dhcp.needsDynamicRange=!0,i=0;i<vm.relatedSubnets.length;i++){var iprange=(subnet=vm.relatedSubnets[i].subnet).statistics.suggested_dynamic_range;if(!angular.isObject(iprange)){dhcp.subnet=subnet.id,dhcp.needsDynamicRange=!1;break}}for(dhcp.needsGatewayIP=!1,dhcp.subnetMissingGatewayIP=!0,i=0;i<vm.relatedSubnets.length;i++)if(null===(subnet=vm.relatedSubnets[i].subnet).gateway_ip||""===subnet.gateway_ip){dhcp.needsGatewayIP=!0;break}}forRelay||(vm.updatePrimaryRack(),vm.updateSecondaryRack()),vm.updateSubnet(forRelay)},vm.actionOptionChanged=function(){"enable_dhcp"===vm.actionOption.name?vm.initProvideDHCP(!1):"relay_dhcp"===vm.actionOption.name&&vm.initProvideDHCP(!0),vm.actionError=null},vm.actionCancel=function(){vm.actionOption=null,vm.actionError=null},vm.updatePrimaryRack=function(){var i,dhcp=vm.provideDHCPAction;for(dhcp.primaryRack===dhcp.secondaryRack&&(dhcp.secondaryRack=null),i=0;i<vm.relatedControllers.length;i++)if(vm.relatedControllers[i].system_id!==dhcp.primaryRack){dhcp.secondaryRack=vm.relatedControllers[i].system_id;break}},vm.updateSecondaryRack=function(){var dhcp=vm.provideDHCPAction;dhcp.primaryRack===dhcp.secondaryRack&&(dhcp.primaryRack=null,dhcp.secondaryRack=null)},vm.filterPrimaryRack=function(rack){var dhcp=vm.provideDHCPAction;return rack.system_id!==dhcp.primaryRack},vm.updateSubnet=function(forRelay){var dhcp=vm.provideDHCPAction,subnet=SubnetsManager.getItemFromList(dhcp.subnet);if(angular.isObject(subnet)){var suggested_gateway=null,iprange=null;angular.isObject(subnet.statistics)&&(suggested_gateway=subnet.statistics.suggested_gateway,iprange=subnet.statistics.suggested_dynamic_range),angular.isObject(iprange)&&iprange.num_addresses>0?(dhcp.maxIPs=iprange.num_addresses,forRelay?(dhcp.startIP="",dhcp.endIP="",dhcp.startPlaceholder=iprange.start+"(optional)",dhcp.endPlaceholder=iprange.end+" (optional)"):(dhcp.startIP=iprange.start,dhcp.endIP=iprange.end,dhcp.startPlaceholder=iprange.start,dhcp.endPlaceholder=iprange.end)):(dhcp.maxIPs=0,dhcp.startIP="",dhcp.endIP="",dhcp.startPlaceholder="(no available IPs)",dhcp.endPlaceholder="(no available IPs)"),angular.isString(suggested_gateway)?forRelay?(dhcp.gatewayIP="",dhcp.gatewayPlaceholder=suggested_gateway+" (optional)"):(dhcp.gatewayIP=suggested_gateway,dhcp.gatewayPlaceholder=suggested_gateway):(dhcp.gatewayIP="",dhcp.gatewayPlaceholder="")}else dhcp.maxIPs=0,dhcp.startIP=null,dhcp.endIP=null,dhcp.gatewayIP="";angular.isObject(subnet)?dhcp.subnetMissingGatewayIP=!angular.isString(subnet.gateway_ip):dhcp.subnetMissingGatewayIP=!1,!1===dhcp.subnetMissingGatewayIP&&(dhcp.gatewayIP=null)},vm.actionRetry=function(){vm.actionError=null},vm.canPerformAction=function(){return"enable_dhcp"===vm.actionOption.name?vm.relatedSubnets.length>0:"relay_dhcp"!==vm.actionOption.name||angular.isObject(vm.provideDHCPAction.relayVLAN)},vm.actionGo=function(){if(vm.canPerformAction())if("enable_dhcp"===vm.actionOption.name){var dhcp=vm.provideDHCPAction,controllers=[],extra={};if(extra.subnet=dhcp.subnet,extra.start=dhcp.startIP,extra.end=dhcp.endIP,extra.gateway=dhcp.gatewayIP,angular.isString(dhcp.primaryRack)&&controllers.push(dhcp.primaryRack),angular.isString(dhcp.secondaryRack)&&controllers.push(dhcp.secondaryRack),0===controllers.length)return void(vm.actionError="A primary rack controller must be specified.");VLANsManager.configureDHCP(vm.vlan,controllers,extra).then(function(){vm.actionOption=null,vm.actionError=null},function(result){vm.actionError=result.error,vm.actionOption=vm.PROVIDE_DHCP_ACTION})}else if("relay_dhcp"===vm.actionOption.name){var extraDHCP={};extraDHCP.subnet=vm.provideDHCPAction.subnet,extraDHCP.start=vm.provideDHCPAction.startIP,extraDHCP.end=vm.provideDHCPAction.endIP,extraDHCP.gateway=vm.provideDHCPAction.gatewayIP;var relay=vm.provideDHCPAction.relayVLAN.id;VLANsManager.configureDHCP(vm.vlan,[],extraDHCP,relay).then(function(){vm.actionOption=null,vm.actionError=null},function(result){vm.actionError=result.error,vm.actionOption=vm.RELAY_DHCP_ACTION})}else"disable_dhcp"===vm.actionOption.name?VLANsManager.disableDHCP(vm.vlan).then(function(){vm.actionOption=null,vm.actionError=null},function(result){vm.actionError=result.error,vm.actionOption=vm.DISABLE_DHCP_ACTION}):"delete"===vm.actionOption.name&&VLANsManager.deleteVLAN(vm.vlan).then(function(){$location.path("/networks"),vm.actionOption=null,vm.actionError=null},function(result){vm.actionError=result.error,vm.actionOption=vm.DELETE_ACTION})},vm.isActionError=function(){return null!==vm.actionError},vm.getFullVLANName=function(vlan_id){var vlan=VLANsManager.getItemFromList(vlan_id),fabric=FabricsManager.getItemFromList(vlan.fabric);return FabricsManager.getName(fabric)+"."+VLANsManager.getName(vlan)},vm.getDHCPStatus=function(){return vm.vlan?vm.vlan.dhcp_on?"Enabled":vm.vlan.relay_vlan?"Relayed via "+vm.getFullVLANName(vm.vlan.relay_vlan):"Disabled":""},ManagerHelperService.loadManagers($scope,[VLANsManager,SubnetsManager,SpacesManager,FabricsManager,ControllersManager,UsersManager]).then(function(){var activeVLAN=VLANsManager.getActiveItem(),requestedVLAN=parseInt($routeParams.vlan_id,10);isNaN(requestedVLAN)?ErrorService.raiseError("Invalid VLAN identifier."):angular.isObject(activeVLAN)&&activeVLAN.id===requestedVLAN?vlanLoaded(activeVLAN):VLANsManager.setActiveItem(requestedVLAN).then(function(vlan){vlanLoaded(vlan)},function(error){ErrorService.raiseError(error)}),$scope.$watch("vlanDetails.vlan.name",updateTitle),$scope.$watch("vlanDetails.vlan.vid",updateTitle),$scope.$watch("vlanDetails.vlan.dhcp_on",updatePossibleActions),$scope.$watch("vlanDetails.vlan.relay_vlan",updatePossibleActions),$scope.$watch("vlanDetails.fabric.name",updateTitle),$scope.$watch("vlanDetails.vlan.primary_rack",updateManagementRacks),$scope.$watch("vlanDetails.vlan.secondary_rack",updateManagementRacks),$scope.$watchCollection("vlanDetails.subnets",updateRelatedSubnets),$scope.$watchCollection("vlanDetails.spaces",updateRelatedSubnets),$scope.$watchCollection("vlanDetails.controllers",updateRelatedControllers)})}])},"./src/maasserver/static/js/angular/controllers/zone_details.js":function(module,exports){angular.module("MAAS").controller("ZoneDetailsController",["$scope","$rootScope","$routeParams","$location","MachinesManager","DevicesManager","ZonesManager","UsersManager","ManagerHelperService","ErrorService",function($scope,$rootScope,$routeParams,$location,MachinesManager,DevicesManager,ZonesManager,UsersManager,ManagerHelperService,ErrorService){function zoneLoaded(zone){$scope.zone=zone,$scope.loaded=!0,$rootScope.title=$scope.zone.name}$rootScope.title="Loading...",$rootScope.page="zones",$scope.loaded=!1,$scope.zone=null,$scope.zoneManager=ZonesManager,$scope.editSummary=!1,$scope.predicate="name",$scope.reverse=!1,$scope.enterEditSummary=function(){$scope.editSummary=!0},$scope.exitEditSummary=function(){$scope.editSummary=!1},$scope.isSuperUser=function(){return UsersManager.isSuperUser()},$scope.isDefaultZone=function(){return!!angular.isObject($scope.zone)&&1===$scope.zone.id},$scope.canBeDeleted=function(){return!!angular.isObject($scope.zone)&&0!==$scope.zone.id},$scope.deleteButton=function(){$scope.error=null,$scope.confirmingDelete=!0},$scope.cancelDeleteButton=function(){$scope.confirmingDelete=!1},$scope.deleteConfirmButton=function(){ZonesManager.deleteItem($scope.zone).then(function(){$scope.confirmingDelete=!1,$location.path("/zones")},function(error){$scope.error=ManagerHelperService.parseValidationError(error)})},ManagerHelperService.loadManagers($scope,[ZonesManager,UsersManager]).then(function(){var activeZone=ZonesManager.getActiveItem(),requestedZone=parseInt($routeParams.zone_id,10);isNaN(requestedZone)?ErrorService.raiseError("Invalid zone identifier."):angular.isObject(activeZone)&&activeZone.id===requestedZone?zoneLoaded(activeZone):ZonesManager.setActiveItem(requestedZone).then(function(zone){zoneLoaded(zone)},function(error){ErrorService.raiseError(error)})})}])},"./src/maasserver/static/js/angular/controllers/zones_list.js":function(module,exports){angular.module("MAAS").controller("ZonesListController",["$scope","$rootScope","$routeParams","$filter","MachinesManager","DevicesManager","ControllersManager","ZonesManager","ServicesManager","UsersManager","ManagerHelperService","ErrorService",function($scope,$rootScope,$routeParams,$filter,MachinesManager,DevicesManager,ControllersManager,ZonesManager,ServicesManager,UsersManager,ManagerHelperService,ErrorService){$rootScope.title="Zones",$rootScope.page="zones",$scope.zoneManager=ZonesManager,$scope.zones=ZonesManager.getItems(),$scope.currentpage="zones",$scope.predicate="name",$scope.reverse=!1,$scope.loading=!0,$scope.action={open:!1,obj:{}},$scope.addZone=function(){$scope.action.open=!0},$scope.closeZone=function(){$scope.action.open=!1,$scope.action.obj={}},$scope.isSuperUser=function(){return UsersManager.isSuperUser()},ManagerHelperService.loadManagers($scope,[ZonesManager,UsersManager]).then(function(){$scope.loading=!1})}])},"./src/maasserver/static/js/angular/directives/accordion.js":function(module,exports){angular.module("MAAS").directive("maasAccordion",function(){return{restrict:"C",link:function(scope,element,attrs){var clickHandler=function(evt){var tab=evt.data.tab;angular.element(tab).toggleClass("is-selected")},tabs=element.find(".maas-accordion-tab");angular.forEach(tabs,function(tab){(tab=angular.element(tab)).on("click",{tab:tab},clickHandler)}),scope.$on("$destroy",function(){angular.forEach(tabs,function(tab){angular.element(tab).off("click",clickHandler)})})}}})},"./src/maasserver/static/js/angular/directives/boot_images.js":function(module,exports){angular.module("MAAS").directive("maasBootImagesStatus",["BootResourcesManager",function(BootResourcesManager){return{restrict:"E",scope:{},template:['<p class="page-header__status" ','data-ng-if="data.region_import_running">','<span class="u-text--loading">','<i class="p-icon--loading u-animation--spin"></i>',"Step 1/2: Region controller importing","</span>","</p>",'<p class="page-header__status" ','data-ng-if="!data.region_import_running && ','data.rack_import_running">','<span class="u-text--loading">','<i class="p-icon--loading u-animation--spin"></i>',"Step 2/2: Rack controller(s) importing","</span>","</p>"].join(""),controller:function($scope,$rootScope,$element,$document){$scope.data=BootResourcesManager.getData()}}}]),angular.module("MAAS").directive("maasBootImages",["$filter","BootResourcesManager","UsersManager","ManagerHelperService",function($filter,BootResourcesManager,UsersManager,ManagerHelperService){return{restrict:"E",scope:{design:"=?"},templateUrl:"static/partials/boot-images.html?v="+MAAS_config.files_version,controller:function($scope,$rootScope,$element,$document){$scope.loading=!0,$scope.saving=!1,$scope.stopping=!1,$scope.design=$scope.design||"page",$scope.bootResources=BootResourcesManager.getData(),$scope.ubuntuImages=[],$scope.source={isNew:!1,tooMany:!1,showingAdvanced:!1,connecting:!1,errorMessage:"",source_type:"maas.io",url:"",keyring_filename:"",keyring_data:"",releases:[],arches:[],selections:{changed:!1,releases:[],arches:[]}},$scope.ubuntuCoreImages=[],$scope.ubuntu_core={changed:!1,images:[]},$scope.otherImages=[],$scope.other={changed:!1,images:[]},$scope.generatedImages=[],$scope.customImages=[],$scope.ubuntuDeleteId=null,$scope.removingImage=null,$scope.isSuperUser=function(){return UsersManager.isSuperUser()},$scope.getTitleIcon=function(){return 0===$scope.bootResources.resources.length?"p-icon--success-muted":"p-icon--success"},$scope.showMirrorPath=function(){return"custom"===$scope.source.source_type},$scope.isShowingAdvancedOptions=function(){return $scope.source.showingAdvanced},$scope.toggleAdvancedOptions=function(){$scope.source.showingAdvanced=!$scope.source.showingAdvanced},$scope.bothKeyringOptionsSet=function(){return $scope.source.keyring_filename.length>0&&$scope.source.keyring_data.length>0},$scope.showConnectButton=function(){return $scope.source.isNew},$scope.sourceChanged=function(){var currentSources=$scope.bootResources.ubuntu.sources;if(0===currentSources.length)$scope.source.isNew=!0;else{var prevNew=$scope.source.isNew;$scope.source.isNew=$scope.source.source_type!==currentSources[0].source_type,"custom"===$scope.source.source_type&&($scope.source.isNew=$scope.source.isNew||$scope.source.url!==currentSources[0].url),prevNew&&!$scope.source.isNew&&($scope.source.url=currentSources[0].url,$scope.source.keyring_filename=currentSources[0].keyring_filename,$scope.source.keyring_data=currentSources[0].keyring_data),$scope.source.releases=[],$scope.source.arches=[],$scope.source.selections={changed:!1,releases:[],arches:[]}}$scope.updateSource(),$scope.regenerateUbuntuImages(),$scope.source.isNew&&"maas.io"===$scope.source.source_type&&$scope.connect()},$scope.isConnectButtonDisabled=function(){return"maas.io"!==$scope.source.source_type&&($scope.bothKeyringOptionsSet()||0===$scope.source.url.length||$scope.source.connecting)},$scope.getSourceParams=function(){return"maas.io"===$scope.source.source_type?{source_type:"maas.io"}:{source_type:$scope.source.source_type,url:$scope.source.url,keyring_filename:$scope.source.keyring_filename,keyring_data:$scope.source.keyring_data}},$scope.selectDefaults=function(){angular.forEach($scope.source.releases,function(release){"bionic"===release.name&&$scope.source.selections.releases.push(release)}),angular.forEach($scope.source.arches,function(arch){"amd64"===arch.name&&$scope.source.selections.arches.push(arch)})},$scope.connect=function(){if(!$scope.isConnectButtonDisabled()){var source=$scope.getSourceParams();$scope.source.connecting=!0,$scope.source.releases=[],$scope.source.arches=[],$scope.source.selections.changed=!0,$scope.source.selections.releases=[],$scope.source.selections.arches=[],$scope.regenerateUbuntuImages(),BootResourcesManager.fetch(source).then(function(data){$scope.source.connecting=!1,data=angular.fromJson(data),$scope.source.releases=data.releases,$scope.source.arches=data.arches,$scope.selectDefaults(),$scope.regenerateUbuntuImages()},function(error){$scope.source.connecting=!1,$scope.source.errorMessage=error})}},$scope.showConnectBlock=function(){return $scope.source.tooMany||$scope.source.isNew&&!$scope.showSelections()},$scope.showSelections=function(){return $scope.source.releases.length>0&&$scope.source.arches.length>0},$scope.getUbuntuLTSReleases=function(){var releases=$scope.bootResources.ubuntu.releases;$scope.source.isNew&&(releases=$scope.source.releases);var filtered=[];return angular.forEach(releases,function(release){release.deleted||-1===release.title.indexOf("LTS")||filtered.push(release)}),filtered},$scope.getUbuntuNonLTSReleases=function(){var releases=$scope.bootResources.ubuntu.releases;$scope.source.isNew&&(releases=$scope.source.releases);var filtered=[];return angular.forEach(releases,function(release){release.deleted||-1!==release.title.indexOf("LTS")||filtered.push(release)}),filtered},$scope.getArchitectures=function(){var arches=$scope.bootResources.ubuntu.arches;$scope.source.isNew&&(arches=$scope.source.arches);var filtered=[];return angular.forEach(arches,function(arch){arch.deleted||filtered.push(arch)}),filtered},$scope.isSelected=function(type,obj){return $scope.source.selections[type].indexOf(obj)>=0},$scope.toggleSelection=function(type,obj){var idx=$scope.source.selections[type].indexOf(obj);-1===idx?$scope.source.selections[type].push(obj):$scope.source.selections[type].splice(idx,1),$scope.source.selections.changed=!0,$scope.regenerateUbuntuImages()},$scope.showImagesTable=function(){return $scope.ubuntuImages.length>0||$scope.source.arches.length>0&&$scope.source.releases.length>0},$scope.regenerateUbuntuImages=function(){var getResource=function(){return null},resources=$scope.bootResources.resources.filter(function(resource){var resource_os=resource.name.split("/")[0];return 0===resource.rtype&&"ubuntu"===resource_os});$scope.source.isNew||(getResource=function(release,arch){var i;for(i=0;i<resources.length;i++){var resource=resources[i];if(resource.name.split("/")[1]===release&&resource.arch===arch)return resources.splice(i,1),resource}return null}),$scope.ubuntuImages.length=0,angular.forEach($scope.source.selections.releases,function(release){angular.forEach($scope.source.selections.arches,function(arch){var image={icon:"p-icon--status-queued",title:release.title,arch:arch.title,size:"-",status:"Selected for download",beingDeleted:!1,name:release.name},resource=getResource(release.name,arch.name);angular.isObject(resource)&&(image.resourceId=resource.id,image.icon="p-icon--status-"+resource.icon,image.size=resource.size,image.status=resource.status,resource.downloading&&(image.icon+=" u-animation--pulse")),$scope.ubuntuImages.push(image)})}),$scope.source.isNew||angular.forEach(resources,function(resource){var name_split=resource.name.split("/"),image={icon:"p-icon--status-failed",title:resource.title,arch:resource.arch,size:resource.size,status:"Will be deleted",beingDeleted:!0,name:name_split[1]};$scope.ubuntuImages.push(image)})},$scope.regenerateUbuntuCoreImages=function(){var resources=$scope.bootResources.resources.filter(function(resource){var resource_os=resource.name.split("/")[0];return 0===resource.rtype&&"ubuntu-core"===resource_os});$scope.ubuntuCoreImages.length=0,angular.forEach($scope.ubuntu_core.images,function(ubuntuCoreImage){if(ubuntuCoreImage.checked){var name_split=ubuntuCoreImage.name.split("/"),image={icon:"p-icon--status-queued",title:ubuntuCoreImage.title,arch:name_split[1],size:"-",status:"Selected for download",beingDeleted:!1},resource=function(release,arch){var i;for(i=0;i<resources.length;i++){var resource=resources[i];if(resource.name.split("/")[1]===release&&resource.arch===arch)return resources.splice(i,1),resource}return null}(name_split[3],name_split[1]);angular.isObject(resource)&&(image.icon="p-icon--status-"+resource.icon,image.size=resource.size,image.status=resource.status,resource.downloading&&(image.icon+=" u-animation--pulse")),$scope.ubuntuCoreImages.push(image)}}),angular.forEach(resources,function(resource){var image={icon:"p-icon--status-failed",title:resource.title,arch:resource.arch,size:resource.size,status:"Will be deleted",beingDeleted:!0};$scope.ubuntuCoreImages.push(image)})},$scope.regenerateOtherImages=function(){var resources=$scope.bootResources.resources.filter(function(resource){var resource_os=resource.name.split("/")[0];return 0===resource.rtype&&"ubuntu"!==resource_os&&"ubuntu-core"!==resource_os&&"custom"!==resource_os});$scope.otherImages.length=0,angular.forEach($scope.other.images,function(otherImage){if(otherImage.checked){var name_split=otherImage.name.split("/"),image={icon:"p-icon--status-queued",title:otherImage.title,arch:name_split[1],size:"-",status:"Selected for download",beingDeleted:!1},resource=function(release,arch){var i;for(i=0;i<resources.length;i++){var resource=resources[i];if(resource.name.split("/")[1]===release&&resource.arch===arch)return resources.splice(i,1),resource}return null}(name_split[3],name_split[1]);angular.isObject(resource)&&(image.icon="p-icon--status-"+resource.icon,image.size=resource.size,image.status=resource.status,resource.downloading&&(image.icon+=" u-animation--pulse")),$scope.otherImages.push(image)}}),angular.forEach(resources,function(resource){var image={icon:"p-icon--status-failed",title:resource.title,arch:resource.arch,size:resource.size,status:"Will be deleted",beingDeleted:!0};$scope.otherImages.push(image)})},$scope._regenerateImages=function(rtype,images){images.length=0,angular.forEach($scope.bootResources.resources,function(resource){if(resource.rtype===rtype){var image={icon:"p-icon--status-"+resource.icon,title:resource.title,arch:resource.arch,image_id:resource.id,size:resource.size,status:resource.status};resource.downloading&&(image.icon+=" u-animation--pulse"),images.push(image)}})},$scope.regenerateGeneratedImages=function(){$scope._regenerateImages(1,$scope.generatedImages)},$scope.regenerateCustomImages=function(){$scope._regenerateImages(2,$scope.customImages)},$scope.ltsIsSelected=function(){var i;for(i=0;i<$scope.ubuntuImages.length;i++){if(!$scope.ubuntuImages[i].beingDeleted&&$scope.ubuntuImages[i].title.indexOf("LTS")>=0)if(parseInt($scope.ubuntuImages[i].title.split(".")[0],10)>=14)return!0}return!1},$scope.commissioningSeriesSelected=function(){var i;for(i=0;i<$scope.ubuntuImages.length;i++)if(!$scope.ubuntuImages[i].beingDeleted&&$scope.ubuntuImages[i].name===$scope.bootResources.ubuntu.commissioning_series)return!0;return!1},$scope.isShowingDeleteConfirm=function(image){return image===$scope.removingImage},$scope.quickRemove=function(image){$scope.removingImage=image},$scope.cancelRemove=function(){$scope.removingImage=null},$scope.confirmRemove=function(image){image===$scope.removingImage&&BootResourcesManager.deleteImage({id:image.image_id}),$scope.cancelRemove()},$scope.showStopImportButton=function(){return $scope.bootResources.region_import_running},$scope.showSaveSelection=function(){return $scope.showImagesTable()},$scope.canSaveSelection=function(){var i,commissioning_series_being_deleted=!1,commissioning_series_arches=0;for(i=0;i<$scope.ubuntuImages.length;i++)$scope.ubuntuImages[i].name===$scope.bootResources.ubuntu.commissioning_series&&commissioning_series_arches++;for(i=0;i<$scope.ubuntuImages.length;i++)if($scope.ubuntuImages[i].beingDeleted&&$scope.ubuntuImages[i].name===$scope.bootResources.ubuntu.commissioning_series&&1===commissioning_series_arches){commissioning_series_being_deleted=!0;break}return!commissioning_series_being_deleted&&!$scope.saving&&!$scope.stopping&&$scope.ltsIsSelected()},$scope.getSaveSelectionText=function(){return $scope.saving?"Saving...":"Update selection"},$scope.canStopImport=function(){return!$scope.saving&&!$scope.stopping},$scope.getStopImportText=function(){return $scope.stopping?"Stopping...":"Stop import"},$scope.stopImport=function(){$scope.canStopImport()&&($scope.stopping=!0,BootResourcesManager.stopImport().then(function(){$scope.stopping=!1}))},$scope.saveSelection=function(){if($scope.canSaveSelection()){var params=$scope.getSourceParams();params.releases=$scope.source.selections.releases.map(function(obj){return obj.name}),params.arches=$scope.source.selections.arches.map(function(obj){return obj.name}),$scope.saving=!0,BootResourcesManager.saveUbuntu(params).then(function(){$scope.saving=!1,$scope.source.isNew=!1,$scope.source.selections.changed=!1,$scope.updateSource()})}},$scope.getNewSelections=function(newObjs,oldSelections){var newSelections=[];return angular.forEach(newObjs,function(obj){angular.forEach(oldSelections,function(selection){obj.name===selection.name&&newSelections.push(obj)})}),newSelections},$scope.updateSource=function(){if(!$scope.source.isNew){var source_len=$scope.bootResources.ubuntu.sources.length;if(0===source_len)$scope.source.isNew=!0,$scope.source.source_type="custom",$scope.source.errorMessage="Currently no source exists.";else if(1===source_len){var source=$scope.bootResources.ubuntu.sources[0];$scope.source.source_type=source.source_type,"maas.io"===source.source_type?($scope.source.url="",$scope.source.keyring_filename="",$scope.source.keyring_data=""):($scope.source.url=source.url,$scope.source.keyring_filename=source.keyring_filename,$scope.source.keyring_data=source.keyring_data),$scope.source.releases=$scope.bootResources.ubuntu.releases,$scope.source.arches=$scope.bootResources.ubuntu.arches,$scope.source.selections.changed?($scope.source.selections.releases=$scope.getNewSelections($scope.source.releases,$scope.source.selections.releases),$scope.source.selections.arches=$scope.getNewSelections($scope.source.arches,$scope.source.selections.arches)):($scope.source.selections.releases=$scope.source.releases.filter(function(obj){return obj.checked}),$scope.source.selections.arches=$scope.source.arches.filter(function(obj){return obj.checked})),$scope.regenerateUbuntuImages()}else $scope.source.tooMany=!0,$scope.source.releases=$scope.bootResources.ubuntu.releases,$scope.source.arches=$scope.bootResources.ubuntu.arches,$scope.source.selections.releases=$scope.source.releases.filter(function(obj){return obj.checked}),$scope.source.selections.arches=$scope.source.arches.filter(function(obj){return obj.checked}),$scope.source.errorMessage="More than one image source exists. UI does not support modification of sources when more than one has been defined. Used the API to adjust your sources.",$scope.regenerateUbuntuImages()}},$scope.toggleUbuntuCoreSelection=function(image){$scope.ubuntu_core.changed=!0,image.checked=!image.checked,$scope.regenerateUbuntuCoreImages()},$scope.saveUbuntuCoreSelection=function(){var params={images:$scope.ubuntu_core.images.filter(function(image){return image.checked}).map(function(image){return image.name})};$scope.saving=!0,BootResourcesManager.saveUbuntuCore(params).then(function(){$scope.saving=!1})},$scope.toggleOtherSelection=function(image){$scope.other.changed=!0,image.checked=!image.checked,$scope.regenerateOtherImages()},$scope.saveOtherSelection=function(){var params={images:$scope.other.images.filter(function(image){return image.checked}).map(function(image){return image.name})};$scope.saving=!0,BootResourcesManager.saveOther(params).then(function(){$scope.saving=!1})},$scope.canBeRemoved=function(image){if(!angular.isNumber(image.resourceId))return!1;var i,releases=$scope.bootResources.ubuntu.releases,arches=$scope.bootResources.ubuntu.arches;for(i=0;i<releases.length;i++){var release=releases[i];if(release.deleted&&image.title===release.title)return!0}for(i=0;i<arches.length;i++){var arch=arches[i];if(arch.deleted&&image.arch===arch.name)return!0}return!1},$scope.deleteImage=function(image){angular.isObject(image)?$scope.ubuntuDeleteId=image.resourceId:$scope.ubuntuDeleteId=null},$scope.confirmDeleteImage=function(){BootResourcesManager.deleteImage({id:$scope.ubuntuDeleteId}),$scope.ubuntuDeleteId=null};var ready=2;BootResourcesManager.startPolling().then(function(){0===(ready-=1)&&($scope.loading=!1)}),ManagerHelperService.loadManager($scope,UsersManager).then(function(){0===(ready-=1)&&($scope.loading=!1)}),$scope.$watch("bootResources.ubuntu",function(){angular.isObject($scope.bootResources.ubuntu)&&$scope.updateSource()}),$scope.$watch("bootResources.resources",function(){angular.isArray($scope.bootResources.resources)&&($scope.regenerateUbuntuImages(),$scope.regenerateUbuntuCoreImages(),$scope.regenerateOtherImages(),$scope.regenerateGeneratedImages(),$scope.regenerateCustomImages())}),$scope.$watch("bootResources.ubuntu_core_images",function(){var images=$scope.bootResources.ubuntu_core_images;angular.isArray(images)&&($scope.ubuntu_core.changed||($scope.ubuntu_core.images=images),$scope.regenerateUbuntuCoreImages())}),$scope.$watch("bootResources.other_images",function(){angular.isArray($scope.bootResources.other_images)&&($scope.other.changed||($scope.other.images=$scope.bootResources.other_images),$scope.regenerateOtherImages())}),$scope.$on("$destroy",function(){BootResourcesManager.stopPolling()})}}}])},"./src/maasserver/static/js/angular/directives/call_to_action.js":function(module,exports){angular.module("MAAS").run(["$templateCache",function($templateCache){$templateCache.put("directive/templates/cta.html",['<div class="p-contextual-menu">',"<button ",'class="p-button p-contextual-menu__toggle" ','aria-controls="#cta-menu" ','aria-expanded="false" ','aria-haspopup="true" ','data-ng-click="shown=!shown"',">","{$ getTitle() $}",'<i class="p-icon--chevron on-right"></i>',"</button>",'<div class="p-contextual-menu__dropdown" ','id="cta-menu" ','aria-hidden="false" ','aria-label="submenu"','data-ng-show="shown"',">","<button ",'class="',"p-button u-no-margin--left p-contextual-menu__link",'" ','data-ng-repeat="select in maasCta" ','data-ng-click="selectItem(select)">',"{$ getOptionTitle(select) $}","</button>","</div>","</div>"].join(""))}]),angular.module("MAAS").directive("maasCta",function(){return{restrict:"A",replace:!0,require:"ngModel",scope:{maasCta:"=",ngModel:"="},templateUrl:"directive/templates/cta.html",link:function(scope,element,attrs,ngModelCtrl){var defaultTitle="Take action";angular.isString(attrs.defaultTitle)&&""!==attrs.defaultTitle&&(defaultTitle=attrs.defaultTitle),scope.selectItem=function(select){scope.shown=!1,ngModelCtrl.$setViewValue(select)},scope.getTitle=function(){return angular.isObject(ngModelCtrl.$modelValue)?(option=ngModelCtrl.$modelValue,scope.secondary=!0,angular.isString(option.selectedTitle)?option.selectedTitle:option.title):(scope.secondary=!1,defaultTitle)},scope.getOptionTitle=function(option){return scope.secondary&&angular.isString(option.selectedTitle)?option.selectedTitle:option.title},ngModelCtrl.$viewChangeListeners.push(function(){scope.$eval(attrs.ngChange)})},controller:function($scope,$rootScope,$element,$document){$scope.shown=!1,$scope.secondary=!1,$element.bind("click",function(evt){evt.stopPropagation()}),$document.find("body").bind("click",function(){$rootScope.$apply($scope.shown=!1)})}}})},"./src/maasserver/static/js/angular/directives/card_loader.js":function(module,exports){angular.module("MAAS").directive("maasCardLoader",["$compile",function($compile){return{restrict:"A",link:function(scope,element,attrs){var include="<ng-include src=\"'"+("static/partials/cards/"+attrs.maasCardLoader+".html?v="+MAAS_config.files_version)+"'\"></ng-include>";element.html(include),$compile(element.contents())(scope)}}}])},"./src/maasserver/static/js/angular/directives/code_lines.js":function(module,exports){angular.module("MAAS").directive("maasCodeLines",function(){return{restrict:"A",scope:{maasCodeLines:"&"},link:function(scope,element,attributes){scope.$watch(scope.maasCodeLines,function(){element.empty(),element.text(scope.maasCodeLines);var lines=element.html().split("\n"),newLine="",insert="<code>";$.each(lines,function(){insert+=newLine+'<span class="code-line">'+this+"</span>",newLine="\n"}),insert+="</code>",element.html(insert)})}}})},"./src/maasserver/static/js/angular/directives/contenteditable.js":function(module,exports){angular.module("MAAS").directive("contenteditable",function(){return{restrict:"A",require:"ngModel",scope:{ngDisabled:"&",maasEditing:"&"},link:function(scope,element,attrs,ngModel){var focusHandler=function(){scope.ngDisabled()?element.blur():scope.$apply(scope.maasEditing())};element.bind("focus",focusHandler);var changeHandler=function(){scope.$apply(ngModel.$setViewValue(element.text()))};element.bind("blur keyup change",changeHandler),ngModel.$render=function(){element.html(ngModel.$viewValue||"")},ngModel.$viewChangeListeners.push(function(){scope.$eval(attrs.ngChange)}),scope.$on("$destroy",function(){element.unbind("blur keyup change",changeHandler),element.unbind("focus",focusHandler)})}}})},"./src/maasserver/static/js/angular/directives/controller_image_status.js":function(module,exports){angular.module("MAAS").service("ControllerImageStatusService",["$timeout","$interval","ControllersManager",function($timeout,$interval,ControllersManager){var self=this;this.controllers=[],this.statuses={},this.updateStatuses=function(){var controllerIds=[];angular.forEach(self.controllers,function(system_id){controllerIds.push({system_id:system_id})}),ControllersManager.checkImageStates(controllerIds).then(function(results){angular.forEach(controllerIds,function(controller){var status=results[controller.system_id];self.statuses[controller.system_id]=status||"Unknown"})})},this.register=function(system_id){var known=self.controllers.indexOf(system_id)>=0;if(known||self.controllers.push(system_id),angular.isDefined(self.runningInterval)){if(known)return;$interval.cancel(self.runningInterval),self.runningInterval=void 0}angular.isDefined(self.startTimeout)&&$timeout.cancel(self.startTimeout),self.startTimeout=$timeout(function(){self.startTimeout=void 0,self.runningInterval=$interval(function(){self.updateStatuses()},3e4),self.updateStatuses()},100)},this.unregister=function(system_id){var idx=self.controllers.indexOf(system_id);idx>-1&&self.controllers.splice(idx,1),0===self.controllers.length&&(angular.isDefined(self.startTimeout)&&($timeout.cancel(self.startTimeout),self.startTimeout=void 0),angular.isDefined(self.runningInterval)&&($interval.cancel(self.runningInterval),self.runningInterval=void 0))},this.showSpinner=function(system_id){var status=self.statuses[system_id];return!angular.isString(status)||"Syncing"===status},this.getImageStatus=function(system_id){var status=self.statuses[system_id];return angular.isString(status)?status:"Asking for status..."}}]),angular.module("MAAS").directive("maasControllerImageStatus",["ControllerImageStatusService",function(ControllerImageStatusService){return{restrict:"E",scope:{systemId:"="},template:['<i class="p-icon--loading u-animation--spin"','data-ng-if="showSpinner()"></i> ',"{$ getImageStatus() $}"].join(""),link:function(scope,element,attrs){var unwatch,registered=!1;unwatch=scope.$watch("systemId",function(){angular.isDefined(scope.systemId)&&!registered&&(ControllerImageStatusService.register(scope.systemId),registered=!0,unwatch())}),scope.showSpinner=function(){return ControllerImageStatusService.showSpinner(scope.systemId)},scope.getImageStatus=function(){return ControllerImageStatusService.getImageStatus(scope.systemId)},scope.$on("$destroy",function(){registered&&ControllerImageStatusService.unregister(scope.systemId)})}}}])},"./src/maasserver/static/js/angular/directives/controller_status.js":function(module,exports){angular.module("MAAS").run(["$templateCache",function($templateCache){$templateCache.put("directive/templates/controller-status.html",["<span>",'<span class="p-icon--{$ serviceClass $}" data-ng-if="!textOnly">',"</span>",'<span data-ng-if="textOnly" data-ng-bind="serviceText"></span>',"</span>"].join(""))}]),angular.module("MAAS").directive("maasControllerStatus",["ControllersManager","ServicesManager",function(ControllersManager,ServicesManager){return{restrict:"A",scope:{controller:"=maasControllerStatus",textOnly:"=?maasTextOnly"},templateUrl:"directive/templates/controller-status.html",controller:function($scope){function getClass(service){return"running"===service.status?"success":"degraded"===service.status?"warning":"dead"===service.status?"error":"unknown"}function countClass(classes,class_name){var counter=0;return angular.forEach(classes,function(name){name===class_name&&counter++}),counter}function updateStatusClass(){if($scope.serviceClass="unknown",angular.isObject($scope.controller)){var services=ControllersManager.getServices($scope.controller);if(services.length>0){var classes=services.map(getClass);-1!==classes.indexOf("error")?($scope.serviceClass="power-error",$scope.serviceText=countClass(classes,"error")+" dead"):-1!==classes.indexOf("warning")?($scope.serviceClass="warning",$scope.serviceText=countClass(classes,"warning")+" degraded"):($scope.serviceClass="success",$scope.serviceText=countClass(classes,"success")+" running")}}}$scope.serviceClass="unknown",$scope.services=ServicesManager.getItems(),$scope.serviceText="",$scope.textOnly?$scope.textOnly=!0:$scope.textOnly=!1,$scope.$watch("controller.service_ids",updateStatusClass),$scope.$watch("services",updateStatusClass,!0),updateStatusClass()}}}])},"./src/maasserver/static/js/angular/directives/dbl_click_overlay.js":function(module,exports){angular.module("MAAS").run(["$templateCache",function($templateCache){var styleElement=document.createElement("style");styleElement.innerHTML=[".maas-dbl-overlay {","display: inline-block;","position: relative;","}",".maas-dbl-overlay--overlay {","position: absolute;","left: 0;","right: 0;","top: 0;","bottom: 0;","-webkit-touch-callout: none;","-webkit-user-select: none;","-khtml-user-select: none;","-moz-user-select: none;","-ms-user-select: none;","user-select: none;","}"].join(""),document.getElementsByTagName("head")[0].appendChild(styleElement),$templateCache.put("directive/templates/double_click_overlay.html",['<div class="maas-dbl-overlay">',"<span data-ng-transclude></span>",'<div class="maas-dbl-overlay--overlay"></div>',"</div>"].join(""))}]),angular.module("MAAS").directive("maasDblClickOverlay",["BrowserService",function(BrowserService){return{restrict:"A",transclude:!0,replace:!0,scope:{maasDblClickOverlay:"&"},templateUrl:"directive/templates/double_click_overlay.html",link:function(scope,element,attrs){var clickElement,overlay=element.find(".maas-dbl-overlay--overlay"),transclude=element.find("span[data-ng-transclude]").children()[0];"SELECT"===transclude.tagName?(clickElement=function(){var evt=document.createEvent("MouseEvents");evt.initMouseEvent("mousedown",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),transclude.dispatchEvent(evt)},overlay.css({cursor:"pointer"})):"INPUT"===transclude.tagName?(clickElement=function(){angular.element(transclude).triggerHandler("focus")},overlay.css({cursor:"text"})):clickElement=function(){angular.element(transclude).triggerHandler("click")};var overlayClick=function(evt){clickElement(),evt.preventDefault(),evt.stopPropagation()},overlayDblClick=function(evt){scope.$apply(scope.maasDblClickOverlay),evt.preventDefault(),evt.stopPropagation()};"firefox"!==BrowserService.browser?(overlay.on("click",overlayClick),overlay.on("dblclick",overlayDblClick)):overlay.addClass("ng-hide"),scope.$on("$destroy",function(){overlay.off("click",overlayClick),overlay.off("dblclick",overlayDblClick)})}}}])},"./src/maasserver/static/js/angular/directives/default_os_select.js":function(module,exports){angular.module("MAAS").directive("maasDefaultOsSelect",function(){return{restrict:"A",scope:{osInput:"@maasDefaultOsSelect",seriesInput:"@maasDefaultSeriesSelect"},link:function($scope,$element,$attrs){var osElement=angular.element($element.find($scope.osInput)),seriesElement=angular.element($element.find($scope.seriesInput));if(!osElement||!seriesElement)throw new Error("Unable to find os or series elements");var switchTo=function(newOSValue,initialSkip){var options=seriesElement.find("option"),selected=!1;angular.forEach(options,function(option){var sel=function(option,newOSValue,initialSkip){var selected=!1,value=option.val(),split_value=value.split("/");return""===newOSValue?""===value?(option.removeClass("u-hide"),option.attr("selected","selected")):option.addClass("u-hide"):split_value[0]===newOSValue?(option.removeClass("u-hide"),""!==split_value[1]||initialSkip||(selected=!0,option.attr("selected","selected"))):option.addClass("u-hide"),selected}(angular.element(option),newOSValue,initialSkip);!1===selected&&(selected=sel)}),initialSkip||selected||function(options){var first_option=null;angular.forEach(options,function(option){(option=angular.element(option)).hasClass("u-hide")||null===first_option&&(first_option=option)}),null!==first_option&&seriesElement.val(first_option.val())}(options)};osElement.on("change",function(evt){switchTo(osElement.val(),!1)}),switchTo(osElement.val(),!0)}}})},"./src/maasserver/static/js/angular/directives/enter.js":function(module,exports){angular.module("MAAS").directive("maasEnter",function(){return{restrict:"A",link:function(scope,element,attrs){element.bind("keydown keypress",function(evt){13===evt.which&&(scope.$apply(function(){scope.$eval(attrs.maasEnter)}),evt.preventDefault())})}}})},"./src/maasserver/static/js/angular/directives/enter_blur.js":function(module,exports){angular.module("MAAS").directive("maasEnterBlur",function(){return{restrict:"A",link:function(scope,element,attrs){element.bind("keydown keypress",function(evt){13===evt.which&&(element.blur(),evt.preventDefault())})}}})},"./src/maasserver/static/js/angular/directives/error_overlay.js":function(module,exports){angular.module("MAAS").run(["$templateCache",function($templateCache){if($templateCache.put("directive/templates/error_overlay.html",['<header id="error-header" class="page-header" data-ng-show="show()">','<div class="row">','<h1 class="page-header__title">','<span class="p-icon--loading u-animation--spin ','u-margin--right-small"','data-ng-hide="clientError"></span>',"{$ getTitle() $}","</h1>",'<div class="page-header__controls">','<button class="button--secondary button--inline"','data-ng-click="reload()"','data-ng-show="clientError">Reload</button>',"</div>",'<div class="page-header__dropdown is-open" ','data-ng-show="error">','<div class="page-header__section twelve-col','u-margin--bottom-none">','<p class="page-header__message','page-header__message--error">',"{$ error $}","</p>","</div>","</div>","</div>","</header>",'<div class="ng-hide u-no-margin--top" data-ng-hide="show()">',"<div data-ng-transclude></div>","</div>"].join("")),!angular.isDefined(window.jasmine)){var image=new Image;image.src="static/assets/images/icons/error.svg",(image=new Image).src="static/assets/images/icons/error.png"}}]),angular.module("MAAS").directive("maasErrorOverlay",["$window","$timeout","RegionConnection","ErrorService",function($window,$timeout,RegionConnection,ErrorService){return{restrict:"A",transclude:!0,scope:!0,templateUrl:"directive/templates/error_overlay.html",link:function(scope,element,attrs){var markDisconnected;scope.connected=!1,scope.showDisconnected=!1,scope.clientError=!1,scope.wasConnected=!1,scope.show=function(){return!!scope.clientError||!scope.connected&&(!scope.wasConnected||scope.showDisconnected)},scope.getTitle=function(){return scope.clientError?"Error occurred":scope.wasConnected?"Connection lost, reconnecting...":"Connecting..."},scope.reload=function(){$window.location.reload()};var watchConnection=function(){if(!scope.clientError){var connected=RegionConnection.isConnected();connected!==scope.connected&&(scope.connected=connected,connected||(scope.showDisconnected=!1,markDisconnected=$timeout(function(){scope.showDisconnected=!0,markDisconnected=void 0},500))),scope.error=RegionConnection.error,!scope.wasConnected&&connected&&(scope.wasConnected=!0)}};scope.$watch(function(){return RegionConnection.isConnected()},watchConnection),scope.$watch(function(){return RegionConnection.error},watchConnection);scope.$watch(function(){return ErrorService._error},function(){var error=ErrorService._error;angular.isString(error)&&(scope.clientError=!0,scope.error=ErrorService._error)}),scope.$on("$destroy",function(){angular.isDefined(markDisconnected)&&$timeout.cancel(markDisconnected)})}}}])},"./src/maasserver/static/js/angular/directives/error_toggle.js":function(module,exports){angular.module("MAAS").directive("maasErrorToggle",["$timeout","RegionConnection","ErrorService",function($timeout,RegionConnection,ErrorService){return{restrict:"A",link:function(scope,element,attrs){var disconnectedPromise,cancelTimeout=function(){angular.isDefined(disconnectedPromise)&&($timeout.cancel(disconnectedPromise),disconnectedPromise=void 0)},watchConnectionAndError=function(){var connected=RegionConnection.isConnected(),error=ErrorService._error;connected&&!angular.isString(error)?(cancelTimeout(),element.removeClass("ng-hide")):angular.isString(error)?(cancelTimeout(),element.addClass("ng-hide")):connected||(cancelTimeout(),disconnectedPromise=$timeout(function(){element.addClass("ng-hide")},500))};scope.$watch(function(){return RegionConnection.isConnected()},watchConnectionAndError),scope.$watch(function(){return ErrorService._error},watchConnectionAndError),scope.$on("$destroy",function(){cancelTimeout()})}}}])},"./src/maasserver/static/js/angular/directives/ipranges.js":function(module,exports){angular.module("MAAS").directive("maasIpRanges",["$filter","IPRangesManager","UsersManager","ManagerHelperService","ConverterService",function($filter,IPRangesManager,UsersManager,ManagerHelperService,ConverterService){return{restrict:"E",scope:{subnet:"=",vlan:"="},templateUrl:"static/partials/ipranges.html?v="+MAAS_config.files_version,controller:function($scope,$rootScope,$element,$document){$scope.loading=!0,$scope.ipranges=IPRangesManager.getItems(),$scope.iprangeManager=IPRangesManager,$scope.newRange=null,$scope.editIPRange=null,$scope.deleteIPRange=null,$scope.isSuperUser=function(){return UsersManager.isSuperUser()},$scope.addRange=function(type){$scope.newRange={type:type,start_ip:"",end_ip:"",comment:""},angular.isObject($scope.subnet)&&($scope.newRange.subnet=$scope.subnet.id),angular.isObject($scope.vlan)&&($scope.newRange.vlan=$scope.vlan.id),"dynamic"===type&&($scope.newRange.comment="Dynamic")},$scope.cancelAddRange=function(){$scope.newRange=null},$scope.ipRangeCanBeModified=function(range){return!!$scope.isSuperUser()||"reserved"===range.type&&range.user===UsersManager.getAuthUser().id},$scope.isIPRangeInEditMode=function(range){return $scope.editIPRange===range},$scope.ipRangeToggleEditMode=function(range){$scope.deleteIPRange=null,$scope.isIPRangeInEditMode(range)?$scope.editIPRange=null:$scope.editIPRange=range},$scope.ipRangeClearEditMode=function(){$scope.editIPRange=null},$scope.isIPRangeInDeleteMode=function(range){return $scope.deleteIPRange===range},$scope.ipRangeEnterDeleteMode=function(range){$scope.editIPRange=null,$scope.deleteIPRange=range},$scope.ipRangeCancelDelete=function(){$scope.deleteIPRange=null},$scope.ipRangeConfirmDelete=function(){IPRangesManager.deleteItem($scope.deleteIPRange).then(function(){$scope.deleteIPRange=null})},$scope.ipRangeSort=function(range){return-1!==range.start_ip.indexOf(":")?ConverterService.ipv6Expand(range.start_ip):ConverterService.ipv4ToInteger(range.start_ip)},ManagerHelperService.loadManagers($scope,[IPRangesManager,UsersManager]).then(function(){$scope.loading=!1})}}}])},"./src/maasserver/static/js/angular/directives/login.js":function(module,exports){angular.module("MAAS").factory("getBakery",function(){return function(visitPage){return new Bakery(new WebHandler,new BakeryStorage(localStorage,{}),{visitPage:visitPage})}}).directive("externalLogin",["$window","getBakery",function($window,getBakery){return{restrict:"E",scope:{},template:['<a target="_blank" class="p-button--positive"',' href="{{ loginURL }}"',' title="Login through {{ externalAuthURL }}">'," Go to login page","</a>",'<div id="login-error" class="p-form-validation__message"',' ng-if="errorMessage">'," <strong>Error getting login link:</strong><br>"," {{ errorMessage }}","</div>"].join(""),controller:function($scope,$rootScope,$element,$document){$scope.errorMessage="",$scope.loginURL="#",$scope.externalAuthURL=$element.attr("auth-url");var bakery=getBakery(function(error){$scope.$apply(function(){$scope.loginURL=error.Info.VisitURL,$scope.errorMessage=""})}),nextPath=$element.attr("next-path");bakery.get("/MAAS/accounts/discharge-request/",{Accept:"application/json","Content-Type":"application/json"},function(error,response){200!=response.currentTarget.status?$scope.$apply(function(){$scope.errorMessage=response.currentTarget.responseText}):$window.location.replace(nextPath)})}}}])},"./src/maasserver/static/js/angular/directives/maas_obj_form.js":function(module,exports){angular.module("MAAS").directive("maasObjForm",["JSONService",function(JSONService){function MAASFormController(scope){this.obj=scope.obj,this.manager=scope.manager,this.fields={},this.scope=scope,this.scope.saving=!1,this.scope.savingKeys=[],angular.isObject(this.scope.obj)&&(this.scope.obj.$maasForm=this),this.managerMethod=scope.managerMethod,angular.isUndefined(this.managerMethod)&&(this.managerMethod="updateItem");var self=this;scope.$watch("obj",function(){self.obj=scope.obj,angular.isObject(self.obj)&&(self.obj.$maasForm=self)}),scope.$on("$destroy",function(){angular.isObject(self.obj)&&delete self.obj.$maasForm})}return MAASFormController.prototype.getValue=function(key){var field=this.fields[key];if(angular.isObject(field)&&angular.isObject(field.scope))return field.scope.getValue()},MAASFormController.prototype.updateValue=function(key,value){var field=this.fields[key];if(angular.isObject(field)&&angular.isObject(field.scope))return field.scope.updateValue(value)},MAASFormController.prototype.cloneObject=function(){if(angular.isObject(this.obj)){delete this.obj.$maasForm;var clonedObj=angular.copy(this.obj);return this.obj.$maasForm=this,clonedObj}return this.obj},MAASFormController.prototype.isTableForm=function(){return!angular.isUndefined(this.scope.tableForm)&&this.scope.tableForm},MAASFormController.prototype.saveOnBlur=function(){return!!angular.isUndefined(this.scope.saveOnBlur)||this.scope.saveOnBlur},MAASFormController.prototype.isSaving=function(key){return this.scope.saving&&this.scope.savingKeys.indexOf(key)>=0},MAASFormController.prototype.showInputSaving=function(key){return this.saveOnBlur()&&this.isSaving(key)},MAASFormController.prototype.hasErrors=function(){var hasErrors=!1;return angular.forEach(this.fields,function(field){field.scope.hasErrors()&&(hasErrors=!0)}),angular.isDefined(this.errorScope)&&this.errorScope.hasErrors()&&(hasErrors=!0),hasErrors},MAASFormController.prototype.registerField=function(key,scope){this.fields[key]={editing:!1,scope:scope};var self=this;return this.scope.$watch("obj."+key,function(){angular.isObject(self.obj)&&!self.fields[key].editing&&self.fields[key].scope.updateValue(self.obj[key])}),angular.isObject(this.obj)?this.obj[key]:null},MAASFormController.prototype.unregisterField=function(key){delete this.fields[key]},MAASFormController.prototype.startEditingField=function(key){this.fields[key].editing=!0},MAASFormController.prototype.stopEditingField=function(key,value){var field=this.fields[key];if(this.saveOnBlur()){field.scope.clearErrors();var updatedObj=this.cloneObject();updatedObj[key]=value,updatedObj[key]!==this.obj[key]?(this.scope.saving=!0,this.scope.savingKeys=[key],this.updateItem(updatedObj,[key])):field.editing=!1}else field.editing=!1},MAASFormController.prototype.updateItem=function(updatedObj,keys){var key=keys[0],field=this.fields[key],self=this;return angular.isFunction(this.scope.preProcess)&&(updatedObj=this.scope.preProcess(updatedObj,keys)),this.manager[this.managerMethod](updatedObj).then(function(newObj){return field.editing=!1,field.scope.updateValue(newObj[key]),self.scope.saving=!1,self.scope.savingKeys=[],angular.isFunction(self.scope.afterSave)&&self.scope.afterSave(newObj),newObj},function(error){var errorJson=JSONService.tryParse(error);return angular.isObject(errorJson)?angular.forEach(errorJson,function(value,key){var errorField=self.fields[key];angular.isArray(value)||(value=[value]),angular.isObject(errorField)?errorField.scope.setErrors(value):("__all__"!==key&&(value=value.map(function(v){return key+": "+v})),field.scope.setErrors(value))}):field.scope.setErrors([error]),self.scope.saving=!1,self.scope.savingKeys=[],error})},MAASFormController.prototype.saveForm=function(){var keys=[],updatedObj=this.cloneObject();angular.forEach(this.fields,function(value,key){value.scope.clearErrors();var newValue=value.scope.getValue();angular.isDefined(newValue)&&updatedObj[key]!==newValue&&(updatedObj[key]=newValue,keys.push(key))}),angular.isFunction(this.scope.preProcess)&&(updatedObj=this.scope.preProcess(updatedObj,keys)),angular.isDefined(this.errorScope)&&this.errorScope.clearErrors();var self=this;return this.scope.saving=!0,this.scope.savingKeys=keys,this.manager[this.managerMethod](updatedObj).then(function(newObj){return self.scope.saving=!1,self.scope.savingKeys=[],angular.isFunction(self.scope.afterSave)&&self.scope.afterSave(newObj),newObj},function(error){var errorJson=JSONService.tryParse(error);return angular.isObject(errorJson)?angular.forEach(errorJson,function(value,key){var errorField=self.fields[key];angular.isArray(value)||(value=[value]),angular.isObject(errorField)?errorField.scope.setErrors(value):("__all__"!==key&&(value=value.map(function(v){return key+": "+v})),angular.isDefined(self.errorScope)?self.errorScope.setErrors(value):console.log(value))}):angular.isDefined(self.errorScope)?self.errorScope.setErrors([error]):console.log(error),self.scope.saving=!1,self.scope.savingKeys=[],error})},{restrict:"E",scope:{obj:"=",manager:"=",managerMethod:"@",preProcess:"=",afterSave:"=",tableForm:"=",saveOnBlur:"=",inline:"=",ngDisabled:"&"},transclude:!0,template:"<form class=\"p-form\" data-ng-class=\"{saving: saving, 'p-form--inline': inline, 'p-form--stacked': tableForm}\" ng-transclude></form>",controller:["$scope",MAASFormController]}}]),angular.module("MAAS").directive("maasObjFieldGroup",["JSONService",function(JSONService){function MAASGroupController(scope,timeout){this.fields={},this.scope=scope,this.scope.saving=!1,this.scope.savingKeys=[],this.timeout=timeout;var self=this;this.scope.isEditing=function(){var editing=!1;return angular.forEach(self.fields,function(value){editing||(editing=value.editing)}),editing}}return MAASGroupController.prototype.isTableForm=function(){return this.formController.isTableForm()},MAASGroupController.prototype.saveOnBlur=function(){return this.formController.saveOnBlur()},MAASGroupController.prototype.isSaving=function(key){return this.scope.saving&&this.scope.savingKeys.indexOf(key)>=0},MAASGroupController.prototype.showInputSaving=function(key){return this.saveOnBlur()&&this.scope.saving},MAASGroupController.prototype.registerField=function(key,scope){return this.fields[key]={editing:!1,scope:scope},this.formController.registerField(key,scope)},MAASGroupController.prototype.unregisterField=function(key){delete this.fields[key],this.formController.unregisterField(key)},MAASGroupController.prototype.startEditingField=function(key){this.fields[key].editing=!0;var self=this;angular.forEach(this.fields,function(value,key){self.formController.startEditingField(key)})},MAASGroupController.prototype.stopEditingField=function(key,value){if(this.fields[key].editing=!1,this.saveOnBlur()){var self=this;this.timeout(function(){var editing=!1;if(angular.forEach(self.fields,function(value){editing||(editing=value.editing)}),!editing){var keys=[],changed=!1,updatedObj=self.formController.cloneObject();if(angular.forEach(self.fields,function(value,key){value.scope.clearErrors();var newValue=value.scope.getValue();angular.isDefined(newValue)&&updatedObj[key]!==newValue&&(keys.push(key),updatedObj[key]=newValue,changed=!0)}),changed){var keyIdx=keys.indexOf(key);-1!==keyIdx&&(keys.splice(keyIdx,1),keys.splice(0,0,key)),self.scope.saving=!0,self.scope.savingKeys=keys,self.formController.updateItem(updatedObj,keys).then(function(obj){return self.scope.saving=!1,self.scope.savingKeys=[],obj},function(error){return self.scope.saving=!1,self.scope.savingKeys=[],error})}}},10)}},{restrict:"E",require:["^^maasObjForm","maasObjFieldGroup"],scope:{},transclude:!0,template:'<div class="form__siblings" data-ng-class="{\'is-active\': isEditing()}" data-ng-transclude></div>',controller:["$scope","$timeout",MAASGroupController],link:{pre:function(scope,element,attrs,controllers){controllers[1].formController=controllers[0],scope.ngDisabled=controllers[0].scope.ngDisabled,controllers[0].scope.$watch("obj",function(obj){scope.obj=obj})}}}}]),angular.module("MAAS").directive("maasObjField",["$compile",function($compile){return{restrict:"E",require:["^^maasObjForm","?^^maasObjFieldGroup"],scope:{onChange:"=",subtleText:"@"},transclude:!0,template:"<div data-ng-transclude></div>",link:function(scope,element,attrs,controllers){var controller=controllers[1];angular.isObject(controller)||(controller=controllers[0]),scope.ngDisabled=controller.scope.ngDisabled,element.addClass("p-form__group"),"false"!==attrs.subtle&&element.addClass("form__group--subtle");var missingAttrs=[];if(angular.isString(attrs.type)&&0!==attrs.type.length||missingAttrs.push("type"),angular.isString(attrs.key)&&0!==attrs.key.length||missingAttrs.push("key"),missingAttrs.length>0)throw new Error(missingAttrs.join(", ")+" are required on maas-obj-field.");angular.isString(attrs.disabled)&&(scope.ngDisabled=function(){return!0}),element.find("div").remove();var label=attrs.label||attrs.key;if("true"!==attrs.disableLabel&&"hidden"!==attrs.type){var labelElement=angular.element("<label/>");if(labelElement.attr("for",attrs.key),labelElement.text(label),labelElement.addClass("p-form__label"),attrs.labelWidth?labelElement.addClass("col-"+attrs.labelWidth):labelElement.addClass("u-margin--right"),"true"===attrs.labelLeft&&(labelElement.addClass("u-padding--left"),labelElement.addClass("u-position--relative")),element.append(labelElement),angular.isString(attrs.labelInfo)&&attrs.labelInfo.length>0){var infoWrapper=angular.element("<span>&nbsp;</span>");infoWrapper.addClass("p-tooltip p-tooltip--btm-right");var infoIcon=angular.element("<i/>");infoIcon.addClass("p-icon--information"),infoIcon.attr("aria-describedby",attrs.key+"-tooptip");var infoTooltip=angular.element("<p></p>");infoTooltip.addClass("p-tooltip__message"),infoTooltip.text(attrs.labelInfo),infoTooltip.attr("id",attrs.key+"-tooptip"),infoWrapper.append(infoIcon),infoWrapper.append(infoTooltip),labelElement.append(infoWrapper),infoIcon.bind("click",function(evt){evt.preventDefault()})}}var inputWrapper=angular.element("<div></div>");inputWrapper.addClass("p-form__control"),inputWrapper.addClass("u-no-margin--top"),attrs.inputWidth&&inputWrapper.addClass("col-"+attrs.inputWidth);var placeholder=attrs.placeholder||label,inputElement=null;if("text"===attrs.type||"textarea"===attrs.type||"password"===attrs.type){"text"===attrs.type?inputElement=$compile('<input type="text" id="'+attrs.key+'" placeholder="'+placeholder+'"data-ng-disabled="ngDisabled()">')(scope):"textarea"===attrs.type?inputElement=$compile('<textarea id="'+attrs.key+'" placeholder="'+placeholder+'"data-ng-disabled="ngDisabled()"></textarea>')(scope):"password"===attrs.type&&(inputElement=$compile('<input type="password" id="'+attrs.key+'" placeholder="'+placeholder+'"data-ng-disabled="ngDisabled()">')(scope)),attrs.blurOnEnter&&inputElement.bind("keydown keypress",function(evt){13===evt.which&&(inputElement.blur(),evt.preventDefault())});inputElement.bind("keydown keypress",function(evt){27===evt.which&&(inputElement.val(controller.scope.obj[attrs.key]),inputElement.blur(),evt.preventDefault())});var currentValue=controller.registerField(attrs.key,scope);inputElement.val(currentValue),inputElement.on("focus",function(){scope.$apply(function(){controller.startEditingField(attrs.key)})}),inputElement.on("blur",function(){scope.$apply(function(){controller.stopEditingField(attrs.key,inputElement.val())})}),scope.updateValue=function(newValue){inputElement.val(newValue)},scope.getValue=function(){return inputElement.val()}}else if("options"===attrs.type){var options=attrs.options;if(!angular.isString(options)||0===options.length)throw new Error("options attribute is required on type 'options' on maas-obj-field.");var disabled="disabled";"true"===attrs.placeholderEnabled&&(disabled="");var childScope=scope.$parent.$new();childScope._ngDisabled=scope.ngDisabled,childScope._selectValue=controller.registerField(attrs.key,scope),childScope._selectNgChange=function(){scope._change(),controller.stopEditingField(attrs.key,childScope._selectValue)},inputElement=$compile('<select id="'+attrs.key+'" data-ng-model="_selectValue" data-ng-options="'+options+'"data-ng-change="_selectNgChange()"data-ng-disabled="_ngDisabled()"><option value="" '+disabled+">"+placeholder+"</option></select>")(childScope),scope.updateValue=function(newValue){childScope._selectValue=newValue},scope.getValue=function(){return childScope._selectValue}}else if("checkboxes"===attrs.type){var values=attrs.values;if(!angular.isString(values)||0===values.length)throw new Error("values attribute is required on type 'checkboxes' on maas-obj-field.");var checkScope=scope.$parent.$new();checkScope._selectedValues=controller.registerField(attrs.key,scope),checkScope._checked=function(val){return checkScope._selectedValues.indexOf(val)>-1},checkScope._toggleChecked=function(val){var idx=checkScope._selectedValues.indexOf(val);idx>-1?checkScope._selectedValues.splice(idx,1):checkScope._selectedValues.push(val)},inputElement=angular.element(['<div class="width--full" ','data-ng-repeat="val in '+values+'">','<input id="'+attrs.key+"_{$ val $}",'" type="checkbox" value="{$ val $}" ','class="checkbox" ','data-ng-checked="_checked(val)" ','data-ng-click="_toggleChecked(val)">','<label for="'+attrs.key+"_",'{$ val $}" ','class="checkbox-label">{$ val $}</label>',"</div>"].join("")),inputElement=$compile(inputElement)(checkScope),scope.updateValue=function(newValue){checkScope._selectedValues=newValue},scope.getValue=function(){return checkScope._selectedValues}}else if("tags"===attrs.type){var tagsScope=scope.$new(),tags=controller.registerField(attrs.key,scope);tagsScope._tags=tags.map(function(val){return{text:val}}),inputElement=angular.element(['<span data-ng-if="ngDisabled()" ','data-ng-repeat="tag in _tags">',"{$ tag.text $} </span>",'<tags-input id="'+attrs.key+'" ','data-ng-model="_tags" ','data-ng-if="!ngDisabled()" ','placeholder="'+placeholder+'" ','data-ng-change="_change()" ','allow-tags-pattern="[\\w-]+"></tags-input>'].join("")),inputElement=$compile(inputElement)(tagsScope),scope.updateValue=function(newValue){tagsScope._tags=newValue.map(function(val){return{text:val}})},scope.getValue=function(){return tagsScope._tags.map(function(val){return val.text})}}else if("hidden"===attrs.type){var hiddenScope=scope.$new();hiddenScope._toggle=controller.registerField(attrs.key,scope),inputElement=angular.element(['<input type="hidden" name="'+attrs.key+'" ','id="'+attrs.key+'" ','value="'+attrs.value+'">',"</input>"].join("")),inputElement=$compile(inputElement)(hiddenScope),scope.getValue=function(){return attrs.value},scope.updateValue=function(){return null}}else if("onoffswitch"===attrs.type){var switchScope=scope.$new();switchScope._toggle=controller.registerField(attrs.key,scope),switchScope._changed=function(){scope._change(),controller.startEditingField(attrs.key),controller.stopEditingField(attrs.key,switchScope.getValue())},inputElement=angular.element(['<div class="maas-p-switch">','<input type="checkbox" name="'+attrs.key+'" ','class="maas-p-switch--input" ','id="'+attrs.key+'" ','data-ng-model="_toggle" ','data-ng-change="_changed()">','<div class="maas-p-switch--mask"></div>',"</div>"].join("")),inputElement=$compile(inputElement)(switchScope),scope.updateValue=function(newValue){attrs.onValue&&attrs.onValue===newValue?switchScope._toggle=!0:attrs.offValue&&attrs.offValue===newValue?switchScope._toggle=!1:switchScope._toggle=newValue},scope.getValue=function(){return switchScope._toggle?!attrs.onValue||attrs.onValue:!!attrs.offValue&&attrs.offValue}}else{if("slider"!=attrs.type)throw new Error("Unknown type on maas-obj-field: "+attrs.type);var sliderScope=scope.$new();sliderScope._slider=controller.registerField(attrs.key,scope),sliderScope._ngDisabled=scope.ngDisabled,inputElement=angular.element(['<div class="p-slider__wrapper">','<input class="p-slider" type="range"','min="'+attrs.min+'" max="'+attrs.max+'" ','value="1" step="1" id="'+attrs.key+'" ','data-ng-model="_slider" data-ng-disabled="','_ngDisabled()">','<input class="p-slider__input" type="text" ','maxlength="3" id="'+attrs.key+'-input" ','data-ng-model="_slider" data-ng-disabled="','_ngDisabled()"></div>'].join("")),inputElement=$compile(inputElement)(sliderScope),scope.updateValue=function(newValue){sliderScope._slider=newValue},scope.getValue=function(){return sliderScope._slider}}scope._change=function(){angular.isFunction(scope.onChange)&&scope.onChange(attrs.key,controller.getValue(attrs.key),controller)},attrs.inputClass&&inputElement.addClass(attrs.inputClass),inputWrapper.append(inputElement);var errorsElement=angular.element('<ul class="p-list u-no-margin--top"></ul>');if(controller.isTableForm()||errorsElement.addClass("form__error"),inputWrapper.append(errorsElement),attrs.helpText){var helpTextElement=angular.element("<p>"+attrs.helpText+"</p>");helpTextElement.addClass("p-form-help-text"),inputWrapper.append(helpTextElement)}if(scope.clearErrors=function(){inputElement.removeClass("ng-dirty"),inputElement.removeClass("p-form-validation__input"),inputWrapper.removeClass("p-form-validation"),inputWrapper.removeClass("is-error"),inputWrapper.removeClass("u-no-margin--top"),errorsElement.empty()},scope.setErrors=function(errors){errors.length>0&&(inputWrapper.addClass("p-form-validation"),inputWrapper.addClass("is-error"),inputWrapper.addClass("u-no-margin--top"),inputElement.addClass("ng-dirty"),inputElement.addClass("p-form-validation__input"),angular.forEach(errors,function(error){errorsElement.append('<li class="p-form-validation__message"><strong>Error:</strong> '+error+"</li>")}),setTimeout(function(){inputElement.focus()},1))},scope.hasErrors=function(){return inputWrapper.hasClass("is-error")},attrs.subtleText){var subtleTextElement=$compile(angular.element('<span class="p-form-help-text" data-ng-bind="subtleText"></span>'))(scope);inputWrapper.append(subtleTextElement)}element.append(inputWrapper),scope.$watch(function(){return controller.showInputSaving(attrs.key)},function(value){value?(inputWrapper.children(":first").addClass("u-border--information"),inputWrapper.append('<i class="obj-saving icon p-icon--spinner u-animation--spin"></i>'),inputWrapper.addClass("p-tooltip"),inputWrapper.addClass("p-tooltip--bottom"),inputWrapper.addClass("u-no-margin--top"),inputWrapper.attr("aria-label","Saving")):(inputWrapper.children(":first").removeClass("u-border--information"),inputWrapper.find("i.obj-saving").remove(),inputWrapper.removeClass("p-tooltip"),inputWrapper.removeClass("p-tooltip--right"),inputWrapper.addClass("u-no-margin--top"),inputWrapper.removeAttr("aria-label"))}),scope.$on("$destroy",function(){controller.unregisterField(attrs.key)})}}}]),angular.module("MAAS").directive("maasObjSave",function(){return{restrict:"A",require:["^^maasObjForm"],scope:{},link:function(scope,element,attrs,controllers){var controller=controllers[0];if(controller.saveOnBlur())throw new Error("maas-obj-save is only allowed when save-on-blur is set to false.");element.on("click",function(){scope.$apply(function(){controller.saveForm()})})}}}),angular.module("MAAS").directive("maasObjErrors",function(){return{restrict:"E",require:["^^maasObjForm"],scope:{},template:'<ul class="p-list u-no-margin--top"></ul>',link:function(scope,element,attrs,controllers){controllers[0].errorScope=scope;var ul=element.find("ul");scope.clearErrors=function(){ul.empty()},scope.setErrors=function(errors){errors.length>0&&angular.forEach(errors,function(error){ul.append('<li class="p-list__item"><i class="p-icon--error"></i> '+error+"</li>")})},scope.hasErrors=function(){return ul.children().length>0}}}}),angular.module("MAAS").directive("maasObjSaving",function(){return{restrict:"E",require:"^^maasObjForm",scope:{},transclude:!0,template:['<span data-ng-if="saving">','<i class="p-icon--loading u-animation--spin"></i>',"<span data-ng-transclude></span>","</span>"].join(""),link:function(scope,element,attrs,controller){scope.saving=!1,scope.$watch(function(){return controller.scope.saving},function(value){scope.saving=value})}}}),angular.module("MAAS").directive("maasObjShowSaving",function(){return{restrict:"A",require:"^^maasObjForm",link:function(scope,element,attrs,controller){scope.$watch(function(){return controller.scope.saving},function(value){value?element.removeClass("ng-hide"):element.addClass("ng-hide")})}}}),angular.module("MAAS").directive("maasObjHideSaving",function(){return{restrict:"A",require:"^^maasObjForm",link:function(scope,element,attrs,controller){scope.$watch(function(){return controller.scope.saving},function(value){value?element.addClass("ng-hide"):element.removeClass("ng-hide")})}}})},"./src/maasserver/static/js/angular/directives/mac_address.js":function(module,exports){angular.module("MAAS").directive("macAddress",function(){return{restrict:"A",require:"ngModel",link:function(scope,ele,attr,ngModelCtrl,ngModel){if(ngModelCtrl){var macAddressFormat=function(value){if(value){var numbers=value.replace(/:/g,"");return value.length%3==0?numbers.replace(/([0-9A-Za-z]{2})/g,"$1:"):void 0}};ngModelCtrl.$parsers.push(function(value){return value.toUpperCase()}),ngModelCtrl.$formatters.push(macAddressFormat),ele.on("input",function(){var value=macAddressFormat(ele.val());void 0!==value&&(ngModelCtrl.$setViewValue(value),ngModelCtrl.$render()),scope.$apply()})}}}})},"./src/maasserver/static/js/angular/directives/machines_table.js":function(module,exports){angular.module("MAAS").directive("maasMachinesTable",["MachinesManager","GeneralManager","ManagerHelperService",function(MachinesManager,GeneralManager,ManagerHelperService){return{restrict:"E",scope:{search:"=",ngDisabled:"&",machineHasError:"&",hideCheckboxes:"=?",onListingChange:"&",onCheckAll:"&",onCheck:"&"},templateUrl:"static/partials/machines-table.html?v="+MAAS_config.files_version,link:function(scope,element,attrs){var SPINNER_STATUSES=[1,9,12,14,17,19,21];scope.table={column:"fqdn",predicate:"fqdn",reverse:!1,allViewableChecked:!1,machines:MachinesManager.getItems(),filteredMachines:[],osinfo:GeneralManager.getData("osinfo")},scope.updateAllChecked=function(){if(0!==scope.table.filteredMachines.length){var i;for(i=0;i<scope.table.filteredMachines.length;i++)if(!scope.table.filteredMachines[i].$selected)return void(scope.table.allViewableChecked=!1);scope.table.allViewableChecked=!0}else scope.table.allViewableChecked=!1},scope.toggleCheckAll=function(){scope.table.allViewableChecked?angular.forEach(scope.table.filteredMachines,function(machine){MachinesManager.unselectItem(machine.system_id)}):angular.forEach(scope.table.filteredMachines,function(machine){MachinesManager.selectItem(machine.system_id)}),scope.updateAllChecked(),scope.onCheckAll()},scope.toggleChecked=function(machine){MachinesManager.isSelected(machine.system_id)?MachinesManager.unselectItem(machine.system_id):MachinesManager.selectItem(machine.system_id),scope.updateAllChecked(),scope.onCheck({$machine:machine})},scope.sortTable=function(predicate){scope.table.predicate=predicate,scope.table.reverse=!scope.table.reverse},scope.selectColumnOrSort=function(predicate){scope.table.column!==predicate?scope.table.column=predicate:scope.sortTable(predicate)},scope.showSpinner=function(machine){return SPINNER_STATUSES.indexOf(machine.status_code)>-1},scope.showFailedTestWarning=function(machine){if(scope.showSpinner(machine))return!1;switch(machine.status_code){case 0:case 1:case 2:case 21:case 22:return!1}switch(machine.testing_status){case-1:case 2:return!1}return!0},scope.showNodeStatus=function(machine){return!scope.showSpinner(machine)&&!scope.showFailedTestWarning(machine)&&-1!==machine.other_test_status&&2!==machine.other_test_status},scope.getReleaseTitle=function(os_release){if(angular.isArray(scope.table.osinfo.releases))for(i=0;i<scope.table.osinfo.releases.length;i++){var release=scope.table.osinfo.releases[i];if(release[0]===os_release)return release[1]}return os_release},scope.getStatusText=function(machine){if(-1===["Deploying","Deployed"].indexOf(machine.status))return machine.status;var releaseTitle=scope.getReleaseTitle(machine.osystem+"/"+machine.distro_series);return"ubuntu"===machine.osystem&&(releaseTitle=releaseTitle.split('"')[0].trim()),"Deployed"===machine.status?releaseTitle:"Deploying"===machine.status?machine.status+" "+releaseTitle:void 0},scope.$watchCollection("table.filteredMachines",function(){scope.updateAllChecked(),scope.onListingChange({$machines:scope.table.filteredMachines})})}}}])},"./src/maasserver/static/js/angular/directives/navigation_dropdown.js":function(module,exports){angular.module("MAAS").directive("maasNavigationDropdown",["$document",function($document){return{restrict:"A",link:function(scope,element,attrs){element.on("click",function(e){e.stopPropagation(),element.parent().find(".p-dropdown__menu").toggleClass("u-hide")}),$document.on("click",function(){element.parent().find(".p-dropdown__menu").addClass("u-hide")})}}}])},"./src/maasserver/static/js/angular/directives/navigation_mobile.js":function(module,exports){angular.module("MAAS").directive("maasNavigationMobile",["$document",function($document){return{restrict:"A",link:function(scope,element,attrs){element.on("click",function(e){e.stopPropagation(),element.parent().parent().find("#mobile-nav-menu").toggleClass("u-show")})}}}])},"./src/maasserver/static/js/angular/directives/notifications.js":function(module,exports){angular.module("MAAS").run(["$templateCache",function($templateCache){$templateCache.put("directive/templates/notifications.html",['<div class="u-no-margin--top" data-ng-repeat="category in categories"',' data-ng-init="notifications = categoryNotifications[category]">','<span class="row" data-ng-if="notifications.length == 1">','<ul class="p-list" data-ng-class="{\'is-open\': shown}">','<li data-ng-repeat="notification in notifications"',' class="p-notification"',' data-ng-class="categoryClasses[notification.category]">','<p class="p-notification__response">','<span data-ng-bind-html="notification.message"></span> ','<a class="p-notification__action"',' data-ng-click="dismiss(notification)">Dismiss</a>',"</p>","</li>","</ul>","</span>",'<div class="row p-notification--group" ','data-ng-if="notifications.length >= 2"',' data-ng-init="shown = false">','<div data-ng-class="categoryClasses[notifications[0].category]">','<a aria-label="{$ notifications.length $} ','{$ categoryTitles[category] $}, click to open messages."',' maas-enter="shown = !shown"',' class="p-notification__toggle"',' data-ng-click="shown = !shown">','<p class="p-notification__response">','<span class="p-notification__status"',' data-count="{$ notifications.length $}"'," data-ng-bind=\"notifications.length + ' ' + ",'categoryTitles[category]"></span>',"<small>","<i data-ng-class=\"{ 'p-icon--expand': !shown,"," 'p-icon--collapse': shown }\"></i></small>","</p>","</a>",'<ul class="p-list--divided" ',"data-ng-class=\"{'u-hide': !shown}\">",'<li data-ng-repeat="notification in notifications"',' class="p-list__item">','<p class="p-notification__response">','<span data-ng-bind-html="notification.message">',"</span> ",'<a class="p-notification__action"',' data-ng-click="dismiss(notification)">Dismiss</a>',"</p>","</li>","</ul>","</div>","</div>","</div>"].join(""))}]),angular.module("MAAS").directive("maasNotifications",["NotificationsManager","ManagerHelperService",function(NotificationsManager,ManagerHelperService){return{restrict:"E",templateUrl:"directive/templates/notifications.html",link:function($scope,element,attrs){ManagerHelperService.loadManager($scope,NotificationsManager),$scope.notifications=NotificationsManager.getItems(),$scope.dismiss=angular.bind(NotificationsManager,NotificationsManager.dismiss),$scope.categories=["error","warning","success","info"],$scope.categoryTitles={error:"Errors",warning:"Warnings",success:"Successes",info:"Other messages"},$scope.categoryClasses={error:"p-notification--negative",warning:"p-notification--caution",success:"p-notification--positive",info:"p-notification"},$scope.categoryNotifications={error:[],warning:[],success:[],info:[]},$scope.$watchCollection("notifications",function(){var cns=$scope.categoryNotifications;angular.forEach($scope.categories,function(category){cns[category].length=0}),angular.forEach($scope.notifications,function(notification){cns[notification.category].push(notification)})})}}}])},"./src/maasserver/static/js/angular/directives/os_select.js":function(module,exports){angular.module("MAAS").run(["$templateCache",function($templateCache){$templateCache.put("directive/templates/os-select.html",['<ul class="p-inline-list--settings u-no-margin--top u-no-margin--left',' u-no-padding--left">','<li class="p-inline-list__item"> ','<label class="p-form__label">Choose your image</label>',"</li>",'<li class="p-inline-list__item"> ','<select name="os" ','data-ng-model="ngModel.osystem" ','data-ng-change="selectedOSChanged()" ','data-ng-options="','os[0] as os[1] for os in maasOsSelect.osystems">',"</select>","</li>",'<li class="p-inline-list__item"> ','<select name="release" ','data-ng-model="ngModel.release" ','data-ng-change="selectedReleaseChanged()" ','data-ng-options="','release[0] as release[1] for release in releases">',"</select>","</li>",'<li class="p-inline-list__item"> ','<select name="hwe_kernel" data-ng-model="ngModel.hwe_kernel" ','data-ng-show="hwe_kernels.length"','data-ng-options="',"hwe_kernel[0] as hwe_kernel[1] for hwe_kernel ",'in hwe_kernels">','<option value="">Default kernel</option>',"</select>","</li>","</ul>"].join(""))}]),angular.module("MAAS").directive("maasOsSelect",function(){return{restrict:"A",require:"ngModel",scope:{maasOsSelect:"=",ngModel:"="},templateUrl:"directive/templates/os-select.html",controller:function($scope){function getSelectableReleases(){if(angular.isObject($scope.maasOsSelect)&&angular.isArray($scope.maasOsSelect.releases)){var i,choice,allChoices=$scope.maasOsSelect.releases,choices=[];for(i=0;i<allChoices.length;i++)(choice=allChoices[i])[0].indexOf($scope.ngModel.osystem+"/")>-1&&choices.push(choice);return choices}return[]}function getSelectableKernels(){if(angular.isObject($scope.maasOsSelect)&&angular.isObject($scope.maasOsSelect.kernels)&&angular.isString($scope.ngModel.osystem)&&angular.isString($scope.ngModel.release)){var os=$scope.ngModel.osystem,release=$scope.ngModel.release.split("/")[1],osKernels=$scope.maasOsSelect.kernels[os];if(angular.isObject(osKernels))return osKernels[release]}return[]}function getDefaultOrFirst(array,defaultValue,weightValue){var i,first,weightedPresent=!1;for(i=0;i<array.length;i++){if(angular.isUndefined(first)&&(first=array[i][0]),array[i][0]===defaultValue)return defaultValue;angular.isString(weightValue)&&array[i][0]===weightValue&&(weightedPresent=!0)}return weightedPresent?weightValue:angular.isUndefined(first)?null:first}function setDefault(){angular.isString($scope.ngModel.osystem)&&angular.isString($scope.ngModel.release)||angular.isUndefined($scope.maasOsSelect.default_osystem)||angular.isUndefined($scope.maasOsSelect.default_release)||($scope.ngModel.osystem=getDefaultOrFirst($scope.maasOsSelect.osystems,$scope.maasOsSelect.default_osystem,"ubuntu"),$scope.releases=getSelectableReleases(),$scope.ngModel.release=getDefaultOrFirst($scope.releases,$scope.ngModel.osystem+"/"+$scope.maasOsSelect.default_release),$scope.ngModel.kernel="")}angular.isObject($scope.ngModel)||($scope.ngModel={osystem:null,release:null,hwe_kernel:null}),$scope.releases=getSelectableReleases(),$scope.hwe_kernels=getSelectableKernels(),$scope.ngModel.$reset=function(){$scope.ngModel.osystem=null,$scope.ngModel.release=null,$scope.ngModel.hwe_kernel=null,setDefault()},$scope.$watch("maasOsSelect.releases",function(){$scope.releases=getSelectableReleases(),setDefault()}),$scope.$watch("maasOsSelect.kernels",function(){$scope.hwe_kernels=getSelectableKernels(),setDefault()}),$scope.selectedOSChanged=function(){$scope.releases=getSelectableReleases(),$scope.hwe_kernels=getSelectableKernels(),$scope.ngModel.release=null,$scope.ngModel.hwe_kernel=null,$scope.releases.length>0&&($scope.ngModel.release=$scope.releases[0][0])},$scope.selectedReleaseChanged=function(){$scope.hwe_kernels=getSelectableKernels(),$scope.ngModel.hwe_kernel=null}}}})},"./src/maasserver/static/js/angular/directives/placeholder.js":function(module,exports){angular.module("MAAS").directive("ngPlaceholder",function(){return{restrict:"A",scope:{ngPlaceholder:"="},link:function(scope,element,attrs){scope.$watch("ngPlaceholder",function(){element[0].placeholder=scope.ngPlaceholder})}}})},"./src/maasserver/static/js/angular/directives/pod_parameters.js":function(module,exports){angular.module("MAAS").run(["$templateCache",function($templateCache){$templateCache.put("directive/templates/pod-parameters.html",['<maas-obj-field type="options" key="type" label="Pod type" ','label-width="2" input-width="5" ','placeholder="Select the pod type" ','options="type.name as type.description for type in podTypes" ','ng-if="!hideType">',"</maas-obj-field>","<div pod-fields></div>"].join(""))}]),angular.module("MAAS").directive("maasPodParameters",["$compile","GeneralManager","ManagerHelperService",function($compile,GeneralManager,ManagerHelperService){return{restrict:"E",require:"^^maasObjForm",scope:{hideType:"="},templateUrl:"directive/templates/pod-parameters.html",link:function(scope,element,attrs,controller){scope.powerTypes=GeneralManager.getData("power_types"),scope.podTypes=[],scope.type=null;var childScope,fieldsElement=angular.element(element.find("div[pod-fields]")),updateFields=function(podType){var i,type=null;for(i=0;i<scope.podTypes.length;i++)scope.podTypes[i].name===podType&&(type=scope.podTypes[i]);if(fieldsElement.empty(),childScope&&childScope.$destroy(),angular.isObject(type)){var html="<maas-obj-field-group>";angular.forEach(type.fields,function(field){"bmc"===field.scope&&("power_pass"===field.name?html+='<maas-obj-field type="password" key="':html+='<maas-obj-field type="text" key="',html+=field.name+'" label="'+field.label+'" label-width="2" input-width="5"></maas-obj-field>')}),"virsh"===type.name&&"true"!==attrs.hideSlider&&(html+='<maas-obj-field type="slider" key="cpu_over_commit_ratio" label="CPU over commit" min="0" max="10" label-width="2" input-width="5"></maas-obj-field>',html+='<maas-obj-field type="slider" key="memory_over_commit_ratio" label="Memory over commit" min="0" max="10" label-width="2" input-width="5"></maas-obj-field>'),html+="</maas-obj-field-group>",childScope=scope.$new();var ele=angular.element(html);fieldsElement.append(ele),$compile(ele)(childScope,void 0,{maasObjForm:controller})}},getType=function(){return scope.hideType?controller.obj.type:controller.getValue("type")};scope.$watch(getType,updateFields),scope.$watchCollection("powerTypes",function(){scope.podTypes.length=0,angular.forEach(scope.powerTypes,function(type){"pod"===type.driver_type&&scope.podTypes.push(type)}),updateFields(getType())}),ManagerHelperService.loadManager(scope,GeneralManager)}}}])},"./src/maasserver/static/js/angular/directives/power_parameters.js":function(module,exports){angular.module("MAAS").run(["$templateCache",function($templateCache){$templateCache.put("directive/templates/power-parameters.html",['<div class="p-form__group">','<label for="power-type" ','class="form__group-label col-2">Power type</label>','<div class="form__group-input col-3">','<select name="power-type" id="power-type" ','data-ng-disabled="ngDisabled || ngModel.in_pod" ','data-ng-class="{ invalid: !ngModel.type }" ','data-ng-model="ngModel.type" ','data-ng-options="',"type as type.description ",'for type in maasPowerParameters track by type.name">','<option value="" disabled selected>',"Select your power type","</option>","</select>","</div>","</div>",'<div class="p-form__group" ','data-ng-repeat="field in ngModel.type.fields">','<label for="{$ field.name $}" class="form__group-label col-2" ',"data-ng-if=\"field.name !== 'default_storage_pool' && ","(field.scope !== 'bmc' || !ngModel.in_pod)\">","{$ field.label $}","</label>",'<div class="form__group-input col-3">','<maas-power-input field="field" ','data-ng-disabled="ngDisabled || (field.scope === ',"'bmc' && ngModel.in_pod)\" ","data-ng-if=\"field.name !== 'default_storage_pool' ","&& (field.scope !== 'bmc' || !ngModel.in_pod)\" ",'data-ng-model="ngModel.parameters[field.name]">',"</div>","</div>"].join(""))}]),angular.module("MAAS").directive("maasPowerInput",["$compile",function($compile){return{restrict:"E",require:"ngModel",scope:{field:"=",ngModel:"="},link:function(scope,element,attrs){var type=scope.field.field_type,req=scope.field.required?'required="required" ':"",html="";if("string"===type||"mac_address"===type||"password"===type){var input_type='type="text"';"password"===type&&(input_type="data-ng-type=\"ngModel.editing && 'text' || 'password'\""),html="<input "+input_type+' name="'+scope.field.name+'" '+req+'data-ng-model="'+attrs.ngModel+'" data-ng-disabled="'+attrs.ngDisabled+'" ',"mac_address"===type&&(html+='data-ng-pattern="/^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$/"'),html+=">",angular.isUndefined(scope.ngModel)&&(scope.ngModel=scope.field.default)}else{if("choice"!==type)throw new Error("Unknown power_type: "+type);html='<select name="'+scope.field.name+'"'+req+'data-ng-model="'+attrs.ngModel+'" data-ng-disabled="'+attrs.ngDisabled+'" data-ng-options="choice[0] as choice[1] for choice in field.choices">',html+="</select>",angular.isUndefined(scope.ngModel)&&scope.field.default&&(scope.ngModel=scope.field.default)}element.replaceWith($compile(html)(scope.$parent))}}}]),angular.module("MAAS").directive("maasPowerParameters",function(){return{restrict:"A",require:"ngModel",scope:{maasPowerParameters:"=",ngModel:"=",ngDisabled:"="},templateUrl:"directive/templates/power-parameters.html"}})},"./src/maasserver/static/js/angular/directives/pref_keys.js":function(module,exports){angular.module("MAAS").directive("maasPrefKeys",["$q","RegionConnection","UsersManager",function($q,RegionConnection,UsersManager){return{restrict:"A",controller:function(){var self=this;self.addKey=function(){var defer=$q.defer();return RegionConnection.defaultConnect().then(function(){UsersManager.createAuthorisationToken().then(function(token){self.injector&&self.injector(token),defer.resolve(token)})}),defer.promise},self.deleteKey=function(key){RegionConnection.defaultConnect().then(function(){UsersManager.deleteAuthorisationToken(key)})}}}}]).directive("maasPrefKeysInject",["$compile","$templateCache",function($compile,$templateCache){return{restrict:"A",require:"^maasPrefKeys",scope:{template:"@maasPrefKeysInject"},link:function($scope,$element,$attrs,controller){var template=$templateCache.get($scope.template);if(!template)throw new Error("Unable to load template: "+$scope.template);controller.injector=function(token){var newScope=$scope.$new();newScope.token=token;var newElement=angular.element(template);$element.append(newElement),$compile(newElement)(newScope)}}}}]).directive("maasPrefKeysAdd",function(){return{restrict:"A",require:"^maasPrefKeys",link:function($scope,$element,$attrs,controller){$element.on("click",function(evt){evt.preventDefault();var spinElement=angular.element('<i class="p-icon--spinner u-animation--spin"></i>');$element.prepend(spinElement),$scope.$apply(function(){controller.addKey().then(function(){spinElement.remove()})})})}}}).directive("maasPrefKey",function(){return{restrict:"A",require:"^maasPrefKeys",scope:{key:"@maasPrefKey"},controller:["$scope","$element",function($scope,$element){this.deleteKey=function(){$scope.prefsController.deleteKey($scope.key),$scope.$destroy(),$element.remove()}}],link:function($scope,$element,$attrs,controller){$scope.prefsController=controller}}}).directive("maasPrefKeyDelete",function(){return{restrict:"A",require:"^maasPrefKey",link:function($scope,$element,$attrs,controller){$element.on("click",function(evt){evt.preventDefault(),$scope.$apply(function(){controller.deleteKey()})})}}})},"./src/maasserver/static/js/angular/directives/proxy_settings.js":function(module,exports){angular.module("MAAS").directive("maasProxySettings",["$sce","ConfigsManager","ManagerHelperService","JSONService",function($sce,ConfigsManager,ManagerHelperService,JSONService){return{restrict:"E",scope:{},templateUrl:"static/partials/proxy-settings.html",controller:function($scope,$rootScope,$element,$document){$scope.loading=!0,ManagerHelperService.loadManager($scope,ConfigsManager).then(function(){$scope.loading=!1,$scope.httpProxy=ConfigsManager.getItemFromList("http_proxy"),$scope.enableHttpProxy=ConfigsManager.getItemFromList("enable_http_proxy"),$scope.usePeerProxy=ConfigsManager.getItemFromList("use_peer_proxy"),$scope.enableHttpProxy.value?$scope.httpProxy.value?$scope.usePeerProxy.value?$scope.proxy_type="peer-proxy":$scope.proxy_type="external-proxy":$scope.proxy_type="builtin-proxy":$scope.proxy_type="no-proxy"})}}}])},"./src/maasserver/static/js/angular/directives/release_name.js":function(module,exports){angular.module("MAAS").directive("maasReleaseName",["GeneralManager","ManagerHelperService",function(GeneralManager,ManagerHelperService){return{restrict:"A",scope:{releaseName:"=maasReleaseName"},link:function(scope,element,attrs){scope.osinfo=GeneralManager.getData("osinfo");var setText=function(){element.text(function(){if(angular.isArray(scope.osinfo.releases))for(i=0;i<scope.osinfo.releases.length;i++){var release=scope.osinfo.releases[i];if(release[0]===scope.releaseName)return release[1]}return scope.releaseName}())};scope.$watch("releaseName",function(){setText()}),scope.$watchCollection("osinfo.releases",function(){setText()})}}}])},"./src/maasserver/static/js/angular/directives/release_options.js":function(module,exports){angular.module("MAAS").run(["$templateCache",function($templateCache){$templateCache.put("directive/templates/release-options.html",['<ul class="p-inline-list--settings u-no-margin--top">','<li class="p-inline-list__item">','<input id="diskErase" ','type="checkbox" data-ng-model="maasReleaseOptions.erase" ','data-ng-disabled="globalOptions.erase" ','data-ng-change="onEraseChange()">','<label for="diskErase">',"Erase disks before releasing","</label>","</li>",'<li class="p-inline-list__item">','<input id="secureErase" ','type="checkbox" ','data-ng-model="maasReleaseOptions.secureErase" ','data-ng-disabled="!maasReleaseOptions.erase">','<label for="secureErase">',"Use secure erase","</label>","</li>",'<li class="p-inline-list__item">','<input id="quickErase" type="checkbox" ','data-ng-model="maasReleaseOptions.quickErase" ','data-ng-disabled="!maasReleaseOptions.erase">','<label for="quickErase">',"Use quick erase (not secure)","</label>","</li>","</ul>"].join(""))}]),angular.module("MAAS").directive("maasReleaseOptions",["GeneralManager",function(GeneralManager){return{restrict:"A",scope:{maasReleaseOptions:"="},templateUrl:"directive/templates/release-options.html",link:function(scope,element,attrs){scope.onEraseChange=function(){scope.maasReleaseOptions.erase?(scope.maasReleaseOptions.secureErase=scope.globalOptions.secure_erase,scope.maasReleaseOptions.quickErase=scope.globalOptions.quick_erase):(scope.maasReleaseOptions.secureErase=!1,scope.maasReleaseOptions.quickErase=!1)},scope.globalOptions=GeneralManager.getData("release_options"),scope.$watch("globalOptions",function(){angular.isDefined(scope.globalOptions.erase)&&(scope.maasReleaseOptions.erase=scope.globalOptions.erase,scope.onEraseChange())},!0)}}}])},"./src/maasserver/static/js/angular/directives/script_expander.js":function(module,exports){angular.module("MAAS").directive("pScriptExpander",function(){return{restrict:"C",link:function($scope,$element,$attrs){var link=$element.find(".p-script-expander__trigger"),target=$element.find(".p-script-expander__content");target.addClass("u-hide"),link.on("click",function(evt){evt.preventDefault(),target.toggleClass("u-hide")})}}})},"./src/maasserver/static/js/angular/directives/script_results_list.js":function(module,exports){angular.module("MAAS").directive("maasScriptResultsList",function(){return{templateUrl:"static/partials/script-results-list.html?v="+MAAS_config.files_version}})},"./src/maasserver/static/js/angular/directives/script_runtime.js":function(module,exports){angular.module("MAAS").run(["$templateCache",function($templateCache){$templateCache.put("directive/templates/script_runtime.html",['<span data-ng-if="(scriptStatus === 1 || scriptStatus === 7) &&'," estimatedRunTime !== 'Unknown'\">{{counter}} of ","~{{estimatedRunTime}}</span>",'<span data-ng-if="(scriptStatus === 1 || scriptStatus === 7) &&'," estimatedRunTime == 'Unknown'\">{{counter}}</span>",'<span data-ng-if="scriptStatus === 0 && estimatedRunTime !== ',"'Unknown'\">~{{estimatedRunTime}}</span>",'<span data-ng-if="scriptStatus !== 0 && scriptStatus !== 1 ','&& scriptStatus !== 7">{{runTime}}</span>'].join(""))}]),angular.module("MAAS").directive("maasScriptRunTime",function(){return{restrict:"A",require:["startTime","runTime","estimatedRunTime","scriptStatus"],scope:{startTime:"=",runTime:"@",estimatedRunTime:"@",scriptStatus:"="},templateUrl:"directive/templates/script_runtime.html",controller:function($scope,$interval){function incrementCounter(){if((1===$scope.scriptStatus||7===$scope.scriptStatus)&&$scope.startTime){var seconds=Math.floor(Date.now()/1e3-$scope.startTime),minutes=Math.floor(seconds/60),hours=Math.floor(minutes/60),days=Math.floor(hours/24);seconds=seconds-24*days*60*60-60*(hours-=24*days)*60-60*(minutes=minutes-24*days*60-60*hours);var new_counter="";1===days?new_counter=days+" day, ":days>1&&(new_counter=days+" days, "),new_counter+=hours+":",new_counter+=minutes<10?"0"+minutes+":":minutes+":",new_counter+=seconds<10?"0"+seconds:seconds,$scope.counter=new_counter}}$scope.counter="0:00:00",incrementCounter();var promise=$interval(incrementCounter,1e3);$scope.$on("$destroy",function(){$interval.cancel(promise)})}}})},"./src/maasserver/static/js/angular/directives/script_select.js":function(module,exports){angular.module("MAAS").run(["$templateCache",function($templateCache){$templateCache.put("directive/templates/script-select.html",['<tags-input data-ng-model="ngModel" placeholder="Select scripts" ','key-property="id" display-property="name" min-length=1','on-tag-adding="onTagAdding($tag)" spellcheck="false"','add-from-autocomplete-only="true" on-tag-removed="refocus()"','on-tag-adding="onTagAdding($tag)" on-tag-added="refocus()">','<auto-complete source="getScripts($query)" min-length="0" ','load-on-down-arrow="true" load-on-focus="true" ','load-on-empty="true" template="script-template" ','max-results-to-show="1000">',"</auto-complete>","</tags-input>",'<script type="text/ng-template" id="script-template">',"<div>","<p>","{{data.name}} {{data.tags_string}}","</p>",'<span class="p-form-help-text">',"{{data.description}}","</span>","</div>","<\/script>"].join(""))}]),angular.module("MAAS").directive("maasScriptSelect",["$q","ScriptsManager","ManagerHelperService",function($q,ScriptsManager,ManagerHelperService){return{restrict:"A",require:"ngModel",scope:{ngModel:"=",scriptType:"="},templateUrl:"directive/templates/script-select.html",link:function($scope,element,attrs,ngModelCtrl){$scope.allScripts=ScriptsManager.getItems(),$scope.scripts=[],$scope.getScripts=function(query){return $scope.scripts.length=0,angular.forEach($scope.allScripts,function(script){script.script_type===$scope.scriptType&&script.name.indexOf(query)>=0&&(script.tags_string="",angular.forEach(script.tags,function(tag){""===script.tags_string?script.tags_string="("+tag:script.tags_string+=", "+tag}),""!==script.tags_string&&(script.tags_string+=")"),$scope.scripts.push(script))}),{data:$scope.scripts}},$scope.onTagAdding=function(tag){return void 0!==tag.id},$scope.refocus=function(){var tagsInput=element.find("tags-input"),tagsInputScope=tagsInput.isolateScope();tagsInputScope.eventHandlers.input.change(""),tagsInputScope.eventHandlers.input.focus(),tagsInput.find("input").focus()},angular.isArray($scope.ngModel)||($scope.ngModel=[]),ManagerHelperService.loadManager($scope,ScriptsManager).then(function(){$scope.ngModel.length=0,angular.forEach($scope.allScripts,function(script){script.script_type===$scope.scriptType&&0===script.for_hardware.length&&(0===$scope.scriptType?$scope.ngModel.push(script):2===$scope.scriptType&&script.tags.indexOf("commissioning")>=0&&$scope.ngModel.push(script))})})}}}])},"./src/maasserver/static/js/angular/directives/script_status.js":function(module,exports){angular.module("MAAS").run(["$templateCache",function($templateCache){$templateCache.put("directive/templates/script_status.html",['<span data-ng-class="icon" data-ng-show="show"></span>'].join(""))}]),angular.module("MAAS").directive("maasScriptStatus",function(){return{restrict:"A",require:"scriptStatus",scope:{scriptStatus:"="},templateUrl:"directive/templates/script_status.html",controller:function($scope){function getIcon(){switch($scope.show=!0,$scope.scriptStatus){case 0:$scope.icon="p-icon--pending";break;case 1:case 7:$scope.icon="p-icon--running";break;case 2:$scope.icon="p-icon--pass";break;case 3:case 5:case 6:case 8:$scope.icon="p-icon--power-error";break;case 4:$scope.icon="p-icon--timed-out";break;case 9:$scope.icon="p-icon--warning";break;case-1:$scope.show=!1;break;default:$scope.icon="p-icon--help"}}getIcon(),$scope.$watch("scriptStatus",function(){getIcon()})}}})},"./src/maasserver/static/js/angular/directives/ssh_keys.js":function(module,exports){angular.module("MAAS").directive("maasSshKeys",["$sce","SSHKeysManager","ManagerHelperService","JSONService",function($sce,SSHKeysManager,ManagerHelperService,JSONService){return{restrict:"E",scope:{},templateUrl:"static/partials/ssh-keys.html?v="+MAAS_config.files_version,controller:function($scope,$rootScope,$element,$document){$scope.loading=!0,$scope.keys=SSHKeysManager.getItems(),$scope.groupedKeys=[],$scope.add={source:"lp",authId:"",key:"",error:null,saving:!1},$scope.sourceTitles={lp:"Launchpad",gh:"Github",upload:"Upload"},$scope.openRow=null,$scope.rowMode=null,$scope.trustAsHtml=$sce.trustAsHtml,$scope.open=function(obj,mode){$scope.openRow=obj.id,$scope.rowMode=mode},$scope.close=function(){$scope.openRow=null},$scope.canImportKeys=function(){return!$scope.add.saving&&("lp"===$scope.add.source||"gh"===$scope.add.source?$scope.add.authId.length>0:$scope.add.key.length>0)},$scope.importKeys=function(){$scope.canImportKeys()&&($scope.add.error=null,$scope.add.saving=!0,"lp"===$scope.add.source||"gh"===$scope.add.source?SSHKeysManager.importKeys({protocol:$scope.add.source,auth_id:$scope.add.authId}).then(function(){$scope.add.saving=!1,$scope.add.source="lp",$scope.add.authId="",$scope.add.key=""},function(error){$scope.add.saving=!1;var errorJson=JSONService.tryParse(error);angular.isObject(errorJson)&&angular.isArray(errorJson.__all__)?$scope.add.error=errorJson.__all__[0]:$scope.add.error=error}):SSHKeysManager.createItem({key:$scope.add.key}).then(function(){$scope.add.saving=!1,$scope.add.source="lp",$scope.add.authId="",$scope.add.key=""},function(error){$scope.add.saving=!1;var errorJson=JSONService.tryParse(error);angular.isObject(errorJson)?angular.isArray(errorJson.key)?$scope.add.error=errorJson.key[0]:angular.isArray(errorJson.__all__)?$scope.add.error=errorJson.__all__[0]:$scope.add.error=error:$scope.add.error=error}))},$scope.confirmDelete=function(obj){angular.forEach(obj.keys,function(key){SSHKeysManager.deleteItem(key)})},$scope.$watchCollection("keys",function(){$scope.groupedKeys=[];var keyMap={};angular.forEach($scope.keys,function(key){var groupObj,keysource=key.keysource;if(angular.isObject(keysource)){var keysourceKey=keysource.protocol+"/"+keysource.auth_id;groupObj=keyMap[keysourceKey],angular.isObject(groupObj)?groupObj.keys.push(key):(groupObj={id:keysourceKey,source:keysource.protocol,authId:keysource.auth_id,keys:[key]},keyMap[keysourceKey]=groupObj,$scope.groupedKeys.push(groupObj))}else groupObj={id:"upload/"+key.id,source:"upload",authId:"",keys:[key]},$scope.groupedKeys.push(groupObj)})}),ManagerHelperService.loadManager($scope,SSHKeysManager).then(function(){$scope.loading=!1})}}}])},"./src/maasserver/static/js/angular/directives/switches_table.js":function(module,exports){angular.module("MAAS").directive("maasSwitchesTable",["SwitchesManager","GeneralManager","ManagerHelperService",function(SwitchesManager,GeneralManager,ManagerHelperService){return{restrict:"E",scope:{search:"=",ngDisabled:"&",switchHasError:"&",hideCheckboxes:"=?",onListingChange:"&",onCheckAll:"&",onCheck:"&"},templateUrl:"static/partials/switches-table.html?v="+MAAS_config.files_version,link:function(scope,element,attrs){var SPINNER_STATUSES=[1,9,12,14,17,19,21];scope.table={column:"fqdn",predicate:"fqdn",reverse:!1,allViewableChecked:!1,switches:SwitchesManager.getItems(),filteredSwitches:[],osinfo:GeneralManager.getData("osinfo")},scope.updateAllChecked=function(){if(0!==scope.table.filteredSwitches.length){var i;for(i=0;i<scope.table.filteredSwitches.length;i++)if(!scope.table.filteredSwitches[i].$selected)return void(scope.table.allViewableChecked=!1);scope.table.allViewableChecked=!0}else scope.table.allViewableChecked=!1},scope.toggleCheckAll=function(){scope.table.allViewableChecked?angular.forEach(scope.table.filteredSwitches,function(switch_){SwitchesManager.unselectItem(switch_.system_id)}):angular.forEach(scope.table.filteredSwitches,function(switch_){SwitchesManager.selectItem(switch_.system_id)}),scope.updateAllChecked(),scope.onCheckAll()},scope.toggleChecked=function(switch_){SwitchesManager.isSelected(switch_.system_id)?SwitchesManager.unselectItem(switch_.system_id):SwitchesManager.selectItem(switch_.system_id),scope.updateAllChecked(),scope.onCheck({$switch_:switch_})},scope.sortTable=function(predicate){scope.table.predicate=predicate,scope.table.reverse=!scope.table.reverse},scope.selectColumnOrSort=function(predicate){scope.table.column!==predicate?scope.table.column=predicate:scope.sortTable(predicate)},scope.showSpinner=function(switch_){return SPINNER_STATUSES.indexOf(switch_.status_code)>-1},scope.getReleaseTitle=function(os_release){if(angular.isArray(scope.table.osinfo.releases))for(i=0;i<scope.table.osinfo.releases.length;i++){var release=scope.table.osinfo.releases[i];if(release[0]===os_release)return release[1]}return os_release},scope.getStatusText=function(switch_){if(-1===["Deploying","Deployed"].indexOf(switch_.status))return switch_.status;var releaseTitle=scope.getReleaseTitle(switch_.osystem+"/"+switch_.distro_series);return"ubuntu"===switch_.osystem&&(releaseTitle=releaseTitle.split('"')[0].trim()),"Deployed"===switch_.status?releaseTitle:"Deploying"===switch_.status?switch_.status+" "+releaseTitle:void 0},scope.$watchCollection("table.filteredSwitches",function(){scope.updateAllChecked(),scope.onListingChange({$switches:scope.table.filteredSwitches})})}}}])},"./src/maasserver/static/js/angular/directives/toggle_control.js":function(module,exports){angular.module("MAAS").directive("toggleCtrl",["$document",function($document){return{restrict:"A",link:function($scope,$element,$attr){$scope.isToggled=!1,$scope.toggleMenu=function(){$scope.isToggled=!$scope.isToggled};var clickHandler=function(event){$element.find(event.target).length>0||$scope.$apply(function(){$scope.isToggled=!1})};$document.on("click",clickHandler),$scope.$on("$destroy",function(){$document.off("click",clickHandler)})}}}])},"./src/maasserver/static/js/angular/directives/type.js":function(module,exports){angular.module("MAAS").directive("ngType",function(){return{restrict:"A",scope:{ngType:"="},link:function(scope,element,attrs){scope.$watch("ngType",function(){if(valid_types=["button","checkbox","color","date ","datetime ","datetime-local ","email ","file","hidden","image","month ","number ","password","radio","range ","reset","search","submit","tel","text","time ","url","week"],-1===valid_types.indexOf(scope.ngType))throw new Error("Invalid input type: "+scope.ngType);element[0].type=scope.ngType})}}})},"./src/maasserver/static/js/angular/directives/version_reloader.js":function(module,exports){angular.module("MAAS").directive("maasVersionReloader",["$window","GeneralManager","ManagerHelperService","LogService",function($window,GeneralManager,ManagerHelperService,LogService){return{restrict:"A",controller:function($scope){$scope.version=GeneralManager.getData("version"),$scope.reloadPage=function(){$window.location.reload(!0)},ManagerHelperService.loadManager($scope,GeneralManager).then(function(){GeneralManager.enableAutoReload(!0),LogService.info('Version reloader: Monitoring MAAS "'+$scope.site+'"; version',$scope.version.text,"via",$window.location.href),$scope.$watch("version.text",function(newValue,oldValue){newValue!==oldValue&&(LogService.info("MAAS version changed from '"+oldValue+"' to '"+newValue+"'; forcing reload."),$scope.reloadPage())})})}}}])},"./src/maasserver/static/js/angular/directives/window_width.js":function(module,exports){angular.module("MAAS").directive("windowWidth",["$window",function($window){return{restrict:"A",link:function($scope,element,attrs){function onResize(){$scope.windowWidth!==$window.innerWidth&&($scope.windowWidth=$window.innerWidth,$scope.$apply(function(){$scope.message="Timeout called!"}))}$scope.windowWidth=$window.innerWidth,angular.element($window).on("resize",onResize),$scope.$on("$destroy",function(){angular.element($window).off("resize",onResize)})}}}])},"./src/maasserver/static/js/angular/factories/bootresources.js":function(module,exports){angular.module("MAAS").factory("BootResourcesManager",["$q","$timeout","RegionConnection","ErrorService",function($q,$timeout,RegionConnection,ErrorService){function BootResourcesManager(){this._loaded=!1,this._data={},this._polling=!1,this._nextPromise=null,this._pollTimeout=1e4,this._pollErrorTimeout=500,this._pollEmptyTimeout=3e3}return BootResourcesManager.prototype.getData=function(){return this._data},BootResourcesManager.prototype.isLoaded=function(){return this._loaded},BootResourcesManager.prototype.isPolling=function(){return this._polling},BootResourcesManager.prototype.startPolling=function(){return this._polling?this._nextPromise:(this._polling=!0,this._poll())},BootResourcesManager.prototype.stopPolling=function(){this._polling=!1,angular.isObject(this._nextPromise)&&($timeout.cancel(this._nextPromise),this._nextPromise=null)},BootResourcesManager.prototype._loadData=function(raiseError){raiseError=raiseError||!1;var self=this;return RegionConnection.callMethod("bootresource.poll").then(function(newData){return angular.copy(angular.fromJson(newData),self._data),self._loaded=!0,self._data},function(error){raiseError&&ErrorService.raiseError(error)})},BootResourcesManager.prototype._pollAgain=function(timeout){var self=this;return this._nextPromise=$timeout(function(){self._poll()},timeout),this._nextPromise},BootResourcesManager.prototype._poll=function(){var self=this;return RegionConnection.isConnected()?this._loadData(!1).then(function(newData){var pollTimeout=self._pollTimeout;return angular.isObject(newData)&&!newData.connection_error&&angular.isArray(newData.resources)&&0!==newData.resources.length||(pollTimeout=self._pollEmptyTimeout),self._pollAgain(pollTimeout),newData},function(error){console.log(error),self._pollAgain(self._pollErrorTimeout)}):this._pollAgain(this._pollErrorTimeout)},BootResourcesManager.prototype.loadItems=function(){var defer=$q.defer();return this._loadData(!0).then(function(){defer.resolve()}),defer.promise},BootResourcesManager.prototype.enableAutoReload=function(){},BootResourcesManager.prototype.stopImport=function(params){var self=this;return RegionConnection.callMethod("bootresource.stop_import",params).then(function(newData){return angular.copy(angular.fromJson(newData),self._data),self._loaded=!0,self._data})},BootResourcesManager.prototype.saveUbuntu=function(params){var self=this;return RegionConnection.callMethod("bootresource.save_ubuntu",params).then(function(newData){return angular.copy(angular.fromJson(newData),self._data),self._loaded=!0,self._data})},BootResourcesManager.prototype.saveUbuntuCore=function(params){var self=this;return RegionConnection.callMethod("bootresource.save_ubuntu_core",params).then(function(newData){return angular.copy(angular.fromJson(newData),self._data),self._loaded=!0,self._data})},BootResourcesManager.prototype.saveOther=function(params){var self=this;return RegionConnection.callMethod("bootresource.save_other",params).then(function(newData){return angular.copy(angular.fromJson(newData),self._data),self._loaded=!0,self._data})},BootResourcesManager.prototype.fetch=function(source){return RegionConnection.callMethod("bootresource.fetch",source)},BootResourcesManager.prototype.deleteImage=function(params){var self=this;return RegionConnection.callMethod("bootresource.delete_image",params).then(function(newData){return angular.copy(angular.fromJson(newData),self._data),self._loaded=!0,self._data})},new BootResourcesManager}])},"./src/maasserver/static/js/angular/factories/configs.js":function(module,exports){angular.module("MAAS").factory("ConfigsManager",["$q","$rootScope","RegionConnection","Manager",function($q,$rootScope,RegionConnection,Manager){function ConfigsManager(){Manager.call(this),this._pk="name",this._handler="config";var self=this;RegionConnection.registerNotifier("config",function(action,data){self.onNotify(action,data)})}return ConfigsManager.prototype=new Manager,new ConfigsManager}])},"./src/maasserver/static/js/angular/factories/controllers.js":function(module,exports){angular.module("MAAS").factory("ControllersManager",["$q","$rootScope","RegionConnection","NodesManager","ServicesManager",function($q,$rootScope,RegionConnection,NodesManager,ServicesManager){function ControllersManager(){NodesManager.call(this),this._pk="system_id",this._handler="controller";var self=this;RegionConnection.registerNotifier("controller",function(action,data){self.onNotify(action,data)})}return ControllersManager.prototype=new NodesManager,ControllersManager.prototype.getServices=function(controller){var services=[];return angular.forEach(controller.service_ids,function(service_id){var service=ServicesManager.getItemFromList(service_id);angular.isObject(service)&&services.push(service)}),services},ControllersManager.prototype.checkImageStates=function(controllers){return RegionConnection.callMethod(this._handler+".check_images",controllers)},new ControllersManager}])},"./src/maasserver/static/js/angular/factories/devices.js":function(module,exports){angular.module("MAAS").factory("DevicesManager",["$q","$rootScope","RegionConnection","NodesManager",function($q,$rootScope,RegionConnection,NodesManager){function DevicesManager(){NodesManager.call(this),this._pk="system_id",this._handler="device",this._metadataAttributes={owner:null,subnets:null,tags:null,zone:function(device){return device.zone.name}};var self=this;RegionConnection.registerNotifier("device",function(action,data){self.onNotify(action,data)})}return DevicesManager.prototype=new NodesManager,DevicesManager.prototype.create=function(node){return RegionConnection.callMethod("device.create",node)},DevicesManager.prototype.createInterface=function(params){var self=this;return RegionConnection.callMethod("device.create_interface",params).then(function(device){return self._replaceItem(device),device})},DevicesManager.prototype.performAction=function(device,action,extra){return angular.isObject(extra)||(extra={}),RegionConnection.callMethod("device.action",{system_id:device.system_id,action:action,extra:extra})},new DevicesManager}])},"./src/maasserver/static/js/angular/factories/dhcpsnippets.js":function(module,exports){angular.module("MAAS").factory("DHCPSnippetsManager",["$q","$rootScope","RegionConnection","Manager",function($q,$rootScope,RegionConnection,Manager){function DHCPSnippetsManager(){Manager.call(this),this._pk="id",this._handler="dhcpsnippet";var self=this;RegionConnection.registerNotifier("dhcpsnippet",function(action,data){self.onNotify(action,data)})}return DHCPSnippetsManager.prototype=new Manager,DHCPSnippetsManager.prototype.create=function(snippet){return RegionConnection.callMethod(this._handler+".create",snippet,!0)},new DHCPSnippetsManager}])},"./src/maasserver/static/js/angular/factories/discoveries.js":function(module,exports){angular.module("MAAS").factory("DiscoveriesManager",["$q","$rootScope","RegionConnection","PollingManager",function($q,$rootScope,RegionConnection,PollingManager){function DiscoveriesManager(){PollingManager.call(this),this._pk="first_seen",this._batchKey="first_seen",this._handler="discovery",this._pollEmptyTimeout=5e3}return DiscoveriesManager.prototype=new PollingManager,new DiscoveriesManager}])},"./src/maasserver/static/js/angular/factories/domains.js":function(module,exports){angular.module("MAAS").factory("DomainsManager",["$q","$rootScope","RegionConnection","Manager",function($q,$rootScope,RegionConnection,Manager){function DomainsManager(){Manager.call(this),this._pk="id",this._handler="domain";var self=this;RegionConnection.registerNotifier("domain",function(action,data){self.onNotify(action,data)})}return DomainsManager.prototype=new Manager,DomainsManager.prototype.create=function(domain){return RegionConnection.callMethod("domain.create",domain)},DomainsManager.prototype.deleteDomain=function(domain){return RegionConnection.callMethod("domain.delete",domain)},DomainsManager.prototype.createDNSRecord=function(record){return"A"===record.rrtype||"AAAA"===record.rrtype?(record.ip_addresses=record.rrdata.split(/[ ,]+/),RegionConnection.callMethod("domain.create_address_record",record)):RegionConnection.callMethod("domain.create_dnsdata",record)},DomainsManager.prototype.updateDNSRecord=function(record){return"A"===record.rrtype||"AAAA"===record.rrtype?(record.ip_addresses=record.rrdata.split(/[ ,]+/),RegionConnection.callMethod("domain.update_address_record",record)):RegionConnection.callMethod("domain.update_dnsdata",record)},DomainsManager.prototype.deleteDNSRecord=function(record){return"A"===record.rrtype||"AAAA"===record.rrtype?(record.ip_addresses=record.rrdata.split(/[ ,]+/),RegionConnection.callMethod("domain.delete_address_record",record)):RegionConnection.callMethod("domain.delete_dnsdata",record)},DomainsManager.prototype.getDefaultDomain=function(){if(0===this._items.length)return null;var i;for(i=0;i<this._items.length;i++)if(0===this._items[i].id)return this._items[i];return this._items[0]},DomainsManager.prototype.getDomainByName=function(name){var i;if(this._items.length>0)for(i=0;i<this._items.length;i++)if(this._items[i].name===name)return this._items[i];return null},new DomainsManager}])},"./src/maasserver/static/js/angular/factories/events.js":function(module,exports){angular.module("MAAS").factory("EventsManagerFactory",["RegionConnection","Manager","ErrorService",function(RegionConnection,Manager,ErrorService){function EventsManager(nodeId,factory){Manager.call(this),this._pk="id",this._handler="event",this._nodeId=nodeId,this._factory=factory,this._maxDays=1}function EventsManagerFactory(){this._managers=[];var self=this;RegionConnection.registerNotifier("event",function(action,data){self.onNotify(action,data)})}return EventsManager.prototype=new Manager,EventsManager.prototype._initBatchLoadParameters=function(){return{node_id:this._nodeId,max_days:this._maxDays}},EventsManager.prototype.destroy=function(){this._factory.destroyManager(this),this.isLoaded()&&RegionConnection.callMethod("event.clear",{node_id:this._nodeId})},EventsManager.prototype.getMaximumDays=function(){return this._maxDays},EventsManager.prototype.loadMaximumDays=function(days){var self=this,setMaximumDays=function(){self._maxDays=days,self.loadItems()};this.isLoading()?this.loadItems().then(function(){setMaximumDays()}):setMaximumDays()},EventsManagerFactory.prototype._getManager=function(nodeId){var i;for(i=0;i<this._managers.length;i++)if(this._managers[i]._nodeId===nodeId)return this._managers[i];return null},EventsManagerFactory.prototype.getManager=function(nodeId){var manager=this._getManager(nodeId);return angular.isObject(manager)?manager:(manager=new EventsManager(nodeId,this),this._managers.push(manager),manager)},EventsManagerFactory.prototype.destroyManager=function(manager){var idx=this._managers.indexOf(manager);idx>=0&&this._managers.splice(idx,1)},EventsManagerFactory.prototype.onNotify=function(action,data){if("delete"===action)angular.forEach(this._managers,function(manager){manager.onNotify(action,data)});else if("create"===action||"update"===action){var manager=this._getManager(data.node_id);angular.isObject(manager)&&manager.onNotify(action,data)}},new EventsManagerFactory}])},"./src/maasserver/static/js/angular/factories/fabrics.js":function(module,exports){angular.module("MAAS").factory("FabricsManager",["$q","$rootScope","RegionConnection","Manager","VLANsManager",function($q,$rootScope,RegionConnection,Manager,VLANsManager){function FabricsManager(){Manager.call(this),this._pk="id",this._handler="fabric";var self=this;RegionConnection.registerNotifier("fabric",function(action,data){self.onNotify(action,data)})}return FabricsManager.prototype=new Manager,FabricsManager.prototype.getName=function(fabric){if(angular.isObject(fabric))return angular.isString(fabric.name)?fabric.name:this._handler+"-"+fabric[this._pk]},FabricsManager.prototype.deleteFabric=function(fabric){return RegionConnection.callMethod("fabric.delete",{id:fabric.id},!0)},FabricsManager.prototype.create=function(fabric){return RegionConnection.callMethod("fabric.create",fabric)},new FabricsManager}])},"./src/maasserver/static/js/angular/factories/general.js":function(module,exports){angular.module("MAAS").factory("GeneralManager",["$q","$timeout","RegionConnection","ErrorService",function($q,$timeout,RegionConnection,ErrorService){function GeneralManager(){this._data={machine_actions:{method:"general.machine_actions",data:[],requested:!1,loaded:!1,polling:[],nextPromise:null},device_actions:{method:"general.device_actions",data:[],request:!1,loaded:!1,polling:[],nextPromise:null},region_controller_actions:{method:"general.region_controller_actions",data:[],requested:!1,loaded:!1,polling:[],nextPromise:null},rack_controller_actions:{method:"general.rack_controller_actions",data:[],requested:!1,loaded:!1,polling:[],nextPromise:null},region_and_rack_controller_actions:{method:"general.region_and_rack_controller_actions",data:[],requested:!1,loaded:!1,polling:[],nextPromise:null},architectures:{method:"general.architectures",data:[],requested:!1,loaded:!1,polling:[],nextPromise:null},known_architectures:{method:"general.known_architectures",data:[],requested:!1,loaded:!1,polling:[],nextPromise:null},pockets_to_disable:{method:"general.pockets_to_disable",data:[],requested:!1,loaded:!1,polling:[],nextPromise:null},components_to_disable:{method:"general.components_to_disable",data:[],requested:!1,loaded:!1,polling:[],nextPromise:null},hwe_kernels:{method:"general.hwe_kernels",data:[],requested:!1,loaded:!1,polling:[],nextPromise:null},min_hwe_kernels:{method:"general.min_hwe_kernels",data:[],requested:!1,loaded:!1,polling:[],nextPromise:null},default_min_hwe_kernel:{method:"general.default_min_hwe_kernel",data:{text:""},requested:!1,loaded:!1,polling:[],nextPromise:null,replaceData:function(oldData,newData){oldData.text=newData}},osinfo:{method:"general.osinfo",data:{},requested:!1,loaded:!1,polling:[],nextPromise:null,isEmpty:function(data){var osystems=data.osystems;return angular.isUndefined(osystems)||0===osystems.length},replaceData:function(oldData,newData){angular.copy(newData,oldData)}},bond_options:{method:"general.bond_options",data:{},requested:!1,loaded:!1,polling:[],nextPromise:null,replaceData:function(oldData,newData){angular.copy(newData,oldData)}},version:{method:"general.version",data:{text:null},requested:!1,loaded:!1,polling:[],nextPromise:null,replaceData:function(oldData,newData){oldData.text=newData}},power_types:{method:"general.power_types",data:[],requested:!1,loaded:!1,polling:[],nextPromise:null,replaceData:function(oldData,newData){var i,j,newPowerType,oldPowerType;for(i=0;i<newData.length;i++){newPowerType=newData[i];var newItem=!0;for(j=0;j<oldData.length;j++)if(oldPowerType=oldData[j],newPowerType.name===oldPowerType.name){newItem=!1;break}newItem&&oldData.push(newPowerType)}for(i=oldData.length-1;i>=0;i--){oldPowerType=oldData[i];var found=!1;for(j=0;j<newData.length;j++)if((newPowerType=newData[j]).name===oldPowerType.name){found=!0;break}found||oldData.splice(i,1)}}},release_options:{method:"general.release_options",data:{},requested:!1,loaded:!1,polling:[],nextPromise:null,replaceData:function(oldData,newData){angular.copy(newData,oldData)}}},this._pollTimeout=1e4,this._pollErrorTimeout=3e3,this._pollEmptyTimeout=3e3,this._autoReload=!1,this._type="notify",this._scopes=[]}return GeneralManager.prototype._getInternalData=function(name){var data=this._data[name];if(angular.isUndefined(data))throw new Error("Unknown data: "+name);return data},GeneralManager.prototype.getData=function(name){var d=this._getInternalData(name);return d.requested=!0,d.data},GeneralManager.prototype.isLoaded=function(){var loaded=!0;return angular.forEach(this._data,function(data){data.loaded||(loaded=!1)}),loaded},GeneralManager.prototype.isDataLoaded=function(name){return this._getInternalData(name).loaded},GeneralManager.prototype.isPolling=function(){var polling=!1;return angular.forEach(this._data,function(data){data.polling.length>0&&(polling=!0)}),polling},GeneralManager.prototype.isDataPolling=function(name){return this._getInternalData(name).polling},GeneralManager.prototype.startPolling=function(scope,name){var data=this._getInternalData(name);-1===data.polling.indexOf(scope)&&(data.polling.push(scope),1===data.polling.length&&this._poll(data))},GeneralManager.prototype.stopPolling=function(scope,name){var data=this._getInternalData(name),idx=data.polling.indexOf(scope);idx>=0&&data.polling.splice(idx,1),0===data.polling.length&&angular.isObject(data.nextPromise)&&($timeout.cancel(data.nextPromise),data.nextPromise=null)},GeneralManager.prototype._loadData=function(data,raiseError){var replaceData=data.replaceData;return raiseError=raiseError||!1,angular.isUndefined(replaceData)&&(replaceData=function(oldData,newData){oldData.length=0,oldData.push.apply(oldData,newData)}),RegionConnection.callMethod(data.method).then(function(newData){return replaceData(data.data,newData),data.loaded=!0,data.data},function(error){return raiseError&&ErrorService.raiseError(error),error})},GeneralManager.prototype._pollAgain=function(data,timeout){var self=this;data.nextPromise=$timeout(function(){self._poll(data)},timeout)},GeneralManager.prototype._poll=function(data){var self=this,isEmpty=data.isEmpty;if(angular.isUndefined(isEmpty)&&(isEmpty=function(data){return 0===data.length}),RegionConnection.isConnected())return this._loadData(data,!1).then(function(newData){var pollTimeout=self._pollTimeout;return isEmpty(data.data)&&(pollTimeout=self._pollEmptyTimeout),self._pollAgain(data,pollTimeout),newData},function(error){console.log(error),self._pollAgain(data,self._pollErrorTimeout)});this._pollAgain(data,this._pollErrorTimeout)},GeneralManager.prototype.loadItems=function(items){var self=this,defer=$q.defer(),waitingCount=0;angular.isArray(items)?waitingCount=items.length:angular.forEach(this._data,function(data){data.requested&&waitingCount++});return angular.forEach(this._data,function(data,name){(angular.isArray(items)&&-1!==items.indexOf(name)||!angular.isArray(items)&&data.requested)&&self._loadData(data,!0).then(function(){0==(waitingCount-=1)&&defer.resolve()})}),defer.promise},GeneralManager.prototype.enableAutoReload=function(){if(!this._autoReload){this._autoReload=!0;var self=this;this._reloadFunc=function(){self.loadItems()},RegionConnection.registerHandler("open",this._reloadFunc)}},GeneralManager.prototype.disableAutoReload=function(){this._autoReload&&(RegionConnection.unregisterHandler("open",this._reloadFunc),this._reloadFunc=null,this._autoReload=!1)},new GeneralManager}])},"./src/maasserver/static/js/angular/factories/ipranges.js":function(module,exports){angular.module("MAAS").factory("IPRangesManager",["$q","$rootScope","RegionConnection","Manager",function($q,$rootScope,RegionConnection,Manager){function IPRangesManager(){Manager.call(this),this._pk="id",this._handler="iprange";var self=this;RegionConnection.registerNotifier("iprange",function(action,data){self.onNotify(action,data)})}return IPRangesManager.prototype=new Manager,new IPRangesManager}])},"./src/maasserver/static/js/angular/factories/machines.js":function(module,exports){angular.module("MAAS").factory("MachinesManager",["$q","$rootScope","RegionConnection","NodesManager",function($q,$rootScope,RegionConnection,NodesManager){function MachinesManager(){NodesManager.call(this),this._pk="system_id",this._handler="machine",this._metadataAttributes={architecture:null,status:null,owner:null,tags:null,pod:function(machine){return void 0===machine.pod?"":machine.pod.name},pool:function(machine){return machine.pool.name},zone:function(machine){return machine.zone.name},subnets:null,fabrics:null,spaces:null,storage_tags:null,release:function(machine){return 6===machine.status_code||9===machine.status_code?machine.osystem+"/"+machine.distro_series:""}};var self=this;RegionConnection.registerNotifier("machine",function(action,data){self.onNotify(action,data)})}return MachinesManager.prototype=new NodesManager,MachinesManager.prototype.mountSpecialFilesystem=function(machine,fstype,mount_point,mount_options){var method=this._handler+".mount_special",params={system_id:machine.system_id,fstype:fstype,mount_point:mount_point,mount_options:mount_options};return RegionConnection.callMethod(method,params)},MachinesManager.prototype.unmountSpecialFilesystem=function(machine,mount_point){var method=this._handler+".unmount_special",params={system_id:machine.system_id,mount_point:mount_point};return RegionConnection.callMethod(method,params)},new MachinesManager}])},"./src/maasserver/static/js/angular/factories/node_results.js":function(module,exports){angular.module("MAAS").factory("NodeResultsManagerFactory",["RegionConnection","Manager",function(RegionConnection,Manager){function NodeResultsManager(node,factory){Manager.call(this),this._pk="id",this._handler="noderesult",this._node=node,this._factory=factory,this.commissioning_results=[{title:null,hardware_type:0,results:{}},{title:"CPU",hardware_type:1,results:{}},{title:"Memory",hardware_type:2,results:{}},{title:"Storage",hardware_type:3,results:{}}],this.testing_results=[{title:"CPU",hardware_type:1,results:{}},{title:"Memory",hardware_type:2,results:{}},{title:"Storage",hardware_type:3,results:{}},{title:"Other Results",hardware_type:0,results:{}}],this.installation_results=[];var self=this;RegionConnection.registerNotifier("noderesult",function(action,data){self.onNotify(action,data)})}function NodeResultsManagerFactory(){this._managers=[]}return NodeResultsManager.prototype=new Manager,NodeResultsManager.prototype._getStorageSubtext=function(disk){var deviceinfo="";return""!==disk.model&&(deviceinfo+="Model: "+disk.model),""!==disk.serial&&(""!==deviceinfo&&(deviceinfo+=", "),deviceinfo+="Serial: "+disk.serial),""!==deviceinfo?"/dev/"+disk.name+" ("+deviceinfo+")":"/dev/"+disk.name},NodeResultsManager.prototype._updateObject=function(existing,updated){angular.forEach(updated,function(value,key){existing[key]!==value&&"showing_results"!==key&&"showing_history"!==key&&"showing_menu"!==key&&"$selected"!==key&&(existing[key]=value)})},NodeResultsManager.prototype._addOrReplace=function(results,result){var i;for(i=0;i<results.length;i++)if(results[i].name===result.name)return result.$selected=results[i].$selected,result.showing_results=results[i].showing_results,result.showing_history=results[i].showing_history,result.showing_menu=results[i].showing_menu,void angular.copy(result,results[i]);for(i=0;i<results.length;i++)if(results[i].name>result.name)return void results.splice(i,0,result);results.push(result)},NodeResultsManager.prototype._processItem=function(result){var results,i;if(result.showing_results=!1,result.showing_history=!1,result.showing_menu=!1,result.result_section="scripts",0===result.result_type)results=this.commissioning_results;else{if(1===result.result_type)return void this._addOrReplace(this.installation_results,result);results=this.testing_results,result.result_section="tests"}var disk,subtext,hardware_type_results=results[3];for(i=0;i<results.length;i++)if(results[i].hardware_type===result.hardware_type){hardware_type_results=results[i].results;break}if(3===result.hardware_type&&null!==result.physical_blockdevice){for(i=0;i<this._node.disks.length;i++)if((disk=this._node.disks[i]).id===result.physical_blockdevice){subtext=this._getStorageSubtext(disk),angular.isArray(hardware_type_results[subtext])||(hardware_type_results[subtext]=[]),this._addOrReplace(hardware_type_results[subtext],result);break}}else angular.isArray(hardware_type_results.null)||(hardware_type_results.null=[]),this._addOrReplace(hardware_type_results.null,result)},NodeResultsManager.prototype._removeItem=function(result){var idx=this._getIndexOfItem(this._items,result.id);idx>=0&&this._updateMetadata(this._items[idx],"delete"),this._removeItemByIdFromArray(this._items,result.id),this._removeItemByIdFromArray(this._selectedItems,result.id);var self=this;angular.forEach(this.commissioning_results,function(hw_type){angular.forEach(hw_type.results,function(results,subtext){self._removeItemByIdFromArray(results,result.id),0===results.length&&delete hw_type.results[subtext]})}),angular.forEach(this.testing_results,function(hw_type){angular.forEach(hw_type.results,function(results,subtext){self._removeItemByIdFromArray(results,result.id),0===results.length&&delete hw_type.results[subtext]})}),this._removeItemByIdFromArray(this.installation_results,result.id)},NodeResultsManager.prototype._initBatchLoadParameters=function(){var ret={system_id:this._node.system_id};return"summary"===this._area?(ret.has_surfaced=!0,ret.result_type=2):"testing"===this._area?ret.result_type=2:"commissioning"===this._area?ret.result_type=0:"logs"===this._area&&(ret.result_type=1),ret},NodeResultsManager.prototype.destroy=function(){if(this._factory.destroyManager(this),this.isLoaded()){var method=this._handler+".clear";RegionConnection.callMethod(method,{system_id:this._node.system_id})}},NodeResultsManager.prototype.get_result_data=function(script_id,data_type){var method=this._handler+".get_result_data",params={id:script_id,data_type:data_type};return RegionConnection.callMethod(method,params)},NodeResultsManager.prototype.get_history=function(script_id){var method=this._handler+".get_history",params={id:script_id};return RegionConnection.callMethod(method,params)},NodeResultsManagerFactory.prototype._getManager=function(node){var i;for(i=0;i<this._managers.length;i++)if(this._managers[i]._node.system_id===node.system_id)return this._managers[i];return null},NodeResultsManagerFactory.prototype.getManager=function(node,area){var manager=this._getManager(node);return angular.isObject(manager)||(manager=new NodeResultsManager(node,this),this._managers.push(manager)),manager._area=area,manager.results="commissioning"===area?manager.commissioning_results:"logs"===area?manager.installation_results:manager.testing_results,manager},NodeResultsManagerFactory.prototype.destroyManager=function(manager){var idx=this._managers.indexOf(manager);idx>=0&&this._managers.splice(idx,1)},new NodeResultsManagerFactory}])},"./src/maasserver/static/js/angular/factories/nodes.js":function(module,exports){angular.module("MAAS").service("NodesManager",["$q","$rootScope","$timeout","RegionConnection","Manager",function($q,$rootScope,$timeout,RegionConnection,Manager){function NodesManager(){Manager.call(this)}return NodesManager.prototype=new Manager,NodesManager.prototype.create=function(node){return RegionConnection.callMethod(this._handler+".create",node)},NodesManager.prototype.performAction=function(node,action,extra){return angular.isObject(extra)||(extra={}),RegionConnection.callMethod(this._handler+".action",{system_id:node.system_id,action:action,extra:extra})},NodesManager.prototype.checkPowerState=function(node){return RegionConnection.callMethod(this._handler+".check_power",{system_id:node.system_id}).then(function(state){return node.power_state=state,state},function(error){return node.power_state="error",console.log(error),"error"})},NodesManager.prototype.createPhysicalInterface=function(node,params){return angular.isObject(params)||(params={}),params.system_id=node.system_id,RegionConnection.callMethod(this._handler+".create_physical",params)},NodesManager.prototype.createVLANInterface=function(node,params){return angular.isObject(params)||(params={}),params.system_id=node.system_id,RegionConnection.callMethod(this._handler+".create_vlan",params)},NodesManager.prototype.createBondInterface=function(node,params){return angular.isObject(params)||(params={}),params.system_id=node.system_id,RegionConnection.callMethod(this._handler+".create_bond",params)},NodesManager.prototype.createBridgeInterface=function(node,params){return angular.isObject(params)||(params={}),params.system_id=node.system_id,RegionConnection.callMethod(this._handler+".create_bridge",params)},NodesManager.prototype.updateInterface=function(node,interface_id,params){return angular.isObject(params)||(params={}),params.system_id=node.system_id,params.interface_id=interface_id,RegionConnection.callMethod(this._handler+".update_interface",params)},NodesManager.prototype.updateInterfaceForm=function(params){return RegionConnection.callMethod(this._handler+".update_interface",params)},NodesManager.prototype.deleteInterface=function(node,interface_id){var params={system_id:node.system_id,interface_id:interface_id};return RegionConnection.callMethod(this._handler+".delete_interface",params)},NodesManager.prototype.linkSubnet=function(node,interface_id,params){return angular.isObject(params)||(params={}),params.system_id=node.system_id,params.interface_id=interface_id,RegionConnection.callMethod(this._handler+".link_subnet",params)},NodesManager.prototype.unlinkSubnet=function(node,interface_id,link_id){var params={system_id:node.system_id,interface_id:interface_id,link_id:link_id};return RegionConnection.callMethod(this._handler+".unlink_subnet",params)},NodesManager.prototype.updateFilesystem=function(node,block_id,partition_id,fstype,mount_point,mount_options,tags){var method=this._handler+".update_filesystem",params={system_id:node.system_id,block_id:block_id,partition_id:partition_id,fstype:fstype,mount_point:mount_point,mount_options:mount_options,tags:tags};return RegionConnection.callMethod(method,params)},NodesManager.prototype.deleteDisk=function(node,block_id){var method=this._handler+".delete_disk",params={system_id:node.system_id,block_id:block_id};return RegionConnection.callMethod(method,params)},NodesManager.prototype.deletePartition=function(node,partition_id){var method=this._handler+".delete_partition",params={system_id:node.system_id,partition_id:partition_id};return RegionConnection.callMethod(method,params)},NodesManager.prototype.deleteVolumeGroup=function(node,volume_group_id){var method=this._handler+".delete_volume_group",params={system_id:node.system_id,volume_group_id:volume_group_id};return RegionConnection.callMethod(method,params)},NodesManager.prototype.deleteCacheSet=function(node,cache_set_id){var method=this._handler+".delete_cache_set",params={system_id:node.system_id,cache_set_id:cache_set_id};return RegionConnection.callMethod(method,params)},NodesManager.prototype.deleteFilesystem=function(node,blockdevice_id,partition_id,filesystem_id){var method=this._handler+".delete_filesystem",params={system_id:node.system_id,blockdevice_id:blockdevice_id,partition_id:partition_id,filesystem_id:filesystem_id};return RegionConnection.callMethod(method,params)},NodesManager.prototype.createPartition=function(node,block_id,size,params){angular.isObject(params)||(params={});var method=this._handler+".create_partition";return params.system_id=node.system_id,params.block_id=block_id,params.partition_size=size,RegionConnection.callMethod(method,params)},NodesManager.prototype.createCacheSet=function(node,block_id,partition_id){var method=this._handler+".create_cache_set",params={system_id:node.system_id,block_id:block_id,partition_id:partition_id};return RegionConnection.callMethod(method,params)},NodesManager.prototype.createBcache=function(node,params){return angular.isObject(params)||(params={}),params.system_id=node.system_id,RegionConnection.callMethod(this._handler+".create_bcache",params)},NodesManager.prototype.createRAID=function(node,params){return angular.isObject(params)||(params={}),params.system_id=node.system_id,RegionConnection.callMethod(this._handler+".create_raid",params)},NodesManager.prototype.createVolumeGroup=function(node,params){return angular.isObject(params)||(params={}),params.system_id=node.system_id,RegionConnection.callMethod(this._handler+".create_volume_group",params)},NodesManager.prototype.createLogicalVolume=function(node,volume_group_id,name,size,params){angular.isObject(params)||(params={});var method=this._handler+".create_logical_volume";return params.system_id=node.system_id,params.volume_group_id=volume_group_id,params.name=name,params.size=size,RegionConnection.callMethod(method,params)},NodesManager.prototype.updateDisk=function(node,block_id,params){return angular.isObject(params)||(params={}),params.system_id=node.system_id,params.block_id=block_id,RegionConnection.callMethod(this._handler+".update_disk",params)},NodesManager.prototype.setBootDisk=function(node,block_id){var params={system_id:node.system_id,block_id:block_id};return RegionConnection.callMethod(this._handler+".set_boot_disk",params)},NodesManager.prototype.getSummaryXML=function(node){return RegionConnection.callMethod(this._handler+".get_summary_xml",{system_id:node.system_id})},NodesManager.prototype.getSummaryYAML=function(node){return RegionConnection.callMethod(this._handler+".get_summary_yaml",{system_id:node.system_id})},NodesManager}])},"./src/maasserver/static/js/angular/factories/notifications.js":function(module,exports){angular.module("MAAS").factory("NotificationsManager",["$q","$rootScope","RegionConnection","Manager",function($q,$rootScope,RegionConnection,Manager){function NotificationsManager(){Manager.call(this),this._pk="id",this._handler="notification",RegionConnection.registerNotifier("notification",angular.bind(this,this.onNotify))}return NotificationsManager.prototype=new Manager,NotificationsManager.prototype.dismiss=function(notification){return RegionConnection.callMethod("notification.dismiss",{id:notification.id})},new NotificationsManager}])},"./src/maasserver/static/js/angular/factories/packagerepositories.js":function(module,exports){angular.module("MAAS").factory("PackageRepositoriesManager",["$q","$rootScope","RegionConnection","Manager",function($q,$rootScope,RegionConnection,Manager){function PackageRepositoriesManager(){Manager.call(this),this._pk="id",this._handler="packagerepository";var self=this;RegionConnection.registerNotifier("packagerepository",function(action,data){self.onNotify(action,data)})}return PackageRepositoriesManager.prototype=new Manager,PackageRepositoriesManager.prototype.create=function(repository){return RegionConnection.callMethod(this._handler+".create",repository,!0)},new PackageRepositoriesManager}])},"./src/maasserver/static/js/angular/factories/pods.js":function(module,exports){angular.module("MAAS").service("PodsManager",["$q","$rootScope","$timeout","RegionConnection","Manager",function($q,$rootScope,$timeout,RegionConnection,Manager){function PodsManager(){Manager.call(this),this._pk="id",this._handler="pod";var self=this;RegionConnection.registerNotifier("pod",function(action,data){self.onNotify(action,data)})}return PodsManager.prototype=new Manager,PodsManager.prototype.refresh=function(pod){var self=this;return RegionConnection.callMethod("pod.refresh",pod).then(function(pod){return self._replaceItem(pod),pod})},PodsManager.prototype.compose=function(params){var self=this;return RegionConnection.callMethod("pod.compose",params).then(function(pod){return self._replaceItem(pod),pod})},new PodsManager}])},"./src/maasserver/static/js/angular/factories/region.js":function(module,exports){angular.module("MAAS").factory("RegionConnection",["$q","$rootScope","$timeout","$window","$cookies",function($q,$rootScope,$timeout,$window,$cookies){var MSG_TYPE_REQUEST=0,MSG_TYPE_RESPONSE=1,MSG_TYPE_NOTIFY=2,RESPONSE_TYPE_SUCCESS=0,RESPONSE_TYPE_ERROR=1;function RegionConnection(){this.callbacks={},this.requests={},this.requestId=0,this.url=null,this.websocket=null,this.connected=!1,this.autoReconnect=!0,this.retryTimeout=5e3,this.error=null,this.defaultConnectDefer=null,this.handlers={open:[],error:[],close:[]},this.notifiers={}}return RegionConnection.prototype.newRequestId=function(){return this.requestId+=1,this.requestId},RegionConnection.prototype.registerHandler=function(name,func){if(!angular.isDefined(this.handlers[name]))throw new Error("Invalid handler: "+name);if(!angular.isFunction(func))throw new Error("Requires a function to register a handler.");this.handlers[name].push(func)},RegionConnection.prototype.unregisterHandler=function(name,func){if(!angular.isDefined(this.handlers[name]))throw new Error("Invalid handler: "+name);var idx=this.handlers[name].indexOf(func);idx>=0&&this.handlers[name].splice(idx,1)},RegionConnection.prototype.registerNotifier=function(name,func){if(!angular.isFunction(func))throw new Error("Requires a function to register a notifier.");angular.isUndefined(this.notifiers[name])&&(this.notifiers[name]=[]),this.notifiers[name].push(func)},RegionConnection.prototype.unregisterNotifier=function(name,func){if(!angular.isUndefined(this.notifiers[name])){var idx=this.notifiers[name].indexOf(func);idx>=0&&this.notifiers[name].splice(idx,1)}},RegionConnection.prototype.isConnected=function(){return this.connected},RegionConnection.prototype.buildSocket=function(url){return new WebSocket(url)},RegionConnection.prototype.connect=function(){this.url=this._buildUrl(),this.autoReconnect=!0,this.websocket=this.buildSocket(this.url);var self=this;this.websocket.onopen=function(evt){self.connected=!0,angular.forEach(self.handlers.open,function(func){func(evt)})},this.websocket.onerror=function(evt){angular.forEach(self.handlers.error,function(func){func(evt)})},this.websocket.onclose=function(evt){self.connected=!1,self.error="Unable to connect to: "+self.url.split("?")[0],angular.forEach(self.handlers.close,function(func){func(evt)}),self.autoReconnect&&$timeout(function(){self.connect()},self.retryTimeout)},this.websocket.onmessage=function(evt){self.onMessage(angular.fromJson(evt.data))}},RegionConnection.prototype.close=function(){this.autoReconnect=!1,this.websocket.close(),this.websocket=null},RegionConnection.prototype._getProtocol=function(){return $window.location.protocol},RegionConnection.prototype._buildUrl=function(){var host=$window.location.hostname,port=$window.location.port,path=$window.location.pathname,proto="ws";"https:"===this._getProtocol()&&(proto="wss");var csrftoken,base=angular.element("base");if(angular.isDefined(base)){var newPath=base.attr("href");angular.isDefined(newPath)&&(path=newPath);var newPort=base.data("websocket-port");angular.isDefined(newPort)&&(port=newPort)}return"/"!==path[path.length-1]&&(path+="/"),url=proto+"://"+host,angular.isString(port)&&port.length>0&&(url+=":"+port),url+=path+"ws",csrftoken=angular.isFunction($cookies.get)?$cookies.get("csrftoken"):$cookies.csrftoken,angular.isDefined(csrftoken)&&(url+="?csrftoken="+encodeURIComponent(csrftoken)),url},RegionConnection.prototype.defaultConnect=function(){if(angular.isObject(this.defaultConnectDefer))return this.defaultConnectDefer.promise;var defer;if(this.isConnected())return defer=$q.defer(),$timeout(defer.resolve),defer.promise;var _opened,_errored,self=this;return defer=this.defaultConnectDefer=$q.defer(),_opened=function(evt){this.defaultConnectDefer=null,self.unregisterHandler("open",_opened),self.unregisterHandler("error",_errored),$rootScope.$apply(defer.resolve(evt))},_errored=function(evt){this.defaultConnectDefer=null,self.unregisterHandler("open",_opened),self.unregisterHandler("error",_errored),$rootScope.$apply(defer.reject(evt))},this.registerHandler("open",_opened),this.registerHandler("error",_errored),this.connect(),defer.promise},RegionConnection.prototype.onMessage=function(msg){msg.type===MSG_TYPE_RESPONSE?this.onResponse(msg):msg.type===MSG_TYPE_NOTIFY&&this.onNotify(msg)},RegionConnection.prototype.onResponse=function(msg){var defer=this.callbacks[msg.request_id],remembered_request=this.requests[msg.request_id];angular.isDefined(defer)&&(msg.rtype===RESPONSE_TYPE_SUCCESS?$rootScope.$apply(defer.resolve(msg.result)):msg.rtype===RESPONSE_TYPE_ERROR&&(angular.isObject(remembered_request)?$rootScope.$apply(defer.reject({error:msg.error,request:remembered_request})):$rootScope.$apply(defer.reject(msg.error))),delete this.callbacks[msg.request_id],delete this.requests[msg.request_id])},RegionConnection.prototype.onNotify=function(msg){var handlers=this.notifiers[msg.name];angular.isArray(handlers)&&angular.forEach(handlers,function(handler){handler(msg.action,msg.data)})},RegionConnection.prototype.callMethod=function(method,params,remember){var defer=$q.defer(),request_id=this.newRequestId(),request={type:MSG_TYPE_REQUEST,request_id:request_id,method:method,params:params};return this.callbacks[request_id]=defer,remember&&(this.requests[request_id]=request),this.websocket.send(angular.toJson(request)),defer.promise},new RegionConnection}])},"./src/maasserver/static/js/angular/factories/resourcepools.js":function(module,exports){angular.module("MAAS").factory("ResourcePoolsManager",["$q","$rootScope","RegionConnection","Manager",function($q,$rootScope,RegionConnection,Manager){function ResourcePoolsManager(){Manager.call(this),this._pk="id",this._handler="resourcepool";var self=this;RegionConnection.registerNotifier("resourcepool",function(action,data){self.onNotify(action,data)})}return ResourcePoolsManager.prototype=new Manager,ResourcePoolsManager.prototype.getDefaultPool=function(){var i;for(i=0;i<this._items.length;i++)if(0===this._items[i].id)return this._items[i]},new ResourcePoolsManager}])},"./src/maasserver/static/js/angular/factories/scripts.js":function(module,exports){angular.module("MAAS").factory("ScriptsManager",["$q","$rootScope","RegionConnection","Manager",function($q,$rootScope,RegionConnection,Manager){function ScriptsManager(){Manager.call(this),this._pk="id",this._handler="script";var self=this;RegionConnection.registerNotifier("script",function(action,data){self.onNotify(action,data)})}return ScriptsManager.prototype=new Manager,new ScriptsManager}])},"./src/maasserver/static/js/angular/factories/services.js":function(module,exports){angular.module("MAAS").factory("ServicesManager",["$q","$rootScope","RegionConnection","Manager",function($q,$rootScope,RegionConnection,Manager){function ServicesManager(){Manager.call(this),this._pk="id",this._handler="service";var self=this;RegionConnection.registerNotifier("service",function(action,data){self.onNotify(action,data)})}return ServicesManager.prototype=new Manager,new ServicesManager}])},"./src/maasserver/static/js/angular/factories/spaces.js":function(module,exports){angular.module("MAAS").factory("SpacesManager",["$q","$rootScope","RegionConnection","Manager","SubnetsManager",function($q,$rootScope,RegionConnection,Manager,SubnetsManager){function SpacesManager(){Manager.call(this),this._pk="id",this._handler="space";var self=this;RegionConnection.registerNotifier("space",function(action,data){self.onNotify(action,data)})}return SpacesManager.prototype=new Manager,SpacesManager.prototype.create=function(space){return RegionConnection.callMethod("space.create",space)},SpacesManager.prototype.deleteSpace=function(space){return RegionConnection.callMethod("space.delete",space)},new SpacesManager}])},"./src/maasserver/static/js/angular/factories/sshkeys.js":function(module,exports){angular.module("MAAS").factory("SSHKeysManager",["$q","$rootScope","RegionConnection","Manager",function($q,$rootScope,RegionConnection,Manager){function SSHKeysManager(){Manager.call(this),this._pk="id",this._handler="sshkey";var self=this;RegionConnection.registerNotifier("sshkey",function(action,data){self.onNotify(action,data)})}return SSHKeysManager.prototype=new Manager,SSHKeysManager.prototype.importKeys=function(params){return RegionConnection.callMethod("sshkey.import_keys",params)},new SSHKeysManager}])},"./src/maasserver/static/js/angular/factories/staticroutes.js":function(module,exports){angular.module("MAAS").factory("StaticRoutesManager",["$q","$rootScope","RegionConnection","Manager",function($q,$rootScope,RegionConnection,Manager){function StaticRoutesManager(){Manager.call(this),this._pk="id",this._handler="staticroute";var self=this;RegionConnection.registerNotifier("staticroute",function(action,data){self.onNotify(action,data)})}return StaticRoutesManager.prototype=new Manager,new StaticRoutesManager}])},"./src/maasserver/static/js/angular/factories/subnets.js":function(module,exports){angular.module("MAAS").factory("SubnetsManager",["$q","$rootScope","RegionConnection","Manager",function($q,$rootScope,RegionConnection,Manager){function SubnetsManager(){Manager.call(this),this._pk="id",this._handler="subnet";var self=this;RegionConnection.registerNotifier("subnet",function(action,data){self.onNotify(action,data)})}return SubnetsManager.prototype=new Manager,SubnetsManager.prototype.getName=function(subnet){if(!angular.isObject(subnet))return"";var name=subnet.cidr;return angular.isString(subnet.name)&&""!==subnet.name&&subnet.name!==subnet.cidr&&(name+=" ("+subnet.name+")"),name},SubnetsManager.prototype.getLargestRange=function(subnet){var largest_range={num_addresses:0,start:"",end:""};return angular.forEach(subnet.statistics.ranges,function(iprange){angular.equals(iprange.purpose,["unused"])&&iprange.num_addresses>largest_range.num_addresses&&(largest_range=iprange)}),largest_range},SubnetsManager.prototype.hasDynamicRange=function(subnet){var i;for(i=0;i<subnet.statistics.ranges.length;i++){if(-1!==subnet.statistics.ranges[i].purpose.indexOf("dynamic"))return!0}return!1},SubnetsManager.prototype.create=function(subnet){return RegionConnection.callMethod("subnet.create",subnet)},SubnetsManager.prototype.deleteSubnet=function(subnet){return RegionConnection.callMethod("subnet.delete",{id:subnet.id})},SubnetsManager.prototype.scanSubnet=function(subnet){return RegionConnection.callMethod("subnet.scan",{id:subnet.id})},new SubnetsManager}])},"./src/maasserver/static/js/angular/factories/switches.js":function(module,exports){angular.module("MAAS").factory("SwitchesManager",["$q","$rootScope","RegionConnection","NodesManager",function($q,$rootScope,RegionConnection,NodesManager){function SwitchesManager(){NodesManager.call(this),this._pk="system_id",this._handler="switch",this._metadataAttributes={owner:null,subnets:null,tags:null,zone:function(device){return device.zone.name}};var self=this;RegionConnection.registerNotifier("switch",function(action,data){self.onNotify(action,data)})}return SwitchesManager.prototype=new NodesManager,SwitchesManager.prototype.create=function(node){return RegionConnection.callMethod("switch.create",node)},SwitchesManager.prototype.performAction=function(device,action,extra){return angular.isObject(extra)||(extra={}),RegionConnection.callMethod("switch.action",{system_id:device.system_id,action:action,extra:extra})},new SwitchesManager}])},"./src/maasserver/static/js/angular/factories/tags.js":function(module,exports){angular.module("MAAS").factory("TagsManager",["$q","$rootScope","RegionConnection","Manager",function($q,$rootScope,RegionConnection,Manager){function TagsManager(){Manager.call(this),this._pk="id",this._handler="tag";var self=this;RegionConnection.registerNotifier("tag",function(action,data){self.onNotify(action,data)})}return TagsManager.prototype=new Manager,TagsManager.prototype.autocomplete=function(query){var matching=[];return angular.forEach(this._items,function(item){item.name.indexOf(query)>-1&&matching.push(item.name)}),matching},new TagsManager}])},"./src/maasserver/static/js/angular/factories/users.js":function(module,exports){angular.module("MAAS").factory("UsersManager",["RegionConnection","Manager","ErrorService",function(RegionConnection,Manager,ErrorService){function UsersManager(){Manager.call(this),this._pk="id",this._handler="user",this._authUser=null;var self=this;RegionConnection.registerNotifier("user",function(action,data){self.onNotify(action,data)})}return UsersManager.prototype=new Manager,UsersManager.prototype.getAuthUser=function(){return this._authUser},UsersManager.prototype.isSuperUser=function(){var authUser=this.getAuthUser();return!!angular.isObject(authUser)&&authUser.is_superuser},UsersManager.prototype.getSSHKeyCount=function(){return authuser=this._authUser,angular.isObject(authuser)?authuser.sshkeys_count:0},UsersManager.prototype._loadAuthUser=function(){var self=this;return RegionConnection.callMethod("user.auth_user",{}).then(function(user){return angular.isObject(self._authUser)?angular.copy(user,self._authUser):self._authUser=user,self._authUser},function(error){ErrorService.raiseError(error)})},UsersManager.prototype._replaceItem=function(item){Manager.prototype._replaceItem.call(this,item),angular.isObject(this._authUser)&&this._authUser[this._pk]===item[this._pk]&&angular.copy(item,this._authUser)},UsersManager.prototype.loadItems=function(){return this._loadAuthUser(),Manager.prototype.loadItems.call(this)},UsersManager.prototype.reloadItems=function(){return this._loadAuthUser(),Manager.prototype.reloadItems.call(this)},UsersManager.prototype.markIntroComplete=function(){var self=this;return RegionConnection.callMethod("user.mark_intro_complete",{}).then(function(user){return angular.isObject(self._authUser)?angular.copy(user,self._authUser):self._authUser=user,self._authUser},function(error){ErrorService.raiseError(error)})},UsersManager.prototype.createAuthorisationToken=function(){return RegionConnection.callMethod("user.create_authorisation_token",{}).catch(function(error){ErrorService.raiseError(error)})},UsersManager.prototype.deleteAuthorisationToken=function(key){return RegionConnection.callMethod("user.delete_authorisation_token",{key:key}).catch(function(error){ErrorService.raiseError(error)})},new UsersManager}])},"./src/maasserver/static/js/angular/factories/vlans.js":function(module,exports){angular.module("MAAS").factory("VLANsManager",["$q","$rootScope","RegionConnection","Manager","SubnetsManager",function($q,$rootScope,RegionConnection,Manager,SubnetsManager){function VLANsManager(){Manager.call(this),this._pk="id",this._handler="vlan";var self=this;RegionConnection.registerNotifier("vlan",function(action,data){self.onNotify(action,data)})}return VLANsManager.prototype=new Manager,VLANsManager.prototype.getName=function(vlan){var name=vlan.vid;return 0===vlan.vid?name="untagged":angular.isString(vlan.name)&&""!==vlan.name&&(name+=" ("+vlan.name+")"),name},VLANsManager.prototype.deleteVLAN=function(vlan){return RegionConnection.callMethod("vlan.delete",{id:vlan.id},!0)},VLANsManager.prototype.addRackController=function(vlan,rack){vlan.rack_sids.push(rack.system_id)},VLANsManager.prototype.configureDHCP=function(vlan,controllers,extra,relay_vlan){var params={id:vlan.id,controllers:controllers,extra:extra};return(null===relay_vlan||angular.isNumber(relay_vlan))&&(params.relay_vlan=relay_vlan),RegionConnection.callMethod("vlan.configure_dhcp",params,!0)},VLANsManager.prototype.disableDHCP=function(vlan){return RegionConnection.callMethod("vlan.configure_dhcp",{id:vlan.id,controllers:[],relay_vlan:null},!0)},VLANsManager.prototype.create=function(vlan){return RegionConnection.callMethod("vlan.create",vlan)},new VLANsManager}])},"./src/maasserver/static/js/angular/factories/zones.js":function(module,exports){angular.module("MAAS").factory("ZonesManager",["$q","$rootScope","RegionConnection","Manager",function($q,$rootScope,RegionConnection,Manager){function ZonesManager(){Manager.call(this),this._pk="id",this._handler="zone";var self=this;RegionConnection.registerNotifier("zone",function(action,data){self.onNotify(action,data)})}return ZonesManager.prototype=new Manager,ZonesManager.prototype.getDefaultZone=function(){if(0===this._items.length)return null;var i;for(i=0;i<this._items.length;i++)if(0===this._items[i].id)return this._items[i];return this._items[0]},new ZonesManager}])},"./src/maasserver/static/js/angular/filters/by_fabric.js":function(module,exports){angular.module("MAAS").filter("filterByFabric",function(){return function(vlans,fabric){var id,filtered=[];if(angular.isObject(fabric))id=fabric.id;else{if(!angular.isNumber(fabric))return filtered;id=fabric}return angular.forEach(vlans,function(vlan){vlan.fabric===id&&filtered.push(vlan)}),filtered}})},"./src/maasserver/static/js/angular/filters/by_space.js":function(module,exports){angular.module("MAAS").filter("filterBySpace",function(){return function(objects,space){var id,filtered=[];if(angular.isObject(space))id=space.id;else{if(!angular.isNumber(space))return filtered;id=space}return angular.forEach(objects,function(object){object.space===id&&filtered.push(object)}),filtered}}),angular.module("MAAS").filter("filterByNullSpace",function(){return function(objects){var filtered=[];return angular.forEach(objects,function(object){null===object.space&&filtered.push(object)}),filtered}})},"./src/maasserver/static/js/angular/filters/by_subnet.js":function(module,exports){angular.module("MAAS").filter("filterBySubnet",function(){return function(foreign_objects,subnet,key){var id,filtered=[];if(angular.isObject(subnet))id=subnet.id;else{if(!angular.isNumber(subnet))return filtered;id=subnet}return angular.isUndefined(key)&&(key="subnet"),angular.forEach(foreign_objects,function(obj){obj[key]===id&&filtered.push(obj)}),filtered}}),angular.module("MAAS").filter("filterBySubnetOrVlan",function(){return function(foreign_objects,subnet,vlan){var id,filtered=[],key=null;if(angular.isDefined(subnet)&&null!==subnet)key="subnet",angular.isObject(subnet)?id=subnet.id:angular.isNumber(subnet)&&(id=subnet);else{if(!angular.isDefined(vlan)||null===vlan)return filtered;key="vlan",angular.isObject(vlan)?id=vlan.id:angular.isNumber(vlan)&&(id=vlan)}return angular.forEach(foreign_objects,function(obj){obj[key]===id&&filtered.push(obj)}),filtered}})},"./src/maasserver/static/js/angular/filters/by_vlan.js":function(module,exports){angular.module("MAAS").filter("filterByVLAN",function(){return function(subnets,vlan){var id,filtered=[];if(angular.isObject(vlan))id=vlan.id;else{if(!angular.isNumber(vlan))return filtered;id=vlan}return angular.forEach(subnets,function(subnet){subnet.vlan===id&&filtered.push(subnet)}),filtered}}),angular.module("MAAS").filter("filterControllersByVLAN",function(){return function(controllers,vlan){var filtered=[];return angular.isObject(vlan)?(angular.forEach(controllers,function(controller){2!==controller.node_type&&4!==controller.node_type||filtered.push(controller)}),filtered):filtered}})},"./src/maasserver/static/js/angular/filters/nodes.js":function(module,exports){angular.module("MAAS").filter("nodesFilter",["$filter","SearchService",function($filter,SearchService){var standardFilter=$filter("filter"),mappings={cpu:function(node){return node.cpu_count},cores:function(node){return node.cpu_count},ram:function(node){return node.memory},mac:function(node){return macs=[],macs.push(node.pxe_mac),macs.push.apply(macs,node.extra_macs),macs},zone:function(node){return node.zone.name},pool:function(node){return node.pool.name},pod:function(node){return void 0===node.pod?void 0:node.pod.name},"pod-id":function(node){return void 0===node.pod?void 0:node.pod.id},power:function(node){return node.power_state},release:function(node){return 6===node.status_code||9===node.status_code?node.osystem+"/"+node.distro_series:""}};function isInteger(value){return value%1==0}function matches(value,lowerTerm,exact,negate){var match=function(value,lowerTerm,exact){return angular.isNumber(value)?exact?isInteger(value)?value===parseInt(lowerTerm,10):value===parseFloat(lowerTerm):isInteger(value)?value>=parseInt(lowerTerm,10):value>=parseFloat(lowerTerm):angular.isString(value)?exact?value.toLowerCase()===lowerTerm:value.toLowerCase().indexOf(lowerTerm)>=0:value===lowerTerm}(value,lowerTerm,exact);return negate?!match:match}return function(nodes,search){if(angular.isUndefined(nodes)||angular.isUndefined(search)||0===nodes.length)return nodes;var filtered=nodes,filters=SearchService.getCurrentFilters(search);return angular.forEach(filters,function(terms,attr){if("_"===attr)angular.forEach(terms,function(term){filtered=standardFilter(filtered,term)});else if("in"===attr)angular.forEach(terms,function(term){var matched=[];angular.forEach(filtered,function(node){node.$selected&&"selected"===term.toLowerCase()?matched.push(node):node.$selected||"!selected"!==term.toLowerCase()||matched.push(node)}),filtered=matched});else{var mapFunc=mappings[attr],matched=[];angular.forEach(filtered,function(node){var value,i,j;if(angular.isFunction(mapFunc)?value=mapFunc(node):node.hasOwnProperty(attr)&&(value=node[attr]),!angular.isUndefined(value))for(i=0;i<terms.length;i++){for(var term=terms[i].toLowerCase(),exact=!1,negate=!1;0===term.indexOf("!");)negate=!negate,term=term.substring(1);for(0===term.indexOf("=")&&(exact=!0,term=term.substring(1));0===term.indexOf("!");)negate=!negate,term=term.substring(1);if(angular.isArray(value)){if(negate){var no_match=!0;for(j=0;j<value.length;j++)if(matches(value[j],term,exact,!1)){no_match=!1;break}if(no_match)return void matched.push(node)}else for(j=0;j<value.length;j++)if(matches(value[j],term,exact,!1))return void matched.push(node)}else if(matches(value,term,exact,negate))return void matched.push(node)}}),filtered=matched}}),filtered}}])},"./src/maasserver/static/js/angular/filters/order_by_date.js":function(module,exports){angular.module("MAAS").filter("orderByDate",function(){return function(items,field,field2){var sorted=items.slice();return sorted.sort(function(a,b){return aDate=new Date(a[field]),bDate=new Date(b[field]),angular.isString(field2)&&aDate.getTime()===bDate.getTime()?a[field2]>b[field2]?-1:a[field2]<b[field2]?1:0:aDate>bDate?-1:aDate<bDate?1:0}),sorted}})},"./src/maasserver/static/js/angular/filters/remove_default_vlan.js":function(module,exports){angular.module("MAAS").filter("removeDefaultVLAN",function(){return function(vlans){var filtered=[];return angular.forEach(vlans,function(vlan){0!==vlan.vid&&filtered.push(vlan)}),filtered}})},"./src/maasserver/static/js/angular/maas.js":function(module,exports){angular.module("MAAS",["ngRoute","ngCookies","ngSanitize","ngTagsInput","vs-repeat"]).config(function($interpolateProvider,$routeProvider,$httpProvider){function versionedPath(path){return path+"?v="+MAAS_config.files_version}$interpolateProvider.startSymbol("{$"),$interpolateProvider.endSymbol("$}"),$httpProvider.defaults.xsrfCookieName="csrftoken",$httpProvider.defaults.xsrfHeaderName="X-CSRFToken";var href=angular.element("base").attr("href"),path=document.location.pathname;if("/"!==path[path.length-1]&&(path+="/"),path===href){var routes=$routeProvider.when("/intro",{templateUrl:versionedPath("static/partials/intro.html"),controller:"IntroController"}).when("/intro/user",{templateUrl:versionedPath("static/partials/intro-user.html"),controller:"IntroUserController"}).when("/machines",{templateUrl:versionedPath("static/partials/nodes-list.html"),controller:"NodesListController"}).when("/machine/:system_id/:result_type/:id",{templateUrl:versionedPath("static/partials/node-result.html"),controller:"NodeResultController"}).when("/machine/:system_id/events",{templateUrl:versionedPath("static/partials/node-events.html"),controller:"NodeEventsController"}).when("/machine/:system_id",{templateUrl:versionedPath("static/partials/node-details.html"),controller:"NodeDetailsController"}).when("/devices",{templateUrl:versionedPath("static/partials/nodes-list.html"),controller:"NodesListController"}).when("/device/:system_id/:result_type/:id",{templateUrl:versionedPath("static/partials/node-result.html"),controller:"NodeResultController"}).when("/device/:system_id/events",{templateUrl:versionedPath("static/partials/node-events.html"),controller:"NodeEventsController"}).when("/device/:system_id",{templateUrl:versionedPath("static/partials/node-details.html"),controller:"NodeDetailsController"}).when("/controllers",{templateUrl:versionedPath("static/partials/nodes-list.html"),controller:"NodesListController"}).when("/controller/:system_id/:result_type/:id",{templateUrl:versionedPath("static/partials/node-result.html"),controller:"NodeResultController"}).when("/controller/:system_id/events",{templateUrl:versionedPath("static/partials/node-events.html"),controller:"NodeEventsController"}).when("/controller/:system_id",{templateUrl:versionedPath("static/partials/node-details.html"),controller:"NodeDetailsController"}).when("/nodes",{redirectTo:"/machines"}).when("/node/machine/:system_id",{redirectTo:"/machine/:system_id"}).when("/node/machine/:system_id/:result_type/:id",{redirectTo:"/machine/:system_id/:result_type/:id"}).when("/node/machine/:system_id/events",{redirectTo:"/machine/:system_id/events"}).when("/node/device/:system_id",{redirectTo:"/device/:system_id"}).when("/node/device/:system_id/:result_type/:id",{redirectTo:"/device/:system_id/:result_type/:id"}).when("/node/device/:system_id/events",{redirectTo:"/device/:system_id/events"}).when("/node/controller/:system_id",{redirectTo:"/controller/:system_id"}).when("/node/controller/:system_id/:result_type/:id",{redirectTo:"/controller/:system_id/:result_type/:id"}).when("/node/controller/:system_id/events",{redirectTo:"/controller/:system_id/events"}).when("/pods",{templateUrl:versionedPath("static/partials/pods-list.html"),controller:"PodsListController"}).when("/pod/:id",{templateUrl:versionedPath("static/partials/pod-details.html"),controller:"PodDetailsController"}).when("/images",{templateUrl:versionedPath("static/partials/images.html"),controller:"ImagesController"}).when("/domains",{templateUrl:versionedPath("static/partials/domains-list.html"),controller:"DomainsListController"}).when("/domain/:domain_id",{templateUrl:versionedPath("static/partials/domain-details.html"),controller:"DomainDetailsController"}).when("/space/:space_id",{templateUrl:versionedPath("static/partials/space-details.html"),controller:"SpaceDetailsController"}).when("/fabric/:fabric_id",{templateUrl:versionedPath("static/partials/fabric-details.html"),controller:"FabricDetailsController"}).when("/subnets",{redirectTo:"/networks?by=fabric"}).when("/networks",{templateUrl:versionedPath("static/partials/networks-list.html"),controller:"NetworksListController",reloadOnSearch:!1}).when("/subnet/:subnet_id",{templateUrl:versionedPath("static/partials/subnet-details.html"),controller:"SubnetDetailsController"}).when("/vlan/:vlan_id",{templateUrl:versionedPath("static/partials/vlan-details.html"),controller:"VLANDetailsController",controllerAs:"vlanDetails"}).when("/settings/:section",{templateUrl:versionedPath("static/partials/settings.html"),controller:"SettingsController"}).when("/zone/:zone_id",{templateUrl:versionedPath("static/partials/zone-details.html"),controller:"ZoneDetailsController"}).when("/zones",{templateUrl:versionedPath("static/partials/zones-list.html"),controller:"ZonesListController",reloadOnSearch:!1}).when("/pools",{templateUrl:versionedPath("static/partials/nodes-list.html"),controller:"NodesListController"});MAAS_config.superuser&&(routes=routes.when("/dashboard",{templateUrl:versionedPath("static/partials/dashboard.html"),controller:"DashboardController"})),routes=routes.otherwise({redirectTo:"/machines"})}}),angular.module("MAAS").run(["$rootScope","$location",function($rootScope,$location){$rootScope.$on("$routeChangeStart",function(event,next,current){MAAS_config.completed_intro?MAAS_config.user_completed_intro||"IntroUserController"!==next.controller&&$location.path("/intro/user"):"IntroController"!==next.controller&&$location.path("/intro")})}]),angular.module("MAAS").run(["$rootScope",function($rootScope){window.ga=window.ga||function(){(window.ga.q=window.ga.q||[]).push(arguments)},window.ga.l=+new Date,window.ga("create","UA-1018242-63","auto",{userId:MAAS_config.analytics_user_id}),window.ga("set","dimension1",MAAS_config.version),window.ga("set","dimension2",MAAS_config.uuid),$rootScope.$on("$routeChangeSuccess",function(){var path=window.location.pathname+window.location.hash;window.ga("send","pageview",path)})}])},"./src/maasserver/static/js/angular/services/browser.js":function(module,exports){angular.module("MAAS").service("BrowserService",["$window",function($window){this.browser="other";var self=this;angular.forEach([{name:"chrome",regex:/chrome/i},{name:"safari",regex:/safari/i},{name:"firefox",regex:/firefox/i},{name:"ie",regex:/MSIE/}],function(matcher){matcher.regex.test($window.navigator.userAgent)&&"other"===self.browser&&(self.browser=matcher.name)})}])},"./src/maasserver/static/js/angular/services/converter.js":function(module,exports){angular.module("MAAS").service("ConverterService",function(){var UNITS=["bytes","kB","MB","GB","TB"];this.bytesToUnits=function(bytes){angular.isString(bytes)&&(bytes=parseInt(bytes,10));var i,unit,converted=bytes;for(i=0;i<UNITS.length;i++){if(unit=UNITS[i],Math.abs(converted)<1e3||"TB"===unit){var string=converted.toFixed(1)+" "+unit;return"bytes"===unit&&(string=converted+" "+unit),{original:bytes,converted:converted,units:unit,string:string}}converted/=1e3}},this.unitsToBytes=function(data,unit){return angular.isString(data)&&(data=parseFloat(data)),"bytes"===unit?Math.floor(data):"kB"===unit?Math.floor(1e3*data):"MB"===unit?Math.floor(1e6*data):"GB"===unit?Math.floor(1e9*data):"TB"===unit?Math.floor(1e12*data):void 0},this.roundUnits=function(data,unit){return angular.isString(data)&&(data=parseFloat(data)),"bytes"===unit?Math.floor(data):"kB"===unit?Math.floor(1e3*data)-50:"MB"===unit?Math.floor(1e6*data)-5e4:"GB"===unit?Math.floor(1e9*data)-5e7:"TB"===unit?Math.floor(1e12*data)-5e10:void 0},this.roundByBlockSize=function(bytes,block_size){return block_size*Math.floor(bytes/block_size)},this.ipv4ToOctets=function(ipAddress){var parts=ipAddress.split("."),octets=[];return angular.forEach(parts,function(part){octets.push(parseInt(part,10))}),octets},this.ipv4ToInteger=function(ipAddress){var octets=this.ipv4ToOctets(ipAddress);return octets[0]*Math.pow(256,3)+octets[1]*Math.pow(256,2)+256*octets[2]+octets[3]},this.ipv6Expand=function(ipAddress){var i,expandedAddress=ipAddress;if(-1!==expandedAddress.indexOf("::")){var split=ipAddress.split("::"),groups=0;for(i=0;i<split.length;i++)groups+=split[i].split(":").length;for(expandedAddress=split[0]+":",i=0;i<8-groups;i++)expandedAddress+="0000:";expandedAddress+=split[1]}var output=[],parts=expandedAddress.split(":");return angular.forEach(parts,function(part){output.push("0000".substr(part.length)+part)}),output.join(":")},this.ipv6ToGroups=function(ipAddress){var groups=[],parts=this.ipv6Expand(ipAddress).split(":");return angular.forEach(parts,function(part){groups.push(parseInt(part,16))}),groups}})},"./src/maasserver/static/js/angular/services/error.js":function(module,exports){angular.module("MAAS").service("ErrorService",function(){this._error=null,this.raiseError=function(error){angular.isString(this._error)||(this._error=error)}})},"./src/maasserver/static/js/angular/services/json.js":function(module,exports){function _typeof(obj){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(obj){return typeof obj}:function(obj){return obj&&"function"==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj})(obj)}angular.module("MAAS").service("JSONService",function(){this.tryParse=function(jsonString){try{var obj=JSON.parse(jsonString);if(obj&&"object"===_typeof(obj)&&null!==obj)return obj}catch(e){}return null}})},"./src/maasserver/static/js/angular/services/log.js":function(module,exports){angular.module("MAAS").service("LogService",["$window",function($window){var self=this;self.logging=!0,self.logLevel=5,self.now=function(){return $window.performance?$window.performance.now():0},self._debug=console.debug,self._log=console.log,self._info=console.info,self._warn=console.warn,self._error=console.error,this.formatMilliseconds=function(milliseconds){return parseFloat(milliseconds/1e3).toFixed(3)},this.__log=function(destination,args){!0===self.logging&&(Array.prototype.unshift.call(args,"["+self.formatMilliseconds(self.now())+"]"),destination.apply(self,args))},this.debug=function(){self.logLevel>=5&&self.__log(self._debug,arguments)},this.log=function(){self.logLevel>=4&&self.__log(self._log,arguments)},this.info=function(){self.logLevel>=3&&self.__log(self._info,arguments)},this.warn=function(){self.logLevel>=2&&self.__log(self._warn,arguments)},this.error=function(){self.logLevel>=1&&self.__log(self._error,arguments)}}])},"./src/maasserver/static/js/angular/services/manager.js":function(module,exports){angular.module("MAAS").service("Manager",["$q","$rootScope","$timeout","RegionConnection",function($q,$rootScope,$timeout,RegionConnection){var METADATA_ACTIONS={CREATE:"create",UPDATE:"update",DELETE:"delete"};function Manager(){this._pk="id",this._batchKey="id",this._name_field="name",this._handler=null,this._items=[],this._type="notify",this._scopes=[],this._loaded=!1,this._isLoading=!1,this._extraLoadDefers=[],this._extraReloadDefers=[],this._actionQueue=[],this._selectedItems=[],this._autoReload=!1,this._activeItem=null,this._metadata={},this._metadataAttributes=[]}return Manager.prototype._getIndexOfItem=function(array,pk_value){var i;for(i=0,len=array.length;i<len;i++)if(array[i][this._pk]===pk_value)return i;return-1},Manager.prototype._replaceItemInArray=function(array,item){var idx=this._getIndexOfItem(array,item[this._pk]);idx>=0&&(item.$selected=array[idx].$selected,angular.copy(item,array[idx]))},Manager.prototype._removeItemByIdFromArray=function(array,pk_value){var idx=this._getIndexOfItem(array,pk_value);idx>=0&&array.splice(idx,1)},Manager.prototype._initBatchLoadParameters=function(){return{}},Manager.prototype._batchLoadItems=function(array,extra_func){var self=this,defer=$q.defer(),method=this._handler+".list";return function callLoad(){var params=self._initBatchLoadParameters();params.limit=50,array.length>0&&(params.start=array[array.length-1][self._batchKey]),RegionConnection.callMethod(method,params).then(function(items){angular.isFunction(extra_func)&&angular.forEach(items,function(item){extra_func(item)}),array.push.apply(array,items),50===items.length?callLoad():defer.resolve(array)},defer.reject)}(),defer.promise},Manager.prototype._resolveDefers=function(defersArray,item){angular.forEach(defersArray,function(defer){defer.resolve(item)})},Manager.prototype._rejectDefers=function(defersArray,error){angular.forEach(defersArray,function(defer){defer.reject(error)})},Manager.prototype.getItems=function(){return this._items},Manager.prototype.clear=function(){this._loaded=!1,this._items.length=0,this._actionQueue.length=0,this._selectedItems.length=0,this._activeItem=null,this._metadata={},this._metadataAttributes.length=0},Manager.prototype.loadItems=function(){if(this._loaded)return this.reloadItems();if(this._isLoading){var defer=$q.defer();return this._extraLoadDefers.push(defer),defer.promise}var self=this;return this._isLoading=!0,this._batchLoadItems(this._items,function(item){item.$selected=!1,self._updateMetadata(item,METADATA_ACTIONS.CREATE),self._processItem(item)}).then(function(){return self._loaded=!0,self._isLoading=!1,self.processActions(),self._resolveDefers(self._extraLoadDefers,self._items),self._extraLoadDefers=[],self._items},function(error){return self._rejectDefers(self._extraLoadDefers,error),self._extraLoadDefers=[],$q.reject(error)})},Manager.prototype.reloadItems=function(){if(!this._loaded)return this.loadItems();if(this._isLoading){var defer=$q.defer();return this._extraReloadDefers.push(defer),defer.promise}var self=this;return self._isLoading=!0,this._batchLoadItems([]).then(function(items){return function(items){for(var i=self._items.length;i--;){var item=self._items[i],updatedIdx=self._getIndexOfItem(items,item[self._pk]);if(-1===updatedIdx)self._updateMetadata(item,METADATA_ACTIONS.DELETE),self._items.splice(i,1),self._removeItemByIdFromArray(self._selectedItems,item[self._pk]);else{var updatedItem=items[updatedIdx];self._updateMetadata(updatedItem,METADATA_ACTIONS.UPDATE),updatedItem.$selected=item.$selected,angular.copy(items[updatedIdx],item),items.splice(updatedIdx,1)}}angular.forEach(items,function(item){self._items.push(item),self._processItem(item)})}(items),self._isLoading=!1,self.processActions(),angular.isObject(self._activeItem)&&self.setActiveItem(self._activeItem[self._pk]),self._resolveDefers(self._extraReloadDefers,self._items),self._extraReloadDefers=[],self._items},function(error){return self._rejectDefers(self._extraReloadDefers,error),self._extraReloadDefers=[],$q.reject(error)})},Manager.prototype.enableAutoReload=function(){if(!this._autoReload){this._autoReload=!0;var self=this;this._reloadFunc=function(){self.reloadItems()},RegionConnection.registerHandler("open",this._reloadFunc)}},Manager.prototype.disableAutoReload=function(){this._autoReload&&(RegionConnection.unregisterHandler("open",this._reloadFunc),this._reloadFunc=null,this._autoReload=!1)},Manager.prototype.isLoaded=function(){return this._loaded},Manager.prototype.isLoading=function(){return this._isLoading},Manager.prototype._processItem=function(item){},Manager.prototype._replaceItem=function(item){this._updateMetadata(item,METADATA_ACTIONS.UPDATE),this._replaceItemInArray(this._items,item)},Manager.prototype._removeItem=function(pk_value){var idx=this._getIndexOfItem(this._items,pk_value);idx>=0&&this._updateMetadata(this._items[idx],METADATA_ACTIONS.DELETE),this._removeItemByIdFromArray(this._items,pk_value),this._removeItemByIdFromArray(this._selectedItems,pk_value)},Manager.prototype.getItemFromList=function(pk_value){var idx=this._getIndexOfItem(this._items,pk_value);return idx>=0?this._items[idx]:null},Manager.prototype.getItem=function(pk_value){var self=this,method=this._handler+".get",params={};return params[this._pk]=pk_value,RegionConnection.callMethod(method,params).then(function(item){return self._replaceItem(item),item})},Manager.prototype.createItem=function(item){var self=this,method=this._handler+".create";return delete(item=angular.copy(item)).$selected,RegionConnection.callMethod(method,item).then(function(item){return self._replaceItem(item),item})},Manager.prototype.updateItem=function(item){var self=this,method=this._handler+".update";return delete(item=angular.copy(item)).$selected,RegionConnection.callMethod(method,item).then(function(item){return self._replaceItem(item),item})},Manager.prototype.deleteItem=function(item){var self=this,method=this._handler+".delete",params={};return params[this._pk]=item[this._pk],RegionConnection.callMethod(method,params).then(function(){self._removeItem(item[self._pk])})},Manager.prototype.getActiveItem=function(){return this._activeItem},Manager.prototype.setActiveItem=function(pk_value){if(!this._loaded)throw new Error("Cannot set active item unless the manager is loaded.");var idx=this._getIndexOfItem(this._items,pk_value);if(-1===idx){this._activeItem=null;var defer=$q.defer();return $timeout(function(){defer.reject("No item with pk: "+pk_value)}),defer.promise}this._activeItem=this._items[idx];var self=this,method=this._handler+".set_active",params={};return params[this._pk]=pk_value,RegionConnection.callMethod(method,params).then(function(item){return self._replaceItem(item),self._activeItem})},Manager.prototype.clearActiveItem=function(){this._activeItem=null},Manager.prototype.canProcessActions=function(){return!this._isLoading},Manager.prototype.onNotify=function(action,data){this._actionQueue.push({action:action,data:data}),this.canProcessActions()&&$rootScope.$apply(this.processActions())},Manager.prototype.processActions=function(){for(;this._actionQueue.length>0;){var action=this._actionQueue.shift();if("create"===action.action)this._getIndexOfItem(this._items,action.data[this._pk])>=0?this._replaceItem(action.data):(action.data.$selected=!1,this._updateMetadata(action.data,METADATA_ACTIONS.CREATE),this._items.push(action.data)),this._processItem(action.data);else"update"===action.action?(this._replaceItem(action.data),this._processItem(action.data)):"delete"===action.action&&this._removeItem(action.data)}},Manager.prototype.getSelectedItems=function(){return this._selectedItems},Manager.prototype.selectItem=function(pk_value){var idx=this._getIndexOfItem(this._items,pk_value);if(-1!==idx){var item=this._items[idx];item.$selected=!0,-1===(idx=this._selectedItems.indexOf(item))&&this._selectedItems.push(item)}else console.log("WARN: selection of "+this._handler+"("+pk_value+") failed because its missing in the items list.")},Manager.prototype.unselectItem=function(pk_value){var idx=this._getIndexOfItem(this._items,pk_value);if(-1!==idx){var item=this._items[idx];item.$selected=!1,(idx=this._selectedItems.indexOf(item))>=0&&this._selectedItems.splice(idx,1)}else console.log("WARN: de-selection of "+this._handler+"("+pk_value+") failed because its missing in the nodes list.")},Manager.prototype.isSelected=function(pk_value){var idx=this._getIndexOfItem(this._items,pk_value);return-1===idx?(console.log("WARN: unable to determine if "+this._handler+"("+pk_value+") is selected because its missing in the nodes list."),!1):!0===this._items[idx].$selected},Manager.prototype._getMetadataValue=function(metadatas,name){var i;for(i=0;i<metadatas.length;i++)if(metadatas[i].name===name)return metadatas[i];return null},Manager.prototype._addMetadataValue=function(metadatas,value){var metadata=this._getMetadataValue(metadatas,value);metadata?metadata.count+=1:(metadata={name:value,count:1},metadatas.push(metadata))},Manager.prototype._removeMetadataValue=function(metadatas,value){var metadata=this._getMetadataValue(metadatas,value);metadata&&(metadata.count-=1,metadata.count<=0&&metadatas.splice(metadatas.indexOf(metadata),1))},Manager.prototype._updateMetadataArrayEntry=function(metadatas,newValue,action,oldValue){var self=this;if(action===METADATA_ACTIONS.CREATE)angular.forEach(newValue,function(value){""!==value&&self._addMetadataValue(metadatas,value)});else if(action===METADATA_ACTIONS.DELETE)angular.forEach(newValue,function(value){self._removeMetadataValue(metadatas,value)});else if(action===METADATA_ACTIONS.UPDATE&&angular.isDefined(oldValue)){var added=[],oldArray=angular.copy(oldValue);angular.forEach(newValue,function(value){var idx=oldArray.indexOf(value);-1===idx?added.push(value):oldArray.splice(idx,1)}),angular.forEach(added,function(value){self._addMetadataValue(metadatas,value)}),angular.forEach(oldArray,function(value){self._removeMetadataValue(metadatas,value)})}},Manager.prototype._updateMetadataValueEntry=function(metadatas,newValue,action,oldValue){if(action===METADATA_ACTIONS.CREATE){if(""===newValue)return;this._addMetadataValue(metadatas,newValue)}else action===METADATA_ACTIONS.DELETE?this._removeMetadataValue(metadatas,newValue):action===METADATA_ACTIONS.UPDATE&&angular.isDefined(oldValue)&&oldValue!==newValue&&(""!==oldValue&&this._removeMetadataValue(metadatas,oldValue),this._updateMetadataEntry(metadatas,newValue,METADATA_ACTIONS.CREATE,oldValue))},Manager.prototype._updateMetadataEntry=function(metadatas,newValue,action,oldValue){angular.isArray(newValue)?this._updateMetadataArrayEntry(metadatas,newValue,action,oldValue):this._updateMetadataValueEntry(metadatas,newValue,action,oldValue)},Manager.prototype.getMetadata=function(){return this._metadata},Manager.prototype._updateMetadata=function(item,action){var oldItem,idx,self=this;action===METADATA_ACTIONS.UPDATE&&(idx=this._getIndexOfItem(this._items,item[this._pk]))>=0&&(oldItem=this._items[idx]),angular.forEach(this._metadataAttributes,function(func,attr){var newValue,oldValue;angular.isUndefined(self._metadata[attr])&&(self._metadata[attr]=[]),angular.isFunction(func)?(newValue=func(item),angular.isObject(oldItem)&&(oldValue=func(oldItem))):(newValue=item[attr],angular.isObject(oldItem)&&(oldValue=oldItem[attr])),self._updateMetadataEntry(self._metadata[attr],newValue,action,oldValue)})},Manager.prototype.getName=function(obj){if(angular.isObject(obj))return angular.isString(obj[this._name_field])?obj[this._name_field]:void 0},Manager}])},"./src/maasserver/static/js/angular/services/managerhelper.js":function(module,exports){angular.module("MAAS").service("ManagerHelperService",["$q","$timeout","ErrorService","RegionConnection",function($q,$timeout,ErrorService,RegionConnection){this.loadManager=function(scope,manager){var defer=$q.defer(),self=this;return manager._scopes.indexOf(scope)>-1?($timeout(function(){defer.resolve(manager)}),defer.promise):(RegionConnection.defaultConnect().then(function(){if("notify"===manager._type)manager.isLoaded()?$timeout(function(){manager._scopes.push(scope),defer.resolve(manager)}):manager.loadItems().then(function(){manager._scopes.push(scope),defer.resolve(manager)},function(error){ErrorService.raiseError(error)}),manager.enableAutoReload(),scope.$on("$destroy",function(){self.unloadManager(scope,manager)});else{if("poll"!==manager._type)throw new Error("Unknown manager type: "+manager._type);manager.isPolling()?$timeout(function(){manager._scopes.push(scope),defer.resolve(manager)}):manager.startPolling().then(function(){manager._scopes.push(scope),defer.resolve(manager)},function(error){ErrorService.raiseError(error)}),scope.$on("$destroy",function(){self.unloadManager(scope,manager)})}}),defer.promise)},this.loadManagers=function(scope,managers){var defer=$q.defer(),loadedManagers=[],self=this;return angular.forEach(managers,function(manager){self.loadManager(scope,manager).then(function(loadedManager){loadedManagers.push(loadedManager),loadedManagers.length===managers.length&&defer.resolve(managers)})}),defer.promise},this.unloadManager=function(scope,manager){var idx=manager._scopes.indexOf(scope);idx>-1&&manager._scopes.splice(idx,1),"poll"===manager._type&&0===manager._scopes.length&&manager.stopPolling()},this.unloadManagers=function(scope,managers){var self=this;angular.forEach(managers,function(manager){self.unloadManager(scope,manager)})},this.tryParsingJSON=function(string){var error,left,right;try{error=JSON.parse(string)}catch(e){if(left=e,null!=(right=SyntaxError)&&"undefined"!=typeof Symbol&&right[Symbol.hasInstance]?right[Symbol.hasInstance](left):left instanceof right)return string;throw e}return error},this.getPrintableString=function(dict,showNames){var result="";return angular.forEach(dict,function(value,key){var error=dict[key];!0===showNames&&(result+=key+": "),angular.isString(error)||angular.isNumber(error)?result+=error+" ":angular.isObject(error)&&angular.forEach(error,function(error){result+=error+" "}),result=result.trim()+"\n"}),result.trim()},this.parseValidationError=function(error,showNames){return error=this.tryParsingJSON(error),angular.isObject(error)?this.getPrintableString(error,showNames):error}}])},"./src/maasserver/static/js/angular/services/pollingmanager.js":function(module,exports){angular.module("MAAS").factory("PollingManager",["$q","$timeout","RegionConnection","Manager",function($q,$timeout,RegionConnection,Manager){function PollingManager(){Manager.call(this),this._type="poll",this._polling=!1,this._nextPromise=null,this._pollTimeout=1e4,this._pollErrorTimeout=3e3,this._pollEmptyTimeout=3e3}return PollingManager.prototype=new Manager,PollingManager.prototype.isPolling=function(){return this._polling},PollingManager.prototype.startPolling=function(){return this._polling?this._nextPromise:(this._polling=!0,this._poll())},PollingManager.prototype.stopPolling=function(){this._polling=!1,angular.isObject(this._nextPromise)&&($timeout.cancel(this._nextPromise),this._nextPromise=null)},PollingManager.prototype._pollAgain=function(timeout){var self=this;return this._nextPromise=$timeout(function(){self._poll()},timeout),this._nextPromise},PollingManager.prototype._poll=function(){var self=this;return this.reloadItems().then(function(items){var pollTimeout=self._pollTimeout;return 0===items.length&&(pollTimeout=self._pollEmptyTimeout),self._pollAgain(pollTimeout),items},function(error){return self._pollAgain(self._pollErrorTimeout),$q.reject(error)})},PollingManager}])},"./src/maasserver/static/js/angular/services/search.js":function(module,exports){angular.module("MAAS").service("SearchService",function(){var emptyFilter={_:[]};this.getEmptyFilter=function(){return angular.copy(emptyFilter)},this.getSplitSearch=function(search){var terms=search.split(" "),fixedTerms=[],spanningParentheses=!1;return angular.forEach(terms,function(term,idx){if(spanningParentheses)fixedTerms[fixedTerms.length-1]+=" "+term,-1!==term.indexOf(")")&&(spanningParentheses=!1);else{fixedTerms.push(term);var startIdx=term.indexOf("(");-1!==startIdx&&-1===term.indexOf(")",startIdx)&&(spanningParentheses=!0)}}),spanningParentheses?null:fixedTerms},this.getCurrentFilters=function(search){var filters=this.getEmptyFilter();if(0===search.length)return filters;var searchTerms=this.getSplitSearch(search);return searchTerms?(angular.forEach(searchTerms,function(terms){if(1===(terms=terms.split(":")).length)-1===filters._.indexOf(terms[0])&&filters._.push(terms[0]);else{var field=terms.shift(),values=terms.join(":");if(0===(values=(values=values.replace("(","")).replace(")","")).length)return;values=values.split(","),angular.isUndefined(filters[field])&&(filters[field]=[]),angular.forEach(values,function(value){-1===filters[field].indexOf(value)&&filters[field].push(value)})}}),filters):null},this.filtersToString=function(filters){var search="";return angular.forEach(filters,function(terms,type){0!==terms.length&&"_"!==type&&(search+=type+":("+terms.join(",")+") ")}),filters._.length>0&&(search=filters._.join(" ")+" "+search),search.trim()},this._getFilterValueIndex=function(filters,type,value){var values=filters[type];return angular.isUndefined(values)?-1:values.map(function(value){return value.toLowerCase()}).indexOf(value.toLowerCase())},this.isFilterActive=function(filters,type,value,exact){var values=filters[type];return!angular.isUndefined(values)&&(angular.isUndefined(exact)&&(exact=!1),exact&&(value="="+value),-1!==this._getFilterValueIndex(filters,type,value))},this.toggleFilter=function(filters,type,value,exact){angular.isUndefined(filters[type])&&(filters[type]=[]),exact&&(value="="+value);var idx=this._getFilterValueIndex(filters,type,value);return-1===idx?filters[type].push(value):filters[type].splice(idx,1),filters};var storedFilters={};this.storeFilters=function(name,filters){storedFilters[name]=filters},this.retrieveFilters=function(name){return storedFilters[name]}})},"./src/maasserver/static/js/angular/services/validation.js":function(module,exports){angular.module("MAAS").service("ValidationService",["ConverterService",function(ConverterService){var domainnamePattern=/^([a-z\d]|[a-z\d][a-z\d-.]*[a-z\d])*$/i,hostnamePattern=/^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])*$/,macPattern=/^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$/,ipv4Pattern=new RegExp(["^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.","(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.","(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.","(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"].join(""));function cidrMatcher(one,two,size,bits){for(var part=0;bits>0;){var shift=size-bits;if(shift<0&&(shift=0),one[part]>>shift!==two[part]>>shift)return!1;bits-=size,part+=1}return!0}this.validateDomainName=function(domainname){return!(!angular.isString(domainname)||0===domainname.length||domainname.length>253)&&domainnamePattern.test(domainname)},this.validateHostname=function(hostname){return!(!angular.isString(hostname)||0===hostname.length||hostname.length>63)&&hostnamePattern.test(hostname)},this.validateMAC=function(macAddress){return!!angular.isString(macAddress)&&macPattern.test(macAddress.trim())},this.validateIPv4=function(ipAddress){return!(!angular.isString(ipAddress)||0===ipAddress.length)&&ipv4Pattern.test(ipAddress)},this.validateIPv6=function(ipAddress){if(!angular.isString(ipAddress)||0===ipAddress.length||-1===ipAddress.indexOf(":"))return!1;var i,expandedAddress=ConverterService.ipv6Expand(ipAddress),octets=ConverterService.ipv6ToGroups(expandedAddress);if(8!==octets.length)return!1;for(i=0;i<8;i++)if(isNaN(octets[i])||octets[i]<0||octets[i]>65535)return!1;return!(octets[0]<1||65280===octets[0]||65152===octets[0])},this.validateIP=function(ipAddress){return this.validateIPv4(ipAddress)||this.validateIPv6(ipAddress)},this.validateIPInNetwork=function(ipAddress,network){var networkSplit=network.split("/"),networkAddress=networkSplit[0],cidrBits=parseInt(networkSplit[1],10);return this.validateIPv4(ipAddress)&&this.validateIPv4(networkAddress)?cidrMatcher(ConverterService.ipv4ToOctets(ipAddress),ConverterService.ipv4ToOctets(networkAddress),8,cidrBits):!(!this.validateIPv6(ipAddress)||!this.validateIPv6(networkAddress))&&cidrMatcher(ConverterService.ipv6ToGroups(ipAddress),ConverterService.ipv6ToGroups(networkAddress),16,cidrBits)},this.validateIPInRange=function(ipAddress,network,lowAddress,highAddress){if(!this.validateIPInNetwork(ipAddress,network))return!1;var i,ipOctets,lowOctets,highOctets;if(this.validateIPv4(ipAddress)&&this.validateIPv4(lowAddress)&&this.validateIPv4(highAddress)){for(ipOctets=ConverterService.ipv4ToOctets(ipAddress),lowOctets=ConverterService.ipv4ToOctets(lowAddress),highOctets=ConverterService.ipv4ToOctets(highAddress),i=0;i<4;i++)if(ipOctets[i]>highOctets[i]||ipOctets[i]<lowOctets[i])return!1;return!0}if(this.validateIPv6(ipAddress)&&this.validateIPv6(lowAddress)&&this.validateIPv6(highAddress)){for(ipOctets=ConverterService.ipv6ToGroups(ipAddress),lowOctets=ConverterService.ipv6ToGroups(lowAddress),highOctets=ConverterService.ipv6ToGroups(highAddress),i=0;i<8;i++)if(ipOctets[i]>highOctets[i]||ipOctets[i]<lowOctets[i])return!1;return!0}return!1}}])},1:function(module,exports,__webpack_require__){__webpack_require__("./src/maasserver/static/js/angular/maas.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/add_device.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/add_domain.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/add_hardware.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/dashboard.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/domain_details.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/domains_list.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/fabric_details.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/images.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/intro_user.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/intro.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/networks_list.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/node_details_networking.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/node_details_storage_filesystems.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/node_details_storage.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/node_details.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/node_events.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/node_result.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/node_results.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/nodes_list.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/pod_details.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/pods_list.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/prefs.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/settings.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/space_details.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/subnet_details.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/vlan_details.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/zone_details.js"),__webpack_require__("./src/maasserver/static/js/angular/controllers/zones_list.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/accordion.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/boot_images.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/call_to_action.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/card_loader.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/code_lines.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/contenteditable.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/controller_image_status.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/controller_status.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/dbl_click_overlay.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/default_os_select.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/enter_blur.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/enter.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/error_overlay.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/error_toggle.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/ipranges.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/login.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/maas_obj_form.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/mac_address.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/machines_table.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/navigation_dropdown.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/navigation_mobile.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/notifications.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/os_select.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/placeholder.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/pod_parameters.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/power_parameters.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/pref_keys.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/proxy_settings.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/release_name.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/release_options.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/script_expander.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/script_results_list.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/script_runtime.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/script_select.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/script_status.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/ssh_keys.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/switches_table.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/toggle_control.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/type.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/version_reloader.js"),__webpack_require__("./src/maasserver/static/js/angular/directives/window_width.js"),__webpack_require__("./src/maasserver/static/js/angular/filters/by_fabric.js"),__webpack_require__("./src/maasserver/static/js/angular/filters/by_space.js"),__webpack_require__("./src/maasserver/static/js/angular/filters/by_subnet.js"),__webpack_require__("./src/maasserver/static/js/angular/filters/by_vlan.js"),__webpack_require__("./src/maasserver/static/js/angular/filters/nodes.js"),__webpack_require__("./src/maasserver/static/js/angular/filters/order_by_date.js"),__webpack_require__("./src/maasserver/static/js/angular/filters/remove_default_vlan.js"),__webpack_require__("./src/maasserver/static/js/angular/services/browser.js"),__webpack_require__("./src/maasserver/static/js/angular/services/converter.js"),__webpack_require__("./src/maasserver/static/js/angular/services/error.js"),__webpack_require__("./src/maasserver/static/js/angular/services/json.js"),__webpack_require__("./src/maasserver/static/js/angular/services/log.js"),__webpack_require__("./src/maasserver/static/js/angular/services/manager.js"),__webpack_require__("./src/maasserver/static/js/angular/services/managerhelper.js"),__webpack_require__("./src/maasserver/static/js/angular/services/pollingmanager.js"),__webpack_require__("./src/maasserver/static/js/angular/services/search.js"),__webpack_require__("./src/maasserver/static/js/angular/services/validation.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/bootresources.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/configs.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/controllers.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/devices.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/dhcpsnippets.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/discoveries.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/domains.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/events.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/fabrics.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/general.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/ipranges.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/machines.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/node_results.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/nodes.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/notifications.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/packagerepositories.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/pods.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/region.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/resourcepools.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/scripts.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/services.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/spaces.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/sshkeys.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/staticroutes.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/subnets.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/switches.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/tags.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/users.js"),__webpack_require__("./src/maasserver/static/js/angular/factories/vlans.js"),module.exports=__webpack_require__("./src/maasserver/static/js/angular/factories/zones.js")}});
21+!function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={i:moduleId,l:!1,exports:{}};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.l=!0,module.exports}__webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.d=function(exports,name,getter){__webpack_require__.o(exports,name)||Object.defineProperty(exports,name,{configurable:!1,enumerable:!0,get:getter})},__webpack_require__.r=function(exports){Object.defineProperty(exports,"__esModule",{value:!0})},__webpack_require__.n=function(module){var getter=module&&module.__esModule?function(){return module.default}:function(){return module};return __webpack_require__.d(getter,"a",getter),getter},__webpack_require__.o=function(object,property){return Object.prototype.hasOwnProperty.call(object,property)},__webpack_require__.p="",__webpack_require__(__webpack_require__.s=1)}({"./src/maasserver/static/js/angular/controllers/add_device.js":function(module,exports){angular.module("MAAS").controller("AddDeviceController",["$scope","DevicesManager","SubnetsManager","DomainsManager","ManagerHelperService","ValidationService",function($scope,DevicesManager,SubnetsManager,DomainsManager,ManagerHelperService,ValidationService){function newDevice(cloneDevice){return angular.isObject(cloneDevice)?{name:"",domain:cloneDevice.domain,interfaces:[{mac:"",ipAssignment:null,subnetId:null,ipAddress:""}]}:{name:"",domain:DomainsManager.getDefaultDomain(),interfaces:[{mac:"",ipAssignment:null,subnetId:null,ipAddress:""}]}}$scope.$parent.addDeviceScope=$scope,$scope.subnets=SubnetsManager.getItems(),$scope.domains=DomainsManager.getItems(),$scope.viewable=!1,$scope.error=null,$scope.ipAssignments=[{name:"external",title:"External"},{name:"dynamic",title:"Dynamic"},{name:"static",title:"Static"}],$scope.device=null,$scope.show=function(){$scope.viewable||ManagerHelperService.loadManagers($scope,[SubnetsManager,DomainsManager]).then(function(){$scope.device=newDevice($scope.device),$scope.viewable=!0})},$scope.hide=function(){$scope.viewable=!1,ManagerHelperService.unloadManagers($scope,[SubnetsManager,DomainsManager]),$scope.$emit("addDeviceHidden")},$scope.nameHasError=function(){return null!==$scope.device&&0!==$scope.device.name.length&&!ValidationService.validateHostname($scope.device.name)},$scope.macHasError=function(deviceInterface){if(0===deviceInterface.mac.length)return!1;if(!ValidationService.validateMAC(deviceInterface.mac))return!0;var i;for(i=0;i<$scope.device.interfaces.length;i++){if(!($scope.device.interfaces[i]===deviceInterface)&&$scope.device.interfaces[i].mac===deviceInterface.mac)return!0}return!1},$scope.ipHasError=function(deviceInterface){if(0===deviceInterface.ipAddress.length)return!1;if(!ValidationService.validateIP(deviceInterface.ipAddress))return!0;var i;if(angular.isObject(deviceInterface.ipAssignment))if("external"===deviceInterface.ipAssignment.name){for(i=0;i<$scope.subnets.length;i++)if(ValidationService.validateIPInNetwork(deviceInterface.ipAddress,$scope.subnets[i].cidr))return!0}else if("static"===deviceInterface.ipAssignment.name&&angular.isNumber(deviceInterface.subnetId)){var subnet=SubnetsManager.getItemFromList(deviceInterface.subnetId);if(!ValidationService.validateIPInNetwork(deviceInterface.ipAddress,subnet.cidr))return!0}return!1},$scope.deviceHasError=function(){if(null===$scope.device||""===$scope.device.name||$scope.nameHasError())return!0;var i;for(i=0;i<$scope.device.interfaces.length;i++){var deviceInterface=$scope.device.interfaces[i];if(""===deviceInterface.mac||$scope.macHasError(deviceInterface)||!angular.isObject(deviceInterface.ipAssignment))return!0;var externalIpError="external"===deviceInterface.ipAssignment.name&&(""===deviceInterface.ipAddress||$scope.ipHasError(deviceInterface)),staticIpError="static"===deviceInterface.ipAssignment.name&&(!angular.isNumber(deviceInterface.subnetId)||$scope.ipHasError(deviceInterface));if(externalIpError||staticIpError)return!0}return!1},$scope.addInterface=function(){$scope.device.interfaces.push({mac:"",ipAssignment:null,subnetId:null,ipAddress:""})},$scope.isPrimaryInterface=function(deviceInterface){return 0===$scope.device.interfaces.indexOf(deviceInterface)},$scope.deleteInterface=function(deviceInterface){$scope.isPrimaryInterface(deviceInterface)||$scope.device.interfaces.splice($scope.device.interfaces.indexOf(deviceInterface),1)},$scope.cancel=function(){$scope.error=null,$scope.device=newDevice(),$scope.hide()},$scope.save=function(addAnother){if(!$scope.deviceHasError()){$scope.error=null;var device=function(device){var i,convertedDevice={hostname:device.name,domain:device.domain,primary_mac:device.interfaces[0].mac,extra_macs:[],interfaces:[]};for(i=1;i<device.interfaces.length;i++)convertedDevice.extra_macs.push(device.interfaces[i].mac);return angular.forEach(device.interfaces,function(nic){convertedDevice.interfaces.push({mac:nic.mac,ip_assignment:nic.ipAssignment.name,ip_address:nic.ipAddress,subnet:nic.subnetId})}),convertedDevice}($scope.device);DevicesManager.create(device).then(function(device){addAnother?$scope.device=newDevice($scope.device):($scope.device=newDevice(),$scope.hide())},function(error){$scope.error=ManagerHelperService.parseValidationError(error)})}}}])},"./src/maasserver/static/js/angular/controllers/add_domain.js":function(module,exports){angular.module("MAAS").controller("AddDomainController",["$scope","DomainsManager","ManagerHelperService","ValidationService",function($scope,DomainsManager,ManagerHelperService,ValidationService){$scope.$parent.addDomainScope=$scope,$scope.viewable=!1,$scope.error=null,$scope.domain={name:"",authoritative:!0},$scope.show=function(){$scope.viewable||($scope.domain={name:"",authoritative:!0},$scope.viewable=!0)},$scope.hide=function(){$scope.viewable=!1,$scope.$emit("addDomainHidden")},$scope.nameHasError=function(){return 0!==$scope.domain.name.length&&!ValidationService.validateDomainName($scope.domain.name)},$scope.domainHasError=function(){return!(""!==$scope.domain.name&&!$scope.nameHasError())},$scope.cancel=function(){$scope.error=null,$scope.domain={name:"",authoritative:!0},$scope.hide()},$scope.save=function(addAnother){if(!$scope.domainHasError()){$scope.error=null;var domain=function(domain){return angular.copy(domain)}($scope.domain);DomainsManager.create(domain).then(function(){$scope.domain={name:"",authoritative:!0},addAnother||$scope.hide()},function(error){$scope.error=ManagerHelperService.parseValidationError(error)})}}}])},"./src/maasserver/static/js/angular/controllers/add_hardware.js":function(module,exports){angular.module("MAAS").controller("AddHardwareController",["$q","$scope","$http","ZonesManager","ResourcePoolsManager","MachinesManager","GeneralManager","DomainsManager","RegionConnection","ManagerHelperService","ValidationService",function($q,$scope,$http,ZonesManager,ResourcePoolsManager,MachinesManager,GeneralManager,DomainsManager,RegionConnection,ManagerHelperService,ValidationService){$scope.$parent.addHardwareScope=$scope,$scope.viewable=!1,$scope.model="machine",$scope.zones=ZonesManager.getItems(),$scope.pools=ResourcePoolsManager.getItems(),$scope.domains=DomainsManager.getItems(),$scope.architectures=GeneralManager.getData("architectures"),$scope.hwe_kernels=GeneralManager.getData("hwe_kernels"),$scope.default_min_hwe_kernel=GeneralManager.getData("default_min_hwe_kernel"),$scope.power_types=GeneralManager.getData("power_types"),$scope.error=null,$scope.macAddressRegex=/^([0-9A-F]{2}[::]){5}([0-9A-F]{2})$/gim,$scope.machine=null,$scope.chassis=null;var virshFields=[{name:"hostname",label:"Address",field_type:"string",default:"",choices:[],required:!0},{name:"password",label:"Password",field_type:"string",default:"",choices:[],required:!1},{name:"prefix_filter",label:"Prefix filter",field_type:"string",default:"",choices:[],required:!1}];function defaultArchitecture(){if(0===$scope.architectures.length)return"";var i;for(i=0;i<$scope.architectures.length;i++)if("amd64/generic"===$scope.architectures[i])return $scope.architectures[i];return $scope.architectures[0]}function newMachine(cloneMachine){return angular.isObject(cloneMachine)?{name:"",domain:cloneMachine.domain,macs:[{mac:"",error:!1}],zone:cloneMachine.zone,pool:cloneMachine.pool,architecture:cloneMachine.architecture,min_hwe_kernel:cloneMachine.min_hwe_kernel,power:{type:cloneMachine.power.type,parameters:{}}}:{name:"",domain:DomainsManager.getDefaultDomain(),macs:[{mac:"",error:!1}],zone:0===$scope.zones.length?null:$scope.zones[0],pool:0===$scope.pools.length?null:$scope.pools[0],architecture:defaultArchitecture(),min_hwe_kernel:$scope.default_min_hwe_kernel.text,power:{type:null,parameters:{}}}}function newChassis(cloneChassis){return angular.isObject(cloneChassis)?{domain:cloneChassis.domain,power:{type:null,parameters:{}}}:{domain:DomainsManager.getDefaultDomain(),power:{type:null,parameters:{}}}}$scope.chassisPowerTypes=[{name:"mscm",description:"Moonshot Chassis Manager",fields:[{name:"hostname",label:"Host",field_type:"string",default:"",choices:[],required:!0},{name:"username",label:"Username",field_type:"string",default:"",choices:[],required:!0},{name:"password",label:"Password",field_type:"string",default:"",choices:[],required:!0}]},{name:"powerkvm",description:"PowerKVM",fields:virshFields},{name:"recs_box",description:"Christmann RECS|Box",fields:[{name:"hostname",label:"Hostname",field_type:"string",default:"",choices:[],required:!0},{name:"port",label:"Port",field_type:"string",default:"80",choices:[],required:!1},{name:"username",label:"Username",field_type:"string",default:"",choices:[],required:!0},{name:"password",label:"Password",field_type:"string",default:"",choices:[],required:!0}]},{name:"seamicro15k",description:"SeaMicro 15000",fields:[{name:"hostname",label:"Hostname",field_type:"string",default:"",choices:[],required:!0},{name:"username",label:"Username",field_type:"string",default:"",choices:[],required:!0},{name:"password",label:"Password",field_type:"string",default:"",choices:[],required:!0},{name:"power_control",label:"Power Control",field_type:"choice",default:"restapi2",choices:[["restapi2","REST API V2.0"],["restapi","REST API V0.9"],["ipmi","IPMI"]],required:!0}]},{name:"ucsm",description:"UCS Chassis Manager",fields:[{name:"hostname",label:"URL",field_type:"string",default:"",choices:[],required:!0},{name:"username",label:"Username",field_type:"string",default:"",choices:[],required:!0},{name:"password",label:"Password",field_type:"string",default:"",choices:[],required:!0}]},{name:"virsh",description:"Virsh (virtual systems)",fields:virshFields},{name:"vmware",description:"VMware",fields:[{name:"hostname",label:"Host",field_type:"string",default:"",choices:[],required:!0},{name:"username",label:"Username",field_type:"string",default:"",choices:[],required:!0},{name:"password",label:"Password",field_type:"string",default:"",choices:[],required:!0},{name:"prefix_filter",label:"Prefix filter",field_type:"string",default:"",choices:[],required:!1}]}],$scope.show=function(mode){if(!$scope.viewable){$scope.mode=mode;var loadedItems=!1,loadedManagers=!1,defer=$q.defer();defer.promise.then(function(){$scope.machine=newMachine($scope.machine),$scope.chassis=newChassis($scope.chassis),$scope.error=null,angular.isObject($scope.machine)&&""===$scope.machine.architecture&&($scope.machine.architecture=defaultArchitecture()),$scope.viewable=!0}),GeneralManager.loadItems(["architectures","hwe_kernels","default_min_hwe_kernel"]).then(function(){loadedItems=!0,loadedManagers&&defer.resolve()}),ManagerHelperService.loadManagers($scope,[ZonesManager,DomainsManager]).then(function(){loadedManagers=!0,loadedItems&&defer.resolve()})}},$scope.hide=function(){$scope.viewable=!1,ManagerHelperService.unloadManagers($scope,[ZonesManager,DomainsManager]),$scope.$emit("addHardwareHidden")},$scope.showMachine=function(){return 0!==$scope.architectures.length&&"machine"===$scope.mode},$scope.showChassis=function(){return 0!==$scope.architectures.length&&"chassis"===$scope.mode},$scope.addMac=function(){$scope.machine.macs.push({mac:"",error:!1})},$scope.removeMac=function(mac){var idx=$scope.machine.macs.indexOf(mac);idx>-1&&$scope.machine.macs.splice(idx,1)},$scope.invalidName=function(){return 0!==$scope.machine.name.length&&!ValidationService.validateHostname($scope.machine.name)},$scope.validateMac=function(mac){""===mac.mac?mac.error=!1:mac.error=!ValidationService.validateMAC(mac.mac)},$scope.machineHasError=function(){if(in_error=null===$scope.machine||null===$scope.machine.zone||null===$scope.machine.pool||""===$scope.machine.architecture||null===$scope.machine.power.type||$scope.invalidName($scope.machine),in_error)return in_error;if(""===$scope.machine.macs[0].mac||$scope.machine.macs[0].error)return!0;var i;for(i=1;i<$scope.machine.macs.length;i++){var mac=$scope.machine.macs[i];if(""!==mac.mac&&mac.error)return!0}return!1},$scope.chassisHasErrors=function(){return in_error=null===$scope.chassis||null===$scope.chassis.power.type,in_error||function(power_type,parameters){var i;for(i=0;i<power_type.fields.length;i++){var field=power_type.fields[i],value=parameters[field.name];if(field.required&&(angular.isUndefined(value)||""===value))return!0}return!1}($scope.chassis.power.type,$scope.chassis.power.parameters)},$scope.cancel=function(){$scope.error=null,$scope.machine=newMachine(),$scope.chassis=newChassis(),$scope.hide()},$scope.saveMachine=function(addAnother){var machine,macs,pxe_mac,extra_macs;$scope.machineHasError()||($scope.error=null,MachinesManager.create((machine=$scope.machine,macs=angular.copy(machine.macs),pxe_mac=macs.shift().mac,extra_macs=macs.map(function(mac){return mac.mac}),{hostname:machine.name,domain:machine.domain,architecture:machine.architecture,min_hwe_kernel:machine.min_hwe_kernel,pxe_mac:pxe_mac,extra_macs:extra_macs,power_type:machine.power.type.name,power_parameters:angular.copy(machine.power.parameters),zone:{id:machine.zone.id,name:machine.zone.name},pool:{id:machine.pool.id,name:machine.pool.name}})).then(function(){addAnother?$scope.machine=newMachine($scope.machine):($scope.machine=newMachine(),$scope.hide())},function(error){$scope.error=ManagerHelperService.parseValidationError(error)}))},$scope.saveChassis=function(addAnother){if(!$scope.chassisHasErrors()){$scope.error=null;var params=angular.copy($scope.chassis.power.parameters);params.chassis_type=$scope.chassis.power.type.name,params.domain=$scope.chassis.domain.name,"powerkvm"!==params.chassis_type&&"virsh"!==params.chassis_type||delete params.username,$http({method:"POST",url:"api/2.0/machines/?op=add_chassis",data:$.param(params),headers:{"Content-Type":"application/x-www-form-urlencoded"}}).then(function(){addAnother?$scope.chassis=newChassis($scope.chassis):($scope.chassis=newChassis(),$scope.hide())},function(error){$scope.error=ManagerHelperService.parseValidationError(error.data)})}}}])},"./src/maasserver/static/js/angular/controllers/dashboard.js":function(module,exports){angular.module("MAAS").controller("DashboardController",["$scope","$window","$rootScope","$routeParams","$location","DiscoveriesManager","DomainsManager","MachinesManager","DevicesManager","SubnetsManager","VLANsManager","ConfigsManager","ManagerHelperService",function($scope,$window,$rootScope,$routeParams,$location,DiscoveriesManager,DomainsManager,MachinesManager,DevicesManager,SubnetsManager,VLANsManager,ConfigsManager,ManagerHelperService){var deviceIPOptions=[["static","Static"],["dynamic","Dynamic"],["external","External"]];$rootScope.title="Dashboard",$rootScope.page="dashboard",$scope.loaded=!1,$scope.discoveredDevices=DiscoveriesManager.getItems(),$scope.domains=DomainsManager.getItems(),$scope.machines=MachinesManager.getItems(),$scope.devices=DevicesManager.getItems(),$scope.configManager=ConfigsManager,$scope.networkDiscovery=null,$scope.column="mac",$scope.selectedDevice=null,$scope.convertTo=null,$scope.predicate=$scope.last_seen,$scope.sortTable=function(predicate){$scope.predicate=predicate,$scope.reverse=!$scope.reverse},$scope.proxyManager={updateItem:function(params){if("device"===$scope.convertTo.type)return DevicesManager.createItem(params);if("interface"===$scope.convertTo.type)return DevicesManager.createInterface(params);throw new Error("Unknown type: "+$scope.convertTo.type)}},$scope.getDiscoveryName=function(discovery){return null===discovery.hostname?"unknown":discovery.hostname},$scope.getSubnetName=function(subnetId){var subnet=SubnetsManager.getItemFromList(subnetId);return SubnetsManager.getName(subnet)},$scope.getVLANName=function(vlanId){var vlan=VLANsManager.getItemFromList(vlanId);return VLANsManager.getName(vlan)},$scope.toggleSelected=function(deviceId){if($scope.selectedDevice===deviceId)$scope.selectedDevice=null;else{var domain,discovered=DiscoveriesManager.getItemFromList(deviceId),hostname=$scope.getDiscoveryName(discovered);"unknown"===hostname&&(hostname=""),hostname.indexOf(".")>0?(domain=DomainsManager.getDomainByName(hostname.slice(hostname.indexOf(".")+1)),hostname=hostname.split(".",1)[0],null===domain&&(domain=DomainsManager.getDefaultDomain())):domain=DomainsManager.getDefaultDomain(),$scope.convertTo={type:"device",hostname:hostname,domain:domain,parent:null,ip_assignment:"dynamic",goTo:!1,saved:!1,deviceIPOptions:deviceIPOptions.filter(function(option){return!("static"===option[0]&&!angular.isNumber(discovered.subnet))})},$scope.selectedDevice=deviceId}},$scope.preProcess=function(item){var discovered=DiscoveriesManager.getItemFromList($scope.selectedDevice);return item=angular.copy(item),"device"===$scope.convertTo.type?(item.primary_mac=discovered.mac_address,item.extra_macs=[],item.interfaces=[{mac:discovered.mac_address,ip_assignment:item.ip_assignment,ip_address:discovered.ip,subnet:discovered.subnet}]):"interface"===$scope.convertTo.type&&(item.mac_address=discovered.mac_address,item.ip_address=discovered.ip,item.subnet=discovered.subnet),item},$scope.afterSave=function(obj){DiscoveriesManager._removeItem($scope.selectedDevice),$scope.selectedDevice=null,$scope.convertTo.hostname=obj.hostname,$scope.convertTo.parent=obj.parent,$scope.convertTo.saved=!0,$scope.convertTo.goTo&&(angular.isString(obj.parent)?$location.path("/device/"+obj.parent):$location.path("/devices/"))},ManagerHelperService.loadManagers($scope,[DiscoveriesManager,DomainsManager,MachinesManager,DevicesManager,SubnetsManager,VLANsManager,ConfigsManager]).then(function(){$scope.loaded=!0,$scope.networkDiscovery=ConfigsManager.getItemFromList("network_discovery")})}])},"./src/maasserver/static/js/angular/controllers/domain_details.js":function(module,exports){angular.module("MAAS").controller("DomainDetailsController",["$scope","$rootScope","$routeParams","$location","DomainsManager","UsersManager","ManagerHelperService","ErrorService",function($scope,$rootScope,$routeParams,$location,DomainsManager,UsersManager,ManagerHelperService,ErrorService){function domainLoaded(domain){$scope.domain=domain,$scope.loaded=!0,$rootScope.title=$scope.domain.displayname}$rootScope.title="Loading...",$rootScope.page="domains",$scope.loaded=!1,$scope.domain=null,$scope.editSummary=!1,$scope.predicate="name",$scope.reverse=!1,$scope.action=null,$scope.editRow=null,$scope.deleteRow=null,$scope.domainsManager=DomainsManager,$scope.newObject={},$scope.supportedRecordTypes=["A","AAAA","CNAME","MX","NS","SRV","SSHFP","TXT"],$scope.predicate="name",$scope.sortTable=function(predicate){$scope.predicate=predicate,$scope.reverse=!$scope.reverse},$scope.enterEditSummary=function(){$scope.editSummary=!0},$scope.exitEditSummary=function(){$scope.editSummary=!1},$scope.isRecordAutogenerated=function(row){return!row.dnsresource_id},$scope.editRecord=function(row){$scope.editRow=row,row.previous_rrdata=row.rrdata,row.previous_rrtype=row.rrtype,row.previous_name=row.name,row.previous_ttl=row.ttl,$scope.deleteRow=null},$scope.removeRecord=function(row){$scope.deleteRow=row,$scope.editRow=null},$scope.confirmRemoveRecord=function(row){row.domain=$scope.domain.id,$scope.domainsManager.deleteDNSRecord(row),$scope.stopEditingRow()},$scope.stopEditingRow=function(){$scope.editRow=null,$scope.deleteRow=null},$scope.isSuperUser=function(){return UsersManager.isSuperUser()},$scope.isDefaultDomain=function(){return!!angular.isObject($scope.domain)&&0===$scope.domain.id},$scope.canBeDeleted=function(){return!!angular.isObject($scope.domain)&&0===$scope.domain.rrsets.length},$scope.deleteButton=function(){$scope.error=null,$scope.actionInProgress=!0,$scope.action="delete"},$scope.addRecordButton=function(){$scope.error=null,$scope.actionInProgress=!0,$scope.action="add_record"},$scope.cancelAction=function(){$scope.actionInProgress=!1},$scope.deleteConfirmButton=function(){DomainsManager.deleteDomain($scope.domain).then(function(){$scope.actionInProgress=!1,$location.path("/domains")},function(error){$scope.error=ManagerHelperService.parseValidationError(error)})},ManagerHelperService.loadManagers($scope,[DomainsManager,UsersManager]).then(function(){var activeDomain=DomainsManager.getActiveItem(),requestedDomain=parseInt($routeParams.domain_id,10);isNaN(requestedDomain)?ErrorService.raiseError("Invalid domain identifier."):angular.isObject(activeDomain)&&activeDomain.id===requestedDomain?domainLoaded(activeDomain):DomainsManager.setActiveItem(requestedDomain).then(function(domain){domainLoaded(domain)},function(error){ErrorService.raiseError(error)})})}])},"./src/maasserver/static/js/angular/controllers/domains_list.js":function(module,exports){angular.module("MAAS").controller("DomainsListController",["$scope","$rootScope","$routeParams","$filter","DomainsManager","UsersManager","ManagerHelperService",function($scope,$rootScope,$routeParams,$filter,DomainsManager,UsersManager,ManagerHelperService){$rootScope.title="DNS",$rootScope.page="domains",$scope.domains=DomainsManager.getItems(),$scope.currentpage="domains",$scope.predicate="name",$scope.reverse=!1,$scope.loading=!0,$scope.addDomainScope=null,$scope.addDomain=function(){$scope.addDomainScope.show()},$scope.cancelAddDomain=function(){$scope.addDomainScope.cancel()},$scope.isSuperUser=function(){return UsersManager.isSuperUser()},ManagerHelperService.loadManagers($scope,[DomainsManager,UsersManager]).then(function(){$scope.loading=!1})}])},"./src/maasserver/static/js/angular/controllers/fabric_details.js":function(module,exports){angular.module("MAAS").controller("FabricDetailsController",["$scope","$rootScope","$routeParams","$filter","$location","FabricsManager","VLANsManager","SubnetsManager","SpacesManager","ControllersManager","UsersManager","ManagerHelperService","ErrorService",function($scope,$rootScope,$routeParams,$filter,$location,FabricsManager,VLANsManager,SubnetsManager,SpacesManager,ControllersManager,UsersManager,ManagerHelperService,ErrorService){function fabricLoaded(fabric){angular.isObject(fabric)&&($scope.fabric=fabric,$rootScope.title=$scope.fabric.name,$scope.$watch("vlans",updateVLANs,!0),$scope.$watch("subnets",updateVLANs,!0),$scope.$watch("controllers",updateVLANs,!0),$scope.loaded=!0,$scope.predicate="['vlan_name', 'vlan.id', 'subnet_name']")}function updateVLANs(){var rows=[],racks={};angular.forEach($filter("filter")($scope.vlans,{fabric:$scope.fabric.id},!0),function(vlan){var subnets=$filter("filter")($scope.subnets,{vlan:vlan.id},!0);if(subnets.length>0)angular.forEach(subnets,function(subnet){var space=SpacesManager.getItemFromList(subnet.space),space_name=null===space?"(undefined)":space.name,row={vlan:vlan,vlan_name:VLANsManager.getName(vlan),subnet:subnet,subnet_name:SubnetsManager.getName(subnet),space:space,space_name:space_name};rows.push(row)});else{var row={vlan:vlan,vlan_name:VLANsManager.getName(vlan),subnet:null,subnet_name:null,space:null,space_name:null};rows.push(row)}angular.forEach(vlan.rack_sids,function(rack_sid){var rack=ControllersManager.getItemFromList(rack_sid);angular.isObject(rack)&&(racks[rack.system_id]=rack)})}),$scope.rows=rows,$scope.racks=Object.keys(racks).map(function(key){return racks[key]})}$rootScope.title="Loading...",$rootScope.page="networks",$scope.fabric=null,$scope.fabricManager=FabricsManager,$scope.editSummary=!1,$scope.vlans=VLANsManager.getItems(),$scope.subnets=SubnetsManager.getItems(),$scope.controllers=ControllersManager.getItems(),$scope.loaded=!1,$scope.enterEditSummary=function(){$scope.editSummary=!0},$scope.exitEditSummary=function(){$scope.editSummary=!1},$scope.isSuperUser=function(){return UsersManager.isSuperUser()},$scope.isDefaultFabric=function(){return!!angular.isObject($scope.fabric)&&0===$scope.fabric.id},$scope.canBeDeleted=function(){return!!angular.isObject($scope.fabric)&&0!==$scope.fabric.id},$scope.deleteButton=function(){$scope.error=null,$scope.confirmingDelete=!0},$scope.cancelDeleteButton=function(){$scope.confirmingDelete=!1},$scope.deleteConfirmButton=function(){FabricsManager.deleteFabric($scope.fabric).then(function(){$scope.confirmingDelete=!1,$location.path("/networks"),$location.search("by","fabric")},function(reply){$scope.error=ManagerHelperService.parseValidationError(reply.error)})},ManagerHelperService.loadManagers($scope,[FabricsManager,VLANsManager,SubnetsManager,SpacesManager,ControllersManager,UsersManager]).then(function(){var activeFabric=FabricsManager.getActiveItem(),requestedFabric=parseInt($routeParams.fabric_id,10);isNaN(requestedFabric)?ErrorService.raiseError("Invalid fabric identifier."):angular.isObject(activeFabric)&&activeFabric.id===requestedFabric?fabricLoaded(activeFabric):FabricsManager.setActiveItem(requestedFabric).then(function(fabric){fabricLoaded(fabric)},function(error){ErrorService.raiseError(error)})})}])},"./src/maasserver/static/js/angular/controllers/images.js":function(module,exports){angular.module("MAAS").controller("ImagesController",["$rootScope","$scope","BootResourcesManager","ConfigsManager","UsersManager","ManagerHelperService",function($rootScope,$scope,BootResourcesManager,ConfigsManager,UsersManager,ManagerHelperService){$rootScope.page="images",$rootScope.title="Loading...",$scope.loading=!0,$scope.bootResources=BootResourcesManager.getData(),$scope.configManager=ConfigsManager,$scope.autoImport=null,$scope.isSuperUser=function(){return UsersManager.isSuperUser()},ManagerHelperService.loadManagers($scope,[ConfigsManager,UsersManager]).then(function(){$scope.autoImport=ConfigsManager.getItemFromList("boot_images_auto_import")}),$scope.$watch("bootResources.resources",function(){angular.isArray($scope.bootResources.resources)&&($scope.loading=!1,$rootScope.title="Images")})}])},"./src/maasserver/static/js/angular/controllers/intro.js":function(module,exports){angular.module("MAAS").controller("IntroController",["$rootScope","$scope","$window","$location","ConfigsManager","PackageRepositoriesManager","BootResourcesManager","ManagerHelperService",function($rootScope,$scope,$window,$location,ConfigsManager,PackageRepositoriesManager,BootResourcesManager,ManagerHelperService){if($rootScope.page="intro",$rootScope.title="Welcome",$scope.loading=!0,$scope.configManager=ConfigsManager,$scope.repoManager=PackageRepositoriesManager,$scope.bootResources=BootResourcesManager.getData(),$scope.hasImages=!1,$scope.maasName=null,$scope.upstreamDNS=null,$scope.mainArchive=null,$scope.portsArchive=null,$scope.httpProxy=null,$rootScope.skip=function(){$scope.clickContinue(!0)},$scope.welcomeInError=function(){var form=$scope.maasName.$maasForm;return!!angular.isObject(form)&&form.hasErrors()},$scope.networkInError=function(){var inError=!1,objs=[$scope.upstreamDNS,$scope.mainArchive,$scope.portsArchive,$scope.httpProxy];return angular.forEach(objs,function(obj){var form=obj.$maasForm;angular.isObject(form)&&form.hasErrors()&&(inError=!0)}),inError},$scope.canContinue=function(){return!$scope.welcomeInError()&&!$scope.networkInError()&&$scope.hasImages},$scope.clickContinue=function(force){angular.isUndefined(force)&&(force=!1),(force||$scope.canContinue())&&ConfigsManager.updateItem({name:"completed_intro",value:!0}).then(function(){$window.location.reload()})},MAAS_config.completed_intro)$location.path("/");else{var managers=[ConfigsManager,PackageRepositoriesManager];ManagerHelperService.loadManagers($scope,managers).then(function(){$scope.loading=!1,$scope.maasName=ConfigsManager.getItemFromList("maas_name"),$scope.upstreamDNS=ConfigsManager.getItemFromList("upstream_dns"),$scope.httpProxy=ConfigsManager.getItemFromList("http_proxy"),$scope.mainArchive=PackageRepositoriesManager.getItems().filter(function(repo){return repo.default&&"main_archive"===repo.name})[0],$scope.portsArchive=PackageRepositoriesManager.getItems().filter(function(repo){return repo.default&&"ports_archive"===repo.name})[0]}),$scope.$watch("bootResources.resources",function(){angular.isArray($scope.bootResources.resources)&&$scope.bootResources.resources.length>0?$scope.hasImages=!0:$scope.hasImages=!1})}}])},"./src/maasserver/static/js/angular/controllers/intro_user.js":function(module,exports){angular.module("MAAS").controller("IntroUserController",["$rootScope","$scope","$window","$location","UsersManager","ManagerHelperService",function($rootScope,$scope,$window,$location,UsersManager,ManagerHelperService){$rootScope.page="intro",$rootScope.title="Welcome",$scope.loading=!0,$scope.user=null,$rootScope.skip=function(){$scope.clickContinue(!0)},$scope.isSuperUser=function(){return UsersManager.isSuperUser()},$scope.canContinue=function(){return $scope.user.sshkeys_count>0},$scope.clickContinue=function(force){angular.isUndefined(force)&&(force=!1),(force||$scope.canContinue())&&UsersManager.markIntroComplete().then(function(){$window.location.reload()})},MAAS_config.user_completed_intro?$location.path("/"):ManagerHelperService.loadManager($scope,UsersManager).then(function(){$scope.loading=!1,$scope.user=UsersManager.getAuthUser()})}])},"./src/maasserver/static/js/angular/controllers/networks_list.js":function(module,exports){angular.module("MAAS").controller("NetworksListController",["$scope","$rootScope","$routeParams","$filter","$location","SubnetsManager","FabricsManager","SpacesManager","VLANsManager","UsersManager","ManagerHelperService",function($scope,$rootScope,$routeParams,$filter,$location,SubnetsManager,FabricsManager,SpacesManager,VLANsManager,UsersManager,ManagerHelperService){var filterByVLAN=$filter("filterByVLAN"),filterByFabric=$filter("filterByFabric"),filterBySpace=$filter("filterBySpace"),filterByNullSpace=$filter("filterByNullSpace");$rootScope.title="Subnets",$rootScope.page="networks",$scope.getURLParameters=function(){angular.isString($location.search().by)?$scope.groupBy=$location.search().by:$scope.groupBy="fabric"},$scope.ADD_FABRIC_ACTION={name:"add_fabric",title:"Fabric",selectedTitle:"Add fabric",objectName:"fabric"},$scope.ADD_VLAN_ACTION={name:"add_vlan",title:"VLAN",selectedTitle:"Add VLAN",objectName:"vlan"},$scope.ADD_SPACE_ACTION={name:"add_space",title:"Space",selectedTitle:"Add space",objectName:"space"},$scope.ADD_SUBNET_ACTION={name:"add_subnet",title:"Subnet",selectedTitle:"Add subnet",objectName:"subnet"},$scope.getURLParameters(),$scope.subnetManager=SubnetsManager,$scope.subnets=SubnetsManager.getItems(),$scope.fabricManager=FabricsManager,$scope.fabrics=FabricsManager.getItems(),$scope.spaceManager=SpacesManager,$scope.spaces=SpacesManager.getItems(),$scope.vlanManager=VLANsManager,$scope.vlans=VLANsManager.getItems(),$scope.loading=!0,$scope.group={},$scope.group.fabrics={},$scope.group.spaces={},$scope.group.spaces.orphanVLANs=[];var actionObjectInitializers={fabric:function(){return{}},vlan:function(){return{fabric:$scope.fabrics[0].id}},space:function(){return{}},subnet:function(){return{vlan:$scope.fabrics[0].vlan_ids[0]}}};function getSubnetName(subnet){return SubnetsManager.getName(subnet)}$scope.updateGroupBy=function(){var rows,spaces,previous_space;"space"===$scope.groupBy?($location.search("by","space"),rows=[],spaces=$filter("orderBy")($scope.spaces,["name"]),previous_space={id:-1},angular.forEach(spaces,function(space){var subnets=filterBySpace($scope.subnets,space);subnets=$filter("orderBy")(subnets,["cidr"]);var index=0;angular.forEach(subnets,function(subnet){index++;var vlan=VLANsManager.getItemFromList(subnet.vlan),row={fabric:FabricsManager.getItemFromList(vlan.fabric),vlan:vlan,vlan_name:$scope.getVLANName(vlan),subnet:subnet,subnet_name:getSubnetName(subnet),space:space,space_name:""};space.id!==previous_space.id&&(previous_space.id=space.id,row.space_name=space.name),rows.push(row)}),0===index&&rows.push({space:space,space_name:space.name})}),$scope.group.spaces.rows=rows,function(){var rows=[],subnets=filterByNullSpace($scope.subnets);subnets=$filter("orderBy")(subnets,["cidr"]),angular.forEach(subnets,function(subnet){var vlan=VLANsManager.getItemFromList(subnet.vlan),row={fabric:FabricsManager.getItemFromList(vlan.fabric),vlan:vlan,vlan_name:$scope.getVLANName(vlan),subnet:subnet,subnet_name:getSubnetName(subnet),space:null};rows.push(row)}),$scope.group.spaces.orphanVLANs=rows}()):($location.search("by","fabric"),function(){var rows=[],previous_fabric={id:-1},previous_vlan={id:-1},fabrics=$filter("orderBy")($scope.fabrics,["name"]);angular.forEach(fabrics,function(fabric){var vlans=filterByFabric($scope.vlans,fabric);vlans=$filter("orderBy")(vlans,["vid"]),angular.forEach(vlans,function(vlan){var subnets=filterByVLAN($scope.subnets,vlan);if(subnets.length>0)angular.forEach(subnets,function(subnet){var space=SpacesManager.getItemFromList(subnet.space),row={fabric:fabric,fabric_name:"",vlan:vlan,vlan_name:"",space:space,subnet:subnet,subnet_name:getSubnetName(subnet)};fabric.id!==previous_fabric.id&&(previous_fabric.id=fabric.id,row.fabric_name=fabric.name),vlan.id!==previous_vlan.id&&(previous_vlan.id=vlan.id,row.vlan_name=$scope.getVLANName(vlan)),rows.push(row)});else{var row={fabric:fabric,fabric_name:"",vlan:vlan,vlan_name:$scope.getVLANName(vlan)};fabric.id!==previous_fabric.id&&(previous_fabric.id=fabric.id,row.fabric_name=fabric.name),rows.push(row)}})}),$scope.group.fabrics.rows=rows}())},$scope.updateActions=function(){UsersManager.isSuperUser()?$scope.actionOptions=[$scope.ADD_FABRIC_ACTION,$scope.ADD_VLAN_ACTION,$scope.ADD_SPACE_ACTION,$scope.ADD_SUBNET_ACTION]:$scope.actionOptions=[]},$scope.actionChanged=function(){$scope.newObject=actionObjectInitializers[$scope.actionOption.objectName]()},$scope.cancelAction=function(){$scope.actionOption=null,$scope.newObject=null},$scope.getVLANName=function(vlan){return VLANsManager.getName(vlan)},$scope.getFabricNameById=function(fabricId){return FabricsManager.getName(FabricsManager.getItemFromList(fabricId))},$scope.actionSubnetPreSave=function(obj){return obj.fabric=VLANsManager.getItemFromList(obj.vlan).fabric,obj},ManagerHelperService.loadManagers($scope,[SubnetsManager,FabricsManager,SpacesManager,VLANsManager,UsersManager]).then(function(){$scope.loading=!1,$scope.updateActions(),$scope.$watch("[subnets, fabrics, spaces, vlans]",$scope.updateGroupBy,!0),$scope.$on("$routeUpdate",function(){$scope.getURLParameters(),$scope.updateGroupBy()}),$scope.updateGroupBy()})}])},"./src/maasserver/static/js/angular/controllers/node_details.js":function(module,exports){angular.module("MAAS").controller("NodeDetailsController",["$scope","$rootScope","$routeParams","$location","$interval","DevicesManager","MachinesManager","ControllersManager","ZonesManager","GeneralManager","UsersManager","TagsManager","DomainsManager","ManagerHelperService","ServicesManager","ErrorService","ValidationService","ScriptsManager","ResourcePoolsManager",function($scope,$rootScope,$routeParams,$location,$interval,DevicesManager,MachinesManager,ControllersManager,ZonesManager,GeneralManager,UsersManager,TagsManager,DomainsManager,ManagerHelperService,ServicesManager,ErrorService,ValidationService,ScriptsManager,ResourcePoolsManager){var page_managers,DEVICE_IP_ASSIGNMENT={external:"External",dynamic:"Dynamic",static:"Static"};function updateTitle(){$scope.node&&$scope.node.fqdn&&($rootScope.title=$scope.node.fqdn)}function updateHeader(){var i;if(!$scope.header.editing&&!$scope.header.editing_domain)for($scope.header.hostname.value=$scope.node.fqdn,i=0;i<$scope.header.domain.options.length;i++){var option=$scope.header.domain.options[i];if(option.id===$scope.node.domain.id){$scope.header.domain.selected=option;break}}}function updateAvailableActionOptions(){if(angular.isObject($scope.node)){var actionTypeForNodeType={0:"machine_actions",1:"device_actions",2:"rack_controller_actions",3:"region_controller_actions",4:"region_and_rack_controller_actions"};if(GeneralManager.isDataLoaded(actionTypeForNodeType[$scope.node.node_type]))$scope.action.allOptions=GeneralManager.getData(actionTypeForNodeType[$scope.node.node_type]),$scope.action.availableOptions.length=0,angular.forEach($scope.action.allOptions,function(option){$scope.node.actions.indexOf(option.name)>=0&&"set-zone"!==option.name&&"set-pool"!==option.name&&$scope.action.availableOptions.push(option)});else{GeneralManager.loadItems([actionTypeForNodeType[$scope.node.node_type]]).then(updateAvailableActionOptions)}}}function updatePower(){if(!$scope.power.editing){var i;for($scope.power.type=null,i=0;i<$scope.power_types.length;i++)if($scope.node.power_type===$scope.power_types[i].name){$scope.power.type=$scope.power_types[i];break}$scope.power.bmc_node_count=$scope.node.power_bmc_node_count,$scope.power.parameters=angular.copy($scope.node.power_parameters),angular.isObject($scope.power.parameters)||($scope.power.parameters={}),$scope.canEdit()&&""===$scope.node.power_type&&0===$scope.node.node_type&&($scope.power.editing=!0),$scope.power.in_pod=angular.isDefined($scope.node.pod)}}function updateSummary(){$scope.summary.editing||(angular.isObject($scope.node.zone)&&($scope.summary.zone.selected=ZonesManager.getItemFromList($scope.node.zone.id)),angular.isObject($scope.node.pool)&&($scope.summary.pool.selected=ResourcePoolsManager.getItemFromList($scope.node.pool.id)),$scope.summary.architecture.selected=$scope.node.architecture,$scope.summary.min_hwe_kernel.selected=$scope.node.min_hwe_kernel,$scope.summary.tags=angular.copy($scope.node.tags),$scope.canEdit()&&$scope.hasUsableArchitectures()&&$scope.hasInvalidArchitecture()&&($scope.summary.editing=!0))}function updateServices(){$scope.isController&&($scope.services={},angular.forEach(ControllersManager.getServices($scope.node),function(service){$scope.services[service.name]=service}))}function updateDevices(){$scope.devices=[],angular.forEach($scope.node.devices,function(child){var device={name:child.fqdn};angular.isArray(child.interfaces)&&child.interfaces.length>0?angular.forEach(child.interfaces,function(nic,nicIdx){var deviceWithMAC=angular.copy(device);deviceWithMAC.mac_address=nic.mac_address,nicIdx>0&&(deviceWithMAC.name=""),angular.isArray(nic.links)&&nic.links.length>0?angular.forEach(nic.links,function(link,lIdx){var deviceWithLink=angular.copy(deviceWithMAC);deviceWithLink.ip_address=link.ip_address,lIdx>0&&(deviceWithLink.mac_address=""),$scope.devices.push(deviceWithLink)}):$scope.devices.push(deviceWithMAC)}):$scope.devices.push(device)})}function nodeLoaded(node){$scope.node=node,$scope.loaded=!0,updateTitle(),updateSummary(),updateServices(),$scope.$watch("node.fqdn",function(){updateTitle(),updateHeader()}),$scope.$watch("node.devices",updateDevices),$scope.$watch("node.actions",updateAvailableActionOptions),$scope.$watch("node.architecture",updateSummary),$scope.$watchCollection($scope.summary.architecture.options,updateSummary),$scope.$watch("node.min_hwe_kernel",updateSummary),$scope.$watchCollection($scope.summary.min_hwe_kernel.options,updateSummary),$scope.$watch("node.zone.id",updateSummary),$scope.$watchCollection($scope.summary.zone.options,updateSummary),$scope.$watch("node.pool.id",updateSummary),$scope.$watchCollection($scope.summary.pool.options,updateSummary),$scope.$watch("node.power_type",updatePower),$scope.$watch("node.power_parameters",updatePower),$scope.$watchCollection("power_types",updatePower),$scope.$watch("node.service_ids",updateServices),angular.isObject($scope.storageController)&&$scope.storageController.nodeLoaded(),angular.isObject($scope.networkingController)&&$scope.networkingController.nodeLoaded()}$rootScope.title="Loading...",$scope.MAAS_config=MAAS_config,$scope.loaded=!1,$scope.node=null,$scope.action={option:null,allOptions:null,availableOptions:[],error:null,showing_confirmation:!1},$scope.power_types=GeneralManager.getData("power_types"),$scope.osinfo=GeneralManager.getData("osinfo"),$scope.section={area:angular.isString($routeParams.area)?$routeParams.area:"summary"},$scope.osSelection={osystem:null,release:null,hwe_kernel:null},$scope.commissionOptions={enableSSH:!1,skipNetworking:!1,skipStorage:!1,updateFirmware:!1,configureHBA:!1},$scope.commissioningSelection=[],$scope.testSelection=[],$scope.releaseOptions={},$scope.checkingPower=!1,$scope.devices=[],$scope.scripts=ScriptsManager.getItems(),$scope.header={editing:!1,editing_domain:!1,hostname:{value:""},domain:{selected:null,options:DomainsManager.getItems()}},$scope.summary={editing:!1,architecture:{selected:null,options:GeneralManager.getData("architectures")},min_hwe_kernel:{selected:null,options:GeneralManager.getData("min_hwe_kernels")},zone:{selected:null,options:ZonesManager.getItems()},pool:{selected:null,options:ResourcePoolsManager.getItems()},tags:[]},$scope.services={},$scope.power={editing:!1,type:null,bmc_node_count:0,parameters:{},in_pod:!1},$scope.getDeviceIPAssignment=function(ipAssignment){return DEVICE_IP_ASSIGNMENT[ipAssignment]},$scope.events={limit:10},$scope.updateNode=function(node,queryPower){return angular.isUndefined(queryPower)&&(queryPower=!1),$scope.nodesManager.updateItem(node).then(function(node){updateHeader(),updateSummary(),queryPower&&$scope.checkPowerState()},function(error){console.log(error),updateHeader(),updateSummary()})},$scope.tagsAutocomplete=function(query){return TagsManager.autocomplete(query)},$scope.getPowerStateClass=function(){return angular.isObject($scope.node)?$scope.checkingPower?"checking":$scope.node.power_state:""},$scope.getPowerStateText=function(){return angular.isObject($scope.node)?$scope.checkingPower?"Checking power":"unknown"===$scope.node.power_state?"":"Power "+$scope.node.power_state:""},$scope.canCheckPowerState=function(){return!!angular.isObject($scope.node)&&("unknown"!==$scope.node.power_state&&!$scope.checkingPower)},$scope.checkPowerState=function(){$scope.checkingPower=!0,$scope.nodesManager.checkPowerState($scope.node).then(function(){$scope.checkingPower=!1})},$scope.isUbuntuOS=function(){return!!angular.isObject($scope.node)&&"ubuntu"===$scope.node.osystem},$scope.isUbuntuCoreOS=function(){return!!angular.isObject($scope.node)&&"ubuntu-core"===$scope.node.osystem},$scope.isCustomOS=function(){return!!angular.isObject($scope.node)&&"custom"===$scope.node.osystem},$scope.isActionError=function(){return null!==$scope.action.error},$scope.isDeployError=function(){if($scope.isActionError())return!1;var missing_osinfo=angular.isUndefined($scope.osinfo.osystems)||0===$scope.osinfo.osystems.length;return!(!angular.isObject($scope.action.option)||"deploy"!==$scope.action.option.name||!missing_osinfo)},$scope.isSSHKeyError=function(){return!$scope.isActionError()&&!(!angular.isObject($scope.action.option)||"deploy"!==$scope.action.option.name||0!==UsersManager.getSSHKeyCount())},$scope.action.optionChanged=function(){$scope.action.error=null,$scope.action.showing_confirmation=!1},$scope.actionCancel=function(){$scope.action.option=null,$scope.action.error=null,$scope.action.showing_confirmation=!1},$scope.actionGo=function(){var i,extra={};if("deploy"===$scope.action.option.name&&angular.isString($scope.osSelection.osystem)&&angular.isString($scope.osSelection.release)){extra.osystem=$scope.osSelection.osystem;var release=$scope.osSelection.release;release=(release=release.split("/"))[release.length-1],extra.distro_series=release,angular.isString($scope.osSelection.hwe_kernel)&&($scope.osSelection.hwe_kernel.indexOf("hwe-")>=0||$scope.osSelection.hwe_kernel.indexOf("ga-")>=0)&&(extra.hwe_kernel=$scope.osSelection.hwe_kernel)}else if("commission"===$scope.action.option.name){for(extra.enable_ssh=$scope.commissionOptions.enableSSH,extra.skip_networking=$scope.commissionOptions.skipNetworking,extra.skip_storage=$scope.commissionOptions.skipStorage,extra.commissioning_scripts=[],i=0;i<$scope.commissioningSelection.length;i++)extra.commissioning_scripts.push($scope.commissioningSelection[i].id);for($scope.commissionOptions.updateFirmware&&extra.commissioning_scripts.push("update_firmware"),$scope.commissionOptions.configureHBA&&extra.commissioning_scripts.push("configure_hba"),0===extra.commissioning_scripts.length&&extra.commissioning_scripts.push("none"),extra.testing_scripts=[],i=0;i<$scope.testSelection.length;i++)extra.testing_scripts.push($scope.testSelection[i].id);0===extra.testing_scripts.length&&extra.testing_scripts.push("none")}else if("test"===$scope.action.option.name){if(6===$scope.node.status_code&&!$scope.action.showing_confirmation)return void($scope.action.showing_confirmation=!0);for(extra.enable_ssh=$scope.commissionOptions.enableSSH,extra.testing_scripts=[],i=0;i<$scope.testSelection.length;i++)extra.testing_scripts.push($scope.testSelection[i].id);0===extra.testing_scripts.length&&extra.testing_scripts.push("none")}else"release"===$scope.action.option.name&&(extra.erase=$scope.releaseOptions.erase,extra.secure_erase=$scope.releaseOptions.secureErase,extra.quick_erase=$scope.releaseOptions.quickErase);$scope.nodesManager.performAction($scope.node,$scope.action.option.name,extra).then(function(){"delete"===$scope.action.option.name&&$location.path("/machines"),$scope.action.option=null,$scope.action.error=null,$scope.action.showing_confirmation=!1,$scope.osSelection.$reset(),$scope.commissionOptions.enableSSH=!1,$scope.commissionOptions.skipNetworking=!1,$scope.commissionOptions.skipStorage=!1,$scope.commissionOptions.updateFirmware=!1,$scope.commissionOptions.configureHBA=!1,$scope.commissioningSelection=[],$scope.testSelection=[]},function(error){$scope.action.error=error})},$scope.isSuperUser=function(){return UsersManager.isSuperUser()},$scope.hasUsableArchitectures=function(){return $scope.summary.architecture.options.length>0},$scope.getArchitecturePlaceholder=function(){return $scope.hasUsableArchitectures()?"Choose an architecture":"-- No usable architectures --"},$scope.hasInvalidArchitecture=function(){return!!angular.isObject($scope.node)&&(!$scope.isDevice&&(""===$scope.node.architecture||-1===$scope.summary.architecture.options.indexOf($scope.node.architecture)))},$scope.invalidArchitecture=function(){return!($scope.isDevice||$scope.isController||""!==$scope.summary.architecture.selected&&-1!==$scope.summary.architecture.options.indexOf($scope.summary.architecture.selected))},$scope.isRackControllerConnected=function(){return $scope.power_types.length>0},$scope.isLocked=function(){return null!==$scope.node&&$scope.node.locked},$scope.canEdit=function(){return!!$scope.isDevice||$scope.isRackControllerConnected()&&$scope.isSuperUser()&&!$scope.isLocked()},$scope.editHeaderDomain=function(){$scope.canEdit()||$scope.header.editing_domain||($scope.header.editing=!1,$scope.header.editing_domain=!0,$scope.header.hostname.value=$scope.node.hostname)},$scope.editHeader=function(){$scope.canEdit()&&($scope.header.editing||($scope.header.editing=!0,$scope.header.editing_domain=!1,$scope.header.hostname.value=$scope.node.hostname))},$scope.editHeaderInvalid=function(){if(!$scope.header.editing&&!$scope.header.editing_domain)return!1;var value=$scope.header.hostname.value;return 0===value.length||!ValidationService.validateHostname(value)},$scope.cancelEditHeader=function(){$scope.header.editing=!1,$scope.header.editing_domain=!1,updateHeader()},$scope.saveEditHeader=function(){if(!$scope.editHeaderInvalid()){$scope.header.editing=!1,$scope.header.editing_domain=!1;var node=angular.copy($scope.node);node.hostname=$scope.header.hostname.value,node.domain=$scope.header.domain.selected,$scope.updateNode(node)}},$scope.editSummary=function(){$scope.canEdit()&&($scope.summary.editing=!0)},$scope.cancelEditSummary=function(){$scope.isDevice||$scope.isController?$scope.summary.editing=!1:$scope.hasInvalidArchitecture()||($scope.summary.editing=!1),updateSummary()},$scope.saveEditSummary=function(){if(!$scope.invalidArchitecture()){$scope.summary.editing=!1;var node=angular.copy($scope.node);node.zone=angular.copy($scope.summary.zone.selected),node.pool=angular.copy($scope.summary.pool.selected),node.architecture=$scope.summary.architecture.selected,null===$scope.summary.min_hwe_kernel.selected?node.min_hwe_kernel="":node.min_hwe_kernel=$scope.summary.min_hwe_kernel.selected,node.tags=[],angular.forEach($scope.summary.tags,function(tag){node.tags.push(tag.text)}),$scope.updateNode(node)}},$scope.invalidPowerType=function(){return!angular.isObject($scope.power.type)},$scope.editPower=function(){$scope.canEdit()&&($scope.power.editing=!0)},$scope.cancelEditPower=function(){0===$scope.node.node_type&&""===$scope.node.power_type||($scope.power.editing=!1),updatePower()},$scope.saveEditPower=function(){if(!$scope.invalidPowerType()){$scope.power.editing=!1;var node=angular.copy($scope.node);node.power_type=$scope.power.type.name,node.power_parameters=angular.copy($scope.power.parameters),$scope.updateNode(node,!0)}},$scope.allowShowMoreEvents=function(){return!!angular.isObject($scope.node)&&(!!angular.isArray($scope.node.events)&&($scope.node.events.length>0&&$scope.node.events.length>$scope.events.limit&&$scope.events.limit<50))},$scope.showMoreEvents=function(){$scope.events.limit+=10},$scope.getEventText=function(event){var text=event.type.description;return angular.isString(event.description)&&event.description.length>0&&(text+=" - "+event.description),text},$scope.getPowerEventError=function(){var i;if(angular.isObject($scope.node)&&angular.isArray($scope.node.events))for(i=0;i<$scope.node.events.length;i++){var event=$scope.node.events[i];if("warning"===event.type.level&&"Failed to query node's BMC"===event.type.description)return event;if("info"===event.type.level&&"Queried node's BMC"===event.type.description)return}},$scope.hasPowerEventError=function(){var event=$scope.getPowerEventError();return angular.isObject(event)},$scope.getPowerEventErrorText=function(){var event=$scope.getPowerEventError();return angular.isObject(event)?event.description:""},$scope.hasActionPowerError=function(actionName){if(!$scope.hasPowerError())return!1;return!!(actionName&&["commission","deploy","on","off","release"].indexOf(actionName)>-1)},$scope.hasPowerError=function(){return!!angular.isObject($scope.power.type)&&$scope.power.type.missing_packages.length>0},$scope.getPowerErrors=function(){var i,result="";if(angular.isObject($scope.power.type)){var packages=$scope.power.type.missing_packages;for(packages.sort(),i=0;i<packages.length;i++)result+=packages[i],i+2<packages.length?result+=", ":i+1<packages.length&&(result+=" and ");result+=packages.length>1?" packages":" package"}return result},$scope.getServiceClass=function(service){return angular.isObject(service)?"running"===service.status?"success":"dead"===service.status?"error":"degraded"===service.status?"warning":"none":"none"},$scope.hasCustomCommissioningScripts=function(){var i;for(i=0;i<$scope.scripts.length;i++)if(0===$scope.scripts[i].script_type)return!0;return!1},$scope.controllerLoaded=function(name,scope){$scope[name]=scope,angular.isObject(scope.node)&&scope.nodeLoaded()},$scope.showFailedTestWarning=function(){if(1===$scope.node.node_type||!$scope.node.status_code)return!1;switch($scope.node.status_code){case 0:case 1:case 2:case 21:case 22:return!1}switch($scope.node.testing_status){case-1:case 2:return!1}return!0},$scope.getCPUSubtext=function(){var label=$scope.node.cpu_count+" cores";return $scope.node.cpu_speed&&0!==$scope.node.cpu_speed?$scope.node.cpu_speed<1e3?label+" @ "+$scope.node.cpu_speed+" Mhz":label+" @ "+$scope.node.cpu_speed/1e3+" Ghz":label},$scope.$on("$routeUpdate",function(){GeneralManager.loadItems(["osinfo","architectures","min_hwe_kernels"])}),-1!==$location.path().indexOf("/controller")?($scope.nodesManager=ControllersManager,page_managers=[ControllersManager,ScriptsManager],$scope.isController=!0,$scope.isDevice=!1,$scope.type_name="controller",$scope.type_name_title="Controller",$rootScope.page="controllers"):-1!==$location.path().indexOf("/device")?($scope.nodesManager=DevicesManager,page_managers=[DevicesManager],$scope.isController=!1,$scope.isDevice=!0,$scope.type_name="device",$scope.type_name_title="Device",$rootScope.page="devices"):($scope.nodesManager=MachinesManager,page_managers=[MachinesManager,ScriptsManager],$scope.isController=!1,$scope.isDevice=!1,$scope.type_name="machine",$scope.type_name_title="Machine",$rootScope.page="machines"),ManagerHelperService.loadManagers($scope,[ZonesManager,GeneralManager,UsersManager,TagsManager,DomainsManager,ServicesManager,ResourcePoolsManager].concat(page_managers)).then(function(){var activeNode=$scope.nodesManager.getActiveItem();angular.isObject(activeNode)&&activeNode.system_id===$routeParams.system_id?nodeLoaded(activeNode):($scope.nodesManager.setActiveItem($routeParams.system_id).then(function(node){nodeLoaded(node)},function(error){ErrorService.raiseError(error)}),activeNode=$scope.nodesManager.getActiveItem()),$scope.isDevice&&($scope.ip_assignment=activeNode.ip_assignment)})}])},"./src/maasserver/static/js/angular/controllers/node_details_networking.js":function(module,exports){angular.module("MAAS").filter("filterByUnusedForInterface",function(){return function(vlans,nic,originalInterfaces){var filtered=[];if(!angular.isObject(nic)||!angular.isObject(originalInterfaces))return filtered;var usedVLANs=[];return angular.forEach(originalInterfaces,function(inter){"vlan"===inter.type&&(inter.parents[0]===nic.id&&usedVLANs.push(inter.vlan_id))}),angular.forEach(vlans,function(vlan){-1===usedVLANs.indexOf(vlan.id)&&filtered.push(vlan)}),filtered}}),angular.module("MAAS").filter("removeInterfaceParents",function(){return function(interfaces,childInterface,skip){if(skip||!angular.isObject(childInterface)||!angular.isArray(childInterface.parents))return interfaces;var filtered=[];return angular.forEach(interfaces,function(nic){var i,parent,found=!1;for(i=0;i<childInterface.parents.length;i++)if((parent=childInterface.parents[i]).id===nic.id&&parent.link_id===nic.link_id){found=!0;break}found||filtered.push(nic)}),filtered}}),angular.module("MAAS").filter("removeDefaultVLANIfVLAN",function(){return function(vlans,interfaceType){if(!angular.isString(interfaceType))return vlans;var filtered=[];return angular.forEach(vlans,function(vlan){"vlan"!==interfaceType?filtered.push(vlan):0!==vlan.vid&&filtered.push(vlan)}),filtered}}),angular.module("MAAS").filter("filterLinkModes",function(){return function(modes,nic){if(!angular.isObject(nic))return modes;var filtered=[];if(angular.isFunction(nic.getValue)||(nic.getValue=function(name){return this[name]}),angular.isObject(nic.getValue("subnet"))){var links=nic.getValue("links"),nicType=nic.getValue("type"),allowLinkUp=angular.isObject(links)&&links.length>1||"alias"===nicType;angular.forEach(modes,function(mode){allowLinkUp&&"link_up"===mode.mode||"alias"===nicType&&"dhcp"===mode.mode||filtered.push(mode)})}else angular.forEach(modes,function(mode){"link_up"===mode.mode&&filtered.push(mode)});return filtered}}),angular.module("MAAS").controller("NodeNetworkingController",["$scope","$filter","FabricsManager","VLANsManager","SubnetsManager","MachinesManager","ControllersManager","DevicesManager","GeneralManager","UsersManager","ManagerHelperService","ValidationService","JSONService",function($scope,$filter,FabricsManager,VLANsManager,SubnetsManager,MachinesManager,ControllersManager,DevicesManager,GeneralManager,UsersManager,ManagerHelperService,ValidationService,JSONService){var INTERFACE_TYPE={PHYSICAL:"physical",BOND:"bond",BRIDGE:"bridge",VLAN:"vlan",ALIAS:"alias"},INTERFACE_TYPE_TEXTS={physical:"Physical",bond:"Bond",bridge:"Bridge",vlan:"VLAN",alias:"Alias"},LINK_MODE={AUTO:"auto",STATIC:"static",DHCP:"dhcp",LINK_UP:"link_up"},LINK_MODE_TEXTS={auto:"Auto assign",static:"Static assign",dhcp:"DHCP",link_up:"Unconfigured"},SELECTION_MODE={NONE:null,SINGLE:"single",MULTI:"multi",DELETE:"delete",ADD:"add",CREATE_BOND:"create-bond",CREATE_BRIDGE:"create-bridge",CREATE_PHYSICAL:"create-physical",EDIT:"edit"},IP_ASSIGNMENT_DYNAMIC="dynamic",IP_ASSIGNMENT_EXTERNAL="external",IP_ASSIGNMENT_STATIC="static";function updateLoaded(){$scope.loaded=$scope.nodeHasLoaded&&$scope.managersHaveLoaded,$scope.loaded&&updateInterfaces()}function updateInterfaces(){$scope.originalInterfaces={},angular.forEach($scope.node.interfaces,function(nic){$scope.originalInterfaces[nic.id]=nic});var interfaces=[],vlanTable=[],addedVlans={};if(angular.forEach($scope.node.interfaces,function(nic){if(1===nic.children.length){var child=$scope.originalInterfaces[nic.children[0]];if(child.type===INTERFACE_TYPE.BOND||child.type===INTERFACE_TYPE.BRIDGE)return void(angular.isObject($scope.editInterface)&&$scope.editInterface.id===nic.id&&($scope.editInterface=null,$scope.selectedMode=SELECTION_MODE.NONE))}var tags,formatted;if(nic.type!==INTERFACE_TYPE.BOND&&nic.type!==INTERFACE_TYPE.BRIDGE||(nic.members=[],angular.forEach(nic.parents,function(parent){nic.members.push(angular.copy($scope.originalInterfaces[parent]))})),angular.isArray(nic.tags)&&nic.tags.length>0&&!angular.isString(nic.tags[0].text)&&(nic.tags=(tags=nic.tags,formatted=[],angular.forEach(tags,function(tag){formatted.push({text:tag})}),formatted)),nic.vlan=VLANsManager.getItemFromList(nic.vlan_id),angular.isObject(nic.vlan)&&(nic.fabric=FabricsManager.getItemFromList(nic.vlan.fabric),$scope.$parent.isController)){if(!Object.prototype.hasOwnProperty.call(addedVlans,nic.vlan.id)){addedVlans[nic.vlan.id]=!0;var vlanRecord={fabric:nic.fabric,vlan:nic.vlan,subnets:$filter("filter")($scope.subnets,{vlan:nic.vlan.id},!0),primary_rack:null,secondary_rack:null,sort_key:nic.fabric.name+"|"+$scope.getVLANText(nic.vlan)};nic.vlan.primary_rack&&(vlanRecord.primary_rack=ControllersManager.getItemFromList(nic.vlan.primary_rack)),nic.vlan.secondary_rack&&(vlanRecord.secondary_rack=ControllersManager.getItemFromList(nic.vlan.secondary_rack)),vlanTable.push(vlanRecord)}vlanTable.sort(function(a,b){return a.sort_key.localeCompare(b.sort_key)})}if(0===nic.links.length)nic.link_id=-1,nic.subnet=null,nic.mode=LINK_MODE.LINK_UP,nic.ip_address="",interfaces.push(nic);else{var idx=0;angular.forEach(nic.links,function(link){var nic_copy=angular.copy(nic);nic_copy.link_id=link.id,nic_copy.subnet=SubnetsManager.getItemFromList(link.subnet_id),nic_copy.mode=link.mode,nic_copy.ip_address=link.ip_address,angular.isUndefined(nic_copy.ip_address)&&(nic_copy.ip_address=""),nic_copy.vlan=nic.vlan,nic_copy.fabric=nic.fabric,idx>0&&(nic_copy.type=INTERFACE_TYPE.ALIAS,nic_copy.name+=":"+idx),idx++,interfaces.push(nic_copy)})}}),$scope.interfaces=interfaces,$scope.vlanTable=vlanTable,$scope.interfaceLinksMap={},angular.forEach($scope.interfaces,function(nic){var linkMaps=$scope.interfaceLinksMap[nic.id];angular.isUndefined(linkMaps)&&(linkMaps={},$scope.interfaceLinksMap[nic.id]=linkMaps),linkMaps[nic.link_id]=nic}),angular.isObject($scope.editInterface)){var links=$scope.interfaceLinksMap[$scope.editInterface.id];if(angular.isUndefined(links))$scope.editInterface=null,$scope.selectedMode=SELECTION_MODE.NONE;else{var link=links[$scope.editInterface.link_id];angular.isUndefined(link)&&($scope.editInterface=null,$scope.selectedMode=SELECTION_MODE.NONE)}}!function(){if(angular.isObject($scope.newInterface.parent)){var parentId=$scope.newInterface.parent.id,linkId=$scope.newInterface.parent.link_id,links=$scope.interfaceLinksMap[parentId];if(angular.isObject(links)){var newParent=links[linkId];if(angular.isObject(newParent)){$scope.newInterface.parent=newParent;var iType=$scope.newInterface.type,isAlias=iType===INTERFACE_TYPE.ALIAS,isVLAN=iType===INTERFACE_TYPE.VLAN,canAddAlias=$scope.canAddAlias(newParent),canAddVLAN=$scope.canAddVLAN(newParent);return void(canAddAlias||canAddVLAN?isAlias&&!canAddAlias&&canAddVLAN?($scope.newInterface.type="vlan",$scope.addTypeChanged()):isVLAN&&!canAddVLAN&&canAddAlias&&($scope.newInterface.type="alias",$scope.addTypeChanged()):($scope.newInterface={},leaveSingleSelectionMode()))}}$scope.newInterface={},leaveSingleSelectionMode()}}()}function mapNICToOriginalLink(nic_id,link_id){var originalInteface=$scope.originalInterfaces[nic_id];if(angular.isObject(originalInteface)){var i,link=null;for(i=0;i<originalInteface.links.length&&(link=originalInteface.links[i]).id!==link_id;i++);return link}return null}function leaveSingleSelectionMode(){$scope.selectedMode!==SELECTION_MODE.SINGLE&&$scope.selectedMode!==SELECTION_MODE.ADD&&$scope.selectedMode!==SELECTION_MODE.DELETE||($scope.selectedMode=SELECTION_MODE.NONE)}function getDefaultVLAN(fabric){return VLANsManager.getItemFromList(fabric.default_vlan_id)}function getUnusedVLANs(nic,ignoreVLANs){var vlans=$filter("removeDefaultVLAN")($scope.vlans);return vlans=$filter("filterByFabric")(vlans,nic.fabric),vlans=$filter("filterByUnusedForInterface")(vlans,nic,$scope.originalInterfaces),angular.isUndefined(ignoreVLANs)&&(ignoreVLANs=[]),angular.forEach(ignoreVLANs,function(vlan){var i;for(i=0;i<vlans.length;i++)if(vlans[i].id===vlan.id){vlans.splice(i,1);break}}),vlans}function getSelectedInterfaces(){var interfaces=[];return angular.forEach($scope.selectedInterfaces,function(key){var splitKey=key.split("/"),links=$scope.interfaceLinksMap[splitKey[0]];if(angular.isObject(links)){var nic=links[splitKey[1]];angular.isObject(nic)&&interfaces.push(nic)}}),interfaces}function getNextName(prefix){var idx=0;return angular.forEach($scope.originalInterfaces,function(nic){nic.name===prefix+idx&&idx++}),prefix+idx}$scope.ipAssignments=[{name:IP_ASSIGNMENT_EXTERNAL,text:"External"},{name:IP_ASSIGNMENT_DYNAMIC,text:"Dynamic"},{name:IP_ASSIGNMENT_STATIC,text:"Static"}],$scope.loaded=!1,$scope.nodeHasLoaded=!1,$scope.managersHaveLoaded=!1,$scope.tableInfo={column:"name"},$scope.fabrics=FabricsManager.getItems(),$scope.vlans=VLANsManager.getItems(),$scope.subnets=SubnetsManager.getItems(),$scope.interfaces=[],$scope.interfaceLinksMap={},$scope.interfaceErrorsByLinkId={},$scope.originalInterfaces={},$scope.selectedInterfaces=[],$scope.selectedMode=null,$scope.newInterface={},$scope.newBondInterface={},$scope.newBridgeInterface={},$scope.editInterface=null,$scope.bondOptions=GeneralManager.getData("bond_options"),$scope.modes=[{mode:LINK_MODE.AUTO,text:LINK_MODE_TEXTS[LINK_MODE.AUTO]},{mode:LINK_MODE.STATIC,text:LINK_MODE_TEXTS[LINK_MODE.STATIC]},{mode:LINK_MODE.DHCP,text:LINK_MODE_TEXTS[LINK_MODE.DHCP]},{mode:LINK_MODE.LINK_UP,text:LINK_MODE_TEXTS[LINK_MODE.LINK_UP]}],$scope.nodeLoaded=function(){$scope.$watch("node.interfaces",updateInterfaces),$scope.$parent.isController&&$scope.$watch("subnets",updateInterfaces,!0),$scope.nodeHasLoaded=!0,updateLoaded()},$scope.isLimitedEditingAllowed=function(nic){return!!$scope.isSuperUser()&&(!$scope.$parent.isController&&!$scope.$parent.isDevice&&(angular.isObject($scope.node)&&"Deployed"===$scope.node.status&&"vlan"!==nic.type))},$scope.isAllNetworkingDisabled=function(){return!$scope.isSuperUser()&&!$scope.$parent.isDevice||!$scope.$parent.isController&&!$scope.$parent.isDevice&&!(!angular.isObject($scope.node)||-1!==["New","Ready","Allocated","Broken"].indexOf($scope.node.status))},$scope.isBootInterface=function(nic){if(!angular.isObject(nic))return!1;if(nic.is_boot&&nic.type!==INTERFACE_TYPE.ALIAS)return!0;var i;if(nic.type===INTERFACE_TYPE.BOND||nic.type===INTERFACE_TYPE.BRIDGE)for(i=0;i<nic.members.length;i++)if(nic.members[i].is_boot)return!0;return!1},$scope.getInterfaceTypeText=function(nic){var text=INTERFACE_TYPE_TEXTS[nic.type];return angular.isDefined(text)?text:nic.type},$scope.getLinkModeText=function(nic){var text=LINK_MODE_TEXTS[nic.mode];return angular.isDefined(text)?text:nic.mode},$scope.getVLANText=function(vlan){return angular.isObject(vlan)?0===vlan.vid?"untagged":angular.isString(vlan.name)&&vlan.name.length>0?vlan.vid+" ("+vlan.name+")":vlan.vid:""},$scope.getSubnetText=function(subnet){return angular.isObject(subnet)?angular.isString(subnet.name)&&subnet.name.length>0&&subnet.cidr!==subnet.name?subnet.cidr+" ("+subnet.name+")":subnet.cidr:"Unconfigured"},$scope.getSubnet=function(subnetId){return SubnetsManager.getItemFromList(subnetId)},$scope.isInterfaceNameInvalid=function(nic){if(!angular.isObject(nic)||!nic.hasOwnProperty("name")||0===nic.name.length)return!0;var i;if(angular.isArray($scope.node.interfaces))for(i=0;i<$scope.node.interfaces.length;i++){var otherNic=$scope.node.interfaces[i];if(otherNic.name===nic.name&&otherNic.id!==nic.id)return!0}return!1},$scope.isLinkModeDisabled=function(nic){return angular.isFunction(nic.getValue)?!angular.isObject(nic.getValue("subnet")):!angular.isObject(nic.subnet)},$scope.getInterfaceError=function(nic){return angular.isDefined(nic.link_id)&&nic.link_id>=0?$scope.interfaceErrorsByLinkId[nic.link_id]:null},$scope.isIPAddressInvalid=function(nic){return!(!angular.isString(nic.ip_address)||"static"!==nic.mode)&&(!ValidationService.validateIP(nic.ip_address)||!ValidationService.validateIPInNetwork(nic.ip_address,nic.subnet.cidr))},$scope.getUniqueKey=function(nic){return nic.id+"/"+nic.link_id},$scope.toggleInterfaceSelect=function(nic){var key=$scope.getUniqueKey(nic),idx=$scope.selectedInterfaces.indexOf(key);idx>-1?$scope.selectedInterfaces.splice(idx,1):$scope.selectedInterfaces.push(key),$scope.selectedInterfaces.length>1?$scope.selectedMode!==SELECTION_MODE.BOND&&($scope.selectedMode=SELECTION_MODE.MULTI):1===$scope.selectedInterfaces.length?$scope.selectedMode=SELECTION_MODE.SINGLE:$scope.selectedMode=SELECTION_MODE.NONE},$scope.isInterfaceSelected=function(nic){return $scope.selectedInterfaces.indexOf($scope.getUniqueKey(nic))>-1},$scope.cannotEditInterface=function(nic){return $scope.selectedMode!==SELECTION_MODE.NONE&&($scope.selectedMode===SELECTION_MODE.MULTI||!$scope.isInterfaceSelected(nic))},$scope.isEditing=function(nic){return $scope.selectedMode===SELECTION_MODE.EDIT&&$scope.editInterface.id===nic.id},$scope.edit=function(nic){$scope.selectedInterfaces=[$scope.getUniqueKey(nic)],$scope.selectedMode=SELECTION_MODE.EDIT,$scope.$parent.isDevice?($scope.editInterface={id:nic.id,name:nic.name,mac_address:nic.mac_address,tags:nic.tags.map(function(tag){return tag.text}),subnet:nic.subnet,ip_address:nic.ip_address,ip_assignment:nic.ip_assignment,link_id:nic.link_id},void 0!==nic.subnet&&null!==nic.subnet?$scope.editInterface.defaultSubnet=nic.subnet:$scope.editInterface.defaultSubnet=$scope.subnets[0]):$scope.editInterface={id:nic.id,name:nic.name,mac_address:nic.mac_address,tags:nic.tags.map(function(tag){return tag.text}),fabric:nic.fabric,vlan:nic.vlan,subnet:nic.subnet,mode:nic.mode,ip_address:nic.ip_address,link_id:nic.link_id}},$scope.fabricChanged=function(nic){null!==nic.fabric?nic.vlan=getDefaultVLAN(nic.fabric):nic.vlan=null,$scope.vlanChanged(nic)},$scope.fabricChangedForm=function(key,value,form){var vlan;vlan=null!==value?getDefaultVLAN(value):null,form.updateValue("vlan",vlan),$scope.vlanChangedForm("vlan",vlan,form)},$scope.vlanChanged=function(nic){nic.subnet=null,$scope.subnetChanged(nic)},$scope.vlanChangedForm=function(key,value,form){form.updateValue("subnet",null),$scope.subnetChangedForm("subnet",null,form)},$scope.subnetChanged=function(nic){angular.isObject(nic.subnet)||(nic.mode=LINK_MODE.LINK_UP),$scope.$parent.isDevice&&(nic.ip_address=null),$scope.modeChanged(nic)},$scope.subnetChangedForm=function(key,value,form){angular.isObject(value)||form.updateValue("mode",LINK_MODE.LINK_UP),mode=form.getValue("mode"),form.updateValue("ip_address",null),$scope.modeChangedForm("mode",mode,form)},$scope.modeChanged=function(nic){if(nic.ip_address="","static"===nic.mode){var originalLink=mapNICToOriginalLink(nic.id,nic.link_id);angular.isObject(originalLink)&&nic.subnet.id===originalLink.subnet_id&&(nic.ip_address=originalLink.ip_address)}},$scope.modeChangedForm=function(key,value,form){if(form.updateValue("ip_address",""),"static"===value){var originalLink=mapNICToOriginalLink(form.getValue("id"),form.getValue("link_id"));angular.isObject(originalLink)&&form.getValue("subnet").id===originalLink.subnet_id&&form.updateValue("ip_address",originalLink.ip_address)}},$scope.editCancel=function(nic){$scope.selectedInterfaces=[],$scope.selectedMode=SELECTION_MODE.NONE,$scope.editInterface=null},$scope.preProcessInterface=function(nic){var params=angular.copy(nic);return delete params.id,params.system_id=$scope.node.system_id,params.interface_id=nic.id,void 0!==nic.fabric&&null!==nic.fabric?params.fabric=nic.fabric.id:params.fabric=null,void 0!==nic.vlan&&null!==nic.vlan?params.vlan=nic.vlan.id:params.vlan=null,void 0!==nic.subnet&&null!==nic.subnet?params.subnet=params.subnet.id:delete params.subnet,angular.isDefined(nic.link_id)&&nic.link_id>=0?(params.link_id=nic.link_id,delete $scope.interfaceErrorsByLinkId[nic.link_id]):delete params.link_id,(nic.mode===LINK_MODE.STATIC||nic.ip_assignment!==IP_ASSIGNMENT_DYNAMIC)&&angular.isString(nic.ip_address)&&nic.ip_address.length>0?params.ip_address=nic.ip_address:delete params.ip_address,params},$scope.saveInterface=function(nic){var params;return params=$scope.$parent.isDevice?{name:nic.name,mac_address:nic.mac_address,ip_assignment:nic.ip_assignment,ip_address:nic.ip_address}:{name:nic.name,mac_address:nic.mac_address,mode:nic.mode,tags:nic.tags.map(function(tag){return tag.text})},void 0!==nic.fabric&&null!==nic.fabric?params.fabric=nic.fabric.id:params.fabric=null,void 0!==nic.vlan&&null!==nic.vlan?params.vlan=nic.vlan.id:params.vlan=null,void 0!==nic.subnet&&null!==nic.subnet?params.subnet=nic.subnet.id:params.subnet=null,angular.isDefined(nic.link_id)&&nic.link_id>=0&&(params.link_id=nic.link_id,delete $scope.interfaceErrorsByLinkId[nic.link_id]),angular.isString(nic.ip_address)&&nic.ip_address.length>0&&(params.ip_address=nic.ip_address),$scope.$parent.nodesManager.updateInterface($scope.node,nic.id,params).then(null,function(error){console.log(error),updateInterfaces()})},$scope.saveInterfaceLink=function(nic){var params={mode:nic.mode};return $scope.$parent.isDevice&&(params.ip_assignment=nic.ip_assignment),angular.isObject(nic.subnet)&&(params.subnet=nic.subnet.id),angular.isDefined(nic.link_id)&&nic.link_id>=0&&(params.link_id=nic.link_id,delete $scope.interfaceErrorsByLinkId[nic.link_id]),nic.mode===LINK_MODE.STATIC&&angular.isString(nic.ip_address)&&nic.ip_address.length>0&&(params.ip_address=nic.ip_address),$scope.$parent.nodesManager.linkSubnet($scope.node,nic.id,params).then(null,function(error){throw console.log(error),angular.isDefined(nic.link_id)&&nic.link_id>=0&&($scope.interfaceErrorsByLinkId[nic.link_id]=error),updateInterfaces(),error})},$scope.editSave=function(editInterface){return $scope.editCancel(),editInterface},$scope.isShowingDeleteConfirm=function(){return $scope.selectedMode===SELECTION_MODE.DELETE},$scope.isShowingAdd=function(){return $scope.selectedMode===SELECTION_MODE.ADD},$scope.canAddAliasOrVLAN=function(nic){return!$scope.$parent.isController&&(!$scope.isAllNetworkingDisabled()&&($scope.canAddAlias(nic)||$scope.canAddVLAN(nic)))},$scope.canAddAlias=function(nic){return!!angular.isObject(nic)&&(nic.type!==INTERFACE_TYPE.ALIAS&&(0!==nic.links.length&&nic.links[0].mode!==LINK_MODE.LINK_UP))},$scope.canAddVLAN=function(nic){return!!angular.isObject(nic)&&(nic.type!==INTERFACE_TYPE.ALIAS&&nic.type!==INTERFACE_TYPE.VLAN&&getUnusedVLANs(nic).length>0)},$scope.canAddAnotherVLAN=function(nic){return!!$scope.canAddVLAN(nic)&&getUnusedVLANs(nic).length>1},$scope.getRemoveTypeText=function(nic){return nic.type===INTERFACE_TYPE.PHYSICAL?"interface":nic.type===INTERFACE_TYPE.VLAN?"VLAN":nic.type},$scope.canBeRemoved=function(){return!$scope.$parent.isController&&!$scope.isAllNetworkingDisabled()},$scope.remove=function(){$scope.selectedMode=SELECTION_MODE.DELETE},$scope.quickRemove=function(nic){$scope.selectedInterfaces=[$scope.getUniqueKey(nic)],$scope.remove()},$scope.cancel=function(){$scope.newInterface={},$scope.newBondInterface={},$scope.newBridgeInterface={},$scope.selectedMode===SELECTION_MODE.CREATE_BOND?$scope.selectedMode=SELECTION_MODE.MULTI:$scope.selectedMode===SELECTION_MODE.CREATE_PHYSICAL?$scope.selectedMode=SELECTION_MODE.NONE:$scope.selectedMode=SELECTION_MODE.SINGLE},$scope.confirmRemove=function(nic){$scope.selectedMode=SELECTION_MODE.NONE,$scope.selectedInterfaces=[],nic.type!==INTERFACE_TYPE.ALIAS?$scope.$parent.nodesManager.deleteInterface($scope.node,nic.id):$scope.$parent.nodesManager.unlinkSubnet($scope.node,nic.id,nic.link_id);var idx=$scope.interfaces.indexOf(nic);idx>-1&&$scope.interfaces.splice(idx,1)},$scope.add=function(type,nic){var ignoreVLANs=[];angular.isObject($scope.newInterface.vlan)&&ignoreVLANs.push($scope.newInterface.vlan);var vlans=getUnusedVLANs(nic,ignoreVLANs),defaultVLAN=null;vlans.length>0&&(defaultVLAN=vlans[0]);var defaultSubnet=null,defaultMode=LINK_MODE.LINK_UP;type===INTERFACE_TYPE.ALIAS&&(defaultVLAN=nic.vlan,defaultSubnet=$filter("filter")($scope.subnets,{vlan:defaultVLAN.id},!0)[0],defaultMode=LINK_MODE.AUTO),$scope.newInterface={type:type,vlan:defaultVLAN,subnet:defaultSubnet,mode:defaultMode,parent:nic,tags:[]},$scope.selectedMode=SELECTION_MODE.ADD},$scope.quickAdd=function(nic){$scope.selectedInterfaces=[$scope.getUniqueKey(nic)];var type="alias";$scope.canAddAlias(nic)||(type="vlan"),$scope.add(type,nic)},$scope.getAddName=function(){if($scope.newInterface.type===INTERFACE_TYPE.ALIAS){var aliasIdx=$scope.newInterface.parent.links.length;return $scope.newInterface.parent.name+":"+aliasIdx}if($scope.newInterface.type===INTERFACE_TYPE.VLAN)return $scope.newInterface.parent.name+"."+$scope.newInterface.vlan.vid},$scope.addTypeChanged=function(){if($scope.newInterface.type===INTERFACE_TYPE.ALIAS)$scope.newInterface.vlan=$scope.newInterface.parent.vlan,$scope.newInterface.subnet=$filter("filter")($scope.subnets,{vlan:$scope.newInterface.vlan.id},!0)[0],$scope.newInterface.mode=LINK_MODE.AUTO;else if($scope.newInterface.type===INTERFACE_TYPE.VLAN){var vlans=getUnusedVLANs($scope.newInterface.parent);$scope.newInterface.vlan=null,vlans.length>0&&($scope.newInterface.vlan=vlans[0]),$scope.newInterface.subnet=null,$scope.newInterface.mode=LINK_MODE.LINK_UP}},$scope.addInterface=function(type){var nic;if($scope.$parent.isDevice)nic={id:$scope.newInterface.parent.id,tags:$scope.newInterface.tags.map(function(tag){return tag.text}),ip_assignment:$scope.newInterface.ip_assignment,subnet:$scope.newInterface.subnet,ip_address:$scope.newInterface.ip_address},$scope.saveInterfaceLink(nic);else if($scope.newInterface.type===INTERFACE_TYPE.ALIAS)nic={id:$scope.newInterface.parent.id,mode:$scope.newInterface.mode,subnet:$scope.newInterface.subnet,ip_address:$scope.newInterface.ip_address},$scope.saveInterfaceLink(nic);else if($scope.newInterface.type===INTERFACE_TYPE.VLAN){var params={parent:$scope.newInterface.parent.id,vlan:$scope.newInterface.vlan.id,mode:$scope.newInterface.mode,tags:$scope.newInterface.tags.map(function(tag){return tag.text})};angular.isObject($scope.newInterface.subnet)&&(params.subnet=$scope.newInterface.subnet.id,params.ip_address=$scope.newInterface.ip_address),$scope.$parent.nodesManager.createVLANInterface($scope.node,params).then(null,function(error){console.log(error)})}angular.isString(type)?$scope.add(type,$scope.newInterface.parent):($scope.selectedMode=SELECTION_MODE.NONE,$scope.selectedInterfaces=[],$scope.newInterface={})},$scope.isDisabled=function(){return!!$scope.isAllNetworkingDisabled()||$scope.selectedMode!==SELECTION_MODE.NONE&&$scope.selectedMode!==SELECTION_MODE.SINGLE&&$scope.selectedMode!==SELECTION_MODE.MULTI},$scope.canCreateBond=function(){if($scope.selectedMode!==SELECTION_MODE.MULTI)return!1;var i,vlan,interfaces=getSelectedInterfaces();for(i=0;i<interfaces.length;i++){var nic=interfaces[i];if(nic.type===INTERFACE_TYPE.ALIAS||nic.type===INTERFACE_TYPE.BOND)return!1;if(angular.isObject(vlan)){if(vlan!==nic.vlan)return!1}else vlan=nic.vlan}return!0},$scope.isShowingCreateBond=function(){return $scope.selectedMode===SELECTION_MODE.CREATE_BOND},$scope.showCreateBond=function(){if($scope.selectedMode===SELECTION_MODE.MULTI&&$scope.canCreateBond()){$scope.selectedMode=SELECTION_MODE.CREATE_BOND;var parents=getSelectedInterfaces();$scope.newBondInterface={name:getNextName("bond"),tags:[],parents:parents,primary:parents[0],mac_address:"",mode:"active-backup",lacpRate:"slow",xmitHashPolicy:"layer2"}}},$scope.hasBootInterface=function(nic){if(!angular.isArray(nic.parents))return!1;var i;for(i=0;i<nic.parents.length;i++)if(nic.parents[i].is_boot)return!0;return!1},$scope.getInterfacePlaceholderMACAddress=function(nic){return angular.isObject(nic.primary)?nic.primary.mac_address:""},$scope.isMACAddressInvalid=function(mac_address,invalidEmpty){return angular.isUndefined(invalidEmpty)&&(invalidEmpty=!1),angular.isString(mac_address)&&""!==mac_address?!ValidationService.validateMAC(mac_address):invalidEmpty},$scope.showLACPRate=function(){return"802.3ad"===$scope.newBondInterface.mode},$scope.showXMITHashPolicy=function(){return"balance-xor"===$scope.newBondInterface.mode||"802.3ad"===$scope.newBondInterface.mode||"balance-tlb"===$scope.newBondInterface.mode},$scope.cannotAddBond=function(){return $scope.isInterfaceNameInvalid($scope.newBondInterface)||$scope.isMACAddressInvalid($scope.newBondInterface.mac_address)},$scope.addBond=function(){if(!$scope.cannotAddBond()){var parents=$scope.newBondInterface.parents.map(function(nic){return nic.id}),mac_address=$scope.newBondInterface.mac_address;""===mac_address&&(mac_address=$scope.newBondInterface.primary.mac_address);var vlan_id,vlan=$scope.newBondInterface.primary.vlan;vlan_id=angular.isObject(vlan)?vlan.id:null;var params={name:$scope.newBondInterface.name,mac_address:mac_address,tags:$scope.newBondInterface.tags.map(function(tag){return tag.text}),parents:parents,vlan:vlan_id,bond_mode:$scope.newBondInterface.mode,bond_lacp_rate:$scope.newBondInterface.lacpRate,bond_xmit_hash_policy:$scope.newBondInterface.xmitHashPolicy};$scope.$parent.nodesManager.createBondInterface($scope.node,params).then(null,function(error){console.log(error)}),angular.forEach($scope.newBondInterface.parents,function(parent){var idx=$scope.interfaces.indexOf(parent);idx>-1&&$scope.interfaces.splice(idx,1)}),$scope.newBondInterface={},$scope.selectedInterfaces=[],$scope.selectedMode=SELECTION_MODE.NONE}},$scope.canCreateBridge=function(){if($scope.selectedMode!==SELECTION_MODE.SINGLE)return!1;var nic=getSelectedInterfaces()[0];return nic.type!==INTERFACE_TYPE.ALIAS&&nic.type!==INTERFACE_TYPE.BRIDGE},$scope.isShowingCreateBridge=function(){return $scope.selectedMode===SELECTION_MODE.CREATE_BRIDGE},$scope.showCreateBridge=function(){if($scope.selectedMode===SELECTION_MODE.SINGLE&&$scope.canCreateBridge()){$scope.selectedMode=SELECTION_MODE.CREATE_BRIDGE;var parents=getSelectedInterfaces();$scope.newBridgeInterface={name:getNextName("br"),tags:[],parents:parents,primary:parents[0],mac_address:"",bridge_stp:!1,bridge_fd:15}}},$scope.cannotAddBridge=function(){return $scope.isInterfaceNameInvalid($scope.newBridgeInterface)||$scope.isMACAddressInvalid($scope.newBridgeInterface.mac_address)},$scope.addBridge=function(){if(!$scope.cannotAddBridge()){var parents=[$scope.newBridgeInterface.primary.id],mac_address=$scope.newBridgeInterface.mac_address;""===mac_address&&(mac_address=$scope.newBridgeInterface.primary.mac_address);var params={name:$scope.newBridgeInterface.name,mac_address:mac_address,tags:$scope.newBridgeInterface.tags.map(function(tag){return tag.text}),parents:parents,vlan:$scope.newBridgeInterface.primary.vlan.id,bridge_stp:$scope.newBridgeInterface.bridge_stp,bridge_fd:$scope.newBridgeInterface.bridge_fd};$scope.$parent.nodesManager.createBridgeInterface($scope.node,params).then(null,function(error){console.log(error)});var idx=$scope.interfaces.indexOf($scope.newBridgeInterface.primary);idx>-1&&$scope.interfaces.splice(idx,1),$scope.newBridgeInterface={},$scope.selectedInterfaces=[],$scope.selectedMode=SELECTION_MODE.NONE}},$scope.isShowingCreatePhysical=function(){return $scope.selectedMode===SELECTION_MODE.CREATE_PHYSICAL},$scope.showCreatePhysical=function(){$scope.selectedMode===SELECTION_MODE.NONE&&($scope.selectedMode=SELECTION_MODE.CREATE_PHYSICAL,$scope.$parent.isDevice?$scope.newInterface={name:getNextName("eth"),mac_address:"",macError:!1,tags:[],errorMsg:null,subnet:null,ip_assignment:IP_ASSIGNMENT_DYNAMIC}:$scope.newInterface={name:getNextName("eth"),mac_address:"",macError:!1,tags:[],errorMsg:null,fabric:$scope.fabrics[0],vlan:getDefaultVLAN($scope.fabrics[0]),subnet:null,mode:LINK_MODE.LINK_UP})},$scope.cannotAddPhysicalInterface=function(){return $scope.isInterfaceNameInvalid($scope.newInterface)||$scope.isMACAddressInvalid($scope.newInterface.mac_address,!0)},$scope.addPhysicalInterface=function(){var params;$scope.cannotAddPhysicalInterface()||(params=$scope.$parent.isDevice?{name:$scope.newInterface.name,mac_address:$scope.newInterface.mac_address,tags:$scope.newInterface.tags.map(function(tag){return tag.text}),ip_assignment:$scope.newInterface.ip_assignment,ip_address:$scope.newInterface.ip_address}:{name:$scope.newInterface.name,tags:$scope.newInterface.tags.map(function(tag){return tag.text}),mac_address:$scope.newInterface.mac_address,vlan:$scope.newInterface.vlan.id,mode:$scope.newInterface.mode},angular.isObject($scope.newInterface.subnet)&&(params.subnet=$scope.newInterface.subnet.id),$scope.newInterface.macError=!1,$scope.newInterface.errorMsg=null,$scope.$parent.nodesManager.createPhysicalInterface($scope.node,params).then(function(){$scope.newInterface={},$scope.selectedMode=SELECTION_MODE.NONE},function(errorStr){error=JSONService.tryParse(errorStr),angular.isObject(error)?(macError=error.mac_address,angular.isArray(macError)&&($scope.newInterface.macError=!0,$scope.newInterface.errorMsg=macError[0])):console.log(errorStr)}))},ManagerHelperService.loadManagers($scope,[FabricsManager,VLANsManager,SubnetsManager,UsersManager,ControllersManager]).then(function(){$scope.managersHaveLoaded=!0,updateLoaded()}),$scope.$parent.controllerLoaded("networkingController",$scope)}])},"./src/maasserver/static/js/angular/controllers/node_details_storage.js":function(module,exports){angular.module("MAAS").filter("removeAvailableByNew",function(){return function(disks,availableNew){if(!angular.isObject(availableNew)||!angular.isObject(availableNew.device)&&!angular.isArray(availableNew.devices))return disks;var filtered=[],single=!0;return angular.isArray(availableNew.devices)&&(single=!1),angular.forEach(disks,function(disk){if(single)disk!==availableNew.device&&filtered.push(disk);else{var i,found=!1;for(i=0;i<availableNew.devices.length;i++)if(disk===availableNew.devices[i]){found=!0;break}found||filtered.push(disk)}}),filtered}}),angular.module("MAAS").controller("NodeStorageController",["$scope","MachinesManager","ConverterService","UsersManager",function($scope,MachinesManager,ConverterService,UsersManager){var MIN_PARTITION_SIZE=4194304,SELECTION_MODE={NONE:null,SINGLE:"single",MUTLI:"multi",UNMOUNT:"unmount",UNFORMAT:"unformat",EDIT:"edit",DELETE:"delete",FORMAT_AND_MOUNT:"format-mount",PARTITION:"partition",BCACHE:"bcache",RAID:"raid",VOLUME_GROUP:"volume-group",LOGICAL_VOLUME:"logical-volume"},RAID_MODES=[{level:"raid-0",title:"RAID 0",min_disks:2,allows_spares:!1,calculateSize:function(minSize,numDisks){return minSize*numDisks}},{level:"raid-1",title:"RAID 1",min_disks:2,allows_spares:!0,calculateSize:function(minSize,numDisks){return minSize}},{level:"raid-5",title:"RAID 5",min_disks:3,allows_spares:!0,calculateSize:function(minSize,numDisks){return minSize*(numDisks-1)}},{level:"raid-6",title:"RAID 6",min_disks:4,allows_spares:!0,calculateSize:function(minSize,numDisks){return minSize*(numDisks-2)}},{level:"raid-10",title:"RAID 10",min_disks:3,allows_spares:!0,calculateSize:function(minSize,numDisks){return minSize*numDisks/2}}];function hasMountedFilesystem(item){return angular.isObject(item)&&(filesystem=item.filesystem,angular.isObject(filesystem)&&angular.isString(filesystem.mount_point)&&""!==filesystem.mount_point);var filesystem}function hasFormattedUnmountedFilesystem(item){return angular.isObject(item.filesystem)&&angular.isString(item.filesystem.fstype)&&""!==item.filesystem.fstype&&(!1===angular.isString(item.filesystem.mount_point)||""===item.filesystem.mount_point)?item.filesystem.fstype:null}function isInUse(item){return"cache-set"===item.type||(angular.isObject(item.filesystem)?!(!item.filesystem.is_format_fstype||!angular.isString(item.filesystem.mount_point)||""===item.filesystem.mount_point)||!item.filesystem.is_format_fstype:item.available_size<MIN_PARTITION_SIZE)}function getTags(disk){var tags=[];return angular.forEach(disk.tags,function(tag){tags.push({text:tag})}),tags}function getUniqueKey(disk){if("cache-set"===disk.type)return"cache-set-"+disk.cache_set_id;var key=disk.type+"-"+disk.block_id;return angular.isNumber(disk.partition_id)&&(key+="-"+disk.partition_id),key}function updateDisks(){var used,cachesets,filesystems;angular.isArray($scope.node.disks)?($scope.has_disks=$scope.node.disks.length>0,filesystems=[],angular.forEach($scope.node.disks,function(disk){if(hasMountedFilesystem(disk)){var data={type:"filesystem",name:disk.name,size_human:disk.size_human,fstype:disk.filesystem.fstype,mount_point:disk.filesystem.mount_point,mount_options:disk.filesystem.mount_options,block_id:disk.id,partition_id:null,filesystem_id:disk.filesystem.id,original_type:disk.type,original:disk};"virtual"===disk.type&&(disk.parent_type=disk.parent.type),filesystems.push(data)}angular.forEach(disk.partitions,function(partition){hasMountedFilesystem(partition)&&filesystems.push({type:"filesystem",name:partition.name,size_human:partition.size_human,fstype:partition.filesystem.fstype,mount_point:partition.filesystem.mount_point,mount_options:partition.filesystem.mount_options,block_id:disk.id,partition_id:partition.id,filesystem_id:partition.filesystem.id,original_type:"partition",original:partition})})}),angular.forEach($scope.node.special_filesystems,function(filesystem){filesystems.push({type:"filesystem",name:"—",size_human:"—",fstype:filesystem.fstype,mount_point:filesystem.mount_point,mount_options:filesystem.mount_options,block_id:null,partition_id:null,original_type:"special"})}),angular.forEach(filesystems,function(filesystem){var key=getUniqueKey(filesystem),oldFilesystem=$scope.filesystemsMap[key];angular.isObject(oldFilesystem)?filesystem.$selected=oldFilesystem.$selected:filesystem.$selected=!1}),$scope.filesystems=filesystems,$scope.filesystemsMap={},angular.forEach(filesystems,function(filesystem){$scope.filesystemsMap[getUniqueKey(filesystem)]=filesystem}),$scope.updateFilesystemSelection(!1),cachesets=[],angular.forEach($scope.node.disks,function(disk){"cache-set"===disk.type&&cachesets.push({type:"cache-set",name:disk.name,size_human:disk.size_human,cache_set_id:disk.id,used_by:disk.used_for})}),angular.forEach(cachesets,function(cacheset){var key=getUniqueKey(cacheset),oldCacheSet=$scope.cachesetsMap[key];angular.isObject(oldCacheSet)?cacheset.$selected=oldCacheSet.$selected:cacheset.$selected=!1}),$scope.cachesets=cachesets,$scope.cachesetsMap={},angular.forEach(cachesets,function(cacheset){$scope.cachesetsMap[getUniqueKey(cacheset)]=cacheset}),$scope.updateCacheSetsSelection(!1),function(){var available=[];if(angular.forEach($scope.node.disks,function(disk){if(!isInUse(disk)){var has_partitions=!1;angular.isArray(disk.partitions)&&disk.partitions.length>0&&(has_partitions=!0);var data={name:disk.name,size_human:disk.size_human,available_size_human:disk.available_size_human,used_size_human:disk.used_size_human,type:disk.type,model:disk.model,serial:disk.serial,tags:getTags(disk),fstype:hasFormattedUnmountedFilesystem(disk),mount_point:null,mount_options:null,block_id:disk.id,partition_id:null,has_partitions:has_partitions,is_boot:disk.is_boot,original:disk,test_status:disk.test_status,firmware_version:disk.firmware_version};"virtual"===disk.type&&(data.parent_type=disk.parent.type),available.push(data)}angular.forEach(disk.partitions,function(partition){isInUse(partition)||available.push({name:partition.name,size_human:partition.size_human,available_size_human:partition.available_size_human,used_size_human:partition.used_size_human,type:"partition",model:"",serial:"",tags:[],fstype:hasFormattedUnmountedFilesystem(partition),mount_point:null,mount_options:null,block_id:disk.id,partition_id:partition.id,has_partitions:!1,is_boot:!1,original:partition})})}),angular.forEach(available,function(disk){var key=getUniqueKey(disk),oldDisk=$scope.availableMap[key];angular.isObject(oldDisk)?(disk.$selected=oldDisk.$selected,disk.$options=oldDisk.$options):(disk.$selected=!1,disk.$options={})}),$scope.available=available,$scope.availableMap={},angular.forEach(available,function(disk){$scope.availableMap[getUniqueKey(disk)]=disk}),angular.isObject($scope.availableNew))if(angular.isObject($scope.availableNew.device)){var key=getUniqueKey($scope.availableNew.device);$scope.availableNew.device=$scope.availableMap[key]}else if(angular.isArray($scope.availableNew.devices)){var newDevices=[];angular.forEach($scope.availableNew.devices,function(device){var key=getUniqueKey(device),newDevice=$scope.availableMap[key];angular.isObject(newDevice)&&newDevices.push(newDevice)}),$scope.availableNew.devices=newDevices}$scope.updateAvailableSelection(!1)}(),used=[],angular.forEach($scope.node.disks,function(disk){if(isInUse(disk)&&"cache-set"!==disk.type){var has_partitions=!1;angular.isArray(disk.partitions)&&disk.partitions.length>0&&(has_partitions=!0);var data={name:disk.name,type:disk.type,model:disk.model,serial:disk.serial,tags:getTags(disk),used_for:disk.used_for,is_boot:disk.is_boot,has_partitions:has_partitions,test_status:disk.test_status,firmware_version:disk.firmware_version};"virtual"===disk.type&&(data.parent_type=disk.parent.type),used.push(data)}angular.forEach(disk.partitions,function(partition){isInUse(partition)&&"cache-set"!==partition.type&&used.push({name:partition.name,type:"partition",model:"",serial:"",tags:[],used_for:partition.used_for,is_boot:!1})})}),$scope.used=used):($scope.has_disks=!1,$scope.filesystems=[],$scope.filesystemsMap={},$scope.filesystemMode=SELECTION_MODE.NONE,$scope.filesystemAllSelected=!1,$scope.cachesets=[],$scope.cachesetsMap={},$scope.cachesetsMode=SELECTION_MODE.NONE,$scope.cachesetsAllSelected=!1,$scope.available=[],$scope.availableMap={},$scope.availableMode=SELECTION_MODE.NONE,$scope.availableAllSelected=!1,$scope.availableNew={},$scope.used=[])}function deselectAll(items){angular.forEach(items,function(item){item.$selected=!1})}function capitalizeFirstLetter(string){return string.charAt(0).toUpperCase()+string.slice(1)}function getIndexFromName(prefix,name){var match=new RegExp("^"+prefix+"([0-9]+)$").exec(name);if(angular.isArray(match)&&2===match.length)return parseInt(match[1],10)}function getNextName(prefix){var idx=-1;return angular.forEach($scope.node.disks,function(disk){var dIdx=getIndexFromName(prefix,disk.name);angular.isNumber(dIdx)&&(idx=Math.max(idx,dIdx)),angular.forEach(disk.partitions,function(partition){dIdx=getIndexFromName(prefix,partition.name),angular.isNumber(dIdx)&&(idx=Math.max(idx,dIdx))})}),prefix+(idx+1)}function isNameAlreadyInUse(name,exclude_disk){if(!angular.isArray($scope.node.disks))return!1;var i,j;for(i=0;i<$scope.node.disks.length;i++){var disk=$scope.node.disks[i];if(disk.name===name&&(!angular.isObject(exclude_disk)||"partition"===exclude_disk.type||exclude_disk.block_id!==disk.id))return!0;if(angular.isArray(disk.partitions))for(j=0;j<disk.partitions.length;j++){var partition=disk.partitions[j];if(partition.name===name&&(!angular.isObject(exclude_disk)||"partition"!==exclude_disk.type||exclude_disk.partition_id!==partition.id))return!0}}return!1}function isLogicalVolume(disk){return"virtual"===disk.type&&"lvm-vg"===disk.parent_type}$scope.tableInfo={column:"name"},$scope.has_disks=!1,$scope.filesystems=[],$scope.filesystemsMap={},$scope.filesystemMode=SELECTION_MODE.NONE,$scope.filesystemAllSelected=!1,$scope.cachesets=[],$scope.cachesetsMap={},$scope.cachesetsMode=SELECTION_MODE.NONE,$scope.cachesetsAllSelected=!1,$scope.available=[],$scope.availableMap={},$scope.availableMode=SELECTION_MODE.NONE,$scope.availableAllSelected=!1,$scope.availableNew={},$scope.used=[],$scope.showMembers=[],$scope.nodeLoaded=function(){$scope.$watch("node.disks",updateDisks)},$scope.isBootDiskDisabled=function(item,section){return!$scope.isSuperUser()||(!(!angular.isObject($scope.node)||-1!==["Ready","Allocated"].indexOf($scope.node.status))||("physical"!==item.type||"used"===section&&!item.has_partitions))},$scope.setAsBootDisk=function(item){item.is_boot||$scope.isBootDiskDisabled(item)||MachinesManager.setBootDisk($scope.node,item.block_id)},$scope.getSelectedFilesystems=function(){var filesystems=[];return angular.forEach($scope.filesystems,function(filesystem){filesystem.$selected&&filesystems.push(filesystem)}),filesystems},$scope.updateFilesystemSelection=function(force){angular.isUndefined(force)&&(force=!1);var filesystems=$scope.getSelectedFilesystems();0===filesystems.length?$scope.filesystemMode=SELECTION_MODE.NONE:1===filesystems.length&&force?$scope.filesystemMode=SELECTION_MODE.SINGLE:force&&($scope.filesystemMode=SELECTION_MODE.MUTLI),0===$scope.filesystems.length?$scope.filesystemAllSelected=!1:filesystems.length===$scope.filesystems.length?$scope.filesystemAllSelected=!0:$scope.filesystemAllSelected=!1},$scope.toggleFilesystemSelect=function(filesystem){filesystem.$selected=!filesystem.$selected,$scope.updateFilesystemSelection(!0)},$scope.toggleFilesystemAllSelect=function(){angular.forEach($scope.filesystems,function(filesystem){$scope.filesystemAllSelected?filesystem.$selected=!1:filesystem.$selected=!0}),$scope.updateFilesystemSelection(!0)},$scope.isFilesystemsDisabled=function(){return $scope.filesystemMode!==SELECTION_MODE.NONE&&$scope.filesystemMode!==SELECTION_MODE.SINGLE&&$scope.filesystemMode!==SELECTION_MODE.MUTLI||$scope.isAllStorageDisabled()},$scope.filesystemCancel=function(){deselectAll($scope.filesystems),$scope.updateFilesystemSelection(!0)},$scope.filesystemUnmount=function(){$scope.filesystemMode=SELECTION_MODE.UNMOUNT},$scope.quickFilesystemUnmount=function(filesystem){deselectAll($scope.filesystems),filesystem.$selected=!0,$scope.updateFilesystemSelection(!0),$scope.filesystemUnmount()},$scope.filesystemConfirmUnmount=function(filesystem){MachinesManager.updateFilesystem($scope.node,filesystem.block_id,filesystem.partition_id,filesystem.fstype,null,null);var idx=$scope.filesystems.indexOf(filesystem);$scope.filesystems.splice(idx,1),$scope.updateFilesystemSelection()},$scope.filesystemDelete=function(){$scope.filesystemMode=SELECTION_MODE.DELETE},$scope.quickFilesystemDelete=function(filesystem){deselectAll($scope.filesystems),filesystem.$selected=!0,$scope.updateFilesystemSelection(!0),$scope.filesystemDelete()},$scope.filesystemConfirmDelete=function(filesystem){"special"===filesystem.original_type?MachinesManager.unmountSpecialFilesystem($scope.node,filesystem.mount_point):"partition"===filesystem.original_type?MachinesManager.deletePartition($scope.node,filesystem.original.id):MachinesManager.deleteFilesystem($scope.node,filesystem.block_id,filesystem.partition_id,filesystem.filesystem_id);var idx=$scope.filesystems.indexOf(filesystem);$scope.filesystems.splice(idx,1),$scope.updateFilesystemSelection()},$scope.hasUnmountedFilesystem=function(disk){return!(!angular.isString(disk.fstype)||""===disk.fstype||angular.isString(disk.mount_point)&&""!==disk.mount_point)},$scope.showFreeSpace=function(disk){return"lvm-vg"===disk.type||("physical"===disk.type||"virtual"===disk.type)&&disk.has_partitions},$scope.getDeviceType=function(disk){return angular.isUndefined(disk)?"":"virtual"===disk.type?"lvm-vg"===disk.parent_type?"Logical volume":0===disk.parent_type.indexOf("raid-")?"RAID "+disk.parent_type.split("-")[1]:capitalizeFirstLetter(disk.parent_type):"lvm-vg"===disk.type?"Volume group":capitalizeFirstLetter(disk.type)},$scope.getSelectedAvailable=function(){var available=[];return angular.forEach($scope.available,function(disk){disk.$selected&&available.push(disk)}),available},$scope.updateAvailableSelection=function(force){angular.isUndefined(force)&&(force=!1);var available=$scope.getSelectedAvailable();0===available.length?$scope.availableMode=SELECTION_MODE.NONE:1===available.length&&force?$scope.availableMode=SELECTION_MODE.SINGLE:force&&($scope.availableMode=SELECTION_MODE.MUTLI),0===$scope.available.length?$scope.availableAllSelected=!1:available.length===$scope.available.length?$scope.availableAllSelected=!0:$scope.availableAllSelected=!1},$scope.toggleAvailableSelect=function(disk){disk.$selected=!disk.$selected,$scope.updateAvailableSelection(!0)},$scope.toggleAvailableAllSelect=function(){angular.forEach($scope.available,function(disk){$scope.availableAllSelected?disk.$selected=!1:disk.$selected=!0}),$scope.updateAvailableSelection(!0)},$scope.isAvailableDisabled=function(){return $scope.availableMode!==SELECTION_MODE.NONE&&$scope.availableMode!==SELECTION_MODE.SINGLE&&$scope.availableMode!==SELECTION_MODE.MUTLI||$scope.isAllStorageDisabled()},$scope.canFormatAndMount=function(disk){return!$scope.isAllStorageDisabled()&&("lvm-vg"!==disk.type&&!disk.has_partitions&&("physical"!==disk.type||!disk.original.is_boot))},$scope.getPartitionButtonText=function(disk){return disk.has_partitions?"Add partition":"Partition"},$scope.availablePartitionSpace=function(disk){var space_to_reserve=0;return angular.isString(disk.original.partition_table_type)&&""!==disk.original.partition_table_type||(space_to_reserve=5242880,0===$scope.node.architecture.indexOf("ppc64el")&&(space_to_reserve+=8388608)),ConverterService.roundByBlockSize(disk.original.available_size-space_to_reserve,4194304)},$scope.canAddPartition=function(disk){return!(!$scope.isSuperUser()||$scope.isAllStorageDisabled())&&("partition"!==disk.type&&"lvm-vg"!==disk.type&&(("virtual"!==disk.type||"lvm-vg"!==disk.parent_type&&"bcache"!==disk.parent_type)&&((!angular.isString(disk.fstype)||""===disk.fstype)&&$scope.availablePartitionSpace(disk)-MIN_PARTITION_SIZE>=0)))},$scope.isNameInvalid=function(disk){return""!==disk.name&&!!isNameAlreadyInUse(disk.name,disk)},$scope.nameHasChanged=function(disk){if(isLogicalVolume(disk)){var parentName=disk.original.name.split("-")[0]+"-";0!==disk.name.indexOf(parentName)&&(disk.name=parentName)}},$scope.availableCancel=function(disk){$scope.updateAvailableSelection(!0),$scope.availableNew={}},$scope.usesMountPoint=function(fstype){return angular.isString(fstype)&&"swap"!==fstype},$scope.usesStorage=function(fstype){return angular.isString(fstype)&&"tmpfs"!==fstype&&"ramfs"!==fstype},$scope.isMountPointInvalid=function(mountPoint){return!angular.isUndefined(mountPoint)&&""!==mountPoint&&("none"!==mountPoint&&"/"!==mountPoint[0])},$scope.canDelete=function(disk){return!(!$scope.isSuperUser()||$scope.isAllStorageDisabled())&&("lvm-vg"===disk.type?0===disk.original.used_size:!disk.has_partitions)},$scope.availableDelete=function(){$scope.availableMode=SELECTION_MODE.DELETE},$scope.availableQuickDelete=function(disk){deselectAll($scope.available),disk.$selected=!0,$scope.updateAvailableSelection(!0),$scope.availableDelete()},$scope.canEdit=function(disk){return!(!$scope.isSuperUser()||$scope.isAllStorageDisabled())},$scope.availableEdit=function(disk){$scope.availableMode=SELECTION_MODE.EDIT,"lvm-vg"===disk.type?disk.$options={editingTags:!1,editingFilesystem:!1}:"partition"===disk.type?disk.$options={editingTags:!1,editingFilesystem:!0,fstype:disk.fstype}:(disk.$options={editingFilesystem:!0,editingTags:!0,tags:angular.copy(disk.tags),fstype:disk.fstype},$scope.canFormatAndMount(disk)||(disk.$options.editingFilesystem=!1))},$scope.availableQuickEdit=function(disk){deselectAll($scope.available),disk.$selected=!0,$scope.updateAvailableSelection(!0),$scope.availableEdit(disk)},$scope.availableConfirmEdit=function(disk){var params={name:disk.name};if(!$scope.isNameInvalid(disk)&&!$scope.isMountPointInvalid(disk.$options.mountPoint)){if(""===disk.name&&(disk.name=disk.original.name),isLogicalVolume(disk)){var parentName=disk.original.name.split("-")[0]+"-";params.name=disk.name.slice(parentName.length)}if(angular.isDefined(disk.$options.fstype)&&(params.fstype=disk.$options.fstype,params.mount_point=disk.$options.mountPoint||"",params.mount_options=disk.$options.mountOptions||""),angular.isArray(disk.$options.tags)&&(params.tags=disk.$options.tags.map(function(tag){return tag.text})),"partition"===disk.type?MachinesManager.updateFilesystem($scope.node,disk.block_id,disk.partition_id,params.fstype,params.mount_point,params.mount_options,params.tags):MachinesManager.updateDisk($scope.node,disk.block_id,params),disk.fstype=disk.$options.fstype,disk.mount_point=disk.$options.mountPoint,disk.mount_options=disk.$options.mountOptions,disk.tags=disk.$options.tags,disk.$options={},angular.isString(disk.mount_point)&&""!==disk.mount_point){$scope.filesystems.push({name:disk.name,size_human:disk.size_human,fstype:disk.fstype,mount_point:disk.mount_point,mount_options:disk.mount_options,block_id:disk.block_id,partition_id:disk.partition_id});var idx=$scope.available.indexOf(disk);$scope.available.splice(idx,1)}disk.$selected=!1,$scope.updateAvailableSelection(!0)}},$scope.getRemoveTypeText=function(disk){if("filesystem"===disk.type){if(!angular.isObject(disk.original))return"special filesystem";disk=disk.original}return"physical"===disk.type?"physical disk":"partition"===disk.type?"partition":"lvm-vg"===disk.type?"volume group":"virtual"===disk.type?"lvm-vg"===disk.parent_type?"logical volume":0===disk.parent_type.indexOf("raid-")?"RAID "+disk.parent_type.split("-")[1]+" disk":disk.parent_type+" disk":void 0},$scope.availableConfirmDelete=function(disk){"lvm-vg"===disk.type?MachinesManager.deleteVolumeGroup($scope.node,disk.block_id):"partition"===disk.type?MachinesManager.deletePartition($scope.node,disk.partition_id):MachinesManager.deleteDisk($scope.node,disk.block_id);var idx=$scope.available.indexOf(disk);$scope.available.splice(idx,1),$scope.updateAvailableSelection(!0)},$scope.availablePartition=function(disk){$scope.availableMode=SELECTION_MODE.PARTITION;var size_and_units=disk.available_size_human.split(" ");disk.$options={size:size_and_units[0],sizeUnits:size_and_units[1],fstype:null,mountPoint:"",mountOptions:""}},$scope.availableQuickPartition=function(disk){deselectAll($scope.available),disk.$selected=!0,$scope.updateAvailableSelection(!0),$scope.availablePartition(disk)},$scope.getAddPartitionName=function(disk){var length,partitions=disk.original.partitions;return length=angular.isArray(partitions)?partitions.length:0,"mbr"===disk.original.partition_table_type&&length>2?disk.name+"-part"+(length+2):0===$scope.node.architecture.indexOf("ppc64el")&&disk.original.is_boot?disk.name+"-part"+(length+2):disk.name+"-part"+(length+1)},$scope.isAddPartitionSizeInvalid=function(disk){if(""!==disk.$options.size&&(string=disk.$options.size,/^-?\d+\.?\d*$/.test(string))){var bytes=ConverterService.unitsToBytes(disk.$options.size,disk.$options.sizeUnits);return bytes<MIN_PARTITION_SIZE||bytes>disk.original.available_size&&ConverterService.roundUnits(disk.$options.size,disk.$options.sizeUnits)>disk.original.available_size}return!0;var string},$scope.availableConfirmPartition=function(disk){if(!$scope.isAddPartitionSizeInvalid(disk)&&!$scope.isMountPointInvalid(disk.$options.mountPoint)){var bytes=ConverterService.unitsToBytes(disk.$options.size,disk.$options.sizeUnits),size_and_units=disk.original.available_size_human.split(" ");disk.$options.size===size_and_units[0]&&disk.$options.sizeUnits===size_and_units[1]&&(bytes=disk.original.available_size);var removeDisk=!1,available_space=$scope.availablePartitionSpace(disk);bytes>=available_space&&(bytes=available_space,removeDisk=!0);var params={};if(angular.isString(disk.$options.fstype)&&""!==disk.$options.fstype&&(params.fstype=disk.$options.fstype,""!==disk.$options.mountPoint&&(params.mount_point=disk.$options.mountPoint,params.mount_options=disk.$options.mountOptions)),MachinesManager.createPartition($scope.node,disk.block_id,bytes,params),removeDisk){var idx=$scope.available.indexOf(disk);$scope.available.splice(idx,1)}$scope.updateAvailableSelection(!0)}},$scope.getSelectedCacheSets=function(){var cachesets=[];return angular.forEach($scope.cachesets,function(cacheset){cacheset.$selected&&cachesets.push(cacheset)}),cachesets},$scope.updateCacheSetsSelection=function(force){angular.isUndefined(force)&&(force=!1);var cachesets=$scope.getSelectedCacheSets();0===cachesets.length?$scope.cachesetsMode=SELECTION_MODE.NONE:1===cachesets.length&&force?$scope.cachesetsMode=SELECTION_MODE.SINGLE:force&&($scope.cachesetsMode=SELECTION_MODE.MUTLI),0===$scope.cachesets.length?$scope.cachesetsAllSelected=!1:cachesets.length===$scope.cachesets.length?$scope.cachesetsAllSelected=!0:$scope.cachesetsAllSelected=!1},$scope.toggleCacheSetSelect=function(cacheset){cacheset.$selected=!cacheset.$selected,$scope.updateCacheSetsSelection(!0)},$scope.toggleCacheSetAllSelect=function(){angular.forEach($scope.cachesets,function(cacheset){$scope.cachesetsAllSelected?cacheset.$selected=!1:cacheset.$selected=!0}),$scope.updateCacheSetsSelection(!0)},$scope.isCacheSetsDisabled=function(){return $scope.isAllStorageDisabled()&&!$scope.isSuperUser()||$scope.cachesetsMode!==SELECTION_MODE.NONE&&$scope.cachesetsMode!==SELECTION_MODE.SINGLE&&$scope.cachesetsMode!==SELECTION_MODE.MUTLI},$scope.cacheSetCancel=function(){deselectAll($scope.cachesets),$scope.updateCacheSetsSelection(!0)},$scope.canDeleteCacheSet=function(cacheset){return""===cacheset.used_by&&!$scope.isAllStorageDisabled()&&$scope.isSuperUser()},$scope.cacheSetDelete=function(){$scope.cachesetsMode=SELECTION_MODE.DELETE},$scope.quickCacheSetDelete=function(cacheset){deselectAll($scope.cachesets),cacheset.$selected=!0,$scope.updateCacheSetsSelection(!0),$scope.cacheSetDelete()},$scope.cacheSetConfirmDelete=function(cacheset){MachinesManager.deleteCacheSet($scope.node,cacheset.cache_set_id);var idx=$scope.cachesets.indexOf(cacheset);$scope.cachesets.splice(idx,1),$scope.updateCacheSetsSelection()},$scope.canCreateCacheSet=function(){if($scope.isAvailableDisabled()||!$scope.isSuperUser())return!1;var selected=$scope.getSelectedAvailable();return 1===selected.length&&(!selected[0].has_partitions&&!$scope.hasUnmountedFilesystem(selected[0])&&"lvm-vg"!==selected[0].type)},$scope.createCacheSet=function(){if($scope.canCreateCacheSet()){var disk=$scope.getSelectedAvailable()[0];MachinesManager.createCacheSet($scope.node,disk.block_id,disk.partition_id);var idx=$scope.available.indexOf(disk);$scope.available.splice(idx,1)}},$scope.getCannotCreateBcacheMsg=function(){if(0===$scope.cachesets.length)return"Create at least one cache set to create bcache";var selected=$scope.getSelectedAvailable();return 1===selected.length?$scope.hasUnmountedFilesystem(selected[0])?"Device is formatted; unformat the device to create bcache":"lvm-vg"===selected[0].type?"Cannot use a logical volume as a backing device for bcache.":selected[0].has_partitions?"Device has already been partitioned; create a new partition to use as the bcache backing device":null:"Select only one available device to create bcache"},$scope.canCreateBcache=function(){return!($scope.isAvailableDisabled()||!$scope.isSuperUser())&&null===$scope.getCannotCreateBcacheMsg()},$scope.createBcache=function(){$scope.canCreateBcache()&&($scope.availableMode=SELECTION_MODE.BCACHE,$scope.availableNew={name:getNextName("bcache"),device:$scope.getSelectedAvailable()[0],cacheset:$scope.cachesets[0],cacheMode:"writeback",fstype:null,mountPoint:"",mountOptions:"",tags:[]})},$scope.fstypeChanged=function(options){null===options.fstype?(options.mountPoint="",options.mountOptions=""):$scope.usesMountPoint(options.fstype)?"none"===options.mountPoint&&(options.mountPoint=""):options.mountPoint="none"},$scope.isNewDiskNameInvalid=function(){if(!angular.isObject($scope.node)||!angular.isArray($scope.node.disks))return!0;if(""===$scope.availableNew.name)return!0;var i,j;for(i=0;i<$scope.node.disks.length;i++){var disk=$scope.node.disks[i];if($scope.availableNew.name===disk.name)return!0;if(angular.isArray(disk.partitions))for(j=0;j<disk.partitions.length;j++){var partition=disk.partitions[j];if($scope.availableNew.name===partition.name)return!0}}return!1},$scope.createBcacheCanSave=function(){return!$scope.isNewDiskNameInvalid()&&!$scope.isMountPointInvalid($scope.availableNew.mountPoint)},$scope.availableConfirmCreateBcache=function(){if($scope.createBcacheCanSave()){var params={name:$scope.availableNew.name,cache_set:$scope.availableNew.cacheset.cache_set_id,cache_mode:$scope.availableNew.cacheMode};"partition"===$scope.availableNew.device.type?params.partition_id=$scope.availableNew.device.partition_id:params.block_id=$scope.availableNew.device.block_id,angular.isString($scope.availableNew.fstype)&&""!==$scope.availableNew.fstype&&(params.fstype=$scope.availableNew.fstype,""!==$scope.availableNew.mountPoint&&(params.mount_point=$scope.availableNew.mountPoint,params.mount_options=$scope.availableNew.mountOptions)),angular.isArray($scope.availableNew.tags)&&$scope.availableNew.tags.length>0&&(params.tags=$scope.availableNew.tags.map(function(tag){return tag.text})),MachinesManager.createBcache($scope.node,params);var idx=$scope.available.indexOf($scope.availableNew.device);$scope.available.splice(idx,1),$scope.availableNew={},$scope.updateAvailableSelection(!0)}},$scope.canCreateRAID=function(){if($scope.isAvailableDisabled()||!$scope.isSuperUser())return!1;var selected=$scope.getSelectedAvailable();if(selected.length>1){var i;for(i=0;i<selected.length;i++){if($scope.hasUnmountedFilesystem(selected[i]))return!1;if("lvm-vg"===selected[i].type)return!1}return!0}return!1},$scope.createRAID=function(){$scope.canCreateRAID()&&($scope.availableMode=SELECTION_MODE.RAID,$scope.availableNew={name:getNextName("md"),devices:$scope.getSelectedAvailable(),mode:null,spares:[],fstype:null,mountPoint:"",mountOptions:"",tags:[]},$scope.availableNew.mode=$scope.getAvailableRAIDModes()[0])},$scope.getAvailableRAIDModes=function(){if(!angular.isObject($scope.availableNew)||!angular.isArray($scope.availableNew.devices))return[];var modes=[];return angular.forEach(RAID_MODES,function(mode){$scope.availableNew.devices.length>=mode.min_disks&&modes.push(mode)}),modes},$scope.getTotalNumberOfAvailableSpares=function(){var mode=$scope.availableNew.mode;if(angular.isUndefined(mode)||!mode.allows_spares)return 0;var diff=$scope.availableNew.devices.length-mode.min_disks;return diff<0&&(diff=0),diff},$scope.getNumberOfRemainingSpares=function(){var allowed=$scope.getTotalNumberOfAvailableSpares();return allowed<=0?0:allowed-$scope.availableNew.spares.length},$scope.showSparesColumn=function(){return $scope.getTotalNumberOfAvailableSpares()>0},$scope.RAIDModeChanged=function(){$scope.availableNew.spares=[]},$scope.isActiveRAIDMember=function(disk){return!angular.isArray($scope.availableNew.spares)||-1===$scope.availableNew.spares.indexOf(getUniqueKey(disk))},$scope.isSpareRAIDMember=function(disk){return!$scope.isActiveRAIDMember(disk)},$scope.setAsActiveRAIDMember=function(disk){var idx=$scope.availableNew.spares.indexOf(getUniqueKey(disk));idx>-1&&$scope.availableNew.spares.splice(idx,1)},$scope.setAsSpareRAIDMember=function(disk){var key=getUniqueKey(disk);-1===$scope.availableNew.spares.indexOf(key)&&$scope.availableNew.spares.push(key)},$scope.getNewRAIDSize=function(){if(angular.isUndefined($scope.availableNew.mode))return"";var calculateSize=$scope.availableNew.mode.calculateSize;if(!angular.isFunction(calculateSize))return"";var numDisks=$scope.availableNew.devices.length-$scope.availableNew.spares.length,minSize=Number.MAX_VALUE;angular.forEach($scope.availableNew.devices,function(device){var deviceSize=device.original.available_size||device.original.size;minSize=Math.min(minSize,deviceSize)});var size=calculateSize(minSize,numDisks);return ConverterService.bytesToUnits(size).string},$scope.createRAIDCanSave=function(){return!$scope.isNewDiskNameInvalid()&&!$scope.isMountPointInvalid($scope.availableNew.mountPoint)},$scope.availableConfirmCreateRAID=function(){if($scope.createRAIDCanSave()){var params={name:$scope.availableNew.name,level:$scope.availableNew.mode.level,block_devices:[],partitions:[],spare_devices:[],spare_partitions:[]};angular.forEach($scope.availableNew.devices,function(device){$scope.isActiveRAIDMember(device)?"partition"===device.type?params.partitions.push(device.partition_id):params.block_devices.push(device.block_id):"partition"===device.type?params.spare_partitions.push(device.partition_id):params.spare_devices.push(device.block_id)}),angular.isString($scope.availableNew.fstype)&&""!==$scope.availableNew.fstype&&(params.fstype=$scope.availableNew.fstype,""!==$scope.availableNew.mountPoint&&(params.mount_point=$scope.availableNew.mountPoint,params.mount_options=$scope.availableNew.mountOptions)),angular.isArray($scope.availableNew.tags)&&$scope.availableNew.tags.length>0&&(params.tags=$scope.availableNew.tags.map(function(tag){return tag.text})),MachinesManager.createRAID($scope.node,params),angular.forEach($scope.availableNew.devices,function(device){var idx=$scope.available.indexOf($scope.availableNew.device);$scope.available.splice(idx,1)}),$scope.availableNew={},$scope.updateAvailableSelection(!0)}},$scope.canCreateVolumeGroup=function(){if($scope.isAvailableDisabled()||!$scope.isSuperUser())return!1;var selected=$scope.getSelectedAvailable();if(selected.length>0){var i;for(i=0;i<selected.length;i++){if(selected[i].has_partitions)return!1;if($scope.hasUnmountedFilesystem(selected[i]))return!1;if("lvm-vg"===selected[i].type)return!1}return!0}return!1},$scope.createVolumeGroup=function(){$scope.canCreateVolumeGroup()&&($scope.availableMode=SELECTION_MODE.VOLUME_GROUP,$scope.availableNew={name:getNextName("vg"),devices:$scope.getSelectedAvailable()})},$scope.getNewVolumeGroupSize=function(){var total=0;return angular.forEach($scope.availableNew.devices,function(device){total+=device.original.available_size||device.original.size}),ConverterService.bytesToUnits(total).string},$scope.createVolumeGroupCanSave=function(){return!$scope.isNewDiskNameInvalid()},$scope.availableConfirmCreateVolumeGroup=function(){if($scope.createVolumeGroupCanSave()){var params={name:$scope.availableNew.name,block_devices:[],partitions:[]};angular.forEach($scope.availableNew.devices,function(device){"partition"===device.type?params.partitions.push(device.partition_id):params.block_devices.push(device.block_id)}),MachinesManager.createVolumeGroup($scope.node,params),angular.forEach($scope.availableNew.devices,function(device){var idx=$scope.available.indexOf($scope.availableNew.device);$scope.available.splice(idx,1)}),$scope.availableNew={},$scope.updateAvailableSelection(!0)}},$scope.canAddLogicalVolume=function(disk){return"lvm-vg"===disk.type&&!(disk.original.available_size<MIN_PARTITION_SIZE)},$scope.availableLogicalVolume=function(disk){$scope.availableMode=SELECTION_MODE.LOGICAL_VOLUME,disk.$selected=!0;var size_and_units=disk.available_size_human.split(" "),namePrefix=disk.name+"-lv";disk.$options={name:getNextName(namePrefix),size:size_and_units[0],sizeUnits:size_and_units[1],fstype:null,tags:[]}},$scope.isLogicalVolumeNameInvalid=function(disk){return!!angular.isString(disk.$options.name)&&(0!==disk.$options.name.indexOf(disk.name+"-")||disk.$options.name.length<=disk.name.length+1||isNameAlreadyInUse(disk.$options.name))},$scope.newLogicalVolumeNameChanged=function(disk){angular.isString(disk.$options.name)&&(0!==disk.$options.name.indexOf(disk.name+"-")&&(disk.$options.name=disk.name+"-"))},$scope.isAddLogicalVolumeSizeInvalid=function(disk){return $scope.isAddPartitionSizeInvalid(disk)},$scope.availableConfirmLogicalVolume=function(disk){if(!($scope.isLogicalVolumeNameInvalid(disk)||$scope.isAddLogicalVolumeSizeInvalid(disk)||$scope.isMountPointInvalid(disk.$options.mountPoint))){var bytes=ConverterService.unitsToBytes(disk.$options.size,disk.$options.sizeUnits),size_and_units=disk.original.available_size_human.split(" ");disk.$options.size===size_and_units[0]&&disk.$options.sizeUnits===size_and_units[1]&&(bytes=disk.original.available_size),bytes>disk.original.available_size&&(bytes=disk.original.available_size);var removeDisk=!1;bytes===disk.original.available_size&&(removeDisk=!0);var name=disk.$options.name.slice(disk.name.length+1),params={};if(angular.isString(disk.$options.fstype)&&""!==disk.$options.fstype&&(params.fstype=disk.$options.fstype,""!==disk.$options.mountPoint&&(params.mount_point=disk.$options.mountPoint,params.mount_options=disk.$options.mountOptions)),angular.isArray(disk.$options.tags)&&disk.$options.tags.length>0&&(params.tags=disk.$options.tags.map(function(tag){return tag.text})),MachinesManager.createLogicalVolume($scope.node,disk.block_id,name,bytes,params),removeDisk){var idx=$scope.available.indexOf(disk);$scope.available.splice(idx,1)}$scope.updateAvailableSelection(!0)}},$scope.isAllStorageDisabled=function(){var authUser=UsersManager.getAuthUser();return!angular.isObject(authUser)||!angular.isObject($scope.node)||!authUser.is_superuser&&authUser.username!==$scope.node.owner||!(!angular.isObject($scope.node)||-1!==["Ready","Allocated"].indexOf($scope.node.status))},$scope.hasStorageLayoutIssues=function(){return!(!angular.isObject($scope.node)||!angular.isArray($scope.node.storage_layout_issues))&&$scope.node.storage_layout_issues.length>0},$scope.$parent.controllerLoaded("storageController",$scope)}])},"./src/maasserver/static/js/angular/controllers/node_details_storage_filesystems.js":function(module,exports){!function(){function SpecialFilesystem(){this.fstype="tmpfs",this.mountPoint="",this.mountOptions=""}SpecialFilesystem.prototype.isValid=function(){return this.mountPoint.startsWith("/")},SpecialFilesystem.prototype.describe=function(){var parts=[this.fstype];switch(this.mountPoint.startsWith("/")&&parts.push("at "+this.mountPoint),this.fstype){case"tmpfs":var size=this.mountOptions.match(/\bsize=(\d+)(%?)/);null!==size&&("%"===size[2]?parts.push("limited to "+size[1]+"% of memory"):parts.push("limited to "+size[1]+" bytes"))}return parts.join(" ")},angular.module("MAAS").controller("NodeFilesystemsController",["$scope",function($scope){$scope.dropdown=null,$scope.addSpecialFilesystem=function(){$scope.dropdown="special"},$scope.addSpecialFilesystemFinished=function(){"special"===$scope.dropdown&&($scope.dropdown=null)}}]),angular.module("MAAS").controller("NodeAddSpecialFilesystemController",["$scope","MachinesManager",function($scope,MachinesManager){$scope.filesystem=new SpecialFilesystem,$scope.description=null,$scope.$watch("filesystem",function(filesystem){$scope.description=filesystem.describe()},!0),$scope.canMount=function(){return $scope.filesystem.isValid()},$scope.mount=function(){MachinesManager.mountSpecialFilesystem($scope.node,$scope.filesystem.fstype,$scope.filesystem.mountPoint,$scope.filesystem.mountOptions),$scope.addSpecialFilesystemFinished()},$scope.cancel=function(){$scope.filesystem=new SpecialFilesystem,$scope.addSpecialFilesystemFinished()}}])}()},"./src/maasserver/static/js/angular/controllers/node_events.js":function(module,exports){angular.module("MAAS").controller("NodeEventsController",["$scope","$rootScope","$routeParams","$location","MachinesManager","ControllersManager","EventsManagerFactory","ManagerHelperService","ErrorService",function($scope,$rootScope,$routeParams,$location,MachinesManager,ControllersManager,EventsManagerFactory,ManagerHelperService,ErrorService){var eventsManager=null;function nodeLoaded(node){$scope.node=node,$scope.loaded=!0,eventsManager=EventsManagerFactory.getManager(node.id),$scope.events=eventsManager.getItems(),$scope.days=eventsManager.getMaximumDays(),eventsManager.loadItems().then(function(){$scope.eventsLoaded=!0}),$scope.$watch("node.fqdn",function(){$rootScope.title=$scope.node.fqdn+" - events"})}$rootScope.title="Loading...",$scope.loaded=!1,$scope.node=null,$scope.events=[],$scope.eventsLoaded=!1,$scope.days=1,$scope.getEventText=function(event){var text=event.type.description;return angular.isString(event.description)&&event.description.length>0&&(text+=" - "+event.description),text},$scope.loadMore=function(){$scope.days+=1,eventsManager.loadMaximumDays($scope.days)},-1!==$location.path().indexOf("/controller")?($scope.nodesManager=ControllersManager,$scope.type_name="controller",$rootScope.page="controllers"):($scope.nodesManager=MachinesManager,$scope.type_name="machine",$rootScope.page="machines"),ManagerHelperService.loadManager($scope,$scope.nodesManager).then(function(){var activeNode=$scope.nodesManager.getActiveItem();angular.isObject(activeNode)&&activeNode.system_id===$routeParams.system_id?nodeLoaded(activeNode):$scope.nodesManager.setActiveItem($routeParams.system_id).then(function(node){nodeLoaded(node)},function(error){ErrorService.raiseError(error)})}),$scope.$on("$destroy",function(){angular.isObject(eventsManager)&&eventsManager.destroy()})}])},"./src/maasserver/static/js/angular/controllers/node_result.js":function(module,exports){angular.module("MAAS").controller("NodeResultController",["$scope","$rootScope","$routeParams","$location","MachinesManager","ControllersManager","NodeResultsManagerFactory","ManagerHelperService","ErrorService",function($scope,$rootScope,$routeParams,$location,MachinesManager,ControllersManager,NodeResultsManagerFactory,ManagerHelperService,ErrorService){function nodeLoaded(node){$scope.node=node,$scope.loaded=!0;var nodeResultsManager=NodeResultsManagerFactory.getManager($scope.node),requestedResult=parseInt($routeParams.id,10);nodeResultsManager.getItem(requestedResult).then(function(result){$scope.result=result,$scope.get_result_data($scope.output),$scope.resultLoaded=!0,$rootScope.title=$scope.node.fqdn+" - "+$scope.result.name})}$rootScope.title="Loading...",$scope.loaded=!1,$scope.resultLoaded=!1,$scope.node=null,$scope.output="combined",$scope.result=null,$scope.get_result_data=function(output){$scope.output=output,$scope.data="Loading...",NodeResultsManagerFactory.getManager($scope.node).get_result_data($scope.result.id,$scope.output).then(function(data){$scope.data=""===data?"Empty file.":data})},$scope.$watch("node.fqdn",function(){angular.isObject($scope.node)&&angular.isObject($scope.result)&&($rootScope.title=$scope.node.fqdn+" - "+$scope.result.name)}),-1!==$location.path().indexOf("/controller")?($scope.nodesManager=ControllersManager,$scope.type_name="controller",$rootScope.page="controllers"):($scope.nodesManager=MachinesManager,$scope.type_name="machine",$rootScope.page="machines"),ManagerHelperService.loadManager($scope,$scope.nodesManager).then(function(){var activeNode=$scope.nodesManager.getActiveItem();angular.isObject(activeNode)&&activeNode.system_id===$routeParams.system_id?nodeLoaded(activeNode):$scope.nodesManager.setActiveItem($routeParams.system_id).then(function(node){nodeLoaded(node)},function(error){ErrorService.raiseError(error)})}),$scope.$on("$destroy",function(){var nodeResultsManager=NodeResultsManagerFactory.getManager($scope.node);angular.isObject(nodeResultsManager)&&nodeResultsManager.destroy()})}])},"./src/maasserver/static/js/angular/controllers/node_results.js":function(module,exports){angular.module("MAAS").controller("NodeResultsController",["$scope","$routeParams","$location","MachinesManager","ControllersManager","NodeResultsManagerFactory","ManagerHelperService","ErrorService",function($scope,$routeParams,$location,MachinesManager,ControllersManager,NodeResultsManagerFactory,ManagerHelperService,ErrorService){function updateLogs(){var i,had_installation=3===$scope.logs.availableOptions.length;if($scope.logs.availableOptions.length=0,$scope.installation_results&&$scope.installation_results.length>0&&(6===$scope.node.status_code||9===$scope.node.status_code||11===$scope.node.status_code))for(i=0;i<$scope.installation_results.length;i++)if("/tmp/install.log"===$scope.installation_results[i].name){$scope.logs.availableOptions.push({title:"Installation output",id:$scope.installation_results[i].id});break}$scope.logs.availableOptions.push({title:"Machine output (YAML)",id:"summary_yaml"}),$scope.logs.availableOptions.push({title:"Machine output (XML)",id:"summary_xml"}),had_installation||3!==$scope.logs.availableOptions.length?(!$scope.selectedLog||had_installation&&2===$scope.logs.length)&&($scope.logs.option=$scope.logs.availableOptions[0]):$scope.logs.option=$scope.logs.availableOptions[0]}function nodeLoaded(node){$scope.node=node,$scope.loaded=!0,$scope.nodeResultsManager=NodeResultsManagerFactory.getManager(node,$scope.section.area),$scope.nodeResultsManager.loadItems().then(function(){$scope.commissioning_results=$scope.nodeResultsManager.commissioning_results,$scope.testing_results=$scope.nodeResultsManager.testing_results,$scope.installation_results=$scope.nodeResultsManager.installation_results,$scope.results=$scope.nodeResultsManager.results,"logs"===$scope.section.area&&(updateLogs(),$scope.$watch("installation_results",updateLogs,!0),$scope.$watch("installation_results",$scope.updateLogOutput,!0)),$scope.resultsLoaded=!0})}$scope.nodeResultsManager=null,$scope.commissioning_results=null,$scope.testing_results=null,$scope.installation_results=null,$scope.results=null,$scope.logs={option:null,availableOptions:[]},$scope.logOutput="Loading...",$scope.loaded=!1,$scope.resultsLoaded=!1,$scope.node=null,-1!==$location.path().indexOf("/controller")?$scope.nodesManager=ControllersManager:$scope.nodesManager=MachinesManager,ManagerHelperService.loadManager($scope,$scope.nodesManager).then(function(){var activeNode=$scope.nodesManager.getActiveItem();angular.isObject(activeNode)&&activeNode.system_id===$routeParams.system_id?nodeLoaded(activeNode):$scope.nodesManager.setActiveItem($routeParams.system_id).then(function(node){nodeLoaded(node)},function(error){ErrorService.raiseError(error)})}),$scope.updateLogOutput=function(){if($scope.logOutput="Loading...",$scope.node)if("summary_xml"===$scope.logs.option.id)$scope.nodesManager.getSummaryXML($scope.node).then(function(output){$scope.logOutput=output});else if("summary_yaml"===$scope.logs.option.id)$scope.nodesManager.getSummaryYAML($scope.node).then(function(output){$scope.logOutput=output});else{var i,result=null;for(i=0;i<$scope.installation_results.length;i++)if($scope.installation_results[i].id===$scope.logs.option.id){result=$scope.installation_results[i];break}switch(result.status){case 0:$scope.logOutput="System is booting...";break;case 1:$scope.logOutput="Installation has begun!";break;case 2:$scope.nodeResultsManager.get_result_data(result.id,"combined").then(function(output){$scope.logOutput=""===output?"Installation has succeeded but no output was given.":output});break;case 3:$scope.nodeResultsManager.get_result_data(result.id,"combined").then(function(output){$scope.logOutput=""===output?"Installation has failed and no output was given.":output});break;case 4:$scope.logOutput="Installation failed after 40 minutes.";break;case 5:$scope.logOutput="Installation was aborted.";break;default:$scope.logOutput="BUG: Unknown log status "+result.status}}},$scope.loadHistory=function(result){result.showing_results=!1,angular.isArray(result.history_list)?result.showing_history=!0:(result.loading_history=!0,$scope.nodeResultsManager.get_history(result.id).then(function(history){result.history_list=history,result.loading_history=!1,result.showing_history=!0}))},$scope.$on("$destroy",function(){angular.isObject($scope.nodeResultsManager)&&$scope.nodeResultsManager.destroy()})}])},"./src/maasserver/static/js/angular/controllers/nodes_list.js":function(module,exports){angular.module("MAAS").controller("NodesListController",["$q","$scope","$interval","$rootScope","$routeParams","$location","MachinesManager","DevicesManager","ControllersManager","GeneralManager","ManagerHelperService","SearchService","ZonesManager","UsersManager","ServicesManager","ScriptsManager","SwitchesManager","ResourcePoolsManager",function($q,$scope,$interval,$rootScope,$routeParams,$location,MachinesManager,DevicesManager,ControllersManager,GeneralManager,ManagerHelperService,SearchService,ZonesManager,UsersManager,ServicesManager,ScriptsManager,SwitchesManager,ResourcePoolsManager){var DEVICE_IP_ASSIGNMENT={external:"External",dynamic:"Dynamic",static:"Static"};function isViewingSelected(tab){var search=$scope.tabs[tab].search.toLowerCase();return"in:(selected)"===search||"in:selected"===search}function enterViewSelected(tab){$scope.tabs[tab].previous_search=$scope.tabs[tab].search,$scope.tabs[tab].search="in:(Selected)"}function leaveViewSelected(tab){isViewingSelected(tab)&&($scope.tabs[tab].search=$scope.tabs[tab].previous_search,$scope.updateFilters(tab))}function updateAllViewableChecked(tab){if(0!==$scope.tabs[tab].filtered_items.length){var i;for(i=0;i<$scope.tabs[tab].filtered_items.length;i++)if(!$scope.tabs[tab].filtered_items[i].$selected)return void($scope.tabs[tab].allViewableChecked=!1);$scope.tabs[tab].allViewableChecked=!0}else $scope.tabs[tab].allViewableChecked=!1}function clearAction(tab){resetActionProgress(tab),leaveViewSelected(tab),$scope.tabs[tab].actionOption=null,$scope.tabs[tab].zoneSelection=null,$scope.tabs[tab].poolSelection=null,$scope.tabs[tab].poolAction="select-pool",$scope.tabs[tab].newPool={},"machines"!==tab&&"switches"!==tab||(angular.isFunction($scope.tabs[tab].osSelection.$reset)&&$scope.tabs[tab].osSelection.$reset(),$scope.tabs[tab].commissionOptions.enableSSH=!1,$scope.tabs[tab].commissionOptions.skipNetworking=!1,$scope.tabs[tab].commissionOptions.skipStorage=!1,$scope.tabs[tab].commissionOptions.updateFirmware=!1,$scope.tabs[tab].commissionOptions.configureHBA=!1),$scope.tabs[tab].commissioningSelection=[],$scope.tabs[tab].testSelection=[]}function shouldClearAction(tab){0===$scope.tabs[tab].selectedItems.length&&clearAction(tab),$scope.tabs[tab].actionOption&&!isViewingSelected(tab)&&($scope.tabs[tab].actionOption=null)}function removeEmptyFilter(tab){0===$scope.tabs[tab].filtered_items.length&&""!==$scope.tabs[tab].search&&$scope.tabs[tab].search===$scope.tabs[tab].previous_search&&($scope.tabs[tab].search="",$scope.updateFilters(tab))}function updateActionErrorCount(tab){var i;for($scope.tabs[tab].actionErrorCount=0,i=0;i<$scope.tabs[tab].selectedItems.length;i++){$scope.supportsAction($scope.tabs[tab].selectedItems[i],tab)||($scope.tabs[tab].actionErrorCount+=1),$scope.tabs[tab].selectedItems[i].action_failed=!1}}function resetActionProgress(tab){var progress=$scope.tabs[tab].actionProgress;progress.completed=progress.total=0,progress.errors={},progress.showing_confirmation=!1,progress.affected_nodes=0}function addErrorToActionProgress(tab,error,node){var progress=$scope.tabs[tab].actionProgress;progress.completed+=1;var nodes=progress.errors[error];angular.isUndefined(nodes)?progress.errors[error]=[node]:nodes.push(node)}function updateSelectedItems(tab){$scope.hasActionsFailed(tab)?angular.forEach($scope.tabs[tab].manager.getItems(),function(node){!1===node.action_failed&&$scope.tabs[tab].manager.unselectItem(node.system_id)}):$scope.hasActionsInProgress(tab)||(clearAction(tab),enterViewSelected(tab))}$rootScope.title="Machines",$rootScope.page="machines",$scope.MAAS_config=MAAS_config,$scope.machines=MachinesManager.getItems(),$scope.zones=ZonesManager.getItems(),$scope.pools=ResourcePoolsManager.getItems(),$scope.devices=DevicesManager.getItems(),$scope.controllers=ControllersManager.getItems(),$scope.switches=SwitchesManager.getItems(),$scope.showswitches="on"===$routeParams.switches,$scope.currentpage="machines",$scope.osinfo={},$scope.scripts=ScriptsManager.getItems(),$scope.loading=!0,$scope.tabs={},$scope.pluralize=function(tab){var verb={machines:"machine",switches:"switch",devices:"device",controllers:"controller"}[tab];return $scope.tabs[tab].selectedItems.length>1&&(verb=tab),verb},$scope.tabs.machines={},$scope.tabs.machines.pagetitle="Machines",$scope.tabs.machines.currentpage="machines",$scope.tabs.machines.manager=MachinesManager,$scope.tabs.machines.previous_search="",$scope.tabs.machines.search="",$scope.tabs.machines.searchValid=!0,$scope.tabs.machines.selectedItems=MachinesManager.getSelectedItems(),$scope.tabs.machines.metadata=MachinesManager.getMetadata(),$scope.tabs.machines.filters=SearchService.getEmptyFilter(),$scope.tabs.machines.actionOption=null,$scope.tabs.machines.takeActionOptions=[],$scope.tabs.machines.actionErrorCount=0,$scope.tabs.machines.actionProgress={total:0,completed:0,errors:{},showing_confirmation:!1,affected_nodes:0},$scope.tabs.machines.osSelection={osystem:null,release:null,hwe_kernel:null},$scope.tabs.machines.zoneSelection=null,$scope.tabs.machines.poolSelection=null,$scope.tabs.machines.poolAction="select-pool",$scope.tabs.machines.newPool={},$scope.tabs.machines.commissionOptions={enableSSH:!1,skipNetworking:!1,skipStorage:!1,updateFirmware:!1,configureHBA:!1},$scope.tabs.machines.releaseOptions={},$scope.tabs.machines.commissioningSelection=[],$scope.tabs.machines.testSelection=[],$scope.tabs.pools={},$scope.tabs.pools.pagetitle="Machines",$scope.tabs.pools.currentpage="pools",$scope.tabs.pools.manager=ResourcePoolsManager,$scope.tabs.pools.actionOption=!1,$scope.tabs.pools.newPool={name:null,description:null},$scope.tabs.pools.addPool=function(){$scope.tabs.pools.actionOption=!0},$scope.tabs.pools.cancelAddPool=function(){$scope.tabs.pools.actionOption=!1,$scope.tabs.pools.newPool={}},$scope.tabs.pools.activeTarget=null,$scope.tabs.pools.activeTargetAction=null,$scope.tabs.pools.actionErrorMessage=null,$scope.tabs.pools.initiatePoolAction=function(pool,action){var tab=$scope.tabs.pools;tab.cancelPoolAction(),tab.activeTargetAction=action,tab.activeTarget=pool,tab.editingPool=pool},$scope.tabs.pools.cancelPoolAction=function(){var tab=$scope.tabs.pools;tab.activeTargetAction=null,tab.activeTarget=null,tab.actionErrorMessage=null},$scope.tabs.pools.isPoolAction=function(pool,action){var tab=$scope.tabs.pools;return(void 0===action||tab.activeTargetAction===action)&&null!==tab.activeTarget&&tab.activeTarget.id===pool.id},$scope.tabs.pools.actionConfirmEditPool=function(){$scope.tabs.pools.cancelPoolAction()},$scope.tabs.pools.actionConfirmDeletePool=function(){var tab=$scope.tabs.pools;tab.manager.deleteItem(tab.activeTarget).then(tab.cancelPoolAction,function(error){$scope.tabs.pools.actionErrorMessage=error})},$scope.tabs.pools.goToPoolMachines=function(pool){$scope.clearSearch("machines"),$scope.toggleFilter("pool",pool.name,"machines"),$scope.toggleTab("machines"),$location.path("/machines")},$scope.tabs.pools.isDefaultPool=function(pool){return 0===pool.id},$scope.tabs.devices={},$scope.tabs.devices.pagetitle="Devices",$scope.tabs.devices.currentpage="devices",$scope.tabs.devices.manager=DevicesManager,$scope.tabs.devices.previous_search="",$scope.tabs.devices.search="",$scope.tabs.devices.searchValid=!0,$scope.tabs.devices.selectedItems=DevicesManager.getSelectedItems(),$scope.tabs.devices.filtered_items=[],$scope.tabs.devices.predicate="fqdn",$scope.tabs.devices.allViewableChecked=!1,$scope.tabs.devices.metadata=DevicesManager.getMetadata(),$scope.tabs.devices.filters=SearchService.getEmptyFilter(),$scope.tabs.devices.column="fqdn",$scope.tabs.devices.actionOption=null,$scope.tabs.devices.takeActionOptions=[],$scope.tabs.devices.actionErrorCount=0,$scope.tabs.devices.actionProgress={total:0,completed:0,errors:{},showing_confirmation:!1,affected_nodes:0},$scope.tabs.devices.zoneSelection=null,$scope.tabs.devices.poolSelection=null,$scope.tabs.devices.poolAction="select-pool",$scope.tabs.devices.newPool={},$scope.tabs.controllers={},$scope.tabs.controllers.pagetitle="Controllers",$scope.tabs.controllers.currentpage="controllers",$scope.tabs.controllers.manager=ControllersManager,$scope.tabs.controllers.previous_search="",$scope.tabs.controllers.search="",$scope.tabs.controllers.searchValid=!0,$scope.tabs.controllers.selectedItems=ControllersManager.getSelectedItems(),$scope.tabs.controllers.filtered_items=[],$scope.tabs.controllers.predicate="fqdn",$scope.tabs.controllers.allViewableChecked=!1,$scope.tabs.controllers.metadata=ControllersManager.getMetadata(),$scope.tabs.controllers.filters=SearchService.getEmptyFilter(),$scope.tabs.controllers.column="fqdn",$scope.tabs.controllers.actionOption=null,$scope.tabs.controllers.takeActionOptions=[],$scope.tabs.controllers.actionErrorCount=0,$scope.tabs.controllers.actionProgress={total:0,completed:0,errors:{},showing_confirmation:!1,affected_nodes:0},$scope.tabs.controllers.zoneSelection=null,$scope.tabs.controllers.poolSelection=null,$scope.tabs.controllers.poolAction="select-pool",$scope.tabs.controllers.newPool={},$scope.tabs.controllers.syncStatuses={},$scope.tabs.controllers.addController=!1,$scope.tabs.controllers.registerUrl=MAAS_config.register_url,$scope.tabs.controllers.registerSecret=MAAS_config.register_secret,$scope.tabs.switches={},$scope.tabs.switches.pagetitle="Switches",$scope.tabs.switches.currentpage="switches",$scope.tabs.switches.manager=SwitchesManager,$scope.tabs.switches.previous_search="",$scope.tabs.switches.search="",$scope.tabs.switches.searchValid=!0,$scope.tabs.switches.selectedItems=SwitchesManager.getSelectedItems(),$scope.tabs.switches.predicate="fqdn",$scope.tabs.switches.allViewableChecked=!1,$scope.tabs.switches.metadata=SwitchesManager.getMetadata(),$scope.tabs.switches.filters=SearchService.getEmptyFilter(),$scope.tabs.switches.column="fqdn",$scope.tabs.switches.actionOption=null,$scope.tabs.switches.takeActionOptions=[],$scope.tabs.switches.actionErrorCount=0,$scope.tabs.switches.actionProgress={total:0,completed:0,errors:{},showing_confirmation:!1,affected_nodes:0},$scope.tabs.switches.osSelection={osystem:null,release:null,hwe_kernel:null},$scope.tabs.switches.zoneSelection=null,$scope.tabs.switches.poolSelection=null,$scope.tabs.switches.poolAction="select-pool",$scope.tabs.switches.newPool={},$scope.tabs.switches.commissioningSelection=[],$scope.tabs.switches.commissionOptions={enableSSH:!1,skipNetworking:!1,skipStorage:!1,updateFirmware:!1,configureHBA:!1},$scope.tabs.switches.releaseOptions={},$scope.addHardwareOption=null,$scope.addHardwareOptions=[{name:"machine",title:"Machine"},{name:"chassis",title:"Chassis"}],$scope.addHardwareScope=null,$scope.addDeviceScope=null,$scope.$on("addHardwareHidden",function(){$scope.addHardwareOption=null}),$scope.toggleTab=function(tab){switch($rootScope.title=$scope.tabs[tab].pagetitle,$rootScope.page=tab,$scope.currentpage=tab,tab){case"machines":$scope.osinfo=GeneralManager.getData("osinfo"),$scope.tabs.machines.takeActionOptions=GeneralManager.getData("machine_actions");break;case"devices":$scope.tabs.devices.takeActionOptions=GeneralManager.getData("device_actions");break;case"controllers":$scope.tabs.controllers.takeActionOptions=GeneralManager.getData("rack_controller_actions");break;case"switches":$scope.tabs.switches.takeActionOptions=GeneralManager.getData("machine_actions")}},$scope.clearSearch=function(tab){$scope.tabs[tab].search="",$scope.updateFilters(tab)},$scope.toggleChecked=function(node,tab){"machines"!==tab&&"switches"!==tab&&($scope.tabs[tab].manager.isSelected(node.system_id)?$scope.tabs[tab].manager.unselectItem(node.system_id):$scope.tabs[tab].manager.selectItem(node.system_id),updateAllViewableChecked(tab)),updateActionErrorCount(t

Subscribers

People subscribed via source and target branches