'use strict';goog.provide("grrUi.core.utils.CLIENT_ID_RE");goog.provide("grrUi.core.utils.camelCaseToDashDelimited");goog.provide("grrUi.core.utils.getLastPathComponent");goog.provide("grrUi.core.utils.stringToList");goog.provide("grrUi.core.utils.stripAff4Prefix");goog.provide("grrUi.core.utils.upperCaseToTitleCase");grrUi.core.utils.CLIENT_ID_RE=/^C\.[0-9a-fA-F]{16}$/;
grrUi.core.utils.camelCaseToDashDelimited=function(input){return input.replace(/\W+/g,"-").replace(/([A-Z])/g,"-$1").replace(/^-+/,"").replace(/-+$/,"").toLowerCase()};grrUi.core.utils.upperCaseToTitleCase=function(input){return(input.charAt(0).toUpperCase()+input.slice(1).toLowerCase()).replace(/_/g," ")};grrUi.core.utils.stringToList=function(input){var result=[];angular.forEach((input||"").split(","),function(item){item=item.trim();if(item)result.push(item)});return result};
grrUi.core.utils.stripAff4Prefix=function(input){var aff4Prefix="aff4:/";if(input.toLowerCase().indexOf(aff4Prefix)==0)return input.substr(aff4Prefix.length);else return input};grrUi.core.utils.getLastPathComponent=function(input){var components=input.split("/");return components[components.length-1]};goog.provide("grrUi.acl.requestApprovalDialogDirective.RequestApprovalDialogController");goog.provide("grrUi.acl.requestApprovalDialogDirective.RequestApprovalDialogDirective");goog.require("grrUi.core.utils.stringToList");
goog.scope(function(){var stringToList=grrUi.core.utils.stringToList;grrUi.acl.requestApprovalDialogDirective.RequestApprovalDialogController=function($scope,$q,grrApiService){this.scope_=$scope;this.q_=$q;this.grrApiService_=grrApiService;this.subjectTitle;this.ccAddresses=[];this.recentReasons;this.selectedRecentReason;this.approversList;this.reason;this.useCcAddresses=true;this.keepClientAlive=true;this.scope_.$watch("approvalType",this.onApprovalTypeChange_.bind(this));this.scope_.$watch("controller.selectedRecentReason",
this.onSelectedRecentReasonChange_.bind(this));this.grrApiService_.getCached("/config/Email.approval_optional_cc_address").then(this.onCcAddressResponse_.bind(this));this.grrApiService_.get("/users/me/approvals/client",{count:7}).then(this.onLatestApprovalsResponse_.bind(this))};var RequestApprovalDialogController=grrUi.acl.requestApprovalDialogDirective.RequestApprovalDialogController;RequestApprovalDialogController.prototype.onApprovalTypeChange_=function(newValue){if(angular.isString(newValue))this.subjectTitle=
newValue.charAt(0).toUpperCase()+newValue.slice(1).replace("-"," ")};RequestApprovalDialogController.prototype.onSelectedRecentReasonChange_=function(newValue){if(angular.isString(newValue)&&newValue)this.reason=newValue};RequestApprovalDialogController.prototype.onCcAddressResponse_=function(response){this.ccAddresses=stringToList(response["data"]["value"]["value"])};RequestApprovalDialogController.prototype.onLatestApprovalsResponse_=function(response){this.recentReasons=[];var items=response["data"]["items"];
for(var i=0;i<items.length;++i){var reason=items[i]["value"]["reason"]["value"];if(this.recentReasons.indexOf(reason)===-1)this.recentReasons.push(reason)}};RequestApprovalDialogController.prototype.proceed=function(){var deferred=this.q_.defer();var url=this.scope_["createRequestUrl"];var args=angular.copy(this.scope_["createRequestArgs"]);args["approval"]["reason"]=this.reason;args["approval"]["notified_users"]=stringToList(this.approversList);if(this.useCcAddresses&&this.ccAddresses)args["approval"]["email_cc_addresses"]=
this.ccAddresses;if(this.scope_["approvalType"]==="client"&&this.keepClientAlive)args["keep_client_alive"]=true;this.grrApiService_.post(url,args).then(function success(){deferred.resolve("Approval request was sent.")},function failure(response){deferred.reject(response["data"]["message"])});return deferred.promise};grrUi.acl.requestApprovalDialogDirective.RequestApprovalDialogDirective=function(){return{scope:{approvalType:"=",createRequestUrl:"=",createRequestArgs:"=",accessErrorDescription:"="},
restrict:"E",templateUrl:"/static/angular-components/acl/"+"request-approval-dialog.html",controller:RequestApprovalDialogController,controllerAs:"controller"}};grrUi.acl.requestApprovalDialogDirective.RequestApprovalDialogDirective.directive_name="grrRequestApprovalDialog"});goog.provide("grrUi.acl.aclDialogService.AclDialogService");goog.require("grrUi.acl.requestApprovalDialogDirective.RequestApprovalDialogDirective");goog.require("grrUi.core.utils.stripAff4Prefix");
goog.scope(function(){grrUi.acl.aclDialogService.AclDialogService=function($rootScope,grrDialogService){this.rootScope_=$rootScope;this.grrDialogService_=grrDialogService};var AclDialogService=grrUi.acl.aclDialogService.AclDialogService;AclDialogService.service_name="grrAclDialogService";AclDialogService.prototype.openRequestApprovalDialog=function(approvalType,createRequestUrl,createRequestArgs,opt_accessErrorDescription){$(".modal-dialog:visible").each(function(){$(this).scope()["$parent"]["$dismiss"]()});
var directive=grrUi.acl.requestApprovalDialogDirective.RequestApprovalDialogDirective;return this.grrDialogService_.openDirectiveDialog(directive.directive_name,{approvalType:approvalType,createRequestUrl:createRequestUrl,createRequestArgs:createRequestArgs,accessErrorDescription:opt_accessErrorDescription})};AclDialogService.prototype.openRequestClientApprovalDialog=function(clientId,opt_accessErrorDescription){return this.openRequestApprovalDialog("client","/users/me/approvals/client/"+clientId,
{client_id:clientId,approval:{}},opt_accessErrorDescription)};AclDialogService.prototype.openRequestHuntApprovalDialog=function(huntId,opt_accessErrorDescription){return this.openRequestApprovalDialog("hunt","/users/me/approvals/hunt/"+huntId,{hunt_id:huntId,approval:{}},opt_accessErrorDescription)};AclDialogService.prototype.openRequestCronJobApprovalDialog=function(cronJobId,opt_accessErrorDescription){return this.openRequestApprovalDialog("cron-job","/users/me/approvals/cron-job/"+cronJobId,{cron_job_id:cronJobId,
approval:{}},opt_accessErrorDescription)};AclDialogService.prototype.openApprovalDialogForSubject=function(subject,message){var components=grrUi.core.utils.stripAff4Prefix(subject).split("/");if(/^C\.[0-9a-fA-F]{16}$/.test(components[0]))this.openRequestClientApprovalDialog(components[0],message);else if(components[0]=="hunts")this.openRequestHuntApprovalDialog(components[1],message);else if(components[0]=="cron")this.openRequestCronJobApprovalDialog(components[1],message);else throw new Error("Can't determine type of resources.");
}});goog.provide("grrUi.core.apiService");goog.provide("grrUi.core.apiService.ApiService");goog.provide("grrUi.core.apiService.encodeUrlPath");goog.provide("grrUi.core.apiService.stripTypeInfo");
goog.scope(function(){var UNAUTHORIZED_API_RESPONSE_EVENT="UnauthorizedApiResponse";grrUi.core.apiService.UNAUTHORIZED_API_RESPONSE_EVENT=UNAUTHORIZED_API_RESPONSE_EVENT;grrUi.core.apiService.encodeUrlPath=function(urlPath){var components=urlPath.split("/");var encodedComponents=components.map(encodeURIComponent);return encodedComponents.join("/")};var encodeUrlPath=grrUi.core.apiService.encodeUrlPath;grrUi.core.apiService.stripTypeInfo=function(richlyTypedValue){var recursiveStrip=function(value){if(angular.isArray(value))value=
value.map(recursiveStrip);else if(angular.isDefined(value.value)){value=value.value;if(angular.isObject(value))for(var k in value)value[k]=recursiveStrip(value[k])}return value};return recursiveStrip(angular.copy(richlyTypedValue))};var stripTypeInfo=grrUi.core.apiService.stripTypeInfo;var wrapCancellablePromise_=function(promise){var cancel=promise["cancel"];if(angular.isUndefined(promise["_oldThen"])){promise["_oldThen"]=promise["then"];promise["then"]=function(onFulfilled,onRejected,progressBack){var result=
promise["_oldThen"](onFulfilled,onRejected,progressBack);result["cancel"]=cancel;return wrapCancellablePromise_(result)}}if(angular.isUndefined(promise["_oldCatch"])){promise["_oldCatch"]=promise["catch"];promise["catch"]=function(callback){var result=promise["_oldCatch"](callback);result["cancel"]=cancel;return wrapCancellablePromise_(result)}}if(angular.isUndefined(promise["_oldFinally"])){promise["_oldFinally"]=promise["finally"];promise["finally"]=function(callback,progressBack){var result=promise["_oldFinally"](callback,
progressBack);result["cancel"]=cancel;return wrapCancellablePromise_(result)}}return promise};grrUi.core.apiService.ApiService=function($http,$q,$interval,$rootScope,grrLoadingIndicatorService){this.http_=$http;this.q_=$q;this.interval_=$interval;this.rootScope_=$rootScope;this.grrLoadingIndicatorService_=grrLoadingIndicatorService;this.authDeferred_=this.q_.defer()};var ApiService=grrUi.core.apiService.ApiService;ApiService.service_name="grrApiService";ApiService.prototype.waitForAuth_=function(fn){return this.authDeferred_.promise.then(function(){return fn()})};
ApiService.prototype.markAuthDone=function(){this.authDeferred_.resolve()};ApiService.prototype.sendRequestWithoutPayload_=function(method,apiPath,opt_params,opt_requestSettings){var requestParams=angular.extend({},opt_params);var requestSettings=angular.extend({},opt_requestSettings);var loadingKey=this.grrLoadingIndicatorService_.startLoading();var apiPrefix="/api/";if(requestSettings["useV2"])apiPrefix+="v2/";var url=encodeUrlPath(apiPrefix+apiPath.replace(/^\//,""));return this.waitForAuth_(function(){var promise=
this.http_({method:method,url:url,params:requestParams,cache:requestSettings["cache"]});return promise.finally(function(){this.grrLoadingIndicatorService_.stopLoading(loadingKey)}.bind(this))}.bind(this))};ApiService.prototype.head=function(apiPath,opt_params){return this.sendRequestWithoutPayload_("HEAD",apiPath,opt_params)};ApiService.prototype.get=function(apiPath,opt_params){return this.sendRequestWithoutPayload_("GET",apiPath,opt_params)};ApiService.prototype.getV2=function(apiPath,opt_params){return this.sendRequestWithoutPayload_("GET",
apiPath,opt_params,{"useV2":true})};ApiService.prototype.getCached=function(apiPath,opt_params){return this.sendRequestWithoutPayload_("GET",apiPath,opt_params,{cache:true})};ApiService.prototype.poll=function(apiPath,intervalMs,opt_params,opt_checkFn){if(angular.isUndefined(opt_checkFn))opt_checkFn=function(response){return response["data"]["state"]==="FINISHED"}.bind(this);var result=this.q_.defer();var inProgress=false;var cancelled=false;var pollIteration=function(){inProgress=true;this.get(apiPath,
opt_params).then(function success(response){if(cancelled)return;result.notify(response);if(opt_checkFn(response))result.resolve(response)}.bind(this),function failure(response){if(cancelled)return;result.reject(response)}.bind(this)).finally(function(){if(cancelled)return;inProgress=false}.bind(this))}.bind(this);pollIteration();var intervalPromise=this.interval_(function(){if(!inProgress)pollIteration()}.bind(this),intervalMs);result.promise["cancel"]=function(){cancelled=true;this.interval_.cancel(intervalPromise)}.bind(this);
result.promise.finally(result.promise["cancel"]);return wrapCancellablePromise_(result.promise)};ApiService.prototype.cancelPoll=function(pollPromise){if(angular.isDefined(pollPromise)){if(angular.isUndefined(pollPromise["cancel"]))throw new Error("Invalid promise to cancel: not cancelable.");pollPromise["cancel"]()}};ApiService.prototype.downloadFile=function(apiPath,opt_params){var requestParams=angular.extend({},opt_params);var url=encodeUrlPath("/api/"+apiPath.replace(/^\//,""));return this.http_.head(url,
{params:requestParams}).then(function(){var paramsString=Object.keys(requestParams).sort().map(function(key){return[key,requestParams[key]].map(encodeURIComponent).join("=")}).join("&");if(paramsString.length>0)url+="?"+paramsString;var deferred=this.q_.defer();var iframe=document.createElement("iframe");iframe.src=url;document.body.appendChild(iframe);var intervalPromise=this.interval_(function(){try{if(iframe.contentWindow.document.readyState==="complete"){this.interval_.cancel(intervalPromise);
deferred.resolve()}}catch(err){deferred.reject({data:{message:"Unknown error."}})}}.bind(this),500);return deferred.promise.finally(function(){this.interval_.cancel(intervalPromise)}.bind(this))}.bind(this),function failure(response){if(response.status==403){var headers=response.headers();this.rootScope_.$broadcast(UNAUTHORIZED_API_RESPONSE_EVENT,{subject:headers["x-grr-unauthorized-access-subject"],reason:headers["x-grr-unauthorized-access-reason"]})}return this.q_.reject(response)}.bind(this))};
ApiService.prototype.sendRequestWithPayload_=function(httpMethod,apiPath,opt_params,opt_stripTypeInfo,opt_files){if(opt_stripTypeInfo)opt_params=stripTypeInfo(opt_params);var request;if(angular.equals(opt_files||{},{}))request={method:httpMethod,url:encodeUrlPath("/api/"+apiPath.replace(/^\//,"")),data:opt_params,headers:{}};else{var fd=new FormData;angular.forEach(opt_files,function(value,key){fd.append(key,value)}.bind(this));fd.append("_params_",angular.toJson(opt_params||{}));request={method:httpMethod,
url:encodeUrlPath("/api/"+apiPath.replace(/^\//,"")),data:fd,transformRequest:angular.identity,headers:{"Content-Type":undefined}}}return this.waitForAuth_(function(){var loadingKey=this.grrLoadingIndicatorService_.startLoading();var promise=this.http_(request);return promise.finally(function(){this.grrLoadingIndicatorService_.stopLoading(loadingKey)}.bind(this))}.bind(this))};ApiService.prototype.post=function(apiPath,opt_params,opt_stripTypeInfo,opt_files){return this.sendRequestWithPayload_("POST",
apiPath,opt_params,opt_stripTypeInfo,opt_files)};ApiService.prototype.delete=function(apiPath,opt_params,opt_stripTypeInfo){return this.sendRequestWithPayload_("DELETE",apiPath,opt_params,opt_stripTypeInfo)};ApiService.prototype.patch=function(apiPath,opt_params,opt_stripTypeInfo){return this.sendRequestWithPayload_("PATCH",apiPath,opt_params,opt_stripTypeInfo)}});goog.provide("grrUi.acl.approvalInfoDirective.ApprovalInfoController");goog.provide("grrUi.acl.approvalInfoDirective.ApprovalInfoDirective");goog.require("grrUi.core.apiService.stripTypeInfo");
goog.scope(function(){var stripTypeInfo=grrUi.core.apiService.stripTypeInfo;grrUi.acl.approvalInfoDirective.ApprovalInfoController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.fetchUrl;this.grantUrl;this.approvalTypeTitle;this.approvalObject;this.requestSent;this.statusMessage;this.scope_.$watchGroup(["approvalType","objectId","approvalId"],this.onParamsChanged_.bind(this));this.scope_.$watch("controller.fetchUrl",this.onApprovalFetchUrlChanged_.bind(this))};
var ApprovalInfoController=grrUi.acl.approvalInfoDirective.ApprovalInfoController;ApprovalInfoController.prototype.onParamsChanged_=function(){if(angular.isString(this.scope_["approvalType"])&&angular.isString(this.scope_["username"])&&angular.isString(this.scope_["objectId"])&&angular.isString(this.scope_["approvalId"])){this.approvalTypeTitle=this.scope_["approvalType"].replace("-"," ");this.fetchUrl=["users",this.scope_["username"],"approvals",this.scope_["approvalType"],this.scope_["objectId"],
this.scope_["approvalId"]].join("/");this.grantUrl=this.fetchUrl+"/actions/grant"}};ApprovalInfoController.prototype.onApprovalFetchUrlChanged_=function(){this.approvalObject=null;if(angular.isString(this.fetchUrl))this.grrApiService_.get(this.fetchUrl).then(function(response){this.scope_["approvalObject"]=response["data"];this.approvalObject=stripTypeInfo(response["data"]);if(this.approvalObject["is_valid"]){this.requestSent=true;this.statusMessage="This approval has already been granted!"}}.bind(this))};
ApprovalInfoController.prototype.onClick=function(){if(!angular.isObject(this.approvalObject))return;this.requestSent=true;this.grrApiService_.post(this.grantUrl).then(function success(){this.statusMessage="Approval granted."}.bind(this),function failure(response){this.statusMessage="FAILURE: "+response["data"]["message"]}.bind(this))};grrUi.acl.approvalInfoDirective.ApprovalInfoDirective=function(){return{scope:{approvalType:"=",username:"=",objectId:"=",approvalId:"=",approvalObject:"="},restrict:"E",
templateUrl:"/static/angular-components/acl/approval-info.html",controller:ApprovalInfoController,controllerAs:"controller"}};grrUi.acl.approvalInfoDirective.ApprovalInfoDirective.directive_name="grrApprovalInfo"});goog.provide("grrUi.acl.clientApprovalViewDirective.ClientApprovalViewController");goog.provide("grrUi.acl.clientApprovalViewDirective.ClientApprovalViewDirective");
goog.scope(function(){grrUi.acl.clientApprovalViewDirective.ClientApprovalViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.username;this.clientId;this.approvalId;this.grrRoutingService_.uiOnParamsChanged(this.scope_,["username","clientId","approvalId"],function(params){this.username=params[0];this.clientId=params[1];this.approvalId=params[2]}.bind(this))};var ClientApprovalViewController=grrUi.acl.clientApprovalViewDirective.ClientApprovalViewController;
grrUi.acl.clientApprovalViewDirective.ClientApprovalViewDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/acl/client-approval-view.html",controller:ClientApprovalViewController,controllerAs:"controller"}};grrUi.acl.clientApprovalViewDirective.ClientApprovalViewDirective.directive_name="grrClientApprovalView"});goog.provide("grrUi.acl.cronJobApprovalViewDirective.CronJobApprovalViewController");goog.provide("grrUi.acl.cronJobApprovalViewDirective.CronJobApprovalViewDirective");
goog.scope(function(){grrUi.acl.cronJobApprovalViewDirective.CronJobApprovalViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.username;this.cronJobId;this.approvalId;this.grrRoutingService_.uiOnParamsChanged(this.scope_,["username","cronJobId","approvalId"],function(params){this.username=params[0];this.cronJobId=params[1];this.approvalId=params[2]}.bind(this))};var CronJobApprovalViewController=grrUi.acl.cronJobApprovalViewDirective.CronJobApprovalViewController;
grrUi.acl.cronJobApprovalViewDirective.CronJobApprovalViewDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/acl/cron-job-approval-view.html",controller:CronJobApprovalViewController,controllerAs:"controller"}};grrUi.acl.cronJobApprovalViewDirective.CronJobApprovalViewDirective.directive_name="grrCronJobApprovalView"});goog.provide("grrUi.acl.huntApprovalViewDirective.HuntApprovalViewController");goog.provide("grrUi.acl.huntApprovalViewDirective.HuntApprovalViewDirective");
goog.scope(function(){grrUi.acl.huntApprovalViewDirective.HuntApprovalViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.username;this.huntId;this.approvalId;this.approvalObject;this.grrRoutingService_.uiOnParamsChanged(this.scope_,["username","huntId","approvalId"],function(params){this.username=params[0];this.huntId=params[1];this.approvalId=params[2]}.bind(this))};var HuntApprovalViewController=grrUi.acl.huntApprovalViewDirective.HuntApprovalViewController;
grrUi.acl.huntApprovalViewDirective.HuntApprovalViewDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/acl/hunt-approval-view.html",controller:HuntApprovalViewController,controllerAs:"controller"}};grrUi.acl.huntApprovalViewDirective.HuntApprovalViewDirective.directive_name="grrHuntApprovalView"});goog.provide("grrUi.acl.huntFromFlowCopyReviewDirective.HuntFromFlowCopyReviewController");goog.provide("grrUi.acl.huntFromFlowCopyReviewDirective.HuntFromFlowCopyReviewDirective");
goog.scope(function(){grrUi.acl.huntFromFlowCopyReviewDirective.HuntFromFlowCopyReviewController=function($scope,grrRoutingService){this.scope_=$scope;this.sourceFlow;this.newFlow;this.scope_.$watchGroup(["sourceFlow","newHunt"],this.onValuesChanged_.bind(this))};var HuntFromFlowCopyReviewController=grrUi.acl.huntFromFlowCopyReviewDirective.HuntFromFlowCopyReviewController;HuntFromFlowCopyReviewController.prototype.onValuesChanged_=function(){if(angular.isDefined(this.scope_["sourceFlow"])&&angular.isDefined(this.scope_["newHunt"])){this.sourceFlow=
this.scope_["sourceFlow"];this.newFlow=angular.copy(this.sourceFlow);var newHunt=this.scope_["newHunt"];this.newFlow["value"]["name"]=newHunt["value"]["flow_name"];this.newFlow["value"]["args"]=newHunt["value"]["flow_args"]}};grrUi.acl.huntFromFlowCopyReviewDirective.HuntFromFlowCopyReviewDirective=function(){return{scope:{sourceFlow:"=",newHunt:"="},restrict:"E",templateUrl:"/static/angular-components/acl/hunt-from-flow-copy-review.html",controller:HuntFromFlowCopyReviewController,controllerAs:"controller"}};
grrUi.acl.huntFromFlowCopyReviewDirective.HuntFromFlowCopyReviewDirective.directive_name="grrHuntFromFlowCopyReview"});goog.provide("grrUi.acl.huntFromHuntCopyReviewDirective.HuntFromHuntCopyReviewDirective");goog.scope(function(){grrUi.acl.huntFromHuntCopyReviewDirective.HuntFromHuntCopyReviewDirective=function(){return{scope:{sourceHunt:"=",newHunt:"="},restrict:"E",templateUrl:"/static/angular-components/acl/hunt-from-hunt-copy-review.html"}};grrUi.acl.huntFromHuntCopyReviewDirective.HuntFromHuntCopyReviewDirective.directive_name="grrHuntFromHuntCopyReview"});goog.provide("grrUi.acl.module");goog.require("grrUi.acl.aclDialogService.AclDialogService");goog.require("grrUi.acl.approvalInfoDirective.ApprovalInfoDirective");goog.require("grrUi.acl.clientApprovalViewDirective.ClientApprovalViewDirective");goog.require("grrUi.acl.cronJobApprovalViewDirective.CronJobApprovalViewDirective");goog.require("grrUi.acl.huntApprovalViewDirective.HuntApprovalViewDirective");goog.require("grrUi.acl.huntFromFlowCopyReviewDirective.HuntFromFlowCopyReviewDirective");goog.require("grrUi.acl.huntFromHuntCopyReviewDirective.HuntFromHuntCopyReviewDirective");
goog.require("grrUi.acl.requestApprovalDialogDirective.RequestApprovalDialogDirective");goog.require("grrUi.core.apiService");grrUi.acl.module=angular.module("grrUi.acl",["grrUi.core"]);grrUi.acl.module.service(grrUi.acl.aclDialogService.AclDialogService.service_name,grrUi.acl.aclDialogService.AclDialogService);grrUi.acl.module.directive(grrUi.acl.approvalInfoDirective.ApprovalInfoDirective.directive_name,grrUi.acl.approvalInfoDirective.ApprovalInfoDirective);
grrUi.acl.module.directive(grrUi.acl.clientApprovalViewDirective.ClientApprovalViewDirective.directive_name,grrUi.acl.clientApprovalViewDirective.ClientApprovalViewDirective);grrUi.acl.module.directive(grrUi.acl.cronJobApprovalViewDirective.CronJobApprovalViewDirective.directive_name,grrUi.acl.cronJobApprovalViewDirective.CronJobApprovalViewDirective);grrUi.acl.module.directive(grrUi.acl.huntApprovalViewDirective.HuntApprovalViewDirective.directive_name,grrUi.acl.huntApprovalViewDirective.HuntApprovalViewDirective);
grrUi.acl.module.directive(grrUi.acl.huntFromFlowCopyReviewDirective.HuntFromFlowCopyReviewDirective.directive_name,grrUi.acl.huntFromFlowCopyReviewDirective.HuntFromFlowCopyReviewDirective);grrUi.acl.module.directive(grrUi.acl.huntFromHuntCopyReviewDirective.HuntFromHuntCopyReviewDirective.directive_name,grrUi.acl.huntFromHuntCopyReviewDirective.HuntFromHuntCopyReviewDirective);grrUi.acl.module.directive(grrUi.acl.requestApprovalDialogDirective.RequestApprovalDialogDirective.directive_name,grrUi.acl.requestApprovalDialogDirective.RequestApprovalDialogDirective);
grrUi.acl.module.run(function($rootScope,grrAclDialogService){var UNAUTHORIZED_API_RESPONSE_EVENT=grrUi.core.apiService.UNAUTHORIZED_API_RESPONSE_EVENT;$rootScope.$on(UNAUTHORIZED_API_RESPONSE_EVENT,function(event,data){grrAclDialogService.openApprovalDialogForSubject(data["subject"],data["reason"])})});goog.provide("grrUi.artifact.artifactDescriptorDirective.ArtifactDescriptorController");goog.provide("grrUi.artifact.artifactDescriptorDirective.ArtifactDescriptorDirective");
goog.scope(function(){grrUi.artifact.artifactDescriptorDirective.ArtifactDescriptorController=function($scope){this.scope_=$scope};var ArtifactDescriptorController=grrUi.artifact.artifactDescriptorDirective.ArtifactDescriptorController;grrUi.artifact.artifactDescriptorDirective.ArtifactDescriptorDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/artifact/artifact-descriptor.html",controller:ArtifactDescriptorController,controllerAs:"controller"}};grrUi.artifact.artifactDescriptorDirective.ArtifactDescriptorDirective.directive_name=
"grrArtifactDescriptor";grrUi.artifact.artifactDescriptorDirective.ArtifactDescriptorDirective.semantic_type="ArtifactDescriptor"});goog.provide("grrUi.artifact.artifactDescriptorsService.ArtifactDescriptorsService");
goog.scope(function(){grrUi.artifact.artifactDescriptorsService.ArtifactDescriptorsService=function($q,grrApiService){this.q_=$q;this.grrApiService_=grrApiService;this.fillCachePromise_;this.descriptorsCache_};var ArtifactDescriptorsService=grrUi.artifact.artifactDescriptorsService.ArtifactDescriptorsService;ArtifactDescriptorsService.prototype.fillCacheIfNeeded_=function(){if(this.fillCachePromise_)return this.fillCachePromise_;var deferred=this.q_.defer();if(!angular.isObject(this.descriptorsCache_)){this.grrApiService_.get("/artifacts").then(function success(response){this.descriptorsCache_=
{};angular.forEach(response["data"]["items"],function(descriptor){var name=descriptor["value"]["artifact"]["value"]["name"]["value"];this.descriptorsCache_[name]=descriptor}.bind(this));deferred.resolve()}.bind(this),function failure(response){deferred.reject(response["data"]["message"])}.bind(this)).finally(function(){this.fillCachePromise_=null}.bind(this));this.fillCachePromise_=deferred.promise}else deferred.resolve();return deferred.promise};ArtifactDescriptorsService.prototype.listDescriptors=
function(){return this.fillCacheIfNeeded_().then(function(){return angular.copy(this.descriptorsCache_)}.bind(this))};ArtifactDescriptorsService.prototype.getDescriptorByName=function(name){return this.fillCacheIfNeeded_().then(function(){return this.descriptorsCache_[name]}.bind(this))};ArtifactDescriptorsService.prototype.clearCache=function(){this.descriptorsCache_=null};ArtifactDescriptorsService.service_name="grrArtifactDescriptorsService"});goog.provide("grrUi.artifact.deleteArtifactsDialogDirective.DeleteArtifactsDialogController");goog.provide("grrUi.artifact.deleteArtifactsDialogDirective.DeleteArtifactsDialogDirective");
goog.scope(function(){grrUi.artifact.deleteArtifactsDialogDirective.DeleteArtifactsDialogController=function($scope,$q,grrApiService,grrArtifactDescriptorsService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrArtifactDescriptorsService_=grrArtifactDescriptorsService;this.q_=$q};var DeleteArtifactsDialogController=grrUi.artifact.deleteArtifactsDialogDirective.DeleteArtifactsDialogController;DeleteArtifactsDialogController.prototype.proceed=function(){var deferred=this.q_.defer();this.grrApiService_.delete("/artifacts",
{names:this.scope_["names"]}).then(function success(){deferred.resolve("Artifacts were deleted successfully.");this.grrArtifactDescriptorsService_.clearCache()}.bind(this),function failure(response){deferred.reject(response.data.message)}.bind(this));return deferred.promise};grrUi.artifact.deleteArtifactsDialogDirective.DeleteArtifactsDialogDirective=function(){return{scope:{names:"="},restrict:"E",templateUrl:"/static/angular-components/artifact/"+"delete-artifacts-dialog.html",controller:DeleteArtifactsDialogController,
controllerAs:"controller"}};grrUi.artifact.deleteArtifactsDialogDirective.DeleteArtifactsDialogDirective.directive_name="grrDeleteArtifactsDialog"});goog.provide("grrUi.artifact.uploadArtifactDialogDirective.UploadArtifactDialogController");goog.provide("grrUi.artifact.uploadArtifactDialogDirective.UploadArtifactDialogDirective");
goog.scope(function(){grrUi.artifact.uploadArtifactDialogDirective.UploadArtifactDialogController=function($scope,$q,grrApiService,grrArtifactDescriptorsService){this.scope_=$scope;this.q_=$q;this.grrApiService_=grrApiService;this.grrArtifactDescriptorsService_=grrArtifactDescriptorsService;this.file;this.inProgress=false};var UploadArtifactDialogController=grrUi.artifact.uploadArtifactDialogDirective.UploadArtifactDialogController;UploadArtifactDialogController.prototype.onFileSet=function(files){this.scope_.$apply(function(){this.file=
files[0]}.bind(this))};UploadArtifactDialogController.prototype.proceed=function(){var deferred=this.q_.defer();this.inProgress=true;this.grrApiService_.post("/artifacts",{},false,{"artifact":this.file}).then(function success(){deferred.resolve("Artifact was successfully uploaded.");this.grrArtifactDescriptorsService_.clearCache()}.bind(this),function failure(response){deferred.reject(response.data.message)}.bind(this));return deferred.promise};grrUi.artifact.uploadArtifactDialogDirective.UploadArtifactDialogDirective=
function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/artifact/"+"upload-artifact-dialog.html",controller:UploadArtifactDialogController,controllerAs:"controller"}};grrUi.artifact.uploadArtifactDialogDirective.UploadArtifactDialogDirective.directive_name="grrUploadArtifactDialog"});goog.provide("grrUi.artifact.artifactDialogService.ArtifactDialogService");goog.require("grrUi.artifact.deleteArtifactsDialogDirective.DeleteArtifactsDialogDirective");goog.require("grrUi.artifact.uploadArtifactDialogDirective.UploadArtifactDialogDirective");
goog.scope(function(){grrUi.artifact.artifactDialogService.ArtifactDialogService=function(grrDialogService){this.grrDialogService_=grrDialogService};var ArtifactDialogService=grrUi.artifact.artifactDialogService.ArtifactDialogService;ArtifactDialogService.service_name="grrArtifactDialogService";ArtifactDialogService.prototype.openDeleteArtifacts=function(names){var directive=grrUi.artifact.deleteArtifactsDialogDirective.DeleteArtifactsDialogDirective;return this.grrDialogService_.openDirectiveDialog(directive.directive_name,
{names:names})};ArtifactDialogService.prototype.openUploadArtifact=function(){var directive=grrUi.artifact.uploadArtifactDialogDirective.UploadArtifactDialogDirective;return this.grrDialogService_.openDirectiveDialog(directive.directive_name)}});goog.provide("grrUi.artifact.artifactManagerViewDirective.ArtifactManagerViewController");goog.provide("grrUi.artifact.artifactManagerViewDirective.ArtifactManagerViewDirective");
goog.scope(function(){grrUi.artifact.artifactManagerViewDirective.ArtifactManagerViewController=function($scope,grrApiService,grrArtifactDialogService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrArtifactDialogService_=grrArtifactDialogService;this.triggerUpdate;this.descriptors=[];this.selectedDescriptors={};this.numSelectedDescriptors=0;this.allDescriptorsSelected=false};var ArtifactManagerViewController=grrUi.artifact.artifactManagerViewDirective.ArtifactManagerViewController;
ArtifactManagerViewController.prototype.artifactsUrl="/artifacts";ArtifactManagerViewController.prototype.transformItems=function(items){this.descriptors=[];angular.forEach(items,function(item){if(item.value.is_custom.value)this.descriptors.push(item)}.bind(this));return this.descriptors};ArtifactManagerViewController.prototype.selectAll=function(){angular.forEach(this.descriptors,function(descriptor){this.selectedDescriptors[descriptor.value.artifact.value.name.value]=this.allDescriptorsSelected}.bind(this));
this.updateNumSelectedDescriptors()};ArtifactManagerViewController.prototype.upload=function(){var result=this.grrArtifactDialogService_.openUploadArtifact();result.then(function resolve(){this.triggerUpdate()}.bind(this))};ArtifactManagerViewController.prototype.deleteSelected=function(){var namesToDelete=[];for(var name in this.selectedDescriptors)if(this.selectedDescriptors[name])namesToDelete.push(name);var result=this.grrArtifactDialogService_.openDeleteArtifacts(namesToDelete);result.then(function resolve(){this.selectedDescriptors=
{};this.numSelectedDescriptors=0;this.triggerUpdate()}.bind(this))};ArtifactManagerViewController.prototype.updateNumSelectedDescriptors=function(){var count=0;for(var key in this.selectedDescriptors)if(this.selectedDescriptors[key])++count;this.numSelectedDescriptors=count};grrUi.artifact.artifactManagerViewDirective.ArtifactManagerViewDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/artifact/"+"artifact-manager-view.html",controller:ArtifactManagerViewController,
controllerAs:"controller"}};grrUi.artifact.artifactManagerViewDirective.ArtifactManagerViewDirective.directive_name="grrArtifactManagerView"});goog.provide("grrUi.artifact.artifactNameDirective.ArtifactNameController");goog.provide("grrUi.artifact.artifactNameDirective.ArtifactNameDirective");
goog.scope(function(){var SYSTEM_ARTIFACT_TYPE="SYSTEM";var USER_ARTIFACT_TYPE="USER";var UNKNOWN_ARTIFACT_TYPE="UNKNOWN";var namesCache;grrUi.artifact.artifactNameDirective.clearCache=function(){namesCache=null};grrUi.artifact.artifactNameDirective.ArtifactNameController=function($scope,grrArtifactDescriptorsService){this.scope_=$scope;this.grrArtifactDescriptorsService_=grrArtifactDescriptorsService;this.artifactType;this.scope_.$watch("::value",this.onValueChange_.bind(this))};var ArtifactNameController=
grrUi.artifact.artifactNameDirective.ArtifactNameController;ArtifactNameController.prototype.onValueChange_=function(newArtifactName){if(!angular.isObject(newArtifactName))return;this.grrArtifactDescriptorsService_.getDescriptorByName(newArtifactName["value"]).then(function(descriptor){if(angular.isDefined(descriptor)){var isCustom=descriptor["value"]["is_custom"]["value"];this.artifactType=isCustom?USER_ARTIFACT_TYPE:SYSTEM_ARTIFACT_TYPE}else this.artifactType=UNKNOWN_ARTIFACT_TYPE}.bind(this))};
grrUi.artifact.artifactNameDirective.ArtifactNameDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/artifact/artifact-name.html",controller:ArtifactNameController,controllerAs:"controller"}};grrUi.artifact.artifactNameDirective.ArtifactNameDirective.directive_name="grrArtifactName";grrUi.artifact.artifactNameDirective.ArtifactNameDirective.semantic_type="ArtifactName"});goog.provide("grrUi.artifact.artifactsListFormDirective.ArtifactsListFormController");goog.provide("grrUi.artifact.artifactsListFormDirective.ArtifactsListFormDirective");
goog.scope(function(){grrUi.artifact.artifactsListFormDirective.ArtifactsListFormController=function($scope,grrArtifactDescriptorsService){this.scope_=$scope;this.grrArtifactDescriptorsService_=grrArtifactDescriptorsService;this.descriptorsList=[];this.descriptors;this.descriptorsError;this.selectedName;this.platforms=["","Darwin","Linux","Windows"];this.selectedPlatform="";this.search="";this.searchFilterRef=this.searchFilter.bind(this);this.platformFilterRef=this.platformFilter.bind(this);this.grrArtifactDescriptorsService_.listDescriptors().then(this.onArtifactsResponse_.bind(this),
this.onArtifactsRequestFailure_.bind(this));this.scope_.$watch("controller.descriptors",this.onDescriptorsOrValueChange_.bind(this));this.scope_.$watchCollection("value",this.onDescriptorsOrValueChange_.bind(this))};var ArtifactsListFormController=grrUi.artifact.artifactsListFormDirective.ArtifactsListFormController;ArtifactsListFormController.prototype.searchFilter=function(descriptor){return!this.search||descriptor.value.artifact.value.name.value.toLowerCase().indexOf(this.search.toLowerCase())!=
-1};ArtifactsListFormController.prototype.platformFilter=function(descriptor){if(!this.selectedPlatform)return true;var checkOsList=function(osList){for(var i in osList){var os=osList[i];if(os.value==this.selectedPlatform)return true}return false}.bind(this);if(checkOsList(descriptor["value"]["artifact"]["value"]["supported_os"]||[]))return true;var sourceList=descriptor["value"]["artifact"]["value"]["sources"]||[];for(var index in sourceList){var source=sourceList[index];if(checkOsList(source["value"]["supported_os"]||
[]))return true}return false};ArtifactsListFormController.prototype.onArtifactsResponse_=function(descriptors){this.descriptors=descriptors};ArtifactsListFormController.prototype.onArtifactsRequestFailure_=function(error){this.descriptorsError=error};ArtifactsListFormController.prototype.add=function(name){var index=-1;for(var i=0;i<this.scope_.value.length;++i)if(this.scope_.value[i]["value"]==name["value"]){index=i;break}if(index==-1)this.scope_.value.push(name)};ArtifactsListFormController.prototype.remove=
function(name){var index=-1;for(var i=0;i<this.scope_.value.length;++i)if(this.scope_.value[i]["value"]==name["value"]){index=i;break}if(index!=-1)this.scope_.value.splice(index,1)};ArtifactsListFormController.prototype.clear=function(){angular.forEach(angular.copy(this.scope_.value),function(name){this.remove(name)}.bind(this))};ArtifactsListFormController.prototype.onDescriptorsOrValueChange_=function(){if(angular.isDefined(this.descriptors)&&angular.isDefined(this.scope_.value)){this.descriptorsList=
[];angular.forEach(this.descriptors,function(descriptor,name){var index=-1;for(var i=0;i<this.scope_.value.length;++i)if(this.scope_.value[i]["value"]==name){index=i;break}if(index==-1)this.descriptorsList.push(descriptor)}.bind(this))}};grrUi.artifact.artifactsListFormDirective.ArtifactsListFormDirective=function(){return{restrict:"E",scope:{descriptor:"=",value:"="},templateUrl:"/static/angular-components/artifact/"+"artifacts-list-form.html",controller:ArtifactsListFormController,controllerAs:"controller"}};
grrUi.artifact.artifactsListFormDirective.ArtifactsListFormDirective.directive_name="grrArtifactsListForm";grrUi.artifact.artifactsListFormDirective.ArtifactsListFormDirective.semantic_type="ArtifactName"});goog.provide("grrUi.core.aff4ObjectRepresentationDirective.Aff4ObjectRepresentationDirective");
goog.scope(function(){var Aff4ObjectRepresentationController=function($scope){this.scope_=$scope;this.scope_.value;this.aff4ObjectRepresentation;this.scope_.$watch("::value",this.onValueChange.bind(this))};Aff4ObjectRepresentationController.prototype.onValueChange=function(){if(angular.isObject(this.scope_.value))this.aff4ObjectRepresentation=this.scope_.value.value;else this.aff4ObjectRepresentation=this.scope_.value};grrUi.core.aff4ObjectRepresentationDirective.Aff4ObjectRepresentationDirective=
function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/core/aff4-object-representation.html",controller:Aff4ObjectRepresentationController,controllerAs:"controller"}};grrUi.core.aff4ObjectRepresentationDirective.Aff4ObjectRepresentationDirective.directive_name="grrAff4ObjectRepresentation"});goog.provide("grrUi.core.itemsProviderController.Items");goog.provide("grrUi.core.itemsProviderController.ItemsProviderController");goog.scope(function(){grrUi.core.itemsProviderController.Items;grrUi.core.itemsProviderController.ItemsProviderController=function(){};var ItemsProviderController=grrUi.core.itemsProviderController.ItemsProviderController;ItemsProviderController.prototype.fetchItems=goog.abstractMethod;ItemsProviderController.prototype.fetchFilteredItems=goog.abstractMethod});goog.provide("grrUi.core.apiItemsProviderDirective.ApiItemsProviderController");goog.provide("grrUi.core.apiItemsProviderDirective.ApiItemsProviderDirective");goog.require("grrUi.core.itemsProviderController.ItemsProviderController");
goog.scope(function(){grrUi.core.apiItemsProviderDirective.ApiItemsProviderController=function($scope,$attrs,$parse,grrApiService,$log){this.scope_=$scope;this.grrApiService_=grrApiService;this.log_=$log;this.url;this.queryParams;this.transformItems;this.method;$scope.$watch($attrs["url"],function(){this.url=$scope.$eval($attrs["url"])}.bind(this));if($attrs["queryParams"])$scope.$watch($attrs["queryParams"],function(){this.queryParams=$scope.$eval($attrs["queryParams"])}.bind(this));if($attrs["transformItems"])this.transformItems=
$parse($attrs["transformItems"]);if($attrs["method"])this.method=$attrs["method"]};var ApiItemsProviderController=grrUi.core.apiItemsProviderDirective.ApiItemsProviderController;ApiItemsProviderController.prototype.fetchItems=function(offset,count,opt_withTotalCount){var params=angular.extend(this.queryParams||{},{"offset":offset,"count":count});if(this.method==="POST")return this.grrApiService_.post(this.url,params).then(this.onFetchedItems_.bind(this));else return this.grrApiService_.get(this.url,
params).then(this.onFetchedItems_.bind(this))};ApiItemsProviderController.prototype.fetchFilteredItems=function(filter,offset,count){var params=angular.extend(this.queryParams||{},{"filter":filter,"offset":offset,"count":count});if(this.method==="POST")return this.grrApiService_.post(this.url,params).then(this.onFetchedItems_.bind(this));else return this.grrApiService_.get(this.url,params).then(this.onFetchedItems_.bind(this))};ApiItemsProviderController.prototype.onFetchedItems_=function(response){var result=
{items:response.data["items"]||[],offset:response.data["offset"]};if(angular.isDefined(response.data["total_count"]))result.totalCount=response.data["total_count"];if(angular.isDefined(result.items)&&angular.isDefined(this.transformItems)){try{result.items=this.transformItems(this.scope_,{"items":result.items})}catch(e){this.log_.error("transformItems (on url "+this.url+") failed: "+e);throw e;}if(angular.isUndefined(result.items)){var errorStr="transform-items function returned undefined";this.log_.error(errorStr);
throw new Error(errorStr);}}return result};grrUi.core.apiItemsProviderDirective.ApiItemsProviderDirective=function(){return{restrict:"A",priority:2E3,controller:ApiItemsProviderController}};grrUi.core.apiItemsProviderDirective.ApiItemsProviderDirective.directive_name="grrApiItemsProvider"});goog.provide("grrUi.core.basenameFilter.BasenameFilter");goog.scope(function(){grrUi.core.basenameFilter.filterImplementation=function(input){if(!angular.isString(input))return input;else{var components=input.split("/");return components[components.length-1]}};grrUi.core.basenameFilter.BasenameFilter=function(){return grrUi.core.basenameFilter.filterImplementation};grrUi.core.basenameFilter.BasenameFilter.filter_name="grrBasename"});goog.provide("grrUi.core.bindKeyDirective.BindKeyController");goog.provide("grrUi.core.bindKeyDirective.BindKeyDirective");
goog.scope(function(){grrUi.core.bindKeyDirective.BindKeyController=function($scope,$element,$attrs){this.scope_=$scope;this.element_=$element;this.key_=13;this.callbackExpr_;if($attrs["key"])this.key_=parseInt($attrs["key"],10);if($attrs["grrBindKey"])this.callbackExpr_=$attrs["grrBindKey"];$element.bind("keydown, keypress",this.onKeyDown_.bind(this))};var BindKeyController=grrUi.core.bindKeyDirective.BindKeyController;BindKeyController.prototype.onKeyDown_=function(event){if(event["which"]===this.key_){this.scope_.$apply(function(){this.scope_.$eval(this.callbackExpr_)}.bind(this));
event.preventDefault()}};grrUi.core.bindKeyDirective.BindKeyDirective=function(){return{restrict:"A",controller:BindKeyController}};grrUi.core.bindKeyDirective.BindKeyDirective.directive_name="grrBindKey"});goog.provide("grrUi.core.bytesToHexFilter.BytesToHexFilter");goog.scope(function(){grrUi.core.bytesToHexFilter.filterImplementation=function(bytes){var hex="";for(var i=0;i<bytes.length;i+=1){var char=bytes.charCodeAt(i).toString(16);hex+=("0"+char).substr(-2)}return hex};grrUi.core.bytesToHexFilter.BytesToHexFilter=function(){return function(input){return grrUi.core.bytesToHexFilter.filterImplementation(input)}};grrUi.core.bytesToHexFilter.BytesToHexFilter.filter_name="grrBytesToHex"});goog.provide("grrUi.core.canaryOnlyDirective.CanaryOnlyController");goog.provide("grrUi.core.canaryOnlyDirective.CanaryOnlyDirective");goog.provide("grrUi.core.canaryOnlyDirective.NonCanaryOnlyController");goog.provide("grrUi.core.canaryOnlyDirective.NonCanaryOnlyDirective");
goog.scope(function(){var getCanaryModeValue=function(grrApiService,callback){grrApiService.getCached("/users/me").then(function(response){var canaryMode;try{canaryMode=response["data"]["value"]["settings"]["value"]["canary_mode"]["value"]}catch(err){canaryMode=false}callback(canaryMode)})};grrUi.core.canaryOnlyDirective.CanaryOnlyDirective=function(){return{scope:{},restrict:"E",controller:function(grrApiService){this.canaryMode=false;getCanaryModeValue(grrApiService,function(canaryMode){this.canaryMode=
canaryMode}.bind(this))},controllerAs:"controller",transclude:true,template:"<ng-transclude ng-if='controller.canaryMode'></ng-transclude>"}};grrUi.core.canaryOnlyDirective.CanaryOnlyDirective.directive_name="grrCanaryOnly";grrUi.core.canaryOnlyDirective.NonCanaryOnlyDirective=function(){return{scope:{},restrict:"E",controller:function(grrApiService){this.canaryMode=true;getCanaryModeValue(grrApiService,function(canaryMode){this.canaryMode=canaryMode}.bind(this))},controllerAs:"controller",transclude:true,
template:"<ng-transclude ng-if='!controller.canaryMode'></ng-transclude>"}};grrUi.core.canaryOnlyDirective.NonCanaryOnlyDirective.directive_name="grrNonCanaryOnly"});goog.provide("grrUi.core.clockDirective.ClockController");goog.provide("grrUi.core.clockDirective.ClockDirective");
goog.scope(function(){grrUi.core.clockDirective.ClockController=function($scope,$interval,grrTimeService){this.grrTimeService_=grrTimeService;this.formattedClock;this.updateLiveClock_();$interval(this.updateLiveClock_.bind(this),1E3)};var ClockController=grrUi.core.clockDirective.ClockController;grrUi.core.clockDirective.ClockController.prototype.updateLiveClock_=function(){this.formattedClock=this.grrTimeService_.formatAsUTC()};grrUi.core.clockDirective.ClockDirective=function(){return{scope:{},
restrict:"E",template:'<div class="navbar-text pull-right">'+"{$ controller.formattedClock $}"+"</div>",controller:ClockController,controllerAs:"controller"}};grrUi.core.clockDirective.ClockDirective.directive_name="grrLiveClock"});goog.provide("grrUi.core.confirmationDialogDirective.ConfirmationDialogController");goog.provide("grrUi.core.confirmationDialogDirective.ConfirmationDialogDirective");
goog.scope(function(){grrUi.core.confirmationDialogDirective.ConfirmationDialogController=function($scope,$timeout){this.scope_=$scope;this.timeout_=$timeout;this.error;this.success};var ConfirmationDialogController=grrUi.core.confirmationDialogDirective.ConfirmationDialogController;ConfirmationDialogController.prototype.proceed=function(){var result=this.scope_.proceed();if(result)result.then(function success(successMessage){this.success=successMessage;if(this.scope_["autoCloseOnSuccess"])this.timeout_(function(){this.close()}.bind(this),
1E3)}.bind(this),function failure(errorMessage){this.error=errorMessage}.bind(this))};ConfirmationDialogController.prototype.dismiss=function(){var curScope=this.scope_;while(curScope&&!curScope["$dismiss"])curScope=curScope.$parent;if(curScope)curScope["$dismiss"]()};ConfirmationDialogController.prototype.close=function(){var curScope=this.scope_;while(curScope&&!curScope["$close"])curScope=curScope.$parent;if(curScope)curScope["$close"]()};grrUi.core.confirmationDialogDirective.ConfirmationDialogDirective=
function(){return{scope:{title:"=",closeName:"=",cancelName:"=",proceedName:"=",proceedClass:"=",proceed:"&",canProceed:"&?",autoCloseOnSuccess:"="},restrict:"E",transclude:true,templateUrl:"/static/angular-components/core/confirmation-dialog.html",controller:ConfirmationDialogController,controllerAs:"controller"}};grrUi.core.confirmationDialogDirective.ConfirmationDialogDirective.directive_name="grrConfirmationDialog"});goog.provide("grrUi.core.dialogService.DialogService");goog.require("grrUi.core.utils.camelCaseToDashDelimited");
goog.scope(function(){grrUi.core.dialogService.DialogService=function($rootScope,$uibModal){this.rootScope_=$rootScope;this.uibModal_=$uibModal};var DialogService=grrUi.core.dialogService.DialogService;DialogService.service_name="grrDialogService";DialogService.prototype.openConfirmation=function(title,message,proceed){var modalScope=this.rootScope_.$new();modalScope.title=title;modalScope.message=message;modalScope.proceed=proceed;var modalInstance=this.uibModal_.open({template:'<grr-confirmation-dialog title="title" proceed="proceed()" >'+
'  <div class="vertically-padded">{$ message $}</div>'+"</grr-confirmation-dialog>",scope:modalScope});return modalInstance.result};DialogService.prototype.openDirectiveDialog=function(directive,opt_params,opt_modalParams){var modalScope=this.rootScope_.$new();var paramString="";var tagName=grrUi.core.utils.camelCaseToDashDelimited(directive);if(angular.isDefined(opt_params))angular.forEach(opt_params||{},function(value,key){modalScope[key]=opt_params[key];paramString+=" "+grrUi.core.utils.camelCaseToDashDelimited(key)+
'="'+key+'"'});var template="<"+tagName+" "+paramString+' close="$close()" />';var modalParams=angular.extend({template:template,scope:modalScope},opt_modalParams||{});var modalInstance=this.uibModal_.open(modalParams);return modalInstance.result}});goog.provide("grrUi.core.disableIfNoTraitDirective.DisableIfNoTraitController");goog.provide("grrUi.core.disableIfNoTraitDirective.DisableIfNoTraitDirective");
goog.scope(function(){grrUi.core.disableIfNoTraitDirective.DisableIfNoTraitController=function($attrs,grrApiService){this.attrs_=$attrs;this.grrApiService_=grrApiService;this.traitName_;this.attrs_.$observe("grrDisableIfNoTrait",this.onTraitNameChange_.bind(this))};var DisableIfNoTraitController=grrUi.core.disableIfNoTraitDirective.DisableIfNoTraitController;DisableIfNoTraitController.prototype.onTraitNameChange_=function(newValue){this.traitName_=newValue;if(angular.isUndefined(newValue))this.attrs_.$set("disable",
false);else this.grrApiService_.getCached("users/me").then(this.onUserInfo_.bind(this))};DisableIfNoTraitController.prototype.onUserInfo_=function(response){var traitValue=false;var interfaceTraits=response["data"]["value"]["interface_traits"];if(angular.isDefined(interfaceTraits))if(angular.isDefined(interfaceTraits["value"][this.traitName_]))traitValue=interfaceTraits["value"][this.traitName_]["value"];this.attrs_.$set("disabled",!traitValue)};grrUi.core.disableIfNoTraitDirective.DisableIfNoTraitDirective=
function(){return{scope:{},restrict:"A",controller:DisableIfNoTraitController,controllerAs:"controller"}};grrUi.core.disableIfNoTraitDirective.DisableIfNoTraitDirective.directive_name="grrDisableIfNoTrait"});goog.provide("grrUi.core.serverErrorButtonDirective.ServerErrorButtonController");goog.provide("grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective");
goog.scope(function(){var ERROR_EVENT_NAME="ServerError";grrUi.core.serverErrorButtonDirective.ServerErrorButtonController=function($rootScope,$scope,$uibModal){this.rootScope_=$rootScope;this.scope_=$scope;this.uibModal_=$uibModal;this.error;this.buttonVisible;this.rootScope_.$on(ERROR_EVENT_NAME,this.onErrorEvent.bind(this))};var ServerErrorButtonController=grrUi.core.serverErrorButtonDirective.ServerErrorButtonController;ServerErrorButtonController.prototype.onErrorEvent=function(unused_event,
error){if(!angular.isObject(error)||!angular.isString(error.message))return;if(error.message.length){this.error=error;this.buttonVisible=true}else{this.error=null;this.buttonVisible=false}};ServerErrorButtonController.prototype.showError=function(){var modalScope=this.scope_.$new();modalScope.message=this.error.message;modalScope.traceBack=this.error.traceBack;modalScope.close=function(){modalInstance.close()};this.scope_.$on("$destroy",function(){modalScope.$destroy()});var modalInstance=this.uibModal_.open({template:'<grr-server-error-dialog close="close()" message="message" trace-back="traceBack" />',
scope:modalScope,windowClass:"wide-modal high-modal",size:"lg"});modalInstance.result.finally(function(){this.error=null;this.buttonVisible=false}.bind(this))};grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective=function(){return{scope:true,restrict:"E",replace:true,templateUrl:"/static/angular-components/core/server-error-button.html",controller:ServerErrorButtonController,controllerAs:"controller"}};var ServerErrorButtonDirective=grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective;
ServerErrorButtonDirective.directive_name="grrServerErrorButton";ServerErrorButtonDirective.error_event_name=ERROR_EVENT_NAME});goog.provide("grrUi.core.downloadCollectionAsDirective.DownloadCollectionAsController");goog.provide("grrUi.core.downloadCollectionAsDirective.DownloadCollectionAsDirective");goog.require("grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective");
goog.scope(function(){var ERROR_EVENT_NAME=grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective.error_event_name;grrUi.core.downloadCollectionAsDirective.DownloadCollectionAsController=function($rootScope,$scope,grrApiService){this.rootScope_=$rootScope;this.scope_=$scope;this.grrApiService_=grrApiService;this.pluginToDisplayName={"csv-zip":"CSV (Zipped)","flattened-yaml-zip":"Flattened YAML (Zipped)","sqlite-zip":"SQLite Scripts (Zipped)"};this.selectedPlugin="csv-zip"};var DownloadCollectionAsController=
grrUi.core.downloadCollectionAsDirective.DownloadCollectionAsController;DownloadCollectionAsController.prototype.downloadAs=function(pluginName){var url=this.scope_["baseUrl"]+"/"+pluginName;this.grrApiService_.downloadFile(url).then(function success(){}.bind(this),function failure(response){if(angular.isUndefined(response.status))this.rootScope_.$broadcast(ERROR_EVENT_NAME,{message:"Couldn't download exported results."})}.bind(this))};grrUi.core.downloadCollectionAsDirective.DownloadCollectionAsDirective=
function(){return{scope:{baseUrl:"="},restrict:"E",templateUrl:"/static/angular-components/core/download-collection-as.html",controller:DownloadCollectionAsController,controllerAs:"controller"}};grrUi.core.downloadCollectionAsDirective.DownloadCollectionAsDirective.directive_name="grrDownloadCollectionAs"});goog.provide("grrUi.core.downloadCollectionFilesDirective.DownloadCollectionFilesController");goog.provide("grrUi.core.downloadCollectionFilesDirective.DownloadCollectionFilesDirective");goog.provide("grrUi.core.downloadCollectionFilesDirective.valuePointsToFile");
goog.scope(function(){grrUi.core.downloadCollectionFilesDirective.valuePointsToFile=function(value){if(value["type"]=="ApiFlowResult"||value["type"]=="ApiHuntResult")value=value["value"]["payload"];if(value["type"]=="StatEntry"||value["type"]=="FileFinderResult"||value["type"]=="ArtifactFilesDownloaderResult")return true;else return false};grrUi.core.downloadCollectionFilesDirective.DownloadCollectionFilesController=function($scope,$window,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;
this.scope_.downloadUrl;this.primaryArchiveExtension;this.secondaryArchiveExtension;this.fileArchiveGenerationStarted;this.fileArchiveGenerationSuccess;this.fileArchiveGenerationError;this.exportCommand;if($window.navigator.appVersion.indexOf("Mac")!=-1){this.primaryArchiveExtension="tar.gz";this.secondaryArchiveExtension="zip"}else{this.primaryArchiveExtension="zip";this.secondaryArchiveExtension="tar.gz"}this.scope_.$watch("exportCommandUrl",function(newValue){if(angular.isUndefined(newValue))return;
this.grrApiService_.get(newValue).then(function(response){if(angular.isDefined(response["data"]["command"]))this.exportCommand=response["data"]["command"]}.bind(this))}.bind(this))};var DownloadCollectionFilesController=grrUi.core.downloadCollectionFilesDirective.DownloadCollectionFilesController;DownloadCollectionFilesController.prototype.generateFileArchive=function(format){var requestFormat=format.toUpperCase().replace(".","_");this.grrApiService_.downloadFile(this.scope_["downloadUrl"],{archive_format:requestFormat}).then(function success(){this.fileArchiveGenerationSuccess=
true}.bind(this),function failure(response){this.fileArchiveGenerationError=response.data["message"]}.bind(this));this.fileArchiveGenerationStarted=true};grrUi.core.downloadCollectionFilesDirective.DownloadCollectionFilesDirective=function(){return{scope:{exportCommandUrl:"=?",downloadUrl:"="},restrict:"E",templateUrl:"/static/angular-components/core/"+"download-collection-files.html",controller:DownloadCollectionFilesController,controllerAs:"controller"}};grrUi.core.downloadCollectionFilesDirective.DownloadCollectionFilesDirective.directive_name=
"grrDownloadCollectionFiles"});goog.provide("grrUi.core.encodeUriComponentFilter.EncodeUriComponentFilter");goog.scope(function(){grrUi.core.encodeUriComponentFilter.EncodeUriComponentFilter=function(){return window.encodeURIComponent};grrUi.core.encodeUriComponentFilter.EncodeUriComponentFilter.filter_name="grrEncodeUriComponent"});goog.provide("grrUi.core.firebaseService.FirebaseService");grrUi.core.firebaseService.FirebaseService=function($http,grrApiService){this.http_=$http;this.grrApiService_=grrApiService};var FirebaseService=grrUi.core.firebaseService.FirebaseService;FirebaseService.service_name="grrFirebaseService";
FirebaseService.prototype.setupIfNeeded=function(){if(angular.isUndefined(window.firebase)||firebase.apps.length==0){this.grrApiService_.markAuthDone();return}var firebaseError;firebase.auth().getRedirectResult().then(function(result){}.bind(this)).catch(function(error){firebaseError=error;this.grrApiService_.markAuthDone()}.bind(this));firebase.auth().onAuthStateChanged(function(user){if(user)user.getToken().then(function(token){this.http_.defaults.headers["common"]["Authorization"]="Bearer "+token;
this.grrApiService_.markAuthDone()}.bind(this));else if(!firebaseError){var providerName=firebase.apps[0].options["authProvider"];var provider=new firebase.auth[providerName];firebase.auth().signInWithRedirect(provider)}}.bind(this))};goog.provide("grrUi.core.forceRefreshDirective.ForceRefreshController");goog.provide("grrUi.core.forceRefreshDirective.ForceRefreshDirective");
goog.scope(function(){grrUi.core.forceRefreshDirective.ForceRefreshController=function($scope,$element,$transclude){this.scope_=$scope;this.element_=$element;this.transclude_=$transclude;this.transcludedScope_;this.scope_.$watch("refreshTrigger",this.updateDom_.bind(this),true)};var ForceRefreshController=grrUi.core.forceRefreshDirective.ForceRefreshController;ForceRefreshController.prototype.updateDom_=function(){if(angular.isDefined(this.transcludedScope_)){this.transcludedScope_.$destroy();this.transcludedScope_=
undefined}this.element_.empty();this.transclude_(function(clone,scope){this.element_.empty();this.element_.append(clone);this.transcludedScope_=scope}.bind(this))};grrUi.core.forceRefreshDirective.ForceRefreshDirective=function(){return{scope:{refreshTrigger:"="},restrict:"EA",transclude:true,controller:ForceRefreshController,controllerAs:"controller"}};grrUi.core.forceRefreshDirective.ForceRefreshDirective.directive_name="grrForceRefresh"});goog.provide("grrUi.core.globalNotificationsDirective.GlobalNotificationsController");goog.provide("grrUi.core.globalNotificationsDirective.GlobalNotificationsDirective");
goog.scope(function(){var SECOND=1E3;var FETCH_INTERVAL=60*SECOND;grrUi.core.globalNotificationsDirective.GlobalNotificationsController=function($scope,$interval,grrApiService){this.scope_=$scope;this.interval_=$interval;this.grrApiService_=grrApiService;this.globalNotifications=[];this.intervalPromise_;this.fetchGlobalNotifications_();this.intervalPromise_=this.interval_(this.fetchGlobalNotifications_.bind(this),FETCH_INTERVAL);this.scope_.$on("$destroy",this.stopPollingGlobalNotifications_.bind(this))};
var GlobalNotificationsController=grrUi.core.globalNotificationsDirective.GlobalNotificationsController;GlobalNotificationsController.prototype.fetchGlobalNotifications_=function(){this.grrApiService_.get("users/me/notifications/pending/global").then(function(response){this.globalNotifications=response.data["items"]}.bind(this))};GlobalNotificationsController.prototype.deleteGlobalNotification=function(notification){var index=this.globalNotifications.indexOf(notification);this.globalNotifications.splice(index,
1);var type=notification["value"]["type"]["value"];var url="users/me/notifications/pending/global/"+type;this.grrApiService_.delete(url)};GlobalNotificationsController.prototype.stopPollingGlobalNotifications_=function(){this.interval_.cancel(this.intervalPromise_)};grrUi.core.globalNotificationsDirective.GlobalNotificationsDirective=function(){return{scope:true,restrict:"E",templateUrl:"/static/angular-components/core/global-notifications.html",controller:GlobalNotificationsController,controllerAs:"controller"}};
var GlobalNotificationsDirective=grrUi.core.globalNotificationsDirective.GlobalNotificationsDirective;GlobalNotificationsDirective.directive_name="grrGlobalNotifications";GlobalNotificationsDirective.fetch_interval=FETCH_INTERVAL});goog.provide("grrUi.core.hexNumberFilter.HexNumberFilter");goog.scope(function(){grrUi.core.hexNumberFilter.filterImplementation=function(input){var hex=input.toString(16);var targetLength=Math.ceil(hex.length/8)*8;var leadingZeros=Array(targetLength-hex.length+1).join(0);return"0x"+leadingZeros+hex};grrUi.core.hexNumberFilter.HexNumberFilter=function(){return function(input){return grrUi.core.hexNumberFilter.filterImplementation(input)}};grrUi.core.hexNumberFilter.HexNumberFilter.filter_name="grrHexNumber"});goog.provide("grrUi.core.infiniteTableDirective.InfiniteTableController");goog.provide("grrUi.core.infiniteTableDirective.InfiniteTableDirective");
goog.scope(function(){grrUi.core.infiniteTableDirective.InfiniteTableController=function($scope,$attrs,$element,$interval,$transclude,$parse,$log){this.scope_=$scope;this.attrs_=$attrs;this.element_=$element;this.interval_=$interval;this.transclude_=$transclude;this.log_=$log;this.itemsProvider;this.fetchedItems_=[];this.currentPage_=0;this.showUntilPage_=0;this.updateCounter_=0;this.filterValue_;this.loadingInProgress_=false;this.autoRefreshInProgress_=false;this.rootElement_=this.element_.parent();
this.pageSize_=Number($scope.$eval(this.attrs_["pageSize"]))||InfiniteTableController.DEFAULT_PAGE_SIZE;this.elementScopes_={};var template=angular.element(InfiniteTableController.LOADING_TEMPLATE);this.element_.replaceWith(template);if(angular.isDefined(this.attrs_["triggerUpdate"])){var parsedExpression=$parse(this.attrs_["triggerUpdate"]);parsedExpression.assign(this.scope_,this.triggerUpdate.bind(this))}var loadingTimer=this.interval_(this.checkIfTableLoadingIsVisible_.bind(this),100);this.scope_.$on("$destroy",
function(){this.interval_.cancel(loadingTimer)}.bind(this));this.autoRefreshInterval_=Number($scope.$eval(this.attrs_["autoRefreshInterval"]));if(this.autoRefreshInterval_){var refreshTimer=this.interval_(this.refreshData_.bind(this),this.autoRefreshInterval_);this.scope_.$on("$destroy",function(){this.interval_.cancel(refreshTimer)}.bind(this))}this.scope_.$watch(this.attrs_["filterValue"],this.onFilterChange_.bind(this))};var InfiniteTableController=grrUi.core.infiniteTableDirective.InfiniteTableController;
InfiniteTableController.DEFAULT_PAGE_SIZE=50;InfiniteTableController.LOADING_TEMPLATE='<tr><td colspan="100" '+'class="table-loading">Loading...</td></tr>';InfiniteTableController.UNIQUE_KEY_NAME="_grrTableKey";InfiniteTableController.ROW_HASH_NAME="_grrTableRowHash";InfiniteTableController.prototype.setFetchedItems_=function(newValue){if(newValue.length!=this.fetchedItems_.length){var loadingElement=$(this.rootElement_).find("tr:has(td.table-loading)");for(var i=this.fetchedItems_.length;i<newValue.length;++i)this.transclude_(function(clone,
scope){scope.item=newValue[i];var key=newValue[i][InfiniteTableController.UNIQUE_KEY_NAME];if(angular.isUndefined(key)&&this.autoRefreshInterval_)this.log_.error("items in infinite table with auto-refresh "+"have to have "+InfiniteTableController.UNIQUE_KEY_NAME+" set");key=key||"";var rowHash=newValue[i][InfiniteTableController.ROW_HASH_NAME];if(angular.isUndefined(rowHash)&&this.autoRefreshInterval_)this.log_.error("items in infinite table with auto-refresh "+"have to have "+InfiniteTableController.ROW_HASH_NAME+
" set");rowHash=rowHash||"";var startComment=document.createComment("-> "+key);var endComment=document.createComment("<- "+key);this.elementScopes_[key]=[startComment,endComment,scope,rowHash];$(startComment).insertBefore(loadingElement);clone.insertBefore(loadingElement);$(endComment).insertBefore(loadingElement)}.bind(this))}this.fetchedItems_=newValue};InfiniteTableController.prototype.triggerUpdate=function(graceful){if(graceful){if(!this.autoRefreshInterval_)throw new Error("graceful refresh is only possible in infinite tables "+
"with auto-refresh turned on");this.refreshData_()}else{this.updateCounter_++;this.loadingInProgress_=false;this.autoRefreshInProgress_=false;this.setFetchedItems_([]);this.currentPage_=0;this.rootElement_.html(InfiniteTableController.LOADING_TEMPLATE)}};InfiniteTableController.prototype.onFilterChange_=function(newFilterValue){if(newFilterValue!==this.filterValue_){this.filterValue_=newFilterValue;this.triggerUpdate(false)}};InfiniteTableController.prototype.checkIfTableLoadingIsVisible_=function(){if(this.loadingInProgress_)return;
$(this.rootElement_).find(".table-loading").each(function(index,loadingElement){var loadingOffset=loadingElement.getBoundingClientRect();var elem=document.elementFromPoint(Math.ceil(loadingOffset.left)+1,Math.ceil(loadingOffset.top)+1);if($(elem).hasClass("table-loading"))this.tableLoadingElementWasShown_();else if(this.showUntilPage_>this.currentPage_)this.tableLoadingElementWasShown_()}.bind(this))};InfiniteTableController.prototype.refreshData_=function(){if(this.loadingInProgress_||this.autoRefreshInProgress_)return;
this.autoRefreshInProgress_=true;var prevUpdateCounter=this.updateCounter_;this.itemsProvider.fetchItems(0,this.currentPage_*this.pageSize_).then(function(newItems){if(this.updateCounter_===prevUpdateCounter){this.autoRefreshInProgress_=false;this.onAutoRefreshDataFetched_(newItems)}}.bind(this))};InfiniteTableController.prototype.onAutoRefreshDataFetched_=function(newItems){for(var i=0;i<newItems.items.length;++i){var newItem=newItems.items[i];var key=newItem[InfiniteTableController.UNIQUE_KEY_NAME];
var rowHash=newItem[InfiniteTableController.ROW_HASH_NAME];var elemScope=this.elementScopes_[key];if(angular.isDefined(elemScope)){var startComment=elemScope[0];var endComment=elemScope[1];var scope=elemScope[2];var oldRowHash=elemScope[3];if(angular.equals(oldRowHash,rowHash))continue;scope.$destroy();var toRemove=[];for(var e=startComment.nextSibling;e!==endComment;e=e.nextSibling)toRemove.push(e);$(toRemove).remove();this.transclude_(function(clone,scope){scope.item=newItem;this.elementScopes_[key]=
[startComment,endComment,scope,rowHash];clone.insertBefore(endComment)}.bind(this))}else{this.fetchedItems_.splice(0,0,newItem);this.transclude_(function(clone,scope){scope.item=newItem;var startComment=document.createComment("-> "+key);var endComment=document.createComment("<- "+key);this.elementScopes_[key]=[startComment,endComment,scope,rowHash];this.rootElement_.prepend([startComment,clone,endComment])}.bind(this))}}};InfiniteTableController.prototype.tableLoadingElementWasShown_=function(){this.loadingInProgress_=
true;var prevUpdateCounter=this.updateCounter_;if(!this.filterValue_)this.itemsProvider.fetchItems(this.currentPage_*this.pageSize_,this.pageSize_).then(function(values){if(this.updateCounter_===prevUpdateCounter)this.onItemsFetched_(values)}.bind(this));else this.itemsProvider.fetchFilteredItems(this.filterValue_,this.currentPage_*this.pageSize_,this.pageSize_).then(function(values){if(this.updateCounter_===prevUpdateCounter)this.onItemsFetched_(values)}.bind(this))};InfiniteTableController.prototype.onItemsFetched_=
function(newlyFetchedItems){this.setFetchedItems_(this.fetchedItems_.concat(newlyFetchedItems.items));if(newlyFetchedItems.items.length==0)$(this.rootElement_).find("tr:has(.table-loading)").remove();this.currentPage_+=1;if(this.currentPage_>this.showUntilPage_)this.showUntilPage_=this.currentPage_;this.loadingInProgress_=false};grrUi.core.infiniteTableDirective.InfiniteTableDirective=function(){return{transclude:"element",restrict:"A",priority:1E3,terminal:true,require:["grrInfiniteTable","?grrMemoryItemsProvider",
"?grrApiItemsProvider"],controller:InfiniteTableController,link:function(scope,element,attrs,controllers){var providerController=undefined;for(var i=1;i<controllers.length;++i)if(angular.isObject(controllers[i])){if(angular.isDefined(providerController))throw new Error("Can have only 1 provider.");providerController=controllers[i]}if(angular.isUndefined(providerController))throw new Error("Data provider not specified.");controllers[0].itemsProvider=providerController}}};grrUi.core.infiniteTableDirective.InfiniteTableDirective.directive_name=
"grrInfiniteTable"});goog.provide("grrUi.core.loadingIndicatorDirective.LoadingIndicatorController");goog.provide("grrUi.core.loadingIndicatorDirective.LoadingIndicatorDirective");
goog.scope(function(){var LOADING_STARTED_EVENT_NAME="grrLoadingStartedEvent";var LOADING_FINISHED_EVENT_NAME="grrLoadingFinishedEvent";grrUi.core.loadingIndicatorDirective.LoadingIndicatorController=function($rootScope,$scope){this.rootScope_=$rootScope;this.scope_=$scope;this.queue=[];this.queueIsEmpty=true;this.rootScope_.$on(LOADING_STARTED_EVENT_NAME,this.onLoadingStartedEvent_.bind(this));this.rootScope_.$on(LOADING_FINISHED_EVENT_NAME,this.onLoadingFinishedEvent_.bind(this))};var LoadingIndicatorController=
grrUi.core.loadingIndicatorDirective.LoadingIndicatorController;LoadingIndicatorController.prototype.onLoadingStartedEvent_=function(event,key){this.queue.push(key);this.queueIsEmpty=this.queue.length===0};LoadingIndicatorController.prototype.onLoadingFinishedEvent_=function(event,key){var index=this.queue.indexOf(key);if(index>=0){this.queue.splice(index,1);this.queueIsEmpty=this.queue.length===0}else;};grrUi.core.loadingIndicatorDirective.LoadingIndicatorDirective=function(){return{scope:true,restrict:"E",
template:'<div id="ajax_spinner" class="ajax_spinner" ng-hide="controller.queueIsEmpty">'+'    <img src="/static/images/ajax-loader.gif">'+"</div>",controller:LoadingIndicatorController,controllerAs:"controller"}};var LoadingIndicatorDirective=grrUi.core.loadingIndicatorDirective.LoadingIndicatorDirective;LoadingIndicatorDirective.directive_name="grrLoadingIndicator";LoadingIndicatorDirective.loading_started_event_name=LOADING_STARTED_EVENT_NAME;LoadingIndicatorDirective.loading_finished_event_name=
LOADING_FINISHED_EVENT_NAME});goog.provide("grrUi.core.loadingIndicatorService.LoadingIndicatorService");goog.require("grrUi.core.loadingIndicatorDirective.LoadingIndicatorDirective");
goog.scope(function(){var LoadingIndicatorDirective=grrUi.core.loadingIndicatorDirective.LoadingIndicatorDirective;var LOADING_STARTED_EVENT_NAME=LoadingIndicatorDirective.loading_started_event_name;var LOADING_FINISHED_EVENT_NAME=LoadingIndicatorDirective.loading_finished_event_name;grrUi.core.loadingIndicatorService.LoadingIndicatorService=function($rootScope){this.rootScope_=$rootScope;this.key=0};var LoadingIndicatorService=grrUi.core.loadingIndicatorService.LoadingIndicatorService;LoadingIndicatorService.service_name=
"grrLoadingIndicatorService";LoadingIndicatorService.prototype.getNextKey_=function(){return this.key++};LoadingIndicatorService.prototype.startLoading=function(){var key=this.getNextKey_();this.rootScope_.$broadcast(LOADING_STARTED_EVENT_NAME,key);return key};LoadingIndicatorService.prototype.stopLoading=function(key){this.rootScope_.$broadcast(LOADING_FINISHED_EVENT_NAME,key)}});goog.provide("grrUi.core.memoryItemsProviderDirective.MemoryItemsProviderController");goog.provide("grrUi.core.memoryItemsProviderDirective.MemoryItemsProviderDirective");goog.require("grrUi.core.itemsProviderController.ItemsProviderController");
goog.scope(function(){grrUi.core.memoryItemsProviderDirective.MemoryItemsProviderController=function($scope,$q,$attrs,$parse){this.q_=$q;this.items_;if(angular.isUndefined($attrs.items))throw new Error('"items" attribute has to be specified.');$scope.$watch($attrs.items,function(){this.items_=$scope.$eval($attrs.items)}.bind(this))};var MemoryItemsProviderController=grrUi.core.memoryItemsProviderDirective.MemoryItemsProviderController;MemoryItemsProviderController.prototype.fetchItems=function(offset,
count,opt_withTotalCount){if(angular.isUndefined(opt_withTotalCount))opt_withTotalCount=false;var items=this.items_;var deferred=this.q_.defer();var resultItems=items.slice(offset,offset+count);var result={offset:offset,items:resultItems};if(opt_withTotalCount)result.totalCount=items.length;deferred.resolve(result);return deferred.promise};MemoryItemsProviderController.prototype.fetchFilteredItems=function(filter,offset,count){filter=filter.toLowerCase();var items=this.items_;var deferred=this.q_.defer();
var filteredItems=[];angular.forEach(items,function(item){if(JSON.stringify(item).toLowerCase().indexOf(filter)!=-1)filteredItems.push(item)});filteredItems=filteredItems.slice(offset,offset+count);var result={offset:offset,items:filteredItems};deferred.resolve(result);return deferred.promise};grrUi.core.memoryItemsProviderDirective.MemoryItemsProviderDirective=function(){return{restrict:"A",priority:2E3,controller:MemoryItemsProviderController}};grrUi.core.memoryItemsProviderDirective.MemoryItemsProviderDirective.directive_name=
"grrMemoryItemsProvider"});goog.provide("grrUi.core.onScrollIntoViewDirective.OnScrollIntoViewController");goog.provide("grrUi.core.onScrollIntoViewDirective.OnScrollIntoViewDirective");
goog.scope(function(){grrUi.core.onScrollIntoViewDirective.OnScrollIntoViewController=function($scope,$element,$attrs,$interval,$window){this.scope_=$scope;this.attrs_=$attrs;this.element_=$element;this.window_=$window;this.currentlyVisible=false;var stop=$interval(this.onInterval.bind(this),100);$scope.$on("$destroy",function(){$interval.cancel(stop)})};var OnScrollIntoViewController=grrUi.core.onScrollIntoViewDirective.OnScrollIntoViewController;OnScrollIntoViewController.prototype.onInterval=function(){var elemOffset=
$(this.element_).offset();var elemWidth=$(this.element_).width();var elemHeight=$(this.element_).height();var elem=document.elementFromPoint(elemOffset.left-$(this.window_).scrollLeft()+1,elemOffset.top-$(this.window_).scrollTop()+1);var isVisible=elem==$(this.element_)[0];if(!isVisible){elem=document.elementFromPoint(elemOffset.left+elemWidth-$(this.window_).scrollLeft()-1,elemOffset.top+elemHeight-$(this.window_).scrollTop()-1);isVisible=elem==$(this.element_)[0]}if(!isVisible){elem=document.elementFromPoint(elemOffset.left+
elemWidth/2-$(this.window_).scrollLeft(),elemOffset.top+elemHeight/2-$(this.window_).scrollTop());isVisible=elem==$(this.element_)[0]}if(this.currentlyVisible!=isVisible){this.currentlyVisible=isVisible;if(isVisible)this.scope_.$eval(this.attrs_["grrOnScrollIntoView"])}};grrUi.core.onScrollIntoViewDirective.OnScrollIntoViewDirective=function(){return{restrict:"A",controller:OnScrollIntoViewController}};grrUi.core.onScrollIntoViewDirective.OnScrollIntoViewDirective.directive_name="grrOnScrollIntoView"});goog.provide("grrUi.core.pagedFilteredTableDirective.PagedFilteredTableController");goog.provide("grrUi.core.pagedFilteredTableDirective.PagedFilteredTableDirective");goog.provide("grrUi.core.pagedFilteredTableDirective.TableBottomDirective");goog.provide("grrUi.core.pagedFilteredTableDirective.TableTopDirective");
goog.scope(function(){grrUi.core.pagedFilteredTableDirective.TableTopDirective=function(){return{scope:{parentController:"="},require:"^grrPagedFilteredTable",templateUrl:"/static/angular-components/core/"+"paged-filtered-table-top.html",restrict:"E"}};grrUi.core.pagedFilteredTableDirective.TableTopDirective.directive_name="grrPagedFilteredTableTop";grrUi.core.pagedFilteredTableDirective.TableBottomDirective=function(){return{scope:{parentController:"="},require:"^grrPagedFilteredTable",templateUrl:"/static/angular-components/core/"+
"paged-filtered-table-bottom.html",restrict:"E"}};grrUi.core.pagedFilteredTableDirective.TableBottomDirective.directive_name="grrPagedFilteredTableBottom";grrUi.core.pagedFilteredTableDirective.PagedFilteredTableController=function($scope,$element,$transclude,$compile,$interval){this.scope_=$scope;this.scope_.pageSize;this.scope_.autoRefreshInterval;this.element_=$element;this.transclude_=$transclude;this.compile_=$compile;this.interval_=$interval;this.itemsProvider;this.currentPage=0;this.paginationSelectedPage=
1;this.showLoading=true;this.items=[];this.totalCount;this.pageSize=this.scope_.pageSize||PagedFilteredTableController.DEFAULT_PAGE_SIZE;this.filterEditedValue="";this.filterValue="";this.filterApplied=false;this.filterFinished=false;this.requestCounter_=0;this.autoRefreshInProgress_=false;this.addTopDirective_();this.addBottomDirective_();this.scope_.$watch("::controller.itemsProvider",function(){this.fetchUnfilteredItems(true)}.bind(this));if(this.scope_.autoRefreshInterval){var refreshTimer=this.interval_(this.onAutoRefresh_.bind(this),
this.scope_.autoRefreshInterval);this.scope_.$on("$destroy",function(){this.interval_.cancel(refreshTimer)}.bind(this))}};var PagedFilteredTableController=grrUi.core.pagedFilteredTableDirective.PagedFilteredTableController;PagedFilteredTableController.DEFAULT_PAGE_SIZE=50;PagedFilteredTableController.prototype.addTopDirective_=function(){var template=angular.element('<grr-paged-filtered-table-top parent-controller="controller" />');var table=this.element_.closest("table");template.insertBefore(table);
this.compile_(template)(this.scope_)};PagedFilteredTableController.prototype.addBottomDirective_=function(){var template=angular.element('<grr-paged-filtered-table-bottom parent-controller="controller" />');var table=this.element_.closest("table");template.insertAfter(table);this.compile_(template)(this.scope_)};PagedFilteredTableController.prototype.wrapWithCounterCheck_=function(callback){this.requestCounter_+=1;var curRequestCounter=this.requestCounter_;return function(data){if(this.requestCounter_==
curRequestCounter)return callback(data)}.bind(this)};PagedFilteredTableController.prototype.fetchUnfilteredItems=function(withTotalCount){this.showLoading=true;this.setItems_([]);this.itemsProvider.fetchItems(this.currentPage*this.pageSize,this.pageSize,withTotalCount).then(this.wrapWithCounterCheck_(this.onFetchedUnfilteredItems_.bind(this)))};PagedFilteredTableController.prototype.onFetchedUnfilteredItems_=function(items){this.showLoading=false;this.setItems_(items.items);if(angular.isDefined(items.totalCount))this.totalCount=
items.totalCount};PagedFilteredTableController.prototype.applyFilter=function(){this.filterValue=this.filterEditedValue;this.filterApplied=this.filterValue!="";this.filterFinished=false;this.currentPage=0;this.paginationSelectedPage=1;this.setItems_([]);if(this.filterApplied)this.fetchFilteredItems();else this.fetchUnfilteredItems(false)};PagedFilteredTableController.prototype.fetchFilteredItems=function(opt_numPages){if(angular.isUndefined(opt_numPages))opt_numPages=1;this.showLoading=true;this.itemsProvider.fetchFilteredItems(this.filterValue,
this.items.length,this.pageSize*opt_numPages).then(this.wrapWithCounterCheck_(this.onFetchedFilteredItems_.bind(this)))};PagedFilteredTableController.prototype.onFetchedFilteredItems_=function(items){this.showLoading=false;this.setItems_(this.items.concat(items.items));if(items.items.length==0||items.items.length%this.pageSize!=0)this.filterFinished=true};PagedFilteredTableController.prototype.setItems_=function(newItems){var indexOffset=0;if(angular.equals(this.items,newItems.slice(0,this.items.length)))indexOffset=
this.items.length;else this.element_.siblings().remove();this.items=newItems;for(var i=indexOffset;i<this.items.length;++i)this.transclude_(function(clone,scope){scope.item=this.items[i];scope.$index=i;this.element_.parent().append(clone)}.bind(this),this.element_.parent())};PagedFilteredTableController.prototype.onAutoRefresh_=function(){if(this.filterApplied||this.items.length>=this.pageSize||this.autoRefreshInProgress_)return;var callback=this.wrapWithCounterCheck_(this.onFetchedUnfilteredItems_.bind(this));
this.autoRefreshInProgress_=true;this.itemsProvider.fetchItems(this.currentPage*this.pageSize,this.pageSize,true).then(callback).finally(function(){this.autoRefreshInProgress_=false}.bind(this))};PagedFilteredTableController.prototype.onPageChange=function(newPage){this.currentPage=newPage;if(!this.filterApplied)this.fetchUnfilteredItems(false)};grrUi.core.pagedFilteredTableDirective.PagedFilteredTableDirective=function(){return{scope:{pageSize:"=?",autoRefreshInterval:"=?"},transclude:"element",
restrict:"A",priority:1E3,terminal:true,require:["?grrMemoryItemsProvider","?grrApiItemsProvider"],controller:PagedFilteredTableController,controllerAs:"controller",link:function(scope,element,attrs,controllers){var providerController=undefined;for(var i=0;i<controllers.length;++i)if(angular.isObject(controllers[i])){if(angular.isDefined(providerController))throw new Error("Can have only 1 provider.");providerController=controllers[i]}if(angular.isUndefined(providerController))throw new Error("Data provider not specified.");
scope.controller.itemsProvider=providerController}}};grrUi.core.pagedFilteredTableDirective.PagedFilteredTableDirective.directive_name="grrPagedFilteredTable"});goog.provide("grrUi.core.periodicRefreshDirective.PeriodicRefreshController");goog.provide("grrUi.core.periodicRefreshDirective.PeriodicRefreshDirective");
goog.scope(function(){grrUi.core.periodicRefreshDirective.PeriodicRefreshController=function($scope,$interval){this.scope_=$scope;this.interval_=$interval;this.refreshTrigger=0;this.updateOperationInterval_;this.scope_.$watch("interval",this.onIntervalChange_.bind(this));this.scope_.$on("$destroy",function(){if(this.updateOperationInterval_)this.interval_.cancel(this.updateOperationInterval_)}.bind(this))};var PeriodicRefreshController=grrUi.core.periodicRefreshDirective.PeriodicRefreshController;
PeriodicRefreshController.prototype.onIntervalChange_=function(newValue){if(this.updateOperationInterval_){this.interval_.cancel(this.updateOperationInterval_);this.updateOperationInterval_=null}if(angular.isDefined(newValue))this.updateOperationInterval_=this.interval_(this.onInterval_.bind(this),newValue)};PeriodicRefreshController.prototype.onInterval_=function(){this.refreshTrigger+=1;if(this.scope_["onRefresh"])this.scope_["onRefresh"]()};grrUi.core.periodicRefreshDirective.PeriodicRefreshDirective=
function(){return{scope:{interval:"=",onRefresh:"&"},restrict:"EA",transclude:true,template:"<grr-force-refresh "+'refresh-trigger="controller.refreshTrigger">'+"<ng-transclude /></grr-force-refresh>",controller:PeriodicRefreshController,controllerAs:"controller"}};grrUi.core.periodicRefreshDirective.PeriodicRefreshDirective.directive_name="grrPeriodicRefresh"});goog.provide("grrUi.core.reflectionService.ReflectionService");
goog.scope(function(){grrUi.core.reflectionService.ReflectionService=function($q,grrApiService){this.q_=$q;this.grrApiService_=grrApiService;this.descriptorsCache_;this.requestsQueue_=[]};var ReflectionService=grrUi.core.reflectionService.ReflectionService;ReflectionService.service_name="grrReflectionService";ReflectionService.prototype.processRequestsQueue_=function(){angular.forEach(this.requestsQueue_,function(request){var result=this.getRDFValueDescriptorFromCache_(request[1],request[2]);request[0].resolve(result)}.bind(this));
this.requestsQueue_=[]};ReflectionService.prototype.getRDFValueDescriptorFromCache_=function(valueType,opt_withDeps){if(!opt_withDeps)return this.descriptorsCache_[valueType];else{var results={};var fillInResult=function(type){if(angular.isDefined(results[type]))return;var descriptor=this.descriptorsCache_[type];results[type]=descriptor;angular.forEach(descriptor["fields"],function(fieldDescriptor){if(angular.isDefined(fieldDescriptor["type"]))fillInResult(fieldDescriptor["type"])})}.bind(this);fillInResult(valueType);
return results}};ReflectionService.prototype.getRDFValueDescriptor=function(valueType,opt_withDeps){var deferred=this.q_.defer();if(angular.isDefined(this.descriptorsCache_)){var result=this.getRDFValueDescriptorFromCache_(valueType,opt_withDeps);deferred.resolve(result);return deferred.promise}else{if(this.requestsQueue_.length===0){var apiPromise=this.grrApiService_.get("reflection/rdfvalue/all");apiPromise.then(function(response){this.descriptorsCache_={};angular.forEach(response["data"]["items"],
function(item){this.descriptorsCache_[item["name"]]=item}.bind(this));return this.processRequestsQueue_()}.bind(this))}this.requestsQueue_.push([deferred,valueType,opt_withDeps]);return deferred.promise}}});goog.provide("grrUi.core.fileDownloadUtils.downloadableVfsRoots");goog.provide("grrUi.core.fileDownloadUtils.getPathSpecFromValue");goog.provide("grrUi.core.fileDownloadUtils.makeValueDownloadable");goog.provide("grrUi.core.fileDownloadUtils.pathSpecToAff4Path");goog.provide("grrUi.core.fileDownloadUtils.vfsRoots");
goog.scope(function(){var AFF4_PREFIXES={"OS":"fs/os","TSK":"fs/tsk","REGISTRY":"registry","MEMORY":"devices/memory","TMPFILE":"temp"};var splitPathspec=function(pathspec){var result=[];var cur=pathspec["value"];while(angular.isDefined(cur["pathtype"])){result.push(cur);if(angular.isDefined(cur["nested_path"]))cur=cur["nested_path"]["value"];else break}return result};grrUi.core.fileDownloadUtils.pathSpecToAff4Path=function(pathspec,clientId){var components=splitPathspec(pathspec);var firstComponent=
components[0];var dev=firstComponent["path"]["value"];if(angular.isDefined(firstComponent["offset"]))dev+=":"+Math.round(firstComponent["offset"]["value"]/512);var result,start;if(components.length>1&&firstComponent["pathtype"]["value"]=="OS"&&components[1]["pathtype"]["value"]=="TSK"){result=["aff4:",clientId,AFF4_PREFIXES["TSK"],dev];start=1}else{result=["aff4:",clientId,AFF4_PREFIXES[firstComponent["pathtype"]["value"]]];start=0}for(var i=start;i<components.length;++i){var p=components[i];var component=
p["path"]["value"];if(component.startsWith("/"))component=component.substring(1);if(angular.isDefined(p["offset"]))component+=":"+Math.round(p["offset"]["value"]/512);if(angular.isDefined(p["stream_name"]))component+=":"+p["stream_name"]["value"];result.push(component)}return result.join("/")};var pathSpecToAff4Path=grrUi.core.fileDownloadUtils.pathSpecToAff4Path;grrUi.core.fileDownloadUtils.vfsRoots=["fs","registry","temp"];grrUi.core.fileDownloadUtils.downloadableVfsRoots=["fs","temp"];grrUi.core.fileDownloadUtils.getPathSpecFromValue=
function(value){if(!value)return null;if(value["type"]=="ApiFlowResult"||value["type"]=="ApiHuntResult")value=value["value"]["payload"];switch(value["type"]){case "StatEntry":return value["value"]["pathspec"];case "FileFinderResult":var st=value["value"]["stat_entry"];if(angular.isDefined(st)&&angular.isDefined(st["value"]["pathspec"]))return st["value"]["pathspec"];return null;case "ArtifactFilesDownloaderResult":return grrUi.core.fileDownloadUtils.getPathSpecFromValue(value["value"]["downloaded_file"]);
default:return null}};grrUi.core.fileDownloadUtils.makeStatEntryDownloadable_=function(value,downloadUrl,downloadParams){var originalValue=angular.copy(value);for(var prop in value)if(value.hasOwnProperty(prop))delete value[prop];angular.extend(value,{type:"__DownloadableStatEntry",originalValue:originalValue,downloadUrl:downloadUrl,downloadParams:downloadParams})};grrUi.core.fileDownloadUtils.makeFileFinderResultDownloadable_=function(value,downloadUrl,downloadParams){grrUi.core.fileDownloadUtils.makeStatEntryDownloadable_(value["value"]["stat_entry"],
downloadUrl,downloadParams)};grrUi.core.fileDownloadUtils.makeArtifactFilesDownloaderResultDownloadable_=function(value,downloadUrl,downloadParams){grrUi.core.fileDownloadUtils.makeValueDownloadable(value["value"]["downloaded_file"],downloadUrl,downloadParams)};grrUi.core.fileDownloadUtils.makeValueDownloadable=function(value,downloadUrl,downloadParams){if(!value)return false;if(value["type"]==="ApiFlowResult"||value["type"]==="ApiHuntResult")value=value["value"]["payload"];switch(value["type"]){case "StatEntry":grrUi.core.fileDownloadUtils.makeStatEntryDownloadable_(value,
downloadUrl,downloadParams);return true;case "FileFinderResult":grrUi.core.fileDownloadUtils.makeFileFinderResultDownloadable_(value,downloadUrl,downloadParams);return true;case "ArtifactFilesDownloaderResult":grrUi.core.fileDownloadUtils.makeArtifactFilesDownloaderResultDownloadable_(value,downloadUrl,downloadParams);return true;default:return false}}});goog.provide("grrUi.core.resultsCollectionDirective.ResultsCollectionController");goog.provide("grrUi.core.resultsCollectionDirective.ResultsCollectionDirective");goog.require("grrUi.core.fileDownloadUtils.getPathSpecFromValue");
goog.scope(function(){grrUi.core.resultsCollectionDirective.AUTO_REFRESH_INTERVAL_MS=20*1E3;var MAX_ITEMS_TO_CHECK_FOR_FILES=50;grrUi.core.resultsCollectionDirective.ResultsCollectionController=function($scope){this.scope_=$scope;this.resultsArePresent;this.resultsAreFiles;this.autoRefreshInterval=grrUi.core.resultsCollectionDirective.AUTO_REFRESH_INTERVAL_MS;this.numCheckedItems_=0};var ResultsCollectionController=grrUi.core.resultsCollectionDirective.ResultsCollectionController;ResultsCollectionController.prototype.transformItems=
function(items){if(items.length>0)this.resultsArePresent=true;if(!this.resultsAreFiles&&this.numCheckedItems_<MAX_ITEMS_TO_CHECK_FOR_FILES){this.numCheckedItems_+=items.length;this.resultsAreFiles=false;for(var i=0;i<items.length;i++)if(grrUi.core.fileDownloadUtils.getPathSpecFromValue(items[i])!=null){this.resultsAreFiles=true;break}}if(this.scope_["transformItems"])return this.scope_["transformItems"]({"items":items});else return items};grrUi.core.resultsCollectionDirective.ResultsCollectionDirective=
function(){return{scope:{resultsUrl:"=",exportedResultsUrl:"=",outputPluginsUrl:"=",exportCommandUrl:"=?",downloadFilesUrl:"=",transformItems:"&?"},restrict:"E",templateUrl:"/static/angular-components/core/results-collection.html",controller:ResultsCollectionController,controllerAs:"controller"}};grrUi.core.resultsCollectionDirective.ResultsCollectionDirective.directive_name="grrResultsCollection"});goog.provide("grrUi.core.searchBoxDirective.SearchBoxController");goog.provide("grrUi.core.searchBoxDirective.SearchBoxDirective");
goog.scope(function(){var SEARCH_KEYWORDS=["host","mac","ip","user","label"];grrUi.core.searchBoxDirective.SearchBoxController=function($scope,$element,$interval,grrApiService,grrRoutingService){this.scope_=$scope;this.element_=$element;this.interval_=$interval;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.query="";this.labels=[];this.grrApiService_.get("/clients/labels").then(this.onGetLabels_.bind(this))};var SearchBoxController=grrUi.core.searchBoxDirective.SearchBoxController;
SearchBoxController.prototype.onGetLabels_=function(response){angular.forEach(response["data"]["items"],function(label){this.labels.push("label:"+label["value"]["name"]["value"])}.bind(this))};SearchBoxController.prototype.submitQuery=function(){if(this.isHuntId_(this.query))this.checkHunt_(this.query);else this.grrRoutingService_.go("search",{q:this.query})};SearchBoxController.prototype.isHuntId_=function(input){var hunt_regex=/^[A-Z0-9]+:[A-F0-9]{6,12}$/i;if(!hunt_regex.test(input))return false;
var components=input.split(":");var potential_keyword=components[0].toLowerCase();return SEARCH_KEYWORDS.indexOf(potential_keyword)===-1};SearchBoxController.prototype.checkHunt_=function(huntId){this.grrApiService_.get("hunts/"+huntId).then(function success(response){var huntUrn=response.data["value"]["urn"]["value"];var components=huntUrn.split("/");var huntId=components[components.length-1];this.grrRoutingService_.go("hunts",{huntId:huntId})}.bind(this),function error(){this.grrRoutingService_.go("search",
{q:this.query})}.bind(this))};SearchBoxController.prototype.contextHelpUrl="investigating-with-grr/searching-for-client.html";grrUi.core.searchBoxDirective.SearchBoxDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/core/search-box.html",controller:SearchBoxController,controllerAs:"controller"}};grrUi.core.searchBoxDirective.SearchBoxDirective.directive_name="grrSearchBox"});goog.provide("grrUi.core.serverErrorDialogDirective.ServerErrorDialogController");goog.provide("grrUi.core.serverErrorDialogDirective.ServerErrorDialogDirective");
goog.scope(function(){grrUi.core.serverErrorDialogDirective.ServerErrorDialogController=function($scope){this.scope_=$scope};var ServerErrorDialogController=grrUi.core.serverErrorDialogDirective.ServerErrorDialogController;grrUi.core.serverErrorDialogDirective.ServerErrorDialogDirective=function(){return{scope:{close:"&",message:"=",traceBack:"="},restrict:"E",templateUrl:"/static/angular-components/core/server-error-dialog.html",controller:ServerErrorDialogController,controllerAs:"controller"}};
grrUi.core.serverErrorDialogDirective.ServerErrorDialogDirective.directive_name="grrServerErrorDialog"});goog.provide("grrUi.core.serverErrorInterceptorFactory.ServerErrorInterceptorFactory");goog.require("grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective");
goog.scope(function(){var ERROR_EVENT_NAME=grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective.error_event_name;var INTERCEPTED_STATUS_CODES=[500];grrUi.core.serverErrorInterceptorFactory.needsInterception_=function(response){return INTERCEPTED_STATUS_CODES.indexOf(response.status)!==-1};grrUi.core.serverErrorInterceptorFactory.extractError_=function(response){var data=response.data||{};return{message:data.message||"Unknown Server Error",traceBack:data.traceBack}};grrUi.core.serverErrorInterceptorFactory.ServerErrorInterceptorFactory=
function($rootScope,$q){return{responseError:function(response){if(grrUi.core.serverErrorInterceptorFactory.needsInterception_(response)){var error=grrUi.core.serverErrorInterceptorFactory.extractError_(response);$rootScope.$broadcast(ERROR_EVENT_NAME,error)}return $q.reject(response)}}};var ServerErrorInterceptorFactory=grrUi.core.serverErrorInterceptorFactory.ServerErrorInterceptorFactory;ServerErrorInterceptorFactory.factory_name="grrServerErrorInterceptorFactory"});goog.provide("grrUi.core.serverErrorPreviewDirective.ServerErrorPreviewController");goog.provide("grrUi.core.serverErrorPreviewDirective.ServerErrorPreviewDirective");goog.require("grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective");
goog.scope(function(){var ServerErrorButtonDirective=grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective;var ERROR_EVENT_NAME=ServerErrorButtonDirective.error_event_name;var ERROR_PREVIEW_INTERVAL=5E3;grrUi.core.serverErrorPreviewDirective.ServerErrorPreviewController=function($rootScope,$scope,$timeout){this.rootScope_=$rootScope;this.scope_=$scope;this.timeout_=$timeout;this.error;this.labelVisible;this.rootScope_.$on(ERROR_EVENT_NAME,this.onErrorEvent.bind(this))};var ServerErrorPreviewController=
grrUi.core.serverErrorPreviewDirective.ServerErrorPreviewController;ServerErrorPreviewController.prototype.onErrorEvent=function(unused_event,error){if(!angular.isObject(error)||!angular.isString(error.message))return;if(error.message.length){this.error=error;this.labelVisible=true;this.timeout_(function(){this.labelVisible=false}.bind(this),ERROR_PREVIEW_INTERVAL)}else{this.error=null;this.labelVisible=false}};grrUi.core.serverErrorPreviewDirective.ServerErrorPreviewDirective=function(){return{scope:true,
restrict:"E",replace:true,template:'<div class="navbar-text" ng-show="controller.labelVisible">'+"    {$ controller.error.message $}"+"</div>",controller:ServerErrorPreviewController,controllerAs:"controller"}};var ServerErrorPreviewDirective=grrUi.core.serverErrorPreviewDirective.ServerErrorPreviewDirective;ServerErrorPreviewDirective.directive_name="grrServerErrorPreview";ServerErrorPreviewDirective.error_preview_interval=5E3});goog.provide("grrUi.core.splitterDirective.SplitterController");goog.provide("grrUi.core.splitterDirective.SplitterDirective");goog.provide("grrUi.core.splitterDirective.SplitterPaneDirective");
goog.scope(function(){grrUi.core.splitterDirective.SplitterController=function($scope,$element,$interval){this.scope_=$scope;this.element_=$element;this.interval_=$interval;this.scope_.orientation;this.panes=[]};var SplitterController=grrUi.core.splitterDirective.SplitterController;SplitterController.prototype.addPane=function(pane){this.panes.push(pane)};SplitterController.prototype.link=function(){var closeableTo;if(angular.isDefined(this.scope_["closeableTo"]))closeableTo=Number(this.scope_["closeableTo"]);
else closeableTo=100;var splitterOptions={animSpeed:50,closeableto:closeableTo,minAsize:this.scope_["minLeftPaneSize"]||0,maxAsize:this.scope_["maxLeftPaneSize"]||3E3};if(this.scope_.orientation==="horizontal")splitterOptions["splitHorizontal"]=true;else if(this.scope_.orientation==="vertical")splitterOptions["splitVertical"]=true;else throw Error('Orientation can be either "vertical" or "horizontal".');splitterOptions["A"]=$(this.panes[0].elem);splitterOptions["B"]=$(this.panes[1].elem);var count=
0;var stop;var registerSplitter=function(){if($(this.element_).width()>0&&$(this.element_).height()>0||count>5){$(this.element_).children("div.splitter").splitter(splitterOptions);this.interval_.cancel(stop)}else count+=1}.bind(this);stop=this.interval_(registerSplitter,100);registerSplitter();this.element_.on("$destroy",function(){this.interval_.cancel(stop)}.bind(this))};grrUi.core.splitterDirective.SplitterDirective=function(){return{scope:{orientation:"@",closeableTo:"@",minLeftPaneSize:"@",maxLeftPaneSize:"@"},
restrict:"EA",transclude:true,template:'<div class="splitter fill-parent no-margins" '+"ng-transclude></div>",controller:SplitterController,controllerAs:"controller",link:function(scope,element,attrs){scope.controller.link()}}};grrUi.core.splitterDirective.SplitterDirective.directive_name="grrSplitter";grrUi.core.splitterDirective.SplitterPaneDirective=function(){return{scope:{},restrict:"EA",require:"^grrSplitter",transclude:true,template:'<div class="fill-parent no-margins" ng-transclude></div>',
link:function(scope,element,attrs,grrSplitterCtrl){scope.elem=element;grrSplitterCtrl.addPane(scope)}}};grrUi.core.splitterDirective.SplitterPaneDirective.directive_name="grrSplitterPane"});goog.provide("grrUi.core.timeService.TimeService");
goog.scope(function(){grrUi.core.timeService.TimeService=function(){};var TimeService=grrUi.core.timeService.TimeService;TimeService.service_name="grrTimeService";TimeService.prototype.getCurrentTimeMs=function(){return(new Date).getTime()};TimeService.prototype.formatAsUTC=function(opt_timestamp){var when=angular.isUndefined(opt_timestamp)?moment():moment(opt_timestamp);return when.utc().format("YYYY-MM-DD HH:mm:ss")+" UTC"};TimeService.prototype.getFormattedDiffFromCurrentTime=function(timestamp){var diff=
moment(timestamp).diff(moment());if(Math.abs(diff)<60*1E3)return"now";return moment.duration(diff).humanize(true)}});goog.provide("grrUi.core.timeSinceFilter.TimeSinceFilter");
goog.scope(function(){grrUi.core.timeSinceFilter.filterImplementation=function(grrTimeService,input){var currentTimeMs=grrTimeService.getCurrentTimeMs();var inputTimeMs=input/1E3;if(inputTimeMs<1E-6)return"<invalid time value>";var differenceSec=Math.abs(Math.round((currentTimeMs-inputTimeMs)/1E3));var measureUnit;var measureValue;if(differenceSec<60){measureUnit="seconds";measureValue=differenceSec}else if(differenceSec<60*60){measureUnit="minutes";measureValue=Math.floor(differenceSec/60)}else if(differenceSec<
60*60*24){measureUnit="hours";measureValue=Math.floor(differenceSec/(60*60))}else{measureUnit="days";measureValue=Math.floor(differenceSec/(60*60*24))}if(currentTimeMs>=inputTimeMs)return measureValue+" "+measureUnit+" ago";else return"in "+measureValue+" "+measureUnit};grrUi.core.timeSinceFilter.TimeSinceFilter=function(grrTimeService){return function(input){return grrUi.core.timeSinceFilter.filterImplementation(grrTimeService,input)}};grrUi.core.timeSinceFilter.TimeSinceFilter.filter_name="grrTimeSince"});goog.provide("grrUi.core.timestampFilter.TimestampFilter");goog.scope(function(){grrUi.core.timestampFilter.filterImplementation=function(grrTimeService,value){if(angular.isNumber(value)){var timestamp=value/1E3;return grrTimeService.formatAsUTC(timestamp)}else return"-"};grrUi.core.timestampFilter.TimestampFilter=function(grrTimeService){return function(input){return grrUi.core.timestampFilter.filterImplementation(grrTimeService,input)}};grrUi.core.timestampFilter.TimestampFilter.filter_name="grrTimestamp"});goog.provide("grrUi.core.versionDropdownDirective.VersionDropdownController");goog.provide("grrUi.core.versionDropdownDirective.VersionDropdownDirective");
goog.scope(function(){var REFRESH_VERSIONS_EVENT="RefreshVersionsEvent";grrUi.core.versionDropdownDirective.VersionDropdownController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.versions;this.version;this.updateInProgress_=false;this.scope_.$watchGroup(["url","version"],this.fetchVersions_.bind(this));this.scope_.$watch("controller.version",this.onControllerVersionChange_.bind(this));this.scope_.$on(REFRESH_VERSIONS_EVENT,this.fetchVersions_.bind(this))};
var VersionDropdownController=grrUi.core.versionDropdownDirective.VersionDropdownController;VersionDropdownController.prototype.fetchVersions_=function(){var url=this.scope_["url"];var responseField=this.scope_["responseField"]||"times";if(angular.isDefined(url)){this.updateInProgress_=true;this.grrApiService_.get(url).then(function success(response){if(url!=this.scope_["url"])return;this.versions=response["data"][responseField];if(!this.versions.length)return;if(this.scope_["version"]){this.versions.push({value:this.scope_["version"],
type:"RDFDatetime"});this.versions.sort(function(v1,v2){if(v1["value"]<v2["value"])return 1;else if(v1["value"]==v2["value"])return 0;else return-1}.bind(this));this.versions=this.versions.filter(function(value,index,arr){if(index==0)return true;else return value["value"]!=arr[index-1]["value"]}.bind(this));this.version=this.scope_["version"].toString()}else this.version="HEAD"}.bind(this)).finally(function(){this.updateInProgress_=false}.bind(this))}};VersionDropdownController.prototype.onControllerVersionChange_=
function(){if(angular.isUndefined(this.version))return;if(this.version=="HEAD")this.scope_["version"]=undefined;else this.scope_["version"]=parseInt(this.version,10)};VersionDropdownController.prototype.isSelected=function(value){if(value=="HEAD")return this.version==value;else return parseInt(this.version,10)==value};VersionDropdownController.prototype.isLatestSelected=function(){if(this.updateInProgress_)return true;if(this.version=="HEAD")return true;return!this.versions||this.versions.length===
0||!this.scope_["version"]||this.version===this.versions[0].value.toString()};grrUi.core.versionDropdownDirective.VersionDropdownDirective=function(){return{restrict:"E",scope:{url:"=",version:"=",responseField:"@"},templateUrl:"/static/angular-components/core/version-dropdown.html",controller:VersionDropdownController,controllerAs:"controller"}};grrUi.core.versionDropdownDirective.VersionDropdownDirective.directive_name="grrVersionDropdown";grrUi.core.versionDropdownDirective.VersionDropdownDirective.REFRESH_VERSIONS_EVENT=
REFRESH_VERSIONS_EVENT});goog.provide("grrUi.core.wizardFormDirective.WizardFormController");goog.provide("grrUi.core.wizardFormDirective.WizardFormDirective");
goog.scope(function(){grrUi.core.wizardFormDirective.WizardFormController=function($scope){this.scope_=$scope;this.pages=[];this.currentPage;this.currentPageIndex;this.scope_.$watchCollection("controller.pages",this.onPagesOrCurrentPageChange_.bind(this));this.scope_.$watch("controller.currentPage",this.onPagesOrCurrentPageChange_.bind(this));this.scope_.$watch("controller.currentPage",function(newValue){if(angular.isDefined(newValue))newValue.onShow()}.bind(this))};var WizardFormController=grrUi.core.wizardFormDirective.WizardFormController;
WizardFormController.prototype.onPagesOrCurrentPageChange_=function(){this.currentPageIndex=this.pages.indexOf(this.currentPage)};WizardFormController.prototype.back=function(){var index=this.pages.indexOf(this.currentPage);if(index==0)throw new Error("Can't go back from the first page.");this.currentPage=this.pages[index-1]};WizardFormController.prototype.next=function(){var index=this.pages.indexOf(this.currentPage);if(index<this.pages.length-1)this.currentPage=this.pages[index+1];else this.scope_["onResolve"]()};
WizardFormController.prototype.reject=function(){this.scope_["onReject"]()};WizardFormController.prototype.registerPage=function(pageController){this.pages.push(pageController);if(angular.isUndefined(this.currentPage))this.currentPage=pageController};grrUi.core.wizardFormDirective.WizardFormDirective=function(){return{scope:{title:"@",onResolve:"&",onReject:"&"},restrict:"E",transclude:true,templateUrl:"/static/angular-components/core/wizard-form.html",controller:WizardFormController,controllerAs:"controller"}};
grrUi.core.wizardFormDirective.WizardFormDirective.directive_name="grrWizardForm"});goog.provide("grrUi.core.wizardFormPageDirective.WizardFormPageController");goog.provide("grrUi.core.wizardFormPageDirective.WizardFormPageDirective");
goog.scope(function(){grrUi.core.wizardFormPageDirective.WizardFormPageController=function($scope,$attrs){this.scope_=$scope;this.attrs_=$attrs;this.formController;this.title;this.helpLink;this.prevButtonLabel="Back";this.nextButtonLabel="Next";this.noBackButton=false;this.isValid=true;this.scope_.$watch("title",function(newValue){this.title=newValue}.bind(this));this.scope_.$watch("prevButtonLabel",function(newValue){if(angular.isDefined(newValue))this.prevButtonLabel=newValue}.bind(this));this.scope_.$watch("nextButtonLabel",
function(newValue){if(angular.isDefined(newValue))this.nextButtonLabel=newValue}.bind(this));this.scope_.$watch("noBackButton",function(newValue){this.noBackButton=newValue}.bind(this));this.scope_.$watch("isValid",function(newValue){if(angular.isDefined(this.attrs_["isValid"]))this.isValid=newValue}.bind(this));this.scope_.$watch("helpLink",function(newValue){this.helpLink=newValue}.bind(this))};var WizardFormPageController=grrUi.core.wizardFormPageDirective.WizardFormPageController;WizardFormPageController.prototype.onShow=
function(){this.scope_["onShow"]()};grrUi.core.wizardFormPageDirective.WizardFormPageDirective=function(){return{scope:{title:"@",helpLink:"@",prevButtonLabel:"@",nextButtonLabel:"@",noBackButton:"=?",isValid:"=?",onShow:"&"},restrict:"E",transclude:true,templateUrl:"/static/angular-components/core/wizard-form-page.html",controller:WizardFormPageController,controllerAs:"controller",require:"^grrWizardForm",link:function(scope,element,attrs,formController){scope.controller.formController=formController;
formController.registerPage(scope.controller)}}};grrUi.core.wizardFormPageDirective.WizardFormPageDirective.directive_name="grrWizardFormPage"});goog.provide("grrUi.core.module");goog.require("grrUi.core.aff4ObjectRepresentationDirective.Aff4ObjectRepresentationDirective");goog.require("grrUi.core.apiItemsProviderDirective.ApiItemsProviderDirective");goog.require("grrUi.core.apiService.ApiService");goog.require("grrUi.core.basenameFilter.BasenameFilter");goog.require("grrUi.core.bindKeyDirective.BindKeyDirective");goog.require("grrUi.core.bytesToHexFilter.BytesToHexFilter");goog.require("grrUi.core.canaryOnlyDirective.CanaryOnlyDirective");
goog.require("grrUi.core.clockDirective.ClockDirective");goog.require("grrUi.core.confirmationDialogDirective.ConfirmationDialogDirective");goog.require("grrUi.core.dialogService.DialogService");goog.require("grrUi.core.disableIfNoTraitDirective.DisableIfNoTraitDirective");goog.require("grrUi.core.downloadCollectionAsDirective.DownloadCollectionAsDirective");goog.require("grrUi.core.downloadCollectionFilesDirective.DownloadCollectionFilesDirective");goog.require("grrUi.core.encodeUriComponentFilter.EncodeUriComponentFilter");
goog.require("grrUi.core.firebaseService.FirebaseService");goog.require("grrUi.core.forceRefreshDirective.ForceRefreshDirective");goog.require("grrUi.core.globalNotificationsDirective.GlobalNotificationsDirective");goog.require("grrUi.core.hexNumberFilter.HexNumberFilter");goog.require("grrUi.core.infiniteTableDirective.InfiniteTableDirective");goog.require("grrUi.core.loadingIndicatorDirective.LoadingIndicatorDirective");goog.require("grrUi.core.loadingIndicatorService.LoadingIndicatorService");
goog.require("grrUi.core.memoryItemsProviderDirective.MemoryItemsProviderDirective");goog.require("grrUi.core.onScrollIntoViewDirective.OnScrollIntoViewDirective");goog.require("grrUi.core.pagedFilteredTableDirective.PagedFilteredTableDirective");goog.require("grrUi.core.pagedFilteredTableDirective.TableBottomDirective");goog.require("grrUi.core.pagedFilteredTableDirective.TableTopDirective");goog.require("grrUi.core.periodicRefreshDirective.PeriodicRefreshDirective");goog.require("grrUi.core.reflectionService.ReflectionService");
goog.require("grrUi.core.resultsCollectionDirective.ResultsCollectionDirective");goog.require("grrUi.core.searchBoxDirective.SearchBoxDirective");goog.require("grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective");goog.require("grrUi.core.serverErrorDialogDirective.ServerErrorDialogDirective");goog.require("grrUi.core.serverErrorInterceptorFactory.ServerErrorInterceptorFactory");goog.require("grrUi.core.serverErrorPreviewDirective.ServerErrorPreviewDirective");goog.require("grrUi.core.splitterDirective.SplitterDirective");
goog.require("grrUi.core.splitterDirective.SplitterPaneDirective");goog.require("grrUi.core.timeService.TimeService");goog.require("grrUi.core.timeSinceFilter.TimeSinceFilter");goog.require("grrUi.core.timestampFilter.TimestampFilter");goog.require("grrUi.core.versionDropdownDirective.VersionDropdownDirective");goog.require("grrUi.core.wizardFormDirective.WizardFormDirective");goog.require("grrUi.core.wizardFormPageDirective.WizardFormPageDirective");
grrUi.core.module=angular.module("grrUi.core",["ngCookies","ui.bootstrap"]);grrUi.core.module.directive(grrUi.core.aff4ObjectRepresentationDirective.Aff4ObjectRepresentationDirective.directive_name,grrUi.core.aff4ObjectRepresentationDirective.Aff4ObjectRepresentationDirective);grrUi.core.module.directive(grrUi.core.apiItemsProviderDirective.ApiItemsProviderDirective.directive_name,grrUi.core.apiItemsProviderDirective.ApiItemsProviderDirective);
grrUi.core.module.directive(grrUi.core.bindKeyDirective.BindKeyDirective.directive_name,grrUi.core.bindKeyDirective.BindKeyDirective);grrUi.core.module.directive(grrUi.core.versionDropdownDirective.VersionDropdownDirective.directive_name,grrUi.core.versionDropdownDirective.VersionDropdownDirective);grrUi.core.module.directive(grrUi.core.forceRefreshDirective.ForceRefreshDirective.directive_name,grrUi.core.forceRefreshDirective.ForceRefreshDirective);
grrUi.core.module.directive(grrUi.core.loadingIndicatorDirective.LoadingIndicatorDirective.directive_name,grrUi.core.loadingIndicatorDirective.LoadingIndicatorDirective);grrUi.core.module.directive(grrUi.core.onScrollIntoViewDirective.OnScrollIntoViewDirective.directive_name,grrUi.core.onScrollIntoViewDirective.OnScrollIntoViewDirective);grrUi.core.module.directive(grrUi.core.memoryItemsProviderDirective.MemoryItemsProviderDirective.directive_name,grrUi.core.memoryItemsProviderDirective.MemoryItemsProviderDirective);
grrUi.core.module.directive(grrUi.core.pagedFilteredTableDirective.PagedFilteredTableDirective.directive_name,grrUi.core.pagedFilteredTableDirective.PagedFilteredTableDirective);grrUi.core.module.directive(grrUi.core.pagedFilteredTableDirective.TableTopDirective.directive_name,grrUi.core.pagedFilteredTableDirective.TableTopDirective);grrUi.core.module.directive(grrUi.core.pagedFilteredTableDirective.TableBottomDirective.directive_name,grrUi.core.pagedFilteredTableDirective.TableBottomDirective);
grrUi.core.module.directive(grrUi.core.periodicRefreshDirective.PeriodicRefreshDirective.directive_name,grrUi.core.periodicRefreshDirective.PeriodicRefreshDirective);grrUi.core.module.directive(grrUi.core.infiniteTableDirective.InfiniteTableDirective.directive_name,grrUi.core.infiniteTableDirective.InfiniteTableDirective);grrUi.core.module.directive(grrUi.core.resultsCollectionDirective.ResultsCollectionDirective.directive_name,grrUi.core.resultsCollectionDirective.ResultsCollectionDirective);
grrUi.core.module.directive(grrUi.core.splitterDirective.SplitterDirective.directive_name,grrUi.core.splitterDirective.SplitterDirective);grrUi.core.module.directive(grrUi.core.splitterDirective.SplitterPaneDirective.directive_name,grrUi.core.splitterDirective.SplitterPaneDirective);grrUi.core.module.directive(grrUi.core.clockDirective.ClockDirective.directive_name,grrUi.core.clockDirective.ClockDirective);
grrUi.core.module.directive(grrUi.core.downloadCollectionAsDirective.DownloadCollectionAsDirective.directive_name,grrUi.core.downloadCollectionAsDirective.DownloadCollectionAsDirective);grrUi.core.module.directive(grrUi.core.downloadCollectionFilesDirective.DownloadCollectionFilesDirective.directive_name,grrUi.core.downloadCollectionFilesDirective.DownloadCollectionFilesDirective);grrUi.core.module.directive(grrUi.core.wizardFormDirective.WizardFormDirective.directive_name,grrUi.core.wizardFormDirective.WizardFormDirective);
grrUi.core.module.directive(grrUi.core.wizardFormPageDirective.WizardFormPageDirective.directive_name,grrUi.core.wizardFormPageDirective.WizardFormPageDirective);grrUi.core.module.directive(grrUi.core.confirmationDialogDirective.ConfirmationDialogDirective.directive_name,grrUi.core.confirmationDialogDirective.ConfirmationDialogDirective);grrUi.core.module.directive(grrUi.core.disableIfNoTraitDirective.DisableIfNoTraitDirective.directive_name,grrUi.core.disableIfNoTraitDirective.DisableIfNoTraitDirective);
grrUi.core.module.directive(grrUi.core.canaryOnlyDirective.CanaryOnlyDirective.directive_name,grrUi.core.canaryOnlyDirective.CanaryOnlyDirective);grrUi.core.module.directive(grrUi.core.canaryOnlyDirective.NonCanaryOnlyDirective.directive_name,grrUi.core.canaryOnlyDirective.NonCanaryOnlyDirective);grrUi.core.module.directive(grrUi.core.searchBoxDirective.SearchBoxDirective.directive_name,grrUi.core.searchBoxDirective.SearchBoxDirective);
grrUi.core.module.directive(grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective.directive_name,grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective);grrUi.core.module.directive(grrUi.core.serverErrorDialogDirective.ServerErrorDialogDirective.directive_name,grrUi.core.serverErrorDialogDirective.ServerErrorDialogDirective);grrUi.core.module.directive(grrUi.core.serverErrorPreviewDirective.ServerErrorPreviewDirective.directive_name,grrUi.core.serverErrorPreviewDirective.ServerErrorPreviewDirective);
grrUi.core.module.directive(grrUi.core.globalNotificationsDirective.GlobalNotificationsDirective.directive_name,grrUi.core.globalNotificationsDirective.GlobalNotificationsDirective);grrUi.core.module.service(grrUi.core.apiService.ApiService.service_name,grrUi.core.apiService.ApiService);grrUi.core.module.service(grrUi.core.firebaseService.FirebaseService.service_name,grrUi.core.firebaseService.FirebaseService);grrUi.core.module.service(grrUi.core.reflectionService.ReflectionService.service_name,grrUi.core.reflectionService.ReflectionService);
grrUi.core.module.service(grrUi.core.timeService.TimeService.service_name,grrUi.core.timeService.TimeService);grrUi.core.module.service(grrUi.core.dialogService.DialogService.service_name,grrUi.core.dialogService.DialogService);grrUi.core.module.service(grrUi.core.loadingIndicatorService.LoadingIndicatorService.service_name,grrUi.core.loadingIndicatorService.LoadingIndicatorService);grrUi.core.module.filter(grrUi.core.basenameFilter.BasenameFilter.filter_name,grrUi.core.basenameFilter.BasenameFilter);
grrUi.core.module.filter(grrUi.core.bytesToHexFilter.BytesToHexFilter.filter_name,grrUi.core.bytesToHexFilter.BytesToHexFilter);grrUi.core.module.filter(grrUi.core.encodeUriComponentFilter.EncodeUriComponentFilter.filter_name,grrUi.core.encodeUriComponentFilter.EncodeUriComponentFilter);grrUi.core.module.filter(grrUi.core.hexNumberFilter.HexNumberFilter.filter_name,grrUi.core.hexNumberFilter.HexNumberFilter);grrUi.core.module.filter(grrUi.core.timeSinceFilter.TimeSinceFilter.filter_name,grrUi.core.timeSinceFilter.TimeSinceFilter);
grrUi.core.module.filter(grrUi.core.timestampFilter.TimestampFilter.filter_name,grrUi.core.timestampFilter.TimestampFilter);grrUi.core.module.factory(grrUi.core.serverErrorInterceptorFactory.ServerErrorInterceptorFactory.factory_name,grrUi.core.serverErrorInterceptorFactory.ServerErrorInterceptorFactory);grrUi.core.module.config(function($httpProvider){$httpProvider.interceptors.push(grrUi.core.serverErrorInterceptorFactory.ServerErrorInterceptorFactory.factory_name)});goog.provide("grrUi.core.semanticRegistry.SemanticRegistryService");
goog.scope(function(){grrUi.core.semanticRegistry.SemanticRegistryService=function($q,grrReflectionService){this.q_=$q;this.grrReflectionService_=grrReflectionService;this.directivesByType_={}};var SemanticRegistryService=grrUi.core.semanticRegistry.SemanticRegistryService;SemanticRegistryService.values_service_name="grrSemanticValueDirectivesRegistryService";SemanticRegistryService.forms_service_name="grrSemanticFormDirectivesRegistryService";SemanticRegistryService.repeated_forms_service_name="grrSemanticRepeatedFormDirectivesRegistryService";
SemanticRegistryService.output_plugins_service_name="grrOutputPluginsDirectivesRegistryService";SemanticRegistryService.prototype.registerDirective=function(type,directive){this.directivesByType_[type]=directive};SemanticRegistryService.prototype.findDirectiveForMro=function(mro,overrides){overrides=overrides||{};for(var i=0;i<mro.length;++i){var objType=mro[i];var directive=overrides[objType];if(angular.isUndefined(directive))directive=this.directivesByType_[objType];if(angular.isDefined(directive))return directive}return undefined};
SemanticRegistryService.prototype.findDirectiveForType=function(type,overrides){overrides=overrides||{};if(angular.isDefined(overrides[type])){var deferred=this.q_.defer();deferred.resolve(overrides[type]);return deferred.promise}if(angular.isDefined(this.directivesByType_[type])){var deferred=this.q_.defer();deferred.resolve(this.directivesByType_[type]);return deferred.promise}var handleDescriptor=function(descriptor){var directive=this.findDirectiveForMro(descriptor["mro"],overrides);if(angular.isDefined(directive))return directive;
else return this.q_.reject(new Error("No directive found."))}.bind(this);return this.grrReflectionService_.getRDFValueDescriptor(type).then(handleDescriptor)}});goog.provide("grrUi.forms.aff4AttributeFormDirective.Aff4AttributeFormController");goog.provide("grrUi.forms.aff4AttributeFormDirective.Aff4AttributeFormDirective");
goog.scope(function(){grrUi.forms.aff4AttributeFormDirective.Aff4AttributeFormController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrApiService_.get("/reflection/aff4/attributes").then(this.onGetAttributes_.bind(this));this.allowedOptions=[]};var Aff4AttributeFormController=grrUi.forms.aff4AttributeFormDirective.Aff4AttributeFormController;Aff4AttributeFormController.prototype.onGetAttributes_=function(response){this.allowedOptions=[];angular.forEach(response["data"]["items"],
function(item){this.allowedOptions.push(item["value"]["name"]["value"])}.bind(this));this.allowedOptions=this.allowedOptions.sort();if(this.allowedOptions.length>0&&!this.scope_["value"]["value"])this.scope_["value"]["value"]=this.allowedOptions[0]};grrUi.forms.aff4AttributeFormDirective.Aff4AttributeFormDirective=function(){return{restrict:"E",scope:{value:"=",metadata:"="},templateUrl:"/static/angular-components/forms/aff4-attribute-form.html",controller:Aff4AttributeFormController,controllerAs:"controller"}};
grrUi.forms.aff4AttributeFormDirective.Aff4AttributeFormDirective.directive_name="grrFormAff4Attribute";grrUi.forms.aff4AttributeFormDirective.Aff4AttributeFormDirective.semantic_type="AFF4Attribute"});goog.provide("grrUi.forms.autoGeneratedAES128KeyFormDirective.AutoGeneratedAES128KeyFormController");goog.provide("grrUi.forms.autoGeneratedAES128KeyFormDirective.AutoGeneratedAES128KeyFormDirective");goog.provide("grrUi.forms.autoGeneratedAES128KeyFormDirective.generateRandomBytes");grrUi.forms.autoGeneratedAES128KeyFormDirective.generateRandomBytes=function(length){var tokens="0123456789abcdef";var result=[];for(var i=0;i<length*2;++i)result.push(tokens[Math.floor(Math.random()*16)]);return result.join("")};
grrUi.forms.autoGeneratedAES128KeyFormDirective.AutoGeneratedAES128KeyFormController=function($scope){this.scope_=$scope;this.scope_.$watch("value",this.onValueChange_.bind(this))};var AutoGeneratedAES128KeyFormController=grrUi.forms.autoGeneratedAES128KeyFormDirective.AutoGeneratedAES128KeyFormController;AutoGeneratedAES128KeyFormController.prototype.onValueChange_=function(newValue){if(angular.isDefined(newValue)&&!newValue["value"])newValue["value"]=grrUi.forms.autoGeneratedAES128KeyFormDirective.generateRandomBytes(16)};
grrUi.forms.autoGeneratedAES128KeyFormDirective.AutoGeneratedAES128KeyFormDirective=function(){return{scope:{value:"=",metadata:"=?",hiddenFields:"=?"},restrict:"E",templateUrl:"/static/angular-components/forms/"+"auto-generated-aes128-key-form.html",controller:AutoGeneratedAES128KeyFormController,controllerAs:"controller"}};grrUi.forms.autoGeneratedAES128KeyFormDirective.AutoGeneratedAES128KeyFormDirective.directive_name="grrFormAutoGeneratedAes128Key";
grrUi.forms.autoGeneratedAES128KeyFormDirective.AutoGeneratedAES128KeyFormDirective.semantic_type="AutoGeneratedAES128Key";goog.provide("grrUi.forms.bytesFormDirective.BytesFormController");goog.provide("grrUi.forms.bytesFormDirective.BytesFormDirective");goog.provide("grrUi.forms.bytesFormDirective.bytesToHexEncodedString");goog.provide("grrUi.forms.bytesFormDirective.hexEncodedStringToBytes");goog.provide("grrUi.forms.bytesFormDirective.isByteString");
goog.scope(function(){grrUi.forms.bytesFormDirective.bytesToHexEncodedString=function(bytes){var segmentStart=0;var str=[];var blen=bytes.length;for(var i=0;i<blen;i+=1){var c=bytes.charCodeAt(i);if(c<32||c>126){var segmentLength=i-segmentStart;if(segmentLength>0)str.push(bytes.substr(segmentStart,segmentLength));segmentStart=i+1;var hc=c.toString(16);if(hc.length==1)hc="0"+hc;str.push("\\x"+hc)}}segmentLength=blen-segmentStart;if(segmentLength>0)str.push(bytes.substr(segmentStart,segmentLength));
return str.join("")};var bytesToHexEncodedString=grrUi.forms.bytesFormDirective.bytesToHexEncodedString;grrUi.forms.bytesFormDirective.hexEncodedStringToBytes=function(str){return str.replace(/\\x([0-9A-Fa-f]{2})/g,function(){return String.fromCharCode(parseInt(arguments[1],16))})};var hexEncodedStringToBytes=grrUi.forms.bytesFormDirective.hexEncodedStringToBytes;grrUi.forms.bytesFormDirective.isByteString=function(str){var blen=str.length;for(var i=0;i<blen;i+=1){var c=str.charCodeAt(i);if(c>=256)return false}return true};
var isByteString=grrUi.forms.bytesFormDirective.isByteString;grrUi.forms.bytesFormDirective.BytesFormController=function($scope,$window){this.scope_=$scope;this.window_=$window;this.valueString="";this.scope_.$watch("value.value",this.onValueChange_.bind(this));this.scope_.$watch("controller.valueString",this.onValueStringChange_.bind(this))};var BytesFormController=grrUi.forms.bytesFormDirective.BytesFormController;BytesFormController.prototype.onValueChange_=function(newValue){if(angular.isString(newValue))try{var base64DecodedBytes=
this.window_.atob(newValue);if(base64DecodedBytes!=hexEncodedStringToBytes(this.valueString))this.valueString=bytesToHexEncodedString(base64DecodedBytes)}catch(err){this.valueString=""}};BytesFormController.prototype.onValueStringChange_=function(newValue){if(angular.isUndefined(newValue))return;if(!isByteString(newValue)){this.scope_["value"]["validationError"]="Unicode characters are not allowed in a byte string.";return}else delete this.scope_["value"]["validationError"];this.scope_["value"]["value"]=
this.window_.btoa(hexEncodedStringToBytes(newValue))};grrUi.forms.bytesFormDirective.BytesFormDirective=function(){return{restrict:"E",scope:{value:"=",metadata:"="},templateUrl:"/static/angular-components/forms/bytes-form.html",controller:BytesFormController,controllerAs:"controller"}};grrUi.forms.bytesFormDirective.BytesFormDirective.directive_name="grrFormBytes";grrUi.forms.bytesFormDirective.BytesFormDirective.semantic_type="RDFBytes"});goog.provide("grrUi.forms.clientLabelFormDirective.ClientLabelFormController");goog.provide("grrUi.forms.clientLabelFormDirective.ClientLabelFormDirective");goog.require("grrUi.core.apiService.stripTypeInfo");
goog.scope(function(){var stripTypeInfo=grrUi.core.apiService.stripTypeInfo;grrUi.forms.clientLabelFormDirective.ClientLabelFormController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.labelsList;this.clientLabel;this.formLabel;this.hideEmptyOption;this.emptyOptionLabel;this.grrApiService_.get("/clients/labels").then(function(response){this.labelsList=stripTypeInfo(response["data"]["items"]);this.scope_.$watch("controller.hideEmptyOption",function(){if(!this.clientLabel&&
this.hideEmptyOption&&this.labelsList.length>0)this.clientLabel=this.labelsList[0]["name"]}.bind(this))}.bind(this))};var ClientLabelFormController=grrUi.forms.clientLabelFormDirective.ClientLabelFormController;ClientLabelFormController.prototype.$onInit=function(){this.hideEmptyOption=this.hideEmptyOption||false;this.emptyOptionLabel=this.emptyOptionLabel||"-- All clients --"};grrUi.forms.clientLabelFormDirective.ClientLabelFormDirective=function(){return{scope:{clientLabel:"=",formLabel:"=?",hideEmptyOption:"=?",
emptyOptionLabel:"=?"},bindToController:true,restrict:"E",templateUrl:"/static/angular-components/forms/client-label-form.html",controller:ClientLabelFormController,controllerAs:"controller"}};grrUi.forms.clientLabelFormDirective.ClientLabelFormDirective.directive_name="grrFormClientLabel"});goog.provide("grrUi.forms.datetimeFormDirective.DatetimeFormController");goog.provide("grrUi.forms.datetimeFormDirective.DatetimeFormDirective");
goog.scope(function(){grrUi.forms.datetimeFormDirective.DatetimeFormController=function($scope){this.scope_=$scope;this.valueString="";this.isInvalid=false;this.format="YYYY-MM-DD HH:mm";this.example=moment.utc("1989-04-20T13:42:00.000Z").utc().format(this.format);this.scope_.$watch("value.value",this.onValueChange_.bind(this));this.scope_.$watch("controller.valueString",this.onValueStringChange_.bind(this))};var DatetimeFormController=grrUi.forms.datetimeFormDirective.DatetimeFormController;DatetimeFormController.prototype.onValueChange_=
function(newValue){if(angular.isNumber(newValue)){var parsed=moment.utc(newValue/1E3);if(parsed.isValid()){var newValueString=parsed.format(this.format);if(!moment.utc(this.valueString,this.format).isSame(parsed))this.valueString=newValueString}else this.valueString=""}};DatetimeFormController.prototype.onValueStringChange_=function(newValue){if(newValue==""){this.scope_.value.value=null;this.isInvalid=false}else{var parsed=moment.utc(newValue,this.format,true);if(parsed.isValid()){this.scope_.value.value=
parsed.valueOf()*1E3;this.isInvalid=false}else{this.scope_.value.value=null;this.isInvalid=true}}};DatetimeFormController.prototype.today=function(){this.scope_.value.value=moment().valueOf()*1E3};grrUi.forms.datetimeFormDirective.DatetimeFormDirective=function(){return{restrict:"E",scope:{value:"=",metadata:"="},templateUrl:"/static/angular-components/forms/datetime-form.html",controller:DatetimeFormController,controllerAs:"controller"}};grrUi.forms.datetimeFormDirective.DatetimeFormDirective.directive_name=
"grrFormDatetime";grrUi.forms.datetimeFormDirective.DatetimeFormDirective.semantic_type="RDFDatetime"});goog.provide("grrUi.forms.dictFormDirective.DictFormController");goog.provide("grrUi.forms.dictFormDirective.DictFormDirective");
goog.scope(function(){grrUi.forms.dictFormDirective.DictFormController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.keyValueList;this.keyValueDescriptor;this.stringDefault;this.grrReflectionService_.getRDFValueDescriptor("RDFString").then(function(descriptor){this.stringDefault=descriptor["default"];this.scope_.$watch("controller.keyValueList",this.onKeyValueListChange_.bind(this),true);this.scope_.$watch("value.value",this.onValueChange_.bind(this),
true)}.bind(this))};var DictFormController=grrUi.forms.dictFormDirective.DictFormController;DictFormController.prototype.convertFromRDFString=function(value){if(angular.isUndefined(value)||value["type"]!="RDFString")return value;value=angular.copy(value);var s=value["value"].trim();if(/^\d+$/.test(s)){value["value"]=parseInt(s,10);value["type"]="RDFInteger"}else if(/^0x[0-9a-fA-F]+$/.test(s)){value["value"]=parseInt(s.substring(2),16);value["type"]="RDFInteger"}else if(s.toLowerCase()=="true"){value["value"]=
true;value["type"]="RDFBool"}else if(s.toLowerCase()=="false"){value["value"]=false;value["type"]="RDFBool"}return value};DictFormController.prototype.onKeyValueListChange_=function(newValue){if(angular.isDefined(newValue)){this.scope_.value.value={};for(var i=0;i<this.keyValueList.length;++i){var pair=this.keyValueList[i];this.scope_.value.value[pair["key"]]=this.convertFromRDFString(pair["value"])}}};DictFormController.prototype.onValueChange_=function(newValue){if(angular.isObject(newValue)){if(angular.isUndefined(this.keyValueList))this.keyValueList=
[];angular.forEach(newValue,function(value,key){var found=false;for(var i=0;i<this.keyValueList.length;++i){var pair=this.keyValueList[i];if(pair["key"]==key){found=true;if(!angular.equals(this.convertFromRDFString(pair["value"]),value))pair["value"]=value}}if(!found)this.keyValueList.push({key:key,value:value})}.bind(this))}else this.keyValueList=[]};DictFormController.prototype.addPair=function(){this.keyValueList.push({key:"",value:angular.copy(this.stringDefault)})};DictFormController.prototype.removePair=
function(index){this.keyValueList.splice(index,1)};grrUi.forms.dictFormDirective.DictFormDirective=function(){return{restrict:"E",scope:{value:"="},templateUrl:"/static/angular-components/forms/dict-form.html",controller:DictFormController,controllerAs:"controller"}};grrUi.forms.dictFormDirective.DictFormDirective.directive_name="grrFormDict";grrUi.forms.dictFormDirective.DictFormDirective.semantic_types=["dict","Dict"]});goog.provide("grrUi.semantic.durationDirective.DurationController");goog.provide("grrUi.semantic.durationDirective.DurationDirective");goog.provide("grrUi.semantic.durationDirective.stringifySeconds");
goog.scope(function(){var hasFraction_=function(value){return value-Math.floor(value)>1E-16};grrUi.semantic.durationDirective.stringifySeconds=function(value){if(value==0)return"0";var newDuration=moment.duration(value,"s");var unit;var units=["d","h","m","s"];for(var i=0;i<units.length;++i)if(!hasFraction_(newDuration.as(units[i]))){unit=units[i];break}if(angular.isUndefined(unit))throw new Error("Internal logic error: unit can't be undefined.");var n=newDuration.as(unit);if(unit=="d"&&n%7==0){n=
n/7;unit="w"}return n.toString()+unit};grrUi.semantic.durationDirective.DurationController=function($scope){this.scope_=$scope;this.stringifiedDuration;this.scope_.$watch("::value",this.onValueChange.bind(this))};var DurationController=grrUi.semantic.durationDirective.DurationController;DurationController.prototype.onValueChange=function(newValue){var duration=newValue.value;if(angular.isNumber(duration))this.stringifiedDuration=grrUi.semantic.durationDirective.stringifySeconds(duration);else this.stringifiedDuration=
"-"};grrUi.semantic.durationDirective.DurationDirective=function(){return{scope:{value:"="},restrict:"E",template:'<nobr ng-if="::controller.stringifiedDuration">'+"{$ ::controller.stringifiedDuration $}</nobr>",controller:DurationController,controllerAs:"controller"}};grrUi.semantic.durationDirective.DurationDirective.directive_name="grrDuration";grrUi.semantic.durationDirective.DurationDirective.semantic_type="Duration"});goog.provide("grrUi.forms.durationFormDirective.DurationFormController");goog.provide("grrUi.forms.durationFormDirective.DurationFormDirective");goog.require("grrUi.semantic.durationDirective.stringifySeconds");
goog.scope(function(){grrUi.forms.durationFormDirective.DurationFormController=function($scope){this.scope_=$scope;this.valueString="";this.isInvalid=false;this.regex_=/^(\d+)([smhdw])?$/;this.scope_.$watch("value.value",this.onValueChange_.bind(this));this.scope_.$watch("controller.valueString",this.onValueStringChange_.bind(this))};var DurationFormController=grrUi.forms.durationFormDirective.DurationFormController;DurationFormController.prototype.parseString_=function(stringValue){var match=stringValue.trim().match(this.regex_);
if(match==null)return null;else{var n=parseInt(match[1],10);var unit=match[2]||"s";return moment.duration(n,unit)}};DurationFormController.prototype.onValueChange_=function(newValue){if(angular.isNumber(newValue)){var currentParsedDuration=this.parseString_(this.valueString);if(currentParsedDuration!=null&&newValue==currentParsedDuration.asSeconds())return;this.valueString=grrUi.semantic.durationDirective.stringifySeconds(newValue)}};DurationFormController.prototype.onValueStringChange_=function(newValue){if(newValue==
""){this.scope_.value.value=null;this.isInvalid=false}else{var duration=this.parseString_(newValue);this.scope_.value.value=duration!==null?duration.asSeconds():null;this.isInvalid=duration===null}};grrUi.forms.durationFormDirective.DurationFormDirective=function(){return{restrict:"E",scope:{value:"=",metadata:"="},templateUrl:"/static/angular-components/forms/duration-form.html",controller:DurationFormController,controllerAs:"controller"}};grrUi.forms.durationFormDirective.DurationFormDirective.directive_name=
"grrFormDuration";grrUi.forms.durationFormDirective.DurationFormDirective.semantic_type="Duration"});goog.provide("grrUi.forms.foremanLabelRuleFormDirective.ForemanLabelRuleFormController");goog.provide("grrUi.forms.foremanLabelRuleFormDirective.ForemanLabelRuleFormDirective");
goog.scope(function(){grrUi.forms.foremanLabelRuleFormDirective.ForemanLabelRuleFormController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.defaultLabel_="";this.grrReflectionService_.getRDFValueDescriptor("ForemanLabelClientRule").then(function(descriptor){angular.forEach(descriptor["fields"],function(field){if(field["name"]=="match_mode")this.matchModeMetadata=field}.bind(this));this.scope_.$watch("value.value",function(value){if(angular.isDefined(value)){if(angular.isUndefined(value["match_mode"]))value["match_mode"]=
angular.copy(this.matchModeMetadata["default"]);if(angular.isUndefined(value["label_names"]))value["label_names"]=[];if(value["label_names"].length==0)this.addLabel()}}.bind(this))}.bind(this))};var ForemanLabelRuleFormController=grrUi.forms.foremanLabelRuleFormDirective.ForemanLabelRuleFormController;ForemanLabelRuleFormController.prototype.addLabel=function(){this.scope_["value"]["value"]["label_names"].push({type:"unicode",value:this.defaultLabel_})};ForemanLabelRuleFormController.prototype.removeLabel=
function(index){this.scope_["value"]["value"]["label_names"].splice(index,1)};grrUi.forms.foremanLabelRuleFormDirective.ForemanLabelRuleFormDirective=function(){return{restrict:"E",scope:{value:"=",metadata:"="},templateUrl:"/static/angular-components/forms/foreman-label-rule-form.html",controller:ForemanLabelRuleFormController,controllerAs:"controller"}};grrUi.forms.foremanLabelRuleFormDirective.ForemanLabelRuleFormDirective.directive_name="grrFormLabel";grrUi.forms.foremanLabelRuleFormDirective.ForemanLabelRuleFormDirective.semantic_type=
"ForemanLabelClientRule"});goog.provide("grrUi.forms.globExpressionFormDirective.GlobExpressionFormController");goog.provide("grrUi.forms.globExpressionFormDirective.GlobExpressionFormDirective");
goog.scope(function(){grrUi.forms.globExpressionFormDirective.GlobExpressionFormController=function($element,$interval,grrApiService){this.element_=$element;this.interval_=$interval;this.grrApiService_=grrApiService;this.grrApiService_.get("/clients/kb-fields").then(this.onGetFields_.bind(this))};var GlobExpressionFormController=grrUi.forms.globExpressionFormDirective.GlobExpressionFormController;GlobExpressionFormController.prototype.completionFilter_=function(completions,term){var matcher=new RegExp("^"+
$["ui"]["autocomplete"]["escapeRegex"](term),"i");return $["grep"](completions,function(value){return matcher.test(value.label||value.value||value)})};GlobExpressionFormController.prototype.buildCompleter_=function(element,completions){if(angular.isString(element))element=$("#"+element);var self=this;element.bind("keydown",function(event){if(event.keyCode===$["ui"]["keyCode"]["TAB"]&&$(this).data("ui-autocomplete")["menu"]["active"])event.preventDefault()})["autocomplete"]({minLength:0,source:function(request,
response){var terms=request["term"].split(/%%/);if(terms.length%2)response([]);else response(self.completionFilter_(completions,terms.pop()))},focus:function(){return false},select:function(event,ui){var terms=this.value.split(/%%/);terms.pop();terms.push(ui.item.value);terms.push("");this.value=terms.join("%%");$(this).change();return false}}).wrap('<abbr title="Type %% to open a list of possible completions."/>')};GlobExpressionFormController.prototype.onGetFields_=function(response){var fieldsNames=
[];angular.forEach(response["data"]["items"],function(field){fieldsNames.push(field["value"])}.bind(this));var intervalPromise=this.interval_(function(){var inputBox=$(this.element_).find("input");if(inputBox){this.buildCompleter_(inputBox,fieldsNames);this.interval_.cancel(intervalPromise)}}.bind(this),500,10)};grrUi.forms.globExpressionFormDirective.GlobExpressionFormDirective=function(){return{restrict:"E",scope:{value:"=",metadata:"="},templateUrl:"/static/angular-components/forms/glob-expression-form.html",
controller:GlobExpressionFormController,controllerAs:"controller"}};grrUi.forms.globExpressionFormDirective.GlobExpressionFormDirective.directive_name="grrFormGlobExpression";grrUi.forms.globExpressionFormDirective.GlobExpressionFormDirective.semantic_type="GlobExpression"});goog.provide("grrUi.forms.globExpressionsListFormDirective.GlobExpressionsListFormController");goog.provide("grrUi.forms.globExpressionsListFormDirective.GlobExpressionsListFormDirective");
goog.scope(function(){grrUi.forms.globExpressionsListFormDirective.GlobExpressionsListFormController=function($scope){this.scope_=$scope;this.scope_.$watchGroup(["descriptor","value","field"],this.onArgumentsChange_.bind(this))};var GlobExpressionsListFormController=grrUi.forms.globExpressionsListFormDirective.GlobExpressionsListFormController;GlobExpressionsListFormController.prototype.onArgumentsChange_=function(){if(angular.isDefined(this.scope_["descriptor"])&&angular.isDefined(this.scope_["field"])&&
angular.isDefined(this.scope_["value"]))if(this.scope_["value"].length==0){var newGlob=angular.copy(this.scope_["descriptor"]["default"]);this.scope_["value"].push(newGlob)}};grrUi.forms.globExpressionsListFormDirective.GlobExpressionsListFormDirective=function(){return{restrict:"E",scope:{descriptor:"=",value:"=",field:"="},templateUrl:"/static/angular-components/forms/"+"glob-expressions-list-form.html",controller:GlobExpressionsListFormController,controllerAs:"controller"}};grrUi.forms.globExpressionsListFormDirective.GlobExpressionsListFormDirective.directive_name=
"grrGlobExpressionsListForm";grrUi.forms.globExpressionsListFormDirective.GlobExpressionsListFormDirective.hideCustomTemplateLabel=true;grrUi.forms.globExpressionsListFormDirective.GlobExpressionsListFormDirective.semantic_type="GlobExpression"});goog.provide("grrUi.forms.outputPluginDescriptorFormDirective.OutputPluginDescriptorFormController");goog.provide("grrUi.forms.outputPluginDescriptorFormDirective.OutputPluginDescriptorFormDirective");
goog.scope(function(){grrUi.forms.outputPluginDescriptorFormDirective.OutputPluginDescriptorFormController=function($scope,grrApiService,grrReflectionService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrReflectionService_=grrReflectionService;this.outputPluginsDescriptors;this.allowedPluginsNames;this.grrApiService_.get("/output-plugins/all").then(function(response){this.outputPluginsDescriptors={};angular.forEach(response["data"]["items"],function(item){if(item["plugin_type"]===
"LEGACY")this.outputPluginsDescriptors[item["name"]]=item}.bind(this));this.allowedPluginsNames=Object.keys(this.outputPluginsDescriptors).sort();if(angular.isUndefined(this.scope_.$eval("value.value.plugin_name.value")))this.scope_["value"]["value"]["plugin_name"]={type:"RDFString",value:this.allowedPluginsNames[0]};this.scope_.$watch("value.value.plugin_name.value",function(newValue){if(angular.isDefined(newValue)){var argsType=this.outputPluginsDescriptors[newValue]["args_type"];var pluginArgs=
this.scope_["value"]["value"]["plugin_args"];if(angular.isUndefined(pluginArgs)||pluginArgs["type"]!=argsType)this.grrReflectionService_.getRDFValueDescriptor(argsType).then(function(descriptor){this.scope_["value"]["value"]["plugin_args"]=angular.copy(descriptor["default"])}.bind(this))}}.bind(this))}.bind(this))};var OutputPluginDescriptorFormController=grrUi.forms.outputPluginDescriptorFormDirective.OutputPluginDescriptorFormController;grrUi.forms.outputPluginDescriptorFormDirective.OutputPluginDescriptorFormDirective=
function(){return{restrict:"E",scope:{value:"="},templateUrl:"/static/angular-components/forms/"+"output-plugin-descriptor-form.html",controller:OutputPluginDescriptorFormController,controllerAs:"controller"}};grrUi.forms.outputPluginDescriptorFormDirective.OutputPluginDescriptorFormDirective.directive_name="grrOutputPluginDescriptorForm";grrUi.forms.outputPluginDescriptorFormDirective.OutputPluginDescriptorFormDirective.semantic_type="OutputPluginDescriptor"});goog.provide("grrUi.forms.semanticEnumFormDirective");goog.provide("grrUi.forms.semanticEnumFormDirective.SemanticEnumFormController");goog.provide("grrUi.forms.semanticEnumFormDirective.SemanticEnumFormDirective");grrUi.forms.semanticEnumFormDirective.SemanticEnumFormController=function($scope){this.scope_=$scope;this.allowedOptions=[];this.scope_.$watch("metadata.allowed_values",this.onAllowedValuesChange_.bind(this))};var SemanticEnumFormController=grrUi.forms.semanticEnumFormDirective.SemanticEnumFormController;
SemanticEnumFormController.prototype.onAllowedValuesChange_=function(newValue){this.allowedOptions=[];if(angular.isDefined(newValue)){this.allowedOptions=[];angular.forEach(newValue,function(option){var defaultLabel="";var defaultOptionName=this.scope_.$eval("metadata.default.value");if(defaultOptionName==option.name)defaultLabel=" (default)";var label=option.name;if(option.doc)label=option.doc;this.allowedOptions.push({value:option.name,label:label+defaultLabel})}.bind(this))}};
grrUi.forms.semanticEnumFormDirective.SemanticEnumFormDirective=function(){return{restrict:"E",scope:{value:"=",metadata:"="},templateUrl:"/static/angular-components/forms/semantic-enum-form.html",controller:SemanticEnumFormController,controllerAs:"controller"}};grrUi.forms.semanticEnumFormDirective.SemanticEnumFormDirective.directive_name="grrFormEnum";grrUi.forms.semanticEnumFormDirective.SemanticEnumFormDirective.semantic_type="EnumNamedValue";goog.provide("grrUi.forms.semanticPrimitiveFormDirective");goog.provide("grrUi.forms.semanticPrimitiveFormDirective.SemanticPrimitiveFormController");goog.provide("grrUi.forms.semanticPrimitiveFormDirective.SemanticPrimitiveFormDirective");grrUi.forms.semanticPrimitiveFormDirective.SemanticPrimitiveFormController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.valueType;this.scope_.$watch("value.type",this.onValueTypeChange_.bind(this))};
var SemanticPrimitiveFormController=grrUi.forms.semanticPrimitiveFormDirective.SemanticPrimitiveFormController;
SemanticPrimitiveFormController.prototype.onValueTypeChange_=function(newValue){if(angular.isUndefined(newValue)){this.valueType=undefined;return}var descriptorHandler=function(descriptor){var allowedTypes=grrUi.forms.semanticPrimitiveFormDirective.SemanticPrimitiveFormDirective.semantic_types;var typeIndex=-1;angular.forEach(allowedTypes,function(type){var index=descriptor["mro"].indexOf(type);if(index!=-1&&(typeIndex==-1||typeIndex>index)){typeIndex=index;this.valueType=type}}.bind(this));if(!this.valueType)this.valueType=
"RDFString"}.bind(this);this.grrReflectionService_.getRDFValueDescriptor(newValue).then(descriptorHandler)};grrUi.forms.semanticPrimitiveFormDirective.SemanticPrimitiveFormDirective=function(){return{restrict:"E",scope:{value:"="},templateUrl:"/static/angular-components/forms/"+"semantic-primitive-form.html",controller:SemanticPrimitiveFormController,controllerAs:"controller"}};grrUi.forms.semanticPrimitiveFormDirective.SemanticPrimitiveFormDirective.directive_name="grrFormPrimitive";
grrUi.forms.semanticPrimitiveFormDirective.SemanticPrimitiveFormDirective.semantic_types=["RDFBool","bool","RDFInteger","int","long","float","RDFString","basestring","RDFURN","bytes"];goog.provide("grrUi.forms.semanticProtoFormDirective.SemanticProtoFormController");goog.provide("grrUi.forms.semanticProtoFormDirective.SemanticProtoFormDirective");
grrUi.forms.semanticProtoFormDirective.SemanticProtoFormController=function($scope,$attrs,grrReflectionService){this.scope_=$scope;this.scope_.value;this.grrReflectionService_=grrReflectionService;this.advancedShown=false;this.hasAdvancedFields=false;this.expanded=false;this.editedValue;if(angular.isDefined($attrs["hiddenFields"])&&angular.isDefined($attrs["visibleFields"]))throw new Error("Either hidden-fields or visible-fields attribute may "+"be specified, not both.");this.scope_.$watch("value",
this.onValueChange_.bind(this));this.scope_.$watch("controller.editedValue.value",this.onEditedValueChange_.bind(this),true);this.boundNotExplicitlyHiddenFields=this.notExplicitlyHiddenFields_.bind(this)};var SemanticProtoFormController=grrUi.forms.semanticProtoFormDirective.SemanticProtoFormController;
SemanticProtoFormController.prototype.notExplicitlyHiddenFields_=function(field,opt_index){if(angular.isDefined(this.scope_["hiddenFields"]))return this.scope_["hiddenFields"].indexOf(field["name"])==-1;else if(angular.isDefined(this.scope_["visibleFields"]))return this.scope_["visibleFields"].indexOf(field["name"])!=-1;else return true};
SemanticProtoFormController.prototype.regularFieldsOnly=function(field,index){return angular.isUndefined(field.labels)||field.labels.indexOf("HIDDEN")==-1&&field.labels.indexOf("ADVANCED")==-1};SemanticProtoFormController.prototype.advancedFieldsOnly=function(field,index){return angular.isDefined(field.labels)&&field.labels.indexOf("HIDDEN")==-1&&field.labels.indexOf("ADVANCED")!=-1};
SemanticProtoFormController.prototype.onValueChange_=function(newValue,oldValue){if(angular.isUndefined(newValue)){this.descriptors=undefined;this.valueDescriptor=undefined;this.editedValue=undefined;return}if(newValue!==oldValue||angular.isUndefined(this.valueDescriptor))this.grrReflectionService_.getRDFValueDescriptor(this.scope_.value.type,true).then(this.onDescriptorsFetched_.bind(this))};
SemanticProtoFormController.prototype.onEditedValueChange_=function(newValue,oldValue){if(angular.isDefined(newValue)){if(angular.isDefined(oldValue))angular.forEach(newValue,function(value,key){if(!angular.equals(oldValue[key],newValue[key]))this.scope_.value.value[key]=value}.bind(this));angular.forEach(this.valueDescriptor["fields"],function(field){if(this.notExplicitlyHiddenFields_(field))if(field.type&&angular.equals(this.scope_.value.value[field.name],this.descriptors[field.type]["default"])&&
(angular.isUndefined(field["default"])||angular.equals(field["default"],this.descriptors[field.type]["default"])))delete this.scope_.value.value[field.name]}.bind(this))}};
SemanticProtoFormController.prototype.onDescriptorsFetched_=function(descriptors){this.descriptors=descriptors;this.valueDescriptor=angular.copy(descriptors[this.scope_.value.type]);this.editedValue=angular.copy(this.scope_.value);if(angular.isUndefined(this.editedValue.value))this.editedValue.value={};angular.forEach(this.valueDescriptor["fields"],function(field){if(angular.isDefined(field.labels)){if(field.labels.indexOf("HIDDEN")!=-1)return;if(field.labels.indexOf("ADVANCED")!=-1)this.hasAdvancedFields=
true}if(field.repeated){field.depth=0;if(angular.isUndefined(this.editedValue.value[field.name]))this.editedValue.value[field.name]=[]}else{field.depth=(this.scope_.$eval("metadata.depth")||0)+1;if(angular.isUndefined(this.editedValue.value[field.name]))if(angular.isDefined(field["default"]))this.editedValue.value[field.name]=angular.copy(field["default"]);else this.editedValue.value[field.name]=angular.copy(descriptors[field.type]["default"])}}.bind(this))};
grrUi.forms.semanticProtoFormDirective.SemanticProtoFormDirective=function(){return{scope:{value:"=",metadata:"=?",hiddenFields:"=?",visibleFields:"=?"},restrict:"E",templateUrl:"/static/angular-components/forms/semantic-proto-form.html",controller:SemanticProtoFormController,controllerAs:"controller"}};grrUi.forms.semanticProtoFormDirective.SemanticProtoFormDirective.directive_name="grrFormProto";grrUi.forms.semanticProtoFormDirective.SemanticProtoFormDirective.semantic_type="RDFProtoStruct";goog.provide("grrUi.forms.semanticValueFormDirective");goog.provide("grrUi.forms.semanticValueFormDirective.SemanticValueFormController");goog.provide("grrUi.forms.semanticValueFormDirective.SemanticValueFormDirective");grrUi.forms.semanticValueFormDirective.templatesCache={};grrUi.forms.semanticValueFormDirective.clearCaches=function(){grrUi.forms.semanticValueFormDirective.templatesCache={}};
grrUi.forms.semanticValueFormDirective.SemanticValueFormController=function($scope,$compile,$element,grrSemanticFormDirectivesRegistryService){this.scope_=$scope;this.compile_=$compile;this.element_=$element;this.elementScope_;this.grrSemanticFormDirectivesRegistryService_=grrSemanticFormDirectivesRegistryService;this.scope_.$watch("value.type",this.onValueTypeChange_.bind(this))};var SemanticValueFormController=grrUi.forms.semanticValueFormDirective.SemanticValueFormController;
SemanticValueFormController.prototype.onValueTypeChange_=function(newValue){this.element_.html("");if(angular.isDefined(this.elementScope_)){this.elementScope_.$destroy();this.elementScope_=undefined}if(angular.isUndefined(newValue))return;var updateElement=function(tmpl){if(angular.isDefined(tmpl)){this.elementScope_=this.scope_.$new();tmpl(this.elementScope_,function(cloned,opt_scope){this.element_.append(cloned)}.bind(this))}else this.element_.text("Can't handle type: "+this.value["type"])}.bind(this);
var templatesCache=grrUi.forms.semanticValueFormDirective.templatesCache;var value=this.scope_.value;var template=templatesCache[value["type"]];if(angular.isUndefined(template))this.compileSingleTypedValueTemplate_(value).then(function(template){templatesCache[value["type"]]=template;updateElement(template)}.bind(this));else updateElement(template)};SemanticValueFormController.prototype.camelCaseToDashDelimited=function(directiveName){return directiveName.replace(/([a-z\d])([A-Z])/g,"$1-$2").toLowerCase()};
SemanticValueFormController.prototype.compileSingleTypedValueTemplate_=function(value){var successHandler=function success(directive){var element=angular.element("<span />");element.html("<"+this.camelCaseToDashDelimited(directive.directive_name)+' metadata="metadata" value="value" />');return this.compile_(element)}.bind(this);var failureHandler=function failure(){var element=angular.element("<span />");element.html('<p class="form-control-static">No directive '+"for type: {$ value.type $}.</p>");
return this.compile_(element)}.bind(this);return this.grrSemanticFormDirectivesRegistryService_.findDirectiveForType(value["type"]).then(successHandler,failureHandler)};grrUi.forms.semanticValueFormDirective.SemanticValueFormDirective=function(){return{restrict:"E",scope:{value:"=",metadata:"=?"},controller:SemanticValueFormController,controllerAs:"controller"}};grrUi.forms.semanticValueFormDirective.SemanticValueFormDirective.directive_name="grrFormValue";goog.provide("grrUi.forms.semanticProtoRepeatedFieldFormDirective.SemanticProtoRepeatedFieldFormController");goog.provide("grrUi.forms.semanticProtoRepeatedFieldFormDirective.SemanticProtoRepeatedFieldFormDirective");goog.require("grrUi.core.utils.camelCaseToDashDelimited");goog.require("grrUi.forms.semanticValueFormDirective.SemanticValueFormController");
goog.scope(function(){var camelCaseToDashDelimited=grrUi.core.utils.camelCaseToDashDelimited;grrUi.forms.semanticProtoRepeatedFieldFormDirective.SemanticProtoRepeatedFieldFormController=function($scope,$element,$compile,grrSemanticRepeatedFormDirectivesRegistryService){this.scope_=$scope;this.element_=$element;this.compile_=$compile;this.grrSemanticRepeatedFormDirectivesRegistryService_=grrSemanticRepeatedFormDirectivesRegistryService;this.hasCustomTemplate;this.hideCustomTemplateLabel;this.scope_.$watchGroup(["field",
"descriptor","value"],this.onFieldDescriptorChange_.bind(this))};var SemanticProtoRepeatedFieldFormController=grrUi.forms.semanticProtoRepeatedFieldFormDirective.SemanticProtoRepeatedFieldFormController;SemanticProtoRepeatedFieldFormController.prototype.onFieldDescriptorChange_=function(){if(angular.isDefined(this.scope_["field"])&&angular.isDefined(this.scope_["descriptor"])&&angular.isDefined(this.scope_["value"]))if(this.scope_["noCustomTemplate"])this.onCustomDirectiveNotFound_();else this.grrSemanticRepeatedFormDirectivesRegistryService_.findDirectiveForType(this.scope_["descriptor"]["mro"][0]).then(this.onCustomDirectiveFound_.bind(this),
this.onCustomDirectiveNotFound_.bind(this))};SemanticProtoRepeatedFieldFormController.prototype.onCustomDirectiveNotFound_=function(){this.hasCustomTemplate=false};SemanticProtoRepeatedFieldFormController.prototype.onCustomDirectiveFound_=function(directive){this.hasCustomTemplate=true;this.hideCustomTemplateLabel=directive["hideCustomTemplateLabel"];var element=angular.element("<span />");element.html("<"+camelCaseToDashDelimited(directive.directive_name)+' descriptor="descriptor" value="value" field="field" />');
var template=this.compile_(element);var customTemplateElement;if(this.hideCustomTemplateLabel)customTemplateElement=this.element_.find('div[name="custom-template-without-label"]');else customTemplateElement=this.element_.find('div[name="custom-template"]');customTemplateElement.html("");template(this.scope_,function(cloned,opt_scope){customTemplateElement.append(cloned)}.bind(this))};SemanticProtoRepeatedFieldFormController.prototype.addItem=function(){this.scope_.value.splice(0,0,angular.copy(this.scope_["descriptor"]["default"]))};
SemanticProtoRepeatedFieldFormController.prototype.removeItem=function(index){this.scope_.value.splice(index,1)};grrUi.forms.semanticProtoRepeatedFieldFormDirective.SemanticProtoRepeatedFieldFormDirective=function(){return{scope:{value:"=",descriptor:"=",field:"=",noCustomTemplate:"="},restrict:"E",templateUrl:"/static/angular-components/forms/"+"semantic-proto-repeated-field-form.html",controller:SemanticProtoRepeatedFieldFormController,controllerAs:"controller"}};grrUi.forms.semanticProtoRepeatedFieldFormDirective.SemanticProtoRepeatedFieldFormDirective.directive_name=
"grrFormProtoRepeatedField"});goog.provide("grrUi.forms.semanticProtoSingleFieldFormDirective.SemanticProtoSingleFieldFormController");goog.provide("grrUi.forms.semanticProtoSingleFieldFormDirective.SemanticProtoSingleFieldFormDirective");grrUi.forms.semanticProtoSingleFieldFormDirective.SemanticProtoSingleFieldFormDirective=function(){return{scope:{value:"=",field:"="},restrict:"E",templateUrl:"/static/angular-components/forms/"+"semantic-proto-single-field-form.html"}};
grrUi.forms.semanticProtoSingleFieldFormDirective.SemanticProtoSingleFieldFormDirective.directive_name="grrFormProtoSingleField";goog.provide("grrUi.forms.semanticProtoUnionFormDirective.SemanticProtoUnionFormController");goog.provide("grrUi.forms.semanticProtoUnionFormDirective.SemanticProtoUnionFormDirective");grrUi.forms.semanticProtoUnionFormDirective.SemanticProtoUnionFormController=function($scope){this.scope_=$scope;this.unionField;this.unionFieldValue;$scope.$watch("descriptor",this.onDescriptorChange_.bind(this));$scope.$watch("value.value[controller.unionField.name].value",this.onUnionFieldValueChange_.bind(this))};
var SemanticProtoUnionFormController=grrUi.forms.semanticProtoUnionFormDirective.SemanticProtoUnionFormController;SemanticProtoUnionFormController.prototype.onDescriptorChange_=function(newValue){if(angular.isUndefined(newValue))this.unionField=undefined;else angular.forEach(newValue["fields"],function(field){if(field.name==newValue["union_field"])this.unionField=field}.bind(this))};
SemanticProtoUnionFormController.prototype.onUnionFieldValueChange_=function(newValue,oldValue){if(angular.isDefined(newValue)){if(angular.isDefined(oldValue)&&oldValue!==newValue){var unionPart=this.scope_["value"]["value"][this.unionFieldValue];if(angular.isObject(unionPart)){unionPart["value"]={};this.scope_["value"]["value"][this.unionFieldValue]=angular.copy(unionPart)}}this.unionFieldValue=newValue.toLowerCase()}else this.unionFieldValue=undefined};
grrUi.forms.semanticProtoUnionFormDirective.SemanticProtoUnionFormDirective=function(){return{scope:{value:"=",descriptor:"="},restrict:"E",templateUrl:"/static/angular-components/forms/"+"semantic-proto-union-form.html",controller:SemanticProtoUnionFormController,controllerAs:"controller"}};grrUi.forms.semanticProtoUnionFormDirective.SemanticProtoUnionFormDirective.directive_name="grrFormProtoUnion";goog.provide("grrUi.forms.timerangeFormDirective.TimerangeFormController");goog.provide("grrUi.forms.timerangeFormDirective.TimerangeFormDirective");
goog.scope(function(){grrUi.forms.timerangeFormDirective.TimerangeFormController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.startTimeSecs;this.formStartTime;this.durationSecs;this.formDuration;this.startTimeLabel;this.durationLabel;this.grrReflectionService_.getRDFValueDescriptor("RDFDatetime").then(function(rdfDesc){this.formStartTime=angular.copy(rdfDesc["default"]);return this.grrReflectionService_.getRDFValueDescriptor("Duration")}.bind(this)).then(function(rdfDesc){this.formDuration=
angular.copy(rdfDesc["default"]);this.scope_.$watchGroup(["controller.startTimeSecs","controller.durationSecs"],this.onParamsChange_.bind(this));this.scope_.$watchGroup(["controller.formStartTime.value","controller.formDuration.value"],this.onSubformsChange_.bind(this));this.onParamsChange_()}.bind(this))};var TimerangeFormController=grrUi.forms.timerangeFormDirective.TimerangeFormController;TimerangeFormController.prototype.onParamsChange_=function(){if(angular.isDefined(this.startTimeSecs))this.formStartTime["value"]=
this.startTimeSecs*1E6;if(angular.isDefined(this.durationSecs))this.formDuration["value"]=this.durationSecs};TimerangeFormController.prototype.onSubformsChange_=function(){this.startTimeSecs=this.formStartTime["value"]/1E6;this.durationSecs=this.formDuration["value"]};grrUi.forms.timerangeFormDirective.TimerangeFormDirective=function(){return{scope:{startTimeSecs:"=",durationSecs:"=",startTimeLabel:"=?",durationLabel:"=?"},bindToController:true,restrict:"E",templateUrl:"/static/angular-components/forms/timerange-form.html",
controller:TimerangeFormController,controllerAs:"controller"}};grrUi.forms.timerangeFormDirective.TimerangeFormDirective.directive_name="grrFormTimerange"});goog.provide("grrUi.forms.module");goog.require("grrUi.core.module");goog.require("grrUi.core.semanticRegistry.SemanticRegistryService");goog.require("grrUi.forms.aff4AttributeFormDirective.Aff4AttributeFormDirective");goog.require("grrUi.forms.autoGeneratedAES128KeyFormDirective.AutoGeneratedAES128KeyFormDirective");goog.require("grrUi.forms.bytesFormDirective.BytesFormDirective");goog.require("grrUi.forms.clientLabelFormDirective.ClientLabelFormDirective");goog.require("grrUi.forms.datetimeFormDirective.DatetimeFormDirective");
goog.require("grrUi.forms.dictFormDirective.DictFormDirective");goog.require("grrUi.forms.durationFormDirective.DurationFormDirective");goog.require("grrUi.forms.foremanLabelRuleFormDirective.ForemanLabelRuleFormDirective");goog.require("grrUi.forms.globExpressionFormDirective.GlobExpressionFormDirective");goog.require("grrUi.forms.globExpressionsListFormDirective.GlobExpressionsListFormDirective");goog.require("grrUi.forms.outputPluginDescriptorFormDirective.OutputPluginDescriptorFormDirective");
goog.require("grrUi.forms.semanticEnumFormDirective.SemanticEnumFormDirective");goog.require("grrUi.forms.semanticPrimitiveFormDirective.SemanticPrimitiveFormDirective");goog.require("grrUi.forms.semanticProtoFormDirective.SemanticProtoFormDirective");goog.require("grrUi.forms.semanticProtoRepeatedFieldFormDirective.SemanticProtoRepeatedFieldFormDirective");goog.require("grrUi.forms.semanticProtoSingleFieldFormDirective.SemanticProtoSingleFieldFormDirective");goog.require("grrUi.forms.semanticProtoUnionFormDirective.SemanticProtoUnionFormDirective");
goog.require("grrUi.forms.semanticValueFormDirective.SemanticValueFormDirective");goog.require("grrUi.forms.timerangeFormDirective.TimerangeFormDirective");grrUi.forms.module=angular.module("grrUi.forms",[grrUi.core.module.name,"ui.bootstrap"]);grrUi.forms.module.service(grrUi.core.semanticRegistry.SemanticRegistryService.forms_service_name,grrUi.core.semanticRegistry.SemanticRegistryService);
grrUi.forms.module.service(grrUi.core.semanticRegistry.SemanticRegistryService.repeated_forms_service_name,grrUi.core.semanticRegistry.SemanticRegistryService);grrUi.forms.module.directive(grrUi.forms.aff4AttributeFormDirective.Aff4AttributeFormDirective.directive_name,grrUi.forms.aff4AttributeFormDirective.Aff4AttributeFormDirective);grrUi.forms.module.directive(grrUi.forms.autoGeneratedAES128KeyFormDirective.AutoGeneratedAES128KeyFormDirective.directive_name,grrUi.forms.autoGeneratedAES128KeyFormDirective.AutoGeneratedAES128KeyFormDirective);
grrUi.forms.module.directive(grrUi.forms.bytesFormDirective.BytesFormDirective.directive_name,grrUi.forms.bytesFormDirective.BytesFormDirective);grrUi.forms.module.directive(grrUi.forms.clientLabelFormDirective.ClientLabelFormDirective.directive_name,grrUi.forms.clientLabelFormDirective.ClientLabelFormDirective);grrUi.forms.module.directive(grrUi.forms.datetimeFormDirective.DatetimeFormDirective.directive_name,grrUi.forms.datetimeFormDirective.DatetimeFormDirective);
grrUi.forms.module.directive(grrUi.forms.dictFormDirective.DictFormDirective.directive_name,grrUi.forms.dictFormDirective.DictFormDirective);grrUi.forms.module.directive(grrUi.forms.durationFormDirective.DurationFormDirective.directive_name,grrUi.forms.durationFormDirective.DurationFormDirective);grrUi.forms.module.directive(grrUi.forms.globExpressionFormDirective.GlobExpressionFormDirective.directive_name,grrUi.forms.globExpressionFormDirective.GlobExpressionFormDirective);
grrUi.forms.module.directive(grrUi.forms.globExpressionsListFormDirective.GlobExpressionsListFormDirective.directive_name,grrUi.forms.globExpressionsListFormDirective.GlobExpressionsListFormDirective);grrUi.forms.module.directive(grrUi.forms.outputPluginDescriptorFormDirective.OutputPluginDescriptorFormDirective.directive_name,grrUi.forms.outputPluginDescriptorFormDirective.OutputPluginDescriptorFormDirective);
grrUi.forms.module.directive(grrUi.forms.semanticEnumFormDirective.SemanticEnumFormDirective.directive_name,grrUi.forms.semanticEnumFormDirective.SemanticEnumFormDirective);grrUi.forms.module.directive(grrUi.forms.foremanLabelRuleFormDirective.ForemanLabelRuleFormDirective.directive_name,grrUi.forms.foremanLabelRuleFormDirective.ForemanLabelRuleFormDirective);grrUi.forms.module.directive(grrUi.forms.semanticPrimitiveFormDirective.SemanticPrimitiveFormDirective.directive_name,grrUi.forms.semanticPrimitiveFormDirective.SemanticPrimitiveFormDirective);
grrUi.forms.module.directive(grrUi.forms.semanticProtoFormDirective.SemanticProtoFormDirective.directive_name,grrUi.forms.semanticProtoFormDirective.SemanticProtoFormDirective);grrUi.forms.module.directive(grrUi.forms.semanticProtoSingleFieldFormDirective.SemanticProtoSingleFieldFormDirective.directive_name,grrUi.forms.semanticProtoSingleFieldFormDirective.SemanticProtoSingleFieldFormDirective);
grrUi.forms.module.directive(grrUi.forms.semanticProtoRepeatedFieldFormDirective.SemanticProtoRepeatedFieldFormDirective.directive_name,grrUi.forms.semanticProtoRepeatedFieldFormDirective.SemanticProtoRepeatedFieldFormDirective);grrUi.forms.module.directive(grrUi.forms.semanticProtoUnionFormDirective.SemanticProtoUnionFormDirective.directive_name,grrUi.forms.semanticProtoUnionFormDirective.SemanticProtoUnionFormDirective);
grrUi.forms.module.directive(grrUi.forms.semanticValueFormDirective.SemanticValueFormDirective.directive_name,grrUi.forms.semanticValueFormDirective.SemanticValueFormDirective);grrUi.forms.module.directive(grrUi.forms.timerangeFormDirective.TimerangeFormDirective.directive_name,grrUi.forms.timerangeFormDirective.TimerangeFormDirective);
grrUi.forms.module.run(function(grrSemanticFormDirectivesRegistryService){var registry=grrSemanticFormDirectivesRegistryService;registry.registerDirective(grrUi.forms.aff4AttributeFormDirective.Aff4AttributeFormDirective.semantic_type,grrUi.forms.aff4AttributeFormDirective.Aff4AttributeFormDirective);registry.registerDirective(grrUi.forms.autoGeneratedAES128KeyFormDirective.AutoGeneratedAES128KeyFormDirective.semantic_type,grrUi.forms.autoGeneratedAES128KeyFormDirective.AutoGeneratedAES128KeyFormDirective);
registry.registerDirective(grrUi.forms.bytesFormDirective.BytesFormDirective.semantic_type,grrUi.forms.bytesFormDirective.BytesFormDirective);registry.registerDirective(grrUi.forms.datetimeFormDirective.DatetimeFormDirective.semantic_type,grrUi.forms.datetimeFormDirective.DatetimeFormDirective);var dictSemanticTypes=grrUi.forms.dictFormDirective.DictFormDirective.semantic_types;angular.forEach(dictSemanticTypes,function(dictSemanticType){registry.registerDirective(dictSemanticType,grrUi.forms.dictFormDirective.DictFormDirective)});
registry.registerDirective(grrUi.forms.durationFormDirective.DurationFormDirective.semantic_type,grrUi.forms.durationFormDirective.DurationFormDirective);registry.registerDirective(grrUi.forms.globExpressionFormDirective.GlobExpressionFormDirective.semantic_type,grrUi.forms.globExpressionFormDirective.GlobExpressionFormDirective);registry.registerDirective(grrUi.forms.outputPluginDescriptorFormDirective.OutputPluginDescriptorFormDirective.semantic_type,grrUi.forms.outputPluginDescriptorFormDirective.OutputPluginDescriptorFormDirective);
var primitiveSemanticTypes=grrUi.forms.semanticPrimitiveFormDirective.SemanticPrimitiveFormDirective.semantic_types;angular.forEach(primitiveSemanticTypes,function(primitiveSemanticType){registry.registerDirective(primitiveSemanticType,grrUi.forms.semanticPrimitiveFormDirective.SemanticPrimitiveFormDirective)});registry.registerDirective(grrUi.forms.semanticEnumFormDirective.SemanticEnumFormDirective.semantic_type,grrUi.forms.semanticEnumFormDirective.SemanticEnumFormDirective);registry.registerDirective(grrUi.forms.foremanLabelRuleFormDirective.ForemanLabelRuleFormDirective.semantic_type,
grrUi.forms.foremanLabelRuleFormDirective.ForemanLabelRuleFormDirective);registry.registerDirective(grrUi.forms.semanticProtoFormDirective.SemanticProtoFormDirective.semantic_type,grrUi.forms.semanticProtoFormDirective.SemanticProtoFormDirective)});
grrUi.forms.module.run(function(grrSemanticRepeatedFormDirectivesRegistryService){var registry=grrSemanticRepeatedFormDirectivesRegistryService;registry.registerDirective(grrUi.forms.globExpressionsListFormDirective.GlobExpressionsListFormDirective.semantic_type,grrUi.forms.globExpressionsListFormDirective.GlobExpressionsListFormDirective)});goog.provide("grrUi.client.virtualFileSystem.events");goog.provide("grrUi.client.virtualFileSystem.fileViewDirective.FileViewController");goog.provide("grrUi.client.virtualFileSystem.fileViewDirective.FileViewDirective");goog.provide("grrUi.client.virtualFileSystem.fileViewDirective.getFileId");goog.provide("grrUi.client.virtualFileSystem.fileViewDirective.getFilePathFromId");
goog.scope(function(){var REFRESH_FOLDER_EVENT="RefreshFolderEvent";grrUi.client.virtualFileSystem.events.REFRESH_FOLDER_EVENT=REFRESH_FOLDER_EVENT;var REFRESH_FILE_EVENT="RefreshFileEvent";grrUi.client.virtualFileSystem.events.REFRESH_FILE_EVENT=REFRESH_FILE_EVENT;grrUi.client.virtualFileSystem.fileViewDirective.replaceInvalidChars_=function(item){return item.replace(/[^a-zA-Z0-9]/g,function(invChar){var hex=invChar.charCodeAt(0).toString(16);return"_"+hex.toUpperCase()})};var replaceInvalidChars_=
grrUi.client.virtualFileSystem.fileViewDirective.replaceInvalidChars_;grrUi.client.virtualFileSystem.fileViewDirective.getFileId=function(filePath){var components=filePath.split("/");var result=components.map(replaceInvalidChars_);return"_"+result.join("-")};grrUi.client.virtualFileSystem.fileViewDirective.getFilePathFromId=function(fileId){var replaceEncodedChars=function(item){return item.replace(/_[0-9A-F][0-9A-F]?/g,function(encChar){var charNum=parseInt(encChar.substr(1),16);return String.fromCharCode(charNum)})};
var components=fileId.substr(1).split("-");var mapped=components.map(replaceEncodedChars);return mapped.join("/")};grrUi.client.virtualFileSystem.fileViewDirective.FileViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.selectedFilePath;this.viewMode="list";this.tab="stats";this.fileVersion;this.clientId;this.grrRoutingService_.uiOnParamsChanged(this.scope_,["clientId","path","version","mode","tab"],this.onUrlRoutingParamsChanged_.bind(this));
this.scope_.$watchGroup(["controller.selectedFilePath","controller.fileVersion","controller.viewMode","controller.tab"],this.onFileContextRoutingParamsChange_.bind(this))};var FileViewController=grrUi.client.virtualFileSystem.fileViewDirective.FileViewController;FileViewController.prototype.onUrlRoutingParamsChanged_=function(params){this.clientId=params[0];this.selectedFilePath=params[1];this.fileVersion=parseInt(params[2],10);this.viewMode=params[3]||"list";this.tab=params[4]||"stats"};FileViewController.prototype.onFileContextRoutingParamsChange_=
function(){var params={path:this.selectedFilePath};params["version"]=this.fileVersion||undefined;if(!this.viewMode||this.viewMode=="list")params["mode"]=undefined;else params["mode"]=this.viewMode;if(!this.tab||this.tab=="stats")params["tab"]=undefined;else params["tab"]=this.tab;this.grrRoutingService_.go("client.vfs",params)};grrUi.client.virtualFileSystem.fileViewDirective.FileViewDirective=function(){return{restrict:"E",scope:{},templateUrl:"/static/angular-components/client/virtual-file-system/file-view.html",
controller:FileViewController,controllerAs:"controller"}};grrUi.client.virtualFileSystem.fileViewDirective.FileViewDirective.directive_name="grrFileView"});goog.provide("grrUi.client.virtualFileSystem.utils.ensurePathIsFolder");goog.provide("grrUi.client.virtualFileSystem.utils.getFolderFromPath");goog.scope(function(){grrUi.client.virtualFileSystem.utils.ensurePathIsFolder=function(path){if(path.endsWith("/"))return path;else return path+"/"};grrUi.client.virtualFileSystem.utils.getFolderFromPath=function(path){if(!path)return"";var components=path.split("/");return components.slice(0,-1).join("/")}});goog.provide("grrUi.routing.aff4UrnToUrl");goog.require("grrUi.core.fileDownloadUtils.vfsRoots");goog.require("grrUi.core.utils.CLIENT_ID_RE");goog.require("grrUi.core.utils.stripAff4Prefix");
grrUi.routing.aff4UrnToUrl=function(urn){var components=grrUi.core.utils.stripAff4Prefix(urn).split("/");if(grrUi.core.utils.CLIENT_ID_RE.test(components[0]))if(grrUi.core.fileDownloadUtils.vfsRoots.includes(components[1]))return{state:"client.vfs",params:{clientId:components[0],path:components.slice(1).join("/")}};else if(components[1]==="flows"&&components.length===3)return{state:"client.flows",params:{clientId:components[0],flowId:components[2]}};else return{state:"client",params:{clientId:components[0]}};
else if(components[0]==="hunts")return{state:"hunts",params:{huntId:components[1]}};else if(components[0]==="cron")return{state:"crons",params:{cronJobId:components[1]}};else if(components[0]==="ACL")if(grrUi.core.utils.CLIENT_ID_RE.test(components[1]))return{state:"clientApproval",params:{clientId:components[1],username:components[components.length-2],approvalId:components[components.length-1]}};else if(components[1]=="hunts")return{state:"huntApproval",params:{huntId:components[2],username:components[components.length-
2],approvalId:components[components.length-1]}};else if(components[1]=="cron")return{state:"cronJobApproval",params:{cronJobId:components[2],username:components[components.length-2],approvalId:components[components.length-1]}};return null};goog.provide("grrUi.routing.rewriteUrl");goog.require("grrUi.client.virtualFileSystem.fileViewDirective.getFilePathFromId");goog.require("grrUi.client.virtualFileSystem.utils.ensurePathIsFolder");goog.require("grrUi.core.apiService.encodeUrlPath");goog.require("grrUi.routing.aff4UrnToUrl");
goog.scope(function(){var getFilePathFromId=grrUi.client.virtualFileSystem.fileViewDirective.getFilePathFromId;var ensurePathIsFolder=grrUi.client.virtualFileSystem.utils.ensurePathIsFolder;var encodeUrlPath=grrUi.core.apiService.encodeUrlPath;grrUi.routing.rewriteUrl=function(url){var hashState=grrUi.routing.parseHash_(url);var clientId=hashState["c"];if(clientId&&clientId.indexOf("aff4:/")===0)clientId=clientId.split("/")[1];var main=hashState["main"];switch(main){case "ManageCron":var cronJobUrn=
hashState["cron_job_urn"];var cronJobId=cronJobUrn?cronJobUrn.split("/")[2]:"";return"/crons/"+cronJobId;case "ManageHunts":var huntUrn=hashState["hunt_id"];var huntId=huntUrn?huntUrn.split("/")[2]:"";return"/hunts/"+huntId;case "GlobalLaunchFlows":return"/global-flows";case "ServerLoadView":return"/server-load";case "BinaryConfigurationView":return"/manage-binaries";case "ConfigManager":return"/config";case "ArtifactManagerView":return"/artifacts";case "ApiDocumentation":return"/api-docs";case "GrantAccess":var acl=
hashState["acl"]||"";var routingState=grrUi.routing.aff4UrnToUrl(acl);switch(routingState["state"]){case "clientApproval":return["/users",routingState["params"]["username"],"approvals","client",routingState["params"]["clientId"],routingState["params"]["approvalId"]].join("/");case "huntApproval":return["/users",routingState["params"]["username"],"approvals","hunt",routingState["params"]["huntId"],routingState["params"]["approvalId"]].join("/");case "cronJobApproval":return["/users",routingState["params"]["username"],
"approvals","cron-job",routingState["params"]["cronJobId"],routingState["params"]["approvalId"]].join("/");default:break}return"/";case "CanaryTestRenderer":return"/canary-test";case "HostTable":var q=hashState["q"]||"";return"/search?q="+q;case "HostInformation":return"/clients/"+clientId;case "VirtualFileSystemView":var path;if(hashState["aff4_path"])path=hashState["aff4_path"].slice(hashState["c"].length+1);else path=ensurePathIsFolder(getFilePathFromId(hashState["t"]||""));return"/clients/"+clientId+
"/vfs/"+encodeUrlPath(path);case "TimelineMain":case "ContainerViewer":var path=hashState["container"]||"";var query=hashState["query"]||"";return"/clients/"+clientId+"/vfs-container"+"?path="+path+"&query="+query;case "LaunchFlows":return"/clients/"+clientId+"/launch-flow";case "ManageFlows":var flowUrn=hashState["flow"];var flowId=flowUrn?flowUrn.split("/")[3]:"";return"/clients/"+clientId+"/flows/"+flowId;case "DebugClientRequestsView":return"/clients/"+clientId+"/debug-requests";case "ClientLoadView":return"/clients/"+
clientId+"/load";case "ClientCrashesRenderer":return"/clients/"+clientId+"/crashes";case "ClientStatsView":return"/clients/"+clientId+"/stats";default:if(clientId)return"/clients/"+clientId;return null}};grrUi.routing.parseHash_=function(hash){if(hash.indexOf("#")==0)hash=hash.substr(1);var result={};var parts=hash.split("&");for(var i=0;i<parts.length;i++){var kv=parts[i].split("=");if(kv[0]&&kv[1])result[kv[0]]=decodeURIComponent(kv[1].replace(/\+/g," ")||"")}return result}});goog.provide("grrUi.routing.routingService.RoutingService");
goog.scope(function(){grrUi.routing.routingService.RoutingService=function($state){this.state_=$state};var RoutingService=grrUi.routing.routingService.RoutingService;RoutingService.service_name="grrRoutingService";RoutingService.prototype.href=function(targetState,opt_params){return this.state_.href(targetState,opt_params)};RoutingService.prototype.go=function(targetState,opt_params){var currentState=this.state_.current.name;return this.state_.go(targetState,opt_params,{notify:currentState!==targetState})};
RoutingService.prototype.uiOnParamsChanged=function(scope,paramNames,callback,opt_stateAgnostic){var currentStateName=this.state_.current.name;if(!angular.isArray(paramNames)){var paramName=paramNames;paramNames=[paramName]}return scope.$watchCollection(function(){return paramNames.map(function(paramName){return this.state_.params[paramName]}.bind(this))}.bind(this),function(newValues,oldValues){if(!opt_stateAgnostic&&!this.state_.includes(currentStateName))return;if(newValues.length===1)callback(newValues[0],
this.state_.params);else callback(newValues,this.state_.params)}.bind(this))};RoutingService.prototype.onStateChange=function(scope,callback){callback(this.state_.current.name,this.state_.params);return scope.$on("$stateChangeSuccess",function(event,state,params){callback(state.name,params)}.bind(this))}});goog.provide("grrUi.routing.module");goog.require("grrUi.core.apiService.encodeUrlPath");goog.require("grrUi.routing.rewriteUrl");goog.require("grrUi.routing.routingService.RoutingService");grrUi.routing.module=angular.module("grrUi.routing",["ui.router"]);grrUi.routing.module.service(grrUi.routing.routingService.RoutingService.service_name,grrUi.routing.routingService.RoutingService);
grrUi.routing.module.config(function($stateProvider,$urlRouterProvider,$urlMatcherFactoryProvider){$urlMatcherFactoryProvider.type("pathWithUnescapedSlashes",{encode:function(item){if(!item)return"";else return grrUi.core.apiService.encodeUrlPath(item)},decode:function(item){if(!item)return"";else return decodeURIComponent(item)},pattern:/.*/});$urlRouterProvider.deferIntercept();$stateProvider.state("userDashboard",{url:"",template:"<grr-user-dashboard />",title:"Home"}).state("search",{url:"/search?q",
template:"<grr-clients-list />",title:function(params){if(params["q"])return'Search for "'+params["q"]+'"';else return"Client List"}}).state("apiDocs",{url:"/api-docs",template:"<grr-api-docs />",title:"API Docs"}).state("clientApproval",{url:"/users/:username/approvals/client/:clientId/:approvalId",template:"<grr-client-approval-view />",title:function(params){return["Approvals",params["username"],params["clientId"]]}}).state("huntApproval",{url:"/users/:username/approvals/hunt/:huntId/:approvalId",
template:"<grr-hunt-approval-view />",title:function(params){return["Approvals",params["username"],params["huntId"]]}}).state("cronJobApproval",{url:"/users/:username/approvals/cron-job/:cronJobId/:approvalId",template:"<grr-cron-job-approval-view />",title:function(params){return["Approvals",params["username"],params["cronJobId"]]}}).state("crons",{url:"/crons/:cronJobId/:tab",template:"<grr-cron-view />",params:{cronJobId:{value:null,squash:true},tab:{value:null,squash:true}},title:function(params){if(params["cronJobId"])return["Cron Jobs",
params["cronJobId"]];else return"Cron Jobs"}}).state("hunts",{url:"/hunts/:huntId/:tab",template:"<grr-hunts-view />",params:{huntId:{value:null,squash:true},tab:{value:null,squash:true}},title:function(params){if(params["huntId"])return params["huntId"];else return"Hunts"}}).state("stats",{url:"/stats/:name/:client_label?start_time&duration",template:"<grr-stats-view />",params:{name:{value:null,squash:true},client_label:{value:null,squash:true}},title:"Stats"}).state("serverLoad",{url:"/server-load",
template:"<grr-server-load />",title:"Server Load"}).state("manageBinaries",{url:"/manage-binaries",template:"<grr-config-binaries-view />",title:"Manage Binaries"}).state("config",{url:"/config",template:"<grr-config-view />",title:"Configuration"}).state("artifacts",{url:"/artifacts",template:"<grr-artifact-manager-view />",title:"Artifacts"}).state("client",{url:"/clients/:clientId",redirectTo:"client.hostInfo",template:"<div ui-view></div>",title:function(params){return params["clientId"]}}).state("client.hostInfo",
{url:"/host-info",template:"<grr-host-info />",title:"Host Information"}).state("client.launchFlows",{url:"/launch-flow",template:"<grr-start-flow-view />",title:"Launch Flows"}).state("client.vfs",{url:"/vfs/{path:pathWithUnescapedSlashes}?version&mode&tab",template:"<grr-file-view />",title:function(params){return"/"+(params["path"]||"")}}).state("client.flows",{url:"/flows/:flowId/:tab",template:"<grr-client-flows-view />",params:{flowId:{value:null,squash:true},tab:{value:null,squash:true}},title:function(params){if(params["flowId"])return params["flowId"];
else return"Flows"}}).state("client.crashes",{url:"/crashes",template:"<grr-client-crashes />",title:"Crashes"}).state("client.debugRequests",{url:"/debug-requests",template:"<grr-debug-requests-view />",title:"Debug Requests"}).state("client.loadStats",{url:"/load-stats",template:"<grr-client-load-view />",title:"Load Stats"})}).run(function($rootScope,$location,$state,$urlRouter,$document){var updateTitle=function(){var breadcrumbs=[];var curState=$state["$current"];while(angular.isDefined(curState)){if(angular.isString(curState.title))breadcrumbs.splice(0,
0,curState.title);else if(angular.isFunction(curState.title)){var newItem=curState.title($state.params);if(angular.isArray(newItem))breadcrumbs=newItem.concat(breadcrumbs);else breadcrumbs.splice(0,0,newItem)}curState=curState.parent}breadcrumbs.splice(0,0,"GRR");$document[0].title=breadcrumbs.join(" | ")};$rootScope.$on("$stateChangeStart",function(evt,to,params){if(to.redirectTo){evt.preventDefault();$state.go(to.redirectTo,params)}});$rootScope.$on("$stateChangeSuccess",updateTitle);$rootScope.$on("$locationChangeSuccess",
function(evt){evt.preventDefault();var url=$location.url().substring(1);var rewrittenUrl=grrUi.routing.rewriteUrl(url);if(rewrittenUrl)$location.url(rewrittenUrl);$urlRouter.sync();updateTitle()});$urlRouter.listen()});goog.provide("grrUi.semantic.apiHuntResultDirective.ApiHuntResultDirective");goog.scope(function(){grrUi.semantic.apiHuntResultDirective.ApiHuntResultDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/api-hunt-result.html"}};grrUi.semantic.apiHuntResultDirective.ApiHuntResultDirective.directive_name="grrApiHuntResult";grrUi.semantic.apiHuntResultDirective.ApiHuntResultDirective.semantic_type="ApiHuntResult"});goog.provide("grrUi.semantic.byteSizeDirective.ByteSizeController");goog.provide("grrUi.semantic.byteSizeDirective.ByteSizeDirective");goog.provide("grrUi.semantic.byteSizeDirective.stringifyByteSize");
goog.scope(function(){var KB_UNIT=1024;var MB_UNIT=KB_UNIT*1024;var GB_UNIT=MB_UNIT*1024;grrUi.semantic.byteSizeDirective.stringifyByteSize=function(value){if(value==0)return[0,""];if(value>GB_UNIT)return[value/GB_UNIT,"Gb"];else if(value>MB_UNIT)return[value/MB_UNIT,"Mb"];else if(value>KB_UNIT)return[value/KB_UNIT,"Kb"];else return[value,"b"]};var stringifyByteSize=grrUi.semantic.byteSizeDirective.stringifyByteSize;grrUi.semantic.byteSizeDirective.ByteSizeController=function($scope){this.scope_=
$scope;this.stringifiedByteSize;this.scope_.$watch("::value",this.onValueChange.bind(this))};var ByteSizeController=grrUi.semantic.byteSizeDirective.ByteSizeController;ByteSizeController.prototype.onValueChange=function(newValue){var byteSize=newValue.value;if(angular.isNumber(byteSize)){var stringified=stringifyByteSize(byteSize);var size=stringified[0];var sizeToken=stringified[1];var result=[Math.floor(size).toString()];var decimalPart=Math.round(size%1*10).toString();if(decimalPart!=="0")result.push(".",
decimalPart);result.push(sizeToken);this.stringifiedByteSize=result.join("")}else this.stringifiedByteSize="-"};grrUi.semantic.byteSizeDirective.ByteSizeDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/byte-size.html",controller:ByteSizeController,controllerAs:"controller"}};grrUi.semantic.byteSizeDirective.ByteSizeDirective.directive_name="grrByteSize";grrUi.semantic.byteSizeDirective.ByteSizeDirective.semantic_type="ByteSize"});goog.provide("grrUi.semantic.bytesDirective.BytesController");goog.provide("grrUi.semantic.bytesDirective.BytesDirective");goog.require("grrUi.forms.bytesFormDirective.bytesToHexEncodedString");
goog.scope(function(){grrUi.semantic.bytesDirective.BytesController=function($scope,$window){this.scope_=$scope;this.window_=$window;this.stringifiedBytes;this.scope_.$watch("::value",this.onValueChange.bind(this))};var BytesController=grrUi.semantic.bytesDirective.BytesController;var FIRST_RENDER_LIMIT=1024;BytesController.prototype.onClick=function(e){e.stopPropagation();var bytes=this.scope_["value"]["value"];try{this.stringifiedBytes=grrUi.forms.bytesFormDirective.bytesToHexEncodedString(this.window_.atob(bytes))}catch(err){this.stringifiedBytes=
"base64decodeerror("+err.message+"):"+bytes}};BytesController.prototype.onValueChange=function(newValue){var bytes=newValue.value;if(angular.isString(bytes)){if(bytes.length<FIRST_RENDER_LIMIT)try{this.stringifiedBytes=grrUi.forms.bytesFormDirective.bytesToHexEncodedString(this.window_.atob(bytes))}catch(err){this.stringifiedBytes="base64decodeerror("+err.message+"):"+bytes}}else this.stringifiedBytes=""};grrUi.semantic.bytesDirective.BytesDirective=function(){return{scope:{value:"="},restrict:"E",
templateUrl:"/static/angular-components/semantic/bytes.html",controller:BytesController,controllerAs:"controller"}};grrUi.semantic.bytesDirective.BytesDirective.directive_name="grrBytes";grrUi.semantic.bytesDirective.BytesDirective.semantic_types=["RDFBytes","str"]});goog.provide("grrUi.semantic.clientUrnDirective.ClientUrnDirective");
goog.scope(function(){var ClientUrnController=function($scope,$uibModal,grrApiService){this.scope_=$scope;this.scope_.value;this.uibModal_=$uibModal;this.grrApiService_=grrApiService;this.clientDetails;this.clientId;this.scope_.$watch("::value",this.onValueChange.bind(this))};ClientUrnController.prototype.onValueChange=function(){var clientUrn;if(angular.isObject(this.scope_.value))clientUrn=this.scope_.value.value;else clientUrn=this.scope_.value;if(angular.isString(clientUrn))this.clientId=clientUrn.replace(/^aff4:\//,
"")};ClientUrnController.prototype.onInfoClick=function(){this.uibModal_.open({templateUrl:"/static/angular-components/semantic/client-urn-modal.html",scope:this.scope_});this.grrApiService_.get("clients/"+this.clientId).then(function(response){this.clientDetails=response.data}.bind(this))};grrUi.semantic.clientUrnDirective.ClientUrnDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/client-urn.html",controller:ClientUrnController,controllerAs:"controller"}};
grrUi.semantic.clientUrnDirective.ClientUrnDirective.directive_name="grrClientUrn";grrUi.semantic.clientUrnDirective.ClientUrnDirective.semantic_types=["ClientURN","ApiClientId"]});goog.provide("grrUi.semantic.dataObjectDirective.DataObjectController");goog.provide("grrUi.semantic.dataObjectDirective.DataObjectDirective");goog.scope(function(){grrUi.semantic.dataObjectDirective.DataObjectDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/data-object.html"}};grrUi.semantic.dataObjectDirective.DataObjectDirective.directive_name="grrDataObject";grrUi.semantic.dataObjectDirective.DataObjectDirective.semantic_type="ApiDataObject"});goog.provide("grrUi.semantic.dictDirective.DictController");goog.provide("grrUi.semantic.dictDirective.DictDirective");goog.scope(function(){grrUi.semantic.dictDirective.DictDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/dict.html"}};grrUi.semantic.dictDirective.DictDirective.directive_name="grrDict";grrUi.semantic.dictDirective.DictDirective.semantic_types=["dict","Dict"]});goog.provide("grrUi.semantic.encryptionKeyDirective.EncryptionKeyController");goog.provide("grrUi.semantic.encryptionKeyDirective.EncryptionKeyDirective");goog.provide("grrUi.semantic.encryptionKeyDirective.stringifyEncryptionKey");
goog.scope(function(){grrUi.semantic.encryptionKeyDirective.stringifyEncryptionKey=function(base64Bytes){var decoded=window.atob(base64Bytes);var result=[];for(var i=0;i<decoded.length;++i){var c=decoded.charCodeAt(i).toString(16);if(c.length==1)c="0"+c;result.push(c)}return result.join("")};grrUi.semantic.encryptionKeyDirective.EncryptionKeyController=function($scope){this.scope_=$scope;this.stringifiedKey;this.scope_.$watch("::value.value",this.onValueChange.bind(this))};var EncryptionKeyController=
grrUi.semantic.encryptionKeyDirective.EncryptionKeyController;EncryptionKeyController.prototype.onValueChange=function(newValue){if(angular.isDefined(newValue))this.stringifiedKey=grrUi.semantic.encryptionKeyDirective.stringifyEncryptionKey(newValue)};grrUi.semantic.encryptionKeyDirective.EncryptionKeyDirective=function(){return{scope:{value:"="},restrict:"E",template:"{$ ::controller.stringifiedKey $}",controller:EncryptionKeyController,controllerAs:"controller"}};grrUi.semantic.encryptionKeyDirective.EncryptionKeyDirective.directive_name=
"grrEncryptionKey";grrUi.semantic.encryptionKeyDirective.EncryptionKeyDirective.semantic_type="EncryptionKey"});goog.provide("grrUi.semantic.flowIdDirective.FlowIdController");goog.provide("grrUi.semantic.flowIdDirective.FlowIdDirective");
goog.scope(function(){grrUi.semantic.flowIdDirective.FlowIdController=function($scope){this.scope_=$scope;this.clientId};var FlowIdController=grrUi.semantic.flowIdDirective.FlowIdController;grrUi.semantic.flowIdDirective.FlowIdDirective=function(){return{scope:{value:"="},require:"?^grrClientContext",restrict:"E",templateUrl:"/static/angular-components/semantic/flow-id.html",controller:FlowIdController,controllerAs:"controller",link:function(scope,element,attrs,grrClientContextCtrl){if(grrClientContextCtrl)scope["controller"].clientId=
grrClientContextCtrl.clientId}}};grrUi.semantic.flowIdDirective.FlowIdDirective.directive_name="grrFlowId";grrUi.semantic.flowIdDirective.FlowIdDirective.semantic_type="ApiFlowId"});goog.provide("grrUi.semantic.hashDigestDirective.HashDigestController");goog.provide("grrUi.semantic.hashDigestDirective.HashDigestDirective");
goog.scope(function(){grrUi.semantic.hashDigestDirective.HashDigestController=function($scope,$window){this.scope_=$scope;this.window_=$window;this.stringifiedBytes;this.scope_.$watch("::value",this.onValueChange.bind(this))};var HashDigestController=grrUi.semantic.hashDigestDirective.HashDigestController;HashDigestController.prototype.bytesToHexString=function(bytes){var hex="";for(var i=0;i<bytes.length;i+=1){var char=bytes.charCodeAt(i).toString(16);hex+=("0"+char).substr(-2)}return hex};HashDigestController.prototype.onValueChange=
function(newValue){var bytes=newValue.value;if(angular.isString(bytes))try{this.stringifiedBytes=this.bytesToHexString(this.window_.atob(bytes))}catch(err){this.stringifiedBytes="base64decodeerror("+err.message+"):"+bytes}else this.stringifiedBytes=""};grrUi.semantic.hashDigestDirective.HashDigestDirective=function(){return{scope:{value:"="},restrict:"E",template:'<nobr ng-if="::controller.stringifiedBytes !== undefined">'+"{$ ::controller.stringifiedBytes $}</nobr>",controller:HashDigestController,
controllerAs:"controller"}};grrUi.semantic.hashDigestDirective.HashDigestDirective.directive_name="grrHashDigest";grrUi.semantic.hashDigestDirective.HashDigestDirective.semantic_type="HashDigest"});goog.provide("grrUi.semantic.hashListDirective.HashListController");goog.provide("grrUi.semantic.hashListDirective.HashListDirective");
goog.scope(function(){var HASH_SIZE=32;grrUi.semantic.hashListDirective.HashListController=function($scope,$window){this.scope_=$scope;this.window_=$window;this.chunks=[];this.scope_.$watch("::value",this.onValueChange.bind(this))};var HashListController=grrUi.semantic.hashListDirective.HashListController;HashListController.prototype.onValueChange=function(newValue){this.chunks=[];if(angular.isString(newValue.value)){var bytes=this.window_.atob(newValue.value);while(bytes){var chunkStr=bytes.substr(0,
HASH_SIZE);bytes=bytes.substr(HASH_SIZE);this.chunks.push({value:this.window_.btoa(chunkStr),type:"HashDigest"})}}};grrUi.semantic.hashListDirective.HashListDirective=function(){return{scope:{value:"="},restrict:"E",template:'<grr-semantic-value value="::controller.chunks" />',controller:HashListController,controllerAs:"controller"}};grrUi.semantic.hashListDirective.HashListDirective.directive_name="grrHashList";grrUi.semantic.hashListDirective.HashListDirective.semantic_type="HashList"});goog.provide("grrUi.semantic.huntIdDirective.HuntIdController");goog.provide("grrUi.semantic.huntIdDirective.HuntIdDirective");goog.scope(function(){grrUi.semantic.huntIdDirective.HuntIdDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/hunt-id.html"}};grrUi.semantic.huntIdDirective.HuntIdDirective.directive_name="grrHuntId";grrUi.semantic.huntIdDirective.HuntIdDirective.semantic_type="ApiHuntId"});goog.provide("grrUi.semantic.jsonDirective.JsonController");goog.provide("grrUi.semantic.jsonDirective.JsonDirective");
goog.scope(function(){grrUi.semantic.jsonDirective.JsonController=function($scope,$window){this.scope_=$scope;this.window_=$window;this.prettyJson;this.scope_.$watch("::value",this.onValueChange.bind(this))};var JsonController=grrUi.semantic.jsonDirective.JsonController;var FIRST_RENDER_LIMIT=1024;JsonController.prototype.onClick=function(e){e.stopPropagation();var jsonStr=this.scope_["value"]["value"];try{var parsedJson=JSON.parse(jsonStr);this.prettyJson=JSON.stringify(parsedJson,null,2)}catch(err){this.prettyJson=
"jsonerror("+err.message+"):"+jsonStr}};JsonController.prototype.onValueChange=function(newValue){var jsonStr=newValue.value;if(angular.isString(jsonStr)){if(jsonStr.length<FIRST_RENDER_LIMIT)try{var parsedJson=JSON.parse(jsonStr);this.prettyJson=JSON.stringify(parsedJson,null,2)}catch(err){this.prettyJson="jsonerror("+err.message+"):"+jsonStr}}else this.prettyJson=""};grrUi.semantic.jsonDirective.JsonDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/json.html",
controller:JsonController,controllerAs:"controller"}};grrUi.semantic.jsonDirective.JsonDirective.directive_name="grrJson";grrUi.semantic.jsonDirective.JsonDirective.semantic_type="ZippedJSONBytes"});goog.provide("grrUi.semantic.macAddressDirective.MacAddressController");goog.provide("grrUi.semantic.macAddressDirective.MacAddressDirective");goog.provide("grrUi.semantic.macAddressDirective.convertMacAddressToString");
goog.scope(function(){grrUi.semantic.macAddressDirective.convertMacAddressToString=function(address){var result=[];for(var i=0;i<address.length;++i){var part=address.charCodeAt(i).toString(16);if(part.length===1)part="0"+part;result.push(part)}return result.join(":")};var convertMacAddressToString=grrUi.semantic.macAddressDirective.convertMacAddressToString;grrUi.semantic.macAddressDirective.MacAddressController=function($scope){this.scope_=$scope;this.convertedAddress;this.scope_.$watch("::value",
this.onValueChange.bind(this))};var MacAddressController=grrUi.semantic.macAddressDirective.MacAddressController;MacAddressController.prototype.onValueChange=function(newValue){var address=newValue.value;if(angular.isString(address))this.convertedAddress=convertMacAddressToString(window.atob(address));else this.convertedAddress="-"};grrUi.semantic.macAddressDirective.MacAddressDirective=function(){return{scope:{value:"="},restrict:"E",template:'<nobr ng-if="::controller.convertedAddress !== undefined">'+
"{$ ::controller.convertedAddress $}</nobr>",controller:MacAddressController,controllerAs:"controller"}};grrUi.semantic.macAddressDirective.MacAddressDirective.directive_name="grrMacAddress";grrUi.semantic.macAddressDirective.MacAddressDirective.semantic_type="MacAddress"});goog.provide("grrUi.semantic.networkAddressDirective.NetworkAddressController");goog.provide("grrUi.semantic.networkAddressDirective.NetworkAddressDirective");goog.provide("grrUi.semantic.networkAddressDirective.convertIpv4AddressToString");goog.provide("grrUi.semantic.networkAddressDirective.convertIpv6AddressToString");
goog.scope(function(){grrUi.semantic.networkAddressDirective.convertIpv4AddressToString=function(address){var result=[];for(var i=0;i<address.length;++i){var part=address.charCodeAt(i).toString(10);if(part.length===1)part="0"+part;result.push(part)}return result.join(".")};var convertIpv4AddressToString=grrUi.semantic.networkAddressDirective.convertIpv4AddressToString;grrUi.semantic.networkAddressDirective.convertIpv6AddressToString=function(address){var result=[];var colonCounter=0;for(var i=0;i<
address.length;++i){var part=address.charCodeAt(i).toString(16);if(part.length===1)part="0"+part;result.push(part);if(++colonCounter==2){result.push(":");colonCounter=0}}return result.join("")};var convertIpv6AddressToString=grrUi.semantic.networkAddressDirective.convertIpv6AddressToString;grrUi.semantic.networkAddressDirective.convertBase64AddressToString=function(address,addressType){if(angular.isUndefined(address))return"-";else switch(addressType){case "INET":return convertIpv4AddressToString(window.atob(address));
case "INET6":return convertIpv6AddressToString(window.atob(address));default:return"<unknown address type>"}};var convertBase64AddressToString=grrUi.semantic.networkAddressDirective.convertBase64AddressToString;grrUi.semantic.networkAddressDirective.NetworkAddressController=function($scope){this.scope_=$scope;this.convertedAddress;this.scope_.$watch("::value",this.onValueChange.bind(this))};var NetworkAddressController=grrUi.semantic.networkAddressDirective.NetworkAddressController;NetworkAddressController.prototype.onValueChange=
function(newValue){if(!angular.isObject(newValue)){this.convertedAddress="-";return}if(angular.isObject(newValue.value))if(angular.isDefined(newValue.value.packed_bytes))this.convertedAddress=convertBase64AddressToString(newValue.value.packed_bytes.value,newValue.value.address_type.value);else if(angular.isDefined(newValue.value.human_readable))this.convertedAddress=newValue.value.human_readable.value;else this.convertedAddress="<unknown>";else if(angular.isObject(newValue))if(angular.isDefined(newValue.packed_bytes))this.convertedAddress=
convertBase64AddressToString(newValue.packed_bytes,newValue.address_type);else if(angular.isDefined(newValue.human_readable))this.convertedAddress=newValue.human_readable;else this.convertedAddress="<unknown>"};grrUi.semantic.networkAddressDirective.NetworkAddressDirective=function(){return{scope:{value:"="},restrict:"E",template:'<nobr ng-if="::controller.convertedAddress !== undefined">'+"{$ ::controller.convertedAddress $}</nobr>",controller:NetworkAddressController,controllerAs:"controller"}};
grrUi.semantic.networkAddressDirective.NetworkAddressDirective.directive_name="grrNetworkAddress";grrUi.semantic.networkAddressDirective.NetworkAddressDirective.semantic_type="NetworkAddress"});goog.provide("grrUi.semantic.objectLabelDirective.ObjectLabelController");goog.provide("grrUi.semantic.objectLabelDirective.ObjectLabelDirective");
goog.scope(function(){grrUi.semantic.objectLabelDirective.ObjectLabelController=function($scope){this.scope_=$scope;this.labelName;this.labelOwner;this.scope_.$watch("::value",this.onValueChange_.bind(this))};var ObjectLabelController=grrUi.semantic.objectLabelDirective.ObjectLabelController;ObjectLabelController.prototype.onValueChange_=function(newValue){if(!newValue)this.labelName=this.labelType=null;if(angular.isDefined(newValue["value"])){this.labelName=newValue["value"]["name"]["value"];this.labelOwner=
newValue["value"]["owner"]["value"]}else{this.labelName=newValue["name"];this.labelOwner=newValue["owner"]}};grrUi.semantic.objectLabelDirective.ObjectLabelDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/object-label.html",controller:ObjectLabelController,controllerAs:"controller"}};grrUi.semantic.objectLabelDirective.ObjectLabelDirective.directive_name="grrObjectLabel";grrUi.semantic.objectLabelDirective.ObjectLabelDirective.semantic_type=
"AFF4ObjectLabel"});goog.provide("grrUi.semantic.objectLabelsListDirective.ObjectLabelsListDirective");
goog.scope(function(){grrUi.semantic.objectLabelsListDirective.ObjectLabelsListDirective=function(){return{scope:{value:"="},restrict:"E",template:"<grr-object-label "+'ng-repeat="label in ::value.value.labels" '+'value="::label"></grr-object-label>',controllerAs:"controller"}};grrUi.semantic.objectLabelsListDirective.ObjectLabelsListDirective.directive_name="grrObjectLabelsList";grrUi.semantic.objectLabelsListDirective.ObjectLabelsListDirective.semantic_type="AFF4ObjectLabelsList"});goog.provide("grrUi.semantic.primitiveDirective.PrimitiveDirective");goog.scope(function(){grrUi.semantic.primitiveDirective.PrimitiveDirective=function(){return{scope:{value:"="},restrict:"E",template:"{$ ::value.value $}"}};grrUi.semantic.primitiveDirective.PrimitiveDirective.directive_name="grrPrimitive";grrUi.semantic.primitiveDirective.PrimitiveDirective.semantic_types=["RDFBool","bool","RDFInteger","int","long","float","RDFString","basestring"]});goog.provide("grrUi.semantic.pseudo.fetchMoreLinkDirective.FetchMoreLinkDirective");
goog.scope(function(){grrUi.semantic.pseudo.fetchMoreLinkDirective.FetchMoreLinkDirective=function(){return{scope:{value:"="},link:function(scope){scope.onClick=function(e){scope.continuationShown=true;e.stopPropagation()}},restrict:"E",templateUrl:"/static/angular-components/semantic/pseudo/"+"semantic-fetch-more-link.html"}};grrUi.semantic.pseudo.fetchMoreLinkDirective.FetchMoreLinkDirective.directive_name="grrFetchMoreLink";grrUi.semantic.pseudo.fetchMoreLinkDirective.FetchMoreLinkDirective.semantic_type=
"__FetchMoreLink"});goog.provide("grrUi.semantic.pseudo.module");goog.require("grrUi.core.module");goog.require("grrUi.semantic.pseudo.fetchMoreLinkDirective.FetchMoreLinkDirective");grrUi.semantic.pseudo.module=angular.module("grrUi.semantic.pseudo",[grrUi.core.module.name,"ui.bootstrap"]);grrUi.semantic.pseudo.module.directive(grrUi.semantic.pseudo.fetchMoreLinkDirective.FetchMoreLinkDirective.directive_name,grrUi.semantic.pseudo.fetchMoreLinkDirective.FetchMoreLinkDirective);
grrUi.semantic.pseudo.module.run(function(grrSemanticValueDirectivesRegistryService){var registry=grrSemanticValueDirectivesRegistryService;registry.registerDirective(grrUi.semantic.pseudo.fetchMoreLinkDirective.FetchMoreLinkDirective.semantic_type,grrUi.semantic.pseudo.fetchMoreLinkDirective.FetchMoreLinkDirective)});goog.provide("grrUi.semantic.rekall.logDirective.LogDirective");goog.scope(function(){grrUi.semantic.rekall.logDirective.LogDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/rekall/log.html"}};grrUi.semantic.rekall.logDirective.LogDirective.directive_name="grrRekallLog"});goog.provide("grrUi.semantic.rekall.metadataDirective.MetadataDirective");goog.scope(function(){grrUi.semantic.rekall.metadataDirective.MetadataDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/rekall/metadata.html"}};grrUi.semantic.rekall.metadataDirective.MetadataDirective.directive_name="grrRekallMetadata"});goog.provide("grrUi.semantic.rekall.registeredUnixTimeStampDirective.RegisteredUnixTimeStampDirective");
goog.scope(function(){grrUi.semantic.rekall.registeredUnixTimeStampDirective.RegisteredUnixTimeStampDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/rekall/"+"registered-unix-time-stamp.html"}};grrUi.semantic.rekall.registeredUnixTimeStampDirective.RegisteredUnixTimeStampDirective.directive_name="grrRekallRegisteredUnixTimeStamp";grrUi.semantic.rekall.registeredUnixTimeStampDirective.RegisteredUnixTimeStampDirective.rekall_type="UnixTimeStamp"});goog.provide("grrUi.semantic.rekall.rekallDefaultValueDirective.RekallDefaultValueDirective");goog.scope(function(){grrUi.semantic.rekall.rekallDefaultValueDirective.RekallDefaultValueDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/rekall/rekall-default-value.html"}};grrUi.semantic.rekall.rekallDefaultValueDirective.RekallDefaultValueDirective.directive_name="grrRekallDefaultValue"});goog.provide("grrUi.semantic.rekall.utils.cropRekallJson");goog.provide("grrUi.semantic.rekall.utils.stackRekallTables");
grrUi.semantic.rekall.utils.cropRekallJson=function(jsonStr,targetLen){if(targetLen<=2||jsonStr==="[]")return"[]";if(jsonStr.length<=targetLen)return jsonStr;if(!jsonStr.startsWith("[["))throw new Error("Malformed Rekall JSON message.");var lastMsgEnd=1;var depth=1;var escaped=false;var insideString=false;for(var i=2;i<targetLen-1;++i){if(!insideString)if(jsonStr[i]==="[")++depth;else if(jsonStr[i]==="]"){--depth;if(depth==0)lastMsgEnd=i+1;else if(depth<0)throw new Error("Syntax error in Rekall JSON message.");
}if(!escaped&&jsonStr[i]=='"')insideString=!insideString;escaped=!escaped&&jsonStr[i]==="\\"}return jsonStr.slice(0,lastMsgEnd)+"]"};
grrUi.semantic.rekall.utils.stackRekallTables=function(parsed){var ret=[];var lastTableRows;angular.forEach(parsed,function(message){var type=message[0];var content=message[1];if(type=="t"){lastTableRows=[];ret.push(["t",{"header":content,"rows":lastTableRows}])}else if(type=="r"){if(angular.isUndefined(lastTableRows)){lastTableRows=[];ret.push(["t",{"header":undefined,"rows":lastTableRows}])}lastTableRows.push(content)}else ret.push(message)});return ret};goog.provide("grrUi.semantic.rekall.rekallJsonDirective.RekallJsonController");goog.provide("grrUi.semantic.rekall.rekallJsonDirective.RekallJsonDirective");goog.require("grrUi.semantic.rekall.utils.cropRekallJson");goog.require("grrUi.semantic.rekall.utils.stackRekallTables");
goog.scope(function(){grrUi.semantic.rekall.rekallJsonDirective.RekallJsonController=function($scope){this.scope_=$scope;this.parsedJson;this.error="";this.jsonContextStr;this.compressedJsonStr;this.state;this.renderIncomplete=true;this.scope_.$watchGroup(["jsonContextMessages","compressedJsonMessages"],this.onScopeChange_.bind(this))};var RekallJsonController=grrUi.semantic.rekall.rekallJsonDirective.RekallJsonController;var FIRST_RENDER_LIMIT=1024;RekallJsonController.prototype.onClick=function(e){e.stopPropagation();
this.render_()};RekallJsonController.prototype.render_=function(opt_renderLimit){var renderLimit=opt_renderLimit||Infinity;if(this.jsonContextStr.length+this.compressedJsonStr.length<=renderLimit)this.renderIncomplete=false;try{this.parsedJson=JSON.parse(grrUi.semantic.rekall.utils.cropRekallJson(this.jsonContextStr,renderLimit)).concat(JSON.parse(grrUi.semantic.rekall.utils.cropRekallJson(this.compressedJsonStr,renderLimit-this.jsonContextStr.length)))}catch(err){this.error="error: "+err.message+
", in:"+this.jsonContextStr+", "+this.compressedJsonStr;return}this.state=grrUi.semantic.rekall.utils.stackRekallTables(this.parsedJson)};RekallJsonController.prototype.onScopeChange_=function(){if(angular.isDefined(this.state))return;var jsonContext=this.scope_["jsonContextMessages"];var compressedJson=this.scope_["compressedJsonMessages"];if(angular.isUndefined(jsonContext)||angular.isUndefined(compressedJson))return;this.jsonContextStr=jsonContext.value;this.compressedJsonStr=compressedJson.value;
if(!angular.isString(this.jsonContextStr)||!angular.isString(this.compressedJsonStr)){this.error="Expected strings, got "+typeof this.jsonContextStr+" and "+typeof this.compressedJsonStr+".";return}this.render_(FIRST_RENDER_LIMIT)};grrUi.semantic.rekall.rekallJsonDirective.RekallJsonDirective=function(){return{scope:{jsonContextMessages:"=",compressedJsonMessages:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/rekall/rekall-json.html",controller:RekallJsonController,controllerAs:"controller"}};
grrUi.semantic.rekall.rekallJsonDirective.RekallJsonDirective.directive_name="grrRekallJson"});goog.provide("grrUi.semantic.rekall.rekallRegistry.RekallRegistryService");
goog.scope(function(){grrUi.semantic.rekall.rekallRegistry.RekallRegistryService=function(){this.directivesByType_={}};var RekallRegistryService=grrUi.semantic.rekall.rekallRegistry.RekallRegistryService;RekallRegistryService.service_name="grrRekallDirectivesRegistryService";RekallRegistryService.prototype.registerDirective=function(type,directive){this.directivesByType_[type]=directive};RekallRegistryService.prototype.findDirectiveForMro=function(mro){if(angular.isUndefined(mro))return undefined;
var splittedMro=mro.split(":");for(var i=0;i<splittedMro.length;++i){var objType=splittedMro[i];var directive=this.directivesByType_[objType];if(angular.isDefined(directive))return directive}return undefined}});goog.provide("grrUi.semantic.rekall.rekallValueDirective.RekallValueController");goog.provide("grrUi.semantic.rekall.rekallValueDirective.RekallValueDirective");goog.require("grrUi.core.utils.camelCaseToDashDelimited");
goog.scope(function(){grrUi.semantic.rekall.rekallValueDirective.RekallValueController=function($scope,$element,$compile,grrRekallDirectivesRegistryService){this.scope_=$scope;this.element_=$element;this.compile_=$compile;this.grrRekallDirectivesRegistryService_=grrRekallDirectivesRegistryService;this.scope_.$watch("::value",this.onValueChange_.bind(this))};var RekallValueController=grrUi.semantic.rekall.rekallValueDirective.RekallValueController;RekallValueController.prototype.onValueChange_=function(value){if(value===
null||angular.isUndefined(value))return;if(!angular.isObject(value)){this.element_.text(value.toString());return}var directive=this.grrRekallDirectivesRegistryService_.findDirectiveForMro(value["mro"]);var tag="grr-rekall-default-value";if(angular.isDefined(directive))tag=grrUi.core.utils.camelCaseToDashDelimited(directive.directive_name);this.element_.html("<"+tag+' value="::value"></'+tag+">");this.compile_(this.element_.contents())(this.scope_)};grrUi.semantic.rekall.rekallValueDirective.RekallValueDirective=
function(){return{scope:{value:"="},restrict:"E",controller:RekallValueController,controllerAs:"controller"}};grrUi.semantic.rekall.rekallValueDirective.RekallValueDirective.directive_name="grrRekallValue"});goog.provide("grrUi.semantic.rekall.tableDirective.TableDirective");goog.scope(function(){grrUi.semantic.rekall.tableDirective.TableDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/rekall/table.html"}};grrUi.semantic.rekall.tableDirective.TableDirective.directive_name="grrRekallTable"});goog.provide("grrUi.semantic.rekall.module");goog.require("grrUi.core.module");goog.require("grrUi.semantic.rekall.logDirective.LogDirective");goog.require("grrUi.semantic.rekall.metadataDirective.MetadataDirective");goog.require("grrUi.semantic.rekall.registeredUnixTimeStampDirective.RegisteredUnixTimeStampDirective");goog.require("grrUi.semantic.rekall.rekallDefaultValueDirective.RekallDefaultValueDirective");goog.require("grrUi.semantic.rekall.rekallJsonDirective.RekallJsonDirective");goog.require("grrUi.semantic.rekall.rekallRegistry.RekallRegistryService");
goog.require("grrUi.semantic.rekall.rekallValueDirective.RekallValueDirective");goog.require("grrUi.semantic.rekall.tableDirective.TableDirective");grrUi.semantic.rekall.module=angular.module("grrUi.semantic.rekall",[grrUi.core.module.name,"ui.bootstrap"]);grrUi.semantic.rekall.module.directive(grrUi.semantic.rekall.logDirective.LogDirective.directive_name,grrUi.semantic.rekall.logDirective.LogDirective);
grrUi.semantic.rekall.module.directive(grrUi.semantic.rekall.metadataDirective.MetadataDirective.directive_name,grrUi.semantic.rekall.metadataDirective.MetadataDirective);grrUi.semantic.rekall.module.directive(grrUi.semantic.rekall.registeredUnixTimeStampDirective.RegisteredUnixTimeStampDirective.directive_name,grrUi.semantic.rekall.registeredUnixTimeStampDirective.RegisteredUnixTimeStampDirective);
grrUi.semantic.rekall.module.directive(grrUi.semantic.rekall.rekallDefaultValueDirective.RekallDefaultValueDirective.directive_name,grrUi.semantic.rekall.rekallDefaultValueDirective.RekallDefaultValueDirective);grrUi.semantic.rekall.module.directive(grrUi.semantic.rekall.rekallJsonDirective.RekallJsonDirective.directive_name,grrUi.semantic.rekall.rekallJsonDirective.RekallJsonDirective);
grrUi.semantic.rekall.module.directive(grrUi.semantic.rekall.rekallValueDirective.RekallValueDirective.directive_name,grrUi.semantic.rekall.rekallValueDirective.RekallValueDirective);grrUi.semantic.rekall.module.directive(grrUi.semantic.rekall.tableDirective.TableDirective.directive_name,grrUi.semantic.rekall.tableDirective.TableDirective);grrUi.semantic.rekall.module.service(grrUi.semantic.rekall.rekallRegistry.RekallRegistryService.service_name,grrUi.semantic.rekall.rekallRegistry.RekallRegistryService);
grrUi.semantic.rekall.module.run(function(grrRekallDirectivesRegistryService){var registry=grrRekallDirectivesRegistryService;registry.registerDirective(grrUi.semantic.rekall.registeredUnixTimeStampDirective.RegisteredUnixTimeStampDirective.rekall_type,grrUi.semantic.rekall.registeredUnixTimeStampDirective.RegisteredUnixTimeStampDirective)});goog.provide("grrUi.semantic.rekallResponseDirective.RekallResponseController");goog.provide("grrUi.semantic.rekallResponseDirective.RekallResponseDirective");
goog.scope(function(){grrUi.semantic.rekallResponseDirective.RekallResponseDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/rekall-response.html"}};grrUi.semantic.rekallResponseDirective.RekallResponseDirective.directive_name="grrRekallResponse";grrUi.semantic.rekallResponseDirective.RekallResponseDirective.semantic_type="RekallResponse"});goog.provide("grrUi.semantic.semanticProtoDirective.SemanticProtoController");goog.provide("grrUi.semantic.semanticProtoDirective.SemanticProtoDirective");goog.provide("grrUi.semantic.semanticProtoDirective.buildItems");goog.provide("grrUi.semantic.semanticProtoDirective.buildNonUnionItems");goog.provide("grrUi.semantic.semanticProtoDirective.buildUnionItems");goog.provide("grrUi.semantic.semanticProtoDirective.getUnionFieldValue");
goog.scope(function(){grrUi.semantic.semanticProtoDirective.getUnionFieldValue=function(value,descriptor){var unionFieldName=descriptor["union_field"];if(angular.isUndefined(unionFieldName))throw new Error("Not a union-type structure.");if(angular.isDefined(value["value"][unionFieldName]))return value["value"][unionFieldName]["value"].toLowerCase();else{var fieldsLength=descriptor["fields"].length;for(var i=0;i<fieldsLength;++i){var field=descriptor["fields"][i];if(field["name"]==unionFieldName)return field["default"]["value"].toLowerCase()}}throw new Error("Can't determine value of the union field.");
};var getUnionFieldValue=grrUi.semantic.semanticProtoDirective.getUnionFieldValue;grrUi.semantic.semanticProtoDirective.buildUnionItems=function(value,descriptor){var items=[];var unionFieldName=descriptor["union_field"];var unionFieldValue=getUnionFieldValue(value,descriptor);var fieldsLength=descriptor["fields"].length;for(var i=0;i<fieldsLength;++i){var field=descriptor["fields"][i];var key=field["name"];if(key!==unionFieldName&&key!==unionFieldValue)continue;var keyValue=value.value[key];if(angular.isUndefined(keyValue))keyValue=
field["default"];items.push({"value":keyValue,"key":field["friendly_name"]||field["name"],"desc":field["doc"]})}return items};var buildUnionItems=grrUi.semantic.semanticProtoDirective.buildUnionItems;grrUi.semantic.semanticProtoDirective.buildNonUnionItems=function(value,descriptor,opt_visibleFields,opt_hiddenFields){if(angular.isUndefined(descriptor["fields"]))return[];var items=[];var fieldsLength=descriptor["fields"].length;for(var i=0;i<fieldsLength;++i){var field=descriptor["fields"][i];var key=
field["name"];var keyValue=value.value[key];if(opt_visibleFields&&opt_visibleFields.indexOf(key)==-1)continue;if(opt_hiddenFields&&opt_hiddenFields.indexOf(key)!=-1)continue;if(angular.isUndefined(keyValue))if(!opt_visibleFields)continue;else keyValue=angular.copy(field["default"]);items.push({"value":keyValue,"key":field["friendly_name"]||field["name"],"structKey":field["name"],"desc":field["doc"],"fieldDescriptor":field})}return items};var buildNonUnionItems=grrUi.semantic.semanticProtoDirective.buildNonUnionItems;
grrUi.semantic.semanticProtoDirective.buildItems=function(value,descriptor,opt_visibleFields,opt_hiddenFields){if(angular.isDefined(descriptor["union_field"]))return buildUnionItems(value,descriptor);else return buildNonUnionItems(value,descriptor,opt_visibleFields,opt_hiddenFields)};var buildItems=grrUi.semantic.semanticProtoDirective.buildItems;var SemanticProtoController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.items;this.scope_.$watch("::value",
this.onValueChange.bind(this))};SemanticProtoController.prototype.onValueChange=function(newValue,oldValue){if(newValue===undefined&&oldValue===undefined)return;if(angular.isObject(this.scope_["value"])){var valueType=this.scope_["value"]["type"];this.grrReflectionService_.getRDFValueDescriptor(valueType).then(function success(descriptor){this.items=buildItems(this.scope_["value"],descriptor,this.scope_["visibleFields"],this.scope_["hiddenFields"])}.bind(this))}else this.items=[]};grrUi.semantic.semanticProtoDirective.SemanticProtoDirective=
function(){return{scope:{value:"=",visibleFields:"=",hiddenFields:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/semantic-proto.html",controller:SemanticProtoController,controllerAs:"controller"}};grrUi.semantic.semanticProtoDirective.SemanticProtoDirective.directive_name="grrSemanticProto";grrUi.semantic.semanticProtoDirective.SemanticProtoDirective.semantic_type="RDFProtoStruct"});goog.provide("grrUi.semantic.semanticDiffAnnotatedProtoDirective.SemanticDiffAnnotatedProtoController");goog.provide("grrUi.semantic.semanticDiffAnnotatedProtoDirective.SemanticDiffAnnotatedProtoDirective");goog.require("grrUi.semantic.semanticProtoDirective.buildItems");
goog.scope(function(){var buildItems=grrUi.semantic.semanticProtoDirective.buildItems;var SemanticDiffAnnotatedProtoController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.items;this.scope_.$watch("::value",this.onValueChange_.bind(this))};SemanticDiffAnnotatedProtoController.prototype.onValueChange_=function(newValue,oldValue){if(newValue===undefined&&oldValue===undefined)return;if(angular.isObject(this.scope_["value"]))this.grrReflectionService_.getRDFValueDescriptor(this.scope_["value"]["type"]).then(function success(descriptor){this.items=
buildItems(this.scope_["value"],descriptor,this.scope_["visibleFields"],this.scope_["hiddenFields"]);angular.forEach(this.items,function(item){item["isList"]=angular.isArray(item["value"])}.bind(this))}.bind(this));else this.items=[]};grrUi.semantic.semanticDiffAnnotatedProtoDirective.SemanticDiffAnnotatedProtoDirective=function(){return{scope:{value:"=",visibleFields:"=",hiddenFields:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/"+"semantic-diff-annotated-proto.html",controller:SemanticDiffAnnotatedProtoController,
controllerAs:"controller"}};grrUi.semantic.semanticDiffAnnotatedProtoDirective.SemanticDiffAnnotatedProtoDirective.directive_name="grrSemanticDiffAnnotatedProto"});goog.provide("grrUi.semantic.semanticProtosDiffDirective.SemanticProtosDiffController");goog.provide("grrUi.semantic.semanticProtosDiffDirective.SemanticProtosDiffDirective");goog.provide("grrUi.semantic.semanticProtosDiffDirective.diffAnnotate");goog.require("grrUi.semantic.semanticDiffAnnotatedProtoDirective.SemanticDiffAnnotatedProtoDirective");goog.require("grrUi.semantic.semanticProtoDirective.SemanticProtoDirective");
goog.scope(function(){var diffAnnotateArrays=function(originalValue,newValue){angular.forEach(originalValue,function(originalItem){var found=false;angular.forEach(newValue,function(newItem){if(angular.equals(originalItem,newItem))found=true});if(!found)originalItem["_diff"]="removed"});angular.forEach(newValue,function(newItem){var found=false;angular.forEach(originalValue,function(originalItem){if(angular.equals(originalItem,newItem))found=true});if(!found)newItem["_diff"]="added"})};grrUi.semantic.semanticProtosDiffDirective.diffAnnotate=
function(originalValue,newValue){if(angular.isUndefined(originalValue)&&angular.isUndefined(newValue))return;if(angular.isUndefined(originalValue)){newValue["_diff"]="added";return}if(angular.isUndefined(newValue)){originalValue["_diff"]="removed";return}if(angular.isArray(originalValue)&&!angular.isArray(newValue)||!angular.isArray(originalValue)&&angular.isArray(newValue)){originalValue["_diff"]=newValue["_diff"]="changed";return}if(angular.isArray(originalValue)&&angular.isArray(newValue)){diffAnnotateArrays(originalValue,
newValue);return}if(originalValue["type"]!=newValue["type"]){originalValue["_diff"]=newValue["_diff"]="changed";return}if(angular.isString(originalValue["value"])||angular.isNumber(originalValue["value"])){if(!angular.equals(originalValue["value"],newValue["value"]))originalValue["_diff"]=newValue["_diff"]="changed";return}var allKeys=angular.extend({},originalValue["value"],newValue["value"]);for(var key in allKeys)diffAnnotate(originalValue["value"][key],newValue["value"][key])};var diffAnnotate=
grrUi.semantic.semanticProtosDiffDirective.diffAnnotate;grrUi.semantic.semanticProtosDiffDirective.SemanticProtosDiffController=function($scope){this.scope_=$scope;this.annotatedOriginalValue;this.annotatedNewValue;var protoType=grrUi.semantic.semanticProtoDirective.SemanticProtoDirective.semantic_type;var protoDirectiveOverride=grrUi.semantic.semanticDiffAnnotatedProtoDirective.SemanticDiffAnnotatedProtoDirective;this.overrideMap={};this.overrideMap[protoType]=protoDirectiveOverride;this.scope_.$watchGroup(["originalValue",
"newValue"],this.onValuesChange_.bind(this))};var SemanticProtosDiffController=grrUi.semantic.semanticProtosDiffDirective.SemanticProtosDiffController;SemanticProtosDiffController.prototype.onValuesChange_=function(){if(angular.isUndefined(this.scope_["originalValue"])||angular.isUndefined(this.scope_["newValue"]))return;this.annotatedOriginalValue=angular.copy(this.scope_["originalValue"]);this.annotatedNewValue=angular.copy(this.scope_["newValue"]);diffAnnotate(this.annotatedOriginalValue,this.annotatedNewValue)};
grrUi.semantic.semanticProtosDiffDirective.SemanticProtosDiffDirective=function(){return{scope:{originalValue:"=",newValue:"=",visibleFields:"=",hiddenFields:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/"+"semantic-protos-diff.html",controller:SemanticProtosDiffController,controllerAs:"controller"}};grrUi.semantic.semanticProtosDiffDirective.SemanticProtosDiffDirective.directive_name="grrSemanticProtosDiff"});goog.provide("grrUi.semantic.semanticValueDirective");goog.provide("grrUi.semantic.semanticValueDirective.RegistryOverrideController");goog.provide("grrUi.semantic.semanticValueDirective.RegistryOverrideDirective");goog.provide("grrUi.semantic.semanticValueDirective.SemanticValueController");goog.provide("grrUi.semantic.semanticValueDirective.SemanticValueDirective");goog.provide("grrUi.semantic.semanticValueDirective.clearCaches");
goog.scope(function(){grrUi.semantic.semanticValueDirective.singleValueTemplateCache={};grrUi.semantic.semanticValueDirective.repeatedValuesTemplate;grrUi.semantic.semanticValueDirective.clearCaches=function(){grrUi.semantic.semanticValueDirective.singleValueTemplateCache={};grrUi.semantic.semanticValueDirective.repeatedValuesTemplate=undefined};grrUi.semantic.semanticValueDirective.RegistryOverrideController=function($scope){this.scope_=$scope;this.map;this.overrideKey;this.scope_.$watch(function(){return this.map}.bind(this),
this.onMapChange_.bind(this))};var RegistryOverrideController=grrUi.semantic.semanticValueDirective.RegistryOverrideController;RegistryOverrideController.prototype.onMapChange_=function(newValue){this.overrideKey="";angular.forEach(Object.keys(this.map).sort(),function(key){var value=this.map[key];this.overrideKey+=":"+key+"_"+value["directive_name"]}.bind(this))};grrUi.semantic.semanticValueDirective.RegistryOverrideDirective=function(){return{scope:{map:"="},controller:RegistryOverrideController,
bindToController:true,restrict:"E",transclude:true,template:"<ng-transclude></ng-transclude>"}};grrUi.semantic.semanticValueDirective.RegistryOverrideDirective.directive_name="grrSemanticValueRegistryOverride";grrUi.semantic.semanticValueDirective.SemanticValueController=function($scope,$compile,$element,grrSemanticValueDirectivesRegistryService){this.scope_=$scope;this.scope_.value;this.compile_=$compile;this.element_=$element;this.grrSemanticValueDirectivesRegistryService_=grrSemanticValueDirectivesRegistryService;
this.registryOverrideController;this.scope_.$watch("::value",this.onValueChange.bind(this))};var SemanticValueController=grrUi.semantic.semanticValueDirective.SemanticValueController;SemanticValueController.prototype.camelCaseToDashDelimited=function(directiveName){return directiveName.replace(/\W+/g,"-").replace(/([a-z\d])([A-Z])/g,"$1-$2").toLowerCase()};SemanticValueController.prototype.compileSingleTypedValueTemplate_=function(value){var successHandler=function(directive){var element=angular.element("<span />");
element.html("<"+this.camelCaseToDashDelimited(directive.directive_name)+' value="::value" />');return this.compile_(element)}.bind(this);var failureHandler=function(directive){var element=angular.element("<span />");element.html("{$ ::value.value $}");return this.compile_(element)}.bind(this);var overrides;if(this.registryOverrideController)overrides=this.registryOverrideController.map;return this.grrSemanticValueDirectivesRegistryService_.findDirectiveForType(value["type"],overrides).then(successHandler,
failureHandler)};SemanticValueController.prototype.compileRepeatedValueTemplate_=function(){var element=angular.element('<div ng-repeat="item in ::repeatedValue || []">'+'<grr-semantic-value value="::item" /></div>');return this.compile_(element)};SemanticValueController.prototype.onValueChange=function(){var value=this.scope_.value;if(value==null)return;var template;if(angular.isDefined(value["type"])){var handleTemplate=function(template){template(this.scope_,function(cloned,opt_scope){this.element_.html("");
this.element_.append(cloned)}.bind(this))}.bind(this);var singleValueTemplateCache=grrUi.semantic.semanticValueDirective.singleValueTemplateCache;var cacheKey=value["type"];if(this.registryOverrideController)cacheKey+=this.registryOverrideController.overrideKey;template=singleValueTemplateCache[cacheKey];if(angular.isUndefined(template))this.compileSingleTypedValueTemplate_(value).then(function(tmpl){singleValueTemplateCache[cacheKey]=tmpl;handleTemplate(tmpl)}.bind(this));else handleTemplate(template)}else if(angular.isArray(value)){if(value.length>
10){var continuation=value.slice(10);this.scope_.repeatedValue=value.slice(0,10);this.scope_.repeatedValue.push({type:"__FetchMoreLink",value:continuation})}else this.scope_.repeatedValue=value;if(angular.isUndefined(grrUi.semantic.semanticValueDirective.repeatedValuesTemplate))grrUi.semantic.semanticValueDirective.repeatedValuesTemplate=this.compileRepeatedValueTemplate_();template=grrUi.semantic.semanticValueDirective.repeatedValuesTemplate;template(this.scope_,function(cloned,opt_scope){this.element_.html("");
this.element_.append(cloned)}.bind(this))}else this.element_.text(value.toString()+" ")};grrUi.semantic.semanticValueDirective.SemanticValueDirective=function(){return{scope:{value:"="},require:"?^grrSemanticValueRegistryOverride",restrict:"E",controller:SemanticValueController,controllerAs:"controller",link:function(scope,element,attrs,grrSemanticValueRegistryOverrideCtrl){if(grrSemanticValueRegistryOverrideCtrl)scope["controller"]["registryOverrideController"]=grrSemanticValueRegistryOverrideCtrl}}};
grrUi.semantic.semanticValueDirective.SemanticValueDirective.directive_name="grrSemanticValue"});goog.provide("grrUi.semantic.semanticVersionedProtoDirective.SemanticVersionedProtoController");goog.provide("grrUi.semantic.semanticVersionedProtoDirective.SemanticVersionedProtoDirective");goog.require("grrUi.semantic.semanticProtoDirective.buildNonUnionItems");
goog.scope(function(){var SemanticVersionedProtoController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.items;this.scope_.$watch("::value",this.onValueChange_.bind(this))};SemanticVersionedProtoController.prototype.processItems_=function(items,descriptors){angular.forEach(items,function(item){var itemType=item["fieldDescriptor"]["type"];item["recursiveItem"]=this.scope_["historyDepth"]>1&&descriptors[itemType]["kind"]==="struct"&&!item["fieldDescriptor"]["repeated"]&&
!item["fieldDescriptor"]["dynamic"];if(!this.scope_["historyPath"])item["historyPath"]=item["structKey"];else item["historyPath"]=this.scope_["historyPath"]+"."+item["structKey"]}.bind(this));return items};SemanticVersionedProtoController.prototype.onValueChange_=function(newValue,oldValue){if(newValue===undefined&&oldValue===undefined)return;if(angular.isObject(this.scope_["value"])){var valueType=this.scope_["value"]["type"];this.grrReflectionService_.getRDFValueDescriptor(valueType,true).then(function success(descriptors){var items=
grrUi.semantic.semanticProtoDirective.buildNonUnionItems(this.scope_["value"],descriptors[valueType]);this.items=this.processItems_(items,descriptors)}.bind(this))}else this.items=[]};grrUi.semantic.semanticVersionedProtoDirective.SemanticVersionedProtoDirective=function(){return{scope:{value:"=",onFieldClick:"&",historyDepth:"=",historyPath:"=?"},restrict:"E",templateUrl:"/static/angular-components/semantic/semantic-versioned-proto.html",controller:SemanticVersionedProtoController,controllerAs:"controller"}};
grrUi.semantic.semanticVersionedProtoDirective.SemanticVersionedProtoDirective.directive_name="grrSemanticVersionedProto"});goog.provide("grrUi.semantic.statEntryDirective.StatEntryController");goog.provide("grrUi.semantic.statEntryDirective.StatEntryDirective");goog.require("grrUi.core.fileDownloadUtils.pathSpecToAff4Path");goog.require("grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective");
goog.scope(function(){var ERROR_EVENT_NAME=grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective.error_event_name;var pathSpecToAff4Path=grrUi.core.fileDownloadUtils.pathSpecToAff4Path;grrUi.semantic.statEntryDirective.StatEntryController=function($rootScope,$scope,grrApiService){this.rootScope_=$rootScope;this.scope_=$scope;this.grrApiService_=grrApiService;this.clientId;this.aff4Path;this.statEntry;this.downloadUrl;this.downloadParams;this.scope_.$watch("::value",this.onValueChange_.bind(this))};
var StatEntryController=grrUi.semantic.statEntryDirective.StatEntryController;StatEntryController.prototype.onValueChange_=function(newValue){if(angular.isUndefined(newValue))return;if(newValue["type"]=="__DownloadableStatEntry"){this.statEntry=newValue["originalValue"];this.downloadUrl=newValue["downloadUrl"];this.downloadParams=newValue["downloadParams"]}else this.statEntry=newValue;if(this.clientId&&angular.isDefined(this.statEntry["value"]["pathspec"]))this.aff4Path={type:"RDFURN",value:pathSpecToAff4Path(this.statEntry["value"]["pathspec"],
this.clientId)};else this.aff4Path={type:"RDFString",value:"<unknown>"}};StatEntryController.prototype.onDownloadClick=function(){this.grrApiService_.downloadFile(this.downloadUrl,this.downloadParams).then(function success(){}.bind(this),function failure(response){if(response.status!==500)this.rootScope_.$broadcast(ERROR_EVENT_NAME,{message:"Couldn't download the file. Most likely "+"it was just referenced and not downloaded from the "+"client."})}.bind(this))};grrUi.semantic.statEntryDirective.StatEntryDirective=
function(){return{scope:{value:"="},require:"?^grrClientContext",restrict:"E",templateUrl:"/static/angular-components/semantic/stat-entry.html",controller:StatEntryController,controllerAs:"controller",link:function(scope,element,attrs,grrClientContextCtrl){if(grrClientContextCtrl)scope["controller"].clientId=grrClientContextCtrl.clientId}}};grrUi.semantic.statEntryDirective.StatEntryDirective.directive_name="grrStatEntry";grrUi.semantic.statEntryDirective.StatEntryDirective.semantic_types=["StatEntry",
"__DownloadableStatEntry"]});goog.provide("grrUi.semantic.statModeDirective.StatModeController");goog.provide("grrUi.semantic.statModeDirective.StatModeDirective");
goog.scope(function(){var S_IFMT=61440;var S_IFIFO=4096;var S_IFCHR=8192;var S_IFDIR=16384;var S_IFBLK=24576;var S_IFREG=32768;var S_IFLNK=40960;var S_IFSOCK=49152;var S_IFWHT=57344;var S_IMODE=4095;var S_ISUID=2048;var S_ISGID=1024;var S_ISVTX=512;var S_IRUSR=256;var S_IWUSR=128;var S_IXUSR=64;var S_IRGRP=32;var S_IWGRP=16;var S_IXGRP=8;var S_IROTH=4;var S_IWOTH=2;var S_IXOTH=1;grrUi.semantic.statModeDirective.StatModeController=function($scope){this.scope_=$scope;this.scope_.value;this.statMode;
this.octalStatMode;this.scope_.$watch("::value",this.onValueChange.bind(this))};var StatModeController=grrUi.semantic.statModeDirective.StatModeController;StatModeController.prototype.onValueChange=function(newValue){if(!newValue||!angular.isNumber(newValue.value)){this.octalStatMode="-";this.statMode="-"}else{var statMode=newValue.value;this.octalStatMode=this.calculateOctalMode_(statMode);this.statMode=this.calculateModeString_(statMode)}};StatModeController.prototype.calculateOctalMode_=function(statMode){return this.getMode_(statMode).toString(8)};
StatModeController.prototype.calculateModeString_=function(statMode){var fileType="-";if(this.isRegularFile_(statMode))fileType="-";else if(this.isBlockDevice_(statMode))fileType="b";else if(this.isCharacterDevice_(statMode))fileType="c";else if(this.isDirectory_(statMode))fileType="d";else if(this.isFifo_(statMode))fileType="p";else if(this.isLink_(statMode))fileType="l";else if(this.isSocket_(statMode))fileType="s";var permissions="";permissions+=statMode&S_IRUSR?"r":"-";permissions+=statMode&S_IWUSR?
"w":"-";if(statMode&S_ISUID)permissions+=statMode&S_IXUSR?"s":"S";else permissions+=statMode&S_IXUSR?"x":"-";permissions+=statMode&S_IRGRP?"r":"-";permissions+=statMode&S_IWGRP?"w":"-";if(statMode&S_ISGID)permissions+=statMode&S_IXGRP?"s":"S";else permissions+=statMode&S_IXGRP?"x":"-";permissions+=statMode&S_IROTH?"r":"-";permissions+=statMode&S_IWOTH?"w":"-";if(statMode&S_ISVTX)permissions+=statMode&S_IXOTH?"t":"T";else permissions+=statMode&S_IXOTH?"x":"-";return fileType+permissions};StatModeController.prototype.getMode_=
function(mode){return mode&S_IMODE};StatModeController.prototype.getType_=function(mode){return mode&S_IFMT};StatModeController.prototype.isDirectory_=function(mode){return this.getType_(mode)===S_IFDIR};StatModeController.prototype.isCharacterDevice_=function(mode){return this.getType_(mode)===S_IFCHR};StatModeController.prototype.isBlockDevice_=function(mode){return this.getType_(mode)===S_IFBLK};StatModeController.prototype.isRegularFile_=function(mode){return this.getType_(mode)===S_IFREG};StatModeController.prototype.isFifo_=
function(mode){return this.getType_(mode)===S_IFIFO};StatModeController.prototype.isLink_=function(mode){return this.getType_(mode)===S_IFLNK};StatModeController.prototype.isSocket_=function(mode){return this.getType_(mode)===S_IFSOCK};grrUi.semantic.statModeDirective.StatModeDirective=function($filter){return{scope:{value:"="},restrict:"E",template:'<abbr title="Mode {$ ::controller.octalStatMode $}">'+"  {$ ::controller.statMode $}"+"</abbr>",controller:StatModeController,controllerAs:"controller"}};
grrUi.semantic.statModeDirective.StatModeDirective.directive_name="grrStatMode";grrUi.semantic.statModeDirective.StatModeDirective.semantic_type="StatMode"});goog.provide("grrUi.semantic.timestampDirective.TimestampController");goog.provide("grrUi.semantic.timestampDirective.TimestampDirective");
goog.scope(function(){grrUi.semantic.timestampDirective.TimestampController=function($scope,$element,grrTimeService){this.scope_=$scope;this.scope_.value;this.formattedTimestamp;this.formattedTimestampComponents;this.value;this.element_=$element;this.timeService_=grrTimeService;this.scope_.$watch("::value",this.onValueChange.bind(this))};var TimestampController=grrUi.semantic.timestampDirective.TimestampController;TimestampController.prototype.onValueChange=function(newValue){if(angular.isDefined(newValue))if(newValue===
null||newValue===0)this.formattedTimestamp="-";else{var timestamp;if(angular.isObject(newValue))timestamp=newValue.value/1E3;else timestamp=newValue/1E3;this.value=timestamp;this.formattedTimestamp=this.timeService_.formatAsUTC(timestamp);this.formattedTimestampComponents=this.formattedTimestamp.split(" ")}};TimestampController.prototype.onMouseEnter=function(){var span=$(this.element_).find("span")[0];if(angular.isDefined(this.value))span.title=this.timeService_.getFormattedDiffFromCurrentTime(Number(this.value))};
grrUi.semantic.timestampDirective.TimestampDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/timestamp.html",controller:TimestampController,controllerAs:"controller"}};grrUi.semantic.timestampDirective.TimestampDirective.directive_name="grrTimestamp";grrUi.semantic.timestampDirective.TimestampDirective.semantic_type="RDFDatetime"});goog.provide("grrUi.semantic.timestampSecondsDirective.TimestampSecondsController");goog.provide("grrUi.semantic.timestampSecondsDirective.TimestampSecondsDirective");
goog.scope(function(){grrUi.semantic.timestampSecondsDirective.TimestampSecondsController=function($scope){this.scope_=$scope;this.scope_.value;this.timestampValue;this.scope_.$watch("::value",this.onValueChange.bind(this))};var TimestampSecondsController=grrUi.semantic.timestampSecondsDirective.TimestampSecondsController;TimestampSecondsController.prototype.onValueChange=function(newValue){if(angular.isDefined(newValue)){var timestamp;if(angular.isObject(newValue))timestamp=newValue.value;else timestamp=
newValue;this.timestampValue=timestamp*1E6}};grrUi.semantic.timestampSecondsDirective.TimestampSecondsDirective=function(){return{scope:{value:"="},restrict:"E",template:'<grr-timestamp value="::controller.timestampValue"></grr-timestamp>',controller:TimestampSecondsController,controllerAs:"controller"}};grrUi.semantic.timestampSecondsDirective.TimestampSecondsDirective.directive_name="grrTimestampSeconds";grrUi.semantic.timestampSecondsDirective.TimestampSecondsDirective.semantic_type="RDFDatetimeSeconds"});goog.provide("grrUi.semantic.urnDirective.UrnController");goog.provide("grrUi.semantic.urnDirective.UrnDirective");goog.require("grrUi.routing.aff4UrnToUrl");
goog.scope(function(){grrUi.semantic.urnDirective.UrnController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.plainValue;this.ref;this.refState;this.refParams;this.scope_.$watch("::value",this.onValueChange_.bind(this))};var UrnController=grrUi.semantic.urnDirective.UrnController;UrnController.prototype.onValueChange_=function(newValue){if(angular.isObject(newValue))this.plainValue=newValue.value;else if(angular.isString(newValue))this.plainValue=
newValue;else return;var urlResult=grrUi.routing.aff4UrnToUrl(this.plainValue);if(urlResult){this.refState=urlResult.state;this.refParams=urlResult.params;this.ref=this.grrRoutingService_.href(urlResult.state,urlResult.params)}};UrnController.prototype.onClick=function(){this.grrRoutingService_.go("client.vfs",this.refParams)};grrUi.semantic.urnDirective.UrnDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/urn.html",controller:UrnController,
controllerAs:"controller"}};grrUi.semantic.urnDirective.UrnDirective.directive_name="grrUrn";grrUi.semantic.urnDirective.UrnDirective.semantic_type="RDFURN"});goog.provide("grrUi.semantic.module");goog.require("grrUi.core.module");goog.require("grrUi.core.semanticRegistry.SemanticRegistryService");goog.require("grrUi.routing.module");goog.require("grrUi.semantic.apiHuntResultDirective.ApiHuntResultDirective");goog.require("grrUi.semantic.byteSizeDirective.ByteSizeDirective");goog.require("grrUi.semantic.bytesDirective.BytesDirective");goog.require("grrUi.semantic.clientUrnDirective.ClientUrnDirective");goog.require("grrUi.semantic.dataObjectDirective.DataObjectDirective");
goog.require("grrUi.semantic.dictDirective.DictDirective");goog.require("grrUi.semantic.durationDirective.DurationDirective");goog.require("grrUi.semantic.encryptionKeyDirective.EncryptionKeyDirective");goog.require("grrUi.semantic.flowIdDirective.FlowIdDirective");goog.require("grrUi.semantic.hashDigestDirective.HashDigestDirective");goog.require("grrUi.semantic.hashListDirective.HashListDirective");goog.require("grrUi.semantic.huntIdDirective.HuntIdDirective");goog.require("grrUi.semantic.jsonDirective.JsonDirective");
goog.require("grrUi.semantic.macAddressDirective.MacAddressDirective");goog.require("grrUi.semantic.networkAddressDirective.NetworkAddressDirective");goog.require("grrUi.semantic.objectLabelDirective.ObjectLabelDirective");goog.require("grrUi.semantic.objectLabelsListDirective.ObjectLabelsListDirective");goog.require("grrUi.semantic.primitiveDirective.PrimitiveDirective");goog.require("grrUi.semantic.pseudo.module");goog.require("grrUi.semantic.rekall.module");goog.require("grrUi.semantic.rekallResponseDirective.RekallResponseDirective");
goog.require("grrUi.semantic.semanticDiffAnnotatedProtoDirective.SemanticDiffAnnotatedProtoDirective");goog.require("grrUi.semantic.semanticProtoDirective.SemanticProtoDirective");goog.require("grrUi.semantic.semanticProtosDiffDirective.SemanticProtosDiffDirective");goog.require("grrUi.semantic.semanticValueDirective.RegistryOverrideDirective");goog.require("grrUi.semantic.semanticValueDirective.SemanticValueDirective");goog.require("grrUi.semantic.semanticVersionedProtoDirective.SemanticVersionedProtoDirective");
goog.require("grrUi.semantic.statEntryDirective.StatEntryDirective");goog.require("grrUi.semantic.statModeDirective.StatModeDirective");goog.require("grrUi.semantic.timestampDirective.TimestampDirective");goog.require("grrUi.semantic.timestampSecondsDirective.TimestampSecondsDirective");goog.require("grrUi.semantic.urnDirective.UrnDirective");
grrUi.semantic.module=angular.module("grrUi.semantic",[grrUi.core.module.name,grrUi.routing.module.name,grrUi.semantic.pseudo.module.name,grrUi.semantic.rekall.module.name,"ui.bootstrap"]);grrUi.semantic.module.directive(grrUi.semantic.apiHuntResultDirective.ApiHuntResultDirective.directive_name,grrUi.semantic.apiHuntResultDirective.ApiHuntResultDirective);grrUi.semantic.module.directive(grrUi.semantic.byteSizeDirective.ByteSizeDirective.directive_name,grrUi.semantic.byteSizeDirective.ByteSizeDirective);
grrUi.semantic.module.directive(grrUi.semantic.bytesDirective.BytesDirective.directive_name,grrUi.semantic.bytesDirective.BytesDirective);grrUi.semantic.module.directive(grrUi.semantic.clientUrnDirective.ClientUrnDirective.directive_name,grrUi.semantic.clientUrnDirective.ClientUrnDirective);grrUi.semantic.module.directive(grrUi.semantic.dataObjectDirective.DataObjectDirective.directive_name,grrUi.semantic.dataObjectDirective.DataObjectDirective);
grrUi.semantic.module.directive(grrUi.semantic.dictDirective.DictDirective.directive_name,grrUi.semantic.dictDirective.DictDirective);grrUi.semantic.module.directive(grrUi.semantic.durationDirective.DurationDirective.directive_name,grrUi.semantic.durationDirective.DurationDirective);grrUi.semantic.module.directive(grrUi.semantic.encryptionKeyDirective.EncryptionKeyDirective.directive_name,grrUi.semantic.encryptionKeyDirective.EncryptionKeyDirective);
grrUi.semantic.module.directive(grrUi.semantic.flowIdDirective.FlowIdDirective.directive_name,grrUi.semantic.flowIdDirective.FlowIdDirective);grrUi.semantic.module.directive(grrUi.semantic.hashDigestDirective.HashDigestDirective.directive_name,grrUi.semantic.hashDigestDirective.HashDigestDirective);grrUi.semantic.module.directive(grrUi.semantic.hashListDirective.HashListDirective.directive_name,grrUi.semantic.hashListDirective.HashListDirective);
grrUi.semantic.module.directive(grrUi.semantic.huntIdDirective.HuntIdDirective.directive_name,grrUi.semantic.huntIdDirective.HuntIdDirective);grrUi.semantic.module.directive(grrUi.semantic.jsonDirective.JsonDirective.directive_name,grrUi.semantic.jsonDirective.JsonDirective);grrUi.semantic.module.directive(grrUi.semantic.macAddressDirective.MacAddressDirective.directive_name,grrUi.semantic.macAddressDirective.MacAddressDirective);
grrUi.semantic.module.directive(grrUi.semantic.networkAddressDirective.NetworkAddressDirective.directive_name,grrUi.semantic.networkAddressDirective.NetworkAddressDirective);grrUi.semantic.module.directive(grrUi.semantic.objectLabelDirective.ObjectLabelDirective.directive_name,grrUi.semantic.objectLabelDirective.ObjectLabelDirective);grrUi.semantic.module.directive(grrUi.semantic.objectLabelsListDirective.ObjectLabelsListDirective.directive_name,grrUi.semantic.objectLabelsListDirective.ObjectLabelsListDirective);
grrUi.semantic.module.directive(grrUi.semantic.primitiveDirective.PrimitiveDirective.directive_name,grrUi.semantic.primitiveDirective.PrimitiveDirective);grrUi.semantic.module.directive(grrUi.semantic.rekallResponseDirective.RekallResponseDirective.directive_name,grrUi.semantic.rekallResponseDirective.RekallResponseDirective);grrUi.semantic.module.directive(grrUi.semantic.semanticDiffAnnotatedProtoDirective.SemanticDiffAnnotatedProtoDirective.directive_name,grrUi.semantic.semanticDiffAnnotatedProtoDirective.SemanticDiffAnnotatedProtoDirective);
grrUi.semantic.module.directive(grrUi.semantic.semanticProtoDirective.SemanticProtoDirective.directive_name,grrUi.semantic.semanticProtoDirective.SemanticProtoDirective);grrUi.semantic.module.directive(grrUi.semantic.semanticValueDirective.RegistryOverrideDirective.directive_name,grrUi.semantic.semanticValueDirective.RegistryOverrideDirective);grrUi.semantic.module.directive(grrUi.semantic.semanticValueDirective.SemanticValueDirective.directive_name,grrUi.semantic.semanticValueDirective.SemanticValueDirective);
grrUi.semantic.module.directive(grrUi.semantic.semanticProtosDiffDirective.SemanticProtosDiffDirective.directive_name,grrUi.semantic.semanticProtosDiffDirective.SemanticProtosDiffDirective);grrUi.semantic.module.directive(grrUi.semantic.semanticVersionedProtoDirective.SemanticVersionedProtoDirective.directive_name,grrUi.semantic.semanticVersionedProtoDirective.SemanticVersionedProtoDirective);grrUi.semantic.module.directive(grrUi.semantic.statEntryDirective.StatEntryDirective.directive_name,grrUi.semantic.statEntryDirective.StatEntryDirective);
grrUi.semantic.module.directive(grrUi.semantic.statModeDirective.StatModeDirective.directive_name,grrUi.semantic.statModeDirective.StatModeDirective);grrUi.semantic.module.directive(grrUi.semantic.timestampDirective.TimestampDirective.directive_name,grrUi.semantic.timestampDirective.TimestampDirective);grrUi.semantic.module.directive(grrUi.semantic.timestampSecondsDirective.TimestampSecondsDirective.directive_name,grrUi.semantic.timestampSecondsDirective.TimestampSecondsDirective);
grrUi.semantic.module.directive(grrUi.semantic.urnDirective.UrnDirective.directive_name,grrUi.semantic.urnDirective.UrnDirective);grrUi.semantic.module.service(grrUi.core.semanticRegistry.SemanticRegistryService.values_service_name,grrUi.core.semanticRegistry.SemanticRegistryService);
grrUi.semantic.module.run(function(grrSemanticValueDirectivesRegistryService){var registry=grrSemanticValueDirectivesRegistryService;registry.registerDirective(grrUi.semantic.apiHuntResultDirective.ApiHuntResultDirective.semantic_type,grrUi.semantic.apiHuntResultDirective.ApiHuntResultDirective);registry.registerDirective(grrUi.semantic.byteSizeDirective.ByteSizeDirective.semantic_type,grrUi.semantic.byteSizeDirective.ByteSizeDirective);angular.forEach(grrUi.semantic.bytesDirective.BytesDirective.semantic_types,
function(type){registry.registerDirective(type,grrUi.semantic.bytesDirective.BytesDirective)}.bind(this));angular.forEach(grrUi.semantic.clientUrnDirective.ClientUrnDirective.semantic_types,function(type){registry.registerDirective(type,grrUi.semantic.clientUrnDirective.ClientUrnDirective)}.bind(this));registry.registerDirective(grrUi.semantic.dataObjectDirective.DataObjectDirective.semantic_type,grrUi.semantic.dataObjectDirective.DataObjectDirective);angular.forEach(grrUi.semantic.dictDirective.DictDirective.semantic_types,
function(type){registry.registerDirective(type,grrUi.semantic.dictDirective.DictDirective)}.bind(this));registry.registerDirective(grrUi.semantic.durationDirective.DurationDirective.semantic_type,grrUi.semantic.durationDirective.DurationDirective);registry.registerDirective(grrUi.semantic.encryptionKeyDirective.EncryptionKeyDirective.semantic_type,grrUi.semantic.encryptionKeyDirective.EncryptionKeyDirective);registry.registerDirective(grrUi.semantic.flowIdDirective.FlowIdDirective.semantic_type,grrUi.semantic.flowIdDirective.FlowIdDirective);
registry.registerDirective(grrUi.semantic.hashDigestDirective.HashDigestDirective.semantic_type,grrUi.semantic.hashDigestDirective.HashDigestDirective);registry.registerDirective(grrUi.semantic.hashListDirective.HashListDirective.semantic_type,grrUi.semantic.hashListDirective.HashListDirective);registry.registerDirective(grrUi.semantic.huntIdDirective.HuntIdDirective.semantic_type,grrUi.semantic.huntIdDirective.HuntIdDirective);registry.registerDirective(grrUi.semantic.jsonDirective.JsonDirective.semantic_type,
grrUi.semantic.jsonDirective.JsonDirective);registry.registerDirective(grrUi.semantic.macAddressDirective.MacAddressDirective.semantic_type,grrUi.semantic.macAddressDirective.MacAddressDirective);registry.registerDirective(grrUi.semantic.networkAddressDirective.NetworkAddressDirective.semantic_type,grrUi.semantic.networkAddressDirective.NetworkAddressDirective);registry.registerDirective(grrUi.semantic.objectLabelDirective.ObjectLabelDirective.semantic_type,grrUi.semantic.objectLabelDirective.ObjectLabelDirective);
registry.registerDirective(grrUi.semantic.objectLabelDirective.ObjectLabelDirective.semantic_type,grrUi.semantic.objectLabelDirective.ObjectLabelDirective);registry.registerDirective(grrUi.semantic.objectLabelsListDirective.ObjectLabelsListDirective.semantic_type,grrUi.semantic.objectLabelsListDirective.ObjectLabelsListDirective);angular.forEach(grrUi.semantic.primitiveDirective.PrimitiveDirective.semantic_types,function(type){registry.registerDirective(type,grrUi.semantic.primitiveDirective.PrimitiveDirective)}.bind(this));
registry.registerDirective(grrUi.semantic.rekallResponseDirective.RekallResponseDirective.semantic_type,grrUi.semantic.rekallResponseDirective.RekallResponseDirective);registry.registerDirective(grrUi.semantic.semanticProtoDirective.SemanticProtoDirective.semantic_type,grrUi.semantic.semanticProtoDirective.SemanticProtoDirective);angular.forEach(grrUi.semantic.statEntryDirective.StatEntryDirective.semantic_types,function(type){registry.registerDirective(type,grrUi.semantic.statEntryDirective.StatEntryDirective)}.bind(this));
registry.registerDirective(grrUi.semantic.statModeDirective.StatModeDirective.semantic_type,grrUi.semantic.statModeDirective.StatModeDirective);registry.registerDirective(grrUi.semantic.timestampDirective.TimestampDirective.semantic_type,grrUi.semantic.timestampDirective.TimestampDirective);registry.registerDirective(grrUi.semantic.timestampSecondsDirective.TimestampSecondsDirective.semantic_type,grrUi.semantic.timestampSecondsDirective.TimestampSecondsDirective);registry.registerDirective(grrUi.semantic.urnDirective.UrnDirective.semantic_type,
grrUi.semantic.urnDirective.UrnDirective)});goog.provide("grrUi.artifact.module");goog.require("grrUi.artifact.artifactDescriptorDirective.ArtifactDescriptorDirective");goog.require("grrUi.artifact.artifactDescriptorsService.ArtifactDescriptorsService");goog.require("grrUi.artifact.artifactDialogService.ArtifactDialogService");goog.require("grrUi.artifact.artifactManagerViewDirective.ArtifactManagerViewDirective");goog.require("grrUi.artifact.artifactNameDirective.ArtifactNameDirective");goog.require("grrUi.artifact.artifactsListFormDirective.ArtifactsListFormDirective");
goog.require("grrUi.artifact.deleteArtifactsDialogDirective.DeleteArtifactsDialogDirective");goog.require("grrUi.artifact.uploadArtifactDialogDirective.UploadArtifactDialogDirective");goog.require("grrUi.core.module");goog.require("grrUi.forms.module");goog.require("grrUi.semantic.module");grrUi.artifact.module=angular.module("grrUi.artifact",[grrUi.core.module.name,grrUi.forms.module.name,grrUi.semantic.module.name,"ui.bootstrap"]);
grrUi.artifact.module.directive(grrUi.artifact.artifactDescriptorDirective.ArtifactDescriptorDirective.directive_name,grrUi.artifact.artifactDescriptorDirective.ArtifactDescriptorDirective);grrUi.artifact.module.directive(grrUi.artifact.artifactNameDirective.ArtifactNameDirective.directive_name,grrUi.artifact.artifactNameDirective.ArtifactNameDirective);grrUi.artifact.module.directive(grrUi.artifact.artifactManagerViewDirective.ArtifactManagerViewDirective.directive_name,grrUi.artifact.artifactManagerViewDirective.ArtifactManagerViewDirective);
grrUi.artifact.module.directive(grrUi.artifact.artifactsListFormDirective.ArtifactsListFormDirective.directive_name,grrUi.artifact.artifactsListFormDirective.ArtifactsListFormDirective);grrUi.artifact.module.directive(grrUi.artifact.deleteArtifactsDialogDirective.DeleteArtifactsDialogDirective.directive_name,grrUi.artifact.deleteArtifactsDialogDirective.DeleteArtifactsDialogDirective);
grrUi.artifact.module.directive(grrUi.artifact.uploadArtifactDialogDirective.UploadArtifactDialogDirective.directive_name,grrUi.artifact.uploadArtifactDialogDirective.UploadArtifactDialogDirective);grrUi.core.module.service(grrUi.artifact.artifactDescriptorsService.ArtifactDescriptorsService.service_name,grrUi.artifact.artifactDescriptorsService.ArtifactDescriptorsService);grrUi.core.module.service(grrUi.artifact.artifactDialogService.ArtifactDialogService.service_name,grrUi.artifact.artifactDialogService.ArtifactDialogService);
grrUi.artifact.module.run(function(grrSemanticRepeatedFormDirectivesRegistryService){var registry=grrSemanticRepeatedFormDirectivesRegistryService;registry.registerDirective(grrUi.artifact.artifactsListFormDirective.ArtifactsListFormDirective.semantic_type,grrUi.artifact.artifactsListFormDirective.ArtifactsListFormDirective)});
grrUi.artifact.module.run(function(grrSemanticValueDirectivesRegistryService){var registry=grrSemanticValueDirectivesRegistryService;registry.registerDirective(grrUi.artifact.artifactDescriptorDirective.ArtifactDescriptorDirective.semantic_type,grrUi.artifact.artifactDescriptorDirective.ArtifactDescriptorDirective);registry.registerDirective(grrUi.artifact.artifactNameDirective.ArtifactNameDirective.semantic_type,grrUi.artifact.artifactNameDirective.ArtifactNameDirective)});goog.provide("grrUi.client.addClientsLabelsDialogDirective.AddClientsLabelsDialogController");goog.provide("grrUi.client.addClientsLabelsDialogDirective.AddClientsLabelsDialogDirective");
goog.scope(function(){grrUi.client.addClientsLabelsDialogDirective.AddClientsLabelsDialogController=function($scope,$q,grrApiService){this.scope_=$scope;this.q_=$q;this.grrApiService_=grrApiService;this.labelName};var AddClientsLabelsDialogController=grrUi.client.addClientsLabelsDialogDirective.AddClientsLabelsDialogController;AddClientsLabelsDialogController.prototype.proceed=function(){var clients=[];angular.forEach(this.scope_["clients"],function(clientObj){clients.push(clientObj["value"]["client_id"]["value"])});
var deferred=this.q_.defer();var url="/clients/labels/add";var params={client_ids:clients,labels:[this.labelName]};this.grrApiService_.post(url,params).then(function success(){deferred.resolve("Label was successfully added.")}.bind(this),function failure(response){deferred.reject(response.data.message)}.bind(this));return deferred.promise};grrUi.client.addClientsLabelsDialogDirective.AddClientsLabelsDialogDirective=function(){return{scope:{clients:"="},restrict:"E",templateUrl:"/static/angular-components/client/"+
"add-clients-labels-dialog.html",controller:AddClientsLabelsDialogController,controllerAs:"controller"}};grrUi.client.addClientsLabelsDialogDirective.AddClientsLabelsDialogDirective.directive_name="grrAddClientsLabelsDialog"});goog.provide("grrUi.client.checkClientAccessDirective.CheckClientAccessController");goog.provide("grrUi.client.checkClientAccessDirective.CheckClientAccessDirective");
goog.scope(function(){grrUi.client.checkClientAccessDirective.CheckClientAccessController=function($scope,$timeout,grrApiService,grrRoutingService){this.scope_=$scope;this.timeout_=$timeout;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.scope_.$watch("clientId",this.onClientIdChange_.bind(this))};var CheckClientAccessController=grrUi.client.checkClientAccessDirective.CheckClientAccessController;CheckClientAccessController.prototype.onClientIdChange_=function(clientId){if(angular.isDefined(clientId)){this.scope_["outHasAccess"]=
undefined;this.grrApiService_.head("clients/"+clientId+"/flows").then(this.onClientAccessPermitted_.bind(this),this.onClientAccessRejected_.bind(this))}};CheckClientAccessController.prototype.onClientAccessPermitted_=function(){this.scope_["outHasAccess"]=true};CheckClientAccessController.prototype.onClientAccessRejected_=function(){this.scope_["outHasAccess"]=false;if(!this.scope_["noRedirect"])this.timeout_(function(){var clientId=this.scope_["clientId"];if(angular.isDefined(clientId))this.grrRoutingService_.go("client",
{clientId:clientId})}.bind(this),1E3)};grrUi.client.checkClientAccessDirective.CheckClientAccessDirective=function(){return{scope:{noRedirect:"=",clientId:"=",outHasAccess:"=?"},transclude:true,restrict:"E",templateUrl:"/static/angular-components/client/check-client-access.html",controller:CheckClientAccessController,controllerAs:"controller"}};grrUi.client.checkClientAccessDirective.CheckClientAccessDirective.directive_name="grrCheckClientAccess"});goog.provide("grrUi.client.clientContextDirective.ClientContextController");goog.provide("grrUi.client.clientContextDirective.ClientContextDirective");
goog.scope(function(){grrUi.client.clientContextDirective.ClientContextController=function($scope){this.clientId;$scope.$watch("clientId",this.onClientIdChange_.bind(this))};var ClientContextController=grrUi.client.clientContextDirective.ClientContextController;ClientContextController.prototype.onClientIdChange_=function(clientId){this.clientId=clientId};grrUi.client.clientContextDirective.ClientContextDirective=function(){return{scope:{clientId:"="},restrict:"E",transclude:true,template:'<ng-transclude ng-if="controller.clientId"></ng-transclude>',
controller:ClientContextController,controllerAs:"controller"}};grrUi.client.clientContextDirective.ClientContextDirective.directive_name="grrClientContext"});goog.provide("grrUi.client.clientCrashesDirective.ClientCrashesController");goog.provide("grrUi.client.clientCrashesDirective.ClientCrashesDirective");
goog.scope(function(){grrUi.client.clientCrashesDirective.ClientCrashesController=function($scope,grrApiService,grrRoutingService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.clientId;this.crashes;this.grrRoutingService_.uiOnParamsChanged(this.scope_,"clientId",this.onClientIdChange_.bind(this))};var ClientCrashesController=grrUi.client.clientCrashesDirective.ClientCrashesController;ClientCrashesController.prototype.onClientIdChange_=function(clientId){this.clientId=
clientId;this.grrApiService_.get("clients/"+clientId+"/crashes").then(function(response){this.crashes=response["data"]["items"]}.bind(this))};grrUi.client.clientCrashesDirective.ClientCrashesDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/client/client-crashes.html",controller:ClientCrashesController,controllerAs:"controller"}};grrUi.client.clientCrashesDirective.ClientCrashesDirective.directive_name="grrClientCrashes"});goog.provide("grrUi.client.removeClientsLabelsDialogDirective.RemoveClientsLabelsDialogController");goog.provide("grrUi.client.removeClientsLabelsDialogDirective.RemoveClientsLabelsDialogDirective");
goog.scope(function(){grrUi.client.removeClientsLabelsDialogDirective.RemoveClientsLabelsDialogController=function($scope,$q,grrApiService){this.scope_=$scope;this.q_=$q;this.grrApiService_=grrApiService;this.availableLabels=[];this.labelName;this.scope_.$watch("clients",this.onClientsChange_.bind(this))};var RemoveClientsLabelsDialogController=grrUi.client.removeClientsLabelsDialogDirective.RemoveClientsLabelsDialogController;RemoveClientsLabelsDialogController.prototype.onClientsChange_=function(newValue){var labelsSet=
{};if(angular.isDefined(newValue))angular.forEach(newValue,function(client){if(angular.isDefined(client["value"]["labels"]))angular.forEach(client["value"]["labels"],function(label){if(label["value"]["owner"]["value"]!=="GRR")labelsSet[label["value"]["name"]["value"]]=true})}.bind(this));this.availableLabels=Object.keys(labelsSet);if(this.availableLabels.length>0)this.labelName=this.availableLabels[0]};RemoveClientsLabelsDialogController.prototype.proceed=function(){var clients=[];angular.forEach(this.scope_["clients"],
function(clientObj){clients.push(clientObj["value"]["client_id"]["value"])});var deferred=this.q_.defer();var url="/clients/labels/remove";var params={client_ids:clients,labels:[this.labelName]};this.grrApiService_.post(url,params).then(function success(){deferred.resolve("Label was successfully removed.")}.bind(this),function failure(response){deferred.reject(response.data.message)}.bind(this));return deferred.promise};grrUi.client.removeClientsLabelsDialogDirective.RemoveClientsLabelsDialogDirective=
function(){return{scope:{clients:"="},restrict:"E",templateUrl:"/static/angular-components/client/"+"remove-clients-labels-dialog.html",controller:RemoveClientsLabelsDialogController,controllerAs:"controller"}};grrUi.client.removeClientsLabelsDialogDirective.RemoveClientsLabelsDialogDirective.directive_name="grrRemoveClientsLabelsDialog"});goog.provide("grrUi.client.clientDialogService.ClientDialogService");goog.require("grrUi.client.addClientsLabelsDialogDirective.AddClientsLabelsDialogDirective");goog.require("grrUi.client.removeClientsLabelsDialogDirective.RemoveClientsLabelsDialogDirective");
goog.scope(function(){grrUi.client.clientDialogService.ClientDialogService=function(grrDialogService){this.grrDialogService_=grrDialogService};var ClientDialogService=grrUi.client.clientDialogService.ClientDialogService;ClientDialogService.service_name="grrClientDialogService";ClientDialogService.prototype.openAddClientLabels=function(clients){var directive=grrUi.client.addClientsLabelsDialogDirective.AddClientsLabelsDialogDirective;return this.grrDialogService_.openDirectiveDialog(directive.directive_name,
{clients:clients})};ClientDialogService.prototype.openRemoveClientLabels=function(clients){var directive=grrUi.client.removeClientsLabelsDialogDirective.RemoveClientsLabelsDialogDirective;return this.grrDialogService_.openDirectiveDialog(directive.directive_name,{clients:clients})}});goog.provide("grrUi.client.clientLoadGraphSerieDirective.ClientLoadGraphSerieDirective");
goog.scope(function(){grrUi.client.clientLoadGraphSerieDirective.ClientLoadGraphSerieDirective=function(){return{scope:{clientId:"=",metric:"@",rate:"@",label:"@"},restrict:"E",require:"^grrTimeseriesGraph",link:function(scope,element,attrs,grrTimeseriesGrpahCtrl){scope.$watch("::clientId",function(){if(angular.isUndefined(scope.clientId))return;var options={};if(scope.rate)options["rate"]=scope.rate;var path="clients/"+scope.clientId+"/load-stats/"+scope.metric;grrTimeseriesGrpahCtrl.addSerieDescriptor({label:scope.label,
requestPath:path,requestOptions:options})})}}};grrUi.client.clientLoadGraphSerieDirective.ClientLoadGraphSerieDirective.directive_name="grrClientLoadGraphSerie"});goog.provide("grrUi.client.clientLoadViewDirective.ClientLoadViewController");goog.provide("grrUi.client.clientLoadViewDirective.ClientLoadViewDirective");
goog.scope(function(){grrUi.client.clientLoadViewDirective.ClientLoadViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.cliendId;this.startTime;this.endTime;this.duration=60;this.grrRoutingService_.uiOnParamsChanged(this.scope_,"clientId",this.onClientIdChange_.bind(this));this.scope_.$watch("controller.duration",this.onDurationChange.bind(this))};var ClientLoadViewController=grrUi.client.clientLoadViewDirective.ClientLoadViewController;
ClientLoadViewController.prototype.onClientIdChange_=function(clientId){this.clientId=clientId};ClientLoadViewController.prototype.onDurationChange=function(newValue){this.endTime=Math.round((new Date).getTime()*1E3);this.startTime=this.endTime-this.duration*60*1E6};grrUi.client.clientLoadViewDirective.ClientLoadViewDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/client/client-load-view.html",controller:ClientLoadViewController,controllerAs:"controller"}};
grrUi.client.clientLoadViewDirective.ClientLoadViewDirective.directive_name="grrClientLoadView"});goog.provide("grrUi.client.clientStatusIconsDirective.ClientStatusIconsController");goog.provide("grrUi.client.clientStatusIconsDirective.ClientStatusIconsDirective");
goog.scope(function(){grrUi.client.clientStatusIconsDirective.ClientStatusIconsController=function($scope,grrTimeService){this.scope_=$scope;this.grrTimeService_=grrTimeService;this.iconName;this.crashTime;this.diskWarnings=[];this.lastPing;this.scope_.$watch("::client",this.onClientChange_.bind(this))};var ClientStatusIconsController=grrUi.client.clientStatusIconsDirective.ClientStatusIconsController;ClientStatusIconsController.prototype.onClientChange_=function(newValue){this.iconName=this.showCrashIcon=
null;this.diskWarnings=[];if(angular.isObject(newValue)){this.lastPing=this.scope_.$eval("client.value.last_seen_at.value");if(angular.isUndefined(this.lastPing))this.lastPing=0;var currentTimeMs=this.grrTimeService_.getCurrentTimeMs();var timeLastSeenSecs=(currentTimeMs-this.lastPing/1E3)/1E3;if(timeLastSeenSecs<60*15)this.iconName="online";else if(timeLastSeenSecs<60*60*24)this.iconName="online-1d";else this.iconName="offline";var crashTime=this.scope_.$eval("client.value.last_crash_at.value");
if(angular.isDefined(crashTime)&&currentTimeMs/1E3-crashTime/1E6<60*60*24)this.crashTime=crashTime;angular.forEach(newValue["value"]["volumes"]||[],function(volume){if(volume["value"]["windowsvolume"]&&volume["value"]["windowsvolume"]["value"]["drive_type"]["value"]=="DRIVE_CDROM")return;if(angular.isDefined(volume["value"]["actual_available_allocation_units"])&&angular.isDefined(volume["value"]["total_allocation_units"])){var percent=volume["value"]["actual_available_allocation_units"]["value"]/
volume["value"]["total_allocation_units"]["value"]*100;if(percent<=5){var volumeName="";if(volume["value"]["name"])volumeName=volume["value"]["name"]["value"];this.diskWarnings.push([volumeName,percent])}}}.bind(this))}};grrUi.client.clientStatusIconsDirective.ClientStatusIconsDirective=function(){return{scope:{client:"="},restrict:"E",templateUrl:"/static/angular-components/client/"+"client-status-icons.html",controller:ClientStatusIconsController,controllerAs:"controller"}};grrUi.client.clientStatusIconsDirective.ClientStatusIconsDirective.directive_name=
"grrClientStatusIcons"});goog.provide("grrUi.client.clientUsernamesDirective.ClientUsernamesController");goog.provide("grrUi.client.clientUsernamesDirective.ClientUsernamesDirective");
goog.scope(function(){grrUi.client.clientUsernamesDirective.ClientUsernamesController=function($scope){this.scope_=$scope;this.scope_.usernames;this.scope_.$watch("::value",this.onValueChange_.bind(this))};var ClientUsernamesController=grrUi.client.clientUsernamesDirective.ClientUsernamesController;ClientUsernamesController.prototype.onValueChange_=function(){if(angular.isDefined(this.scope_.value)){var users=this.scope_.value.value.split(" ");var array=[];angular.forEach(users,function(value){array.push({"type":"RDFString",
"value":value})});this.scope_.usernames=array}};grrUi.client.clientUsernamesDirective.ClientUsernamesDirective=function(){return{scope:{value:"="},restrict:"E",template:'<grr-semantic-value value="::usernames" />',controller:ClientUsernamesController,controllerAs:"controller"}};grrUi.client.clientUsernamesDirective.ClientUsernamesDirective.directive_name="grrClientUsernames"});goog.provide("grrUi.client.clientsListDirective.ClientsListController");goog.provide("grrUi.client.clientsListDirective.ClientsListDirective");
goog.scope(function(){grrUi.client.clientsListDirective.ClientsListController=function($scope,grrClientDialogService,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.grrClientDialogService_=grrClientDialogService;this.triggerUpdate;this.clients={};this.selectedClients={};this.allClientsSelected=false;this.numSelectedClients=0;this.query;this.grrRoutingService_.uiOnParamsChanged(this.scope_,"q",this.onQueryChange_.bind(this))};var ClientsListController=grrUi.client.clientsListDirective.ClientsListController;
ClientsListController.prototype.onQueryChange_=function(query){this.query=query;if(this.triggerUpdate)this.triggerUpdate()};ClientsListController.prototype.onClientClick=function(client){var clientId=client["value"]["urn"]["value"].split("/")[1];this.grrRoutingService_.go("client",{clientId:clientId})};ClientsListController.prototype.updateNumSelectedClients=function(){var count=0;for(var key in this.selectedClients)if(this.selectedClients[key])++count;this.numSelectedClients=count};ClientsListController.prototype.onClientsFetched=
function(items){angular.forEach(items,function(item){var urn=item["value"]["urn"]["value"];this.clients[urn]=item;this.selectedClients[urn]=false;item["_mac_addresses"]=[];angular.forEach(item["value"]["interfaces"],function(iface){if(angular.isDefined(iface["value"]["mac_address"]))item["_mac_addresses"].push(iface["value"]["mac_address"])}.bind(this));item["_usernames"]=[];angular.forEach(item["value"]["users"],function(user){item["_usernames"].push(user["value"]["username"])}.bind(this));item["tableKey"]=
urn}.bind(this));return items};ClientsListController.prototype.selectAll=function(){for(var key in this.selectedClients)this.selectedClients[key]=this.allClientsSelected;this.updateNumSelectedClients()};ClientsListController.prototype.showLabelsDialog=function(action){var clients=[];for(var clientUrn in this.selectedClients)if(this.selectedClients[clientUrn])clients.push(this.clients[clientUrn]);var result;if(action=="add")result=this.grrClientDialogService_.openAddClientLabels(clients);else if(action==
"remove")result=this.grrClientDialogService_.openRemoveClientLabels(clients);else throw Error("Unexpected action: "+action);result.then(function resolve(){this.triggerUpdate()}.bind(this),function dismiss(){}.bind(this))};ClientsListController.prototype.clientsQueryUrl="/clients";grrUi.client.clientsListDirective.ClientsListDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/client/clients-list.html",controller:ClientsListController,controllerAs:"controller"}};
grrUi.client.clientsListDirective.ClientsListDirective.directive_name="grrClientsList"});goog.provide("grrUi.client.debugRequestsViewDirective.DebugRequestsViewController");goog.provide("grrUi.client.debugRequestsViewDirective.DebugRequestsViewDirective");
goog.scope(function(){grrUi.client.debugRequestsViewDirective.DebugRequestsViewController=function($scope,grrApiService,grrRoutingService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.cliendId;this.actionRequests;this.grrRoutingService_.uiOnParamsChanged(this.scope_,"clientId",this.onClientIdChange_.bind(this))};var DebugRequestsViewController=grrUi.client.debugRequestsViewDirective.DebugRequestsViewController;DebugRequestsViewController.prototype.onClientIdChange_=
function(clientId){this.clientId=clientId;this.actionRequests=undefined;if(angular.isDefined(this.clientId)){var url="clients/"+this.clientId+"/action-requests";var fetchResponses=1;if(angular.isDefined(this.scope_["fetchResponses"]))fetchResponses=this.scope_["fetchResponses"];this.grrApiService_.get(url,{"fetch_responses":fetchResponses}).then(function(response){this.actionRequests=response["data"]["items"]||[]}.bind(this))}};grrUi.client.debugRequestsViewDirective.DebugRequestsViewDirective=function(){return{scope:{fetchResponses:"="},
restrict:"E",templateUrl:"/static/angular-components/client/debug-requests-view.html",controller:DebugRequestsViewController,controllerAs:"controller"}};grrUi.client.debugRequestsViewDirective.DebugRequestsViewDirective.directive_name="grrDebugRequestsView"});goog.provide("grrUi.client.hostHistoryDialogDirective.HostHistoryDialogController");goog.provide("grrUi.client.hostHistoryDialogDirective.HostHistoryDialogDirective");goog.require("grrUi.core.apiService.stripTypeInfo");
goog.scope(function(){var stripTypeInfo=grrUi.core.apiService.stripTypeInfo;grrUi.client.hostHistoryDialogDirective.HostHistoryDialogController=function($scope,grrApiService,grrTimeService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrTimeService_=grrTimeService;this.items;this.endTime;this.startTime;this.scope_.$watchGroup(["clientId","fieldPath"],this.onParamsChange_.bind(this))};var HostHistoryDialogController=grrUi.client.hostHistoryDialogDirective.HostHistoryDialogController;
HostHistoryDialogController.prototype.onParamsChange_=function(){var clientId=this.scope_["clientId"];var fieldPath=this.scope_["fieldPath"];if(angular.isDefined(clientId)&&angular.isDefined(fieldPath)){var endTime=this.grrTimeService_.getCurrentTimeMs()*1E3;var startTime=endTime-1E6*60*60*24*365;this.startTime={type:"RDFDatetime",value:startTime};this.endTime={type:"RDFDatetime",value:endTime};this.grrApiService_.get("/clients/"+clientId+"/versions",{mode:"DIFF",start:startTime,end:endTime}).then(function(response){this.buildItems_(response["data"]["items"])}.bind(this))}};
HostHistoryDialogController.prototype.getFieldFromVersion_=function(version,fieldPath){var components=fieldPath.split(".");var curValue=version;for(var i=0;i<components.length;++i){var component=components[i];curValue=curValue["value"][component];if(angular.isUndefined(curValue))break}return curValue};HostHistoryDialogController.prototype.buildItems_=function(versions){var fieldPath=this.scope_["fieldPath"];var prevCompareValue;this.items=[];angular.forEach(versions,function(version){var versionValue=
this.getFieldFromVersion_(version,fieldPath);if(angular.isUndefined(versionValue))return;var compareValue=stripTypeInfo(versionValue);if(angular.equals(prevCompareValue,compareValue))return;this.items.push([version["value"]["age"],versionValue]);prevCompareValue=compareValue}.bind(this));this.items.reverse()};grrUi.client.hostHistoryDialogDirective.HostHistoryDialogDirective=function(){return{scope:{clientId:"=",fieldPath:"=",close:"&"},restrict:"E",templateUrl:"/static/angular-components/client/host-history-dialog.html",
controller:HostHistoryDialogController,controllerAs:"controller"}};grrUi.client.hostHistoryDialogDirective.HostHistoryDialogDirective.directive_name="grrHostHistoryDialog"});goog.provide("grrUi.client.hostInfoDirective.HostInfoController");goog.provide("grrUi.client.hostInfoDirective.HostInfoDirective");
goog.scope(function(){var OPERATION_POLL_INTERVAL_MS=1E3;grrUi.client.hostInfoDirective.HostInfoController=function($scope,$interval,grrApiService,grrRoutingService,grrAclDialogService,grrDialogService){this.scope_=$scope;this.interval_=$interval;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.grrAclDialogService_=grrAclDialogService;this.grrDialogService_=grrDialogService;this.clientVersionUrl;this.clientId;this.clientVersion;this.client;this.hasClientAccess;this.interrogateOperationId;
this.interrogateOperationInterval_;this.grrRoutingService_.uiOnParamsChanged(this.scope_,"clientId",this.onClientIdChange_.bind(this));this.scope_.$watch("clientId",this.onClientIdChange_.bind(this));this.scope_.$watch("controller.clientVersion",this.onClientVersionChange_.bind(this));this.scope_.$on("$destroy",this.stopMonitorInterrogateOperation_.bind(this))};var HostInfoController=grrUi.client.hostInfoDirective.HostInfoController;HostInfoController.prototype.onClientIdChange_=function(clientId){if(angular.isDefined(clientId)){this.clientId=
clientId;this.clientVersionUrl="/clients/"+clientId+"/version-times";this.fetchClientDetails_()}};HostInfoController.prototype.onClientVersionChange_=function(newValue,oldValue){if(oldValue)this.fetchClientDetails_()};HostInfoController.prototype.fetchClientDetails_=function(){var url="/clients/"+this.clientId;var params={};if(this.clientVersion)params["timestamp"]=this.clientVersion;this.grrApiService_.get(url,params).then(function success(response){this.client=response.data;this.clientVersion=response.data["value"]["age"]["value"]}.bind(this))};
HostInfoController.prototype.requestApproval=function(){this.grrAclDialogService_.openRequestClientApprovalDialog(this.clientId)};HostInfoController.prototype.interrogate=function(){var url="/clients/"+this.clientId+"/actions/interrogate";this.grrApiService_.post(url).then(function success(response){this.interrogateOperationId=response["data"]["operation_id"];this.monitorInterrogateOperation_()}.bind(this),function failure(response){this.stopMonitorInterrogateOperation_()}.bind(this))};HostInfoController.prototype.monitorInterrogateOperation_=
function(){this.interrogateOperationInterval_=this.interval_(this.pollInterrogateOperationState_.bind(this),OPERATION_POLL_INTERVAL_MS)};HostInfoController.prototype.pollInterrogateOperationState_=function(){var url="clients/"+this.clientId+"/actions/interrogate/"+this.interrogateOperationId;this.grrApiService_.get(url).then(function success(response){if(response["data"]["state"]==="FINISHED"){this.stopMonitorInterrogateOperation_();this.clientVersion=null;this.fetchClientDetails_()}}.bind(this),
function failure(response){this.stopMonitorInterrogateOperation_()}.bind(this))};HostInfoController.prototype.stopMonitorInterrogateOperation_=function(){this.interrogateOperationId=null;this.interval_.cancel(this.interrogateOperationInterval_)};HostInfoController.prototype.showHistoryDialog=function(fieldPath){this.grrDialogService_.openDirectiveDialog("grrHostHistoryDialog",{clientId:this.clientId,fieldPath:fieldPath},{windowClass:"high-modal"})};grrUi.client.hostInfoDirective.HostInfoDirective=
function(){return{scope:{"clientId":"=","readOnly":"="},restrict:"E",templateUrl:"/static/angular-components/client/host-info.html",controller:HostInfoController,controllerAs:"controller"}};grrUi.client.hostInfoDirective.HostInfoDirective.directive_name="grrHostInfo"});goog.provide("grrUi.client.virtualFileSystem.breadcrumbsDirective.BreadcrumbsController");goog.provide("grrUi.client.virtualFileSystem.breadcrumbsDirective.BreadcrumbsDirective");
goog.scope(function(){grrUi.client.virtualFileSystem.breadcrumbsDirective.BreadcrumbsController=function($rootScope,$scope,grrApiService){this.rootScope_=$rootScope;this.scope_=$scope;this.items;this.activeItem;this.scope_.$watchGroup(["path","stripEndingSlash"],this.onDirectiveArgsChange_.bind(this))};var BreadcrumbsController=grrUi.client.virtualFileSystem.breadcrumbsDirective.BreadcrumbsController;BreadcrumbsController.prototype.onDirectiveArgsChange_=function(){var pathArg=this.scope_["path"];
var stripEndingSlashArg=this.scope_["stripEndingSlash"];this.items=[];this.activeItem=undefined;if(!pathArg)return;var components=pathArg.split("/");if(stripEndingSlashArg&&pathArg.endsWith("/"))components=components.slice(0,components.length-1);if(components.length<2)return;components=components.slice(0,-1);var currentPath="";angular.forEach(components.slice(0,-1),function(component){currentPath+=component+"/";this.items.push({name:component,path:currentPath})}.bind(this));this.activeItem=components[components.length-
1]};BreadcrumbsController.prototype.selectPath=function(path){this.scope_["path"]=path};grrUi.client.virtualFileSystem.breadcrumbsDirective.BreadcrumbsDirective=function(){return{restrict:"E",scope:{path:"=",stripEndingSlash:"="},templateUrl:"/static/angular-components/client/virtual-file-system/breadcrumbs.html",controller:BreadcrumbsController,controllerAs:"controller"}};grrUi.client.virtualFileSystem.breadcrumbsDirective.BreadcrumbsDirective.directive_name="grrBreadcrumbs"});goog.provide("grrUi.client.virtualFileSystem.encodingsDropdownDirective.EncodingsDropdownController");goog.provide("grrUi.client.virtualFileSystem.encodingsDropdownDirective.EncodingsDropdownDirective");
goog.scope(function(){grrUi.client.virtualFileSystem.encodingsDropdownDirective.EncodingsDropdownController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrApiService_.get("reflection/file-encodings").then(function(response){this.encodings=response.data["encodings"]}.bind(this))};var EncodingsDropdownController=grrUi.client.virtualFileSystem.encodingsDropdownDirective.EncodingsDropdownController;grrUi.client.virtualFileSystem.encodingsDropdownDirective.EncodingsDropdownDirective=
function(){return{restrict:"E",scope:{encoding:"="},templateUrl:"/static/angular-components/client/virtual-file-system/encodings-dropdown.html",controller:EncodingsDropdownController,controllerAs:"controller"}};grrUi.client.virtualFileSystem.encodingsDropdownDirective.EncodingsDropdownDirective.directive_name="grrEncodingsDropdown"});goog.provide("grrUi.client.virtualFileSystem.fileContextDirective.FileContextController");goog.provide("grrUi.client.virtualFileSystem.fileContextDirective.FileContextDirective");
goog.scope(function(){grrUi.client.virtualFileSystem.fileContextDirective.FileContextController=function($scope){this.scope_=$scope;this.clientId;this.selectedFilePath;this.selectedFileVersion;this.scope_.$watchGroup(["clientId","selectedFilePath","selectedFileVersion"],this.onDirectiveArgumentsChange_.bind(this));this.scope_.$watchGroup(["controller.clientId","controller.selectedFilePath","controller.selectedFileVersion"],this.onControllerValuesChange_.bind(this))};var FileContextController=grrUi.client.virtualFileSystem.fileContextDirective.FileContextController;
FileContextController.prototype.onDirectiveArgumentsChange_=function(){this.clientId=this.scope_["clientId"];this.selectedFilePath=this.scope_["selectedFilePath"];this.selectedFileVersion=this.scope_["selectedFileVersion"]};FileContextController.prototype.onControllerValuesChange_=function(){this.scope_["clientId"]=this.clientId;this.scope_["selectedFilePath"]=this.selectedFilePath;this.scope_["selectedFileVersion"]=this.selectedFileVersion};FileContextController.prototype.selectFile=function(filePath,
opt_fileVersion){this.selectedFilePath=filePath;this.selectedFileVersion=opt_fileVersion||null};grrUi.client.virtualFileSystem.fileContextDirective.FileContextDirective=function(){return{restrict:"E",scope:{clientId:"=",selectedFilePath:"=",selectedFileVersion:"="},transclude:true,template:"<ng-transclude />",controller:FileContextController,controllerAs:"controller"}};grrUi.client.virtualFileSystem.fileContextDirective.FileContextDirective.directive_name="grrFileContext"});goog.provide("grrUi.client.virtualFileSystem.fileDetailsDirective.FileDetailsController");goog.provide("grrUi.client.virtualFileSystem.fileDetailsDirective.FileDetailsDirective");goog.require("grrUi.client.virtualFileSystem.events");goog.require("grrUi.core.versionDropdownDirective.VersionDropdownDirective");
goog.scope(function(){var REFRESH_FILE_EVENT=grrUi.client.virtualFileSystem.events.REFRESH_FILE_EVENT;var REFRESH_VERSIONS_EVENT=grrUi.core.versionDropdownDirective.VersionDropdownDirective.REFRESH_VERSIONS_EVENT;grrUi.client.virtualFileSystem.fileDetailsDirective.FileDetailsController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.shownFileName;this.fileVersionUrl;this.fileContext;this.fileIsDirectory;this.downloadQueryParams;this.currentTab="stats";this.scope_.$on(REFRESH_FILE_EVENT,
this.refreshFile_.bind(this));this.scope_.$watch("currentTab",this.onDirectiveTabChange_.bind(this));this.scope_.$watch("controller.currentTab",this.onControllerTabChange_.bind(this));this.scope_.$watchGroup(["controller.fileContext.clientId","controller.fileContext.selectedFilePath","controller.fileContext.selectedFileVersion"],this.onContextChange_.bind(this))};var FileDetailsController=grrUi.client.virtualFileSystem.fileDetailsDirective.FileDetailsController;FileDetailsController.prototype.onDirectiveTabChange_=
function(newValue){if(angular.isString(newValue))this.currentTab=newValue};FileDetailsController.prototype.onControllerTabChange_=function(newValue,oldValue){if(newValue!==oldValue)this.scope_["currentTab"]=newValue};FileDetailsController.prototype.onContextChange_=function(){var clientId=this.fileContext["clientId"];var selectedFilePath=this.fileContext["selectedFilePath"];if(angular.isDefined(clientId)&&angular.isDefined(selectedFilePath))this.fetchFileDetails_()};FileDetailsController.prototype.fetchFileDetails_=
function(){var clientId=this.fileContext["clientId"];var selectedFilePath=this.fileContext["selectedFilePath"];var fileVersion=this.fileContext["selectedFileVersion"];var url="clients/"+clientId+"/vfs-details/"+selectedFilePath;var params={};if(fileVersion)params["timestamp"]=fileVersion;this.grrApiService_.get(url,params).then(this.onFileDetailsFetched_.bind(this))};FileDetailsController.prototype.onFileDetailsFetched_=function(response){var clientId=this.fileContext["clientId"];var selectedFilePath=
this.fileContext["selectedFilePath"];var fileVersion=this.fileContext["selectedFileVersion"];var fileDetails=response.data["file"];this.fileVersionUrl="clients/"+clientId+"/vfs-version-times/"+selectedFilePath;this.fileIsDirectory=fileDetails["value"]["is_directory"]["value"];this.downloadQueryParams={clientId:clientId,aff4_path:"aff4:/"+clientId+"/"+selectedFilePath};if(fileVersion)this.downloadQueryParams["age"]=fileVersion;var components=fileDetails["value"]["path"]["value"].split("/");this.selectedFileName=
components[components.length-1]};FileDetailsController.prototype.refreshFile_=function(){this.fileContext["selectedFileVersion"]=undefined;this.scope_.$broadcast(REFRESH_VERSIONS_EVENT,{});this.fetchFileDetails_()};FileDetailsController.prototype.targetsCurrentSelection_=function(fileDetails){var selectedFilePath=this.fileContext["selectedFilePath"];return fileDetails["value"]["path"]["value"]===selectedFilePath};grrUi.client.virtualFileSystem.fileDetailsDirective.FileDetailsDirective=function(){return{restrict:"E",
scope:{currentTab:"="},require:"^grrFileContext",templateUrl:"/static/angular-components/client/virtual-file-system/file-details.html",controller:FileDetailsController,controllerAs:"controller",link:function(scope,element,attrs,fileContextController){scope.controller.fileContext=fileContextController}}};grrUi.client.virtualFileSystem.fileDetailsDirective.FileDetailsDirective.directive_name="grrFileDetails"});goog.provide("grrUi.client.virtualFileSystem.fileDownloadViewDirective.FileDownloadViewController");goog.provide("grrUi.client.virtualFileSystem.fileDownloadViewDirective.FileDownloadViewDirective");goog.require("grrUi.client.virtualFileSystem.events");goog.require("grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective");
goog.scope(function(){var REFRESH_FILE_EVENT=grrUi.client.virtualFileSystem.events.REFRESH_FILE_EVENT;var ERROR_EVENT_NAME=grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective.error_event_name;var OPERATION_POLL_INTERVAL_MS=1E3;grrUi.client.virtualFileSystem.fileDownloadViewDirective.FileDownloadViewController=function($rootScope,$scope,$interval,grrApiService){this.rootScope_=$rootScope;this.scope_=$scope;this.interval_=$interval;this.fileContext;this.grrApiService_=grrApiService;this.updateOperationId;
this.updateOperationInterval_;this.updateInProgress;this.downloadCommand;this.fileDetails;this.scope_.$watchGroup(["controller.fileContext.clientId","controller.fileContext.selectedFilePath","controller.fileContext.selectedFileVersion"],this.onContextChange_.bind(this));this.scope_.$on("$destroy",this.stopMonitorUpdateOperation_.bind(this))};var FileDownloadViewController=grrUi.client.virtualFileSystem.fileDownloadViewDirective.FileDownloadViewController;FileDownloadViewController.prototype.onContextChange_=
function(){var clientId=this.fileContext["clientId"];var filePath=this.fileContext["selectedFilePath"];var fileVersion=this.fileContext["selectedFileVersion"];if(angular.isDefined(clientId)&&angular.isDefined(filePath)){var commandUrl="clients/"+clientId+"/vfs-download-command/"+filePath;this.grrApiService_.get(commandUrl).then(function(response){this.downloadCommand=response.data["command"]}.bind(this));var detailsUrl="clients/"+clientId+"/vfs-details/"+filePath;var params={};if(fileVersion)params["timestamp"]=
fileVersion;this.grrApiService_.get(detailsUrl,params).then(function(response){this.fileDetails=response.data["file"]}.bind(this))}};FileDownloadViewController.prototype.updateFile=function(){if(this.updateInProgress)return;var clientId=this.fileContext["clientId"];var selectedFilePath=this.fileContext["selectedFilePath"];var url="clients/"+clientId+"/vfs-update";var params={file_path:selectedFilePath};this.updateInProgress=true;this.grrApiService_.post(url,params).then(function success(response){this.updateOperationId=
response["data"]["operation_id"];this.monitorUpdateOperation_()}.bind(this),function failure(response){this.stopMonitorUpdateOperation_()}.bind(this))};FileDownloadViewController.prototype.monitorUpdateOperation_=function(){this.updateOperationInterval_=this.interval_(this.pollUpdateOperationState_.bind(this),OPERATION_POLL_INTERVAL_MS)};FileDownloadViewController.prototype.pollUpdateOperationState_=function(){var clientId=this.fileContext["clientId"];var url="clients/"+clientId+"/vfs-update/"+this.updateOperationId;
this.grrApiService_.get(url).then(function success(response){if(response["data"]["state"]==="FINISHED"){this.rootScope_.$broadcast(REFRESH_FILE_EVENT);this.stopMonitorUpdateOperation_()}}.bind(this),function failure(response){this.stopMonitorUpdateOperation_()}.bind(this))};FileDownloadViewController.prototype.stopMonitorUpdateOperation_=function(){this.updateOperationId=null;this.updateInProgress=false;this.interval_.cancel(this.updateOperationInterval_)};FileDownloadViewController.prototype.downloadFile=
function(){var clientId=this.fileContext["clientId"];var filePath=this.fileContext["selectedFilePath"];var fileVersion=this.fileContext["selectedFileVersion"];var url="clients/"+clientId+"/vfs-blob/"+filePath;var params={};if(fileVersion)params["timestamp"]=fileVersion;this.grrApiService_.downloadFile(url,params).then(function success(){}.bind(this),function failure(response){if(angular.isUndefined(response.status))this.rootScope_.$broadcast(ERROR_EVENT_NAME,{message:"Couldn't download file."})}.bind(this))};
grrUi.client.virtualFileSystem.fileDownloadViewDirective.FileDownloadViewDirective=function(){return{restrict:"E",scope:{},require:"^grrFileContext",templateUrl:"/static/angular-components/client/virtual-file-system/file-download-view.html",controller:FileDownloadViewController,controllerAs:"controller",link:function(scope,element,attrs,fileContextController){scope.controller.fileContext=fileContextController}}};grrUi.client.virtualFileSystem.fileDownloadViewDirective.FileDownloadViewDirective.directive_name=
"grrFileDownloadView"});goog.provide("grrUi.client.virtualFileSystem.fileHexViewDirective.FileHexViewController");goog.provide("grrUi.client.virtualFileSystem.fileHexViewDirective.FileHexViewDirective");
goog.scope(function(){grrUi.client.virtualFileSystem.fileHexViewDirective.FileHexViewController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.fileContext;this.hexDataRows;this.page=1;this.pageCount=1;this.rows_=25;this.columns_=32;this.offset_=0;this.chunkSize_=this.rows_*this.columns_;this.scope_.$watchGroup(["controller.fileContext.clientId","controller.fileContext.selectedFilePath","controller.fileContext.selectedFileVersion"],this.onContextChange_.bind(this));
this.scope_.$watch("controller.page",this.onPageChange_.bind(this))};var FileHexViewController=grrUi.client.virtualFileSystem.fileHexViewDirective.FileHexViewController;FileHexViewController.prototype.onContextChange_=function(){var clientId=this.fileContext["clientId"];var filePath=this.fileContext["selectedFilePath"];if(angular.isDefined(clientId)&&angular.isDefined(filePath))this.fetchText_()};FileHexViewController.prototype.onPageChange_=function(page,oldPage){if(this.page!==oldPage){this.offset_=
(this.page-1)*this.chunkSize_;this.fetchText_()}};FileHexViewController.prototype.fetchText_=function(){var clientId=this.fileContext["clientId"];var filePath=this.fileContext["selectedFilePath"];var fileVersion=this.fileContext["selectedFileVersion"];var url="clients/"+clientId+"/vfs-blob/"+filePath;var headParams={};if(fileVersion)headParams["timestamp"]=fileVersion;this.grrApiService_.head(url,headParams).then(function(response){var total_size=response.headers("Content-Length");this.pageCount=
Math.ceil(total_size/this.chunkSize_);var params={};params["offset"]=this.offset_;params["length"]=this.chunkSize_;if(fileVersion)params["timestamp"]=fileVersion;return this.grrApiService_.get(url,params)}.bind(this)).then(function(response){this.parseFileContentToHexRepresentation_(response.data)}.bind(this),function(){this.hexDataRows=null}.bind(this))};FileHexViewController.prototype.parseFileContentToHexRepresentation_=function(fileContent){this.hexDataRows=[];if(!fileContent)return;for(var i=
0;i<this.rows_;i++){var rowOffset=this.offset_+i*this.columns_;this.hexDataRows.push({offset:rowOffset,data:fileContent.substr(i*this.columns_,this.columns_)})}};grrUi.client.virtualFileSystem.fileHexViewDirective.FileHexViewDirective=function(){return{restrict:"E",scope:{},require:"^grrFileContext",templateUrl:"/static/angular-components/client/virtual-file-system/file-hex-view.html",controller:FileHexViewController,controllerAs:"controller",link:function(scope,element,attrs,fileContextController){scope.controller.fileContext=
fileContextController}}};grrUi.client.virtualFileSystem.fileHexViewDirective.FileHexViewDirective.directive_name="grrFileHexView"});goog.provide("grrUi.client.virtualFileSystem.fileStatsViewDirective.FileStatsViewController");goog.provide("grrUi.client.virtualFileSystem.fileStatsViewDirective.FileStatsViewDirective");
goog.scope(function(){grrUi.client.virtualFileSystem.fileStatsViewDirective.FileStatsViewController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.fileContext;this.details;this.scope_.$watchGroup(["controller.fileContext.clientId","controller.fileContext.selectedFilePath","controller.fileContext.selectedFileVersion"],this.onContextChange_.bind(this))};var FileStatsViewController=grrUi.client.virtualFileSystem.fileStatsViewDirective.FileStatsViewController;
FileStatsViewController.prototype.onContextChange_=function(){var clientId=this.fileContext["clientId"];var filePath=this.fileContext["selectedFilePath"];var fileVersion=this.fileContext["selectedFileVersion"];if(angular.isDefined(clientId)&&angular.isDefined(filePath)){var fileDetailsUrl="clients/"+clientId+"/vfs-details/"+filePath;var params={};if(fileVersion)params["timestamp"]=fileVersion;this.grrApiService_.get(fileDetailsUrl,params).then(function(response){this.details=response.data["file"]["value"]["details"]}.bind(this))}};
grrUi.client.virtualFileSystem.fileStatsViewDirective.FileStatsViewDirective=function(){return{restrict:"E",scope:{},require:"^grrFileContext",templateUrl:"/static/angular-components/client/virtual-file-system/file-stats-view.html",controller:FileStatsViewController,controllerAs:"controller",link:function(scope,element,attrs,fileContextController){scope.controller.fileContext=fileContextController}}};grrUi.client.virtualFileSystem.fileStatsViewDirective.FileStatsViewDirective.directive_name="grrFileStatsView"});goog.provide("grrUi.client.virtualFileSystem.fileTableDirective.FileTableController");goog.provide("grrUi.client.virtualFileSystem.fileTableDirective.FileTableDirective");goog.require("grrUi.client.virtualFileSystem.events");goog.require("grrUi.client.virtualFileSystem.utils.ensurePathIsFolder");goog.require("grrUi.client.virtualFileSystem.utils.getFolderFromPath");goog.require("grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective");
goog.scope(function(){var REFRESH_FOLDER_EVENT=grrUi.client.virtualFileSystem.events.REFRESH_FOLDER_EVENT;var REFRESH_FILE_EVENT=grrUi.client.virtualFileSystem.events.REFRESH_FILE_EVENT;var ERROR_EVENT_NAME=grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective.error_event_name;var OPERATION_POLL_INTERVAL_MS=1E3;var ensurePathIsFolder=grrUi.client.virtualFileSystem.utils.ensurePathIsFolder;grrUi.client.virtualFileSystem.fileTableDirective.FileTableController=function($rootScope,$scope,$interval,
grrApiService){this.rootScope_=$rootScope;this.scope_=$scope;this.interval_=$interval;this.grrApiService_=grrApiService;this.selectedFilePath_;this.fileListUrl;this.lastRefreshOperationId;this.filterEditedValue="";this.filterValue="";this.fileContext;this.triggerUpdate;this.scope_.$on(REFRESH_FOLDER_EVENT,this.refreshFileList_.bind(this));this.scope_.$on(REFRESH_FILE_EVENT,this.refreshFileList_.bind(this));this.scope_.$watch("controller.fileContext.clientId",this.refreshFileList_.bind(this));this.scope_.$watch("controller.fileContext.selectedFilePath",
this.onFilePathChange_.bind(this))};var FileTableController=grrUi.client.virtualFileSystem.fileTableDirective.FileTableController;FileTableController.prototype.setViewMode=function(mode){this.scope_["viewMode"]=mode};FileTableController.prototype.onFilePathChange_=function(newValue,oldValue){var newFolder=grrUi.client.virtualFileSystem.utils.getFolderFromPath(newValue);var oldFolder=grrUi.client.virtualFileSystem.utils.getFolderFromPath(oldValue);if(newFolder!==oldFolder){this.refreshFileList_();
this.lastRefreshOperationId=null}};FileTableController.prototype.refreshFileList_=function(){var clientId=this.fileContext["clientId"];var selectedFilePath=this.fileContext["selectedFilePath"]||"";var selectedFolderPath=grrUi.client.virtualFileSystem.utils.getFolderFromPath(selectedFilePath);this.filter="";this.fileListUrl="clients/"+clientId+"/vfs-index/"+selectedFolderPath;if(this.triggerUpdate)this.triggerUpdate()};FileTableController.prototype.selectFile=function(file){this.fileContext.selectFile(file["value"]["path"]["value"],
0)};FileTableController.prototype.selectFolder=function(file){var clientId=this.fileContext["clientId"];var filePath=file["value"]["path"]["value"];filePath=ensurePathIsFolder(filePath);this.fileContext.selectFile(filePath,0);this.fileListUrl="clients/"+clientId+"/vfs-index/"+filePath};FileTableController.prototype.startVfsRefreshOperation=function(){var clientId=this.fileContext["clientId"];var selectedFilePath=this.fileContext["selectedFilePath"];var selectedFolderPath=grrUi.client.virtualFileSystem.utils.getFolderFromPath(selectedFilePath);
var url="clients/"+clientId+"/vfs-refresh-operations";var refreshOperation={file_path:selectedFolderPath,max_depth:1,notify_user:false};var operationId=this.lastRefreshOperationId="unknown";this.grrApiService_.post(url,refreshOperation).then(function success(response){operationId=this.lastRefreshOperationId=response["data"]["operation_id"];var pollPromise=this.grrApiService_.poll(url+"/"+operationId,OPERATION_POLL_INTERVAL_MS);this.scope_.$on("$destroy",function(){this.grrApiService_.cancelPoll(pollPromise)}.bind(this));
return pollPromise}.bind(this)).then(function success(){this.rootScope_.$broadcast(REFRESH_FOLDER_EVENT,ensurePathIsFolder(selectedFolderPath))}.bind(this)).finally(function(){if(this.lastRefreshOperationId==operationId)this.lastRefreshOperationId=null}.bind(this))};FileTableController.prototype.updateFilter=function(){this.filterValue=this.filterEditedValue};FileTableController.prototype.downloadTimeline=function(){var clientId=this.fileContext["clientId"];var selectedFilePath=this.fileContext["selectedFilePath"]||
"";var selectedFolderPath=grrUi.client.virtualFileSystem.utils.getFolderFromPath(selectedFilePath);var url="clients/"+clientId+"/vfs-timeline-csv/"+selectedFolderPath;this.grrApiService_.downloadFile(url).then(function success(){}.bind(this),function failure(response){if(angular.isUndefined(response.status))this.rootScope_.$broadcast(ERROR_EVENT_NAME,{message:"Couldn't export the timeline."})}.bind(this))};grrUi.client.virtualFileSystem.fileTableDirective.FileTableDirective=function(){return{restrict:"E",
scope:{viewMode:"="},require:"^grrFileContext",templateUrl:"/static/angular-components/client/virtual-file-system/file-table.html",controller:FileTableController,controllerAs:"controller",link:function(scope,element,attrs,fileContextController){scope.controller.fileContext=fileContextController}}};grrUi.client.virtualFileSystem.fileTableDirective.FileTableDirective.directive_name="grrFileTable"});goog.provide("grrUi.client.virtualFileSystem.fileTextViewDirective.FileTextViewController");goog.provide("grrUi.client.virtualFileSystem.fileTextViewDirective.FileTextViewDirective");
goog.scope(function(){grrUi.client.virtualFileSystem.fileTextViewDirective.FileTextViewController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.fileContext;this.fileContent;this.encoding="UTF_8";this.page=1;this.pageCount=1;this.chunkSize_=1E4;this.scope_.$watchGroup(["controller.fileContext.clientId","controller.fileContext.selectedFilePath","controller.fileContext.selectedFileVersion"],this.onContextChange_.bind(this));this.scope_.$watch("controller.encoding",
this.onEncodingChange_.bind(this));this.scope_.$watch("controller.page",this.onPageChange_.bind(this))};var FileTextViewController=grrUi.client.virtualFileSystem.fileTextViewDirective.FileTextViewController;FileTextViewController.prototype.onContextChange_=function(){var clientId=this.fileContext["clientId"];var filePath=this.fileContext["selectedFilePath"];if(angular.isDefined(clientId)&&angular.isDefined(filePath))this.fetchText_()};FileTextViewController.prototype.onPageChange_=function(page,oldPage){if(this.page!==
oldPage)this.fetchText_()};FileTextViewController.prototype.onEncodingChange_=function(encoding,oldEncoding){if(this.encoding!==oldEncoding)this.fetchText_()};FileTextViewController.prototype.fetchText_=function(){var clientId=this.fileContext["clientId"];var filePath=this.fileContext["selectedFilePath"];var fileVersion=this.fileContext["selectedFileVersion"];var offset=(this.page-1)*this.chunkSize_;var url="clients/"+clientId+"/vfs-text/"+filePath;var params={};params["encoding"]=this.encoding;params["offset"]=
offset;params["length"]=this.chunkSize_;if(fileVersion)params["timestamp"]=fileVersion;this.grrApiService_.get(url,params).then(function(response){this.fileContent=response.data["content"];var total_size=response.data["total_size"];this.pageCount=Math.ceil(total_size/this.chunkSize_)}.bind(this),function(){this.fileContent=null}.bind(this))};grrUi.client.virtualFileSystem.fileTextViewDirective.FileTextViewDirective=function(){return{restrict:"E",scope:{},require:"^grrFileContext",templateUrl:"/static/angular-components/client/virtual-file-system/file-text-view.html",
controller:FileTextViewController,controllerAs:"controller",link:function(scope,element,attrs,fileContextController){scope.controller.fileContext=fileContextController}}};grrUi.client.virtualFileSystem.fileTextViewDirective.FileTextViewDirective.directive_name="grrFileTextView"});goog.provide("grrUi.client.virtualFileSystem.fileTimelineDirective.FileTimelineController");goog.provide("grrUi.client.virtualFileSystem.fileTimelineDirective.FileTimelineDirective");goog.require("grrUi.client.virtualFileSystem.events");goog.require("grrUi.client.virtualFileSystem.utils.getFolderFromPath");
goog.scope(function(){var getFolderFromPath=grrUi.client.virtualFileSystem.utils.getFolderFromPath;var REFRESH_FOLDER_EVENT=grrUi.client.virtualFileSystem.events.REFRESH_FOLDER_EVENT;var REFRESH_FILE_EVENT=grrUi.client.virtualFileSystem.events.REFRESH_FILE_EVENT;grrUi.client.virtualFileSystem.fileTimelineDirective.FileTimelineController=function($scope,$interval,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.fileContext;this.timelineItems;this.selectedItem;this.inProgress;
this.currentFolder;this.triggerUpdate;this.scope_.$on(REFRESH_FOLDER_EVENT,this.refreshTimeline_.bind(this));this.scope_.$on(REFRESH_FILE_EVENT,this.refreshTimeline_.bind(this));this.scope_.$watch("controller.fileContext.clientId",this.refreshTimeline_.bind(this));this.scope_.$watch("controller.fileContext.selectedFilePath",this.onFilePathChange_.bind(this))};var FileTimelineController=grrUi.client.virtualFileSystem.fileTimelineDirective.FileTimelineController;FileTimelineController.prototype.onFilePathChange_=
function(newFilePath){if(angular.isUndefined(newFilePath))return;var newFolder=getFolderFromPath(newFilePath);if(newFilePath.endsWith("/")||angular.isUndefined(this.currentFolder)){this.currentFolder=newFolder;this.refreshTimeline_();return}var newFolderComponents=newFolder.split("/");var currentFolderComponents=this.currentFolder.split("/");for(var i=0;i<currentFolderComponents.length;++i)if(newFolderComponents[i]!=currentFolderComponents[i]){this.refreshTimeline_();this.currentFolder=newFolder}};
FileTimelineController.prototype.refreshTimeline_=function(){var clientId=this.fileContext["clientId"];var selectedFolderPath=getFolderFromPath(this.fileContext["selectedFilePath"]);if(angular.isUndefined(this.currentFolder))this.currentFolder=selectedFolderPath;this.inProgress=true;var url="clients/"+clientId+"/vfs-timeline/"+selectedFolderPath;this.grrApiService_.get(url).then(this.onTimelineFetched_.bind(this)).finally(function(){this.inProgress=false}.bind(this))};FileTimelineController.prototype.onTimelineFetched_=
function(response){var selectedFilePath=this.fileContext["selectedFilePath"];var selectedFileVersion=this.fileContext["selectedFileVersion"];this.timelineItems=response.data["items"];this.selectedItem=this.timelineItems.find(function(item){var v=item["value"];if(v["file_path"]["value"]===selectedFilePath)return!selectedFileVersion||v["timestamp"]["value"]===selectedFileVersion}.bind(this))||null;if(this.selectedItem&&!selectedFileVersion)this.fileContext["selectedFileVersion"]=this.selectedItem["value"]["timestamp"]["value"];
if(this.triggerUpdate)this.triggerUpdate()};FileTimelineController.prototype.selectFile=function(timelineItem){this.selectedItem=timelineItem;var clientId=this.fileContext["clientId"];var selectedFilePath=timelineItem["value"]["file_path"]["value"];var timestamp=timelineItem["value"]["timestamp"]["value"];var url="clients/"+clientId+"/vfs-version-times/"+selectedFilePath;this.grrApiService_.get(url).then(function success(response){var versions=response.data["times"];var fileVersion=Number.MAX_VALUE;
angular.forEach(versions,function(version){if(version["value"]>=timestamp)fileVersion=Math.min(fileVersion,version["value"])});if(fileVersion===Number.MAX_VALUE)if(versions.length)fileVersion=versions[0]["value"];else fileVersion=null;this.fileContext.selectFile(selectedFilePath,fileVersion)}.bind(this))};grrUi.client.virtualFileSystem.fileTimelineDirective.FileTimelineDirective=function(){return{restrict:"E",scope:{filterValue:"=?"},require:"^grrFileContext",templateUrl:"/static/angular-components/client/virtual-file-system/file-timeline.html",
controller:FileTimelineController,controllerAs:"controller",link:function(scope,element,attrs,fileContextController){scope.controller.fileContext=fileContextController}}};grrUi.client.virtualFileSystem.fileTimelineDirective.FileTimelineDirective.directive_name="grrFileTimeline"});goog.provide("grrUi.client.virtualFileSystem.fileTreeDirective.FileTreeController");goog.provide("grrUi.client.virtualFileSystem.fileTreeDirective.FileTreeDirective");goog.require("grrUi.client.virtualFileSystem.events");goog.require("grrUi.client.virtualFileSystem.fileViewDirective.getFileId");goog.require("grrUi.client.virtualFileSystem.utils.ensurePathIsFolder");goog.require("grrUi.client.virtualFileSystem.utils.getFolderFromPath");
goog.scope(function(){var REFRESH_FOLDER_EVENT=grrUi.client.virtualFileSystem.events.REFRESH_FOLDER_EVENT;var ensurePathIsFolder=grrUi.client.virtualFileSystem.utils.ensurePathIsFolder;var getFileId=grrUi.client.virtualFileSystem.fileViewDirective.getFileId;var getFolderFromPath=grrUi.client.virtualFileSystem.utils.getFolderFromPath;grrUi.client.virtualFileSystem.fileTreeDirective.FileTreeController=function($rootScope,$scope,$element,grrApiService,grrRoutingService){this.rootScope_=$rootScope;this.scope_=
$scope;this.element_=$element;this.treeElement_=$element.find("#file-tree");this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.fileContext;this.scope_.$on(REFRESH_FOLDER_EVENT,this.onRefreshFolderEvent_.bind(this));this.scope_.$watch("controller.fileContext.clientId",this.onClientIdChange_.bind(this));this.scope_.$watch("controller.fileContext.selectedFilePath",this.onSelectedFilePathChange_.bind(this))};var FileTreeController=grrUi.client.virtualFileSystem.fileTreeDirective.FileTreeController;
FileTreeController.prototype.onClientIdChange_=function(){if(angular.isDefined(this.fileContext["clientId"]))this.initTree_()};FileTreeController.prototype.initTree_=function(){var controller=this;this.treeElement_.jstree({"core":{"multiple":false,"data":function(node,cb){if(node.id==="#")controller.getChildFiles_("").then(cb);else controller.getChildFiles_(node.data.path).then(cb)}}});this.treeElement_.on("changed.jstree",function(e,data){if(data["action"]!=="select_node")return;var selectionId=
data.selected[0];var node=this.treeElement_.jstree("get_node",selectionId);var folderPath=node.data.path;if(getFolderFromPath(this.fileContext["selectedFilePath"])===folderPath)this.rootScope_.$broadcast(REFRESH_FOLDER_EVENT,ensurePathIsFolder(folderPath));else this.fileContext.selectFile(ensurePathIsFolder(folderPath));var treeInstance=data["instance"];treeInstance["refresh_node"](data.node)}.bind(this));this.treeElement_.on("close_node.jstree",function(e,data){data.node["data"]["refreshOnOpen"]=
true}.bind(this));this.treeElement_.on("open_node.jstree",function(e,data){if(data.node["data"]["refreshOnOpen"]){data.node["data"]["refreshOnOpen"]=false;var treeInstance=data["instance"];treeInstance["refresh_node"](data.node)}}.bind(this));this.treeElement_.on("loaded.jstree",function(){var selectedFilePath=this.fileContext["selectedFilePath"];if(selectedFilePath)this.expandToFilePath_(getFileId(getFolderFromPath(selectedFilePath)),true)}.bind(this));this.treeElement_.on("select_node.jstree",function(event,
data){$(this)["jstree"]("open_node","#"+data.node.id);return true})};FileTreeController.prototype.getChildFiles_=function(folderPath){var clientId_=this.fileContext["clientId"];var url="clients/"+clientId_+"/vfs-index/"+folderPath;var params={directories_only:1};return this.grrApiService_.get(url,params).then(this.parseFileResponse_.bind(this))};FileTreeController.prototype.parseFileResponse_=function(response){var files=response.data["items"];var result=[];angular.forEach(files,function(file){var filePath=
file["value"]["path"]["value"];var fileId=getFileId(filePath);result.push({id:fileId,text:file["value"]["name"]["value"],data:{path:filePath},children:true})}.bind(this));return result};FileTreeController.prototype.onRefreshFolderEvent_=function(e,path){if(angular.isUndefined(path))path=this.fileContext["selectedFilePath"];var nodeId=getFileId(getFolderFromPath(path));var node=$("#"+nodeId);this.treeElement_.jstree(true)["refresh_node"](node)};FileTreeController.prototype.onSelectedFilePathChange_=
function(){var selectedFilePath=this.fileContext["selectedFilePath"];if(selectedFilePath){var selectedFolderPath=getFolderFromPath(selectedFilePath);this.expandToFilePath_(getFileId(selectedFolderPath),true)}};FileTreeController.prototype.expandToFilePath_=function(filePathId,opt_suppressEvent){if(!filePathId)return;var element=this.treeElement_;var parts=filePathId.split("-");var cb=function(i,prev_node){var id_to_open=parts.slice(0,i+1).join("-");var node=$("#"+id_to_open);if(node.length)if(parts[i+
1])element.jstree("open_node",node,function(){cb(i+1,node)},"no_hash");else{element.jstree(true)["deselect_all"](true);element.jstree(true)["select_node"](node,opt_suppressEvent)}else if(prev_node){element.jstree(true)["deselect_all"](true);element.jstree(true)["select_node"](prev_node,opt_suppressEvent)}}.bind(this);cb(0,null)};grrUi.client.virtualFileSystem.fileTreeDirective.FileTreeDirective=function(){return{restrict:"E",scope:{},require:"^grrFileContext",templateUrl:"/static/angular-components/client/virtual-file-system/file-tree.html",
controller:FileTreeController,controllerAs:"controller",link:function(scope,element,attrs,fileContextController){scope.controller.fileContext=fileContextController}}};grrUi.client.virtualFileSystem.fileTreeDirective.FileTreeDirective.directive_name="grrFileTree"});goog.provide("grrUi.client.virtualFileSystem.rWeOwnedButtonDirective.RWeOwnedButtonController");goog.provide("grrUi.client.virtualFileSystem.rWeOwnedButtonDirective.RWeOwnedButtonDirective");
goog.scope(function(){var phrases=["It is certain","You were eaten by a Grue!","\u4e2d\u56fd got you!!","All your bases are belong to us!","Maybe it was the Russians?","It is decidedly so","Without a doubt","Yes - definitely","You may rely on it","As I see it, yes","Most likely","Outlook good","Signs point to yes","Yes","Reply hazy, try again","Ask again later","Better not tell you now","Cannot predict now","Concentrate and ask again","Don't count on it","My reply is no","My sources say no","Outlook not so good",
"Very doubtful"];grrUi.client.virtualFileSystem.rWeOwnedButtonDirective.RWeOwnedButtonController=function($scope,$uibModal){this.scope_=$scope;this.uibModal_=$uibModal;this.phrase};var RWeOwnedButtonController=grrUi.client.virtualFileSystem.rWeOwnedButtonDirective.RWeOwnedButtonController;RWeOwnedButtonController.prototype.onClick=function(){var randomIndex=Math.floor(Math.random()*phrases.length);this.scope_.phrase=phrases[randomIndex];this.uibModal_.open({templateUrl:"/static/angular-components/client/virtual-file-system/"+
"r-we-owned-button-modal.html",scope:this.scope_})};grrUi.client.virtualFileSystem.rWeOwnedButtonDirective.RWeOwnedButtonDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/client/virtual-file-system/r-we-owned-button.html",controller:RWeOwnedButtonController,controllerAs:"controller"}};grrUi.client.virtualFileSystem.rWeOwnedButtonDirective.RWeOwnedButtonDirective.directive_name="grrRWeOwnedButton"});goog.provide("grrUi.client.virtualFileSystem.recursiveListButtonDirective.RecursiveListButtonController");goog.provide("grrUi.client.virtualFileSystem.recursiveListButtonDirective.RecursiveListButtonDirective");goog.require("grrUi.client.virtualFileSystem.events");goog.require("grrUi.client.virtualFileSystem.utils.ensurePathIsFolder");goog.require("grrUi.client.virtualFileSystem.utils.getFolderFromPath");
goog.scope(function(){var REFRESH_FOLDER_EVENT=grrUi.client.virtualFileSystem.events.REFRESH_FOLDER_EVENT;var OPERATION_POLL_INTERVAL_MS=1E3;var ensurePathIsFolder=grrUi.client.virtualFileSystem.utils.ensurePathIsFolder;var getFolderFromPath=grrUi.client.virtualFileSystem.utils.getFolderFromPath;grrUi.client.virtualFileSystem.recursiveListButtonDirective.RecursiveListButtonController=function($rootScope,$scope,$timeout,$uibModal,grrApiService,grrReflectionService){this.rootScope_=$rootScope;this.scope_=
$scope;this.timeout_=$timeout;this.uibModal_=$uibModal;this.grrApiService_=grrApiService;this.grrReflectionService_=grrReflectionService;this.lastOperationId;this.refreshOperation;this.done;this.error;this.modalInstance;this.scope_.$watchGroup(["clientId","filePath"],this.onClientOrPathChange_.bind(this))};var RecursiveListButtonController=grrUi.client.virtualFileSystem.recursiveListButtonDirective.RecursiveListButtonController;RecursiveListButtonController.MAX_DEPTH=5;RecursiveListButtonController.prototype.onClientOrPathChange_=
function(){this.lastOperationId=null};RecursiveListButtonController.prototype.onClick=function(){this.isDisabled=true;this.done=false;this.error=null;this.grrReflectionService_.getRDFValueDescriptor("ApiCreateVfsRefreshOperationArgs",true).then(function(descriptors){this.refreshOperation=angular.copy(descriptors["ApiCreateVfsRefreshOperationArgs"]["default"]);var filePath=angular.copy(descriptors["RDFString"]["default"]);filePath["value"]=getFolderFromPath(this.scope_["filePath"]);this.refreshOperation["value"]["file_path"]=
filePath;var maxDepth=angular.copy(descriptors["RDFInteger"]["default"]);maxDepth["value"]=RecursiveListButtonController.MAX_DEPTH;this.refreshOperation["value"]["max_depth"]=maxDepth;this.refreshOperation["value"]["notify_user"]=true;this.modalInstance=this.uibModal_.open({templateUrl:"/static/angular-components/client/virtual-file-system/"+"recursive-list-button-modal.html",scope:this.scope_})}.bind(this))};RecursiveListButtonController.prototype.createRefreshOperation=function(){var aff4Prefix=
"aff4:/";var clientId=this.scope_["clientId"];if(clientId.toLowerCase().indexOf(aff4Prefix)==0)clientId=clientId.substr(aff4Prefix.length);var url="clients/"+clientId+"/vfs-refresh-operations";var refreshOperation=angular.copy(this.refreshOperation);var operationId=this.lastOperationId="unknown";this.grrApiService_.post(url,refreshOperation,true).then(function success(response){this.done=true;this.timeout_(function(){this.modalInstance.close()}.bind(this),1E3);operationId=this.lastOperationId=response["data"]["operation_id"];
var pollPromise=this.grrApiService_.poll(url+"/"+operationId,OPERATION_POLL_INTERVAL_MS);this.scope_.$on("$destroy",function(){this.grrApiService_.cancelPoll(pollPromise)}.bind(this));return pollPromise}.bind(this),function failure(response){this.done=true;this.error=response["data"]["message"]||"Unknown error."}.bind(this)).then(function success(){var path=refreshOperation["value"]["file_path"]["value"];this.rootScope_.$broadcast(REFRESH_FOLDER_EVENT,ensurePathIsFolder(path))}.bind(this)).finally(function(){if(this.lastOperationId==
operationId)this.lastOperationId=null}.bind(this))};grrUi.client.virtualFileSystem.recursiveListButtonDirective.RecursiveListButtonDirective=function(){return{scope:{clientId:"=",filePath:"="},restrict:"E",templateUrl:"/static/angular-components/client/virtual-file-system/"+"recursive-list-button.html",controller:RecursiveListButtonController,controllerAs:"controller"}};grrUi.client.virtualFileSystem.recursiveListButtonDirective.RecursiveListButtonDirective.directive_name="grrRecursiveListButton"});goog.provide("grrUi.client.virtualFileSystem.vfsFilesArchiveButtonDirective.DOWNLOAD_EVERYTHING_REENABLE_DELAY");goog.provide("grrUi.client.virtualFileSystem.vfsFilesArchiveButtonDirective.VfsFilesArchiveButtonController");goog.provide("grrUi.client.virtualFileSystem.vfsFilesArchiveButtonDirective.VfsFilesArchiveButtonDirective");goog.require("grrUi.client.virtualFileSystem.utils.ensurePathIsFolder");goog.require("grrUi.client.virtualFileSystem.utils.getFolderFromPath");goog.require("grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective");
goog.scope(function(){var ERROR_EVENT_NAME=grrUi.core.serverErrorButtonDirective.ServerErrorButtonDirective.error_event_name;var ensurePathIsFolder=grrUi.client.virtualFileSystem.utils.ensurePathIsFolder;var getFolderFromPath=grrUi.client.virtualFileSystem.utils.getFolderFromPath;grrUi.client.virtualFileSystem.vfsFilesArchiveButtonDirective.DOWNLOAD_EVERYTHING_REENABLE_DELAY=3E4;var DOWNLOAD_EVERYTHING_REENABLE_DELAY=grrUi.client.virtualFileSystem.vfsFilesArchiveButtonDirective.DOWNLOAD_EVERYTHING_REENABLE_DELAY;
grrUi.client.virtualFileSystem.vfsFilesArchiveButtonDirective.VfsFilesArchiveButtonController=function($rootScope,$scope,$timeout,grrApiService){this.rootScope_=$rootScope;this.scope_=$scope;this.timeout_=$timeout;this.grrApiService_=grrApiService;this.downloadEverythingDisabled=false;this.downloadCurrentFolderDisabled=false;this.scope_.$watch("clientId",function(){this.downloadEverythingDisabled=false}.bind(this));this.scope_.$watch("filePath",function(value){this.downloadCurrentFolderDisabled=false}.bind(this))};
var VfsFilesArchiveButtonController=grrUi.client.virtualFileSystem.vfsFilesArchiveButtonDirective.VfsFilesArchiveButtonController;VfsFilesArchiveButtonController.prototype._download=function(path){var clientId=this.scope_["clientId"];var url="clients/"+clientId+"/vfs-files-archive/"+path;this.grrApiService_.downloadFile(url).then(function success(){}.bind(this),function failure(response){if(angular.isUndefined(response.status))this.rootScope_.$broadcast(ERROR_EVENT_NAME,{message:"Couldn't download the VFS archive."})}.bind(this))};
VfsFilesArchiveButtonController.prototype.downloadCurrentFolder=function(e){e.preventDefault();if(!this.downloadCurrentFolderDisabled){var folderPath=getFolderFromPath(this.scope_["filePath"]);this._download(folderPath);this.downloadCurrentFolderDisabled=true}};VfsFilesArchiveButtonController.prototype.downloadEverything=function(e){e.preventDefault();if(!this.downloadEverythingDisabled){this._download("");this.downloadEverythingDisabled=true;this.timeout_(function(){this.downloadEverythingDisabled=
false}.bind(this),DOWNLOAD_EVERYTHING_REENABLE_DELAY)}};grrUi.client.virtualFileSystem.vfsFilesArchiveButtonDirective.VfsFilesArchiveButtonDirective=function(){return{scope:{clientId:"=",filePath:"="},restrict:"E",templateUrl:"/static/angular-components/client/virtual-file-system/"+"vfs-files-archive-button.html",controller:VfsFilesArchiveButtonController,controllerAs:"controller"}};grrUi.client.virtualFileSystem.vfsFilesArchiveButtonDirective.VfsFilesArchiveButtonDirective.directive_name="grrVfsFilesArchiveButton"});goog.provide("grrUi.client.virtualFileSystem.module");goog.require("grrUi.client.virtualFileSystem.breadcrumbsDirective.BreadcrumbsDirective");goog.require("grrUi.client.virtualFileSystem.encodingsDropdownDirective.EncodingsDropdownDirective");goog.require("grrUi.client.virtualFileSystem.fileContextDirective.FileContextDirective");goog.require("grrUi.client.virtualFileSystem.fileDetailsDirective.FileDetailsDirective");goog.require("grrUi.client.virtualFileSystem.fileDownloadViewDirective.FileDownloadViewDirective");
goog.require("grrUi.client.virtualFileSystem.fileHexViewDirective.FileHexViewDirective");goog.require("grrUi.client.virtualFileSystem.fileStatsViewDirective.FileStatsViewDirective");goog.require("grrUi.client.virtualFileSystem.fileTableDirective.FileTableDirective");goog.require("grrUi.client.virtualFileSystem.fileTextViewDirective.FileTextViewDirective");goog.require("grrUi.client.virtualFileSystem.fileTimelineDirective.FileTimelineDirective");goog.require("grrUi.client.virtualFileSystem.fileTreeDirective.FileTreeDirective");
goog.require("grrUi.client.virtualFileSystem.fileViewDirective.FileViewDirective");goog.require("grrUi.client.virtualFileSystem.rWeOwnedButtonDirective.RWeOwnedButtonDirective");goog.require("grrUi.client.virtualFileSystem.recursiveListButtonDirective.RecursiveListButtonDirective");goog.require("grrUi.client.virtualFileSystem.vfsFilesArchiveButtonDirective.VfsFilesArchiveButtonDirective");goog.require("grrUi.core.module");goog.require("grrUi.semantic.module");
grrUi.client.virtualFileSystem.module=angular.module("grrUi.client.virtualFileSystem",[grrUi.core.module.name,grrUi.semantic.module.name]);grrUi.client.virtualFileSystem.module.directive(grrUi.client.virtualFileSystem.breadcrumbsDirective.BreadcrumbsDirective.directive_name,grrUi.client.virtualFileSystem.breadcrumbsDirective.BreadcrumbsDirective);grrUi.client.virtualFileSystem.module.directive(grrUi.client.virtualFileSystem.encodingsDropdownDirective.EncodingsDropdownDirective.directive_name,grrUi.client.virtualFileSystem.encodingsDropdownDirective.EncodingsDropdownDirective);
grrUi.client.virtualFileSystem.module.directive(grrUi.client.virtualFileSystem.fileContextDirective.FileContextDirective.directive_name,grrUi.client.virtualFileSystem.fileContextDirective.FileContextDirective);grrUi.client.virtualFileSystem.module.directive(grrUi.client.virtualFileSystem.fileDetailsDirective.FileDetailsDirective.directive_name,grrUi.client.virtualFileSystem.fileDetailsDirective.FileDetailsDirective);
grrUi.client.virtualFileSystem.module.directive(grrUi.client.virtualFileSystem.fileDownloadViewDirective.FileDownloadViewDirective.directive_name,grrUi.client.virtualFileSystem.fileDownloadViewDirective.FileDownloadViewDirective);grrUi.client.virtualFileSystem.module.directive(grrUi.client.virtualFileSystem.fileHexViewDirective.FileHexViewDirective.directive_name,grrUi.client.virtualFileSystem.fileHexViewDirective.FileHexViewDirective);
grrUi.client.virtualFileSystem.module.directive(grrUi.client.virtualFileSystem.fileStatsViewDirective.FileStatsViewDirective.directive_name,grrUi.client.virtualFileSystem.fileStatsViewDirective.FileStatsViewDirective);grrUi.client.virtualFileSystem.module.directive(grrUi.client.virtualFileSystem.fileTableDirective.FileTableDirective.directive_name,grrUi.client.virtualFileSystem.fileTableDirective.FileTableDirective);
grrUi.client.virtualFileSystem.module.directive(grrUi.client.virtualFileSystem.fileTimelineDirective.FileTimelineDirective.directive_name,grrUi.client.virtualFileSystem.fileTimelineDirective.FileTimelineDirective);grrUi.client.virtualFileSystem.module.directive(grrUi.client.virtualFileSystem.fileTextViewDirective.FileTextViewDirective.directive_name,grrUi.client.virtualFileSystem.fileTextViewDirective.FileTextViewDirective);
grrUi.client.virtualFileSystem.module.directive(grrUi.client.virtualFileSystem.fileTreeDirective.FileTreeDirective.directive_name,grrUi.client.virtualFileSystem.fileTreeDirective.FileTreeDirective);grrUi.client.virtualFileSystem.module.directive(grrUi.client.virtualFileSystem.fileViewDirective.FileViewDirective.directive_name,grrUi.client.virtualFileSystem.fileViewDirective.FileViewDirective);
grrUi.client.virtualFileSystem.module.directive(grrUi.client.virtualFileSystem.recursiveListButtonDirective.RecursiveListButtonDirective.directive_name,grrUi.client.virtualFileSystem.recursiveListButtonDirective.RecursiveListButtonDirective);grrUi.client.virtualFileSystem.module.directive(grrUi.client.virtualFileSystem.vfsFilesArchiveButtonDirective.VfsFilesArchiveButtonDirective.directive_name,grrUi.client.virtualFileSystem.vfsFilesArchiveButtonDirective.VfsFilesArchiveButtonDirective);
grrUi.client.virtualFileSystem.module.directive(grrUi.client.virtualFileSystem.rWeOwnedButtonDirective.RWeOwnedButtonDirective.directive_name,grrUi.client.virtualFileSystem.rWeOwnedButtonDirective.RWeOwnedButtonDirective);goog.provide("grrUi.stats.auditChartDirective.AuditChartController");goog.provide("grrUi.stats.auditChartDirective.AuditChartDirective");goog.require("grrUi.core.apiService.stripTypeInfo");goog.require("grrUi.core.utils.upperCaseToTitleCase");
goog.scope(function(){var stripTypeInfo=grrUi.core.apiService.stripTypeInfo;grrUi.stats.auditChartDirective.AuditChartController=function($scope,$element){this.scope_=$scope;this.element_=$element;this.auditUsedFields;this.auditTitleCaseUsedFields;this.typedAuditRows;this.errorMsg="";this.scope_.$watch("typedData",function(typedData){if(angular.isDefined(typedData)&&angular.isDefined(typedData["value"]))this.initAuditChart_(typedData["value"]["audit_chart"])}.bind(this))};var AuditChartController=
grrUi.stats.auditChartDirective.AuditChartController;AuditChartController.prototype.initAuditChart_=function(typedAuditChartData){var auditChartData=stripTypeInfo(typedAuditChartData);this.auditUsedFields=undefined;this.auditTitleCaseUsedFields=undefined;this.typedAuditRows=undefined;if(angular.isUndefined(auditChartData["rows"])||auditChartData["rows"].length==0||angular.isUndefined(auditChartData["used_fields"])||auditChartData["used_fields"].length==0){this.errorMsg="No data to display.";return}this.auditUsedFields=
auditChartData["used_fields"];this.auditTitleCaseUsedFields=auditChartData["used_fields"].map(grrUi.core.utils.upperCaseToTitleCase);this.typedAuditRows=typedAuditChartData["value"]["rows"]};grrUi.stats.auditChartDirective.AuditChartDirective=function(){return{scope:{typedData:"="},restrict:"E",templateUrl:"/static/angular-components/stats/audit-chart.html",controller:AuditChartController,controllerAs:"controller"}};grrUi.stats.auditChartDirective.AuditChartDirective.directive_name="grrAuditChart"});goog.provide("grrUi.stats.chartDirective.ChartController");goog.provide("grrUi.stats.chartDirective.ChartDirective");goog.require("grrUi.core.apiService.stripTypeInfo");
goog.scope(function(){var stripTypeInfo=grrUi.core.apiService.stripTypeInfo;var DEFAULT_HOVER_TEXT="";grrUi.stats.chartDirective.ChartController=function($scope,$element){this.scope_=$scope;this.element_=$element;this.chartElement_=this.element_.find(".chart");this.hoverElement_=this.element_.find(".hover");this.hoverColor="#000";this.hoverText=DEFAULT_HOVER_TEXT;this.errorMsg="";this.scope_.$watch("typedData",function(){var typedData=this.scope_["typedData"];if(angular.isDefined(typedData)){var data=
stripTypeInfo(typedData);this.initChart_(data,typedData)}}.bind(this))};var ChartController=grrUi.stats.chartDirective.ChartController;ChartController.prototype.initChart_=function(data,typedData){this.hoverText=DEFAULT_HOVER_TEXT;this.errorMsg="";switch(data["representation_type"]){case "STACK_CHART":this.initStackChart_(data["stack_chart"]);break;case "PIE_CHART":this.initPieChart_(data["pie_chart"]);break;case "LINE_CHART":this.initLineChart_(data["line_chart"]);break;case "AUDIT_CHART":break;
default:this.errorMsg="Unexpected representation type."}};ChartController.prototype.initStackChart_=function(stackChartData){if(angular.isUndefined(stackChartData["data"])||stackChartData["data"].length==0){this.errorMsg="No data to display.";return}var specs=stackChartData["data"].map(function(series){return{label:series["label"],data:series["points"].map(function(point){return[point["x"],point["y"]]}.bind(this))}}.bind(this));var extractTicks=function(protoTick){return[protoTick["x"],protoTick["label"]]}.bind(this);
var x_ticks=undefined;var y_ticks=undefined;if(angular.isDefined(stackChartData["x_ticks"]))x_ticks=stackChartData["x_ticks"].map(extractTicks);if(angular.isDefined(stackChartData["y_ticks"]))y_ticks=stackChartData["y_ticks"].map(extractTicks);var barWidth=stackChartData["bar_width"]||.6;this.chartElement_.resize(function(){this.chartElement_.html("");$.plot($(this.chartElement_),specs,{series:{stack:true,bars:{show:true,barWidth:barWidth},label:{show:true,radius:.5},background:{opacity:.8}},grid:{hoverable:true,
clickable:true},xaxis:{min:0,ticks:x_ticks},yaxis:{min:0,ticks:y_ticks}})}.bind(this));this.chartElement_.bind("plothover",function(event,pos,obj){if(obj){this.hoverColor=obj.series.color;this.hoverText=obj.series.label+": "+(obj.datapoint[1]-obj.datapoint[2])}}.bind(this));this.chartElement_.resize()};ChartController.prototype.initPieChart_=function(pieChartData){if(angular.isUndefined(pieChartData["data"])||pieChartData["data"].length==0){this.errorMsg="No data to display.";return}var specs=pieChartData["data"].map(function(point){return{label:point["label"],
data:point["x"]}}.bind(this));this.chartElement_.resize(function(){this.chartElement_.html("");$.plot($(this.chartElement_),specs,{series:{pie:{show:true,label:{show:true,radius:.5,formatter:function(label,series){return'<div class="pie-label">'+label+"<br/>"+Math.round(series["percent"])+"%"+"</div>"},background:{opacity:.8}}}},grid:{hoverable:true,clickable:true}})}.bind(this));this.chartElement_.bind("plothover",function(event,pos,obj){if(obj){var percent=parseFloat(obj.series.percent).toFixed(2);
this.hoverColor=obj.series.color;this.hoverText=obj.series.label+" "+obj.series.data[0][1]+" ("+percent+"%)"}}.bind(this));this.chartElement_.resize()};ChartController.prototype.initLineChart_=function(lineChartData){if(angular.isUndefined(lineChartData["data"])||lineChartData["data"].length==0){this.errorMsg="No data to display.";return}var specs=lineChartData["data"].map(function(series){return{label:series["label"],data:series["points"].map(function(point){return[point["x"],point["y"]]}.bind(this))}}.bind(this));
this.chartElement_.resize(function(){this.chartElement_.html("");$.plot($(this.chartElement_),specs,{xaxis:{mode:"time",timeformat:"%y/%m/%d"},lines:{show:true},points:{show:true},zoom:{interactive:true},pan:{interactive:true},grid:{clickable:true,autohighlight:true}})}.bind(this));this.chartElement_.bind("plotclick",function(event,pos,obj){if(obj){var date=new Date(obj.datapoint[0]);this.hoverColor=obj.series.color;this.hoverText="On "+date.toDateString()+", there were "+obj.datapoint[1]+" "+obj.series.label+
" systems."}}.bind(this));this.chartElement_.resize()};grrUi.stats.chartDirective.ChartDirective=function(){return{scope:{typedData:"="},restrict:"E",templateUrl:"/static/angular-components/stats/chart.html",controller:ChartController,controllerAs:"controller"}};grrUi.stats.chartDirective.ChartDirective.directive_name="grrChart"});goog.provide("grrUi.stats.reportDescsService.ReportDescsService");goog.require("grrUi.core.apiService.stripTypeInfo");
goog.scope(function(){grrUi.stats.reportDescsService.ReportDescsService=function($q,grrApiService){this.q_=$q;this.grrApiService_=grrApiService;this.reports_;this.descsByName_};var ReportDescsService=grrUi.stats.reportDescsService.ReportDescsService;ReportDescsService.service_name="grrReportDescsService";ReportDescsService.prototype.getDescs=function(){var deferred=this.q_.defer();if(angular.isDefined(this.reports_))deferred.resolve(this.reports_);else this.grrApiService_.get("stats/reports").then(function(response){this.reports_=
grrUi.core.apiService.stripTypeInfo(response["data"]["reports"]);deferred.resolve(this.reports_)}.bind(this));return deferred.promise};ReportDescsService.prototype.getDescByName=function(name){var deferred=this.q_.defer();if(angular.isDefined(this.descsByName_))deferred.resolve(this.descsByName_[name]);else this.getDescs().then(function(reports){this.descsByName_={};for(var i=0;i<reports.length;i++){var desc=reports[i]["desc"];this.descsByName_[desc["name"]]=desc}deferred.resolve(this.descsByName_[name])}.bind(this));
return deferred.promise}});goog.provide("grrUi.stats.reportDirective.ReportController");goog.provide("grrUi.stats.reportDirective.ReportDirective");goog.require("grrUi.core.apiService.stripTypeInfo");goog.require("grrUi.core.utils.upperCaseToTitleCase");
goog.scope(function(){var stripTypeInfo=grrUi.core.apiService.stripTypeInfo;var WEEK_SECONDS=7*24*60*60;var DEFAULT_START_TIME_SECS=Math.ceil(moment().valueOf()/1E3-WEEK_SECONDS);var DEFAULT_DURATION_SECS=WEEK_SECONDS;var DEFAULT_CLIENT_LABEL="";grrUi.stats.reportDirective.ReportController=function($scope,grrApiService,grrReflectionService,grrTimeService,grrReportDescsService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrReflectionService_=grrReflectionService;this.grrTimeService_=
grrTimeService;this.grrReportDescsService_=grrReportDescsService;this.state="INITIAL";this.titleCasedType;this.typedReportData;this.reportData;this.reportDesc;this.startTime=null;this.duration=null;this.clientLabel=null;this.latestFetchTime_=0;this.scope_.$watch("name",function(name){this.grrReportDescsService_.getDescByName(name).then(function(desc){if(angular.isUndefined(desc))return;this.reportDesc=desc;this.titleCasedType=grrUi.core.utils.upperCaseToTitleCase(this.reportDesc["type"]);this.onParamsChange_()}.bind(this))}.bind(this));
this.scope_.$watchGroup(["startTime","duration","clientLabel"],this.onParamsChange_.bind(this))};var ReportController=grrUi.stats.reportDirective.ReportController;ReportController.prototype.onParamsChange_=function(){var startTime=this.scope_["startTime"];if(angular.isDefined(startTime))this.startTime=startTime;var duration=this.scope_["duration"];if(angular.isDefined(duration))this.duration=duration;var clientLabel=this.scope_["clientLabel"];if(angular.isDefined(clientLabel))this.clientLabel=clientLabel;
this.fetchData_()};ReportController.prototype.refreshReport=function(){this.scope_["startTime"]=this.startTime;this.scope_["duration"]=this.duration;this.scope_["clientLabel"]=this.clientLabel};ReportController.prototype.fetchData_=function(){if(angular.isUndefined(this.reportDesc))return;var name=this.reportDesc["name"];if(!name)return;this.state="LOADING";var startTime=DEFAULT_START_TIME_SECS;if(this.startTime!==null)startTime=this.startTime;var duration=DEFAULT_DURATION_SECS;if(this.duration!==
null)duration=this.duration;var clientLabel=DEFAULT_CLIENT_LABEL;if(this.clientLabel!==null)clientLabel=this.clientLabel;var apiUrl="stats/reports/"+name;var apiParams={start_time:startTime*1E6,duration:duration,client_label:clientLabel};if(this.reportDesc["requires_time_range"]){this.startTime=startTime;this.duration=duration}if(this.reportDesc["type"]==="CLIENT")this.clientLabel=clientLabel;var fetchTime=this.grrTimeService_.getCurrentTimeMs();this.latestFetchTime_=fetchTime;this.grrApiService_.get(apiUrl,
apiParams).then(function(response){if(fetchTime!==this.latestFetchTime_)return;this.typedReportData=response["data"]["data"];this.reportData=stripTypeInfo(this.typedReportData);this.state="LOADED"}.bind(this))};grrUi.stats.reportDirective.ReportDirective=function(){return{scope:{name:"=?",startTime:"=?",duration:"=?",clientLabel:"=?"},restrict:"E",templateUrl:"/static/angular-components/stats/report.html",controller:ReportController,controllerAs:"controller"}};grrUi.stats.reportDirective.ReportDirective.directive_name=
"grrReport"});goog.provide("grrUi.stats.reportListingDirective.ReportListingController");goog.provide("grrUi.stats.reportListingDirective.ReportListingDirective");goog.provide("grrUi.stats.reportListingDirective.parseStatsReportsApiResponse");goog.require("grrUi.core.utils.upperCaseToTitleCase");
goog.scope(function(){grrUi.stats.reportListingDirective.parseStatsReportsApiResponse=function(reports){var ret=[];var reportsByType={};angular.forEach(reports,function(report){var desc=report["desc"];var reportType=desc["type"];var typeReportListing;if(angular.isUndefined(reportsByType[reportType])){typeReportListing=[];reportsByType[reportType]=typeReportListing;ret.push({text:grrUi.core.utils.upperCaseToTitleCase(reportType),children:typeReportListing,state:{opened:true,disabled:true}})}else typeReportListing=
reportsByType[reportType];var leaf={id:desc["name"],text:desc["title"],desc:desc};typeReportListing.push(leaf)});return ret};var parseStatsReportsApiResponse=grrUi.stats.reportListingDirective.parseStatsReportsApiResponse;grrUi.stats.reportListingDirective.ReportListingController=function($scope,$element,grrReportDescsService){this.scope_=$scope;this.element_=$element;this.grrReportDescsService_=grrReportDescsService;this.treeElement_=this.element_.find(".report-listing-tree");this.tree_;this.selectionName_;
this.reportListing_;this.grrReportDescsService_.getDescs().then(function(reports){this.reportListing_=parseStatsReportsApiResponse(reports);this.initTree_()}.bind(this));this.scope_.$watch("selectionName",function(selectionName){if(angular.isUndefined(selectionName))return;this.selectionName_=selectionName}.bind(this));this.scope_.$watch("controller.selectionName_",function(){if(angular.isUndefined(this.selectionName_))return;this.scope_["selectionName"]=this.selectionName_;this.updateTreeSelection_()}.bind(this))};
var ReportListingController=grrUi.stats.reportListingDirective.ReportListingController;ReportListingController.prototype.initTree_=function(){this.treeElement_.jstree({"core":{"data":this.reportListing_}});this.tree_=this.treeElement_.jstree(true);this.treeElement_.on("loaded.jstree",function(event,data){this.updateTreeSelection_()}.bind(this));this.treeElement_.on("select_node.jstree",function(event,data){var desc=data["node"]["original"]["desc"];this.selectionName_=desc["name"]}.bind(this))};ReportListingController.prototype.updateTreeSelection_=
function(){if(angular.isUndefined(this.tree_))return;this.tree_["deselect_all"]();this.tree_["select_node"](this.selectionName_)};grrUi.stats.reportListingDirective.ReportListingDirective=function(){return{restrict:"E",scope:{selectionName:"=?"},templateUrl:"/static/angular-components/stats/report-listing.html",controller:ReportListingController,controllerAs:"controller"}};grrUi.stats.reportListingDirective.ReportListingDirective.directive_name="grrReportListing"});goog.provide("grrUi.stats.serverLoadDirective.ServerLoadController");goog.provide("grrUi.stats.serverLoadDirective.ServerLoadDirective");goog.provide("grrUi.stats.serverLoadDirective.ServerLoadIndicatorService");
goog.scope(function(){grrUi.stats.serverLoadDirective.ServerLoadIndicatorService=function($q,grrApiService){this.q_=$q;this.grrApiService_=grrApiService};var ServerLoadIndicatorService=grrUi.stats.serverLoadDirective.ServerLoadIndicatorService;ServerLoadIndicatorService.service_name="grrServerLoadIndicatorService";ServerLoadIndicatorService.prototype.calculateMean_=function(timeseries){if(timeseries.length==0)return 0;var result=0;for(var i=0;i<timeseries.length;++i){var dataPoint=timeseries[i];if(dataPoint.length!=
2)throw new Error("Invalid data: timeseries data point is not an array "+"with 2 numbers.");result+=dataPoint[1]}return result/timeseries.length};ServerLoadIndicatorService.prototype.fetchRatioIndicator=function(component,numeratorMetric,denominatorMetric,warningRatio,dangerRatio){var endTime=Math.round((new Date).getTime()*1E3);var startTime=endTime-10*60*1E6;var options={start:startTime,end:endTime,aggregation:"mean"};var metricsCache={numerator:undefined,denominator:undefined};var deferred=this.q_.defer();
var responseHandler=function(response){if(response.data["metric_name"]==numeratorMetric)metricsCache.numerator=this.calculateMean_(response.data["data_points"]);else if(response.data["metric_name"]==denominatorMetric)metricsCache.denominator=this.calculateMean_(response.data["data_points"]);else throw new Error("Unexpected metric name: "+response.data["metric_name"]);if(angular.isDefined(metricsCache.numerator)&&angular.isDefined(metricsCache.denominator))if(metricsCache.denominator==0)deferred.resolve("unknown");
else{var ratio=metricsCache.numerator/metricsCache.denominator;if(ratio>dangerRatio)deferred.resolve("danger");else if(ratio>warningRatio)deferred.resolve("warning");else deferred.resolve("normal")}};this.grrApiService_.get("stats/store/"+component.toUpperCase()+"/metrics/"+numeratorMetric,options).then(responseHandler.bind(this));this.grrApiService_.get("stats/store/"+component.toUpperCase()+"/metrics/"+denominatorMetric,options).then(responseHandler.bind(this));return deferred.promise};grrUi.stats.serverLoadDirective.ServerLoadController=
function($scope,grrServerLoadIndicatorService){this.scope_=$scope;this.grrServerLoadIndicatorService_=grrServerLoadIndicatorService;this.startTime;this.endTime;this.indicators={};this.duration=1;this.scope_.$watch("controller.duration",this.onDurationChange.bind(this))};var ServerLoadController=grrUi.stats.serverLoadDirective.ServerLoadController;ServerLoadController.prototype.onDurationChange=function(newValue){this.endTime=Math.round((new Date).getTime()*1E3);this.startTime=this.endTime-this.duration*
60*60*1E6;this.fetchIndicators_()};ServerLoadController.prototype.fetchIndicators_=function(){this.grrServerLoadIndicatorService_.fetchRatioIndicator("frontend","frontend_active_count","frontend_max_active_count",.35,.75).then(function(result){this.indicators["frontendLoad"]=result}.bind(this));this.grrServerLoadIndicatorService_.fetchRatioIndicator("worker","grr_threadpool_outstanding_tasks","grr_threadpool_threads",4,10).then(function(result){this.indicators["workerLoad"]=result}.bind(this))};grrUi.stats.serverLoadDirective.ServerLoadDirective=
function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/stats/server-load.html",controller:ServerLoadController,controllerAs:"controller"}};grrUi.stats.serverLoadDirective.ServerLoadDirective.directive_name="grrServerLoad"});goog.provide("grrUi.stats.serverLoadGraphSerieDirective.ServerLoadGraphSerieDirective");
goog.scope(function(){grrUi.stats.serverLoadGraphSerieDirective.ServerLoadGraphSerieDirective=function(){return{scope:{component:"@",metric:"@",rate:"@",aggregation:"@",distributionHandling:"@",label:"@"},restrict:"E",require:"^grrTimeseriesGraph",link:function(scope,element,attrs,grrTimeseriesGrpahCtrl){var options={};if(scope.distributionHandling)options["distribution_handling_mode"]=scope.distributionHandling;if(scope.aggregation)options["aggregation_mode"]=scope.aggregation;if(scope.rate)options["rate"]=
scope.rate;var path="stats/store/"+scope.component.toUpperCase()+"/metrics/"+scope.metric;grrTimeseriesGrpahCtrl.addSerieDescriptor({label:scope.label,requestPath:path,requestOptions:options})}}};grrUi.stats.serverLoadGraphSerieDirective.ServerLoadGraphSerieDirective.directive_name="grrServerLoadGraphSerie"});goog.provide("grrUi.stats.serverLoadIndicatorDirective.ServerLoadIndicatorController");goog.provide("grrUi.stats.serverLoadIndicatorDirective.ServerLoadIndicatorDirective");
goog.scope(function(){grrUi.stats.serverLoadIndicatorDirective.ServerLoadIndicatorController=function($scope){this.scope_=$scope;this.imageFile;this.files_={normal:"online.png",warning:"online-1d.png",danger:"offline.png",unknown:"unknown-indicator.png"};this.scope_.$watch("status",function(newValue){if(angular.isDefined(newValue)&&newValue!=="normal"&&newValue!=="warning"&&newValue!=="danger"&&newValue!=="unknown")throw new Error('status can be undefined or "normal", '+'"danger", "warning" or "unknown".');
if(angular.isUndefined(newValue))this.imageFile=this.files_["unknown"];else this.imageFile=this.files_[newValue]}.bind(this))};var ServerLoadIndicatorController=grrUi.stats.serverLoadIndicatorDirective.ServerLoadIndicatorController;grrUi.stats.serverLoadIndicatorDirective.ServerLoadIndicatorDirective=function(){return{scope:{status:"="},restrict:"E",templateUrl:"/static/angular-components/stats/"+"server-load-indicator.html",controller:ServerLoadIndicatorController,controllerAs:"controller"}};grrUi.stats.serverLoadIndicatorDirective.ServerLoadIndicatorDirective.directive_name=
"grrServerLoadIndicator"});goog.provide("grrUi.stats.statsViewDirective.StatsViewController");goog.provide("grrUi.stats.statsViewDirective.StatsViewDirective");
goog.scope(function(){grrUi.stats.statsViewDirective.StatsViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.selectionName;this.startTime;this.duration;this.clientLabel;this.oldSelectionName_;this.grrRoutingService_.uiOnParamsChanged(this.scope_,["name","start_time","duration","client_label"],this.onUrlParamsChange_.bind(this));this.scope_.$watchGroup(["controller.selectionName","controller.startTime","controller.duration","controller.clientLabel"],
this.onControllerParamsChange_.bind(this))};var StatsViewController=grrUi.stats.statsViewDirective.StatsViewController;StatsViewController.prototype.onUrlParamsChange_=function(unused_values,params){var selectionName=params["name"];if(angular.isDefined(selectionName))this.selectionName=selectionName;var startTimeStr=params["start_time"];if(angular.isDefined(startTimeStr))this.startTime=parseInt(startTimeStr,10);var durationStr=params["duration"];if(angular.isDefined(durationStr))this.duration=parseInt(durationStr,
10);var clientLabel=params["client_label"];if(angular.isDefined(clientLabel))this.clientLabel=clientLabel};StatsViewController.prototype.onControllerParamsChange_=function(){if(angular.isUndefined(this.selectionName))return;if(angular.isDefined(this.oldSelectionName_)&&this.oldSelectionName_!==this.selectionName){this.startTime=null;this.duration=null;this.clientLabel=null}this.oldSelectionName_=this.selectionName;var urlParams={name:this.selectionName};if(angular.isDefined(this.startTime))urlParams["start_time"]=
this.startTime;if(angular.isDefined(this.duration))urlParams["duration"]=this.duration;if(angular.isDefined(this.clientLabel))urlParams["client_label"]=this.clientLabel;this.grrRoutingService_.go("stats",urlParams)};grrUi.stats.statsViewDirective.StatsViewDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/stats/stats-view.html",controller:StatsViewController,controllerAs:"controller"}};grrUi.stats.statsViewDirective.StatsViewDirective.directive_name="grrStatsView"});goog.provide("grrUi.stats.timeseriesGraphDirective.TimeseriesGraphController");goog.provide("grrUi.stats.timeseriesGraphDirective.TimeseriesGraphDirective");goog.provide("grrUi.stats.timeseriesGraphDirective.TimeseriesGraphSerieDirective");
goog.scope(function(){grrUi.stats.timeseriesGraphDirective.TimeserieDescriptor;grrUi.stats.timeseriesGraphDirective.TimeseriesGraphController=function($scope,$element,$interval,grrApiService){this.scope_=$scope;this.element_=$element;this.interval_=$interval;this.grrApiService_=grrApiService;this.timeRange=[NaN,NaN];this.seriesDescriptors=[];this.fetchedSeries={};this.inProgress=false;this.scope_.$watch("startTime",this.onStartTimeChange_.bind(this));this.scope_.$watch("endTime",this.onEndTimeChange_.bind(this));
this.scope_.$watch("controller.timeRange",this.onConfigurationChange_.bind(this),true);this.scope_.$watch("controller.seriesDescriptors",this.onConfigurationChange_.bind(this),true)};var TimeseriesGraphController=grrUi.stats.timeseriesGraphDirective.TimeseriesGraphController;TimeseriesGraphController.prototype.onStartTimeChange_=function(newValue){this.timeRange[0]=newValue};TimeseriesGraphController.prototype.onEndTimeChange_=function(newValue){this.timeRange[1]=newValue};TimeseriesGraphController.prototype.computeDelta_=
function(points){if(points.length<2)return;var prevPointValue=points.shift()[1];for(var i=0;i<points.length;++i){var pointValue=points[i][1];points[i][1]=points[i][1]-prevPointValue;prevPointValue=pointValue}};TimeseriesGraphController.prototype.onConfigurationChange_=function(){this.inProgress=true;this.fetchedSeries={};angular.forEach(this.seriesDescriptors,function(descriptor){var options={start:this.timeRange[0],end:this.timeRange[1]};angular.extend(options,descriptor.requestOptions||{});var prevTimeRange=
this.timeRange.slice();this.grrApiService_.get(descriptor.requestPath,options).then(function(response){if(angular.equals(prevTimeRange,this.timeRange)){var serie=response["data"];serie["data_points"]=serie["data_points"]||[];if(this.scope_["computeDelta"])this.computeDelta_(serie["data_points"]);this.fetchedSeries[descriptor.label]=serie;this.buildGraphIfNeeded_()}}.bind(this))}.bind(this))};TimeseriesGraphController.prototype.addSerieDescriptor=function(descriptor){this.seriesDescriptors.push(descriptor)};
TimeseriesGraphController.prototype.buildGraphIfNeeded_=function(){if(Object.keys(this.fetchedSeries).length==this.seriesDescriptors.length){this.inProgress=false;var data=[];for(var label in this.fetchedSeries){var item=this.fetchedSeries[label];data.push({label:label,data:item["data_points"]})}var config={xaxis:{mode:"time",axisLabel:"Time"},yaxis:{axisLabel:label}};var intervalPromise=this.interval_(function(){var graphElement=$(this.element_).find(".timeseries-graph");if(graphElement){$.plot(graphElement,
data,config);this.interval_.cancel(intervalPromise)}}.bind(this),500,10)}};grrUi.stats.timeseriesGraphDirective.TimeseriesGraphDirective=function(){return{scope:{title:"@",computeDelta:"@",startTime:"=",endTime:"="},restrict:"E",templateUrl:"/static/angular-components/stats/timeseries-graph.html",transclude:true,controller:TimeseriesGraphController,controllerAs:"controller"}};grrUi.stats.timeseriesGraphDirective.TimeseriesGraphDirective.directive_name="grrTimeseriesGraph";grrUi.stats.timeseriesGraphDirective.TimeseriesGraphSerieDirective.directive_name=
"grrTimeseriesGraph"});goog.provide("grrUi.stats.module");goog.require("grrUi.core.module");goog.require("grrUi.stats.auditChartDirective.AuditChartDirective");goog.require("grrUi.stats.chartDirective.ChartDirective");goog.require("grrUi.stats.reportDescsService.ReportDescsService");goog.require("grrUi.stats.reportDirective.ReportDirective");goog.require("grrUi.stats.reportListingDirective.ReportListingDirective");goog.require("grrUi.stats.serverLoadDirective.ServerLoadDirective");goog.require("grrUi.stats.serverLoadDirective.ServerLoadIndicatorService");
goog.require("grrUi.stats.serverLoadGraphSerieDirective.ServerLoadGraphSerieDirective");goog.require("grrUi.stats.serverLoadIndicatorDirective.ServerLoadIndicatorDirective");goog.require("grrUi.stats.statsViewDirective.StatsViewDirective");goog.require("grrUi.stats.timeseriesGraphDirective.TimeseriesGraphDirective");grrUi.stats.module=angular.module("grrUi.stats",[grrUi.core.module.name]);grrUi.stats.module.directive(grrUi.stats.auditChartDirective.AuditChartDirective.directive_name,grrUi.stats.auditChartDirective.AuditChartDirective);
grrUi.stats.module.directive(grrUi.stats.chartDirective.ChartDirective.directive_name,grrUi.stats.chartDirective.ChartDirective);grrUi.stats.module.directive(grrUi.stats.reportDirective.ReportDirective.directive_name,grrUi.stats.reportDirective.ReportDirective);grrUi.stats.module.directive(grrUi.stats.reportListingDirective.ReportListingDirective.directive_name,grrUi.stats.reportListingDirective.ReportListingDirective);
grrUi.stats.module.directive(grrUi.stats.serverLoadDirective.ServerLoadDirective.directive_name,grrUi.stats.serverLoadDirective.ServerLoadDirective);grrUi.stats.module.directive(grrUi.stats.serverLoadGraphSerieDirective.ServerLoadGraphSerieDirective.directive_name,grrUi.stats.serverLoadGraphSerieDirective.ServerLoadGraphSerieDirective);grrUi.stats.module.directive(grrUi.stats.serverLoadIndicatorDirective.ServerLoadIndicatorDirective.directive_name,grrUi.stats.serverLoadIndicatorDirective.ServerLoadIndicatorDirective);
grrUi.stats.module.directive(grrUi.stats.statsViewDirective.StatsViewDirective.directive_name,grrUi.stats.statsViewDirective.StatsViewDirective);grrUi.stats.module.directive(grrUi.stats.timeseriesGraphDirective.TimeseriesGraphDirective.directive_name,grrUi.stats.timeseriesGraphDirective.TimeseriesGraphDirective);grrUi.stats.module.service(grrUi.stats.serverLoadDirective.ServerLoadIndicatorService.service_name,grrUi.stats.serverLoadDirective.ServerLoadIndicatorService);
grrUi.stats.module.service(grrUi.stats.reportDescsService.ReportDescsService.service_name,grrUi.stats.reportDescsService.ReportDescsService);goog.provide("grrUi.client.module");goog.require("grrUi.client.addClientsLabelsDialogDirective.AddClientsLabelsDialogDirective");goog.require("grrUi.client.checkClientAccessDirective.CheckClientAccessDirective");goog.require("grrUi.client.clientContextDirective.ClientContextDirective");goog.require("grrUi.client.clientCrashesDirective.ClientCrashesDirective");goog.require("grrUi.client.clientDialogService.ClientDialogService");goog.require("grrUi.client.clientLoadGraphSerieDirective.ClientLoadGraphSerieDirective");
goog.require("grrUi.client.clientLoadViewDirective.ClientLoadViewDirective");goog.require("grrUi.client.clientStatusIconsDirective.ClientStatusIconsDirective");goog.require("grrUi.client.clientUsernamesDirective.ClientUsernamesDirective");goog.require("grrUi.client.clientsListDirective.ClientsListDirective");goog.require("grrUi.client.debugRequestsViewDirective.DebugRequestsViewDirective");goog.require("grrUi.client.hostHistoryDialogDirective.HostHistoryDialogDirective");goog.require("grrUi.client.hostInfoDirective.HostInfoDirective");
goog.require("grrUi.client.removeClientsLabelsDialogDirective.RemoveClientsLabelsDialogDirective");goog.require("grrUi.client.virtualFileSystem.module");goog.require("grrUi.core.module");goog.require("grrUi.semantic.module");goog.require("grrUi.stats.module");grrUi.client.module=angular.module("grrUi.client",[grrUi.client.virtualFileSystem.module.name,grrUi.core.module.name,grrUi.semantic.module.name,grrUi.stats.module.name]);
grrUi.client.module.directive(grrUi.client.addClientsLabelsDialogDirective.AddClientsLabelsDialogDirective.directive_name,grrUi.client.addClientsLabelsDialogDirective.AddClientsLabelsDialogDirective);grrUi.client.module.directive(grrUi.client.checkClientAccessDirective.CheckClientAccessDirective.directive_name,grrUi.client.checkClientAccessDirective.CheckClientAccessDirective);grrUi.client.module.directive(grrUi.client.clientContextDirective.ClientContextDirective.directive_name,grrUi.client.clientContextDirective.ClientContextDirective);
grrUi.client.module.directive(grrUi.client.clientCrashesDirective.ClientCrashesDirective.directive_name,grrUi.client.clientCrashesDirective.ClientCrashesDirective);grrUi.client.module.directive(grrUi.client.clientsListDirective.ClientsListDirective.directive_name,grrUi.client.clientsListDirective.ClientsListDirective);grrUi.client.module.directive(grrUi.client.clientLoadGraphSerieDirective.ClientLoadGraphSerieDirective.directive_name,grrUi.client.clientLoadGraphSerieDirective.ClientLoadGraphSerieDirective);
grrUi.client.module.directive(grrUi.client.clientLoadViewDirective.ClientLoadViewDirective.directive_name,grrUi.client.clientLoadViewDirective.ClientLoadViewDirective);grrUi.client.module.directive(grrUi.client.clientStatusIconsDirective.ClientStatusIconsDirective.directive_name,grrUi.client.clientStatusIconsDirective.ClientStatusIconsDirective);grrUi.client.module.directive(grrUi.client.clientUsernamesDirective.ClientUsernamesDirective.directive_name,grrUi.client.clientUsernamesDirective.ClientUsernamesDirective);
grrUi.client.module.directive(grrUi.client.debugRequestsViewDirective.DebugRequestsViewDirective.directive_name,grrUi.client.debugRequestsViewDirective.DebugRequestsViewDirective);grrUi.client.module.directive(grrUi.client.hostHistoryDialogDirective.HostHistoryDialogDirective.directive_name,grrUi.client.hostHistoryDialogDirective.HostHistoryDialogDirective);grrUi.client.module.directive(grrUi.client.hostInfoDirective.HostInfoDirective.directive_name,grrUi.client.hostInfoDirective.HostInfoDirective);
grrUi.client.module.directive(grrUi.client.removeClientsLabelsDialogDirective.RemoveClientsLabelsDialogDirective.directive_name,grrUi.client.removeClientsLabelsDialogDirective.RemoveClientsLabelsDialogDirective);grrUi.core.module.service(grrUi.client.clientDialogService.ClientDialogService.service_name,grrUi.client.clientDialogService.ClientDialogService);goog.provide("grrUi.config.binariesListDirective.BinariesListController");goog.provide("grrUi.config.binariesListDirective.BinariesListDirective");goog.provide("grrUi.config.binariesListDirective.sortBinaries");
goog.scope(function(){grrUi.config.binariesListDirective.sortBinaries=function(binaries){return binaries.map(function(b){var newB=angular.copy(b);var pathComponents=newB["value"]["path"]["value"].split("/");newB["pathLen"]=pathComponents.length;newB["baseName"]=pathComponents.pop();newB["dirName"]=pathComponents.join("/");return newB}).sort(function(a,b){if(a["pathLen"]!==b["pathLen"])return b["pathLen"]-a["pathLen"];return a["value"]["path"]["value"].localeCompare(b["value"]["path"]["value"])})};
var sortBinaries=grrUi.config.binariesListDirective.sortBinaries;grrUi.config.binariesListDirective.BinariesListController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.binaries;this.scope_.$watchGroup(["binaries","binaryType"],this.onBinariesChange_.bind(this))};var BinariesListController=grrUi.config.binariesListDirective.BinariesListController;BinariesListController.prototype.onBinariesChange_=function(){this.binaries=[];if(angular.isDefined(this.scope_["binaries"])){var filteredBinaries=
this.scope_["binaries"].filter(function(b){return b["value"]["type"]["value"]===this.scope_["typeFilter"]}.bind(this));this.binaries=sortBinaries(filteredBinaries)}};BinariesListController.prototype.onBinaryClicked=function(binary){var url="/config/binaries"+"/"+binary["value"]["type"]["value"]+"/"+binary["value"]["path"]["value"];this.grrApiService_.downloadFile(url)};grrUi.config.binariesListDirective.BinariesListDirective=function(){return{restrict:"E",scope:{binaries:"=",typeFilter:"@"},templateUrl:"/static/angular-components/config/binaries-list.html",
controller:BinariesListController,controllerAs:"controller"}};grrUi.config.binariesListDirective.BinariesListDirective.directive_name="grrBinariesList"});goog.provide("grrUi.config.configBinariesViewDirective.ConfigBinariesViewController");goog.provide("grrUi.config.configBinariesViewDirective.ConfigBinariesViewDirective");
goog.scope(function(){grrUi.config.configBinariesViewDirective.ConfigBinariesViewController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.binaries;this.grrApiService_.get("/config/binaries").then(function(response){this.binaries=response["data"]["items"]}.bind(this))};var ConfigBinariesViewController=grrUi.config.configBinariesViewDirective.ConfigBinariesViewController;grrUi.config.configBinariesViewDirective.ConfigBinariesViewDirective=function(){return{restrict:"E",
scope:{},templateUrl:"/static/angular-components/config/config-binaries-view.html",controller:ConfigBinariesViewController,controllerAs:"controller"}};grrUi.config.configBinariesViewDirective.ConfigBinariesViewDirective.directive_name="grrConfigBinariesView"});goog.provide("grrUi.config.configViewDirective.ConfigViewController");goog.provide("grrUi.config.configViewDirective.ConfigViewDirective");
goog.scope(function(){grrUi.config.configViewDirective.ConfigViewController=function($scope,$http){$http.get("/api/config").then(function(config){this.items={};angular.forEach(config["data"]["sections"],function(section){var sectionName=section["value"]["name"]["value"];var sectionOptions=section["value"]["options"];this.items[sectionName]={};angular.forEach(sectionOptions,function(option){this.items[sectionName][option["value"]["name"]["value"]]=option}.bind(this))}.bind(this))}.bind(this))};var ConfigViewController=
grrUi.config.configViewDirective.ConfigViewController;grrUi.config.configViewDirective.ConfigViewDirective=function(){return{restrict:"E",scope:{},templateUrl:"/static/angular-components/config/config-view.html",controller:ConfigViewController,controllerAs:"controller"}};grrUi.config.configViewDirective.ConfigViewDirective.directive_name="grrConfigView"});goog.provide("grrUi.config.module");goog.require("grrUi.config.binariesListDirective.BinariesListDirective");goog.require("grrUi.config.configBinariesViewDirective.ConfigBinariesViewDirective");goog.require("grrUi.config.configViewDirective.ConfigViewDirective");goog.require("grrUi.core.module");grrUi.config.module=angular.module("grrUi.config",[grrUi.core.module.name]);grrUi.config.module.directive(grrUi.config.binariesListDirective.BinariesListDirective.directive_name,grrUi.config.binariesListDirective.BinariesListDirective);
grrUi.config.module.directive(grrUi.config.configBinariesViewDirective.ConfigBinariesViewDirective.directive_name,grrUi.config.configBinariesViewDirective.ConfigBinariesViewDirective);grrUi.config.module.directive(grrUi.config.configViewDirective.ConfigViewDirective.directive_name,grrUi.config.configViewDirective.ConfigViewDirective);goog.provide("grrUi.cron.cronJobFlowsListDirective.CronJobFlowsListController");goog.provide("grrUi.cron.cronJobFlowsListDirective.CronJobFlowsListDirective");
goog.scope(function(){grrUi.cron.cronJobFlowsListDirective.CronJobFlowsListController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.flowsUrl;this.cronJobId;this.selectedFlowId;this.scope_.$watch("cronJobUrn",this.onCronJobUrnChange_.bind(this))};var CronJobFlowsListController=grrUi.cron.cronJobFlowsListDirective.CronJobFlowsListController;CronJobFlowsListController.prototype.onCronJobUrnChange_=function(cronJobUrn){if(angular.isString(cronJobUrn)){var components=
cronJobUrn.split("/");this.cronJobId=components[components.length-1];this.flowsUrl="/cron-jobs/"+this.cronJobId+"/flows"}};CronJobFlowsListController.prototype.closeDetails=function(){this.selectedFlowId=null};grrUi.cron.cronJobFlowsListDirective.CronJobFlowsListDirective=function(){return{scope:{cronJobUrn:"=",selectedFlowUrn:"=?"},restrict:"E",templateUrl:"/static/angular-components/cron/cron-job-flows-list.html",controller:CronJobFlowsListController,controllerAs:"controller"}};grrUi.cron.cronJobFlowsListDirective.CronJobFlowsListDirective.directive_name=
"grrCronJobFlowsList"});goog.provide("grrUi.cron.cronJobInspectorDirective.CronJobInspectorDirective");goog.scope(function(){grrUi.cron.cronJobInspectorDirective.CronJobInspectorDirective=function(){return{scope:{cronJobUrn:"="},restrict:"E",templateUrl:"/static/angular-components/cron/cron-job-inspector.html"}};grrUi.cron.cronJobInspectorDirective.CronJobInspectorDirective.directive_name="grrCronJobInspector"});goog.provide("grrUi.cron.cronJobOverviewDirective.CronJobOverviewController");goog.provide("grrUi.cron.cronJobOverviewDirective.CronJobOverviewDirective");goog.require("grrUi.core.utils.stripAff4Prefix");
goog.scope(function(){var stripAff4Prefix=grrUi.core.utils.stripAff4Prefix;grrUi.cron.cronJobOverviewDirective.CronJobOverviewController=function($scope,grrApiService){this.scope_=$scope;this.scope_.cronJobUrn;this.grrApiService_=grrApiService;this.cronJob;this.cronJobId;this.scope_.$watch("cronJobUrn",this.onCronJobUrnChange.bind(this))};var CronJobOverviewController=grrUi.cron.cronJobOverviewDirective.CronJobOverviewController;CronJobOverviewController.prototype.onCronJobUrnChange=function(newCronJobUrn){this.cronJob=
null;if(angular.isDefined(newCronJobUrn)){var cronJobUrnComponents=stripAff4Prefix(newCronJobUrn).split("/");this.cronJobId=cronJobUrnComponents[cronJobUrnComponents.length-1];this.grrApiService_.get("cron-jobs/"+this.cronJobId).then(this.onCronJobFetched.bind(this))}};CronJobOverviewController.prototype.onCronJobFetched=function(response){this.cronJob=response.data};grrUi.cron.cronJobOverviewDirective.CronJobOverviewDirective=function(){return{scope:{cronJobUrn:"="},restrict:"E",templateUrl:"/static/angular-components/cron/cron-job-overview.html",
controller:CronJobOverviewController,controllerAs:"controller"}};grrUi.cron.cronJobOverviewDirective.CronJobOverviewDirective.directive_name="grrCronJobOverview"});goog.provide("grrUi.cron.cronJobStatusIconDirective.CronJobStatusIconController");goog.provide("grrUi.cron.cronJobStatusIconDirective.CronJobStatusIconDirective");goog.scope(function(){grrUi.cron.cronJobStatusIconDirective.CronJobStatusIconDirective=function(){return{scope:{cronJob:"="},restrict:"E",templateUrl:"/static/angular-components/cron/cron-job-status-icon.html"}};grrUi.cron.cronJobStatusIconDirective.CronJobStatusIconDirective.directive_name="grrCronJobStatusIcon"});goog.provide("grrUi.cron.cronJobsListDirective.CronJobsListController");goog.provide("grrUi.cron.cronJobsListDirective.CronJobsListDirective");goog.require("grrUi.core.utils.stripAff4Prefix");
goog.scope(function(){grrUi.cron.cronJobsListDirective.CronJobsListController=function($scope,$uibModal,$q,grrTimeService,grrApiService,grrDialogService,grrAclDialogService){this.scope_=$scope;this.uibModal_=$uibModal;this.q_=$q;this.timeService_=grrTimeService;this.grrApiService_=grrApiService;this.grrDialogService_=grrDialogService;this.grrAclDialogService_=grrAclDialogService;this.cronJobsByUrn={};this.selectedCronJobUrn;this.triggerUpdate;this.ooCronHuntsEnabled;this.scope_.$watch("controller.selectedCronJobUrn",
function(newValue){if(angular.isDefined(newValue))this.scope_["selectedCronJobUrn"]=newValue}.bind(this));this.scope_.$watch("selectedCronJobUrn",function(newValue){if(angular.isDefined(newValue))this.selectedCronJobUrn=newValue}.bind(this))};var CronJobsListController=grrUi.cron.cronJobsListDirective.CronJobsListController;CronJobsListController.prototype.cronUrl="/cron-jobs";CronJobsListController.prototype.wrapApiPromise_=function(promise,successMessage){return promise.then(function success(){return successMessage}.bind(this),
function failure(response){var message=response["data"]["message"];if(response["status"]===403){var subject=response["data"]["subject"];var cronJobId=grrUi.core.utils.stripAff4Prefix(subject).split("/")[1];this.grrAclDialogService_.openRequestCronJobApprovalDialog(cronJobId,message)}return this.q_.reject(message)}.bind(this))};CronJobsListController.prototype.buildCronJobUrl_=function(cronJobUrn){var cronJobId=cronJobUrn.split("/")[2];return"cron-jobs/"+cronJobId};CronJobsListController.prototype.selectItem=
function(item){this.selectedCronJobUrn=item["value"]["urn"]["value"]};CronJobsListController.prototype.transformItems=function(items){items=angular.copy(items);angular.forEach(items,function(item,index){var urn=item["value"]["urn"]["value"];this.cronJobsByUrn[urn]=item;var components=urn.split("/");item.shortUrn=components[components.length-1];var periodicity=item["value"]["periodicity"]["value"];var currentTime=this.timeService_.getCurrentTimeMs()/1E3;var last_run_time;if(angular.isDefined(item["value"]["last_run_time"]))last_run_time=
item["value"]["last_run_time"]["value"]/1E3;else last_run_time=0;item.isStuck=currentTime-last_run_time>periodicity*2}.bind(this));return items};CronJobsListController.prototype.newCronJob=function(){var modalScope=this.scope_.$new();modalScope.resolve=function(){modalInstance.close()};modalScope.reject=function(){modalInstance.dismiss()};this.scope_.$on("$destroy",function(){modalScope.$destroy()});modalScope.result={};var modalInstance=this.uibModal_.open({template:'<grr-new-cron-job-wizard-form on-resolve="resolve()" '+
'on-reject="reject()" cron-job="result.cronJob" />',scope:modalScope,windowClass:"wide-modal high-modal",size:"lg"});modalInstance.result.then(function resolve(){this.triggerUpdate();this.selectedCronJobUrn=modalScope["result"]["cronJob"]["value"]["urn"]["value"]}.bind(this))};CronJobsListController.prototype.enableCronJob=function(){var modalPromise=this.grrDialogService_.openConfirmation("Enable this cron job?","Are you sure you want to ENABLE this cron job?",function(){var promise=this.grrApiService_.patch(this.buildCronJobUrl_(this.selectedCronJobUrn),
{state:"ENABLED"});return this.wrapApiPromise_(promise,"Cron job was ENABLED successfully!")}.bind(this));modalPromise.then(function resolve(){this.triggerUpdate()}.bind(this),function dismiss(){this.triggerUpdate()}.bind(this))};CronJobsListController.prototype.disableCronJob=function(){var modalPromise=this.grrDialogService_.openConfirmation("Disable this cron job?","Are you sure you want to DISABLE this cron job?",function(){var promise=this.grrApiService_.patch(this.buildCronJobUrl_(this.selectedCronJobUrn),
{state:"DISABLED"});return this.wrapApiPromise_(promise,"Cron job was DISABLED successfully!")}.bind(this));modalPromise.then(function resolve(){this.triggerUpdate()}.bind(this),function dismiss(){this.triggerUpdate()}.bind(this))};CronJobsListController.prototype.showDeleteCronJobConfirmation=function(){var dialogResult=this.grrDialogService_.openConfirmation("Delete cron job","Are you sure you want to DELETE this cron job?",this.deleteCronJob_.bind(this));dialogResult.then(function resolve(){this.triggerUpdate()}.bind(this))};
CronJobsListController.prototype.deleteCronJob_=function(){var url=this.buildCronJobUrl_(this.selectedCronJobUrn);var deferred=this.q_.defer();this.grrApiService_.delete(url).then(function success(){deferred.resolve("Cron job was deleted successfully!")},function failure(response){if(response.status===403){var headers=response.headers();this.grrAclDialogService_.openRequestCronJobApprovalDialog(headers["x-grr-unauthorized-access-subject"],headers["x-grr-unauthorized-access-reason"])}else deferred.reject(response.data.message)}.bind(this));
return deferred.promise};CronJobsListController.prototype.forceRunCronJob=function(){var modalPromise=this.grrDialogService_.openConfirmation("Force-run this cron job?","Are you sure you want to FORCE-RUN this cron job?",function(){var promise=this.grrApiService_.post(this.buildCronJobUrl_(this.selectedCronJobUrn)+"/actions/force-run");return this.wrapApiPromise_(promise,"Cron job flow was FORCE-STARTED successfully!")}.bind(this));modalPromise.then(function resolve(){this.triggerUpdate()}.bind(this),
function dismiss(){this.triggerUpdate()}.bind(this))};grrUi.cron.cronJobsListDirective.CronJobsListDirective=function(){return{scope:{selectedCronJobUrn:"=?"},restrict:"E",templateUrl:"/static/angular-components/cron/cron-jobs-list.html",controller:CronJobsListController,controllerAs:"controller"}};grrUi.cron.cronJobsListDirective.CronJobsListDirective.directive_name="grrCronJobsList"});goog.provide("grrUi.cron.cronViewDirective.CronViewController");goog.provide("grrUi.cron.cronViewDirective.CronViewDirective");
goog.scope(function(){grrUi.cron.cronViewDirective.CronViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.selectedCronJobUrn;this.scope_.$watch("controller.selectedCronJobUrn",this.onSelectedCronJobUrnChange_.bind(this));this.grrRoutingService_.uiOnParamsChanged(this.scope_,"cronJobId",this.onParamsChange_.bind(this))};var CronViewController=grrUi.cron.cronViewDirective.CronViewController;CronViewController.prototype.onParamsChange_=
function(cronJobId){if(cronJobId)this.selectedCronJobUrn="aff4:/cron/"+cronJobId};CronViewController.prototype.onSelectedCronJobUrnChange_=function(newValue){if(angular.isDefined(newValue)){var cronJobId=this.selectedCronJobUrn.split("/")[2];this.grrRoutingService_.go("crons",{cronJobId:cronJobId})}};grrUi.cron.cronViewDirective.CronViewDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/cron/cron-view.html",controller:CronViewController,controllerAs:"controller"}};
grrUi.cron.cronViewDirective.CronViewDirective.directive_name="grrCronView"});goog.provide("grrUi.cron.newCronJobWizard.configureSchedulePageDirective.ConfigureSchedulePageDirective");goog.scope(function(){grrUi.cron.newCronJobWizard.configureSchedulePageDirective.ConfigureSchedulePageDirective=function(){return{scope:{cronJob:"="},restrict:"E",templateUrl:"/static/angular-components/cron/new-cron-job-wizard/"+"configure-schedule-page.html",controllerAs:"controller"}};grrUi.cron.newCronJobWizard.configureSchedulePageDirective.ConfigureSchedulePageDirective.directive_name="grrConfigureSchedulePage"});goog.provide("grrUi.hunt.newHuntWizard.formDirective.DEFAULT_PLUGIN_URL");goog.provide("grrUi.hunt.newHuntWizard.formDirective.FormController");goog.provide("grrUi.hunt.newHuntWizard.formDirective.FormDirective");goog.require("grrUi.core.apiService.stripTypeInfo");
goog.scope(function(){grrUi.hunt.newHuntWizard.formDirective.DEFAULT_PLUGIN_URL="/config/"+"AdminUI.new_hunt_wizard.default_output_plugin";var DEFAULT_PLUGIN_URL=grrUi.hunt.newHuntWizard.formDirective.DEFAULT_PLUGIN_URL;var stripTypeInfo=grrUi.core.apiService.stripTypeInfo;grrUi.hunt.newHuntWizard.formDirective.FormController=function($scope,grrReflectionService,grrApiService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.grrApiService_=grrApiService;this.descriptors_={};
this.defaultOutputPluginName;this.configureFlowPageHasErrors;this.grrApiService_.get(DEFAULT_PLUGIN_URL).then(function(response){if(angular.isDefined(response["data"]["value"]))this.defaultOutputPluginName=response["data"]["value"]["value"];return this.grrReflectionService_.getRDFValueDescriptor("ApiCreateHuntArgs",true)}.bind(this)).then(function(descriptors){angular.extend(this.descriptors_,descriptors);this.scope_.$watch("createHuntArgs",this.onCreateHuntArgsChange_.bind(this))}.bind(this))};var FormController=
grrUi.hunt.newHuntWizard.formDirective.FormController;FormController.prototype.onCreateHuntArgsChange_=function(newValue){if(angular.isUndefined(newValue))newValue=this.scope_["createHuntArgs"]=angular.copy(this.descriptors_["ApiCreateHuntArgs"]["default"]);if(angular.isUndefined(newValue["value"]["flow_name"]))newValue["value"]["flow_name"]=angular.copy(this.descriptors_["RDFString"]["default"]);var hra=newValue["value"]["hunt_runner_args"];if(angular.isUndefined(hra))hra=newValue["value"]["hunt_runner_args"]=
angular.copy(this.descriptors_["HuntRunnerArgs"]["default"]);if(angular.isUndefined(hra["value"]["output_plugins"]))if(this.defaultOutputPluginName){var defaultPluginDescriptor=angular.copy(this.descriptors_["OutputPluginDescriptor"]["default"]);defaultPluginDescriptor["value"]["plugin_name"]=angular.copy(this.descriptors_["RDFString"]["default"]);defaultPluginDescriptor["value"]["plugin_name"]["value"]=this.defaultOutputPluginName;hra["value"]["output_plugins"]=[defaultPluginDescriptor]}else if(angular.isUndefined(newValue["value"]["output_plugins"]))hra["value"]["output_plugins"]=
[];if(angular.isUndefined(hra["value"]["client_rule_set"]))hra["value"]["client_rule_set"]=angular.copy(this.descriptors_["ForemanClientRuleSet"]["default"])};FormController.prototype.sendRequest=function(){this.grrApiService_.post("/hunts",stripTypeInfo(this.scope_["createHuntArgs"])).then(function resolve(response){this.serverResponse=response}.bind(this),function reject(response){this.serverResponse=response;this.serverResponse["error"]=true}.bind(this))};FormController.prototype.resolve=function(){var onResolve=
this.scope_["onResolve"];if(onResolve&&this.serverResponse){var huntUrn=this.serverResponse["data"]["value"]["urn"]["value"];onResolve({huntUrn:huntUrn})}};grrUi.hunt.newHuntWizard.formDirective.FormDirective=function(){return{scope:{createHuntArgs:"=?",onResolve:"&",onReject:"&"},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/form.html",controller:FormController,controllerAs:"controller"}};grrUi.hunt.newHuntWizard.formDirective.FormDirective.directive_name="grrNewHuntWizardForm"});goog.provide("grrUi.cron.newCronJobWizard.formDirective.FormController");goog.provide("grrUi.cron.newCronJobWizard.formDirective.FormDirective");goog.require("grrUi.hunt.newHuntWizard.formDirective.DEFAULT_PLUGIN_URL");
goog.scope(function(){var DEFAULT_PLUGIN_URL=grrUi.hunt.newHuntWizard.formDirective.DEFAULT_PLUGIN_URL;grrUi.cron.newCronJobWizard.formDirective.FormController=function($scope,grrReflectionService,grrApiService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.grrApiService_=grrApiService;this.descriptors_={};this.defaultOutputPluginName;this.grrApiService_.get(DEFAULT_PLUGIN_URL).then(function(response){if(angular.isDefined(response["data"]["value"]))this.defaultOutputPluginName=
response["data"]["value"]["value"];return this.grrReflectionService_.getRDFValueDescriptor("CreateGenericHuntFlowArgs",true)}.bind(this)).then(function(descriptors){angular.extend(this.descriptors_,descriptors);return this.grrReflectionService_.getRDFValueDescriptor("ApiCronJob",true)}.bind(this)).then(function(descriptors){angular.extend(this.descriptors_,descriptors);this.scope_.$watch("cronJob",this.onCronJobChange_.bind(this))}.bind(this));this.scope_.$watch("cronJob.value.flow_args.value.hunt_args",
function(newValue){this.genericHuntArgs=newValue}.bind(this));this.scope_.$watch("cronJob.value.flow_args.value.hunt_runner_args",function(newValue){this.huntRunnerArgs=newValue}.bind(this));this.scope_.$watch("cronJob.value.description.value",this.onCronJobDescriptionChange_.bind(this))};var FormController=grrUi.cron.newCronJobWizard.formDirective.FormController;FormController.prototype.onCronJobDescriptionChange_=function(newValue,oldValue){if(newValue&&this.huntRunnerArgs){oldValue=oldValue||"";
var huntDescription;if(angular.isDefined(this.huntRunnerArgs.value.description))huntDescription=this.huntRunnerArgs.value.description.value;var cronSuffix=" (cron)";if(angular.isUndefined(huntDescription)||huntDescription==oldValue+cronSuffix)this.huntRunnerArgs.value.description={type:"RDFString",value:newValue+cronSuffix}}};FormController.prototype.onCronJobChange_=function(newValue){if(angular.isUndefined(newValue))newValue=this.scope_["cronJob"]=angular.copy(this.descriptors_["ApiCronJob"]["default"]);
newValue["value"]["flow_name"]={type:"RDFString",value:"CreateAndRunGenericHuntFlow"};if(angular.isUndefined(newValue["value"]["periodicity"]))newValue["value"]["periodicity"]={type:"Duration",value:60*60*24*7};if(angular.isUndefined(newValue["value"]["lifetime"]))newValue["value"]["lifetime"]={type:"Duration",value:60*60*1};if(angular.isUndefined(newValue["value"]["flow_args"]))newValue["value"]["flow_args"]=angular.copy(this.descriptors_["CreateGenericHuntFlowArgs"]["default"]);var createHuntFlowArgs=
newValue["value"]["flow_args"]["value"];if(angular.isUndefined(createHuntFlowArgs["hunt_args"]))createHuntFlowArgs["hunt_args"]=angular.copy(this.descriptors_["GenericHuntArgs"]["default"]);var huntArgs=createHuntFlowArgs["hunt_args"]["value"];if(angular.isUndefined(huntArgs["flow_runner_args"]))huntArgs["flow_runner_args"]=angular.copy(this.descriptors_["FlowRunnerArgs"]["default"]);if(angular.isUndefined(huntArgs["flow_runner_args"]["value"]["flow_name"]))huntArgs["flow_runner_args"]["value"]["flow_name"]=
angular.copy(this.descriptors_["RDFString"]["default"]);if(angular.isUndefined(createHuntFlowArgs["hunt_runner_args"]))createHuntFlowArgs["hunt_runner_args"]=angular.copy(this.descriptors_["HuntRunnerArgs"]["default"]);var huntRunnerArgs=createHuntFlowArgs["hunt_runner_args"]["value"];if(angular.isUndefined(huntRunnerArgs["client_rule_set"]))huntRunnerArgs["client_rule_set"]=angular.copy(this.descriptors_["ForemanClientRuleSet"]["default"]);if(angular.isUndefined(huntRunnerArgs["output_plugins"]))if(this.defaultOutputPluginName){var defaultPluginDescriptor=
angular.copy(this.descriptors_["OutputPluginDescriptor"]["default"]);defaultPluginDescriptor["value"]["plugin_name"]=angular.copy(this.descriptors_["RDFString"]["default"]);defaultPluginDescriptor["value"]["plugin_name"]["value"]=this.defaultOutputPluginName;huntRunnerArgs["output_plugins"]=[defaultPluginDescriptor]}else huntRunnerArgs["output_plugins"]=[]};FormController.prototype.sendRequest=function(){this.grrApiService_.post("/cron-jobs",this.scope_["cronJob"],true).then(function resolve(response){this.serverResponse=
response;this.scope_["cronJob"]=response["data"]}.bind(this),function reject(response){this.serverResponse=response;this.serverResponse["error"]=true}.bind(this))};grrUi.cron.newCronJobWizard.formDirective.FormDirective=function(){return{scope:{cronJob:"=?",onResolve:"&",onReject:"&"},restrict:"E",templateUrl:"/static/angular-components/cron/new-cron-job-wizard/"+"form.html",controller:FormController,controllerAs:"controller"}};grrUi.cron.newCronJobWizard.formDirective.FormDirective.directive_name=
"grrNewCronJobWizardForm"});goog.provide("grrUi.cron.newCronJobWizard.reviewPageDirective.ReviewPageDirective");goog.scope(function(){grrUi.cron.newCronJobWizard.reviewPageDirective.ReviewPageDirective=function(){return{scope:{cronJob:"="},restrict:"E",templateUrl:"/static/angular-components/cron/new-cron-job-wizard/"+"review-page.html",controllerAs:"controller"}};grrUi.cron.newCronJobWizard.reviewPageDirective.ReviewPageDirective.directive_name="grrNewCronJobReviewPage"});goog.provide("grrUi.cron.newCronJobWizard.statusPageDirective.StatusPageDirective");goog.scope(function(){grrUi.cron.newCronJobWizard.statusPageDirective.StatusPageDirective=function(){return{scope:{response:"="},restrict:"E",templateUrl:"/static/angular-components/cron/new-cron-job-wizard/"+"status-page.html"}};grrUi.cron.newCronJobWizard.statusPageDirective.StatusPageDirective.directive_name="grrNewCronJobStatusPage"});goog.provide("grrUi.cron.newCronJobWizard.module");goog.require("grrUi.core.module");goog.require("grrUi.cron.newCronJobWizard.configureSchedulePageDirective.ConfigureSchedulePageDirective");goog.require("grrUi.cron.newCronJobWizard.formDirective.FormDirective");goog.require("grrUi.cron.newCronJobWizard.reviewPageDirective.ReviewPageDirective");goog.require("grrUi.cron.newCronJobWizard.statusPageDirective.StatusPageDirective");
grrUi.cron.newCronJobWizard.module=angular.module("grrUi.cron.newCronJobWizard",["ui.bootstrap",grrUi.core.module.name]);grrUi.cron.newCronJobWizard.module.directive(grrUi.cron.newCronJobWizard.formDirective.FormDirective.directive_name,grrUi.cron.newCronJobWizard.formDirective.FormDirective);grrUi.cron.newCronJobWizard.module.directive(grrUi.cron.newCronJobWizard.reviewPageDirective.ReviewPageDirective.directive_name,grrUi.cron.newCronJobWizard.reviewPageDirective.ReviewPageDirective);
grrUi.cron.newCronJobWizard.module.directive(grrUi.cron.newCronJobWizard.statusPageDirective.StatusPageDirective.directive_name,grrUi.cron.newCronJobWizard.statusPageDirective.StatusPageDirective);grrUi.cron.newCronJobWizard.module.directive(grrUi.cron.newCronJobWizard.configureSchedulePageDirective.ConfigureSchedulePageDirective.directive_name,grrUi.cron.newCronJobWizard.configureSchedulePageDirective.ConfigureSchedulePageDirective);goog.provide("grrUi.cron.module");goog.require("grrUi.core.module");goog.require("grrUi.cron.cronJobFlowsListDirective.CronJobFlowsListDirective");goog.require("grrUi.cron.cronJobInspectorDirective.CronJobInspectorDirective");goog.require("grrUi.cron.cronJobOverviewDirective.CronJobOverviewDirective");goog.require("grrUi.cron.cronJobStatusIconDirective.CronJobStatusIconDirective");goog.require("grrUi.cron.cronJobsListDirective.CronJobsListDirective");goog.require("grrUi.cron.cronViewDirective.CronViewDirective");
goog.require("grrUi.cron.newCronJobWizard.module");grrUi.cron.module=angular.module("grrUi.cron",[grrUi.core.module.name,grrUi.cron.newCronJobWizard.module.name]);grrUi.cron.module.directive(grrUi.cron.cronJobFlowsListDirective.CronJobFlowsListDirective.directive_name,grrUi.cron.cronJobFlowsListDirective.CronJobFlowsListDirective);grrUi.cron.module.directive(grrUi.cron.cronJobInspectorDirective.CronJobInspectorDirective.directive_name,grrUi.cron.cronJobInspectorDirective.CronJobInspectorDirective);
grrUi.cron.module.directive(grrUi.cron.cronJobsListDirective.CronJobsListDirective.directive_name,grrUi.cron.cronJobsListDirective.CronJobsListDirective);grrUi.cron.module.directive(grrUi.cron.cronJobOverviewDirective.CronJobOverviewDirective.directive_name,grrUi.cron.cronJobOverviewDirective.CronJobOverviewDirective);grrUi.cron.module.directive(grrUi.cron.cronJobStatusIconDirective.CronJobStatusIconDirective.directive_name,grrUi.cron.cronJobStatusIconDirective.CronJobStatusIconDirective);
grrUi.cron.module.directive(grrUi.cron.cronViewDirective.CronViewDirective.directive_name,grrUi.cron.cronViewDirective.CronViewDirective);goog.provide("grrUi.docs.apiDescriptionDirective.ApiDescriptionController");goog.provide("grrUi.docs.apiDescriptionDirective.ApiDescriptionDirective");
goog.scope(function(){grrUi.docs.apiDescriptionDirective.ApiDescriptionController=function($scope){this.scope_=$scope;this.paragraphs=[];this.scope_.$watch("::value",this.onValueChange.bind(this))};var ApiDescriptionController=grrUi.docs.apiDescriptionDirective.ApiDescriptionController;ApiDescriptionController.prototype.onValueChange=function(newValue){if(angular.isString(newValue))this.paragraphs=newValue.split("\n\n")};grrUi.docs.apiDescriptionDirective.ApiDescriptionDirective=function(){return{scope:{value:"="},
restrict:"E",templateUrl:"/static/angular-components/docs/api-description.html",controller:ApiDescriptionController,controllerAs:"controller"}};grrUi.docs.apiDescriptionDirective.ApiDescriptionDirective.directive_name="grrApiDescription"});goog.provide("grrUi.docs.apiDocsDirective.ApiCallHandlerDescriptor");goog.provide("grrUi.docs.apiDocsDirective.ApiDocsController");goog.provide("grrUi.docs.apiDocsDirective.ApiDocsDirective");goog.provide("grrUi.docs.apiDocsDirective.ApiObjectRendererDescriptor");goog.require("grrUi.core.apiService.stripTypeInfo");
goog.scope(function(){var stripTypeInfo=grrUi.core.apiService.stripTypeInfo;grrUi.docs.apiDocsDirective.ApiDocsController=function($element,$http,grrApiService){this.element_=$element;this.http_=$http;this.grrApiService_=grrApiService;this.apiMethodsByCategory;this.examplesByMethod;this.categories;this.visibleCategory;this.grrApiService_.get("reflection/api-methods").then(this.onApiMethodsListFetched_.bind(this));this.http_.get("/static/angular-components/docs/api-docs-examples.json").then(this.onExamplesFetched_.bind(this))};
var ApiDocsController=grrUi.docs.apiDocsDirective.ApiDocsController;ApiDocsController.prototype.onApiMethodsListFetched_=function(response){var categoriesDict={};var items=stripTypeInfo(response["data"]["items"]);angular.forEach(items,function(descriptor){var category=descriptor["category"];if(!category)category="Other";if(categoriesDict[category]===undefined)categoriesDict[category]=[];categoriesDict[category].push(descriptor)}.bind(this));angular.forEach(categoriesDict,function(descriptors){descriptors.sort(function(a,
b){var astr=a["name"]+"_"+a["http_route"];var bstr=b["name"]+"_"+b["http_route"];if(astr>bstr)return 1;else if(astr<bstr)return-1;else return 0})}.bind(this));this.apiMethodsByCategory=categoriesDict;this.categories=Object.keys(categoriesDict).sort();this.visibleCategory=this.categories[0]};ApiDocsController.prototype.onExamplesFetched_=function(response){this.examplesByMethod={};angular.forEach(response.data,function(handlerExamples){angular.forEach(handlerExamples,function(example){var apiMethod=
example["api_method"];if(!this.examplesByMethod[apiMethod])this.examplesByMethod[apiMethod]=[];this.examplesByMethod[apiMethod].push(example)}.bind(this))}.bind(this))};ApiDocsController.prototype.onCategoryLinkClick=function(category){var index=this.categories.indexOf(category);var headingElement=$("#docs-category-"+index.toString());var scrollableContainer=headingElement.parent();while(scrollableContainer.length!=0){if(scrollableContainer.scrollTop()>0||Math.abs(scrollableContainer[0].clientHeight-
scrollableContainer[0].scrollHeight)>1){var offset=headingElement.offset()["top"]-scrollableContainer.offset()["top"]+scrollableContainer.scrollTop();var prevOffset=scrollableContainer.scrollTop();scrollableContainer.scrollTop(offset);if(scrollableContainer.scrollTop()!=prevOffset||Math.abs(prevOffset-offset)<=1)break}scrollableContainer=scrollableContainer.parent()}};grrUi.docs.apiDocsDirective.ApiDocsDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/docs/api-docs.html",
controller:ApiDocsController,controllerAs:"controller"}};grrUi.docs.apiDocsDirective.ApiDocsDirective.directive_name="grrApiDocs"});goog.provide("grrUi.docs.apiHelperCurlService.ApiHelperCurlService");
goog.scope(function(){grrUi.docs.apiHelperCurlService.ApiHelperCurlService=function($q,$window){this.q_=$q;this.window_=$window};var ApiHelperCurlService=grrUi.docs.apiHelperCurlService.ApiHelperCurlService;ApiHelperCurlService.service_name="grrApiHelperCurlService";ApiHelperCurlService.prototype.buildStartFlow=function(clientId,createFlowJson){var deferred=this.q_.defer();var result="CSRFTOKEN=`curl "+this.window_.location.origin+" -o /dev/null -s -c - | grep csrftoken  | cut -f 7`; \\\n\t"+'curl -X POST -H "Content-Type: application/json" '+
'-H "X-CSRFToken: $CSRFTOKEN" \\\n\t'+this.window_.location.origin+"/api/v2/clients/"+clientId+"/flows -d @- << EOF\n";result+=JSON.stringify(createFlowJson,null,2);result+="\nEOF";deferred.resolve(result);return deferred.promise}});goog.provide("grrUi.docs.apiHelperService.ApiHelperService");
goog.scope(function(){grrUi.docs.apiHelperService.ApiHelperService=function($q,grrApiService){this.q_=$q;this.grrApiService_=grrApiService;this.helperTuples_=[]};var ApiHelperService=grrUi.docs.apiHelperService.ApiHelperService;ApiHelperService.service_name="grrApiHelperService";ApiHelperService.prototype.clear=function(){this.helperTuples_=[]};ApiHelperService.prototype.registerHelper=function(type,webAuthType,helper){this.helperTuples_.push([type,webAuthType,helper])};ApiHelperService.prototype.buildStartFlow_=
function(webAuthType,clientId,createFlowJson){var helpersByType={};for(var i=0;i<this.helperTuples_.length;++i){var helperTuple=this.helperTuples_[i];var helperType=helperTuple[0];var helperWebAuthType=helperTuple[1];if(!helpersByType[helperType]&&!helperWebAuthType||helperWebAuthType==webAuthType)helpersByType[helperType]=helperTuple}var result={};var promises=[];angular.forEach(helpersByType,function(helperTuple,key){var helperWebAuthType=helperTuple[1];var helper=helperTuple[2];var promise=helper["buildStartFlow"](clientId,
createFlowJson).then(function(data){result[key]={webAuthType:helperWebAuthType,data:data}}.bind(this));promises.push(promise)}.bind(this));return this.q_.all(promises).then(function(){return result}.bind(this))};ApiHelperService.prototype.buildStartFlow=function(clientId,createFlowJson){return this.grrApiService_.getCached("/config/AdminUI.webauth_manager").then(function(response){var webAuthType=response["data"]["value"]["value"];return this.buildStartFlow_(webAuthType,clientId,createFlowJson)}.bind(this))}});goog.provide("grrUi.docs.apiQuerySpecDirective.ApiQuerySpecController");goog.provide("grrUi.docs.apiQuerySpecDirective.ApiQuerySpecDirective");
goog.scope(function(){grrUi.docs.apiQuerySpecDirective.ApiQuerySpecController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.descriptorFields;this.descriptorsCache;this.typeHints={"RDFDatetime":"Time since epoch in microseconds.","RDFBool":"Either 1 or 0.","RDFURN":'Path string with components separated by "/", i.e. '+'"foo/bar/blah".'};this.scope_.$watch("argsType",this.onArgsTypeChange.bind(this))};var ApiQuerySpecController=grrUi.docs.apiQuerySpecDirective.ApiQuerySpecController;
ApiQuerySpecController.prototype.onArgsTypeChange=function(newValue){this.argsDescriptor=null;if(angular.isString(newValue))this.grrReflectionService_.getRDFValueDescriptor(newValue,true).then(function(result){this.descriptorFields=[];angular.forEach(result[newValue]["fields"],function(field){if(field.name!=="additional_args")this.descriptorFields.push(field)}.bind(this));this.descriptorsCache=result}.bind(this))};grrUi.docs.apiQuerySpecDirective.ApiQuerySpecDirective=function(){return{scope:{argsType:"=",
prefix:"=",noHeader:"@"},restrict:"E",templateUrl:"/static/angular-components/docs/api-query-spec.html",controller:ApiQuerySpecController,controllerAs:"controller"}};grrUi.docs.apiQuerySpecDirective.ApiQuerySpecDirective.directive_name="grrApiQuerySpec"});goog.provide("grrUi.docs.apiRouteDirective.ApiRouteController");goog.provide("grrUi.docs.apiRouteDirective.ApiRouteDirective");goog.provide("grrUi.docs.apiRouteDirective.RouteComponent");
goog.scope(function(){grrUi.docs.apiRouteDirective.RouteComponent;grrUi.docs.apiRouteDirective.ApiRouteController=function($scope){this.scope_=$scope;this.routeComponents;this.queryParameters;this.hasQueryParameters;this.scope_.$watch("::value",this.onValueChange.bind(this))};var ApiRouteController=grrUi.docs.apiRouteDirective.ApiRouteController;ApiRouteController.prototype.onValueChange=function(){var routeComponents=this.routeComponents=[];var queryParameters=this.queryParameters={};if(angular.isString(this.scope_.value)){var route=
this.scope_.value;var questionMarkIndex=route.indexOf("?");if(questionMarkIndex!=-1){var queryParamString=route.substring(questionMarkIndex+1,route.length);route=route.substring(0,questionMarkIndex);var vars=queryParamString.split("&");angular.forEach(vars,function(variable){var pair=variable.split("=");if(pair.length==2)queryParameters[pair[0]]=pair[1];else queryParameters[pair[0]]=null})}var components=route.split("/");angular.forEach(components,function(component){if(component.length>0)if(component[0]===
"<"){component=component.substring(1,component.length-1);var componentParts=component.split(":");var componentType,componentValue;if(componentParts.length===1){componentType="string";componentValue=componentParts[0]}else{componentType=componentParts[0];componentValue=componentParts[1]}routeComponents.push({type:componentType,value:componentValue})}else routeComponents.push({value:component})}.bind(this))}this.hasQueryParameters=Object.keys(queryParameters).length>0};grrUi.docs.apiRouteDirective.ApiRouteDirective=
function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/docs/api-route.html",controller:ApiRouteController,controllerAs:"controller"}};grrUi.docs.apiRouteDirective.ApiRouteDirective.directive_name="grrApiRoute"});goog.provide("grrUi.docs.module");goog.require("grrUi.core.module");goog.require("grrUi.docs.apiDescriptionDirective.ApiDescriptionDirective");goog.require("grrUi.docs.apiDocsDirective.ApiDocsDirective");goog.require("grrUi.docs.apiHelperCurlService.ApiHelperCurlService");goog.require("grrUi.docs.apiHelperService.ApiHelperService");goog.require("grrUi.docs.apiQuerySpecDirective.ApiQuerySpecDirective");goog.require("grrUi.docs.apiRouteDirective.ApiRouteDirective");
grrUi.docs.module=angular.module("grrUi.docs",[grrUi.core.module.name]);grrUi.docs.module.directive(grrUi.docs.apiDescriptionDirective.ApiDescriptionDirective.directive_name,grrUi.docs.apiDescriptionDirective.ApiDescriptionDirective);grrUi.docs.module.directive(grrUi.docs.apiDocsDirective.ApiDocsDirective.directive_name,grrUi.docs.apiDocsDirective.ApiDocsDirective);grrUi.docs.module.directive(grrUi.docs.apiRouteDirective.ApiRouteDirective.directive_name,grrUi.docs.apiRouteDirective.ApiRouteDirective);
grrUi.docs.module.directive(grrUi.docs.apiQuerySpecDirective.ApiQuerySpecDirective.directive_name,grrUi.docs.apiQuerySpecDirective.ApiQuerySpecDirective);grrUi.core.module.service(grrUi.docs.apiHelperService.ApiHelperService.service_name,grrUi.docs.apiHelperService.ApiHelperService);grrUi.core.module.service(grrUi.docs.apiHelperCurlService.ApiHelperCurlService.service_name,grrUi.docs.apiHelperCurlService.ApiHelperCurlService);
grrUi.docs.module.run(function(grrApiHelperService,grrApiHelperCurlService){grrApiHelperService.registerHelper("HTTP",null,grrApiHelperCurlService)});goog.provide("grrUi.flow.clientFlowsListDirective.ClientFlowsListController");goog.provide("grrUi.flow.clientFlowsListDirective.ClientFlowsListDirective");
goog.scope(function(){grrUi.flow.clientFlowsListDirective.ClientFlowsListController=function($scope,$timeout,$uibModal,grrApiService,grrRoutingService){this.scope_=$scope;this.timeout_=$timeout;this.uibModal_=$uibModal;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.flowsUrl;this.triggerUpdate;this.scope_.$watch("clientId",this.onClientIdChange_.bind(this))};var ClientFlowsListController=grrUi.flow.clientFlowsListDirective.ClientFlowsListController;ClientFlowsListController.prototype.onClientIdChange_=
function(newValue){if(angular.isString(newValue)){var components=newValue.split("/");var basename=components[components.length-1];this.flowsUrl="/clients/"+basename+"/flows"}else this.flowsUrl=null};ClientFlowsListController.prototype.cancelButtonClicked=function(){var cancelUrl=[this.flowsUrl,this.scope_["selectedFlowId"],"actions/cancel"].join("/");this.grrApiService_.post(cancelUrl,{}).then(function(){this.triggerUpdate();var flowId=this.scope_["selectedFlowId"];this.scope_["selectedFlowId"]=undefined;
this.timeout_(function(){this.scope_["selectedFlowId"]=flowId}.bind(this),0)}.bind(this))};ClientFlowsListController.prototype.createHuntFromFlow=function(){var huntUrn;var modalScope=this.scope_.$new();modalScope["clientId"]=this.scope_["clientId"];modalScope["flowId"]=this.scope_["selectedFlowId"];modalScope["resolve"]=function(newHuntUrn){huntUrn=newHuntUrn;modalInstance.close()}.bind(this);modalScope["reject"]=function(){modalInstance.dismiss()}.bind(this);this.scope_.$on("$destroy",function(){modalScope.$destroy()});
var modalInstance=this.uibModal_.open({template:'<grr-new-hunt-wizard-create-from-flow-form on-resolve="resolve(huntUrn)" '+'on-reject="reject()" flow-id="flowId" client-id="clientId" />',scope:modalScope,windowClass:"wide-modal high-modal",size:"lg"});modalInstance.result.then(function resolve(){var huntId=huntUrn.split("/")[2];this.grrRoutingService_.go("hunts",{huntId:huntId})}.bind(this))};ClientFlowsListController.prototype.copyFlow=function(){var newFlowId;var modalScope=this.scope_.$new();
modalScope["clientId"]=this.scope_["clientId"];modalScope["flowId"]=this.scope_["selectedFlowId"];modalScope["resolve"]=function(newFlowObj){newFlowId=newFlowObj["value"]["flow_id"]["value"];modalInstance.close()}.bind(this);modalScope["reject"]=function(){modalInstance.dismiss()}.bind(this);this.scope_.$on("$destroy",function(){modalScope.$destroy()});var modalInstance=this.uibModal_.open({template:'<grr-copy-flow-form on-resolve="resolve(flow)" '+'on-reject="reject()" flow-id="flowId" client-id="clientId" />',
scope:modalScope,windowClass:"wide-modal high-modal",size:"lg"});modalInstance.result.then(function resolve(){this.grrRoutingService_.go("client.flows",{flowId:newFlowId});this.triggerUpdate()}.bind(this))};grrUi.flow.clientFlowsListDirective.ClientFlowsListDirective=function(){return{scope:{clientId:"=",selectedFlowId:"=?"},restrict:"E",templateUrl:"/static/angular-components/flow/client-flows-list.html",controller:ClientFlowsListController,controllerAs:"controller"}};grrUi.flow.clientFlowsListDirective.ClientFlowsListDirective.directive_name=
"grrClientFlowsList"});goog.provide("grrUi.flow.clientFlowsViewDirective.ClientFlowsViewController");goog.provide("grrUi.flow.clientFlowsViewDirective.ClientFlowsViewDirective");
goog.scope(function(){grrUi.flow.clientFlowsViewDirective.ClientFlowsViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.clientId;this.selectedFlowId;this.tab;this.flowApiBasePath;this.scope_.$watchGroup(["controller.selectedFlowId","controller.tab"],this.onSelectionOrTabChange_.bind(this));this.grrRoutingService_.uiOnParamsChanged(this.scope_,["clientId","flowId","tab"],this.onRoutingParamsChange_.bind(this))};var ClientFlowsViewController=
grrUi.flow.clientFlowsViewDirective.ClientFlowsViewController;ClientFlowsViewController.prototype.onRoutingParamsChange_=function(unused_newValues,opt_stateParams){this.clientId=opt_stateParams["clientId"];this.selectedFlowId=opt_stateParams["flowId"];this.tab=opt_stateParams["tab"];this.flowApiBasePath=["clients",this.clientId,"flows"].join("/")};ClientFlowsViewController.prototype.onSelectionOrTabChange_=function(){if(angular.isDefined(this.selectedFlowId))this.grrRoutingService_.go("client.flows",
{flowId:this.selectedFlowId,tab:this.tab})};grrUi.flow.clientFlowsViewDirective.ClientFlowsViewDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/flow/client-flows-view.html",controller:ClientFlowsViewController,controllerAs:"controller"}};grrUi.flow.clientFlowsViewDirective.ClientFlowsViewDirective.directive_name="grrClientFlowsView"});goog.provide("grrUi.flow.copyFlowFormDirective.CopyFlowFormController");goog.provide("grrUi.flow.copyFlowFormDirective.CopyFlowFormDirective");goog.require("grrUi.core.apiService.stripTypeInfo");
goog.scope(function(){var stripTypeInfo=grrUi.core.apiService.stripTypeInfo;grrUi.flow.copyFlowFormDirective.CopyFlowFormController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.flow;this.flowFormHasErrors;this.scope_.$watchGroup(["flowId","clientId"],this.onFlowIdClientIdChange_.bind(this))};var CopyFlowFormController=grrUi.flow.copyFlowFormDirective.CopyFlowFormController;CopyFlowFormController.prototype.onFlowIdClientIdChange_=function(newValues){if(newValues.every(angular.isDefined)){var flowUrl=
["clients",this.scope_["clientId"],"flows",this.scope_["flowId"]].join("/");this.grrApiService_.get(flowUrl).then(function(response){this.flow=response["data"]}.bind(this))}};CopyFlowFormController.prototype.proceed=function(){var strippedFlow=stripTypeInfo(this.flow);return this.grrApiService_.post("clients/"+this.scope_["clientId"]+"/flows",{flow:{runner_args:strippedFlow["runner_args"],args:strippedFlow["args"]},original_flow:{flow_id:this.scope_["flowId"],client_id:this.scope_["clientId"]}}).then(function success(response){this.scope_["onResolve"]({"flow":response["data"]});
return"Flow was successfully launched!"}.bind(this),function failure(response){var e=response["data"]["message"]||"Unknown error";this.scope_["onReject"]({"error":e});return e}.bind(this))};grrUi.flow.copyFlowFormDirective.CopyFlowFormDirective=function(){return{scope:{flowId:"=",clientId:"=",onResolve:"&",onReject:"&"},restrict:"E",templateUrl:"/static/angular-components/flow/copy-flow-form.html",controller:CopyFlowFormController,controllerAs:"controller"}};grrUi.flow.copyFlowFormDirective.CopyFlowFormDirective.directive_name=
"grrCopyFlowForm"});goog.provide("grrUi.flow.flowApiHelperDirective.FlowApiHelperController");goog.provide("grrUi.flow.flowApiHelperDirective.FlowApiHelperDirective");
goog.scope(function(){grrUi.flow.flowApiHelperDirective.FlowApiHelperController=function($scope,grrApiService,grrApiHelperService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrApiHelperService_=grrApiHelperService;this.clientId;this.result;this.scope_.$watchGroup(["flowId","apiBasePath"],this.onFlowIdOrBasePathChange_.bind(this))};var FlowApiHelperController=grrUi.flow.flowApiHelperDirective.FlowApiHelperController;FlowApiHelperController.prototype.onFlowIdOrBasePathChange_=function(newValues){this.flow=
null;this.result=null;if(newValues.every(angular.isDefined)){var flowUrl=this.scope_["apiBasePath"]+"/"+this.scope_["flowId"];this.grrApiService_.getV2(flowUrl).then(function(response){var flow={args:response.data["args"],name:response.data["name"]};if(response.data["runnerArgs"]&&response.data["runnerArgs"]["outputPlugins"])flow["runnerArgs"]={outputPlugins:response.data["runnerArgs"]["outputPlugins"]};var createFlow={flow:flow};this.grrApiHelperService_.buildStartFlow(this.clientId,createFlow).then(function(result){this.result=
result}.bind(this))}.bind(this))}};grrUi.flow.flowApiHelperDirective.FlowApiHelperDirective=function(){return{scope:{flowId:"=",apiBasePath:"="},require:"?^grrClientContext",restrict:"E",templateUrl:"/static/angular-components/flow/flow-api-helper.html",controller:FlowApiHelperController,controllerAs:"controller",link:function(scope,element,attrs,grrClientContextCtrl){if(grrClientContextCtrl)scope["controller"].clientId=grrClientContextCtrl.clientId}}};grrUi.flow.flowApiHelperDirective.FlowApiHelperDirective.directive_name=
"grrFlowApiHelper"});goog.provide("grrUi.flow.flowDescriptorsTreeDirective.FlowDescriptorsTreeController");goog.provide("grrUi.flow.flowDescriptorsTreeDirective.FlowDescriptorsTreeDirective");goog.require("grrUi.core.apiService.stripTypeInfo");
goog.scope(function(){var stripTypeInfo=grrUi.core.apiService.stripTypeInfo;grrUi.flow.flowDescriptorsTreeDirective.FlowDescriptorsTreeController=function($scope,$element,grrApiService){this.scope_=$scope;this.element_=$element;this.grrApiService_=grrApiService;this.flowsDescriptors;this.userSettings;this.grrApiService_.get("/users/me").then(function(response){this.userSettings=response.data["value"]["settings"]}.bind(this));this.grrApiService_.get("/flows/descriptors").then(function(response){this.flowsDescriptors=
this.groupDescriptorsByCategory_(response["data"]["items"])}.bind(this));this.scope_.$watchGroup(["controller.userSettings","controller.flowsDescriptors"],this.onDescriptorsOrSettingsChange_.bind(this))};var FlowDescriptorsTreeController=grrUi.flow.flowDescriptorsTreeDirective.FlowDescriptorsTreeController;FlowDescriptorsTreeController.prototype.groupDescriptorsByCategory_=function(items){var result={};angular.forEach(items,function(item){var category=item["value"]["category"]["value"];result[category]=
result[category]||[];result[category].push(item)}.bind(this));return result};FlowDescriptorsTreeController.prototype.onDescriptorsOrSettingsChange_=function(){if(angular.isUndefined(this.flowsDescriptors)||angular.isUndefined(this.userSettings))return;var mode=this.scope_.$eval("controller.userSettings.value.mode.value");if(angular.isUndefined(mode))mode="BASIC";var treeNodes=[];var descriptorsKeys=Object.keys(this.flowsDescriptors).sort();angular.forEach(descriptorsKeys,function(category){var categoryNode=
{text:category,li_attr:{id:"_"+category},children:[]};var descriptors=this.flowsDescriptors[category].sort(function(a,b){a=stripTypeInfo(a);b=stripTypeInfo(b);var aName=a["friendly_name"]||a["name"];var bName=b["friendly_name"]||b["name"];if(aName<bName)return-1;else if(aName>bName)return 1;else return 0});angular.forEach(descriptors,function(descriptor){var strippedDescriptor=stripTypeInfo(descriptor);if(mode=="DEBUG"||strippedDescriptor["behaviours"].indexOf(mode)!=-1)categoryNode["children"].push({data:{descriptor:descriptor},
li_attr:{id:"_"+category+"-"+strippedDescriptor["name"]},text:strippedDescriptor["friendly_name"]||strippedDescriptor["name"],icon:"file"})}.bind(this));treeNodes.push(categoryNode)}.bind(this));var treeElem=$(this.element_).children("div.tree");treeElem.jstree({"core":{"data":treeNodes}});treeElem.on("select_node.jstree",function(e,data){data["instance"]["toggle_node"](data["node"]);if(data.node.data!==null){var descriptor=data.node.data.descriptor;this.scope_.$apply(function(){this.scope_.selectedDescriptor=
descriptor}.bind(this))}}.bind(this))};grrUi.flow.flowDescriptorsTreeDirective.FlowDescriptorsTreeDirective=function(){return{scope:{selectedDescriptor:"=?"},restrict:"E",template:'<div class="tree"></div>',controller:FlowDescriptorsTreeController,controllerAs:"controller"}};grrUi.flow.flowDescriptorsTreeDirective.FlowDescriptorsTreeDirective.directive_name="grrFlowDescriptorsTree"});goog.provide("grrUi.forms.utils.valueHasErrors");goog.scope(function(){grrUi.forms.utils.valueHasErrors=function(value){if(!angular.isObject(value))return false;if(value["validationError"])return true;if(angular.isArray(value)){var alen=value.length;for(var i=0;i<alen;++i)if(valueHasErrors(value[i]))return true;return false}if(angular.isObject(value["value"])){var nestedValue=value["value"];for(var k in nestedValue)if(valueHasErrors(nestedValue[k]))return true}return false};var valueHasErrors=grrUi.forms.utils.valueHasErrors});goog.provide("grrUi.flow.flowFormDirective.FlowFormController");goog.provide("grrUi.flow.flowFormDirective.FlowFormDirective");goog.require("grrUi.forms.utils.valueHasErrors");
goog.scope(function(){var valueHasErrors=grrUi.forms.utils.valueHasErrors;grrUi.flow.flowFormDirective.FlowFormController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.outputPluginsField;this.outputPluginDescriptor;this.grrReflectionService_.getRDFValueDescriptor("FlowRunnerArgs").then(function(descriptor){angular.forEach(descriptor["fields"],function(field){if(field.name=="output_plugins")this.outputPluginsField=field}.bind(this));return this.grrReflectionService_.getRDFValueDescriptor("OutputPluginDescriptor")}.bind(this)).then(function(descriptor){this.outputPluginDescriptor=
descriptor}.bind(this));this.scope_.$watch("flowRunnerArgs.value.output_plugins",this.onOutputPluginsChanged_.bind(this));this.scope_.$watch(function(){return[this.scope_["flowArgs"],this.scope_["flowRunnerArgs"]]}.bind(this),this.onArgsDeepChange_.bind(this),true)};var FlowFormController=grrUi.flow.flowFormDirective.FlowFormController;FlowFormController.prototype.onArgsDeepChange_=function(){this.scope_["hasErrors"]=valueHasErrors(this.scope_["flowArgs"])||valueHasErrors(this.scope_["flowRunnerArgs"])};
FlowFormController.prototype.onOutputPluginsChanged_=function(newValue){if(!this.scope_["withOutputPlugins"])return;var flowRunnerArgs=this.scope_["flowRunnerArgs"];if(angular.isUndefined(newValue)&&angular.isDefined(flowRunnerArgs))flowRunnerArgs["value"]["output_plugins"]=[]};grrUi.flow.flowFormDirective.FlowFormDirective=function(){return{scope:{flowArgs:"=",flowRunnerArgs:"=",withOutputPlugins:"=",hasErrors:"=?"},restrict:"E",templateUrl:"/static/angular-components/flow/flow-form.html",controller:FlowFormController,
controllerAs:"controller"}};grrUi.flow.flowFormDirective.FlowFormDirective.directive_name="grrFlowForm"});goog.provide("grrUi.flow.flowInfoDirective.FlowInfoController");goog.provide("grrUi.flow.flowInfoDirective.FlowInfoDirective");
goog.scope(function(){grrUi.flow.flowInfoDirective.FlowInfoController=function($scope){this.scope_=$scope};var FlowInfoController=grrUi.flow.flowInfoDirective.FlowInfoController;grrUi.flow.flowInfoDirective.FlowInfoDirective=function(){return{scope:{descriptor:"="},restrict:"E",templateUrl:"/static/angular-components/flow/flow-info.html",controller:FlowInfoController,controllerAs:"controller"}};grrUi.flow.flowInfoDirective.FlowInfoDirective.directive_name="grrFlowInfo"});goog.provide("grrUi.flow.flowInspectorDirective.FlowInspectorController");goog.provide("grrUi.flow.flowInspectorDirective.FlowInspectorDirective");
goog.scope(function(){grrUi.flow.flowInspectorDirective.FlowInspectorController=function($scope){this.scope_=$scope;this.activeTab="";this.tabsShown={};this.scope_.$watch("activeTab",this.onDirectiveArgumentsChange_.bind(this));this.scope_.$watch("controller.activeTab",this.onTabChange_.bind(this))};var FlowInspectorController=grrUi.flow.flowInspectorDirective.FlowInspectorController;FlowInspectorController.prototype.onDirectiveArgumentsChange_=function(newValue){if(angular.isString(newValue))this.activeTab=
newValue};FlowInspectorController.prototype.onTabChange_=function(newValue,oldValue){if(newValue!==oldValue)this.scope_["activeTab"]=newValue;this.tabsShown[newValue]=true};grrUi.flow.flowInspectorDirective.FlowInspectorDirective=function(){return{scope:{flowId:"=",apiBasePath:"=",activeTab:"=?"},controller:FlowInspectorController,controllerAs:"controller",restrict:"E",templateUrl:"/static/angular-components/flow/flow-inspector.html"}};grrUi.flow.flowInspectorDirective.FlowInspectorDirective.directive_name=
"grrFlowInspector"});goog.provide("grrUi.flow.flowLogDirective.FlowLogController");goog.provide("grrUi.flow.flowLogDirective.FlowLogDirective");
goog.scope(function(){grrUi.flow.flowLogDirective.AUTO_REFRESH_INTERVAL_MS=20*1E3;grrUi.flow.flowLogDirective.FlowLogController=function($scope){this.scope_=$scope;this.logsUrl;this.autoRefreshInterval=grrUi.flow.flowLogDirective.AUTO_REFRESH_INTERVAL_MS;this.scope_.$watchGroup(["flowId","apiBasePath"],this.onFlowIdOrBasePathChange_.bind(this))};var FlowLogController=grrUi.flow.flowLogDirective.FlowLogController;FlowLogController.prototype.onFlowIdOrBasePathChange_=function(newValue){if(angular.isDefined(this.scope_["flowId"])&&
angular.isDefined(this.scope_["apiBasePath"]))this.logsUrl=[this.scope_["apiBasePath"],this.scope_["flowId"],"log"].join("/")};grrUi.flow.flowLogDirective.FlowLogDirective=function(){return{scope:{flowId:"=",apiBasePath:"="},restrict:"E",templateUrl:"/static/angular-components/flow/flow-log.html",controller:FlowLogController,controllerAs:"controller"}};grrUi.flow.flowLogDirective.FlowLogDirective.directive_name="grrFlowLog"});goog.provide("grrUi.flow.flowOverviewDirective.FlowOverviewController");goog.provide("grrUi.flow.flowOverviewDirective.FlowOverviewDirective");goog.require("grrUi.core.utils.stripAff4Prefix");
goog.scope(function(){var stripAff4Prefix=grrUi.core.utils.stripAff4Prefix;grrUi.flow.flowOverviewDirective.AUTO_REFRESH_INTERVAL_MS=15*1E3;grrUi.flow.flowOverviewDirective.FlowOverviewController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.flow;this.pollPromise_;this.scope_.$on("$destroy",function(){this.grrApiService_.cancelPoll(this.pollPromise_)}.bind(this));this.scope_.$watchGroup(["flowId","apiBasePath"],this.startPolling.bind(this))};var FlowOverviewController=
grrUi.flow.flowOverviewDirective.FlowOverviewController;FlowOverviewController.prototype.startPolling=function(){this.grrApiService_.cancelPoll(this.pollPromise_);this.pollPromise_=undefined;if(angular.isDefined(this.scope_["apiBasePath"])&&angular.isDefined(this.scope_["flowId"])){var flowUrl=this.scope_["apiBasePath"]+"/"+this.scope_["flowId"];var interval=grrUi.flow.flowOverviewDirective.AUTO_REFRESH_INTERVAL_MS;this.pollPromise_=this.grrApiService_.poll(flowUrl,interval);this.pollPromise_.then(undefined,
undefined,function notify(response){this.flow=response["data"]}.bind(this))}};grrUi.flow.flowOverviewDirective.FlowOverviewDirective=function(){return{scope:{flowId:"=",apiBasePath:"="},restrict:"E",templateUrl:"/static/angular-components/flow/flow-overview.html",controller:FlowOverviewController,controllerAs:"controller"}};grrUi.flow.flowOverviewDirective.FlowOverviewDirective.directive_name="grrFlowOverview"});goog.provide("grrUi.flow.flowRequestsDirective.FlowRequestsController");goog.provide("grrUi.flow.flowRequestsDirective.FlowRequestsDirective");
goog.scope(function(){grrUi.flow.flowRequestsDirective.FlowRequestsController=function($scope){this.scope_=$scope;this.requestsUrl;this.scope_.$watchGroup(["flowId","apiBasePath"],this.onFlowIdOrBasePathChange_.bind(this))};var FlowRequestsController=grrUi.flow.flowRequestsDirective.FlowRequestsController;FlowRequestsController.prototype.onFlowIdOrBasePathChange_=function(newValues){if(newValues.every(angular.isDefined))this.requestsUrl=[this.scope_["apiBasePath"],this.scope_["flowId"],"requests"].join("/")};
grrUi.flow.flowRequestsDirective.FlowRequestsDirective=function(){return{scope:{flowId:"=",apiBasePath:"="},restrict:"E",templateUrl:"/static/angular-components/flow/flow-requests.html",controller:FlowRequestsController,controllerAs:"controller"}};grrUi.flow.flowRequestsDirective.FlowRequestsDirective.directive_name="grrFlowRequests"});goog.provide("grrUi.flow.flowResultsDirective.FlowResultsController");goog.provide("grrUi.flow.flowResultsDirective.FlowResultsDirective");goog.require("grrUi.core.downloadCollectionFilesDirective.valuePointsToFile");
goog.scope(function(){grrUi.flow.flowResultsDirective.FlowResultsController=function($scope){this.scope_=$scope;this.flowResultsUrl;this.flowExportedResultsUrl;this.outputPluginsMetadataUrl;this.downloadFilesUrl;this.exportCommand;this.scope_.$watchGroup(["flowId","apiBasePath"],this.onFlowIdOrBasePathChange_.bind(this))};var FlowResultsController=grrUi.flow.flowResultsDirective.FlowResultsController;FlowResultsController.prototype.onFlowIdOrBasePathChange_=function(newValues){this.flowResultsUrl=
this.outputPluginsMetadataUrl=this.downloadFilesUrl=null;if(newValues.every(angular.isDefined)){var flowUrl=this.scope_["apiBasePath"]+"/"+this.scope_["flowId"];this.flowResultsUrl=flowUrl+"/results";this.flowExportedResultsUrl=flowUrl+"/exported-results";this.outputPluginsUrl=flowUrl+"/output-plugins";this.exportCommandUrl=flowUrl+"/results/export-command";this.downloadFilesUrl=flowUrl+"/results/files-archive"}};grrUi.flow.flowResultsDirective.FlowResultsDirective=function(){return{scope:{flowId:"=",
apiBasePath:"="},restrict:"E",templateUrl:"/static/angular-components/flow/flow-results.html",controller:FlowResultsController,controllerAs:"controller"}};grrUi.flow.flowResultsDirective.FlowResultsDirective.directive_name="grrFlowResults"});goog.provide("grrUi.flow.flowStatusIconDirective.FlowStatusIconController");goog.provide("grrUi.flow.flowStatusIconDirective.FlowStatusIconDirective");goog.scope(function(){grrUi.flow.flowStatusIconDirective.FlowStatusIconDirective=function(){return{scope:{flow:"="},restrict:"E",templateUrl:"/static/angular-components/flow/flow-status-icon.html"}};grrUi.flow.flowStatusIconDirective.FlowStatusIconDirective.directive_name="grrFlowStatusIcon"});goog.provide("grrUi.flow.flowsListDirective.FlowsListController");goog.provide("grrUi.flow.flowsListDirective.FlowsListDirective");goog.provide("grrUi.flow.flowsListDirective.flattenFlowsList");goog.provide("grrUi.flow.flowsListDirective.toggleFlowExpansion");goog.require("grrUi.core.infiniteTableDirective.InfiniteTableController");
goog.scope(function(){var TABLE_KEY_NAME=grrUi.core.infiniteTableDirective.InfiniteTableController.UNIQUE_KEY_NAME;var TABLE_ROW_HASH=grrUi.core.infiniteTableDirective.InfiniteTableController.ROW_HASH_NAME;grrUi.flow.flowsListDirective.AUTO_REFRESH_INTERVAL_MS=30*1E3;grrUi.flow.flowsListDirective.flattenFlowsList=function(flows,opt_currentDepth){if(angular.isUndefined(opt_currentDepth))opt_currentDepth=0;var result=[];for(var i=0;i<flows.length;++i){var flow=angular.copy(flows[i]);flow["depth"]=opt_currentDepth;
result.push(flow);if(angular.isDefined(flow["value"])&&angular.isDefined(flow["value"]["nested_flows"])){result=result.concat(grrUi.flow.flowsListDirective.flattenFlowsList(flow["value"]["nested_flows"],opt_currentDepth+1));delete flow["value"]["nested_flows"]}}return result};var flattenFlowsList=grrUi.flow.flowsListDirective.flattenFlowsList;grrUi.flow.flowsListDirective.toggleFlowExpansion=function(flows,index){var flowToExpand=flows[index];var i;flowToExpand.expanded=!flowToExpand.expanded;if(!flowToExpand.expanded)for(i=
index+1;i<flows.length;++i)if(flows[i].depth>flowToExpand.depth)flows[i].shown=false;else break;else{var ignoreDepth=null;for(i=index+1;i<flows.length;++i)if(flows[i].depth>flowToExpand.depth){if(!ignoreDepth||ignoreDepth>=flows[i].depth){flows[i].shown=true;ignoreDepth=flows[i].expanded?null:flows[i].depth}}else break}return flows};var toggleFlowExpansion=grrUi.flow.flowsListDirective.toggleFlowExpansion;grrUi.flow.flowsListDirective.FlowsListController=function($scope,$element,grrApiService){this.scope_=
$scope;this.element_=$element;this.flowsById={};this.selectedFlowId;this.triggerTableUpdate;this.autoRefreshInterval=grrUi.flow.flowsListDirective.AUTO_REFRESH_INTERVAL_MS;this.scope_.$watch("controller.selectedFlowId",function(newValue){if(angular.isDefined(newValue))this.scope_["selectedFlowId"]=newValue}.bind(this));this.scope_.$watch("selectedFlowId",function(newValue){if(angular.isDefined(newValue))this.selectedFlowId=newValue}.bind(this));this.scope_["triggerUpdate"]=this.triggerUpdate.bind(this)};
var FlowsListController=grrUi.flow.flowsListDirective.FlowsListController;FlowsListController.prototype.selectItem=function(item){this.selectedFlowId=item["value"]["flow_id"]["value"]};FlowsListController.prototype.transformItems=function(items){var flattenedItems=flattenFlowsList(items);angular.forEach(flattenedItems,function(item,index){var components=item["value"]["flow_id"]["value"].split("/");item.shortId=components[components.length-1];item.shown=item.depth==0;if(index<flattenedItems.length-
1&&flattenedItems[index+1].depth>item.depth)item.expanded=false;item.expand=function(e){e.stopPropagation();toggleFlowExpansion(flattenedItems,index)};var state="BROKEN";if(angular.isDefined(item["value"]["state"]))state=item["value"]["state"]["value"];var last_active_at=0;if(angular.isDefined(item["value"]["last_active_at"]))last_active_at=item["value"]["last_active_at"]["value"];item[TABLE_KEY_NAME]=item["value"]["flow_id"]["value"];item[TABLE_ROW_HASH]=[state,last_active_at]}.bind(this));return flattenedItems};
FlowsListController.prototype.triggerUpdate=function(){this.triggerTableUpdate(true)};grrUi.flow.flowsListDirective.FlowsListDirective=function(){return{scope:{flowsUrl:"=",selectedFlowId:"=?",triggerUpdate:"=?"},restrict:"E",templateUrl:"/static/angular-components/flow/flows-list.html",controller:FlowsListController,controllerAs:"controller"}};grrUi.flow.flowsListDirective.FlowsListDirective.directive_name="grrFlowsList"});goog.provide("grrUi.flow.startFlowFormDirective.StartFlowFormController");goog.provide("grrUi.flow.startFlowFormDirective.StartFlowFormDirective");goog.require("grrUi.core.apiService.stripTypeInfo");
goog.scope(function(){var stripTypeInfo=grrUi.core.apiService.stripTypeInfo;grrUi.flow.startFlowFormDirective.StartFlowFormController=function($scope,grrApiService,grrReflectionService){this.scope_=$scope;this.scope_.clientId;this.grrApiService_=grrApiService;this.grrReflectionService_=grrReflectionService;this.flowArguments;this.flowRunnerArguments;this.requestSent=false;this.responseError;this.responseData;this.outputPluginsField;this.outputPluginDescriptor;this.flowFormHasErrors;this.scope_.$watch("descriptor",
function(flowDescriptor){this.requestSent=false;this.responseError=null;this.responseData=null;if(angular.isDefined(flowDescriptor)){this.flowArguments=angular.copy(flowDescriptor["value"]["default_args"]);this.grrReflectionService_.getRDFValueDescriptor("FlowRunnerArgs").then(function(descriptor){this.flowRunnerArguments=angular.copy(descriptor["default"]);this.flowRunnerArguments["value"]["flow_name"]=flowDescriptor["value"]["name"]}.bind(this))}}.bind(this))};var StartFlowFormController=grrUi.flow.startFlowFormDirective.StartFlowFormController;
StartFlowFormController.prototype.startClientFlow=function(){var clientIdComponents=this.scope_["clientId"].split("/");var clientId;if(clientIdComponents[0]=="aff4:")clientId=clientIdComponents[1];else clientId=clientIdComponents[0];this.grrApiService_.post("/clients/"+clientId+"/flows",{flow:{runner_args:stripTypeInfo(this.flowRunnerArguments),args:stripTypeInfo(this.flowArguments)}}).then(function success(response){this.responseData=response["data"]}.bind(this),function failure(response){this.responseError=
response["data"]["message"]||"Unknown error"}.bind(this));this.requestSent=true};grrUi.flow.startFlowFormDirective.StartFlowFormDirective=function(){return{scope:{clientId:"=?",descriptor:"="},restrict:"E",templateUrl:"/static/angular-components/flow/start-flow-form.html",controller:StartFlowFormController,controllerAs:"controller"}};grrUi.flow.startFlowFormDirective.StartFlowFormDirective.directive_name="grrStartFlowForm"});goog.provide("grrUi.flow.startFlowViewDirective.StartFlowViewController");goog.provide("grrUi.flow.startFlowViewDirective.StartFlowViewDirective");
goog.scope(function(){grrUi.flow.startFlowViewDirective.StartFlowViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.cliendId;this.selection={};this.grrRoutingService_.uiOnParamsChanged(this.scope_,"clientId",this.onClientIdChange_.bind(this))};var StartFlowViewController=grrUi.flow.startFlowViewDirective.StartFlowViewController;StartFlowViewController.prototype.onClientIdChange_=function(clientId){this.clientId=clientId};grrUi.flow.startFlowViewDirective.StartFlowViewDirective=
function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/flow/start-flow-view.html",controller:StartFlowViewController,controllerAs:"controller"}};grrUi.flow.startFlowViewDirective.StartFlowViewDirective.directive_name="grrStartFlowView"});goog.provide("grrUi.flow.module");goog.require("grrUi.core.module");goog.require("grrUi.flow.clientFlowsListDirective.ClientFlowsListDirective");goog.require("grrUi.flow.clientFlowsViewDirective.ClientFlowsViewDirective");goog.require("grrUi.flow.copyFlowFormDirective.CopyFlowFormDirective");goog.require("grrUi.flow.flowApiHelperDirective.FlowApiHelperDirective");goog.require("grrUi.flow.flowDescriptorsTreeDirective.FlowDescriptorsTreeDirective");goog.require("grrUi.flow.flowFormDirective.FlowFormDirective");
goog.require("grrUi.flow.flowInfoDirective.FlowInfoDirective");goog.require("grrUi.flow.flowInspectorDirective.FlowInspectorDirective");goog.require("grrUi.flow.flowLogDirective.FlowLogDirective");goog.require("grrUi.flow.flowOverviewDirective.FlowOverviewDirective");goog.require("grrUi.flow.flowRequestsDirective.FlowRequestsDirective");goog.require("grrUi.flow.flowResultsDirective.FlowResultsDirective");goog.require("grrUi.flow.flowStatusIconDirective.FlowStatusIconDirective");goog.require("grrUi.flow.flowsListDirective.FlowsListDirective");
goog.require("grrUi.flow.startFlowFormDirective.StartFlowFormDirective");goog.require("grrUi.flow.startFlowViewDirective.StartFlowViewDirective");grrUi.flow.module=angular.module("grrUi.flow",[grrUi.core.module.name]);grrUi.flow.module.directive(grrUi.flow.clientFlowsListDirective.ClientFlowsListDirective.directive_name,grrUi.flow.clientFlowsListDirective.ClientFlowsListDirective);grrUi.flow.module.directive(grrUi.flow.clientFlowsViewDirective.ClientFlowsViewDirective.directive_name,grrUi.flow.clientFlowsViewDirective.ClientFlowsViewDirective);
grrUi.flow.module.directive(grrUi.flow.copyFlowFormDirective.CopyFlowFormDirective.directive_name,grrUi.flow.copyFlowFormDirective.CopyFlowFormDirective);grrUi.flow.module.directive(grrUi.flow.flowApiHelperDirective.FlowApiHelperDirective.directive_name,grrUi.flow.flowApiHelperDirective.FlowApiHelperDirective);grrUi.flow.module.directive(grrUi.flow.flowDescriptorsTreeDirective.FlowDescriptorsTreeDirective.directive_name,grrUi.flow.flowDescriptorsTreeDirective.FlowDescriptorsTreeDirective);
grrUi.flow.module.directive(grrUi.flow.flowFormDirective.FlowFormDirective.directive_name,grrUi.flow.flowFormDirective.FlowFormDirective);grrUi.flow.module.directive(grrUi.flow.flowInfoDirective.FlowInfoDirective.directive_name,grrUi.flow.flowInfoDirective.FlowInfoDirective);grrUi.flow.module.directive(grrUi.flow.flowInspectorDirective.FlowInspectorDirective.directive_name,grrUi.flow.flowInspectorDirective.FlowInspectorDirective);
grrUi.flow.module.directive(grrUi.flow.flowLogDirective.FlowLogDirective.directive_name,grrUi.flow.flowLogDirective.FlowLogDirective);grrUi.flow.module.directive(grrUi.flow.flowOverviewDirective.FlowOverviewDirective.directive_name,grrUi.flow.flowOverviewDirective.FlowOverviewDirective);grrUi.flow.module.directive(grrUi.flow.flowRequestsDirective.FlowRequestsDirective.directive_name,grrUi.flow.flowRequestsDirective.FlowRequestsDirective);
grrUi.flow.module.directive(grrUi.flow.flowResultsDirective.FlowResultsDirective.directive_name,grrUi.flow.flowResultsDirective.FlowResultsDirective);grrUi.flow.module.directive(grrUi.flow.flowStatusIconDirective.FlowStatusIconDirective.directive_name,grrUi.flow.flowStatusIconDirective.FlowStatusIconDirective);grrUi.flow.module.directive(grrUi.flow.flowsListDirective.FlowsListDirective.directive_name,grrUi.flow.flowsListDirective.FlowsListDirective);
grrUi.flow.module.directive(grrUi.flow.startFlowFormDirective.StartFlowFormDirective.directive_name,grrUi.flow.startFlowFormDirective.StartFlowFormDirective);grrUi.flow.module.directive(grrUi.flow.startFlowViewDirective.StartFlowViewDirective.directive_name,grrUi.flow.startFlowViewDirective.StartFlowViewDirective);goog.provide("grrUi.hunt.huntClientsDirective.HuntClientsController");goog.provide("grrUi.hunt.huntClientsDirective.HuntClientsDirective");
goog.scope(function(){grrUi.hunt.huntClientsDirective.HuntClientsController=function($scope){this.scope_=$scope;this.huntClientsUrl;this.clientType="completed";this.scope_.$watchGroup(["huntUrn","controller.clientType"],this.onHuntUrnOrClientTypeChange_.bind(this))};var HuntClientsController=grrUi.hunt.huntClientsDirective.HuntClientsController;HuntClientsController.prototype.onHuntUrnOrClientTypeChange_=function(){var huntUrn=this.scope_["huntUrn"];if(!angular.isString(huntUrn)||!angular.isString(this.clientType))return;
var components=huntUrn.split("/");var huntId=components[components.length-1];this.huntClientsUrl="/hunts/"+huntId+"/clients/"+this.clientType};grrUi.hunt.huntClientsDirective.HuntClientsDirective=function(){return{scope:{huntUrn:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-clients.html",controller:HuntClientsController,controllerAs:"controller"}};grrUi.hunt.huntClientsDirective.HuntClientsDirective.directive_name="grrHuntClients"});goog.provide("grrUi.hunt.huntContextDirective.HuntContextController");goog.provide("grrUi.hunt.huntContextDirective.HuntContextDirective");
goog.scope(function(){grrUi.hunt.huntContextDirective.HuntContextController=function($scope,grrApiService){this.grrApiService_=grrApiService;this.context;this.state;$scope.$watch("huntUrn",this.onHuntUrnChange_.bind(this))};var HuntContextController=grrUi.hunt.huntContextDirective.HuntContextController;HuntContextController.prototype.onHuntUrnChange_=function(huntUrn){if(!angular.isString(huntUrn))return;var components=huntUrn.split("/");var huntId=components[components.length-1];var url="/hunts/"+
huntId+"/context";this.grrApiService_.get(url).then(function success(response){this.context=response.data["context"];this.state=response.data["state"]}.bind(this))};grrUi.hunt.huntContextDirective.HuntContextDirective=function(){return{scope:{huntUrn:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-context.html",controller:HuntContextController,controllerAs:"controller"}};grrUi.hunt.huntContextDirective.HuntContextDirective.directive_name="grrHuntContext"});goog.provide("grrUi.hunt.huntCrashesDirective.HuntCrashesController");goog.provide("grrUi.hunt.huntCrashesDirective.HuntCrashesDirective");
goog.scope(function(){grrUi.hunt.huntCrashesDirective.AUTO_REFRESH_INTERVAL_MS=20*1E3;grrUi.hunt.huntCrashesDirective.HuntCrashesController=function($scope){this.scope_=$scope;this.scope_.huntUrn;this.crashesUrl;this.autoRefreshInterval=grrUi.hunt.huntCrashesDirective.AUTO_REFRESH_INTERVAL_MS;this.scope_.$watch("huntUrn",this.onHuntUrnChange_.bind(this))};var HuntCrashesController=grrUi.hunt.huntCrashesDirective.HuntCrashesController;HuntCrashesController.prototype.onHuntUrnChange_=function(){if(angular.isDefined(this.scope_.huntUrn)){var huntUrnComponents=
this.scope_.huntUrn.split("/");var huntId=huntUrnComponents[huntUrnComponents.length-1];this.crashesUrl="hunts/"+huntId+"/crashes"}};grrUi.hunt.huntCrashesDirective.HuntCrashesDirective=function(){return{scope:{huntUrn:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-crashes.html",controller:HuntCrashesController,controllerAs:"controller"}};grrUi.hunt.huntCrashesDirective.HuntCrashesDirective.directive_name="grrHuntCrashes"});goog.provide("grrUi.hunt.huntErrorsDirective.HuntErrorsController");goog.provide("grrUi.hunt.huntErrorsDirective.HuntErrorsDirective");
goog.scope(function(){grrUi.hunt.huntErrorsDirective.AUTO_REFRESH_INTERVAL_MS=20*1E3;grrUi.hunt.huntErrorsDirective.HuntErrorsController=function($scope){this.scope_=$scope;this.scope_.huntUrn;this.errorsUrl;this.autoRefreshInterval=grrUi.hunt.huntErrorsDirective.AUTO_REFRESH_INTERVAL_MS;this.scope_.$watch("huntUrn",this.onHuntUrnChange_.bind(this))};var HuntErrorsController=grrUi.hunt.huntErrorsDirective.HuntErrorsController;HuntErrorsController.prototype.onHuntUrnChange_=function(){if(angular.isDefined(this.scope_.huntUrn)){var huntUrnComponents=
this.scope_.huntUrn.split("/");var huntId=huntUrnComponents[huntUrnComponents.length-1];this.errorsUrl="hunts/"+huntId+"/errors"}};grrUi.hunt.huntErrorsDirective.HuntErrorsDirective=function(){return{scope:{huntUrn:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-errors.html",controller:HuntErrorsController,controllerAs:"controller"}};grrUi.hunt.huntErrorsDirective.HuntErrorsDirective.directive_name="grrHuntErrors"});goog.provide("grrUi.hunt.huntGraphDirective.HuntGraphController");goog.provide("grrUi.hunt.huntGraphDirective.HuntGraphDirective");
goog.scope(function(){grrUi.hunt.huntGraphDirective.HuntGraphController=function($scope,$element,grrApiService){this.scope_=$scope;this.element_=$element;this.grrApiService_=grrApiService;this.scope_.huntUrn;this.inProgress=false;this.clientStartPoints;this.clientFinishPoints;this.informationAvailable;this.maxSampleSize=1E3;this.scope_.$watch("huntUrn",this.onHuntUrnChange_.bind(this))};var HuntGraphController=grrUi.hunt.huntGraphDirective.HuntGraphController;HuntGraphController.prototype.onHuntUrnChange_=
function(){this.hunt=null;this.huntSummary=null;if(angular.isDefined(this.scope_.huntUrn)){var huntUrnComponents=this.scope_.huntUrn.split("/");this.huntId=huntUrnComponents[huntUrnComponents.length-1];this.inProgress=true;var url="hunts/"+this.huntId+"/client-completion-stats";var params={"strip_type_info":1,"size":this.maxSampleSize};this.grrApiService_.get(url,params).then(this.onHuntGraphFetched_.bind(this))}};HuntGraphController.prototype.onHuntGraphFetched_=function(response){this.clientStartPoints=
this.parseDataPoints_(response.data["start_points"]);this.clientFinishPoints=this.parseDataPoints_(response.data["complete_points"]);this.informationAvailable=angular.isArray(this.clientStartPoints)&&this.clientStartPoints.length>0||angular.isArray(this.clientFinishPoints)&&this.clientFinishPoints.length>0;this.drawGraph_();this.inProgress=false};HuntGraphController.prototype.parseDataPoints_=function(points){var result=[];angular.forEach(points,function(point){result.push([point["x_value"],point["y_value"]])});
return result};HuntGraphController.prototype.drawGraph_=function(){var graphElement=$(this.element_).find(".client-completion-graph");if(graphElement&&this.informationAvailable)$.plot(graphElement,[{label:"Agents issued.",data:this.clientStartPoints},{label:"Agents completed.",data:this.clientFinishPoints}],{series:{lines:{show:true},points:{show:true}},xaxis:{min:0,tickDecimals:4},yaxis:{tickDecimals:0}})};grrUi.hunt.huntGraphDirective.HuntGraphDirective=function(){return{scope:{huntUrn:"="},restrict:"E",
templateUrl:"/static/angular-components/hunt/hunt-graph.html",controller:HuntGraphController,controllerAs:"controller"}};grrUi.hunt.huntGraphDirective.HuntGraphDirective.directive_name="grrHuntGraph"});goog.provide("grrUi.hunt.huntInspectorDirective");goog.provide("grrUi.hunt.huntInspectorDirective.HuntInspectorDirective");goog.provide("grrUi.hunt.huntInspectorDirective.huntInspectorController");
goog.scope(function(){grrUi.hunt.huntInspectorDirective.huntInspectorController=function($scope){this.scope_=$scope;this.shownHuntUrn;this.activeTab="";this.tabsShown={};this.scope_.$watchGroup(["huntUrn","activeTab"],this.onDirectiveArgumentsChange_.bind(this));this.scope_.$watch("controller.activeTab",this.onTabChange_.bind(this))};var HuntInspectorController=grrUi.hunt.huntInspectorDirective.huntInspectorController;HuntInspectorController.prototype.onDirectiveArgumentsChange_=function(){if(angular.isString(this.scope_["activeTab"]))this.activeTab=
this.scope_["activeTab"];this.scope_.$evalAsync(function(){this.shownHuntUrn=this.scope_["huntUrn"]}.bind(this))};HuntInspectorController.prototype.onTabChange_=function(newValue,oldValue){if(newValue!==oldValue)this.scope_["activeTab"]=newValue;this.tabsShown[newValue]=true};grrUi.hunt.huntInspectorDirective.HuntInspectorDirective=function(){return{scope:{huntUrn:"=",activeTab:"=?"},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-inspector.html",controller:HuntInspectorController,
controllerAs:"controller"}};grrUi.hunt.huntInspectorDirective.HuntInspectorDirective.directive_name="grrHuntInspector"});goog.provide("grrUi.hunt.huntLogDirective.HuntLogController");goog.provide("grrUi.hunt.huntLogDirective.HuntLogDirective");
goog.scope(function(){grrUi.hunt.huntLogDirective.AUTO_REFRESH_INTERVAL_MS=20*1E3;grrUi.hunt.huntLogDirective.HuntLogController=function($scope){this.scope_=$scope;this.scope_.huntUrn;this.autoRefreshInterval=grrUi.hunt.huntLogDirective.AUTO_REFRESH_INTERVAL_MS;this.scope_.$watch("huntUrn",this.onHuntUrnChange.bind(this))};var HuntLogController=grrUi.hunt.huntLogDirective.HuntLogController;HuntLogController.prototype.onHuntUrnChange=function(){if(angular.isDefined(this.scope_.huntUrn)){var huntUrnComponents=
this.scope_.huntUrn.split("/");var huntId=huntUrnComponents[huntUrnComponents.length-1];this.logsUrl="hunts/"+huntId+"/log"}};HuntLogController.prototype.transformItems=function(items){var clientId=null;var highlighted=false;for(var i=0;i<items.length;++i){var item=items[i];if(item.value.urn!==undefined){var components=item.value.urn.value.split("/");if(components.length>0)item.shortUrn=components[components.length-1]}var itemClientId=null;if(item.value.client_id!==undefined)itemClientId=item.value.client_id.value;
if(clientId!==itemClientId){clientId=itemClientId;highlighted=!highlighted}else item.value.client_id=null;item.highlighted=highlighted}return items};grrUi.hunt.huntLogDirective.HuntLogDirective=function(){return{scope:{huntUrn:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-log.html",controller:HuntLogController,controllerAs:"controller"}};grrUi.hunt.huntLogDirective.HuntLogDirective.directive_name="grrHuntLog"});goog.provide("grrUi.hunt.huntOverviewDirective.HuntOverviewController");goog.provide("grrUi.hunt.huntOverviewDirective.HuntOverviewDirective");
goog.scope(function(){grrUi.hunt.huntOverviewDirective.AUTO_REFRESH_INTERVAL_MS=15*1E3;grrUi.hunt.huntOverviewDirective.HuntOverviewController=function($scope,grrApiService,grrRoutingService){this.scope_=$scope;this.scope_.huntUrn;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.huntId;this.hunt;this.pollPromise_;this.scope_.$on("$destroy",function(){this.grrApiService_.cancelPoll(this.pollPromise_)}.bind(this));this.scope_.$watch("huntUrn",this.startPolling_.bind(this))};
var HuntOverviewController=grrUi.hunt.huntOverviewDirective.HuntOverviewController;HuntOverviewController.prototype.startPolling_=function(){this.grrApiService_.cancelPoll(this.pollPromise_);this.pollPromise_=undefined;if(angular.isDefined(this.scope_["huntUrn"])){var huntUrnComponents=this.scope_["huntUrn"].split("/");this.huntId=huntUrnComponents[huntUrnComponents.length-1];var huntUrl="hunts/"+this.huntId;var interval=grrUi.hunt.huntOverviewDirective.AUTO_REFRESH_INTERVAL_MS;this.pollPromise_=
this.grrApiService_.poll(huntUrl,interval);this.pollPromise_.then(undefined,undefined,function notify(response){this.hunt=response["data"]}.bind(this))}};grrUi.hunt.huntOverviewDirective.HuntOverviewDirective=function(){return{scope:{huntUrn:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-overview.html",controller:HuntOverviewController,controllerAs:"controller"}};grrUi.hunt.huntOverviewDirective.HuntOverviewDirective.directive_name="grrHuntOverview"});goog.provide("grrUi.hunt.huntResultsDirective.HuntResultsController");goog.provide("grrUi.hunt.huntResultsDirective.HuntResultsDirective");goog.require("grrUi.core.fileDownloadUtils.downloadableVfsRoots");goog.require("grrUi.core.fileDownloadUtils.getPathSpecFromValue");goog.require("grrUi.core.fileDownloadUtils.makeValueDownloadable");goog.require("grrUi.core.fileDownloadUtils.pathSpecToAff4Path");goog.require("grrUi.core.utils.stripAff4Prefix");
goog.scope(function(){grrUi.hunt.huntResultsDirective.HuntResultsController=function($scope){this.scope_=$scope;this.resultsUrl;this.exportedResultsUrl;this.outputPluginsUrl;this.downloadFilesUrl;this.exportCommandUrl;$scope.$watch("huntUrn",this.onHuntUrnChange.bind(this))};var HuntResultsController=grrUi.hunt.huntResultsDirective.HuntResultsController;HuntResultsController.prototype.onHuntUrnChange=function(huntUrn){if(!angular.isString(huntUrn))return;var components=huntUrn.split("/");var huntId=
components[components.length-1];this.resultsUrl="/hunts/"+huntId+"/results";this.exportedResultsUrl="/hunts/"+huntId+"/exported-results";this.downloadFilesUrl=this.resultsUrl+"/files-archive";this.exportCommandUrl=this.resultsUrl+"/export-command";this.outputPluginsUrl="/hunts/"+huntId+"/output-plugins"};HuntResultsController.prototype.transformItems=function(items){var components=this.scope_["huntUrn"].split("/");var huntId=components[components.length-1];var urlPrefix="/hunts/"+huntId+"/results/clients";
var newItems=items.map(function(item){var pathSpec=grrUi.core.fileDownloadUtils.getPathSpecFromValue(item);if(!pathSpec)return item;var clientId=item["value"]["client_id"]["value"];var aff4Path=grrUi.core.utils.stripAff4Prefix(grrUi.core.fileDownloadUtils.pathSpecToAff4Path(pathSpec,clientId));var components=aff4Path.split("/");var vfsPath=components.slice(1).join("/");var downloadableVfsRoots=grrUi.core.fileDownloadUtils.downloadableVfsRoots;var legitimatePath=downloadableVfsRoots.some(function(vfsRoot){var prefix=
vfsRoot+"/";return vfsPath.startsWith(prefix)}.bind(this));if(!legitimatePath)return item;var downloadUrl=urlPrefix+"/"+clientId+"/vfs-blob/"+vfsPath;var downloadParams={"timestamp":item["value"]["timestamp"]["value"]};var downloadableItem=angular.copy(item);grrUi.core.fileDownloadUtils.makeValueDownloadable(downloadableItem,downloadUrl,downloadParams);return downloadableItem});return newItems};grrUi.hunt.huntResultsDirective.HuntResultsDirective=function(){return{scope:{huntUrn:"="},restrict:"E",
templateUrl:"/static/angular-components/hunt/hunt-results.html",controller:HuntResultsController,controllerAs:"controller"}};grrUi.hunt.huntResultsDirective.HuntResultsDirective.directive_name="grrHuntResults"});goog.provide("grrUi.hunt.huntStatsDirective.HuntStatsController");goog.provide("grrUi.hunt.huntStatsDirective.HuntStatsDirective");goog.require("grrUi.core.apiService.stripTypeInfo");
goog.scope(function(){var stripTypeInfo=grrUi.core.apiService.stripTypeInfo;grrUi.hunt.huntStatsDirective.HuntStatsController=function($scope,$element,grrApiService){this.scope_=$scope;this.element_=$element;this.grrApiService_=grrApiService;this.stats;this.userCpuStats;this.systemCpuStats;this.networkBytesStats;this.totalClientCount;$scope.$watch("huntUrn",this.onHuntUrnChange_.bind(this))};var HuntStatsController=grrUi.hunt.huntStatsDirective.HuntStatsController;HuntStatsController.prototype.onHuntUrnChange_=
function(huntUrn){if(!angular.isString(huntUrn))return;var components=huntUrn.split("/");var huntId=components[components.length-1];var url="/hunts/"+huntId+"/stats";this.grrApiService_.get(url).then(function success(response){this.stats=response.data["stats"];var strippedStats=stripTypeInfo(this.stats);this.userCpuStats=this.parseStats_(strippedStats["user_cpu_stats"],null);this.systemCpuStats=this.parseStats_(strippedStats["system_cpu_stats"],null);this.networkBytesStats=this.parseStats_(strippedStats["network_bytes_sent_stats"],
this.formatBytes_);if(strippedStats["user_cpu_stats"])this.totalClientCount=strippedStats["user_cpu_stats"]["num"];this.drawHistograms_()}.bind(this))};HuntStatsController.prototype.formatBytes_=function(value){if(value<1024)return value+"B";else return Math.round(value/1024)+"K"};HuntStatsController.prototype.parseStats_=function(stats,xAxisFormatter){if(!stats)return null;var mean=0;if(stats["num"])mean=stats["sum"]/stats["num"];var stdev=0;if(stats["num"])stdev=Math.sqrt(stats["sum_sq"]/stats["num"]-
Math.pow(mean,2));var histogramData=[];var histogramTicks=[];angular.forEach(stats["histogram"]["bins"],function(item,index){var value=item["num"]||0;histogramData.push([index,value]);var range=item["range_max_value"];var xValue=range%1!=0?range.toFixed(1):range;if(xAxisFormatter)xValue=xAxisFormatter(xValue);histogramTicks.push([index+.5,xValue])});return{mean:mean,stdev:stdev,histogram:{data:histogramData,ticks:histogramTicks}}};HuntStatsController.prototype.drawHistograms_=function(){if(this.userCpuStats){var userCpuGraphElement=
this.element_.find(".user-cpu-histogram");this.drawSingleHistogram_(userCpuGraphElement,this.userCpuStats.histogram)}if(this.systemCpuStats){var systemCpuGraphElement=this.element_.find(".system-cpu-histogram");this.drawSingleHistogram_(systemCpuGraphElement,this.systemCpuStats.histogram)}if(this.networkBytesStats){var networkBytesGraphElement=this.element_.find(".network-bytes-histogram");this.drawSingleHistogram_(networkBytesGraphElement,this.networkBytesStats.histogram)}};HuntStatsController.prototype.drawSingleHistogram_=
function(element,histogram){$.plot(element,[{data:histogram["data"],bars:{show:true,lineWidth:1}}],{xaxis:{tickLength:0,ticks:histogram["ticks"]},yaxis:{minTickSize:1,tickDecimals:0}})};grrUi.hunt.huntStatsDirective.HuntStatsDirective=function(){return{scope:{huntUrn:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-stats.html",controller:HuntStatsController,controllerAs:"controller"}};grrUi.hunt.huntStatsDirective.HuntStatsDirective.directive_name="grrHuntStats"});goog.provide("grrUi.hunt.huntStatusIconDirective.HuntStatusIconController");goog.provide("grrUi.hunt.huntStatusIconDirective.HuntStatusIconDirective");goog.scope(function(){grrUi.hunt.huntStatusIconDirective.HuntStatusIconDirective=function(){return{scope:{hunt:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-status-icon.html"}};grrUi.hunt.huntStatusIconDirective.HuntStatusIconDirective.directive_name="grrHuntStatusIcon"});goog.provide("grrUi.hunt.huntsListDirective.HuntsListController");goog.provide("grrUi.hunt.huntsListDirective.HuntsListDirective");goog.require("grrUi.core.utils.stripAff4Prefix");
goog.scope(function(){grrUi.hunt.huntsListDirective.HuntsListController=function($scope,$q,$uibModal,grrDialogService,grrApiService,grrAclDialogService){this.scope_=$scope;this.q_=$q;this.uibModal_=$uibModal;this.grrDialogService_=grrDialogService;this.grrApiService_=grrApiService;this.grrAclDialogService_=grrAclDialogService;this.huntsByUrn={};this.showRobotHunts=false;this.triggerUpdate};var HuntsListController=grrUi.hunt.huntsListDirective.HuntsListController;HuntsListController.prototype.huntsUrl=
"/hunts";HuntsListController.prototype.buildHuntUrl_=function(){var components=this.scope_["selectedHuntUrn"].split("/");var basename=components[components.length-1];return this.huntsUrl+"/"+basename};HuntsListController.prototype.wrapApiPromise_=function(promise,successMessage){return promise.then(function success(){return successMessage}.bind(this),function failure(response){var message=response["data"]["message"];if(response["status"]===403){var subject=response["data"]["subject"];var huntId=grrUi.core.utils.stripAff4Prefix(subject).split("/")[1];
this.grrAclDialogService_.openRequestHuntApprovalDialog(huntId,message)}return this.q_.reject(message)}.bind(this))};HuntsListController.prototype.selectItem=function(item){this.scope_["selectedHuntUrn"]=item.value.urn.value};HuntsListController.prototype.newHunt=function(){var modalScope=this.scope_.$new();modalScope.resolve=function(){modalInstance.close()};modalScope.reject=function(){modalInstance.dismiss()};this.scope_.$on("$destroy",function(){modalScope.$destroy()});var modalInstance=this.uibModal_.open({template:'<grr-new-hunt-wizard-form on-resolve="resolve()" '+
'on-reject="reject()" />',scope:modalScope,windowClass:"wide-modal high-modal",size:"lg"});modalInstance.result.then(function resolve(){this.triggerUpdate()}.bind(this))};HuntsListController.prototype.runHunt=function(){var modalPromise=this.grrDialogService_.openConfirmation("Run this hunt?","Are you sure you want to run this hunt?",function(){var promise=this.grrApiService_.patch(this.buildHuntUrl_(),{state:"STARTED"});return this.wrapApiPromise_(promise,"Hunt started successfully!")}.bind(this));
modalPromise.then(function resolve(){this.triggerUpdate()}.bind(this),function dismiss(){this.triggerUpdate()}.bind(this))};HuntsListController.prototype.stopHunt=function(){var modalPromise=this.grrDialogService_.openConfirmation("Stop this hunt?","Are you sure you want to stop this hunt? Once a hunt is "+"stopped, resuming it is not possible.",function(){var promise=this.grrApiService_.patch(this.buildHuntUrl_(),{state:"STOPPED"});return this.wrapApiPromise_(promise,"Hunt stopped successfully!")}.bind(this));
modalPromise.then(function resolve(){this.triggerUpdate()}.bind(this),function dismiss(){this.triggerUpdate()}.bind(this))};HuntsListController.prototype.modifyHunt=function(){var components=this.scope_["selectedHuntUrn"].split("/");var huntId=components[components.length-1];var argsObj={};var modalPromise=this.grrDialogService_.openDirectiveDialog("grrModifyHuntDialog",{huntId:huntId});modalPromise.then(function resolve(){this.triggerUpdate()}.bind(this),function dismiss(){this.triggerUpdate()}.bind(this))};
HuntsListController.prototype.copyHunt=function(){var modalScope=this.scope_.$new();modalScope.huntUrn=this.scope_["selectedHuntUrn"];modalScope.resolve=function(){modalInstance.close()};modalScope.reject=function(){modalInstance.dismiss()};this.scope_.$on("$destroy",function(){modalScope.$destroy()});var modalInstance=this.uibModal_.open({template:'<grr-new-hunt-wizard-copy-form on-resolve="resolve()" '+'on-reject="reject()" hunt-urn="huntUrn" />',scope:modalScope,windowClass:"wide-modal high-modal",
size:"lg"});modalInstance.result.then(function resolve(){this.triggerUpdate()}.bind(this))};HuntsListController.prototype.deleteHunt=function(){var modalPromise=this.grrDialogService_.openConfirmation("Delete this hunt?","Are you sure you want to delete this hunt?",function(){var promise=this.grrApiService_.delete(this.buildHuntUrl_());return this.wrapApiPromise_(promise,"Hunt deleted successfully!")}.bind(this));modalPromise.then(function resolve(){this.triggerUpdate()}.bind(this),function dismiss(){this.triggerUpdate()}.bind(this))};
HuntsListController.prototype.transformItems=function(items){angular.forEach(items,function(item){this.huntsByUrn[item.value.urn.value]=item}.bind(this));return items};grrUi.hunt.huntsListDirective.HuntsListDirective=function(){return{scope:{selectedHuntUrn:"=?"},restrict:"E",templateUrl:"/static/angular-components/hunt/hunts-list.html",controller:HuntsListController,controllerAs:"controller"}};grrUi.hunt.huntsListDirective.HuntsListDirective.directive_name="grrHuntsList"});goog.provide("grrUi.hunt.huntsViewDirective.HuntsViewController");goog.provide("grrUi.hunt.huntsViewDirective.HuntsViewDirective");
goog.scope(function(){grrUi.hunt.huntsViewDirective.HuntsViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.selectedHuntUrn;this.tab;this.scope_.$watchGroup(["controller.selectedHuntUrn","controller.tab"],this.onSelectionChange_.bind(this));this.grrRoutingService_.uiOnParamsChanged(this.scope_,["huntId","tab"],this.onParamsChange_.bind(this))};var HuntsViewController=grrUi.hunt.huntsViewDirective.HuntsViewController;HuntsViewController.prototype.onParamsChange_=
function(newValues,opt_stateParams){if(opt_stateParams["huntId"])this.selectedHuntUrn="aff4:/hunts/"+opt_stateParams["huntId"];this.tab=opt_stateParams["tab"]};HuntsViewController.prototype.onSelectionChange_=function(){if(angular.isDefined(this.selectedHuntUrn)){var huntId=this.selectedHuntUrn.split("/")[2];this.grrRoutingService_.go("hunts",{huntId:huntId,tab:this.tab})}};grrUi.hunt.huntsViewDirective.HuntsViewDirective=function(){return{restrict:"E",scope:{},templateUrl:"/static/angular-components/hunt/hunts-view.html",
controller:HuntsViewController,controllerAs:"controller"}};grrUi.hunt.huntsViewDirective.HuntsViewDirective.directive_name="grrHuntsView"});goog.provide("grrUi.hunt.modifyHuntDialogDirective.ModifyHuntDialogController");goog.provide("grrUi.hunt.modifyHuntDialogDirective.ModifyHuntDialogDirective");goog.require("grrUi.core.apiService.stripTypeInfo");goog.require("grrUi.core.utils.stripAff4Prefix");
goog.scope(function(){var stripTypeInfo=grrUi.core.apiService.stripTypeInfo;grrUi.hunt.modifyHuntDialogDirective.ModifyHuntDialogController=function($scope,$q,grrApiService,grrAclDialogService){this.scope_=$scope;this.q_=$q;this.grrApiService_=grrApiService;this.grrAclDialogService_=grrAclDialogService;this.argsObj;this.scope_.$watch("huntId",this.onHuntIdChange_.bind(this))};var ModifyHuntDialogController=grrUi.hunt.modifyHuntDialogDirective.ModifyHuntDialogController;ModifyHuntDialogController.prototype.onHuntIdChange_=
function(newValue){this.argsObj=undefined;if(angular.isString(newValue))this.grrApiService_.get("/hunts/"+newValue).then(function(response){var hunt=response["data"];this.argsObj={type:"ApiModifyHuntArgs",value:{}};angular.forEach(["client_limit","client_rate","expires"],function(k){var v=hunt["value"][k];if(v)this.argsObj["value"][k]=angular.copy(v)}.bind(this))}.bind(this))};ModifyHuntDialogController.prototype.proceed=function(){var request=stripTypeInfo(this.argsObj);return this.grrApiService_.patch("/hunts/"+
this.scope_["huntId"],request).then(function success(){return"Hunt modified successfully!"}.bind(this),function failure(response){var message=response["data"]["message"];if(response["status"]===403){var subject=response["data"]["subject"];var huntId=grrUi.core.utils.stripAff4Prefix(subject).split("/")[1];this.grrAclDialogService_.openRequestHuntApprovalDialog(huntId,message)}return this.q_.reject(message)}.bind(this))};grrUi.hunt.modifyHuntDialogDirective.ModifyHuntDialogDirective=function(){return{scope:{huntId:"="},
restrict:"E",templateUrl:"/static/angular-components/hunt/modify-hunt-dialog.html",controller:ModifyHuntDialogController,controllerAs:"controller"}};grrUi.hunt.modifyHuntDialogDirective.ModifyHuntDialogDirective.directive_name="grrModifyHuntDialog"});goog.provide("grrUi.hunt.newHuntWizard.configureFlowPageDirective.ConfigureFlowPageController");goog.provide("grrUi.hunt.newHuntWizard.configureFlowPageDirective.ConfigureFlowPageDirective");goog.require("grrUi.forms.utils.valueHasErrors");
goog.scope(function(){var valueHasErrors=grrUi.forms.utils.valueHasErrors;grrUi.hunt.newHuntWizard.configureFlowPageDirective.ConfigureFlowPageController=function($scope){this.scope_=$scope;this.flowDescriptor;this.scope_.$watch("controller.flowDescriptor",function(flowDescriptor){if(angular.isUndefined(flowDescriptor))return;this.scope_.flowName=flowDescriptor["value"]["name"]["value"];this.scope_["flowArguments"]=angular.copy(flowDescriptor["value"]["default_args"])}.bind(this));this.scope_.$watch("flowArguments",
this.onFlowArgumentsDeepChange_.bind(this),true)};var ConfigureFlowPageController=grrUi.hunt.newHuntWizard.configureFlowPageDirective.ConfigureFlowPageController;ConfigureFlowPageController.prototype.onFlowArgumentsDeepChange_=function(newValue){this.scope_["hasErrors"]=valueHasErrors(newValue)};grrUi.hunt.newHuntWizard.configureFlowPageDirective.ConfigureFlowPageDirective=function(){return{scope:{flowName:"=",flowArguments:"=",hasErrors:"=?"},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/"+
"configure-flow-page.html",controller:ConfigureFlowPageController,controllerAs:"controller"}};grrUi.hunt.newHuntWizard.configureFlowPageDirective.ConfigureFlowPageDirective.directive_name="grrConfigureFlowPage"});goog.provide("grrUi.hunt.newHuntWizard.configureHuntPageDirective.ConfigureHuntPageController");goog.provide("grrUi.hunt.newHuntWizard.configureHuntPageDirective.ConfigureHuntPageDirective");
goog.scope(function(){grrUi.hunt.newHuntWizard.configureHuntPageDirective.ConfigureHuntPageDirective=function(){return{scope:{huntRunnerArgs:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/"+"configure-hunt-page.html"}};grrUi.hunt.newHuntWizard.configureHuntPageDirective.ConfigureHuntPageDirective.directive_name="grrConfigureHuntPage"});goog.provide("grrUi.hunt.newHuntWizard.configureOutputPluginsPageDirective.ConfigureOutputPluginsPageController");goog.provide("grrUi.hunt.newHuntWizard.configureOutputPluginsPageDirective.ConfigureOutputPluginsPageDirective");
goog.scope(function(){grrUi.hunt.newHuntWizard.configureOutputPluginsPageDirective.ConfigureOutputPluginsPageController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.outputPluginsField;this.outputPluginDescriptor;this.grrReflectionService_.getRDFValueDescriptor("GenericHuntArgs",true).then(this.onDescriptors_.bind(this))};var ConfigureOutputPluginsPageController=grrUi.hunt.newHuntWizard.configureOutputPluginsPageDirective.ConfigureOutputPluginsPageController;
ConfigureOutputPluginsPageController.prototype.onDescriptors_=function(descriptors){angular.forEach(descriptors["GenericHuntArgs"]["fields"],function(field){if(field.name=="output_plugins")this.outputPluginsField=field}.bind(this));this.outputPluginDescriptor=descriptors["OutputPluginDescriptor"]};grrUi.hunt.newHuntWizard.configureOutputPluginsPageDirective.ConfigureOutputPluginsPageDirective=function(){return{scope:{outputPlugins:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/"+
"configure-output-plugins-page.html",controller:ConfigureOutputPluginsPageController,controllerAs:"controller"}};grrUi.hunt.newHuntWizard.configureOutputPluginsPageDirective.ConfigureOutputPluginsPageDirective.directive_name="grrConfigureOutputPluginsPage"});goog.provide("grrUi.hunt.newHuntWizard.configureRulesPageDirective.ConfigureRulesPageDirective");goog.scope(function(){grrUi.hunt.newHuntWizard.configureRulesPageDirective.ConfigureRulesPageDirective=function(){return{scope:{clientRuleSet:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/"+"configure-rules-page.html"}};grrUi.hunt.newHuntWizard.configureRulesPageDirective.ConfigureRulesPageDirective.directive_name="grrConfigureRulesPage"});goog.provide("grrUi.hunt.newHuntWizard.copyFormDirective.CopyFormController");goog.provide("grrUi.hunt.newHuntWizard.copyFormDirective.CopyFormDirective");
goog.scope(function(){grrUi.hunt.newHuntWizard.copyFormDirective.CopyFormController=function($scope,grrReflectionService,grrApiService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.grrApiService_=grrApiService;this.createHuntArgs;this.createHuntArgsDescriptor;this.grrReflectionService_.getRDFValueDescriptor("ApiCreateHuntArgs",true).then(function(descriptor){this.createHuntArgsDescriptor=descriptor["ApiCreateHuntArgs"];this.huntRefDescriptor=descriptor["ApiHuntReference"];
this.scope_.$watch("huntUrn",this.onHuntUrnChange_.bind(this))}.bind(this))};var CopyFormController=grrUi.hunt.newHuntWizard.copyFormDirective.CopyFormController;CopyFormController.prototype.onHuntUrnChange_=function(){if(angular.isDefined(this.scope_.huntUrn)){var huntUrnComponents=this.scope_.huntUrn.split("/");this.huntId=huntUrnComponents[huntUrnComponents.length-1];this.grrApiService_.get("hunts/"+this.huntId).then(this.onHuntFetched_.bind(this))}};CopyFormController.prototype.onHuntFetched_=
function(response){var hunt=response["data"];this.createHuntArgs=angular.copy(this.createHuntArgsDescriptor["default"]);this.createHuntArgs["value"]["flow_name"]=angular.copy(hunt["value"]["flow_name"]);this.createHuntArgs["value"]["flow_args"]=angular.copy(hunt["value"]["flow_args"]);var huntRunnerArgs=this.createHuntArgs["value"]["hunt_runner_args"]=angular.copy(hunt["value"]["hunt_runner_args"]);if(angular.isDefined(huntRunnerArgs["value"]["description"]))huntRunnerArgs["value"]["description"]["value"]+=
" (copy)";this.createHuntArgs["value"]["original_hunt"]=angular.copy(this.huntRefDescriptor["default"]);this.createHuntArgs["value"]["original_hunt"]["value"]["hunt_id"]=hunt["value"]["hunt_id"]};grrUi.hunt.newHuntWizard.copyFormDirective.CopyFormDirective=function(){return{scope:{huntUrn:"=",onResolve:"&",onReject:"&"},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/"+"copy-form.html",controller:CopyFormController,controllerAs:"controller"}};grrUi.hunt.newHuntWizard.copyFormDirective.CopyFormDirective.directive_name=
"grrNewHuntWizardCopyForm"});goog.provide("grrUi.hunt.newHuntWizard.createHuntFromFlowFormDirective.CreateHuntFromFlowFormController");goog.provide("grrUi.hunt.newHuntWizard.createHuntFromFlowFormDirective.CreateHuntFromFlowFormDirective");
goog.scope(function(){grrUi.hunt.newHuntWizard.createHuntFromFlowFormDirective.CreateHuntFromFlowFormController=function($scope,grrApiService,grrReflectionService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrReflectionService_=grrReflectionService;this.createHuntArgs;this.flow_;this.descriptors_={};this.grrReflectionService_.getRDFValueDescriptor("ApiCreateHuntArgs",true).then(function(descriptors){angular.extend(this.descriptors_,descriptors);this.scope_.$watchGroup(["flowId","clientId"],
this.onFlowIdClientIdChange_.bind(this))}.bind(this))};var CreateHuntFromFlowFormController=grrUi.hunt.newHuntWizard.createHuntFromFlowFormDirective.CreateHuntFromFlowFormController;CreateHuntFromFlowFormController.prototype.onFlowIdClientIdChange_=function(newValues){if(newValues.every(angular.isDefined)){var flowUrl=["clients",this.scope_["clientId"],"flows",this.scope_["flowId"]].join("/");this.grrApiService_.get(flowUrl).then(function(response){this.flow_=response["data"]}.bind(this)).then(this.onFlowDataFetched_.bind(this))}};
CreateHuntFromFlowFormController.prototype.onFlowDataFetched_=function(){var huntArgs=angular.copy(this.descriptors_["ApiCreateHuntArgs"]["default"]);huntArgs["value"]["flow_name"]=angular.copy(this.flow_["value"]["name"]);huntArgs["value"]["flow_args"]=angular.copy(this.flow_["value"]["args"]);huntArgs["value"]["original_flow"]=angular.copy(this.descriptors_["FlowReference"]["default"]);huntArgs["value"]["original_flow"]["value"]["flow_id"]=this.flow_["value"]["flow_id"]["value"];huntArgs["value"]["original_flow"]["value"]["client_id"]=
this.scope_["clientId"];this.createHuntArgs=huntArgs};grrUi.hunt.newHuntWizard.createHuntFromFlowFormDirective.CreateHuntFromFlowFormDirective=function(){return{scope:{flowId:"=",clientId:"=",onResolve:"&",onReject:"&"},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/"+"create-hunt-from-flow-form.html",controller:CreateHuntFromFlowFormController,controllerAs:"controller"}};grrUi.hunt.newHuntWizard.createHuntFromFlowFormDirective.CreateHuntFromFlowFormDirective.directive_name=
"grrNewHuntWizardCreateFromFlowForm"});goog.provide("grrUi.hunt.newHuntWizard.reviewPageDirective.ReviewPageDirective");goog.scope(function(){grrUi.hunt.newHuntWizard.reviewPageDirective.ReviewPageDirective=function(){return{scope:{createHuntArgs:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/"+"review-page.html"}};grrUi.hunt.newHuntWizard.reviewPageDirective.ReviewPageDirective.directive_name="grrNewHuntReviewPage"});goog.provide("grrUi.hunt.newHuntWizard.statusPageDirective.StatusPageDirective");goog.scope(function(){grrUi.hunt.newHuntWizard.statusPageDirective.StatusPageDirective=function(){return{scope:{response:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/"+"status-page.html"}};grrUi.hunt.newHuntWizard.statusPageDirective.StatusPageDirective.directive_name="grrNewHuntStatusPage"});goog.provide("grrUi.hunt.newHuntWizard.module");goog.require("grrUi.core.module");goog.require("grrUi.hunt.newHuntWizard.configureFlowPageDirective.ConfigureFlowPageDirective");goog.require("grrUi.hunt.newHuntWizard.configureHuntPageDirective.ConfigureHuntPageDirective");goog.require("grrUi.hunt.newHuntWizard.configureOutputPluginsPageDirective.ConfigureOutputPluginsPageDirective");goog.require("grrUi.hunt.newHuntWizard.configureRulesPageDirective.ConfigureRulesPageDirective");goog.require("grrUi.hunt.newHuntWizard.copyFormDirective.CopyFormDirective");
goog.require("grrUi.hunt.newHuntWizard.createHuntFromFlowFormDirective.CreateHuntFromFlowFormDirective");goog.require("grrUi.hunt.newHuntWizard.formDirective.FormDirective");goog.require("grrUi.hunt.newHuntWizard.reviewPageDirective.ReviewPageDirective");goog.require("grrUi.hunt.newHuntWizard.statusPageDirective.StatusPageDirective");grrUi.hunt.newHuntWizard.module=angular.module("grrUi.hunt.newHuntWizard",["ui.bootstrap",grrUi.core.module.name]);
grrUi.hunt.newHuntWizard.module.directive(grrUi.hunt.newHuntWizard.configureFlowPageDirective.ConfigureFlowPageDirective.directive_name,grrUi.hunt.newHuntWizard.configureFlowPageDirective.ConfigureFlowPageDirective);grrUi.hunt.newHuntWizard.module.directive(grrUi.hunt.newHuntWizard.configureHuntPageDirective.ConfigureHuntPageDirective.directive_name,grrUi.hunt.newHuntWizard.configureHuntPageDirective.ConfigureHuntPageDirective);
grrUi.hunt.newHuntWizard.module.directive(grrUi.hunt.newHuntWizard.configureOutputPluginsPageDirective.ConfigureOutputPluginsPageDirective.directive_name,grrUi.hunt.newHuntWizard.configureOutputPluginsPageDirective.ConfigureOutputPluginsPageDirective);grrUi.hunt.newHuntWizard.module.directive(grrUi.hunt.newHuntWizard.configureRulesPageDirective.ConfigureRulesPageDirective.directive_name,grrUi.hunt.newHuntWizard.configureRulesPageDirective.ConfigureRulesPageDirective);
grrUi.hunt.newHuntWizard.module.directive(grrUi.hunt.newHuntWizard.reviewPageDirective.ReviewPageDirective.directive_name,grrUi.hunt.newHuntWizard.reviewPageDirective.ReviewPageDirective);grrUi.hunt.newHuntWizard.module.directive(grrUi.hunt.newHuntWizard.statusPageDirective.StatusPageDirective.directive_name,grrUi.hunt.newHuntWizard.statusPageDirective.StatusPageDirective);grrUi.hunt.newHuntWizard.module.directive(grrUi.hunt.newHuntWizard.copyFormDirective.CopyFormDirective.directive_name,grrUi.hunt.newHuntWizard.copyFormDirective.CopyFormDirective);
grrUi.hunt.newHuntWizard.module.directive(grrUi.hunt.newHuntWizard.formDirective.FormDirective.directive_name,grrUi.hunt.newHuntWizard.formDirective.FormDirective);grrUi.hunt.newHuntWizard.module.directive(grrUi.hunt.newHuntWizard.createHuntFromFlowFormDirective.CreateHuntFromFlowFormDirective.directive_name,grrUi.hunt.newHuntWizard.createHuntFromFlowFormDirective.CreateHuntFromFlowFormDirective);goog.provide("grrUi.hunt.module");goog.require("grrUi.core.module");goog.require("grrUi.hunt.huntClientsDirective.HuntClientsDirective");goog.require("grrUi.hunt.huntContextDirective.HuntContextDirective");goog.require("grrUi.hunt.huntCrashesDirective.HuntCrashesDirective");goog.require("grrUi.hunt.huntErrorsDirective.HuntErrorsDirective");goog.require("grrUi.hunt.huntGraphDirective.HuntGraphDirective");goog.require("grrUi.hunt.huntInspectorDirective.HuntInspectorDirective");goog.require("grrUi.hunt.huntLogDirective.HuntLogDirective");
goog.require("grrUi.hunt.huntOverviewDirective.HuntOverviewDirective");goog.require("grrUi.hunt.huntResultsDirective.HuntResultsDirective");goog.require("grrUi.hunt.huntStatsDirective.HuntStatsDirective");goog.require("grrUi.hunt.huntStatusIconDirective.HuntStatusIconDirective");goog.require("grrUi.hunt.huntsListDirective.HuntsListDirective");goog.require("grrUi.hunt.huntsViewDirective.HuntsViewDirective");goog.require("grrUi.hunt.modifyHuntDialogDirective.ModifyHuntDialogDirective");goog.require("grrUi.hunt.newHuntWizard.module");
grrUi.hunt.module=angular.module("grrUi.hunt",["ui.bootstrap",grrUi.core.module.name,grrUi.hunt.newHuntWizard.module.name]);grrUi.hunt.module.directive(grrUi.hunt.huntClientsDirective.HuntClientsDirective.directive_name,grrUi.hunt.huntClientsDirective.HuntClientsDirective);grrUi.hunt.module.directive(grrUi.hunt.huntContextDirective.HuntContextDirective.directive_name,grrUi.hunt.huntContextDirective.HuntContextDirective);
grrUi.hunt.module.directive(grrUi.hunt.huntCrashesDirective.HuntCrashesDirective.directive_name,grrUi.hunt.huntCrashesDirective.HuntCrashesDirective);grrUi.hunt.module.directive(grrUi.hunt.huntErrorsDirective.HuntErrorsDirective.directive_name,grrUi.hunt.huntErrorsDirective.HuntErrorsDirective);grrUi.hunt.module.directive(grrUi.hunt.huntGraphDirective.HuntGraphDirective.directive_name,grrUi.hunt.huntGraphDirective.HuntGraphDirective);
grrUi.hunt.module.directive(grrUi.hunt.huntInspectorDirective.HuntInspectorDirective.directive_name,grrUi.hunt.huntInspectorDirective.HuntInspectorDirective);grrUi.hunt.module.directive(grrUi.hunt.huntLogDirective.HuntLogDirective.directive_name,grrUi.hunt.huntLogDirective.HuntLogDirective);grrUi.hunt.module.directive(grrUi.hunt.huntOverviewDirective.HuntOverviewDirective.directive_name,grrUi.hunt.huntOverviewDirective.HuntOverviewDirective);
grrUi.hunt.module.directive(grrUi.hunt.huntResultsDirective.HuntResultsDirective.directive_name,grrUi.hunt.huntResultsDirective.HuntResultsDirective);grrUi.hunt.module.directive(grrUi.hunt.huntStatusIconDirective.HuntStatusIconDirective.directive_name,grrUi.hunt.huntStatusIconDirective.HuntStatusIconDirective);grrUi.hunt.module.directive(grrUi.hunt.huntStatsDirective.HuntStatsDirective.directive_name,grrUi.hunt.huntStatsDirective.HuntStatsDirective);
grrUi.hunt.module.directive(grrUi.hunt.huntsListDirective.HuntsListDirective.directive_name,grrUi.hunt.huntsListDirective.HuntsListDirective);grrUi.hunt.module.directive(grrUi.hunt.huntsViewDirective.HuntsViewDirective.directive_name,grrUi.hunt.huntsViewDirective.HuntsViewDirective);grrUi.hunt.module.directive(grrUi.hunt.modifyHuntDialogDirective.ModifyHuntDialogDirective.directive_name,grrUi.hunt.modifyHuntDialogDirective.ModifyHuntDialogDirective);goog.provide("grrUi.local.module");grrUi.local.module=angular.module("grrUi.local",[]);goog.provide("grrUi.outputPlugins.outputPluginLogsDirective.OutputPluginLogsController");goog.provide("grrUi.outputPlugins.outputPluginLogsDirective.OutputPluginLogsDirective");
goog.scope(function(){grrUi.outputPlugins.outputPluginLogsDirective.OutputPluginLogsController=function($scope,$uibModal,grrApiService){this.scope_=$scope;this.uibModal_=$uibModal;this.grrApiService_=grrApiService;this.itemsCount;this.scope_.$watch("url",this.onUrlChange_.bind(this))};var OutputPluginLogsController=grrUi.outputPlugins.outputPluginLogsDirective.OutputPluginLogsController;OutputPluginLogsController.prototype.onUrlChange_=function(newValue){if(angular.isDefined(newValue))this.grrApiService_.get(newValue,
{count:1}).then(function(response){this.itemsCount=response["data"]["total_count"]}.bind(this))};OutputPluginLogsController.prototype.onClick=function(){this.uibModal_.open({templateUrl:"/static/angular-components/output-plugins/"+"output-plugin-logs-modal.html",scope:this.scope_,windowClass:"wide-modal high-modal",size:"lg"})};grrUi.outputPlugins.outputPluginLogsDirective.OutputPluginLogsDirective=function(){return{scope:{url:"=",label:"@",cssClass:"@",icon:"@"},restrict:"E",templateUrl:"/static/angular-components/output-plugins/"+
"output-plugin-logs.html",controller:OutputPluginLogsController,controllerAs:"controller"}};grrUi.outputPlugins.outputPluginLogsDirective.OutputPluginLogsDirective.directive_name="grrOutputPluginLogs"});goog.provide("grrUi.outputPlugins.outputPluginNoteBodyDirective.OutputPluginNoteBodyController");goog.provide("grrUi.outputPlugins.outputPluginNoteBodyDirective.OutputPluginNoteBodyDirective");
goog.scope(function(){grrUi.outputPlugins.outputPluginNoteBodyDirective.OutputPluginNoteBodyController=function($scope,$compile,$element,grrOutputPluginsDirectivesRegistryService){this.scope_=$scope;this.scope_.outputPlugin;this.compile_=$compile;this.element_=$element;this.grrOutputPluginsDirectivesRegistryService_=grrOutputPluginsDirectivesRegistryService;this.scope_.$watch("outputPlugin",this.onOutputPluginChange_.bind(this))};var OutputPluginNoteBodyController=grrUi.outputPlugins.outputPluginNoteBodyDirective.OutputPluginNoteBodyController;
OutputPluginNoteBodyController.prototype.camelCaseToDashDelimited=function(directiveName){return directiveName.replace(/([a-z\d])([A-Z])/g,"$1-$2").toLowerCase()};OutputPluginNoteBodyController.prototype.onOutputPluginChange_=function(){if(angular.isDefined(this.scope_["outputPlugin"])){var descriptor=this.scope_["outputPlugin"]["value"]["plugin_descriptor"];var pluginName=descriptor["value"]["plugin_name"]["value"];var directive=this.grrOutputPluginsDirectivesRegistryService_.findDirectiveForMro([pluginName]);
if(angular.isDefined(directive)){var element=angular.element("<span />");element.html("<"+this.camelCaseToDashDelimited(directive.directive_name)+' output-plugin="outputPlugin" />');var template=this.compile_(element);template(this.scope_,function(cloned,opt_scope){this.element_.html("");this.element_.append(cloned)}.bind(this))}else this.element_.html("")}};grrUi.outputPlugins.outputPluginNoteBodyDirective.OutputPluginNoteBodyDirective=function(){return{scope:{outputPlugin:"="},restrict:"E",controller:OutputPluginNoteBodyController,
controllerAs:"controller"}};grrUi.outputPlugins.outputPluginNoteBodyDirective.OutputPluginNoteBodyDirective.directive_name="grrOutputPluginNoteBody"});goog.provide("grrUi.outputPlugins.outputPluginNoteDirective.OutputPluginNoteController");goog.provide("grrUi.outputPlugins.outputPluginNoteDirective.OutputPluginNoteDirective");
goog.scope(function(){grrUi.outputPlugins.outputPluginNoteDirective.OutputPluginNoteController=function($scope,grrOutputPluginsDirectivesRegistryService){this.scope_=$scope;this.scope_.outputPlugin;this.pluginTitle;this.pluginLogsUrl;this.pluginErrorsUrl;this.grrOutputPluginsDirectivesRegistryService_=grrOutputPluginsDirectivesRegistryService;this.scope_.$watchGroup(["outputPlugin","outputPluginsUrl"],this.onOutputPluginChange_.bind(this))};var OutputPluginNoteController=grrUi.outputPlugins.outputPluginNoteDirective.OutputPluginNoteController;
OutputPluginNoteController.prototype.onOutputPluginChange_=function(){if(angular.isDefined(this.scope_["outputPlugin"])&&angular.isDefined(this.scope_["outputPluginsUrl"])){var descriptor=this.scope_["outputPlugin"]["value"]["plugin_descriptor"];var pluginName=descriptor["value"]["plugin_name"]["value"];var directive=this.grrOutputPluginsDirectivesRegistryService_.findDirectiveForMro([pluginName]);if(angular.isDefined(directive))this.pluginTitle=directive.output_plugin_title;else this.pluginTitle=
pluginName;var logsUrlBase=this.scope_["outputPluginsUrl"]+"/"+this.scope_["outputPlugin"]["value"]["id"]["value"];this.pluginLogsUrl=logsUrlBase+"/logs";this.pluginErrorsUrl=logsUrlBase+"/errors"}};grrUi.outputPlugins.outputPluginNoteDirective.OutputPluginNoteDirective=function(){return{scope:{outputPluginsUrl:"=",outputPlugin:"="},restrict:"E",templateUrl:"/static/angular-components/output-plugins/"+"output-plugin-note.html",controller:OutputPluginNoteController,controllerAs:"controller"}};grrUi.outputPlugins.outputPluginNoteDirective.OutputPluginNoteDirective.directive_name=
"grrOutputPluginNote"});goog.provide("grrUi.outputPlugins.outputPluginsNotesDirective.OutputPluginsNotesController");goog.provide("grrUi.outputPlugins.outputPluginsNotesDirective.OutputPluginsNotesDirective");
goog.scope(function(){grrUi.outputPlugins.outputPluginsNotesDirective.OutputPluginsNotesController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.error;this.outputPlugins;this.scope_.$watch("outputPluginsUrl",this.onOutputPluginsUrlChange_.bind(this))};var OutputPluginsNotesController=grrUi.outputPlugins.outputPluginsNotesDirective.OutputPluginsNotesController;OutputPluginsNotesController.prototype.onOutputPluginsUrlChange_=function(newValue){if(angular.isDefined(newValue))this.grrApiService_.get(newValue).then(function success(response){this.outputPlugins=
response["data"]["items"]}.bind(this),function failure(response){this.error=response["data"]["message"]}.bind(this))};grrUi.outputPlugins.outputPluginsNotesDirective.OutputPluginsNotesDirective=function(){return{scope:{outputPluginsUrl:"="},restrict:"E",templateUrl:"/static/angular-components/output-plugins/"+"output-plugins-notes.html",controller:OutputPluginsNotesController,controllerAs:"controller"}};grrUi.outputPlugins.outputPluginsNotesDirective.OutputPluginsNotesDirective.directive_name="grrOutputPluginsNotes"});goog.provide("grrUi.outputPlugins.module");goog.require("grrUi.core.module");goog.require("grrUi.core.semanticRegistry.SemanticRegistryService");goog.require("grrUi.outputPlugins.outputPluginLogsDirective.OutputPluginLogsDirective");goog.require("grrUi.outputPlugins.outputPluginNoteBodyDirective.OutputPluginNoteBodyDirective");goog.require("grrUi.outputPlugins.outputPluginNoteDirective.OutputPluginNoteDirective");goog.require("grrUi.outputPlugins.outputPluginsNotesDirective.OutputPluginsNotesDirective");
grrUi.outputPlugins.module=angular.module("grrUi.outputPlugins",[grrUi.core.module.name,"ui.bootstrap"]);grrUi.outputPlugins.module.directive(grrUi.outputPlugins.outputPluginsNotesDirective.OutputPluginsNotesDirective.directive_name,grrUi.outputPlugins.outputPluginsNotesDirective.OutputPluginsNotesDirective);grrUi.outputPlugins.module.directive(grrUi.outputPlugins.outputPluginLogsDirective.OutputPluginLogsDirective.directive_name,grrUi.outputPlugins.outputPluginLogsDirective.OutputPluginLogsDirective);
grrUi.outputPlugins.module.directive(grrUi.outputPlugins.outputPluginNoteDirective.OutputPluginNoteDirective.directive_name,grrUi.outputPlugins.outputPluginNoteDirective.OutputPluginNoteDirective);grrUi.outputPlugins.module.directive(grrUi.outputPlugins.outputPluginNoteBodyDirective.OutputPluginNoteBodyDirective.directive_name,grrUi.outputPlugins.outputPluginNoteBodyDirective.OutputPluginNoteBodyDirective);
grrUi.outputPlugins.module.service(grrUi.core.semanticRegistry.SemanticRegistryService.output_plugins_service_name,grrUi.core.semanticRegistry.SemanticRegistryService);grrUi.outputPlugins.module.run(function(grrOutputPluginsDirectivesRegistryService){});goog.provide("grrUi.sidebar.clientSummaryDirective.ClientSummaryController");goog.provide("grrUi.sidebar.clientSummaryDirective.ClientSummaryDirective");
goog.scope(function(){grrUi.sidebar.clientSummaryDirective.ClientSummaryController=function($scope,grrApiService,grrTimeService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrTimeService_=grrTimeService;this.approvalReason;this.lastIP;this.crashTime;this.scope_.$watch("client",this.onClientChange_.bind(this))};var ClientSummaryController=grrUi.sidebar.clientSummaryDirective.ClientSummaryController;ClientSummaryController.prototype.onClientChange_=function(){if(!this.scope_["client"])return;
if(this.scope_["client"]["value"]["last_crash_at"]){var currentTimeMs=this.grrTimeService_.getCurrentTimeMs();var crashTime=this.scope_["client"]["value"]["last_crash_at"]["value"];if(angular.isDefined(crashTime)&&currentTimeMs/1E3-crashTime/1E6<60*60*24)this.crashTime=crashTime}var clientUrn=this.scope_["client"]["value"]["urn"]["value"];var clientId=clientUrn.split("/")[1];var lastIPUrl="clients/"+clientId+"/last-ip";this.grrApiService_.get(lastIPUrl).then(function(response){this.lastIP=response.data}.bind(this));
var approvalUrl="users/me/approvals/client/"+clientId;this.grrApiService_.get(approvalUrl).then(function(response){var approvals=response.data["items"];if(approvals&&approvals.length)this.approvalReason=approvals[0]["value"]["reason"]["value"]}.bind(this))};grrUi.sidebar.clientSummaryDirective.ClientSummaryDirective=function(){return{scope:{client:"="},restrict:"E",templateUrl:"/static/angular-components/sidebar/client-summary.html",controller:ClientSummaryController,controllerAs:"controller"}};grrUi.sidebar.clientSummaryDirective.ClientSummaryDirective.directive_name=
"grrClientSummary"});goog.provide("grrUi.sidebar.navDropdownDirective.NavDropdownController");goog.provide("grrUi.sidebar.navDropdownDirective.NavDropdownDirective");
goog.scope(function(){grrUi.sidebar.navDropdownDirective.NavDropdownController=function(){this.isCollapsed=true};var NavDropdownController=grrUi.sidebar.navDropdownDirective.NavDropdownController;grrUi.sidebar.navDropdownDirective.NavDropdownDirective=function(){return{scope:{title:"@"},restrict:"A",transclude:true,templateUrl:"/static/angular-components/sidebar/nav-dropdown.html",controller:NavDropdownController,controllerAs:"controller"}};grrUi.sidebar.navDropdownDirective.NavDropdownDirective.directive_name=
"grrNavDropdown"});goog.provide("grrUi.sidebar.navLinkDirective.NavLinkController");goog.provide("grrUi.sidebar.navLinkDirective.NavLinkDirective");
goog.scope(function(){grrUi.sidebar.navLinkDirective.NavLinkController=function($scope,$element,grrRoutingService){this.scope_=$scope;this.element_=$element;this.grrRoutingService_=grrRoutingService;this.navDropdownController;this.isActive=false;this.href;this.scope_.$watchGroup(["state","params"],this.onStateOrParamsChange_.bind(this));this.grrRoutingService_.onStateChange(this.scope_,this.applyActiveState_.bind(this))};var NavLinkController=grrUi.sidebar.navLinkDirective.NavLinkController;NavLinkController.prototype.onStateOrParamsChange_=
function(){this.href="#";if(angular.isDefined(this.scope_["state"]))this.href=this.grrRoutingService_.href(this.scope_["state"],this.scope_["params"])};NavLinkController.prototype.openLink=function(event){event.preventDefault();if(this.scope_["disabled"])return;this.grrRoutingService_.go(this.scope_["state"],this.scope_["params"])};NavLinkController.prototype.applyActiveState_=function(activeState){this.isActive=activeState===this.scope_["state"];if(this.isActive){this.element_.addClass("active");
if(this.navDropdownController)this.navDropdownController.isCollapsed=false}else this.element_.removeClass("active")};grrUi.sidebar.navLinkDirective.NavLinkDirective=function(){return{scope:{state:"@",params:"=?",disabled:"=?"},restrict:"A",require:"?^grrNavDropdown",transclude:true,templateUrl:"/static/angular-components/sidebar/nav-link.html",controller:NavLinkController,controllerAs:"controller",link:function(scope,elem,attr,navDropdownController){scope.controller.navDropdownController=navDropdownController}}};
grrUi.sidebar.navLinkDirective.NavLinkDirective.directive_name="grrNavLink"});goog.provide("grrUi.sidebar.navigatorDirective.NavigatorController");goog.provide("grrUi.sidebar.navigatorDirective.NavigatorDirective");goog.require("grrUi.core.apiService.stripTypeInfo");
goog.scope(function(){var stripTypeInfo=grrUi.core.apiService.stripTypeInfo;grrUi.sidebar.navigatorDirective.NavigatorController=function($scope,grrApiService,grrRoutingService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.client;this.clientId;this.hasClientAccess=false;this.uiTraits;this.grrApiService_.getCached("users/me").then(function(response){this.uiTraits=stripTypeInfo(response["data"])["interface_traits"]}.bind(this));this.grrRoutingService_.uiOnParamsChanged(this.scope_,
"clientId",this.onClientSelectionChange_.bind(this),true)};var NavigatorController=grrUi.sidebar.navigatorDirective.NavigatorController;NavigatorController.prototype.onClientSelectionChange_=function(clientId){if(!clientId)return;if(clientId.indexOf("aff4:/")===0)clientId=clientId.split("/")[1];if(this.clientId===clientId)return;this.clientId=clientId;this.client=null;this.refreshClientDetails();this.checkClientAccess_()};NavigatorController.prototype.refreshClientDetails=function(){var url="clients/"+
this.clientId;this.grrApiService_.get(url).then(this.onClientDetailsFetched_.bind(this))};NavigatorController.prototype.onClientDetailsFetched_=function(response){this.client=response["data"]};NavigatorController.prototype.checkClientAccess_=function(){this.grrApiService_.head("clients/"+this.clientId+"/flows").then(function resolve(){this.hasClientAccess=true}.bind(this),function reject(){this.hasClientAccess=false}.bind(this))};grrUi.sidebar.navigatorDirective.NavigatorDirective=function(){return{scope:{},
restrict:"E",templateUrl:"/static/angular-components/sidebar/navigator.html",controller:NavigatorController,controllerAs:"controller"}};grrUi.sidebar.navigatorDirective.NavigatorDirective.directive_name="grrNavigator"});goog.provide("grrUi.sidebar.module");goog.require("grrUi.sidebar.clientSummaryDirective.ClientSummaryDirective");goog.require("grrUi.sidebar.navDropdownDirective.NavDropdownDirective");goog.require("grrUi.sidebar.navLinkDirective.NavLinkDirective");goog.require("grrUi.sidebar.navigatorDirective.NavigatorDirective");grrUi.sidebar.module=angular.module("grrUi.sidebar",[]);grrUi.sidebar.module.directive(grrUi.sidebar.clientSummaryDirective.ClientSummaryDirective.directive_name,grrUi.sidebar.clientSummaryDirective.ClientSummaryDirective);
grrUi.sidebar.module.directive(grrUi.sidebar.navDropdownDirective.NavDropdownDirective.directive_name,grrUi.sidebar.navDropdownDirective.NavDropdownDirective);grrUi.sidebar.module.directive(grrUi.sidebar.navLinkDirective.NavLinkDirective.directive_name,grrUi.sidebar.navLinkDirective.NavLinkDirective);grrUi.sidebar.module.directive(grrUi.sidebar.navigatorDirective.NavigatorDirective.directive_name,grrUi.sidebar.navigatorDirective.NavigatorDirective);goog.provide("grrUi.templates.module");grrUi.templates.module=angular.module("grrUi.templates",[]);
angular.module("grrUi.templates").run(["$templateCache",function($templateCache){$templateCache.put("acl/approval-info.html",'<h2>Grant access to a {$ controller.approvalTypeTitle $}</h2>\n\n<p>\n  The user <strong>{$ username $}</strong> has requested you to grant them\n  access based on:\n</p>\n\n<blockquote>\n  {$ controller.approvalObject.reason $}\n</blockquote>\n\x3c!--\nThere is a Chrome bug that selects too much text when using triple\nclick, see\nhttps://groups.google.com/a/chromium.org/forum/#!topic/chromium-bugs/P1N9-q5875Y\n\nThe only workaround here is to add a <br>, really nothing else we tried\n(p, div) works. We don\'t want to have any visual difference\neither so it\'s in a div with 0 height.\n--\x3e\n<div style="height: 0"><br></div>\n\n<button class="btn"\n        name="grant-approval"\n        ng-class="{\'btn-success\': !controller.approvalObject.isValid,\n                   \'btn-warning\': controller.approvalObject.isValid}"\n        ng-click="controller.onClick()"\n        ng-disabled="controller.requestSent">\n  <i ng-if="controller.requestSent && !controller.statusMessage"\n     class="fa fa-spinner fa-spin fa-fw"></i>\n  Approve\n</button>\n\n<span class="status-message"\n      ng-if="controller.requestSent && controller.statusMessage">\n  <em>{$ controller.statusMessage $}</em>\n</span>\n');$templateCache.put("acl/client-approval-view.html",
'<grr-approval-info approval-type="\'client\'"\n                   username="controller.username"\n                   object-id="controller.clientId"\n                   approval-id="controller.approvalId">\n</grr-approval-info>\n\n<hr>\n\n<grr-host-info client-id="controller.clientId"\n               read-only="true">\n</grr-host-info>\n');$templateCache.put("acl/cron-job-approval-view.html",'<grr-approval-info approval-type="\'cron-job\'"\n                   username="controller.username"\n                   object-id="controller.cronJobId"\n                   approval-id="controller.approvalId">\n</grr-approval-info>\n\n<hr>\n\n\x3c!-- TODO(user): grr-cron-job-overview should accept cron-job-id, not\n     cron-job-urn. --\x3e\n<grr-cron-job-overview ng-if="controller.cronJobId"\n                       cron-job-urn="\'aff4:/cron/\' + controller.cronJobId" />\n');
$templateCache.put("acl/hunt-approval-view.html",'<div class="container-fluid">\n\n  <div class="row">\n    <div class="col-md-12 vertically-padded">\n      <div class="panel panel-default">\n        <div class="panel-body">\n          \x3c!-- NOTE: approval-object is an out-binding.\n               It is set by grr-approval-info when the approval object is fetched. --\x3e\n          <grr-approval-info approval-type="\'hunt\'"\n                             username="controller.username"\n                             object-id="controller.huntId"\n                             approval-id="controller.approvalId"\n\n                             approval-object="controller.approvalObject">\n          </grr-approval-info>\n\n          <span class="text-danger" ng-if="controller.approvalObject &&\n                                           !controller.approvalObject.value.copied_from_hunt &&\n                                           !controller.approvalObject.value.copied_from_flow">\n            This hunt is new. It wasn\'t copied from another hunt and wasn\'t created from a flow. <strong>Make sure it is safe to run!</strong>\n          </span>\n        </div>\n      </div>\n    </div>\n  </div>\n\n\n  <div ng-if="controller.approvalObject.value.copied_from_hunt">\n    <div class="row">\n      <div class="col-md-12">\n        <div class="panel panel-default">\n          <div class="panel-body">\n            <h3>This hunt was copied from <grr-semantic-value value="controller.approvalObject.value.copied_from_hunt.value.hunt_id"></grr-semantic-value></h3>\n\n            <grr-hunt-from-hunt-copy-review source-hunt="controller.approvalObject.value.copied_from_hunt"\n                                            new-hunt="controller.approvalObject.value.subject">\n            </grr-hunt-from-hunt-copy-review>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n\n  <div ng-if="controller.approvalObject.value.copied_from_flow">\n    <div class="row">\n      <div class="col-md-12">\n        <div class="panel panel-default">\n          <div class="panel-body">\n            \x3c!-- grr-client-context is needed to render the flow ID link correctly. --\x3e\n            <grr-client-context client-id="controller.approvalObject.value.copied_from_flow.value.client_id.value">\n              <h3>This hunt was created from a flow <grr-semantic-value value="controller.approvalObject.value.copied_from_flow.value.flow_id"></grr-semantic-value></h3>\n\n              <grr-hunt-from-flow-copy-review source-flow="controller.approvalObject.value.copied_from_flow"\n                                              new-hunt="controller.approvalObject.value.subject">\n              </grr-hunt-from-flow-copy-review>\n            </grr-client-context>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n\n\n  <div class="row" ng-show="controller.approvalObject">\n    <div class="col-md-12">\n      <div class="panel panel-default">\n        <div class="panel-body">\n          <h3>Hunt overview</h3>\n          \x3c!-- TODO(user): grr-hunt-overview should accept hunt-id, not hunt-urn. --\x3e\n          <grr-hunt-overview hunt-urn="\'aff4:/hunts/\' + controller.huntId">\n          </grr-hunt-overview>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n');
$templateCache.put("acl/hunt-from-flow-copy-review.html",'<div class="container-fluid">\n  <div class="row comparison">\n\n    <div class="row">\n      <div class="col-md-6">\n        <div class="comparison-header">Source flow:</div>\n      </div>\n      <div class="col-md-6">\n        <div class="comparison-header">Hunt flow parameters:</div>\n      </div>\n    </div>\n\n    <div class="comparison-section">\n      <grr-semantic-protos-diff original-value="controller.sourceFlow"\n                                new-value="controller.newFlow"\n                                visible-fields="[\'name\', \'args\']">\n      </grr-semantic-protos-diff>\n    </div>\n\n  </div>\n</div>\n');
$templateCache.put("acl/hunt-from-hunt-copy-review.html",'<div class="container-fluid">\n  <div class="row comparison">\n\n    <div class="row">\n      <div class="col-md-6">\n        <div class="comparison-header">Was:</div>\n      </div>\n      <div class="col-md-6">\n        <div class="comparison-header">Is:</div>\n      </div>\n    </div>\n\n    <div class="comparison-section">\n      <grr-semantic-protos-diff original-value="sourceHunt"\n                                new-value="newHunt"\n                                visible-fields="[\'flow_name\', \'flow_args\']">\n      </grr-semantic-protos-diff>\n    </div>\n\n    <div class="comparison-section">\n      <grr-semantic-protos-diff original-value="sourceHunt.value.hunt_runner_args"\n                                new-value="newHunt.value.hunt_runner_args"\n                                hidden-fields="[\'client_rule_set\', \'original_object\']">\n      </grr-semantic-protos-diff>\n    </div>\n\n    <div class="comparison-section">\n      <grr-semantic-protos-diff original-value="sourceHunt.value.client_rule_set"\n                                new-value="newHunt.value.client_rule_set">\n      </grr-semantic-protos-diff>\n    </div>\n\n    <div class="comparison-section">\n      <grr-semantic-protos-diff original-value="sourceHunt.value.hunt_runner_args.value.output_plugins"\n                                new-value="newHunt.value.hunt_runner_args.value.output_plugins">\n      </grr-semantic-protos-diff>\n    </div>\n\n  </div>\n</div>\n');
$templateCache.put("acl/request-approval-dialog.html",'<grr-confirmation-dialog name="RequestApprovalDialog"\n                         title="\'Request \' + controller.subjectTitle + \' Approval\'"\n                         proceed="controller.proceed()"\n                         proceed-name="\'Submit\'"\n                         proceed-class="\'btn-success\'"\n                         can-proceed="controller.reason && controller.approversList"\n                         auto-close-on-success="true">\n\n  <p class="text-info">\n    Approval is required to access this\n    {$ controller.subjectTitle | lowercase $}.\n\n    <blockquote ng-if="accessErrorDescription">\n      {$ accessErrorDescription $}\n    </blockquote>\n  </p>\n\n  <h3>Create a new approval request.</h3>\n  <form class="form-horizontal acl-form">\n    <div class="form-group">\n      <label class="control-label">Approvers</label>\n      <div class="controls">\n        <input type="text" name="acl_approver" class="form-control"\n               ng-model="controller.approversList"\n               placeholder="approver1,approver2,approver3">\n        </input>\n      </div>\n    </div>\n\n\n    <div class="form-group" ng-if="controller.ccAddresses.length">\n      <div class="controls">\n        <label>\n          <input type="checkbox" name="cc_approval" ng-model="controller.useCcAddresses">\n          </input>\n          CC {$ controller.ccAddresses.join(\', \') $}\n        </label>\n      </div>\n    </div>\n\n    <div class="form-group">\n      <label class="control-label">Reason</label>\n      <div class="controls">\n        <select class="form-control"\n                name="acl_recent_reasons"\n                ng-model="controller.selectedRecentReason">\n          <option value="">Enter New Reason...</option>\n          <option ng-repeat="reason in controller.recentReasons"\n                  value="{$ reason $}">{$ reason $}</option>\n        </select>\n      </div>\n    </div>\n\n    <div class="form-group">\n      <label class="control-label"></label>\n      <div class="controls">\n        <input type="text" name="acl_reason" class="form-control"\n               ng-disabled="controller.selectedRecentReason"\n               ng-model="controller.reason">\n        </input>\n      </div>\n    </div>\n\n    <div class="form-group" ng-if="approvalType == \'client\'">\n      <div class="controls">\n        <label>\n          <input type="checkbox" name="keepalive" ng-model="controller.keepClientAlive">\n          </input>\n          Keep this client alive as soon as it comes online.\n        </label>\n      </div>\n    </div>\n\n  </form>\n\n</grr-confirmation-dialog>\n');
$templateCache.put("artifact/artifact-descriptor.html",'<h5 class="preserve-linebreaks">{$ ::value.value.artifact.value.doc.value $}</h5>\n<table class="table table-bordered table-condensed">\n  <tr ng-if="::value.value.error_message.value">\n    <td class="col-md-3 proto_error">Error</td>\n    <td class="col-md-9 proto_error">\n      <grr-semantic-value value="::value.value.error_message.value" />\n    </td>\n  </tr>\n  <tr>\n    <td class="col-md-3">Labels</td>\n    <td class="col-md-9">\n      <grr-semantic-value value="::value.value.artifact.value.labels" />\n    </td>\n  </tr>\n\n  <tr>\n    <td class="col-md-3">Platforms</td>\n    <td class="col-md-9">\n      <grr-semantic-value value="::value.value.artifact.value.supported_os" />\n    </td>\n  </tr>\n\n  <tr>\n    <td class="col-md-3">Conditions</td>\n    <td class="col-md-9">\n      <grr-semantic-value value="::value.value.artifact.value.conditions" />\n    </td>\n  </tr>\n\n  <tr>\n    <td class="col-md-3">Path Dependencies</td>\n    <td class="col-md-9">\n      <grr-semantic-value value="::value.value.path_dependencies" />\n    </td>\n  </tr>\n\n  <tr>\n    <td class="col-md-3">Links</td>\n    <td class="col-md-9">\n      <div ng-repeat="link in ::value.value.artifact.value.urls">\n        <a ng-href="{{::link.value}}" target="_blank">{$ ::link.value $}</a>\n      </div>\n    </td>\n  </tr>\n\n  <tr>\n    <td class="col-md-3">Output Type</td>\n    <td class="col-md-9">\n      <grr-semantic-value value="::value.value.output_types" />\n    </td>\n  </tr>\n</table>\n\n<div ng-if="::value.value.artifact.value.sources.length > 0">\n  <h5>Artifact Sources</h5>\n  <grr-semantic-value value="::value.value.artifact.value.sources" />\n</div>\n\n<div ng-if="::value.value.processors.length > 0">\n  <h5>Artifact Processors</h5>\n  <grr-semantic-value value="::value.value.processors" />\n</div>\n');
$templateCache.put("artifact/artifact-manager-view.html",'<ul class="breadcrumb">\n  <li>\n    <button class="btn btn-default"\n            title="Upload Artifacts as JSON or YAML"\n            name="UploadArtifact"\n            ng-click="controller.upload()">\n      <img src=\'/static/images/upload.png\' class=\'toolbar_icon\'>\n    </button>\n\n    <button class="btn btn-default"\n            title="Delete selected artifacts"\n            name="DeleteArtifact"\n            ng-disabled="controller.numSelectedDescriptors == 0"\n            ng-click="controller.deleteSelected()">\n      <img src=\'/static/images/editdelete.png\' class=\'toolbar_icon\'>\n    </button>\n  </li>\n</ul>\n\n<table class="table table-condensed table-bordered full-width">\n  <colgroup>\n    <col style="width: 40px">\n    <col width="100px"></col>\n    <col width="100%"></col>\n  </colgroup>\n\n  <thead>\n    <tr>\n      <th><input type="checkbox" class="client-checkbox select-all"\n                 ng-model="controller.allDescriptorsSelected"\n                 ng-change="controller.selectAll()" />\n      <th>Artifact Name</th>\n      <th>Artifact Details</th>\n    </tr>\n  </thead>\n\n  <tbody>\n    <tr grr-infinite-table grr-api-items-provider url="controller.artifactsUrl"\n        page-size="65536"\n        transform-items="controller.transformItems(items)"\n        trigger-update="controller.triggerUpdate">\n\n      \x3c!-- Selection checkbox --\x3e\n      <td>\n        <input type="checkbox" class="client-checkbox"\n               ng-change="controller.updateNumSelectedDescriptors()"\n               ng-model="controller.selectedDescriptors[item.value.artifact.value.name.value]"\n               ng-click="$event.stopPropagation()"\n               />\n      </td>\n\n      <td><grr-semantic-value value="::item.value.artifact.value.name"></grr-semantic-value></td>\n      <td><grr-semantic-value value="::item"></grr-semantic-value></td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("artifact/artifact-name.html",'\x3c!-- We\'re using "controller.artifactType && ..." syntax so that the expression is\n     resolved to undefined when artifactType is undefined. This way one-time\n     binding doesn\'t get removed until controller.artifactType becomes something\n     other than undefined (see "One-time binding" section here:\n     https://docs.angularjs.org/guide/expression). --\x3e\n<span ng-class="::{\'system\': controller.artifactType && controller.artifactType === \'SYSTEM\',\n                   \'user\': controller.artifactType && controller.artifactType === \'USER\'}">\n  <nobr>\n    {$ ::value.value $}\n\n    <span class="icon"\n          title="Custom Uploaded Artifact"\n          ng-if="::controller.artifactType && controller.artifactType === \'USER\'">\n      <i class="fa fa-user fa-1" aria-hidden="true"></i>\n    </span>\n  </nobr>\n</span>\n');
$templateCache.put("artifact/artifacts-list-form.html",'<div class="container-fluid">\n\n<div class="col-md-5">\n\n  <div class="input-group">\n    <input name="Search" class="form-control" style="background-color: #ffffff" type="text" placeholder="Search" ng-model="controller.search"></input>\n\n    <span class="input-group-btn">\n      <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">\n        {$ controller.selectedPlatform || "All Platforms" $}\n        <span class="caret"></span>\n      </button>\n      <ul class="dropdown-menu">\n        <li ng-repeat="platform in controller.platforms">\n          <a ng-click="controller.selectedPlatform = platform">{$ platform || "All Platforms" $}</a>\n        </li>\n      </ul>\n    </span>\n\n  </div>\n\n  <div style="height: 150px; overflow-y: auto; overflow-x: hidden; border: 1px solid #dddddd; border-top: none">\n\n    <table name="Artifacts" class="table table-condensed table-hover table-striped">\n      <colgroup>\n        <col width="100%"></col>\n      </colgroup>\n\n      <tbody>\n        <tr ng-if="!controller.descriptorsError && controller.descriptors === undefined">\n          <td>\n            <i class="fa fa-spinner fa-spin fa-1"></i>\n            <em>Loading artifacts...</em>\n          </td>\n        </tr>\n        <tr ng-if="controller.descriptorsError" class="alert-danger danger">\n          <td>\n            <strong>Can\'t fetch artifacts list:</strong><br/>\n            <span class="preserve-linebreaks">{$ controller.descriptorsError $}</span>\n          </td>\n        </tr>\n        <tr ng-repeat="descriptor in controller.descriptorsList |\n                       orderBy:\'value.artifact.value.name.value\' |\n                       filter:controller.searchFilterRef |\n                       filter:controller.platformFilterRef"\n            ng-class="{\'row-selected\': descriptor.value.artifact.value.name ==\n                      controller.selectedName}">\n          <td style="cursor: pointer; border: none"\n              ng-dblclick="controller.add(descriptor.value.artifact.value.name)"\n              ng-click="controller.selectedName = descriptor.value.artifact.value.name">\n            <div style="display:block" class="full-width-height"\n                 ng-class="::{\'custom-artifact\': descriptor.value.is_custom.value === true}">\n              {$ ::descriptor.value.artifact.value.name.value $}\n\n              <span title="Custom Uploaded Artifact"\n                    ng-if="::descriptor.value.is_custom.value === true">\n                <i class="fa fa-user fa-1" aria-hidden="true"></i>\n              </span>\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n\n  <div style="full-width">\n    <div class="pull-left" style="padding-top: 1.5em">\n      <p>Selected Artifacts:</p>\n    </div>\n    <div class="pull-right">\n      <button class="btn btn-default btn-sm form-add" style="margin-top: 0.5em" name="Add"\n              ng-click="controller.add(controller.selectedName)">\n        Add\n      </button>\n    </div>\n    <div class="clearfix"></div>\n  </div>\n\n  <div style="margin-top: 0em; height: 150px; overflow-y: auto; overflow-x: hidden; border: 1px solid #dddddd">\n\n    <table name="SelectedArtifacts" class="table table-condensed table-hover table-striped">\n      <colgroup>\n        <col width="100%"></col>\n      </colgroup>\n\n      <tbody>\n        <tr ng-if="value.length > 0"\n            ng-repeat="name in value | orderBy:\'value\'"\n            ng-class="{\'row-selected\': name == controller.selectedName}">\n          <td style="cursor: pointer; border: none"\n              ng-dblclick="controller.remove(name)"\n              ng-click="controller.selectedName = name"\n              ng-class="{\'row-selected\': name == controller.selectedName}">\n            <div style="display:block" class="full-width-height">\n              <strong>{$ ::name.value $}</strong>\n\n              <span title="Custom Uploaded Artifact"\n                    ng-if="::controller.descriptors[name.value].value.is_custom.value === true">\n                <i class="fa fa-user fa-1" aria-hidden="true"></i>\n              </span>\n            </div>\n          </td>\n        </tr>\n        <tr ng-if="value.length == 0">\n          <td>\n            <em>Use "Add" button or double-click to add artifacts to the list.</em>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n\n  <div class="full-width" style="margin-top: 0.5em">\n    <button class="btn btn-default btn-sm form-add" name="Add"\n            ng-click="controller.clear()">\n      Clear\n    </button>\n\n    <div class="pull-right">\n      <button class="btn btn-default btn-sm form-add" name="Add"\n              ng-click="controller.remove(controller.selectedName)">\n        Remove\n      </button>\n    </div>\n    <div style="cleafix"></div>\n  </div>\n</div>\n\n<div name="ArtifactInfo" class="col-md-7"\n     grr-force-refresh refresh-trigger="controller.selectedName.value">\n  <grr-semantic-value value="controller.descriptors[controller.selectedName.value]" />\n</div>\n\n</div>\n');
$templateCache.put("artifact/delete-artifacts-dialog.html",'<grr-confirmation-dialog name="DeleteArtifactDialog"\n                         title="\'Delete Selected Artifacts\'"\n                         proceed="controller.proceed()">\n\n  <p>Are you sure you want to delete following artifacts?</p>\n  <ul>\n    <li ng-repeat="name in names">\n      {$ name $}\n    </li>\n  </ul>\n\n</grr-confirmation-dialog>');$templateCache.put("artifact/upload-artifact-dialog.html",'<grr-confirmation-dialog name="UploadArtifactDialog"\n                         title="\'Upload Artifact\'"\n                         proceed="controller.proceed()">\n\n  <input type="file" ng-disabled="controller.inProgress"\n         onchange="angular.element(this).scope().controller.onFileSet(this.files)" />\n\n</grr-confirmation-dialog>\n');
$templateCache.put("client/add-clients-labels-dialog.html",'<grr-confirmation-dialog name="AddClientsLabelsDialog"\n                         title="\'Add Label\'"\n                         proceed="controller.proceed()"\n                         can-proceed="controller.labelName">\n\n  <form class="form-horizontal">\n    <div class="form-group">\n      <label class="control-label" for="labelBox">Label</label>\n      <div class="controls">\n        <input type="text" name="labelBox" ng-model="controller.labelName" />\n      </div>\n    </div>\n  </form>\n\n  <table class="table table-striped table-condensed">\n    <thead>\n    <tr>\n      <th>Affected clients:</th>\n    </tr>\n    </thead>\n    <tbody>\n    <tr ng-repeat="client in clients">\n      <td><grr-client-urn value="client.value.urn" /></td>\n    </tr>\n    </tbody>\n  </table>\n\n</grr-confirmation-dialog>\n');
$templateCache.put("client/check-client-access.html","<div ng-class=\"{'access-disabled': clientId !== undefined && !outHasAccess}\">\n  <ng-transclude></ng-transclude>\n</div>\n");$templateCache.put("client/client-crashes.html",'<grr-check-client-access client-id="controller.clientId">\n  <grr-semantic-value value="controller.crashes"></grr-semantic-value>\n</grr-check-client-access>\n');$templateCache.put("client/client-load-view.html",'<grr-check-client-access client-id="controller.clientId">\n\n  <div ng-if="controller.clientId">\n\n    <grr-debug-requests-view fetch-responses="0">\n    </grr-debug-requests-view>\n\n    <div class="pull-right padded">\n      <div class="btn-group">\n        <label class="btn btn-primary" ng-model="controller.duration" btn-radio="60">1h</label>\n        <label class="btn btn-primary" ng-model="controller.duration" btn-radio="180">3h</label>\n        <label class="btn btn-primary" ng-model="controller.duration" btn-radio="360">6h</label>\n        <label class="btn btn-primary" ng-model="controller.duration" btn-radio="1440">1d</label>\n        <label class="btn btn-primary" ng-model="controller.duration" btn-radio="10080">7d</label>\n        <label class="btn btn-primary" ng-model="controller.duration" btn-radio="44640">31d</label>\n      </div>\n    </div>\n\n    <div class="clearfix"></div>\n\n    <div class="padded">\n\n      <h4>Client CPU usage</h4>\n      <grr-timeseries-graph title="Client CPU usage"\n                            start-time="controller.startTime"\n                            end-time="controller.endTime"\n                            compute-delta="true">\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="User CPU seconds"\n                                     metric="cpu_user">\n        </grr-client-load-graph-serie>\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="System CPU seconds"\n                                     metric="cpu_system">\n        </grr-client-load-graph-serie>\n      </grr-timeseries-graph>\n\n      <h4>Client CPU load percentage</h4>\n      <grr-timeseries-graph title="Client CPU load percentage"\n                            start-time="controller.startTime"\n                            end-time="controller.endTime">\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="CPU load percentage"\n                                     metric="cpu_percent">\n        </grr-client-load-graph-serie>\n      </grr-timeseries-graph>\n\n      <h4>Client IO usage</h4>\n      <grr-timeseries-graph title="Client IO usage"\n                            start-time="controller.startTime"\n                            end-time="controller.endTime"\n                            compute-delta="true">\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="Bytes read"\n                                     metric="io_read_bytes">\n        </grr-client-load-graph-serie>\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="Bytes written"\n                                     metric="io_write_bytes">\n        </grr-client-load-graph-serie>\n      </grr-timeseries-graph>\n\n      <h4>Client IO operations count</h4>\n      <grr-timeseries-graph title="Client IO operations"\n                            start-time="controller.startTime"\n                            end-time="controller.endTime"\n                            compute-delta="true">\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="Read operations count"\n                                     metric="io_read_ops">\n        </grr-client-load-graph-serie>\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="Write operations count"\n                                     metric="io_write_ops">\n        </grr-client-load-graph-serie>\n      </grr-timeseries-graph>\n\n      <h4>Client memory usage percentage</h4>\n      <grr-timeseries-graph title="Client memory usage percentage"\n                            start-time="controller.startTime"\n                            end-time="controller.endTime">\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="Memory usage percentage"\n                                     metric="memory_percent">\n        </grr-client-load-graph-serie>\n      </grr-timeseries-graph>\n\n      <h4>Client RSS/VMS sizes</h4>\n      <grr-timeseries-graph title="Client RSS/VMS sizes"\n                            start-time="controller.startTime"\n                            end-time="controller.endTime">\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="RSS size"\n                                     metric="memory_rss_size">\n        </grr-client-load-graph-serie>\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="VMS size"\n                                     metric="memory_vms_size">\n        </grr-client-load-graph-serie>\n      </grr-timeseries-graph>\n\n      <h4>Client network usage</h4>\n      <grr-timeseries-graph title="Client network usage"\n                            start-time="controller.startTime"\n                            end-time="controller.endTime"\n                            compute-delta="true">\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="Bytes received"\n                                     metric="network_bytes_received">\n        </grr-client-load-graph-serie>\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="Bytes sent"\n                                     metric="network_bytes_sent">\n        </grr-client-load-graph-serie>\n      </grr-timeseries-graph>\n\n    </div>\n\n  </div>\n\n</grr-check-client-access>\n');
$templateCache.put("client/client-status-icons.html",'<div ng-cloak class="centered" ng-if="controller.iconName != null">\n  <img class="grr-icon-small" name="clientStatusIcon"\n       ng-src="/static/images/{$ ::controller.iconName $}.png"\n       title="{$ ::controller.lastPing | grrTimeSince $}" />\n\n  <img ng-if="::controller.crashTime != null" class="grr-icon"\n       ng-src="/static/images/skull-icon.png" name="clientCrashIcon"\n       title="{$ ::controller.crashTime | grrTimeSince $}" />\n\n  <span ng-if="::controller.diskWarnings.length > 0"\n        name="clientDiskWarnings">\n    <img class="grr-icon" ng-src="/static/images/hdd-bang-icon.png" />\n    <strong>Disk free space low:</strong><br/>\n    <span ng-repeat="warning in ::controller.diskWarnings">\n      {$ ::warning[0] $} {$ warning[1] | number:0 $}% free<br/>\n    </span>\n  </span>\n</div>\n');
$templateCache.put("client/clients-list.html",'<ul class="breadcrumb">\n  <li>\n    <button title="Add Labels" class="btn btn-default"\n            ng-disabled="controller.numSelectedClients == 0"\n            ng-click="controller.showLabelsDialog(\'add\')"\n            name="AddLabels">\n      <img src="/static/images/label-add.png" class="toolbar_icon" />\n    </button>\n    <button title="Remove Labels" class="btn btn-default"\n            ng-disabled="controller.numSelectedClients == 0"\n            ng-click="controller.showLabelsDialog(\'remove\')"\n            name="RemoveLabels">\n      <img src="/static/images/label-remove.png" class="toolbar_icon" />\n    </button>\n  </li>\n</ul>\n\n<table class="table table-striped table-condensed table-hover table-bordered full-width">\n  <colgroup>\n    <col style="width: 40px">\n    <col style="width: 40px">\n    <col style="width: 13em">\n    <col style="width: 13em">\n    <col style="width: 20%">\n    <col style="width: 10%">\n    <col style="width: 20%">\n    <col style="width: 15%">\n    <col style="width: 15%">\n    <col style="width: 8%">\n    <col style="width: 15%">\n  </colgroup>\n  <thead>\n    <tr>\n      <th><input type="checkbox" class="client-checkbox select-all"\n                 grr-disable-if-no-trait="modify_client_labels_action_enabled"\n                 ng-model="controller.allClientsSelected"\n                 ng-change="controller.selectAll()" />\n      </th>\n      <th>Online</th>\n      <th>Subject</th>\n      <th>Host</th>\n      <th>OS Version</th>\n      <th>MAC</th>\n      <th>Usernames</th>\n      <th>First Seen</th>\n      <th>Client version</th>\n      <th>Labels</th>\n      <th>Last Checkin</th>\n      <th>OS Install Date</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-infinite-table grr-api-items-provider\n        query-params="{query: controller.query}"\n        url="controller.clientsQueryUrl"\n        transform-items="controller.onClientsFetched(items)"\n        trigger-update="controller.triggerUpdate"\n        ng-click="controller.onClientClick(item)">\n      \x3c!-- Selection checkbox --\x3e\n      <td>\n        <input type="checkbox" class="client-checkbox"\n               grr-disable-if-no-trait="modify_client_labels_action_enabled"\n               client_urn="{$ item.value.urn.value $}"\n               ng-model="controller.selectedClients[item.value.urn.value]"\n               ng-change="controller.updateNumSelectedClients()"\n               ng-click="$event.stopPropagation()"\n               />\n      </td>\n\n      \x3c!-- Online status --\x3e\n      <td>\n        <grr-client-status-icons client="::item" />\n      </td>\n\n      \x3c!-- Subject --\x3e\n      <td>\n        <span type="subject">{$ ::item.value.urn.value | grrBasename $}</span>\n      </td>\n\n      \x3c!-- Host --\x3e\n      <td>\n        <grr-semantic-value value="::item.value.os_info.value.node" />\n      </td>\n\n      \x3c!-- OS Version --\x3e\n      <td>\n        <grr-semantic-value value="::item.value.os_info.value.version" />\n      </td>\n\n      \x3c!-- MAC --\x3e\n      <td>\n        <grr-semantic-value value="::item._mac_addresses" />\n      </td>\n\n      \x3c!-- Usernames --\x3e\n      <td>\n        <grr-semantic-value value="::item._usernames" />\n      </td>\n\n      \x3c!-- First seen --\x3e\n      <td>\n        <grr-semantic-value value="::item.value.first_seen_at" />\n      </td>\n\n      \x3c!-- Client version --\x3e\n      <td>\n        <grr-semantic-value value="::item.value.agent_info.value.client_version" />\n      </td>\n\n      \x3c!-- Labels --\x3e\n      <td>\n        <grr-semantic-value value="::item.value.labels" />\n      </td>\n\n      \x3c!-- Latest checkin --\x3e\n      <td>\n        <grr-semantic-value value="::item.value.last_clock" />\n      </td>\n\n      \x3c!-- OS install date --\x3e\n      <td>\n        <grr-semantic-value value="::item.value.os_info.value.install_date" />\n      </td>\n\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("client/debug-requests-view.html",'<grr-check-client-access client-id="controller.clientId"\n                         ng-if="controller.clientId">\n\n  <div class="horizontally-padded">\n\n    <h3>Client requests for {$ controller.clientId $}</h3>\n\n    <div ng-if="controller.actionRequests === undefined">\n      Loading...\n    </div>\n\n    <div ng-if="controller.actionRequests.length === 0">\n      No actions currently in progress.\n    </div>\n\n    <div grr-force-refresh refresh-trigger="controller.actionRequests">\n      <grr-semantic-value value="::controller.actionRequests">\n      </grr-semantic-value>\n    </div>\n\n  </div>\n\n</grr-check-client-access>\n');
$templateCache.put("client/host-history-dialog.html",'<div class="modal-header">\n  <button type="button" class="close" ng-click="$close()">\n    <span aria-hidden="true">&times;</span>\n    <span class="sr-only">Close</span>\n  </button>\n  <h4 class="modal-title">Client {$ clientId $}: {$ fieldPath $} history</h4>\n</div>\n<div class="modal-body">\n  <div ng-if="controller.items === undefined" class="text-center">\n    <i class="fa fa-spinner fa-spin fa-3x margin-bottom"></i>\n    <div>Loading...</div>\n  </div>\n\n  <div ng-if="controller.items !== undefined"\n       grr-force-refresh refresh-trigger="controller.items">\n\n    <p class="text-right">\n      <em>\n        Time range <strong>from</strong>\n        <grr-semantic-value value="::controller.startTime"></grr-semantic-value>\n        <strong>to</strong>\n        <grr-semantic-value value="::controller.endTime"></grr-semantic-value>\n      </em>\n    </p>\n\n    <table class="table table-condensed history">\n      <thead>\n        <tr>\n          <th>Time</th>\n          <th>Version</th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr ng-repeat="item in ::controller.items">\n          <td class="time">\n            <grr-semantic-value value="::item[0]"></grr-semantic-value>\n          </td>\n          <td class="version">\n            <grr-semantic-value value="::item[1]"></grr-semantic-value>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n\n  </div>\n</div>\n<div class="modal-footer">\n  <button class="btn btn-primary" ng-click="close()">Close</button>\n</div>\n');
$templateCache.put("client/host-info.html",'<div ng-if="controller.client">\n\n  <h1>\n    {$ controller.client.value.os_info.value.node.value $}\n    <span>{$ controller.clientId $}</span>\n  </h1>\n\n  <div ng-if="!readOnly">\n    <grr-check-client-access client-id="controller.clientId" no-redirect="true"\n                             out-has-access="controller.hasClientAccess">\n    </grr-check-client-access>\n\n    <div class="no-approval alert alert-danger alert-block"\n         ng-if="controller.hasClientAccess !== undefined && !controller.hasClientAccess">\n      <i class="fa fa-warning"></i> You do not have an <b>approval</b> for this client. <br/>\n\n      <button name="requestApproval" class="btn btn-default"\n              ng-click="controller.requestApproval()">Request Approval</button>\n    </div>\n  </div>\n\n  \x3c!-- Toolbar --\x3e\n  <div class="client-actions">\n\n    <button ng-if="!readOnly"\n            class="btn btn-default"\n            ng-click="controller.interrogate()"\n            ng-disabled="!controller.hasClientAccess || controller.interrogateOperationId">\n      <i class="fa fa-search-plus"\n         ng-if="!controller.interrogateOperationId"></i>\n      <i class="fa fa-spinner fa-spin fa-fw"\n          ng-if="controller.interrogateOperationId"></i>\n      Interrogate\n    </button>\n\n    <div class="btn-group" data-toggle="buttons">\n      <label class="btn btn-default active" ng-click="controller.showDetails = false">\n        <input type="radio" name="show-client-details" checked> Overview\n      </label>\n      <label class="btn btn-default" ng-click="controller.showDetails = true">\n        <input type="radio" name="show-client-details"> Full details\n      </label>\n    </div>\n\n    <grr-version-dropdown version="controller.clientVersion"\n                          url="controller.clientVersionUrl">\n    </grr-version-dropdown>\n\n    <div class="clearfix"></div>\n  </div>\n\n\n  \x3c!-- Client Details --\x3e\n  <div class="client-overview" ng-if="!controller.showDetails"\n       grr-force-refresh refresh-trigger="controller.client">\n\n    \x3c!-- Overview --\x3e\n    <div class="client-info-wrapup">\n      <dt>OS</dt>\n      <dd>\n        <div ng-if="controller.client.value.os_info.value.system">\n          <i class="fa fa-linux" ng-if="controller.client.value.os_info.value.system.value == \'Linux\'"></i>\n          <i class="fa fa-windows" ng-if="controller.client.value.os_info.value.system.value == \'Windows\'"></i>\n          <i class="fa fa-apple" ng-if="controller.client.value.os_info.value.system.value == \'Apple\'"></i>\n\n          <grr-semantic-value value="controller.client.value.os_info.value.system"></grr-semantic-value>\n          <span ng-if="controller.client.value.os_info.value.system.value && (controller.client.value.os_info.value.release.value || controller.client.value.os_info.value.version.value)">,</span>\n          <grr-semantic-value value="controller.client.value.os_info.value.release"></grr-semantic-value>\n          <grr-semantic-value value="controller.client.value.os_info.value.version"></grr-semantic-value>\n        </div>\n\n        <div ng-if="!controller.client.value.os_info.value.system">\n          -\n        </div>\n      </dd>\n\n      <dt>Last Local Clock</dt>\n      <dd>\n        <i class="fa fa-history"></i>\n        <div ng-if="!controller.client.value.last_clock">-</div>\n        <grr-semantic-value value="controller.client.value.last_clock"\n                            ng-if="controller.client.value.last_clock">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>GRR Client Version</dt>\n      <dd>\n        <div ng-if="!controller.client.value.agent_info.value.client_version.value">-</div>\n        <grr-semantic-value value="controller.client.value.agent_info.value.client_version.value"\n                            ng-if="controller.client.value.agent_info.value.client_version.value">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Architecture</dt>\n      <dd>\n        <div ng-if="!controller.client.value.os_info.value.machine">-</div>\n        <grr-semantic-value value="controller.client.value.os_info.value.machine"\n                            ng-if="controller.client.value.os_info.value.machine">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Kernel</dt>\n      <dd>\n        <div ng-if="!controller.client.value.os_info.value.kernel">-</div>\n        <grr-semantic-value value="controller.client.value.os_info.value.kernel"\n                            ng-if="controller.client.value.os_info.value.kernel">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Memory Size</dt>\n      <dd>\n        <div ng-if="!controller.client.value.memory_size">-</div>\n        <grr-semantic-value value="controller.client.value.memory_size"\n                            ng-if="controller.client.value.memory_size">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Labels</dt>\n      <dd>\n        <span ng-if="!controller.client.value.labels.length">\n          No labels assigned.\n        </span>\n\n        <ul ng-if="controller.client.value.labels.length" class="label-list">\n          <li ng-repeat="label in controller.client.value.labels">\n            <span class="label label-success">{$ label.value.name.value $}</span>\n          </li>\n        </ul>\n      </dd>\n\n      <dt>Users</dt>\n      <dd>\n        <div ng-if="!controller.client.value.users.length">-</div>\n\n        <ul class="user-list">\n          <li ng-repeat="user in controller.client.value.users">\n            <i class="fa fa-user"></i> {$ ::user.value.full_name.value $} ({$ ::user.value.username.value $})\n          </li>\n        </ul>\n      </dd>\n    </div>\n\n    \x3c!-- Info Tiles --\x3e\n    <div class="client-info-details">\n\n      <div class="col-md-12 col-lg-6">\n\n        <section>\n          <h2><i class="fa fa-clock-o"></i> Timestamps</h2>\n\n          <table class="properties">\n            <tr>\n              <th>Installation time</th>\n              <td ng-if="controller.client.value.os_info.value.install_date">\n                <grr-semantic-value value="controller.client.value.os_info.value.install_date">\n                </grr-semantic-value>\n                <span class="time-since">{$ (controller.client.value.os_info.value.install_date.value | grrTimeSince) $}</span>\n              </td>\n              <td ng-if="!controller.client.value.os_info.value.install_date">\n                -\n              </td>\n            </tr>\n            <tr>\n              <th>First seen</th>\n              <td ng-if="controller.client.value.first_seen_at">\n                <grr-semantic-value value="controller.client.value.first_seen_at">\n                </grr-semantic-value>\n                <span class="time-since">{$ controller.client.value.first_seen_at.value | grrTimeSince $}</span>\n              </td>\n              <td ng-if="!controller.client.value.first_seen_at">\n                -\n              </td>\n            </tr>\n            <tr>\n              <th>Last booted</th>\n              <td ng-if="controller.client.value.last_booted_at">\n                <grr-semantic-value value="controller.client.value.last_booted_at">\n                </grr-semantic-value>\n                <span class="time-since">{$ controller.client.value.last_booted_at.value | grrTimeSince $}</span>\n              </td>\n              <td ng-if="!controller.client.value.last_booted_at">\n                -\n              </td>\n            </tr>\n            <tr>\n              <th>Last seen</th>\n              <td ng-if="controller.client.value.last_seen_at">\n                <grr-semantic-value value="controller.client.value.last_seen_at">\n                </grr-semantic-value>\n                <span class="time-since">{$ controller.client.value.last_seen_at.value | grrTimeSince $}</span>\n              </td>\n              <td ng-if="!controller.client.value.last_seen_at">\n                -\n              </td>\n            </tr>\n          </table>\n        </section>\n      </div>\n\n      <div class="col-md-12 col-lg-6">\n        <section>\n          <h2><i class="fa fa-exchange"></i> Interfaces</h2>\n\n          <div ng-if="!controller.client.value.interfaces"\n               class="no-section-info">\n            No interface information available.\n          </div>\n\n          <table ng-if="controller.client.value.interfaces"\n                 class="full-section-info">\n            <thead>\n              <tr>\n                <th>IF Name</th>\n                <th>Mac Address</th>\n                <th>Addresses</th>\n              </tr>\n            </thead>\n            <tr ng-repeat="interface in controller.client.value.interfaces">\n              <td>\n                {$ ::interface.value.ifname.value $}\n              </td>\n              <td class="mac-address">\n                <grr-semantic-value value="interface.value.mac_address"></grr-semantic-value>\n              </td>\n              <td class="mac-address">\n                <ul>\n                  <li ng-repeat="address in interface.value.addresses">\n                    <grr-semantic-value value="address"></grr-semantic-value>\n                  </li>\n                </ul>\n              </td>\n            </tr>\n          </table>\n        </section>\n      </div>\n    </div>\n  </div>\n\n  \x3c!-- Shows the full view on the client with all properties and in full details --\x3e\n  <div class="client-details"\n       ng-if="controller.showDetails"\n       grr-force-refresh refresh-trigger="controller.client">\n    <grr-semantic-versioned-proto\n      client="::controller.client"\n      value="::controller.client"\n      on-field-click="controller.showHistoryDialog(fieldPath)"\n      history-depth="2">\n    </grr-semantic-versioned-proto>\n  </div>\n</div>\n');
$templateCache.put("client/remove-clients-labels-dialog.html",'<grr-confirmation-dialog name="RemoveClientsLabelsDialog"\n                         title="\'Remove Label\'"\n                         proceed="controller.proceed()">\n\n  <form class="form-horizontal">\n    <div class="form-group">\n      <label class="control-label" for="labelBox">Label</label>\n      <div class="controls">\n        <select class="form-control"\n                ng-model="controller.labelName"\n                ng-options="item as item for item in controller.availableLabels">\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <table class="table table-striped table-condensed">\n    <thead>\n    <tr>\n      <th>Affected clients:</th>\n    </tr>\n    </thead>\n    <tbody>\n    <tr ng-repeat="client in clients">\n      <td><grr-client-urn value="client.value.urn" /></td>\n    </tr>\n    </tbody>\n  </table>\n\n</grr-confirmation-dialog>\n\n');
$templateCache.put("config/binaries-list.html",'<table class="table table-condensed table-hover table-striped"\n       ng-if="controller.binaries.length > 0">\n  <tbody>\n    <tr ng-repeat="binary in ::controller.binaries"\n        ng-click="controller.onBinaryClicked(binary)">\n      <td>\n        <span ng-if="::binary.dirName.length > 0" class="path">\n          <strong>{$ ::binary.dirName $}</strong> / {$ ::binary.baseName $}\n        </span>\n        <span ng-if="::binary.dirName.length === 0" class="path">\n          {$ ::binary.baseName $}\n        </span>\n        <span class="timestamp pull-right">\n          <grr-semantic-value value="::binary.value.timestamp">\n          </grr-semantic-value>\n        </span>\n        <span ng-if="::binary.value.size !== undefined"\n              class="size pull-right">\n          <grr-semantic-value value="::binary.value.size">\n          </grr-semantic-value>\n        </span>\n      </td>\n    </tr>\n  </tbody>\n</table>\n\n<div class="padded" ng-if="controller.binaries.length === 0">\nNone.\n</div>\n');
$templateCache.put("config/config-binaries-view.html",'<div class="padded" ng-if="controller.binaries !== undefined">\n\n  <div class="panel panel-default">\n    <div class="panel-heading">\n      <i class="fa fa-code fa-2" aria-hidden="true"></i>\n      Python Hacks\n    </div>\n\n    <grr-binaries-list binaries="controller.binaries"\n                       type-filter="PYTHON_HACK">\n    </grr-binaries-list>\n  </div>\n\n  <div class="panel panel-default">\n    <div class="panel-heading">\n      <i class="fa fa-cogs fa-xs" aria-hidden="true"></i>\n      Executables\n    </div>\n    <grr-binaries-list binaries="controller.binaries"\n                       type-filter="EXECUTABLE">\n    </grr-binaries-list>\n  </div>\n\n  <div class="panel panel-default">\n    <div class="panel-heading">\n      <i class="fa fa-th-large fa-2" aria-hidden="true"></i>\n      Components\n    </div>\n    <grr-binaries-list binaries="controller.binaries"\n                       type-filter="COMPONENT">\n    </grr-binaries-list>\n  </div>\n\n</div>\n\n<div class="padded" ng-if="controller.binaries === undefined">\nLoading...\n</div>\n');
$templateCache.put("config/config-view.html",'<div class="container-fluid">\n  <div class="row horizontally-padded">\n\n    <h2>Configuration</h2>\n    <p>This is a read-only view of the frontend configuration. Blue values have\n    been changed from the default settings.</p>\n\n    <section ng-repeat="(section_name, section) in ::controller.items">\n      <h3>{$ ::section_name $}</h3>\n\n      <table class="table table-condensed table-bordered table-striped\n                    full-width fixed-layout">\n        <colgroup>\n          <col style="width: 40%" />\n          <col style="width: 60%" />\n        </colgroup>\n\n        <tbody class="TableBody">\n          <tr ng-repeat="(name, config) in ::section"\n              ng-class="::{warning: config.value.is_redacted.value}">\n            <td>{$ name $}</td>\n            <td>\n              <div ng-if="::config.value.is_redacted.value">(redacted)</div>\n              <grr-semantic-value value="::config.value.value">\n              </grr-semantic-value>\n              <div ng-if="::config.is_expanded">\n                <em>(expanded from {$ ::config.value.raw_value $})</em>\n              </div>\n            </td>\n          </tr>\n        </tbody>\n      <table>\n    </section>\n\n  </div>\n</div>\n');
$templateCache.put("core/aff4-object-representation.html",'<div>\n  <table class="table table-condensed table-bordered full-width">\n\n    <colgroup>\n      <col style="width: 30ex" />\n      <col style="width: 100%" />\n      <col style="width: 30ex" />\n    </colgroup>\n\n    <thead>\n      <tr>\n        <th class="ui-state-default">Attribute</th>\n        <th class="ui-state-default">Value</th>\n        <th class="ui-state-default">Age</th>\n      </tr>\n    </thead>\n\n    <tbody>\n\n      <tr ng-repeat-start="type in ::controller.aff4ObjectRepresentation.types">\n        <td colspan="3" class="grr_aff4_type_header">\n          <b>{$ ::type.value.name.value $}</b>\n        </td>\n      </tr>\n\n      <tr ng-repeat="attribute in ::type.value.attributes" ng-repeat-end>\n\n        <td ng-click="attribute.historical = !attribute.historical">\n          <i class="fa fa-plus" ng-if="attribute.value.values.length > 1 && !attribute.historical"></i>\n          <i class="fa fa-minus" ng-if="attribute.value.values.length > 1 && attribute.historical"></i>\n          <b>{$ ::attribute.value.name.value $}</b>\n        </td>\n\n        <td>\n          <div ng-if="!attribute.historical">\n            <grr-semantic-value value="::attribute.value.values[0].value.value"></grr-semantic-value>\n          </div>\n\n          \x3c!-- Historical view with all previous values and their timestamps. --\x3e\n          <div class="historical" ng-if="attribute.historical">\n            <table class="table table-striped table-condensed table-hover table-bordered full-width">\n              <tr>\n                <th class="ui-state-default">Value</th>\n                <th class="ui-state-default">Age</th>\n              </tr>\n              <tr ng-repeat="historical in ::attribute.value.values">\n                <td>\n                  <grr-semantic-value value="::historical.value.value"></grr-semantic-value>\n                </td>\n                <td>\n                  <grr-timestamp value="::historical.age"></grr-timestamp>\n                </td>\n              </tr>\n            </table>\n          </div>\n        </td>\n\n        <td>\n          <grr-timestamp value="::attribute.value.values[0].age"></grr-timestamp>\n        </td>\n\n      </tr>\n\n    </tbody>\n\n  </table>\n\n</div>');
$templateCache.put("core/confirmation-dialog.html",'\x3c!-- "title" attribute here is needed to override the "title" attribute that\n     will be set in grr-confirmation-dialog (that will be one level above)\n     and that will contain an Angular template expression. "title"\n     attribute is used by nested DOM elements when showing tooltips. --\x3e\n<div ng-attr-title="{$ title $}">\n\n  <div class="modal-header">\n    <button type="button" class="close" ng-click="controller.dismiss()">\n      <span aria-hidden="true">&times;</span>\n      <span class="sr-only">Close</span>\n    </button>\n    <h3 class="modal-title">{$ title $}</h3>\n  </div>\n\n  <div class="modal-body">\n    <ng-transclude></ng-transclude>\n\n    <div class="alert alert-success padded" role="alert" ng-if="controller.success">\n      {$ controller.success $}\n    </div>\n\n    <div class="alert alert-danger padded" role="alert" ng-if="controller.error">\n      {$ controller.error $}\n    </div>\n  </div>\n\n  <div class="modal-footer" ng-if="!controller.success && !controller.error">\n    <button class="btn btn-default"\n            ng-click="controller.dismiss()"\n            ng-attr-title="{$ cancelName || \'Cancel\' $}"\n            name="Cancel">\n      {$ cancelName || \'Cancel\' $}\n    </button>\n\n    <button class="btn {$ proceedClass || \'btn-primary\' $}"\n            ng-click="controller.proceed()"\n            ng-disabled="canProceed && !canProceed()"\n            ng-attr-title="{$ proceedName || \'Proceed\' $}"\n            name="Proceed">\n      {$ proceedName || \'Proceed\' $}\n    </button>\n  </div>\n\n  <div class="modal-footer" ng-if="controller.success || controller.error">\n    <button class="btn btn-default"\n            ng-click="controller.close()"\n            ng-attr-title="{$ closeName || \'Close\' $}"\n            name="Close">\n      {$ closeName || \'Close\' $}\n    </button>\n  </div>\n\n</div>\n');
$templateCache.put("core/download-collection-as.html",'<div class="export-buttons pull-right">\n  <div class="well well-sm export-well">\n    <span class="control-label">Download As:</span>\n    <select class="form-control pull-left"\n            ng-options="plugin as displayName for\n                        (plugin, displayName) in controller.pluginToDisplayName"\n            ng-model="controller.selectedPlugin"\n            id="plugin-select">\n    </select>\n    <button ng-click="controller.downloadAs(controller.selectedPlugin)" type="button"\n            name="download-as" class="btn btn-default">\n      Download\n    </button>\n  </div>\n</div>\n<div class="clearfix"></div>\n');
$templateCache.put("core/download-collection-files.html",'<div class="well well-small">\n  <div class="pull-left">\n    Files referenced in this collection can be downloaded as an archive:&nbsp;\n\n    <div class="btn-group">\n      <button class="btn btn-default DownloadButton"\n              ng-disabled="controller.fileArchiveGenerationStarted"\n              ng-click="controller.generateFileArchive(controller.primaryArchiveExtension)">\n        Generate {$ controller.primaryArchiveExtension | uppercase $}\n      </button>\n      <button class="btn btn-default dropdown-toggle"\n              ng-disabled="controller.fileArchiveGenerationStarted"\n              data-toggle="dropdown">\n        <span class="caret"></span>\n      </button>\n      <ul class="dropdown-menu">\n       <li>\n         <a ng-click="controller.generateFileArchive(controller.secondaryArchiveExtension); $event.preventDefault()"\n            href="#">\n           Generate {$ controller.secondaryArchiveExtension | uppercase $}\n         </a>\n       </li>\n      </ul>\n    </div>\n  </div>\n\n  <div class="pull-right">\n    <em>NOTE: generated archive will contain <strong>symlinks</strong>.<br/>\n      Unsure whether your archive utility supports them?<br/>\n      Just unpack the archive before browsing its contents.</em>\n  </div>\n  <div class="clearfix"></div>\n\n  <div class="export-command" ng-if="controller.exportCommand">\n    <a ng-click="exportCommandExpanded = !exportCommandExpanded">\n      {$ exportCommandExpanded ? \'Hide\' : \'Show\' $} export command\n    </a>\n    <div uib-collapse="!exportCommandExpanded" class="padded">\n      <p>\n        To download all the files referenced in the collection, you can use\n        this command:\n      </p>\n      <pre>{$ controller.exportCommand $}</pre>\n    </div>\n  </div>\n</div>\n\n<div class="alert alert-success"\n     ng-if="controller.fileArchiveGenerationStarted &&\n            controller.fileArchiveGenerationSuccess !== undefined">\n  <em>Generation has started.</em>\n</div>\n\n<div class="alert alert-error"\n     ng-if="controller.fileArchiveGenerationStarted &&\n            controller.fileArchiveGenerationError !== undefined">\n  <em>Can\'t generate archive: {$ controller.fileArchiveGenerationError $}.</em>\n</div>\n');
$templateCache.put("core/global-notifications.html",'<div id="global-notification"\n     ng-if="controller.globalNotifications.length">\n\n  <div class="alert alert-block"\n       ng-repeat="notification in controller.globalNotifications"\n       ng-init="notifType = notification.value.type.value"\n       ng-class="{\'alert-info\': notifType === \'INFO\', \'alert-warning\': notifType === \'WARNING\', \'alert-error\': notifType === \'ERROR\'}">\n\n    <button type="button" class="close"\n            ng-click="controller.deleteGlobalNotification(notification)">&times;</button>\n    <h4>\n      {$ notification.value.header.value $}\n    </h4>\n    <p>\n      {$ notification.value.content.value $}\n    </p>\n    <div ng-if="notification.value.link">\n      <a ng-href="{$ notification.value.link.value $}" target="_blank">More...</a>\n    </div>\n\n  </div>\n\n</div>');
$templateCache.put("core/paged-filtered-table-bottom.html",'<h5 ng-if="parentController.showLoading">Loading...</h5>\n\n<div ng-if="!parentController.showLoading && parentController.totalCount > 0 && !parentController.filterApplied">\n  <uib-pagination total-items="parentController.totalCount" items-per-page="parentController.pageSize"\n              max-size="15" rotate="false" boundary-links="true"\n              ng-model="parentController.paginationSelectedPage"\n              ng-change="parentController.onPageChange(parentController.paginationSelectedPage - 1)" />\n</div>\n\n<div ng-if="!parentController.showLoading && parentController.totalCount > 0 &&\n            parentController.filterApplied && !parentController.filterFinished">\n  <div class="btn-group">\n    <button class="btn btn-default" ng-click="parentController.fetchFilteredItems(1)">\n      Fetch More\n    </button>\n    <button class="btn btn-default dropdown-toggle" data-toggle="dropdown">\n      <span class="caret"></span>\n    </button>\n    <ul class="dropdown-menu">\n      <li><a ng-click="parentController.fetchFilteredItems(2)">Fetch {$ parentController.pageSize * 2 $} items</a></li>\n      <li><a ng-click="parentController.fetchFilteredItems(5)">Fetch {$ parentController.pageSize * 5 $} items</a></li>\n      <li><a ng-click="parentController.fetchFilteredItems(10)">Fetch {$ parentController.pageSize * 10 $} items</a></li>\n    </ul>\n  </div>\n</div>\n');
$templateCache.put("core/paged-filtered-table-top.html",'<h5 class="pull-left" ng-if="parentController.totalCount !== undefined">\n  <span ng-if="parentController.totalCount && !parentController.filterApplied">{$ parentController.totalCount $} entries</span>\n  <span ng-if="parentController.totalCount && parentController.filterApplied">Filtered by: {$ parentController.filterValue $}</span>\n</h5>\n\n<div class="pull-right" ng-if="parentController.totalCount">\n  <input type="text" class="search-query"\n         ng-model="parentController.filterEditedValue"\n         ng-keydown="$event.which == 13 && parentController.applyFilter()"\n         placeholder="">\n  <button class="btn btn-default" ng-click="parentController.applyFilter()">Filter</button>\n</div>\n<div class="clear"></div>\n\n');
$templateCache.put("core/results-collection.html",'\x3c!-- "Download as" buttons --\x3e\n<grr-download-collection-as base-url="exportedResultsUrl"\n                            ng-if="exportedResultsUrl &&\n                                   controller.resultsArePresent">\n</grr-download-collection-as>\n\n\x3c!-- "Download Files" panel --\x3e\n<grr-download-collection-files download-url="downloadFilesUrl"\n                               export-command-url="exportCommandUrl"\n\n                               ng-if="downloadFilesUrl &&\n                                      controller.resultsAreFiles">\n\n</grr-download-collection-files>\n\n<grr-output-plugins-notes output-plugins-url="outputPluginsUrl"\n                          ng-if="outputPluginsUrl">\n</grr-output-plugins-notes>\n\n\x3c!-- Results table --\x3e\n<table class="table table-striped table-condensed table-bordered full-width"\n       ng-if="resultsUrl">\n  <thead>\n    <tr>\n      <th>Value</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-paged-filtered-table\n        grr-api-items-provider url="::resultsUrl"\n        transform-items="controller.transformItems(items)"\n        auto-refresh-interval="::controller.autoRefreshInterval">\n      <td><grr-semantic-value value="::item" /></td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("core/search-box.html",'<abbr title="Type label: to open a list of possible labels completions.">\n  <a href="/help/{$ controller.contextHelpUrl $}" target="_blank"\n     class="pull-right">\n    <i class="glyphicon glyphicon-question-sign input-append"></i>\n  </a>\n\n  <form class="pull-right client-search-box">\n    <div class="form-group">\n      <div class="input-group">\n        <input id="client_query" autocomplete="off"\n               grr-disable-if-no-trait="search_clients_action_enabled"\n               type="text" name="q" class="form-control search-query"\n               placeholder="Search Box" ng-model="controller.query"\n               ng-keypress="$event.which == 13 && controller.submitQuery()"\n               uib-typeahead="label for label in controller.labels | filter:$viewValue | limitTo:8"\n               typeahead-min-length="3" typeahead-focus-first="false" />\n        <span class="input-group-btn">\n          <button id="client_query_submit"\n                  type="button"\n                  class="btn btn-default search-query"\n                  ng-click="controller.submitQuery()">\n            <span class="glyphicon glyphicon-search"></span>\n          </button>\n        </span>\n      </div>\n    </div>\n  </form>\n</abbr>\n');
$templateCache.put("core/server-error-button.html",'<button id="show_backtrace" class="nav-btn btn btn-danger"\n        ng-click="controller.showError()"\n        ng-show="controller.buttonVisible">\n  <img src="/static/images/stock_dialog_question.png" class="grr-icon"/>\n</button>\n');$templateCache.put("core/server-error-dialog.html",'<div name="ServerErrorDialog">\n  <div class="modal-header">\n    <button type="button" class="close" ng-click="close()" aria-hidden="true">\u00d7</button>\n    <h3>{$ message $}</h3>\n  </div>\n  <div class="modal-body">\n    <pre>{$ traceBack $}</pre>\n  </div>\n  <div class="modal-footer">\n    <button class="btn btn-primary" ng-click="close()">Close</button>\n  </div>\n</div>');
$templateCache.put("core/version-dropdown.html",'<div>\n\n  <b>Version:</b>\n  <select ng-model="controller.version"\n          ng-disabled="!controller.versions.length"\n          class="form-control version-dropdown">\n\n    <option ng-if="controller.versions.length"\n            ng-selected="controller.isSelected(\'HEAD\')"\n            value="HEAD">\n      HEAD\n    </option>\n\n    \x3c!-- We cannot use ng-options here, since it does not set the selected attribute. --\x3e\n    <option ng-repeat="v in controller.versions"\n            ng-selected="controller.isSelected(v.value)"\n            value="{$ v.value $}">\n      {$ v.value | grrTimestamp $}\n    </option>\n\n    <option ng-if="!controller.versions.length"\n            ng-selected="!controller.versions.length"\n            value="">\n      No versions available.\n    </option>\n\n  </select>\n\n  \x3c!-- Indicate that we are not showing the latest item. --\x3e\n  <div class="newer-version-hint" ng-if="!controller.isLatestSelected()">\n    Newer Version available.\n  </div>\n\n</div>\n');
$templateCache.put("core/wizard-form-page.html",'<div class="modal-body" ng-show="controller.formController.currentPage === controller">\n  <ng-transclude></ng-transclude>\n</div>\n');$templateCache.put("core/wizard-form.html",'<div class="Wizard FormData">\n  <div class="WizardPage">\n    <div class="WizardBar modal-header">\n      <button type="button" class="close"\n              ng-click="controller.reject()" aria-hidden="true">\n        x\n      </button>\n\n      <h3>{$ title $} -\n        <span class="Description">\n          {$ controller.currentPage.title $}\n        </span>\n        <span ng-if="controller.currentPage.helpLink">\n          <a ng-href="{$ controller.currentPage.helpLink $}" target="_blank">\n            <i class="glyphicon glyphicon-question-sign"></i>\n          </a>\n        </span>\n        <span class="page-indicator">\n          Step {$ controller.currentPageIndex + 1 $} out of {$ controller.pages.length $}\n        </span>\n      </h3>\n    </div>\n\n    <ng-transclude></ng-transclude>\n  </div>\n\n  <div class="modal-footer navbar-inner">\n    <ul class="nav pull-right">\n      <button ng-if="controller.currentPageIndex > 0 && !controller.currentPage.noBackButton"\n              class="btn btn-default Back"\n              ng-click="controller.back()">\n        {$ controller.currentPage.prevButtonLabel $}\n      </button>\n      <button class="btn btn-primary Next"\n              ng-disabled="!controller.currentPage.isValid"\n              ng-click="controller.next()">\n        {$ controller.currentPage.nextButtonLabel $}\n      </button>\n    </ul>\n  </div>\n\n</div>\n');
$templateCache.put("cron/cron-job-flows-list.html",'<grr-flows-list flows-url="controller.flowsUrl"\n                selected-flow-id="controller.selectedFlowId">\n</grr-flows-list>\n\n<div ng-if="controller.selectedFlowId"\n     class="panel details-right-panel">\n  <div class="padded">\n    <button ng-click="controller.closeDetails()"\n            class="close">\n      &times;\n    </button>\n  </div>\n\n  <div grr-force-refresh refresh-trigger="controller.selectedFlowId"\n       class="padded">\n\n    <grr-flow-overview flow-id="controller.selectedFlowId"\n                       api-base-path="controller.flowsUrl">\n    </grr-flow-overview>\n\n  </div>\n</div>\n');
$templateCache.put("cron/cron-job-inspector.html",'<div class="padded" grr-force-refresh refresh-trigger="cronJobUrn">\n\n  <div ng-if="!cronJobUrn">\n    Please select a cron job to see the details.\n  </div>\n\n  <uib-tabset ng-if="cronJobUrn">\n    <uib-tab heading="Details" id="Details">\n      <grr-cron-job-overview cron-job-urn="cronJobUrn">\n      </grr-cron-job-overview>\n    </uib-tab>\n\n    <uib-tab heading="Flows" id="Flows">\n      <grr-cron-job-flows-list cron-job-urn="cronJobUrn">\n      </grr-cron-job-flows-list>\n    </uib-tab>\n  </uib-tabset>\n\n</div>\n');
$templateCache.put("cron/cron-job-overview.html",'<div ng-if="cronJobUrn && !controller.cronJob">\n  Loading...\n</div>\n\n<div ng-if="controller.cronJob">\n\n  <dl class="dl-horizontal dl-flow">\n    <div class="dl-group">\n      <dt>ID</dt>\n      <dd>{$ controller.cronJobId $}</dd>\n\n      <dt>Flow Name</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.flow_name">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Description</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.description">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>State</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.state">\n        </grr-semantic-value>\n      </dd>\n    </div>\n\n\n    <div class="dl-group">\n      <dt>Periodicity</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.periodicity">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Last Run Time</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.last_run_time">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Max Iteration Lifetime</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.lifetime">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Allow Overruns</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.allow_overruns">\n        </grr-semantic-value>\n      </dd>\n    </div>\n\n    <div class="dl-group">\n      <dt>Flow Arguments</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.flow_args">\n        </grr-semantic-value>\n      </dd>\n    </div>\n\n    <div class="dl-group">\n      <dt>Flow Runner Arguments</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.flow_runner_args">\n        </grr-semantic-value>\n      </dd>\n    </div>\n\n  </dl>\n\n</div>\n');
$templateCache.put("cron/cron-job-status-icon.html",'<div class="centered cron-state-icon"\n     ng-init="cronJobState = cronJob.value.state.value"\n     state="{$ ::cronJobState $}">\n  <img ng-if="::cronJobState == \'ENABLED\'"\n       title="Cron job is enabled."\n       class="grr-icon grr-cronJob-icon" src="/static/images/clock.png" />\n  <img ng-if="::cronJobState == \'DISABLED\'"\n       title="Cron job is disabled."\n       class="grr-icon grr-cronJob-icon" src="/static/images/pause.png" />\n</div>\n');
$templateCache.put("cron/cron-jobs-list.html",'<ul class="breadcrumb">\n  <li>\n    <div class="btn-group">\n      <button title="Schedule Hunt" class="btn btn-default" name="ScheduleHuntCronJob"\n              ng-click="controller.newCronJob()">\n        <img src="/static/images/new.png" class="toolbar_icon">\n      </button>\n    </div>\n\n    <div class="btn-group">\n      <button title="Enable Cron Job" class="btn btn-default" name="EnableCronJob"\n              ng-click="controller.enableCronJob()"\n              ng-disabled="!controller.selectedCronJobUrn ||\n                           controller.cronJobsByUrn[controller.selectedCronJobUrn].value.state.value == \'ENABLED\'">\n        <img src="/static/images/play_button.png" class="toolbar_icon">\n      </button>\n\n      <button title="Force Run Cron Job" class="btn btn-default" name="ForceRunCronJob"\n              ng-click="controller.forceRunCronJob()"\n              ng-disabled="!controller.selectedCronJobUrn">\n        <img src="/static/images/play_force_button.png" class="toolbar_icon">\n      </button>\n\n      <button title="Disable Cron Job" class="btn btn-default" name="DisableCronJob"\n              ng-click="controller.disableCronJob()"\n              ng-disabled="!controller.selectedCronJobUrn ||\n                           controller.cronJobsByUrn[controller.selectedCronJobUrn].value.state.value == \'DISABLED\'">\n        <img src="/static/images/pause_button.png" class="toolbar_icon">\n      </button>\n    </div>\n\n    <div class="btn-group">\n      <button title="Delete Cron Job" class="btn btn-default" name="DeleteCronJob"\n              ng-click="controller.showDeleteCronJobConfirmation()"\n              ng-disabled="!controller.selectedCronJobUrn">\n        <img src="/static/images/editdelete.png" class="toolbar_icon">\n      </button>\n    </div>\n  </li>\n</ul>\n\n<table class="table table-striped table-condensed table-hover table-bordered full-width">\n  <colgroup>\n    <col style="width: 40px">\n    <col style="width: 10%">\n    <col style="width: 10%">\n    <col style="width: 10%">\n    <col style="width: 70%">\n  </colgroup>\n  <thead>\n    <tr>\n      <th>State</th>\n      <th>Name</th>\n      <th>Last Run</th>\n      <th>Frequency</th>\n      <th>Description</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-infinite-table grr-api-items-provider url="controller.cronUrl" page-size="50"\n        transform-items="controller.transformItems(items)"\n        trigger-update="controller.triggerUpdate"\n        ng-click="controller.selectItem(item)"\n        ng-class="{\'row-selected\': item.value.urn.value == controller.selectedCronJobUrn,\n                  \'danger\': item.value.is_failing.value == true,\n                  \'warning\': item.value.is_failing.value != true && item.isStuck == true}">\n      <td><grr-cron-job-status-icon cron-job="::item" /></td>\n      <td>{$::item.shortUrn $}</td>\n      <td><grr-semantic-value value="::item.value.last_run_time" /></td>\n      <td><grr-semantic-value value="::item.value.periodicity" /></td>\n      <td><grr-semantic-value value="::item.value.description" /></td>\n    </tr>\n\n  </tbody>\n</table>\n');
$templateCache.put("cron/cron-view.html",'<div grr-splitter orientation="horizontal" class="rightSplitterContainer">\n  <div grr-splitter-pane id="content_rightPane" class="rightTopPane">\n    <grr-cron-jobs-list selected-cron-job-urn="controller.selectedCronJobUrn">\n    </grr-cron-jobs-list>\n  </div>\n\n  <div grr-splitter-pane id="main_bottomPane" class="rightBottomPane">\n    <grr-cron-job-inspector cron-job-urn="controller.selectedCronJobUrn">\n    </grr-cron-job-inspector>\n  </div>\n</div>\n');
$templateCache.put("docs/api-description.html",'<span ng-repeat="paragraph in ::controller.paragraphs">\n  {$ paragraph $}\n  <br ng-if="::!$last"></br>\n</span>\n');$templateCache.put("docs/api-docs.html",'<div class="container-fluid">\n  <div class="row">\n    <div class="col-md-9">\n      <div class="doc-item">\n        <h1>GRR API</h1>\n      </div>\n\n      <p>\n        Below is the list of HTTP API calls that the GRR Admin UI can handle.\n        For every supported route you\'ll find a list of supported query\n        parameters (if any). These parameters are passed either as URL query\n        parameters or as parts of URL path.<br/>\n        For example:\n      </p>\n      <p>\n        <samp>/api/hunts?<strong>offset=100&amp;count=20</strong></samp><br>\n      </p>\n\n      <br/>\n      <h4>Permissions</h4>\n      <p>\n        If special permissions are required to access certain resources,\n        &quot;reason&quot; query parameter may be specified.\n        For example:</p>\n      <p>\n        <samp>/api/aff4/C.123456789abcdef1/analysis/AnalyzeClientMemory/myusername-1435178456.2?<strong>reason=InvestigationID+1234</strong></samp>\n      </p>\n\n      <br/>\n      <h4>Type information</h4>\n      <p>\n        GRR API responses usually contain richly typed data. If you don\'t need the type information, you can strip it from any response by setting "strip_type_info" flag. For example:\n      </p>\n      <p>\n        <samp>/api/hunts?offset=100&amp;count=20&amp;<strong>strip_type_info=1</strong></samp><br>\n      </p>\n\n      <h4>XSSI protection</h4>\n      <p>\n        To prevent against Cross Site Script Inclusion (XSSI) attacks, the JSON response body starts with a magic prefix line that must be stripped before feeding the rest of the response body to a JSON parser:\n      </p>\n      <p>\n        <samp>)]}\'<br>[ ... valid JSON ... ]</samp><br>\n      </p>\n      <br/>\n\n      <div class="panel panel-default doc-item-category"\n           ng-repeat="category in ::controller.categories">\n\n        <div class="panel-heading" id="docs-category-{$ $index $}">\n          <h2>{$ category $}</h2>\n        </div>\n\n        <div class="panel-body" grr-on-scroll-into-view="controller.visibleCategory = category">\n          <div class="doc-item"\n               ng-repeat="apiMethod in ::controller.apiMethodsByCategory[category]">\n            <p class="lead">\n              {$ ::apiMethod.http_methods.join(\', \') $}\n              <grr-api-route value="::apiMethod.http_route"></grr-api-route>\n            </p>\n\n            <grr-api-description value="::apiMethod.doc"></grr-api-description>\n            <grr-api-query-spec args-type="::apiMethod.args_type_descriptor.name"></grr-api-query-spec>\n\n            <div ng-if="controller.examplesByMethod[apiMethod.name].length > 0">\n              <h4>Examples:</h4>\n\n              <table class="example table table-condensed"\n                     ng-repeat="example in ::controller.examplesByMethod[apiMethod.name]">\n                <thead>\n                  <th>\n                    <grr-api-route value="::example.url"></grr-api-route>\n\n                    <div class="pull-right" ng-if="::example.type_stripped_response !== undefined">\n                      <input ng-model="example.showTypeStripped" type="checkbox">\n                        Show type-stripped response\n                      </input>\n                    </div>\n\n                    <div class="request-payload" ng-if="example.request_payload">\n                      <span class="method-label">{$ ::apiMethod.http_methods.join(\', \') $} body:</span>\n                      <div class="json pre-scrollable">{$ ::example.request_payload | json:2 $}</div>\n                    </div>\n                  </th>\n                </thead>\n                <tbody>\n                  <tr>\n                    <td>\n                      <div class="json pre-scrollable" ng-if="!example.showTypeStripped">{$ ::example.response | json:2 $}</div>\n                      <div class="json pre-scrollable" ng-if="example.showTypeStripped">{$ ::example.type_stripped_response | json:2 $}</div>\n                    </td>\n                  </tr>\n                </tbody>\n              </table>\n            </div>\n\n          </div>\n        </div>\n\n      </div>\n\n    </div>\n    <div class="col-md-3 vertically-padded">\n\n      <div class="list-group doc-toc">\n        <a ng-class="{\'active\': controller.visibleCategory == category}"\n           ng-repeat="category in controller.categories" class="list-group-item"\n           ng-click="controller.onCategoryLinkClick(category)">\n          {$ category $}\n        </a>\n      </ul>\n    </div>\n  </div>  \x3c!-- div class=row --\x3e\n</div>  \x3c!-- div class=container-fluid --\x3e\n');
$templateCache.put("docs/api-query-spec.html",'<div ng-if="::argsType.length > 0" class="query-parameters">\n  <h4 ng-if="::noHeader === undefined">Parameters</h4>\n\n  <table class="table table-striped table-condensed table-bordered">\n    <thead>\n      <th>Parameter</th>\n      <th>Type</th>\n      <th>Description</th>\n    </thead>\n    <tbody>\n      <tr ng-repeat="field in ::controller.descriptorFields">\n        <td>{$ ::prefix $}{$ ::field.name $}</td>\n        <td>\n          <abbr ng-if="::controller.typeHints[field.type] !== undefined"\n                title="{$ ::controller.typeHints[field.type] $}">\n            {$ ::field.type $}\n          </abbr>\n          <span ng-if="::controller.typeHints[field.type] === undefined">\n            {$ ::field.type $}\n          </span>\n        </td>\n        <td>\n          <grr-api-description value="::field.doc"></grr-api-description>\n          <span ng-if="::field.type == \'EnumNamedValue\'">\n            Possible values:\n            <ul>\n              <li ng-repeat="allowedValue in ::field.allowed_values">\n                {$ ::allowedValue.name $}\n                <span ng-if="::allowedValue.doc.length > 0">\n                  - {$ ::allowedValue.doc $}\n                </span>\n              </li>\n            </ul>\n          </span>\n        </td>\n      </tr>\n    </tbody>\n  </table>\n</div>\n</div>\n');
$templateCache.put("docs/api-route.html",'<span ng-repeat="component in ::controller.routeComponents"><wbr><span>/</span><strong ng-if="component.type && !controller.fillIns[component.value]">&lt;{$ component.value $}&gt;<span ng-if="component.type === \'path\'">...</span></strong><strong ng-if="component.type && controller.fillIns[component.value]">{$ controller.fillIns[component.value] $}</strong><span ng-if="!component.type">{$ component.value $}</span></span>\x3c!-- query parameters (if any) --\x3e<span ng-if="::controller.hasQueryParameters">?<span ng-repeat="(paramName, paramValue) in ::controller.queryParameters"><strong>{$ ::paramName $}<span ng-if="::paramValue !== null">={$ ::paramValue $}</span></strong><span ng-if="::!$last">&amp;</span><wbr></span>\n');
$templateCache.put("flow/client-flows-list.html",'<div class="toolbar">\n  <div class="breadcrumb">\n    <li>\n      <button title="Cancel Selected Flows" class="btn btn-default" name="cancel_flow"\n              ng-disabled="!selectedFlowId"\n              ng-click="controller.cancelButtonClicked()">\n        <img src="/static/images/editdelete.png" class="toolbar_icon">\n      </button>\n\n      <button class="btn btn-default" name="copy_flow"\n              title="Copy Flow"\n              ng-disabled="!selectedFlowId"\n              ng-click="controller.copyFlow()">\n        <img src="/static/images/copy.png" class="toolbar-icon" />\n      </button>\n\n      <button title="Create Hunt From Flow" class="btn btn-default" name="create_hunt"\n              ng-disabled="!selectedFlowId"\n              ng-click="controller.createHuntFromFlow()">\n        <i class="fa fa-crosshairs"></i>\n      </button>\n    </li>\n  </div>\n</div>\n\n<div class="fill-parent-with-toolbar">\n  <grr-flows-list flows-url="controller.flowsUrl"\n                  selected-flow-id="selectedFlowId"\n                  trigger-update="controller.triggerUpdate">\n  </grr-flows-list>\n</div>\n');
$templateCache.put("flow/client-flows-view.html",'<grr-check-client-access client-id="controller.clientId">\n\n  \x3c!-- grr-client-context is used by directives that need to know current client-id to render\n       data. Example: stats/grr-stat-entry-directive.js uses client id to build AFF4 path\n       corresponding to a stat entry. --\x3e\n  <grr-client-context client-id="controller.clientId">\n\n    <div grr-splitter orientation="horizontal" class="rightSplitterContainer">\n      <div grr-splitter-pane id="content_rightPane" class="rightTopPane">\n        <grr-client-flows-list client-id="controller.clientId"\n                               selected-flow-id="controller.selectedFlowId"/>\n      </div>\n\n      <div grr-splitter-pane id="main_bottomPane" class="rightBottomPane">\n        <grr-flow-inspector flow-id="controller.selectedFlowId"\n                            api-base-path="controller.flowApiBasePath"\n                            active-tab="controller.tab" />\n      </div>\n    </div>\n\n  </grr-client-context>\n\n</grr-check-client-access>\n');
$templateCache.put("flow/copy-flow-form.html",'<div ng-if="!controller.flow">\n  Loading...\n</div>\n\n<grr-confirmation-dialog ng-if="controller.flow"\n                         name="CopyFlowDialog"\n                         title="\'Copy \' + controller.flow.value.name.value + \' flow\'"\n                         proceed="controller.proceed()"\n                         proceed-name="\'Launch!\'"\n                         can-proceed="!controller.flowFormHasErrors">\n\n  <grr-flow-form\n    flow-args="controller.flow.value.args"\n    flow-runner-args="controller.flow.value.runner_args"\n    with-output-plugins="true"\n    has-errors="controller.flowFormHasErrors">\n  </grr-flow-form>\n\n</grr-confirmation-dialog>\n');
$templateCache.put("flow/flow-api-helper.html",'<p>To start this flow on this client via the API, you can use one of the following options:</p>\n\n<div ng-repeat="(label, result) in controller.result">\n  <p>\n    <strong>{$ label $}</strong>\n    <em ng-if="!result[\'webAuthType\']">(authentication details are omitted)</em>\n\n    <pre>{$ result.data $}</pre>\n  </p>\n\n</div>\n');$templateCache.put("flow/flow-form.html",'<grr-form-value value="flowArgs"></grr-form-value>\n<hr>\n<grr-form-value value="flowRunnerArgs"></grr-form-value>\n\n<div ng-if="withOutputPlugins && controller.outputPluginsField !== undefined">\n  <hr>\n  <grr-form-proto-repeated-field\n    descriptor="controller.outputPluginDescriptor"\n    field="controller.outputPluginsField"\n    value="flowRunnerArgs.value.output_plugins">\n  </grr-form-proto-repeated-field>\n</div>\n');
$templateCache.put("flow/flow-info.html",'<div class="padded" ng-if="descriptor.value.name.value">\n\n<h3>{$ descriptor.value.name.value $}</h3>\n<p class="preserve-linebreaks">{$ descriptor.value.doc.value $}</p>\n\n</div>\n\n<div class="padded" ng-if="!descriptor.value.name.value">No flow selected.</span>\n');$templateCache.put("flow/flow-inspector.html",'<div class="padded" grr-force-refresh refresh-trigger="flowId">\n\n  <div ng-if="!flowId">\n    Please select a flow to see its details here.\n  </div>\n\n  <uib-tabset ng-if="flowId" active="controller.activeTab">\n    <uib-tab heading="Flow Information" index="\'\'">\n      <grr-flow-overview flow-id="flowId" api-base-path="apiBasePath"\n                         ng-if="controller.tabsShown[\'\']" />\n    </uib-tab>\n\n    <uib-tab heading="Requests" index="\'requests\'">\n      <grr-flow-requests flow-id="flowId" api-base-path="apiBasePath"\n                         ng-if="controller.tabsShown[\'requests\']" />\n    </uib-tab>\n\n    <uib-tab heading="Results" index="\'results\'">\n      <grr-flow-results flow-id="flowId" api-base-path="apiBasePath"\n                        ng-if="controller.tabsShown[\'results\']" />\n    </uib-tab>\n\n    <uib-tab heading="Log" index="\'log\'">\n      <grr-flow-log flow-id="flowId" api-base-path="apiBasePath"\n                    ng-if="controller.tabsShown[\'log\']" />\n    </uib-tab>\n\n    <uib-tab heading="API" index="\'api\'">\n      <grr-flow-api-helper flow-id="flowId" api-base-path="apiBasePath"\n                           ng-if="controller.tabsShown[\'api\']" />\n    </uib-tab>\n  </uib-tabset>\n\n</div>\n');
$templateCache.put("flow/flow-log.html",'<table class="proto-table no-cell-border full-width">\n  <thead>\n    <tr>\n      <th>Age</th>\n      <th>Flow Name</th>\n      <th>Flow URN</th>\n      <th>Message</th>\n    </tr>\n  </thead>\n  <tbody ng-if="controller.logsUrl">\n    <tr grr-paged-filtered-table grr-api-items-provider url="::controller.logsUrl"\n        auto-refresh-interval="::controller.autoRefreshInterval">\n      <td class="table-cell proto_key"><grr-timestamp value="::item.age" /></td>\n      <td class="table-cell proto_key"><grr-semantic-value value="::item.value.flow_name" /></td>\n      <td class="table-cell proto_key"><grr-semantic-value value="::item.value.urn" /></td>\n      <td class="table-cell proto_key"><grr-semantic-value value="::item.value.log_message" /></td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("flow/flow-overview.html",'<div ng-if="flowUrn && !controller.flow">\n  Loading...\n</div>\n\n<div ng-if="controller.flow">\n\n  <dl class="dl-horizontal dl-flow">\n    <grr-force-refresh refresh-trigger="controller.flow">\n\n      <div ng-if="::controller.flow.value.internal_error">\n        <br>\n        <dt class="alert-danger danger">Error while Opening</dt>\n        <dd>{$ ::controller.flow.value.internal_error.value $}</dd>\n        <br><br>\n      </div>\n\n      <dt>Name</dt>\n      <dd><grr-semantic-value value="::controller.flow.value.name" /></dd>\n\n      <dt>Flow ID</dt>\n      <dd><grr-semantic-value value="::controller.flow.value.flow_id" /></dd>\n\n      <dt>Flow URN</dt>\n      <dd><grr-semantic-value value="::controller.flow.value.urn" /></dd>\n\n      <dt>Creator</dt>\n      <dd><grr-semantic-value value="::controller.flow.value.creator" /></dd>\n\n      <dt>Start Time</dt>\n      <dd><grr-timestamp value="controller.flow.value.started_at" /></dd>\n\n      <dt>Last Active</dt>\n      <dd><grr-timestamp value="controller.flow.value.last_active_at" /></dd>\n\n      <dt>State</dt>\n      <dd><grr-semantic-value value="::controller.flow.value.state" /></dd>\n      <br>\n    </grr-force-refresh>\n\n    \x3c!-- Don\'t auto-refresh arguments since they don\'t change during\n         the lifetime of the flow. --\x3e\n    <dt>Arguments</dt>\n    <dd>\n      <grr-semantic-value value="::controller.flow.value.args"\n                          ng-if="::controller.flow.value.args">\n      </grr-semantic-value>\n      <span ng-if="!controller.flow.value.args">-</span>\n    </dd>\n    <br>\n\n    <dt>Runner Arguments</dt>\n    <dd>\n      <grr-semantic-value value="::controller.flow.value.runner_args"\n                          ng-if="::controller.flow.value.runner_args">\n      </grr-semantic-value>\n      <span ng-if="!controller.flow.value.runner_args">-</span>\n    </dd>\n    <br>\n\n    \x3c!-- As context may be UI-heavy, only update it when it actually\n         changes. --\x3e\n    <grr-force-refresh refresh-trigger="controller.flow.value.context">\n      <dt>Context</dt>\n      <dd>\n        <grr-semantic-value value="::controller.flow.value.context">\n        </grr-semantic-value>\n        <span ng-if="::!controller.flow.value.context">-</span>\n      </dd>\n      <br>\n    </grr-force-refresh>\n\n    \x3c!-- As state may be UI-heavy, only update it when it actually\n         changes. --\x3e\n    <grr-force-refresh refresh-trigger="controller.flow.value.state_data">\n      <dt>State Data</dt>\n      <dd>\n        <grr-semantic-value value="::controller.flow.value.state_data">\n        </grr-semantic-value>\n        <span ng-if="::!controller.flow.value.state_data">-</span>\n      </dd>\n      <br>\n    </grr-force-refresh>\n  </dl>\n\n</div>\n');
$templateCache.put("flow/flow-requests.html",'<table class="table table-striped table-condensed table-hover table-bordered\n              full-width">\n  <thead>\n    <tr>\n      <th>ID</th>\n      <th>Request</th>\n      <th>Responses</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-infinite-table grr-api-items-provider url="controller.requestsUrl">\n      <td><grr-semantic-value value="::item.value.request_id" /></td>\n      <td><grr-semantic-value value="::item.value.request_state" /></td>\n      <td><grr-semantic-value value="::item.value.responses" /></td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("flow/flow-results.html",'<grr-results-collection\n  results-url="controller.flowResultsUrl"\n  exported-results-url="controller.flowExportedResultsUrl"\n  output-plugins-url="controller.outputPluginsUrl"\n  export-command-url="controller.exportCommandUrl"\n  download-files-url="controller.downloadFilesUrl"\n\n  ng-if= "controller.flowResultsUrl" />\n');$templateCache.put("flow/flow-status-icon.html",'<div class="centered flow-state-icon"\n     ng-init="flowState = flow.value.state.value"\n     state="{$ ::flowState $}">\n  <img ng-if="::flowState == \'TERMINATED\'"\n       title="Flow finished normally."\n       class="grr-icon grr-flow-icon" src="/static/images/stock_yes.png" />\n  <img ng-if="::flowState == \'RUNNING\'"\n       title="Flow is still running."\n       class="grr-icon grr-flow-icon" src="/static/images/clock.png" />\n  <img ng-if="::flowState == \'ERROR\'"\n       title="Flow terminated with an error."\n       class="grr-icon grr-flow-icon" src="/static/images/nuke.png" />\n  <img ng-if="::flowState == \'CLIENT_CRASHED\'"\n       title="The client crashed while executing this flow."\n       class="grr-icon grr-flow-icon" src="/static/images/skull-icon.png" />\n</div>\n');
$templateCache.put("flow/flows-list.html",'<table class="table table-striped table-condensed table-hover table-bordered full-width">\n  <colgroup>\n    <col style="width: 40px">\n    <col style="width: 20%">\n    <col style="width: 20%">\n    <col style="width: 20%">\n    <col style="width: 20%">\n    <col style="width: 20%">\n  </colgroup>\n  <thead>\n    <tr>\n      <th>State</th>\n      <th>Path</th>\n      <th>Flow Name</th>\n      <th>Creation Time</th>\n      <th>Last Active</th>\n      <th>Creator</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-infinite-table grr-api-items-provider url="flowsUrl" page-size="100"\n        transform-items="controller.transformItems(items)"\n        trigger-update="controller.triggerTableUpdate"\n        auto-refresh-interval="controller.autoRefreshInterval"\n        ng-click="controller.selectItem(item)"\n        ng-class="{\'row-selected\': item.value.flow_id.value == controller.selectedFlowId}"\n        ng-if="item.shown">\n      <td><grr-flow-status-icon flow="::item" /></td>\n      <td>\n        <span ng-if="::item.expanded === undefined"\n              style="float: left; margin-left: {$ ::item.depth $}em"\n              class="tree_leaf">\n        </span>\n        <span ng-if="::item.expanded !== undefined"\n              ng-class="{\'tree_closed\': !item.expanded, \'tree_opened\': item.expanded}"\n              ng-click="item.expand($event)"\n              style="margin-left: {$ ::item.depth $}em"\n              class="tree_branch">\n        </span>\n        {$ ::item.shortId $}\n      </td>\n      <td>\n        <grr-semantic-value value="::item.value.name" />\n      </td>\n      <td>\n        <grr-semantic-value value="::item.value.started_at" />\n      </td>\n      <td>\n        <grr-semantic-value value="::item.value.last_active_at" />\n      </td>\n      <td>\n        <grr-semantic-value value="::item.value.creator" />\n      </td>\n    </tr>\n\n  </tbody>\n</table>\n');
$templateCache.put("flow/start-flow-form.html",'<div ng-if="!controller.requestSent">\n\n<div class="context-help">\n  <a href="/help/investigating-with-grr/flows/index.html" target="_blank">\n    <i class="glyphicon glyphicon-question-sign"></i>\n  </a>\n</div>\n\n<div class="padded" ng-if="!descriptor">\nPlease Select a flow to launch from the tree on the left.\n</div>\n\n<div class="padded" ng-if="descriptor">\n\n  <grr-flow-form flow-args="controller.flowArguments"\n                 flow-runner-args="controller.flowRunnerArguments"\n                 with-output-plugins="clientId"\n                 has-errors="controller.flowFormHasErrors">\n  </grr-flow-form>\n\n  <div class="form-group">\n    <div class="col-sm-offset-2 col-sm-3 padded">\n      <button class="btn btn-success Launch"\n              ng-disabled="controller.flowFormHasErrors"\n              ng-click="controller.startClientFlow()">\n        Launch\n      </button>\n    </div>\n  </div>\n\n</div>\n\n</div>\n\n<div class="padded" ng-if="controller.requestSent">\n  <div ng-if="!controller.responseData && !controller.responseError">\n    <uib-progressbar class="progress-striped active" max="100" value="50">\n      Launching flow {$ descriptor[\'value\'][\'name\'][\'value\'] $}...\n    </uib-progressbar>\n  </div>\n\n  <div class="panel panel-default" ng-if="controller.responseData">\n    <div class="panel-body">\n      <p>\n        Launched Flow {$ descriptor[\'value\'][\'name\'][\'value\'] $}:\n      </p>\n      <p>\n        <grr-semantic-value value="controller.responseData"></grr-semantic-value>\n      </p>\n    </div>\n  </div>\n\n  <div class="alert alert-error" ng-if="controller.responseError">\n    <p><em>Can\'t start flow {$ descriptor[\'name\'] $}:</em></p>\n    <p class="preserve-linebreaks">{$ controller.responseError $}</p>\n  </div>\n</div>\n');
$templateCache.put("flow/start-flow-view.html",'<grr-check-client-access client-id="controller.clientId">\n\n  <div grr-splitter orientation="vertical" class="rightSplitterContainer" closeable-to="0">\n\n    <div grr-splitter-pane id="main_leftPane" class="leftPane">\n      <grr-flow-descriptors-tree selected-descriptor="controller.selection.flowDescriptor" />\n    </div>\n\n    <div grr-splitter-pane id="main_rightPane" class="rightPane no-overflow">\n      <div grr-splitter orientation="horizontal" class="rightSplitterContainer" closeable-to="100">\n\n        <div grr-splitter-pane id="main_rightTopPane" class="rightTopPane">\n          <grr-start-flow-form client-id="controller.clientId"\n                               descriptor="controller.selection.flowDescriptor" />\n        </div>\n\n        <div grr-splitter-pane id="main_rightBottomPane" class="rightBottomPane">\n          <grr-flow-info descriptor="controller.selection.flowDescriptor" />\n        </div>\n\n      </div>\n    </div>\n\n  </div>\n\n</grr-check-client-access>\n');
$templateCache.put("forms/aff4-attribute-form.html",'<div class="input-group" >\n  <select class="form-control"\n          ng-model="value.value"\n          ng-options="optionValue as optionValue\n                      for optionValue in controller.allowedOptions">\n  </select>\n</div>\n');$templateCache.put("forms/auto-generated-aes128-key-form.html",'<grr-form-primitive value="value"\n                    metadata="metadata">\n</grr-form-value>\n');$templateCache.put("forms/bytes-form.html",'<div class="form-group" ng-class="{\'has-error has-feedback\': value.validationError}">\n  <input class="form-control" type="text" ng-model="controller.valueString"></input>\n  <span ng-if="value.validationError"\n        class="glyphicon glyphicon-remove form-control-feedback"\n        aria-hidden="true"></span>\n  <div class="text-danger" ng-if="value.validationError">\n    {$ value.validationError $}\n  </div>\n</div>\n');
$templateCache.put("forms/client-label-form.html",'<label class="control-label">{{\n  controller.formLabel || \'Client label\'\n}}</label>\n<div class="controls select-label-controls">\n  <select class="form-control"\n          ng-model="controller.clientLabel"\n          ng-options="label.name as label.name\n                      for label in controller.labelsList">\n    <option value="" ng-if="!controller.hideEmptyOption">{{\n      controller.emptyOptionLabel\n    }}</option>\n  </select>\n</div>\n');
$templateCache.put("forms/datetime-form.html",'<div class="input-group" ng-class="{\'has-error\': controller.isInvalid}">\n\n  <input type="text" class="form-control"\n         ng-model="controller.valueString"\n         placeholder="{$ controller.format $}"></input>\n  <div class="input-group-btn">\n    <button type="button" name="Today" class="btn btn-default"\n            ng-click="controller.today()"><small>Today</small></button>\n  </div>\n\n</div>\n\n<div class="has-error" ng-if="controller.isInvalid">\n  <span class="help-block">\n    Expected format is {$ controller.format $}, i.e. {$ controller.example $}\n  </span>\n</div>\n');
$templateCache.put("forms/dict-form.html",'<div class="form-group">\n  <button class="btn btn-default add" name="Add"\n          ng-click="controller.addPair()">\n    <i class="glyphicon glyphicon-plus"></i>\n  </button>\n</div>\n\n<div ng-repeat="pair in controller.keyValueList">\n  <button type="button" class="close" name="Remove"\n          ng-click="controller.removePair($index)">&times;</button>\n  <div class="form-group pair">\n      <input class="form-control key" type="text" ng-model="pair.key"></input>\n      <span>=</span>\n      <grr-form-value class="value" value="pair.value"></grr-form-value>\n  </div>\n</div>\n');
$templateCache.put("forms/duration-form.html",'<div class="input-group" ng-class="{\'has-error\': controller.isInvalid}">\n\n  <input type="text" class="form-control"\n         ng-model="controller.valueString"></input>\n\n</div>\n\n<div class="has-error" ng-if="controller.isInvalid">\n  <span class="help-block">\n    Expected format is [number][unit] where unit may be "s" for seconds, "m" for minutes, "h" for hours, "d" for days or "w" for weeks.\n  </span>\n</div>\n');$templateCache.put("forms/foreman-label-rule-form.html",
'<div class="form-group">\n  <label class="control-label">Match mode</label>\n  <div class="controls">\n    <grr-form-value value="value.value.match_mode"\n                    metadata="controller.matchModeMetadata">\n    </grr-form-value>\n  </div>\n</div>\n\n<div class="form-group">\n  <label class="control-label">Add label</label>\n  <div class="controls">\n    <button class="btn btn-default form-add" ng-click="controller.addLabel()">\n      <i class="glyphicon glyphicon-plus"></i>\n    </button>\n  </div>\n</div>\n\n<div class="form-group" ng-repeat="label_name in value.value.label_names">\n  <grr-form-client-label client-label="label_name.value"\n                         form-label="\'Label name\'"\n                         hide-empty-option="true">\n  </grr-form-client-label>\n  <button type="button" class="close remove-label"\n          ng-click="controller.removeLabel($index)"\n          ng-disabled="value.value.label_names.length <= 1">\u00d7</button>\n</div>\n');
$templateCache.put("forms/glob-expression-form.html",'<div class="input-group" >\n  <input type="text" class="form-control"\n         ng-model="value.value"\n         placeholder="Type %% for autocompletion..."></input>\n</div>\n');$templateCache.put("forms/glob-expressions-list-form.html",'\x3c!-- no-custom-template=true prevents infinite recursion. --\x3e\n<grr-form-proto-repeated-field ng-if="value"\n  value="value"\n  descriptor="descriptor"\n  field="field"\n  no-custom-template="true">\n</grr-form-proto-repeated-field>\n');
$templateCache.put("forms/output-plugin-descriptor-form.html",'<div class="well well-large">\n\n  <div class="form-group">\n    <label class="control-label" title="Plugin">\n      Plugin\n    </label>\n    <div class="controls">\n      <select class="form-control" ng-model="value.value.plugin_name.value"\n              ng-options="optionValue as optionValue\n                          for optionValue in controller.allowedPluginsNames">\n      </select>\n    </div>\n  </div>\n\n  <div class="form-group">\n    <grr-form-value value="value.value.plugin_args" />\n  </div>\n\n</div>\n');
$templateCache.put("forms/semantic-enum-form.html",'<select class="form-control" ng-model="value.value"\n        ng-options="optionValue.value as optionValue.label\n                    for optionValue in controller.allowedOptions">\n</select>\n');$templateCache.put("forms/semantic-primitive-form.html",'<span ng-if="controller.valueType">\n  <input ng-if="controller.valueType == \'RDFBool\' ||\n                controller.valueType == \'bool\'" class="form-control"\n         type="checkbox" ng-model="value.value" />\n\n  <input ng-if="controller.valueType == \'RDFInteger\' ||\n                controller.valueType == \'int\' ||\n                controller.valueType == \'long\' ||\n                controller.valueType == \'float\'" class="form-control"\n         type="number" ng-model="value.value" />\n\n  <input ng-if="controller.valueType == \'RDFString\' ||\n                controller.valueType == \'basestring\' ||\n                controller.valueType == \'RDFURN\'" class="form-control"\n         type="text" ng-model="value.value" />\n\n  <input ng-if="controller.valueType == \'RDFBytes\' ||\n                controller.valueType == \'bytes\'" class="form-control"\n         type="text" ng-model="value.value" />\n</span>\n');
$templateCache.put("forms/semantic-proto-form.html",'<div ng-if="controller.valueDescriptor.union_field">\n  <grr-form-proto-union value="controller.editedValue"\n                        descriptor="controller.valueDescriptor" />\n</div>\n\n<div ng-if="!controller.valueDescriptor.union_field">\n  <div class="form-group" ng-if="metadata.depth >= 2">\n    <i class="nested-icon glyphicon" ng-click="controller.expanded = !controller.expanded"\n       ng-class="{\'glyphicon-plus\': !controller.expanded, \'glyphicon-minus\': controller.expanded}"></i>\n  </div>\n\n  <div ng-if="(metadata.depth === undefined || metadata.depth < 2 || controller.expanded)">\n\n    <div ng-repeat="field in controller.valueDescriptor.fields |\n                    filter:controller.regularFieldsOnly |\n                    filter:controller.boundNotExplicitlyHiddenFields">\n      <grr-form-proto-single-field value="controller.editedValue.value[field.name]"\n                                   field="field"\n                                   ng-if="!field.repeated">\n      </grr-form-proto-single-field>\n\n      <grr-form-proto-repeated-field value="controller.editedValue.value[field.name]"\n                                     descriptor="controller.descriptors[field.type]"\n                                     field="field"\n                                     ng-if="field.repeated">\n      </grr-form-proto-repeated-field>\n    </div>\n\n    <div ng-if="controller.hasAdvancedFields">\n      <div>\n        <label class="control-label">\n          <a class="advanced-label"\n             ng-click="controller.advancedShown = !controller.advancedShown">\n            Advanced\n          </a>\n          <i class="advanced-icon glyphicon"\n             ng-class="{\'glyphicon-chevron-right\': !controller.advancedShown,\n                       \'glyphicon-chevron-down\': controller.advancedShown}"></i>\n        </label>\n      </div>\n      <div class="clearfix"></div>\n\n      <div class="advanced-controls" ng-show="controller.advancedShown">\n        <div ng-repeat="field in controller.valueDescriptor.fields |\n                        filter:controller.advancedFieldsOnly |\n                        filter:controller.boundNotExplicitlyHiddenFields">\n          <grr-form-proto-single-field value="controller.editedValue.value[field.name]"\n                                       field="field"\n                                       ng-if="!field.repeated">\n          </grr-form-proto-single-field>\n\n          <grr-form-proto-repeated-field value="controller.editedValue.value[field.name]"\n                                         descriptor="controller.descriptors[field.type]"\n                                         field="field"\n                                         ng-if="field.repeated">\n          </grr-form-proto-repeated-field>\n        </div>\n      </div>\n    </div>\n    <div class="clearfix"></div>\n\n  </div>\n\n</div>\n');
$templateCache.put("forms/semantic-proto-repeated-field-form.html",'<div ng-if="controller.hasCustomTemplate === false">\n  <div class="form-group">\n    <label class="control-label" title="{$ field.doc $}">\n      {$ field.friendly_name $}\n      <a ng-if="field.context_help_url"\n         ng-href="/help/{$ field.context_help_url $}" target="_blank">\n        <i class="glyphicon glyphicon-question-sign"></i>\n      </a>\n    </label>\n\n    <div class="controls">\n      <button class="btn btn-default form-add" name="Add"\n              ng-click="controller.addItem()">\n        <i class="glyphicon glyphicon-plus"></i>\n      </button>\n    </div>\n  </div>\n\n  <div ng-repeat="item in value">\n    <button type="button" class="control-label close" name="Remove"\n            ng-click="controller.removeItem($index)">&times;</button>\n    <div class="controls">\n      <div class="form-group">\n        <grr-form-value value="item" metadata="field"></grr-form-value>\n      </div>\n    </div>\n  </div>\n</div>\n\n<div ng-show="controller.hasCustomTemplate === true && !controller.hideCustomTemplateLabel">\n  <div class="form-group">\n    <label class="control-label" title="{$ field.doc $}">\n      {$ field.friendly_name $}\n      <a ng-if="field.context_help_url"\n         ng-href="/help/{$ field.context_help_url $}" target="_blank">\n        <i class="glyphicon glyphicon-question-sign"></i>\n      </a>\n    </label>\n  </div>\n\n  <div class="controls">\n    <div class="form-group" name="custom-template">\n      \x3c!-- custom template will be inserted here if it\'s available --\x3e\n    </div>\n  </div>\n</div>\n\n<div ng-show="controller.hasCustomTemplate === true && controller.hideCustomTemplateLabel">\n  <div class="form-group" name="custom-template-without-label">\n    \x3c!-- custom template occupying the full form row (without a standard form label)\n         will be inserted here if it\'s available --\x3e\n  </div>\n</div>\n');
$templateCache.put("forms/semantic-proto-single-field-form.html",'<div class="form-group">\n  <label class="control-label" title="{$ field.doc $}">\n    {$ field.friendly_name $}\n    <a ng-if="field.context_help_url"\n       ng-href="/help/{$ field.context_help_url $}" target="_blank">\n      <i class="glyphicon glyphicon-question-sign"></i>\n    </a>\n  </label>\n  <div class="controls">\n    <grr-form-value value="value" metadata="field" />\n  </div>\n</div>\n');$templateCache.put("forms/semantic-proto-union-form.html",
'<div class="well well-large">\n\n  <div class="form-group">\n    <label class="control-label" title="{$ controller.unionField.doc $}">\n      {$ controller.unionField.friendly_name $}\n    </label>\n    <div class="controls">\n      <grr-form-value value="value.value[controller.unionField.name]"\n                      metadata="controller.unionField" />\n    </div>\n  </div>\n\n  <div class="form-group">\n    <grr-form-value value="value.value[controller.unionFieldValue]" />\n  </div>\n\n</div>\n');
$templateCache.put("forms/timerange-form.html",'<label class="control-label">{{\n  controller.startTimeLabel || \'Time range start time\'\n}}</label>\n<div class="controls">\n  <grr-form-value value="controller.formStartTime"></grr-form-value>\n</div>\n\n<label class="control-label">{{\n  controller.durationLabel || \'Time range duration\'\n}}</label>\n<div class="controls">\n  <grr-form-value value="controller.formDuration"></grr-form-value>\n</div>\n');$templateCache.put("hunt/hunt-clients.html",
'<div class="pull-right horizontally-padded">\n  <div class="btn-group" data-toggle="buttons">\n    <label class="btn btn-default" name="ShowOutstandingClients"\n           ng-click="controller.clientType = \'outstanding\'">\n      <input type="radio">Outstanding</input>\n    </label>\n    <label class="btn btn-default active" name="ShowCompletedClients"\n           ng-click="controller.clientType = \'completed\'">\n      <input type="radio">Completed</input>\n    </label>\n  </div>\n</div>\n<div class="padded clearfix"></div>\n\n<grr-force-refresh refresh-trigger="controller.huntClientsUrl">\n\n  <table class="table table-striped table-condensed table-bordered full-width">\n    <thead>\n      <tr>\n        <th>Client</th>\n        <th>Flow</th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr grr-infinite-table grr-api-items-provider\n          url="::controller.huntClientsUrl">\n        <td><grr-semantic-value value="::item.value.client_id" /></td>\n        <td>\n          <a ui-sref="client.flows(::{clientId: item.value.client_id.value,\n                      flowId: item.value.flow_id.value})">\n            {$ ::item.value.flow_id.value $}\n          </a>\n        </td>\n      </tr>\n    </tbody>\n  </table>\n\n</grr-force-refresh>\n');
$templateCache.put("hunt/hunt-context.html",'<grr-semantic-value value="::controller.runner_args"></grr-semantic-value>\n<grr-semantic-value value="::controller.args"></grr-semantic-value>\n<grr-semantic-value value="::controller.context"></grr-semantic-value>\n<grr-semantic-value value="::controller.state"></grr-semantic-value>\n');$templateCache.put("hunt/hunt-crashes.html",'<table class="table table-striped table-condensed table-bordered full-width">\n  <thead>\n    <tr>\n      <th>Client</th>\n      <th>Crash Details</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-paged-filtered-table grr-api-items-provider url="::controller.crashesUrl"\n        auto-refresh-interval="::controller.autoRefreshInterval">\n      <td ng-class="::{proto_key: $index % 2 == 0}">\n        <grr-client-urn value="::item.value.client_id.value" />\n      </td>\n      <td ng-class="::{proto_key: $index % 2 == 0}">\n        <dl class="dl-horizontal">\n\n          <dt>Timestamp</dt>\n          <dd><grr-timestamp value="::item.value.timestamp" /></dd>\n\n          <dt>Crash Type</dt>\n          <dd><grr-semantic-value value="::item.value.crash_type" /> </dd>\n\n          <div ng-if="::item.value.crash_message !== undefined">\n            <dt>Crash Message</dt><dd><grr-semantic-value value="::item.value.crash_message" />\n          </div>\n\n          <div ng-if="::item.value.backtrace !== undefined">\n            <dt>Backtrace</dt><dd><grr-semantic-value value="::item.value.backtrace" />\n          </div>\n\n          <div ng-if="::item.value.session_id !== undefined">\n            <dt>Session Id</dt><dd><grr-semantic-value value="::item.value.session_id" /></dd>\n          </div>\n\n          <dt>Client Information</dt>\n          <dd><grr-semantic-value value="::item.value.client_info" /></dd>\n        </dl>\n      </td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("hunt/hunt-errors.html",'<table class="proto-table no-cell-border full-width">\n  <thead>\n    <tr>\n      <th>Age</th>\n      <th>Client</th>\n      <th>Backtrace</th>\n      <th>Message</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-paged-filtered-table grr-api-items-provider url="::controller.errorsUrl"\n        auto-refresh-interval="::controller.autoRefreshInterval">\n      <td ng-class="::{proto_key: $index % 2 == 0}"><grr-timestamp value="::item.age" /></td>\n      <td ng-class="::{proto_key: $index % 2 == 0}"><grr-client-urn value="::item.value.client_id" /></td>\n      <td ng-class="::{proto_key: $index % 2 == 0}">{$ ::item.value.backtrace.value $}</td>\n      <td ng-class="::{proto_key: $index % 2 == 0}">{$ ::item.value.log_message.value $}</td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("hunt/hunt-graph.html",'<div class="fill-parent-no-margins" ng-show="controller.inProgress">\n    Loading...\n</div>\n\n<div ng-hide="controller.inProgress">\n    <table class="grr_flot_graph" ng-show="controller.informationAvailable">\n        <tr>\n            <td></td>\n            <td class="title">Agent Coverage</td>\n        </tr>\n        <tr>\n            <td class="axis-y">Agents</td>\n            <td class="graph-wrapper">\n                <div class="client-completion-graph"></div>\n            </td>\n        </tr>\n        <tr>\n            <td></td>\n            <td class="axis-x">Time (h)</td>\n        </tr>\n    </table>\n\n    <div ng-hide="controller.informationAvailable">\n        No data to graph yet.\n    </div>\n</div>\n');
$templateCache.put("hunt/hunt-inspector.html",'<div class="padded">\n\n  <div ng-if="!huntUrn">\n    Please select a hunt to see its details here.\n  </div>\n\n  <uib-tabset ng-if="huntUrn && huntUrn === controller.shownHuntUrn"\n              active="controller.activeTab">\n    <uib-tab heading="Overview" index="\'\'">\n      <grr-hunt-overview hunt-urn="huntUrn" ng-if="controller.tabsShown[\'\']">\n      </grr-hunt-overview>\n    </uib-tab>\n\n    <uib-tab heading="Log" index="\'log\'">\n      <grr-hunt-log hunt-urn="huntUrn" ng-if="controller.tabsShown[\'log\']">\n      </grr-hunt-log>\n    </uib-tab>\n\n    <uib-tab heading="Errors" index="\'errors\'">\n      <grr-hunt-errors hunt-urn="huntUrn" ng-if="controller.tabsShown[\'errors\']">\n      </grr-hunt-errors>\n    </uib-tab>\n\n    <uib-tab heading="Graph" index="\'hunt-graph\'">\n      <grr-hunt-graph hunt-urn="huntUrn" ng-if="controller.tabsShown[\'hunt-graph\']">\n      </grr-hunt-graph>\n    </uib-tab>\n\n    <uib-tab heading="Results" index="\'results\'">\n      <grr-hunt-results hunt-urn="huntUrn" ng-if="controller.tabsShown[\'results\']">\n      </grr-hunt-results>\n    </uib-tab>\n\n    <uib-tab heading="Stats" index="\'stats\'">\n      <grr-hunt-stats hunt-urn="huntUrn" ng-if="controller.tabsShown[\'stats\']">\n      </grr-hunt-stats>\n    </uib-tab>\n\n    <uib-tab heading="Crashes" index="\'crashes\'">\n      <grr-hunt-crashes hunt-urn="huntUrn" ng-if="controller.tabsShown[\'crashes\']">\n      </grr-hunt-crashes>\n    </uib-tab>\n\n    <uib-tab heading="Clients" index="\'clients\'">\n      <grr-hunt-clients hunt-urn="huntUrn" ng-if="controller.tabsShown[\'clients\']">\n      </grr-hunt-clients>\n    </uib-tab>\n\n    <uib-tab heading="Context Details" index="\'context-details\'">\n      <grr-hunt-context hunt-urn="huntUrn" ng-if="controller.tabsShown[\'context-details\']">\n      </grr-hunt-context>\n    </uib-tab>\n  </uib-tabset>\n\n</div>\n');
$templateCache.put("hunt/hunt-log.html",'<table class="proto-table no-cell-border full-width">\n  <thead>\n    <tr>\n      <th>Age</th>\n      <th>Client</th>\n      <th>Flow URN</th>\n      <th>Flow Name</th>\n      <th>Message</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-paged-filtered-table page-size="100"\n        grr-api-items-provider url="::controller.logsUrl"\n        transform-items="controller.transformItems(items)"\n        auto-refresh-interval="::controller.autoRefreshInterval">\n      <td ng-class="::{proto_key: item.highlighted}"><grr-timestamp value="::item.age" /></td>\n      <td ng-class="::{proto_key: item.highlighted}"><grr-client-urn value="::item.value.client_id.value" /></td>\n      <td ng-class="::{proto_key: item.highlighted}">{$ ::item.shortUrn.value $}</td>\n      <td ng-class="::{proto_key: item.highlighted}">{$ ::item.value.flow_name.value $}</td>\n      <td ng-class="::{proto_key: item.highlighted}">{$ ::item.value.log_message.value $}</td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("hunt/hunt-overview.html",'<div ng-if="huntUrn && !controller.hunt">\n  Loading...\n</div>\n\n<div ng-if="controller.hunt">\n\n  <dl class="dl-horizontal dl-hunt">\n\n    <grr-force-refresh refresh-trigger="controller.hunt">\n\n      <div ng-if="::controller.hunt.value.internal_error">\n        <br>\n        <dt class="alert-danger danger">Error while Opening</dt>\n        <dd>{$ ::controller.hunt.value.internal_error.value $}</dd>\n        <br><br>\n      </div>\n\n      <dt>Name</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.name" /></dd>\n\n      <dt>Description</dt>\n      <dd>{$ ::controller.hunt.value.description.value $}</dd>\n\n      <dt>Hunt ID</dt>\n      <dd>{$ ::controller.huntId $}</dd>\n\n      <dt>Hunt URN</dt>\n      <dd>{$ ::controller.hunt.value.urn.value $}</dd>\n\n      <dt>Creator</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.creator" /></dd>\n\n      <dt>Start Time</dt>\n      <dd><grr-timestamp value="controller.hunt.value.created" /></dd>\n\n      <dt>Expiry Time</dt>\n      <dd><grr-timestamp value="controller.hunt.value.expires" /></dd>\n\n      <dt>Crash Limit</dt>\n      <dd ng-if="::!controller.hunt.value.crash_limit">-</dd>\n      <dd ng-if="::controller.hunt.value.crash_limit">\n        <grr-semantic-value value="::controller.hunt.value.crash_limit" />\n      </dd>\n\n      <dt>Client Limit</dt>\n      <dd ng-if="::!controller.hunt.value.client_limit">-</dd>\n      <dd ng-if="::controller.hunt.value.client_limit">\n        <grr-semantic-value value="::controller.hunt.value.client_limit" />\n      </dd>\n\n      <dt>Client Rate (clients/min)</dt>\n      <dd ng-if="::!controller.hunt.value.client_rate">-</dd>\n      <dd ng-if="::controller.hunt.value.client_rate">\n        <grr-semantic-value value="::controller.hunt.value.client_rate" />\n      </dd>\n      <br>\n\n\n      <dt>Status</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.state" /></dd>\n\n      <dt>Clients Queued</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.clients_queued_count" /></dd>\n\n      <dt>Clients Scheduled</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.all_clients_count" /></dd>\n\n      <dt>Clients Outstanding</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.remaining_clients_count" /></dd>\n\n      <dt>Clients Completed</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.completed_clients_count" /></dd>\n\n      <dt>Clients with Results</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.clients_with_results_count" /></dd>\n\n      <dt>Results</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.results_count" /></dd>\n\n      <dt>Total CPU Seconds Used</dt>\n      <dd>{$ ::controller.hunt.value.total_cpu_usage.value | number:2 $}s</dd>\n\n      <dt>Total Network Traffic</dt>\n      <dd>{$ ::controller.hunt.value.total_net_usage.value | number:0 $}b</dd>\n      <br>\n    </grr-force-refresh>\n\n    \x3c!-- Don\'t auto-refresh hunt arguments since they can\'t be changed after the\n         hunt object is created. --\x3e\n    <dt>Flow Name</dt>\n    <dd><grr-semantic-value value="::controller.hunt.value.flow_name" /></dd>\n\n    <dt>Flow Arguments</dt>\n    <dd><grr-semantic-value value="::controller.hunt.value.flow_args" /></dd>\n    <br>\n\n\n    <span ng-if="::controller.hunt.value.client_rule_set">\n      <dt>Client Rule Set</dt>\n      <dd>\n        <grr-semantic-value value="::controller.hunt.value.client_rule_set" />\n      </dd>\n    </span>\n    <br>\n\n\n    <span ng-if="::controller.hunt.value.hunt_runner_args.value.output_plugins">\n      <dt>Output Plugins</dt>\n      <dd>\n        <grr-semantic-value value="::controller.hunt.value.hunt_runner_args.value.output_plugins" />\n      </dd>\n    </span>\n\n  </dl>\n\n</div>\n');
$templateCache.put("hunt/hunt-results.html",'<grr-results-collection\n  results-url="controller.resultsUrl"\n  exported-results-url="controller.exportedResultsUrl"\n  output-plugins-url="controller.outputPluginsUrl"\n  download-files-url="controller.downloadFilesUrl"\n  export-command-url="controller.exportCommandUrl"\n  transform-items="controller.transformItems(items)"\n\n  ng-if= "controller.resultsUrl"/>\n');$templateCache.put("hunt/hunt-stats.html",'<h3>Total number of clients: {$ ::controller.totalClientCount $}</h3>\n\n<h3>User CPU seconds</h3>\n<dl class="dl-horizontal">\n  <dt>User CPU mean</dt>\n  <dd>{$ ::controller.userCpuStats.mean | number:1 $}</dd>\n\n  <dt>User CPU stdev</dt>\n  <dd>{$ ::controller.userCpuStats.stdev | number:1 $}</dd>\n\n  <dt>Clients Histogram</dt>\n  <dd class="histogram">\n    <div class="user-cpu-histogram"></div>\n  </dd>\n</dl>\n\n<h3>System CPU seconds</h3>\n<dl class="dl-horizontal">\n  <dt>System CPU mean</dt>\n  <dd>{$ ::controller.systemCpuStats.mean | number:1 $}</dd>\n\n  <dt>System CPU stdev</dt>\n  <dd>{$ ::controller.systemCpuStats.stdev | number:1 $}</dd>\n\n  <dt>Clients Histogram</dt>\n  <dd class="histogram">\n    <div class="system-cpu-histogram"></div>\n  </dd>\n</dl>\n\n<h3>Network bytes sent</h3>\n<dl class="dl-horizontal">\n  <dt>Network bytes sent mean</dt>\n  <dd>{$ ::controller.networkBytesStats.mean | number:1 $}</dd>\n\n  <dt>Network bytes sent stdev</dt>\n  <dd>{$ ::controller.networkBytesStats.stdev | number:1 $}</dd>\n\n  <dt>Clients Histogram</dt>\n  <dd class="histogram">\n    <div class="network-bytes-histogram"></div>\n  </dd>\n</dl>\n\n<h3>Worst performers</h3>\n<table class="table table-condensed table-striped table-bordered">\n  <thead>\n    <th>Client Id</th>\n    <th>User CPU seconds</th>\n    <th>System CPU seconds</th>\n    <th>Network bytes sent</th>\n  </thead>\n  <tbody>\n    <tr ng-repeat="client in controller.stats.value.worst_performers">\n      <td><grr-semantic-value value="client.value.client_id"></grr-semantic-value></td>\n      <td>{$ ::client.value.cpu_usage.value.user_cpu_time.value | number:1 $}</td>\n      <td>{$ ::client.value.cpu_usage.value.system_cpu_time.value | number:1 $}</td>\n      <td>{$ ::client.value.network_bytes_sent.value $}</td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("hunt/hunt-status-icon.html",'<div class="centered hunt-state-icon" state="{$ ::hunt.value.state.value $}">\n  <img ng-if="::hunt.value.state.value == \'STOPPED\'"\n       class="grr-icon grr-flow-icon" src="/static/images/stop.png" />\n  <img ng-if="::hunt.value.state.value == \'STARTED\'"\n       class="grr-icon grr-flow-icon" src="/static/images/clock.png" />\n  <img ng-if="::hunt.value.state.value == \'PAUSED\'"\n       class="grr-icon grr-flow-icon" src="/static/images/pause.png" />\n  <img ng-if="::hunt.value.state.value == \'COMPLETED\'"\n       class="grr-icon grr-flow-icon" src="/static/images/stock_yes.png" />\n</div>\n');
$templateCache.put("hunt/hunts-list.html",'<div class="toolbar">\n  <ul class="breadcrumb">\n    <li>\n      <button class="btn btn-default" name="NewHunt"\n              title="New Hunt" ng-click="controller.newHunt()">\n        <img src="/static/images/new.png" class="toolbar-icon" />\n      </button>\n\n      <div class="btn-group">\n        <button class="btn btn-default" name="RunHunt"\n                title="Run Hunt"\n                ng-disabled="controller.huntsByUrn[selectedHuntUrn].value.state.value != \'PAUSED\' &&\n                             controller.huntsByUrn[selectedHuntUrn].value.state.value != \'STOPPED\'"\n                ng-click="controller.runHunt()">\n          <img src="/static/images/play_button.png" class="toolbar-icon" />\n        </button>\n\n        <button class="btn btn-default" name="StopHunt"\n                title="Stop Hunt"\n                ng-disabled="controller.huntsByUrn[selectedHuntUrn].value.state.value != \'STARTED\'"\n                ng-click="controller.stopHunt()">\n          <img src="/static/images/stop_button.png" class="toolbar-icon" />\n        </button>\n      </div>\n\n      <div class="btn-group">\n        <button class="btn btn-default" name="ModifyHunt"\n                title="Modify Hunt"\n                ng-disabled="controller.huntsByUrn[selectedHuntUrn].value.state.value != \'PAUSED\' &&\n                             controller.huntsByUrn[selectedHuntUrn].value.state.value != \'STOPPED\'"\n                ng-click="controller.modifyHunt()">\n          <img src="/static/images/modify.png" class="toolbar-icon" />\n        </button>\n\n        <button class="btn btn-default" name="CopyHunt"\n                title="Copy Hunt"\n                ng-disabled="!selectedHuntUrn"\n                ng-click="controller.copyHunt()">\n          <img src="/static/images/copy.png" class="toolbar-icon" />\n        </button>\n\n        <button class="btn btn-default" name="DeleteHunt"\n                title="Delete Hunt"\n                ng-disabled="controller.huntsByUrn[selectedHuntUrn].value.state.value != \'PAUSED\' &&\n                             controller.huntsByUrn[selectedHuntUrn].value.state.value != \'STOPPED\'"\n                ng-click="controller.deleteHunt()">\n          <img src="/static/images/editdelete.png" class="toolbar-icon" />\n        </button>\n      </div>\n\n      <div class="btn-group">\n        <button class="btn btn-default" name="ToggleRobotHuntDisplay"\n                title="Show/Hide Automated hunts" uib-btn-checkbox\n                ng-model="controller.showRobotHunts">\n          <img src="/static/images/robot.png" class="toolbar-icon" />\n        </button>\n        <a href="/help/investigating-with-grr/hunts/controlling-hunts.html" target="_blank"\n          class="pull-right">\n          <i class="glyphicon glyphicon-question-sign input-append"></i>\n        </a>\n      </div>\n    </li>\n  </ul>\n</div>\n\n<div class="fill-parent-with-toolbar">\n  <table class="table table-striped table-condensed table-hover table-bordered full-width">\n    <colgroup>\n      <col />\n      <col />\n      <col />\n      <col />\n      <col />\n      <col />\n      <col />\n      <col width="100%" />\n    </colgroup>\n    <thead>\n      <tr>\n        <th>Status</th>\n        <th>Hunt ID</th>\n        <th>Name</th>\n        <th>Start Time</th>\n        <th>Expires</th>\n        <th>Client Limit</th>\n        <th>Creator</th>\n        <th>Description</th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr grr-infinite-table page-size="100"\n          grr-api-items-provider url="controller.huntsUrl"\n          transform-items="controller.transformItems(items)" trigger-update="controller.triggerUpdate"\n          ng-click="controller.selectItem(item)"\n          ng-class="{\'row-selected\': item.value.urn.value == selectedHuntUrn, \'warning\': item.value.is_robot.value}"\n          ng-show="controller.showRobotHunts || !item.value.is_robot.value">\n\n        <td><grr-hunt-status-icon hunt="::item" /></td>\n        <td>{$ ::item.value.hunt_id.value $}</td>\n        <td>{$ ::item.value.name.value $}</td>\n        <td><grr-timestamp value="::item.value.created" /></td>\n        <td><grr-timestamp value="::item.value.expires" /></td>\n        <td>{$ ::item.value.client_limit.value $}</td>\n        <td>{$ ::item.value.creator.value $}</td>\n        <td>{$ ::item.value.description.value $}</td>\n      </tr>\n    </tbody>\n  </table>\n</div>\n');
$templateCache.put("hunt/hunts-view.html",'<div grr-splitter orientation="horizontal" class="rightSplitterContainer">\n  <div grr-splitter-pane id="content_rightPane" class="rightTopPane">\n    <grr-hunts-list selected-hunt-urn="controller.selectedHuntUrn" />\n  </div>\n\n  <div grr-splitter-pane id="main_bottomPane" class="rightBottomPane">\n    <grr-hunt-inspector hunt-urn="controller.selectedHuntUrn"\n                        active-tab="controller.tab" />\n  </div>\n</div>\n');$templateCache.put("hunt/modify-hunt-dialog.html",
'<grr-confirmation-dialog name="ModifyHuntDialog"\n                         title="\'Modify this hunt\'"\n                         proceed="controller.proceed()"\n                         proceed-name="\'Modify!\'"\n                         can-proceed="controller.argsObj">\n\n\n  <grr-form-proto ng-if="controller.argsObj"\n                  value="controller.argsObj"\n                  visible-fields="[\'client_limit\', \'client_rate\', \'expires\']">\n  </grr-form-proto>\n\n  <div ng-if="!controller.argsObj">\n    <i class="fa fa-spinner fa-spin fa-fw"></i> Loading...\n  </div>\n\n</grr-confirmation-dialog>\n');
$templateCache.put("output-plugins/output-plugin-logs-modal.html",'<div class="modal-header">\n  <button type="button" class="close" ng-click="$dismiss()">\n    <span aria-hidden="true">&times;</span>\n    <span class="sr-only">Close</span>\n  </button>\n  <h3 class="modal-title">Inspect {$ label $}</h3>\n</div>\n<div class="modal-body">\n  <div class="padded">\n\n    <table class="table table-striped table-condensed table-hover table-bordered full-width">\n      <thead>\n        <tr>\n          <th>Time</th>\n          <th>Status</th>\n          <th>Summary</th>\n          <th>Batch size</th>\n          <th>Batch index</th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr grr-paged-filtered-table grr-api-items-provider url="url">\n          <td><grr-timestamp value="::item.age" /></td>\n          <td><grr-semantic-value value="::item.value.status" /></td>\n          <td><grr-semantic-value value="::item.value.summary" /></td>\n          <td><grr-semantic-value value="::item.value.batch_size" /></td>\n          <td><grr-semantic-value value="::item.value.batch_index" /></td>\n        </tr>\n      </tbody>\n    </table>\n\n  </div>\n</div>\n<div class="modal-footer">\n  <button class="btn btn-default" ng-click="$dismiss()" name="Close">\n    Close\n  </button>\n</div>\n');
$templateCache.put("output-plugins/output-plugin-logs.html",'<span ng-if="controller.itemsCount > 0">\n\n  <span class="label" ng-class="cssClass" ng-click="controller.onClick()">\n    <span ng-if="icon" ng-class="icon"\n          class="glyphicon" aria-hidden="true">\n    </span>\n    {$ controller.itemsCount $} {$ label $}\n  </span>\n\n</span>\n');$templateCache.put("output-plugins/output-plugin-note.html",'<div class="panel panel-default">\n  <div class="panel-heading">\n    {$ controller.pluginTitle $}\n    <div class="pull-right">\n      <grr-output-plugin-logs url="controller.pluginLogsUrl"\n                              label="logs"\n                              css-class="label-default">\n      </grr-output-plugin-logs>\n      &nbsp;\n      <grr-output-plugin-logs url="controller.pluginErrorsUrl"\n                              label="errors"\n                              css-class="label-danger"\n                              icon="glyphicon-exclamation-mark">\n      </grr-output-plugin-logs>\n    </div>\n  </div>\n  <div class="panel-body">\n    <grr-output-plugin-note-body output-plugin="outputPlugin" />\n  </div>\n</div>\n');
$templateCache.put("output-plugins/output-plugins-notes.html",'<div ng-repeat="outputPlugin in controller.outputPlugins">\n  <grr-output-plugin-note output-plugin="outputPlugin"\n                          output-plugins-url="outputPluginsUrl">\n  </grr-output-plugin-note>\n</div>\n<div class="alert alert-error" ng-if="controller.error">\n  <em>Can\'t fetch output plugins list: {$ controller.error $}.</em>\n</div>\n');$templateCache.put("semantic/api-hunt-result.html",'<grr-client-context client-id="::value.value.client_id.value">\n  <grr-semantic-proto value="::value"><grr-semantic-proto>\n</grr-client-context>\n');
$templateCache.put("semantic/byte-size.html",'<span ng-if="::controller.stringifiedByteSize !== undefined"\n      title="{$ ::value.value $} bytes">\n  {$ ::controller.stringifiedByteSize $}\n</span>\n');$templateCache.put("semantic/bytes.html",'<a ng-if="controller.stringifiedBytes === undefined" ng-click="controller.onClick($event)">\n  Show bytes...\n</a>\n<nobr ng-if="::controller.stringifiedBytes">{$ ::controller.stringifiedBytes $}</nobr>\n');$templateCache.put("semantic/client-urn-modal.html",
'<div class="modal-header">\n  <button type="button" class="close" ng-click="$dismiss()">\n    <span aria-hidden="true">&times;</span>\n    <span class="sr-only">Close</span>\n  </button>\n  <h4 class="modal-title">Client {$ ::controller.clientId $}</h4>\n</div>\n<div class="modal-body">\n  <grr-semantic-value value="::controller.clientDetails" />\n</div>\n');$templateCache.put("semantic/client-urn.html",'<nobr ng-if="::value">\n  <a ng-if="::controller.clientId"\n     ui-sref="client.hostInfo(::{clientId: controller.clientId })">\n    {$ ::controller.clientId $}\n  </a>\n\n  <button class="btn btn-default btn-xs" ng-click="controller.onInfoClick()">\n    <span class="glyphicon glyphicon-info-sign"></span>\n  </button>\n</nobr>\n');
$templateCache.put("semantic/data-object.html",'<table class="proto_table">\n  <tbody>\n    <tr ng-repeat="keyValuePair in ::value.value.items">\n      <td class="proto_key">\n        {$ ::keyValuePair.value.key.value $}\n      </td>\n\n      <td class="proto_value">\n        <grr-semantic-value value="::keyValuePair.value.value" />\n      </td>\n    </tr>\n  </tbody>\n</table>\n');$templateCache.put("semantic/dict.html",'<table class="proto_table">\n  <tbody>\n    <tr ng-repeat="(key, value) in ::value.value">\n      <td class="proto_key" ng-if="::key !== \'mro\' && key !== \'data\'">\n        {$ ::key $}\n      </td>\n\n      <td class="proto_value">\n        <grr-semantic-value value="::value" />\n      </td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("semantic/flow-id.html",'<nobr ng-if="::value">\n  <a ng-if="::controller.clientId !== undefined"\n    title="Flow {$ ::value.value $} ran on client {$ ::controller.clientId $}"\n    ui-sref="client.flows(::{clientId: controller.clientId, flowId: value.value })">\n    {$ ::value.value $}\n  </a>\n  <span ng-if="::controller.clientId === undefined">{$ ::value.value $}</span>\n</nobr>\n');$templateCache.put("semantic/hunt-id.html",'<nobr ng-if="::value">\n  <a ui-sref="hunts(::{huntId: value.value })">\n    {$ ::value.value $}\n  </a>\n</nobr>\n');
$templateCache.put("semantic/json.html",'<a ng-if="controller.prettyJson === undefined" ng-click="controller.onClick($event)">\n  Show JSON...\n</a>\n<span ng-if="::controller.prettyJson" class="preserve-whitespace">{$ ::controller.prettyJson $}</span>\n');$templateCache.put("semantic/object-label.html",'<span ng-if="::controller.labelOwner == \'GRR\'" class="label label-default">\n  {$ ::controller.labelName $}\n</span>\n\n<span ng-if="::controller.labelOwner != \'GRR\'" class="label label-success">\n  {$ ::controller.labelName $}\n</span>\n');
$templateCache.put("semantic/rekall-response.html",'<grr-semantic-proto value="::value"></grr-semantic-proto>\n\n<grr-rekall-json\n    json-context-messages="::value.value.json_context_messages"\n    compressed-json-messages="::value.value.compressed_json_messages">\n</grr-rekall-json>\n');$templateCache.put("semantic/semantic-diff-annotated-proto.html","<table ng-class=\"::{'diff-added': value._diff === 'added',\n                 'diff-removed': value._diff === 'removed',\n                 'diff-changed': value._diff === 'changed',\n                 'proto_table': true}\">\n  <tbody>\n    <tr ng-repeat=\"item in ::controller.items\"\n        ng-class=\"::{'diff-added': item.value._diff === 'added',\n                  'diff-removed': item.value._diff === 'removed',\n                  'diff-changed': item.value._diff === 'changed'}\">\n      <td class=\"proto_key\" ng-if=\"::item.desc !== undefined\">\n        <abbr title=\"{$ ::item.desc $}\">{$ ::item.key $}</abbr>\n      </td>\n      <td class=\"proto_key\" ng-if=\"::item.desc === undefined\">{$ ::item.key $}</td>\n\n      <td class=\"proto_value\">\n        <grr-semantic-value ng-if=\"::!item.isList && item.value !== undefined\" value=\"::item.value\">\n        </grr-semantic-value>\n        <div ng-if=\"::item.isList === true\">\n          <div ng-repeat=\"repeatedItem in ::item.value\"\n               ng-class=\"::{'diff-added': repeatedItem._diff === 'added',\n                         'diff-removed': repeatedItem._diff === 'removed',\n                         'diff-changed': repeatedItem._diff === 'changed',\n                         'repeated': true}\">\n            <grr-semantic-value value=\"::repeatedItem\"></grr-semantic-value>\n          </div>\n        </div>\n      </td>\n    </tr>\n  </tbody>\n</table>\n");
$templateCache.put("semantic/semantic-proto.html",'<table class="proto_table">\n  <tbody>\n    <tr ng-repeat="item in ::controller.items">\n      <td class="proto_key" ng-if="::item.desc !== undefined">\n        <abbr title="{$ ::item.desc $}">{$ ::item.key $}</abbr>\n      </td>\n      <td class="proto_key" ng-if="::item.desc === undefined">{$ ::item.key $}</td>\n\n      <td class="proto_value">\n        <grr-semantic-value ng-if="::item.value !== undefined" value="::item.value" />\n      </td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("semantic/semantic-protos-diff.html",'<grr-semantic-value-registry-override map="::controller.overrideMap">\n\n  <div class="row">\n    <div class="col-md-6">\n      <grr-semantic-diff-annotated-proto ng-if="::controller.annotatedOriginalValue"\n                                         value="::controller.annotatedOriginalValue"\n                                         visible-fields="::visibleFields"\n                                         hidden-fields="::hiddenFields">\n      </grr-semantic-diff-annotated-proto>\n      <span ng-if="::!controller.annotatedOriginalValue">-</span>\n    </div>\n\n    <div class="col-md-6">\n      <grr-semantic-diff-annotated-proto ng-if="::controller.annotatedNewValue"\n                                         value="::controller.annotatedNewValue"\n                                         visible-fields="::visibleFields"\n                                         hidden-fields="::hiddenFields">\n      </grr-semantic-diff-annotated-proto>\n      <span ng-if="::!controller.annotatedNewValue">-</span>\n    </div>\n  </div>\n\n</grr-semantic-value-registry-override>\n');
$templateCache.put("semantic/semantic-versioned-proto.html",'<table class="proto_table">\n  <tbody>\n    <tr ng-repeat="item in ::controller.items">\n      <td class="proto_key" >\n        <abbr title="{$ ::item.desc $}" ng-if="::item.desc !== undefined">{$ ::item.key $}</abbr>\n        <span ng-if="::item.desc === undefined">{$ ::item.key $}</span>\n        <span class="proto_history">\n          <button class="btn btn-default btn-xs"\n                  ng-click="onFieldClick({\'fieldPath\': item.historyPath || item.structKey})">\n            <span class="glyphicon glyphicon-time"></span>\n          </button>\n        </span>\n      </td>\n\n      <td class="proto_value" ng-if="::item.recursiveItem === true">\n        <grr-semantic-versioned-proto ng-if="::item.value !== undefined"\n                                      value="::item.value"\n                                      on-field-click="onFieldClick({\'fieldPath\': fieldPath})"\n                                      history-depth="::historyDepth - 1"\n                                      history-path="::item.historyPath">\n        </grr-semantic-versioned-proto>\n      </td>\n      <td class="proto_value" ng-if="::item.recursiveItem === false">\n        <grr-semantic-value ng-if="::item.value !== undefined" value="::item.value" />\n      </td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("semantic/stat-entry.html",'<table class="proto_table">\n  <tbody>\n    <tr>\n      <td class="proto_key">\n        <abbr title="The location of this file in the AFF4 space.">Aff4path</abbr>\n      </td>\n      <td class="proto_value">\n        <grr-semantic-value value="::controller.aff4Path"></grr-semantic-value>\n\n        <button ng-if="::controller.downloadUrl !== undefined"\n                class="btn btn-default btn-xs" name="download"\n                type="button" ng-click="controller.onDownloadClick()">\n          <span class="glyphicon glyphicon-download"></span>\n        </button>\n      </td>\n    </tr>\n  </tbody>\n</table>\n<grr-semantic-proto value="::controller.statEntry"\n                    hidden-fields="::[\'aff4path\']">\n</grr-semantic-proto>\n');
$templateCache.put("semantic/timestamp.html",'<span ng-if="::controller.formattedTimestamp" ng-mouseenter="controller.onMouseEnter()">\n  <span class="hidden-md hidden-lg">\n    <span ng-repeat="component in ::controller.formattedTimestampComponents">\n      <nobr>{$ ::component $}</nobr>\n    </span>\n  </span>\n  <span class="visible-md-inline visible-lg-inline">\n    <nobr>\n      {$ ::controller.formattedTimestamp $}\n    </nobr>\n  </span>\n</span>\n');$templateCache.put("semantic/urn.html",
'<span ng-if="::controller.ref === undefined"\n      title="This URN points to AFF4 location not accessible from the UI">\n  <em>{$ ::controller.plainValue $}</em>\n</span>\n<a ng-if="::controller.ref !== undefined" ng-href="{$ ::controller.ref $}"\n   ng-click="controller.onClick()">{$ ::controller.plainValue $}</a>\n');$templateCache.put("sidebar/client-summary.html",'<div>\n  <div class="client-name">\n    <span ng-if="client.value.os_info.value.fqdn">\n      {$ client.value.os_info.value.fqdn.value $}\n    </span>\n    <span ng-if="!client.value.os_info.value.fqdn">\n      {$ client.value.urn.value $}\n    </span>\n  </div>\n  <div class="approval-reason" ng-if="controller.approvalReason">\n    Access reason: {$ controller.approvalReason $}\n  </div>\n  <div class="client-status">\n    \x3c!-- Output of the directives below depends on the current time (as\n         they depend on the time *passed since* the time the client was last\n         active. We have to refresh them every second, as Angular won\'t\n         detect the changes automatically (since source value - last_seen_at -\n         stays the same). --\x3e\n    <grr-periodic-refresh interval="1000">\n      Status:\n      <grr-client-status-icons client="client"></grr-client-status-icons>\n      {$ (client.value.last_seen_at.value | grrTimeSince) $}\n    </grr-periodic-refresh>\n  </div>\n  <span ng-if="controller.crashTime != null" class="last-crash">\n    <strong>Last crash:</strong><br/>\n    {$ (controller.crashTime | grrTimeSince) $}\n  </span>\n  <div class="client-ip-info">\n    <img ng-if="controller.lastIP.status === \'UNKNOWN\'" class="grr-icon-small vertical_aligned" src="/static/images/ip_unknown.png">\n    <img ng-if="controller.lastIP.status === \'INTERNAL\'" class="grr-icon-small vertical_aligned" src="/static/images/ip_internal.png">\n    <img ng-if="controller.lastIP.status === \'EXTERNAL\'" class="grr-icon-small vertical_aligned" src="/static/images/ip_external.png">\n    <img ng-if="controller.lastIP.status === \'VPN\'" class="grr-icon-small vertical_aligned" src="/static/images/ip_unknown.png">\n    {$ controller.lastIP.info $}\n  </div>\n</div>\n');
$templateCache.put("sidebar/nav-dropdown.html",'<a class="dropdown-toggle"\n   ng-click="controller.isCollapsed = !controller.isCollapsed">\n\n  {$ title $}<i class="caret"></i>\n\n</a>\n<div uib-collapse="controller.isCollapsed">\n  <ng-transclude></ng-transclude>\n</div>');$templateCache.put("sidebar/nav-link.html",'<a class="nav-link"\n   ng-disabled="disabled"\n   ng-class="{\'disabled\': disabled}"\n   ng-click="controller.openLink($event)"\n   ng-href="{$ controller.href $}"\n   grrtarget="{$ state $}">\n\n  <i ng-if="disabled" class="fa fa-lock" title="Missing approvals."></i>\n  <ng-transclude></ng-transclude>\n\n</a>\n');
$templateCache.put("sidebar/navigator.html",'<div id="navigator">\n\n  <section ng-if="controller.clientId && !controller.client">\n    Loading...\n  </section>\n\n  \x3c!-- Client overview and links for client navigation --\x3e\n  <section ng-if="controller.client">\n    \x3c!-- Client overview--\x3e\n    <grr-periodic-refresh interval="30000"\n                          on-refresh="controller.refreshClientDetails()">\n    </grr-periodic-refresh>\n    <grr-client-summary client="controller.client"></grr-client-summary>\n\n    \x3c!-- Client links --\x3e\n    <ul class="nav nav-list">\n      <li grr-nav-link state="client.hostInfo"\n          params="{clientId: controller.clientId}">\n        Host Information\n      </li>\n      <li grr-nav-link state="client.launchFlows"\n          params="{clientId: controller.clientId}"\n          disabled="!controller.uiTraits.start_client_flow_nav_item_enabled || !controller.hasClientAccess">\n        Start new flows\n      </li>\n      <li grr-nav-link state="client.vfs"\n          params="{clientId: controller.clientId}"\n          disabled="!controller.uiTraits.browse_virtual_file_system_nav_item_enabled || !controller.hasClientAccess">\n        Browse Virtual Filesystem\n      </li>\n      <li grr-nav-link state="client.flows"\n          params="{clientId: controller.clientId}"\n          disabled="!controller.uiTraits.manage_client_flows_nav_item_enabled || !controller.hasClientAccess">\n        Manage launched flows\n      </li>\n\n      <li id="HostAdvanced" grr-nav-dropdown title="Advanced">\n        <ul class="nav nav-list">\n          <li grr-nav-link state="client.crashes"\n              params="{clientId: controller.clientId}"\n              disabled="!controller.hasClientAccess">\n            Crashes\n          </li>\n          <li grr-nav-link state="client.debugRequests"\n              params="{clientId: controller.clientId}"\n              disabled="!controller.hasClientAccess">\n            Debug Client Requests\n          </li>\n          <li grr-nav-link state="client.loadStats"\n              params="{clientId: controller.clientId}"\n              disabled="!controller.hasClientAccess">\n            Client Load Stats\n          </li>\n        </ul>\n      </li>\n    </ul>\n  </section>\n\n  \x3c!-- Management links --\x3e\n  <section>\n    <h1>Management</h1>\n\n    <ul class="nav nav-list">\n      <li grr-nav-link state="crons"\n          disabled="!controller.uiTraits.cron_jobs_nav_item_enabled">\n        Cron Job Viewer\n      </li>\n      <li grr-nav-link state="hunts"\n          disabled="!controller.uiTraits.hunt_manager_nav_item_enabled">\n        Hunt Manager\n      </li>\n      <li grr-nav-link state="stats"\n          disabled="!controller.uiTraits.show_statistics_nav_item_enabled">\n        Show Statistics\n      </li>\n\n      <li id="ManagementAdvanced" grr-nav-dropdown title="Advanced">\n        <ul class="nav nav-list">\n          <li grr-nav-link state="serverLoad"\n              disabled="!controller.uiTraits.server_load_nav_item_enabled">\n            Server Load\n          </li>\n        </ul>\n      </li>\n    </ul>\n  </section>\n\n  \x3c!-- Configuration links --\x3e\n  <section>\n    <h1>Configuration</h1>\n\n    <ul class="nav nav-list">\n      <li grr-nav-link state="manageBinaries"\n          disabled="!controller.uiTraits.manage_binaries_nav_item_enabled">\n        Manage Binaries\n      </li>\n      <li grr-nav-link state="config"\n          disabled="!controller.uiTraits.settings_nav_item_enabled">\n        Settings\n      </li>\n      <li grr-nav-link state="artifacts"\n          disabled="!controller.uiTraits.artifact_manager_nav_item_enabled">\n        Artifact Manager\n      </li>\n    </ul>\n  </section>\n</div>\n');
$templateCache.put("stats/audit-chart.html",'<h3>{{ controller.errorMsg }}</h3>\n\n<table class="table table-striped table-condensed table-hover table-bordered\n              full-width">\n  <thead>\n    <tr>\n      <th ng-repeat="titleCaseLabel in controller.auditTitleCaseUsedFields\n                     track by $index">\n        {{ titleCaseLabel }}\n      </th>\n    </tr>\n  </thead>\n\n  <tbody>\n    <tr ng-repeat="row in controller.typedAuditRows track by $index">\n      <td ng-repeat="label in controller.auditUsedFields track by $index">\n        <grr-semantic-value value="row.value[label]"></grr-semantic-value>\n      </td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("stats/chart.html",'<h3>{{ controller.errorMsg }}</h3>\n\n<div class="hover" ng-style="{color: controller.hoverColor}">\n  {{controller.hoverText}}\n</div>\n\n<div class="chart" ng-show="typedData.value.representation_type.value != \'AUDIT_CHART\'"></div>\n<grr-audit-chart ng-if="typedData.value.representation_type.value == \'AUDIT_CHART\'"\n                 typed-data="typedData"></grr-audit-chart>\n');$templateCache.put("stats/report-listing.html",'<div>\n  <div class="report-listing-tree">\n  </div>\n</div>\n');
$templateCache.put("stats/report.html",'<div class="padded">\n  <span ng-if="controller.state === \'INITIAL\'">\n    <h3>\n      Select a report to view.\n    </h3>\n  </span>\n\n  <span ng-if="controller.reportDesc">\n    <h3>\n      {{ controller.titleCasedType }}\n      |\n      {{ controller.reportDesc.title }}\n    </h3>\n\n    <h4>\n      {{ controller.reportDesc.summary }}\n    </h4>\n\n    <span ng-if="controller.reportDesc.type === \'CLIENT\'">\n      <grr-form-client-label client-label="controller.clientLabel">\n      </grr-form-client-label>\n    </span>\n\n    <span ng-if="controller.reportDesc.requires_time_range">\n      <grr-form-timerange start-time-secs="controller.startTime"\n                          duration-secs="controller.duration">\n      </grr-form-timerange>\n    </span>\n\n    <div ng-if="controller.reportDesc.type === \'CLIENT\' ||\n                controller.reportDesc.requires_time_range"\n         class="controls">\n        <button class="btn btn-default" ng-click="controller.refreshReport()">\n          Show report\n        </button>\n    </div>\n  </span>\n\n  <span ng-if="controller.state === \'LOADING\'">\n    <h4>\n      Loading...\n    </h4>\n  </span>\n\n  <span ng-if="controller.state === \'LOADED\'">\n    <grr-chart typed-data="controller.typedReportData"></grr-chart>\n  </span>\n</div>\n');
$templateCache.put("stats/server-load-indicator.html",'<img class="grr-icon-small"\n     ng-attr-src="/static/images/{$ controller.imageFile $}"\n     ng-if="controller.imageFile">\n</img>\n');$templateCache.put("stats/server-load.html",'<div class="padded">\n  <div class="well">\n\n    <table class="table table-condensed no-bottom-margin">\n      <thead>\n        <th colspan="2">System Health</th>\n      </thead>\n      <tbody>\n        <tr>\n          <td class="col-md-4">\n            <grr-server-load-indicator\n               status="controller.indicators[\'frontendLoad\']">\n            </grr-server-load-indicator>\n            <span class="indicator-label">Frontends load</span>\n          </td>\n\n          <td class="col-md-4">\n            <grr-server-load-indicator\n               status="controller.indicators[\'workerLoad\']">\n            </grr-server-load-indicator>\n            <span class="indicator-label">Workers load</span>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n\n  </div>\n</div>\n\n<div class="pull-right horizontally-padded">\n  <div class="btn-group">\n    <label class="btn btn-primary" ng-model="controller.duration" uib-btn-radio="1">1h</label>\n    <label class="btn btn-primary" ng-model="controller.duration" uib-btn-radio="6">6h</label>\n    <label class="btn btn-primary" ng-model="controller.duration" uib-btn-radio="12">12h</label>\n    <label class="btn btn-primary" ng-model="controller.duration" uib-btn-radio="24">1d</label>\n    <label class="btn btn-primary" ng-model="controller.duration" uib-btn-radio="72">3d</label>\n  </div>\n</div>\n\n<div class="padded">\n\n  <uib-tabset>\n    <uib-tab heading="Frontend" select="frontendTabShown = true">\n      <div ng-if="frontendTabShown">\n        <p class="lead">Frontend\n          <span ng-if="controller.frontendCount">\n            ({$ controller.frontendCount $} instances)\n          </span>\n        </p>\n        <h4>Frontend QPS</h4>\n        <grr-timeseries-graph start-time="controller.startTime"\n                              end-time="controller.endTime">\n          <grr-server-load-graph-serie component="frontend"\n                                       metric="frontend_request_latency"\n                                       rate="10m"\n                                       distribution-handling="DH_COUNT"\n                                       label="Requests">\n          </grr-server-load-graph-serie>\n        </grr-timeseries-graph>\n\n        <h4>Frontend request latency rate</h4>\n        <grr-timeseries-graph start-time="controller.startTime"\n                              end-time="controller.endTime">\n          <grr-server-load-graph-serie component="frontend"\n                                       metric="frontend_request_latency"\n                                       rate="10m"\n                                       distribution-handling="DH_SUM"\n                                       label="Latency">\n          </grr-server-load-graph-serie>\n        </grr-timeseries-graph>\n\n\n        <h4>Frontend active tasks count</h4>\n        <grr-timeseries-graph start-time="controller.startTime"\n                              end-time="controller.endTime">\n          <grr-server-load-graph-serie component="frontend"\n                                       metric="frontend_active_count"\n                                       rate="10m"\n                                       label="Active tasks">\n          </grr-server-load-graph-serie>\n        </grr-timeseries-graph>\n      </div>\n    </uib-tab>\n\n    <uib-tab heading="Worker" select="workerTabShown = true">\n      <div ng-if="workerTabShown">\n\n        <p class="lead">Worker\n          <span ng-if="controller.workerCount">\n            ({$ controller.workerCount $} instances)\n          </span>\n        </p>\n\n        <h4>Worker successful vs failed flows rate</h4>\n        <grr-timeseries-graph start-time="controller.startTime"\n                              end-time="controller.endTime">\n          <grr-server-load-graph-serie component="worker"\n                                       metric="grr_flow_completed_count"\n                                       rate="10m"\n                                       label="Successes">\n          </grr-server-load-graph-serie>\n          <grr-server-load-graph-serie component="worker"\n                                       metric="grr_flow_errors"\n                                       rate="10m"\n                                       label="Failures">\n          </grr-server-load-graph-serie>\n        </grr-timeseries-graph>\n\n        <h4>Worker threadpool latency vs queuing time rate</h4>\n        <grr-timeseries-graph start-time="controller.startTime"\n                              end-time="controller.endTime">\n          <grr-server-load-graph-serie component="worker"\n                                       metric="grr_threadpool_working_time"\n                                       rate="10m"\n                                       distribution-handling="DH_SUM"\n                                       label="Latency">\n          </grr-server-load-graph-serie>\n          <grr-server-load-graph-serie component="worker"\n                                       metric="grr_threadpool_queueing_time"\n                                       rate="10m"\n                                       distribution-handling="DH_SUM"\n                                       label="Queueing time">\n          </grr-server-load-graph-serie>\n        </grr-timeseries-graph>\n\n        <h4>Worker outstanding tasks vs number of threads</h4>\n        <grr-timeseries-graph start-time="controller.startTime"\n                              end-time="controller.endTime">\n          <grr-server-load-graph-serie component="worker"\n                                       metric="grr_threadpool_outstanding_tasks"\n                                       rate="10m"\n                                       aggregation="AGG_MEAN"\n                                       label="Outstanding tasks">\n          </grr-server-load-graph-serie>\n          <grr-server-load-graph-serie component="worker"\n                                       metric="grr_threadpool_threads"\n                                       rate="10m"\n                                       aggregation="AGG_MEAN"\n                                       label="Threads">\n          </grr-server-load-graph-serie>\n        </grr-timeseries-graph>\n\n        <h4>Client crashes rate</h4>\n        <grr-timeseries-graph start-time="controller.startTime"\n                              end-time="controller.endTime">\n          <grr-server-load-graph-serie component="worker"\n                                       metric="grr_client_crashes"\n                                       rate="10m"\n                                       label="Crashes">\n          </grr-server-load-graph-serie>\n        </grr-timeseries-graph>\n\n      </div>\n    </uib-tab>\n  </uib-tabset>\n\n\n</div>\n');
$templateCache.put("stats/stats-view.html",'<div grr-splitter orientation="vertical" class="rightSplitterContainer">\n\n  <div grr-splitter-pane id="main_leftPane" class="leftPane">\n    <grr-report-listing selection-name="controller.selectionName">\n    </grr-report-listing>\n  </div>\n\n  <div grr-splitter-pane id="main_rightPane" class="rightPane">\n    <grr-report name="controller.selectionName"\n                start-time="controller.startTime"\n                duration="controller.duration"\n                client-label="controller.clientLabel"></grr-report>\n  </div>\n\n</div>\n');
$templateCache.put("stats/timeseries-graph.html",'<ng-transclude></ng-transclude>\n\n<div class="fill-parent-no-margins" ng-if="controller.inProgress">\n  Loading...\n</div>\n<div class="timeseries-graph" ng-if="!controller.inProgress">\n</div>\n');$templateCache.put("user/user-dashboard.html",'<div class="container-fluid">\n  <div class="row horizontally-padded">\n    <div id=\'front\'><h2>Welcome to GRR</h2></div>\n    Query for a system to view in the search box above.\n\n    <p>\n      Type a search term to search for a machine using either a hostname,\n      mac address or username.\n    </p>\n    <br/>\n\n    <div name="RecentlyAccessedClients" class="panel panel-default">\n      <div class="panel-heading">\n        <h4>Recently Accessed <strong>Clients</strong></h4>\n      </div>\n      <div class="panel-body">\n\n        <span ng-if="controller.clientApprovals === undefined">\n          Loading...\n        </span>\n\n        <span ng-if="controller.clientApprovals.length == 0">\n          None.\n        </span>\n\n        <table ng-if="controller.clientApprovals.length > 0"\n               class="table table-condensed table-hover table-bordered full-width">\n          <colgroup>\n            <col style="width: 40px">\n            <col style="width: 40px">\n            <col style="width: 13em">\n            <col style="width: 13em">\n            <col style="width: 20%">\n            <col style="width: 20%">\n            <col style="width: 20%">\n            <col style="width: 20%">\n          </colgroup>\n          <thead>\n            <tr>\n              <th>Online</th>\n              <th>Subject</th>\n              <th>Host</th>\n              <th>Labels</th>\n              <th>Last Checkin</th>\n              <th>Reason</th>\n            </tr>\n          </thead>\n          <tr ng-repeat="approval in ::controller.clientApprovals"\n              ng-class="::{\'half-transparent\': !approval.value.is_valid.value}"\n              ng-click="controller.onClientClicked(approval.value.subject.value.urn.value)">\n            \x3c!-- Online status --\x3e\n            <td>\n              <grr-client-status-icons client="::approval.value.subject" />\n            </td>\n\n            \x3c!-- Client URN --\x3e\n            <td>\n              <span type="subject">\n                {$ ::approval.value.subject.value.urn.value | grrBasename $}\n              </span>\n            </td>\n\n            \x3c!-- Client Host --\x3e\n            <td>\n              <grr-semantic-value\n                 value="::approval.value.subject.value.os_info.value.node" />\n            </td>\n\n            \x3c!-- Client Labels --\x3e\n            <td>\n              <grr-semantic-value\n                 value="::approval.value.subject.value.labels" />\n            </td>\n\n            \x3c!-- Client Latest checkin --\x3e\n            <td>\n              <grr-semantic-value\n                 value="::approval.value.subject.value.last_clock" />\n            </td>\n\n            \x3c!-- Reason --\x3e\n            <td>\n              <grr-semantic-value\n                 value="::approval.value.reason" />\n            </td>\n\n          </tr>\n\n        </table>\n        <p class="small text-right">\n          <em>* semi-transparent rows designate expired approvals</em>\n        </p>\n      </div>\n    </div>\n\n\n    <div name="RecentlyCreatedHunts"  class="panel panel-default">\n      <div class="panel-heading">\n        <h4>Recently Created <strong>Hunts</strong></h4>\n      </div>\n      <div class="panel-body">\n\n        <span ng-if="controller.hunts === undefined">\n          Loading...\n        </span>\n\n        <span ng-if="controller.hunts.length == 0">\n          None.\n        </span>\n\n        <table ng-if="controller.hunts.length > 0"\n               class="table table-condensed table-hover table-bordered full-width">\n          <colgroup>\n            <col style="width: 40px" />\n            <col />\n            <col />\n            <col style="width: 16em" />\n            <col style="width: 16em" />\n            <col />\n            <col width="100%" />\n          </colgroup>\n          <thead>\n            <tr>\n              <th>Status</th>\n              <th>Hunt ID</th>\n              <th>Name</th>\n              <th>Start Time</th>\n              <th>Expires</th>\n              <th>Client Limit</th>\n              <th>Description</th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr ng-repeat="hunt in ::controller.hunts"\n                ng-click="controller.onHuntClicked(hunt)">\n              <td><grr-hunt-status-icon hunt="::hunt" /></td>\n              <td>{$ ::hunt.value.urn.value | grrBasename $}</td>\n              <td>{$ ::hunt.value.name.value $}</td>\n              <td><grr-timestamp value="::hunt.value.created" /></td>\n              <td><grr-timestamp value="::hunt.value.expires" /></td>\n              <td>{$ ::hunt.value.client_limit.value $}</td>\n              <td>{$ ::hunt.value.description.value $}</td>\n            </tr>\n          </tbody>\n        </table>\n\n      </div>\n    </div>\n\n  </div>  \x3c!-- row --\x3e\n</div>  \x3c!-- container --\x3e\n');
$templateCache.put("user/user-label.html",'<p ng-if="!controller.error">\n  User: {$ controller.username $}\n</p>\n<p ng-if="controller.error">\n  User: <span class="text-danger"><em>{$ controller.error $}</em></span>\n</p>\n');$templateCache.put("user/user-notification-button.html",'<button id="notification_button" class="nav-btn btn"\n        ng-class="controller.notificationCount === 0 ? \'btn-info\' : \'btn-danger\'"\n        ng-click="controller.showNotifications()">\n   {$ controller.notificationCount $}\n</button>');
$templateCache.put("user/user-notification-dialog.html",'<div name="NotificationDialog">\n  <div class="modal-header">\n    <button type="button" class="close" ng-click="close()" aria-hidden="true">\u00d7</button>\n    <h3>Notifications</h3>\n  </div>\n  <div class="modal-body">\n    <table class="table table-striped table-condensed table-bordered full-width">\n      <tbody>\n      <tr grr-paged-filtered-table\n          page-size="50"\n          grr-api-items-provider\n          method="POST"\n          url="::controller.notificationUrl">\n        <td>\n          <grr-user-notification-item notification="item" close="close()" />\n        </td>\n      </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class="modal-footer">\n    <button class="btn btn-primary" ng-click="close()">Close</button>\n  </div>\n</div>\n');
$templateCache.put("user/user-notification-item.html",'<div ng-class="{ \'pending\': notification.isPending, \'has-link\': notification.link }">\n  \x3c!-- Either the notification is shown as regular link to some source item --\x3e\n  <a ng-if="!notification.isFileDownload" ng-click="controller.openReference()">\n    <div class="notification-icon">\n      <i ng-if="notification.refType === \'DISCOVERY\'" class="fa fa-binoculars"></i>\n      <i ng-if="notification.refType === \'HUNT\'" class="fa fa-crosshairs"></i>\n      <i ng-if="notification.refType === \'FLOW\'" class="fa fa-code-fork"></i>\n      <i ng-if="notification.refType === \'CRON\'" class="fa fa-history"></i>\n      <i ng-if="notification.refType === \'VFS\'" class="fa fa-hdd-o"></i>\n      <i ng-if="notification.refType === \'CLIENT_APPROVAL\'" class="fa fa-unlock"></i>\n      <i ng-if="notification.refType === \'HUNT_APPROVAL\'" class="fa fa-unlock"></i>\n      <i ng-if="notification.refType === \'CRON_JOB_APPROVAL\'" class="fa fa-unlock"></i>\n    </div>\n\n    <div class="notification-content">\n      <grr-semantic-value value="::notification.value.message"></grr-semantic-value>\n      <grr-timestamp value="::notification.value.timestamp" />\n    </div>\n\n    <div class="no-link-indicator" ng-if="!notification.link">\n      <i class="fa fa-chain-broken"></i>\n      This is a LEGACY notification (therefore it\'s not clickable)\n    </div>\n  </a>\n\n  <div ng-if="notification.isFileDownload">\n    <div class="notification-icon">\n      <i class="fa fa-download"></i>\n    </div>\n    <div class="notification-content">\n      <grr-semantic-value value="::notification.value.message"></grr-semantic-value>\n      <grr-timestamp value="::notification.value.timestamp" />\n    </div>\n    <div class="no-link-indicator">\n      <i class="fa fa-chain-broken"></i>\n      This is a LEGACY file download notification (therefore it\'s not clickable)\n    </div>\n  </div>\n</div>\n');
$templateCache.put("user/user-settings-button-modal.html",'<div class="modal-header">\n  <button type="button" class="close" ng-click="$dismiss()">\n    <span aria-hidden="true">&times;</span>\n    <span class="sr-only">Close</span>\n  </button>\n  <h3 class="modal-title">Settings</h3>\n</div>\n<div class="modal-body">\n  <grr-form-value value="controller.userSettings"></grr-form-value>\n\n  <div class="aler alert-success padded" role="alert"\n       ng-if="controller.done && !controller.error">\n    Settings were successfully updated. Reloading...\n  </div>\n\n  <div class="aler alert-danger padded" role="alert"\n       ng-if="controller.done && controller.error">\n    {$ controller.error $}\n  </div>\n</div>\n<div class="modal-footer">\n  <button class="btn btn-default" ng-click="$dismiss()" name="Close">\n    Close\n  </button>\n  <button class="btn btn-primary" ng-if="!controller.requestSent"\n          ng-click="controller.saveSettings()" name="Proceed">\n    Apply\n  </button>\n</div>\n');
$templateCache.put("user/user-settings-button.html",'<button class="btn btn-default" ng-click="controller.onClick()">\n  <img src="/static/images/modify.png">\n</button>\n');$templateCache.put("client/virtual-file-system/breadcrumbs.html",'<ul class="breadcrumb">\n\n  <li ng-repeat="item in controller.items">\n    <a ng-click="controller.selectPath(item.path)">{$ item.name $}</a>\n  </li>\n\n  <li ng-if="controller.activeItem" class="active">\n      {$ controller.activeItem $}\n  </li>\n\n  <div class="clearfix"></div>\n\n</ul>\n');
$templateCache.put("client/virtual-file-system/encodings-dropdown.html",'<select ng-model="encoding"\n        ng-disabled="!controller.encodings.length"\n        class="form-control">\n\n    \x3c!-- We cannot use ng-options here, since it does not set the selected attribute. --\x3e\n    <option ng-repeat="e in controller.encodings"\n            ng-selected="e.value === encoding"\n            value="{$ e.value $}">\n      {$ e.value $}\n    </option>\n\n    <option ng-if="!controller.encodings.length"\n            ng-selected="!controller.encodings.length"\n            value="">\n      No encodings available.\n    </option>\n\n</select>');
$templateCache.put("client/virtual-file-system/file-details.html",'<div>\n\n  <div ng-if="!controller.fileContext.selectedFilePath" class="padded">\n    Please select a file or a folder to see its details here.\n  </div>\n\n  <div ng-if="controller.fileContext.selectedFilePath" class="padded">\n\n    <grr-breadcrumbs path="controller.fileContext.selectedFilePath"\n                     strip-ending-slash="true">\n    </grr-breadcrumbs>\n\n    <grr-version-dropdown url="controller.fileVersionUrl"\n                          version="controller.fileContext.selectedFileVersion">\n    </grr-version-dropdown>\n\n    <h1>{$ controller.selectedFileName $}</h1>\n\n    <uib-tabset active="controller.currentTab">\n\n      <uib-tab heading="Stats" index="\'stats\'">\n        <div ng-if="controller.currentTab === \'stats\'">\n          <grr-file-stats-view></grr-file-stats-view>\n        </div>\n      </uib-tab>\n\n      <uib-tab heading="Download" index="\'download\'"\n               disable="controller.fileIsDirectory">\n        <div ng-if="controller.currentTab === \'download\'">\n          <div grr-force-refresh refresh-trigger="controller.downloadQueryParams.age">\n            <grr-file-download-view></grr-file-download-view>\n          </div>\n        </div>\n\n      </uib-tab>\n\n      <uib-tab heading="TextView" index="\'textview\'"\n               disable="controller.fileIsDirectory">\n        <div ng-if="controller.currentTab === \'textview\'">\n          <grr-file-text-view></grr-file-text-view>\n        </div>\n      </uib-tab>\n\n      <uib-tab heading="HexView" index="\'hexview\'"\n               disable="controller.fileIsDirectory">\n        <div ng-if="controller.currentTab === \'hexview\'">\n          <grr-file-hex-view></grr-file-hex-view>\n        </div>\n      </uib-tab>\n\n    </uib-tabset>\n\n  </div>\n\n</div>\n');
$templateCache.put("client/virtual-file-system/file-download-view.html",'<div grr-force-refresh refresh-trigger="controller.fileContext.fileVersion">\n\n  <div ng-if="controller.fileDetails.value.hash">\n    <h4>Hash</h4>\n    <span>\n      <grr-semantic-value value="controller.fileDetails.value.hash" />\n    </span>\n  </div>\n\n  <div ng-if="controller.fileDetails.value.last_collected">\n    <h4>Last Collected</h4>\n    <span>\n      <grr-timestamp value="controller.fileDetails.value.last_collected" />\n    </span>\n\n    <h4>Download</h4>\n    <p>\n      <button class="btn btn-default"\n              ng-click="controller.downloadFile()">\n        Download ({$ controller.fileDetails.value.last_collected_size.value $} bytes)\n      </button>\n    </p>\n    <p>\n      Or by using command line export tool:\n    </p>\n    <div class="monospace">\n      <pre>{$ controller.downloadCommand $}</pre>\n    </div>\n    <hr />\n  </div>\n\n  <div>\n    <button class="btn btn-default"\n            ng-click="controller.updateFile()"\n            ng-disabled="controller.updateInProgress">\n      <i class="fa fa-refresh"\n         ng-class="{\'fa-spin\': controller.updateInProgress}"></i>\n      {{ controller.fileDetails.value.last_collected ? \'Re-Collect\' : \'Collect\' }} from the client\n    </button>\n  </div>\n\n</div>\n');
$templateCache.put("client/virtual-file-system/file-hex-view.html",'<div>\n\n  \x3c!-- Show pagination and content if there is file content. --\x3e\n  <div ng-if="controller.hexDataRows.length">\n\n    <div>\n      <uib-pagination total-items="controller.pageCount" items-per-page="1"\n                  max-size="10" rotate="false" boundary-links="true"\n                  ng-model="controller.page" ng-if="controller.pageCount > 1">\n      </uib-pagination>\n    </div>\n\n    \x3c!-- Show the hex view using three separate tables to enable vertical selection. --\x3e\n    <div class="monospace">\n      <table>\n        <tr>\n          <th>Offset</th>\n          <th>000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f</th>\n          <th></th>\n        </tr>\n        <tr>\n          <td>\n            \x3c!-- Offset --\x3e\n            <table class="offset-area">\n              <tr ng-repeat="row in controller.hexDataRows">\n                <td class="offset">\n                  {$ ::row.offset | grrHexNumber $}\n                </td>\n              </tr>\n            </table>\n          </td>\n          <td>\n            \x3c!-- Hex --\x3e\n            <table class="hex-area">\n              <tr ng-repeat="row in controller.hexDataRows">\n                <td>\n                  {$ ::row.data | grrBytesToHex $}\n                </td>\n              </tr>\n            </table>\n          </td>\n          <td>\n            \x3c!-- Content --\x3e\n            <table class="content-area">\n              <tr ng-repeat="row in controller.hexDataRows">\n                <td class="data">\n                  {$ ::row.data $}\n                </td>\n              </tr>\n            </table>\n          </td>\n        </tr>\n      </table>\n    </div>\n\n    <div>\n      <uib-pagination total-items="controller.pageCount" items-per-page="1"\n                  max-size="10" rotate="false" boundary-links="true"\n                  ng-model="controller.page" ng-if="controller.pageCount > 1">\n      </uib-pagination>\n    </div>\n\n  </div>\n\n  \x3c!-- Show a hint if no content exists. --\x3e\n  <div ng-if="!controller.hexDataRows.length" class="no-content">\n    No file content to show.\n  </div>\n\n</div>');
$templateCache.put("client/virtual-file-system/file-stats-view.html",'<div grr-force-refresh refresh-trigger="controller.details">\n  <grr-aff4-object-representation value="controller.details"></grr-aff4-object-representation>\n</div>');$templateCache.put("client/virtual-file-system/file-table.html",'<div>\n\n  <div class="navbar navbar-default toolbar">\n\n    <div class="navbar-inner">\n      <div class="navbar-form pull-left">\n\n        <div class="btn-group" role="group">\n          <button id="refresh-dir" class="btn btn-default"\n                  title="Refresh this directory (sync its listing with the client)"\n                  ng-disabled="controller.lastRefreshOperationId"\n                  ng-click="controller.startVfsRefreshOperation()">\n            <img src="/static/images/stock_refresh.png" class="toolbar_icon" />\n          </button>\n\n          <grr-recursive-list-button client-id="controller.fileContext.clientId"\n                                     file-path="controller.fileContext.selectedFilePath"\n                                     class="space-right">\n          </grr-recursive-list-button>\n        </div>\n\n        <grr-vfs-files-archive-button client-id="controller.fileContext.clientId"\n                                      file-path="controller.fileContext.selectedFilePath"\n                                      class="space-right">\n        </grr-vfs-files-archive-button>\n\n        <div class="input-group large">\n          <input type="text" class="form-control file-search" placeholder="Filter Items"\n                 ng-model="controller.filterEditedValue" grr-bind-key="controller.updateFilter()">\n          <span class="input-group-btn">\n            <button class="btn btn-default" type="button" ng-click="controller.updateFilter()">\n              <i class="fa fa-filter"></i>\n            </button>\n          </span>\n        </div>\n\n      </div>\n\n      <div class="navbar-form pull-right">\n\n        <grr-r-we-owned-button class="space-right"></grr-r-we-owned-button>\n\n        <div class="btn-group" data-toggle="buttons">\n          <label class="btn btn-default"\n                 ng-class="{\'active\': viewMode == \'list\'}"\n                 ng-click="controller.setViewMode(\'list\')">\n            <input type="radio" name="show-client-details" checked>\n            <i class="fa fa-list"></i> File list\n          </label>\n          <label class="btn btn-default"\n                 ng-class="{\'active\': viewMode == \'timeline\'}"\n                 ng-click="controller.setViewMode(\'timeline\')">\n            <input type="radio" name="show-client-details">\n            <i class="fa fa-history"></i> Timeline\n          </label>\n          <button name="timelineDropdown" class="btn btn-default dropdown-toggle"\n                  data-toggle="dropdown">\n            <span class="caret"></span>\n          </button>\n          <ul class="dropdown-menu">\n            <li>\n              <a name="downloadTimeline"\n                 ng-click="controller.downloadTimeline(); $event.preventDefault()"\n                 href="#">\n                Download timeline as CSV\n              </a>\n            </li>\n          </ul>\n        </div>\n      </div>\n\n    </div>\n\n  </div>\n\n  <div class="fill-parent-with-toolbar">\n    <grr-breadcrumbs path="controller.fileContext.selectedFilePath"></grr-breadcrumbs>\n\n    <div grr-force-refresh refresh-trigger="controller.fileListUrl"\n         ng-if="viewMode == \'list\'">\n      <table class="table table-striped table-condensed table-hover table-bordered full-width file-list">\n\n        <thead>\n          <tr>\n            <th>Icon</th>\n            <th>Name</th>\n            <th>st_size</th>\n            <th>st_mtime</th>\n            <th>st_ctime</th>\n            <th>GRR Snapshot</th>\n          </tr>\n        </thead>\n\n        \x3c!-- We need this ng-if to make sure fileListUrl is stable when ApiItemsProvider is called. --\x3e\n        <tbody ng-if="controller.fileListUrl">\n          <tr grr-infinite-table page-size="1000"\n              filter-value="controller.filterValue"\n              trigger-update="controller.triggerUpdate"\n              grr-api-items-provider\n              url="controller.fileListUrl"\n              ng-click="controller.selectFile(item)"\n              ng-dblclick="controller.selectFolder(item)"\n              ng-class="{\'row-selected\': item.value.path.value === controller.fileContext.selectedFilePath}">\n            <td>\n              <img class="grr-icon directory" src="/static/images/directory.png"\n                   alt="Directory" title="Directory" ng-if="item.value.is_directory.value">\n              <img class="grr-icon file" src="/static/images/file.png"\n                   alt="File Like Object" title="File Like Object" ng-if="!item.value.is_directory.value">\n            </td>\n            <td><grr-semantic-value value="::item.value.name" /></td>\n            <td>\n              <grr-semantic-value class="pull-left"\n                                  value="::item.value.stat.value.st_size"></grr-semantic-value>\n              <span ng-if="::item.value.last_collected_size !== undefined" class="pull-right">\n                <i class="fa fa-download"\n                   title="Collected ({$ ::item.value.last_collected_size.value $} bytes)"\n                   aria-hidden="true">\n                </i>\n              </span>\n              <div class="clearfix"></div>\n            </td>\n            <td><grr-semantic-value value="::item.value.stat.value.st_mtime" /></td>\n            <td><grr-semantic-value value="::item.value.stat.value.st_ctime" /></td>\n            <td><grr-timestamp value="::item.value.age.value" /></td>\n          </tr>\n        </tbody>\n\n      </table>\n\n    </div>\n\n    <grr-file-timeline ng-if="viewMode == \'timeline\'"\n                         filter-value="controller.filterValue">\n    </grr-file-timeline>\n\n  </div>\n</div>\n');
$templateCache.put("client/virtual-file-system/file-text-view.html",'<div>\n\n  \x3c!-- Show pagination and content if there is file content. --\x3e\n  <div ng-if="controller.fileContent">\n\n    <div>\n      <uib-pagination total-items="controller.pageCount" items-per-page="1"\n                  max-size="1" rotate="false" boundary-links="true"\n                  ng-model="controller.page" ng-if="controller.pageCount > 1">\n      </uib-pagination>\n\n      <grr-encodings-dropdown encoding="controller.encoding">\n      </grr-encodings-dropdown>\n\n      <div style="clear:both"></div>\n    </div>\n\n    <div class="monospace">\n      <pre>{$ controller.fileContent $}</pre>\n    </div>\n\n    <div>\n      <uib-pagination total-items="controller.pageCount" items-per-page="1"\n                  max-size="1" rotate="false" boundary-links="true"\n                  ng-model="controller.page" ng-if="controller.pageCount > 1">\n      </uib-pagination>\n    </div>\n\n  </div>\n\n  \x3c!-- Show a hint if no content exists. --\x3e\n  <div ng-if="!controller.fileContent" class="no-content">\n    No file content to show.\n  </div>\n\n</div>');
$templateCache.put("client/virtual-file-system/file-timeline.html",'<table class="table table-striped table-condensed table-hover table-bordered full-width file-list">\n\n  <colgroup>\n    <col style="width: 14em">\n    <col>\n    <col style="width: 225px">\n  </colgroup>\n\n  <thead>\n    <tr>\n      <th>Timestamp</th>\n      <th>File</th>\n      <th>Message</th>\n    </tr>\n  </thead>\n\n  <tbody ng-if="controller.inProgress">\n    <tr class="timeline-refresh-indicator">\n      <td colspan="3">\n        <i class="fa fa-spinner fa-spin fa-3x margin-bottom"></i>\n        <div>Creating timeline...</div>\n      </td>\n    </tr>\n  </tbody>\n\n  \x3c!-- We need this ng-if to make sure timelineItems is stable when ApiMemoryItemsProvider is called. --\x3e\n  <tbody ng-if="controller.timelineItems && !controller.inProgress">\n    <tr grr-infinite-table\n        filter-value=\'filterValue\'\n        trigger-update="controller.triggerUpdate"\n        grr-memory-items-provider\n        items="controller.timelineItems"\n        ng-class="{\'row-selected\': item === controller.selectedItem}"\n        ng-click="controller.selectFile(item)">\n      <td><grr-semantic-value value="::item.value.timestamp" /></td>\n      <td><grr-semantic-value value="::item.value.file_path" /></td>\n      <td>\n        <div ng-if="item.value.action.value === \'MODIFICATION\'"><pre class=\'inline\'>M--</pre> File modified.</div>\n        <div ng-if="item.value.action.value === \'ACCESS\'"><pre class=\'inline\'>-A-</pre> File access.</div>\n        <div ng-if="item.value.action.value === \'METADATA_CHANGED\'"><pre class=\'inline\'>--C</pre> File metadata changed.</div>\n      </td>\n    </tr>\n  </tbody>\n\n</table>\n');
$templateCache.put("client/virtual-file-system/file-tree.html",'<div>\n  <div id="file-tree">\n  </div>\n</div>');$templateCache.put("client/virtual-file-system/file-view.html",'<grr-check-client-access client-id="controller.clientId">\n\n  <grr-file-context client-id="controller.clientId"\n                    selected-file-path="controller.selectedFilePath"\n                    selected-file-version="controller.fileVersion">\n\n    <div grr-splitter orientation="vertical">\n      <div grr-splitter-pane id="main_leftPane" class="leftPane">\n        <grr-file-tree />\n      </div>\n\n      <div grr-splitter-pane id="main_rightPane" class="rightPane">\n        <div grr-splitter orientation="horizontal" class="rightSplitterContainer">\n\n          <div grr-splitter-pane id="content_rightPane" class="rightTopPane">\n            <grr-file-table view-mode="controller.viewMode" />\n          </div>\n\n          <div grr-splitter-pane id="main_bottomPane" class="rightBottomPane">\n            <grr-file-details current-tab="controller.tab" />\n          </div>\n\n        </div>\n      </div>\n    </div>\n\n  </grr-file-context>\n\n</grr-check-client-access>\n');
$templateCache.put("client/virtual-file-system/r-we-owned-button-modal.html",'<div class="modal-header">\n  <button type="button" class="close" ng-click="$dismiss()">\n    <span aria-hidden="true">&times;</span>\n    <span class="sr-only">Close</span>\n  </button>\n  <h3 class="modal-title">Are we owned?</h3>\n</div>\n<div class="modal-body">\n  <p class="text-info">\n    {$ phrase $}\n  </p>\n</div>\n<div class="modal-footer">\n  <button ng-if="!controller.done"\n          class="btn btn-default" ng-click="$dismiss()" name="Cancel">\n    Cancel\n  </button>\n</div>\n');
$templateCache.put("client/virtual-file-system/r-we-owned-button.html",'<button class="btn btn-default"\n        title="Is this machine pwned?"\n        style="position: relative"\n        ng-click="controller.onClick()">\n  <img src="/static/images/stock_dialog_question.png" class="toolbar_icon">\n</button>\n');$templateCache.put("client/virtual-file-system/recursive-list-button-modal.html",'<div class="modal-header">\n  <button type="button" class="close" ng-click="$dismiss()">\n    <span aria-hidden="true">&times;</span>\n    <span class="sr-only">Close</span>\n  </button>\n  <h3 class="modal-title">Recursive Directory Refresh</h3>\n</div>\n<div class="modal-body">\n  <grr-form-proto value="controller.refreshOperation"\n                  visible-fields="[\'max_depth\']">\n  </grr-form-proto>\n\n  <div class="aler alert-success padded" role="alert"\n       ng-if="controller.done && !controller.error">\n    Refresh started successfully!\n  </div>\n\n  <div class="aler alert-danger padded" role="alert"\n       ng-if="controller.done && controller.error">\n    {$ controller.error $}\n  </div>\n</div>\n<div class="modal-footer">\n  <button ng-if="!controller.done"\n          class="btn btn-default" ng-click="$dismiss()" name="Cancel">\n    Cancel\n  </button>\n  <button ng-if="controller.done"\n          class="btn btn-default" ng-click="$dismiss()" name="Close">\n    Close\n  </button>\n  <button class="btn btn-primary" ng-if="!controller.requestSent"\n          ng-click="controller.createRefreshOperation()"\n          name="Proceed">\n    Refresh\n  </button>\n</div>\n');
$templateCache.put("client/virtual-file-system/recursive-list-button.html",'<button class="btn btn-default"\n        title="Recursively refresh this directory (sync its listing with the client)"\n        style="position: relative"\n        name="RecursiveRefresh"\n        ng-click="controller.onClick()"\n        ng-disabled="controller.lastOperationId">\n  <img src="/static/images/stock_refresh.png" class="toolbar_icon">\n  <span style="position: absolute; left: 23px; top: 5px; font-weight: bold;\n               font-size: 18px; -webkit-text-stroke: 1px #000; color: #fff">R</span>\n</button>\n');
$templateCache.put("client/virtual-file-system/vfs-files-archive-button.html",'<div class="btn-group large">\n  <button class="btn btn-default" data-toggle="dropdown">\n    <i class="fa fa-file-o"></i>\n    <i class="fa fa-arrow-circle-down annotation"></i>\n  </button>\n  <button class="btn btn-default dropdown-toggle" data-toggle="dropdown">\n    <span class="caret"></span>\n  </button>\n  <ul class="dropdown-menu">\n    <li ng-class="{\'disabled\': controller.downloadCurrentFolderDisabled}">\n      <a name="downloadCurrentFolder"\n         ng-click="controller.downloadCurrentFolder($event)"\n         href="#">\n        Download files collected in <strong>this folder and below</strong>\n      </a>\n    </li>\n    <li ng-class="{\'disabled\': controller.downloadEverythingDisabled}">\n      <a name="downloadEverything"\n         ng-click="controller.downloadEverything($event)"\n         href="#">\n        Download <strong>all</strong> files collected from this client\n      </a>\n    </li>\n  </ul>\n</div>\n');
$templateCache.put("cron/new-cron-job-wizard/configure-schedule-page.html","<div class=\"padded\">\n  <grr-form-proto value=\"cronJob\"\n                  visible-fields=\"['description', 'periodicity', 'lifetime', 'allow_overruns']\">\n  </grr-form-proto>\n</div>\n");$templateCache.put("cron/new-cron-job-wizard/form.html",'<grr-wizard-form title="Schedule Cron Hunt" on-resolve="onResolve()" on-reject="onReject()">\n\n  \x3c!-- Configure schedule --\x3e\n  <grr-wizard-form-page\n      title="Cron Job properties"\n      is-valid="controller.huntRunnerArgs.value.client_rule_set">\n\n    <grr-configure-schedule-page cron-job="cronJob">\n    </grr-configure-schedule-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Configure flow --\x3e\n  <grr-wizard-form-page title="What to run?"\n                        is-valid="controller.genericHuntArgs.value.flow_runner_args.value.flow_name.value">\n\n    <grr-configure-flow-page flow-name="controller.genericHuntArgs.value.flow_runner_args.value.flow_name.value"\n                             flow-arguments="controller.genericHuntArgs.value.flow_args"\n                             hunt-runner-args="controller.huntRunnerArgs">\n    </grr-configure-flow-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Configure output plugins --\x3e\n  <grr-wizard-form-page title="Define Output Processing">\n\n    <grr-configure-output-plugins-page output-plugins="controller.huntRunnerArgs.value.output_plugins">\n    </grr-configure-output-plugins-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Configure rules --\x3e\n  <grr-wizard-form-page title="Where to run?">\n\n    <grr-configure-rules-page\n        client-rule-set="controller.huntRunnerArgs.value.client_rule_set">\n    </grr-configure-rules-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Review --\x3e\n  <grr-wizard-form-page title="Review"\n                        next-button-label="Schedule Hunt">\n\n    <grr-new-cron-job-review-page cron-job="cronJob">\n    </grr-new-cron-job-review-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Submit the hunt and show the status --\x3e\n  <grr-wizard-form-page title="Result"\n                        is-valid="controller.serverResponse != null"\n                        on-show="controller.sendRequest()"\n                        next-button-label="Done"\n                        no-back-button="true">\n\n    <grr-new-cron-job-status-page response="controller.serverResponse">\n    </grr-new-cron-job-status-page>\n\n  </grr-wizard-form-page>\n\n</grr-wizard-form>\n');
$templateCache.put("cron/new-cron-job-wizard/review-page.html",'<div class="padded" grr-force-refresh refresh-trigger="cronJob">\n\n  <dl class="dl-horizontal">\n    <dt>Scheduling</dt>\n    <dd>\n      <grr-semantic-proto value="cronJob"\n                          visible-fields="[\'description\', \'periodicity\', \'lifetime\', \'allow_overruns\']">\n      </grr-semantic-proto>\n    </dd>\n  </dl>\n\n  <dl class="dl-horizontal">\n    <dt>Hunt Arguments</dt>\n    <dd>\n      <grr-semantic-value value="cronJob.value.flow_args.value.hunt_args">\n      </grr-semantic-value>\n    </dd>\n  </dl>\n\n  <dl class="dl-horizontal">\n    <dt>Hunt Runner Arguments</dt>\n    <dd>\n      <grr-semantic-value value="cronJob.value.flow_args.value.hunt_runner_args">\n      </grr-semantic-value>\n    </dd>\n  </dl>\n\n</div>\n');
$templateCache.put("cron/new-cron-job-wizard/status-page.html",'<div class="padded">\n\n  <div ng-if="!response">\n    <uib-progressbar class="progress-striped active" max="100" value="50">\n      Creating cron job...\n    </uib-progressbar>\n  </div>\n\n  <div ng-if="response && response.error" class="alert alert-error">\n    <p><em>Can\'t create cron job:</em></p>\n    <p class="preserve-linebreaks">{$ response.data $}</p>\n  </div>\n\n  <div ng-if="response && !response.error" class="panel panel-default">\n    <div class="panel-body">\n      <p>\n        Created Cron Job:\n        <grr-semantic-value value="response.data"></grr-semantic-value>\n      </p>\n    </div>\n  </div>\n\n</div>\n');
$templateCache.put("hunt/new-hunt-wizard/configure-flow-page.html",'<div grr-splitter orientation="vertical" class="rightSplitterContainer" closeable-to="0">\n\n  <div grr-splitter-pane class="leftPane">\n    <grr-flow-descriptors-tree selected-descriptor="controller.flowDescriptor" />\n  </div>\n\n  <div grr-splitter-pane class="rightPane">\n\n    <div class="padded">\n      <div ng-if="flowArguments != null">\n        <legend>{$ flowName $}</legend>\n\n        <grr-form-value value="flowArguments">\n        </grr-form-value>\n\n        <br>\n        <legend>Description</legend>\n        <grr-flow-info descriptor="controller.flowDescriptor" />\n      </div>\n\n      <span ng-if="flowArguments == null">\n        Please select a flow from the tree on the left.\n      </span>\n    </div>\n\n  </div>\n</div>\n');
$templateCache.put("hunt/new-hunt-wizard/configure-hunt-page.html",'<div class="padded">\n  <grr-form-proto value="huntRunnerArgs"\n                  hidden-fields="[\'hunt_name\', \'client_rule_set\']">\n  </grr-form-proto>\n</div>\n');$templateCache.put("hunt/new-hunt-wizard/configure-output-plugins-page.html",'<div class="padded">\n  <grr-form-proto-repeated-field\n     descriptor="controller.outputPluginDescriptor"\n     field="controller.outputPluginsField"\n     value="outputPlugins">\n  </grr-form-proto-repeated-field>\n</div>\n');
$templateCache.put("hunt/new-hunt-wizard/configure-rules-page.html",'<div class="padded">\n  <grr-form-value value="clientRuleSet"></grr-form-value>\n\n  <h3 class="text-center" ng-if="!clientRuleSet.value.rules ||\n                              clientRuleSet.value.rules.length == 0">\n    No rules specified!\n    <span ng-if="!clientRuleSet.value.match_mode.value ||\n                 clientRuleSet.value.match_mode.value == \'MATCH_ALL\'">\n      The hunt will run on all clients.\n    </span>\n    <span ng-if="clientRuleSet.value.match_mode.value &&\n                 clientRuleSet.value.match_mode.value == \'MATCH_ANY\'">\n      The hunt won\'t run on any client.\n    </span>\n  </h3>\n</div>\n');
$templateCache.put("hunt/new-hunt-wizard/copy-form.html",'<div class="padded" ng-if="controller.createHuntArgs === undefined">\n  Loading...\n</div>\n\n<grr-new-hunt-wizard-form\n   ng-if="controller.createHuntArgs !== undefined"\n\n   on-resolve="onResolve()"\n   on-reject="onReject()"\n   create-hunt-args="controller.createHuntArgs">\n</grr-new-hunt-wizard-form>\n');$templateCache.put("hunt/new-hunt-wizard/create-hunt-from-flow-form.html",'<div class="padded" ng-if="controller.createHuntArgs === undefined">\n  Loading...\n</div>\n\n<grr-new-hunt-wizard-form\n   ng-if="controller.createHuntArgs !== undefined"\n\n   on-resolve="onResolve({huntUrn: huntUrn})"\n   on-reject="onReject()"\n   create-hunt-args="controller.createHuntArgs">\n\n</grr-new-hunt-wizard-form>\n');
$templateCache.put("hunt/new-hunt-wizard/form.html",'<grr-wizard-form title="New Hunt" on-resolve="controller.resolve()" on-reject="onReject()">\n\n  \x3c!-- Configure flow --\x3e\n  <grr-wizard-form-page title="What to run?"\n                        is-valid="createHuntArgs.value.flow_name.value &&\n                                  !controller.configureFlowPageHasErrors">\n\n    <grr-configure-flow-page flow-name="createHuntArgs.value.flow_name.value"\n                             flow-arguments="createHuntArgs.value.flow_args"\n                             has-errors="controller.configureFlowPageHasErrors">\n    </grr-configure-flow-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Configure hunt --\x3e\n  <grr-wizard-form-page title="Hunt parameters"\n                        help-link="/help/investigating-with-grr/hunts/limits.html">\n    <grr-configure-hunt-page hunt-runner-args="createHuntArgs.value.hunt_runner_args">\n    </grr-configure-hunt-page>\n  </grr-wizard-form-page>\n\n  \x3c!-- Configure output plugins --\x3e\n  <grr-wizard-form-page title="How to process results?">\n\n    <grr-configure-output-plugins-page\n      output-plugins="createHuntArgs.value.hunt_runner_args.value.output_plugins">\n    </grr-configure-output-plugins-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Configure rules --\x3e\n  <grr-wizard-form-page title="Where to run?"\n                        help-link="/help/investigating-with-grr/hunts/rules.html">\n\n    <grr-configure-rules-page\n        client-rule-set="createHuntArgs.value.hunt_runner_args.value.client_rule_set">\n    </grr-configure-rules-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Review --\x3e\n  <grr-wizard-form-page title="Review"\n                        next-button-label="Create Hunt">\n\n    <grr-new-hunt-review-page create-hunt-args="createHuntArgs">\n    </grr-new-hunt-review-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Submit the hunt and show the status --\x3e\n  <grr-wizard-form-page title="Result"\n                        is-valid="controller.serverResponse != null"\n                        on-show="controller.sendRequest()"\n                        next-button-label="Done"\n                        no-back-button="true">\n\n    <grr-new-hunt-status-page response="controller.serverResponse">\n    </grr-new-hunt-status-page>\n\n  </grr-wizard-form-page>\n\n</grr-wizard-form>\n');
$templateCache.put("hunt/new-hunt-wizard/review-page.html",'<div class="padded" grr-force-refresh refresh-trigger="createHuntArgs">\n  <grr-semantic-value value="createHuntArgs"></grr-semantic-value>\n</div>\n');$templateCache.put("hunt/new-hunt-wizard/status-page.html",'<div class="padded">\n\n  <div ng-if="!response">\n    <uib-progressbar class="progress-striped active" max="100" value="50">\n      Creating hunt...\n    </uib-progressbar>\n  </div>\n\n  <div ng-if="response && response.error" class="alert alert-error">\n    <p><em>Can\'t create hunt:</em></p>\n    <p class="preserve-linebreaks">{$ response.data $}</p>\n  </div>\n\n  <div ng-if="response && !response.error" class="panel panel-default">\n    <div class="panel-body">\n      <p>\n        Created Hunt:\n        <grr-semantic-value value="response.data.value.urn"></grr-semantic-value>\n      </p>\n      <p>\n        Hunt arguments:<br/>\n        <grr-semantic-value value="response.data.value.hunt_args"></grr-semantic-value>\n      </p>\n      <p>\n        Runner arguments:<br/>\n        <grr-semantic-value value="response.data.value.hunt_runner_args"></grr-semantic-value>\n      </p>\n    </div>\n  </div>\n\n</div>\n');
$templateCache.put("semantic/pseudo/semantic-fetch-more-link.html",'<a ng-if="!continuationShown" ng-click="onClick($event)">\n  More items available...\n</a>\n<grr-semantic-value ng-if="::continuationShown" value="::value.value" />\n');$templateCache.put("semantic/rekall/log.html","[{$ ::value['level'] $}\n(<grr-timestamp-seconds value=\"::value['time']\"></grr-timestamp-seconds>)\n{$ ::value['name'] $}]\n{$ ::value['msg'] $}\n");$templateCache.put("semantic/rekall/metadata.html",'<b>Metadata:</b>\n<grr-rekall-value value="::value"></grr-rekall-value>\n');
$templateCache.put("semantic/rekall/registered-unix-time-stamp.html",'<grr-timestamp-seconds value="::value.epoch"></grr-timestamp-seconds>\n');$templateCache.put("semantic/rekall/rekall-default-value.html",'<table class="proto_table">\n  <tr ng-repeat="(k, v) in ::value track by $index"\n      ng-if="::k !== \'mro\' && k !== \'id\'">\n    <td class="proto_key" ng-if="::k !== \'data\'">\n      <i>{$ ::k $}</i>\n    </td>\n    <td class="proto_value">\n      <grr-rekall-value value="::v"></grr-rekall-value>\n    </td>\n  </tr>\n</table>\n');
$templateCache.put("semantic/rekall/rekall-json.html",'{$ ::controller.error $}\n\n<div ng-repeat="item in controller.state" ng-switch="::item[0]">\n  <span ng-switch-when="L">\n    <grr-rekall-log value="::item[1]"></grr-rekall-log>\n  </span>\n  <span ng-switch-when="m">\n    <grr-rekall-metadata value="::item[1]"></grr-rekall-metadata>\n  </span>\n  <span ng-switch-when="t">\n    <grr-rekall-table value="::item[1]"></grr-rekall-table>\n  </span>\n  <span ng-switch-when="x">EOM</span>\n  <span ng-switch-default>{$ ::item $}</span>\n</div>\n\n<a ng-if="controller.renderIncomplete" ng-click="controller.onClick($event)">\n  Render all the data... (May take a while)\n</a>\n');
$templateCache.put("semantic/rekall/table.html",'<b>Table:</b>\n\n<table class="proto_table" ng-if="::value.header">\n  <thead>\n    <tr>\n      <td class="proto_value" ng-repeat="column in ::value.header">\n        <b>{$ column.name $}</b>\n      </td>\n    </tr>\n  </thead>\n  <tbody>\n    <tr ng-repeat="row in ::value.rows">\n      <td class="proto_value" ng-repeat="column in ::value.header">\n        <grr-rekall-value value="row[column.cname||column.name]"></grr-rekall-value>\n      </td>\n    </tr>\n  </tbody>\n</table>\n\n\x3c!-- Still render the data even if it\'s incomplete --\x3e\n<table class="proto_table" ng-if="::!value.header">\n  <tbody>\n    <tr ng-repeat="row in ::value.rows">\n      <td class="proto_value" ng-repeat="(k, v) in ::row track by $index">\n        <i>{$ ::k $}</i>:\n        <grr-rekall-value value="::v"></grr-rekall-value>\n      </td>\n    </tr>\n  </tbody>\n</table>\n')}]);goog.provide("grrUi.user.userDashboardDirective.UserDashboardController");goog.provide("grrUi.user.userDashboardDirective.UserDashboardDirective");
grrUi.user.userDashboardDirective.UserDashboardController=function($scope,grrApiService,grrRoutingService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.clientApprovals;this.grrApiService_.get("/users/me/approvals/client",{count:7}).then(this.onApprovals_.bind(this));this.grrApiService_.get("/hunts",{count:5,active_within:"31d",created_by:"me"}).then(this.onHunts_.bind(this))};var UserDashboardController=grrUi.user.userDashboardDirective.UserDashboardController;
UserDashboardController.prototype.onApprovals_=function(response){this.clientApprovals=response["data"]["items"]};UserDashboardController.prototype.onHunts_=function(response){this.hunts=response["data"]["items"]};UserDashboardController.prototype.onClientClicked=function(clientUrn){var clientId=clientUrn.split("/")[1];this.grrRoutingService_.go("client",{clientId:clientId})};
UserDashboardController.prototype.onHuntClicked=function(hunt){var huntId=hunt["value"]["urn"]["value"].split("/")[2];this.grrRoutingService_.go("hunts",{huntId:huntId})};grrUi.user.userDashboardDirective.UserDashboardDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/user/user-dashboard.html",controller:UserDashboardController,controllerAs:"controller"}};grrUi.user.userDashboardDirective.UserDashboardDirective.directive_name="grrUserDashboard";goog.provide("grrUi.user.userNotificationButtonDirective.UserNotificationButtonController");goog.provide("grrUi.user.userNotificationButtonDirective.UserNotificationButtonDirective");
goog.scope(function(){var SECOND=1E3;var FETCH_INTERVAL=10*SECOND;grrUi.user.userNotificationButtonDirective.UserNotificationButtonController=function($scope,$interval,$uibModal,grrApiService){this.scope_=$scope;this.interval_=$interval;this.uibModal_=$uibModal;this.grrApiService_=grrApiService;this.notificationCount=0;this.fetchNotificationCount_();this.interval_(this.fetchNotificationCount_.bind(this),FETCH_INTERVAL)};var UserNotificationButtonController=grrUi.user.userNotificationButtonDirective.UserNotificationButtonController;
UserNotificationButtonController.prototype.fetchNotificationCount_=function(){this.grrApiService_.get("users/me/notifications/pending/count").then(function(response){this.notificationCount=response.data["count"]}.bind(this))};UserNotificationButtonController.prototype.showNotifications=function(){var modalScope=this.scope_.$new();var modalInstance=this.uibModal_.open({template:'<grr-user-notification-dialog close="$close()" />',scope:modalScope,size:"lg"});modalInstance.result.finally(function(){this.notificationCount=
0}.bind(this))};grrUi.user.userNotificationButtonDirective.UserNotificationButtonDirective=function(){return{scope:true,restrict:"E",templateUrl:"/static/angular-components/user/user-notification-button.html",controller:UserNotificationButtonController,controllerAs:"controller"}};var UserNotificationButtonDirective=grrUi.user.userNotificationButtonDirective.UserNotificationButtonDirective;UserNotificationButtonDirective.directive_name="grrUserNotificationButton";UserNotificationButtonDirective.fetch_interval=
FETCH_INTERVAL});goog.provide("grrUi.user.userNotificationItemDirective.UserNotificationItemController");goog.provide("grrUi.user.userNotificationItemDirective.UserNotificationItemDirective");goog.provide("grrUi.user.userNotificationItemDirective.annotateApiNotification");goog.provide("grrUi.user.userNotificationItemDirective.openReference");goog.require("grrUi.client.virtualFileSystem.fileViewDirective.getFileId");goog.require("grrUi.core.apiService.encodeUrlPath");goog.require("grrUi.core.apiService.stripTypeInfo");
goog.require("grrUi.core.utils.getLastPathComponent");goog.require("grrUi.core.utils.stripAff4Prefix");
goog.scope(function(){var encodeUrlPath=grrUi.core.apiService.encodeUrlPath;var getLastPathComponent=grrUi.core.utils.getLastPathComponent;var stripTypeInfo=grrUi.core.apiService.stripTypeInfo;var getFileId=grrUi.client.virtualFileSystem.fileViewDirective.getFileId;var stripAff4Prefix=grrUi.core.utils.stripAff4Prefix;grrUi.user.userNotificationItemDirective.openReference=function(notification,angularWindow){if(!notification["isFileDownload"]&&notification["link"]){angularWindow.location.href="#/"+
notification["link"];return true}else return false};var openReference=grrUi.user.userNotificationItemDirective.openReference;grrUi.user.userNotificationItemDirective.annotateApiNotification=function(notification){notification["isPending"]=notification["value"]["is_pending"]["value"];if(angular.isDefined(notification["value"]["reference"])){notification["link"]=getLink_(notification);notification["refType"]=notification["value"]["reference"]["value"]["type"]["value"]}};var annotateApiNotification=
grrUi.user.userNotificationItemDirective.annotateApiNotification;var getLink_=function(notification){var strippedNotification=stripTypeInfo(notification);if(!strippedNotification["reference"]||!strippedNotification["reference"]["type"])return null;var reference=strippedNotification["reference"];var referenceType=reference["type"];var referenceDetails=reference[referenceType.toLowerCase()];var urlParameters={};if(referenceType==="DISCOVERY")return["clients",stripAff4Prefix(referenceDetails["client_id"])].join("/");
else if(referenceType==="HUNT"){var huntId=getLastPathComponent(referenceDetails["hunt_urn"]);return["hunts",huntId].join("/")}else if(referenceType==="CRON"){var cronJobName=getLastPathComponent(referenceDetails["cron_job_urn"]);return["crons",cronJobName].join("/")}else if(referenceType==="VFS")return["clients",stripAff4Prefix(referenceDetails["client_id"]),"vfs",encodeUrlPath(stripAff4Prefix(referenceDetails["vfs_path"]))].join("/");else if(referenceType=="FLOW"){var flowId=referenceDetails["flow_id"];
return["clients",stripAff4Prefix(referenceDetails["client_id"]),"flows",flowId].join("/")}else if(referenceType==="CLIENT_APPROVAL"){var clientId=stripAff4Prefix(referenceDetails["client_id"]);return["users",referenceDetails["username"],"approvals","client",clientId,referenceDetails["approval_id"]].join("/")}else if(referenceType==="HUNT_APPROVAL")return["users",referenceDetails["username"],"approvals","hunt",referenceDetails["hunt_id"],referenceDetails["approval_id"]].join("/");else if(referenceType===
"CRON_JOB_APPROVAL")return["users",referenceDetails["username"],"approvals","cron-job",referenceDetails["cron_job_id"],referenceDetails["approval_id"]].join("/");return null};var getFileIdFromFullPath_=function(vfsPath){var components=vfsPath.split("/").slice(2,-1);return getFileId(components.join("/"))};grrUi.user.userNotificationItemDirective.UserNotificationItemController=function($scope,$window){this.scope_=$scope;this.window_=$window;this.scope_.$watch("notification",this.onNotificationChanged_.bind(this))};
var UserNotificationItemController=grrUi.user.userNotificationItemDirective.UserNotificationItemController;UserNotificationItemController.prototype.onNotificationChanged_=function(notification){annotateApiNotification(notification)};UserNotificationItemController.prototype.openReference=function(){if(openReference(this.scope_["notification"],this.window_))this.scope_["close"]()};grrUi.user.userNotificationItemDirective.UserNotificationItemDirective=function(){return{scope:{notification:"=",close:"&"},
restrict:"E",templateUrl:"/static/angular-components/user/user-notification-item.html",controller:UserNotificationItemController,controllerAs:"controller"}};grrUi.user.userNotificationItemDirective.UserNotificationItemDirective.directive_name="grrUserNotificationItem"});goog.provide("grrUi.user.userDesktopNotificationsDirective.UserDesktopNotificationsController");goog.provide("grrUi.user.userDesktopNotificationsDirective.UserDesktopNotificationsDirective");goog.require("grrUi.user.userNotificationButtonDirective.UserNotificationButtonDirective");goog.require("grrUi.user.userNotificationItemDirective.annotateApiNotification");goog.require("grrUi.user.userNotificationItemDirective.openReference");
goog.scope(function(){document.addEventListener("DOMContentLoaded",function(){if(Notification&&Notification.permission!=="granted")Notification.requestPermission()});var FETCH_INTERVAL=grrUi.user.userNotificationButtonDirective.UserNotificationButtonDirective.fetch_interval;var MAX_DISPLAYED_NOTIFICATIONS=2;grrUi.user.userDesktopNotificationsDirective.UserDesktopNotificationsController=function($scope,$interval,$window,grrApiService,grrTimeService){if(!Notification)return;this.scope_=$scope;this.interval_=
$interval;this.window_=$window;this.grrApiService_=grrApiService;this.timeService_=grrTimeService;this.notifications_=[];this.lastTimestamp_=this.timeService_.getCurrentTimeMs()*1E3;this.interval_(this.fetchPendingNotifications_.bind(this),FETCH_INTERVAL)};var UserDesktopNotificationsController=grrUi.user.userDesktopNotificationsDirective.UserDesktopNotificationsController;UserDesktopNotificationsController.prototype.notify_=function(title,body,tag,opt_onclick){var notification=new Notification(title,
{body:body,icon:"static/images/grr_logo_notification.png",tag:tag});notification.onclick=function(){this.window_.focus();notification.close();if(angular.isDefined(opt_onclick))opt_onclick()}.bind(this);this.notifications_.push(notification);if(this.notifications_.length>MAX_DISPLAYED_NOTIFICATIONS)this.notifications_.shift().close();return notification};UserDesktopNotificationsController.prototype.fetchPendingNotifications_=function(){this.grrApiService_.get("users/me/notifications/pending",{timestamp:this.lastTimestamp_}).then(function(response){var items=
response["data"]["items"];if(items.length==0)return;items.sort(function(lhs,rhs){return lhs["value"]["timestamp"]["value"]-rhs["value"]["timestamp"]["value"]});this.lastTimestamp_=items[items.length-1]["value"]["timestamp"]["value"];if(items.length>MAX_DISPLAYED_NOTIFICATIONS)items=items.slice(-MAX_DISPLAYED_NOTIFICATIONS);for(var i=0;i<items.length;++i){var item=items[i];grrUi.user.userNotificationItemDirective.annotateApiNotification(item);this.notify_("GRR",item["value"]["message"]["value"],"GRR"+
item["value"]["timestamp"]["value"],function(){this.grrApiService_.delete("users/me/notifications/pending/"+item["value"]["timestamp"]["value"]);grrUi.user.userNotificationItemDirective.openReference(item,this.window_)}.bind(this))}}.bind(this))};grrUi.user.userDesktopNotificationsDirective.UserDesktopNotificationsDirective=function(){return{scope:true,restrict:"E",controller:UserDesktopNotificationsController,controllerAs:"controller"}};var UserDesktopNotificationsDirective=grrUi.user.userDesktopNotificationsDirective.UserDesktopNotificationsDirective;
UserDesktopNotificationsDirective.directive_name="grrUserDesktopNotifications"});goog.provide("grrUi.user.userLabelDirective.UserLabelController");goog.provide("grrUi.user.userLabelDirective.UserLabelDirective");
goog.scope(function(){grrUi.user.userLabelDirective.UserLabelController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.username;this.error;this.grrApiService_.getCached("users/me").then(function(response){this.username=response.data["value"]["username"]["value"]}.bind(this),function(error){if(error["status"]==403)this.error="Authentication Error";else this.error=error["statusText"]||"Error"}.bind(this))};var UserLabelController=grrUi.user.userLabelDirective.UserLabelController;
grrUi.user.userLabelDirective.UserLabelDirective=function(){return{scope:true,restrict:"E",templateUrl:"/static/angular-components/user/user-label.html",controller:UserLabelController,controllerAs:"controller"}};var UserLabelDirective=grrUi.user.userLabelDirective.UserLabelDirective;UserLabelDirective.directive_name="grrUserLabel"});goog.provide("grrUi.user.userNotificationDialogDirective.UserNotificationDialogController");goog.provide("grrUi.user.userNotificationDialogDirective.UserNotificationDialogDirective");
goog.scope(function(){grrUi.user.userNotificationDialogDirective.UserNotificationDialogController=function($scope){this.scope_=$scope;this.notificationUrl="users/me/notifications"};var UserNotificationDialogController=grrUi.user.userNotificationDialogDirective.UserNotificationDialogController;grrUi.user.userNotificationDialogDirective.UserNotificationDialogDirective=function(){return{scope:{close:"&"},restrict:"E",templateUrl:"/static/angular-components/user/user-notification-dialog.html",controller:UserNotificationDialogController,
controllerAs:"controller"}};grrUi.user.userNotificationDialogDirective.UserNotificationDialogDirective.directive_name="grrUserNotificationDialog"});goog.provide("grrUi.user.userSettingsButtonDirective.UserSettingsButtonController");goog.provide("grrUi.user.userSettingsButtonDirective.UserSettingsButtonDirective");grrUi.user.userSettingsButtonDirective.UserSettingsButtonController=function($scope,$uibModal,$timeout,$window,grrApiService){this.scope_=$scope;this.uibModal_=$uibModal;this.timeout_=$timeout;this.window_=$window;this.grrApiService_=grrApiService;this.requestSent;this.done;this.error;this.userSettings};
var UserSettingsButtonController=grrUi.user.userSettingsButtonDirective.UserSettingsButtonController;UserSettingsButtonController.prototype.onClick=function(){this.requestSent=false;this.done=false;this.error=undefined;this.userSettings=undefined;this.grrApiService_.getCached("users/me").then(function(response){this.userSettings=response["data"]["value"]["settings"]}.bind(this));this.uibModal_.open({templateUrl:"/static/angular-components/user/"+"user-settings-button-modal.html",scope:this.scope_})};
UserSettingsButtonController.prototype.saveSettings=function(){var newUser={type:"GRRUser",value:{settings:this.userSettings}};this.grrApiService_.post("users/me",newUser,true).then(function success(){this.done=true;this.timeout_(this.window_.location.reload.bind(this.window_.location),500)}.bind(this),function failure(response){this.done=true;this.error=response.data.message||"Unknown error."}.bind(this));this.requestSent=true};
grrUi.user.userSettingsButtonDirective.UserSettingsButtonDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/user/"+"user-settings-button.html",controller:UserSettingsButtonController,controllerAs:"controller"}};grrUi.user.userSettingsButtonDirective.UserSettingsButtonDirective.directive_name="grrUserSettingsButton";goog.provide("grrUi.user.module");goog.require("grrUi.core.module");goog.require("grrUi.forms.module");goog.require("grrUi.user.userDashboardDirective.UserDashboardDirective");goog.require("grrUi.user.userDesktopNotificationsDirective.UserDesktopNotificationsDirective");goog.require("grrUi.user.userLabelDirective.UserLabelDirective");goog.require("grrUi.user.userNotificationButtonDirective.UserNotificationButtonDirective");goog.require("grrUi.user.userNotificationDialogDirective.UserNotificationDialogDirective");
goog.require("grrUi.user.userNotificationItemDirective.UserNotificationItemDirective");goog.require("grrUi.user.userSettingsButtonDirective.UserSettingsButtonDirective");grrUi.user.module=angular.module("grrUi.user",[grrUi.core.module.name,grrUi.forms.module.name]);grrUi.user.module.directive(grrUi.user.userDashboardDirective.UserDashboardDirective.directive_name,grrUi.user.userDashboardDirective.UserDashboardDirective);
grrUi.core.module.directive(grrUi.user.userDesktopNotificationsDirective.UserDesktopNotificationsDirective.directive_name,grrUi.user.userDesktopNotificationsDirective.UserDesktopNotificationsDirective);grrUi.core.module.directive(grrUi.user.userLabelDirective.UserLabelDirective.directive_name,grrUi.user.userLabelDirective.UserLabelDirective);grrUi.core.module.directive(grrUi.user.userNotificationButtonDirective.UserNotificationButtonDirective.directive_name,grrUi.user.userNotificationButtonDirective.UserNotificationButtonDirective);
grrUi.core.module.directive(grrUi.user.userNotificationDialogDirective.UserNotificationDialogDirective.directive_name,grrUi.user.userNotificationDialogDirective.UserNotificationDialogDirective);grrUi.core.module.directive(grrUi.user.userNotificationItemDirective.UserNotificationItemDirective.directive_name,grrUi.user.userNotificationItemDirective.UserNotificationItemDirective);grrUi.user.module.directive(grrUi.user.userSettingsButtonDirective.UserSettingsButtonDirective.directive_name,grrUi.user.userSettingsButtonDirective.UserSettingsButtonDirective);goog.provide("grrUi.appController.module");goog.require("grrUi.acl.module");goog.require("grrUi.artifact.module");goog.require("grrUi.client.module");goog.require("grrUi.config.module");goog.require("grrUi.core.module");goog.require("grrUi.cron.module");goog.require("grrUi.docs.module");goog.require("grrUi.flow.module");goog.require("grrUi.forms.module");goog.require("grrUi.hunt.module");goog.require("grrUi.local.module");goog.require("grrUi.outputPlugins.module");goog.require("grrUi.routing.module");
goog.require("grrUi.semantic.module");goog.require("grrUi.sidebar.module");goog.require("grrUi.stats.module");goog.require("grrUi.templates.module");goog.require("grrUi.user.module");
grrUi.appController.module=angular.module("grrUi.appController",[grrUi.acl.module.name,grrUi.artifact.module.name,grrUi.client.module.name,grrUi.config.module.name,grrUi.core.module.name,grrUi.cron.module.name,grrUi.docs.module.name,grrUi.flow.module.name,grrUi.forms.module.name,grrUi.hunt.module.name,grrUi.local.module.name,grrUi.outputPlugins.module.name,grrUi.routing.module.name,grrUi.semantic.module.name,grrUi.stats.module.name,grrUi.sidebar.module.name,grrUi.templates.module.name,grrUi.user.module.name]);
grrUi.appController.module.config(function($httpProvider,$interpolateProvider,$qProvider,$locationProvider,$rootScopeProvider){$interpolateProvider.startSymbol("{$");$interpolateProvider.endSymbol("$}");$httpProvider.defaults.headers.post["Content-Type"]="application/x-www-form-urlencoded";$qProvider.errorOnUnhandledRejections(false);$locationProvider.hashPrefix("");$rootScopeProvider.digestTtl(50)});
grrUi.appController.module.run(function($injector,$http,$cookies,grrFirebaseService,grrReflectionService){$http.defaults.headers.post["X-CSRFToken"]=$cookies.get("csrftoken");$http.defaults.headers.delete=$http.defaults.headers.patch={"X-CSRFToken":$cookies.get("csrftoken")};grrFirebaseService.setupIfNeeded();grrReflectionService.getRDFValueDescriptor("ACLToken")});$["jstree"]["_themes"]="/static/third-party/jstree/themes/";jQuery["migrateMute"]=true;
grrUi.appController.module.controller("GrrUiAppController",function(){});
//# sourceMappingURL=grr-ui.bundle.js.map