From 5fd05775294332bd909e6af56919faec1e5f5cee Mon Sep 17 00:00:00 2001 From: James Kolpack Date: Thu, 20 Oct 2016 10:04:28 -0400 Subject: [PATCH] Initial deployment --- .../InventoryTraker.Web.Tests.csproj | 4 +- .../Documents/InventoryData-NoExtension | Bin 9343 -> 0 bytes .../InventoryTraker_ImportTemplate.xlsx | Bin 0 -> 9758 bytes .../Utilities/InventoryParserTests.cs | 23 +- .../Utilities/InventoryReportWriterTests.cs | 2 +- .../InventoryTraker_ImportTemplate.xlsx | Bin 0 -> 9758 bytes InventoryTraker.Web/Content/ui-grid.css | 4 +- InventoryTraker.Web/Content/ui-grid.eot | Bin 8728 -> 10320 bytes InventoryTraker.Web/Content/ui-grid.min.css | 4 +- InventoryTraker.Web/Content/ui-grid.svg | 68 +- InventoryTraker.Web/Content/ui-grid.ttf | Bin 8564 -> 10156 bytes InventoryTraker.Web/Content/ui-grid.woff | Bin 4792 -> 5728 bytes .../Controllers/InventoryController.cs | 7 +- .../InventoryTraker.Web.csproj | 28 +- InventoryTraker.Web/Migrations/SeedData.cs | 2 +- InventoryTraker.Web/NLog.config | 4 +- InventoryTraker.Web/NLog.xsd | 36 +- .../Scripts/angular-strap.compat.js | 4474 +++++++++++ .../Scripts/angular-strap.compat.min.js | 3 + InventoryTraker.Web/Scripts/angular-strap.js | 6956 +++++++++-------- .../Scripts/angular-strap.min.js | 11 +- .../Scripts/angular-strap.min.js.map | 2 +- .../Scripts/angular-strap.tpl.js | 24 +- .../Scripts/angular-strap.tpl.min.js | 4 +- InventoryTraker.Web/Scripts/ui-grid.js | 918 ++- InventoryTraker.Web/Scripts/ui-grid.min.js | 22 +- .../Utilities/InventoryParser.cs | 33 +- .../Utilities/InventoryReportWriter.cs | 1 + .../Views/Shared/_Layout.cshtml | 3 +- .../Views/Shared/_NavigationNoAuth.cshtml | 2 +- .../js/inventory/InventoryImportDirective.js | 10 +- .../js/inventory/inventorySvc.js | 11 +- .../templates/inventoryImport.tmpl.cshtml | 22 +- InventoryTraker.Web/packages.config | 14 +- 34 files changed, 9078 insertions(+), 3614 deletions(-) delete mode 100644 InventoryTraker.Web.Tests/Utilities/Documents/InventoryData-NoExtension create mode 100644 InventoryTraker.Web.Tests/Utilities/Documents/InventoryTraker_ImportTemplate.xlsx create mode 100644 InventoryTraker.Web/Content/InventoryTraker_ImportTemplate.xlsx create mode 100644 InventoryTraker.Web/Scripts/angular-strap.compat.js create mode 100644 InventoryTraker.Web/Scripts/angular-strap.compat.min.js diff --git a/InventoryTraker.Web.Tests/InventoryTraker.Web.Tests.csproj b/InventoryTraker.Web.Tests/InventoryTraker.Web.Tests.csproj index 67c0ee0..efe0fd7 100644 --- a/InventoryTraker.Web.Tests/InventoryTraker.Web.Tests.csproj +++ b/InventoryTraker.Web.Tests/InventoryTraker.Web.Tests.csproj @@ -81,9 +81,9 @@ PreserveNewest - + PreserveNewest - + diff --git a/InventoryTraker.Web.Tests/Utilities/Documents/InventoryData-NoExtension b/InventoryTraker.Web.Tests/Utilities/Documents/InventoryData-NoExtension deleted file mode 100644 index 3671dcb5532837e6c9ed302a2e975f227bb3b42a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9343 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 bGXM9AsIG(nom~I`75WK+QuH3p&tLxs^Ts;% diff --git a/InventoryTraker.Web.Tests/Utilities/Documents/InventoryTraker_ImportTemplate.xlsx b/InventoryTraker.Web.Tests/Utilities/Documents/InventoryTraker_ImportTemplate.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..e0c7cde08d4b2cf7fe572297015fce806c71d262 GIT binary patch literal 9758 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 Nj~1fF>y*E>{s-I3v?Txl literal 0 HcmV?d00001 diff --git a/InventoryTraker.Web.Tests/Utilities/InventoryParserTests.cs b/InventoryTraker.Web.Tests/Utilities/InventoryParserTests.cs index c94feb4..ec01cd1 100644 --- a/InventoryTraker.Web.Tests/Utilities/InventoryParserTests.cs +++ b/InventoryTraker.Web.Tests/Utilities/InventoryParserTests.cs @@ -20,6 +20,8 @@ namespace InventoryTraker.Web.Tests.Utilities var forms = parser.Parse(); + Assert.That(forms.Count, Is.GreaterThan(0)); + foreach (var form in forms) { Console.WriteLine($"{form.Id} {form.ProgramName} {form.ShredReadyDate}"); @@ -27,18 +29,27 @@ namespace InventoryTraker.Web.Tests.Utilities } [Test] - public void Parse_NoExtension() + public void Parse_NullableValues() { - var fileInfo = new FileInfo(Path.Combine(_documentFolder, "InventoryData-NoExtension")); + var fileInfo = new FileInfo(Path.Combine(_documentFolder, "InventoryData.xlsx")); var parser = new InventoryParser(fileInfo); var forms = parser.Parse(); - foreach (var form in forms) - { - Console.WriteLine($"{form.Id} {form.ProgramName} {form.ShredReadyDate}"); - } + Assert.That(forms[0].ProgramSubtype, Is.Null); + } + + [Test] + public void Parse_ImportTemplate() + { + var fileInfo = new FileInfo(Path.Combine(_documentFolder, "InventoryTraker_ImportTemplate.xlsx")); + + var parser = new InventoryParser(fileInfo); + + var forms = parser.Parse(); + + Assert.That(forms.Count, Is.EqualTo(1)); } } } diff --git a/InventoryTraker.Web.Tests/Utilities/InventoryReportWriterTests.cs b/InventoryTraker.Web.Tests/Utilities/InventoryReportWriterTests.cs index f46e998..d1f3ec1 100644 --- a/InventoryTraker.Web.Tests/Utilities/InventoryReportWriterTests.cs +++ b/InventoryTraker.Web.Tests/Utilities/InventoryReportWriterTests.cs @@ -16,7 +16,7 @@ namespace InventoryTraker.Web.Tests.Utilities Id = "34634584", AddedDate = new DateTime(2015,3,1), ShredReadyDate = new DateTime(2017,4,1), - Quantity = 0, + Quantity = 1, Memo = "my memo", } }; diff --git a/InventoryTraker.Web/Content/InventoryTraker_ImportTemplate.xlsx b/InventoryTraker.Web/Content/InventoryTraker_ImportTemplate.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..e0c7cde08d4b2cf7fe572297015fce806c71d262 GIT binary patch literal 9758 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 Nj~1fF>y*E>{s-I3v?Txl literal 0 HcmV?d00001 diff --git a/InventoryTraker.Web/Content/ui-grid.css b/InventoryTraker.Web/Content/ui-grid.css index e0b9a27..8bb6c7b 100644 --- a/InventoryTraker.Web/Content/ui-grid.css +++ b/InventoryTraker.Web/Content/ui-grid.css @@ -1,5 +1,5 @@ /*! - * ui-grid - v3.1.1 - 2016-02-09 + * ui-grid - v3.2.9 - 2016-09-21 * Copyright (c) 2016 ; License: MIT */ #ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:before, @@ -614,7 +614,6 @@ input[type="text"].ui-grid-filter-input:hover { .ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.focus, .ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active.focus, .ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active.focus { - outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } @@ -1303,7 +1302,6 @@ div.ui-grid-cell input.ng-valid { .ui-grid-pager-control button.focus, .ui-grid-pager-control button:active.focus, .ui-grid-pager-control button.active.focus { - outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } diff --git a/InventoryTraker.Web/Content/ui-grid.eot b/InventoryTraker.Web/Content/ui-grid.eot index 7c3e956d6760373db38af6e838c0e6365e35fcdc..6d5ac716d7015731e4151a7d62c148e93bedc821 100644 GIT binary patch delta 3940 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 C25}Ss delta 2325 zcmY*aeQZ-z6hG(Q_io$wy1tHeuNx~}*N%a!-P&zTJ~kX|#1BB{@BLJ)~))PD>hiZL;f1Y6I2uS|T+J@=mT&iS3+ zIlcG36YYE3L`f82uws{JROStZFYRi1Fyn*AfWz|J7uD94uA5&302gW8-96BiUVE^z z6#(04Ea`q^FhX{EiZ_waR;GIghIa0}m-Hb3J>A>2HcfUv>4P-8dsnSrS+=0!V*qvl zpx|U*PuB|fYw54aMZRzBBZF%nUzQ=mt7NF`8yH+S|8`n|{{)HUtJZXP#e(GuKw*;f zx`D2BY53IJPWlScBdfaxdR{nS+(-IWO7c;9&Dy~q&vzdJ2;5ABG?&74%5dtI$a3^VU6#@mO)2x9T82#W__c^@KmCH$| zW9{d_SvQTA6c@jfkCm_JL1F#Ou2_FCPc_BmM)|#5hZxj@`%rS~L=Q{Eaau!_D@I~U zEGk^ZB!boowMH>9;J5autraq1KG1-23Je8wel@T{y8A@faZiex4wlR1`uRa#Kx8Y( zyHpppcS8+|FwRB{h-fW}ShR-CR>CY8a0N}a<+(5SD9@bQj?wF929B)Q*uJ~3g*B~u zW@LMMI=8+NRTHQWxl8O6dlD)^jF}21tSPPyns#`4U3GM#neHB36l?5(jIS>$lQp!-!qD3YJiw!peg}k%@ znV07QS@^kQXJoI|YaDm%Wt*UY+;vXoO?q|SJcn(zy>*Fl zL~qQrQd%))xG)j-Ff(AFh)%((h8wW4t{lw(+mStkQ+0i*9@4W9=sFH-VQs0-Udf)x zeoM<`nuagZOmVarS%FuY?31c8Tm2RYiqtAtBD56(Xb(f!t;4XbC%J z7gk7xS(^(IML~b|x9kH!jqA^91{zr8r}_&_!)Wm?n%_FBJ{~LcDQdz>`I=cAt+X$~ zTyI&seZ56)O>;j)0!=CHrDYh`M22ZoQsm=CGsdhVMnVSuZggg@dS4T0_lHi}2-|BH zR!D`#G2qH~T{fp2o!0XaBOCEw@6TQ^j0H50;A)Z!3}%}CY{W3ol&atVGOqE{EcXZ< zVA^F%*e4)Qi?CF7i&(pRofJu;m zW>^T+lUwJ^sJpIWVxe7`d%}6yr}=Yd)>lW%CTOxxw-lYqfR_^X^K-nzPMCsLx;J{@ z5qJvr!K?5AdC8kq%37 zrB=edBbV$pp+u41lNVzdWtji-8RPp=VJs#ziKpUmClB{1cB1UlL_={mD;~B~@ig(> zHaB#5@{W8CN<lnevjZhwuM%fF}21&3f}5>F}LkaWydIkHux9%Lb*Hu diff --git a/InventoryTraker.Web/Content/ui-grid.min.css b/InventoryTraker.Web/Content/ui-grid.min.css index 33b1e89..6c7bd68 100644 --- a/InventoryTraker.Web/Content/ui-grid.min.css +++ b/InventoryTraker.Web/Content/ui-grid.min.css @@ -1,4 +1,4 @@ /*! - * ui-grid - v3.1.1 - 2016-02-09 + * ui-grid - v3.2.9 - 2016-09-21 * Copyright (c) 2016 ; License: MIT - */#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:before,#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:after,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:before,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:after,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:before,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:after{content:" ";display:table}#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:after,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:after,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:after{clear:both}.ui-grid{border:1px solid #d4d4d4;box-sizing:content-box;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-o-transform:translateZ(0);-ms-transform:translateZ(0);transform:translateZ(0)}.ui-grid-vertical-bar{position:absolute;right:0;width:0}.ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar,.ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{width:1px}.ui-grid-scrollbar-placeholder{background-color:transparent}.ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#d4d4d4}.ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#d4d4d4}.ui-grid-header-cell:last-child .ui-grid-vertical-bar{right:-1px;width:1px;background-color:#d4d4d4}.ui-grid-clearfix:before,.ui-grid-clearfix:after{content:"";display:table}.ui-grid-clearfix:after{clear:both}.ui-grid-invisible{visibility:hidden}.ui-grid-contents-wrapper{position:relative;height:100%;width:100%}.ui-grid-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.ui-grid-top-panel-background{background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0)}.ui-grid-header{border-bottom:1px solid #d4d4d4;box-sizing:border-box}.ui-grid-top-panel{position:relative;overflow:hidden;font-weight:bold;background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);-webkit-border-top-right-radius:-1px;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:-1px;-moz-border-radius-topright:-1px;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:-1px;border-top-right-radius:-1px;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:-1px;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}.ui-grid-header-viewport{overflow:hidden}.ui-grid-header-canvas:before,.ui-grid-header-canvas:after{content:"";display:table;line-height:0}.ui-grid-header-canvas:after{clear:both}.ui-grid-header-cell-wrapper{position:relative;display:table;box-sizing:border-box;height:100%}.ui-grid-header-cell-row{display:table-row;position:relative}.ui-grid-header-cell{position:relative;box-sizing:border-box;background-color:inherit;border-right:1px solid;border-color:#d4d4d4;display:table-cell;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:0}.ui-grid-header-cell:last-child{border-right:0}.ui-grid-header-cell .sortable{cursor:pointer}.ui-grid-header-cell .ui-grid-sort-priority-number{margin-left:-8px}.ui-grid-header .ui-grid-vertical-bar{top:0;bottom:0}.ui-grid-column-menu-button{position:absolute;right:1px;top:0}.ui-grid-column-menu-button .ui-grid-icon-angle-down{vertical-align:sub}.ui-grid-column-menu-button-last-col{margin-right:25px}.ui-grid-column-menu{position:absolute}.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-add,.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove{-webkit-transition:all .05s linear;-moz-transition:all .05s linear;-o-transition:all .05s linear;transition:all .05s linear;display:block !important}.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-add.ng-hide-add-active,.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-o-transform:translateY(-100%);-ms-transform:translateY(-100%);transform:translateY(-100%)}.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-add,.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove.ng-hide-remove-active{-webkit-transform:translateY(0);-moz-transform:translateY(0);-o-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-add,.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove{-webkit-transition:all .05s linear;-moz-transition:all .05s linear;-o-transition:all .05s linear;transition:all .05s linear;display:block !important}.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-add.ng-hide-add-active,.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-o-transform:translateY(-100%);-ms-transform:translateY(-100%);transform:translateY(-100%)}.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-add,.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove.ng-hide-remove-active{-webkit-transform:translateY(0);-moz-transform:translateY(0);-o-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.ui-grid-filter-container{padding:4px 10px;position:relative}.ui-grid-filter-container .ui-grid-filter-button{position:absolute;top:0;bottom:0;right:0}.ui-grid-filter-container .ui-grid-filter-button [class^="ui-grid-icon"]{position:absolute;top:50%;line-height:32px;margin-top:-16px;right:10px;opacity:.66}.ui-grid-filter-container .ui-grid-filter-button [class^="ui-grid-icon"]:hover{opacity:1}.ui-grid-filter-container .ui-grid-filter-button-select{position:absolute;top:0;bottom:0;right:0}.ui-grid-filter-container .ui-grid-filter-button-select [class^="ui-grid-icon"]{position:absolute;top:50%;line-height:32px;margin-top:-16px;right:0;opacity:.66}.ui-grid-filter-container .ui-grid-filter-button-select [class^="ui-grid-icon"]:hover{opacity:1}input[type="text"].ui-grid-filter-input{padding:0;margin:0;border:0;width:100%;border:1px solid #d4d4d4;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}input[type="text"].ui-grid-filter-input:hover{border:1px solid #d4d4d4}select.ui-grid-filter-select{padding:0;margin:0;border:0;width:90%;border:1px solid #d4d4d4;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}select.ui-grid-filter-select:hover{border:1px solid #d4d4d4}.ui-grid-filter-cancel-button-hidden select.ui-grid-filter-select{width:100%}.ui-grid-render-container{position:inherit;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}.ui-grid-render-container:focus{outline:none}.ui-grid-viewport{min-height:20px;position:relative;overflow-y:scroll;-webkit-overflow-scrolling:touch}.ui-grid-viewport:focus{outline:none !important}.ui-grid-canvas{position:relative;padding-top:1px}.ui-grid-row:nth-child(odd) .ui-grid-cell{background-color:#fdfdfd}.ui-grid-row:nth-child(even) .ui-grid-cell{background-color:#f3f3f3}.ui-grid-row:last-child .ui-grid-cell{border-bottom-color:#d4d4d4;border-bottom-style:solid}.ui-grid-no-row-overlay{position:absolute;top:0;bottom:0;left:0;right:0;margin:10%;background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #d4d4d4;font-size:2em;text-align:center}.ui-grid-no-row-overlay>*{position:absolute;display:table;margin:auto 0;width:100%;top:0;bottom:0;left:0;right:0;opacity:.66}.ui-grid-cell{overflow:hidden;float:left;background-color:inherit;border-right:1px solid;border-color:#d4d4d4;box-sizing:border-box}.ui-grid-cell:last-child{border-right:0}.ui-grid-cell-contents{padding:5px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden;height:100%}.ui-grid-cell-contents-hidden{visibility:hidden;width:0;height:0;display:none}.ui-grid-row .ui-grid-cell.ui-grid-row-header-cell{background-color:#f0f0ee;border-bottom:solid 1px #d4d4d4}.ui-grid-footer-panel-background{background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0)}.ui-grid-footer-panel{position:relative;border-bottom:1px solid #d4d4d4;border-top:1px solid #d4d4d4;overflow:hidden;font-weight:bold;background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);-webkit-border-top-right-radius:-1px;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:-1px;-moz-border-radius-topright:-1px;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:-1px;border-top-right-radius:-1px;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:-1px;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}.ui-grid-grid-footer{float:left;width:100%}.ui-grid-footer-viewport{overflow:hidden}.ui-grid-footer-canvas{position:relative}.ui-grid-footer-canvas:before,.ui-grid-footer-canvas:after{content:"";display:table;line-height:0}.ui-grid-footer-canvas:after{clear:both}.ui-grid-footer-cell-wrapper{position:relative;display:table;box-sizing:border-box;height:100%}.ui-grid-footer-cell-row{display:table-row}.ui-grid-footer-cell{overflow:hidden;background-color:inherit;border-right:1px solid;border-color:#d4d4d4;box-sizing:border-box;display:table-cell}.ui-grid-footer-cell:last-child{border-right:0}input[type="text"].ui-grid-filter-input{padding:0;margin:0;border:0;width:100%;border:1px solid #d4d4d4;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}input[type="text"].ui-grid-filter-input:hover{border:1px solid #d4d4d4}.ui-grid-menu-button{z-index:2;position:absolute;right:0;top:0;background:#f3f3f3;border:1px solid #d4d4d4;cursor:pointer;height:31px;font-weight:normal}.ui-grid-menu-button .ui-grid-icon-container{margin-top:3px}.ui-grid-menu-button .ui-grid-menu{right:0}.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid{overflow:scroll;border:1px solid #d4d4d4}.ui-grid-menu{z-index:2;position:absolute;padding:0 10px 20px 10px;cursor:pointer;box-sizing:border-box}.ui-grid-menu .ui-grid-menu-inner{background:#f3f3f3;border:1px solid #d4d4d4;position:relative;white-space:nowrap;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2);box-shadow:0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2)}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button{position:absolute;right:0;top:0;display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;padding:1px 1px;font-size:10px;line-height:1;border-radius:2px;color:transparent;background-color:transparent;border-color:transparent}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active.focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:hover,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.focus{color:#333;text-decoration:none}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.disabled,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button[disabled],fieldset[disabled] .ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button{cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.disabled,fieldset[disabled] a.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button{pointer-events:none}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.focus{color:transparent;background-color:rgba(0,0,0,0);border-color:rgba(0,0,0,0)}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:hover{color:transparent;background-color:rgba(0,0,0,0);border-color:rgba(0,0,0,0)}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active,.open>.dropdown-toggle.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button{color:transparent;background-color:rgba(0,0,0,0);border-color:rgba(0,0,0,0)}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active:hover,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active:hover,.open>.dropdown-toggle.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:hover,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active:focus,.open>.dropdown-toggle.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active.focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active.focus,.open>.dropdown-toggle.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.focus{color:transparent;background-color:rgba(0,0,0,0);border-color:rgba(0,0,0,0)}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active,.open>.dropdown-toggle.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button{background-image:none}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.disabled:hover,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button[disabled]:hover,fieldset[disabled] .ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:hover,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.disabled:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button[disabled]:focus,fieldset[disabled] .ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.disabled.focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button[disabled].focus,fieldset[disabled] .ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.focus{background-color:transparent;border-color:transparent}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button .badge{color:transparent;background-color:transparent}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button>i{opacity:.75;color:black}.ui-grid-menu .ui-grid-menu-inner ul{margin:0;padding:0;list-style-type:none}.ui-grid-menu .ui-grid-menu-inner ul li{padding:0}.ui-grid-menu .ui-grid-menu-inner ul li button{min-width:100%;padding:8px;text-align:left;background:transparent;border:none}.ui-grid-menu .ui-grid-menu-inner ul li button:hover,.ui-grid-menu .ui-grid-menu-inner ul li button:focus{-webkit-box-shadow:inset 0 0 14px rgba(0,0,0,0.2);-moz-box-shadow:inset 0 0 14px rgba(0,0,0,0.2);box-shadow:inset 0 0 14px rgba(0,0,0,0.2)}.ui-grid-menu .ui-grid-menu-inner ul li button.ui-grid-menu-item-active{-webkit-box-shadow:inset 0 0 14px rgba(0,0,0,0.2);-moz-box-shadow:inset 0 0 14px rgba(0,0,0,0.2);box-shadow:inset 0 0 14px rgba(0,0,0,0.2);background-color:#cecece}.ui-grid-menu .ui-grid-menu-inner ul li:not(:last-child)>button{border-bottom:1px solid #d4d4d4}.ui-grid-sortarrow{right:5px;position:absolute;width:20px;top:0;bottom:0;background-position:center}.ui-grid-sortarrow.down{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-o-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}@font-face{font-family:'ui-grid';src:url('ui-grid.eot');src:url('ui-grid.eot#iefix') format('embedded-opentype'),url('ui-grid.woff') format('woff'),url('ui-grid.ttf') format('truetype'),url('ui-grid.svg?#ui-grid') format('svg');font-weight:normal;font-style:normal}[class^="ui-grid-icon"]:before,[class*=" ui-grid-icon"]:before{font-family:"ui-grid";font-style:normal;font-weight:normal;speak:none;display:inline-block;text-decoration:inherit;width:1em;margin-right:.2em;text-align:center;font-variant:normal;text-transform:none;line-height:1em;margin-left:.2em}.ui-grid-icon-blank::before{width:1em;content:' '}.ui-grid[dir=rtl] .ui-grid-header-cell,.ui-grid[dir=rtl] .ui-grid-footer-cell,.ui-grid[dir=rtl] .ui-grid-cell{float:right !important}.ui-grid[dir=rtl] .ui-grid-column-menu-button{position:absolute;left:1px;top:0;right:inherit}.ui-grid[dir=rtl] .ui-grid-cell:first-child,.ui-grid[dir=rtl] .ui-grid-header-cell:first-child,.ui-grid[dir=rtl] .ui-grid-footer-cell:first-child{border-right:0}.ui-grid[dir=rtl] .ui-grid-cell:last-child,.ui-grid[dir=rtl] .ui-grid-header-cell:last-child{border-right:1px solid #d4d4d4;border-left:0}.ui-grid[dir=rtl] .ui-grid-header-cell:first-child .ui-grid-vertical-bar,.ui-grid[dir=rtl] .ui-grid-footer-cell:first-child .ui-grid-vertical-bar,.ui-grid[dir=rtl] .ui-grid-cell:first-child .ui-grid-vertical-bar{width:0}.ui-grid[dir=rtl] .ui-grid-menu-button{z-index:2;position:absolute;left:0;right:auto;background:#f3f3f3;border:1px solid #d4d4d4;cursor:pointer;min-height:27px;font-weight:normal}.ui-grid[dir=rtl] .ui-grid-menu-button .ui-grid-menu{left:0;right:auto}.ui-grid[dir=rtl] .ui-grid-filter-container .ui-grid-filter-button{right:initial;left:0}.ui-grid[dir=rtl] .ui-grid-filter-container .ui-grid-filter-button [class^="ui-grid-icon"]{right:initial;left:10px}.ui-grid-animate-spin{-moz-animation:ui-grid-spin 2s infinite linear;-o-animation:ui-grid-spin 2s infinite linear;-webkit-animation:ui-grid-spin 2s infinite linear;animation:ui-grid-spin 2s infinite linear;display:inline-block}@-moz-keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-webkit-keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-ms-keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:before,#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:after,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:before,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:after,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:before,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:after{content:" ";display:table}#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:after,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:after,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:after{clear:both}.ui-grid-cell-focus{outline:0;background-color:#b3c4c7}.ui-grid-focuser{position:absolute;left:0;top:0;z-index:-1;width:100%;height:100%}.ui-grid-focuser:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}.ui-grid-offscreen{display:block;position:absolute;left:-10000px;top:-10000px;clip:rect(0, 0, 0, 0)}div.ui-grid-cell input{border-radius:inherit;padding:0;width:100%;color:inherit;height:auto;font:inherit;outline:none}div.ui-grid-cell input:focus{color:inherit;outline:none}div.ui-grid-cell input[type="checkbox"]{margin:9px 0 0 6px;width:auto}div.ui-grid-cell input.ng-invalid{border:1px solid #fc8f8f}div.ui-grid-cell input.ng-valid{border:1px solid #d4d4d4}.expandableRow .ui-grid-row:nth-child(odd) .ui-grid-cell{background-color:#fdfdfd}.expandableRow .ui-grid-row:nth-child(even) .ui-grid-cell{background-color:#f3f3f3}.ui-grid-cell.ui-grid-disable-selection.ui-grid-row-header-cell{pointer-events:none}.ui-grid-expandable-buttons-cell i{pointer-events:all}.scrollFiller{float:left;border:1px solid #d4d4d4}.ui-grid-tree-header-row{font-weight:bold !important}.movingColumn{position:absolute;top:0;border:1px solid #d4d4d4;box-shadow:inset 0 0 14px rgba(0,0,0,0.2)}.movingColumn .ui-grid-icon-angle-down{display:none}#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:before,#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:after,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:before,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:after,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:before,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:after{content:" ";display:table}#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:after,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:after,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:after{clear:both}.ui-grid-pager-panel{position:absolute;left:0;bottom:0;width:100%;padding-top:3px;padding-bottom:3px;box-sizing:content-box}.ui-grid-pager-container{float:left}.ui-grid-pager-control{margin-right:10px;margin-left:10px;min-width:135px;float:left}.ui-grid-pager-control button{height:25px;min-width:26px;display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:#eee;background-color:#f3f3f3;border-color:#ccc}.ui-grid-pager-control button:focus,.ui-grid-pager-control button:active:focus,.ui-grid-pager-control button.active:focus,.ui-grid-pager-control button.focus,.ui-grid-pager-control button:active.focus,.ui-grid-pager-control button.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.ui-grid-pager-control button:hover,.ui-grid-pager-control button:focus,.ui-grid-pager-control button.focus{color:#333;text-decoration:none}.ui-grid-pager-control button:active,.ui-grid-pager-control button.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.ui-grid-pager-control button.disabled,.ui-grid-pager-control button[disabled],fieldset[disabled] .ui-grid-pager-control button{cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.ui-grid-pager-control button.disabled,fieldset[disabled] a.ui-grid-pager-control button{pointer-events:none}.ui-grid-pager-control button:focus,.ui-grid-pager-control button.focus{color:#eee;background-color:#dadada;border-color:#8c8c8c}.ui-grid-pager-control button:hover{color:#eee;background-color:#dadada;border-color:#adadad}.ui-grid-pager-control button:active,.ui-grid-pager-control button.active,.open>.dropdown-toggle.ui-grid-pager-control button{color:#eee;background-color:#dadada;border-color:#adadad}.ui-grid-pager-control button:active:hover,.ui-grid-pager-control button.active:hover,.open>.dropdown-toggle.ui-grid-pager-control button:hover,.ui-grid-pager-control button:active:focus,.ui-grid-pager-control button.active:focus,.open>.dropdown-toggle.ui-grid-pager-control button:focus,.ui-grid-pager-control button:active.focus,.ui-grid-pager-control button.active.focus,.open>.dropdown-toggle.ui-grid-pager-control button.focus{color:#eee;background-color:#c8c8c8;border-color:#8c8c8c}.ui-grid-pager-control button:active,.ui-grid-pager-control button.active,.open>.dropdown-toggle.ui-grid-pager-control button{background-image:none}.ui-grid-pager-control button.disabled:hover,.ui-grid-pager-control button[disabled]:hover,fieldset[disabled] .ui-grid-pager-control button:hover,.ui-grid-pager-control button.disabled:focus,.ui-grid-pager-control button[disabled]:focus,fieldset[disabled] .ui-grid-pager-control button:focus,.ui-grid-pager-control button.disabled.focus,.ui-grid-pager-control button[disabled].focus,fieldset[disabled] .ui-grid-pager-control button.focus{background-color:#f3f3f3;border-color:#ccc}.ui-grid-pager-control button .badge{color:#f3f3f3;background-color:#eee}.ui-grid-pager-control input{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px;display:inline;height:26px;width:50px;vertical-align:top}.ui-grid-pager-control input:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}.ui-grid-pager-control input::-moz-placeholder{color:#999;opacity:1}.ui-grid-pager-control input:-ms-input-placeholder{color:#999}.ui-grid-pager-control input::-webkit-input-placeholder{color:#999}.ui-grid-pager-control input::-ms-expand{border:0;background-color:transparent}.ui-grid-pager-control input[disabled],.ui-grid-pager-control input[readonly],fieldset[disabled] .ui-grid-pager-control input{background-color:#eee;opacity:1}.ui-grid-pager-control input[disabled],fieldset[disabled] .ui-grid-pager-control input{cursor:not-allowed}textarea.ui-grid-pager-control input{height:auto}select.ui-grid-pager-control input{height:30px;line-height:30px}textarea.ui-grid-pager-control input,select[multiple].ui-grid-pager-control input{height:auto}.ui-grid-pager-control .ui-grid-pager-max-pages-number{vertical-align:bottom}.ui-grid-pager-control .ui-grid-pager-max-pages-number>*{vertical-align:middle}.ui-grid-pager-control .first-bar{width:10px;border-left:2px solid #4d4d4d;margin-top:-6px;height:12px;margin-left:-3px}.ui-grid-pager-control .first-bar-rtl{width:10px;border-left:2px solid #4d4d4d;margin-top:-6px;height:12px;margin-right:-7px}.ui-grid-pager-control .first-triangle{width:0;height:0;border-style:solid;border-width:5px 8.7px 5px 0;border-color:transparent #4d4d4d transparent transparent;margin-left:2px}.ui-grid-pager-control .next-triangle{margin-left:1px}.ui-grid-pager-control .prev-triangle{margin-left:0}.ui-grid-pager-control .last-triangle{width:0;height:0;border-style:solid;border-width:5px 0 5px 8.7px;border-color:transparent transparent transparent #4d4d4d;margin-left:-1px}.ui-grid-pager-control .last-bar{width:10px;border-left:2px solid #4d4d4d;margin-top:-6px;height:12px;margin-left:1px}.ui-grid-pager-control .last-bar-rtl{width:10px;border-left:2px solid #4d4d4d;margin-top:-6px;height:12px;margin-right:-11px}.ui-grid-pager-row-count-picker{float:left}.ui-grid-pager-row-count-picker select{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px;height:26px;width:67px;display:inline}.ui-grid-pager-row-count-picker select:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}.ui-grid-pager-row-count-picker select::-moz-placeholder{color:#999;opacity:1}.ui-grid-pager-row-count-picker select:-ms-input-placeholder{color:#999}.ui-grid-pager-row-count-picker select::-webkit-input-placeholder{color:#999}.ui-grid-pager-row-count-picker select::-ms-expand{border:0;background-color:transparent}.ui-grid-pager-row-count-picker select[disabled],.ui-grid-pager-row-count-picker select[readonly],fieldset[disabled] .ui-grid-pager-row-count-picker select{background-color:#eee;opacity:1}.ui-grid-pager-row-count-picker select[disabled],fieldset[disabled] .ui-grid-pager-row-count-picker select{cursor:not-allowed}textarea.ui-grid-pager-row-count-picker select{height:auto}select.ui-grid-pager-row-count-picker select{height:30px;line-height:30px}textarea.ui-grid-pager-row-count-picker select,select[multiple].ui-grid-pager-row-count-picker select{height:auto}.ui-grid-pager-row-count-picker .ui-grid-pager-row-count-label{margin-top:3px}.ui-grid-pager-count-container{float:right;margin-top:4px;min-width:50px}.ui-grid-pager-count-container .ui-grid-pager-count{margin-right:10px;margin-left:10px;float:right}.ui-grid-pinned-container{position:absolute;display:inline;top:0}.ui-grid-pinned-container.ui-grid-pinned-container-left{float:left;left:0}.ui-grid-pinned-container.ui-grid-pinned-container-right{float:right;right:0}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:last-child{box-sizing:border-box;border-right:1px solid;border-width:1px;border-right-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-cell:last-child{box-sizing:border-box;border-right:1px solid;border-width:1px;border-right-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar,.ui-grid-pinned-container .ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{width:1px}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#d4d4d4}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:last-child .ui-grid-vertical-bar{right:-1px;width:1px;background-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-right .ui-grid-header-cell:first-child{box-sizing:border-box;border-left:1px solid;border-width:1px;border-left-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-right .ui-grid-cell:first-child{box-sizing:border-box;border-left:1px solid;border-width:1px;border-left-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-right .ui-grid-header-cell:not(:first-child) .ui-grid-vertical-bar,.ui-grid-pinned-container .ui-grid-cell:not(:first-child) .ui-grid-vertical-bar{width:1px}.ui-grid-pinned-container.ui-grid-pinned-container-right .ui-grid-header-cell:not(:first-child) .ui-grid-vertical-bar{background-color:#d4d4d4}.ui-grid-pinned-container.ui-grid-pinned-container-right .ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-first .ui-grid-header-cell:first-child .ui-grid-vertical-bar{left:-1px;width:1px;background-color:#aeaeae}.ui-grid-column-resizer{top:0;bottom:0;width:5px;position:absolute;cursor:col-resize}.ui-grid-column-resizer.left{left:0}.ui-grid-column-resizer.right{right:0}.ui-grid-header-cell:last-child .ui-grid-column-resizer.right{border-right:1px solid #d4d4d4}.ui-grid[dir=rtl] .ui-grid-header-cell:last-child .ui-grid-column-resizer.right{border-right:0}.ui-grid[dir=rtl] .ui-grid-header-cell:last-child .ui-grid-column-resizer.left{border-left:1px solid #d4d4d4}.ui-grid.column-resizing{cursor:col-resize}.ui-grid.column-resizing .ui-grid-resize-overlay{position:absolute;top:0;height:100%;width:1px;background-color:#aeaeae}.ui-grid-row-saving .ui-grid-cell{color:#848484 !important}.ui-grid-row-dirty .ui-grid-cell{color:#610b38}.ui-grid-row-error .ui-grid-cell{color:#f00 !important}.ui-grid-row.ui-grid-row-selected>[ui-grid-row]>.ui-grid-cell{background-color:#c9dde1}.ui-grid-disable-selection{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.ui-grid-selection-row-header-buttons{cursor:pointer;opacity:.1}.ui-grid-selection-row-header-buttons.ui-grid-row-selected{opacity:1}.ui-grid-selection-row-header-buttons.ui-grid-all-selected{opacity:1}.ui-grid-tree-row-header-buttons.ui-grid-tree-header{cursor:pointer;opacity:1}.ui-grid-tree-header-row{font-weight:bold !important}.ui-grid-tree-header-row .ui-grid-cell.ui-grid-disable-selection.ui-grid-row-header-cell{pointer-events:all}div.ui-grid-cell-contents.invalid{border:1px solid #fc8f8f}.ui-grid-icon-plus-squared:before{content:'\c350'}.ui-grid-icon-minus-squared:before{content:'\c351'}.ui-grid-icon-search:before{content:'\c352'}.ui-grid-icon-cancel:before{content:'\c353'}.ui-grid-icon-info-circled:before{content:'\c354'}.ui-grid-icon-lock:before{content:'\c355'}.ui-grid-icon-lock-open:before{content:'\c356'}.ui-grid-icon-pencil:before{content:'\c357'}.ui-grid-icon-down-dir:before{content:'\c358'}.ui-grid-icon-up-dir:before{content:'\c359'}.ui-grid-icon-left-dir:before{content:'\c35a'}.ui-grid-icon-right-dir:before{content:'\c35b'}.ui-grid-icon-left-open:before{content:'\c35c'}.ui-grid-icon-right-open:before{content:'\c35d'}.ui-grid-icon-angle-down:before{content:'\c35e'}.ui-grid-icon-filter:before{content:'\c35f'}.ui-grid-icon-sort-alt-up:before{content:'\c360'}.ui-grid-icon-sort-alt-down:before{content:'\c361'}.ui-grid-icon-ok:before{content:'\c362'}.ui-grid-icon-menu:before{content:'\c363'}.ui-grid-icon-indent-left:before{content:'\e800'}.ui-grid-icon-indent-right:before{content:'\e801'}.ui-grid-icon-spin5:before{content:'\ea61'} \ No newline at end of file + */#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:before,#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:after,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:before,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:after,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:before,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:after{content:" ";display:table}#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:after,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:after,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:after{clear:both}.ui-grid{border:1px solid #d4d4d4;box-sizing:content-box;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-o-transform:translateZ(0);-ms-transform:translateZ(0);transform:translateZ(0)}.ui-grid-vertical-bar{position:absolute;right:0;width:0}.ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar,.ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{width:1px}.ui-grid-scrollbar-placeholder{background-color:transparent}.ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#d4d4d4}.ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#d4d4d4}.ui-grid-header-cell:last-child .ui-grid-vertical-bar{right:-1px;width:1px;background-color:#d4d4d4}.ui-grid-clearfix:before,.ui-grid-clearfix:after{content:"";display:table}.ui-grid-clearfix:after{clear:both}.ui-grid-invisible{visibility:hidden}.ui-grid-contents-wrapper{position:relative;height:100%;width:100%}.ui-grid-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.ui-grid-top-panel-background{background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0)}.ui-grid-header{border-bottom:1px solid #d4d4d4;box-sizing:border-box}.ui-grid-top-panel{position:relative;overflow:hidden;font-weight:bold;background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);-webkit-border-top-right-radius:-1px;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:-1px;-moz-border-radius-topright:-1px;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:-1px;border-top-right-radius:-1px;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:-1px;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}.ui-grid-header-viewport{overflow:hidden}.ui-grid-header-canvas:before,.ui-grid-header-canvas:after{content:"";display:table;line-height:0}.ui-grid-header-canvas:after{clear:both}.ui-grid-header-cell-wrapper{position:relative;display:table;box-sizing:border-box;height:100%}.ui-grid-header-cell-row{display:table-row;position:relative}.ui-grid-header-cell{position:relative;box-sizing:border-box;background-color:inherit;border-right:1px solid;border-color:#d4d4d4;display:table-cell;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:0}.ui-grid-header-cell:last-child{border-right:0}.ui-grid-header-cell .sortable{cursor:pointer}.ui-grid-header-cell .ui-grid-sort-priority-number{margin-left:-8px}.ui-grid-header .ui-grid-vertical-bar{top:0;bottom:0}.ui-grid-column-menu-button{position:absolute;right:1px;top:0}.ui-grid-column-menu-button .ui-grid-icon-angle-down{vertical-align:sub}.ui-grid-column-menu-button-last-col{margin-right:25px}.ui-grid-column-menu{position:absolute}.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-add,.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove{-webkit-transition:all .05s linear;-moz-transition:all .05s linear;-o-transition:all .05s linear;transition:all .05s linear;display:block !important}.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-add.ng-hide-add-active,.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-o-transform:translateY(-100%);-ms-transform:translateY(-100%);transform:translateY(-100%)}.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-add,.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove.ng-hide-remove-active{-webkit-transform:translateY(0);-moz-transform:translateY(0);-o-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-add,.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove{-webkit-transition:all .05s linear;-moz-transition:all .05s linear;-o-transition:all .05s linear;transition:all .05s linear;display:block !important}.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-add.ng-hide-add-active,.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-o-transform:translateY(-100%);-ms-transform:translateY(-100%);transform:translateY(-100%)}.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-add,.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove.ng-hide-remove-active{-webkit-transform:translateY(0);-moz-transform:translateY(0);-o-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.ui-grid-filter-container{padding:4px 10px;position:relative}.ui-grid-filter-container .ui-grid-filter-button{position:absolute;top:0;bottom:0;right:0}.ui-grid-filter-container .ui-grid-filter-button [class^="ui-grid-icon"]{position:absolute;top:50%;line-height:32px;margin-top:-16px;right:10px;opacity:.66}.ui-grid-filter-container .ui-grid-filter-button [class^="ui-grid-icon"]:hover{opacity:1}.ui-grid-filter-container .ui-grid-filter-button-select{position:absolute;top:0;bottom:0;right:0}.ui-grid-filter-container .ui-grid-filter-button-select [class^="ui-grid-icon"]{position:absolute;top:50%;line-height:32px;margin-top:-16px;right:0;opacity:.66}.ui-grid-filter-container .ui-grid-filter-button-select [class^="ui-grid-icon"]:hover{opacity:1}input[type="text"].ui-grid-filter-input{padding:0;margin:0;border:0;width:100%;border:1px solid #d4d4d4;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}input[type="text"].ui-grid-filter-input:hover{border:1px solid #d4d4d4}select.ui-grid-filter-select{padding:0;margin:0;border:0;width:90%;border:1px solid #d4d4d4;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}select.ui-grid-filter-select:hover{border:1px solid #d4d4d4}.ui-grid-filter-cancel-button-hidden select.ui-grid-filter-select{width:100%}.ui-grid-render-container{position:inherit;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}.ui-grid-render-container:focus{outline:none}.ui-grid-viewport{min-height:20px;position:relative;overflow-y:scroll;-webkit-overflow-scrolling:touch}.ui-grid-viewport:focus{outline:none !important}.ui-grid-canvas{position:relative;padding-top:1px}.ui-grid-row:nth-child(odd) .ui-grid-cell{background-color:#fdfdfd}.ui-grid-row:nth-child(even) .ui-grid-cell{background-color:#f3f3f3}.ui-grid-row:last-child .ui-grid-cell{border-bottom-color:#d4d4d4;border-bottom-style:solid}.ui-grid-no-row-overlay{position:absolute;top:0;bottom:0;left:0;right:0;margin:10%;background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #d4d4d4;font-size:2em;text-align:center}.ui-grid-no-row-overlay>*{position:absolute;display:table;margin:auto 0;width:100%;top:0;bottom:0;left:0;right:0;opacity:.66}.ui-grid-cell{overflow:hidden;float:left;background-color:inherit;border-right:1px solid;border-color:#d4d4d4;box-sizing:border-box}.ui-grid-cell:last-child{border-right:0}.ui-grid-cell-contents{padding:5px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden;height:100%}.ui-grid-cell-contents-hidden{visibility:hidden;width:0;height:0;display:none}.ui-grid-row .ui-grid-cell.ui-grid-row-header-cell{background-color:#f0f0ee;border-bottom:solid 1px #d4d4d4}.ui-grid-footer-panel-background{background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0)}.ui-grid-footer-panel{position:relative;border-bottom:1px solid #d4d4d4;border-top:1px solid #d4d4d4;overflow:hidden;font-weight:bold;background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);-webkit-border-top-right-radius:-1px;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:-1px;-moz-border-radius-topright:-1px;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:-1px;border-top-right-radius:-1px;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:-1px;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}.ui-grid-grid-footer{float:left;width:100%}.ui-grid-footer-viewport{overflow:hidden}.ui-grid-footer-canvas{position:relative}.ui-grid-footer-canvas:before,.ui-grid-footer-canvas:after{content:"";display:table;line-height:0}.ui-grid-footer-canvas:after{clear:both}.ui-grid-footer-cell-wrapper{position:relative;display:table;box-sizing:border-box;height:100%}.ui-grid-footer-cell-row{display:table-row}.ui-grid-footer-cell{overflow:hidden;background-color:inherit;border-right:1px solid;border-color:#d4d4d4;box-sizing:border-box;display:table-cell}.ui-grid-footer-cell:last-child{border-right:0}input[type="text"].ui-grid-filter-input{padding:0;margin:0;border:0;width:100%;border:1px solid #d4d4d4;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}input[type="text"].ui-grid-filter-input:hover{border:1px solid #d4d4d4}.ui-grid-menu-button{z-index:2;position:absolute;right:0;top:0;background:#f3f3f3;border:1px solid #d4d4d4;cursor:pointer;height:31px;font-weight:normal}.ui-grid-menu-button .ui-grid-icon-container{margin-top:3px}.ui-grid-menu-button .ui-grid-menu{right:0}.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid{overflow:scroll;border:1px solid #d4d4d4}.ui-grid-menu{z-index:2;position:absolute;padding:0 10px 20px 10px;cursor:pointer;box-sizing:border-box}.ui-grid-menu .ui-grid-menu-inner{background:#f3f3f3;border:1px solid #d4d4d4;position:relative;white-space:nowrap;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2);box-shadow:0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2)}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button{position:absolute;right:0;top:0;display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;padding:1px 1px;font-size:10px;line-height:1;border-radius:2px;color:transparent;background-color:transparent;border-color:transparent}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active.focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active.focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:hover,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.focus{color:#333;text-decoration:none}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.disabled,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button[disabled],fieldset[disabled] .ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button{cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.disabled,fieldset[disabled] a.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button{pointer-events:none}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.focus{color:transparent;background-color:rgba(0,0,0,0);border-color:rgba(0,0,0,0)}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:hover{color:transparent;background-color:rgba(0,0,0,0);border-color:rgba(0,0,0,0)}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active,.open>.dropdown-toggle.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button{color:transparent;background-color:rgba(0,0,0,0);border-color:rgba(0,0,0,0)}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active:hover,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active:hover,.open>.dropdown-toggle.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:hover,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active:focus,.open>.dropdown-toggle.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active.focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active.focus,.open>.dropdown-toggle.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.focus{color:transparent;background-color:rgba(0,0,0,0);border-color:rgba(0,0,0,0)}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active,.open>.dropdown-toggle.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button{background-image:none}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.disabled:hover,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button[disabled]:hover,fieldset[disabled] .ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:hover,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.disabled:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button[disabled]:focus,fieldset[disabled] .ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.disabled.focus,.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button[disabled].focus,fieldset[disabled] .ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.focus{background-color:transparent;border-color:transparent}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button .badge{color:transparent;background-color:transparent}.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button>i{opacity:.75;color:black}.ui-grid-menu .ui-grid-menu-inner ul{margin:0;padding:0;list-style-type:none}.ui-grid-menu .ui-grid-menu-inner ul li{padding:0}.ui-grid-menu .ui-grid-menu-inner ul li button{min-width:100%;padding:8px;text-align:left;background:transparent;border:none}.ui-grid-menu .ui-grid-menu-inner ul li button:hover,.ui-grid-menu .ui-grid-menu-inner ul li button:focus{-webkit-box-shadow:inset 0 0 14px rgba(0,0,0,0.2);-moz-box-shadow:inset 0 0 14px rgba(0,0,0,0.2);box-shadow:inset 0 0 14px rgba(0,0,0,0.2)}.ui-grid-menu .ui-grid-menu-inner ul li button.ui-grid-menu-item-active{-webkit-box-shadow:inset 0 0 14px rgba(0,0,0,0.2);-moz-box-shadow:inset 0 0 14px rgba(0,0,0,0.2);box-shadow:inset 0 0 14px rgba(0,0,0,0.2);background-color:#cecece}.ui-grid-menu .ui-grid-menu-inner ul li:not(:last-child)>button{border-bottom:1px solid #d4d4d4}.ui-grid-sortarrow{right:5px;position:absolute;width:20px;top:0;bottom:0;background-position:center}.ui-grid-sortarrow.down{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-o-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}@font-face{font-family:'ui-grid';src:url('ui-grid.eot');src:url('ui-grid.eot#iefix') format('embedded-opentype'),url('ui-grid.woff') format('woff'),url('ui-grid.ttf') format('truetype'),url('ui-grid.svg?#ui-grid') format('svg');font-weight:normal;font-style:normal}[class^="ui-grid-icon"]:before,[class*=" ui-grid-icon"]:before{font-family:"ui-grid";font-style:normal;font-weight:normal;speak:none;display:inline-block;text-decoration:inherit;width:1em;margin-right:.2em;text-align:center;font-variant:normal;text-transform:none;line-height:1em;margin-left:.2em}.ui-grid-icon-blank::before{width:1em;content:' '}.ui-grid[dir=rtl] .ui-grid-header-cell,.ui-grid[dir=rtl] .ui-grid-footer-cell,.ui-grid[dir=rtl] .ui-grid-cell{float:right !important}.ui-grid[dir=rtl] .ui-grid-column-menu-button{position:absolute;left:1px;top:0;right:inherit}.ui-grid[dir=rtl] .ui-grid-cell:first-child,.ui-grid[dir=rtl] .ui-grid-header-cell:first-child,.ui-grid[dir=rtl] .ui-grid-footer-cell:first-child{border-right:0}.ui-grid[dir=rtl] .ui-grid-cell:last-child,.ui-grid[dir=rtl] .ui-grid-header-cell:last-child{border-right:1px solid #d4d4d4;border-left:0}.ui-grid[dir=rtl] .ui-grid-header-cell:first-child .ui-grid-vertical-bar,.ui-grid[dir=rtl] .ui-grid-footer-cell:first-child .ui-grid-vertical-bar,.ui-grid[dir=rtl] .ui-grid-cell:first-child .ui-grid-vertical-bar{width:0}.ui-grid[dir=rtl] .ui-grid-menu-button{z-index:2;position:absolute;left:0;right:auto;background:#f3f3f3;border:1px solid #d4d4d4;cursor:pointer;min-height:27px;font-weight:normal}.ui-grid[dir=rtl] .ui-grid-menu-button .ui-grid-menu{left:0;right:auto}.ui-grid[dir=rtl] .ui-grid-filter-container .ui-grid-filter-button{right:initial;left:0}.ui-grid[dir=rtl] .ui-grid-filter-container .ui-grid-filter-button [class^="ui-grid-icon"]{right:initial;left:10px}.ui-grid-animate-spin{-moz-animation:ui-grid-spin 2s infinite linear;-o-animation:ui-grid-spin 2s infinite linear;-webkit-animation:ui-grid-spin 2s infinite linear;animation:ui-grid-spin 2s infinite linear;display:inline-block}@-moz-keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-webkit-keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-ms-keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:before,#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:after,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:before,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:after,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:before,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:after{content:" ";display:table}#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:after,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:after,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:after{clear:both}.ui-grid-cell-focus{outline:0;background-color:#b3c4c7}.ui-grid-focuser{position:absolute;left:0;top:0;z-index:-1;width:100%;height:100%}.ui-grid-focuser:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}.ui-grid-offscreen{display:block;position:absolute;left:-10000px;top:-10000px;clip:rect(0, 0, 0, 0)}div.ui-grid-cell input{border-radius:inherit;padding:0;width:100%;color:inherit;height:auto;font:inherit;outline:none}div.ui-grid-cell input:focus{color:inherit;outline:none}div.ui-grid-cell input[type="checkbox"]{margin:9px 0 0 6px;width:auto}div.ui-grid-cell input.ng-invalid{border:1px solid #fc8f8f}div.ui-grid-cell input.ng-valid{border:1px solid #d4d4d4}.expandableRow .ui-grid-row:nth-child(odd) .ui-grid-cell{background-color:#fdfdfd}.expandableRow .ui-grid-row:nth-child(even) .ui-grid-cell{background-color:#f3f3f3}.ui-grid-cell.ui-grid-disable-selection.ui-grid-row-header-cell{pointer-events:none}.ui-grid-expandable-buttons-cell i{pointer-events:all}.scrollFiller{float:left;border:1px solid #d4d4d4}.ui-grid-tree-header-row{font-weight:bold !important}.movingColumn{position:absolute;top:0;border:1px solid #d4d4d4;box-shadow:inset 0 0 14px rgba(0,0,0,0.2)}.movingColumn .ui-grid-icon-angle-down{display:none}#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:before,#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:after,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:before,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:after,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:before,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:after{content:" ";display:table}#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:after,#ui-grid-twbs #ui-grid-twbs .btn-toolbar:after,#ui-grid-twbs #ui-grid-twbs .btn-group-vertical>.btn-group:after{clear:both}.ui-grid-pager-panel{position:absolute;left:0;bottom:0;width:100%;padding-top:3px;padding-bottom:3px;box-sizing:content-box}.ui-grid-pager-container{float:left}.ui-grid-pager-control{margin-right:10px;margin-left:10px;min-width:135px;float:left}.ui-grid-pager-control button{height:25px;min-width:26px;display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:#eee;background-color:#f3f3f3;border-color:#ccc}.ui-grid-pager-control button:focus,.ui-grid-pager-control button:active:focus,.ui-grid-pager-control button.active:focus,.ui-grid-pager-control button.focus,.ui-grid-pager-control button:active.focus,.ui-grid-pager-control button.active.focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.ui-grid-pager-control button:hover,.ui-grid-pager-control button:focus,.ui-grid-pager-control button.focus{color:#333;text-decoration:none}.ui-grid-pager-control button:active,.ui-grid-pager-control button.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.ui-grid-pager-control button.disabled,.ui-grid-pager-control button[disabled],fieldset[disabled] .ui-grid-pager-control button{cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.ui-grid-pager-control button.disabled,fieldset[disabled] a.ui-grid-pager-control button{pointer-events:none}.ui-grid-pager-control button:focus,.ui-grid-pager-control button.focus{color:#eee;background-color:#dadada;border-color:#8c8c8c}.ui-grid-pager-control button:hover{color:#eee;background-color:#dadada;border-color:#adadad}.ui-grid-pager-control button:active,.ui-grid-pager-control button.active,.open>.dropdown-toggle.ui-grid-pager-control button{color:#eee;background-color:#dadada;border-color:#adadad}.ui-grid-pager-control button:active:hover,.ui-grid-pager-control button.active:hover,.open>.dropdown-toggle.ui-grid-pager-control button:hover,.ui-grid-pager-control button:active:focus,.ui-grid-pager-control button.active:focus,.open>.dropdown-toggle.ui-grid-pager-control button:focus,.ui-grid-pager-control button:active.focus,.ui-grid-pager-control button.active.focus,.open>.dropdown-toggle.ui-grid-pager-control button.focus{color:#eee;background-color:#c8c8c8;border-color:#8c8c8c}.ui-grid-pager-control button:active,.ui-grid-pager-control button.active,.open>.dropdown-toggle.ui-grid-pager-control button{background-image:none}.ui-grid-pager-control button.disabled:hover,.ui-grid-pager-control button[disabled]:hover,fieldset[disabled] .ui-grid-pager-control button:hover,.ui-grid-pager-control button.disabled:focus,.ui-grid-pager-control button[disabled]:focus,fieldset[disabled] .ui-grid-pager-control button:focus,.ui-grid-pager-control button.disabled.focus,.ui-grid-pager-control button[disabled].focus,fieldset[disabled] .ui-grid-pager-control button.focus{background-color:#f3f3f3;border-color:#ccc}.ui-grid-pager-control button .badge{color:#f3f3f3;background-color:#eee}.ui-grid-pager-control input{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px;display:inline;height:26px;width:50px;vertical-align:top}.ui-grid-pager-control input:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}.ui-grid-pager-control input::-moz-placeholder{color:#999;opacity:1}.ui-grid-pager-control input:-ms-input-placeholder{color:#999}.ui-grid-pager-control input::-webkit-input-placeholder{color:#999}.ui-grid-pager-control input::-ms-expand{border:0;background-color:transparent}.ui-grid-pager-control input[disabled],.ui-grid-pager-control input[readonly],fieldset[disabled] .ui-grid-pager-control input{background-color:#eee;opacity:1}.ui-grid-pager-control input[disabled],fieldset[disabled] .ui-grid-pager-control input{cursor:not-allowed}textarea.ui-grid-pager-control input{height:auto}select.ui-grid-pager-control input{height:30px;line-height:30px}textarea.ui-grid-pager-control input,select[multiple].ui-grid-pager-control input{height:auto}.ui-grid-pager-control .ui-grid-pager-max-pages-number{vertical-align:bottom}.ui-grid-pager-control .ui-grid-pager-max-pages-number>*{vertical-align:middle}.ui-grid-pager-control .first-bar{width:10px;border-left:2px solid #4d4d4d;margin-top:-6px;height:12px;margin-left:-3px}.ui-grid-pager-control .first-bar-rtl{width:10px;border-left:2px solid #4d4d4d;margin-top:-6px;height:12px;margin-right:-7px}.ui-grid-pager-control .first-triangle{width:0;height:0;border-style:solid;border-width:5px 8.7px 5px 0;border-color:transparent #4d4d4d transparent transparent;margin-left:2px}.ui-grid-pager-control .next-triangle{margin-left:1px}.ui-grid-pager-control .prev-triangle{margin-left:0}.ui-grid-pager-control .last-triangle{width:0;height:0;border-style:solid;border-width:5px 0 5px 8.7px;border-color:transparent transparent transparent #4d4d4d;margin-left:-1px}.ui-grid-pager-control .last-bar{width:10px;border-left:2px solid #4d4d4d;margin-top:-6px;height:12px;margin-left:1px}.ui-grid-pager-control .last-bar-rtl{width:10px;border-left:2px solid #4d4d4d;margin-top:-6px;height:12px;margin-right:-11px}.ui-grid-pager-row-count-picker{float:left}.ui-grid-pager-row-count-picker select{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px;height:26px;width:67px;display:inline}.ui-grid-pager-row-count-picker select:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}.ui-grid-pager-row-count-picker select::-moz-placeholder{color:#999;opacity:1}.ui-grid-pager-row-count-picker select:-ms-input-placeholder{color:#999}.ui-grid-pager-row-count-picker select::-webkit-input-placeholder{color:#999}.ui-grid-pager-row-count-picker select::-ms-expand{border:0;background-color:transparent}.ui-grid-pager-row-count-picker select[disabled],.ui-grid-pager-row-count-picker select[readonly],fieldset[disabled] .ui-grid-pager-row-count-picker select{background-color:#eee;opacity:1}.ui-grid-pager-row-count-picker select[disabled],fieldset[disabled] .ui-grid-pager-row-count-picker select{cursor:not-allowed}textarea.ui-grid-pager-row-count-picker select{height:auto}select.ui-grid-pager-row-count-picker select{height:30px;line-height:30px}textarea.ui-grid-pager-row-count-picker select,select[multiple].ui-grid-pager-row-count-picker select{height:auto}.ui-grid-pager-row-count-picker .ui-grid-pager-row-count-label{margin-top:3px}.ui-grid-pager-count-container{float:right;margin-top:4px;min-width:50px}.ui-grid-pager-count-container .ui-grid-pager-count{margin-right:10px;margin-left:10px;float:right}.ui-grid-pinned-container{position:absolute;display:inline;top:0}.ui-grid-pinned-container.ui-grid-pinned-container-left{float:left;left:0}.ui-grid-pinned-container.ui-grid-pinned-container-right{float:right;right:0}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:last-child{box-sizing:border-box;border-right:1px solid;border-width:1px;border-right-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-cell:last-child{box-sizing:border-box;border-right:1px solid;border-width:1px;border-right-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar,.ui-grid-pinned-container .ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{width:1px}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#d4d4d4}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:last-child .ui-grid-vertical-bar{right:-1px;width:1px;background-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-right .ui-grid-header-cell:first-child{box-sizing:border-box;border-left:1px solid;border-width:1px;border-left-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-right .ui-grid-cell:first-child{box-sizing:border-box;border-left:1px solid;border-width:1px;border-left-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-right .ui-grid-header-cell:not(:first-child) .ui-grid-vertical-bar,.ui-grid-pinned-container .ui-grid-cell:not(:first-child) .ui-grid-vertical-bar{width:1px}.ui-grid-pinned-container.ui-grid-pinned-container-right .ui-grid-header-cell:not(:first-child) .ui-grid-vertical-bar{background-color:#d4d4d4}.ui-grid-pinned-container.ui-grid-pinned-container-right .ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-first .ui-grid-header-cell:first-child .ui-grid-vertical-bar{left:-1px;width:1px;background-color:#aeaeae}.ui-grid-column-resizer{top:0;bottom:0;width:5px;position:absolute;cursor:col-resize}.ui-grid-column-resizer.left{left:0}.ui-grid-column-resizer.right{right:0}.ui-grid-header-cell:last-child .ui-grid-column-resizer.right{border-right:1px solid #d4d4d4}.ui-grid[dir=rtl] .ui-grid-header-cell:last-child .ui-grid-column-resizer.right{border-right:0}.ui-grid[dir=rtl] .ui-grid-header-cell:last-child .ui-grid-column-resizer.left{border-left:1px solid #d4d4d4}.ui-grid.column-resizing{cursor:col-resize}.ui-grid.column-resizing .ui-grid-resize-overlay{position:absolute;top:0;height:100%;width:1px;background-color:#aeaeae}.ui-grid-row-saving .ui-grid-cell{color:#848484 !important}.ui-grid-row-dirty .ui-grid-cell{color:#610b38}.ui-grid-row-error .ui-grid-cell{color:#f00 !important}.ui-grid-row.ui-grid-row-selected>[ui-grid-row]>.ui-grid-cell{background-color:#c9dde1}.ui-grid-disable-selection{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.ui-grid-selection-row-header-buttons{cursor:pointer;opacity:.1}.ui-grid-selection-row-header-buttons.ui-grid-row-selected{opacity:1}.ui-grid-selection-row-header-buttons.ui-grid-all-selected{opacity:1}.ui-grid-tree-row-header-buttons.ui-grid-tree-header{cursor:pointer;opacity:1}.ui-grid-tree-header-row{font-weight:bold !important}.ui-grid-tree-header-row .ui-grid-cell.ui-grid-disable-selection.ui-grid-row-header-cell{pointer-events:all}div.ui-grid-cell-contents.invalid{border:1px solid #fc8f8f}.ui-grid-icon-plus-squared:before{content:'\c350'}.ui-grid-icon-minus-squared:before{content:'\c351'}.ui-grid-icon-search:before{content:'\c352'}.ui-grid-icon-cancel:before{content:'\c353'}.ui-grid-icon-info-circled:before{content:'\c354'}.ui-grid-icon-lock:before{content:'\c355'}.ui-grid-icon-lock-open:before{content:'\c356'}.ui-grid-icon-pencil:before{content:'\c357'}.ui-grid-icon-down-dir:before{content:'\c358'}.ui-grid-icon-up-dir:before{content:'\c359'}.ui-grid-icon-left-dir:before{content:'\c35a'}.ui-grid-icon-right-dir:before{content:'\c35b'}.ui-grid-icon-left-open:before{content:'\c35c'}.ui-grid-icon-right-open:before{content:'\c35d'}.ui-grid-icon-angle-down:before{content:'\c35e'}.ui-grid-icon-filter:before{content:'\c35f'}.ui-grid-icon-sort-alt-up:before{content:'\c360'}.ui-grid-icon-sort-alt-down:before{content:'\c361'}.ui-grid-icon-ok:before{content:'\c362'}.ui-grid-icon-menu:before{content:'\c363'}.ui-grid-icon-indent-left:before{content:'\e800'}.ui-grid-icon-indent-right:before{content:'\e801'}.ui-grid-icon-spin5:before{content:'\ea61'} \ No newline at end of file diff --git a/InventoryTraker.Web/Content/ui-grid.svg b/InventoryTraker.Web/Content/ui-grid.svg index 3556111..9d2e03c 100644 --- a/InventoryTraker.Web/Content/ui-grid.svg +++ b/InventoryTraker.Web/Content/ui-grid.svg @@ -6,29 +6,51 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/InventoryTraker.Web/Content/ui-grid.ttf b/InventoryTraker.Web/Content/ui-grid.ttf index 9cee108e137a3636a318b8bf176400ad2b6a1605..33a12da14b46daddc675fe00982c6e4d2390bf96 100644 GIT binary patch delta 3952 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 E0yMR+*8l(j diff --git a/InventoryTraker.Web/Content/ui-grid.woff b/InventoryTraker.Web/Content/ui-grid.woff index fbbbb4e09ef041ab4437a986a071b8dc05496560..d164149a96905c2daa6733e0a8f8ee79486c1d8d 100644 GIT binary patch delta 5361 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 RA1ZTzX#pf&tfv6L{{W9{$~XW3 delta 4443 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 abd;tC@y5+OSg3<3mmUTX&v5>|Y4{IRlLU4E diff --git a/InventoryTraker.Web/Controllers/InventoryController.cs b/InventoryTraker.Web/Controllers/InventoryController.cs index 89b1d1b..e5c08d3 100644 --- a/InventoryTraker.Web/Controllers/InventoryController.cs +++ b/InventoryTraker.Web/Controllers/InventoryController.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using System.Web; using System.Web.Mvc; using AutoMapper; using AutoMapper.QueryableExtensions; @@ -19,13 +17,11 @@ namespace InventoryTraker.Web.Controllers { private readonly AppDbContext _context; private readonly IMapper _mapper; - private readonly InventoryImporter _inventoryImporter; - public InventoryController(AppDbContext context, IMapper mapper, InventoryImporter inventoryImporter) + public InventoryController(AppDbContext context, IMapper mapper) { _context = context; _mapper = mapper; - _inventoryImporter = inventoryImporter; } public ActionResult Index() @@ -158,6 +154,5 @@ namespace InventoryTraker.Web.Controllers return BetterJson(_mapper.Map(inventory)); } - } } \ No newline at end of file diff --git a/InventoryTraker.Web/InventoryTraker.Web.csproj b/InventoryTraker.Web/InventoryTraker.Web.csproj index a51116d..b393fb8 100644 --- a/InventoryTraker.Web/InventoryTraker.Web.csproj +++ b/InventoryTraker.Web/InventoryTraker.Web.csproj @@ -129,7 +129,7 @@ True - ..\packages\NLog.4.3.8\lib\net45\NLog.dll + ..\packages\NLog.4.3.10\lib\net45\NLog.dll True @@ -140,8 +140,8 @@ ..\packages\Owin.1.0\lib\net40\Owin.dll True - - ..\packages\StructureMap.4.4.0\lib\net45\StructureMap.dll + + ..\packages\StructureMap.4.4.1\lib\net45\StructureMap.dll True @@ -202,7 +202,7 @@ - ..\packages\WebActivatorEx.2.1.0\lib\net40\WebActivatorEx.dll + ..\packages\WebActivatorEx.2.2.0\lib\net40\WebActivatorEx.dll True @@ -211,6 +211,9 @@ + + Always + @@ -260,6 +263,8 @@ + + @@ -274,15 +279,11 @@ - - - - @@ -298,10 +299,17 @@ + + PreserveNewest + + + + Designer + @@ -414,9 +422,7 @@ Web.config - - - + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) diff --git a/InventoryTraker.Web/Migrations/SeedData.cs b/InventoryTraker.Web/Migrations/SeedData.cs index 826a056..7c9c104 100644 --- a/InventoryTraker.Web/Migrations/SeedData.cs +++ b/InventoryTraker.Web/Migrations/SeedData.cs @@ -149,7 +149,7 @@ namespace InventoryTraker.Web.Migrations RemovedQuantity = inventory.Quantity, CurrentQuantity = 0, Inventory = inventory, - Memo = $"Expired on {inventory.ShredReadyDate.ToShortDateString()}", + Memo = $"Shreded on {inventory.ShredReadyDate.ToShortDateString()}", TransactionDate = dd, Timestamp = dd }; diff --git a/InventoryTraker.Web/NLog.config b/InventoryTraker.Web/NLog.config index 7fd01fd..c12535d 100644 --- a/InventoryTraker.Web/NLog.config +++ b/InventoryTraker.Web/NLog.config @@ -16,8 +16,8 @@ for information on customizing logging rules and outputs. --> - - + + diff --git a/InventoryTraker.Web/NLog.xsd b/InventoryTraker.Web/NLog.xsd index 2104459..f61050f 100644 --- a/InventoryTraker.Web/NLog.xsd +++ b/InventoryTraker.Web/NLog.xsd @@ -531,6 +531,7 @@ + @@ -559,6 +560,11 @@ Indicates whether to use default row highlighting rules. + + + Indicates whether to auto-check if the console is available. - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App) + + The encoding for writing messages to the . @@ -670,6 +676,7 @@ + @@ -697,6 +704,11 @@ Indicates whether to send the log messages to the standard error instead of the standard output. + + + Indicates whether to auto-check if the console is available - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App) + + The encoding for writing messages to the . @@ -1031,6 +1043,7 @@ + @@ -1039,7 +1052,7 @@ - + @@ -1047,8 +1060,8 @@ + - @@ -1130,6 +1143,11 @@ Gets or set a value indicating whether a managed file stream is forced, instead of used the native implementation. + + + Indicates whether the footer should be written only when the file is archived. + + Name of the file to write to. @@ -1170,9 +1188,9 @@ Indicates whether to replace file contents on each write instead of appending log message at the end. - + - Delay in milliseconds to wait before attempting to write to the file again. + Indicates whether concurrent writes to the log file by multiple processes on the same host. @@ -1210,16 +1228,16 @@ Indicates whether to automatically flush the file buffers after each log message. + + + Delay in milliseconds to wait before attempting to write to the file again. + + Number of times the write is appended on the file before NLog discards the log message. - - - Indicates whether concurrent writes to the log file by multiple processes on the same host. - - diff --git a/InventoryTraker.Web/Scripts/angular-strap.compat.js b/InventoryTraker.Web/Scripts/angular-strap.compat.js new file mode 100644 index 0000000..32d035d --- /dev/null +++ b/InventoryTraker.Web/Scripts/angular-strap.compat.js @@ -0,0 +1,4474 @@ +/** + * angular-strap + * @version v2.3.9 - 2016-06-10 + * @link http://mgcrea.github.io/angular-strap + * @author Olivier Louvignes (https://github.com/mgcrea) + * @license MIT License, http://www.opensource.org/licenses/MIT + */ +(function(window, document, undefined) { + 'use strict'; + bsCompilerService.$inject = ["$q", "$http", "$injector", "$compile", "$controller", "$templateCache"]; + angular.module('mgcrea.ngStrap.typeahead', [ 'mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions' ]).provider('$bsTypeahead', function() { + var defaults = this.defaults = { + animation: 'am-fade', + prefixClass: 'typeahead', + prefixEvent: '$typeahead', + placement: 'bottom-left', + templateUrl: 'typeahead/typeahead.tpl.html', + trigger: 'focus', + container: false, + keyboard: true, + html: false, + delay: 0, + minLength: 1, + filter: 'bsAsyncFilter', + limit: 6, + autoSelect: false, + comparator: '', + trimValue: true + }; + this.$get = ["$window", "$rootScope", "$bsTooltip", "$$rAF", "$timeout", function($window, $rootScope, $tooltip, $$rAF, $timeout) { + function TypeaheadFactory(element, controller, config) { + var $typeahead = {}; + var options = angular.extend({}, defaults, config); + $typeahead = $tooltip(element, options); + var parentScope = config.scope; + var scope = $typeahead.$scope; + scope.$resetMatches = function() { + scope.$matches = []; + scope.$activeIndex = options.autoSelect ? 0 : -1; + }; + scope.$resetMatches(); + scope.$activate = function(index) { + scope.$$postDigest(function() { + $typeahead.activate(index); + }); + }; + scope.$select = function(index, evt) { + scope.$$postDigest(function() { + $typeahead.select(index); + }); + }; + scope.$isVisible = function() { + return $typeahead.$isVisible(); + }; + $typeahead.update = function(matches) { + scope.$matches = matches; + if (scope.$activeIndex >= matches.length) { + scope.$activeIndex = options.autoSelect ? 0 : -1; + } + safeDigest(scope); + $$rAF($typeahead.$applyPlacement); + }; + $typeahead.activate = function(index) { + scope.$activeIndex = index; + }; + $typeahead.select = function(index) { + if (index === -1) return; + var value = scope.$matches[index].value; + controller.$setViewValue(value); + controller.$render(); + scope.$resetMatches(); + if (parentScope) parentScope.$digest(); + scope.$emit(options.prefixEvent + '.select', value, index, $typeahead); + if (angular.isDefined(options.onSelect) && angular.isFunction(options.onSelect)) { + options.onSelect(value, index, $typeahead); + } + }; + $typeahead.$isVisible = function() { + if (!options.minLength || !controller) { + return !!scope.$matches.length; + } + return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength; + }; + $typeahead.$getIndex = function(value) { + var index; + for (index = scope.$matches.length; index--; ) { + if (angular.equals(scope.$matches[index].value, value)) break; + } + return index; + }; + $typeahead.$onMouseDown = function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + }; + $typeahead.$onKeyDown = function(evt) { + if (!/(38|40|13)/.test(evt.keyCode)) return; + if ($typeahead.$isVisible() && !(evt.keyCode === 13 && scope.$activeIndex === -1)) { + evt.preventDefault(); + evt.stopPropagation(); + } + if (evt.keyCode === 13 && scope.$matches.length) { + $typeahead.select(scope.$activeIndex); + } else if (evt.keyCode === 38 && scope.$activeIndex > 0) { + scope.$activeIndex--; + } else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) { + scope.$activeIndex++; + } else if (angular.isUndefined(scope.$activeIndex)) { + scope.$activeIndex = 0; + } + scope.$digest(); + }; + var show = $typeahead.show; + $typeahead.show = function() { + show(); + $timeout(function() { + if ($typeahead.$element) { + $typeahead.$element.on('mousedown', $typeahead.$onMouseDown); + if (options.keyboard) { + if (element) element.on('keydown', $typeahead.$onKeyDown); + } + } + }, 0, false); + }; + var hide = $typeahead.hide; + $typeahead.hide = function() { + if ($typeahead.$element) $typeahead.$element.off('mousedown', $typeahead.$onMouseDown); + if (options.keyboard) { + if (element) element.off('keydown', $typeahead.$onKeyDown); + } + if (!options.autoSelect) { + $typeahead.activate(-1); + } + hide(); + }; + return $typeahead; + } + function safeDigest(scope) { + scope.$$phase || scope.$root && scope.$root.$$phase || scope.$digest(); + } + TypeaheadFactory.defaults = defaults; + return TypeaheadFactory; + } ]; + }).filter('bsAsyncFilter', ["$filter", function($filter) { + return function(array, expression, comparator) { + if (array && angular.isFunction(array.then)) { + return array.then(function(results) { + return $filter('filter')(results, expression, comparator); + }); + } + return $filter('filter')(array, expression, comparator); + }; + } ]).directive('bsTypeahead', ["$window", "$parse", "$q", "$bsTypeahead", "$bsParseOptions", function($window, $parse, $q, $typeahead, $parseOptions) { + var defaults = $typeahead.defaults; + return { + restrict: 'EAC', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + element.off('change'); + var options = { + scope: scope + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container', 'trimValue', 'filter' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide', 'onSelect' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + if (!element.attr('autocomplete')) element.attr('autocomplete', 'off'); + var filter = angular.isDefined(options.filter) ? options.filter : defaults.filter; + var limit = options.limit || defaults.limit; + var comparator = options.comparator || defaults.comparator; + var bsOptions = attr.bsOptions; + if (filter) { + bsOptions += ' | ' + filter + ':$viewValue'; + if (comparator) bsOptions += ':' + comparator; + } + if (limit) bsOptions += ' | limitTo:' + limit; + var parsedOptions = $parseOptions(bsOptions); + var typeahead = $typeahead(element, controller, options); + if (options.watchOptions) { + var watchedOptions = parsedOptions.$match[7].replace(/\|.+/, '').replace(/\(.*\)/g, '').trim(); + scope.$watchCollection(watchedOptions, function(newValue, oldValue) { + parsedOptions.valuesFn(scope, controller).then(function(values) { + typeahead.update(values); + controller.$render(); + }); + }); + } + scope.$watch(attr.ngModel, function(newValue, oldValue) { + scope.$modelValue = newValue; + parsedOptions.valuesFn(scope, controller).then(function(values) { + if (options.selectMode && !values.length && newValue.length > 0) { + controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1)); + return; + } + if (values.length > limit) values = values.slice(0, limit); + typeahead.update(values); + controller.$render(); + }); + }); + controller.$formatters.push(function(modelValue) { + var displayValue = parsedOptions.displayValue(modelValue); + if (displayValue) { + return displayValue; + } + if (angular.isDefined(modelValue) && typeof modelValue !== 'object') { + return modelValue; + } + return ''; + }); + controller.$render = function() { + if (controller.$isEmpty(controller.$viewValue)) { + return element.val(''); + } + var index = typeahead.$getIndex(controller.$modelValue); + var selected = index !== -1 ? typeahead.$scope.$matches[index].label : controller.$viewValue; + selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected; + var value = selected ? selected.toString().replace(/<(?:.|\n)*?>/gm, '') : ''; + var ss = element[0].selectionStart; + var sd = element[0].selectionEnd; + element.val(options.trimValue === false ? value : value.trim()); + element[0].setSelectionRange(ss, sd); + }; + scope.$on('$destroy', function() { + if (typeahead) typeahead.destroy(); + options = null; + typeahead = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.tab', []).provider('$bsTab', function() { + var defaults = this.defaults = { + animation: 'am-fade', + template: 'tab/tab.tpl.html', + navClass: 'nav-tabs', + activeClass: 'active' + }; + var controller = this.controller = function($scope, $element, $attrs) { + var self = this; + self.$options = angular.copy(defaults); + angular.forEach([ 'animation', 'navClass', 'activeClass' ], function(key) { + if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key]; + }); + $scope.$navClass = self.$options.navClass; + $scope.$activeClass = self.$options.activeClass; + self.$panes = $scope.$panes = []; + self.$activePaneChangeListeners = self.$viewChangeListeners = []; + self.$push = function(pane) { + if (angular.isUndefined(self.$panes.$active)) { + $scope.$setActive(pane.name || 0); + } + self.$panes.push(pane); + }; + self.$remove = function(pane) { + var index = self.$panes.indexOf(pane); + var active = self.$panes.$active; + var activeIndex; + if (angular.isString(active)) { + activeIndex = self.$panes.map(function(pane) { + return pane.name; + }).indexOf(active); + } else { + activeIndex = self.$panes.$active; + } + self.$panes.splice(index, 1); + if (index < activeIndex) { + activeIndex--; + } else if (index === activeIndex && activeIndex === self.$panes.length) { + activeIndex--; + } + if (activeIndex >= 0 && activeIndex < self.$panes.length) { + self.$setActive(self.$panes[activeIndex].name || activeIndex); + } else { + self.$setActive(); + } + }; + self.$setActive = $scope.$setActive = function(value) { + self.$panes.$active = value; + self.$activePaneChangeListeners.forEach(function(fn) { + fn(); + }); + }; + self.$isActive = $scope.$isActive = function($pane, $index) { + return self.$panes.$active === $pane.name || self.$panes.$active === $index; + }; + }; + this.$get = function() { + var $tab = {}; + $tab.defaults = defaults; + $tab.controller = controller; + return $tab; + }; + }).directive('bsTabs', ["$window", "$animate", "$bsTab", "$parse", function($window, $animate, $tab, $parse) { + var defaults = $tab.defaults; + return { + require: [ '?ngModel', 'bsTabs' ], + transclude: true, + scope: true, + controller: [ '$scope', '$element', '$attrs', $tab.controller ], + templateUrl: function(element, attr) { + return attr.template || defaults.template; + }, + link: function postLink(scope, element, attrs, controllers) { + var ngModelCtrl = controllers[0]; + var bsTabsCtrl = controllers[1]; + if (ngModelCtrl) { + bsTabsCtrl.$activePaneChangeListeners.push(function() { + ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active); + }); + ngModelCtrl.$formatters.push(function(modelValue) { + bsTabsCtrl.$setActive(modelValue); + return modelValue; + }); + } + if (attrs.bsActivePane) { + var parsedBsActivePane = $parse(attrs.bsActivePane); + bsTabsCtrl.$activePaneChangeListeners.push(function() { + parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active); + }); + scope.$watch(attrs.bsActivePane, function(newValue, oldValue) { + bsTabsCtrl.$setActive(newValue); + }, true); + } + } + }; + } ]).directive('bsPane', ["$window", "$animate", "$sce", function($window, $animate, $sce) { + return { + require: [ '^?ngModel', '^bsTabs' ], + scope: true, + link: function postLink(scope, element, attrs, controllers) { + var bsTabsCtrl = controllers[1]; + element.addClass('tab-pane'); + attrs.$observe('title', function(newValue, oldValue) { + scope.title = $sce.trustAsHtml(newValue); + }); + scope.name = attrs.name; + if (bsTabsCtrl.$options.animation) { + element.addClass(bsTabsCtrl.$options.animation); + } + attrs.$observe('disabled', function(newValue, oldValue) { + scope.disabled = scope.$eval(newValue); + }); + bsTabsCtrl.$push(scope); + scope.$on('$destroy', function() { + bsTabsCtrl.$remove(scope); + }); + function render() { + var index = bsTabsCtrl.$panes.indexOf(scope); + $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass); + } + bsTabsCtrl.$activePaneChangeListeners.push(function() { + render(); + }); + render(); + } + }; + } ]); + angular.module('mgcrea.ngStrap.tooltip', [ 'mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$bsTooltip', function() { + var defaults = this.defaults = { + animation: 'am-fade', + customClass: '', + prefixClass: 'tooltip', + prefixEvent: 'tooltip', + container: false, + target: false, + placement: 'top', + templateUrl: 'tooltip/tooltip.tpl.html', + template: '', + titleTemplate: false, + trigger: 'hover focus', + keyboard: false, + html: false, + show: false, + title: '', + type: '', + delay: 0, + autoClose: false, + bsEnabled: true, + mouseDownPreventDefault: true, + mouseDownStopPropagation: true, + viewport: { + selector: 'body', + padding: 0 + } + }; + this.$get = ["$window", "$rootScope", "$bsCompiler", "$q", "$templateCache", "$http", "$animate", "$sce", "bsDimensions", "$$rAF", "$timeout", function($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) { + var isNative = /(ip[ao]d|iphone|android)/gi.test($window.navigator.userAgent); + var isTouch = 'createTouch' in $window.document && isNative; + var $body = angular.element($window.document); + function TooltipFactory(element, config) { + var $tooltip = {}; + var options = $tooltip.$options = angular.extend({}, defaults, config); + var promise = $tooltip.$promise = $bsCompiler.compile(options); + var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new(); + var nodeName = element[0].nodeName.toLowerCase(); + if (options.delay && angular.isString(options.delay)) { + var split = options.delay.split(',').map(parseFloat); + options.delay = split.length > 1 ? { + show: split[0], + hide: split[1] + } : split[0]; + } + $tooltip.$id = options.id || element.attr('id') || ''; + if (options.title) { + scope.title = $sce.trustAsHtml(options.title); + } + scope.$setEnabled = function(isEnabled) { + scope.$$postDigest(function() { + $tooltip.setEnabled(isEnabled); + }); + }; + scope.$hide = function() { + scope.$$postDigest(function() { + $tooltip.hide(); + }); + }; + scope.$show = function() { + scope.$$postDigest(function() { + $tooltip.show(); + }); + }; + scope.$toggle = function() { + scope.$$postDigest(function() { + $tooltip.toggle(); + }); + }; + $tooltip.$isShown = scope.$isShown = false; + var timeout; + var hoverState; + var compileData; + var tipElement; + var tipContainer; + var tipScope; + promise.then(function(data) { + compileData = data; + $tooltip.init(); + }); + $tooltip.init = function() { + if (options.delay && angular.isNumber(options.delay)) { + options.delay = { + show: options.delay, + hide: options.delay + }; + } + if (options.container === 'self') { + tipContainer = element; + } else if (angular.isElement(options.container)) { + tipContainer = options.container; + } else if (options.container) { + tipContainer = findElement(options.container); + } + bindTriggerEvents(); + if (options.target) { + options.target = angular.isElement(options.target) ? options.target : findElement(options.target); + } + if (options.show) { + scope.$$postDigest(function() { + if (options.trigger === 'focus') { + element[0].focus(); + } else { + $tooltip.show(); + } + }); + } + }; + $tooltip.destroy = function() { + unbindTriggerEvents(); + destroyTipElement(); + scope.$destroy(); + }; + $tooltip.enter = function() { + clearTimeout(timeout); + hoverState = 'in'; + if (!options.delay || !options.delay.show) { + return $tooltip.show(); + } + timeout = setTimeout(function() { + if (hoverState === 'in') $tooltip.show(); + }, options.delay.show); + }; + $tooltip.show = function() { + if (!options.bsEnabled || $tooltip.$isShown) return; + scope.$emit(options.prefixEvent + '.show.before', $tooltip); + if (angular.isDefined(options.onBeforeShow) && angular.isFunction(options.onBeforeShow)) { + options.onBeforeShow($tooltip); + } + var parent; + var after; + if (options.container) { + parent = tipContainer; + if (tipContainer[0].lastChild) { + after = angular.element(tipContainer[0].lastChild); + } else { + after = null; + } + } else { + parent = null; + after = element; + } + if (tipElement) destroyTipElement(); + tipScope = $tooltip.$scope.$new(); + tipElement = $tooltip.$element = compileData.link(tipScope, function(clonedElement, scope) {}); + tipElement.css({ + top: '-9999px', + left: '-9999px', + right: 'auto', + display: 'block', + visibility: 'hidden' + }); + if (options.animation) tipElement.addClass(options.animation); + if (options.type) tipElement.addClass(options.prefixClass + '-' + options.type); + if (options.customClass) tipElement.addClass(options.customClass); + if (after) { + after.after(tipElement); + } else { + parent.prepend(tipElement); + } + $tooltip.$isShown = scope.$isShown = true; + safeDigest(scope); + $tooltip.$applyPlacement(); + if (angular.version.minor <= 2) { + $animate.enter(tipElement, parent, after, enterAnimateCallback); + } else { + $animate.enter(tipElement, parent, after).then(enterAnimateCallback); + } + safeDigest(scope); + $$rAF(function() { + if (tipElement) tipElement.css({ + visibility: 'visible' + }); + if (options.keyboard) { + if (options.trigger !== 'focus') { + $tooltip.focus(); + } + bindKeyboardEvents(); + } + }); + if (options.autoClose) { + bindAutoCloseEvents(); + } + }; + function enterAnimateCallback() { + scope.$emit(options.prefixEvent + '.show', $tooltip); + if (angular.isDefined(options.onShow) && angular.isFunction(options.onShow)) { + options.onShow($tooltip); + } + } + $tooltip.leave = function() { + clearTimeout(timeout); + hoverState = 'out'; + if (!options.delay || !options.delay.hide) { + return $tooltip.hide(); + } + timeout = setTimeout(function() { + if (hoverState === 'out') { + $tooltip.hide(); + } + }, options.delay.hide); + }; + var _blur; + var _tipToHide; + $tooltip.hide = function(blur) { + if (!$tooltip.$isShown) return; + scope.$emit(options.prefixEvent + '.hide.before', $tooltip); + if (angular.isDefined(options.onBeforeHide) && angular.isFunction(options.onBeforeHide)) { + options.onBeforeHide($tooltip); + } + _blur = blur; + _tipToHide = tipElement; + if (angular.version.minor <= 2) { + $animate.leave(tipElement, leaveAnimateCallback); + } else { + $animate.leave(tipElement).then(leaveAnimateCallback); + } + $tooltip.$isShown = scope.$isShown = false; + safeDigest(scope); + if (options.keyboard && tipElement !== null) { + unbindKeyboardEvents(); + } + if (options.autoClose && tipElement !== null) { + unbindAutoCloseEvents(); + } + }; + function leaveAnimateCallback() { + scope.$emit(options.prefixEvent + '.hide', $tooltip); + if (angular.isDefined(options.onHide) && angular.isFunction(options.onHide)) { + options.onHide($tooltip); + } + if (tipElement === _tipToHide) { + if (_blur && options.trigger === 'focus') { + return element[0].blur(); + } + destroyTipElement(); + } + } + $tooltip.toggle = function(evt) { + if (evt) { + evt.preventDefault(); + } + if ($tooltip.$isShown) { + $tooltip.leave(); + } else { + $tooltip.enter(); + } + }; + $tooltip.focus = function() { + tipElement[0].focus(); + }; + $tooltip.setEnabled = function(isEnabled) { + options.bsEnabled = isEnabled; + }; + $tooltip.setViewport = function(viewport) { + options.viewport = viewport; + }; + $tooltip.$applyPlacement = function() { + if (!tipElement) return; + var placement = options.placement; + var autoToken = /\s?auto?\s?/i; + var autoPlace = autoToken.test(placement); + if (autoPlace) { + placement = placement.replace(autoToken, '') || defaults.placement; + } + tipElement.addClass(options.placement); + var elementPosition = getPosition(); + var tipWidth = tipElement.prop('offsetWidth'); + var tipHeight = tipElement.prop('offsetHeight'); + $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport); + if (autoPlace) { + var originalPlacement = placement; + var viewportPosition = getPosition($tooltip.$viewport); + if (/bottom/.test(originalPlacement) && elementPosition.bottom + tipHeight > viewportPosition.bottom) { + placement = originalPlacement.replace('bottom', 'top'); + } else if (/top/.test(originalPlacement) && elementPosition.top - tipHeight < viewportPosition.top) { + placement = originalPlacement.replace('top', 'bottom'); + } + if (/left/.test(originalPlacement) && elementPosition.left - tipWidth < viewportPosition.left) { + placement = placement.replace('left', 'right'); + } else if (/right/.test(originalPlacement) && elementPosition.right + tipWidth > viewportPosition.width) { + placement = placement.replace('right', 'left'); + } + tipElement.removeClass(originalPlacement).addClass(placement); + } + var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight); + applyPlacement(tipPosition, placement); + }; + $tooltip.$onKeyUp = function(evt) { + if (evt.which === 27 && $tooltip.$isShown) { + $tooltip.hide(); + evt.stopPropagation(); + } + }; + $tooltip.$onFocusKeyUp = function(evt) { + if (evt.which === 27) { + element[0].blur(); + evt.stopPropagation(); + } + }; + $tooltip.$onFocusElementMouseDown = function(evt) { + if (options.mouseDownPreventDefault) { + evt.preventDefault(); + } + if (options.mouseDownStopPropagation) { + evt.stopPropagation(); + } + if ($tooltip.$isShown) { + element[0].blur(); + } else { + element[0].focus(); + } + }; + function bindTriggerEvents() { + var triggers = options.trigger.split(' '); + angular.forEach(triggers, function(trigger) { + if (trigger === 'click' || trigger === 'contextmenu') { + element.on(trigger, $tooltip.toggle); + } else if (trigger !== 'manual') { + element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter); + element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave); + if (nodeName === 'button' && trigger !== 'hover') { + element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown); + } + } + }); + } + function unbindTriggerEvents() { + var triggers = options.trigger.split(' '); + for (var i = triggers.length; i--; ) { + var trigger = triggers[i]; + if (trigger === 'click' || trigger === 'contextmenu') { + element.off(trigger, $tooltip.toggle); + } else if (trigger !== 'manual') { + element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter); + element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave); + if (nodeName === 'button' && trigger !== 'hover') { + element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown); + } + } + } + } + function bindKeyboardEvents() { + if (options.trigger !== 'focus') { + tipElement.on('keyup', $tooltip.$onKeyUp); + } else { + element.on('keyup', $tooltip.$onFocusKeyUp); + } + } + function unbindKeyboardEvents() { + if (options.trigger !== 'focus') { + tipElement.off('keyup', $tooltip.$onKeyUp); + } else { + element.off('keyup', $tooltip.$onFocusKeyUp); + } + } + var _autoCloseEventsBinded = false; + function bindAutoCloseEvents() { + $timeout(function() { + tipElement.on('click', stopEventPropagation); + $body.on('click', $tooltip.hide); + _autoCloseEventsBinded = true; + }, 0, false); + } + function unbindAutoCloseEvents() { + if (_autoCloseEventsBinded) { + tipElement.off('click', stopEventPropagation); + $body.off('click', $tooltip.hide); + _autoCloseEventsBinded = false; + } + } + function stopEventPropagation(event) { + event.stopPropagation(); + } + function getPosition($element) { + $element = $element || (options.target || element); + var el = $element[0]; + var isBody = el.tagName === 'BODY'; + var elRect = el.getBoundingClientRect(); + var rect = {}; + for (var p in elRect) { + rect[p] = elRect[p]; + } + if (rect.width === null) { + rect = angular.extend({}, rect, { + width: elRect.right - elRect.left, + height: elRect.bottom - elRect.top + }); + } + var elOffset = isBody ? { + top: 0, + left: 0 + } : dimensions.offset(el); + var scroll = { + scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 + }; + var outerDims = isBody ? { + width: document.documentElement.clientWidth, + height: $window.innerHeight + } : null; + return angular.extend({}, rect, scroll, outerDims, elOffset); + } + function getCalculatedOffset(placement, position, actualWidth, actualHeight) { + var offset; + var split = placement.split('-'); + switch (split[0]) { + case 'right': + offset = { + top: position.top + position.height / 2 - actualHeight / 2, + left: position.left + position.width + }; + break; + + case 'bottom': + offset = { + top: position.top + position.height, + left: position.left + position.width / 2 - actualWidth / 2 + }; + break; + + case 'left': + offset = { + top: position.top + position.height / 2 - actualHeight / 2, + left: position.left - actualWidth + }; + break; + + default: + offset = { + top: position.top - actualHeight, + left: position.left + position.width / 2 - actualWidth / 2 + }; + break; + } + if (!split[1]) { + return offset; + } + if (split[0] === 'top' || split[0] === 'bottom') { + switch (split[1]) { + case 'left': + offset.left = position.left; + break; + + case 'right': + offset.left = position.left + position.width - actualWidth; + break; + + default: + break; + } + } else if (split[0] === 'left' || split[0] === 'right') { + switch (split[1]) { + case 'top': + offset.top = position.top - actualHeight + position.height; + break; + + case 'bottom': + offset.top = position.top; + break; + + default: + break; + } + } + return offset; + } + function applyPlacement(offset, placement) { + var tip = tipElement[0]; + var width = tip.offsetWidth; + var height = tip.offsetHeight; + var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10); + var marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10); + if (isNaN(marginTop)) marginTop = 0; + if (isNaN(marginLeft)) marginLeft = 0; + offset.top = offset.top + marginTop; + offset.left = offset.left + marginLeft; + dimensions.setOffset(tip, angular.extend({ + using: function(props) { + tipElement.css({ + top: Math.round(props.top) + 'px', + left: Math.round(props.left) + 'px', + right: '' + }); + } + }, offset), 0); + var actualWidth = tip.offsetWidth; + var actualHeight = tip.offsetHeight; + if (placement === 'top' && actualHeight !== height) { + offset.top = offset.top + height - actualHeight; + } + if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return; + var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight); + if (delta.left) { + offset.left += delta.left; + } else { + offset.top += delta.top; + } + dimensions.setOffset(tip, offset); + if (/top|right|bottom|left/.test(placement)) { + var isVertical = /top|bottom/.test(placement); + var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight; + var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'; + replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical); + } + } + function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) { + var delta = { + top: 0, + left: 0 + }; + if (!$tooltip.$viewport) return delta; + var viewportPadding = options.viewport && options.viewport.padding || 0; + var viewportDimensions = getPosition($tooltip.$viewport); + if (/right|left/.test(placement)) { + var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll; + var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight; + if (topEdgeOffset < viewportDimensions.top) { + delta.top = viewportDimensions.top - topEdgeOffset; + } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { + delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset; + } + } else { + var leftEdgeOffset = position.left - viewportPadding; + var rightEdgeOffset = position.left + viewportPadding + actualWidth; + if (leftEdgeOffset < viewportDimensions.left) { + delta.left = viewportDimensions.left - leftEdgeOffset; + } else if (rightEdgeOffset > viewportDimensions.right) { + delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset; + } + } + return delta; + } + function replaceArrow(delta, dimension, isHorizontal) { + var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]); + $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%').css(isHorizontal ? 'top' : 'left', ''); + } + function destroyTipElement() { + clearTimeout(timeout); + if ($tooltip.$isShown && tipElement !== null) { + if (options.autoClose) { + unbindAutoCloseEvents(); + } + if (options.keyboard) { + unbindKeyboardEvents(); + } + } + if (tipScope) { + tipScope.$destroy(); + tipScope = null; + } + if (tipElement) { + tipElement.remove(); + tipElement = $tooltip.$element = null; + } + } + return $tooltip; + } + function safeDigest(scope) { + scope.$$phase || scope.$root && scope.$root.$$phase || scope.$digest(); + } + function findElement(query, element) { + return angular.element((element || document).querySelectorAll(query)); + } + return TooltipFactory; + } ]; + }).directive('bsTooltip', ["$window", "$location", "$sce", "$parse", "$bsTooltip", "$$rAF", function($window, $location, $sce, $parse, $tooltip, $$rAF) { + return { + restrict: 'EAC', + scope: true, + link: function postLink(scope, element, attr, transclusion) { + var tooltip; + var options = { + scope: scope + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'titleTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) { + options[key] = false; + } + }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + var dataTarget = element.attr('data-target'); + if (angular.isDefined(dataTarget)) { + if (falseValueRegExp.test(dataTarget)) { + options.target = false; + } else { + options.target = dataTarget; + } + } + if (!scope.hasOwnProperty('title')) { + scope.title = ''; + } + attr.$observe('title', function(newValue) { + if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) { + var oldValue = scope.title; + scope.title = $sce.trustAsHtml(newValue); + if (angular.isDefined(oldValue)) { + $$rAF(function() { + if (tooltip) tooltip.$applyPlacement(); + }); + } + } + }); + attr.$observe('disabled', function(newValue) { + if (newValue && tooltip.$isShown) { + tooltip.hide(); + } + }); + if (attr.bsTooltip) { + scope.$watch(attr.bsTooltip, function(newValue, oldValue) { + if (angular.isObject(newValue)) { + angular.extend(scope, newValue); + } else { + scope.title = newValue; + } + if (angular.isDefined(oldValue)) { + $$rAF(function() { + if (tooltip) tooltip.$applyPlacement(); + }); + } + }, true); + } + if (attr.bsShow) { + scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!tooltip || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i); + if (newValue === true) { + tooltip.show(); + } else { + tooltip.hide(); + } + }); + } + if (attr.bsEnabled) { + scope.$watch(attr.bsEnabled, function(newValue, oldValue) { + if (!tooltip || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i); + if (newValue === false) { + tooltip.setEnabled(false); + } else { + tooltip.setEnabled(true); + } + }); + } + if (attr.viewport) { + scope.$watch(attr.viewport, function(newValue) { + if (!tooltip || !angular.isDefined(newValue)) return; + tooltip.setViewport(newValue); + }); + } + tooltip = $tooltip(element, options); + scope.$on('$destroy', function() { + if (tooltip) tooltip.destroy(); + options = null; + tooltip = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.timepicker', [ 'mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip' ]).provider('$bsTimepicker', function() { + var defaults = this.defaults = { + animation: 'am-fade', + defaultDate: 'auto', + prefixClass: 'timepicker', + placement: 'bottom-left', + templateUrl: 'timepicker/timepicker.tpl.html', + trigger: 'focus', + container: false, + keyboard: true, + html: false, + delay: 0, + useNative: true, + timeType: 'date', + timeFormat: 'shortTime', + timezone: null, + modelTimeFormat: null, + autoclose: false, + minTime: -Infinity, + maxTime: +Infinity, + length: 5, + hourStep: 1, + minuteStep: 5, + secondStep: 5, + roundDisplay: false, + iconUp: 'glyphicon glyphicon-chevron-up', + iconDown: 'glyphicon glyphicon-chevron-down', + arrowBehavior: 'pager' + }; + this.$get = ["$window", "$document", "$rootScope", "$sce", "$bsDateFormatter", "$bsTooltip", "$timeout", function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) { + var isNative = /(ip[ao]d|iphone|android)/gi.test($window.navigator.userAgent); + var isTouch = 'createTouch' in $window.document && isNative; + if (!defaults.lang) { + defaults.lang = $dateFormatter.getDefaultLocale(); + } + function timepickerFactory(element, controller, config) { + var $timepicker = $tooltip(element, angular.extend({}, defaults, config)); + var parentScope = config.scope; + var options = $timepicker.$options; + var scope = $timepicker.$scope; + var lang = options.lang; + var formatDate = function(date, format, timezone) { + return $dateFormatter.formatDate(date, format, lang, timezone); + }; + function floorMinutes(time) { + var coeff = 1e3 * 60 * options.minuteStep; + return new Date(Math.floor(time.getTime() / coeff) * coeff); + } + var selectedIndex = 0; + var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date(); + var startDate = controller.$dateValue || defaultDate; + var viewDate = { + hour: startDate.getHours(), + meridian: startDate.getHours() < 12, + minute: startDate.getMinutes(), + second: startDate.getSeconds(), + millisecond: startDate.getMilliseconds() + }; + var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang); + var hoursFormat = $dateFormatter.hoursFormat(format); + var timeSeparator = $dateFormatter.timeSeparator(format); + var minutesFormat = $dateFormatter.minutesFormat(format); + var secondsFormat = $dateFormatter.secondsFormat(format); + var showSeconds = $dateFormatter.showSeconds(format); + var showAM = $dateFormatter.showAM(format); + scope.$iconUp = options.iconUp; + scope.$iconDown = options.iconDown; + scope.$select = function(date, index) { + $timepicker.select(date, index); + }; + scope.$moveIndex = function(value, index) { + $timepicker.$moveIndex(value, index); + }; + scope.$switchMeridian = function(date) { + $timepicker.switchMeridian(date); + }; + $timepicker.update = function(date) { + if (angular.isDate(date) && !isNaN(date.getTime())) { + $timepicker.$date = date; + angular.extend(viewDate, { + hour: date.getHours(), + minute: date.getMinutes(), + second: date.getSeconds(), + millisecond: date.getMilliseconds() + }); + $timepicker.$build(); + } else if (!$timepicker.$isBuilt) { + $timepicker.$build(); + } + }; + $timepicker.select = function(date, index, keep) { + if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) { + controller.$dateValue = options.defaultDate === 'today' ? new Date() : new Date(1970, 0, 1); + } + if (!angular.isDate(date)) date = new Date(date); + if (index === 0) controller.$dateValue.setHours(date.getHours()); else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes()); else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds()); + controller.$setViewValue(angular.copy(controller.$dateValue)); + controller.$render(); + if (options.autoclose && !keep) { + $timeout(function() { + $timepicker.hide(true); + }); + } + }; + $timepicker.switchMeridian = function(date) { + if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) { + return; + } + var hours = (date || controller.$dateValue).getHours(); + controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12); + controller.$setViewValue(angular.copy(controller.$dateValue)); + controller.$render(); + }; + $timepicker.$build = function() { + var i; + var midIndex = scope.midIndex = parseInt(options.length / 2, 10); + var hours = []; + var hour; + for (i = 0; i < options.length; i++) { + hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep); + hours.push({ + date: hour, + label: formatDate(hour, hoursFormat), + selected: $timepicker.$date && $timepicker.$isSelected(hour, 0), + disabled: $timepicker.$isDisabled(hour, 0) + }); + } + var minutes = []; + var minute; + for (i = 0; i < options.length; i++) { + minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep); + minutes.push({ + date: minute, + label: formatDate(minute, minutesFormat), + selected: $timepicker.$date && $timepicker.$isSelected(minute, 1), + disabled: $timepicker.$isDisabled(minute, 1) + }); + } + var seconds = []; + var second; + for (i = 0; i < options.length; i++) { + second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep); + seconds.push({ + date: second, + label: formatDate(second, secondsFormat), + selected: $timepicker.$date && $timepicker.$isSelected(second, 2), + disabled: $timepicker.$isDisabled(second, 2) + }); + } + var rows = []; + for (i = 0; i < options.length; i++) { + if (showSeconds) { + rows.push([ hours[i], minutes[i], seconds[i] ]); + } else { + rows.push([ hours[i], minutes[i] ]); + } + } + scope.rows = rows; + scope.showSeconds = showSeconds; + scope.showAM = showAM; + scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12; + scope.timeSeparator = timeSeparator; + $timepicker.$isBuilt = true; + }; + $timepicker.$isSelected = function(date, index) { + if (!$timepicker.$date) return false; else if (index === 0) { + return date.getHours() === $timepicker.$date.getHours(); + } else if (index === 1) { + return date.getMinutes() === $timepicker.$date.getMinutes(); + } else if (index === 2) { + return date.getSeconds() === $timepicker.$date.getSeconds(); + } + }; + $timepicker.$isDisabled = function(date, index) { + var selectedTime; + if (index === 0) { + selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3; + } else if (index === 1) { + selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3; + } else if (index === 2) { + selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4; + } + return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1; + }; + scope.$arrowAction = function(value, index) { + if (options.arrowBehavior === 'picker') { + $timepicker.$setTimeByStep(value, index); + } else { + $timepicker.$moveIndex(value, index); + } + }; + $timepicker.$setTimeByStep = function(value, index) { + var newDate = new Date($timepicker.$date || startDate); + var hours = newDate.getHours(); + var minutes = newDate.getMinutes(); + var seconds = newDate.getSeconds(); + if (index === 0) { + newDate.setHours(hours - parseInt(options.hourStep, 10) * value); + } else if (index === 1) { + newDate.setMinutes(minutes - parseInt(options.minuteStep, 10) * value); + } else if (index === 2) { + newDate.setSeconds(seconds - parseInt(options.secondStep, 10) * value); + } + $timepicker.select(newDate, index, true); + }; + $timepicker.$moveIndex = function(value, index) { + var targetDate; + if (index === 0) { + targetDate = new Date(1970, 0, 1, viewDate.hour + value * options.length, viewDate.minute, viewDate.second); + angular.extend(viewDate, { + hour: targetDate.getHours() + }); + } else if (index === 1) { + targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + value * options.length * options.minuteStep, viewDate.second); + angular.extend(viewDate, { + minute: targetDate.getMinutes() + }); + } else if (index === 2) { + targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + value * options.length * options.secondStep); + angular.extend(viewDate, { + second: targetDate.getSeconds() + }); + } + $timepicker.$build(); + }; + $timepicker.$onMouseDown = function(evt) { + if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault(); + evt.stopPropagation(); + if (isTouch) { + var targetEl = angular.element(evt.target); + if (targetEl[0].nodeName.toLowerCase() !== 'button') { + targetEl = targetEl.parent(); + } + targetEl.triggerHandler('click'); + } + }; + $timepicker.$onKeyDown = function(evt) { + if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return; + evt.preventDefault(); + evt.stopPropagation(); + if (evt.keyCode === 13) { + $timepicker.hide(true); + return; + } + var newDate = new Date($timepicker.$date); + var hours = newDate.getHours(); + var hoursLength = formatDate(newDate, hoursFormat).length; + var minutes = newDate.getMinutes(); + var minutesLength = formatDate(newDate, minutesFormat).length; + var seconds = newDate.getSeconds(); + var secondsLength = formatDate(newDate, secondsFormat).length; + var sepLength = 1; + var lateralMove = /(37|39)/.test(evt.keyCode); + var count = 2 + showSeconds * 1 + showAM * 1; + if (lateralMove) { + if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1; else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0; + } + var selectRange = [ 0, hoursLength ]; + var incr = 0; + if (evt.keyCode === 38) incr = -1; + if (evt.keyCode === 40) incr = +1; + var isSeconds = selectedIndex === 2 && showSeconds; + var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds; + if (selectedIndex === 0) { + newDate.setHours(hours + incr * parseInt(options.hourStep, 10)); + hoursLength = formatDate(newDate, hoursFormat).length; + selectRange = [ 0, hoursLength ]; + } else if (selectedIndex === 1) { + newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10)); + minutesLength = formatDate(newDate, minutesFormat).length; + selectRange = [ hoursLength + sepLength, minutesLength ]; + } else if (isSeconds) { + newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10)); + secondsLength = formatDate(newDate, secondsFormat).length; + selectRange = [ hoursLength + sepLength + minutesLength + sepLength, secondsLength ]; + } else if (isMeridian) { + if (!lateralMove) $timepicker.switchMeridian(); + selectRange = [ hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2 ]; + } + $timepicker.select(newDate, selectedIndex, true); + createSelection(selectRange[0], selectRange[1]); + parentScope.$digest(); + }; + function createSelection(start, length) { + var end = start + length; + if (element[0].createTextRange) { + var selRange = element[0].createTextRange(); + selRange.collapse(true); + selRange.moveStart('character', start); + selRange.moveEnd('character', end); + selRange.select(); + } else if (element[0].setSelectionRange) { + element[0].setSelectionRange(start, end); + } else if (angular.isUndefined(element[0].selectionStart)) { + element[0].selectionStart = start; + element[0].selectionEnd = end; + } + } + function focusElement() { + element[0].focus(); + } + var _init = $timepicker.init; + $timepicker.init = function() { + if (isNative && options.useNative) { + element.prop('type', 'time'); + element.css('-webkit-appearance', 'textfield'); + return; + } else if (isTouch) { + element.prop('type', 'text'); + element.attr('readonly', 'true'); + element.on('click', focusElement); + } + _init(); + }; + var _destroy = $timepicker.destroy; + $timepicker.destroy = function() { + if (isNative && options.useNative) { + element.off('click', focusElement); + } + _destroy(); + }; + var _show = $timepicker.show; + $timepicker.show = function() { + if (!isTouch && element.attr('readonly') || element.attr('disabled')) return; + _show(); + $timeout(function() { + if ($timepicker.$element) $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown); + if (options.keyboard) { + if (element) element.on('keydown', $timepicker.$onKeyDown); + } + }, 0, false); + }; + var _hide = $timepicker.hide; + $timepicker.hide = function(blur) { + if (!$timepicker.$isShown) return; + if ($timepicker.$element) $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown); + if (options.keyboard) { + if (element) element.off('keydown', $timepicker.$onKeyDown); + } + _hide(blur); + }; + return $timepicker; + } + timepickerFactory.defaults = defaults; + return timepickerFactory; + } ]; + }).directive('bsTimepicker', ["$window", "$parse", "$q", "$bsDateFormatter", "$bsDateParser", "$bsTimepicker", function($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) { + var defaults = $timepicker.defaults; + var isNative = /(ip[ao]d|iphone|android)/gi.test($window.navigator.userAgent); + return { + restrict: 'EAC', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + var options = { + scope: scope + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent', 'defaultDate' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container', 'autoclose', 'useNative', 'roundDisplay' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) { + options[key] = false; + } + }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm'; + var timepicker = $timepicker(element, controller, options); + options = timepicker.$options; + var lang = options.lang; + var formatDate = function(date, format, timezone) { + return $dateFormatter.formatDate(date, format, lang, timezone); + }; + if (attr.bsShow) { + scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!timepicker || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i); + if (newValue === true) { + timepicker.show(); + } else { + timepicker.hide(); + } + }); + } + var dateParser = $dateParser({ + format: options.timeFormat, + lang: lang + }); + angular.forEach([ 'minTime', 'maxTime' ], function(key) { + if (angular.isDefined(attr[key])) { + attr.$observe(key, function(newValue) { + timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue); + if (!isNaN(timepicker.$options[key])) timepicker.$build(); + validateAgainstMinMaxTime(controller.$dateValue); + }); + } + }); + scope.$watch(attr.ngModel, function(newValue, oldValue) { + timepicker.update(controller.$dateValue); + }, true); + function validateAgainstMinMaxTime(parsedTime) { + if (!angular.isDate(parsedTime)) return; + var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime; + var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime; + var isValid = isMinValid && isMaxValid; + controller.$setValidity('date', isValid); + controller.$setValidity('min', isMinValid); + controller.$setValidity('max', isMaxValid); + if (!isValid) { + return; + } + controller.$dateValue = parsedTime; + } + controller.$parsers.unshift(function(viewValue) { + var date; + if (!viewValue) { + controller.$setValidity('date', true); + return null; + } + var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue); + if (!parsedTime || isNaN(parsedTime.getTime())) { + controller.$setValidity('date', false); + return undefined; + } + validateAgainstMinMaxTime(parsedTime); + if (options.timeType === 'string') { + date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true); + return formatDate(date, options.modelTimeFormat || options.timeFormat); + } + date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true); + if (options.timeType === 'number') { + return date.getTime(); + } else if (options.timeType === 'unix') { + return date.getTime() / 1e3; + } else if (options.timeType === 'iso') { + return date.toISOString(); + } + return new Date(date); + }); + controller.$formatters.push(function(modelValue) { + var date; + if (angular.isUndefined(modelValue) || modelValue === null) { + date = NaN; + } else if (angular.isDate(modelValue)) { + date = modelValue; + } else if (options.timeType === 'string') { + date = dateParser.parse(modelValue, null, options.modelTimeFormat); + } else if (options.timeType === 'unix') { + date = new Date(modelValue * 1e3); + } else { + date = new Date(modelValue); + } + controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone); + return getTimeFormattedString(); + }); + controller.$render = function() { + element.val(getTimeFormattedString()); + }; + function getTimeFormattedString() { + return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat); + } + scope.$on('$destroy', function() { + if (timepicker) timepicker.destroy(); + options = null; + timepicker = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.scrollspy', [ 'mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$bsScrollspy', function() { + var spies = this.$$spies = {}; + var defaults = this.defaults = { + debounce: 150, + throttle: 100, + offset: 100 + }; + this.$get = ["$window", "$document", "$rootScope", "bsDimensions", "bsDebounce", "bsThrottle", function($window, $document, $rootScope, dimensions, debounce, throttle) { + var windowEl = angular.element($window); + var docEl = angular.element($document.prop('documentElement')); + var bodyEl = angular.element($window.document.body); + function nodeName(element, name) { + return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase(); + } + function ScrollSpyFactory(config) { + var options = angular.extend({}, defaults, config); + if (!options.element) options.element = bodyEl; + var isWindowSpy = nodeName(options.element, 'body'); + var scrollEl = isWindowSpy ? windowEl : options.element; + var scrollId = isWindowSpy ? 'window' : options.id; + if (spies[scrollId]) { + spies[scrollId].$$count++; + return spies[scrollId]; + } + var $scrollspy = {}; + var unbindViewContentLoaded; + var unbindIncludeContentLoaded; + var trackedElements = $scrollspy.$trackedElements = []; + var sortedElements = []; + var activeTarget; + var debouncedCheckPosition; + var throttledCheckPosition; + var debouncedCheckOffsets; + var viewportHeight; + var scrollTop; + $scrollspy.init = function() { + this.$$count = 1; + debouncedCheckPosition = debounce(this.checkPosition, options.debounce); + throttledCheckPosition = throttle(this.checkPosition, options.throttle); + scrollEl.on('click', this.checkPositionWithEventLoop); + windowEl.on('resize', debouncedCheckPosition); + scrollEl.on('scroll', throttledCheckPosition); + debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce); + unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets); + unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets); + debouncedCheckOffsets(); + if (scrollId) { + spies[scrollId] = $scrollspy; + } + }; + $scrollspy.destroy = function() { + this.$$count--; + if (this.$$count > 0) { + return; + } + scrollEl.off('click', this.checkPositionWithEventLoop); + windowEl.off('resize', debouncedCheckPosition); + scrollEl.off('scroll', throttledCheckPosition); + unbindViewContentLoaded(); + unbindIncludeContentLoaded(); + if (scrollId) { + delete spies[scrollId]; + } + }; + $scrollspy.checkPosition = function() { + if (!sortedElements.length) return; + scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0; + viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight')); + if (scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) { + return $scrollspy.$activateElement(sortedElements[0]); + } + for (var i = sortedElements.length; i--; ) { + if (angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue; + if (activeTarget === sortedElements[i].target) continue; + if (scrollTop < sortedElements[i].offsetTop) continue; + if (sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue; + return $scrollspy.$activateElement(sortedElements[i]); + } + }; + $scrollspy.checkPositionWithEventLoop = function() { + setTimeout($scrollspy.checkPosition, 1); + }; + $scrollspy.$activateElement = function(element) { + if (activeTarget) { + var activeElement = $scrollspy.$getTrackedElement(activeTarget); + if (activeElement) { + activeElement.source.removeClass('active'); + if (nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) { + activeElement.source.parent().parent().removeClass('active'); + } + } + } + activeTarget = element.target; + element.source.addClass('active'); + if (nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) { + element.source.parent().parent().addClass('active'); + } + }; + $scrollspy.$getTrackedElement = function(target) { + return trackedElements.filter(function(obj) { + return obj.target === target; + })[0]; + }; + $scrollspy.checkOffsets = function() { + angular.forEach(trackedElements, function(trackedElement) { + var targetElement = document.querySelector(trackedElement.target); + trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null; + if (options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1; + }); + sortedElements = trackedElements.filter(function(el) { + return el.offsetTop !== null; + }).sort(function(a, b) { + return a.offsetTop - b.offsetTop; + }); + debouncedCheckPosition(); + }; + $scrollspy.trackElement = function(target, source) { + trackedElements.push({ + target: target, + source: source + }); + }; + $scrollspy.untrackElement = function(target, source) { + var toDelete; + for (var i = trackedElements.length; i--; ) { + if (trackedElements[i].target === target && trackedElements[i].source === source) { + toDelete = i; + break; + } + } + trackedElements.splice(toDelete, 1); + }; + $scrollspy.activate = function(i) { + trackedElements[i].addClass('active'); + }; + $scrollspy.init(); + return $scrollspy; + } + return ScrollSpyFactory; + } ]; + }).directive('bsScrollspy', ["$rootScope", "bsDebounce", "bsDimensions", "$bsScrollspy", function($rootScope, debounce, dimensions, $scrollspy) { + return { + restrict: 'EAC', + link: function postLink(scope, element, attr) { + var options = { + scope: scope + }; + angular.forEach([ 'offset', 'target' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var scrollspy = $scrollspy(options); + scrollspy.trackElement(options.target, element); + scope.$on('$destroy', function() { + if (scrollspy) { + scrollspy.untrackElement(options.target, element); + scrollspy.destroy(); + } + options = null; + scrollspy = null; + }); + } + }; + } ]).directive('bsScrollspyList', ["$rootScope", "bsDebounce", "bsDimensions", "$bsScrollspy", function($rootScope, debounce, dimensions, $scrollspy) { + return { + restrict: 'A', + compile: function postLink(element, attr) { + var children = element[0].querySelectorAll('li > a[href]'); + angular.forEach(children, function(child) { + var childEl = angular.element(child); + childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href')); + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.select', [ 'mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions' ]).provider('$bsSelect', function() { + var defaults = this.defaults = { + animation: 'am-fade', + prefixClass: 'select', + prefixEvent: '$select', + placement: 'bottom-left', + templateUrl: 'select/select.tpl.html', + trigger: 'focus', + container: false, + keyboard: true, + html: false, + delay: 0, + multiple: false, + allNoneButtons: false, + sort: true, + caretHtml: ' ', + placeholder: 'Choose among the following...', + allText: 'All', + noneText: 'None', + maxLength: 3, + maxLengthHtml: 'selected', + iconCheckmark: 'glyphicon glyphicon-ok', + toggle: false + }; + this.$get = ["$window", "$document", "$rootScope", "$bsTooltip", "$timeout", function($window, $document, $rootScope, $tooltip, $timeout) { + var isNative = /(ip[ao]d|iphone|android)/gi.test($window.navigator.userAgent); + var isTouch = 'createTouch' in $window.document && isNative; + function SelectFactory(element, controller, config) { + var $select = {}; + var options = angular.extend({}, defaults, config); + $select = $tooltip(element, options); + var scope = $select.$scope; + scope.$matches = []; + if (options.multiple) { + scope.$activeIndex = []; + } else { + scope.$activeIndex = -1; + } + scope.$isMultiple = options.multiple; + scope.$showAllNoneButtons = options.allNoneButtons && options.multiple; + scope.$iconCheckmark = options.iconCheckmark; + scope.$allText = options.allText; + scope.$noneText = options.noneText; + scope.$activate = function(index) { + scope.$$postDigest(function() { + $select.activate(index); + }); + }; + scope.$select = function(index, evt) { + scope.$$postDigest(function() { + $select.select(index); + }); + }; + scope.$isVisible = function() { + return $select.$isVisible(); + }; + scope.$isActive = function(index) { + return $select.$isActive(index); + }; + scope.$selectAll = function() { + for (var i = 0; i < scope.$matches.length; i++) { + if (!scope.$isActive(i)) { + scope.$select(i); + } + } + }; + scope.$selectNone = function() { + for (var i = 0; i < scope.$matches.length; i++) { + if (scope.$isActive(i)) { + scope.$select(i); + } + } + }; + $select.update = function(matches) { + scope.$matches = matches; + $select.$updateActiveIndex(); + }; + $select.activate = function(index) { + if (options.multiple) { + if ($select.$isActive(index)) { + scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1); + } else { + scope.$activeIndex.push(index); + } + if (options.sort) scope.$activeIndex.sort(function(a, b) { + return a - b; + }); + } else { + scope.$activeIndex = index; + } + return scope.$activeIndex; + }; + $select.select = function(index) { + if (angular.isUndefined(index) || index < 0 || index >= scope.$matches.length) { + return; + } + var value = scope.$matches[index].value; + scope.$apply(function() { + $select.activate(index); + if (options.multiple) { + controller.$setViewValue(scope.$activeIndex.map(function(index) { + if (angular.isUndefined(scope.$matches[index])) { + return null; + } + return scope.$matches[index].value; + })); + } else { + if (options.toggle) { + controller.$setViewValue(value === controller.$modelValue ? undefined : value); + } else { + controller.$setViewValue(value); + } + $select.hide(); + } + }); + scope.$emit(options.prefixEvent + '.select', value, index, $select); + if (angular.isDefined(options.onSelect) && angular.isFunction(options.onSelect)) { + options.onSelect(value, index, $select); + } + }; + $select.$updateActiveIndex = function() { + if (options.multiple) { + if (angular.isArray(controller.$modelValue)) { + scope.$activeIndex = controller.$modelValue.map(function(value) { + return $select.$getIndex(value); + }); + } else { + scope.$activeIndex = []; + } + } else { + if (angular.isDefined(controller.$modelValue) && scope.$matches.length) { + scope.$activeIndex = $select.$getIndex(controller.$modelValue); + } else { + scope.$activeIndex = -1; + } + } + }; + $select.$isVisible = function() { + if (!options.minLength || !controller) { + return scope.$matches.length; + } + return scope.$matches.length && controller.$viewValue.length >= options.minLength; + }; + $select.$isActive = function(index) { + if (options.multiple) { + return scope.$activeIndex.indexOf(index) !== -1; + } + return scope.$activeIndex === index; + }; + $select.$getIndex = function(value) { + var index; + for (index = scope.$matches.length; index--; ) { + if (angular.equals(scope.$matches[index].value, value)) break; + } + return index; + }; + $select.$onMouseDown = function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + if (isTouch) { + var targetEl = angular.element(evt.target); + targetEl.triggerHandler('click'); + } + }; + $select.$onKeyDown = function(evt) { + if (!/(9|13|38|40)/.test(evt.keyCode)) return; + if (evt.keyCode !== 9) { + evt.preventDefault(); + evt.stopPropagation(); + } + if (options.multiple && evt.keyCode === 9) { + return $select.hide(); + } + if (!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) { + return $select.select(scope.$activeIndex); + } + if (!options.multiple) { + if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--; else if (evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1; else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++; else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0; + scope.$digest(); + } + }; + $select.$isIE = function() { + var ua = $window.navigator.userAgent; + return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0; + }; + $select.$selectScrollFix = function(e) { + if ($document[0].activeElement.tagName === 'UL') { + e.preventDefault(); + e.stopImmediatePropagation(); + e.target.focus(); + } + }; + var _show = $select.show; + $select.show = function() { + _show(); + if (options.multiple) { + $select.$element.addClass('select-multiple'); + } + $timeout(function() { + $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown); + if (options.keyboard) { + element.on('keydown', $select.$onKeyDown); + } + }, 0, false); + }; + var _hide = $select.hide; + $select.hide = function() { + if (!options.multiple && angular.isUndefined(controller.$modelValue)) { + scope.$activeIndex = -1; + } + $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown); + if (options.keyboard) { + element.off('keydown', $select.$onKeyDown); + } + _hide(true); + }; + return $select; + } + SelectFactory.defaults = defaults; + return SelectFactory; + } ]; + }).directive('bsSelect', ["$window", "$parse", "$q", "$bsSelect", "$bsParseOptions", function($window, $parse, $q, $select, $parseOptions) { + var defaults = $select.defaults; + return { + restrict: 'EAC', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + var options = { + scope: scope, + placeholder: defaults.placeholder + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent', 'toggle' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container', 'allNoneButtons', 'sort' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) { + options[key] = false; + } + }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide', 'onSelect' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + var dataMultiple = element.attr('data-multiple'); + if (angular.isDefined(dataMultiple)) { + if (falseValueRegExp.test(dataMultiple)) { + options.multiple = false; + } else { + options.multiple = dataMultiple; + } + } + if (element[0].nodeName.toLowerCase() === 'select') { + var inputEl = element; + inputEl.css('display', 'none'); + element = angular.element(''); + inputEl.after(element); + } + var parsedOptions = $parseOptions(attr.bsOptions); + var select = $select(element, controller, options); + if (select.$isIE()) { + element[0].addEventListener('blur', select.$selectScrollFix); + } + var watchedOptions = parsedOptions.$match[7].replace(/\|.+/, '').trim(); + scope.$watch(watchedOptions, function(newValue, oldValue) { + parsedOptions.valuesFn(scope, controller).then(function(values) { + select.update(values); + controller.$render(); + }); + }, true); + scope.$watch(attr.ngModel, function(newValue, oldValue) { + select.$updateActiveIndex(); + controller.$render(); + }, true); + controller.$render = function() { + var selected; + var index; + if (options.multiple && angular.isArray(controller.$modelValue)) { + selected = controller.$modelValue.map(function(value) { + index = select.$getIndex(value); + return index !== -1 ? select.$scope.$matches[index].label : false; + }).filter(angular.isDefined); + if (selected.length > (options.maxLength || defaults.maxLength)) { + selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml); + } else { + selected = selected.join(', '); + } + } else { + index = select.$getIndex(controller.$modelValue); + selected = index !== -1 ? select.$scope.$matches[index].label : false; + } + element.html((selected || options.placeholder) + (options.caretHtml || defaults.caretHtml)); + }; + if (options.multiple) { + controller.$isEmpty = function(value) { + return !value || value.length === 0; + }; + } + scope.$on('$destroy', function() { + if (select) select.destroy(); + options = null; + select = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.popover', [ 'mgcrea.ngStrap.tooltip' ]).provider('$bsPopover', function() { + var defaults = this.defaults = { + animation: 'am-fade', + customClass: '', + container: false, + target: false, + placement: 'right', + templateUrl: 'popover/popover.tpl.html', + contentTemplate: false, + trigger: 'click', + keyboard: true, + html: false, + title: '', + content: '', + delay: 0, + autoClose: false + }; + this.$get = ["$bsTooltip", function($tooltip) { + function PopoverFactory(element, config) { + var options = angular.extend({}, defaults, config); + var $popover = $tooltip(element, options); + if (options.content) { + $popover.$scope.content = options.content; + } + return $popover; + } + return PopoverFactory; + } ]; + }).directive('bsPopover', ["$window", "$sce", "$bsPopover", function($window, $sce, $popover) { + var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout; + return { + restrict: 'EAC', + scope: true, + link: function postLink(scope, element, attr) { + var popover; + var options = { + scope: scope + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container', 'autoClose' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + var dataTarget = element.attr('data-target'); + if (angular.isDefined(dataTarget)) { + if (falseValueRegExp.test(dataTarget)) { + options.target = false; + } else { + options.target = dataTarget; + } + } + angular.forEach([ 'title', 'content' ], function(key) { + if (attr[key]) { + attr.$observe(key, function(newValue, oldValue) { + scope[key] = $sce.trustAsHtml(newValue); + if (angular.isDefined(oldValue)) { + requestAnimationFrame(function() { + if (popover) popover.$applyPlacement(); + }); + } + }); + } + }); + if (attr.bsPopover) { + scope.$watch(attr.bsPopover, function(newValue, oldValue) { + if (angular.isObject(newValue)) { + angular.extend(scope, newValue); + } else { + scope.content = newValue; + } + if (angular.isDefined(oldValue)) { + requestAnimationFrame(function() { + if (popover) popover.$applyPlacement(); + }); + } + }, true); + } + if (attr.bsShow) { + scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!popover || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i); + if (newValue === true) { + popover.show(); + } else { + popover.hide(); + } + }); + } + if (attr.viewport) { + scope.$watch(attr.viewport, function(newValue) { + if (!popover || !angular.isDefined(newValue)) return; + popover.setViewport(newValue); + }); + } + popover = $popover(element, options); + scope.$on('$destroy', function() { + if (popover) popover.destroy(); + options = null; + popover = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.navbar', []).provider('$bsNavbar', function() { + var defaults = this.defaults = { + activeClass: 'active', + routeAttr: 'data-match-route', + strict: false + }; + this.$get = function() { + return { + defaults: defaults + }; + }; + }).directive('bsNavbar', ["$window", "$location", "$bsNavbar", function($window, $location, $navbar) { + var defaults = $navbar.defaults; + return { + restrict: 'A', + link: function postLink(scope, element, attr, controller) { + var options = angular.copy(defaults); + angular.forEach(Object.keys(defaults), function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + scope.$watch(function() { + return $location.path(); + }, function(newValue, oldValue) { + var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']'); + angular.forEach(liElements, function(li) { + var liElement = angular.element(li); + var pattern = liElement.attr(options.routeAttr).replace('/', '\\/'); + if (options.strict) { + pattern = '^' + pattern + '$'; + } + var regexp = new RegExp(pattern, 'i'); + if (regexp.test(newValue)) { + liElement.addClass(options.activeClass); + } else { + liElement.removeClass(options.activeClass); + } + }); + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.modal', [ 'mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$bsModal', function() { + var defaults = this.defaults = { + animation: 'am-fade', + backdropAnimation: 'am-fade', + customClass: '', + prefixClass: 'modal', + prefixEvent: 'modal', + placement: 'top', + templateUrl: 'modal/modal.tpl.html', + template: '', + contentTemplate: false, + container: false, + element: null, + backdrop: true, + keyboard: true, + html: false, + show: true, + size: null + }; + this.$get = ["$window", "$rootScope", "$bsCompiler", "$animate", "$timeout", "$sce", "bsDimensions", function($window, $rootScope, $bsCompiler, $animate, $timeout, $sce, dimensions) { + var forEach = angular.forEach; + var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout; + var bodyElement = angular.element($window.document.body); + var backdropCount = 0; + var dialogBaseZindex = 1050; + var backdropBaseZindex = 1040; + var validSizes = { + lg: 'modal-lg', + sm: 'modal-sm' + }; + function ModalFactory(config) { + var $modal = {}; + var options = $modal.$options = angular.extend({}, defaults, config); + var promise = $modal.$promise = $bsCompiler.compile(options); + var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new(); + if (!options.element && !options.container) { + options.container = 'body'; + } + $modal.$id = options.id || options.element && options.element.attr('id') || ''; + forEach([ 'title', 'content' ], function(key) { + if (options[key]) scope[key] = $sce.trustAsHtml(options[key]); + }); + scope.$hide = function() { + scope.$$postDigest(function() { + $modal.hide(); + }); + }; + scope.$show = function() { + scope.$$postDigest(function() { + $modal.show(); + }); + }; + scope.$toggle = function() { + scope.$$postDigest(function() { + $modal.toggle(); + }); + }; + $modal.$isShown = scope.$isShown = false; + var compileData; + var modalElement; + var modalScope; + var backdropElement = angular.element('
'); + backdropElement.css({ + position: 'fixed', + top: '0px', + left: '0px', + bottom: '0px', + right: '0px' + }); + promise.then(function(data) { + compileData = data; + $modal.init(); + }); + $modal.init = function() { + if (options.show) { + scope.$$postDigest(function() { + $modal.show(); + }); + } + }; + $modal.destroy = function() { + destroyModalElement(); + if (backdropElement) { + backdropElement.remove(); + backdropElement = null; + } + scope.$destroy(); + }; + $modal.show = function() { + if ($modal.$isShown) return; + var parent; + var after; + if (angular.isElement(options.container)) { + parent = options.container; + after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null; + } else { + if (options.container) { + parent = findElement(options.container); + after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null; + } else { + parent = null; + after = options.element; + } + } + if (modalElement) destroyModalElement(); + modalScope = $modal.$scope.$new(); + modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {}); + if (options.backdrop) { + modalElement.css({ + 'z-index': dialogBaseZindex + backdropCount * 20 + }); + backdropElement.css({ + 'z-index': backdropBaseZindex + backdropCount * 20 + }); + backdropCount++; + } + if (scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) { + return; + } + if (angular.isDefined(options.onBeforeShow) && angular.isFunction(options.onBeforeShow)) { + options.onBeforeShow($modal); + } + modalElement.css({ + display: 'block' + }).addClass(options.placement); + if (options.customClass) { + modalElement.addClass(options.customClass); + } + if (options.size && validSizes[options.size]) { + angular.element(findElement('.modal-dialog', modalElement[0])).addClass(validSizes[options.size]); + } + if (options.animation) { + if (options.backdrop) { + backdropElement.addClass(options.backdropAnimation); + } + modalElement.addClass(options.animation); + } + if (options.backdrop) { + $animate.enter(backdropElement, bodyElement, null); + } + if (angular.version.minor <= 2) { + $animate.enter(modalElement, parent, after, enterAnimateCallback); + } else { + $animate.enter(modalElement, parent, after).then(enterAnimateCallback); + } + $modal.$isShown = scope.$isShown = true; + safeDigest(scope); + var el = modalElement[0]; + requestAnimationFrame(function() { + el.focus(); + }); + bodyElement.addClass(options.prefixClass + '-open'); + if (options.animation) { + bodyElement.addClass(options.prefixClass + '-with-' + options.animation); + } + bindBackdropEvents(); + bindKeyboardEvents(); + }; + function enterAnimateCallback() { + scope.$emit(options.prefixEvent + '.show', $modal); + if (angular.isDefined(options.onShow) && angular.isFunction(options.onShow)) { + options.onShow($modal); + } + } + $modal.hide = function() { + if (!$modal.$isShown) return; + if (scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) { + return; + } + if (angular.isDefined(options.onBeforeHide) && angular.isFunction(options.onBeforeHide)) { + options.onBeforeHide($modal); + } + if (angular.version.minor <= 2) { + $animate.leave(modalElement, leaveAnimateCallback); + } else { + $animate.leave(modalElement).then(leaveAnimateCallback); + } + if (options.backdrop) { + backdropCount--; + $animate.leave(backdropElement); + } + $modal.$isShown = scope.$isShown = false; + safeDigest(scope); + unbindBackdropEvents(); + unbindKeyboardEvents(); + }; + function leaveAnimateCallback() { + scope.$emit(options.prefixEvent + '.hide', $modal); + if (angular.isDefined(options.onHide) && angular.isFunction(options.onHide)) { + options.onHide($modal); + } + bodyElement.removeClass(options.prefixClass + '-open'); + if (options.animation) { + bodyElement.removeClass(options.prefixClass + '-with-' + options.animation); + } + } + $modal.toggle = function() { + if ($modal.$isShown) { + $modal.hide(); + } else { + $modal.show(); + } + }; + $modal.focus = function() { + modalElement[0].focus(); + }; + $modal.$onKeyUp = function(evt) { + if (evt.which === 27 && $modal.$isShown) { + $modal.hide(); + evt.stopPropagation(); + } + }; + function bindBackdropEvents() { + if (options.backdrop) { + modalElement.on('click', hideOnBackdropClick); + backdropElement.on('click', hideOnBackdropClick); + backdropElement.on('wheel', preventEventDefault); + } + } + function unbindBackdropEvents() { + if (options.backdrop) { + modalElement.off('click', hideOnBackdropClick); + backdropElement.off('click', hideOnBackdropClick); + backdropElement.off('wheel', preventEventDefault); + } + } + function bindKeyboardEvents() { + if (options.keyboard) { + modalElement.on('keyup', $modal.$onKeyUp); + } + } + function unbindKeyboardEvents() { + if (options.keyboard) { + modalElement.off('keyup', $modal.$onKeyUp); + } + } + function hideOnBackdropClick(evt) { + if (evt.target !== evt.currentTarget) return; + if (options.backdrop === 'static') { + $modal.focus(); + } else { + $modal.hide(); + } + } + function preventEventDefault(evt) { + evt.preventDefault(); + } + function destroyModalElement() { + if ($modal.$isShown && modalElement !== null) { + unbindBackdropEvents(); + unbindKeyboardEvents(); + } + if (modalScope) { + modalScope.$destroy(); + modalScope = null; + } + if (modalElement) { + modalElement.remove(); + modalElement = $modal.$element = null; + } + } + return $modal; + } + function safeDigest(scope) { + scope.$$phase || scope.$root && scope.$root.$$phase || scope.$digest(); + } + function findElement(query, element) { + return angular.element((element || document).querySelectorAll(query)); + } + return ModalFactory; + } ]; + }).directive('bsModal', ["$window", "$sce", "$parse", "$bsModal", function($window, $sce, $parse, $modal) { + return { + restrict: 'EAC', + scope: true, + link: function postLink(scope, element, attr, transclusion) { + var options = { + scope: scope, + element: element, + show: false + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass', 'customClass', 'modalClass', 'size' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + if (options.modalClass) { + options.customClass = options.modalClass; + } + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'backdrop', 'keyboard', 'html', 'container' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + angular.forEach([ 'title', 'content' ], function(key) { + if (attr[key]) { + attr.$observe(key, function(newValue, oldValue) { + scope[key] = $sce.trustAsHtml(newValue); + }); + } + }); + if (attr.bsModal) { + scope.$watch(attr.bsModal, function(newValue, oldValue) { + if (angular.isObject(newValue)) { + angular.extend(scope, newValue); + } else { + scope.content = newValue; + } + }, true); + } + var modal = $modal(options); + element.on(attr.trigger || 'click', modal.toggle); + scope.$on('$destroy', function() { + if (modal) modal.destroy(); + options = null; + modal = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.dropdown', [ 'mgcrea.ngStrap.tooltip' ]).provider('$bsDropdown', function() { + var defaults = this.defaults = { + animation: 'am-fade', + prefixClass: 'dropdown', + prefixEvent: 'dropdown', + placement: 'bottom-left', + templateUrl: 'dropdown/dropdown.tpl.html', + trigger: 'click', + container: false, + keyboard: true, + html: false, + delay: 0 + }; + this.$get = ["$window", "$rootScope", "$bsTooltip", "$timeout", function($window, $rootScope, $tooltip, $timeout) { + var bodyEl = angular.element($window.document.body); + var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector; + function DropdownFactory(element, config) { + var $dropdown = {}; + var options = angular.extend({}, defaults, config); + $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new(); + $dropdown = $tooltip(element, options); + var parentEl = element.parent(); + $dropdown.$onKeyDown = function(evt) { + if (!/(38|40)/.test(evt.keyCode)) return; + evt.preventDefault(); + evt.stopPropagation(); + var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a')); + if (!items.length) return; + var index; + angular.forEach(items, function(el, i) { + if (matchesSelector && matchesSelector.call(el, ':focus')) index = i; + }); + if (evt.keyCode === 38 && index > 0) index--; else if (evt.keyCode === 40 && index < items.length - 1) index++; else if (angular.isUndefined(index)) index = 0; + items.eq(index)[0].focus(); + }; + var show = $dropdown.show; + $dropdown.show = function() { + show(); + $timeout(function() { + if (options.keyboard && $dropdown.$element) $dropdown.$element.on('keydown', $dropdown.$onKeyDown); + bodyEl.on('click', onBodyClick); + }, 0, false); + if (parentEl.hasClass('dropdown')) parentEl.addClass('open'); + }; + var hide = $dropdown.hide; + $dropdown.hide = function() { + if (!$dropdown.$isShown) return; + if (options.keyboard && $dropdown.$element) $dropdown.$element.off('keydown', $dropdown.$onKeyDown); + bodyEl.off('click', onBodyClick); + if (parentEl.hasClass('dropdown')) parentEl.removeClass('open'); + hide(); + }; + var destroy = $dropdown.destroy; + $dropdown.destroy = function() { + bodyEl.off('click', onBodyClick); + destroy(); + }; + function onBodyClick(evt) { + if (evt.target === element[0]) return; + return evt.target !== element[0] && $dropdown.hide(); + } + return $dropdown; + } + return DropdownFactory; + } ]; + }).directive('bsDropdown', ["$window", "$sce", "$bsDropdown", function($window, $sce, $dropdown) { + return { + restrict: 'EAC', + scope: true, + compile: function(tElement, tAttrs) { + if (!tAttrs.bsDropdown) { + var nextSibling = tElement[0].nextSibling; + while (nextSibling && nextSibling.nodeType !== 1) { + nextSibling = nextSibling.nextSibling; + } + if (nextSibling && nextSibling.className.split(' ').indexOf('dropdown-menu') >= 0) { + tAttrs.template = nextSibling.outerHTML; + tAttrs.templateUrl = undefined; + nextSibling.parentNode.removeChild(nextSibling); + } + } + return function postLink(scope, element, attr) { + var options = { + scope: scope + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id', 'autoClose' ], function(key) { + if (angular.isDefined(tAttrs[key])) options[key] = tAttrs[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + if (attr.bsDropdown) { + scope.$watch(attr.bsDropdown, function(newValue, oldValue) { + scope.content = newValue; + }, true); + } + var dropdown = $dropdown(element, options); + if (attr.bsShow) { + scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!dropdown || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i); + if (newValue === true) { + dropdown.show(); + } else { + dropdown.hide(); + } + }); + } + scope.$on('$destroy', function() { + if (dropdown) dropdown.destroy(); + options = null; + dropdown = null; + }); + }; + } + }; + } ]); + if (angular.version.minor < 3 && angular.version.dot < 14) { + angular.module('ng').factory('$$rAF', ["$window", "$timeout", function($window, $timeout) { + var requestAnimationFrame = $window.requestAnimationFrame || $window.webkitRequestAnimationFrame || $window.mozRequestAnimationFrame; + var cancelAnimationFrame = $window.cancelAnimationFrame || $window.webkitCancelAnimationFrame || $window.mozCancelAnimationFrame || $window.webkitCancelRequestAnimationFrame; + var rafSupported = !!requestAnimationFrame; + var raf = rafSupported ? function(fn) { + var id = requestAnimationFrame(fn); + return function() { + cancelAnimationFrame(id); + }; + } : function(fn) { + var timer = $timeout(fn, 16.66, false); + return function() { + $timeout.cancel(timer); + }; + }; + raf.supported = rafSupported; + return raf; + } ]); + } + angular.module('mgcrea.ngStrap.helpers.parseOptions', []).provider('$bsParseOptions', function() { + var defaults = this.defaults = { + regexp: /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/ + }; + this.$get = ["$parse", "$q", function($parse, $q) { + function ParseOptionsFactory(attr, config) { + var $parseOptions = {}; + var options = angular.extend({}, defaults, config); + $parseOptions.$values = []; + var match; + var displayFn; + var valueName; + var keyName; + var groupByFn; + var valueFn; + var valuesFn; + $parseOptions.init = function() { + $parseOptions.$match = match = attr.match(options.regexp); + displayFn = $parse(match[2] || match[1]); + valueName = match[4] || match[6]; + keyName = match[5]; + groupByFn = $parse(match[3] || ''); + valueFn = $parse(match[2] ? match[1] : valueName); + valuesFn = $parse(match[7]); + }; + $parseOptions.valuesFn = function(scope, controller) { + return $q.when(valuesFn(scope, controller)).then(function(values) { + if (!angular.isArray(values)) { + values = []; + } + $parseOptions.$values = values.length ? parseValues(values, scope) : []; + return $parseOptions.$values; + }); + }; + $parseOptions.displayValue = function(modelValue) { + var scope = {}; + scope[valueName] = modelValue; + return displayFn(scope); + }; + function parseValues(values, scope) { + return values.map(function(match, index) { + var locals = {}; + var label; + var value; + locals[valueName] = match; + label = displayFn(scope, locals); + value = valueFn(scope, locals); + return { + label: label, + value: value, + index: index + }; + }); + } + $parseOptions.init(); + return $parseOptions; + } + return ParseOptionsFactory; + } ]; + }); + angular.module('mgcrea.ngStrap.helpers.dimensions', []).factory('bsDimensions', function() { + var fn = {}; + var nodeName = fn.nodeName = function(element, name) { + return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase(); + }; + fn.css = function(element, prop, extra) { + var value; + if (element.currentStyle) { + value = element.currentStyle[prop]; + } else if (window.getComputedStyle) { + value = window.getComputedStyle(element)[prop]; + } else { + value = element.style[prop]; + } + return extra === true ? parseFloat(value) || 0 : value; + }; + fn.offset = function(element) { + var boxRect = element.getBoundingClientRect(); + var docElement = element.ownerDocument; + return { + width: boxRect.width || element.offsetWidth, + height: boxRect.height || element.offsetHeight, + top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0), + left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0) + }; + }; + fn.setOffset = function(element, options, i) { + var curPosition; + var curLeft; + var curCSSTop; + var curTop; + var curOffset; + var curCSSLeft; + var calculatePosition; + var position = fn.css(element, 'position'); + var curElem = angular.element(element); + var props = {}; + if (position === 'static') { + element.style.position = 'relative'; + } + curOffset = fn.offset(element); + curCSSTop = fn.css(element, 'top'); + curCSSLeft = fn.css(element, 'left'); + calculatePosition = (position === 'absolute' || position === 'fixed') && (curCSSTop + curCSSLeft).indexOf('auto') > -1; + if (calculatePosition) { + curPosition = fn.position(element); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat(curCSSTop) || 0; + curLeft = parseFloat(curCSSLeft) || 0; + } + if (angular.isFunction(options)) { + options = options.call(element, i, curOffset); + } + if (options.top !== null) { + props.top = options.top - curOffset.top + curTop; + } + if (options.left !== null) { + props.left = options.left - curOffset.left + curLeft; + } + if ('using' in options) { + options.using.call(curElem, props); + } else { + curElem.css({ + top: props.top + 'px', + left: props.left + 'px' + }); + } + }; + fn.position = function(element) { + var offsetParentRect = { + top: 0, + left: 0 + }; + var offsetParentEl; + var offset; + if (fn.css(element, 'position') === 'fixed') { + offset = element.getBoundingClientRect(); + } else { + offsetParentEl = offsetParentElement(element); + offset = fn.offset(element); + if (!nodeName(offsetParentEl, 'html')) { + offsetParentRect = fn.offset(offsetParentEl); + } + offsetParentRect.top += fn.css(offsetParentEl, 'borderTopWidth', true); + offsetParentRect.left += fn.css(offsetParentEl, 'borderLeftWidth', true); + } + return { + width: element.offsetWidth, + height: element.offsetHeight, + top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true), + left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true) + }; + }; + function offsetParentElement(element) { + var docElement = element.ownerDocument; + var offsetParent = element.offsetParent || docElement; + if (nodeName(offsetParent, '#document')) return docElement.documentElement; + while (offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') { + offsetParent = offsetParent.offsetParent; + } + return offsetParent || docElement.documentElement; + } + fn.height = function(element, outer) { + var value = element.offsetHeight; + if (outer) { + value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true); + } else { + value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true); + } + return value; + }; + fn.width = function(element, outer) { + var value = element.offsetWidth; + if (outer) { + value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true); + } else { + value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true); + } + return value; + }; + return fn; + }); + angular.module('mgcrea.ngStrap.helpers.debounce', []).factory('bsDebounce', ["$timeout", function($timeout) { + return function(func, wait, immediate) { + var timeout = null; + return function() { + var context = this; + var args = arguments; + var callNow = immediate && !timeout; + if (timeout) { + $timeout.cancel(timeout); + } + timeout = $timeout(function later() { + timeout = null; + if (!immediate) { + func.apply(context, args); + } + }, wait, false); + if (callNow) { + func.apply(context, args); + } + return timeout; + }; + }; + } ]).factory('bsThrottle', ["$timeout", function($timeout) { + return function(func, wait, options) { + var timeout = null; + if (!options) options = {}; + return function() { + var context = this; + var args = arguments; + if (!timeout) { + if (options.leading !== false) { + func.apply(context, args); + } + timeout = $timeout(function later() { + timeout = null; + if (options.trailing !== false) { + func.apply(context, args); + } + }, wait, false); + } + }; + }; + } ]); + angular.module('mgcrea.ngStrap.helpers.dateParser', []).provider('$bsDateParser', ["$localeProvider", function($localeProvider) { + function ParseDate() { + this.year = 1970; + this.month = 0; + this.day = 1; + this.hours = 0; + this.minutes = 0; + this.seconds = 0; + this.milliseconds = 0; + } + ParseDate.prototype.setMilliseconds = function(value) { + this.milliseconds = value; + }; + ParseDate.prototype.setSeconds = function(value) { + this.seconds = value; + }; + ParseDate.prototype.setMinutes = function(value) { + this.minutes = value; + }; + ParseDate.prototype.setHours = function(value) { + this.hours = value; + }; + ParseDate.prototype.getHours = function() { + return this.hours; + }; + ParseDate.prototype.setDate = function(value) { + this.day = value; + }; + ParseDate.prototype.setMonth = function(value) { + this.month = value; + }; + ParseDate.prototype.setFullYear = function(value) { + this.year = value; + }; + ParseDate.prototype.fromDate = function(value) { + this.year = value.getFullYear(); + this.month = value.getMonth(); + this.day = value.getDate(); + this.hours = value.getHours(); + this.minutes = value.getMinutes(); + this.seconds = value.getSeconds(); + this.milliseconds = value.getMilliseconds(); + return this; + }; + ParseDate.prototype.toDate = function() { + return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds); + }; + var proto = ParseDate.prototype; + function noop() {} + function isNumeric(n) { + return !isNaN(parseFloat(n)) && isFinite(n); + } + function indexOfCaseInsensitive(array, value) { + var len = array.length; + var str = value.toString().toLowerCase(); + for (var i = 0; i < len; i++) { + if (array[i].toLowerCase() === str) { + return i; + } + } + return -1; + } + var defaults = this.defaults = { + format: 'shortDate', + strict: false + }; + this.$get = ["$locale", "dateFilter", function($locale, dateFilter) { + var DateParserFactory = function(config) { + var options = angular.extend({}, defaults, config); + var $dateParser = {}; + var regExpMap = { + sss: '[0-9]{3}', + ss: '[0-5][0-9]', + s: options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]', + mm: '[0-5][0-9]', + m: options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]', + HH: '[01][0-9]|2[0-3]', + H: options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]', + hh: '[0][1-9]|[1][012]', + h: options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]', + a: 'AM|PM', + EEEE: $locale.DATETIME_FORMATS.DAY.join('|'), + EEE: $locale.DATETIME_FORMATS.SHORTDAY.join('|'), + dd: '0[1-9]|[12][0-9]|3[01]', + d: options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]', + MMMM: $locale.DATETIME_FORMATS.MONTH.join('|'), + MMM: $locale.DATETIME_FORMATS.SHORTMONTH.join('|'), + MM: '0[1-9]|1[012]', + M: options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]', + yyyy: '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}', + yy: '[0-9]{2}', + y: options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}' + }; + var setFnMap = { + sss: proto.setMilliseconds, + ss: proto.setSeconds, + s: proto.setSeconds, + mm: proto.setMinutes, + m: proto.setMinutes, + HH: proto.setHours, + H: proto.setHours, + hh: proto.setHours, + h: proto.setHours, + EEEE: noop, + EEE: noop, + dd: proto.setDate, + d: proto.setDate, + a: function(value) { + var hours = this.getHours() % 12; + return this.setHours(value.match(/pm/i) ? hours + 12 : hours); + }, + MMMM: function(value) { + return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); + }, + MMM: function(value) { + return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); + }, + MM: function(value) { + return this.setMonth(1 * value - 1); + }, + M: function(value) { + return this.setMonth(1 * value - 1); + }, + yyyy: proto.setFullYear, + yy: function(value) { + return this.setFullYear(2e3 + 1 * value); + }, + y: function(value) { + return 1 * value <= 50 && value.length === 2 ? this.setFullYear(2e3 + 1 * value) : this.setFullYear(1 * value); + } + }; + var regex; + var setMap; + $dateParser.init = function() { + $dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format; + regex = regExpForFormat($dateParser.$format); + setMap = setMapForFormat($dateParser.$format); + }; + $dateParser.isValid = function(date) { + if (angular.isDate(date)) return !isNaN(date.getTime()); + return regex.test(date); + }; + $dateParser.parse = function(value, baseDate, format, timezone) { + if (format) format = $locale.DATETIME_FORMATS[format] || format; + if (angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format, timezone); + var formatRegex = format ? regExpForFormat(format) : regex; + var formatSetMap = format ? setMapForFormat(format) : setMap; + var matches = formatRegex.exec(value); + if (!matches) return false; + var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0)); + for (var i = 0; i < matches.length - 1; i++) { + if (formatSetMap[i]) formatSetMap[i].call(date, matches[i + 1]); + } + var newDate = date.toDate(); + if (parseInt(date.day, 10) !== newDate.getDate()) { + return false; + } + return newDate; + }; + $dateParser.getDateForAttribute = function(key, value) { + var date; + if (value === 'today') { + var today = new Date(); + date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, key === 'minDate' ? 0 : -1); + } else if (angular.isString(value) && value.match(/^".+"$/)) { + date = new Date(value.substr(1, value.length - 2)); + } else if (isNumeric(value)) { + date = new Date(parseInt(value, 10)); + } else if (angular.isString(value) && value.length === 0) { + date = key === 'minDate' ? -Infinity : +Infinity; + } else { + date = new Date(value); + } + return date; + }; + $dateParser.getTimeForAttribute = function(key, value) { + var time; + if (value === 'now') { + time = new Date().setFullYear(1970, 0, 1); + } else if (angular.isString(value) && value.match(/^".+"$/)) { + time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1); + } else if (isNumeric(value)) { + time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1); + } else if (angular.isString(value) && value.length === 0) { + time = key === 'minTime' ? -Infinity : +Infinity; + } else { + time = $dateParser.parse(value, new Date(1970, 0, 1, 0)); + } + return time; + }; + $dateParser.daylightSavingAdjust = function(date) { + if (!date) { + return null; + } + date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); + return date; + }; + $dateParser.timezoneOffsetAdjust = function(date, timezone, undo) { + if (!date) { + return null; + } + if (timezone && timezone === 'UTC') { + date = new Date(date.getTime()); + date.setMinutes(date.getMinutes() + (undo ? -1 : 1) * date.getTimezoneOffset()); + } + return date; + }; + function regExpForFormat(format) { + var re = buildDateAbstractRegex(format); + return buildDateParseRegex(re); + } + function buildDateAbstractRegex(format) { + var escapedFormat = escapeReservedSymbols(format); + var escapedLiteralFormat = escapedFormat.replace(/''/g, '\\\''); + var literalRegex = /('(?:\\'|.)*?')/; + var formatParts = escapedLiteralFormat.split(literalRegex); + var dateElements = Object.keys(regExpMap); + var dateRegexParts = []; + angular.forEach(formatParts, function(part) { + if (isFormatStringLiteral(part)) { + part = trimLiteralEscapeChars(part); + } else { + for (var i = 0; i < dateElements.length; i++) { + part = part.split(dateElements[i]).join('${' + i + '}'); + } + } + dateRegexParts.push(part); + }); + return dateRegexParts.join(''); + } + function escapeReservedSymbols(text) { + return text.replace(/\\/g, '[\\\\]').replace(/-/g, '[-]').replace(/\./g, '[.]').replace(/\*/g, '[*]').replace(/\+/g, '[+]').replace(/\?/g, '[?]').replace(/\$/g, '[$]').replace(/\^/g, '[^]').replace(/\//g, '[/]').replace(/\\s/g, '[\\s]'); + } + function isFormatStringLiteral(text) { + return /^'.*'$/.test(text); + } + function trimLiteralEscapeChars(text) { + return text.replace(/^'(.*)'$/, '$1'); + } + function buildDateParseRegex(abstractRegex) { + var dateElements = Object.keys(regExpMap); + var re = abstractRegex; + for (var i = 0; i < dateElements.length; i++) { + re = re.split('${' + i + '}').join('(' + regExpMap[dateElements[i]] + ')'); + } + return new RegExp('^' + re + '$', [ 'i' ]); + } + function setMapForFormat(format) { + var re = buildDateAbstractRegex(format); + return buildDateParseValuesMap(re); + } + function buildDateParseValuesMap(abstractRegex) { + var dateElements = Object.keys(regExpMap); + var valuesRegex = new RegExp('\\${(\\d+)}', 'g'); + var valuesMatch; + var keyIndex; + var valueKey; + var valueFunction; + var valuesFunctionMap = []; + while ((valuesMatch = valuesRegex.exec(abstractRegex)) !== null) { + keyIndex = valuesMatch[1]; + valueKey = dateElements[keyIndex]; + valueFunction = setFnMap[valueKey]; + valuesFunctionMap.push(valueFunction); + } + return valuesFunctionMap; + } + $dateParser.init(); + return $dateParser; + }; + return DateParserFactory; + } ]; + } ]); + angular.module('mgcrea.ngStrap.helpers.dateFormatter', []).service('$bsDateFormatter', ["$locale", "dateFilter", function($locale, dateFilter) { + this.getDefaultLocale = function() { + return $locale.id; + }; + this.getDatetimeFormat = function(format, lang) { + return $locale.DATETIME_FORMATS[format] || format; + }; + this.weekdaysShort = function(lang) { + return $locale.DATETIME_FORMATS.SHORTDAY; + }; + function splitTimeFormat(format) { + return /(h+)([:\.])?(m+)([:\.])?(s*)[ ]?(a?)/i.exec(format).slice(1); + } + this.hoursFormat = function(timeFormat) { + return splitTimeFormat(timeFormat)[0]; + }; + this.minutesFormat = function(timeFormat) { + return splitTimeFormat(timeFormat)[2]; + }; + this.secondsFormat = function(timeFormat) { + return splitTimeFormat(timeFormat)[4]; + }; + this.timeSeparator = function(timeFormat) { + return splitTimeFormat(timeFormat)[1]; + }; + this.showSeconds = function(timeFormat) { + return !!splitTimeFormat(timeFormat)[4]; + }; + this.showAM = function(timeFormat) { + return !!splitTimeFormat(timeFormat)[5]; + }; + this.formatDate = function(date, format, lang, timezone) { + return dateFilter(date, format, timezone); + }; + } ]); + angular.module('mgcrea.ngStrap.core', []).service('$bsCompiler', bsCompilerService); + function bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) { + this.compile = function(options) { + if (options.template && /\.html$/.test(options.template)) { + console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'); + options.templateUrl = options.template; + options.template = ''; + } + var templateUrl = options.templateUrl; + var template = options.template || ''; + var controller = options.controller; + var controllerAs = options.controllerAs; + var resolve = angular.copy(options.resolve || {}); + var locals = angular.copy(options.locals || {}); + var transformTemplate = options.transformTemplate || angular.identity; + var bindToController = options.bindToController; + angular.forEach(resolve, function(value, key) { + if (angular.isString(value)) { + resolve[key] = $injector.get(value); + } else { + resolve[key] = $injector.invoke(value); + } + }); + angular.extend(resolve, locals); + if (template) { + resolve.$template = $q.when(template); + } else if (templateUrl) { + resolve.$template = fetchTemplate(templateUrl); + } else { + throw new Error('Missing `template` / `templateUrl` option.'); + } + if (options.titleTemplate) { + resolve.$template = $q.all([ resolve.$template, fetchTemplate(options.titleTemplate) ]).then(function(templates) { + var templateEl = angular.element(templates[0]); + findElement('[ng-bind="title"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]); + return templateEl[0].outerHTML; + }); + } + if (options.contentTemplate) { + resolve.$template = $q.all([ resolve.$template, fetchTemplate(options.contentTemplate) ]).then(function(templates) { + var templateEl = angular.element(templates[0]); + var contentEl = findElement('[ng-bind="content"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]); + if (!options.templateUrl) contentEl.next().remove(); + return templateEl[0].outerHTML; + }); + } + return $q.all(resolve).then(function(locals) { + var template = transformTemplate(locals.$template); + if (options.html) { + template = template.replace(/ng-bind="/gi, 'ng-bind-html="'); + } + var element = angular.element('
').html(template.trim()).contents(); + var linkFn = $compile(element); + return { + locals: locals, + element: element, + link: function link(scope) { + locals.$scope = scope; + if (controller) { + var invokeCtrl = $controller(controller, locals, true); + if (bindToController) { + angular.extend(invokeCtrl.instance, locals); + } + var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl(); + element.data('$ngControllerController', ctrl); + element.children().data('$ngControllerController', ctrl); + if (controllerAs) { + scope[controllerAs] = ctrl; + } + } + return linkFn.apply(null, arguments); + } + }; + }); + }; + function findElement(query, element) { + return angular.element((element || document).querySelectorAll(query)); + } + var fetchPromises = {}; + function fetchTemplate(template) { + if (fetchPromises[template]) return fetchPromises[template]; + return fetchPromises[template] = $http.get(template, { + cache: $templateCache + }).then(function(res) { + return res.data; + }); + } + } + angular.module('mgcrea.ngStrap.datepicker', [ 'mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip' ]).provider('$bsDatepicker', function() { + var defaults = this.defaults = { + animation: 'am-fade', + prefixClass: 'datepicker', + placement: 'bottom-left', + templateUrl: 'datepicker/datepicker.tpl.html', + trigger: 'focus', + container: false, + keyboard: true, + html: false, + delay: 0, + useNative: false, + dateType: 'date', + dateFormat: 'shortDate', + timezone: null, + modelDateFormat: null, + dayFormat: 'dd', + monthFormat: 'MMM', + yearFormat: 'yyyy', + monthTitleFormat: 'MMMM yyyy', + yearTitleFormat: 'yyyy', + strictFormat: false, + autoclose: false, + minDate: -Infinity, + maxDate: +Infinity, + startView: 0, + minView: 0, + startWeek: 0, + daysOfWeekDisabled: '', + hasToday: false, + hasClear: false, + iconLeft: 'glyphicon glyphicon-chevron-left', + iconRight: 'glyphicon glyphicon-chevron-right' + }; + this.$get = ["$window", "$document", "$rootScope", "$sce", "$bsDateFormatter", "bsDatepickerViews", "$bsTooltip", "$timeout", function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) { + var isNative = /(ip[ao]d|iphone|android)/gi.test($window.navigator.userAgent); + var isTouch = 'createTouch' in $window.document && isNative; + if (!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale(); + function DatepickerFactory(element, controller, config) { + var $datepicker = $tooltip(element, angular.extend({}, defaults, config)); + var parentScope = config.scope; + var options = $datepicker.$options; + var scope = $datepicker.$scope; + if (options.startView) options.startView -= options.minView; + var pickerViews = datepickerViews($datepicker); + $datepicker.$views = pickerViews.views; + var viewDate = pickerViews.viewDate; + scope.$mode = options.startView; + scope.$iconLeft = options.iconLeft; + scope.$iconRight = options.iconRight; + scope.$hasToday = options.hasToday; + scope.$hasClear = options.hasClear; + var $picker = $datepicker.$views[scope.$mode]; + scope.$select = function(date) { + $datepicker.select(date); + }; + scope.$selectPane = function(value) { + $datepicker.$selectPane(value); + }; + scope.$toggleMode = function() { + $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length); + }; + scope.$setToday = function() { + if (options.autoclose) { + $datepicker.setMode(0); + $datepicker.select(new Date()); + } else { + $datepicker.select(new Date(), true); + } + }; + scope.$clear = function() { + if (options.autoclose) { + $datepicker.setMode(0); + $datepicker.select(null); + } else { + $datepicker.select(null, true); + } + }; + $datepicker.update = function(date) { + if (angular.isDate(date) && !isNaN(date.getTime())) { + $datepicker.$date = date; + $picker.update.call($picker, date); + } + $datepicker.$build(true); + }; + $datepicker.updateDisabledDates = function(dateRanges) { + options.disabledDateRanges = dateRanges; + for (var i = 0, l = scope.rows.length; i < l; i++) { + angular.forEach(scope.rows[i], $datepicker.$setDisabledEl); + } + }; + $datepicker.select = function(date, keep) { + if (angular.isDate(date)) { + if (!angular.isDate(controller.$dateValue) || isNaN(controller.$dateValue.getTime())) { + controller.$dateValue = new Date(date); + } + } else { + controller.$dateValue = null; + } + if (!scope.$mode || keep) { + controller.$setViewValue(angular.copy(date)); + controller.$render(); + if (options.autoclose && !keep) { + $timeout(function() { + $datepicker.hide(true); + }); + } + } else { + angular.extend(viewDate, { + year: date.getFullYear(), + month: date.getMonth(), + date: date.getDate() + }); + $datepicker.setMode(scope.$mode - 1); + $datepicker.$build(); + } + }; + $datepicker.setMode = function(mode) { + scope.$mode = mode; + $picker = $datepicker.$views[scope.$mode]; + $datepicker.$build(); + }; + $datepicker.$build = function(pristine) { + if (pristine === true && $picker.built) return; + if (pristine === false && !$picker.built) return; + $picker.build.call($picker); + }; + $datepicker.$updateSelected = function() { + for (var i = 0, l = scope.rows.length; i < l; i++) { + angular.forEach(scope.rows[i], updateSelected); + } + }; + $datepicker.$isSelected = function(date) { + return $picker.isSelected(date); + }; + $datepicker.$setDisabledEl = function(el) { + el.disabled = $picker.isDisabled(el.date); + }; + $datepicker.$selectPane = function(value) { + var steps = $picker.steps; + var targetDate = new Date(Date.UTC(viewDate.year + (steps.year || 0) * value, viewDate.month + (steps.month || 0) * value, 1)); + angular.extend(viewDate, { + year: targetDate.getUTCFullYear(), + month: targetDate.getUTCMonth(), + date: targetDate.getUTCDate() + }); + $datepicker.$build(); + }; + $datepicker.$onMouseDown = function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + if (isTouch) { + var targetEl = angular.element(evt.target); + if (targetEl[0].nodeName.toLowerCase() !== 'button') { + targetEl = targetEl.parent(); + } + targetEl.triggerHandler('click'); + } + }; + $datepicker.$onKeyDown = function(evt) { + if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return; + evt.preventDefault(); + evt.stopPropagation(); + if (evt.keyCode === 13) { + if (!scope.$mode) { + $datepicker.hide(true); + } else { + scope.$apply(function() { + $datepicker.setMode(scope.$mode - 1); + }); + } + return; + } + $picker.onKeyDown(evt); + parentScope.$digest(); + }; + function updateSelected(el) { + el.selected = $datepicker.$isSelected(el.date); + } + function focusElement() { + element[0].focus(); + } + var _init = $datepicker.init; + $datepicker.init = function() { + if (isNative && options.useNative) { + element.prop('type', 'date'); + element.css('-webkit-appearance', 'textfield'); + return; + } else if (isTouch) { + element.prop('type', 'text'); + element.attr('readonly', 'true'); + element.on('click', focusElement); + } + _init(); + }; + var _destroy = $datepicker.destroy; + $datepicker.destroy = function() { + if (isNative && options.useNative) { + element.off('click', focusElement); + } + _destroy(); + }; + var _show = $datepicker.show; + $datepicker.show = function() { + if (!isTouch && element.attr('readonly') || element.attr('disabled')) return; + _show(); + $timeout(function() { + if (!$datepicker.$isShown) return; + $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown); + if (options.keyboard) { + element.on('keydown', $datepicker.$onKeyDown); + } + }, 0, false); + }; + var _hide = $datepicker.hide; + $datepicker.hide = function(blur) { + if (!$datepicker.$isShown) return; + $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown); + if (options.keyboard) { + element.off('keydown', $datepicker.$onKeyDown); + } + _hide(blur); + }; + return $datepicker; + } + DatepickerFactory.defaults = defaults; + return DatepickerFactory; + } ]; + }).directive('bsDatepicker', ["$window", "$parse", "$q", "$bsDateFormatter", "$bsDateParser", "$bsDatepicker", function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) { + var isNative = /(ip[ao]d|iphone|android)/gi.test($window.navigator.userAgent); + return { + restrict: 'EAC', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + var options = { + scope: scope + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent', 'hasToday', 'hasClear' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container', 'autoclose', 'useNative', 'hasToday', 'hasClear' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) { + options[key] = false; + } + }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + var datepicker = $datepicker(element, controller, options); + options = datepicker.$options; + if (isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd'; + var lang = options.lang; + var formatDate = function(date, format) { + return $dateFormatter.formatDate(date, format, lang); + }; + var dateParser = $dateParser({ + format: options.dateFormat, + lang: lang, + strict: options.strictFormat + }); + if (attr.bsShow) { + scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!datepicker || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i); + if (newValue === true) { + datepicker.show(); + } else { + datepicker.hide(); + } + }); + } + angular.forEach([ 'minDate', 'maxDate' ], function(key) { + if (angular.isDefined(attr[key])) { + attr.$observe(key, function(newValue) { + datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue); + if (!isNaN(datepicker.$options[key])) datepicker.$build(false); + validateAgainstMinMaxDate(controller.$dateValue); + }); + } + }); + if (angular.isDefined(attr.dateFormat)) { + attr.$observe('dateFormat', function(newValue) { + datepicker.$options.dateFormat = newValue; + }); + } + scope.$watch(attr.ngModel, function(newValue, oldValue) { + datepicker.update(controller.$dateValue); + }, true); + function normalizeDateRanges(ranges) { + if (!ranges || !ranges.length) return null; + return ranges; + } + if (angular.isDefined(attr.disabledDates)) { + scope.$watch(attr.disabledDates, function(disabledRanges, previousValue) { + disabledRanges = normalizeDateRanges(disabledRanges); + previousValue = normalizeDateRanges(previousValue); + if (disabledRanges) { + datepicker.updateDisabledDates(disabledRanges); + } + }); + } + function validateAgainstMinMaxDate(parsedDate) { + if (!angular.isDate(parsedDate)) return; + var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate; + var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate; + var isValid = isMinValid && isMaxValid; + controller.$setValidity('date', isValid); + controller.$setValidity('min', isMinValid); + controller.$setValidity('max', isMaxValid); + if (isValid) controller.$dateValue = parsedDate; + } + controller.$parsers.unshift(function(viewValue) { + var date; + if (!viewValue) { + controller.$setValidity('date', true); + return null; + } + var parsedDate = dateParser.parse(viewValue, controller.$dateValue); + if (!parsedDate || isNaN(parsedDate.getTime())) { + controller.$setValidity('date', false); + return; + } + validateAgainstMinMaxDate(parsedDate); + if (options.dateType === 'string') { + date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true); + return formatDate(date, options.modelDateFormat || options.dateFormat); + } + date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true); + if (options.dateType === 'number') { + return date.getTime(); + } else if (options.dateType === 'unix') { + return date.getTime() / 1e3; + } else if (options.dateType === 'iso') { + return date.toISOString(); + } + return new Date(date); + }); + controller.$formatters.push(function(modelValue) { + var date; + if (angular.isUndefined(modelValue) || modelValue === null) { + date = NaN; + } else if (angular.isDate(modelValue)) { + date = modelValue; + } else if (options.dateType === 'string') { + date = dateParser.parse(modelValue, null, options.modelDateFormat); + } else if (options.dateType === 'unix') { + date = new Date(modelValue * 1e3); + } else { + date = new Date(modelValue); + } + controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone); + return getDateFormattedString(); + }); + controller.$render = function() { + element.val(getDateFormattedString()); + }; + function getDateFormattedString() { + return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat); + } + scope.$on('$destroy', function() { + if (datepicker) datepicker.destroy(); + options = null; + datepicker = null; + }); + } + }; + } ]).provider('bsDatepickerViews', function() { + function split(arr, size) { + var arrays = []; + while (arr.length > 0) { + arrays.push(arr.splice(0, size)); + } + return arrays; + } + function mod(n, m) { + return (n % m + m) % m; + } + this.$get = ["$bsDateFormatter", "$bsDateParser", "$sce", function($dateFormatter, $dateParser, $sce) { + return function(picker) { + var scope = picker.$scope; + var options = picker.$options; + var lang = options.lang; + var formatDate = function(date, format) { + return $dateFormatter.formatDate(date, format, lang); + }; + var dateParser = $dateParser({ + format: options.dateFormat, + lang: lang, + strict: options.strictFormat + }); + var weekDaysMin = $dateFormatter.weekdaysShort(lang); + var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek)); + var weekDaysLabelsHtml = $sce.trustAsHtml('' + weekDaysLabels.join('') + ''); + var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date()); + var viewDate = { + year: startDate.getFullYear(), + month: startDate.getMonth(), + date: startDate.getDate() + }; + var views = [ { + format: options.dayFormat, + split: 7, + steps: { + month: 1 + }, + update: function(date, force) { + if (!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) { + angular.extend(viewDate, { + year: picker.$date.getFullYear(), + month: picker.$date.getMonth(), + date: picker.$date.getDate() + }); + picker.$build(); + } else if (date.getDate() !== viewDate.date || date.getDate() === 1) { + viewDate.date = picker.$date.getDate(); + picker.$updateSelected(); + } + }, + build: function() { + var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1); + var firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset(); + var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5); + var firstDateOffset = firstDate.getTimezoneOffset(); + var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString(); + if (firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 6e4); + var days = []; + var day; + for (var i = 0; i < 42; i++) { + day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i)); + days.push({ + date: day, + isToday: day.toDateString() === today, + label: formatDate(day, this.format), + selected: picker.$date && this.isSelected(day), + muted: day.getMonth() !== viewDate.month, + disabled: this.isDisabled(day) + }); + } + scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat); + scope.showLabels = true; + scope.labels = weekDaysLabelsHtml; + scope.rows = split(days, this.split); + scope.isTodayDisabled = this.isDisabled(new Date()); + this.built = true; + }, + isSelected: function(date) { + return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate(); + }, + isDisabled: function(date) { + var time = date.getTime(); + if (time < options.minDate || time > options.maxDate) return true; + if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true; + if (options.disabledDateRanges) { + for (var i = 0; i < options.disabledDateRanges.length; i++) { + if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) { + return true; + } + } + } + return false; + }, + onKeyDown: function(evt) { + if (!picker.$date) { + return; + } + var actualTime = picker.$date.getTime(); + var newDate; + if (evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5); else if (evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5); else if (evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5); else if (evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5); + if (!this.isDisabled(newDate)) picker.select(newDate, true); + } + }, { + name: 'month', + format: options.monthFormat, + split: 4, + steps: { + year: 1 + }, + update: function(date, force) { + if (!this.built || date.getFullYear() !== viewDate.year) { + angular.extend(viewDate, { + year: picker.$date.getFullYear(), + month: picker.$date.getMonth(), + date: picker.$date.getDate() + }); + picker.$build(); + } else if (date.getMonth() !== viewDate.month) { + angular.extend(viewDate, { + month: picker.$date.getMonth(), + date: picker.$date.getDate() + }); + picker.$updateSelected(); + } + }, + build: function() { + var months = []; + var month; + for (var i = 0; i < 12; i++) { + month = new Date(viewDate.year, i, 1); + months.push({ + date: month, + label: formatDate(month, this.format), + selected: picker.$isSelected(month), + disabled: this.isDisabled(month) + }); + } + scope.title = formatDate(month, options.yearTitleFormat); + scope.showLabels = false; + scope.rows = split(months, this.split); + this.built = true; + }, + isSelected: function(date) { + return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth(); + }, + isDisabled: function(date) { + var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0); + return lastDate < options.minDate || date.getTime() > options.maxDate; + }, + onKeyDown: function(evt) { + if (!picker.$date) { + return; + } + var actualMonth = picker.$date.getMonth(); + var newDate = new Date(picker.$date); + if (evt.keyCode === 37) newDate.setMonth(actualMonth - 1); else if (evt.keyCode === 38) newDate.setMonth(actualMonth - 4); else if (evt.keyCode === 39) newDate.setMonth(actualMonth + 1); else if (evt.keyCode === 40) newDate.setMonth(actualMonth + 4); + if (!this.isDisabled(newDate)) picker.select(newDate, true); + } + }, { + name: 'year', + format: options.yearFormat, + split: 4, + steps: { + year: 12 + }, + update: function(date, force) { + if (!this.built || force || parseInt(date.getFullYear() / 20, 10) !== parseInt(viewDate.year / 20, 10)) { + angular.extend(viewDate, { + year: picker.$date.getFullYear(), + month: picker.$date.getMonth(), + date: picker.$date.getDate() + }); + picker.$build(); + } else if (date.getFullYear() !== viewDate.year) { + angular.extend(viewDate, { + year: picker.$date.getFullYear(), + month: picker.$date.getMonth(), + date: picker.$date.getDate() + }); + picker.$updateSelected(); + } + }, + build: function() { + var firstYear = viewDate.year - viewDate.year % (this.split * 3); + var years = []; + var year; + for (var i = 0; i < 12; i++) { + year = new Date(firstYear + i, 0, 1); + years.push({ + date: year, + label: formatDate(year, this.format), + selected: picker.$isSelected(year), + disabled: this.isDisabled(year) + }); + } + scope.title = years[0].label + '-' + years[years.length - 1].label; + scope.showLabels = false; + scope.rows = split(years, this.split); + this.built = true; + }, + isSelected: function(date) { + return picker.$date && date.getFullYear() === picker.$date.getFullYear(); + }, + isDisabled: function(date) { + var lastDate = +new Date(date.getFullYear() + 1, 0, 0); + return lastDate < options.minDate || date.getTime() > options.maxDate; + }, + onKeyDown: function(evt) { + if (!picker.$date) { + return; + } + var actualYear = picker.$date.getFullYear(); + var newDate = new Date(picker.$date); + if (evt.keyCode === 37) newDate.setYear(actualYear - 1); else if (evt.keyCode === 38) newDate.setYear(actualYear - 4); else if (evt.keyCode === 39) newDate.setYear(actualYear + 1); else if (evt.keyCode === 40) newDate.setYear(actualYear + 4); + if (!this.isDisabled(newDate)) picker.select(newDate, true); + } + } ]; + return { + views: options.minView ? Array.prototype.slice.call(views, options.minView) : views, + viewDate: viewDate + }; + }; + } ]; + }); + angular.module('mgcrea.ngStrap.button', []).provider('$bsButton', function() { + var defaults = this.defaults = { + activeClass: 'active', + toggleEvent: 'click' + }; + this.$get = function() { + return { + defaults: defaults + }; + }; + }).directive('bsCheckboxGroup', function() { + return { + restrict: 'A', + require: 'ngModel', + compile: function postLink(element, attr) { + element.attr('data-toggle', 'buttons'); + element.removeAttr('ng-model'); + var children = element[0].querySelectorAll('input[type="checkbox"]'); + angular.forEach(children, function(child) { + var childEl = angular.element(child); + childEl.attr('bs-checkbox', ''); + childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value')); + }); + } + }; + }).directive('bsCheckbox', ["$bsButton", "$$rAF", function($button, $$rAF) { + var defaults = $button.defaults; + var constantValueRegExp = /^(true|false|\d+)$/; + return { + restrict: 'A', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + var options = defaults; + var isInput = element[0].nodeName === 'INPUT'; + var activeElement = isInput ? element.parent() : element; + var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true; + if (constantValueRegExp.test(attr.trueValue)) { + trueValue = scope.$eval(attr.trueValue); + } + var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false; + if (constantValueRegExp.test(attr.falseValue)) { + falseValue = scope.$eval(attr.falseValue); + } + var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean'; + if (hasExoticValues) { + controller.$parsers.push(function(viewValue) { + return viewValue ? trueValue : falseValue; + }); + controller.$formatters.push(function(modelValue) { + return angular.equals(modelValue, trueValue); + }); + scope.$watch(attr.ngModel, function(newValue, oldValue) { + controller.$render(); + }); + } + controller.$render = function() { + var isActive = angular.equals(controller.$modelValue, trueValue); + $$rAF(function() { + if (isInput) element[0].checked = isActive; + activeElement.toggleClass(options.activeClass, isActive); + }); + }; + element.bind(options.toggleEvent, function() { + scope.$apply(function() { + if (!isInput) { + controller.$setViewValue(!activeElement.hasClass('active')); + } + if (!hasExoticValues) { + controller.$render(); + } + }); + }); + } + }; + } ]).directive('bsRadioGroup', function() { + return { + restrict: 'A', + require: 'ngModel', + compile: function postLink(element, attr) { + element.attr('data-toggle', 'buttons'); + element.removeAttr('ng-model'); + var children = element[0].querySelectorAll('input[type="radio"]'); + angular.forEach(children, function(child) { + angular.element(child).attr('bs-radio', ''); + angular.element(child).attr('ng-model', attr.ngModel); + }); + } + }; + }).directive('bsRadio', ["$bsButton", "$$rAF", function($button, $$rAF) { + var defaults = $button.defaults; + var constantValueRegExp = /^(true|false|\d+)$/; + return { + restrict: 'A', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + var options = defaults; + var isInput = element[0].nodeName === 'INPUT'; + var activeElement = isInput ? element.parent() : element; + var value; + attr.$observe('value', function(v) { + if (typeof v !== 'boolean' && constantValueRegExp.test(v)) { + value = scope.$eval(v); + } else { + value = v; + } + controller.$render(); + }); + controller.$render = function() { + var isActive = angular.equals(controller.$modelValue, value); + $$rAF(function() { + if (isInput) element[0].checked = isActive; + activeElement.toggleClass(options.activeClass, isActive); + }); + }; + element.bind(options.toggleEvent, function() { + scope.$apply(function() { + controller.$setViewValue(value); + controller.$render(); + }); + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.collapse', []).provider('$bsCollapse', function() { + var defaults = this.defaults = { + animation: 'am-collapse', + disallowToggle: false, + activeClass: 'in', + startCollapsed: false, + allowMultiple: false + }; + var controller = this.controller = function($scope, $element, $attrs) { + var self = this; + self.$options = angular.copy(defaults); + angular.forEach([ 'animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple' ], function(key) { + if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'disallowToggle', 'startCollapsed', 'allowMultiple' ], function(key) { + if (angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) { + self.$options[key] = false; + } + }); + self.$toggles = []; + self.$targets = []; + self.$viewChangeListeners = []; + self.$registerToggle = function(element) { + self.$toggles.push(element); + }; + self.$registerTarget = function(element) { + self.$targets.push(element); + }; + self.$unregisterToggle = function(element) { + var index = self.$toggles.indexOf(element); + self.$toggles.splice(index, 1); + }; + self.$unregisterTarget = function(element) { + var index = self.$targets.indexOf(element); + self.$targets.splice(index, 1); + if (self.$options.allowMultiple) { + deactivateItem(element); + } + fixActiveItemIndexes(index); + self.$viewChangeListeners.forEach(function(fn) { + fn(); + }); + }; + self.$targets.$active = !self.$options.startCollapsed ? [ 0 ] : []; + self.$setActive = $scope.$setActive = function(value) { + if (angular.isArray(value)) { + self.$targets.$active = value; + } else if (!self.$options.disallowToggle && isActive(value)) { + deactivateItem(value); + } else { + activateItem(value); + } + self.$viewChangeListeners.forEach(function(fn) { + fn(); + }); + }; + self.$activeIndexes = function() { + if (self.$options.allowMultiple) { + return self.$targets.$active; + } + return self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1; + }; + function fixActiveItemIndexes(index) { + var activeIndexes = self.$targets.$active; + for (var i = 0; i < activeIndexes.length; i++) { + if (index < activeIndexes[i]) { + activeIndexes[i] = activeIndexes[i] - 1; + } + if (activeIndexes[i] === self.$targets.length) { + activeIndexes[i] = self.$targets.length - 1; + } + } + } + function isActive(value) { + var activeItems = self.$targets.$active; + return activeItems.indexOf(value) !== -1; + } + function deactivateItem(value) { + var index = self.$targets.$active.indexOf(value); + if (index !== -1) { + self.$targets.$active.splice(index, 1); + } + } + function activateItem(value) { + if (!self.$options.allowMultiple) { + self.$targets.$active.splice(0, 1); + } + if (self.$targets.$active.indexOf(value) === -1) { + self.$targets.$active.push(value); + } + } + }; + this.$get = function() { + var $collapse = {}; + $collapse.defaults = defaults; + $collapse.controller = controller; + return $collapse; + }; + }).directive('bsCollapse', ["$window", "$animate", "$bsCollapse", function($window, $animate, $collapse) { + return { + require: [ '?ngModel', 'bsCollapse' ], + controller: [ '$scope', '$element', '$attrs', $collapse.controller ], + link: function postLink(scope, element, attrs, controllers) { + var ngModelCtrl = controllers[0]; + var bsCollapseCtrl = controllers[1]; + if (ngModelCtrl) { + bsCollapseCtrl.$viewChangeListeners.push(function() { + ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes()); + }); + ngModelCtrl.$formatters.push(function(modelValue) { + if (angular.isArray(modelValue)) { + bsCollapseCtrl.$setActive(modelValue); + } else { + var activeIndexes = bsCollapseCtrl.$activeIndexes(); + if (angular.isArray(activeIndexes)) { + if (activeIndexes.indexOf(modelValue * 1) === -1) { + bsCollapseCtrl.$setActive(modelValue * 1); + } + } else if (activeIndexes !== modelValue * 1) { + bsCollapseCtrl.$setActive(modelValue * 1); + } + } + return modelValue; + }); + } + } + }; + } ]).directive('bsCollapseToggle', function() { + return { + require: [ '^?ngModel', '^bsCollapse' ], + link: function postLink(scope, element, attrs, controllers) { + var bsCollapseCtrl = controllers[1]; + element.attr('data-toggle', 'collapse'); + bsCollapseCtrl.$registerToggle(element); + scope.$on('$destroy', function() { + bsCollapseCtrl.$unregisterToggle(element); + }); + element.on('click', function() { + if (!attrs.disabled) { + var index = attrs.bsCollapseToggle && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element); + bsCollapseCtrl.$setActive(index * 1); + scope.$apply(); + } + }); + } + }; + }).directive('bsCollapseTarget', ["$animate", function($animate) { + return { + require: [ '^?ngModel', '^bsCollapse' ], + link: function postLink(scope, element, attrs, controllers) { + var bsCollapseCtrl = controllers[1]; + element.addClass('collapse'); + if (bsCollapseCtrl.$options.animation) { + element.addClass(bsCollapseCtrl.$options.animation); + } + bsCollapseCtrl.$registerTarget(element); + scope.$on('$destroy', function() { + bsCollapseCtrl.$unregisterTarget(element); + }); + function render() { + var index = bsCollapseCtrl.$targets.indexOf(element); + var active = bsCollapseCtrl.$activeIndexes(); + var action = 'removeClass'; + if (angular.isArray(active)) { + if (active.indexOf(index) !== -1) { + action = 'addClass'; + } + } else if (index === active) { + action = 'addClass'; + } + $animate[action](element, bsCollapseCtrl.$options.activeClass); + } + bsCollapseCtrl.$viewChangeListeners.push(function() { + render(); + }); + render(); + } + }; + } ]); + angular.module('mgcrea.ngStrap.aside', [ 'mgcrea.ngStrap.modal' ]).provider('$bsAside', function() { + var defaults = this.defaults = { + animation: 'am-fade-and-slide-right', + prefixClass: 'aside', + prefixEvent: 'aside', + placement: 'right', + templateUrl: 'aside/aside.tpl.html', + contentTemplate: false, + container: false, + element: null, + backdrop: true, + keyboard: true, + html: false, + show: true + }; + this.$get = ["$bsModal", function($modal) { + function AsideFactory(config) { + var $aside = {}; + var options = angular.extend({}, defaults, config); + $aside = $modal(options); + return $aside; + } + return AsideFactory; + } ]; + }).directive('bsAside', ["$window", "$sce", "$bsAside", function($window, $sce, $aside) { + return { + restrict: 'EAC', + scope: true, + link: function postLink(scope, element, attr, transclusion) { + var options = { + scope: scope, + element: element, + show: false + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'backdrop', 'keyboard', 'html', 'container' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + angular.forEach([ 'title', 'content' ], function(key) { + if (attr[key]) { + attr.$observe(key, function(newValue, oldValue) { + scope[key] = $sce.trustAsHtml(newValue); + }); + } + }); + if (attr.bsAside) { + scope.$watch(attr.bsAside, function(newValue, oldValue) { + if (angular.isObject(newValue)) { + angular.extend(scope, newValue); + } else { + scope.content = newValue; + } + }, true); + } + var aside = $aside(options); + element.on(attr.trigger || 'click', aside.toggle); + scope.$on('$destroy', function() { + if (aside) aside.destroy(); + options = null; + aside = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.alert', [ 'mgcrea.ngStrap.modal' ]).provider('$bsAlert', function() { + var defaults = this.defaults = { + animation: 'am-fade', + prefixClass: 'alert', + prefixEvent: 'alert', + placement: null, + templateUrl: 'alert/alert.tpl.html', + container: false, + element: null, + backdrop: false, + keyboard: true, + show: true, + duration: false, + type: false, + dismissable: true + }; + this.$get = ["$bsModal", "$timeout", function($modal, $timeout) { + function AlertFactory(config) { + var $alert = {}; + var options = angular.extend({}, defaults, config); + $alert = $modal(options); + $alert.$scope.dismissable = !!options.dismissable; + if (options.type) { + $alert.$scope.type = options.type; + } + var show = $alert.show; + if (options.duration) { + $alert.show = function() { + show(); + $timeout(function() { + $alert.hide(); + }, options.duration * 1e3); + }; + } + return $alert; + } + return AlertFactory; + } ]; + }).directive('bsAlert', ["$window", "$sce", "$bsAlert", function($window, $sce, $alert) { + return { + restrict: 'EAC', + scope: true, + link: function postLink(scope, element, attr, transclusion) { + var options = { + scope: scope, + element: element, + show: false + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'keyboard', 'html', 'container', 'dismissable' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + if (!scope.hasOwnProperty('title')) { + scope.title = ''; + } + angular.forEach([ 'title', 'content', 'type' ], function(key) { + if (attr[key]) { + attr.$observe(key, function(newValue, oldValue) { + scope[key] = $sce.trustAsHtml(newValue); + }); + } + }); + if (attr.bsAlert) { + scope.$watch(attr.bsAlert, function(newValue, oldValue) { + if (angular.isObject(newValue)) { + angular.extend(scope, newValue); + } else { + scope.content = newValue; + } + }, true); + } + var alert = $alert(options); + element.on(attr.trigger || 'click', alert.toggle); + scope.$on('$destroy', function() { + if (alert) alert.destroy(); + options = null; + alert = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.affix', [ 'mgcrea.ngStrap.helpers.dimensions', 'mgcrea.ngStrap.helpers.debounce' ]).provider('$bsAffix', function() { + var defaults = this.defaults = { + offsetTop: 'auto', + inlineStyles: true + }; + this.$get = ["$window", "bsDebounce", "bsDimensions", function($window, debounce, dimensions) { + var bodyEl = angular.element($window.document.body); + var windowEl = angular.element($window); + function AffixFactory(element, config) { + var $affix = {}; + var options = angular.extend({}, defaults, config); + var targetEl = options.target; + var reset = 'affix affix-top affix-bottom'; + var setWidth = false; + var initialAffixTop = 0; + var initialOffsetTop = 0; + var offsetTop = 0; + var offsetBottom = 0; + var affixed = null; + var unpin = null; + var parent = element.parent(); + if (options.offsetParent) { + if (options.offsetParent.match(/^\d+$/)) { + for (var i = 0; i < options.offsetParent * 1 - 1; i++) { + parent = parent.parent(); + } + } else { + parent = angular.element(options.offsetParent); + } + } + $affix.init = function() { + this.$parseOffsets(); + initialOffsetTop = dimensions.offset(element[0]).top + initialAffixTop; + setWidth = !element[0].style.width; + targetEl.on('scroll', this.checkPosition); + targetEl.on('click', this.checkPositionWithEventLoop); + windowEl.on('resize', this.$debouncedOnResize); + this.checkPosition(); + this.checkPositionWithEventLoop(); + }; + $affix.destroy = function() { + targetEl.off('scroll', this.checkPosition); + targetEl.off('click', this.checkPositionWithEventLoop); + windowEl.off('resize', this.$debouncedOnResize); + }; + $affix.checkPositionWithEventLoop = function() { + setTimeout($affix.checkPosition, 1); + }; + $affix.checkPosition = function() { + var scrollTop = getScrollTop(); + var position = dimensions.offset(element[0]); + var elementHeight = dimensions.height(element[0]); + var affix = getRequiredAffixClass(unpin, position, elementHeight); + if (affixed === affix) return; + affixed = affix; + if (affix === 'top') { + unpin = null; + if (setWidth) { + element.css('width', ''); + } + if (options.inlineStyles) { + element.css('position', options.offsetParent ? '' : 'relative'); + element.css('top', ''); + } + } else if (affix === 'bottom') { + if (options.offsetUnpin) { + unpin = -(options.offsetUnpin * 1); + } else { + unpin = position.top - scrollTop; + } + if (setWidth) { + element.css('width', ''); + } + if (options.inlineStyles) { + element.css('position', options.offsetParent ? '' : 'relative'); + element.css('top', options.offsetParent ? '' : bodyEl[0].offsetHeight - offsetBottom - elementHeight - initialOffsetTop + 'px'); + } + } else { + unpin = null; + if (setWidth) { + element.css('width', element[0].offsetWidth + 'px'); + } + if (options.inlineStyles) { + element.css('position', 'fixed'); + element.css('top', initialAffixTop + 'px'); + } + } + element.removeClass(reset).addClass('affix' + (affix !== 'middle' ? '-' + affix : '')); + }; + $affix.$onResize = function() { + $affix.$parseOffsets(); + $affix.checkPosition(); + }; + $affix.$debouncedOnResize = debounce($affix.$onResize, 50); + $affix.$parseOffsets = function() { + var initialPosition = element.css('position'); + if (options.inlineStyles) { + element.css('position', options.offsetParent ? '' : 'relative'); + } + if (options.offsetTop) { + if (options.offsetTop === 'auto') { + options.offsetTop = '+0'; + } + if (options.offsetTop.match(/^[-+]\d+$/)) { + initialAffixTop = -options.offsetTop * 1; + if (options.offsetParent) { + offsetTop = dimensions.offset(parent[0]).top + options.offsetTop * 1; + } else { + offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + options.offsetTop * 1; + } + } else { + offsetTop = options.offsetTop * 1; + } + } + if (options.offsetBottom) { + if (options.offsetParent && options.offsetBottom.match(/^[-+]\d+$/)) { + offsetBottom = getScrollHeight() - (dimensions.offset(parent[0]).top + dimensions.height(parent[0])) + options.offsetBottom * 1 + 1; + } else { + offsetBottom = options.offsetBottom * 1; + } + } + if (options.inlineStyles) { + element.css('position', initialPosition); + } + }; + function getRequiredAffixClass(_unpin, position, elementHeight) { + var scrollTop = getScrollTop(); + var scrollHeight = getScrollHeight(); + if (scrollTop <= offsetTop) { + return 'top'; + } else if (_unpin !== null && scrollTop + _unpin <= position.top) { + return 'middle'; + } else if (offsetBottom !== null && position.top + elementHeight + initialAffixTop >= scrollHeight - offsetBottom) { + return 'bottom'; + } + return 'middle'; + } + function getScrollTop() { + return targetEl[0] === $window ? $window.pageYOffset : targetEl[0].scrollTop; + } + function getScrollHeight() { + return targetEl[0] === $window ? $window.document.body.scrollHeight : targetEl[0].scrollHeight; + } + $affix.init(); + return $affix; + } + return AffixFactory; + } ]; + }).directive('bsAffix', ["$bsAffix", "$window", function($affix, $window) { + return { + restrict: 'EAC', + require: '^?bsAffixTarget', + link: function postLink(scope, element, attr, affixTarget) { + var options = { + scope: scope, + target: affixTarget ? affixTarget.$element : angular.element($window) + }; + angular.forEach([ 'offsetTop', 'offsetBottom', 'offsetParent', 'offsetUnpin', 'inlineStyles' ], function(key) { + if (angular.isDefined(attr[key])) { + var option = attr[key]; + if (/true/i.test(option)) option = true; + if (/false/i.test(option)) option = false; + options[key] = option; + } + }); + var affix = $affix(element, options); + scope.$on('$destroy', function() { + if (affix) affix.destroy(); + options = null; + affix = null; + }); + } + }; + } ]).directive('bsAffixTarget', function() { + return { + controller: ["$element", function($element) { + this.$element = $element; + } ] + }; + }); + angular.module('mgcrea.ngStrap', [ 'mgcrea.ngStrap.modal', 'mgcrea.ngStrap.aside', 'mgcrea.ngStrap.alert', 'mgcrea.ngStrap.button', 'mgcrea.ngStrap.select', 'mgcrea.ngStrap.datepicker', 'mgcrea.ngStrap.timepicker', 'mgcrea.ngStrap.navbar', 'mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.popover', 'mgcrea.ngStrap.dropdown', 'mgcrea.ngStrap.typeahead', 'mgcrea.ngStrap.scrollspy', 'mgcrea.ngStrap.affix', 'mgcrea.ngStrap.tab', 'mgcrea.ngStrap.collapse' ]); +})(window, document); \ No newline at end of file diff --git a/InventoryTraker.Web/Scripts/angular-strap.compat.min.js b/InventoryTraker.Web/Scripts/angular-strap.compat.min.js new file mode 100644 index 0000000..f32e2d9 --- /dev/null +++ b/InventoryTraker.Web/Scripts/angular-strap.compat.min.js @@ -0,0 +1,3 @@ +!function(e,t,n){'use strict';function a(e,n,a,o,i,r){function s(e,n){return angular.element((n||t).querySelectorAll(e))}function l(e){return u[e]?u[e]:u[e]=n.get(e,{cache:r}).then(function(e){return e.data})}this.compile=function(t){t.template&&/\.html$/.test(t.template)&&(console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'),t.templateUrl=t.template,t.template='');var n=t.templateUrl,r=t.template||'',u=t.controller,c=t.controllerAs,d=angular.copy(t.resolve||{}),f=angular.copy(t.locals||{}),p=t.transformTemplate||angular.identity,g=t.bindToController;if(angular.forEach(d,function(e,t){angular.isString(e)?d[t]=a.get(e):d[t]=a.invoke(e)}),angular.extend(d,f),r)d.$template=e.when(r);else{if(!n)throw new Error('Missing `template` / `templateUrl` option.');d.$template=l(n)}return t.titleTemplate&&(d.$template=e.all([d.$template,l(t.titleTemplate)]).then(function(e){var t=angular.element(e[0]);return s('[ng-bind="title"]',t[0]).removeAttr('ng-bind').html(e[1]),t[0].outerHTML})),t.contentTemplate&&(d.$template=e.all([d.$template,l(t.contentTemplate)]).then(function(e){var n=angular.element(e[0]),a=s('[ng-bind="content"]',n[0]).removeAttr('ng-bind').html(e[1]);return t.templateUrl||a.next().remove(),n[0].outerHTML})),e.all(d).then(function(e){var n=p(e.$template);t.html&&(n=n.replace(/ng-bind="/gi,'ng-bind-html="'));var a=angular.element('
').html(n.trim()).contents(),r=o(a);return{locals:e,element:a,link:function(t){if(e.$scope=t,u){var n=i(u,e,!0);g&&angular.extend(n.instance,e);var o=angular.isObject(n)?n:n();a.data('$ngControllerController',o),a.children().data('$ngControllerController',o),c&&(t[c]=o)}return r.apply(null,arguments)}}})};var u={}}a.$inject=['$q','$http','$injector','$compile','$controller','$templateCache'],angular.module('mgcrea.ngStrap.typeahead',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$bsTypeahead',function(){var e=this.defaults={animation:'am-fade',prefixClass:'typeahead',prefixEvent:'$typeahead',placement:'bottom-left',templateUrl:'typeahead/typeahead.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,minLength:1,filter:'bsAsyncFilter',limit:6,autoSelect:!1,comparator:'',trimValue:!0};this.$get=['$window','$rootScope','$bsTooltip','$$rAF','$timeout',function(t,n,a,o,i){function r(t,n,r){var l={},u=angular.extend({},e,r);l=a(t,u);var c=r.scope,d=l.$scope;d.$resetMatches=function(){d.$matches=[],d.$activeIndex=u.autoSelect?0:-1},d.$resetMatches(),d.$activate=function(e){d.$$postDigest(function(){l.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){l.select(e)})},d.$isVisible=function(){return l.$isVisible()},l.update=function(e){d.$matches=e,d.$activeIndex>=e.length&&(d.$activeIndex=u.autoSelect?0:-1),s(d),o(l.$applyPlacement)},l.activate=function(e){d.$activeIndex=e},l.select=function(e){if(-1!==e){var t=d.$matches[e].value;n.$setViewValue(t),n.$render(),d.$resetMatches(),c&&c.$digest(),d.$emit(u.prefixEvent+'.select',t,e,l),angular.isDefined(u.onSelect)&&angular.isFunction(u.onSelect)&&u.onSelect(t,e,l)}},l.$isVisible=function(){return u.minLength&&n?d.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=u.minLength:!!d.$matches.length},l.$getIndex=function(e){var t;for(t=d.$matches.length;t--&&!angular.equals(d.$matches[t].value,e););return t},l.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},l.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!l.$isVisible()||13===e.keyCode&&-1===d.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&d.$matches.length?l.select(d.$activeIndex):38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:40===e.keyCode&&d.$activeIndex0?void r.$setViewValue(r.$viewValue.substring(0,r.$viewValue.length-1)):(e.length>c&&(e=e.slice(0,c)),g.update(e),void r.$render())})}),r.$formatters.push(function(e){var t=p.displayValue(e);return t?t:angular.isDefined(e)&&'object'!=typeof e?e:''}),r.$render=function(){if(r.$isEmpty(r.$viewValue))return t.val('');var e=g.$getIndex(r.$modelValue),n=-1!==e?g.$scope.$matches[e].label:r.$viewValue;n=angular.isObject(n)?p.displayValue(n):n;var a=n?n.toString().replace(/<(?:.|\n)*?>/gm,''):'',o=t[0].selectionStart,i=t[0].selectionEnd;t.val(s.trimValue===!1?a:a.trim()),t[0].setSelectionRange(o,i)},e.$on('$destroy',function(){g&&g.destroy(),s=null,g=null})}}}]),angular.module('mgcrea.ngStrap.tab',[]).provider('$bsTab',function(){var e=this.defaults={animation:'am-fade',template:'tab/tab.tpl.html',navClass:'nav-tabs',activeClass:'active'},t=this.controller=function(t,n,a){var o=this;o.$options=angular.copy(e),angular.forEach(['animation','navClass','activeClass'],function(e){angular.isDefined(a[e])&&(o.$options[e]=a[e])}),t.$navClass=o.$options.navClass,t.$activeClass=o.$options.activeClass,o.$panes=t.$panes=[],o.$activePaneChangeListeners=o.$viewChangeListeners=[],o.$push=function(e){angular.isUndefined(o.$panes.$active)&&t.$setActive(e.name||0),o.$panes.push(e)},o.$remove=function(e){var t,n=o.$panes.indexOf(e),a=o.$panes.$active;t=angular.isString(a)?o.$panes.map(function(e){return e.name}).indexOf(a):o.$panes.$active,o.$panes.splice(n,1),t>n?t--:n===t&&t===o.$panes.length&&t--,t>=0&&tr.top+r.height&&(o.top=r.top+r.height-l)}else{var u=t.left-i,c=t.left+i+n;ur.right&&(o.left=r.left+r.width-c)}return o}function A(e,t,n){var a=m('.tooltip-arrow, .arrow',B[0]);a.css(n?'left':'top',50*(1-e/t)+'%').css(n?'top':'left','')}function M(){clearTimeout(I),F.$isShown&&null!==B&&(V.autoClose&&S(),V.keyboard&&y()),Y&&(Y.$destroy(),Y=null),B&&(B.remove(),B=F.$element=null)}var F={},V=F.$options=angular.extend({},e,r),H=F.$promise=o.compile(V),O=F.$scope=V.scope&&V.scope.$new()||a.$new(),P=i[0].nodeName.toLowerCase();if(V.delay&&angular.isString(V.delay)){var N=V.delay.split(',').map(parseFloat);V.delay=N.length>1?{show:N[0],hide:N[1]}:N[0]}F.$id=V.id||i.attr('id')||'',V.title&&(O.title=u.trustAsHtml(V.title)),O.$setEnabled=function(e){O.$$postDigest(function(){F.setEnabled(e)})},O.$hide=function(){O.$$postDigest(function(){F.hide()})},O.$show=function(){O.$$postDigest(function(){F.show()})},O.$toggle=function(){O.$$postDigest(function(){F.toggle()})},F.$isShown=O.$isShown=!1;var I,U,L,B,R,Y;H.then(function(e){L=e,F.init()}),F.init=function(){V.delay&&angular.isNumber(V.delay)&&(V.delay={show:V.delay,hide:V.delay}),'self'===V.container?R=i:angular.isElement(V.container)?R=V.container:V.container&&(R=m(V.container)),$(),V.target&&(V.target=angular.isElement(V.target)?V.target:m(V.target)),V.show&&O.$$postDigest(function(){'focus'===V.trigger?i[0].focus():F.show()})},F.destroy=function(){w(),M(),O.$destroy()},F.enter=function(){return clearTimeout(I),U='in',V.delay&&V.delay.show?void(I=setTimeout(function(){'in'===U&&F.show()},V.delay.show)):F.show()},F.show=function(){if(V.bsEnabled&&!F.$isShown){O.$emit(V.prefixEvent+'.show.before',F),angular.isDefined(V.onBeforeShow)&&angular.isFunction(V.onBeforeShow)&&V.onBeforeShow(F);var e,t;V.container?(e=R,t=R[0].lastChild?angular.element(R[0].lastChild):null):(e=null,t=i),B&&M(),Y=F.$scope.$new(),B=F.$element=L.link(Y,function(e,t){}),B.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),V.animation&&B.addClass(V.animation),V.type&&B.addClass(V.prefixClass+'-'+V.type),V.customClass&&B.addClass(V.customClass),t?t.after(B):e.prepend(B),F.$isShown=O.$isShown=!0,g(O),F.$applyPlacement(),angular.version.minor<=2?l.enter(B,e,t,s):l.enter(B,e,t).then(s),g(O),d(function(){B&&B.css({visibility:'visible'}),V.keyboard&&('focus'!==V.trigger&&F.focus(),b())}),V.autoClose&&D()}},F.leave=function(){return clearTimeout(I),U='out',V.delay&&V.delay.hide?void(I=setTimeout(function(){'out'===U&&F.hide()},V.delay.hide)):F.hide()};var q,z;F.hide=function(e){F.$isShown&&(O.$emit(V.prefixEvent+'.hide.before',F),angular.isDefined(V.onBeforeHide)&&angular.isFunction(V.onBeforeHide)&&V.onBeforeHide(F),q=e,z=B,angular.version.minor<=2?l.leave(B,p):l.leave(B).then(p),F.$isShown=O.$isShown=!1,g(O),V.keyboard&&null!==B&&y(),V.autoClose&&null!==B&&S())},F.toggle=function(e){e&&e.preventDefault(),F.$isShown?F.leave():F.enter()},F.focus=function(){B[0].focus()},F.setEnabled=function(e){V.bsEnabled=e},F.setViewport=function(e){V.viewport=e},F.$applyPlacement=function(){if(B){var t=V.placement,n=/\s?auto?\s?/i,a=n.test(t);a&&(t=t.replace(n,'')||e.placement),B.addClass(V.placement);var o=x(),i=B.prop('offsetWidth'),r=B.prop('offsetHeight');if(F.$viewport=V.viewport&&m(V.viewport.selector||V.viewport),a){var s=t,l=x(F.$viewport);/bottom/.test(s)&&o.bottom+r>l.bottom?t=s.replace('bottom','top'):/top/.test(s)&&o.top-rl.width&&(t=t.replace('right','left')),B.removeClass(s).addClass(t)}var u=T(t,o,i,r);C(u,t)}},F.$onKeyUp=function(e){27===e.which&&F.$isShown&&(F.hide(),e.stopPropagation())},F.$onFocusKeyUp=function(e){27===e.which&&(i[0].blur(),e.stopPropagation())},F.$onFocusElementMouseDown=function(e){V.mouseDownPreventDefault&&e.preventDefault(),V.mouseDownStopPropagation&&e.stopPropagation(),F.$isShown?i[0].blur():i[0].focus()};var j=!1;return F}function g(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function m(e,n){return angular.element((n||t).querySelectorAll(e))}var $=/(ip[ao]d|iphone|android)/gi.test(n.navigator.userAgent),h='createTouch'in n.document&&$,v=angular.element(n.document);return p}]}).directive('bsTooltip',['$window','$location','$sce','$parse','$bsTooltip','$$rAF',function(e,t,n,a,o,i){return{restrict:'EAC',scope:!0,link:function(e,t,a,r){var s,l={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','titleTemplate','placement','container','delay','trigger','html','animation','backdropAnimation','type','customClass','id'],function(e){angular.isDefined(a[e])&&(l[e]=a[e])});var u=/^(false|0|)$/i;angular.forEach(['html','container'],function(e){angular.isDefined(a[e])&&u.test(a[e])&&(l[e]=!1)}),angular.forEach(['onBeforeShow','onShow','onBeforeHide','onHide'],function(t){var n='bs'+t.charAt(0).toUpperCase()+t.slice(1);angular.isDefined(a[n])&&(l[t]=e.$eval(a[n]))});var c=t.attr('data-target');angular.isDefined(c)&&(u.test(c)?l.target=!1:l.target=c),e.hasOwnProperty('title')||(e.title=''),a.$observe('title',function(t){if(angular.isDefined(t)||!e.hasOwnProperty('title')){var a=e.title;e.title=n.trustAsHtml(t),angular.isDefined(a)&&i(function(){s&&s.$applyPlacement()})}}),a.$observe('disabled',function(e){e&&s.$isShown&&s.hide()}),a.bsTooltip&&e.$watch(a.bsTooltip,function(t,n){angular.isObject(t)?angular.extend(e,t):e.title=t,angular.isDefined(n)&&i(function(){s&&s.$applyPlacement()})},!0),a.bsShow&&e.$watch(a.bsShow,function(e,t){s&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(tooltip),?/i)),e===!0?s.show():s.hide())}),a.bsEnabled&&e.$watch(a.bsEnabled,function(e,t){s&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|1|,?(tooltip),?/i)),e===!1?s.setEnabled(!1):s.setEnabled(!0))}),a.viewport&&e.$watch(a.viewport,function(e){s&&angular.isDefined(e)&&s.setViewport(e)}),s=o(t,l),e.$on('$destroy',function(){s&&s.destroy(),l=null,s=null})}}}]),angular.module('mgcrea.ngStrap.timepicker',['mgcrea.ngStrap.helpers.dateParser','mgcrea.ngStrap.helpers.dateFormatter','mgcrea.ngStrap.tooltip']).provider('$bsTimepicker',function(){var e=this.defaults={animation:'am-fade',defaultDate:'auto',prefixClass:'timepicker',placement:'bottom-left',templateUrl:'timepicker/timepicker.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,useNative:!0,timeType:'date',timeFormat:'shortTime',timezone:null,modelTimeFormat:null,autoclose:!1,minTime:-(1/0),maxTime:+(1/0),length:5,hourStep:1,minuteStep:5,secondStep:5,roundDisplay:!1,iconUp:'glyphicon glyphicon-chevron-up',iconDown:'glyphicon glyphicon-chevron-down',arrowBehavior:'pager'};this.$get=['$window','$document','$rootScope','$sce','$bsDateFormatter','$bsTooltip','$timeout',function(t,n,a,o,i,r,s){function l(t,n,a){function o(e){var t=6e4*g.minuteStep;return new Date(Math.floor(e.getTime()/t)*t)}function l(e,n){var a=e+n;if(t[0].createTextRange){var o=t[0].createTextRange();o.collapse(!0),o.moveStart('character',e),o.moveEnd('character',a),o.select()}else t[0].setSelectionRange?t[0].setSelectionRange(e,a):angular.isUndefined(t[0].selectionStart)&&(t[0].selectionStart=e,t[0].selectionEnd=a)}function d(){t[0].focus()}var f=r(t,angular.extend({},e,a)),p=a.scope,g=f.$options,m=f.$scope,$=g.lang,h=function(e,t,n){return i.formatDate(e,t,$,n)},v=0,w=g.roundDisplay?o(new Date):new Date,b=n.$dateValue||w,y={hour:b.getHours(),meridian:b.getHours()<12,minute:b.getMinutes(),second:b.getSeconds(),millisecond:b.getMilliseconds()},D=i.getDatetimeFormat(g.timeFormat,$),S=i.hoursFormat(D),k=i.timeSeparator(D),x=i.minutesFormat(D),T=i.secondsFormat(D),C=i.showSeconds(D),E=i.showAM(D);m.$iconUp=g.iconUp,m.$iconDown=g.iconDown,m.$select=function(e,t){f.select(e,t)},m.$moveIndex=function(e,t){f.$moveIndex(e,t)},m.$switchMeridian=function(e){f.switchMeridian(e)},f.update=function(e){angular.isDate(e)&&!isNaN(e.getTime())?(f.$date=e,angular.extend(y,{hour:e.getHours(),minute:e.getMinutes(),second:e.getSeconds(),millisecond:e.getMilliseconds()}),f.$build()):f.$isBuilt||f.$build()},f.select=function(e,t,a){n.$dateValue&&!isNaN(n.$dateValue.getTime())||(n.$dateValue='today'===g.defaultDate?new Date:new Date(1970,0,1)),angular.isDate(e)||(e=new Date(e)),0===t?n.$dateValue.setHours(e.getHours()):1===t?n.$dateValue.setMinutes(e.getMinutes()):2===t&&n.$dateValue.setSeconds(e.getSeconds()),n.$setViewValue(angular.copy(n.$dateValue)),n.$render(),g.autoclose&&!a&&s(function(){f.hide(!0)})},f.switchMeridian=function(e){if(n.$dateValue&&!isNaN(n.$dateValue.getTime())){var t=(e||n.$dateValue).getHours();n.$dateValue.setHours(12>t?t+12:t-12),n.$setViewValue(angular.copy(n.$dateValue)),n.$render()}},f.$build=function(){var e,t,n=m.midIndex=parseInt(g.length/2,10),a=[];for(e=0;e1*g.maxTime},m.$arrowAction=function(e,t){'picker'===g.arrowBehavior?f.$setTimeByStep(e,t):f.$moveIndex(e,t)},f.$setTimeByStep=function(e,t){var n=new Date(f.$date||b),a=n.getHours(),o=n.getMinutes(),i=n.getSeconds();0===t?n.setHours(a-parseInt(g.hourStep,10)*e):1===t?n.setMinutes(o-parseInt(g.minuteStep,10)*e):2===t&&n.setSeconds(i-parseInt(g.secondStep,10)*e),f.select(n,t,!0)},f.$moveIndex=function(e,t){var n;0===t?(n=new Date(1970,0,1,y.hour+e*g.length,y.minute,y.second),angular.extend(y,{hour:n.getHours()})):1===t?(n=new Date(1970,0,1,y.hour,y.minute+e*g.length*g.minuteStep,y.second),angular.extend(y,{minute:n.getMinutes()})):2===t&&(n=new Date(1970,0,1,y.hour,y.minute,y.second+e*g.length*g.secondStep),angular.extend(y,{second:n.getSeconds()})),f.$build()},f.$onMouseDown=function(e){if('input'!==e.target.nodeName.toLowerCase()&&e.preventDefault(),e.stopPropagation(),c){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},f.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return void f.hide(!0);var t=new Date(f.$date),n=t.getHours(),a=h(t,S).length,o=t.getMinutes(),i=h(t,x).length,r=t.getSeconds(),s=h(t,T).length,u=1,c=/(37|39)/.test(e.keyCode),d=2+1*C+1*E;c&&(37===e.keyCode?v=1>v?d-1:v-1:39===e.keyCode&&(v=d-1>v?v+1:0));var m=[0,a],$=0;38===e.keyCode&&($=-1),40===e.keyCode&&($=1);var w=2===v&&C,b=2===v&&!C||3===v&&C;0===v?(t.setHours(n+$*parseInt(g.hourStep,10)),a=h(t,S).length,m=[0,a]):1===v?(t.setMinutes(o+$*parseInt(g.minuteStep,10)),i=h(t,x).length,m=[a+u,i]):w?(t.setSeconds(r+$*parseInt(g.secondStep,10)),s=h(t,T).length,m=[a+u+i+u,s]):b&&(c||f.switchMeridian(),m=[a+u+i+u+(s+u)*C,2]),f.select(t,v,!0),l(m[0],m[1]),p.$digest()}};var A=f.init;f.init=function(){return u&&g.useNative?(t.prop('type','time'),void t.css('-webkit-appearance','textfield')):(c&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',d)),void A())};var M=f.destroy;f.destroy=function(){u&&g.useNative&&t.off('click',d),M()};var F=f.show;f.show=function(){!c&&t.attr('readonly')||t.attr('disabled')||(F(),s(function(){f.$element&&f.$element.on(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.on('keydown',f.$onKeyDown)},0,!1))};var V=f.hide;return f.hide=function(e){f.$isShown&&(f.$element&&f.$element.off(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.off('keydown',f.$onKeyDown),V(e))},f}var u=/(ip[ao]d|iphone|android)/gi.test(t.navigator.userAgent),c='createTouch'in t.document&&u;return e.lang||(e.lang=i.getDefaultLocale()),l.defaults=e,l}]}).directive('bsTimepicker',['$window','$parse','$q','$bsDateFormatter','$bsDateParser','$bsTimepicker',function(e,t,a,o,i,r){var s=r.defaults,l=/(ip[ao]d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,a,u){function c(e){if(angular.isDate(e)){var t=isNaN(f.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=f.minTime,n=isNaN(f.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=f.maxTime,a=t&&n;u.$setValidity('date',a),u.$setValidity('min',t),u.$setValidity('max',n),a&&(u.$dateValue=e)}}function d(){return!u.$dateValue||isNaN(u.$dateValue.getTime())?'':$(u.$dateValue,f.timeFormat)}var f={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent','defaultDate'],function(e){angular.isDefined(a[e])&&(f[e]=a[e])});var p=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(a[e])&&p.test(a[e])&&(f[e]=!1)}),angular.forEach(['onBeforeShow','onShow','onBeforeHide','onHide'],function(t){var n='bs'+t.charAt(0).toUpperCase()+t.slice(1);angular.isDefined(a[n])&&(f[t]=e.$eval(a[n]))}),l&&(f.useNative||s.useNative)&&(f.timeFormat='HH:mm');var g=r(t,u,f);f=g.$options;var m=f.lang,$=function(e,t,n){return o.formatDate(e,t,m,n)};a.bsShow&&e.$watch(a.bsShow,function(e,t){g&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?g.show():g.hide())});var h=i({format:f.timeFormat,lang:m});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(a[e])&&a.$observe(e,function(t){g.$options[e]=h.getTimeForAttribute(e,t),isNaN(g.$options[e])||g.$build(),c(u.$dateValue)})}),e.$watch(a.ngModel,function(e,t){g.update(u.$dateValue)},!0),u.$parsers.unshift(function(e){var t;if(!e)return u.$setValidity('date',!0),null;var a=angular.isDate(e)?e:h.parse(e,u.$dateValue);return!a||isNaN(a.getTime())?(u.$setValidity('date',!1),n):(c(a),'string'===f.timeType?(t=h.timezoneOffsetAdjust(a,f.timezone,!0),$(t,f.modelTimeFormat||f.timeFormat)):(t=h.timezoneOffsetAdjust(u.$dateValue,f.timezone,!0),'number'===f.timeType?t.getTime():'unix'===f.timeType?t.getTime()/1e3:'iso'===f.timeType?t.toISOString():new Date(t)))}),u.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?NaN:angular.isDate(e)?e:'string'===f.timeType?h.parse(e,null,f.modelTimeFormat):'unix'===f.timeType?new Date(1e3*e):new Date(e),u.$dateValue=h.timezoneOffsetAdjust(t,f.timezone),d()}),u.$render=function(){t.val(d())},e.$on('$destroy',function(){g&&g.destroy(),f=null,g=null})}}}]),angular.module('mgcrea.ngStrap.scrollspy',['mgcrea.ngStrap.helpers.debounce','mgcrea.ngStrap.helpers.dimensions']).provider('$bsScrollspy',function(){var e=this.$$spies={},n=this.defaults={debounce:150,throttle:100,offset:100};this.$get=['$window','$document','$rootScope','bsDimensions','bsDebounce','bsThrottle',function(a,o,i,r,s,l){function u(e,t){return e[0].nodeName&&e[0].nodeName.toLowerCase()===t.toLowerCase()}function c(o){var c=angular.extend({},n,o);c.element||(c.element=p);var g=u(c.element,'body'),m=g?d:c.element,$=g?'window':c.id;if(e[$])return e[$].$$count++,e[$];var h,v,w,b,y,D,S,k,x={},T=x.$trackedElements=[],C=[];return x.init=function(){this.$$count=1,b=s(this.checkPosition,c.debounce),y=l(this.checkPosition,c.throttle),m.on('click',this.checkPositionWithEventLoop),d.on('resize',b),m.on('scroll',y),D=s(this.checkOffsets,c.debounce),h=i.$on('$viewContentLoaded',D),v=i.$on('$includeContentLoaded',D),D(),$&&(e[$]=x)},x.destroy=function(){this.$$count--,this.$$count>0||(m.off('click',this.checkPositionWithEventLoop),d.off('resize',b),m.off('scroll',y),h(),v(),$&&delete e[$])},x.checkPosition=function(){if(C.length){if(k=(g?a.pageYOffset:m.prop('scrollTop'))||0,S=Math.max(a.innerHeight,f.prop('clientHeight')),kC[e+1].offsetTop))return x.$activateElement(C[e])}},x.checkPositionWithEventLoop=function(){setTimeout(x.checkPosition,1)},x.$activateElement=function(e){if(w){var t=x.$getTrackedElement(w);t&&(t.source.removeClass('active'),u(t.source,'li')&&u(t.source.parent().parent(),'li')&&t.source.parent().parent().removeClass('active'))}w=e.target,e.source.addClass('active'),u(e.source,'li')&&u(e.source.parent().parent(),'li')&&e.source.parent().parent().addClass('active')},x.$getTrackedElement=function(e){return T.filter(function(t){return t.target===e})[0]},x.checkOffsets=function(){angular.forEach(T,function(e){var n=t.querySelector(e.target);e.offsetTop=n?r.offset(n).top:null,c.offset&&null!==e.offsetTop&&(e.offsetTop-=1*c.offset)}),C=T.filter(function(e){return null!==e.offsetTop}).sort(function(e,t){return e.offsetTop-t.offsetTop}),b()},x.trackElement=function(e,t){T.push({target:e,source:t})},x.untrackElement=function(e,t){for(var n,a=T.length;a--;)if(T[a].target===e&&T[a].source===t){n=a;break}T.splice(n,1)},x.activate=function(e){T[e].addClass('active')},x.init(),x}var d=angular.element(a),f=angular.element(o.prop('documentElement')),p=angular.element(a.document.body);return c}]}).directive('bsScrollspy',['$rootScope','bsDebounce','bsDimensions','$bsScrollspy',function(e,t,n,a){return{restrict:'EAC',link:function(e,t,n){var o={scope:e};angular.forEach(['offset','target'],function(e){angular.isDefined(n[e])&&(o[e]=n[e])});var i=a(o);i.trackElement(o.target,t),e.$on('$destroy',function(){i&&(i.untrackElement(o.target,t),i.destroy()),o=null,i=null})}}}]).directive('bsScrollspyList',['$rootScope','bsDebounce','bsDimensions','$bsScrollspy',function(e,t,n,a){return{restrict:'A',compile:function(e,t){var n=e[0].querySelectorAll('li > a[href]');angular.forEach(n,function(e){var t=angular.element(e);t.parent().attr('bs-scrollspy','').attr('data-target',t.attr('href'))})}}}]),angular.module('mgcrea.ngStrap.select',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$bsSelect',function(){var e=this.defaults={animation:'am-fade',prefixClass:'select',prefixEvent:'$select',placement:'bottom-left',templateUrl:'select/select.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,multiple:!1,allNoneButtons:!1,sort:!0,caretHtml:' ',placeholder:'Choose among the following...',allText:'All',noneText:'None',maxLength:3, +maxLengthHtml:'selected',iconCheckmark:'glyphicon glyphicon-ok',toggle:!1};this.$get=['$window','$document','$rootScope','$bsTooltip','$timeout',function(t,a,o,i,r){function s(o,s,l){var c={},d=angular.extend({},e,l);c=i(o,d);var f=c.$scope;f.$matches=[],d.multiple?f.$activeIndex=[]:f.$activeIndex=-1,f.$isMultiple=d.multiple,f.$showAllNoneButtons=d.allNoneButtons&&d.multiple,f.$iconCheckmark=d.iconCheckmark,f.$allText=d.allText,f.$noneText=d.noneText,f.$activate=function(e){f.$$postDigest(function(){c.activate(e)})},f.$select=function(e,t){f.$$postDigest(function(){c.select(e)})},f.$isVisible=function(){return c.$isVisible()},f.$isActive=function(e){return c.$isActive(e)},f.$selectAll=function(){for(var e=0;ee||e>=f.$matches.length)){var t=f.$matches[e].value;f.$apply(function(){c.activate(e),d.multiple?s.$setViewValue(f.$activeIndex.map(function(e){return angular.isUndefined(f.$matches[e])?null:f.$matches[e].value})):(d.toggle?s.$setViewValue(t===s.$modelValue?n:t):s.$setViewValue(t),c.hide())}),f.$emit(d.prefixEvent+'.select',t,e,c),angular.isDefined(d.onSelect)&&angular.isFunction(d.onSelect)&&d.onSelect(t,e,c)}},c.$updateActiveIndex=function(){d.multiple?angular.isArray(s.$modelValue)?f.$activeIndex=s.$modelValue.map(function(e){return c.$getIndex(e)}):f.$activeIndex=[]:angular.isDefined(s.$modelValue)&&f.$matches.length?f.$activeIndex=c.$getIndex(s.$modelValue):f.$activeIndex=-1},c.$isVisible=function(){return d.minLength&&s?f.$matches.length&&s.$viewValue.length>=d.minLength:f.$matches.length},c.$isActive=function(e){return d.multiple?-1!==f.$activeIndex.indexOf(e):f.$activeIndex===e},c.$getIndex=function(e){var t;for(t=f.$matches.length;t--&&!angular.equals(f.$matches[t].value,e););return t},c.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),u){var t=angular.element(e.target);t.triggerHandler('click')}},c.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(9!==e.keyCode&&(e.preventDefault(),e.stopPropagation()),d.multiple&&9===e.keyCode?c.hide():d.multiple||13!==e.keyCode&&9!==e.keyCode?void(d.multiple||(38===e.keyCode&&f.$activeIndex>0?f.$activeIndex--:38===e.keyCode&&f.$activeIndex<0?f.$activeIndex=f.$matches.length-1:40===e.keyCode&&f.$activeIndex0||e.indexOf('Trident/')>0||e.indexOf('Edge/')>0},c.$selectScrollFix=function(e){'UL'===a[0].activeElement.tagName&&(e.preventDefault(),e.stopImmediatePropagation(),e.target.focus())};var p=c.show;c.show=function(){p(),d.multiple&&c.$element.addClass('select-multiple'),r(function(){c.$element.on(u?'touchstart':'mousedown',c.$onMouseDown),d.keyboard&&o.on('keydown',c.$onKeyDown)},0,!1)};var g=c.hide;return c.hide=function(){!d.multiple&&angular.isUndefined(s.$modelValue)&&(f.$activeIndex=-1),c.$element.off(u?'touchstart':'mousedown',c.$onMouseDown),d.keyboard&&o.off('keydown',c.$onKeyDown),g(!0)},c}var l=/(ip[ao]d|iphone|android)/gi.test(t.navigator.userAgent),u='createTouch'in t.document&&l;return s.defaults=e,s}]}).directive('bsSelect',['$window','$parse','$q','$bsSelect','$bsParseOptions',function(e,t,n,a,o){var i=a.defaults;return{restrict:'EAC',require:'ngModel',link:function(e,t,n,r){var s={scope:e,placeholder:i.placeholder};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','placeholder','allNoneButtons','maxLength','maxLengthHtml','allText','noneText','iconCheckmark','autoClose','id','sort','caretHtml','prefixClass','prefixEvent','toggle'],function(e){angular.isDefined(n[e])&&(s[e]=n[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container','allNoneButtons','sort'],function(e){angular.isDefined(n[e])&&l.test(n[e])&&(s[e]=!1)}),angular.forEach(['onBeforeShow','onShow','onBeforeHide','onHide','onSelect'],function(t){var a='bs'+t.charAt(0).toUpperCase()+t.slice(1);angular.isDefined(n[a])&&(s[t]=e.$eval(n[a]))});var u=t.attr('data-multiple');if(angular.isDefined(u)&&(l.test(u)?s.multiple=!1:s.multiple=u),'select'===t[0].nodeName.toLowerCase()){var c=t;c.css('display','none'),t=angular.element(''),c.after(t)}var d=o(n.bsOptions),f=a(t,r,s);f.$isIE()&&t[0].addEventListener('blur',f.$selectScrollFix);var p=d.$match[7].replace(/\|.+/,'').trim();e.$watch(p,function(t,n){d.valuesFn(e,r).then(function(e){f.update(e),r.$render()})},!0),e.$watch(n.ngModel,function(e,t){f.$updateActiveIndex(),r.$render()},!0),r.$render=function(){var e,n;s.multiple&&angular.isArray(r.$modelValue)?(e=r.$modelValue.map(function(e){return n=f.$getIndex(e),-1!==n?f.$scope.$matches[n].label:!1}).filter(angular.isDefined),e=e.length>(s.maxLength||i.maxLength)?e.length+' '+(s.maxLengthHtml||i.maxLengthHtml):e.join(', ')):(n=f.$getIndex(r.$modelValue),e=-1!==n?f.$scope.$matches[n].label:!1),t.html((e||s.placeholder)+(s.caretHtml||i.caretHtml))},s.multiple&&(r.$isEmpty=function(e){return!e||0===e.length}),e.$on('$destroy',function(){f&&f.destroy(),s=null,f=null})}}}]),angular.module('mgcrea.ngStrap.popover',['mgcrea.ngStrap.tooltip']).provider('$bsPopover',function(){var e=this.defaults={animation:'am-fade',customClass:'',container:!1,target:!1,placement:'right',templateUrl:'popover/popover.tpl.html',contentTemplate:!1,trigger:'click',keyboard:!0,html:!1,title:'',content:'',delay:0,autoClose:!1};this.$get=['$bsTooltip',function(t){function n(n,a){var o=angular.extend({},e,a),i=t(n,o);return o.content&&(i.$scope.content=o.content),i}return n}]}).directive('bsPopover',['$window','$sce','$bsPopover',function(e,t,n){var a=e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,o,i){var r,s={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','container','delay','trigger','html','animation','customClass','autoClose','id','prefixClass','prefixEvent'],function(e){angular.isDefined(i[e])&&(s[e]=i[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container','autoClose'],function(e){angular.isDefined(i[e])&&l.test(i[e])&&(s[e]=!1)}),angular.forEach(['onBeforeShow','onShow','onBeforeHide','onHide'],function(t){var n='bs'+t.charAt(0).toUpperCase()+t.slice(1);angular.isDefined(i[n])&&(s[t]=e.$eval(i[n]))});var u=o.attr('data-target');angular.isDefined(u)&&(l.test(u)?s.target=!1:s.target=u),angular.forEach(['title','content'],function(n){i[n]&&i.$observe(n,function(o,i){e[n]=t.trustAsHtml(o),angular.isDefined(i)&&a(function(){r&&r.$applyPlacement()})})}),i.bsPopover&&e.$watch(i.bsPopover,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t,angular.isDefined(n)&&a(function(){r&&r.$applyPlacement()})},!0),i.bsShow&&e.$watch(i.bsShow,function(e,t){r&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(popover),?/i)),e===!0?r.show():r.hide())}),i.viewport&&e.$watch(i.viewport,function(e){r&&angular.isDefined(e)&&r.setViewport(e)}),r=n(o,s),e.$on('$destroy',function(){r&&r.destroy(),s=null,r=null})}}}]),angular.module('mgcrea.ngStrap.navbar',[]).provider('$bsNavbar',function(){var e=this.defaults={activeClass:'active',routeAttr:'data-match-route',strict:!1};this.$get=function(){return{defaults:e}}}).directive('bsNavbar',['$window','$location','$bsNavbar',function(e,t,n){var a=n.defaults;return{restrict:'A',link:function(e,n,o,i){var r=angular.copy(a);angular.forEach(Object.keys(a),function(e){angular.isDefined(o[e])&&(r[e]=o[e])}),e.$watch(function(){return t.path()},function(e,t){var a=n[0].querySelectorAll('li['+r.routeAttr+']');angular.forEach(a,function(t){var n=angular.element(t),a=n.attr(r.routeAttr).replace('/','\\/');r.strict&&(a='^'+a+'$');var o=new RegExp(a,'i');o.test(e)?n.addClass(r.activeClass):n.removeClass(r.activeClass)})})}}}]),angular.module('mgcrea.ngStrap.modal',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$bsModal',function(){var e=this.defaults={animation:'am-fade',backdropAnimation:'am-fade',customClass:'',prefixClass:'modal',prefixEvent:'modal',placement:'top',templateUrl:'modal/modal.tpl.html',template:'',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0,size:null};this.$get=['$window','$rootScope','$bsCompiler','$animate','$timeout','$sce','bsDimensions',function(n,a,o,i,r,s,l){function u(t){function n(){C.$emit(x.prefixEvent+'.show',k),angular.isDefined(x.onShow)&&angular.isFunction(x.onShow)&&x.onShow(k)}function r(){C.$emit(x.prefixEvent+'.hide',k),angular.isDefined(x.onHide)&&angular.isFunction(x.onHide)&&x.onHide(k),g.removeClass(x.prefixClass+'-open'),x.animation&&g.removeClass(x.prefixClass+'-with-'+x.animation)}function l(){x.backdrop&&(A.on('click',y),F.on('click',y),F.on('wheel',D))}function u(){x.backdrop&&(A.off('click',y),F.off('click',y),F.off('wheel',D))}function w(){x.keyboard&&A.on('keyup',k.$onKeyUp)}function b(){x.keyboard&&A.off('keyup',k.$onKeyUp)}function y(e){e.target===e.currentTarget&&('static'===x.backdrop?k.focus():k.hide())}function D(e){e.preventDefault()}function S(){k.$isShown&&null!==A&&(u(),b()),M&&(M.$destroy(),M=null),A&&(A.remove(),A=k.$element=null)}var k={},x=k.$options=angular.extend({},e,t),T=k.$promise=o.compile(x),C=k.$scope=x.scope&&x.scope.$new()||a.$new();x.element||x.container||(x.container='body'),k.$id=x.id||x.element&&x.element.attr('id')||'',f(['title','content'],function(e){x[e]&&(C[e]=s.trustAsHtml(x[e]))}),C.$hide=function(){C.$$postDigest(function(){k.hide()})},C.$show=function(){C.$$postDigest(function(){k.show()})},C.$toggle=function(){C.$$postDigest(function(){k.toggle()})},k.$isShown=C.$isShown=!1;var E,A,M,F=angular.element('
');return F.css({position:'fixed',top:'0px',left:'0px',bottom:'0px',right:'0px'}),T.then(function(e){E=e,k.init()}),k.init=function(){x.show&&C.$$postDigest(function(){k.show()})},k.destroy=function(){S(),F&&(F.remove(),F=null),C.$destroy()},k.show=function(){if(!k.$isShown){var e,t;if(angular.isElement(x.container)?(e=x.container,t=x.container[0].lastChild?angular.element(x.container[0].lastChild):null):x.container?(e=d(x.container),t=e[0]&&e[0].lastChild?angular.element(e[0].lastChild):null):(e=null,t=x.element),A&&S(),M=k.$scope.$new(),A=k.$element=E.link(M,function(e,t){}),x.backdrop&&(A.css({'z-index':$+20*m}),F.css({'z-index':h+20*m}),m++),!C.$emit(x.prefixEvent+'.show.before',k).defaultPrevented){angular.isDefined(x.onBeforeShow)&&angular.isFunction(x.onBeforeShow)&&x.onBeforeShow(k),A.css({display:'block'}).addClass(x.placement),x.customClass&&A.addClass(x.customClass),x.size&&v[x.size]&&angular.element(d('.modal-dialog',A[0])).addClass(v[x.size]),x.animation&&(x.backdrop&&F.addClass(x.backdropAnimation),A.addClass(x.animation)),x.backdrop&&i.enter(F,g,null),angular.version.minor<=2?i.enter(A,e,t,n):i.enter(A,e,t).then(n),k.$isShown=C.$isShown=!0,c(C);var a=A[0];p(function(){a.focus()}),g.addClass(x.prefixClass+'-open'),x.animation&&g.addClass(x.prefixClass+'-with-'+x.animation),l(),w()}}},k.hide=function(){k.$isShown&&(C.$emit(x.prefixEvent+'.hide.before',k).defaultPrevented||(angular.isDefined(x.onBeforeHide)&&angular.isFunction(x.onBeforeHide)&&x.onBeforeHide(k),angular.version.minor<=2?i.leave(A,r):i.leave(A).then(r),x.backdrop&&(m--,i.leave(F)),k.$isShown=C.$isShown=!1,c(C),u(),b()))},k.toggle=function(){k.$isShown?k.hide():k.show()},k.focus=function(){A[0].focus()},k.$onKeyUp=function(e){27===e.which&&k.$isShown&&(k.hide(),e.stopPropagation())},k}function c(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function d(e,n){return angular.element((n||t).querySelectorAll(e))}var f=angular.forEach,p=n.requestAnimationFrame||n.setTimeout,g=angular.element(n.document.body),m=0,$=1050,h=1040,v={lg:'modal-lg',sm:'modal-sm'};return u}]}).directive('bsModal',['$window','$sce','$parse','$bsModal',function(e,t,n,a){return{restrict:'EAC',scope:!0,link:function(e,n,o,i){var r={scope:e,element:n,show:!1};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','backdrop','keyboard','html','container','animation','backdropAnimation','id','prefixEvent','prefixClass','customClass','modalClass','size'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])}),r.modalClass&&(r.customClass=r.modalClass);var s=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),angular.forEach(['onBeforeShow','onShow','onBeforeHide','onHide'],function(t){var n='bs'+t.charAt(0).toUpperCase()+t.slice(1);angular.isDefined(o[n])&&(r[t]=e.$eval(o[n]))}),angular.forEach(['title','content'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsModal&&e.$watch(o.bsModal,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=a(r);n.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.module('mgcrea.ngStrap.dropdown',['mgcrea.ngStrap.tooltip']).provider('$bsDropdown',function(){var e=this.defaults={animation:'am-fade',prefixClass:'dropdown',prefixEvent:'dropdown',placement:'bottom-left',templateUrl:'dropdown/dropdown.tpl.html',trigger:'click',container:!1,keyboard:!0,html:!1,delay:0};this.$get=['$window','$rootScope','$bsTooltip','$timeout',function(t,n,a,o){function i(t,i){function l(e){return e.target!==t[0]?e.target!==t[0]&&u.hide():void 0}var u={},c=angular.extend({},e,i);u.$scope=c.scope&&c.scope.$new()||n.$new(),u=a(t,c);var d=t.parent();u.$onKeyDown=function(e){if(/(38|40)/.test(e.keyCode)){e.preventDefault(),e.stopPropagation();var t=angular.element(u.$element[0].querySelectorAll('li:not(.divider) a'));if(t.length){var n;angular.forEach(t,function(e,t){s&&s.call(e,':focus')&&(n=t)}),38===e.keyCode&&n>0?n--:40===e.keyCode&&n=0&&(t.template=o.outerHTML,t.templateUrl=n,o.parentNode.removeChild(o))}return function(e,n,o){var i={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','id','autoClose'],function(e){angular.isDefined(t[e])&&(i[e]=t[e])});var r=/^(false|0|)$/i;angular.forEach(['html','container'],function(e){angular.isDefined(o[e])&&r.test(o[e])&&(i[e]=!1)}),angular.forEach(['onBeforeShow','onShow','onBeforeHide','onHide'],function(t){var n='bs'+t.charAt(0).toUpperCase()+t.slice(1);angular.isDefined(o[n])&&(i[t]=e.$eval(o[n]))}),o.bsDropdown&&e.$watch(o.bsDropdown,function(t,n){e.content=t},!0);var s=a(n,i);o.bsShow&&e.$watch(o.bsShow,function(e,t){s&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(dropdown),?/i)),e===!0?s.show():s.hide())}),e.$on('$destroy',function(){s&&s.destroy(),i=null,s=null})}}}}]),angular.version.minor<3&&angular.version.dot<14&&angular.module('ng').factory('$$rAF',['$window','$timeout',function(e,t){var n=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame,a=e.cancelAnimationFrame||e.webkitCancelAnimationFrame||e.mozCancelAnimationFrame||e.webkitCancelRequestAnimationFrame,o=!!n,i=o?function(e){var t=n(e);return function(){a(t)}}:function(e){var n=t(e,16.66,!1);return function(){t.cancel(n)}};return i.supported=o,i}]),angular.module('mgcrea.ngStrap.helpers.parseOptions',[]).provider('$bsParseOptions',function(){var e=this.defaults={regexp:/^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/};this.$get=['$parse','$q',function(t,n){function a(a,o){function i(e,t){return e.map(function(e,n){var a,o,i={};return i[c]=e,a=u(t,i),o=p(t,i),{label:a,value:o,index:n}})}var r={},s=angular.extend({},e,o);r.$values=[];var l,u,c,d,f,p,g;return r.init=function(){r.$match=l=a.match(s.regexp),u=t(l[2]||l[1]),c=l[4]||l[6],d=l[5],f=t(l[3]||''),p=t(l[2]?l[1]:c),g=t(l[7])},r.valuesFn=function(e,t){return n.when(g(e,t)).then(function(t){return angular.isArray(t)||(t=[]),r.$values=t.length?i(t,e):[],r.$values})},r.displayValue=function(e){var t={};return t[c]=e,u(t)},r.init(),r}return a}]}),angular.module('mgcrea.ngStrap.helpers.dimensions',[]).factory('bsDimensions',function(){function t(e){var t=e.ownerDocument,o=e.offsetParent||t;if(a(o,'#document'))return t.documentElement;for(;o&&!a(o,'html')&&'static'===n.css(o,'position');)o=o.offsetParent;return o||t.documentElement}var n={},a=n.nodeName=function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()};return n.css=function(t,n,a){var o;return o=t.currentStyle?t.currentStyle[n]:e.getComputedStyle?e.getComputedStyle(t)[n]:t.style[n],a===!0?parseFloat(o)||0:o},n.offset=function(t){var n=t.getBoundingClientRect(),a=t.ownerDocument;return{width:n.width||t.offsetWidth,height:n.height||t.offsetHeight,top:n.top+(e.pageYOffset||a.documentElement.scrollTop)-(a.documentElement.clientTop||0),left:n.left+(e.pageXOffset||a.documentElement.scrollLeft)-(a.documentElement.clientLeft||0)}},n.setOffset=function(e,t,a){var o,i,r,s,l,u,c,d=n.css(e,'position'),f=angular.element(e),p={};'static'===d&&(e.style.position='relative'),l=n.offset(e),r=n.css(e,'top'),u=n.css(e,'left'),c=('absolute'===d||'fixed'===d)&&(r+u).indexOf('auto')>-1,c?(o=n.position(e),s=o.top,i=o.left):(s=parseFloat(r)||0,i=parseFloat(u)||0),angular.isFunction(t)&&(t=t.call(e,a,l)),null!==t.top&&(p.top=t.top-l.top+s),null!==t.left&&(p.left=t.left-l.left+i),'using'in t?t.using.call(f,p):f.css({top:p.top+'px',left:p.left+'px'})},n.position=function(e){var o,i,r={top:0,left:0};return'fixed'===n.css(e,'position')?i=e.getBoundingClientRect():(o=t(e),i=n.offset(e),a(o,'html')||(r=n.offset(o)),r.top+=n.css(o,'borderTopWidth',!0),r.left+=n.css(o,'borderLeftWidth',!0)),{width:e.offsetWidth,height:e.offsetHeight,top:i.top-r.top-n.css(e,'marginTop',!0),left:i.left-r.left-n.css(e,'marginLeft',!0)}},n.height=function(e,t){var a=e.offsetHeight;return t?a+=n.css(e,'marginTop',!0)+n.css(e,'marginBottom',!0):a-=n.css(e,'paddingTop',!0)+n.css(e,'paddingBottom',!0)+n.css(e,'borderTopWidth',!0)+n.css(e,'borderBottomWidth',!0),a},n.width=function(e,t){var a=e.offsetWidth;return t?a+=n.css(e,'marginLeft',!0)+n.css(e,'marginRight',!0):a-=n.css(e,'paddingLeft',!0)+n.css(e,'paddingRight',!0)+n.css(e,'borderLeftWidth',!0)+n.css(e,'borderRightWidth',!0),a},n}),angular.module('mgcrea.ngStrap.helpers.debounce',[]).factory('bsDebounce',['$timeout',function(e){return function(t,n,a){var o=null;return function(){var i=this,r=arguments,s=a&&!o;return o&&e.cancel(o),o=e(function(){o=null,a||t.apply(i,r)},n,!1),s&&t.apply(i,r),o}}}]).factory('bsThrottle',['$timeout',function(e){return function(t,n,a){var o=null;return a||(a={}),function(){var i=this,r=arguments;o||(a.leading!==!1&&t.apply(i,r),o=e(function(){o=null,a.trailing!==!1&&t.apply(i,r)},n,!1))}}}]),angular.module('mgcrea.ngStrap.helpers.dateParser',[]).provider('$bsDateParser',['$localeProvider',function(e){function t(){this.year=1970,this.month=0,this.day=1,this.hours=0,this.minutes=0,this.seconds=0,this.milliseconds=0}function n(){}function a(e){return!isNaN(parseFloat(e))&&isFinite(e)}function o(e,t){for(var n=e.length,a=t.toString().toLowerCase(),o=0;n>o;o++)if(e[o].toLowerCase()===a)return o;return-1}t.prototype.setMilliseconds=function(e){this.milliseconds=e},t.prototype.setSeconds=function(e){this.seconds=e},t.prototype.setMinutes=function(e){this.minutes=e},t.prototype.setHours=function(e){this.hours=e},t.prototype.getHours=function(){return this.hours},t.prototype.setDate=function(e){this.day=e},t.prototype.setMonth=function(e){this.month=e},t.prototype.setFullYear=function(e){this.year=e},t.prototype.fromDate=function(e){return this.year=e.getFullYear(),this.month=e.getMonth(),this.day=e.getDate(),this.hours=e.getHours(),this.minutes=e.getMinutes(),this.seconds=e.getSeconds(),this.milliseconds=e.getMilliseconds(),this},t.prototype.toDate=function(){return new Date(this.year,this.month,this.day,this.hours,this.minutes,this.seconds,this.milliseconds)};var i=t.prototype,r=this.defaults={format:'shortDate',strict:!1};this.$get=['$locale','dateFilter',function(e,s){var l=function(l){function u(e){var t=c(e);return g(t)}function c(e){var t=d(e),n=t.replace(/''/g,'\\\''),a=/('(?:\\'|.)*?')/,o=n.split(a),i=Object.keys(y),r=[];return angular.forEach(o,function(e){if(f(e))e=p(e);else for(var t=0;t=1*e&&2===e.length?this.setFullYear(2e3+1*e):this.setFullYear(1*e)}};return b.init=function(){b.$format=e.DATETIME_FORMATS[w.format]||w.format,h=u(b.$format),v=m(b.$format)},b.isValid=function(e){return angular.isDate(e)?!isNaN(e.getTime()):h.test(e)},b.parse=function(n,a,o,i){o&&(o=e.DATETIME_FORMATS[o]||o),angular.isDate(n)&&(n=s(n,o||b.$format,i));var r=o?u(o):h,l=o?m(o):v,c=r.exec(n);if(!c)return!1;for(var d=a&&!isNaN(a.getTime())?(new t).fromDate(a):(new t).fromDate(new Date(1970,0,1,0)),f=0;f12?e.getHours()+2:0),e):null},b.timezoneOffsetAdjust=function(e,t,n){return e?(t&&'UTC'===t&&(e=new Date(e.getTime()),e.setMinutes(e.getMinutes()+(n?-1:1)*e.getTimezoneOffset())),e):null},b.init(),b};return l}]}]),angular.module('mgcrea.ngStrap.helpers.dateFormatter',[]).service('$bsDateFormatter',['$locale','dateFilter',function(e,t){function n(e){return/(h+)([:\.])?(m+)([:\.])?(s*)[ ]?(a?)/i.exec(e).slice(1)}this.getDefaultLocale=function(){return e.id},this.getDatetimeFormat=function(t,n){return e.DATETIME_FORMATS[t]||t},this.weekdaysShort=function(t){return e.DATETIME_FORMATS.SHORTDAY},this.hoursFormat=function(e){return n(e)[0]},this.minutesFormat=function(e){return n(e)[2]},this.secondsFormat=function(e){return n(e)[4]},this.timeSeparator=function(e){return n(e)[1]},this.showSeconds=function(e){return!!n(e)[4]},this.showAM=function(e){return!!n(e)[5]},this.formatDate=function(e,n,a,o){return t(e,n,o)}}]),angular.module('mgcrea.ngStrap.core',[]).service('$bsCompiler',a),angular.module('mgcrea.ngStrap.datepicker',['mgcrea.ngStrap.helpers.dateParser','mgcrea.ngStrap.helpers.dateFormatter','mgcrea.ngStrap.tooltip']).provider('$bsDatepicker',function(){var e=this.defaults={animation:'am-fade',prefixClass:'datepicker',placement:'bottom-left',templateUrl:'datepicker/datepicker.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,useNative:!1,dateType:'date',dateFormat:'shortDate',timezone:null,modelDateFormat:null,dayFormat:'dd',monthFormat:'MMM',yearFormat:'yyyy',monthTitleFormat:'MMMM yyyy',yearTitleFormat:'yyyy',strictFormat:!1,autoclose:!1,minDate:-(1/0),maxDate:+(1/0),startView:0,minView:0,startWeek:0,daysOfWeekDisabled:'',hasToday:!1,hasClear:!1,iconLeft:'glyphicon glyphicon-chevron-left',iconRight:'glyphicon glyphicon-chevron-right'};this.$get=['$window','$document','$rootScope','$sce','$bsDateFormatter','bsDatepickerViews','$bsTooltip','$timeout',function(t,n,a,o,i,r,s,l){function u(t,n,a){function o(e){e.selected=u.$isSelected(e.date)}function i(){t[0].focus()}var u=s(t,angular.extend({},e,a)),f=a.scope,p=u.$options,g=u.$scope;p.startView&&(p.startView-=p.minView);var m=r(u);u.$views=m.views;var $=m.viewDate;g.$mode=p.startView,g.$iconLeft=p.iconLeft,g.$iconRight=p.iconRight,g.$hasToday=p.hasToday,g.$hasClear=p.hasClear;var h=u.$views[g.$mode];g.$select=function(e){u.select(e)},g.$selectPane=function(e){u.$selectPane(e)},g.$toggleMode=function(){u.setMode((g.$mode+1)%u.$views.length)},g.$setToday=function(){p.autoclose?(u.setMode(0),u.select(new Date)):u.select(new Date,!0)},g.$clear=function(){p.autoclose?(u.setMode(0),u.select(null)):u.select(null,!0)},u.update=function(e){angular.isDate(e)&&!isNaN(e.getTime())&&(u.$date=e,h.update.call(h,e)),u.$build(!0)},u.updateDisabledDates=function(e){p.disabledDateRanges=e;for(var t=0,n=g.rows.length;n>t;t++)angular.forEach(g.rows[t],u.$setDisabledEl)},u.select=function(e,t){angular.isDate(e)?angular.isDate(n.$dateValue)&&!isNaN(n.$dateValue.getTime())||(n.$dateValue=new Date(e)):n.$dateValue=null,!g.$mode||t?(n.$setViewValue(angular.copy(e)),n.$render(),p.autoclose&&!t&&l(function(){u.hide(!0)})):(angular.extend($,{year:e.getFullYear(),month:e.getMonth(),date:e.getDate()}),u.setMode(g.$mode-1),u.$build())},u.setMode=function(e){g.$mode=e,h=u.$views[g.$mode],u.$build()},u.$build=function(e){e===!0&&h.built||(e!==!1||h.built)&&h.build.call(h)},u.$updateSelected=function(){for(var e=0,t=g.rows.length;t>e;e++)angular.forEach(g.rows[e],o)},u.$isSelected=function(e){return h.isSelected(e)},u.$setDisabledEl=function(e){e.disabled=h.isDisabled(e.date)},u.$selectPane=function(e){var t=h.steps,n=new Date(Date.UTC($.year+(t.year||0)*e,$.month+(t.month||0)*e,1));angular.extend($,{year:n.getUTCFullYear(),month:n.getUTCMonth(),date:n.getUTCDate()}),u.$build()},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),d){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},u.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return void(g.$mode?g.$apply(function(){u.setMode(g.$mode-1)}):u.hide(!0));h.onKeyDown(e),f.$digest()}};var v=u.init;u.init=function(){return c&&p.useNative?(t.prop('type','date'),void t.css('-webkit-appearance','textfield')):(d&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',i)),void v())};var w=u.destroy;u.destroy=function(){c&&p.useNative&&t.off('click',i),w()};var b=u.show;u.show=function(){!d&&t.attr('readonly')||t.attr('disabled')||(b(),l(function(){u.$isShown&&(u.$element.on(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.on('keydown',u.$onKeyDown))},0,!1))};var y=u.hide;return u.hide=function(e){u.$isShown&&(u.$element.off(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.off('keydown',u.$onKeyDown),y(e))},u}var c=/(ip[ao]d|iphone|android)/gi.test(t.navigator.userAgent),d='createTouch'in t.document&&c;return e.lang||(e.lang=i.getDefaultLocale()),u.defaults=e,u}]}).directive('bsDatepicker',['$window','$parse','$q','$bsDateFormatter','$bsDateParser','$bsDatepicker',function(e,t,n,a,o,i){var r=/(ip[ao]d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,n,s){function l(e){return e&&e.length?e:null}function u(e){if(angular.isDate(e)){var t=isNaN(p.$options.minDate)||e.getTime()>=p.$options.minDate,n=isNaN(p.$options.maxDate)||e.getTime()<=p.$options.maxDate,a=t&&n;s.$setValidity('date',a),s.$setValidity('min',t),s.$setValidity('max',n),a&&(s.$dateValue=e)}}function c(){return!s.$dateValue||isNaN(s.$dateValue.getTime())?'':m(s.$dateValue,d.dateFormat)}var d={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','html','animation','autoclose','dateType','dateFormat','timezone','modelDateFormat','dayFormat','strictFormat','startWeek','startDate','useNative','lang','startView','minView','iconLeft','iconRight','daysOfWeekDisabled','id','prefixClass','prefixEvent','hasToday','hasClear'],function(e){angular.isDefined(n[e])&&(d[e]=n[e])});var f=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','hasToday','hasClear'],function(e){angular.isDefined(n[e])&&f.test(n[e])&&(d[e]=!1)}),angular.forEach(['onBeforeShow','onShow','onBeforeHide','onHide'],function(t){var a='bs'+t.charAt(0).toUpperCase()+t.slice(1);angular.isDefined(n[a])&&(d[t]=e.$eval(n[a]))});var p=i(t,s,d);d=p.$options,r&&d.useNative&&(d.dateFormat='yyyy-MM-dd');var g=d.lang,m=function(e,t){return a.formatDate(e,t,g)},$=o({format:d.dateFormat,lang:g,strict:d.strictFormat});n.bsShow&&e.$watch(n.bsShow,function(e,t){p&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(datepicker),?/i)), +e===!0?p.show():p.hide())}),angular.forEach(['minDate','maxDate'],function(e){angular.isDefined(n[e])&&n.$observe(e,function(t){p.$options[e]=$.getDateForAttribute(e,t),isNaN(p.$options[e])||p.$build(!1),u(s.$dateValue)})}),angular.isDefined(n.dateFormat)&&n.$observe('dateFormat',function(e){p.$options.dateFormat=e}),e.$watch(n.ngModel,function(e,t){p.update(s.$dateValue)},!0),angular.isDefined(n.disabledDates)&&e.$watch(n.disabledDates,function(e,t){e=l(e),t=l(t),e&&p.updateDisabledDates(e)}),s.$parsers.unshift(function(e){var t;if(!e)return s.$setValidity('date',!0),null;var n=$.parse(e,s.$dateValue);return!n||isNaN(n.getTime())?void s.$setValidity('date',!1):(u(n),'string'===d.dateType?(t=$.timezoneOffsetAdjust(n,d.timezone,!0),m(t,d.modelDateFormat||d.dateFormat)):(t=$.timezoneOffsetAdjust(s.$dateValue,d.timezone,!0),'number'===d.dateType?t.getTime():'unix'===d.dateType?t.getTime()/1e3:'iso'===d.dateType?t.toISOString():new Date(t)))}),s.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?NaN:angular.isDate(e)?e:'string'===d.dateType?$.parse(e,null,d.modelDateFormat):'unix'===d.dateType?new Date(1e3*e):new Date(e),s.$dateValue=$.timezoneOffsetAdjust(t,d.timezone),c()}),s.$render=function(){t.val(c())},e.$on('$destroy',function(){p&&p.destroy(),d=null,p=null})}}}]).provider('bsDatepickerViews',function(){function e(e,t){for(var n=[];e.length>0;)n.push(e.splice(0,t));return n}function t(e,t){return(e%t+t)%t}this.$get=['$bsDateFormatter','$bsDateParser','$sce',function(n,a,o){return function(i){var r=i.$scope,s=i.$options,l=s.lang,u=function(e,t){return n.formatDate(e,t,l)},c=a({format:s.dateFormat,lang:l,strict:s.strictFormat}),d=n.weekdaysShort(l),f=d.slice(s.startWeek).concat(d.slice(0,s.startWeek)),p=o.trustAsHtml(''+f.join('')+''),g=i.$date||(s.startDate?c.getDateForAttribute('startDate',s.startDate):new Date),m={year:g.getFullYear(),month:g.getMonth(),date:g.getDate()},$=[{format:s.dayFormat,split:7,steps:{month:1},update:function(e,t){!this.built||t||e.getFullYear()!==m.year||e.getMonth()!==m.month?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):e.getDate()===m.date&&1!==e.getDate()||(m.date=i.$date.getDate(),i.$updateSelected())},build:function(){var n=new Date(m.year,m.month,1),a=n.getTimezoneOffset(),o=new Date(+n-864e5*t(n.getDay()-s.startWeek,7)),l=o.getTimezoneOffset(),d=c.timezoneOffsetAdjust(new Date,s.timezone).toDateString();l!==a&&(o=new Date(+o+6e4*(l-a)));for(var f,g=[],$=0;42>$;$++)f=c.daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth(),o.getDate()+$)),g.push({date:f,isToday:f.toDateString()===d,label:u(f,this.format),selected:i.$date&&this.isSelected(f),muted:f.getMonth()!==m.month,disabled:this.isDisabled(f)});r.title=u(n,s.monthTitleFormat),r.showLabels=!0,r.labels=p,r.rows=e(g,this.split),r.isTodayDisabled=this.isDisabled(new Date),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()&&e.getDate()===i.$date.getDate()},isDisabled:function(e){var t=e.getTime();if(ts.maxDate)return!0;if(-1!==s.daysOfWeekDisabled.indexOf(e.getDay()))return!0;if(s.disabledDateRanges)for(var n=0;n=s.disabledDateRanges[n].start&&t<=s.disabledDateRanges[n].end)return!0;return!1},onKeyDown:function(e){if(i.$date){var t,n=i.$date.getTime();37===e.keyCode?t=new Date(n-864e5):38===e.keyCode?t=new Date(n-6048e5):39===e.keyCode?t=new Date(n+864e5):40===e.keyCode&&(t=new Date(n+6048e5)),this.isDisabled(t)||i.select(t,!0)}}},{name:'month',format:s.monthFormat,split:4,steps:{year:1},update:function(e,t){this.built&&e.getFullYear()===m.year?e.getMonth()!==m.month&&(angular.extend(m,{month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected()):(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build())},build:function(){for(var t,n=[],a=0;12>a;a++)t=new Date(m.year,a,1),n.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=u(t,s.yearTitleFormat),r.showLabels=!1,r.rows=e(n,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()},isDisabled:function(e){var t=+new Date(e.getFullYear(),e.getMonth()+1,0);return ts.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getMonth(),n=new Date(i.$date);37===e.keyCode?n.setMonth(t-1):38===e.keyCode?n.setMonth(t-4):39===e.keyCode?n.setMonth(t+1):40===e.keyCode&&n.setMonth(t+4),this.isDisabled(n)||i.select(n,!0)}}},{name:'year',format:s.yearFormat,split:4,steps:{year:12},update:function(e,t){!this.built||t||parseInt(e.getFullYear()/20,10)!==parseInt(m.year/20,10)?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):e.getFullYear()!==m.year&&(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected())},build:function(){for(var t,n=m.year-m.year%(3*this.split),a=[],o=0;12>o;o++)t=new Date(n+o,0,1),a.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=a[0].label+'-'+a[a.length-1].label,r.showLabels=!1,r.rows=e(a,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()},isDisabled:function(e){var t=+new Date(e.getFullYear()+1,0,0);return ts.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getFullYear(),n=new Date(i.$date);37===e.keyCode?n.setYear(t-1):38===e.keyCode?n.setYear(t-4):39===e.keyCode?n.setYear(t+1):40===e.keyCode&&n.setYear(t+4),this.isDisabled(n)||i.select(n,!0)}}}];return{views:s.minView?Array.prototype.slice.call($,s.minView):$,viewDate:m}}}]}),angular.module('mgcrea.ngStrap.button',[]).provider('$bsButton',function(){var e=this.defaults={activeClass:'active',toggleEvent:'click'};this.$get=function(){return{defaults:e}}}).directive('bsCheckboxGroup',function(){return{restrict:'A',require:'ngModel',compile:function(e,t){e.attr('data-toggle','buttons'),e.removeAttr('ng-model');var n=e[0].querySelectorAll('input[type="checkbox"]');angular.forEach(n,function(e){var n=angular.element(e);n.attr('bs-checkbox',''),n.attr('ng-model',t.ngModel+'.'+n.attr('value'))})}}}).directive('bsCheckbox',['$bsButton','$$rAF',function(e,t){var n=e.defaults,a=/^(true|false|\d+)$/;return{restrict:'A',require:'ngModel',link:function(e,o,i,r){var s=n,l='INPUT'===o[0].nodeName,u=l?o.parent():o,c=angular.isDefined(i.trueValue)?i.trueValue:!0;a.test(i.trueValue)&&(c=e.$eval(i.trueValue));var d=angular.isDefined(i.falseValue)?i.falseValue:!1;a.test(i.falseValue)&&(d=e.$eval(i.falseValue));var f='boolean'!=typeof c||'boolean'!=typeof d;f&&(r.$parsers.push(function(e){return e?c:d}),r.$formatters.push(function(e){return angular.equals(e,c)}),e.$watch(i.ngModel,function(e,t){r.$render()})),r.$render=function(){var e=angular.equals(r.$modelValue,c);t(function(){l&&(o[0].checked=e),u.toggleClass(s.activeClass,e)})},o.bind(s.toggleEvent,function(){e.$apply(function(){l||r.$setViewValue(!u.hasClass('active')),f||r.$render()})})}}}]).directive('bsRadioGroup',function(){return{restrict:'A',require:'ngModel',compile:function(e,t){e.attr('data-toggle','buttons'),e.removeAttr('ng-model');var n=e[0].querySelectorAll('input[type="radio"]');angular.forEach(n,function(e){angular.element(e).attr('bs-radio',''),angular.element(e).attr('ng-model',t.ngModel)})}}}).directive('bsRadio',['$bsButton','$$rAF',function(e,t){var n=e.defaults,a=/^(true|false|\d+)$/;return{restrict:'A',require:'ngModel',link:function(e,o,i,r){var s,l=n,u='INPUT'===o[0].nodeName,c=u?o.parent():o;i.$observe('value',function(t){s='boolean'!=typeof t&&a.test(t)?e.$eval(t):t,r.$render()}),r.$render=function(){var e=angular.equals(r.$modelValue,s);t(function(){u&&(o[0].checked=e),c.toggleClass(l.activeClass,e)})},o.bind(l.toggleEvent,function(){e.$apply(function(){r.$setViewValue(s),r.$render()})})}}}]),angular.module('mgcrea.ngStrap.collapse',[]).provider('$bsCollapse',function(){var e=this.defaults={animation:'am-collapse',disallowToggle:!1,activeClass:'in',startCollapsed:!1,allowMultiple:!1},t=this.controller=function(t,n,a){function o(e){for(var t=l.$targets.$active,n=0;n=a?'top':null!==e&&a+e<=t.top?'middle':null!==w&&t.top+n+$>=o-w?'bottom':'middle'}function u(){return p[0]===t?t.pageYOffset:p[0].scrollTop}function c(){return p[0]===t?t.document.body.scrollHeight:p[0].scrollHeight}var d={},f=angular.extend({},e,s),p=f.target,g='affix affix-top affix-bottom',m=!1,$=0,h=0,v=0,w=0,b=null,y=null,D=o.parent();if(f.offsetParent)if(f.offsetParent.match(/^\d+$/))for(var S=0;S<1*f.offsetParent-1;S++)D=D.parent();else D=angular.element(f.offsetParent);return d.init=function(){this.$parseOffsets(),h=a.offset(o[0]).top+$,m=!o[0].style.width,p.on('scroll',this.checkPosition),p.on('click',this.checkPositionWithEventLoop),r.on('resize',this.$debouncedOnResize),this.checkPosition(),this.checkPositionWithEventLoop()},d.destroy=function(){p.off('scroll',this.checkPosition),p.off('click',this.checkPositionWithEventLoop),r.off('resize',this.$debouncedOnResize)},d.checkPositionWithEventLoop=function(){setTimeout(d.checkPosition,1)},d.checkPosition=function(){var e=u(),t=a.offset(o[0]),n=a.height(o[0]),r=l(y,t,n);b!==r&&(b=r,'top'===r?(y=null,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',''))):'bottom'===r?(y=f.offsetUnpin?-(1*f.offsetUnpin):t.top-e,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',f.offsetParent?'':i[0].offsetHeight-w-n-h+'px'))):(y=null,m&&o.css('width',o[0].offsetWidth+'px'),f.inlineStyles&&(o.css('position','fixed'),o.css('top',$+'px'))),o.removeClass(g).addClass('affix'+('middle'!==r?'-'+r:'')))},d.$onResize=function(){d.$parseOffsets(),d.checkPosition()},d.$debouncedOnResize=n(d.$onResize,50),d.$parseOffsets=function(){var e=o.css('position');f.inlineStyles&&o.css('position',f.offsetParent?'':'relative'),f.offsetTop&&('auto'===f.offsetTop&&(f.offsetTop='+0'),f.offsetTop.match(/^[-+]\d+$/)?($=1*-f.offsetTop,v=f.offsetParent?a.offset(D[0]).top+1*f.offsetTop:a.offset(o[0]).top-a.css(o[0],'marginTop',!0)+1*f.offsetTop):v=1*f.offsetTop),f.offsetBottom&&(w=f.offsetParent&&f.offsetBottom.match(/^[-+]\d+$/)?c()-(a.offset(D[0]).top+a.height(D[0]))+1*f.offsetBottom+1:1*f.offsetBottom),f.inlineStyles&&o.css('position',e)},d.init(),d}var i=angular.element(t.document.body),r=angular.element(t);return o}]}).directive('bsAffix',['$bsAffix','$window',function(e,t){return{restrict:'EAC',require:'^?bsAffixTarget',link:function(n,a,o,i){var r={scope:n,target:i?i.$element:angular.element(t)};angular.forEach(['offsetTop','offsetBottom','offsetParent','offsetUnpin','inlineStyles'],function(e){if(angular.isDefined(o[e])){var t=o[e];/true/i.test(t)&&(t=!0),/false/i.test(t)&&(t=!1),r[e]=t}});var s=e(a,r);n.$on('$destroy',function(){s&&s.destroy(),r=null,s=null})}}}]).directive('bsAffixTarget',function(){return{controller:['$element',function(e){this.$element=e}]}}),angular.module('mgcrea.ngStrap',['mgcrea.ngStrap.modal','mgcrea.ngStrap.aside','mgcrea.ngStrap.alert','mgcrea.ngStrap.button','mgcrea.ngStrap.select','mgcrea.ngStrap.datepicker','mgcrea.ngStrap.timepicker','mgcrea.ngStrap.navbar','mgcrea.ngStrap.tooltip','mgcrea.ngStrap.popover','mgcrea.ngStrap.dropdown','mgcrea.ngStrap.typeahead','mgcrea.ngStrap.scrollspy','mgcrea.ngStrap.affix','mgcrea.ngStrap.tab','mgcrea.ngStrap.collapse'])}(window,document); \ No newline at end of file diff --git a/InventoryTraker.Web/Scripts/angular-strap.js b/InventoryTraker.Web/Scripts/angular-strap.js index 5eabc28..ae96d30 100644 --- a/InventoryTraker.Web/Scripts/angular-strap.js +++ b/InventoryTraker.Web/Scripts/angular-strap.js @@ -1,2072 +1,924 @@ /** * angular-strap - * @version v2.3.1 - 2015-07-19 + * @version v2.3.9 - 2016-06-10 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ (function(window, document, undefined) { 'use strict'; - angular.module('mgcrea.ngStrap', [ 'mgcrea.ngStrap.modal', 'mgcrea.ngStrap.aside', 'mgcrea.ngStrap.alert', 'mgcrea.ngStrap.button', 'mgcrea.ngStrap.select', 'mgcrea.ngStrap.datepicker', 'mgcrea.ngStrap.timepicker', 'mgcrea.ngStrap.navbar', 'mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.popover', 'mgcrea.ngStrap.dropdown', 'mgcrea.ngStrap.typeahead', 'mgcrea.ngStrap.scrollspy', 'mgcrea.ngStrap.affix', 'mgcrea.ngStrap.tab', 'mgcrea.ngStrap.collapse' ]); - angular.module('mgcrea.ngStrap.affix', [ 'mgcrea.ngStrap.helpers.dimensions', 'mgcrea.ngStrap.helpers.debounce' ]).provider('$affix', function() { - var defaults = this.defaults = { - offsetTop: 'auto', - inlineStyles: true - }; - this.$get = [ '$window', 'debounce', 'dimensions', function($window, debounce, dimensions) { - var bodyEl = angular.element($window.document.body); - var windowEl = angular.element($window); - function AffixFactory(element, config) { - var $affix = {}; - var options = angular.extend({}, defaults, config); - var targetEl = options.target; - var reset = 'affix affix-top affix-bottom', setWidth = false, initialAffixTop = 0, initialOffsetTop = 0, offsetTop = 0, offsetBottom = 0, affixed = null, unpin = null; - var parent = element.parent(); - if (options.offsetParent) { - if (options.offsetParent.match(/^\d+$/)) { - for (var i = 0; i < options.offsetParent * 1 - 1; i++) { - parent = parent.parent(); - } - } else { - parent = angular.element(options.offsetParent); - } - } - $affix.init = function() { - this.$parseOffsets(); - initialOffsetTop = dimensions.offset(element[0]).top + initialAffixTop; - setWidth = !element[0].style.width; - targetEl.on('scroll', this.checkPosition); - targetEl.on('click', this.checkPositionWithEventLoop); - windowEl.on('resize', this.$debouncedOnResize); - this.checkPosition(); - this.checkPositionWithEventLoop(); - }; - $affix.destroy = function() { - targetEl.off('scroll', this.checkPosition); - targetEl.off('click', this.checkPositionWithEventLoop); - windowEl.off('resize', this.$debouncedOnResize); - }; - $affix.checkPositionWithEventLoop = function() { - setTimeout($affix.checkPosition, 1); - }; - $affix.checkPosition = function() { - var scrollTop = getScrollTop(); - var position = dimensions.offset(element[0]); - var elementHeight = dimensions.height(element[0]); - var affix = getRequiredAffixClass(unpin, position, elementHeight); - if (affixed === affix) return; - affixed = affix; - element.removeClass(reset).addClass('affix' + (affix !== 'middle' ? '-' + affix : '')); - if (affix === 'top') { - unpin = null; - if (setWidth) { - element.css('width', ''); - } - if (options.inlineStyles) { - element.css('position', options.offsetParent ? '' : 'relative'); - element.css('top', ''); - } - } else if (affix === 'bottom') { - if (options.offsetUnpin) { - unpin = -(options.offsetUnpin * 1); - } else { - unpin = position.top - scrollTop; - } - if (setWidth) { - element.css('width', ''); - } - if (options.inlineStyles) { - element.css('position', options.offsetParent ? '' : 'relative'); - element.css('top', options.offsetParent ? '' : bodyEl[0].offsetHeight - offsetBottom - elementHeight - initialOffsetTop + 'px'); - } - } else { - unpin = null; - if (setWidth) { - element.css('width', element[0].offsetWidth + 'px'); - } - if (options.inlineStyles) { - element.css('position', 'fixed'); - element.css('top', initialAffixTop + 'px'); - } - } - }; - $affix.$onResize = function() { - $affix.$parseOffsets(); - $affix.checkPosition(); - }; - $affix.$debouncedOnResize = debounce($affix.$onResize, 50); - $affix.$parseOffsets = function() { - var initialPosition = element.css('position'); - if (options.inlineStyles) { - element.css('position', options.offsetParent ? '' : 'relative'); - } - if (options.offsetTop) { - if (options.offsetTop === 'auto') { - options.offsetTop = '+0'; - } - if (options.offsetTop.match(/^[-+]\d+$/)) { - initialAffixTop = -options.offsetTop * 1; - if (options.offsetParent) { - offsetTop = dimensions.offset(parent[0]).top + options.offsetTop * 1; - } else { - offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + options.offsetTop * 1; - } - } else { - offsetTop = options.offsetTop * 1; - } - } - if (options.offsetBottom) { - if (options.offsetParent && options.offsetBottom.match(/^[-+]\d+$/)) { - offsetBottom = getScrollHeight() - (dimensions.offset(parent[0]).top + dimensions.height(parent[0])) + options.offsetBottom * 1 + 1; - } else { - offsetBottom = options.offsetBottom * 1; - } - } - if (options.inlineStyles) { - element.css('position', initialPosition); - } - }; - function getRequiredAffixClass(unpin, position, elementHeight) { - var scrollTop = getScrollTop(); - var scrollHeight = getScrollHeight(); - if (scrollTop <= offsetTop) { - return 'top'; - } else if (unpin !== null && scrollTop + unpin <= position.top) { - return 'middle'; - } else if (offsetBottom !== null && position.top + elementHeight + initialAffixTop >= scrollHeight - offsetBottom) { - return 'bottom'; - } else { - return 'middle'; - } - } - function getScrollTop() { - return targetEl[0] === $window ? $window.pageYOffset : targetEl[0].scrollTop; - } - function getScrollHeight() { - return targetEl[0] === $window ? $window.document.body.scrollHeight : targetEl[0].scrollHeight; - } - $affix.init(); - return $affix; - } - return AffixFactory; - } ]; - }).directive('bsAffix', [ '$affix', '$window', function($affix, $window) { - return { - restrict: 'EAC', - require: '^?bsAffixTarget', - link: function postLink(scope, element, attr, affixTarget) { - var options = { - scope: scope, - target: affixTarget ? affixTarget.$element : angular.element($window) - }; - angular.forEach([ 'offsetTop', 'offsetBottom', 'offsetParent', 'offsetUnpin', 'inlineStyles' ], function(key) { - if (angular.isDefined(attr[key])) { - var option = attr[key]; - if (/true/i.test(option)) option = true; - if (/false/i.test(option)) option = false; - options[key] = option; - } - }); - var affix = $affix(element, options); - scope.$on('$destroy', function() { - affix && affix.destroy(); - options = null; - affix = null; - }); - } - }; - } ]).directive('bsAffixTarget', function() { - return { - controller: [ '$element', function($element) { - this.$element = $element; - } ] - }; - }); - angular.module('mgcrea.ngStrap.alert', [ 'mgcrea.ngStrap.modal' ]).provider('$alert', function() { + bsCompilerService.$inject = [ '$q', '$http', '$injector', '$compile', '$controller', '$templateCache' ]; + angular.module('mgcrea.ngStrap.typeahead', [ 'mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions' ]).provider('$typeahead', function() { var defaults = this.defaults = { animation: 'am-fade', - prefixClass: 'alert', - prefixEvent: 'alert', - placement: null, - templateUrl: 'alert/alert.tpl.html', + prefixClass: 'typeahead', + prefixEvent: '$typeahead', + placement: 'bottom-left', + templateUrl: 'typeahead/typeahead.tpl.html', + trigger: 'focus', container: false, - element: null, - backdrop: false, - keyboard: true, - show: true, - duration: false, - type: false, - dismissable: true - }; - this.$get = [ '$modal', '$timeout', function($modal, $timeout) { - function AlertFactory(config) { - var $alert = {}; - var options = angular.extend({}, defaults, config); - $alert = $modal(options); - $alert.$scope.dismissable = !!options.dismissable; - if (options.type) { - $alert.$scope.type = options.type; - } - var show = $alert.show; - if (options.duration) { - $alert.show = function() { - show(); - $timeout(function() { - $alert.hide(); - }, options.duration * 1e3); - }; - } - return $alert; - } - return AlertFactory; - } ]; - }).directive('bsAlert', [ '$window', '$sce', '$alert', function($window, $sce, $alert) { - var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout; - return { - restrict: 'EAC', - scope: true, - link: function postLink(scope, element, attr, transclusion) { - var options = { - scope: scope, - element: element, - show: false - }; - angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable' ], function(key) { - if (angular.isDefined(attr[key])) options[key] = attr[key]; - }); - var falseValueRegExp = /^(false|0|)$/i; - angular.forEach([ 'keyboard', 'html', 'container', 'dismissable' ], function(key) { - if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; - }); - if (!scope.hasOwnProperty('title')) { - scope.title = ''; - } - angular.forEach([ 'title', 'content', 'type' ], function(key) { - attr[key] && attr.$observe(key, function(newValue, oldValue) { - scope[key] = $sce.trustAsHtml(newValue); - }); - }); - attr.bsAlert && scope.$watch(attr.bsAlert, function(newValue, oldValue) { - if (angular.isObject(newValue)) { - angular.extend(scope, newValue); - } else { - scope.content = newValue; - } - }, true); - var alert = $alert(options); - element.on(attr.trigger || 'click', alert.toggle); - scope.$on('$destroy', function() { - if (alert) alert.destroy(); - options = null; - alert = null; - }); - } - }; - } ]); - angular.module('mgcrea.ngStrap.aside', [ 'mgcrea.ngStrap.modal' ]).provider('$aside', function() { - var defaults = this.defaults = { - animation: 'am-fade-and-slide-right', - prefixClass: 'aside', - prefixEvent: 'aside', - placement: 'right', - templateUrl: 'aside/aside.tpl.html', - contentTemplate: false, - container: false, - element: null, - backdrop: true, keyboard: true, html: false, - show: true + delay: 0, + minLength: 1, + filter: 'bsAsyncFilter', + limit: 6, + autoSelect: false, + comparator: '', + trimValue: true }; - this.$get = [ '$modal', function($modal) { - function AsideFactory(config) { - var $aside = {}; + this.$get = [ '$window', '$rootScope', '$tooltip', '$$rAF', '$timeout', function($window, $rootScope, $tooltip, $$rAF, $timeout) { + function TypeaheadFactory(element, controller, config) { + var $typeahead = {}; var options = angular.extend({}, defaults, config); - $aside = $modal(options); - return $aside; + $typeahead = $tooltip(element, options); + var parentScope = config.scope; + var scope = $typeahead.$scope; + scope.$resetMatches = function() { + scope.$matches = []; + scope.$activeIndex = options.autoSelect ? 0 : -1; + }; + scope.$resetMatches(); + scope.$activate = function(index) { + scope.$$postDigest(function() { + $typeahead.activate(index); + }); + }; + scope.$select = function(index, evt) { + scope.$$postDigest(function() { + $typeahead.select(index); + }); + }; + scope.$isVisible = function() { + return $typeahead.$isVisible(); + }; + $typeahead.update = function(matches) { + scope.$matches = matches; + if (scope.$activeIndex >= matches.length) { + scope.$activeIndex = options.autoSelect ? 0 : -1; + } + safeDigest(scope); + $$rAF($typeahead.$applyPlacement); + }; + $typeahead.activate = function(index) { + scope.$activeIndex = index; + }; + $typeahead.select = function(index) { + if (index === -1) return; + var value = scope.$matches[index].value; + controller.$setViewValue(value); + controller.$render(); + scope.$resetMatches(); + if (parentScope) parentScope.$digest(); + scope.$emit(options.prefixEvent + '.select', value, index, $typeahead); + if (angular.isDefined(options.onSelect) && angular.isFunction(options.onSelect)) { + options.onSelect(value, index, $typeahead); + } + }; + $typeahead.$isVisible = function() { + if (!options.minLength || !controller) { + return !!scope.$matches.length; + } + return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength; + }; + $typeahead.$getIndex = function(value) { + var index; + for (index = scope.$matches.length; index--; ) { + if (angular.equals(scope.$matches[index].value, value)) break; + } + return index; + }; + $typeahead.$onMouseDown = function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + }; + $typeahead.$onKeyDown = function(evt) { + if (!/(38|40|13)/.test(evt.keyCode)) return; + if ($typeahead.$isVisible() && !(evt.keyCode === 13 && scope.$activeIndex === -1)) { + evt.preventDefault(); + evt.stopPropagation(); + } + if (evt.keyCode === 13 && scope.$matches.length) { + $typeahead.select(scope.$activeIndex); + } else if (evt.keyCode === 38 && scope.$activeIndex > 0) { + scope.$activeIndex--; + } else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) { + scope.$activeIndex++; + } else if (angular.isUndefined(scope.$activeIndex)) { + scope.$activeIndex = 0; + } + scope.$digest(); + }; + var show = $typeahead.show; + $typeahead.show = function() { + show(); + $timeout(function() { + if ($typeahead.$element) { + $typeahead.$element.on('mousedown', $typeahead.$onMouseDown); + if (options.keyboard) { + if (element) element.on('keydown', $typeahead.$onKeyDown); + } + } + }, 0, false); + }; + var hide = $typeahead.hide; + $typeahead.hide = function() { + if ($typeahead.$element) $typeahead.$element.off('mousedown', $typeahead.$onMouseDown); + if (options.keyboard) { + if (element) element.off('keydown', $typeahead.$onKeyDown); + } + if (!options.autoSelect) { + $typeahead.activate(-1); + } + hide(); + }; + return $typeahead; } - return AsideFactory; + function safeDigest(scope) { + scope.$$phase || scope.$root && scope.$root.$$phase || scope.$digest(); + } + TypeaheadFactory.defaults = defaults; + return TypeaheadFactory; } ]; - }).directive('bsAside', [ '$window', '$sce', '$aside', function($window, $sce, $aside) { - var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout; + }).filter('bsAsyncFilter', [ '$filter', function($filter) { + return function(array, expression, comparator) { + if (array && angular.isFunction(array.then)) { + return array.then(function(results) { + return $filter('filter')(results, expression, comparator); + }); + } + return $filter('filter')(array, expression, comparator); + }; + } ]).directive('bsTypeahead', [ '$window', '$parse', '$q', '$typeahead', '$parseOptions', function($window, $parse, $q, $typeahead, $parseOptions) { + var defaults = $typeahead.defaults; return { restrict: 'EAC', - scope: true, - link: function postLink(scope, element, attr, transclusion) { + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + element.off('change'); var options = { - scope: scope, - element: element, - show: false + scope: scope }; - angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation' ], function(key) { + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass' ], function(key) { if (angular.isDefined(attr[key])) options[key] = attr[key]; }); var falseValueRegExp = /^(false|0|)$/i; - angular.forEach([ 'backdrop', 'keyboard', 'html', 'container' ], function(key) { + angular.forEach([ 'html', 'container', 'trimValue', 'filter' ], function(key) { if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; }); - angular.forEach([ 'title', 'content' ], function(key) { - attr[key] && attr.$observe(key, function(newValue, oldValue) { - scope[key] = $sce.trustAsHtml(newValue); - }); - }); - attr.bsAside && scope.$watch(attr.bsAside, function(newValue, oldValue) { - if (angular.isObject(newValue)) { - angular.extend(scope, newValue); - } else { - scope.content = newValue; + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide', 'onSelect' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); } - }, true); - var aside = $aside(options); - element.on(attr.trigger || 'click', aside.toggle); - scope.$on('$destroy', function() { - if (aside) aside.destroy(); - options = null; - aside = null; }); - } - }; - } ]); - angular.module('mgcrea.ngStrap.button', []).provider('$button', function() { - var defaults = this.defaults = { - activeClass: 'active', - toggleEvent: 'click' - }; - this.$get = function() { - return { - defaults: defaults - }; - }; - }).directive('bsCheckboxGroup', function() { - return { - restrict: 'A', - require: 'ngModel', - compile: function postLink(element, attr) { - element.attr('data-toggle', 'buttons'); - element.removeAttr('ng-model'); - var children = element[0].querySelectorAll('input[type="checkbox"]'); - angular.forEach(children, function(child) { - var childEl = angular.element(child); - childEl.attr('bs-checkbox', ''); - childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value')); - }); - } - }; - }).directive('bsCheckbox', [ '$button', '$$rAF', function($button, $$rAF) { - var defaults = $button.defaults; - var constantValueRegExp = /^(true|false|\d+)$/; - return { - restrict: 'A', - require: 'ngModel', - link: function postLink(scope, element, attr, controller) { - var options = defaults; - var isInput = element[0].nodeName === 'INPUT'; - var activeElement = isInput ? element.parent() : element; - var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true; - if (constantValueRegExp.test(attr.trueValue)) { - trueValue = scope.$eval(attr.trueValue); + if (!element.attr('autocomplete')) element.attr('autocomplete', 'off'); + var filter = angular.isDefined(options.filter) ? options.filter : defaults.filter; + var limit = options.limit || defaults.limit; + var comparator = options.comparator || defaults.comparator; + var bsOptions = attr.bsOptions; + if (filter) { + bsOptions += ' | ' + filter + ':$viewValue'; + if (comparator) bsOptions += ':' + comparator; } - var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false; - if (constantValueRegExp.test(attr.falseValue)) { - falseValue = scope.$eval(attr.falseValue); - } - var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean'; - if (hasExoticValues) { - controller.$parsers.push(function(viewValue) { - return viewValue ? trueValue : falseValue; - }); - controller.$formatters.push(function(modelValue) { - return angular.equals(modelValue, trueValue); - }); - scope.$watch(attr.ngModel, function(newValue, oldValue) { - controller.$render(); - }); - } - controller.$render = function() { - var isActive = angular.equals(controller.$modelValue, trueValue); - $$rAF(function() { - if (isInput) element[0].checked = isActive; - activeElement.toggleClass(options.activeClass, isActive); - }); - }; - element.bind(options.toggleEvent, function() { - scope.$apply(function() { - if (!isInput) { - controller.$setViewValue(!activeElement.hasClass('active')); - } - if (!hasExoticValues) { + if (limit) bsOptions += ' | limitTo:' + limit; + var parsedOptions = $parseOptions(bsOptions); + var typeahead = $typeahead(element, controller, options); + if (options.watchOptions) { + var watchedOptions = parsedOptions.$match[7].replace(/\|.+/, '').replace(/\(.*\)/g, '').trim(); + scope.$watchCollection(watchedOptions, function(newValue, oldValue) { + parsedOptions.valuesFn(scope, controller).then(function(values) { + typeahead.update(values); controller.$render(); + }); + }); + } + scope.$watch(attr.ngModel, function(newValue, oldValue) { + scope.$modelValue = newValue; + parsedOptions.valuesFn(scope, controller).then(function(values) { + if (options.selectMode && !values.length && newValue.length > 0) { + controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1)); + return; } - }); - }); - } - }; - } ]).directive('bsRadioGroup', function() { - return { - restrict: 'A', - require: 'ngModel', - compile: function postLink(element, attr) { - element.attr('data-toggle', 'buttons'); - element.removeAttr('ng-model'); - var children = element[0].querySelectorAll('input[type="radio"]'); - angular.forEach(children, function(child) { - angular.element(child).attr('bs-radio', ''); - angular.element(child).attr('ng-model', attr.ngModel); - }); - } - }; - }).directive('bsRadio', [ '$button', '$$rAF', function($button, $$rAF) { - var defaults = $button.defaults; - var constantValueRegExp = /^(true|false|\d+)$/; - return { - restrict: 'A', - require: 'ngModel', - link: function postLink(scope, element, attr, controller) { - var options = defaults; - var isInput = element[0].nodeName === 'INPUT'; - var activeElement = isInput ? element.parent() : element; - var value; - attr.$observe('value', function(v) { - value = constantValueRegExp.test(v) ? scope.$eval(v) : v; - controller.$render(); - }); - controller.$render = function() { - var isActive = angular.equals(controller.$modelValue, value); - $$rAF(function() { - if (isInput) element[0].checked = isActive; - activeElement.toggleClass(options.activeClass, isActive); - }); - }; - element.bind(options.toggleEvent, function() { - scope.$apply(function() { - controller.$setViewValue(value); + if (values.length > limit) values = values.slice(0, limit); + typeahead.update(values); controller.$render(); }); }); + controller.$formatters.push(function(modelValue) { + var displayValue = parsedOptions.displayValue(modelValue); + if (displayValue) { + return displayValue; + } + if (angular.isDefined(modelValue) && typeof modelValue !== 'object') { + return modelValue; + } + return ''; + }); + controller.$render = function() { + if (controller.$isEmpty(controller.$viewValue)) { + return element.val(''); + } + var index = typeahead.$getIndex(controller.$modelValue); + var selected = index !== -1 ? typeahead.$scope.$matches[index].label : controller.$viewValue; + selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected; + var value = selected ? selected.toString().replace(/<(?:.|\n)*?>/gm, '') : ''; + var ss = element[0].selectionStart; + var sd = element[0].selectionEnd; + element.val(options.trimValue === false ? value : value.trim()); + element[0].setSelectionRange(ss, sd); + }; + scope.$on('$destroy', function() { + if (typeahead) typeahead.destroy(); + options = null; + typeahead = null; + }); } }; } ]); - angular.module('mgcrea.ngStrap.collapse', []).provider('$collapse', function() { + angular.module('mgcrea.ngStrap.tab', []).provider('$tab', function() { var defaults = this.defaults = { - animation: 'am-collapse', - disallowToggle: false, - activeClass: 'in', - startCollapsed: false, - allowMultiple: false + animation: 'am-fade', + template: 'tab/tab.tpl.html', + navClass: 'nav-tabs', + activeClass: 'active' }; var controller = this.controller = function($scope, $element, $attrs) { var self = this; self.$options = angular.copy(defaults); - angular.forEach([ 'animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple' ], function(key) { + angular.forEach([ 'animation', 'navClass', 'activeClass' ], function(key) { if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key]; }); - var falseValueRegExp = /^(false|0|)$/i; - angular.forEach([ 'disallowToggle', 'startCollapsed', 'allowMultiple' ], function(key) { - if (angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) { - self.$options[key] = false; + $scope.$navClass = self.$options.navClass; + $scope.$activeClass = self.$options.activeClass; + self.$panes = $scope.$panes = []; + self.$activePaneChangeListeners = self.$viewChangeListeners = []; + self.$push = function(pane) { + if (angular.isUndefined(self.$panes.$active)) { + $scope.$setActive(pane.name || 0); } - }); - self.$toggles = []; - self.$targets = []; - self.$viewChangeListeners = []; - self.$registerToggle = function(element) { - self.$toggles.push(element); + self.$panes.push(pane); }; - self.$registerTarget = function(element) { - self.$targets.push(element); - }; - self.$unregisterToggle = function(element) { - var index = self.$toggles.indexOf(element); - self.$toggles.splice(index, 1); - }; - self.$unregisterTarget = function(element) { - var index = self.$targets.indexOf(element); - self.$targets.splice(index, 1); - if (self.$options.allowMultiple) { - deactivateItem(element); - } - fixActiveItemIndexes(index); - self.$viewChangeListeners.forEach(function(fn) { - fn(); - }); - }; - self.$targets.$active = !self.$options.startCollapsed ? [ 0 ] : []; - self.$setActive = $scope.$setActive = function(value) { - if (angular.isArray(value)) { - self.$targets.$active = value; - } else if (!self.$options.disallowToggle) { - isActive(value) ? deactivateItem(value) : activateItem(value); + self.$remove = function(pane) { + var index = self.$panes.indexOf(pane); + var active = self.$panes.$active; + var activeIndex; + if (angular.isString(active)) { + activeIndex = self.$panes.map(function(pane) { + return pane.name; + }).indexOf(active); } else { - activateItem(value); + activeIndex = self.$panes.$active; } - self.$viewChangeListeners.forEach(function(fn) { + self.$panes.splice(index, 1); + if (index < activeIndex) { + activeIndex--; + } else if (index === activeIndex && activeIndex === self.$panes.length) { + activeIndex--; + } + if (activeIndex >= 0 && activeIndex < self.$panes.length) { + self.$setActive(self.$panes[activeIndex].name || activeIndex); + } else { + self.$setActive(); + } + }; + self.$setActive = $scope.$setActive = function(value) { + self.$panes.$active = value; + self.$activePaneChangeListeners.forEach(function(fn) { fn(); }); }; - self.$activeIndexes = function() { - return self.$options.allowMultiple ? self.$targets.$active : self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1; + self.$isActive = $scope.$isActive = function($pane, $index) { + return self.$panes.$active === $pane.name || self.$panes.$active === $index; }; - function fixActiveItemIndexes(index) { - var activeIndexes = self.$targets.$active; - for (var i = 0; i < activeIndexes.length; i++) { - if (index < activeIndexes[i]) { - activeIndexes[i] = activeIndexes[i] - 1; - } - if (activeIndexes[i] === self.$targets.length) { - activeIndexes[i] = self.$targets.length - 1; - } - } - } - function isActive(value) { - var activeItems = self.$targets.$active; - return activeItems.indexOf(value) === -1 ? false : true; - } - function deactivateItem(value) { - var index = self.$targets.$active.indexOf(value); - if (index !== -1) { - self.$targets.$active.splice(index, 1); - } - } - function activateItem(value) { - if (!self.$options.allowMultiple) { - self.$targets.$active.splice(0, 1); - } - if (self.$targets.$active.indexOf(value) === -1) { - self.$targets.$active.push(value); - } - } }; this.$get = function() { - var $collapse = {}; - $collapse.defaults = defaults; - $collapse.controller = controller; - return $collapse; + var $tab = {}; + $tab.defaults = defaults; + $tab.controller = controller; + return $tab; }; - }).directive('bsCollapse', [ '$window', '$animate', '$collapse', function($window, $animate, $collapse) { - var defaults = $collapse.defaults; + }).directive('bsTabs', [ '$window', '$animate', '$tab', '$parse', function($window, $animate, $tab, $parse) { + var defaults = $tab.defaults; return { - require: [ '?ngModel', 'bsCollapse' ], - controller: [ '$scope', '$element', '$attrs', $collapse.controller ], + require: [ '?ngModel', 'bsTabs' ], + transclude: true, + scope: true, + controller: [ '$scope', '$element', '$attrs', $tab.controller ], + templateUrl: function(element, attr) { + return attr.template || defaults.template; + }, link: function postLink(scope, element, attrs, controllers) { var ngModelCtrl = controllers[0]; - var bsCollapseCtrl = controllers[1]; + var bsTabsCtrl = controllers[1]; if (ngModelCtrl) { - bsCollapseCtrl.$viewChangeListeners.push(function() { - ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes()); + bsTabsCtrl.$activePaneChangeListeners.push(function() { + ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active); }); ngModelCtrl.$formatters.push(function(modelValue) { - if (angular.isArray(modelValue)) { - bsCollapseCtrl.$setActive(modelValue); - } else { - var activeIndexes = bsCollapseCtrl.$activeIndexes(); - if (angular.isArray(activeIndexes)) { - if (activeIndexes.indexOf(modelValue * 1) === -1) { - bsCollapseCtrl.$setActive(modelValue * 1); - } - } else if (activeIndexes !== modelValue * 1) { - bsCollapseCtrl.$setActive(modelValue * 1); - } - } + bsTabsCtrl.$setActive(modelValue); return modelValue; }); } - } - }; - } ]).directive('bsCollapseToggle', function() { - return { - require: [ '^?ngModel', '^bsCollapse' ], - link: function postLink(scope, element, attrs, controllers) { - var ngModelCtrl = controllers[0]; - var bsCollapseCtrl = controllers[1]; - element.attr('data-toggle', 'collapse'); - bsCollapseCtrl.$registerToggle(element); - scope.$on('$destroy', function() { - bsCollapseCtrl.$unregisterToggle(element); - }); - element.on('click', function() { - var index = attrs.bsCollapseToggle && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element); - bsCollapseCtrl.$setActive(index * 1); - scope.$apply(); - }); - } - }; - }).directive('bsCollapseTarget', [ '$animate', function($animate) { - return { - require: [ '^?ngModel', '^bsCollapse' ], - link: function postLink(scope, element, attrs, controllers) { - var ngModelCtrl = controllers[0]; - var bsCollapseCtrl = controllers[1]; - element.addClass('collapse'); - if (bsCollapseCtrl.$options.animation) { - element.addClass(bsCollapseCtrl.$options.animation); + if (attrs.bsActivePane) { + var parsedBsActivePane = $parse(attrs.bsActivePane); + bsTabsCtrl.$activePaneChangeListeners.push(function() { + parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active); + }); + scope.$watch(attrs.bsActivePane, function(newValue, oldValue) { + bsTabsCtrl.$setActive(newValue); + }, true); } - bsCollapseCtrl.$registerTarget(element); + } + }; + } ]).directive('bsPane', [ '$window', '$animate', '$sce', function($window, $animate, $sce) { + return { + require: [ '^?ngModel', '^bsTabs' ], + scope: true, + link: function postLink(scope, element, attrs, controllers) { + var bsTabsCtrl = controllers[1]; + element.addClass('tab-pane'); + attrs.$observe('title', function(newValue, oldValue) { + scope.title = $sce.trustAsHtml(newValue); + }); + scope.name = attrs.name; + if (bsTabsCtrl.$options.animation) { + element.addClass(bsTabsCtrl.$options.animation); + } + attrs.$observe('disabled', function(newValue, oldValue) { + scope.disabled = scope.$eval(newValue); + }); + bsTabsCtrl.$push(scope); scope.$on('$destroy', function() { - bsCollapseCtrl.$unregisterTarget(element); + bsTabsCtrl.$remove(scope); }); function render() { - var index = bsCollapseCtrl.$targets.indexOf(element); - var active = bsCollapseCtrl.$activeIndexes(); - var action = 'removeClass'; - if (angular.isArray(active)) { - if (active.indexOf(index) !== -1) { - action = 'addClass'; - } - } else if (index === active) { - action = 'addClass'; - } - $animate[action](element, bsCollapseCtrl.$options.activeClass); + var index = bsTabsCtrl.$panes.indexOf(scope); + $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass); } - bsCollapseCtrl.$viewChangeListeners.push(function() { + bsTabsCtrl.$activePaneChangeListeners.push(function() { render(); }); render(); } }; } ]); - angular.module('mgcrea.ngStrap.datepicker', [ 'mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip' ]).provider('$datepicker', function() { + angular.module('mgcrea.ngStrap.tooltip', [ 'mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$tooltip', function() { var defaults = this.defaults = { animation: 'am-fade', - prefixClass: 'datepicker', - placement: 'bottom-left', - templateUrl: 'datepicker/datepicker.tpl.html', - trigger: 'focus', + customClass: '', + prefixClass: 'tooltip', + prefixEvent: 'tooltip', container: false, - keyboard: true, - html: false, - delay: 0, - useNative: false, - dateType: 'date', - dateFormat: 'shortDate', - timezone: null, - modelDateFormat: null, - dayFormat: 'dd', - monthFormat: 'MMM', - yearFormat: 'yyyy', - monthTitleFormat: 'MMMM yyyy', - yearTitleFormat: 'yyyy', - strictFormat: false, - autoclose: false, - minDate: -Infinity, - maxDate: +Infinity, - startView: 0, - minView: 0, - startWeek: 0, - daysOfWeekDisabled: '', - iconLeft: 'glyphicon glyphicon-chevron-left', - iconRight: 'glyphicon glyphicon-chevron-right' - }; - this.$get = [ '$window', '$document', '$rootScope', '$sce', '$dateFormatter', 'datepickerViews', '$tooltip', '$timeout', function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) { - var bodyEl = angular.element($window.document.body); - var isNative = /(ip(a|o)d|iphone|android)/gi.test($window.navigator.userAgent); - var isTouch = 'createTouch' in $window.document && isNative; - if (!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale(); - function DatepickerFactory(element, controller, config) { - var $datepicker = $tooltip(element, angular.extend({}, defaults, config)); - var parentScope = config.scope; - var options = $datepicker.$options; - var scope = $datepicker.$scope; - if (options.startView) options.startView -= options.minView; - var pickerViews = datepickerViews($datepicker); - $datepicker.$views = pickerViews.views; - var viewDate = pickerViews.viewDate; - scope.$mode = options.startView; - scope.$iconLeft = options.iconLeft; - scope.$iconRight = options.iconRight; - var $picker = $datepicker.$views[scope.$mode]; - scope.$select = function(date) { - $datepicker.select(date); - }; - scope.$selectPane = function(value) { - $datepicker.$selectPane(value); - }; - scope.$toggleMode = function() { - $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length); - }; - $datepicker.update = function(date) { - if (angular.isDate(date) && !isNaN(date.getTime())) { - $datepicker.$date = date; - $picker.update.call($picker, date); - } - $datepicker.$build(true); - }; - $datepicker.updateDisabledDates = function(dateRanges) { - options.disabledDateRanges = dateRanges; - for (var i = 0, l = scope.rows.length; i < l; i++) { - angular.forEach(scope.rows[i], $datepicker.$setDisabledEl); - } - }; - $datepicker.select = function(date, keep) { - if (!angular.isDate(controller.$dateValue)) controller.$dateValue = new Date(date); - if (!scope.$mode || keep) { - controller.$setViewValue(angular.copy(date)); - controller.$render(); - if (options.autoclose && !keep) { - $timeout(function() { - $datepicker.hide(true); - }); - } - } else { - angular.extend(viewDate, { - year: date.getFullYear(), - month: date.getMonth(), - date: date.getDate() - }); - $datepicker.setMode(scope.$mode - 1); - $datepicker.$build(); - } - }; - $datepicker.setMode = function(mode) { - scope.$mode = mode; - $picker = $datepicker.$views[scope.$mode]; - $datepicker.$build(); - }; - $datepicker.$build = function(pristine) { - if (pristine === true && $picker.built) return; - if (pristine === false && !$picker.built) return; - $picker.build.call($picker); - }; - $datepicker.$updateSelected = function() { - for (var i = 0, l = scope.rows.length; i < l; i++) { - angular.forEach(scope.rows[i], updateSelected); - } - }; - $datepicker.$isSelected = function(date) { - return $picker.isSelected(date); - }; - $datepicker.$setDisabledEl = function(el) { - el.disabled = $picker.isDisabled(el.date); - }; - $datepicker.$selectPane = function(value) { - var steps = $picker.steps; - var targetDate = new Date(Date.UTC(viewDate.year + (steps.year || 0) * value, viewDate.month + (steps.month || 0) * value, 1)); - angular.extend(viewDate, { - year: targetDate.getUTCFullYear(), - month: targetDate.getUTCMonth(), - date: targetDate.getUTCDate() - }); - $datepicker.$build(); - }; - $datepicker.$onMouseDown = function(evt) { - evt.preventDefault(); - evt.stopPropagation(); - if (isTouch) { - var targetEl = angular.element(evt.target); - if (targetEl[0].nodeName.toLowerCase() !== 'button') { - targetEl = targetEl.parent(); - } - targetEl.triggerHandler('click'); - } - }; - $datepicker.$onKeyDown = function(evt) { - if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return; - evt.preventDefault(); - evt.stopPropagation(); - if (evt.keyCode === 13) { - if (!scope.$mode) { - return $datepicker.hide(true); - } else { - return scope.$apply(function() { - $datepicker.setMode(scope.$mode - 1); - }); - } - } - $picker.onKeyDown(evt); - parentScope.$digest(); - }; - function updateSelected(el) { - el.selected = $datepicker.$isSelected(el.date); - } - function focusElement() { - element[0].focus(); - } - var _init = $datepicker.init; - $datepicker.init = function() { - if (isNative && options.useNative) { - element.prop('type', 'date'); - element.css('-webkit-appearance', 'textfield'); - return; - } else if (isTouch) { - element.prop('type', 'text'); - element.attr('readonly', 'true'); - element.on('click', focusElement); - } - _init(); - }; - var _destroy = $datepicker.destroy; - $datepicker.destroy = function() { - if (isNative && options.useNative) { - element.off('click', focusElement); - } - _destroy(); - }; - var _show = $datepicker.show; - $datepicker.show = function() { - if (!isTouch && element.attr('readonly') || element.attr('disabled')) return; - _show(); - $timeout(function() { - if (!$datepicker.$isShown) return; - $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown); - if (options.keyboard) { - element.on('keydown', $datepicker.$onKeyDown); - } - }, 0, false); - }; - var _hide = $datepicker.hide; - $datepicker.hide = function(blur) { - if (!$datepicker.$isShown) return; - $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown); - if (options.keyboard) { - element.off('keydown', $datepicker.$onKeyDown); - } - _hide(blur); - }; - return $datepicker; - } - DatepickerFactory.defaults = defaults; - return DatepickerFactory; - } ]; - }).directive('bsDatepicker', [ '$window', '$parse', '$q', '$dateFormatter', '$dateParser', '$datepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) { - var defaults = $datepicker.defaults; - var isNative = /(ip(a|o)d|iphone|android)/gi.test($window.navigator.userAgent); - return { - restrict: 'EAC', - require: 'ngModel', - link: function postLink(scope, element, attr, controller) { - var options = { - scope: scope - }; - angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent' ], function(key) { - if (angular.isDefined(attr[key])) options[key] = attr[key]; - }); - var falseValueRegExp = /^(false|0|)$/i; - angular.forEach([ 'html', 'container', 'autoclose', 'useNative' ], function(key) { - if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; - }); - attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) { - if (!datepicker || !angular.isDefined(newValue)) return; - if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i); - newValue === true ? datepicker.show() : datepicker.hide(); - }); - var datepicker = $datepicker(element, controller, options); - options = datepicker.$options; - if (isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd'; - var lang = options.lang; - var formatDate = function(date, format) { - return $dateFormatter.formatDate(date, format, lang); - }; - var dateParser = $dateParser({ - format: options.dateFormat, - lang: lang, - strict: options.strictFormat - }); - angular.forEach([ 'minDate', 'maxDate' ], function(key) { - angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) { - datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue); - !isNaN(datepicker.$options[key]) && datepicker.$build(false); - validateAgainstMinMaxDate(controller.$dateValue); - }); - }); - scope.$watch(attr.ngModel, function(newValue, oldValue) { - datepicker.update(controller.$dateValue); - }, true); - function normalizeDateRanges(ranges) { - if (!ranges || !ranges.length) return null; - return ranges; - } - if (angular.isDefined(attr.disabledDates)) { - scope.$watch(attr.disabledDates, function(disabledRanges, previousValue) { - disabledRanges = normalizeDateRanges(disabledRanges); - previousValue = normalizeDateRanges(previousValue); - if (disabledRanges) { - datepicker.updateDisabledDates(disabledRanges); - } - }); - } - function validateAgainstMinMaxDate(parsedDate) { - if (!angular.isDate(parsedDate)) return; - var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate; - var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate; - var isValid = isMinValid && isMaxValid; - controller.$setValidity('date', isValid); - controller.$setValidity('min', isMinValid); - controller.$setValidity('max', isMaxValid); - if (isValid) controller.$dateValue = parsedDate; - } - controller.$parsers.unshift(function(viewValue) { - var date; - if (!viewValue) { - controller.$setValidity('date', true); - return null; - } - var parsedDate = dateParser.parse(viewValue, controller.$dateValue); - if (!parsedDate || isNaN(parsedDate.getTime())) { - controller.$setValidity('date', false); - return; - } else { - validateAgainstMinMaxDate(parsedDate); - } - if (options.dateType === 'string') { - date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true); - return formatDate(date, options.modelDateFormat || options.dateFormat); - } - date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true); - if (options.dateType === 'number') { - return date.getTime(); - } else if (options.dateType === 'unix') { - return date.getTime() / 1e3; - } else if (options.dateType === 'iso') { - return date.toISOString(); - } else { - return new Date(date); - } - }); - controller.$formatters.push(function(modelValue) { - var date; - if (angular.isUndefined(modelValue) || modelValue === null) { - date = NaN; - } else if (angular.isDate(modelValue)) { - date = modelValue; - } else if (options.dateType === 'string') { - date = dateParser.parse(modelValue, null, options.modelDateFormat); - } else if (options.dateType === 'unix') { - date = new Date(modelValue * 1e3); - } else { - date = new Date(modelValue); - } - controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone); - return getDateFormattedString(); - }); - controller.$render = function() { - element.val(getDateFormattedString()); - }; - function getDateFormattedString() { - return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat); - } - scope.$on('$destroy', function() { - if (datepicker) datepicker.destroy(); - options = null; - datepicker = null; - }); - } - }; - } ]).provider('datepickerViews', function() { - var defaults = this.defaults = { - dayFormat: 'dd', - daySplit: 7 - }; - function split(arr, size) { - var arrays = []; - while (arr.length > 0) { - arrays.push(arr.splice(0, size)); - } - return arrays; - } - function mod(n, m) { - return (n % m + m) % m; - } - this.$get = [ '$dateFormatter', '$dateParser', '$sce', function($dateFormatter, $dateParser, $sce) { - return function(picker) { - var scope = picker.$scope; - var options = picker.$options; - var lang = options.lang; - var formatDate = function(date, format) { - return $dateFormatter.formatDate(date, format, lang); - }; - var dateParser = $dateParser({ - format: options.dateFormat, - lang: lang, - strict: options.strictFormat - }); - var weekDaysMin = $dateFormatter.weekdaysShort(lang); - var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek)); - var weekDaysLabelsHtml = $sce.trustAsHtml('' + weekDaysLabels.join('') + ''); - var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date()); - var viewDate = { - year: startDate.getFullYear(), - month: startDate.getMonth(), - date: startDate.getDate() - }; - var views = [ { - format: options.dayFormat, - split: 7, - steps: { - month: 1 - }, - update: function(date, force) { - if (!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) { - angular.extend(viewDate, { - year: picker.$date.getFullYear(), - month: picker.$date.getMonth(), - date: picker.$date.getDate() - }); - picker.$build(); - } else if (date.getDate() !== viewDate.date || date.getDate() === 1) { - viewDate.date = picker.$date.getDate(); - picker.$updateSelected(); - } - }, - build: function() { - var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1), firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset(); - var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5), firstDateOffset = firstDate.getTimezoneOffset(); - var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString(); - if (firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 6e4); - var days = [], day; - for (var i = 0; i < 42; i++) { - day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i)); - days.push({ - date: day, - isToday: day.toDateString() === today, - label: formatDate(day, this.format), - selected: picker.$date && this.isSelected(day), - muted: day.getMonth() !== viewDate.month, - disabled: this.isDisabled(day) - }); - } - scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat); - scope.showLabels = true; - scope.labels = weekDaysLabelsHtml; - scope.rows = split(days, this.split); - this.built = true; - }, - isSelected: function(date) { - return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate(); - }, - isDisabled: function(date) { - var time = date.getTime(); - if (time < options.minDate || time > options.maxDate) return true; - if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true; - if (options.disabledDateRanges) { - for (var i = 0; i < options.disabledDateRanges.length; i++) { - if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) { - return true; - } - } - } - return false; - }, - onKeyDown: function(evt) { - if (!picker.$date) { - return; - } - var actualTime = picker.$date.getTime(); - var newDate; - if (evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5); else if (evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5); else if (evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5); else if (evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5); - if (!this.isDisabled(newDate)) picker.select(newDate, true); - } - }, { - name: 'month', - format: options.monthFormat, - split: 4, - steps: { - year: 1 - }, - update: function(date, force) { - if (!this.built || date.getFullYear() !== viewDate.year) { - angular.extend(viewDate, { - year: picker.$date.getFullYear(), - month: picker.$date.getMonth(), - date: picker.$date.getDate() - }); - picker.$build(); - } else if (date.getMonth() !== viewDate.month) { - angular.extend(viewDate, { - month: picker.$date.getMonth(), - date: picker.$date.getDate() - }); - picker.$updateSelected(); - } - }, - build: function() { - var firstMonth = new Date(viewDate.year, 0, 1); - var months = [], month; - for (var i = 0; i < 12; i++) { - month = new Date(viewDate.year, i, 1); - months.push({ - date: month, - label: formatDate(month, this.format), - selected: picker.$isSelected(month), - disabled: this.isDisabled(month) - }); - } - scope.title = formatDate(month, options.yearTitleFormat); - scope.showLabels = false; - scope.rows = split(months, this.split); - this.built = true; - }, - isSelected: function(date) { - return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth(); - }, - isDisabled: function(date) { - var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0); - return lastDate < options.minDate || date.getTime() > options.maxDate; - }, - onKeyDown: function(evt) { - if (!picker.$date) { - return; - } - var actualMonth = picker.$date.getMonth(); - var newDate = new Date(picker.$date); - if (evt.keyCode === 37) newDate.setMonth(actualMonth - 1); else if (evt.keyCode === 38) newDate.setMonth(actualMonth - 4); else if (evt.keyCode === 39) newDate.setMonth(actualMonth + 1); else if (evt.keyCode === 40) newDate.setMonth(actualMonth + 4); - if (!this.isDisabled(newDate)) picker.select(newDate, true); - } - }, { - name: 'year', - format: options.yearFormat, - split: 4, - steps: { - year: 12 - }, - update: function(date, force) { - if (!this.built || force || parseInt(date.getFullYear() / 20, 10) !== parseInt(viewDate.year / 20, 10)) { - angular.extend(viewDate, { - year: picker.$date.getFullYear(), - month: picker.$date.getMonth(), - date: picker.$date.getDate() - }); - picker.$build(); - } else if (date.getFullYear() !== viewDate.year) { - angular.extend(viewDate, { - year: picker.$date.getFullYear(), - month: picker.$date.getMonth(), - date: picker.$date.getDate() - }); - picker.$updateSelected(); - } - }, - build: function() { - var firstYear = viewDate.year - viewDate.year % (this.split * 3); - var years = [], year; - for (var i = 0; i < 12; i++) { - year = new Date(firstYear + i, 0, 1); - years.push({ - date: year, - label: formatDate(year, this.format), - selected: picker.$isSelected(year), - disabled: this.isDisabled(year) - }); - } - scope.title = years[0].label + '-' + years[years.length - 1].label; - scope.showLabels = false; - scope.rows = split(years, this.split); - this.built = true; - }, - isSelected: function(date) { - return picker.$date && date.getFullYear() === picker.$date.getFullYear(); - }, - isDisabled: function(date) { - var lastDate = +new Date(date.getFullYear() + 1, 0, 0); - return lastDate < options.minDate || date.getTime() > options.maxDate; - }, - onKeyDown: function(evt) { - if (!picker.$date) { - return; - } - var actualYear = picker.$date.getFullYear(), newDate = new Date(picker.$date); - if (evt.keyCode === 37) newDate.setYear(actualYear - 1); else if (evt.keyCode === 38) newDate.setYear(actualYear - 4); else if (evt.keyCode === 39) newDate.setYear(actualYear + 1); else if (evt.keyCode === 40) newDate.setYear(actualYear + 4); - if (!this.isDisabled(newDate)) picker.select(newDate, true); - } - } ]; - return { - views: options.minView ? Array.prototype.slice.call(views, options.minView) : views, - viewDate: viewDate - }; - }; - } ]; - }); - angular.module('mgcrea.ngStrap.dropdown', [ 'mgcrea.ngStrap.tooltip' ]).provider('$dropdown', function() { - var defaults = this.defaults = { - animation: 'am-fade', - prefixClass: 'dropdown', - prefixEvent: 'dropdown', - placement: 'bottom-left', - templateUrl: 'dropdown/dropdown.tpl.html', - trigger: 'click', - container: false, - keyboard: true, - html: false, - delay: 0 - }; - this.$get = [ '$window', '$rootScope', '$tooltip', '$timeout', function($window, $rootScope, $tooltip, $timeout) { - var bodyEl = angular.element($window.document.body); - var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector; - function DropdownFactory(element, config) { - var $dropdown = {}; - var options = angular.extend({}, defaults, config); - var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new(); - $dropdown = $tooltip(element, options); - var parentEl = element.parent(); - $dropdown.$onKeyDown = function(evt) { - if (!/(38|40)/.test(evt.keyCode)) return; - evt.preventDefault(); - evt.stopPropagation(); - var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a')); - if (!items.length) return; - var index; - angular.forEach(items, function(el, i) { - if (matchesSelector && matchesSelector.call(el, ':focus')) index = i; - }); - if (evt.keyCode === 38 && index > 0) index--; else if (evt.keyCode === 40 && index < items.length - 1) index++; else if (angular.isUndefined(index)) index = 0; - items.eq(index)[0].focus(); - }; - var show = $dropdown.show; - $dropdown.show = function() { - show(); - $timeout(function() { - options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown); - bodyEl.on('click', onBodyClick); - }, 0, false); - parentEl.hasClass('dropdown') && parentEl.addClass('open'); - }; - var hide = $dropdown.hide; - $dropdown.hide = function() { - if (!$dropdown.$isShown) return; - options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown); - bodyEl.off('click', onBodyClick); - parentEl.hasClass('dropdown') && parentEl.removeClass('open'); - hide(); - }; - var destroy = $dropdown.destroy; - $dropdown.destroy = function() { - bodyEl.off('click', onBodyClick); - destroy(); - }; - function onBodyClick(evt) { - if (evt.target === element[0]) return; - return evt.target !== element[0] && $dropdown.hide(); - } - return $dropdown; - } - return DropdownFactory; - } ]; - }).directive('bsDropdown', [ '$window', '$sce', '$dropdown', function($window, $sce, $dropdown) { - return { - restrict: 'EAC', - scope: true, - link: function postLink(scope, element, attr, transclusion) { - var options = { - scope: scope - }; - angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id' ], function(key) { - if (angular.isDefined(attr[key])) options[key] = attr[key]; - }); - var falseValueRegExp = /^(false|0|)$/i; - angular.forEach([ 'html', 'container' ], function(key) { - if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; - }); - attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) { - scope.content = newValue; - }, true); - attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) { - if (!dropdown || !angular.isDefined(newValue)) return; - if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i); - newValue === true ? dropdown.show() : dropdown.hide(); - }); - var dropdown = $dropdown(element, options); - scope.$on('$destroy', function() { - if (dropdown) dropdown.destroy(); - options = null; - dropdown = null; - }); - } - }; - } ]); - angular.module('mgcrea.ngStrap.core', []).service('$bsCompiler', bsCompilerService); - function bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) { - this.compile = function(options) { - if (options.template && /\.html$/.test(options.template)) { - console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'); - options.templateUrl = options.template; - options.template = ''; - } - var templateUrl = options.templateUrl; - var template = options.template || ''; - var controller = options.controller; - var controllerAs = options.controllerAs; - var resolve = angular.copy(options.resolve || {}); - var locals = angular.copy(options.locals || {}); - var transformTemplate = options.transformTemplate || angular.identity; - var bindToController = options.bindToController; - angular.forEach(resolve, function(value, key) { - if (angular.isString(value)) { - resolve[key] = $injector.get(value); - } else { - resolve[key] = $injector.invoke(value); - } - }); - angular.extend(resolve, locals); - if (templateUrl) { - resolve.$template = fetchTemplate(templateUrl); - } else { - resolve.$template = $q.when(template); - } - if (options.contentTemplate) { - resolve.$template = $q.all([ resolve.$template, fetchTemplate(options.contentTemplate) ]).then(function(templates) { - var templateEl = angular.element(templates[0]); - var contentEl = findElement('[ng-bind="content"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]); - if (!options.templateUrl) contentEl.next().remove(); - return templateEl[0].outerHTML; - }); - } - return $q.all(resolve).then(function(locals) { - var template = transformTemplate(locals.$template); - if (options.html) { - template = template.replace(/ng-bind="/gi, 'ng-bind-html="'); - } - var element = angular.element('
').html(template.trim()).contents(); - var linkFn = $compile(element); - return { - locals: locals, - element: element, - link: function link(scope) { - locals.$scope = scope; - if (controller) { - var invokeCtrl = $controller(controller, locals, true); - if (bindToController) { - angular.extend(invokeCtrl.instance, locals); - } - var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl(); - element.data('$ngControllerController', ctrl); - element.children().data('$ngControllerController', ctrl); - if (controllerAs) { - scope[controllerAs] = ctrl; - } - } - return linkFn.apply(null, arguments); - } - }; - }); - }; - function findElement(query, element) { - return angular.element((element || document).querySelectorAll(query)); - } - var fetchPromises = {}; - function fetchTemplate(template) { - if (fetchPromises[template]) return fetchPromises[template]; - return fetchPromises[template] = $http.get(template, { - cache: $templateCache - }).then(function(res) { - return res.data; - }); - } - } - bsCompilerService.$inject = [ '$q', '$http', '$injector', '$compile', '$controller', '$templateCache' ]; - angular.module('mgcrea.ngStrap.helpers.dateFormatter', []).service('$dateFormatter', [ '$locale', 'dateFilter', function($locale, dateFilter) { - this.getDefaultLocale = function() { - return $locale.id; - }; - this.getDatetimeFormat = function(format, lang) { - return $locale.DATETIME_FORMATS[format] || format; - }; - this.weekdaysShort = function(lang) { - return $locale.DATETIME_FORMATS.SHORTDAY; - }; - function splitTimeFormat(format) { - return /(h+)([:\.])?(m+)([:\.])?(s*)[ ]?(a?)/i.exec(format).slice(1); - } - this.hoursFormat = function(timeFormat) { - return splitTimeFormat(timeFormat)[0]; - }; - this.minutesFormat = function(timeFormat) { - return splitTimeFormat(timeFormat)[2]; - }; - this.secondsFormat = function(timeFormat) { - return splitTimeFormat(timeFormat)[4]; - }; - this.timeSeparator = function(timeFormat) { - return splitTimeFormat(timeFormat)[1]; - }; - this.showSeconds = function(timeFormat) { - return !!splitTimeFormat(timeFormat)[4]; - }; - this.showAM = function(timeFormat) { - return !!splitTimeFormat(timeFormat)[5]; - }; - this.formatDate = function(date, format, lang, timezone) { - return dateFilter(date, format, timezone); - }; - } ]); - angular.module('mgcrea.ngStrap.helpers.dateParser', []).provider('$dateParser', [ '$localeProvider', function($localeProvider) { - function ParseDate() { - this.year = 1970; - this.month = 0; - this.day = 1; - this.hours = 0; - this.minutes = 0; - this.seconds = 0; - this.milliseconds = 0; - } - ParseDate.prototype.setMilliseconds = function(value) { - this.milliseconds = value; - }; - ParseDate.prototype.setSeconds = function(value) { - this.seconds = value; - }; - ParseDate.prototype.setMinutes = function(value) { - this.minutes = value; - }; - ParseDate.prototype.setHours = function(value) { - this.hours = value; - }; - ParseDate.prototype.getHours = function() { - return this.hours; - }; - ParseDate.prototype.setDate = function(value) { - this.day = value; - }; - ParseDate.prototype.setMonth = function(value) { - this.month = value; - }; - ParseDate.prototype.setFullYear = function(value) { - this.year = value; - }; - ParseDate.prototype.fromDate = function(value) { - this.year = value.getFullYear(); - this.month = value.getMonth(); - this.day = value.getDate(); - this.hours = value.getHours(); - this.minutes = value.getMinutes(); - this.seconds = value.getSeconds(); - this.milliseconds = value.getMilliseconds(); - return this; - }; - ParseDate.prototype.toDate = function() { - return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds); - }; - var proto = ParseDate.prototype; - function noop() {} - function isNumeric(n) { - return !isNaN(parseFloat(n)) && isFinite(n); - } - function indexOfCaseInsensitive(array, value) { - var len = array.length, str = value.toString().toLowerCase(); - for (var i = 0; i < len; i++) { - if (array[i].toLowerCase() === str) { - return i; - } - } - return -1; - } - var defaults = this.defaults = { - format: 'shortDate', - strict: false - }; - this.$get = [ '$locale', 'dateFilter', function($locale, dateFilter) { - var DateParserFactory = function(config) { - var options = angular.extend({}, defaults, config); - var $dateParser = {}; - var regExpMap = { - sss: '[0-9]{3}', - ss: '[0-5][0-9]', - s: options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]', - mm: '[0-5][0-9]', - m: options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]', - HH: '[01][0-9]|2[0-3]', - H: options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]', - hh: '[0][1-9]|[1][012]', - h: options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]', - a: 'AM|PM', - EEEE: $locale.DATETIME_FORMATS.DAY.join('|'), - EEE: $locale.DATETIME_FORMATS.SHORTDAY.join('|'), - dd: '0[1-9]|[12][0-9]|3[01]', - d: options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]', - MMMM: $locale.DATETIME_FORMATS.MONTH.join('|'), - MMM: $locale.DATETIME_FORMATS.SHORTMONTH.join('|'), - MM: '0[1-9]|1[012]', - M: options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]', - yyyy: '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}', - yy: '[0-9]{2}', - y: options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}' - }; - var setFnMap = { - sss: proto.setMilliseconds, - ss: proto.setSeconds, - s: proto.setSeconds, - mm: proto.setMinutes, - m: proto.setMinutes, - HH: proto.setHours, - H: proto.setHours, - hh: proto.setHours, - h: proto.setHours, - EEEE: noop, - EEE: noop, - dd: proto.setDate, - d: proto.setDate, - a: function(value) { - var hours = this.getHours() % 12; - return this.setHours(value.match(/pm/i) ? hours + 12 : hours); - }, - MMMM: function(value) { - return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); - }, - MMM: function(value) { - return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); - }, - MM: function(value) { - return this.setMonth(1 * value - 1); - }, - M: function(value) { - return this.setMonth(1 * value - 1); - }, - yyyy: proto.setFullYear, - yy: function(value) { - return this.setFullYear(2e3 + 1 * value); - }, - y: function(value) { - return 1 * value <= 50 && value.length === 2 ? this.setFullYear(2e3 + 1 * value) : this.setFullYear(1 * value); - } - }; - var regex, setMap; - $dateParser.init = function() { - $dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format; - regex = regExpForFormat($dateParser.$format); - setMap = setMapForFormat($dateParser.$format); - }; - $dateParser.isValid = function(date) { - if (angular.isDate(date)) return !isNaN(date.getTime()); - return regex.test(date); - }; - $dateParser.parse = function(value, baseDate, format, timezone) { - if (format) format = $locale.DATETIME_FORMATS[format] || format; - if (angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format, timezone); - var formatRegex = format ? regExpForFormat(format) : regex; - var formatSetMap = format ? setMapForFormat(format) : setMap; - var matches = formatRegex.exec(value); - if (!matches) return false; - var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0)); - for (var i = 0; i < matches.length - 1; i++) { - formatSetMap[i] && formatSetMap[i].call(date, matches[i + 1]); - } - var newDate = date.toDate(); - if (parseInt(date.day, 10) !== newDate.getDate()) { - return false; - } - return newDate; - }; - $dateParser.getDateForAttribute = function(key, value) { - var date; - if (value === 'today') { - var today = new Date(); - date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, key === 'minDate' ? 0 : -1); - } else if (angular.isString(value) && value.match(/^".+"$/)) { - date = new Date(value.substr(1, value.length - 2)); - } else if (isNumeric(value)) { - date = new Date(parseInt(value, 10)); - } else if (angular.isString(value) && 0 === value.length) { - date = key === 'minDate' ? -Infinity : +Infinity; - } else { - date = new Date(value); - } - return date; - }; - $dateParser.getTimeForAttribute = function(key, value) { - var time; - if (value === 'now') { - time = new Date().setFullYear(1970, 0, 1); - } else if (angular.isString(value) && value.match(/^".+"$/)) { - time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1); - } else if (isNumeric(value)) { - time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1); - } else if (angular.isString(value) && 0 === value.length) { - time = key === 'minTime' ? -Infinity : +Infinity; - } else { - time = $dateParser.parse(value, new Date(1970, 0, 1, 0)); - } - return time; - }; - $dateParser.daylightSavingAdjust = function(date) { - if (!date) { - return null; - } - date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); - return date; - }; - $dateParser.timezoneOffsetAdjust = function(date, timezone, undo) { - if (!date) { - return null; - } - if (timezone && timezone === 'UTC') { - date = new Date(date.getTime()); - date.setMinutes(date.getMinutes() + (undo ? -1 : 1) * date.getTimezoneOffset()); - } - return date; - }; - function setMapForFormat(format) { - var keys = Object.keys(setFnMap), i; - var map = [], sortedMap = []; - var clonedFormat = format; - for (i = 0; i < keys.length; i++) { - if (format.split(keys[i]).length > 1) { - var index = clonedFormat.search(keys[i]); - format = format.split(keys[i]).join(''); - if (setFnMap[keys[i]]) { - map[index] = setFnMap[keys[i]]; - } - } - } - angular.forEach(map, function(v) { - if (v) sortedMap.push(v); - }); - return sortedMap; - } - function escapeReservedSymbols(text) { - return text.replace(/\//g, '[\\/]').replace('/-/g', '[-]').replace(/\./g, '[.]').replace(/\\s/g, '[\\s]'); - } - function regExpForFormat(format) { - var keys = Object.keys(regExpMap), i; - var re = format; - for (i = 0; i < keys.length; i++) { - re = re.split(keys[i]).join('${' + i + '}'); - } - for (i = 0; i < keys.length; i++) { - re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')'); - } - format = escapeReservedSymbols(format); - return new RegExp('^' + re + '$', [ 'i' ]); - } - $dateParser.init(); - return $dateParser; - }; - return DateParserFactory; - } ]; - } ]); - angular.module('mgcrea.ngStrap.helpers.debounce', []).factory('debounce', [ '$timeout', function($timeout) { - return function(func, wait, immediate) { - var timeout = null; - return function() { - var context = this, args = arguments, callNow = immediate && !timeout; - if (timeout) { - $timeout.cancel(timeout); - } - timeout = $timeout(function later() { - timeout = null; - if (!immediate) { - func.apply(context, args); - } - }, wait, false); - if (callNow) { - func.apply(context, args); - } - return timeout; - }; - }; - } ]).factory('throttle', [ '$timeout', function($timeout) { - return function(func, wait, options) { - var timeout = null; - options || (options = {}); - return function() { - var context = this, args = arguments; - if (!timeout) { - if (options.leading !== false) { - func.apply(context, args); - } - timeout = $timeout(function later() { - timeout = null; - if (options.trailing !== false) { - func.apply(context, args); - } - }, wait, false); - } - }; - }; - } ]); - angular.module('mgcrea.ngStrap.helpers.dimensions', []).factory('dimensions', [ '$document', '$window', function($document, $window) { - var jqLite = angular.element; - var fn = {}; - var nodeName = fn.nodeName = function(element, name) { - return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase(); - }; - fn.css = function(element, prop, extra) { - var value; - if (element.currentStyle) { - value = element.currentStyle[prop]; - } else if (window.getComputedStyle) { - value = window.getComputedStyle(element)[prop]; - } else { - value = element.style[prop]; - } - return extra === true ? parseFloat(value) || 0 : value; - }; - fn.offset = function(element) { - var boxRect = element.getBoundingClientRect(); - var docElement = element.ownerDocument; - return { - width: boxRect.width || element.offsetWidth, - height: boxRect.height || element.offsetHeight, - top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0), - left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0) - }; - }; - fn.setOffset = function(element, options, i) { - var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, position = fn.css(element, 'position'), curElem = angular.element(element), props = {}; - if (position === 'static') { - element.style.position = 'relative'; - } - curOffset = fn.offset(element); - curCSSTop = fn.css(element, 'top'); - curCSSLeft = fn.css(element, 'left'); - calculatePosition = (position === 'absolute' || position === 'fixed') && (curCSSTop + curCSSLeft).indexOf('auto') > -1; - if (calculatePosition) { - curPosition = fn.position(element); - curTop = curPosition.top; - curLeft = curPosition.left; - } else { - curTop = parseFloat(curCSSTop) || 0; - curLeft = parseFloat(curCSSLeft) || 0; - } - if (angular.isFunction(options)) { - options = options.call(element, i, curOffset); - } - if (options.top !== null) { - props.top = options.top - curOffset.top + curTop; - } - if (options.left !== null) { - props.left = options.left - curOffset.left + curLeft; - } - if ('using' in options) { - options.using.call(curElem, props); - } else { - curElem.css({ - top: props.top + 'px', - left: props.left + 'px' - }); - } - }; - fn.position = function(element) { - var offsetParentRect = { - top: 0, - left: 0 - }, offsetParentElement, offset; - if (fn.css(element, 'position') === 'fixed') { - offset = element.getBoundingClientRect(); - } else { - offsetParentElement = offsetParent(element); - offset = fn.offset(element); - if (!nodeName(offsetParentElement, 'html')) { - offsetParentRect = fn.offset(offsetParentElement); - } - offsetParentRect.top += fn.css(offsetParentElement, 'borderTopWidth', true); - offsetParentRect.left += fn.css(offsetParentElement, 'borderLeftWidth', true); - } - return { - width: element.offsetWidth, - height: element.offsetHeight, - top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true), - left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true) - }; - }; - var offsetParent = function offsetParentElement(element) { - var docElement = element.ownerDocument; - var offsetParent = element.offsetParent || docElement; - if (nodeName(offsetParent, '#document')) return docElement.documentElement; - while (offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') { - offsetParent = offsetParent.offsetParent; - } - return offsetParent || docElement.documentElement; - }; - fn.height = function(element, outer) { - var value = element.offsetHeight; - if (outer) { - value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true); - } else { - value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true); - } - return value; - }; - fn.width = function(element, outer) { - var value = element.offsetWidth; - if (outer) { - value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true); - } else { - value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true); - } - return value; - }; - return fn; - } ]); - angular.module('mgcrea.ngStrap.helpers.parseOptions', []).provider('$parseOptions', function() { - var defaults = this.defaults = { - regexp: /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/ - }; - this.$get = [ '$parse', '$q', function($parse, $q) { - function ParseOptionsFactory(attr, config) { - var $parseOptions = {}; - var options = angular.extend({}, defaults, config); - $parseOptions.$values = []; - var match, displayFn, valueName, keyName, groupByFn, valueFn, valuesFn; - $parseOptions.init = function() { - $parseOptions.$match = match = attr.match(options.regexp); - displayFn = $parse(match[2] || match[1]), valueName = match[4] || match[6], keyName = match[5], - groupByFn = $parse(match[3] || ''), valueFn = $parse(match[2] ? match[1] : valueName), - valuesFn = $parse(match[7]); - }; - $parseOptions.valuesFn = function(scope, controller) { - return $q.when(valuesFn(scope, controller)).then(function(values) { - if (!angular.isArray(values)) { - values = []; - } - $parseOptions.$values = values.length ? parseValues(values, scope) : []; - return $parseOptions.$values; - }); - }; - $parseOptions.displayValue = function(modelValue) { - var scope = {}; - scope[valueName] = modelValue; - return displayFn(scope); - }; - function parseValues(values, scope) { - return values.map(function(match, index) { - var locals = {}, label, value; - locals[valueName] = match; - label = displayFn(scope, locals); - value = valueFn(scope, locals); - return { - label: label, - value: value, - index: index - }; - }); - } - $parseOptions.init(); - return $parseOptions; - } - return ParseOptionsFactory; - } ]; - }); - angular.version.minor < 3 && angular.version.dot < 14 && angular.module('ng').factory('$$rAF', [ '$window', '$timeout', function($window, $timeout) { - var requestAnimationFrame = $window.requestAnimationFrame || $window.webkitRequestAnimationFrame || $window.mozRequestAnimationFrame; - var cancelAnimationFrame = $window.cancelAnimationFrame || $window.webkitCancelAnimationFrame || $window.mozCancelAnimationFrame || $window.webkitCancelRequestAnimationFrame; - var rafSupported = !!requestAnimationFrame; - var raf = rafSupported ? function(fn) { - var id = requestAnimationFrame(fn); - return function() { - cancelAnimationFrame(id); - }; - } : function(fn) { - var timer = $timeout(fn, 16.66, false); - return function() { - $timeout.cancel(timer); - }; - }; - raf.supported = rafSupported; - return raf; - } ]); - angular.module('mgcrea.ngStrap.modal', [ 'mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$modal', function() { - var defaults = this.defaults = { - animation: 'am-fade', - backdropAnimation: 'am-fade', - prefixClass: 'modal', - prefixEvent: 'modal', + target: false, placement: 'top', - templateUrl: 'modal/modal.tpl.html', + templateUrl: 'tooltip/tooltip.tpl.html', template: '', - contentTemplate: false, - container: false, - element: null, - backdrop: true, - keyboard: true, + titleTemplate: false, + trigger: 'hover focus', + keyboard: false, html: false, - show: true + show: false, + title: '', + type: '', + delay: 0, + autoClose: false, + bsEnabled: true, + mouseDownPreventDefault: true, + mouseDownStopPropagation: true, + viewport: { + selector: 'body', + padding: 0 + } }; - this.$get = [ '$window', '$rootScope', '$bsCompiler', '$q', '$templateCache', '$http', '$animate', '$timeout', '$sce', 'dimensions', function($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $timeout, $sce, dimensions) { - var forEach = angular.forEach; - var trim = String.prototype.trim; - var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout; - var bodyElement = angular.element($window.document.body); - function ModalFactory(config) { - var $modal = {}; - var options = $modal.$options = angular.extend({}, defaults, config); - var promise = $modal.$promise = $bsCompiler.compile(options); - var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new(); - if (!options.element && !options.container) { - options.container = 'body'; + this.$get = [ '$window', '$rootScope', '$bsCompiler', '$q', '$templateCache', '$http', '$animate', '$sce', 'dimensions', '$$rAF', '$timeout', function($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) { + var isNative = /(ip[ao]d|iphone|android)/gi.test($window.navigator.userAgent); + var isTouch = 'createTouch' in $window.document && isNative; + var $body = angular.element($window.document); + function TooltipFactory(element, config) { + var $tooltip = {}; + var options = $tooltip.$options = angular.extend({}, defaults, config); + var promise = $tooltip.$promise = $bsCompiler.compile(options); + var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new(); + var nodeName = element[0].nodeName.toLowerCase(); + if (options.delay && angular.isString(options.delay)) { + var split = options.delay.split(',').map(parseFloat); + options.delay = split.length > 1 ? { + show: split[0], + hide: split[1] + } : split[0]; } - $modal.$id = options.id || options.element && options.element.attr('id') || ''; - forEach([ 'title', 'content' ], function(key) { - if (options[key]) scope[key] = $sce.trustAsHtml(options[key]); - }); + $tooltip.$id = options.id || element.attr('id') || ''; + if (options.title) { + scope.title = $sce.trustAsHtml(options.title); + } + scope.$setEnabled = function(isEnabled) { + scope.$$postDigest(function() { + $tooltip.setEnabled(isEnabled); + }); + }; scope.$hide = function() { scope.$$postDigest(function() { - $modal.hide(); + $tooltip.hide(); }); }; scope.$show = function() { scope.$$postDigest(function() { - $modal.show(); + $tooltip.show(); }); }; scope.$toggle = function() { scope.$$postDigest(function() { - $modal.toggle(); + $tooltip.toggle(); }); }; - $modal.$isShown = scope.$isShown = false; - var compileData, modalElement, modalScope; - var backdropElement = angular.element('
'); - backdropElement.css({ - position: 'fixed', - top: '0px', - left: '0px', - bottom: '0px', - right: '0px', - 'z-index': 1038 - }); + $tooltip.$isShown = scope.$isShown = false; + var timeout; + var hoverState; + var compileData; + var tipElement; + var tipContainer; + var tipScope; promise.then(function(data) { compileData = data; - $modal.init(); + $tooltip.init(); }); - $modal.init = function() { + $tooltip.init = function() { + if (options.delay && angular.isNumber(options.delay)) { + options.delay = { + show: options.delay, + hide: options.delay + }; + } + if (options.container === 'self') { + tipContainer = element; + } else if (angular.isElement(options.container)) { + tipContainer = options.container; + } else if (options.container) { + tipContainer = findElement(options.container); + } + bindTriggerEvents(); + if (options.target) { + options.target = angular.isElement(options.target) ? options.target : findElement(options.target); + } if (options.show) { scope.$$postDigest(function() { - $modal.show(); + if (options.trigger === 'focus') { + element[0].focus(); + } else { + $tooltip.show(); + } }); } }; - $modal.destroy = function() { - destroyModalElement(); - if (backdropElement) { - backdropElement.remove(); - backdropElement = null; - } + $tooltip.destroy = function() { + unbindTriggerEvents(); + destroyTipElement(); scope.$destroy(); }; - $modal.show = function() { - if ($modal.$isShown) return; - var parent, after; - if (angular.isElement(options.container)) { - parent = options.container; - after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null; - } else { - if (options.container) { - parent = findElement(options.container); - after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null; + $tooltip.enter = function() { + clearTimeout(timeout); + hoverState = 'in'; + if (!options.delay || !options.delay.show) { + return $tooltip.show(); + } + timeout = setTimeout(function() { + if (hoverState === 'in') $tooltip.show(); + }, options.delay.show); + }; + $tooltip.show = function() { + if (!options.bsEnabled || $tooltip.$isShown) return; + scope.$emit(options.prefixEvent + '.show.before', $tooltip); + if (angular.isDefined(options.onBeforeShow) && angular.isFunction(options.onBeforeShow)) { + options.onBeforeShow($tooltip); + } + var parent; + var after; + if (options.container) { + parent = tipContainer; + if (tipContainer[0].lastChild) { + after = angular.element(tipContainer[0].lastChild); } else { - parent = null; - after = options.element; + after = null; } - } - if (modalElement) destroyModalElement(); - modalScope = $modal.$scope.$new(); - modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {}); - if (scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) { - return; - } - modalElement.css({ - display: 'block' - }).addClass(options.placement); - if (options.animation) { - if (options.backdrop) { - backdropElement.addClass(options.backdropAnimation); - } - modalElement.addClass(options.animation); - } - if (options.backdrop) { - $animate.enter(backdropElement, bodyElement, null); - } - if (angular.version.minor <= 2) { - $animate.enter(modalElement, parent, after, enterAnimateCallback); } else { - $animate.enter(modalElement, parent, after).then(enterAnimateCallback); + parent = null; + after = element; } - $modal.$isShown = scope.$isShown = true; - safeDigest(scope); - var el = modalElement[0]; - requestAnimationFrame(function() { - el.focus(); + if (tipElement) destroyTipElement(); + tipScope = $tooltip.$scope.$new(); + tipElement = $tooltip.$element = compileData.link(tipScope, function(clonedElement, scope) {}); + tipElement.css({ + top: '-9999px', + left: '-9999px', + right: 'auto', + display: 'block', + visibility: 'hidden' }); - bodyElement.addClass(options.prefixClass + '-open'); - if (options.animation) { - bodyElement.addClass(options.prefixClass + '-with-' + options.animation); + if (options.animation) tipElement.addClass(options.animation); + if (options.type) tipElement.addClass(options.prefixClass + '-' + options.type); + if (options.customClass) tipElement.addClass(options.customClass); + if (after) { + after.after(tipElement); + } else { + parent.prepend(tipElement); + } + $tooltip.$isShown = scope.$isShown = true; + safeDigest(scope); + $tooltip.$applyPlacement(); + if (angular.version.minor <= 2) { + $animate.enter(tipElement, parent, after, enterAnimateCallback); + } else { + $animate.enter(tipElement, parent, after).then(enterAnimateCallback); + } + safeDigest(scope); + $$rAF(function() { + if (tipElement) tipElement.css({ + visibility: 'visible' + }); + if (options.keyboard) { + if (options.trigger !== 'focus') { + $tooltip.focus(); + } + bindKeyboardEvents(); + } + }); + if (options.autoClose) { + bindAutoCloseEvents(); } - bindBackdropEvents(); - bindKeyboardEvents(); }; function enterAnimateCallback() { - scope.$emit(options.prefixEvent + '.show', $modal); + scope.$emit(options.prefixEvent + '.show', $tooltip); + if (angular.isDefined(options.onShow) && angular.isFunction(options.onShow)) { + options.onShow($tooltip); + } } - $modal.hide = function() { - if (!$modal.$isShown) return; - if (scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) { - return; + $tooltip.leave = function() { + clearTimeout(timeout); + hoverState = 'out'; + if (!options.delay || !options.delay.hide) { + return $tooltip.hide(); } + timeout = setTimeout(function() { + if (hoverState === 'out') { + $tooltip.hide(); + } + }, options.delay.hide); + }; + var _blur; + var _tipToHide; + $tooltip.hide = function(blur) { + if (!$tooltip.$isShown) return; + scope.$emit(options.prefixEvent + '.hide.before', $tooltip); + if (angular.isDefined(options.onBeforeHide) && angular.isFunction(options.onBeforeHide)) { + options.onBeforeHide($tooltip); + } + _blur = blur; + _tipToHide = tipElement; if (angular.version.minor <= 2) { - $animate.leave(modalElement, leaveAnimateCallback); + $animate.leave(tipElement, leaveAnimateCallback); } else { - $animate.leave(modalElement).then(leaveAnimateCallback); + $animate.leave(tipElement).then(leaveAnimateCallback); } - if (options.backdrop) { - $animate.leave(backdropElement); - } - $modal.$isShown = scope.$isShown = false; + $tooltip.$isShown = scope.$isShown = false; safeDigest(scope); - unbindBackdropEvents(); - unbindKeyboardEvents(); + if (options.keyboard && tipElement !== null) { + unbindKeyboardEvents(); + } + if (options.autoClose && tipElement !== null) { + unbindAutoCloseEvents(); + } }; function leaveAnimateCallback() { - scope.$emit(options.prefixEvent + '.hide', $modal); - bodyElement.removeClass(options.prefixClass + '-open'); - if (options.animation) { - bodyElement.removeClass(options.prefixClass + '-with-' + options.animation); + scope.$emit(options.prefixEvent + '.hide', $tooltip); + if (angular.isDefined(options.onHide) && angular.isFunction(options.onHide)) { + options.onHide($tooltip); + } + if (tipElement === _tipToHide) { + if (_blur && options.trigger === 'focus') { + return element[0].blur(); + } + destroyTipElement(); } } - $modal.toggle = function() { - $modal.$isShown ? $modal.hide() : $modal.show(); + $tooltip.toggle = function(evt) { + if (evt) { + evt.preventDefault(); + } + if ($tooltip.$isShown) { + $tooltip.leave(); + } else { + $tooltip.enter(); + } }; - $modal.focus = function() { - modalElement[0].focus(); + $tooltip.focus = function() { + tipElement[0].focus(); }; - $modal.$onKeyUp = function(evt) { - if (evt.which === 27 && $modal.$isShown) { - $modal.hide(); + $tooltip.setEnabled = function(isEnabled) { + options.bsEnabled = isEnabled; + }; + $tooltip.setViewport = function(viewport) { + options.viewport = viewport; + }; + $tooltip.$applyPlacement = function() { + if (!tipElement) return; + var placement = options.placement; + var autoToken = /\s?auto?\s?/i; + var autoPlace = autoToken.test(placement); + if (autoPlace) { + placement = placement.replace(autoToken, '') || defaults.placement; + } + tipElement.addClass(options.placement); + var elementPosition = getPosition(); + var tipWidth = tipElement.prop('offsetWidth'); + var tipHeight = tipElement.prop('offsetHeight'); + $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport); + if (autoPlace) { + var originalPlacement = placement; + var viewportPosition = getPosition($tooltip.$viewport); + if (/bottom/.test(originalPlacement) && elementPosition.bottom + tipHeight > viewportPosition.bottom) { + placement = originalPlacement.replace('bottom', 'top'); + } else if (/top/.test(originalPlacement) && elementPosition.top - tipHeight < viewportPosition.top) { + placement = originalPlacement.replace('top', 'bottom'); + } + if (/left/.test(originalPlacement) && elementPosition.left - tipWidth < viewportPosition.left) { + placement = placement.replace('left', 'right'); + } else if (/right/.test(originalPlacement) && elementPosition.right + tipWidth > viewportPosition.width) { + placement = placement.replace('right', 'left'); + } + tipElement.removeClass(originalPlacement).addClass(placement); + } + var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight); + applyPlacement(tipPosition, placement); + }; + $tooltip.$onKeyUp = function(evt) { + if (evt.which === 27 && $tooltip.$isShown) { + $tooltip.hide(); evt.stopPropagation(); } }; - function bindBackdropEvents() { - if (options.backdrop) { - modalElement.on('click', hideOnBackdropClick); - backdropElement.on('click', hideOnBackdropClick); - backdropElement.on('wheel', preventEventDefault); + $tooltip.$onFocusKeyUp = function(evt) { + if (evt.which === 27) { + element[0].blur(); + evt.stopPropagation(); } + }; + $tooltip.$onFocusElementMouseDown = function(evt) { + if (options.mouseDownPreventDefault) { + evt.preventDefault(); + } + if (options.mouseDownStopPropagation) { + evt.stopPropagation(); + } + if ($tooltip.$isShown) { + element[0].blur(); + } else { + element[0].focus(); + } + }; + function bindTriggerEvents() { + var triggers = options.trigger.split(' '); + angular.forEach(triggers, function(trigger) { + if (trigger === 'click' || trigger === 'contextmenu') { + element.on(trigger, $tooltip.toggle); + } else if (trigger !== 'manual') { + element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter); + element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave); + if (nodeName === 'button' && trigger !== 'hover') { + element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown); + } + } + }); } - function unbindBackdropEvents() { - if (options.backdrop) { - modalElement.off('click', hideOnBackdropClick); - backdropElement.off('click', hideOnBackdropClick); - backdropElement.off('wheel', preventEventDefault); + function unbindTriggerEvents() { + var triggers = options.trigger.split(' '); + for (var i = triggers.length; i--; ) { + var trigger = triggers[i]; + if (trigger === 'click' || trigger === 'contextmenu') { + element.off(trigger, $tooltip.toggle); + } else if (trigger !== 'manual') { + element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter); + element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave); + if (nodeName === 'button' && trigger !== 'hover') { + element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown); + } + } } } function bindKeyboardEvents() { - if (options.keyboard) { - modalElement.on('keyup', $modal.$onKeyUp); + if (options.trigger !== 'focus') { + tipElement.on('keyup', $tooltip.$onKeyUp); + } else { + element.on('keyup', $tooltip.$onFocusKeyUp); } } function unbindKeyboardEvents() { - if (options.keyboard) { - modalElement.off('keyup', $modal.$onKeyUp); + if (options.trigger !== 'focus') { + tipElement.off('keyup', $tooltip.$onKeyUp); + } else { + element.off('keyup', $tooltip.$onFocusKeyUp); } } - function hideOnBackdropClick(evt) { - if (evt.target !== evt.currentTarget) return; - options.backdrop === 'static' ? $modal.focus() : $modal.hide(); + var _autoCloseEventsBinded = false; + function bindAutoCloseEvents() { + $timeout(function() { + tipElement.on('click', stopEventPropagation); + $body.on('click', $tooltip.hide); + _autoCloseEventsBinded = true; + }, 0, false); } - function preventEventDefault(evt) { - evt.preventDefault(); - } - function destroyModalElement() { - if ($modal.$isShown && modalElement !== null) { - unbindBackdropEvents(); - unbindKeyboardEvents(); - } - if (modalScope) { - modalScope.$destroy(); - modalScope = null; - } - if (modalElement) { - modalElement.remove(); - modalElement = $modal.$element = null; + function unbindAutoCloseEvents() { + if (_autoCloseEventsBinded) { + tipElement.off('click', stopEventPropagation); + $body.off('click', $tooltip.hide); + _autoCloseEventsBinded = false; } } - return $modal; + function stopEventPropagation(event) { + event.stopPropagation(); + } + function getPosition($element) { + $element = $element || (options.target || element); + var el = $element[0]; + var isBody = el.tagName === 'BODY'; + var elRect = el.getBoundingClientRect(); + var rect = {}; + for (var p in elRect) { + rect[p] = elRect[p]; + } + if (rect.width === null) { + rect = angular.extend({}, rect, { + width: elRect.right - elRect.left, + height: elRect.bottom - elRect.top + }); + } + var elOffset = isBody ? { + top: 0, + left: 0 + } : dimensions.offset(el); + var scroll = { + scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 + }; + var outerDims = isBody ? { + width: document.documentElement.clientWidth, + height: $window.innerHeight + } : null; + return angular.extend({}, rect, scroll, outerDims, elOffset); + } + function getCalculatedOffset(placement, position, actualWidth, actualHeight) { + var offset; + var split = placement.split('-'); + switch (split[0]) { + case 'right': + offset = { + top: position.top + position.height / 2 - actualHeight / 2, + left: position.left + position.width + }; + break; + + case 'bottom': + offset = { + top: position.top + position.height, + left: position.left + position.width / 2 - actualWidth / 2 + }; + break; + + case 'left': + offset = { + top: position.top + position.height / 2 - actualHeight / 2, + left: position.left - actualWidth + }; + break; + + default: + offset = { + top: position.top - actualHeight, + left: position.left + position.width / 2 - actualWidth / 2 + }; + break; + } + if (!split[1]) { + return offset; + } + if (split[0] === 'top' || split[0] === 'bottom') { + switch (split[1]) { + case 'left': + offset.left = position.left; + break; + + case 'right': + offset.left = position.left + position.width - actualWidth; + break; + + default: + break; + } + } else if (split[0] === 'left' || split[0] === 'right') { + switch (split[1]) { + case 'top': + offset.top = position.top - actualHeight + position.height; + break; + + case 'bottom': + offset.top = position.top; + break; + + default: + break; + } + } + return offset; + } + function applyPlacement(offset, placement) { + var tip = tipElement[0]; + var width = tip.offsetWidth; + var height = tip.offsetHeight; + var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10); + var marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10); + if (isNaN(marginTop)) marginTop = 0; + if (isNaN(marginLeft)) marginLeft = 0; + offset.top = offset.top + marginTop; + offset.left = offset.left + marginLeft; + dimensions.setOffset(tip, angular.extend({ + using: function(props) { + tipElement.css({ + top: Math.round(props.top) + 'px', + left: Math.round(props.left) + 'px', + right: '' + }); + } + }, offset), 0); + var actualWidth = tip.offsetWidth; + var actualHeight = tip.offsetHeight; + if (placement === 'top' && actualHeight !== height) { + offset.top = offset.top + height - actualHeight; + } + if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return; + var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight); + if (delta.left) { + offset.left += delta.left; + } else { + offset.top += delta.top; + } + dimensions.setOffset(tip, offset); + if (/top|right|bottom|left/.test(placement)) { + var isVertical = /top|bottom/.test(placement); + var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight; + var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'; + replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical); + } + } + function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) { + var delta = { + top: 0, + left: 0 + }; + if (!$tooltip.$viewport) return delta; + var viewportPadding = options.viewport && options.viewport.padding || 0; + var viewportDimensions = getPosition($tooltip.$viewport); + if (/right|left/.test(placement)) { + var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll; + var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight; + if (topEdgeOffset < viewportDimensions.top) { + delta.top = viewportDimensions.top - topEdgeOffset; + } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { + delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset; + } + } else { + var leftEdgeOffset = position.left - viewportPadding; + var rightEdgeOffset = position.left + viewportPadding + actualWidth; + if (leftEdgeOffset < viewportDimensions.left) { + delta.left = viewportDimensions.left - leftEdgeOffset; + } else if (rightEdgeOffset > viewportDimensions.right) { + delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset; + } + } + return delta; + } + function replaceArrow(delta, dimension, isHorizontal) { + var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]); + $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%').css(isHorizontal ? 'top' : 'left', ''); + } + function destroyTipElement() { + clearTimeout(timeout); + if ($tooltip.$isShown && tipElement !== null) { + if (options.autoClose) { + unbindAutoCloseEvents(); + } + if (options.keyboard) { + unbindKeyboardEvents(); + } + } + if (tipScope) { + tipScope.$destroy(); + tipScope = null; + } + if (tipElement) { + tipElement.remove(); + tipElement = $tooltip.$element = null; + } + } + return $tooltip; } function safeDigest(scope) { scope.$$phase || scope.$root && scope.$root.$$phase || scope.$digest(); @@ -2074,602 +926,106 @@ function findElement(query, element) { return angular.element((element || document).querySelectorAll(query)); } - return ModalFactory; + return TooltipFactory; } ]; - }).directive('bsModal', [ '$window', '$sce', '$modal', function($window, $sce, $modal) { + }).directive('bsTooltip', [ '$window', '$location', '$sce', '$parse', '$tooltip', '$$rAF', function($window, $location, $sce, $parse, $tooltip, $$rAF) { return { restrict: 'EAC', scope: true, link: function postLink(scope, element, attr, transclusion) { - var options = { - scope: scope, - element: element, - show: false - }; - angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'controller', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'id', 'prefixEvent', 'prefixClass' ], function(key) { - if (angular.isDefined(attr[key])) options[key] = attr[key]; - }); - var falseValueRegExp = /^(false|0|)$/i; - angular.forEach([ 'backdrop', 'keyboard', 'html', 'container' ], function(key) { - if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; - }); - angular.forEach([ 'title', 'content' ], function(key) { - attr[key] && attr.$observe(key, function(newValue, oldValue) { - scope[key] = $sce.trustAsHtml(newValue); - }); - }); - attr.bsModal && scope.$watch(attr.bsModal, function(newValue, oldValue) { - if (angular.isObject(newValue)) { - angular.extend(scope, newValue); - } else { - scope.content = newValue; - } - }, true); - var modal = $modal(options); - element.on(attr.trigger || 'click', modal.toggle); - scope.$on('$destroy', function() { - if (modal) modal.destroy(); - options = null; - modal = null; - }); - } - }; - } ]); - angular.module('mgcrea.ngStrap.navbar', []).provider('$navbar', function() { - var defaults = this.defaults = { - activeClass: 'active', - routeAttr: 'data-match-route', - strict: false - }; - this.$get = function() { - return { - defaults: defaults - }; - }; - }).directive('bsNavbar', [ '$window', '$location', '$navbar', function($window, $location, $navbar) { - var defaults = $navbar.defaults; - return { - restrict: 'A', - link: function postLink(scope, element, attr, controller) { - var options = angular.copy(defaults); - angular.forEach(Object.keys(defaults), function(key) { - if (angular.isDefined(attr[key])) options[key] = attr[key]; - }); - scope.$watch(function() { - return $location.path(); - }, function(newValue, oldValue) { - var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']'); - angular.forEach(liElements, function(li) { - var liElement = angular.element(li); - var pattern = liElement.attr(options.routeAttr).replace('/', '\\/'); - if (options.strict) { - pattern = '^' + pattern + '$'; - } - var regexp = new RegExp(pattern, 'i'); - if (regexp.test(newValue)) { - liElement.addClass(options.activeClass); - } else { - liElement.removeClass(options.activeClass); - } - }); - }); - } - }; - } ]); - angular.module('mgcrea.ngStrap.popover', [ 'mgcrea.ngStrap.tooltip' ]).provider('$popover', function() { - var defaults = this.defaults = { - animation: 'am-fade', - customClass: '', - container: false, - target: false, - placement: 'right', - templateUrl: 'popover/popover.tpl.html', - contentTemplate: false, - trigger: 'click', - keyboard: true, - html: false, - title: '', - content: '', - delay: 0, - autoClose: false - }; - this.$get = [ '$tooltip', function($tooltip) { - function PopoverFactory(element, config) { - var options = angular.extend({}, defaults, config); - var $popover = $tooltip(element, options); - if (options.content) { - $popover.$scope.content = options.content; - } - return $popover; - } - return PopoverFactory; - } ]; - }).directive('bsPopover', [ '$window', '$sce', '$popover', function($window, $sce, $popover) { - var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout; - return { - restrict: 'EAC', - scope: true, - link: function postLink(scope, element, attr) { + var tooltip; var options = { scope: scope }; - angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent' ], function(key) { + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'titleTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id' ], function(key) { if (angular.isDefined(attr[key])) options[key] = attr[key]; }); var falseValueRegExp = /^(false|0|)$/i; - angular.forEach([ 'html', 'container', 'autoClose' ], function(key) { - if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + angular.forEach([ 'html', 'container' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) { + options[key] = false; + } + }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } }); var dataTarget = element.attr('data-target'); if (angular.isDefined(dataTarget)) { - if (falseValueRegExp.test(dataTarget)) options.target = false; else options.target = dataTarget; - } - angular.forEach([ 'title', 'content' ], function(key) { - attr[key] && attr.$observe(key, function(newValue, oldValue) { - scope[key] = $sce.trustAsHtml(newValue); - angular.isDefined(oldValue) && requestAnimationFrame(function() { - popover && popover.$applyPlacement(); - }); - }); - }); - attr.bsPopover && scope.$watch(attr.bsPopover, function(newValue, oldValue) { - if (angular.isObject(newValue)) { - angular.extend(scope, newValue); + if (falseValueRegExp.test(dataTarget)) { + options.target = false; } else { - scope.content = newValue; + options.target = dataTarget; } - angular.isDefined(oldValue) && requestAnimationFrame(function() { - popover && popover.$applyPlacement(); - }); - }, true); - attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) { - if (!popover || !angular.isDefined(newValue)) return; - if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i); - newValue === true ? popover.show() : popover.hide(); - }); - attr.viewport && scope.$watch(attr.viewport, function(newValue) { - if (!popover || !angular.isDefined(newValue)) return; - popover.setViewport(newValue); - }); - var popover = $popover(element, options); - scope.$on('$destroy', function() { - if (popover) popover.destroy(); - options = null; - popover = null; - }); - } - }; - } ]); - angular.module('mgcrea.ngStrap.scrollspy', [ 'mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$scrollspy', function() { - var spies = this.$$spies = {}; - var defaults = this.defaults = { - debounce: 150, - throttle: 100, - offset: 100 - }; - this.$get = [ '$window', '$document', '$rootScope', 'dimensions', 'debounce', 'throttle', function($window, $document, $rootScope, dimensions, debounce, throttle) { - var windowEl = angular.element($window); - var docEl = angular.element($document.prop('documentElement')); - var bodyEl = angular.element($window.document.body); - function nodeName(element, name) { - return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase(); - } - function ScrollSpyFactory(config) { - var options = angular.extend({}, defaults, config); - if (!options.element) options.element = bodyEl; - var isWindowSpy = nodeName(options.element, 'body'); - var scrollEl = isWindowSpy ? windowEl : options.element; - var scrollId = isWindowSpy ? 'window' : options.id; - if (spies[scrollId]) { - spies[scrollId].$$count++; - return spies[scrollId]; } - var $scrollspy = {}; - var unbindViewContentLoaded, unbindIncludeContentLoaded; - var trackedElements = $scrollspy.$trackedElements = []; - var sortedElements = []; - var activeTarget; - var debouncedCheckPosition; - var throttledCheckPosition; - var debouncedCheckOffsets; - var viewportHeight; - var scrollTop; - $scrollspy.init = function() { - this.$$count = 1; - debouncedCheckPosition = debounce(this.checkPosition, options.debounce); - throttledCheckPosition = throttle(this.checkPosition, options.throttle); - scrollEl.on('click', this.checkPositionWithEventLoop); - windowEl.on('resize', debouncedCheckPosition); - scrollEl.on('scroll', throttledCheckPosition); - debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce); - unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets); - unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets); - debouncedCheckOffsets(); - if (scrollId) { - spies[scrollId] = $scrollspy; - } - }; - $scrollspy.destroy = function() { - this.$$count--; - if (this.$$count > 0) { - return; - } - scrollEl.off('click', this.checkPositionWithEventLoop); - windowEl.off('resize', debouncedCheckPosition); - scrollEl.off('scroll', throttledCheckPosition); - unbindViewContentLoaded(); - unbindIncludeContentLoaded(); - if (scrollId) { - delete spies[scrollId]; - } - }; - $scrollspy.checkPosition = function() { - if (!sortedElements.length) return; - scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0; - viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight')); - if (scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) { - return $scrollspy.$activateElement(sortedElements[0]); - } - for (var i = sortedElements.length; i--; ) { - if (angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue; - if (activeTarget === sortedElements[i].target) continue; - if (scrollTop < sortedElements[i].offsetTop) continue; - if (sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue; - return $scrollspy.$activateElement(sortedElements[i]); - } - }; - $scrollspy.checkPositionWithEventLoop = function() { - setTimeout($scrollspy.checkPosition, 1); - }; - $scrollspy.$activateElement = function(element) { - if (activeTarget) { - var activeElement = $scrollspy.$getTrackedElement(activeTarget); - if (activeElement) { - activeElement.source.removeClass('active'); - if (nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) { - activeElement.source.parent().parent().removeClass('active'); - } - } - } - activeTarget = element.target; - element.source.addClass('active'); - if (nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) { - element.source.parent().parent().addClass('active'); - } - }; - $scrollspy.$getTrackedElement = function(target) { - return trackedElements.filter(function(obj) { - return obj.target === target; - })[0]; - }; - $scrollspy.checkOffsets = function() { - angular.forEach(trackedElements, function(trackedElement) { - var targetElement = document.querySelector(trackedElement.target); - trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null; - if (options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1; - }); - sortedElements = trackedElements.filter(function(el) { - return el.offsetTop !== null; - }).sort(function(a, b) { - return a.offsetTop - b.offsetTop; - }); - debouncedCheckPosition(); - }; - $scrollspy.trackElement = function(target, source) { - trackedElements.push({ - target: target, - source: source - }); - }; - $scrollspy.untrackElement = function(target, source) { - var toDelete; - for (var i = trackedElements.length; i--; ) { - if (trackedElements[i].target === target && trackedElements[i].source === source) { - toDelete = i; - break; - } - } - trackedElements = trackedElements.splice(toDelete, 1); - }; - $scrollspy.activate = function(i) { - trackedElements[i].addClass('active'); - }; - $scrollspy.init(); - return $scrollspy; - } - return ScrollSpyFactory; - } ]; - }).directive('bsScrollspy', [ '$rootScope', 'debounce', 'dimensions', '$scrollspy', function($rootScope, debounce, dimensions, $scrollspy) { - return { - restrict: 'EAC', - link: function postLink(scope, element, attr) { - var options = { - scope: scope - }; - angular.forEach([ 'offset', 'target' ], function(key) { - if (angular.isDefined(attr[key])) options[key] = attr[key]; - }); - var scrollspy = $scrollspy(options); - scrollspy.trackElement(options.target, element); - scope.$on('$destroy', function() { - if (scrollspy) { - scrollspy.untrackElement(options.target, element); - scrollspy.destroy(); - } - options = null; - scrollspy = null; - }); - } - }; - } ]).directive('bsScrollspyList', [ '$rootScope', 'debounce', 'dimensions', '$scrollspy', function($rootScope, debounce, dimensions, $scrollspy) { - return { - restrict: 'A', - compile: function postLink(element, attr) { - var children = element[0].querySelectorAll('li > a[href]'); - angular.forEach(children, function(child) { - var childEl = angular.element(child); - childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href')); - }); - } - }; - } ]); - angular.module('mgcrea.ngStrap.select', [ 'mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions' ]).provider('$select', function() { - var defaults = this.defaults = { - animation: 'am-fade', - prefixClass: 'select', - prefixEvent: '$select', - placement: 'bottom-left', - templateUrl: 'select/select.tpl.html', - trigger: 'focus', - container: false, - keyboard: true, - html: false, - delay: 0, - multiple: false, - allNoneButtons: false, - sort: true, - caretHtml: ' ', - placeholder: 'Choose among the following...', - allText: 'All', - noneText: 'None', - maxLength: 3, - maxLengthHtml: 'selected', - iconCheckmark: 'glyphicon glyphicon-ok' - }; - this.$get = [ '$window', '$document', '$rootScope', '$tooltip', '$timeout', function($window, $document, $rootScope, $tooltip, $timeout) { - var bodyEl = angular.element($window.document.body); - var isNative = /(ip(a|o)d|iphone|android)/gi.test($window.navigator.userAgent); - var isTouch = 'createTouch' in $window.document && isNative; - function SelectFactory(element, controller, config) { - var $select = {}; - var options = angular.extend({}, defaults, config); - $select = $tooltip(element, options); - var scope = $select.$scope; - scope.$matches = []; - if (options.multiple) { - scope.$activeIndex = []; - } else { - scope.$activeIndex = -1; + if (!scope.hasOwnProperty('title')) { + scope.title = ''; } - scope.$isMultiple = options.multiple; - scope.$showAllNoneButtons = options.allNoneButtons && options.multiple; - scope.$iconCheckmark = options.iconCheckmark; - scope.$allText = options.allText; - scope.$noneText = options.noneText; - scope.$activate = function(index) { - scope.$$postDigest(function() { - $select.activate(index); - }); - }; - scope.$select = function(index, evt) { - scope.$$postDigest(function() { - $select.select(index); - }); - }; - scope.$isVisible = function() { - return $select.$isVisible(); - }; - scope.$isActive = function(index) { - return $select.$isActive(index); - }; - scope.$selectAll = function() { - for (var i = 0; i < scope.$matches.length; i++) { - if (!scope.$isActive(i)) { - scope.$select(i); - } - } - }; - scope.$selectNone = function() { - for (var i = 0; i < scope.$matches.length; i++) { - if (scope.$isActive(i)) { - scope.$select(i); - } - } - }; - $select.update = function(matches) { - scope.$matches = matches; - $select.$updateActiveIndex(); - }; - $select.activate = function(index) { - if (options.multiple) { - $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index); - if (options.sort) scope.$activeIndex.sort(function(a, b) { - return a - b; - }); - } else { - scope.$activeIndex = index; - } - return scope.$activeIndex; - }; - $select.select = function(index) { - var value = scope.$matches[index].value; - scope.$apply(function() { - $select.activate(index); - if (options.multiple) { - controller.$setViewValue(scope.$activeIndex.map(function(index) { - return scope.$matches[index].value; - })); - } else { - controller.$setViewValue(value); - $select.hide(); - } - }); - scope.$emit(options.prefixEvent + '.select', value, index, $select); - }; - $select.$updateActiveIndex = function() { - if (controller.$modelValue && scope.$matches.length) { - if (options.multiple && angular.isArray(controller.$modelValue)) { - scope.$activeIndex = controller.$modelValue.map(function(value) { - return $select.$getIndex(value); + attr.$observe('title', function(newValue) { + if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) { + var oldValue = scope.title; + scope.title = $sce.trustAsHtml(newValue); + if (angular.isDefined(oldValue)) { + $$rAF(function() { + if (tooltip) tooltip.$applyPlacement(); }); + } + } + }); + attr.$observe('disabled', function(newValue) { + if (newValue && tooltip.$isShown) { + tooltip.hide(); + } + }); + if (attr.bsTooltip) { + scope.$watch(attr.bsTooltip, function(newValue, oldValue) { + if (angular.isObject(newValue)) { + angular.extend(scope, newValue); } else { - scope.$activeIndex = $select.$getIndex(controller.$modelValue); + scope.title = newValue; } - } else if (scope.$activeIndex >= scope.$matches.length) { - scope.$activeIndex = options.multiple ? [] : 0; - } - }; - $select.$isVisible = function() { - if (!options.minLength || !controller) { - return scope.$matches.length; - } - return scope.$matches.length && controller.$viewValue.length >= options.minLength; - }; - $select.$isActive = function(index) { - if (options.multiple) { - return scope.$activeIndex.indexOf(index) !== -1; - } else { - return scope.$activeIndex === index; - } - }; - $select.$getIndex = function(value) { - var l = scope.$matches.length, i = l; - if (!l) return; - for (i = l; i--; ) { - if (scope.$matches[i].value === value) break; - } - if (i < 0) return; - return i; - }; - $select.$onMouseDown = function(evt) { - evt.preventDefault(); - evt.stopPropagation(); - if (isTouch) { - var targetEl = angular.element(evt.target); - targetEl.triggerHandler('click'); - } - }; - $select.$onKeyDown = function(evt) { - if (!/(9|13|38|40)/.test(evt.keyCode)) return; - evt.preventDefault(); - evt.stopPropagation(); - if (options.multiple && evt.keyCode === 9) { - return $select.hide(); - } - if (!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) { - return $select.select(scope.$activeIndex); - } - if (!options.multiple) { - if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--; else if (evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1; else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++; else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0; - scope.$digest(); - } - }; - var _show = $select.show; - $select.show = function() { - _show(); - if (options.multiple) { - $select.$element.addClass('select-multiple'); - } - $timeout(function() { - $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown); - if (options.keyboard) { - element.on('keydown', $select.$onKeyDown); + if (angular.isDefined(oldValue)) { + $$rAF(function() { + if (tooltip) tooltip.$applyPlacement(); + }); } - }, 0, false); - }; - var _hide = $select.hide; - $select.hide = function() { - if (!options.multiple && !controller.$modelValue) { - scope.$activeIndex = -1; - } - $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown); - if (options.keyboard) { - element.off('keydown', $select.$onKeyDown); - } - _hide(true); - }; - return $select; - } - SelectFactory.defaults = defaults; - return SelectFactory; - } ]; - }).directive('bsSelect', [ '$window', '$parse', '$q', '$select', '$parseOptions', function($window, $parse, $q, $select, $parseOptions) { - var defaults = $select.defaults; - return { - restrict: 'EAC', - require: 'ngModel', - link: function postLink(scope, element, attr, controller) { - var options = { - scope: scope, - placeholder: defaults.placeholder - }; - angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent' ], function(key) { - if (angular.isDefined(attr[key])) options[key] = attr[key]; - }); - var falseValueRegExp = /^(false|0|)$/i; - angular.forEach([ 'html', 'container', 'allNoneButtons', 'sort' ], function(key) { - if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; - }); - var dataMultiple = element.attr('data-multiple'); - if (angular.isDefined(dataMultiple)) { - if (falseValueRegExp.test(dataMultiple)) options.multiple = false; else options.multiple = dataMultiple; + }, true); } - if (element[0].nodeName.toLowerCase() === 'select') { - var inputEl = element; - inputEl.css('display', 'none'); - element = angular.element(''); - inputEl.after(element); - } - var parsedOptions = $parseOptions(attr.bsOptions); - var select = $select(element, controller, options); - var watchedOptions = parsedOptions.$match[7].replace(/\|.+/, '').trim(); - scope.$watchCollection(watchedOptions, function(newValue, oldValue) { - parsedOptions.valuesFn(scope, controller).then(function(values) { - select.update(values); - controller.$render(); + if (attr.bsShow) { + scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!tooltip || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i); + if (newValue === true) { + tooltip.show(); + } else { + tooltip.hide(); + } }); - }); - scope.$watch(attr.ngModel, function(newValue, oldValue) { - select.$updateActiveIndex(); - controller.$render(); - }, true); - controller.$render = function() { - var selected, index; - if (options.multiple && angular.isArray(controller.$modelValue)) { - selected = controller.$modelValue.map(function(value) { - index = select.$getIndex(value); - return angular.isDefined(index) ? select.$scope.$matches[index].label : false; - }).filter(angular.isDefined); - if (selected.length > (options.maxLength || defaults.maxLength)) { - selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml); - } else { - selected = selected.join(', '); - } - } else { - index = select.$getIndex(controller.$modelValue); - selected = angular.isDefined(index) ? select.$scope.$matches[index].label : false; - } - element.html((selected ? selected : options.placeholder) + (options.caretHtml ? options.caretHtml : defaults.caretHtml)); - }; - if (options.multiple) { - controller.$isEmpty = function(value) { - return !value || value.length === 0; - }; } + if (attr.bsEnabled) { + scope.$watch(attr.bsEnabled, function(newValue, oldValue) { + if (!tooltip || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i); + if (newValue === false) { + tooltip.setEnabled(false); + } else { + tooltip.setEnabled(true); + } + }); + } + if (attr.viewport) { + scope.$watch(attr.viewport, function(newValue) { + if (!tooltip || !angular.isDefined(newValue)) return; + tooltip.setViewport(newValue); + }); + } + tooltip = $tooltip(element, options); scope.$on('$destroy', function() { - if (select) select.destroy(); + if (tooltip) tooltip.destroy(); options = null; - select = null; + tooltip = null; }); } }; @@ -2677,6 +1033,7 @@ angular.module('mgcrea.ngStrap.timepicker', [ 'mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip' ]).provider('$timepicker', function() { var defaults = this.defaults = { animation: 'am-fade', + defaultDate: 'auto', prefixClass: 'timepicker', placement: 'bottom-left', templateUrl: 'timepicker/timepicker.tpl.html', @@ -2703,7 +1060,7 @@ arrowBehavior: 'pager' }; this.$get = [ '$window', '$document', '$rootScope', '$sce', '$dateFormatter', '$tooltip', '$timeout', function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) { - var isNative = /(ip(a|o)d|iphone|android)/gi.test($window.navigator.userAgent); + var isNative = /(ip[ao]d|iphone|android)/gi.test($window.navigator.userAgent); var isTouch = 'createTouch' in $window.document && isNative; if (!defaults.lang) { defaults.lang = $dateFormatter.getDefaultLocale(); @@ -2732,7 +1089,12 @@ millisecond: startDate.getMilliseconds() }; var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang); - var hoursFormat = $dateFormatter.hoursFormat(format), timeSeparator = $dateFormatter.timeSeparator(format), minutesFormat = $dateFormatter.minutesFormat(format), secondsFormat = $dateFormatter.secondsFormat(format), showSeconds = $dateFormatter.showSeconds(format), showAM = $dateFormatter.showAM(format); + var hoursFormat = $dateFormatter.hoursFormat(format); + var timeSeparator = $dateFormatter.timeSeparator(format); + var minutesFormat = $dateFormatter.minutesFormat(format); + var secondsFormat = $dateFormatter.secondsFormat(format); + var showSeconds = $dateFormatter.showSeconds(format); + var showAM = $dateFormatter.showAM(format); scope.$iconUp = options.iconUp; scope.$iconDown = options.iconDown; scope.$select = function(date, index) { @@ -2759,7 +1121,9 @@ } }; $timepicker.select = function(date, index, keep) { - if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1); + if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) { + controller.$dateValue = options.defaultDate === 'today' ? new Date() : new Date(1970, 0, 1); + } if (!angular.isDate(date)) date = new Date(date); if (index === 0) controller.$dateValue.setHours(date.getHours()); else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes()); else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds()); controller.$setViewValue(angular.copy(controller.$dateValue)); @@ -2780,8 +1144,10 @@ controller.$render(); }; $timepicker.$build = function() { - var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10); - var hours = [], hour; + var i; + var midIndex = scope.midIndex = parseInt(options.length / 2, 10); + var hours = []; + var hour; for (i = 0; i < options.length; i++) { hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep); hours.push({ @@ -2791,7 +1157,8 @@ disabled: $timepicker.$isDisabled(hour, 0) }); } - var minutes = [], minute; + var minutes = []; + var minute; for (i = 0; i < options.length; i++) { minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep); minutes.push({ @@ -2801,7 +1168,8 @@ disabled: $timepicker.$isDisabled(minute, 1) }); } - var seconds = [], second; + var seconds = []; + var second; for (i = 0; i < options.length; i++) { second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep); seconds.push({ @@ -2907,9 +1275,12 @@ return; } var newDate = new Date($timepicker.$date); - var hours = newDate.getHours(), hoursLength = formatDate(newDate, hoursFormat).length; - var minutes = newDate.getMinutes(), minutesLength = formatDate(newDate, minutesFormat).length; - var seconds = newDate.getSeconds(), secondsLength = formatDate(newDate, secondsFormat).length; + var hours = newDate.getHours(); + var hoursLength = formatDate(newDate, hoursFormat).length; + var minutes = newDate.getMinutes(); + var minutesLength = formatDate(newDate, minutesFormat).length; + var seconds = newDate.getSeconds(); + var secondsLength = formatDate(newDate, secondsFormat).length; var sepLength = 1; var lateralMove = /(37|39)/.test(evt.keyCode); var count = 2 + showSeconds * 1 + showAM * 1; @@ -2985,18 +1356,18 @@ if (!isTouch && element.attr('readonly') || element.attr('disabled')) return; _show(); $timeout(function() { - $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown); + if ($timepicker.$element) $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown); if (options.keyboard) { - element && element.on('keydown', $timepicker.$onKeyDown); + if (element) element.on('keydown', $timepicker.$onKeyDown); } }, 0, false); }; var _hide = $timepicker.hide; $timepicker.hide = function(blur) { if (!$timepicker.$isShown) return; - $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown); + if ($timepicker.$element) $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown); if (options.keyboard) { - element && element.off('keydown', $timepicker.$onKeyDown); + if (element) element.off('keydown', $timepicker.$onKeyDown); } _hide(blur); }; @@ -3007,7 +1378,7 @@ } ]; }).directive('bsTimepicker', [ '$window', '$parse', '$q', '$dateFormatter', '$dateParser', '$timepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) { var defaults = $timepicker.defaults; - var isNative = /(ip(a|o)d|iphone|android)/gi.test($window.navigator.userAgent); + var isNative = /(ip[ao]d|iphone|android)/gi.test($window.navigator.userAgent); return { restrict: 'EAC', require: 'ngModel', @@ -3015,17 +1386,20 @@ var options = { scope: scope }; - angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent' ], function(key) { + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent', 'defaultDate' ], function(key) { if (angular.isDefined(attr[key])) options[key] = attr[key]; }); var falseValueRegExp = /^(false|0|)$/i; angular.forEach([ 'html', 'container', 'autoclose', 'useNative', 'roundDisplay' ], function(key) { - if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) { + options[key] = false; + } }); - attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) { - if (!timepicker || !angular.isDefined(newValue)) return; - if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i); - newValue === true ? timepicker.show() : timepicker.hide(); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } }); if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm'; var timepicker = $timepicker(element, controller, options); @@ -3034,16 +1408,29 @@ var formatDate = function(date, format, timezone) { return $dateFormatter.formatDate(date, format, lang, timezone); }; + if (attr.bsShow) { + scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!timepicker || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i); + if (newValue === true) { + timepicker.show(); + } else { + timepicker.hide(); + } + }); + } var dateParser = $dateParser({ format: options.timeFormat, lang: lang }); angular.forEach([ 'minTime', 'maxTime' ], function(key) { - angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) { - timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue); - !isNaN(timepicker.$options[key]) && timepicker.$build(); - validateAgainstMinMaxTime(controller.$dateValue); - }); + if (angular.isDefined(attr[key])) { + attr.$observe(key, function(newValue) { + timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue); + if (!isNaN(timepicker.$options[key])) timepicker.$build(); + validateAgainstMinMaxTime(controller.$dateValue); + }); + } }); scope.$watch(attr.ngModel, function(newValue, oldValue) { timepicker.update(controller.$dateValue); @@ -3071,9 +1458,8 @@ if (!parsedTime || isNaN(parsedTime.getTime())) { controller.$setValidity('date', false); return undefined; - } else { - validateAgainstMinMaxTime(parsedTime); } + validateAgainstMinMaxTime(parsedTime); if (options.timeType === 'string') { date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true); return formatDate(date, options.modelTimeFormat || options.timeFormat); @@ -3085,9 +1471,8 @@ return date.getTime() / 1e3; } else if (options.timeType === 'iso') { return date.toISOString(); - } else { - return new Date(date); } + return new Date(date); }); controller.$formatters.push(function(modelValue) { var date; @@ -3119,834 +1504,902 @@ } }; } ]); - angular.module('mgcrea.ngStrap.tab', []).provider('$tab', function() { + angular.module('mgcrea.ngStrap.scrollspy', [ 'mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$scrollspy', function() { + var spies = this.$$spies = {}; var defaults = this.defaults = { - animation: 'am-fade', - template: 'tab/tab.tpl.html', - navClass: 'nav-tabs', - activeClass: 'active' + debounce: 150, + throttle: 100, + offset: 100 }; - var controller = this.controller = function($scope, $element, $attrs) { - var self = this; - self.$options = angular.copy(defaults); - angular.forEach([ 'animation', 'navClass', 'activeClass' ], function(key) { - if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key]; - }); - $scope.$navClass = self.$options.navClass; - $scope.$activeClass = self.$options.activeClass; - self.$panes = $scope.$panes = []; - self.$activePaneChangeListeners = self.$viewChangeListeners = []; - self.$push = function(pane) { - if (angular.isUndefined(self.$panes.$active)) { - $scope.$setActive(pane.name || 0); + this.$get = [ '$window', '$document', '$rootScope', 'dimensions', 'debounce', 'throttle', function($window, $document, $rootScope, dimensions, debounce, throttle) { + var windowEl = angular.element($window); + var docEl = angular.element($document.prop('documentElement')); + var bodyEl = angular.element($window.document.body); + function nodeName(element, name) { + return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase(); + } + function ScrollSpyFactory(config) { + var options = angular.extend({}, defaults, config); + if (!options.element) options.element = bodyEl; + var isWindowSpy = nodeName(options.element, 'body'); + var scrollEl = isWindowSpy ? windowEl : options.element; + var scrollId = isWindowSpy ? 'window' : options.id; + if (spies[scrollId]) { + spies[scrollId].$$count++; + return spies[scrollId]; } - self.$panes.push(pane); - }; - self.$remove = function(pane) { - var index = self.$panes.indexOf(pane); - var active = self.$panes.$active; - var activeIndex; - if (angular.isString(active)) { - activeIndex = self.$panes.map(function(pane) { - return pane.name; - }).indexOf(active); - } else { - activeIndex = self.$panes.$active; - } - self.$panes.splice(index, 1); - if (index < activeIndex) { - activeIndex--; - } else if (index === activeIndex && activeIndex === self.$panes.length) { - activeIndex--; - } - if (activeIndex >= 0 && activeIndex < self.$panes.length) { - self.$setActive(self.$panes[activeIndex].name || activeIndex); - } else { - self.$setActive(); - } - }; - self.$setActive = $scope.$setActive = function(value) { - self.$panes.$active = value; - self.$activePaneChangeListeners.forEach(function(fn) { - fn(); - }); - }; - self.$isActive = $scope.$isActive = function($pane, $index) { - return self.$panes.$active === $pane.name || self.$panes.$active === $index; - }; - }; - this.$get = function() { - var $tab = {}; - $tab.defaults = defaults; - $tab.controller = controller; - return $tab; - }; - }).directive('bsTabs', [ '$window', '$animate', '$tab', '$parse', function($window, $animate, $tab, $parse) { - var defaults = $tab.defaults; + var $scrollspy = {}; + var unbindViewContentLoaded; + var unbindIncludeContentLoaded; + var trackedElements = $scrollspy.$trackedElements = []; + var sortedElements = []; + var activeTarget; + var debouncedCheckPosition; + var throttledCheckPosition; + var debouncedCheckOffsets; + var viewportHeight; + var scrollTop; + $scrollspy.init = function() { + this.$$count = 1; + debouncedCheckPosition = debounce(this.checkPosition, options.debounce); + throttledCheckPosition = throttle(this.checkPosition, options.throttle); + scrollEl.on('click', this.checkPositionWithEventLoop); + windowEl.on('resize', debouncedCheckPosition); + scrollEl.on('scroll', throttledCheckPosition); + debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce); + unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets); + unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets); + debouncedCheckOffsets(); + if (scrollId) { + spies[scrollId] = $scrollspy; + } + }; + $scrollspy.destroy = function() { + this.$$count--; + if (this.$$count > 0) { + return; + } + scrollEl.off('click', this.checkPositionWithEventLoop); + windowEl.off('resize', debouncedCheckPosition); + scrollEl.off('scroll', throttledCheckPosition); + unbindViewContentLoaded(); + unbindIncludeContentLoaded(); + if (scrollId) { + delete spies[scrollId]; + } + }; + $scrollspy.checkPosition = function() { + if (!sortedElements.length) return; + scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0; + viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight')); + if (scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) { + return $scrollspy.$activateElement(sortedElements[0]); + } + for (var i = sortedElements.length; i--; ) { + if (angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue; + if (activeTarget === sortedElements[i].target) continue; + if (scrollTop < sortedElements[i].offsetTop) continue; + if (sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue; + return $scrollspy.$activateElement(sortedElements[i]); + } + }; + $scrollspy.checkPositionWithEventLoop = function() { + setTimeout($scrollspy.checkPosition, 1); + }; + $scrollspy.$activateElement = function(element) { + if (activeTarget) { + var activeElement = $scrollspy.$getTrackedElement(activeTarget); + if (activeElement) { + activeElement.source.removeClass('active'); + if (nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) { + activeElement.source.parent().parent().removeClass('active'); + } + } + } + activeTarget = element.target; + element.source.addClass('active'); + if (nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) { + element.source.parent().parent().addClass('active'); + } + }; + $scrollspy.$getTrackedElement = function(target) { + return trackedElements.filter(function(obj) { + return obj.target === target; + })[0]; + }; + $scrollspy.checkOffsets = function() { + angular.forEach(trackedElements, function(trackedElement) { + var targetElement = document.querySelector(trackedElement.target); + trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null; + if (options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1; + }); + sortedElements = trackedElements.filter(function(el) { + return el.offsetTop !== null; + }).sort(function(a, b) { + return a.offsetTop - b.offsetTop; + }); + debouncedCheckPosition(); + }; + $scrollspy.trackElement = function(target, source) { + trackedElements.push({ + target: target, + source: source + }); + }; + $scrollspy.untrackElement = function(target, source) { + var toDelete; + for (var i = trackedElements.length; i--; ) { + if (trackedElements[i].target === target && trackedElements[i].source === source) { + toDelete = i; + break; + } + } + trackedElements.splice(toDelete, 1); + }; + $scrollspy.activate = function(i) { + trackedElements[i].addClass('active'); + }; + $scrollspy.init(); + return $scrollspy; + } + return ScrollSpyFactory; + } ]; + }).directive('bsScrollspy', [ '$rootScope', 'debounce', 'dimensions', '$scrollspy', function($rootScope, debounce, dimensions, $scrollspy) { return { - require: [ '?ngModel', 'bsTabs' ], - transclude: true, - scope: true, - controller: [ '$scope', '$element', '$attrs', $tab.controller ], - templateUrl: function(element, attr) { - return attr.template || defaults.template; - }, - link: function postLink(scope, element, attrs, controllers) { - var ngModelCtrl = controllers[0]; - var bsTabsCtrl = controllers[1]; - if (ngModelCtrl) { - bsTabsCtrl.$activePaneChangeListeners.push(function() { - ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active); - }); - ngModelCtrl.$formatters.push(function(modelValue) { - bsTabsCtrl.$setActive(modelValue); - return modelValue; - }); - } - if (attrs.bsActivePane) { - var parsedBsActivePane = $parse(attrs.bsActivePane); - bsTabsCtrl.$activePaneChangeListeners.push(function() { - parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active); - }); - scope.$watch(attrs.bsActivePane, function(newValue, oldValue) { - bsTabsCtrl.$setActive(newValue); - }, true); - } + restrict: 'EAC', + link: function postLink(scope, element, attr) { + var options = { + scope: scope + }; + angular.forEach([ 'offset', 'target' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var scrollspy = $scrollspy(options); + scrollspy.trackElement(options.target, element); + scope.$on('$destroy', function() { + if (scrollspy) { + scrollspy.untrackElement(options.target, element); + scrollspy.destroy(); + } + options = null; + scrollspy = null; + }); } }; - } ]).directive('bsPane', [ '$window', '$animate', '$sce', function($window, $animate, $sce) { + } ]).directive('bsScrollspyList', [ '$rootScope', 'debounce', 'dimensions', '$scrollspy', function($rootScope, debounce, dimensions, $scrollspy) { return { - require: [ '^?ngModel', '^bsTabs' ], - scope: true, - link: function postLink(scope, element, attrs, controllers) { - var ngModelCtrl = controllers[0]; - var bsTabsCtrl = controllers[1]; - element.addClass('tab-pane'); - attrs.$observe('title', function(newValue, oldValue) { - scope.title = $sce.trustAsHtml(newValue); + restrict: 'A', + compile: function postLink(element, attr) { + var children = element[0].querySelectorAll('li > a[href]'); + angular.forEach(children, function(child) { + var childEl = angular.element(child); + childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href')); }); - scope.name = attrs.name; - if (bsTabsCtrl.$options.animation) { - element.addClass(bsTabsCtrl.$options.animation); - } - attrs.$observe('disabled', function(newValue, oldValue) { - scope.disabled = scope.$eval(newValue); - }); - bsTabsCtrl.$push(scope); - scope.$on('$destroy', function() { - bsTabsCtrl.$remove(scope); - }); - function render() { - var index = bsTabsCtrl.$panes.indexOf(scope); - $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass); - } - bsTabsCtrl.$activePaneChangeListeners.push(function() { - render(); - }); - render(); } }; } ]); - angular.module('mgcrea.ngStrap.typeahead', [ 'mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions' ]).provider('$typeahead', function() { + angular.module('mgcrea.ngStrap.select', [ 'mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions' ]).provider('$select', function() { var defaults = this.defaults = { animation: 'am-fade', - prefixClass: 'typeahead', - prefixEvent: '$typeahead', + prefixClass: 'select', + prefixEvent: '$select', placement: 'bottom-left', - templateUrl: 'typeahead/typeahead.tpl.html', + templateUrl: 'select/select.tpl.html', trigger: 'focus', container: false, keyboard: true, html: false, delay: 0, - minLength: 1, - filter: 'bsAsyncFilter', - limit: 6, - autoSelect: false, - comparator: '', - trimValue: true + multiple: false, + allNoneButtons: false, + sort: true, + caretHtml: ' ', + placeholder: 'Choose among the following...', + allText: 'All', + noneText: 'None', + maxLength: 3, + maxLengthHtml: 'selected', + iconCheckmark: 'glyphicon glyphicon-ok', + toggle: false }; - this.$get = [ '$window', '$rootScope', '$tooltip', '$$rAF', '$timeout', function($window, $rootScope, $tooltip, $$rAF, $timeout) { - var bodyEl = angular.element($window.document.body); - function TypeaheadFactory(element, controller, config) { - var $typeahead = {}; + this.$get = [ '$window', '$document', '$rootScope', '$tooltip', '$timeout', function($window, $document, $rootScope, $tooltip, $timeout) { + var isNative = /(ip[ao]d|iphone|android)/gi.test($window.navigator.userAgent); + var isTouch = 'createTouch' in $window.document && isNative; + function SelectFactory(element, controller, config) { + var $select = {}; var options = angular.extend({}, defaults, config); - $typeahead = $tooltip(element, options); - var parentScope = config.scope; - var scope = $typeahead.$scope; - scope.$resetMatches = function() { - scope.$matches = []; - scope.$activeIndex = options.autoSelect ? 0 : -1; - }; - scope.$resetMatches(); + $select = $tooltip(element, options); + var scope = $select.$scope; + scope.$matches = []; + if (options.multiple) { + scope.$activeIndex = []; + } else { + scope.$activeIndex = -1; + } + scope.$isMultiple = options.multiple; + scope.$showAllNoneButtons = options.allNoneButtons && options.multiple; + scope.$iconCheckmark = options.iconCheckmark; + scope.$allText = options.allText; + scope.$noneText = options.noneText; scope.$activate = function(index) { scope.$$postDigest(function() { - $typeahead.activate(index); + $select.activate(index); }); }; scope.$select = function(index, evt) { scope.$$postDigest(function() { - $typeahead.select(index); + $select.select(index); }); }; scope.$isVisible = function() { - return $typeahead.$isVisible(); + return $select.$isVisible(); }; - $typeahead.update = function(matches) { + scope.$isActive = function(index) { + return $select.$isActive(index); + }; + scope.$selectAll = function() { + for (var i = 0; i < scope.$matches.length; i++) { + if (!scope.$isActive(i)) { + scope.$select(i); + } + } + }; + scope.$selectNone = function() { + for (var i = 0; i < scope.$matches.length; i++) { + if (scope.$isActive(i)) { + scope.$select(i); + } + } + }; + $select.update = function(matches) { scope.$matches = matches; - if (scope.$activeIndex >= matches.length) { - scope.$activeIndex = options.autoSelect ? 0 : -1; + $select.$updateActiveIndex(); + }; + $select.activate = function(index) { + if (options.multiple) { + if ($select.$isActive(index)) { + scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1); + } else { + scope.$activeIndex.push(index); + } + if (options.sort) scope.$activeIndex.sort(function(a, b) { + return a - b; + }); + } else { + scope.$activeIndex = index; } - safeDigest(scope); - $$rAF($typeahead.$applyPlacement); + return scope.$activeIndex; }; - $typeahead.activate = function(index) { - scope.$activeIndex = index; - }; - $typeahead.select = function(index) { - if (index === -1) return; + $select.select = function(index) { + if (angular.isUndefined(index) || index < 0 || index >= scope.$matches.length) { + return; + } var value = scope.$matches[index].value; - controller.$setViewValue(value); - controller.$render(); - scope.$resetMatches(); - if (parentScope) parentScope.$digest(); - scope.$emit(options.prefixEvent + '.select', value, index, $typeahead); + scope.$apply(function() { + $select.activate(index); + if (options.multiple) { + controller.$setViewValue(scope.$activeIndex.map(function(index) { + if (angular.isUndefined(scope.$matches[index])) { + return null; + } + return scope.$matches[index].value; + })); + } else { + if (options.toggle) { + controller.$setViewValue(value === controller.$modelValue ? undefined : value); + } else { + controller.$setViewValue(value); + } + $select.hide(); + } + }); + scope.$emit(options.prefixEvent + '.select', value, index, $select); + if (angular.isDefined(options.onSelect) && angular.isFunction(options.onSelect)) { + options.onSelect(value, index, $select); + } }; - $typeahead.$isVisible = function() { + $select.$updateActiveIndex = function() { + if (options.multiple) { + if (angular.isArray(controller.$modelValue)) { + scope.$activeIndex = controller.$modelValue.map(function(value) { + return $select.$getIndex(value); + }); + } else { + scope.$activeIndex = []; + } + } else { + if (angular.isDefined(controller.$modelValue) && scope.$matches.length) { + scope.$activeIndex = $select.$getIndex(controller.$modelValue); + } else { + scope.$activeIndex = -1; + } + } + }; + $select.$isVisible = function() { if (!options.minLength || !controller) { - return !!scope.$matches.length; + return scope.$matches.length; } - return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength; + return scope.$matches.length && controller.$viewValue.length >= options.minLength; }; - $typeahead.$getIndex = function(value) { - var l = scope.$matches.length, i = l; - if (!l) return; - for (i = l; i--; ) { - if (scope.$matches[i].value === value) break; + $select.$isActive = function(index) { + if (options.multiple) { + return scope.$activeIndex.indexOf(index) !== -1; } - if (i < 0) return; - return i; + return scope.$activeIndex === index; }; - $typeahead.$onMouseDown = function(evt) { + $select.$getIndex = function(value) { + var index; + for (index = scope.$matches.length; index--; ) { + if (angular.equals(scope.$matches[index].value, value)) break; + } + return index; + }; + $select.$onMouseDown = function(evt) { evt.preventDefault(); evt.stopPropagation(); + if (isTouch) { + var targetEl = angular.element(evt.target); + targetEl.triggerHandler('click'); + } }; - $typeahead.$onKeyDown = function(evt) { - if (!/(38|40|13)/.test(evt.keyCode)) return; - if ($typeahead.$isVisible() && !(evt.keyCode === 13 && scope.$activeIndex === -1)) { + $select.$onKeyDown = function(evt) { + if (!/(9|13|38|40)/.test(evt.keyCode)) return; + if (evt.keyCode !== 9) { evt.preventDefault(); evt.stopPropagation(); } - if (evt.keyCode === 13 && scope.$matches.length) { - $typeahead.select(scope.$activeIndex); - } else if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--; else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++; else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0; - scope.$digest(); + if (options.multiple && evt.keyCode === 9) { + return $select.hide(); + } + if (!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) { + return $select.select(scope.$activeIndex); + } + if (!options.multiple) { + if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--; else if (evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1; else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++; else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0; + scope.$digest(); + } }; - var show = $typeahead.show; - $typeahead.show = function() { - show(); + $select.$isIE = function() { + var ua = $window.navigator.userAgent; + return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0; + }; + $select.$selectScrollFix = function(e) { + if ($document[0].activeElement.tagName === 'UL') { + e.preventDefault(); + e.stopImmediatePropagation(); + e.target.focus(); + } + }; + var _show = $select.show; + $select.show = function() { + _show(); + if (options.multiple) { + $select.$element.addClass('select-multiple'); + } $timeout(function() { - $typeahead.$element && $typeahead.$element.on('mousedown', $typeahead.$onMouseDown); + $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown); if (options.keyboard) { - element && element.on('keydown', $typeahead.$onKeyDown); + element.on('keydown', $select.$onKeyDown); } }, 0, false); }; - var hide = $typeahead.hide; - $typeahead.hide = function() { - $typeahead.$element && $typeahead.$element.off('mousedown', $typeahead.$onMouseDown); - if (options.keyboard) { - element && element.off('keydown', $typeahead.$onKeyDown); + var _hide = $select.hide; + $select.hide = function() { + if (!options.multiple && angular.isUndefined(controller.$modelValue)) { + scope.$activeIndex = -1; } - if (!options.autoSelect) $typeahead.activate(-1); - hide(); + $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown); + if (options.keyboard) { + element.off('keydown', $select.$onKeyDown); + } + _hide(true); }; - return $typeahead; + return $select; } - function safeDigest(scope) { - scope.$$phase || scope.$root && scope.$root.$$phase || scope.$digest(); - } - TypeaheadFactory.defaults = defaults; - return TypeaheadFactory; + SelectFactory.defaults = defaults; + return SelectFactory; } ]; - }).filter('bsAsyncFilter', [ '$filter', function($filter) { - return function(array, expression, comparator) { - if (array && angular.isFunction(array.then)) { - return array.then(function(results) { - return $filter('filter')(results, expression, comparator); - }); - } else { - return $filter('filter')(array, expression, comparator); - } - }; - } ]).directive('bsTypeahead', [ '$window', '$parse', '$q', '$typeahead', '$parseOptions', function($window, $parse, $q, $typeahead, $parseOptions) { - var defaults = $typeahead.defaults; + }).directive('bsSelect', [ '$window', '$parse', '$q', '$select', '$parseOptions', function($window, $parse, $q, $select, $parseOptions) { + var defaults = $select.defaults; return { restrict: 'EAC', require: 'ngModel', link: function postLink(scope, element, attr, controller) { var options = { - scope: scope + scope: scope, + placeholder: defaults.placeholder }; - angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass' ], function(key) { + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent', 'toggle' ], function(key) { if (angular.isDefined(attr[key])) options[key] = attr[key]; }); var falseValueRegExp = /^(false|0|)$/i; - angular.forEach([ 'html', 'container', 'trimValue' ], function(key) { - if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + angular.forEach([ 'html', 'container', 'allNoneButtons', 'sort' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) { + options[key] = false; + } }); - element.attr('autocomplete', 'false'); - var filter = options.filter || defaults.filter; - var limit = options.limit || defaults.limit; - var comparator = options.comparator || defaults.comparator; - var bsOptions = attr.bsOptions; - if (filter) bsOptions += ' | ' + filter + ':$viewValue'; - if (comparator) bsOptions += ':' + comparator; - if (limit) bsOptions += ' | limitTo:' + limit; - var parsedOptions = $parseOptions(bsOptions); - var typeahead = $typeahead(element, controller, options); - if (options.watchOptions) { - var watchedOptions = parsedOptions.$match[7].replace(/\|.+/, '').replace(/\(.*\)/g, '').trim(); - scope.$watchCollection(watchedOptions, function(newValue, oldValue) { - parsedOptions.valuesFn(scope, controller).then(function(values) { - typeahead.update(values); - controller.$render(); - }); - }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide', 'onSelect' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + var dataMultiple = element.attr('data-multiple'); + if (angular.isDefined(dataMultiple)) { + if (falseValueRegExp.test(dataMultiple)) { + options.multiple = false; + } else { + options.multiple = dataMultiple; + } } - scope.$watch(attr.ngModel, function(newValue, oldValue) { - scope.$modelValue = newValue; + if (element[0].nodeName.toLowerCase() === 'select') { + var inputEl = element; + inputEl.css('display', 'none'); + element = angular.element(''); + inputEl.after(element); + } + var parsedOptions = $parseOptions(attr.bsOptions); + var select = $select(element, controller, options); + if (select.$isIE()) { + element[0].addEventListener('blur', select.$selectScrollFix); + } + var watchedOptions = parsedOptions.$match[7].replace(/\|.+/, '').trim(); + scope.$watch(watchedOptions, function(newValue, oldValue) { parsedOptions.valuesFn(scope, controller).then(function(values) { - if (options.selectMode && !values.length && newValue.length > 0) { - controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1)); - return; - } - if (values.length > limit) values = values.slice(0, limit); - var isVisible = typeahead.$isVisible(); - isVisible && typeahead.update(values); - if (values.length === 1 && values[0].value === newValue) return; - !isVisible && typeahead.update(values); + select.update(values); controller.$render(); }); - }); - controller.$formatters.push(function(modelValue) { - var displayValue = parsedOptions.displayValue(modelValue); - if (displayValue) { - return displayValue; - } - if (modelValue && typeof modelValue !== 'object') { - return modelValue; - } - return ''; - }); + }, true); + scope.$watch(attr.ngModel, function(newValue, oldValue) { + select.$updateActiveIndex(); + controller.$render(); + }, true); controller.$render = function() { - if (controller.$isEmpty(controller.$viewValue)) { - return element.val(''); + var selected; + var index; + if (options.multiple && angular.isArray(controller.$modelValue)) { + selected = controller.$modelValue.map(function(value) { + index = select.$getIndex(value); + return index !== -1 ? select.$scope.$matches[index].label : false; + }).filter(angular.isDefined); + if (selected.length > (options.maxLength || defaults.maxLength)) { + selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml); + } else { + selected = selected.join(', '); + } + } else { + index = select.$getIndex(controller.$modelValue); + selected = index !== -1 ? select.$scope.$matches[index].label : false; } - var index = typeahead.$getIndex(controller.$modelValue); - var selected = angular.isDefined(index) ? typeahead.$scope.$matches[index].label : controller.$viewValue; - selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected; - var value = selected ? selected.toString().replace(/<(?:.|\n)*?>/gm, '') : ''; - element.val(options.trimValue === false ? value : value.trim()); + element.html((selected || options.placeholder) + (options.caretHtml || defaults.caretHtml)); }; + if (options.multiple) { + controller.$isEmpty = function(value) { + return !value || value.length === 0; + }; + } scope.$on('$destroy', function() { - if (typeahead) typeahead.destroy(); + if (select) select.destroy(); options = null; - typeahead = null; + select = null; }); } }; } ]); - angular.module('mgcrea.ngStrap.tooltip', [ 'mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$tooltip', function() { + angular.module('mgcrea.ngStrap.popover', [ 'mgcrea.ngStrap.tooltip' ]).provider('$popover', function() { var defaults = this.defaults = { animation: 'am-fade', customClass: '', - prefixClass: 'tooltip', - prefixEvent: 'tooltip', container: false, target: false, - placement: 'top', - templateUrl: 'tooltip/tooltip.tpl.html', - template: '', + placement: 'right', + templateUrl: 'popover/popover.tpl.html', contentTemplate: false, - trigger: 'hover focus', - keyboard: false, + trigger: 'click', + keyboard: true, html: false, - show: false, title: '', - type: '', + content: '', delay: 0, - autoClose: false, - bsEnabled: true, - viewport: { - selector: 'body', - padding: 0 + autoClose: false + }; + this.$get = [ '$tooltip', function($tooltip) { + function PopoverFactory(element, config) { + var options = angular.extend({}, defaults, config); + var $popover = $tooltip(element, options); + if (options.content) { + $popover.$scope.content = options.content; + } + return $popover; + } + return PopoverFactory; + } ]; + }).directive('bsPopover', [ '$window', '$sce', '$popover', function($window, $sce, $popover) { + var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout; + return { + restrict: 'EAC', + scope: true, + link: function postLink(scope, element, attr) { + var popover; + var options = { + scope: scope + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container', 'autoClose' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + var dataTarget = element.attr('data-target'); + if (angular.isDefined(dataTarget)) { + if (falseValueRegExp.test(dataTarget)) { + options.target = false; + } else { + options.target = dataTarget; + } + } + angular.forEach([ 'title', 'content' ], function(key) { + if (attr[key]) { + attr.$observe(key, function(newValue, oldValue) { + scope[key] = $sce.trustAsHtml(newValue); + if (angular.isDefined(oldValue)) { + requestAnimationFrame(function() { + if (popover) popover.$applyPlacement(); + }); + } + }); + } + }); + if (attr.bsPopover) { + scope.$watch(attr.bsPopover, function(newValue, oldValue) { + if (angular.isObject(newValue)) { + angular.extend(scope, newValue); + } else { + scope.content = newValue; + } + if (angular.isDefined(oldValue)) { + requestAnimationFrame(function() { + if (popover) popover.$applyPlacement(); + }); + } + }, true); + } + if (attr.bsShow) { + scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!popover || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i); + if (newValue === true) { + popover.show(); + } else { + popover.hide(); + } + }); + } + if (attr.viewport) { + scope.$watch(attr.viewport, function(newValue) { + if (!popover || !angular.isDefined(newValue)) return; + popover.setViewport(newValue); + }); + } + popover = $popover(element, options); + scope.$on('$destroy', function() { + if (popover) popover.destroy(); + options = null; + popover = null; + }); } }; - this.$get = [ '$window', '$rootScope', '$bsCompiler', '$q', '$templateCache', '$http', '$animate', '$sce', 'dimensions', '$$rAF', '$timeout', function($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) { - var trim = String.prototype.trim; - var isTouch = 'createTouch' in $window.document; - var htmlReplaceRegExp = /ng-bind="/gi; - var $body = angular.element($window.document); - function TooltipFactory(element, config) { - var $tooltip = {}; - var options = $tooltip.$options = angular.extend({}, defaults, config); - var promise = $tooltip.$promise = $bsCompiler.compile(options); - var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new(); - var nodeName = element[0].nodeName.toLowerCase(); - if (options.delay && angular.isString(options.delay)) { - var split = options.delay.split(',').map(parseFloat); - options.delay = split.length > 1 ? { - show: split[0], - hide: split[1] - } : split[0]; - } - $tooltip.$id = options.id || element.attr('id') || ''; - if (options.title) { - scope.title = $sce.trustAsHtml(options.title); - } - scope.$setEnabled = function(isEnabled) { - scope.$$postDigest(function() { - $tooltip.setEnabled(isEnabled); + } ]); + angular.module('mgcrea.ngStrap.navbar', []).provider('$navbar', function() { + var defaults = this.defaults = { + activeClass: 'active', + routeAttr: 'data-match-route', + strict: false + }; + this.$get = function() { + return { + defaults: defaults + }; + }; + }).directive('bsNavbar', [ '$window', '$location', '$navbar', function($window, $location, $navbar) { + var defaults = $navbar.defaults; + return { + restrict: 'A', + link: function postLink(scope, element, attr, controller) { + var options = angular.copy(defaults); + angular.forEach(Object.keys(defaults), function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + scope.$watch(function() { + return $location.path(); + }, function(newValue, oldValue) { + var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']'); + angular.forEach(liElements, function(li) { + var liElement = angular.element(li); + var pattern = liElement.attr(options.routeAttr).replace('/', '\\/'); + if (options.strict) { + pattern = '^' + pattern + '$'; + } + var regexp = new RegExp(pattern, 'i'); + if (regexp.test(newValue)) { + liElement.addClass(options.activeClass); + } else { + liElement.removeClass(options.activeClass); + } }); - }; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.modal', [ 'mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$modal', function() { + var defaults = this.defaults = { + animation: 'am-fade', + backdropAnimation: 'am-fade', + customClass: '', + prefixClass: 'modal', + prefixEvent: 'modal', + placement: 'top', + templateUrl: 'modal/modal.tpl.html', + template: '', + contentTemplate: false, + container: false, + element: null, + backdrop: true, + keyboard: true, + html: false, + show: true, + size: null + }; + this.$get = [ '$window', '$rootScope', '$bsCompiler', '$animate', '$timeout', '$sce', 'dimensions', function($window, $rootScope, $bsCompiler, $animate, $timeout, $sce, dimensions) { + var forEach = angular.forEach; + var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout; + var bodyElement = angular.element($window.document.body); + var backdropCount = 0; + var dialogBaseZindex = 1050; + var backdropBaseZindex = 1040; + var validSizes = { + lg: 'modal-lg', + sm: 'modal-sm' + }; + function ModalFactory(config) { + var $modal = {}; + var options = $modal.$options = angular.extend({}, defaults, config); + var promise = $modal.$promise = $bsCompiler.compile(options); + var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new(); + if (!options.element && !options.container) { + options.container = 'body'; + } + $modal.$id = options.id || options.element && options.element.attr('id') || ''; + forEach([ 'title', 'content' ], function(key) { + if (options[key]) scope[key] = $sce.trustAsHtml(options[key]); + }); scope.$hide = function() { scope.$$postDigest(function() { - $tooltip.hide(); + $modal.hide(); }); }; scope.$show = function() { scope.$$postDigest(function() { - $tooltip.show(); + $modal.show(); }); }; scope.$toggle = function() { scope.$$postDigest(function() { - $tooltip.toggle(); + $modal.toggle(); }); }; - $tooltip.$isShown = scope.$isShown = false; - var timeout, hoverState; - var compileData, tipElement, tipContainer, tipScope; + $modal.$isShown = scope.$isShown = false; + var compileData; + var modalElement; + var modalScope; + var backdropElement = angular.element('
'); + backdropElement.css({ + position: 'fixed', + top: '0px', + left: '0px', + bottom: '0px', + right: '0px' + }); promise.then(function(data) { compileData = data; - $tooltip.init(); + $modal.init(); }); - $tooltip.init = function() { - if (options.delay && angular.isNumber(options.delay)) { - options.delay = { - show: options.delay, - hide: options.delay - }; - } - if (options.container === 'self') { - tipContainer = element; - } else if (angular.isElement(options.container)) { - tipContainer = options.container; - } else if (options.container) { - tipContainer = findElement(options.container); - } - bindTriggerEvents(); - if (options.target) { - options.target = angular.isElement(options.target) ? options.target : findElement(options.target); - } + $modal.init = function() { if (options.show) { scope.$$postDigest(function() { - options.trigger === 'focus' ? element[0].focus() : $tooltip.show(); + $modal.show(); }); } }; - $tooltip.destroy = function() { - unbindTriggerEvents(); - destroyTipElement(); + $modal.destroy = function() { + destroyModalElement(); + if (backdropElement) { + backdropElement.remove(); + backdropElement = null; + } scope.$destroy(); }; - $tooltip.enter = function() { - clearTimeout(timeout); - hoverState = 'in'; - if (!options.delay || !options.delay.show) { - return $tooltip.show(); - } - timeout = setTimeout(function() { - if (hoverState === 'in') $tooltip.show(); - }, options.delay.show); - }; - $tooltip.show = function() { - if (!options.bsEnabled || $tooltip.$isShown) return; - scope.$emit(options.prefixEvent + '.show.before', $tooltip); - var parent, after; - if (options.container) { - parent = tipContainer; - if (tipContainer[0].lastChild) { - after = angular.element(tipContainer[0].lastChild); + $modal.show = function() { + if ($modal.$isShown) return; + var parent; + var after; + if (angular.isElement(options.container)) { + parent = options.container; + after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null; + } else { + if (options.container) { + parent = findElement(options.container); + after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null; } else { - after = null; + parent = null; + after = options.element; } - } else { - parent = null; - after = element; } - if (tipElement) destroyTipElement(); - tipScope = $tooltip.$scope.$new(); - tipElement = $tooltip.$element = compileData.link(tipScope, function(clonedElement, scope) {}); - tipElement.css({ - top: '-9999px', - left: '-9999px', - right: 'auto', - display: 'block', - visibility: 'hidden' - }); - if (options.animation) tipElement.addClass(options.animation); - if (options.type) tipElement.addClass(options.prefixClass + '-' + options.type); - if (options.customClass) tipElement.addClass(options.customClass); - after ? after.after(tipElement) : parent.prepend(tipElement); - $tooltip.$isShown = scope.$isShown = true; - safeDigest(scope); - $tooltip.$applyPlacement(); - if (angular.version.minor <= 2) { - $animate.enter(tipElement, parent, after, enterAnimateCallback); - } else { - $animate.enter(tipElement, parent, after).then(enterAnimateCallback); - } - safeDigest(scope); - $$rAF(function() { - if (tipElement) tipElement.css({ - visibility: 'visible' + if (modalElement) destroyModalElement(); + modalScope = $modal.$scope.$new(); + modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {}); + if (options.backdrop) { + modalElement.css({ + 'z-index': dialogBaseZindex + backdropCount * 20 }); - }); - if (options.keyboard) { - if (options.trigger !== 'focus') { - $tooltip.focus(); + backdropElement.css({ + 'z-index': backdropBaseZindex + backdropCount * 20 + }); + backdropCount++; + } + if (scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) { + return; + } + if (angular.isDefined(options.onBeforeShow) && angular.isFunction(options.onBeforeShow)) { + options.onBeforeShow($modal); + } + modalElement.css({ + display: 'block' + }).addClass(options.placement); + if (options.customClass) { + modalElement.addClass(options.customClass); + } + if (options.size && validSizes[options.size]) { + angular.element(findElement('.modal-dialog', modalElement[0])).addClass(validSizes[options.size]); + } + if (options.animation) { + if (options.backdrop) { + backdropElement.addClass(options.backdropAnimation); } - bindKeyboardEvents(); + modalElement.addClass(options.animation); } - if (options.autoClose) { - bindAutoCloseEvents(); + if (options.backdrop) { + $animate.enter(backdropElement, bodyElement, null); } + if (angular.version.minor <= 2) { + $animate.enter(modalElement, parent, after, enterAnimateCallback); + } else { + $animate.enter(modalElement, parent, after).then(enterAnimateCallback); + } + $modal.$isShown = scope.$isShown = true; + safeDigest(scope); + var el = modalElement[0]; + requestAnimationFrame(function() { + el.focus(); + }); + bodyElement.addClass(options.prefixClass + '-open'); + if (options.animation) { + bodyElement.addClass(options.prefixClass + '-with-' + options.animation); + } + bindBackdropEvents(); + bindKeyboardEvents(); }; function enterAnimateCallback() { - scope.$emit(options.prefixEvent + '.show', $tooltip); + scope.$emit(options.prefixEvent + '.show', $modal); + if (angular.isDefined(options.onShow) && angular.isFunction(options.onShow)) { + options.onShow($modal); + } } - $tooltip.leave = function() { - clearTimeout(timeout); - hoverState = 'out'; - if (!options.delay || !options.delay.hide) { - return $tooltip.hide(); + $modal.hide = function() { + if (!$modal.$isShown) return; + if (scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) { + return; + } + if (angular.isDefined(options.onBeforeHide) && angular.isFunction(options.onBeforeHide)) { + options.onBeforeHide($modal); } - timeout = setTimeout(function() { - if (hoverState === 'out') { - $tooltip.hide(); - } - }, options.delay.hide); - }; - var _blur; - var _tipToHide; - $tooltip.hide = function(blur) { - if (!$tooltip.$isShown) return; - scope.$emit(options.prefixEvent + '.hide.before', $tooltip); - _blur = blur; - _tipToHide = tipElement; if (angular.version.minor <= 2) { - $animate.leave(tipElement, leaveAnimateCallback); + $animate.leave(modalElement, leaveAnimateCallback); } else { - $animate.leave(tipElement).then(leaveAnimateCallback); + $animate.leave(modalElement).then(leaveAnimateCallback); } - $tooltip.$isShown = scope.$isShown = false; + if (options.backdrop) { + backdropCount--; + $animate.leave(backdropElement); + } + $modal.$isShown = scope.$isShown = false; safeDigest(scope); - if (options.keyboard && tipElement !== null) { - unbindKeyboardEvents(); - } - if (options.autoClose && tipElement !== null) { - unbindAutoCloseEvents(); - } + unbindBackdropEvents(); + unbindKeyboardEvents(); }; function leaveAnimateCallback() { - scope.$emit(options.prefixEvent + '.hide', $tooltip); - if (tipElement === _tipToHide) { - if (_blur && options.trigger === 'focus') { - return element[0].blur(); - } - destroyTipElement(); + scope.$emit(options.prefixEvent + '.hide', $modal); + if (angular.isDefined(options.onHide) && angular.isFunction(options.onHide)) { + options.onHide($modal); + } + bodyElement.removeClass(options.prefixClass + '-open'); + if (options.animation) { + bodyElement.removeClass(options.prefixClass + '-with-' + options.animation); } } - $tooltip.toggle = function() { - $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter(); - }; - $tooltip.focus = function() { - tipElement[0].focus(); - }; - $tooltip.setEnabled = function(isEnabled) { - options.bsEnabled = isEnabled; - }; - $tooltip.setViewport = function(viewport) { - options.viewport = viewport; - }; - $tooltip.$applyPlacement = function() { - if (!tipElement) return; - var placement = options.placement, autoToken = /\s?auto?\s?/i, autoPlace = autoToken.test(placement); - if (autoPlace) { - placement = placement.replace(autoToken, '') || defaults.placement; + $modal.toggle = function() { + if ($modal.$isShown) { + $modal.hide(); + } else { + $modal.show(); } - tipElement.addClass(options.placement); - var elementPosition = getPosition(), tipWidth = tipElement.prop('offsetWidth'), tipHeight = tipElement.prop('offsetHeight'); - $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport); - if (autoPlace) { - var originalPlacement = placement; - var viewportPosition = getPosition($tooltip.$viewport); - if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > viewportPosition.bottom) { - placement = originalPlacement.replace('bottom', 'top'); - } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < viewportPosition.top) { - placement = originalPlacement.replace('top', 'bottom'); - } - if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') && elementPosition.right + tipWidth > viewportPosition.width) { - placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right'); - } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') && elementPosition.left - tipWidth < viewportPosition.left) { - placement = originalPlacement === 'left' ? 'right' : placement.replace('right', 'left'); - } - tipElement.removeClass(originalPlacement).addClass(placement); - } - var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight); - applyPlacement(tipPosition, placement); }; - $tooltip.$onKeyUp = function(evt) { - if (evt.which === 27 && $tooltip.$isShown) { - $tooltip.hide(); + $modal.focus = function() { + modalElement[0].focus(); + }; + $modal.$onKeyUp = function(evt) { + if (evt.which === 27 && $modal.$isShown) { + $modal.hide(); evt.stopPropagation(); } }; - $tooltip.$onFocusKeyUp = function(evt) { - if (evt.which === 27) { - element[0].blur(); - evt.stopPropagation(); + function bindBackdropEvents() { + if (options.backdrop) { + modalElement.on('click', hideOnBackdropClick); + backdropElement.on('click', hideOnBackdropClick); + backdropElement.on('wheel', preventEventDefault); } - }; - $tooltip.$onFocusElementMouseDown = function(evt) { - evt.preventDefault(); - evt.stopPropagation(); - $tooltip.$isShown ? element[0].blur() : element[0].focus(); - }; - function bindTriggerEvents() { - var triggers = options.trigger.split(' '); - angular.forEach(triggers, function(trigger) { - if (trigger === 'click') { - element.on('click', $tooltip.toggle); - } else if (trigger !== 'manual') { - element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter); - element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave); - nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown); - } - }); } - function unbindTriggerEvents() { - var triggers = options.trigger.split(' '); - for (var i = triggers.length; i--; ) { - var trigger = triggers[i]; - if (trigger === 'click') { - element.off('click', $tooltip.toggle); - } else if (trigger !== 'manual') { - element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter); - element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave); - nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown); - } + function unbindBackdropEvents() { + if (options.backdrop) { + modalElement.off('click', hideOnBackdropClick); + backdropElement.off('click', hideOnBackdropClick); + backdropElement.off('wheel', preventEventDefault); } } function bindKeyboardEvents() { - if (options.trigger !== 'focus') { - tipElement.on('keyup', $tooltip.$onKeyUp); - } else { - element.on('keyup', $tooltip.$onFocusKeyUp); + if (options.keyboard) { + modalElement.on('keyup', $modal.$onKeyUp); } } function unbindKeyboardEvents() { - if (options.trigger !== 'focus') { - tipElement.off('keyup', $tooltip.$onKeyUp); + if (options.keyboard) { + modalElement.off('keyup', $modal.$onKeyUp); + } + } + function hideOnBackdropClick(evt) { + if (evt.target !== evt.currentTarget) return; + if (options.backdrop === 'static') { + $modal.focus(); } else { - element.off('keyup', $tooltip.$onFocusKeyUp); + $modal.hide(); } } - var _autoCloseEventsBinded = false; - function bindAutoCloseEvents() { - $timeout(function() { - tipElement.on('click', stopEventPropagation); - $body.on('click', $tooltip.hide); - _autoCloseEventsBinded = true; - }, 0, false); + function preventEventDefault(evt) { + evt.preventDefault(); } - function unbindAutoCloseEvents() { - if (_autoCloseEventsBinded) { - tipElement.off('click', stopEventPropagation); - $body.off('click', $tooltip.hide); - _autoCloseEventsBinded = false; + function destroyModalElement() { + if ($modal.$isShown && modalElement !== null) { + unbindBackdropEvents(); + unbindKeyboardEvents(); + } + if (modalScope) { + modalScope.$destroy(); + modalScope = null; + } + if (modalElement) { + modalElement.remove(); + modalElement = $modal.$element = null; } } - function stopEventPropagation(event) { - event.stopPropagation(); - } - function getPosition($element) { - $element = $element || (options.target || element); - var el = $element[0], isBody = el.tagName === 'BODY'; - var elRect = el.getBoundingClientRect(); - var rect = {}; - for (var p in elRect) { - rect[p] = elRect[p]; - } - if (rect.width === null) { - rect = angular.extend({}, rect, { - width: elRect.right - elRect.left, - height: elRect.bottom - elRect.top - }); - } - var elOffset = isBody ? { - top: 0, - left: 0 - } : dimensions.offset(el), scroll = { - scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 - }, outerDims = isBody ? { - width: document.documentElement.clientWidth, - height: $window.innerHeight - } : null; - return angular.extend({}, rect, scroll, outerDims, elOffset); - } - function getCalculatedOffset(placement, position, actualWidth, actualHeight) { - var offset; - var split = placement.split('-'); - switch (split[0]) { - case 'right': - offset = { - top: position.top + position.height / 2 - actualHeight / 2, - left: position.left + position.width - }; - break; - - case 'bottom': - offset = { - top: position.top + position.height, - left: position.left + position.width / 2 - actualWidth / 2 - }; - break; - - case 'left': - offset = { - top: position.top + position.height / 2 - actualHeight / 2, - left: position.left - actualWidth - }; - break; - - default: - offset = { - top: position.top - actualHeight, - left: position.left + position.width / 2 - actualWidth / 2 - }; - break; - } - if (!split[1]) { - return offset; - } - if (split[0] === 'top' || split[0] === 'bottom') { - switch (split[1]) { - case 'left': - offset.left = position.left; - break; - - case 'right': - offset.left = position.left + position.width - actualWidth; - } - } else if (split[0] === 'left' || split[0] === 'right') { - switch (split[1]) { - case 'top': - offset.top = position.top - actualHeight; - break; - - case 'bottom': - offset.top = position.top + position.height; - } - } - return offset; - } - function applyPlacement(offset, placement) { - var tip = tipElement[0], width = tip.offsetWidth, height = tip.offsetHeight; - var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10), marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10); - if (isNaN(marginTop)) marginTop = 0; - if (isNaN(marginLeft)) marginLeft = 0; - offset.top = offset.top + marginTop; - offset.left = offset.left + marginLeft; - dimensions.setOffset(tip, angular.extend({ - using: function(props) { - tipElement.css({ - top: Math.round(props.top) + 'px', - left: Math.round(props.left) + 'px', - right: '' - }); - } - }, offset), 0); - var actualWidth = tip.offsetWidth, actualHeight = tip.offsetHeight; - if (placement === 'top' && actualHeight !== height) { - offset.top = offset.top + height - actualHeight; - } - if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return; - var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight); - if (delta.left) { - offset.left += delta.left; - } else { - offset.top += delta.top; - } - dimensions.setOffset(tip, offset); - if (/top|right|bottom|left/.test(placement)) { - var isVertical = /top|bottom/.test(placement), arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight, arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'; - replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical); - } - } - function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) { - var delta = { - top: 0, - left: 0 - }; - if (!$tooltip.$viewport) return delta; - var viewportPadding = options.viewport && options.viewport.padding || 0; - var viewportDimensions = getPosition($tooltip.$viewport); - if (/right|left/.test(placement)) { - var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll; - var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight; - if (topEdgeOffset < viewportDimensions.top) { - delta.top = viewportDimensions.top - topEdgeOffset; - } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { - delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset; - } - } else { - var leftEdgeOffset = position.left - viewportPadding; - var rightEdgeOffset = position.left + viewportPadding + actualWidth; - if (leftEdgeOffset < viewportDimensions.left) { - delta.left = viewportDimensions.left - leftEdgeOffset; - } else if (rightEdgeOffset > viewportDimensions.right) { - delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset; - } - } - return delta; - } - function replaceArrow(delta, dimension, isHorizontal) { - var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]); - $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%').css(isHorizontal ? 'top' : 'left', ''); - } - function destroyTipElement() { - clearTimeout(timeout); - if ($tooltip.$isShown && tipElement !== null) { - if (options.autoClose) { - unbindAutoCloseEvents(); - } - if (options.keyboard) { - unbindKeyboardEvents(); - } - } - if (tipScope) { - tipScope.$destroy(); - tipScope = null; - } - if (tipElement) { - tipElement.remove(); - tipElement = $tooltip.$element = null; - } - } - return $tooltip; + return $modal; } function safeDigest(scope) { scope.$$phase || scope.$root && scope.$root.$$phase || scope.$digest(); @@ -3954,79 +2407,2068 @@ function findElement(query, element) { return angular.element((element || document).querySelectorAll(query)); } - var fetchPromises = {}; - function fetchTemplate(template) { - if (fetchPromises[template]) return fetchPromises[template]; - return fetchPromises[template] = $http.get(template, { - cache: $templateCache - }).then(function(res) { - return res.data; - }); - } - return TooltipFactory; + return ModalFactory; } ]; - }).directive('bsTooltip', [ '$window', '$location', '$sce', '$tooltip', '$$rAF', function($window, $location, $sce, $tooltip, $$rAF) { + }).directive('bsModal', [ '$window', '$sce', '$parse', '$modal', function($window, $sce, $parse, $modal) { return { restrict: 'EAC', scope: true, link: function postLink(scope, element, attr, transclusion) { var options = { - scope: scope + scope: scope, + element: element, + show: false }; - angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id' ], function(key) { + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass', 'customClass', 'modalClass', 'size' ], function(key) { if (angular.isDefined(attr[key])) options[key] = attr[key]; }); + if (options.modalClass) { + options.customClass = options.modalClass; + } var falseValueRegExp = /^(false|0|)$/i; - angular.forEach([ 'html', 'container' ], function(key) { + angular.forEach([ 'backdrop', 'keyboard', 'html', 'container' ], function(key) { if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; }); - var dataTarget = element.attr('data-target'); - if (angular.isDefined(dataTarget)) { - if (falseValueRegExp.test(dataTarget)) options.target = false; else options.target = dataTarget; - } - if (!scope.hasOwnProperty('title')) { - scope.title = ''; - } - attr.$observe('title', function(newValue) { - if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) { - var oldValue = scope.title; - scope.title = $sce.trustAsHtml(newValue); - angular.isDefined(oldValue) && $$rAF(function() { - tooltip && tooltip.$applyPlacement(); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + angular.forEach([ 'title', 'content' ], function(key) { + if (attr[key]) { + attr.$observe(key, function(newValue, oldValue) { + scope[key] = $sce.trustAsHtml(newValue); }); } }); - attr.bsTooltip && scope.$watch(attr.bsTooltip, function(newValue, oldValue) { - if (angular.isObject(newValue)) { - angular.extend(scope, newValue); - } else { - scope.title = newValue; - } - angular.isDefined(oldValue) && $$rAF(function() { - tooltip && tooltip.$applyPlacement(); - }); - }, true); - attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) { - if (!tooltip || !angular.isDefined(newValue)) return; - if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i); - newValue === true ? tooltip.show() : tooltip.hide(); - }); - attr.bsEnabled && scope.$watch(attr.bsEnabled, function(newValue, oldValue) { - if (!tooltip || !angular.isDefined(newValue)) return; - if (angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i); - newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true); - }); - attr.viewport && scope.$watch(attr.viewport, function(newValue) { - if (!tooltip || !angular.isDefined(newValue)) return; - tooltip.setViewport(newValue); - }); - var tooltip = $tooltip(element, options); + if (attr.bsModal) { + scope.$watch(attr.bsModal, function(newValue, oldValue) { + if (angular.isObject(newValue)) { + angular.extend(scope, newValue); + } else { + scope.content = newValue; + } + }, true); + } + var modal = $modal(options); + element.on(attr.trigger || 'click', modal.toggle); scope.$on('$destroy', function() { - if (tooltip) tooltip.destroy(); + if (modal) modal.destroy(); options = null; - tooltip = null; + modal = null; }); } }; } ]); + angular.module('mgcrea.ngStrap.dropdown', [ 'mgcrea.ngStrap.tooltip' ]).provider('$dropdown', function() { + var defaults = this.defaults = { + animation: 'am-fade', + prefixClass: 'dropdown', + prefixEvent: 'dropdown', + placement: 'bottom-left', + templateUrl: 'dropdown/dropdown.tpl.html', + trigger: 'click', + container: false, + keyboard: true, + html: false, + delay: 0 + }; + this.$get = [ '$window', '$rootScope', '$tooltip', '$timeout', function($window, $rootScope, $tooltip, $timeout) { + var bodyEl = angular.element($window.document.body); + var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector; + function DropdownFactory(element, config) { + var $dropdown = {}; + var options = angular.extend({}, defaults, config); + $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new(); + $dropdown = $tooltip(element, options); + var parentEl = element.parent(); + $dropdown.$onKeyDown = function(evt) { + if (!/(38|40)/.test(evt.keyCode)) return; + evt.preventDefault(); + evt.stopPropagation(); + var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a')); + if (!items.length) return; + var index; + angular.forEach(items, function(el, i) { + if (matchesSelector && matchesSelector.call(el, ':focus')) index = i; + }); + if (evt.keyCode === 38 && index > 0) index--; else if (evt.keyCode === 40 && index < items.length - 1) index++; else if (angular.isUndefined(index)) index = 0; + items.eq(index)[0].focus(); + }; + var show = $dropdown.show; + $dropdown.show = function() { + show(); + $timeout(function() { + if (options.keyboard && $dropdown.$element) $dropdown.$element.on('keydown', $dropdown.$onKeyDown); + bodyEl.on('click', onBodyClick); + }, 0, false); + if (parentEl.hasClass('dropdown')) parentEl.addClass('open'); + }; + var hide = $dropdown.hide; + $dropdown.hide = function() { + if (!$dropdown.$isShown) return; + if (options.keyboard && $dropdown.$element) $dropdown.$element.off('keydown', $dropdown.$onKeyDown); + bodyEl.off('click', onBodyClick); + if (parentEl.hasClass('dropdown')) parentEl.removeClass('open'); + hide(); + }; + var destroy = $dropdown.destroy; + $dropdown.destroy = function() { + bodyEl.off('click', onBodyClick); + destroy(); + }; + function onBodyClick(evt) { + if (evt.target === element[0]) return; + return evt.target !== element[0] && $dropdown.hide(); + } + return $dropdown; + } + return DropdownFactory; + } ]; + }).directive('bsDropdown', [ '$window', '$sce', '$dropdown', function($window, $sce, $dropdown) { + return { + restrict: 'EAC', + scope: true, + compile: function(tElement, tAttrs) { + if (!tAttrs.bsDropdown) { + var nextSibling = tElement[0].nextSibling; + while (nextSibling && nextSibling.nodeType !== 1) { + nextSibling = nextSibling.nextSibling; + } + if (nextSibling && nextSibling.className.split(' ').indexOf('dropdown-menu') >= 0) { + tAttrs.template = nextSibling.outerHTML; + tAttrs.templateUrl = undefined; + nextSibling.parentNode.removeChild(nextSibling); + } + } + return function postLink(scope, element, attr) { + var options = { + scope: scope + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id', 'autoClose' ], function(key) { + if (angular.isDefined(tAttrs[key])) options[key] = tAttrs[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + if (attr.bsDropdown) { + scope.$watch(attr.bsDropdown, function(newValue, oldValue) { + scope.content = newValue; + }, true); + } + var dropdown = $dropdown(element, options); + if (attr.bsShow) { + scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!dropdown || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i); + if (newValue === true) { + dropdown.show(); + } else { + dropdown.hide(); + } + }); + } + scope.$on('$destroy', function() { + if (dropdown) dropdown.destroy(); + options = null; + dropdown = null; + }); + }; + } + }; + } ]); + if (angular.version.minor < 3 && angular.version.dot < 14) { + angular.module('ng').factory('$$rAF', [ '$window', '$timeout', function($window, $timeout) { + var requestAnimationFrame = $window.requestAnimationFrame || $window.webkitRequestAnimationFrame || $window.mozRequestAnimationFrame; + var cancelAnimationFrame = $window.cancelAnimationFrame || $window.webkitCancelAnimationFrame || $window.mozCancelAnimationFrame || $window.webkitCancelRequestAnimationFrame; + var rafSupported = !!requestAnimationFrame; + var raf = rafSupported ? function(fn) { + var id = requestAnimationFrame(fn); + return function() { + cancelAnimationFrame(id); + }; + } : function(fn) { + var timer = $timeout(fn, 16.66, false); + return function() { + $timeout.cancel(timer); + }; + }; + raf.supported = rafSupported; + return raf; + } ]); + } + angular.module('mgcrea.ngStrap.helpers.parseOptions', []).provider('$parseOptions', function() { + var defaults = this.defaults = { + regexp: /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/ + }; + this.$get = [ '$parse', '$q', function($parse, $q) { + function ParseOptionsFactory(attr, config) { + var $parseOptions = {}; + var options = angular.extend({}, defaults, config); + $parseOptions.$values = []; + var match; + var displayFn; + var valueName; + var keyName; + var groupByFn; + var valueFn; + var valuesFn; + $parseOptions.init = function() { + $parseOptions.$match = match = attr.match(options.regexp); + displayFn = $parse(match[2] || match[1]); + valueName = match[4] || match[6]; + keyName = match[5]; + groupByFn = $parse(match[3] || ''); + valueFn = $parse(match[2] ? match[1] : valueName); + valuesFn = $parse(match[7]); + }; + $parseOptions.valuesFn = function(scope, controller) { + return $q.when(valuesFn(scope, controller)).then(function(values) { + if (!angular.isArray(values)) { + values = []; + } + $parseOptions.$values = values.length ? parseValues(values, scope) : []; + return $parseOptions.$values; + }); + }; + $parseOptions.displayValue = function(modelValue) { + var scope = {}; + scope[valueName] = modelValue; + return displayFn(scope); + }; + function parseValues(values, scope) { + return values.map(function(match, index) { + var locals = {}; + var label; + var value; + locals[valueName] = match; + label = displayFn(scope, locals); + value = valueFn(scope, locals); + return { + label: label, + value: value, + index: index + }; + }); + } + $parseOptions.init(); + return $parseOptions; + } + return ParseOptionsFactory; + } ]; + }); + angular.module('mgcrea.ngStrap.helpers.dimensions', []).factory('dimensions', function() { + var fn = {}; + var nodeName = fn.nodeName = function(element, name) { + return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase(); + }; + fn.css = function(element, prop, extra) { + var value; + if (element.currentStyle) { + value = element.currentStyle[prop]; + } else if (window.getComputedStyle) { + value = window.getComputedStyle(element)[prop]; + } else { + value = element.style[prop]; + } + return extra === true ? parseFloat(value) || 0 : value; + }; + fn.offset = function(element) { + var boxRect = element.getBoundingClientRect(); + var docElement = element.ownerDocument; + return { + width: boxRect.width || element.offsetWidth, + height: boxRect.height || element.offsetHeight, + top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0), + left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0) + }; + }; + fn.setOffset = function(element, options, i) { + var curPosition; + var curLeft; + var curCSSTop; + var curTop; + var curOffset; + var curCSSLeft; + var calculatePosition; + var position = fn.css(element, 'position'); + var curElem = angular.element(element); + var props = {}; + if (position === 'static') { + element.style.position = 'relative'; + } + curOffset = fn.offset(element); + curCSSTop = fn.css(element, 'top'); + curCSSLeft = fn.css(element, 'left'); + calculatePosition = (position === 'absolute' || position === 'fixed') && (curCSSTop + curCSSLeft).indexOf('auto') > -1; + if (calculatePosition) { + curPosition = fn.position(element); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat(curCSSTop) || 0; + curLeft = parseFloat(curCSSLeft) || 0; + } + if (angular.isFunction(options)) { + options = options.call(element, i, curOffset); + } + if (options.top !== null) { + props.top = options.top - curOffset.top + curTop; + } + if (options.left !== null) { + props.left = options.left - curOffset.left + curLeft; + } + if ('using' in options) { + options.using.call(curElem, props); + } else { + curElem.css({ + top: props.top + 'px', + left: props.left + 'px' + }); + } + }; + fn.position = function(element) { + var offsetParentRect = { + top: 0, + left: 0 + }; + var offsetParentEl; + var offset; + if (fn.css(element, 'position') === 'fixed') { + offset = element.getBoundingClientRect(); + } else { + offsetParentEl = offsetParentElement(element); + offset = fn.offset(element); + if (!nodeName(offsetParentEl, 'html')) { + offsetParentRect = fn.offset(offsetParentEl); + } + offsetParentRect.top += fn.css(offsetParentEl, 'borderTopWidth', true); + offsetParentRect.left += fn.css(offsetParentEl, 'borderLeftWidth', true); + } + return { + width: element.offsetWidth, + height: element.offsetHeight, + top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true), + left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true) + }; + }; + function offsetParentElement(element) { + var docElement = element.ownerDocument; + var offsetParent = element.offsetParent || docElement; + if (nodeName(offsetParent, '#document')) return docElement.documentElement; + while (offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') { + offsetParent = offsetParent.offsetParent; + } + return offsetParent || docElement.documentElement; + } + fn.height = function(element, outer) { + var value = element.offsetHeight; + if (outer) { + value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true); + } else { + value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true); + } + return value; + }; + fn.width = function(element, outer) { + var value = element.offsetWidth; + if (outer) { + value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true); + } else { + value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true); + } + return value; + }; + return fn; + }); + angular.module('mgcrea.ngStrap.helpers.debounce', []).factory('debounce', [ '$timeout', function($timeout) { + return function(func, wait, immediate) { + var timeout = null; + return function() { + var context = this; + var args = arguments; + var callNow = immediate && !timeout; + if (timeout) { + $timeout.cancel(timeout); + } + timeout = $timeout(function later() { + timeout = null; + if (!immediate) { + func.apply(context, args); + } + }, wait, false); + if (callNow) { + func.apply(context, args); + } + return timeout; + }; + }; + } ]).factory('throttle', [ '$timeout', function($timeout) { + return function(func, wait, options) { + var timeout = null; + if (!options) options = {}; + return function() { + var context = this; + var args = arguments; + if (!timeout) { + if (options.leading !== false) { + func.apply(context, args); + } + timeout = $timeout(function later() { + timeout = null; + if (options.trailing !== false) { + func.apply(context, args); + } + }, wait, false); + } + }; + }; + } ]); + angular.module('mgcrea.ngStrap.helpers.dateParser', []).provider('$dateParser', [ '$localeProvider', function($localeProvider) { + function ParseDate() { + this.year = 1970; + this.month = 0; + this.day = 1; + this.hours = 0; + this.minutes = 0; + this.seconds = 0; + this.milliseconds = 0; + } + ParseDate.prototype.setMilliseconds = function(value) { + this.milliseconds = value; + }; + ParseDate.prototype.setSeconds = function(value) { + this.seconds = value; + }; + ParseDate.prototype.setMinutes = function(value) { + this.minutes = value; + }; + ParseDate.prototype.setHours = function(value) { + this.hours = value; + }; + ParseDate.prototype.getHours = function() { + return this.hours; + }; + ParseDate.prototype.setDate = function(value) { + this.day = value; + }; + ParseDate.prototype.setMonth = function(value) { + this.month = value; + }; + ParseDate.prototype.setFullYear = function(value) { + this.year = value; + }; + ParseDate.prototype.fromDate = function(value) { + this.year = value.getFullYear(); + this.month = value.getMonth(); + this.day = value.getDate(); + this.hours = value.getHours(); + this.minutes = value.getMinutes(); + this.seconds = value.getSeconds(); + this.milliseconds = value.getMilliseconds(); + return this; + }; + ParseDate.prototype.toDate = function() { + return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds); + }; + var proto = ParseDate.prototype; + function noop() {} + function isNumeric(n) { + return !isNaN(parseFloat(n)) && isFinite(n); + } + function indexOfCaseInsensitive(array, value) { + var len = array.length; + var str = value.toString().toLowerCase(); + for (var i = 0; i < len; i++) { + if (array[i].toLowerCase() === str) { + return i; + } + } + return -1; + } + var defaults = this.defaults = { + format: 'shortDate', + strict: false + }; + this.$get = [ '$locale', 'dateFilter', function($locale, dateFilter) { + var DateParserFactory = function(config) { + var options = angular.extend({}, defaults, config); + var $dateParser = {}; + var regExpMap = { + sss: '[0-9]{3}', + ss: '[0-5][0-9]', + s: options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]', + mm: '[0-5][0-9]', + m: options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]', + HH: '[01][0-9]|2[0-3]', + H: options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]', + hh: '[0][1-9]|[1][012]', + h: options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]', + a: 'AM|PM', + EEEE: $locale.DATETIME_FORMATS.DAY.join('|'), + EEE: $locale.DATETIME_FORMATS.SHORTDAY.join('|'), + dd: '0[1-9]|[12][0-9]|3[01]', + d: options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]', + MMMM: $locale.DATETIME_FORMATS.MONTH.join('|'), + MMM: $locale.DATETIME_FORMATS.SHORTMONTH.join('|'), + MM: '0[1-9]|1[012]', + M: options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]', + yyyy: '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}', + yy: '[0-9]{2}', + y: options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}' + }; + var setFnMap = { + sss: proto.setMilliseconds, + ss: proto.setSeconds, + s: proto.setSeconds, + mm: proto.setMinutes, + m: proto.setMinutes, + HH: proto.setHours, + H: proto.setHours, + hh: proto.setHours, + h: proto.setHours, + EEEE: noop, + EEE: noop, + dd: proto.setDate, + d: proto.setDate, + a: function(value) { + var hours = this.getHours() % 12; + return this.setHours(value.match(/pm/i) ? hours + 12 : hours); + }, + MMMM: function(value) { + return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); + }, + MMM: function(value) { + return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); + }, + MM: function(value) { + return this.setMonth(1 * value - 1); + }, + M: function(value) { + return this.setMonth(1 * value - 1); + }, + yyyy: proto.setFullYear, + yy: function(value) { + return this.setFullYear(2e3 + 1 * value); + }, + y: function(value) { + return 1 * value <= 50 && value.length === 2 ? this.setFullYear(2e3 + 1 * value) : this.setFullYear(1 * value); + } + }; + var regex; + var setMap; + $dateParser.init = function() { + $dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format; + regex = regExpForFormat($dateParser.$format); + setMap = setMapForFormat($dateParser.$format); + }; + $dateParser.isValid = function(date) { + if (angular.isDate(date)) return !isNaN(date.getTime()); + return regex.test(date); + }; + $dateParser.parse = function(value, baseDate, format, timezone) { + if (format) format = $locale.DATETIME_FORMATS[format] || format; + if (angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format, timezone); + var formatRegex = format ? regExpForFormat(format) : regex; + var formatSetMap = format ? setMapForFormat(format) : setMap; + var matches = formatRegex.exec(value); + if (!matches) return false; + var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0)); + for (var i = 0; i < matches.length - 1; i++) { + if (formatSetMap[i]) formatSetMap[i].call(date, matches[i + 1]); + } + var newDate = date.toDate(); + if (parseInt(date.day, 10) !== newDate.getDate()) { + return false; + } + return newDate; + }; + $dateParser.getDateForAttribute = function(key, value) { + var date; + if (value === 'today') { + var today = new Date(); + date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, key === 'minDate' ? 0 : -1); + } else if (angular.isString(value) && value.match(/^".+"$/)) { + date = new Date(value.substr(1, value.length - 2)); + } else if (isNumeric(value)) { + date = new Date(parseInt(value, 10)); + } else if (angular.isString(value) && value.length === 0) { + date = key === 'minDate' ? -Infinity : +Infinity; + } else { + date = new Date(value); + } + return date; + }; + $dateParser.getTimeForAttribute = function(key, value) { + var time; + if (value === 'now') { + time = new Date().setFullYear(1970, 0, 1); + } else if (angular.isString(value) && value.match(/^".+"$/)) { + time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1); + } else if (isNumeric(value)) { + time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1); + } else if (angular.isString(value) && value.length === 0) { + time = key === 'minTime' ? -Infinity : +Infinity; + } else { + time = $dateParser.parse(value, new Date(1970, 0, 1, 0)); + } + return time; + }; + $dateParser.daylightSavingAdjust = function(date) { + if (!date) { + return null; + } + date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); + return date; + }; + $dateParser.timezoneOffsetAdjust = function(date, timezone, undo) { + if (!date) { + return null; + } + if (timezone && timezone === 'UTC') { + date = new Date(date.getTime()); + date.setMinutes(date.getMinutes() + (undo ? -1 : 1) * date.getTimezoneOffset()); + } + return date; + }; + function regExpForFormat(format) { + var re = buildDateAbstractRegex(format); + return buildDateParseRegex(re); + } + function buildDateAbstractRegex(format) { + var escapedFormat = escapeReservedSymbols(format); + var escapedLiteralFormat = escapedFormat.replace(/''/g, '\\\''); + var literalRegex = /('(?:\\'|.)*?')/; + var formatParts = escapedLiteralFormat.split(literalRegex); + var dateElements = Object.keys(regExpMap); + var dateRegexParts = []; + angular.forEach(formatParts, function(part) { + if (isFormatStringLiteral(part)) { + part = trimLiteralEscapeChars(part); + } else { + for (var i = 0; i < dateElements.length; i++) { + part = part.split(dateElements[i]).join('${' + i + '}'); + } + } + dateRegexParts.push(part); + }); + return dateRegexParts.join(''); + } + function escapeReservedSymbols(text) { + return text.replace(/\\/g, '[\\\\]').replace(/-/g, '[-]').replace(/\./g, '[.]').replace(/\*/g, '[*]').replace(/\+/g, '[+]').replace(/\?/g, '[?]').replace(/\$/g, '[$]').replace(/\^/g, '[^]').replace(/\//g, '[/]').replace(/\\s/g, '[\\s]'); + } + function isFormatStringLiteral(text) { + return /^'.*'$/.test(text); + } + function trimLiteralEscapeChars(text) { + return text.replace(/^'(.*)'$/, '$1'); + } + function buildDateParseRegex(abstractRegex) { + var dateElements = Object.keys(regExpMap); + var re = abstractRegex; + for (var i = 0; i < dateElements.length; i++) { + re = re.split('${' + i + '}').join('(' + regExpMap[dateElements[i]] + ')'); + } + return new RegExp('^' + re + '$', [ 'i' ]); + } + function setMapForFormat(format) { + var re = buildDateAbstractRegex(format); + return buildDateParseValuesMap(re); + } + function buildDateParseValuesMap(abstractRegex) { + var dateElements = Object.keys(regExpMap); + var valuesRegex = new RegExp('\\${(\\d+)}', 'g'); + var valuesMatch; + var keyIndex; + var valueKey; + var valueFunction; + var valuesFunctionMap = []; + while ((valuesMatch = valuesRegex.exec(abstractRegex)) !== null) { + keyIndex = valuesMatch[1]; + valueKey = dateElements[keyIndex]; + valueFunction = setFnMap[valueKey]; + valuesFunctionMap.push(valueFunction); + } + return valuesFunctionMap; + } + $dateParser.init(); + return $dateParser; + }; + return DateParserFactory; + } ]; + } ]); + angular.module('mgcrea.ngStrap.helpers.dateFormatter', []).service('$dateFormatter', [ '$locale', 'dateFilter', function($locale, dateFilter) { + this.getDefaultLocale = function() { + return $locale.id; + }; + this.getDatetimeFormat = function(format, lang) { + return $locale.DATETIME_FORMATS[format] || format; + }; + this.weekdaysShort = function(lang) { + return $locale.DATETIME_FORMATS.SHORTDAY; + }; + function splitTimeFormat(format) { + return /(h+)([:\.])?(m+)([:\.])?(s*)[ ]?(a?)/i.exec(format).slice(1); + } + this.hoursFormat = function(timeFormat) { + return splitTimeFormat(timeFormat)[0]; + }; + this.minutesFormat = function(timeFormat) { + return splitTimeFormat(timeFormat)[2]; + }; + this.secondsFormat = function(timeFormat) { + return splitTimeFormat(timeFormat)[4]; + }; + this.timeSeparator = function(timeFormat) { + return splitTimeFormat(timeFormat)[1]; + }; + this.showSeconds = function(timeFormat) { + return !!splitTimeFormat(timeFormat)[4]; + }; + this.showAM = function(timeFormat) { + return !!splitTimeFormat(timeFormat)[5]; + }; + this.formatDate = function(date, format, lang, timezone) { + return dateFilter(date, format, timezone); + }; + } ]); + angular.module('mgcrea.ngStrap.core', []).service('$bsCompiler', bsCompilerService); + function bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) { + this.compile = function(options) { + if (options.template && /\.html$/.test(options.template)) { + console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'); + options.templateUrl = options.template; + options.template = ''; + } + var templateUrl = options.templateUrl; + var template = options.template || ''; + var controller = options.controller; + var controllerAs = options.controllerAs; + var resolve = angular.copy(options.resolve || {}); + var locals = angular.copy(options.locals || {}); + var transformTemplate = options.transformTemplate || angular.identity; + var bindToController = options.bindToController; + angular.forEach(resolve, function(value, key) { + if (angular.isString(value)) { + resolve[key] = $injector.get(value); + } else { + resolve[key] = $injector.invoke(value); + } + }); + angular.extend(resolve, locals); + if (template) { + resolve.$template = $q.when(template); + } else if (templateUrl) { + resolve.$template = fetchTemplate(templateUrl); + } else { + throw new Error('Missing `template` / `templateUrl` option.'); + } + if (options.titleTemplate) { + resolve.$template = $q.all([ resolve.$template, fetchTemplate(options.titleTemplate) ]).then(function(templates) { + var templateEl = angular.element(templates[0]); + findElement('[ng-bind="title"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]); + return templateEl[0].outerHTML; + }); + } + if (options.contentTemplate) { + resolve.$template = $q.all([ resolve.$template, fetchTemplate(options.contentTemplate) ]).then(function(templates) { + var templateEl = angular.element(templates[0]); + var contentEl = findElement('[ng-bind="content"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]); + if (!options.templateUrl) contentEl.next().remove(); + return templateEl[0].outerHTML; + }); + } + return $q.all(resolve).then(function(locals) { + var template = transformTemplate(locals.$template); + if (options.html) { + template = template.replace(/ng-bind="/gi, 'ng-bind-html="'); + } + var element = angular.element('
').html(template.trim()).contents(); + var linkFn = $compile(element); + return { + locals: locals, + element: element, + link: function link(scope) { + locals.$scope = scope; + if (controller) { + var invokeCtrl = $controller(controller, locals, true); + if (bindToController) { + angular.extend(invokeCtrl.instance, locals); + } + var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl(); + element.data('$ngControllerController', ctrl); + element.children().data('$ngControllerController', ctrl); + if (controllerAs) { + scope[controllerAs] = ctrl; + } + } + return linkFn.apply(null, arguments); + } + }; + }); + }; + function findElement(query, element) { + return angular.element((element || document).querySelectorAll(query)); + } + var fetchPromises = {}; + function fetchTemplate(template) { + if (fetchPromises[template]) return fetchPromises[template]; + return fetchPromises[template] = $http.get(template, { + cache: $templateCache + }).then(function(res) { + return res.data; + }); + } + } + angular.module('mgcrea.ngStrap.datepicker', [ 'mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip' ]).provider('$datepicker', function() { + var defaults = this.defaults = { + animation: 'am-fade', + prefixClass: 'datepicker', + placement: 'bottom-left', + templateUrl: 'datepicker/datepicker.tpl.html', + trigger: 'focus', + container: false, + keyboard: true, + html: false, + delay: 0, + useNative: false, + dateType: 'date', + dateFormat: 'shortDate', + timezone: null, + modelDateFormat: null, + dayFormat: 'dd', + monthFormat: 'MMM', + yearFormat: 'yyyy', + monthTitleFormat: 'MMMM yyyy', + yearTitleFormat: 'yyyy', + strictFormat: false, + autoclose: false, + minDate: -Infinity, + maxDate: +Infinity, + startView: 0, + minView: 0, + startWeek: 0, + daysOfWeekDisabled: '', + hasToday: false, + hasClear: false, + iconLeft: 'glyphicon glyphicon-chevron-left', + iconRight: 'glyphicon glyphicon-chevron-right' + }; + this.$get = [ '$window', '$document', '$rootScope', '$sce', '$dateFormatter', 'datepickerViews', '$tooltip', '$timeout', function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) { + var isNative = /(ip[ao]d|iphone|android)/gi.test($window.navigator.userAgent); + var isTouch = 'createTouch' in $window.document && isNative; + if (!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale(); + function DatepickerFactory(element, controller, config) { + var $datepicker = $tooltip(element, angular.extend({}, defaults, config)); + var parentScope = config.scope; + var options = $datepicker.$options; + var scope = $datepicker.$scope; + if (options.startView) options.startView -= options.minView; + var pickerViews = datepickerViews($datepicker); + $datepicker.$views = pickerViews.views; + var viewDate = pickerViews.viewDate; + scope.$mode = options.startView; + scope.$iconLeft = options.iconLeft; + scope.$iconRight = options.iconRight; + scope.$hasToday = options.hasToday; + scope.$hasClear = options.hasClear; + var $picker = $datepicker.$views[scope.$mode]; + scope.$select = function(date) { + $datepicker.select(date); + }; + scope.$selectPane = function(value) { + $datepicker.$selectPane(value); + }; + scope.$toggleMode = function() { + $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length); + }; + scope.$setToday = function() { + if (options.autoclose) { + $datepicker.setMode(0); + $datepicker.select(new Date()); + } else { + $datepicker.select(new Date(), true); + } + }; + scope.$clear = function() { + if (options.autoclose) { + $datepicker.setMode(0); + $datepicker.select(null); + } else { + $datepicker.select(null, true); + } + }; + $datepicker.update = function(date) { + if (angular.isDate(date) && !isNaN(date.getTime())) { + $datepicker.$date = date; + $picker.update.call($picker, date); + } + $datepicker.$build(true); + }; + $datepicker.updateDisabledDates = function(dateRanges) { + options.disabledDateRanges = dateRanges; + for (var i = 0, l = scope.rows.length; i < l; i++) { + angular.forEach(scope.rows[i], $datepicker.$setDisabledEl); + } + }; + $datepicker.select = function(date, keep) { + if (angular.isDate(date)) { + if (!angular.isDate(controller.$dateValue) || isNaN(controller.$dateValue.getTime())) { + controller.$dateValue = new Date(date); + } + } else { + controller.$dateValue = null; + } + if (!scope.$mode || keep) { + controller.$setViewValue(angular.copy(date)); + controller.$render(); + if (options.autoclose && !keep) { + $timeout(function() { + $datepicker.hide(true); + }); + } + } else { + angular.extend(viewDate, { + year: date.getFullYear(), + month: date.getMonth(), + date: date.getDate() + }); + $datepicker.setMode(scope.$mode - 1); + $datepicker.$build(); + } + }; + $datepicker.setMode = function(mode) { + scope.$mode = mode; + $picker = $datepicker.$views[scope.$mode]; + $datepicker.$build(); + }; + $datepicker.$build = function(pristine) { + if (pristine === true && $picker.built) return; + if (pristine === false && !$picker.built) return; + $picker.build.call($picker); + }; + $datepicker.$updateSelected = function() { + for (var i = 0, l = scope.rows.length; i < l; i++) { + angular.forEach(scope.rows[i], updateSelected); + } + }; + $datepicker.$isSelected = function(date) { + return $picker.isSelected(date); + }; + $datepicker.$setDisabledEl = function(el) { + el.disabled = $picker.isDisabled(el.date); + }; + $datepicker.$selectPane = function(value) { + var steps = $picker.steps; + var targetDate = new Date(Date.UTC(viewDate.year + (steps.year || 0) * value, viewDate.month + (steps.month || 0) * value, 1)); + angular.extend(viewDate, { + year: targetDate.getUTCFullYear(), + month: targetDate.getUTCMonth(), + date: targetDate.getUTCDate() + }); + $datepicker.$build(); + }; + $datepicker.$onMouseDown = function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + if (isTouch) { + var targetEl = angular.element(evt.target); + if (targetEl[0].nodeName.toLowerCase() !== 'button') { + targetEl = targetEl.parent(); + } + targetEl.triggerHandler('click'); + } + }; + $datepicker.$onKeyDown = function(evt) { + if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return; + evt.preventDefault(); + evt.stopPropagation(); + if (evt.keyCode === 13) { + if (!scope.$mode) { + $datepicker.hide(true); + } else { + scope.$apply(function() { + $datepicker.setMode(scope.$mode - 1); + }); + } + return; + } + $picker.onKeyDown(evt); + parentScope.$digest(); + }; + function updateSelected(el) { + el.selected = $datepicker.$isSelected(el.date); + } + function focusElement() { + element[0].focus(); + } + var _init = $datepicker.init; + $datepicker.init = function() { + if (isNative && options.useNative) { + element.prop('type', 'date'); + element.css('-webkit-appearance', 'textfield'); + return; + } else if (isTouch) { + element.prop('type', 'text'); + element.attr('readonly', 'true'); + element.on('click', focusElement); + } + _init(); + }; + var _destroy = $datepicker.destroy; + $datepicker.destroy = function() { + if (isNative && options.useNative) { + element.off('click', focusElement); + } + _destroy(); + }; + var _show = $datepicker.show; + $datepicker.show = function() { + if (!isTouch && element.attr('readonly') || element.attr('disabled')) return; + _show(); + $timeout(function() { + if (!$datepicker.$isShown) return; + $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown); + if (options.keyboard) { + element.on('keydown', $datepicker.$onKeyDown); + } + }, 0, false); + }; + var _hide = $datepicker.hide; + $datepicker.hide = function(blur) { + if (!$datepicker.$isShown) return; + $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown); + if (options.keyboard) { + element.off('keydown', $datepicker.$onKeyDown); + } + _hide(blur); + }; + return $datepicker; + } + DatepickerFactory.defaults = defaults; + return DatepickerFactory; + } ]; + }).directive('bsDatepicker', [ '$window', '$parse', '$q', '$dateFormatter', '$dateParser', '$datepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) { + var isNative = /(ip[ao]d|iphone|android)/gi.test($window.navigator.userAgent); + return { + restrict: 'EAC', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + var options = { + scope: scope + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent', 'hasToday', 'hasClear' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'html', 'container', 'autoclose', 'useNative', 'hasToday', 'hasClear' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) { + options[key] = false; + } + }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + var datepicker = $datepicker(element, controller, options); + options = datepicker.$options; + if (isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd'; + var lang = options.lang; + var formatDate = function(date, format) { + return $dateFormatter.formatDate(date, format, lang); + }; + var dateParser = $dateParser({ + format: options.dateFormat, + lang: lang, + strict: options.strictFormat + }); + if (attr.bsShow) { + scope.$watch(attr.bsShow, function(newValue, oldValue) { + if (!datepicker || !angular.isDefined(newValue)) return; + if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i); + if (newValue === true) { + datepicker.show(); + } else { + datepicker.hide(); + } + }); + } + angular.forEach([ 'minDate', 'maxDate' ], function(key) { + if (angular.isDefined(attr[key])) { + attr.$observe(key, function(newValue) { + datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue); + if (!isNaN(datepicker.$options[key])) datepicker.$build(false); + validateAgainstMinMaxDate(controller.$dateValue); + }); + } + }); + if (angular.isDefined(attr.dateFormat)) { + attr.$observe('dateFormat', function(newValue) { + datepicker.$options.dateFormat = newValue; + }); + } + scope.$watch(attr.ngModel, function(newValue, oldValue) { + datepicker.update(controller.$dateValue); + }, true); + function normalizeDateRanges(ranges) { + if (!ranges || !ranges.length) return null; + return ranges; + } + if (angular.isDefined(attr.disabledDates)) { + scope.$watch(attr.disabledDates, function(disabledRanges, previousValue) { + disabledRanges = normalizeDateRanges(disabledRanges); + previousValue = normalizeDateRanges(previousValue); + if (disabledRanges) { + datepicker.updateDisabledDates(disabledRanges); + } + }); + } + function validateAgainstMinMaxDate(parsedDate) { + if (!angular.isDate(parsedDate)) return; + var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate; + var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate; + var isValid = isMinValid && isMaxValid; + controller.$setValidity('date', isValid); + controller.$setValidity('min', isMinValid); + controller.$setValidity('max', isMaxValid); + if (isValid) controller.$dateValue = parsedDate; + } + controller.$parsers.unshift(function(viewValue) { + var date; + if (!viewValue) { + controller.$setValidity('date', true); + return null; + } + var parsedDate = dateParser.parse(viewValue, controller.$dateValue); + if (!parsedDate || isNaN(parsedDate.getTime())) { + controller.$setValidity('date', false); + return; + } + validateAgainstMinMaxDate(parsedDate); + if (options.dateType === 'string') { + date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true); + return formatDate(date, options.modelDateFormat || options.dateFormat); + } + date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true); + if (options.dateType === 'number') { + return date.getTime(); + } else if (options.dateType === 'unix') { + return date.getTime() / 1e3; + } else if (options.dateType === 'iso') { + return date.toISOString(); + } + return new Date(date); + }); + controller.$formatters.push(function(modelValue) { + var date; + if (angular.isUndefined(modelValue) || modelValue === null) { + date = NaN; + } else if (angular.isDate(modelValue)) { + date = modelValue; + } else if (options.dateType === 'string') { + date = dateParser.parse(modelValue, null, options.modelDateFormat); + } else if (options.dateType === 'unix') { + date = new Date(modelValue * 1e3); + } else { + date = new Date(modelValue); + } + controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone); + return getDateFormattedString(); + }); + controller.$render = function() { + element.val(getDateFormattedString()); + }; + function getDateFormattedString() { + return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat); + } + scope.$on('$destroy', function() { + if (datepicker) datepicker.destroy(); + options = null; + datepicker = null; + }); + } + }; + } ]).provider('datepickerViews', function() { + function split(arr, size) { + var arrays = []; + while (arr.length > 0) { + arrays.push(arr.splice(0, size)); + } + return arrays; + } + function mod(n, m) { + return (n % m + m) % m; + } + this.$get = [ '$dateFormatter', '$dateParser', '$sce', function($dateFormatter, $dateParser, $sce) { + return function(picker) { + var scope = picker.$scope; + var options = picker.$options; + var lang = options.lang; + var formatDate = function(date, format) { + return $dateFormatter.formatDate(date, format, lang); + }; + var dateParser = $dateParser({ + format: options.dateFormat, + lang: lang, + strict: options.strictFormat + }); + var weekDaysMin = $dateFormatter.weekdaysShort(lang); + var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek)); + var weekDaysLabelsHtml = $sce.trustAsHtml('' + weekDaysLabels.join('') + ''); + var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date()); + var viewDate = { + year: startDate.getFullYear(), + month: startDate.getMonth(), + date: startDate.getDate() + }; + var views = [ { + format: options.dayFormat, + split: 7, + steps: { + month: 1 + }, + update: function(date, force) { + if (!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) { + angular.extend(viewDate, { + year: picker.$date.getFullYear(), + month: picker.$date.getMonth(), + date: picker.$date.getDate() + }); + picker.$build(); + } else if (date.getDate() !== viewDate.date || date.getDate() === 1) { + viewDate.date = picker.$date.getDate(); + picker.$updateSelected(); + } + }, + build: function() { + var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1); + var firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset(); + var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5); + var firstDateOffset = firstDate.getTimezoneOffset(); + var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString(); + if (firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 6e4); + var days = []; + var day; + for (var i = 0; i < 42; i++) { + day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i)); + days.push({ + date: day, + isToday: day.toDateString() === today, + label: formatDate(day, this.format), + selected: picker.$date && this.isSelected(day), + muted: day.getMonth() !== viewDate.month, + disabled: this.isDisabled(day) + }); + } + scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat); + scope.showLabels = true; + scope.labels = weekDaysLabelsHtml; + scope.rows = split(days, this.split); + scope.isTodayDisabled = this.isDisabled(new Date()); + this.built = true; + }, + isSelected: function(date) { + return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate(); + }, + isDisabled: function(date) { + var time = date.getTime(); + if (time < options.minDate || time > options.maxDate) return true; + if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true; + if (options.disabledDateRanges) { + for (var i = 0; i < options.disabledDateRanges.length; i++) { + if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) { + return true; + } + } + } + return false; + }, + onKeyDown: function(evt) { + if (!picker.$date) { + return; + } + var actualTime = picker.$date.getTime(); + var newDate; + if (evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5); else if (evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5); else if (evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5); else if (evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5); + if (!this.isDisabled(newDate)) picker.select(newDate, true); + } + }, { + name: 'month', + format: options.monthFormat, + split: 4, + steps: { + year: 1 + }, + update: function(date, force) { + if (!this.built || date.getFullYear() !== viewDate.year) { + angular.extend(viewDate, { + year: picker.$date.getFullYear(), + month: picker.$date.getMonth(), + date: picker.$date.getDate() + }); + picker.$build(); + } else if (date.getMonth() !== viewDate.month) { + angular.extend(viewDate, { + month: picker.$date.getMonth(), + date: picker.$date.getDate() + }); + picker.$updateSelected(); + } + }, + build: function() { + var months = []; + var month; + for (var i = 0; i < 12; i++) { + month = new Date(viewDate.year, i, 1); + months.push({ + date: month, + label: formatDate(month, this.format), + selected: picker.$isSelected(month), + disabled: this.isDisabled(month) + }); + } + scope.title = formatDate(month, options.yearTitleFormat); + scope.showLabels = false; + scope.rows = split(months, this.split); + this.built = true; + }, + isSelected: function(date) { + return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth(); + }, + isDisabled: function(date) { + var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0); + return lastDate < options.minDate || date.getTime() > options.maxDate; + }, + onKeyDown: function(evt) { + if (!picker.$date) { + return; + } + var actualMonth = picker.$date.getMonth(); + var newDate = new Date(picker.$date); + if (evt.keyCode === 37) newDate.setMonth(actualMonth - 1); else if (evt.keyCode === 38) newDate.setMonth(actualMonth - 4); else if (evt.keyCode === 39) newDate.setMonth(actualMonth + 1); else if (evt.keyCode === 40) newDate.setMonth(actualMonth + 4); + if (!this.isDisabled(newDate)) picker.select(newDate, true); + } + }, { + name: 'year', + format: options.yearFormat, + split: 4, + steps: { + year: 12 + }, + update: function(date, force) { + if (!this.built || force || parseInt(date.getFullYear() / 20, 10) !== parseInt(viewDate.year / 20, 10)) { + angular.extend(viewDate, { + year: picker.$date.getFullYear(), + month: picker.$date.getMonth(), + date: picker.$date.getDate() + }); + picker.$build(); + } else if (date.getFullYear() !== viewDate.year) { + angular.extend(viewDate, { + year: picker.$date.getFullYear(), + month: picker.$date.getMonth(), + date: picker.$date.getDate() + }); + picker.$updateSelected(); + } + }, + build: function() { + var firstYear = viewDate.year - viewDate.year % (this.split * 3); + var years = []; + var year; + for (var i = 0; i < 12; i++) { + year = new Date(firstYear + i, 0, 1); + years.push({ + date: year, + label: formatDate(year, this.format), + selected: picker.$isSelected(year), + disabled: this.isDisabled(year) + }); + } + scope.title = years[0].label + '-' + years[years.length - 1].label; + scope.showLabels = false; + scope.rows = split(years, this.split); + this.built = true; + }, + isSelected: function(date) { + return picker.$date && date.getFullYear() === picker.$date.getFullYear(); + }, + isDisabled: function(date) { + var lastDate = +new Date(date.getFullYear() + 1, 0, 0); + return lastDate < options.minDate || date.getTime() > options.maxDate; + }, + onKeyDown: function(evt) { + if (!picker.$date) { + return; + } + var actualYear = picker.$date.getFullYear(); + var newDate = new Date(picker.$date); + if (evt.keyCode === 37) newDate.setYear(actualYear - 1); else if (evt.keyCode === 38) newDate.setYear(actualYear - 4); else if (evt.keyCode === 39) newDate.setYear(actualYear + 1); else if (evt.keyCode === 40) newDate.setYear(actualYear + 4); + if (!this.isDisabled(newDate)) picker.select(newDate, true); + } + } ]; + return { + views: options.minView ? Array.prototype.slice.call(views, options.minView) : views, + viewDate: viewDate + }; + }; + } ]; + }); + angular.module('mgcrea.ngStrap.button', []).provider('$button', function() { + var defaults = this.defaults = { + activeClass: 'active', + toggleEvent: 'click' + }; + this.$get = function() { + return { + defaults: defaults + }; + }; + }).directive('bsCheckboxGroup', function() { + return { + restrict: 'A', + require: 'ngModel', + compile: function postLink(element, attr) { + element.attr('data-toggle', 'buttons'); + element.removeAttr('ng-model'); + var children = element[0].querySelectorAll('input[type="checkbox"]'); + angular.forEach(children, function(child) { + var childEl = angular.element(child); + childEl.attr('bs-checkbox', ''); + childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value')); + }); + } + }; + }).directive('bsCheckbox', [ '$button', '$$rAF', function($button, $$rAF) { + var defaults = $button.defaults; + var constantValueRegExp = /^(true|false|\d+)$/; + return { + restrict: 'A', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + var options = defaults; + var isInput = element[0].nodeName === 'INPUT'; + var activeElement = isInput ? element.parent() : element; + var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true; + if (constantValueRegExp.test(attr.trueValue)) { + trueValue = scope.$eval(attr.trueValue); + } + var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false; + if (constantValueRegExp.test(attr.falseValue)) { + falseValue = scope.$eval(attr.falseValue); + } + var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean'; + if (hasExoticValues) { + controller.$parsers.push(function(viewValue) { + return viewValue ? trueValue : falseValue; + }); + controller.$formatters.push(function(modelValue) { + return angular.equals(modelValue, trueValue); + }); + scope.$watch(attr.ngModel, function(newValue, oldValue) { + controller.$render(); + }); + } + controller.$render = function() { + var isActive = angular.equals(controller.$modelValue, trueValue); + $$rAF(function() { + if (isInput) element[0].checked = isActive; + activeElement.toggleClass(options.activeClass, isActive); + }); + }; + element.bind(options.toggleEvent, function() { + scope.$apply(function() { + if (!isInput) { + controller.$setViewValue(!activeElement.hasClass('active')); + } + if (!hasExoticValues) { + controller.$render(); + } + }); + }); + } + }; + } ]).directive('bsRadioGroup', function() { + return { + restrict: 'A', + require: 'ngModel', + compile: function postLink(element, attr) { + element.attr('data-toggle', 'buttons'); + element.removeAttr('ng-model'); + var children = element[0].querySelectorAll('input[type="radio"]'); + angular.forEach(children, function(child) { + angular.element(child).attr('bs-radio', ''); + angular.element(child).attr('ng-model', attr.ngModel); + }); + } + }; + }).directive('bsRadio', [ '$button', '$$rAF', function($button, $$rAF) { + var defaults = $button.defaults; + var constantValueRegExp = /^(true|false|\d+)$/; + return { + restrict: 'A', + require: 'ngModel', + link: function postLink(scope, element, attr, controller) { + var options = defaults; + var isInput = element[0].nodeName === 'INPUT'; + var activeElement = isInput ? element.parent() : element; + var value; + attr.$observe('value', function(v) { + if (typeof v !== 'boolean' && constantValueRegExp.test(v)) { + value = scope.$eval(v); + } else { + value = v; + } + controller.$render(); + }); + controller.$render = function() { + var isActive = angular.equals(controller.$modelValue, value); + $$rAF(function() { + if (isInput) element[0].checked = isActive; + activeElement.toggleClass(options.activeClass, isActive); + }); + }; + element.bind(options.toggleEvent, function() { + scope.$apply(function() { + controller.$setViewValue(value); + controller.$render(); + }); + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.collapse', []).provider('$collapse', function() { + var defaults = this.defaults = { + animation: 'am-collapse', + disallowToggle: false, + activeClass: 'in', + startCollapsed: false, + allowMultiple: false + }; + var controller = this.controller = function($scope, $element, $attrs) { + var self = this; + self.$options = angular.copy(defaults); + angular.forEach([ 'animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple' ], function(key) { + if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'disallowToggle', 'startCollapsed', 'allowMultiple' ], function(key) { + if (angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) { + self.$options[key] = false; + } + }); + self.$toggles = []; + self.$targets = []; + self.$viewChangeListeners = []; + self.$registerToggle = function(element) { + self.$toggles.push(element); + }; + self.$registerTarget = function(element) { + self.$targets.push(element); + }; + self.$unregisterToggle = function(element) { + var index = self.$toggles.indexOf(element); + self.$toggles.splice(index, 1); + }; + self.$unregisterTarget = function(element) { + var index = self.$targets.indexOf(element); + self.$targets.splice(index, 1); + if (self.$options.allowMultiple) { + deactivateItem(element); + } + fixActiveItemIndexes(index); + self.$viewChangeListeners.forEach(function(fn) { + fn(); + }); + }; + self.$targets.$active = !self.$options.startCollapsed ? [ 0 ] : []; + self.$setActive = $scope.$setActive = function(value) { + if (angular.isArray(value)) { + self.$targets.$active = value; + } else if (!self.$options.disallowToggle && isActive(value)) { + deactivateItem(value); + } else { + activateItem(value); + } + self.$viewChangeListeners.forEach(function(fn) { + fn(); + }); + }; + self.$activeIndexes = function() { + if (self.$options.allowMultiple) { + return self.$targets.$active; + } + return self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1; + }; + function fixActiveItemIndexes(index) { + var activeIndexes = self.$targets.$active; + for (var i = 0; i < activeIndexes.length; i++) { + if (index < activeIndexes[i]) { + activeIndexes[i] = activeIndexes[i] - 1; + } + if (activeIndexes[i] === self.$targets.length) { + activeIndexes[i] = self.$targets.length - 1; + } + } + } + function isActive(value) { + var activeItems = self.$targets.$active; + return activeItems.indexOf(value) !== -1; + } + function deactivateItem(value) { + var index = self.$targets.$active.indexOf(value); + if (index !== -1) { + self.$targets.$active.splice(index, 1); + } + } + function activateItem(value) { + if (!self.$options.allowMultiple) { + self.$targets.$active.splice(0, 1); + } + if (self.$targets.$active.indexOf(value) === -1) { + self.$targets.$active.push(value); + } + } + }; + this.$get = function() { + var $collapse = {}; + $collapse.defaults = defaults; + $collapse.controller = controller; + return $collapse; + }; + }).directive('bsCollapse', [ '$window', '$animate', '$collapse', function($window, $animate, $collapse) { + return { + require: [ '?ngModel', 'bsCollapse' ], + controller: [ '$scope', '$element', '$attrs', $collapse.controller ], + link: function postLink(scope, element, attrs, controllers) { + var ngModelCtrl = controllers[0]; + var bsCollapseCtrl = controllers[1]; + if (ngModelCtrl) { + bsCollapseCtrl.$viewChangeListeners.push(function() { + ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes()); + }); + ngModelCtrl.$formatters.push(function(modelValue) { + if (angular.isArray(modelValue)) { + bsCollapseCtrl.$setActive(modelValue); + } else { + var activeIndexes = bsCollapseCtrl.$activeIndexes(); + if (angular.isArray(activeIndexes)) { + if (activeIndexes.indexOf(modelValue * 1) === -1) { + bsCollapseCtrl.$setActive(modelValue * 1); + } + } else if (activeIndexes !== modelValue * 1) { + bsCollapseCtrl.$setActive(modelValue * 1); + } + } + return modelValue; + }); + } + } + }; + } ]).directive('bsCollapseToggle', function() { + return { + require: [ '^?ngModel', '^bsCollapse' ], + link: function postLink(scope, element, attrs, controllers) { + var bsCollapseCtrl = controllers[1]; + element.attr('data-toggle', 'collapse'); + bsCollapseCtrl.$registerToggle(element); + scope.$on('$destroy', function() { + bsCollapseCtrl.$unregisterToggle(element); + }); + element.on('click', function() { + if (!attrs.disabled) { + var index = attrs.bsCollapseToggle && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element); + bsCollapseCtrl.$setActive(index * 1); + scope.$apply(); + } + }); + } + }; + }).directive('bsCollapseTarget', [ '$animate', function($animate) { + return { + require: [ '^?ngModel', '^bsCollapse' ], + link: function postLink(scope, element, attrs, controllers) { + var bsCollapseCtrl = controllers[1]; + element.addClass('collapse'); + if (bsCollapseCtrl.$options.animation) { + element.addClass(bsCollapseCtrl.$options.animation); + } + bsCollapseCtrl.$registerTarget(element); + scope.$on('$destroy', function() { + bsCollapseCtrl.$unregisterTarget(element); + }); + function render() { + var index = bsCollapseCtrl.$targets.indexOf(element); + var active = bsCollapseCtrl.$activeIndexes(); + var action = 'removeClass'; + if (angular.isArray(active)) { + if (active.indexOf(index) !== -1) { + action = 'addClass'; + } + } else if (index === active) { + action = 'addClass'; + } + $animate[action](element, bsCollapseCtrl.$options.activeClass); + } + bsCollapseCtrl.$viewChangeListeners.push(function() { + render(); + }); + render(); + } + }; + } ]); + angular.module('mgcrea.ngStrap.aside', [ 'mgcrea.ngStrap.modal' ]).provider('$aside', function() { + var defaults = this.defaults = { + animation: 'am-fade-and-slide-right', + prefixClass: 'aside', + prefixEvent: 'aside', + placement: 'right', + templateUrl: 'aside/aside.tpl.html', + contentTemplate: false, + container: false, + element: null, + backdrop: true, + keyboard: true, + html: false, + show: true + }; + this.$get = [ '$modal', function($modal) { + function AsideFactory(config) { + var $aside = {}; + var options = angular.extend({}, defaults, config); + $aside = $modal(options); + return $aside; + } + return AsideFactory; + } ]; + }).directive('bsAside', [ '$window', '$sce', '$aside', function($window, $sce, $aside) { + return { + restrict: 'EAC', + scope: true, + link: function postLink(scope, element, attr, transclusion) { + var options = { + scope: scope, + element: element, + show: false + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'backdrop', 'keyboard', 'html', 'container' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + angular.forEach([ 'title', 'content' ], function(key) { + if (attr[key]) { + attr.$observe(key, function(newValue, oldValue) { + scope[key] = $sce.trustAsHtml(newValue); + }); + } + }); + if (attr.bsAside) { + scope.$watch(attr.bsAside, function(newValue, oldValue) { + if (angular.isObject(newValue)) { + angular.extend(scope, newValue); + } else { + scope.content = newValue; + } + }, true); + } + var aside = $aside(options); + element.on(attr.trigger || 'click', aside.toggle); + scope.$on('$destroy', function() { + if (aside) aside.destroy(); + options = null; + aside = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.alert', [ 'mgcrea.ngStrap.modal' ]).provider('$alert', function() { + var defaults = this.defaults = { + animation: 'am-fade', + prefixClass: 'alert', + prefixEvent: 'alert', + placement: null, + templateUrl: 'alert/alert.tpl.html', + container: false, + element: null, + backdrop: false, + keyboard: true, + show: true, + duration: false, + type: false, + dismissable: true + }; + this.$get = [ '$modal', '$timeout', function($modal, $timeout) { + function AlertFactory(config) { + var $alert = {}; + var options = angular.extend({}, defaults, config); + $alert = $modal(options); + $alert.$scope.dismissable = !!options.dismissable; + if (options.type) { + $alert.$scope.type = options.type; + } + var show = $alert.show; + if (options.duration) { + $alert.show = function() { + show(); + $timeout(function() { + $alert.hide(); + }, options.duration * 1e3); + }; + } + return $alert; + } + return AlertFactory; + } ]; + }).directive('bsAlert', [ '$window', '$sce', '$alert', function($window, $sce, $alert) { + return { + restrict: 'EAC', + scope: true, + link: function postLink(scope, element, attr, transclusion) { + var options = { + scope: scope, + element: element, + show: false + }; + angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable' ], function(key) { + if (angular.isDefined(attr[key])) options[key] = attr[key]; + }); + var falseValueRegExp = /^(false|0|)$/i; + angular.forEach([ 'keyboard', 'html', 'container', 'dismissable' ], function(key) { + if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false; + }); + angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) { + var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1); + if (angular.isDefined(attr[bsKey])) { + options[key] = scope.$eval(attr[bsKey]); + } + }); + if (!scope.hasOwnProperty('title')) { + scope.title = ''; + } + angular.forEach([ 'title', 'content', 'type' ], function(key) { + if (attr[key]) { + attr.$observe(key, function(newValue, oldValue) { + scope[key] = $sce.trustAsHtml(newValue); + }); + } + }); + if (attr.bsAlert) { + scope.$watch(attr.bsAlert, function(newValue, oldValue) { + if (angular.isObject(newValue)) { + angular.extend(scope, newValue); + } else { + scope.content = newValue; + } + }, true); + } + var alert = $alert(options); + element.on(attr.trigger || 'click', alert.toggle); + scope.$on('$destroy', function() { + if (alert) alert.destroy(); + options = null; + alert = null; + }); + } + }; + } ]); + angular.module('mgcrea.ngStrap.affix', [ 'mgcrea.ngStrap.helpers.dimensions', 'mgcrea.ngStrap.helpers.debounce' ]).provider('$affix', function() { + var defaults = this.defaults = { + offsetTop: 'auto', + inlineStyles: true + }; + this.$get = [ '$window', 'debounce', 'dimensions', function($window, debounce, dimensions) { + var bodyEl = angular.element($window.document.body); + var windowEl = angular.element($window); + function AffixFactory(element, config) { + var $affix = {}; + var options = angular.extend({}, defaults, config); + var targetEl = options.target; + var reset = 'affix affix-top affix-bottom'; + var setWidth = false; + var initialAffixTop = 0; + var initialOffsetTop = 0; + var offsetTop = 0; + var offsetBottom = 0; + var affixed = null; + var unpin = null; + var parent = element.parent(); + if (options.offsetParent) { + if (options.offsetParent.match(/^\d+$/)) { + for (var i = 0; i < options.offsetParent * 1 - 1; i++) { + parent = parent.parent(); + } + } else { + parent = angular.element(options.offsetParent); + } + } + $affix.init = function() { + this.$parseOffsets(); + initialOffsetTop = dimensions.offset(element[0]).top + initialAffixTop; + setWidth = !element[0].style.width; + targetEl.on('scroll', this.checkPosition); + targetEl.on('click', this.checkPositionWithEventLoop); + windowEl.on('resize', this.$debouncedOnResize); + this.checkPosition(); + this.checkPositionWithEventLoop(); + }; + $affix.destroy = function() { + targetEl.off('scroll', this.checkPosition); + targetEl.off('click', this.checkPositionWithEventLoop); + windowEl.off('resize', this.$debouncedOnResize); + }; + $affix.checkPositionWithEventLoop = function() { + setTimeout($affix.checkPosition, 1); + }; + $affix.checkPosition = function() { + var scrollTop = getScrollTop(); + var position = dimensions.offset(element[0]); + var elementHeight = dimensions.height(element[0]); + var affix = getRequiredAffixClass(unpin, position, elementHeight); + if (affixed === affix) return; + affixed = affix; + if (affix === 'top') { + unpin = null; + if (setWidth) { + element.css('width', ''); + } + if (options.inlineStyles) { + element.css('position', options.offsetParent ? '' : 'relative'); + element.css('top', ''); + } + } else if (affix === 'bottom') { + if (options.offsetUnpin) { + unpin = -(options.offsetUnpin * 1); + } else { + unpin = position.top - scrollTop; + } + if (setWidth) { + element.css('width', ''); + } + if (options.inlineStyles) { + element.css('position', options.offsetParent ? '' : 'relative'); + element.css('top', options.offsetParent ? '' : bodyEl[0].offsetHeight - offsetBottom - elementHeight - initialOffsetTop + 'px'); + } + } else { + unpin = null; + if (setWidth) { + element.css('width', element[0].offsetWidth + 'px'); + } + if (options.inlineStyles) { + element.css('position', 'fixed'); + element.css('top', initialAffixTop + 'px'); + } + } + element.removeClass(reset).addClass('affix' + (affix !== 'middle' ? '-' + affix : '')); + }; + $affix.$onResize = function() { + $affix.$parseOffsets(); + $affix.checkPosition(); + }; + $affix.$debouncedOnResize = debounce($affix.$onResize, 50); + $affix.$parseOffsets = function() { + var initialPosition = element.css('position'); + if (options.inlineStyles) { + element.css('position', options.offsetParent ? '' : 'relative'); + } + if (options.offsetTop) { + if (options.offsetTop === 'auto') { + options.offsetTop = '+0'; + } + if (options.offsetTop.match(/^[-+]\d+$/)) { + initialAffixTop = -options.offsetTop * 1; + if (options.offsetParent) { + offsetTop = dimensions.offset(parent[0]).top + options.offsetTop * 1; + } else { + offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + options.offsetTop * 1; + } + } else { + offsetTop = options.offsetTop * 1; + } + } + if (options.offsetBottom) { + if (options.offsetParent && options.offsetBottom.match(/^[-+]\d+$/)) { + offsetBottom = getScrollHeight() - (dimensions.offset(parent[0]).top + dimensions.height(parent[0])) + options.offsetBottom * 1 + 1; + } else { + offsetBottom = options.offsetBottom * 1; + } + } + if (options.inlineStyles) { + element.css('position', initialPosition); + } + }; + function getRequiredAffixClass(_unpin, position, elementHeight) { + var scrollTop = getScrollTop(); + var scrollHeight = getScrollHeight(); + if (scrollTop <= offsetTop) { + return 'top'; + } else if (_unpin !== null && scrollTop + _unpin <= position.top) { + return 'middle'; + } else if (offsetBottom !== null && position.top + elementHeight + initialAffixTop >= scrollHeight - offsetBottom) { + return 'bottom'; + } + return 'middle'; + } + function getScrollTop() { + return targetEl[0] === $window ? $window.pageYOffset : targetEl[0].scrollTop; + } + function getScrollHeight() { + return targetEl[0] === $window ? $window.document.body.scrollHeight : targetEl[0].scrollHeight; + } + $affix.init(); + return $affix; + } + return AffixFactory; + } ]; + }).directive('bsAffix', [ '$affix', '$window', function($affix, $window) { + return { + restrict: 'EAC', + require: '^?bsAffixTarget', + link: function postLink(scope, element, attr, affixTarget) { + var options = { + scope: scope, + target: affixTarget ? affixTarget.$element : angular.element($window) + }; + angular.forEach([ 'offsetTop', 'offsetBottom', 'offsetParent', 'offsetUnpin', 'inlineStyles' ], function(key) { + if (angular.isDefined(attr[key])) { + var option = attr[key]; + if (/true/i.test(option)) option = true; + if (/false/i.test(option)) option = false; + options[key] = option; + } + }); + var affix = $affix(element, options); + scope.$on('$destroy', function() { + if (affix) affix.destroy(); + options = null; + affix = null; + }); + } + }; + } ]).directive('bsAffixTarget', function() { + return { + controller: [ '$element', function($element) { + this.$element = $element; + } ] + }; + }); + angular.module('mgcrea.ngStrap', [ 'mgcrea.ngStrap.modal', 'mgcrea.ngStrap.aside', 'mgcrea.ngStrap.alert', 'mgcrea.ngStrap.button', 'mgcrea.ngStrap.select', 'mgcrea.ngStrap.datepicker', 'mgcrea.ngStrap.timepicker', 'mgcrea.ngStrap.navbar', 'mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.popover', 'mgcrea.ngStrap.dropdown', 'mgcrea.ngStrap.typeahead', 'mgcrea.ngStrap.scrollspy', 'mgcrea.ngStrap.affix', 'mgcrea.ngStrap.tab', 'mgcrea.ngStrap.collapse' ]); })(window, document); \ No newline at end of file diff --git a/InventoryTraker.Web/Scripts/angular-strap.min.js b/InventoryTraker.Web/Scripts/angular-strap.min.js index 36e53f8..b453acb 100644 --- a/InventoryTraker.Web/Scripts/angular-strap.min.js +++ b/InventoryTraker.Web/Scripts/angular-strap.min.js @@ -1,12 +1,11 @@ /** * angular-strap - * @version v2.3.1 - 2015-07-19 + * @version v2.3.9 - 2016-06-10 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -!function(e,t,n){'use strict';function a(e,n,a,o,i,r){function s(e,n){return angular.element((n||t).querySelectorAll(e))}function l(e){return u[e]?u[e]:u[e]=n.get(e,{cache:r}).then(function(e){return e.data})}this.compile=function(t){t.template&&/\.html$/.test(t.template)&&(console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.'),t.templateUrl=t.template,t.template='');var n=t.templateUrl,r=t.template||'',u=t.controller,c=t.controllerAs,d=angular.copy(t.resolve||{}),f=angular.copy(t.locals||{}),p=t.transformTemplate||angular.identity,g=t.bindToController;return angular.forEach(d,function(e,t){d[t]=angular.isString(e)?a.get(e):a.invoke(e)}),angular.extend(d,f),d.$template=n?l(n):e.when(r),t.contentTemplate&&(d.$template=e.all([d.$template,l(t.contentTemplate)]).then(function(e){var n=angular.element(e[0]),a=s('[ng-bind="content"]',n[0]).removeAttr('ng-bind').html(e[1]);return t.templateUrl||a.next().remove(),n[0].outerHTML})),e.all(d).then(function(e){var n=p(e.$template);t.html&&(n=n.replace(/ng-bind="/gi,'ng-bind-html="'));var a=angular.element('
').html(n.trim()).contents(),r=o(a);return{locals:e,element:a,link:function(t){if(e.$scope=t,u){var n=i(u,e,!0);g&&angular.extend(n.instance,e);var o=angular.isObject(n)?n:n();a.data('$ngControllerController',o),a.children().data('$ngControllerController',o),c&&(t[c]=o)}return r.apply(null,arguments)}}})};var u={}}angular.module('mgcrea.ngStrap',['mgcrea.ngStrap.modal','mgcrea.ngStrap.aside','mgcrea.ngStrap.alert','mgcrea.ngStrap.button','mgcrea.ngStrap.select','mgcrea.ngStrap.datepicker','mgcrea.ngStrap.timepicker','mgcrea.ngStrap.navbar','mgcrea.ngStrap.tooltip','mgcrea.ngStrap.popover','mgcrea.ngStrap.dropdown','mgcrea.ngStrap.typeahead','mgcrea.ngStrap.scrollspy','mgcrea.ngStrap.affix','mgcrea.ngStrap.tab','mgcrea.ngStrap.collapse']),angular.module('mgcrea.ngStrap.affix',['mgcrea.ngStrap.helpers.dimensions','mgcrea.ngStrap.helpers.debounce']).provider('$affix',function(){var e=this.defaults={offsetTop:'auto',inlineStyles:!0};this.$get=['$window','debounce','dimensions',function(t,n,a){function o(o,s){function l(e,t,n){var a=u(),o=c();return v>=a?'top':null!==e&&a+e<=t.top?'middle':null!==w&&t.top+n+$>=o-w?'bottom':'middle'}function u(){return p[0]===t?t.pageYOffset:p[0].scrollTop}function c(){return p[0]===t?t.document.body.scrollHeight:p[0].scrollHeight}var d={},f=angular.extend({},e,s),p=f.target,g='affix affix-top affix-bottom',m=!1,$=0,h=0,v=0,w=0,y=null,b=null,D=o.parent();if(f.offsetParent)if(f.offsetParent.match(/^\d+$/))for(var k=0;k<1*f.offsetParent-1;k++)D=D.parent();else D=angular.element(f.offsetParent);return d.init=function(){this.$parseOffsets(),h=a.offset(o[0]).top+$,m=!o[0].style.width,p.on('scroll',this.checkPosition),p.on('click',this.checkPositionWithEventLoop),r.on('resize',this.$debouncedOnResize),this.checkPosition(),this.checkPositionWithEventLoop()},d.destroy=function(){p.off('scroll',this.checkPosition),p.off('click',this.checkPositionWithEventLoop),r.off('resize',this.$debouncedOnResize)},d.checkPositionWithEventLoop=function(){setTimeout(d.checkPosition,1)},d.checkPosition=function(){var e=u(),t=a.offset(o[0]),n=a.height(o[0]),r=l(b,t,n);y!==r&&(y=r,o.removeClass(g).addClass('affix'+('middle'!==r?'-'+r:'')),'top'===r?(b=null,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',''))):'bottom'===r?(b=f.offsetUnpin?-(1*f.offsetUnpin):t.top-e,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',f.offsetParent?'':i[0].offsetHeight-w-n-h+'px'))):(b=null,m&&o.css('width',o[0].offsetWidth+'px'),f.inlineStyles&&(o.css('position','fixed'),o.css('top',$+'px'))))},d.$onResize=function(){d.$parseOffsets(),d.checkPosition()},d.$debouncedOnResize=n(d.$onResize,50),d.$parseOffsets=function(){var e=o.css('position');f.inlineStyles&&o.css('position',f.offsetParent?'':'relative'),f.offsetTop&&('auto'===f.offsetTop&&(f.offsetTop='+0'),f.offsetTop.match(/^[-+]\d+$/)?($=1*-f.offsetTop,v=f.offsetParent?a.offset(D[0]).top+1*f.offsetTop:a.offset(o[0]).top-a.css(o[0],'marginTop',!0)+1*f.offsetTop):v=1*f.offsetTop),f.offsetBottom&&(w=f.offsetParent&&f.offsetBottom.match(/^[-+]\d+$/)?c()-(a.offset(D[0]).top+a.height(D[0]))+1*f.offsetBottom+1:1*f.offsetBottom),f.inlineStyles&&o.css('position',e)},d.init(),d}var i=angular.element(t.document.body),r=angular.element(t);return o}]}).directive('bsAffix',['$affix','$window',function(e,t){return{restrict:'EAC',require:'^?bsAffixTarget',link:function(n,a,o,i){var r={scope:n,target:i?i.$element:angular.element(t)};angular.forEach(['offsetTop','offsetBottom','offsetParent','offsetUnpin','inlineStyles'],function(e){if(angular.isDefined(o[e])){var t=o[e];/true/i.test(t)&&(t=!0),/false/i.test(t)&&(t=!1),r[e]=t}});var s=e(a,r);n.$on('$destroy',function(){s&&s.destroy(),r=null,s=null})}}}]).directive('bsAffixTarget',function(){return{controller:['$element',function(e){this.$element=e}]}}),angular.module('mgcrea.ngStrap.alert',['mgcrea.ngStrap.modal']).provider('$alert',function(){var e=this.defaults={animation:'am-fade',prefixClass:'alert',prefixEvent:'alert',placement:null,templateUrl:'alert/alert.tpl.html',container:!1,element:null,backdrop:!1,keyboard:!0,show:!0,duration:!1,type:!1,dismissable:!0};this.$get=['$modal','$timeout',function(t,n){function a(a){var o={},i=angular.extend({},e,a);o=t(i),o.$scope.dismissable=!!i.dismissable,i.type&&(o.$scope.type=i.type);var r=o.show;return i.duration&&(o.show=function(){r(),n(function(){o.hide()},1e3*i.duration)}),o}return a}]}).directive('bsAlert',['$window','$sce','$alert',function(e,t,n){e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','templateUrl','controller','controllerAs','placement','keyboard','html','container','animation','duration','dismissable'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['keyboard','html','container','dismissable'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),e.hasOwnProperty('title')||(e.title=''),angular.forEach(['title','content','type'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsAlert&&e.$watch(o.bsAlert,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.module('mgcrea.ngStrap.aside',['mgcrea.ngStrap.modal']).provider('$aside',function(){var e=this.defaults={animation:'am-fade-and-slide-right',prefixClass:'aside',prefixEvent:'aside',placement:'right',templateUrl:'aside/aside.tpl.html',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$modal',function(t){function n(n){var a={},o=angular.extend({},e,n);return a=t(o)}return n}]}).directive('bsAside',['$window','$sce','$aside',function(e,t,n){e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','backdrop','keyboard','html','container','animation'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),angular.forEach(['title','content'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsAside&&e.$watch(o.bsAside,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.module('mgcrea.ngStrap.button',[]).provider('$button',function(){var e=this.defaults={activeClass:'active',toggleEvent:'click'};this.$get=function(){return{defaults:e}}}).directive('bsCheckboxGroup',function(){return{restrict:'A',require:'ngModel',compile:function(e,t){e.attr('data-toggle','buttons'),e.removeAttr('ng-model');var n=e[0].querySelectorAll('input[type="checkbox"]');angular.forEach(n,function(e){var n=angular.element(e);n.attr('bs-checkbox',''),n.attr('ng-model',t.ngModel+'.'+n.attr('value'))})}}}).directive('bsCheckbox',['$button','$$rAF',function(e,t){var n=e.defaults,a=/^(true|false|\d+)$/;return{restrict:'A',require:'ngModel',link:function(e,o,i,r){var s=n,l='INPUT'===o[0].nodeName,u=l?o.parent():o,c=angular.isDefined(i.trueValue)?i.trueValue:!0;a.test(i.trueValue)&&(c=e.$eval(i.trueValue));var d=angular.isDefined(i.falseValue)?i.falseValue:!1;a.test(i.falseValue)&&(d=e.$eval(i.falseValue));var f='boolean'!=typeof c||'boolean'!=typeof d;f&&(r.$parsers.push(function(e){return e?c:d}),r.$formatters.push(function(e){return angular.equals(e,c)}),e.$watch(i.ngModel,function(e,t){r.$render()})),r.$render=function(){var e=angular.equals(r.$modelValue,c);t(function(){l&&(o[0].checked=e),u.toggleClass(s.activeClass,e)})},o.bind(s.toggleEvent,function(){e.$apply(function(){l||r.$setViewValue(!u.hasClass('active')),f||r.$render()})})}}}]).directive('bsRadioGroup',function(){return{restrict:'A',require:'ngModel',compile:function(e,t){e.attr('data-toggle','buttons'),e.removeAttr('ng-model');var n=e[0].querySelectorAll('input[type="radio"]');angular.forEach(n,function(e){angular.element(e).attr('bs-radio',''),angular.element(e).attr('ng-model',t.ngModel)})}}}).directive('bsRadio',['$button','$$rAF',function(e,t){var n=e.defaults,a=/^(true|false|\d+)$/;return{restrict:'A',require:'ngModel',link:function(e,o,i,r){var s,l=n,u='INPUT'===o[0].nodeName,c=u?o.parent():o;i.$observe('value',function(t){s=a.test(t)?e.$eval(t):t,r.$render()}),r.$render=function(){var e=angular.equals(r.$modelValue,s);t(function(){u&&(o[0].checked=e),c.toggleClass(l.activeClass,e)})},o.bind(l.toggleEvent,function(){e.$apply(function(){r.$setViewValue(s),r.$render()})})}}}]),angular.module('mgcrea.ngStrap.collapse',[]).provider('$collapse',function(){var e=this.defaults={animation:'am-collapse',disallowToggle:!1,activeClass:'in',startCollapsed:!1,allowMultiple:!1},t=this.controller=function(t,n,a){function o(e){for(var t=l.$targets.$active,n=0;nt;t++)angular.forEach(g.rows[t],u.$setDisabledEl)},u.select=function(e,t){angular.isDate(n.$dateValue)||(n.$dateValue=new Date(e)),!g.$mode||t?(n.$setViewValue(angular.copy(e)),n.$render(),p.autoclose&&!t&&l(function(){u.hide(!0)})):(angular.extend($,{year:e.getFullYear(),month:e.getMonth(),date:e.getDate()}),u.setMode(g.$mode-1),u.$build())},u.setMode=function(e){g.$mode=e,h=u.$views[g.$mode],u.$build()},u.$build=function(e){e===!0&&h.built||(e!==!1||h.built)&&h.build.call(h)},u.$updateSelected=function(){for(var e=0,t=g.rows.length;t>e;e++)angular.forEach(g.rows[e],o)},u.$isSelected=function(e){return h.isSelected(e)},u.$setDisabledEl=function(e){e.disabled=h.isDisabled(e.date)},u.$selectPane=function(e){var t=h.steps,n=new Date(Date.UTC($.year+(t.year||0)*e,$.month+(t.month||0)*e,1));angular.extend($,{year:n.getUTCFullYear(),month:n.getUTCMonth(),date:n.getUTCDate()}),u.$build()},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),d){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},u.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return g.$mode?g.$apply(function(){u.setMode(g.$mode-1)}):u.hide(!0);h.onKeyDown(e),f.$digest()}};var v=u.init;u.init=function(){return c&&p.useNative?(t.prop('type','date'),void t.css('-webkit-appearance','textfield')):(d&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',i)),void v())};var w=u.destroy;u.destroy=function(){c&&p.useNative&&t.off('click',i),w()};var y=u.show;u.show=function(){!d&&t.attr('readonly')||t.attr('disabled')||(y(),l(function(){u.$isShown&&(u.$element.on(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.on('keydown',u.$onKeyDown))},0,!1))};var b=u.hide;return u.hide=function(e){u.$isShown&&(u.$element.off(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.off('keydown',u.$onKeyDown),b(e))},u}var c=(angular.element(t.document.body),/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent)),d='createTouch'in t.document&&c;return e.lang||(e.lang=i.getDefaultLocale()),u.defaults=e,u}]}).directive('bsDatepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$datepicker',function(e,t,n,a,o,i){var r=(i.defaults,/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent));return{restrict:'EAC',require:'ngModel',link:function(e,t,n,s){function l(e){return e&&e.length?e:null}function u(e){if(angular.isDate(e)){var t=isNaN(p.$options.minDate)||e.getTime()>=p.$options.minDate,n=isNaN(p.$options.maxDate)||e.getTime()<=p.$options.maxDate,a=t&&n;s.$setValidity('date',a),s.$setValidity('min',t),s.$setValidity('max',n),a&&(s.$dateValue=e)}}function c(){return!s.$dateValue||isNaN(s.$dateValue.getTime())?'':m(s.$dateValue,d.dateFormat)}var d={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','html','animation','autoclose','dateType','dateFormat','timezone','modelDateFormat','dayFormat','strictFormat','startWeek','startDate','useNative','lang','startView','minView','iconLeft','iconRight','daysOfWeekDisabled','id','prefixClass','prefixEvent'],function(e){angular.isDefined(n[e])&&(d[e]=n[e])});var f=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative'],function(e){angular.isDefined(n[e])&&f.test(n[e])&&(d[e]=!1)}),n.bsShow&&e.$watch(n.bsShow,function(e,t){p&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(datepicker),?/i)),e===!0?p.show():p.hide())});var p=i(t,s,d);d=p.$options,r&&d.useNative&&(d.dateFormat='yyyy-MM-dd');var g=d.lang,m=function(e,t){return a.formatDate(e,t,g)},$=o({format:d.dateFormat,lang:g,strict:d.strictFormat});angular.forEach(['minDate','maxDate'],function(e){angular.isDefined(n[e])&&n.$observe(e,function(t){p.$options[e]=$.getDateForAttribute(e,t),!isNaN(p.$options[e])&&p.$build(!1),u(s.$dateValue)})}),e.$watch(n.ngModel,function(e,t){p.update(s.$dateValue)},!0),angular.isDefined(n.disabledDates)&&e.$watch(n.disabledDates,function(e,t){e=l(e),t=l(t),e&&p.updateDisabledDates(e)}),s.$parsers.unshift(function(e){var t;if(!e)return s.$setValidity('date',!0),null;var n=$.parse(e,s.$dateValue);return!n||isNaN(n.getTime())?void s.$setValidity('date',!1):(u(n),'string'===d.dateType?(t=$.timezoneOffsetAdjust(n,d.timezone,!0),m(t,d.modelDateFormat||d.dateFormat)):(t=$.timezoneOffsetAdjust(s.$dateValue,d.timezone,!0),'number'===d.dateType?t.getTime():'unix'===d.dateType?t.getTime()/1e3:'iso'===d.dateType?t.toISOString():new Date(t)))}),s.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?0/0:angular.isDate(e)?e:'string'===d.dateType?$.parse(e,null,d.modelDateFormat):new Date('unix'===d.dateType?1e3*e:e),s.$dateValue=$.timezoneOffsetAdjust(t,d.timezone),c()}),s.$render=function(){t.val(c())},e.$on('$destroy',function(){p&&p.destroy(),d=null,p=null})}}}]).provider('datepickerViews',function(){function e(e,t){for(var n=[];e.length>0;)n.push(e.splice(0,t));return n}function t(e,t){return(e%t+t)%t}this.defaults={dayFormat:'dd',daySplit:7};this.$get=['$dateFormatter','$dateParser','$sce',function(n,a,o){return function(i){var r=i.$scope,s=i.$options,l=s.lang,u=function(e,t){return n.formatDate(e,t,l)},c=a({format:s.dateFormat,lang:l,strict:s.strictFormat}),d=n.weekdaysShort(l),f=d.slice(s.startWeek).concat(d.slice(0,s.startWeek)),p=o.trustAsHtml(''+f.join('')+''),g=i.$date||(s.startDate?c.getDateForAttribute('startDate',s.startDate):new Date),m={year:g.getFullYear(),month:g.getMonth(),date:g.getDate()},$=[{format:s.dayFormat,split:7,steps:{month:1},update:function(e,t){!this.built||t||e.getFullYear()!==m.year||e.getMonth()!==m.month?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):(e.getDate()!==m.date||1===e.getDate())&&(m.date=i.$date.getDate(),i.$updateSelected())},build:function(){var n=new Date(m.year,m.month,1),a=n.getTimezoneOffset(),o=new Date(+n-864e5*t(n.getDay()-s.startWeek,7)),l=o.getTimezoneOffset(),d=c.timezoneOffsetAdjust(new Date,s.timezone).toDateString();l!==a&&(o=new Date(+o+6e4*(l-a)));for(var f,g=[],$=0;42>$;$++)f=c.daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth(),o.getDate()+$)),g.push({date:f,isToday:f.toDateString()===d,label:u(f,this.format),selected:i.$date&&this.isSelected(f),muted:f.getMonth()!==m.month,disabled:this.isDisabled(f)});r.title=u(n,s.monthTitleFormat),r.showLabels=!0,r.labels=p,r.rows=e(g,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()&&e.getDate()===i.$date.getDate()},isDisabled:function(e){var t=e.getTime();if(ts.maxDate)return!0;if(-1!==s.daysOfWeekDisabled.indexOf(e.getDay()))return!0;if(s.disabledDateRanges)for(var n=0;n=s.disabledDateRanges[n].start&&t<=s.disabledDateRanges[n].end)return!0;return!1},onKeyDown:function(e){if(i.$date){var t,n=i.$date.getTime();37===e.keyCode?t=new Date(n-864e5):38===e.keyCode?t=new Date(n-6048e5):39===e.keyCode?t=new Date(n+864e5):40===e.keyCode&&(t=new Date(n+6048e5)),this.isDisabled(t)||i.select(t,!0)}}},{name:'month',format:s.monthFormat,split:4,steps:{year:1},update:function(e,t){this.built&&e.getFullYear()===m.year?e.getMonth()!==m.month&&(angular.extend(m,{month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected()):(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build())},build:function(){for(var t,n=(new Date(m.year,0,1),[]),a=0;12>a;a++)t=new Date(m.year,a,1),n.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=u(t,s.yearTitleFormat),r.showLabels=!1,r.rows=e(n,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()},isDisabled:function(e){var t=+new Date(e.getFullYear(),e.getMonth()+1,0);return ts.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getMonth(),n=new Date(i.$date);37===e.keyCode?n.setMonth(t-1):38===e.keyCode?n.setMonth(t-4):39===e.keyCode?n.setMonth(t+1):40===e.keyCode&&n.setMonth(t+4),this.isDisabled(n)||i.select(n,!0)}}},{name:'year',format:s.yearFormat,split:4,steps:{year:12},update:function(e,t){!this.built||t||parseInt(e.getFullYear()/20,10)!==parseInt(m.year/20,10)?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):e.getFullYear()!==m.year&&(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected())},build:function(){for(var t,n=m.year-m.year%(3*this.split),a=[],o=0;12>o;o++)t=new Date(n+o,0,1),a.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=a[0].label+'-'+a[a.length-1].label,r.showLabels=!1,r.rows=e(a,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()},isDisabled:function(e){var t=+new Date(e.getFullYear()+1,0,0);return ts.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getFullYear(),n=new Date(i.$date);37===e.keyCode?n.setYear(t-1):38===e.keyCode?n.setYear(t-4):39===e.keyCode?n.setYear(t+1):40===e.keyCode&&n.setYear(t+4),this.isDisabled(n)||i.select(n,!0)}}}];return{views:s.minView?Array.prototype.slice.call($,s.minView):$,viewDate:m}}}]}),angular.module('mgcrea.ngStrap.dropdown',['mgcrea.ngStrap.tooltip']).provider('$dropdown',function(){var e=this.defaults={animation:'am-fade',prefixClass:'dropdown',prefixEvent:'dropdown',placement:'bottom-left',templateUrl:'dropdown/dropdown.tpl.html',trigger:'click',container:!1,keyboard:!0,html:!1,delay:0};this.$get=['$window','$rootScope','$tooltip','$timeout',function(t,n,a,o){function i(t,i){function l(e){return e.target!==t[0]?e.target!==t[0]&&u.hide():void 0}{var u={},c=angular.extend({},e,i);u.$scope=c.scope&&c.scope.$new()||n.$new()}u=a(t,c);var d=t.parent();u.$onKeyDown=function(e){if(/(38|40)/.test(e.keyCode)){e.preventDefault(),e.stopPropagation();var t=angular.element(u.$element[0].querySelectorAll('li:not(.divider) a'));if(t.length){var n;angular.forEach(t,function(e,t){s&&s.call(e,':focus')&&(n=t)}),38===e.keyCode&&n>0?n--:40===e.keyCode&&no;o++)if(e[o].toLowerCase()===a)return o;return-1}t.prototype.setMilliseconds=function(e){this.milliseconds=e},t.prototype.setSeconds=function(e){this.seconds=e},t.prototype.setMinutes=function(e){this.minutes=e},t.prototype.setHours=function(e){this.hours=e},t.prototype.getHours=function(){return this.hours},t.prototype.setDate=function(e){this.day=e},t.prototype.setMonth=function(e){this.month=e},t.prototype.setFullYear=function(e){this.year=e},t.prototype.fromDate=function(e){return this.year=e.getFullYear(),this.month=e.getMonth(),this.day=e.getDate(),this.hours=e.getHours(),this.minutes=e.getMinutes(),this.seconds=e.getSeconds(),this.milliseconds=e.getMilliseconds(),this},t.prototype.toDate=function(){return new Date(this.year,this.month,this.day,this.hours,this.minutes,this.seconds,this.milliseconds)};var i=t.prototype,r=this.defaults={format:'shortDate',strict:!1};this.$get=['$locale','dateFilter',function(e,s){var l=function(l){function u(e){var t,n=Object.keys(h),a=[],o=[],i=e;for(t=0;t1){var r=i.search(n[t]);e=e.split(n[t]).join(''),h[n[t]]&&(a[r]=h[n[t]])}return angular.forEach(a,function(e){e&&o.push(e)}),o}function c(e){return e.replace(/\//g,'[\\/]').replace('/-/g','[-]').replace(/\./g,'[.]').replace(/\\s/g,'[\\s]')}function d(e){var t,n=Object.keys($),a=e;for(t=0;t=1*e&&2===e.length?2e3+1*e:1*e)}};return m.init=function(){m.$format=e.DATETIME_FORMATS[g.format]||g.format,f=d(m.$format),p=u(m.$format)},m.isValid=function(e){return angular.isDate(e)?!isNaN(e.getTime()):f.test(e)},m.parse=function(n,a,o,i){o&&(o=e.DATETIME_FORMATS[o]||o),angular.isDate(n)&&(n=s(n,o||m.$format,i));var r=o?d(o):f,l=o?u(o):p,c=r.exec(n);if(!c)return!1;for(var g=(new t).fromDate(a&&!isNaN(a.getTime())?a:new Date(1970,0,1,0)),$=0;$12?e.getHours()+2:0),e):null},m.timezoneOffsetAdjust=function(e,t,n){return e?(t&&'UTC'===t&&(e=new Date(e.getTime()),e.setMinutes(e.getMinutes()+(n?-1:1)*e.getTimezoneOffset())),e):null},m.init(),m};return l}]}]),angular.module('mgcrea.ngStrap.helpers.debounce',[]).factory('debounce',['$timeout',function(e){return function(t,n,a){var o=null;return function(){var i=this,r=arguments,s=a&&!o;return o&&e.cancel(o),o=e(function(){o=null,a||t.apply(i,r)},n,!1),s&&t.apply(i,r),o}}}]).factory('throttle',['$timeout',function(e){return function(t,n,a){var o=null;return a||(a={}),function(){var i=this,r=arguments;o||(a.leading!==!1&&t.apply(i,r),o=e(function(){o=null,a.trailing!==!1&&t.apply(i,r)},n,!1))}}}]),angular.module('mgcrea.ngStrap.helpers.dimensions',[]).factory('dimensions',['$document','$window',function(t,n){var a=(angular.element,{}),o=a.nodeName=function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()};a.css=function(t,n,a){var o;return o=t.currentStyle?t.currentStyle[n]:e.getComputedStyle?e.getComputedStyle(t)[n]:t.style[n],a===!0?parseFloat(o)||0:o},a.offset=function(t){var n=t.getBoundingClientRect(),a=t.ownerDocument;return{width:n.width||t.offsetWidth,height:n.height||t.offsetHeight,top:n.top+(e.pageYOffset||a.documentElement.scrollTop)-(a.documentElement.clientTop||0),left:n.left+(e.pageXOffset||a.documentElement.scrollLeft)-(a.documentElement.clientLeft||0)}},a.setOffset=function(e,t,n){var o,i,r,s,l,u,c,d=a.css(e,'position'),f=angular.element(e),p={};'static'===d&&(e.style.position='relative'),l=a.offset(e),r=a.css(e,'top'),u=a.css(e,'left'),c=('absolute'===d||'fixed'===d)&&(r+u).indexOf('auto')>-1,c?(o=a.position(e),s=o.top,i=o.left):(s=parseFloat(r)||0,i=parseFloat(u)||0),angular.isFunction(t)&&(t=t.call(e,n,l)),null!==t.top&&(p.top=t.top-l.top+s),null!==t.left&&(p.left=t.left-l.left+i),'using'in t?t.using.call(f,p):f.css({top:p.top+'px',left:p.left+'px'})},a.position=function(e){var t,n,r={top:0,left:0};return'fixed'===a.css(e,'position')?n=e.getBoundingClientRect():(t=i(e),n=a.offset(e),o(t,'html')||(r=a.offset(t)),r.top+=a.css(t,'borderTopWidth',!0),r.left+=a.css(t,'borderLeftWidth',!0)),{width:e.offsetWidth,height:e.offsetHeight,top:n.top-r.top-a.css(e,'marginTop',!0),left:n.left-r.left-a.css(e,'marginLeft',!0)}};var i=function(e){var t=e.ownerDocument,n=e.offsetParent||t;if(o(n,'#document'))return t.documentElement;for(;n&&!o(n,'html')&&'static'===a.css(n,'position');)n=n.offsetParent;return n||t.documentElement};return a.height=function(e,t){var n=e.offsetHeight;return t?n+=a.css(e,'marginTop',!0)+a.css(e,'marginBottom',!0):n-=a.css(e,'paddingTop',!0)+a.css(e,'paddingBottom',!0)+a.css(e,'borderTopWidth',!0)+a.css(e,'borderBottomWidth',!0),n},a.width=function(e,t){var n=e.offsetWidth;return t?n+=a.css(e,'marginLeft',!0)+a.css(e,'marginRight',!0):n-=a.css(e,'paddingLeft',!0)+a.css(e,'paddingRight',!0)+a.css(e,'borderLeftWidth',!0)+a.css(e,'borderRightWidth',!0),n},a}]),angular.module('mgcrea.ngStrap.helpers.parseOptions',[]).provider('$parseOptions',function(){var e=this.defaults={regexp:/^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/};this.$get=['$parse','$q',function(t,n){function a(a,o){function i(e,t){return e.map(function(e,n){var a,o,i={};return i[c]=e,a=u(t,i),o=p(t,i),{label:a,value:o,index:n}})}var r={},s=angular.extend({},e,o);r.$values=[];var l,u,c,d,f,p,g;return r.init=function(){r.$match=l=a.match(s.regexp),u=t(l[2]||l[1]),c=l[4]||l[6],d=l[5],f=t(l[3]||''),p=t(l[2]?l[1]:c),g=t(l[7])},r.valuesFn=function(e,t){return n.when(g(e,t)).then(function(t){return angular.isArray(t)||(t=[]),r.$values=t.length?i(t,e):[],r.$values})},r.displayValue=function(e){var t={};return t[c]=e,u(t)},r.init(),r}return a}]}),angular.version.minor<3&&angular.version.dot<14&&angular.module('ng').factory('$$rAF',['$window','$timeout',function(e,t){var n=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame,a=e.cancelAnimationFrame||e.webkitCancelAnimationFrame||e.mozCancelAnimationFrame||e.webkitCancelRequestAnimationFrame,o=!!n,i=o?function(e){var t=n(e);return function(){a(t)}}:function(e){var n=t(e,16.66,!1);return function(){t.cancel(n)}};return i.supported=o,i}]),angular.module('mgcrea.ngStrap.modal',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$modal',function(){var e=this.defaults={animation:'am-fade',backdropAnimation:'am-fade',prefixClass:'modal',prefixEvent:'modal',placement:'top',templateUrl:'modal/modal.tpl.html',template:'',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0};this.$get=['$window','$rootScope','$bsCompiler','$q','$templateCache','$http','$animate','$timeout','$sce','dimensions',function(n,a,o,i,r,s,l,u,c,d){function f(t){function n(){k.$emit(b.prefixEvent+'.show',y)}function i(){k.$emit(b.prefixEvent+'.hide',y),h.removeClass(b.prefixClass+'-open'),b.animation&&h.removeClass(b.prefixClass+'-with-'+b.animation)}function r(){b.backdrop&&(x.on('click',f),C.on('click',f),C.on('wheel',v))}function s(){b.backdrop&&(x.off('click',f),C.off('click',f),C.off('wheel',v))}function u(){b.keyboard&&x.on('keyup',y.$onKeyUp)}function d(){b.keyboard&&x.off('keyup',y.$onKeyUp)}function f(e){e.target===e.currentTarget&&('static'===b.backdrop?y.focus():y.hide())}function v(e){e.preventDefault()}function w(){y.$isShown&&null!==x&&(s(),d()),T&&(T.$destroy(),T=null),x&&(x.remove(),x=y.$element=null)}var y={},b=y.$options=angular.extend({},e,t),D=y.$promise=o.compile(b),k=y.$scope=b.scope&&b.scope.$new()||a.$new();b.element||b.container||(b.container='body'),y.$id=b.id||b.element&&b.element.attr('id')||'',m(['title','content'],function(e){b[e]&&(k[e]=c.trustAsHtml(b[e]))}),k.$hide=function(){k.$$postDigest(function(){y.hide()})},k.$show=function(){k.$$postDigest(function(){y.show()})},k.$toggle=function(){k.$$postDigest(function(){y.toggle()})},y.$isShown=k.$isShown=!1;var S,x,T,C=angular.element('
');return C.css({position:'fixed',top:'0px',left:'0px',bottom:'0px',right:'0px','z-index':1038}),D.then(function(e){S=e,y.init()}),y.init=function(){b.show&&k.$$postDigest(function(){y.show()})},y.destroy=function(){w(),C&&(C.remove(),C=null),k.$destroy()},y.show=function(){if(!y.$isShown){var e,t;if(angular.isElement(b.container)?(e=b.container,t=b.container[0].lastChild?angular.element(b.container[0].lastChild):null):b.container?(e=g(b.container),t=e[0]&&e[0].lastChild?angular.element(e[0].lastChild):null):(e=null,t=b.element),x&&w(),T=y.$scope.$new(),x=y.$element=S.link(T,function(e,t){}),!k.$emit(b.prefixEvent+'.show.before',y).defaultPrevented){x.css({display:'block'}).addClass(b.placement),b.animation&&(b.backdrop&&C.addClass(b.backdropAnimation),x.addClass(b.animation)),b.backdrop&&l.enter(C,h,null),angular.version.minor<=2?l.enter(x,e,t,n):l.enter(x,e,t).then(n),y.$isShown=k.$isShown=!0,p(k);var a=x[0];$(function(){a.focus()}),h.addClass(b.prefixClass+'-open'),b.animation&&h.addClass(b.prefixClass+'-with-'+b.animation),r(),u()}}},y.hide=function(){y.$isShown&&(k.$emit(b.prefixEvent+'.hide.before',y).defaultPrevented||(angular.version.minor<=2?l.leave(x,i):l.leave(x).then(i),b.backdrop&&l.leave(C),y.$isShown=k.$isShown=!1,p(k),s(),d()))},y.toggle=function(){y.$isShown?y.hide():y.show()},y.focus=function(){x[0].focus()},y.$onKeyUp=function(e){27===e.which&&y.$isShown&&(y.hide(),e.stopPropagation())},y}function p(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function g(e,n){return angular.element((n||t).querySelectorAll(e))}var m=angular.forEach,$=(String.prototype.trim,n.requestAnimationFrame||n.setTimeout),h=angular.element(n.document.body);return f}]}).directive('bsModal',['$window','$sce','$modal',function(e,t,n){return{restrict:'EAC',scope:!0,link:function(e,a,o,i){var r={scope:e,element:a,show:!1};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','controller','placement','backdrop','keyboard','html','container','animation','id','prefixEvent','prefixClass'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])});var s=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),angular.forEach(['title','content'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsModal&&e.$watch(o.bsModal,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=n(r);a.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.module('mgcrea.ngStrap.navbar',[]).provider('$navbar',function(){var e=this.defaults={activeClass:'active',routeAttr:'data-match-route',strict:!1};this.$get=function(){return{defaults:e}}}).directive('bsNavbar',['$window','$location','$navbar',function(e,t,n){var a=n.defaults;return{restrict:'A',link:function(e,n,o,i){var r=angular.copy(a);angular.forEach(Object.keys(a),function(e){angular.isDefined(o[e])&&(r[e]=o[e])}),e.$watch(function(){return t.path()},function(e,t){var a=n[0].querySelectorAll('li['+r.routeAttr+']');angular.forEach(a,function(t){var n=angular.element(t),a=n.attr(r.routeAttr).replace('/','\\/');r.strict&&(a='^'+a+'$');var o=new RegExp(a,'i');o.test(e)?n.addClass(r.activeClass):n.removeClass(r.activeClass)})})}}}]),angular.module('mgcrea.ngStrap.popover',['mgcrea.ngStrap.tooltip']).provider('$popover',function(){var e=this.defaults={animation:'am-fade',customClass:'',container:!1,target:!1,placement:'right',templateUrl:'popover/popover.tpl.html',contentTemplate:!1,trigger:'click',keyboard:!0,html:!1,title:'',content:'',delay:0,autoClose:!1};this.$get=['$tooltip',function(t){function n(n,a){var o=angular.extend({},e,a),i=t(n,o);return o.content&&(i.$scope.content=o.content),i}return n}]}).directive('bsPopover',['$window','$sce','$popover',function(e,t,n){var a=e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,o,i){var r={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','container','delay','trigger','html','animation','customClass','autoClose','id','prefixClass','prefixEvent'],function(e){angular.isDefined(i[e])&&(r[e]=i[e])});var s=/^(false|0|)$/i;angular.forEach(['html','container','autoClose'],function(e){angular.isDefined(i[e])&&s.test(i[e])&&(r[e]=!1)});var l=o.attr('data-target');angular.isDefined(l)&&(r.target=s.test(l)?!1:l),angular.forEach(['title','content'],function(n){i[n]&&i.$observe(n,function(o,i){e[n]=t.trustAsHtml(o),angular.isDefined(i)&&a(function(){u&&u.$applyPlacement()})})}),i.bsPopover&&e.$watch(i.bsPopover,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t,angular.isDefined(n)&&a(function(){u&&u.$applyPlacement()})},!0),i.bsShow&&e.$watch(i.bsShow,function(e,t){u&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(popover),?/i)),e===!0?u.show():u.hide())}),i.viewport&&e.$watch(i.viewport,function(e){u&&angular.isDefined(e)&&u.setViewport(e)});var u=n(o,r);e.$on('$destroy',function(){u&&u.destroy(),r=null,u=null})}}}]),angular.module('mgcrea.ngStrap.scrollspy',['mgcrea.ngStrap.helpers.debounce','mgcrea.ngStrap.helpers.dimensions']).provider('$scrollspy',function(){var e=this.$$spies={},n=this.defaults={debounce:150,throttle:100,offset:100};this.$get=['$window','$document','$rootScope','dimensions','debounce','throttle',function(a,o,i,r,s,l){function u(e,t){return e[0].nodeName&&e[0].nodeName.toLowerCase()===t.toLowerCase()}function c(o){var c=angular.extend({},n,o);c.element||(c.element=p);var g=u(c.element,'body'),m=g?d:c.element,$=g?'window':c.id;if(e[$])return e[$].$$count++,e[$];var h,v,w,y,b,D,k,S,x={},T=x.$trackedElements=[],C=[];return x.init=function(){this.$$count=1,y=s(this.checkPosition,c.debounce),b=l(this.checkPosition,c.throttle),m.on('click',this.checkPositionWithEventLoop),d.on('resize',y),m.on('scroll',b),D=s(this.checkOffsets,c.debounce),h=i.$on('$viewContentLoaded',D),v=i.$on('$includeContentLoaded',D),D(),$&&(e[$]=x)},x.destroy=function(){this.$$count--,this.$$count>0||(m.off('click',this.checkPositionWithEventLoop),d.off('resize',y),m.off('scroll',b),h(),v(),$&&delete e[$])},x.checkPosition=function(){if(C.length){if(S=(g?a.pageYOffset:m.prop('scrollTop'))||0,k=Math.max(a.innerHeight,f.prop('clientHeight')),SC[e+1].offsetTop))return x.$activateElement(C[e])}},x.checkPositionWithEventLoop=function(){setTimeout(x.checkPosition,1)},x.$activateElement=function(e){if(w){var t=x.$getTrackedElement(w);t&&(t.source.removeClass('active'),u(t.source,'li')&&u(t.source.parent().parent(),'li')&&t.source.parent().parent().removeClass('active'))}w=e.target,e.source.addClass('active'),u(e.source,'li')&&u(e.source.parent().parent(),'li')&&e.source.parent().parent().addClass('active')},x.$getTrackedElement=function(e){return T.filter(function(t){return t.target===e})[0]},x.checkOffsets=function(){angular.forEach(T,function(e){var n=t.querySelector(e.target);e.offsetTop=n?r.offset(n).top:null,c.offset&&null!==e.offsetTop&&(e.offsetTop-=1*c.offset)}),C=T.filter(function(e){return null!==e.offsetTop}).sort(function(e,t){return e.offsetTop-t.offsetTop}),y()},x.trackElement=function(e,t){T.push({target:e,source:t})},x.untrackElement=function(e,t){for(var n,a=T.length;a--;)if(T[a].target===e&&T[a].source===t){n=a;break}T=T.splice(n,1)},x.activate=function(e){T[e].addClass('active')},x.init(),x}var d=angular.element(a),f=angular.element(o.prop('documentElement')),p=angular.element(a.document.body);return c}]}).directive('bsScrollspy',['$rootScope','debounce','dimensions','$scrollspy',function(e,t,n,a){return{restrict:'EAC',link:function(e,t,n){var o={scope:e};angular.forEach(['offset','target'],function(e){angular.isDefined(n[e])&&(o[e]=n[e])});var i=a(o);i.trackElement(o.target,t),e.$on('$destroy',function(){i&&(i.untrackElement(o.target,t),i.destroy()),o=null,i=null})}}}]).directive('bsScrollspyList',['$rootScope','debounce','dimensions','$scrollspy',function(e,t,n,a){return{restrict:'A',compile:function(e,t){var n=e[0].querySelectorAll('li > a[href]');angular.forEach(n,function(e){var t=angular.element(e);t.parent().attr('bs-scrollspy','').attr('data-target',t.attr('href'))})}}}]),angular.module('mgcrea.ngStrap.select',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$select',function(){var e=this.defaults={animation:'am-fade',prefixClass:'select',prefixEvent:'$select',placement:'bottom-left',templateUrl:'select/select.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,multiple:!1,allNoneButtons:!1,sort:!0,caretHtml:' ',placeholder:'Choose among the following...',allText:'All',noneText:'None',maxLength:3,maxLengthHtml:'selected',iconCheckmark:'glyphicon glyphicon-ok'};this.$get=['$window','$document','$rootScope','$tooltip','$timeout',function(t,n,a,o,i){function r(t,n,a){var r={},s=angular.extend({},e,a);r=o(t,s);var u=r.$scope;u.$matches=[],u.$activeIndex=s.multiple?[]:-1,u.$isMultiple=s.multiple,u.$showAllNoneButtons=s.allNoneButtons&&s.multiple,u.$iconCheckmark=s.iconCheckmark,u.$allText=s.allText,u.$noneText=s.noneText,u.$activate=function(e){u.$$postDigest(function(){r.activate(e)})},u.$select=function(e,t){u.$$postDigest(function(){r.select(e)})},u.$isVisible=function(){return r.$isVisible()},u.$isActive=function(e){return r.$isActive(e)},u.$selectAll=function(){for(var e=0;e=u.$matches.length&&(u.$activeIndex=s.multiple?[]:0)},r.$isVisible=function(){return s.minLength&&n?u.$matches.length&&n.$viewValue.length>=s.minLength:u.$matches.length},r.$isActive=function(e){return s.multiple?-1!==u.$activeIndex.indexOf(e):u.$activeIndex===e},r.$getIndex=function(e){var t=u.$matches.length,n=t;if(t){for(n=t;n--&&u.$matches[n].value!==e;);if(!(0>n))return n}},r.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),l){var t=angular.element(e.target);t.triggerHandler('click')}},r.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(e.preventDefault(),e.stopPropagation(),s.multiple&&9===e.keyCode?r.hide():s.multiple||13!==e.keyCode&&9!==e.keyCode?void(s.multiple||(38===e.keyCode&&u.$activeIndex>0?u.$activeIndex--:38===e.keyCode&&u.$activeIndex<0?u.$activeIndex=u.$matches.length-1:40===e.keyCode&&u.$activeIndex'),c.after(t)}var d=o(n.bsOptions),f=a(t,r,s),p=d.$match[7].replace(/\|.+/,'').trim();e.$watchCollection(p,function(t,n){d.valuesFn(e,r).then(function(e){f.update(e),r.$render()})}),e.$watch(n.ngModel,function(e,t){f.$updateActiveIndex(),r.$render()},!0),r.$render=function(){var e,n;s.multiple&&angular.isArray(r.$modelValue)?(e=r.$modelValue.map(function(e){return n=f.$getIndex(e),angular.isDefined(n)?f.$scope.$matches[n].label:!1}).filter(angular.isDefined),e=e.length>(s.maxLength||i.maxLength)?e.length+' '+(s.maxLengthHtml||i.maxLengthHtml):e.join(', ')):(n=f.$getIndex(r.$modelValue),e=angular.isDefined(n)?f.$scope.$matches[n].label:!1),t.html((e?e:s.placeholder)+(s.caretHtml?s.caretHtml:i.caretHtml))},s.multiple&&(r.$isEmpty=function(e){return!e||0===e.length}),e.$on('$destroy',function(){f&&f.destroy(),s=null,f=null})}}}]),angular.module('mgcrea.ngStrap.timepicker',['mgcrea.ngStrap.helpers.dateParser','mgcrea.ngStrap.helpers.dateFormatter','mgcrea.ngStrap.tooltip']).provider('$timepicker',function(){var e=this.defaults={animation:'am-fade',prefixClass:'timepicker',placement:'bottom-left',templateUrl:'timepicker/timepicker.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,useNative:!0,timeType:'date',timeFormat:'shortTime',timezone:null,modelTimeFormat:null,autoclose:!1,minTime:-(1/0),maxTime:+(1/0),length:5,hourStep:1,minuteStep:5,secondStep:5,roundDisplay:!1,iconUp:'glyphicon glyphicon-chevron-up',iconDown:'glyphicon glyphicon-chevron-down',arrowBehavior:'pager'};this.$get=['$window','$document','$rootScope','$sce','$dateFormatter','$tooltip','$timeout',function(t,n,a,o,i,r,s){function l(t,n,a){function o(e){var t=6e4*g.minuteStep;return new Date(Math.floor(e.getTime()/t)*t)}function l(e,n){var a=e+n;if(t[0].createTextRange){var o=t[0].createTextRange();o.collapse(!0),o.moveStart('character',e),o.moveEnd('character',a),o.select()}else t[0].setSelectionRange?t[0].setSelectionRange(e,a):angular.isUndefined(t[0].selectionStart)&&(t[0].selectionStart=e,t[0].selectionEnd=a)}function d(){t[0].focus()}var f=r(t,angular.extend({},e,a)),p=a.scope,g=f.$options,m=f.$scope,$=g.lang,h=function(e,t,n){return i.formatDate(e,t,$,n)},v=0,w=g.roundDisplay?o(new Date):new Date,y=n.$dateValue||w,b={hour:y.getHours(),meridian:y.getHours()<12,minute:y.getMinutes(),second:y.getSeconds(),millisecond:y.getMilliseconds()},D=i.getDatetimeFormat(g.timeFormat,$),k=i.hoursFormat(D),S=i.timeSeparator(D),x=i.minutesFormat(D),T=i.secondsFormat(D),C=i.showSeconds(D),M=i.showAM(D);m.$iconUp=g.iconUp,m.$iconDown=g.iconDown,m.$select=function(e,t){f.select(e,t)},m.$moveIndex=function(e,t){f.$moveIndex(e,t)},m.$switchMeridian=function(e){f.switchMeridian(e)},f.update=function(e){angular.isDate(e)&&!isNaN(e.getTime())?(f.$date=e,angular.extend(b,{hour:e.getHours(),minute:e.getMinutes(),second:e.getSeconds(),millisecond:e.getMilliseconds()}),f.$build()):f.$isBuilt||f.$build()},f.select=function(e,t,a){(!n.$dateValue||isNaN(n.$dateValue.getTime()))&&(n.$dateValue=new Date(1970,0,1)),angular.isDate(e)||(e=new Date(e)),0===t?n.$dateValue.setHours(e.getHours()):1===t?n.$dateValue.setMinutes(e.getMinutes()):2===t&&n.$dateValue.setSeconds(e.getSeconds()),n.$setViewValue(angular.copy(n.$dateValue)),n.$render(),g.autoclose&&!a&&s(function(){f.hide(!0)})},f.switchMeridian=function(e){if(n.$dateValue&&!isNaN(n.$dateValue.getTime())){var t=(e||n.$dateValue).getHours();n.$dateValue.setHours(12>t?t+12:t-12),n.$setViewValue(angular.copy(n.$dateValue)),n.$render()}},f.$build=function(){var e,t,n=m.midIndex=parseInt(g.length/2,10),a=[];for(e=0;e1*g.maxTime},m.$arrowAction=function(e,t){'picker'===g.arrowBehavior?f.$setTimeByStep(e,t):f.$moveIndex(e,t)},f.$setTimeByStep=function(e,t){var n=new Date(f.$date||y),a=n.getHours(),o=n.getMinutes(),i=n.getSeconds();0===t?n.setHours(a-parseInt(g.hourStep,10)*e):1===t?n.setMinutes(o-parseInt(g.minuteStep,10)*e):2===t&&n.setSeconds(i-parseInt(g.secondStep,10)*e),f.select(n,t,!0)},f.$moveIndex=function(e,t){var n;0===t?(n=new Date(1970,0,1,b.hour+e*g.length,b.minute,b.second),angular.extend(b,{hour:n.getHours()})):1===t?(n=new Date(1970,0,1,b.hour,b.minute+e*g.length*g.minuteStep,b.second),angular.extend(b,{minute:n.getMinutes()})):2===t&&(n=new Date(1970,0,1,b.hour,b.minute,b.second+e*g.length*g.secondStep),angular.extend(b,{second:n.getSeconds()})),f.$build()},f.$onMouseDown=function(e){if('input'!==e.target.nodeName.toLowerCase()&&e.preventDefault(),e.stopPropagation(),c){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},f.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return void f.hide(!0);var t=new Date(f.$date),n=t.getHours(),a=h(t,k).length,o=t.getMinutes(),i=h(t,x).length,r=t.getSeconds(),s=h(t,T).length,u=1,c=/(37|39)/.test(e.keyCode),d=2+1*C+1*M;c&&(37===e.keyCode?v=1>v?d-1:v-1:39===e.keyCode&&(v=d-1>v?v+1:0));var m=[0,a],$=0;38===e.keyCode&&($=-1),40===e.keyCode&&($=1);var w=2===v&&C,y=2===v&&!C||3===v&&C;0===v?(t.setHours(n+$*parseInt(g.hourStep,10)),a=h(t,k).length,m=[0,a]):1===v?(t.setMinutes(o+$*parseInt(g.minuteStep,10)),i=h(t,x).length,m=[a+u,i]):w?(t.setSeconds(r+$*parseInt(g.secondStep,10)),s=h(t,T).length,m=[a+u+i+u,s]):y&&(c||f.switchMeridian(),m=[a+u+i+u+(s+u)*C,2]),f.select(t,v,!0),l(m[0],m[1]),p.$digest()}};var E=f.init;f.init=function(){return u&&g.useNative?(t.prop('type','time'),void t.css('-webkit-appearance','textfield')):(c&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',d)),void E())};var A=f.destroy;f.destroy=function(){u&&g.useNative&&t.off('click',d),A()};var F=f.show;f.show=function(){!c&&t.attr('readonly')||t.attr('disabled')||(F(),s(function(){f.$element&&f.$element.on(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.on('keydown',f.$onKeyDown)},0,!1))};var V=f.hide;return f.hide=function(e){f.$isShown&&(f.$element&&f.$element.off(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.off('keydown',f.$onKeyDown),V(e))},f}var u=/(ip(a|o)d|iphone|android)/gi.test(t.navigator.userAgent),c='createTouch'in t.document&&u;return e.lang||(e.lang=i.getDefaultLocale()),l.defaults=e,l}]}).directive('bsTimepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$timepicker',function(e,t,a,o,i,r){var s=r.defaults,l=/(ip(a|o)d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,a,u){function c(e){if(angular.isDate(e)){var t=isNaN(f.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=f.minTime,n=isNaN(f.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=f.maxTime,a=t&&n;u.$setValidity('date',a),u.$setValidity('min',t),u.$setValidity('max',n),a&&(u.$dateValue=e)}}function d(){return!u.$dateValue||isNaN(u.$dateValue.getTime())?'':$(u.$dateValue,f.timeFormat)}var f={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent'],function(e){angular.isDefined(a[e])&&(f[e]=a[e])});var p=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(a[e])&&p.test(a[e])&&(f[e]=!1)}),a.bsShow&&e.$watch(a.bsShow,function(e,t){g&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?g.show():g.hide())}),l&&(f.useNative||s.useNative)&&(f.timeFormat='HH:mm');var g=r(t,u,f);f=g.$options;var m=f.lang,$=function(e,t,n){return o.formatDate(e,t,m,n)},h=i({format:f.timeFormat,lang:m});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(a[e])&&a.$observe(e,function(t){g.$options[e]=h.getTimeForAttribute(e,t),!isNaN(g.$options[e])&&g.$build(),c(u.$dateValue)})}),e.$watch(a.ngModel,function(e,t){g.update(u.$dateValue)},!0),u.$parsers.unshift(function(e){var t;if(!e)return u.$setValidity('date',!0),null;var a=angular.isDate(e)?e:h.parse(e,u.$dateValue);return!a||isNaN(a.getTime())?(u.$setValidity('date',!1),n):(c(a),'string'===f.timeType?(t=h.timezoneOffsetAdjust(a,f.timezone,!0),$(t,f.modelTimeFormat||f.timeFormat)):(t=h.timezoneOffsetAdjust(u.$dateValue,f.timezone,!0),'number'===f.timeType?t.getTime():'unix'===f.timeType?t.getTime()/1e3:'iso'===f.timeType?t.toISOString():new Date(t)))}),u.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?0/0:angular.isDate(e)?e:'string'===f.timeType?h.parse(e,null,f.modelTimeFormat):new Date('unix'===f.timeType?1e3*e:e),u.$dateValue=h.timezoneOffsetAdjust(t,f.timezone),d()}),u.$render=function(){t.val(d())},e.$on('$destroy',function(){g&&g.destroy(),f=null,g=null})}}}]),angular.module('mgcrea.ngStrap.tab',[]).provider('$tab',function(){var e=this.defaults={animation:'am-fade',template:'tab/tab.tpl.html',navClass:'nav-tabs',activeClass:'active'},t=this.controller=function(t,n,a){var o=this;o.$options=angular.copy(e),angular.forEach(['animation','navClass','activeClass'],function(e){angular.isDefined(a[e])&&(o.$options[e]=a[e])}),t.$navClass=o.$options.navClass,t.$activeClass=o.$options.activeClass,o.$panes=t.$panes=[],o.$activePaneChangeListeners=o.$viewChangeListeners=[],o.$push=function(e){angular.isUndefined(o.$panes.$active)&&t.$setActive(e.name||0),o.$panes.push(e)},o.$remove=function(e){var t,n=o.$panes.indexOf(e),a=o.$panes.$active;t=angular.isString(a)?o.$panes.map(function(e){return e.name}).indexOf(a):o.$panes.$active,o.$panes.splice(n,1),t>n?t--:n===t&&t===o.$panes.length&&t--,t>=0&&t=e.length&&(d.$activeIndex=u.autoSelect?0:-1),s(d),o(l.$applyPlacement)},l.activate=function(e){d.$activeIndex=e},l.select=function(e){if(-1!==e){var t=d.$matches[e].value;n.$setViewValue(t),n.$render(),d.$resetMatches(),c&&c.$digest(),d.$emit(u.prefixEvent+'.select',t,e,l)}},l.$isVisible=function(){return u.minLength&&n?d.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=u.minLength:!!d.$matches.length},l.$getIndex=function(e){var t=d.$matches.length,n=t;if(t){for(n=t;n--&&d.$matches[n].value!==e;);if(!(0>n))return n}},l.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},l.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!l.$isVisible()||13===e.keyCode&&-1===d.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&d.$matches.length?l.select(d.$activeIndex):38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:40===e.keyCode&&d.$activeIndex0)return void r.$setViewValue(r.$viewValue.substring(0,r.$viewValue.length-1));e.length>c&&(e=e.slice(0,c));var n=g.$isVisible();n&&g.update(e),(1!==e.length||e[0].value!==t)&&(!n&&g.update(e),r.$render())})}),r.$formatters.push(function(e){var t=p.displayValue(e);return t?t:e&&'object'!=typeof e?e:''}),r.$render=function(){if(r.$isEmpty(r.$viewValue))return t.val('');var e=g.$getIndex(r.$modelValue),n=angular.isDefined(e)?g.$scope.$matches[e].label:r.$viewValue;n=angular.isObject(n)?p.displayValue(n):n;var a=n?n.toString().replace(/<(?:.|\n)*?>/gm,''):'';t.val(s.trimValue===!1?a:a.trim())},e.$on('$destroy',function(){g&&g.destroy(),s=null,g=null})}}}]),angular.module('mgcrea.ngStrap.tooltip',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$tooltip',function(){var e=this.defaults={animation:'am-fade',customClass:'',prefixClass:'tooltip',prefixEvent:'tooltip',container:!1,target:!1,placement:'top',templateUrl:'tooltip/tooltip.tpl.html',template:'',contentTemplate:!1,trigger:'hover focus',keyboard:!1,html:!1,show:!1,title:'',type:'',delay:0,autoClose:!1,bsEnabled:!0,viewport:{selector:'body',padding:0}};this.$get=['$window','$rootScope','$bsCompiler','$q','$templateCache','$http','$animate','$sce','dimensions','$$rAF','$timeout',function(n,a,o,i,r,s,l,u,c,d,f){function p(i,r){function s(){P.$emit(V.prefixEvent+'.show',F)}function p(){if(P.$emit(V.prefixEvent+'.hide',F),R===j){if(z&&'focus'===V.trigger)return i[0].blur();A()}}function v(){var e=V.trigger.split(' ');angular.forEach(e,function(e){'click'===e?i.on('click',F.toggle):'manual'!==e&&(i.on('hover'===e?'mouseenter':'focus',F.enter),i.on('hover'===e?'mouseleave':'blur',F.leave),'button'===I&&'hover'!==e&&i.on($?'touchstart':'mousedown',F.$onFocusElementMouseDown))})}function w(){for(var e=V.trigger.split(' '),t=e.length;t--;){var n=e[t];'click'===n?i.off('click',F.toggle):'manual'!==n&&(i.off('hover'===n?'mouseenter':'focus',F.enter),i.off('hover'===n?'mouseleave':'blur',F.leave),'button'===I&&'hover'!==n&&i.off($?'touchstart':'mousedown',F.$onFocusElementMouseDown))}}function y(){'focus'!==V.trigger?R.on('keyup',F.$onKeyUp):i.on('keyup',F.$onFocusKeyUp)}function b(){'focus'!==V.trigger?R.off('keyup',F.$onKeyUp):i.off('keyup',F.$onFocusKeyUp)}function D(){f(function(){R.on('click',S),h.on('click',F.hide),K=!0},0,!1)}function k(){K&&(R.off('click',S),h.off('click',F.hide),K=!1)}function S(e){e.stopPropagation()}function x(e){e=e||V.target||i;var a=e[0],o='BODY'===a.tagName,r=a.getBoundingClientRect(),s={};for(var l in r)s[l]=r[l];null===s.width&&(s=angular.extend({},s,{width:r.right-r.left,height:r.bottom-r.top}));var u=o?{top:0,left:0}:c.offset(a),d={scroll:o?t.documentElement.scrollTop||t.body.scrollTop:e.prop('scrollTop')||0},f=o?{width:t.documentElement.clientWidth,height:n.innerHeight}:null;return angular.extend({},s,d,f,u)}function T(e,t,n,a){var o,i=e.split('-');switch(i[0]){case'right':o={top:t.top+t.height/2-a/2,left:t.left+t.width};break;case'bottom':o={top:t.top+t.height,left:t.left+t.width/2-n/2};break;case'left':o={top:t.top+t.height/2-a/2,left:t.left-n};break;default:o={top:t.top-a,left:t.left+t.width/2-n/2}}if(!i[1])return o;if('top'===i[0]||'bottom'===i[0])switch(i[1]){case'left':o.left=t.left;break;case'right':o.left=t.left+t.width-n}else if('left'===i[0]||'right'===i[0])switch(i[1]){case'top':o.top=t.top-a;break;case'bottom':o.top=t.top+t.height}return o}function C(e,t){var n=R[0],a=n.offsetWidth,o=n.offsetHeight,i=parseInt(c.css(n,'margin-top'),10),r=parseInt(c.css(n,'margin-left'),10);isNaN(i)&&(i=0),isNaN(r)&&(r=0),e.top=e.top+i,e.left=e.left+r,c.setOffset(n,angular.extend({using:function(e){R.css({top:Math.round(e.top)+'px',left:Math.round(e.left)+'px',right:''})}},e),0);var s=n.offsetWidth,l=n.offsetHeight;if('top'===t&&l!==o&&(e.top=e.top+o-l),!/top-left|top-right|bottom-left|bottom-right/.test(t)){var u=M(t,e,s,l);if(u.left?e.left+=u.left:e.top+=u.top,c.setOffset(n,e),/top|right|bottom|left/.test(t)){var d=/top|bottom/.test(t),f=d?2*u.left-a+s:2*u.top-o+l,p=d?'offsetWidth':'offsetHeight';E(f,n[p],d)}}}function M(e,t,n,a){var o={top:0,left:0};if(!F.$viewport)return o;var i=V.viewport&&V.viewport.padding||0,r=x(F.$viewport);if(/right|left/.test(e)){var s=t.top-i-r.scroll,l=t.top+i-r.scroll+a;sr.top+r.height&&(o.top=r.top+r.height-l)}else{var u=t.left-i,c=t.left+i+n;ur.right&&(o.left=r.left+r.width-c)}return o}function E(e,t,n){var a=m('.tooltip-arrow, .arrow',R[0]);a.css(n?'left':'top',50*(1-e/t)+'%').css(n?'top':'left','')}function A(){clearTimeout(H),F.$isShown&&null!==R&&(V.autoClose&&k(),V.keyboard&&b()),Y&&(Y.$destroy(),Y=null),R&&(R.remove(),R=F.$element=null)}var F={},V=F.$options=angular.extend({},e,r),O=F.$promise=o.compile(V),P=F.$scope=V.scope&&V.scope.$new()||a.$new(),I=i[0].nodeName.toLowerCase();if(V.delay&&angular.isString(V.delay)){var N=V.delay.split(',').map(parseFloat);V.delay=N.length>1?{show:N[0],hide:N[1]}:N[0]}F.$id=V.id||i.attr('id')||'',V.title&&(P.title=u.trustAsHtml(V.title)),P.$setEnabled=function(e){P.$$postDigest(function(){F.setEnabled(e)})},P.$hide=function(){P.$$postDigest(function(){F.hide()})},P.$show=function(){P.$$postDigest(function(){F.show()})},P.$toggle=function(){P.$$postDigest(function(){F.toggle()})},F.$isShown=P.$isShown=!1;var H,L,U,R,q,Y;O.then(function(e){U=e,F.init()}),F.init=function(){V.delay&&angular.isNumber(V.delay)&&(V.delay={show:V.delay,hide:V.delay}),'self'===V.container?q=i:angular.isElement(V.container)?q=V.container:V.container&&(q=m(V.container)),v(),V.target&&(V.target=angular.isElement(V.target)?V.target:m(V.target)),V.show&&P.$$postDigest(function(){'focus'===V.trigger?i[0].focus():F.show()})},F.destroy=function(){w(),A(),P.$destroy()},F.enter=function(){return clearTimeout(H),L='in',V.delay&&V.delay.show?void(H=setTimeout(function(){'in'===L&&F.show()},V.delay.show)):F.show()},F.show=function(){if(V.bsEnabled&&!F.$isShown){P.$emit(V.prefixEvent+'.show.before',F);var e,t;V.container?(e=q,t=q[0].lastChild?angular.element(q[0].lastChild):null):(e=null,t=i),R&&A(),Y=F.$scope.$new(),R=F.$element=U.link(Y,function(e,t){}),R.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),V.animation&&R.addClass(V.animation),V.type&&R.addClass(V.prefixClass+'-'+V.type),V.customClass&&R.addClass(V.customClass),t?t.after(R):e.prepend(R),F.$isShown=P.$isShown=!0,g(P),F.$applyPlacement(),angular.version.minor<=2?l.enter(R,e,t,s):l.enter(R,e,t).then(s),g(P),d(function(){R&&R.css({visibility:'visible'})}),V.keyboard&&('focus'!==V.trigger&&F.focus(),y()),V.autoClose&&D()}},F.leave=function(){return clearTimeout(H),L='out',V.delay&&V.delay.hide?void(H=setTimeout(function(){'out'===L&&F.hide()},V.delay.hide)):F.hide()};var z,j;F.hide=function(e){F.$isShown&&(P.$emit(V.prefixEvent+'.hide.before',F),z=e,j=R,angular.version.minor<=2?l.leave(R,p):l.leave(R).then(p),F.$isShown=P.$isShown=!1,g(P),V.keyboard&&null!==R&&b(),V.autoClose&&null!==R&&k())},F.toggle=function(){F.$isShown?F.leave():F.enter()},F.focus=function(){R[0].focus()},F.setEnabled=function(e){V.bsEnabled=e},F.setViewport=function(e){V.viewport=e},F.$applyPlacement=function(){if(R){var t=V.placement,n=/\s?auto?\s?/i,a=n.test(t);a&&(t=t.replace(n,'')||e.placement),R.addClass(V.placement);var o=x(),i=R.prop('offsetWidth'),r=R.prop('offsetHeight');if(F.$viewport=V.viewport&&m(V.viewport.selector||V.viewport),a){var s=t,l=x(F.$viewport);s.indexOf('bottom')>=0&&o.bottom+r>l.bottom?t=s.replace('bottom','top'):s.indexOf('top')>=0&&o.top-rl.width?t='right'===s?'left':t.replace('left','right'):('left'===s||'bottom-right'===s||'top-right'===s)&&o.left-i').html(n.trim()).contents(),r=o(a);return{locals:e,element:a,link:function(t){if(e.$scope=t,u){var n=i(u,e,!0);g&&angular.extend(n.instance,e);var o=angular.isObject(n)?n:n();a.data('$ngControllerController',o),a.children().data('$ngControllerController',o),c&&(t[c]=o)}return r.apply(null,arguments)}}})};var u={}}a.$inject=['$q','$http','$injector','$compile','$controller','$templateCache'],angular.module('mgcrea.ngStrap.typeahead',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$typeahead',function(){var e=this.defaults={animation:'am-fade',prefixClass:'typeahead',prefixEvent:'$typeahead',placement:'bottom-left',templateUrl:'typeahead/typeahead.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,minLength:1,filter:'bsAsyncFilter',limit:6,autoSelect:!1,comparator:'',trimValue:!0};this.$get=['$window','$rootScope','$tooltip','$$rAF','$timeout',function(t,n,a,o,i){function r(t,n,r){var l={},u=angular.extend({},e,r);l=a(t,u);var c=r.scope,d=l.$scope;d.$resetMatches=function(){d.$matches=[],d.$activeIndex=u.autoSelect?0:-1},d.$resetMatches(),d.$activate=function(e){d.$$postDigest(function(){l.activate(e)})},d.$select=function(e,t){d.$$postDigest(function(){l.select(e)})},d.$isVisible=function(){return l.$isVisible()},l.update=function(e){d.$matches=e,d.$activeIndex>=e.length&&(d.$activeIndex=u.autoSelect?0:-1),s(d),o(l.$applyPlacement)},l.activate=function(e){d.$activeIndex=e},l.select=function(e){if(-1!==e){var t=d.$matches[e].value;n.$setViewValue(t),n.$render(),d.$resetMatches(),c&&c.$digest(),d.$emit(u.prefixEvent+'.select',t,e,l),angular.isDefined(u.onSelect)&&angular.isFunction(u.onSelect)&&u.onSelect(t,e,l)}},l.$isVisible=function(){return u.minLength&&n?d.$matches.length&&angular.isString(n.$viewValue)&&n.$viewValue.length>=u.minLength:!!d.$matches.length},l.$getIndex=function(e){var t;for(t=d.$matches.length;t--&&!angular.equals(d.$matches[t].value,e););return t},l.$onMouseDown=function(e){e.preventDefault(),e.stopPropagation()},l.$onKeyDown=function(e){/(38|40|13)/.test(e.keyCode)&&(!l.$isVisible()||13===e.keyCode&&-1===d.$activeIndex||(e.preventDefault(),e.stopPropagation()),13===e.keyCode&&d.$matches.length?l.select(d.$activeIndex):38===e.keyCode&&d.$activeIndex>0?d.$activeIndex--:40===e.keyCode&&d.$activeIndex0?void r.$setViewValue(r.$viewValue.substring(0,r.$viewValue.length-1)):(e.length>c&&(e=e.slice(0,c)),g.update(e),void r.$render())})}),r.$formatters.push(function(e){var t=p.displayValue(e);return t?t:angular.isDefined(e)&&'object'!=typeof e?e:''}),r.$render=function(){if(r.$isEmpty(r.$viewValue))return t.val('');var e=g.$getIndex(r.$modelValue),n=-1!==e?g.$scope.$matches[e].label:r.$viewValue;n=angular.isObject(n)?p.displayValue(n):n;var a=n?n.toString().replace(/<(?:.|\n)*?>/gm,''):'',o=t[0].selectionStart,i=t[0].selectionEnd;t.val(s.trimValue===!1?a:a.trim()),t[0].setSelectionRange(o,i)},e.$on('$destroy',function(){g&&g.destroy(),s=null,g=null})}}}]),angular.module('mgcrea.ngStrap.tab',[]).provider('$tab',function(){var e=this.defaults={animation:'am-fade',template:'tab/tab.tpl.html',navClass:'nav-tabs',activeClass:'active'},t=this.controller=function(t,n,a){var o=this;o.$options=angular.copy(e),angular.forEach(['animation','navClass','activeClass'],function(e){angular.isDefined(a[e])&&(o.$options[e]=a[e])}),t.$navClass=o.$options.navClass,t.$activeClass=o.$options.activeClass,o.$panes=t.$panes=[],o.$activePaneChangeListeners=o.$viewChangeListeners=[],o.$push=function(e){angular.isUndefined(o.$panes.$active)&&t.$setActive(e.name||0),o.$panes.push(e)},o.$remove=function(e){var t,n=o.$panes.indexOf(e),a=o.$panes.$active;t=angular.isString(a)?o.$panes.map(function(e){return e.name}).indexOf(a):o.$panes.$active,o.$panes.splice(n,1),t>n?t--:n===t&&t===o.$panes.length&&t--,t>=0&&tr.top+r.height&&(o.top=r.top+r.height-l)}else{var u=t.left-i,c=t.left+i+n;ur.right&&(o.left=r.left+r.width-c)}return o}function M(e,t,n){var a=m('.tooltip-arrow, .arrow',B[0]);a.css(n?'left':'top',50*(1-e/t)+'%').css(n?'top':'left','')}function A(){clearTimeout(P),F.$isShown&&null!==B&&(V.autoClose&&S(),V.keyboard&&b()),Y&&(Y.$destroy(),Y=null),B&&(B.remove(),B=F.$element=null)}var F={},V=F.$options=angular.extend({},e,r),H=F.$promise=o.compile(V),O=F.$scope=V.scope&&V.scope.$new()||a.$new(),I=i[0].nodeName.toLowerCase();if(V.delay&&angular.isString(V.delay)){var N=V.delay.split(',').map(parseFloat);V.delay=N.length>1?{show:N[0],hide:N[1]}:N[0]}F.$id=V.id||i.attr('id')||'',V.title&&(O.title=u.trustAsHtml(V.title)),O.$setEnabled=function(e){O.$$postDigest(function(){F.setEnabled(e)})},O.$hide=function(){O.$$postDigest(function(){F.hide()})},O.$show=function(){O.$$postDigest(function(){F.show()})},O.$toggle=function(){O.$$postDigest(function(){F.toggle()})},F.$isShown=O.$isShown=!1;var P,U,L,B,R,Y;H.then(function(e){L=e,F.init()}),F.init=function(){V.delay&&angular.isNumber(V.delay)&&(V.delay={show:V.delay,hide:V.delay}),'self'===V.container?R=i:angular.isElement(V.container)?R=V.container:V.container&&(R=m(V.container)),$(),V.target&&(V.target=angular.isElement(V.target)?V.target:m(V.target)),V.show&&O.$$postDigest(function(){'focus'===V.trigger?i[0].focus():F.show()})},F.destroy=function(){w(),A(),O.$destroy()},F.enter=function(){return clearTimeout(P),U='in',V.delay&&V.delay.show?void(P=setTimeout(function(){'in'===U&&F.show()},V.delay.show)):F.show()},F.show=function(){if(V.bsEnabled&&!F.$isShown){O.$emit(V.prefixEvent+'.show.before',F),angular.isDefined(V.onBeforeShow)&&angular.isFunction(V.onBeforeShow)&&V.onBeforeShow(F);var e,t;V.container?(e=R,t=R[0].lastChild?angular.element(R[0].lastChild):null):(e=null,t=i),B&&A(),Y=F.$scope.$new(),B=F.$element=L.link(Y,function(e,t){}),B.css({top:'-9999px',left:'-9999px',right:'auto',display:'block',visibility:'hidden'}),V.animation&&B.addClass(V.animation),V.type&&B.addClass(V.prefixClass+'-'+V.type),V.customClass&&B.addClass(V.customClass),t?t.after(B):e.prepend(B),F.$isShown=O.$isShown=!0,g(O),F.$applyPlacement(),angular.version.minor<=2?l.enter(B,e,t,s):l.enter(B,e,t).then(s),g(O),d(function(){B&&B.css({visibility:'visible'}),V.keyboard&&('focus'!==V.trigger&&F.focus(),y())}),V.autoClose&&D()}},F.leave=function(){return clearTimeout(P),U='out',V.delay&&V.delay.hide?void(P=setTimeout(function(){'out'===U&&F.hide()},V.delay.hide)):F.hide()};var q,z;F.hide=function(e){F.$isShown&&(O.$emit(V.prefixEvent+'.hide.before',F),angular.isDefined(V.onBeforeHide)&&angular.isFunction(V.onBeforeHide)&&V.onBeforeHide(F),q=e,z=B,angular.version.minor<=2?l.leave(B,p):l.leave(B).then(p),F.$isShown=O.$isShown=!1,g(O),V.keyboard&&null!==B&&b(),V.autoClose&&null!==B&&S())},F.toggle=function(e){e&&e.preventDefault(),F.$isShown?F.leave():F.enter()},F.focus=function(){B[0].focus()},F.setEnabled=function(e){V.bsEnabled=e},F.setViewport=function(e){V.viewport=e},F.$applyPlacement=function(){if(B){var t=V.placement,n=/\s?auto?\s?/i,a=n.test(t);a&&(t=t.replace(n,'')||e.placement),B.addClass(V.placement);var o=x(),i=B.prop('offsetWidth'),r=B.prop('offsetHeight');if(F.$viewport=V.viewport&&m(V.viewport.selector||V.viewport),a){var s=t,l=x(F.$viewport);/bottom/.test(s)&&o.bottom+r>l.bottom?t=s.replace('bottom','top'):/top/.test(s)&&o.top-rl.width&&(t=t.replace('right','left')),B.removeClass(s).addClass(t)}var u=C(t,o,i,r);T(u,t)}},F.$onKeyUp=function(e){27===e.which&&F.$isShown&&(F.hide(),e.stopPropagation())},F.$onFocusKeyUp=function(e){27===e.which&&(i[0].blur(),e.stopPropagation())},F.$onFocusElementMouseDown=function(e){V.mouseDownPreventDefault&&e.preventDefault(),V.mouseDownStopPropagation&&e.stopPropagation(),F.$isShown?i[0].blur():i[0].focus()};var j=!1;return F}function g(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function m(e,n){return angular.element((n||t).querySelectorAll(e))}var $=/(ip[ao]d|iphone|android)/gi.test(n.navigator.userAgent),h='createTouch'in n.document&&$,v=angular.element(n.document);return p}]}).directive('bsTooltip',['$window','$location','$sce','$parse','$tooltip','$$rAF',function(e,t,n,a,o,i){return{restrict:'EAC',scope:!0,link:function(e,t,a,r){var s,l={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','titleTemplate','placement','container','delay','trigger','html','animation','backdropAnimation','type','customClass','id'],function(e){angular.isDefined(a[e])&&(l[e]=a[e])});var u=/^(false|0|)$/i;angular.forEach(['html','container'],function(e){angular.isDefined(a[e])&&u.test(a[e])&&(l[e]=!1)}),angular.forEach(['onBeforeShow','onShow','onBeforeHide','onHide'],function(t){var n='bs'+t.charAt(0).toUpperCase()+t.slice(1);angular.isDefined(a[n])&&(l[t]=e.$eval(a[n]))});var c=t.attr('data-target');angular.isDefined(c)&&(u.test(c)?l.target=!1:l.target=c),e.hasOwnProperty('title')||(e.title=''),a.$observe('title',function(t){if(angular.isDefined(t)||!e.hasOwnProperty('title')){var a=e.title;e.title=n.trustAsHtml(t),angular.isDefined(a)&&i(function(){s&&s.$applyPlacement()})}}),a.$observe('disabled',function(e){e&&s.$isShown&&s.hide()}),a.bsTooltip&&e.$watch(a.bsTooltip,function(t,n){angular.isObject(t)?angular.extend(e,t):e.title=t,angular.isDefined(n)&&i(function(){s&&s.$applyPlacement()})},!0),a.bsShow&&e.$watch(a.bsShow,function(e,t){s&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(tooltip),?/i)),e===!0?s.show():s.hide())}),a.bsEnabled&&e.$watch(a.bsEnabled,function(e,t){s&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|1|,?(tooltip),?/i)),e===!1?s.setEnabled(!1):s.setEnabled(!0))}),a.viewport&&e.$watch(a.viewport,function(e){s&&angular.isDefined(e)&&s.setViewport(e)}),s=o(t,l),e.$on('$destroy',function(){s&&s.destroy(),l=null,s=null})}}}]),angular.module('mgcrea.ngStrap.timepicker',['mgcrea.ngStrap.helpers.dateParser','mgcrea.ngStrap.helpers.dateFormatter','mgcrea.ngStrap.tooltip']).provider('$timepicker',function(){var e=this.defaults={animation:'am-fade',defaultDate:'auto',prefixClass:'timepicker',placement:'bottom-left',templateUrl:'timepicker/timepicker.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,useNative:!0,timeType:'date',timeFormat:'shortTime',timezone:null,modelTimeFormat:null,autoclose:!1,minTime:-(1/0),maxTime:+(1/0),length:5,hourStep:1,minuteStep:5,secondStep:5,roundDisplay:!1,iconUp:'glyphicon glyphicon-chevron-up',iconDown:'glyphicon glyphicon-chevron-down',arrowBehavior:'pager'};this.$get=['$window','$document','$rootScope','$sce','$dateFormatter','$tooltip','$timeout',function(t,n,a,o,i,r,s){function l(t,n,a){function o(e){var t=6e4*g.minuteStep;return new Date(Math.floor(e.getTime()/t)*t)}function l(e,n){var a=e+n;if(t[0].createTextRange){var o=t[0].createTextRange();o.collapse(!0),o.moveStart('character',e),o.moveEnd('character',a),o.select()}else t[0].setSelectionRange?t[0].setSelectionRange(e,a):angular.isUndefined(t[0].selectionStart)&&(t[0].selectionStart=e,t[0].selectionEnd=a)}function d(){t[0].focus()}var f=r(t,angular.extend({},e,a)),p=a.scope,g=f.$options,m=f.$scope,$=g.lang,h=function(e,t,n){return i.formatDate(e,t,$,n)},v=0,w=g.roundDisplay?o(new Date):new Date,y=n.$dateValue||w,b={hour:y.getHours(),meridian:y.getHours()<12,minute:y.getMinutes(),second:y.getSeconds(),millisecond:y.getMilliseconds()},D=i.getDatetimeFormat(g.timeFormat,$),S=i.hoursFormat(D),k=i.timeSeparator(D),x=i.minutesFormat(D),C=i.secondsFormat(D),T=i.showSeconds(D),E=i.showAM(D);m.$iconUp=g.iconUp,m.$iconDown=g.iconDown,m.$select=function(e,t){f.select(e,t)},m.$moveIndex=function(e,t){f.$moveIndex(e,t)},m.$switchMeridian=function(e){f.switchMeridian(e)},f.update=function(e){angular.isDate(e)&&!isNaN(e.getTime())?(f.$date=e,angular.extend(b,{hour:e.getHours(),minute:e.getMinutes(),second:e.getSeconds(),millisecond:e.getMilliseconds()}),f.$build()):f.$isBuilt||f.$build()},f.select=function(e,t,a){(!n.$dateValue||isNaN(n.$dateValue.getTime()))&&(n.$dateValue='today'===g.defaultDate?new Date:new Date(1970,0,1)),angular.isDate(e)||(e=new Date(e)),0===t?n.$dateValue.setHours(e.getHours()):1===t?n.$dateValue.setMinutes(e.getMinutes()):2===t&&n.$dateValue.setSeconds(e.getSeconds()),n.$setViewValue(angular.copy(n.$dateValue)),n.$render(),g.autoclose&&!a&&s(function(){f.hide(!0)})},f.switchMeridian=function(e){if(n.$dateValue&&!isNaN(n.$dateValue.getTime())){var t=(e||n.$dateValue).getHours();n.$dateValue.setHours(12>t?t+12:t-12),n.$setViewValue(angular.copy(n.$dateValue)),n.$render()}},f.$build=function(){var e,t,n=m.midIndex=parseInt(g.length/2,10),a=[];for(e=0;e1*g.maxTime},m.$arrowAction=function(e,t){'picker'===g.arrowBehavior?f.$setTimeByStep(e,t):f.$moveIndex(e,t)},f.$setTimeByStep=function(e,t){var n=new Date(f.$date||y),a=n.getHours(),o=n.getMinutes(),i=n.getSeconds();0===t?n.setHours(a-parseInt(g.hourStep,10)*e):1===t?n.setMinutes(o-parseInt(g.minuteStep,10)*e):2===t&&n.setSeconds(i-parseInt(g.secondStep,10)*e),f.select(n,t,!0)},f.$moveIndex=function(e,t){var n;0===t?(n=new Date(1970,0,1,b.hour+e*g.length,b.minute,b.second),angular.extend(b,{hour:n.getHours()})):1===t?(n=new Date(1970,0,1,b.hour,b.minute+e*g.length*g.minuteStep,b.second),angular.extend(b,{minute:n.getMinutes()})):2===t&&(n=new Date(1970,0,1,b.hour,b.minute,b.second+e*g.length*g.secondStep),angular.extend(b,{second:n.getSeconds()})),f.$build()},f.$onMouseDown=function(e){if('input'!==e.target.nodeName.toLowerCase()&&e.preventDefault(),e.stopPropagation(),c){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},f.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return void f.hide(!0);var t=new Date(f.$date),n=t.getHours(),a=h(t,S).length,o=t.getMinutes(),i=h(t,x).length,r=t.getSeconds(),s=h(t,C).length,u=1,c=/(37|39)/.test(e.keyCode),d=2+1*T+1*E;c&&(37===e.keyCode?v=1>v?d-1:v-1:39===e.keyCode&&(v=d-1>v?v+1:0));var m=[0,a],$=0;38===e.keyCode&&($=-1),40===e.keyCode&&($=1);var w=2===v&&T,y=2===v&&!T||3===v&&T;0===v?(t.setHours(n+$*parseInt(g.hourStep,10)),a=h(t,S).length,m=[0,a]):1===v?(t.setMinutes(o+$*parseInt(g.minuteStep,10)),i=h(t,x).length,m=[a+u,i]):w?(t.setSeconds(r+$*parseInt(g.secondStep,10)),s=h(t,C).length,m=[a+u+i+u,s]):y&&(c||f.switchMeridian(),m=[a+u+i+u+(s+u)*T,2]),f.select(t,v,!0),l(m[0],m[1]),p.$digest()}};var M=f.init;f.init=function(){return u&&g.useNative?(t.prop('type','time'),void t.css('-webkit-appearance','textfield')):(c&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',d)),void M())};var A=f.destroy;f.destroy=function(){u&&g.useNative&&t.off('click',d),A()};var F=f.show;f.show=function(){!c&&t.attr('readonly')||t.attr('disabled')||(F(),s(function(){f.$element&&f.$element.on(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.on('keydown',f.$onKeyDown)},0,!1))};var V=f.hide;return f.hide=function(e){f.$isShown&&(f.$element&&f.$element.off(c?'touchstart':'mousedown',f.$onMouseDown),g.keyboard&&t&&t.off('keydown',f.$onKeyDown),V(e))},f}var u=/(ip[ao]d|iphone|android)/gi.test(t.navigator.userAgent),c='createTouch'in t.document&&u;return e.lang||(e.lang=i.getDefaultLocale()),l.defaults=e,l}]}).directive('bsTimepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$timepicker',function(e,t,a,o,i,r){var s=r.defaults,l=/(ip[ao]d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,a,u){function c(e){if(angular.isDate(e)){var t=isNaN(f.minTime)||new Date(e.getTime()).setFullYear(1970,0,1)>=f.minTime,n=isNaN(f.maxTime)||new Date(e.getTime()).setFullYear(1970,0,1)<=f.maxTime,a=t&&n;u.$setValidity('date',a),u.$setValidity('min',t),u.$setValidity('max',n),a&&(u.$dateValue=e)}}function d(){return!u.$dateValue||isNaN(u.$dateValue.getTime())?'':$(u.$dateValue,f.timeFormat)}var f={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','autoclose','timeType','timeFormat','timezone','modelTimeFormat','useNative','hourStep','minuteStep','secondStep','length','arrowBehavior','iconUp','iconDown','roundDisplay','id','prefixClass','prefixEvent','defaultDate'],function(e){angular.isDefined(a[e])&&(f[e]=a[e])});var p=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','roundDisplay'],function(e){angular.isDefined(a[e])&&p.test(a[e])&&(f[e]=!1)}),angular.forEach(['onBeforeShow','onShow','onBeforeHide','onHide'],function(t){var n='bs'+t.charAt(0).toUpperCase()+t.slice(1);angular.isDefined(a[n])&&(f[t]=e.$eval(a[n]))}),l&&(f.useNative||s.useNative)&&(f.timeFormat='HH:mm');var g=r(t,u,f);f=g.$options;var m=f.lang,$=function(e,t,n){return o.formatDate(e,t,m,n)};a.bsShow&&e.$watch(a.bsShow,function(e,t){g&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(timepicker),?/i)),e===!0?g.show():g.hide())});var h=i({format:f.timeFormat,lang:m});angular.forEach(['minTime','maxTime'],function(e){angular.isDefined(a[e])&&a.$observe(e,function(t){g.$options[e]=h.getTimeForAttribute(e,t),isNaN(g.$options[e])||g.$build(),c(u.$dateValue)})}),e.$watch(a.ngModel,function(e,t){g.update(u.$dateValue)},!0),u.$parsers.unshift(function(e){var t;if(!e)return u.$setValidity('date',!0),null;var a=angular.isDate(e)?e:h.parse(e,u.$dateValue);return!a||isNaN(a.getTime())?(u.$setValidity('date',!1),n):(c(a),'string'===f.timeType?(t=h.timezoneOffsetAdjust(a,f.timezone,!0),$(t,f.modelTimeFormat||f.timeFormat)):(t=h.timezoneOffsetAdjust(u.$dateValue,f.timezone,!0),'number'===f.timeType?t.getTime():'unix'===f.timeType?t.getTime()/1e3:'iso'===f.timeType?t.toISOString():new Date(t)))}),u.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?NaN:angular.isDate(e)?e:'string'===f.timeType?h.parse(e,null,f.modelTimeFormat):'unix'===f.timeType?new Date(1e3*e):new Date(e),u.$dateValue=h.timezoneOffsetAdjust(t,f.timezone),d()}),u.$render=function(){t.val(d())},e.$on('$destroy',function(){g&&g.destroy(),f=null,g=null})}}}]),angular.module('mgcrea.ngStrap.scrollspy',['mgcrea.ngStrap.helpers.debounce','mgcrea.ngStrap.helpers.dimensions']).provider('$scrollspy',function(){var e=this.$$spies={},n=this.defaults={debounce:150,throttle:100,offset:100};this.$get=['$window','$document','$rootScope','dimensions','debounce','throttle',function(a,o,i,r,s,l){function u(e,t){return e[0].nodeName&&e[0].nodeName.toLowerCase()===t.toLowerCase()}function c(o){var c=angular.extend({},n,o);c.element||(c.element=p);var g=u(c.element,'body'),m=g?d:c.element,$=g?'window':c.id;if(e[$])return e[$].$$count++,e[$];var h,v,w,y,b,D,S,k,x={},C=x.$trackedElements=[],T=[];return x.init=function(){this.$$count=1,y=s(this.checkPosition,c.debounce),b=l(this.checkPosition,c.throttle),m.on('click',this.checkPositionWithEventLoop),d.on('resize',y),m.on('scroll',b),D=s(this.checkOffsets,c.debounce),h=i.$on('$viewContentLoaded',D),v=i.$on('$includeContentLoaded',D),D(),$&&(e[$]=x)},x.destroy=function(){this.$$count--,this.$$count>0||(m.off('click',this.checkPositionWithEventLoop),d.off('resize',y),m.off('scroll',b),h(),v(),$&&delete e[$])},x.checkPosition=function(){if(T.length){if(k=(g?a.pageYOffset:m.prop('scrollTop'))||0,S=Math.max(a.innerHeight,f.prop('clientHeight')),kT[e+1].offsetTop))return x.$activateElement(T[e])}},x.checkPositionWithEventLoop=function(){setTimeout(x.checkPosition,1)},x.$activateElement=function(e){if(w){var t=x.$getTrackedElement(w);t&&(t.source.removeClass('active'),u(t.source,'li')&&u(t.source.parent().parent(),'li')&&t.source.parent().parent().removeClass('active'))}w=e.target,e.source.addClass('active'),u(e.source,'li')&&u(e.source.parent().parent(),'li')&&e.source.parent().parent().addClass('active')},x.$getTrackedElement=function(e){return C.filter(function(t){return t.target===e})[0]},x.checkOffsets=function(){angular.forEach(C,function(e){var n=t.querySelector(e.target);e.offsetTop=n?r.offset(n).top:null,c.offset&&null!==e.offsetTop&&(e.offsetTop-=1*c.offset)}),T=C.filter(function(e){return null!==e.offsetTop}).sort(function(e,t){return e.offsetTop-t.offsetTop}),y()},x.trackElement=function(e,t){C.push({target:e,source:t})},x.untrackElement=function(e,t){for(var n,a=C.length;a--;)if(C[a].target===e&&C[a].source===t){n=a;break}C.splice(n,1)},x.activate=function(e){C[e].addClass('active')},x.init(),x}var d=angular.element(a),f=angular.element(o.prop('documentElement')),p=angular.element(a.document.body);return c}]}).directive('bsScrollspy',['$rootScope','debounce','dimensions','$scrollspy',function(e,t,n,a){return{restrict:'EAC',link:function(e,t,n){var o={scope:e};angular.forEach(['offset','target'],function(e){angular.isDefined(n[e])&&(o[e]=n[e])});var i=a(o);i.trackElement(o.target,t),e.$on('$destroy',function(){i&&(i.untrackElement(o.target,t),i.destroy()),o=null,i=null})}}}]).directive('bsScrollspyList',['$rootScope','debounce','dimensions','$scrollspy',function(e,t,n,a){return{restrict:'A',compile:function(e,t){var n=e[0].querySelectorAll('li > a[href]');angular.forEach(n,function(e){var t=angular.element(e);t.parent().attr('bs-scrollspy','').attr('data-target',t.attr('href'))})}}}]),angular.module('mgcrea.ngStrap.select',['mgcrea.ngStrap.tooltip','mgcrea.ngStrap.helpers.parseOptions']).provider('$select',function(){var e=this.defaults={animation:'am-fade',prefixClass:'select',prefixEvent:'$select',placement:'bottom-left',templateUrl:'select/select.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,multiple:!1,allNoneButtons:!1,sort:!0,caretHtml:' ',placeholder:'Choose among the following...',allText:'All',noneText:'None',maxLength:3,maxLengthHtml:'selected',iconCheckmark:'glyphicon glyphicon-ok', +toggle:!1};this.$get=['$window','$document','$rootScope','$tooltip','$timeout',function(t,a,o,i,r){function s(o,s,l){var c={},d=angular.extend({},e,l);c=i(o,d);var f=c.$scope;f.$matches=[],d.multiple?f.$activeIndex=[]:f.$activeIndex=-1,f.$isMultiple=d.multiple,f.$showAllNoneButtons=d.allNoneButtons&&d.multiple,f.$iconCheckmark=d.iconCheckmark,f.$allText=d.allText,f.$noneText=d.noneText,f.$activate=function(e){f.$$postDigest(function(){c.activate(e)})},f.$select=function(e,t){f.$$postDigest(function(){c.select(e)})},f.$isVisible=function(){return c.$isVisible()},f.$isActive=function(e){return c.$isActive(e)},f.$selectAll=function(){for(var e=0;ee||e>=f.$matches.length)){var t=f.$matches[e].value;f.$apply(function(){c.activate(e),d.multiple?s.$setViewValue(f.$activeIndex.map(function(e){return angular.isUndefined(f.$matches[e])?null:f.$matches[e].value})):(d.toggle?s.$setViewValue(t===s.$modelValue?n:t):s.$setViewValue(t),c.hide())}),f.$emit(d.prefixEvent+'.select',t,e,c),angular.isDefined(d.onSelect)&&angular.isFunction(d.onSelect)&&d.onSelect(t,e,c)}},c.$updateActiveIndex=function(){d.multiple?angular.isArray(s.$modelValue)?f.$activeIndex=s.$modelValue.map(function(e){return c.$getIndex(e)}):f.$activeIndex=[]:angular.isDefined(s.$modelValue)&&f.$matches.length?f.$activeIndex=c.$getIndex(s.$modelValue):f.$activeIndex=-1},c.$isVisible=function(){return d.minLength&&s?f.$matches.length&&s.$viewValue.length>=d.minLength:f.$matches.length},c.$isActive=function(e){return d.multiple?-1!==f.$activeIndex.indexOf(e):f.$activeIndex===e},c.$getIndex=function(e){var t;for(t=f.$matches.length;t--&&!angular.equals(f.$matches[t].value,e););return t},c.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),u){var t=angular.element(e.target);t.triggerHandler('click')}},c.$onKeyDown=function(e){return/(9|13|38|40)/.test(e.keyCode)?(9!==e.keyCode&&(e.preventDefault(),e.stopPropagation()),d.multiple&&9===e.keyCode?c.hide():d.multiple||13!==e.keyCode&&9!==e.keyCode?void(d.multiple||(38===e.keyCode&&f.$activeIndex>0?f.$activeIndex--:38===e.keyCode&&f.$activeIndex<0?f.$activeIndex=f.$matches.length-1:40===e.keyCode&&f.$activeIndex0||e.indexOf('Trident/')>0||e.indexOf('Edge/')>0},c.$selectScrollFix=function(e){'UL'===a[0].activeElement.tagName&&(e.preventDefault(),e.stopImmediatePropagation(),e.target.focus())};var p=c.show;c.show=function(){p(),d.multiple&&c.$element.addClass('select-multiple'),r(function(){c.$element.on(u?'touchstart':'mousedown',c.$onMouseDown),d.keyboard&&o.on('keydown',c.$onKeyDown)},0,!1)};var g=c.hide;return c.hide=function(){!d.multiple&&angular.isUndefined(s.$modelValue)&&(f.$activeIndex=-1),c.$element.off(u?'touchstart':'mousedown',c.$onMouseDown),d.keyboard&&o.off('keydown',c.$onKeyDown),g(!0)},c}var l=/(ip[ao]d|iphone|android)/gi.test(t.navigator.userAgent),u='createTouch'in t.document&&l;return s.defaults=e,s}]}).directive('bsSelect',['$window','$parse','$q','$select','$parseOptions',function(e,t,n,a,o){var i=a.defaults;return{restrict:'EAC',require:'ngModel',link:function(e,t,n,r){var s={scope:e,placeholder:i.placeholder};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','placeholder','allNoneButtons','maxLength','maxLengthHtml','allText','noneText','iconCheckmark','autoClose','id','sort','caretHtml','prefixClass','prefixEvent','toggle'],function(e){angular.isDefined(n[e])&&(s[e]=n[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container','allNoneButtons','sort'],function(e){angular.isDefined(n[e])&&l.test(n[e])&&(s[e]=!1)}),angular.forEach(['onBeforeShow','onShow','onBeforeHide','onHide','onSelect'],function(t){var a='bs'+t.charAt(0).toUpperCase()+t.slice(1);angular.isDefined(n[a])&&(s[t]=e.$eval(n[a]))});var u=t.attr('data-multiple');if(angular.isDefined(u)&&(l.test(u)?s.multiple=!1:s.multiple=u),'select'===t[0].nodeName.toLowerCase()){var c=t;c.css('display','none'),t=angular.element(''),c.after(t)}var d=o(n.bsOptions),f=a(t,r,s);f.$isIE()&&t[0].addEventListener('blur',f.$selectScrollFix);var p=d.$match[7].replace(/\|.+/,'').trim();e.$watch(p,function(t,n){d.valuesFn(e,r).then(function(e){f.update(e),r.$render()})},!0),e.$watch(n.ngModel,function(e,t){f.$updateActiveIndex(),r.$render()},!0),r.$render=function(){var e,n;s.multiple&&angular.isArray(r.$modelValue)?(e=r.$modelValue.map(function(e){return n=f.$getIndex(e),-1!==n?f.$scope.$matches[n].label:!1}).filter(angular.isDefined),e=e.length>(s.maxLength||i.maxLength)?e.length+' '+(s.maxLengthHtml||i.maxLengthHtml):e.join(', ')):(n=f.$getIndex(r.$modelValue),e=-1!==n?f.$scope.$matches[n].label:!1),t.html((e||s.placeholder)+(s.caretHtml||i.caretHtml))},s.multiple&&(r.$isEmpty=function(e){return!e||0===e.length}),e.$on('$destroy',function(){f&&f.destroy(),s=null,f=null})}}}]),angular.module('mgcrea.ngStrap.popover',['mgcrea.ngStrap.tooltip']).provider('$popover',function(){var e=this.defaults={animation:'am-fade',customClass:'',container:!1,target:!1,placement:'right',templateUrl:'popover/popover.tpl.html',contentTemplate:!1,trigger:'click',keyboard:!0,html:!1,title:'',content:'',delay:0,autoClose:!1};this.$get=['$tooltip',function(t){function n(n,a){var o=angular.extend({},e,a),i=t(n,o);return o.content&&(i.$scope.content=o.content),i}return n}]}).directive('bsPopover',['$window','$sce','$popover',function(e,t,n){var a=e.requestAnimationFrame||e.setTimeout;return{restrict:'EAC',scope:!0,link:function(e,o,i){var r,s={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','container','delay','trigger','html','animation','customClass','autoClose','id','prefixClass','prefixEvent'],function(e){angular.isDefined(i[e])&&(s[e]=i[e])});var l=/^(false|0|)$/i;angular.forEach(['html','container','autoClose'],function(e){angular.isDefined(i[e])&&l.test(i[e])&&(s[e]=!1)}),angular.forEach(['onBeforeShow','onShow','onBeforeHide','onHide'],function(t){var n='bs'+t.charAt(0).toUpperCase()+t.slice(1);angular.isDefined(i[n])&&(s[t]=e.$eval(i[n]))});var u=o.attr('data-target');angular.isDefined(u)&&(l.test(u)?s.target=!1:s.target=u),angular.forEach(['title','content'],function(n){i[n]&&i.$observe(n,function(o,i){e[n]=t.trustAsHtml(o),angular.isDefined(i)&&a(function(){r&&r.$applyPlacement()})})}),i.bsPopover&&e.$watch(i.bsPopover,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t,angular.isDefined(n)&&a(function(){r&&r.$applyPlacement()})},!0),i.bsShow&&e.$watch(i.bsShow,function(e,t){r&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(popover),?/i)),e===!0?r.show():r.hide())}),i.viewport&&e.$watch(i.viewport,function(e){r&&angular.isDefined(e)&&r.setViewport(e)}),r=n(o,s),e.$on('$destroy',function(){r&&r.destroy(),s=null,r=null})}}}]),angular.module('mgcrea.ngStrap.navbar',[]).provider('$navbar',function(){var e=this.defaults={activeClass:'active',routeAttr:'data-match-route',strict:!1};this.$get=function(){return{defaults:e}}}).directive('bsNavbar',['$window','$location','$navbar',function(e,t,n){var a=n.defaults;return{restrict:'A',link:function(e,n,o,i){var r=angular.copy(a);angular.forEach(Object.keys(a),function(e){angular.isDefined(o[e])&&(r[e]=o[e])}),e.$watch(function(){return t.path()},function(e,t){var a=n[0].querySelectorAll('li['+r.routeAttr+']');angular.forEach(a,function(t){var n=angular.element(t),a=n.attr(r.routeAttr).replace('/','\\/');r.strict&&(a='^'+a+'$');var o=new RegExp(a,'i');o.test(e)?n.addClass(r.activeClass):n.removeClass(r.activeClass)})})}}}]),angular.module('mgcrea.ngStrap.modal',['mgcrea.ngStrap.core','mgcrea.ngStrap.helpers.dimensions']).provider('$modal',function(){var e=this.defaults={animation:'am-fade',backdropAnimation:'am-fade',customClass:'',prefixClass:'modal',prefixEvent:'modal',placement:'top',templateUrl:'modal/modal.tpl.html',template:'',contentTemplate:!1,container:!1,element:null,backdrop:!0,keyboard:!0,html:!1,show:!0,size:null};this.$get=['$window','$rootScope','$bsCompiler','$animate','$timeout','$sce','dimensions',function(n,a,o,i,r,s,l){function u(t){function n(){T.$emit(x.prefixEvent+'.show',k),angular.isDefined(x.onShow)&&angular.isFunction(x.onShow)&&x.onShow(k)}function r(){T.$emit(x.prefixEvent+'.hide',k),angular.isDefined(x.onHide)&&angular.isFunction(x.onHide)&&x.onHide(k),g.removeClass(x.prefixClass+'-open'),x.animation&&g.removeClass(x.prefixClass+'-with-'+x.animation)}function l(){x.backdrop&&(M.on('click',b),F.on('click',b),F.on('wheel',D))}function u(){x.backdrop&&(M.off('click',b),F.off('click',b),F.off('wheel',D))}function w(){x.keyboard&&M.on('keyup',k.$onKeyUp)}function y(){x.keyboard&&M.off('keyup',k.$onKeyUp)}function b(e){e.target===e.currentTarget&&('static'===x.backdrop?k.focus():k.hide())}function D(e){e.preventDefault()}function S(){k.$isShown&&null!==M&&(u(),y()),A&&(A.$destroy(),A=null),M&&(M.remove(),M=k.$element=null)}var k={},x=k.$options=angular.extend({},e,t),C=k.$promise=o.compile(x),T=k.$scope=x.scope&&x.scope.$new()||a.$new();x.element||x.container||(x.container='body'),k.$id=x.id||x.element&&x.element.attr('id')||'',f(['title','content'],function(e){x[e]&&(T[e]=s.trustAsHtml(x[e]))}),T.$hide=function(){T.$$postDigest(function(){k.hide()})},T.$show=function(){T.$$postDigest(function(){k.show()})},T.$toggle=function(){T.$$postDigest(function(){k.toggle()})},k.$isShown=T.$isShown=!1;var E,M,A,F=angular.element('
');return F.css({position:'fixed',top:'0px',left:'0px',bottom:'0px',right:'0px'}),C.then(function(e){E=e,k.init()}),k.init=function(){x.show&&T.$$postDigest(function(){k.show()})},k.destroy=function(){S(),F&&(F.remove(),F=null),T.$destroy()},k.show=function(){if(!k.$isShown){var e,t;if(angular.isElement(x.container)?(e=x.container,t=x.container[0].lastChild?angular.element(x.container[0].lastChild):null):x.container?(e=d(x.container),t=e[0]&&e[0].lastChild?angular.element(e[0].lastChild):null):(e=null,t=x.element),M&&S(),A=k.$scope.$new(),M=k.$element=E.link(A,function(e,t){}),x.backdrop&&(M.css({'z-index':$+20*m}),F.css({'z-index':h+20*m}),m++),!T.$emit(x.prefixEvent+'.show.before',k).defaultPrevented){angular.isDefined(x.onBeforeShow)&&angular.isFunction(x.onBeforeShow)&&x.onBeforeShow(k),M.css({display:'block'}).addClass(x.placement),x.customClass&&M.addClass(x.customClass),x.size&&v[x.size]&&angular.element(d('.modal-dialog',M[0])).addClass(v[x.size]),x.animation&&(x.backdrop&&F.addClass(x.backdropAnimation),M.addClass(x.animation)),x.backdrop&&i.enter(F,g,null),angular.version.minor<=2?i.enter(M,e,t,n):i.enter(M,e,t).then(n),k.$isShown=T.$isShown=!0,c(T);var a=M[0];p(function(){a.focus()}),g.addClass(x.prefixClass+'-open'),x.animation&&g.addClass(x.prefixClass+'-with-'+x.animation),l(),w()}}},k.hide=function(){k.$isShown&&(T.$emit(x.prefixEvent+'.hide.before',k).defaultPrevented||(angular.isDefined(x.onBeforeHide)&&angular.isFunction(x.onBeforeHide)&&x.onBeforeHide(k),angular.version.minor<=2?i.leave(M,r):i.leave(M).then(r),x.backdrop&&(m--,i.leave(F)),k.$isShown=T.$isShown=!1,c(T),u(),y()))},k.toggle=function(){k.$isShown?k.hide():k.show()},k.focus=function(){M[0].focus()},k.$onKeyUp=function(e){27===e.which&&k.$isShown&&(k.hide(),e.stopPropagation())},k}function c(e){e.$$phase||e.$root&&e.$root.$$phase||e.$digest()}function d(e,n){return angular.element((n||t).querySelectorAll(e))}var f=angular.forEach,p=n.requestAnimationFrame||n.setTimeout,g=angular.element(n.document.body),m=0,$=1050,h=1040,v={lg:'modal-lg',sm:'modal-sm'};return u}]}).directive('bsModal',['$window','$sce','$parse','$modal',function(e,t,n,a){return{restrict:'EAC',scope:!0,link:function(e,n,o,i){var r={scope:e,element:n,show:!1};angular.forEach(['template','templateUrl','controller','controllerAs','contentTemplate','placement','backdrop','keyboard','html','container','animation','backdropAnimation','id','prefixEvent','prefixClass','customClass','modalClass','size'],function(e){angular.isDefined(o[e])&&(r[e]=o[e])}),r.modalClass&&(r.customClass=r.modalClass);var s=/^(false|0|)$/i;angular.forEach(['backdrop','keyboard','html','container'],function(e){angular.isDefined(o[e])&&s.test(o[e])&&(r[e]=!1)}),angular.forEach(['onBeforeShow','onShow','onBeforeHide','onHide'],function(t){var n='bs'+t.charAt(0).toUpperCase()+t.slice(1);angular.isDefined(o[n])&&(r[t]=e.$eval(o[n]))}),angular.forEach(['title','content'],function(n){o[n]&&o.$observe(n,function(a,o){e[n]=t.trustAsHtml(a)})}),o.bsModal&&e.$watch(o.bsModal,function(t,n){angular.isObject(t)?angular.extend(e,t):e.content=t},!0);var l=a(r);n.on(o.trigger||'click',l.toggle),e.$on('$destroy',function(){l&&l.destroy(),r=null,l=null})}}}]),angular.module('mgcrea.ngStrap.dropdown',['mgcrea.ngStrap.tooltip']).provider('$dropdown',function(){var e=this.defaults={animation:'am-fade',prefixClass:'dropdown',prefixEvent:'dropdown',placement:'bottom-left',templateUrl:'dropdown/dropdown.tpl.html',trigger:'click',container:!1,keyboard:!0,html:!1,delay:0};this.$get=['$window','$rootScope','$tooltip','$timeout',function(t,n,a,o){function i(t,i){function l(e){return e.target!==t[0]?e.target!==t[0]&&u.hide():void 0}var u={},c=angular.extend({},e,i);u.$scope=c.scope&&c.scope.$new()||n.$new(),u=a(t,c);var d=t.parent();u.$onKeyDown=function(e){if(/(38|40)/.test(e.keyCode)){e.preventDefault(),e.stopPropagation();var t=angular.element(u.$element[0].querySelectorAll('li:not(.divider) a'));if(t.length){var n;angular.forEach(t,function(e,t){s&&s.call(e,':focus')&&(n=t)}),38===e.keyCode&&n>0?n--:40===e.keyCode&&n=0&&(t.template=o.outerHTML,t.templateUrl=n,o.parentNode.removeChild(o))}return function(e,n,o){var i={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','keyboard','html','animation','id','autoClose'],function(e){angular.isDefined(t[e])&&(i[e]=t[e])});var r=/^(false|0|)$/i;angular.forEach(['html','container'],function(e){angular.isDefined(o[e])&&r.test(o[e])&&(i[e]=!1)}),angular.forEach(['onBeforeShow','onShow','onBeforeHide','onHide'],function(t){var n='bs'+t.charAt(0).toUpperCase()+t.slice(1);angular.isDefined(o[n])&&(i[t]=e.$eval(o[n]))}),o.bsDropdown&&e.$watch(o.bsDropdown,function(t,n){e.content=t},!0);var s=a(n,i);o.bsShow&&e.$watch(o.bsShow,function(e,t){s&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(dropdown),?/i)),e===!0?s.show():s.hide())}),e.$on('$destroy',function(){s&&s.destroy(),i=null,s=null})}}}}]),angular.version.minor<3&&angular.version.dot<14&&angular.module('ng').factory('$$rAF',['$window','$timeout',function(e,t){var n=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame,a=e.cancelAnimationFrame||e.webkitCancelAnimationFrame||e.mozCancelAnimationFrame||e.webkitCancelRequestAnimationFrame,o=!!n,i=o?function(e){var t=n(e);return function(){a(t)}}:function(e){var n=t(e,16.66,!1);return function(){t.cancel(n)}};return i.supported=o,i}]),angular.module('mgcrea.ngStrap.helpers.parseOptions',[]).provider('$parseOptions',function(){var e=this.defaults={regexp:/^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/};this.$get=['$parse','$q',function(t,n){function a(a,o){function i(e,t){return e.map(function(e,n){var a,o,i={};return i[c]=e,a=u(t,i),o=p(t,i),{label:a,value:o,index:n}})}var r={},s=angular.extend({},e,o);r.$values=[];var l,u,c,d,f,p,g;return r.init=function(){r.$match=l=a.match(s.regexp),u=t(l[2]||l[1]),c=l[4]||l[6],d=l[5],f=t(l[3]||''),p=t(l[2]?l[1]:c),g=t(l[7])},r.valuesFn=function(e,t){return n.when(g(e,t)).then(function(t){return angular.isArray(t)||(t=[]),r.$values=t.length?i(t,e):[],r.$values})},r.displayValue=function(e){var t={};return t[c]=e,u(t)},r.init(),r}return a}]}),angular.module('mgcrea.ngStrap.helpers.dimensions',[]).factory('dimensions',function(){function t(e){var t=e.ownerDocument,o=e.offsetParent||t;if(a(o,'#document'))return t.documentElement;for(;o&&!a(o,'html')&&'static'===n.css(o,'position');)o=o.offsetParent;return o||t.documentElement}var n={},a=n.nodeName=function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()};return n.css=function(t,n,a){var o;return o=t.currentStyle?t.currentStyle[n]:e.getComputedStyle?e.getComputedStyle(t)[n]:t.style[n],a===!0?parseFloat(o)||0:o},n.offset=function(t){var n=t.getBoundingClientRect(),a=t.ownerDocument;return{width:n.width||t.offsetWidth,height:n.height||t.offsetHeight,top:n.top+(e.pageYOffset||a.documentElement.scrollTop)-(a.documentElement.clientTop||0),left:n.left+(e.pageXOffset||a.documentElement.scrollLeft)-(a.documentElement.clientLeft||0)}},n.setOffset=function(e,t,a){var o,i,r,s,l,u,c,d=n.css(e,'position'),f=angular.element(e),p={};'static'===d&&(e.style.position='relative'),l=n.offset(e),r=n.css(e,'top'),u=n.css(e,'left'),c=('absolute'===d||'fixed'===d)&&(r+u).indexOf('auto')>-1,c?(o=n.position(e),s=o.top,i=o.left):(s=parseFloat(r)||0,i=parseFloat(u)||0),angular.isFunction(t)&&(t=t.call(e,a,l)),null!==t.top&&(p.top=t.top-l.top+s),null!==t.left&&(p.left=t.left-l.left+i),'using'in t?t.using.call(f,p):f.css({top:p.top+'px',left:p.left+'px'})},n.position=function(e){var o,i,r={top:0,left:0};return'fixed'===n.css(e,'position')?i=e.getBoundingClientRect():(o=t(e),i=n.offset(e),a(o,'html')||(r=n.offset(o)),r.top+=n.css(o,'borderTopWidth',!0),r.left+=n.css(o,'borderLeftWidth',!0)),{width:e.offsetWidth,height:e.offsetHeight,top:i.top-r.top-n.css(e,'marginTop',!0),left:i.left-r.left-n.css(e,'marginLeft',!0)}},n.height=function(e,t){var a=e.offsetHeight;return t?a+=n.css(e,'marginTop',!0)+n.css(e,'marginBottom',!0):a-=n.css(e,'paddingTop',!0)+n.css(e,'paddingBottom',!0)+n.css(e,'borderTopWidth',!0)+n.css(e,'borderBottomWidth',!0),a},n.width=function(e,t){var a=e.offsetWidth;return t?a+=n.css(e,'marginLeft',!0)+n.css(e,'marginRight',!0):a-=n.css(e,'paddingLeft',!0)+n.css(e,'paddingRight',!0)+n.css(e,'borderLeftWidth',!0)+n.css(e,'borderRightWidth',!0),a},n}),angular.module('mgcrea.ngStrap.helpers.debounce',[]).factory('debounce',['$timeout',function(e){return function(t,n,a){var o=null;return function(){var i=this,r=arguments,s=a&&!o;return o&&e.cancel(o),o=e(function(){o=null,a||t.apply(i,r)},n,!1),s&&t.apply(i,r),o}}}]).factory('throttle',['$timeout',function(e){return function(t,n,a){var o=null;return a||(a={}),function(){var i=this,r=arguments;o||(a.leading!==!1&&t.apply(i,r),o=e(function(){o=null,a.trailing!==!1&&t.apply(i,r)},n,!1))}}}]),angular.module('mgcrea.ngStrap.helpers.dateParser',[]).provider('$dateParser',['$localeProvider',function(e){function t(){this.year=1970,this.month=0,this.day=1,this.hours=0,this.minutes=0,this.seconds=0,this.milliseconds=0}function n(){}function a(e){return!isNaN(parseFloat(e))&&isFinite(e)}function o(e,t){for(var n=e.length,a=t.toString().toLowerCase(),o=0;n>o;o++)if(e[o].toLowerCase()===a)return o;return-1}t.prototype.setMilliseconds=function(e){this.milliseconds=e},t.prototype.setSeconds=function(e){this.seconds=e},t.prototype.setMinutes=function(e){this.minutes=e},t.prototype.setHours=function(e){this.hours=e},t.prototype.getHours=function(){return this.hours},t.prototype.setDate=function(e){this.day=e},t.prototype.setMonth=function(e){this.month=e},t.prototype.setFullYear=function(e){this.year=e},t.prototype.fromDate=function(e){return this.year=e.getFullYear(),this.month=e.getMonth(),this.day=e.getDate(),this.hours=e.getHours(),this.minutes=e.getMinutes(),this.seconds=e.getSeconds(),this.milliseconds=e.getMilliseconds(),this},t.prototype.toDate=function(){return new Date(this.year,this.month,this.day,this.hours,this.minutes,this.seconds,this.milliseconds)};var i=t.prototype,r=this.defaults={format:'shortDate',strict:!1};this.$get=['$locale','dateFilter',function(e,s){var l=function(l){function u(e){var t=c(e);return g(t)}function c(e){var t=d(e),n=t.replace(/''/g,'\\\''),a=/('(?:\\'|.)*?')/,o=n.split(a),i=Object.keys(b),r=[];return angular.forEach(o,function(e){if(f(e))e=p(e);else for(var t=0;t=1*e&&2===e.length?this.setFullYear(2e3+1*e):this.setFullYear(1*e)}};return y.init=function(){y.$format=e.DATETIME_FORMATS[w.format]||w.format,h=u(y.$format),v=m(y.$format)},y.isValid=function(e){return angular.isDate(e)?!isNaN(e.getTime()):h.test(e)},y.parse=function(n,a,o,i){o&&(o=e.DATETIME_FORMATS[o]||o),angular.isDate(n)&&(n=s(n,o||y.$format,i));var r=o?u(o):h,l=o?m(o):v,c=r.exec(n);if(!c)return!1;for(var d=a&&!isNaN(a.getTime())?(new t).fromDate(a):(new t).fromDate(new Date(1970,0,1,0)),f=0;f12?e.getHours()+2:0),e):null},y.timezoneOffsetAdjust=function(e,t,n){return e?(t&&'UTC'===t&&(e=new Date(e.getTime()),e.setMinutes(e.getMinutes()+(n?-1:1)*e.getTimezoneOffset())),e):null},y.init(),y};return l}]}]),angular.module('mgcrea.ngStrap.helpers.dateFormatter',[]).service('$dateFormatter',['$locale','dateFilter',function(e,t){function n(e){return/(h+)([:\.])?(m+)([:\.])?(s*)[ ]?(a?)/i.exec(e).slice(1)}this.getDefaultLocale=function(){return e.id},this.getDatetimeFormat=function(t,n){return e.DATETIME_FORMATS[t]||t},this.weekdaysShort=function(t){return e.DATETIME_FORMATS.SHORTDAY},this.hoursFormat=function(e){return n(e)[0]},this.minutesFormat=function(e){return n(e)[2]},this.secondsFormat=function(e){return n(e)[4]},this.timeSeparator=function(e){return n(e)[1]},this.showSeconds=function(e){return!!n(e)[4]},this.showAM=function(e){return!!n(e)[5]},this.formatDate=function(e,n,a,o){return t(e,n,o)}}]),angular.module('mgcrea.ngStrap.core',[]).service('$bsCompiler',a),angular.module('mgcrea.ngStrap.datepicker',['mgcrea.ngStrap.helpers.dateParser','mgcrea.ngStrap.helpers.dateFormatter','mgcrea.ngStrap.tooltip']).provider('$datepicker',function(){var e=this.defaults={animation:'am-fade',prefixClass:'datepicker',placement:'bottom-left',templateUrl:'datepicker/datepicker.tpl.html',trigger:'focus',container:!1,keyboard:!0,html:!1,delay:0,useNative:!1,dateType:'date',dateFormat:'shortDate',timezone:null,modelDateFormat:null,dayFormat:'dd',monthFormat:'MMM',yearFormat:'yyyy',monthTitleFormat:'MMMM yyyy',yearTitleFormat:'yyyy',strictFormat:!1,autoclose:!1,minDate:-(1/0),maxDate:+(1/0),startView:0,minView:0,startWeek:0,daysOfWeekDisabled:'',hasToday:!1,hasClear:!1,iconLeft:'glyphicon glyphicon-chevron-left',iconRight:'glyphicon glyphicon-chevron-right'};this.$get=['$window','$document','$rootScope','$sce','$dateFormatter','datepickerViews','$tooltip','$timeout',function(t,n,a,o,i,r,s,l){function u(t,n,a){function o(e){e.selected=u.$isSelected(e.date)}function i(){t[0].focus()}var u=s(t,angular.extend({},e,a)),f=a.scope,p=u.$options,g=u.$scope;p.startView&&(p.startView-=p.minView);var m=r(u);u.$views=m.views;var $=m.viewDate;g.$mode=p.startView,g.$iconLeft=p.iconLeft,g.$iconRight=p.iconRight,g.$hasToday=p.hasToday,g.$hasClear=p.hasClear;var h=u.$views[g.$mode];g.$select=function(e){u.select(e)},g.$selectPane=function(e){u.$selectPane(e)},g.$toggleMode=function(){u.setMode((g.$mode+1)%u.$views.length)},g.$setToday=function(){p.autoclose?(u.setMode(0),u.select(new Date)):u.select(new Date,!0)},g.$clear=function(){p.autoclose?(u.setMode(0),u.select(null)):u.select(null,!0)},u.update=function(e){angular.isDate(e)&&!isNaN(e.getTime())&&(u.$date=e,h.update.call(h,e)),u.$build(!0)},u.updateDisabledDates=function(e){p.disabledDateRanges=e;for(var t=0,n=g.rows.length;n>t;t++)angular.forEach(g.rows[t],u.$setDisabledEl)},u.select=function(e,t){angular.isDate(e)?(!angular.isDate(n.$dateValue)||isNaN(n.$dateValue.getTime()))&&(n.$dateValue=new Date(e)):n.$dateValue=null,!g.$mode||t?(n.$setViewValue(angular.copy(e)),n.$render(),p.autoclose&&!t&&l(function(){u.hide(!0)})):(angular.extend($,{year:e.getFullYear(),month:e.getMonth(),date:e.getDate()}),u.setMode(g.$mode-1),u.$build())},u.setMode=function(e){g.$mode=e,h=u.$views[g.$mode],u.$build()},u.$build=function(e){e===!0&&h.built||(e!==!1||h.built)&&h.build.call(h)},u.$updateSelected=function(){for(var e=0,t=g.rows.length;t>e;e++)angular.forEach(g.rows[e],o)},u.$isSelected=function(e){return h.isSelected(e)},u.$setDisabledEl=function(e){e.disabled=h.isDisabled(e.date)},u.$selectPane=function(e){var t=h.steps,n=new Date(Date.UTC($.year+(t.year||0)*e,$.month+(t.month||0)*e,1));angular.extend($,{year:n.getUTCFullYear(),month:n.getUTCMonth(),date:n.getUTCDate()}),u.$build()},u.$onMouseDown=function(e){if(e.preventDefault(),e.stopPropagation(),d){var t=angular.element(e.target);'button'!==t[0].nodeName.toLowerCase()&&(t=t.parent()),t.triggerHandler('click')}},u.$onKeyDown=function(e){if(/(38|37|39|40|13)/.test(e.keyCode)&&!e.shiftKey&&!e.altKey){if(e.preventDefault(),e.stopPropagation(),13===e.keyCode)return void(g.$mode?g.$apply(function(){u.setMode(g.$mode-1)}):u.hide(!0));h.onKeyDown(e),f.$digest()}};var v=u.init;u.init=function(){return c&&p.useNative?(t.prop('type','date'),void t.css('-webkit-appearance','textfield')):(d&&(t.prop('type','text'),t.attr('readonly','true'),t.on('click',i)),void v())};var w=u.destroy;u.destroy=function(){c&&p.useNative&&t.off('click',i),w()};var y=u.show;u.show=function(){!d&&t.attr('readonly')||t.attr('disabled')||(y(),l(function(){u.$isShown&&(u.$element.on(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.on('keydown',u.$onKeyDown))},0,!1))};var b=u.hide;return u.hide=function(e){u.$isShown&&(u.$element.off(d?'touchstart':'mousedown',u.$onMouseDown),p.keyboard&&t.off('keydown',u.$onKeyDown),b(e))},u}var c=/(ip[ao]d|iphone|android)/gi.test(t.navigator.userAgent),d='createTouch'in t.document&&c;return e.lang||(e.lang=i.getDefaultLocale()),u.defaults=e,u}]}).directive('bsDatepicker',['$window','$parse','$q','$dateFormatter','$dateParser','$datepicker',function(e,t,n,a,o,i){var r=/(ip[ao]d|iphone|android)/gi.test(e.navigator.userAgent);return{restrict:'EAC',require:'ngModel',link:function(e,t,n,s){function l(e){return e&&e.length?e:null}function u(e){if(angular.isDate(e)){var t=isNaN(p.$options.minDate)||e.getTime()>=p.$options.minDate,n=isNaN(p.$options.maxDate)||e.getTime()<=p.$options.maxDate,a=t&&n;s.$setValidity('date',a),s.$setValidity('min',t),s.$setValidity('max',n),a&&(s.$dateValue=e)}}function c(){return!s.$dateValue||isNaN(s.$dateValue.getTime())?'':m(s.$dateValue,d.dateFormat)}var d={scope:e};angular.forEach(['template','templateUrl','controller','controllerAs','placement','container','delay','trigger','html','animation','autoclose','dateType','dateFormat','timezone','modelDateFormat','dayFormat','strictFormat','startWeek','startDate','useNative','lang','startView','minView','iconLeft','iconRight','daysOfWeekDisabled','id','prefixClass','prefixEvent','hasToday','hasClear'],function(e){angular.isDefined(n[e])&&(d[e]=n[e])});var f=/^(false|0|)$/i;angular.forEach(['html','container','autoclose','useNative','hasToday','hasClear'],function(e){angular.isDefined(n[e])&&f.test(n[e])&&(d[e]=!1)}),angular.forEach(['onBeforeShow','onShow','onBeforeHide','onHide'],function(t){var a='bs'+t.charAt(0).toUpperCase()+t.slice(1);angular.isDefined(n[a])&&(d[t]=e.$eval(n[a]))});var p=i(t,s,d);d=p.$options,r&&d.useNative&&(d.dateFormat='yyyy-MM-dd');var g=d.lang,m=function(e,t){return a.formatDate(e,t,g)},$=o({format:d.dateFormat,lang:g,strict:d.strictFormat});n.bsShow&&e.$watch(n.bsShow,function(e,t){p&&angular.isDefined(e)&&(angular.isString(e)&&(e=!!e.match(/true|,?(datepicker),?/i)),e===!0?p.show():p.hide())}),angular.forEach(['minDate','maxDate'],function(e){ +angular.isDefined(n[e])&&n.$observe(e,function(t){p.$options[e]=$.getDateForAttribute(e,t),isNaN(p.$options[e])||p.$build(!1),u(s.$dateValue)})}),angular.isDefined(n.dateFormat)&&n.$observe('dateFormat',function(e){p.$options.dateFormat=e}),e.$watch(n.ngModel,function(e,t){p.update(s.$dateValue)},!0),angular.isDefined(n.disabledDates)&&e.$watch(n.disabledDates,function(e,t){e=l(e),t=l(t),e&&p.updateDisabledDates(e)}),s.$parsers.unshift(function(e){var t;if(!e)return s.$setValidity('date',!0),null;var n=$.parse(e,s.$dateValue);return!n||isNaN(n.getTime())?void s.$setValidity('date',!1):(u(n),'string'===d.dateType?(t=$.timezoneOffsetAdjust(n,d.timezone,!0),m(t,d.modelDateFormat||d.dateFormat)):(t=$.timezoneOffsetAdjust(s.$dateValue,d.timezone,!0),'number'===d.dateType?t.getTime():'unix'===d.dateType?t.getTime()/1e3:'iso'===d.dateType?t.toISOString():new Date(t)))}),s.$formatters.push(function(e){var t;return t=angular.isUndefined(e)||null===e?NaN:angular.isDate(e)?e:'string'===d.dateType?$.parse(e,null,d.modelDateFormat):'unix'===d.dateType?new Date(1e3*e):new Date(e),s.$dateValue=$.timezoneOffsetAdjust(t,d.timezone),c()}),s.$render=function(){t.val(c())},e.$on('$destroy',function(){p&&p.destroy(),d=null,p=null})}}}]).provider('datepickerViews',function(){function e(e,t){for(var n=[];e.length>0;)n.push(e.splice(0,t));return n}function t(e,t){return(e%t+t)%t}this.$get=['$dateFormatter','$dateParser','$sce',function(n,a,o){return function(i){var r=i.$scope,s=i.$options,l=s.lang,u=function(e,t){return n.formatDate(e,t,l)},c=a({format:s.dateFormat,lang:l,strict:s.strictFormat}),d=n.weekdaysShort(l),f=d.slice(s.startWeek).concat(d.slice(0,s.startWeek)),p=o.trustAsHtml(''+f.join('')+''),g=i.$date||(s.startDate?c.getDateForAttribute('startDate',s.startDate):new Date),m={year:g.getFullYear(),month:g.getMonth(),date:g.getDate()},$=[{format:s.dayFormat,split:7,steps:{month:1},update:function(e,t){!this.built||t||e.getFullYear()!==m.year||e.getMonth()!==m.month?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):(e.getDate()!==m.date||1===e.getDate())&&(m.date=i.$date.getDate(),i.$updateSelected())},build:function(){var n=new Date(m.year,m.month,1),a=n.getTimezoneOffset(),o=new Date(+n-864e5*t(n.getDay()-s.startWeek,7)),l=o.getTimezoneOffset(),d=c.timezoneOffsetAdjust(new Date,s.timezone).toDateString();l!==a&&(o=new Date(+o+6e4*(l-a)));for(var f,g=[],$=0;42>$;$++)f=c.daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth(),o.getDate()+$)),g.push({date:f,isToday:f.toDateString()===d,label:u(f,this.format),selected:i.$date&&this.isSelected(f),muted:f.getMonth()!==m.month,disabled:this.isDisabled(f)});r.title=u(n,s.monthTitleFormat),r.showLabels=!0,r.labels=p,r.rows=e(g,this.split),r.isTodayDisabled=this.isDisabled(new Date),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()&&e.getDate()===i.$date.getDate()},isDisabled:function(e){var t=e.getTime();if(ts.maxDate)return!0;if(-1!==s.daysOfWeekDisabled.indexOf(e.getDay()))return!0;if(s.disabledDateRanges)for(var n=0;n=s.disabledDateRanges[n].start&&t<=s.disabledDateRanges[n].end)return!0;return!1},onKeyDown:function(e){if(i.$date){var t,n=i.$date.getTime();37===e.keyCode?t=new Date(n-864e5):38===e.keyCode?t=new Date(n-6048e5):39===e.keyCode?t=new Date(n+864e5):40===e.keyCode&&(t=new Date(n+6048e5)),this.isDisabled(t)||i.select(t,!0)}}},{name:'month',format:s.monthFormat,split:4,steps:{year:1},update:function(e,t){this.built&&e.getFullYear()===m.year?e.getMonth()!==m.month&&(angular.extend(m,{month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected()):(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build())},build:function(){for(var t,n=[],a=0;12>a;a++)t=new Date(m.year,a,1),n.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=u(t,s.yearTitleFormat),r.showLabels=!1,r.rows=e(n,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()&&e.getMonth()===i.$date.getMonth()},isDisabled:function(e){var t=+new Date(e.getFullYear(),e.getMonth()+1,0);return ts.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getMonth(),n=new Date(i.$date);37===e.keyCode?n.setMonth(t-1):38===e.keyCode?n.setMonth(t-4):39===e.keyCode?n.setMonth(t+1):40===e.keyCode&&n.setMonth(t+4),this.isDisabled(n)||i.select(n,!0)}}},{name:'year',format:s.yearFormat,split:4,steps:{year:12},update:function(e,t){!this.built||t||parseInt(e.getFullYear()/20,10)!==parseInt(m.year/20,10)?(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$build()):e.getFullYear()!==m.year&&(angular.extend(m,{year:i.$date.getFullYear(),month:i.$date.getMonth(),date:i.$date.getDate()}),i.$updateSelected())},build:function(){for(var t,n=m.year-m.year%(3*this.split),a=[],o=0;12>o;o++)t=new Date(n+o,0,1),a.push({date:t,label:u(t,this.format),selected:i.$isSelected(t),disabled:this.isDisabled(t)});r.title=a[0].label+'-'+a[a.length-1].label,r.showLabels=!1,r.rows=e(a,this.split),this.built=!0},isSelected:function(e){return i.$date&&e.getFullYear()===i.$date.getFullYear()},isDisabled:function(e){var t=+new Date(e.getFullYear()+1,0,0);return ts.maxDate},onKeyDown:function(e){if(i.$date){var t=i.$date.getFullYear(),n=new Date(i.$date);37===e.keyCode?n.setYear(t-1):38===e.keyCode?n.setYear(t-4):39===e.keyCode?n.setYear(t+1):40===e.keyCode&&n.setYear(t+4),this.isDisabled(n)||i.select(n,!0)}}}];return{views:s.minView?Array.prototype.slice.call($,s.minView):$,viewDate:m}}}]}),angular.module('mgcrea.ngStrap.button',[]).provider('$button',function(){var e=this.defaults={activeClass:'active',toggleEvent:'click'};this.$get=function(){return{defaults:e}}}).directive('bsCheckboxGroup',function(){return{restrict:'A',require:'ngModel',compile:function(e,t){e.attr('data-toggle','buttons'),e.removeAttr('ng-model');var n=e[0].querySelectorAll('input[type="checkbox"]');angular.forEach(n,function(e){var n=angular.element(e);n.attr('bs-checkbox',''),n.attr('ng-model',t.ngModel+'.'+n.attr('value'))})}}}).directive('bsCheckbox',['$button','$$rAF',function(e,t){var n=e.defaults,a=/^(true|false|\d+)$/;return{restrict:'A',require:'ngModel',link:function(e,o,i,r){var s=n,l='INPUT'===o[0].nodeName,u=l?o.parent():o,c=angular.isDefined(i.trueValue)?i.trueValue:!0;a.test(i.trueValue)&&(c=e.$eval(i.trueValue));var d=angular.isDefined(i.falseValue)?i.falseValue:!1;a.test(i.falseValue)&&(d=e.$eval(i.falseValue));var f='boolean'!=typeof c||'boolean'!=typeof d;f&&(r.$parsers.push(function(e){return e?c:d}),r.$formatters.push(function(e){return angular.equals(e,c)}),e.$watch(i.ngModel,function(e,t){r.$render()})),r.$render=function(){var e=angular.equals(r.$modelValue,c);t(function(){l&&(o[0].checked=e),u.toggleClass(s.activeClass,e)})},o.bind(s.toggleEvent,function(){e.$apply(function(){l||r.$setViewValue(!u.hasClass('active')),f||r.$render()})})}}}]).directive('bsRadioGroup',function(){return{restrict:'A',require:'ngModel',compile:function(e,t){e.attr('data-toggle','buttons'),e.removeAttr('ng-model');var n=e[0].querySelectorAll('input[type="radio"]');angular.forEach(n,function(e){angular.element(e).attr('bs-radio',''),angular.element(e).attr('ng-model',t.ngModel)})}}}).directive('bsRadio',['$button','$$rAF',function(e,t){var n=e.defaults,a=/^(true|false|\d+)$/;return{restrict:'A',require:'ngModel',link:function(e,o,i,r){var s,l=n,u='INPUT'===o[0].nodeName,c=u?o.parent():o;i.$observe('value',function(t){s='boolean'!=typeof t&&a.test(t)?e.$eval(t):t,r.$render()}),r.$render=function(){var e=angular.equals(r.$modelValue,s);t(function(){u&&(o[0].checked=e),c.toggleClass(l.activeClass,e)})},o.bind(l.toggleEvent,function(){e.$apply(function(){r.$setViewValue(s),r.$render()})})}}}]),angular.module('mgcrea.ngStrap.collapse',[]).provider('$collapse',function(){var e=this.defaults={animation:'am-collapse',disallowToggle:!1,activeClass:'in',startCollapsed:!1,allowMultiple:!1},t=this.controller=function(t,n,a){function o(e){for(var t=l.$targets.$active,n=0;n=a?'top':null!==e&&a+e<=t.top?'middle':null!==w&&t.top+n+$>=o-w?'bottom':'middle'}function u(){return p[0]===t?t.pageYOffset:p[0].scrollTop}function c(){return p[0]===t?t.document.body.scrollHeight:p[0].scrollHeight}var d={},f=angular.extend({},e,s),p=f.target,g='affix affix-top affix-bottom',m=!1,$=0,h=0,v=0,w=0,y=null,b=null,D=o.parent();if(f.offsetParent)if(f.offsetParent.match(/^\d+$/))for(var S=0;S<1*f.offsetParent-1;S++)D=D.parent();else D=angular.element(f.offsetParent);return d.init=function(){this.$parseOffsets(),h=a.offset(o[0]).top+$,m=!o[0].style.width,p.on('scroll',this.checkPosition),p.on('click',this.checkPositionWithEventLoop),r.on('resize',this.$debouncedOnResize),this.checkPosition(),this.checkPositionWithEventLoop()},d.destroy=function(){p.off('scroll',this.checkPosition),p.off('click',this.checkPositionWithEventLoop),r.off('resize',this.$debouncedOnResize)},d.checkPositionWithEventLoop=function(){setTimeout(d.checkPosition,1)},d.checkPosition=function(){var e=u(),t=a.offset(o[0]),n=a.height(o[0]),r=l(b,t,n);y!==r&&(y=r,'top'===r?(b=null,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',''))):'bottom'===r?(b=f.offsetUnpin?-(1*f.offsetUnpin):t.top-e,m&&o.css('width',''),f.inlineStyles&&(o.css('position',f.offsetParent?'':'relative'),o.css('top',f.offsetParent?'':i[0].offsetHeight-w-n-h+'px'))):(b=null,m&&o.css('width',o[0].offsetWidth+'px'),f.inlineStyles&&(o.css('position','fixed'),o.css('top',$+'px'))),o.removeClass(g).addClass('affix'+('middle'!==r?'-'+r:'')))},d.$onResize=function(){d.$parseOffsets(),d.checkPosition()},d.$debouncedOnResize=n(d.$onResize,50),d.$parseOffsets=function(){var e=o.css('position');f.inlineStyles&&o.css('position',f.offsetParent?'':'relative'),f.offsetTop&&('auto'===f.offsetTop&&(f.offsetTop='+0'),f.offsetTop.match(/^[-+]\d+$/)?($=1*-f.offsetTop,v=f.offsetParent?a.offset(D[0]).top+1*f.offsetTop:a.offset(o[0]).top-a.css(o[0],'marginTop',!0)+1*f.offsetTop):v=1*f.offsetTop),f.offsetBottom&&(w=f.offsetParent&&f.offsetBottom.match(/^[-+]\d+$/)?c()-(a.offset(D[0]).top+a.height(D[0]))+1*f.offsetBottom+1:1*f.offsetBottom),f.inlineStyles&&o.css('position',e)},d.init(),d}var i=angular.element(t.document.body),r=angular.element(t);return o}]}).directive('bsAffix',['$affix','$window',function(e,t){return{restrict:'EAC',require:'^?bsAffixTarget',link:function(n,a,o,i){var r={scope:n,target:i?i.$element:angular.element(t)};angular.forEach(['offsetTop','offsetBottom','offsetParent','offsetUnpin','inlineStyles'],function(e){if(angular.isDefined(o[e])){var t=o[e];/true/i.test(t)&&(t=!0),/false/i.test(t)&&(t=!1),r[e]=t}});var s=e(a,r);n.$on('$destroy',function(){s&&s.destroy(),r=null,s=null})}}}]).directive('bsAffixTarget',function(){return{controller:['$element',function(e){this.$element=e}]}}),angular.module('mgcrea.ngStrap',['mgcrea.ngStrap.modal','mgcrea.ngStrap.aside','mgcrea.ngStrap.alert','mgcrea.ngStrap.button','mgcrea.ngStrap.select','mgcrea.ngStrap.datepicker','mgcrea.ngStrap.timepicker','mgcrea.ngStrap.navbar','mgcrea.ngStrap.tooltip','mgcrea.ngStrap.popover','mgcrea.ngStrap.dropdown','mgcrea.ngStrap.typeahead','mgcrea.ngStrap.scrollspy','mgcrea.ngStrap.affix','mgcrea.ngStrap.tab','mgcrea.ngStrap.collapse'])}(window,document); +//# sourceMappingURL=angular-strap.min.js.map diff --git a/InventoryTraker.Web/Scripts/angular-strap.min.js.map b/InventoryTraker.Web/Scripts/angular-strap.min.js.map index 4846ea2..01c6301 100644 --- a/InventoryTraker.Web/Scripts/angular-strap.min.js.map +++ b/InventoryTraker.Web/Scripts/angular-strap.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["angular-strap.js","helpers/compiler.js","helpers/date-formatter.js","affix/affix.js","alert/alert.js","aside/aside.js","button/button.js","collapse/collapse.js","datepicker/datepicker.js","dropdown/dropdown.js","helpers/date-parser.js","helpers/debounce.js","helpers/dimensions.js","helpers/parse-options.js","helpers/raf.js","modal/modal.js","navbar/navbar.js","popover/popover.js","scrollspy/scrollspy.js","select/select.js","timepicker/timepicker.js","tab/tab.js","typeahead/typeahead.js","tooltip/tooltip.js"],"names":["window","document","undefined","templateUrl","options","cache","$templateCache","then","element","res","fetchTemplate","template","fetchPromises","bsCompilerService","$inject","$http","get","angular","module","getDefaultLocale","$locale","this","compile","controller","console","controllerAs","resolve","copy","locals","bindToController","forEach","value","isString","$injector","key","invoke","transformTemplate","identity","extend","$template","when","$q","contentEl","findElement","outerHTML","contentTemplate","all","templateEl","removeAttr","html","templates","replace","next","remove","link","scope","trim","contents","linkFn","invokeCtrl","children","instance","ctrl","isObject","arguments","data","apply","bodyEl","$window","body","windowEl","defaults","AffixFactory","offsetTop","$affix","inlineStyles","$get","reset","setWidth","initialAffixTop","offsetParent","match","getRequiredAffixClass","unpin","position","top","scrollTop","getScrollTop","scrollHeight","getScrollHeight","targetEl","pageYOffset","directive","parent","target","initialOffsetTop","offsetBottom","affixed","init","i","$parseOffsets","on","checkPosition","require","checkPositionWithEventLoop","dimensions","offset","destroy","style","width","off","affix","setTimeout","elementHeight","height","css","addClass","offsetUnpin","offsetHeight","offsetWidth","$debouncedOnResize","$onResize","initialPosition","restrict","affixTarget","$element","option","$on","attr","test","animation","prefixClass","container","provider","backdrop","keyboard","show","duration","type","dismissable","AlertFactory","$alert","$scope","config","$timeout","hide","isDefined","falseValueRegExp","hasOwnProperty","title","newValue","oldValue","trustAsHtml","bsAlert","$observe","content","alert","trigger","toggle","AsideFactory","$aside","requestAnimationFrame","$modal","bsAside","$watch","aside","activeClass","querySelectorAll","childEl","ngModel","child","$button","constantValueRegExp","isInput","trueValue","falseValue","hasExoticValues","viewValue","$formatters","push","$render","modelValue","isActive","equals","checked","activeElement","bind","toggleEvent","$modelValue","$$rAF","$setViewValue","toggleClass","$apply","hasClass","nodeName","self","startCollapsed","allowMultiple","$attrs","activeIndexes","$targets","$active","length","index","indexOf","activeItems","splice","activateItem","$options","$collapse","$viewChangeListeners","$registerToggle","$toggles","$unregisterToggle","$unregisterTarget","deactivateItem","fn","fixActiveItemIndexes","$setActive","disallowToggle","$activeIndexes","bsCollapseCtrl","controllers","$animate","ngModelCtrl","attrs","isArray","bsCollapseToggle","$registerTarget","render","active","action","delay","useNative","dateType","dateFormat","timezone","modelDateFormat","dayFormat","monthFormat","yearFormat","monthTitleFormat","yearTitleFormat","strictFormat","autoclose","minDate","Infinity","maxDate","startView","minView","startWeek","daysOfWeekDisabled","iconLeft","iconRight","isNative","DatepickerFactory","parentScope","$datepicker","pickerViews","views","el","selected","date","focus","viewDate","$iconLeft","$iconRight","$picker","$views","$mode","datepickerViews","$selectPane","$toggleMode","setMode","select","isDate","$build","updateDisabledDates","disabledDateRanges","dateRanges","$date","$dateValue","keep","Date","year","getFullYear","month","getDate","mode","pristine","call","$updateSelected","rows","built","$isSelected","$setDisabledEl","disabled","isDisabled","steps","targetDate","getUTCFullYear","getUTCMonth","UTC","$onMouseDown","evt","preventDefault","stopPropagation","isTouch","getUTCDate","$onKeyDown","keyCode","shiftKey","altKey","updateSelected","onKeyDown","$digest","prop","focusElement","_init","_destroy","_show","_hide","blur","navigator","userAgent","previousValue","normalizeDateRanges","ranges","disabledRanges","datepicker","isMaxValid","isValid","isMinValid","isNaN","parsedDate","getTime","$parsers","unshift","$setValidity","getDateFormattedString","formatDate","bsShow","lang","format","$dateFormatter","dateParser","$dateParser","strict","validateAgainstMinMaxDate","getDateForAttribute","disabledDates","parse","timezoneOffsetAdjust","isUndefined","NaN","daySplit","arr","mod","n","m","arrays","size","$sce","weekDaysMin","weekdaysShort","weekDaysLabelsHtml","startDate","picker","weekDaysLabels","slice","concat","split","getMonth","update","firstDayOfMonth","firstDate","getDay","today","firstDateOffset","build","day","days","isToday","toDateString","label","muted","showLabels","labels","time","isSelected","newDate","name","firstMonth","months","lastDate","actualMonth","parseInt","firstYear","years","actualYear","setYear","placement","matchesSelector","DropdownFactory","$dropdown","onBodyClick","items","$rootScope","$new","parentEl","$isShown","removeClass","prototype","transclusion","bsDropdown","dropdown","service","splitTimeFormat","timeFormat","exec","DATETIME_FORMATS","id","getDatetimeFormat","SHORTDAY","hoursFormat","minutesFormat","secondsFormat","timeSeparator","showSeconds","dateFilter","ParseDate","seconds","$localeProvider","milliseconds","hours","array","isNumeric","parseFloat","isFinite","indexOfCaseInsensitive","len","str","toString","toLowerCase","DateParserFactory","minutes","getHours","getMilliseconds","getMinutes","proto","noop","toDate","regExpMap","sss","mm","keys","setFnMap","map","clonedFormat","search","v","sortedMap","regExpForFormat","re","join","text","Object","escapeReservedSymbols","RegExp","regex","HH","H","hh","h","a","EEEE","EEE","dd","d","MMMM","MMM","SHORTMONTH","MM","M","DAY","yyyy","yy","y","MONTH","ss","setSeconds","s","setMinutes","setHours","setDate","setMonth","setFullYear","setMap","$format","setMapForFormat","baseDate","formatRegex","formatSetMap","matches","fromDate","substr","getTimeForAttribute","daylightSavingAdjust","undo","func","timeout","context","factory","immediate","args","cancel","callNow","leading","trailing","wait","currentStyle","getComputedStyle","extra","boxRect","getBoundingClientRect","left","docElement","ownerDocument","curPosition","curLeft","curCSSTop","documentElement","clientTop","pageXOffset","scrollLeft","clientLeft","curCSSLeft","calculatePosition","curTop","curOffset","curElem","props","isFunction","using","offsetParentRect","offsetParentElement","outer","$parseOptions","$values","regexp","$match","displayFn","valueName","valueFn","ParseOptionsFactory","groupByFn","valuesFn","$parse","keyName","cancelAnimationFrame","values","displayValue","raf","webkitRequestAnimationFrame","mozRequestAnimationFrame","rafSupported","timer","prefixEvent","bodyElement","ModalFactory","enterAnimateCallback","version","minor","modalElement","unbindBackdropEvents","hideOnBackdropClick","backdropElement","preventEventDefault","bindKeyboardEvents","$onKeyUp","destroyModalElement","modalScope","$destroy","promise","$hide","$$postDigest","$id","$show","bottom","right","z-index","compileData","after","isElement","$emit","display","clonedElement","defaultPrevented","enter","backdropAnimation","safeDigest","bindBackdropEvents","leave","leaveAnimateCallback","unbindKeyboardEvents","which","$root","$$phase","query","bsModal","modal","routeAttr","$navbar","liElements","li","liElement","pattern","path","autoClose","$popover","PopoverFactory","$tooltip","dataTarget","popover","bsPopover","$applyPlacement","setViewport","viewport","spies","$document","debounce","throttle","ScrollSpyFactory","scrollEl","isWindowSpy","scrollId","$$count","$scrollspy","unbindViewContentLoaded","unbindIncludeContentLoaded","trackedElements","$trackedElements","sortedElements","activeTarget","debouncedCheckPosition","viewportHeight","throttledCheckPosition","debouncedCheckOffsets","checkOffsets","docEl","$activateElement","source","$getTrackedElement","filter","targetElement","querySelector","trackedElement","b","trackElement","toDelete","untrackElement","activate","scrollspy","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","SelectFactory","$select","$activeIndex","$isMultiple","$showAllNoneButtons","$allText","$iconCheckmark","$isActive","$isVisible","$selectNone","$matches","$updateActiveIndex","$getIndex","minLength","$viewValue","l","dataMultiple","inputEl","watchedOptions","$watchCollection","parsedOptions","bsOptions","$isEmpty","timeType","modelTimeFormat","minTime","maxTime","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","$timepicker","timepickerFactory","hour","meridian","coeff","selRange","end","start","setSelectionRange","collapse","selectionStart","moveStart","selectionEnd","moveEnd","floorMinutes","floor","selectedIndex","defaultDate","second","getSeconds","millisecond","$iconUp","$iconDown","$moveIndex","$switchMeridian","switchMeridian","minute","midIndex","$isDisabled","showAM","isAM","selectedTime","$arrowAction","$setTimeByStep","triggerHandler","sepLength","lateralMove","count","minutesLength","selectRange","hoursLength","incr","isSeconds","isMeridian","secondsLength","createSelection","createTextRange","parsedTime","getTimeFormattedString","timepicker","validateAgainstMinMaxTime","navClass","$activeClass","$panes","$activePaneChangeListeners","$push","pane","$navClass","$remove","activeIndex","$pane","$tab","transclude","postLink","bsTabsCtrl","bsActivePane","parsedBsActivePane","assign","limit","autoSelect","comparator","trimValue","$typeahead","$resetMatches","TypeaheadFactory","$filter","expression","results","typeahead","watchOptions","selectMode","isVisible","val","bsEnabled","selector","padding","String","htmlReplaceRegExp","$body","_tipToHide","tipElement","triggers","unbindTriggerEvents","$onFocusElementMouseDown","_autoCloseEventsBinded","bindAutoCloseEvents","unbindAutoCloseEvents","stopEventPropagation","event","getPosition","rect","elRect","p","scroll","isBody","getCalculatedOffset","actualWidth","actualHeight","outerDims","clientWidth","innerHeight","tip","marginTop","marginLeft","setOffset","delta","getViewportAdjustedDelta","isVertical","replaceArrow","arrowDelta","arrowOffsetPosition","viewportDimensions","$viewport","topEdgeOffset","bottomEdgeOffset","viewportPadding","leftEdgeOffset","rightEdgeOffset","dimension","isHorizontal","$arrow","clearTimeout","tipScope","$promise","$bsCompiler","$setEnabled","setEnabled","isEnabled","tipContainer","bindTriggerEvents","destroyTipElement","hoverState","lastChild","visibility","customClass","_blur","elementPosition","autoPlace","autoToken","viewportPosition","originalPlacement","tipHeight","tipPosition","applyPlacement","tipWidth","$location","tooltip","bsTooltip"],"mappings":"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","file":"angular-strap.min.js","sourcesContent":["(function(window, document, undefined) {\n'use strict';\n\n// Source: module.js\nangular.module('mgcrea.ngStrap', [\n 'mgcrea.ngStrap.modal',\n 'mgcrea.ngStrap.aside',\n 'mgcrea.ngStrap.alert',\n 'mgcrea.ngStrap.button',\n 'mgcrea.ngStrap.select',\n 'mgcrea.ngStrap.datepicker',\n 'mgcrea.ngStrap.timepicker',\n 'mgcrea.ngStrap.navbar',\n 'mgcrea.ngStrap.tooltip',\n 'mgcrea.ngStrap.popover',\n 'mgcrea.ngStrap.dropdown',\n 'mgcrea.ngStrap.typeahead',\n 'mgcrea.ngStrap.scrollspy',\n 'mgcrea.ngStrap.affix',\n 'mgcrea.ngStrap.tab',\n 'mgcrea.ngStrap.collapse'\n]);\n\n// Source: affix/affix.js\nangular.module('mgcrea.ngStrap.affix', ['mgcrea.ngStrap.helpers.dimensions', 'mgcrea.ngStrap.helpers.debounce'])\n\n .provider('$affix', function() {\n\n var defaults = this.defaults = {\n offsetTop: 'auto',\n inlineStyles: true\n };\n\n this.$get = function($window, debounce, dimensions) {\n\n var bodyEl = angular.element($window.document.body);\n var windowEl = angular.element($window);\n\n function AffixFactory(element, config) {\n\n var $affix = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var targetEl = options.target;\n\n // Initial private vars\n var reset = 'affix affix-top affix-bottom',\n setWidth = false,\n initialAffixTop = 0,\n initialOffsetTop = 0,\n offsetTop = 0,\n offsetBottom = 0,\n affixed = null,\n unpin = null;\n\n var parent = element.parent();\n // Options: custom parent\n if (options.offsetParent) {\n if (options.offsetParent.match(/^\\d+$/)) {\n for (var i = 0; i < (options.offsetParent * 1) - 1; i++) {\n parent = parent.parent();\n }\n }\n else {\n parent = angular.element(options.offsetParent);\n }\n }\n\n $affix.init = function() {\n\n this.$parseOffsets();\n initialOffsetTop = dimensions.offset(element[0]).top + initialAffixTop;\n setWidth = !element[0].style.width;\n\n // Bind events\n targetEl.on('scroll', this.checkPosition);\n targetEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', this.$debouncedOnResize);\n\n // Both of these checkPosition() calls are necessary for the case where\n // the user hits refresh after scrolling to the bottom of the page.\n this.checkPosition();\n this.checkPositionWithEventLoop();\n\n };\n\n $affix.destroy = function() {\n\n // Unbind events\n targetEl.off('scroll', this.checkPosition);\n targetEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', this.$debouncedOnResize);\n\n };\n\n $affix.checkPositionWithEventLoop = function() {\n\n // IE 9 throws an error if we use 'this' instead of '$affix'\n // in this setTimeout call\n setTimeout($affix.checkPosition, 1);\n\n };\n\n $affix.checkPosition = function() {\n // if (!this.$element.is(':visible')) return\n\n var scrollTop = getScrollTop();\n var position = dimensions.offset(element[0]);\n var elementHeight = dimensions.height(element[0]);\n\n // Get required affix class according to position\n var affix = getRequiredAffixClass(unpin, position, elementHeight);\n\n // Did affix status changed this last check?\n if(affixed === affix) return;\n affixed = affix;\n\n // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + affix : ''));\n\n if(affix === 'top') {\n unpin = null;\n if(setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', '');\n }\n } else if(affix === 'bottom') {\n if (options.offsetUnpin) {\n unpin = -(options.offsetUnpin * 1);\n }\n else {\n // Calculate unpin threshold when affixed to bottom.\n // Hopefully the browser scrolls pixel by pixel.\n unpin = position.top - scrollTop;\n }\n if(setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', (options.offsetParent) ? '' : ((bodyEl[0].offsetHeight - offsetBottom - elementHeight - initialOffsetTop) + 'px'));\n }\n } else { // affix === 'middle'\n unpin = null;\n if(setWidth) {\n element.css('width', element[0].offsetWidth + 'px');\n }\n if (options.inlineStyles) {\n element.css('position', 'fixed');\n element.css('top', initialAffixTop + 'px');\n }\n }\n\n };\n\n $affix.$onResize = function() {\n $affix.$parseOffsets();\n $affix.checkPosition();\n };\n $affix.$debouncedOnResize = debounce($affix.$onResize, 50);\n\n $affix.$parseOffsets = function() {\n var initialPosition = element.css('position');\n // Reset position to calculate correct offsetTop\n if (options.inlineStyles){\n element.css('position', (options.offsetParent) ? '' : 'relative');\n }\n\n if(options.offsetTop) {\n if(options.offsetTop === 'auto') {\n options.offsetTop = '+0';\n }\n if(options.offsetTop.match(/^[-+]\\d+$/)) {\n initialAffixTop = - options.offsetTop * 1;\n if(options.offsetParent) {\n offsetTop = dimensions.offset(parent[0]).top + (options.offsetTop * 1);\n }\n else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\n }\n }\n else {\n offsetTop = options.offsetTop * 1;\n }\n }\n\n if(options.offsetBottom) {\n if(options.offsetParent && options.offsetBottom.match(/^[-+]\\d+$/)) {\n // add 1 pixel due to rounding problems...\n offsetBottom = getScrollHeight() - (dimensions.offset(parent[0]).top + dimensions.height(parent[0])) + (options.offsetBottom * 1) + 1;\n }\n else {\n offsetBottom = options.offsetBottom * 1;\n }\n }\n\n // Bring back the element's position after calculations\n if (options.inlineStyles){\n element.css('position', initialPosition);\n }\n };\n\n // Private methods\n\n function getRequiredAffixClass(unpin, position, elementHeight) {\n\n var scrollTop = getScrollTop();\n var scrollHeight = getScrollHeight();\n\n if(scrollTop <= offsetTop) {\n return 'top';\n } else if(unpin !== null && (scrollTop + unpin <= position.top)) {\n return 'middle';\n } else if(offsetBottom !== null && (position.top + elementHeight + initialAffixTop >= scrollHeight - offsetBottom)) {\n return 'bottom';\n } else {\n return 'middle';\n }\n\n }\n\n function getScrollTop() {\n return targetEl[0] === $window ? $window.pageYOffset : targetEl[0].scrollTop;\n }\n\n function getScrollHeight() {\n return targetEl[0] === $window ? $window.document.body.scrollHeight : targetEl[0].scrollHeight;\n }\n\n $affix.init();\n return $affix;\n\n }\n\n return AffixFactory;\n\n };\n\n })\n\n .directive('bsAffix', function($affix, $window) {\n\n return {\n restrict: 'EAC',\n require: '^?bsAffixTarget',\n link: function postLink(scope, element, attr, affixTarget) {\n\n var options = {scope: scope, target: affixTarget ? affixTarget.$element : angular.element($window)};\n angular.forEach(['offsetTop', 'offsetBottom', 'offsetParent', 'offsetUnpin', 'inlineStyles'], function(key) {\n if(angular.isDefined(attr[key])) {\n var option = attr[key];\n if (/true/i.test(option)) option = true;\n if (/false/i.test(option)) option = false;\n options[key] = option;\n }\n });\n\n var affix = $affix(element, options);\n scope.$on('$destroy', function() {\n affix && affix.destroy();\n options = null;\n affix = null;\n });\n\n }\n };\n\n })\n\n .directive('bsAffixTarget', function() {\n return {\n controller: function($element) {\n this.$element = $element;\n }\n };\n });\n\n// Source: alert/alert.js\n// @BUG: following snippet won't compile correctly\n// @TODO: submit issue to core\n// ' ' +\n\nangular.module('mgcrea.ngStrap.alert', ['mgcrea.ngStrap.modal'])\n\n .provider('$alert', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'alert',\n prefixEvent: 'alert',\n placement: null,\n templateUrl: 'alert/alert.tpl.html',\n container: false,\n element: null,\n backdrop: false,\n keyboard: true,\n show: true,\n // Specific options\n duration: false,\n type: false,\n dismissable: true\n };\n\n this.$get = function($modal, $timeout) {\n\n function AlertFactory(config) {\n\n var $alert = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $alert = $modal(options);\n\n // Support scope as string options [/*title, content, */ type, dismissable]\n $alert.$scope.dismissable = !!options.dismissable;\n if(options.type) {\n $alert.$scope.type = options.type;\n }\n\n // Support auto-close duration\n var show = $alert.show;\n if(options.duration) {\n $alert.show = function() {\n show();\n $timeout(function() {\n $alert.hide();\n }, options.duration * 1000);\n };\n }\n\n return $alert;\n\n }\n\n return AlertFactory;\n\n };\n\n })\n\n .directive('bsAlert', function($window, $sce, $alert) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['keyboard', 'html', 'container', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content', 'type'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAlert && scope.$watch(attr.bsAlert, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize alert\n var alert = $alert(options);\n\n // Trigger\n element.on(attr.trigger || 'click', alert.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (alert) alert.destroy();\n options = null;\n alert = null;\n });\n\n }\n };\n\n });\n\n// Source: aside/aside.js\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($modal) {\n\n function AsideFactory(config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function($window, $sce, $aside) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAside && scope.$watch(attr.bsAside, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize aside\n var aside = $aside(options);\n\n // Trigger\n element.on(attr.trigger || 'click', aside.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (aside) aside.destroy();\n options = null;\n aside = null;\n });\n\n }\n };\n\n });\n\n// Source: button/button.js\nangular.module('mgcrea.ngStrap.button', [])\n\n .provider('$button', function() {\n\n var defaults = this.defaults = {\n activeClass:'active',\n toggleEvent:'click'\n };\n\n this.$get = function() {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsCheckboxGroup', function() {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"checkbox\"]');\n angular.forEach(children, function(child) {\n var childEl = angular.element(child);\n childEl.attr('bs-checkbox', '');\n childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value'));\n });\n }\n\n };\n\n })\n\n .directive('bsCheckbox', function($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support label > input[type=\"checkbox\"]\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true;\n if(constantValueRegExp.test(attr.trueValue)) {\n trueValue = scope.$eval(attr.trueValue);\n }\n var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false;\n if(constantValueRegExp.test(attr.falseValue)) {\n falseValue = scope.$eval(attr.falseValue);\n }\n\n // Parse exotic values\n var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean';\n if(hasExoticValues) {\n controller.$parsers.push(function(viewValue) {\n // console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue);\n return viewValue ? trueValue : falseValue;\n });\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n return angular.equals(modelValue, trueValue);\n });\n // Fix rendering for exotic values\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n controller.$render();\n });\n }\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, trueValue);\n $$rAF(function() {\n if(isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function() {\n scope.$apply(function () {\n // console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n if(!isInput) {\n controller.$setViewValue(!activeElement.hasClass('active'));\n }\n if(!hasExoticValues) {\n controller.$render();\n }\n });\n });\n\n }\n\n };\n\n })\n\n .directive('bsRadioGroup', function() {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"radio\"]');\n angular.forEach(children, function(child) {\n angular.element(child).attr('bs-radio', '');\n angular.element(child).attr('ng-model', attr.ngModel);\n });\n }\n\n };\n\n })\n\n .directive('bsRadio', function($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support `label > input[type=\"radio\"]` markup\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var value;\n attr.$observe('value', function(v) {\n value = constantValueRegExp.test(v) ? scope.$eval(v) : v;\n controller.$render();\n });\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, value);\n $$rAF(function() {\n if(isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function() {\n scope.$apply(function () {\n // console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n controller.$setViewValue(value);\n controller.$render();\n });\n });\n\n }\n\n };\n\n });\n\n// Source: collapse/collapse.js\nangular.module('mgcrea.ngStrap.collapse', [])\n\n .provider('$collapse', function() {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['disallowToggle', 'startCollapsed', 'allowMultiple'], function(key) {\n if(angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) {\n self.$options[key] = false;\n }\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function(element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function(element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function(element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function(element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function(value) {\n if(angular.isArray(value)) {\n self.$targets.$active = value;\n }\n else if(!self.$options.disallowToggle) {\n // toogle element active status\n isActive(value) ? deactivateItem(value) : activateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function() {\n return self.$options.allowMultiple ? self.$targets.$active :\n self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1;\n };\n\n function fixActiveItemIndexes(index) {\n // item with index was removed, so we\n // need to adjust other items index values\n var activeIndexes = self.$targets.$active;\n for(var i = 0; i < activeIndexes.length; i++) {\n if (index < activeIndexes[i]) {\n activeIndexes[i] = activeIndexes[i] - 1;\n }\n\n // the last item is active, so we need to\n // adjust its index\n if (activeIndexes[i] === self.$targets.length) {\n activeIndexes[i] = self.$targets.length - 1;\n }\n }\n }\n\n function isActive(value) {\n var activeItems = self.$targets.$active;\n return activeItems.indexOf(value) === -1 ? false : true;\n }\n\n function deactivateItem(value) {\n var index = self.$targets.$active.indexOf(value);\n if (index !== -1) {\n self.$targets.$active.splice(index, 1);\n }\n }\n\n function activateItem(value) {\n if (!self.$options.allowMultiple) {\n // remove current selected item\n self.$targets.$active.splice(0, 1);\n }\n\n if (self.$targets.$active.indexOf(value) === -1) {\n self.$targets.$active.push(value);\n }\n }\n\n };\n\n this.$get = function() {\n var $collapse = {};\n $collapse.defaults = defaults;\n $collapse.controller = controller;\n return $collapse;\n };\n\n })\n\n .directive('bsCollapse', function($window, $animate, $collapse) {\n\n var defaults = $collapse.defaults;\n\n return {\n require: ['?ngModel', 'bsCollapse'],\n controller: ['$scope', '$element', '$attrs', $collapse.controller],\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n if(ngModelCtrl) {\n\n // Update the modelValue following\n bsCollapseCtrl.$viewChangeListeners.push(function() {\n ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes());\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n if (angular.isArray(modelValue)) {\n // model value is an array, so just replace\n // the active items directly\n bsCollapseCtrl.$setActive(modelValue);\n }\n else {\n var activeIndexes = bsCollapseCtrl.$activeIndexes();\n\n if (angular.isArray(activeIndexes)) {\n // we have an array of selected indexes\n if (activeIndexes.indexOf(modelValue * 1) === -1) {\n // item with modelValue index is not active\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n else if (activeIndexes !== modelValue * 1) {\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n return modelValue;\n });\n\n }\n\n }\n };\n\n })\n\n .directive('bsCollapseToggle', function() {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base attr\n element.attr('data-toggle', 'collapse');\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerToggle(element);\n\n // remove toggle from collapse controller when toggle is destroyed\n scope.$on('$destroy', function() {\n bsCollapseCtrl.$unregisterToggle(element);\n });\n\n element.on('click', function() {\n var index = attrs.bsCollapseToggle && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n });\n\n }\n };\n\n })\n\n .directive('bsCollapseTarget', function($animate) {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n // scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base class\n element.addClass('collapse');\n\n // Add animation class\n if(bsCollapseCtrl.$options.animation) {\n element.addClass(bsCollapseCtrl.$options.animation);\n }\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerTarget(element);\n\n // remove pane target from collapse controller when target is destroyed\n scope.$on('$destroy', function() {\n bsCollapseCtrl.$unregisterTarget(element);\n });\n\n function render() {\n var index = bsCollapseCtrl.$targets.indexOf(element);\n var active = bsCollapseCtrl.$activeIndexes();\n var action = 'removeClass';\n if (angular.isArray(active)) {\n if (active.indexOf(index) !== -1) {\n action = 'addClass';\n }\n }\n else if (index === active) {\n action = 'addClass';\n }\n\n $animate[action](element, bsCollapseCtrl.$options.activeClass);\n }\n\n bsCollapseCtrl.$viewChangeListeners.push(function() {\n render();\n });\n render();\n\n }\n };\n\n });\n\n// Source: datepicker/datepicker.js\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if(!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();\n\n function DatepickerFactory(element, controller, config) {\n\n var $datepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $datepicker.$options;\n var scope = $datepicker.$scope;\n if(options.startView) options.startView -= options.minView;\n\n // View vars\n\n var pickerViews = datepickerViews($datepicker);\n $datepicker.$views = pickerViews.views;\n var viewDate = pickerViews.viewDate;\n scope.$mode = options.startView;\n scope.$iconLeft = options.iconLeft;\n scope.$iconRight = options.iconRight;\n var $picker = $datepicker.$views[scope.$mode];\n\n // Scope methods\n\n scope.$select = function(date) {\n $datepicker.select(date);\n };\n scope.$selectPane = function(value) {\n $datepicker.$selectPane(value);\n };\n scope.$toggleMode = function() {\n $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);\n };\n\n // Public methods\n\n $datepicker.update = function(date) {\n // console.warn('$datepicker.update() newValue=%o', date);\n if(angular.isDate(date) && !isNaN(date.getTime())) {\n $datepicker.$date = date;\n $picker.update.call($picker, date);\n }\n // Build only if pristine\n $datepicker.$build(true);\n };\n\n $datepicker.updateDisabledDates = function(dateRanges) {\n options.disabledDateRanges = dateRanges;\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);\n }\n };\n\n $datepicker.select = function(date, keep) {\n // console.warn('$datepicker.select', date, scope.$mode);\n if(!angular.isDate(controller.$dateValue)) controller.$dateValue = new Date(date);\n if(!scope.$mode || keep) {\n controller.$setViewValue(angular.copy(date));\n controller.$render();\n if(options.autoclose && !keep) {\n $timeout(function() { $datepicker.hide(true); });\n }\n } else {\n angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});\n $datepicker.setMode(scope.$mode - 1);\n $datepicker.$build();\n }\n };\n\n $datepicker.setMode = function(mode) {\n // console.warn('$datepicker.setMode', mode);\n scope.$mode = mode;\n $picker = $datepicker.$views[scope.$mode];\n $datepicker.$build();\n };\n\n // Protected methods\n\n $datepicker.$build = function(pristine) {\n // console.warn('$datepicker.$build() viewDate=%o', viewDate);\n if(pristine === true && $picker.built) return;\n if(pristine === false && !$picker.built) return;\n $picker.build.call($picker);\n };\n\n $datepicker.$updateSelected = function() {\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], updateSelected);\n }\n };\n\n $datepicker.$isSelected = function(date) {\n return $picker.isSelected(date);\n };\n\n $datepicker.$setDisabledEl = function(el) {\n el.disabled = $picker.isDisabled(el.date);\n };\n\n $datepicker.$selectPane = function(value) {\n var steps = $picker.steps;\n // set targetDate to first day of month to avoid problems with\n // date values rollover. This assumes the viewDate does not\n // depend on the day of the month\n var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));\n angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});\n $datepicker.$build();\n };\n\n $datepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n if(targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $datepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n if(evt.keyCode === 13) {\n if(!scope.$mode) {\n return $datepicker.hide(true);\n } else {\n return scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected(el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function() {\n if(isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if(isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function() {\n if(isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // if $datepicker is no longer showing, don't setup events\n if(!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function(blur) {\n if(!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n var defaults = $datepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!datepicker || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);\n newValue === true ? datepicker.show() : datepicker.hide();\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if(isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n // console.warn('attr.$observe(%s)=%o', key, newValue);\n datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);\n // Build only if dirty\n !isNaN(datepicker.$options[key]) && datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges(ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function(disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate(parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if(isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if(!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if(!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n } else {\n validateAgainstMinMaxDate(parsedDate);\n }\n\n if(options.dateType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true);\n return formatDate(date, options.modelDateFormat || options.dateFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if(options.dateType === 'number') {\n return date.getTime();\n } else if(options.dateType === 'unix') {\n return date.getTime() / 1000;\n } else if(options.dateType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if(angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if(angular.isDate(modelValue)) {\n date = modelValue;\n } else if(options.dateType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelDateFormat);\n } else if(options.dateType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) {\n // var today = new Date();\n // date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);\n // }\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getDateFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getDateFormattedString());\n };\n\n function getDateFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(datepicker) datepicker.destroy();\n options = null;\n datepicker = null;\n });\n\n }\n };\n\n })\n\n .provider('datepickerViews', function() {\n\n var defaults = this.defaults = {\n dayFormat: 'dd',\n daySplit: 7\n };\n\n // Split array into smaller arrays\n function split(arr, size) {\n var arrays = [];\n while(arr.length > 0) {\n arrays.push(arr.splice(0, size));\n }\n return arrays;\n }\n\n // Modulus operator\n function mod(n, m) {\n return ((n % m) + m) % m;\n }\n\n this.$get = function($dateFormatter, $dateParser, $sce) {\n\n return function(picker) {\n\n var scope = picker.$scope;\n var options = picker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n var weekDaysMin = $dateFormatter.weekdaysShort(lang);\n var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));\n var weekDaysLabelsHtml = $sce.trustAsHtml('' + weekDaysLabels.join('') + '');\n\n var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date());\n var viewDate = {year: startDate.getFullYear(), month: startDate.getMonth(), date: startDate.getDate()};\n\n var views = [{\n format: options.dayFormat,\n split: 7,\n steps: { month: 1 },\n update: function(date, force) {\n if(!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getDate() !== viewDate.date || date.getDate() === 1) {\n // chaging picker current month will cause viewDate.date to be set to first day of the month,\n // in $datepicker.$selectPane, so picker would not update selected day display if\n // user picks first day of the new month.\n // As a workaround, we are always forcing update when picked date is first day of month.\n viewDate.date = picker.$date.getDate();\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1), firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5), firstDateOffset = firstDate.getTimezoneOffset();\n var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString();\n // Handle daylight time switch\n if(firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 60e3);\n var days = [], day;\n for(var i = 0; i < 42; i++) { // < 7 * 6\n day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i));\n days.push({date: day, isToday: day.toDateString() === today, label: formatDate(day, this.format), selected: picker.$date && this.isSelected(day), muted: day.getMonth() !== viewDate.month, disabled: this.isDisabled(day)});\n }\n scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat);\n scope.showLabels = true;\n scope.labels = weekDaysLabelsHtml;\n scope.rows = split(days, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate();\n },\n isDisabled: function(date) {\n var time = date.getTime();\n\n // Disabled because of min/max date.\n if (time < options.minDate || time > options.maxDate) return true;\n\n // Disabled due to being a disabled day of the week\n if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true;\n\n // Disabled because of disabled date range.\n if (options.disabledDateRanges) {\n for (var i = 0; i < options.disabledDateRanges.length; i++) {\n if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) {\n return true;\n }\n }\n }\n\n return false;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualTime = picker.$date.getTime();\n var newDate;\n\n if(evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5);\n else if(evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5);\n else if(evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5);\n else if(evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'month',\n format: options.monthFormat,\n split: 4,\n steps: { year: 1 },\n update: function(date, force) {\n if(!this.built || date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstMonth = new Date(viewDate.year, 0, 1);\n var months = [], month;\n for (var i = 0; i < 12; i++) {\n month = new Date(viewDate.year, i, 1);\n months.push({date: month, label: formatDate(month, this.format), selected: picker.$isSelected(month), disabled: this.isDisabled(month)});\n }\n scope.title = formatDate(month, options.yearTitleFormat);\n scope.showLabels = false;\n scope.rows = split(months, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth();\n },\n isDisabled: function(date) {\n var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualMonth = picker.$date.getMonth();\n var newDate = new Date(picker.$date);\n\n if(evt.keyCode === 37) newDate.setMonth(actualMonth - 1);\n else if(evt.keyCode === 38) newDate.setMonth(actualMonth - 4);\n else if(evt.keyCode === 39) newDate.setMonth(actualMonth + 1);\n else if(evt.keyCode === 40) newDate.setMonth(actualMonth + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'year',\n format: options.yearFormat,\n split: 4,\n steps: { year: 12 },\n update: function(date, force) {\n if(!this.built || force || parseInt(date.getFullYear()/20, 10) !== parseInt(viewDate.year/20, 10)) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstYear = viewDate.year - viewDate.year % (this.split * 3);\n var years = [], year;\n for (var i = 0; i < 12; i++) {\n year = new Date(firstYear + i, 0, 1);\n years.push({date: year, label: formatDate(year, this.format), selected: picker.$isSelected(year), disabled: this.isDisabled(year)});\n }\n scope.title = years[0].label + '-' + years[years.length - 1].label;\n scope.showLabels = false;\n scope.rows = split(years, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear();\n },\n isDisabled: function(date) {\n var lastDate = +new Date(date.getFullYear() + 1, 0, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualYear = picker.$date.getFullYear(),\n newDate = new Date(picker.$date);\n\n if(evt.keyCode === 37) newDate.setYear(actualYear - 1);\n else if(evt.keyCode === 38) newDate.setYear(actualYear - 4);\n else if(evt.keyCode === 39) newDate.setYear(actualYear + 1);\n else if(evt.keyCode === 40) newDate.setYear(actualYear + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }];\n\n return {\n views: options.minView ? Array.prototype.slice.call(views, options.minView) : views,\n viewDate: viewDate\n };\n\n };\n\n };\n\n });\n\n// Source: dropdown/dropdown.js\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory(element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function(evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if(!items.length) return;\n var index;\n angular.forEach(items, function(el, i) {\n if(matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if(evt.keyCode === 38 && index > 0) index--;\n else if(evt.keyCode === 40 && index < items.length - 1) index++;\n else if(angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n parentEl.hasClass('dropdown') && parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function() {\n if(!$dropdown.$isShown) return;\n options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n parentEl.hasClass('dropdown') && parentEl.removeClass('open');\n hide();\n };\n\n var destroy = $dropdown.destroy;\n $dropdown.destroy = function() {\n bodyEl.off('click', onBodyClick);\n destroy();\n };\n\n // Private functions\n\n function onBodyClick(evt) {\n if(evt.target === element[0]) return;\n return evt.target !== element[0] && $dropdown.hide();\n }\n\n return $dropdown;\n\n }\n\n return DropdownFactory;\n\n };\n\n })\n\n .directive('bsDropdown', function($window, $sce, $dropdown) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as an object\n attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {\n scope.content = newValue;\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!dropdown || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);\n newValue === true ? dropdown.show() : dropdown.hide();\n });\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (dropdown) dropdown.destroy();\n options = null;\n dropdown = null;\n });\n\n }\n };\n\n });\n\n// Source: helpers/compiler.js\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {\n /* jshint validthis: true */\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function(options) {\n\n if(options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function(value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n resolve.$template = $q.when(template);\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function(templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function(locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link(scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function(res) {\n return res.data;\n }));\n }\n\n}\n\n// Source: helpers/date-formatter.js\nangular.module('mgcrea.ngStrap.helpers.dateFormatter', [])\n\n .service('$dateFormatter', function($locale, dateFilter) {\n\n // The unused `lang` arguments are on purpose. The default implementation does not\n // use them and it always uses the locale loaded into the `$locale` service.\n // Custom implementations might use it, thus allowing different directives to\n // have different languages.\n\n this.getDefaultLocale = function() {\n return $locale.id;\n };\n\n // Format is either a data format name, e.g. \"shortTime\" or \"fullDate\", or a date format\n // Return either the corresponding date format or the given date format.\n this.getDatetimeFormat = function(format, lang) {\n return $locale.DATETIME_FORMATS[format] || format;\n };\n\n this.weekdaysShort = function(lang) {\n return $locale.DATETIME_FORMATS.SHORTDAY;\n };\n\n function splitTimeFormat(format) {\n return /(h+)([:\\.])?(m+)([:\\.])?(s*)[ ]?(a?)/i.exec(format).slice(1);\n }\n\n // h:mm a => h\n this.hoursFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[0];\n };\n\n // h:mm a => mm\n this.minutesFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[2];\n };\n\n // h:mm:ss a => ss\n this.secondsFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => :\n this.timeSeparator = function(timeFormat) {\n return splitTimeFormat(timeFormat)[1];\n };\n\n // h:mm:ss a => true, h:mm a => false\n this.showSeconds = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => true, H.mm => false\n this.showAM = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[5];\n };\n\n this.formatDate = function(date, format, lang, timezone){\n return dateFilter(date, format, timezone);\n };\n\n });\n\n// Source: helpers/date-parser.js\nangular.module('mgcrea.ngStrap.helpers.dateParser', [])\n\n.provider('$dateParser', function($localeProvider) {\n\n // define a custom ParseDate object to use instead of native Date\n // to avoid date values wrapping when setting date component values\n function ParseDate() {\n this.year = 1970;\n this.month = 0;\n this.day = 1;\n this.hours = 0;\n this.minutes = 0;\n this.seconds = 0;\n this.milliseconds = 0;\n }\n\n ParseDate.prototype.setMilliseconds = function(value) { this.milliseconds = value; };\n ParseDate.prototype.setSeconds = function(value) { this.seconds = value; };\n ParseDate.prototype.setMinutes = function(value) { this.minutes = value; };\n ParseDate.prototype.setHours = function(value) { this.hours = value; };\n ParseDate.prototype.getHours = function() { return this.hours; };\n ParseDate.prototype.setDate = function(value) { this.day = value; };\n ParseDate.prototype.setMonth = function(value) { this.month = value; };\n ParseDate.prototype.setFullYear = function(value) { this.year = value; };\n ParseDate.prototype.fromDate = function(value) {\n this.year = value.getFullYear();\n this.month = value.getMonth();\n this.day = value.getDate();\n this.hours = value.getHours();\n this.minutes = value.getMinutes();\n this.seconds = value.getSeconds();\n this.milliseconds = value.getMilliseconds();\n return this;\n };\n\n ParseDate.prototype.toDate = function() {\n return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);\n };\n\n var proto = ParseDate.prototype;\n\n function noop() {\n }\n\n function isNumeric(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n function indexOfCaseInsensitive(array, value) {\n var len = array.length, str=value.toString().toLowerCase();\n for (var i=0; i 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function(date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n /* Correct the date for timezone offset.\n * @param date (Date) the date to adjust\n * @param timezone (string) the timezone to adjust for\n * @param undo (boolean) to add or subtract timezone offset\n * @return (Date) the corrected date\n */\n $dateParser.timezoneOffsetAdjust = function(date, timezone, undo) {\n if (!date) {\n return null;\n }\n // Right now, only 'UTC' is supported.\n if (timezone && timezone === 'UTC') {\n date = new Date(date.getTime());\n date.setMinutes(date.getMinutes() + (undo?-1:1)*date.getTimezoneOffset());\n }\n return date;\n };\n\n // Private functions\n\n function setMapForFormat(format) {\n var keys = Object.keys(setFnMap), i;\n var map = [], sortedMap = [];\n // Map to setFn\n var clonedFormat = format;\n for(i = 0; i < keys.length; i++) {\n if(format.split(keys[i]).length > 1) {\n var index = clonedFormat.search(keys[i]);\n format = format.split(keys[i]).join('');\n if(setFnMap[keys[i]]) {\n map[index] = setFnMap[keys[i]];\n }\n }\n }\n // Sort result map\n angular.forEach(map, function(v) {\n // conditional required since angular.forEach broke around v1.2.21\n // related pr: https://github.com/angular/angular.js/pull/8525\n if(v) sortedMap.push(v);\n });\n return sortedMap;\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\//g, '[\\\\/]').replace('/-/g', '[-]').replace(/\\./g, '[.]').replace(/\\\\s/g, '[\\\\s]');\n }\n\n function regExpForFormat(format) {\n var keys = Object.keys(regExpMap), i;\n\n var re = format;\n // Abstract replaces to avoid collisions\n for(i = 0; i < keys.length; i++) {\n re = re.split(keys[i]).join('${' + i + '}');\n }\n // Replace abstracted values\n for(i = 0; i < keys.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');\n }\n format = escapeReservedSymbols(format);\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n\n// Source: helpers/debounce.js\nangular.module('mgcrea.ngStrap.helpers.debounce', [])\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L693\n.factory('debounce', function($timeout) {\n return function(func, wait, immediate) {\n var timeout = null;\n return function() {\n var context = this,\n args = arguments,\n callNow = immediate && !timeout;\n if(timeout) {\n $timeout.cancel(timeout);\n }\n timeout = $timeout(function later() {\n timeout = null;\n if(!immediate) {\n func.apply(context, args);\n }\n }, wait, false);\n if(callNow) {\n func.apply(context, args);\n }\n return timeout;\n };\n };\n})\n\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L661\n.factory('throttle', function($timeout) {\n return function(func, wait, options) {\n var timeout = null;\n options || (options = {});\n return function() {\n var context = this,\n args = arguments;\n if(!timeout) {\n if(options.leading !== false) {\n func.apply(context, args);\n }\n timeout = $timeout(function later() {\n timeout = null;\n if(options.trailing !== false) {\n func.apply(context, args);\n }\n }, wait, false);\n }\n };\n };\n});\n\n// Source: helpers/dimensions.js\nangular.module('mgcrea.ngStrap.helpers.dimensions', [])\n\n .factory('dimensions', function($document, $window) {\n\n var jqLite = angular.element;\n var fn = {};\n\n /**\n * Test the element nodeName\n * @param element\n * @param name\n */\n var nodeName = fn.nodeName = function(element, name) {\n return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase();\n };\n\n /**\n * Returns the element computed style\n * @param element\n * @param prop\n * @param extra\n */\n fn.css = function(element, prop, extra) {\n var value;\n if (element.currentStyle) { //IE\n value = element.currentStyle[prop];\n } else if (window.getComputedStyle) {\n value = window.getComputedStyle(element)[prop];\n } else {\n value = element.style[prop];\n }\n return extra === true ? parseFloat(value) || 0 : value;\n };\n\n /**\n * Provides read-only equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.offset = function(element) {\n var boxRect = element.getBoundingClientRect();\n var docElement = element.ownerDocument;\n return {\n width: boxRect.width || element.offsetWidth,\n height: boxRect.height || element.offsetHeight,\n top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0),\n left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0)\n };\n };\n \n /**\n * Provides set equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip\n * @url http://api.jquery.com/offset/\n * @param element\n * @param options\n * @param i\n */\n fn.setOffset = function (element, options, i) {\n var curPosition,\n curLeft,\n curCSSTop,\n curTop,\n curOffset,\n curCSSLeft,\n calculatePosition,\n position = fn.css(element, 'position'),\n curElem = angular.element(element),\n props = {};\n \n // Set position first, in-case top/left are set even on static elem\n if (position === 'static') {\n element.style.position = 'relative';\n }\n \n curOffset = fn.offset(element);\n curCSSTop = fn.css(element, 'top');\n curCSSLeft = fn.css(element, 'left');\n calculatePosition = (position === 'absolute' || position === 'fixed') && \n (curCSSTop + curCSSLeft).indexOf('auto') > -1;\n \n // Need to be able to calculate position if either\n // top or left is auto and position is either absolute or fixed\n if (calculatePosition) {\n curPosition = fn.position(element);\n curTop = curPosition.top;\n curLeft = curPosition.left;\n } else {\n curTop = parseFloat(curCSSTop) || 0;\n curLeft = parseFloat(curCSSLeft) || 0;\n }\n \n if (angular.isFunction(options)) {\n options = options.call(element, i, curOffset);\n }\n \n if (options.top !== null ) {\n props.top = (options.top - curOffset.top) + curTop;\n }\n if ( options.left !== null ) {\n props.left = (options.left - curOffset.left) + curLeft;\n }\n\n if ('using' in options) {\n options.using.call(curElem, props);\n } else {\n curElem.css({\n top: props.top + 'px',\n left: props.left + 'px'\n });\n }\n };\n\n /**\n * Provides read-only equivalent of jQuery's position function\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.position = function(element) {\n\n var offsetParentRect = {top: 0, left: 0},\n offsetParentElement,\n offset;\n\n // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent\n if (fn.css(element, 'position') === 'fixed') {\n\n // We assume that getBoundingClientRect is available when computed position is fixed\n offset = element.getBoundingClientRect();\n\n } else {\n\n // Get *real* offsetParentElement\n offsetParentElement = offsetParent(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentElement, 'html')) {\n offsetParentRect = fn.offset(offsetParentElement);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentElement, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentElement, 'borderLeftWidth', true);\n }\n\n // Subtract parent offsets and element margins\n return {\n width: element.offsetWidth,\n height: element.offsetHeight,\n top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true),\n left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true)\n };\n\n };\n\n /**\n * Returns the closest, non-statically positioned offsetParent of a given element\n * @required-by fn.position\n * @param element\n */\n var offsetParent = function offsetParentElement(element) {\n var docElement = element.ownerDocument;\n var offsetParent = element.offsetParent || docElement;\n if(nodeName(offsetParent, '#document')) return docElement.documentElement;\n while(offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') {\n offsetParent = offsetParent.offsetParent;\n }\n return offsetParent || docElement.documentElement;\n };\n\n /**\n * Provides equivalent of jQuery's height function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/height/\n * @param element\n * @param outer\n */\n fn.height = function(element, outer) {\n var value = element.offsetHeight;\n if(outer) {\n value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true);\n } else {\n value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true);\n }\n return value;\n };\n\n /**\n * Provides equivalent of jQuery's width function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/width/\n * @param element\n * @param outer\n */\n fn.width = function(element, outer) {\n var value = element.offsetWidth;\n if(outer) {\n value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true);\n } else {\n value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true);\n }\n return value;\n };\n\n return fn;\n\n });\n\n// Source: helpers/parse-options.js\nangular.module('mgcrea.ngStrap.helpers.parseOptions', [])\n\n .provider('$parseOptions', function() {\n\n var defaults = this.defaults = {\n regexp: /^\\s*(.*?)(?:\\s+as\\s+(.*?))?(?:\\s+group\\s+by\\s+(.*))?\\s+for\\s+(?:([\\$\\w][\\$\\w]*)|(?:\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)))\\s+in\\s+(.*?)(?:\\s+track\\s+by\\s+(.*?))?$/\n };\n\n this.$get = function($parse, $q) {\n\n function ParseOptionsFactory(attr, config) {\n\n var $parseOptions = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n $parseOptions.$values = [];\n\n // Private vars\n var match, displayFn, valueName, keyName, groupByFn, valueFn, valuesFn;\n\n $parseOptions.init = function() {\n $parseOptions.$match = match = attr.match(options.regexp);\n displayFn = $parse(match[2] || match[1]),\n valueName = match[4] || match[6],\n keyName = match[5],\n groupByFn = $parse(match[3] || ''),\n valueFn = $parse(match[2] ? match[1] : valueName),\n valuesFn = $parse(match[7]);\n };\n\n $parseOptions.valuesFn = function(scope, controller) {\n return $q.when(valuesFn(scope, controller))\n .then(function(values) {\n if(!angular.isArray(values)) {\n values = [];\n }\n $parseOptions.$values = values.length ? parseValues(values, scope) : [];\n return $parseOptions.$values;\n });\n };\n\n $parseOptions.displayValue = function(modelValue) {\n var scope = {};\n scope[valueName] = modelValue;\n return displayFn(scope);\n };\n\n // Private functions\n\n function parseValues(values, scope) {\n return values.map(function(match, index) {\n var locals = {}, label, value;\n locals[valueName] = match;\n label = displayFn(scope, locals);\n value = valueFn(scope, locals);\n return {label: label, value: value, index: index};\n });\n }\n\n $parseOptions.init();\n return $parseOptions;\n\n }\n\n return ParseOptionsFactory;\n\n };\n\n });\n\n// Source: helpers/raf.js\n(angular.version.minor < 3 && angular.version.dot < 14) && angular.module('ng')\n\n.factory('$$rAF', function($window, $timeout) {\n\n var requestAnimationFrame = $window.requestAnimationFrame ||\n $window.webkitRequestAnimationFrame ||\n $window.mozRequestAnimationFrame;\n\n var cancelAnimationFrame = $window.cancelAnimationFrame ||\n $window.webkitCancelAnimationFrame ||\n $window.mozCancelAnimationFrame ||\n $window.webkitCancelRequestAnimationFrame;\n\n var rafSupported = !!requestAnimationFrame;\n var raf = rafSupported ?\n function(fn) {\n var id = requestAnimationFrame(fn);\n return function() {\n cancelAnimationFrame(id);\n };\n } :\n function(fn) {\n var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666\n return function() {\n $timeout.cancel(timer);\n };\n };\n\n raf.supported = rafSupported;\n\n return raf;\n\n});\n\n// .factory('$$animateReflow', function($$rAF, $document) {\n\n// var bodyEl = $document[0].body;\n\n// return function(fn) {\n// //the returned function acts as the cancellation function\n// return $$rAF(function() {\n// //the line below will force the browser to perform a repaint\n// //so that all the animated elements within the animation frame\n// //will be properly updated and drawn on screen. This is\n// //required to perform multi-class CSS based animations with\n// //Firefox. DO NOT REMOVE THIS LINE.\n// var a = bodyEl.offsetWidth + 1;\n// fn();\n// });\n// };\n\n// });\n\n// Source: modal/modal.js\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var trim = String.prototype.trim;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if(!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function(key) {\n if(options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $modal.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $modal.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData, modalElement, modalScope;\n var backdropElement = angular.element('
');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n promise.then(function(data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function() {\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function() {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, after;\n if(angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if(modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {});\n\n if(scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) {\n return;\n }\n\n // Set the initial positioning.\n modalElement.css({display: 'block'}).addClass(options.placement);\n\n // Options: animation\n if(options.animation) {\n if(options.backdrop) {\n backdropElement.addClass(options.backdropAnimation);\n }\n modalElement.addClass(options.animation);\n }\n\n if(options.backdrop) {\n $animate.enter(backdropElement, bodyElement, null);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(modalElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(modalElement, parent, after).then(enterAnimateCallback);\n }\n\n $modal.$isShown = scope.$isShown = true;\n safeDigest(scope);\n // Focus once the enter-animation has started\n // Weird PhantomJS bug hack\n var el = modalElement[0];\n requestAnimationFrame(function() {\n el.focus();\n });\n\n bodyElement.addClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.addClass(options.prefixClass + '-with-' + options.animation);\n }\n\n // Bind events\n bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $modal);\n }\n\n $modal.hide = function() {\n if(!$modal.$isShown) return;\n\n if(scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if(options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n bodyElement.removeClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function() {\n\n $modal.$isShown ? $modal.hide() : $modal.show();\n\n };\n\n $modal.focus = function() {\n modalElement[0].focus();\n };\n\n // Protected methods\n\n $modal.$onKeyUp = function(evt) {\n\n if (evt.which === 27 && $modal.$isShown) {\n $modal.hide();\n evt.stopPropagation();\n }\n\n };\n\n function bindBackdropEvents() {\n if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents() {\n if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private methods\n\n function hideOnBackdropClick(evt) {\n if(evt.target !== evt.currentTarget) return;\n options.backdrop === 'static' ? $modal.focus() : $modal.hide();\n }\n\n function preventEventDefault(evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement() {\n if($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if(modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if(modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function($window, $sce, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'controller', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'id', 'prefixEvent', 'prefixClass'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsModal && scope.$watch(attr.bsModal, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize modal\n var modal = $modal(options);\n\n // Trigger\n element.on(attr.trigger || 'click', modal.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (modal) modal.destroy();\n options = null;\n modal = null;\n });\n\n }\n };\n\n });\n\n// Source: navbar/navbar.js\nangular.module('mgcrea.ngStrap.navbar', [])\n\n .provider('$navbar', function() {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n routeAttr: 'data-match-route',\n strict: false\n };\n\n this.$get = function() {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsNavbar', function($window, $location, $navbar) {\n\n var defaults = $navbar.defaults;\n\n return {\n restrict: 'A',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = angular.copy(defaults);\n angular.forEach(Object.keys(defaults), function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Watch for the $location\n scope.$watch(function() {\n\n return $location.path();\n\n }, function(newValue, oldValue) {\n\n var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']');\n\n angular.forEach(liElements, function(li) {\n\n var liElement = angular.element(li);\n var pattern = liElement.attr(options.routeAttr).replace('/', '\\\\/');\n if(options.strict) {\n pattern = '^' + pattern + '$';\n }\n var regexp = new RegExp(pattern, 'i');\n\n if(regexp.test(newValue)) {\n liElement.addClass(options.activeClass);\n } else {\n liElement.removeClass(options.activeClass);\n }\n\n });\n\n });\n\n }\n\n };\n\n });\n\n// Source: popover/popover.js\nangular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function($tooltip) {\n\n function PopoverFactory(element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if(options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n });\n });\n\n // Support scope as an object\n attr.bsPopover && scope.$watch(attr.bsPopover, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);\n newValue === true ? popover.show() : popover.hide();\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n\n // Initialize popover\n var popover = $popover(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (popover) popover.destroy();\n options = null;\n popover = null;\n });\n\n }\n };\n\n });\n\n// Source: scrollspy/scrollspy.js\nangular.module('mgcrea.ngStrap.scrollspy', ['mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$scrollspy', function() {\n\n // Pool of registered spies\n var spies = this.$$spies = {};\n\n var defaults = this.defaults = {\n debounce: 150,\n throttle: 100,\n offset: 100\n };\n\n this.$get = function($window, $document, $rootScope, dimensions, debounce, throttle) {\n\n var windowEl = angular.element($window);\n var docEl = angular.element($document.prop('documentElement'));\n var bodyEl = angular.element($window.document.body);\n\n // Helper functions\n\n function nodeName(element, name) {\n return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase();\n }\n\n function ScrollSpyFactory(config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n if(!options.element) options.element = bodyEl;\n var isWindowSpy = nodeName(options.element, 'body');\n var scrollEl = isWindowSpy ? windowEl : options.element;\n var scrollId = isWindowSpy ? 'window' : options.id;\n\n // Use existing spy\n if(spies[scrollId]) {\n spies[scrollId].$$count++;\n return spies[scrollId];\n }\n\n var $scrollspy = {};\n\n // Private vars\n var unbindViewContentLoaded, unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n var viewportHeight;\n var scrollTop;\n\n $scrollspy.init = function() {\n\n // Setup internal ref counter\n this.$$count = 1;\n\n // Bind events\n debouncedCheckPosition = debounce(this.checkPosition, options.debounce);\n throttledCheckPosition = throttle(this.checkPosition, options.throttle);\n scrollEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', debouncedCheckPosition);\n scrollEl.on('scroll', throttledCheckPosition);\n\n debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce);\n unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets);\n unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets);\n debouncedCheckOffsets();\n\n // Register spy for reuse\n if(scrollId) {\n spies[scrollId] = $scrollspy;\n }\n\n };\n\n $scrollspy.destroy = function() {\n\n // Check internal ref counter\n this.$$count--;\n if(this.$$count > 0) {\n return;\n }\n\n // Unbind events\n scrollEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', debouncedCheckPosition);\n scrollEl.off('scroll', throttledCheckPosition);\n unbindViewContentLoaded();\n unbindIncludeContentLoaded();\n if (scrollId) {\n delete spies[scrollId];\n }\n };\n\n $scrollspy.checkPosition = function() {\n\n // Not ready yet\n if(!sortedElements.length) return;\n\n // Calculate the scroll position\n scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0;\n\n // Calculate the viewport height for use by the components\n viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight'));\n\n // Activate first element if scroll is smaller\n if(scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) {\n return $scrollspy.$activateElement(sortedElements[0]);\n }\n\n // Activate proper element\n for (var i = sortedElements.length; i--;) {\n if(angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue;\n if(activeTarget === sortedElements[i].target) continue;\n if(scrollTop < sortedElements[i].offsetTop) continue;\n if(sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue;\n return $scrollspy.$activateElement(sortedElements[i]);\n }\n\n };\n\n $scrollspy.checkPositionWithEventLoop = function() {\n // IE 9 throws an error if we use 'this' instead of '$scrollspy'\n // in this setTimeout call\n setTimeout($scrollspy.checkPosition, 1);\n };\n\n // Protected methods\n\n $scrollspy.$activateElement = function(element) {\n if(activeTarget) {\n var activeElement = $scrollspy.$getTrackedElement(activeTarget);\n if(activeElement) {\n activeElement.source.removeClass('active');\n if(nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) {\n activeElement.source.parent().parent().removeClass('active');\n }\n }\n }\n activeTarget = element.target;\n element.source.addClass('active');\n if(nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) {\n element.source.parent().parent().addClass('active');\n }\n };\n\n $scrollspy.$getTrackedElement = function(target) {\n return trackedElements.filter(function(obj) {\n return obj.target === target;\n })[0];\n };\n\n // Track offsets behavior\n\n $scrollspy.checkOffsets = function() {\n\n angular.forEach(trackedElements, function(trackedElement) {\n var targetElement = document.querySelector(trackedElement.target);\n trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null;\n if(options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1;\n });\n\n sortedElements = trackedElements\n .filter(function(el) {\n return el.offsetTop !== null;\n })\n .sort(function(a, b) {\n return a.offsetTop - b.offsetTop;\n });\n\n debouncedCheckPosition();\n\n };\n\n $scrollspy.trackElement = function(target, source) {\n trackedElements.push({target: target, source: source});\n };\n\n $scrollspy.untrackElement = function(target, source) {\n var toDelete;\n for (var i = trackedElements.length; i--;) {\n if(trackedElements[i].target === target && trackedElements[i].source === source) {\n toDelete = i;\n break;\n }\n }\n trackedElements = trackedElements.splice(toDelete, 1);\n };\n\n $scrollspy.activate = function(i) {\n trackedElements[i].addClass('active');\n };\n\n // Initialize plugin\n\n $scrollspy.init();\n return $scrollspy;\n\n }\n\n return ScrollSpyFactory;\n\n };\n\n })\n\n .directive('bsScrollspy', function($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'EAC',\n link: function postLink(scope, element, attr) {\n\n var options = {scope: scope};\n angular.forEach(['offset', 'target'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n var scrollspy = $scrollspy(options);\n scrollspy.trackElement(options.target, element);\n\n scope.$on('$destroy', function() {\n if (scrollspy) {\n scrollspy.untrackElement(options.target, element);\n scrollspy.destroy();\n }\n options = null;\n scrollspy = null;\n });\n\n }\n };\n\n })\n\n\n .directive('bsScrollspyList', function($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'A',\n compile: function postLink(element, attr) {\n var children = element[0].querySelectorAll('li > a[href]');\n angular.forEach(children, function(child) {\n var childEl = angular.element(child);\n childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href'));\n });\n }\n\n };\n\n });\n\n// Source: select/select.js\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' ',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok'\n };\n\n this.$get = function($window, $document, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n\n function SelectFactory(element, controller, config) {\n\n var $select = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $select = $tooltip(element, options);\n var scope = $select.$scope;\n\n scope.$matches = [];\n if (options.multiple) {\n scope.$activeIndex = [];\n }\n else {\n scope.$activeIndex = -1;\n }\n scope.$isMultiple = options.multiple;\n scope.$showAllNoneButtons = options.allNoneButtons && options.multiple;\n scope.$iconCheckmark = options.iconCheckmark;\n scope.$allText = options.allText;\n scope.$noneText = options.noneText;\n\n scope.$activate = function(index) {\n scope.$$postDigest(function() {\n $select.activate(index);\n });\n };\n\n scope.$select = function(index, evt) {\n scope.$$postDigest(function() {\n $select.select(index);\n });\n };\n\n scope.$isVisible = function() {\n return $select.$isVisible();\n };\n\n scope.$isActive = function(index) {\n return $select.$isActive(index);\n };\n\n scope.$selectAll = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (!scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n scope.$selectNone = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n // Public methods\n\n $select.update = function(matches) {\n scope.$matches = matches;\n $select.$updateActiveIndex();\n };\n\n $select.activate = function(index) {\n if(options.multiple) {\n $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index);\n if(options.sort) scope.$activeIndex.sort(function(a, b) { return a - b; }); // use numeric sort instead of default sort\n } else {\n scope.$activeIndex = index;\n }\n return scope.$activeIndex;\n };\n\n $select.select = function(index) {\n var value = scope.$matches[index].value;\n scope.$apply(function() {\n $select.activate(index);\n if(options.multiple) {\n controller.$setViewValue(scope.$activeIndex.map(function(index) {\n return scope.$matches[index].value;\n }));\n } else {\n controller.$setViewValue(value);\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function() {\n if(controller.$modelValue && scope.$matches.length) {\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n }\n } else if(scope.$activeIndex >= scope.$matches.length) {\n scope.$activeIndex = options.multiple ? [] : 0;\n }\n };\n\n $select.$isVisible = function() {\n if(!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function(index) {\n if(options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n } else {\n return scope.$activeIndex === index;\n }\n };\n\n $select.$getIndex = function(value) {\n var l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\n };\n\n $select.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n targetEl.triggerHandler('click');\n }\n };\n\n $select.$onKeyDown = function(evt) {\n if (!/(9|13|38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if(!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if(evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if(evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if(angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function() {\n _show();\n if(options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function() {\n if(!options.multiple && !controller.$modelValue) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Only parse data-multiple. Angular sets existence attributes to true (multiple/required/etc), they apply this\n // to data-multiple as well for some reason, so we'll parse this ourselves and disregard multiple\n var dataMultiple = element.attr('data-multiple');\n if(angular.isDefined(dataMultiple)) {\n if(falseValueRegExp.test(dataMultiple))\n options.multiple = false;\n else\n options.multiple = dataMultiple;\n }\n\n // Add support for select markup\n if(element[0].nodeName.toLowerCase() === 'select') {\n var inputEl = element;\n inputEl.css('display', 'none');\n element = angular.element('');\n inputEl.after(element);\n }\n\n // Build proper bsOptions\n var parsedOptions = $parseOptions(attr.bsOptions);\n\n // Initialize select\n var select = $select(element, controller, options);\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n select.update(values);\n controller.$render();\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);\n select.$updateActiveIndex();\n controller.$render();\n }, true);\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var selected, index;\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function(value) {\n index = select.$getIndex(value);\n return angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }).filter(angular.isDefined);\n if(selected.length > (options.maxLength || defaults.maxLength)) {\n selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);\n } else {\n selected = selected.join(', ');\n }\n } else {\n index = select.$getIndex(controller.$modelValue);\n selected = angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }\n element.html((selected ? selected : options.placeholder) + (options.caretHtml ? options.caretHtml : defaults.caretHtml));\n };\n\n if(options.multiple){\n controller.$isEmpty = function(value){\n return !value || value.length === 0;\n };\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (select) select.destroy();\n options = null;\n select = null;\n });\n\n }\n };\n\n });\n\n// Source: timepicker/timepicker.js\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory(element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes(time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n timeSeparator = $dateFormatter.timeSeparator(format),\n minutesFormat = $dateFormatter.minutesFormat(format),\n secondsFormat = $dateFormatter.secondsFormat(format),\n showSeconds = $dateFormatter.showSeconds(format),\n showAM = $dateFormatter.showAM(format);\n\n scope.$iconUp = options.iconUp;\n scope.$iconDown = options.iconDown;\n\n // Scope methods\n\n scope.$select = function(date, index) {\n $timepicker.select(date, index);\n };\n scope.$moveIndex = function(value, index) {\n $timepicker.$moveIndex(value, index);\n };\n scope.$switchMeridian = function(date) {\n $timepicker.switchMeridian(date);\n };\n\n // Public methods\n\n $timepicker.update = function(date) {\n // console.warn('$timepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $timepicker.$date = date;\n angular.extend(viewDate, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function(date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function() {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function(date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function() {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [],\n hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [],\n minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [],\n second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function(date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function(date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function(value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function(value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function(value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(),\n hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(),\n minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(),\n secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection(start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.on('keydown', $timepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $timepicker.hide;\n $timepicker.hide = function(blur) {\n if (!$timepicker.$isShown) return;\n $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.off('keydown', $timepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $timepicker;\n\n }\n\n timepickerFactory.defaults = defaults;\n return timepickerFactory;\n\n };\n\n })\n\n\n .directive('bsTimepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {\n\n var defaults = $timepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if (!timepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);\n newValue === true ? timepicker.show() : timepicker.hide();\n });\n\n // Initialize timepicker\n if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';\n var timepicker = $timepicker(element, controller, options);\n options = timepicker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n // Initialize parser\n var dateParser = $dateParser({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n !isNaN(timepicker.$options[key]) && timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);\n timepicker.update(controller.$dateValue);\n }, true);\n\n function validateAgainstMinMaxTime(parsedTime) {\n if (!angular.isDate(parsedTime)) return;\n var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;\n var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (!isValid) {\n return;\n }\n controller.$dateValue = parsedTime;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n controller.$setValidity('date', true);\n return null;\n }\n var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedTime || isNaN(parsedTime.getTime())) {\n controller.$setValidity('date', false);\n // Return undefined, causes ngModelController to\n // invalidate model value\n return undefined;\n } else {\n validateAgainstMinMaxTime(parsedTime);\n }\n\n if (options.timeType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true);\n return formatDate(date, options.modelTimeFormat || options.timeFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.timeType === 'number') {\n return date.getTime();\n } else if (options.timeType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.timeType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n\n// Source: tab/tab.js\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function(key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // Please use $activePaneChangeListeners if you use `bsActivePane`\n // Because we removed `ngModel` as default, we rename viewChangeListeners to\n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function(pane) {\n if(angular.isUndefined(self.$panes.$active)) {\n $scope.$setActive(pane.name || 0);\n }\n self.$panes.push(pane);\n };\n\n self.$remove = function(pane) {\n var index = self.$panes.indexOf(pane);\n var active = self.$panes.$active;\n var activeIndex;\n if(angular.isString(active)) {\n activeIndex = self.$panes.map(function(pane) {\n return pane.name;\n }).indexOf(active);\n } else {\n activeIndex = self.$panes.$active;\n }\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to\n // decrement the active pane index\n activeIndex--;\n }\n else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n if(activeIndex >= 0 && activeIndex < self.$panes.length) {\n self.$setActive(self.$panes[activeIndex].name || activeIndex);\n } else {\n self.$setActive();\n }\n };\n\n self.$setActive = $scope.$setActive = function(value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$isActive = $scope.$isActive = function($pane, $index) {\n return self.$panes.$active === $pane.name || self.$panes.$active === $index;\n };\n\n };\n\n this.$get = function() {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function(element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // 'ngModel' does interfere with form validation\n // and status, use `bsActivePane` instead to avoid it\n if(ngModelCtrl) {\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function(newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function(newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Save tab name into scope\n scope.name = attrs.name;\n\n // Add animation class\n if(bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n attrs.$observe('disabled', function(newValue, oldValue) {\n scope.disabled = scope.$eval(newValue);\n });\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function() {\n bsTabsCtrl.$remove(scope);\n });\n\n function render() {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n render();\n });\n render();\n\n }\n };\n\n });\n\n// Source: typeahead/typeahead.js\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n\n function TypeaheadFactory(element, controller, config) {\n\n var $typeahead = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $typeahead = $tooltip(element, options);\n var parentScope = config.scope;\n var scope = $typeahead.$scope;\n\n scope.$resetMatches = function() {\n scope.$matches = [];\n scope.$activeIndex = options.autoSelect ? 0 : -1; // If set to 0, the first match will be highlighted\n };\n scope.$resetMatches();\n\n scope.$activate = function(index) {\n scope.$$postDigest(function() {\n $typeahead.activate(index);\n });\n };\n\n scope.$select = function(index, evt) {\n scope.$$postDigest(function() {\n $typeahead.select(index);\n });\n };\n\n scope.$isVisible = function() {\n return $typeahead.$isVisible();\n };\n\n // Public methods\n\n $typeahead.update = function(matches) {\n scope.$matches = matches;\n if (scope.$activeIndex >= matches.length) {\n scope.$activeIndex = options.autoSelect ? 0 : -1;\n }\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n safeDigest(scope);\n $$rAF($typeahead.$applyPlacement);\n };\n\n $typeahead.activate = function(index) {\n scope.$activeIndex = index;\n };\n\n $typeahead.select = function(index) {\n if (index === -1) return;\n var value = scope.$matches[index].value;\n // console.log('$setViewValue', value);\n controller.$setViewValue(value);\n controller.$render();\n scope.$resetMatches();\n if (parentScope) parentScope.$digest();\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $typeahead);\n };\n\n // Protected methods\n\n $typeahead.$isVisible = function() {\n if (!options.minLength || !controller) {\n return !!scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength;\n };\n\n $typeahead.$getIndex = function(value) {\n var l = scope.$matches.length,\n i = l;\n if (!l) return;\n for (i = l; i--;) {\n if (scope.$matches[i].value === value) break;\n }\n if (i < 0) return;\n return i;\n };\n\n $typeahead.$onMouseDown = function(evt) {\n // Prevent blur on mousedown\n evt.preventDefault();\n evt.stopPropagation();\n };\n\n $typeahead.$onKeyDown = function(evt) {\n if (!/(38|40|13)/.test(evt.keyCode)) return;\n\n // Let ngSubmit pass if the typeahead tip is hidden or no option is selected\n if ($typeahead.$isVisible() && !(evt.keyCode === 13 && scope.$activeIndex === -1)) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // Select with enter\n if (evt.keyCode === 13 && scope.$matches.length) {\n $typeahead.select(scope.$activeIndex);\n }\n\n // Navigate with keyboard\n else if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n };\n\n // Overrides\n\n var show = $typeahead.show;\n $typeahead.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed immediately.\n $timeout(function() {\n $typeahead.$element && $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n element && element.on('keydown', $typeahead.$onKeyDown);\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function() {\n $typeahead.$element && $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n element && element.off('keydown', $typeahead.$onKeyDown);\n }\n if (!options.autoSelect)\n $typeahead.activate(-1);\n hide();\n };\n\n return $typeahead;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\n\n })\n\n .filter('bsAsyncFilter', function($filter) {\n return function(array, expression, comparator) {\n if (array && angular.isFunction(array.then)) {\n return array.then(function(results) {\n return $filter('filter')(results, expression, comparator);\n });\n } else {\n return $filter('filter')(array, expression, comparator);\n }\n };\n })\n\n .directive('bsTypeahead', function($window, $parse, $q, $typeahead, $parseOptions) {\n\n var defaults = $typeahead.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'trimValue'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n element.attr('autocomplete', 'false');\n\n // Build proper bsOptions\n var filter = options.filter || defaults.filter;\n var limit = options.limit || defaults.limit;\n var comparator = options.comparator || defaults.comparator;\n\n var bsOptions = attr.bsOptions;\n if (filter) bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\n if (limit) bsOptions += ' | limitTo:' + limit;\n var parsedOptions = $parseOptions(bsOptions);\n\n // Initialize typeahead\n var typeahead = $typeahead(element, controller, options);\n\n // Watch options on demand\n if (options.watchOptions) {\n // Watch bsOptions values before filtering for changes, drop function calls\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').replace(/\\(.*\\)/g, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller).then(function(values) {\n typeahead.update(values);\n controller.$render();\n });\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('$watch', element.attr('ng-model'), newValue);\n scope.$modelValue = newValue; // Publish modelValue on scope for custom templates\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n // Prevent input with no future prospect if selectMode is truthy\n // @TODO test selectMode\n if (options.selectMode && !values.length && newValue.length > 0) {\n controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1));\n return;\n }\n if (values.length > limit) values = values.slice(0, limit);\n var isVisible = typeahead.$isVisible();\n isVisible && typeahead.update(values);\n // Do not re-queue an update if a correct value has been selected\n if (values.length === 1 && values[0].value === newValue) return;\n !isVisible && typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (modelValue && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function() {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = angular.isDefined(index) ? typeahead.$scope.$matches[index].label : controller.$viewValue;\n selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected;\n var value = selected ? selected.toString().replace(/<(?:.|\\n)*?>/gm, '') : '';\n element.val(options.trimValue === false ? value : value.trim());\n };\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (typeahead) typeahead.destroy();\n options = null;\n typeahead = null;\n });\n\n }\n };\n\n });\n\n// Source: tooltip/tooltip.js\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n contentTemplate: false,\n trigger: 'hover focus',\n keyboard: false,\n html: false,\n show: false,\n title: '',\n type: '',\n delay: 0,\n autoClose: false,\n bsEnabled: true,\n viewport: {\n selector: 'body',\n padding: 0\n }\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var trim = String.prototype.trim;\n var isTouch = 'createTouch' in $window.document;\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n var $body = angular.element($window.document);\n\n function TooltipFactory(element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if(options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if(options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function(isEnabled) {\n scope.$$postDigest(function() {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $tooltip.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $tooltip.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout, hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData, tipElement, tipContainer, tipScope;\n promise.then(function(data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function() {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if(options.container === 'self') {\n tipContainer = element;\n } else if(angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if(options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if(options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n options.trigger === 'focus' ? element[0].focus() : $tooltip.show();\n });\n }\n\n };\n\n $tooltip.destroy = function() {\n\n // Unbind events\n unbindTriggerEvents();\n\n // Remove element\n destroyTipElement();\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $tooltip.enter = function() {\n\n clearTimeout(timeout);\n hoverState = 'in';\n if (!options.delay || !options.delay.show) {\n return $tooltip.show();\n }\n\n timeout = setTimeout(function() {\n if (hoverState ==='in') $tooltip.show();\n }, options.delay.show);\n\n };\n\n $tooltip.show = function() {\n if (!options.bsEnabled || $tooltip.$isShown) return;\n\n scope.$emit(options.prefixEvent + '.show.before', $tooltip);\n var parent, after;\n if (options.container) {\n parent = tipContainer;\n if (tipContainer[0].lastChild) {\n after = angular.element(tipContainer[0].lastChild);\n } else {\n after = null;\n }\n } else {\n parent = null;\n after = element;\n }\n\n\n // Hide any existing tipElement\n if(tipElement) destroyTipElement();\n // Fetch a cloned element linked from template\n tipScope = $tooltip.$scope.$new();\n tipElement = $tooltip.$element = compileData.link(tipScope, function(clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if(options.animation) tipElement.addClass(options.animation);\n // Options: type\n if(options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if(options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n after ? after.after(tipElement) : parent.prepend(tipElement);\n\n $tooltip.$isShown = scope.$isShown = true;\n safeDigest(scope);\n\n // Now, apply placement\n $tooltip.$applyPlacement();\n\n // Once placed, animate it.\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(tipElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(tipElement, parent, after).then(enterAnimateCallback);\n }\n safeDigest(scope);\n\n $$rAF(function () {\n // Once the tooltip is placed and the animation starts, make the tooltip visible\n if(tipElement) tipElement.css({visibility: 'visible'});\n });\n\n // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n\n if(options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n }\n\n $tooltip.leave = function() {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function(blur) {\n\n if(!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if(options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if(_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function() {\n $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter();\n };\n\n $tooltip.focus = function() {\n tipElement[0].focus();\n };\n\n $tooltip.setEnabled = function(isEnabled) {\n options.bsEnabled = isEnabled;\n };\n\n $tooltip.setViewport = function(viewport) {\n options.viewport = viewport;\n };\n\n // Protected methods\n\n $tooltip.$applyPlacement = function() {\n if(!tipElement) return;\n\n // Determine if we're doing an auto or normal placement\n var placement = options.placement,\n autoToken = /\\s?auto?\\s?/i,\n autoPlace = autoToken.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(autoToken, '') || defaults.placement;\n }\n\n // Need to add the position class before we get\n // the offsets\n tipElement.addClass(options.placement);\n\n // Get the position of the target element\n // and the height and width of the tooltip so we can center it.\n var elementPosition = getPosition(),\n tipWidth = tipElement.prop('offsetWidth'),\n tipHeight = tipElement.prop('offsetHeight');\n\n // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n // Determine the horizontal placement\n // The exotic placements of left and right are opposite of the standard placements. Their arrows are put on the left/right\n // and flow in the opposite direction of their placement.\n if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') &&\n elementPosition.right + tipWidth > viewportPosition.width) {\n\n placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right');\n } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') &&\n elementPosition.left - tipWidth < viewportPosition.left) {\n\n placement = originalPlacement === 'left' ? 'right' : placement.replace('right', 'left');\n }\n\n tipElement.removeClass(originalPlacement).addClass(placement);\n }\n\n // Get the tooltip's top and left coordinates to center it with this directive.\n var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight);\n applyPlacement(tipPosition, placement);\n };\n\n $tooltip.$onKeyUp = function(evt) {\n if (evt.which === 27 && $tooltip.$isShown) {\n $tooltip.hide();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusKeyUp = function(evt) {\n if (evt.which === 27) {\n element[0].blur();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusElementMouseDown = function(evt) {\n evt.preventDefault();\n evt.stopPropagation();\n // Some browsers do not auto-focus buttons (eg. Safari)\n $tooltip.$isShown ? element[0].blur() : element[0].focus();\n };\n\n // bind/unbind events\n function bindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n angular.forEach(triggers, function(trigger) {\n if(trigger === 'click') {\n element.on('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n });\n }\n\n function unbindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i];\n if(trigger === 'click') {\n element.off('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n }\n\n function bindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.on('keyup', $tooltip.$onKeyUp);\n } else {\n element.on('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.off('keyup', $tooltip.$onKeyUp);\n } else {\n element.off('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n var _autoCloseEventsBinded = false;\n function bindAutoCloseEvents() {\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // Stop propagation when clicking inside tooltip\n tipElement.on('click', stopEventPropagation);\n\n // Hide when clicking outside tooltip\n $body.on('click', $tooltip.hide);\n\n _autoCloseEventsBinded = true;\n }, 0, false);\n }\n\n function unbindAutoCloseEvents() {\n if (_autoCloseEventsBinded) {\n tipElement.off('click', stopEventPropagation);\n $body.off('click', $tooltip.hide);\n _autoCloseEventsBinded = false;\n }\n }\n\n function stopEventPropagation(event) {\n event.stopPropagation();\n }\n\n // Private methods\n\n function getPosition($element) {\n $element = $element || (options.target || element);\n\n var el = $element[0],\n isBody = el.tagName === 'BODY';\n\n var elRect = el.getBoundingClientRect();\n var rect = {};\n\n // IE8 has issues with angular.extend and using elRect directly.\n // By coping the values of elRect into a new object, we can continue to use extend\n for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n\n if (rect.width === null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n rect = angular.extend({}, rect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top });\n }\n var elOffset = isBody ? { top: 0, left: 0 } : dimensions.offset(el),\n scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 },\n outerDims = isBody ? { width: document.documentElement.clientWidth, height: $window.innerHeight } : null;\n\n return angular.extend({}, rect, scroll, outerDims, elOffset);\n }\n\n function getCalculatedOffset(placement, position, actualWidth, actualHeight) {\n var offset;\n var split = placement.split('-');\n\n switch (split[0]) {\n case 'right':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left + position.width\n };\n break;\n case 'bottom':\n offset = {\n top: position.top + position.height,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n case 'left':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left - actualWidth\n };\n break;\n default:\n offset = {\n top: position.top - actualHeight,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n }\n\n if(!split[1]) {\n return offset;\n }\n\n // Add support for corners @todo css\n if(split[0] === 'top' || split[0] === 'bottom') {\n switch (split[1]) {\n case 'left':\n offset.left = position.left;\n break;\n case 'right':\n offset.left = position.left + position.width - actualWidth;\n }\n } else if(split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight;\n break;\n case 'bottom':\n offset.top = position.top + position.height;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0],\n width = tip.offsetWidth,\n height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10),\n marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10);\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0;\n if (isNaN(marginLeft)) marginLeft = 0;\n\n offset.top = offset.top + marginTop;\n offset.left = offset.left + marginLeft;\n\n // dimensions setOffset doesn't round pixel values\n // so we use setOffset directly with our own function\n dimensions.setOffset(tip, angular.extend({\n using: function (props) {\n tipElement.css({\n top: Math.round(props.top) + 'px',\n left: Math.round(props.left) + 'px',\n right: ''\n });\n }\n }, offset), 0);\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = tip.offsetWidth,\n actualHeight = tip.offsetHeight;\n\n if (placement === 'top' && actualHeight !== height) {\n offset.top = offset.top + height - actualHeight;\n }\n\n // If it's an exotic placement, exit now instead of\n // applying a delta and changing the arrow\n if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return;\n\n var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);\n\n if (delta.left) {\n offset.left += delta.left;\n } else {\n offset.top += delta.top;\n }\n\n dimensions.setOffset(tip, offset);\n\n if (/top|right|bottom|left/.test(placement)) {\n var isVertical = /top|bottom/.test(placement),\n arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight,\n arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow(delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement() {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if($tooltip.$isShown && tipElement !== null) {\n if(options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if(options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if(tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if(tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache}).then(function(res) {\n return res.data;\n }));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function($window, $location, $sce, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function(newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && scope.$watch(attr.bsTooltip, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && scope.$watch(attr.bsEnabled, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n\n})(window, document);\n","'use strict';\n\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {\n /* jshint validthis: true */\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function(options) {\n\n if(options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function(value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n resolve.$template = $q.when(template);\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function(templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0]).removeAttr('ng-bind').html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if(!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function(locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link(scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function(res) {\n return res.data;\n }));\n }\n\n}\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dateFormatter', [])\n\n .service('$dateFormatter', function($locale, dateFilter) {\n\n // The unused `lang` arguments are on purpose. The default implementation does not\n // use them and it always uses the locale loaded into the `$locale` service.\n // Custom implementations might use it, thus allowing different directives to\n // have different languages.\n\n this.getDefaultLocale = function() {\n return $locale.id;\n };\n\n // Format is either a data format name, e.g. \"shortTime\" or \"fullDate\", or a date format\n // Return either the corresponding date format or the given date format.\n this.getDatetimeFormat = function(format, lang) {\n return $locale.DATETIME_FORMATS[format] || format;\n };\n\n this.weekdaysShort = function(lang) {\n return $locale.DATETIME_FORMATS.SHORTDAY;\n };\n\n function splitTimeFormat(format) {\n return /(h+)([:\\.])?(m+)([:\\.])?(s*)[ ]?(a?)/i.exec(format).slice(1);\n }\n\n // h:mm a => h\n this.hoursFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[0];\n };\n\n // h:mm a => mm\n this.minutesFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[2];\n };\n\n // h:mm:ss a => ss\n this.secondsFormat = function(timeFormat) {\n return splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => :\n this.timeSeparator = function(timeFormat) {\n return splitTimeFormat(timeFormat)[1];\n };\n\n // h:mm:ss a => true, h:mm a => false\n this.showSeconds = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => true, H.mm => false\n this.showAM = function(timeFormat) {\n return !!splitTimeFormat(timeFormat)[5];\n };\n\n this.formatDate = function(date, format, lang, timezone){\n return dateFilter(date, format, timezone);\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.affix', ['mgcrea.ngStrap.helpers.dimensions', 'mgcrea.ngStrap.helpers.debounce'])\n\n .provider('$affix', function() {\n\n var defaults = this.defaults = {\n offsetTop: 'auto',\n inlineStyles: true\n };\n\n this.$get = function($window, debounce, dimensions) {\n\n var bodyEl = angular.element($window.document.body);\n var windowEl = angular.element($window);\n\n function AffixFactory(element, config) {\n\n var $affix = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var targetEl = options.target;\n\n // Initial private vars\n var reset = 'affix affix-top affix-bottom',\n setWidth = false,\n initialAffixTop = 0,\n initialOffsetTop = 0,\n offsetTop = 0,\n offsetBottom = 0,\n affixed = null,\n unpin = null;\n\n var parent = element.parent();\n // Options: custom parent\n if (options.offsetParent) {\n if (options.offsetParent.match(/^\\d+$/)) {\n for (var i = 0; i < (options.offsetParent * 1) - 1; i++) {\n parent = parent.parent();\n }\n }\n else {\n parent = angular.element(options.offsetParent);\n }\n }\n\n $affix.init = function() {\n\n this.$parseOffsets();\n initialOffsetTop = dimensions.offset(element[0]).top + initialAffixTop;\n setWidth = !element[0].style.width;\n\n // Bind events\n targetEl.on('scroll', this.checkPosition);\n targetEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', this.$debouncedOnResize);\n\n // Both of these checkPosition() calls are necessary for the case where\n // the user hits refresh after scrolling to the bottom of the page.\n this.checkPosition();\n this.checkPositionWithEventLoop();\n\n };\n\n $affix.destroy = function() {\n\n // Unbind events\n targetEl.off('scroll', this.checkPosition);\n targetEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', this.$debouncedOnResize);\n\n };\n\n $affix.checkPositionWithEventLoop = function() {\n\n // IE 9 throws an error if we use 'this' instead of '$affix'\n // in this setTimeout call\n setTimeout($affix.checkPosition, 1);\n\n };\n\n $affix.checkPosition = function() {\n // if (!this.$element.is(':visible')) return\n\n var scrollTop = getScrollTop();\n var position = dimensions.offset(element[0]);\n var elementHeight = dimensions.height(element[0]);\n\n // Get required affix class according to position\n var affix = getRequiredAffixClass(unpin, position, elementHeight);\n\n // Did affix status changed this last check?\n if(affixed === affix) return;\n affixed = affix;\n\n // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + affix : ''));\n\n if(affix === 'top') {\n unpin = null;\n if(setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', '');\n }\n } else if(affix === 'bottom') {\n if (options.offsetUnpin) {\n unpin = -(options.offsetUnpin * 1);\n }\n else {\n // Calculate unpin threshold when affixed to bottom.\n // Hopefully the browser scrolls pixel by pixel.\n unpin = position.top - scrollTop;\n }\n if(setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', (options.offsetParent) ? '' : ((bodyEl[0].offsetHeight - offsetBottom - elementHeight - initialOffsetTop) + 'px'));\n }\n } else { // affix === 'middle'\n unpin = null;\n if(setWidth) {\n element.css('width', element[0].offsetWidth + 'px');\n }\n if (options.inlineStyles) {\n element.css('position', 'fixed');\n element.css('top', initialAffixTop + 'px');\n }\n }\n\n };\n\n $affix.$onResize = function() {\n $affix.$parseOffsets();\n $affix.checkPosition();\n };\n $affix.$debouncedOnResize = debounce($affix.$onResize, 50);\n\n $affix.$parseOffsets = function() {\n var initialPosition = element.css('position');\n // Reset position to calculate correct offsetTop\n if (options.inlineStyles){\n element.css('position', (options.offsetParent) ? '' : 'relative');\n }\n\n if(options.offsetTop) {\n if(options.offsetTop === 'auto') {\n options.offsetTop = '+0';\n }\n if(options.offsetTop.match(/^[-+]\\d+$/)) {\n initialAffixTop = - options.offsetTop * 1;\n if(options.offsetParent) {\n offsetTop = dimensions.offset(parent[0]).top + (options.offsetTop * 1);\n }\n else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\n }\n }\n else {\n offsetTop = options.offsetTop * 1;\n }\n }\n\n if(options.offsetBottom) {\n if(options.offsetParent && options.offsetBottom.match(/^[-+]\\d+$/)) {\n // add 1 pixel due to rounding problems...\n offsetBottom = getScrollHeight() - (dimensions.offset(parent[0]).top + dimensions.height(parent[0])) + (options.offsetBottom * 1) + 1;\n }\n else {\n offsetBottom = options.offsetBottom * 1;\n }\n }\n\n // Bring back the element's position after calculations\n if (options.inlineStyles){\n element.css('position', initialPosition);\n }\n };\n\n // Private methods\n\n function getRequiredAffixClass(unpin, position, elementHeight) {\n\n var scrollTop = getScrollTop();\n var scrollHeight = getScrollHeight();\n\n if(scrollTop <= offsetTop) {\n return 'top';\n } else if(unpin !== null && (scrollTop + unpin <= position.top)) {\n return 'middle';\n } else if(offsetBottom !== null && (position.top + elementHeight + initialAffixTop >= scrollHeight - offsetBottom)) {\n return 'bottom';\n } else {\n return 'middle';\n }\n\n }\n\n function getScrollTop() {\n return targetEl[0] === $window ? $window.pageYOffset : targetEl[0].scrollTop;\n }\n\n function getScrollHeight() {\n return targetEl[0] === $window ? $window.document.body.scrollHeight : targetEl[0].scrollHeight;\n }\n\n $affix.init();\n return $affix;\n\n }\n\n return AffixFactory;\n\n };\n\n })\n\n .directive('bsAffix', function($affix, $window) {\n\n return {\n restrict: 'EAC',\n require: '^?bsAffixTarget',\n link: function postLink(scope, element, attr, affixTarget) {\n\n var options = {scope: scope, target: affixTarget ? affixTarget.$element : angular.element($window)};\n angular.forEach(['offsetTop', 'offsetBottom', 'offsetParent', 'offsetUnpin', 'inlineStyles'], function(key) {\n if(angular.isDefined(attr[key])) {\n var option = attr[key];\n if (/true/i.test(option)) option = true;\n if (/false/i.test(option)) option = false;\n options[key] = option;\n }\n });\n\n var affix = $affix(element, options);\n scope.$on('$destroy', function() {\n affix && affix.destroy();\n options = null;\n affix = null;\n });\n\n }\n };\n\n })\n\n .directive('bsAffixTarget', function() {\n return {\n controller: function($element) {\n this.$element = $element;\n }\n };\n });\n","'use strict';\n\n// @BUG: following snippet won't compile correctly\n// @TODO: submit issue to core\n// ' ' +\n\nangular.module('mgcrea.ngStrap.alert', ['mgcrea.ngStrap.modal'])\n\n .provider('$alert', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'alert',\n prefixEvent: 'alert',\n placement: null,\n templateUrl: 'alert/alert.tpl.html',\n container: false,\n element: null,\n backdrop: false,\n keyboard: true,\n show: true,\n // Specific options\n duration: false,\n type: false,\n dismissable: true\n };\n\n this.$get = function($modal, $timeout) {\n\n function AlertFactory(config) {\n\n var $alert = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $alert = $modal(options);\n\n // Support scope as string options [/*title, content, */ type, dismissable]\n $alert.$scope.dismissable = !!options.dismissable;\n if(options.type) {\n $alert.$scope.type = options.type;\n }\n\n // Support auto-close duration\n var show = $alert.show;\n if(options.duration) {\n $alert.show = function() {\n show();\n $timeout(function() {\n $alert.hide();\n }, options.duration * 1000);\n };\n }\n\n return $alert;\n\n }\n\n return AlertFactory;\n\n };\n\n })\n\n .directive('bsAlert', function($window, $sce, $alert) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['keyboard', 'html', 'container', 'dismissable'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content', 'type'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAlert && scope.$watch(attr.bsAlert, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize alert\n var alert = $alert(options);\n\n // Trigger\n element.on(attr.trigger || 'click', alert.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (alert) alert.destroy();\n options = null;\n alert = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($modal) {\n\n function AsideFactory(config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function($window, $sce, $aside) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsAside && scope.$watch(attr.bsAside, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize aside\n var aside = $aside(options);\n\n // Trigger\n element.on(attr.trigger || 'click', aside.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (aside) aside.destroy();\n options = null;\n aside = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.button', [])\n\n .provider('$button', function() {\n\n var defaults = this.defaults = {\n activeClass:'active',\n toggleEvent:'click'\n };\n\n this.$get = function() {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsCheckboxGroup', function() {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"checkbox\"]');\n angular.forEach(children, function(child) {\n var childEl = angular.element(child);\n childEl.attr('bs-checkbox', '');\n childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value'));\n });\n }\n\n };\n\n })\n\n .directive('bsCheckbox', function($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support label > input[type=\"checkbox\"]\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true;\n if(constantValueRegExp.test(attr.trueValue)) {\n trueValue = scope.$eval(attr.trueValue);\n }\n var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false;\n if(constantValueRegExp.test(attr.falseValue)) {\n falseValue = scope.$eval(attr.falseValue);\n }\n\n // Parse exotic values\n var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean';\n if(hasExoticValues) {\n controller.$parsers.push(function(viewValue) {\n // console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue);\n return viewValue ? trueValue : falseValue;\n });\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n return angular.equals(modelValue, trueValue);\n });\n // Fix rendering for exotic values\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n controller.$render();\n });\n }\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, trueValue);\n $$rAF(function() {\n if(isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function() {\n scope.$apply(function () {\n // console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n if(!isInput) {\n controller.$setViewValue(!activeElement.hasClass('active'));\n }\n if(!hasExoticValues) {\n controller.$render();\n }\n });\n });\n\n }\n\n };\n\n })\n\n .directive('bsRadioGroup', function() {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink(element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"radio\"]');\n angular.forEach(children, function(child) {\n angular.element(child).attr('bs-radio', '');\n angular.element(child).attr('ng-model', attr.ngModel);\n });\n }\n\n };\n\n })\n\n .directive('bsRadio', function($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support `label > input[type=\"radio\"]` markup\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var value;\n attr.$observe('value', function(v) {\n value = constantValueRegExp.test(v) ? scope.$eval(v) : v;\n controller.$render();\n });\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, value);\n $$rAF(function() {\n if(isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function() {\n scope.$apply(function () {\n // console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n controller.$setViewValue(value);\n controller.$render();\n });\n });\n\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.collapse', [])\n\n .provider('$collapse', function() {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['disallowToggle', 'startCollapsed', 'allowMultiple'], function(key) {\n if(angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) {\n self.$options[key] = false;\n }\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function(element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function(element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function(element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function(element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function(value) {\n if(angular.isArray(value)) {\n self.$targets.$active = value;\n }\n else if(!self.$options.disallowToggle) {\n // toogle element active status\n isActive(value) ? deactivateItem(value) : activateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function() {\n return self.$options.allowMultiple ? self.$targets.$active :\n self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1;\n };\n\n function fixActiveItemIndexes(index) {\n // item with index was removed, so we\n // need to adjust other items index values\n var activeIndexes = self.$targets.$active;\n for(var i = 0; i < activeIndexes.length; i++) {\n if (index < activeIndexes[i]) {\n activeIndexes[i] = activeIndexes[i] - 1;\n }\n\n // the last item is active, so we need to\n // adjust its index\n if (activeIndexes[i] === self.$targets.length) {\n activeIndexes[i] = self.$targets.length - 1;\n }\n }\n }\n\n function isActive(value) {\n var activeItems = self.$targets.$active;\n return activeItems.indexOf(value) === -1 ? false : true;\n }\n\n function deactivateItem(value) {\n var index = self.$targets.$active.indexOf(value);\n if (index !== -1) {\n self.$targets.$active.splice(index, 1);\n }\n }\n\n function activateItem(value) {\n if (!self.$options.allowMultiple) {\n // remove current selected item\n self.$targets.$active.splice(0, 1);\n }\n\n if (self.$targets.$active.indexOf(value) === -1) {\n self.$targets.$active.push(value);\n }\n }\n\n };\n\n this.$get = function() {\n var $collapse = {};\n $collapse.defaults = defaults;\n $collapse.controller = controller;\n return $collapse;\n };\n\n })\n\n .directive('bsCollapse', function($window, $animate, $collapse) {\n\n var defaults = $collapse.defaults;\n\n return {\n require: ['?ngModel', 'bsCollapse'],\n controller: ['$scope', '$element', '$attrs', $collapse.controller],\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n if(ngModelCtrl) {\n\n // Update the modelValue following\n bsCollapseCtrl.$viewChangeListeners.push(function() {\n ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes());\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n if (angular.isArray(modelValue)) {\n // model value is an array, so just replace\n // the active items directly\n bsCollapseCtrl.$setActive(modelValue);\n }\n else {\n var activeIndexes = bsCollapseCtrl.$activeIndexes();\n\n if (angular.isArray(activeIndexes)) {\n // we have an array of selected indexes\n if (activeIndexes.indexOf(modelValue * 1) === -1) {\n // item with modelValue index is not active\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n else if (activeIndexes !== modelValue * 1) {\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n return modelValue;\n });\n\n }\n\n }\n };\n\n })\n\n .directive('bsCollapseToggle', function() {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base attr\n element.attr('data-toggle', 'collapse');\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerToggle(element);\n\n // remove toggle from collapse controller when toggle is destroyed\n scope.$on('$destroy', function() {\n bsCollapseCtrl.$unregisterToggle(element);\n });\n\n element.on('click', function() {\n var index = attrs.bsCollapseToggle && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n });\n\n }\n };\n\n })\n\n .directive('bsCollapseTarget', function($animate) {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n // scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base class\n element.addClass('collapse');\n\n // Add animation class\n if(bsCollapseCtrl.$options.animation) {\n element.addClass(bsCollapseCtrl.$options.animation);\n }\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerTarget(element);\n\n // remove pane target from collapse controller when target is destroyed\n scope.$on('$destroy', function() {\n bsCollapseCtrl.$unregisterTarget(element);\n });\n\n function render() {\n var index = bsCollapseCtrl.$targets.indexOf(element);\n var active = bsCollapseCtrl.$activeIndexes();\n var action = 'removeClass';\n if (angular.isArray(active)) {\n if (active.indexOf(index) !== -1) {\n action = 'addClass';\n }\n }\n else if (index === active) {\n action = 'addClass';\n }\n\n $animate[action](element, bsCollapseCtrl.$options.activeClass);\n }\n\n bsCollapseCtrl.$viewChangeListeners.push(function() {\n render();\n });\n render();\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if(!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();\n\n function DatepickerFactory(element, controller, config) {\n\n var $datepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $datepicker.$options;\n var scope = $datepicker.$scope;\n if(options.startView) options.startView -= options.minView;\n\n // View vars\n\n var pickerViews = datepickerViews($datepicker);\n $datepicker.$views = pickerViews.views;\n var viewDate = pickerViews.viewDate;\n scope.$mode = options.startView;\n scope.$iconLeft = options.iconLeft;\n scope.$iconRight = options.iconRight;\n var $picker = $datepicker.$views[scope.$mode];\n\n // Scope methods\n\n scope.$select = function(date) {\n $datepicker.select(date);\n };\n scope.$selectPane = function(value) {\n $datepicker.$selectPane(value);\n };\n scope.$toggleMode = function() {\n $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);\n };\n\n // Public methods\n\n $datepicker.update = function(date) {\n // console.warn('$datepicker.update() newValue=%o', date);\n if(angular.isDate(date) && !isNaN(date.getTime())) {\n $datepicker.$date = date;\n $picker.update.call($picker, date);\n }\n // Build only if pristine\n $datepicker.$build(true);\n };\n\n $datepicker.updateDisabledDates = function(dateRanges) {\n options.disabledDateRanges = dateRanges;\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);\n }\n };\n\n $datepicker.select = function(date, keep) {\n // console.warn('$datepicker.select', date, scope.$mode);\n if(!angular.isDate(controller.$dateValue)) controller.$dateValue = new Date(date);\n if(!scope.$mode || keep) {\n controller.$setViewValue(angular.copy(date));\n controller.$render();\n if(options.autoclose && !keep) {\n $timeout(function() { $datepicker.hide(true); });\n }\n } else {\n angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});\n $datepicker.setMode(scope.$mode - 1);\n $datepicker.$build();\n }\n };\n\n $datepicker.setMode = function(mode) {\n // console.warn('$datepicker.setMode', mode);\n scope.$mode = mode;\n $picker = $datepicker.$views[scope.$mode];\n $datepicker.$build();\n };\n\n // Protected methods\n\n $datepicker.$build = function(pristine) {\n // console.warn('$datepicker.$build() viewDate=%o', viewDate);\n if(pristine === true && $picker.built) return;\n if(pristine === false && !$picker.built) return;\n $picker.build.call($picker);\n };\n\n $datepicker.$updateSelected = function() {\n for(var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], updateSelected);\n }\n };\n\n $datepicker.$isSelected = function(date) {\n return $picker.isSelected(date);\n };\n\n $datepicker.$setDisabledEl = function(el) {\n el.disabled = $picker.isDisabled(el.date);\n };\n\n $datepicker.$selectPane = function(value) {\n var steps = $picker.steps;\n // set targetDate to first day of month to avoid problems with\n // date values rollover. This assumes the viewDate does not\n // depend on the day of the month\n var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));\n angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});\n $datepicker.$build();\n };\n\n $datepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n if(targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $datepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n if(evt.keyCode === 13) {\n if(!scope.$mode) {\n return $datepicker.hide(true);\n } else {\n return scope.$apply(function() { $datepicker.setMode(scope.$mode - 1); });\n }\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected(el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function() {\n if(isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if(isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function() {\n if(isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // if $datepicker is no longer showing, don't setup events\n if(!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function(blur) {\n if(!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n var defaults = $datepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!datepicker || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);\n newValue === true ? datepicker.show() : datepicker.hide();\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if(isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n // console.warn('attr.$observe(%s)=%o', key, newValue);\n datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);\n // Build only if dirty\n !isNaN(datepicker.$options[key]) && datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges(ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function(disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate(parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if(isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if(!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if(!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n } else {\n validateAgainstMinMaxDate(parsedDate);\n }\n\n if(options.dateType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true);\n return formatDate(date, options.modelDateFormat || options.dateFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if(options.dateType === 'number') {\n return date.getTime();\n } else if(options.dateType === 'unix') {\n return date.getTime() / 1000;\n } else if(options.dateType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if(angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if(angular.isDate(modelValue)) {\n date = modelValue;\n } else if(options.dateType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelDateFormat);\n } else if(options.dateType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) {\n // var today = new Date();\n // date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);\n // }\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getDateFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getDateFormattedString());\n };\n\n function getDateFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(datepicker) datepicker.destroy();\n options = null;\n datepicker = null;\n });\n\n }\n };\n\n })\n\n .provider('datepickerViews', function() {\n\n var defaults = this.defaults = {\n dayFormat: 'dd',\n daySplit: 7\n };\n\n // Split array into smaller arrays\n function split(arr, size) {\n var arrays = [];\n while(arr.length > 0) {\n arrays.push(arr.splice(0, size));\n }\n return arrays;\n }\n\n // Modulus operator\n function mod(n, m) {\n return ((n % m) + m) % m;\n }\n\n this.$get = function($dateFormatter, $dateParser, $sce) {\n\n return function(picker) {\n\n var scope = picker.$scope;\n var options = picker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n var weekDaysMin = $dateFormatter.weekdaysShort(lang);\n var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));\n var weekDaysLabelsHtml = $sce.trustAsHtml('' + weekDaysLabels.join('') + '');\n\n var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date());\n var viewDate = {year: startDate.getFullYear(), month: startDate.getMonth(), date: startDate.getDate()};\n\n var views = [{\n format: options.dayFormat,\n split: 7,\n steps: { month: 1 },\n update: function(date, force) {\n if(!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getDate() !== viewDate.date || date.getDate() === 1) {\n // chaging picker current month will cause viewDate.date to be set to first day of the month,\n // in $datepicker.$selectPane, so picker would not update selected day display if\n // user picks first day of the new month.\n // As a workaround, we are always forcing update when picked date is first day of month.\n viewDate.date = picker.$date.getDate();\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1), firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5), firstDateOffset = firstDate.getTimezoneOffset();\n var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString();\n // Handle daylight time switch\n if(firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 60e3);\n var days = [], day;\n for(var i = 0; i < 42; i++) { // < 7 * 6\n day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i));\n days.push({date: day, isToday: day.toDateString() === today, label: formatDate(day, this.format), selected: picker.$date && this.isSelected(day), muted: day.getMonth() !== viewDate.month, disabled: this.isDisabled(day)});\n }\n scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat);\n scope.showLabels = true;\n scope.labels = weekDaysLabelsHtml;\n scope.rows = split(days, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate();\n },\n isDisabled: function(date) {\n var time = date.getTime();\n\n // Disabled because of min/max date.\n if (time < options.minDate || time > options.maxDate) return true;\n\n // Disabled due to being a disabled day of the week\n if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true;\n\n // Disabled because of disabled date range.\n if (options.disabledDateRanges) {\n for (var i = 0; i < options.disabledDateRanges.length; i++) {\n if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) {\n return true;\n }\n }\n }\n\n return false;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualTime = picker.$date.getTime();\n var newDate;\n\n if(evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5);\n else if(evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5);\n else if(evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5);\n else if(evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'month',\n format: options.monthFormat,\n split: 4,\n steps: { year: 1 },\n update: function(date, force) {\n if(!this.built || date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstMonth = new Date(viewDate.year, 0, 1);\n var months = [], month;\n for (var i = 0; i < 12; i++) {\n month = new Date(viewDate.year, i, 1);\n months.push({date: month, label: formatDate(month, this.format), selected: picker.$isSelected(month), disabled: this.isDisabled(month)});\n }\n scope.title = formatDate(month, options.yearTitleFormat);\n scope.showLabels = false;\n scope.rows = split(months, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth();\n },\n isDisabled: function(date) {\n var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualMonth = picker.$date.getMonth();\n var newDate = new Date(picker.$date);\n\n if(evt.keyCode === 37) newDate.setMonth(actualMonth - 1);\n else if(evt.keyCode === 38) newDate.setMonth(actualMonth - 4);\n else if(evt.keyCode === 39) newDate.setMonth(actualMonth + 1);\n else if(evt.keyCode === 40) newDate.setMonth(actualMonth + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'year',\n format: options.yearFormat,\n split: 4,\n steps: { year: 12 },\n update: function(date, force) {\n if(!this.built || force || parseInt(date.getFullYear()/20, 10) !== parseInt(viewDate.year/20, 10)) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if(date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function() {\n var firstYear = viewDate.year - viewDate.year % (this.split * 3);\n var years = [], year;\n for (var i = 0; i < 12; i++) {\n year = new Date(firstYear + i, 0, 1);\n years.push({date: year, label: formatDate(year, this.format), selected: picker.$isSelected(year), disabled: this.isDisabled(year)});\n }\n scope.title = years[0].label + '-' + years[years.length - 1].label;\n scope.showLabels = false;\n scope.rows = split(years, this.split);\n this.built = true;\n },\n isSelected: function(date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear();\n },\n isDisabled: function(date) {\n var lastDate = +new Date(date.getFullYear() + 1, 0, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function(evt) {\n if (!picker.$date) {\n return;\n }\n var actualYear = picker.$date.getFullYear(),\n newDate = new Date(picker.$date);\n\n if(evt.keyCode === 37) newDate.setYear(actualYear - 1);\n else if(evt.keyCode === 38) newDate.setYear(actualYear - 4);\n else if(evt.keyCode === 39) newDate.setYear(actualYear + 1);\n else if(evt.keyCode === 40) newDate.setYear(actualYear + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }];\n\n return {\n views: options.minView ? Array.prototype.slice.call(views, options.minView) : views,\n viewDate: viewDate\n };\n\n };\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory(element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var scope = $dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function(evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if(!items.length) return;\n var index;\n angular.forEach(items, function(el, i) {\n if(matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if(evt.keyCode === 38 && index > 0) index--;\n else if(evt.keyCode === 40 && index < items.length - 1) index++;\n else if(angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n options.keyboard && $dropdown.$element && $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n parentEl.hasClass('dropdown') && parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function() {\n if(!$dropdown.$isShown) return;\n options.keyboard && $dropdown.$element && $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n parentEl.hasClass('dropdown') && parentEl.removeClass('open');\n hide();\n };\n\n var destroy = $dropdown.destroy;\n $dropdown.destroy = function() {\n bodyEl.off('click', onBodyClick);\n destroy();\n };\n\n // Private functions\n\n function onBodyClick(evt) {\n if(evt.target === element[0]) return;\n return evt.target !== element[0] && $dropdown.hide();\n }\n\n return $dropdown;\n\n }\n\n return DropdownFactory;\n\n };\n\n })\n\n .directive('bsDropdown', function($window, $sce, $dropdown) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as an object\n attr.bsDropdown && scope.$watch(attr.bsDropdown, function(newValue, oldValue) {\n scope.content = newValue;\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!dropdown || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);\n newValue === true ? dropdown.show() : dropdown.hide();\n });\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (dropdown) dropdown.destroy();\n options = null;\n dropdown = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dateParser', [])\n\n.provider('$dateParser', function($localeProvider) {\n\n // define a custom ParseDate object to use instead of native Date\n // to avoid date values wrapping when setting date component values\n function ParseDate() {\n this.year = 1970;\n this.month = 0;\n this.day = 1;\n this.hours = 0;\n this.minutes = 0;\n this.seconds = 0;\n this.milliseconds = 0;\n }\n\n ParseDate.prototype.setMilliseconds = function(value) { this.milliseconds = value; };\n ParseDate.prototype.setSeconds = function(value) { this.seconds = value; };\n ParseDate.prototype.setMinutes = function(value) { this.minutes = value; };\n ParseDate.prototype.setHours = function(value) { this.hours = value; };\n ParseDate.prototype.getHours = function() { return this.hours; };\n ParseDate.prototype.setDate = function(value) { this.day = value; };\n ParseDate.prototype.setMonth = function(value) { this.month = value; };\n ParseDate.prototype.setFullYear = function(value) { this.year = value; };\n ParseDate.prototype.fromDate = function(value) {\n this.year = value.getFullYear();\n this.month = value.getMonth();\n this.day = value.getDate();\n this.hours = value.getHours();\n this.minutes = value.getMinutes();\n this.seconds = value.getSeconds();\n this.milliseconds = value.getMilliseconds();\n return this;\n };\n\n ParseDate.prototype.toDate = function() {\n return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);\n };\n\n var proto = ParseDate.prototype;\n\n function noop() {\n }\n\n function isNumeric(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n function indexOfCaseInsensitive(array, value) {\n var len = array.length, str=value.toString().toLowerCase();\n for (var i=0; i 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function(date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n /* Correct the date for timezone offset.\n * @param date (Date) the date to adjust\n * @param timezone (string) the timezone to adjust for\n * @param undo (boolean) to add or subtract timezone offset\n * @return (Date) the corrected date\n */\n $dateParser.timezoneOffsetAdjust = function(date, timezone, undo) {\n if (!date) {\n return null;\n }\n // Right now, only 'UTC' is supported.\n if (timezone && timezone === 'UTC') {\n date = new Date(date.getTime());\n date.setMinutes(date.getMinutes() + (undo?-1:1)*date.getTimezoneOffset());\n }\n return date;\n };\n\n // Private functions\n\n function setMapForFormat(format) {\n var keys = Object.keys(setFnMap), i;\n var map = [], sortedMap = [];\n // Map to setFn\n var clonedFormat = format;\n for(i = 0; i < keys.length; i++) {\n if(format.split(keys[i]).length > 1) {\n var index = clonedFormat.search(keys[i]);\n format = format.split(keys[i]).join('');\n if(setFnMap[keys[i]]) {\n map[index] = setFnMap[keys[i]];\n }\n }\n }\n // Sort result map\n angular.forEach(map, function(v) {\n // conditional required since angular.forEach broke around v1.2.21\n // related pr: https://github.com/angular/angular.js/pull/8525\n if(v) sortedMap.push(v);\n });\n return sortedMap;\n }\n\n function escapeReservedSymbols(text) {\n return text.replace(/\\//g, '[\\\\/]').replace('/-/g', '[-]').replace(/\\./g, '[.]').replace(/\\\\s/g, '[\\\\s]');\n }\n\n function regExpForFormat(format) {\n var keys = Object.keys(regExpMap), i;\n\n var re = format;\n // Abstract replaces to avoid collisions\n for(i = 0; i < keys.length; i++) {\n re = re.split(keys[i]).join('${' + i + '}');\n }\n // Replace abstracted values\n for(i = 0; i < keys.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');\n }\n format = escapeReservedSymbols(format);\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.debounce', [])\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L693\n.factory('debounce', function($timeout) {\n return function(func, wait, immediate) {\n var timeout = null;\n return function() {\n var context = this,\n args = arguments,\n callNow = immediate && !timeout;\n if(timeout) {\n $timeout.cancel(timeout);\n }\n timeout = $timeout(function later() {\n timeout = null;\n if(!immediate) {\n func.apply(context, args);\n }\n }, wait, false);\n if(callNow) {\n func.apply(context, args);\n }\n return timeout;\n };\n };\n})\n\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L661\n.factory('throttle', function($timeout) {\n return function(func, wait, options) {\n var timeout = null;\n options || (options = {});\n return function() {\n var context = this,\n args = arguments;\n if(!timeout) {\n if(options.leading !== false) {\n func.apply(context, args);\n }\n timeout = $timeout(function later() {\n timeout = null;\n if(options.trailing !== false) {\n func.apply(context, args);\n }\n }, wait, false);\n }\n };\n };\n});\n\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dimensions', [])\n\n .factory('dimensions', function($document, $window) {\n\n var jqLite = angular.element;\n var fn = {};\n\n /**\n * Test the element nodeName\n * @param element\n * @param name\n */\n var nodeName = fn.nodeName = function(element, name) {\n return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase();\n };\n\n /**\n * Returns the element computed style\n * @param element\n * @param prop\n * @param extra\n */\n fn.css = function(element, prop, extra) {\n var value;\n if (element.currentStyle) { //IE\n value = element.currentStyle[prop];\n } else if (window.getComputedStyle) {\n value = window.getComputedStyle(element)[prop];\n } else {\n value = element.style[prop];\n }\n return extra === true ? parseFloat(value) || 0 : value;\n };\n\n /**\n * Provides read-only equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.offset = function(element) {\n var boxRect = element.getBoundingClientRect();\n var docElement = element.ownerDocument;\n return {\n width: boxRect.width || element.offsetWidth,\n height: boxRect.height || element.offsetHeight,\n top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0),\n left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0)\n };\n };\n \n /**\n * Provides set equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip\n * @url http://api.jquery.com/offset/\n * @param element\n * @param options\n * @param i\n */\n fn.setOffset = function (element, options, i) {\n var curPosition,\n curLeft,\n curCSSTop,\n curTop,\n curOffset,\n curCSSLeft,\n calculatePosition,\n position = fn.css(element, 'position'),\n curElem = angular.element(element),\n props = {};\n \n // Set position first, in-case top/left are set even on static elem\n if (position === 'static') {\n element.style.position = 'relative';\n }\n \n curOffset = fn.offset(element);\n curCSSTop = fn.css(element, 'top');\n curCSSLeft = fn.css(element, 'left');\n calculatePosition = (position === 'absolute' || position === 'fixed') && \n (curCSSTop + curCSSLeft).indexOf('auto') > -1;\n \n // Need to be able to calculate position if either\n // top or left is auto and position is either absolute or fixed\n if (calculatePosition) {\n curPosition = fn.position(element);\n curTop = curPosition.top;\n curLeft = curPosition.left;\n } else {\n curTop = parseFloat(curCSSTop) || 0;\n curLeft = parseFloat(curCSSLeft) || 0;\n }\n \n if (angular.isFunction(options)) {\n options = options.call(element, i, curOffset);\n }\n \n if (options.top !== null ) {\n props.top = (options.top - curOffset.top) + curTop;\n }\n if ( options.left !== null ) {\n props.left = (options.left - curOffset.left) + curLeft;\n }\n\n if ('using' in options) {\n options.using.call(curElem, props);\n } else {\n curElem.css({\n top: props.top + 'px',\n left: props.left + 'px'\n });\n }\n };\n\n /**\n * Provides read-only equivalent of jQuery's position function\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.position = function(element) {\n\n var offsetParentRect = {top: 0, left: 0},\n offsetParentElement,\n offset;\n\n // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent\n if (fn.css(element, 'position') === 'fixed') {\n\n // We assume that getBoundingClientRect is available when computed position is fixed\n offset = element.getBoundingClientRect();\n\n } else {\n\n // Get *real* offsetParentElement\n offsetParentElement = offsetParent(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentElement, 'html')) {\n offsetParentRect = fn.offset(offsetParentElement);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentElement, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentElement, 'borderLeftWidth', true);\n }\n\n // Subtract parent offsets and element margins\n return {\n width: element.offsetWidth,\n height: element.offsetHeight,\n top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true),\n left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true)\n };\n\n };\n\n /**\n * Returns the closest, non-statically positioned offsetParent of a given element\n * @required-by fn.position\n * @param element\n */\n var offsetParent = function offsetParentElement(element) {\n var docElement = element.ownerDocument;\n var offsetParent = element.offsetParent || docElement;\n if(nodeName(offsetParent, '#document')) return docElement.documentElement;\n while(offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') {\n offsetParent = offsetParent.offsetParent;\n }\n return offsetParent || docElement.documentElement;\n };\n\n /**\n * Provides equivalent of jQuery's height function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/height/\n * @param element\n * @param outer\n */\n fn.height = function(element, outer) {\n var value = element.offsetHeight;\n if(outer) {\n value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true);\n } else {\n value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true);\n }\n return value;\n };\n\n /**\n * Provides equivalent of jQuery's width function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/width/\n * @param element\n * @param outer\n */\n fn.width = function(element, outer) {\n var value = element.offsetWidth;\n if(outer) {\n value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true);\n } else {\n value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true);\n }\n return value;\n };\n\n return fn;\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.parseOptions', [])\n\n .provider('$parseOptions', function() {\n\n var defaults = this.defaults = {\n regexp: /^\\s*(.*?)(?:\\s+as\\s+(.*?))?(?:\\s+group\\s+by\\s+(.*))?\\s+for\\s+(?:([\\$\\w][\\$\\w]*)|(?:\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)))\\s+in\\s+(.*?)(?:\\s+track\\s+by\\s+(.*?))?$/\n };\n\n this.$get = function($parse, $q) {\n\n function ParseOptionsFactory(attr, config) {\n\n var $parseOptions = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n $parseOptions.$values = [];\n\n // Private vars\n var match, displayFn, valueName, keyName, groupByFn, valueFn, valuesFn;\n\n $parseOptions.init = function() {\n $parseOptions.$match = match = attr.match(options.regexp);\n displayFn = $parse(match[2] || match[1]),\n valueName = match[4] || match[6],\n keyName = match[5],\n groupByFn = $parse(match[3] || ''),\n valueFn = $parse(match[2] ? match[1] : valueName),\n valuesFn = $parse(match[7]);\n };\n\n $parseOptions.valuesFn = function(scope, controller) {\n return $q.when(valuesFn(scope, controller))\n .then(function(values) {\n if(!angular.isArray(values)) {\n values = [];\n }\n $parseOptions.$values = values.length ? parseValues(values, scope) : [];\n return $parseOptions.$values;\n });\n };\n\n $parseOptions.displayValue = function(modelValue) {\n var scope = {};\n scope[valueName] = modelValue;\n return displayFn(scope);\n };\n\n // Private functions\n\n function parseValues(values, scope) {\n return values.map(function(match, index) {\n var locals = {}, label, value;\n locals[valueName] = match;\n label = displayFn(scope, locals);\n value = valueFn(scope, locals);\n return {label: label, value: value, index: index};\n });\n }\n\n $parseOptions.init();\n return $parseOptions;\n\n }\n\n return ParseOptionsFactory;\n\n };\n\n });\n","'use strict';\n\n(angular.version.minor < 3 && angular.version.dot < 14) && angular.module('ng')\n\n.factory('$$rAF', function($window, $timeout) {\n\n var requestAnimationFrame = $window.requestAnimationFrame ||\n $window.webkitRequestAnimationFrame ||\n $window.mozRequestAnimationFrame;\n\n var cancelAnimationFrame = $window.cancelAnimationFrame ||\n $window.webkitCancelAnimationFrame ||\n $window.mozCancelAnimationFrame ||\n $window.webkitCancelRequestAnimationFrame;\n\n var rafSupported = !!requestAnimationFrame;\n var raf = rafSupported ?\n function(fn) {\n var id = requestAnimationFrame(fn);\n return function() {\n cancelAnimationFrame(id);\n };\n } :\n function(fn) {\n var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666\n return function() {\n $timeout.cancel(timer);\n };\n };\n\n raf.supported = rafSupported;\n\n return raf;\n\n});\n\n// .factory('$$animateReflow', function($$rAF, $document) {\n\n// var bodyEl = $document[0].body;\n\n// return function(fn) {\n// //the returned function acts as the cancellation function\n// return $$rAF(function() {\n// //the line below will force the browser to perform a repaint\n// //so that all the animated elements within the animation frame\n// //will be properly updated and drawn on screen. This is\n// //required to perform multi-class CSS based animations with\n// //Firefox. DO NOT REMOVE THIS LINE.\n// var a = bodyEl.offsetWidth + 1;\n// fn();\n// });\n// };\n\n// });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var trim = String.prototype.trim;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n\n function ModalFactory(config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if(!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function(key) {\n if(options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $modal.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $modal.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData, modalElement, modalScope;\n var backdropElement = angular.element('
');\n backdropElement.css({position:'fixed', top:'0px', left:'0px', bottom:'0px', right:'0px', 'z-index': 1038});\n promise.then(function(data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function() {\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function() {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if(backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function() {\n if($modal.$isShown) return;\n\n var parent, after;\n if(angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if(modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {});\n\n if(scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) {\n return;\n }\n\n // Set the initial positioning.\n modalElement.css({display: 'block'}).addClass(options.placement);\n\n // Options: animation\n if(options.animation) {\n if(options.backdrop) {\n backdropElement.addClass(options.backdropAnimation);\n }\n modalElement.addClass(options.animation);\n }\n\n if(options.backdrop) {\n $animate.enter(backdropElement, bodyElement, null);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(modalElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(modalElement, parent, after).then(enterAnimateCallback);\n }\n\n $modal.$isShown = scope.$isShown = true;\n safeDigest(scope);\n // Focus once the enter-animation has started\n // Weird PhantomJS bug hack\n var el = modalElement[0];\n requestAnimationFrame(function() {\n el.focus();\n });\n\n bodyElement.addClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.addClass(options.prefixClass + '-with-' + options.animation);\n }\n\n // Bind events\n bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $modal);\n }\n\n $modal.hide = function() {\n if(!$modal.$isShown) return;\n\n if(scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if(options.backdrop) {\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n bodyElement.removeClass(options.prefixClass + '-open');\n if(options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function() {\n\n $modal.$isShown ? $modal.hide() : $modal.show();\n\n };\n\n $modal.focus = function() {\n modalElement[0].focus();\n };\n\n // Protected methods\n\n $modal.$onKeyUp = function(evt) {\n\n if (evt.which === 27 && $modal.$isShown) {\n $modal.hide();\n evt.stopPropagation();\n }\n\n };\n\n function bindBackdropEvents() {\n if(options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents() {\n if(options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private methods\n\n function hideOnBackdropClick(evt) {\n if(evt.target !== evt.currentTarget) return;\n options.backdrop === 'static' ? $modal.focus() : $modal.hide();\n }\n\n function preventEventDefault(evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement() {\n if($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if(modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if(modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function($window, $sce, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'controller', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'id', 'prefixEvent', 'prefixClass'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n });\n\n // Support scope as an object\n attr.bsModal && scope.$watch(attr.bsModal, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n\n // Initialize modal\n var modal = $modal(options);\n\n // Trigger\n element.on(attr.trigger || 'click', modal.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (modal) modal.destroy();\n options = null;\n modal = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.navbar', [])\n\n .provider('$navbar', function() {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n routeAttr: 'data-match-route',\n strict: false\n };\n\n this.$get = function() {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsNavbar', function($window, $location, $navbar) {\n\n var defaults = $navbar.defaults;\n\n return {\n restrict: 'A',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = angular.copy(defaults);\n angular.forEach(Object.keys(defaults), function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Watch for the $location\n scope.$watch(function() {\n\n return $location.path();\n\n }, function(newValue, oldValue) {\n\n var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']');\n\n angular.forEach(liElements, function(li) {\n\n var liElement = angular.element(li);\n var pattern = liElement.attr(options.routeAttr).replace('/', '\\\\/');\n if(options.strict) {\n pattern = '^' + pattern + '$';\n }\n var regexp = new RegExp(pattern, 'i');\n\n if(regexp.test(newValue)) {\n liElement.addClass(options.activeClass);\n } else {\n liElement.removeClass(options.activeClass);\n }\n\n });\n\n });\n\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function($tooltip) {\n\n function PopoverFactory(element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if(options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function(key) {\n attr[key] && attr.$observe(key, function(newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n });\n });\n\n // Support scope as an object\n attr.bsPopover && scope.$watch(attr.bsPopover, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n angular.isDefined(oldValue) && requestAnimationFrame(function() {\n popover && popover.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);\n newValue === true ? popover.show() : popover.hide();\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n\n // Initialize popover\n var popover = $popover(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (popover) popover.destroy();\n options = null;\n popover = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.scrollspy', ['mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$scrollspy', function() {\n\n // Pool of registered spies\n var spies = this.$$spies = {};\n\n var defaults = this.defaults = {\n debounce: 150,\n throttle: 100,\n offset: 100\n };\n\n this.$get = function($window, $document, $rootScope, dimensions, debounce, throttle) {\n\n var windowEl = angular.element($window);\n var docEl = angular.element($document.prop('documentElement'));\n var bodyEl = angular.element($window.document.body);\n\n // Helper functions\n\n function nodeName(element, name) {\n return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase();\n }\n\n function ScrollSpyFactory(config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n if(!options.element) options.element = bodyEl;\n var isWindowSpy = nodeName(options.element, 'body');\n var scrollEl = isWindowSpy ? windowEl : options.element;\n var scrollId = isWindowSpy ? 'window' : options.id;\n\n // Use existing spy\n if(spies[scrollId]) {\n spies[scrollId].$$count++;\n return spies[scrollId];\n }\n\n var $scrollspy = {};\n\n // Private vars\n var unbindViewContentLoaded, unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n var viewportHeight;\n var scrollTop;\n\n $scrollspy.init = function() {\n\n // Setup internal ref counter\n this.$$count = 1;\n\n // Bind events\n debouncedCheckPosition = debounce(this.checkPosition, options.debounce);\n throttledCheckPosition = throttle(this.checkPosition, options.throttle);\n scrollEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', debouncedCheckPosition);\n scrollEl.on('scroll', throttledCheckPosition);\n\n debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce);\n unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets);\n unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets);\n debouncedCheckOffsets();\n\n // Register spy for reuse\n if(scrollId) {\n spies[scrollId] = $scrollspy;\n }\n\n };\n\n $scrollspy.destroy = function() {\n\n // Check internal ref counter\n this.$$count--;\n if(this.$$count > 0) {\n return;\n }\n\n // Unbind events\n scrollEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', debouncedCheckPosition);\n scrollEl.off('scroll', throttledCheckPosition);\n unbindViewContentLoaded();\n unbindIncludeContentLoaded();\n if (scrollId) {\n delete spies[scrollId];\n }\n };\n\n $scrollspy.checkPosition = function() {\n\n // Not ready yet\n if(!sortedElements.length) return;\n\n // Calculate the scroll position\n scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0;\n\n // Calculate the viewport height for use by the components\n viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight'));\n\n // Activate first element if scroll is smaller\n if(scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) {\n return $scrollspy.$activateElement(sortedElements[0]);\n }\n\n // Activate proper element\n for (var i = sortedElements.length; i--;) {\n if(angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue;\n if(activeTarget === sortedElements[i].target) continue;\n if(scrollTop < sortedElements[i].offsetTop) continue;\n if(sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue;\n return $scrollspy.$activateElement(sortedElements[i]);\n }\n\n };\n\n $scrollspy.checkPositionWithEventLoop = function() {\n // IE 9 throws an error if we use 'this' instead of '$scrollspy'\n // in this setTimeout call\n setTimeout($scrollspy.checkPosition, 1);\n };\n\n // Protected methods\n\n $scrollspy.$activateElement = function(element) {\n if(activeTarget) {\n var activeElement = $scrollspy.$getTrackedElement(activeTarget);\n if(activeElement) {\n activeElement.source.removeClass('active');\n if(nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) {\n activeElement.source.parent().parent().removeClass('active');\n }\n }\n }\n activeTarget = element.target;\n element.source.addClass('active');\n if(nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) {\n element.source.parent().parent().addClass('active');\n }\n };\n\n $scrollspy.$getTrackedElement = function(target) {\n return trackedElements.filter(function(obj) {\n return obj.target === target;\n })[0];\n };\n\n // Track offsets behavior\n\n $scrollspy.checkOffsets = function() {\n\n angular.forEach(trackedElements, function(trackedElement) {\n var targetElement = document.querySelector(trackedElement.target);\n trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null;\n if(options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1;\n });\n\n sortedElements = trackedElements\n .filter(function(el) {\n return el.offsetTop !== null;\n })\n .sort(function(a, b) {\n return a.offsetTop - b.offsetTop;\n });\n\n debouncedCheckPosition();\n\n };\n\n $scrollspy.trackElement = function(target, source) {\n trackedElements.push({target: target, source: source});\n };\n\n $scrollspy.untrackElement = function(target, source) {\n var toDelete;\n for (var i = trackedElements.length; i--;) {\n if(trackedElements[i].target === target && trackedElements[i].source === source) {\n toDelete = i;\n break;\n }\n }\n trackedElements = trackedElements.splice(toDelete, 1);\n };\n\n $scrollspy.activate = function(i) {\n trackedElements[i].addClass('active');\n };\n\n // Initialize plugin\n\n $scrollspy.init();\n return $scrollspy;\n\n }\n\n return ScrollSpyFactory;\n\n };\n\n })\n\n .directive('bsScrollspy', function($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'EAC',\n link: function postLink(scope, element, attr) {\n\n var options = {scope: scope};\n angular.forEach(['offset', 'target'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n var scrollspy = $scrollspy(options);\n scrollspy.trackElement(options.target, element);\n\n scope.$on('$destroy', function() {\n if (scrollspy) {\n scrollspy.untrackElement(options.target, element);\n scrollspy.destroy();\n }\n options = null;\n scrollspy = null;\n });\n\n }\n };\n\n })\n\n\n .directive('bsScrollspyList', function($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'A',\n compile: function postLink(element, attr) {\n var children = element[0].querySelectorAll('li > a[href]');\n angular.forEach(children, function(child) {\n var childEl = angular.element(child);\n childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href'));\n });\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' ',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok'\n };\n\n this.$get = function($window, $document, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n\n function SelectFactory(element, controller, config) {\n\n var $select = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $select = $tooltip(element, options);\n var scope = $select.$scope;\n\n scope.$matches = [];\n if (options.multiple) {\n scope.$activeIndex = [];\n }\n else {\n scope.$activeIndex = -1;\n }\n scope.$isMultiple = options.multiple;\n scope.$showAllNoneButtons = options.allNoneButtons && options.multiple;\n scope.$iconCheckmark = options.iconCheckmark;\n scope.$allText = options.allText;\n scope.$noneText = options.noneText;\n\n scope.$activate = function(index) {\n scope.$$postDigest(function() {\n $select.activate(index);\n });\n };\n\n scope.$select = function(index, evt) {\n scope.$$postDigest(function() {\n $select.select(index);\n });\n };\n\n scope.$isVisible = function() {\n return $select.$isVisible();\n };\n\n scope.$isActive = function(index) {\n return $select.$isActive(index);\n };\n\n scope.$selectAll = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (!scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n scope.$selectNone = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n // Public methods\n\n $select.update = function(matches) {\n scope.$matches = matches;\n $select.$updateActiveIndex();\n };\n\n $select.activate = function(index) {\n if(options.multiple) {\n $select.$isActive(index) ? scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1) : scope.$activeIndex.push(index);\n if(options.sort) scope.$activeIndex.sort(function(a, b) { return a - b; }); // use numeric sort instead of default sort\n } else {\n scope.$activeIndex = index;\n }\n return scope.$activeIndex;\n };\n\n $select.select = function(index) {\n var value = scope.$matches[index].value;\n scope.$apply(function() {\n $select.activate(index);\n if(options.multiple) {\n controller.$setViewValue(scope.$activeIndex.map(function(index) {\n return scope.$matches[index].value;\n }));\n } else {\n controller.$setViewValue(value);\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function() {\n if(controller.$modelValue && scope.$matches.length) {\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function(value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n }\n } else if(scope.$activeIndex >= scope.$matches.length) {\n scope.$activeIndex = options.multiple ? [] : 0;\n }\n };\n\n $select.$isVisible = function() {\n if(!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function(index) {\n if(options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n } else {\n return scope.$activeIndex === index;\n }\n };\n\n $select.$getIndex = function(value) {\n var l = scope.$matches.length, i = l;\n if(!l) return;\n for(i = l; i--;) {\n if(scope.$matches[i].value === value) break;\n }\n if(i < 0) return;\n return i;\n };\n\n $select.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if(isTouch) {\n var targetEl = angular.element(evt.target);\n targetEl.triggerHandler('click');\n }\n };\n\n $select.$onKeyDown = function(evt) {\n if (!/(9|13|38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if(!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if(evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if(evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if(evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if(angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function() {\n _show();\n if(options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function() {\n if(!options.multiple && !controller.$modelValue) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if(options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Only parse data-multiple. Angular sets existence attributes to true (multiple/required/etc), they apply this\n // to data-multiple as well for some reason, so we'll parse this ourselves and disregard multiple\n var dataMultiple = element.attr('data-multiple');\n if(angular.isDefined(dataMultiple)) {\n if(falseValueRegExp.test(dataMultiple))\n options.multiple = false;\n else\n options.multiple = dataMultiple;\n }\n\n // Add support for select markup\n if(element[0].nodeName.toLowerCase() === 'select') {\n var inputEl = element;\n inputEl.css('display', 'none');\n element = angular.element('');\n inputEl.after(element);\n }\n\n // Build proper bsOptions\n var parsedOptions = $parseOptions(attr.bsOptions);\n\n // Initialize select\n var select = $select(element, controller, options);\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n select.update(values);\n controller.$render();\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);\n select.$updateActiveIndex();\n controller.$render();\n }, true);\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var selected, index;\n if(options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function(value) {\n index = select.$getIndex(value);\n return angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }).filter(angular.isDefined);\n if(selected.length > (options.maxLength || defaults.maxLength)) {\n selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);\n } else {\n selected = selected.join(', ');\n }\n } else {\n index = select.$getIndex(controller.$modelValue);\n selected = angular.isDefined(index) ? select.$scope.$matches[index].label : false;\n }\n element.html((selected ? selected : options.placeholder) + (options.caretHtml ? options.caretHtml : defaults.caretHtml));\n };\n\n if(options.multiple){\n controller.$isEmpty = function(value){\n return !value || value.length === 0;\n };\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (select) select.destroy();\n options = null;\n select = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n //uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory(element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes(time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format),\n timeSeparator = $dateFormatter.timeSeparator(format),\n minutesFormat = $dateFormatter.minutesFormat(format),\n secondsFormat = $dateFormatter.secondsFormat(format),\n showSeconds = $dateFormatter.showSeconds(format),\n showAM = $dateFormatter.showAM(format);\n\n scope.$iconUp = options.iconUp;\n scope.$iconDown = options.iconDown;\n\n // Scope methods\n\n scope.$select = function(date, index) {\n $timepicker.select(date, index);\n };\n scope.$moveIndex = function(value, index) {\n $timepicker.$moveIndex(value, index);\n };\n scope.$switchMeridian = function(date) {\n $timepicker.switchMeridian(date);\n };\n\n // Public methods\n\n $timepicker.update = function(date) {\n // console.warn('$timepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $timepicker.$date = date;\n angular.extend(viewDate, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function(date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) controller.$dateValue = new Date(1970, 0, 1);\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function() {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function(date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function() {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i, midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [],\n hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [],\n minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [],\n second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function(date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function(date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function(value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function(value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function(value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function(evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function(evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours(),\n hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes(),\n minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds(),\n secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection(start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement() {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function() {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function() {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function() {\n if((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n $timepicker.$element && $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.on('keydown', $timepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $timepicker.hide;\n $timepicker.hide = function(blur) {\n if (!$timepicker.$isShown) return;\n $timepicker.$element && $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n element && element.off('keydown', $timepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $timepicker;\n\n }\n\n timepickerFactory.defaults = defaults;\n return timepickerFactory;\n\n };\n\n })\n\n\n .directive('bsTimepicker', function($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {\n\n var defaults = $timepicker.defaults;\n var isNative = /(ip(a|o)d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if (!timepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);\n newValue === true ? timepicker.show() : timepicker.hide();\n });\n\n // Initialize timepicker\n if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';\n var timepicker = $timepicker(element, controller, options);\n options = timepicker.$options;\n\n var lang = options.lang;\n var formatDate = function(date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n // Initialize parser\n var dateParser = $dateParser({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function(key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n angular.isDefined(attr[key]) && attr.$observe(key, function(newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n !isNaN(timepicker.$options[key]) && timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);\n timepicker.update(controller.$dateValue);\n }, true);\n\n function validateAgainstMinMaxTime(parsedTime) {\n if (!angular.isDate(parsedTime)) return;\n var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;\n var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (!isValid) {\n return;\n }\n controller.$dateValue = parsedTime;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function(viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n controller.$setValidity('date', true);\n return null;\n }\n var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedTime || isNaN(parsedTime.getTime())) {\n controller.$setValidity('date', false);\n // Return undefined, causes ngModelController to\n // invalidate model value\n return undefined;\n } else {\n validateAgainstMinMaxTime(parsedTime);\n }\n\n if (options.timeType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true);\n return formatDate(date, options.modelTimeFormat || options.timeFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.timeType === 'number') {\n return date.getTime();\n } else if (options.timeType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.timeType === 'iso') {\n return date.toISOString();\n } else {\n return new Date(date);\n }\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function() {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString() {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function(key) {\n if(angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // Please use $activePaneChangeListeners if you use `bsActivePane`\n // Because we removed `ngModel` as default, we rename viewChangeListeners to\n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function(pane) {\n if(angular.isUndefined(self.$panes.$active)) {\n $scope.$setActive(pane.name || 0);\n }\n self.$panes.push(pane);\n };\n\n self.$remove = function(pane) {\n var index = self.$panes.indexOf(pane);\n var active = self.$panes.$active;\n var activeIndex;\n if(angular.isString(active)) {\n activeIndex = self.$panes.map(function(pane) {\n return pane.name;\n }).indexOf(active);\n } else {\n activeIndex = self.$panes.$active;\n }\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to\n // decrement the active pane index\n activeIndex--;\n }\n else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n if(activeIndex >= 0 && activeIndex < self.$panes.length) {\n self.$setActive(self.$panes[activeIndex].name || activeIndex);\n } else {\n self.$setActive();\n }\n };\n\n self.$setActive = $scope.$setActive = function(value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function(fn) {\n fn();\n });\n };\n\n self.$isActive = $scope.$isActive = function($pane, $index) {\n return self.$panes.$active === $pane.name || self.$panes.$active === $index;\n };\n\n };\n\n this.$get = function() {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function(element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // 'ngModel' does interfere with form validation\n // and status, use `bsActivePane` instead to avoid it\n if(ngModelCtrl) {\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function(newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink(scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function(newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Save tab name into scope\n scope.name = attrs.name;\n\n // Add animation class\n if(bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n attrs.$observe('disabled', function(newValue, oldValue) {\n scope.disabled = scope.$eval(newValue);\n });\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function() {\n bsTabsCtrl.$remove(scope);\n });\n\n function render() {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function() {\n render();\n });\n render();\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n\n function TypeaheadFactory(element, controller, config) {\n\n var $typeahead = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $typeahead = $tooltip(element, options);\n var parentScope = config.scope;\n var scope = $typeahead.$scope;\n\n scope.$resetMatches = function() {\n scope.$matches = [];\n scope.$activeIndex = options.autoSelect ? 0 : -1; // If set to 0, the first match will be highlighted\n };\n scope.$resetMatches();\n\n scope.$activate = function(index) {\n scope.$$postDigest(function() {\n $typeahead.activate(index);\n });\n };\n\n scope.$select = function(index, evt) {\n scope.$$postDigest(function() {\n $typeahead.select(index);\n });\n };\n\n scope.$isVisible = function() {\n return $typeahead.$isVisible();\n };\n\n // Public methods\n\n $typeahead.update = function(matches) {\n scope.$matches = matches;\n if (scope.$activeIndex >= matches.length) {\n scope.$activeIndex = options.autoSelect ? 0 : -1;\n }\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n safeDigest(scope);\n $$rAF($typeahead.$applyPlacement);\n };\n\n $typeahead.activate = function(index) {\n scope.$activeIndex = index;\n };\n\n $typeahead.select = function(index) {\n if (index === -1) return;\n var value = scope.$matches[index].value;\n // console.log('$setViewValue', value);\n controller.$setViewValue(value);\n controller.$render();\n scope.$resetMatches();\n if (parentScope) parentScope.$digest();\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $typeahead);\n };\n\n // Protected methods\n\n $typeahead.$isVisible = function() {\n if (!options.minLength || !controller) {\n return !!scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength;\n };\n\n $typeahead.$getIndex = function(value) {\n var l = scope.$matches.length,\n i = l;\n if (!l) return;\n for (i = l; i--;) {\n if (scope.$matches[i].value === value) break;\n }\n if (i < 0) return;\n return i;\n };\n\n $typeahead.$onMouseDown = function(evt) {\n // Prevent blur on mousedown\n evt.preventDefault();\n evt.stopPropagation();\n };\n\n $typeahead.$onKeyDown = function(evt) {\n if (!/(38|40|13)/.test(evt.keyCode)) return;\n\n // Let ngSubmit pass if the typeahead tip is hidden or no option is selected\n if ($typeahead.$isVisible() && !(evt.keyCode === 13 && scope.$activeIndex === -1)) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // Select with enter\n if (evt.keyCode === 13 && scope.$matches.length) {\n $typeahead.select(scope.$activeIndex);\n }\n\n // Navigate with keyboard\n else if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n };\n\n // Overrides\n\n var show = $typeahead.show;\n $typeahead.show = function() {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed immediately.\n $timeout(function() {\n $typeahead.$element && $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n element && element.on('keydown', $typeahead.$onKeyDown);\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function() {\n $typeahead.$element && $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n element && element.off('keydown', $typeahead.$onKeyDown);\n }\n if (!options.autoSelect)\n $typeahead.activate(-1);\n hide();\n };\n\n return $typeahead;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\n\n })\n\n .filter('bsAsyncFilter', function($filter) {\n return function(array, expression, comparator) {\n if (array && angular.isFunction(array.then)) {\n return array.then(function(results) {\n return $filter('filter')(results, expression, comparator);\n });\n } else {\n return $filter('filter')(array, expression, comparator);\n }\n };\n })\n\n .directive('bsTypeahead', function($window, $parse, $q, $typeahead, $parseOptions) {\n\n var defaults = $typeahead.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink(scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass'], function(key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'trimValue'], function(key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // Disable browser autocompletion\n element.attr('autocomplete', 'false');\n\n // Build proper bsOptions\n var filter = options.filter || defaults.filter;\n var limit = options.limit || defaults.limit;\n var comparator = options.comparator || defaults.comparator;\n\n var bsOptions = attr.bsOptions;\n if (filter) bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\n if (limit) bsOptions += ' | limitTo:' + limit;\n var parsedOptions = $parseOptions(bsOptions);\n\n // Initialize typeahead\n var typeahead = $typeahead(element, controller, options);\n\n // Watch options on demand\n if (options.watchOptions) {\n // Watch bsOptions values before filtering for changes, drop function calls\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').replace(/\\(.*\\)/g, '').trim();\n scope.$watchCollection(watchedOptions, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller).then(function(values) {\n typeahead.update(values);\n controller.$render();\n });\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function(newValue, oldValue) {\n // console.warn('$watch', element.attr('ng-model'), newValue);\n scope.$modelValue = newValue; // Publish modelValue on scope for custom templates\n parsedOptions.valuesFn(scope, controller)\n .then(function(values) {\n // Prevent input with no future prospect if selectMode is truthy\n // @TODO test selectMode\n if (options.selectMode && !values.length && newValue.length > 0) {\n controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1));\n return;\n }\n if (values.length > limit) values = values.slice(0, limit);\n var isVisible = typeahead.$isVisible();\n isVisible && typeahead.update(values);\n // Do not re-queue an update if a correct value has been selected\n if (values.length === 1 && values[0].value === newValue) return;\n !isVisible && typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function(modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (modelValue && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function() {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = angular.isDefined(index) ? typeahead.$scope.$matches[index].label : controller.$viewValue;\n selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected;\n var value = selected ? selected.toString().replace(/<(?:.|\\n)*?>/gm, '') : '';\n element.val(options.trimValue === false ? value : value.trim());\n };\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if (typeahead) typeahead.destroy();\n options = null;\n typeahead = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function() {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n contentTemplate: false,\n trigger: 'hover focus',\n keyboard: false,\n html: false,\n show: false,\n title: '',\n type: '',\n delay: 0,\n autoClose: false,\n bsEnabled: true,\n viewport: {\n selector: 'body',\n padding: 0\n }\n };\n\n this.$get = function($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var trim = String.prototype.trim;\n var isTouch = 'createTouch' in $window.document;\n var htmlReplaceRegExp = /ng-bind=\"/ig;\n var $body = angular.element($window.document);\n\n function TooltipFactory(element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if(options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if(options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function(isEnabled) {\n scope.$$postDigest(function() {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function() {\n scope.$$postDigest(function() {\n $tooltip.hide();\n });\n };\n scope.$show = function() {\n scope.$$postDigest(function() {\n $tooltip.show();\n });\n };\n scope.$toggle = function() {\n scope.$$postDigest(function() {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout, hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData, tipElement, tipContainer, tipScope;\n promise.then(function(data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function() {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if(options.container === 'self') {\n tipContainer = element;\n } else if(angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if(options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if(options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if(options.show) {\n scope.$$postDigest(function() {\n options.trigger === 'focus' ? element[0].focus() : $tooltip.show();\n });\n }\n\n };\n\n $tooltip.destroy = function() {\n\n // Unbind events\n unbindTriggerEvents();\n\n // Remove element\n destroyTipElement();\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $tooltip.enter = function() {\n\n clearTimeout(timeout);\n hoverState = 'in';\n if (!options.delay || !options.delay.show) {\n return $tooltip.show();\n }\n\n timeout = setTimeout(function() {\n if (hoverState ==='in') $tooltip.show();\n }, options.delay.show);\n\n };\n\n $tooltip.show = function() {\n if (!options.bsEnabled || $tooltip.$isShown) return;\n\n scope.$emit(options.prefixEvent + '.show.before', $tooltip);\n var parent, after;\n if (options.container) {\n parent = tipContainer;\n if (tipContainer[0].lastChild) {\n after = angular.element(tipContainer[0].lastChild);\n } else {\n after = null;\n }\n } else {\n parent = null;\n after = element;\n }\n\n\n // Hide any existing tipElement\n if(tipElement) destroyTipElement();\n // Fetch a cloned element linked from template\n tipScope = $tooltip.$scope.$new();\n tipElement = $tooltip.$element = compileData.link(tipScope, function(clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if(options.animation) tipElement.addClass(options.animation);\n // Options: type\n if(options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if(options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n after ? after.after(tipElement) : parent.prepend(tipElement);\n\n $tooltip.$isShown = scope.$isShown = true;\n safeDigest(scope);\n\n // Now, apply placement\n $tooltip.$applyPlacement();\n\n // Once placed, animate it.\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.enter(tipElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(tipElement, parent, after).then(enterAnimateCallback);\n }\n safeDigest(scope);\n\n $$rAF(function () {\n // Once the tooltip is placed and the animation starts, make the tooltip visible\n if(tipElement) tipElement.css({visibility: 'visible'});\n });\n\n // Bind events\n if(options.keyboard) {\n if(options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n\n if(options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback() {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n }\n\n $tooltip.leave = function() {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function(blur) {\n\n if(!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if(angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if(options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if(options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback() {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if(_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function() {\n $tooltip.$isShown ? $tooltip.leave() : $tooltip.enter();\n };\n\n $tooltip.focus = function() {\n tipElement[0].focus();\n };\n\n $tooltip.setEnabled = function(isEnabled) {\n options.bsEnabled = isEnabled;\n };\n\n $tooltip.setViewport = function(viewport) {\n options.viewport = viewport;\n };\n\n // Protected methods\n\n $tooltip.$applyPlacement = function() {\n if(!tipElement) return;\n\n // Determine if we're doing an auto or normal placement\n var placement = options.placement,\n autoToken = /\\s?auto?\\s?/i,\n autoPlace = autoToken.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(autoToken, '') || defaults.placement;\n }\n\n // Need to add the position class before we get\n // the offsets\n tipElement.addClass(options.placement);\n\n // Get the position of the target element\n // and the height and width of the tooltip so we can center it.\n var elementPosition = getPosition(),\n tipWidth = tipElement.prop('offsetWidth'),\n tipHeight = tipElement.prop('offsetHeight');\n\n // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n // Determine if the vertical placement\n if (originalPlacement.indexOf('bottom') >= 0 && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (originalPlacement.indexOf('top') >= 0 && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n // Determine the horizontal placement\n // The exotic placements of left and right are opposite of the standard placements. Their arrows are put on the left/right\n // and flow in the opposite direction of their placement.\n if ((originalPlacement === 'right' || originalPlacement === 'bottom-left' || originalPlacement === 'top-left') &&\n elementPosition.right + tipWidth > viewportPosition.width) {\n\n placement = originalPlacement === 'right' ? 'left' : placement.replace('left', 'right');\n } else if ((originalPlacement === 'left' || originalPlacement === 'bottom-right' || originalPlacement === 'top-right') &&\n elementPosition.left - tipWidth < viewportPosition.left) {\n\n placement = originalPlacement === 'left' ? 'right' : placement.replace('right', 'left');\n }\n\n tipElement.removeClass(originalPlacement).addClass(placement);\n }\n\n // Get the tooltip's top and left coordinates to center it with this directive.\n var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight);\n applyPlacement(tipPosition, placement);\n };\n\n $tooltip.$onKeyUp = function(evt) {\n if (evt.which === 27 && $tooltip.$isShown) {\n $tooltip.hide();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusKeyUp = function(evt) {\n if (evt.which === 27) {\n element[0].blur();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusElementMouseDown = function(evt) {\n evt.preventDefault();\n evt.stopPropagation();\n // Some browsers do not auto-focus buttons (eg. Safari)\n $tooltip.$isShown ? element[0].blur() : element[0].focus();\n };\n\n // bind/unbind events\n function bindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n angular.forEach(triggers, function(trigger) {\n if(trigger === 'click') {\n element.on('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n });\n }\n\n function unbindTriggerEvents() {\n var triggers = options.trigger.split(' ');\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i];\n if(trigger === 'click') {\n element.off('click', $tooltip.toggle);\n } else if(trigger !== 'manual') {\n element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n nodeName === 'button' && trigger !== 'hover' && element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n }\n\n function bindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.on('keyup', $tooltip.$onKeyUp);\n } else {\n element.on('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n function unbindKeyboardEvents() {\n if(options.trigger !== 'focus') {\n tipElement.off('keyup', $tooltip.$onKeyUp);\n } else {\n element.off('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n var _autoCloseEventsBinded = false;\n function bindAutoCloseEvents() {\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function() {\n // Stop propagation when clicking inside tooltip\n tipElement.on('click', stopEventPropagation);\n\n // Hide when clicking outside tooltip\n $body.on('click', $tooltip.hide);\n\n _autoCloseEventsBinded = true;\n }, 0, false);\n }\n\n function unbindAutoCloseEvents() {\n if (_autoCloseEventsBinded) {\n tipElement.off('click', stopEventPropagation);\n $body.off('click', $tooltip.hide);\n _autoCloseEventsBinded = false;\n }\n }\n\n function stopEventPropagation(event) {\n event.stopPropagation();\n }\n\n // Private methods\n\n function getPosition($element) {\n $element = $element || (options.target || element);\n\n var el = $element[0],\n isBody = el.tagName === 'BODY';\n\n var elRect = el.getBoundingClientRect();\n var rect = {};\n\n // IE8 has issues with angular.extend and using elRect directly.\n // By coping the values of elRect into a new object, we can continue to use extend\n for (var p in elRect) {\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n\n if (rect.width === null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n rect = angular.extend({}, rect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top });\n }\n var elOffset = isBody ? { top: 0, left: 0 } : dimensions.offset(el),\n scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0 },\n outerDims = isBody ? { width: document.documentElement.clientWidth, height: $window.innerHeight } : null;\n\n return angular.extend({}, rect, scroll, outerDims, elOffset);\n }\n\n function getCalculatedOffset(placement, position, actualWidth, actualHeight) {\n var offset;\n var split = placement.split('-');\n\n switch (split[0]) {\n case 'right':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left + position.width\n };\n break;\n case 'bottom':\n offset = {\n top: position.top + position.height,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n case 'left':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left - actualWidth\n };\n break;\n default:\n offset = {\n top: position.top - actualHeight,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n }\n\n if(!split[1]) {\n return offset;\n }\n\n // Add support for corners @todo css\n if(split[0] === 'top' || split[0] === 'bottom') {\n switch (split[1]) {\n case 'left':\n offset.left = position.left;\n break;\n case 'right':\n offset.left = position.left + position.width - actualWidth;\n }\n } else if(split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight;\n break;\n case 'bottom':\n offset.top = position.top + position.height;\n }\n }\n\n return offset;\n }\n\n function applyPlacement(offset, placement) {\n var tip = tipElement[0],\n width = tip.offsetWidth,\n height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10),\n marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10);\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0;\n if (isNaN(marginLeft)) marginLeft = 0;\n\n offset.top = offset.top + marginTop;\n offset.left = offset.left + marginLeft;\n\n // dimensions setOffset doesn't round pixel values\n // so we use setOffset directly with our own function\n dimensions.setOffset(tip, angular.extend({\n using: function (props) {\n tipElement.css({\n top: Math.round(props.top) + 'px',\n left: Math.round(props.left) + 'px',\n right: ''\n });\n }\n }, offset), 0);\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = tip.offsetWidth,\n actualHeight = tip.offsetHeight;\n\n if (placement === 'top' && actualHeight !== height) {\n offset.top = offset.top + height - actualHeight;\n }\n\n // If it's an exotic placement, exit now instead of\n // applying a delta and changing the arrow\n if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return;\n\n var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);\n\n if (delta.left) {\n offset.left += delta.left;\n } else {\n offset.top += delta.top;\n }\n\n dimensions.setOffset(tip, offset);\n\n if (/top|right|bottom|left/.test(placement)) {\n var isVertical = /top|bottom/.test(placement),\n arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight,\n arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta(placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow(delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement() {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if($tooltip.$isShown && tipElement !== null) {\n if(options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if(options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if(tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if(tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest(scope) {\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n }\n\n function findElement(query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate(template) {\n if(fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache}).then(function(res) {\n return res.data;\n }));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function($window, $location, $sce, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink(scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function(key) {\n if(angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function(key) {\n if(angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key]))\n options[key] = false;\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if(angular.isDefined(dataTarget)) {\n if(falseValueRegExp.test(dataTarget))\n options.target = false;\n else\n options.target = dataTarget;\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')){\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function(newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }\n });\n\n // Support scope as an object\n attr.bsTooltip && scope.$watch(attr.bsTooltip, function(newValue, oldValue) {\n if(angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n angular.isDefined(oldValue) && $$rAF(function() {\n tooltip && tooltip.$applyPlacement();\n });\n }, true);\n\n // Visibility binding support\n attr.bsShow && scope.$watch(attr.bsShow, function(newValue, oldValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n newValue === true ? tooltip.show() : tooltip.hide();\n });\n\n // Enabled binding support\n attr.bsEnabled && scope.$watch(attr.bsEnabled, function(newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if(!tooltip || !angular.isDefined(newValue)) return;\n if(angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n newValue === false ? tooltip.setEnabled(false) : tooltip.setEnabled(true);\n });\n\n // Viewport support\n attr.viewport && scope.$watch(attr.viewport, function (newValue) {\n if(!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n\n // Initialize popover\n var tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function() {\n if(tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["angular-strap.js","typeahead/typeahead.js","helpers/compiler.js","datepicker/datepicker.js","tab/tab.js","tooltip/tooltip.js","timepicker/timepicker.js","scrollspy/scrollspy.js","select/select.js","popover/popover.js","navbar/navbar.js","modal/modal.js","dropdown/dropdown.js","helpers/raf.js","helpers/parse-options.js","helpers/dimensions.js","helpers/debounce.js","helpers/date-parser.js","helpers/date-formatter.js","button/button.js","collapse/collapse.js","aside/aside.js","alert/alert.js","affix/affix.js","module.js"],"names":["prefixEvent","undefined","templateUrl","options","cache","$templateCache","then","element","res","fetchTemplate","template","fetchPromises","module","$http","get","defaults","animation","prefixClass","data","this","compile","controller","console","controllerAs","resolve","copy","locals","bindToController","angular","forEach","value","isString","$injector","key","invoke","transformTemplate","identity","extend","$template","when","$q","all","templateEl","Error","findElement","contentTemplate","templates","contentEl","removeAttr","html","replace","next","remove","outerHTML","link","scope","trim","contents","linkFn","invokeCtrl","children","instance","ctrl","isObject","arguments","apply","bsCompilerService","$inject","trigger","provider","container","keyboard","delay","minLength","filter","limit","autoSelect","comparator","trimValue","$get","$typeahead","parentScope","$resetMatches","$window","$rootScope","$tooltip","$$rAF","$timeout","$matches","config","$$postDigest","$scope","activate","$activeIndex","select","index","$select","evt","matches","$isVisible","safeDigest","update","$render","$emit","isDefined","onSelect","$setViewValue","length","isFunction","equals","$onMouseDown","preventDefault","stopPropagation","keyCode","$digest","show","$element","hide","$onKeyDown","$$phase","$root","TypeaheadFactory","array","$filter","expression","directive","results","postLink","attr","restrict","require","falseValueRegExp","bsKey","charAt","toUpperCase","slice","test","bsOptions","parsedOptions","$parseOptions","typeahead","watchedOptions","$watchCollection","values","watchOptions","$match","$watch","ngModel","newValue","oldValue","$modelValue","valuesFn","selectMode","$viewValue","substring","displayValue","$formatters","push","modelValue","selected","ss","selectionStart","val","selectionEnd","setSelectionRange","sd","label","destroy","$on","self","$options","navClass","activeClass","$activeClass","$panes","$activePaneChangeListeners","$push","pane","isUndefined","$active","$attrs","$navClass","$remove","active","activeIndex","indexOf","splice","map","$setActive","name","fn","$pane","$tab","transclude","ngModelCtrl","bsTabsCtrl","attrs","bsActivePane","parsedBsActivePane","assign","$parse","$observe","controllers","render","$animate","$isActive","addClass","disabled","customClass","target","placement","titleTemplate","title","type","autoClose","bsEnabled","mouseDownPreventDefault","mouseDownStopPropagation","viewport","selector","padding","TooltipFactory","promise","$bsCompiler","split","clearTimeout","hoverState","onShow","leaveAnimateCallback","destroyTipElement","onHide","_tipToHide","triggers","nodeName","on","isTouch","toggle","enter","unbindTriggerEvents","$onFocusElementMouseDown","off","i","bindKeyboardEvents","tipElement","$onKeyUp","unbindKeyboardEvents","_autoCloseEventsBinded","bindAutoCloseEvents","$body","unbindAutoCloseEvents","stopEventPropagation","event","getPosition","elRect","getBoundingClientRect","rect","p","width","height","top","left","dimensions","offset","el","scroll","outerDims","isBody","document","documentElement","scrollTop","body","prop","clientWidth","innerHeight","position","actualWidth","actualHeight","marginLeft","isNaN","setOffset","using","parseInt","props","css","right","marginTop","tip","offsetHeight","getViewportAdjustedDelta","delta","offsetWidth","isVertical","arrowDelta","replaceArrow","arrowOffsetPosition","viewportDimensions","$viewport","topEdgeOffset","bottomEdgeOffset","viewportPadding","leftEdgeOffset","rightEdgeOffset","dimension","isHorizontal","$arrow","timeout","$isShown","tipScope","$destroy","$promise","$new","toLowerCase","$id","parseFloat","$sce","trustAsHtml","$setEnabled","id","$hide","setEnabled","isEnabled","compileData","tipContainer","init","bindTriggerEvents","isElement","focus","onBeforeShow","after","parent","lastChild","display","visibility","clonedElement","version","prepend","$applyPlacement","enterAnimateCallback","_blur","leave","onBeforeHide","autoPlace","autoToken","elementPosition","tipWidth","tipHeight","viewportPosition","originalPlacement","removeClass","tipPosition","getCalculatedOffset","applyPlacement","blur","query","querySelectorAll","isNative","tooltip","transclusion","$eval","dataTarget","hasOwnProperty","bsTooltip","bsShow","match","setViewport","useNative","timeType","timeFormat","timezone","modelTimeFormat","autoclose","minTime","maxTime","Infinity","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","$timepicker","timepickerFactory","formatDate","format","viewDate","hour","startDate","getHours","meridian","coeff","selRange","end","start","collapse","moveStart","moveEnd","focusElement","_init","floorMinutes","time","floor","lang","selectedIndex","date","defaultDate","second","getSeconds","millisecond","getMilliseconds","$dateValue","hoursFormat","$dateFormatter","timeSeparator","minute","minutesFormat","secondsFormat","showSeconds","$iconUp","$moveIndex","$switchMeridian","switchMeridian","isDate","getMinutes","getTime","$build","$isBuilt","keep","Date","setHours","setMinutes","setSeconds","midIndex","hours","minutes","$date","seconds","rows","$isDisabled","showAM","$isSelected","isAM","selectedTime","$arrowAction","$setTimeByStep","newDate","targetDate","targetEl","triggerHandler","hoursLength","minutesLength","sepLength","lateralMove","count","selectRange","incr","isSeconds","isMeridian","secondsLength","createSelection","createTextRange","_destroy","_show","_hide","navigator","userAgent","isMaxValid","isValid","parsedTime","isMinValid","setFullYear","$setValidity","$parsers","unshift","viewValue","getTimeFormattedString","timepicker","dateParser","$dateParser","validateAgainstMinMaxTime","timezoneOffsetAdjust","NaN","parse","spies","$document","windowEl","debounce","bodyEl","throttle","ScrollSpyFactory","scrollEl","isWindowSpy","scrollId","$$count","$scrollspy","unbindViewContentLoaded","unbindIncludeContentLoaded","trackedElements","sortedElements","activeTarget","debouncedCheckOffsets","viewportHeight","debouncedCheckPosition","throttledCheckPosition","checkPositionWithEventLoop","checkOffsets","checkPosition","docEl","$activateElement","offsetTop","setTimeout","activeElement","source","$getTrackedElement","targetElement","querySelector","trackedElement","b","trackElement","toDelete","untrackElement","scrollspy","childEl","child","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","SelectFactory","$isMultiple","$showAllNoneButtons","$iconCheckmark","$allText","$activate","$selectNone","$updateActiveIndex","a","$apply","isArray","$getIndex","$selectScrollFix","$isIE","stopImmediatePropagation","ua","tagName","e","dataMultiple","inputEl","addEventListener","join","$isEmpty","content","$popover","PopoverFactory","requestAnimationFrame","bsPopover","popover","routeAttr","$navbar","liElements","li","liElement","pattern","path","RegExp","regexp","backdrop","size","bodyElement","backdropCount","dialogBaseZindex","validSizes","ModalFactory","$modal","unbindBackdropEvents","modalElement","hideOnBackdropClick","backdropElement","preventEventDefault","modalScope","$show","bottom","destroyModalElement","z-index","backdropBaseZindex","defaultPrevented","minor","backdropAnimation","bindBackdropEvents","which","lg","sm","modalClass","bsModal","modal","matchesSelector","DropdownFactory","$dropdown","onBodyClick","items","parentEl","hasClass","prototype","tAttrs","nextSibling","nodeType","parentNode","removeChild","dropdown","dot","cancelAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","rafSupported","raf","timer","cancel","supported","$values","valueName","keyName","displayFn","valueFn","ParseOptionsFactory","groupByFn","factory","offsetParent","docElement","ownerDocument","outer","window","getComputedStyle","extra","currentStyle","boxRect","style","curPosition","curLeft","curCSSTop","curTop","calculatePosition","curElem","curCSSLeft","curOffset","call","offsetParentRect","offsetParentEl","offsetParentElement","func","immediate","args","context","callNow","leading","wait","trailing","year","$localeProvider","milliseconds","ParseDate","noop","indexOfCaseInsensitive","len","str","toString","strict","DateParserFactory","day","month","getFullYear","getMonth","proto","isNumeric","toDate","regExpMap","sss","$locale","dateFilter","mm","literalRegex","formatParts","escapedLiteralFormat","dateElements","keys","escapedFormat","isFormatStringLiteral","part","trimLiteralEscapeChars","dateRegexParts","escapeReservedSymbols","text","re","abstractRegex","buildDateParseRegex","setMapForFormat","buildDateAbstractRegex","buildDateParseValuesMap","Object","valuesMatch","keyIndex","valueKey","valuesFunctionMap","valueFunction","valuesRegex","exec","setFnMap","setMap","m","HH","H","hh","h","EEEE","EEE","DATETIME_FORMATS","SHORTDAY","dd","d","MMMM","MMM","SHORTMONTH","MM","M","DAY","yyyy","yy","y","MONTH","s","setDate","setMonth","regex","$format","regExpForFormat","baseDate","formatRegex","formatSetMap","fromDate","getDate","today","getDateForAttribute","substr","getTimeForAttribute","daylightSavingAdjust","undo","getTimezoneOffset","getDefaultLocale","getDatetimeFormat","weekdaysShort","splitTimeFormat","service","dateType","dateFormat","modelDateFormat","dayFormat","monthFormat","yearFormat","monthTitleFormat","yearTitleFormat","strictFormat","minDate","maxDate","startView","minView","startWeek","daysOfWeekDisabled","hasToday","hasClear","iconLeft","iconRight","DatepickerFactory","$datepicker","pickerViews","views","$iconLeft","$iconRight","$hasToday","$picker","$selectPane","$hasClear","$toggleMode","$views","$mode","setMode","$setToday","$clear","updateDisabledDates","disabledDateRanges","dateRanges","$setDisabledEl","mode","pristine","$updateSelected","built","isDisabled","steps","getUTCFullYear","getUTCMonth","UTC","getUTCDate","shiftKey","altKey","onKeyDown","datepickerViews","previousValue","normalizeDateRanges","ranges","disabledRanges","datepicker","parsedDate","getDateFormattedString","validateAgainstMinMaxDate","disabledDates","arrays","mod","n","arr","weekDaysMin","weekDaysLabelsHtml","picker","weekDaysLabels","concat","firstDayOfMonth","firstDayOfMonthOffset","firstDate","firstDateOffset","build","days","isToday","toDateString","muted","showLabels","labels","isTodayDisabled","isSelected","getDay","months","lastDate","actualMonth","firstYear","years","actualYear","Array","setYear","$button","constantValueRegExp","isInput","trueValue","falseValue","hasExoticValues","isActive","checked","bind","toggleEvent","toggleClass","v","startCollapsed","allowMultiple","activeIndexes","$targets","activeItems","activateItem","$collapse","$viewChangeListeners","$registerToggle","$toggles","$unregisterToggle","$unregisterTarget","deactivateItem","fixActiveItemIndexes","disallowToggle","$activeIndexes","bsCollapseCtrl","bsCollapseToggle","$registerTarget","action","AsideFactory","$aside","bsAside","aside","duration","dismissable","AlertFactory","$alert","bsAlert","alert","AffixFactory","$affix","inlineStyles","reset","initialOffsetTop","getRequiredAffixClass","_unpin","getScrollTop","scrollHeight","getScrollHeight","offsetBottom","elementHeight","initialAffixTop","pageYOffset","affixed","unpin","$parseOffsets","affix","setWidth","offsetUnpin","$onResize","$debouncedOnResize","initialPosition","affixTarget","option"],"mappings":"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","file":"angular-strap.min.js","sourcesContent":["(function(window, document, undefined) {\n'use strict';\n\n// Source: typeahead/typeahead.js\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function ($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n function TypeaheadFactory (element, controller, config) {\n\n var $typeahead = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $typeahead = $tooltip(element, options);\n var parentScope = config.scope;\n var scope = $typeahead.$scope;\n\n scope.$resetMatches = function () {\n scope.$matches = [];\n scope.$activeIndex = options.autoSelect ? 0 : -1; // If set to 0, the first match will be highlighted\n };\n scope.$resetMatches();\n\n scope.$activate = function (index) {\n scope.$$postDigest(function () {\n $typeahead.activate(index);\n });\n };\n\n scope.$select = function (index, evt) {\n scope.$$postDigest(function () {\n $typeahead.select(index);\n });\n };\n\n scope.$isVisible = function () {\n return $typeahead.$isVisible();\n };\n\n // Public methods\n\n $typeahead.update = function (matches) {\n scope.$matches = matches;\n if (scope.$activeIndex >= matches.length) {\n scope.$activeIndex = options.autoSelect ? 0 : -1;\n }\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n safeDigest(scope);\n $$rAF($typeahead.$applyPlacement);\n };\n\n $typeahead.activate = function (index) {\n scope.$activeIndex = index;\n };\n\n $typeahead.select = function (index) {\n if (index === -1) return;\n var value = scope.$matches[index].value;\n // console.log('$setViewValue', value);\n controller.$setViewValue(value);\n controller.$render();\n scope.$resetMatches();\n if (parentScope) parentScope.$digest();\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $typeahead);\n if (angular.isDefined(options.onSelect) && angular.isFunction(options.onSelect)) {\n options.onSelect(value, index, $typeahead);\n }\n };\n\n // Protected methods\n\n $typeahead.$isVisible = function () {\n if (!options.minLength || !controller) {\n return !!scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength;\n };\n\n $typeahead.$getIndex = function (value) {\n var index;\n for (index = scope.$matches.length; index--;) {\n if (angular.equals(scope.$matches[index].value, value)) break;\n }\n return index;\n };\n\n $typeahead.$onMouseDown = function (evt) {\n // Prevent blur on mousedown\n evt.preventDefault();\n evt.stopPropagation();\n };\n\n $typeahead.$onKeyDown = function (evt) {\n if (!/(38|40|13)/.test(evt.keyCode)) return;\n\n // Let ngSubmit pass if the typeahead tip is hidden or no option is selected\n if ($typeahead.$isVisible() && !(evt.keyCode === 13 && scope.$activeIndex === -1)) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // Select with enter\n if (evt.keyCode === 13 && scope.$matches.length) {\n $typeahead.select(scope.$activeIndex);\n // Navigate with keyboard\n } else if (evt.keyCode === 38 && scope.$activeIndex > 0) {\n scope.$activeIndex--;\n } else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) {\n scope.$activeIndex++;\n } else if (angular.isUndefined(scope.$activeIndex)) {\n scope.$activeIndex = 0;\n }\n scope.$digest();\n };\n\n // Overrides\n\n var show = $typeahead.show;\n $typeahead.show = function () {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed immediately.\n $timeout(function () {\n if ($typeahead.$element) {\n $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n if (element) element.on('keydown', $typeahead.$onKeyDown);\n }\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function () {\n if ($typeahead.$element) $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n if (element) element.off('keydown', $typeahead.$onKeyDown);\n }\n if (!options.autoSelect) {\n $typeahead.activate(-1);\n }\n hide();\n };\n\n return $typeahead;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\n\n })\n\n .filter('bsAsyncFilter', function ($filter) {\n return function (array, expression, comparator) {\n if (array && angular.isFunction(array.then)) {\n return array.then(function (results) {\n return $filter('filter')(results, expression, comparator);\n });\n }\n return $filter('filter')(array, expression, comparator);\n };\n })\n\n .directive('bsTypeahead', function ($window, $parse, $q, $typeahead, $parseOptions) {\n\n var defaults = $typeahead.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Fixes firefox bug when using objects in model with typeahead\n // Yes this breaks any other directive using a 'change' event on this input,\n // but if it is using the 'change' event why is it used with typeahead?\n element.off('change');\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'trimValue', 'filter'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show, hide and select events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide', 'onSelect'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Disable browser autocompletion\n if (!element.attr('autocomplete')) element.attr('autocomplete', 'off');\n\n // Build proper bsOptions\n var filter = angular.isDefined(options.filter) ? options.filter : defaults.filter;\n var limit = options.limit || defaults.limit;\n var comparator = options.comparator || defaults.comparator;\n\n var bsOptions = attr.bsOptions;\n if (filter) {\n bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\n }\n if (limit) bsOptions += ' | limitTo:' + limit;\n var parsedOptions = $parseOptions(bsOptions);\n\n // Initialize typeahead\n var typeahead = $typeahead(element, controller, options);\n\n // Watch options on demand\n if (options.watchOptions) {\n // Watch bsOptions values before filtering for changes, drop function calls\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').replace(/\\(.*\\)/g, '').trim();\n scope.$watchCollection(watchedOptions, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller).then(function (values) {\n typeahead.update(values);\n controller.$render();\n });\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('$watch', element.attr('ng-model'), newValue);\n scope.$modelValue = newValue; // Publish modelValue on scope for custom templates\n parsedOptions.valuesFn(scope, controller)\n .then(function (values) {\n // Prevent input with no future prospect if selectMode is truthy\n // @TODO test selectMode\n if (options.selectMode && !values.length && newValue.length > 0) {\n controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1));\n return;\n }\n if (values.length > limit) values = values.slice(0, limit);\n typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (angular.isDefined(modelValue) && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = index !== -1 ? typeahead.$scope.$matches[index].label : controller.$viewValue;\n selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected;\n var value = selected ? selected.toString().replace(/<(?:.|\\n)*?>/gm, '') : '';\n var ss = element[0].selectionStart;\n var sd = element[0].selectionEnd;\n element.val(options.trimValue === false ? value : value.trim());\n element[0].setSelectionRange(ss, sd);\n };\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (typeahead) typeahead.destroy();\n options = null;\n typeahead = null;\n });\n\n }\n };\n\n });\n\n// Source: tab/tab.js\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function ($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function (key) {\n if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // Please use $activePaneChangeListeners if you use `bsActivePane`\n // Because we removed `ngModel` as default, we rename viewChangeListeners to\n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function (pane) {\n if (angular.isUndefined(self.$panes.$active)) {\n $scope.$setActive(pane.name || 0);\n }\n self.$panes.push(pane);\n };\n\n self.$remove = function (pane) {\n var index = self.$panes.indexOf(pane);\n var active = self.$panes.$active;\n var activeIndex;\n if (angular.isString(active)) {\n activeIndex = self.$panes.map(function (pane) {\n return pane.name;\n }).indexOf(active);\n } else {\n activeIndex = self.$panes.$active;\n }\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to\n // decrement the active pane index\n activeIndex--;\n } else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n if (activeIndex >= 0 && activeIndex < self.$panes.length) {\n self.$setActive(self.$panes[activeIndex].name || activeIndex);\n } else {\n self.$setActive();\n }\n };\n\n self.$setActive = $scope.$setActive = function (value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n self.$isActive = $scope.$isActive = function ($pane, $index) {\n return self.$panes.$active === $pane.name || self.$panes.$active === $index;\n };\n\n };\n\n this.$get = function () {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function ($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function (element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink (scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // 'ngModel' does interfere with form validation\n // and status, use `bsActivePane` instead to avoid it\n if (ngModelCtrl) {\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function (newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function ($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function (newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Save tab name into scope\n scope.name = attrs.name;\n\n // Add animation class\n if (bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n attrs.$observe('disabled', function (newValue, oldValue) {\n scope.disabled = scope.$eval(newValue);\n });\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function () {\n bsTabsCtrl.$remove(scope);\n });\n\n function render () {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n render();\n });\n render();\n\n }\n };\n\n });\n\n// Source: tooltip/tooltip.js\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n titleTemplate: false,\n trigger: 'hover focus',\n keyboard: false,\n html: false,\n show: false,\n title: '',\n type: '',\n delay: 0,\n autoClose: false,\n bsEnabled: true,\n mouseDownPreventDefault: true,\n mouseDownStopPropagation: true,\n viewport: {\n selector: 'body',\n padding: 0\n }\n };\n\n this.$get = function ($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n var $body = angular.element($window.document);\n\n function TooltipFactory (element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if (options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if (options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function (isEnabled) {\n scope.$$postDigest(function () {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function () {\n scope.$$postDigest(function () {\n $tooltip.hide();\n });\n };\n scope.$show = function () {\n scope.$$postDigest(function () {\n $tooltip.show();\n });\n };\n scope.$toggle = function () {\n scope.$$postDigest(function () {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout;\n var hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData;\n var tipElement;\n var tipContainer;\n var tipScope;\n promise.then(function (data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function () {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if (options.container === 'self') {\n tipContainer = element;\n } else if (angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if (options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if (options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if (options.show) {\n scope.$$postDigest(function () {\n if (options.trigger === 'focus') {\n element[0].focus();\n } else {\n $tooltip.show();\n }\n });\n }\n\n };\n\n $tooltip.destroy = function () {\n\n // Unbind events\n unbindTriggerEvents();\n\n // Remove element\n destroyTipElement();\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $tooltip.enter = function () {\n\n clearTimeout(timeout);\n hoverState = 'in';\n if (!options.delay || !options.delay.show) {\n return $tooltip.show();\n }\n\n timeout = setTimeout(function () {\n if (hoverState === 'in') $tooltip.show();\n }, options.delay.show);\n\n };\n\n $tooltip.show = function () {\n if (!options.bsEnabled || $tooltip.$isShown) return;\n\n scope.$emit(options.prefixEvent + '.show.before', $tooltip);\n if (angular.isDefined(options.onBeforeShow) && angular.isFunction(options.onBeforeShow)) {\n options.onBeforeShow($tooltip);\n }\n var parent;\n var after;\n if (options.container) {\n parent = tipContainer;\n if (tipContainer[0].lastChild) {\n after = angular.element(tipContainer[0].lastChild);\n } else {\n after = null;\n }\n } else {\n parent = null;\n after = element;\n }\n\n\n // Hide any existing tipElement\n if (tipElement) destroyTipElement();\n // Fetch a cloned element linked from template\n tipScope = $tooltip.$scope.$new();\n tipElement = $tooltip.$element = compileData.link(tipScope, function (clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if (options.animation) tipElement.addClass(options.animation);\n // Options: type\n if (options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if (options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n if (after) {\n after.after(tipElement);\n } else {\n parent.prepend(tipElement);\n }\n\n $tooltip.$isShown = scope.$isShown = true;\n safeDigest(scope);\n\n // Now, apply placement\n $tooltip.$applyPlacement();\n\n // Once placed, animate it.\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.enter(tipElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(tipElement, parent, after).then(enterAnimateCallback);\n }\n safeDigest(scope);\n\n $$rAF(function () {\n // Once the tooltip is placed and the animation starts, make the tooltip visible\n if (tipElement) tipElement.css({visibility: 'visible'});\n\n // Bind events\n if (options.keyboard) {\n if (options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n });\n\n if (options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback () {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n if (angular.isDefined(options.onShow) && angular.isFunction(options.onShow)) {\n options.onShow($tooltip);\n }\n }\n\n $tooltip.leave = function () {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function (blur) {\n\n if (!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n if (angular.isDefined(options.onBeforeHide) && angular.isFunction(options.onBeforeHide)) {\n options.onBeforeHide($tooltip);\n }\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if (options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if (options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback () {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n if (angular.isDefined(options.onHide) && angular.isFunction(options.onHide)) {\n options.onHide($tooltip);\n }\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if (_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function (evt) {\n if (evt) { evt.preventDefault(); }\n if ($tooltip.$isShown) {\n $tooltip.leave();\n } else {\n $tooltip.enter();\n }\n };\n\n $tooltip.focus = function () {\n tipElement[0].focus();\n };\n\n $tooltip.setEnabled = function (isEnabled) {\n options.bsEnabled = isEnabled;\n };\n\n $tooltip.setViewport = function (viewport) {\n options.viewport = viewport;\n };\n\n // Protected methods\n\n $tooltip.$applyPlacement = function () {\n if (!tipElement) return;\n\n // Determine if we're doing an auto or normal placement\n var placement = options.placement;\n var autoToken = /\\s?auto?\\s?/i;\n var autoPlace = autoToken.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(autoToken, '') || defaults.placement;\n }\n\n // Need to add the position class before we get\n // the offsets\n tipElement.addClass(options.placement);\n\n // Get the position of the target element\n // and the height and width of the tooltip so we can center it.\n var elementPosition = getPosition();\n var tipWidth = tipElement.prop('offsetWidth');\n var tipHeight = tipElement.prop('offsetHeight');\n\n // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n if (/bottom/.test(originalPlacement) && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (/top/.test(originalPlacement) && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n if (/left/.test(originalPlacement) && elementPosition.left - tipWidth < viewportPosition.left) {\n placement = placement.replace('left', 'right');\n } else if (/right/.test(originalPlacement) && elementPosition.right + tipWidth > viewportPosition.width) {\n placement = placement.replace('right', 'left');\n }\n\n tipElement.removeClass(originalPlacement).addClass(placement);\n }\n\n // Get the tooltip's top and left coordinates to center it with this directive.\n var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight);\n applyPlacement(tipPosition, placement);\n };\n\n $tooltip.$onKeyUp = function (evt) {\n if (evt.which === 27 && $tooltip.$isShown) {\n $tooltip.hide();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusKeyUp = function (evt) {\n if (evt.which === 27) {\n element[0].blur();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusElementMouseDown = function (evt) {\n if (options.mouseDownPreventDefault) { evt.preventDefault(); }\n if (options.mouseDownStopPropagation) { evt.stopPropagation(); }\n // Some browsers do not auto-focus buttons (eg. Safari)\n if ($tooltip.$isShown) {\n element[0].blur();\n } else {\n element[0].focus();\n }\n };\n\n // bind/unbind events\n function bindTriggerEvents () {\n var triggers = options.trigger.split(' ');\n angular.forEach(triggers, function (trigger) {\n if (trigger === 'click' || trigger === 'contextmenu') {\n element.on(trigger, $tooltip.toggle);\n } else if (trigger !== 'manual') {\n element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n if (nodeName === 'button' && trigger !== 'hover') {\n element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n });\n }\n\n function unbindTriggerEvents () {\n var triggers = options.trigger.split(' ');\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i];\n if (trigger === 'click' || trigger === 'contextmenu') {\n element.off(trigger, $tooltip.toggle);\n } else if (trigger !== 'manual') {\n element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n if (nodeName === 'button' && trigger !== 'hover') {\n element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n }\n }\n\n function bindKeyboardEvents () {\n if (options.trigger !== 'focus') {\n tipElement.on('keyup', $tooltip.$onKeyUp);\n } else {\n element.on('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n function unbindKeyboardEvents () {\n if (options.trigger !== 'focus') {\n tipElement.off('keyup', $tooltip.$onKeyUp);\n } else {\n element.off('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n var _autoCloseEventsBinded = false;\n function bindAutoCloseEvents () {\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n // Stop propagation when clicking inside tooltip\n tipElement.on('click', stopEventPropagation);\n\n // Hide when clicking outside tooltip\n $body.on('click', $tooltip.hide);\n\n _autoCloseEventsBinded = true;\n }, 0, false);\n }\n\n function unbindAutoCloseEvents () {\n if (_autoCloseEventsBinded) {\n tipElement.off('click', stopEventPropagation);\n $body.off('click', $tooltip.hide);\n _autoCloseEventsBinded = false;\n }\n }\n\n function stopEventPropagation (event) {\n event.stopPropagation();\n }\n\n // Private methods\n\n function getPosition ($element) {\n $element = $element || (options.target || element);\n\n var el = $element[0];\n var isBody = el.tagName === 'BODY';\n\n var elRect = el.getBoundingClientRect();\n var rect = {};\n\n // IE8 has issues with angular.extend and using elRect directly.\n // By coping the values of elRect into a new object, we can continue to use extend\n /* eslint-disable guard-for-in */\n for (var p in elRect) { // eslint-disable-line\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n /* eslint-enable guard-for-in */\n\n if (rect.width === null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n rect = angular.extend({}, rect, {width: elRect.right - elRect.left, height: elRect.bottom - elRect.top});\n }\n var elOffset = isBody ? {top: 0, left: 0} : dimensions.offset(el);\n var scroll = {scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0};\n var outerDims = isBody ? {width: document.documentElement.clientWidth, height: $window.innerHeight} : null;\n\n return angular.extend({}, rect, scroll, outerDims, elOffset);\n }\n\n function getCalculatedOffset (placement, position, actualWidth, actualHeight) {\n var offset;\n var split = placement.split('-');\n\n switch (split[0]) {\n case 'right':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left + position.width\n };\n break;\n case 'bottom':\n offset = {\n top: position.top + position.height,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n case 'left':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left - actualWidth\n };\n break;\n default:\n offset = {\n top: position.top - actualHeight,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n }\n\n if (!split[1]) {\n return offset;\n }\n\n // Add support for corners @todo css\n if (split[0] === 'top' || split[0] === 'bottom') {\n switch (split[1]) {\n case 'left':\n offset.left = position.left;\n break;\n case 'right':\n offset.left = position.left + position.width - actualWidth;\n break;\n default:\n break;\n }\n } else if (split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight + position.height;\n break;\n case 'bottom':\n offset.top = position.top;\n break;\n default:\n break;\n }\n }\n\n return offset;\n }\n\n function applyPlacement (offset, placement) {\n var tip = tipElement[0];\n var width = tip.offsetWidth;\n var height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10);\n var marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10);\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0;\n if (isNaN(marginLeft)) marginLeft = 0;\n\n offset.top = offset.top + marginTop;\n offset.left = offset.left + marginLeft;\n\n // dimensions setOffset doesn't round pixel values\n // so we use setOffset directly with our own function\n dimensions.setOffset(tip, angular.extend({\n using: function (props) {\n tipElement.css({\n top: Math.round(props.top) + 'px',\n left: Math.round(props.left) + 'px',\n right: ''\n });\n }\n }, offset), 0);\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = tip.offsetWidth;\n var actualHeight = tip.offsetHeight;\n\n if (placement === 'top' && actualHeight !== height) {\n offset.top = offset.top + height - actualHeight;\n }\n\n // If it's an exotic placement, exit now instead of\n // applying a delta and changing the arrow\n if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return;\n\n var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);\n\n if (delta.left) {\n offset.left += delta.left;\n } else {\n offset.top += delta.top;\n }\n\n dimensions.setOffset(tip, offset);\n\n if (/top|right|bottom|left/.test(placement)) {\n var isVertical = /top|bottom/.test(placement);\n var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight;\n var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta (placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow (delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement () {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if ($tooltip.$isShown && tipElement !== null) {\n if (options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if (options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if (tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if (tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function ($window, $location, $sce, $parse, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n var tooltip;\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'titleTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if (angular.isDefined(dataTarget)) {\n if (falseValueRegExp.test(dataTarget)) {\n options.target = false;\n } else {\n options.target = dataTarget;\n }\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')) {\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function (newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n if (angular.isDefined(oldValue)) {\n $$rAF(function () {\n if (tooltip) tooltip.$applyPlacement();\n });\n }\n }\n });\n\n attr.$observe('disabled', function (newValue) {\n if (newValue && tooltip.$isShown) {\n tooltip.hide();\n }\n });\n\n // Support scope as an object\n if (attr.bsTooltip) {\n scope.$watch(attr.bsTooltip, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n if (angular.isDefined(oldValue)) {\n $$rAF(function () {\n if (tooltip) tooltip.$applyPlacement();\n });\n }\n }, true);\n }\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!tooltip || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n if (newValue === true) {\n tooltip.show();\n } else {\n tooltip.hide();\n }\n });\n }\n\n // Enabled binding support\n if (attr.bsEnabled) {\n scope.$watch(attr.bsEnabled, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if (!tooltip || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n if (newValue === false) {\n tooltip.setEnabled(false);\n } else {\n tooltip.setEnabled(true);\n }\n });\n }\n\n // Viewport support\n if (attr.viewport) {\n scope.$watch(attr.viewport, function (newValue) {\n if (!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n }\n\n // Initialize popover\n tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n\n// Source: timepicker/timepicker.js\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n defaultDate: 'auto',\n // uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function ($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory (element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function (date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes (time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format);\n var timeSeparator = $dateFormatter.timeSeparator(format);\n var minutesFormat = $dateFormatter.minutesFormat(format);\n var secondsFormat = $dateFormatter.secondsFormat(format);\n var showSeconds = $dateFormatter.showSeconds(format);\n var showAM = $dateFormatter.showAM(format);\n\n scope.$iconUp = options.iconUp;\n scope.$iconDown = options.iconDown;\n\n // Scope methods\n\n scope.$select = function (date, index) {\n $timepicker.select(date, index);\n };\n scope.$moveIndex = function (value, index) {\n $timepicker.$moveIndex(value, index);\n };\n scope.$switchMeridian = function (date) {\n $timepicker.switchMeridian(date);\n };\n\n // Public methods\n\n $timepicker.update = function (date) {\n // console.warn('$timepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $timepicker.$date = date;\n angular.extend(viewDate, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function (date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n controller.$dateValue = options.defaultDate === 'today' ? new Date() : new Date(1970, 0, 1);\n }\n\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function () {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function (date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function () {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i;\n var midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [];\n var hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [];\n var minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [];\n var second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function (date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function (date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function (value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function (value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function (value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function (evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours();\n var hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes();\n var minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds();\n var secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection (start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement () {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function () {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function () {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function () {\n if ((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n if ($timepicker.$element) $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n if (element) element.on('keydown', $timepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $timepicker.hide;\n $timepicker.hide = function (blur) {\n if (!$timepicker.$isShown) return;\n if ($timepicker.$element) $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n if (element) element.off('keydown', $timepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $timepicker;\n\n }\n\n timepickerFactory.defaults = defaults;\n return timepickerFactory;\n\n };\n\n })\n\n\n .directive('bsTimepicker', function ($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {\n\n var defaults = $timepicker.defaults;\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent', 'defaultDate'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Initialize timepicker\n if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';\n var timepicker = $timepicker(element, controller, options);\n options = timepicker.$options;\n\n var lang = options.lang;\n var formatDate = function (date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!timepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);\n if (newValue === true) {\n timepicker.show();\n } else {\n timepicker.hide();\n }\n });\n }\n\n // Initialize parser\n var dateParser = $dateParser({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function (key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n if (angular.isDefined(attr[key])) {\n attr.$observe(key, function (newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n if (!isNaN(timepicker.$options[key])) timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\n }\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);\n timepicker.update(controller.$dateValue);\n }, true);\n\n function validateAgainstMinMaxTime (parsedTime) {\n if (!angular.isDate(parsedTime)) return;\n var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;\n var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (!isValid) {\n return;\n }\n controller.$dateValue = parsedTime;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function (viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n controller.$setValidity('date', true);\n return null;\n }\n var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedTime || isNaN(parsedTime.getTime())) {\n controller.$setValidity('date', false);\n // Return undefined, causes ngModelController to\n // invalidate model value\n return undefined;\n }\n validateAgainstMinMaxTime(parsedTime);\n\n if (options.timeType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true);\n return formatDate(date, options.modelTimeFormat || options.timeFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.timeType === 'number') {\n return date.getTime();\n } else if (options.timeType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.timeType === 'iso') {\n return date.toISOString();\n }\n return new Date(date);\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function () {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString () {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n\n// Source: scrollspy/scrollspy.js\nangular.module('mgcrea.ngStrap.scrollspy', ['mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$scrollspy', function () {\n\n // Pool of registered spies\n var spies = this.$$spies = {};\n\n var defaults = this.defaults = {\n debounce: 150,\n throttle: 100,\n offset: 100\n };\n\n this.$get = function ($window, $document, $rootScope, dimensions, debounce, throttle) {\n\n var windowEl = angular.element($window);\n var docEl = angular.element($document.prop('documentElement'));\n var bodyEl = angular.element($window.document.body);\n\n // Helper functions\n\n function nodeName (element, name) {\n return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase();\n }\n\n function ScrollSpyFactory (config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n if (!options.element) options.element = bodyEl;\n var isWindowSpy = nodeName(options.element, 'body');\n var scrollEl = isWindowSpy ? windowEl : options.element;\n var scrollId = isWindowSpy ? 'window' : options.id;\n\n // Use existing spy\n if (spies[scrollId]) {\n spies[scrollId].$$count++;\n return spies[scrollId];\n }\n\n var $scrollspy = {};\n\n // Private vars\n var unbindViewContentLoaded;\n var unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n /* eslint-disable no-unused-vars */\n var viewportHeight;\n /* eslint-enable no-unused-vars */\n var scrollTop;\n\n $scrollspy.init = function () {\n\n // Setup internal ref counter\n this.$$count = 1;\n\n // Bind events\n debouncedCheckPosition = debounce(this.checkPosition, options.debounce);\n throttledCheckPosition = throttle(this.checkPosition, options.throttle);\n scrollEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', debouncedCheckPosition);\n scrollEl.on('scroll', throttledCheckPosition);\n\n debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce);\n unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets);\n unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets);\n debouncedCheckOffsets();\n\n // Register spy for reuse\n if (scrollId) {\n spies[scrollId] = $scrollspy;\n }\n\n };\n\n $scrollspy.destroy = function () {\n\n // Check internal ref counter\n this.$$count--;\n if (this.$$count > 0) {\n return;\n }\n\n // Unbind events\n scrollEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', debouncedCheckPosition);\n scrollEl.off('scroll', throttledCheckPosition);\n unbindViewContentLoaded();\n unbindIncludeContentLoaded();\n if (scrollId) {\n delete spies[scrollId];\n }\n };\n\n $scrollspy.checkPosition = function () {\n\n // Not ready yet\n if (!sortedElements.length) return;\n\n // Calculate the scroll position\n scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0;\n\n // Calculate the viewport height for use by the components\n viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight'));\n\n // Activate first element if scroll is smaller\n if (scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) {\n return $scrollspy.$activateElement(sortedElements[0]);\n }\n\n // Activate proper element\n for (var i = sortedElements.length; i--;) {\n if (angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue;\n if (activeTarget === sortedElements[i].target) continue;\n if (scrollTop < sortedElements[i].offsetTop) continue;\n if (sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue;\n return $scrollspy.$activateElement(sortedElements[i]);\n }\n\n };\n\n $scrollspy.checkPositionWithEventLoop = function () {\n // IE 9 throws an error if we use 'this' instead of '$scrollspy'\n // in this setTimeout call\n setTimeout($scrollspy.checkPosition, 1);\n };\n\n // Protected methods\n\n $scrollspy.$activateElement = function (element) {\n if (activeTarget) {\n var activeElement = $scrollspy.$getTrackedElement(activeTarget);\n if (activeElement) {\n activeElement.source.removeClass('active');\n if (nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) {\n activeElement.source.parent().parent().removeClass('active');\n }\n }\n }\n activeTarget = element.target;\n element.source.addClass('active');\n if (nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) {\n element.source.parent().parent().addClass('active');\n }\n };\n\n $scrollspy.$getTrackedElement = function (target) {\n return trackedElements.filter(function (obj) {\n return obj.target === target;\n })[0];\n };\n\n // Track offsets behavior\n\n $scrollspy.checkOffsets = function () {\n\n angular.forEach(trackedElements, function (trackedElement) {\n var targetElement = document.querySelector(trackedElement.target);\n trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null;\n if (options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1;\n });\n\n sortedElements = trackedElements\n .filter(function (el) {\n return el.offsetTop !== null;\n })\n .sort(function (a, b) {\n return a.offsetTop - b.offsetTop;\n });\n\n debouncedCheckPosition();\n\n };\n\n $scrollspy.trackElement = function (target, source) {\n trackedElements.push({target: target, source: source});\n };\n\n $scrollspy.untrackElement = function (target, source) {\n var toDelete;\n for (var i = trackedElements.length; i--;) {\n if (trackedElements[i].target === target && trackedElements[i].source === source) {\n toDelete = i;\n break;\n }\n }\n trackedElements.splice(toDelete, 1);\n };\n\n $scrollspy.activate = function (i) {\n trackedElements[i].addClass('active');\n };\n\n // Initialize plugin\n\n $scrollspy.init();\n return $scrollspy;\n\n }\n\n return ScrollSpyFactory;\n\n };\n\n })\n\n .directive('bsScrollspy', function ($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'EAC',\n link: function postLink (scope, element, attr) {\n\n var options = {scope: scope};\n angular.forEach(['offset', 'target'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n var scrollspy = $scrollspy(options);\n scrollspy.trackElement(options.target, element);\n\n scope.$on('$destroy', function () {\n if (scrollspy) {\n scrollspy.untrackElement(options.target, element);\n scrollspy.destroy();\n }\n options = null;\n scrollspy = null;\n });\n\n }\n };\n\n })\n\n\n .directive('bsScrollspyList', function ($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'A',\n compile: function postLink (element, attr) {\n var children = element[0].querySelectorAll('li > a[href]');\n angular.forEach(children, function (child) {\n var childEl = angular.element(child);\n childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href'));\n });\n }\n\n };\n\n });\n\n// Source: select/select.js\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' ',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok',\n toggle: false\n };\n\n this.$get = function ($window, $document, $rootScope, $tooltip, $timeout) {\n\n // var bodyEl = angular.element($window.document.body);\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n\n function SelectFactory (element, controller, config) {\n\n var $select = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $select = $tooltip(element, options);\n var scope = $select.$scope;\n\n scope.$matches = [];\n if (options.multiple) {\n scope.$activeIndex = [];\n } else {\n scope.$activeIndex = -1;\n }\n scope.$isMultiple = options.multiple;\n scope.$showAllNoneButtons = options.allNoneButtons && options.multiple;\n scope.$iconCheckmark = options.iconCheckmark;\n scope.$allText = options.allText;\n scope.$noneText = options.noneText;\n\n scope.$activate = function (index) {\n scope.$$postDigest(function () {\n $select.activate(index);\n });\n };\n\n scope.$select = function (index, evt) {\n scope.$$postDigest(function () {\n $select.select(index);\n });\n };\n\n scope.$isVisible = function () {\n return $select.$isVisible();\n };\n\n scope.$isActive = function (index) {\n return $select.$isActive(index);\n };\n\n scope.$selectAll = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (!scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n scope.$selectNone = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n // Public methods\n\n $select.update = function (matches) {\n scope.$matches = matches;\n $select.$updateActiveIndex();\n };\n\n $select.activate = function (index) {\n if (options.multiple) {\n if ($select.$isActive(index)) {\n scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1);\n } else {\n scope.$activeIndex.push(index);\n }\n if (options.sort) scope.$activeIndex.sort(function (a, b) { return a - b; }); // use numeric sort instead of default sort\n } else {\n scope.$activeIndex = index;\n }\n return scope.$activeIndex;\n };\n\n $select.select = function (index) {\n if (angular.isUndefined(index) || index < 0 || index >= scope.$matches.length) { return; }\n var value = scope.$matches[index].value;\n scope.$apply(function () {\n $select.activate(index);\n if (options.multiple) {\n controller.$setViewValue(scope.$activeIndex.map(function (index) {\n if (angular.isUndefined(scope.$matches[index])) {\n return null;\n }\n return scope.$matches[index].value;\n }));\n } else {\n if (options.toggle) {\n controller.$setViewValue((value === controller.$modelValue) ? undefined : value);\n } else {\n controller.$setViewValue(value);\n }\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n if (angular.isDefined(options.onSelect) && angular.isFunction(options.onSelect)) {\n options.onSelect(value, index, $select);\n }\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function () {\n if (options.multiple) {\n if (angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function (value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = [];\n }\n } else {\n if (angular.isDefined(controller.$modelValue) && scope.$matches.length) {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n } else {\n scope.$activeIndex = -1;\n }\n }\n };\n\n $select.$isVisible = function () {\n if (!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function (index) {\n if (options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n }\n return scope.$activeIndex === index;\n };\n\n $select.$getIndex = function (value) {\n var index;\n for (index = scope.$matches.length; index--;) {\n if (angular.equals(scope.$matches[index].value, value)) break;\n }\n return index;\n };\n\n $select.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n targetEl.triggerHandler('click');\n }\n };\n\n $select.$onKeyDown = function (evt) {\n if (!/(9|13|38|40)/.test(evt.keyCode)) return;\n // Let tab propagate\n if (evt.keyCode !== 9) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if (!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if (evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n $select.$isIE = function () {\n var ua = $window.navigator.userAgent;\n return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0;\n };\n\n $select.$selectScrollFix = function (e) {\n if ($document[0].activeElement.tagName === 'UL') {\n e.preventDefault();\n e.stopImmediatePropagation();\n e.target.focus();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function () {\n _show();\n if (options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if (options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function () {\n if (!options.multiple && angular.isUndefined(controller.$modelValue)) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if (options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function ($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent', 'toggle'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // bind functions from the attrs to the show, hide and select events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide', 'onSelect'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Only parse data-multiple. Angular sets existence attributes to true (multiple/required/etc), they apply this\n // to data-multiple as well for some reason, so we'll parse this ourselves and disregard multiple\n var dataMultiple = element.attr('data-multiple');\n if (angular.isDefined(dataMultiple)) {\n if (falseValueRegExp.test(dataMultiple)) {\n options.multiple = false;\n } else {\n options.multiple = dataMultiple;\n }\n }\n\n // Add support for select markup\n if (element[0].nodeName.toLowerCase() === 'select') {\n var inputEl = element;\n inputEl.css('display', 'none');\n element = angular.element('');\n inputEl.after(element);\n }\n\n // Build proper bsOptions\n var parsedOptions = $parseOptions(attr.bsOptions);\n\n // Initialize select\n var select = $select(element, controller, options);\n\n if (select.$isIE()) {\n element[0].addEventListener('blur', select.$selectScrollFix);\n }\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watch(watchedOptions, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller)\n .then(function (values) {\n select.update(values);\n controller.$render();\n });\n }, true);\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);\n select.$updateActiveIndex();\n controller.$render();\n }, true);\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var selected;\n var index;\n if (options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function (value) {\n index = select.$getIndex(value);\n return index !== -1 ? select.$scope.$matches[index].label : false;\n }).filter(angular.isDefined);\n if (selected.length > (options.maxLength || defaults.maxLength)) {\n selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);\n } else {\n selected = selected.join(', ');\n }\n } else {\n index = select.$getIndex(controller.$modelValue);\n selected = index !== -1 ? select.$scope.$matches[index].label : false;\n }\n element.html((selected || options.placeholder) + (options.caretHtml || defaults.caretHtml));\n };\n\n if (options.multiple) {\n controller.$isEmpty = function (value) {\n return !value || value.length === 0;\n };\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (select) select.destroy();\n options = null;\n select = null;\n });\n\n }\n };\n\n });\n\n// Source: popover/popover.js\nangular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function ($tooltip) {\n\n function PopoverFactory (element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if (options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function ($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr) {\n\n var popover;\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if (angular.isDefined(dataTarget)) {\n if (falseValueRegExp.test(dataTarget)) {\n options.target = false;\n } else {\n options.target = dataTarget;\n }\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n if (angular.isDefined(oldValue)) {\n requestAnimationFrame(function () {\n if (popover) popover.$applyPlacement();\n });\n }\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsPopover) {\n scope.$watch(attr.bsPopover, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n if (angular.isDefined(oldValue)) {\n requestAnimationFrame(function () {\n if (popover) popover.$applyPlacement();\n });\n }\n }, true);\n }\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!popover || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);\n if (newValue === true) {\n popover.show();\n } else {\n popover.hide();\n }\n });\n }\n\n // Viewport support\n if (attr.viewport) {\n scope.$watch(attr.viewport, function (newValue) {\n if (!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n }\n\n // Initialize popover\n popover = $popover(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (popover) popover.destroy();\n options = null;\n popover = null;\n });\n\n }\n };\n\n });\n\n// Source: navbar/navbar.js\nangular.module('mgcrea.ngStrap.navbar', [])\n\n .provider('$navbar', function () {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n routeAttr: 'data-match-route',\n strict: false\n };\n\n this.$get = function () {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsNavbar', function ($window, $location, $navbar) {\n\n var defaults = $navbar.defaults;\n\n return {\n restrict: 'A',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = angular.copy(defaults);\n angular.forEach(Object.keys(defaults), function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Watch for the $location\n scope.$watch(function () {\n\n return $location.path();\n\n }, function (newValue, oldValue) {\n\n var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']');\n\n angular.forEach(liElements, function (li) {\n\n var liElement = angular.element(li);\n var pattern = liElement.attr(options.routeAttr).replace('/', '\\\\/');\n if (options.strict) {\n pattern = '^' + pattern + '$';\n }\n var regexp = new RegExp(pattern, 'i');\n\n if (regexp.test(newValue)) {\n liElement.addClass(options.activeClass);\n } else {\n liElement.removeClass(options.activeClass);\n }\n\n });\n\n });\n\n }\n\n };\n\n });\n\n// Source: modal/modal.js\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n customClass: '',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true,\n size: null\n };\n\n this.$get = function ($window, $rootScope, $bsCompiler, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n\n var backdropCount = 0;\n var dialogBaseZindex = 1050;\n var backdropBaseZindex = 1040;\n\n var validSizes = {\n lg: 'modal-lg',\n sm: 'modal-sm'\n };\n\n function ModalFactory (config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if (!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function (key) {\n if (options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function () {\n scope.$$postDigest(function () {\n $modal.hide();\n });\n };\n scope.$show = function () {\n scope.$$postDigest(function () {\n $modal.show();\n });\n };\n scope.$toggle = function () {\n scope.$$postDigest(function () {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData;\n var modalElement;\n var modalScope;\n var backdropElement = angular.element('
');\n backdropElement.css({position: 'fixed', top: '0px', left: '0px', bottom: '0px', right: '0px'});\n promise.then(function (data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function () {\n\n // Options: show\n if (options.show) {\n scope.$$postDigest(function () {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function () {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if (backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function () {\n if ($modal.$isShown) return;\n\n var parent;\n var after;\n if (angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if (modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function (clonedElement, scope) {});\n\n if (options.backdrop) {\n // set z-index\n modalElement.css({'z-index': dialogBaseZindex + (backdropCount * 20)});\n backdropElement.css({'z-index': backdropBaseZindex + (backdropCount * 20)});\n\n // increment number of backdrops\n backdropCount++;\n }\n\n if (scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) {\n return;\n }\n if (angular.isDefined(options.onBeforeShow) && angular.isFunction(options.onBeforeShow)) {\n options.onBeforeShow($modal);\n }\n\n // Set the initial positioning.\n modalElement.css({display: 'block'}).addClass(options.placement);\n\n // Options: customClass\n if (options.customClass) {\n modalElement.addClass(options.customClass);\n }\n\n // Options: size\n if (options.size && validSizes[options.size]) {\n angular.element(findElement('.modal-dialog', modalElement[0])).addClass(validSizes[options.size]);\n }\n\n // Options: animation\n if (options.animation) {\n if (options.backdrop) {\n backdropElement.addClass(options.backdropAnimation);\n }\n modalElement.addClass(options.animation);\n }\n\n if (options.backdrop) {\n $animate.enter(backdropElement, bodyElement, null);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.enter(modalElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(modalElement, parent, after).then(enterAnimateCallback);\n }\n\n $modal.$isShown = scope.$isShown = true;\n safeDigest(scope);\n // Focus once the enter-animation has started\n // Weird PhantomJS bug hack\n var el = modalElement[0];\n requestAnimationFrame(function () {\n el.focus();\n });\n\n bodyElement.addClass(options.prefixClass + '-open');\n if (options.animation) {\n bodyElement.addClass(options.prefixClass + '-with-' + options.animation);\n }\n\n // Bind events\n bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback () {\n scope.$emit(options.prefixEvent + '.show', $modal);\n if (angular.isDefined(options.onShow) && angular.isFunction(options.onShow)) {\n options.onShow($modal);\n }\n }\n\n $modal.hide = function () {\n if (!$modal.$isShown) return;\n\n if (scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n if (angular.isDefined(options.onBeforeHide) && angular.isFunction(options.onBeforeHide)) {\n options.onBeforeHide($modal);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if (options.backdrop) {\n // decrement number of backdrops\n backdropCount--;\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback () {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n if (angular.isDefined(options.onHide) && angular.isFunction(options.onHide)) {\n options.onHide($modal);\n }\n bodyElement.removeClass(options.prefixClass + '-open');\n if (options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function () {\n if ($modal.$isShown) {\n $modal.hide();\n } else {\n $modal.show();\n }\n };\n\n $modal.focus = function () {\n modalElement[0].focus();\n };\n\n // Protected methods\n\n $modal.$onKeyUp = function (evt) {\n\n if (evt.which === 27 && $modal.$isShown) {\n $modal.hide();\n evt.stopPropagation();\n }\n\n };\n\n function bindBackdropEvents () {\n if (options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents () {\n if (options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents () {\n if (options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents () {\n if (options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private helpers\n\n function hideOnBackdropClick (evt) {\n if (evt.target !== evt.currentTarget) return;\n if (options.backdrop === 'static') {\n $modal.focus();\n } else {\n $modal.hide();\n }\n }\n\n function preventEventDefault (evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement () {\n if ($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if (modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if (modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function ($window, $sce, $parse, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass', 'customClass', 'modalClass', 'size'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Options: alias modalClass to customClass\n if (options.modalClass) {\n options.customClass = options.modalClass;\n }\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsModal) {\n scope.$watch(attr.bsModal, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize modal\n var modal = $modal(options);\n\n // Trigger\n element.on(attr.trigger || 'click', modal.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (modal) modal.destroy();\n options = null;\n modal = null;\n });\n\n }\n };\n\n });\n\n// Source: dropdown/dropdown.js\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function ($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory (element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n /* var scope = */$dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function (evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if (!items.length) return;\n var index;\n angular.forEach(items, function (el, i) {\n if (matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if (evt.keyCode === 38 && index > 0) index--;\n else if (evt.keyCode === 40 && index < items.length - 1) index++;\n else if (angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function () {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n if (options.keyboard && $dropdown.$element) $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n if (parentEl.hasClass('dropdown')) parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function () {\n if (!$dropdown.$isShown) return;\n if (options.keyboard && $dropdown.$element) $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n if (parentEl.hasClass('dropdown')) parentEl.removeClass('open');\n hide();\n };\n\n var destroy = $dropdown.destroy;\n $dropdown.destroy = function () {\n bodyEl.off('click', onBodyClick);\n destroy();\n };\n\n // Private functions\n\n function onBodyClick (evt) {\n if (evt.target === element[0]) return;\n return evt.target !== element[0] && $dropdown.hide();\n }\n\n return $dropdown;\n\n }\n\n return DropdownFactory;\n\n };\n\n })\n\n .directive('bsDropdown', function ($window, $sce, $dropdown) {\n\n return {\n restrict: 'EAC',\n scope: true,\n compile: function (tElement, tAttrs) {\n\n // Support for inlined template (next sibling)\n // It must be fetched before compilation\n if (!tAttrs.bsDropdown) {\n var nextSibling = tElement[0].nextSibling;\n while (nextSibling && nextSibling.nodeType !== 1) {\n nextSibling = nextSibling.nextSibling;\n }\n if (nextSibling && nextSibling.className.split(' ').indexOf('dropdown-menu') >= 0) {\n tAttrs.template = nextSibling.outerHTML;\n tAttrs.templateUrl = undefined;\n nextSibling.parentNode.removeChild(nextSibling);\n }\n }\n\n return function postLink (scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id', 'autoClose'], function (key) {\n if (angular.isDefined(tAttrs[key])) options[key] = tAttrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Support scope as an object\n if (attr.bsDropdown) {\n scope.$watch(attr.bsDropdown, function (newValue, oldValue) {\n scope.content = newValue;\n }, true);\n }\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!dropdown || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);\n if (newValue === true) {\n dropdown.show();\n } else {\n dropdown.hide();\n }\n });\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (dropdown) dropdown.destroy();\n options = null;\n dropdown = null;\n });\n\n };\n }\n };\n\n });\n\n// Source: helpers/raf.js\nif (angular.version.minor < 3 && angular.version.dot < 14) {\n angular.module('ng')\n\n .factory('$$rAF', function ($window, $timeout) {\n\n var requestAnimationFrame = $window.requestAnimationFrame ||\n $window.webkitRequestAnimationFrame ||\n $window.mozRequestAnimationFrame;\n\n var cancelAnimationFrame = $window.cancelAnimationFrame ||\n $window.webkitCancelAnimationFrame ||\n $window.mozCancelAnimationFrame ||\n $window.webkitCancelRequestAnimationFrame;\n\n var rafSupported = !!requestAnimationFrame;\n var raf = rafSupported ?\n function (fn) {\n var id = requestAnimationFrame(fn);\n return function () {\n cancelAnimationFrame(id);\n };\n } :\n function (fn) {\n var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666\n return function () {\n $timeout.cancel(timer);\n };\n };\n\n raf.supported = rafSupported;\n\n return raf;\n\n });\n}\n\n// Source: helpers/parse-options.js\nangular.module('mgcrea.ngStrap.helpers.parseOptions', [])\n\n .provider('$parseOptions', function () {\n\n var defaults = this.defaults = {\n regexp: /^\\s*(.*?)(?:\\s+as\\s+(.*?))?(?:\\s+group\\s+by\\s+(.*))?\\s+for\\s+(?:([\\$\\w][\\$\\w]*)|(?:\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)))\\s+in\\s+(.*?)(?:\\s+track\\s+by\\s+(.*?))?$/\n };\n\n this.$get = function ($parse, $q) {\n\n function ParseOptionsFactory (attr, config) {\n\n var $parseOptions = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n $parseOptions.$values = [];\n\n // Private vars\n var match;\n var displayFn;\n var valueName;\n /* eslint-disable no-unused-vars */\n var keyName;\n var groupByFn;\n /* eslint-enable no-unused-vars */\n var valueFn;\n var valuesFn;\n\n $parseOptions.init = function () {\n $parseOptions.$match = match = attr.match(options.regexp);\n displayFn = $parse(match[2] || match[1]);\n valueName = match[4] || match[6];\n keyName = match[5];\n groupByFn = $parse(match[3] || '');\n valueFn = $parse(match[2] ? match[1] : valueName);\n valuesFn = $parse(match[7]);\n };\n\n $parseOptions.valuesFn = function (scope, controller) {\n return $q.when(valuesFn(scope, controller))\n .then(function (values) {\n if (!angular.isArray(values)) {\n values = [];\n }\n $parseOptions.$values = values.length ? parseValues(values, scope) : [];\n return $parseOptions.$values;\n });\n };\n\n $parseOptions.displayValue = function (modelValue) {\n var scope = {};\n scope[valueName] = modelValue;\n return displayFn(scope);\n };\n\n // Private functions\n\n function parseValues (values, scope) {\n return values.map(function (match, index) {\n var locals = {};\n var label;\n var value;\n locals[valueName] = match;\n label = displayFn(scope, locals);\n value = valueFn(scope, locals);\n return {label: label, value: value, index: index};\n });\n }\n\n $parseOptions.init();\n return $parseOptions;\n\n }\n\n return ParseOptionsFactory;\n\n };\n\n });\n\n// Source: helpers/dimensions.js\nangular.module('mgcrea.ngStrap.helpers.dimensions', [])\n\n .factory('dimensions', function () {\n\n var fn = {};\n\n /**\n * Test the element nodeName\n * @param element\n * @param name\n */\n var nodeName = fn.nodeName = function (element, name) {\n return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase();\n };\n\n /**\n * Returns the element computed style\n * @param element\n * @param prop\n * @param extra\n */\n fn.css = function (element, prop, extra) {\n var value;\n if (element.currentStyle) { // IE\n value = element.currentStyle[prop];\n } else if (window.getComputedStyle) {\n value = window.getComputedStyle(element)[prop];\n } else {\n value = element.style[prop];\n }\n return extra === true ? parseFloat(value) || 0 : value;\n };\n\n /**\n * Provides read-only equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.offset = function (element) {\n var boxRect = element.getBoundingClientRect();\n var docElement = element.ownerDocument;\n return {\n width: boxRect.width || element.offsetWidth,\n height: boxRect.height || element.offsetHeight,\n top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0),\n left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0)\n };\n };\n\n /**\n * Provides set equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip\n * @url http://api.jquery.com/offset/\n * @param element\n * @param options\n * @param i\n */\n fn.setOffset = function (element, options, i) {\n var curPosition;\n var curLeft;\n var curCSSTop;\n var curTop;\n var curOffset;\n var curCSSLeft;\n var calculatePosition;\n var position = fn.css(element, 'position');\n var curElem = angular.element(element);\n var props = {};\n\n // Set position first, in-case top/left are set even on static elem\n if (position === 'static') {\n element.style.position = 'relative';\n }\n\n curOffset = fn.offset(element);\n curCSSTop = fn.css(element, 'top');\n curCSSLeft = fn.css(element, 'left');\n calculatePosition = (position === 'absolute' || position === 'fixed') &&\n (curCSSTop + curCSSLeft).indexOf('auto') > -1;\n\n // Need to be able to calculate position if either\n // top or left is auto and position is either absolute or fixed\n if (calculatePosition) {\n curPosition = fn.position(element);\n curTop = curPosition.top;\n curLeft = curPosition.left;\n } else {\n curTop = parseFloat(curCSSTop) || 0;\n curLeft = parseFloat(curCSSLeft) || 0;\n }\n\n if (angular.isFunction(options)) {\n options = options.call(element, i, curOffset);\n }\n\n if (options.top !== null) {\n props.top = (options.top - curOffset.top) + curTop;\n }\n if (options.left !== null) {\n props.left = (options.left - curOffset.left) + curLeft;\n }\n\n if ('using' in options) {\n options.using.call(curElem, props);\n } else {\n curElem.css({\n top: props.top + 'px',\n left: props.left + 'px'\n });\n }\n };\n\n /**\n * Provides read-only equivalent of jQuery's position function\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.position = function (element) {\n\n var offsetParentRect = {top: 0, left: 0};\n var offsetParentEl;\n var offset;\n\n // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent\n if (fn.css(element, 'position') === 'fixed') {\n\n // We assume that getBoundingClientRect is available when computed position is fixed\n offset = element.getBoundingClientRect();\n\n } else {\n\n // Get *real* offsetParentEl\n offsetParentEl = offsetParentElement(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentEl, 'html')) {\n offsetParentRect = fn.offset(offsetParentEl);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentEl, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentEl, 'borderLeftWidth', true);\n }\n\n // Subtract parent offsets and element margins\n return {\n width: element.offsetWidth,\n height: element.offsetHeight,\n top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true),\n left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true)\n };\n\n };\n\n /**\n * Returns the closest, non-statically positioned offsetParent of a given element\n * @required-by fn.position\n * @param element\n */\n function offsetParentElement (element) {\n var docElement = element.ownerDocument;\n var offsetParent = element.offsetParent || docElement;\n if (nodeName(offsetParent, '#document')) return docElement.documentElement;\n while (offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') {\n offsetParent = offsetParent.offsetParent;\n }\n return offsetParent || docElement.documentElement;\n }\n\n /**\n * Provides equivalent of jQuery's height function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/height/\n * @param element\n * @param outer\n */\n fn.height = function (element, outer) {\n var value = element.offsetHeight;\n if (outer) {\n value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true);\n } else {\n value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true);\n }\n return value;\n };\n\n /**\n * Provides equivalent of jQuery's width function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/width/\n * @param element\n * @param outer\n */\n fn.width = function (element, outer) {\n var value = element.offsetWidth;\n if (outer) {\n value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true);\n } else {\n value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true);\n }\n return value;\n };\n\n return fn;\n\n });\n\n// Source: helpers/debounce.js\nangular.module('mgcrea.ngStrap.helpers.debounce', [])\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L693\n.factory('debounce', function ($timeout) {\n return function (func, wait, immediate) {\n var timeout = null;\n return function () {\n var context = this;\n var args = arguments;\n var callNow = immediate && !timeout;\n if (timeout) {\n $timeout.cancel(timeout);\n }\n timeout = $timeout(function later () {\n timeout = null;\n if (!immediate) {\n func.apply(context, args);\n }\n }, wait, false);\n if (callNow) {\n func.apply(context, args);\n }\n return timeout;\n };\n };\n})\n\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L661\n.factory('throttle', function ($timeout) {\n return function (func, wait, options) {\n var timeout = null;\n if (!options) options = {};\n return function () {\n var context = this;\n var args = arguments;\n if (!timeout) {\n if (options.leading !== false) {\n func.apply(context, args);\n }\n timeout = $timeout(function later () {\n timeout = null;\n if (options.trailing !== false) {\n func.apply(context, args);\n }\n }, wait, false);\n }\n };\n };\n});\n\n// Source: helpers/date-parser.js\nangular.module('mgcrea.ngStrap.helpers.dateParser', [])\n\n.provider('$dateParser', function ($localeProvider) {\n\n // define a custom ParseDate object to use instead of native Date\n // to avoid date values wrapping when setting date component values\n function ParseDate () {\n this.year = 1970;\n this.month = 0;\n this.day = 1;\n this.hours = 0;\n this.minutes = 0;\n this.seconds = 0;\n this.milliseconds = 0;\n }\n\n ParseDate.prototype.setMilliseconds = function (value) { this.milliseconds = value; };\n ParseDate.prototype.setSeconds = function (value) { this.seconds = value; };\n ParseDate.prototype.setMinutes = function (value) { this.minutes = value; };\n ParseDate.prototype.setHours = function (value) { this.hours = value; };\n ParseDate.prototype.getHours = function () { return this.hours; };\n ParseDate.prototype.setDate = function (value) { this.day = value; };\n ParseDate.prototype.setMonth = function (value) { this.month = value; };\n ParseDate.prototype.setFullYear = function (value) { this.year = value; };\n ParseDate.prototype.fromDate = function (value) {\n this.year = value.getFullYear();\n this.month = value.getMonth();\n this.day = value.getDate();\n this.hours = value.getHours();\n this.minutes = value.getMinutes();\n this.seconds = value.getSeconds();\n this.milliseconds = value.getMilliseconds();\n return this;\n };\n\n ParseDate.prototype.toDate = function () {\n return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);\n };\n\n var proto = ParseDate.prototype;\n\n function noop () {\n }\n\n function isNumeric (n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n function indexOfCaseInsensitive (array, value) {\n var len = array.length;\n var str = value.toString().toLowerCase();\n for (var i = 0; i < len; i++) {\n if (array[i].toLowerCase() === str) { return i; }\n }\n return -1; // Return -1 per the \"Array.indexOf()\" method.\n }\n\n var defaults = this.defaults = {\n format: 'shortDate',\n strict: false\n };\n\n this.$get = function ($locale, dateFilter) {\n\n var DateParserFactory = function (config) {\n\n var options = angular.extend({}, defaults, config);\n\n var $dateParser = {};\n\n /* eslint-disable key-spacing, quote-props */\n var regExpMap = {\n 'sss' : '[0-9]{3}',\n 'ss' : '[0-5][0-9]',\n 's' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'mm' : '[0-5][0-9]',\n 'm' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'HH' : '[01][0-9]|2[0-3]',\n 'H' : options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]',\n 'hh' : '[0][1-9]|[1][012]',\n 'h' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'a' : 'AM|PM',\n 'EEEE' : $locale.DATETIME_FORMATS.DAY.join('|'),\n 'EEE' : $locale.DATETIME_FORMATS.SHORTDAY.join('|'),\n 'dd' : '0[1-9]|[12][0-9]|3[01]',\n 'd' : options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]',\n 'MMMM' : $locale.DATETIME_FORMATS.MONTH.join('|'),\n 'MMM' : $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),\n 'MM' : '0[1-9]|1[012]',\n 'M' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'yyyy' : '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}',\n 'yy' : '[0-9]{2}',\n 'y' : options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}'\n };\n\n var setFnMap = {\n 'sss' : proto.setMilliseconds,\n 'ss' : proto.setSeconds,\n 's' : proto.setSeconds,\n 'mm' : proto.setMinutes,\n 'm' : proto.setMinutes,\n 'HH' : proto.setHours,\n 'H' : proto.setHours,\n 'hh' : proto.setHours,\n 'h' : proto.setHours,\n 'EEEE' : noop,\n 'EEE' : noop,\n 'dd' : proto.setDate,\n 'd' : proto.setDate,\n 'a' : function (value) { var hours = this.getHours() % 12; return this.setHours(value.match(/pm/i) ? hours + 12 : hours); },\n 'MMMM' : function (value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); },\n 'MMM' : function (value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); },\n 'MM' : function (value) { return this.setMonth(1 * value - 1); },\n 'M' : function (value) { return this.setMonth(1 * value - 1); },\n 'yyyy' : proto.setFullYear,\n 'yy' : function (value) { return this.setFullYear(2000 + 1 * value); },\n 'y' : function (value) { return (1 * value <= 50 && value.length === 2) ? this.setFullYear(2000 + 1 * value) : this.setFullYear(1 * value); }\n };\n /* eslint-enable key-spacing, quote-props */\n\n var regex;\n var setMap;\n\n $dateParser.init = function () {\n $dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format;\n regex = regExpForFormat($dateParser.$format);\n setMap = setMapForFormat($dateParser.$format);\n };\n\n $dateParser.isValid = function (date) {\n if (angular.isDate(date)) return !isNaN(date.getTime());\n return regex.test(date);\n };\n\n $dateParser.parse = function (value, baseDate, format, timezone) {\n // check for date format special names\n if (format) format = $locale.DATETIME_FORMATS[format] || format;\n if (angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format, timezone);\n var formatRegex = format ? regExpForFormat(format) : regex;\n var formatSetMap = format ? setMapForFormat(format) : setMap;\n var matches = formatRegex.exec(value);\n if (!matches) return false;\n // use custom ParseDate object to set parsed values\n var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0));\n for (var i = 0; i < matches.length - 1; i++) {\n if (formatSetMap[i]) formatSetMap[i].call(date, matches[i + 1]);\n }\n // convert back to native Date object\n var newDate = date.toDate();\n\n // check new native Date object for day values overflow\n if (parseInt(date.day, 10) !== newDate.getDate()) {\n return false;\n }\n\n return newDate;\n };\n\n $dateParser.getDateForAttribute = function (key, value) {\n var date;\n\n if (value === 'today') {\n var today = new Date();\n date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, (key === 'minDate' ? 0 : -1));\n } else if (angular.isString(value) && value.match(/^\".+\"$/)) { // Support {{ dateObj }}\n date = new Date(value.substr(1, value.length - 2));\n } else if (isNumeric(value)) {\n date = new Date(parseInt(value, 10));\n } else if (angular.isString(value) && value.length === 0) { // Reset date\n date = key === 'minDate' ? -Infinity : +Infinity;\n } else {\n date = new Date(value);\n }\n\n return date;\n };\n\n $dateParser.getTimeForAttribute = function (key, value) {\n var time;\n\n if (value === 'now') {\n time = new Date().setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && value.match(/^\".+\"$/)) {\n time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1);\n } else if (isNumeric(value)) {\n time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && value.length === 0) { // Reset time\n time = key === 'minTime' ? -Infinity : +Infinity;\n } else {\n time = $dateParser.parse(value, new Date(1970, 0, 1, 0));\n }\n\n return time;\n };\n\n /* Handle switch to/from daylight saving.\n * Hours may be non-zero on daylight saving cut-over:\n * > 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function (date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n /* Correct the date for timezone offset.\n * @param date (Date) the date to adjust\n * @param timezone (string) the timezone to adjust for\n * @param undo (boolean) to add or subtract timezone offset\n * @return (Date) the corrected date\n */\n $dateParser.timezoneOffsetAdjust = function (date, timezone, undo) {\n if (!date) {\n return null;\n }\n // Right now, only 'UTC' is supported.\n if (timezone && timezone === 'UTC') {\n date = new Date(date.getTime());\n date.setMinutes(date.getMinutes() + (undo ? -1 : 1) * date.getTimezoneOffset());\n }\n return date;\n };\n\n // Private functions\n\n function regExpForFormat (format) {\n // `format` string can contain literal values.\n // These need to be escaped by surrounding with\n // single quotes (e.g. `\"h 'in the morning'\"`).\n // In order to output a single quote, escape it - i.e.,\n // two single quotes in a sequence (e.g. `\"h 'o''clock'\"`).\n\n var re = buildDateAbstractRegex(format);\n return buildDateParseRegex(re);\n }\n\n function buildDateAbstractRegex (format) {\n var escapedFormat = escapeReservedSymbols(format);\n var escapedLiteralFormat = escapedFormat.replace(/''/g, '\\\\\\'');\n var literalRegex = /('(?:\\\\'|.)*?')/;\n var formatParts = escapedLiteralFormat.split(literalRegex);\n var dateElements = Object.keys(regExpMap);\n var dateRegexParts = [];\n\n angular.forEach(formatParts, function (part) {\n if (isFormatStringLiteral(part)) {\n part = trimLiteralEscapeChars(part);\n } else {\n // Abstract replaces to avoid collisions\n for (var i = 0; i < dateElements.length; i++) {\n part = part.split(dateElements[i]).join('${' + i + '}');\n }\n }\n dateRegexParts.push(part);\n });\n\n return dateRegexParts.join('');\n }\n\n function escapeReservedSymbols (text) {\n return text.replace(/\\\\/g, '[\\\\\\\\]')\n .replace(/-/g, '[-]')\n .replace(/\\./g, '[.]')\n .replace(/\\*/g, '[*]')\n .replace(/\\+/g, '[+]')\n .replace(/\\?/g, '[?]')\n .replace(/\\$/g, '[$]')\n .replace(/\\^/g, '[^]')\n .replace(/\\//g, '[/]')\n .replace(/\\\\s/g, '[\\\\s]');\n }\n\n function isFormatStringLiteral (text) {\n return /^'.*'$/.test(text);\n }\n\n function trimLiteralEscapeChars (text) {\n return text.replace(/^'(.*)'$/, '$1');\n }\n\n function buildDateParseRegex (abstractRegex) {\n var dateElements = Object.keys(regExpMap);\n var re = abstractRegex;\n\n // Replace abstracted values\n for (var i = 0; i < dateElements.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[dateElements[i]] + ')');\n }\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n function setMapForFormat (format) {\n var re = buildDateAbstractRegex(format);\n return buildDateParseValuesMap(re);\n }\n\n function buildDateParseValuesMap (abstractRegex) {\n var dateElements = Object.keys(regExpMap);\n var valuesRegex = new RegExp('\\\\${(\\\\d+)}', 'g');\n var valuesMatch;\n var keyIndex;\n var valueKey;\n var valueFunction;\n var valuesFunctionMap = [];\n\n /* eslint-disable no-cond-assign */\n while ((valuesMatch = valuesRegex.exec(abstractRegex)) !== null) {\n keyIndex = valuesMatch[1];\n valueKey = dateElements[keyIndex];\n valueFunction = setFnMap[valueKey];\n\n valuesFunctionMap.push(valueFunction);\n }\n\n return valuesFunctionMap;\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n\n// Source: helpers/date-formatter.js\nangular.module('mgcrea.ngStrap.helpers.dateFormatter', [])\n\n .service('$dateFormatter', function ($locale, dateFilter) {\n\n // The unused `lang` arguments are on purpose. The default implementation does not\n // use them and it always uses the locale loaded into the `$locale` service.\n // Custom implementations might use it, thus allowing different directives to\n // have different languages.\n\n this.getDefaultLocale = function () {\n return $locale.id;\n };\n\n // Format is either a data format name, e.g. \"shortTime\" or \"fullDate\", or a date format\n // Return either the corresponding date format or the given date format.\n this.getDatetimeFormat = function (format, lang) {\n return $locale.DATETIME_FORMATS[format] || format;\n };\n\n this.weekdaysShort = function (lang) {\n return $locale.DATETIME_FORMATS.SHORTDAY;\n };\n\n function splitTimeFormat (format) {\n return /(h+)([:\\.])?(m+)([:\\.])?(s*)[ ]?(a?)/i.exec(format).slice(1);\n }\n\n // h:mm a => h\n this.hoursFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[0];\n };\n\n // h:mm a => mm\n this.minutesFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[2];\n };\n\n // h:mm:ss a => ss\n this.secondsFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => :\n this.timeSeparator = function (timeFormat) {\n return splitTimeFormat(timeFormat)[1];\n };\n\n // h:mm:ss a => true, h:mm a => false\n this.showSeconds = function (timeFormat) {\n return !!splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => true, H.mm => false\n this.showAM = function (timeFormat) {\n return !!splitTimeFormat(timeFormat)[5];\n };\n\n this.formatDate = function (date, format, lang, timezone) {\n return dateFilter(date, format, timezone);\n };\n\n });\n\n// Source: helpers/compiler.js\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService ($q, $http, $injector, $compile, $controller, $templateCache) {\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function (options) {\n\n if (options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function (value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (template) {\n resolve.$template = $q.when(template);\n } else if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n throw new Error('Missing `template` / `templateUrl` option.');\n }\n\n if (options.titleTemplate) {\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.titleTemplate)])\n .then(function (templates) {\n var templateEl = angular.element(templates[0]);\n findElement('[ng-bind=\"title\"]', templateEl[0])\n .removeAttr('ng-bind')\n .html(templates[1]);\n return templateEl[0].outerHTML;\n });\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function (templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0])\n .removeAttr('ng-bind')\n .html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if (!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function (locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link (scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate (template) {\n if (fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function (res) {\n return res.data;\n }));\n }\n\n}\n\n// Source: datepicker/datepicker.js\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n // Uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n hasToday: false,\n hasClear: false,\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function ($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();\n\n function DatepickerFactory (element, controller, config) {\n\n var $datepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $datepicker.$options;\n var scope = $datepicker.$scope;\n if (options.startView) options.startView -= options.minView;\n\n // View vars\n\n var pickerViews = datepickerViews($datepicker);\n $datepicker.$views = pickerViews.views;\n var viewDate = pickerViews.viewDate;\n scope.$mode = options.startView;\n scope.$iconLeft = options.iconLeft;\n scope.$iconRight = options.iconRight;\n scope.$hasToday = options.hasToday;\n scope.$hasClear = options.hasClear;\n var $picker = $datepicker.$views[scope.$mode];\n\n // Scope methods\n\n scope.$select = function (date) {\n $datepicker.select(date);\n };\n scope.$selectPane = function (value) {\n $datepicker.$selectPane(value);\n };\n scope.$toggleMode = function () {\n $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);\n };\n scope.$setToday = function () {\n if (options.autoclose) {\n $datepicker.setMode(0);\n $datepicker.select(new Date());\n } else {\n $datepicker.select(new Date(), true);\n }\n };\n scope.$clear = function () {\n if (options.autoclose) {\n $datepicker.setMode(0);\n $datepicker.select(null);\n } else {\n $datepicker.select(null, true);\n }\n };\n\n // Public methods\n\n $datepicker.update = function (date) {\n // console.warn('$datepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $datepicker.$date = date;\n $picker.update.call($picker, date);\n }\n // Build only if pristine\n $datepicker.$build(true);\n };\n\n $datepicker.updateDisabledDates = function (dateRanges) {\n options.disabledDateRanges = dateRanges;\n for (var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);\n }\n };\n\n $datepicker.select = function (date, keep) {\n // console.warn('$datepicker.select', date, scope.$mode);\n if (angular.isDate(date)) {\n if (!angular.isDate(controller.$dateValue) || isNaN(controller.$dateValue.getTime())) {\n controller.$dateValue = new Date(date);\n }\n } else {\n controller.$dateValue = null;\n }\n if (!scope.$mode || keep) {\n controller.$setViewValue(angular.copy(date));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function () { $datepicker.hide(true); });\n }\n } else {\n angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});\n $datepicker.setMode(scope.$mode - 1);\n $datepicker.$build();\n }\n };\n\n $datepicker.setMode = function (mode) {\n // console.warn('$datepicker.setMode', mode);\n scope.$mode = mode;\n $picker = $datepicker.$views[scope.$mode];\n $datepicker.$build();\n };\n\n // Protected methods\n\n $datepicker.$build = function (pristine) {\n // console.warn('$datepicker.$build() viewDate=%o', viewDate);\n if (pristine === true && $picker.built) return;\n if (pristine === false && !$picker.built) return;\n $picker.build.call($picker);\n };\n\n $datepicker.$updateSelected = function () {\n for (var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], updateSelected);\n }\n };\n\n $datepicker.$isSelected = function (date) {\n return $picker.isSelected(date);\n };\n\n $datepicker.$setDisabledEl = function (el) {\n el.disabled = $picker.isDisabled(el.date);\n };\n\n $datepicker.$selectPane = function (value) {\n var steps = $picker.steps;\n // set targetDate to first day of month to avoid problems with\n // date values rollover. This assumes the viewDate does not\n // depend on the day of the month\n var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));\n angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});\n $datepicker.$build();\n };\n\n $datepicker.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $datepicker.$onKeyDown = function (evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n if (evt.keyCode === 13) {\n if (!scope.$mode) {\n $datepicker.hide(true);\n } else {\n scope.$apply(function () { $datepicker.setMode(scope.$mode - 1); });\n }\n return;\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected (el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement () {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function () {\n if (isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function () {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function () {\n if ((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n // if $datepicker is no longer showing, don't setup events\n if (!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function (blur) {\n if (!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function ($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n // var defaults = $datepicker.defaults;\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent', 'hasToday', 'hasClear'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'hasToday', 'hasClear'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if (isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function (date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!datepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);\n if (newValue === true) {\n datepicker.show();\n } else {\n datepicker.hide();\n }\n });\n }\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function (key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n if (angular.isDefined(attr[key])) {\n attr.$observe(key, function (newValue) {\n // console.warn('attr.$observe(%s)=%o', key, newValue);\n datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);\n // Build only if dirty\n if (!isNaN(datepicker.$options[key])) datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n }\n });\n\n // Observe date format\n if (angular.isDefined(attr.dateFormat)) {\n attr.$observe('dateFormat', function (newValue) {\n datepicker.$options.dateFormat = newValue;\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges (ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function (disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate (parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function (viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n }\n validateAgainstMinMaxDate(parsedDate);\n\n if (options.dateType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true);\n return formatDate(date, options.modelDateFormat || options.dateFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.dateType === 'number') {\n return date.getTime();\n } else if (options.dateType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.dateType === 'iso') {\n return date.toISOString();\n }\n return new Date(date);\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.dateType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelDateFormat);\n } else if (options.dateType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if (isNaN(date.getTime())) {\n // var today = new Date();\n // date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);\n // }\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getDateFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function () {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getDateFormattedString());\n };\n\n function getDateFormattedString () {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (datepicker) datepicker.destroy();\n options = null;\n datepicker = null;\n });\n\n }\n };\n\n })\n\n .provider('datepickerViews', function () {\n\n // var defaults = this.defaults = {\n // dayFormat: 'dd',\n // daySplit: 7\n // };\n\n // Split array into smaller arrays\n function split (arr, size) {\n var arrays = [];\n while (arr.length > 0) {\n arrays.push(arr.splice(0, size));\n }\n return arrays;\n }\n\n // Modulus operator\n function mod (n, m) {\n return ((n % m) + m) % m;\n }\n\n this.$get = function ($dateFormatter, $dateParser, $sce) {\n\n return function (picker) {\n\n var scope = picker.$scope;\n var options = picker.$options;\n\n var lang = options.lang;\n var formatDate = function (date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n var weekDaysMin = $dateFormatter.weekdaysShort(lang);\n var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));\n var weekDaysLabelsHtml = $sce.trustAsHtml('' + weekDaysLabels.join('') + '');\n\n var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date());\n var viewDate = {year: startDate.getFullYear(), month: startDate.getMonth(), date: startDate.getDate()};\n\n var views = [{\n format: options.dayFormat,\n split: 7,\n steps: {month: 1},\n update: function (date, force) {\n if (!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getDate() !== viewDate.date || date.getDate() === 1) {\n // chaging picker current month will cause viewDate.date to be set to first day of the month,\n // in $datepicker.$selectPane, so picker would not update selected day display if\n // user picks first day of the new month.\n // As a workaround, we are always forcing update when picked date is first day of month.\n viewDate.date = picker.$date.getDate();\n picker.$updateSelected();\n }\n },\n build: function () {\n var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1);\n var firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5);\n var firstDateOffset = firstDate.getTimezoneOffset();\n var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString();\n // Handle daylight time switch\n if (firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 60e3);\n var days = [];\n var day;\n for (var i = 0; i < 42; i++) { // < 7 * 6\n day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i));\n days.push({date: day, isToday: day.toDateString() === today, label: formatDate(day, this.format), selected: picker.$date && this.isSelected(day), muted: day.getMonth() !== viewDate.month, disabled: this.isDisabled(day)});\n }\n scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat);\n scope.showLabels = true;\n scope.labels = weekDaysLabelsHtml;\n scope.rows = split(days, this.split);\n scope.isTodayDisabled = this.isDisabled(new Date());\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate();\n },\n isDisabled: function (date) {\n var time = date.getTime();\n\n // Disabled because of min/max date.\n if (time < options.minDate || time > options.maxDate) return true;\n\n // Disabled due to being a disabled day of the week\n if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true;\n\n // Disabled because of disabled date range.\n if (options.disabledDateRanges) {\n for (var i = 0; i < options.disabledDateRanges.length; i++) {\n if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) {\n return true;\n }\n }\n }\n\n return false;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualTime = picker.$date.getTime();\n var newDate;\n\n if (evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5);\n else if (evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5);\n else if (evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5);\n else if (evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'month',\n format: options.monthFormat,\n split: 4,\n steps: {year: 1},\n update: function (date, force) {\n if (!this.built || date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function () {\n // var firstMonth = new Date(viewDate.year, 0, 1);\n var months = [];\n var month;\n for (var i = 0; i < 12; i++) {\n month = new Date(viewDate.year, i, 1);\n months.push({date: month, label: formatDate(month, this.format), selected: picker.$isSelected(month), disabled: this.isDisabled(month)});\n }\n scope.title = formatDate(month, options.yearTitleFormat);\n scope.showLabels = false;\n scope.rows = split(months, this.split);\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth();\n },\n isDisabled: function (date) {\n var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualMonth = picker.$date.getMonth();\n var newDate = new Date(picker.$date);\n\n if (evt.keyCode === 37) newDate.setMonth(actualMonth - 1);\n else if (evt.keyCode === 38) newDate.setMonth(actualMonth - 4);\n else if (evt.keyCode === 39) newDate.setMonth(actualMonth + 1);\n else if (evt.keyCode === 40) newDate.setMonth(actualMonth + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'year',\n format: options.yearFormat,\n split: 4,\n steps: {year: 12},\n update: function (date, force) {\n if (!this.built || force || parseInt(date.getFullYear() / 20, 10) !== parseInt(viewDate.year / 20, 10)) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function () {\n var firstYear = viewDate.year - viewDate.year % (this.split * 3);\n var years = [];\n var year;\n for (var i = 0; i < 12; i++) {\n year = new Date(firstYear + i, 0, 1);\n years.push({date: year, label: formatDate(year, this.format), selected: picker.$isSelected(year), disabled: this.isDisabled(year)});\n }\n scope.title = years[0].label + '-' + years[years.length - 1].label;\n scope.showLabels = false;\n scope.rows = split(years, this.split);\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear();\n },\n isDisabled: function (date) {\n var lastDate = +new Date(date.getFullYear() + 1, 0, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualYear = picker.$date.getFullYear();\n var newDate = new Date(picker.$date);\n\n if (evt.keyCode === 37) newDate.setYear(actualYear - 1);\n else if (evt.keyCode === 38) newDate.setYear(actualYear - 4);\n else if (evt.keyCode === 39) newDate.setYear(actualYear + 1);\n else if (evt.keyCode === 40) newDate.setYear(actualYear + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }];\n\n return {\n views: options.minView ? Array.prototype.slice.call(views, options.minView) : views,\n viewDate: viewDate\n };\n\n };\n\n };\n\n });\n\n// Source: button/button.js\nangular.module('mgcrea.ngStrap.button', [])\n\n .provider('$button', function () {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n toggleEvent: 'click'\n };\n\n this.$get = function () {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsCheckboxGroup', function () {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink (element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"checkbox\"]');\n angular.forEach(children, function (child) {\n var childEl = angular.element(child);\n childEl.attr('bs-checkbox', '');\n childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value'));\n });\n }\n\n };\n\n })\n\n .directive('bsCheckbox', function ($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support label > input[type=\"checkbox\"]\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true;\n if (constantValueRegExp.test(attr.trueValue)) {\n trueValue = scope.$eval(attr.trueValue);\n }\n var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false;\n if (constantValueRegExp.test(attr.falseValue)) {\n falseValue = scope.$eval(attr.falseValue);\n }\n\n // Parse exotic values\n var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean';\n if (hasExoticValues) {\n controller.$parsers.push(function (viewValue) {\n // console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue);\n return viewValue ? trueValue : falseValue;\n });\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n return angular.equals(modelValue, trueValue);\n });\n // Fix rendering for exotic values\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n controller.$render();\n });\n }\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, trueValue);\n $$rAF(function () {\n if (isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function () {\n scope.$apply(function () {\n // console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n if (!isInput) {\n controller.$setViewValue(!activeElement.hasClass('active'));\n }\n if (!hasExoticValues) {\n controller.$render();\n }\n });\n });\n\n }\n\n };\n\n })\n\n .directive('bsRadioGroup', function () {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink (element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"radio\"]');\n angular.forEach(children, function (child) {\n angular.element(child).attr('bs-radio', '');\n angular.element(child).attr('ng-model', attr.ngModel);\n });\n }\n\n };\n\n })\n\n .directive('bsRadio', function ($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support `label > input[type=\"radio\"]` markup\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var value;\n attr.$observe('value', function (v) {\n if (typeof v !== 'boolean' && constantValueRegExp.test(v)) {\n value = scope.$eval(v);\n } else {\n value = v;\n }\n controller.$render();\n });\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, value);\n $$rAF(function () {\n if (isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function () {\n scope.$apply(function () {\n // console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n controller.$setViewValue(value);\n controller.$render();\n });\n });\n\n }\n\n };\n\n });\n\n// Source: collapse/collapse.js\nangular.module('mgcrea.ngStrap.collapse', [])\n\n .provider('$collapse', function () {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function ($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['disallowToggle', 'startCollapsed', 'allowMultiple'], function (key) {\n if (angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) {\n self.$options[key] = false;\n }\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function (element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function (element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function (element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function (element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function (value) {\n if (angular.isArray(value)) {\n self.$targets.$active = value;\n } else if (!self.$options.disallowToggle && isActive(value)) {\n deactivateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function () {\n if (self.$options.allowMultiple) {\n return self.$targets.$active;\n }\n return self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1;\n };\n\n function fixActiveItemIndexes (index) {\n // item with index was removed, so we\n // need to adjust other items index values\n var activeIndexes = self.$targets.$active;\n for (var i = 0; i < activeIndexes.length; i++) {\n if (index < activeIndexes[i]) {\n activeIndexes[i] = activeIndexes[i] - 1;\n }\n\n // the last item is active, so we need to\n // adjust its index\n if (activeIndexes[i] === self.$targets.length) {\n activeIndexes[i] = self.$targets.length - 1;\n }\n }\n }\n\n function isActive (value) {\n var activeItems = self.$targets.$active;\n return activeItems.indexOf(value) !== -1;\n }\n\n function deactivateItem (value) {\n var index = self.$targets.$active.indexOf(value);\n if (index !== -1) {\n self.$targets.$active.splice(index, 1);\n }\n }\n\n function activateItem (value) {\n if (!self.$options.allowMultiple) {\n // remove current selected item\n self.$targets.$active.splice(0, 1);\n }\n\n if (self.$targets.$active.indexOf(value) === -1) {\n self.$targets.$active.push(value);\n }\n }\n\n };\n\n this.$get = function () {\n var $collapse = {};\n $collapse.defaults = defaults;\n $collapse.controller = controller;\n return $collapse;\n };\n\n })\n\n .directive('bsCollapse', function ($window, $animate, $collapse) {\n\n return {\n require: ['?ngModel', 'bsCollapse'],\n controller: ['$scope', '$element', '$attrs', $collapse.controller],\n link: function postLink (scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n if (ngModelCtrl) {\n\n // Update the modelValue following\n bsCollapseCtrl.$viewChangeListeners.push(function () {\n ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes());\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n if (angular.isArray(modelValue)) {\n // model value is an array, so just replace\n // the active items directly\n bsCollapseCtrl.$setActive(modelValue);\n } else {\n var activeIndexes = bsCollapseCtrl.$activeIndexes();\n\n if (angular.isArray(activeIndexes)) {\n // we have an array of selected indexes\n if (activeIndexes.indexOf(modelValue * 1) === -1) {\n // item with modelValue index is not active\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n } else if (activeIndexes !== modelValue * 1) {\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n return modelValue;\n });\n\n }\n\n }\n };\n\n })\n\n .directive('bsCollapseToggle', function () {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base attr\n element.attr('data-toggle', 'collapse');\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerToggle(element);\n\n // remove toggle from collapse controller when toggle is destroyed\n scope.$on('$destroy', function () {\n bsCollapseCtrl.$unregisterToggle(element);\n });\n\n element.on('click', function () {\n if (!attrs.disabled) {\n var index = attrs.bsCollapseToggle && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n }\n });\n\n }\n };\n\n })\n\n .directive('bsCollapseTarget', function ($animate) {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n // scope: true,\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base class\n element.addClass('collapse');\n\n // Add animation class\n if (bsCollapseCtrl.$options.animation) {\n element.addClass(bsCollapseCtrl.$options.animation);\n }\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerTarget(element);\n\n // remove pane target from collapse controller when target is destroyed\n scope.$on('$destroy', function () {\n bsCollapseCtrl.$unregisterTarget(element);\n });\n\n function render () {\n var index = bsCollapseCtrl.$targets.indexOf(element);\n var active = bsCollapseCtrl.$activeIndexes();\n var action = 'removeClass';\n if (angular.isArray(active)) {\n if (active.indexOf(index) !== -1) {\n action = 'addClass';\n }\n } else if (index === active) {\n action = 'addClass';\n }\n\n $animate[action](element, bsCollapseCtrl.$options.activeClass);\n }\n\n bsCollapseCtrl.$viewChangeListeners.push(function () {\n render();\n });\n render();\n\n }\n };\n\n });\n\n// Source: aside/aside.js\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function ($modal) {\n\n function AsideFactory (config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function ($window, $sce, $aside) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsAside) {\n scope.$watch(attr.bsAside, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize aside\n var aside = $aside(options);\n\n // Trigger\n element.on(attr.trigger || 'click', aside.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (aside) aside.destroy();\n options = null;\n aside = null;\n });\n\n }\n };\n\n });\n\n// Source: alert/alert.js\n// @BUG: following snippet won't compile correctly\n\nangular.module('mgcrea.ngStrap.alert', ['mgcrea.ngStrap.modal'])\n\n .provider('$alert', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'alert',\n prefixEvent: 'alert',\n placement: null,\n templateUrl: 'alert/alert.tpl.html',\n container: false,\n element: null,\n backdrop: false,\n keyboard: true,\n show: true,\n // Specific options\n duration: false,\n type: false,\n dismissable: true\n };\n\n this.$get = function ($modal, $timeout) {\n\n function AlertFactory (config) {\n\n var $alert = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $alert = $modal(options);\n\n // Support scope as string options [/*title, content, */ type, dismissable]\n $alert.$scope.dismissable = !!options.dismissable;\n if (options.type) {\n $alert.$scope.type = options.type;\n }\n\n // Support auto-close duration\n var show = $alert.show;\n if (options.duration) {\n $alert.show = function () {\n show();\n $timeout(function () {\n $alert.hide();\n }, options.duration * 1000);\n };\n }\n\n return $alert;\n\n }\n\n return AlertFactory;\n\n };\n\n })\n\n .directive('bsAlert', function ($window, $sce, $alert) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['keyboard', 'html', 'container', 'dismissable'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')) {\n scope.title = '';\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content', 'type'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsAlert) {\n scope.$watch(attr.bsAlert, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize alert\n var alert = $alert(options);\n\n // Trigger\n element.on(attr.trigger || 'click', alert.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (alert) alert.destroy();\n options = null;\n alert = null;\n });\n\n }\n };\n\n });\n\n// Source: affix/affix.js\nangular.module('mgcrea.ngStrap.affix', ['mgcrea.ngStrap.helpers.dimensions', 'mgcrea.ngStrap.helpers.debounce'])\n\n .provider('$affix', function () {\n\n var defaults = this.defaults = {\n offsetTop: 'auto',\n inlineStyles: true\n };\n\n this.$get = function ($window, debounce, dimensions) {\n\n var bodyEl = angular.element($window.document.body);\n var windowEl = angular.element($window);\n\n function AffixFactory (element, config) {\n\n var $affix = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var targetEl = options.target;\n\n // Initial private vars\n var reset = 'affix affix-top affix-bottom';\n var setWidth = false;\n var initialAffixTop = 0;\n var initialOffsetTop = 0;\n var offsetTop = 0;\n var offsetBottom = 0;\n var affixed = null;\n var unpin = null;\n\n var parent = element.parent();\n // Options: custom parent\n if (options.offsetParent) {\n if (options.offsetParent.match(/^\\d+$/)) {\n for (var i = 0; i < (options.offsetParent * 1) - 1; i++) {\n parent = parent.parent();\n }\n } else {\n parent = angular.element(options.offsetParent);\n }\n }\n\n $affix.init = function () {\n\n this.$parseOffsets();\n initialOffsetTop = dimensions.offset(element[0]).top + initialAffixTop;\n setWidth = !element[0].style.width;\n\n // Bind events\n targetEl.on('scroll', this.checkPosition);\n targetEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', this.$debouncedOnResize);\n\n // Both of these checkPosition() calls are necessary for the case where\n // the user hits refresh after scrolling to the bottom of the page.\n this.checkPosition();\n this.checkPositionWithEventLoop();\n\n };\n\n $affix.destroy = function () {\n\n // Unbind events\n targetEl.off('scroll', this.checkPosition);\n targetEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', this.$debouncedOnResize);\n\n };\n\n $affix.checkPositionWithEventLoop = function () {\n\n // IE 9 throws an error if we use 'this' instead of '$affix'\n // in this setTimeout call\n setTimeout($affix.checkPosition, 1);\n\n };\n\n $affix.checkPosition = function () {\n // if (!this.$element.is(':visible')) return\n\n var scrollTop = getScrollTop();\n var position = dimensions.offset(element[0]);\n var elementHeight = dimensions.height(element[0]);\n\n // Get required affix class according to position\n var affix = getRequiredAffixClass(unpin, position, elementHeight);\n\n // Did affix status changed this last check?\n if (affixed === affix) return;\n affixed = affix;\n\n if (affix === 'top') {\n unpin = null;\n if (setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', '');\n }\n } else if (affix === 'bottom') {\n if (options.offsetUnpin) {\n unpin = -(options.offsetUnpin * 1);\n } else {\n // Calculate unpin threshold when affixed to bottom.\n // Hopefully the browser scrolls pixel by pixel.\n unpin = position.top - scrollTop;\n }\n if (setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', (options.offsetParent) ? '' : ((bodyEl[0].offsetHeight - offsetBottom - elementHeight - initialOffsetTop) + 'px'));\n }\n } else { // affix === 'middle'\n unpin = null;\n if (setWidth) {\n element.css('width', element[0].offsetWidth + 'px');\n }\n if (options.inlineStyles) {\n element.css('position', 'fixed');\n element.css('top', initialAffixTop + 'px');\n }\n }\n\n // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + affix : ''));\n\n };\n\n $affix.$onResize = function () {\n $affix.$parseOffsets();\n $affix.checkPosition();\n };\n $affix.$debouncedOnResize = debounce($affix.$onResize, 50);\n\n $affix.$parseOffsets = function () {\n var initialPosition = element.css('position');\n // Reset position to calculate correct offsetTop\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n }\n\n if (options.offsetTop) {\n if (options.offsetTop === 'auto') {\n options.offsetTop = '+0';\n }\n if (options.offsetTop.match(/^[-+]\\d+$/)) {\n initialAffixTop = - options.offsetTop * 1;\n if (options.offsetParent) {\n offsetTop = dimensions.offset(parent[0]).top + (options.offsetTop * 1);\n } else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\n }\n } else {\n offsetTop = options.offsetTop * 1;\n }\n }\n\n if (options.offsetBottom) {\n if (options.offsetParent && options.offsetBottom.match(/^[-+]\\d+$/)) {\n // add 1 pixel due to rounding problems...\n offsetBottom = getScrollHeight() - (dimensions.offset(parent[0]).top + dimensions.height(parent[0])) + (options.offsetBottom * 1) + 1;\n } else {\n offsetBottom = options.offsetBottom * 1;\n }\n }\n\n // Bring back the element's position after calculations\n if (options.inlineStyles) {\n element.css('position', initialPosition);\n }\n };\n\n // Private methods\n\n function getRequiredAffixClass (_unpin, position, elementHeight) {\n var scrollTop = getScrollTop();\n var scrollHeight = getScrollHeight();\n\n if (scrollTop <= offsetTop) {\n return 'top';\n } else if (_unpin !== null && (scrollTop + _unpin <= position.top)) {\n return 'middle';\n } else if (offsetBottom !== null && (position.top + elementHeight + initialAffixTop >= scrollHeight - offsetBottom)) {\n return 'bottom';\n }\n return 'middle';\n }\n\n function getScrollTop () {\n return targetEl[0] === $window ? $window.pageYOffset : targetEl[0].scrollTop;\n }\n\n function getScrollHeight () {\n return targetEl[0] === $window ? $window.document.body.scrollHeight : targetEl[0].scrollHeight;\n }\n\n $affix.init();\n return $affix;\n\n }\n\n return AffixFactory;\n\n };\n\n })\n\n .directive('bsAffix', function ($affix, $window) {\n\n return {\n restrict: 'EAC',\n require: '^?bsAffixTarget',\n link: function postLink (scope, element, attr, affixTarget) {\n\n var options = {scope: scope, target: affixTarget ? affixTarget.$element : angular.element($window)};\n angular.forEach(['offsetTop', 'offsetBottom', 'offsetParent', 'offsetUnpin', 'inlineStyles'], function (key) {\n if (angular.isDefined(attr[key])) {\n var option = attr[key];\n if (/true/i.test(option)) option = true;\n if (/false/i.test(option)) option = false;\n options[key] = option;\n }\n });\n\n var affix = $affix(element, options);\n scope.$on('$destroy', function () {\n if (affix) affix.destroy();\n options = null;\n affix = null;\n });\n\n }\n };\n\n })\n\n .directive('bsAffixTarget', function () {\n return {\n controller: function ($element) {\n this.$element = $element;\n }\n };\n });\n\n// Source: module.js\nangular.module('mgcrea.ngStrap', [\n 'mgcrea.ngStrap.modal',\n 'mgcrea.ngStrap.aside',\n 'mgcrea.ngStrap.alert',\n 'mgcrea.ngStrap.button',\n 'mgcrea.ngStrap.select',\n 'mgcrea.ngStrap.datepicker',\n 'mgcrea.ngStrap.timepicker',\n 'mgcrea.ngStrap.navbar',\n 'mgcrea.ngStrap.tooltip',\n 'mgcrea.ngStrap.popover',\n 'mgcrea.ngStrap.dropdown',\n 'mgcrea.ngStrap.typeahead',\n 'mgcrea.ngStrap.scrollspy',\n 'mgcrea.ngStrap.affix',\n 'mgcrea.ngStrap.tab',\n 'mgcrea.ngStrap.collapse'\n]);\n\n})(window, document);\n","'use strict';\n\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function ($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n function TypeaheadFactory (element, controller, config) {\n\n var $typeahead = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $typeahead = $tooltip(element, options);\n var parentScope = config.scope;\n var scope = $typeahead.$scope;\n\n scope.$resetMatches = function () {\n scope.$matches = [];\n scope.$activeIndex = options.autoSelect ? 0 : -1; // If set to 0, the first match will be highlighted\n };\n scope.$resetMatches();\n\n scope.$activate = function (index) {\n scope.$$postDigest(function () {\n $typeahead.activate(index);\n });\n };\n\n scope.$select = function (index, evt) {\n scope.$$postDigest(function () {\n $typeahead.select(index);\n });\n };\n\n scope.$isVisible = function () {\n return $typeahead.$isVisible();\n };\n\n // Public methods\n\n $typeahead.update = function (matches) {\n scope.$matches = matches;\n if (scope.$activeIndex >= matches.length) {\n scope.$activeIndex = options.autoSelect ? 0 : -1;\n }\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n safeDigest(scope);\n $$rAF($typeahead.$applyPlacement);\n };\n\n $typeahead.activate = function (index) {\n scope.$activeIndex = index;\n };\n\n $typeahead.select = function (index) {\n if (index === -1) return;\n var value = scope.$matches[index].value;\n // console.log('$setViewValue', value);\n controller.$setViewValue(value);\n controller.$render();\n scope.$resetMatches();\n if (parentScope) parentScope.$digest();\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $typeahead);\n if (angular.isDefined(options.onSelect) && angular.isFunction(options.onSelect)) {\n options.onSelect(value, index, $typeahead);\n }\n };\n\n // Protected methods\n\n $typeahead.$isVisible = function () {\n if (!options.minLength || !controller) {\n return !!scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength;\n };\n\n $typeahead.$getIndex = function (value) {\n var index;\n for (index = scope.$matches.length; index--;) {\n if (angular.equals(scope.$matches[index].value, value)) break;\n }\n return index;\n };\n\n $typeahead.$onMouseDown = function (evt) {\n // Prevent blur on mousedown\n evt.preventDefault();\n evt.stopPropagation();\n };\n\n $typeahead.$onKeyDown = function (evt) {\n if (!/(38|40|13)/.test(evt.keyCode)) return;\n\n // Let ngSubmit pass if the typeahead tip is hidden or no option is selected\n if ($typeahead.$isVisible() && !(evt.keyCode === 13 && scope.$activeIndex === -1)) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // Select with enter\n if (evt.keyCode === 13 && scope.$matches.length) {\n $typeahead.select(scope.$activeIndex);\n // Navigate with keyboard\n } else if (evt.keyCode === 38 && scope.$activeIndex > 0) {\n scope.$activeIndex--;\n } else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) {\n scope.$activeIndex++;\n } else if (angular.isUndefined(scope.$activeIndex)) {\n scope.$activeIndex = 0;\n }\n scope.$digest();\n };\n\n // Overrides\n\n var show = $typeahead.show;\n $typeahead.show = function () {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed immediately.\n $timeout(function () {\n if ($typeahead.$element) {\n $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n if (element) element.on('keydown', $typeahead.$onKeyDown);\n }\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function () {\n if ($typeahead.$element) $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n if (element) element.off('keydown', $typeahead.$onKeyDown);\n }\n if (!options.autoSelect) {\n $typeahead.activate(-1);\n }\n hide();\n };\n\n return $typeahead;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\n\n })\n\n .filter('bsAsyncFilter', function ($filter) {\n return function (array, expression, comparator) {\n if (array && angular.isFunction(array.then)) {\n return array.then(function (results) {\n return $filter('filter')(results, expression, comparator);\n });\n }\n return $filter('filter')(array, expression, comparator);\n };\n })\n\n .directive('bsTypeahead', function ($window, $parse, $q, $typeahead, $parseOptions) {\n\n var defaults = $typeahead.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Fixes firefox bug when using objects in model with typeahead\n // Yes this breaks any other directive using a 'change' event on this input,\n // but if it is using the 'change' event why is it used with typeahead?\n element.off('change');\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'trimValue', 'filter'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show, hide and select events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide', 'onSelect'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Disable browser autocompletion\n if (!element.attr('autocomplete')) element.attr('autocomplete', 'off');\n\n // Build proper bsOptions\n var filter = angular.isDefined(options.filter) ? options.filter : defaults.filter;\n var limit = options.limit || defaults.limit;\n var comparator = options.comparator || defaults.comparator;\n\n var bsOptions = attr.bsOptions;\n if (filter) {\n bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\n }\n if (limit) bsOptions += ' | limitTo:' + limit;\n var parsedOptions = $parseOptions(bsOptions);\n\n // Initialize typeahead\n var typeahead = $typeahead(element, controller, options);\n\n // Watch options on demand\n if (options.watchOptions) {\n // Watch bsOptions values before filtering for changes, drop function calls\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').replace(/\\(.*\\)/g, '').trim();\n scope.$watchCollection(watchedOptions, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller).then(function (values) {\n typeahead.update(values);\n controller.$render();\n });\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('$watch', element.attr('ng-model'), newValue);\n scope.$modelValue = newValue; // Publish modelValue on scope for custom templates\n parsedOptions.valuesFn(scope, controller)\n .then(function (values) {\n // Prevent input with no future prospect if selectMode is truthy\n // @TODO test selectMode\n if (options.selectMode && !values.length && newValue.length > 0) {\n controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1));\n return;\n }\n if (values.length > limit) values = values.slice(0, limit);\n typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (angular.isDefined(modelValue) && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = index !== -1 ? typeahead.$scope.$matches[index].label : controller.$viewValue;\n selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected;\n var value = selected ? selected.toString().replace(/<(?:.|\\n)*?>/gm, '') : '';\n var ss = element[0].selectionStart;\n var sd = element[0].selectionEnd;\n element.val(options.trimValue === false ? value : value.trim());\n element[0].setSelectionRange(ss, sd);\n };\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (typeahead) typeahead.destroy();\n options = null;\n typeahead = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService ($q, $http, $injector, $compile, $controller, $templateCache) {\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * \n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * \n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function (options) {\n\n if (options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function (value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (template) {\n resolve.$template = $q.when(template);\n } else if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n throw new Error('Missing `template` / `templateUrl` option.');\n }\n\n if (options.titleTemplate) {\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.titleTemplate)])\n .then(function (templates) {\n var templateEl = angular.element(templates[0]);\n findElement('[ng-bind=\"title\"]', templateEl[0])\n .removeAttr('ng-bind')\n .html(templates[1]);\n return templateEl[0].outerHTML;\n });\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function (templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0])\n .removeAttr('ng-bind')\n .html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if (!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function (locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('
').html(template.trim()).contents();\n var element = angular.element('
').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link (scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate (template) {\n if (fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function (res) {\n return res.data;\n }));\n }\n\n}\n","'use strict';\n\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n // Uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n hasToday: false,\n hasClear: false,\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function ($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();\n\n function DatepickerFactory (element, controller, config) {\n\n var $datepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $datepicker.$options;\n var scope = $datepicker.$scope;\n if (options.startView) options.startView -= options.minView;\n\n // View vars\n\n var pickerViews = datepickerViews($datepicker);\n $datepicker.$views = pickerViews.views;\n var viewDate = pickerViews.viewDate;\n scope.$mode = options.startView;\n scope.$iconLeft = options.iconLeft;\n scope.$iconRight = options.iconRight;\n scope.$hasToday = options.hasToday;\n scope.$hasClear = options.hasClear;\n var $picker = $datepicker.$views[scope.$mode];\n\n // Scope methods\n\n scope.$select = function (date) {\n $datepicker.select(date);\n };\n scope.$selectPane = function (value) {\n $datepicker.$selectPane(value);\n };\n scope.$toggleMode = function () {\n $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);\n };\n scope.$setToday = function () {\n if (options.autoclose) {\n $datepicker.setMode(0);\n $datepicker.select(new Date());\n } else {\n $datepicker.select(new Date(), true);\n }\n };\n scope.$clear = function () {\n if (options.autoclose) {\n $datepicker.setMode(0);\n $datepicker.select(null);\n } else {\n $datepicker.select(null, true);\n }\n };\n\n // Public methods\n\n $datepicker.update = function (date) {\n // console.warn('$datepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $datepicker.$date = date;\n $picker.update.call($picker, date);\n }\n // Build only if pristine\n $datepicker.$build(true);\n };\n\n $datepicker.updateDisabledDates = function (dateRanges) {\n options.disabledDateRanges = dateRanges;\n for (var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);\n }\n };\n\n $datepicker.select = function (date, keep) {\n // console.warn('$datepicker.select', date, scope.$mode);\n if (angular.isDate(date)) {\n if (!angular.isDate(controller.$dateValue) || isNaN(controller.$dateValue.getTime())) {\n controller.$dateValue = new Date(date);\n }\n } else {\n controller.$dateValue = null;\n }\n if (!scope.$mode || keep) {\n controller.$setViewValue(angular.copy(date));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function () { $datepicker.hide(true); });\n }\n } else {\n angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});\n $datepicker.setMode(scope.$mode - 1);\n $datepicker.$build();\n }\n };\n\n $datepicker.setMode = function (mode) {\n // console.warn('$datepicker.setMode', mode);\n scope.$mode = mode;\n $picker = $datepicker.$views[scope.$mode];\n $datepicker.$build();\n };\n\n // Protected methods\n\n $datepicker.$build = function (pristine) {\n // console.warn('$datepicker.$build() viewDate=%o', viewDate);\n if (pristine === true && $picker.built) return;\n if (pristine === false && !$picker.built) return;\n $picker.build.call($picker);\n };\n\n $datepicker.$updateSelected = function () {\n for (var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], updateSelected);\n }\n };\n\n $datepicker.$isSelected = function (date) {\n return $picker.isSelected(date);\n };\n\n $datepicker.$setDisabledEl = function (el) {\n el.disabled = $picker.isDisabled(el.date);\n };\n\n $datepicker.$selectPane = function (value) {\n var steps = $picker.steps;\n // set targetDate to first day of month to avoid problems with\n // date values rollover. This assumes the viewDate does not\n // depend on the day of the month\n var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));\n angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});\n $datepicker.$build();\n };\n\n $datepicker.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $datepicker.$onKeyDown = function (evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n if (evt.keyCode === 13) {\n if (!scope.$mode) {\n $datepicker.hide(true);\n } else {\n scope.$apply(function () { $datepicker.setMode(scope.$mode - 1); });\n }\n return;\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected (el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement () {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function () {\n if (isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function () {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function () {\n if ((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n // if $datepicker is no longer showing, don't setup events\n if (!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function (blur) {\n if (!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function ($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n // var defaults = $datepicker.defaults;\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent', 'hasToday', 'hasClear'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'hasToday', 'hasClear'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if (isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function (date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!datepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);\n if (newValue === true) {\n datepicker.show();\n } else {\n datepicker.hide();\n }\n });\n }\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function (key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n if (angular.isDefined(attr[key])) {\n attr.$observe(key, function (newValue) {\n // console.warn('attr.$observe(%s)=%o', key, newValue);\n datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);\n // Build only if dirty\n if (!isNaN(datepicker.$options[key])) datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n }\n });\n\n // Observe date format\n if (angular.isDefined(attr.dateFormat)) {\n attr.$observe('dateFormat', function (newValue) {\n datepicker.$options.dateFormat = newValue;\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges (ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function (disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate (parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function (viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n }\n validateAgainstMinMaxDate(parsedDate);\n\n if (options.dateType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true);\n return formatDate(date, options.modelDateFormat || options.dateFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.dateType === 'number') {\n return date.getTime();\n } else if (options.dateType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.dateType === 'iso') {\n return date.toISOString();\n }\n return new Date(date);\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.dateType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelDateFormat);\n } else if (options.dateType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if (isNaN(date.getTime())) {\n // var today = new Date();\n // date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);\n // }\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getDateFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function () {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getDateFormattedString());\n };\n\n function getDateFormattedString () {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (datepicker) datepicker.destroy();\n options = null;\n datepicker = null;\n });\n\n }\n };\n\n })\n\n .provider('datepickerViews', function () {\n\n // var defaults = this.defaults = {\n // dayFormat: 'dd',\n // daySplit: 7\n // };\n\n // Split array into smaller arrays\n function split (arr, size) {\n var arrays = [];\n while (arr.length > 0) {\n arrays.push(arr.splice(0, size));\n }\n return arrays;\n }\n\n // Modulus operator\n function mod (n, m) {\n return ((n % m) + m) % m;\n }\n\n this.$get = function ($dateFormatter, $dateParser, $sce) {\n\n return function (picker) {\n\n var scope = picker.$scope;\n var options = picker.$options;\n\n var lang = options.lang;\n var formatDate = function (date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n var weekDaysMin = $dateFormatter.weekdaysShort(lang);\n var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));\n var weekDaysLabelsHtml = $sce.trustAsHtml('' + weekDaysLabels.join('') + '');\n\n var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date());\n var viewDate = {year: startDate.getFullYear(), month: startDate.getMonth(), date: startDate.getDate()};\n\n var views = [{\n format: options.dayFormat,\n split: 7,\n steps: {month: 1},\n update: function (date, force) {\n if (!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getDate() !== viewDate.date || date.getDate() === 1) {\n // chaging picker current month will cause viewDate.date to be set to first day of the month,\n // in $datepicker.$selectPane, so picker would not update selected day display if\n // user picks first day of the new month.\n // As a workaround, we are always forcing update when picked date is first day of month.\n viewDate.date = picker.$date.getDate();\n picker.$updateSelected();\n }\n },\n build: function () {\n var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1);\n var firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5);\n var firstDateOffset = firstDate.getTimezoneOffset();\n var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString();\n // Handle daylight time switch\n if (firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 60e3);\n var days = [];\n var day;\n for (var i = 0; i < 42; i++) { // < 7 * 6\n day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i));\n days.push({date: day, isToday: day.toDateString() === today, label: formatDate(day, this.format), selected: picker.$date && this.isSelected(day), muted: day.getMonth() !== viewDate.month, disabled: this.isDisabled(day)});\n }\n scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat);\n scope.showLabels = true;\n scope.labels = weekDaysLabelsHtml;\n scope.rows = split(days, this.split);\n scope.isTodayDisabled = this.isDisabled(new Date());\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate();\n },\n isDisabled: function (date) {\n var time = date.getTime();\n\n // Disabled because of min/max date.\n if (time < options.minDate || time > options.maxDate) return true;\n\n // Disabled due to being a disabled day of the week\n if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true;\n\n // Disabled because of disabled date range.\n if (options.disabledDateRanges) {\n for (var i = 0; i < options.disabledDateRanges.length; i++) {\n if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) {\n return true;\n }\n }\n }\n\n return false;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualTime = picker.$date.getTime();\n var newDate;\n\n if (evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5);\n else if (evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5);\n else if (evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5);\n else if (evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'month',\n format: options.monthFormat,\n split: 4,\n steps: {year: 1},\n update: function (date, force) {\n if (!this.built || date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function () {\n // var firstMonth = new Date(viewDate.year, 0, 1);\n var months = [];\n var month;\n for (var i = 0; i < 12; i++) {\n month = new Date(viewDate.year, i, 1);\n months.push({date: month, label: formatDate(month, this.format), selected: picker.$isSelected(month), disabled: this.isDisabled(month)});\n }\n scope.title = formatDate(month, options.yearTitleFormat);\n scope.showLabels = false;\n scope.rows = split(months, this.split);\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth();\n },\n isDisabled: function (date) {\n var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualMonth = picker.$date.getMonth();\n var newDate = new Date(picker.$date);\n\n if (evt.keyCode === 37) newDate.setMonth(actualMonth - 1);\n else if (evt.keyCode === 38) newDate.setMonth(actualMonth - 4);\n else if (evt.keyCode === 39) newDate.setMonth(actualMonth + 1);\n else if (evt.keyCode === 40) newDate.setMonth(actualMonth + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'year',\n format: options.yearFormat,\n split: 4,\n steps: {year: 12},\n update: function (date, force) {\n if (!this.built || force || parseInt(date.getFullYear() / 20, 10) !== parseInt(viewDate.year / 20, 10)) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function () {\n var firstYear = viewDate.year - viewDate.year % (this.split * 3);\n var years = [];\n var year;\n for (var i = 0; i < 12; i++) {\n year = new Date(firstYear + i, 0, 1);\n years.push({date: year, label: formatDate(year, this.format), selected: picker.$isSelected(year), disabled: this.isDisabled(year)});\n }\n scope.title = years[0].label + '-' + years[years.length - 1].label;\n scope.showLabels = false;\n scope.rows = split(years, this.split);\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear();\n },\n isDisabled: function (date) {\n var lastDate = +new Date(date.getFullYear() + 1, 0, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualYear = picker.$date.getFullYear();\n var newDate = new Date(picker.$date);\n\n if (evt.keyCode === 37) newDate.setYear(actualYear - 1);\n else if (evt.keyCode === 38) newDate.setYear(actualYear - 4);\n else if (evt.keyCode === 39) newDate.setYear(actualYear + 1);\n else if (evt.keyCode === 40) newDate.setYear(actualYear + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }];\n\n return {\n views: options.minView ? Array.prototype.slice.call(views, options.minView) : views,\n viewDate: viewDate\n };\n\n };\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function ($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function (key) {\n if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // Please use $activePaneChangeListeners if you use `bsActivePane`\n // Because we removed `ngModel` as default, we rename viewChangeListeners to\n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function (pane) {\n if (angular.isUndefined(self.$panes.$active)) {\n $scope.$setActive(pane.name || 0);\n }\n self.$panes.push(pane);\n };\n\n self.$remove = function (pane) {\n var index = self.$panes.indexOf(pane);\n var active = self.$panes.$active;\n var activeIndex;\n if (angular.isString(active)) {\n activeIndex = self.$panes.map(function (pane) {\n return pane.name;\n }).indexOf(active);\n } else {\n activeIndex = self.$panes.$active;\n }\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to\n // decrement the active pane index\n activeIndex--;\n } else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n if (activeIndex >= 0 && activeIndex < self.$panes.length) {\n self.$setActive(self.$panes[activeIndex].name || activeIndex);\n } else {\n self.$setActive();\n }\n };\n\n self.$setActive = $scope.$setActive = function (value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n self.$isActive = $scope.$isActive = function ($pane, $index) {\n return self.$panes.$active === $pane.name || self.$panes.$active === $index;\n };\n\n };\n\n this.$get = function () {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function ($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function (element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink (scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // 'ngModel' does interfere with form validation\n // and status, use `bsActivePane` instead to avoid it\n if (ngModelCtrl) {\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function (newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function ($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function (newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Save tab name into scope\n scope.name = attrs.name;\n\n // Add animation class\n if (bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n attrs.$observe('disabled', function (newValue, oldValue) {\n scope.disabled = scope.$eval(newValue);\n });\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function () {\n bsTabsCtrl.$remove(scope);\n });\n\n function render () {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n render();\n });\n render();\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n titleTemplate: false,\n trigger: 'hover focus',\n keyboard: false,\n html: false,\n show: false,\n title: '',\n type: '',\n delay: 0,\n autoClose: false,\n bsEnabled: true,\n mouseDownPreventDefault: true,\n mouseDownStopPropagation: true,\n viewport: {\n selector: 'body',\n padding: 0\n }\n };\n\n this.$get = function ($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n var $body = angular.element($window.document);\n\n function TooltipFactory (element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if (options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if (options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function (isEnabled) {\n scope.$$postDigest(function () {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function () {\n scope.$$postDigest(function () {\n $tooltip.hide();\n });\n };\n scope.$show = function () {\n scope.$$postDigest(function () {\n $tooltip.show();\n });\n };\n scope.$toggle = function () {\n scope.$$postDigest(function () {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout;\n var hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData;\n var tipElement;\n var tipContainer;\n var tipScope;\n promise.then(function (data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function () {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if (options.container === 'self') {\n tipContainer = element;\n } else if (angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if (options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if (options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if (options.show) {\n scope.$$postDigest(function () {\n if (options.trigger === 'focus') {\n element[0].focus();\n } else {\n $tooltip.show();\n }\n });\n }\n\n };\n\n $tooltip.destroy = function () {\n\n // Unbind events\n unbindTriggerEvents();\n\n // Remove element\n destroyTipElement();\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $tooltip.enter = function () {\n\n clearTimeout(timeout);\n hoverState = 'in';\n if (!options.delay || !options.delay.show) {\n return $tooltip.show();\n }\n\n timeout = setTimeout(function () {\n if (hoverState === 'in') $tooltip.show();\n }, options.delay.show);\n\n };\n\n $tooltip.show = function () {\n if (!options.bsEnabled || $tooltip.$isShown) return;\n\n scope.$emit(options.prefixEvent + '.show.before', $tooltip);\n if (angular.isDefined(options.onBeforeShow) && angular.isFunction(options.onBeforeShow)) {\n options.onBeforeShow($tooltip);\n }\n var parent;\n var after;\n if (options.container) {\n parent = tipContainer;\n if (tipContainer[0].lastChild) {\n after = angular.element(tipContainer[0].lastChild);\n } else {\n after = null;\n }\n } else {\n parent = null;\n after = element;\n }\n\n\n // Hide any existing tipElement\n if (tipElement) destroyTipElement();\n // Fetch a cloned element linked from template\n tipScope = $tooltip.$scope.$new();\n tipElement = $tooltip.$element = compileData.link(tipScope, function (clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if (options.animation) tipElement.addClass(options.animation);\n // Options: type\n if (options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if (options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n if (after) {\n after.after(tipElement);\n } else {\n parent.prepend(tipElement);\n }\n\n $tooltip.$isShown = scope.$isShown = true;\n safeDigest(scope);\n\n // Now, apply placement\n $tooltip.$applyPlacement();\n\n // Once placed, animate it.\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.enter(tipElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(tipElement, parent, after).then(enterAnimateCallback);\n }\n safeDigest(scope);\n\n $$rAF(function () {\n // Once the tooltip is placed and the animation starts, make the tooltip visible\n if (tipElement) tipElement.css({visibility: 'visible'});\n\n // Bind events\n if (options.keyboard) {\n if (options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n });\n\n if (options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback () {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n if (angular.isDefined(options.onShow) && angular.isFunction(options.onShow)) {\n options.onShow($tooltip);\n }\n }\n\n $tooltip.leave = function () {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function (blur) {\n\n if (!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n if (angular.isDefined(options.onBeforeHide) && angular.isFunction(options.onBeforeHide)) {\n options.onBeforeHide($tooltip);\n }\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if (options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if (options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback () {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n if (angular.isDefined(options.onHide) && angular.isFunction(options.onHide)) {\n options.onHide($tooltip);\n }\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if (_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function (evt) {\n if (evt) { evt.preventDefault(); }\n if ($tooltip.$isShown) {\n $tooltip.leave();\n } else {\n $tooltip.enter();\n }\n };\n\n $tooltip.focus = function () {\n tipElement[0].focus();\n };\n\n $tooltip.setEnabled = function (isEnabled) {\n options.bsEnabled = isEnabled;\n };\n\n $tooltip.setViewport = function (viewport) {\n options.viewport = viewport;\n };\n\n // Protected methods\n\n $tooltip.$applyPlacement = function () {\n if (!tipElement) return;\n\n // Determine if we're doing an auto or normal placement\n var placement = options.placement;\n var autoToken = /\\s?auto?\\s?/i;\n var autoPlace = autoToken.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(autoToken, '') || defaults.placement;\n }\n\n // Need to add the position class before we get\n // the offsets\n tipElement.addClass(options.placement);\n\n // Get the position of the target element\n // and the height and width of the tooltip so we can center it.\n var elementPosition = getPosition();\n var tipWidth = tipElement.prop('offsetWidth');\n var tipHeight = tipElement.prop('offsetHeight');\n\n // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n if (/bottom/.test(originalPlacement) && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (/top/.test(originalPlacement) && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n if (/left/.test(originalPlacement) && elementPosition.left - tipWidth < viewportPosition.left) {\n placement = placement.replace('left', 'right');\n } else if (/right/.test(originalPlacement) && elementPosition.right + tipWidth > viewportPosition.width) {\n placement = placement.replace('right', 'left');\n }\n\n tipElement.removeClass(originalPlacement).addClass(placement);\n }\n\n // Get the tooltip's top and left coordinates to center it with this directive.\n var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight);\n applyPlacement(tipPosition, placement);\n };\n\n $tooltip.$onKeyUp = function (evt) {\n if (evt.which === 27 && $tooltip.$isShown) {\n $tooltip.hide();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusKeyUp = function (evt) {\n if (evt.which === 27) {\n element[0].blur();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusElementMouseDown = function (evt) {\n if (options.mouseDownPreventDefault) { evt.preventDefault(); }\n if (options.mouseDownStopPropagation) { evt.stopPropagation(); }\n // Some browsers do not auto-focus buttons (eg. Safari)\n if ($tooltip.$isShown) {\n element[0].blur();\n } else {\n element[0].focus();\n }\n };\n\n // bind/unbind events\n function bindTriggerEvents () {\n var triggers = options.trigger.split(' ');\n angular.forEach(triggers, function (trigger) {\n if (trigger === 'click' || trigger === 'contextmenu') {\n element.on(trigger, $tooltip.toggle);\n } else if (trigger !== 'manual') {\n element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n if (nodeName === 'button' && trigger !== 'hover') {\n element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n });\n }\n\n function unbindTriggerEvents () {\n var triggers = options.trigger.split(' ');\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i];\n if (trigger === 'click' || trigger === 'contextmenu') {\n element.off(trigger, $tooltip.toggle);\n } else if (trigger !== 'manual') {\n element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n if (nodeName === 'button' && trigger !== 'hover') {\n element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n }\n }\n\n function bindKeyboardEvents () {\n if (options.trigger !== 'focus') {\n tipElement.on('keyup', $tooltip.$onKeyUp);\n } else {\n element.on('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n function unbindKeyboardEvents () {\n if (options.trigger !== 'focus') {\n tipElement.off('keyup', $tooltip.$onKeyUp);\n } else {\n element.off('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n var _autoCloseEventsBinded = false;\n function bindAutoCloseEvents () {\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n // Stop propagation when clicking inside tooltip\n tipElement.on('click', stopEventPropagation);\n\n // Hide when clicking outside tooltip\n $body.on('click', $tooltip.hide);\n\n _autoCloseEventsBinded = true;\n }, 0, false);\n }\n\n function unbindAutoCloseEvents () {\n if (_autoCloseEventsBinded) {\n tipElement.off('click', stopEventPropagation);\n $body.off('click', $tooltip.hide);\n _autoCloseEventsBinded = false;\n }\n }\n\n function stopEventPropagation (event) {\n event.stopPropagation();\n }\n\n // Private methods\n\n function getPosition ($element) {\n $element = $element || (options.target || element);\n\n var el = $element[0];\n var isBody = el.tagName === 'BODY';\n\n var elRect = el.getBoundingClientRect();\n var rect = {};\n\n // IE8 has issues with angular.extend and using elRect directly.\n // By coping the values of elRect into a new object, we can continue to use extend\n /* eslint-disable guard-for-in */\n for (var p in elRect) { // eslint-disable-line\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n /* eslint-enable guard-for-in */\n\n if (rect.width === null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n rect = angular.extend({}, rect, {width: elRect.right - elRect.left, height: elRect.bottom - elRect.top});\n }\n var elOffset = isBody ? {top: 0, left: 0} : dimensions.offset(el);\n var scroll = {scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0};\n var outerDims = isBody ? {width: document.documentElement.clientWidth, height: $window.innerHeight} : null;\n\n return angular.extend({}, rect, scroll, outerDims, elOffset);\n }\n\n function getCalculatedOffset (placement, position, actualWidth, actualHeight) {\n var offset;\n var split = placement.split('-');\n\n switch (split[0]) {\n case 'right':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left + position.width\n };\n break;\n case 'bottom':\n offset = {\n top: position.top + position.height,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n case 'left':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left - actualWidth\n };\n break;\n default:\n offset = {\n top: position.top - actualHeight,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n }\n\n if (!split[1]) {\n return offset;\n }\n\n // Add support for corners @todo css\n if (split[0] === 'top' || split[0] === 'bottom') {\n switch (split[1]) {\n case 'left':\n offset.left = position.left;\n break;\n case 'right':\n offset.left = position.left + position.width - actualWidth;\n break;\n default:\n break;\n }\n } else if (split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight + position.height;\n break;\n case 'bottom':\n offset.top = position.top;\n break;\n default:\n break;\n }\n }\n\n return offset;\n }\n\n function applyPlacement (offset, placement) {\n var tip = tipElement[0];\n var width = tip.offsetWidth;\n var height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10);\n var marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10);\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0;\n if (isNaN(marginLeft)) marginLeft = 0;\n\n offset.top = offset.top + marginTop;\n offset.left = offset.left + marginLeft;\n\n // dimensions setOffset doesn't round pixel values\n // so we use setOffset directly with our own function\n dimensions.setOffset(tip, angular.extend({\n using: function (props) {\n tipElement.css({\n top: Math.round(props.top) + 'px',\n left: Math.round(props.left) + 'px',\n right: ''\n });\n }\n }, offset), 0);\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = tip.offsetWidth;\n var actualHeight = tip.offsetHeight;\n\n if (placement === 'top' && actualHeight !== height) {\n offset.top = offset.top + height - actualHeight;\n }\n\n // If it's an exotic placement, exit now instead of\n // applying a delta and changing the arrow\n if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return;\n\n var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);\n\n if (delta.left) {\n offset.left += delta.left;\n } else {\n offset.top += delta.top;\n }\n\n dimensions.setOffset(tip, offset);\n\n if (/top|right|bottom|left/.test(placement)) {\n var isVertical = /top|bottom/.test(placement);\n var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight;\n var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta (placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow (delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement () {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if ($tooltip.$isShown && tipElement !== null) {\n if (options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if (options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if (tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if (tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function ($window, $location, $sce, $parse, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n var tooltip;\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'titleTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if (angular.isDefined(dataTarget)) {\n if (falseValueRegExp.test(dataTarget)) {\n options.target = false;\n } else {\n options.target = dataTarget;\n }\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')) {\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function (newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n if (angular.isDefined(oldValue)) {\n $$rAF(function () {\n if (tooltip) tooltip.$applyPlacement();\n });\n }\n }\n });\n\n attr.$observe('disabled', function (newValue) {\n if (newValue && tooltip.$isShown) {\n tooltip.hide();\n }\n });\n\n // Support scope as an object\n if (attr.bsTooltip) {\n scope.$watch(attr.bsTooltip, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n if (angular.isDefined(oldValue)) {\n $$rAF(function () {\n if (tooltip) tooltip.$applyPlacement();\n });\n }\n }, true);\n }\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!tooltip || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n if (newValue === true) {\n tooltip.show();\n } else {\n tooltip.hide();\n }\n });\n }\n\n // Enabled binding support\n if (attr.bsEnabled) {\n scope.$watch(attr.bsEnabled, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if (!tooltip || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n if (newValue === false) {\n tooltip.setEnabled(false);\n } else {\n tooltip.setEnabled(true);\n }\n });\n }\n\n // Viewport support\n if (attr.viewport) {\n scope.$watch(attr.viewport, function (newValue) {\n if (!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n }\n\n // Initialize popover\n tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n defaultDate: 'auto',\n // uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function ($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory (element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function (date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes (time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format);\n var timeSeparator = $dateFormatter.timeSeparator(format);\n var minutesFormat = $dateFormatter.minutesFormat(format);\n var secondsFormat = $dateFormatter.secondsFormat(format);\n var showSeconds = $dateFormatter.showSeconds(format);\n var showAM = $dateFormatter.showAM(format);\n\n scope.$iconUp = options.iconUp;\n scope.$iconDown = options.iconDown;\n\n // Scope methods\n\n scope.$select = function (date, index) {\n $timepicker.select(date, index);\n };\n scope.$moveIndex = function (value, index) {\n $timepicker.$moveIndex(value, index);\n };\n scope.$switchMeridian = function (date) {\n $timepicker.switchMeridian(date);\n };\n\n // Public methods\n\n $timepicker.update = function (date) {\n // console.warn('$timepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $timepicker.$date = date;\n angular.extend(viewDate, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function (date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n controller.$dateValue = options.defaultDate === 'today' ? new Date() : new Date(1970, 0, 1);\n }\n\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function () {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function (date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function () {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i;\n var midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [];\n var hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [];\n var minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [];\n var second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function (date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function (date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function (value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function (value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function (value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function (evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours();\n var hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes();\n var minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds();\n var secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection (start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement () {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function () {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function () {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function () {\n if ((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n if ($timepicker.$element) $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n if (element) element.on('keydown', $timepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $timepicker.hide;\n $timepicker.hide = function (blur) {\n if (!$timepicker.$isShown) return;\n if ($timepicker.$element) $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n if (element) element.off('keydown', $timepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $timepicker;\n\n }\n\n timepickerFactory.defaults = defaults;\n return timepickerFactory;\n\n };\n\n })\n\n\n .directive('bsTimepicker', function ($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {\n\n var defaults = $timepicker.defaults;\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent', 'defaultDate'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Initialize timepicker\n if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';\n var timepicker = $timepicker(element, controller, options);\n options = timepicker.$options;\n\n var lang = options.lang;\n var formatDate = function (date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!timepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);\n if (newValue === true) {\n timepicker.show();\n } else {\n timepicker.hide();\n }\n });\n }\n\n // Initialize parser\n var dateParser = $dateParser({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function (key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n if (angular.isDefined(attr[key])) {\n attr.$observe(key, function (newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n if (!isNaN(timepicker.$options[key])) timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\n }\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);\n timepicker.update(controller.$dateValue);\n }, true);\n\n function validateAgainstMinMaxTime (parsedTime) {\n if (!angular.isDate(parsedTime)) return;\n var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;\n var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (!isValid) {\n return;\n }\n controller.$dateValue = parsedTime;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function (viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n controller.$setValidity('date', true);\n return null;\n }\n var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedTime || isNaN(parsedTime.getTime())) {\n controller.$setValidity('date', false);\n // Return undefined, causes ngModelController to\n // invalidate model value\n return undefined;\n }\n validateAgainstMinMaxTime(parsedTime);\n\n if (options.timeType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true);\n return formatDate(date, options.modelTimeFormat || options.timeFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.timeType === 'number') {\n return date.getTime();\n } else if (options.timeType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.timeType === 'iso') {\n return date.toISOString();\n }\n return new Date(date);\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function () {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString () {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.scrollspy', ['mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$scrollspy', function () {\n\n // Pool of registered spies\n var spies = this.$$spies = {};\n\n var defaults = this.defaults = {\n debounce: 150,\n throttle: 100,\n offset: 100\n };\n\n this.$get = function ($window, $document, $rootScope, dimensions, debounce, throttle) {\n\n var windowEl = angular.element($window);\n var docEl = angular.element($document.prop('documentElement'));\n var bodyEl = angular.element($window.document.body);\n\n // Helper functions\n\n function nodeName (element, name) {\n return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase();\n }\n\n function ScrollSpyFactory (config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n if (!options.element) options.element = bodyEl;\n var isWindowSpy = nodeName(options.element, 'body');\n var scrollEl = isWindowSpy ? windowEl : options.element;\n var scrollId = isWindowSpy ? 'window' : options.id;\n\n // Use existing spy\n if (spies[scrollId]) {\n spies[scrollId].$$count++;\n return spies[scrollId];\n }\n\n var $scrollspy = {};\n\n // Private vars\n var unbindViewContentLoaded;\n var unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n /* eslint-disable no-unused-vars */\n var viewportHeight;\n /* eslint-enable no-unused-vars */\n var scrollTop;\n\n $scrollspy.init = function () {\n\n // Setup internal ref counter\n this.$$count = 1;\n\n // Bind events\n debouncedCheckPosition = debounce(this.checkPosition, options.debounce);\n throttledCheckPosition = throttle(this.checkPosition, options.throttle);\n scrollEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', debouncedCheckPosition);\n scrollEl.on('scroll', throttledCheckPosition);\n\n debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce);\n unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets);\n unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets);\n debouncedCheckOffsets();\n\n // Register spy for reuse\n if (scrollId) {\n spies[scrollId] = $scrollspy;\n }\n\n };\n\n $scrollspy.destroy = function () {\n\n // Check internal ref counter\n this.$$count--;\n if (this.$$count > 0) {\n return;\n }\n\n // Unbind events\n scrollEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', debouncedCheckPosition);\n scrollEl.off('scroll', throttledCheckPosition);\n unbindViewContentLoaded();\n unbindIncludeContentLoaded();\n if (scrollId) {\n delete spies[scrollId];\n }\n };\n\n $scrollspy.checkPosition = function () {\n\n // Not ready yet\n if (!sortedElements.length) return;\n\n // Calculate the scroll position\n scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0;\n\n // Calculate the viewport height for use by the components\n viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight'));\n\n // Activate first element if scroll is smaller\n if (scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) {\n return $scrollspy.$activateElement(sortedElements[0]);\n }\n\n // Activate proper element\n for (var i = sortedElements.length; i--;) {\n if (angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue;\n if (activeTarget === sortedElements[i].target) continue;\n if (scrollTop < sortedElements[i].offsetTop) continue;\n if (sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue;\n return $scrollspy.$activateElement(sortedElements[i]);\n }\n\n };\n\n $scrollspy.checkPositionWithEventLoop = function () {\n // IE 9 throws an error if we use 'this' instead of '$scrollspy'\n // in this setTimeout call\n setTimeout($scrollspy.checkPosition, 1);\n };\n\n // Protected methods\n\n $scrollspy.$activateElement = function (element) {\n if (activeTarget) {\n var activeElement = $scrollspy.$getTrackedElement(activeTarget);\n if (activeElement) {\n activeElement.source.removeClass('active');\n if (nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) {\n activeElement.source.parent().parent().removeClass('active');\n }\n }\n }\n activeTarget = element.target;\n element.source.addClass('active');\n if (nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) {\n element.source.parent().parent().addClass('active');\n }\n };\n\n $scrollspy.$getTrackedElement = function (target) {\n return trackedElements.filter(function (obj) {\n return obj.target === target;\n })[0];\n };\n\n // Track offsets behavior\n\n $scrollspy.checkOffsets = function () {\n\n angular.forEach(trackedElements, function (trackedElement) {\n var targetElement = document.querySelector(trackedElement.target);\n trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null;\n if (options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1;\n });\n\n sortedElements = trackedElements\n .filter(function (el) {\n return el.offsetTop !== null;\n })\n .sort(function (a, b) {\n return a.offsetTop - b.offsetTop;\n });\n\n debouncedCheckPosition();\n\n };\n\n $scrollspy.trackElement = function (target, source) {\n trackedElements.push({target: target, source: source});\n };\n\n $scrollspy.untrackElement = function (target, source) {\n var toDelete;\n for (var i = trackedElements.length; i--;) {\n if (trackedElements[i].target === target && trackedElements[i].source === source) {\n toDelete = i;\n break;\n }\n }\n trackedElements.splice(toDelete, 1);\n };\n\n $scrollspy.activate = function (i) {\n trackedElements[i].addClass('active');\n };\n\n // Initialize plugin\n\n $scrollspy.init();\n return $scrollspy;\n\n }\n\n return ScrollSpyFactory;\n\n };\n\n })\n\n .directive('bsScrollspy', function ($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'EAC',\n link: function postLink (scope, element, attr) {\n\n var options = {scope: scope};\n angular.forEach(['offset', 'target'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n var scrollspy = $scrollspy(options);\n scrollspy.trackElement(options.target, element);\n\n scope.$on('$destroy', function () {\n if (scrollspy) {\n scrollspy.untrackElement(options.target, element);\n scrollspy.destroy();\n }\n options = null;\n scrollspy = null;\n });\n\n }\n };\n\n })\n\n\n .directive('bsScrollspyList', function ($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'A',\n compile: function postLink (element, attr) {\n var children = element[0].querySelectorAll('li > a[href]');\n angular.forEach(children, function (child) {\n var childEl = angular.element(child);\n childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href'));\n });\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' ',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok',\n toggle: false\n };\n\n this.$get = function ($window, $document, $rootScope, $tooltip, $timeout) {\n\n // var bodyEl = angular.element($window.document.body);\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n\n function SelectFactory (element, controller, config) {\n\n var $select = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $select = $tooltip(element, options);\n var scope = $select.$scope;\n\n scope.$matches = [];\n if (options.multiple) {\n scope.$activeIndex = [];\n } else {\n scope.$activeIndex = -1;\n }\n scope.$isMultiple = options.multiple;\n scope.$showAllNoneButtons = options.allNoneButtons && options.multiple;\n scope.$iconCheckmark = options.iconCheckmark;\n scope.$allText = options.allText;\n scope.$noneText = options.noneText;\n\n scope.$activate = function (index) {\n scope.$$postDigest(function () {\n $select.activate(index);\n });\n };\n\n scope.$select = function (index, evt) {\n scope.$$postDigest(function () {\n $select.select(index);\n });\n };\n\n scope.$isVisible = function () {\n return $select.$isVisible();\n };\n\n scope.$isActive = function (index) {\n return $select.$isActive(index);\n };\n\n scope.$selectAll = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (!scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n scope.$selectNone = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n // Public methods\n\n $select.update = function (matches) {\n scope.$matches = matches;\n $select.$updateActiveIndex();\n };\n\n $select.activate = function (index) {\n if (options.multiple) {\n if ($select.$isActive(index)) {\n scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1);\n } else {\n scope.$activeIndex.push(index);\n }\n if (options.sort) scope.$activeIndex.sort(function (a, b) { return a - b; }); // use numeric sort instead of default sort\n } else {\n scope.$activeIndex = index;\n }\n return scope.$activeIndex;\n };\n\n $select.select = function (index) {\n if (angular.isUndefined(index) || index < 0 || index >= scope.$matches.length) { return; }\n var value = scope.$matches[index].value;\n scope.$apply(function () {\n $select.activate(index);\n if (options.multiple) {\n controller.$setViewValue(scope.$activeIndex.map(function (index) {\n if (angular.isUndefined(scope.$matches[index])) {\n return null;\n }\n return scope.$matches[index].value;\n }));\n } else {\n if (options.toggle) {\n controller.$setViewValue((value === controller.$modelValue) ? undefined : value);\n } else {\n controller.$setViewValue(value);\n }\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n if (angular.isDefined(options.onSelect) && angular.isFunction(options.onSelect)) {\n options.onSelect(value, index, $select);\n }\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function () {\n if (options.multiple) {\n if (angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function (value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = [];\n }\n } else {\n if (angular.isDefined(controller.$modelValue) && scope.$matches.length) {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n } else {\n scope.$activeIndex = -1;\n }\n }\n };\n\n $select.$isVisible = function () {\n if (!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function (index) {\n if (options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n }\n return scope.$activeIndex === index;\n };\n\n $select.$getIndex = function (value) {\n var index;\n for (index = scope.$matches.length; index--;) {\n if (angular.equals(scope.$matches[index].value, value)) break;\n }\n return index;\n };\n\n $select.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n targetEl.triggerHandler('click');\n }\n };\n\n $select.$onKeyDown = function (evt) {\n if (!/(9|13|38|40)/.test(evt.keyCode)) return;\n // Let tab propagate\n if (evt.keyCode !== 9) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if (!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if (evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n $select.$isIE = function () {\n var ua = $window.navigator.userAgent;\n return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0;\n };\n\n $select.$selectScrollFix = function (e) {\n if ($document[0].activeElement.tagName === 'UL') {\n e.preventDefault();\n e.stopImmediatePropagation();\n e.target.focus();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function () {\n _show();\n if (options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if (options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function () {\n if (!options.multiple && angular.isUndefined(controller.$modelValue)) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if (options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function ($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent', 'toggle'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // bind functions from the attrs to the show, hide and select events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide', 'onSelect'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Only parse data-multiple. Angular sets existence attributes to true (multiple/required/etc), they apply this\n // to data-multiple as well for some reason, so we'll parse this ourselves and disregard multiple\n var dataMultiple = element.attr('data-multiple');\n if (angular.isDefined(dataMultiple)) {\n if (falseValueRegExp.test(dataMultiple)) {\n options.multiple = false;\n } else {\n options.multiple = dataMultiple;\n }\n }\n\n // Add support for select markup\n if (element[0].nodeName.toLowerCase() === 'select') {\n var inputEl = element;\n inputEl.css('display', 'none');\n element = angular.element('');\n inputEl.after(element);\n }\n\n // Build proper bsOptions\n var parsedOptions = $parseOptions(attr.bsOptions);\n\n // Initialize select\n var select = $select(element, controller, options);\n\n if (select.$isIE()) {\n element[0].addEventListener('blur', select.$selectScrollFix);\n }\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watch(watchedOptions, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller)\n .then(function (values) {\n select.update(values);\n controller.$render();\n });\n }, true);\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);\n select.$updateActiveIndex();\n controller.$render();\n }, true);\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var selected;\n var index;\n if (options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function (value) {\n index = select.$getIndex(value);\n return index !== -1 ? select.$scope.$matches[index].label : false;\n }).filter(angular.isDefined);\n if (selected.length > (options.maxLength || defaults.maxLength)) {\n selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);\n } else {\n selected = selected.join(', ');\n }\n } else {\n index = select.$getIndex(controller.$modelValue);\n selected = index !== -1 ? select.$scope.$matches[index].label : false;\n }\n element.html((selected || options.placeholder) + (options.caretHtml || defaults.caretHtml));\n };\n\n if (options.multiple) {\n controller.$isEmpty = function (value) {\n return !value || value.length === 0;\n };\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (select) select.destroy();\n options = null;\n select = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function ($tooltip) {\n\n function PopoverFactory (element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if (options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function ($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr) {\n\n var popover;\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if (angular.isDefined(dataTarget)) {\n if (falseValueRegExp.test(dataTarget)) {\n options.target = false;\n } else {\n options.target = dataTarget;\n }\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n if (angular.isDefined(oldValue)) {\n requestAnimationFrame(function () {\n if (popover) popover.$applyPlacement();\n });\n }\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsPopover) {\n scope.$watch(attr.bsPopover, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n if (angular.isDefined(oldValue)) {\n requestAnimationFrame(function () {\n if (popover) popover.$applyPlacement();\n });\n }\n }, true);\n }\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!popover || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);\n if (newValue === true) {\n popover.show();\n } else {\n popover.hide();\n }\n });\n }\n\n // Viewport support\n if (attr.viewport) {\n scope.$watch(attr.viewport, function (newValue) {\n if (!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n }\n\n // Initialize popover\n popover = $popover(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (popover) popover.destroy();\n options = null;\n popover = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.navbar', [])\n\n .provider('$navbar', function () {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n routeAttr: 'data-match-route',\n strict: false\n };\n\n this.$get = function () {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsNavbar', function ($window, $location, $navbar) {\n\n var defaults = $navbar.defaults;\n\n return {\n restrict: 'A',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = angular.copy(defaults);\n angular.forEach(Object.keys(defaults), function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Watch for the $location\n scope.$watch(function () {\n\n return $location.path();\n\n }, function (newValue, oldValue) {\n\n var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']');\n\n angular.forEach(liElements, function (li) {\n\n var liElement = angular.element(li);\n var pattern = liElement.attr(options.routeAttr).replace('/', '\\\\/');\n if (options.strict) {\n pattern = '^' + pattern + '$';\n }\n var regexp = new RegExp(pattern, 'i');\n\n if (regexp.test(newValue)) {\n liElement.addClass(options.activeClass);\n } else {\n liElement.removeClass(options.activeClass);\n }\n\n });\n\n });\n\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n customClass: '',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true,\n size: null\n };\n\n this.$get = function ($window, $rootScope, $bsCompiler, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n\n var backdropCount = 0;\n var dialogBaseZindex = 1050;\n var backdropBaseZindex = 1040;\n\n var validSizes = {\n lg: 'modal-lg',\n sm: 'modal-sm'\n };\n\n function ModalFactory (config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if (!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function (key) {\n if (options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function () {\n scope.$$postDigest(function () {\n $modal.hide();\n });\n };\n scope.$show = function () {\n scope.$$postDigest(function () {\n $modal.show();\n });\n };\n scope.$toggle = function () {\n scope.$$postDigest(function () {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData;\n var modalElement;\n var modalScope;\n var backdropElement = angular.element('
');\n backdropElement.css({position: 'fixed', top: '0px', left: '0px', bottom: '0px', right: '0px'});\n promise.then(function (data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function () {\n\n // Options: show\n if (options.show) {\n scope.$$postDigest(function () {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function () {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if (backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function () {\n if ($modal.$isShown) return;\n\n var parent;\n var after;\n if (angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if (modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function (clonedElement, scope) {});\n\n if (options.backdrop) {\n // set z-index\n modalElement.css({'z-index': dialogBaseZindex + (backdropCount * 20)});\n backdropElement.css({'z-index': backdropBaseZindex + (backdropCount * 20)});\n\n // increment number of backdrops\n backdropCount++;\n }\n\n if (scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) {\n return;\n }\n if (angular.isDefined(options.onBeforeShow) && angular.isFunction(options.onBeforeShow)) {\n options.onBeforeShow($modal);\n }\n\n // Set the initial positioning.\n modalElement.css({display: 'block'}).addClass(options.placement);\n\n // Options: customClass\n if (options.customClass) {\n modalElement.addClass(options.customClass);\n }\n\n // Options: size\n if (options.size && validSizes[options.size]) {\n angular.element(findElement('.modal-dialog', modalElement[0])).addClass(validSizes[options.size]);\n }\n\n // Options: animation\n if (options.animation) {\n if (options.backdrop) {\n backdropElement.addClass(options.backdropAnimation);\n }\n modalElement.addClass(options.animation);\n }\n\n if (options.backdrop) {\n $animate.enter(backdropElement, bodyElement, null);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.enter(modalElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(modalElement, parent, after).then(enterAnimateCallback);\n }\n\n $modal.$isShown = scope.$isShown = true;\n safeDigest(scope);\n // Focus once the enter-animation has started\n // Weird PhantomJS bug hack\n var el = modalElement[0];\n requestAnimationFrame(function () {\n el.focus();\n });\n\n bodyElement.addClass(options.prefixClass + '-open');\n if (options.animation) {\n bodyElement.addClass(options.prefixClass + '-with-' + options.animation);\n }\n\n // Bind events\n bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback () {\n scope.$emit(options.prefixEvent + '.show', $modal);\n if (angular.isDefined(options.onShow) && angular.isFunction(options.onShow)) {\n options.onShow($modal);\n }\n }\n\n $modal.hide = function () {\n if (!$modal.$isShown) return;\n\n if (scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n if (angular.isDefined(options.onBeforeHide) && angular.isFunction(options.onBeforeHide)) {\n options.onBeforeHide($modal);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if (options.backdrop) {\n // decrement number of backdrops\n backdropCount--;\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback () {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n if (angular.isDefined(options.onHide) && angular.isFunction(options.onHide)) {\n options.onHide($modal);\n }\n bodyElement.removeClass(options.prefixClass + '-open');\n if (options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function () {\n if ($modal.$isShown) {\n $modal.hide();\n } else {\n $modal.show();\n }\n };\n\n $modal.focus = function () {\n modalElement[0].focus();\n };\n\n // Protected methods\n\n $modal.$onKeyUp = function (evt) {\n\n if (evt.which === 27 && $modal.$isShown) {\n $modal.hide();\n evt.stopPropagation();\n }\n\n };\n\n function bindBackdropEvents () {\n if (options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents () {\n if (options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents () {\n if (options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents () {\n if (options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private helpers\n\n function hideOnBackdropClick (evt) {\n if (evt.target !== evt.currentTarget) return;\n if (options.backdrop === 'static') {\n $modal.focus();\n } else {\n $modal.hide();\n }\n }\n\n function preventEventDefault (evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement () {\n if ($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if (modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if (modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function ($window, $sce, $parse, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass', 'customClass', 'modalClass', 'size'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Options: alias modalClass to customClass\n if (options.modalClass) {\n options.customClass = options.modalClass;\n }\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsModal) {\n scope.$watch(attr.bsModal, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize modal\n var modal = $modal(options);\n\n // Trigger\n element.on(attr.trigger || 'click', modal.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (modal) modal.destroy();\n options = null;\n modal = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function ($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory (element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n /* var scope = */$dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function (evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if (!items.length) return;\n var index;\n angular.forEach(items, function (el, i) {\n if (matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if (evt.keyCode === 38 && index > 0) index--;\n else if (evt.keyCode === 40 && index < items.length - 1) index++;\n else if (angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function () {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n if (options.keyboard && $dropdown.$element) $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n if (parentEl.hasClass('dropdown')) parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function () {\n if (!$dropdown.$isShown) return;\n if (options.keyboard && $dropdown.$element) $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n if (parentEl.hasClass('dropdown')) parentEl.removeClass('open');\n hide();\n };\n\n var destroy = $dropdown.destroy;\n $dropdown.destroy = function () {\n bodyEl.off('click', onBodyClick);\n destroy();\n };\n\n // Private functions\n\n function onBodyClick (evt) {\n if (evt.target === element[0]) return;\n return evt.target !== element[0] && $dropdown.hide();\n }\n\n return $dropdown;\n\n }\n\n return DropdownFactory;\n\n };\n\n })\n\n .directive('bsDropdown', function ($window, $sce, $dropdown) {\n\n return {\n restrict: 'EAC',\n scope: true,\n compile: function (tElement, tAttrs) {\n\n // Support for inlined template (next sibling)\n // It must be fetched before compilation\n if (!tAttrs.bsDropdown) {\n var nextSibling = tElement[0].nextSibling;\n while (nextSibling && nextSibling.nodeType !== 1) {\n nextSibling = nextSibling.nextSibling;\n }\n if (nextSibling && nextSibling.className.split(' ').indexOf('dropdown-menu') >= 0) {\n tAttrs.template = nextSibling.outerHTML;\n tAttrs.templateUrl = undefined;\n nextSibling.parentNode.removeChild(nextSibling);\n }\n }\n\n return function postLink (scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id', 'autoClose'], function (key) {\n if (angular.isDefined(tAttrs[key])) options[key] = tAttrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Support scope as an object\n if (attr.bsDropdown) {\n scope.$watch(attr.bsDropdown, function (newValue, oldValue) {\n scope.content = newValue;\n }, true);\n }\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!dropdown || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);\n if (newValue === true) {\n dropdown.show();\n } else {\n dropdown.hide();\n }\n });\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (dropdown) dropdown.destroy();\n options = null;\n dropdown = null;\n });\n\n };\n }\n };\n\n });\n","'use strict';\n\nif (angular.version.minor < 3 && angular.version.dot < 14) {\n angular.module('ng')\n\n .factory('$$rAF', function ($window, $timeout) {\n\n var requestAnimationFrame = $window.requestAnimationFrame ||\n $window.webkitRequestAnimationFrame ||\n $window.mozRequestAnimationFrame;\n\n var cancelAnimationFrame = $window.cancelAnimationFrame ||\n $window.webkitCancelAnimationFrame ||\n $window.mozCancelAnimationFrame ||\n $window.webkitCancelRequestAnimationFrame;\n\n var rafSupported = !!requestAnimationFrame;\n var raf = rafSupported ?\n function (fn) {\n var id = requestAnimationFrame(fn);\n return function () {\n cancelAnimationFrame(id);\n };\n } :\n function (fn) {\n var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666\n return function () {\n $timeout.cancel(timer);\n };\n };\n\n raf.supported = rafSupported;\n\n return raf;\n\n });\n}\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.parseOptions', [])\n\n .provider('$parseOptions', function () {\n\n var defaults = this.defaults = {\n regexp: /^\\s*(.*?)(?:\\s+as\\s+(.*?))?(?:\\s+group\\s+by\\s+(.*))?\\s+for\\s+(?:([\\$\\w][\\$\\w]*)|(?:\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)))\\s+in\\s+(.*?)(?:\\s+track\\s+by\\s+(.*?))?$/\n };\n\n this.$get = function ($parse, $q) {\n\n function ParseOptionsFactory (attr, config) {\n\n var $parseOptions = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n $parseOptions.$values = [];\n\n // Private vars\n var match;\n var displayFn;\n var valueName;\n /* eslint-disable no-unused-vars */\n var keyName;\n var groupByFn;\n /* eslint-enable no-unused-vars */\n var valueFn;\n var valuesFn;\n\n $parseOptions.init = function () {\n $parseOptions.$match = match = attr.match(options.regexp);\n displayFn = $parse(match[2] || match[1]);\n valueName = match[4] || match[6];\n keyName = match[5];\n groupByFn = $parse(match[3] || '');\n valueFn = $parse(match[2] ? match[1] : valueName);\n valuesFn = $parse(match[7]);\n };\n\n $parseOptions.valuesFn = function (scope, controller) {\n return $q.when(valuesFn(scope, controller))\n .then(function (values) {\n if (!angular.isArray(values)) {\n values = [];\n }\n $parseOptions.$values = values.length ? parseValues(values, scope) : [];\n return $parseOptions.$values;\n });\n };\n\n $parseOptions.displayValue = function (modelValue) {\n var scope = {};\n scope[valueName] = modelValue;\n return displayFn(scope);\n };\n\n // Private functions\n\n function parseValues (values, scope) {\n return values.map(function (match, index) {\n var locals = {};\n var label;\n var value;\n locals[valueName] = match;\n label = displayFn(scope, locals);\n value = valueFn(scope, locals);\n return {label: label, value: value, index: index};\n });\n }\n\n $parseOptions.init();\n return $parseOptions;\n\n }\n\n return ParseOptionsFactory;\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dimensions', [])\n\n .factory('dimensions', function () {\n\n var fn = {};\n\n /**\n * Test the element nodeName\n * @param element\n * @param name\n */\n var nodeName = fn.nodeName = function (element, name) {\n return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase();\n };\n\n /**\n * Returns the element computed style\n * @param element\n * @param prop\n * @param extra\n */\n fn.css = function (element, prop, extra) {\n var value;\n if (element.currentStyle) { // IE\n value = element.currentStyle[prop];\n } else if (window.getComputedStyle) {\n value = window.getComputedStyle(element)[prop];\n } else {\n value = element.style[prop];\n }\n return extra === true ? parseFloat(value) || 0 : value;\n };\n\n /**\n * Provides read-only equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.offset = function (element) {\n var boxRect = element.getBoundingClientRect();\n var docElement = element.ownerDocument;\n return {\n width: boxRect.width || element.offsetWidth,\n height: boxRect.height || element.offsetHeight,\n top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0),\n left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0)\n };\n };\n\n /**\n * Provides set equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip\n * @url http://api.jquery.com/offset/\n * @param element\n * @param options\n * @param i\n */\n fn.setOffset = function (element, options, i) {\n var curPosition;\n var curLeft;\n var curCSSTop;\n var curTop;\n var curOffset;\n var curCSSLeft;\n var calculatePosition;\n var position = fn.css(element, 'position');\n var curElem = angular.element(element);\n var props = {};\n\n // Set position first, in-case top/left are set even on static elem\n if (position === 'static') {\n element.style.position = 'relative';\n }\n\n curOffset = fn.offset(element);\n curCSSTop = fn.css(element, 'top');\n curCSSLeft = fn.css(element, 'left');\n calculatePosition = (position === 'absolute' || position === 'fixed') &&\n (curCSSTop + curCSSLeft).indexOf('auto') > -1;\n\n // Need to be able to calculate position if either\n // top or left is auto and position is either absolute or fixed\n if (calculatePosition) {\n curPosition = fn.position(element);\n curTop = curPosition.top;\n curLeft = curPosition.left;\n } else {\n curTop = parseFloat(curCSSTop) || 0;\n curLeft = parseFloat(curCSSLeft) || 0;\n }\n\n if (angular.isFunction(options)) {\n options = options.call(element, i, curOffset);\n }\n\n if (options.top !== null) {\n props.top = (options.top - curOffset.top) + curTop;\n }\n if (options.left !== null) {\n props.left = (options.left - curOffset.left) + curLeft;\n }\n\n if ('using' in options) {\n options.using.call(curElem, props);\n } else {\n curElem.css({\n top: props.top + 'px',\n left: props.left + 'px'\n });\n }\n };\n\n /**\n * Provides read-only equivalent of jQuery's position function\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.position = function (element) {\n\n var offsetParentRect = {top: 0, left: 0};\n var offsetParentEl;\n var offset;\n\n // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent\n if (fn.css(element, 'position') === 'fixed') {\n\n // We assume that getBoundingClientRect is available when computed position is fixed\n offset = element.getBoundingClientRect();\n\n } else {\n\n // Get *real* offsetParentEl\n offsetParentEl = offsetParentElement(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentEl, 'html')) {\n offsetParentRect = fn.offset(offsetParentEl);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentEl, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentEl, 'borderLeftWidth', true);\n }\n\n // Subtract parent offsets and element margins\n return {\n width: element.offsetWidth,\n height: element.offsetHeight,\n top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true),\n left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true)\n };\n\n };\n\n /**\n * Returns the closest, non-statically positioned offsetParent of a given element\n * @required-by fn.position\n * @param element\n */\n function offsetParentElement (element) {\n var docElement = element.ownerDocument;\n var offsetParent = element.offsetParent || docElement;\n if (nodeName(offsetParent, '#document')) return docElement.documentElement;\n while (offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') {\n offsetParent = offsetParent.offsetParent;\n }\n return offsetParent || docElement.documentElement;\n }\n\n /**\n * Provides equivalent of jQuery's height function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/height/\n * @param element\n * @param outer\n */\n fn.height = function (element, outer) {\n var value = element.offsetHeight;\n if (outer) {\n value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true);\n } else {\n value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true);\n }\n return value;\n };\n\n /**\n * Provides equivalent of jQuery's width function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/width/\n * @param element\n * @param outer\n */\n fn.width = function (element, outer) {\n var value = element.offsetWidth;\n if (outer) {\n value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true);\n } else {\n value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true);\n }\n return value;\n };\n\n return fn;\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.debounce', [])\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L693\n.factory('debounce', function ($timeout) {\n return function (func, wait, immediate) {\n var timeout = null;\n return function () {\n var context = this;\n var args = arguments;\n var callNow = immediate && !timeout;\n if (timeout) {\n $timeout.cancel(timeout);\n }\n timeout = $timeout(function later () {\n timeout = null;\n if (!immediate) {\n func.apply(context, args);\n }\n }, wait, false);\n if (callNow) {\n func.apply(context, args);\n }\n return timeout;\n };\n };\n})\n\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L661\n.factory('throttle', function ($timeout) {\n return function (func, wait, options) {\n var timeout = null;\n if (!options) options = {};\n return function () {\n var context = this;\n var args = arguments;\n if (!timeout) {\n if (options.leading !== false) {\n func.apply(context, args);\n }\n timeout = $timeout(function later () {\n timeout = null;\n if (options.trailing !== false) {\n func.apply(context, args);\n }\n }, wait, false);\n }\n };\n };\n});\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dateParser', [])\n\n.provider('$dateParser', function ($localeProvider) {\n\n // define a custom ParseDate object to use instead of native Date\n // to avoid date values wrapping when setting date component values\n function ParseDate () {\n this.year = 1970;\n this.month = 0;\n this.day = 1;\n this.hours = 0;\n this.minutes = 0;\n this.seconds = 0;\n this.milliseconds = 0;\n }\n\n ParseDate.prototype.setMilliseconds = function (value) { this.milliseconds = value; };\n ParseDate.prototype.setSeconds = function (value) { this.seconds = value; };\n ParseDate.prototype.setMinutes = function (value) { this.minutes = value; };\n ParseDate.prototype.setHours = function (value) { this.hours = value; };\n ParseDate.prototype.getHours = function () { return this.hours; };\n ParseDate.prototype.setDate = function (value) { this.day = value; };\n ParseDate.prototype.setMonth = function (value) { this.month = value; };\n ParseDate.prototype.setFullYear = function (value) { this.year = value; };\n ParseDate.prototype.fromDate = function (value) {\n this.year = value.getFullYear();\n this.month = value.getMonth();\n this.day = value.getDate();\n this.hours = value.getHours();\n this.minutes = value.getMinutes();\n this.seconds = value.getSeconds();\n this.milliseconds = value.getMilliseconds();\n return this;\n };\n\n ParseDate.prototype.toDate = function () {\n return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);\n };\n\n var proto = ParseDate.prototype;\n\n function noop () {\n }\n\n function isNumeric (n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n function indexOfCaseInsensitive (array, value) {\n var len = array.length;\n var str = value.toString().toLowerCase();\n for (var i = 0; i < len; i++) {\n if (array[i].toLowerCase() === str) { return i; }\n }\n return -1; // Return -1 per the \"Array.indexOf()\" method.\n }\n\n var defaults = this.defaults = {\n format: 'shortDate',\n strict: false\n };\n\n this.$get = function ($locale, dateFilter) {\n\n var DateParserFactory = function (config) {\n\n var options = angular.extend({}, defaults, config);\n\n var $dateParser = {};\n\n /* eslint-disable key-spacing, quote-props */\n var regExpMap = {\n 'sss' : '[0-9]{3}',\n 'ss' : '[0-5][0-9]',\n 's' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'mm' : '[0-5][0-9]',\n 'm' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'HH' : '[01][0-9]|2[0-3]',\n 'H' : options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]',\n 'hh' : '[0][1-9]|[1][012]',\n 'h' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'a' : 'AM|PM',\n 'EEEE' : $locale.DATETIME_FORMATS.DAY.join('|'),\n 'EEE' : $locale.DATETIME_FORMATS.SHORTDAY.join('|'),\n 'dd' : '0[1-9]|[12][0-9]|3[01]',\n 'd' : options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]',\n 'MMMM' : $locale.DATETIME_FORMATS.MONTH.join('|'),\n 'MMM' : $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),\n 'MM' : '0[1-9]|1[012]',\n 'M' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'yyyy' : '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}',\n 'yy' : '[0-9]{2}',\n 'y' : options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}'\n };\n\n var setFnMap = {\n 'sss' : proto.setMilliseconds,\n 'ss' : proto.setSeconds,\n 's' : proto.setSeconds,\n 'mm' : proto.setMinutes,\n 'm' : proto.setMinutes,\n 'HH' : proto.setHours,\n 'H' : proto.setHours,\n 'hh' : proto.setHours,\n 'h' : proto.setHours,\n 'EEEE' : noop,\n 'EEE' : noop,\n 'dd' : proto.setDate,\n 'd' : proto.setDate,\n 'a' : function (value) { var hours = this.getHours() % 12; return this.setHours(value.match(/pm/i) ? hours + 12 : hours); },\n 'MMMM' : function (value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); },\n 'MMM' : function (value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); },\n 'MM' : function (value) { return this.setMonth(1 * value - 1); },\n 'M' : function (value) { return this.setMonth(1 * value - 1); },\n 'yyyy' : proto.setFullYear,\n 'yy' : function (value) { return this.setFullYear(2000 + 1 * value); },\n 'y' : function (value) { return (1 * value <= 50 && value.length === 2) ? this.setFullYear(2000 + 1 * value) : this.setFullYear(1 * value); }\n };\n /* eslint-enable key-spacing, quote-props */\n\n var regex;\n var setMap;\n\n $dateParser.init = function () {\n $dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format;\n regex = regExpForFormat($dateParser.$format);\n setMap = setMapForFormat($dateParser.$format);\n };\n\n $dateParser.isValid = function (date) {\n if (angular.isDate(date)) return !isNaN(date.getTime());\n return regex.test(date);\n };\n\n $dateParser.parse = function (value, baseDate, format, timezone) {\n // check for date format special names\n if (format) format = $locale.DATETIME_FORMATS[format] || format;\n if (angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format, timezone);\n var formatRegex = format ? regExpForFormat(format) : regex;\n var formatSetMap = format ? setMapForFormat(format) : setMap;\n var matches = formatRegex.exec(value);\n if (!matches) return false;\n // use custom ParseDate object to set parsed values\n var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0));\n for (var i = 0; i < matches.length - 1; i++) {\n if (formatSetMap[i]) formatSetMap[i].call(date, matches[i + 1]);\n }\n // convert back to native Date object\n var newDate = date.toDate();\n\n // check new native Date object for day values overflow\n if (parseInt(date.day, 10) !== newDate.getDate()) {\n return false;\n }\n\n return newDate;\n };\n\n $dateParser.getDateForAttribute = function (key, value) {\n var date;\n\n if (value === 'today') {\n var today = new Date();\n date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, (key === 'minDate' ? 0 : -1));\n } else if (angular.isString(value) && value.match(/^\".+\"$/)) { // Support {{ dateObj }}\n date = new Date(value.substr(1, value.length - 2));\n } else if (isNumeric(value)) {\n date = new Date(parseInt(value, 10));\n } else if (angular.isString(value) && value.length === 0) { // Reset date\n date = key === 'minDate' ? -Infinity : +Infinity;\n } else {\n date = new Date(value);\n }\n\n return date;\n };\n\n $dateParser.getTimeForAttribute = function (key, value) {\n var time;\n\n if (value === 'now') {\n time = new Date().setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && value.match(/^\".+\"$/)) {\n time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1);\n } else if (isNumeric(value)) {\n time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && value.length === 0) { // Reset time\n time = key === 'minTime' ? -Infinity : +Infinity;\n } else {\n time = $dateParser.parse(value, new Date(1970, 0, 1, 0));\n }\n\n return time;\n };\n\n /* Handle switch to/from daylight saving.\n * Hours may be non-zero on daylight saving cut-over:\n * > 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function (date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n /* Correct the date for timezone offset.\n * @param date (Date) the date to adjust\n * @param timezone (string) the timezone to adjust for\n * @param undo (boolean) to add or subtract timezone offset\n * @return (Date) the corrected date\n */\n $dateParser.timezoneOffsetAdjust = function (date, timezone, undo) {\n if (!date) {\n return null;\n }\n // Right now, only 'UTC' is supported.\n if (timezone && timezone === 'UTC') {\n date = new Date(date.getTime());\n date.setMinutes(date.getMinutes() + (undo ? -1 : 1) * date.getTimezoneOffset());\n }\n return date;\n };\n\n // Private functions\n\n function regExpForFormat (format) {\n // `format` string can contain literal values.\n // These need to be escaped by surrounding with\n // single quotes (e.g. `\"h 'in the morning'\"`).\n // In order to output a single quote, escape it - i.e.,\n // two single quotes in a sequence (e.g. `\"h 'o''clock'\"`).\n\n var re = buildDateAbstractRegex(format);\n return buildDateParseRegex(re);\n }\n\n function buildDateAbstractRegex (format) {\n var escapedFormat = escapeReservedSymbols(format);\n var escapedLiteralFormat = escapedFormat.replace(/''/g, '\\\\\\'');\n var literalRegex = /('(?:\\\\'|.)*?')/;\n var formatParts = escapedLiteralFormat.split(literalRegex);\n var dateElements = Object.keys(regExpMap);\n var dateRegexParts = [];\n\n angular.forEach(formatParts, function (part) {\n if (isFormatStringLiteral(part)) {\n part = trimLiteralEscapeChars(part);\n } else {\n // Abstract replaces to avoid collisions\n for (var i = 0; i < dateElements.length; i++) {\n part = part.split(dateElements[i]).join('${' + i + '}');\n }\n }\n dateRegexParts.push(part);\n });\n\n return dateRegexParts.join('');\n }\n\n function escapeReservedSymbols (text) {\n return text.replace(/\\\\/g, '[\\\\\\\\]')\n .replace(/-/g, '[-]')\n .replace(/\\./g, '[.]')\n .replace(/\\*/g, '[*]')\n .replace(/\\+/g, '[+]')\n .replace(/\\?/g, '[?]')\n .replace(/\\$/g, '[$]')\n .replace(/\\^/g, '[^]')\n .replace(/\\//g, '[/]')\n .replace(/\\\\s/g, '[\\\\s]');\n }\n\n function isFormatStringLiteral (text) {\n return /^'.*'$/.test(text);\n }\n\n function trimLiteralEscapeChars (text) {\n return text.replace(/^'(.*)'$/, '$1');\n }\n\n function buildDateParseRegex (abstractRegex) {\n var dateElements = Object.keys(regExpMap);\n var re = abstractRegex;\n\n // Replace abstracted values\n for (var i = 0; i < dateElements.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[dateElements[i]] + ')');\n }\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n function setMapForFormat (format) {\n var re = buildDateAbstractRegex(format);\n return buildDateParseValuesMap(re);\n }\n\n function buildDateParseValuesMap (abstractRegex) {\n var dateElements = Object.keys(regExpMap);\n var valuesRegex = new RegExp('\\\\${(\\\\d+)}', 'g');\n var valuesMatch;\n var keyIndex;\n var valueKey;\n var valueFunction;\n var valuesFunctionMap = [];\n\n /* eslint-disable no-cond-assign */\n while ((valuesMatch = valuesRegex.exec(abstractRegex)) !== null) {\n keyIndex = valuesMatch[1];\n valueKey = dateElements[keyIndex];\n valueFunction = setFnMap[valueKey];\n\n valuesFunctionMap.push(valueFunction);\n }\n\n return valuesFunctionMap;\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dateFormatter', [])\n\n .service('$dateFormatter', function ($locale, dateFilter) {\n\n // The unused `lang` arguments are on purpose. The default implementation does not\n // use them and it always uses the locale loaded into the `$locale` service.\n // Custom implementations might use it, thus allowing different directives to\n // have different languages.\n\n this.getDefaultLocale = function () {\n return $locale.id;\n };\n\n // Format is either a data format name, e.g. \"shortTime\" or \"fullDate\", or a date format\n // Return either the corresponding date format or the given date format.\n this.getDatetimeFormat = function (format, lang) {\n return $locale.DATETIME_FORMATS[format] || format;\n };\n\n this.weekdaysShort = function (lang) {\n return $locale.DATETIME_FORMATS.SHORTDAY;\n };\n\n function splitTimeFormat (format) {\n return /(h+)([:\\.])?(m+)([:\\.])?(s*)[ ]?(a?)/i.exec(format).slice(1);\n }\n\n // h:mm a => h\n this.hoursFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[0];\n };\n\n // h:mm a => mm\n this.minutesFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[2];\n };\n\n // h:mm:ss a => ss\n this.secondsFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => :\n this.timeSeparator = function (timeFormat) {\n return splitTimeFormat(timeFormat)[1];\n };\n\n // h:mm:ss a => true, h:mm a => false\n this.showSeconds = function (timeFormat) {\n return !!splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => true, H.mm => false\n this.showAM = function (timeFormat) {\n return !!splitTimeFormat(timeFormat)[5];\n };\n\n this.formatDate = function (date, format, lang, timezone) {\n return dateFilter(date, format, timezone);\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.button', [])\n\n .provider('$button', function () {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n toggleEvent: 'click'\n };\n\n this.$get = function () {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsCheckboxGroup', function () {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink (element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"checkbox\"]');\n angular.forEach(children, function (child) {\n var childEl = angular.element(child);\n childEl.attr('bs-checkbox', '');\n childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value'));\n });\n }\n\n };\n\n })\n\n .directive('bsCheckbox', function ($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support label > input[type=\"checkbox\"]\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true;\n if (constantValueRegExp.test(attr.trueValue)) {\n trueValue = scope.$eval(attr.trueValue);\n }\n var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false;\n if (constantValueRegExp.test(attr.falseValue)) {\n falseValue = scope.$eval(attr.falseValue);\n }\n\n // Parse exotic values\n var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean';\n if (hasExoticValues) {\n controller.$parsers.push(function (viewValue) {\n // console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue);\n return viewValue ? trueValue : falseValue;\n });\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n return angular.equals(modelValue, trueValue);\n });\n // Fix rendering for exotic values\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n controller.$render();\n });\n }\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, trueValue);\n $$rAF(function () {\n if (isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function () {\n scope.$apply(function () {\n // console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n if (!isInput) {\n controller.$setViewValue(!activeElement.hasClass('active'));\n }\n if (!hasExoticValues) {\n controller.$render();\n }\n });\n });\n\n }\n\n };\n\n })\n\n .directive('bsRadioGroup', function () {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink (element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"radio\"]');\n angular.forEach(children, function (child) {\n angular.element(child).attr('bs-radio', '');\n angular.element(child).attr('ng-model', attr.ngModel);\n });\n }\n\n };\n\n })\n\n .directive('bsRadio', function ($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support `label > input[type=\"radio\"]` markup\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var value;\n attr.$observe('value', function (v) {\n if (typeof v !== 'boolean' && constantValueRegExp.test(v)) {\n value = scope.$eval(v);\n } else {\n value = v;\n }\n controller.$render();\n });\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, value);\n $$rAF(function () {\n if (isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function () {\n scope.$apply(function () {\n // console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n controller.$setViewValue(value);\n controller.$render();\n });\n });\n\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.collapse', [])\n\n .provider('$collapse', function () {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function ($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['disallowToggle', 'startCollapsed', 'allowMultiple'], function (key) {\n if (angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) {\n self.$options[key] = false;\n }\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function (element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function (element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function (element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function (element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function (value) {\n if (angular.isArray(value)) {\n self.$targets.$active = value;\n } else if (!self.$options.disallowToggle && isActive(value)) {\n deactivateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function () {\n if (self.$options.allowMultiple) {\n return self.$targets.$active;\n }\n return self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1;\n };\n\n function fixActiveItemIndexes (index) {\n // item with index was removed, so we\n // need to adjust other items index values\n var activeIndexes = self.$targets.$active;\n for (var i = 0; i < activeIndexes.length; i++) {\n if (index < activeIndexes[i]) {\n activeIndexes[i] = activeIndexes[i] - 1;\n }\n\n // the last item is active, so we need to\n // adjust its index\n if (activeIndexes[i] === self.$targets.length) {\n activeIndexes[i] = self.$targets.length - 1;\n }\n }\n }\n\n function isActive (value) {\n var activeItems = self.$targets.$active;\n return activeItems.indexOf(value) !== -1;\n }\n\n function deactivateItem (value) {\n var index = self.$targets.$active.indexOf(value);\n if (index !== -1) {\n self.$targets.$active.splice(index, 1);\n }\n }\n\n function activateItem (value) {\n if (!self.$options.allowMultiple) {\n // remove current selected item\n self.$targets.$active.splice(0, 1);\n }\n\n if (self.$targets.$active.indexOf(value) === -1) {\n self.$targets.$active.push(value);\n }\n }\n\n };\n\n this.$get = function () {\n var $collapse = {};\n $collapse.defaults = defaults;\n $collapse.controller = controller;\n return $collapse;\n };\n\n })\n\n .directive('bsCollapse', function ($window, $animate, $collapse) {\n\n return {\n require: ['?ngModel', 'bsCollapse'],\n controller: ['$scope', '$element', '$attrs', $collapse.controller],\n link: function postLink (scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n if (ngModelCtrl) {\n\n // Update the modelValue following\n bsCollapseCtrl.$viewChangeListeners.push(function () {\n ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes());\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n if (angular.isArray(modelValue)) {\n // model value is an array, so just replace\n // the active items directly\n bsCollapseCtrl.$setActive(modelValue);\n } else {\n var activeIndexes = bsCollapseCtrl.$activeIndexes();\n\n if (angular.isArray(activeIndexes)) {\n // we have an array of selected indexes\n if (activeIndexes.indexOf(modelValue * 1) === -1) {\n // item with modelValue index is not active\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n } else if (activeIndexes !== modelValue * 1) {\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n return modelValue;\n });\n\n }\n\n }\n };\n\n })\n\n .directive('bsCollapseToggle', function () {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base attr\n element.attr('data-toggle', 'collapse');\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerToggle(element);\n\n // remove toggle from collapse controller when toggle is destroyed\n scope.$on('$destroy', function () {\n bsCollapseCtrl.$unregisterToggle(element);\n });\n\n element.on('click', function () {\n if (!attrs.disabled) {\n var index = attrs.bsCollapseToggle && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n }\n });\n\n }\n };\n\n })\n\n .directive('bsCollapseTarget', function ($animate) {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n // scope: true,\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base class\n element.addClass('collapse');\n\n // Add animation class\n if (bsCollapseCtrl.$options.animation) {\n element.addClass(bsCollapseCtrl.$options.animation);\n }\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerTarget(element);\n\n // remove pane target from collapse controller when target is destroyed\n scope.$on('$destroy', function () {\n bsCollapseCtrl.$unregisterTarget(element);\n });\n\n function render () {\n var index = bsCollapseCtrl.$targets.indexOf(element);\n var active = bsCollapseCtrl.$activeIndexes();\n var action = 'removeClass';\n if (angular.isArray(active)) {\n if (active.indexOf(index) !== -1) {\n action = 'addClass';\n }\n } else if (index === active) {\n action = 'addClass';\n }\n\n $animate[action](element, bsCollapseCtrl.$options.activeClass);\n }\n\n bsCollapseCtrl.$viewChangeListeners.push(function () {\n render();\n });\n render();\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function ($modal) {\n\n function AsideFactory (config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function ($window, $sce, $aside) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsAside) {\n scope.$watch(attr.bsAside, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize aside\n var aside = $aside(options);\n\n // Trigger\n element.on(attr.trigger || 'click', aside.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (aside) aside.destroy();\n options = null;\n aside = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\n// @BUG: following snippet won't compile correctly\n\nangular.module('mgcrea.ngStrap.alert', ['mgcrea.ngStrap.modal'])\n\n .provider('$alert', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'alert',\n prefixEvent: 'alert',\n placement: null,\n templateUrl: 'alert/alert.tpl.html',\n container: false,\n element: null,\n backdrop: false,\n keyboard: true,\n show: true,\n // Specific options\n duration: false,\n type: false,\n dismissable: true\n };\n\n this.$get = function ($modal, $timeout) {\n\n function AlertFactory (config) {\n\n var $alert = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $alert = $modal(options);\n\n // Support scope as string options [/*title, content, */ type, dismissable]\n $alert.$scope.dismissable = !!options.dismissable;\n if (options.type) {\n $alert.$scope.type = options.type;\n }\n\n // Support auto-close duration\n var show = $alert.show;\n if (options.duration) {\n $alert.show = function () {\n show();\n $timeout(function () {\n $alert.hide();\n }, options.duration * 1000);\n };\n }\n\n return $alert;\n\n }\n\n return AlertFactory;\n\n };\n\n })\n\n .directive('bsAlert', function ($window, $sce, $alert) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['keyboard', 'html', 'container', 'dismissable'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')) {\n scope.title = '';\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content', 'type'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsAlert) {\n scope.$watch(attr.bsAlert, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize alert\n var alert = $alert(options);\n\n // Trigger\n element.on(attr.trigger || 'click', alert.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (alert) alert.destroy();\n options = null;\n alert = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.affix', ['mgcrea.ngStrap.helpers.dimensions', 'mgcrea.ngStrap.helpers.debounce'])\n\n .provider('$affix', function () {\n\n var defaults = this.defaults = {\n offsetTop: 'auto',\n inlineStyles: true\n };\n\n this.$get = function ($window, debounce, dimensions) {\n\n var bodyEl = angular.element($window.document.body);\n var windowEl = angular.element($window);\n\n function AffixFactory (element, config) {\n\n var $affix = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var targetEl = options.target;\n\n // Initial private vars\n var reset = 'affix affix-top affix-bottom';\n var setWidth = false;\n var initialAffixTop = 0;\n var initialOffsetTop = 0;\n var offsetTop = 0;\n var offsetBottom = 0;\n var affixed = null;\n var unpin = null;\n\n var parent = element.parent();\n // Options: custom parent\n if (options.offsetParent) {\n if (options.offsetParent.match(/^\\d+$/)) {\n for (var i = 0; i < (options.offsetParent * 1) - 1; i++) {\n parent = parent.parent();\n }\n } else {\n parent = angular.element(options.offsetParent);\n }\n }\n\n $affix.init = function () {\n\n this.$parseOffsets();\n initialOffsetTop = dimensions.offset(element[0]).top + initialAffixTop;\n setWidth = !element[0].style.width;\n\n // Bind events\n targetEl.on('scroll', this.checkPosition);\n targetEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', this.$debouncedOnResize);\n\n // Both of these checkPosition() calls are necessary for the case where\n // the user hits refresh after scrolling to the bottom of the page.\n this.checkPosition();\n this.checkPositionWithEventLoop();\n\n };\n\n $affix.destroy = function () {\n\n // Unbind events\n targetEl.off('scroll', this.checkPosition);\n targetEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', this.$debouncedOnResize);\n\n };\n\n $affix.checkPositionWithEventLoop = function () {\n\n // IE 9 throws an error if we use 'this' instead of '$affix'\n // in this setTimeout call\n setTimeout($affix.checkPosition, 1);\n\n };\n\n $affix.checkPosition = function () {\n // if (!this.$element.is(':visible')) return\n\n var scrollTop = getScrollTop();\n var position = dimensions.offset(element[0]);\n var elementHeight = dimensions.height(element[0]);\n\n // Get required affix class according to position\n var affix = getRequiredAffixClass(unpin, position, elementHeight);\n\n // Did affix status changed this last check?\n if (affixed === affix) return;\n affixed = affix;\n\n if (affix === 'top') {\n unpin = null;\n if (setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', '');\n }\n } else if (affix === 'bottom') {\n if (options.offsetUnpin) {\n unpin = -(options.offsetUnpin * 1);\n } else {\n // Calculate unpin threshold when affixed to bottom.\n // Hopefully the browser scrolls pixel by pixel.\n unpin = position.top - scrollTop;\n }\n if (setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', (options.offsetParent) ? '' : ((bodyEl[0].offsetHeight - offsetBottom - elementHeight - initialOffsetTop) + 'px'));\n }\n } else { // affix === 'middle'\n unpin = null;\n if (setWidth) {\n element.css('width', element[0].offsetWidth + 'px');\n }\n if (options.inlineStyles) {\n element.css('position', 'fixed');\n element.css('top', initialAffixTop + 'px');\n }\n }\n\n // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + affix : ''));\n\n };\n\n $affix.$onResize = function () {\n $affix.$parseOffsets();\n $affix.checkPosition();\n };\n $affix.$debouncedOnResize = debounce($affix.$onResize, 50);\n\n $affix.$parseOffsets = function () {\n var initialPosition = element.css('position');\n // Reset position to calculate correct offsetTop\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n }\n\n if (options.offsetTop) {\n if (options.offsetTop === 'auto') {\n options.offsetTop = '+0';\n }\n if (options.offsetTop.match(/^[-+]\\d+$/)) {\n initialAffixTop = - options.offsetTop * 1;\n if (options.offsetParent) {\n offsetTop = dimensions.offset(parent[0]).top + (options.offsetTop * 1);\n } else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\n }\n } else {\n offsetTop = options.offsetTop * 1;\n }\n }\n\n if (options.offsetBottom) {\n if (options.offsetParent && options.offsetBottom.match(/^[-+]\\d+$/)) {\n // add 1 pixel due to rounding problems...\n offsetBottom = getScrollHeight() - (dimensions.offset(parent[0]).top + dimensions.height(parent[0])) + (options.offsetBottom * 1) + 1;\n } else {\n offsetBottom = options.offsetBottom * 1;\n }\n }\n\n // Bring back the element's position after calculations\n if (options.inlineStyles) {\n element.css('position', initialPosition);\n }\n };\n\n // Private methods\n\n function getRequiredAffixClass (_unpin, position, elementHeight) {\n var scrollTop = getScrollTop();\n var scrollHeight = getScrollHeight();\n\n if (scrollTop <= offsetTop) {\n return 'top';\n } else if (_unpin !== null && (scrollTop + _unpin <= position.top)) {\n return 'middle';\n } else if (offsetBottom !== null && (position.top + elementHeight + initialAffixTop >= scrollHeight - offsetBottom)) {\n return 'bottom';\n }\n return 'middle';\n }\n\n function getScrollTop () {\n return targetEl[0] === $window ? $window.pageYOffset : targetEl[0].scrollTop;\n }\n\n function getScrollHeight () {\n return targetEl[0] === $window ? $window.document.body.scrollHeight : targetEl[0].scrollHeight;\n }\n\n $affix.init();\n return $affix;\n\n }\n\n return AffixFactory;\n\n };\n\n })\n\n .directive('bsAffix', function ($affix, $window) {\n\n return {\n restrict: 'EAC',\n require: '^?bsAffixTarget',\n link: function postLink (scope, element, attr, affixTarget) {\n\n var options = {scope: scope, target: affixTarget ? affixTarget.$element : angular.element($window)};\n angular.forEach(['offsetTop', 'offsetBottom', 'offsetParent', 'offsetUnpin', 'inlineStyles'], function (key) {\n if (angular.isDefined(attr[key])) {\n var option = attr[key];\n if (/true/i.test(option)) option = true;\n if (/false/i.test(option)) option = false;\n options[key] = option;\n }\n });\n\n var affix = $affix(element, options);\n scope.$on('$destroy', function () {\n if (affix) affix.destroy();\n options = null;\n affix = null;\n });\n\n }\n };\n\n })\n\n .directive('bsAffixTarget', function () {\n return {\n controller: function ($element) {\n this.$element = $element;\n }\n };\n });\n","\nangular.module('mgcrea.ngStrap', [\n 'mgcrea.ngStrap.modal',\n 'mgcrea.ngStrap.aside',\n 'mgcrea.ngStrap.alert',\n 'mgcrea.ngStrap.button',\n 'mgcrea.ngStrap.select',\n 'mgcrea.ngStrap.datepicker',\n 'mgcrea.ngStrap.timepicker',\n 'mgcrea.ngStrap.navbar',\n 'mgcrea.ngStrap.tooltip',\n 'mgcrea.ngStrap.popover',\n 'mgcrea.ngStrap.dropdown',\n 'mgcrea.ngStrap.typeahead',\n 'mgcrea.ngStrap.scrollspy',\n 'mgcrea.ngStrap.affix',\n 'mgcrea.ngStrap.tab',\n 'mgcrea.ngStrap.collapse'\n]);\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/InventoryTraker.Web/Scripts/angular-strap.tpl.js b/InventoryTraker.Web/Scripts/angular-strap.tpl.js index 5dd509b..72195ff 100644 --- a/InventoryTraker.Web/Scripts/angular-strap.tpl.js +++ b/InventoryTraker.Web/Scripts/angular-strap.tpl.js @@ -1,6 +1,6 @@ /** * angular-strap - * @version v2.3.1 - 2015-07-19 + * @version v2.3.9 - 2016-06-10 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT @@ -8,36 +8,36 @@ (function(window, document, undefined) { 'use strict'; angular.module('mgcrea.ngStrap.alert').run([ '$templateCache', function($templateCache) { - $templateCache.put('alert/alert.tpl.html', '
 
'); + $templateCache.put('alert/alert.tpl.html', '
 
'); } ]); angular.module('mgcrea.ngStrap.aside').run([ '$templateCache', function($templateCache) { $templateCache.put('aside/aside.tpl.html', ''); } ]); angular.module('mgcrea.ngStrap.datepicker').run([ '$templateCache', function($templateCache) { - $templateCache.put('datepicker/datepicker.tpl.html', ''); + $templateCache.put('datepicker/datepicker.tpl.html', ''); } ]); angular.module('mgcrea.ngStrap.dropdown').run([ '$templateCache', function($templateCache) { - $templateCache.put('dropdown/dropdown.tpl.html', ''); + $templateCache.put('dropdown/dropdown.tpl.html', ''); } ]); angular.module('mgcrea.ngStrap.modal').run([ '$templateCache', function($templateCache) { $templateCache.put('modal/modal.tpl.html', ''); } ]); angular.module('mgcrea.ngStrap.popover').run([ '$templateCache', function($templateCache) { - $templateCache.put('popover/popover.tpl.html', '

'); + $templateCache.put('popover/popover.tpl.html', '

'); } ]); angular.module('mgcrea.ngStrap.select').run([ '$templateCache', function($templateCache) { $templateCache.put('select/select.tpl.html', ''); } ]); angular.module('mgcrea.ngStrap.timepicker').run([ '$templateCache', function($templateCache) { - $templateCache.put('timepicker/timepicker.tpl.html', ''); - } ]); - angular.module('mgcrea.ngStrap.tab').run([ '$templateCache', function($templateCache) { - $templateCache.put('tab/tab.tpl.html', '
'); - } ]); - angular.module('mgcrea.ngStrap.typeahead').run([ '$templateCache', function($templateCache) { - $templateCache.put('typeahead/typeahead.tpl.html', ''); + $templateCache.put('timepicker/timepicker.tpl.html', ''); } ]); angular.module('mgcrea.ngStrap.tooltip').run([ '$templateCache', function($templateCache) { $templateCache.put('tooltip/tooltip.tpl.html', '
'); } ]); + angular.module('mgcrea.ngStrap.tab').run([ '$templateCache', function($templateCache) { + $templateCache.put('tab/tab.tpl.html', '
'); + } ]); + angular.module('mgcrea.ngStrap.typeahead').run([ '$templateCache', function($templateCache) { + $templateCache.put('typeahead/typeahead.tpl.html', ''); + } ]); })(window, document); \ No newline at end of file diff --git a/InventoryTraker.Web/Scripts/angular-strap.tpl.min.js b/InventoryTraker.Web/Scripts/angular-strap.tpl.min.js index 8b97e41..e02813e 100644 --- a/InventoryTraker.Web/Scripts/angular-strap.tpl.min.js +++ b/InventoryTraker.Web/Scripts/angular-strap.tpl.min.js @@ -1,8 +1,8 @@ /** * angular-strap - * @version v2.3.1 - 2015-07-19 + * @version v2.3.9 - 2016-06-10 * @link http://mgcrea.github.io/angular-strap * @author Olivier Louvignes (https://github.com/mgcrea) * @license MIT License, http://www.opensource.org/licenses/MIT */ -!function(t,e,n){'use strict';angular.module('mgcrea.ngStrap.alert').run(['$templateCache',function(t){t.put('alert/alert.tpl.html','
 
')}]),angular.module('mgcrea.ngStrap.aside').run(['$templateCache',function(t){t.put('aside/aside.tpl.html','')}]),angular.module('mgcrea.ngStrap.datepicker').run(['$templateCache',function(t){t.put('datepicker/datepicker.tpl.html','')}]),angular.module('mgcrea.ngStrap.dropdown').run(['$templateCache',function(t){t.put('dropdown/dropdown.tpl.html','')}]),angular.module('mgcrea.ngStrap.modal').run(['$templateCache',function(t){t.put('modal/modal.tpl.html','')}]),angular.module('mgcrea.ngStrap.popover').run(['$templateCache',function(t){t.put('popover/popover.tpl.html','

')}]),angular.module('mgcrea.ngStrap.select').run(['$templateCache',function(t){t.put('select/select.tpl.html','')}]),angular.module('mgcrea.ngStrap.timepicker').run(['$templateCache',function(t){t.put('timepicker/timepicker.tpl.html','')}]),angular.module('mgcrea.ngStrap.tab').run(['$templateCache',function(t){t.put('tab/tab.tpl.html','
')}]),angular.module('mgcrea.ngStrap.typeahead').run(['$templateCache',function(t){t.put('typeahead/typeahead.tpl.html','')}]),angular.module('mgcrea.ngStrap.tooltip').run(['$templateCache',function(t){t.put('tooltip/tooltip.tpl.html','
')}])}(window,document); \ No newline at end of file +!function(t,e,n){'use strict';angular.module('mgcrea.ngStrap.alert').run(['$templateCache',function(t){t.put('alert/alert.tpl.html','
 
')}]),angular.module('mgcrea.ngStrap.aside').run(['$templateCache',function(t){t.put('aside/aside.tpl.html','')}]),angular.module('mgcrea.ngStrap.datepicker').run(['$templateCache',function(t){t.put('datepicker/datepicker.tpl.html','')}]),angular.module('mgcrea.ngStrap.dropdown').run(['$templateCache',function(t){t.put('dropdown/dropdown.tpl.html','')}]),angular.module('mgcrea.ngStrap.modal').run(['$templateCache',function(t){t.put('modal/modal.tpl.html','')}]),angular.module('mgcrea.ngStrap.popover').run(['$templateCache',function(t){t.put('popover/popover.tpl.html','

')}]),angular.module('mgcrea.ngStrap.select').run(['$templateCache',function(t){t.put('select/select.tpl.html','')}]),angular.module('mgcrea.ngStrap.timepicker').run(['$templateCache',function(t){t.put('timepicker/timepicker.tpl.html','')}]),angular.module('mgcrea.ngStrap.tooltip').run(['$templateCache',function(t){t.put('tooltip/tooltip.tpl.html','
')}]),angular.module('mgcrea.ngStrap.tab').run(['$templateCache',function(t){t.put('tab/tab.tpl.html','
')}]),angular.module('mgcrea.ngStrap.typeahead').run(['$templateCache',function(t){t.put('typeahead/typeahead.tpl.html','')}])}(window,document); \ No newline at end of file diff --git a/InventoryTraker.Web/Scripts/ui-grid.js b/InventoryTraker.Web/Scripts/ui-grid.js index 88bed45..545ef70 100644 --- a/InventoryTraker.Web/Scripts/ui-grid.js +++ b/InventoryTraker.Web/Scripts/ui-grid.js @@ -1,5 +1,5 @@ /*! - * ui-grid - v3.1.1 - 2016-02-09 + * ui-grid - v3.2.9 - 2016-09-21 * Copyright (c) 2016 ; License: MIT */ @@ -10,6 +10,15 @@ })(); (function () { 'use strict'; + + /** + * @ngdoc object + * @name ui.grid.service:uiGridConstants + * @description Constants for use across many grid features + * + */ + + angular.module('ui.grid').constant('uiGridConstants', { LOG_DEBUG_MESSAGES: true, LOG_WARN_MESSAGES: true, @@ -25,6 +34,7 @@ APOS_REGEXP: /'/g, BRACKET_REGEXP: /^(.*)((?:\s*\[\s*\d+\s*\]\s*)|(?:\s*\[\s*"(?:[^"\\]|\\.)*"\s*\]\s*)|(?:\s*\[\s*'(?:[^'\\]|\\.)*'\s*\]\s*))(.*)$/, COL_CLASS_PREFIX: 'ui-grid-col', + ENTITY_BINDING: '$$this', events: { GRID_SCROLL: 'uiGridScroll', COLUMN_MENU_SHOWN: 'uiGridColMenuShown', @@ -72,8 +82,52 @@ F11: 122, F12: 123 }, + /** + * @ngdoc object + * @name ASC + * @propertyOf ui.grid.service:uiGridConstants + * @description Used in {@link ui.grid.class:GridOptions.columnDef#properties_sort columnDef.sort} and + * {@link ui.grid.class:GridOptions.columnDef#properties_sortDirectionCycle columnDef.sortDirectionCycle} + * to configure the sorting direction of the column + */ ASC: 'asc', + /** + * @ngdoc object + * @name DESC + * @propertyOf ui.grid.service:uiGridConstants + * @description Used in {@link ui.grid.class:GridOptions.columnDef#properties_sort columnDef.sort} and + * {@link ui.grid.class:GridOptions.columnDef#properties_sortDirectionCycle columnDef.sortDirectionCycle} + * to configure the sorting direction of the column + */ DESC: 'desc', + + + /** + * @ngdoc object + * @name filter + * @propertyOf ui.grid.service:uiGridConstants + * @description Used in {@link ui.grid.class:GridOptions.columnDef#properties_filter columnDef.filter} + * to configure filtering on the column + * + * `SELECT` and `INPUT` are used with the `type` property of the filter, the rest are used to specify + * one of the built-in conditions. + * + * Available `condition` options are: + * - `uiGridConstants.filter.STARTS_WITH` + * - `uiGridConstants.filter.ENDS_WITH` + * - `uiGridConstants.filter.CONTAINS` + * - `uiGridConstants.filter.GREATER_THAN` + * - `uiGridConstants.filter.GREATER_THAN_OR_EQUAL` + * - `uiGridConstants.filter.LESS_THAN` + * - `uiGridConstants.filter.LESS_THAN_OR_EQUAL` + * - `uiGridConstants.filter.NOT_EQUAL` + * - `uiGridConstants.filter.STARTS_WITH` + * + * + * Available `type` options are: + * - `uiGridConstants.filter.SELECT` - use a dropdown box for the cell header filter field + * - `uiGridConstants.filter.INPUT` - use a text box for the cell header filter field + */ filter: { STARTS_WITH: 2, ENDS_WITH: 4, @@ -88,6 +142,20 @@ INPUT: 'input' }, + /** + * @ngdoc object + * @name aggregationTypes + * @propertyOf ui.grid.service:uiGridConstants + * @description Used in {@link ui.grid.class:GridOptions.columnDef#properties_aggregationType columnDef.aggregationType} + * to specify the type of built-in aggregation the column should use. + * + * Available options are: + * - `uiGridConstants.aggregationTypes.sum` - add the values in this column to produce the aggregated value + * - `uiGridConstants.aggregationTypes.count` - count the number of rows to produce the aggregated value + * - `uiGridConstants.aggregationTypes.avg` - average the values in this column to produce the aggregated value + * - `uiGridConstants.aggregationTypes.min` - use the minimum value in this column as the aggregated value + * - `uiGridConstants.aggregationTypes.max` - use the maximum value in this column as the aggregated value + */ aggregationTypes: { sum: 2, count: 4, @@ -99,6 +167,20 @@ // TODO(c0bra): Create full list of these somehow. NOTE: do any allow a space before or after them? CURRENCY_SYMBOLS: ['ƒ', '$', '£', '$', '¤', '¥', '៛', '₩', '₱', '฿', '₫'], + /** + * @ngdoc object + * @name scrollDirection + * @propertyOf ui.grid.service:uiGridConstants + * @description Set on {@link ui.grid.class:Grid#properties_scrollDirection Grid.scrollDirection}, + * to indicate the direction the grid is currently scrolling in + * + * Available options are: + * - `uiGridConstants.scrollDirection.UP` - set when the grid is scrolling up + * - `uiGridConstants.scrollDirection.DOWN` - set when the grid is scrolling down + * - `uiGridConstants.scrollDirection.LEFT` - set when the grid is scrolling left + * - `uiGridConstants.scrollDirection.RIGHT` - set when the grid is scrolling right + * - `uiGridConstants.scrollDirection.NONE` - set when the grid is not scrolling, this is the default + */ scrollDirection: { UP: 'up', DOWN: 'down', @@ -108,6 +190,22 @@ }, + /** + * @ngdoc object + * @name dataChange + * @propertyOf ui.grid.service:uiGridConstants + * @description Used with {@link ui.grid.core.api:PublicApi#methods_notifyDataChange PublicApi.notifyDataChange}, + * {@link ui.grid.class:Grid#methods_callDataChangeCallbacks Grid.callDataChangeCallbacks}, + * and {@link ui.grid.class:Grid#methods_registerDataChangeCallback Grid.registerDataChangeCallback} + * to specify the type of the event(s). + * + * Available options are: + * - `uiGridConstants.dataChange.ALL` - listeners fired on any of these events, fires listeners on all events. + * - `uiGridConstants.dataChange.EDIT` - fired when the data in a cell is edited + * - `uiGridConstants.dataChange.ROW` - fired when a row is added or removed + * - `uiGridConstants.dataChange.COLUMN` - fired when the column definitions are modified + * - `uiGridConstants.dataChange.OPTIONS` - fired when the grid options are modified + */ dataChange: { ALL: 'all', EDIT: 'edit', @@ -115,6 +213,20 @@ COLUMN: 'column', OPTIONS: 'options' }, + + /** + * @ngdoc object + * @name scrollbars + * @propertyOf ui.grid.service:uiGridConstants + * @description Used with {@link ui.grid.class:GridOptions#properties_enableHorizontalScrollbar GridOptions.enableHorizontalScrollbar} + * and {@link ui.grid.class:GridOptions#properties_enableVerticalScrollbar GridOptions.enableVerticalScrollbar} + * to specify the scrollbar policy for that direction. + * + * Available options are: + * - `uiGridConstants.scrollbars.NEVER` - never show scrollbars in this direction + * - `uiGridConstants.scrollbars.ALWAYS` - always show scrollbars in this direction + */ + scrollbars: { NEVER: 0, ALWAYS: 1 @@ -123,6 +235,7 @@ }); })(); + angular.module('ui.grid').directive('uiGridCell', ['$compile', '$parse', 'gridUtil', 'uiGridConstants', function ($compile, $parse, gridUtil, uiGridConstants) { var uiGridCell = { priority: 0, @@ -1994,19 +2107,25 @@ function ($compile, $timeout, $window, $document, gridUtil, uiGridConstants, i18 templateUrl: 'ui-grid/uiGridMenu', replace: false, link: function ($scope, $elm, $attrs, uiGridCtrl) { - var gridMenuMaxHeight; $scope.dynamicStyles = ''; - if (uiGridCtrl) { - // magic number of 30 because the grid menu displays somewhat below - // the top of the grid. It is approximately 30px. - gridMenuMaxHeight = uiGridCtrl.grid.gridHeight - 30; + var setupHeightStyle = function(gridHeight) { + //menu appears under header row, so substract that height from it's total + // additional 20px for general padding + var gridMenuMaxHeight = gridHeight - uiGridCtrl.grid.headerHeight - 20; $scope.dynamicStyles = [ '.grid' + uiGridCtrl.grid.id + ' .ui-grid-menu-mid {', - 'max-height: ' + gridMenuMaxHeight + 'px;', + 'max-height: ' + gridMenuMaxHeight + 'px;', '}' ].join(' '); + }; + + if (uiGridCtrl) { + setupHeightStyle(uiGridCtrl.grid.gridHeight); + uiGridCtrl.grid.api.core.on.gridDimensionChanged($scope, function(oldGridHeight, oldGridWidth, newGridHeight, newGridWidth) { + setupHeightStyle(newGridHeight); + }); } $scope.i18n = { @@ -2216,7 +2335,6 @@ function ($compile, $timeout, $window, $document, gridUtil, uiGridConstants, i18 }; $scope.itemAction = function($event,title) { - gridUtil.logDebug('itemAction'); $event.stopPropagation(); if (typeof($scope.action) === 'function') { @@ -3680,8 +3798,9 @@ angular.module('ui.grid') * @ngdoc property * @name scrollDirection * @propertyOf ui.grid.class:Grid - * @description set one of the uiGridConstants.scrollDirection values (UP, DOWN, LEFT, RIGHT, NONE), which tells - * us which direction we are scrolling. Set to NONE via debounced method + * @description set one of the {@link ui.grid.service:uiGridConstants#properties_scrollDirection uiGridConstants.scrollDirection} + * values (UP, DOWN, LEFT, RIGHT, NONE), which tells us which direction we are scrolling. + * Set to NONE via debounced method */ self.scrollDirection = uiGridConstants.scrollDirection.NONE; @@ -3773,6 +3892,7 @@ angular.module('ui.grid') * If you only want to resize the grid, not regenerate all the rows * and columns, you should consider directly calling refreshCanvas instead. * + * @param {boolean} [rowsAltered] Optional flag for refreshing when the number of rows has changed */ self.api.registerMethod( 'core', 'refresh', this.refresh ); @@ -3831,6 +3951,8 @@ angular.module('ui.grid') * @methodOf ui.grid.core.api:PublicApi * @description adds a row header column to the grid * @param {object} column def + * @param {number} order Determines order of header column on grid. Lower order means header + * is positioned to the left of higher order headers * */ self.api.registerMethod( 'core', 'addRowHeaderColumn', this.addRowHeaderColumn ); @@ -3938,7 +4060,7 @@ angular.module('ui.grid') * that have sorting on them, sorted in priority order. * * @param {$scope} scope The scope of the controller. This is used to deregister this event when the scope is destroyed. - * @param {Function} callBack Will be called when the event is emited. The function passes back the grid and an array of + * @param {Function} callBack Will be called when the event is emited. The function passes back the grid and an array of * columns with sorts on them, in priority order. * * @example @@ -3979,8 +4101,8 @@ angular.module('ui.grid') * and you'd like cell classes to be re-evaluated, or changed config within * the columnDef and you'd like headerCellClasses to be re-evaluated. * @param {string} type one of the - * uiGridConstants.dataChange values (ALL, ROW, EDIT, COLUMN), which tells - * us which refreshes to fire. + * {@link ui.grid.service:uiGridConstants#properties_dataChange uiGridConstants.dataChange} + * values (ALL, ROW, EDIT, COLUMN), which tells us which refreshes to fire. * */ self.api.registerMethod( 'core', 'notifyDataChange', this.notifyDataChange ); @@ -4112,8 +4234,8 @@ angular.module('ui.grid') * * @param {function(grid)} callback function to be called * @param {array} types the types of data change you want to be informed of. Values from - * the uiGridConstants.dataChange values ( ALL, EDIT, ROW, COLUMN, OPTIONS ). Optional and defaults to - * ALL + * the {@link ui.grid.service:uiGridConstants#properties_dataChange uiGridConstants.dataChange} + * values ( ALL, EDIT, ROW, COLUMN, OPTIONS ). Optional and defaults to ALL * @returns {function} deregister function - a function that can be called to deregister this callback */ Grid.prototype.registerDataChangeCallback = function registerDataChangeCallback(callback, types, _this) { @@ -4140,8 +4262,9 @@ angular.module('ui.grid') * @description Calls the callbacks based on the type of data change that * has occurred. Always calls the ALL callbacks, calls the ROW, EDIT, COLUMN and OPTIONS callbacks if the * event type is matching, or if the type is ALL. - * @param {number} type the type of event that occurred - one of the - * uiGridConstants.dataChange values (ALL, ROW, EDIT, COLUMN, OPTIONS) + * @param {string} type the type of event that occurred - one of the + * {@link ui.grid.service:uiGridConstants#properties_dataChange uiGridConstants.dataChange} + * values (ALL, ROW, EDIT, COLUMN, OPTIONS) */ Grid.prototype.callDataChangeCallbacks = function callDataChangeCallbacks(type, options) { angular.forEach( this.dataChangeCallbacks, function( callback, uid ){ @@ -4313,8 +4436,14 @@ angular.module('ui.grid') * @description adds a row header column to the grid * @param {object} column def */ - Grid.prototype.addRowHeaderColumn = function addRowHeaderColumn(colDef) { + Grid.prototype.addRowHeaderColumn = function addRowHeaderColumn(colDef, order) { var self = this; + + //default order + if (order === undefined) { + order = 0; + } + var rowHeaderCol = new GridColumn(colDef, gridUtil.nextUid(), self); rowHeaderCol.isRowHeader = true; if (self.isRTL()) { @@ -4333,7 +4462,12 @@ angular.module('ui.grid') rowHeaderCol.enableFiltering = false; rowHeaderCol.enableSorting = false; rowHeaderCol.enableHiding = false; + rowHeaderCol.headerPriority = order; self.rowHeaderColumns.push(rowHeaderCol); + self.rowHeaderColumns = self.rowHeaderColumns.sort(function (a, b) { + return a.headerPriority - b.headerPriority; + }); + self.buildColumns() .then( function() { self.preCompileCellTemplates(); @@ -4395,9 +4529,11 @@ angular.module('ui.grid') } //add row header columns to the grid columns array _after_ columns without columnDefs have been removed - self.rowHeaderColumns.forEach(function (rowHeaderColumn) { - self.columns.unshift(rowHeaderColumn); - }); + //rowHeaderColumns is ordered by priority so insert in reverse + for (var j = self.rowHeaderColumns.length - 1; j >= 0; j--) { + self.columns.unshift(self.rowHeaderColumns[j]); + } + // look at each column def, and update column properties to match. If the column def @@ -4457,6 +4593,19 @@ angular.module('ui.grid') }); }; + Grid.prototype.preCompileCellTemplate = function(col) { + var self = this; + var html = col.cellTemplate.replace(uiGridConstants.MODEL_COL_FIELD, self.getQualifiedColField(col)); + html = html.replace(uiGridConstants.COL_FIELD, 'grid.getCellValue(row, col)'); + + var compiledElementFn = $compile(html); + col.compiledElementFn = compiledElementFn; + + if (col.compiledElementFnDefer) { + col.compiledElementFnDefer.resolve(col.compiledElementFn); + } + }; + /** * @ngdoc function * @name preCompileCellTemplates @@ -4465,25 +4614,12 @@ angular.module('ui.grid') */ Grid.prototype.preCompileCellTemplates = function() { var self = this; - - var preCompileTemplate = function( col ) { - var html = col.cellTemplate.replace(uiGridConstants.MODEL_COL_FIELD, self.getQualifiedColField(col)); - html = html.replace(uiGridConstants.COL_FIELD, 'grid.getCellValue(row, col)'); - - var compiledElementFn = $compile(html); - col.compiledElementFn = compiledElementFn; - - if (col.compiledElementFnDefer) { - col.compiledElementFnDefer.resolve(col.compiledElementFn); - } - }; - - this.columns.forEach(function (col) { + self.columns.forEach(function (col) { if ( col.cellTemplate ){ - preCompileTemplate( col ); + self.preCompileCellTemplate( col ); } else if ( col.cellTemplatePromise ){ col.cellTemplatePromise.then( function() { - preCompileTemplate( col ); + self.preCompileCellTemplate( col ); }); } }); @@ -4497,7 +4633,11 @@ angular.module('ui.grid') * @param {GridColumn} col col object */ Grid.prototype.getQualifiedColField = function (col) { - return 'row.entity.' + gridUtil.preEval(col.field); + var base = 'row.entity'; + if ( col.field === uiGridConstants.ENTITY_BINDING ) { + return base; + } + return gridUtil.preEval(base + '.' + col.field); }; /** @@ -4928,6 +5068,7 @@ angular.module('ui.grid') self.renderContainers[targetContainer].visibleRowCache.push(row); } } + self.api.core.raise.rowsVisibleChanged(this.api); self.api.core.raise.rowsRendered(this.api); }; @@ -5523,7 +5664,7 @@ angular.module('ui.grid') // Get the actual priority since there may be columns which have suppressRemoveSort set column.sort.priority = self.getNextColumnSortPriority(); } - else if (!column.sort.priority){ + else if (column.sort.priority === undefined){ column.sort.priority = self.getNextColumnSortPriority(); } @@ -5541,7 +5682,7 @@ angular.module('ui.grid') if (column.sortDirectionCycle[i]) { column.sort.direction = column.sortDirectionCycle[i]; } else { - column.sort = {}; + removeSortOfColumn(column, self); } } else { @@ -5553,6 +5694,18 @@ angular.module('ui.grid') return $q.when(column); }; + var removeSortOfColumn = function removeSortOfColumn(column, grid) { + //Decrease priority for every col where priority is higher than the removed sort's priority. + grid.columns.forEach(function (col) { + if (col.sort && col.sort.priority !== undefined && col.sort.priority > column.sort.priority) { + col.sort.priority -= 1; + } + }); + + //Remove sort + column.sort = {}; + }; + /** * communicate to outside world that we are done with initial rendering */ @@ -5922,18 +6075,13 @@ angular.module('ui.grid') // We were given a column to scroll to if (gridCol !== null) { - // This is the index of the row we want to scroll to, within the list of rows that can be visible + // This is the index of the column we want to scroll to, within the list of columns that can be visible var seekColumnIndex = visColCache.indexOf(gridCol); - // Total vertical scroll length of the grid + // Total horizontal scroll length of the grid var horizScrollLength = (self.renderContainers.body.getCanvasWidth() - self.renderContainers.body.getViewportWidth()); - // Add the height of the native horizontal scrollbar to the scroll length, if it's there. Otherwise it will mask over the final row - // if (self.verticalScrollbarWidth && self.verticalScrollbarWidth > 0) { - // horizScrollLength = horizScrollLength + self.verticalScrollbarWidth; - // } - - // This is the minimum amount of pixels we need to scroll vertical in order to see this column + // This is the minimum amount of pixels we need to scroll horizontal in order to see this column var columnLeftEdge = 0; for (var i = 0; i < seekColumnIndex; i++) { var col = visColCache[i]; @@ -5948,9 +6096,9 @@ angular.module('ui.grid') var horizScrollPixels, horizPercentage; - // If the scroll position we need to see the row is LESS than the top boundary, i.e. obscured above the top of the self... + // If the scroll position we need to see the column is LESS than the left boundary, i.e. obscured before the left of the self... if (columnLeftEdge < leftBound) { - // Get the different between the top boundary and the required scroll position and subtract it from the current scroll position\ + // Get the different between the left boundary and the required scroll position and subtract it from the current scroll position\ // to get the full position we need horizScrollPixels = self.renderContainers.body.prevScrollLeft - (leftBound - columnLeftEdge); @@ -5959,9 +6107,9 @@ angular.module('ui.grid') horizPercentage = (horizPercentage > 1) ? 1 : horizPercentage; scrollEvent.x = { percentage: horizPercentage }; } - // Otherwise if the scroll position we need to see the row is MORE than the bottom boundary, i.e. obscured below the bottom of the self... + // Otherwise if the scroll position we need to see the column is MORE than the right boundary, i.e. obscured after the right of the self... else if (columnRightEdge > rightBound) { - // Get the different between the bottom boundary and the required scroll position and add it to the current scroll position + // Get the different between the right boundary and the required scroll position and add it to the current scroll position // to get the full position we need horizScrollPixels = columnRightEdge - rightBound + self.renderContainers.body.prevScrollLeft; @@ -6119,7 +6267,7 @@ angular.module('ui.grid') var GridApi = function GridApi(grid) { this.grid = grid; this.listeners = []; - + /** * @ngdoc function * @name renderingComplete @@ -6128,14 +6276,14 @@ angular.module('ui.grid') * time as `onRegisterApi`, but provides a way to obtain * that same event within features without stopping end * users from getting at the onRegisterApi method. - * + * * Included in gridApi so that it's always there - otherwise * there is still a timing problem with when a feature can - * call this. - * - * @param {GridApi} gridApi the grid api, as normally + * call this. + * + * @param {GridApi} gridApi the grid api, as normally * returned in the onRegisterApi method - * + * * @example *
            *      gridApi.core.on.renderingComplete( grid );
@@ -6149,9 +6297,9 @@ angular.module('ui.grid')
            * @eventOf  ui.grid.core.api:PublicApi
            * @description  is raised after the filter is changed.  The nature
            * of the watch expression doesn't allow notification of what changed,
-           * so the receiver of this event will need to re-extract the filter 
+           * so the receiver of this event will need to re-extract the filter
            * conditions from the columns.
-           * 
+           *
            */
           this.registerEvent( 'core', 'filterChanged' );
 
@@ -6160,26 +6308,26 @@ angular.module('ui.grid')
            * @name setRowInvisible
            * @methodOf  ui.grid.core.api:PublicApi
            * @description Sets an override on the row to make it always invisible,
-           * which will override any filtering or other visibility calculations.  
+           * which will override any filtering or other visibility calculations.
            * If the row is currently visible then sets it to invisible and calls
            * both grid refresh and emits the rowsVisibleChanged event
            * @param {object} rowEntity gridOptions.data[] array instance
            */
           this.registerMethod( 'core', 'setRowInvisible', GridRow.prototype.setRowInvisible );
-      
+
           /**
            * @ngdoc function
            * @name clearRowInvisible
            * @methodOf  ui.grid.core.api:PublicApi
-           * @description Clears any override on visibility for the row so that it returns to 
-           * using normal filtering and other visibility calculations.  
+           * @description Clears any override on visibility for the row so that it returns to
+           * using normal filtering and other visibility calculations.
            * If the row is currently invisible then sets it to visible and calls
            * both grid refresh and emits the rowsVisibleChanged event
            * TODO: if a filter is active then we can't just set it to visible?
            * @param {object} rowEntity gridOptions.data[] array instance
            */
           this.registerMethod( 'core', 'clearRowInvisible', GridRow.prototype.clearRowInvisible );
-      
+
           /**
            * @ngdoc function
            * @name getVisibleRows
@@ -6189,7 +6337,7 @@ angular.module('ui.grid')
            * @returns {array} an array of gridRow
            */
           this.registerMethod( 'core', 'getVisibleRows', this.grid.getVisibleRows );
-          
+
           /**
            * @ngdoc event
            * @name rowsVisibleChanged
@@ -6239,6 +6387,16 @@ angular.module('ui.grid')
            * arguments: oldHeight, newHeight
            */
           this.registerEvent( 'core', 'canvasHeightChanged');
+
+          /**
+           * @ngdoc event
+           * @name gridDimensionChanged
+           * @eventOf  ui.grid.core.api:PublicApi
+           * @description  is raised when the grid dimensions have changed (when autoResize is on)
+           * 
+ * arguments: oldGridHeight, oldGridWidth, newGridHeight, newGridWidth + */ + this.registerEvent( 'core', 'gridDimensionChanged'); }; /** @@ -6462,7 +6620,7 @@ angular.module('ui.grid') }); }; - + return GridApi; }]); @@ -6546,6 +6704,8 @@ angular.module('ui.grid') * @name filter * @propertyOf ui.grid.class:GridColumn * @description Filter on this column. + * + * Available built-in conditions and types are listed under {@link jui.grid.service:uiGridConstants#properties_filter uiGridOptions.filter} * @example *
{ term: 'text', condition: uiGridConstants.filter.STARTS_WITH, placeholder: 'type to filter...', ariaLabel: 'Filter for text', flags: { caseSensitive: false }, type: uiGridConstants.filter.SELECT, [ { value: 1, label: 'male' }, { value: 2, label: 'female' } ] }
* @@ -6581,7 +6741,9 @@ angular.module('ui.grid') * @name aggregationType * @propertyOf ui.grid.class:GridOptions.columnDef * @description The aggregation that you'd like to show in the columnFooter for this - * column. Valid values are in uiGridConstants, and currently include `uiGridConstants.aggregationTypes.count`, + * column. Valid values are in + * {@link ui.grid.service:uiGridConstants#properties_aggregationTypes uiGridConstants.aggregationTypes}, + * and currently include `uiGridConstants.aggregationTypes.count`, * `uiGridConstants.aggregationTypes.sum`, `uiGridConstants.aggregationTypes.avg`, `uiGridConstants.aggregationTypes.min`, * `uiGridConstants.aggregationTypes.max`. * @@ -6749,7 +6911,8 @@ angular.module('ui.grid') * @propertyOf ui.grid.class:GridOptions.columnDef * @description An object of sort information, attributes are: * - * - direction: values are uiGridConstants.ASC or uiGridConstants.DESC + * - direction: values are {@link ui.grid.service:uiGridConstants#properties_ASC uiGridConstants.ASC} + * or {@link ui.grid.service:uiGridConstants#properties_DESC uiGridConstants.DESC} * - ignoreSort: if set to true this sort is ignored (used by tree to manipulate the sort functionality) * - priority: says what order to sort the columns in (lower priority gets sorted first). * @example @@ -7118,8 +7281,8 @@ angular.module('ui.grid') * @ngdoc property * @name sortDirectionCycle * @propertyOf ui.grid.class:GridOptions.columnDef - * @description (optional) An array of sort directions, specifying the order that they - * should cycle through as the user repeatedly clicks on the column heading. + * @description (optional) An array of {@link ui.grid.service:uiGridConstants#properties_ASC sort directions}, + * specifying the order that they should cycle through as the user repeatedly clicks on the column heading. * The default is `[null, uiGridConstants.ASC, uiGridConstants.DESC]`. Null * refers to the unsorted state. This does not affect the initial sort * direction; use the {@link ui.grid.class:GridOptions.columnDef#sort sort} @@ -7197,7 +7360,8 @@ angular.module('ui.grid') * A filter consists of a condition, a term, and a placeholder: * * - condition defines how rows are chosen as matching the filter term. This can be set to - * one of the constants in uiGridConstants.filter, or you can supply a custom filter function + * one of the constants in {@link ui.grid.service:uiGridConstants#properties_filter uiGridConstants.filter}, + * or you can supply a custom filter function * that gets passed the following arguments: [searchTerm, cellValue, row, column]. * - term: If set, the filter field will be pre-populated * with this value. @@ -7205,9 +7369,12 @@ angular.module('ui.grid') * - ariaLabel: String that will be set to the `.ariaLabel` attribute. This is what is read as a label to screen reader users. * - noTerm: set this to true if you have defined a custom function in condition, and * your custom function doesn't require a term (so it can run even when the term is null) + * - rawTerm: set this to true if you have defined a custom function in condition, and + * your custom function requires access to the raw unmodified search term that was entered * - flags: only flag currently available is `caseSensitive`, set to false if you don't want * case sensitive matching - * - type: defaults to uiGridConstants.filter.INPUT, which gives a text box. If set to uiGridConstants.filter.SELECT + * - type: defaults to {@link ui.grid.service:uiGridConstants#properties_filter uiGridConstants.filter.INPUT}, + * which gives a text box. If set to {@link ui.grid.service:uiGridConstants#properties_filter uiGridConstants.filter.SELECT} * then a select box will be shown with options selectOptions * - selectOptions: options in the format `[ { value: 1, label: 'male' }]`. No i18n filter is provided, you need * to perform the i18n on the values before you provide them @@ -7813,7 +7980,8 @@ angular.module('ui.grid') * @ngdoc boolean * @name enableVerticalScrollbar * @propertyOf ui.grid.class:GridOptions - * @description uiGridConstants.scrollbars.ALWAYS by default. This settings controls the vertical scrollbar for the grid. + * @description {@link ui.grid.service:uiGridConstants#properties_scrollbars uiGridConstants.scrollbars.ALWAYS} by default. + * This settings controls the vertical scrollbar for the grid. * Supported values: uiGridConstants.scrollbars.ALWAYS, uiGridConstants.scrollbars.NEVER */ baseOptions.enableVerticalScrollbar = typeof(baseOptions.enableVerticalScrollbar) !== "undefined" ? baseOptions.enableVerticalScrollbar : uiGridConstants.scrollbars.ALWAYS; @@ -7822,7 +7990,8 @@ angular.module('ui.grid') * @ngdoc boolean * @name enableHorizontalScrollbar * @propertyOf ui.grid.class:GridOptions - * @description uiGridConstants.scrollbars.ALWAYS by default. This settings controls the horizontal scrollbar for the grid. + * @description {@link ui.grid.service:uiGridConstants#properties_scrollbars uiGridConstants.scrollbars.ALWAYS} by default. + * This settings controls the horizontal scrollbar for the grid. * Supported values: uiGridConstants.scrollbars.ALWAYS, uiGridConstants.scrollbars.NEVER */ baseOptions.enableHorizontalScrollbar = typeof(baseOptions.enableHorizontalScrollbar) !== "undefined" ? baseOptions.enableHorizontalScrollbar : uiGridConstants.scrollbars.ALWAYS; @@ -8237,6 +8406,10 @@ angular.module('ui.grid') return this.getCanvasHeight() - this.getViewportHeight() + this.grid.scrollbarHeight; }; + GridRenderContainer.prototype.getHorizontalScrollLength = function getHorizontalScrollLength() { + return this.getCanvasWidth() - this.getViewportWidth() + this.grid.scrollbarWidth; + }; + GridRenderContainer.prototype.getCanvasWidth = function getCanvasWidth() { var self = this; @@ -8309,7 +8482,7 @@ angular.module('ui.grid') if (xDiff > 0) { this.grid.scrollDirection = uiGridConstants.scrollDirection.RIGHT; } if (xDiff < 0) { this.grid.scrollDirection = uiGridConstants.scrollDirection.LEFT; } - var horizScrollLength = (this.canvasWidth - this.getViewportWidth()); + var horizScrollLength = this.getHorizontalScrollLength(); if (horizScrollLength !== 0) { horizScrollPercentage = newScrollLeft / horizScrollLength; } @@ -8421,8 +8594,7 @@ angular.module('ui.grid') // Calculate the scroll percentage according to the scrollLeft location, if no percentage was provided if ((typeof(scrollPercentage) === 'undefined' || scrollPercentage === null) && scrollLeft) { - var horizScrollLength = (self.getCanvasWidth() - self.getViewportWidth()); - scrollPercentage = scrollLeft / horizScrollLength; + scrollPercentage = scrollLeft / self.getHorizontalScrollLength(); } var colIndex = Math.ceil(Math.min(maxColumnIndex, maxColumnIndex * scrollPercentage)); @@ -8726,7 +8898,7 @@ angular.module('ui.grid') (function(){ angular.module('ui.grid') -.factory('GridRow', ['gridUtil', function(gridUtil) { +.factory('GridRow', ['gridUtil', 'uiGridConstants', function(gridUtil, uiGridConstants) { /** * @ngdoc function @@ -8819,7 +8991,11 @@ angular.module('ui.grid') * @returns {string} resulting name that can be evaluated against a row */ GridRow.prototype.getEntityQualifiedColField = function(col) { - return gridUtil.preEval('entity.' + col.field); + var base = 'entity'; + if ( col.field === uiGridConstants.ENTITY_BINDING ) { + return base; + } + return gridUtil.preEval(base + '.' + col.field); }; @@ -8990,41 +9166,6 @@ angular.module('ui.grid') var context = this.row; return getter(context); }; - /** - * @ngdoc function - * @name getIntersectionValueFiltered - * @methodOf ui.grid.class:GridRowColumn - * @description Gets the intersection of where the row and column meet. - * @returns {String|Number|Object} The value from the grid data that this GridRowColumn points too. - * If the column has a cellFilter this will also apply the filter to it and return the value that the filter displays. - */ - GridRowColumn.prototype.getIntersectionValueFiltered = function(){ - var value = this.getIntersectionValueRaw(); - if (this.col.cellFilter && this.col.cellFilter !== ''){ - var getFilterIfExists = function(filterName){ - try { - return $filter(filterName); - } catch (e){ - return null; - } - }; - var filter = getFilterIfExists(this.col.cellFilter); - if (filter) { // Check if this is filter name or a filter string - value = filter(value); - } else { // We have the template version of a filter so we need to parse it apart - // Get the filter params out using a regex - // Test out this regex here https://regex101.com/r/rC5eR5/2 - var re = /([^:]*):([^:]*):?([\s\S]+)?/; - var matches; - if ((matches = re.exec(this.col.cellFilter)) !== null) { - // View your result using the matches-variable. - // eg matches[0] etc. - value = $filter(matches[1])(value, matches[2], matches[3]); - } - } - } - return value; - }; return GridRowColumn; } ]); @@ -9254,25 +9395,14 @@ angular.module('ui.grid') return rows; }); - grid.registerColumnsProcessor(function allColumnsVisible(columns) { + grid.registerColumnsProcessor(function applyColumnVisibility(columns) { columns.forEach(function (column) { - column.visible = true; + column.visible = angular.isDefined(column.colDef.visible) ? column.colDef.visible : true; }); return columns; }, 50); - grid.registerColumnsProcessor(function(renderableColumns) { - renderableColumns.forEach(function (column) { - if (column.colDef.visible === false) { - column.visible = false; - } - }); - - return renderableColumns; - }, 50); - - grid.registerRowsProcessor(grid.searchRows, 100); // Register the default row processor, it sorts rows by selected columns @@ -9552,10 +9682,14 @@ module.service('rowSearcher', ['gridUtil', 'uiGridConstants', function (gridUtil } if ( !gridUtil.isNullOrUndefined(filter.term) ){ - // it is possible to have noTerm. We don't need to copy that across, it was just a flag to avoid - // getting the filter ignored if the filter was a function that didn't use a term - newFilter.term = rowSearcher.stripTerm(filter); + // it is possible to have noTerm. + if ( filter.rawTerm ){ + newFilter.term = filter.term; + } else { + newFilter.term = rowSearcher.stripTerm(filter); + } } + newFilter.noTerm = filter.noTerm; if ( filter.condition ){ newFilter.condition = filter.condition; @@ -9715,9 +9849,11 @@ module.service('rowSearcher', ['gridUtil', 'uiGridConstants', function (gridUtil for (var i = 0; i < filtersLength; i++) { var filter = filters[i]; - var ret = rowSearcher.runColumnFilter(grid, row, column, filter); - if (!ret) { - return false; + if ( !gridUtil.isNullOrUndefined(filter.term) && filter.term !== '' || filter.noTerm ){ + var ret = rowSearcher.runColumnFilter(grid, row, column, filter); + if (!ret) { + return false; + } } } @@ -9822,8 +9958,8 @@ var module = angular.module('ui.grid'); /** * @ngdoc object - * @name ui.grid.class:RowSorter - * @description RowSorter provides the default sorting mechanisms, + * @name ui.grid.class:rowSorter + * @description rowSorter provides the default sorting mechanisms, * including guessing column types and applying appropriate sort * algorithms * @@ -9850,7 +9986,7 @@ module.service('rowSorter', ['$parse', 'uiGridConstants', function ($parse, uiGr /** * @ngdoc method - * @methodOf ui.grid.class:RowSorter + * @methodOf ui.grid.class:rowSorter * @name guessSortFn * @description Assigns a sort function to use based on the itemType in the column * @param {string} itemType one of 'number', 'boolean', 'string', 'date', 'object'. And @@ -9879,7 +10015,7 @@ module.service('rowSorter', ['$parse', 'uiGridConstants', function ($parse, uiGr /** * @ngdoc method - * @methodOf ui.grid.class:RowSorter + * @methodOf ui.grid.class:rowSorter * @name handleNulls * @description Sorts nulls and undefined to the bottom (top when * descending). Called by each of the internal sorters before @@ -9910,7 +10046,7 @@ module.service('rowSorter', ['$parse', 'uiGridConstants', function ($parse, uiGr /** * @ngdoc method - * @methodOf ui.grid.class:RowSorter + * @methodOf ui.grid.class:rowSorter * @name basicSort * @description Sorts any values that provide the < method, including strings * or numbers. Handles nulls and undefined through calling handleNulls @@ -9936,7 +10072,7 @@ module.service('rowSorter', ['$parse', 'uiGridConstants', function ($parse, uiGr /** * @ngdoc method - * @methodOf ui.grid.class:RowSorter + * @methodOf ui.grid.class:rowSorter * @name sortNumber * @description Sorts numerical values. Handles nulls and undefined through calling handleNulls * @param {object} a sort value a @@ -9955,7 +10091,7 @@ module.service('rowSorter', ['$parse', 'uiGridConstants', function ($parse, uiGr /** * @ngdoc method - * @methodOf ui.grid.class:RowSorter + * @methodOf ui.grid.class:rowSorter * @name sortNumberStr * @description Sorts numerical values that are stored in a string (i.e. parses them to numbers first). * Handles nulls and undefined through calling handleNulls @@ -10009,7 +10145,7 @@ module.service('rowSorter', ['$parse', 'uiGridConstants', function ($parse, uiGr /** * @ngdoc method - * @methodOf ui.grid.class:RowSorter + * @methodOf ui.grid.class:rowSorter * @name sortAlpha * @description Sorts string values. Handles nulls and undefined through calling handleNulls * @param {object} a sort value a @@ -10031,7 +10167,7 @@ module.service('rowSorter', ['$parse', 'uiGridConstants', function ($parse, uiGr /** * @ngdoc method - * @methodOf ui.grid.class:RowSorter + * @methodOf ui.grid.class:rowSorter * @name sortDate * @description Sorts date values. Handles nulls and undefined through calling handleNulls. * Handles date strings by converting to Date object if not already an instance of Date @@ -10060,7 +10196,7 @@ module.service('rowSorter', ['$parse', 'uiGridConstants', function ($parse, uiGr /** * @ngdoc method - * @methodOf ui.grid.class:RowSorter + * @methodOf ui.grid.class:rowSorter * @name sortBool * @description Sorts boolean values, true is considered larger than false. * Handles nulls and undefined through calling handleNulls @@ -10089,7 +10225,7 @@ module.service('rowSorter', ['$parse', 'uiGridConstants', function ($parse, uiGr /** * @ngdoc method - * @methodOf ui.grid.class:RowSorter + * @methodOf ui.grid.class:rowSorter * @name getSortFn * @description Get the sort function for the column. Looks first in * rowSorter.colSortFnCache using the column name, failing that it @@ -10149,7 +10285,7 @@ module.service('rowSorter', ['$parse', 'uiGridConstants', function ($parse, uiGr /** * @ngdoc method - * @methodOf ui.grid.class:RowSorter + * @methodOf ui.grid.class:rowSorter * @name prioritySort * @description Used where multiple columns are present in the sort criteria, * we determine which column should take precedence in the sort by sorting @@ -10202,7 +10338,7 @@ module.service('rowSorter', ['$parse', 'uiGridConstants', function ($parse, uiGr */ /** * @ngdoc method - * @methodOf ui.grid.class:RowSorter + * @methodOf ui.grid.class:rowSorter * @name sort * @description sorts the grid * @param {Object} grid the grid itself @@ -10663,7 +10799,7 @@ module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateC } // See if the template is itself a promise - if (template.hasOwnProperty('then')) { + if (angular.isFunction(template.then)) { return template.then(s.postProcessTemplate); } @@ -11537,7 +11673,7 @@ module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateC function runFunc(endDate){ lastCall = +new Date(); func.apply(context, args); - $interval(function(){ queued = null; }, 0, 1, false); + $interval(function(){queued = null; }, 0, 1, false); } return function(){ @@ -11687,8 +11823,6 @@ module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateC deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta); deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta); - event.deltaMode = 0; - // Normalise offsetX and offsetY properties // if ($elm[0].getBoundingClientRect ) { // var boundingRect = $(elm)[0].getBoundingClientRect(); @@ -11880,14 +12014,14 @@ module.filter('px', function() { max: 'max: ' }, gridMenu: { - columns: 'Columns:', - importerTitle: 'Import file', - exporterAllAsCsv: 'Export all data as csv', - exporterVisibleAsCsv: 'Export visible data as csv', - exporterSelectedAsCsv: 'Export selected data as csv', - exporterAllAsPdf: 'Export all data as pdf', - exporterVisibleAsPdf: 'Export visible data as pdf', - exporterSelectedAsPdf: 'Export selected data as pdf', + columns: 'Kolonner:', + importerTitle: 'Importer fil', + exporterAllAsCsv: 'Eksporter alle data som csv', + exporterVisibleAsCsv: 'Eksporter synlige data som csv', + exporterSelectedAsCsv: 'Eksporter markerede data som csv', + exporterAllAsPdf: 'Eksporter alle data som pdf', + exporterVisibleAsPdf: 'Eksporter synlige data som pdf', + exporterSelectedAsPdf: 'Eksporter markerede data som pdf', clearAllFilters: 'Clear all filters' }, importer: { @@ -11896,6 +12030,19 @@ module.filter('px', function() { invalidCsv: 'File was unable to be processed, is it valid CSV?', invalidJson: 'File was unable to be processed, is it valid Json?', jsonNotArray: 'Imported json file must contain an array, aborting.' + }, + pagination: { + aria: { + pageToFirst: 'Gå til første', + pageBack: 'Gå tilbage', + pageSelected: 'Valgte side', + pageForward: 'Gå frem', + pageToLast: 'Gå til sidste' + }, + sizes: 'genstande per side', + totalItems: 'genstande', + through: 'gennem', + of: 'af' } }); return $delegate; @@ -11971,7 +12118,7 @@ module.filter('px', function() { exporterSelectedAsCsv: 'markierte Daten als CSV exportieren', exporterAllAsPdf: 'Alle Daten als PDF exportieren', exporterVisibleAsPdf: 'sichtbare Daten als PDF exportieren', - exporterSelectedAsPdf: 'markierte Daten als CSV exportieren', + exporterSelectedAsPdf: 'markierte Daten als PDF exportieren', clearAllFilters: 'Alle Filter zurücksetzen' }, importer: { @@ -12366,6 +12513,15 @@ module.filter('px', function() { angular.module('ui.grid').config(['$provide', function($provide) { $provide.decorator('i18nService', ['$delegate', function($delegate) { $delegate.add('fr', { + headerCell: { + aria: { + defaultFilterLabel: 'Filtre de la colonne', + removeFilter: 'Supprimer le filtre', + columnMenuButtonLabel: 'Menu de la colonne' + }, + priority: 'Priorité:', + filterLabel: "Filtre de la colonne: " + }, aggregate: { label: 'éléments' }, @@ -12389,6 +12545,7 @@ module.filter('px', function() { sort: { ascending: 'Trier par ordre croissant', descending: 'Trier par ordre décroissant', + none: 'Aucun tri', remove: 'Enlever le tri' }, column: { @@ -12406,7 +12563,13 @@ module.filter('px', function() { pinRight: 'Épingler à droite', unpin: 'Détacher' }, + columnMenu: { + close: 'Fermer' + }, gridMenu: { + aria: { + buttonLabel: 'Menu du tableau' + }, columns: 'Colonnes:', importerTitle: 'Importer un fichier', exporterAllAsCsv: 'Exporter toutes les données en CSV', @@ -12425,19 +12588,33 @@ module.filter('px', function() { jsonNotArray: 'Le fichier JSON importé doit contenir un tableau, abandon.' }, pagination: { + aria: { + pageToFirst: 'Aller à la première page', + pageBack: 'Page précédente', + pageSelected: 'Page sélectionnée', + pageForward: 'Page suivante', + pageToLast: 'Aller à la dernière page' + }, sizes: 'éléments par page', totalItems: 'éléments', + through: 'à', of: 'sur' }, grouping: { group: 'Grouper', ungroup: 'Dégrouper', - aggregate_count: 'Agg: Compte', + aggregate_count: 'Agg: Compter', aggregate_sum: 'Agg: Somme', aggregate_max: 'Agg: Max', aggregate_min: 'Agg: Min', aggregate_avg: 'Agg: Moy', aggregate_remove: 'Agg: Retirer' + }, + validate: { + error: 'Erreur:', + minLength: 'La valeur doit être supérieure ou égale à THRESHOLD caractères.', + maxLength: 'La valeur doit être inférieure ou égale à THRESHOLD caractères.', + required: 'Une valeur est nécéssaire.' } }); return $delegate; @@ -12638,6 +12815,19 @@ module.filter('px', function() { invalidJson: 'Impossibile elaborare il file, sicuro che sia un JSON valido?', jsonNotArray: 'Errore! Il file JSON da importare deve contenere un array.' }, + pagination: { + aria: { + pageToFirst: 'Prima', + pageBack: 'Indietro', + pageSelected: 'Pagina selezionata', + pageForward: 'Avanti', + pageToLast: 'Ultima' + }, + sizes: 'elementi per pagina', + totalItems: 'elementi', + through: 'a', + of: 'di' + }, grouping: { group: 'Raggruppa', ungroup: 'Separa', @@ -12896,6 +13086,113 @@ module.filter('px', function() { }]); })(); +(function () { + angular.module('ui.grid').config(['$provide', function($provide) { + $provide.decorator('i18nService', ['$delegate', function($delegate) { + $delegate.add('no', { + headerCell: { + aria: { + defaultFilterLabel: 'Filter for column', + removeFilter: 'Remove Filter', + columnMenuButtonLabel: 'Column Menu' + }, + priority: 'Priority:', + filterLabel: "Filter for column: " + }, + aggregate: { + label: 'items' + }, + groupPanel: { + description: 'Drag a column header here and drop it to group by that column.' + }, + search: { + placeholder: 'Search...', + showingItems: 'Showing Items:', + selectedItems: 'Selected Items:', + totalItems: 'Total Items:', + size: 'Page Size:', + first: 'First Page', + next: 'Next Page', + previous: 'Previous Page', + last: 'Last Page' + }, + menu: { + text: 'Choose Columns:' + }, + sort: { + ascending: 'Sort Ascending', + descending: 'Sort Descending', + none: 'Sort None', + remove: 'Remove Sort' + }, + column: { + hide: 'Hide Column' + }, + aggregation: { + count: 'total rows: ', + sum: 'total: ', + avg: 'avg: ', + min: 'min: ', + max: 'max: ' + }, + pinning: { + pinLeft: 'Pin Left', + pinRight: 'Pin Right', + unpin: 'Unpin' + }, + columnMenu: { + close: 'Close' + }, + gridMenu: { + aria: { + buttonLabel: 'Grid Menu' + }, + columns: 'Kolonner:', + importerTitle: 'Importer fil', + exporterAllAsCsv: 'Eksporter alle data som csv', + exporterVisibleAsCsv: 'Eksporter synlige data som csv', + exporterSelectedAsCsv: 'Eksporter utvalgte data som csv', + exporterAllAsPdf: 'Eksporter alle data som pdf', + exporterVisibleAsPdf: 'Eksporter synlige data som pdf', + exporterSelectedAsPdf: 'Eksporter utvalgte data som pdf', + clearAllFilters: 'Clear all filters' + }, + importer: { + noHeaders: 'Column names were unable to be derived, does the file have a header?', + noObjects: 'Objects were not able to be derived, was there data in the file other than headers?', + invalidCsv: 'File was unable to be processed, is it valid CSV?', + invalidJson: 'File was unable to be processed, is it valid Json?', + jsonNotArray: 'Imported json file must contain an array, aborting.' + }, + pagination: { + aria: { + pageToFirst: 'Page to first', + pageBack: 'Page back', + pageSelected: 'Selected page', + pageForward: 'Page forward', + pageToLast: 'Page to last' + }, + sizes: 'items per page', + totalItems: 'items', + through: 'through', + of: 'of' + }, + grouping: { + group: 'Group', + ungroup: 'Ungroup', + aggregate_count: 'Agg: Count', + aggregate_sum: 'Agg: Sum', + aggregate_max: 'Agg: Max', + aggregate_min: 'Agg: Min', + aggregate_avg: 'Agg: Avg', + aggregate_remove: 'Agg: Remove' + } + }); + return $delegate; + }]); + }]); +})(); + (function () { angular.module('ui.grid').config(['$provide', function($provide) { $provide.decorator('i18nService', ['$delegate', function($delegate) { @@ -13751,6 +14048,113 @@ module.filter('px', function() { }]); }]); })(); +(function () { + angular.module('ui.grid').config(['$provide', function($provide) { + $provide.decorator('i18nService', ['$delegate', function($delegate) { + $delegate.add('ua', { + headerCell: { + aria: { + defaultFilterLabel: 'Фільтр стовпчика', + removeFilter: 'Видалити фільтр', + columnMenuButtonLabel: 'Меню ствпчика' + }, + priority: 'Пріоритет:', + filterLabel: "Фільтр стовпчика: " + }, + aggregate: { + label: 'елементи' + }, + groupPanel: { + description: 'Для групування за стовпчиком перетягніть сюди його назву.' + }, + search: { + placeholder: 'Пошук...', + showingItems: 'Показати елементи:', + selectedItems: 'Обрані елементи:', + totalItems: 'Усього елементів:', + size: 'Розмір сторінки:', + first: 'Перша сторінка', + next: 'Наступна сторінка', + previous: 'Попередня сторінка', + last: 'Остання сторінка' + }, + menu: { + text: 'Обрати ствпчики:' + }, + sort: { + ascending: 'За зростанням', + descending: 'За спаданням', + none: 'Без сортування', + remove: 'Прибрати сортування' + }, + column: { + hide: 'Приховати стовпчик' + }, + aggregation: { + count: 'усього рядків: ', + sum: 'ітого: ', + avg: 'середнє: ', + min: 'мін: ', + max: 'макс: ' + }, + pinning: { + pinLeft: 'Закріпити ліворуч', + pinRight: 'Закріпити праворуч', + unpin: 'Відкріпити' + }, + columnMenu: { + close: 'Закрити' + }, + gridMenu: { + aria: { + buttonLabel: 'Меню' + }, + columns: 'Стовпчики:', + importerTitle: 'Імпортувати файл', + exporterAllAsCsv: 'Експортувати все в CSV', + exporterVisibleAsCsv: 'Експортувати видимі дані в CSV', + exporterSelectedAsCsv: 'Експортувати обрані дані в CSV', + exporterAllAsPdf: 'Експортувати все в PDF', + exporterVisibleAsPdf: 'Експортувати видимі дані в PDF', + exporterSelectedAsPdf: 'Експортувати обрані дані в PDF', + clearAllFilters: 'Очистити всі фільтри' + }, + importer: { + noHeaders: 'Не вдалося отримати назви стовпчиків, чи є в файлі заголовок?', + noObjects: 'Не вдалося отримати дані, чи є в файлі рядки окрім заголовка?', + invalidCsv: 'Не вдалося обробити файл, чи це коректний CSV-файл?', + invalidJson: 'Не вдалося обробити файл, чи це коректний JSON?', + jsonNotArray: 'JSON-файл що імпортується повинен містити масив, операцію скасовано.' + }, + pagination: { + aria: { + pageToFirst: 'Перша сторінка', + pageBack: 'Попередня сторінка', + pageSelected: 'Обрана сторінка', + pageForward: 'Наступна сторінка', + pageToLast: 'Остання сторінка' + }, + sizes: 'рядків на сторінку', + totalItems: 'рядків', + through: 'по', + of: 'з' + }, + grouping: { + group: 'Групувати', + ungroup: 'Розгрупувати', + aggregate_count: 'Групувати: Кількість', + aggregate_sum: 'Для групи: Сума', + aggregate_max: 'Для групи: Максимум', + aggregate_min: 'Для групи: Мінімум', + aggregate_avg: 'Для групи: Серднє', + aggregate_remove: 'Для групи: Пусто' + } + }); + return $delegate; + }]); + }]); +})(); + /** * @ngdoc overview * @name ui.grid.i18n @@ -14271,6 +14675,7 @@ module.filter('px', function() { if (newGridHeight !== prevGridHeight || newGridWidth !== prevGridWidth) { uiGridCtrl.grid.gridHeight = newGridHeight; uiGridCtrl.grid.gridWidth = newGridWidth; + uiGridCtrl.grid.api.core.raise.gridDimensionChanged(prevGridHeight, prevGridWidth, newGridHeight, newGridWidth); $scope.$apply(function () { uiGridCtrl.grid.refresh() @@ -15114,7 +15519,7 @@ module.filter('px', function() { var values = []; var currentSelection = grid.api.cellNav.getCurrentSelection(); for (var i = 0; i < currentSelection.length; i++) { - values.push(currentSelection[i].getIntersectionValueFiltered()); + values.push(grid.getCellDisplayValue(currentSelection[i].row, currentSelection[i].col)); } var cellText = values.toString(); setNotifyText(cellText); @@ -16086,7 +16491,7 @@ module.filter('px', function() { * [ {id: xxx, value: xxx} ], which will be used to populate * the edit dropdown. This can be used when the dropdown values are dependent on * the backing row entity with some kind of algorithm. - * If this property is set then both editDropdownOptionsArray and + * If this property is set then both editDropdownOptionsArray and * editDropdownRowEntityOptionsArrayPath will be ignored. * @param {object} rowEntity the options.data element that the returned array refers to * @param {object} colDef the column that implements this dropdown @@ -16158,20 +16563,18 @@ module.filter('px', function() { return; } + var modelField = $scope.row.getQualifiedColField($scope.col); + if ($scope.col.colDef.editModelField) { + modelField = gridUtil.preEval('row.entity.' + $scope.col.colDef.editModelField); + } + + cellModel = $parse(modelField); - cellModel = $parse($scope.row.getQualifiedColField($scope.col)); //get original value from the cell origCellValue = cellModel($scope); html = $scope.col.editableCellTemplate; - - if ($scope.col.colDef.editModelField) { - html = html.replace(uiGridConstants.MODEL_COL_FIELD, gridUtil.preEval('row.entity.' + $scope.col.colDef.editModelField)); - } - else { - html = html.replace(uiGridConstants.MODEL_COL_FIELD, $scope.row.getQualifiedColField($scope.col)); - } - + html = html.replace(uiGridConstants.MODEL_COL_FIELD, modelField); html = html.replace(uiGridConstants.COL_FIELD, 'grid.getCellValue(row, col)'); var optionFilter = $scope.col.colDef.editDropdownFilter ? '|' + $scope.col.colDef.editDropdownFilter : ''; @@ -16282,7 +16685,10 @@ module.filter('px', function() { var gridCellContentsEl = angular.element($elm.children()[0]); //remove edit element editCellScope.$destroy(); - angular.element($elm.children()[1]).remove(); + var children = $elm.children(); + for (var i = 1; i < children.length; i++) { + angular.element(children[i]).remove(); + } gridCellContentsEl.removeClass('ui-grid-cell-contents-hidden'); inEdit = false; registerBeginEditEvents(); @@ -16361,7 +16767,7 @@ module.filter('px', function() { $timeout(function () { $elm[0].focus(); //only select text if it is not being replaced below in the cellNav viewPortKeyPress - if ($elm[0].select && $scope.col.colDef.enableCellEditOnFocus || !(uiGridCtrl && uiGridCtrl.grid.api.cellNav)) { + if ($elm[0].select && ($scope.col.colDef.enableCellEditOnFocus || !(uiGridCtrl && uiGridCtrl.grid.api.cellNav))) { $elm[0].select(); } else { @@ -17033,7 +17439,13 @@ module.filter('px', function() { compile: function () { return { pre: function ($scope, $elm, $attrs, uiGridCtrl) { - if ( uiGridCtrl.grid.options.enableExpandableRowHeader !== false ) { + uiGridExpandableService.initializeGrid(uiGridCtrl.grid); + + if (!uiGridCtrl.grid.options.enableExpandable) { + return; + } + + if (uiGridCtrl.grid.options.enableExpandableRowHeader !== false ) { var expandableRowHeaderColDef = { name: 'expandableButtons', displayName: '', @@ -17044,9 +17456,9 @@ module.filter('px', function() { }; expandableRowHeaderColDef.cellTemplate = $templateCache.get('ui-grid/expandableRowHeader'); expandableRowHeaderColDef.headerCellTemplate = $templateCache.get('ui-grid/expandableTopRowHeader'); - uiGridCtrl.grid.addRowHeaderColumn(expandableRowHeaderColDef); + uiGridCtrl.grid.addRowHeaderColumn(expandableRowHeaderColDef, -90); } - uiGridExpandableService.initializeGrid(uiGridCtrl.grid); + }, post: function ($scope, $elm, $attrs, uiGridCtrl) { } @@ -17125,6 +17537,18 @@ module.filter('px', function() { gridUtil.getTemplate($scope.grid.options.expandableRowTemplate).then( function (template) { if ($scope.grid.options.expandableRowScope) { + /** + * @ngdoc object + * @name expandableRowScope + * @propertyOf ui.grid.expandable.api:GridOptions + * @description Variables of object expandableScope will be available in the scope of the expanded subgrid + * @example + *
+                     *    $scope.gridOptions = {
+                     *      expandableRowScope: expandableScope
+                     *    }
+                     *  
+ */ var expandableRowScope = $scope.grid.options.expandableRowScope; for (var property in expandableRowScope) { if (expandableRowScope.hasOwnProperty(property)) { @@ -17132,8 +17556,9 @@ module.filter('px', function() { } } } - var expandedRowElement = $compile(template)($scope); + var expandedRowElement = angular.element(template); $elm.append(expandedRowElement); + expandedRowElement = $compile(expandedRowElement)($scope); $scope.row.expandedRendered = true; }); }, @@ -17163,6 +17588,10 @@ module.filter('px', function() { return { pre: function ($scope, $elm, $attrs, controllers) { + if (!$scope.grid.options.enableExpandable) { + return; + } + $scope.expandableRow = {}; $scope.expandableRow.shouldRenderExpand = function () { @@ -17221,6 +17650,11 @@ module.filter('px', function() { priority: -200, scope: false, compile: function ($elm, $attrs) { + + //todo: this adds ng-if watchers to each row even if the grid is not using expandable directive + // or options.enableExpandable == false + // The alternative is to compile the template and append to each row in a uiGridRow directive + var rowRepeatDiv = angular.element($elm.children().children()[0]); var expandedRowFillerElement = $templateCache.get('ui-grid/expandableScrollFiller'); var expandedRowElement = $templateCache.get('ui-grid/expandableRow'); @@ -17865,7 +18299,7 @@ module.filter('px', function() { var exportData = self.getData(grid, rowTypes, colTypes); var csvContent = self.formatAsCsv(exportColumnHeaders, exportData, grid.options.exporterCsvColumnSeparator); - self.downloadFile (grid.options.exporterCsvFilename, csvContent, grid.options.exporterOlderExcelCompatibility); + self.downloadFile (grid.options.exporterCsvFilename, csvContent, grid.options.exporterCsvColumnSeparator, grid.options.exporterOlderExcelCompatibility); }); }, @@ -18052,7 +18486,7 @@ module.filter('px', function() { /** * @ngdoc function - * @name formatAsCSV + * @name formatAsCsv * @methodOf ui.grid.exporter.service:uiGridExporterService * @description Formats the column headers and data as a CSV, * and sends that data to the user @@ -18060,6 +18494,7 @@ module.filter('px', function() { * where each header is an object with name, width and maybe alignment * @param {array} exportData an array of rows, where each row is * an array of column data + * @param {string} separator a string that represents the separator to be used in the csv file * @returns {string} csv the formatted csv as a string */ formatAsCsv: function (exportColumnHeaders, exportData, separator) { @@ -18148,27 +18583,12 @@ module.filter('px', function() { * download as a file * @param {boolean} exporterOlderExcelCompatibility whether or not we put a utf-16 BOM on the from (\uFEFF) */ - downloadFile: function (fileName, csvContent, exporterOlderExcelCompatibility) { + downloadFile: function (fileName, csvContent, columnSeparator, exporterOlderExcelCompatibility) { var D = document; var a = D.createElement('a'); var strMimeType = 'application/octet-stream;charset=utf-8'; var rawFile; - var ieVersion; - - ieVersion = this.isIE(); - if (ieVersion && ieVersion < 10) { - var frame = D.createElement('iframe'); - document.body.appendChild(frame); - - frame.contentWindow.document.open("text/html", "replace"); - frame.contentWindow.document.write('sep=,\r\n' + csvContent); - frame.contentWindow.document.close(); - frame.contentWindow.focus(); - frame.contentWindow.document.execCommand('SaveAs', true, fileName); - - document.body.removeChild(frame); - return true; - } + var ieVersion = this.isIE(); // IE10+ if (navigator.msSaveBlob) { @@ -18180,6 +18600,20 @@ module.filter('px', function() { ); } + if (ieVersion) { + var frame = D.createElement('iframe'); + document.body.appendChild(frame); + + frame.contentWindow.document.open('text/html', 'replace'); + frame.contentWindow.document.write('sep=' + columnSeparator + '\r\n' + csvContent); + frame.contentWindow.document.close(); + frame.contentWindow.focus(); + frame.contentWindow.document.execCommand('SaveAs', true, fileName); + + document.body.removeChild(frame); + return true; + } + //html5 A[download] if ('download' in a) { var blob = new Blob( @@ -19138,7 +19572,7 @@ module.filter('px', function() { columns.sort(function(a, b){ var a_group, b_group; if (a.isRowHeader){ - a_group = -1000; + a_group = a.headerPriority; } else if ( typeof(a.grouping) === 'undefined' || typeof(a.grouping.groupPriority) === 'undefined' || a.grouping.groupPriority < 0){ a_group = null; @@ -19147,7 +19581,7 @@ module.filter('px', function() { } if (b.isRowHeader){ - b_group = -1000; + b_group = b.headerPriority; } else if ( typeof(b.grouping) === 'undefined' || typeof(b.grouping.groupPriority) === 'undefined' || b.grouping.groupPriority < 0){ b_group = null; @@ -20827,17 +21261,28 @@ module.filter('px', function() { } if (args.y) { - var percentage; - var targetPercentage = args.grid.options.infiniteScrollRowsFromEnd / args.grid.renderContainers.body.visibleRowCache.length; - if (args.grid.scrollDirection === uiGridConstants.scrollDirection.UP ) { - percentage = args.y.percentage; - if (percentage <= targetPercentage){ - service.loadData(args.grid); - } - } else if (args.grid.scrollDirection === uiGridConstants.scrollDirection.DOWN) { - percentage = 1 - args.y.percentage; - if (percentage <= targetPercentage){ - service.loadData(args.grid); + + // If the user is scrolling very quickly all the way to the top/bottom, the scroll handler can get confused + // about the direction. First we check if they've gone all the way, and data always is loaded in this case. + if (args.y.percentage === 0) { + args.grid.scrollDirection = uiGridConstants.scrollDirection.UP; + service.loadData(args.grid); + } else if (args.y.percentage === 1) { + args.grid.scrollDirection = uiGridConstants.scrollDirection.DOWN; + service.loadData(args.grid); + } else { // Scroll position is somewhere in between top/bottom, so determine whether it's far enough to load more data. + var percentage; + var targetPercentage = args.grid.options.infiniteScrollRowsFromEnd / args.grid.renderContainers.body.visibleRowCache.length; + if (args.grid.scrollDirection === uiGridConstants.scrollDirection.UP ) { + percentage = args.y.percentage; + if (percentage <= targetPercentage){ + service.loadData(args.grid); + } + } else if (args.grid.scrollDirection === uiGridConstants.scrollDirection.DOWN) { + percentage = 1 - args.y.percentage; + if (percentage <= targetPercentage){ + service.loadData(args.grid); + } } } } @@ -21240,11 +21685,24 @@ module.filter('px', function() { }); }, redrawColumnAtPosition: function (grid, originalPosition, newPosition) { + var columns = grid.columns; + if (originalPosition === newPosition) { return; } - var columns = grid.columns; + //check columns in between move-range to make sure they are visible columns + var pos = (originalPosition < newPosition) ? originalPosition + 1 : originalPosition - 1; + var i0 = Math.min(pos, newPosition); + for (i0; i0 <= Math.max(pos, newPosition); i0++) { + if (columns[i0].visible) { + break; + } + } + if (i0 > Math.max(pos, newPosition)) { + //no visible column found, column did not visibly move + return; + } var originalColumn = columns[originalPosition]; if (originalColumn.colDef.enableColumnMoving) { @@ -21383,7 +21841,7 @@ module.filter('px', function() { gridLeft += $scope.grid.renderContainers.left.header[0].getBoundingClientRect().width; } - previousMouseX = event.pageX; + previousMouseX = event.pageX || (event.originalEvent ? event.originalEvent.pageX : 0); totalMouseMovement = 0; rightMoveLimit = gridLeft + $scope.grid.getViewportWidth(); @@ -21397,7 +21855,8 @@ module.filter('px', function() { }; var moveFn = function( event ) { - var changeValue = event.pageX - previousMouseX; + var pageX = event.pageX || (event.originalEvent ? event.originalEvent.pageX : 0); + var changeValue = pageX - previousMouseX; if ( changeValue === 0 ){ return; } //Disable text selection in Chrome during column move document.onselectstart = function() { return false; }; @@ -21409,7 +21868,7 @@ module.filter('px', function() { } else if (elmCloned) { moveElement(changeValue); - previousMouseX = event.pageX; + previousMouseX = pageX; } }; @@ -24504,12 +24963,9 @@ module.filter('px', function() { * @param {bool} selected value to set */ $delegate.prototype.setSelected = function(selected) { - this.isSelected = selected; - if (selected) { - this.grid.selection.selectedCount++; - } - else { - this.grid.selection.selectedCount--; + if (selected !== this.isSelected) { + this.isSelected = selected; + this.grid.selection.selectedCount += selected ? 1 : -1; } }; @@ -25105,7 +25561,7 @@ module.filter('px', function() { allowCellFocus: true }; - uiGridCtrl.grid.addRowHeaderColumn(selectionRowHeaderDef); + uiGridCtrl.grid.addRowHeaderColumn(selectionRowHeaderDef, 0); } var processorSet = false; @@ -25878,7 +26334,7 @@ module.filter('px', function() { * @ngdoc object * @name showTreeRowHeader * @propertyOf ui.grid.treeBase.api:GridOptions - * @description If set to false, don't create the row header. Youll need to programatically control the expand + * @description If set to false, don't create the row header. You'll need to programmatically control the expand * states *
Defaults to true */ @@ -26132,7 +26588,7 @@ module.filter('px', function() { }; rowHeaderColumnDef.visible = grid.options.treeRowHeaderAlwaysVisible; - grid.addRowHeaderColumn( rowHeaderColumnDef ); + grid.addRowHeaderColumn( rowHeaderColumnDef, -100 ); }, @@ -26912,7 +27368,7 @@ module.filter('px', function() { * @param {gridRow} row the parent we're finalising */ finaliseAggregations: function( row ){ - if ( typeof(row.treeNode.aggregations) === 'undefined' ){ + if ( row == null || typeof(row.treeNode.aggregations) === 'undefined' ){ return; } @@ -27621,16 +28077,21 @@ module.filter('px', function() { }; }; + var promises = []; + for (var validatorName in colDef.validators) { service.clearError(rowEntity, colDef, validatorName); var msg; var validatorFunction = service.getValidator(validatorName, colDef.validators[validatorName]); // We pass the arguments as oldValue, newValue so they are in the same order // as ng-model validators (modelValue, viewValue) - $q.when(validatorFunction(oldValue, newValue, rowEntity, colDef)) - .then(validateClosureFactory(rowEntity, colDef, validatorName) - ); + var promise = $q + .when(validatorFunction(oldValue, newValue, rowEntity, colDef)) + .then(validateClosureFactory(rowEntity, colDef, validatorName)); + promises.push(promise); } + + return $q.all(promises); }, /** @@ -27842,6 +28303,7 @@ module.filter('px', function() { }; }]); })(); + angular.module('ui.grid').run(['$templateCache', function($templateCache) { 'use strict'; @@ -27982,7 +28444,7 @@ angular.module('ui.grid').run(['$templateCache', function($templateCache) { $templateCache.put('ui-grid/expandableRowHeader', - "
" + "
" ); diff --git a/InventoryTraker.Web/Scripts/ui-grid.min.js b/InventoryTraker.Web/Scripts/ui-grid.min.js index 15f8db4..e92867a 100644 --- a/InventoryTraker.Web/Scripts/ui-grid.min.js +++ b/InventoryTraker.Web/Scripts/ui-grid.min.js @@ -1,15 +1,15 @@ /*! - * ui-grid - v3.1.1 - 2016-02-09 + * ui-grid - v3.2.9 - 2016-09-21 * Copyright (c) 2016 ; License: MIT */ -!function(){"use strict";angular.module("ui.grid.i18n",[]),angular.module("ui.grid",["ui.grid.i18n"])}(),function(){"use strict";angular.module("ui.grid").constant("uiGridConstants",{LOG_DEBUG_MESSAGES:!0,LOG_WARN_MESSAGES:!0,LOG_ERROR_MESSAGES:!0,CUSTOM_FILTERS:/CUSTOM_FILTERS/g,COL_FIELD:/COL_FIELD/g,MODEL_COL_FIELD:/MODEL_COL_FIELD/g,TOOLTIP:/title=\"TOOLTIP\"/g,DISPLAY_CELL_TEMPLATE:/DISPLAY_CELL_TEMPLATE/g,TEMPLATE_REGEXP:/<.+>/,FUNC_REGEXP:/(\([^)]*\))?$/,DOT_REGEXP:/\./g,APOS_REGEXP:/'/g,BRACKET_REGEXP:/^(.*)((?:\s*\[\s*\d+\s*\]\s*)|(?:\s*\[\s*"(?:[^"\\]|\\.)*"\s*\]\s*)|(?:\s*\[\s*'(?:[^'\\]|\\.)*'\s*\]\s*))(.*)$/,COL_CLASS_PREFIX:"ui-grid-col",events:{GRID_SCROLL:"uiGridScroll",COLUMN_MENU_SHOWN:"uiGridColMenuShown",ITEM_DRAGGING:"uiGridItemDragStart",COLUMN_HEADER_CLICK:"uiGridColumnHeaderClick"},keymap:{TAB:9,STRG:17,CAPSLOCK:20,CTRL:17,CTRLRIGHT:18,CTRLR:18,SHIFT:16,RETURN:13,ENTER:13,BACKSPACE:8,BCKSP:8,ALT:18,ALTR:17,ALTRIGHT:17,SPACE:32,WIN:91,MAC:91,FN:null,PG_UP:33,PG_DOWN:34,UP:38,DOWN:40,LEFT:37,RIGHT:39,ESC:27,DEL:46,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123},ASC:"asc",DESC:"desc",filter:{STARTS_WITH:2,ENDS_WITH:4,EXACT:8,CONTAINS:16,GREATER_THAN:32,GREATER_THAN_OR_EQUAL:64,LESS_THAN:128,LESS_THAN_OR_EQUAL:256,NOT_EQUAL:512,SELECT:"select",INPUT:"input"},aggregationTypes:{sum:2,count:4,avg:8,min:16,max:32},CURRENCY_SYMBOLS:["ƒ","$","£","$","¤","¥","៛","₩","₱","฿","₫"],scrollDirection:{UP:"up",DOWN:"down",LEFT:"left",RIGHT:"right",NONE:"none"},dataChange:{ALL:"all",EDIT:"edit",ROW:"row",COLUMN:"column",OPTIONS:"options"},scrollbars:{NEVER:0,ALWAYS:1}})}(),angular.module("ui.grid").directive("uiGridCell",["$compile","$parse","gridUtil","uiGridConstants",function(a,b,c,d){var e={priority:0,scope:!1,require:"?^uiGrid",compile:function(){return{pre:function(b,e,f,g){function h(){var a=b.col.compiledElementFn;a(b,function(a,b){e.append(a)})}if(g&&b.col.compiledElementFn)h();else if(g&&!b.col.compiledElementFn)b.col.getCompiledElementFn().then(function(a){a(b,function(a,b){e.append(a)})});else{var i=b.col.cellTemplate.replace(d.MODEL_COL_FIELD,"row.entity."+c.preEval(b.col.field)).replace(d.COL_FIELD,"grid.getCellValue(row, col)"),j=a(i)(b);e.append(j)}},post:function(a,b,c,e){var f=a.col.getColClass(!1);b.addClass(f);var g,h=function(c){var d=b;g&&(d.removeClass(g),g=null),g=angular.isFunction(a.col.cellClass)?a.col.cellClass(a.grid,a.row,a.col,a.rowRenderIndex,a.colRenderIndex):a.col.cellClass,d.addClass(g)};a.col.cellClass&&h();var i=a.grid.registerDataChangeCallback(h,[d.dataChange.COLUMN,d.dataChange.EDIT]),j=function(c,d){if(c!==d){(g||a.col.cellClass)&&h();var e=a.col.getColClass(!1);e!==f&&(b.removeClass(f),b.addClass(e),f=e)}},k=a.$watch("row",j),l=function(){i(),k()};a.$on("$destroy",l),b.on("$destroy",l)}}}};return e}]),function(){angular.module("ui.grid").service("uiGridColumnMenuService",["i18nService","uiGridConstants","gridUtil",function(a,b,c){var d={initialize:function(a,b){a.grid=b.grid,b.columnMenuScope=a,a.menuShown=!1},setColMenuItemWatch:function(a){var b=a.$watch("col.menuItems",function(b){"undefined"!=typeof b&&b&&angular.isArray(b)?(b.forEach(function(b){"undefined"!=typeof b.context&&b.context||(b.context={}),b.context.col=a.col}),a.menuItems=a.defaultMenuItems.concat(b)):a.menuItems=a.defaultMenuItems});a.$on("$destroy",b)},sortable:function(a){return a.grid.options.enableSorting&&"undefined"!=typeof a.col&&a.col&&a.col.enableSorting?!0:!1},isActiveSort:function(a,b){return"undefined"!=typeof a.col&&"undefined"!=typeof a.col.sort&&"undefined"!=typeof a.col.sort.direction&&a.col.sort.direction===b},suppressRemoveSort:function(a){return a.col&&a.col.suppressRemoveSort?!0:!1},hideable:function(a){return"undefined"!=typeof a.col&&a.col&&a.col.colDef&&a.col.colDef.enableHiding===!1?!1:!0},getDefaultMenuItems:function(c){return[{title:a.getSafeText("sort.ascending"),icon:"ui-grid-icon-sort-alt-up",action:function(a){a.stopPropagation(),c.sortColumn(a,b.ASC)},shown:function(){return d.sortable(c)},active:function(){return d.isActiveSort(c,b.ASC)}},{title:a.getSafeText("sort.descending"),icon:"ui-grid-icon-sort-alt-down",action:function(a){a.stopPropagation(),c.sortColumn(a,b.DESC)},shown:function(){return d.sortable(c)},active:function(){return d.isActiveSort(c,b.DESC)}},{title:a.getSafeText("sort.remove"),icon:"ui-grid-icon-cancel",action:function(a){a.stopPropagation(),c.unsortColumn()},shown:function(){return d.sortable(c)&&"undefined"!=typeof c.col&&"undefined"!=typeof c.col.sort&&"undefined"!=typeof c.col.sort.direction&&null!==c.col.sort.direction&&!d.suppressRemoveSort(c)}},{title:a.getSafeText("column.hide"),icon:"ui-grid-icon-cancel",shown:function(){return d.hideable(c)},action:function(a){a.stopPropagation(),c.hideColumn()}}]},getColumnElementPosition:function(a,b,d){var e={};return e.left=d[0].offsetLeft,e.top=d[0].offsetTop,e.parentLeft=d[0].offsetParent.offsetLeft,e.offset=0,b.grid.options.offsetLeft&&(e.offset=b.grid.options.offsetLeft),e.height=c.elementHeight(d,!0),e.width=c.elementWidth(d,!0),e},repositionMenu:function(a,b,d,e,f){var g=e[0].querySelectorAll(".ui-grid-menu"),h=c.closestElm(f,".ui-grid-render-container"),i=h.getBoundingClientRect().left-a.grid.element[0].getBoundingClientRect().left,j=h.querySelectorAll(".ui-grid-viewport")[0].scrollLeft,k=b.lastMenuWidth?b.lastMenuWidth:a.lastMenuWidth?a.lastMenuWidth:170,l=b.lastMenuPaddingRight?b.lastMenuPaddingRight:a.lastMenuPaddingRight?a.lastMenuPaddingRight:10;if(0!==g.length){var m=g[0].querySelectorAll(".ui-grid-menu-mid");0===m.length||angular.element(m).hasClass("ng-hide")||(k=c.elementWidth(g,!0),a.lastMenuWidth=k,b.lastMenuWidth=k,l=parseInt(c.getStyles(angular.element(g)[0]).paddingRight,10),a.lastMenuPaddingRight=l,b.lastMenuPaddingRight=l)}var n=d.left+i-j+d.parentLeft+d.width-k+l;nc)d=b;else{if(c>a&&!d)return d=b,!0;if(c>a&&d)return!0}}),d){var g=d.getColClass();b.focus.bySelector(e,".ui-grid-header-cell."+g+" .ui-grid-header-cell-primary-focus",!0).then(angular.noop,function(a){return"canceled"!==a?c():void 0})}else c()})};f.hideColumn=function(){f.col.colDef.visible=!1,f.col.visible=!1,f.grid.queueGridRefresh(),f.hideMenu(),f.grid.api.core.notifyDataChange(c.dataChange.COLUMN),f.grid.api.core.raise.columnVisibilityChanged(f.col),j()}},controller:["$scope",function(a){var b=this;a.$watch("menuItems",function(a){b.menuItems=a})}]};return f}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridFilter",["$compile","$templateCache","i18nService","gridUtil",function(a,b,c,d){return{compile:function(){return{pre:function(b,c,d,e){b.col.updateFilters=function(d){if(c.children().remove(),d){var e=b.col.filterHeaderTemplate;c.append(a(e)(b))}},b.$on("$destroy",function(){delete b.col.updateFilters})},post:function(a,b,e,f){a.aria=c.getSafeText("headerCell.aria"),a.removeFilter=function(a,c){a.term=null,d.focus.bySelector(b,".ui-grid-filter-input-"+c)}}}}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridFooterCell",["$timeout","gridUtil","uiGridConstants","$compile",function(a,b,c,d){var e={priority:0,scope:{col:"=",row:"=",renderIndex:"="},replace:!0,require:"^uiGrid",compile:function(a,b,e){return{pre:function(a,b,c,e){var f=d(a.col.footerCellTemplate)(a);b.append(f)},post:function(a,b,d,e){a.grid=e.grid;var f=a.col.getColClass(!1);b.addClass(f);var g,h=function(c){var d=b;g&&(d.removeClass(g),g=null),g=angular.isFunction(a.col.footerCellClass)?a.col.footerCellClass(a.grid,a.row,a.col,a.rowRenderIndex,a.colRenderIndex):a.col.footerCellClass,d.addClass(g)};a.col.footerCellClass&&h(),a.col.updateAggregationValue();var i=a.grid.registerDataChangeCallback(h,[c.dataChange.COLUMN]);a.grid.api.core.on.rowsRendered(a,a.col.updateAggregationValue),a.grid.api.core.on.rowsRendered(a,h),a.$on("$destroy",i)}}}};return e}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridFooter",["$templateCache","$compile","uiGridConstants","gridUtil","$timeout",function(a,b,c,d,e){return{restrict:"EA",replace:!0,require:["^uiGrid","^uiGridRenderContainer"],scope:!0,compile:function(a,c){return{pre:function(a,c,e,f){var g=f[0],h=f[1];a.grid=g.grid,a.colContainer=h.colContainer,h.footer=c;var i=a.grid.options.footerTemplate;d.getTemplate(i).then(function(d){var e=angular.element(d),f=b(e)(a);if(c.append(f),h){var g=c[0].getElementsByClassName("ui-grid-footer-viewport")[0];g&&(h.footerViewport=g)}})},post:function(a,b,c,e){var f=e[0],g=e[1];f.grid;d.disableAnimations(b),g.footer=b;var h=b[0].getElementsByClassName("ui-grid-footer-viewport")[0];h&&(g.footerViewport=h)}}}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridGridFooter",["$templateCache","$compile","uiGridConstants","gridUtil","$timeout",function(a,b,c,d,e){return{restrict:"EA",replace:!0,require:"^uiGrid",scope:!0,compile:function(a,c){return{pre:function(a,c,e,f){a.grid=f.grid;var g=a.grid.options.gridFooterTemplate;d.getTemplate(g).then(function(d){var e=angular.element(d),f=b(e)(a);c.append(f)})},post:function(a,b,c,d){}}}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridGroupPanel",["$compile","uiGridConstants","gridUtil",function(a,b,c){var d="ui-grid/ui-grid-group-panel";return{restrict:"EA",replace:!0,require:"?^uiGrid",scope:!1,compile:function(b,e){return{pre:function(b,e,f,g){var h=b.grid.options.groupPanelTemplate||d;c.getTemplate(h).then(function(c){var d=angular.element(c),f=a(d)(b);e.append(f)})},post:function(a,b,c,d){b.bind("$destroy",function(){})}}}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridHeaderCell",["$compile","$timeout","$window","$document","gridUtil","uiGridConstants","ScrollEvent","i18nService",function(a,b,c,d,e,f,g,h){var i=500,j=500,k={priority:0,scope:{col:"=",row:"=",renderIndex:"="},require:["^uiGrid","^uiGridRenderContainer"],replace:!0,compile:function(){return{pre:function(b,c,d){var e=a(b.col.headerCellTemplate)(b);c.append(e)},post:function(a,c,e,g){var k=g[0],l=g[1];a.i18n={headerCell:h.getSafeText("headerCell"),sort:h.getSafeText("sort")},a.isSortPriorityVisible=function(){return angular.isNumber(a.col.sort.priority)&&a.grid.columns.some(function(b,c){return angular.isNumber(b.sort.priority)&&b!==a.col})},a.getSortDirectionAriaLabel=function(){var b=a.col,c=b.sort.direction===f.ASC?a.i18n.sort.ascending:b.sort.direction===f.DESC?a.i18n.sort.descending:a.i18n.sort.none,d=c;return a.isSortPriorityVisible()&&(d=d+". "+a.i18n.headerCell.priority+" "+b.sort.priority),d},a.grid=k.grid,a.renderContainer=k.grid.renderContainers[l.containerId];var m=a.col.getColClass(!1);c.addClass(m),a.menuShown=!1,a.asc=f.ASC,a.desc=f.DESC;var n,o,p=(angular.element(c[0].querySelectorAll(".ui-grid-header-cell-menu")),angular.element(c[0].querySelectorAll(".ui-grid-cell-contents"))),q=[];a.downFn=function(e){e.stopPropagation(),"undefined"!=typeof e.originalEvent&&void 0!==e.originalEvent&&(e=e.originalEvent),e.button&&0!==e.button||(o=e.pageX,a.mousedownStartTime=(new Date).getTime(),a.mousedownTimeout=b(function(){},i),a.mousedownTimeout.then(function(){a.colMenu&&k.columnMenuScope.showMenu(a.col,c,e)}),k.fireEvent(f.events.COLUMN_HEADER_CLICK,{event:e,columnName:a.col.colDef.name}),a.offAllEvents(),"touchstart"===e.type?(d.on("touchend",a.upFn),d.on("touchmove",a.moveFn)):"mousedown"===e.type&&(d.on("mouseup",a.upFn),d.on("mousemove",a.moveFn)))},a.upFn=function(c){c.stopPropagation(),b.cancel(a.mousedownTimeout),a.offAllEvents(),a.onDownEvents(c.type);var d=(new Date).getTime(),e=d-a.mousedownStartTime;e>i||a.sortable&&a.handleClick(c)},a.moveFn=function(c){var d=c.pageX-o;0!==d&&(b.cancel(a.mousedownTimeout),a.offAllEvents(),a.onDownEvents(c.type))},a.clickFn=function(b){b.stopPropagation(),p.off("click",a.clickFn)},a.offAllEvents=function(){p.off("touchstart",a.downFn),p.off("mousedown",a.downFn),d.off("touchend",a.upFn),d.off("mouseup",a.upFn),d.off("touchmove",a.moveFn),d.off("mousemove",a.moveFn),p.off("click",a.clickFn)},a.onDownEvents=function(c){switch(c){case"touchmove":case"touchend":p.on("click",a.clickFn),p.on("touchstart",a.downFn),b(function(){p.on("mousedown",a.downFn)},j);break;case"mousemove":case"mouseup":p.on("click",a.clickFn),p.on("mousedown",a.downFn),b(function(){p.on("touchstart",a.downFn)},j);break;default:p.on("click",a.clickFn),p.on("touchstart",a.downFn),p.on("mousedown",a.downFn)}};var r=function(d){var e=c;n&&(e.removeClass(n),n=null),n=angular.isFunction(a.col.headerCellClass)?a.col.headerCellClass(a.grid,a.row,a.col,a.rowRenderIndex,a.colRenderIndex):a.col.headerCellClass,e.addClass(n),b(function(){var b=a.grid.renderContainers.right?a.grid.renderContainers.right:a.grid.renderContainers.body;a.isLastCol=a.col===b.visibleColumnCache[b.visibleColumnCache.length-1]}),k.grid.options.enableSorting&&a.col.enableSorting?a.sortable=!0:a.sortable=!1;var g=a.filterable;k.grid.options.enableFiltering&&a.col.enableFiltering?a.filterable=!0:a.filterable=!1,g!==a.filterable&&("undefined"!=typeof a.col.updateFilters&&a.col.updateFilters(a.filterable),a.filterable?(a.col.filters.forEach(function(b,c){q.push(a.$watch("col.filters["+c+"].term",function(a,b){a!==b&&(k.grid.api.core.raise.filterChanged(),k.grid.api.core.notifyDataChange(f.dataChange.COLUMN),k.grid.queueGridRefresh())}))}),a.$on("$destroy",function(){q.forEach(function(a){a()})})):q.forEach(function(a){a()})),a.col.grid.options&&a.col.grid.options.enableColumnMenus!==!1&&a.col.colDef&&a.col.colDef.enableColumnMenu!==!1?a.colMenu=!0:a.colMenu=!1,a.offAllEvents(),(a.sortable||a.colMenu)&&(a.onDownEvents(),a.$on("$destroy",function(){a.offAllEvents()}))};r();var s=a.grid.registerDataChangeCallback(r,[f.dataChange.COLUMN]);a.$on("$destroy",s),a.handleClick=function(b){var c=!1;b.shiftKey&&(c=!0),k.grid.sortColumn(a.col,c).then(function(){k.columnMenuScope&&k.columnMenuScope.hideMenu(),k.grid.refresh()})},a.toggleMenu=function(b){b.stopPropagation(),k.columnMenuScope.menuShown&&k.columnMenuScope.col===a.col?k.columnMenuScope.hideMenu():k.columnMenuScope.showMenu(a.col,c)}}}}};return k}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridHeader",["$templateCache","$compile","uiGridConstants","gridUtil","$timeout","ScrollEvent",function(a,b,c,d,e,f){var g="ui-grid/ui-grid-header",h="ui-grid/ui-grid-no-header";return{restrict:"EA",replace:!0,require:["^uiGrid","^uiGridRenderContainer"],scope:!0,compile:function(a,c){return{pre:function(a,c,e,i){function j(){m.header=m.colContainer.header=c;var a=c[0].getElementsByClassName("ui-grid-header-canvas");a.length>0?m.headerCanvas=m.colContainer.headerCanvas=a[0]:m.headerCanvas=null}function k(a){if(!l.grid.isScrollingHorizontally){var b=d.normalizeScrollLeft(m.headerViewport,l.grid),c=m.colContainer.scrollHorizontal(b),e=new f(l.grid,null,m.colContainer,f.Sources.ViewPortScroll);e.newScrollLeft=b,c>-1&&(e.x={percentage:c}),l.grid.scrollContainers(null,e)}}var l=i[0],m=i[1];a.grid=l.grid,a.colContainer=m.colContainer,j();var n;n=a.grid.options.showHeader?a.grid.options.headerTemplate?a.grid.options.headerTemplate:g:h,d.getTemplate(n).then(function(d){var e=angular.element(d),f=b(e)(a);if(c.replaceWith(f),c=f,j(),m){var g=c[0].getElementsByClassName("ui-grid-header-viewport")[0];g&&(m.headerViewport=g,angular.element(g).on("scroll",k),a.$on("$destroy",function(){angular.element(g).off("scroll",k)}))}a.grid.queueRefresh()})},post:function(a,b,c,e){function f(){var a=h.colContainer.visibleColumnCache,b="",c=0;return a.forEach(function(a){b+=a.getColClassDefinition(),c+=a.drawnWidth}),h.colContainer.canvasWidth=c,b}var g=e[0],h=e[1];g.grid;d.disableAnimations(b),h.header=b;var i=b[0].getElementsByClassName("ui-grid-header-viewport")[0];i&&(h.headerViewport=i),g&&g.grid.registerStyleComputation({priority:15,func:f})}}}}}])}(),function(){angular.module("ui.grid").service("uiGridGridMenuService",["gridUtil","i18nService","uiGridConstants",function(a,b,c){var d={initialize:function(a,b){b.gridMenuScope=a,a.grid=b,a.registeredMenuItems=[],a.$on("$destroy",function(){a.grid&&a.grid.gridMenuScope&&(a.grid.gridMenuScope=null),a.grid&&(a.grid=null),a.registeredMenuItems&&(a.registeredMenuItems=null)}),a.registeredMenuItems=[],b.api.registerMethod("core","addToGridMenu",d.addToGridMenu),b.api.registerMethod("core","removeFromGridMenu",d.removeFromGridMenu)},addToGridMenu:function(b,c){angular.isArray(c)?b.gridMenuScope?(b.gridMenuScope.registeredMenuItems=b.gridMenuScope.registeredMenuItems?b.gridMenuScope.registeredMenuItems:[],b.gridMenuScope.registeredMenuItems=b.gridMenuScope.registeredMenuItems.concat(c)):a.logError("Asked to addToGridMenu, but gridMenuScope not present. Timing issue? Please log issue with ui-grid"):a.logError("addToGridMenu: menuItems must be an array, and is not, not adding any items")},removeFromGridMenu:function(b,c){var d=-1;b&&b.gridMenuScope&&b.gridMenuScope.registeredMenuItems.forEach(function(b,e){b.id===c&&(d>-1?a.logError("removeFromGridMenu: found multiple items with the same id, removing only the last"):d=e)}),d>-1&&b.gridMenuScope.registeredMenuItems.splice(d,1)},getMenuItems:function(c){var e=[];c.grid.options.gridMenuCustomItems&&(angular.isArray(c.grid.options.gridMenuCustomItems)?e=e.concat(c.grid.options.gridMenuCustomItems):a.logError("gridOptions.gridMenuCustomItems must be an array, and is not"));var f=[{title:b.getSafeText("gridMenu.clearAllFilters"),action:function(a){c.grid.clearAllFilters(void 0,!0,void 0)},shown:function(){return c.grid.options.enableFiltering},order:100}];return e=e.concat(f),e=e.concat(c.registeredMenuItems),c.grid.options.gridMenuShowHideColumns!==!1&&(e=e.concat(d.showHideColumns(c))),e.sort(function(a,b){return a.order-b.order}),e},showHideColumns:function(a){var c=[];return a.grid.options.columnDefs&&0!==a.grid.options.columnDefs.length&&0!==a.grid.columns.length?(c.push({title:b.getSafeText("gridMenu.columns"),order:300}),a.grid.options.gridMenuTitleFilter=a.grid.options.gridMenuTitleFilter?a.grid.options.gridMenuTitleFilter:function(a){return a},a.grid.options.columnDefs.forEach(function(b,e){if(b.enableHiding!==!1){var f={icon:"ui-grid-icon-ok",action:function(a){a.stopPropagation(),d.toggleColumnVisibility(this.context.gridCol)},shown:function(){return this.context.gridCol.colDef.visible===!0||void 0===this.context.gridCol.colDef.visible},context:{gridCol:a.grid.getColumn(b.name||b.field)},leaveOpen:!0,order:301+2*e};d.setMenuItemTitle(f,b,a.grid),c.push(f),f={icon:"ui-grid-icon-cancel",action:function(a){a.stopPropagation(),d.toggleColumnVisibility(this.context.gridCol)},shown:function(){return!(this.context.gridCol.colDef.visible===!0||void 0===this.context.gridCol.colDef.visible)},context:{gridCol:a.grid.getColumn(b.name||b.field)},leaveOpen:!0,order:301+2*e+1},d.setMenuItemTitle(f,b,a.grid),c.push(f)}}),c):c},setMenuItemTitle:function(b,c,d){var e=d.options.gridMenuTitleFilter(c.displayName||a.readableColumnName(c.name)||c.field);"string"==typeof e?b.title=e:e.then?(b.title="",e.then(function(a){b.title=a},function(a){b.title=a})):(a.logError("Expected gridMenuTitleFilter to return a string or a promise, it has returned neither, bad config"),b.title="badconfig")},toggleColumnVisibility:function(a){a.colDef.visible=!(a.colDef.visible===!0||void 0===a.colDef.visible),a.grid.refresh(),a.grid.api.core.notifyDataChange(c.dataChange.COLUMN),a.grid.api.core.raise.columnVisibilityChanged(a)}};return d}]).directive("uiGridMenuButton",["gridUtil","uiGridConstants","uiGridGridMenuService","i18nService",function(a,b,c,d){return{priority:0,scope:!0,require:["^uiGrid"],templateUrl:"ui-grid/ui-grid-menu-button",replace:!0,link:function(b,e,f,g){var h=g[0];b.i18n={aria:d.getSafeText("gridMenu.aria")},c.initialize(b,h.grid),b.shown=!1,b.toggleMenu=function(){b.shown?(b.$broadcast("hide-menu"),b.shown=!1):(b.menuItems=c.getMenuItems(b),b.$broadcast("show-menu"),b.shown=!0)},b.$on("menu-hidden",function(){b.shown=!1,a.focus.bySelector(e,".ui-grid-icon-container")})}}}])}(),function(){angular.module("ui.grid").directive("uiGridMenu",["$compile","$timeout","$window","$document","gridUtil","uiGridConstants","i18nService",function(a,b,c,d,e,f,g){var h={priority:0,scope:{menuItems:"=",autoHide:"=?"},require:"?^uiGrid",templateUrl:"ui-grid/uiGridMenu",replace:!1,link:function(a,d,h,i){var j;a.dynamicStyles="",i&&(j=i.grid.gridHeight-30,a.dynamicStyles=[".grid"+i.grid.id+" .ui-grid-menu-mid {","max-height: "+j+"px;","}"].join(" ")),a.i18n={close:g.getSafeText("columnMenu.close")},a.showMenu=function(c,f){a.shown?a.shownMid||(a.shownMid=!0,a.$emit("menu-shown")):(a.shown=!0,b(function(){a.shownMid=!0,a.$emit("menu-shown")}));var g="click";f&&f.originalEvent&&f.originalEvent.type&&"touchstart"===f.originalEvent.type&&(g=f.originalEvent.type),angular.element(document).off("click touchstart",k),d.off("keyup",l),d.off("keydown",m),b(function(){angular.element(document).on(g,k),d.on("keyup",l),d.on("keydown",m)}),e.focus.bySelector(d,"button[type=button]",!0)},a.hideMenu=function(c){a.shown&&(a.shownMid=!1,b(function(){a.shownMid||(a.shown=!1,a.$emit("menu-hidden"))},200)),angular.element(document).off("click touchstart",k),d.off("keyup",l),d.off("keydown",m)},a.$on("hide-menu",function(b,c){a.hideMenu(b,c)}),a.$on("show-menu",function(b,c){a.showMenu(b,c)});var k=function(){a.shown&&a.$apply(function(){a.hideMenu()})},l=function(b){27===b.keyCode&&a.hideMenu()},m=function(a){var b=function(b){return b.focus(),a.preventDefault(),!1};if(9===a.keyCode){var c,e,f=d[0].querySelectorAll("button:not(.ng-hide)");f.length>0&&(c=f[0],e=f[f.length-1],a.target!==e||a.shiftKey?a.target===c&&a.shiftKey&&b(e):b(c))}};("undefined"==typeof a.autoHide||void 0===a.autoHide)&&(a.autoHide=!0),a.autoHide&&angular.element(c).on("resize",k),a.$on("$destroy",function(){angular.element(document).off("click touchstart",k)}),a.$on("$destroy",function(){angular.element(c).off("resize",k)}),i&&a.$on("$destroy",i.grid.api.core.on.scrollBegin(a,k)),a.$on("$destroy",a.$on(f.events.ITEM_DRAGGING,k))}};return h}]).directive("uiGridMenuItem",["gridUtil","$compile","i18nService",function(a,b,c){var d={priority:0,scope:{name:"=",active:"=",action:"=",icon:"=",shown:"=",context:"=",templateUrl:"=",leaveOpen:"=",screenReaderOnly:"="},require:["?^uiGrid"],templateUrl:"ui-grid/uiGridMenuItem",replace:!1,compile:function(){return{pre:function(c,d){c.templateUrl&&a.getTemplate(c.templateUrl).then(function(a){var e=angular.element(a),f=b(e)(c);d.replaceWith(f)})},post:function(b,d,e,f){var g=f[0];("undefined"==typeof b.shown||null===b.shown)&&(b.shown=function(){return!0}),b.itemShown=function(){var a={};return b.context&&(a.context=b.context),"undefined"!=typeof g&&g&&(a.grid=g.grid),b.shown.call(a)},b.itemAction=function(c,e){if(a.logDebug("itemAction"),c.stopPropagation(),"function"==typeof b.action){var f={};b.context&&(f.context=b.context),"undefined"!=typeof g&&g&&(f.grid=g.grid),b.action.call(f,c,e),b.leaveOpen?a.focus.bySelector(angular.element(a.closestElm(d,".ui-grid-menu-items")),"button[type=button]",!0):b.$emit("hide-menu")}},b.i18n=c.get()}}}};return d}])}(),function(){"use strict";var a=angular.module("ui.grid");angular.forEach([{tag:"Src",method:"attr"},{tag:"Text",method:"text"},{tag:"Href",method:"attr"},{tag:"Class",method:"addClass"},{tag:"Html",method:"html"},{tag:"Alt",method:"attr"},{tag:"Style",method:"css"},{tag:"Value",method:"attr"},{tag:"Id",method:"attr"},{tag:"Id",directiveName:"IdGrid",method:"attr",appendGridId:!0},{tag:"Title",method:"attr"},{tag:"Label",method:"attr",aria:!0},{tag:"Labelledby",method:"attr",aria:!0},{tag:"Labelledby",directiveName:"LabelledbyGrid",appendGridId:!0,method:"attr",aria:!0},{tag:"Describedby",method:"attr",aria:!0},{tag:"Describedby",directiveName:"DescribedbyGrid",appendGridId:!0,method:"attr",aria:!0}],function(b){var c="uiGridOneBind",d=(b.aria?c+"Aria":c)+(b.directiveName?b.directiveName:b.tag);a.directive(d,["gridUtil",function(a){return{restrict:"A",require:["?uiGrid","?^uiGrid"],link:function(c,e,f,g){var h=function(b){var e;if(c.grid)e=c.grid;else if(c.col&&c.col.grid)e=c.col.grid;else if(!g.some(function(a){return a&&a.grid?(e=a.grid,!0):void 0}))throw a.logError("["+d+"] A valid grid could not be found to bind id. Are you using this directive within the correct scope? Trying to generate id: [gridID]-"+b),new Error("No valid grid could be found");if(e){var f=new RegExp(e.id.toString());f.test(b)||(b=e.id.toString()+"-"+b)}return b},i=c.$watch(f[d],function(a){if(a){if(b.appendGridId){var c=null;angular.forEach(a.split(" "),function(a){c=(c?c+" ":"")+h(a)}),a=c}switch(b.method){case"attr":b.aria?e[b.method]("aria-"+b.tag.toLowerCase(),a):e[b.method](b.tag.toLowerCase(),a);break;case"addClass":if(angular.isObject(a)&&!angular.isArray(a)){var d=[],f=!1;if(angular.forEach(a,function(a,b){null!==a&&"undefined"!=typeof a&&(f=!0,a&&d.push(b))}),!f)return;a=d}if(!a)return;e.addClass(angular.isArray(a)?a.join(" "):a);break;default:e[b.method](a)}i()}},!0)}}}])})}(),function(){"use strict";var a=angular.module("ui.grid");a.directive("uiGridRenderContainer",["$timeout","$document","uiGridConstants","gridUtil","ScrollEvent",function(a,b,c,d,e){return{replace:!0,transclude:!0,templateUrl:"ui-grid/uiGridRenderContainer",require:["^uiGrid","uiGridRenderContainer"],scope:{containerId:"=",rowContainerName:"=",colContainerName:"=",bindScrollHorizontal:"=",bindScrollVertical:"=",enableVerticalScrollbar:"=",enableHorizontalScrollbar:"="},controller:"uiGridRenderContainer as RenderContainer",compile:function(){return{pre:function(a,b,c,d){var e=d[0],f=d[1],g=a.grid=e.grid;if(!a.rowContainerName)throw"No row render container name specified";if(!a.colContainerName)throw"No column render container name specified";if(!g.renderContainers[a.rowContainerName])throw"Row render container '"+a.rowContainerName+"' is not registered.";if(!g.renderContainers[a.colContainerName])throw"Column render container '"+a.colContainerName+"' is not registered.";var h=a.rowContainer=g.renderContainers[a.rowContainerName],i=a.colContainer=g.renderContainers[a.colContainerName];f.containerId=a.containerId,f.rowContainer=h,f.colContainer=i},post:function(a,b,c,f){function g(){var b="",c=l.canvasWidth,d=l.getViewportWidth(),e=k.getCanvasHeight(),f=k.getViewportHeight();l.needsHScrollbarPlaceholder()&&(f-=j.scrollbarHeight);var g,i;return g=i=l.getHeaderViewportWidth(),b+="\n .grid"+h.grid.id+" .ui-grid-render-container-"+a.containerId+" .ui-grid-canvas { width: "+c+"px; height: "+e+"px; }",b+="\n .grid"+h.grid.id+" .ui-grid-render-container-"+a.containerId+" .ui-grid-header-canvas { width: "+(c+j.scrollbarWidth)+"px; }",b+=o.explicitHeaderCanvasHeight?"\n .grid"+h.grid.id+" .ui-grid-render-container-"+a.containerId+" .ui-grid-header-canvas { height: "+o.explicitHeaderCanvasHeight+"px; }":"\n .grid"+h.grid.id+" .ui-grid-render-container-"+a.containerId+" .ui-grid-header-canvas { height: inherit; }",b+="\n .grid"+h.grid.id+" .ui-grid-render-container-"+a.containerId+" .ui-grid-viewport { width: "+d+"px; height: "+f+"px; }",b+="\n .grid"+h.grid.id+" .ui-grid-render-container-"+a.containerId+" .ui-grid-header-viewport { width: "+g+"px; }",b+="\n .grid"+h.grid.id+" .ui-grid-render-container-"+a.containerId+" .ui-grid-footer-canvas { width: "+(c+j.scrollbarWidth)+"px; }",b+="\n .grid"+h.grid.id+" .ui-grid-render-container-"+a.containerId+" .ui-grid-footer-viewport { width: "+i+"px; }"}var h=f[0],i=f[1],j=h.grid,k=i.rowContainer,l=i.colContainer,m=null,n=null,o=j.renderContainers[a.containerId];b.addClass("ui-grid-render-container-"+a.containerId),d.on.mousewheel(b,function(a){var b=new e(j,k,l,e.Sources.RenderContainerMouseWheel);if(0!==a.deltaY){var c=-1*a.deltaY*a.deltaFactor;m=i.viewport[0].scrollTop,b.verticalScrollLength=k.getVerticalScrollLength();var f=(m+c)/b.verticalScrollLength;f>=1&&mf?f=0:f>1&&(f=1),b.y={percentage:f,pixels:c}}if(0!==a.deltaX){var g=a.deltaX*a.deltaFactor;n=d.normalizeScrollLeft(i.viewport,j),b.horizontalScrollLength=l.getCanvasWidth()-l.getViewportWidth();var h=(n+g)/b.horizontalScrollLength;0>h?h=0:h>1&&(h=1),b.x={percentage:h,pixels:g}}0!==a.deltaY&&(b.atTop(m)||b.atBottom(m))||0!==a.deltaX&&(b.atLeft(n)||b.atRight(n))||(a.preventDefault(),a.stopPropagation(),b.fireThrottledScrollingEvent("",b))}),b.bind("$destroy",function(){b.unbind("keydown"),["touchstart","touchmove","touchend","keydown","wheel","mousewheel","DomMouseScroll","MozMousePixelScroll"].forEach(function(a){b.unbind(a)})}),h.grid.registerStyleComputation({priority:6,func:g})}}}}}]),a.controller("uiGridRenderContainer",["$scope","gridUtil",function(a,b){}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridRow",["gridUtil",function(a){return{replace:!0,require:["^uiGrid","^uiGridRenderContainer"],scope:{row:"=uiGridRow",rowRenderIndex:"="},compile:function(){return{pre:function(a,b,c,d){function e(){a.row.getRowTemplateFn.then(function(c){var d=a.$new();c(d,function(a,c){h&&(h.remove(),i.$destroy()),b.empty().append(a),h=a,i=d})})}var f=d[0],g=d[1];f.grid;a.grid=f.grid,a.colContainer=g.colContainer;var h,i;e(),a.$watch("row.getRowTemplateFn",function(a,b){a!==b&&e()})},post:function(a,b,c,d){}}}}}])}(),function(){angular.module("ui.grid").directive("uiGridStyle",["gridUtil","$interpolate",function(a,b){return{link:function(a,c,d,e){var f=b(c.text(),!0);f&&a.$watch(f,function(a){c.text(a)})}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridViewport",["gridUtil","ScrollEvent","uiGridConstants","$log",function(a,b,c,d){return{replace:!0,scope:{},controllerAs:"Viewport",templateUrl:"ui-grid/uiGridViewport",require:["^uiGrid","^uiGridRenderContainer"],link:function(c,d,e,f){function g(e){var f=d[0].scrollTop,g=a.normalizeScrollLeft(d,p),h=n.scrollVertical(f),i=o.scrollHorizontal(g),j=new b(p,n,o,b.Sources.ViewPortScroll);j.newScrollLeft=g,j.newScrollTop=f,i>-1&&(j.x={percentage:i}),h>-1&&(j.y={percentage:h}),p.scrollContainers(c.$parent.containerId,j)}function h(a){m.prevScrollArgs=a;var b=a.getNewScrollTop(n,m.viewport);d[0].scrollTop=b}function i(b){m.prevScrollArgs=b;var c=b.getNewScrollLeft(o,m.viewport); -d[0].scrollLeft=a.denormalizeScrollLeft(m.viewport,c,p)}function j(b){var c=b.getNewScrollLeft(o,m.viewport);m.headerViewport&&(m.headerViewport.scrollLeft=a.denormalizeScrollLeft(m.viewport,c,p))}function k(b){var c=b.getNewScrollLeft(o,m.viewport);m.footerViewport&&(m.footerViewport.scrollLeft=a.denormalizeScrollLeft(m.viewport,c,p))}var l=f[0],m=f[1];c.containerCtrl=m;var n=m.rowContainer,o=m.colContainer,p=l.grid;c.grid=l.grid,c.rowContainer=m.rowContainer,c.colContainer=m.colContainer,m.viewport=d,d.on("scroll",g);c.$parent.bindScrollVertical&&p.addVerticalScrollSync(c.$parent.containerId,h),c.$parent.bindScrollHorizontal&&(p.addHorizontalScrollSync(c.$parent.containerId,i),p.addHorizontalScrollSync(c.$parent.containerId+"header",j),p.addHorizontalScrollSync(c.$parent.containerId+"footer",k))},controller:["$scope",function(a){this.rowStyle=function(b){var c=a.rowContainer,d=a.colContainer,e={};if(0===b&&0!==c.currentTopRow){var f=c.currentTopRow*c.grid.options.rowHeight;e["margin-top"]=f+"px"}return 0!==d.currentFirstColumn&&(d.grid.isRTL()?e["margin-right"]=d.columnOffset+"px":e["margin-left"]=d.columnOffset+"px"),e}}]}}])}(),function(){angular.module("ui.grid").directive("uiGridVisible",function(){return function(a,b,c){a.$watch(c.uiGridVisible,function(a){b[a?"removeClass":"addClass"]("ui-grid-invisible")})}})}(),function(){"use strict";function a(a,b,c,d,e,f){return{templateUrl:"ui-grid/ui-grid",scope:{uiGrid:"="},replace:!0,transclude:!0,controller:"uiGridController",compile:function(){return{post:function(a,b,g,h){function i(){b[0].offsetWidth<=0&&p>q?(setTimeout(i,o),q++):c(k)}function j(){angular.element(d).on("resize",m),b.on("$destroy",function(){angular.element(d).off("resize",m)}),a.$watch(function(){return n.hasLeftContainer()},function(a,b){a!==b&&n.refreshCanvas(!0)}),a.$watch(function(){return n.hasRightContainer()},function(a,b){a!==b&&n.refreshCanvas(!0)})}function k(){n.gridWidth=a.gridWidth=e.elementWidth(b),n.canvasWidth=h.grid.gridWidth,n.gridHeight=a.gridHeight=e.elementHeight(b),n.gridHeight<=n.options.rowHeight&&n.options.enableMinHeightCheck&&l(),n.refreshCanvas(!0)}function l(){var c=n.options.minRowsToShow*n.options.rowHeight,d=n.options.showHeader?n.options.headerRowHeight:0,g=n.calcFooterHeight(),h=0;n.options.enableHorizontalScrollbar===f.scrollbars.ALWAYS&&(h=e.getScrollbarWidth());var i=0;if(angular.forEach(n.options.columnDefs,function(a){a.hasOwnProperty("filter")?1>i&&(i=1):a.hasOwnProperty("filters")&&i(n.grid.rowHeaderColumns?n.grid.rowHeaderColumns.length:0);!g&&!c.uiGridColumns&&0===n.grid.options.columnDefs.length&&b.length>0&&n.grid.buildColumnDefsFromData(b),!g&&(n.grid.options.columnDefs.length>0||b.length>0)&&d.push(n.grid.buildColumns().then(function(){n.grid.preCompileCellTemplates()})),e.all(d).then(function(){n.grid.modifyRows(p).then(function(){n.grid.redrawInPlace(!0),a.$evalAsync(function(){n.grid.refreshCanvas(!0),n.grid.callDataChangeCallbacks(f.dataChange.ROW)})})})}}var n=this;n.grid=h.createGrid(a.uiGrid),n.grid.appScope=n.grid.appScope||a.$parent,b.addClass("grid"+n.grid.id),n.grid.rtl="rtl"===d.getStyles(b[0]).direction,a.grid=n.grid,c.uiGridColumns&&c.$observe("uiGridColumns",function(a){n.grid.options.columnDefs=a,n.grid.buildColumns().then(function(){n.grid.preCompileCellTemplates(),n.grid.refreshCanvas(!0)})});var o=[];n.grid.options.fastWatch?(n.uiGrid=a.uiGrid,angular.isString(a.uiGrid.data)?(o.push(a.$parent.$watch(a.uiGrid.data,m)),o.push(a.$parent.$watch(function(){return n.grid.appScope[a.uiGrid.data]?n.grid.appScope[a.uiGrid.data].length:void 0},m))):(o.push(a.$parent.$watch(function(){return a.uiGrid.data},m)),o.push(a.$parent.$watch(function(){return a.uiGrid.data.length},function(){m(a.uiGrid.data)}))),o.push(a.$parent.$watch(function(){return a.uiGrid.columnDefs},l)),o.push(a.$parent.$watch(function(){return a.uiGrid.columnDefs.length},function(){l(a.uiGrid.columnDefs)}))):(angular.isString(a.uiGrid.data)?o.push(a.$parent.$watchCollection(a.uiGrid.data,m)):o.push(a.$parent.$watchCollection(function(){return a.uiGrid.data},m)),o.push(a.$parent.$watchCollection(function(){return a.uiGrid.columnDefs},l)));var p,q=a.$watch(function(){return n.grid.styleComputations},function(){n.grid.refreshCanvas(!0)});a.$on("$destroy",function(){o.forEach(function(a){a()}),q()}),n.fireEvent=function(b,c){("undefined"==typeof c||void 0===c)&&(c={}),("undefined"==typeof c.grid||void 0===c.grid)&&(c.grid=n.grid),a.$broadcast(b,c)},n.innerCompile=function(b){k(b)(a)}}]),angular.module("ui.grid").directive("uiGrid",a),a.$inject=["$compile","$templateCache","$timeout","$window","gridUtil","uiGridConstants"]}(),function(){"use strict";angular.module("ui.grid").directive("uiGridPinnedContainer",["gridUtil",function(a){return{restrict:"EA",replace:!0,template:'
',scope:{side:"=uiGridPinnedContainer"},require:"^uiGrid",compile:function(){return{post:function(a,b,c,d){function e(){var a=this,b=0;a.visibleColumnCache.forEach(function(a){b+=a.drawnWidth});var c=a.getViewportAdjustment();return b+=c.width}function f(){if("left"===a.side||"right"===a.side){for(var b=h.renderContainers[a.side].visibleColumnCache,c=0,d=0;d0?b[0]:null},p.prototype.getColDef=function(a){var b=this.options.columnDefs.filter(function(b){return b.name===a});return b.length>0?b[0]:null},p.prototype.assignTypes=function(){var a=this;a.options.columnDefs.forEach(function(b,c){if(!b.type){var e=new g(b,c,a),f=a.rows.length>0?a.rows[0]:null;f?b.type=d.guessType(a.getCellValue(f,e)):b.type="string"}})},p.prototype.isRowHeaderColumn=function(a){return-1!==this.rowHeaderColumns.indexOf(a)},p.prototype.addRowHeaderColumn=function(a){var b=this,c=new g(a,d.nextUid(),b);c.isRowHeader=!0,b.isRTL()?(b.createRightContainer(),c.renderContainer="right"):(b.createLeftContainer(),c.renderContainer="left"),b.columnBuilders[0](a,c,b.options).then(function(){c.enableFiltering=!1,c.enableSorting=!1,c.enableHiding=!1,b.rowHeaderColumns.push(c),b.buildColumns().then(function(){b.preCompileCellTemplates(),b.queueGridRefresh()})})},p.prototype.getOnlyDataColumns=function(){var a=this,b=[];return a.columns.forEach(function(c){-1===a.rowHeaderColumns.indexOf(c)&&b.push(c)}),b},p.prototype.buildColumns=function(b){var c={orderByColumnDefs:!1};angular.extend(c,b);var e,f=this,h=[],i=f.rowHeaderColumns.length;for(e=0;ee;e++)f.columns[e+i].name!==f.options.columnDefs[e].name?j[e+i]=f.getColumn(f.options.columnDefs[e].name):j[e+i]=f.columns[e+i];f.columns.length=0,Array.prototype.splice.apply(f.columns,[0,0].concat(j))}return a.all(h).then(function(){f.rows.length>0&&f.assignTypes()})},p.prototype.preCompileCellTemplates=function(){var a=this,c=function(c){var d=c.cellTemplate.replace(e.MODEL_COL_FIELD,a.getQualifiedColField(c));d=d.replace(e.COL_FIELD,"grid.getCellValue(row, col)");var f=b(d);c.compiledElementFn=f,c.compiledElementFnDefer&&c.compiledElementFnDefer.resolve(c.compiledElementFn)};this.columns.forEach(function(a){a.cellTemplate?c(a):a.cellTemplatePromise&&a.cellTemplatePromise.then(function(){c(a)})})},p.prototype.getQualifiedColField=function(a){return"row.entity."+d.preEval(a.field)},p.prototype.createLeftContainer=function(){this.hasLeftContainer()||(this.renderContainers.left=new l("left",this,{disableColumnOffset:!0}))},p.prototype.createRightContainer=function(){this.hasRightContainer()||(this.renderContainers.right=new l("right",this,{disableColumnOffset:!0}))},p.prototype.hasLeftContainer=function(){return void 0!==this.renderContainers.left},p.prototype.hasRightContainer=function(){return void 0!==this.renderContainers.right},p.prototype.preprocessColDef=function(a){var b=this;if(!a.field&&!a.name)throw new Error("colDef.name or colDef.field property is required");if(void 0===a.name&&void 0!==a.field){for(var c=a.field,d=2;b.getColumn(c);)c=a.field+d.toString(),d++;a.name=c}},p.prototype.newInN=function(a,b,c,d){for(var e=this,f=[],g=0;g0?d[0]:null},p.prototype.modifyRows=function(b){var c=this,d=c.rows.slice(0),e=c.rowHashMap||c.createRowHashMap();c.rowHashMap=c.createRowHashMap(),c.rows.length=0,b.forEach(function(a,b){var f;f=c.options.enableRowHashing?e.get(a):c.getRow(a,d),f||(f=c.processRowBuilders(new h(a,b,c))),c.rows.push(f),c.rowHashMap.put(a,f)}),c.assignTypes();var f=a.when(c.processRowsProcessors(c.rows)).then(function(a){return c.setVisibleRows(a)}),g=a.when(c.processColumnsProcessors(c.columns)).then(function(a){return c.setVisibleColumns(a)});return a.all([f,g])},p.prototype.addRows=function(a){for(var b=this,c=b.rows.length,d=0;dd)d+=e.drawnWidth,c++;else{for(var g=0,h=f;h>=f-c;h--)g+=a.columns[h].drawnWidth;b>g&&c++}}),c},p.prototype.getBodyHeight=function(){var a=this.getViewportHeight();return a},p.prototype.getViewportHeight=function(){var a=this,b=this.gridHeight-this.headerHeight-this.footerHeight,c=a.getViewportAdjustment();return b+=c.height},p.prototype.getViewportWidth=function(){var a=this,b=this.gridWidth,c=a.getViewportAdjustment();return b+=c.width},p.prototype.getHeaderViewportWidth=function(){var a=this.getViewportWidth();return a},p.prototype.addVerticalScrollSync=function(a,b){this.verticalScrollSyncCallBackFns[a]=b},p.prototype.addHorizontalScrollSync=function(a,b){this.horizontalScrollSyncCallBackFns[a]=b},p.prototype.scrollContainers=function(a,b){if(b.y){var c=["body","left","right"];this.flagScrollingVertically(b),"body"===a?c=["left","right"]:"left"===a?c=["body","right"]:"right"===a&&(c=["body","left"]);for(var d=0;d=b&&(b=a.sort.priority+1)}),b},p.prototype.resetColumnSorting=function(a){var b=this;b.columns.forEach(function(b){b===a||b.suppressRemoveSort||(b.sort={})})},p.prototype.getColumnSorting=function(){var a,b=this,c=[];return a=b.columns.slice(0),a.sort(j.prioritySort).forEach(function(a){a.sort&&"undefined"!=typeof a.sort.direction&&a.sort.direction&&(a.sort.direction===e.ASC||a.sort.direction===e.DESC)&&c.push(a)}),c},p.prototype.sortColumn=function(b,c,d){var e=this,f=null;if("undefined"==typeof b||!b)throw new Error("No column parameter provided");if("boolean"==typeof c?d=c:f=c,d?b.sort.priority||(b.sort.priority=e.getNextColumnSortPriority()):(e.resetColumnSorting(b),b.sort.priority=void 0,b.sort.priority=e.getNextColumnSortPriority()),f)b.sort.direction=f;else{var g=b.sortDirectionCycle.indexOf(b.sort.direction?b.sort.direction:null);g=(g+1)%b.sortDirectionCycle.length,b.colDef&&b.suppressRemoveSort&&!b.sortDirectionCycle[g]&&(g=(g+1)%b.sortDirectionCycle.length),b.sortDirectionCycle[g]?b.sort.direction=b.sortDirectionCycle[g]:b.sort={}}return e.api.core.raise.sortChanged(e,e.getColumnSorting()),a.when(b)},p.prototype.renderingComplete=function(){angular.isFunction(this.options.onRegisterApi)&&this.options.onRegisterApi(this.api),this.api.core.raise.renderingComplete(this.api)},p.prototype.createRowHashMap=function(){var a=this,b=new o;return b.grid=a,b},p.prototype.refresh=function(b){var c=this,d=c.processRowsProcessors(c.rows).then(function(a){c.setVisibleRows(a)}),e=c.processColumnsProcessors(c.columns).then(function(a){c.setVisibleColumns(a)});return a.all([d,e]).then(function(){c.redrawInPlace(b),c.refreshCanvas(!0)})},p.prototype.refreshRows=function(){var a=this;return a.processRowsProcessors(a.rows).then(function(b){a.setVisibleRows(b),a.redrawInPlace(),a.refreshCanvas(!0)})},p.prototype.refreshCanvas=function(b){var c=this;b&&c.buildStyles();var e=a.defer(),f=[];for(var g in c.renderContainers)if(c.renderContainers.hasOwnProperty(g)){var h=c.renderContainers[g];if(null===h.canvasWidth||isNaN(h.canvasWidth))continue;(h.header||h.headerCanvas)&&(h.explicitHeaderHeight=h.explicitHeaderHeight||null,h.explicitHeaderCanvasHeight=h.explicitHeaderCanvasHeight||null,f.push(h))}return f.length>0?(b&&c.buildStyles(),m(function(){var a,g,h=!1,i=0,j=0,k=function(a,b){return a!==b&&(h=!0),b};for(a=0;ao?0:o,g.innerHeaderHeight=o,!g.explicitHeaderHeight&&o>i&&(i=o)}if(g.headerCanvas){var p=g.headerCanvasHeight=k(g.headerCanvasHeight,parseInt(d.outerElementHeight(g.headerCanvas),10));!g.explicitHeaderCanvasHeight&&p>j&&(j=p)}}for(a=0;a0&&"undefined"!=typeof g.headerHeight&&null!==g.headerHeight&&(g.explicitHeaderHeight||g.headerHeight0&&"undefined"!=typeof g.headerCanvasHeight&&null!==g.headerCanvasHeight&&(g.explicitHeaderCanvasHeight||g.headerCanvasHeight0},p.prototype.hasRightContainerColumns=function(){return this.hasRightContainer()&&this.renderContainers.right.renderedColumns.length>0},p.prototype.scrollToIfNecessary=function(b,c){var d=this,e=new n(d,"uiGrid.scrollToIfNecessary"),f=d.renderContainers.body.visibleRowCache,g=d.renderContainers.body.visibleColumnCache,h=d.renderContainers.body.prevScrollTop+d.headerHeight;h=0>h?0:h;var i=d.renderContainers.body.prevScrollLeft,j=d.renderContainers.body.prevScrollTop+d.gridHeight-d.renderContainers.body.headerHeight-d.footerHeight-d.scrollbarWidth,k=d.renderContainers.body.prevScrollLeft+Math.ceil(d.renderContainers.body.getViewportWidth());if(null!==b){var l=f.indexOf(b),m=d.renderContainers.body.getCanvasHeight()-d.renderContainers.body.getViewportHeight(),o=l*d.options.rowHeight+d.headerHeight;o=0>o?0:o;var p,q;h>o?(p=d.renderContainers.body.prevScrollTop-(h-o),q=p/m,e.y={percentage:q}):o>j&&(p=o-j+d.renderContainers.body.prevScrollTop,q=p/m,e.y={percentage:q})}if(null!==c){for(var r=g.indexOf(c),s=d.renderContainers.body.getCanvasWidth()-d.renderContainers.body.getViewportWidth(),t=0,u=0;r>u;u++){var v=g[u];t+=v.drawnWidth}t=0>t?0:t;var w=t+c.drawnWidth;w=0>w?0:w;var x,y;i>t?(x=d.renderContainers.body.prevScrollLeft-(i-t),y=x/s,y=y>1?1:y,e.x={percentage:y}):w>k&&(x=w-k+d.renderContainers.body.prevScrollLeft,y=x/s,y=y>1?1:y,e.x={percentage:y})}var z=a.defer();if(e.y||e.x){e.withDelay=!1,d.scrollContainers("",e);var A=d.api.core.on.scrollEnd(null,function(){z.resolve(e),A()})}else z.resolve();return z.promise},p.prototype.scrollTo=function(a,b){var c=null,d=null;return null!==a&&"undefined"!=typeof a&&(c=this.getRow(a)),null!==b&&"undefined"!=typeof b&&(d=this.getColumn(b.name?b.name:b.field)),this.scrollToIfNecessary(c,d)},p.prototype.clearAllFilters=function(a,b,c){return void 0===a&&(a=!0),void 0===b&&(b=!1),void 0===c&&(c=!1),this.columns.forEach(function(a){a.filters.forEach(function(a){a.term=void 0,b&&(a.condition=void 0),c&&(a.flags=void 0)})}),a?this.refreshRows():void 0},o.prototype={put:function(a,b){this[this.grid.options.rowIdentity(a)]=b},get:function(a){return this[this.grid.options.rowIdentity(a)]},remove:function(a){var b=this[a=this.grid.options.rowIdentity(a)];return delete this[a],b}},p}])}(),function(){angular.module("ui.grid").factory("GridApi",["$q","$rootScope","gridUtil","uiGridConstants","GridRow","uiGridGridMenuService",function(a,b,c,d,e,f){function g(a,c,d,e){return b.$on(a,function(a){var b=Array.prototype.slice.call(arguments);b.splice(0,1),c.apply(e?e:d.api,b)})}var h=function(a){this.grid=a,this.listeners=[],this.registerEvent("core","renderingComplete"),this.registerEvent("core","filterChanged"),this.registerMethod("core","setRowInvisible",e.prototype.setRowInvisible),this.registerMethod("core","clearRowInvisible",e.prototype.clearRowInvisible),this.registerMethod("core","getVisibleRows",this.grid.getVisibleRows),this.registerEvent("core","rowsVisibleChanged"),this.registerEvent("core","rowsRendered"),this.registerEvent("core","scrollBegin"),this.registerEvent("core","scrollEnd"),this.registerEvent("core","canvasHeightChanged")};return h.prototype.suppressEvents=function(a,b){var c=this,d=angular.isArray(a)?a:[a],e=c.listeners.filter(function(a){return d.some(function(b){return a.handler===b})});e.forEach(function(a){a.dereg()}),b(),e.forEach(function(a){a.dereg=g(a.eventId,a.handler,c.grid,a._this)})},h.prototype.registerEvent=function(a,d){var e=this;e[a]||(e[a]={});var f=e[a];f.on||(f.on={},f.raise={});var h=e.grid.id+a+d;f.raise[d]=function(){b.$emit.apply(b,[h].concat(Array.prototype.slice.call(arguments)))},f.on[d]=function(b,f,i){if(null!==b&&"undefined"==typeof b.$on)return void c.logError("asked to listen on "+a+".on."+d+" but scope wasn't passed in the input parameters. It is legitimate to pass null, but you've passed something else, so you probably forgot to provide scope rather than did it deliberately, not registering"); -var j=g(h,f,e.grid,i),k={handler:f,dereg:j,eventId:h,scope:b,_this:i};e.listeners.push(k);var l=function(){k.dereg();var a=e.listeners.indexOf(k);e.listeners.splice(a,1)};return b&&b.$on("$destroy",function(){l()}),l}},h.prototype.registerEventsFromObject=function(a){var b=this,c=[];angular.forEach(a,function(a,b){var d={name:b,events:[]};angular.forEach(a,function(a,b){d.events.push(b)}),c.push(d)}),c.forEach(function(a){a.events.forEach(function(c){b.registerEvent(a.name,c)})})},h.prototype.registerMethod=function(a,b,d,e){this[a]||(this[a]={});var f=this[a];f[b]=c.createBoundedWrapper(e||this.grid,d)},h.prototype.registerMethodsFromObject=function(a,b){var c=this,d=[];angular.forEach(a,function(a,b){var c={name:b,methods:[]};angular.forEach(a,function(a,b){c.methods.push({name:b,fn:a})}),d.push(c)}),d.forEach(function(a){a.methods.forEach(function(d){c.registerMethod(a.name,d.name,d.fn,b)})})},h}])}(),function(){angular.module("ui.grid").factory("GridColumn",["gridUtil","uiGridConstants","i18nService",function(a,b,c){function d(a,c,d){var e=this;e.grid=d,e.uid=c,e.updateColumnDef(a,!0),e.aggregationValue=void 0,e.updateAggregationValue=function(){if(!e.aggregationType)return void(e.aggregationValue=void 0);var a=0,c=e.grid.getVisibleRows(),d=function(){var a=[];return c.forEach(function(b){var c=e.grid.getCellValue(b,e),d=Number(c);isNaN(d)||a.push(d)}),a};angular.isFunction(e.aggregationType)?e.aggregationValue=e.aggregationType(c,e):e.aggregationType===b.aggregationTypes.count?e.aggregationValue=e.grid.getVisibleRowCount():e.aggregationType===b.aggregationTypes.sum?(d().forEach(function(b){a+=b}),e.aggregationValue=a):e.aggregationType===b.aggregationTypes.avg?(d().forEach(function(b){a+=b}),a/=d().length,e.aggregationValue=a):e.aggregationType===b.aggregationTypes.min?e.aggregationValue=Math.min.apply(null,d()):e.aggregationType===b.aggregationTypes.max?e.aggregationValue=Math.max.apply(null,d()):e.aggregationValue=" "},this.getAggregationValue=function(){return e.aggregationValue}}return d.prototype.hideColumn=function(){this.colDef.visible=!1},d.prototype.setPropertyOrDefault=function(a,b,c){var d=this;"undefined"!=typeof a[b]&&a[b]?d[b]=a[b]:"undefined"!=typeof d[b]?d[b]=d[b]:d[b]=c?c:{}},d.prototype.updateColumnDef=function(c,d){var e=this;if(e.colDef=c,void 0===c.name)throw new Error("colDef.name is required for column at index "+e.grid.options.columnDefs.indexOf(c));if(e.displayName=void 0===c.displayName?a.readableColumnName(c.name):c.displayName,!angular.isNumber(e.width)||!e.hasCustomWidth||c.allowCustomWidthOverride){var f=c.width,g="Cannot parse column width '"+f+"' for column named '"+c.name+"'";if(e.hasCustomWidth=!1,angular.isString(f)||angular.isNumber(f))if(angular.isString(f))if(a.endsWith(f,"%")){var h=f.replace(/%/g,""),i=parseInt(h,10);if(isNaN(i))throw new Error(g);e.width=f}else if(f.match(/^(\d+)$/))e.width=parseInt(f.match(/^(\d+)$/)[1],10);else{if(!f.match(/^\*+$/))throw new Error(g);e.width=f}else e.width=f;else e.width="*"}["minWidth","maxWidth"].forEach(function(a){var b=c[a],d="Cannot parse column "+a+" '"+b+"' for column named '"+c.name+"'";if(angular.isString(b)||angular.isNumber(b))if(angular.isString(b)){if(!b.match(/^(\d+)$/))throw new Error(d);e[a]=parseInt(b.match(/^(\d+)$/)[1],10)}else e[a]=b;else e[a]="minWidth"===a?30:9e3}),e.field=void 0===c.field?c.name:c.field,"string"!=typeof e.field&&a.logError("Field is not a string, this is likely to break the code, Field is: "+e.field),e.name=c.name,e.displayName=void 0===c.displayName?a.readableColumnName(c.name):c.displayName,e.aggregationType=angular.isDefined(c.aggregationType)?c.aggregationType:null,e.footerCellTemplate=angular.isDefined(c.footerCellTemplate)?c.footerCellTemplate:null,"undefined"==typeof c.cellTooltip||c.cellTooltip===!1?e.cellTooltip=!1:c.cellTooltip===!0?e.cellTooltip=function(a,b){return e.grid.getCellValue(a,b)}:"function"==typeof c.cellTooltip?e.cellTooltip=c.cellTooltip:e.cellTooltip=function(a,b){return b.colDef.cellTooltip},"undefined"==typeof c.headerTooltip||c.headerTooltip===!1?e.headerTooltip=!1:c.headerTooltip===!0?e.headerTooltip=function(a){return a.displayName}:"function"==typeof c.headerTooltip?e.headerTooltip=c.headerTooltip:e.headerTooltip=function(a){return a.colDef.headerTooltip},e.footerCellClass=c.footerCellClass,e.cellClass=c.cellClass,e.headerCellClass=c.headerCellClass,e.cellFilter=c.cellFilter?c.cellFilter:"",e.sortCellFiltered=c.sortCellFiltered?!0:!1,e.filterCellFiltered=c.filterCellFiltered?!0:!1,e.headerCellFilter=c.headerCellFilter?c.headerCellFilter:"",e.footerCellFilter=c.footerCellFilter?c.footerCellFilter:"",e.visible=a.isNullOrUndefined(c.visible)||c.visible,e.headerClass=c.headerClass,e.enableSorting="undefined"!=typeof c.enableSorting?c.enableSorting:!0,e.sortingAlgorithm=c.sortingAlgorithm,e.sortDirectionCycle="undefined"!=typeof c.sortDirectionCycle?c.sortDirectionCycle:[null,b.ASC,b.DESC],"undefined"==typeof e.suppressRemoveSort&&(e.suppressRemoveSort="undefined"!=typeof c.suppressRemoveSort?c.suppressRemoveSort:!1),e.enableFiltering="undefined"!=typeof c.enableFiltering?c.enableFiltering:!0,e.setPropertyOrDefault(c,"menuItems",[]),d&&e.setPropertyOrDefault(c,"sort");var j=[];c.filter?j.push(c.filter):c.filters?j=c.filters:j.push({}),d?(e.setPropertyOrDefault(c,"filter"),e.setPropertyOrDefault(c,"filters",j)):e.filters.length===j.length&&e.filters.forEach(function(a,b){"undefined"!=typeof j[b].placeholder&&(a.placeholder=j[b].placeholder),"undefined"!=typeof j[b].ariaLabel&&(a.ariaLabel=j[b].ariaLabel),"undefined"!=typeof j[b].flags&&(a.flags=j[b].flags),"undefined"!=typeof j[b].type&&(a.type=j[b].type),"undefined"!=typeof j[b].selectOptions&&(a.selectOptions=j[b].selectOptions)})},d.prototype.unsort=function(){this.sort={},this.grid.api.core.raise.sortChanged(this.grid,this.grid.getColumnSorting())},d.prototype.getColClass=function(a){var c=b.COL_CLASS_PREFIX+this.uid;return a?"."+c:c},d.prototype.isPinnedLeft=function(){return"left"===this.renderContainer},d.prototype.isPinnedRight=function(){return"right"===this.renderContainer},d.prototype.getColClassDefinition=function(){return" .grid"+this.grid.id+" "+this.getColClass(!0)+" { min-width: "+this.drawnWidth+"px; max-width: "+this.drawnWidth+"px; }"},d.prototype.getRenderContainer=function(){var a=this,b=a.renderContainer;return(null===b||""===b||void 0===b)&&(b="body"),a.grid.renderContainers[b]},d.prototype.showColumn=function(){this.colDef.visible=!0},d.prototype.getAggregationText=function(){var a=this;if(a.colDef.aggregationHideLabel)return"";if(a.colDef.aggregationLabel)return a.colDef.aggregationLabel;switch(a.colDef.aggregationType){case b.aggregationTypes.count:return c.getSafeText("aggregation.count");case b.aggregationTypes.sum:return c.getSafeText("aggregation.sum");case b.aggregationTypes.avg:return c.getSafeText("aggregation.avg");case b.aggregationTypes.min:return c.getSafeText("aggregation.min");case b.aggregationTypes.max:return c.getSafeText("aggregation.max");default:return""}},d.prototype.getCellTemplate=function(){var a=this;return a.cellTemplatePromise},d.prototype.getCompiledElementFn=function(){var a=this;return a.compiledElementFnDefer.promise},d}])}(),function(){angular.module("ui.grid").factory("GridOptions",["gridUtil","uiGridConstants",function(a,b){return{initialize:function(c){return c.onRegisterApi=c.onRegisterApi||angular.noop(),c.data=c.data||[],c.columnDefs=c.columnDefs||[],c.excludeProperties=c.excludeProperties||["$$hashKey"],c.enableRowHashing=c.enableRowHashing!==!1,c.rowIdentity=c.rowIdentity||function(b){return a.hashKey(b)},c.getRowIdentity=c.getRowIdentity||function(a){return a.$$hashKey},c.flatEntityAccess=c.flatEntityAccess===!0,c.showHeader="undefined"!=typeof c.showHeader?c.showHeader:!0,c.showHeader?c.headerRowHeight="undefined"!=typeof c.headerRowHeight?c.headerRowHeight:30:c.headerRowHeight=0,c.rowHeight=c.rowHeight||30,c.minRowsToShow="undefined"!=typeof c.minRowsToShow?c.minRowsToShow:10,c.showGridFooter=c.showGridFooter===!0,c.showColumnFooter=c.showColumnFooter===!0,c.columnFooterHeight="undefined"!=typeof c.columnFooterHeight?c.columnFooterHeight:30,c.gridFooterHeight="undefined"!=typeof c.gridFooterHeight?c.gridFooterHeight:30,c.columnWidth="undefined"!=typeof c.columnWidth?c.columnWidth:50,c.maxVisibleColumnCount="undefined"!=typeof c.maxVisibleColumnCount?c.maxVisibleColumnCount:200,c.virtualizationThreshold="undefined"!=typeof c.virtualizationThreshold?c.virtualizationThreshold:20,c.columnVirtualizationThreshold="undefined"!=typeof c.columnVirtualizationThreshold?c.columnVirtualizationThreshold:10,c.excessRows="undefined"!=typeof c.excessRows?c.excessRows:4,c.scrollThreshold="undefined"!=typeof c.scrollThreshold?c.scrollThreshold:4,c.excessColumns="undefined"!=typeof c.excessColumns?c.excessColumns:4,c.horizontalScrollThreshold="undefined"!=typeof c.horizontalScrollThreshold?c.horizontalScrollThreshold:2,c.aggregationCalcThrottle="undefined"!=typeof c.aggregationCalcThrottle?c.aggregationCalcThrottle:500,c.wheelScrollThrottle="undefined"!=typeof c.wheelScrollThrottle?c.wheelScrollThrottle:70,c.scrollDebounce="undefined"!=typeof c.scrollDebounce?c.scrollDebounce:300,c.enableSorting=c.enableSorting!==!1,c.enableFiltering=c.enableFiltering===!0,c.enableColumnMenus=c.enableColumnMenus!==!1,c.enableVerticalScrollbar="undefined"!=typeof c.enableVerticalScrollbar?c.enableVerticalScrollbar:b.scrollbars.ALWAYS,c.enableHorizontalScrollbar="undefined"!=typeof c.enableHorizontalScrollbar?c.enableHorizontalScrollbar:b.scrollbars.ALWAYS,c.enableMinHeightCheck=c.enableMinHeightCheck!==!1,c.minimumColumnSize="undefined"!=typeof c.minimumColumnSize?c.minimumColumnSize:10,c.rowEquality=c.rowEquality||function(a,b){return a===b},c.headerTemplate=c.headerTemplate||null,c.footerTemplate=c.footerTemplate||"ui-grid/ui-grid-footer",c.gridFooterTemplate=c.gridFooterTemplate||"ui-grid/ui-grid-grid-footer",c.rowTemplate=c.rowTemplate||"ui-grid/ui-grid-row",c.appScopeProvider=c.appScopeProvider||null,c}}}])}(),function(){angular.module("ui.grid").factory("GridRenderContainer",["gridUtil","uiGridConstants",function(a,b){function c(a,b,c){var d=this;d.name=a,d.grid=b,d.visibleRowCache=[],d.visibleColumnCache=[],d.renderedRows=[],d.renderedColumns=[],d.prevScrollTop=0,d.prevScrolltopPercentage=0,d.prevRowScrollIndex=0,d.prevScrollLeft=0,d.prevScrollleftPercentage=0,d.prevColumnScrollIndex=0,d.columnStyles="",d.viewportAdjusters=[],d.hasHScrollbar=!1,d.hasVScrollbar=!1,d.canvasHeightShouldUpdate=!0,d.$$canvasHeight=0,c&&angular.isObject(c)&&angular.extend(d,c),b.registerStyleComputation({priority:5,func:function(){return d.updateColumnWidths(),d.columnStyles}})}return c.prototype.reset=function(){this.visibleColumnCache.length=0,this.visibleRowCache.length=0,this.renderedRows.length=0,this.renderedColumns.length=0},c.prototype.containsColumn=function(a){return-1!==this.visibleColumnCache.indexOf(a)},c.prototype.minRowsToRender=function(){for(var a=this,b=0,c=0,d=a.getViewportHeight(),e=a.visibleRowCache.length-1;d>c&&e>=0;e--)c+=a.visibleRowCache[e].height,b++;return b},c.prototype.minColumnsToRender=function(){for(var a=this,b=this.getViewportWidth(),c=0,d=0,e=0;ed)d+=f.drawnWidth?f.drawnWidth:0,c++;else{for(var g=0,h=e;h>=e-c;h--)g+=a.visibleColumnCache[h].drawnWidth?a.visibleColumnCache[h].drawnWidth:0;b>g&&c++}}return c},c.prototype.getVisibleRowCount=function(){return this.visibleRowCache.length},c.prototype.registerViewportAdjuster=function(a){this.viewportAdjusters.push(a)},c.prototype.removeViewportAdjuster=function(a){var b=this.viewportAdjusters.indexOf(a);b>-1&&this.viewportAdjusters.splice(b,1)},c.prototype.getViewportAdjustment=function(){var a=this,b={height:0,width:0};return a.viewportAdjusters.forEach(function(a){b=a.call(this,b)}),b},c.prototype.getMargin=function(a){var b=this,c=0;return b.viewportAdjusters.forEach(function(b){var d=b.call(this,{height:0,width:0});d.side&&d.side===a&&(c+=-1*d.width)}),c},c.prototype.getViewportHeight=function(){var a=this,b=a.headerHeight?a.headerHeight:a.grid.headerHeight,c=a.grid.gridHeight-b-a.grid.footerHeight,d=a.getViewportAdjustment();return c+=d.height},c.prototype.getViewportWidth=function(){var a=this,b=a.grid.gridWidth,c=a.getViewportAdjustment();return b+=c.width},c.prototype.getHeaderViewportWidth=function(){var a=this.getViewportWidth();return a},c.prototype.getCanvasHeight=function(){var a=this;if(!a.canvasHeightShouldUpdate)return a.$$canvasHeight;var b=a.$$canvasHeight;return a.$$canvasHeight=0,a.visibleRowCache.forEach(function(b){a.$$canvasHeight+=b.height}),a.canvasHeightShouldUpdate=!1,a.grid.api.core.raise.canvasHeightChanged(b,a.$$canvasHeight),a.$$canvasHeight},c.prototype.getVerticalScrollLength=function(){return this.getCanvasHeight()-this.getViewportHeight()+this.grid.scrollbarHeight},c.prototype.getCanvasWidth=function(){var a=this,b=a.canvasWidth;return b},c.prototype.setRenderedRows=function(a){this.renderedRows.length=a.length;for(var b=0;b0&&(this.grid.scrollDirection=b.scrollDirection.DOWN),0>d&&(this.grid.scrollDirection=b.scrollDirection.UP);var e=this.getVerticalScrollLength();return c=a/e,c>1&&(c=1),0>c&&(c=0),this.adjustScrollVertical(a,c),c}},c.prototype.scrollHorizontal=function(a){var c=-1;if(a!==this.prevScrollLeft){var d=a-this.prevScrollLeft;d>0&&(this.grid.scrollDirection=b.scrollDirection.RIGHT),0>d&&(this.grid.scrollDirection=b.scrollDirection.LEFT);var e=this.canvasWidth-this.getViewportWidth();return c=0!==e?a/e:0,this.adjustScrollHorizontal(a,c),c}},c.prototype.adjustScrollVertical=function(a,b,c){(this.prevScrollTop!==a||c)&&(("undefined"==typeof a||void 0===a||null===a)&&(a=(this.getCanvasHeight()-this.getViewportHeight())*b),this.adjustRows(a,b,!1),this.prevScrollTop=a,this.prevScrolltopPercentage=b,this.grid.queueRefresh())},c.prototype.adjustScrollHorizontal=function(a,b,c){(this.prevScrollLeft!==a||c)&&(("undefined"==typeof a||void 0===a||null===a)&&(a=(this.getCanvasWidth()-this.getViewportWidth())*b),this.adjustColumns(a,b),this.prevScrollLeft=a,this.prevScrollleftPercentage=b,this.grid.queueRefresh())},c.prototype.adjustRows=function(a,b,c){var d=this,e=d.minRowsToRender(),f=d.visibleRowCache,g=f.length-e;"undefined"!=typeof b&&null!==b||!a||(b=a/d.getVerticalScrollLength());var h=Math.ceil(Math.min(g,g*b));h>g&&(h=g);var i=[];if(f.length>d.grid.options.virtualizationThreshold){if("undefined"!=typeof a&&null!==a){if(!d.grid.suppressParentScrollDown&&d.prevScrollToph)return;if(!d.grid.suppressParentScrollUp&&d.prevScrollTop>a&&h>d.prevRowScrollIndex-d.grid.options.scrollThreshold&&g>h)return}var j={},k={};j=Math.max(0,h-d.grid.options.excessRows),k=Math.min(f.length,h+e+d.grid.options.excessRows),i=[j,k]}else{var l=d.visibleRowCache.length;i=[0,Math.max(l,e+d.grid.options.excessRows)]}d.updateViewableRowRange(i),d.prevRowScrollIndex=h},c.prototype.adjustColumns=function(a,b){var c=this,d=c.minColumnsToRender(),e=c.visibleColumnCache,f=e.length-d;if(("undefined"==typeof b||null===b)&&a){var g=c.getCanvasWidth()-c.getViewportWidth();b=a/g}var h=Math.ceil(Math.min(f,f*b));h>f&&(h=f);var i=[];if(e.length>c.grid.options.columnVirtualizationThreshold&&c.getCanvasWidth()>c.getViewportWidth()){var j=Math.max(0,h-c.grid.options.excessColumns),k=Math.min(e.length,h+d+c.grid.options.excessColumns);i=[j,k]}else{var l=c.visibleColumnCache.length;i=[0,Math.max(l,d+c.grid.options.excessColumns)]}c.updateViewableColumnRange(i),c.prevColumnScrollIndex=h},c.prototype.updateViewableRowRange=function(a){var b=this.visibleRowCache.slice(a[0],a[1]);this.currentTopRow=a[0],this.setRenderedRows(b)},c.prototype.updateViewableColumnRange=function(a){var b=this.visibleColumnCache.slice(a[0],a[1]);this.currentFirstColumn=a[0],this.setRenderedColumns(b)},c.prototype.headerCellWrapperStyle=function(){var a=this;if(0!==a.currentFirstColumn){var b=a.columnOffset;return a.grid.isRTL()?{"margin-right":b+"px"}:{"margin-left":b+"px"}}return null},c.prototype.updateColumnWidths=function(){var b=this,c=[],d=0,e=0,f="",g=b.grid.getViewportWidth()-b.grid.scrollbarWidth,h=[];angular.forEach(b.grid.renderContainers,function(a,b){h=h.concat(a.visibleColumnCache)}),h.forEach(function(b,f){var h=0;b.visible&&(angular.isNumber(b.width)?(h=parseInt(b.width,10),e+=h,b.drawnWidth=h):a.endsWith(b.width,"%")?(h=parseInt(parseInt(b.width.replace(/%/g,""),10)/100*g),h>b.maxWidth&&(h=b.maxWidth),h0){var j=i/d;c.forEach(function(a){var b=parseInt(a.width.length*j,10);b>a.maxWidth&&(b=a.maxWidth),b0&&(a.drawnWidth++,e++,l--,m=!0)},l=g-e,m=!0;l>0&&m;)m=!1,c.forEach(k);var n=function(a){a.drawnWidth>a.minWidth&&o>0&&(a.drawnWidth--,e--,o--,m=!0)},o=e-g;for(m=!0;o>0&&m;)m=!1,c.forEach(n);var p=0;b.visibleColumnCache.forEach(function(a){a.visible&&(p+=a.drawnWidth)}),h.forEach(function(a){f+=a.getColClassDefinition()}),b.canvasWidth=p,this.columnStyles=f},c.prototype.needsHScrollbarPlaceholder=function(){return this.grid.options.enableHorizontalScrollbar&&!this.hasHScrollbar&&!this.grid.disableScrolling},c.prototype.getViewportStyle=function(){var a=this,c={};return a.hasHScrollbar=!1,a.hasVScrollbar=!1,a.grid.disableScrolling?(c["overflow-x"]="hidden",c["overflow-y"]="hidden",c):("body"===a.name?(a.hasHScrollbar=a.grid.options.enableHorizontalScrollbar!==b.scrollbars.NEVER,a.grid.isRTL()?a.grid.hasLeftContainerColumns()||(a.hasVScrollbar=a.grid.options.enableVerticalScrollbar!==b.scrollbars.NEVER):a.grid.hasRightContainerColumns()||(a.hasVScrollbar=a.grid.options.enableVerticalScrollbar!==b.scrollbars.NEVER)):"left"===a.name?a.hasVScrollbar=a.grid.isRTL()?a.grid.options.enableVerticalScrollbar!==b.scrollbars.NEVER:!1:a.hasVScrollbar=a.grid.isRTL()?!1:a.grid.options.enableVerticalScrollbar!==b.scrollbars.NEVER,c["overflow-x"]=a.hasHScrollbar?"scroll":"hidden",c["overflow-y"]=a.hasVScrollbar?"scroll":"hidden",c)},c}])}(),function(){angular.module("ui.grid").factory("GridRow",["gridUtil",function(a){function b(b,c,d){this.grid=d,this.entity=b,this.uid=a.nextUid(),this.visible=!0,this.$$height=d.options.rowHeight}return Object.defineProperty(b.prototype,"height",{get:function(){return this.$$height},set:function(a){a!==this.$$height&&(this.grid.updateCanvasHeight(),this.$$height=a)}}),b.prototype.getQualifiedColField=function(a){return"row."+this.getEntityQualifiedColField(a)},b.prototype.getEntityQualifiedColField=function(b){return a.preEval("entity."+b.field)},b.prototype.setRowInvisible=function(a){a&&a.setThisRowInvisible&&a.setThisRowInvisible("user")},b.prototype.clearRowInvisible=function(a){a&&a.clearThisRowInvisible&&a.clearThisRowInvisible("user")},b.prototype.setThisRowInvisible=function(a,b){this.invisibleReason||(this.invisibleReason={}),this.invisibleReason[a]=!0,this.evaluateRowVisibility(b)},b.prototype.clearThisRowInvisible=function(a,b){"undefined"!=typeof this.invisibleReason&&delete this.invisibleReason[a],this.evaluateRowVisibility(b)},b.prototype.evaluateRowVisibility=function(a){var b=!0;"undefined"!=typeof this.invisibleReason&&angular.forEach(this.invisibleReason,function(a,c){a&&(b=!1)}),("undefined"==typeof this.visible||this.visible!==b)&&(this.visible=b,a||(this.grid.queueGridRefresh(),this.grid.api.core.raise.rowsVisibleChanged(this)))},b}])}(),function(){"use strict";angular.module("ui.grid").factory("GridRowColumn",["$parse","$filter",function(a,b){var c=function d(a,b){if(!(this instanceof d))throw"Using GridRowColumn as a function insead of as a constructor. Must be called with `new` keyword";this.row=a,this.col=b};return c.prototype.getIntersectionValueRaw=function(){var b=a(this.row.getEntityQualifiedColField(this.col)),c=this.row;return b(c)},c.prototype.getIntersectionValueFiltered=function(){var a=this.getIntersectionValueRaw();if(this.col.cellFilter&&""!==this.col.cellFilter){var c=function(a){try{return b(a)}catch(c){return null}},d=c(this.col.cellFilter);if(d)a=d(a);else{var e,f=/([^:]*):([^:]*):?([\s\S]+)?/;null!==(e=f.exec(this.col.cellFilter))&&(a=b(e[1])(a,e[2],e[3]))}}return a},c}])}(),function(){angular.module("ui.grid").factory("ScrollEvent",["gridUtil",function(a){function b(b,c,d,e){var f=this;if(!b)throw new Error("grid argument is required");f.grid=b,f.source=e,f.withDelay=!0,f.sourceRowContainer=c,f.sourceColContainer=d,f.newScrollLeft=null,f.newScrollTop=null,f.x=null,f.y=null,f.verticalScrollLength=-9999999,f.horizontalScrollLength=-999999,f.fireThrottledScrollingEvent=a.throttle(function(a){f.grid.scrollContainers(a,f)},f.grid.options.wheelScrollThrottle,{trailing:!0})}return b.prototype.getNewScrollLeft=function(b,c){var d=this;if(!d.newScrollLeft){var e,f=b.getCanvasWidth()-b.getViewportWidth(),g=a.normalizeScrollLeft(c,d.grid);if("undefined"!=typeof d.x.percentage&&void 0!==d.x.percentage)e=d.x.percentage;else{if("undefined"==typeof d.x.pixels||void 0===d.x.pixels)throw new Error("No percentage or pixel value provided for scroll event X axis");e=d.x.percentage=(g+d.x.pixels)/f}return Math.max(0,e*f)}return d.newScrollLeft},b.prototype.getNewScrollTop=function(a,b){var c=this;if(!c.newScrollTop){var d,e=a.getVerticalScrollLength(),f=b[0].scrollTop;if("undefined"!=typeof c.y.percentage&&void 0!==c.y.percentage)d=c.y.percentage;else{if("undefined"==typeof c.y.pixels||void 0===c.y.pixels)throw new Error("No percentage or pixel value provided for scroll event Y axis");d=c.y.percentage=(f+c.y.pixels)/e}return Math.max(0,d*e)}return c.newScrollTop},b.prototype.atTop=function(a){return this.y&&(0===this.y.percentage||this.verticalScrollLength<0)&&0===a},b.prototype.atBottom=function(a){return this.y&&(1===this.y.percentage||0===this.verticalScrollLength)&&a>0},b.prototype.atLeft=function(a){return this.x&&(0===this.x.percentage||this.horizontalScrollLength<0)&&0===a},b.prototype.atRight=function(a){return this.x&&(1===this.x.percentage||0===this.horizontalScrollLength)&&a>0},b.Sources={ViewPortScroll:"ViewPortScroll",RenderContainerMouseWheel:"RenderContainerMouseWheel",RenderContainerTouchMove:"RenderContainerTouchMove",Other:99},b}])}(),function(){"use strict";angular.module("ui.grid").service("gridClassFactory",["gridUtil","$q","$compile","$templateCache","uiGridConstants","Grid","GridColumn","GridRow",function(a,b,c,d,e,f,g,h){var i={createGrid:function(d){d="undefined"!=typeof d?d:{},d.id=a.newId();var e=new f(d);if(e.options.rowTemplate){var g=b.defer();e.getRowTemplateFn=g.promise,a.getTemplate(e.options.rowTemplate).then(function(a){var b=c(a);g.resolve(b)},function(a){throw new Error("Couldn't fetch/use row template '"+e.options.rowTemplate+"'")})}return e.registerColumnBuilder(i.defaultColumnBuilder),e.registerRowBuilder(i.rowTemplateAssigner),e.registerRowsProcessor(function(a){return a.forEach(function(a){a.evaluateRowVisibility(!0)},50),a}),e.registerColumnsProcessor(function(a){return a.forEach(function(a){a.visible=!0}),a},50),e.registerColumnsProcessor(function(a){return a.forEach(function(a){a.colDef.visible===!1&&(a.visible=!1)}),a},50),e.registerRowsProcessor(e.searchRows,100),e.options.externalSort&&angular.isFunction(e.options.externalSort)?e.registerRowsProcessor(e.options.externalSort,200):e.registerRowsProcessor(e.sortByColumn,200),e},defaultColumnBuilder:function(c,d,f){var g=[],h=function(b,f,h,i,j){c[b]?d[f]=c[b]:d[f]=h,g.push(a.getTemplate(d[f]).then(function(a){angular.isFunction(a)&&(a=a());var c="cellTooltip"===j?"col.cellTooltip(row,col)":"col.headerTooltip(col)";j&&d[j]===!1?a=a.replace(e.TOOLTIP,""):j&&d[j]&&(a=a.replace(e.TOOLTIP,'title="{{'+c+' CUSTOM_FILTERS }}"')),i?d[b]=a.replace(e.CUSTOM_FILTERS,function(){return d[i]?"|"+d[i]:""}):d[b]=a},function(a){throw new Error("Couldn't fetch/use colDef."+b+" '"+c[b]+"'")}))};return h("cellTemplate","providedCellTemplate","ui-grid/uiGridCell","cellFilter","cellTooltip"),d.cellTemplatePromise=g[0],h("headerCellTemplate","providedHeaderCellTemplate","ui-grid/uiGridHeaderCell","headerCellFilter","headerTooltip"),h("footerCellTemplate","providedFooterCellTemplate","ui-grid/uiGridFooterCell","footerCellFilter"),h("filterHeaderTemplate","providedFilterHeaderTemplate","ui-grid/ui-grid-filter"),d.compiledElementFnDefer=b.defer(),b.all(g)},rowTemplateAssigner:function(d){var e=this;if(d.rowTemplate){var f=b.defer();d.getRowTemplateFn=f.promise,a.getTemplate(d.rowTemplate).then(function(a){var b=c(a);f.resolve(b)},function(a){throw new Error("Couldn't fetch/use row template '"+d.rowTemplate+"'")})}else d.rowTemplate=e.options.rowTemplate,d.getRowTemplateFn=e.getRowTemplateFn;return d.getRowTemplateFn}};return i}])}(),function(){function a(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}var b=angular.module("ui.grid");b.service("rowSearcher",["gridUtil","uiGridConstants",function(b,c){var d=c.filter.CONTAINS,e={};return e.getTerm=function(a){if("undefined"==typeof a.term)return a.term;var b=a.term;return"string"==typeof b&&(b=b.trim()),b},e.stripTerm=function(b){var c=e.getTerm(b);return"string"==typeof c?a(c.replace(/(^\*|\*$)/g,"")):c},e.guessCondition=function(a){if("undefined"==typeof a.term||!a.term)return d;var b=e.getTerm(a);if(/\*/.test(b)){var c="";a.flags&&a.flags.caseSensitive||(c+="i");var f=b.replace(/(\\)?\*/g,function(a,b){return b?a:"[\\s\\S]*?"});return new RegExp("^"+f+"$",c)}return d},e.setupFilters=function(a){for(var d=[],f=a.length,g=0;f>g;g++){var h=a[g];if(h.noTerm||!b.isNullOrUndefined(h.term)){var i={},j="";h.flags&&h.flags.caseSensitive||(j+="i"),b.isNullOrUndefined(h.term)||(i.term=e.stripTerm(h)),h.condition?i.condition=h.condition:i.condition=e.guessCondition(h),i.flags=angular.extend({caseSensitive:!1,date:!1},h.flags),i.condition===c.filter.STARTS_WITH&&(i.startswithRE=new RegExp("^"+i.term,j)),i.condition===c.filter.ENDS_WITH&&(i.endswithRE=new RegExp(i.term+"$",j)),i.condition===c.filter.CONTAINS&&(i.containsRE=new RegExp(i.term,j)),i.condition===c.filter.EXACT&&(i.exactRE=new RegExp("^"+i.term+"$",j)),d.push(i)}}return d},e.runColumnFilter=function(a,b,d,e){var f,g=typeof e.condition,h=e.term;if(f=d.filterCellFiltered?a.getCellDisplayValue(b,d):a.getCellValue(b,d),e.condition instanceof RegExp)return e.condition.test(f);if("function"===g)return e.condition(h,f,b,d);if(e.startswithRE)return e.startswithRE.test(f);if(e.endswithRE)return e.endswithRE.test(f);if(e.containsRE)return e.containsRE.test(f);if(e.exactRE)return e.exactRE.test(f);if(e.condition===c.filter.NOT_EQUAL){var i=new RegExp("^"+h+"$");return!i.exec(f)}if("number"==typeof f&&"string"==typeof h){var j=parseFloat(h.replace(/\\\./,".").replace(/\\\-/,"-"));isNaN(j)||(h=j)}return e.flags.date===!0&&(f=new Date(f),h=new Date(h.replace(/\\/g,""))),e.condition===c.filter.GREATER_THAN?f>h:e.condition===c.filter.GREATER_THAN_OR_EQUAL?f>=h:e.condition===c.filter.LESS_THAN?h>f:e.condition===c.filter.LESS_THAN_OR_EQUAL?h>=f:!0},e.searchColumn=function(a,b,c,d){if(a.options.useExternalFiltering)return!0;for(var f=d.length,g=0;f>g;g++){var h=d[g],i=e.runColumnFilter(a,b,c,h);if(!i)return!1}return!0},e.search=function(a,c,d){if(c){if(!a.options.enableFiltering)return c;for(var f=[],g=d.length,h=function(a){var c=!1;return a.forEach(function(a){(!b.isNullOrUndefined(a.term)&&""!==a.term||a.noTerm)&&(c=!0)}),c},i=0;g>i;i++){var j=d[i];"undefined"!=typeof j.filters&&h(j.filters)&&f.push({col:j,filters:e.setupFilters(j.filters)})}if(f.length>0){for(var k=function(a,b,c,d){b.visible&&!e.searchColumn(a,b,c,d)&&(b.visible=!1)},l=function(a,b){for(var d=c.length,e=0;d>e;e++)k(a,c[e],b.col,b.filters)},m=f.length,n=0;m>n;n++)l(a,f[n]);a.api.core.raise.rowsVisibleChanged&&a.api.core.raise.rowsVisibleChanged()}return c}},e}])}(),function(){var a=angular.module("ui.grid");a.service("rowSorter",["$parse","uiGridConstants",function(a,b){var c="("+b.CURRENCY_SYMBOLS.map(function(a){return"\\"+a}).join("|")+")?",d=(new RegExp("^[-+]?"+c+"[\\d,.]+"+c+"%?$"),{colSortFnCache:{}});return d.guessSortFn=function(a){switch(a){case"number":return d.sortNumber;case"numberStr":return d.sortNumberStr;case"boolean":return d.sortBool;case"string":return d.sortAlpha;case"date":return d.sortDate;case"object":return d.basicSort;default:throw new Error("No sorting function found for type:"+a)}},d.handleNulls=function(a,b){if(!a&&0!==a&&a!==!1||!b&&0!==b&&b!==!1){if(!a&&0!==a&&a!==!1&&!b&&0!==b&&b!==!1)return 0;if(!a&&0!==a&&a!==!1)return 1;if(!b&&0!==b&&b!==!1)return-1}return null},d.basicSort=function(a,b){var c=d.handleNulls(a,b);return null!==c?c:a===b?0:b>a?-1:1},d.sortNumber=function(a,b){var c=d.handleNulls(a,b);return null!==c?c:a-b},d.sortNumberStr=function(a,b){var c=d.handleNulls(a,b);if(null!==c)return c;var e,f,g=!1,h=!1;return e=parseFloat(a.replace(/[^0-9.-]/g,"")),isNaN(e)&&(g=!0),f=parseFloat(b.replace(/[^0-9.-]/g,"")),isNaN(f)&&(h=!0),g&&h?0:g?1:h?-1:e-f},d.sortAlpha=function(a,b){var c=d.handleNulls(a,b);if(null!==c)return c;var e=a.toString().toLowerCase(),f=b.toString().toLowerCase();return e===f?0:e.localeCompare(f)},d.sortDate=function(a,b){var c=d.handleNulls(a,b);if(null!==c)return c;a instanceof Date||(a=new Date(a)),b instanceof Date||(b=new Date(b));var e=a.getTime(),f=b.getTime();return e===f?0:f>e?-1:1},d.sortBool=function(a,b){var c=d.handleNulls(a,b);return null!==c?c:a&&b?0:a||b?a?1:-1:0},d.getSortFn=function(a,b,c){var e;return d.colSortFnCache[b.colDef.name]?e=d.colSortFnCache[b.colDef.name]:void 0!==b.sortingAlgorithm?(e=b.sortingAlgorithm,d.colSortFnCache[b.colDef.name]=b.sortingAlgorithm):b.sortCellFiltered&&b.cellFilter?(e=d.sortAlpha,d.colSortFnCache[b.colDef.name]=e):(e=d.guessSortFn(b.colDef.type),e?d.colSortFnCache[b.colDef.name]=e:e=d.sortAlpha),e},d.prioritySort=function(a,b){return void 0!==a.sort.priority&&void 0!==b.sort.priority?a.sort.priorityf;f+=2){var i=h[f];if("margin"===c){var j=parseFloat(e[c+i]);isNaN(j)||(g+=j)}if(d){if("content"===c){var k=parseFloat(e["padding"+i]);isNaN(k)||(g-=k)}if("margin"!==c){var l=parseFloat(e["border"+i+"Width"]);isNaN(l)||(g-=l)}}else{var m=parseFloat(e["padding"+i]);if(isNaN(m)||(g+=m),"padding"!==c){var n=parseFloat(e["border"+i+"Width"]);isNaN(n)||(g+=n); -}}}return g}function c(c,d,e){var f,h=!0,i=a(c),j="border-box"===i.boxSizing;if(0>=f||null==f){if(f=i[d],(0>f||null==f)&&(f=c.style[d]),g.test(f))return f;h=j&&!0,f=parseFloat(f)||0}var k=f+b(c,d,e||(j?"border":"content"),h,i);return k}function d(b){b=angular.element(b)[0];var c=b.parentElement;return c||(c=document.getElementsByTagName("body")[0]),parseInt(a(c).fontSize)||parseInt(a(b).fontSize)||16}var e,f=angular.module("ui.grid");"function"!=typeof Function.prototype.bind&&(e=function(){var a=Array.prototype.slice;return function(b){var c=this,d=a.call(arguments,1);return d.length?function(){return arguments.length?c.apply(b,d.concat(a.call(arguments))):c.apply(b,d)}:function(){return arguments.length?c.apply(b,arguments):c.call(b)}}});var g=new RegExp("^("+/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source+")(?!px)[a-z%]+$","i"),h=/^(block|none|table(?!-c[ea]).+)/,i={position:"absolute",visibility:"hidden",display:"block"},j=["0","0","0","0"],k="uiGrid-";f.service("gridUtil",["$log","$window","$document","$http","$templateCache","$timeout","$interval","$injector","$q","$interpolate","uiGridConstants",function(f,g,l,m,n,o,p,q,r,s,t){function u(a,b){var c=angular.element(this),d=0,e=0,f=0,g=0;if(b.originalEvent&&(b=b.originalEvent),"detail"in b&&(f=-1*b.detail),"wheelDelta"in b&&(f=b.wheelDelta),"wheelDeltaY"in b&&(f=b.wheelDeltaY),"wheelDeltaX"in b&&(e=-1*b.wheelDeltaX),"axis"in b&&b.axis===b.HORIZONTAL_AXIS&&(e=-1*f,f=0),d=0===f?e:f,"deltaY"in b&&(f=-1*b.deltaY,d=f),"deltaX"in b&&(e=b.deltaX,0===f&&(d=-1*e)),0!==f||0!==e){if(1===b.deltaMode){var h=c.data("mousewheel-line-height");d*=h,f*=h,e*=h}else if(2===b.deltaMode){var i=c.data("mousewheel-page-height");d*=i,f*=i,e*=i}g=Math.max(Math.abs(f),Math.abs(e)),(!z||z>g)&&(z=g,w(b,g)&&(z/=40)),d=Math[d>=1?"floor":"ceil"](d/z),e=Math[e>=1?"floor":"ceil"](e/z),f=Math[f>=1?"floor":"ceil"](f/z),b.deltaMode=0;var j={originalEvent:b,deltaX:e,deltaY:f,deltaFactor:z,preventDefault:function(){b.preventDefault()},stopPropagation:function(){b.stopPropagation()}};y&&clearTimeout(y),y=setTimeout(v,200),a.call(c[0],j)}}function v(){z=null}function w(a,b){return"mousewheel"===a.type&&b%120===0}var x={augmentWidthOrHeight:b,getStyles:a,createBoundedWrapper:function(a,b){return function(){return b.apply(a,arguments)}},readableColumnName:function(a){return"undefined"==typeof a||void 0===a||null===a?a:("string"!=typeof a&&(a=String(a)),a.replace(/_+/g," ").replace(/^[A-Z]+$/,function(a){return angular.lowercase(angular.uppercase(a.charAt(0))+a.slice(1))}).replace(/([\w\u00C0-\u017F]+)/g,function(a){return angular.uppercase(a.charAt(0))+a.slice(1)}).replace(/(\w+?(?=[A-Z]))/g,"$1 "))},getColumnsFromData:function(a,b){var c=[];if(!a||"undefined"==typeof a[0]||void 0===a[0])return[];angular.isUndefined(b)&&(b=[]);var d=a[0];return angular.forEach(d,function(a,d){-1===b.indexOf(d)&&c.push({name:d})}),c},newId:function(){var a=(new Date).getTime();return function(){return a+=1}}(),getTemplate:function(a){if(n.get(a))return x.postProcessTemplate(n.get(a));if(a.hasOwnProperty("then"))return a.then(x.postProcessTemplate);try{if(angular.element(a).length>0)return r.when(a).then(x.postProcessTemplate)}catch(b){}return x.logDebug("fetching url",a),m({method:"GET",url:a}).then(function(b){var c=b.data.trim();return n.put(a,c),c},function(b){throw new Error("Could not get template "+a+": "+b)}).then(x.postProcessTemplate)},postProcessTemplate:function(a){var b=s.startSymbol(),c=s.endSymbol();return("{{"!==b||"}}"!==c)&&(a=a.replace(/\{\{/g,b),a=a.replace(/\}\}/g,c)),r.when(a)},guessType:function(a){var b=typeof a;switch(b){case"number":case"boolean":case"string":return b;default:return angular.isDate(a)?"date":"object"}},elementWidth:function(a){},elementHeight:function(a){},getScrollbarWidth:function(){var a=document.createElement("div");a.style.visibility="hidden",a.style.width="100px",a.style.msOverflowStyle="scrollbar",document.body.appendChild(a);var b=a.offsetWidth;a.style.overflow="scroll";var c=document.createElement("div");c.style.width="100%",a.appendChild(c);var d=c.offsetWidth;return a.parentNode.removeChild(a),b-d},swap:function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},fakeElement:function(a,b,c,d){var e,f,g=angular.element(a).clone()[0];for(f in b)g.style[f]=b[f];return angular.element(document.body).append(g),e=c.call(g,g),angular.element(g).remove(),e},normalizeWheelEvent:function(a){var b,c,d,e=a||window.event,f=([].slice.call(arguments,1),0),g=0,h=0,i=0,j=0;return e.originalEvent&&(e=e.originalEvent),e.wheelDelta&&(f=e.wheelDelta),e.detail&&(f=-1*e.detail),h=f,void 0!==e.axis&&e.axis===e.HORIZONTAL_AXIS&&(h=0,g=-1*f),e.deltaY&&(h=-1*e.deltaY,f=h),e.deltaX&&(g=e.deltaX,f=-1*g),void 0!==e.wheelDeltaY&&(h=e.wheelDeltaY),void 0!==e.wheelDeltaX&&(g=e.wheelDeltaX),i=Math.abs(f),(!b||b>i)&&(b=i),j=Math.max(Math.abs(h),Math.abs(g)),(!c||c>j)&&(c=j),d=f>0?"floor":"ceil",f=Math[d](f/b),g=Math[d](g/c),h=Math[d](h/c),{delta:f,deltaX:g,deltaY:h}},isTouchEnabled:function(){var a;return("ontouchstart"in g||g.DocumentTouch&&l instanceof DocumentTouch)&&(a=!0),a},isNullOrUndefined:function(a){return void 0===a||null===a?!0:!1},endsWith:function(a,b){return a&&b&&"string"==typeof a?-1!==a.indexOf(b,a.length-b.length):!1},arrayContainsObjectWithProperty:function(a,b,c){var d=!1;return angular.forEach(a,function(a){a[b]===c&&(d=!0)}),d},numericAndNullSort:function(a,b){return null===a?1:null===b?-1:null===a&&null===b?0:a-b},disableAnimations:function(a){var b;try{b=q.get("$animate"),angular.version.major>1||1===angular.version.major&&angular.version.minor>=4?b.enabled(a,!1):b.enabled(!1,a)}catch(c){}},enableAnimations:function(a){var b;try{return b=q.get("$animate"),angular.version.major>1||1===angular.version.major&&angular.version.minor>=4?b.enabled(a,!0):b.enabled(!0,a),b}catch(c){}},nextUid:function(){for(var a,b=j.length;b;){if(b--,a=j[b].charCodeAt(0),57===a)return j[b]="A",k+j.join("");if(90!==a)return j[b]=String.fromCharCode(a+1),k+j.join("");j[b]="0"}return j.unshift("0"),k+j.join("")},hashKey:function(a){var b,c=typeof a;return"object"===c&&null!==a?"function"==typeof(b=a.$$hashKey)?b=a.$$hashKey():"undefined"!=typeof a.$$hashKey&&a.$$hashKey?b=a.$$hashKey:void 0===b&&(b=a.$$hashKey=x.nextUid()):b=a,c+":"+b},resetUids:function(){j=["0","0","0"]},logError:function(a){t.LOG_ERROR_MESSAGES&&f.error(a)},logWarn:function(a){t.LOG_WARN_MESSAGES&&f.warn(a)},logDebug:function(){t.LOG_DEBUG_MESSAGES&&f.debug.apply(f,arguments)}};x.focus={queue:[],byId:function(a,b){this._purgeQueue();var c=o(function(){var c=(b&&b.id?b.id+"-":"")+a,d=g.document.getElementById(c);d?d.focus():x.logWarn("[focus.byId] Element id "+c+" was not found.")});return this.queue.push(c),c},byElement:function(a){if(!angular.isElement(a))return x.logWarn("Trying to focus on an element that isn't an element."),r.reject("not-element");a=angular.element(a),this._purgeQueue();var b=o(function(){a&&a[0].focus()});return this.queue.push(b),b},bySelector:function(a,b,c){var d=this;if(!angular.isElement(a))throw new Error("The parent element is not an element.");a=angular.element(a);var e=function(){var c=a[0].querySelector(b);return d.byElement(c)};if(this._purgeQueue(),c){var f=o(e);return this.queue.push(o(e)),f}return e()},_purgeQueue:function(){this.queue.forEach(function(a){o.cancel(a)}),this.queue=[]}},["width","height"].forEach(function(b){var d=angular.uppercase(b.charAt(0))+b.substr(1);x["element"+d]=function(d,e){var f=d;if(f&&"undefined"!=typeof f.length&&f.length&&(f=d[0]),f){var g=a(f);return 0===f.offsetWidth&&h.test(g.display)?x.swap(f,i,function(){return c(f,b,e)}):c(f,b,e)}return null},x["outerElement"+d]=function(a,b){return a?x["element"+d].call(this,a,b?"margin":"border"):null}}),x.closestElm=function(a,b){"undefined"!=typeof a.length&&a.length&&(a=a[0]);var c;["matches","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector"].some(function(a){return"function"==typeof document.body[a]?(c=a,!0):!1});for(var d;null!==a;){if(d=a.parentElement,null!==d&&d[c](b))return d;a=d}return null},x.type=function(a){var b=Function.prototype.toString.call(a.constructor);return b.match(/function (.*?)\(/)[1]},x.getBorderSize=function(b,c){"undefined"!=typeof b.length&&b.length&&(b=b[0]);var d=a(b);c=c?"border"+c.charAt(0).toUpperCase()+c.slice(1):"border",c+="Width";var e=parseInt(d[c],10);return isNaN(e)?0:e},x.detectBrowser=function(){var a=g.navigator.userAgent,b={chrome:/chrome/i,safari:/safari/i,firefox:/firefox/i,ie:/internet explorer|trident\//i};for(var c in b)if(b[c].test(a))return c;return"unknown"},x.rtlScrollType=function B(){if(B.type)return B.type;var a=angular.element('
A
')[0],b="reverse";return document.body.appendChild(a),a.scrollLeft>0?b="default":(a.scrollLeft=1,0===a.scrollLeft&&(b="negative")),angular.element(a).remove(),B.type=b,b},x.normalizeScrollLeft=function(a,b){"undefined"!=typeof a.length&&a.length&&(a=a[0]);var c=a.scrollLeft;if(b.isRTL())switch(x.rtlScrollType()){case"default":return a.scrollWidth-c-a.clientWidth;case"negative":return Math.abs(c);case"reverse":return c}return c},x.denormalizeScrollLeft=function(a,b,c){if("undefined"!=typeof a.length&&a.length&&(a=a[0]),c.isRTL())switch(x.rtlScrollType()){case"default":var d=a.scrollWidth-a.clientWidth;return d-b;case"negative":return-1*b;case"reverse":return b}return b},x.preEval=function(a){var b=t.BRACKET_REGEXP.exec(a);if(b)return(b[1]?x.preEval(b[1]):b[1])+b[2]+(b[3]?x.preEval(b[3]):b[3]);a=a.replace(t.APOS_REGEXP,"\\'");var c=a.split(t.DOT_REGEXP),d=[c.shift()];return angular.forEach(c,function(a){d.push(a.replace(t.FUNC_REGEXP,"']$1"))}),d.join("['")},x.debounce=function(a,b,c){function d(){g=this,f=arguments;var d=function(){e=null,c||(h=a.apply(g,f))},i=c&&!e;return e&&o.cancel(e),e=o(d,b,!1),i&&(h=a.apply(g,f)),h}var e,f,g,h;return d.cancel=function(){o.cancel(e),e=null},d},x.throttle=function(a,b,c){function d(b){g=+new Date,a.apply(e,f),p(function(){h=null},0,1,!1)}c=c||{};var e,f,g=0,h=null;return function(){if(e=this,f=arguments,null===h){var a=+new Date-g;a>b?d():c.trailing&&(h=p(d,b-a,1,!1))}}},x.on={},x.off={},x._events={},x.addOff=function(a){x.off[a]=function(b,c){var d=x._events[a].indexOf(c);d>0&&x._events[a].removeAt(d)}};var y,z,A="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"];return x.on.mousewheel=function(a,b){if(a&&b){var c=angular.element(a);c.data("mousewheel-line-height",d(c)),c.data("mousewheel-page-height",x.elementHeight(c)),c.data("mousewheel-callbacks")||c.data("mousewheel-callbacks",{});var f=c.data("mousewheel-callbacks");f[b]=(Function.prototype.bind||e).call(u,c[0],b);for(var g=A.length;g;)c.on(A[--g],f[b])}},x.off.mousewheel=function(a,b){var c=angular.element(a),d=c.data("mousewheel-callbacks"),e=d[b];if(e)for(var f=A.length;f;)c.off(A[--f],e);delete d[b],0===Object.keys(d).length&&(c.removeData("mousewheel-line-height"),c.removeData("mousewheel-page-height"),c.removeData("mousewheel-callbacks"))},x}]),f.filter("px",function(){return function(a){return a.match(/^[\d\.]+$/)?a+"px":a}})}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){var b={aggregate:{label:"položky"},groupPanel:{description:"Přesuňte záhlaví zde pro vytvoření skupiny dle sloupce."},search:{placeholder:"Hledat...",showingItems:"Zobrazuji položky:",selectedItems:"Vybrané položky:",totalItems:"Celkem položek:",size:"Velikost strany:",first:"První strana",next:"Další strana",previous:"Předchozí strana",last:"Poslední strana"},menu:{text:"Vyberte sloupec:"},sort:{ascending:"Seřadit od A-Z",descending:"Seřadit od Z-A",remove:"Odebrat seřazení"},column:{hide:"Schovat sloupec"},aggregation:{count:"celkem řádků: ",sum:"celkem: ",avg:"avg: ",min:"min.: ",max:"max.: "},pinning:{pinLeft:"Zamknout vlevo",pinRight:"Zamknout vpravo",unpin:"Odemknout"},gridMenu:{columns:"Sloupce:",importerTitle:"Importovat soubor",exporterAllAsCsv:"Exportovat všechna data do csv",exporterVisibleAsCsv:"Exportovat viditelná data do csv",exporterSelectedAsCsv:"Exportovat vybraná data do csv",exporterAllAsPdf:"Exportovat všechna data do pdf",exporterVisibleAsPdf:"Exportovat viditelná data do pdf",exporterSelectedAsPdf:"Exportovat vybraná data do pdf",clearAllFilters:"Odstranit všechny filtry"},importer:{noHeaders:"Názvy sloupců se nepodařilo získat, obsahuje soubor záhlaví?",noObjects:"Data se nepodařilo zpracovat, obsahuje soubor řádky mimo záhlaví?",invalidCsv:"Soubor nelze zpracovat, jedná se o CSV?",invalidJson:"Soubor nelze zpracovat, je to JSON?",jsonNotArray:"Soubor musí obsahovat json. Ukončuji.."},pagination:{sizes:"položek na stránku",totalItems:"položek"},grouping:{group:"Seskupit",ungroup:"Odebrat seskupení",aggregate_count:"Agregace: Count",aggregate_sum:"Agregace: Sum",aggregate_max:"Agregace: Max",aggregate_min:"Agregace: Min",aggregate_avg:"Agregace: Avg",aggregate_remove:"Agregace: Odebrat"}};return a.add("cs",b),a.add("cz",b),a.add("cs-cz",b),a.add("cs-CZ",b),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("da",{aggregate:{label:"artikler"},groupPanel:{description:"Grupér rækker udfra en kolonne ved at trække dens overskift hertil."},search:{placeholder:"Søg...",showingItems:"Viste rækker:",selectedItems:"Valgte rækker:",totalItems:"Rækker totalt:",size:"Side størrelse:",first:"Første side",next:"Næste side",previous:"Forrige side",last:"Sidste side"},menu:{text:"Vælg kolonner:"},sort:{ascending:"Sorter stigende",descending:"Sorter faldende",none:"Sorter ingen",remove:"Fjern sortering"},column:{hide:"Skjul kolonne"},aggregation:{count:"antal rækker: ",sum:"sum: ",avg:"gns: ",min:"min: ",max:"max: "},gridMenu:{columns:"Columns:",importerTitle:"Import file",exporterAllAsCsv:"Export all data as csv",exporterVisibleAsCsv:"Export visible data as csv",exporterSelectedAsCsv:"Export selected data as csv",exporterAllAsPdf:"Export all data as pdf",exporterVisibleAsPdf:"Export visible data as pdf",exporterSelectedAsPdf:"Export selected data as pdf",clearAllFilters:"Clear all filters"},importer:{noHeaders:"Column names were unable to be derived, does the file have a header?",noObjects:"Objects were not able to be derived, was there data in the file other than headers?",invalidCsv:"File was unable to be processed, is it valid CSV?",invalidJson:"File was unable to be processed, is it valid Json?",jsonNotArray:"Imported json file must contain an array, aborting."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("de",{headerCell:{aria:{defaultFilterLabel:"Filter für Spalte",removeFilter:"Filter löschen",columnMenuButtonLabel:"Spaltenmenü"},priority:"Priorität:",filterLabel:"Filter für Spalte: "},aggregate:{label:"Eintrag"},groupPanel:{description:"Ziehen Sie eine Spaltenüberschrift hierhin, um nach dieser Spalte zu gruppieren."},search:{placeholder:"Suche...",showingItems:"Zeige Einträge:",selectedItems:"Ausgewählte Einträge:",totalItems:"Einträge gesamt:",size:"Einträge pro Seite:",first:"Erste Seite",next:"Nächste Seite",previous:"Vorherige Seite",last:"Letzte Seite"},menu:{text:"Spalten auswählen:"},sort:{ascending:"aufsteigend sortieren",descending:"absteigend sortieren",none:"keine Sortierung",remove:"Sortierung zurücksetzen"},column:{hide:"Spalte ausblenden"},aggregation:{count:"Zeilen insgesamt: ",sum:"gesamt: ",avg:"Durchschnitt: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Links anheften",pinRight:"Rechts anheften",unpin:"Lösen"},columnMenu:{close:"Schließen"},gridMenu:{aria:{buttonLabel:"Tabellenmenü"},columns:"Spalten:",importerTitle:"Datei importieren",exporterAllAsCsv:"Alle Daten als CSV exportieren",exporterVisibleAsCsv:"sichtbare Daten als CSV exportieren",exporterSelectedAsCsv:"markierte Daten als CSV exportieren",exporterAllAsPdf:"Alle Daten als PDF exportieren",exporterVisibleAsPdf:"sichtbare Daten als PDF exportieren",exporterSelectedAsPdf:"markierte Daten als CSV exportieren",clearAllFilters:"Alle Filter zurücksetzen"},importer:{noHeaders:"Es konnten keine Spaltennamen ermittelt werden. Sind in der Datei Spaltendefinitionen enthalten?",noObjects:"Es konnten keine Zeileninformationen gelesen werden, Sind in der Datei außer den Spaltendefinitionen auch Daten enthalten?",invalidCsv:"Die Datei konnte nicht eingelesen werden, ist es eine gültige CSV-Datei?",invalidJson:"Die Datei konnte nicht eingelesen werden. Enthält sie gültiges JSON?",jsonNotArray:"Die importierte JSON-Datei muß ein Array enthalten. Breche Import ab."},pagination:{aria:{pageToFirst:"Zum Anfang",pageBack:"Seite zurück",pageSelected:"Ausgwählte Seite",pageForward:"Seite vor",pageToLast:"Zum Ende"},sizes:"Einträge pro Seite",totalItems:"Einträge",through:"bis",of:"von"},grouping:{group:"Gruppieren",ungroup:"Gruppierung aufheben",aggregate_count:"Agg: Anzahl",aggregate_sum:"Agg: Summe",aggregate_max:"Agg: Maximum",aggregate_min:"Agg: Minimum",aggregate_avg:"Agg: Mittelwert",aggregate_remove:"Aggregation entfernen"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("en",{headerCell:{aria:{defaultFilterLabel:"Filter for column",removeFilter:"Remove Filter",columnMenuButtonLabel:"Column Menu"},priority:"Priority:",filterLabel:"Filter for column: "},aggregate:{label:"items"},groupPanel:{description:"Drag a column header here and drop it to group by that column."},search:{placeholder:"Search...",showingItems:"Showing Items:",selectedItems:"Selected Items:",totalItems:"Total Items:",size:"Page Size:",first:"First Page",next:"Next Page",previous:"Previous Page",last:"Last Page"},menu:{text:"Choose Columns:"},sort:{ascending:"Sort Ascending",descending:"Sort Descending",none:"Sort None",remove:"Remove Sort"},column:{hide:"Hide Column"},aggregation:{count:"total rows: ",sum:"total: ",avg:"avg: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Pin Left",pinRight:"Pin Right",unpin:"Unpin"},columnMenu:{close:"Close"},gridMenu:{aria:{buttonLabel:"Grid Menu"},columns:"Columns:",importerTitle:"Import file",exporterAllAsCsv:"Export all data as csv",exporterVisibleAsCsv:"Export visible data as csv",exporterSelectedAsCsv:"Export selected data as csv",exporterAllAsPdf:"Export all data as pdf",exporterVisibleAsPdf:"Export visible data as pdf",exporterSelectedAsPdf:"Export selected data as pdf",clearAllFilters:"Clear all filters"},importer:{noHeaders:"Column names were unable to be derived, does the file have a header?",noObjects:"Objects were not able to be derived, was there data in the file other than headers?",invalidCsv:"File was unable to be processed, is it valid CSV?",invalidJson:"File was unable to be processed, is it valid Json?",jsonNotArray:"Imported json file must contain an array, aborting."},pagination:{aria:{pageToFirst:"Page to first",pageBack:"Page back",pageSelected:"Selected page",pageForward:"Page forward",pageToLast:"Page to last"},sizes:"items per page",totalItems:"items",through:"through",of:"of"},grouping:{group:"Group",ungroup:"Ungroup",aggregate_count:"Agg: Count",aggregate_sum:"Agg: Sum",aggregate_max:"Agg: Max",aggregate_min:"Agg: Min",aggregate_avg:"Agg: Avg",aggregate_remove:"Agg: Remove"},validate:{error:"Error:",minLength:"Value should be at least THRESHOLD characters long.",maxLength:"Value should be at most THRESHOLD characters long.",required:"A value is needed."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("es",{aggregate:{label:"Artículos"},groupPanel:{description:"Arrastre un encabezado de columna aquí y suéltelo para agrupar por esa columna."},search:{placeholder:"Buscar...",showingItems:"Artículos Mostrados:",selectedItems:"Artículos Seleccionados:",totalItems:"Artículos Totales:",size:"Tamaño de Página:",first:"Primera Página",next:"Página Siguiente",previous:"Página Anterior",last:"Última Página"},menu:{text:"Elegir columnas:"},sort:{ascending:"Orden Ascendente",descending:"Orden Descendente",remove:"Sin Ordenar"},column:{hide:"Ocultar la columna"},aggregation:{count:"filas totales: ",sum:"total: ",avg:"media: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Fijar a la Izquierda",pinRight:"Fijar a la Derecha",unpin:"Quitar Fijación"},gridMenu:{columns:"Columnas:",importerTitle:"Importar archivo",exporterAllAsCsv:"Exportar todo como csv",exporterVisibleAsCsv:"Exportar vista como csv",exporterSelectedAsCsv:"Exportar selección como csv",exporterAllAsPdf:"Exportar todo como pdf",exporterVisibleAsPdf:"Exportar vista como pdf",exporterSelectedAsPdf:"Exportar selección como pdf",clearAllFilters:"Limpiar todos los filtros"},importer:{noHeaders:"No fue posible derivar los nombres de las columnas, ¿tiene encabezados el archivo?",noObjects:"No fue posible obtener registros, ¿contiene datos el archivo, aparte de los encabezados?",invalidCsv:"No fue posible procesar el archivo, ¿es un CSV válido?",invalidJson:"No fue posible procesar el archivo, ¿es un Json válido?",jsonNotArray:"El archivo json importado debe contener un array, abortando."},pagination:{sizes:"registros por página",totalItems:"registros",of:"de"},grouping:{group:"Agrupar",ungroup:"Desagrupar",aggregate_count:"Agr: Cont",aggregate_sum:"Agr: Sum",aggregate_max:"Agr: Máx",aggregate_min:"Agr: Min",aggregate_avg:"Agr: Prom",aggregate_remove:"Agr: Quitar"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("fa",{aggregate:{label:"قلم"},groupPanel:{description:"عنوان یک ستون را بگیر و به گروهی از آن ستون رها کن."},search:{placeholder:"جستجو...",showingItems:"نمایش اقلام:",selectedItems:"قلم‌های انتخاب شده:",totalItems:"مجموع اقلام:",size:"اندازه‌ی صفحه:",first:"اولین صفحه",next:"صفحه‌ی‌بعدی",previous:"صفحه‌ی‌ قبلی",last:"آخرین صفحه"},menu:{text:"ستون‌های انتخابی:"},sort:{ascending:"ترتیب صعودی",descending:"ترتیب نزولی",remove:"حذف مرتب کردن"},column:{hide:"پنهان‌کردن ستون"},aggregation:{count:"تعداد: ",sum:"مجموع: ",avg:"میانگین: ",min:"کمترین: ",max:"بیشترین: "},pinning:{pinLeft:"پین کردن سمت چپ",pinRight:"پین کردن سمت راست",unpin:"حذف پین"},gridMenu:{columns:"ستون‌ها:",importerTitle:"وارد کردن فایل",exporterAllAsCsv:"خروجی تمام داده‌ها در فایل csv",exporterVisibleAsCsv:"خروجی داده‌های قابل مشاهده در فایل csv",exporterSelectedAsCsv:"خروجی داده‌های انتخاب‌شده در فایل csv",exporterAllAsPdf:"خروجی تمام داده‌ها در فایل pdf",exporterVisibleAsPdf:"خروجی داده‌های قابل مشاهده در فایل pdf",exporterSelectedAsPdf:"خروجی داده‌های انتخاب‌شده در فایل pdf",clearAllFilters:"پاک کردن تمام فیلتر"},importer:{noHeaders:"نام ستون قابل استخراج نیست. آیا فایل عنوان دارد؟",noObjects:"اشیا قابل استخراج نیستند. آیا به جز عنوان‌ها در فایل داده وجود دارد؟",invalidCsv:"فایل قابل پردازش نیست. آیا فرمت csv معتبر است؟",invalidJson:"فایل قابل پردازش نیست. آیا فرمت json معتبر است؟",jsonNotArray:"فایل json وارد شده باید حاوی آرایه باشد. عملیات ساقط شد."},pagination:{sizes:"اقلام در هر صفحه",totalItems:"اقلام",of:"از"},grouping:{group:"گروه‌بندی",ungroup:"حذف گروه‌بندی",aggregate_count:"Agg: تعداد",aggregate_sum:"Agg: جمع",aggregate_max:"Agg: بیشینه",aggregate_min:"Agg: کمینه",aggregate_avg:"Agg: میانگین",aggregate_remove:"Agg: حذف"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("fi",{aggregate:{label:"rivit"},groupPanel:{description:"Raahaa ja pudota otsikko tähän ryhmittääksesi sarakkeen mukaan."},search:{placeholder:"Hae...",showingItems:"Näytetään rivejä:",selectedItems:"Valitut rivit:",totalItems:"Rivejä yht.:",size:"Näytä:",first:"Ensimmäinen sivu",next:"Seuraava sivu",previous:"Edellinen sivu",last:"Viimeinen sivu"},menu:{text:"Valitse sarakkeet:"},sort:{ascending:"Järjestä nouseva",descending:"Järjestä laskeva",remove:"Poista järjestys"},column:{hide:"Piilota sarake"},aggregation:{count:"Rivejä yht.: ",sum:"Summa: ",avg:"K.a.: ",min:"Min: ",max:"Max: "},pinning:{pinLeft:"Lukitse vasemmalle",pinRight:"Lukitse oikealle",unpin:"Poista lukitus"},gridMenu:{columns:"Sarakkeet:",importerTitle:"Tuo tiedosto",exporterAllAsCsv:"Vie tiedot csv-muodossa",exporterVisibleAsCsv:"Vie näkyvä tieto csv-muodossa",exporterSelectedAsCsv:"Vie valittu tieto csv-muodossa",exporterAllAsPdf:"Vie tiedot pdf-muodossa",exporterVisibleAsPdf:"Vie näkyvä tieto pdf-muodossa",exporterSelectedAsPdf:"Vie valittu tieto pdf-muodossa",clearAllFilters:"Puhdista kaikki suodattimet"},importer:{noHeaders:"Sarakkeen nimiä ei voitu päätellä, onko tiedostossa otsikkoriviä?",noObjects:"Tietoja ei voitu lukea, onko tiedostossa muuta kuin otsikkot?",invalidCsv:"Tiedostoa ei voitu käsitellä, oliko se CSV-muodossa?",invalidJson:"Tiedostoa ei voitu käsitellä, oliko se JSON-muodossa?",jsonNotArray:"Tiedosto ei sisältänyt taulukkoa, lopetetaan."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("fr",{aggregate:{label:"éléments"},groupPanel:{description:"Faites glisser une en-tête de colonne ici pour créer un groupe de colonnes."},search:{placeholder:"Recherche...",showingItems:"Affichage des éléments :",selectedItems:"Éléments sélectionnés :",totalItems:"Nombre total d'éléments:",size:"Taille de page:",first:"Première page",next:"Page Suivante",previous:"Page précédente",last:"Dernière page"},menu:{text:"Choisir des colonnes :"},sort:{ascending:"Trier par ordre croissant",descending:"Trier par ordre décroissant",remove:"Enlever le tri"},column:{hide:"Cacher la colonne"},aggregation:{count:"lignes totales: ",sum:"total: ",avg:"moy: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Épingler à gauche",pinRight:"Épingler à droite",unpin:"Détacher"},gridMenu:{columns:"Colonnes:",importerTitle:"Importer un fichier",exporterAllAsCsv:"Exporter toutes les données en CSV",exporterVisibleAsCsv:"Exporter les données visibles en CSV",exporterSelectedAsCsv:"Exporter les données sélectionnées en CSV",exporterAllAsPdf:"Exporter toutes les données en PDF",exporterVisibleAsPdf:"Exporter les données visibles en PDF",exporterSelectedAsPdf:"Exporter les données sélectionnées en PDF",clearAllFilters:"Nettoyez tous les filtres"},importer:{noHeaders:"Impossible de déterminer le nom des colonnes, le fichier possède-t-il une en-tête ?",noObjects:"Aucun objet trouvé, le fichier possède-t-il des données autres que l'en-tête ?",invalidCsv:"Le fichier n'a pas pu être traité, le CSV est-il valide ?",invalidJson:"Le fichier n'a pas pu être traité, le JSON est-il valide ?",jsonNotArray:"Le fichier JSON importé doit contenir un tableau, abandon."},pagination:{sizes:"éléments par page",totalItems:"éléments",of:"sur"},grouping:{group:"Grouper",ungroup:"Dégrouper",aggregate_count:"Agg: Compte",aggregate_sum:"Agg: Somme",aggregate_max:"Agg: Max",aggregate_min:"Agg: Min",aggregate_avg:"Agg: Moy",aggregate_remove:"Agg: Retirer"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("he",{aggregate:{label:"items"},groupPanel:{description:"גרור עמודה לכאן ושחרר בכדי לקבץ עמודה זו."},search:{placeholder:"חפש...",showingItems:"מציג:",selectedItems:'סה"כ נבחרו:',totalItems:'סה"כ רשומות:',size:"תוצאות בדף:",first:"דף ראשון",next:"דף הבא",previous:"דף קודם",last:"דף אחרון"},menu:{text:"בחר עמודות:"},sort:{ascending:"סדר עולה",descending:"סדר יורד",remove:"בטל"},column:{hide:"טור הסתר"},aggregation:{count:"total rows: ",sum:"total: ",avg:"avg: ",min:"min: ",max:"max: "},gridMenu:{columns:"Columns:",importerTitle:"Import file",exporterAllAsCsv:"Export all data as csv",exporterVisibleAsCsv:"Export visible data as csv",exporterSelectedAsCsv:"Export selected data as csv",exporterAllAsPdf:"Export all data as pdf",exporterVisibleAsPdf:"Export visible data as pdf",exporterSelectedAsPdf:"Export selected data as pdf",clearAllFilters:"Clean all filters"},importer:{noHeaders:"Column names were unable to be derived, does the file have a header?",noObjects:"Objects were not able to be derived, was there data in the file other than headers?",invalidCsv:"File was unable to be processed, is it valid CSV?",invalidJson:"File was unable to be processed, is it valid Json?",jsonNotArray:"Imported json file must contain an array, aborting."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("hy",{aggregate:{label:"տվյալներ"},groupPanel:{description:"Ըստ սյան խմբավորելու համար քաշեք և գցեք վերնագիրն այստեղ։"},search:{placeholder:"Փնտրում...",showingItems:"Ցուցադրված տվյալներ՝",selectedItems:"Ընտրված:",totalItems:"Ընդամենը՝",size:"Տողերի քանակը էջում՝",first:"Առաջին էջ",next:"Հաջորդ էջ",previous:"Նախորդ էջ",last:"Վերջին էջ"},menu:{text:"Ընտրել սյուները:"},sort:{ascending:"Աճման կարգով",descending:"Նվազման կարգով",remove:"Հանել "},column:{hide:"Թաքցնել սյունը"},aggregation:{count:"ընդամենը տող՝ ",sum:"ընդամենը՝ ",avg:"միջին՝ ",min:"մին՝ ",max:"մաքս՝ "},pinning:{pinLeft:"Կպցնել ձախ կողմում",pinRight:"Կպցնել աջ կողմում",unpin:"Արձակել"},gridMenu:{columns:"Սյուներ:",importerTitle:"Ներմուծել ֆայլ",exporterAllAsCsv:"Արտահանել ամբողջը CSV",exporterVisibleAsCsv:"Արտահանել երևացող տվյալները CSV",exporterSelectedAsCsv:"Արտահանել ընտրված տվյալները CSV",exporterAllAsPdf:"Արտահանել PDF",exporterVisibleAsPdf:"Արտահանել երևացող տվյալները PDF",exporterSelectedAsPdf:"Արտահանել ընտրված տվյալները PDF",clearAllFilters:"Մաքրել բոլոր ֆիլտրերը"},importer:{noHeaders:"Հնարավոր չեղավ որոշել սյան վերնագրերը։ Արդյո՞ք ֆայլը ունի վերնագրեր։",noObjects:"Հնարավոր չեղավ կարդալ տվյալները։ Արդյո՞ք ֆայլում կան տվյալներ։",invalidCsv:"Հնարավոր չեղավ մշակել ֆայլը։ Արդյո՞ք այն վավեր CSV է։",invalidJson:"Հնարավոր չեղավ մշակել ֆայլը։ Արդյո՞ք այն վավեր Json է։",jsonNotArray:"Ներմուծված json ֆայլը պետք է պարունակի զանգված, կասեցվում է։"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("it",{aggregate:{label:"elementi"},groupPanel:{description:"Trascina un'intestazione all'interno del gruppo della colonna."},search:{placeholder:"Ricerca...",showingItems:"Mostra:",selectedItems:"Selezionati:",totalItems:"Totali:",size:"Tot Pagine:",first:"Prima",next:"Prossima",previous:"Precedente",last:"Ultima"},menu:{text:"Scegli le colonne:"},sort:{ascending:"Asc.",descending:"Desc.",remove:"Annulla ordinamento"},column:{hide:"Nascondi"},aggregation:{count:"righe totali: ",sum:"tot: ",avg:"media: ",min:"minimo: ",max:"massimo: "},pinning:{pinLeft:"Blocca a sx",pinRight:"Blocca a dx",unpin:"Blocca in alto"},gridMenu:{columns:"Colonne:",importerTitle:"Importa",exporterAllAsCsv:"Esporta tutti i dati in CSV",exporterVisibleAsCsv:"Esporta i dati visibili in CSV",exporterSelectedAsCsv:"Esporta i dati selezionati in CSV",exporterAllAsPdf:"Esporta tutti i dati in PDF",exporterVisibleAsPdf:"Esporta i dati visibili in PDF",exporterSelectedAsPdf:"Esporta i dati selezionati in PDF",clearAllFilters:"Pulire tutti i filtri"},importer:{noHeaders:"Impossibile reperire i nomi delle colonne, sicuro che siano indicati all'interno del file?",noObjects:"Impossibile reperire gli oggetti, sicuro che siano indicati all'interno del file?",invalidCsv:"Impossibile elaborare il file, sicuro che sia un CSV?",invalidJson:"Impossibile elaborare il file, sicuro che sia un JSON valido?",jsonNotArray:"Errore! Il file JSON da importare deve contenere un array."},grouping:{group:"Raggruppa",ungroup:"Separa",aggregate_count:"Agg: N. Elem.",aggregate_sum:"Agg: Somma",aggregate_max:"Agg: Massimo",aggregate_min:"Agg: Minimo",aggregate_avg:"Agg: Media",aggregate_remove:"Agg: Rimuovi" -},validate:{error:"Errore:",minLength:"Lunghezza minima pari a THRESHOLD caratteri.",maxLength:"Lunghezza massima pari a THRESHOLD caratteri.",required:"Necessario inserire un valore."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("ja",{aggregate:{label:"項目"},groupPanel:{description:"ここに列ヘッダをドラッグアンドドロップして、その列でグループ化します。"},search:{placeholder:"検索...",showingItems:"表示中の項目:",selectedItems:"選択した項目:",totalItems:"項目の総数:",size:"ページサイズ:",first:"最初のページ",next:"次のページ",previous:"前のページ",last:"前のページ"},menu:{text:"列の選択:"},sort:{ascending:"昇順に並べ替え",descending:"降順に並べ替え",remove:"並べ替えの解除"},column:{hide:"列の非表示"},aggregation:{count:"合計行数: ",sum:"合計: ",avg:"平均: ",min:"最小: ",max:"最大: "},pinning:{pinLeft:"左に固定",pinRight:"右に固定",unpin:"固定解除"},gridMenu:{columns:"列:",importerTitle:"ファイルのインポート",exporterAllAsCsv:"すべてのデータをCSV形式でエクスポート",exporterVisibleAsCsv:"表示中のデータをCSV形式でエクスポート",exporterSelectedAsCsv:"選択したデータをCSV形式でエクスポート",exporterAllAsPdf:"すべてのデータをPDF形式でエクスポート",exporterVisibleAsPdf:"表示中のデータをPDF形式でエクスポート",exporterSelectedAsPdf:"選択したデータをPDF形式でエクスポート",clearAllFilters:"すべてのフィルタを清掃してください"},importer:{noHeaders:"列名を取得できません。ファイルにヘッダが含まれていることを確認してください。",noObjects:"オブジェクトを取得できません。ファイルにヘッダ以外のデータが含まれていることを確認してください。",invalidCsv:"ファイルを処理できません。ファイルが有効なCSV形式であることを確認してください。",invalidJson:"ファイルを処理できません。ファイルが有効なJSON形式であることを確認してください。",jsonNotArray:"インポートしたJSONファイルには配列が含まれている必要があります。処理を中止します。"},pagination:{aria:{pageToFirst:"最初のページ",pageBack:"前のページ",pageSelected:"現在のページ",pageForward:"次のページ",pageToLast:"最後のページ"},sizes:"項目/ページ",totalItems:"項目",through:"から",of:"項目/全"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("ko",{aggregate:{label:"아이템"},groupPanel:{description:"컬럼으로 그룹핑하기 위해서는 컬럼 헤더를 끌어 떨어뜨려 주세요."},search:{placeholder:"검색...",showingItems:"항목 보여주기:",selectedItems:"선택 항목:",totalItems:"전체 항목:",size:"페이지 크기:",first:"첫번째 페이지",next:"다음 페이지",previous:"이전 페이지",last:"마지막 페이지"},menu:{text:"컬럼을 선택하세요:"},sort:{ascending:"오름차순 정렬",descending:"내림차순 정렬",remove:"소팅 제거"},column:{hide:"컬럼 제거"},aggregation:{count:"전체 갯수: ",sum:"전체: ",avg:"평균: ",min:"최소: ",max:"최대: "},pinning:{pinLeft:"왼쪽 핀",pinRight:"오른쪽 핀",unpin:"핀 제거"},gridMenu:{columns:"컬럼:",importerTitle:"파일 가져오기",exporterAllAsCsv:"csv로 모든 데이터 내보내기",exporterVisibleAsCsv:"csv로 보이는 데이터 내보내기",exporterSelectedAsCsv:"csv로 선택된 데이터 내보내기",exporterAllAsPdf:"pdf로 모든 데이터 내보내기",exporterVisibleAsPdf:"pdf로 보이는 데이터 내보내기",exporterSelectedAsPdf:"pdf로 선택 데이터 내보내기",clearAllFilters:"모든 필터를 청소"},importer:{noHeaders:"컬럼명이 지정되어 있지 않습니다. 파일에 헤더가 명시되어 있는지 확인해 주세요.",noObjects:"데이터가 지정되어 있지 않습니다. 데이터가 파일에 있는지 확인해 주세요.",invalidCsv:"파일을 처리할 수 없습니다. 올바른 csv인지 확인해 주세요.",invalidJson:"파일을 처리할 수 없습니다. 올바른 json인지 확인해 주세요.",jsonNotArray:"json 파일은 배열을 포함해야 합니다."},pagination:{sizes:"페이지당 항목",totalItems:"전체 항목"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("nl",{aggregate:{label:"items"},groupPanel:{description:"Sleep hier een kolomnaam heen om op te groeperen."},search:{placeholder:"Zoeken...",showingItems:"Getoonde items:",selectedItems:"Geselecteerde items:",totalItems:"Totaal aantal items:",size:"Items per pagina:",first:"Eerste pagina",next:"Volgende pagina",previous:"Vorige pagina",last:"Laatste pagina"},menu:{text:"Kies kolommen:"},sort:{ascending:"Sorteer oplopend",descending:"Sorteer aflopend",remove:"Verwijder sortering"},column:{hide:"Verberg kolom"},aggregation:{count:"Aantal rijen: ",sum:"Som: ",avg:"Gemiddelde: ",min:"Min: ",max:"Max: "},pinning:{pinLeft:"Zet links vast",pinRight:"Zet rechts vast",unpin:"Maak los"},gridMenu:{columns:"Kolommen:",importerTitle:"Importeer bestand",exporterAllAsCsv:"Exporteer alle data als csv",exporterVisibleAsCsv:"Exporteer zichtbare data als csv",exporterSelectedAsCsv:"Exporteer geselecteerde data als csv",exporterAllAsPdf:"Exporteer alle data als pdf",exporterVisibleAsPdf:"Exporteer zichtbare data als pdf",exporterSelectedAsPdf:"Exporteer geselecteerde data als pdf",clearAllFilters:"Reinig alle filters"},importer:{noHeaders:"Kolomnamen kunnen niet worden afgeleid. Heeft het bestand een header?",noObjects:"Objecten kunnen niet worden afgeleid. Bevat het bestand data naast de headers?",invalidCsv:"Het bestand kan niet verwerkt worden. Is het een valide csv bestand?",invalidJson:"Het bestand kan niet verwerkt worden. Is het valide json?",jsonNotArray:"Het json bestand moet een array bevatten. De actie wordt geannuleerd."},pagination:{sizes:"items per pagina",totalItems:"items",of:"van de"},grouping:{group:"Groepeer",ungroup:"Groepering opheffen",aggregate_count:"Agg: Aantal",aggregate_sum:"Agg: Som",aggregate_max:"Agg: Max",aggregate_min:"Agg: Min",aggregate_avg:"Agg: Gem",aggregate_remove:"Agg: Verwijder"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("pl",{headerCell:{aria:{defaultFilterLabel:"Filter dla kolumny",removeFilter:"Usuń filter",columnMenuButtonLabel:"Menu kolumny"},priority:"Prioritet:",filterLabel:"Filtr dla kolumny: "},aggregate:{label:"pozycji"},groupPanel:{description:"Przeciągnij nagłówek kolumny tutaj, aby pogrupować według niej."},search:{placeholder:"Szukaj...",showingItems:"Widoczne pozycje:",selectedItems:"Zaznaczone pozycje:",totalItems:"Wszystkich pozycji:",size:"Rozmiar strony:",first:"Pierwsza strona",next:"Następna strona",previous:"Poprzednia strona",last:"Ostatnia strona"},menu:{text:"Wybierz kolumny:"},sort:{ascending:"Sortuj rosnąco",descending:"Sortuj malejąco",none:"Brak sortowania",remove:"Wyłącz sortowanie"},column:{hide:"Ukryj kolumne"},aggregation:{count:"Razem pozycji: ",sum:"Razem: ",avg:"Średnia: ",min:"Min: ",max:"Max: "},pinning:{pinLeft:"Przypnij do lewej",pinRight:"Przypnij do prawej",unpin:"Odepnij"},columnMenu:{close:"Zamknij"},gridMenu:{aria:{buttonLabel:"Menu Grida"},columns:"Kolumny:",importerTitle:"Importuj plik",exporterAllAsCsv:"Eksportuj wszystkie dane do csv",exporterVisibleAsCsv:"Eksportuj widoczne dane do csv",exporterSelectedAsCsv:"Eksportuj zaznaczone dane do csv",exporterAllAsPdf:"Eksportuj wszystkie dane do pdf",exporterVisibleAsPdf:"Eksportuj widoczne dane do pdf",exporterSelectedAsPdf:"Eksportuj zaznaczone dane do pdf",clearAllFilters:"Wyczyść filtry"},importer:{noHeaders:"Nie udało się wczytać nazw kolumn. Czy plik posiada nagłówek?",noObjects:"Nie udalo się wczytać pozycji. Czy plik zawiera dane??",invalidCsv:"Nie udało się przetworzyć pliku, jest to prawidlowy plik CSV??",invalidJson:"Nie udało się przetworzyć pliku, jest to prawidlowy plik Json?",jsonNotArray:"Importowany plik json musi zawierać tablicę, importowanie przerwane."},pagination:{aria:{pageToFirst:"Pierwsza strona",pageBack:"Poprzednia strona",pageSelected:"Wybrana strona",pageForward:"Następna strona",pageToLast:"Ostatnia strona"},sizes:"pozycji na stronę",totalItems:"pozycji",through:"do",of:"z"},grouping:{group:"Grupuj",ungroup:"Rozgrupuj",aggregate_count:"Zbiorczo: Razem",aggregate_sum:"Zbiorczo: Suma",aggregate_max:"Zbiorczo: Max",aggregate_min:"Zbiorczo: Min",aggregate_avg:"Zbiorczo: Średnia",aggregate_remove:"Zbiorczo: Usuń"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("pt-br",{headerCell:{aria:{defaultFilterLabel:"Filtro por coluna",removeFilter:"Remover filtro",columnMenuButtonLabel:"Menu coluna"},priority:"Prioridade:",filterLabel:"Filtro por coluna: "},aggregate:{label:"itens"},groupPanel:{description:"Arraste e solte uma coluna aqui para agrupar por essa coluna"},search:{placeholder:"Procurar...",showingItems:"Mostrando os Itens:",selectedItems:"Items Selecionados:",totalItems:"Total de Itens:",size:"Tamanho da Página:",first:"Primeira Página",next:"Próxima Página",previous:"Página Anterior",last:"Última Página"},menu:{text:"Selecione as colunas:"},sort:{ascending:"Ordenar Ascendente",descending:"Ordenar Descendente",none:"Nenhuma Ordem",remove:"Remover Ordenação"},column:{hide:"Esconder coluna"},aggregation:{count:"total de linhas: ",sum:"total: ",avg:"med: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Fixar Esquerda",pinRight:"Fixar Direita",unpin:"Desprender"},columnMenu:{close:"Fechar"},gridMenu:{aria:{buttonLabel:"Menu Grid"},columns:"Colunas:",importerTitle:"Importar arquivo",exporterAllAsCsv:"Exportar todos os dados como csv",exporterVisibleAsCsv:"Exportar dados visíveis como csv",exporterSelectedAsCsv:"Exportar dados selecionados como csv",exporterAllAsPdf:"Exportar todos os dados como pdf",exporterVisibleAsPdf:"Exportar dados visíveis como pdf",exporterSelectedAsPdf:"Exportar dados selecionados como pdf",clearAllFilters:"Limpar todos os filtros"},importer:{noHeaders:"Nomes de colunas não puderam ser derivados. O arquivo tem um cabeçalho?",noObjects:"Objetos não puderam ser derivados. Havia dados no arquivo, além dos cabeçalhos?",invalidCsv:"Arquivo não pode ser processado. É um CSV válido?",invalidJson:"Arquivo não pode ser processado. É um Json válido?",jsonNotArray:"Arquivo json importado tem que conter um array. Abortando."},pagination:{aria:{pageToFirst:"Primeira página",pageBack:"Página anterior",pageSelected:"Página Selecionada",pageForward:"Proxima",pageToLast:"Anterior"},sizes:"itens por página",totalItems:"itens",through:"através dos",of:"de"},grouping:{group:"Agrupar",ungroup:"Desagrupar",aggregate_count:"Agr: Contar",aggregate_sum:"Agr: Soma",aggregate_max:"Agr: Max",aggregate_min:"Agr: Min",aggregate_avg:"Agr: Med",aggregate_remove:"Agr: Remover"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("pt",{headerCell:{aria:{defaultFilterLabel:"Filtro por coluna",removeFilter:"Remover filtro",columnMenuButtonLabel:"Menu coluna"},priority:"Prioridade:",filterLabel:"Filtro por coluna: "},aggregate:{label:"itens"},groupPanel:{description:"Arraste e solte uma coluna aqui para agrupar por essa coluna"},search:{placeholder:"Procurar...",showingItems:"Mostrando os Itens:",selectedItems:"Itens Selecionados:",totalItems:"Total de Itens:",size:"Tamanho da Página:",first:"Primeira Página",next:"Próxima Página",previous:"Página Anterior",last:"Última Página"},menu:{text:"Selecione as colunas:"},sort:{ascending:"Ordenar Ascendente",descending:"Ordenar Descendente",none:"Nenhuma Ordem",remove:"Remover Ordenação"},column:{hide:"Esconder coluna"},aggregation:{count:"total de linhas: ",sum:"total: ",avg:"med: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Fixar Esquerda",pinRight:"Fixar Direita",unpin:"Desprender"},columnMenu:{close:"Fechar"},gridMenu:{aria:{buttonLabel:"Menu Grid"},columns:"Colunas:",importerTitle:"Importar ficheiro",exporterAllAsCsv:"Exportar todos os dados como csv",exporterVisibleAsCsv:"Exportar dados visíveis como csv",exporterSelectedAsCsv:"Exportar dados selecionados como csv",exporterAllAsPdf:"Exportar todos os dados como pdf",exporterVisibleAsPdf:"Exportar dados visíveis como pdf",exporterSelectedAsPdf:"Exportar dados selecionados como pdf",clearAllFilters:"Limpar todos os filtros"},importer:{noHeaders:"Nomes de colunas não puderam ser derivados. O ficheiro tem um cabeçalho?",noObjects:"Objetos não puderam ser derivados. Havia dados no ficheiro, além dos cabeçalhos?",invalidCsv:"Ficheiro não pode ser processado. É um CSV válido?",invalidJson:"Ficheiro não pode ser processado. É um Json válido?",jsonNotArray:"Ficheiro json importado tem que conter um array. Interrompendo."},pagination:{aria:{pageToFirst:"Primeira página",pageBack:"Página anterior",pageSelected:"Página Selecionada",pageForward:"Próxima",pageToLast:"Anterior"},sizes:"itens por página",totalItems:"itens",through:"através dos",of:"de"},grouping:{group:"Agrupar",ungroup:"Desagrupar",aggregate_count:"Agr: Contar",aggregate_sum:"Agr: Soma",aggregate_max:"Agr: Max",aggregate_min:"Agr: Min",aggregate_avg:"Agr: Med",aggregate_remove:"Agr: Remover"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("ro",{headerCell:{aria:{defaultFilterLabel:"Filtru pentru coloana",removeFilter:"Sterge filtru",columnMenuButtonLabel:"Column Menu"},priority:"Prioritate:",filterLabel:"Filtru pentru coloana:"},aggregate:{label:"Elemente"},groupPanel:{description:"Trage un cap de coloana aici pentru a grupa elementele dupa coloana respectiva"},search:{placeholder:"Cauta...",showingItems:"Arata elementele:",selectedItems:"Elementele selectate:",totalItems:"Total elemente:",size:"Marime pagina:",first:"Prima pagina",next:"Pagina urmatoare",previous:"Pagina anterioara",last:"Ultima pagina"},menu:{text:"Alege coloane:"},sort:{ascending:"Ordoneaza crescator",descending:"Ordoneaza descrescator",none:"Fara ordonare",remove:"Sterge ordonarea"},column:{hide:"Ascunde coloana"},aggregation:{count:"total linii: ",sum:"total: ",avg:"medie: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Pin la stanga",pinRight:"Pin la dreapta",unpin:"Sterge pinul"},columnMenu:{close:"Inchide"},gridMenu:{aria:{buttonLabel:"Grid Menu"},columns:"Coloane:",importerTitle:"Incarca fisier",exporterAllAsCsv:"Exporta toate datele ca csv",exporterVisibleAsCsv:"Exporta datele vizibile ca csv",exporterSelectedAsCsv:"Exporta datele selectate ca csv",exporterAllAsPdf:"Exporta toate datele ca pdf",exporterVisibleAsPdf:"Exporta datele vizibile ca pdf",exporterSelectedAsPdf:"Exporta datele selectate ca csv pdf",clearAllFilters:"Sterge toate filtrele"},importer:{noHeaders:"Numele coloanelor nu a putut fi incarcat, acest fisier are un header?",noObjects:"Datele nu au putut fi incarcate, exista date in fisier in afara numelor de coloane?",invalidCsv:"Fisierul nu a putut fi procesat, ati incarcat un CSV valid ?",invalidJson:"Fisierul nu a putut fi procesat, ati incarcat un Json valid?",jsonNotArray:"Json-ul incarcat trebuie sa contina un array, inchidere."},pagination:{aria:{pageToFirst:"Prima pagina",pageBack:"O pagina inapoi",pageSelected:"Pagina selectata",pageForward:"O pagina inainte",pageToLast:"Ultima pagina"},sizes:"Elemente per pagina",totalItems:"elemente",through:"prin",of:"of"},grouping:{group:"Grupeaza",ungroup:"Opreste gruparea",aggregate_count:"Agg: Count",aggregate_sum:"Agg: Sum",aggregate_max:"Agg: Max",aggregate_min:"Agg: Min",aggregate_avg:"Agg: Avg",aggregate_remove:"Agg: Remove"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("ru",{headerCell:{aria:{defaultFilterLabel:"Фильтр столбца",removeFilter:"Удалить фильтр",columnMenuButtonLabel:"Меню столбца"},priority:"Приоритет:",filterLabel:"Фильтр столбца: "},aggregate:{label:"элементы"},groupPanel:{description:"Для группировки по столбцу перетащите сюда его название."},search:{placeholder:"Поиск...",showingItems:"Показать элементы:",selectedItems:"Выбранные элементы:",totalItems:"Всего элементов:",size:"Размер страницы:",first:"Первая страница",next:"Следующая страница",previous:"Предыдущая страница",last:"Последняя страница"},menu:{text:"Выбрать столбцы:"},sort:{ascending:"По возрастанию",descending:"По убыванию",none:"Без сортировки",remove:"Убрать сортировку"},column:{hide:"Спрятать столбец"},aggregation:{count:"всего строк: ",sum:"итого: ",avg:"среднее: ",min:"мин: ",max:"макс: "},pinning:{pinLeft:"Закрепить слева",pinRight:"Закрепить справа",unpin:"Открепить"},columnMenu:{close:"Закрыть"},gridMenu:{aria:{buttonLabel:"Меню"},columns:"Столбцы:",importerTitle:"Импортировать файл",exporterAllAsCsv:"Экспортировать всё в CSV",exporterVisibleAsCsv:"Экспортировать видимые данные в CSV",exporterSelectedAsCsv:"Экспортировать выбранные данные в CSV",exporterAllAsPdf:"Экспортировать всё в PDF",exporterVisibleAsPdf:"Экспортировать видимые данные в PDF",exporterSelectedAsPdf:"Экспортировать выбранные данные в PDF",clearAllFilters:"Очистите все фильтры"},importer:{noHeaders:"Не удалось получить названия столбцов, есть ли в файле заголовок?",noObjects:"Не удалось получить данные, есть ли в файле строки кроме заголовка?",invalidCsv:"Не удалось обработать файл, это правильный CSV-файл?",invalidJson:"Не удалось обработать файл, это правильный JSON?",jsonNotArray:"Импортируемый JSON-файл должен содержать массив, операция отменена."},pagination:{aria:{pageToFirst:"Первая страница",pageBack:"Предыдущая страница",pageSelected:"Выбранная страница",pageForward:"Следующая страница",pageToLast:"Последняя страница"},sizes:"строк на страницу",totalItems:"строк",through:"по",of:"из"},grouping:{group:"Группировать",ungroup:"Разгруппировать",aggregate_count:"Группировать: Count",aggregate_sum:"Для группы: Сумма",aggregate_max:"Для группы: Максимум",aggregate_min:"Для группы: Минимум",aggregate_avg:"Для группы: Среднее",aggregate_remove:"Для группы: Пусто"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("sk",{aggregate:{label:"items"},groupPanel:{description:"Pretiahni sem názov stĺpca pre zoskupenie podľa toho stĺpca."},search:{placeholder:"Hľadaj...",showingItems:"Zobrazujem položky:",selectedItems:"Vybraté položky:",totalItems:"Počet položiek:",size:"Počet:",first:"Prvá strana",next:"Ďalšia strana",previous:"Predchádzajúca strana",last:"Posledná strana"},menu:{text:"Vyberte stĺpce:"},sort:{ascending:"Zotriediť vzostupne",descending:"Zotriediť zostupne",remove:"Vymazať triedenie"},aggregation:{count:"total rows: ",sum:"total: ",avg:"avg: ",min:"min: ",max:"max: "},gridMenu:{columns:"Columns:",importerTitle:"Import file",exporterAllAsCsv:"Export all data as csv",exporterVisibleAsCsv:"Export visible data as csv",exporterSelectedAsCsv:"Export selected data as csv",exporterAllAsPdf:"Export all data as pdf",exporterVisibleAsPdf:"Export visible data as pdf",exporterSelectedAsPdf:"Export selected data as pdf",clearAllFilters:"Clear all filters"},importer:{noHeaders:"Column names were unable to be derived, does the file have a header?",noObjects:"Objects were not able to be derived, was there data in the file other than headers?",invalidCsv:"File was unable to be processed, is it valid CSV?",invalidJson:"File was unable to be processed, is it valid Json?",jsonNotArray:"Imported json file must contain an array, aborting."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("sv",{aggregate:{label:"Artiklar"},groupPanel:{description:"Dra en kolumnrubrik hit och släpp den för att gruppera efter den kolumnen."},search:{placeholder:"Sök...",showingItems:"Visar artiklar:",selectedItems:"Valda artiklar:",totalItems:"Antal artiklar:",size:"Sidstorlek:",first:"Första sidan",next:"Nästa sida",previous:"Föregående sida",last:"Sista sidan"},menu:{text:"Välj kolumner:"},sort:{ascending:"Sortera stigande",descending:"Sortera fallande",remove:"Inaktivera sortering"},column:{hide:"Göm kolumn"},aggregation:{count:"Antal rader: ",sum:"Summa: ",avg:"Genomsnitt: ",min:"Min: ",max:"Max: "},pinning:{pinLeft:"Fäst vänster",pinRight:"Fäst höger",unpin:"Lösgör"},gridMenu:{columns:"Kolumner:",importerTitle:"Importera fil",exporterAllAsCsv:"Exportera all data som CSV",exporterVisibleAsCsv:"Exportera synlig data som CSV",exporterSelectedAsCsv:"Exportera markerad data som CSV",exporterAllAsPdf:"Exportera all data som PDF",exporterVisibleAsPdf:"Exportera synlig data som PDF",exporterSelectedAsPdf:"Exportera markerad data som PDF",clearAllFilters:"Rengör alla filter"},importer:{noHeaders:"Kolumnnamn kunde inte härledas. Har filen ett sidhuvud?",noObjects:"Objekt kunde inte härledas. Har filen data undantaget sidhuvud?",invalidCsv:"Filen kunde inte behandlas, är den en giltig CSV?",invalidJson:"Filen kunde inte behandlas, är den en giltig JSON?",jsonNotArray:"Importerad JSON-fil måste innehålla ett fält. Import avbruten."},pagination:{sizes:"Artiklar per sida",totalItems:"Artiklar"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("ta",{aggregate:{label:"உருப்படிகள்"},groupPanel:{description:"ஒரு பத்தியை குழுவாக அமைக்க அப்பத்தியின் தலைப்பை இங்கே இழுத்து வரவும் "},search:{placeholder:"தேடல் ...",showingItems:"உருப்படிகளை காண்பித்தல்:",selectedItems:"தேர்ந்தெடுக்கப்பட்ட உருப்படிகள்:",totalItems:"மொத்த உருப்படிகள்:",size:"பக்க அளவு: ",first:"முதல் பக்கம்",next:"அடுத்த பக்கம்",previous:"முந்தைய பக்கம் ",last:"இறுதி பக்கம்"},menu:{text:"பத்திகளை தேர்ந்தெடு:"},sort:{ascending:"மேலிருந்து கீழாக",descending:"கீழிருந்து மேலாக",remove:"வரிசையை நீக்கு"},column:{hide:"பத்தியை மறைத்து வை "},aggregation:{count:"மொத்த வரிகள்:",sum:"மொத்தம்: ",avg:"சராசரி: ",min:"குறைந்தபட்ச: ",max:"அதிகபட்ச: "},pinning:{pinLeft:"இடதுபுறமாக தைக்க ",pinRight:"வலதுபுறமாக தைக்க",unpin:"பிரி"},gridMenu:{columns:"பத்திகள்:",importerTitle:"கோப்பு : படித்தல்",exporterAllAsCsv:"எல்லா தரவுகளையும் கோப்பாக்கு: csv",exporterVisibleAsCsv:"இருக்கும் தரவுகளை கோப்பாக்கு: csv",exporterSelectedAsCsv:"தேர்ந்தெடுத்த தரவுகளை கோப்பாக்கு: csv",exporterAllAsPdf:"எல்லா தரவுகளையும் கோப்பாக்கு: pdf",exporterVisibleAsPdf:"இருக்கும் தரவுகளை கோப்பாக்கு: pdf",exporterSelectedAsPdf:"தேர்ந்தெடுத்த தரவுகளை கோப்பாக்கு: pdf",clearAllFilters:"Clear all filters"},importer:{noHeaders:"பத்தியின் தலைப்புகளை பெற இயலவில்லை, கோப்பிற்கு தலைப்பு உள்ளதா?",noObjects:"இலக்குகளை உருவாக்க முடியவில்லை, கோப்பில் தலைப்புகளை தவிர தரவு ஏதேனும் உள்ளதா? ",invalidCsv:"சரிவர நடைமுறை படுத்த இயலவில்லை, கோப்பு சரிதானா? - csv",invalidJson:"சரிவர நடைமுறை படுத்த இயலவில்லை, கோப்பு சரிதானா? - json",jsonNotArray:"படித்த கோப்பில் வரிசைகள் உள்ளது, நடைமுறை ரத்து செய் : json"},pagination:{sizes:"உருப்படிகள் / பக்கம்",totalItems:"உருப்படிகள் "},grouping:{group:"குழு",ungroup:"பிரி",aggregate_count:"மதிப்பீட்டு : எண்ணு",aggregate_sum:"மதிப்பீட்டு : கூட்டல்",aggregate_max:"மதிப்பீட்டு : அதிகபட்சம்",aggregate_min:"மதிப்பீட்டு : குறைந்தபட்சம்",aggregate_avg:"மதிப்பீட்டு : சராசரி",aggregate_remove:"மதிப்பீட்டு : நீக்கு"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("tr",{headerCell:{aria:{defaultFilterLabel:"Sütun için filtre",removeFilter:"Filtreyi Kaldır",columnMenuButtonLabel:"Sütun Menüsü"},priority:"Öncelik:",filterLabel:"Sütun için filtre: "},aggregate:{label:"kayıtlar"},groupPanel:{description:"Sütuna göre gruplamak için sütun başlığını buraya sürükleyin ve bırakın."},search:{placeholder:"Arama...",showingItems:"Gösterilen Kayıt:",selectedItems:"Seçili Kayıt:",totalItems:"Toplam Kayıt:",size:"Sayfa Boyutu:",first:"İlk Sayfa",next:"Sonraki Sayfa",previous:"Önceki Sayfa",last:"Son Sayfa"},menu:{text:"Sütunları Seç:"},sort:{ascending:"Artan Sırada Sırala",descending:"Azalan Sırada Sırala",none:"Sıralama Yapma",remove:"Sıralamayı Kaldır"},column:{hide:"Sütunu Gizle"},aggregation:{count:"toplam satır: ",sum:"toplam: ",avg:"ort: ",min:"min: ",max:"maks: "},pinning:{pinLeft:"Sola Sabitle",pinRight:"Sağa Sabitle",unpin:"Sabitlemeyi Kaldır"},columnMenu:{close:"Kapat"},gridMenu:{aria:{buttonLabel:"Tablo Menü"},columns:"Sütunlar:",importerTitle:"Dosya içeri aktar",exporterAllAsCsv:"Bütün veriyi CSV olarak dışarı aktar",exporterVisibleAsCsv:"Görünen veriyi CSV olarak dışarı aktar",exporterSelectedAsCsv:"Seçili veriyi CSV olarak dışarı aktar",exporterAllAsPdf:"Bütün veriyi PDF olarak dışarı aktar",exporterVisibleAsPdf:"Görünen veriyi PDF olarak dışarı aktar",exporterSelectedAsPdf:"Seçili veriyi PDF olarak dışarı aktar",clearAllFilters:"Bütün filtreleri kaldır"},importer:{noHeaders:"Sütun isimleri üretilemiyor, dosyanın bir başlığı var mı?",noObjects:"Nesneler üretilemiyor, dosyada başlıktan başka bir veri var mı?",invalidCsv:"Dosya işlenemedi, geçerli bir CSV dosyası mı?",invalidJson:"Dosya işlenemedi, geçerli bir Json dosyası mı?",jsonNotArray:"Alınan Json dosyasında bir dizi bulunmalıdır, işlem iptal ediliyor."},pagination:{aria:{pageToFirst:"İlk sayfaya",pageBack:"Geri git",pageSelected:"Seçili sayfa",pageForward:"İleri git",pageToLast:"Sona git"},sizes:"Sayfadaki nesne sayısı",totalItems:"kayıtlar",through:"",of:""},grouping:{group:"Grupla",ungroup:"Gruplama",aggregate_count:"Yekun: Sayı",aggregate_sum:"Yekun: Toplam",aggregate_max:"Yekun: Maks",aggregate_min:"Yekun: Min",aggregate_avg:"Yekun: Ort",aggregate_remove:"Yekun: Sil"}}),a}])}])}(),function(){var a=["uiT","uiTranslate"],b=["t","uiTranslate"],c=angular.module("ui.grid.i18n");c.constant("i18nConstants",{MISSING:"[MISSING]",UPDATE_EVENT:"$uiI18n",LOCALE_DIRECTIVE_ALIAS:"uiI18n",DEFAULT_LANG:"en"}),c.service("i18nService",["$log","i18nConstants","$rootScope",function(a,b,c){var d={_langs:{},current:null,get:function(a){return this._langs[a.toLowerCase()]},add:function(a,b){var c=a.toLowerCase();this._langs[c]||(this._langs[c]={}),angular.extend(this._langs[c],b)},getAllLangs:function(){var a=[];if(!this._langs)return a;for(var b in this._langs)a.push(b);return a},setCurrent:function(a){this.current=a.toLowerCase()},getCurrentLang:function(){return this.current}},e={add:function(a,b){"object"==typeof a?angular.forEach(a,function(a){a&&d.add(a,b)}):d.add(a,b)},getAllLangs:function(){return d.getAllLangs()},get:function(a){var b=a?a:e.getCurrentLang();return d.get(b)},getSafeText:function(a,c){var f=c?c:e.getCurrentLang(),g=d.get(f);if(!g)return b.MISSING;for(var h=a.split("."),i=g,j=0;jf?0===g?new d(a,c[h]):new d(e[g-1],c[h]):new d(a,c[h])},f.prototype.getRowColRight=function(a,b){var c=this.getFocusableCols(),e=this.getFocusableRows(),f=c.indexOf(b),g=e.indexOf(a);-1===f&&(f=0);var h=f===c.length-1?0:f+1;return f>h?g===e.length-1?new d(a,c[h]):new d(e[g+1],c[h]):new d(a,c[h])},f.prototype.getRowColDown=function(a,b){var c=this.getFocusableCols(),e=this.getFocusableRows(),f=c.indexOf(b),g=e.indexOf(a);return-1===f&&(f=0),g===e.length-1?new d(a,c[f]):new d(e[g+1],c[f])},f.prototype.getRowColPageDown=function(a,b){ -var c=this.getFocusableCols(),e=this.getFocusableRows(),f=c.indexOf(b),g=e.indexOf(a);-1===f&&(f=0);var h=this.bodyContainer.minRowsToRender();return g>=e.length-h?new d(e[e.length-1],c[f]):new d(e[g+h],c[f])},f.prototype.getRowColUp=function(a,b){var c=this.getFocusableCols(),e=this.getFocusableRows(),f=c.indexOf(b),g=e.indexOf(a);return-1===f&&(f=0),0===g?new d(a,c[f]):new d(e[g-1],c[f])},f.prototype.getRowColPageUp=function(a,b){var c=this.getFocusableCols(),e=this.getFocusableRows(),f=c.indexOf(b),g=e.indexOf(a);-1===f&&(f=0);var h=this.bodyContainer.minRowsToRender();return 0>g-h?new d(e[0],c[f]):new d(e[g-h],c[f])},f}]),a.service("uiGridCellNavService",["gridUtil","uiGridConstants","uiGridCellNavConstants","$q","uiGridCellNavFactory","GridRowColumn","ScrollEvent",function(a,b,c,d,e,f,g){var h={initializeGrid:function(a){a.registerColumnBuilder(h.cellNavColumnBuilder),a.cellNav={},a.cellNav.lastRowCol=null,a.cellNav.focusedCells=[],h.defaultGridOptions(a.options);var b={events:{cellNav:{navigate:function(a,b){},viewPortKeyDown:function(a,b){},viewPortKeyPress:function(a,b){}}},methods:{cellNav:{scrollToFocus:function(b,c){return h.scrollToFocus(a,b,c)},getFocusedCell:function(){return a.cellNav.lastRowCol},getCurrentSelection:function(){return a.cellNav.focusedCells},rowColSelectIndex:function(b){for(var c=-1,d=0;db&&(c+=a.drawnWidth)});var e=0===d?0:(d+1)/a.renderContainers.body.visibleColumnCache.length;return c+=b.drawnWidth*e}};return h}]),a.directive("uiGridCellnav",["gridUtil","uiGridCellNavService","uiGridCellNavConstants","uiGridConstants","GridRowColumn","$timeout","$compile",function(a,b,c,d,e,f,g){return{replace:!0,priority:-150,require:"^uiGrid",scope:!1,controller:function(){},compile:function(){return{pre:function(a,f,g,h){var i=a,j=h.grid;b.initializeGrid(j),h.cellNav={},h.cellNav.makeRowCol=function(a){return a instanceof e||(a=new e(a.row,a.col)),a},h.cellNav.getActiveCell=function(){var a=f[0].getElementsByClassName("ui-grid-cell-focus");return a.length>0?a[0]:void 0},h.cellNav.broadcastCellNav=j.cellNav.broadcastCellNav=function(a,b,d){b=!(void 0===b||!b),a=h.cellNav.makeRowCol(a),h.cellNav.broadcastFocus(a,b,d),i.$broadcast(c.CELL_NAV_EVENT,a,b,d)},h.cellNav.clearFocus=j.cellNav.clearFocus=function(){j.cellNav.focusedCells=[],i.$broadcast(c.CELL_NAV_EVENT)},h.cellNav.broadcastFocus=function(a,b,c){b=!(void 0===b||!b),a=h.cellNav.makeRowCol(a);var d=a.row,f=a.col,g=h.grid.api.cellNav.rowColSelectIndex(a);if(null===j.cellNav.lastRowCol||-1===g){var i=new e(d,f);(null===j.cellNav.lastRowCol||j.cellNav.lastRowCol.row!==i.row||j.cellNav.lastRowCol.col!==i.col)&&(j.api.cellNav.raise.navigate(i,j.cellNav.lastRowCol),j.cellNav.lastRowCol=i),h.grid.options.modifierKeysToMultiSelectCells&&b?j.cellNav.focusedCells.push(a):j.cellNav.focusedCells=[a]}else j.options.modifierKeysToMultiSelectCells&&b&&g>=0&&j.cellNav.focusedCells.splice(g,1)},h.cellNav.handleKeyDown=function(a){var e=b.getDirection(a);if(null===e)return null;var f="body";a.uiGridTargetRenderContainerId&&(f=a.uiGridTargetRenderContainerId);var g=h.grid.api.cellNav.getFocusedCell();if(g){var i=h.grid.renderContainers[f].cellNav.getNextRowCol(e,g.row,g.col),k=h.grid.renderContainers[f].cellNav.getFocusableCols(),l=h.grid.api.cellNav.rowColSelectIndex(i);return e===c.direction.LEFT&&i.col===k[k.length-1]&&i.row===g.row&&a.keyCode===d.keymap.TAB&&a.shiftKey?(j.cellNav.focusedCells.splice(l,1),h.cellNav.clearFocus(),!0):e!==c.direction.RIGHT||i.col!==k[0]||i.row!==g.row||a.keyCode!==d.keymap.TAB||a.shiftKey?(j.scrollToIfNecessary(i.row,i.col).then(function(){h.cellNav.broadcastCellNav(i)}),a.stopPropagation(),a.preventDefault(),!1):(j.cellNav.focusedCells.splice(l,1),h.cellNav.clearFocus(),!0)}}},post:function(a,b,d,e){function f(){var d='
 
',e=g(d)(a);b.prepend(e),a.$on(c.CELL_NAV_EVENT,function(a,b,c,d){function f(a){a!==e.text()&&(e[0].style.clip="rect(0px,0px,0px,0px)",e[0].innerHTML="",e[0].style.visibility="hidden",e[0].style.visibility="visible",""!==a&&(e[0].style.clip="auto",e[0].appendChild(document.createTextNode(a+" ")),e[0].style.visibility="hidden",e[0].style.visibility="visible"))}if(!d||"focus"!==d.type){for(var g=[],i=h.api.cellNav.getCurrentSelection(),j=0;j
')(b);d.append(o),o.on("focus",function(a){a.uiGridTargetRenderContainerId=m;var b=j.grid.api.cellNav.getFocusedCell();null===b&&(b=j.grid.renderContainers[m].cellNav.getNextRowCol(g.direction.DOWN,null,null),b.row&&b.col&&j.cellNav.broadcastCellNav(b))}),l.setAriaActivedescendant=function(a){d.attr("aria-activedescendant",a)},l.removeAriaActivedescendant=function(a){d.attr("aria-activedescendant")===a&&d.attr("aria-activedescendant","")},j.focus=function(){c.focus.byElement(o[0])};var p=null;o.on("keydown",function(a){a.uiGridTargetRenderContainerId=m;var b=j.grid.api.cellNav.getFocusedCell(),c=j.cellNav.handleKeyDown(a);null===c&&(j.grid.api.cellNav.raise.viewPortKeyDown(a,b),p=b)}),o.on("keypress",function(b){p&&(a(function(){j.grid.api.cellNav.raise.viewPortKeyPress(b,p)},4),p=null)}),b.$on("$destroy",function(){o.off()})}}}}}}}]),a.directive("uiGridViewport",["$timeout","$document","gridUtil","uiGridConstants","uiGridCellNavService","uiGridCellNavConstants","$log","$compile",function(a,b,c,d,e,f,g,h){return{replace:!0,priority:-99999,require:["^uiGrid","^uiGridRenderContainer","?^uiGridCellnav"],scope:!1,compile:function(){return{pre:function(a,b,c,d){},post:function(a,b,c,d){var e=d[0],f=d[1];if(e.grid.api.cellNav){var g=f.containerId;if("body"===g){var h=e.grid;h.api.core.on.scrollBegin(a,function(a){var b=e.grid.api.cellNav.getFocusedCell();null!==b&&f.colContainer.containsColumn(b.col)&&e.cellNav.clearFocus()}),h.api.core.on.scrollEnd(a,function(a){var b=e.grid.api.cellNav.getFocusedCell();null!==b&&f.colContainer.containsColumn(b.col)&&e.cellNav.broadcastCellNav(b)}),h.api.cellNav.on.navigate(a,function(){e.focus()})}}}}}}}]),a.directive("uiGridCell",["$timeout","$document","uiGridCellNavService","gridUtil","uiGridCellNavConstants","uiGridConstants","GridRowColumn",function(a,b,c,d,e,f,g){return{priority:-150,restrict:"A",require:["^uiGrid","?^uiGridCellnav"],scope:!1,link:function(a,b,c,d){function f(a){a.preventDefault()}function h(){if(!a.focused){var c=b.find("div");c.addClass("ui-grid-cell-focus"),b.attr("aria-selected",!0),k.setAriaActivedescendant(b.attr("id")),a.focused=!0}}function i(){if(a.focused){var c=b.find("div");c.removeClass("ui-grid-cell-focus"),b.attr("aria-selected",!1),k.removeAriaActivedescendant(b.attr("id")),a.focused=!1}}var j=d[0],k=d[1];if(j.grid.api.cellNav&&a.col.colDef.allowCellFocus){var l=j.grid;a.focused=!1,b.attr("tabindex",-1),b.find("div").on("click",function(b){j.cellNav.broadcastCellNav(new g(a.row,a.col),b.ctrlKey||b.metaKey,b),b.stopPropagation(),a.$apply()}),b.on("mousedown",f),j.grid.api.edit&&(j.grid.api.edit.on.beginCellEdit(a,function(){b.off("mousedown",f)}),j.grid.api.edit.on.afterCellEdit(a,function(){b.on("mousedown",f)}),j.grid.api.edit.on.cancelCellEdit(a,function(){b.on("mousedown",f)})),b.on("focus",function(b){j.cellNav.broadcastCellNav(new g(a.row,a.col),!1,b),b.stopPropagation(),a.$apply()}),a.$on(e.CELL_NAV_EVENT,function(b,c,d){var e=l.cellNav.focusedCells.some(function(b,c){return b.row===a.row&&b.col===a.col});e?h():i()}),a.$on("$destroy",function(){b.find("div").off(),b.off()})}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.edit",["ui.grid"]);a.constant("uiGridEditConstants",{EDITABLE_CELL_TEMPLATE:/EDITABLE_CELL_TEMPLATE/g,EDITABLE_CELL_DIRECTIVE:/editable_cell_directive/g,events:{BEGIN_CELL_EDIT:"uiGridEventBeginCellEdit",END_CELL_EDIT:"uiGridEventEndCellEdit",CANCEL_CELL_EDIT:"uiGridEventCancelCellEdit"}}),a.service("uiGridEditService",["$q","uiGridConstants","gridUtil",function(a,b,c){var d={initializeGrid:function(a){d.defaultGridOptions(a.options),a.registerColumnBuilder(d.editColumnBuilder),a.edit={};var b={events:{edit:{afterCellEdit:function(a,b,c,d){},beginCellEdit:function(a,b,c){},cancelCellEdit:function(a,b){}}},methods:{edit:{}}};a.api.registerEventsFromObject(b.events)},defaultGridOptions:function(a){a.cellEditableCondition=void 0===a.cellEditableCondition?!0:a.cellEditableCondition,a.enableCellEditOnFocus=void 0===a.enableCellEditOnFocus?!1:a.enableCellEditOnFocus},editColumnBuilder:function(b,d,e){var f=[];return b.enableCellEdit=void 0===b.enableCellEdit?void 0===e.enableCellEdit?"object"!==b.type:e.enableCellEdit:b.enableCellEdit,b.cellEditableCondition=void 0===b.cellEditableCondition?e.cellEditableCondition:b.cellEditableCondition,b.enableCellEdit&&(b.editableCellTemplate=b.editableCellTemplate||e.editableCellTemplate||"ui-grid/cellEditor",f.push(c.getTemplate(b.editableCellTemplate).then(function(a){d.editableCellTemplate=a},function(a){throw new Error("Couldn't fetch/use colDef.editableCellTemplate '"+b.editableCellTemplate+"'")}))),b.enableCellEditOnFocus=void 0===b.enableCellEditOnFocus?e.enableCellEditOnFocus:b.enableCellEditOnFocus,a.all(f)},isStartEditKey:function(a){return a.metaKey||a.keyCode===b.keymap.ESC||a.keyCode===b.keymap.SHIFT||a.keyCode===b.keymap.CTRL||a.keyCode===b.keymap.ALT||a.keyCode===b.keymap.WIN||a.keyCode===b.keymap.CAPSLOCK||a.keyCode===b.keymap.LEFT||a.keyCode===b.keymap.TAB&&a.shiftKey||a.keyCode===b.keymap.RIGHT||a.keyCode===b.keymap.TAB||a.keyCode===b.keymap.UP||a.keyCode===b.keymap.ENTER&&a.shiftKey||a.keyCode===b.keymap.DOWN||a.keyCode===b.keymap.ENTER?!1:!0}};return d}]),a.directive("uiGridEdit",["gridUtil","uiGridEditService",function(a,b){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.initializeGrid(e.grid)},post:function(a,b,c,d){}}}}}]),a.directive("uiGridViewport",["uiGridEditConstants",function(a){return{replace:!0,priority:-99998,require:["^uiGrid","^uiGridRenderContainer"],scope:!1,compile:function(){return{post:function(b,c,d,e){var f=e[0];if(f.grid.api.edit&&f.grid.api.cellNav){var g=e[1].containerId;"body"===g&&(b.$on(a.events.CANCEL_CELL_EDIT,function(){f.focus()}),b.$on(a.events.END_CELL_EDIT,function(){f.focus()}))}}}}}}]),a.directive("uiGridCell",["$compile","$injector","$timeout","uiGridConstants","uiGridEditConstants","gridUtil","$parse","uiGridEditService","$rootScope","$q",function(a,b,c,d,e,f,g,h,i,j){var k=500;if(b.has("uiGridCellNavService")){b.get("uiGridCellNavService")}return{priority:-100,restrict:"A",scope:!1,require:"?^uiGrid",link:function(b,l,m,n){function o(){l.on("dblclick",u),l.on("touchstart",p),n&&n.grid.api.cellNav&&(G=n.grid.api.cellNav.on.viewPortKeyDown(b,function(a,c){null!==c&&(c.row!==b.row||c.col!==b.col||b.col.colDef.enableCellEditOnFocus||s(a))}),F=n.grid.api.cellNav.on.navigate(b,function(a,d){b.col.colDef.enableCellEditOnFocus&&(d&&a.row===d.row&&a.col===d.col||a.row!==b.row||a.col!==b.col||c(function(){u()}))})),b.beginEditEventsWired=!0}function p(a){"undefined"!=typeof a.originalEvent&&void 0!==a.originalEvent&&(a=a.originalEvent),l.on("touchend",q),C=c(function(){},k),C.then(function(){setTimeout(u,0),l.off("touchend",q)})}function q(a){c.cancel(C),l.off("touchend",q)}function r(){l.off("dblclick",u),l.off("keydown",s),l.off("touchstart",p),F(),G(),b.beginEditEventsWired=!1}function s(a){h.isStartEditKey(a)&&u(a)}function t(a,c){return!c.isSaving&&(angular.isFunction(a.colDef.cellEditableCondition)?a.colDef.cellEditableCondition(b):a.colDef.cellEditableCondition)}function u(a){b.grid.api.core.scrollToIfNecessary(b.row,b.col).then(function(){v(a)})}function v(h){if(!E&&t(b.col,b.row)){B=g(b.row.getQualifiedColField(b.col)),A=B(b),z=b.col.editableCellTemplate,z=b.col.colDef.editModelField?z.replace(d.MODEL_COL_FIELD,f.preEval("row.entity."+b.col.colDef.editModelField)):z.replace(d.MODEL_COL_FIELD,b.row.getQualifiedColField(b.col)),z=z.replace(d.COL_FIELD,"grid.getCellValue(row, col)");var k=b.col.colDef.editDropdownFilter?"|"+b.col.colDef.editDropdownFilter:"";z=z.replace(d.CUSTOM_FILTERS,k);var m="text";switch(b.col.colDef.type){case"boolean":m="checkbox";break;case"number":m="number";break;case"date":m="date"}z=z.replace("INPUT_TYPE",m);var n=b.col.colDef.editDropdownOptionsFunction;if(n)j.when(n(b.row.entity,b.col.colDef)).then(function(a){b.editDropdownOptionsArray=a});else{var o=b.col.colDef.editDropdownRowEntityOptionsArrayPath;o?b.editDropdownOptionsArray=y(b.row.entity,o):b.editDropdownOptionsArray=b.col.colDef.editDropdownOptionsArray}b.editDropdownIdLabel=b.col.colDef.editDropdownIdLabel?b.col.colDef.editDropdownIdLabel:"id",b.editDropdownValueLabel=b.col.colDef.editDropdownValueLabel?b.col.colDef.editDropdownValueLabel:"value";var p=function(){E=!0,r();var c=angular.element(z);l.append(c),D=b.$new(),a(c)(D);var d=angular.element(l.children()[0]);d.addClass("ui-grid-cell-contents-hidden")};i.$$phase?p():b.$apply(p);var q=b.col.grid.api.core.on.scrollBegin(b,function(){b.grid.disableScrolling||(w(),b.grid.api.edit.raise.afterCellEdit(b.row.entity,b.col.colDef,B(b),A),q(),s(),u())}),s=b.$on(e.events.END_CELL_EDIT,function(){w(),b.grid.api.edit.raise.afterCellEdit(b.row.entity,b.col.colDef,B(b),A),s(),q(),u()}),u=b.$on(e.events.CANCEL_CELL_EDIT,function(){x(),u(),q(),s()});b.$broadcast(e.events.BEGIN_CELL_EDIT,h),c(function(){b.grid.api.edit.raise.beginCellEdit(b.row.entity,b.col.colDef,h)})}}function w(){if(b.grid.disableScrolling=!1,E){n&&n.grid.api.cellNav&&n.focus();var a=angular.element(l.children()[0]);D.$destroy(),angular.element(l.children()[1]).remove(),a.removeClass("ui-grid-cell-contents-hidden"),E=!1,o(),b.grid.api.core.notifyDataChange(d.dataChange.EDIT)}}function x(){b.grid.disableScrolling=!1,E&&(B.assign(b,A),b.$apply(),b.grid.api.edit.raise.cancelCellEdit(b.row.entity,b.col.colDef),w())}function y(a,b){b=b.replace(/\[(\w+)\]/g,".$1"),b=b.replace(/^\./,"");for(var c=b.split(".");c.length;){var d=c.shift();if(!(d in a))return;a=a[d]}return a}var z,A,B,C,D,E=!1;if(b.col.colDef.enableCellEdit){var F=function(){},G=function(){},H=function(){b.col.colDef.enableCellEdit&&b.row.enableCellEdit!==!1?b.beginEditEventsWired||o():b.beginEditEventsWired&&r()};H();var I=b.$watch("row",function(a,b){a!==b&&H()});b.$on("$destroy",I)}}}}]),a.directive("uiGridEditor",["gridUtil","uiGridConstants","uiGridEditConstants","$timeout","uiGridEditService",function(a,b,c,d,e){return{scope:!0,require:["?^uiGrid","?^uiGridRenderContainer","ngModel"],compile:function(){return{pre:function(a,b,c){},post:function(a,f,g,h){var i,j,k;h[0]&&(i=h[0]),h[1]&&(j=h[1]),h[2]&&(k=h[2]),a.$on(c.events.BEGIN_CELL_EDIT,function(b,c){if(d(function(){if(f[0].focus(),f[0].select&&a.col.colDef.enableCellEditOnFocus||!i||!i.grid.api.cellNav)f[0].select();else try{f[0].setSelectionRange(f[0].value.length,f[0].value.length)}catch(b){}}),i&&i.grid.api.cellNav)var g=i.grid.api.cellNav.on.viewPortKeyPress(a,function(a,b){e.isStartEditKey(a)&&(k.$setViewValue(String.fromCharCode("number"==typeof a.which?a.which:a.keyCode),a),k.$render()),g()});f.on("blur",function(b){a.stopEdit(b)})}),a.deepEdit=!1,a.stopEdit=function(b){a.inputForm&&!a.inputForm.$valid?(b.stopPropagation(),a.$emit(c.events.CANCEL_CELL_EDIT)):a.$emit(c.events.END_CELL_EDIT),a.deepEdit=!1},f.on("click",function(b){"checkbox"!==f[0].type&&(a.deepEdit=!0,d(function(){a.grid.disableScrolling=!0}))}),f.on("keydown",function(d){switch(d.keyCode){case b.keymap.ESC:d.stopPropagation(),a.$emit(c.events.CANCEL_CELL_EDIT)}if(!a.deepEdit||d.keyCode!==b.keymap.LEFT&&d.keyCode!==b.keymap.RIGHT&&d.keyCode!==b.keymap.UP&&d.keyCode!==b.keymap.DOWN)if(i&&i.grid.api.cellNav)d.uiGridTargetRenderContainerId=j.containerId,null!==i.cellNav.handleKeyDown(d)&&a.stopEdit(d);else switch(d.keyCode){case b.keymap.ENTER:case b.keymap.TAB:d.stopPropagation(),d.preventDefault(),a.stopEdit(d)}else d.stopPropagation();return!0})}}}}}]),a.directive("uiGridEditor",["$filter",function(a){function b(a){if("undefined"==typeof a||""===a)return null;var b=a.split("-");if(3!==b.length)return null;var c=parseInt(b[0],10),d=parseInt(b[1],10),e=parseInt(b[2],10);return 1>d||1>c||1>e?null:new Date(c,d-1,e)}return{priority:-100,require:"?ngModel",link:function(c,d,e,f){2===angular.version.minor&&e.type&&"date"===e.type&&f&&(f.$formatters.push(function(b){return f.$setValidity(null,!b||!isNaN(b.getTime())),a("date")(b,"yyyy-MM-dd")}),f.$parsers.push(function(a){if(a&&a.length>0){var c=b(a);return f.$setValidity(null,c&&!isNaN(c.getTime())),c}return f.$setValidity(null,!0),null}))}}}]),a.directive("uiGridEditDropdown",["uiGridConstants","uiGridEditConstants",function(a,b){return{require:["?^uiGrid","?^uiGridRenderContainer"],scope:!0,compile:function(){return{pre:function(a,b,c){},post:function(c,d,e,f){var g=f[0],h=f[1];c.$on(b.events.BEGIN_CELL_EDIT,function(){d[0].focus(),d[0].style.width=d[0].parentElement.offsetWidth-1+"px",d.on("blur",function(a){c.stopEdit(a)})}),c.stopEdit=function(a){c.$emit(b.events.END_CELL_EDIT)},d.on("keydown",function(d){switch(d.keyCode){case a.keymap.ESC:d.stopPropagation(),c.$emit(b.events.CANCEL_CELL_EDIT)}if(g&&g.grid.api.cellNav)d.uiGridTargetRenderContainerId=h.containerId,null!==g.cellNav.handleKeyDown(d)&&c.stopEdit(d);else switch(d.keyCode){case a.keymap.ENTER:case a.keymap.TAB:d.stopPropagation(),d.preventDefault(),c.stopEdit(d)}return!0})}}}}}]),a.directive("uiGridEditFileChooser",["gridUtil","uiGridConstants","uiGridEditConstants","$timeout",function(a,b,c,d){return{scope:!0,require:["?^uiGrid","?^uiGridRenderContainer"],compile:function(){return{pre:function(a,b,c){},post:function(b,d,e,f){var g,h;f[0]&&(g=f[0]),f[1]&&(h=f[1]);var i=(g.grid,function(d){var e=d.srcElement||d.target;e&&e.files&&e.files.length>0?("function"==typeof b.col.colDef.editFileChooserCallback?b.col.colDef.editFileChooserCallback(b.row,b.col,e.files):a.logError("You need to set colDef.editFileChooserCallback to use the file chooser"),e.form.reset(),b.$emit(c.events.END_CELL_EDIT)):b.$emit(c.events.CANCEL_CELL_EDIT)});d[0].addEventListener("change",i,!1),b.$on(c.events.BEGIN_CELL_EDIT,function(){d[0].focus(),d[0].select(),d.on("blur",function(a){b.$emit(c.events.END_CELL_EDIT)})})}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.expandable",["ui.grid"]);a.service("uiGridExpandableService",["gridUtil","$compile",function(a,b){var c={initializeGrid:function(b){b.expandable={},b.expandable.expandedAll=!1,b.options.enableExpandable=b.options.enableExpandable!==!1,b.options.expandableRowHeight=b.options.expandableRowHeight||150,b.options.expandableRowHeaderWidth=b.options.expandableRowHeaderWidth||40,b.options.enableExpandable&&!b.options.expandableRowTemplate&&(a.logError("You have not set the expandableRowTemplate, disabling expandable module"),b.options.enableExpandable=!1);var d={events:{expandable:{rowExpandedBeforeStateChanged:function(a,b){},rowExpandedStateChanged:function(a,b){}}},methods:{expandable:{toggleRowExpansion:function(a){var d=b.getRow(a);null!==d&&c.toggleRowExpansion(b,d)},expandAllRows:function(){c.expandAllRows(b)},collapseAllRows:function(){c.collapseAllRows(b)},toggleAllRows:function(){c.toggleAllRows(b)},expandRow:function(a){var d=b.getRow(a);null===d||d.isExpanded||c.toggleRowExpansion(b,d)},collapseRow:function(a){var d=b.getRow(a);null!==d&&d.isExpanded&&c.toggleRowExpansion(b,d)},getExpandedRows:function(){return c.getExpandedRows(b).map(function(a){return a.entity})}}}};b.api.registerEventsFromObject(d.events),b.api.registerMethodsFromObject(d.methods)},toggleRowExpansion:function(a,b){a.api.expandable.raise.rowExpandedBeforeStateChanged(b),b.isExpanded=!b.isExpanded,angular.isUndefined(b.expandedRowHeight)&&(b.expandedRowHeight=a.options.expandableRowHeight),b.isExpanded?b.height=b.grid.options.rowHeight+b.expandedRowHeight:(b.height=b.grid.options.rowHeight,a.expandable.expandedAll=!1),a.api.expandable.raise.rowExpandedStateChanged(b)},expandAllRows:function(a,b){a.renderContainers.body.visibleRowCache.forEach(function(b){b.isExpanded||c.toggleRowExpansion(a,b)}),a.expandable.expandedAll=!0,a.queueGridRefresh()},collapseAllRows:function(a){a.renderContainers.body.visibleRowCache.forEach(function(b){b.isExpanded&&c.toggleRowExpansion(a,b)}),a.expandable.expandedAll=!1,a.queueGridRefresh()},toggleAllRows:function(a){a.expandable.expandedAll?c.collapseAllRows(a):c.expandAllRows(a)},getExpandedRows:function(a){return a.rows.filter(function(a){return a.isExpanded})}};return c}]),a.directive("uiGridExpandable",["uiGridExpandableService","$templateCache",function(a,b){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(c,d,e,f){if(f.grid.options.enableExpandableRowHeader!==!1){var g={name:"expandableButtons",displayName:"",exporterSuppressExport:!0,enableColumnResizing:!1,enableColumnMenu:!1,width:f.grid.options.expandableRowHeaderWidth||40};g.cellTemplate=b.get("ui-grid/expandableRowHeader"),g.headerCellTemplate=b.get("ui-grid/expandableTopRowHeader"),f.grid.addRowHeaderColumn(g)}a.initializeGrid(f.grid)},post:function(a,b,c,d){}}}}}]),a.directive("uiGrid",["uiGridExpandableService","$templateCache",function(a,b){return{replace:!0,priority:599,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,b,c,d){d.grid.api.core.on.renderingComplete(a,function(){a.row&&a.row.grid&&a.row.grid.options&&a.row.grid.options.enableExpandable&&(d.grid.parentRow=a.row)})},post:function(a,b,c,d){}}}}}]),a.directive("uiGridExpandableRow",["uiGridExpandableService","$timeout","$compile","uiGridConstants","gridUtil","$interval","$log",function(a,b,c,d,e,f,g){return{replace:!1,priority:0,scope:!1,compile:function(){return{pre:function(a,b,d,f){e.getTemplate(a.grid.options.expandableRowTemplate).then(function(d){if(a.grid.options.expandableRowScope){var e=a.grid.options.expandableRowScope;for(var f in e)e.hasOwnProperty(f)&&(a[f]=e[f])}var g=c(d)(a);b.append(g),a.row.expandedRendered=!0})},post:function(a,b,c,d){a.$on("$destroy",function(){a.row.expandedRendered=!1})}}}}}]),a.directive("uiGridRow",["$compile","gridUtil","$templateCache",function(a,b,c){return{priority:-200,scope:!1,compile:function(a,b){return{pre:function(a,b,c,d){a.expandableRow={},a.expandableRow.shouldRenderExpand=function(){var b="body"===a.colContainer.name&&a.grid.options.enableExpandable!==!1&&a.row.isExpanded&&(!a.grid.isScrollingVertically||a.row.expandedRendered);return b},a.expandableRow.shouldRenderFiller=function(){var b=a.row.isExpanded&&("body"!==a.colContainer.name||a.grid.isScrollingVertically&&!a.row.expandedRendered);return b}},post:function(a,b,c,d){}}}}}]),a.directive("uiGridViewport",["$compile","gridUtil","$templateCache",function(a,b,c){return{priority:-200,scope:!1,compile:function(a,b){var d=angular.element(a.children().children()[0]),e=c.get("ui-grid/expandableScrollFiller"),f=c.get("ui-grid/expandableRow");return d.append(f),d.append(e),{pre:function(a,b,c,d){},post:function(a,b,c,d){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.exporter",["ui.grid"]);a.constant("uiGridExporterConstants",{featureName:"exporter",ALL:"all",VISIBLE:"visible",SELECTED:"selected",CSV_CONTENT:"CSV_CONTENT",BUTTON_LABEL:"BUTTON_LABEL",FILE_NAME:"FILE_NAME"}),a.service("uiGridExporterService",["$q","uiGridExporterConstants","gridUtil","$compile","$interval","i18nService",function(a,b,c,d,e,f){var g={delay:100,initializeGrid:function(a){a.exporter={},this.defaultGridOptions(a.options);var b={events:{exporter:{}},methods:{exporter:{csvExport:function(b,c){g.csvExport(a,b,c)},pdfExport:function(b,c){g.pdfExport(a,b,c)}}}};a.api.registerEventsFromObject(b.events),a.api.registerMethodsFromObject(b.methods),a.api.core.addToGridMenu?g.addToMenu(a):e(function(){a.api.core.addToGridMenu&&g.addToMenu(a)},this.delay,1)},defaultGridOptions:function(a){a.exporterSuppressMenu=a.exporterSuppressMenu===!0,a.exporterMenuLabel=a.exporterMenuLabel?a.exporterMenuLabel:"Export",a.exporterSuppressColumns=a.exporterSuppressColumns?a.exporterSuppressColumns:[],a.exporterCsvColumnSeparator=a.exporterCsvColumnSeparator?a.exporterCsvColumnSeparator:",",a.exporterCsvFilename=a.exporterCsvFilename?a.exporterCsvFilename:"download.csv",a.exporterPdfFilename=a.exporterPdfFilename?a.exporterPdfFilename:"download.pdf",a.exporterOlderExcelCompatibility=a.exporterOlderExcelCompatibility===!0,a.exporterPdfDefaultStyle=a.exporterPdfDefaultStyle?a.exporterPdfDefaultStyle:{fontSize:11},a.exporterPdfTableStyle=a.exporterPdfTableStyle?a.exporterPdfTableStyle:{margin:[0,5,0,15]},a.exporterPdfTableHeaderStyle=a.exporterPdfTableHeaderStyle?a.exporterPdfTableHeaderStyle:{bold:!0,fontSize:12,color:"black"},a.exporterPdfHeader=a.exporterPdfHeader?a.exporterPdfHeader:null,a.exporterPdfFooter=a.exporterPdfFooter?a.exporterPdfFooter:null,a.exporterPdfOrientation=a.exporterPdfOrientation?a.exporterPdfOrientation:"landscape",a.exporterPdfPageSize=a.exporterPdfPageSize?a.exporterPdfPageSize:"A4",a.exporterPdfMaxGridWidth=a.exporterPdfMaxGridWidth?a.exporterPdfMaxGridWidth:720,a.exporterMenuAllData=void 0!==a.exporterMenuAllData?a.exporterMenuAllData:!0,a.exporterMenuVisibleData=void 0!==a.exporterMenuVisibleData?a.exporterMenuVisibleData:!0,a.exporterMenuSelectedData=void 0!==a.exporterMenuSelectedData?a.exporterMenuSelectedData:!0,a.exporterMenuCsv=void 0!==a.exporterMenuCsv?a.exporterMenuCsv:!0,a.exporterMenuPdf=void 0!==a.exporterMenuPdf?a.exporterMenuPdf:!0,a.exporterPdfCustomFormatter=a.exporterPdfCustomFormatter&&"function"==typeof a.exporterPdfCustomFormatter?a.exporterPdfCustomFormatter:function(a){return a},a.exporterHeaderFilterUseName=a.exporterHeaderFilterUseName===!0,a.exporterFieldCallback=a.exporterFieldCallback?a.exporterFieldCallback:function(a,b,c,d){return d},a.exporterAllDataFn=a.exporterAllDataFn?a.exporterAllDataFn:null,null==a.exporterAllDataFn&&a.exporterAllDataPromise&&(a.exporterAllDataFn=a.exporterAllDataPromise)},addToMenu:function(a){a.api.core.addToGridMenu(a,[{title:f.getSafeText("gridMenu.exporterAllAsCsv"),action:function(a){this.grid.api.exporter.csvExport(b.ALL,b.ALL)},shown:function(){return this.grid.options.exporterMenuCsv&&this.grid.options.exporterMenuAllData},order:200},{title:f.getSafeText("gridMenu.exporterVisibleAsCsv"),action:function(a){this.grid.api.exporter.csvExport(b.VISIBLE,b.VISIBLE)},shown:function(){return this.grid.options.exporterMenuCsv&&this.grid.options.exporterMenuVisibleData},order:201},{title:f.getSafeText("gridMenu.exporterSelectedAsCsv"),action:function(a){this.grid.api.exporter.csvExport(b.SELECTED,b.VISIBLE)},shown:function(){return this.grid.options.exporterMenuCsv&&this.grid.options.exporterMenuSelectedData&&this.grid.api.selection&&this.grid.api.selection.getSelectedRows().length>0},order:202},{title:f.getSafeText("gridMenu.exporterAllAsPdf"),action:function(a){this.grid.api.exporter.pdfExport(b.ALL,b.ALL)},shown:function(){return this.grid.options.exporterMenuPdf&&this.grid.options.exporterMenuAllData},order:203},{title:f.getSafeText("gridMenu.exporterVisibleAsPdf"),action:function(a){this.grid.api.exporter.pdfExport(b.VISIBLE,b.VISIBLE)},shown:function(){return this.grid.options.exporterMenuPdf&&this.grid.options.exporterMenuVisibleData},order:204},{title:f.getSafeText("gridMenu.exporterSelectedAsPdf"),action:function(a){this.grid.api.exporter.pdfExport(b.SELECTED,b.VISIBLE)},shown:function(){return this.grid.options.exporterMenuPdf&&this.grid.options.exporterMenuSelectedData&&this.grid.api.selection&&this.grid.api.selection.getSelectedRows().length>0},order:205}])},csvExport:function(a,b,c){var d=this;this.loadAllDataIfNeeded(a,b,c).then(function(){var e=a.options.showHeader?d.getColumnHeaders(a,c):[],f=d.getData(a,b,c),g=d.formatAsCsv(e,f,a.options.exporterCsvColumnSeparator);d.downloadFile(a.options.exporterCsvFilename,g,a.options.exporterOlderExcelCompatibility)})},loadAllDataIfNeeded:function(c,d,e){if(d===b.ALL&&c.rows.length!==c.options.totalItems&&c.options.exporterAllDataFn)return c.options.exporterAllDataFn().then(function(){c.modifyRows(c.options.data)});var f=a.defer();return f.resolve(),f.promise},getColumnHeaders:function(a,c){var d,e=[];if(c===b.ALL)d=a.columns;else{var f=a.renderContainers.left?a.renderContainers.left.visibleColumnCache.filter(function(a){return a.visible}):[],g=a.renderContainers.body?a.renderContainers.body.visibleColumnCache.filter(function(a){return a.visible}):[],h=a.renderContainers.right?a.renderContainers.right.visibleColumnCache.filter(function(a){return a.visible}):[];d=f.concat(g,h)}return d.forEach(function(b,c){b.colDef.exporterSuppressExport!==!0&&-1===a.options.exporterSuppressColumns.indexOf(b.name)&&e.push({name:b.field,displayName:a.options.exporterHeaderFilter?a.options.exporterHeaderFilterUseName?a.options.exporterHeaderFilter(b.name):a.options.exporterHeaderFilter(b.displayName):b.displayName,width:b.drawnWidth?b.drawnWidth:b.width,align:"number"===b.colDef.type?"right":"left"})}),e},getData:function(a,d,e,f){var g,h,i=[];switch(d){case b.ALL:g=a.rows;break;case b.VISIBLE:g=a.getVisibleRows();break;case b.SELECTED:a.api.selection?g=a.api.selection.getSelectedGridRows():c.logError("selection feature must be enabled to allow selected rows to be exported")}if(e===b.ALL)h=a.columns;else{ -var j=a.renderContainers.left?a.renderContainers.left.visibleColumnCache.filter(function(a){return a.visible}):[],k=a.renderContainers.body?a.renderContainers.body.visibleColumnCache.filter(function(a){return a.visible}):[],l=a.renderContainers.right?a.renderContainers.right.visibleColumnCache.filter(function(a){return a.visible}):[];h=j.concat(k,l)}return g.forEach(function(c,d){if(c.exporterEnableExporting!==!1){var g=[];h.forEach(function(d,h){if((d.visible||e===b.ALL)&&d.colDef.exporterSuppressExport!==!0&&-1===a.options.exporterSuppressColumns.indexOf(d.name)){var i=f?a.getCellDisplayValue(c,d):a.getCellValue(c,d),j={value:a.options.exporterFieldCallback(a,c,d,i)};d.colDef.exporterPdfAlign&&(j.alignment=d.colDef.exporterPdfAlign),g.push(j)}}),i.push(g)}}),i},formatAsCsv:function(a,b,c){var d=this,e=a.map(function(a){return{value:a.displayName}}),f=e.length>0?d.formatRowAsCsv(this,c)(e)+"\n":"";return f+=b.map(this.formatRowAsCsv(this,c)).join("\n")},formatRowAsCsv:function(a,b){return function(c){return c.map(a.formatFieldAsCsv).join(b)}},formatFieldAsCsv:function(a){return null==a.value?"":"number"==typeof a.value?a.value:"boolean"==typeof a.value?a.value?"TRUE":"FALSE":"string"==typeof a.value?'"'+a.value.replace(/"/g,'""')+'"':JSON.stringify(a.value)},isIE:function(){var a=navigator.userAgent.search(/(?:Edge|MSIE|Trident\/.*; rv:)/),b=!1;return-1!==a&&(b=!0),b},downloadFile:function(a,b,c){var d,e,f=document,g=f.createElement("a"),h="application/octet-stream;charset=utf-8";if(e=this.isIE(),e&&10>e){var i=f.createElement("iframe");return document.body.appendChild(i),i.contentWindow.document.open("text/html","replace"),i.contentWindow.document.write("sep=,\r\n"+b),i.contentWindow.document.close(),i.contentWindow.focus(),i.contentWindow.document.execCommand("SaveAs",!0,a),document.body.removeChild(i),!0}if(navigator.msSaveBlob)return navigator.msSaveOrOpenBlob(new Blob([c?"\ufeff":"",b],{type:h}),a);if("download"in g){var j=new Blob([c?"\ufeff":"",b],{type:h});d=URL.createObjectURL(j),g.setAttribute("download",a)}else d="data:"+h+","+encodeURIComponent(b),g.setAttribute("target","_blank");g.href=d,g.setAttribute("style","display:none;"),f.body.appendChild(g),setTimeout(function(){if(g.click)g.click();else if(document.createEvent){var a=document.createEvent("MouseEvents");a.initEvent("click",!0,!0),g.dispatchEvent(a)}f.body.removeChild(g)},this.delay)},pdfExport:function(a,b,c){var d=this;this.loadAllDataIfNeeded(a,b,c).then(function(){var e=d.getColumnHeaders(a,c),f=d.getData(a,b,c),g=d.prepareAsPdf(a,e,f);d.isIE()||-1!==navigator.appVersion.indexOf("Edge")?d.downloadPDF(a.options.exporterPdfFilename,g):pdfMake.createPdf(g).open()})},downloadPDF:function(a,b){var c,d=document;d.createElement("a");c=this.isIE();var e,f=pdfMake.createPdf(b);f.getBuffer(function(b){if(e=new Blob([b]),navigator.msSaveBlob)return navigator.msSaveBlob(e,a);if(c){var f=d.createElement("iframe");return document.body.appendChild(f),f.contentWindow.document.open("text/html","replace"),f.contentWindow.document.write(e),f.contentWindow.document.close(),f.contentWindow.focus(),f.contentWindow.document.execCommand("SaveAs",!0,a),document.body.removeChild(f),!0}})},prepareAsPdf:function(a,b,c){var d=this.calculatePdfHeaderWidths(a,b),e=b.map(function(a){return{text:a.displayName,style:"tableHeader"}}),f=c.map(this.formatRowAsPdf(this)),g=[e].concat(f),h={pageOrientation:a.options.exporterPdfOrientation,pageSize:a.options.exporterPdfPageSize,content:[{style:"tableStyle",table:{headerRows:1,widths:d,body:g}}],styles:{tableStyle:a.options.exporterPdfTableStyle,tableHeader:a.options.exporterPdfTableHeaderStyle},defaultStyle:a.options.exporterPdfDefaultStyle};return a.options.exporterPdfLayout&&(h.layout=a.options.exporterPdfLayout),a.options.exporterPdfHeader&&(h.header=a.options.exporterPdfHeader),a.options.exporterPdfFooter&&(h.footer=a.options.exporterPdfFooter),a.options.exporterPdfCustomFormatter&&(h=a.options.exporterPdfCustomFormatter(h)),h},calculatePdfHeaderWidths:function(a,b){var c=0;b.forEach(function(a){"number"==typeof a.width&&(c+=a.width)});var d=0;b.forEach(function(a){if("*"===a.width&&(d+=100),"string"==typeof a.width&&a.width.match(/(\d)*%/)){var b=parseInt(a.width.match(/(\d)*%/)[0]);a.width=c*b/100,d+=a.width}});var e=c+d;return b.map(function(b){return"*"===b.width?b.width:b.width*a.options.exporterPdfMaxGridWidth/e})},formatRowAsPdf:function(a){return function(b){return b.map(a.formatFieldAsPdfString)}},formatFieldAsPdfString:function(a){var b;return b=null==a.value?"":"number"==typeof a.value?a.value.toString():"boolean"==typeof a.value?a.value?"TRUE":"FALSE":"string"==typeof a.value?a.value.replace(/"/g,'""'):JSON.stringify(a.value).replace(/^"/,"").replace(/"$/,""),a.alignment&&"string"==typeof a.alignment&&(b={text:b,alignment:a.alignment}),b}};return g}]),a.directive("uiGridExporter",["uiGridExporterConstants","uiGridExporterService","gridUtil","$compile",function(a,b,c,d){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,link:function(a,c,d,e){b.initializeGrid(e.grid),e.grid.exporter.$scope=a}}}])}(),function(){"use strict";var a=angular.module("ui.grid.grouping",["ui.grid","ui.grid.treeBase"]);a.constant("uiGridGroupingConstants",{featureName:"grouping",rowHeaderColName:"treeBaseRowHeaderCol",EXPANDED:"expanded",COLLAPSED:"collapsed",aggregation:{COUNT:"count",SUM:"sum",MAX:"max",MIN:"min",AVG:"avg"}}),a.service("uiGridGroupingService",["$q","uiGridGroupingConstants","gridUtil","rowSorter","GridRow","gridClassFactory","i18nService","uiGridConstants","uiGridTreeBaseService",function(a,b,c,d,e,f,g,h,i){var j={initializeGrid:function(a,b){i.initializeGrid(a,b),a.grouping={},a.grouping.groupHeaderCache={},j.defaultGridOptions(a.options),a.registerRowsProcessor(j.groupRows,400),a.registerColumnBuilder(j.groupingColumnBuilder),a.registerColumnsProcessor(j.groupingColumnProcessor,400);var c={events:{grouping:{aggregationChanged:{},groupingChanged:{}}},methods:{grouping:{getGrouping:function(b){var c=j.getGrouping(a);return c.grouping.forEach(function(a){a.colName=a.col.name,delete a.col}),c.aggregations.forEach(function(a){a.colName=a.col.name,delete a.col}),c.aggregations=c.aggregations.filter(function(a){return!a.aggregation.source||"grouping"!==a.aggregation.source}),b&&(c.rowExpandedStates=j.getRowExpandedStates(a.grouping.groupingHeaderCache)),c},setGrouping:function(b){j.setGrouping(a,b)},groupColumn:function(b){var c=a.getColumn(b);j.groupColumn(a,c)},ungroupColumn:function(b){var c=a.getColumn(b);j.ungroupColumn(a,c)},clearGrouping:function(){j.clearGrouping(a)},aggregateColumn:function(b,c,d){var e=a.getColumn(b);j.aggregateColumn(a,e,c,d)}}}};a.api.registerEventsFromObject(c.events),a.api.registerMethodsFromObject(c.methods),a.api.core.on.sortChanged(b,j.tidyPriorities)},defaultGridOptions:function(a){a.enableGrouping=a.enableGrouping!==!1,a.groupingShowCounts=a.groupingShowCounts!==!1,a.groupingNullLabel="undefined"==typeof a.groupingNullLabel?"Null":a.groupingNullLabel,a.enableGroupHeaderSelection=a.enableGroupHeaderSelection===!0},groupingColumnBuilder:function(a,d,e){if(a.enableGrouping!==!1){"undefined"==typeof d.grouping&&"undefined"!=typeof a.grouping?(d.grouping=angular.copy(a.grouping),"undefined"!=typeof d.grouping.groupPriority&&d.grouping.groupPriority>-1&&(d.treeAggregationFn=i.nativeAggregations()[b.aggregation.COUNT].aggregationFn,d.treeAggregationFinalizerFn=j.groupedFinalizerFn)):"undefined"==typeof d.grouping&&(d.grouping={}),"undefined"!=typeof d.grouping&&"undefined"!=typeof d.grouping.groupPriority&&d.grouping.groupPriority>=0&&(d.suppressRemoveSort=!0);var f={name:"ui.grid.grouping.group",title:g.get().grouping.group,icon:"ui-grid-icon-indent-right",shown:function(){return"undefined"==typeof this.context.col.grouping||"undefined"==typeof this.context.col.grouping.groupPriority||this.context.col.grouping.groupPriority<0},action:function(){j.groupColumn(this.context.col.grid,this.context.col)}},h={name:"ui.grid.grouping.ungroup",title:g.get().grouping.ungroup,icon:"ui-grid-icon-indent-left",shown:function(){return"undefined"!=typeof this.context.col.grouping&&"undefined"!=typeof this.context.col.grouping.groupPriority&&this.context.col.grouping.groupPriority>=0},action:function(){j.ungroupColumn(this.context.col.grid,this.context.col)}},k={name:"ui.grid.grouping.aggregateRemove",title:g.get().grouping.aggregate_remove,shown:function(){return"undefined"!=typeof this.context.col.treeAggregationFn},action:function(){j.aggregateColumn(this.context.col.grid,this.context.col,null)}},l=function(a,b){b=b||g.get().grouping["aggregate_"+a]||a;var e={name:"ui.grid.grouping.aggregate"+a,title:b,shown:function(){return"undefined"==typeof this.context.col.treeAggregation||"undefined"==typeof this.context.col.treeAggregation.type||this.context.col.treeAggregation.type!==a},action:function(){j.aggregateColumn(this.context.col.grid,this.context.col,a)}};c.arrayContainsObjectWithProperty(d.menuItems,"name","ui.grid.grouping.aggregate"+a)||d.menuItems.push(e)};d.colDef.groupingShowGroupingMenu!==!1&&(c.arrayContainsObjectWithProperty(d.menuItems,"name","ui.grid.grouping.group")||d.menuItems.push(f),c.arrayContainsObjectWithProperty(d.menuItems,"name","ui.grid.grouping.ungroup")||d.menuItems.push(h)),d.colDef.groupingShowAggregationMenu!==!1&&(angular.forEach(i.nativeAggregations(),function(a,b){l(b)}),angular.forEach(e.treeCustomAggregations,function(a,b){l(b,a.menuTitle)}),c.arrayContainsObjectWithProperty(d.menuItems,"name","ui.grid.grouping.aggregateRemove")||d.menuItems.push(k))}},groupingColumnProcessor:function(a,b){return a=j.moveGroupColumns(this,a,b)},groupedFinalizerFn:function(a){var b=this;"undefined"!=typeof a.groupVal?(a.rendered=a.groupVal,b.grid.options.groupingShowCounts&&"date"!==b.colDef.type&&(a.rendered+=" ("+a.value+")")):a.rendered=null},moveGroupColumns:function(a,b,c){return a.options.moveGroupColumns===!1?b:(b.forEach(function(a,b){a.groupingPosition=b}),b.sort(function(a,b){var c,d;return c=a.isRowHeader?-1e3:"undefined"==typeof a.grouping||"undefined"==typeof a.grouping.groupPriority||a.grouping.groupPriority<0?null:a.grouping.groupPriority,d=b.isRowHeader?-1e3:"undefined"==typeof b.grouping||"undefined"==typeof b.grouping.groupPriority||b.grouping.groupPriority<0?null:b.grouping.groupPriority,null!==c&&null===d?-1:null!==d&&null===c?1:null!==c&&null!==d?c-d:a.groupingPosition-b.groupingPosition}),b.forEach(function(a,b){delete a.groupingPosition}),b)},groupColumn:function(a,c){"undefined"==typeof c.grouping&&(c.grouping={});var d=j.getGrouping(a);c.grouping.groupPriority=d.grouping.length,c.sort?("undefined"==typeof c.sort.direction||null===c.sort.direction)&&(c.sort.direction=h.ASC):c.sort={direction:h.ASC},c.treeAggregation={type:b.aggregation.COUNT,source:"grouping"},c.treeAggregationFn=i.nativeAggregations()[b.aggregation.COUNT].aggregationFn,c.treeAggregationFinalizerFn=j.groupedFinalizerFn,a.api.grouping.raise.groupingChanged(c),a.api.core.raise.sortChanged(a,a.getColumnSorting()),a.queueGridRefresh()},ungroupColumn:function(a,b){"undefined"!=typeof b.grouping&&(delete b.grouping.groupPriority,delete b.treeAggregation,delete b.customTreeAggregationFinalizer,j.tidyPriorities(a),a.api.grouping.raise.groupingChanged(b),a.queueGridRefresh())},aggregateColumn:function(a,b,c){"undefined"!=typeof b.grouping&&"undefined"!=typeof b.grouping.groupPriority&&b.grouping.groupPriority>=0&&j.ungroupColumn(a,b);var d={};"undefined"!=typeof a.options.treeCustomAggregations[c]?d=a.options.treeCustomAggregations[c]:"undefined"!=typeof i.nativeAggregations()[c]&&(d=i.nativeAggregations()[c]),b.treeAggregation={type:c,label:g.get().aggregation[d.label]||d.label},b.treeAggregationFn=d.aggregationFn,b.treeAggregationFinalizerFn=d.finalizerFn,a.api.grouping.raise.aggregationChanged(b),a.queueGridRefresh()},setGrouping:function(a,b){"undefined"!=typeof b&&(j.clearGrouping(a),b.grouping&&b.grouping.length&&b.grouping.length>0&&b.grouping.forEach(function(b){var c=a.getColumn(b.colName);c&&j.groupColumn(a,c)}),b.aggregations&&b.aggregations.length&&b.aggregations.forEach(function(b){var c=a.getColumn(b.colName);c&&j.aggregateColumn(a,c,b.aggregation.type)}),b.rowExpandedStates&&j.applyRowExpandedStates(a.grouping.groupingHeaderCache,b.rowExpandedStates))},clearGrouping:function(a){var b=j.getGrouping(a);b.grouping.length>0&&b.grouping.forEach(function(b){b.col||(b.col=a.getColumn(b.colName)),j.ungroupColumn(a,b.col)}),b.aggregations.length>0&&b.aggregations.forEach(function(b){b.col||(b.col=a.getColumn(b.colName)),j.aggregateColumn(a,b.col,null)})},tidyPriorities:function(a){"undefined"!=typeof a&&"undefined"==typeof a.grid||"undefined"==typeof this.grid||(a=this.grid);var b=[],c=[];a.columns.forEach(function(a,d){"undefined"!=typeof a.grouping&&"undefined"!=typeof a.grouping.groupPriority&&a.grouping.groupPriority>=0?b.push(a):"undefined"!=typeof a.sort&&"undefined"!=typeof a.sort.priority&&a.sort.priority>=0&&c.push(a)}),b.sort(function(a,b){return a.grouping.groupPriority-b.grouping.groupPriority}),b.forEach(function(a,b){a.grouping.groupPriority=b,a.suppressRemoveSort=!0,"undefined"==typeof a.sort&&(a.sort={}),a.sort.priority=b});var d=b.length;c.sort(function(a,b){return a.sort.priority-b.sort.priority}),c.forEach(function(a,b){a.sort.priority=d,a.suppressRemoveSort=a.colDef.suppressRemoveSort,d++})},groupRows:function(a){if(0===a.length)return a;var b=this;b.grouping.oldGroupingHeaderCache=b.grouping.groupingHeaderCache||{},b.grouping.groupingHeaderCache={};for(var c=j.initialiseProcessingState(b),e=function(e,h){var i=b.getCellValue(g,e.col);e.initialised&&0===d.getSortFn(b,e.col,a)(i,e.currentValue)||(j.insertGroupHeader(b,a,f,c,h),f++)},f=0;f=0&&b.push({field:a.field,col:a,groupPriority:a.grouping.groupPriority,grouping:a.grouping}),a.treeAggregation&&a.treeAggregation.type&&c.push({field:a.field,col:a,aggregation:a.treeAggregation})}),b.sort(function(a,b){return a.groupPriority-b.groupPriority}),b.forEach(function(a,b){a.grouping.groupPriority=b,a.groupPriority=b,delete a.grouping}),{grouping:b,aggregations:c}},insertGroupHeader:function(a,b,c,d,g){var h=(d[g].fieldName,d[g].col),i=a.getCellValue(b[c],h),k=i;("undefined"==typeof i||null===i)&&(k=a.options.groupingNullLabel);for(var l=function(a){return angular.isObject(a)?JSON.stringify(a):a},m=a.grouping.oldGroupingHeaderCache,n=0;g>n;n++)m&&m[l(d[n].currentValue)]&&(m=m[l(d[n].currentValue)].children);var o;for(m&&m[l(i)]?(o=m[l(i)].row,o.entity={}):(o=new e({},null,a),f.rowTemplateAssigner.call(a,o)),o.entity["$$"+d[g].col.uid]={groupVal:k},o.treeLevel=g,o.groupHeader=!0,o.internalRow=!0,o.enableCellEdit=!1,o.enableSelection=a.options.enableGroupHeaderSelection,d[g].initialised=!0,d[g].currentValue=i,d[g].currentRow=o,j.finaliseProcessingState(d,g+1),b.splice(c,0,o),m=a.grouping.groupingHeaderCache,n=0;g>n;n++)m=m[l(d[n].currentValue)].children;m[l(i)]={row:o,children:{}}},finaliseProcessingState:function(a,b){for(var c=b;c 1 or < 1 file choosers within the menu item, error, cannot continue"):h[0].addEventListener("change",g,!1)}}}])}(),function(){"use strict";var a=angular.module("ui.grid.infiniteScroll",["ui.grid"]);a.service("uiGridInfiniteScrollService",["gridUtil","$compile","$timeout","uiGridConstants","ScrollEvent","$q",function(a,b,c,d,e,f){var g={initializeGrid:function(a,b){if(g.defaultGridOptions(a.options),a.options.enableInfiniteScroll){a.infiniteScroll={dataLoading:!1},g.setScrollDirections(a,a.options.infiniteScrollUp,a.options.infiniteScrollDown),a.api.core.on.scrollEnd(b,g.handleScroll);var c={events:{infiniteScroll:{needLoadMoreData:function(a,b){},needLoadMoreDataTop:function(a,b){}}},methods:{infiniteScroll:{dataLoaded:function(b,c){g.setScrollDirections(a,b,c);var d=g.adjustScroll(a).then(function(){a.infiniteScroll.dataLoading=!1});return d},resetScroll:function(b,c){return g.setScrollDirections(a,b,c),g.adjustInfiniteScrollPosition(a,0)},saveScrollPercentage:function(){a.infiniteScroll.prevScrollTop=a.renderContainers.body.prevScrollTop,a.infiniteScroll.previousVisibleRows=a.getVisibleRowCount()},dataRemovedTop:function(b,c){g.dataRemovedTop(a,b,c)},dataRemovedBottom:function(b,c){g.dataRemovedBottom(a,b,c)},setScrollDirections:function(b,c){g.setScrollDirections(a,b,c)}}}};a.api.registerEventsFromObject(c.events),a.api.registerMethodsFromObject(c.methods)}},defaultGridOptions:function(a){a.enableInfiniteScroll=a.enableInfiniteScroll!==!1,a.infiniteScrollRowsFromEnd=a.infiniteScrollRowsFromEnd||20,a.infiniteScrollUp=a.infiniteScrollUp===!0,a.infiniteScrollDown=a.infiniteScrollDown!==!1},setScrollDirections:function(a,b,c){a.infiniteScroll.scrollUp=b===!0,a.suppressParentScrollUp=b===!0,a.infiniteScroll.scrollDown=c!==!1,a.suppressParentScrollDown=c!==!1},handleScroll:function(a){if(!(a.grid.infiniteScroll&&a.grid.infiniteScroll.dataLoading||"ui.grid.adjustInfiniteScrollPosition"===a.source)&&a.y){var b,c=a.grid.options.infiniteScrollRowsFromEnd/a.grid.renderContainers.body.visibleRowCache.length;a.grid.scrollDirection===d.scrollDirection.UP?(b=a.y.percentage,c>=b&&g.loadData(a.grid)):a.grid.scrollDirection===d.scrollDirection.DOWN&&(b=1-a.y.percentage,c>=b&&g.loadData(a.grid))}},loadData:function(a){a.infiniteScroll.previousVisibleRows=a.renderContainers.body.visibleRowCache.length,a.infiniteScroll.direction=a.scrollDirection,delete a.infiniteScroll.prevScrollTop,a.scrollDirection===d.scrollDirection.UP&&a.infiniteScroll.scrollUp?(a.infiniteScroll.dataLoading=!0,a.api.infiniteScroll.raise.needLoadMoreDataTop()):a.scrollDirection===d.scrollDirection.DOWN&&a.infiniteScroll.scrollDown&&(a.infiniteScroll.dataLoading=!0,a.api.infiniteScroll.raise.needLoadMoreData())},adjustScroll:function(a){var b=f.defer();return c(function(){var e,f,h,i,j;e=a.getViewportHeight()+a.headerHeight-a.renderContainers.body.headerHeight-a.scrollbarHeight,f=a.options.rowHeight,void 0===a.infiniteScroll.direction&&g.adjustInfiniteScrollPosition(a,0),h=a.getVisibleRowCount();var k=f*h;a.infiniteScroll.scrollDown&&e>k&&a.api.infiniteScroll.raise.needLoadMoreData(),a.infiniteScroll.direction===d.scrollDirection.UP&&(i=a.infiniteScroll.prevScrollTop||0,j=i+(h-a.infiniteScroll.previousVisibleRows)*f,g.adjustInfiniteScrollPosition(a,j),c(function(){b.resolve()})),a.infiniteScroll.direction===d.scrollDirection.DOWN&&(j=a.infiniteScroll.prevScrollTop||a.infiniteScroll.previousVisibleRows*f-e,g.adjustInfiniteScrollPosition(a,j),c(function(){b.resolve()}))},0),b.promise},adjustInfiniteScrollPosition:function(a,b){var c=new e(a,null,null,"ui.grid.adjustInfiniteScrollPosition"),d=a.getVisibleRowCount(),f=a.getViewportHeight()+a.headerHeight-a.renderContainers.body.headerHeight-a.scrollbarHeight,g=a.options.rowHeight,h=d*g-f;0===b&&a.infiniteScroll.scrollUp?c.y={percentage:1/h}:c.y={percentage:b/h},a.scrollContainers("",c)},dataRemovedTop:function(a,b,c){var d,e,f,h;return g.setScrollDirections(a,b,c),d=a.renderContainers.body.visibleRowCache.length,e=a.infiniteScroll.prevScrollTop,h=a.options.rowHeight,f=e-(a.infiniteScroll.previousVisibleRows-d)*h,g.adjustInfiniteScrollPosition(a,f)},dataRemovedBottom:function(a,b,c){var d;return g.setScrollDirections(a,b,c),d=a.infiniteScroll.prevScrollTop,g.adjustInfiniteScrollPosition(a,d)}};return g}]),a.directive("uiGridInfiniteScroll",["uiGridInfiniteScrollService",function(a){return{priority:-200,scope:!1,require:"^uiGrid",compile:function(b,c,d){return{pre:function(b,c,d,e){a.initializeGrid(e.grid,b)},post:function(a,b,c){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.moveColumns",["ui.grid"]);a.service("uiGridMoveColumnService",["$q","$timeout","$log","ScrollEvent","uiGridConstants","gridUtil",function(a,b,c,d,e,f){var g={initializeGrid:function(a){var b=this;this.registerPublicApi(a),this.defaultGridOptions(a.options),a.moveColumns={orderCache:[]},a.registerColumnBuilder(b.movableColumnBuilder),a.registerDataChangeCallback(b.verifyColumnOrder,[e.dataChange.COLUMN])},registerPublicApi:function(a){var b=this,c={events:{colMovable:{columnPositionChanged:function(a,b,c){}}},methods:{colMovable:{moveColumn:function(c,d){var e=a.columns;if(!angular.isNumber(c)||!angular.isNumber(d))return void f.logError("MoveColumn: Please provide valid values for originalPosition and finalPosition");for(var g=0,h=0;h=e.length-g||d>=e.length-g)return void f.logError("MoveColumn: Invalid values for originalPosition, finalPosition");var i=function(a){for(var b=a,c=0;b>=c;c++)angular.isDefined(e[c])&&(angular.isDefined(e[c].colDef.visible)&&e[c].colDef.visible===!1||e[c].isRowHeader===!0)&&b++;return b};b.redrawColumnAtPosition(a,i(c),i(d))}}}};a.api.registerEventsFromObject(c.events),a.api.registerMethodsFromObject(c.methods)},defaultGridOptions:function(a){a.enableColumnMoving=a.enableColumnMoving!==!1},movableColumnBuilder:function(b,c,d){var e=[];return b.enableColumnMoving=void 0===b.enableColumnMoving?d.enableColumnMoving:b.enableColumnMoving,a.all(e)},updateColumnCache:function(a){a.moveColumns.orderCache=a.getOnlyDataColumns()},verifyColumnOrder:function(a){var b,c=a.rowHeaderColumns.length;angular.forEach(a.moveColumns.orderCache,function(d,e){if(b=a.columns.indexOf(d),-1!==b&&b-c!==e){var f=a.columns.splice(b,1)[0];a.columns.splice(e+c,0,f)}})},redrawColumnAtPosition:function(a,c,d){if(c!==d){var f=a.columns,h=f[c];if(h.colDef.enableColumnMoving){if(c>d)for(var i=c;i>d;i--)f[i]=f[i-1];else if(d>c)for(var j=c;d>j;j++)f[j]=f[j+1];f[d]=h,g.updateColumnCache(a),a.queueGridRefresh(),b(function(){a.api.core.notifyDataChange(e.dataChange.COLUMN),a.api.colMovable.raise.columnPositionChanged(h.colDef,c,d)})}}}};return g}]),a.directive("uiGridMoveColumns",["uiGridMoveColumnService",function(a){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(b,c,d,e){a.initializeGrid(e.grid)},post:function(a,b,c,d){}}}}}]),a.directive("uiGridHeaderCell",["$q","gridUtil","uiGridMoveColumnService","$document","$log","uiGridConstants","ScrollEvent",function(a,b,c,d,e,f,g){return{priority:-10,require:"^uiGrid",compile:function(){return{post:function(a,b,e,f){if(a.col.colDef.enableColumnMoving){var h,i,j,k,l,m,n=angular.element(b[0].querySelectorAll(".ui-grid-cell-contents")),o=!1,p=!1,q=function(b){h=a.grid.element[0].getBoundingClientRect().left,a.grid.hasLeftContainer()&&(h+=a.grid.renderContainers.left.header[0].getBoundingClientRect().width),i=b.pageX,j=0,k=h+a.grid.getViewportWidth(),"mousedown"===b.type?(d.on("mousemove",r),d.on("mouseup",s)):"touchstart"===b.type&&(d.on("touchmove",r),d.on("touchend",s))},r=function(a){var b=a.pageX-i;0!==b&&(document.onselectstart=function(){return!1},p=!0,o?o&&(w(b),i=a.pageX):v())},s=function(b){if(document.onselectstart=null,l&&(l.remove(),o=!1),u(),t(),p){for(var d=a.grid.columns,e=0,f=0;fj){var h,i=0;if(a.grid.isRTL()){for(h=e+1;hMath.abs(j))){c.redrawColumnAtPosition(a.grid,e,h-1);break}}else for(h=e-1;h>=0;h--)if((angular.isUndefined(d[h].colDef.visible)||d[h].colDef.visible===!0)&&(i+=d[h].drawnWidth||d[h].width||d[h].colDef.width,i>Math.abs(j))){c.redrawColumnAtPosition(a.grid,e,h+1);break}i0){var k,m=0;if(a.grid.isRTL()){for(k=e-1;k>0;k--)if((angular.isUndefined(d[k].colDef.visible)||d[k].colDef.visible===!0)&&(m+=d[k].drawnWidth||d[k].width||d[k].colDef.width,m>j)){c.redrawColumnAtPosition(a.grid,e,k);break}}else for(k=e+1;kj)){c.redrawColumnAtPosition(a.grid,e,k-1);break}j>m&&(g=d.length-1,a.grid.isRTL()&&(g=0),c.redrawColumnAtPosition(a.grid,e,g))}}},t=function(){n.on("touchstart",q),n.on("mousedown",q)},u=function(){n.off("touchstart",q),n.off("mousedown",q),d.off("mousemove",r),d.off("touchmove",r),d.off("mouseup",s),d.off("touchend",s)};t();var v=function(){o=!0,l=b.clone(),b.parent().append(l),l.addClass("movingColumn");var c={};c.left=b[0].offsetLeft+"px";var d=a.grid.element[0].getBoundingClientRect().right,e=b[0].getBoundingClientRect().right;e>d&&(m=a.col.drawnWidth+(d-e),c.width=m+"px"),l.css(c)},w=function(b){for(var c=a.grid.columns,d=0,e=0;ei?i:k,(n>=h||b>0)&&(k>=o||0>b))l.css({visibility:"visible",left:l[0].offsetLeft+(k>i?b:k-n)+"px"});else if(d>Math.ceil(f.grid.gridWidth)){b*=8;var p=new g(a.col.grid,null,null,"uiGridHeaderCell.moveElement");p.x={pixels:b},p.grid.scrollContainers("",p)}for(var q=0,r=0;r0?a.options.paginationCurrentPage=Math.min(a.options.paginationCurrentPage+1,c.methods.pagination.getTotalPages()):a.options.paginationCurrentPage++)},previousPage:function(){a.options.enablePagination&&(a.options.paginationCurrentPage=Math.max(a.options.paginationCurrentPage-1,1))},seek:function(b){if(a.options.enablePagination){if(!angular.isNumber(b)||1>b)throw"Invalid page number: "+b;a.options.paginationCurrentPage=Math.min(b,c.methods.pagination.getTotalPages())}}}}};a.api.registerEventsFromObject(c.events),a.api.registerMethodsFromObject(c.methods);var d=function(b){if(a.options.useExternalPagination||!a.options.enablePagination)return b;var c=parseInt(a.options.paginationPageSize,10),d=parseInt(a.options.paginationCurrentPage,10),e=b.filter(function(a){return a.visible});a.options.totalItems=e.length;var f=(d-1)*c;return f>e.length&&(d=a.options.paginationCurrentPage=1,f=(d-1)*c),e.slice(f,f+c)};a.registerRowsProcessor(d,900)},defaultGridOptions:function(b){b.enablePagination=b.enablePagination!==!1,b.enablePaginationControls=b.enablePaginationControls!==!1,b.useExternalPagination=b.useExternalPagination===!0,a.isNullOrUndefined(b.totalItems)&&(b.totalItems=0),a.isNullOrUndefined(b.paginationPageSizes)&&(b.paginationPageSizes=[250,500,1e3]),a.isNullOrUndefined(b.paginationPageSize)&&(b.paginationPageSizes.length>0?b.paginationPageSize=b.paginationPageSizes[0]:b.paginationPageSize=0),a.isNullOrUndefined(b.paginationCurrentPage)&&(b.paginationCurrentPage=1),a.isNullOrUndefined(b.paginationTemplate)&&(b.paginationTemplate="ui-grid/pagination")},onPaginationChanged:function(a,b,c){a.api.pagination.raise.paginationChanged(b,c),a.options.useExternalPagination||a.queueGridRefresh()}};return b}]),a.directive("uiGridPagination",["gridUtil","uiGridPaginationService",function(a,b){return{priority:-200,scope:!1,require:"uiGrid",link:{pre:function(c,d,e,f){b.initializeGrid(f.grid),a.getTemplate(f.grid.options.paginationTemplate).then(function(a){var b=angular.element(a);d.append(b),f.innerCompile(b)})}}}}]),a.directive("uiGridPager",["uiGridPaginationService","uiGridConstants","gridUtil","i18nService",function(a,b,c,d){return{priority:-200,scope:!0,require:"^uiGrid",link:function(e,f,g,h){var i=".ui-grid-pager-control-input";e.aria=d.getSafeText("pagination.aria"),e.paginationApi=h.grid.api.pagination,e.sizesLabel=d.getSafeText("pagination.sizes"),e.totalItemsLabel=d.getSafeText("pagination.totalItems"),e.paginationOf=d.getSafeText("pagination.of"),e.paginationThrough=d.getSafeText("pagination.through");var j=h.grid.options;h.grid.renderContainers.body.registerViewportAdjuster(function(a){return a.height=a.height-c.elementHeight(f,"padding"),a});var k=h.grid.registerDataChangeCallback(function(a){a.options.useExternalPagination||(a.options.totalItems=a.rows.length)},[b.dataChange.ROW]);e.$on("$destroy",k);var l=function(){e.showingLow=(j.paginationCurrentPage-1)*j.paginationPageSize+1,e.showingHigh=Math.min(j.paginationCurrentPage*j.paginationPageSize,j.totalItems)},m=e.$watch("grid.options.totalItems + grid.options.paginationPageSize",l),n=e.$watch("grid.options.paginationCurrentPage + grid.options.paginationPageSize",function(b,c){if(b!==c&&void 0!==c){if(!angular.isNumber(j.paginationCurrentPage)||j.paginationCurrentPage<1)return void(j.paginationCurrentPage=1);if(j.totalItems>0&&j.paginationCurrentPage>e.paginationApi.getTotalPages())return void(j.paginationCurrentPage=e.paginationApi.getTotalPages());l(),a.onPaginationChanged(e.grid,j.paginationCurrentPage,j.paginationPageSize)}});e.$on("$destroy",function(){m(),n()}),e.cantPageForward=function(){return j.totalItems>0?j.paginationCurrentPage>=e.paginationApi.getTotalPages():j.data.length<1},e.cantPageToLast=function(){return j.totalItems>0?e.cantPageForward():!0},e.cantPageBackward=function(){return j.paginationCurrentPage<=1};var o=function(a){a&&c.focus.bySelector(f,i)};e.pageFirstPageClick=function(){e.paginationApi.seek(1),o(e.cantPageBackward())},e.pagePreviousPageClick=function(){e.paginationApi.previousPage(),o(e.cantPageBackward())},e.pageNextPageClick=function(){e.paginationApi.nextPage(),o(e.cantPageForward())},e.pageLastPageClick=function(){e.paginationApi.seek(e.paginationApi.getTotalPages()),o(e.cantPageToLast())}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.pinning",["ui.grid"]);a.constant("uiGridPinningConstants",{container:{LEFT:"left",RIGHT:"right",NONE:""}}),a.service("uiGridPinningService",["gridUtil","GridRenderContainer","i18nService","uiGridPinningConstants",function(a,b,c,d){var e={initializeGrid:function(a){e.defaultGridOptions(a.options),a.registerColumnBuilder(e.pinningColumnBuilder);var b={events:{pinning:{columnPinned:function(a,b){}}},methods:{pinning:{pinColumn:function(b,c){e.pinColumn(a,b,c)}}}};a.api.registerEventsFromObject(b.events),a.api.registerMethodsFromObject(b.methods)},defaultGridOptions:function(a){a.enablePinning=a.enablePinning!==!1},pinningColumnBuilder:function(b,f,g){if(b.enablePinning=void 0===b.enablePinning?g.enablePinning:b.enablePinning,b.pinnedLeft?(f.renderContainer="left",f.grid.createLeftContainer()):b.pinnedRight&&(f.renderContainer="right",f.grid.createRightContainer()),b.enablePinning){var h={name:"ui.grid.pinning.pinLeft",title:c.get().pinning.pinLeft,icon:"ui-grid-icon-left-open",shown:function(){return"undefined"==typeof this.context.col.renderContainer||!this.context.col.renderContainer||"left"!==this.context.col.renderContainer},action:function(){e.pinColumn(this.context.col.grid,this.context.col,d.container.LEFT)}},i={name:"ui.grid.pinning.pinRight",title:c.get().pinning.pinRight,icon:"ui-grid-icon-right-open",shown:function(){return"undefined"==typeof this.context.col.renderContainer||!this.context.col.renderContainer||"right"!==this.context.col.renderContainer},action:function(){e.pinColumn(this.context.col.grid,this.context.col,d.container.RIGHT)}},j={name:"ui.grid.pinning.unpin",title:c.get().pinning.unpin,icon:"ui-grid-icon-cancel",shown:function(){return"undefined"!=typeof this.context.col.renderContainer&&null!==this.context.col.renderContainer&&"body"!==this.context.col.renderContainer},action:function(){e.pinColumn(this.context.col.grid,this.context.col,d.container.NONE)}};a.arrayContainsObjectWithProperty(f.menuItems,"name","ui.grid.pinning.pinLeft")||f.menuItems.push(h),a.arrayContainsObjectWithProperty(f.menuItems,"name","ui.grid.pinning.pinRight")||f.menuItems.push(i),a.arrayContainsObjectWithProperty(f.menuItems,"name","ui.grid.pinning.unpin")||f.menuItems.push(j)}},pinColumn:function(a,b,c){c===d.container.NONE?(b.renderContainer=null,b.colDef.pinnedLeft=b.colDef.pinnedRight=!1):(b.renderContainer=c,c===d.container.LEFT?a.createLeftContainer():c===d.container.RIGHT&&a.createRightContainer()),a.refresh().then(function(){a.api.pinning.raise.columnPinned(b.colDef,c)})}};return e}]),a.directive("uiGridPinning",["gridUtil","uiGridPinningService",function(a,b){return{require:"uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.initializeGrid(e.grid)},post:function(a,b,c,d){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.resizeColumns",["ui.grid"]);a.service("uiGridResizeColumnsService",["gridUtil","$q","$timeout",function(a,b,c){var d={defaultGridOptions:function(a){a.enableColumnResizing=a.enableColumnResizing!==!1,a.enableColumnResize===!1&&(a.enableColumnResizing=!1)},colResizerColumnBuilder:function(a,c,d){var e=[];return a.enableColumnResizing=void 0===a.enableColumnResizing?d.enableColumnResizing:a.enableColumnResizing,a.enableColumnResize===!1&&(a.enableColumnResizing=!1),b.all(e)},registerPublicApi:function(a){var b={events:{colResizable:{columnSizeChanged:function(a,b){}}}};a.api.registerEventsFromObject(b.events)},fireColumnSizeChanged:function(b,d,e){c(function(){b.api.colResizable?b.api.colResizable.raise.columnSizeChanged(d,e):a.logError("The resizeable api is not registered, this may indicate that you've included the module but not added the 'ui-grid-resize-columns' directive to your grid definition. Cannot raise any events.")})},findTargetCol:function(a,b,c){var d=a.getRenderContainer();if("left"===b){var e=d.visibleColumnCache.indexOf(a);return d.visibleColumnCache[e-1*c]}return a}};return d}]),a.directive("uiGridResizeColumns",["gridUtil","uiGridResizeColumnsService",function(a,b){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.defaultGridOptions(e.grid.options),e.grid.registerColumnBuilder(b.colResizerColumnBuilder),b.registerPublicApi(e.grid)},post:function(a,b,c,d){}}}}}]),a.directive("uiGridHeaderCell",["gridUtil","$templateCache","$compile","$q","uiGridResizeColumnsService","uiGridConstants","$timeout",function(a,b,c,d,e,f,g){return{priority:-10,require:"^uiGrid",compile:function(){return{post:function(a,d,h,i){var j=i.grid;if(j.options.enableColumnResizing){var k=b.get("ui-grid/columnResizer"),l=1;j.isRTL()&&(a.position="left",l=-1);var m=function(){for(var b=d[0].getElementsByClassName("ui-grid-column-resizer"),f=0;f
'),f={priority:0,scope:{col:"=",position:"@",renderIndex:"="},require:"?^uiGrid",link:function(f,g,h,i){function j(a){i.grid.refreshCanvas(!0).then(function(){i.grid.queueGridRefresh()})}function k(a,b){var c=b;return a.minWidth&&ca.maxWidth&&(c=a.maxWidth),c}function l(a,b){a.originalEvent&&(a=a.originalEvent),a.preventDefault(),o=(a.targetTouches?a.targetTouches[0]:a).clientX-p,0>o?o=0:o>i.grid.gridWidth&&(o=i.grid.gridWidth);var g=d.findTargetCol(f.col,f.position,q);if(g.colDef.enableColumnResizing!==!1){i.grid.element.hasClass("column-resizing")||i.grid.element.addClass("column-resizing");var h=o-n,j=parseInt(g.drawnWidth+h*q,10);o+=(k(g,j)-j)*q,e.css({left:o+"px"}),i.fireEvent(c.events.ITEM_DRAGGING)}}function m(a,b){a.originalEvent&&(a=a.originalEvent),a.preventDefault(),i.grid.element.removeClass("column-resizing"),e.remove(),o=(a.changedTouches?a.changedTouches[0]:a).clientX-p;var c=o-n;if(0===c)return t(),void s();var g=d.findTargetCol(f.col,f.position,q);if(g.colDef.enableColumnResizing!==!1){var h=parseInt(g.drawnWidth+c*q,10);g.width=k(g,h),g.hasCustomWidth=!0,j(c),d.fireColumnSizeChanged(i.grid,g.colDef,c),t(),s()}}var n=0,o=0,p=0,q=1;i.grid.isRTL()&&(f.position="left",q=-1),"left"===f.position?g.addClass("left"):"right"===f.position&&g.addClass("right");var r=function(b,c){b.originalEvent&&(b=b.originalEvent),b.stopPropagation(),p=i.grid.element[0].getBoundingClientRect().left,n=(b.targetTouches?b.targetTouches[0]:b).clientX-p,i.grid.element.append(e),e.css({left:n}),"touchstart"===b.type?(a.on("touchend",m),a.on("touchmove",l),g.off("mousedown",r)):(a.on("mouseup",m),a.on("mousemove",l),g.off("touchstart",r))},s=function(){g.on("mousedown",r),g.on("touchstart",r)},t=function(){a.off("mouseup",m),a.off("touchend",m),a.off("mousemove",l),a.off("touchmove",l),g.off("mousedown",r),g.off("touchstart",r)};s();var u=function(a,e){a.stopPropagation();var h=d.findTargetCol(f.col,f.position,q);if(h.colDef.enableColumnResizing!==!1){var l=0,m=0,n=b.closestElm(g,".ui-grid-render-container"),o=n.querySelectorAll("."+c.COL_CLASS_PREFIX+h.uid+" .ui-grid-cell-contents");Array.prototype.forEach.call(o,function(a){var c;angular.element(a).parent().hasClass("ui-grid-header-cell")&&(c=angular.element(a).parent()[0].querySelectorAll(".ui-grid-column-menu-button")),b.fakeElement(a,{},function(a){var d=angular.element(a);d.attr("style","float: left");var e=b.elementWidth(d);if(c){var f=b.elementWidth(c);e+=f}e>l&&(l=e,m=l-e)})}),h.width=k(h,l),h.hasCustomWidth=!0,j(m),d.fireColumnSizeChanged(i.grid,h.colDef,m)}};g.on("dblclick",u),g.on("$destroy",function(){g.off("dblclick",u),t()})}};return f}])}(),function(){"use strict";var a=angular.module("ui.grid.rowEdit",["ui.grid","ui.grid.edit","ui.grid.cellNav"]);a.constant("uiGridRowEditConstants",{}),a.service("uiGridRowEditService",["$interval","$q","uiGridConstants","uiGridRowEditConstants","gridUtil",function(a,b,c,d,e){var f={initializeGrid:function(a,b){b.rowEdit={};var c={events:{rowEdit:{saveRow:function(a){}}},methods:{rowEdit:{setSavePromise:function(a,c){f.setSavePromise(b,a,c)},getDirtyRows:function(){return b.rowEdit.dirtyRows?b.rowEdit.dirtyRows:[]},getErrorRows:function(){return b.rowEdit.errorRows?b.rowEdit.errorRows:[]},flushDirtyRows:function(){return f.flushDirtyRows(b)},setRowsDirty:function(a){f.setRowsDirty(b,a)},setRowsClean:function(a){f.setRowsClean(b,a)}}}};b.api.registerEventsFromObject(c.events),b.api.registerMethodsFromObject(c.methods),b.api.core.on.renderingComplete(a,function(c){b.api.edit.on.afterCellEdit(a,f.endEditCell),b.api.edit.on.beginCellEdit(a,f.beginEditCell),b.api.edit.on.cancelCellEdit(a,f.cancelEditCell),b.api.cellNav&&b.api.cellNav.on.navigate(a,f.navigate)})},defaultGridOptions:function(a){},saveRow:function(a,b){var c=this;return function(){if(b.isSaving=!0,b.rowEditSavePromise)return b.rowEditSavePromise;var d=a.api.rowEdit.raise.saveRow(b.entity);return b.rowEditSavePromise?b.rowEditSavePromise.then(c.processSuccessPromise(a,b),c.processErrorPromise(a,b)):e.logError("A promise was not returned when saveRow event was raised, either nobody is listening to event, or event handler did not return a promise"),d}},setSavePromise:function(a,b,c){var d=a.getRow(b);d.rowEditSavePromise=c},processSuccessPromise:function(a,b){var c=this;return function(){delete b.isSaving,delete b.isDirty,delete b.isError,delete b.rowEditSaveTimer,delete b.rowEditSavePromise,c.removeRow(a.rowEdit.errorRows,b),c.removeRow(a.rowEdit.dirtyRows,b)}},processErrorPromise:function(a,b){return function(){delete b.isSaving,delete b.rowEditSaveTimer,delete b.rowEditSavePromise,b.isError=!0,a.rowEdit.errorRows||(a.rowEdit.errorRows=[]),f.isRowPresent(a.rowEdit.errorRows,b)||a.rowEdit.errorRows.push(b)}},removeRow:function(a,b){"undefined"!=typeof a&&null!==a&&a.forEach(function(c,d){c.uid===b.uid&&a.splice(d,1)})},isRowPresent:function(a,b){var c=!1;return a.forEach(function(a,d){a.uid===b.uid&&(c=!0)}),c},flushDirtyRows:function(a){var c=[];return a.api.rowEdit.getDirtyRows().forEach(function(b){f.saveRow(a,b)(),c.push(b.rowEditSavePromise)}),b.all(c)},endEditCell:function(a,b,c,d){var g=this.grid,h=g.getRow(a);return h?void((c!==d||h.isDirty)&&(g.rowEdit.dirtyRows||(g.rowEdit.dirtyRows=[]),h.isDirty||(h.isDirty=!0,g.rowEdit.dirtyRows.push(h)),delete h.isError,f.considerSetTimer(g,h))):void e.logError("Unable to find rowEntity in grid data, dirty flag cannot be set")},beginEditCell:function(a,b){var c=this.grid,d=c.getRow(a);return d?void f.cancelTimer(c,d):void e.logError("Unable to find rowEntity in grid data, timer cannot be cancelled")},cancelEditCell:function(a,b){var c=this.grid,d=c.getRow(a);return d?void f.considerSetTimer(c,d):void e.logError("Unable to find rowEntity in grid data, timer cannot be set")},navigate:function(a,b){var c=this.grid;a.row.rowEditSaveTimer&&f.cancelTimer(c,a.row),b&&b.row&&b.row!==a.row&&f.considerSetTimer(c,b.row)},considerSetTimer:function(b,c){if(f.cancelTimer(b,c),c.isDirty&&!c.isSaving&&-1!==b.options.rowEditWaitInterval){var d=b.options.rowEditWaitInterval?b.options.rowEditWaitInterval:2e3;c.rowEditSaveTimer=a(f.saveRow(b,c),d,1)}},cancelTimer:function(b,c){c.rowEditSaveTimer&&!c.isSaving&&(a.cancel(c.rowEditSaveTimer),delete c.rowEditSaveTimer)},setRowsDirty:function(a,b){var c;b.forEach(function(b,d){c=a.getRow(b),c?(a.rowEdit.dirtyRows||(a.rowEdit.dirtyRows=[]),c.isDirty||(c.isDirty=!0,a.rowEdit.dirtyRows.push(c)),delete c.isError,f.considerSetTimer(a,c)):e.logError("requested row not found in rowEdit.setRowsDirty, row was: "+b)})},setRowsClean:function(a,b){var c;b.forEach(function(b,d){c=a.getRow(b),c?(delete c.isDirty,f.removeRow(a.rowEdit.dirtyRows,c),f.cancelTimer(a,c),delete c.isError,f.removeRow(a.rowEdit.errorRows,c)):e.logError("requested row not found in rowEdit.setRowsClean, row was: "+b)})}};return f}]),a.directive("uiGridRowEdit",["gridUtil","uiGridRowEditService","uiGridEditConstants",function(a,b,c){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.initializeGrid(a,e.grid)},post:function(a,b,c,d){}}}}}]),a.directive("uiGridViewport",["$compile","uiGridConstants","gridUtil","$parse",function(a,b,c,d){return{priority:-200,scope:!1,compile:function(a,b){var c=angular.element(a.children().children()[0]),d=c.attr("ng-class"),e="";return e=d?d.slice(0,-1)+", 'ui-grid-row-dirty': row.isDirty, 'ui-grid-row-saving': row.isSaving, 'ui-grid-row-error': row.isError}":"{'ui-grid-row-dirty': row.isDirty, 'ui-grid-row-saving': row.isSaving, 'ui-grid-row-error': row.isError}",c.attr("ng-class",e),{pre:function(a,b,c,d){},post:function(a,b,c,d){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.saveState",["ui.grid","ui.grid.selection","ui.grid.cellNav","ui.grid.grouping","ui.grid.pinning","ui.grid.treeView"]);a.constant("uiGridSaveStateConstants",{featureName:"saveState"}),a.service("uiGridSaveStateService",["$q","uiGridSaveStateConstants","gridUtil","$compile","$interval","uiGridConstants",function(a,b,c,d,e,f){var g={initializeGrid:function(a){a.saveState={},this.defaultGridOptions(a.options);var b={events:{saveState:{}},methods:{saveState:{save:function(){return g.save(a)},restore:function(b,c){g.restore(a,b,c)}}}};a.api.registerEventsFromObject(b.events),a.api.registerMethodsFromObject(b.methods)},defaultGridOptions:function(a){a.saveWidths=a.saveWidths!==!1,a.saveOrder=a.saveOrder!==!1,a.saveScroll=a.saveScroll===!0,a.saveFocus=a.saveScroll!==!0&&a.saveFocus!==!1,a.saveVisible=a.saveVisible!==!1,a.saveSort=a.saveSort!==!1,a.saveFilter=a.saveFilter!==!1,a.saveSelection=a.saveSelection!==!1,a.saveGrouping=a.saveGrouping!==!1,a.saveGroupingExpandedStates=a.saveGroupingExpandedStates===!0,a.savePinning=a.savePinning!==!1,a.saveTreeView=a.saveTreeView!==!1},save:function(a){var b={};return b.columns=g.saveColumns(a),b.scrollFocus=g.saveScrollFocus(a),b.selection=g.saveSelection(a),b.grouping=g.saveGrouping(a),b.treeView=g.saveTreeView(a),b.pagination=g.savePagination(a),b},restore:function(a,b,c){c.columns&&g.restoreColumns(a,c.columns),c.scrollFocus&&g.restoreScrollFocus(a,b,c.scrollFocus),c.selection&&g.restoreSelection(a,c.selection),c.grouping&&g.restoreGrouping(a,c.grouping),c.treeView&&g.restoreTreeView(a,c.treeView),c.pagination&&g.restorePagination(a,c.pagination),a.refresh()},saveColumns:function(a){var b=[];return a.getOnlyDataColumns().forEach(function(c){var d={};d.name=c.name,a.options.saveVisible&&(d.visible=c.visible),a.options.saveWidths&&(d.width=c.width),a.options.saveSort&&(d.sort=angular.copy(c.sort)),a.options.saveFilter&&(d.filters=[],c.filters.forEach(function(a){var b={};angular.forEach(a,function(a,c){"condition"!==c&&"$$hashKey"!==c&&"placeholder"!==c&&(b[c]=a)}),d.filters.push(b)})),a.api.pinning&&a.options.savePinning&&(d.pinned=c.renderContainer?c.renderContainer:""),b.push(d)}),b},saveScrollFocus:function(a){if(!a.api.cellNav)return{};var b={};if(a.options.saveFocus){b.focus=!0;var c=a.api.cellNav.getFocusedCell();null!==c&&(null!==c.col&&(b.colName=c.col.colDef.name),null!==c.row&&(b.rowVal=g.getRowVal(a,c.row)))}return(a.options.saveScroll||a.options.saveFocus&&!b.colName&&!b.rowVal)&&(b.focus=!1,a.renderContainers.body.prevRowScrollIndex&&(b.rowVal=g.getRowVal(a,a.renderContainers.body.visibleRowCache[a.renderContainers.body.prevRowScrollIndex])),a.renderContainers.body.prevColScrollIndex&&(b.colName=a.renderContainers.body.visibleColumnCache[a.renderContainers.body.prevColScrollIndex].name)),b},saveSelection:function(a){if(!a.api.selection||!a.options.saveSelection)return[];var b=a.api.selection.getSelectedGridRows().map(function(b){return g.getRowVal(a,b)});return b},saveGrouping:function(a){return a.api.grouping&&a.options.saveGrouping?a.api.grouping.getGrouping(a.options.saveGroupingExpandedStates):{}},savePagination:function(a){return a.api.pagination&&a.options.paginationPageSize?{paginationCurrentPage:a.options.paginationCurrentPage,paginationPageSize:a.options.paginationPageSize}:{}},saveTreeView:function(a){return a.api.treeView&&a.options.saveTreeView?a.api.treeView.getTreeView():{}},getRowVal:function(a,b){if(!b)return null;var c={};return a.options.saveRowIdentity?(c.identity=!0,c.row=a.options.saveRowIdentity(b.entity)):(c.identity=!1,c.row=a.renderContainers.body.visibleRowCache.indexOf(b)),c},restoreColumns:function(a,b){var c=!1;b.forEach(function(b,d){var e=a.getColumn(b.name);if(e&&!a.isRowHeaderColumn(e)){!a.options.saveVisible||e.visible===b.visible&&e.colDef.visible===b.visible||(e.visible=b.visible,e.colDef.visible=b.visible,a.api.core.raise.columnVisibilityChanged(e)),a.options.saveWidths&&e.width!==b.width&&(e.width=b.width,e.hasCustomWidth=!0),!a.options.saveSort||angular.equals(e.sort,b.sort)||void 0===e.sort&&angular.isEmpty(b.sort)||(e.sort=angular.copy(b.sort),c=!0),a.options.saveFilter&&!angular.equals(e.filters,b.filters)&&(b.filters.forEach(function(a,b){angular.extend(e.filters[b],a),("undefined"==typeof a.term||null===a.term)&&delete e.filters[b].term}),a.api.core.raise.filterChanged()),a.api.pinning&&a.options.savePinning&&e.renderContainer!==b.pinned&&a.api.pinning.pinColumn(e,b.pinned);var f=a.getOnlyDataColumns().indexOf(e);if(-1!==f&&a.options.saveOrder&&f!==d){var g=a.columns.splice(f+a.rowHeaderColumns.length,1)[0];a.columns.splice(d+a.rowHeaderColumns.length,0,g)}}}),c&&a.api.core.raise.sortChanged(a,a.getColumnSorting())},restoreScrollFocus:function(a,b,c){if(a.api.cellNav){var d,e;if(c.colName){var f=a.options.columnDefs.filter(function(a){return a.name===c.colName});f.length>0&&(d=f[0])}c.rowVal&&c.rowVal.row&&(e=c.rowVal.identity?g.findRowByIdentity(a,c.rowVal):a.renderContainers.body.visibleRowCache[c.rowVal.row]);var h=e&&e.entity?e.entity:null;(d||h)&&(c.focus?a.api.cellNav.scrollToFocus(h,d):a.scrollTo(h,d))}},restoreSelection:function(a,b){a.api.selection&&(a.api.selection.clearSelectedRows(),b.forEach(function(b){if(b.identity){var c=g.findRowByIdentity(a,b);c&&a.api.selection.selectRow(c.entity)}else a.api.selection.selectRowByVisibleIndex(b.row)}))},restoreGrouping:function(a,b){a.api.grouping&&"undefined"!=typeof b&&null!==b&&!angular.equals(b,{})&&a.api.grouping.setGrouping(b)},restoreTreeView:function(a,b){a.api.treeView&&"undefined"!=typeof b&&null!==b&&!angular.equals(b,{})&&a.api.treeView.setTreeView(b)},restorePagination:function(a,b){a.api.pagination&&a.options.paginationPageSize&&(a.options.paginationCurrentPage=b.paginationCurrentPage,a.options.paginationPageSize=b.paginationPageSize)},findRowByIdentity:function(a,b){if(!a.options.saveRowIdentity)return null;var c=a.rows.filter(function(c){return a.options.saveRowIdentity(c.entity)===b.row?!0:!1});return c.length>0?c[0]:null}};return g}]),a.directive("uiGridSaveState",["uiGridSaveStateConstants","uiGridSaveStateService","gridUtil","$compile",function(a,b,c,d){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,link:function(a,c,d,e){b.initializeGrid(e.grid)}}}])}(),function(){"use strict";var a=angular.module("ui.grid.selection",["ui.grid"]);a.constant("uiGridSelectionConstants",{featureName:"selection",selectionRowHeaderColName:"selectionRowHeaderCol"}),angular.module("ui.grid").config(["$provide",function(a){a.decorator("GridRow",["$delegate",function(a){return a.prototype.setSelected=function(a){this.isSelected=a,a?this.grid.selection.selectedCount++:this.grid.selection.selectedCount--},a}])}]),a.service("uiGridSelectionService",["$q","$templateCache","uiGridSelectionConstants","gridUtil",function(a,b,c,d){var e={initializeGrid:function(a){a.selection={},a.selection.lastSelectedRow=null,a.selection.selectAll=!1,a.selection.selectedCount=0,e.defaultGridOptions(a.options);var b={events:{selection:{rowSelectionChanged:function(a,b,c){},rowSelectionChangedBatch:function(a,b,c){}}},methods:{selection:{toggleRowSelection:function(b,c){var d=a.getRow(b);null!==d&&e.toggleRowSelection(a,d,c,a.options.multiSelect,a.options.noUnselect)},selectRow:function(b,c){var d=a.getRow(b);null===d||d.isSelected||e.toggleRowSelection(a,d,c,a.options.multiSelect,a.options.noUnselect)},selectRowByVisibleIndex:function(b,c){var d=a.renderContainers.body.visibleRowCache[b];null===d||"undefined"==typeof d||d.isSelected||e.toggleRowSelection(a,d,c,a.options.multiSelect,a.options.noUnselect)},unSelectRow:function(b,c){var d=a.getRow(b);null!==d&&d.isSelected&&e.toggleRowSelection(a,d,c,a.options.multiSelect,a.options.noUnselect)},selectAllRows:function(b){if(a.options.multiSelect!==!1){var c=[];a.rows.forEach(function(d){d.isSelected||d.enableSelection===!1||(d.setSelected(!0),e.decideRaiseSelectionEvent(a,d,c,b))}),e.decideRaiseSelectionBatchEvent(a,c,b),a.selection.selectAll=!0}},selectAllVisibleRows:function(b){if(a.options.multiSelect!==!1){var c=[];a.rows.forEach(function(d){d.visible?d.isSelected||d.enableSelection===!1||(d.setSelected(!0),e.decideRaiseSelectionEvent(a,d,c,b)):d.isSelected&&(d.setSelected(!1),e.decideRaiseSelectionEvent(a,d,c,b))}),e.decideRaiseSelectionBatchEvent(a,c,b),a.selection.selectAll=!0}},clearSelectedRows:function(b){e.clearSelectedRows(a,b)},getSelectedRows:function(){return e.getSelectedRows(a).map(function(a){return a.entity})},getSelectedGridRows:function(){return e.getSelectedRows(a)},getSelectedCount:function(){return a.selection.selectedCount},setMultiSelect:function(b){a.options.multiSelect=b},setModifierKeysToMultiSelect:function(b){a.options.modifierKeysToMultiSelect=b},getSelectAllState:function(){return a.selection.selectAll}}}};a.api.registerEventsFromObject(b.events),a.api.registerMethodsFromObject(b.methods)},defaultGridOptions:function(a){a.enableRowSelection=a.enableRowSelection!==!1,a.multiSelect=a.multiSelect!==!1,a.noUnselect=a.noUnselect===!0,a.modifierKeysToMultiSelect=a.modifierKeysToMultiSelect===!0,a.enableRowHeaderSelection=a.enableRowHeaderSelection!==!1,"undefined"==typeof a.enableFullRowSelection&&(a.enableFullRowSelection=!a.enableRowHeaderSelection),a.enableSelectAll=a.enableSelectAll!==!1,a.enableSelectionBatchEvent=a.enableSelectionBatchEvent!==!1,a.selectionRowHeaderWidth=angular.isDefined(a.selectionRowHeaderWidth)?a.selectionRowHeaderWidth:30,a.enableFooterTotalSelected=a.enableFooterTotalSelected!==!1,a.isRowSelectable=angular.isDefined(a.isRowSelectable)?a.isRowSelectable:angular.noop},toggleRowSelection:function(a,b,c,d,f){var g=b.isSelected;if(b.enableSelection!==!1||g){var h;d||g?!d&&g&&(h=e.getSelectedRows(a),h.length>1&&(g=!1,e.clearSelectedRows(a,c))):e.clearSelectedRows(a,c),g&&f||(b.setSelected(!g),b.isSelected===!0&&(a.selection.lastSelectedRow=b),h=e.getSelectedRows(a),a.selection.selectAll=a.rows.length===h.length,a.api.selection.raise.rowSelectionChanged(b,c))}},shiftSelect:function(a,b,c,d){if(d){var f=e.getSelectedRows(a),g=f.length>0?a.renderContainers.body.visibleRowCache.indexOf(a.selection.lastSelectedRow):0,h=a.renderContainers.body.visibleRowCache.indexOf(b);if(g>h){var i=g;g=h,h=i}for(var j=[],k=g;h>=k;k++){var l=a.renderContainers.body.visibleRowCache[k];l&&(l.isSelected||l.enableSelection===!1||(l.setSelected(!0),a.selection.lastSelectedRow=l,e.decideRaiseSelectionEvent(a,l,j,c)))}e.decideRaiseSelectionBatchEvent(a,j,c)}},getSelectedRows:function(a){return a.rows.filter(function(a){return a.isSelected})},clearSelectedRows:function(a,b){var c=[];e.getSelectedRows(a).forEach(function(d){d.isSelected&&(d.setSelected(!1),e.decideRaiseSelectionEvent(a,d,c,b))}),e.decideRaiseSelectionBatchEvent(a,c,b),a.selection.selectAll=!1,a.selection.selectedCount=0},decideRaiseSelectionEvent:function(a,b,c,d){a.options.enableSelectionBatchEvent?c.push(b):a.api.selection.raise.rowSelectionChanged(b,d)},decideRaiseSelectionBatchEvent:function(a,b,c){b.length>0&&a.api.selection.raise.rowSelectionChangedBatch(b,c)}};return e}]),a.directive("uiGridSelection",["uiGridSelectionConstants","uiGridSelectionService","$templateCache","uiGridConstants",function(a,b,c,d){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(c,e,f,g){if(b.initializeGrid(g.grid),g.grid.options.enableRowHeaderSelection){var h={name:a.selectionRowHeaderColName,displayName:"",width:g.grid.options.selectionRowHeaderWidth,minWidth:10,cellTemplate:"ui-grid/selectionRowHeader",headerCellTemplate:"ui-grid/selectionHeaderCell",enableColumnResizing:!1,enableColumnMenu:!1,exporterSuppressExport:!0,allowCellFocus:!0};g.grid.addRowHeaderColumn(h)}var i=!1,j=function(a){return a.forEach(function(a){a.enableSelection=g.grid.options.isRowSelectable(a)}),a},k=function(){g.grid.options.isRowSelectable!==angular.noop&&i!==!0&&(g.grid.registerRowsProcessor(j,500),i=!0)};k();var l=g.grid.registerDataChangeCallback(k,[d.dataChange.OPTIONS]);c.$on("$destroy",l)},post:function(a,b,c,d){}}}}}]),a.directive("uiGridSelectionRowHeaderButtons",["$templateCache","uiGridSelectionService","gridUtil",function(a,b,c){return{replace:!0,restrict:"E",template:a.get("ui-grid/selectionRowHeaderButtons"),scope:!0,require:"^uiGrid",link:function(a,d,e,f){function g(a,c){c.stopPropagation(),c.shiftKey?b.shiftSelect(i,a,c,i.options.multiSelect):c.ctrlKey||c.metaKey?b.toggleRowSelection(i,a,c,i.options.multiSelect,i.options.noUnselect):b.toggleRowSelection(i,a,c,i.options.multiSelect&&!i.options.modifierKeysToMultiSelect,i.options.noUnselect)}function h(a){(a.ctrlKey||a.shiftKey)&&(a.target.onselectstart=function(){return!1},window.setTimeout(function(){a.target.onselectstart=null},0))}var i=f.grid;a.selectButtonClick=g,"ie"===c.detectBrowser()&&d.on("mousedown",h)}}}]),a.directive("uiGridSelectionSelectAllButtons",["$templateCache","uiGridSelectionService",function(a,b){return{replace:!0,restrict:"E",template:a.get("ui-grid/selectionSelectAllButtons"),scope:!1,link:function(a,c,d,e){var f=a.col.grid;a.headerButtonClick=function(a,c){f.selection.selectAll?(b.clearSelectedRows(f,c),f.options.noUnselect&&f.api.selection.selectRowByVisibleIndex(0,c),f.selection.selectAll=!1):f.options.multiSelect&&(f.api.selection.selectAllVisibleRows(c),f.selection.selectAll=!0)}}}}]),a.directive("uiGridViewport",["$compile","uiGridConstants","uiGridSelectionConstants","gridUtil","$parse","uiGridSelectionService",function(a,b,c,d,e,f){return{priority:-200,scope:!1,compile:function(a,b){var c=angular.element(a.children().children()[0]),d=c.attr("ng-class"),e="";return e=d?d.slice(0,-1)+",'ui-grid-row-selected': row.isSelected}":"{'ui-grid-row-selected': row.isSelected}",c.attr("ng-class",e), -{pre:function(a,b,c,d){},post:function(a,b,c,d){}}}}}]),a.directive("uiGridCell",["$compile","uiGridConstants","uiGridSelectionConstants","gridUtil","$parse","uiGridSelectionService","$timeout",function(a,b,c,d,e,f,g){return{priority:-200,restrict:"A",require:"?^uiGrid",scope:!1,link:function(a,c,d,e){function h(){a.grid.options.enableRowSelection&&a.grid.options.enableFullRowSelection&&(c.addClass("ui-grid-disable-selection"),c.on("touchstart",m),c.on("touchend",n),c.on("click",l),a.registered=!0)}function i(){a.registered&&(c.removeClass("ui-grid-disable-selection"),c.off("touchstart",m),c.off("touchend",n),c.off("click",l),a.registered=!1)}var j=0,k=300;e.grid.api.cellNav&&e.grid.api.cellNav.on.viewPortKeyDown(a,function(b,c){null!==c&&c.row===a.row&&c.col===a.col&&32===b.keyCode&&"selectionRowHeaderCol"===a.col.colDef.name&&(f.toggleRowSelection(a.grid,a.row,b,a.grid.options.multiSelect&&!a.grid.options.modifierKeysToMultiSelect,a.grid.options.noUnselect),a.$apply())});var l=function(b){c.off("touchend",n),b.shiftKey?f.shiftSelect(a.grid,a.row,b,a.grid.options.multiSelect):b.ctrlKey||b.metaKey?f.toggleRowSelection(a.grid,a.row,b,a.grid.options.multiSelect,a.grid.options.noUnselect):f.toggleRowSelection(a.grid,a.row,b,a.grid.options.multiSelect&&!a.grid.options.modifierKeysToMultiSelect,a.grid.options.noUnselect),a.$apply(),g(function(){c.on("touchend",n)},k)},m=function(a){j=(new Date).getTime(),c.off("click",l)},n=function(a){var b=(new Date).getTime(),d=b-j;k>d&&l(a),g(function(){c.on("click",l)},k)};h();var o=a.grid.registerDataChangeCallback(function(){a.grid.options.enableRowSelection&&a.grid.options.enableFullRowSelection&&!a.registered?h():a.grid.options.enableRowSelection&&a.grid.options.enableFullRowSelection||!a.registered||i()},[b.dataChange.OPTIONS]);c.on("$destroy",o)}}}]),a.directive("uiGridGridFooter",["$compile","uiGridConstants","gridUtil",function(a,b,c){return{restrict:"EA",replace:!0,priority:-1e3,require:"^uiGrid",scope:!0,compile:function(b,d){return{pre:function(b,d,e,f){f.grid.options.showGridFooter&&c.getTemplate("ui-grid/gridFooterSelectedItems").then(function(c){var e=angular.element(c),f=a(e)(b);angular.element(d[0].getElementsByClassName("ui-grid-grid-footer")[0]).append(f)})},post:function(a,b,c,d){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.treeBase",["ui.grid"]);a.constant("uiGridTreeBaseConstants",{featureName:"treeBase",rowHeaderColName:"treeBaseRowHeaderCol",EXPANDED:"expanded",COLLAPSED:"collapsed",aggregation:{COUNT:"count",SUM:"sum",MAX:"max",MIN:"min",AVG:"avg"}}),a.service("uiGridTreeBaseService",["$q","uiGridTreeBaseConstants","gridUtil","GridRow","gridClassFactory","i18nService","uiGridConstants","rowSorter",function(a,b,c,d,e,f,g,h){var i={initializeGrid:function(a,b){a.treeBase={},a.treeBase.numberLevels=0,a.treeBase.expandAll=!1,a.treeBase.tree=[],i.defaultGridOptions(a.options),a.registerRowsProcessor(i.treeRows,410),a.registerColumnBuilder(i.treeBaseColumnBuilder),i.createRowHeader(a);var c={events:{treeBase:{rowExpanded:{},rowCollapsed:{}}},methods:{treeBase:{expandAllRows:function(){i.expandAllRows(a)},collapseAllRows:function(){i.collapseAllRows(a)},toggleRowTreeState:function(b){i.toggleRowTreeState(a,b)},expandRow:function(b){i.expandRow(a,b)},expandRowChildren:function(b){i.expandRowChildren(a,b)},collapseRow:function(b){i.collapseRow(a,b)},collapseRowChildren:function(b){i.collapseRowChildren(a,b)},getTreeExpandedState:function(){return{expandedState:i.getTreeState(a)}},setTreeState:function(b){i.setTreeState(a,b)},getRowChildren:function(a){return a.treeNode.children.map(function(a){return a.row})}}}};a.api.registerEventsFromObject(c.events),a.api.registerMethodsFromObject(c.methods)},defaultGridOptions:function(a){a.treeRowHeaderBaseWidth=a.treeRowHeaderBaseWidth||30,a.treeIndent=a.treeIndent||10,a.showTreeRowHeader=a.showTreeRowHeader!==!1,a.showTreeExpandNoChildren=a.showTreeExpandNoChildren!==!1,a.treeRowHeaderAlwaysVisible=a.treeRowHeaderAlwaysVisible!==!1,a.treeCustomAggregations=a.treeCustomAggregations||{},a.enableExpandAll=a.enableExpandAll!==!1},treeBaseColumnBuilder:function(a,b,c){"undefined"!=typeof a.customTreeAggregationFn&&(b.treeAggregationFn=a.customTreeAggregationFn),"undefined"!=typeof a.treeAggregationType&&(b.treeAggregation={type:a.treeAggregationType},"undefined"!=typeof c.treeCustomAggregations[a.treeAggregationType]?(b.treeAggregationFn=c.treeCustomAggregations[a.treeAggregationType].aggregationFn,b.treeAggregationFinalizerFn=c.treeCustomAggregations[a.treeAggregationType].finalizerFn,b.treeAggregation.label=c.treeCustomAggregations[a.treeAggregationType].label):"undefined"!=typeof i.nativeAggregations()[a.treeAggregationType]&&(b.treeAggregationFn=i.nativeAggregations()[a.treeAggregationType].aggregationFn,b.treeAggregation.label=i.nativeAggregations()[a.treeAggregationType].label)),"undefined"!=typeof a.treeAggregationLabel&&("undefined"==typeof b.treeAggregation&&(b.treeAggregation={}),b.treeAggregation.label=a.treeAggregationLabel),b.treeAggregationUpdateEntity=a.treeAggregationUpdateEntity!==!1,"undefined"==typeof b.customTreeAggregationFinalizerFn&&(b.customTreeAggregationFinalizerFn=a.customTreeAggregationFinalizerFn)},createRowHeader:function(a){var c={name:b.rowHeaderColName,displayName:"",width:a.options.treeRowHeaderBaseWidth,minWidth:10,cellTemplate:"ui-grid/treeBaseRowHeader",headerCellTemplate:"ui-grid/treeBaseHeaderCell",enableColumnResizing:!1,enableColumnMenu:!1,exporterSuppressExport:!0,allowCellFocus:!0};c.visible=a.options.treeRowHeaderAlwaysVisible,a.addRowHeaderColumn(c)},expandAllRows:function(a){a.treeBase.tree.forEach(function(c){i.setAllNodes(a,c,b.EXPANDED)}),a.treeBase.expandAll=!0,a.queueGridRefresh()},collapseAllRows:function(a){a.treeBase.tree.forEach(function(c){i.setAllNodes(a,c,b.COLLAPSED)}),a.treeBase.expandAll=!1,a.queueGridRefresh()},setAllNodes:function(a,c,d){"undefined"!=typeof c.state&&c.state!==d&&(c.state=d,d===b.EXPANDED?a.api.treeBase.raise.rowExpanded(c.row):a.api.treeBase.raise.rowCollapsed(c.row)),c.children&&c.children.forEach(function(b){i.setAllNodes(a,b,d)})},toggleRowTreeState:function(a,c){"undefined"==typeof c.treeLevel||null===c.treeLevel||c.treeLevel<0||(c.treeNode.state===b.EXPANDED?i.collapseRow(a,c):i.expandRow(a,c),a.queueGridRefresh())},expandRow:function(a,c){"undefined"==typeof c.treeLevel||null===c.treeLevel||c.treeLevel<0||c.treeNode.state!==b.EXPANDED&&(c.treeNode.state=b.EXPANDED,a.api.treeBase.raise.rowExpanded(c),a.treeBase.expandAll=i.allExpanded(a.treeBase.tree),a.queueGridRefresh())},expandRowChildren:function(a,c){"undefined"==typeof c.treeLevel||null===c.treeLevel||c.treeLevel<0||(i.setAllNodes(a,c.treeNode,b.EXPANDED),a.treeBase.expandAll=i.allExpanded(a.treeBase.tree),a.queueGridRefresh())},collapseRow:function(a,c){"undefined"==typeof c.treeLevel||null===c.treeLevel||c.treeLevel<0||c.treeNode.state!==b.COLLAPSED&&(c.treeNode.state=b.COLLAPSED,a.treeBase.expandAll=!1,a.api.treeBase.raise.rowCollapsed(c),a.queueGridRefresh())},collapseRowChildren:function(a,c){"undefined"==typeof c.treeLevel||null===c.treeLevel||c.treeLevel<0||(i.setAllNodes(a,c.treeNode,b.COLLAPSED),a.treeBase.expandAll=!1,a.queueGridRefresh())},allExpanded:function(a){var b=!0;return a.forEach(function(a){i.allExpandedInternal(a)||(b=!1)}),b},allExpandedInternal:function(a){if(a.children&&a.children.length>0){if(a.state===b.COLLAPSED)return!1;var c=!0;return a.children.forEach(function(a){i.allExpandedInternal(a)||(c=!1)}),c}return!0},treeRows:function(a){if(0===a.length)return a;var c=this;b.EXPANDED;return c.treeBase.tree=i.createTree(c,a),i.updateRowHeaderWidth(c),i.sortTree(c),i.fixFilter(c),i.renderTree(c.treeBase.tree)},updateRowHeaderWidth:function(a){var c=a.getColumn(b.rowHeaderColName),d=a.options.treeRowHeaderBaseWidth+a.options.treeIndent*Math.max(a.treeBase.numberLevels-1,0);c&&d!==c.width&&(c.width=d,a.queueRefresh());var e=!0;a.options.showTreeRowHeader===!1&&(e=!1),a.options.treeRowHeaderAlwaysVisible===!1&&a.treeBase.numberLevels<=0&&(e=!1),c.visible!==e&&(c.visible=e,c.colDef.visible=e,a.queueGridRefresh())},renderTree:function(a){var c=[];return a.forEach(function(a){a.row.visible&&c.push(a.row),a.state===b.EXPANDED&&a.children&&a.children.length>0&&(c=c.concat(i.renderTree(a.children)))}),c},createTree:function(a,c){var d,e=-1,f=[];a.treeBase.tree=[],a.treeBase.numberLevels=0;var g=i.getAggregations(a),h=function(c){if("undefined"!=typeof c.entity.$$treeLevel&&c.treeLevel!==c.entity.$$treeLevel&&(c.treeLevel=c.entity.$$treeLevel),c.treeLevel<=e){for(;c.treeLevel<=e;){var h=f.pop();i.finaliseAggregations(h),e--}d=f.length>0?i.setCurrentState(f):b.EXPANDED}("undefined"==typeof c.treeLevel||null===c.treeLevel||c.treeLevel<0)&&c.visible&&i.aggregate(a,c,f),i.addOrUseNode(a,c,f,g),"undefined"!=typeof c.treeLevel&&null!==c.treeLevel&&c.treeLevel>=0&&(f.push(c),e++,d=i.setCurrentState(f)),a.treeBase.numberLevels0;){var j=f.pop();i.finaliseAggregations(j)}return a.treeBase.tree},addOrUseNode:function(a,c,d,e){var f=[];e.forEach(function(a){f.push(i.buildAggregationObject(a.col))});var g={state:b.COLLAPSED,row:c,parentRow:null,aggregations:f,children:[]};c.treeNode&&(g.state=c.treeNode.state),d.length>0&&(g.parentRow=d[d.length-1]),c.treeNode=g,0===d.length?a.treeBase.tree.push(g):d[d.length-1].treeNode.children.push(g)},setCurrentState:function(a){var c=b.EXPANDED;return a.forEach(function(a){a.treeNode.state===b.COLLAPSED&&(c=b.COLLAPSED)}),c},sortTree:function(a){a.columns.forEach(function(a){a.sort&&a.sort.ignoreSort&&delete a.sort.ignoreSort}),a.treeBase.tree=i.sortInternal(a,a.treeBase.tree)},sortInternal:function(a,c){var d=c.map(function(a){return a.row});d=h.sort(a,d,a.columns);var e=d.map(function(a){return a.treeNode});return e.forEach(function(c){c.state===b.EXPANDED&&c.children&&c.children.length>0&&(c.children=i.sortInternal(a,c.children))}),e},fixFilter:function(a){var b;a.treeBase.tree.forEach(function(a){a.children&&a.children.length>0&&(b=a.row.visible,i.fixFilterInternal(a.children,b))})},fixFilterInternal:function(a,b){return a.forEach(function(a){a.row.visible&&!b&&(i.setParentsVisible(a),b=!0),a.children&&a.children.length>0&&i.fixFilterInternal(a.children,b&&a.row.visible)&&(b=!0)}),b},setParentsVisible:function(a){for(;a.parentRow;)a.parentRow.visible=!0,a=a.parentRow.treeNode},buildAggregationObject:function(a){var b={col:a};return a.treeAggregation&&a.treeAggregation.type&&(b.type=a.treeAggregation.type),a.treeAggregation&&a.treeAggregation.label&&(b.label=a.treeAggregation.label),b},getAggregations:function(a){var b=[];return a.columns.forEach(function(c){"undefined"!=typeof c.treeAggregationFn&&(b.push(i.buildAggregationObject(c)),a.options.showColumnFooter&&"undefined"==typeof c.colDef.aggregationType&&c.treeAggregation&&(c.treeFooterAggregation=i.buildAggregationObject(c),c.aggregationType=i.treeFooterAggregationType))}),b},aggregate:function(a,b,c){0===c.length&&b.treeNode&&b.treeNode.aggregations&&b.treeNode.aggregations.forEach(function(c){if("undefined"!=typeof c.col.treeFooterAggregation){var d=a.getCellValue(b,c.col),e=Number(d);c.col.treeAggregationFn(c.col.treeFooterAggregation,d,e,b)}}),c.forEach(function(c,d){c.treeNode.aggregations&&c.treeNode.aggregations.forEach(function(c){var e=a.getCellValue(b,c.col),f=Number(e);c.col.treeAggregationFn(c,e,f,b),0===d&&"undefined"!=typeof c.col.treeFooterAggregation&&c.col.treeAggregationFn(c.col.treeFooterAggregation,e,f,b)})})},nativeAggregations:function(){var a={count:{label:f.get().aggregation.count,menuTitle:f.get().grouping.aggregate_count,aggregationFn:function(a,b,c){"undefined"==typeof a.value?a.value=1:a.value++}},sum:{label:f.get().aggregation.sum,menuTitle:f.get().grouping.aggregate_sum,aggregationFn:function(a,b,c){isNaN(c)||("undefined"==typeof a.value?a.value=c:a.value+=c)}},min:{label:f.get().aggregation.min,menuTitle:f.get().grouping.aggregate_min,aggregationFn:function(a,b,c){"undefined"==typeof a.value?a.value=b:"undefined"!=typeof b&&null!==b&&(ba.value||null===a.value)&&(a.value=b)}},avg:{label:f.get().aggregation.avg,menuTitle:f.get().grouping.aggregate_avg,aggregationFn:function(a,b,c){"undefined"==typeof a.count?a.count=1:a.count++,isNaN(c)||("undefined"==typeof a.value||"undefined"==typeof a.sum?(a.value=c,a.sum=c):(a.sum+=c,a.value=a.sum/a.count))}}};return a},finaliseAggregation:function(a,b){b.col.treeAggregationUpdateEntity&&"undefined"!=typeof a&&"undefined"!=typeof a.entity["$$"+b.col.uid]&&angular.extend(b,a.entity["$$"+b.col.uid]),"function"==typeof b.col.treeAggregationFinalizerFn&&b.col.treeAggregationFinalizerFn(b),"function"==typeof b.col.customTreeAggregationFinalizerFn&&b.col.customTreeAggregationFinalizerFn(b),"undefined"==typeof b.rendered&&(b.rendered=b.label?b.label+b.value:b.value)},finaliseAggregations:function(a){"undefined"!=typeof a.treeNode.aggregations&&a.treeNode.aggregations.forEach(function(b){if(i.finaliseAggregation(a,b),b.col.treeAggregationUpdateEntity){var c={};angular.forEach(b,function(a,d){b.hasOwnProperty(d)&&"col"!==d&&(c[d]=a)}),a.entity["$$"+b.col.uid]=c}})},treeFooterAggregationType:function(a,b){return i.finaliseAggregation(void 0,b.treeFooterAggregation),"undefined"==typeof b.treeFooterAggregation.value||null===b.treeFooterAggregation.rendered?"":b.treeFooterAggregation.rendered}};return i}]),a.directive("uiGridTreeBaseRowHeaderButtons",["$templateCache","uiGridTreeBaseService",function(a,b){return{replace:!0,restrict:"E",template:a.get("ui-grid/treeBaseRowHeaderButtons"),scope:!0,require:"^uiGrid",link:function(a,c,d,e){var f=e.grid;a.treeButtonClick=function(a,c){b.toggleRowTreeState(f,a,c)}}}}]),a.directive("uiGridTreeBaseExpandAllButtons",["$templateCache","uiGridTreeBaseService",function(a,b){return{replace:!0,restrict:"E",template:a.get("ui-grid/treeBaseExpandAllButtons"),scope:!1,link:function(a,c,d,e){var f=a.col.grid;a.headerButtonClick=function(a,c){f.treeBase.expandAll?b.collapseAllRows(f,c):b.expandAllRows(f,c)}}}}]),a.directive("uiGridViewport",["$compile","uiGridConstants","gridUtil","$parse",function(a,b,c,d){return{priority:-200,scope:!1,compile:function(a,b){var c=angular.element(a.children().children()[0]),d=c.attr("ng-class"),e="";return e=d?d.slice(0,-1)+",'ui-grid-tree-header-row': row.treeLevel > -1}":"{'ui-grid-tree-header-row': row.treeLevel > -1}",c.attr("ng-class",e),{pre:function(a,b,c,d){},post:function(a,b,c,d){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.treeView",["ui.grid","ui.grid.treeBase"]);a.constant("uiGridTreeViewConstants",{featureName:"treeView",rowHeaderColName:"treeBaseRowHeaderCol",EXPANDED:"expanded",COLLAPSED:"collapsed",aggregation:{COUNT:"count",SUM:"sum",MAX:"max",MIN:"min",AVG:"avg"}}),a.service("uiGridTreeViewService",["$q","uiGridTreeViewConstants","uiGridTreeBaseConstants","uiGridTreeBaseService","gridUtil","GridRow","gridClassFactory","i18nService","uiGridConstants",function(a,b,c,d,e,f,g,h,i){var j={initializeGrid:function(a,b){d.initializeGrid(a,b),a.treeView={},a.registerRowsProcessor(j.adjustSorting,60);var c={events:{treeView:{}},methods:{treeView:{}}};a.api.registerEventsFromObject(c.events),a.api.registerMethodsFromObject(c.methods)},defaultGridOptions:function(a){a.enableTreeView=a.enableTreeView!==!1},adjustSorting:function(a){var b=this;return b.columns.forEach(function(a){a.sort&&(a.sort.ignoreSort=!0)}),a}};return j}]),a.directive("uiGridTreeView",["uiGridTreeViewConstants","uiGridTreeViewService","$templateCache",function(a,b,c){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){e.grid.options.enableTreeView!==!1&&b.initializeGrid(e.grid,a)},post:function(a,b,c,d){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.validate",["ui.grid"]);a.service("uiGridValidateService",["$sce","$q","$http","i18nService","uiGridConstants",function(a,b,c,d,e){var f={validatorFactories:{},setExternalFactoryFunction:function(a){f.externalFactoryFunction=a},clearExternalFactory:function(){delete f.externalFactoryFunction},getValidatorFromExternalFactory:function(a,b){return f.externalFactoryFunction(a,b).validatorFactory(b)},getMessageFromExternalFactory:function(a,b){return f.externalFactoryFunction(a,b).messageFunction(b)},setValidator:function(a,b,c){f.validatorFactories[a]={validatorFactory:b,messageFunction:c}},getValidator:function(a,b){if(f.externalFactoryFunction){var c=f.getValidatorFromExternalFactory(a,b);if(c)return c}if(!f.validatorFactories[a])throw"Invalid validator name: "+a;return f.validatorFactories[a].validatorFactory(b)},getMessage:function(a,b){if(f.externalFactoryFunction){var c=f.getMessageFromExternalFactory(a,b);if(c)return c}return f.validatorFactories[a].messageFunction(b)},isInvalid:function(a,b){return a["$$invalid"+b.name]},setInvalid:function(a,b){a["$$invalid"+b.name]=!0},setValid:function(a,b){delete a["$$invalid"+b.name]},setError:function(a,b,c){a["$$errors"+b.name]||(a["$$errors"+b.name]={}),a["$$errors"+b.name][c]=!0},clearError:function(a,b,c){a["$$errors"+b.name]&&c in a["$$errors"+b.name]&&delete a["$$errors"+b.name][c]},getErrorMessages:function(a,b){var c=[];return a["$$errors"+b.name]&&0!==Object.keys(a["$$errors"+b.name]).length?(Object.keys(a["$$errors"+b.name]).sort().forEach(function(a){c.push(f.getMessage(a,b.validators[a]))}),c):c},getFormattedErrors:function(b,c){var e="",g=f.getErrorMessages(b,c);return g.length?(g.forEach(function(a){e+=a+"
"}),a.trustAsHtml("

"+d.getSafeText("validate.error")+"

"+e)):void 0},getTitleFormattedErrors:function(b,c){var e="\n",g="",h=f.getErrorMessages(b,c);return h.length?(h.forEach(function(a){g+=a+e}),a.trustAsHtml(d.getSafeText("validate.error")+e+g)):void 0},runValidators:function(a,c,d,e,g){if(d!==e){if("undefined"==typeof c.name||!c.name)throw new Error("colDef.name is required to perform validation");f.setValid(a,c);var h=function(a,b,c){return function(h){h||(f.setInvalid(a,b),f.setError(a,b,c),g&&g.api.validate.raise.validationFailed(a,b,d,e))}};for(var i in c.validators){f.clearError(a,c,i);var j=f.getValidator(i,c.validators[i]);b.when(j(e,d,a,c)).then(h(a,c,i))}}},createDefaultValidators:function(){f.setValidator("minLength",function(a){return function(b,c,d,e){return void 0===c||null===c||""===c?!0:c.length>=a}},function(a){return d.getSafeText("validate.minLength").replace("THRESHOLD",a)}),f.setValidator("maxLength",function(a){return function(b,c,d,e){return void 0===c||null===c||""===c?!0:c.length<=a}},function(a){return d.getSafeText("validate.maxLength").replace("THRESHOLD",a)}),f.setValidator("required",function(a){return function(b,c,d,e){return a?!(void 0===c||null===c||""===c):!0}},function(a){return d.getSafeText("validate.required")})},initializeGrid:function(a,b){b.validate={isInvalid:f.isInvalid,getFormattedErrors:f.getFormattedErrors,getTitleFormattedErrors:f.getTitleFormattedErrors,runValidators:f.runValidators};var c={events:{validate:{validationFailed:function(a,b,c,d){}}},methods:{validate:{isInvalid:function(a,c){return b.validate.isInvalid(a,c)},getErrorMessages:function(a,c){return b.validate.getErrorMessages(a,c)},getFormattedErrors:function(a,c){return b.validate.getFormattedErrors(a,c)},getTitleFormattedErrors:function(a,c){return b.validate.getTitleFormattedErrors(a,c)}}}};b.api.registerEventsFromObject(c.events),b.api.registerMethodsFromObject(c.methods),b.edit&&b.api.edit.on.afterCellEdit(a,function(a,c,d,e){b.validate.runValidators(a,c,d,e,b)}),f.createDefaultValidators()}};return f}]),a.directive("uiGridValidate",["gridUtil","uiGridValidateService",function(a,b){return{priority:0,replace:!0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.initializeGrid(a,e.grid)},post:function(a,b,c,d){}}}}}])}(),angular.module("ui.grid").run(["$templateCache",function(a){"use strict";a.put("ui-grid/ui-grid-filter",'
 
 
'),a.put("ui-grid/ui-grid-footer",''),a.put("ui-grid/ui-grid-grid-footer",''),a.put("ui-grid/ui-grid-group-panel",'
  • {{group.displayName}} x
'),a.put("ui-grid/ui-grid-header",'
'),a.put("ui-grid/ui-grid-menu-button",'
 
'),a.put("ui-grid/ui-grid-no-header",'
'),a.put("ui-grid/ui-grid-row","
"),a.put("ui-grid/ui-grid",'
'),a.put("ui-grid/uiGridCell",'
{{COL_FIELD CUSTOM_FILTERS}}
'),a.put("ui-grid/uiGridColumnMenu",'
'),a.put("ui-grid/uiGridFooterCell",'
{{ col.getAggregationText() + ( col.getAggregationValue() CUSTOM_FILTERS ) }}
'),a.put("ui-grid/uiGridHeaderCell",'
{{ col.displayName CUSTOM_FILTERS }} {{col.sort.priority + 1}}
'),a.put("ui-grid/uiGridMenu",'
'),a.put("ui-grid/uiGridMenuItem",''),a.put("ui-grid/uiGridRenderContainer","
"),a.put("ui-grid/uiGridViewport",'
'),a.put("ui-grid/cellEditor",'
'),a.put("ui-grid/dropdownEditor",'
'),a.put("ui-grid/fileChooserEditor",'
'),a.put("ui-grid/expandableRow",'
'), -a.put("ui-grid/expandableRowHeader",'
'),a.put("ui-grid/expandableScrollFiller","
"),a.put("ui-grid/expandableTopRowHeader",'
'),a.put("ui-grid/csvLink",'LINK_LABEL'),a.put("ui-grid/importerMenuItem",'
  • '),a.put("ui-grid/importerMenuItemContainer","
    "),a.put("ui-grid/pagination",''),a.put("ui-grid/columnResizer",'
    '),a.put("ui-grid/gridFooterSelectedItems",'({{"search.selectedItems" | t}} {{grid.selection.selectedCount}})'),a.put("ui-grid/selectionHeaderCell",'
    '),a.put("ui-grid/selectionRowHeader",'
    '),a.put("ui-grid/selectionRowHeaderButtons",'
     
    '),a.put("ui-grid/selectionSelectAllButtons",'
    '),a.put("ui-grid/treeBaseExpandAllButtons",'
    '),a.put("ui-grid/treeBaseHeaderCell",'
    '),a.put("ui-grid/treeBaseRowHeader",'
    '),a.put("ui-grid/treeBaseRowHeaderButtons","
    -1 }\" ng-click=\"treeButtonClick(row, $event)\"> -1 ) || ( row.treeNode.children && row.treeNode.children.length > 0 ) ) && row.treeNode.state === 'expanded', 'ui-grid-icon-plus-squared': ( ( grid.options.showTreeExpandNoChildren && row.treeLevel > -1 ) || ( row.treeNode.children && row.treeNode.children.length > 0 ) ) && row.treeNode.state === 'collapsed'}\" ng-style=\"{'padding-left': grid.options.treeIndent * row.treeLevel + 'px'}\">  
    "),a.put("ui-grid/cellTitleValidator",'
    {{COL_FIELD CUSTOM_FILTERS}}
    '),a.put("ui-grid/cellTooltipValidator",'
    {{COL_FIELD CUSTOM_FILTERS}}
    ')}]); \ No newline at end of file +!function(){"use strict";angular.module("ui.grid.i18n",[]),angular.module("ui.grid",["ui.grid.i18n"])}(),function(){"use strict";angular.module("ui.grid").constant("uiGridConstants",{LOG_DEBUG_MESSAGES:!0,LOG_WARN_MESSAGES:!0,LOG_ERROR_MESSAGES:!0,CUSTOM_FILTERS:/CUSTOM_FILTERS/g,COL_FIELD:/COL_FIELD/g,MODEL_COL_FIELD:/MODEL_COL_FIELD/g,TOOLTIP:/title=\"TOOLTIP\"/g,DISPLAY_CELL_TEMPLATE:/DISPLAY_CELL_TEMPLATE/g,TEMPLATE_REGEXP:/<.+>/,FUNC_REGEXP:/(\([^)]*\))?$/,DOT_REGEXP:/\./g,APOS_REGEXP:/'/g,BRACKET_REGEXP:/^(.*)((?:\s*\[\s*\d+\s*\]\s*)|(?:\s*\[\s*"(?:[^"\\]|\\.)*"\s*\]\s*)|(?:\s*\[\s*'(?:[^'\\]|\\.)*'\s*\]\s*))(.*)$/,COL_CLASS_PREFIX:"ui-grid-col",ENTITY_BINDING:"$$this",events:{GRID_SCROLL:"uiGridScroll",COLUMN_MENU_SHOWN:"uiGridColMenuShown",ITEM_DRAGGING:"uiGridItemDragStart",COLUMN_HEADER_CLICK:"uiGridColumnHeaderClick"},keymap:{TAB:9,STRG:17,CAPSLOCK:20,CTRL:17,CTRLRIGHT:18,CTRLR:18,SHIFT:16,RETURN:13,ENTER:13,BACKSPACE:8,BCKSP:8,ALT:18,ALTR:17,ALTRIGHT:17,SPACE:32,WIN:91,MAC:91,FN:null,PG_UP:33,PG_DOWN:34,UP:38,DOWN:40,LEFT:37,RIGHT:39,ESC:27,DEL:46,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123},ASC:"asc",DESC:"desc",filter:{STARTS_WITH:2,ENDS_WITH:4,EXACT:8,CONTAINS:16,GREATER_THAN:32,GREATER_THAN_OR_EQUAL:64,LESS_THAN:128,LESS_THAN_OR_EQUAL:256,NOT_EQUAL:512,SELECT:"select",INPUT:"input"},aggregationTypes:{sum:2,count:4,avg:8,min:16,max:32},CURRENCY_SYMBOLS:["ƒ","$","£","$","¤","¥","៛","₩","₱","฿","₫"],scrollDirection:{UP:"up",DOWN:"down",LEFT:"left",RIGHT:"right",NONE:"none"},dataChange:{ALL:"all",EDIT:"edit",ROW:"row",COLUMN:"column",OPTIONS:"options"},scrollbars:{NEVER:0,ALWAYS:1}})}(),angular.module("ui.grid").directive("uiGridCell",["$compile","$parse","gridUtil","uiGridConstants",function(a,b,c,d){var e={priority:0,scope:!1,require:"?^uiGrid",compile:function(){return{pre:function(b,e,f,g){function h(){var a=b.col.compiledElementFn;a(b,function(a,b){e.append(a)})}if(g&&b.col.compiledElementFn)h();else if(g&&!b.col.compiledElementFn)b.col.getCompiledElementFn().then(function(a){a(b,function(a,b){e.append(a)})});else{var i=b.col.cellTemplate.replace(d.MODEL_COL_FIELD,"row.entity."+c.preEval(b.col.field)).replace(d.COL_FIELD,"grid.getCellValue(row, col)"),j=a(i)(b);e.append(j)}},post:function(a,b,c,e){var f=a.col.getColClass(!1);b.addClass(f);var g,h=function(c){var d=b;g&&(d.removeClass(g),g=null),g=angular.isFunction(a.col.cellClass)?a.col.cellClass(a.grid,a.row,a.col,a.rowRenderIndex,a.colRenderIndex):a.col.cellClass,d.addClass(g)};a.col.cellClass&&h();var i=a.grid.registerDataChangeCallback(h,[d.dataChange.COLUMN,d.dataChange.EDIT]),j=function(c,d){if(c!==d){(g||a.col.cellClass)&&h();var e=a.col.getColClass(!1);e!==f&&(b.removeClass(f),b.addClass(e),f=e)}},k=a.$watch("row",j),l=function(){i(),k()};a.$on("$destroy",l),b.on("$destroy",l)}}}};return e}]),function(){angular.module("ui.grid").service("uiGridColumnMenuService",["i18nService","uiGridConstants","gridUtil",function(a,b,c){var d={initialize:function(a,b){a.grid=b.grid,b.columnMenuScope=a,a.menuShown=!1},setColMenuItemWatch:function(a){var b=a.$watch("col.menuItems",function(b){"undefined"!=typeof b&&b&&angular.isArray(b)?(b.forEach(function(b){"undefined"!=typeof b.context&&b.context||(b.context={}),b.context.col=a.col}),a.menuItems=a.defaultMenuItems.concat(b)):a.menuItems=a.defaultMenuItems});a.$on("$destroy",b)},sortable:function(a){return a.grid.options.enableSorting&&"undefined"!=typeof a.col&&a.col&&a.col.enableSorting?!0:!1},isActiveSort:function(a,b){return"undefined"!=typeof a.col&&"undefined"!=typeof a.col.sort&&"undefined"!=typeof a.col.sort.direction&&a.col.sort.direction===b},suppressRemoveSort:function(a){return a.col&&a.col.suppressRemoveSort?!0:!1},hideable:function(a){return"undefined"!=typeof a.col&&a.col&&a.col.colDef&&a.col.colDef.enableHiding===!1?!1:!0},getDefaultMenuItems:function(c){return[{title:a.getSafeText("sort.ascending"),icon:"ui-grid-icon-sort-alt-up",action:function(a){a.stopPropagation(),c.sortColumn(a,b.ASC)},shown:function(){return d.sortable(c)},active:function(){return d.isActiveSort(c,b.ASC)}},{title:a.getSafeText("sort.descending"),icon:"ui-grid-icon-sort-alt-down",action:function(a){a.stopPropagation(),c.sortColumn(a,b.DESC)},shown:function(){return d.sortable(c)},active:function(){return d.isActiveSort(c,b.DESC)}},{title:a.getSafeText("sort.remove"),icon:"ui-grid-icon-cancel",action:function(a){a.stopPropagation(),c.unsortColumn()},shown:function(){return d.sortable(c)&&"undefined"!=typeof c.col&&"undefined"!=typeof c.col.sort&&"undefined"!=typeof c.col.sort.direction&&null!==c.col.sort.direction&&!d.suppressRemoveSort(c)}},{title:a.getSafeText("column.hide"),icon:"ui-grid-icon-cancel",shown:function(){return d.hideable(c)},action:function(a){a.stopPropagation(),c.hideColumn()}}]},getColumnElementPosition:function(a,b,d){var e={};return e.left=d[0].offsetLeft,e.top=d[0].offsetTop,e.parentLeft=d[0].offsetParent.offsetLeft,e.offset=0,b.grid.options.offsetLeft&&(e.offset=b.grid.options.offsetLeft),e.height=c.elementHeight(d,!0),e.width=c.elementWidth(d,!0),e},repositionMenu:function(a,b,d,e,f){var g=e[0].querySelectorAll(".ui-grid-menu"),h=c.closestElm(f,".ui-grid-render-container"),i=h.getBoundingClientRect().left-a.grid.element[0].getBoundingClientRect().left,j=h.querySelectorAll(".ui-grid-viewport")[0].scrollLeft,k=b.lastMenuWidth?b.lastMenuWidth:a.lastMenuWidth?a.lastMenuWidth:170,l=b.lastMenuPaddingRight?b.lastMenuPaddingRight:a.lastMenuPaddingRight?a.lastMenuPaddingRight:10;if(0!==g.length){var m=g[0].querySelectorAll(".ui-grid-menu-mid");0===m.length||angular.element(m).hasClass("ng-hide")||(k=c.elementWidth(g,!0),a.lastMenuWidth=k,b.lastMenuWidth=k,l=parseInt(c.getStyles(angular.element(g)[0]).paddingRight,10),a.lastMenuPaddingRight=l,b.lastMenuPaddingRight=l)}var n=d.left+i-j+d.parentLeft+d.width-k+l;nc)d=b;else{if(c>a&&!d)return d=b,!0;if(c>a&&d)return!0}}),d){var g=d.getColClass();b.focus.bySelector(e,".ui-grid-header-cell."+g+" .ui-grid-header-cell-primary-focus",!0).then(angular.noop,function(a){return"canceled"!==a?c():void 0})}else c()})};f.hideColumn=function(){f.col.colDef.visible=!1,f.col.visible=!1,f.grid.queueGridRefresh(),f.hideMenu(),f.grid.api.core.notifyDataChange(c.dataChange.COLUMN),f.grid.api.core.raise.columnVisibilityChanged(f.col),j()}},controller:["$scope",function(a){var b=this;a.$watch("menuItems",function(a){b.menuItems=a})}]};return f}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridFilter",["$compile","$templateCache","i18nService","gridUtil",function(a,b,c,d){return{compile:function(){return{pre:function(b,c,d,e){b.col.updateFilters=function(d){if(c.children().remove(),d){var e=b.col.filterHeaderTemplate;c.append(a(e)(b))}},b.$on("$destroy",function(){delete b.col.updateFilters})},post:function(a,b,e,f){a.aria=c.getSafeText("headerCell.aria"),a.removeFilter=function(a,c){a.term=null,d.focus.bySelector(b,".ui-grid-filter-input-"+c)}}}}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridFooterCell",["$timeout","gridUtil","uiGridConstants","$compile",function(a,b,c,d){var e={priority:0,scope:{col:"=",row:"=",renderIndex:"="},replace:!0,require:"^uiGrid",compile:function(a,b,e){return{pre:function(a,b,c,e){var f=d(a.col.footerCellTemplate)(a);b.append(f)},post:function(a,b,d,e){a.grid=e.grid;var f=a.col.getColClass(!1);b.addClass(f);var g,h=function(c){var d=b;g&&(d.removeClass(g),g=null),g=angular.isFunction(a.col.footerCellClass)?a.col.footerCellClass(a.grid,a.row,a.col,a.rowRenderIndex,a.colRenderIndex):a.col.footerCellClass,d.addClass(g)};a.col.footerCellClass&&h(),a.col.updateAggregationValue();var i=a.grid.registerDataChangeCallback(h,[c.dataChange.COLUMN]);a.grid.api.core.on.rowsRendered(a,a.col.updateAggregationValue),a.grid.api.core.on.rowsRendered(a,h),a.$on("$destroy",i)}}}};return e}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridFooter",["$templateCache","$compile","uiGridConstants","gridUtil","$timeout",function(a,b,c,d,e){return{restrict:"EA",replace:!0,require:["^uiGrid","^uiGridRenderContainer"],scope:!0,compile:function(a,c){return{pre:function(a,c,e,f){var g=f[0],h=f[1];a.grid=g.grid,a.colContainer=h.colContainer,h.footer=c;var i=a.grid.options.footerTemplate;d.getTemplate(i).then(function(d){var e=angular.element(d),f=b(e)(a);if(c.append(f),h){var g=c[0].getElementsByClassName("ui-grid-footer-viewport")[0];g&&(h.footerViewport=g)}})},post:function(a,b,c,e){var f=e[0],g=e[1];f.grid;d.disableAnimations(b),g.footer=b;var h=b[0].getElementsByClassName("ui-grid-footer-viewport")[0];h&&(g.footerViewport=h)}}}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridGridFooter",["$templateCache","$compile","uiGridConstants","gridUtil","$timeout",function(a,b,c,d,e){return{restrict:"EA",replace:!0,require:"^uiGrid",scope:!0,compile:function(a,c){return{pre:function(a,c,e,f){a.grid=f.grid;var g=a.grid.options.gridFooterTemplate;d.getTemplate(g).then(function(d){var e=angular.element(d),f=b(e)(a);c.append(f)})},post:function(a,b,c,d){}}}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridGroupPanel",["$compile","uiGridConstants","gridUtil",function(a,b,c){var d="ui-grid/ui-grid-group-panel";return{restrict:"EA",replace:!0,require:"?^uiGrid",scope:!1,compile:function(b,e){return{pre:function(b,e,f,g){var h=b.grid.options.groupPanelTemplate||d;c.getTemplate(h).then(function(c){var d=angular.element(c),f=a(d)(b);e.append(f)})},post:function(a,b,c,d){b.bind("$destroy",function(){})}}}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridHeaderCell",["$compile","$timeout","$window","$document","gridUtil","uiGridConstants","ScrollEvent","i18nService",function(a,b,c,d,e,f,g,h){var i=500,j=500,k={priority:0,scope:{col:"=",row:"=",renderIndex:"="},require:["^uiGrid","^uiGridRenderContainer"],replace:!0,compile:function(){return{pre:function(b,c,d){var e=a(b.col.headerCellTemplate)(b);c.append(e)},post:function(a,c,e,g){var k=g[0],l=g[1];a.i18n={headerCell:h.getSafeText("headerCell"),sort:h.getSafeText("sort")},a.isSortPriorityVisible=function(){return angular.isNumber(a.col.sort.priority)&&a.grid.columns.some(function(b,c){return angular.isNumber(b.sort.priority)&&b!==a.col})},a.getSortDirectionAriaLabel=function(){var b=a.col,c=b.sort.direction===f.ASC?a.i18n.sort.ascending:b.sort.direction===f.DESC?a.i18n.sort.descending:a.i18n.sort.none,d=c;return a.isSortPriorityVisible()&&(d=d+". "+a.i18n.headerCell.priority+" "+b.sort.priority),d},a.grid=k.grid,a.renderContainer=k.grid.renderContainers[l.containerId];var m=a.col.getColClass(!1);c.addClass(m),a.menuShown=!1,a.asc=f.ASC,a.desc=f.DESC;var n,o,p=(angular.element(c[0].querySelectorAll(".ui-grid-header-cell-menu")),angular.element(c[0].querySelectorAll(".ui-grid-cell-contents"))),q=[];a.downFn=function(e){e.stopPropagation(),"undefined"!=typeof e.originalEvent&&void 0!==e.originalEvent&&(e=e.originalEvent),e.button&&0!==e.button||(o=e.pageX,a.mousedownStartTime=(new Date).getTime(),a.mousedownTimeout=b(function(){},i),a.mousedownTimeout.then(function(){a.colMenu&&k.columnMenuScope.showMenu(a.col,c,e)}),k.fireEvent(f.events.COLUMN_HEADER_CLICK,{event:e,columnName:a.col.colDef.name}),a.offAllEvents(),"touchstart"===e.type?(d.on("touchend",a.upFn),d.on("touchmove",a.moveFn)):"mousedown"===e.type&&(d.on("mouseup",a.upFn),d.on("mousemove",a.moveFn)))},a.upFn=function(c){c.stopPropagation(),b.cancel(a.mousedownTimeout),a.offAllEvents(),a.onDownEvents(c.type);var d=(new Date).getTime(),e=d-a.mousedownStartTime;e>i||a.sortable&&a.handleClick(c)},a.moveFn=function(c){var d=c.pageX-o;0!==d&&(b.cancel(a.mousedownTimeout),a.offAllEvents(),a.onDownEvents(c.type))},a.clickFn=function(b){b.stopPropagation(),p.off("click",a.clickFn)},a.offAllEvents=function(){p.off("touchstart",a.downFn),p.off("mousedown",a.downFn),d.off("touchend",a.upFn),d.off("mouseup",a.upFn),d.off("touchmove",a.moveFn),d.off("mousemove",a.moveFn),p.off("click",a.clickFn)},a.onDownEvents=function(c){switch(c){case"touchmove":case"touchend":p.on("click",a.clickFn),p.on("touchstart",a.downFn),b(function(){p.on("mousedown",a.downFn)},j);break;case"mousemove":case"mouseup":p.on("click",a.clickFn),p.on("mousedown",a.downFn),b(function(){p.on("touchstart",a.downFn)},j);break;default:p.on("click",a.clickFn),p.on("touchstart",a.downFn),p.on("mousedown",a.downFn)}};var r=function(d){var e=c;n&&(e.removeClass(n),n=null),n=angular.isFunction(a.col.headerCellClass)?a.col.headerCellClass(a.grid,a.row,a.col,a.rowRenderIndex,a.colRenderIndex):a.col.headerCellClass,e.addClass(n),b(function(){var b=a.grid.renderContainers.right?a.grid.renderContainers.right:a.grid.renderContainers.body;a.isLastCol=a.col===b.visibleColumnCache[b.visibleColumnCache.length-1]}),k.grid.options.enableSorting&&a.col.enableSorting?a.sortable=!0:a.sortable=!1;var g=a.filterable;k.grid.options.enableFiltering&&a.col.enableFiltering?a.filterable=!0:a.filterable=!1,g!==a.filterable&&("undefined"!=typeof a.col.updateFilters&&a.col.updateFilters(a.filterable),a.filterable?(a.col.filters.forEach(function(b,c){q.push(a.$watch("col.filters["+c+"].term",function(a,b){a!==b&&(k.grid.api.core.raise.filterChanged(),k.grid.api.core.notifyDataChange(f.dataChange.COLUMN),k.grid.queueGridRefresh())}))}),a.$on("$destroy",function(){q.forEach(function(a){a()})})):q.forEach(function(a){a()})),a.col.grid.options&&a.col.grid.options.enableColumnMenus!==!1&&a.col.colDef&&a.col.colDef.enableColumnMenu!==!1?a.colMenu=!0:a.colMenu=!1,a.offAllEvents(),(a.sortable||a.colMenu)&&(a.onDownEvents(),a.$on("$destroy",function(){a.offAllEvents()}))};r();var s=a.grid.registerDataChangeCallback(r,[f.dataChange.COLUMN]);a.$on("$destroy",s),a.handleClick=function(b){var c=!1;b.shiftKey&&(c=!0),k.grid.sortColumn(a.col,c).then(function(){k.columnMenuScope&&k.columnMenuScope.hideMenu(),k.grid.refresh()})},a.toggleMenu=function(b){b.stopPropagation(),k.columnMenuScope.menuShown&&k.columnMenuScope.col===a.col?k.columnMenuScope.hideMenu():k.columnMenuScope.showMenu(a.col,c)}}}}};return k}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridHeader",["$templateCache","$compile","uiGridConstants","gridUtil","$timeout","ScrollEvent",function(a,b,c,d,e,f){var g="ui-grid/ui-grid-header",h="ui-grid/ui-grid-no-header";return{restrict:"EA",replace:!0,require:["^uiGrid","^uiGridRenderContainer"],scope:!0,compile:function(a,c){return{pre:function(a,c,e,i){function j(){m.header=m.colContainer.header=c;var a=c[0].getElementsByClassName("ui-grid-header-canvas");a.length>0?m.headerCanvas=m.colContainer.headerCanvas=a[0]:m.headerCanvas=null}function k(a){if(!l.grid.isScrollingHorizontally){var b=d.normalizeScrollLeft(m.headerViewport,l.grid),c=m.colContainer.scrollHorizontal(b),e=new f(l.grid,null,m.colContainer,f.Sources.ViewPortScroll);e.newScrollLeft=b,c>-1&&(e.x={percentage:c}),l.grid.scrollContainers(null,e)}}var l=i[0],m=i[1];a.grid=l.grid,a.colContainer=m.colContainer,j();var n;n=a.grid.options.showHeader?a.grid.options.headerTemplate?a.grid.options.headerTemplate:g:h,d.getTemplate(n).then(function(d){var e=angular.element(d),f=b(e)(a);if(c.replaceWith(f),c=f,j(),m){var g=c[0].getElementsByClassName("ui-grid-header-viewport")[0];g&&(m.headerViewport=g,angular.element(g).on("scroll",k),a.$on("$destroy",function(){angular.element(g).off("scroll",k)}))}a.grid.queueRefresh()})},post:function(a,b,c,e){function f(){var a=h.colContainer.visibleColumnCache,b="",c=0;return a.forEach(function(a){b+=a.getColClassDefinition(),c+=a.drawnWidth}),h.colContainer.canvasWidth=c,b}var g=e[0],h=e[1];g.grid;d.disableAnimations(b),h.header=b;var i=b[0].getElementsByClassName("ui-grid-header-viewport")[0];i&&(h.headerViewport=i),g&&g.grid.registerStyleComputation({priority:15,func:f})}}}}}])}(),function(){angular.module("ui.grid").service("uiGridGridMenuService",["gridUtil","i18nService","uiGridConstants",function(a,b,c){var d={initialize:function(a,b){b.gridMenuScope=a,a.grid=b,a.registeredMenuItems=[],a.$on("$destroy",function(){a.grid&&a.grid.gridMenuScope&&(a.grid.gridMenuScope=null),a.grid&&(a.grid=null),a.registeredMenuItems&&(a.registeredMenuItems=null)}),a.registeredMenuItems=[],b.api.registerMethod("core","addToGridMenu",d.addToGridMenu),b.api.registerMethod("core","removeFromGridMenu",d.removeFromGridMenu)},addToGridMenu:function(b,c){angular.isArray(c)?b.gridMenuScope?(b.gridMenuScope.registeredMenuItems=b.gridMenuScope.registeredMenuItems?b.gridMenuScope.registeredMenuItems:[],b.gridMenuScope.registeredMenuItems=b.gridMenuScope.registeredMenuItems.concat(c)):a.logError("Asked to addToGridMenu, but gridMenuScope not present. Timing issue? Please log issue with ui-grid"):a.logError("addToGridMenu: menuItems must be an array, and is not, not adding any items")},removeFromGridMenu:function(b,c){var d=-1;b&&b.gridMenuScope&&b.gridMenuScope.registeredMenuItems.forEach(function(b,e){b.id===c&&(d>-1?a.logError("removeFromGridMenu: found multiple items with the same id, removing only the last"):d=e)}),d>-1&&b.gridMenuScope.registeredMenuItems.splice(d,1)},getMenuItems:function(c){var e=[];c.grid.options.gridMenuCustomItems&&(angular.isArray(c.grid.options.gridMenuCustomItems)?e=e.concat(c.grid.options.gridMenuCustomItems):a.logError("gridOptions.gridMenuCustomItems must be an array, and is not"));var f=[{title:b.getSafeText("gridMenu.clearAllFilters"),action:function(a){c.grid.clearAllFilters(void 0,!0,void 0)},shown:function(){return c.grid.options.enableFiltering},order:100}];return e=e.concat(f),e=e.concat(c.registeredMenuItems),c.grid.options.gridMenuShowHideColumns!==!1&&(e=e.concat(d.showHideColumns(c))),e.sort(function(a,b){return a.order-b.order}),e},showHideColumns:function(a){var c=[];return a.grid.options.columnDefs&&0!==a.grid.options.columnDefs.length&&0!==a.grid.columns.length?(c.push({title:b.getSafeText("gridMenu.columns"),order:300}),a.grid.options.gridMenuTitleFilter=a.grid.options.gridMenuTitleFilter?a.grid.options.gridMenuTitleFilter:function(a){return a},a.grid.options.columnDefs.forEach(function(b,e){if(b.enableHiding!==!1){var f={icon:"ui-grid-icon-ok",action:function(a){a.stopPropagation(),d.toggleColumnVisibility(this.context.gridCol)},shown:function(){return this.context.gridCol.colDef.visible===!0||void 0===this.context.gridCol.colDef.visible},context:{gridCol:a.grid.getColumn(b.name||b.field)},leaveOpen:!0,order:301+2*e};d.setMenuItemTitle(f,b,a.grid),c.push(f),f={icon:"ui-grid-icon-cancel",action:function(a){a.stopPropagation(),d.toggleColumnVisibility(this.context.gridCol)},shown:function(){return!(this.context.gridCol.colDef.visible===!0||void 0===this.context.gridCol.colDef.visible)},context:{gridCol:a.grid.getColumn(b.name||b.field)},leaveOpen:!0,order:301+2*e+1},d.setMenuItemTitle(f,b,a.grid),c.push(f)}}),c):c},setMenuItemTitle:function(b,c,d){var e=d.options.gridMenuTitleFilter(c.displayName||a.readableColumnName(c.name)||c.field);"string"==typeof e?b.title=e:e.then?(b.title="",e.then(function(a){b.title=a},function(a){b.title=a})):(a.logError("Expected gridMenuTitleFilter to return a string or a promise, it has returned neither, bad config"),b.title="badconfig")},toggleColumnVisibility:function(a){a.colDef.visible=!(a.colDef.visible===!0||void 0===a.colDef.visible),a.grid.refresh(),a.grid.api.core.notifyDataChange(c.dataChange.COLUMN),a.grid.api.core.raise.columnVisibilityChanged(a)}};return d}]).directive("uiGridMenuButton",["gridUtil","uiGridConstants","uiGridGridMenuService","i18nService",function(a,b,c,d){return{priority:0,scope:!0,require:["^uiGrid"],templateUrl:"ui-grid/ui-grid-menu-button",replace:!0,link:function(b,e,f,g){var h=g[0];b.i18n={aria:d.getSafeText("gridMenu.aria")},c.initialize(b,h.grid),b.shown=!1,b.toggleMenu=function(){b.shown?(b.$broadcast("hide-menu"),b.shown=!1):(b.menuItems=c.getMenuItems(b),b.$broadcast("show-menu"),b.shown=!0)},b.$on("menu-hidden",function(){b.shown=!1,a.focus.bySelector(e,".ui-grid-icon-container")})}}}])}(),function(){angular.module("ui.grid").directive("uiGridMenu",["$compile","$timeout","$window","$document","gridUtil","uiGridConstants","i18nService",function(a,b,c,d,e,f,g){var h={priority:0,scope:{menuItems:"=",autoHide:"=?"},require:"?^uiGrid",templateUrl:"ui-grid/uiGridMenu",replace:!1,link:function(a,d,h,i){a.dynamicStyles="";var j=function(b){var c=b-i.grid.headerHeight-20;a.dynamicStyles=[".grid"+i.grid.id+" .ui-grid-menu-mid {","max-height: "+c+"px;","}"].join(" ")};i&&(j(i.grid.gridHeight),i.grid.api.core.on.gridDimensionChanged(a,function(a,b,c,d){j(c)})),a.i18n={close:g.getSafeText("columnMenu.close")},a.showMenu=function(c,f){a.shown?a.shownMid||(a.shownMid=!0,a.$emit("menu-shown")):(a.shown=!0,b(function(){a.shownMid=!0,a.$emit("menu-shown")}));var g="click";f&&f.originalEvent&&f.originalEvent.type&&"touchstart"===f.originalEvent.type&&(g=f.originalEvent.type),angular.element(document).off("click touchstart",k),d.off("keyup",l),d.off("keydown",m),b(function(){angular.element(document).on(g,k),d.on("keyup",l),d.on("keydown",m)}),e.focus.bySelector(d,"button[type=button]",!0)},a.hideMenu=function(c){a.shown&&(a.shownMid=!1,b(function(){a.shownMid||(a.shown=!1,a.$emit("menu-hidden"))},200)),angular.element(document).off("click touchstart",k),d.off("keyup",l),d.off("keydown",m)},a.$on("hide-menu",function(b,c){a.hideMenu(b,c)}),a.$on("show-menu",function(b,c){a.showMenu(b,c)});var k=function(){a.shown&&a.$apply(function(){a.hideMenu()})},l=function(b){27===b.keyCode&&a.hideMenu()},m=function(a){var b=function(b){return b.focus(),a.preventDefault(),!1};if(9===a.keyCode){var c,e,f=d[0].querySelectorAll("button:not(.ng-hide)");f.length>0&&(c=f[0],e=f[f.length-1],a.target!==e||a.shiftKey?a.target===c&&a.shiftKey&&b(e):b(c))}};("undefined"==typeof a.autoHide||void 0===a.autoHide)&&(a.autoHide=!0),a.autoHide&&angular.element(c).on("resize",k),a.$on("$destroy",function(){angular.element(document).off("click touchstart",k)}),a.$on("$destroy",function(){angular.element(c).off("resize",k)}),i&&a.$on("$destroy",i.grid.api.core.on.scrollBegin(a,k)),a.$on("$destroy",a.$on(f.events.ITEM_DRAGGING,k))}};return h}]).directive("uiGridMenuItem",["gridUtil","$compile","i18nService",function(a,b,c){var d={priority:0,scope:{name:"=",active:"=",action:"=",icon:"=",shown:"=",context:"=",templateUrl:"=",leaveOpen:"=",screenReaderOnly:"="},require:["?^uiGrid"],templateUrl:"ui-grid/uiGridMenuItem",replace:!1,compile:function(){return{pre:function(c,d){c.templateUrl&&a.getTemplate(c.templateUrl).then(function(a){var e=angular.element(a),f=b(e)(c);d.replaceWith(f)})},post:function(b,d,e,f){var g=f[0];("undefined"==typeof b.shown||null===b.shown)&&(b.shown=function(){return!0}),b.itemShown=function(){var a={};return b.context&&(a.context=b.context),"undefined"!=typeof g&&g&&(a.grid=g.grid),b.shown.call(a)},b.itemAction=function(c,e){if(c.stopPropagation(),"function"==typeof b.action){var f={};b.context&&(f.context=b.context),"undefined"!=typeof g&&g&&(f.grid=g.grid),b.action.call(f,c,e),b.leaveOpen?a.focus.bySelector(angular.element(a.closestElm(d,".ui-grid-menu-items")),"button[type=button]",!0):b.$emit("hide-menu")}},b.i18n=c.get()}}}};return d}])}(),function(){"use strict";var a=angular.module("ui.grid");angular.forEach([{tag:"Src",method:"attr"},{tag:"Text",method:"text"},{tag:"Href",method:"attr"},{tag:"Class",method:"addClass"},{tag:"Html",method:"html"},{tag:"Alt",method:"attr"},{tag:"Style",method:"css"},{tag:"Value",method:"attr"},{tag:"Id",method:"attr"},{tag:"Id",directiveName:"IdGrid",method:"attr",appendGridId:!0},{tag:"Title",method:"attr"},{tag:"Label",method:"attr",aria:!0},{tag:"Labelledby",method:"attr",aria:!0},{tag:"Labelledby",directiveName:"LabelledbyGrid",appendGridId:!0,method:"attr",aria:!0},{tag:"Describedby",method:"attr",aria:!0},{tag:"Describedby",directiveName:"DescribedbyGrid",appendGridId:!0,method:"attr",aria:!0}],function(b){var c="uiGridOneBind",d=(b.aria?c+"Aria":c)+(b.directiveName?b.directiveName:b.tag);a.directive(d,["gridUtil",function(a){return{restrict:"A",require:["?uiGrid","?^uiGrid"],link:function(c,e,f,g){var h=function(b){var e;if(c.grid)e=c.grid;else if(c.col&&c.col.grid)e=c.col.grid;else if(!g.some(function(a){return a&&a.grid?(e=a.grid,!0):void 0}))throw a.logError("["+d+"] A valid grid could not be found to bind id. Are you using this directive within the correct scope? Trying to generate id: [gridID]-"+b),new Error("No valid grid could be found");if(e){var f=new RegExp(e.id.toString());f.test(b)||(b=e.id.toString()+"-"+b)}return b},i=c.$watch(f[d],function(a){if(a){if(b.appendGridId){var c=null;angular.forEach(a.split(" "),function(a){c=(c?c+" ":"")+h(a)}),a=c}switch(b.method){case"attr":b.aria?e[b.method]("aria-"+b.tag.toLowerCase(),a):e[b.method](b.tag.toLowerCase(),a);break;case"addClass":if(angular.isObject(a)&&!angular.isArray(a)){var d=[],f=!1;if(angular.forEach(a,function(a,b){null!==a&&"undefined"!=typeof a&&(f=!0,a&&d.push(b))}),!f)return;a=d}if(!a)return;e.addClass(angular.isArray(a)?a.join(" "):a);break;default:e[b.method](a)}i()}},!0)}}}])})}(),function(){"use strict";var a=angular.module("ui.grid");a.directive("uiGridRenderContainer",["$timeout","$document","uiGridConstants","gridUtil","ScrollEvent",function(a,b,c,d,e){return{replace:!0,transclude:!0,templateUrl:"ui-grid/uiGridRenderContainer",require:["^uiGrid","uiGridRenderContainer"],scope:{containerId:"=",rowContainerName:"=",colContainerName:"=",bindScrollHorizontal:"=",bindScrollVertical:"=",enableVerticalScrollbar:"=",enableHorizontalScrollbar:"="},controller:"uiGridRenderContainer as RenderContainer",compile:function(){return{pre:function(a,b,c,d){var e=d[0],f=d[1],g=a.grid=e.grid;if(!a.rowContainerName)throw"No row render container name specified";if(!a.colContainerName)throw"No column render container name specified";if(!g.renderContainers[a.rowContainerName])throw"Row render container '"+a.rowContainerName+"' is not registered.";if(!g.renderContainers[a.colContainerName])throw"Column render container '"+a.colContainerName+"' is not registered.";var h=a.rowContainer=g.renderContainers[a.rowContainerName],i=a.colContainer=g.renderContainers[a.colContainerName];f.containerId=a.containerId,f.rowContainer=h,f.colContainer=i},post:function(a,b,c,f){function g(){var b="",c=l.canvasWidth,d=l.getViewportWidth(),e=k.getCanvasHeight(),f=k.getViewportHeight();l.needsHScrollbarPlaceholder()&&(f-=j.scrollbarHeight);var g,i;return g=i=l.getHeaderViewportWidth(),b+="\n .grid"+h.grid.id+" .ui-grid-render-container-"+a.containerId+" .ui-grid-canvas { width: "+c+"px; height: "+e+"px; }",b+="\n .grid"+h.grid.id+" .ui-grid-render-container-"+a.containerId+" .ui-grid-header-canvas { width: "+(c+j.scrollbarWidth)+"px; }",b+=o.explicitHeaderCanvasHeight?"\n .grid"+h.grid.id+" .ui-grid-render-container-"+a.containerId+" .ui-grid-header-canvas { height: "+o.explicitHeaderCanvasHeight+"px; }":"\n .grid"+h.grid.id+" .ui-grid-render-container-"+a.containerId+" .ui-grid-header-canvas { height: inherit; }",b+="\n .grid"+h.grid.id+" .ui-grid-render-container-"+a.containerId+" .ui-grid-viewport { width: "+d+"px; height: "+f+"px; }",b+="\n .grid"+h.grid.id+" .ui-grid-render-container-"+a.containerId+" .ui-grid-header-viewport { width: "+g+"px; }",b+="\n .grid"+h.grid.id+" .ui-grid-render-container-"+a.containerId+" .ui-grid-footer-canvas { width: "+(c+j.scrollbarWidth)+"px; }",b+="\n .grid"+h.grid.id+" .ui-grid-render-container-"+a.containerId+" .ui-grid-footer-viewport { width: "+i+"px; }"}var h=f[0],i=f[1],j=h.grid,k=i.rowContainer,l=i.colContainer,m=null,n=null,o=j.renderContainers[a.containerId];b.addClass("ui-grid-render-container-"+a.containerId),d.on.mousewheel(b,function(a){var b=new e(j,k,l,e.Sources.RenderContainerMouseWheel);if(0!==a.deltaY){var c=-1*a.deltaY*a.deltaFactor;m=i.viewport[0].scrollTop,b.verticalScrollLength=k.getVerticalScrollLength();var f=(m+c)/b.verticalScrollLength;f>=1&&mf?f=0:f>1&&(f=1),b.y={percentage:f,pixels:c}}if(0!==a.deltaX){var g=a.deltaX*a.deltaFactor;n=d.normalizeScrollLeft(i.viewport,j),b.horizontalScrollLength=l.getCanvasWidth()-l.getViewportWidth();var h=(n+g)/b.horizontalScrollLength;0>h?h=0:h>1&&(h=1),b.x={percentage:h,pixels:g}}0!==a.deltaY&&(b.atTop(m)||b.atBottom(m))||0!==a.deltaX&&(b.atLeft(n)||b.atRight(n))||(a.preventDefault(),a.stopPropagation(),b.fireThrottledScrollingEvent("",b))}),b.bind("$destroy",function(){b.unbind("keydown"),["touchstart","touchmove","touchend","keydown","wheel","mousewheel","DomMouseScroll","MozMousePixelScroll"].forEach(function(a){b.unbind(a)})}),h.grid.registerStyleComputation({priority:6,func:g})}}}}}]),a.controller("uiGridRenderContainer",["$scope","gridUtil",function(a,b){}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridRow",["gridUtil",function(a){return{replace:!0,require:["^uiGrid","^uiGridRenderContainer"],scope:{row:"=uiGridRow",rowRenderIndex:"="},compile:function(){return{pre:function(a,b,c,d){function e(){a.row.getRowTemplateFn.then(function(c){var d=a.$new();c(d,function(a,c){h&&(h.remove(),i.$destroy()),b.empty().append(a),h=a,i=d})})}var f=d[0],g=d[1];f.grid;a.grid=f.grid,a.colContainer=g.colContainer;var h,i;e(),a.$watch("row.getRowTemplateFn",function(a,b){a!==b&&e()})},post:function(a,b,c,d){}}}}}])}(),function(){angular.module("ui.grid").directive("uiGridStyle",["gridUtil","$interpolate",function(a,b){return{link:function(a,c,d,e){var f=b(c.text(),!0);f&&a.$watch(f,function(a){c.text(a)})}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridViewport",["gridUtil","ScrollEvent","uiGridConstants","$log",function(a,b,c,d){return{replace:!0,scope:{},controllerAs:"Viewport",templateUrl:"ui-grid/uiGridViewport",require:["^uiGrid","^uiGridRenderContainer"],link:function(c,d,e,f){function g(e){var f=d[0].scrollTop,g=a.normalizeScrollLeft(d,p),h=n.scrollVertical(f),i=o.scrollHorizontal(g),j=new b(p,n,o,b.Sources.ViewPortScroll);j.newScrollLeft=g,j.newScrollTop=f,i>-1&&(j.x={percentage:i}),h>-1&&(j.y={percentage:h}),p.scrollContainers(c.$parent.containerId,j)}function h(a){m.prevScrollArgs=a;var b=a.getNewScrollTop(n,m.viewport); +d[0].scrollTop=b}function i(b){m.prevScrollArgs=b;var c=b.getNewScrollLeft(o,m.viewport);d[0].scrollLeft=a.denormalizeScrollLeft(m.viewport,c,p)}function j(b){var c=b.getNewScrollLeft(o,m.viewport);m.headerViewport&&(m.headerViewport.scrollLeft=a.denormalizeScrollLeft(m.viewport,c,p))}function k(b){var c=b.getNewScrollLeft(o,m.viewport);m.footerViewport&&(m.footerViewport.scrollLeft=a.denormalizeScrollLeft(m.viewport,c,p))}var l=f[0],m=f[1];c.containerCtrl=m;var n=m.rowContainer,o=m.colContainer,p=l.grid;c.grid=l.grid,c.rowContainer=m.rowContainer,c.colContainer=m.colContainer,m.viewport=d,d.on("scroll",g);c.$parent.bindScrollVertical&&p.addVerticalScrollSync(c.$parent.containerId,h),c.$parent.bindScrollHorizontal&&(p.addHorizontalScrollSync(c.$parent.containerId,i),p.addHorizontalScrollSync(c.$parent.containerId+"header",j),p.addHorizontalScrollSync(c.$parent.containerId+"footer",k))},controller:["$scope",function(a){this.rowStyle=function(b){var c=a.rowContainer,d=a.colContainer,e={};if(0===b&&0!==c.currentTopRow){var f=c.currentTopRow*c.grid.options.rowHeight;e["margin-top"]=f+"px"}return 0!==d.currentFirstColumn&&(d.grid.isRTL()?e["margin-right"]=d.columnOffset+"px":e["margin-left"]=d.columnOffset+"px"),e}}]}}])}(),function(){angular.module("ui.grid").directive("uiGridVisible",function(){return function(a,b,c){a.$watch(c.uiGridVisible,function(a){b[a?"removeClass":"addClass"]("ui-grid-invisible")})}})}(),function(){"use strict";function a(a,b,c,d,e,f){return{templateUrl:"ui-grid/ui-grid",scope:{uiGrid:"="},replace:!0,transclude:!0,controller:"uiGridController",compile:function(){return{post:function(a,b,g,h){function i(){b[0].offsetWidth<=0&&p>q?(setTimeout(i,o),q++):c(k)}function j(){angular.element(d).on("resize",m),b.on("$destroy",function(){angular.element(d).off("resize",m)}),a.$watch(function(){return n.hasLeftContainer()},function(a,b){a!==b&&n.refreshCanvas(!0)}),a.$watch(function(){return n.hasRightContainer()},function(a,b){a!==b&&n.refreshCanvas(!0)})}function k(){n.gridWidth=a.gridWidth=e.elementWidth(b),n.canvasWidth=h.grid.gridWidth,n.gridHeight=a.gridHeight=e.elementHeight(b),n.gridHeight<=n.options.rowHeight&&n.options.enableMinHeightCheck&&l(),n.refreshCanvas(!0)}function l(){var c=n.options.minRowsToShow*n.options.rowHeight,d=n.options.showHeader?n.options.headerRowHeight:0,g=n.calcFooterHeight(),h=0;n.options.enableHorizontalScrollbar===f.scrollbars.ALWAYS&&(h=e.getScrollbarWidth());var i=0;if(angular.forEach(n.options.columnDefs,function(a){a.hasOwnProperty("filter")?1>i&&(i=1):a.hasOwnProperty("filters")&&i(n.grid.rowHeaderColumns?n.grid.rowHeaderColumns.length:0);!g&&!c.uiGridColumns&&0===n.grid.options.columnDefs.length&&b.length>0&&n.grid.buildColumnDefsFromData(b),!g&&(n.grid.options.columnDefs.length>0||b.length>0)&&d.push(n.grid.buildColumns().then(function(){n.grid.preCompileCellTemplates()})),e.all(d).then(function(){n.grid.modifyRows(p).then(function(){n.grid.redrawInPlace(!0),a.$evalAsync(function(){n.grid.refreshCanvas(!0),n.grid.callDataChangeCallbacks(f.dataChange.ROW)})})})}}var n=this;n.grid=h.createGrid(a.uiGrid),n.grid.appScope=n.grid.appScope||a.$parent,b.addClass("grid"+n.grid.id),n.grid.rtl="rtl"===d.getStyles(b[0]).direction,a.grid=n.grid,c.uiGridColumns&&c.$observe("uiGridColumns",function(a){n.grid.options.columnDefs=a,n.grid.buildColumns().then(function(){n.grid.preCompileCellTemplates(),n.grid.refreshCanvas(!0)})});var o=[];n.grid.options.fastWatch?(n.uiGrid=a.uiGrid,angular.isString(a.uiGrid.data)?(o.push(a.$parent.$watch(a.uiGrid.data,m)),o.push(a.$parent.$watch(function(){return n.grid.appScope[a.uiGrid.data]?n.grid.appScope[a.uiGrid.data].length:void 0},m))):(o.push(a.$parent.$watch(function(){return a.uiGrid.data},m)),o.push(a.$parent.$watch(function(){return a.uiGrid.data.length},function(){m(a.uiGrid.data)}))),o.push(a.$parent.$watch(function(){return a.uiGrid.columnDefs},l)),o.push(a.$parent.$watch(function(){return a.uiGrid.columnDefs.length},function(){l(a.uiGrid.columnDefs)}))):(angular.isString(a.uiGrid.data)?o.push(a.$parent.$watchCollection(a.uiGrid.data,m)):o.push(a.$parent.$watchCollection(function(){return a.uiGrid.data},m)),o.push(a.$parent.$watchCollection(function(){return a.uiGrid.columnDefs},l)));var p,q=a.$watch(function(){return n.grid.styleComputations},function(){n.grid.refreshCanvas(!0)});a.$on("$destroy",function(){o.forEach(function(a){a()}),q()}),n.fireEvent=function(b,c){("undefined"==typeof c||void 0===c)&&(c={}),("undefined"==typeof c.grid||void 0===c.grid)&&(c.grid=n.grid),a.$broadcast(b,c)},n.innerCompile=function(b){k(b)(a)}}]),angular.module("ui.grid").directive("uiGrid",a),a.$inject=["$compile","$templateCache","$timeout","$window","gridUtil","uiGridConstants"]}(),function(){"use strict";angular.module("ui.grid").directive("uiGridPinnedContainer",["gridUtil",function(a){return{restrict:"EA",replace:!0,template:'
    ',scope:{side:"=uiGridPinnedContainer"},require:"^uiGrid",compile:function(){return{post:function(a,b,c,d){function e(){var a=this,b=0;a.visibleColumnCache.forEach(function(a){b+=a.drawnWidth});var c=a.getViewportAdjustment();return b+=c.width}function f(){if("left"===a.side||"right"===a.side){for(var b=h.renderContainers[a.side].visibleColumnCache,c=0,d=0;d0?b[0]:null},p.prototype.getColDef=function(a){var b=this.options.columnDefs.filter(function(b){return b.name===a});return b.length>0?b[0]:null},p.prototype.assignTypes=function(){var a=this;a.options.columnDefs.forEach(function(b,c){if(!b.type){var e=new g(b,c,a),f=a.rows.length>0?a.rows[0]:null;f?b.type=d.guessType(a.getCellValue(f,e)):b.type="string"}})},p.prototype.isRowHeaderColumn=function(a){return-1!==this.rowHeaderColumns.indexOf(a)},p.prototype.addRowHeaderColumn=function(a,b){var c=this;void 0===b&&(b=0);var e=new g(a,d.nextUid(),c);e.isRowHeader=!0,c.isRTL()?(c.createRightContainer(),e.renderContainer="right"):(c.createLeftContainer(),e.renderContainer="left"),c.columnBuilders[0](a,e,c.options).then(function(){e.enableFiltering=!1,e.enableSorting=!1,e.enableHiding=!1,e.headerPriority=b,c.rowHeaderColumns.push(e),c.rowHeaderColumns=c.rowHeaderColumns.sort(function(a,b){return a.headerPriority-b.headerPriority}),c.buildColumns().then(function(){c.preCompileCellTemplates(),c.queueGridRefresh()})})},p.prototype.getOnlyDataColumns=function(){var a=this,b=[];return a.columns.forEach(function(c){-1===a.rowHeaderColumns.indexOf(c)&&b.push(c)}),b},p.prototype.buildColumns=function(b){var c={orderByColumnDefs:!1};angular.extend(c,b);var e,f=this,h=[],i=f.rowHeaderColumns.length;for(e=0;e=0;j--)f.columns.unshift(f.rowHeaderColumns[j]);if(f.options.columnDefs.forEach(function(a,b){f.preprocessColDef(a);var c=f.getColumn(a.name);c?c.updateColumnDef(a,!1):(c=new g(a,d.nextUid(),f),f.columns.splice(b+i,0,c)),f.columnBuilders.forEach(function(b){h.push(b.call(f,a,c,f.options))})}),c.orderByColumnDefs){var k=f.columns.slice(0),l=Math.min(f.options.columnDefs.length,f.columns.length);for(e=0;l>e;e++)f.columns[e+i].name!==f.options.columnDefs[e].name?k[e+i]=f.getColumn(f.options.columnDefs[e].name):k[e+i]=f.columns[e+i];f.columns.length=0,Array.prototype.splice.apply(f.columns,[0,0].concat(k))}return a.all(h).then(function(){f.rows.length>0&&f.assignTypes()})},p.prototype.preCompileCellTemplate=function(a){var c=this,d=a.cellTemplate.replace(e.MODEL_COL_FIELD,c.getQualifiedColField(a));d=d.replace(e.COL_FIELD,"grid.getCellValue(row, col)");var f=b(d);a.compiledElementFn=f,a.compiledElementFnDefer&&a.compiledElementFnDefer.resolve(a.compiledElementFn)},p.prototype.preCompileCellTemplates=function(){var a=this;a.columns.forEach(function(b){b.cellTemplate?a.preCompileCellTemplate(b):b.cellTemplatePromise&&b.cellTemplatePromise.then(function(){a.preCompileCellTemplate(b)})})},p.prototype.getQualifiedColField=function(a){var b="row.entity";return a.field===e.ENTITY_BINDING?b:d.preEval(b+"."+a.field)},p.prototype.createLeftContainer=function(){this.hasLeftContainer()||(this.renderContainers.left=new l("left",this,{disableColumnOffset:!0}))},p.prototype.createRightContainer=function(){this.hasRightContainer()||(this.renderContainers.right=new l("right",this,{disableColumnOffset:!0}))},p.prototype.hasLeftContainer=function(){return void 0!==this.renderContainers.left},p.prototype.hasRightContainer=function(){return void 0!==this.renderContainers.right},p.prototype.preprocessColDef=function(a){var b=this;if(!a.field&&!a.name)throw new Error("colDef.name or colDef.field property is required");if(void 0===a.name&&void 0!==a.field){for(var c=a.field,d=2;b.getColumn(c);)c=a.field+d.toString(),d++;a.name=c}},p.prototype.newInN=function(a,b,c,d){for(var e=this,f=[],g=0;g0?d[0]:null},p.prototype.modifyRows=function(b){var c=this,d=c.rows.slice(0),e=c.rowHashMap||c.createRowHashMap();c.rowHashMap=c.createRowHashMap(),c.rows.length=0,b.forEach(function(a,b){var f;f=c.options.enableRowHashing?e.get(a):c.getRow(a,d),f||(f=c.processRowBuilders(new h(a,b,c))),c.rows.push(f),c.rowHashMap.put(a,f)}),c.assignTypes();var f=a.when(c.processRowsProcessors(c.rows)).then(function(a){return c.setVisibleRows(a)}),g=a.when(c.processColumnsProcessors(c.columns)).then(function(a){return c.setVisibleColumns(a)});return a.all([f,g])},p.prototype.addRows=function(a){for(var b=this,c=b.rows.length,d=0;dd)d+=e.drawnWidth,c++;else{for(var g=0,h=f;h>=f-c;h--)g+=a.columns[h].drawnWidth;b>g&&c++}}),c},p.prototype.getBodyHeight=function(){var a=this.getViewportHeight();return a},p.prototype.getViewportHeight=function(){var a=this,b=this.gridHeight-this.headerHeight-this.footerHeight,c=a.getViewportAdjustment();return b+=c.height},p.prototype.getViewportWidth=function(){var a=this,b=this.gridWidth,c=a.getViewportAdjustment();return b+=c.width},p.prototype.getHeaderViewportWidth=function(){var a=this.getViewportWidth();return a},p.prototype.addVerticalScrollSync=function(a,b){this.verticalScrollSyncCallBackFns[a]=b},p.prototype.addHorizontalScrollSync=function(a,b){this.horizontalScrollSyncCallBackFns[a]=b},p.prototype.scrollContainers=function(a,b){if(b.y){var c=["body","left","right"];this.flagScrollingVertically(b),"body"===a?c=["left","right"]:"left"===a?c=["body","right"]:"right"===a&&(c=["body","left"]);for(var d=0;d=b&&(b=a.sort.priority+1)}),b},p.prototype.resetColumnSorting=function(a){var b=this;b.columns.forEach(function(b){b===a||b.suppressRemoveSort||(b.sort={})})},p.prototype.getColumnSorting=function(){var a,b=this,c=[];return a=b.columns.slice(0),a.sort(j.prioritySort).forEach(function(a){a.sort&&"undefined"!=typeof a.sort.direction&&a.sort.direction&&(a.sort.direction===e.ASC||a.sort.direction===e.DESC)&&c.push(a)}),c},p.prototype.sortColumn=function(b,c,d){var e=this,f=null;if("undefined"==typeof b||!b)throw new Error("No column parameter provided");if("boolean"==typeof c?d=c:f=c,d?void 0===b.sort.priority&&(b.sort.priority=e.getNextColumnSortPriority()):(e.resetColumnSorting(b),b.sort.priority=void 0,b.sort.priority=e.getNextColumnSortPriority()),f)b.sort.direction=f;else{var g=b.sortDirectionCycle.indexOf(b.sort.direction?b.sort.direction:null);g=(g+1)%b.sortDirectionCycle.length,b.colDef&&b.suppressRemoveSort&&!b.sortDirectionCycle[g]&&(g=(g+1)%b.sortDirectionCycle.length),b.sortDirectionCycle[g]?b.sort.direction=b.sortDirectionCycle[g]:q(b,e)}return e.api.core.raise.sortChanged(e,e.getColumnSorting()),a.when(b)};var q=function(a,b){b.columns.forEach(function(b){b.sort&&void 0!==b.sort.priority&&b.sort.priority>a.sort.priority&&(b.sort.priority-=1)}),a.sort={}};return p.prototype.renderingComplete=function(){angular.isFunction(this.options.onRegisterApi)&&this.options.onRegisterApi(this.api),this.api.core.raise.renderingComplete(this.api)},p.prototype.createRowHashMap=function(){var a=this,b=new o;return b.grid=a,b},p.prototype.refresh=function(b){var c=this,d=c.processRowsProcessors(c.rows).then(function(a){c.setVisibleRows(a)}),e=c.processColumnsProcessors(c.columns).then(function(a){c.setVisibleColumns(a)});return a.all([d,e]).then(function(){c.redrawInPlace(b),c.refreshCanvas(!0)})},p.prototype.refreshRows=function(){var a=this;return a.processRowsProcessors(a.rows).then(function(b){a.setVisibleRows(b),a.redrawInPlace(),a.refreshCanvas(!0)})},p.prototype.refreshCanvas=function(b){var c=this;b&&c.buildStyles();var e=a.defer(),f=[];for(var g in c.renderContainers)if(c.renderContainers.hasOwnProperty(g)){var h=c.renderContainers[g];if(null===h.canvasWidth||isNaN(h.canvasWidth))continue;(h.header||h.headerCanvas)&&(h.explicitHeaderHeight=h.explicitHeaderHeight||null,h.explicitHeaderCanvasHeight=h.explicitHeaderCanvasHeight||null,f.push(h))}return f.length>0?(b&&c.buildStyles(),m(function(){var a,g,h=!1,i=0,j=0,k=function(a,b){return a!==b&&(h=!0),b};for(a=0;ao?0:o,g.innerHeaderHeight=o,!g.explicitHeaderHeight&&o>i&&(i=o)}if(g.headerCanvas){var p=g.headerCanvasHeight=k(g.headerCanvasHeight,parseInt(d.outerElementHeight(g.headerCanvas),10));!g.explicitHeaderCanvasHeight&&p>j&&(j=p)}}for(a=0;a0&&"undefined"!=typeof g.headerHeight&&null!==g.headerHeight&&(g.explicitHeaderHeight||g.headerHeight0&&"undefined"!=typeof g.headerCanvasHeight&&null!==g.headerCanvasHeight&&(g.explicitHeaderCanvasHeight||g.headerCanvasHeight0},p.prototype.hasRightContainerColumns=function(){return this.hasRightContainer()&&this.renderContainers.right.renderedColumns.length>0},p.prototype.scrollToIfNecessary=function(b,c){var d=this,e=new n(d,"uiGrid.scrollToIfNecessary"),f=d.renderContainers.body.visibleRowCache,g=d.renderContainers.body.visibleColumnCache,h=d.renderContainers.body.prevScrollTop+d.headerHeight;h=0>h?0:h;var i=d.renderContainers.body.prevScrollLeft,j=d.renderContainers.body.prevScrollTop+d.gridHeight-d.renderContainers.body.headerHeight-d.footerHeight-d.scrollbarWidth,k=d.renderContainers.body.prevScrollLeft+Math.ceil(d.renderContainers.body.getViewportWidth());if(null!==b){var l=f.indexOf(b),m=d.renderContainers.body.getCanvasHeight()-d.renderContainers.body.getViewportHeight(),o=l*d.options.rowHeight+d.headerHeight;o=0>o?0:o;var p,q;h>o?(p=d.renderContainers.body.prevScrollTop-(h-o),q=p/m,e.y={percentage:q}):o>j&&(p=o-j+d.renderContainers.body.prevScrollTop,q=p/m,e.y={percentage:q})}if(null!==c){for(var r=g.indexOf(c),s=d.renderContainers.body.getCanvasWidth()-d.renderContainers.body.getViewportWidth(),t=0,u=0;r>u;u++){var v=g[u];t+=v.drawnWidth}t=0>t?0:t;var w=t+c.drawnWidth;w=0>w?0:w;var x,y;i>t?(x=d.renderContainers.body.prevScrollLeft-(i-t),y=x/s,y=y>1?1:y,e.x={percentage:y}):w>k&&(x=w-k+d.renderContainers.body.prevScrollLeft,y=x/s,y=y>1?1:y,e.x={percentage:y})}var z=a.defer();if(e.y||e.x){e.withDelay=!1,d.scrollContainers("",e);var A=d.api.core.on.scrollEnd(null,function(){z.resolve(e),A()})}else z.resolve();return z.promise},p.prototype.scrollTo=function(a,b){var c=null,d=null;return null!==a&&"undefined"!=typeof a&&(c=this.getRow(a)),null!==b&&"undefined"!=typeof b&&(d=this.getColumn(b.name?b.name:b.field)),this.scrollToIfNecessary(c,d)},p.prototype.clearAllFilters=function(a,b,c){return void 0===a&&(a=!0),void 0===b&&(b=!1),void 0===c&&(c=!1),this.columns.forEach(function(a){a.filters.forEach(function(a){a.term=void 0,b&&(a.condition=void 0),c&&(a.flags=void 0)})}),a?this.refreshRows():void 0},o.prototype={put:function(a,b){this[this.grid.options.rowIdentity(a)]=b},get:function(a){return this[this.grid.options.rowIdentity(a)]},remove:function(a){var b=this[a=this.grid.options.rowIdentity(a)];return delete this[a],b}},p}])}(),function(){angular.module("ui.grid").factory("GridApi",["$q","$rootScope","gridUtil","uiGridConstants","GridRow","uiGridGridMenuService",function(a,b,c,d,e,f){function g(a,c,d,e){return b.$on(a,function(a){var b=Array.prototype.slice.call(arguments);b.splice(0,1),c.apply(e?e:d.api,b)})}var h=function(a){this.grid=a,this.listeners=[],this.registerEvent("core","renderingComplete"),this.registerEvent("core","filterChanged"),this.registerMethod("core","setRowInvisible",e.prototype.setRowInvisible),this.registerMethod("core","clearRowInvisible",e.prototype.clearRowInvisible),this.registerMethod("core","getVisibleRows",this.grid.getVisibleRows),this.registerEvent("core","rowsVisibleChanged"),this.registerEvent("core","rowsRendered"),this.registerEvent("core","scrollBegin"),this.registerEvent("core","scrollEnd"),this.registerEvent("core","canvasHeightChanged"),this.registerEvent("core","gridDimensionChanged")};return h.prototype.suppressEvents=function(a,b){ +var c=this,d=angular.isArray(a)?a:[a],e=c.listeners.filter(function(a){return d.some(function(b){return a.handler===b})});e.forEach(function(a){a.dereg()}),b(),e.forEach(function(a){a.dereg=g(a.eventId,a.handler,c.grid,a._this)})},h.prototype.registerEvent=function(a,d){var e=this;e[a]||(e[a]={});var f=e[a];f.on||(f.on={},f.raise={});var h=e.grid.id+a+d;f.raise[d]=function(){b.$emit.apply(b,[h].concat(Array.prototype.slice.call(arguments)))},f.on[d]=function(b,f,i){if(null!==b&&"undefined"==typeof b.$on)return void c.logError("asked to listen on "+a+".on."+d+" but scope wasn't passed in the input parameters. It is legitimate to pass null, but you've passed something else, so you probably forgot to provide scope rather than did it deliberately, not registering");var j=g(h,f,e.grid,i),k={handler:f,dereg:j,eventId:h,scope:b,_this:i};e.listeners.push(k);var l=function(){k.dereg();var a=e.listeners.indexOf(k);e.listeners.splice(a,1)};return b&&b.$on("$destroy",function(){l()}),l}},h.prototype.registerEventsFromObject=function(a){var b=this,c=[];angular.forEach(a,function(a,b){var d={name:b,events:[]};angular.forEach(a,function(a,b){d.events.push(b)}),c.push(d)}),c.forEach(function(a){a.events.forEach(function(c){b.registerEvent(a.name,c)})})},h.prototype.registerMethod=function(a,b,d,e){this[a]||(this[a]={});var f=this[a];f[b]=c.createBoundedWrapper(e||this.grid,d)},h.prototype.registerMethodsFromObject=function(a,b){var c=this,d=[];angular.forEach(a,function(a,b){var c={name:b,methods:[]};angular.forEach(a,function(a,b){c.methods.push({name:b,fn:a})}),d.push(c)}),d.forEach(function(a){a.methods.forEach(function(d){c.registerMethod(a.name,d.name,d.fn,b)})})},h}])}(),function(){angular.module("ui.grid").factory("GridColumn",["gridUtil","uiGridConstants","i18nService",function(a,b,c){function d(a,c,d){var e=this;e.grid=d,e.uid=c,e.updateColumnDef(a,!0),e.aggregationValue=void 0,e.updateAggregationValue=function(){if(!e.aggregationType)return void(e.aggregationValue=void 0);var a=0,c=e.grid.getVisibleRows(),d=function(){var a=[];return c.forEach(function(b){var c=e.grid.getCellValue(b,e),d=Number(c);isNaN(d)||a.push(d)}),a};angular.isFunction(e.aggregationType)?e.aggregationValue=e.aggregationType(c,e):e.aggregationType===b.aggregationTypes.count?e.aggregationValue=e.grid.getVisibleRowCount():e.aggregationType===b.aggregationTypes.sum?(d().forEach(function(b){a+=b}),e.aggregationValue=a):e.aggregationType===b.aggregationTypes.avg?(d().forEach(function(b){a+=b}),a/=d().length,e.aggregationValue=a):e.aggregationType===b.aggregationTypes.min?e.aggregationValue=Math.min.apply(null,d()):e.aggregationType===b.aggregationTypes.max?e.aggregationValue=Math.max.apply(null,d()):e.aggregationValue=" "},this.getAggregationValue=function(){return e.aggregationValue}}return d.prototype.hideColumn=function(){this.colDef.visible=!1},d.prototype.setPropertyOrDefault=function(a,b,c){var d=this;"undefined"!=typeof a[b]&&a[b]?d[b]=a[b]:"undefined"!=typeof d[b]?d[b]=d[b]:d[b]=c?c:{}},d.prototype.updateColumnDef=function(c,d){var e=this;if(e.colDef=c,void 0===c.name)throw new Error("colDef.name is required for column at index "+e.grid.options.columnDefs.indexOf(c));if(e.displayName=void 0===c.displayName?a.readableColumnName(c.name):c.displayName,!angular.isNumber(e.width)||!e.hasCustomWidth||c.allowCustomWidthOverride){var f=c.width,g="Cannot parse column width '"+f+"' for column named '"+c.name+"'";if(e.hasCustomWidth=!1,angular.isString(f)||angular.isNumber(f))if(angular.isString(f))if(a.endsWith(f,"%")){var h=f.replace(/%/g,""),i=parseInt(h,10);if(isNaN(i))throw new Error(g);e.width=f}else if(f.match(/^(\d+)$/))e.width=parseInt(f.match(/^(\d+)$/)[1],10);else{if(!f.match(/^\*+$/))throw new Error(g);e.width=f}else e.width=f;else e.width="*"}["minWidth","maxWidth"].forEach(function(a){var b=c[a],d="Cannot parse column "+a+" '"+b+"' for column named '"+c.name+"'";if(angular.isString(b)||angular.isNumber(b))if(angular.isString(b)){if(!b.match(/^(\d+)$/))throw new Error(d);e[a]=parseInt(b.match(/^(\d+)$/)[1],10)}else e[a]=b;else e[a]="minWidth"===a?30:9e3}),e.field=void 0===c.field?c.name:c.field,"string"!=typeof e.field&&a.logError("Field is not a string, this is likely to break the code, Field is: "+e.field),e.name=c.name,e.displayName=void 0===c.displayName?a.readableColumnName(c.name):c.displayName,e.aggregationType=angular.isDefined(c.aggregationType)?c.aggregationType:null,e.footerCellTemplate=angular.isDefined(c.footerCellTemplate)?c.footerCellTemplate:null,"undefined"==typeof c.cellTooltip||c.cellTooltip===!1?e.cellTooltip=!1:c.cellTooltip===!0?e.cellTooltip=function(a,b){return e.grid.getCellValue(a,b)}:"function"==typeof c.cellTooltip?e.cellTooltip=c.cellTooltip:e.cellTooltip=function(a,b){return b.colDef.cellTooltip},"undefined"==typeof c.headerTooltip||c.headerTooltip===!1?e.headerTooltip=!1:c.headerTooltip===!0?e.headerTooltip=function(a){return a.displayName}:"function"==typeof c.headerTooltip?e.headerTooltip=c.headerTooltip:e.headerTooltip=function(a){return a.colDef.headerTooltip},e.footerCellClass=c.footerCellClass,e.cellClass=c.cellClass,e.headerCellClass=c.headerCellClass,e.cellFilter=c.cellFilter?c.cellFilter:"",e.sortCellFiltered=c.sortCellFiltered?!0:!1,e.filterCellFiltered=c.filterCellFiltered?!0:!1,e.headerCellFilter=c.headerCellFilter?c.headerCellFilter:"",e.footerCellFilter=c.footerCellFilter?c.footerCellFilter:"",e.visible=a.isNullOrUndefined(c.visible)||c.visible,e.headerClass=c.headerClass,e.enableSorting="undefined"!=typeof c.enableSorting?c.enableSorting:!0,e.sortingAlgorithm=c.sortingAlgorithm,e.sortDirectionCycle="undefined"!=typeof c.sortDirectionCycle?c.sortDirectionCycle:[null,b.ASC,b.DESC],"undefined"==typeof e.suppressRemoveSort&&(e.suppressRemoveSort="undefined"!=typeof c.suppressRemoveSort?c.suppressRemoveSort:!1),e.enableFiltering="undefined"!=typeof c.enableFiltering?c.enableFiltering:!0,e.setPropertyOrDefault(c,"menuItems",[]),d&&e.setPropertyOrDefault(c,"sort");var j=[];c.filter?j.push(c.filter):c.filters?j=c.filters:j.push({}),d?(e.setPropertyOrDefault(c,"filter"),e.setPropertyOrDefault(c,"filters",j)):e.filters.length===j.length&&e.filters.forEach(function(a,b){"undefined"!=typeof j[b].placeholder&&(a.placeholder=j[b].placeholder),"undefined"!=typeof j[b].ariaLabel&&(a.ariaLabel=j[b].ariaLabel),"undefined"!=typeof j[b].flags&&(a.flags=j[b].flags),"undefined"!=typeof j[b].type&&(a.type=j[b].type),"undefined"!=typeof j[b].selectOptions&&(a.selectOptions=j[b].selectOptions)})},d.prototype.unsort=function(){this.sort={},this.grid.api.core.raise.sortChanged(this.grid,this.grid.getColumnSorting())},d.prototype.getColClass=function(a){var c=b.COL_CLASS_PREFIX+this.uid;return a?"."+c:c},d.prototype.isPinnedLeft=function(){return"left"===this.renderContainer},d.prototype.isPinnedRight=function(){return"right"===this.renderContainer},d.prototype.getColClassDefinition=function(){return" .grid"+this.grid.id+" "+this.getColClass(!0)+" { min-width: "+this.drawnWidth+"px; max-width: "+this.drawnWidth+"px; }"},d.prototype.getRenderContainer=function(){var a=this,b=a.renderContainer;return(null===b||""===b||void 0===b)&&(b="body"),a.grid.renderContainers[b]},d.prototype.showColumn=function(){this.colDef.visible=!0},d.prototype.getAggregationText=function(){var a=this;if(a.colDef.aggregationHideLabel)return"";if(a.colDef.aggregationLabel)return a.colDef.aggregationLabel;switch(a.colDef.aggregationType){case b.aggregationTypes.count:return c.getSafeText("aggregation.count");case b.aggregationTypes.sum:return c.getSafeText("aggregation.sum");case b.aggregationTypes.avg:return c.getSafeText("aggregation.avg");case b.aggregationTypes.min:return c.getSafeText("aggregation.min");case b.aggregationTypes.max:return c.getSafeText("aggregation.max");default:return""}},d.prototype.getCellTemplate=function(){var a=this;return a.cellTemplatePromise},d.prototype.getCompiledElementFn=function(){var a=this;return a.compiledElementFnDefer.promise},d}])}(),function(){angular.module("ui.grid").factory("GridOptions",["gridUtil","uiGridConstants",function(a,b){return{initialize:function(c){return c.onRegisterApi=c.onRegisterApi||angular.noop(),c.data=c.data||[],c.columnDefs=c.columnDefs||[],c.excludeProperties=c.excludeProperties||["$$hashKey"],c.enableRowHashing=c.enableRowHashing!==!1,c.rowIdentity=c.rowIdentity||function(b){return a.hashKey(b)},c.getRowIdentity=c.getRowIdentity||function(a){return a.$$hashKey},c.flatEntityAccess=c.flatEntityAccess===!0,c.showHeader="undefined"!=typeof c.showHeader?c.showHeader:!0,c.showHeader?c.headerRowHeight="undefined"!=typeof c.headerRowHeight?c.headerRowHeight:30:c.headerRowHeight=0,c.rowHeight=c.rowHeight||30,c.minRowsToShow="undefined"!=typeof c.minRowsToShow?c.minRowsToShow:10,c.showGridFooter=c.showGridFooter===!0,c.showColumnFooter=c.showColumnFooter===!0,c.columnFooterHeight="undefined"!=typeof c.columnFooterHeight?c.columnFooterHeight:30,c.gridFooterHeight="undefined"!=typeof c.gridFooterHeight?c.gridFooterHeight:30,c.columnWidth="undefined"!=typeof c.columnWidth?c.columnWidth:50,c.maxVisibleColumnCount="undefined"!=typeof c.maxVisibleColumnCount?c.maxVisibleColumnCount:200,c.virtualizationThreshold="undefined"!=typeof c.virtualizationThreshold?c.virtualizationThreshold:20,c.columnVirtualizationThreshold="undefined"!=typeof c.columnVirtualizationThreshold?c.columnVirtualizationThreshold:10,c.excessRows="undefined"!=typeof c.excessRows?c.excessRows:4,c.scrollThreshold="undefined"!=typeof c.scrollThreshold?c.scrollThreshold:4,c.excessColumns="undefined"!=typeof c.excessColumns?c.excessColumns:4,c.horizontalScrollThreshold="undefined"!=typeof c.horizontalScrollThreshold?c.horizontalScrollThreshold:2,c.aggregationCalcThrottle="undefined"!=typeof c.aggregationCalcThrottle?c.aggregationCalcThrottle:500,c.wheelScrollThrottle="undefined"!=typeof c.wheelScrollThrottle?c.wheelScrollThrottle:70,c.scrollDebounce="undefined"!=typeof c.scrollDebounce?c.scrollDebounce:300,c.enableSorting=c.enableSorting!==!1,c.enableFiltering=c.enableFiltering===!0,c.enableColumnMenus=c.enableColumnMenus!==!1,c.enableVerticalScrollbar="undefined"!=typeof c.enableVerticalScrollbar?c.enableVerticalScrollbar:b.scrollbars.ALWAYS,c.enableHorizontalScrollbar="undefined"!=typeof c.enableHorizontalScrollbar?c.enableHorizontalScrollbar:b.scrollbars.ALWAYS,c.enableMinHeightCheck=c.enableMinHeightCheck!==!1,c.minimumColumnSize="undefined"!=typeof c.minimumColumnSize?c.minimumColumnSize:10,c.rowEquality=c.rowEquality||function(a,b){return a===b},c.headerTemplate=c.headerTemplate||null,c.footerTemplate=c.footerTemplate||"ui-grid/ui-grid-footer",c.gridFooterTemplate=c.gridFooterTemplate||"ui-grid/ui-grid-grid-footer",c.rowTemplate=c.rowTemplate||"ui-grid/ui-grid-row",c.appScopeProvider=c.appScopeProvider||null,c}}}])}(),function(){angular.module("ui.grid").factory("GridRenderContainer",["gridUtil","uiGridConstants",function(a,b){function c(a,b,c){var d=this;d.name=a,d.grid=b,d.visibleRowCache=[],d.visibleColumnCache=[],d.renderedRows=[],d.renderedColumns=[],d.prevScrollTop=0,d.prevScrolltopPercentage=0,d.prevRowScrollIndex=0,d.prevScrollLeft=0,d.prevScrollleftPercentage=0,d.prevColumnScrollIndex=0,d.columnStyles="",d.viewportAdjusters=[],d.hasHScrollbar=!1,d.hasVScrollbar=!1,d.canvasHeightShouldUpdate=!0,d.$$canvasHeight=0,c&&angular.isObject(c)&&angular.extend(d,c),b.registerStyleComputation({priority:5,func:function(){return d.updateColumnWidths(),d.columnStyles}})}return c.prototype.reset=function(){this.visibleColumnCache.length=0,this.visibleRowCache.length=0,this.renderedRows.length=0,this.renderedColumns.length=0},c.prototype.containsColumn=function(a){return-1!==this.visibleColumnCache.indexOf(a)},c.prototype.minRowsToRender=function(){for(var a=this,b=0,c=0,d=a.getViewportHeight(),e=a.visibleRowCache.length-1;d>c&&e>=0;e--)c+=a.visibleRowCache[e].height,b++;return b},c.prototype.minColumnsToRender=function(){for(var a=this,b=this.getViewportWidth(),c=0,d=0,e=0;ed)d+=f.drawnWidth?f.drawnWidth:0,c++;else{for(var g=0,h=e;h>=e-c;h--)g+=a.visibleColumnCache[h].drawnWidth?a.visibleColumnCache[h].drawnWidth:0;b>g&&c++}}return c},c.prototype.getVisibleRowCount=function(){return this.visibleRowCache.length},c.prototype.registerViewportAdjuster=function(a){this.viewportAdjusters.push(a)},c.prototype.removeViewportAdjuster=function(a){var b=this.viewportAdjusters.indexOf(a);b>-1&&this.viewportAdjusters.splice(b,1)},c.prototype.getViewportAdjustment=function(){var a=this,b={height:0,width:0};return a.viewportAdjusters.forEach(function(a){b=a.call(this,b)}),b},c.prototype.getMargin=function(a){var b=this,c=0;return b.viewportAdjusters.forEach(function(b){var d=b.call(this,{height:0,width:0});d.side&&d.side===a&&(c+=-1*d.width)}),c},c.prototype.getViewportHeight=function(){var a=this,b=a.headerHeight?a.headerHeight:a.grid.headerHeight,c=a.grid.gridHeight-b-a.grid.footerHeight,d=a.getViewportAdjustment();return c+=d.height},c.prototype.getViewportWidth=function(){var a=this,b=a.grid.gridWidth,c=a.getViewportAdjustment();return b+=c.width},c.prototype.getHeaderViewportWidth=function(){var a=this.getViewportWidth();return a},c.prototype.getCanvasHeight=function(){var a=this;if(!a.canvasHeightShouldUpdate)return a.$$canvasHeight;var b=a.$$canvasHeight;return a.$$canvasHeight=0,a.visibleRowCache.forEach(function(b){a.$$canvasHeight+=b.height}),a.canvasHeightShouldUpdate=!1,a.grid.api.core.raise.canvasHeightChanged(b,a.$$canvasHeight),a.$$canvasHeight},c.prototype.getVerticalScrollLength=function(){return this.getCanvasHeight()-this.getViewportHeight()+this.grid.scrollbarHeight},c.prototype.getHorizontalScrollLength=function(){return this.getCanvasWidth()-this.getViewportWidth()+this.grid.scrollbarWidth},c.prototype.getCanvasWidth=function(){var a=this,b=a.canvasWidth;return b},c.prototype.setRenderedRows=function(a){this.renderedRows.length=a.length;for(var b=0;b0&&(this.grid.scrollDirection=b.scrollDirection.DOWN),0>d&&(this.grid.scrollDirection=b.scrollDirection.UP);var e=this.getVerticalScrollLength();return c=a/e,c>1&&(c=1),0>c&&(c=0),this.adjustScrollVertical(a,c),c}},c.prototype.scrollHorizontal=function(a){var c=-1;if(a!==this.prevScrollLeft){var d=a-this.prevScrollLeft;d>0&&(this.grid.scrollDirection=b.scrollDirection.RIGHT),0>d&&(this.grid.scrollDirection=b.scrollDirection.LEFT);var e=this.getHorizontalScrollLength();return c=0!==e?a/e:0,this.adjustScrollHorizontal(a,c),c}},c.prototype.adjustScrollVertical=function(a,b,c){(this.prevScrollTop!==a||c)&&(("undefined"==typeof a||void 0===a||null===a)&&(a=(this.getCanvasHeight()-this.getViewportHeight())*b),this.adjustRows(a,b,!1),this.prevScrollTop=a,this.prevScrolltopPercentage=b,this.grid.queueRefresh())},c.prototype.adjustScrollHorizontal=function(a,b,c){(this.prevScrollLeft!==a||c)&&(("undefined"==typeof a||void 0===a||null===a)&&(a=(this.getCanvasWidth()-this.getViewportWidth())*b),this.adjustColumns(a,b),this.prevScrollLeft=a,this.prevScrollleftPercentage=b,this.grid.queueRefresh())},c.prototype.adjustRows=function(a,b,c){var d=this,e=d.minRowsToRender(),f=d.visibleRowCache,g=f.length-e;"undefined"!=typeof b&&null!==b||!a||(b=a/d.getVerticalScrollLength());var h=Math.ceil(Math.min(g,g*b));h>g&&(h=g);var i=[];if(f.length>d.grid.options.virtualizationThreshold){if("undefined"!=typeof a&&null!==a){if(!d.grid.suppressParentScrollDown&&d.prevScrollToph)return;if(!d.grid.suppressParentScrollUp&&d.prevScrollTop>a&&h>d.prevRowScrollIndex-d.grid.options.scrollThreshold&&g>h)return}var j={},k={};j=Math.max(0,h-d.grid.options.excessRows),k=Math.min(f.length,h+e+d.grid.options.excessRows),i=[j,k]}else{var l=d.visibleRowCache.length;i=[0,Math.max(l,e+d.grid.options.excessRows)]}d.updateViewableRowRange(i),d.prevRowScrollIndex=h},c.prototype.adjustColumns=function(a,b){var c=this,d=c.minColumnsToRender(),e=c.visibleColumnCache,f=e.length-d;"undefined"!=typeof b&&null!==b||!a||(b=a/c.getHorizontalScrollLength());var g=Math.ceil(Math.min(f,f*b));g>f&&(g=f);var h=[];if(e.length>c.grid.options.columnVirtualizationThreshold&&c.getCanvasWidth()>c.getViewportWidth()){var i=Math.max(0,g-c.grid.options.excessColumns),j=Math.min(e.length,g+d+c.grid.options.excessColumns);h=[i,j]}else{var k=c.visibleColumnCache.length;h=[0,Math.max(k,d+c.grid.options.excessColumns)]}c.updateViewableColumnRange(h),c.prevColumnScrollIndex=g},c.prototype.updateViewableRowRange=function(a){var b=this.visibleRowCache.slice(a[0],a[1]);this.currentTopRow=a[0],this.setRenderedRows(b)},c.prototype.updateViewableColumnRange=function(a){var b=this.visibleColumnCache.slice(a[0],a[1]);this.currentFirstColumn=a[0],this.setRenderedColumns(b)},c.prototype.headerCellWrapperStyle=function(){var a=this;if(0!==a.currentFirstColumn){var b=a.columnOffset;return a.grid.isRTL()?{"margin-right":b+"px"}:{"margin-left":b+"px"}}return null},c.prototype.updateColumnWidths=function(){var b=this,c=[],d=0,e=0,f="",g=b.grid.getViewportWidth()-b.grid.scrollbarWidth,h=[];angular.forEach(b.grid.renderContainers,function(a,b){h=h.concat(a.visibleColumnCache)}),h.forEach(function(b,f){var h=0;b.visible&&(angular.isNumber(b.width)?(h=parseInt(b.width,10),e+=h,b.drawnWidth=h):a.endsWith(b.width,"%")?(h=parseInt(parseInt(b.width.replace(/%/g,""),10)/100*g),h>b.maxWidth&&(h=b.maxWidth),h0){var j=i/d;c.forEach(function(a){var b=parseInt(a.width.length*j,10);b>a.maxWidth&&(b=a.maxWidth),b0&&(a.drawnWidth++,e++,l--,m=!0)},l=g-e,m=!0;l>0&&m;)m=!1,c.forEach(k);var n=function(a){a.drawnWidth>a.minWidth&&o>0&&(a.drawnWidth--,e--,o--,m=!0)},o=e-g;for(m=!0;o>0&&m;)m=!1,c.forEach(n);var p=0;b.visibleColumnCache.forEach(function(a){a.visible&&(p+=a.drawnWidth)}),h.forEach(function(a){f+=a.getColClassDefinition()}),b.canvasWidth=p,this.columnStyles=f},c.prototype.needsHScrollbarPlaceholder=function(){return this.grid.options.enableHorizontalScrollbar&&!this.hasHScrollbar&&!this.grid.disableScrolling},c.prototype.getViewportStyle=function(){var a=this,c={};return a.hasHScrollbar=!1,a.hasVScrollbar=!1,a.grid.disableScrolling?(c["overflow-x"]="hidden",c["overflow-y"]="hidden",c):("body"===a.name?(a.hasHScrollbar=a.grid.options.enableHorizontalScrollbar!==b.scrollbars.NEVER,a.grid.isRTL()?a.grid.hasLeftContainerColumns()||(a.hasVScrollbar=a.grid.options.enableVerticalScrollbar!==b.scrollbars.NEVER):a.grid.hasRightContainerColumns()||(a.hasVScrollbar=a.grid.options.enableVerticalScrollbar!==b.scrollbars.NEVER)):"left"===a.name?a.hasVScrollbar=a.grid.isRTL()?a.grid.options.enableVerticalScrollbar!==b.scrollbars.NEVER:!1:a.hasVScrollbar=a.grid.isRTL()?!1:a.grid.options.enableVerticalScrollbar!==b.scrollbars.NEVER,c["overflow-x"]=a.hasHScrollbar?"scroll":"hidden",c["overflow-y"]=a.hasVScrollbar?"scroll":"hidden",c)},c}])}(),function(){angular.module("ui.grid").factory("GridRow",["gridUtil","uiGridConstants",function(a,b){function c(b,c,d){this.grid=d,this.entity=b,this.uid=a.nextUid(),this.visible=!0,this.$$height=d.options.rowHeight}return Object.defineProperty(c.prototype,"height",{get:function(){return this.$$height},set:function(a){a!==this.$$height&&(this.grid.updateCanvasHeight(),this.$$height=a)}}),c.prototype.getQualifiedColField=function(a){return"row."+this.getEntityQualifiedColField(a)},c.prototype.getEntityQualifiedColField=function(c){var d="entity";return c.field===b.ENTITY_BINDING?d:a.preEval(d+"."+c.field)},c.prototype.setRowInvisible=function(a){a&&a.setThisRowInvisible&&a.setThisRowInvisible("user")},c.prototype.clearRowInvisible=function(a){a&&a.clearThisRowInvisible&&a.clearThisRowInvisible("user")},c.prototype.setThisRowInvisible=function(a,b){this.invisibleReason||(this.invisibleReason={}),this.invisibleReason[a]=!0,this.evaluateRowVisibility(b)},c.prototype.clearThisRowInvisible=function(a,b){"undefined"!=typeof this.invisibleReason&&delete this.invisibleReason[a],this.evaluateRowVisibility(b)},c.prototype.evaluateRowVisibility=function(a){var b=!0;"undefined"!=typeof this.invisibleReason&&angular.forEach(this.invisibleReason,function(a,c){a&&(b=!1)}),("undefined"==typeof this.visible||this.visible!==b)&&(this.visible=b,a||(this.grid.queueGridRefresh(),this.grid.api.core.raise.rowsVisibleChanged(this)))},c}])}(),function(){"use strict";angular.module("ui.grid").factory("GridRowColumn",["$parse","$filter",function(a,b){var c=function d(a,b){if(!(this instanceof d))throw"Using GridRowColumn as a function insead of as a constructor. Must be called with `new` keyword";this.row=a,this.col=b};return c.prototype.getIntersectionValueRaw=function(){var b=a(this.row.getEntityQualifiedColField(this.col)),c=this.row;return b(c)},c}])}(),function(){angular.module("ui.grid").factory("ScrollEvent",["gridUtil",function(a){function b(b,c,d,e){var f=this;if(!b)throw new Error("grid argument is required");f.grid=b,f.source=e,f.withDelay=!0,f.sourceRowContainer=c,f.sourceColContainer=d,f.newScrollLeft=null,f.newScrollTop=null,f.x=null,f.y=null,f.verticalScrollLength=-9999999,f.horizontalScrollLength=-999999,f.fireThrottledScrollingEvent=a.throttle(function(a){f.grid.scrollContainers(a,f)},f.grid.options.wheelScrollThrottle,{trailing:!0})}return b.prototype.getNewScrollLeft=function(b,c){var d=this;if(!d.newScrollLeft){var e,f=b.getCanvasWidth()-b.getViewportWidth(),g=a.normalizeScrollLeft(c,d.grid);if("undefined"!=typeof d.x.percentage&&void 0!==d.x.percentage)e=d.x.percentage;else{if("undefined"==typeof d.x.pixels||void 0===d.x.pixels)throw new Error("No percentage or pixel value provided for scroll event X axis");e=d.x.percentage=(g+d.x.pixels)/f}return Math.max(0,e*f)}return d.newScrollLeft},b.prototype.getNewScrollTop=function(a,b){var c=this;if(!c.newScrollTop){var d,e=a.getVerticalScrollLength(),f=b[0].scrollTop;if("undefined"!=typeof c.y.percentage&&void 0!==c.y.percentage)d=c.y.percentage;else{if("undefined"==typeof c.y.pixels||void 0===c.y.pixels)throw new Error("No percentage or pixel value provided for scroll event Y axis");d=c.y.percentage=(f+c.y.pixels)/e}return Math.max(0,d*e)}return c.newScrollTop},b.prototype.atTop=function(a){return this.y&&(0===this.y.percentage||this.verticalScrollLength<0)&&0===a},b.prototype.atBottom=function(a){return this.y&&(1===this.y.percentage||0===this.verticalScrollLength)&&a>0},b.prototype.atLeft=function(a){return this.x&&(0===this.x.percentage||this.horizontalScrollLength<0)&&0===a},b.prototype.atRight=function(a){return this.x&&(1===this.x.percentage||0===this.horizontalScrollLength)&&a>0},b.Sources={ViewPortScroll:"ViewPortScroll",RenderContainerMouseWheel:"RenderContainerMouseWheel",RenderContainerTouchMove:"RenderContainerTouchMove",Other:99},b}])}(),function(){"use strict";angular.module("ui.grid").service("gridClassFactory",["gridUtil","$q","$compile","$templateCache","uiGridConstants","Grid","GridColumn","GridRow",function(a,b,c,d,e,f,g,h){var i={createGrid:function(d){d="undefined"!=typeof d?d:{},d.id=a.newId();var e=new f(d);if(e.options.rowTemplate){var g=b.defer();e.getRowTemplateFn=g.promise,a.getTemplate(e.options.rowTemplate).then(function(a){var b=c(a);g.resolve(b)},function(a){throw new Error("Couldn't fetch/use row template '"+e.options.rowTemplate+"'")})}return e.registerColumnBuilder(i.defaultColumnBuilder),e.registerRowBuilder(i.rowTemplateAssigner),e.registerRowsProcessor(function(a){return a.forEach(function(a){a.evaluateRowVisibility(!0)},50),a}),e.registerColumnsProcessor(function(a){return a.forEach(function(a){a.visible=angular.isDefined(a.colDef.visible)?a.colDef.visible:!0}),a},50),e.registerRowsProcessor(e.searchRows,100),e.options.externalSort&&angular.isFunction(e.options.externalSort)?e.registerRowsProcessor(e.options.externalSort,200):e.registerRowsProcessor(e.sortByColumn,200),e},defaultColumnBuilder:function(c,d,f){var g=[],h=function(b,f,h,i,j){c[b]?d[f]=c[b]:d[f]=h,g.push(a.getTemplate(d[f]).then(function(a){angular.isFunction(a)&&(a=a());var c="cellTooltip"===j?"col.cellTooltip(row,col)":"col.headerTooltip(col)";j&&d[j]===!1?a=a.replace(e.TOOLTIP,""):j&&d[j]&&(a=a.replace(e.TOOLTIP,'title="{{'+c+' CUSTOM_FILTERS }}"')),i?d[b]=a.replace(e.CUSTOM_FILTERS,function(){return d[i]?"|"+d[i]:""}):d[b]=a},function(a){throw new Error("Couldn't fetch/use colDef."+b+" '"+c[b]+"'")}))};return h("cellTemplate","providedCellTemplate","ui-grid/uiGridCell","cellFilter","cellTooltip"),d.cellTemplatePromise=g[0],h("headerCellTemplate","providedHeaderCellTemplate","ui-grid/uiGridHeaderCell","headerCellFilter","headerTooltip"),h("footerCellTemplate","providedFooterCellTemplate","ui-grid/uiGridFooterCell","footerCellFilter"),h("filterHeaderTemplate","providedFilterHeaderTemplate","ui-grid/ui-grid-filter"),d.compiledElementFnDefer=b.defer(),b.all(g)},rowTemplateAssigner:function(d){var e=this;if(d.rowTemplate){var f=b.defer();d.getRowTemplateFn=f.promise,a.getTemplate(d.rowTemplate).then(function(a){var b=c(a);f.resolve(b)},function(a){throw new Error("Couldn't fetch/use row template '"+d.rowTemplate+"'")})}else d.rowTemplate=e.options.rowTemplate,d.getRowTemplateFn=e.getRowTemplateFn;return d.getRowTemplateFn}};return i}])}(),function(){function a(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}var b=angular.module("ui.grid");b.service("rowSearcher",["gridUtil","uiGridConstants",function(b,c){var d=c.filter.CONTAINS,e={};return e.getTerm=function(a){if("undefined"==typeof a.term)return a.term;var b=a.term;return"string"==typeof b&&(b=b.trim()),b},e.stripTerm=function(b){var c=e.getTerm(b);return"string"==typeof c?a(c.replace(/(^\*|\*$)/g,"")):c},e.guessCondition=function(a){if("undefined"==typeof a.term||!a.term)return d;var b=e.getTerm(a);if(/\*/.test(b)){var c="";a.flags&&a.flags.caseSensitive||(c+="i");var f=b.replace(/(\\)?\*/g,function(a,b){return b?a:"[\\s\\S]*?"});return new RegExp("^"+f+"$",c)}return d},e.setupFilters=function(a){for(var d=[],f=a.length,g=0;f>g;g++){var h=a[g];if(h.noTerm||!b.isNullOrUndefined(h.term)){var i={},j="";h.flags&&h.flags.caseSensitive||(j+="i"),b.isNullOrUndefined(h.term)||(h.rawTerm?i.term=h.term:i.term=e.stripTerm(h)),i.noTerm=h.noTerm,h.condition?i.condition=h.condition:i.condition=e.guessCondition(h),i.flags=angular.extend({caseSensitive:!1,date:!1},h.flags),i.condition===c.filter.STARTS_WITH&&(i.startswithRE=new RegExp("^"+i.term,j)),i.condition===c.filter.ENDS_WITH&&(i.endswithRE=new RegExp(i.term+"$",j)),i.condition===c.filter.CONTAINS&&(i.containsRE=new RegExp(i.term,j)),i.condition===c.filter.EXACT&&(i.exactRE=new RegExp("^"+i.term+"$",j)),d.push(i)}}return d},e.runColumnFilter=function(a,b,d,e){var f,g=typeof e.condition,h=e.term;if(f=d.filterCellFiltered?a.getCellDisplayValue(b,d):a.getCellValue(b,d),e.condition instanceof RegExp)return e.condition.test(f);if("function"===g)return e.condition(h,f,b,d);if(e.startswithRE)return e.startswithRE.test(f);if(e.endswithRE)return e.endswithRE.test(f);if(e.containsRE)return e.containsRE.test(f);if(e.exactRE)return e.exactRE.test(f);if(e.condition===c.filter.NOT_EQUAL){var i=new RegExp("^"+h+"$");return!i.exec(f)}if("number"==typeof f&&"string"==typeof h){var j=parseFloat(h.replace(/\\\./,".").replace(/\\\-/,"-"));isNaN(j)||(h=j)}return e.flags.date===!0&&(f=new Date(f),h=new Date(h.replace(/\\/g,""))),e.condition===c.filter.GREATER_THAN?f>h:e.condition===c.filter.GREATER_THAN_OR_EQUAL?f>=h:e.condition===c.filter.LESS_THAN?h>f:e.condition===c.filter.LESS_THAN_OR_EQUAL?h>=f:!0},e.searchColumn=function(a,c,d,f){if(a.options.useExternalFiltering)return!0;for(var g=f.length,h=0;g>h;h++){var i=f[h];if(!b.isNullOrUndefined(i.term)&&""!==i.term||i.noTerm){var j=e.runColumnFilter(a,c,d,i);if(!j)return!1}}return!0},e.search=function(a,c,d){if(c){if(!a.options.enableFiltering)return c;for(var f=[],g=d.length,h=function(a){var c=!1;return a.forEach(function(a){(!b.isNullOrUndefined(a.term)&&""!==a.term||a.noTerm)&&(c=!0)}),c},i=0;g>i;i++){var j=d[i];"undefined"!=typeof j.filters&&h(j.filters)&&f.push({col:j,filters:e.setupFilters(j.filters)})}if(f.length>0){for(var k=function(a,b,c,d){b.visible&&!e.searchColumn(a,b,c,d)&&(b.visible=!1)},l=function(a,b){for(var d=c.length,e=0;d>e;e++)k(a,c[e],b.col,b.filters)},m=f.length,n=0;m>n;n++)l(a,f[n]);a.api.core.raise.rowsVisibleChanged&&a.api.core.raise.rowsVisibleChanged()}return c}},e}])}(),function(){var a=angular.module("ui.grid");a.service("rowSorter",["$parse","uiGridConstants",function(a,b){var c="("+b.CURRENCY_SYMBOLS.map(function(a){return"\\"+a}).join("|")+")?",d=(new RegExp("^[-+]?"+c+"[\\d,.]+"+c+"%?$"),{colSortFnCache:{}});return d.guessSortFn=function(a){switch(a){case"number":return d.sortNumber;case"numberStr":return d.sortNumberStr;case"boolean":return d.sortBool;case"string":return d.sortAlpha;case"date":return d.sortDate;case"object":return d.basicSort;default:throw new Error("No sorting function found for type:"+a)}},d.handleNulls=function(a,b){if(!a&&0!==a&&a!==!1||!b&&0!==b&&b!==!1){if(!a&&0!==a&&a!==!1&&!b&&0!==b&&b!==!1)return 0;if(!a&&0!==a&&a!==!1)return 1;if(!b&&0!==b&&b!==!1)return-1}return null},d.basicSort=function(a,b){var c=d.handleNulls(a,b);return null!==c?c:a===b?0:b>a?-1:1},d.sortNumber=function(a,b){var c=d.handleNulls(a,b);return null!==c?c:a-b},d.sortNumberStr=function(a,b){var c=d.handleNulls(a,b);if(null!==c)return c;var e,f,g=!1,h=!1;return e=parseFloat(a.replace(/[^0-9.-]/g,"")),isNaN(e)&&(g=!0),f=parseFloat(b.replace(/[^0-9.-]/g,"")),isNaN(f)&&(h=!0),g&&h?0:g?1:h?-1:e-f},d.sortAlpha=function(a,b){var c=d.handleNulls(a,b);if(null!==c)return c;var e=a.toString().toLowerCase(),f=b.toString().toLowerCase();return e===f?0:e.localeCompare(f)},d.sortDate=function(a,b){var c=d.handleNulls(a,b);if(null!==c)return c;a instanceof Date||(a=new Date(a)),b instanceof Date||(b=new Date(b));var e=a.getTime(),f=b.getTime();return e===f?0:f>e?-1:1},d.sortBool=function(a,b){var c=d.handleNulls(a,b);return null!==c?c:a&&b?0:a||b?a?1:-1:0},d.getSortFn=function(a,b,c){var e;return d.colSortFnCache[b.colDef.name]?e=d.colSortFnCache[b.colDef.name]:void 0!==b.sortingAlgorithm?(e=b.sortingAlgorithm,d.colSortFnCache[b.colDef.name]=b.sortingAlgorithm):b.sortCellFiltered&&b.cellFilter?(e=d.sortAlpha,d.colSortFnCache[b.colDef.name]=e):(e=d.guessSortFn(b.colDef.type),e?d.colSortFnCache[b.colDef.name]=e:e=d.sortAlpha),e},d.prioritySort=function(a,b){return void 0!==a.sort.priority&&void 0!==b.sort.priority?a.sort.priorityf;f+=2){var i=h[f];if("margin"===c){var j=parseFloat(e[c+i]);isNaN(j)||(g+=j)}if(d){if("content"===c){var k=parseFloat(e["padding"+i]);isNaN(k)||(g-=k)}if("margin"!==c){var l=parseFloat(e["border"+i+"Width"]);isNaN(l)||(g-=l)}}else{var m=parseFloat(e["padding"+i]);if(isNaN(m)||(g+=m),"padding"!==c){var n=parseFloat(e["border"+i+"Width"]);isNaN(n)||(g+=n)}}}return g}function c(c,d,e){var f,h=!0,i=a(c),j="border-box"===i.boxSizing;if(0>=f||null==f){if(f=i[d],(0>f||null==f)&&(f=c.style[d]),g.test(f))return f;h=j&&!0,f=parseFloat(f)||0}var k=f+b(c,d,e||(j?"border":"content"),h,i);return k}function d(b){b=angular.element(b)[0];var c=b.parentElement;return c||(c=document.getElementsByTagName("body")[0]),parseInt(a(c).fontSize)||parseInt(a(b).fontSize)||16}var e,f=angular.module("ui.grid");"function"!=typeof Function.prototype.bind&&(e=function(){var a=Array.prototype.slice;return function(b){var c=this,d=a.call(arguments,1);return d.length?function(){return arguments.length?c.apply(b,d.concat(a.call(arguments))):c.apply(b,d)}:function(){return arguments.length?c.apply(b,arguments):c.call(b)}}});var g=new RegExp("^("+/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source+")(?!px)[a-z%]+$","i"),h=/^(block|none|table(?!-c[ea]).+)/,i={position:"absolute",visibility:"hidden",display:"block"},j=["0","0","0","0"],k="uiGrid-";f.service("gridUtil",["$log","$window","$document","$http","$templateCache","$timeout","$interval","$injector","$q","$interpolate","uiGridConstants",function(f,g,l,m,n,o,p,q,r,s,t){function u(a,b){var c=angular.element(this),d=0,e=0,f=0,g=0;if(b.originalEvent&&(b=b.originalEvent),"detail"in b&&(f=-1*b.detail),"wheelDelta"in b&&(f=b.wheelDelta),"wheelDeltaY"in b&&(f=b.wheelDeltaY),"wheelDeltaX"in b&&(e=-1*b.wheelDeltaX),"axis"in b&&b.axis===b.HORIZONTAL_AXIS&&(e=-1*f,f=0),d=0===f?e:f,"deltaY"in b&&(f=-1*b.deltaY,d=f),"deltaX"in b&&(e=b.deltaX,0===f&&(d=-1*e)),0!==f||0!==e){if(1===b.deltaMode){var h=c.data("mousewheel-line-height");d*=h,f*=h,e*=h}else if(2===b.deltaMode){var i=c.data("mousewheel-page-height");d*=i,f*=i,e*=i}g=Math.max(Math.abs(f),Math.abs(e)),(!z||z>g)&&(z=g,w(b,g)&&(z/=40)),d=Math[d>=1?"floor":"ceil"](d/z),e=Math[e>=1?"floor":"ceil"](e/z),f=Math[f>=1?"floor":"ceil"](f/z);var j={originalEvent:b,deltaX:e,deltaY:f,deltaFactor:z,preventDefault:function(){b.preventDefault()},stopPropagation:function(){b.stopPropagation()}};y&&clearTimeout(y),y=setTimeout(v,200),a.call(c[0],j)}}function v(){z=null}function w(a,b){return"mousewheel"===a.type&&b%120===0}var x={augmentWidthOrHeight:b,getStyles:a,createBoundedWrapper:function(a,b){return function(){return b.apply(a,arguments)}},readableColumnName:function(a){return"undefined"==typeof a||void 0===a||null===a?a:("string"!=typeof a&&(a=String(a)),a.replace(/_+/g," ").replace(/^[A-Z]+$/,function(a){return angular.lowercase(angular.uppercase(a.charAt(0))+a.slice(1))}).replace(/([\w\u00C0-\u017F]+)/g,function(a){return angular.uppercase(a.charAt(0))+a.slice(1)}).replace(/(\w+?(?=[A-Z]))/g,"$1 "))},getColumnsFromData:function(a,b){var c=[];if(!a||"undefined"==typeof a[0]||void 0===a[0])return[];angular.isUndefined(b)&&(b=[]);var d=a[0];return angular.forEach(d,function(a,d){-1===b.indexOf(d)&&c.push({name:d})}),c},newId:function(){var a=(new Date).getTime();return function(){return a+=1}}(),getTemplate:function(a){if(n.get(a))return x.postProcessTemplate(n.get(a));if(angular.isFunction(a.then))return a.then(x.postProcessTemplate);try{if(angular.element(a).length>0)return r.when(a).then(x.postProcessTemplate)}catch(b){}return x.logDebug("fetching url",a),m({method:"GET",url:a}).then(function(b){var c=b.data.trim();return n.put(a,c),c},function(b){throw new Error("Could not get template "+a+": "+b)}).then(x.postProcessTemplate)},postProcessTemplate:function(a){var b=s.startSymbol(),c=s.endSymbol();return("{{"!==b||"}}"!==c)&&(a=a.replace(/\{\{/g,b),a=a.replace(/\}\}/g,c)),r.when(a)},guessType:function(a){var b=typeof a;switch(b){case"number":case"boolean":case"string":return b;default:return angular.isDate(a)?"date":"object"}},elementWidth:function(a){},elementHeight:function(a){},getScrollbarWidth:function(){var a=document.createElement("div");a.style.visibility="hidden",a.style.width="100px",a.style.msOverflowStyle="scrollbar",document.body.appendChild(a);var b=a.offsetWidth;a.style.overflow="scroll";var c=document.createElement("div");c.style.width="100%",a.appendChild(c);var d=c.offsetWidth;return a.parentNode.removeChild(a),b-d},swap:function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},fakeElement:function(a,b,c,d){var e,f,g=angular.element(a).clone()[0];for(f in b)g.style[f]=b[f];return angular.element(document.body).append(g),e=c.call(g,g),angular.element(g).remove(),e},normalizeWheelEvent:function(a){var b,c,d,e=a||window.event,f=([].slice.call(arguments,1),0),g=0,h=0,i=0,j=0;return e.originalEvent&&(e=e.originalEvent),e.wheelDelta&&(f=e.wheelDelta),e.detail&&(f=-1*e.detail),h=f,void 0!==e.axis&&e.axis===e.HORIZONTAL_AXIS&&(h=0,g=-1*f),e.deltaY&&(h=-1*e.deltaY,f=h),e.deltaX&&(g=e.deltaX,f=-1*g),void 0!==e.wheelDeltaY&&(h=e.wheelDeltaY),void 0!==e.wheelDeltaX&&(g=e.wheelDeltaX),i=Math.abs(f),(!b||b>i)&&(b=i),j=Math.max(Math.abs(h),Math.abs(g)),(!c||c>j)&&(c=j),d=f>0?"floor":"ceil",f=Math[d](f/b),g=Math[d](g/c),h=Math[d](h/c),{delta:f,deltaX:g,deltaY:h}},isTouchEnabled:function(){var a;return("ontouchstart"in g||g.DocumentTouch&&l instanceof DocumentTouch)&&(a=!0),a},isNullOrUndefined:function(a){return void 0===a||null===a?!0:!1},endsWith:function(a,b){return a&&b&&"string"==typeof a?-1!==a.indexOf(b,a.length-b.length):!1},arrayContainsObjectWithProperty:function(a,b,c){var d=!1;return angular.forEach(a,function(a){a[b]===c&&(d=!0)}),d},numericAndNullSort:function(a,b){return null===a?1:null===b?-1:null===a&&null===b?0:a-b},disableAnimations:function(a){var b;try{b=q.get("$animate"),angular.version.major>1||1===angular.version.major&&angular.version.minor>=4?b.enabled(a,!1):b.enabled(!1,a)}catch(c){}},enableAnimations:function(a){var b;try{return b=q.get("$animate"),angular.version.major>1||1===angular.version.major&&angular.version.minor>=4?b.enabled(a,!0):b.enabled(!0,a),b}catch(c){}},nextUid:function(){for(var a,b=j.length;b;){if(b--,a=j[b].charCodeAt(0),57===a)return j[b]="A",k+j.join("");if(90!==a)return j[b]=String.fromCharCode(a+1),k+j.join("");j[b]="0"}return j.unshift("0"),k+j.join("")},hashKey:function(a){var b,c=typeof a;return"object"===c&&null!==a?"function"==typeof(b=a.$$hashKey)?b=a.$$hashKey():"undefined"!=typeof a.$$hashKey&&a.$$hashKey?b=a.$$hashKey:void 0===b&&(b=a.$$hashKey=x.nextUid()):b=a,c+":"+b},resetUids:function(){j=["0","0","0"]},logError:function(a){t.LOG_ERROR_MESSAGES&&f.error(a)},logWarn:function(a){t.LOG_WARN_MESSAGES&&f.warn(a)},logDebug:function(){t.LOG_DEBUG_MESSAGES&&f.debug.apply(f,arguments)}};x.focus={queue:[],byId:function(a,b){this._purgeQueue();var c=o(function(){var c=(b&&b.id?b.id+"-":"")+a,d=g.document.getElementById(c);d?d.focus():x.logWarn("[focus.byId] Element id "+c+" was not found.")});return this.queue.push(c),c},byElement:function(a){if(!angular.isElement(a))return x.logWarn("Trying to focus on an element that isn't an element."),r.reject("not-element");a=angular.element(a),this._purgeQueue();var b=o(function(){a&&a[0].focus()});return this.queue.push(b),b},bySelector:function(a,b,c){var d=this;if(!angular.isElement(a))throw new Error("The parent element is not an element.");a=angular.element(a);var e=function(){var c=a[0].querySelector(b);return d.byElement(c)};if(this._purgeQueue(),c){var f=o(e);return this.queue.push(o(e)),f}return e()},_purgeQueue:function(){this.queue.forEach(function(a){o.cancel(a)}),this.queue=[]}},["width","height"].forEach(function(b){var d=angular.uppercase(b.charAt(0))+b.substr(1);x["element"+d]=function(d,e){var f=d;if(f&&"undefined"!=typeof f.length&&f.length&&(f=d[0]),f){var g=a(f);return 0===f.offsetWidth&&h.test(g.display)?x.swap(f,i,function(){return c(f,b,e)}):c(f,b,e)}return null},x["outerElement"+d]=function(a,b){return a?x["element"+d].call(this,a,b?"margin":"border"):null}}),x.closestElm=function(a,b){"undefined"!=typeof a.length&&a.length&&(a=a[0]);var c;["matches","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector"].some(function(a){return"function"==typeof document.body[a]?(c=a,!0):!1});for(var d;null!==a;){if(d=a.parentElement,null!==d&&d[c](b))return d;a=d}return null},x.type=function(a){var b=Function.prototype.toString.call(a.constructor);return b.match(/function (.*?)\(/)[1]},x.getBorderSize=function(b,c){"undefined"!=typeof b.length&&b.length&&(b=b[0]);var d=a(b);c=c?"border"+c.charAt(0).toUpperCase()+c.slice(1):"border",c+="Width";var e=parseInt(d[c],10);return isNaN(e)?0:e},x.detectBrowser=function(){var a=g.navigator.userAgent,b={chrome:/chrome/i,safari:/safari/i,firefox:/firefox/i,ie:/internet explorer|trident\//i};for(var c in b)if(b[c].test(a))return c;return"unknown"},x.rtlScrollType=function B(){if(B.type)return B.type;var a=angular.element('
    A
    ')[0],b="reverse";return document.body.appendChild(a),a.scrollLeft>0?b="default":(a.scrollLeft=1,0===a.scrollLeft&&(b="negative")),angular.element(a).remove(),B.type=b,b},x.normalizeScrollLeft=function(a,b){"undefined"!=typeof a.length&&a.length&&(a=a[0]);var c=a.scrollLeft;if(b.isRTL())switch(x.rtlScrollType()){case"default":return a.scrollWidth-c-a.clientWidth;case"negative":return Math.abs(c);case"reverse":return c}return c},x.denormalizeScrollLeft=function(a,b,c){if("undefined"!=typeof a.length&&a.length&&(a=a[0]),c.isRTL())switch(x.rtlScrollType()){case"default":var d=a.scrollWidth-a.clientWidth;return d-b;case"negative":return-1*b;case"reverse":return b}return b},x.preEval=function(a){var b=t.BRACKET_REGEXP.exec(a);if(b)return(b[1]?x.preEval(b[1]):b[1])+b[2]+(b[3]?x.preEval(b[3]):b[3]);a=a.replace(t.APOS_REGEXP,"\\'");var c=a.split(t.DOT_REGEXP),d=[c.shift()];return angular.forEach(c,function(a){d.push(a.replace(t.FUNC_REGEXP,"']$1"))}),d.join("['")},x.debounce=function(a,b,c){function d(){g=this,f=arguments;var d=function(){e=null,c||(h=a.apply(g,f))},i=c&&!e;return e&&o.cancel(e),e=o(d,b,!1),i&&(h=a.apply(g,f)),h}var e,f,g,h;return d.cancel=function(){o.cancel(e),e=null},d},x.throttle=function(a,b,c){function d(b){g=+new Date,a.apply(e,f),p(function(){h=null},0,1,!1)}c=c||{};var e,f,g=0,h=null;return function(){if(e=this,f=arguments,null===h){var a=+new Date-g;a>b?d():c.trailing&&(h=p(d,b-a,1,!1))}}},x.on={},x.off={},x._events={},x.addOff=function(a){x.off[a]=function(b,c){var d=x._events[a].indexOf(c);d>0&&x._events[a].removeAt(d)}};var y,z,A="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"];return x.on.mousewheel=function(a,b){if(a&&b){var c=angular.element(a);c.data("mousewheel-line-height",d(c)),c.data("mousewheel-page-height",x.elementHeight(c)),c.data("mousewheel-callbacks")||c.data("mousewheel-callbacks",{});var f=c.data("mousewheel-callbacks");f[b]=(Function.prototype.bind||e).call(u,c[0],b);for(var g=A.length;g;)c.on(A[--g],f[b])}},x.off.mousewheel=function(a,b){var c=angular.element(a),d=c.data("mousewheel-callbacks"),e=d[b];if(e)for(var f=A.length;f;)c.off(A[--f],e);delete d[b],0===Object.keys(d).length&&(c.removeData("mousewheel-line-height"),c.removeData("mousewheel-page-height"),c.removeData("mousewheel-callbacks"))},x}]),f.filter("px",function(){return function(a){return a.match(/^[\d\.]+$/)?a+"px":a}})}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){var b={aggregate:{label:"položky"},groupPanel:{description:"Přesuňte záhlaví zde pro vytvoření skupiny dle sloupce."},search:{placeholder:"Hledat...",showingItems:"Zobrazuji položky:",selectedItems:"Vybrané položky:",totalItems:"Celkem položek:",size:"Velikost strany:",first:"První strana",next:"Další strana",previous:"Předchozí strana",last:"Poslední strana"},menu:{text:"Vyberte sloupec:"},sort:{ascending:"Seřadit od A-Z",descending:"Seřadit od Z-A",remove:"Odebrat seřazení"},column:{hide:"Schovat sloupec"},aggregation:{count:"celkem řádků: ",sum:"celkem: ",avg:"avg: ",min:"min.: ",max:"max.: "},pinning:{pinLeft:"Zamknout vlevo",pinRight:"Zamknout vpravo",unpin:"Odemknout"},gridMenu:{columns:"Sloupce:",importerTitle:"Importovat soubor",exporterAllAsCsv:"Exportovat všechna data do csv",exporterVisibleAsCsv:"Exportovat viditelná data do csv",exporterSelectedAsCsv:"Exportovat vybraná data do csv",exporterAllAsPdf:"Exportovat všechna data do pdf",exporterVisibleAsPdf:"Exportovat viditelná data do pdf",exporterSelectedAsPdf:"Exportovat vybraná data do pdf",clearAllFilters:"Odstranit všechny filtry"},importer:{noHeaders:"Názvy sloupců se nepodařilo získat, obsahuje soubor záhlaví?",noObjects:"Data se nepodařilo zpracovat, obsahuje soubor řádky mimo záhlaví?",invalidCsv:"Soubor nelze zpracovat, jedná se o CSV?",invalidJson:"Soubor nelze zpracovat, je to JSON?",jsonNotArray:"Soubor musí obsahovat json. Ukončuji.."},pagination:{sizes:"položek na stránku",totalItems:"položek"},grouping:{group:"Seskupit",ungroup:"Odebrat seskupení",aggregate_count:"Agregace: Count",aggregate_sum:"Agregace: Sum",aggregate_max:"Agregace: Max",aggregate_min:"Agregace: Min",aggregate_avg:"Agregace: Avg",aggregate_remove:"Agregace: Odebrat"}};return a.add("cs",b),a.add("cz",b),a.add("cs-cz",b),a.add("cs-CZ",b),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("da",{aggregate:{label:"artikler"},groupPanel:{description:"Grupér rækker udfra en kolonne ved at trække dens overskift hertil."},search:{placeholder:"Søg...",showingItems:"Viste rækker:",selectedItems:"Valgte rækker:",totalItems:"Rækker totalt:",size:"Side størrelse:",first:"Første side",next:"Næste side",previous:"Forrige side",last:"Sidste side"},menu:{text:"Vælg kolonner:"},sort:{ascending:"Sorter stigende",descending:"Sorter faldende",none:"Sorter ingen",remove:"Fjern sortering"},column:{hide:"Skjul kolonne"},aggregation:{count:"antal rækker: ",sum:"sum: ",avg:"gns: ",min:"min: ",max:"max: "},gridMenu:{columns:"Kolonner:",importerTitle:"Importer fil",exporterAllAsCsv:"Eksporter alle data som csv",exporterVisibleAsCsv:"Eksporter synlige data som csv",exporterSelectedAsCsv:"Eksporter markerede data som csv",exporterAllAsPdf:"Eksporter alle data som pdf",exporterVisibleAsPdf:"Eksporter synlige data som pdf",exporterSelectedAsPdf:"Eksporter markerede data som pdf",clearAllFilters:"Clear all filters"},importer:{noHeaders:"Column names were unable to be derived, does the file have a header?",noObjects:"Objects were not able to be derived, was there data in the file other than headers?",invalidCsv:"File was unable to be processed, is it valid CSV?",invalidJson:"File was unable to be processed, is it valid Json?",jsonNotArray:"Imported json file must contain an array, aborting."},pagination:{aria:{pageToFirst:"Gå til første",pageBack:"Gå tilbage",pageSelected:"Valgte side",pageForward:"Gå frem",pageToLast:"Gå til sidste"},sizes:"genstande per side",totalItems:"genstande",through:"gennem",of:"af"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("de",{headerCell:{aria:{defaultFilterLabel:"Filter für Spalte",removeFilter:"Filter löschen",columnMenuButtonLabel:"Spaltenmenü"},priority:"Priorität:",filterLabel:"Filter für Spalte: "},aggregate:{label:"Eintrag"},groupPanel:{description:"Ziehen Sie eine Spaltenüberschrift hierhin, um nach dieser Spalte zu gruppieren."},search:{placeholder:"Suche...",showingItems:"Zeige Einträge:",selectedItems:"Ausgewählte Einträge:",totalItems:"Einträge gesamt:",size:"Einträge pro Seite:",first:"Erste Seite",next:"Nächste Seite",previous:"Vorherige Seite",last:"Letzte Seite"},menu:{text:"Spalten auswählen:"},sort:{ascending:"aufsteigend sortieren",descending:"absteigend sortieren",none:"keine Sortierung",remove:"Sortierung zurücksetzen"},column:{hide:"Spalte ausblenden"},aggregation:{count:"Zeilen insgesamt: ",sum:"gesamt: ",avg:"Durchschnitt: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Links anheften",pinRight:"Rechts anheften",unpin:"Lösen"},columnMenu:{close:"Schließen"},gridMenu:{aria:{buttonLabel:"Tabellenmenü"},columns:"Spalten:",importerTitle:"Datei importieren",exporterAllAsCsv:"Alle Daten als CSV exportieren",exporterVisibleAsCsv:"sichtbare Daten als CSV exportieren",exporterSelectedAsCsv:"markierte Daten als CSV exportieren",exporterAllAsPdf:"Alle Daten als PDF exportieren",exporterVisibleAsPdf:"sichtbare Daten als PDF exportieren",exporterSelectedAsPdf:"markierte Daten als PDF exportieren",clearAllFilters:"Alle Filter zurücksetzen"},importer:{noHeaders:"Es konnten keine Spaltennamen ermittelt werden. Sind in der Datei Spaltendefinitionen enthalten?",noObjects:"Es konnten keine Zeileninformationen gelesen werden, Sind in der Datei außer den Spaltendefinitionen auch Daten enthalten?",invalidCsv:"Die Datei konnte nicht eingelesen werden, ist es eine gültige CSV-Datei?",invalidJson:"Die Datei konnte nicht eingelesen werden. Enthält sie gültiges JSON?",jsonNotArray:"Die importierte JSON-Datei muß ein Array enthalten. Breche Import ab."},pagination:{aria:{pageToFirst:"Zum Anfang",pageBack:"Seite zurück",pageSelected:"Ausgwählte Seite",pageForward:"Seite vor",pageToLast:"Zum Ende"},sizes:"Einträge pro Seite",totalItems:"Einträge",through:"bis",of:"von"},grouping:{group:"Gruppieren",ungroup:"Gruppierung aufheben",aggregate_count:"Agg: Anzahl",aggregate_sum:"Agg: Summe",aggregate_max:"Agg: Maximum",aggregate_min:"Agg: Minimum",aggregate_avg:"Agg: Mittelwert",aggregate_remove:"Aggregation entfernen"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("en",{headerCell:{aria:{defaultFilterLabel:"Filter for column",removeFilter:"Remove Filter",columnMenuButtonLabel:"Column Menu"},priority:"Priority:",filterLabel:"Filter for column: "},aggregate:{label:"items"},groupPanel:{description:"Drag a column header here and drop it to group by that column."},search:{placeholder:"Search...",showingItems:"Showing Items:",selectedItems:"Selected Items:",totalItems:"Total Items:",size:"Page Size:",first:"First Page",next:"Next Page",previous:"Previous Page",last:"Last Page"},menu:{text:"Choose Columns:"},sort:{ascending:"Sort Ascending",descending:"Sort Descending",none:"Sort None",remove:"Remove Sort"},column:{hide:"Hide Column"},aggregation:{count:"total rows: ",sum:"total: ",avg:"avg: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Pin Left",pinRight:"Pin Right",unpin:"Unpin"},columnMenu:{close:"Close"},gridMenu:{aria:{buttonLabel:"Grid Menu"},columns:"Columns:",importerTitle:"Import file",exporterAllAsCsv:"Export all data as csv",exporterVisibleAsCsv:"Export visible data as csv",exporterSelectedAsCsv:"Export selected data as csv",exporterAllAsPdf:"Export all data as pdf",exporterVisibleAsPdf:"Export visible data as pdf",exporterSelectedAsPdf:"Export selected data as pdf",clearAllFilters:"Clear all filters"},importer:{noHeaders:"Column names were unable to be derived, does the file have a header?",noObjects:"Objects were not able to be derived, was there data in the file other than headers?",invalidCsv:"File was unable to be processed, is it valid CSV?",invalidJson:"File was unable to be processed, is it valid Json?",jsonNotArray:"Imported json file must contain an array, aborting."},pagination:{aria:{pageToFirst:"Page to first",pageBack:"Page back",pageSelected:"Selected page",pageForward:"Page forward",pageToLast:"Page to last"},sizes:"items per page",totalItems:"items",through:"through",of:"of"},grouping:{group:"Group",ungroup:"Ungroup",aggregate_count:"Agg: Count",aggregate_sum:"Agg: Sum",aggregate_max:"Agg: Max",aggregate_min:"Agg: Min",aggregate_avg:"Agg: Avg",aggregate_remove:"Agg: Remove"},validate:{error:"Error:",minLength:"Value should be at least THRESHOLD characters long.",maxLength:"Value should be at most THRESHOLD characters long.",required:"A value is needed."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("es",{aggregate:{label:"Artículos"},groupPanel:{description:"Arrastre un encabezado de columna aquí y suéltelo para agrupar por esa columna."},search:{placeholder:"Buscar...",showingItems:"Artículos Mostrados:",selectedItems:"Artículos Seleccionados:",totalItems:"Artículos Totales:",size:"Tamaño de Página:",first:"Primera Página",next:"Página Siguiente",previous:"Página Anterior",last:"Última Página"},menu:{text:"Elegir columnas:"},sort:{ascending:"Orden Ascendente",descending:"Orden Descendente",remove:"Sin Ordenar"},column:{hide:"Ocultar la columna"},aggregation:{count:"filas totales: ",sum:"total: ",avg:"media: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Fijar a la Izquierda",pinRight:"Fijar a la Derecha",unpin:"Quitar Fijación"},gridMenu:{columns:"Columnas:",importerTitle:"Importar archivo",exporterAllAsCsv:"Exportar todo como csv",exporterVisibleAsCsv:"Exportar vista como csv",exporterSelectedAsCsv:"Exportar selección como csv",exporterAllAsPdf:"Exportar todo como pdf",exporterVisibleAsPdf:"Exportar vista como pdf",exporterSelectedAsPdf:"Exportar selección como pdf",clearAllFilters:"Limpiar todos los filtros"},importer:{noHeaders:"No fue posible derivar los nombres de las columnas, ¿tiene encabezados el archivo?",noObjects:"No fue posible obtener registros, ¿contiene datos el archivo, aparte de los encabezados?",invalidCsv:"No fue posible procesar el archivo, ¿es un CSV válido?",invalidJson:"No fue posible procesar el archivo, ¿es un Json válido?",jsonNotArray:"El archivo json importado debe contener un array, abortando."},pagination:{sizes:"registros por página",totalItems:"registros",of:"de"},grouping:{group:"Agrupar",ungroup:"Desagrupar",aggregate_count:"Agr: Cont",aggregate_sum:"Agr: Sum",aggregate_max:"Agr: Máx",aggregate_min:"Agr: Min",aggregate_avg:"Agr: Prom",aggregate_remove:"Agr: Quitar"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("fa",{aggregate:{label:"قلم"},groupPanel:{description:"عنوان یک ستون را بگیر و به گروهی از آن ستون رها کن."},search:{placeholder:"جستجو...",showingItems:"نمایش اقلام:",selectedItems:"قلم‌های انتخاب شده:",totalItems:"مجموع اقلام:",size:"اندازه‌ی صفحه:",first:"اولین صفحه",next:"صفحه‌ی‌بعدی",previous:"صفحه‌ی‌ قبلی",last:"آخرین صفحه"},menu:{text:"ستون‌های انتخابی:"},sort:{ascending:"ترتیب صعودی",descending:"ترتیب نزولی",remove:"حذف مرتب کردن"},column:{hide:"پنهان‌کردن ستون"},aggregation:{count:"تعداد: ",sum:"مجموع: ",avg:"میانگین: ",min:"کمترین: ",max:"بیشترین: "},pinning:{pinLeft:"پین کردن سمت چپ",pinRight:"پین کردن سمت راست",unpin:"حذف پین"},gridMenu:{columns:"ستون‌ها:",importerTitle:"وارد کردن فایل",exporterAllAsCsv:"خروجی تمام داده‌ها در فایل csv",exporterVisibleAsCsv:"خروجی داده‌های قابل مشاهده در فایل csv",exporterSelectedAsCsv:"خروجی داده‌های انتخاب‌شده در فایل csv",exporterAllAsPdf:"خروجی تمام داده‌ها در فایل pdf",exporterVisibleAsPdf:"خروجی داده‌های قابل مشاهده در فایل pdf",exporterSelectedAsPdf:"خروجی داده‌های انتخاب‌شده در فایل pdf",clearAllFilters:"پاک کردن تمام فیلتر"},importer:{noHeaders:"نام ستون قابل استخراج نیست. آیا فایل عنوان دارد؟",noObjects:"اشیا قابل استخراج نیستند. آیا به جز عنوان‌ها در فایل داده وجود دارد؟",invalidCsv:"فایل قابل پردازش نیست. آیا فرمت csv معتبر است؟",invalidJson:"فایل قابل پردازش نیست. آیا فرمت json معتبر است؟",jsonNotArray:"فایل json وارد شده باید حاوی آرایه باشد. عملیات ساقط شد."},pagination:{sizes:"اقلام در هر صفحه",totalItems:"اقلام",of:"از"},grouping:{group:"گروه‌بندی",ungroup:"حذف گروه‌بندی",aggregate_count:"Agg: تعداد",aggregate_sum:"Agg: جمع",aggregate_max:"Agg: بیشینه",aggregate_min:"Agg: کمینه",aggregate_avg:"Agg: میانگین",aggregate_remove:"Agg: حذف"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("fi",{aggregate:{label:"rivit"},groupPanel:{description:"Raahaa ja pudota otsikko tähän ryhmittääksesi sarakkeen mukaan."},search:{placeholder:"Hae...",showingItems:"Näytetään rivejä:",selectedItems:"Valitut rivit:",totalItems:"Rivejä yht.:",size:"Näytä:",first:"Ensimmäinen sivu",next:"Seuraava sivu",previous:"Edellinen sivu",last:"Viimeinen sivu"},menu:{text:"Valitse sarakkeet:"},sort:{ascending:"Järjestä nouseva",descending:"Järjestä laskeva",remove:"Poista järjestys"},column:{hide:"Piilota sarake"},aggregation:{count:"Rivejä yht.: ",sum:"Summa: ",avg:"K.a.: ",min:"Min: ",max:"Max: "},pinning:{pinLeft:"Lukitse vasemmalle",pinRight:"Lukitse oikealle",unpin:"Poista lukitus"},gridMenu:{columns:"Sarakkeet:",importerTitle:"Tuo tiedosto",exporterAllAsCsv:"Vie tiedot csv-muodossa",exporterVisibleAsCsv:"Vie näkyvä tieto csv-muodossa",exporterSelectedAsCsv:"Vie valittu tieto csv-muodossa",exporterAllAsPdf:"Vie tiedot pdf-muodossa",exporterVisibleAsPdf:"Vie näkyvä tieto pdf-muodossa",exporterSelectedAsPdf:"Vie valittu tieto pdf-muodossa",clearAllFilters:"Puhdista kaikki suodattimet"},importer:{noHeaders:"Sarakkeen nimiä ei voitu päätellä, onko tiedostossa otsikkoriviä?",noObjects:"Tietoja ei voitu lukea, onko tiedostossa muuta kuin otsikkot?",invalidCsv:"Tiedostoa ei voitu käsitellä, oliko se CSV-muodossa?",invalidJson:"Tiedostoa ei voitu käsitellä, oliko se JSON-muodossa?",jsonNotArray:"Tiedosto ei sisältänyt taulukkoa, lopetetaan."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("fr",{headerCell:{aria:{defaultFilterLabel:"Filtre de la colonne",removeFilter:"Supprimer le filtre",columnMenuButtonLabel:"Menu de la colonne"},priority:"Priorité:",filterLabel:"Filtre de la colonne: "},aggregate:{label:"éléments"},groupPanel:{description:"Faites glisser une en-tête de colonne ici pour créer un groupe de colonnes."},search:{placeholder:"Recherche...",showingItems:"Affichage des éléments :",selectedItems:"Éléments sélectionnés :",totalItems:"Nombre total d'éléments:",size:"Taille de page:",first:"Première page",next:"Page Suivante",previous:"Page précédente",last:"Dernière page"},menu:{text:"Choisir des colonnes :"},sort:{ascending:"Trier par ordre croissant",descending:"Trier par ordre décroissant",none:"Aucun tri",remove:"Enlever le tri"},column:{hide:"Cacher la colonne"},aggregation:{count:"lignes totales: ",sum:"total: ",avg:"moy: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Épingler à gauche",pinRight:"Épingler à droite",unpin:"Détacher"},columnMenu:{close:"Fermer"},gridMenu:{aria:{buttonLabel:"Menu du tableau"},columns:"Colonnes:",importerTitle:"Importer un fichier",exporterAllAsCsv:"Exporter toutes les données en CSV",exporterVisibleAsCsv:"Exporter les données visibles en CSV",exporterSelectedAsCsv:"Exporter les données sélectionnées en CSV",exporterAllAsPdf:"Exporter toutes les données en PDF",exporterVisibleAsPdf:"Exporter les données visibles en PDF",exporterSelectedAsPdf:"Exporter les données sélectionnées en PDF",clearAllFilters:"Nettoyez tous les filtres"},importer:{noHeaders:"Impossible de déterminer le nom des colonnes, le fichier possède-t-il une en-tête ?",noObjects:"Aucun objet trouvé, le fichier possède-t-il des données autres que l'en-tête ?",invalidCsv:"Le fichier n'a pas pu être traité, le CSV est-il valide ?",invalidJson:"Le fichier n'a pas pu être traité, le JSON est-il valide ?",jsonNotArray:"Le fichier JSON importé doit contenir un tableau, abandon."},pagination:{aria:{pageToFirst:"Aller à la première page",pageBack:"Page précédente",pageSelected:"Page sélectionnée",pageForward:"Page suivante",pageToLast:"Aller à la dernière page"},sizes:"éléments par page",totalItems:"éléments",through:"à",of:"sur"},grouping:{group:"Grouper",ungroup:"Dégrouper",aggregate_count:"Agg: Compter",aggregate_sum:"Agg: Somme",aggregate_max:"Agg: Max",aggregate_min:"Agg: Min",aggregate_avg:"Agg: Moy",aggregate_remove:"Agg: Retirer"},validate:{error:"Erreur:",minLength:"La valeur doit être supérieure ou égale à THRESHOLD caractères.",maxLength:"La valeur doit être inférieure ou égale à THRESHOLD caractères.",required:"Une valeur est nécéssaire."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("he",{aggregate:{label:"items"},groupPanel:{description:"גרור עמודה לכאן ושחרר בכדי לקבץ עמודה זו."},search:{placeholder:"חפש...",showingItems:"מציג:",selectedItems:'סה"כ נבחרו:',totalItems:'סה"כ רשומות:',size:"תוצאות בדף:",first:"דף ראשון",next:"דף הבא",previous:"דף קודם",last:"דף אחרון"},menu:{text:"בחר עמודות:"},sort:{ascending:"סדר עולה",descending:"סדר יורד",remove:"בטל"},column:{hide:"טור הסתר"},aggregation:{count:"total rows: ",sum:"total: ",avg:"avg: ",min:"min: ",max:"max: "},gridMenu:{columns:"Columns:",importerTitle:"Import file",exporterAllAsCsv:"Export all data as csv",exporterVisibleAsCsv:"Export visible data as csv",exporterSelectedAsCsv:"Export selected data as csv",exporterAllAsPdf:"Export all data as pdf",exporterVisibleAsPdf:"Export visible data as pdf",exporterSelectedAsPdf:"Export selected data as pdf",clearAllFilters:"Clean all filters"},importer:{noHeaders:"Column names were unable to be derived, does the file have a header?",noObjects:"Objects were not able to be derived, was there data in the file other than headers?",invalidCsv:"File was unable to be processed, is it valid CSV?",invalidJson:"File was unable to be processed, is it valid Json?",jsonNotArray:"Imported json file must contain an array, aborting."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("hy",{aggregate:{label:"տվյալներ"},groupPanel:{description:"Ըստ սյան խմբավորելու համար քաշեք և գցեք վերնագիրն այստեղ։"},search:{placeholder:"Փնտրում...",showingItems:"Ցուցադրված տվյալներ՝",selectedItems:"Ընտրված:",totalItems:"Ընդամենը՝",size:"Տողերի քանակը էջում՝",first:"Առաջին էջ",next:"Հաջորդ էջ",previous:"Նախորդ էջ",last:"Վերջին էջ"},menu:{text:"Ընտրել սյուները:"},sort:{ascending:"Աճման կարգով",descending:"Նվազման կարգով",remove:"Հանել "},column:{hide:"Թաքցնել սյունը"},aggregation:{count:"ընդամենը տող՝ ",sum:"ընդամենը՝ ",avg:"միջին՝ ",min:"մին՝ ",max:"մաքս՝ "},pinning:{pinLeft:"Կպցնել ձախ կողմում",pinRight:"Կպցնել աջ կողմում",unpin:"Արձակել"},gridMenu:{columns:"Սյուներ:",importerTitle:"Ներմուծել ֆայլ",exporterAllAsCsv:"Արտահանել ամբողջը CSV",exporterVisibleAsCsv:"Արտահանել երևացող տվյալները CSV",exporterSelectedAsCsv:"Արտահանել ընտրված տվյալները CSV",exporterAllAsPdf:"Արտահանել PDF",exporterVisibleAsPdf:"Արտահանել երևացող տվյալները PDF",exporterSelectedAsPdf:"Արտահանել ընտրված տվյալները PDF",clearAllFilters:"Մաքրել բոլոր ֆիլտրերը"},importer:{noHeaders:"Հնարավոր չեղավ որոշել սյան վերնագրերը։ Արդյո՞ք ֆայլը ունի վերնագրեր։",noObjects:"Հնարավոր չեղավ կարդալ տվյալները։ Արդյո՞ք ֆայլում կան տվյալներ։",invalidCsv:"Հնարավոր չեղավ մշակել ֆայլը։ Արդյո՞ք այն վավեր CSV է։",invalidJson:"Հնարավոր չեղավ մշակել ֆայլը։ Արդյո՞ք այն վավեր Json է։",jsonNotArray:"Ներմուծված json ֆայլը պետք է պարունակի զանգված, կասեցվում է։"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("it",{aggregate:{label:"elementi"},groupPanel:{description:"Trascina un'intestazione all'interno del gruppo della colonna." +},search:{placeholder:"Ricerca...",showingItems:"Mostra:",selectedItems:"Selezionati:",totalItems:"Totali:",size:"Tot Pagine:",first:"Prima",next:"Prossima",previous:"Precedente",last:"Ultima"},menu:{text:"Scegli le colonne:"},sort:{ascending:"Asc.",descending:"Desc.",remove:"Annulla ordinamento"},column:{hide:"Nascondi"},aggregation:{count:"righe totali: ",sum:"tot: ",avg:"media: ",min:"minimo: ",max:"massimo: "},pinning:{pinLeft:"Blocca a sx",pinRight:"Blocca a dx",unpin:"Blocca in alto"},gridMenu:{columns:"Colonne:",importerTitle:"Importa",exporterAllAsCsv:"Esporta tutti i dati in CSV",exporterVisibleAsCsv:"Esporta i dati visibili in CSV",exporterSelectedAsCsv:"Esporta i dati selezionati in CSV",exporterAllAsPdf:"Esporta tutti i dati in PDF",exporterVisibleAsPdf:"Esporta i dati visibili in PDF",exporterSelectedAsPdf:"Esporta i dati selezionati in PDF",clearAllFilters:"Pulire tutti i filtri"},importer:{noHeaders:"Impossibile reperire i nomi delle colonne, sicuro che siano indicati all'interno del file?",noObjects:"Impossibile reperire gli oggetti, sicuro che siano indicati all'interno del file?",invalidCsv:"Impossibile elaborare il file, sicuro che sia un CSV?",invalidJson:"Impossibile elaborare il file, sicuro che sia un JSON valido?",jsonNotArray:"Errore! Il file JSON da importare deve contenere un array."},pagination:{aria:{pageToFirst:"Prima",pageBack:"Indietro",pageSelected:"Pagina selezionata",pageForward:"Avanti",pageToLast:"Ultima"},sizes:"elementi per pagina",totalItems:"elementi",through:"a",of:"di"},grouping:{group:"Raggruppa",ungroup:"Separa",aggregate_count:"Agg: N. Elem.",aggregate_sum:"Agg: Somma",aggregate_max:"Agg: Massimo",aggregate_min:"Agg: Minimo",aggregate_avg:"Agg: Media",aggregate_remove:"Agg: Rimuovi"},validate:{error:"Errore:",minLength:"Lunghezza minima pari a THRESHOLD caratteri.",maxLength:"Lunghezza massima pari a THRESHOLD caratteri.",required:"Necessario inserire un valore."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("ja",{aggregate:{label:"項目"},groupPanel:{description:"ここに列ヘッダをドラッグアンドドロップして、その列でグループ化します。"},search:{placeholder:"検索...",showingItems:"表示中の項目:",selectedItems:"選択した項目:",totalItems:"項目の総数:",size:"ページサイズ:",first:"最初のページ",next:"次のページ",previous:"前のページ",last:"前のページ"},menu:{text:"列の選択:"},sort:{ascending:"昇順に並べ替え",descending:"降順に並べ替え",remove:"並べ替えの解除"},column:{hide:"列の非表示"},aggregation:{count:"合計行数: ",sum:"合計: ",avg:"平均: ",min:"最小: ",max:"最大: "},pinning:{pinLeft:"左に固定",pinRight:"右に固定",unpin:"固定解除"},gridMenu:{columns:"列:",importerTitle:"ファイルのインポート",exporterAllAsCsv:"すべてのデータをCSV形式でエクスポート",exporterVisibleAsCsv:"表示中のデータをCSV形式でエクスポート",exporterSelectedAsCsv:"選択したデータをCSV形式でエクスポート",exporterAllAsPdf:"すべてのデータをPDF形式でエクスポート",exporterVisibleAsPdf:"表示中のデータをPDF形式でエクスポート",exporterSelectedAsPdf:"選択したデータをPDF形式でエクスポート",clearAllFilters:"すべてのフィルタを清掃してください"},importer:{noHeaders:"列名を取得できません。ファイルにヘッダが含まれていることを確認してください。",noObjects:"オブジェクトを取得できません。ファイルにヘッダ以外のデータが含まれていることを確認してください。",invalidCsv:"ファイルを処理できません。ファイルが有効なCSV形式であることを確認してください。",invalidJson:"ファイルを処理できません。ファイルが有効なJSON形式であることを確認してください。",jsonNotArray:"インポートしたJSONファイルには配列が含まれている必要があります。処理を中止します。"},pagination:{aria:{pageToFirst:"最初のページ",pageBack:"前のページ",pageSelected:"現在のページ",pageForward:"次のページ",pageToLast:"最後のページ"},sizes:"項目/ページ",totalItems:"項目",through:"から",of:"項目/全"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("ko",{aggregate:{label:"아이템"},groupPanel:{description:"컬럼으로 그룹핑하기 위해서는 컬럼 헤더를 끌어 떨어뜨려 주세요."},search:{placeholder:"검색...",showingItems:"항목 보여주기:",selectedItems:"선택 항목:",totalItems:"전체 항목:",size:"페이지 크기:",first:"첫번째 페이지",next:"다음 페이지",previous:"이전 페이지",last:"마지막 페이지"},menu:{text:"컬럼을 선택하세요:"},sort:{ascending:"오름차순 정렬",descending:"내림차순 정렬",remove:"소팅 제거"},column:{hide:"컬럼 제거"},aggregation:{count:"전체 갯수: ",sum:"전체: ",avg:"평균: ",min:"최소: ",max:"최대: "},pinning:{pinLeft:"왼쪽 핀",pinRight:"오른쪽 핀",unpin:"핀 제거"},gridMenu:{columns:"컬럼:",importerTitle:"파일 가져오기",exporterAllAsCsv:"csv로 모든 데이터 내보내기",exporterVisibleAsCsv:"csv로 보이는 데이터 내보내기",exporterSelectedAsCsv:"csv로 선택된 데이터 내보내기",exporterAllAsPdf:"pdf로 모든 데이터 내보내기",exporterVisibleAsPdf:"pdf로 보이는 데이터 내보내기",exporterSelectedAsPdf:"pdf로 선택 데이터 내보내기",clearAllFilters:"모든 필터를 청소"},importer:{noHeaders:"컬럼명이 지정되어 있지 않습니다. 파일에 헤더가 명시되어 있는지 확인해 주세요.",noObjects:"데이터가 지정되어 있지 않습니다. 데이터가 파일에 있는지 확인해 주세요.",invalidCsv:"파일을 처리할 수 없습니다. 올바른 csv인지 확인해 주세요.",invalidJson:"파일을 처리할 수 없습니다. 올바른 json인지 확인해 주세요.",jsonNotArray:"json 파일은 배열을 포함해야 합니다."},pagination:{sizes:"페이지당 항목",totalItems:"전체 항목"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("nl",{aggregate:{label:"items"},groupPanel:{description:"Sleep hier een kolomnaam heen om op te groeperen."},search:{placeholder:"Zoeken...",showingItems:"Getoonde items:",selectedItems:"Geselecteerde items:",totalItems:"Totaal aantal items:",size:"Items per pagina:",first:"Eerste pagina",next:"Volgende pagina",previous:"Vorige pagina",last:"Laatste pagina"},menu:{text:"Kies kolommen:"},sort:{ascending:"Sorteer oplopend",descending:"Sorteer aflopend",remove:"Verwijder sortering"},column:{hide:"Verberg kolom"},aggregation:{count:"Aantal rijen: ",sum:"Som: ",avg:"Gemiddelde: ",min:"Min: ",max:"Max: "},pinning:{pinLeft:"Zet links vast",pinRight:"Zet rechts vast",unpin:"Maak los"},gridMenu:{columns:"Kolommen:",importerTitle:"Importeer bestand",exporterAllAsCsv:"Exporteer alle data als csv",exporterVisibleAsCsv:"Exporteer zichtbare data als csv",exporterSelectedAsCsv:"Exporteer geselecteerde data als csv",exporterAllAsPdf:"Exporteer alle data als pdf",exporterVisibleAsPdf:"Exporteer zichtbare data als pdf",exporterSelectedAsPdf:"Exporteer geselecteerde data als pdf",clearAllFilters:"Reinig alle filters"},importer:{noHeaders:"Kolomnamen kunnen niet worden afgeleid. Heeft het bestand een header?",noObjects:"Objecten kunnen niet worden afgeleid. Bevat het bestand data naast de headers?",invalidCsv:"Het bestand kan niet verwerkt worden. Is het een valide csv bestand?",invalidJson:"Het bestand kan niet verwerkt worden. Is het valide json?",jsonNotArray:"Het json bestand moet een array bevatten. De actie wordt geannuleerd."},pagination:{sizes:"items per pagina",totalItems:"items",of:"van de"},grouping:{group:"Groepeer",ungroup:"Groepering opheffen",aggregate_count:"Agg: Aantal",aggregate_sum:"Agg: Som",aggregate_max:"Agg: Max",aggregate_min:"Agg: Min",aggregate_avg:"Agg: Gem",aggregate_remove:"Agg: Verwijder"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("no",{headerCell:{aria:{defaultFilterLabel:"Filter for column",removeFilter:"Remove Filter",columnMenuButtonLabel:"Column Menu"},priority:"Priority:",filterLabel:"Filter for column: "},aggregate:{label:"items"},groupPanel:{description:"Drag a column header here and drop it to group by that column."},search:{placeholder:"Search...",showingItems:"Showing Items:",selectedItems:"Selected Items:",totalItems:"Total Items:",size:"Page Size:",first:"First Page",next:"Next Page",previous:"Previous Page",last:"Last Page"},menu:{text:"Choose Columns:"},sort:{ascending:"Sort Ascending",descending:"Sort Descending",none:"Sort None",remove:"Remove Sort"},column:{hide:"Hide Column"},aggregation:{count:"total rows: ",sum:"total: ",avg:"avg: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Pin Left",pinRight:"Pin Right",unpin:"Unpin"},columnMenu:{close:"Close"},gridMenu:{aria:{buttonLabel:"Grid Menu"},columns:"Kolonner:",importerTitle:"Importer fil",exporterAllAsCsv:"Eksporter alle data som csv",exporterVisibleAsCsv:"Eksporter synlige data som csv",exporterSelectedAsCsv:"Eksporter utvalgte data som csv",exporterAllAsPdf:"Eksporter alle data som pdf",exporterVisibleAsPdf:"Eksporter synlige data som pdf",exporterSelectedAsPdf:"Eksporter utvalgte data som pdf",clearAllFilters:"Clear all filters"},importer:{noHeaders:"Column names were unable to be derived, does the file have a header?",noObjects:"Objects were not able to be derived, was there data in the file other than headers?",invalidCsv:"File was unable to be processed, is it valid CSV?",invalidJson:"File was unable to be processed, is it valid Json?",jsonNotArray:"Imported json file must contain an array, aborting."},pagination:{aria:{pageToFirst:"Page to first",pageBack:"Page back",pageSelected:"Selected page",pageForward:"Page forward",pageToLast:"Page to last"},sizes:"items per page",totalItems:"items",through:"through",of:"of"},grouping:{group:"Group",ungroup:"Ungroup",aggregate_count:"Agg: Count",aggregate_sum:"Agg: Sum",aggregate_max:"Agg: Max",aggregate_min:"Agg: Min",aggregate_avg:"Agg: Avg",aggregate_remove:"Agg: Remove"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("pl",{headerCell:{aria:{defaultFilterLabel:"Filter dla kolumny",removeFilter:"Usuń filter",columnMenuButtonLabel:"Menu kolumny"},priority:"Prioritet:",filterLabel:"Filtr dla kolumny: "},aggregate:{label:"pozycji"},groupPanel:{description:"Przeciągnij nagłówek kolumny tutaj, aby pogrupować według niej."},search:{placeholder:"Szukaj...",showingItems:"Widoczne pozycje:",selectedItems:"Zaznaczone pozycje:",totalItems:"Wszystkich pozycji:",size:"Rozmiar strony:",first:"Pierwsza strona",next:"Następna strona",previous:"Poprzednia strona",last:"Ostatnia strona"},menu:{text:"Wybierz kolumny:"},sort:{ascending:"Sortuj rosnąco",descending:"Sortuj malejąco",none:"Brak sortowania",remove:"Wyłącz sortowanie"},column:{hide:"Ukryj kolumne"},aggregation:{count:"Razem pozycji: ",sum:"Razem: ",avg:"Średnia: ",min:"Min: ",max:"Max: "},pinning:{pinLeft:"Przypnij do lewej",pinRight:"Przypnij do prawej",unpin:"Odepnij"},columnMenu:{close:"Zamknij"},gridMenu:{aria:{buttonLabel:"Menu Grida"},columns:"Kolumny:",importerTitle:"Importuj plik",exporterAllAsCsv:"Eksportuj wszystkie dane do csv",exporterVisibleAsCsv:"Eksportuj widoczne dane do csv",exporterSelectedAsCsv:"Eksportuj zaznaczone dane do csv",exporterAllAsPdf:"Eksportuj wszystkie dane do pdf",exporterVisibleAsPdf:"Eksportuj widoczne dane do pdf",exporterSelectedAsPdf:"Eksportuj zaznaczone dane do pdf",clearAllFilters:"Wyczyść filtry"},importer:{noHeaders:"Nie udało się wczytać nazw kolumn. Czy plik posiada nagłówek?",noObjects:"Nie udalo się wczytać pozycji. Czy plik zawiera dane??",invalidCsv:"Nie udało się przetworzyć pliku, jest to prawidlowy plik CSV??",invalidJson:"Nie udało się przetworzyć pliku, jest to prawidlowy plik Json?",jsonNotArray:"Importowany plik json musi zawierać tablicę, importowanie przerwane."},pagination:{aria:{pageToFirst:"Pierwsza strona",pageBack:"Poprzednia strona",pageSelected:"Wybrana strona",pageForward:"Następna strona",pageToLast:"Ostatnia strona"},sizes:"pozycji na stronę",totalItems:"pozycji",through:"do",of:"z"},grouping:{group:"Grupuj",ungroup:"Rozgrupuj",aggregate_count:"Zbiorczo: Razem",aggregate_sum:"Zbiorczo: Suma",aggregate_max:"Zbiorczo: Max",aggregate_min:"Zbiorczo: Min",aggregate_avg:"Zbiorczo: Średnia",aggregate_remove:"Zbiorczo: Usuń"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("pt-br",{headerCell:{aria:{defaultFilterLabel:"Filtro por coluna",removeFilter:"Remover filtro",columnMenuButtonLabel:"Menu coluna"},priority:"Prioridade:",filterLabel:"Filtro por coluna: "},aggregate:{label:"itens"},groupPanel:{description:"Arraste e solte uma coluna aqui para agrupar por essa coluna"},search:{placeholder:"Procurar...",showingItems:"Mostrando os Itens:",selectedItems:"Items Selecionados:",totalItems:"Total de Itens:",size:"Tamanho da Página:",first:"Primeira Página",next:"Próxima Página",previous:"Página Anterior",last:"Última Página"},menu:{text:"Selecione as colunas:"},sort:{ascending:"Ordenar Ascendente",descending:"Ordenar Descendente",none:"Nenhuma Ordem",remove:"Remover Ordenação"},column:{hide:"Esconder coluna"},aggregation:{count:"total de linhas: ",sum:"total: ",avg:"med: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Fixar Esquerda",pinRight:"Fixar Direita",unpin:"Desprender"},columnMenu:{close:"Fechar"},gridMenu:{aria:{buttonLabel:"Menu Grid"},columns:"Colunas:",importerTitle:"Importar arquivo",exporterAllAsCsv:"Exportar todos os dados como csv",exporterVisibleAsCsv:"Exportar dados visíveis como csv",exporterSelectedAsCsv:"Exportar dados selecionados como csv",exporterAllAsPdf:"Exportar todos os dados como pdf",exporterVisibleAsPdf:"Exportar dados visíveis como pdf",exporterSelectedAsPdf:"Exportar dados selecionados como pdf",clearAllFilters:"Limpar todos os filtros"},importer:{noHeaders:"Nomes de colunas não puderam ser derivados. O arquivo tem um cabeçalho?",noObjects:"Objetos não puderam ser derivados. Havia dados no arquivo, além dos cabeçalhos?",invalidCsv:"Arquivo não pode ser processado. É um CSV válido?",invalidJson:"Arquivo não pode ser processado. É um Json válido?",jsonNotArray:"Arquivo json importado tem que conter um array. Abortando."},pagination:{aria:{pageToFirst:"Primeira página",pageBack:"Página anterior",pageSelected:"Página Selecionada",pageForward:"Proxima",pageToLast:"Anterior"},sizes:"itens por página",totalItems:"itens",through:"através dos",of:"de"},grouping:{group:"Agrupar",ungroup:"Desagrupar",aggregate_count:"Agr: Contar",aggregate_sum:"Agr: Soma",aggregate_max:"Agr: Max",aggregate_min:"Agr: Min",aggregate_avg:"Agr: Med",aggregate_remove:"Agr: Remover"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("pt",{headerCell:{aria:{defaultFilterLabel:"Filtro por coluna",removeFilter:"Remover filtro",columnMenuButtonLabel:"Menu coluna"},priority:"Prioridade:",filterLabel:"Filtro por coluna: "},aggregate:{label:"itens"},groupPanel:{description:"Arraste e solte uma coluna aqui para agrupar por essa coluna"},search:{placeholder:"Procurar...",showingItems:"Mostrando os Itens:",selectedItems:"Itens Selecionados:",totalItems:"Total de Itens:",size:"Tamanho da Página:",first:"Primeira Página",next:"Próxima Página",previous:"Página Anterior",last:"Última Página"},menu:{text:"Selecione as colunas:"},sort:{ascending:"Ordenar Ascendente",descending:"Ordenar Descendente",none:"Nenhuma Ordem",remove:"Remover Ordenação"},column:{hide:"Esconder coluna"},aggregation:{count:"total de linhas: ",sum:"total: ",avg:"med: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Fixar Esquerda",pinRight:"Fixar Direita",unpin:"Desprender"},columnMenu:{close:"Fechar"},gridMenu:{aria:{buttonLabel:"Menu Grid"},columns:"Colunas:",importerTitle:"Importar ficheiro",exporterAllAsCsv:"Exportar todos os dados como csv",exporterVisibleAsCsv:"Exportar dados visíveis como csv",exporterSelectedAsCsv:"Exportar dados selecionados como csv",exporterAllAsPdf:"Exportar todos os dados como pdf",exporterVisibleAsPdf:"Exportar dados visíveis como pdf",exporterSelectedAsPdf:"Exportar dados selecionados como pdf",clearAllFilters:"Limpar todos os filtros"},importer:{noHeaders:"Nomes de colunas não puderam ser derivados. O ficheiro tem um cabeçalho?",noObjects:"Objetos não puderam ser derivados. Havia dados no ficheiro, além dos cabeçalhos?",invalidCsv:"Ficheiro não pode ser processado. É um CSV válido?",invalidJson:"Ficheiro não pode ser processado. É um Json válido?",jsonNotArray:"Ficheiro json importado tem que conter um array. Interrompendo."},pagination:{aria:{pageToFirst:"Primeira página",pageBack:"Página anterior",pageSelected:"Página Selecionada",pageForward:"Próxima",pageToLast:"Anterior"},sizes:"itens por página",totalItems:"itens",through:"através dos",of:"de"},grouping:{group:"Agrupar",ungroup:"Desagrupar",aggregate_count:"Agr: Contar",aggregate_sum:"Agr: Soma",aggregate_max:"Agr: Max",aggregate_min:"Agr: Min",aggregate_avg:"Agr: Med",aggregate_remove:"Agr: Remover"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("ro",{headerCell:{aria:{defaultFilterLabel:"Filtru pentru coloana",removeFilter:"Sterge filtru",columnMenuButtonLabel:"Column Menu"},priority:"Prioritate:",filterLabel:"Filtru pentru coloana:"},aggregate:{label:"Elemente"},groupPanel:{description:"Trage un cap de coloana aici pentru a grupa elementele dupa coloana respectiva"},search:{placeholder:"Cauta...",showingItems:"Arata elementele:",selectedItems:"Elementele selectate:",totalItems:"Total elemente:",size:"Marime pagina:",first:"Prima pagina",next:"Pagina urmatoare",previous:"Pagina anterioara",last:"Ultima pagina"},menu:{text:"Alege coloane:"},sort:{ascending:"Ordoneaza crescator",descending:"Ordoneaza descrescator",none:"Fara ordonare",remove:"Sterge ordonarea"},column:{hide:"Ascunde coloana"},aggregation:{count:"total linii: ",sum:"total: ",avg:"medie: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Pin la stanga",pinRight:"Pin la dreapta",unpin:"Sterge pinul"},columnMenu:{close:"Inchide"},gridMenu:{aria:{buttonLabel:"Grid Menu"},columns:"Coloane:",importerTitle:"Incarca fisier",exporterAllAsCsv:"Exporta toate datele ca csv",exporterVisibleAsCsv:"Exporta datele vizibile ca csv",exporterSelectedAsCsv:"Exporta datele selectate ca csv",exporterAllAsPdf:"Exporta toate datele ca pdf",exporterVisibleAsPdf:"Exporta datele vizibile ca pdf",exporterSelectedAsPdf:"Exporta datele selectate ca csv pdf",clearAllFilters:"Sterge toate filtrele"},importer:{noHeaders:"Numele coloanelor nu a putut fi incarcat, acest fisier are un header?",noObjects:"Datele nu au putut fi incarcate, exista date in fisier in afara numelor de coloane?",invalidCsv:"Fisierul nu a putut fi procesat, ati incarcat un CSV valid ?",invalidJson:"Fisierul nu a putut fi procesat, ati incarcat un Json valid?",jsonNotArray:"Json-ul incarcat trebuie sa contina un array, inchidere."},pagination:{aria:{pageToFirst:"Prima pagina",pageBack:"O pagina inapoi",pageSelected:"Pagina selectata",pageForward:"O pagina inainte",pageToLast:"Ultima pagina"},sizes:"Elemente per pagina",totalItems:"elemente",through:"prin",of:"of"},grouping:{group:"Grupeaza",ungroup:"Opreste gruparea",aggregate_count:"Agg: Count",aggregate_sum:"Agg: Sum",aggregate_max:"Agg: Max",aggregate_min:"Agg: Min",aggregate_avg:"Agg: Avg",aggregate_remove:"Agg: Remove"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("ru",{headerCell:{aria:{defaultFilterLabel:"Фильтр столбца",removeFilter:"Удалить фильтр",columnMenuButtonLabel:"Меню столбца"},priority:"Приоритет:",filterLabel:"Фильтр столбца: "},aggregate:{label:"элементы"},groupPanel:{description:"Для группировки по столбцу перетащите сюда его название."},search:{placeholder:"Поиск...",showingItems:"Показать элементы:",selectedItems:"Выбранные элементы:",totalItems:"Всего элементов:",size:"Размер страницы:",first:"Первая страница",next:"Следующая страница",previous:"Предыдущая страница",last:"Последняя страница"},menu:{text:"Выбрать столбцы:"},sort:{ascending:"По возрастанию",descending:"По убыванию",none:"Без сортировки",remove:"Убрать сортировку"},column:{hide:"Спрятать столбец"},aggregation:{count:"всего строк: ",sum:"итого: ",avg:"среднее: ",min:"мин: ",max:"макс: "},pinning:{pinLeft:"Закрепить слева",pinRight:"Закрепить справа",unpin:"Открепить"},columnMenu:{close:"Закрыть"},gridMenu:{aria:{buttonLabel:"Меню"},columns:"Столбцы:",importerTitle:"Импортировать файл",exporterAllAsCsv:"Экспортировать всё в CSV",exporterVisibleAsCsv:"Экспортировать видимые данные в CSV",exporterSelectedAsCsv:"Экспортировать выбранные данные в CSV",exporterAllAsPdf:"Экспортировать всё в PDF",exporterVisibleAsPdf:"Экспортировать видимые данные в PDF",exporterSelectedAsPdf:"Экспортировать выбранные данные в PDF",clearAllFilters:"Очистите все фильтры"},importer:{noHeaders:"Не удалось получить названия столбцов, есть ли в файле заголовок?",noObjects:"Не удалось получить данные, есть ли в файле строки кроме заголовка?",invalidCsv:"Не удалось обработать файл, это правильный CSV-файл?",invalidJson:"Не удалось обработать файл, это правильный JSON?",jsonNotArray:"Импортируемый JSON-файл должен содержать массив, операция отменена."},pagination:{aria:{pageToFirst:"Первая страница",pageBack:"Предыдущая страница",pageSelected:"Выбранная страница",pageForward:"Следующая страница",pageToLast:"Последняя страница"},sizes:"строк на страницу",totalItems:"строк",through:"по",of:"из"},grouping:{group:"Группировать",ungroup:"Разгруппировать",aggregate_count:"Группировать: Count",aggregate_sum:"Для группы: Сумма",aggregate_max:"Для группы: Максимум",aggregate_min:"Для группы: Минимум",aggregate_avg:"Для группы: Среднее",aggregate_remove:"Для группы: Пусто"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("sk",{aggregate:{label:"items"},groupPanel:{description:"Pretiahni sem názov stĺpca pre zoskupenie podľa toho stĺpca."},search:{placeholder:"Hľadaj...",showingItems:"Zobrazujem položky:",selectedItems:"Vybraté položky:",totalItems:"Počet položiek:",size:"Počet:",first:"Prvá strana",next:"Ďalšia strana",previous:"Predchádzajúca strana",last:"Posledná strana"},menu:{text:"Vyberte stĺpce:"},sort:{ascending:"Zotriediť vzostupne",descending:"Zotriediť zostupne",remove:"Vymazať triedenie"},aggregation:{count:"total rows: ",sum:"total: ",avg:"avg: ",min:"min: ",max:"max: "},gridMenu:{columns:"Columns:",importerTitle:"Import file",exporterAllAsCsv:"Export all data as csv",exporterVisibleAsCsv:"Export visible data as csv",exporterSelectedAsCsv:"Export selected data as csv",exporterAllAsPdf:"Export all data as pdf",exporterVisibleAsPdf:"Export visible data as pdf",exporterSelectedAsPdf:"Export selected data as pdf",clearAllFilters:"Clear all filters"},importer:{noHeaders:"Column names were unable to be derived, does the file have a header?",noObjects:"Objects were not able to be derived, was there data in the file other than headers?",invalidCsv:"File was unable to be processed, is it valid CSV?",invalidJson:"File was unable to be processed, is it valid Json?",jsonNotArray:"Imported json file must contain an array, aborting."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("sv",{aggregate:{label:"Artiklar"},groupPanel:{description:"Dra en kolumnrubrik hit och släpp den för att gruppera efter den kolumnen."},search:{placeholder:"Sök...",showingItems:"Visar artiklar:",selectedItems:"Valda artiklar:",totalItems:"Antal artiklar:",size:"Sidstorlek:",first:"Första sidan",next:"Nästa sida",previous:"Föregående sida",last:"Sista sidan"},menu:{text:"Välj kolumner:"},sort:{ascending:"Sortera stigande",descending:"Sortera fallande",remove:"Inaktivera sortering"},column:{hide:"Göm kolumn"},aggregation:{count:"Antal rader: ",sum:"Summa: ",avg:"Genomsnitt: ",min:"Min: ",max:"Max: "},pinning:{pinLeft:"Fäst vänster",pinRight:"Fäst höger",unpin:"Lösgör"},gridMenu:{columns:"Kolumner:",importerTitle:"Importera fil",exporterAllAsCsv:"Exportera all data som CSV",exporterVisibleAsCsv:"Exportera synlig data som CSV",exporterSelectedAsCsv:"Exportera markerad data som CSV",exporterAllAsPdf:"Exportera all data som PDF",exporterVisibleAsPdf:"Exportera synlig data som PDF",exporterSelectedAsPdf:"Exportera markerad data som PDF",clearAllFilters:"Rengör alla filter"},importer:{noHeaders:"Kolumnnamn kunde inte härledas. Har filen ett sidhuvud?",noObjects:"Objekt kunde inte härledas. Har filen data undantaget sidhuvud?",invalidCsv:"Filen kunde inte behandlas, är den en giltig CSV?",invalidJson:"Filen kunde inte behandlas, är den en giltig JSON?",jsonNotArray:"Importerad JSON-fil måste innehålla ett fält. Import avbruten."},pagination:{sizes:"Artiklar per sida",totalItems:"Artiklar"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("ta",{aggregate:{label:"உருப்படிகள்"},groupPanel:{description:"ஒரு பத்தியை குழுவாக அமைக்க அப்பத்தியின் தலைப்பை இங்கே இழுத்து வரவும் "},search:{placeholder:"தேடல் ...",showingItems:"உருப்படிகளை காண்பித்தல்:",selectedItems:"தேர்ந்தெடுக்கப்பட்ட உருப்படிகள்:",totalItems:"மொத்த உருப்படிகள்:",size:"பக்க அளவு: ",first:"முதல் பக்கம்",next:"அடுத்த பக்கம்",previous:"முந்தைய பக்கம் ",last:"இறுதி பக்கம்"},menu:{text:"பத்திகளை தேர்ந்தெடு:"},sort:{ascending:"மேலிருந்து கீழாக",descending:"கீழிருந்து மேலாக",remove:"வரிசையை நீக்கு"},column:{hide:"பத்தியை மறைத்து வை "},aggregation:{count:"மொத்த வரிகள்:",sum:"மொத்தம்: ",avg:"சராசரி: ",min:"குறைந்தபட்ச: ",max:"அதிகபட்ச: "},pinning:{pinLeft:"இடதுபுறமாக தைக்க ",pinRight:"வலதுபுறமாக தைக்க",unpin:"பிரி"},gridMenu:{columns:"பத்திகள்:",importerTitle:"கோப்பு : படித்தல்",exporterAllAsCsv:"எல்லா தரவுகளையும் கோப்பாக்கு: csv",exporterVisibleAsCsv:"இருக்கும் தரவுகளை கோப்பாக்கு: csv",exporterSelectedAsCsv:"தேர்ந்தெடுத்த தரவுகளை கோப்பாக்கு: csv",exporterAllAsPdf:"எல்லா தரவுகளையும் கோப்பாக்கு: pdf",exporterVisibleAsPdf:"இருக்கும் தரவுகளை கோப்பாக்கு: pdf",exporterSelectedAsPdf:"தேர்ந்தெடுத்த தரவுகளை கோப்பாக்கு: pdf",clearAllFilters:"Clear all filters"},importer:{noHeaders:"பத்தியின் தலைப்புகளை பெற இயலவில்லை, கோப்பிற்கு தலைப்பு உள்ளதா?",noObjects:"இலக்குகளை உருவாக்க முடியவில்லை, கோப்பில் தலைப்புகளை தவிர தரவு ஏதேனும் உள்ளதா? ",invalidCsv:"சரிவர நடைமுறை படுத்த இயலவில்லை, கோப்பு சரிதானா? - csv",invalidJson:"சரிவர நடைமுறை படுத்த இயலவில்லை, கோப்பு சரிதானா? - json",jsonNotArray:"படித்த கோப்பில் வரிசைகள் உள்ளது, நடைமுறை ரத்து செய் : json"},pagination:{sizes:"உருப்படிகள் / பக்கம்",totalItems:"உருப்படிகள் "},grouping:{group:"குழு",ungroup:"பிரி",aggregate_count:"மதிப்பீட்டு : எண்ணு",aggregate_sum:"மதிப்பீட்டு : கூட்டல்",aggregate_max:"மதிப்பீட்டு : அதிகபட்சம்",aggregate_min:"மதிப்பீட்டு : குறைந்தபட்சம்",aggregate_avg:"மதிப்பீட்டு : சராசரி",aggregate_remove:"மதிப்பீட்டு : நீக்கு"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("tr",{headerCell:{aria:{defaultFilterLabel:"Sütun için filtre",removeFilter:"Filtreyi Kaldır",columnMenuButtonLabel:"Sütun Menüsü"},priority:"Öncelik:",filterLabel:"Sütun için filtre: "},aggregate:{label:"kayıtlar"},groupPanel:{description:"Sütuna göre gruplamak için sütun başlığını buraya sürükleyin ve bırakın."},search:{placeholder:"Arama...",showingItems:"Gösterilen Kayıt:",selectedItems:"Seçili Kayıt:",totalItems:"Toplam Kayıt:",size:"Sayfa Boyutu:",first:"İlk Sayfa",next:"Sonraki Sayfa",previous:"Önceki Sayfa",last:"Son Sayfa"},menu:{text:"Sütunları Seç:"},sort:{ascending:"Artan Sırada Sırala",descending:"Azalan Sırada Sırala",none:"Sıralama Yapma",remove:"Sıralamayı Kaldır"},column:{hide:"Sütunu Gizle"},aggregation:{count:"toplam satır: ",sum:"toplam: ",avg:"ort: ",min:"min: ",max:"maks: "},pinning:{pinLeft:"Sola Sabitle",pinRight:"Sağa Sabitle",unpin:"Sabitlemeyi Kaldır"},columnMenu:{close:"Kapat"},gridMenu:{aria:{buttonLabel:"Tablo Menü"},columns:"Sütunlar:",importerTitle:"Dosya içeri aktar",exporterAllAsCsv:"Bütün veriyi CSV olarak dışarı aktar",exporterVisibleAsCsv:"Görünen veriyi CSV olarak dışarı aktar",exporterSelectedAsCsv:"Seçili veriyi CSV olarak dışarı aktar",exporterAllAsPdf:"Bütün veriyi PDF olarak dışarı aktar",exporterVisibleAsPdf:"Görünen veriyi PDF olarak dışarı aktar",exporterSelectedAsPdf:"Seçili veriyi PDF olarak dışarı aktar",clearAllFilters:"Bütün filtreleri kaldır"},importer:{noHeaders:"Sütun isimleri üretilemiyor, dosyanın bir başlığı var mı?",noObjects:"Nesneler üretilemiyor, dosyada başlıktan başka bir veri var mı?",invalidCsv:"Dosya işlenemedi, geçerli bir CSV dosyası mı?",invalidJson:"Dosya işlenemedi, geçerli bir Json dosyası mı?",jsonNotArray:"Alınan Json dosyasında bir dizi bulunmalıdır, işlem iptal ediliyor."},pagination:{aria:{pageToFirst:"İlk sayfaya",pageBack:"Geri git",pageSelected:"Seçili sayfa",pageForward:"İleri git",pageToLast:"Sona git"},sizes:"Sayfadaki nesne sayısı",totalItems:"kayıtlar",through:"",of:""},grouping:{group:"Grupla",ungroup:"Gruplama",aggregate_count:"Yekun: Sayı",aggregate_sum:"Yekun: Toplam",aggregate_max:"Yekun: Maks",aggregate_min:"Yekun: Min",aggregate_avg:"Yekun: Ort",aggregate_remove:"Yekun: Sil"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("ua",{headerCell:{aria:{defaultFilterLabel:"Фільтр стовпчика",removeFilter:"Видалити фільтр",columnMenuButtonLabel:"Меню ствпчика"},priority:"Пріоритет:",filterLabel:"Фільтр стовпчика: "},aggregate:{label:"елементи"},groupPanel:{description:"Для групування за стовпчиком перетягніть сюди його назву."},search:{placeholder:"Пошук...",showingItems:"Показати елементи:",selectedItems:"Обрані елементи:",totalItems:"Усього елементів:",size:"Розмір сторінки:",first:"Перша сторінка",next:"Наступна сторінка",previous:"Попередня сторінка",last:"Остання сторінка"},menu:{text:"Обрати ствпчики:"},sort:{ascending:"За зростанням",descending:"За спаданням",none:"Без сортування",remove:"Прибрати сортування"},column:{hide:"Приховати стовпчик"},aggregation:{count:"усього рядків: ",sum:"ітого: ",avg:"середнє: ",min:"мін: ",max:"макс: "},pinning:{pinLeft:"Закріпити ліворуч",pinRight:"Закріпити праворуч",unpin:"Відкріпити"},columnMenu:{close:"Закрити"},gridMenu:{aria:{buttonLabel:"Меню"},columns:"Стовпчики:",importerTitle:"Імпортувати файл",exporterAllAsCsv:"Експортувати все в CSV",exporterVisibleAsCsv:"Експортувати видимі дані в CSV",exporterSelectedAsCsv:"Експортувати обрані дані в CSV",exporterAllAsPdf:"Експортувати все в PDF",exporterVisibleAsPdf:"Експортувати видимі дані в PDF",exporterSelectedAsPdf:"Експортувати обрані дані в PDF",clearAllFilters:"Очистити всі фільтри"},importer:{noHeaders:"Не вдалося отримати назви стовпчиків, чи є в файлі заголовок?",noObjects:"Не вдалося отримати дані, чи є в файлі рядки окрім заголовка?",invalidCsv:"Не вдалося обробити файл, чи це коректний CSV-файл?",invalidJson:"Не вдалося обробити файл, чи це коректний JSON?",jsonNotArray:"JSON-файл що імпортується повинен містити масив, операцію скасовано."},pagination:{aria:{pageToFirst:"Перша сторінка",pageBack:"Попередня сторінка",pageSelected:"Обрана сторінка",pageForward:"Наступна сторінка",pageToLast:"Остання сторінка"},sizes:"рядків на сторінку",totalItems:"рядків",through:"по",of:"з"},grouping:{group:"Групувати",ungroup:"Розгрупувати",aggregate_count:"Групувати: Кількість",aggregate_sum:"Для групи: Сума",aggregate_max:"Для групи: Максимум",aggregate_min:"Для групи: Мінімум",aggregate_avg:"Для групи: Серднє",aggregate_remove:"Для групи: Пусто"}}),a}])}])}(),function(){var a=["uiT","uiTranslate"],b=["t","uiTranslate"],c=angular.module("ui.grid.i18n");c.constant("i18nConstants",{MISSING:"[MISSING]",UPDATE_EVENT:"$uiI18n",LOCALE_DIRECTIVE_ALIAS:"uiI18n",DEFAULT_LANG:"en"}),c.service("i18nService",["$log","i18nConstants","$rootScope",function(a,b,c){var d={_langs:{},current:null,get:function(a){return this._langs[a.toLowerCase()]},add:function(a,b){var c=a.toLowerCase();this._langs[c]||(this._langs[c]={}),angular.extend(this._langs[c],b)},getAllLangs:function(){var a=[];if(!this._langs)return a;for(var b in this._langs)a.push(b);return a},setCurrent:function(a){this.current=a.toLowerCase()},getCurrentLang:function(){return this.current}},e={add:function(a,b){"object"==typeof a?angular.forEach(a,function(a){a&&d.add(a,b)}):d.add(a,b)},getAllLangs:function(){return d.getAllLangs()},get:function(a){var b=a?a:e.getCurrentLang();return d.get(b)},getSafeText:function(a,c){var f=c?c:e.getCurrentLang(),g=d.get(f);if(!g)return b.MISSING;for(var h=a.split("."),i=g,j=0;jf?0===g?new d(a,c[h]):new d(e[g-1],c[h]):new d(a,c[h])},f.prototype.getRowColRight=function(a,b){var c=this.getFocusableCols(),e=this.getFocusableRows(),f=c.indexOf(b),g=e.indexOf(a);-1===f&&(f=0);var h=f===c.length-1?0:f+1;return f>h?g===e.length-1?new d(a,c[h]):new d(e[g+1],c[h]):new d(a,c[h])},f.prototype.getRowColDown=function(a,b){var c=this.getFocusableCols(),e=this.getFocusableRows(),f=c.indexOf(b),g=e.indexOf(a);return-1===f&&(f=0),g===e.length-1?new d(a,c[f]):new d(e[g+1],c[f])},f.prototype.getRowColPageDown=function(a,b){var c=this.getFocusableCols(),e=this.getFocusableRows(),f=c.indexOf(b),g=e.indexOf(a);-1===f&&(f=0);var h=this.bodyContainer.minRowsToRender();return g>=e.length-h?new d(e[e.length-1],c[f]):new d(e[g+h],c[f])},f.prototype.getRowColUp=function(a,b){var c=this.getFocusableCols(),e=this.getFocusableRows(),f=c.indexOf(b),g=e.indexOf(a);return-1===f&&(f=0),0===g?new d(a,c[f]):new d(e[g-1],c[f])},f.prototype.getRowColPageUp=function(a,b){var c=this.getFocusableCols(),e=this.getFocusableRows(),f=c.indexOf(b),g=e.indexOf(a);-1===f&&(f=0);var h=this.bodyContainer.minRowsToRender();return 0>g-h?new d(e[0],c[f]):new d(e[g-h],c[f])},f}]),a.service("uiGridCellNavService",["gridUtil","uiGridConstants","uiGridCellNavConstants","$q","uiGridCellNavFactory","GridRowColumn","ScrollEvent",function(a,b,c,d,e,f,g){var h={initializeGrid:function(a){a.registerColumnBuilder(h.cellNavColumnBuilder),a.cellNav={},a.cellNav.lastRowCol=null,a.cellNav.focusedCells=[],h.defaultGridOptions(a.options);var b={events:{cellNav:{navigate:function(a,b){},viewPortKeyDown:function(a,b){},viewPortKeyPress:function(a,b){}}},methods:{cellNav:{scrollToFocus:function(b,c){return h.scrollToFocus(a,b,c)},getFocusedCell:function(){return a.cellNav.lastRowCol},getCurrentSelection:function(){return a.cellNav.focusedCells},rowColSelectIndex:function(b){for(var c=-1,d=0;db&&(c+=a.drawnWidth)});var e=0===d?0:(d+1)/a.renderContainers.body.visibleColumnCache.length;return c+=b.drawnWidth*e}};return h}]),a.directive("uiGridCellnav",["gridUtil","uiGridCellNavService","uiGridCellNavConstants","uiGridConstants","GridRowColumn","$timeout","$compile",function(a,b,c,d,e,f,g){return{replace:!0,priority:-150,require:"^uiGrid",scope:!1,controller:function(){},compile:function(){return{pre:function(a,f,g,h){var i=a,j=h.grid;b.initializeGrid(j),h.cellNav={},h.cellNav.makeRowCol=function(a){return a instanceof e||(a=new e(a.row,a.col)),a},h.cellNav.getActiveCell=function(){var a=f[0].getElementsByClassName("ui-grid-cell-focus");return a.length>0?a[0]:void 0},h.cellNav.broadcastCellNav=j.cellNav.broadcastCellNav=function(a,b,d){b=!(void 0===b||!b),a=h.cellNav.makeRowCol(a),h.cellNav.broadcastFocus(a,b,d),i.$broadcast(c.CELL_NAV_EVENT,a,b,d)},h.cellNav.clearFocus=j.cellNav.clearFocus=function(){j.cellNav.focusedCells=[],i.$broadcast(c.CELL_NAV_EVENT)},h.cellNav.broadcastFocus=function(a,b,c){b=!(void 0===b||!b),a=h.cellNav.makeRowCol(a);var d=a.row,f=a.col,g=h.grid.api.cellNav.rowColSelectIndex(a);if(null===j.cellNav.lastRowCol||-1===g){var i=new e(d,f);(null===j.cellNav.lastRowCol||j.cellNav.lastRowCol.row!==i.row||j.cellNav.lastRowCol.col!==i.col)&&(j.api.cellNav.raise.navigate(i,j.cellNav.lastRowCol),j.cellNav.lastRowCol=i),h.grid.options.modifierKeysToMultiSelectCells&&b?j.cellNav.focusedCells.push(a):j.cellNav.focusedCells=[a]}else j.options.modifierKeysToMultiSelectCells&&b&&g>=0&&j.cellNav.focusedCells.splice(g,1)},h.cellNav.handleKeyDown=function(a){var e=b.getDirection(a);if(null===e)return null;var f="body";a.uiGridTargetRenderContainerId&&(f=a.uiGridTargetRenderContainerId);var g=h.grid.api.cellNav.getFocusedCell();if(g){var i=h.grid.renderContainers[f].cellNav.getNextRowCol(e,g.row,g.col),k=h.grid.renderContainers[f].cellNav.getFocusableCols(),l=h.grid.api.cellNav.rowColSelectIndex(i);return e===c.direction.LEFT&&i.col===k[k.length-1]&&i.row===g.row&&a.keyCode===d.keymap.TAB&&a.shiftKey?(j.cellNav.focusedCells.splice(l,1),h.cellNav.clearFocus(),!0):e!==c.direction.RIGHT||i.col!==k[0]||i.row!==g.row||a.keyCode!==d.keymap.TAB||a.shiftKey?(j.scrollToIfNecessary(i.row,i.col).then(function(){h.cellNav.broadcastCellNav(i)}),a.stopPropagation(),a.preventDefault(),!1):(j.cellNav.focusedCells.splice(l,1),h.cellNav.clearFocus(),!0)}}},post:function(a,b,d,e){function f(){var d='
     
    ',e=g(d)(a);b.prepend(e),a.$on(c.CELL_NAV_EVENT,function(a,b,c,d){function f(a){a!==e.text()&&(e[0].style.clip="rect(0px,0px,0px,0px)",e[0].innerHTML="",e[0].style.visibility="hidden",e[0].style.visibility="visible",""!==a&&(e[0].style.clip="auto",e[0].appendChild(document.createTextNode(a+" ")),e[0].style.visibility="hidden",e[0].style.visibility="visible"))}if(!d||"focus"!==d.type){for(var g=[],i=h.api.cellNav.getCurrentSelection(),j=0;j
    ')(b);d.append(o),o.on("focus",function(a){a.uiGridTargetRenderContainerId=m;var b=j.grid.api.cellNav.getFocusedCell();null===b&&(b=j.grid.renderContainers[m].cellNav.getNextRowCol(g.direction.DOWN,null,null),b.row&&b.col&&j.cellNav.broadcastCellNav(b))}),l.setAriaActivedescendant=function(a){d.attr("aria-activedescendant",a)},l.removeAriaActivedescendant=function(a){d.attr("aria-activedescendant")===a&&d.attr("aria-activedescendant","")},j.focus=function(){c.focus.byElement(o[0])};var p=null;o.on("keydown",function(a){a.uiGridTargetRenderContainerId=m;var b=j.grid.api.cellNav.getFocusedCell(),c=j.cellNav.handleKeyDown(a);null===c&&(j.grid.api.cellNav.raise.viewPortKeyDown(a,b),p=b)}),o.on("keypress",function(b){p&&(a(function(){j.grid.api.cellNav.raise.viewPortKeyPress(b,p)},4),p=null)}),b.$on("$destroy",function(){o.off()})}}}}}}}]),a.directive("uiGridViewport",["$timeout","$document","gridUtil","uiGridConstants","uiGridCellNavService","uiGridCellNavConstants","$log","$compile",function(a,b,c,d,e,f,g,h){return{replace:!0,priority:-99999,require:["^uiGrid","^uiGridRenderContainer","?^uiGridCellnav"],scope:!1,compile:function(){return{pre:function(a,b,c,d){},post:function(a,b,c,d){var e=d[0],f=d[1];if(e.grid.api.cellNav){var g=f.containerId;if("body"===g){var h=e.grid;h.api.core.on.scrollBegin(a,function(a){var b=e.grid.api.cellNav.getFocusedCell();null!==b&&f.colContainer.containsColumn(b.col)&&e.cellNav.clearFocus()}),h.api.core.on.scrollEnd(a,function(a){var b=e.grid.api.cellNav.getFocusedCell();null!==b&&f.colContainer.containsColumn(b.col)&&e.cellNav.broadcastCellNav(b)}),h.api.cellNav.on.navigate(a,function(){e.focus()})}}}}}}}]),a.directive("uiGridCell",["$timeout","$document","uiGridCellNavService","gridUtil","uiGridCellNavConstants","uiGridConstants","GridRowColumn",function(a,b,c,d,e,f,g){return{priority:-150,restrict:"A",require:["^uiGrid","?^uiGridCellnav"],scope:!1,link:function(a,b,c,d){function f(a){a.preventDefault()}function h(){if(!a.focused){var c=b.find("div");c.addClass("ui-grid-cell-focus"),b.attr("aria-selected",!0),k.setAriaActivedescendant(b.attr("id")),a.focused=!0}}function i(){if(a.focused){var c=b.find("div");c.removeClass("ui-grid-cell-focus"),b.attr("aria-selected",!1),k.removeAriaActivedescendant(b.attr("id")),a.focused=!1}}var j=d[0],k=d[1];if(j.grid.api.cellNav&&a.col.colDef.allowCellFocus){var l=j.grid;a.focused=!1,b.attr("tabindex",-1),b.find("div").on("click",function(b){j.cellNav.broadcastCellNav(new g(a.row,a.col),b.ctrlKey||b.metaKey,b),b.stopPropagation(),a.$apply()}),b.on("mousedown",f),j.grid.api.edit&&(j.grid.api.edit.on.beginCellEdit(a,function(){b.off("mousedown",f)}),j.grid.api.edit.on.afterCellEdit(a,function(){b.on("mousedown",f)}),j.grid.api.edit.on.cancelCellEdit(a,function(){b.on("mousedown",f)})),b.on("focus",function(b){j.cellNav.broadcastCellNav(new g(a.row,a.col),!1,b),b.stopPropagation(),a.$apply()}),a.$on(e.CELL_NAV_EVENT,function(b,c,d){var e=l.cellNav.focusedCells.some(function(b,c){return b.row===a.row&&b.col===a.col});e?h():i()}),a.$on("$destroy",function(){b.find("div").off(),b.off()})}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.edit",["ui.grid"]);a.constant("uiGridEditConstants",{EDITABLE_CELL_TEMPLATE:/EDITABLE_CELL_TEMPLATE/g,EDITABLE_CELL_DIRECTIVE:/editable_cell_directive/g,events:{BEGIN_CELL_EDIT:"uiGridEventBeginCellEdit",END_CELL_EDIT:"uiGridEventEndCellEdit",CANCEL_CELL_EDIT:"uiGridEventCancelCellEdit"}}),a.service("uiGridEditService",["$q","uiGridConstants","gridUtil",function(a,b,c){var d={initializeGrid:function(a){d.defaultGridOptions(a.options),a.registerColumnBuilder(d.editColumnBuilder),a.edit={};var b={events:{edit:{afterCellEdit:function(a,b,c,d){},beginCellEdit:function(a,b,c){},cancelCellEdit:function(a,b){}}},methods:{edit:{}}};a.api.registerEventsFromObject(b.events)},defaultGridOptions:function(a){a.cellEditableCondition=void 0===a.cellEditableCondition?!0:a.cellEditableCondition,a.enableCellEditOnFocus=void 0===a.enableCellEditOnFocus?!1:a.enableCellEditOnFocus},editColumnBuilder:function(b,d,e){var f=[];return b.enableCellEdit=void 0===b.enableCellEdit?void 0===e.enableCellEdit?"object"!==b.type:e.enableCellEdit:b.enableCellEdit,b.cellEditableCondition=void 0===b.cellEditableCondition?e.cellEditableCondition:b.cellEditableCondition,b.enableCellEdit&&(b.editableCellTemplate=b.editableCellTemplate||e.editableCellTemplate||"ui-grid/cellEditor",f.push(c.getTemplate(b.editableCellTemplate).then(function(a){d.editableCellTemplate=a},function(a){throw new Error("Couldn't fetch/use colDef.editableCellTemplate '"+b.editableCellTemplate+"'")}))),b.enableCellEditOnFocus=void 0===b.enableCellEditOnFocus?e.enableCellEditOnFocus:b.enableCellEditOnFocus,a.all(f)},isStartEditKey:function(a){return a.metaKey||a.keyCode===b.keymap.ESC||a.keyCode===b.keymap.SHIFT||a.keyCode===b.keymap.CTRL||a.keyCode===b.keymap.ALT||a.keyCode===b.keymap.WIN||a.keyCode===b.keymap.CAPSLOCK||a.keyCode===b.keymap.LEFT||a.keyCode===b.keymap.TAB&&a.shiftKey||a.keyCode===b.keymap.RIGHT||a.keyCode===b.keymap.TAB||a.keyCode===b.keymap.UP||a.keyCode===b.keymap.ENTER&&a.shiftKey||a.keyCode===b.keymap.DOWN||a.keyCode===b.keymap.ENTER?!1:!0}};return d}]),a.directive("uiGridEdit",["gridUtil","uiGridEditService",function(a,b){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.initializeGrid(e.grid)},post:function(a,b,c,d){}}}}}]),a.directive("uiGridViewport",["uiGridEditConstants",function(a){return{replace:!0,priority:-99998,require:["^uiGrid","^uiGridRenderContainer"],scope:!1,compile:function(){return{post:function(b,c,d,e){var f=e[0];if(f.grid.api.edit&&f.grid.api.cellNav){var g=e[1].containerId;"body"===g&&(b.$on(a.events.CANCEL_CELL_EDIT,function(){f.focus()}),b.$on(a.events.END_CELL_EDIT,function(){f.focus()}))}}}}}}]),a.directive("uiGridCell",["$compile","$injector","$timeout","uiGridConstants","uiGridEditConstants","gridUtil","$parse","uiGridEditService","$rootScope","$q",function(a,b,c,d,e,f,g,h,i,j){var k=500;if(b.has("uiGridCellNavService")){b.get("uiGridCellNavService")}return{priority:-100,restrict:"A",scope:!1,require:"?^uiGrid",link:function(b,l,m,n){function o(){l.on("dblclick",u),l.on("touchstart",p),n&&n.grid.api.cellNav&&(G=n.grid.api.cellNav.on.viewPortKeyDown(b,function(a,c){null!==c&&(c.row!==b.row||c.col!==b.col||b.col.colDef.enableCellEditOnFocus||s(a))}),F=n.grid.api.cellNav.on.navigate(b,function(a,d){b.col.colDef.enableCellEditOnFocus&&(d&&a.row===d.row&&a.col===d.col||a.row!==b.row||a.col!==b.col||c(function(){u()}))})),b.beginEditEventsWired=!0}function p(a){"undefined"!=typeof a.originalEvent&&void 0!==a.originalEvent&&(a=a.originalEvent),l.on("touchend",q),C=c(function(){},k),C.then(function(){setTimeout(u,0),l.off("touchend",q)})}function q(a){c.cancel(C),l.off("touchend",q)}function r(){l.off("dblclick",u),l.off("keydown",s),l.off("touchstart",p),F(),G(),b.beginEditEventsWired=!1}function s(a){h.isStartEditKey(a)&&u(a)}function t(a,c){return!c.isSaving&&(angular.isFunction(a.colDef.cellEditableCondition)?a.colDef.cellEditableCondition(b):a.colDef.cellEditableCondition)}function u(a){b.grid.api.core.scrollToIfNecessary(b.row,b.col).then(function(){v(a)})}function v(h){if(!E&&t(b.col,b.row)){var k=b.row.getQualifiedColField(b.col);b.col.colDef.editModelField&&(k=f.preEval("row.entity."+b.col.colDef.editModelField)),B=g(k),A=B(b),z=b.col.editableCellTemplate,z=z.replace(d.MODEL_COL_FIELD,k),z=z.replace(d.COL_FIELD,"grid.getCellValue(row, col)");var m=b.col.colDef.editDropdownFilter?"|"+b.col.colDef.editDropdownFilter:"";z=z.replace(d.CUSTOM_FILTERS,m);var n="text";switch(b.col.colDef.type){case"boolean":n="checkbox";break;case"number":n="number";break;case"date":n="date"}z=z.replace("INPUT_TYPE",n);var o=b.col.colDef.editDropdownOptionsFunction;if(o)j.when(o(b.row.entity,b.col.colDef)).then(function(a){b.editDropdownOptionsArray=a});else{var p=b.col.colDef.editDropdownRowEntityOptionsArrayPath;p?b.editDropdownOptionsArray=y(b.row.entity,p):b.editDropdownOptionsArray=b.col.colDef.editDropdownOptionsArray}b.editDropdownIdLabel=b.col.colDef.editDropdownIdLabel?b.col.colDef.editDropdownIdLabel:"id",b.editDropdownValueLabel=b.col.colDef.editDropdownValueLabel?b.col.colDef.editDropdownValueLabel:"value";var q=function(){E=!0,r();var c=angular.element(z);l.append(c),D=b.$new(),a(c)(D);var d=angular.element(l.children()[0]);d.addClass("ui-grid-cell-contents-hidden")};i.$$phase?q():b.$apply(q);var s=b.col.grid.api.core.on.scrollBegin(b,function(){b.grid.disableScrolling||(w(),b.grid.api.edit.raise.afterCellEdit(b.row.entity,b.col.colDef,B(b),A),s(),u(),v())}),u=b.$on(e.events.END_CELL_EDIT,function(){w(),b.grid.api.edit.raise.afterCellEdit(b.row.entity,b.col.colDef,B(b),A),u(),s(),v()}),v=b.$on(e.events.CANCEL_CELL_EDIT,function(){x(),v(),s(),u()});b.$broadcast(e.events.BEGIN_CELL_EDIT,h),c(function(){b.grid.api.edit.raise.beginCellEdit(b.row.entity,b.col.colDef,h)})}}function w(){if(b.grid.disableScrolling=!1,E){n&&n.grid.api.cellNav&&n.focus();var a=angular.element(l.children()[0]);D.$destroy();for(var c=l.children(),e=1;ed||1>c||1>e?null:new Date(c,d-1,e)}return{priority:-100,require:"?ngModel",link:function(c,d,e,f){2===angular.version.minor&&e.type&&"date"===e.type&&f&&(f.$formatters.push(function(b){return f.$setValidity(null,!b||!isNaN(b.getTime())),a("date")(b,"yyyy-MM-dd")}),f.$parsers.push(function(a){if(a&&a.length>0){var c=b(a);return f.$setValidity(null,c&&!isNaN(c.getTime())),c}return f.$setValidity(null,!0),null}))}}}]),a.directive("uiGridEditDropdown",["uiGridConstants","uiGridEditConstants",function(a,b){return{require:["?^uiGrid","?^uiGridRenderContainer"],scope:!0,compile:function(){return{pre:function(a,b,c){},post:function(c,d,e,f){var g=f[0],h=f[1];c.$on(b.events.BEGIN_CELL_EDIT,function(){d[0].focus(),d[0].style.width=d[0].parentElement.offsetWidth-1+"px",d.on("blur",function(a){c.stopEdit(a)})}),c.stopEdit=function(a){c.$emit(b.events.END_CELL_EDIT)},d.on("keydown",function(d){switch(d.keyCode){case a.keymap.ESC:d.stopPropagation(),c.$emit(b.events.CANCEL_CELL_EDIT)}if(g&&g.grid.api.cellNav)d.uiGridTargetRenderContainerId=h.containerId,null!==g.cellNav.handleKeyDown(d)&&c.stopEdit(d);else switch(d.keyCode){case a.keymap.ENTER:case a.keymap.TAB:d.stopPropagation(),d.preventDefault(),c.stopEdit(d)}return!0})}}}}}]),a.directive("uiGridEditFileChooser",["gridUtil","uiGridConstants","uiGridEditConstants","$timeout",function(a,b,c,d){return{scope:!0,require:["?^uiGrid","?^uiGridRenderContainer"],compile:function(){return{pre:function(a,b,c){},post:function(b,d,e,f){var g,h;f[0]&&(g=f[0]),f[1]&&(h=f[1]);var i=(g.grid,function(d){var e=d.srcElement||d.target;e&&e.files&&e.files.length>0?("function"==typeof b.col.colDef.editFileChooserCallback?b.col.colDef.editFileChooserCallback(b.row,b.col,e.files):a.logError("You need to set colDef.editFileChooserCallback to use the file chooser"),e.form.reset(),b.$emit(c.events.END_CELL_EDIT)):b.$emit(c.events.CANCEL_CELL_EDIT)});d[0].addEventListener("change",i,!1),b.$on(c.events.BEGIN_CELL_EDIT,function(){d[0].focus(),d[0].select(),d.on("blur",function(a){b.$emit(c.events.END_CELL_EDIT)})})}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.expandable",["ui.grid"]);a.service("uiGridExpandableService",["gridUtil","$compile",function(a,b){var c={initializeGrid:function(b){b.expandable={},b.expandable.expandedAll=!1,b.options.enableExpandable=b.options.enableExpandable!==!1,b.options.expandableRowHeight=b.options.expandableRowHeight||150,b.options.expandableRowHeaderWidth=b.options.expandableRowHeaderWidth||40,b.options.enableExpandable&&!b.options.expandableRowTemplate&&(a.logError("You have not set the expandableRowTemplate, disabling expandable module"),b.options.enableExpandable=!1);var d={events:{expandable:{rowExpandedBeforeStateChanged:function(a,b){},rowExpandedStateChanged:function(a,b){}}},methods:{expandable:{toggleRowExpansion:function(a){var d=b.getRow(a);null!==d&&c.toggleRowExpansion(b,d)},expandAllRows:function(){c.expandAllRows(b)},collapseAllRows:function(){c.collapseAllRows(b)},toggleAllRows:function(){c.toggleAllRows(b)},expandRow:function(a){var d=b.getRow(a);null===d||d.isExpanded||c.toggleRowExpansion(b,d)},collapseRow:function(a){var d=b.getRow(a);null!==d&&d.isExpanded&&c.toggleRowExpansion(b,d)},getExpandedRows:function(){return c.getExpandedRows(b).map(function(a){return a.entity})}}}};b.api.registerEventsFromObject(d.events),b.api.registerMethodsFromObject(d.methods)},toggleRowExpansion:function(a,b){a.api.expandable.raise.rowExpandedBeforeStateChanged(b),b.isExpanded=!b.isExpanded,angular.isUndefined(b.expandedRowHeight)&&(b.expandedRowHeight=a.options.expandableRowHeight),b.isExpanded?b.height=b.grid.options.rowHeight+b.expandedRowHeight:(b.height=b.grid.options.rowHeight,a.expandable.expandedAll=!1),a.api.expandable.raise.rowExpandedStateChanged(b)},expandAllRows:function(a,b){a.renderContainers.body.visibleRowCache.forEach(function(b){b.isExpanded||c.toggleRowExpansion(a,b)}),a.expandable.expandedAll=!0,a.queueGridRefresh()},collapseAllRows:function(a){a.renderContainers.body.visibleRowCache.forEach(function(b){b.isExpanded&&c.toggleRowExpansion(a,b)}),a.expandable.expandedAll=!1,a.queueGridRefresh()},toggleAllRows:function(a){a.expandable.expandedAll?c.collapseAllRows(a):c.expandAllRows(a)},getExpandedRows:function(a){return a.rows.filter(function(a){return a.isExpanded})}};return c}]),a.directive("uiGridExpandable",["uiGridExpandableService","$templateCache",function(a,b){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(c,d,e,f){if(a.initializeGrid(f.grid),f.grid.options.enableExpandable&&f.grid.options.enableExpandableRowHeader!==!1){var g={name:"expandableButtons",displayName:"",exporterSuppressExport:!0,enableColumnResizing:!1,enableColumnMenu:!1,width:f.grid.options.expandableRowHeaderWidth||40};g.cellTemplate=b.get("ui-grid/expandableRowHeader"),g.headerCellTemplate=b.get("ui-grid/expandableTopRowHeader"),f.grid.addRowHeaderColumn(g,-90)}},post:function(a,b,c,d){}}}}}]),a.directive("uiGrid",["uiGridExpandableService","$templateCache",function(a,b){return{replace:!0,priority:599,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,b,c,d){d.grid.api.core.on.renderingComplete(a,function(){a.row&&a.row.grid&&a.row.grid.options&&a.row.grid.options.enableExpandable&&(d.grid.parentRow=a.row)})},post:function(a,b,c,d){}}}}}]),a.directive("uiGridExpandableRow",["uiGridExpandableService","$timeout","$compile","uiGridConstants","gridUtil","$interval","$log",function(a,b,c,d,e,f,g){return{replace:!1,priority:0,scope:!1,compile:function(){return{pre:function(a,b,d,f){e.getTemplate(a.grid.options.expandableRowTemplate).then(function(d){if(a.grid.options.expandableRowScope){var e=a.grid.options.expandableRowScope;for(var f in e)e.hasOwnProperty(f)&&(a[f]=e[f])}var g=angular.element(d);b.append(g),g=c(g)(a),a.row.expandedRendered=!0})},post:function(a,b,c,d){a.$on("$destroy",function(){a.row.expandedRendered=!1})}}}}}]),a.directive("uiGridRow",["$compile","gridUtil","$templateCache",function(a,b,c){return{priority:-200,scope:!1,compile:function(a,b){return{pre:function(a,b,c,d){a.grid.options.enableExpandable&&(a.expandableRow={},a.expandableRow.shouldRenderExpand=function(){var b="body"===a.colContainer.name&&a.grid.options.enableExpandable!==!1&&a.row.isExpanded&&(!a.grid.isScrollingVertically||a.row.expandedRendered);return b},a.expandableRow.shouldRenderFiller=function(){var b=a.row.isExpanded&&("body"!==a.colContainer.name||a.grid.isScrollingVertically&&!a.row.expandedRendered);return b})},post:function(a,b,c,d){}}}}}]),a.directive("uiGridViewport",["$compile","gridUtil","$templateCache",function(a,b,c){ +return{priority:-200,scope:!1,compile:function(a,b){var d=angular.element(a.children().children()[0]),e=c.get("ui-grid/expandableScrollFiller"),f=c.get("ui-grid/expandableRow");return d.append(f),d.append(e),{pre:function(a,b,c,d){},post:function(a,b,c,d){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.exporter",["ui.grid"]);a.constant("uiGridExporterConstants",{featureName:"exporter",ALL:"all",VISIBLE:"visible",SELECTED:"selected",CSV_CONTENT:"CSV_CONTENT",BUTTON_LABEL:"BUTTON_LABEL",FILE_NAME:"FILE_NAME"}),a.service("uiGridExporterService",["$q","uiGridExporterConstants","gridUtil","$compile","$interval","i18nService",function(a,b,c,d,e,f){var g={delay:100,initializeGrid:function(a){a.exporter={},this.defaultGridOptions(a.options);var b={events:{exporter:{}},methods:{exporter:{csvExport:function(b,c){g.csvExport(a,b,c)},pdfExport:function(b,c){g.pdfExport(a,b,c)}}}};a.api.registerEventsFromObject(b.events),a.api.registerMethodsFromObject(b.methods),a.api.core.addToGridMenu?g.addToMenu(a):e(function(){a.api.core.addToGridMenu&&g.addToMenu(a)},this.delay,1)},defaultGridOptions:function(a){a.exporterSuppressMenu=a.exporterSuppressMenu===!0,a.exporterMenuLabel=a.exporterMenuLabel?a.exporterMenuLabel:"Export",a.exporterSuppressColumns=a.exporterSuppressColumns?a.exporterSuppressColumns:[],a.exporterCsvColumnSeparator=a.exporterCsvColumnSeparator?a.exporterCsvColumnSeparator:",",a.exporterCsvFilename=a.exporterCsvFilename?a.exporterCsvFilename:"download.csv",a.exporterPdfFilename=a.exporterPdfFilename?a.exporterPdfFilename:"download.pdf",a.exporterOlderExcelCompatibility=a.exporterOlderExcelCompatibility===!0,a.exporterPdfDefaultStyle=a.exporterPdfDefaultStyle?a.exporterPdfDefaultStyle:{fontSize:11},a.exporterPdfTableStyle=a.exporterPdfTableStyle?a.exporterPdfTableStyle:{margin:[0,5,0,15]},a.exporterPdfTableHeaderStyle=a.exporterPdfTableHeaderStyle?a.exporterPdfTableHeaderStyle:{bold:!0,fontSize:12,color:"black"},a.exporterPdfHeader=a.exporterPdfHeader?a.exporterPdfHeader:null,a.exporterPdfFooter=a.exporterPdfFooter?a.exporterPdfFooter:null,a.exporterPdfOrientation=a.exporterPdfOrientation?a.exporterPdfOrientation:"landscape",a.exporterPdfPageSize=a.exporterPdfPageSize?a.exporterPdfPageSize:"A4",a.exporterPdfMaxGridWidth=a.exporterPdfMaxGridWidth?a.exporterPdfMaxGridWidth:720,a.exporterMenuAllData=void 0!==a.exporterMenuAllData?a.exporterMenuAllData:!0,a.exporterMenuVisibleData=void 0!==a.exporterMenuVisibleData?a.exporterMenuVisibleData:!0,a.exporterMenuSelectedData=void 0!==a.exporterMenuSelectedData?a.exporterMenuSelectedData:!0,a.exporterMenuCsv=void 0!==a.exporterMenuCsv?a.exporterMenuCsv:!0,a.exporterMenuPdf=void 0!==a.exporterMenuPdf?a.exporterMenuPdf:!0,a.exporterPdfCustomFormatter=a.exporterPdfCustomFormatter&&"function"==typeof a.exporterPdfCustomFormatter?a.exporterPdfCustomFormatter:function(a){return a},a.exporterHeaderFilterUseName=a.exporterHeaderFilterUseName===!0,a.exporterFieldCallback=a.exporterFieldCallback?a.exporterFieldCallback:function(a,b,c,d){return d},a.exporterAllDataFn=a.exporterAllDataFn?a.exporterAllDataFn:null,null==a.exporterAllDataFn&&a.exporterAllDataPromise&&(a.exporterAllDataFn=a.exporterAllDataPromise)},addToMenu:function(a){a.api.core.addToGridMenu(a,[{title:f.getSafeText("gridMenu.exporterAllAsCsv"),action:function(a){this.grid.api.exporter.csvExport(b.ALL,b.ALL)},shown:function(){return this.grid.options.exporterMenuCsv&&this.grid.options.exporterMenuAllData},order:200},{title:f.getSafeText("gridMenu.exporterVisibleAsCsv"),action:function(a){this.grid.api.exporter.csvExport(b.VISIBLE,b.VISIBLE)},shown:function(){return this.grid.options.exporterMenuCsv&&this.grid.options.exporterMenuVisibleData},order:201},{title:f.getSafeText("gridMenu.exporterSelectedAsCsv"),action:function(a){this.grid.api.exporter.csvExport(b.SELECTED,b.VISIBLE)},shown:function(){return this.grid.options.exporterMenuCsv&&this.grid.options.exporterMenuSelectedData&&this.grid.api.selection&&this.grid.api.selection.getSelectedRows().length>0},order:202},{title:f.getSafeText("gridMenu.exporterAllAsPdf"),action:function(a){this.grid.api.exporter.pdfExport(b.ALL,b.ALL)},shown:function(){return this.grid.options.exporterMenuPdf&&this.grid.options.exporterMenuAllData},order:203},{title:f.getSafeText("gridMenu.exporterVisibleAsPdf"),action:function(a){this.grid.api.exporter.pdfExport(b.VISIBLE,b.VISIBLE)},shown:function(){return this.grid.options.exporterMenuPdf&&this.grid.options.exporterMenuVisibleData},order:204},{title:f.getSafeText("gridMenu.exporterSelectedAsPdf"),action:function(a){this.grid.api.exporter.pdfExport(b.SELECTED,b.VISIBLE)},shown:function(){return this.grid.options.exporterMenuPdf&&this.grid.options.exporterMenuSelectedData&&this.grid.api.selection&&this.grid.api.selection.getSelectedRows().length>0},order:205}])},csvExport:function(a,b,c){var d=this;this.loadAllDataIfNeeded(a,b,c).then(function(){var e=a.options.showHeader?d.getColumnHeaders(a,c):[],f=d.getData(a,b,c),g=d.formatAsCsv(e,f,a.options.exporterCsvColumnSeparator);d.downloadFile(a.options.exporterCsvFilename,g,a.options.exporterCsvColumnSeparator,a.options.exporterOlderExcelCompatibility)})},loadAllDataIfNeeded:function(c,d,e){if(d===b.ALL&&c.rows.length!==c.options.totalItems&&c.options.exporterAllDataFn)return c.options.exporterAllDataFn().then(function(){c.modifyRows(c.options.data)});var f=a.defer();return f.resolve(),f.promise},getColumnHeaders:function(a,c){var d,e=[];if(c===b.ALL)d=a.columns;else{var f=a.renderContainers.left?a.renderContainers.left.visibleColumnCache.filter(function(a){return a.visible}):[],g=a.renderContainers.body?a.renderContainers.body.visibleColumnCache.filter(function(a){return a.visible}):[],h=a.renderContainers.right?a.renderContainers.right.visibleColumnCache.filter(function(a){return a.visible}):[];d=f.concat(g,h)}return d.forEach(function(b,c){b.colDef.exporterSuppressExport!==!0&&-1===a.options.exporterSuppressColumns.indexOf(b.name)&&e.push({name:b.field,displayName:a.options.exporterHeaderFilter?a.options.exporterHeaderFilterUseName?a.options.exporterHeaderFilter(b.name):a.options.exporterHeaderFilter(b.displayName):b.displayName,width:b.drawnWidth?b.drawnWidth:b.width,align:"number"===b.colDef.type?"right":"left"})}),e},getData:function(a,d,e,f){var g,h,i=[];switch(d){case b.ALL:g=a.rows;break;case b.VISIBLE:g=a.getVisibleRows();break;case b.SELECTED:a.api.selection?g=a.api.selection.getSelectedGridRows():c.logError("selection feature must be enabled to allow selected rows to be exported")}if(e===b.ALL)h=a.columns;else{var j=a.renderContainers.left?a.renderContainers.left.visibleColumnCache.filter(function(a){return a.visible}):[],k=a.renderContainers.body?a.renderContainers.body.visibleColumnCache.filter(function(a){return a.visible}):[],l=a.renderContainers.right?a.renderContainers.right.visibleColumnCache.filter(function(a){return a.visible}):[];h=j.concat(k,l)}return g.forEach(function(c,d){if(c.exporterEnableExporting!==!1){var g=[];h.forEach(function(d,h){if((d.visible||e===b.ALL)&&d.colDef.exporterSuppressExport!==!0&&-1===a.options.exporterSuppressColumns.indexOf(d.name)){var i=f?a.getCellDisplayValue(c,d):a.getCellValue(c,d),j={value:a.options.exporterFieldCallback(a,c,d,i)};d.colDef.exporterPdfAlign&&(j.alignment=d.colDef.exporterPdfAlign),g.push(j)}}),i.push(g)}}),i},formatAsCsv:function(a,b,c){var d=this,e=a.map(function(a){return{value:a.displayName}}),f=e.length>0?d.formatRowAsCsv(this,c)(e)+"\n":"";return f+=b.map(this.formatRowAsCsv(this,c)).join("\n")},formatRowAsCsv:function(a,b){return function(c){return c.map(a.formatFieldAsCsv).join(b)}},formatFieldAsCsv:function(a){return null==a.value?"":"number"==typeof a.value?a.value:"boolean"==typeof a.value?a.value?"TRUE":"FALSE":"string"==typeof a.value?'"'+a.value.replace(/"/g,'""')+'"':JSON.stringify(a.value)},isIE:function(){var a=navigator.userAgent.search(/(?:Edge|MSIE|Trident\/.*; rv:)/),b=!1;return-1!==a&&(b=!0),b},downloadFile:function(a,b,c,d){var e,f=document,g=f.createElement("a"),h="application/octet-stream;charset=utf-8",i=this.isIE();if(navigator.msSaveBlob)return navigator.msSaveOrOpenBlob(new Blob([d?"\ufeff":"",b],{type:h}),a);if(i){var j=f.createElement("iframe");return document.body.appendChild(j),j.contentWindow.document.open("text/html","replace"),j.contentWindow.document.write("sep="+c+"\r\n"+b),j.contentWindow.document.close(),j.contentWindow.focus(),j.contentWindow.document.execCommand("SaveAs",!0,a),document.body.removeChild(j),!0}if("download"in g){var k=new Blob([d?"\ufeff":"",b],{type:h});e=URL.createObjectURL(k),g.setAttribute("download",a)}else e="data:"+h+","+encodeURIComponent(b),g.setAttribute("target","_blank");g.href=e,g.setAttribute("style","display:none;"),f.body.appendChild(g),setTimeout(function(){if(g.click)g.click();else if(document.createEvent){var a=document.createEvent("MouseEvents");a.initEvent("click",!0,!0),g.dispatchEvent(a)}f.body.removeChild(g)},this.delay)},pdfExport:function(a,b,c){var d=this;this.loadAllDataIfNeeded(a,b,c).then(function(){var e=d.getColumnHeaders(a,c),f=d.getData(a,b,c),g=d.prepareAsPdf(a,e,f);d.isIE()||-1!==navigator.appVersion.indexOf("Edge")?d.downloadPDF(a.options.exporterPdfFilename,g):pdfMake.createPdf(g).open()})},downloadPDF:function(a,b){var c,d=document;d.createElement("a");c=this.isIE();var e,f=pdfMake.createPdf(b);f.getBuffer(function(b){if(e=new Blob([b]),navigator.msSaveBlob)return navigator.msSaveBlob(e,a);if(c){var f=d.createElement("iframe");return document.body.appendChild(f),f.contentWindow.document.open("text/html","replace"),f.contentWindow.document.write(e),f.contentWindow.document.close(),f.contentWindow.focus(),f.contentWindow.document.execCommand("SaveAs",!0,a),document.body.removeChild(f),!0}})},prepareAsPdf:function(a,b,c){var d=this.calculatePdfHeaderWidths(a,b),e=b.map(function(a){return{text:a.displayName,style:"tableHeader"}}),f=c.map(this.formatRowAsPdf(this)),g=[e].concat(f),h={pageOrientation:a.options.exporterPdfOrientation,pageSize:a.options.exporterPdfPageSize,content:[{style:"tableStyle",table:{headerRows:1,widths:d,body:g}}],styles:{tableStyle:a.options.exporterPdfTableStyle,tableHeader:a.options.exporterPdfTableHeaderStyle},defaultStyle:a.options.exporterPdfDefaultStyle};return a.options.exporterPdfLayout&&(h.layout=a.options.exporterPdfLayout),a.options.exporterPdfHeader&&(h.header=a.options.exporterPdfHeader),a.options.exporterPdfFooter&&(h.footer=a.options.exporterPdfFooter),a.options.exporterPdfCustomFormatter&&(h=a.options.exporterPdfCustomFormatter(h)),h},calculatePdfHeaderWidths:function(a,b){var c=0;b.forEach(function(a){"number"==typeof a.width&&(c+=a.width)});var d=0;b.forEach(function(a){if("*"===a.width&&(d+=100),"string"==typeof a.width&&a.width.match(/(\d)*%/)){var b=parseInt(a.width.match(/(\d)*%/)[0]);a.width=c*b/100,d+=a.width}});var e=c+d;return b.map(function(b){return"*"===b.width?b.width:b.width*a.options.exporterPdfMaxGridWidth/e})},formatRowAsPdf:function(a){return function(b){return b.map(a.formatFieldAsPdfString)}},formatFieldAsPdfString:function(a){var b;return b=null==a.value?"":"number"==typeof a.value?a.value.toString():"boolean"==typeof a.value?a.value?"TRUE":"FALSE":"string"==typeof a.value?a.value.replace(/"/g,'""'):JSON.stringify(a.value).replace(/^"/,"").replace(/"$/,""),a.alignment&&"string"==typeof a.alignment&&(b={text:b,alignment:a.alignment}),b}};return g}]),a.directive("uiGridExporter",["uiGridExporterConstants","uiGridExporterService","gridUtil","$compile",function(a,b,c,d){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,link:function(a,c,d,e){b.initializeGrid(e.grid),e.grid.exporter.$scope=a}}}])}(),function(){"use strict";var a=angular.module("ui.grid.grouping",["ui.grid","ui.grid.treeBase"]);a.constant("uiGridGroupingConstants",{featureName:"grouping",rowHeaderColName:"treeBaseRowHeaderCol",EXPANDED:"expanded",COLLAPSED:"collapsed",aggregation:{COUNT:"count",SUM:"sum",MAX:"max",MIN:"min",AVG:"avg"}}),a.service("uiGridGroupingService",["$q","uiGridGroupingConstants","gridUtil","rowSorter","GridRow","gridClassFactory","i18nService","uiGridConstants","uiGridTreeBaseService",function(a,b,c,d,e,f,g,h,i){var j={initializeGrid:function(a,b){i.initializeGrid(a,b),a.grouping={},a.grouping.groupHeaderCache={},j.defaultGridOptions(a.options),a.registerRowsProcessor(j.groupRows,400),a.registerColumnBuilder(j.groupingColumnBuilder),a.registerColumnsProcessor(j.groupingColumnProcessor,400);var c={events:{grouping:{aggregationChanged:{},groupingChanged:{}}},methods:{grouping:{getGrouping:function(b){var c=j.getGrouping(a);return c.grouping.forEach(function(a){a.colName=a.col.name,delete a.col}),c.aggregations.forEach(function(a){a.colName=a.col.name,delete a.col}),c.aggregations=c.aggregations.filter(function(a){return!a.aggregation.source||"grouping"!==a.aggregation.source}),b&&(c.rowExpandedStates=j.getRowExpandedStates(a.grouping.groupingHeaderCache)),c},setGrouping:function(b){j.setGrouping(a,b)},groupColumn:function(b){var c=a.getColumn(b);j.groupColumn(a,c)},ungroupColumn:function(b){var c=a.getColumn(b);j.ungroupColumn(a,c)},clearGrouping:function(){j.clearGrouping(a)},aggregateColumn:function(b,c,d){var e=a.getColumn(b);j.aggregateColumn(a,e,c,d)}}}};a.api.registerEventsFromObject(c.events),a.api.registerMethodsFromObject(c.methods),a.api.core.on.sortChanged(b,j.tidyPriorities)},defaultGridOptions:function(a){a.enableGrouping=a.enableGrouping!==!1,a.groupingShowCounts=a.groupingShowCounts!==!1,a.groupingNullLabel="undefined"==typeof a.groupingNullLabel?"Null":a.groupingNullLabel,a.enableGroupHeaderSelection=a.enableGroupHeaderSelection===!0},groupingColumnBuilder:function(a,d,e){if(a.enableGrouping!==!1){"undefined"==typeof d.grouping&&"undefined"!=typeof a.grouping?(d.grouping=angular.copy(a.grouping),"undefined"!=typeof d.grouping.groupPriority&&d.grouping.groupPriority>-1&&(d.treeAggregationFn=i.nativeAggregations()[b.aggregation.COUNT].aggregationFn,d.treeAggregationFinalizerFn=j.groupedFinalizerFn)):"undefined"==typeof d.grouping&&(d.grouping={}),"undefined"!=typeof d.grouping&&"undefined"!=typeof d.grouping.groupPriority&&d.grouping.groupPriority>=0&&(d.suppressRemoveSort=!0);var f={name:"ui.grid.grouping.group",title:g.get().grouping.group,icon:"ui-grid-icon-indent-right",shown:function(){return"undefined"==typeof this.context.col.grouping||"undefined"==typeof this.context.col.grouping.groupPriority||this.context.col.grouping.groupPriority<0},action:function(){j.groupColumn(this.context.col.grid,this.context.col)}},h={name:"ui.grid.grouping.ungroup",title:g.get().grouping.ungroup,icon:"ui-grid-icon-indent-left",shown:function(){return"undefined"!=typeof this.context.col.grouping&&"undefined"!=typeof this.context.col.grouping.groupPriority&&this.context.col.grouping.groupPriority>=0},action:function(){j.ungroupColumn(this.context.col.grid,this.context.col)}},k={name:"ui.grid.grouping.aggregateRemove",title:g.get().grouping.aggregate_remove,shown:function(){return"undefined"!=typeof this.context.col.treeAggregationFn},action:function(){j.aggregateColumn(this.context.col.grid,this.context.col,null)}},l=function(a,b){b=b||g.get().grouping["aggregate_"+a]||a;var e={name:"ui.grid.grouping.aggregate"+a,title:b,shown:function(){return"undefined"==typeof this.context.col.treeAggregation||"undefined"==typeof this.context.col.treeAggregation.type||this.context.col.treeAggregation.type!==a},action:function(){j.aggregateColumn(this.context.col.grid,this.context.col,a)}};c.arrayContainsObjectWithProperty(d.menuItems,"name","ui.grid.grouping.aggregate"+a)||d.menuItems.push(e)};d.colDef.groupingShowGroupingMenu!==!1&&(c.arrayContainsObjectWithProperty(d.menuItems,"name","ui.grid.grouping.group")||d.menuItems.push(f),c.arrayContainsObjectWithProperty(d.menuItems,"name","ui.grid.grouping.ungroup")||d.menuItems.push(h)),d.colDef.groupingShowAggregationMenu!==!1&&(angular.forEach(i.nativeAggregations(),function(a,b){l(b)}),angular.forEach(e.treeCustomAggregations,function(a,b){l(b,a.menuTitle)}),c.arrayContainsObjectWithProperty(d.menuItems,"name","ui.grid.grouping.aggregateRemove")||d.menuItems.push(k))}},groupingColumnProcessor:function(a,b){return a=j.moveGroupColumns(this,a,b)},groupedFinalizerFn:function(a){var b=this;"undefined"!=typeof a.groupVal?(a.rendered=a.groupVal,b.grid.options.groupingShowCounts&&"date"!==b.colDef.type&&(a.rendered+=" ("+a.value+")")):a.rendered=null},moveGroupColumns:function(a,b,c){return a.options.moveGroupColumns===!1?b:(b.forEach(function(a,b){a.groupingPosition=b}),b.sort(function(a,b){var c,d;return c=a.isRowHeader?a.headerPriority:"undefined"==typeof a.grouping||"undefined"==typeof a.grouping.groupPriority||a.grouping.groupPriority<0?null:a.grouping.groupPriority,d=b.isRowHeader?b.headerPriority:"undefined"==typeof b.grouping||"undefined"==typeof b.grouping.groupPriority||b.grouping.groupPriority<0?null:b.grouping.groupPriority,null!==c&&null===d?-1:null!==d&&null===c?1:null!==c&&null!==d?c-d:a.groupingPosition-b.groupingPosition}),b.forEach(function(a,b){delete a.groupingPosition}),b)},groupColumn:function(a,c){"undefined"==typeof c.grouping&&(c.grouping={});var d=j.getGrouping(a);c.grouping.groupPriority=d.grouping.length,c.sort?("undefined"==typeof c.sort.direction||null===c.sort.direction)&&(c.sort.direction=h.ASC):c.sort={direction:h.ASC},c.treeAggregation={type:b.aggregation.COUNT,source:"grouping"},c.treeAggregationFn=i.nativeAggregations()[b.aggregation.COUNT].aggregationFn,c.treeAggregationFinalizerFn=j.groupedFinalizerFn,a.api.grouping.raise.groupingChanged(c),a.api.core.raise.sortChanged(a,a.getColumnSorting()),a.queueGridRefresh()},ungroupColumn:function(a,b){"undefined"!=typeof b.grouping&&(delete b.grouping.groupPriority,delete b.treeAggregation,delete b.customTreeAggregationFinalizer,j.tidyPriorities(a),a.api.grouping.raise.groupingChanged(b),a.queueGridRefresh())},aggregateColumn:function(a,b,c){"undefined"!=typeof b.grouping&&"undefined"!=typeof b.grouping.groupPriority&&b.grouping.groupPriority>=0&&j.ungroupColumn(a,b);var d={};"undefined"!=typeof a.options.treeCustomAggregations[c]?d=a.options.treeCustomAggregations[c]:"undefined"!=typeof i.nativeAggregations()[c]&&(d=i.nativeAggregations()[c]),b.treeAggregation={type:c,label:g.get().aggregation[d.label]||d.label},b.treeAggregationFn=d.aggregationFn,b.treeAggregationFinalizerFn=d.finalizerFn,a.api.grouping.raise.aggregationChanged(b),a.queueGridRefresh()},setGrouping:function(a,b){"undefined"!=typeof b&&(j.clearGrouping(a),b.grouping&&b.grouping.length&&b.grouping.length>0&&b.grouping.forEach(function(b){var c=a.getColumn(b.colName);c&&j.groupColumn(a,c)}),b.aggregations&&b.aggregations.length&&b.aggregations.forEach(function(b){var c=a.getColumn(b.colName);c&&j.aggregateColumn(a,c,b.aggregation.type)}),b.rowExpandedStates&&j.applyRowExpandedStates(a.grouping.groupingHeaderCache,b.rowExpandedStates))},clearGrouping:function(a){var b=j.getGrouping(a);b.grouping.length>0&&b.grouping.forEach(function(b){b.col||(b.col=a.getColumn(b.colName)),j.ungroupColumn(a,b.col)}),b.aggregations.length>0&&b.aggregations.forEach(function(b){b.col||(b.col=a.getColumn(b.colName)),j.aggregateColumn(a,b.col,null)})},tidyPriorities:function(a){"undefined"!=typeof a&&"undefined"==typeof a.grid||"undefined"==typeof this.grid||(a=this.grid);var b=[],c=[];a.columns.forEach(function(a,d){"undefined"!=typeof a.grouping&&"undefined"!=typeof a.grouping.groupPriority&&a.grouping.groupPriority>=0?b.push(a):"undefined"!=typeof a.sort&&"undefined"!=typeof a.sort.priority&&a.sort.priority>=0&&c.push(a)}),b.sort(function(a,b){return a.grouping.groupPriority-b.grouping.groupPriority}),b.forEach(function(a,b){a.grouping.groupPriority=b,a.suppressRemoveSort=!0,"undefined"==typeof a.sort&&(a.sort={}),a.sort.priority=b});var d=b.length;c.sort(function(a,b){return a.sort.priority-b.sort.priority}),c.forEach(function(a,b){a.sort.priority=d,a.suppressRemoveSort=a.colDef.suppressRemoveSort,d++})},groupRows:function(a){if(0===a.length)return a;var b=this;b.grouping.oldGroupingHeaderCache=b.grouping.groupingHeaderCache||{},b.grouping.groupingHeaderCache={};for(var c=j.initialiseProcessingState(b),e=function(e,h){var i=b.getCellValue(g,e.col);e.initialised&&0===d.getSortFn(b,e.col,a)(i,e.currentValue)||(j.insertGroupHeader(b,a,f,c,h),f++)},f=0;f=0&&b.push({field:a.field,col:a,groupPriority:a.grouping.groupPriority,grouping:a.grouping}),a.treeAggregation&&a.treeAggregation.type&&c.push({field:a.field,col:a,aggregation:a.treeAggregation})}),b.sort(function(a,b){return a.groupPriority-b.groupPriority}),b.forEach(function(a,b){a.grouping.groupPriority=b,a.groupPriority=b,delete a.grouping}),{grouping:b,aggregations:c}},insertGroupHeader:function(a,b,c,d,g){var h=(d[g].fieldName,d[g].col),i=a.getCellValue(b[c],h),k=i;("undefined"==typeof i||null===i)&&(k=a.options.groupingNullLabel);for(var l=function(a){return angular.isObject(a)?JSON.stringify(a):a},m=a.grouping.oldGroupingHeaderCache,n=0;g>n;n++)m&&m[l(d[n].currentValue)]&&(m=m[l(d[n].currentValue)].children);var o;for(m&&m[l(i)]?(o=m[l(i)].row,o.entity={}):(o=new e({},null,a),f.rowTemplateAssigner.call(a,o)),o.entity["$$"+d[g].col.uid]={groupVal:k},o.treeLevel=g,o.groupHeader=!0,o.internalRow=!0,o.enableCellEdit=!1,o.enableSelection=a.options.enableGroupHeaderSelection,d[g].initialised=!0,d[g].currentValue=i,d[g].currentRow=o,j.finaliseProcessingState(d,g+1),b.splice(c,0,o),m=a.grouping.groupingHeaderCache,n=0;g>n;n++)m=m[l(d[n].currentValue)].children;m[l(i)]={row:o,children:{}}},finaliseProcessingState:function(a,b){for(var c=b;c 1 or < 1 file choosers within the menu item, error, cannot continue"):h[0].addEventListener("change",g,!1)}}}])}(),function(){"use strict";var a=angular.module("ui.grid.infiniteScroll",["ui.grid"]);a.service("uiGridInfiniteScrollService",["gridUtil","$compile","$timeout","uiGridConstants","ScrollEvent","$q",function(a,b,c,d,e,f){var g={initializeGrid:function(a,b){if(g.defaultGridOptions(a.options),a.options.enableInfiniteScroll){a.infiniteScroll={dataLoading:!1},g.setScrollDirections(a,a.options.infiniteScrollUp,a.options.infiniteScrollDown),a.api.core.on.scrollEnd(b,g.handleScroll);var c={events:{infiniteScroll:{needLoadMoreData:function(a,b){},needLoadMoreDataTop:function(a,b){}}},methods:{infiniteScroll:{dataLoaded:function(b,c){g.setScrollDirections(a,b,c);var d=g.adjustScroll(a).then(function(){a.infiniteScroll.dataLoading=!1});return d},resetScroll:function(b,c){return g.setScrollDirections(a,b,c),g.adjustInfiniteScrollPosition(a,0)},saveScrollPercentage:function(){a.infiniteScroll.prevScrollTop=a.renderContainers.body.prevScrollTop,a.infiniteScroll.previousVisibleRows=a.getVisibleRowCount()},dataRemovedTop:function(b,c){g.dataRemovedTop(a,b,c)},dataRemovedBottom:function(b,c){g.dataRemovedBottom(a,b,c)},setScrollDirections:function(b,c){g.setScrollDirections(a,b,c)}}}};a.api.registerEventsFromObject(c.events),a.api.registerMethodsFromObject(c.methods)}},defaultGridOptions:function(a){a.enableInfiniteScroll=a.enableInfiniteScroll!==!1,a.infiniteScrollRowsFromEnd=a.infiniteScrollRowsFromEnd||20,a.infiniteScrollUp=a.infiniteScrollUp===!0,a.infiniteScrollDown=a.infiniteScrollDown!==!1},setScrollDirections:function(a,b,c){a.infiniteScroll.scrollUp=b===!0,a.suppressParentScrollUp=b===!0,a.infiniteScroll.scrollDown=c!==!1,a.suppressParentScrollDown=c!==!1},handleScroll:function(a){if(!(a.grid.infiniteScroll&&a.grid.infiniteScroll.dataLoading||"ui.grid.adjustInfiniteScrollPosition"===a.source)&&a.y)if(0===a.y.percentage)a.grid.scrollDirection=d.scrollDirection.UP,g.loadData(a.grid);else if(1===a.y.percentage)a.grid.scrollDirection=d.scrollDirection.DOWN,g.loadData(a.grid);else{var b,c=a.grid.options.infiniteScrollRowsFromEnd/a.grid.renderContainers.body.visibleRowCache.length;a.grid.scrollDirection===d.scrollDirection.UP?(b=a.y.percentage,c>=b&&g.loadData(a.grid)):a.grid.scrollDirection===d.scrollDirection.DOWN&&(b=1-a.y.percentage,c>=b&&g.loadData(a.grid))}},loadData:function(a){a.infiniteScroll.previousVisibleRows=a.renderContainers.body.visibleRowCache.length,a.infiniteScroll.direction=a.scrollDirection,delete a.infiniteScroll.prevScrollTop,a.scrollDirection===d.scrollDirection.UP&&a.infiniteScroll.scrollUp?(a.infiniteScroll.dataLoading=!0,a.api.infiniteScroll.raise.needLoadMoreDataTop()):a.scrollDirection===d.scrollDirection.DOWN&&a.infiniteScroll.scrollDown&&(a.infiniteScroll.dataLoading=!0,a.api.infiniteScroll.raise.needLoadMoreData())},adjustScroll:function(a){var b=f.defer();return c(function(){var e,f,h,i,j;e=a.getViewportHeight()+a.headerHeight-a.renderContainers.body.headerHeight-a.scrollbarHeight,f=a.options.rowHeight,void 0===a.infiniteScroll.direction&&g.adjustInfiniteScrollPosition(a,0),h=a.getVisibleRowCount();var k=f*h;a.infiniteScroll.scrollDown&&e>k&&a.api.infiniteScroll.raise.needLoadMoreData(),a.infiniteScroll.direction===d.scrollDirection.UP&&(i=a.infiniteScroll.prevScrollTop||0,j=i+(h-a.infiniteScroll.previousVisibleRows)*f,g.adjustInfiniteScrollPosition(a,j),c(function(){ +b.resolve()})),a.infiniteScroll.direction===d.scrollDirection.DOWN&&(j=a.infiniteScroll.prevScrollTop||a.infiniteScroll.previousVisibleRows*f-e,g.adjustInfiniteScrollPosition(a,j),c(function(){b.resolve()}))},0),b.promise},adjustInfiniteScrollPosition:function(a,b){var c=new e(a,null,null,"ui.grid.adjustInfiniteScrollPosition"),d=a.getVisibleRowCount(),f=a.getViewportHeight()+a.headerHeight-a.renderContainers.body.headerHeight-a.scrollbarHeight,g=a.options.rowHeight,h=d*g-f;0===b&&a.infiniteScroll.scrollUp?c.y={percentage:1/h}:c.y={percentage:b/h},a.scrollContainers("",c)},dataRemovedTop:function(a,b,c){var d,e,f,h;return g.setScrollDirections(a,b,c),d=a.renderContainers.body.visibleRowCache.length,e=a.infiniteScroll.prevScrollTop,h=a.options.rowHeight,f=e-(a.infiniteScroll.previousVisibleRows-d)*h,g.adjustInfiniteScrollPosition(a,f)},dataRemovedBottom:function(a,b,c){var d;return g.setScrollDirections(a,b,c),d=a.infiniteScroll.prevScrollTop,g.adjustInfiniteScrollPosition(a,d)}};return g}]),a.directive("uiGridInfiniteScroll",["uiGridInfiniteScrollService",function(a){return{priority:-200,scope:!1,require:"^uiGrid",compile:function(b,c,d){return{pre:function(b,c,d,e){a.initializeGrid(e.grid,b)},post:function(a,b,c){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.moveColumns",["ui.grid"]);a.service("uiGridMoveColumnService",["$q","$timeout","$log","ScrollEvent","uiGridConstants","gridUtil",function(a,b,c,d,e,f){var g={initializeGrid:function(a){var b=this;this.registerPublicApi(a),this.defaultGridOptions(a.options),a.moveColumns={orderCache:[]},a.registerColumnBuilder(b.movableColumnBuilder),a.registerDataChangeCallback(b.verifyColumnOrder,[e.dataChange.COLUMN])},registerPublicApi:function(a){var b=this,c={events:{colMovable:{columnPositionChanged:function(a,b,c){}}},methods:{colMovable:{moveColumn:function(c,d){var e=a.columns;if(!angular.isNumber(c)||!angular.isNumber(d))return void f.logError("MoveColumn: Please provide valid values for originalPosition and finalPosition");for(var g=0,h=0;h=e.length-g||d>=e.length-g)return void f.logError("MoveColumn: Invalid values for originalPosition, finalPosition");var i=function(a){for(var b=a,c=0;b>=c;c++)angular.isDefined(e[c])&&(angular.isDefined(e[c].colDef.visible)&&e[c].colDef.visible===!1||e[c].isRowHeader===!0)&&b++;return b};b.redrawColumnAtPosition(a,i(c),i(d))}}}};a.api.registerEventsFromObject(c.events),a.api.registerMethodsFromObject(c.methods)},defaultGridOptions:function(a){a.enableColumnMoving=a.enableColumnMoving!==!1},movableColumnBuilder:function(b,c,d){var e=[];return b.enableColumnMoving=void 0===b.enableColumnMoving?d.enableColumnMoving:b.enableColumnMoving,a.all(e)},updateColumnCache:function(a){a.moveColumns.orderCache=a.getOnlyDataColumns()},verifyColumnOrder:function(a){var b,c=a.rowHeaderColumns.length;angular.forEach(a.moveColumns.orderCache,function(d,e){if(b=a.columns.indexOf(d),-1!==b&&b-c!==e){var f=a.columns.splice(b,1)[0];a.columns.splice(e+c,0,f)}})},redrawColumnAtPosition:function(a,c,d){var f=a.columns;if(c!==d){var h=d>c?c+1:c-1,i=Math.min(h,d);for(i;i<=Math.max(h,d)&&!f[i].visible;i++);if(!(i>Math.max(h,d))){var j=f[c];if(j.colDef.enableColumnMoving){if(c>d)for(var k=c;k>d;k--)f[k]=f[k-1];else if(d>c)for(var l=c;d>l;l++)f[l]=f[l+1];f[d]=j,g.updateColumnCache(a),a.queueGridRefresh(),b(function(){a.api.core.notifyDataChange(e.dataChange.COLUMN),a.api.colMovable.raise.columnPositionChanged(j.colDef,c,d)})}}}}};return g}]),a.directive("uiGridMoveColumns",["uiGridMoveColumnService",function(a){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(b,c,d,e){a.initializeGrid(e.grid)},post:function(a,b,c,d){}}}}}]),a.directive("uiGridHeaderCell",["$q","gridUtil","uiGridMoveColumnService","$document","$log","uiGridConstants","ScrollEvent",function(a,b,c,d,e,f,g){return{priority:-10,require:"^uiGrid",compile:function(){return{post:function(a,b,e,f){if(a.col.colDef.enableColumnMoving){var h,i,j,k,l,m,n=angular.element(b[0].querySelectorAll(".ui-grid-cell-contents")),o=!1,p=!1,q=function(b){h=a.grid.element[0].getBoundingClientRect().left,a.grid.hasLeftContainer()&&(h+=a.grid.renderContainers.left.header[0].getBoundingClientRect().width),i=b.pageX||(b.originalEvent?b.originalEvent.pageX:0),j=0,k=h+a.grid.getViewportWidth(),"mousedown"===b.type?(d.on("mousemove",r),d.on("mouseup",s)):"touchstart"===b.type&&(d.on("touchmove",r),d.on("touchend",s))},r=function(a){var b=a.pageX||(a.originalEvent?a.originalEvent.pageX:0),c=b-i;0!==c&&(document.onselectstart=function(){return!1},p=!0,o?o&&(w(c),i=b):v())},s=function(b){if(document.onselectstart=null,l&&(l.remove(),o=!1),u(),t(),p){for(var d=a.grid.columns,e=0,f=0;fj){var h,i=0;if(a.grid.isRTL()){for(h=e+1;hMath.abs(j))){c.redrawColumnAtPosition(a.grid,e,h-1);break}}else for(h=e-1;h>=0;h--)if((angular.isUndefined(d[h].colDef.visible)||d[h].colDef.visible===!0)&&(i+=d[h].drawnWidth||d[h].width||d[h].colDef.width,i>Math.abs(j))){c.redrawColumnAtPosition(a.grid,e,h+1);break}i0){var k,m=0;if(a.grid.isRTL()){for(k=e-1;k>0;k--)if((angular.isUndefined(d[k].colDef.visible)||d[k].colDef.visible===!0)&&(m+=d[k].drawnWidth||d[k].width||d[k].colDef.width,m>j)){c.redrawColumnAtPosition(a.grid,e,k);break}}else for(k=e+1;kj)){c.redrawColumnAtPosition(a.grid,e,k-1);break}j>m&&(g=d.length-1,a.grid.isRTL()&&(g=0),c.redrawColumnAtPosition(a.grid,e,g))}}},t=function(){n.on("touchstart",q),n.on("mousedown",q)},u=function(){n.off("touchstart",q),n.off("mousedown",q),d.off("mousemove",r),d.off("touchmove",r),d.off("mouseup",s),d.off("touchend",s)};t();var v=function(){o=!0,l=b.clone(),b.parent().append(l),l.addClass("movingColumn");var c={};c.left=b[0].offsetLeft+"px";var d=a.grid.element[0].getBoundingClientRect().right,e=b[0].getBoundingClientRect().right;e>d&&(m=a.col.drawnWidth+(d-e),c.width=m+"px"),l.css(c)},w=function(b){for(var c=a.grid.columns,d=0,e=0;ei?i:k,(n>=h||b>0)&&(k>=o||0>b))l.css({visibility:"visible",left:l[0].offsetLeft+(k>i?b:k-n)+"px"});else if(d>Math.ceil(f.grid.gridWidth)){b*=8;var p=new g(a.col.grid,null,null,"uiGridHeaderCell.moveElement");p.x={pixels:b},p.grid.scrollContainers("",p)}for(var q=0,r=0;r0?a.options.paginationCurrentPage=Math.min(a.options.paginationCurrentPage+1,c.methods.pagination.getTotalPages()):a.options.paginationCurrentPage++)},previousPage:function(){a.options.enablePagination&&(a.options.paginationCurrentPage=Math.max(a.options.paginationCurrentPage-1,1))},seek:function(b){if(a.options.enablePagination){if(!angular.isNumber(b)||1>b)throw"Invalid page number: "+b;a.options.paginationCurrentPage=Math.min(b,c.methods.pagination.getTotalPages())}}}}};a.api.registerEventsFromObject(c.events),a.api.registerMethodsFromObject(c.methods);var d=function(b){if(a.options.useExternalPagination||!a.options.enablePagination)return b;var c=parseInt(a.options.paginationPageSize,10),d=parseInt(a.options.paginationCurrentPage,10),e=b.filter(function(a){return a.visible});a.options.totalItems=e.length;var f=(d-1)*c;return f>e.length&&(d=a.options.paginationCurrentPage=1,f=(d-1)*c),e.slice(f,f+c)};a.registerRowsProcessor(d,900)},defaultGridOptions:function(b){b.enablePagination=b.enablePagination!==!1,b.enablePaginationControls=b.enablePaginationControls!==!1,b.useExternalPagination=b.useExternalPagination===!0,a.isNullOrUndefined(b.totalItems)&&(b.totalItems=0),a.isNullOrUndefined(b.paginationPageSizes)&&(b.paginationPageSizes=[250,500,1e3]),a.isNullOrUndefined(b.paginationPageSize)&&(b.paginationPageSizes.length>0?b.paginationPageSize=b.paginationPageSizes[0]:b.paginationPageSize=0),a.isNullOrUndefined(b.paginationCurrentPage)&&(b.paginationCurrentPage=1),a.isNullOrUndefined(b.paginationTemplate)&&(b.paginationTemplate="ui-grid/pagination")},onPaginationChanged:function(a,b,c){a.api.pagination.raise.paginationChanged(b,c),a.options.useExternalPagination||a.queueGridRefresh()}};return b}]),a.directive("uiGridPagination",["gridUtil","uiGridPaginationService",function(a,b){return{priority:-200,scope:!1,require:"uiGrid",link:{pre:function(c,d,e,f){b.initializeGrid(f.grid),a.getTemplate(f.grid.options.paginationTemplate).then(function(a){var b=angular.element(a);d.append(b),f.innerCompile(b)})}}}}]),a.directive("uiGridPager",["uiGridPaginationService","uiGridConstants","gridUtil","i18nService",function(a,b,c,d){return{priority:-200,scope:!0,require:"^uiGrid",link:function(e,f,g,h){var i=".ui-grid-pager-control-input";e.aria=d.getSafeText("pagination.aria"),e.paginationApi=h.grid.api.pagination,e.sizesLabel=d.getSafeText("pagination.sizes"),e.totalItemsLabel=d.getSafeText("pagination.totalItems"),e.paginationOf=d.getSafeText("pagination.of"),e.paginationThrough=d.getSafeText("pagination.through");var j=h.grid.options;h.grid.renderContainers.body.registerViewportAdjuster(function(a){return a.height=a.height-c.elementHeight(f,"padding"),a});var k=h.grid.registerDataChangeCallback(function(a){a.options.useExternalPagination||(a.options.totalItems=a.rows.length)},[b.dataChange.ROW]);e.$on("$destroy",k);var l=function(){e.showingLow=(j.paginationCurrentPage-1)*j.paginationPageSize+1,e.showingHigh=Math.min(j.paginationCurrentPage*j.paginationPageSize,j.totalItems)},m=e.$watch("grid.options.totalItems + grid.options.paginationPageSize",l),n=e.$watch("grid.options.paginationCurrentPage + grid.options.paginationPageSize",function(b,c){if(b!==c&&void 0!==c){if(!angular.isNumber(j.paginationCurrentPage)||j.paginationCurrentPage<1)return void(j.paginationCurrentPage=1);if(j.totalItems>0&&j.paginationCurrentPage>e.paginationApi.getTotalPages())return void(j.paginationCurrentPage=e.paginationApi.getTotalPages());l(),a.onPaginationChanged(e.grid,j.paginationCurrentPage,j.paginationPageSize)}});e.$on("$destroy",function(){m(),n()}),e.cantPageForward=function(){return j.totalItems>0?j.paginationCurrentPage>=e.paginationApi.getTotalPages():j.data.length<1},e.cantPageToLast=function(){return j.totalItems>0?e.cantPageForward():!0},e.cantPageBackward=function(){return j.paginationCurrentPage<=1};var o=function(a){a&&c.focus.bySelector(f,i)};e.pageFirstPageClick=function(){e.paginationApi.seek(1),o(e.cantPageBackward())},e.pagePreviousPageClick=function(){e.paginationApi.previousPage(),o(e.cantPageBackward())},e.pageNextPageClick=function(){e.paginationApi.nextPage(),o(e.cantPageForward())},e.pageLastPageClick=function(){e.paginationApi.seek(e.paginationApi.getTotalPages()),o(e.cantPageToLast())}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.pinning",["ui.grid"]);a.constant("uiGridPinningConstants",{container:{LEFT:"left",RIGHT:"right",NONE:""}}),a.service("uiGridPinningService",["gridUtil","GridRenderContainer","i18nService","uiGridPinningConstants",function(a,b,c,d){var e={initializeGrid:function(a){e.defaultGridOptions(a.options),a.registerColumnBuilder(e.pinningColumnBuilder);var b={events:{pinning:{columnPinned:function(a,b){}}},methods:{pinning:{pinColumn:function(b,c){e.pinColumn(a,b,c)}}}};a.api.registerEventsFromObject(b.events),a.api.registerMethodsFromObject(b.methods)},defaultGridOptions:function(a){a.enablePinning=a.enablePinning!==!1},pinningColumnBuilder:function(b,f,g){if(b.enablePinning=void 0===b.enablePinning?g.enablePinning:b.enablePinning,b.pinnedLeft?(f.renderContainer="left",f.grid.createLeftContainer()):b.pinnedRight&&(f.renderContainer="right",f.grid.createRightContainer()),b.enablePinning){var h={name:"ui.grid.pinning.pinLeft",title:c.get().pinning.pinLeft,icon:"ui-grid-icon-left-open",shown:function(){return"undefined"==typeof this.context.col.renderContainer||!this.context.col.renderContainer||"left"!==this.context.col.renderContainer},action:function(){e.pinColumn(this.context.col.grid,this.context.col,d.container.LEFT)}},i={name:"ui.grid.pinning.pinRight",title:c.get().pinning.pinRight,icon:"ui-grid-icon-right-open",shown:function(){return"undefined"==typeof this.context.col.renderContainer||!this.context.col.renderContainer||"right"!==this.context.col.renderContainer},action:function(){e.pinColumn(this.context.col.grid,this.context.col,d.container.RIGHT)}},j={name:"ui.grid.pinning.unpin",title:c.get().pinning.unpin,icon:"ui-grid-icon-cancel",shown:function(){return"undefined"!=typeof this.context.col.renderContainer&&null!==this.context.col.renderContainer&&"body"!==this.context.col.renderContainer},action:function(){e.pinColumn(this.context.col.grid,this.context.col,d.container.NONE)}};a.arrayContainsObjectWithProperty(f.menuItems,"name","ui.grid.pinning.pinLeft")||f.menuItems.push(h),a.arrayContainsObjectWithProperty(f.menuItems,"name","ui.grid.pinning.pinRight")||f.menuItems.push(i),a.arrayContainsObjectWithProperty(f.menuItems,"name","ui.grid.pinning.unpin")||f.menuItems.push(j)}},pinColumn:function(a,b,c){c===d.container.NONE?(b.renderContainer=null,b.colDef.pinnedLeft=b.colDef.pinnedRight=!1):(b.renderContainer=c,c===d.container.LEFT?a.createLeftContainer():c===d.container.RIGHT&&a.createRightContainer()),a.refresh().then(function(){a.api.pinning.raise.columnPinned(b.colDef,c)})}};return e}]),a.directive("uiGridPinning",["gridUtil","uiGridPinningService",function(a,b){return{require:"uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.initializeGrid(e.grid)},post:function(a,b,c,d){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.resizeColumns",["ui.grid"]);a.service("uiGridResizeColumnsService",["gridUtil","$q","$timeout",function(a,b,c){var d={defaultGridOptions:function(a){a.enableColumnResizing=a.enableColumnResizing!==!1,a.enableColumnResize===!1&&(a.enableColumnResizing=!1)},colResizerColumnBuilder:function(a,c,d){var e=[];return a.enableColumnResizing=void 0===a.enableColumnResizing?d.enableColumnResizing:a.enableColumnResizing,a.enableColumnResize===!1&&(a.enableColumnResizing=!1),b.all(e)},registerPublicApi:function(a){var b={events:{colResizable:{columnSizeChanged:function(a,b){}}}};a.api.registerEventsFromObject(b.events)},fireColumnSizeChanged:function(b,d,e){c(function(){b.api.colResizable?b.api.colResizable.raise.columnSizeChanged(d,e):a.logError("The resizeable api is not registered, this may indicate that you've included the module but not added the 'ui-grid-resize-columns' directive to your grid definition. Cannot raise any events.")})},findTargetCol:function(a,b,c){var d=a.getRenderContainer();if("left"===b){var e=d.visibleColumnCache.indexOf(a);return d.visibleColumnCache[e-1*c]}return a}};return d}]),a.directive("uiGridResizeColumns",["gridUtil","uiGridResizeColumnsService",function(a,b){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.defaultGridOptions(e.grid.options),e.grid.registerColumnBuilder(b.colResizerColumnBuilder),b.registerPublicApi(e.grid)},post:function(a,b,c,d){}}}}}]),a.directive("uiGridHeaderCell",["gridUtil","$templateCache","$compile","$q","uiGridResizeColumnsService","uiGridConstants","$timeout",function(a,b,c,d,e,f,g){return{priority:-10,require:"^uiGrid",compile:function(){return{post:function(a,d,h,i){var j=i.grid;if(j.options.enableColumnResizing){var k=b.get("ui-grid/columnResizer"),l=1;j.isRTL()&&(a.position="left",l=-1);var m=function(){for(var b=d[0].getElementsByClassName("ui-grid-column-resizer"),f=0;f
    '),f={priority:0,scope:{col:"=",position:"@",renderIndex:"="},require:"?^uiGrid",link:function(f,g,h,i){function j(a){i.grid.refreshCanvas(!0).then(function(){i.grid.queueGridRefresh()})}function k(a,b){var c=b;return a.minWidth&&ca.maxWidth&&(c=a.maxWidth),c}function l(a,b){a.originalEvent&&(a=a.originalEvent),a.preventDefault(),o=(a.targetTouches?a.targetTouches[0]:a).clientX-p,0>o?o=0:o>i.grid.gridWidth&&(o=i.grid.gridWidth);var g=d.findTargetCol(f.col,f.position,q);if(g.colDef.enableColumnResizing!==!1){i.grid.element.hasClass("column-resizing")||i.grid.element.addClass("column-resizing");var h=o-n,j=parseInt(g.drawnWidth+h*q,10);o+=(k(g,j)-j)*q,e.css({left:o+"px"}),i.fireEvent(c.events.ITEM_DRAGGING)}}function m(a,b){a.originalEvent&&(a=a.originalEvent),a.preventDefault(),i.grid.element.removeClass("column-resizing"),e.remove(),o=(a.changedTouches?a.changedTouches[0]:a).clientX-p;var c=o-n;if(0===c)return t(),void s();var g=d.findTargetCol(f.col,f.position,q);if(g.colDef.enableColumnResizing!==!1){var h=parseInt(g.drawnWidth+c*q,10);g.width=k(g,h),g.hasCustomWidth=!0,j(c),d.fireColumnSizeChanged(i.grid,g.colDef,c),t(),s()}}var n=0,o=0,p=0,q=1;i.grid.isRTL()&&(f.position="left",q=-1),"left"===f.position?g.addClass("left"):"right"===f.position&&g.addClass("right");var r=function(b,c){b.originalEvent&&(b=b.originalEvent),b.stopPropagation(),p=i.grid.element[0].getBoundingClientRect().left,n=(b.targetTouches?b.targetTouches[0]:b).clientX-p,i.grid.element.append(e),e.css({left:n}),"touchstart"===b.type?(a.on("touchend",m),a.on("touchmove",l),g.off("mousedown",r)):(a.on("mouseup",m),a.on("mousemove",l),g.off("touchstart",r))},s=function(){g.on("mousedown",r),g.on("touchstart",r)},t=function(){a.off("mouseup",m),a.off("touchend",m),a.off("mousemove",l),a.off("touchmove",l),g.off("mousedown",r),g.off("touchstart",r)};s();var u=function(a,e){a.stopPropagation();var h=d.findTargetCol(f.col,f.position,q);if(h.colDef.enableColumnResizing!==!1){var l=0,m=0,n=b.closestElm(g,".ui-grid-render-container"),o=n.querySelectorAll("."+c.COL_CLASS_PREFIX+h.uid+" .ui-grid-cell-contents");Array.prototype.forEach.call(o,function(a){var c;angular.element(a).parent().hasClass("ui-grid-header-cell")&&(c=angular.element(a).parent()[0].querySelectorAll(".ui-grid-column-menu-button")),b.fakeElement(a,{},function(a){var d=angular.element(a);d.attr("style","float: left");var e=b.elementWidth(d);if(c){var f=b.elementWidth(c);e+=f}e>l&&(l=e,m=l-e)})}),h.width=k(h,l),h.hasCustomWidth=!0,j(m),d.fireColumnSizeChanged(i.grid,h.colDef,m)}};g.on("dblclick",u),g.on("$destroy",function(){g.off("dblclick",u),t()})}};return f}])}(),function(){"use strict";var a=angular.module("ui.grid.rowEdit",["ui.grid","ui.grid.edit","ui.grid.cellNav"]);a.constant("uiGridRowEditConstants",{}),a.service("uiGridRowEditService",["$interval","$q","uiGridConstants","uiGridRowEditConstants","gridUtil",function(a,b,c,d,e){var f={initializeGrid:function(a,b){b.rowEdit={};var c={events:{rowEdit:{saveRow:function(a){}}},methods:{rowEdit:{setSavePromise:function(a,c){f.setSavePromise(b,a,c)},getDirtyRows:function(){return b.rowEdit.dirtyRows?b.rowEdit.dirtyRows:[]},getErrorRows:function(){return b.rowEdit.errorRows?b.rowEdit.errorRows:[]},flushDirtyRows:function(){return f.flushDirtyRows(b)},setRowsDirty:function(a){f.setRowsDirty(b,a)},setRowsClean:function(a){f.setRowsClean(b,a)}}}};b.api.registerEventsFromObject(c.events),b.api.registerMethodsFromObject(c.methods),b.api.core.on.renderingComplete(a,function(c){b.api.edit.on.afterCellEdit(a,f.endEditCell),b.api.edit.on.beginCellEdit(a,f.beginEditCell),b.api.edit.on.cancelCellEdit(a,f.cancelEditCell),b.api.cellNav&&b.api.cellNav.on.navigate(a,f.navigate)})},defaultGridOptions:function(a){},saveRow:function(a,b){var c=this;return function(){if(b.isSaving=!0,b.rowEditSavePromise)return b.rowEditSavePromise;var d=a.api.rowEdit.raise.saveRow(b.entity);return b.rowEditSavePromise?b.rowEditSavePromise.then(c.processSuccessPromise(a,b),c.processErrorPromise(a,b)):e.logError("A promise was not returned when saveRow event was raised, either nobody is listening to event, or event handler did not return a promise"),d}},setSavePromise:function(a,b,c){var d=a.getRow(b);d.rowEditSavePromise=c},processSuccessPromise:function(a,b){var c=this;return function(){delete b.isSaving,delete b.isDirty,delete b.isError,delete b.rowEditSaveTimer,delete b.rowEditSavePromise,c.removeRow(a.rowEdit.errorRows,b),c.removeRow(a.rowEdit.dirtyRows,b)}},processErrorPromise:function(a,b){return function(){delete b.isSaving,delete b.rowEditSaveTimer,delete b.rowEditSavePromise,b.isError=!0,a.rowEdit.errorRows||(a.rowEdit.errorRows=[]),f.isRowPresent(a.rowEdit.errorRows,b)||a.rowEdit.errorRows.push(b)}},removeRow:function(a,b){"undefined"!=typeof a&&null!==a&&a.forEach(function(c,d){c.uid===b.uid&&a.splice(d,1)})},isRowPresent:function(a,b){var c=!1;return a.forEach(function(a,d){a.uid===b.uid&&(c=!0)}),c},flushDirtyRows:function(a){var c=[];return a.api.rowEdit.getDirtyRows().forEach(function(b){f.saveRow(a,b)(),c.push(b.rowEditSavePromise)}),b.all(c)},endEditCell:function(a,b,c,d){var g=this.grid,h=g.getRow(a);return h?void((c!==d||h.isDirty)&&(g.rowEdit.dirtyRows||(g.rowEdit.dirtyRows=[]),h.isDirty||(h.isDirty=!0,g.rowEdit.dirtyRows.push(h)),delete h.isError,f.considerSetTimer(g,h))):void e.logError("Unable to find rowEntity in grid data, dirty flag cannot be set")},beginEditCell:function(a,b){var c=this.grid,d=c.getRow(a);return d?void f.cancelTimer(c,d):void e.logError("Unable to find rowEntity in grid data, timer cannot be cancelled")},cancelEditCell:function(a,b){var c=this.grid,d=c.getRow(a);return d?void f.considerSetTimer(c,d):void e.logError("Unable to find rowEntity in grid data, timer cannot be set")},navigate:function(a,b){var c=this.grid;a.row.rowEditSaveTimer&&f.cancelTimer(c,a.row),b&&b.row&&b.row!==a.row&&f.considerSetTimer(c,b.row)},considerSetTimer:function(b,c){if(f.cancelTimer(b,c),c.isDirty&&!c.isSaving&&-1!==b.options.rowEditWaitInterval){var d=b.options.rowEditWaitInterval?b.options.rowEditWaitInterval:2e3;c.rowEditSaveTimer=a(f.saveRow(b,c),d,1)}},cancelTimer:function(b,c){c.rowEditSaveTimer&&!c.isSaving&&(a.cancel(c.rowEditSaveTimer),delete c.rowEditSaveTimer)},setRowsDirty:function(a,b){var c;b.forEach(function(b,d){c=a.getRow(b),c?(a.rowEdit.dirtyRows||(a.rowEdit.dirtyRows=[]),c.isDirty||(c.isDirty=!0,a.rowEdit.dirtyRows.push(c)),delete c.isError,f.considerSetTimer(a,c)):e.logError("requested row not found in rowEdit.setRowsDirty, row was: "+b)})},setRowsClean:function(a,b){var c;b.forEach(function(b,d){c=a.getRow(b),c?(delete c.isDirty,f.removeRow(a.rowEdit.dirtyRows,c),f.cancelTimer(a,c),delete c.isError,f.removeRow(a.rowEdit.errorRows,c)):e.logError("requested row not found in rowEdit.setRowsClean, row was: "+b)})}};return f}]),a.directive("uiGridRowEdit",["gridUtil","uiGridRowEditService","uiGridEditConstants",function(a,b,c){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.initializeGrid(a,e.grid)},post:function(a,b,c,d){}}}}}]),a.directive("uiGridViewport",["$compile","uiGridConstants","gridUtil","$parse",function(a,b,c,d){return{priority:-200,scope:!1,compile:function(a,b){var c=angular.element(a.children().children()[0]),d=c.attr("ng-class"),e="";return e=d?d.slice(0,-1)+", 'ui-grid-row-dirty': row.isDirty, 'ui-grid-row-saving': row.isSaving, 'ui-grid-row-error': row.isError}":"{'ui-grid-row-dirty': row.isDirty, 'ui-grid-row-saving': row.isSaving, 'ui-grid-row-error': row.isError}",c.attr("ng-class",e),{pre:function(a,b,c,d){},post:function(a,b,c,d){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.saveState",["ui.grid","ui.grid.selection","ui.grid.cellNav","ui.grid.grouping","ui.grid.pinning","ui.grid.treeView"]);a.constant("uiGridSaveStateConstants",{featureName:"saveState"}),a.service("uiGridSaveStateService",["$q","uiGridSaveStateConstants","gridUtil","$compile","$interval","uiGridConstants",function(a,b,c,d,e,f){var g={initializeGrid:function(a){a.saveState={},this.defaultGridOptions(a.options);var b={events:{saveState:{}},methods:{saveState:{save:function(){return g.save(a)},restore:function(b,c){g.restore(a,b,c)}}}};a.api.registerEventsFromObject(b.events),a.api.registerMethodsFromObject(b.methods)},defaultGridOptions:function(a){a.saveWidths=a.saveWidths!==!1,a.saveOrder=a.saveOrder!==!1,a.saveScroll=a.saveScroll===!0,a.saveFocus=a.saveScroll!==!0&&a.saveFocus!==!1,a.saveVisible=a.saveVisible!==!1,a.saveSort=a.saveSort!==!1,a.saveFilter=a.saveFilter!==!1,a.saveSelection=a.saveSelection!==!1,a.saveGrouping=a.saveGrouping!==!1,a.saveGroupingExpandedStates=a.saveGroupingExpandedStates===!0,a.savePinning=a.savePinning!==!1,a.saveTreeView=a.saveTreeView!==!1},save:function(a){var b={};return b.columns=g.saveColumns(a),b.scrollFocus=g.saveScrollFocus(a),b.selection=g.saveSelection(a),b.grouping=g.saveGrouping(a),b.treeView=g.saveTreeView(a),b.pagination=g.savePagination(a),b},restore:function(a,b,c){c.columns&&g.restoreColumns(a,c.columns),c.scrollFocus&&g.restoreScrollFocus(a,b,c.scrollFocus),c.selection&&g.restoreSelection(a,c.selection),c.grouping&&g.restoreGrouping(a,c.grouping),c.treeView&&g.restoreTreeView(a,c.treeView),c.pagination&&g.restorePagination(a,c.pagination),a.refresh()},saveColumns:function(a){var b=[];return a.getOnlyDataColumns().forEach(function(c){var d={};d.name=c.name,a.options.saveVisible&&(d.visible=c.visible),a.options.saveWidths&&(d.width=c.width),a.options.saveSort&&(d.sort=angular.copy(c.sort)),a.options.saveFilter&&(d.filters=[],c.filters.forEach(function(a){var b={};angular.forEach(a,function(a,c){"condition"!==c&&"$$hashKey"!==c&&"placeholder"!==c&&(b[c]=a)}),d.filters.push(b)})),a.api.pinning&&a.options.savePinning&&(d.pinned=c.renderContainer?c.renderContainer:""),b.push(d)}),b},saveScrollFocus:function(a){if(!a.api.cellNav)return{};var b={};if(a.options.saveFocus){b.focus=!0;var c=a.api.cellNav.getFocusedCell();null!==c&&(null!==c.col&&(b.colName=c.col.colDef.name),null!==c.row&&(b.rowVal=g.getRowVal(a,c.row)))}return(a.options.saveScroll||a.options.saveFocus&&!b.colName&&!b.rowVal)&&(b.focus=!1,a.renderContainers.body.prevRowScrollIndex&&(b.rowVal=g.getRowVal(a,a.renderContainers.body.visibleRowCache[a.renderContainers.body.prevRowScrollIndex])),a.renderContainers.body.prevColScrollIndex&&(b.colName=a.renderContainers.body.visibleColumnCache[a.renderContainers.body.prevColScrollIndex].name)),b},saveSelection:function(a){if(!a.api.selection||!a.options.saveSelection)return[];var b=a.api.selection.getSelectedGridRows().map(function(b){return g.getRowVal(a,b)});return b},saveGrouping:function(a){return a.api.grouping&&a.options.saveGrouping?a.api.grouping.getGrouping(a.options.saveGroupingExpandedStates):{}},savePagination:function(a){return a.api.pagination&&a.options.paginationPageSize?{paginationCurrentPage:a.options.paginationCurrentPage,paginationPageSize:a.options.paginationPageSize}:{}},saveTreeView:function(a){return a.api.treeView&&a.options.saveTreeView?a.api.treeView.getTreeView():{}},getRowVal:function(a,b){if(!b)return null;var c={};return a.options.saveRowIdentity?(c.identity=!0,c.row=a.options.saveRowIdentity(b.entity)):(c.identity=!1,c.row=a.renderContainers.body.visibleRowCache.indexOf(b)),c},restoreColumns:function(a,b){var c=!1;b.forEach(function(b,d){var e=a.getColumn(b.name);if(e&&!a.isRowHeaderColumn(e)){!a.options.saveVisible||e.visible===b.visible&&e.colDef.visible===b.visible||(e.visible=b.visible,e.colDef.visible=b.visible,a.api.core.raise.columnVisibilityChanged(e)),a.options.saveWidths&&e.width!==b.width&&(e.width=b.width,e.hasCustomWidth=!0),!a.options.saveSort||angular.equals(e.sort,b.sort)||void 0===e.sort&&angular.isEmpty(b.sort)||(e.sort=angular.copy(b.sort),c=!0),a.options.saveFilter&&!angular.equals(e.filters,b.filters)&&(b.filters.forEach(function(a,b){angular.extend(e.filters[b],a),("undefined"==typeof a.term||null===a.term)&&delete e.filters[b].term}),a.api.core.raise.filterChanged()),a.api.pinning&&a.options.savePinning&&e.renderContainer!==b.pinned&&a.api.pinning.pinColumn(e,b.pinned);var f=a.getOnlyDataColumns().indexOf(e);if(-1!==f&&a.options.saveOrder&&f!==d){var g=a.columns.splice(f+a.rowHeaderColumns.length,1)[0];a.columns.splice(d+a.rowHeaderColumns.length,0,g)}}}),c&&a.api.core.raise.sortChanged(a,a.getColumnSorting())},restoreScrollFocus:function(a,b,c){if(a.api.cellNav){var d,e;if(c.colName){var f=a.options.columnDefs.filter(function(a){return a.name===c.colName});f.length>0&&(d=f[0])}c.rowVal&&c.rowVal.row&&(e=c.rowVal.identity?g.findRowByIdentity(a,c.rowVal):a.renderContainers.body.visibleRowCache[c.rowVal.row]);var h=e&&e.entity?e.entity:null;(d||h)&&(c.focus?a.api.cellNav.scrollToFocus(h,d):a.scrollTo(h,d))}},restoreSelection:function(a,b){a.api.selection&&(a.api.selection.clearSelectedRows(),b.forEach(function(b){if(b.identity){var c=g.findRowByIdentity(a,b);c&&a.api.selection.selectRow(c.entity)}else a.api.selection.selectRowByVisibleIndex(b.row)}))},restoreGrouping:function(a,b){a.api.grouping&&"undefined"!=typeof b&&null!==b&&!angular.equals(b,{})&&a.api.grouping.setGrouping(b)},restoreTreeView:function(a,b){a.api.treeView&&"undefined"!=typeof b&&null!==b&&!angular.equals(b,{})&&a.api.treeView.setTreeView(b)},restorePagination:function(a,b){a.api.pagination&&a.options.paginationPageSize&&(a.options.paginationCurrentPage=b.paginationCurrentPage,a.options.paginationPageSize=b.paginationPageSize)},findRowByIdentity:function(a,b){if(!a.options.saveRowIdentity)return null;var c=a.rows.filter(function(c){return a.options.saveRowIdentity(c.entity)===b.row?!0:!1});return c.length>0?c[0]:null}};return g}]),a.directive("uiGridSaveState",["uiGridSaveStateConstants","uiGridSaveStateService","gridUtil","$compile",function(a,b,c,d){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,link:function(a,c,d,e){b.initializeGrid(e.grid)}}}])}(),function(){"use strict";var a=angular.module("ui.grid.selection",["ui.grid"]);a.constant("uiGridSelectionConstants",{featureName:"selection",selectionRowHeaderColName:"selectionRowHeaderCol"}),angular.module("ui.grid").config(["$provide",function(a){a.decorator("GridRow",["$delegate",function(a){return a.prototype.setSelected=function(a){a!==this.isSelected&&(this.isSelected=a,this.grid.selection.selectedCount+=a?1:-1); +},a}])}]),a.service("uiGridSelectionService",["$q","$templateCache","uiGridSelectionConstants","gridUtil",function(a,b,c,d){var e={initializeGrid:function(a){a.selection={},a.selection.lastSelectedRow=null,a.selection.selectAll=!1,a.selection.selectedCount=0,e.defaultGridOptions(a.options);var b={events:{selection:{rowSelectionChanged:function(a,b,c){},rowSelectionChangedBatch:function(a,b,c){}}},methods:{selection:{toggleRowSelection:function(b,c){var d=a.getRow(b);null!==d&&e.toggleRowSelection(a,d,c,a.options.multiSelect,a.options.noUnselect)},selectRow:function(b,c){var d=a.getRow(b);null===d||d.isSelected||e.toggleRowSelection(a,d,c,a.options.multiSelect,a.options.noUnselect)},selectRowByVisibleIndex:function(b,c){var d=a.renderContainers.body.visibleRowCache[b];null===d||"undefined"==typeof d||d.isSelected||e.toggleRowSelection(a,d,c,a.options.multiSelect,a.options.noUnselect)},unSelectRow:function(b,c){var d=a.getRow(b);null!==d&&d.isSelected&&e.toggleRowSelection(a,d,c,a.options.multiSelect,a.options.noUnselect)},selectAllRows:function(b){if(a.options.multiSelect!==!1){var c=[];a.rows.forEach(function(d){d.isSelected||d.enableSelection===!1||(d.setSelected(!0),e.decideRaiseSelectionEvent(a,d,c,b))}),e.decideRaiseSelectionBatchEvent(a,c,b),a.selection.selectAll=!0}},selectAllVisibleRows:function(b){if(a.options.multiSelect!==!1){var c=[];a.rows.forEach(function(d){d.visible?d.isSelected||d.enableSelection===!1||(d.setSelected(!0),e.decideRaiseSelectionEvent(a,d,c,b)):d.isSelected&&(d.setSelected(!1),e.decideRaiseSelectionEvent(a,d,c,b))}),e.decideRaiseSelectionBatchEvent(a,c,b),a.selection.selectAll=!0}},clearSelectedRows:function(b){e.clearSelectedRows(a,b)},getSelectedRows:function(){return e.getSelectedRows(a).map(function(a){return a.entity})},getSelectedGridRows:function(){return e.getSelectedRows(a)},getSelectedCount:function(){return a.selection.selectedCount},setMultiSelect:function(b){a.options.multiSelect=b},setModifierKeysToMultiSelect:function(b){a.options.modifierKeysToMultiSelect=b},getSelectAllState:function(){return a.selection.selectAll}}}};a.api.registerEventsFromObject(b.events),a.api.registerMethodsFromObject(b.methods)},defaultGridOptions:function(a){a.enableRowSelection=a.enableRowSelection!==!1,a.multiSelect=a.multiSelect!==!1,a.noUnselect=a.noUnselect===!0,a.modifierKeysToMultiSelect=a.modifierKeysToMultiSelect===!0,a.enableRowHeaderSelection=a.enableRowHeaderSelection!==!1,"undefined"==typeof a.enableFullRowSelection&&(a.enableFullRowSelection=!a.enableRowHeaderSelection),a.enableSelectAll=a.enableSelectAll!==!1,a.enableSelectionBatchEvent=a.enableSelectionBatchEvent!==!1,a.selectionRowHeaderWidth=angular.isDefined(a.selectionRowHeaderWidth)?a.selectionRowHeaderWidth:30,a.enableFooterTotalSelected=a.enableFooterTotalSelected!==!1,a.isRowSelectable=angular.isDefined(a.isRowSelectable)?a.isRowSelectable:angular.noop},toggleRowSelection:function(a,b,c,d,f){var g=b.isSelected;if(b.enableSelection!==!1||g){var h;d||g?!d&&g&&(h=e.getSelectedRows(a),h.length>1&&(g=!1,e.clearSelectedRows(a,c))):e.clearSelectedRows(a,c),g&&f||(b.setSelected(!g),b.isSelected===!0&&(a.selection.lastSelectedRow=b),h=e.getSelectedRows(a),a.selection.selectAll=a.rows.length===h.length,a.api.selection.raise.rowSelectionChanged(b,c))}},shiftSelect:function(a,b,c,d){if(d){var f=e.getSelectedRows(a),g=f.length>0?a.renderContainers.body.visibleRowCache.indexOf(a.selection.lastSelectedRow):0,h=a.renderContainers.body.visibleRowCache.indexOf(b);if(g>h){var i=g;g=h,h=i}for(var j=[],k=g;h>=k;k++){var l=a.renderContainers.body.visibleRowCache[k];l&&(l.isSelected||l.enableSelection===!1||(l.setSelected(!0),a.selection.lastSelectedRow=l,e.decideRaiseSelectionEvent(a,l,j,c)))}e.decideRaiseSelectionBatchEvent(a,j,c)}},getSelectedRows:function(a){return a.rows.filter(function(a){return a.isSelected})},clearSelectedRows:function(a,b){var c=[];e.getSelectedRows(a).forEach(function(d){d.isSelected&&(d.setSelected(!1),e.decideRaiseSelectionEvent(a,d,c,b))}),e.decideRaiseSelectionBatchEvent(a,c,b),a.selection.selectAll=!1,a.selection.selectedCount=0},decideRaiseSelectionEvent:function(a,b,c,d){a.options.enableSelectionBatchEvent?c.push(b):a.api.selection.raise.rowSelectionChanged(b,d)},decideRaiseSelectionBatchEvent:function(a,b,c){b.length>0&&a.api.selection.raise.rowSelectionChangedBatch(b,c)}};return e}]),a.directive("uiGridSelection",["uiGridSelectionConstants","uiGridSelectionService","$templateCache","uiGridConstants",function(a,b,c,d){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(c,e,f,g){if(b.initializeGrid(g.grid),g.grid.options.enableRowHeaderSelection){var h={name:a.selectionRowHeaderColName,displayName:"",width:g.grid.options.selectionRowHeaderWidth,minWidth:10,cellTemplate:"ui-grid/selectionRowHeader",headerCellTemplate:"ui-grid/selectionHeaderCell",enableColumnResizing:!1,enableColumnMenu:!1,exporterSuppressExport:!0,allowCellFocus:!0};g.grid.addRowHeaderColumn(h,0)}var i=!1,j=function(a){return a.forEach(function(a){a.enableSelection=g.grid.options.isRowSelectable(a)}),a},k=function(){g.grid.options.isRowSelectable!==angular.noop&&i!==!0&&(g.grid.registerRowsProcessor(j,500),i=!0)};k();var l=g.grid.registerDataChangeCallback(k,[d.dataChange.OPTIONS]);c.$on("$destroy",l)},post:function(a,b,c,d){}}}}}]),a.directive("uiGridSelectionRowHeaderButtons",["$templateCache","uiGridSelectionService","gridUtil",function(a,b,c){return{replace:!0,restrict:"E",template:a.get("ui-grid/selectionRowHeaderButtons"),scope:!0,require:"^uiGrid",link:function(a,d,e,f){function g(a,c){c.stopPropagation(),c.shiftKey?b.shiftSelect(i,a,c,i.options.multiSelect):c.ctrlKey||c.metaKey?b.toggleRowSelection(i,a,c,i.options.multiSelect,i.options.noUnselect):b.toggleRowSelection(i,a,c,i.options.multiSelect&&!i.options.modifierKeysToMultiSelect,i.options.noUnselect)}function h(a){(a.ctrlKey||a.shiftKey)&&(a.target.onselectstart=function(){return!1},window.setTimeout(function(){a.target.onselectstart=null},0))}var i=f.grid;a.selectButtonClick=g,"ie"===c.detectBrowser()&&d.on("mousedown",h)}}}]),a.directive("uiGridSelectionSelectAllButtons",["$templateCache","uiGridSelectionService",function(a,b){return{replace:!0,restrict:"E",template:a.get("ui-grid/selectionSelectAllButtons"),scope:!1,link:function(a,c,d,e){var f=a.col.grid;a.headerButtonClick=function(a,c){f.selection.selectAll?(b.clearSelectedRows(f,c),f.options.noUnselect&&f.api.selection.selectRowByVisibleIndex(0,c),f.selection.selectAll=!1):f.options.multiSelect&&(f.api.selection.selectAllVisibleRows(c),f.selection.selectAll=!0)}}}}]),a.directive("uiGridViewport",["$compile","uiGridConstants","uiGridSelectionConstants","gridUtil","$parse","uiGridSelectionService",function(a,b,c,d,e,f){return{priority:-200,scope:!1,compile:function(a,b){var c=angular.element(a.children().children()[0]),d=c.attr("ng-class"),e="";return e=d?d.slice(0,-1)+",'ui-grid-row-selected': row.isSelected}":"{'ui-grid-row-selected': row.isSelected}",c.attr("ng-class",e),{pre:function(a,b,c,d){},post:function(a,b,c,d){}}}}}]),a.directive("uiGridCell",["$compile","uiGridConstants","uiGridSelectionConstants","gridUtil","$parse","uiGridSelectionService","$timeout",function(a,b,c,d,e,f,g){return{priority:-200,restrict:"A",require:"?^uiGrid",scope:!1,link:function(a,c,d,e){function h(){a.grid.options.enableRowSelection&&a.grid.options.enableFullRowSelection&&(c.addClass("ui-grid-disable-selection"),c.on("touchstart",m),c.on("touchend",n),c.on("click",l),a.registered=!0)}function i(){a.registered&&(c.removeClass("ui-grid-disable-selection"),c.off("touchstart",m),c.off("touchend",n),c.off("click",l),a.registered=!1)}var j=0,k=300;e.grid.api.cellNav&&e.grid.api.cellNav.on.viewPortKeyDown(a,function(b,c){null!==c&&c.row===a.row&&c.col===a.col&&32===b.keyCode&&"selectionRowHeaderCol"===a.col.colDef.name&&(f.toggleRowSelection(a.grid,a.row,b,a.grid.options.multiSelect&&!a.grid.options.modifierKeysToMultiSelect,a.grid.options.noUnselect),a.$apply())});var l=function(b){c.off("touchend",n),b.shiftKey?f.shiftSelect(a.grid,a.row,b,a.grid.options.multiSelect):b.ctrlKey||b.metaKey?f.toggleRowSelection(a.grid,a.row,b,a.grid.options.multiSelect,a.grid.options.noUnselect):f.toggleRowSelection(a.grid,a.row,b,a.grid.options.multiSelect&&!a.grid.options.modifierKeysToMultiSelect,a.grid.options.noUnselect),a.$apply(),g(function(){c.on("touchend",n)},k)},m=function(a){j=(new Date).getTime(),c.off("click",l)},n=function(a){var b=(new Date).getTime(),d=b-j;k>d&&l(a),g(function(){c.on("click",l)},k)};h();var o=a.grid.registerDataChangeCallback(function(){a.grid.options.enableRowSelection&&a.grid.options.enableFullRowSelection&&!a.registered?h():a.grid.options.enableRowSelection&&a.grid.options.enableFullRowSelection||!a.registered||i()},[b.dataChange.OPTIONS]);c.on("$destroy",o)}}}]),a.directive("uiGridGridFooter",["$compile","uiGridConstants","gridUtil",function(a,b,c){return{restrict:"EA",replace:!0,priority:-1e3,require:"^uiGrid",scope:!0,compile:function(b,d){return{pre:function(b,d,e,f){f.grid.options.showGridFooter&&c.getTemplate("ui-grid/gridFooterSelectedItems").then(function(c){var e=angular.element(c),f=a(e)(b);angular.element(d[0].getElementsByClassName("ui-grid-grid-footer")[0]).append(f)})},post:function(a,b,c,d){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.treeBase",["ui.grid"]);a.constant("uiGridTreeBaseConstants",{featureName:"treeBase",rowHeaderColName:"treeBaseRowHeaderCol",EXPANDED:"expanded",COLLAPSED:"collapsed",aggregation:{COUNT:"count",SUM:"sum",MAX:"max",MIN:"min",AVG:"avg"}}),a.service("uiGridTreeBaseService",["$q","uiGridTreeBaseConstants","gridUtil","GridRow","gridClassFactory","i18nService","uiGridConstants","rowSorter",function(a,b,c,d,e,f,g,h){var i={initializeGrid:function(a,b){a.treeBase={},a.treeBase.numberLevels=0,a.treeBase.expandAll=!1,a.treeBase.tree=[],i.defaultGridOptions(a.options),a.registerRowsProcessor(i.treeRows,410),a.registerColumnBuilder(i.treeBaseColumnBuilder),i.createRowHeader(a);var c={events:{treeBase:{rowExpanded:{},rowCollapsed:{}}},methods:{treeBase:{expandAllRows:function(){i.expandAllRows(a)},collapseAllRows:function(){i.collapseAllRows(a)},toggleRowTreeState:function(b){i.toggleRowTreeState(a,b)},expandRow:function(b){i.expandRow(a,b)},expandRowChildren:function(b){i.expandRowChildren(a,b)},collapseRow:function(b){i.collapseRow(a,b)},collapseRowChildren:function(b){i.collapseRowChildren(a,b)},getTreeExpandedState:function(){return{expandedState:i.getTreeState(a)}},setTreeState:function(b){i.setTreeState(a,b)},getRowChildren:function(a){return a.treeNode.children.map(function(a){return a.row})}}}};a.api.registerEventsFromObject(c.events),a.api.registerMethodsFromObject(c.methods)},defaultGridOptions:function(a){a.treeRowHeaderBaseWidth=a.treeRowHeaderBaseWidth||30,a.treeIndent=a.treeIndent||10,a.showTreeRowHeader=a.showTreeRowHeader!==!1,a.showTreeExpandNoChildren=a.showTreeExpandNoChildren!==!1,a.treeRowHeaderAlwaysVisible=a.treeRowHeaderAlwaysVisible!==!1,a.treeCustomAggregations=a.treeCustomAggregations||{},a.enableExpandAll=a.enableExpandAll!==!1},treeBaseColumnBuilder:function(a,b,c){"undefined"!=typeof a.customTreeAggregationFn&&(b.treeAggregationFn=a.customTreeAggregationFn),"undefined"!=typeof a.treeAggregationType&&(b.treeAggregation={type:a.treeAggregationType},"undefined"!=typeof c.treeCustomAggregations[a.treeAggregationType]?(b.treeAggregationFn=c.treeCustomAggregations[a.treeAggregationType].aggregationFn,b.treeAggregationFinalizerFn=c.treeCustomAggregations[a.treeAggregationType].finalizerFn,b.treeAggregation.label=c.treeCustomAggregations[a.treeAggregationType].label):"undefined"!=typeof i.nativeAggregations()[a.treeAggregationType]&&(b.treeAggregationFn=i.nativeAggregations()[a.treeAggregationType].aggregationFn,b.treeAggregation.label=i.nativeAggregations()[a.treeAggregationType].label)),"undefined"!=typeof a.treeAggregationLabel&&("undefined"==typeof b.treeAggregation&&(b.treeAggregation={}),b.treeAggregation.label=a.treeAggregationLabel),b.treeAggregationUpdateEntity=a.treeAggregationUpdateEntity!==!1,"undefined"==typeof b.customTreeAggregationFinalizerFn&&(b.customTreeAggregationFinalizerFn=a.customTreeAggregationFinalizerFn)},createRowHeader:function(a){var c={name:b.rowHeaderColName,displayName:"",width:a.options.treeRowHeaderBaseWidth,minWidth:10,cellTemplate:"ui-grid/treeBaseRowHeader",headerCellTemplate:"ui-grid/treeBaseHeaderCell",enableColumnResizing:!1,enableColumnMenu:!1,exporterSuppressExport:!0,allowCellFocus:!0};c.visible=a.options.treeRowHeaderAlwaysVisible,a.addRowHeaderColumn(c,-100)},expandAllRows:function(a){a.treeBase.tree.forEach(function(c){i.setAllNodes(a,c,b.EXPANDED)}),a.treeBase.expandAll=!0,a.queueGridRefresh()},collapseAllRows:function(a){a.treeBase.tree.forEach(function(c){i.setAllNodes(a,c,b.COLLAPSED)}),a.treeBase.expandAll=!1,a.queueGridRefresh()},setAllNodes:function(a,c,d){"undefined"!=typeof c.state&&c.state!==d&&(c.state=d,d===b.EXPANDED?a.api.treeBase.raise.rowExpanded(c.row):a.api.treeBase.raise.rowCollapsed(c.row)),c.children&&c.children.forEach(function(b){i.setAllNodes(a,b,d)})},toggleRowTreeState:function(a,c){"undefined"==typeof c.treeLevel||null===c.treeLevel||c.treeLevel<0||(c.treeNode.state===b.EXPANDED?i.collapseRow(a,c):i.expandRow(a,c),a.queueGridRefresh())},expandRow:function(a,c){"undefined"==typeof c.treeLevel||null===c.treeLevel||c.treeLevel<0||c.treeNode.state!==b.EXPANDED&&(c.treeNode.state=b.EXPANDED,a.api.treeBase.raise.rowExpanded(c),a.treeBase.expandAll=i.allExpanded(a.treeBase.tree),a.queueGridRefresh())},expandRowChildren:function(a,c){"undefined"==typeof c.treeLevel||null===c.treeLevel||c.treeLevel<0||(i.setAllNodes(a,c.treeNode,b.EXPANDED),a.treeBase.expandAll=i.allExpanded(a.treeBase.tree),a.queueGridRefresh())},collapseRow:function(a,c){"undefined"==typeof c.treeLevel||null===c.treeLevel||c.treeLevel<0||c.treeNode.state!==b.COLLAPSED&&(c.treeNode.state=b.COLLAPSED,a.treeBase.expandAll=!1,a.api.treeBase.raise.rowCollapsed(c),a.queueGridRefresh())},collapseRowChildren:function(a,c){"undefined"==typeof c.treeLevel||null===c.treeLevel||c.treeLevel<0||(i.setAllNodes(a,c.treeNode,b.COLLAPSED),a.treeBase.expandAll=!1,a.queueGridRefresh())},allExpanded:function(a){var b=!0;return a.forEach(function(a){i.allExpandedInternal(a)||(b=!1)}),b},allExpandedInternal:function(a){if(a.children&&a.children.length>0){if(a.state===b.COLLAPSED)return!1;var c=!0;return a.children.forEach(function(a){i.allExpandedInternal(a)||(c=!1)}),c}return!0},treeRows:function(a){if(0===a.length)return a;var c=this;b.EXPANDED;return c.treeBase.tree=i.createTree(c,a),i.updateRowHeaderWidth(c),i.sortTree(c),i.fixFilter(c),i.renderTree(c.treeBase.tree)},updateRowHeaderWidth:function(a){var c=a.getColumn(b.rowHeaderColName),d=a.options.treeRowHeaderBaseWidth+a.options.treeIndent*Math.max(a.treeBase.numberLevels-1,0);c&&d!==c.width&&(c.width=d,a.queueRefresh());var e=!0;a.options.showTreeRowHeader===!1&&(e=!1),a.options.treeRowHeaderAlwaysVisible===!1&&a.treeBase.numberLevels<=0&&(e=!1),c.visible!==e&&(c.visible=e,c.colDef.visible=e,a.queueGridRefresh())},renderTree:function(a){var c=[];return a.forEach(function(a){a.row.visible&&c.push(a.row),a.state===b.EXPANDED&&a.children&&a.children.length>0&&(c=c.concat(i.renderTree(a.children)))}),c},createTree:function(a,c){var d,e=-1,f=[];a.treeBase.tree=[],a.treeBase.numberLevels=0;var g=i.getAggregations(a),h=function(c){if("undefined"!=typeof c.entity.$$treeLevel&&c.treeLevel!==c.entity.$$treeLevel&&(c.treeLevel=c.entity.$$treeLevel),c.treeLevel<=e){for(;c.treeLevel<=e;){var h=f.pop();i.finaliseAggregations(h),e--}d=f.length>0?i.setCurrentState(f):b.EXPANDED}("undefined"==typeof c.treeLevel||null===c.treeLevel||c.treeLevel<0)&&c.visible&&i.aggregate(a,c,f),i.addOrUseNode(a,c,f,g),"undefined"!=typeof c.treeLevel&&null!==c.treeLevel&&c.treeLevel>=0&&(f.push(c),e++,d=i.setCurrentState(f)),a.treeBase.numberLevels0;){var j=f.pop();i.finaliseAggregations(j)}return a.treeBase.tree},addOrUseNode:function(a,c,d,e){var f=[];e.forEach(function(a){f.push(i.buildAggregationObject(a.col))});var g={state:b.COLLAPSED,row:c,parentRow:null,aggregations:f,children:[]};c.treeNode&&(g.state=c.treeNode.state),d.length>0&&(g.parentRow=d[d.length-1]),c.treeNode=g,0===d.length?a.treeBase.tree.push(g):d[d.length-1].treeNode.children.push(g)},setCurrentState:function(a){var c=b.EXPANDED;return a.forEach(function(a){a.treeNode.state===b.COLLAPSED&&(c=b.COLLAPSED)}),c},sortTree:function(a){a.columns.forEach(function(a){a.sort&&a.sort.ignoreSort&&delete a.sort.ignoreSort}),a.treeBase.tree=i.sortInternal(a,a.treeBase.tree)},sortInternal:function(a,c){var d=c.map(function(a){return a.row});d=h.sort(a,d,a.columns);var e=d.map(function(a){return a.treeNode});return e.forEach(function(c){c.state===b.EXPANDED&&c.children&&c.children.length>0&&(c.children=i.sortInternal(a,c.children))}),e},fixFilter:function(a){var b;a.treeBase.tree.forEach(function(a){a.children&&a.children.length>0&&(b=a.row.visible,i.fixFilterInternal(a.children,b))})},fixFilterInternal:function(a,b){return a.forEach(function(a){a.row.visible&&!b&&(i.setParentsVisible(a),b=!0),a.children&&a.children.length>0&&i.fixFilterInternal(a.children,b&&a.row.visible)&&(b=!0)}),b},setParentsVisible:function(a){for(;a.parentRow;)a.parentRow.visible=!0,a=a.parentRow.treeNode},buildAggregationObject:function(a){var b={col:a};return a.treeAggregation&&a.treeAggregation.type&&(b.type=a.treeAggregation.type),a.treeAggregation&&a.treeAggregation.label&&(b.label=a.treeAggregation.label),b},getAggregations:function(a){var b=[];return a.columns.forEach(function(c){"undefined"!=typeof c.treeAggregationFn&&(b.push(i.buildAggregationObject(c)),a.options.showColumnFooter&&"undefined"==typeof c.colDef.aggregationType&&c.treeAggregation&&(c.treeFooterAggregation=i.buildAggregationObject(c),c.aggregationType=i.treeFooterAggregationType))}),b},aggregate:function(a,b,c){0===c.length&&b.treeNode&&b.treeNode.aggregations&&b.treeNode.aggregations.forEach(function(c){if("undefined"!=typeof c.col.treeFooterAggregation){var d=a.getCellValue(b,c.col),e=Number(d);c.col.treeAggregationFn(c.col.treeFooterAggregation,d,e,b)}}),c.forEach(function(c,d){c.treeNode.aggregations&&c.treeNode.aggregations.forEach(function(c){var e=a.getCellValue(b,c.col),f=Number(e);c.col.treeAggregationFn(c,e,f,b),0===d&&"undefined"!=typeof c.col.treeFooterAggregation&&c.col.treeAggregationFn(c.col.treeFooterAggregation,e,f,b)})})},nativeAggregations:function(){var a={count:{label:f.get().aggregation.count,menuTitle:f.get().grouping.aggregate_count,aggregationFn:function(a,b,c){"undefined"==typeof a.value?a.value=1:a.value++}},sum:{label:f.get().aggregation.sum,menuTitle:f.get().grouping.aggregate_sum,aggregationFn:function(a,b,c){isNaN(c)||("undefined"==typeof a.value?a.value=c:a.value+=c)}},min:{label:f.get().aggregation.min,menuTitle:f.get().grouping.aggregate_min,aggregationFn:function(a,b,c){"undefined"==typeof a.value?a.value=b:"undefined"!=typeof b&&null!==b&&(ba.value||null===a.value)&&(a.value=b)}},avg:{label:f.get().aggregation.avg,menuTitle:f.get().grouping.aggregate_avg,aggregationFn:function(a,b,c){"undefined"==typeof a.count?a.count=1:a.count++,isNaN(c)||("undefined"==typeof a.value||"undefined"==typeof a.sum?(a.value=c,a.sum=c):(a.sum+=c,a.value=a.sum/a.count))}}};return a},finaliseAggregation:function(a,b){b.col.treeAggregationUpdateEntity&&"undefined"!=typeof a&&"undefined"!=typeof a.entity["$$"+b.col.uid]&&angular.extend(b,a.entity["$$"+b.col.uid]),"function"==typeof b.col.treeAggregationFinalizerFn&&b.col.treeAggregationFinalizerFn(b),"function"==typeof b.col.customTreeAggregationFinalizerFn&&b.col.customTreeAggregationFinalizerFn(b),"undefined"==typeof b.rendered&&(b.rendered=b.label?b.label+b.value:b.value)},finaliseAggregations:function(a){null!=a&&"undefined"!=typeof a.treeNode.aggregations&&a.treeNode.aggregations.forEach(function(b){if(i.finaliseAggregation(a,b),b.col.treeAggregationUpdateEntity){var c={};angular.forEach(b,function(a,d){b.hasOwnProperty(d)&&"col"!==d&&(c[d]=a)}),a.entity["$$"+b.col.uid]=c}})},treeFooterAggregationType:function(a,b){return i.finaliseAggregation(void 0,b.treeFooterAggregation),"undefined"==typeof b.treeFooterAggregation.value||null===b.treeFooterAggregation.rendered?"":b.treeFooterAggregation.rendered}};return i}]),a.directive("uiGridTreeBaseRowHeaderButtons",["$templateCache","uiGridTreeBaseService",function(a,b){return{replace:!0,restrict:"E",template:a.get("ui-grid/treeBaseRowHeaderButtons"),scope:!0,require:"^uiGrid",link:function(a,c,d,e){var f=e.grid;a.treeButtonClick=function(a,c){b.toggleRowTreeState(f,a,c)}}}}]),a.directive("uiGridTreeBaseExpandAllButtons",["$templateCache","uiGridTreeBaseService",function(a,b){return{replace:!0,restrict:"E",template:a.get("ui-grid/treeBaseExpandAllButtons"),scope:!1,link:function(a,c,d,e){var f=a.col.grid;a.headerButtonClick=function(a,c){f.treeBase.expandAll?b.collapseAllRows(f,c):b.expandAllRows(f,c)}}}}]),a.directive("uiGridViewport",["$compile","uiGridConstants","gridUtil","$parse",function(a,b,c,d){return{priority:-200,scope:!1,compile:function(a,b){var c=angular.element(a.children().children()[0]),d=c.attr("ng-class"),e="";return e=d?d.slice(0,-1)+",'ui-grid-tree-header-row': row.treeLevel > -1}":"{'ui-grid-tree-header-row': row.treeLevel > -1}",c.attr("ng-class",e),{pre:function(a,b,c,d){},post:function(a,b,c,d){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.treeView",["ui.grid","ui.grid.treeBase"]);a.constant("uiGridTreeViewConstants",{featureName:"treeView",rowHeaderColName:"treeBaseRowHeaderCol",EXPANDED:"expanded",COLLAPSED:"collapsed",aggregation:{COUNT:"count",SUM:"sum",MAX:"max",MIN:"min",AVG:"avg"}}),a.service("uiGridTreeViewService",["$q","uiGridTreeViewConstants","uiGridTreeBaseConstants","uiGridTreeBaseService","gridUtil","GridRow","gridClassFactory","i18nService","uiGridConstants",function(a,b,c,d,e,f,g,h,i){var j={initializeGrid:function(a,b){d.initializeGrid(a,b),a.treeView={},a.registerRowsProcessor(j.adjustSorting,60);var c={events:{treeView:{}},methods:{treeView:{}}};a.api.registerEventsFromObject(c.events),a.api.registerMethodsFromObject(c.methods)},defaultGridOptions:function(a){a.enableTreeView=a.enableTreeView!==!1},adjustSorting:function(a){var b=this;return b.columns.forEach(function(a){a.sort&&(a.sort.ignoreSort=!0)}),a}};return j}]),a.directive("uiGridTreeView",["uiGridTreeViewConstants","uiGridTreeViewService","$templateCache",function(a,b,c){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){e.grid.options.enableTreeView!==!1&&b.initializeGrid(e.grid,a)},post:function(a,b,c,d){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.validate",["ui.grid"]);a.service("uiGridValidateService",["$sce","$q","$http","i18nService","uiGridConstants",function(a,b,c,d,e){var f={validatorFactories:{},setExternalFactoryFunction:function(a){f.externalFactoryFunction=a},clearExternalFactory:function(){delete f.externalFactoryFunction},getValidatorFromExternalFactory:function(a,b){return f.externalFactoryFunction(a,b).validatorFactory(b)},getMessageFromExternalFactory:function(a,b){return f.externalFactoryFunction(a,b).messageFunction(b)},setValidator:function(a,b,c){f.validatorFactories[a]={validatorFactory:b,messageFunction:c}},getValidator:function(a,b){if(f.externalFactoryFunction){var c=f.getValidatorFromExternalFactory(a,b);if(c)return c}if(!f.validatorFactories[a])throw"Invalid validator name: "+a;return f.validatorFactories[a].validatorFactory(b)},getMessage:function(a,b){if(f.externalFactoryFunction){var c=f.getMessageFromExternalFactory(a,b);if(c)return c}return f.validatorFactories[a].messageFunction(b)},isInvalid:function(a,b){return a["$$invalid"+b.name]},setInvalid:function(a,b){a["$$invalid"+b.name]=!0},setValid:function(a,b){delete a["$$invalid"+b.name]},setError:function(a,b,c){a["$$errors"+b.name]||(a["$$errors"+b.name]={}),a["$$errors"+b.name][c]=!0},clearError:function(a,b,c){a["$$errors"+b.name]&&c in a["$$errors"+b.name]&&delete a["$$errors"+b.name][c]},getErrorMessages:function(a,b){var c=[];return a["$$errors"+b.name]&&0!==Object.keys(a["$$errors"+b.name]).length?(Object.keys(a["$$errors"+b.name]).sort().forEach(function(a){c.push(f.getMessage(a,b.validators[a]))}),c):c},getFormattedErrors:function(b,c){var e="",g=f.getErrorMessages(b,c);return g.length?(g.forEach(function(a){e+=a+"
    "}),a.trustAsHtml("

    "+d.getSafeText("validate.error")+"

    "+e)):void 0},getTitleFormattedErrors:function(b,c){var e="\n",g="",h=f.getErrorMessages(b,c);return h.length?(h.forEach(function(a){g+=a+e}),a.trustAsHtml(d.getSafeText("validate.error")+e+g)):void 0},runValidators:function(a,c,d,e,g){if(d!==e){if("undefined"==typeof c.name||!c.name)throw new Error("colDef.name is required to perform validation");f.setValid(a,c);var h=function(a,b,c){return function(h){h||(f.setInvalid(a,b),f.setError(a,b,c),g&&g.api.validate.raise.validationFailed(a,b,d,e))}},i=[];for(var j in c.validators){f.clearError(a,c,j);var k=f.getValidator(j,c.validators[j]),l=b.when(k(e,d,a,c)).then(h(a,c,j));i.push(l)}return b.all(i)}},createDefaultValidators:function(){f.setValidator("minLength",function(a){return function(b,c,d,e){return void 0===c||null===c||""===c?!0:c.length>=a}},function(a){return d.getSafeText("validate.minLength").replace("THRESHOLD",a)}),f.setValidator("maxLength",function(a){return function(b,c,d,e){return void 0===c||null===c||""===c?!0:c.length<=a}},function(a){return d.getSafeText("validate.maxLength").replace("THRESHOLD",a)}),f.setValidator("required",function(a){return function(b,c,d,e){return a?!(void 0===c||null===c||""===c):!0}},function(a){return d.getSafeText("validate.required")})},initializeGrid:function(a,b){b.validate={isInvalid:f.isInvalid,getFormattedErrors:f.getFormattedErrors,getTitleFormattedErrors:f.getTitleFormattedErrors,runValidators:f.runValidators};var c={events:{validate:{validationFailed:function(a,b,c,d){}}},methods:{validate:{isInvalid:function(a,c){return b.validate.isInvalid(a,c)},getErrorMessages:function(a,c){return b.validate.getErrorMessages(a,c)},getFormattedErrors:function(a,c){return b.validate.getFormattedErrors(a,c)},getTitleFormattedErrors:function(a,c){return b.validate.getTitleFormattedErrors(a,c)}}}};b.api.registerEventsFromObject(c.events),b.api.registerMethodsFromObject(c.methods),b.edit&&b.api.edit.on.afterCellEdit(a,function(a,c,d,e){b.validate.runValidators(a,c,d,e,b)}),f.createDefaultValidators()}};return f}]),a.directive("uiGridValidate",["gridUtil","uiGridValidateService",function(a,b){return{priority:0,replace:!0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.initializeGrid(a,e.grid)},post:function(a,b,c,d){}}}}}])}(),angular.module("ui.grid").run(["$templateCache",function(a){"use strict";a.put("ui-grid/ui-grid-filter",'
     
     
    '),a.put("ui-grid/ui-grid-footer",''),a.put("ui-grid/ui-grid-grid-footer",''),a.put("ui-grid/ui-grid-group-panel",'
    • {{group.displayName}} x
    '),a.put("ui-grid/ui-grid-header",'
    '),a.put("ui-grid/ui-grid-menu-button",'
     
    '),a.put("ui-grid/ui-grid-no-header",'
    '),a.put("ui-grid/ui-grid-row","
    "),a.put("ui-grid/ui-grid",'
    '), +a.put("ui-grid/uiGridCell",'
    {{COL_FIELD CUSTOM_FILTERS}}
    '),a.put("ui-grid/uiGridColumnMenu",'
    '),a.put("ui-grid/uiGridFooterCell",'
    {{ col.getAggregationText() + ( col.getAggregationValue() CUSTOM_FILTERS ) }}
    '),a.put("ui-grid/uiGridHeaderCell",'
    {{ col.displayName CUSTOM_FILTERS }} {{col.sort.priority + 1}}
    '),a.put("ui-grid/uiGridMenu",'
    '),a.put("ui-grid/uiGridMenuItem",''),a.put("ui-grid/uiGridRenderContainer","
    "),a.put("ui-grid/uiGridViewport",'
    '),a.put("ui-grid/cellEditor",'
    '),a.put("ui-grid/dropdownEditor",'
    '),a.put("ui-grid/fileChooserEditor",'
    '),a.put("ui-grid/expandableRow",'
    '),a.put("ui-grid/expandableRowHeader",'
    '),a.put("ui-grid/expandableScrollFiller","
    "),a.put("ui-grid/expandableTopRowHeader",'
    '),a.put("ui-grid/csvLink",'LINK_LABEL'),a.put("ui-grid/importerMenuItem",'
  • '),a.put("ui-grid/importerMenuItemContainer","
    "),a.put("ui-grid/pagination",''),a.put("ui-grid/columnResizer",'
    '),a.put("ui-grid/gridFooterSelectedItems",'({{"search.selectedItems" | t}} {{grid.selection.selectedCount}})'),a.put("ui-grid/selectionHeaderCell",'
    '),a.put("ui-grid/selectionRowHeader",'
    '),a.put("ui-grid/selectionRowHeaderButtons",'
     
    '),a.put("ui-grid/selectionSelectAllButtons",'
    '),a.put("ui-grid/treeBaseExpandAllButtons",'
    '),a.put("ui-grid/treeBaseHeaderCell",'
    '),a.put("ui-grid/treeBaseRowHeader",'
    '),a.put("ui-grid/treeBaseRowHeaderButtons","
    -1 }\" ng-click=\"treeButtonClick(row, $event)\"> -1 ) || ( row.treeNode.children && row.treeNode.children.length > 0 ) ) && row.treeNode.state === 'expanded', 'ui-grid-icon-plus-squared': ( ( grid.options.showTreeExpandNoChildren && row.treeLevel > -1 ) || ( row.treeNode.children && row.treeNode.children.length > 0 ) ) && row.treeNode.state === 'collapsed'}\" ng-style=\"{'padding-left': grid.options.treeIndent * row.treeLevel + 'px'}\">  
    "),a.put("ui-grid/cellTitleValidator",'
    {{COL_FIELD CUSTOM_FILTERS}}
    '),a.put("ui-grid/cellTooltipValidator",'
    {{COL_FIELD CUSTOM_FILTERS}}
    ')}]); \ No newline at end of file diff --git a/InventoryTraker.Web/Utilities/InventoryParser.cs b/InventoryTraker.Web/Utilities/InventoryParser.cs index f80ec9f..da4850f 100644 --- a/InventoryTraker.Web/Utilities/InventoryParser.cs +++ b/InventoryTraker.Web/Utilities/InventoryParser.cs @@ -1,7 +1,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text.RegularExpressions; using CsvHelper.Configuration; +using CsvHelper.TypeConversion; using InventoryTraker.Web.Models; namespace InventoryTraker.Web.Utilities @@ -15,16 +17,28 @@ namespace InventoryTraker.Web.Utilities { public InventoryAddFormMap() { - Map(m => m.Id).Name("Box ID"); - Map(m => m.ProgramName).Name("Program Name"); - Map(m => m.ProgramSubtype).Name("Program Subtype"); - Map(m => m.Description); + Map(m => m.Id).Name("Box ID").TypeConverter(); + Map(m => m.ProgramName).Name("Program Name").TypeConverter(); + Map(m => m.ProgramSubtype).Name("Program Subtype").TypeConverter(); + Map(m => m.Description).TypeConverter(); Map(m => m.ShredReadyDate).Name("Shread Ready Date"); Map(m => m.AddedDate).Name("Added Date"); - Map(m => m.Memo); + Map(m => m.Memo).TypeConverter(); } } + private class StringNullConverter : StringConverter + { + public override object ConvertFromString(TypeConverterOptions options, string text) + { + if (string.IsNullOrEmpty(text)) return null; + if (text.StartsWith("\"") && text.EndsWith("\"")) + return base.ConvertFromString(options, Regex.Replace(text, @"^\""(.*)\""$", "$1")); + return base.ConvertFromString(options, text); + } + } + + public InventoryParser(FileSystemInfo excelFile) { _excelFile = excelFile; @@ -33,7 +47,14 @@ namespace InventoryTraker.Web.Utilities public IList Parse() { var csvConfiguration = - new CsvConfiguration { IsHeaderCaseSensitive = false, IgnoreReadingExceptions = false}; + new CsvConfiguration + { + IsHeaderCaseSensitive = false, + IgnoreReadingExceptions = false, + TrimFields = true, + SkipEmptyRecords = true, + ShouldSkipRecord = strings => strings.Take(7).All(string.IsNullOrEmpty) + }; csvConfiguration.RegisterClassMap(); using (var reader = ExcelParserBase.OpenExcel(_excelFile, csvConfiguration)) { diff --git a/InventoryTraker.Web/Utilities/InventoryReportWriter.cs b/InventoryTraker.Web/Utilities/InventoryReportWriter.cs index 6fe9259..fdd2c8d 100644 --- a/InventoryTraker.Web/Utilities/InventoryReportWriter.cs +++ b/InventoryTraker.Web/Utilities/InventoryReportWriter.cs @@ -41,6 +41,7 @@ namespace InventoryTraker.Web.Utilities var worksheet = workbook.AddWorksheet("Current Inventory"); using (var writer = new CsvWriter(new ExcelSerializer(worksheet))) { + writer.Configuration.TrimFields = true; writer.Configuration.RegisterClassMap(new InventoryViewModelMap()); writer.WriteRecords(items.OrderBy(i => i.Id)); workbook.SaveAs(stream); diff --git a/InventoryTraker.Web/Views/Shared/_Layout.cshtml b/InventoryTraker.Web/Views/Shared/_Layout.cshtml index 63074e8..9856d68 100644 --- a/InventoryTraker.Web/Views/Shared/_Layout.cshtml +++ b/InventoryTraker.Web/Views/Shared/_Layout.cshtml @@ -34,8 +34,7 @@
    -@Scripts.Render("~/js/all-javascript") -@RenderSection("Scripts", false) +@Scripts.Render("~/js/all-javascript")@RenderSection("Scripts", false) diff --git a/InventoryTraker.Web/Views/Shared/_NavigationNoAuth.cshtml b/InventoryTraker.Web/Views/Shared/_NavigationNoAuth.cshtml index de219b3..62e4a3b 100644 --- a/InventoryTraker.Web/Views/Shared/_NavigationNoAuth.cshtml +++ b/InventoryTraker.Web/Views/Shared/_NavigationNoAuth.cshtml @@ -1,6 +1,6 @@  \ No newline at end of file diff --git a/InventoryTraker.Web/js/inventory/InventoryImportDirective.js b/InventoryTraker.Web/js/inventory/InventoryImportDirective.js index cb4c9a7..cc9434e 100644 --- a/InventoryTraker.Web/js/inventory/InventoryImportDirective.js +++ b/InventoryTraker.Web/js/inventory/InventoryImportDirective.js @@ -17,24 +17,28 @@ vm.uploading = false; vm.file = ""; - vm.statusMessage = "Import inventory items below."; + vm.statusMessage = "Select your inventory excel document to import."; vm.errorMessages = []; // upload later on form submit or something similar vm.submit = function () { + console.log("vm.submit"); if (vm.form.file.$valid && vm.file) { + console.log("if (vm.form.file.$valid && vm.file)"); vm.upload(vm.file); } }; // upload on file select or drop vm.upload = function(file) { + console.log("vm.upload"); vm.uploading = true; + angular.copy([], vm.errorMessages); inventorySvc .importFile(file) .then(function(resp) { - console.log("Success " + resp.config.data.file.name + "uploaded. Response: " + resp.data); - vm.uploading = false; + console.log("Success " + resp.config.data.file.name + "uploaded. Response: " + resp.data); + vm.uploading = false; }, function (resp) { if (angular.isArray(resp.data)) diff --git a/InventoryTraker.Web/js/inventory/inventorySvc.js b/InventoryTraker.Web/js/inventory/inventorySvc.js index ea8dd79..498bbb7 100644 --- a/InventoryTraker.Web/js/inventory/inventorySvc.js +++ b/InventoryTraker.Web/js/inventory/inventorySvc.js @@ -95,10 +95,13 @@ function importFile(file) { return Upload.upload({ - url: "/api/Import", - method: 'POST', - data: { file: file} - }); + url: "/api/Import", + method: 'POST', + data: { file: file } + }) + .success(function() { + loadInventories(); + }); } function isShredReady(inventory) { diff --git a/InventoryTraker.Web/js/inventory/templates/inventoryImport.tmpl.cshtml b/InventoryTraker.Web/js/inventory/templates/inventoryImport.tmpl.cshtml index 7d52582..c2938cc 100644 --- a/InventoryTraker.Web/js/inventory/templates/inventoryImport.tmpl.cshtml +++ b/InventoryTraker.Web/js/inventory/templates/inventoryImport.tmpl.cshtml @@ -12,15 +12,21 @@ -
    Select
    - -
    {{vm.file.name}}
    +

    Download the import template: Excel template

    +
    +
    +
    Select
    +
    +
    +
    {{vm.file.name}}
    +
    +