Merge ~blr/maas:bug-1787628-node-listing into maas:master
- Git
- lp:~blr/maas
- bug-1787628-node-listing
- Merge into master
Proposed by
Kit Randel
Status: | Merged |
---|---|
Approved by: | Kit Randel |
Approved revision: | b2d861d22d18384f05af87bc24602d0eb0795d29 |
Merge reported by: | MAAS Lander |
Merged at revision: | not available |
Proposed branch: | ~blr/maas:bug-1787628-node-listing |
Merge into: | maas:master |
Diff against target: |
1415 lines (+593/-641) 11 files modified
src/maasserver/static/js/angular/3rdparty/vs-repeat.js (+580/-628) src/maasserver/static/js/bundle/vendor-min.js (+1/-1) src/maasserver/static/js/bundle/vendor-min.js.map (+1/-1) src/maasserver/static/partials/dashboard.html (+1/-1) src/maasserver/static/partials/machines-table.html (+1/-1) src/maasserver/static/partials/networks-list.html (+2/-2) src/maasserver/static/partials/node-events.html (+1/-1) src/maasserver/static/partials/nodes-list.html (+3/-3) src/maasserver/static/partials/pods-list.html (+1/-1) src/maasserver/static/partials/switches-table.html (+1/-1) src/maasserver/static/partials/zones-list.html (+1/-1) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andres Rodriguez (community) | Approve | ||
MAAS Lander | unittests | Pending | |
Review via email: mp+353376@code.launchpad.net |
Commit message
LP: #1787628 - Downgrade angular-vs-repeat to v1.1.11.
Description of the change
Unfortunately the 2.x series of angular-vs-repeat suffers from a bug (https:/
This branch reverts to the latest release on 1.x which does not have this issue.
To post a comment you must log in.
Revision history for this message
MAAS Lander (maas-lander) wrote : | # |
LANDING
-b bug-1787628-node-listing lp:~blr/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: FAILED BUILD
LOG: http://
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/src/maasserver/static/js/angular/3rdparty/vs-repeat.js b/src/maasserver/static/js/angular/3rdparty/vs-repeat.js | |||
2 | 0 | old mode 100755 | 0 | old mode 100755 |
3 | 1 | new mode 100644 | 1 | new mode 100644 |
4 | index e789333..b42a6e0 | |||
5 | --- a/src/maasserver/static/js/angular/3rdparty/vs-repeat.js | |||
6 | +++ b/src/maasserver/static/js/angular/3rdparty/vs-repeat.js | |||
7 | @@ -1,5 +1,5 @@ | |||
8 | 1 | /*! | 1 | /*! |
10 | 2 | * Angular Virtual Scroll Repeat v2.0.9 | 2 | * Angular Virtual Scroll Repeat v1.1.11 |
11 | 3 | * https://github.com/kamilkp/angular-vs-repeat/ | 3 | * https://github.com/kamilkp/angular-vs-repeat/ |
12 | 4 | * | 4 | * |
13 | 5 | * Copyright Kamil Pękala | 5 | * Copyright Kamil Pękala |
14 | @@ -8,672 +8,624 @@ | |||
15 | 8 | * Released under the MIT License | 8 | * Released under the MIT License |
16 | 9 | * https://opensource.org/licenses/MIT | 9 | * https://opensource.org/licenses/MIT |
17 | 10 | * | 10 | * |
19 | 11 | * Date: 2018/04/02 | 11 | * Date: 2018/03/09 |
20 | 12 | * | ||
21 | 12 | */ | 13 | */ |
22 | 13 | 14 | ||
133 | 14 | function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } | 15 | (function(window, angular) { |
134 | 15 | 16 | 'use strict'; | |
135 | 16 | function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } | 17 | /* jshint eqnull:true */ |
136 | 17 | 18 | /* jshint -W038 */ | |
137 | 18 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | 19 | |
138 | 19 | 20 | // DESCRIPTION: | |
139 | 20 | function _sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } | 21 | // vsRepeat directive stands for Virtual Scroll Repeat. It turns a standard ngRepeated set of elements in a scrollable container |
140 | 21 | 22 | // into a component, where the user thinks he has all the elements rendered and all he needs to do is scroll (without any kind of | |
141 | 22 | function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return _sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } } | 23 | // pagination - which most users loath) and at the same time the browser isn't overloaded by that many elements/angular bindings etc. |
142 | 23 | 24 | // The directive renders only so many elements that can fit into current container's clientHeight/clientWidth. | |
143 | 24 | /* global console, setTimeout, module */ | 25 | |
144 | 25 | (function (window, angular) { | 26 | // LIMITATIONS: |
145 | 26 | /** | 27 | // - current version only supports an Array as a right-hand-side object for ngRepeat |
146 | 27 | * DESCRIPTION: | 28 | // - all rendered elements must have the same height/width or the sizes of the elements must be known up front |
147 | 28 | * vsRepeat directive stands for Virtual Scroll Repeat. It turns a standard ngRepeated set of elements in a scrollable container | 29 | |
148 | 29 | * into a component, where the user thinks he has all the elements rendered and all he needs to do is scroll (without any kind of | 30 | // USAGE: |
149 | 30 | * pagination - which most users loath) and at the same time the browser isn't overloaded by that many elements/angular bindings etc. | 31 | // In order to use the vsRepeat directive you need to place a vs-repeat attribute on a direct parent of an element with ng-repeat |
150 | 31 | * The directive renders only so many elements that can fit into current container's clientHeight/clientWidth. | 32 | // example: |
151 | 32 | * LIMITATIONS: | 33 | // <div vs-repeat> |
152 | 33 | * - current version only supports an Array as a right-hand-side object for ngRepeat | 34 | // <div ng-repeat="item in someArray"> |
153 | 34 | * - all rendered elements must have the same height/width or the sizes of the elements must be known up front | 35 | // <!-- content --> |
154 | 35 | * USAGE: | 36 | // </div> |
155 | 36 | * In order to use the vsRepeat directive you need to place a vs-repeat attribute on a direct parent of an element with ng-repeat | 37 | // </div> |
156 | 37 | * example: | 38 | // |
157 | 38 | * <div vs-repeat="options"> | 39 | // or: |
158 | 39 | * <div ng-repeat="item in someArray"> | 40 | // <div vs-repeat> |
159 | 40 | * <!-- content --> | 41 | // <div ng-repeat-start="item in someArray"> |
160 | 41 | * </div> | 42 | // <!-- content --> |
161 | 42 | * </div> | 43 | // </div> |
162 | 43 | * or: | 44 | // <div> |
163 | 44 | * <div vs-repeat="options"> | 45 | // <!-- something in the middle --> |
164 | 45 | * <div ng-repeat-start="item in someArray"> | 46 | // </div> |
165 | 46 | * <!-- content --> | 47 | // <div ng-repeat-end> |
166 | 47 | * </div> | 48 | // <!-- content --> |
167 | 48 | * <div> | 49 | // </div> |
168 | 49 | * <!-- something in the middle --> | 50 | // </div> |
169 | 50 | * </div> | 51 | // |
170 | 51 | * <div ng-repeat-end> | 52 | // You can also measure the single element's height/width (including all paddings and margins), and then speficy it as a value |
171 | 52 | * <!-- content --> | 53 | // of the attribute 'vs-repeat'. This can be used if one wants to override the automatically computed element size. |
172 | 53 | * </div> | 54 | // example: |
173 | 54 | * </div> | 55 | // <div vs-repeat="50"> <!-- the specified element height is 50px --> |
174 | 55 | * You can also measure the single element's height/width (including all paddings and margins), and then speficy it as a value | 56 | // <div ng-repeat="item in someArray"> |
175 | 56 | * of the option's `size` property. This can be used if one wants to override the automatically computed element size. | 57 | // <!-- content --> |
176 | 57 | * example: | 58 | // </div> |
177 | 58 | * <div vs-repeat="{size: 50}"> <!-- the specified element height is 50px --> | 59 | // </div> |
178 | 59 | * <div ng-repeat="item in someArray"> | 60 | // |
179 | 60 | * <!-- content --> | 61 | // IMPORTANT! |
180 | 61 | * </div> | 62 | // |
181 | 62 | * </div> | 63 | // - the vsRepeat directive must be applied to a direct parent of an element with ngRepeat |
182 | 63 | * IMPORTANT! | 64 | // - the value of vsRepeat attribute is the single element's height/width measured in pixels. If none provided, the directive |
183 | 64 | * - the vsRepeat directive must be applied to a direct parent of an element with ngRepeat | 65 | // will compute it automatically |
184 | 65 | * - the value of vsRepeat attribute is the single element's height/width measured in pixels. If none provided, the directive | 66 | |
185 | 66 | * will compute it automatically | 67 | // OPTIONAL PARAMETERS (attributes): |
186 | 67 | * OPTIONAL PARAMETERS (attributes): | 68 | // vs-repeat-container="selector" - selector for element containing ng-repeat. (defaults to the current element) |
187 | 68 | * vs-repeat-container="selector" - selector for element containing ng-repeat. (defaults to the current element) | 69 | // vs-scroll-parent="selector" - selector to the scrollable container. The directive will look for a closest parent matching |
188 | 69 | * OPTIONS: | 70 | // the given selector (defaults to the current element) |
189 | 70 | * Options shall be passed as an object to the `vs-repeat` attribute e.g.: `<div vs-repeat="{scrollParent: 'window', size: 20}"></div>` | 71 | // vs-horizontal - stack repeated elements horizontally instead of vertically |
190 | 71 | * | 72 | // vs-offset-before="value" - top/left offset in pixels (defaults to 0) |
191 | 72 | * Available options: | 73 | // vs-offset-after="value" - bottom/right offset in pixels (defaults to 0) |
192 | 73 | * `horizontal` - stack repeated elements horizontally instead of vertically | 74 | // vs-excess="value" - an integer number representing the number of elements to be rendered outside of the current container's viewport |
193 | 74 | * `offset-before` - top/left offset in pixels (defaults to 0) | 75 | // (defaults to 2) |
194 | 75 | * `offset-after` - bottom/right offset in pixels (defaults to 0) | 76 | // vs-size - a property name of the items in collection that is a number denoting the element size (in pixels) |
195 | 76 | * `scroll-margin` - how many pixels ahead should elements be rendered while scrolling | 77 | // vs-autoresize - use this attribute without vs-size and without specifying element's size. The automatically computed element style will |
196 | 77 | * `latch` - if true, elements will be rendered gradually but won't be removed when scrolled away (defaults to false) | 78 | // readjust upon window resize if the size is dependable on the viewport size |
197 | 78 | * `size` - a property name of the items in collection that is a number denoting the element size (in pixels) | 79 | // vs-scrolled-to-end="callback" - callback will be called when the last item of the list is rendered |
198 | 79 | * `autoresize` - use this attribute without vs-size and without specifying element's size. The automatically computed element style will | 80 | // vs-scrolled-to-end-offset="integer" - set this number to trigger the scrolledToEnd callback n items before the last gets rendered |
199 | 80 | * readjust upon window resize if the size is dependable on the viewport size | 81 | // vs-scrolled-to-beginning="callback" - callback will be called when the first item of the list is rendered |
200 | 81 | * `scrolled-to-end` - callback will be called when the last item of the list is rendered | 82 | // vs-scrolled-to-beginning-offset="integer" - set this number to trigger the scrolledToBeginning callback n items before the first gets rendered |
201 | 82 | * `scrolled-to-end-offset` - set this number to trigger the scrolledToEnd callback n items before the last gets rendered | 83 | |
202 | 83 | * `scrolled-to-beginning` - callback will be called when the first item of the list is rendered | 84 | // EVENTS: |
203 | 84 | * `scrolled-to-beginning-offset` - set this number to trigger the scrolledToBeginning callback n items before the first gets rendered | 85 | // - 'vsRepeatTrigger' - an event the directive listens for to manually trigger reinitialization |
204 | 85 | * EVENTS: | 86 | // - 'vsRepeatReinitialized' - an event the directive emits upon reinitialization done |
205 | 86 | * - `vsRepeatTrigger` - an event the directive listens for to manually trigger reinitialization | 87 | |
206 | 87 | * - `vsRepeatReinitialized` - an event the directive emits upon reinitialization done | 88 | var dde = document.documentElement, |
207 | 88 | */ | 89 | matchingFunction = dde.matches ? 'matches' : |
208 | 89 | var closestElement = angular.element.prototype.closest; | 90 | dde.matchesSelector ? 'matchesSelector' : |
209 | 90 | 91 | dde.webkitMatches ? 'webkitMatches' : | |
210 | 91 | if (!closestElement) { | 92 | dde.webkitMatchesSelector ? 'webkitMatchesSelector' : |
211 | 92 | var matchingFunction = ['matches', 'matchesSelector', 'webkitMatches', 'webkitMatchesSelector', 'msMatches', 'msMatchesSelector', 'mozMatches', 'mozMatchesSelector'].reduce(function (res, prop) { | 93 | dde.msMatches ? 'msMatches' : |
212 | 93 | var _res; | 94 | dde.msMatchesSelector ? 'msMatchesSelector' : |
213 | 94 | 95 | dde.mozMatches ? 'mozMatches' : | |
214 | 95 | return (_res = res) !== null && _res !== void 0 ? _res : prop in document.documentElement ? prop : null; | 96 | dde.mozMatchesSelector ? 'mozMatchesSelector' : null; |
215 | 96 | }, null); | 97 | |
216 | 97 | 98 | var closestElement = angular.element.prototype.closest || function (selector) { | |
217 | 98 | closestElement = function closestElement(selector) { | 99 | var el = this[0].parentNode; |
218 | 99 | var _el; | 100 | while (el !== document.documentElement && el != null && !el[matchingFunction](selector)) { |
219 | 100 | 101 | el = el.parentNode; | |
220 | 101 | var el = this[0].parentNode; | 102 | } |
111 | 102 | |||
112 | 103 | while (el !== document.documentElement && el != null && !el[matchingFunction](selector)) { | ||
113 | 104 | el = el.parentNode; | ||
114 | 105 | } | ||
115 | 106 | |||
116 | 107 | if ((_el = el) === null || _el === void 0 ? void 0 : _el[matchingFunction](selector)) { | ||
117 | 108 | return angular.element(el); | ||
118 | 109 | } | ||
119 | 110 | |||
120 | 111 | return angular.element(); | ||
121 | 112 | }; | ||
122 | 113 | } | ||
123 | 114 | |||
124 | 115 | function getWindowScroll() { | ||
125 | 116 | var _ref, _document$documentEle, _ref2, _document$documentEle2; | ||
126 | 117 | |||
127 | 118 | if ('pageYOffset' in window) { | ||
128 | 119 | return { | ||
129 | 120 | scrollTop: window.pageYOffset, | ||
130 | 121 | scrollLeft: window.pageXOffset | ||
131 | 122 | }; | ||
132 | 123 | } | ||
221 | 124 | 103 | ||
225 | 125 | return { | 104 | if (el && el[matchingFunction](selector)) { |
226 | 126 | scrollTop: (_ref = (_document$documentEle = document.documentElement.scrollTop) !== null && _document$documentEle !== void 0 ? _document$documentEle : document.body.scrollTop) !== null && _ref !== void 0 ? _ref : 0, | 105 | return angular.element(el); |
227 | 127 | scrollLeft: (_ref2 = (_document$documentEle2 = document.documentElement.scrollLeft) !== null && _document$documentEle2 !== void 0 ? _document$documentEle2 : document.body.scrollLeft) !== null && _ref2 !== void 0 ? _ref2 : 0 | 106 | } |
228 | 107 | else { | ||
229 | 108 | return angular.element(); | ||
230 | 109 | } | ||
231 | 128 | }; | 110 | }; |
232 | 129 | } | ||
233 | 130 | 111 | ||
237 | 131 | function getClientSize(element, sizeProp) { | 112 | function getWindowScroll() { |
238 | 132 | if (element === window) { | 113 | if ('pageYOffset' in window) { |
239 | 133 | return sizeProp === 'clientWidth' ? window.innerWidth : window.innerHeight; | 114 | return { |
240 | 115 | scrollTop: pageYOffset, | ||
241 | 116 | scrollLeft: pageXOffset | ||
242 | 117 | }; | ||
243 | 118 | } | ||
244 | 119 | else { | ||
245 | 120 | var sx, sy, d = document, r = d.documentElement, b = d.body; | ||
246 | 121 | sx = r.scrollLeft || b.scrollLeft || 0; | ||
247 | 122 | sy = r.scrollTop || b.scrollTop || 0; | ||
248 | 123 | return { | ||
249 | 124 | scrollTop: sy, | ||
250 | 125 | scrollLeft: sx | ||
251 | 126 | }; | ||
252 | 127 | } | ||
253 | 134 | } | 128 | } |
254 | 135 | 129 | ||
268 | 136 | return element[sizeProp]; | 130 | function getClientSize(element, sizeProp) { |
269 | 137 | } | 131 | if (element === window) { |
270 | 138 | 132 | return sizeProp === 'clientWidth' ? window.innerWidth : window.innerHeight; | |
271 | 139 | function getScrollPos(element, scrollProp) { | 133 | } |
272 | 140 | return element === window ? getWindowScroll()[scrollProp] : element[scrollProp]; | 134 | else { |
273 | 141 | } | 135 | return element[sizeProp]; |
274 | 142 | 136 | } | |
275 | 143 | function getScrollOffset(vsElement, scrollElement, isHorizontal) { | 137 | } |
263 | 144 | var vsPos = vsElement.getBoundingClientRect()[isHorizontal ? 'left' : 'top']; | ||
264 | 145 | var scrollPos = scrollElement === window ? 0 : scrollElement.getBoundingClientRect()[isHorizontal ? 'left' : 'top']; | ||
265 | 146 | var scrollValue = (scrollElement === window ? getWindowScroll() : scrollElement)[isHorizontal ? 'scrollLeft' : 'scrollTop']; | ||
266 | 147 | return vsPos - scrollPos + scrollValue; | ||
267 | 148 | } | ||
276 | 149 | 138 | ||
279 | 150 | function analyzeNgRepeatUsage(element) { | 139 | function getScrollPos(element, scrollProp) { |
280 | 151 | var options = ['ng-repeat', 'data-ng-repeat', 'ng-repeat-start', 'data-ng-repeat-start']; | 140 | return element === window ? getWindowScroll()[scrollProp] : element[scrollProp]; |
281 | 141 | } | ||
282 | 152 | 142 | ||
285 | 153 | for (var _i = 0; _i < options.length; _i++) { | 143 | function getScrollOffset(vsElement, scrollElement, isHorizontal) { |
286 | 154 | var opt = options[_i]; | 144 | var vsPos = vsElement.getBoundingClientRect()[isHorizontal ? 'left' : 'top']; |
287 | 145 | var scrollPos = scrollElement === window ? 0 : scrollElement.getBoundingClientRect()[isHorizontal ? 'left' : 'top']; | ||
288 | 146 | var correction = vsPos - scrollPos + | ||
289 | 147 | (scrollElement === window ? getWindowScroll() : scrollElement)[isHorizontal ? 'scrollLeft' : 'scrollTop']; | ||
290 | 155 | 148 | ||
294 | 156 | if (element.attr(opt)) { | 149 | return correction; |
292 | 157 | return [opt, element.attr(opt), opt.indexOf('-start') >= 0]; | ||
293 | 158 | } | ||
295 | 159 | } | 150 | } |
296 | 160 | 151 | ||
367 | 161 | throw new Error('angular-vs-repeat: no ng-repeat directive on a child element'); | 152 | var vsRepeatModule = angular.module('vs-repeat', []).directive('vsRepeat', ['$compile', '$parse', function($compile, $parse) { |
298 | 162 | } | ||
299 | 163 | |||
300 | 164 | function printDeprecationWarning($element, message) { | ||
301 | 165 | console.warn("vs-repeat deprecation: ".concat(message), $element[0]); | ||
302 | 166 | } | ||
303 | 167 | |||
304 | 168 | function attrDeprecated(attrname, $element) { | ||
305 | 169 | printDeprecationWarning($element, "".concat(attrname, " attribute is deprecated. Pass the options object to vs-repeat attribute instead https://github.com/kamilkp/angular-vs-repeat#options")); | ||
306 | 170 | } | ||
307 | 171 | |||
308 | 172 | var defaultOptions = { | ||
309 | 173 | latch: false, | ||
310 | 174 | container: null, | ||
311 | 175 | scrollParent: null, | ||
312 | 176 | size: null, | ||
313 | 177 | offsetBefore: 0, | ||
314 | 178 | offsetAfter: 0, | ||
315 | 179 | scrolledToBeginning: angular.noop, | ||
316 | 180 | scrolledToEnd: angular.noop, | ||
317 | 181 | scrolledToBeginningOffset: 0, | ||
318 | 182 | scrolledToEndOffset: 0, | ||
319 | 183 | scrollMargin: 0, | ||
320 | 184 | horizontal: false, | ||
321 | 185 | autoresize: false, | ||
322 | 186 | hunked: false, | ||
323 | 187 | hunkSize: 0 | ||
324 | 188 | }; | ||
325 | 189 | var vsRepeatModule = angular.module('vs-repeat', []).directive('vsRepeat', ['$compile', '$parse', function ($compile, $parse) { | ||
326 | 190 | return { | ||
327 | 191 | restrict: 'A', | ||
328 | 192 | scope: true, | ||
329 | 193 | compile: function compile(compileElement, compileAttrs) { | ||
330 | 194 | var compileRepeatContainer = 'vsRepeatContainer' in compileAttrs ? angular.element(compileElement[0].querySelector(compileAttrs.vsRepeatContainer)) : compileElement; | ||
331 | 195 | var repeatContainerChildren = compileRepeatContainer.children(); | ||
332 | 196 | var ngRepeatChild = repeatContainerChildren.eq(0); | ||
333 | 197 | var childCloneHtml = ngRepeatChild[0].outerHTML; | ||
334 | 198 | var collectionName = '$vs_collection'; // TODO: make configurable? | ||
335 | 199 | |||
336 | 200 | ['vsSize', 'vsScrollParent', 'vsSizeProperty', 'vsHorizontal', 'vsOffsetBefore', 'vsOffsetAfter', 'vsScrolledToEndOffset', 'vsScrolledToBeginningOffset', 'vsExcess', 'vsScrollMargin'].forEach(function (attrname) { | ||
337 | 201 | if (attrname in compileAttrs) { | ||
338 | 202 | attrDeprecated(attrname, compileElement); | ||
339 | 203 | } | ||
340 | 204 | }); | ||
341 | 205 | |||
342 | 206 | var _analyzeNgRepeatUsage = analyzeNgRepeatUsage(ngRepeatChild), | ||
343 | 207 | _analyzeNgRepeatUsage2 = _slicedToArray(_analyzeNgRepeatUsage, 3), | ||
344 | 208 | originalNgRepeatAttr = _analyzeNgRepeatUsage2[0], | ||
345 | 209 | ngRepeatExpression = _analyzeNgRepeatUsage2[1], | ||
346 | 210 | isNgRepeatStart = _analyzeNgRepeatUsage2[2]; | ||
347 | 211 | |||
348 | 212 | var expressionMatches = /^\s*(\S+)\s+in\s+([\S\s]+?)(track\s+by\s+\S+)?$/.exec(ngRepeatExpression); | ||
349 | 213 | |||
350 | 214 | var _expressionMatches = _slicedToArray(expressionMatches, 4), | ||
351 | 215 | lhs = _expressionMatches[1], | ||
352 | 216 | rhs = _expressionMatches[2], | ||
353 | 217 | rhsSuffix = _expressionMatches[3]; | ||
354 | 218 | |||
355 | 219 | if (isNgRepeatStart) { | ||
356 | 220 | var index = 0; | ||
357 | 221 | var repeaterElement = repeatContainerChildren.eq(index); | ||
358 | 222 | |||
359 | 223 | while (repeaterElement.attr('ng-repeat-end') == null && repeaterElement.attr('data-ng-repeat-end') == null) { | ||
360 | 224 | index++; | ||
361 | 225 | repeaterElement = repeatContainerChildren.eq(index); | ||
362 | 226 | childCloneHtml += repeaterElement[0].outerHTML; | ||
363 | 227 | } | ||
364 | 228 | } | ||
365 | 229 | |||
366 | 230 | compileRepeatContainer.empty(); | ||
368 | 231 | return { | 153 | return { |
445 | 232 | pre: function pre($scope, $element, $attrs) { | 154 | restrict: 'A', |
446 | 233 | var _$scope$$eval; | 155 | scope: true, |
447 | 234 | 156 | compile: function($element, $attrs) { | |
448 | 235 | function _parseSize(options) { | 157 | var repeatContainer = angular.isDefined($attrs.vsRepeatContainer) ? angular.element($element[0].querySelector($attrs.vsRepeatContainer)) : $element, |
449 | 236 | if (typeof options.size === 'number') { | 158 | ngRepeatChild = repeatContainer.children().eq(0), |
450 | 237 | options.getSize = function () { | 159 | ngRepeatExpression, |
451 | 238 | return options.size; | 160 | childCloneHtml = ngRepeatChild[0].outerHTML, |
452 | 239 | }; | 161 | expressionMatches, |
453 | 240 | } else { | 162 | lhs, |
454 | 241 | var parsed = $parse(String(options.size)); | 163 | rhs, |
455 | 242 | 164 | rhsSuffix, | |
456 | 243 | options.getSize = function (item) { | 165 | originalNgRepeatAttr, |
457 | 244 | return parsed($scope, _defineProperty({}, lhs, item)); | 166 | collectionName = '$vs_collection', |
458 | 245 | }; | 167 | isNgRepeatStart = false, |
459 | 246 | } | 168 | attributesDictionary = { |
460 | 247 | } | 169 | 'vsRepeat': 'elementSize', |
461 | 248 | 170 | 'vsOffsetBefore': 'offsetBefore', | |
462 | 249 | $scope.vsRepeat = { | 171 | 'vsOffsetAfter': 'offsetAfter', |
463 | 250 | options: _extends({}, defaultOptions, (_$scope$$eval = $scope.$eval($attrs.vsRepeat)) !== null && _$scope$$eval !== void 0 ? _$scope$$eval : {}) | 172 | 'vsScrolledToEndOffset': 'scrolledToEndOffset', |
464 | 251 | }; | 173 | 'vsScrolledToBeginningOffset': 'scrolledToBeginningOffset', |
465 | 252 | var options = $scope.vsRepeat.options; | 174 | 'vsExcess': 'excess', |
466 | 253 | 175 | 'vsScrollMargin': 'scrollMargin' | |
467 | 254 | _parseSize(options); | 176 | }; |
468 | 255 | 177 | ||
469 | 256 | var repeatContainer = angular.isDefined($attrs.vsRepeatContainer) ? angular.element($element[0].querySelector($attrs.vsRepeatContainer)) : $element; | 178 | if (ngRepeatChild.attr('ng-repeat')) { |
470 | 257 | var childClone = angular.element(childCloneHtml); | 179 | originalNgRepeatAttr = 'ng-repeat'; |
471 | 258 | var childTagName = childClone[0].tagName.toLowerCase(); | 180 | ngRepeatExpression = ngRepeatChild.attr('ng-repeat'); |
396 | 259 | var originalCollection = []; | ||
397 | 260 | var originalLength; | ||
398 | 261 | var $beforeContent = angular.element('<' + childTagName + ' class="vs-repeat-before-content"></' + childTagName + '>'); | ||
399 | 262 | var $afterContent = angular.element('<' + childTagName + ' class="vs-repeat-after-content"></' + childTagName + '>'); | ||
400 | 263 | var autosizingRequired = options.size === null; | ||
401 | 264 | var $scrollParent = options.scrollParent ? options.scrollParent === 'window' ? angular.element(window) : closestElement.call(repeatContainer, options.scrollParent) : repeatContainer; | ||
402 | 265 | var clientSize = options.horizontal ? 'clientWidth' : 'clientHeight'; | ||
403 | 266 | var offsetSize = options.horizontal ? 'offsetWidth' : 'offsetHeight'; | ||
404 | 267 | var scrollSize = options.horizontal ? 'scrollWidth' : 'scrollHeight'; | ||
405 | 268 | var scrollPos = options.horizontal ? 'scrollLeft' : 'scrollTop'; | ||
406 | 269 | $scope.vsRepeat.totalSize = 0; | ||
407 | 270 | |||
408 | 271 | if ($scrollParent.length === 0) { | ||
409 | 272 | throw 'Specified scroll parent selector did not match any element'; | ||
410 | 273 | } | ||
411 | 274 | |||
412 | 275 | $scope.vsRepeat.$scrollParent = $scrollParent; | ||
413 | 276 | $scope.vsRepeat.sizesCumulative = []; | ||
414 | 277 | |||
415 | 278 | if (options.debug) { | ||
416 | 279 | var $debugParent = options.scrollParent === 'window' ? angular.element(document.body) : $scrollParent; | ||
417 | 280 | var $debug = angular.element('<div class="vs-repeat-debug-element"></div>'); | ||
418 | 281 | $debug.css('position', options.scrollParent === 'window' ? 'fixed' : 'absolute'); | ||
419 | 282 | $debugParent.append($debug); | ||
420 | 283 | $scope.$on('$destroy', function () { | ||
421 | 284 | $debug.remove(); | ||
422 | 285 | }); | ||
423 | 286 | } | ||
424 | 287 | |||
425 | 288 | var measuredSize = getClientSize($scrollParent[0], clientSize) || 50; | ||
426 | 289 | |||
427 | 290 | if (options.horizontal) { | ||
428 | 291 | $beforeContent.css('height', '100%'); | ||
429 | 292 | $afterContent.css('height', '100%'); | ||
430 | 293 | } else { | ||
431 | 294 | $beforeContent.css('width', '100%'); | ||
432 | 295 | $afterContent.css('width', '100%'); | ||
433 | 296 | } | ||
434 | 297 | |||
435 | 298 | if ($attrs.vsRepeatOptions) { | ||
436 | 299 | $scope.$watchCollection($attrs.vsRepeatOptions, function (newOpts) { | ||
437 | 300 | var mergedOptions = _extends({}, options, newOpts); | ||
438 | 301 | |||
439 | 302 | if (JSON.stringify(mergedOptions) !== JSON.stringify(options)) { | ||
440 | 303 | Object.assign(options, newOpts); | ||
441 | 304 | |||
442 | 305 | _parseSize(options); | ||
443 | 306 | |||
444 | 307 | reinitialize(); | ||
472 | 308 | } | 181 | } |
597 | 309 | }); | 182 | else if (ngRepeatChild.attr('data-ng-repeat')) { |
598 | 310 | } | 183 | originalNgRepeatAttr = 'data-ng-repeat'; |
599 | 311 | 184 | ngRepeatExpression = ngRepeatChild.attr('data-ng-repeat'); | |
476 | 312 | $scope.$watchCollection(rhs, function () { | ||
477 | 313 | var coll = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; | ||
478 | 314 | originalCollection = coll; | ||
479 | 315 | refresh(); | ||
480 | 316 | }); | ||
481 | 317 | |||
482 | 318 | function refresh() { | ||
483 | 319 | if (!originalCollection || originalCollection.length < 1) { | ||
484 | 320 | $scope[collectionName] = []; | ||
485 | 321 | originalLength = 0; | ||
486 | 322 | $scope.vsRepeat.sizesCumulative = [0]; | ||
487 | 323 | } else { | ||
488 | 324 | originalLength = originalCollection.length; | ||
489 | 325 | |||
490 | 326 | if (options.size) { | ||
491 | 327 | _mapSize(); | ||
492 | 328 | } else { | ||
493 | 329 | getFromMeasured(); | ||
494 | 330 | } | ||
495 | 331 | } | ||
496 | 332 | |||
497 | 333 | reinitialize(); | ||
498 | 334 | } | ||
499 | 335 | |||
500 | 336 | function _mapSize() { | ||
501 | 337 | var hardSize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; | ||
502 | 338 | var sizes = originalCollection.map(function (item) { | ||
503 | 339 | var _hardSize; | ||
504 | 340 | |||
505 | 341 | return (_hardSize = hardSize) !== null && _hardSize !== void 0 ? _hardSize : options.getSize(item); | ||
506 | 342 | }); | ||
507 | 343 | var sum = 0; | ||
508 | 344 | $scope.vsRepeat.sizesCumulative = [0].concat(_toConsumableArray(sizes.map(function (size) { | ||
509 | 345 | return sum += size; | ||
510 | 346 | }))); | ||
511 | 347 | } | ||
512 | 348 | |||
513 | 349 | function getFromMeasured() { | ||
514 | 350 | if (autosizingRequired) { | ||
515 | 351 | $scope.$$postDigest(function () { | ||
516 | 352 | if (repeatContainer[0].offsetHeight || repeatContainer[0].offsetWidth) { | ||
517 | 353 | // element is visible | ||
518 | 354 | var children = repeatContainer.children(); | ||
519 | 355 | var i = 0; | ||
520 | 356 | var gotSomething = false; | ||
521 | 357 | var insideStartEndSequence = false; | ||
522 | 358 | |||
523 | 359 | while (i < children.length) { | ||
524 | 360 | if (children[i].attributes[originalNgRepeatAttr] != null || insideStartEndSequence) { | ||
525 | 361 | if (!gotSomething) { | ||
526 | 362 | measuredSize = 0; | ||
527 | 363 | } | ||
528 | 364 | |||
529 | 365 | gotSomething = true; | ||
530 | 366 | |||
531 | 367 | if (children[i][offsetSize]) { | ||
532 | 368 | measuredSize += children[i][offsetSize]; | ||
533 | 369 | } | ||
534 | 370 | |||
535 | 371 | if (isNgRepeatStart) { | ||
536 | 372 | if (children[i].attributes['ng-repeat-end'] != null || children[i].attributes['data-ng-repeat-end'] != null) { | ||
537 | 373 | break; | ||
538 | 374 | } else { | ||
539 | 375 | insideStartEndSequence = true; | ||
540 | 376 | } | ||
541 | 377 | } else { | ||
542 | 378 | break; | ||
543 | 379 | } | ||
544 | 380 | } | ||
545 | 381 | |||
546 | 382 | i++; | ||
547 | 383 | } | ||
548 | 384 | |||
549 | 385 | if (gotSomething) { | ||
550 | 386 | _mapSize(measuredSize); | ||
551 | 387 | |||
552 | 388 | reinitialize(); | ||
553 | 389 | autosizingRequired = false; | ||
554 | 390 | |||
555 | 391 | if ($scope.$root && !$scope.$root.$$phase) { | ||
556 | 392 | $scope.$digest(); | ||
557 | 393 | } | ||
558 | 394 | } | ||
559 | 395 | } else { | ||
560 | 396 | var dereg = $scope.$watch(function () { | ||
561 | 397 | if (repeatContainer[0].offsetHeight || repeatContainer[0].offsetWidth) { | ||
562 | 398 | dereg(); | ||
563 | 399 | getFromMeasured(); | ||
564 | 400 | } | ||
565 | 401 | }); | ||
566 | 402 | } | ||
567 | 403 | }); | ||
568 | 404 | } else { | ||
569 | 405 | _mapSize(measuredSize); | ||
570 | 406 | } | ||
571 | 407 | } | ||
572 | 408 | |||
573 | 409 | function getLayoutProps(value) { | ||
574 | 410 | var layoutProp = options.horizontal ? 'width' : 'height'; | ||
575 | 411 | return ['', 'min-', 'max-'].reduce(function (acc, prop) { | ||
576 | 412 | return acc["".concat(prop).concat(layoutProp)] = value, acc; | ||
577 | 413 | }, {}); | ||
578 | 414 | } | ||
579 | 415 | |||
580 | 416 | childClone.eq(0).attr(originalNgRepeatAttr, lhs + ' in ' + collectionName + (rhsSuffix ? ' ' + rhsSuffix : '')); | ||
581 | 417 | childClone.addClass('vs-repeat-repeated-element'); | ||
582 | 418 | repeatContainer.append($beforeContent); | ||
583 | 419 | repeatContainer.append(childClone); | ||
584 | 420 | $compile(childClone)($scope); | ||
585 | 421 | repeatContainer.append($afterContent); | ||
586 | 422 | $scope.vsRepeat.startIndex = 0; | ||
587 | 423 | $scope.vsRepeat.endIndex = 0; | ||
588 | 424 | |||
589 | 425 | function scrollHandler() { | ||
590 | 426 | var pos = $scrollParent[0][scrollPos]; | ||
591 | 427 | |||
592 | 428 | if (updateInnerCollection()) { | ||
593 | 429 | $scope.$digest(); | ||
594 | 430 | |||
595 | 431 | if (options._ensureScrollIntegrity) { | ||
596 | 432 | $scrollParent[0][scrollPos] = pos; | ||
600 | 433 | } | 185 | } |
613 | 434 | } | 186 | else if (ngRepeatChild.attr('ng-repeat-start')) { |
614 | 435 | } | 187 | isNgRepeatStart = true; |
615 | 436 | 188 | originalNgRepeatAttr = 'ng-repeat-start'; | |
616 | 437 | $scrollParent.on('scroll', scrollHandler); | 189 | ngRepeatExpression = ngRepeatChild.attr('ng-repeat-start'); |
605 | 438 | |||
606 | 439 | function onWindowResize() { | ||
607 | 440 | if (options.autoresize) { | ||
608 | 441 | autosizingRequired = true; | ||
609 | 442 | getFromMeasured(); | ||
610 | 443 | |||
611 | 444 | if ($scope.$root && !$scope.$root.$$phase) { | ||
612 | 445 | $scope.$digest(); | ||
617 | 446 | } | 190 | } |
661 | 447 | } | 191 | else if (ngRepeatChild.attr('data-ng-repeat-start')) { |
662 | 448 | 192 | isNgRepeatStart = true; | |
663 | 449 | if (updateInnerCollection()) { | 193 | originalNgRepeatAttr = 'data-ng-repeat-start'; |
664 | 450 | $scope.$digest(); | 194 | ngRepeatExpression = ngRepeatChild.attr('data-ng-repeat-start'); |
622 | 451 | } | ||
623 | 452 | } | ||
624 | 453 | |||
625 | 454 | angular.element(window).on('resize', onWindowResize); | ||
626 | 455 | $scope.$on('$destroy', function () { | ||
627 | 456 | angular.element(window).off('resize', onWindowResize); | ||
628 | 457 | $scrollParent.off('scroll', scrollHandler); | ||
629 | 458 | }); | ||
630 | 459 | $scope.$on('vsRepeatTrigger', refresh); | ||
631 | 460 | $scope.$on('vsRepeatResize', function () { | ||
632 | 461 | autosizingRequired = true; | ||
633 | 462 | getFromMeasured(); | ||
634 | 463 | }); | ||
635 | 464 | |||
636 | 465 | var _prevStartIndex, _prevEndIndex, _minStartIndex, _maxEndIndex; | ||
637 | 466 | |||
638 | 467 | $scope.$on('vsRenderAll', function () { | ||
639 | 468 | if (!options.latch) { | ||
640 | 469 | return; | ||
641 | 470 | } | ||
642 | 471 | |||
643 | 472 | if ($scope.vsRepeat.endIndex === originalLength) { | ||
644 | 473 | $scope.$emit('vsRenderAllDone'); | ||
645 | 474 | return; | ||
646 | 475 | } | ||
647 | 476 | |||
648 | 477 | setTimeout(function () { | ||
649 | 478 | // var __endIndex = Math.min($scope.vsRepeat.endIndex + (quantum || 1), originalLength); | ||
650 | 479 | var __endIndex = originalLength; | ||
651 | 480 | _maxEndIndex = Math.max(__endIndex, _maxEndIndex); | ||
652 | 481 | $scope.vsRepeat.endIndex = options.latch ? _maxEndIndex : __endIndex; | ||
653 | 482 | $scope[collectionName] = originalCollection.slice($scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex); | ||
654 | 483 | _prevEndIndex = $scope.vsRepeat.endIndex; | ||
655 | 484 | $beforeContent.css(getLayoutProps(0)); | ||
656 | 485 | $afterContent.css(getLayoutProps(0)); | ||
657 | 486 | $scope.$emit('vsRenderAllDone'); | ||
658 | 487 | |||
659 | 488 | if ($scope.$root && !$scope.$root.$$phase) { | ||
660 | 489 | $scope.$digest(); | ||
665 | 490 | } | 195 | } |
693 | 491 | }); | 196 | else { |
694 | 492 | }); | 197 | throw new Error('angular-vs-repeat: no ng-repeat directive on a child element'); |
668 | 493 | |||
669 | 494 | function reinitialize() { | ||
670 | 495 | _prevStartIndex = void 0; | ||
671 | 496 | _prevEndIndex = void 0; | ||
672 | 497 | _minStartIndex = originalLength; | ||
673 | 498 | _maxEndIndex = 0; | ||
674 | 499 | updateTotalSize($scope.vsRepeat.sizesCumulative[originalLength]); | ||
675 | 500 | updateInnerCollection(); | ||
676 | 501 | $scope.$emit('vsRepeatReinitialized', $scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex); | ||
677 | 502 | } | ||
678 | 503 | |||
679 | 504 | function updateTotalSize(size) { | ||
680 | 505 | $scope.vsRepeat.totalSize = options.offsetBefore + size + options.offsetAfter; | ||
681 | 506 | } | ||
682 | 507 | |||
683 | 508 | var _prevClientSize; | ||
684 | 509 | |||
685 | 510 | function reinitOnClientHeightChange() { | ||
686 | 511 | var ch = getClientSize($scrollParent[0], clientSize); | ||
687 | 512 | |||
688 | 513 | if (ch !== _prevClientSize) { | ||
689 | 514 | reinitialize(); | ||
690 | 515 | |||
691 | 516 | if ($scope.$root && !$scope.$root.$$phase) { | ||
692 | 517 | $scope.$digest(); | ||
695 | 518 | } | 198 | } |
696 | 519 | } | ||
697 | 520 | |||
698 | 521 | _prevClientSize = ch; | ||
699 | 522 | } | ||
700 | 523 | 199 | ||
727 | 524 | $scope.$watch(function () { | 200 | expressionMatches = /^\s*(\S+)\s+in\s+([\S\s]+?)(track\s+by\s+\S+)?$/.exec(ngRepeatExpression); |
728 | 525 | if (typeof window.requestAnimationFrame === 'function') { | 201 | lhs = expressionMatches[1]; |
729 | 526 | window.requestAnimationFrame(reinitOnClientHeightChange); | 202 | rhs = expressionMatches[2]; |
730 | 527 | } else { | 203 | rhsSuffix = expressionMatches[3]; |
731 | 528 | reinitOnClientHeightChange(); | 204 | |
732 | 529 | } | 205 | if (isNgRepeatStart) { |
733 | 530 | }); | 206 | var index = 0; |
734 | 531 | 207 | var repeaterElement = repeatContainer.children().eq(0); | |
735 | 532 | function binaryFind(array, threshold) { | 208 | while(repeaterElement.attr('ng-repeat-end') == null && repeaterElement.attr('data-ng-repeat-end') == null) { |
736 | 533 | var a = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; | 209 | index++; |
737 | 534 | var b = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : array.length - 1; | 210 | repeaterElement = repeatContainer.children().eq(index); |
738 | 535 | var d = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; | 211 | childCloneHtml += repeaterElement[0].outerHTML; |
739 | 536 | 212 | } | |
714 | 537 | if (array[a] === threshold) { | ||
715 | 538 | return [a, a, d]; | ||
716 | 539 | } | ||
717 | 540 | |||
718 | 541 | if (array[b] === threshold) { | ||
719 | 542 | return [b, b, d]; | ||
720 | 543 | } | ||
721 | 544 | |||
722 | 545 | if (b - a > 1) { | ||
723 | 546 | var m = Math.floor((a + b) / 2); | ||
724 | 547 | |||
725 | 548 | if (array[m] > threshold) { | ||
726 | 549 | return binaryFind(array, threshold, a, m, d + 1); | ||
740 | 550 | } | 213 | } |
741 | 551 | 214 | ||
767 | 552 | return binaryFind(array, threshold, m, b, d + 1); | 215 | repeatContainer.empty(); |
768 | 553 | } | 216 | return { |
769 | 554 | 217 | pre: function($scope, $element, $attrs) { | |
770 | 555 | return [threshold > array[b] ? b : a, threshold < array[a] ? a : b, d]; | 218 | var repeatContainer = angular.isDefined($attrs.vsRepeatContainer) ? angular.element($element[0].querySelector($attrs.vsRepeatContainer)) : $element, |
771 | 556 | } | 219 | childClone = angular.element(childCloneHtml), |
772 | 557 | 220 | childTagName = childClone[0].tagName.toLowerCase(), | |
773 | 558 | function updateInnerCollection() { | 221 | originalCollection = [], |
774 | 559 | var $scrollPosition = getScrollPos($scrollParent[0], scrollPos); | 222 | originalLength, |
775 | 560 | var $clientSize = getClientSize($scrollParent[0], clientSize); | 223 | $$horizontal = typeof $attrs.vsHorizontal !== 'undefined', |
776 | 561 | 224 | $beforeContent = angular.element('<' + childTagName + ' class="vs-repeat-before-content"></' + childTagName + '>'), | |
777 | 562 | if (options.debug) { | 225 | $afterContent = angular.element('<' + childTagName + ' class="vs-repeat-after-content"></' + childTagName + '>'), |
778 | 563 | $clientSize /= 2; | 226 | autoSize = !$attrs.vsRepeat, |
779 | 564 | } | 227 | sizesPropertyExists = !!$attrs.vsSize || !!$attrs.vsSizeProperty, |
780 | 565 | 228 | $scrollParent = $attrs.vsScrollParent ? | |
781 | 566 | var scrollOffset = repeatContainer[0] === $scrollParent[0] ? 0 : getScrollOffset(repeatContainer[0], $scrollParent[0], options.horizontal); | 229 | $attrs.vsScrollParent === 'window' ? angular.element(window) : |
782 | 567 | var __startIndex = $scope.vsRepeat.startIndex; | 230 | closestElement.call(repeatContainer, $attrs.vsScrollParent) : repeatContainer, |
783 | 568 | var __endIndex = $scope.vsRepeat.endIndex; | 231 | $$options = 'vsOptions' in $attrs ? $scope.$eval($attrs.vsOptions) : {}, |
784 | 569 | 232 | clientSize = $$horizontal ? 'clientWidth' : 'clientHeight', | |
785 | 570 | if (autosizingRequired && !options.size) { | 233 | offsetSize = $$horizontal ? 'offsetWidth' : 'offsetHeight', |
786 | 571 | __startIndex = 0; | 234 | scrollPos = $$horizontal ? 'scrollLeft' : 'scrollTop'; |
787 | 572 | __endIndex = 1; | 235 | |
788 | 573 | } else { | 236 | $scope.totalSize = 0; |
789 | 574 | _warnMismatch(); | 237 | if (!('vsSize' in $attrs) && 'vsSizeProperty' in $attrs) { |
790 | 575 | 238 | console.warn('vs-size-property attribute is deprecated. Please use vs-size attribute which also accepts angular expressions.'); | |
791 | 576 | var relativeScroll = $scrollPosition - options.offsetBefore - scrollOffset; | 239 | } |
792 | 577 | 240 | ||
794 | 578 | var _binaryFind = binaryFind($scope.vsRepeat.sizesCumulative, relativeScroll - options.scrollMargin); | 241 | if ($scrollParent.length === 0) { |
795 | 242 | throw 'Specified scroll parent selector did not match any element'; | ||
796 | 243 | } | ||
797 | 244 | $scope.$scrollParent = $scrollParent; | ||
798 | 579 | 245 | ||
800 | 580 | var _binaryFind2 = _slicedToArray(_binaryFind, 1); | 246 | if (sizesPropertyExists) { |
801 | 247 | $scope.sizesCumulative = []; | ||
802 | 248 | } | ||
803 | 581 | 249 | ||
806 | 582 | __startIndex = _binaryFind2[0]; | 250 | //initial defaults |
807 | 583 | __startIndex = Math.max(__startIndex, 0); | 251 | $scope.elementSize = (+$attrs.vsRepeat) || getClientSize($scrollParent[0], clientSize) || 50; |
808 | 252 | $scope.offsetBefore = 0; | ||
809 | 253 | $scope.offsetAfter = 0; | ||
810 | 254 | $scope.scrollMargin = 0; | ||
811 | 255 | $scope.excess = 2; | ||
812 | 584 | 256 | ||
814 | 585 | var _binaryFind3 = binaryFind($scope.vsRepeat.sizesCumulative, relativeScroll + options.scrollMargin + $clientSize, __startIndex); | 257 | if ($$horizontal) { |
815 | 258 | $beforeContent.css('height', '100%'); | ||
816 | 259 | $afterContent.css('height', '100%'); | ||
817 | 260 | } | ||
818 | 261 | else { | ||
819 | 262 | $beforeContent.css('width', '100%'); | ||
820 | 263 | $afterContent.css('width', '100%'); | ||
821 | 264 | } | ||
822 | 586 | 265 | ||
824 | 587 | var _binaryFind4 = _slicedToArray(_binaryFind3, 2); | 266 | Object.keys(attributesDictionary).forEach(function(key) { |
825 | 267 | if ($attrs[key]) { | ||
826 | 268 | $attrs.$observe(key, function(value) { | ||
827 | 269 | // '+' serves for getting a number from the string as the attributes are always strings | ||
828 | 270 | $scope[attributesDictionary[key]] = +value; | ||
829 | 271 | reinitialize(); | ||
830 | 272 | }); | ||
831 | 273 | } | ||
832 | 274 | }); | ||
833 | 275 | |||
834 | 276 | |||
835 | 277 | $scope.$watchCollection(rhs, function(coll) { | ||
836 | 278 | originalCollection = coll || []; | ||
837 | 279 | refresh(); | ||
838 | 280 | }); | ||
839 | 281 | |||
840 | 282 | function refresh() { | ||
841 | 283 | if (!originalCollection || originalCollection.length < 1) { | ||
842 | 284 | $scope[collectionName] = []; | ||
843 | 285 | originalLength = 0; | ||
844 | 286 | $scope.sizesCumulative = [0]; | ||
845 | 287 | } | ||
846 | 288 | else { | ||
847 | 289 | originalLength = originalCollection.length; | ||
848 | 290 | if (sizesPropertyExists) { | ||
849 | 291 | $scope.sizes = originalCollection.map(function(item) { | ||
850 | 292 | var s = $scope.$new(false); | ||
851 | 293 | angular.extend(s, item); | ||
852 | 294 | s[lhs] = item; | ||
853 | 295 | var size = ($attrs.vsSize || $attrs.vsSizeProperty) ? | ||
854 | 296 | s.$eval($attrs.vsSize || $attrs.vsSizeProperty) : | ||
855 | 297 | $scope.elementSize; | ||
856 | 298 | s.$destroy(); | ||
857 | 299 | return size; | ||
858 | 300 | }); | ||
859 | 301 | var sum = 0; | ||
860 | 302 | $scope.sizesCumulative = $scope.sizes.map(function(size) { | ||
861 | 303 | var res = sum; | ||
862 | 304 | sum += size; | ||
863 | 305 | return res; | ||
864 | 306 | }); | ||
865 | 307 | $scope.sizesCumulative.push(sum); | ||
866 | 308 | } | ||
867 | 309 | else { | ||
868 | 310 | setAutoSize(); | ||
869 | 311 | } | ||
870 | 312 | } | ||
871 | 313 | |||
872 | 314 | reinitialize(); | ||
873 | 315 | } | ||
874 | 588 | 316 | ||
878 | 589 | __endIndex = _binaryFind4[1]; | 317 | function setAutoSize() { |
879 | 590 | __endIndex = Math.min(__endIndex, originalLength); | 318 | if (autoSize) { |
880 | 591 | } | 319 | $scope.$$postDigest(function() { |
881 | 320 | if (repeatContainer[0].offsetHeight || repeatContainer[0].offsetWidth) { // element is visible | ||
882 | 321 | var children = repeatContainer.children(), | ||
883 | 322 | i = 0, | ||
884 | 323 | gotSomething = false, | ||
885 | 324 | insideStartEndSequence = false; | ||
886 | 325 | |||
887 | 326 | while (i < children.length) { | ||
888 | 327 | if (children[i].attributes[originalNgRepeatAttr] != null || insideStartEndSequence) { | ||
889 | 328 | if (!gotSomething) { | ||
890 | 329 | $scope.elementSize = 0; | ||
891 | 330 | } | ||
892 | 331 | |||
893 | 332 | gotSomething = true; | ||
894 | 333 | if (children[i][offsetSize]) { | ||
895 | 334 | $scope.elementSize += children[i][offsetSize]; | ||
896 | 335 | } | ||
897 | 336 | |||
898 | 337 | if (isNgRepeatStart) { | ||
899 | 338 | if (children[i].attributes['ng-repeat-end'] != null || children[i].attributes['data-ng-repeat-end'] != null) { | ||
900 | 339 | break; | ||
901 | 340 | } | ||
902 | 341 | else { | ||
903 | 342 | insideStartEndSequence = true; | ||
904 | 343 | } | ||
905 | 344 | } | ||
906 | 345 | else { | ||
907 | 346 | break; | ||
908 | 347 | } | ||
909 | 348 | } | ||
910 | 349 | i++; | ||
911 | 350 | } | ||
912 | 351 | |||
913 | 352 | if (gotSomething) { | ||
914 | 353 | reinitialize(); | ||
915 | 354 | autoSize = false; | ||
916 | 355 | if ($scope.$root && !$scope.$root.$$phase) { | ||
917 | 356 | $scope.$apply(); | ||
918 | 357 | } | ||
919 | 358 | } | ||
920 | 359 | } | ||
921 | 360 | else { | ||
922 | 361 | var dereg = $scope.$watch(function() { | ||
923 | 362 | if (repeatContainer[0].offsetHeight || repeatContainer[0].offsetWidth) { | ||
924 | 363 | dereg(); | ||
925 | 364 | setAutoSize(); | ||
926 | 365 | } | ||
927 | 366 | }); | ||
928 | 367 | } | ||
929 | 368 | }); | ||
930 | 369 | } | ||
931 | 370 | } | ||
932 | 592 | 371 | ||
937 | 593 | _minStartIndex = Math.min(__startIndex, _minStartIndex); | 372 | function getLayoutProp() { |
938 | 594 | _maxEndIndex = Math.max(__endIndex, _maxEndIndex); | 373 | var layoutPropPrefix = childTagName === 'tr' ? '' : 'min-'; |
939 | 595 | $scope.vsRepeat.startIndex = options.latch ? _minStartIndex : __startIndex; | 374 | var layoutProp = $$horizontal ? layoutPropPrefix + 'width' : layoutPropPrefix + 'height'; |
940 | 596 | $scope.vsRepeat.endIndex = options.latch ? _maxEndIndex : __endIndex; // Move to the end of the collection if we are now past it | 375 | return layoutProp; |
941 | 376 | } | ||
942 | 597 | 377 | ||
945 | 598 | if (_maxEndIndex < $scope.vsRepeat.startIndex) $scope.vsRepeat.startIndex = _maxEndIndex; | 378 | childClone.eq(0).attr(originalNgRepeatAttr, lhs + ' in ' + collectionName + (rhsSuffix ? ' ' + rhsSuffix : '')); |
946 | 599 | var digestRequired = false; | 379 | childClone.addClass('vs-repeat-repeated-element'); |
947 | 600 | 380 | ||
953 | 601 | if (_prevStartIndex == null) { | 381 | repeatContainer.append($beforeContent); |
954 | 602 | digestRequired = true; | 382 | repeatContainer.append(childClone); |
955 | 603 | } else if (_prevEndIndex == null) { | 383 | $compile(childClone)($scope); |
956 | 604 | digestRequired = true; | 384 | repeatContainer.append($afterContent); |
952 | 605 | } | ||
957 | 606 | 385 | ||
969 | 607 | if (!digestRequired) { | 386 | $scope.startIndex = 0; |
970 | 608 | if (options.hunked) { | 387 | $scope.endIndex = 0; |
960 | 609 | if (Math.abs($scope.vsRepeat.startIndex - _prevStartIndex) >= options.hunkSize || $scope.vsRepeat.startIndex === 0 && _prevStartIndex !== 0) { | ||
961 | 610 | digestRequired = true; | ||
962 | 611 | } else if (Math.abs($scope.vsRepeat.endIndex - _prevEndIndex) >= options.hunkSize || $scope.vsRepeat.endIndex === originalLength && _prevEndIndex !== originalLength) { | ||
963 | 612 | digestRequired = true; | ||
964 | 613 | } | ||
965 | 614 | } else { | ||
966 | 615 | digestRequired = $scope.vsRepeat.startIndex !== _prevStartIndex || $scope.vsRepeat.endIndex !== _prevEndIndex; | ||
967 | 616 | } | ||
968 | 617 | } | ||
971 | 618 | 388 | ||
974 | 619 | if (digestRequired) { | 389 | function scrollHandler() { |
975 | 620 | $scope[collectionName] = originalCollection.slice($scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex); // Emit the event | 390 | if (updateInnerCollection()) { |
976 | 391 | $scope.$digest(); | ||
977 | 621 | 392 | ||
980 | 622 | $scope.$emit('vsRepeatInnerCollectionUpdated', $scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex, _prevStartIndex, _prevEndIndex); | 393 | var expectedSize = sizesPropertyExists ? |
981 | 623 | var triggerIndex; | 394 | $scope.sizesCumulative[originalLength] : |
982 | 395 | $scope.elementSize * originalLength; | ||
983 | 624 | 396 | ||
991 | 625 | if (options.scrolledToEnd) { | 397 | if (expectedSize !== $element[0].clientHeight) { |
992 | 626 | triggerIndex = originalCollection.length - options.scrolledToEndOffset; | 398 | console.warn('vsRepeat: size mismatch. Expected size ' + expectedSize + 'px whereas actual size is ' + $element[0].clientHeight + 'px. Fix vsSize on element:', $element[0]); |
993 | 627 | 399 | } | |
994 | 628 | if ($scope.vsRepeat.endIndex >= triggerIndex && _prevEndIndex < triggerIndex || originalCollection.length && $scope.vsRepeat.endIndex === originalCollection.length) { | 400 | } |
995 | 629 | $scope.$eval(options.scrolledToEnd); | 401 | } |
989 | 630 | } | ||
990 | 631 | } | ||
996 | 632 | 402 | ||
999 | 633 | if (options.scrolledToBeginning) { | 403 | $scrollParent.on('scroll', scrollHandler); |
1000 | 634 | triggerIndex = options.scrolledToBeginningOffset; | 404 | |
1001 | 405 | function onWindowResize() { | ||
1002 | 406 | if (typeof $attrs.vsAutoresize !== 'undefined') { | ||
1003 | 407 | autoSize = true; | ||
1004 | 408 | setAutoSize(); | ||
1005 | 409 | if ($scope.$root && !$scope.$root.$$phase) { | ||
1006 | 410 | $scope.$apply(); | ||
1007 | 411 | } | ||
1008 | 412 | } | ||
1009 | 413 | if (updateInnerCollection()) { | ||
1010 | 414 | $scope.$apply(); | ||
1011 | 415 | } | ||
1012 | 416 | } | ||
1013 | 635 | 417 | ||
1018 | 636 | if ($scope.vsRepeat.startIndex <= triggerIndex && _prevStartIndex > $scope.vsRepeat.startIndex) { | 418 | angular.element(window).on('resize', onWindowResize); |
1019 | 637 | $scope.$eval(options.scrolledToBeginning); | 419 | $scope.$on('$destroy', function() { |
1020 | 638 | } | 420 | angular.element(window).off('resize', onWindowResize); |
1021 | 639 | } | 421 | $scrollParent.off('scroll', scrollHandler); |
1022 | 422 | }); | ||
1023 | 423 | |||
1024 | 424 | $scope.$on('vsRepeatTrigger', refresh); | ||
1025 | 425 | |||
1026 | 426 | $scope.$on('vsRepeatResize', function() { | ||
1027 | 427 | autoSize = true; | ||
1028 | 428 | setAutoSize(); | ||
1029 | 429 | }); | ||
1030 | 430 | |||
1031 | 431 | var _prevStartIndex, | ||
1032 | 432 | _prevEndIndex, | ||
1033 | 433 | _minStartIndex, | ||
1034 | 434 | _maxEndIndex; | ||
1035 | 435 | |||
1036 | 436 | $scope.$on('vsRenderAll', function() {//e , quantum) { | ||
1037 | 437 | if($$options.latch) { | ||
1038 | 438 | setTimeout(function() { | ||
1039 | 439 | // var __endIndex = Math.min($scope.endIndex + (quantum || 1), originalLength); | ||
1040 | 440 | var __endIndex = originalLength; | ||
1041 | 441 | _maxEndIndex = Math.max(__endIndex, _maxEndIndex); | ||
1042 | 442 | $scope.endIndex = $$options.latch ? _maxEndIndex : __endIndex; | ||
1043 | 443 | $scope[collectionName] = originalCollection.slice($scope.startIndex, $scope.endIndex); | ||
1044 | 444 | _prevEndIndex = $scope.endIndex; | ||
1045 | 445 | |||
1046 | 446 | $scope.$$postDigest(function() { | ||
1047 | 447 | $beforeContent.css(getLayoutProp(), 0); | ||
1048 | 448 | $afterContent.css(getLayoutProp(), 0); | ||
1049 | 449 | }); | ||
1050 | 450 | |||
1051 | 451 | $scope.$apply(function() { | ||
1052 | 452 | $scope.$emit('vsRenderAllDone'); | ||
1053 | 453 | }); | ||
1054 | 454 | }); | ||
1055 | 455 | } | ||
1056 | 456 | }); | ||
1057 | 457 | |||
1058 | 458 | function reinitialize() { | ||
1059 | 459 | _prevStartIndex = void 0; | ||
1060 | 460 | _prevEndIndex = void 0; | ||
1061 | 461 | _minStartIndex = originalLength; | ||
1062 | 462 | _maxEndIndex = 0; | ||
1063 | 463 | updateTotalSize(sizesPropertyExists ? | ||
1064 | 464 | $scope.sizesCumulative[originalLength] : | ||
1065 | 465 | $scope.elementSize * originalLength | ||
1066 | 466 | ); | ||
1067 | 467 | updateInnerCollection(); | ||
1068 | 468 | |||
1069 | 469 | $scope.$emit('vsRepeatReinitialized', $scope.startIndex, $scope.endIndex); | ||
1070 | 470 | } | ||
1071 | 640 | 471 | ||
1080 | 641 | _prevStartIndex = $scope.vsRepeat.startIndex; | 472 | function updateTotalSize(size) { |
1081 | 642 | _prevEndIndex = $scope.vsRepeat.endIndex; | 473 | $scope.totalSize = $scope.offsetBefore + size + $scope.offsetAfter; |
1082 | 643 | var o1 = $scope.vsRepeat.sizesCumulative[$scope.vsRepeat.startIndex] + options.offsetBefore; | 474 | } |
1075 | 644 | var o2 = $scope.vsRepeat.sizesCumulative[$scope.vsRepeat.startIndex + $scope[collectionName].length] + options.offsetBefore; | ||
1076 | 645 | var total = $scope.vsRepeat.totalSize; | ||
1077 | 646 | $beforeContent.css(getLayoutProps(o1 + 'px')); | ||
1078 | 647 | $afterContent.css(getLayoutProps(total - o2 + 'px')); | ||
1079 | 648 | } | ||
1083 | 649 | 475 | ||
1086 | 650 | return digestRequired; | 476 | var _prevClientSize; |
1087 | 651 | } | 477 | function reinitOnClientHeightChange() { |
1088 | 478 | var ch = getClientSize($scrollParent[0], clientSize); | ||
1089 | 479 | if (ch !== _prevClientSize) { | ||
1090 | 480 | reinitialize(); | ||
1091 | 481 | if ($scope.$root && !$scope.$root.$$phase) { | ||
1092 | 482 | $scope.$apply(); | ||
1093 | 483 | } | ||
1094 | 484 | } | ||
1095 | 485 | _prevClientSize = ch; | ||
1096 | 486 | } | ||
1097 | 652 | 487 | ||
1113 | 653 | function _warnMismatch() { | 488 | $scope.$watch(function() { |
1114 | 654 | $scope.$$postDigest(function () { | 489 | if (typeof window.requestAnimationFrame === 'function') { |
1115 | 655 | window.requestAnimationFrame(function () { | 490 | window.requestAnimationFrame(reinitOnClientHeightChange); |
1116 | 656 | var expectedSize = $scope.vsRepeat.sizesCumulative[originalLength]; | 491 | } |
1117 | 657 | var compStyle = window.getComputedStyle(repeatContainer[0]); | 492 | else { |
1118 | 658 | var paddings = options.horizontal ? ['paddingLeft', 'paddingRight'] : ['paddingTop', 'paddingBottom']; | 493 | reinitOnClientHeightChange(); |
1119 | 659 | var containerSize = repeatContainer[0][scrollSize] - paddings.reduce(function (acc, prop) { | 494 | } |
1120 | 660 | return acc + Number(compStyle[prop].slice(0, -2)); | 495 | }); |
1121 | 661 | }, 0); | 496 | |
1122 | 662 | 497 | function updateInnerCollection() { | |
1123 | 663 | if (repeatContainer[0][scrollSize] && expectedSize !== containerSize) { | 498 | var $scrollPosition = getScrollPos($scrollParent[0], scrollPos); |
1124 | 664 | console.warn('vsRepeat: size mismatch. Expected size ' + expectedSize + 'px whereas actual size is ' + containerSize + 'px. Fix vsSize on element:', $element[0]); | 499 | var $clientSize = getClientSize($scrollParent[0], clientSize); |
1125 | 665 | } | 500 | |
1126 | 666 | }); | 501 | var scrollOffset = repeatContainer[0] === $scrollParent[0] ? 0 : getScrollOffset( |
1127 | 667 | }); | 502 | repeatContainer[0], |
1128 | 503 | $scrollParent[0], | ||
1129 | 504 | $$horizontal | ||
1130 | 505 | ); | ||
1131 | 506 | |||
1132 | 507 | var __startIndex = $scope.startIndex; | ||
1133 | 508 | var __endIndex = $scope.endIndex; | ||
1134 | 509 | |||
1135 | 510 | if (sizesPropertyExists) { | ||
1136 | 511 | __startIndex = 0; | ||
1137 | 512 | while ($scope.sizesCumulative[__startIndex] < $scrollPosition - $scope.offsetBefore - scrollOffset - $scope.scrollMargin) { | ||
1138 | 513 | __startIndex++; | ||
1139 | 514 | } | ||
1140 | 515 | if (__startIndex > 0) { __startIndex--; } | ||
1141 | 516 | |||
1142 | 517 | // Adjust the start index according to the excess | ||
1143 | 518 | __startIndex = Math.max( | ||
1144 | 519 | Math.floor(__startIndex - $scope.excess / 2), | ||
1145 | 520 | 0 | ||
1146 | 521 | ); | ||
1147 | 522 | |||
1148 | 523 | __endIndex = __startIndex; | ||
1149 | 524 | while ($scope.sizesCumulative[__endIndex] < $scrollPosition - $scope.offsetBefore - scrollOffset + $scope.scrollMargin + $clientSize) { | ||
1150 | 525 | __endIndex++; | ||
1151 | 526 | } | ||
1152 | 527 | |||
1153 | 528 | // Adjust the end index according to the excess | ||
1154 | 529 | __endIndex = Math.min( | ||
1155 | 530 | Math.ceil(__endIndex + $scope.excess / 2), | ||
1156 | 531 | originalLength | ||
1157 | 532 | ); | ||
1158 | 533 | } | ||
1159 | 534 | else { | ||
1160 | 535 | __startIndex = Math.max( | ||
1161 | 536 | Math.floor( | ||
1162 | 537 | ($scrollPosition - $scope.offsetBefore - scrollOffset) / $scope.elementSize | ||
1163 | 538 | ) - $scope.excess / 2, | ||
1164 | 539 | 0 | ||
1165 | 540 | ); | ||
1166 | 541 | |||
1167 | 542 | __endIndex = Math.min( | ||
1168 | 543 | __startIndex + Math.ceil( | ||
1169 | 544 | $clientSize / $scope.elementSize | ||
1170 | 545 | ) + $scope.excess, | ||
1171 | 546 | originalLength | ||
1172 | 547 | ); | ||
1173 | 548 | } | ||
1174 | 549 | |||
1175 | 550 | _minStartIndex = Math.min(__startIndex, _minStartIndex); | ||
1176 | 551 | _maxEndIndex = Math.max(__endIndex, _maxEndIndex); | ||
1177 | 552 | |||
1178 | 553 | $scope.startIndex = $$options.latch ? _minStartIndex : __startIndex; | ||
1179 | 554 | $scope.endIndex = $$options.latch ? _maxEndIndex : __endIndex; | ||
1180 | 555 | |||
1181 | 556 | // Move to the end of the collection if we are now past it | ||
1182 | 557 | if (_maxEndIndex < $scope.startIndex) | ||
1183 | 558 | $scope.startIndex = _maxEndIndex; | ||
1184 | 559 | |||
1185 | 560 | var digestRequired = false; | ||
1186 | 561 | if (_prevStartIndex == null) { | ||
1187 | 562 | digestRequired = true; | ||
1188 | 563 | } | ||
1189 | 564 | else if (_prevEndIndex == null) { | ||
1190 | 565 | digestRequired = true; | ||
1191 | 566 | } | ||
1192 | 567 | |||
1193 | 568 | if (!digestRequired) { | ||
1194 | 569 | if ($$options.hunked) { | ||
1195 | 570 | if (Math.abs($scope.startIndex - _prevStartIndex) >= $scope.excess / 2 || | ||
1196 | 571 | ($scope.startIndex === 0 && _prevStartIndex !== 0)) { | ||
1197 | 572 | digestRequired = true; | ||
1198 | 573 | } | ||
1199 | 574 | else if (Math.abs($scope.endIndex - _prevEndIndex) >= $scope.excess / 2 || | ||
1200 | 575 | ($scope.endIndex === originalLength && _prevEndIndex !== originalLength)) { | ||
1201 | 576 | digestRequired = true; | ||
1202 | 577 | } | ||
1203 | 578 | } | ||
1204 | 579 | else { | ||
1205 | 580 | digestRequired = $scope.startIndex !== _prevStartIndex || | ||
1206 | 581 | $scope.endIndex !== _prevEndIndex; | ||
1207 | 582 | } | ||
1208 | 583 | } | ||
1209 | 584 | |||
1210 | 585 | if (digestRequired) { | ||
1211 | 586 | $scope[collectionName] = originalCollection.slice($scope.startIndex, $scope.endIndex); | ||
1212 | 587 | |||
1213 | 588 | // Emit the event | ||
1214 | 589 | $scope.$emit('vsRepeatInnerCollectionUpdated', $scope.startIndex, $scope.endIndex, _prevStartIndex, _prevEndIndex); | ||
1215 | 590 | var triggerIndex; | ||
1216 | 591 | if ($attrs.vsScrolledToEnd) { | ||
1217 | 592 | triggerIndex = originalCollection.length - ($scope.scrolledToEndOffset || 0); | ||
1218 | 593 | if (($scope.endIndex >= triggerIndex && _prevEndIndex < triggerIndex) || (originalCollection.length && $scope.endIndex === originalCollection.length)) { | ||
1219 | 594 | $scope.$eval($attrs.vsScrolledToEnd); | ||
1220 | 595 | } | ||
1221 | 596 | } | ||
1222 | 597 | if ($attrs.vsScrolledToBeginning) { | ||
1223 | 598 | triggerIndex = $scope.scrolledToBeginningOffset || 0; | ||
1224 | 599 | if (($scope.startIndex <= triggerIndex && _prevStartIndex > $scope.startIndex)) { | ||
1225 | 600 | $scope.$eval($attrs.vsScrolledToBeginning); | ||
1226 | 601 | } | ||
1227 | 602 | } | ||
1228 | 603 | |||
1229 | 604 | _prevStartIndex = $scope.startIndex; | ||
1230 | 605 | _prevEndIndex = $scope.endIndex; | ||
1231 | 606 | |||
1232 | 607 | var offsetCalculationString = sizesPropertyExists ? | ||
1233 | 608 | '(sizesCumulative[$index + startIndex] + offsetBefore)' : | ||
1234 | 609 | '(($index + startIndex) * elementSize + offsetBefore)'; | ||
1235 | 610 | |||
1236 | 611 | var parsed = $parse(offsetCalculationString); | ||
1237 | 612 | var o1 = parsed($scope, {$index: 0}); | ||
1238 | 613 | var o2 = parsed($scope, {$index: $scope[collectionName].length}); | ||
1239 | 614 | var total = $scope.totalSize; | ||
1240 | 615 | |||
1241 | 616 | $beforeContent.css(getLayoutProp(), o1 + 'px'); | ||
1242 | 617 | $afterContent.css(getLayoutProp(), (total - o2) + 'px'); | ||
1243 | 618 | } | ||
1244 | 619 | |||
1245 | 620 | return digestRequired; | ||
1246 | 621 | } | ||
1247 | 622 | } | ||
1248 | 623 | }; | ||
1249 | 668 | } | 624 | } |
1250 | 669 | } | ||
1251 | 670 | }; | 625 | }; |
1256 | 671 | } | 626 | }]); |
1253 | 672 | }; | ||
1254 | 673 | }]); | ||
1255 | 674 | angular.element(document.head).append("<style id=\"angular-vs-repeat-style\">\n\t \t.vs-repeat-debug-element {\n top: 50%;\n left: 0;\n right: 0;\n height: 1px;\n background: red;\n z-index: 99999999;\n box-shadow: 0 0 20px red;\n }\n\n .vs-repeat-debug-element + .vs-repeat-debug-element {\n display: none;\n }\n\n .vs-repeat-before-content,\n .vs-repeat-after-content {\n border: none !important;\n padding: 0 !important;\n }\n </style>"); | ||
1257 | 675 | 627 | ||
1258 | 676 | if (typeof module !== 'undefined' && module.exports) { | ||
1259 | 677 | module.exports = vsRepeatModule.name; | ||
1260 | 678 | } | ||
1261 | 679 | })(window, window.angular); | ||
1262 | 680 | \ No newline at end of file | 628 | \ No newline at end of file |
1263 | 629 | if (typeof module !== 'undefined' && module.exports) { | ||
1264 | 630 | module.exports = vsRepeatModule.name; | ||
1265 | 631 | } | ||
1266 | 632 | })(window, window.angular); | ||
1267 | diff --git a/src/maasserver/static/js/bundle/vendor-min.js b/src/maasserver/static/js/bundle/vendor-min.js | |||
1268 | index 26725ae..36bca11 100644 | |||
1269 | --- a/src/maasserver/static/js/bundle/vendor-min.js | |||
1270 | +++ b/src/maasserver/static/js/bundle/vendor-min.js | |||
1271 | @@ -1,2 +1,2 @@ | |||
1273 | 1 | !function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={i:moduleId,l:!1,exports:{}};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.l=!0,module.exports}__webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.d=function(exports,name,getter){__webpack_require__.o(exports,name)||Object.defineProperty(exports,name,{configurable:!1,enumerable:!0,get:getter})},__webpack_require__.r=function(exports){Object.defineProperty(exports,"__esModule",{value:!0})},__webpack_require__.n=function(module){var getter=module&&module.__esModule?function(){return module.default}:function(){return module};return __webpack_require__.d(getter,"a",getter),getter},__webpack_require__.o=function(object,property){return Object.prototype.hasOwnProperty.call(object,property)},__webpack_require__.p="",__webpack_require__(__webpack_require__.s=0)}({"./src/maasserver/static/js/angular/3rdparty/ng-tags-input.js":function(module,exports){!function(){"use strict";var KEYS_backspace=8,KEYS_tab=9,KEYS_enter=13,KEYS_escape=27,KEYS_space=32,KEYS_up=38,KEYS_down=40,KEYS_left=37,KEYS_right=39,KEYS_delete=46,KEYS_comma=188,SUPPORTED_INPUT_TYPES=["text","email","url"],tagsInput=angular.module("ngTagsInput",[]);tagsInput.directive("tagsInput",["$timeout","$document","$window","tagsInputConfig","tiUtil",function($timeout,$document,$window,tagsInputConfig,tiUtil){function validateType(type){return-1!==SUPPORTED_INPUT_TYPES.indexOf(type)}return{restrict:"E",require:"ngModel",scope:{tags:"=ngModel",onTagAdding:"&",onTagAdded:"&",onInvalidTag:"&",onTagRemoving:"&",onTagRemoved:"&"},replace:!1,transclude:!0,templateUrl:"ngTagsInput/tags-input.html",controller:["$scope","$attrs","$element",function($scope,$attrs,$element){$scope.events=tiUtil.simplePubSub(),tagsInputConfig.load("tagsInput",$scope,$attrs,{template:[String,"ngTagsInput/tag-item.html"],type:[String,"text",validateType],placeholder:[String,"Add a tag"],tabindex:[Number,null],removeTagSymbol:[String,String.fromCharCode(215)],replaceSpacesWithDashes:[Boolean,!0],minLength:[Number,3],maxLength:[Number,9007199254740991],addOnEnter:[Boolean,!0],addOnSpace:[Boolean,!1],addOnComma:[Boolean,!0],addOnBlur:[Boolean,!0],addOnPaste:[Boolean,!1],pasteSplitPattern:[RegExp,/,/],allowedTagsPattern:[RegExp,/.+/],enableEditingLastTag:[Boolean,!1],minTags:[Number,0],maxTags:[Number,9007199254740991],displayProperty:[String,"text"],keyProperty:[String,""],allowLeftoverText:[Boolean,!1],addFromAutocompleteOnly:[Boolean,!1],spellcheck:[Boolean,!0]}),$scope.tagList=new function(options,events,onTagAdding,onTagRemoving){var getTagText,setTagText,tagIsValid,self={};return getTagText=function(tag){return tiUtil.safeToString(tag[options.displayProperty])},setTagText=function(tag,text){tag[options.displayProperty]=text},tagIsValid=function(tag){var tagText=getTagText(tag);return tagText&&tagText.length>=options.minLength&&tagText.length<=options.maxLength&&options.allowedTagsPattern.test(tagText)&&!tiUtil.findInObjectArray(self.items,tag,options.keyProperty||options.displayProperty)&&onTagAdding({$tag:tag})},self.items=[],self.addText=function(text){var tag={};return setTagText(tag,text),self.add(tag)},self.add=function(tag){var tagText=getTagText(tag);return options.replaceSpacesWithDashes&&(tagText=tiUtil.replaceSpacesWithDashes(tagText)),setTagText(tag,tagText),tagIsValid(tag)?(self.items.push(tag),events.trigger("tag-added",{$tag:tag})):tagText&&events.trigger("invalid-tag",{$tag:tag}),tag},self.remove=function(index){var tag=self.items[index];if(onTagRemoving({$tag:tag}))return self.items.splice(index,1),self.clearSelection(),events.trigger("tag-removed",{$tag:tag}),tag},self.select=function(index){index<0?index=self.items.length-1:index>=self.items.length&&(index=0),self.index=index,self.selected=self.items[index]},self.selectPrior=function(){self.select(--self.index)},self.selectNext=function(){self.select(++self.index)},self.removeSelected=function(){return self.remove(self.index)},self.clearSelection=function(){self.selected=null,self.index=-1},self.clearSelection(),self}($scope.options,$scope.events,tiUtil.handleUndefinedResult($scope.onTagAdding,!0),tiUtil.handleUndefinedResult($scope.onTagRemoving,!0)),this.registerAutocomplete=function(){$element.find("input");return{addTag:function(tag){return $scope.tagList.add(tag)},focusInput:function(){},getTags:function(){return $scope.tags},getCurrentTagText:function(){return $scope.newTag.text},getOptions:function(){return $scope.options},on:function(name,handler){return $scope.events.on(name,handler),this}}},this.registerTagItem=function(){return{getOptions:function(){return $scope.options},removeTag:function(index){$scope.disabled||$scope.tagList.remove(index)}}}}],link:function(scope,element,attrs,ngModelCtrl){var setElementValidity,hotkeys=[KEYS_enter,KEYS_comma,KEYS_space,KEYS_backspace,KEYS_delete,KEYS_left,KEYS_right],tagList=scope.tagList,events=scope.events,options=scope.options,input=element.find("input"),validationOptions=["minTags","maxTags","allowLeftoverText"];setElementValidity=function(){ngModelCtrl.$setValidity("maxTags",scope.tags.length<=options.maxTags),ngModelCtrl.$setValidity("minTags",scope.tags.length>=options.minTags),ngModelCtrl.$setValidity("leftoverText",!(!scope.hasFocus&&!options.allowLeftoverText)||!scope.newTag.text)},ngModelCtrl.$isEmpty=function(value){return!value||!value.length},scope.newTag={text:"",invalid:null,setText:function(value){this.text=value,events.trigger("input-change",value)}},scope.track=function(tag){return tag[options.keyProperty||options.displayProperty]},scope.$watch("tags",function(value){scope.tags=tiUtil.makeObjectArray(value,options.displayProperty),tagList.items=scope.tags}),scope.$watch("tags.length",function(){setElementValidity()}),attrs.$observe("disabled",function(value){scope.disabled=value}),scope.eventHandlers={input:{change:function(text){events.trigger("input-change",text)},keydown:function($event){events.trigger("input-keydown",$event)},focus:function(){scope.hasFocus||(scope.hasFocus=!0,events.trigger("input-focus"))},blur:function(){$timeout(function(){var activeElement=$document.prop("activeElement"),lostFocusToBrowserWindow=activeElement===input[0],lostFocusToChildElement=element[0].contains(activeElement);!lostFocusToBrowserWindow&&lostFocusToChildElement||(scope.hasFocus=!1,events.trigger("input-blur"))})},paste:function($event){$event.getTextData=function(){var clipboardData=$event.clipboardData||$event.originalEvent&&$event.originalEvent.clipboardData;return clipboardData?clipboardData.getData("text/plain"):$window.clipboardData.getData("Text")},events.trigger("input-paste",$event)}},host:{click:function(){scope.disabled}}},events.on("tag-added",scope.onTagAdded).on("invalid-tag",scope.onInvalidTag).on("tag-removed",scope.onTagRemoved).on("tag-added",function(){scope.newTag.setText("")}).on("tag-added tag-removed",function(){ngModelCtrl.$setViewValue(scope.tags)}).on("invalid-tag",function(){scope.newTag.invalid=!0}).on("option-change",function(e){-1!==validationOptions.indexOf(e.name)&&setElementValidity()}).on("input-change",function(){tagList.clearSelection(),scope.newTag.invalid=null}).on("input-focus",function(){element.triggerHandler("focus"),ngModelCtrl.$setValidity("leftoverText",!0)}).on("input-blur",function(){options.addOnBlur&&!options.addFromAutocompleteOnly&&tagList.addText(scope.newTag.text),element.triggerHandler("blur"),setElementValidity()}).on("input-keydown",function(event){var shouldAdd,shouldRemove,shouldSelect,shouldEditLastTag,key=event.keyCode,addKeys={};if(!(event.shiftKey||event.altKey||event.ctrlKey||event.metaKey)&&-1!==hotkeys.indexOf(key)){if(addKeys[KEYS_enter]=options.addOnEnter,addKeys[KEYS_comma]=options.addOnComma,addKeys[KEYS_space]=options.addOnSpace,shouldAdd=!options.addFromAutocompleteOnly&&addKeys[key],shouldRemove=(key===KEYS_backspace||key===KEYS_delete)&&tagList.selected,shouldEditLastTag=key===KEYS_backspace&&0===scope.newTag.text.length&&options.enableEditingLastTag,shouldSelect=(key===KEYS_backspace||key===KEYS_left||key===KEYS_right)&&0===scope.newTag.text.length&&!options.enableEditingLastTag,shouldAdd)tagList.addText(scope.newTag.text);else if(shouldEditLastTag){var tag;tagList.selectPrior(),(tag=tagList.removeSelected())&&scope.newTag.setText(tag[options.displayProperty])}else shouldRemove?tagList.removeSelected():shouldSelect&&(key===KEYS_left||key===KEYS_backspace?tagList.selectPrior():key===KEYS_right&&tagList.selectNext());(shouldAdd||shouldSelect||shouldRemove||shouldEditLastTag)&&event.preventDefault()}}).on("input-paste",function(event){if(options.addOnPaste){var tags=event.getTextData().split(options.pasteSplitPattern);tags.length>1&&(tags.forEach(function(tag){tagList.addText(tag)}),event.preventDefault())}})}}}]),tagsInput.directive("tiTagItem",["tiUtil",function(tiUtil){return{restrict:"E",require:"^tagsInput",template:'<ng-include src="$$template"></ng-include>',scope:{data:"="},link:function(scope,element,attrs,tagsInputCtrl){var tagsInput=tagsInputCtrl.registerTagItem(),options=tagsInput.getOptions();scope.$$template=options.template,scope.$$removeTagSymbol=options.removeTagSymbol,scope.$getDisplayText=function(){return tiUtil.safeToString(scope.data[options.displayProperty])},scope.$removeTag=function(){tagsInput.removeTag(scope.$index)},scope.$watch("$parent.$index",function(value){scope.$index=value})}}}]),tagsInput.directive("autoComplete",["$document","$timeout","$sce","$q","tagsInputConfig","tiUtil",function($document,$timeout,$sce,$q,tagsInputConfig,tiUtil){return{restrict:"E",require:"^tagsInput",scope:{source:"&"},templateUrl:"ngTagsInput/auto-complete.html",controller:["$scope","$element","$attrs",function($scope,$element,$attrs){$scope.events=tiUtil.simplePubSub(),tagsInputConfig.load("autoComplete",$scope,$attrs,{template:[String,"ngTagsInput/auto-complete-match.html"],debounceDelay:[Number,100],minLength:[Number,3],highlightMatchedText:[Boolean,!0],maxResultsToShow:[Number,10],loadOnDownArrow:[Boolean,!1],loadOnEmpty:[Boolean,!1],loadOnFocus:[Boolean,!1],selectFirstMatch:[Boolean,!0],displayProperty:[String,""]}),$scope.suggestionList=new function(loadFn,options,events){var getDifference,lastPromise,getTagId,self={};return getTagId=function(){return options.tagsInput.keyProperty||options.tagsInput.displayProperty},getDifference=function(array1,array2){return array1.filter(function(item){return!tiUtil.findInObjectArray(array2,item,getTagId(),function(a,b){return options.tagsInput.replaceSpacesWithDashes&&(a=tiUtil.replaceSpacesWithDashes(a),b=tiUtil.replaceSpacesWithDashes(b)),tiUtil.defaultComparer(a,b)})})},self.reset=function(){lastPromise=null,self.items=[],self.visible=!1,self.index=-1,self.selected=null,self.query=null},self.show=function(){options.selectFirstMatch?self.select(0):self.selected=null,self.visible=!0},self.load=tiUtil.debounce(function(query,tags){self.query=query;var promise=$q.when(loadFn({$query:query}));lastPromise=promise,promise.then(function(items){promise===lastPromise&&(items=tiUtil.makeObjectArray(items.data||items,getTagId()),items=getDifference(items,tags),self.items=items.slice(0,options.maxResultsToShow),self.items.length>0?self.show():self.reset())})},options.debounceDelay),self.selectNext=function(){self.select(++self.index)},self.selectPrior=function(){self.select(--self.index)},self.select=function(index){index<0?index=self.items.length-1:index>=self.items.length&&(index=0),self.index=index,self.selected=self.items[index],events.trigger("suggestion-selected",index)},self.reset(),self}($scope.source,$scope.options,$scope.events),this.registerAutocompleteMatch=function(){return{getOptions:function(){return $scope.options},getQuery:function(){return $scope.suggestionList.query}}}}],link:function(scope,element,attrs,tagsInputCtrl){var shouldLoadSuggestions,hotkeys=[KEYS_enter,KEYS_tab,KEYS_escape,KEYS_up,KEYS_down],suggestionList=scope.suggestionList,tagsInput=tagsInputCtrl.registerAutocomplete(),options=scope.options,events=scope.events;options.tagsInput=tagsInput.getOptions(),shouldLoadSuggestions=function(value){return value&&value.length>=options.minLength||!value&&options.loadOnEmpty},scope.addSuggestionByIndex=function(index){suggestionList.select(index),scope.addSuggestion()},scope.addSuggestion=function(){var added=!1;return suggestionList.selected&&(tagsInput.addTag(angular.copy(suggestionList.selected)),suggestionList.reset(),tagsInput.focusInput(),added=!0),added},scope.track=function(item){return item[options.tagsInput.keyProperty||options.tagsInput.displayProperty]},tagsInput.on("tag-added invalid-tag input-blur",function(){suggestionList.reset()}).on("input-change",function(value){shouldLoadSuggestions(value)?suggestionList.load(value,tagsInput.getTags()):suggestionList.reset()}).on("input-focus",function(){var value=tagsInput.getCurrentTagText();options.loadOnFocus&&shouldLoadSuggestions(value)&&suggestionList.load(value,tagsInput.getTags())}).on("input-keydown",function(event){var key=event.keyCode,handled=!1;if(-1!==hotkeys.indexOf(key))return suggestionList.visible?key===KEYS_down?(suggestionList.selectNext(),handled=!0):key===KEYS_up?(suggestionList.selectPrior(),handled=!0):key===KEYS_escape?(suggestionList.reset(),handled=!0):key!==KEYS_enter&&key!==KEYS_tab||(handled=scope.addSuggestion()):key===KEYS_down&&scope.options.loadOnDownArrow&&(suggestionList.load(tagsInput.getCurrentTagText(),tagsInput.getTags()),handled=!0),handled?(event.preventDefault(),event.stopImmediatePropagation(),!1):void 0}),events.on("suggestion-selected",function(index){!function(root,index){var element=root.find("li").eq(index),parent=element.parent(),elementTop=element.prop("offsetTop"),elementHeight=element.prop("offsetHeight"),parentHeight=parent.prop("clientHeight"),parentScrollTop=parent.prop("scrollTop");elementTop<parentScrollTop?parent.prop("scrollTop",elementTop):elementTop+elementHeight>parentHeight+parentScrollTop&&parent.prop("scrollTop",elementTop+elementHeight-parentHeight)}(element,index)})}}}]),tagsInput.directive("tiAutocompleteMatch",["$sce","tiUtil",function($sce,tiUtil){return{restrict:"E",require:"^autoComplete",template:'<ng-include src="$$template"></ng-include>',scope:{data:"="},link:function(scope,element,attrs,autoCompleteCtrl){var autoComplete=autoCompleteCtrl.registerAutocompleteMatch(),options=autoComplete.getOptions();scope.$$template=options.template,scope.$index=scope.$parent.$index,scope.$highlight=function(text){return options.highlightMatchedText&&(text=tiUtil.safeHighlight(text,autoComplete.getQuery())),$sce.trustAsHtml(text)},scope.$getDisplayText=function(){return tiUtil.safeToString(scope.data[options.displayProperty||options.tagsInput.displayProperty])}}}}]),tagsInput.directive("tiTranscludeAppend",function(){return function(scope,element,attrs,ctrl,transcludeFn){transcludeFn(function(clone){element.append(clone)})}}),tagsInput.directive("tiAutosize",["tagsInputConfig",function(tagsInputConfig){return{restrict:"A",require:"ngModel",link:function(scope,element,attrs,ctrl){var span,resize,threshold=tagsInputConfig.getTextAutosizeThreshold();(span=angular.element('<span class="input"></span>')).css("display","none").css("visibility","hidden").css("width","auto").css("white-space","pre"),element.parent().append(span),resize=function(originalValue){var width,value=originalValue;return angular.isString(value)&&0===value.length&&(value=attrs.placeholder),value&&(span.text(value),span.css("display",""),width=span.prop("offsetWidth"),span.css("display","none")),element.css("width",width?width+threshold+"px":""),originalValue},ctrl.$parsers.unshift(resize),ctrl.$formatters.unshift(resize),attrs.$observe("placeholder",function(value){ctrl.$modelValue||resize(value)})}}}]),tagsInput.directive("tiBindAttrs",function(){return function(scope,element,attrs){scope.$watch(attrs.tiBindAttrs,function(value){angular.forEach(value,function(value,key){"type"===key?element[0].type=value:attrs.$set(key,value)})},!0)}}),tagsInput.provider("tagsInputConfig",function(){var globalDefaults={},interpolationStatus={},autosizeThreshold=3;this.setDefaults=function(directive,defaults){return globalDefaults[directive]=defaults,this},this.setActiveInterpolation=function(directive,options){return interpolationStatus[directive]=options,this},this.setTextAutosizeThreshold=function(threshold){return autosizeThreshold=threshold,this},this.$get=["$interpolate",function($interpolate){var converters={};return converters[String]=function(value){return value},converters[Number]=function(value){return parseInt(value,10)},converters[Boolean]=function(value){return"true"===value.toLowerCase()},converters[RegExp]=function(value){return new RegExp(value)},{load:function(directive,scope,attrs,options){var defaultValidator=function(){return!0};scope.options={},angular.forEach(options,function(value,key){var type,localDefault,validator,converter,getDefault,updateValue;type=value[0],localDefault=value[1],validator=value[2]||defaultValidator,converter=converters[type],getDefault=function(){var globalValue=globalDefaults[directive]&&globalDefaults[directive][key];return angular.isDefined(globalValue)?globalValue:localDefault},updateValue=function(value){scope.options[key]=value&&validator(value)?converter(value):getDefault()},interpolationStatus[directive]&&interpolationStatus[directive][key]?attrs.$observe(key,function(value){updateValue(value),scope.events.trigger("option-change",{name:key,newValue:value})}):updateValue(attrs[key]&&$interpolate(attrs[key])(scope.$parent))})},getTextAutosizeThreshold:function(){return autosizeThreshold}}}]}),tagsInput.factory("tiUtil",["$timeout",function($timeout){var self={debounce:function(fn,delay){var timeoutId;return function(){var args=arguments;$timeout.cancel(timeoutId),timeoutId=$timeout(function(){fn.apply(null,args)},delay)}},makeObjectArray:function(array,key){return(array=array||[]).length>0&&!angular.isObject(array[0])&&array.forEach(function(item,index){array[index]={},array[index][key]=item}),array},findInObjectArray:function(array,obj,key,comparer){var item=null;return comparer=comparer||self.defaultComparer,array.some(function(element){if(comparer(element[key],obj[key]))return item=element,!0}),item},defaultComparer:function(a,b){return self.safeToString(a).toLowerCase()===self.safeToString(b).toLowerCase()},safeHighlight:function(str,value){if(!value)return str;str=self.encodeHTML(str),value=self.encodeHTML(value);var expression=new RegExp("&[^;]+;|"+function(str){return str.replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")}(value),"gi");return str.replace(expression,function(match){return match.toLowerCase()===value.toLowerCase()?"<em>"+match+"</em>":match})},safeToString:function(value){return angular.isUndefined(value)||null==value?"":value.toString().trim()},encodeHTML:function(value){return self.safeToString(value).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")},handleUndefinedResult:function(fn,valueIfUndefined){return function(){var result=fn.apply(null,arguments);return angular.isUndefined(result)?valueIfUndefined:result}},replaceSpacesWithDashes:function(str){return self.safeToString(str).replace(/\s/g,"-")},simplePubSub:function(){var events={};return{on:function(names,handler){return names.split(" ").forEach(function(name){events[name]||(events[name]=[]),events[name].push(handler)}),this},trigger:function(name,args){return(events[name]||[]).every(function(handler){return self.handleUndefinedResult(handler,!0)(args)}),this}}}};return self}]),tagsInput.run(["$templateCache",function($templateCache){$templateCache.put("ngTagsInput/tags-input.html",'<div class="host" tabindex="-1" data-ng-click="eventHandlers.host.click()" ti-transclude-append=""><div class="tags" data-ng-class="{focused: hasFocus}"><ul class="tag-list"><li class="tag-item" data-ng-repeat="tag in tagList.items track by track(tag)" data-ng-class="{ selected: tag == tagList.selected }"><ti-tag-item data="tag"></ti-tag-item></li></ul><input class="input u-no-margin--top" autocomplete="off" data-ng-model="newTag.text" data-ng-change="eventHandlers.input.change(newTag.text)" data-ng-keydown="eventHandlers.input.keydown($event)" data-ng-focus="eventHandlers.input.focus($event)" data-ng-blur="eventHandlers.input.blur($event)" data-ng-paste="eventHandlers.input.paste($event)" data-ng-trim="false" data-ng-class="{\'invalid-tag\': newTag.invalid}" data-ng-disabled="disabled" ti-bind-attrs="{type: options.type, placeholder: options.placeholder, tabindex: options.tabindex, spellcheck: options.spellcheck}" ti-autosize=""></div></div>'),$templateCache.put("ngTagsInput/tag-item.html",'<span ng-bind="$getDisplayText()"></span> <a class="p-icon--close" data-ng-click="$removeTag()" data-ng-bind="$$removeTagSymbol">Remove tag</a>'),$templateCache.put("ngTagsInput/auto-complete.html",'<div class="autocomplete" data-ng-if="suggestionList.visible"><ul class="p-list suggestion-list"><li class="suggestion-item" data-ng-repeat="item in suggestionList.items track by track(item)" data-ng-class="{selected: item == suggestionList.selected}" data-ng-click="addSuggestionByIndex($index)" data-ng-mouseenter="suggestionList.select($index)"><ti-autocomplete-match data="item"></ti-autocomplete-match></li></ul></div>'),$templateCache.put("ngTagsInput/auto-complete-match.html",'<span data-ng-bind-html="$highlight($getDisplayText())"></span>')}])}()},"./src/maasserver/static/js/angular/3rdparty/vs-repeat.js":function(module,exports){function _extends(){return(_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source)Object.prototype.hasOwnProperty.call(source,key)&&(target[key]=source[key])}return target}).apply(this,arguments)}function _slicedToArray(arr,i){if(Array.isArray(arr))return arr;if(Symbol.iterator in Object(arr))return function(arr,i){var _arr=[],_n=!0,_d=!1,_e=void 0;try{for(var _s,_i=arr[Symbol.iterator]();!(_n=(_s=_i.next()).done)&&(_arr.push(_s.value),!i||_arr.length!==i);_n=!0);}catch(err){_d=!0,_e=err}finally{try{_n||null==_i.return||_i.return()}finally{if(_d)throw _e}}return _arr}(arr,i);throw new TypeError("Invalid attempt to destructure non-iterable instance")}!function(window,angular){var closestElement=angular.element.prototype.closest;if(!closestElement){var matchingFunction=["matches","matchesSelector","webkitMatches","webkitMatchesSelector","msMatches","msMatchesSelector","mozMatches","mozMatchesSelector"].reduce(function(res,prop){var _res;return null!==(_res=res)&&void 0!==_res?_res:prop in document.documentElement?prop:null},null);closestElement=function(selector){for(var _el,el=this[0].parentNode;el!==document.documentElement&&null!=el&&!el[matchingFunction](selector);)el=el.parentNode;return(null===(_el=el)||void 0===_el?void 0:_el[matchingFunction](selector))?angular.element(el):angular.element()}}function getWindowScroll(){var _ref,_document$documentEle,_ref2,_document$documentEle2;return"pageYOffset"in window?{scrollTop:window.pageYOffset,scrollLeft:window.pageXOffset}:{scrollTop:null!==(_ref=null!==(_document$documentEle=document.documentElement.scrollTop)&&void 0!==_document$documentEle?_document$documentEle:document.body.scrollTop)&&void 0!==_ref?_ref:0,scrollLeft:null!==(_ref2=null!==(_document$documentEle2=document.documentElement.scrollLeft)&&void 0!==_document$documentEle2?_document$documentEle2:document.body.scrollLeft)&&void 0!==_ref2?_ref2:0}}function getClientSize(element,sizeProp){return element===window?"clientWidth"===sizeProp?window.innerWidth:window.innerHeight:element[sizeProp]}function attrDeprecated(attrname,$element){!function($element,message){console.warn("vs-repeat deprecation: ".concat(message),$element[0])}($element,"".concat(attrname," attribute is deprecated. Pass the options object to vs-repeat attribute instead https://github.com/kamilkp/angular-vs-repeat#options"))}var defaultOptions={latch:!1,container:null,scrollParent:null,size:null,offsetBefore:0,offsetAfter:0,scrolledToBeginning:angular.noop,scrolledToEnd:angular.noop,scrolledToBeginningOffset:0,scrolledToEndOffset:0,scrollMargin:0,horizontal:!1,autoresize:!1,hunked:!1,hunkSize:0},vsRepeatModule=angular.module("vs-repeat",[]).directive("vsRepeat",["$compile","$parse",function($compile,$parse){return{restrict:"A",scope:!0,compile:function(compileElement,compileAttrs){var compileRepeatContainer="vsRepeatContainer"in compileAttrs?angular.element(compileElement[0].querySelector(compileAttrs.vsRepeatContainer)):compileElement,repeatContainerChildren=compileRepeatContainer.children(),ngRepeatChild=repeatContainerChildren.eq(0),childCloneHtml=ngRepeatChild[0].outerHTML,collectionName="$vs_collection";["vsSize","vsScrollParent","vsSizeProperty","vsHorizontal","vsOffsetBefore","vsOffsetAfter","vsScrolledToEndOffset","vsScrolledToBeginningOffset","vsExcess","vsScrollMargin"].forEach(function(attrname){attrname in compileAttrs&&attrDeprecated(attrname,compileElement)});var _analyzeNgRepeatUsage2=_slicedToArray(function(element){for(var options=["ng-repeat","data-ng-repeat","ng-repeat-start","data-ng-repeat-start"],_i=0;_i<options.length;_i++){var opt=options[_i];if(element.attr(opt))return[opt,element.attr(opt),opt.indexOf("-start")>=0]}throw new Error("angular-vs-repeat: no ng-repeat directive on a child element")}(ngRepeatChild),3),originalNgRepeatAttr=_analyzeNgRepeatUsage2[0],ngRepeatExpression=_analyzeNgRepeatUsage2[1],isNgRepeatStart=_analyzeNgRepeatUsage2[2],_expressionMatches=_slicedToArray(/^\s*(\S+)\s+in\s+([\S\s]+?)(track\s+by\s+\S+)?$/.exec(ngRepeatExpression),4),lhs=_expressionMatches[1],rhs=_expressionMatches[2],rhsSuffix=_expressionMatches[3];if(isNgRepeatStart)for(var index=0,repeaterElement=repeatContainerChildren.eq(index);null==repeaterElement.attr("ng-repeat-end")&&null==repeaterElement.attr("data-ng-repeat-end");)index++,repeaterElement=repeatContainerChildren.eq(index),childCloneHtml+=repeaterElement[0].outerHTML;return compileRepeatContainer.empty(),{pre:function($scope,$element,$attrs){var _$scope$$eval;function _parseSize(options){if("number"==typeof options.size)options.getSize=function(){return options.size};else{var parsed=$parse(String(options.size));options.getSize=function(item){return parsed($scope,(value=item,(key=lhs)in(obj={})?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj));var obj,key,value}}}$scope.vsRepeat={options:_extends({},defaultOptions,null!==(_$scope$$eval=$scope.$eval($attrs.vsRepeat))&&void 0!==_$scope$$eval?_$scope$$eval:{})};var options=$scope.vsRepeat.options;_parseSize(options);var originalLength,repeatContainer=angular.isDefined($attrs.vsRepeatContainer)?angular.element($element[0].querySelector($attrs.vsRepeatContainer)):$element,childClone=angular.element(childCloneHtml),childTagName=childClone[0].tagName.toLowerCase(),originalCollection=[],$beforeContent=angular.element("<"+childTagName+' class="vs-repeat-before-content"></'+childTagName+">"),$afterContent=angular.element("<"+childTagName+' class="vs-repeat-after-content"></'+childTagName+">"),autosizingRequired=null===options.size,$scrollParent=options.scrollParent?"window"===options.scrollParent?angular.element(window):closestElement.call(repeatContainer,options.scrollParent):repeatContainer,clientSize=options.horizontal?"clientWidth":"clientHeight",offsetSize=options.horizontal?"offsetWidth":"offsetHeight",scrollSize=options.horizontal?"scrollWidth":"scrollHeight",scrollPos=options.horizontal?"scrollLeft":"scrollTop";if($scope.vsRepeat.totalSize=0,0===$scrollParent.length)throw"Specified scroll parent selector did not match any element";if($scope.vsRepeat.$scrollParent=$scrollParent,$scope.vsRepeat.sizesCumulative=[],options.debug){var $debugParent="window"===options.scrollParent?angular.element(document.body):$scrollParent,$debug=angular.element('<div class="vs-repeat-debug-element"></div>');$debug.css("position","window"===options.scrollParent?"fixed":"absolute"),$debugParent.append($debug),$scope.$on("$destroy",function(){$debug.remove()})}var _prevStartIndex,_prevEndIndex,_minStartIndex,_maxEndIndex,_prevClientSize,measuredSize=getClientSize($scrollParent[0],clientSize)||50;function refresh(){!originalCollection||originalCollection.length<1?($scope[collectionName]=[],originalLength=0,$scope.vsRepeat.sizesCumulative=[0]):(originalLength=originalCollection.length,options.size?_mapSize():getFromMeasured()),reinitialize()}function _mapSize(){var hardSize=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,sizes=originalCollection.map(function(item){var _hardSize;return null!==(_hardSize=hardSize)&&void 0!==_hardSize?_hardSize:options.getSize(item)}),sum=0;$scope.vsRepeat.sizesCumulative=[0].concat(function(arr){if(Array.isArray(arr)){for(var i=0,arr2=new Array(arr.length);i<arr.length;i++)arr2[i]=arr[i];return arr2}return Array.from(arr)}(sizes.map(function(size){return sum+=size})))}function getFromMeasured(){autosizingRequired?$scope.$$postDigest(function(){if(repeatContainer[0].offsetHeight||repeatContainer[0].offsetWidth){for(var children=repeatContainer.children(),i=0,gotSomething=!1,insideStartEndSequence=!1;i<children.length;){if(null!=children[i].attributes[originalNgRepeatAttr]||insideStartEndSequence){if(gotSomething||(measuredSize=0),gotSomething=!0,children[i][offsetSize]&&(measuredSize+=children[i][offsetSize]),!isNgRepeatStart)break;if(null!=children[i].attributes["ng-repeat-end"]||null!=children[i].attributes["data-ng-repeat-end"])break;insideStartEndSequence=!0}i++}gotSomething&&(_mapSize(measuredSize),reinitialize(),autosizingRequired=!1,$scope.$root&&!$scope.$root.$$phase&&$scope.$digest())}else var dereg=$scope.$watch(function(){(repeatContainer[0].offsetHeight||repeatContainer[0].offsetWidth)&&(dereg(),getFromMeasured())})}):_mapSize(measuredSize)}function getLayoutProps(value){var layoutProp=options.horizontal?"width":"height";return["","min-","max-"].reduce(function(acc,prop){return acc["".concat(prop).concat(layoutProp)]=value,acc},{})}function scrollHandler(){var pos=$scrollParent[0][scrollPos];updateInnerCollection()&&($scope.$digest(),options._ensureScrollIntegrity&&($scrollParent[0][scrollPos]=pos))}function onWindowResize(){options.autoresize&&(autosizingRequired=!0,getFromMeasured(),$scope.$root&&!$scope.$root.$$phase&&$scope.$digest()),updateInnerCollection()&&$scope.$digest()}function reinitialize(){var size;_prevStartIndex=void 0,_prevEndIndex=void 0,_minStartIndex=originalLength,_maxEndIndex=0,size=$scope.vsRepeat.sizesCumulative[originalLength],$scope.vsRepeat.totalSize=options.offsetBefore+size+options.offsetAfter,updateInnerCollection(),$scope.$emit("vsRepeatReinitialized",$scope.vsRepeat.startIndex,$scope.vsRepeat.endIndex)}function reinitOnClientHeightChange(){var ch=getClientSize($scrollParent[0],clientSize);ch!==_prevClientSize&&(reinitialize(),$scope.$root&&!$scope.$root.$$phase&&$scope.$digest()),_prevClientSize=ch}function binaryFind(array,threshold){var a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,b=arguments.length>3&&void 0!==arguments[3]?arguments[3]:array.length-1,d=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1;if(array[a]===threshold)return[a,a,d];if(array[b]===threshold)return[b,b,d];if(b-a>1){var m=Math.floor((a+b)/2);return array[m]>threshold?binaryFind(array,threshold,a,m,d+1):binaryFind(array,threshold,m,b,d+1)}return[threshold>array[b]?b:a,threshold<array[a]?a:b,d]}function updateInnerCollection(){var element,scrollProp,$scrollPosition=(element=$scrollParent[0],scrollProp=scrollPos,element===window?getWindowScroll()[scrollProp]:element[scrollProp]),$clientSize=getClientSize($scrollParent[0],clientSize);options.debug&&($clientSize/=2);var vsElement,scrollElement,isHorizontal,scrollOffset=repeatContainer[0]===$scrollParent[0]?0:(vsElement=repeatContainer[0],scrollElement=$scrollParent[0],isHorizontal=options.horizontal,vsElement.getBoundingClientRect()[isHorizontal?"left":"top"]-(scrollElement===window?0:scrollElement.getBoundingClientRect()[isHorizontal?"left":"top"])+(scrollElement===window?getWindowScroll():scrollElement)[isHorizontal?"scrollLeft":"scrollTop"]),__startIndex=$scope.vsRepeat.startIndex,__endIndex=$scope.vsRepeat.endIndex;if(autosizingRequired&&!options.size)__startIndex=0,__endIndex=1;else{$scope.$$postDigest(function(){window.requestAnimationFrame(function(){var expectedSize=$scope.vsRepeat.sizesCumulative[originalLength],compStyle=window.getComputedStyle(repeatContainer[0]),paddings=options.horizontal?["paddingLeft","paddingRight"]:["paddingTop","paddingBottom"],containerSize=repeatContainer[0][scrollSize]-paddings.reduce(function(acc,prop){return acc+Number(compStyle[prop].slice(0,-2))},0);repeatContainer[0][scrollSize]&&expectedSize!==containerSize&&console.warn("vsRepeat: size mismatch. Expected size "+expectedSize+"px whereas actual size is "+containerSize+"px. Fix vsSize on element:",$element[0])})});var relativeScroll=$scrollPosition-options.offsetBefore-scrollOffset;__startIndex=_slicedToArray(binaryFind($scope.vsRepeat.sizesCumulative,relativeScroll-options.scrollMargin),1)[0],__startIndex=Math.max(__startIndex,0),__endIndex=_slicedToArray(binaryFind($scope.vsRepeat.sizesCumulative,relativeScroll+options.scrollMargin+$clientSize,__startIndex),2)[1],__endIndex=Math.min(__endIndex,originalLength)}_minStartIndex=Math.min(__startIndex,_minStartIndex),_maxEndIndex=Math.max(__endIndex,_maxEndIndex),$scope.vsRepeat.startIndex=options.latch?_minStartIndex:__startIndex,$scope.vsRepeat.endIndex=options.latch?_maxEndIndex:__endIndex,_maxEndIndex<$scope.vsRepeat.startIndex&&($scope.vsRepeat.startIndex=_maxEndIndex);var digestRequired=!1;if(null==_prevStartIndex?digestRequired=!0:null==_prevEndIndex&&(digestRequired=!0),digestRequired||(options.hunked?Math.abs($scope.vsRepeat.startIndex-_prevStartIndex)>=options.hunkSize||0===$scope.vsRepeat.startIndex&&0!==_prevStartIndex?digestRequired=!0:(Math.abs($scope.vsRepeat.endIndex-_prevEndIndex)>=options.hunkSize||$scope.vsRepeat.endIndex===originalLength&&_prevEndIndex!==originalLength)&&(digestRequired=!0):digestRequired=$scope.vsRepeat.startIndex!==_prevStartIndex||$scope.vsRepeat.endIndex!==_prevEndIndex),digestRequired){var triggerIndex;$scope[collectionName]=originalCollection.slice($scope.vsRepeat.startIndex,$scope.vsRepeat.endIndex),$scope.$emit("vsRepeatInnerCollectionUpdated",$scope.vsRepeat.startIndex,$scope.vsRepeat.endIndex,_prevStartIndex,_prevEndIndex),options.scrolledToEnd&&(triggerIndex=originalCollection.length-options.scrolledToEndOffset,($scope.vsRepeat.endIndex>=triggerIndex&&_prevEndIndex<triggerIndex||originalCollection.length&&$scope.vsRepeat.endIndex===originalCollection.length)&&$scope.$eval(options.scrolledToEnd)),options.scrolledToBeginning&&(triggerIndex=options.scrolledToBeginningOffset,$scope.vsRepeat.startIndex<=triggerIndex&&_prevStartIndex>$scope.vsRepeat.startIndex&&$scope.$eval(options.scrolledToBeginning)),_prevStartIndex=$scope.vsRepeat.startIndex,_prevEndIndex=$scope.vsRepeat.endIndex;var o1=$scope.vsRepeat.sizesCumulative[$scope.vsRepeat.startIndex]+options.offsetBefore,o2=$scope.vsRepeat.sizesCumulative[$scope.vsRepeat.startIndex+$scope[collectionName].length]+options.offsetBefore,total=$scope.vsRepeat.totalSize;$beforeContent.css(getLayoutProps(o1+"px")),$afterContent.css(getLayoutProps(total-o2+"px"))}return digestRequired}options.horizontal?($beforeContent.css("height","100%"),$afterContent.css("height","100%")):($beforeContent.css("width","100%"),$afterContent.css("width","100%")),$attrs.vsRepeatOptions&&$scope.$watchCollection($attrs.vsRepeatOptions,function(newOpts){var mergedOptions=_extends({},options,newOpts);JSON.stringify(mergedOptions)!==JSON.stringify(options)&&(Object.assign(options,newOpts),_parseSize(options),reinitialize())}),$scope.$watchCollection(rhs,function(){var coll=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];originalCollection=coll,refresh()}),childClone.eq(0).attr(originalNgRepeatAttr,lhs+" in "+collectionName+(rhsSuffix?" "+rhsSuffix:"")),childClone.addClass("vs-repeat-repeated-element"),repeatContainer.append($beforeContent),repeatContainer.append(childClone),$compile(childClone)($scope),repeatContainer.append($afterContent),$scope.vsRepeat.startIndex=0,$scope.vsRepeat.endIndex=0,$scrollParent.on("scroll",scrollHandler),angular.element(window).on("resize",onWindowResize),$scope.$on("$destroy",function(){angular.element(window).off("resize",onWindowResize),$scrollParent.off("scroll",scrollHandler)}),$scope.$on("vsRepeatTrigger",refresh),$scope.$on("vsRepeatResize",function(){autosizingRequired=!0,getFromMeasured()}),$scope.$on("vsRenderAll",function(){options.latch&&($scope.vsRepeat.endIndex!==originalLength?setTimeout(function(){var __endIndex=originalLength;_maxEndIndex=Math.max(__endIndex,_maxEndIndex),$scope.vsRepeat.endIndex=options.latch?_maxEndIndex:__endIndex,$scope[collectionName]=originalCollection.slice($scope.vsRepeat.startIndex,$scope.vsRepeat.endIndex),_prevEndIndex=$scope.vsRepeat.endIndex,$beforeContent.css(getLayoutProps(0)),$afterContent.css(getLayoutProps(0)),$scope.$emit("vsRenderAllDone"),$scope.$root&&!$scope.$root.$$phase&&$scope.$digest()}):$scope.$emit("vsRenderAllDone"))}),$scope.$watch(function(){"function"==typeof window.requestAnimationFrame?window.requestAnimationFrame(reinitOnClientHeightChange):reinitOnClientHeightChange()})}}}}}]);angular.element(document.head).append('<style id="angular-vs-repeat-style">\n\t \t.vs-repeat-debug-element {\n top: 50%;\n left: 0;\n right: 0;\n height: 1px;\n background: red;\n z-index: 99999999;\n box-shadow: 0 0 20px red;\n }\n\n .vs-repeat-debug-element + .vs-repeat-debug-element {\n display: none;\n }\n\n .vs-repeat-before-content,\n .vs-repeat-after-content {\n border: none !important;\n padding: 0 !important;\n }\n </style>'),void 0!==module&&module.exports&&(module.exports=vsRepeatModule.name)}(window,window.angular)},0:function(module,exports,__webpack_require__){__webpack_require__("./src/maasserver/static/js/angular/3rdparty/ng-tags-input.js"),module.exports=__webpack_require__("./src/maasserver/static/js/angular/3rdparty/vs-repeat.js")}}); | 1 | !function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={i:moduleId,l:!1,exports:{}};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.l=!0,module.exports}__webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.d=function(exports,name,getter){__webpack_require__.o(exports,name)||Object.defineProperty(exports,name,{configurable:!1,enumerable:!0,get:getter})},__webpack_require__.r=function(exports){Object.defineProperty(exports,"__esModule",{value:!0})},__webpack_require__.n=function(module){var getter=module&&module.__esModule?function(){return module.default}:function(){return module};return __webpack_require__.d(getter,"a",getter),getter},__webpack_require__.o=function(object,property){return Object.prototype.hasOwnProperty.call(object,property)},__webpack_require__.p="",__webpack_require__(__webpack_require__.s=0)}({"./src/maasserver/static/js/angular/3rdparty/ng-tags-input.js":function(module,exports){!function(){"use strict";var KEYS_backspace=8,KEYS_tab=9,KEYS_enter=13,KEYS_escape=27,KEYS_space=32,KEYS_up=38,KEYS_down=40,KEYS_left=37,KEYS_right=39,KEYS_delete=46,KEYS_comma=188,SUPPORTED_INPUT_TYPES=["text","email","url"],tagsInput=angular.module("ngTagsInput",[]);tagsInput.directive("tagsInput",["$timeout","$document","$window","tagsInputConfig","tiUtil",function($timeout,$document,$window,tagsInputConfig,tiUtil){function validateType(type){return-1!==SUPPORTED_INPUT_TYPES.indexOf(type)}return{restrict:"E",require:"ngModel",scope:{tags:"=ngModel",onTagAdding:"&",onTagAdded:"&",onInvalidTag:"&",onTagRemoving:"&",onTagRemoved:"&"},replace:!1,transclude:!0,templateUrl:"ngTagsInput/tags-input.html",controller:["$scope","$attrs","$element",function($scope,$attrs,$element){$scope.events=tiUtil.simplePubSub(),tagsInputConfig.load("tagsInput",$scope,$attrs,{template:[String,"ngTagsInput/tag-item.html"],type:[String,"text",validateType],placeholder:[String,"Add a tag"],tabindex:[Number,null],removeTagSymbol:[String,String.fromCharCode(215)],replaceSpacesWithDashes:[Boolean,!0],minLength:[Number,3],maxLength:[Number,9007199254740991],addOnEnter:[Boolean,!0],addOnSpace:[Boolean,!1],addOnComma:[Boolean,!0],addOnBlur:[Boolean,!0],addOnPaste:[Boolean,!1],pasteSplitPattern:[RegExp,/,/],allowedTagsPattern:[RegExp,/.+/],enableEditingLastTag:[Boolean,!1],minTags:[Number,0],maxTags:[Number,9007199254740991],displayProperty:[String,"text"],keyProperty:[String,""],allowLeftoverText:[Boolean,!1],addFromAutocompleteOnly:[Boolean,!1],spellcheck:[Boolean,!0]}),$scope.tagList=new function(options,events,onTagAdding,onTagRemoving){var getTagText,setTagText,tagIsValid,self={};return getTagText=function(tag){return tiUtil.safeToString(tag[options.displayProperty])},setTagText=function(tag,text){tag[options.displayProperty]=text},tagIsValid=function(tag){var tagText=getTagText(tag);return tagText&&tagText.length>=options.minLength&&tagText.length<=options.maxLength&&options.allowedTagsPattern.test(tagText)&&!tiUtil.findInObjectArray(self.items,tag,options.keyProperty||options.displayProperty)&&onTagAdding({$tag:tag})},self.items=[],self.addText=function(text){var tag={};return setTagText(tag,text),self.add(tag)},self.add=function(tag){var tagText=getTagText(tag);return options.replaceSpacesWithDashes&&(tagText=tiUtil.replaceSpacesWithDashes(tagText)),setTagText(tag,tagText),tagIsValid(tag)?(self.items.push(tag),events.trigger("tag-added",{$tag:tag})):tagText&&events.trigger("invalid-tag",{$tag:tag}),tag},self.remove=function(index){var tag=self.items[index];if(onTagRemoving({$tag:tag}))return self.items.splice(index,1),self.clearSelection(),events.trigger("tag-removed",{$tag:tag}),tag},self.select=function(index){index<0?index=self.items.length-1:index>=self.items.length&&(index=0),self.index=index,self.selected=self.items[index]},self.selectPrior=function(){self.select(--self.index)},self.selectNext=function(){self.select(++self.index)},self.removeSelected=function(){return self.remove(self.index)},self.clearSelection=function(){self.selected=null,self.index=-1},self.clearSelection(),self}($scope.options,$scope.events,tiUtil.handleUndefinedResult($scope.onTagAdding,!0),tiUtil.handleUndefinedResult($scope.onTagRemoving,!0)),this.registerAutocomplete=function(){$element.find("input");return{addTag:function(tag){return $scope.tagList.add(tag)},focusInput:function(){},getTags:function(){return $scope.tags},getCurrentTagText:function(){return $scope.newTag.text},getOptions:function(){return $scope.options},on:function(name,handler){return $scope.events.on(name,handler),this}}},this.registerTagItem=function(){return{getOptions:function(){return $scope.options},removeTag:function(index){$scope.disabled||$scope.tagList.remove(index)}}}}],link:function(scope,element,attrs,ngModelCtrl){var setElementValidity,hotkeys=[KEYS_enter,KEYS_comma,KEYS_space,KEYS_backspace,KEYS_delete,KEYS_left,KEYS_right],tagList=scope.tagList,events=scope.events,options=scope.options,input=element.find("input"),validationOptions=["minTags","maxTags","allowLeftoverText"];setElementValidity=function(){ngModelCtrl.$setValidity("maxTags",scope.tags.length<=options.maxTags),ngModelCtrl.$setValidity("minTags",scope.tags.length>=options.minTags),ngModelCtrl.$setValidity("leftoverText",!(!scope.hasFocus&&!options.allowLeftoverText)||!scope.newTag.text)},ngModelCtrl.$isEmpty=function(value){return!value||!value.length},scope.newTag={text:"",invalid:null,setText:function(value){this.text=value,events.trigger("input-change",value)}},scope.track=function(tag){return tag[options.keyProperty||options.displayProperty]},scope.$watch("tags",function(value){scope.tags=tiUtil.makeObjectArray(value,options.displayProperty),tagList.items=scope.tags}),scope.$watch("tags.length",function(){setElementValidity()}),attrs.$observe("disabled",function(value){scope.disabled=value}),scope.eventHandlers={input:{change:function(text){events.trigger("input-change",text)},keydown:function($event){events.trigger("input-keydown",$event)},focus:function(){scope.hasFocus||(scope.hasFocus=!0,events.trigger("input-focus"))},blur:function(){$timeout(function(){var activeElement=$document.prop("activeElement"),lostFocusToBrowserWindow=activeElement===input[0],lostFocusToChildElement=element[0].contains(activeElement);!lostFocusToBrowserWindow&&lostFocusToChildElement||(scope.hasFocus=!1,events.trigger("input-blur"))})},paste:function($event){$event.getTextData=function(){var clipboardData=$event.clipboardData||$event.originalEvent&&$event.originalEvent.clipboardData;return clipboardData?clipboardData.getData("text/plain"):$window.clipboardData.getData("Text")},events.trigger("input-paste",$event)}},host:{click:function(){scope.disabled}}},events.on("tag-added",scope.onTagAdded).on("invalid-tag",scope.onInvalidTag).on("tag-removed",scope.onTagRemoved).on("tag-added",function(){scope.newTag.setText("")}).on("tag-added tag-removed",function(){ngModelCtrl.$setViewValue(scope.tags)}).on("invalid-tag",function(){scope.newTag.invalid=!0}).on("option-change",function(e){-1!==validationOptions.indexOf(e.name)&&setElementValidity()}).on("input-change",function(){tagList.clearSelection(),scope.newTag.invalid=null}).on("input-focus",function(){element.triggerHandler("focus"),ngModelCtrl.$setValidity("leftoverText",!0)}).on("input-blur",function(){options.addOnBlur&&!options.addFromAutocompleteOnly&&tagList.addText(scope.newTag.text),element.triggerHandler("blur"),setElementValidity()}).on("input-keydown",function(event){var shouldAdd,shouldRemove,shouldSelect,shouldEditLastTag,key=event.keyCode,addKeys={};if(!(event.shiftKey||event.altKey||event.ctrlKey||event.metaKey)&&-1!==hotkeys.indexOf(key)){if(addKeys[KEYS_enter]=options.addOnEnter,addKeys[KEYS_comma]=options.addOnComma,addKeys[KEYS_space]=options.addOnSpace,shouldAdd=!options.addFromAutocompleteOnly&&addKeys[key],shouldRemove=(key===KEYS_backspace||key===KEYS_delete)&&tagList.selected,shouldEditLastTag=key===KEYS_backspace&&0===scope.newTag.text.length&&options.enableEditingLastTag,shouldSelect=(key===KEYS_backspace||key===KEYS_left||key===KEYS_right)&&0===scope.newTag.text.length&&!options.enableEditingLastTag,shouldAdd)tagList.addText(scope.newTag.text);else if(shouldEditLastTag){var tag;tagList.selectPrior(),(tag=tagList.removeSelected())&&scope.newTag.setText(tag[options.displayProperty])}else shouldRemove?tagList.removeSelected():shouldSelect&&(key===KEYS_left||key===KEYS_backspace?tagList.selectPrior():key===KEYS_right&&tagList.selectNext());(shouldAdd||shouldSelect||shouldRemove||shouldEditLastTag)&&event.preventDefault()}}).on("input-paste",function(event){if(options.addOnPaste){var tags=event.getTextData().split(options.pasteSplitPattern);tags.length>1&&(tags.forEach(function(tag){tagList.addText(tag)}),event.preventDefault())}})}}}]),tagsInput.directive("tiTagItem",["tiUtil",function(tiUtil){return{restrict:"E",require:"^tagsInput",template:'<ng-include src="$$template"></ng-include>',scope:{data:"="},link:function(scope,element,attrs,tagsInputCtrl){var tagsInput=tagsInputCtrl.registerTagItem(),options=tagsInput.getOptions();scope.$$template=options.template,scope.$$removeTagSymbol=options.removeTagSymbol,scope.$getDisplayText=function(){return tiUtil.safeToString(scope.data[options.displayProperty])},scope.$removeTag=function(){tagsInput.removeTag(scope.$index)},scope.$watch("$parent.$index",function(value){scope.$index=value})}}}]),tagsInput.directive("autoComplete",["$document","$timeout","$sce","$q","tagsInputConfig","tiUtil",function($document,$timeout,$sce,$q,tagsInputConfig,tiUtil){return{restrict:"E",require:"^tagsInput",scope:{source:"&"},templateUrl:"ngTagsInput/auto-complete.html",controller:["$scope","$element","$attrs",function($scope,$element,$attrs){$scope.events=tiUtil.simplePubSub(),tagsInputConfig.load("autoComplete",$scope,$attrs,{template:[String,"ngTagsInput/auto-complete-match.html"],debounceDelay:[Number,100],minLength:[Number,3],highlightMatchedText:[Boolean,!0],maxResultsToShow:[Number,10],loadOnDownArrow:[Boolean,!1],loadOnEmpty:[Boolean,!1],loadOnFocus:[Boolean,!1],selectFirstMatch:[Boolean,!0],displayProperty:[String,""]}),$scope.suggestionList=new function(loadFn,options,events){var getDifference,lastPromise,getTagId,self={};return getTagId=function(){return options.tagsInput.keyProperty||options.tagsInput.displayProperty},getDifference=function(array1,array2){return array1.filter(function(item){return!tiUtil.findInObjectArray(array2,item,getTagId(),function(a,b){return options.tagsInput.replaceSpacesWithDashes&&(a=tiUtil.replaceSpacesWithDashes(a),b=tiUtil.replaceSpacesWithDashes(b)),tiUtil.defaultComparer(a,b)})})},self.reset=function(){lastPromise=null,self.items=[],self.visible=!1,self.index=-1,self.selected=null,self.query=null},self.show=function(){options.selectFirstMatch?self.select(0):self.selected=null,self.visible=!0},self.load=tiUtil.debounce(function(query,tags){self.query=query;var promise=$q.when(loadFn({$query:query}));lastPromise=promise,promise.then(function(items){promise===lastPromise&&(items=tiUtil.makeObjectArray(items.data||items,getTagId()),items=getDifference(items,tags),self.items=items.slice(0,options.maxResultsToShow),self.items.length>0?self.show():self.reset())})},options.debounceDelay),self.selectNext=function(){self.select(++self.index)},self.selectPrior=function(){self.select(--self.index)},self.select=function(index){index<0?index=self.items.length-1:index>=self.items.length&&(index=0),self.index=index,self.selected=self.items[index],events.trigger("suggestion-selected",index)},self.reset(),self}($scope.source,$scope.options,$scope.events),this.registerAutocompleteMatch=function(){return{getOptions:function(){return $scope.options},getQuery:function(){return $scope.suggestionList.query}}}}],link:function(scope,element,attrs,tagsInputCtrl){var shouldLoadSuggestions,hotkeys=[KEYS_enter,KEYS_tab,KEYS_escape,KEYS_up,KEYS_down],suggestionList=scope.suggestionList,tagsInput=tagsInputCtrl.registerAutocomplete(),options=scope.options,events=scope.events;options.tagsInput=tagsInput.getOptions(),shouldLoadSuggestions=function(value){return value&&value.length>=options.minLength||!value&&options.loadOnEmpty},scope.addSuggestionByIndex=function(index){suggestionList.select(index),scope.addSuggestion()},scope.addSuggestion=function(){var added=!1;return suggestionList.selected&&(tagsInput.addTag(angular.copy(suggestionList.selected)),suggestionList.reset(),tagsInput.focusInput(),added=!0),added},scope.track=function(item){return item[options.tagsInput.keyProperty||options.tagsInput.displayProperty]},tagsInput.on("tag-added invalid-tag input-blur",function(){suggestionList.reset()}).on("input-change",function(value){shouldLoadSuggestions(value)?suggestionList.load(value,tagsInput.getTags()):suggestionList.reset()}).on("input-focus",function(){var value=tagsInput.getCurrentTagText();options.loadOnFocus&&shouldLoadSuggestions(value)&&suggestionList.load(value,tagsInput.getTags())}).on("input-keydown",function(event){var key=event.keyCode,handled=!1;if(-1!==hotkeys.indexOf(key))return suggestionList.visible?key===KEYS_down?(suggestionList.selectNext(),handled=!0):key===KEYS_up?(suggestionList.selectPrior(),handled=!0):key===KEYS_escape?(suggestionList.reset(),handled=!0):key!==KEYS_enter&&key!==KEYS_tab||(handled=scope.addSuggestion()):key===KEYS_down&&scope.options.loadOnDownArrow&&(suggestionList.load(tagsInput.getCurrentTagText(),tagsInput.getTags()),handled=!0),handled?(event.preventDefault(),event.stopImmediatePropagation(),!1):void 0}),events.on("suggestion-selected",function(index){!function(root,index){var element=root.find("li").eq(index),parent=element.parent(),elementTop=element.prop("offsetTop"),elementHeight=element.prop("offsetHeight"),parentHeight=parent.prop("clientHeight"),parentScrollTop=parent.prop("scrollTop");elementTop<parentScrollTop?parent.prop("scrollTop",elementTop):elementTop+elementHeight>parentHeight+parentScrollTop&&parent.prop("scrollTop",elementTop+elementHeight-parentHeight)}(element,index)})}}}]),tagsInput.directive("tiAutocompleteMatch",["$sce","tiUtil",function($sce,tiUtil){return{restrict:"E",require:"^autoComplete",template:'<ng-include src="$$template"></ng-include>',scope:{data:"="},link:function(scope,element,attrs,autoCompleteCtrl){var autoComplete=autoCompleteCtrl.registerAutocompleteMatch(),options=autoComplete.getOptions();scope.$$template=options.template,scope.$index=scope.$parent.$index,scope.$highlight=function(text){return options.highlightMatchedText&&(text=tiUtil.safeHighlight(text,autoComplete.getQuery())),$sce.trustAsHtml(text)},scope.$getDisplayText=function(){return tiUtil.safeToString(scope.data[options.displayProperty||options.tagsInput.displayProperty])}}}}]),tagsInput.directive("tiTranscludeAppend",function(){return function(scope,element,attrs,ctrl,transcludeFn){transcludeFn(function(clone){element.append(clone)})}}),tagsInput.directive("tiAutosize",["tagsInputConfig",function(tagsInputConfig){return{restrict:"A",require:"ngModel",link:function(scope,element,attrs,ctrl){var span,resize,threshold=tagsInputConfig.getTextAutosizeThreshold();(span=angular.element('<span class="input"></span>')).css("display","none").css("visibility","hidden").css("width","auto").css("white-space","pre"),element.parent().append(span),resize=function(originalValue){var width,value=originalValue;return angular.isString(value)&&0===value.length&&(value=attrs.placeholder),value&&(span.text(value),span.css("display",""),width=span.prop("offsetWidth"),span.css("display","none")),element.css("width",width?width+threshold+"px":""),originalValue},ctrl.$parsers.unshift(resize),ctrl.$formatters.unshift(resize),attrs.$observe("placeholder",function(value){ctrl.$modelValue||resize(value)})}}}]),tagsInput.directive("tiBindAttrs",function(){return function(scope,element,attrs){scope.$watch(attrs.tiBindAttrs,function(value){angular.forEach(value,function(value,key){"type"===key?element[0].type=value:attrs.$set(key,value)})},!0)}}),tagsInput.provider("tagsInputConfig",function(){var globalDefaults={},interpolationStatus={},autosizeThreshold=3;this.setDefaults=function(directive,defaults){return globalDefaults[directive]=defaults,this},this.setActiveInterpolation=function(directive,options){return interpolationStatus[directive]=options,this},this.setTextAutosizeThreshold=function(threshold){return autosizeThreshold=threshold,this},this.$get=["$interpolate",function($interpolate){var converters={};return converters[String]=function(value){return value},converters[Number]=function(value){return parseInt(value,10)},converters[Boolean]=function(value){return"true"===value.toLowerCase()},converters[RegExp]=function(value){return new RegExp(value)},{load:function(directive,scope,attrs,options){var defaultValidator=function(){return!0};scope.options={},angular.forEach(options,function(value,key){var type,localDefault,validator,converter,getDefault,updateValue;type=value[0],localDefault=value[1],validator=value[2]||defaultValidator,converter=converters[type],getDefault=function(){var globalValue=globalDefaults[directive]&&globalDefaults[directive][key];return angular.isDefined(globalValue)?globalValue:localDefault},updateValue=function(value){scope.options[key]=value&&validator(value)?converter(value):getDefault()},interpolationStatus[directive]&&interpolationStatus[directive][key]?attrs.$observe(key,function(value){updateValue(value),scope.events.trigger("option-change",{name:key,newValue:value})}):updateValue(attrs[key]&&$interpolate(attrs[key])(scope.$parent))})},getTextAutosizeThreshold:function(){return autosizeThreshold}}}]}),tagsInput.factory("tiUtil",["$timeout",function($timeout){var self={debounce:function(fn,delay){var timeoutId;return function(){var args=arguments;$timeout.cancel(timeoutId),timeoutId=$timeout(function(){fn.apply(null,args)},delay)}},makeObjectArray:function(array,key){return(array=array||[]).length>0&&!angular.isObject(array[0])&&array.forEach(function(item,index){array[index]={},array[index][key]=item}),array},findInObjectArray:function(array,obj,key,comparer){var item=null;return comparer=comparer||self.defaultComparer,array.some(function(element){if(comparer(element[key],obj[key]))return item=element,!0}),item},defaultComparer:function(a,b){return self.safeToString(a).toLowerCase()===self.safeToString(b).toLowerCase()},safeHighlight:function(str,value){if(!value)return str;str=self.encodeHTML(str),value=self.encodeHTML(value);var expression=new RegExp("&[^;]+;|"+function(str){return str.replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")}(value),"gi");return str.replace(expression,function(match){return match.toLowerCase()===value.toLowerCase()?"<em>"+match+"</em>":match})},safeToString:function(value){return angular.isUndefined(value)||null==value?"":value.toString().trim()},encodeHTML:function(value){return self.safeToString(value).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")},handleUndefinedResult:function(fn,valueIfUndefined){return function(){var result=fn.apply(null,arguments);return angular.isUndefined(result)?valueIfUndefined:result}},replaceSpacesWithDashes:function(str){return self.safeToString(str).replace(/\s/g,"-")},simplePubSub:function(){var events={};return{on:function(names,handler){return names.split(" ").forEach(function(name){events[name]||(events[name]=[]),events[name].push(handler)}),this},trigger:function(name,args){return(events[name]||[]).every(function(handler){return self.handleUndefinedResult(handler,!0)(args)}),this}}}};return self}]),tagsInput.run(["$templateCache",function($templateCache){$templateCache.put("ngTagsInput/tags-input.html",'<div class="host" tabindex="-1" data-ng-click="eventHandlers.host.click()" ti-transclude-append=""><div class="tags" data-ng-class="{focused: hasFocus}"><ul class="tag-list"><li class="tag-item" data-ng-repeat="tag in tagList.items track by track(tag)" data-ng-class="{ selected: tag == tagList.selected }"><ti-tag-item data="tag"></ti-tag-item></li></ul><input class="input u-no-margin--top" autocomplete="off" data-ng-model="newTag.text" data-ng-change="eventHandlers.input.change(newTag.text)" data-ng-keydown="eventHandlers.input.keydown($event)" data-ng-focus="eventHandlers.input.focus($event)" data-ng-blur="eventHandlers.input.blur($event)" data-ng-paste="eventHandlers.input.paste($event)" data-ng-trim="false" data-ng-class="{\'invalid-tag\': newTag.invalid}" data-ng-disabled="disabled" ti-bind-attrs="{type: options.type, placeholder: options.placeholder, tabindex: options.tabindex, spellcheck: options.spellcheck}" ti-autosize=""></div></div>'),$templateCache.put("ngTagsInput/tag-item.html",'<span ng-bind="$getDisplayText()"></span> <a class="p-icon--close" data-ng-click="$removeTag()" data-ng-bind="$$removeTagSymbol">Remove tag</a>'),$templateCache.put("ngTagsInput/auto-complete.html",'<div class="autocomplete" data-ng-if="suggestionList.visible"><ul class="p-list suggestion-list"><li class="suggestion-item" data-ng-repeat="item in suggestionList.items track by track(item)" data-ng-class="{selected: item == suggestionList.selected}" data-ng-click="addSuggestionByIndex($index)" data-ng-mouseenter="suggestionList.select($index)"><ti-autocomplete-match data="item"></ti-autocomplete-match></li></ul></div>'),$templateCache.put("ngTagsInput/auto-complete-match.html",'<span data-ng-bind-html="$highlight($getDisplayText())"></span>')}])}()},"./src/maasserver/static/js/angular/3rdparty/vs-repeat.js":function(module,exports){!function(window,angular){"use strict";var dde=document.documentElement,matchingFunction=dde.matches?"matches":dde.matchesSelector?"matchesSelector":dde.webkitMatches?"webkitMatches":dde.webkitMatchesSelector?"webkitMatchesSelector":dde.msMatches?"msMatches":dde.msMatchesSelector?"msMatchesSelector":dde.mozMatches?"mozMatches":dde.mozMatchesSelector?"mozMatchesSelector":null,closestElement=angular.element.prototype.closest||function(selector){for(var el=this[0].parentNode;el!==document.documentElement&&null!=el&&!el[matchingFunction](selector);)el=el.parentNode;return el&&el[matchingFunction](selector)?angular.element(el):angular.element()};function getWindowScroll(){if("pageYOffset"in window)return{scrollTop:pageYOffset,scrollLeft:pageXOffset};var sx,d=document,r=d.documentElement,b=d.body;return sx=r.scrollLeft||b.scrollLeft||0,{scrollTop:r.scrollTop||b.scrollTop||0,scrollLeft:sx}}function getClientSize(element,sizeProp){return element===window?"clientWidth"===sizeProp?window.innerWidth:window.innerHeight:element[sizeProp]}var vsRepeatModule=angular.module("vs-repeat",[]).directive("vsRepeat",["$compile","$parse",function($compile,$parse){return{restrict:"A",scope:!0,compile:function($element,$attrs){var ngRepeatExpression,expressionMatches,lhs,rhs,rhsSuffix,originalNgRepeatAttr,repeatContainer=angular.isDefined($attrs.vsRepeatContainer)?angular.element($element[0].querySelector($attrs.vsRepeatContainer)):$element,ngRepeatChild=repeatContainer.children().eq(0),childCloneHtml=ngRepeatChild[0].outerHTML,collectionName="$vs_collection",isNgRepeatStart=!1,attributesDictionary={vsRepeat:"elementSize",vsOffsetBefore:"offsetBefore",vsOffsetAfter:"offsetAfter",vsScrolledToEndOffset:"scrolledToEndOffset",vsScrolledToBeginningOffset:"scrolledToBeginningOffset",vsExcess:"excess"};if(ngRepeatChild.attr("ng-repeat"))originalNgRepeatAttr="ng-repeat",ngRepeatExpression=ngRepeatChild.attr("ng-repeat");else if(ngRepeatChild.attr("data-ng-repeat"))originalNgRepeatAttr="data-ng-repeat",ngRepeatExpression=ngRepeatChild.attr("data-ng-repeat");else if(ngRepeatChild.attr("ng-repeat-start"))isNgRepeatStart=!0,originalNgRepeatAttr="ng-repeat-start",ngRepeatExpression=ngRepeatChild.attr("ng-repeat-start");else{if(!ngRepeatChild.attr("data-ng-repeat-start"))throw new Error("angular-vs-repeat: no ng-repeat directive on a child element");isNgRepeatStart=!0,originalNgRepeatAttr="data-ng-repeat-start",ngRepeatExpression=ngRepeatChild.attr("data-ng-repeat-start")}if(expressionMatches=/^\s*(\S+)\s+in\s+([\S\s]+?)(track\s+by\s+\S+)?$/.exec(ngRepeatExpression),lhs=expressionMatches[1],rhs=expressionMatches[2],rhsSuffix=expressionMatches[3],isNgRepeatStart)for(var index=0,repeaterElement=repeatContainer.children().eq(0);null==repeaterElement.attr("ng-repeat-end")&&null==repeaterElement.attr("data-ng-repeat-end");)index++,repeaterElement=repeatContainer.children().eq(index),childCloneHtml+=repeaterElement[0].outerHTML;return repeatContainer.empty(),{pre:function($scope,$element,$attrs){var originalLength,_prevStartIndex,_prevEndIndex,_minStartIndex,_maxEndIndex,_prevClientSize,repeatContainer=angular.isDefined($attrs.vsRepeatContainer)?angular.element($element[0].querySelector($attrs.vsRepeatContainer)):$element,childClone=angular.element(childCloneHtml),childTagName=childClone[0].tagName.toLowerCase(),originalCollection=[],$$horizontal=void 0!==$attrs.vsHorizontal,$beforeContent=angular.element("<"+childTagName+' class="vs-repeat-before-content"></'+childTagName+">"),$afterContent=angular.element("<"+childTagName+' class="vs-repeat-after-content"></'+childTagName+">"),autoSize=!$attrs.vsRepeat,sizesPropertyExists=!!$attrs.vsSize||!!$attrs.vsSizeProperty,$scrollParent=$attrs.vsScrollParent?"window"===$attrs.vsScrollParent?angular.element(window):closestElement.call(repeatContainer,$attrs.vsScrollParent):repeatContainer,$$options="vsOptions"in $attrs?$scope.$eval($attrs.vsOptions):{},clientSize=$$horizontal?"clientWidth":"clientHeight",offsetSize=$$horizontal?"offsetWidth":"offsetHeight",scrollPos=$$horizontal?"scrollLeft":"scrollTop";if($scope.totalSize=0,!("vsSize"in $attrs)&&"vsSizeProperty"in $attrs&&console.warn("vs-size-property attribute is deprecated. Please use vs-size attribute which also accepts angular expressions."),0===$scrollParent.length)throw"Specified scroll parent selector did not match any element";function refresh(){if(!originalCollection||originalCollection.length<1)$scope[collectionName]=[],originalLength=0,$scope.sizesCumulative=[0];else if(originalLength=originalCollection.length,sizesPropertyExists){$scope.sizes=originalCollection.map(function(item){var s=$scope.$new(!1);angular.extend(s,item),s[lhs]=item;var size=$attrs.vsSize||$attrs.vsSizeProperty?s.$eval($attrs.vsSize||$attrs.vsSizeProperty):$scope.elementSize;return s.$destroy(),size});var sum=0;$scope.sizesCumulative=$scope.sizes.map(function(size){var res=sum;return sum+=size,res}),$scope.sizesCumulative.push(sum)}else setAutoSize();reinitialize()}function setAutoSize(){autoSize&&$scope.$$postDigest(function(){if(repeatContainer[0].offsetHeight||repeatContainer[0].offsetWidth){for(var children=repeatContainer.children(),i=0,gotSomething=!1,insideStartEndSequence=!1;i<children.length;){if(null!=children[i].attributes[originalNgRepeatAttr]||insideStartEndSequence){if(gotSomething||($scope.elementSize=0),gotSomething=!0,children[i][offsetSize]&&($scope.elementSize+=children[i][offsetSize]),!isNgRepeatStart)break;if(null!=children[i].attributes["ng-repeat-end"]||null!=children[i].attributes["data-ng-repeat-end"])break;insideStartEndSequence=!0}i++}gotSomething&&(reinitialize(),autoSize=!1,$scope.$root&&!$scope.$root.$$phase&&$scope.$apply())}else var dereg=$scope.$watch(function(){(repeatContainer[0].offsetHeight||repeatContainer[0].offsetWidth)&&(dereg(),setAutoSize())})})}function getLayoutProp(){var layoutPropPrefix="tr"===childTagName?"":"min-";return $$horizontal?layoutPropPrefix+"width":layoutPropPrefix+"height"}function scrollHandler(){updateInnerCollection()&&$scope.$digest()}function onWindowResize(){void 0!==$attrs.vsAutoresize&&(autoSize=!0,setAutoSize(),$scope.$root&&!$scope.$root.$$phase&&$scope.$apply()),updateInnerCollection()&&$scope.$apply()}function reinitialize(){var size;_prevStartIndex=void 0,_prevEndIndex=void 0,_minStartIndex=originalLength,_maxEndIndex=0,size=sizesPropertyExists?$scope.sizesCumulative[originalLength]:$scope.elementSize*originalLength,$scope.totalSize=$scope.offsetBefore+size+$scope.offsetAfter,updateInnerCollection(),$scope.$emit("vsRepeatReinitialized",$scope.startIndex,$scope.endIndex)}function reinitOnClientHeightChange(){var ch=getClientSize($scrollParent[0],clientSize);ch!==_prevClientSize&&(reinitialize(),$scope.$root&&!$scope.$root.$$phase&&$scope.$apply()),_prevClientSize=ch}function updateInnerCollection(){var element,scrollProp,vsElement,scrollElement,isHorizontal,$scrollPosition=(element=$scrollParent[0],scrollProp=scrollPos,element===window?getWindowScroll()[scrollProp]:element[scrollProp]),$clientSize=getClientSize($scrollParent[0],clientSize),scrollOffset=repeatContainer[0]===$scrollParent[0]?0:(vsElement=repeatContainer[0],scrollElement=$scrollParent[0],isHorizontal=$$horizontal,vsElement.getBoundingClientRect()[isHorizontal?"left":"top"]-(scrollElement===window?0:scrollElement.getBoundingClientRect()[isHorizontal?"left":"top"])+(scrollElement===window?getWindowScroll():scrollElement)[isHorizontal?"scrollLeft":"scrollTop"]),__startIndex=$scope.startIndex,__endIndex=$scope.endIndex;if(sizesPropertyExists){for(__startIndex=0;$scope.sizesCumulative[__startIndex]<$scrollPosition-$scope.offsetBefore-scrollOffset;)__startIndex++;for(__startIndex>0&&__startIndex--,__endIndex=__startIndex=Math.max(Math.floor(__startIndex-$scope.excess/2),0);$scope.sizesCumulative[__endIndex]<$scrollPosition-$scope.offsetBefore-scrollOffset+$clientSize;)__endIndex++;__endIndex=Math.min(Math.ceil(__endIndex+$scope.excess/2),originalLength)}else __startIndex=Math.max(Math.floor(($scrollPosition-$scope.offsetBefore-scrollOffset)/$scope.elementSize)-$scope.excess/2,0),__endIndex=Math.min(__startIndex+Math.ceil($clientSize/$scope.elementSize)+$scope.excess,originalLength);_minStartIndex=Math.min(__startIndex,_minStartIndex),_maxEndIndex=Math.max(__endIndex,_maxEndIndex),$scope.startIndex=$$options.latch?_minStartIndex:__startIndex,$scope.endIndex=$$options.latch?_maxEndIndex:__endIndex;var digestRequired=!1;if(null==_prevStartIndex?digestRequired=!0:null==_prevEndIndex&&(digestRequired=!0),digestRequired||($$options.hunked?Math.abs($scope.startIndex-_prevStartIndex)>=$scope.excess/2||0===$scope.startIndex&&0!==_prevStartIndex?digestRequired=!0:(Math.abs($scope.endIndex-_prevEndIndex)>=$scope.excess/2||$scope.endIndex===originalLength&&_prevEndIndex!==originalLength)&&(digestRequired=!0):digestRequired=$scope.startIndex!==_prevStartIndex||$scope.endIndex!==_prevEndIndex),digestRequired){var triggerIndex;$scope[collectionName]=originalCollection.slice($scope.startIndex,$scope.endIndex),$scope.$emit("vsRepeatInnerCollectionUpdated",$scope.startIndex,$scope.endIndex,_prevStartIndex,_prevEndIndex),$attrs.vsScrolledToEnd&&(triggerIndex=originalCollection.length-($scope.scrolledToEndOffset||0),($scope.endIndex>=triggerIndex&&_prevEndIndex<triggerIndex||originalCollection.length&&$scope.endIndex===originalCollection.length)&&$scope.$eval($attrs.vsScrolledToEnd)),$attrs.vsScrolledToBeginning&&(triggerIndex=$scope.scrolledToBeginningOffset||0,$scope.startIndex<=triggerIndex&&_prevStartIndex>$scope.startIndex&&$scope.$eval($attrs.vsScrolledToBeginning)),_prevStartIndex=$scope.startIndex,_prevEndIndex=$scope.endIndex;var parsed=$parse(sizesPropertyExists?"(sizesCumulative[$index + startIndex] + offsetBefore)":"(($index + startIndex) * elementSize + offsetBefore)"),o1=parsed($scope,{$index:0}),o2=parsed($scope,{$index:$scope[collectionName].length}),total=$scope.totalSize;$beforeContent.css(getLayoutProp(),o1+"px"),$afterContent.css(getLayoutProp(),total-o2+"px")}return digestRequired}$scope.$scrollParent=$scrollParent,sizesPropertyExists&&($scope.sizesCumulative=[]),$scope.elementSize=+$attrs.vsRepeat||getClientSize($scrollParent[0],clientSize)||50,$scope.offsetBefore=0,$scope.offsetAfter=0,$scope.excess=2,$$horizontal?($beforeContent.css("height","100%"),$afterContent.css("height","100%")):($beforeContent.css("width","100%"),$afterContent.css("width","100%")),Object.keys(attributesDictionary).forEach(function(key){$attrs[key]&&$attrs.$observe(key,function(value){$scope[attributesDictionary[key]]=+value,reinitialize()})}),$scope.$watchCollection(rhs,function(coll){originalCollection=coll||[],refresh()}),childClone.eq(0).attr(originalNgRepeatAttr,lhs+" in "+collectionName+(rhsSuffix?" "+rhsSuffix:"")),childClone.addClass("vs-repeat-repeated-element"),repeatContainer.append($beforeContent),repeatContainer.append(childClone),$compile(childClone)($scope),repeatContainer.append($afterContent),$scope.startIndex=0,$scope.endIndex=0,$scrollParent.on("scroll",scrollHandler),angular.element(window).on("resize",onWindowResize),$scope.$on("$destroy",function(){angular.element(window).off("resize",onWindowResize),$scrollParent.off("scroll",scrollHandler)}),$scope.$on("vsRepeatTrigger",refresh),$scope.$on("vsRepeatResize",function(){autoSize=!0,setAutoSize()}),$scope.$on("vsRenderAll",function(){$$options.latch&&setTimeout(function(){var __endIndex=originalLength;_maxEndIndex=Math.max(__endIndex,_maxEndIndex),$scope.endIndex=$$options.latch?_maxEndIndex:__endIndex,$scope[collectionName]=originalCollection.slice($scope.startIndex,$scope.endIndex),_prevEndIndex=$scope.endIndex,$scope.$$postDigest(function(){$beforeContent.css(getLayoutProp(),0),$afterContent.css(getLayoutProp(),0)}),$scope.$apply(function(){$scope.$emit("vsRenderAllDone")})})}),$scope.$watch(function(){"function"==typeof window.requestAnimationFrame?window.requestAnimationFrame(reinitOnClientHeightChange):reinitOnClientHeightChange()})}}}}}]);void 0!==module&&module.exports&&(module.exports=vsRepeatModule.name)}(window,window.angular)},0:function(module,exports,__webpack_require__){__webpack_require__("./src/maasserver/static/js/angular/3rdparty/ng-tags-input.js"),module.exports=__webpack_require__("./src/maasserver/static/js/angular/3rdparty/vs-repeat.js")}}); |
1274 | 2 | //# sourceMappingURL=vendor-min.js.map | 2 | //# sourceMappingURL=vendor-min.js.map |
1275 | 3 | \ No newline at end of file | 3 | \ No newline at end of file |
1276 | diff --git a/src/maasserver/static/js/bundle/vendor-min.js.map b/src/maasserver/static/js/bundle/vendor-min.js.map | |||
1277 | index 4d387bd..3cb19d2 100644 | |||
1278 | --- a/src/maasserver/static/js/bundle/vendor-min.js.map | |||
1279 | +++ b/src/maasserver/static/js/bundle/vendor-min.js.map | |||
1280 | @@ -1 +1 @@ | |||
1281 | 1 | {"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/maasserver/static/js/angular/3rdparty/ng-tags-input.js","webpack:///./src/maasserver/static/js/angular/3rdparty/vs-repeat.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","r","value","n","__esModule","object","property","prototype","hasOwnProperty","p","s","KEYS","SUPPORTED_INPUT_TYPES","tagsInput","angular","directive","$timeout","$document","$window","tagsInputConfig","tiUtil","validateType","type","indexOf","restrict","require","scope","tags","onTagAdding","onTagAdded","onInvalidTag","onTagRemoving","onTagRemoved","replace","transclude","templateUrl","controller","$scope","$attrs","$element","events","simplePubSub","load","template","String","placeholder","tabindex","Number","removeTagSymbol","fromCharCode","replaceSpacesWithDashes","Boolean","minLength","maxLength","addOnEnter","addOnSpace","addOnComma","addOnBlur","addOnPaste","pasteSplitPattern","RegExp","allowedTagsPattern","enableEditingLastTag","minTags","maxTags","displayProperty","keyProperty","allowLeftoverText","addFromAutocompleteOnly","spellcheck","tagList","options","getTagText","setTagText","tagIsValid","self","tag","safeToString","text","tagText","length","test","findInObjectArray","items","$tag","addText","add","push","trigger","remove","index","splice","clearSelection","select","selected","selectPrior","selectNext","removeSelected","handleUndefinedResult","this","registerAutocomplete","find","addTag","focusInput","getTags","getCurrentTagText","newTag","getOptions","on","handler","registerTagItem","removeTag","disabled","link","element","attrs","ngModelCtrl","setElementValidity","hotkeys","input","validationOptions","$setValidity","hasFocus","$isEmpty","invalid","setText","track","$watch","makeObjectArray","$observe","eventHandlers","change","keydown","$event","focus","blur","activeElement","prop","lostFocusToBrowserWindow","lostFocusToChildElement","contains","paste","getTextData","clipboardData","originalEvent","getData","host","click","$setViewValue","e","triggerHandler","event","shouldAdd","shouldRemove","shouldSelect","shouldEditLastTag","key","keyCode","addKeys","shiftKey","altKey","ctrlKey","metaKey","preventDefault","split","forEach","data","tagsInputCtrl","$$template","$$removeTagSymbol","$getDisplayText","$removeTag","$index","$sce","$q","source","debounceDelay","highlightMatchedText","maxResultsToShow","loadOnDownArrow","loadOnEmpty","loadOnFocus","selectFirstMatch","suggestionList","loadFn","getDifference","lastPromise","getTagId","array1","array2","filter","item","a","b","defaultComparer","reset","visible","query","show","debounce","promise","when","$query","then","slice","registerAutocompleteMatch","getQuery","shouldLoadSuggestions","addSuggestionByIndex","addSuggestion","added","copy","handled","stopImmediatePropagation","root","eq","parent","elementTop","elementHeight","parentHeight","parentScrollTop","scrollToElement","autoCompleteCtrl","autoComplete","$parent","$highlight","safeHighlight","trustAsHtml","ctrl","transcludeFn","clone","append","span","resize","threshold","getTextAutosizeThreshold","css","originalValue","width","isString","$parsers","unshift","$formatters","$modelValue","tiBindAttrs","$set","provider","globalDefaults","interpolationStatus","autosizeThreshold","setDefaults","defaults","setActiveInterpolation","setTextAutosizeThreshold","$get","$interpolate","converters","parseInt","toLowerCase","defaultValidator","localDefault","validator","converter","getDefault","updateValue","globalValue","isDefined","newValue","factory","fn","delay","timeoutId","args","arguments","cancel","apply","array","isObject","obj","comparer","some","str","encodeHTML","expression","escapeRegexChars","match","isUndefined","toString","trim","valueIfUndefined","result","names","every","run","$templateCache","put","_extends","assign","target","_slicedToArray","arr","Array","isArray","Symbol","iterator","_arr","_n","_d","_e","undefined","_s","_i","next","done","err","_sliceIterator","TypeError","window","closestElement","closest","matchingFunction","reduce","res","_res","document","documentElement","selector","_el","el","parentNode","getWindowScroll","_ref","_document$documentEle","_ref2","_document$documentEle2","scrollTop","pageYOffset","scrollLeft","pageXOffset","body","getClientSize","sizeProp","innerWidth","innerHeight","attrDeprecated","attrname","message","console","warn","concat","printDeprecationWarning","defaultOptions","latch","container","scrollParent","size","offsetBefore","offsetAfter","scrolledToBeginning","noop","scrolledToEnd","scrolledToBeginningOffset","scrolledToEndOffset","scrollMargin","horizontal","autoresize","hunked","hunkSize","vsRepeatModule","$compile","$parse","compile","compileElement","compileAttrs","compileRepeatContainer","querySelector","vsRepeatContainer","repeatContainerChildren","children","ngRepeatChild","childCloneHtml","outerHTML","collectionName","_analyzeNgRepeatUsage2","opt","attr","Error","analyzeNgRepeatUsage","originalNgRepeatAttr","ngRepeatExpression","isNgRepeatStart","_expressionMatches","exec","lhs","rhs","rhsSuffix","repeaterElement","empty","pre","_$scope$$eval","_parseSize","getSize","parsed","writable","vsRepeat","$eval","originalLength","repeatContainer","childClone","childTagName","tagName","originalCollection","$beforeContent","$afterContent","autosizingRequired","$scrollParent","clientSize","offsetSize","scrollSize","scrollPos","totalSize","sizesCumulative","debug","$debugParent","$debug","$on","_prevStartIndex","_prevEndIndex","_minStartIndex","_maxEndIndex","_prevClientSize","measuredSize","refresh","_mapSize","getFromMeasured","reinitialize","hardSize","sizes","map","_hardSize","sum","arr2","from","_toConsumableArray","$$postDigest","offsetHeight","offsetWidth","gotSomething","insideStartEndSequence","attributes","$root","$$phase","$digest","dereg","getLayoutProps","layoutProp","acc","scrollHandler","pos","updateInnerCollection","_ensureScrollIntegrity","onWindowResize","$emit","startIndex","endIndex","reinitOnClientHeightChange","ch","binaryFind","Math","floor","scrollProp","$scrollPosition","$clientSize","vsElement","scrollElement","isHorizontal","scrollOffset","getBoundingClientRect","__startIndex","__endIndex","requestAnimationFrame","expectedSize","compStyle","getComputedStyle","paddings","containerSize","relativeScroll","max","min","digestRequired","abs","triggerIndex","o1","o2","total","vsRepeatOptions","$watchCollection","newOpts","mergedOptions","JSON","stringify","coll","addClass","off","setTimeout","head"],"mappings":"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","file":"vendor-min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","/*!\n * ngTagsInput v2.3.0\n * http://mbenford.github.io/ngTagsInput\n *\n * Copyright (c) 2013-2015 Michael Benford\n * License: MIT\n *\n * Generated at 2015-03-24 00:49:44 -0300\n */\n(function() {\n'use strict';\n\nvar KEYS = {\n backspace: 8,\n tab: 9,\n enter: 13,\n escape: 27,\n space: 32,\n up: 38,\n down: 40,\n left: 37,\n right: 39,\n delete: 46,\n comma: 188\n};\n\nvar MAX_SAFE_INTEGER = 9007199254740991;\nvar SUPPORTED_INPUT_TYPES = ['text', 'email', 'url'];\n\nvar tagsInput = angular.module('ngTagsInput', []);\n\n/**\n * @ngdoc directive\n * @name tagsInput\n * @module ngTagsInput\n *\n * @description\n * Renders an input box with tag editing support.\n *\n * @param {string} ngModel Assignable angular expression to data-bind to.\n * @param {string=} [displayProperty=text] Property to be rendered as the tag label.\n * @param {string=} [keyProperty=text] Property to be used as a unique identifier for the tag.\n * @param {string=} [type=text] Type of the input element. Only 'text', 'email' and 'url' are supported values.\n * @param {number=} tabindex Tab order of the control.\n * @param {string=} [placeholder=Add a tag] Placeholder text for the control.\n * @param {number=} [minLength=3] Minimum length for a new tag.\n * @param {number=} [maxLength=MAX_SAFE_INTEGER] Maximum length allowed for a new tag.\n * @param {number=} [minTags=0] Sets minTags validation error key if the number of tags added is less than minTags.\n * @param {number=} [maxTags=MAX_SAFE_INTEGER] Sets maxTags validation error key if the number of tags added is greater than maxTags.\n * @param {boolean=} [allowLeftoverText=false] Sets leftoverText validation error key if there is any leftover text in\n * the input element when the directive loses focus.\n * @param {string=} [removeTagSymbol=×] Symbol character for the remove tag button.\n * @param {boolean=} [addOnEnter=true] Flag indicating that a new tag will be added on pressing the ENTER key.\n * @param {boolean=} [addOnSpace=false] Flag indicating that a new tag will be added on pressing the SPACE key.\n * @param {boolean=} [addOnComma=true] Flag indicating that a new tag will be added on pressing the COMMA key.\n * @param {boolean=} [addOnBlur=true] Flag indicating that a new tag will be added when the input field loses focus.\n * @param {boolean=} [addOnPaste=false] Flag indicating that the text pasted into the input field will be split into tags.\n * @param {string=} [pasteSplitPattern=,] Regular expression used to split the pasted text into tags.\n * @param {boolean=} [replaceSpacesWithDashes=true] Flag indicating that spaces will be replaced with dashes.\n * @param {string=} [allowedTagsPattern=.+] Regular expression that determines whether a new tag is valid.\n * @param {boolean=} [enableEditingLastTag=false] Flag indicating that the last tag will be moved back into\n * the new tag input box instead of being removed when the backspace key\n * is pressed and the input box is empty.\n * @param {boolean=} [addFromAutocompleteOnly=false] Flag indicating that only tags coming from the autocomplete list will be allowed.\n * When this flag is true, addOnEnter, addOnComma, addOnSpace, addOnBlur and\n * allowLeftoverText values are ignored.\n * @param {boolean=} [spellcheck=true] Flag indicating whether the browser's spellcheck is enabled for the input field or not.\n * @param {expression} onTagAdding Expression to evaluate that will be invoked before adding a new tag. The new tag is available as $tag. This method must return either true or false. If false, the tag will not be added.\n * @param {expression} onTagAdded Expression to evaluate upon adding a new tag. The new tag is available as $tag.\n * @param {expression} onInvalidTag Expression to evaluate when a tag is invalid. The invalid tag is available as $tag.\n * @param {expression} onTagRemoving Expression to evaluate that will be invoked before removing a tag. The tag is available as $tag. This method must return either true or false. If false, the tag will not be removed.\n * @param {expression} onTagRemoved Expression to evaluate upon removing an existing tag. The removed tag is available as $tag.\n */\ntagsInput.directive('tagsInput', [\"$timeout\",\"$document\",\"$window\",\"tagsInputConfig\",\"tiUtil\", function($timeout, $document, $window, tagsInputConfig, tiUtil) {\n function TagList(options, events, onTagAdding, onTagRemoving) {\n var self = {}, getTagText, setTagText, tagIsValid;\n\n getTagText = function(tag) {\n return tiUtil.safeToString(tag[options.displayProperty]);\n };\n\n setTagText = function(tag, text) {\n tag[options.displayProperty] = text;\n };\n\n tagIsValid = function(tag) {\n var tagText = getTagText(tag);\n\n return tagText &&\n tagText.length >= options.minLength &&\n tagText.length <= options.maxLength &&\n options.allowedTagsPattern.test(tagText) &&\n !tiUtil.findInObjectArray(self.items, tag, options.keyProperty || options.displayProperty) &&\n onTagAdding({ $tag: tag });\n };\n\n self.items = [];\n\n self.addText = function(text) {\n var tag = {};\n setTagText(tag, text);\n return self.add(tag);\n };\n\n self.add = function(tag) {\n var tagText = getTagText(tag);\n\n if (options.replaceSpacesWithDashes) {\n tagText = tiUtil.replaceSpacesWithDashes(tagText);\n }\n\n setTagText(tag, tagText);\n\n if (tagIsValid(tag)) {\n self.items.push(tag);\n events.trigger('tag-added', { $tag: tag });\n }\n else if (tagText) {\n events.trigger('invalid-tag', { $tag: tag });\n }\n\n return tag;\n };\n\n self.remove = function(index) {\n var tag = self.items[index];\n\n if (onTagRemoving({ $tag: tag })) {\n self.items.splice(index, 1);\n self.clearSelection();\n events.trigger('tag-removed', { $tag: tag });\n return tag;\n }\n };\n\n self.select = function(index) {\n if (index < 0) {\n index = self.items.length - 1;\n }\n else if (index >= self.items.length) {\n index = 0;\n }\n\n self.index = index;\n self.selected = self.items[index];\n };\n\n self.selectPrior = function() {\n self.select(--self.index);\n };\n\n self.selectNext = function() {\n self.select(++self.index);\n };\n\n self.removeSelected = function() {\n return self.remove(self.index);\n };\n\n self.clearSelection = function() {\n self.selected = null;\n self.index = -1;\n };\n\n self.clearSelection();\n\n return self;\n }\n\n function validateType(type) {\n return SUPPORTED_INPUT_TYPES.indexOf(type) !== -1;\n }\n\n return {\n restrict: 'E',\n require: 'ngModel',\n scope: {\n tags: '=ngModel',\n onTagAdding: '&',\n onTagAdded: '&',\n onInvalidTag: '&',\n onTagRemoving: '&',\n onTagRemoved: '&'\n },\n replace: false,\n transclude: true,\n templateUrl: 'ngTagsInput/tags-input.html',\n controller: [\"$scope\",\"$attrs\",\"$element\", function($scope, $attrs, $element) {\n $scope.events = tiUtil.simplePubSub();\n\n tagsInputConfig.load('tagsInput', $scope, $attrs, {\n template: [String, 'ngTagsInput/tag-item.html'],\n type: [String, 'text', validateType],\n placeholder: [String, 'Add a tag'],\n tabindex: [Number, null],\n removeTagSymbol: [String, String.fromCharCode(215)],\n replaceSpacesWithDashes: [Boolean, true],\n minLength: [Number, 3],\n maxLength: [Number, MAX_SAFE_INTEGER],\n addOnEnter: [Boolean, true],\n addOnSpace: [Boolean, false],\n addOnComma: [Boolean, true],\n addOnBlur: [Boolean, true],\n addOnPaste: [Boolean, false],\n pasteSplitPattern: [RegExp, /,/],\n allowedTagsPattern: [RegExp, /.+/],\n enableEditingLastTag: [Boolean, false],\n minTags: [Number, 0],\n maxTags: [Number, MAX_SAFE_INTEGER],\n displayProperty: [String, 'text'],\n keyProperty: [String, ''],\n allowLeftoverText: [Boolean, false],\n addFromAutocompleteOnly: [Boolean, false],\n spellcheck: [Boolean, true]\n });\n\n $scope.tagList = new TagList($scope.options, $scope.events,\n tiUtil.handleUndefinedResult($scope.onTagAdding, true),\n tiUtil.handleUndefinedResult($scope.onTagRemoving, true));\n\n this.registerAutocomplete = function() {\n var input = $element.find('input');\n\n return {\n addTag: function(tag) {\n return $scope.tagList.add(tag);\n },\n focusInput: function() {\n // blake_r - Stop the focus as this breaks on the\n // version of AngularJS that ships with MAAS.\n //input[0].focus();\n },\n getTags: function() {\n return $scope.tags;\n },\n getCurrentTagText: function() {\n return $scope.newTag.text;\n },\n getOptions: function() {\n return $scope.options;\n },\n on: function(name, handler) {\n $scope.events.on(name, handler);\n return this;\n }\n };\n };\n\n this.registerTagItem = function() {\n return {\n getOptions: function() {\n return $scope.options;\n },\n removeTag: function(index) {\n if ($scope.disabled) {\n return;\n }\n $scope.tagList.remove(index);\n }\n };\n };\n }],\n link: function(scope, element, attrs, ngModelCtrl) {\n var hotkeys = [KEYS.enter, KEYS.comma, KEYS.space, KEYS.backspace, KEYS.delete, KEYS.left, KEYS.right],\n tagList = scope.tagList,\n events = scope.events,\n options = scope.options,\n input = element.find('input'),\n validationOptions = ['minTags', 'maxTags', 'allowLeftoverText'],\n setElementValidity;\n\n setElementValidity = function() {\n ngModelCtrl.$setValidity('maxTags', scope.tags.length <= options.maxTags);\n ngModelCtrl.$setValidity('minTags', scope.tags.length >= options.minTags);\n ngModelCtrl.$setValidity('leftoverText', scope.hasFocus || options.allowLeftoverText ? true : !scope.newTag.text);\n };\n\n ngModelCtrl.$isEmpty = function(value) {\n return !value || !value.length;\n };\n\n scope.newTag = {\n text: '',\n invalid: null,\n setText: function(value) {\n this.text = value;\n events.trigger('input-change', value);\n }\n };\n\n scope.track = function(tag) {\n return tag[options.keyProperty || options.displayProperty];\n };\n\n scope.$watch('tags', function(value) {\n scope.tags = tiUtil.makeObjectArray(value, options.displayProperty);\n tagList.items = scope.tags;\n });\n\n scope.$watch('tags.length', function() {\n setElementValidity();\n });\n\n attrs.$observe('disabled', function(value) {\n scope.disabled = value;\n });\n\n scope.eventHandlers = {\n input: {\n change: function(text) {\n events.trigger('input-change', text);\n },\n keydown: function($event) {\n events.trigger('input-keydown', $event);\n },\n focus: function() {\n if (scope.hasFocus) {\n return;\n }\n\n scope.hasFocus = true;\n events.trigger('input-focus');\n },\n blur: function() {\n $timeout(function() {\n var activeElement = $document.prop('activeElement'),\n lostFocusToBrowserWindow = activeElement === input[0],\n lostFocusToChildElement = element[0].contains(activeElement);\n\n if (lostFocusToBrowserWindow || !lostFocusToChildElement) {\n scope.hasFocus = false;\n events.trigger('input-blur');\n }\n });\n },\n paste: function($event) {\n $event.getTextData = function() {\n var clipboardData = $event.clipboardData || ($event.originalEvent && $event.originalEvent.clipboardData);\n return clipboardData ? clipboardData.getData('text/plain') : $window.clipboardData.getData('Text');\n };\n events.trigger('input-paste', $event);\n }\n },\n host: {\n click: function() {\n if (scope.disabled) {\n return;\n }\n // blake_r - Stop the focus as this breaks on the\n // version of AngularJS that ships with MAAS.\n //input[0].focus();\n }\n }\n };\n\n events\n .on('tag-added', scope.onTagAdded)\n .on('invalid-tag', scope.onInvalidTag)\n .on('tag-removed', scope.onTagRemoved)\n .on('tag-added', function() {\n scope.newTag.setText('');\n })\n .on('tag-added tag-removed', function() {\n // Sets the element to its dirty state\n // In Angular 1.3 this will be replaced with $setDirty.\n ngModelCtrl.$setViewValue(scope.tags);\n })\n .on('invalid-tag', function() {\n scope.newTag.invalid = true;\n })\n .on('option-change', function(e) {\n if (validationOptions.indexOf(e.name) !== -1) {\n setElementValidity();\n }\n })\n .on('input-change', function() {\n tagList.clearSelection();\n scope.newTag.invalid = null;\n })\n .on('input-focus', function() {\n element.triggerHandler('focus');\n ngModelCtrl.$setValidity('leftoverText', true);\n })\n .on('input-blur', function() {\n if (options.addOnBlur && !options.addFromAutocompleteOnly) {\n tagList.addText(scope.newTag.text);\n }\n element.triggerHandler('blur');\n setElementValidity();\n })\n .on('input-keydown', function(event) {\n var key = event.keyCode,\n isModifier = event.shiftKey || event.altKey || event.ctrlKey || event.metaKey,\n addKeys = {},\n shouldAdd, shouldRemove, shouldSelect, shouldEditLastTag;\n\n if (isModifier || hotkeys.indexOf(key) === -1) {\n return;\n }\n\n addKeys[KEYS.enter] = options.addOnEnter;\n addKeys[KEYS.comma] = options.addOnComma;\n addKeys[KEYS.space] = options.addOnSpace;\n\n shouldAdd = !options.addFromAutocompleteOnly && addKeys[key];\n shouldRemove = (key === KEYS.backspace || key === KEYS.delete) && tagList.selected;\n shouldEditLastTag = key === KEYS.backspace && scope.newTag.text.length === 0 && options.enableEditingLastTag;\n shouldSelect = (key === KEYS.backspace || key === KEYS.left || key === KEYS.right) && scope.newTag.text.length === 0 && !options.enableEditingLastTag;\n\n if (shouldAdd) {\n tagList.addText(scope.newTag.text);\n }\n else if (shouldEditLastTag) {\n var tag;\n\n tagList.selectPrior();\n tag = tagList.removeSelected();\n\n if (tag) {\n scope.newTag.setText(tag[options.displayProperty]);\n }\n }\n else if (shouldRemove) {\n tagList.removeSelected();\n }\n else if (shouldSelect) {\n if (key === KEYS.left || key === KEYS.backspace) {\n tagList.selectPrior();\n }\n else if (key === KEYS.right) {\n tagList.selectNext();\n }\n }\n\n if (shouldAdd || shouldSelect || shouldRemove || shouldEditLastTag) {\n event.preventDefault();\n }\n })\n .on('input-paste', function(event) {\n if (options.addOnPaste) {\n var data = event.getTextData();\n var tags = data.split(options.pasteSplitPattern);\n\n if (tags.length > 1) {\n tags.forEach(function(tag) {\n tagList.addText(tag);\n });\n event.preventDefault();\n }\n }\n });\n }\n };\n}]);\n\n\n/**\n * @ngdoc directive\n * @name tiTagItem\n * @module ngTagsInput\n *\n * @description\n * Represents a tag item. Used internally by the tagsInput directive.\n */\ntagsInput.directive('tiTagItem', [\"tiUtil\", function(tiUtil) {\n return {\n restrict: 'E',\n require: '^tagsInput',\n template: '<ng-include src=\"$$template\"></ng-include>',\n scope: { data: '=' },\n link: function(scope, element, attrs, tagsInputCtrl) {\n var tagsInput = tagsInputCtrl.registerTagItem(),\n options = tagsInput.getOptions();\n\n scope.$$template = options.template;\n scope.$$removeTagSymbol = options.removeTagSymbol;\n\n scope.$getDisplayText = function() {\n return tiUtil.safeToString(scope.data[options.displayProperty]);\n };\n scope.$removeTag = function() {\n tagsInput.removeTag(scope.$index);\n };\n\n scope.$watch('$parent.$index', function(value) {\n scope.$index = value;\n });\n }\n };\n}]);\n\n\n/**\n * @ngdoc directive\n * @name autoComplete\n * @module ngTagsInput\n *\n * @description\n * Provides autocomplete support for the tagsInput directive.\n *\n * @param {expression} source Expression to evaluate upon changing the input content. The input value is available as\n * $query. The result of the expression must be a promise that eventually resolves to an\n * array of strings.\n * @param {string=} [displayProperty=text] Property to be rendered as the autocomplete label.\n * @param {number=} [debounceDelay=100] Amount of time, in milliseconds, to wait before evaluating the expression in\n * the source option after the last keystroke.\n * @param {number=} [minLength=3] Minimum number of characters that must be entered before evaluating the expression\n * in the source option.\n * @param {boolean=} [highlightMatchedText=true] Flag indicating that the matched text will be highlighted in the\n * suggestions list.\n * @param {number=} [maxResultsToShow=10] Maximum number of results to be displayed at a time.\n * @param {boolean=} [loadOnDownArrow=false] Flag indicating that the source option will be evaluated when the down arrow\n * key is pressed and the suggestion list is closed. The current input value\n * is available as $query.\n * @param {boolean=} {loadOnEmpty=false} Flag indicating that the source option will be evaluated when the input content\n * becomes empty. The $query variable will be passed to the expression as an empty string.\n * @param {boolean=} {loadOnFocus=false} Flag indicating that the source option will be evaluated when the input element\n * gains focus. The current input value is available as $query.\n * @param {boolean=} [selectFirstMatch=true] Flag indicating that the first match will be automatically selected once\n * the suggestion list is shown.\n * @param {string=} [template=] URL or id of a custom template for rendering each element of the autocomplete list.\n */\ntagsInput.directive('autoComplete', [\"$document\",\"$timeout\",\"$sce\",\"$q\",\"tagsInputConfig\",\"tiUtil\", function($document, $timeout, $sce, $q, tagsInputConfig, tiUtil) {\n function SuggestionList(loadFn, options, events) {\n var self = {}, getDifference, lastPromise, getTagId;\n\n getTagId = function() {\n return options.tagsInput.keyProperty || options.tagsInput.displayProperty;\n };\n\n getDifference = function(array1, array2) {\n return array1.filter(function(item) {\n return !tiUtil.findInObjectArray(array2, item, getTagId(), function(a, b) {\n if (options.tagsInput.replaceSpacesWithDashes) {\n a = tiUtil.replaceSpacesWithDashes(a);\n b = tiUtil.replaceSpacesWithDashes(b);\n }\n return tiUtil.defaultComparer(a, b);\n });\n });\n };\n\n self.reset = function() {\n lastPromise = null;\n\n self.items = [];\n self.visible = false;\n self.index = -1;\n self.selected = null;\n self.query = null;\n };\n self.show = function() {\n if (options.selectFirstMatch) {\n self.select(0);\n }\n else {\n self.selected = null;\n }\n self.visible = true;\n };\n self.load = tiUtil.debounce(function(query, tags) {\n self.query = query;\n\n var promise = $q.when(loadFn({ $query: query }));\n lastPromise = promise;\n\n promise.then(function(items) {\n if (promise !== lastPromise) {\n return;\n }\n\n items = tiUtil.makeObjectArray(items.data || items, getTagId());\n items = getDifference(items, tags);\n self.items = items.slice(0, options.maxResultsToShow);\n\n if (self.items.length > 0) {\n self.show();\n }\n else {\n self.reset();\n }\n });\n }, options.debounceDelay);\n\n self.selectNext = function() {\n self.select(++self.index);\n };\n self.selectPrior = function() {\n self.select(--self.index);\n };\n self.select = function(index) {\n if (index < 0) {\n index = self.items.length - 1;\n }\n else if (index >= self.items.length) {\n index = 0;\n }\n self.index = index;\n self.selected = self.items[index];\n events.trigger('suggestion-selected', index);\n };\n\n self.reset();\n\n return self;\n }\n\n function scrollToElement(root, index) {\n var element = root.find('li').eq(index),\n parent = element.parent(),\n elementTop = element.prop('offsetTop'),\n elementHeight = element.prop('offsetHeight'),\n parentHeight = parent.prop('clientHeight'),\n parentScrollTop = parent.prop('scrollTop');\n\n if (elementTop < parentScrollTop) {\n parent.prop('scrollTop', elementTop);\n }\n else if (elementTop + elementHeight > parentHeight + parentScrollTop) {\n parent.prop('scrollTop', elementTop + elementHeight - parentHeight);\n }\n }\n\n return {\n restrict: 'E',\n require: '^tagsInput',\n scope: { source: '&' },\n templateUrl: 'ngTagsInput/auto-complete.html',\n controller: [\"$scope\",\"$element\",\"$attrs\", function($scope, $element, $attrs) {\n $scope.events = tiUtil.simplePubSub();\n\n tagsInputConfig.load('autoComplete', $scope, $attrs, {\n template: [String, 'ngTagsInput/auto-complete-match.html'],\n debounceDelay: [Number, 100],\n minLength: [Number, 3],\n highlightMatchedText: [Boolean, true],\n maxResultsToShow: [Number, 10],\n loadOnDownArrow: [Boolean, false],\n loadOnEmpty: [Boolean, false],\n loadOnFocus: [Boolean, false],\n selectFirstMatch: [Boolean, true],\n displayProperty: [String, '']\n });\n\n $scope.suggestionList = new SuggestionList($scope.source, $scope.options, $scope.events);\n\n this.registerAutocompleteMatch = function() {\n return {\n getOptions: function() {\n return $scope.options;\n },\n getQuery: function() {\n return $scope.suggestionList.query;\n }\n };\n };\n }],\n link: function(scope, element, attrs, tagsInputCtrl) {\n var hotkeys = [KEYS.enter, KEYS.tab, KEYS.escape, KEYS.up, KEYS.down],\n suggestionList = scope.suggestionList,\n tagsInput = tagsInputCtrl.registerAutocomplete(),\n options = scope.options,\n events = scope.events,\n shouldLoadSuggestions;\n\n options.tagsInput = tagsInput.getOptions();\n\n shouldLoadSuggestions = function(value) {\n return value && value.length >= options.minLength || !value && options.loadOnEmpty;\n };\n\n scope.addSuggestionByIndex = function(index) {\n suggestionList.select(index);\n scope.addSuggestion();\n };\n\n scope.addSuggestion = function() {\n var added = false;\n\n if (suggestionList.selected) {\n tagsInput.addTag(angular.copy(suggestionList.selected));\n suggestionList.reset();\n tagsInput.focusInput();\n\n added = true;\n }\n return added;\n };\n\n scope.track = function(item) {\n return item[options.tagsInput.keyProperty || options.tagsInput.displayProperty];\n };\n\n tagsInput\n .on('tag-added invalid-tag input-blur', function() {\n suggestionList.reset();\n })\n .on('input-change', function(value) {\n if (shouldLoadSuggestions(value)) {\n suggestionList.load(value, tagsInput.getTags());\n }\n else {\n suggestionList.reset();\n }\n })\n .on('input-focus', function() {\n var value = tagsInput.getCurrentTagText();\n if (options.loadOnFocus && shouldLoadSuggestions(value)) {\n suggestionList.load(value, tagsInput.getTags());\n }\n })\n .on('input-keydown', function(event) {\n var key = event.keyCode,\n handled = false;\n\n if (hotkeys.indexOf(key) === -1) {\n return;\n }\n\n if (suggestionList.visible) {\n\n if (key === KEYS.down) {\n suggestionList.selectNext();\n handled = true;\n }\n else if (key === KEYS.up) {\n suggestionList.selectPrior();\n handled = true;\n }\n else if (key === KEYS.escape) {\n suggestionList.reset();\n handled = true;\n }\n else if (key === KEYS.enter || key === KEYS.tab) {\n handled = scope.addSuggestion();\n }\n }\n else {\n if (key === KEYS.down && scope.options.loadOnDownArrow) {\n suggestionList.load(tagsInput.getCurrentTagText(), tagsInput.getTags());\n handled = true;\n }\n }\n\n if (handled) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return false;\n }\n });\n\n events.on('suggestion-selected', function(index) {\n scrollToElement(element, index);\n });\n }\n };\n}]);\n\n\n/**\n * @ngdoc directive\n * @name tiAutocompleteMatch\n * @module ngTagsInput\n *\n * @description\n * Represents an autocomplete match. Used internally by the autoComplete directive.\n */\ntagsInput.directive('tiAutocompleteMatch', [\"$sce\",\"tiUtil\", function($sce, tiUtil) {\n return {\n restrict: 'E',\n require: '^autoComplete',\n template: '<ng-include src=\"$$template\"></ng-include>',\n scope: { data: '=' },\n link: function(scope, element, attrs, autoCompleteCtrl) {\n var autoComplete = autoCompleteCtrl.registerAutocompleteMatch(),\n options = autoComplete.getOptions();\n\n scope.$$template = options.template;\n scope.$index = scope.$parent.$index;\n\n scope.$highlight = function(text) {\n if (options.highlightMatchedText) {\n text = tiUtil.safeHighlight(text, autoComplete.getQuery());\n }\n return $sce.trustAsHtml(text);\n };\n scope.$getDisplayText = function() {\n return tiUtil.safeToString(scope.data[options.displayProperty || options.tagsInput.displayProperty]);\n };\n }\n };\n}]);\n\n\n/**\n * @ngdoc directive\n * @name tiTranscludeAppend\n * @module ngTagsInput\n *\n * @description\n * Re-creates the old behavior of ng-transclude. Used internally by tagsInput directive.\n */\ntagsInput.directive('tiTranscludeAppend', function() {\n return function(scope, element, attrs, ctrl, transcludeFn) {\n transcludeFn(function(clone) {\n element.append(clone);\n });\n };\n});\n\n/**\n * @ngdoc directive\n * @name tiAutosize\n * @module ngTagsInput\n *\n * @description\n * Automatically sets the input's width so its content is always visible. Used internally by tagsInput directive.\n */\ntagsInput.directive('tiAutosize', [\"tagsInputConfig\", function(tagsInputConfig) {\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function(scope, element, attrs, ctrl) {\n var threshold = tagsInputConfig.getTextAutosizeThreshold(),\n span, resize;\n\n span = angular.element('<span class=\"input\"></span>');\n span.css('display', 'none')\n .css('visibility', 'hidden')\n .css('width', 'auto')\n .css('white-space', 'pre');\n\n element.parent().append(span);\n\n resize = function(originalValue) {\n var value = originalValue, width;\n\n if (angular.isString(value) && value.length === 0) {\n value = attrs.placeholder;\n }\n\n if (value) {\n span.text(value);\n span.css('display', '');\n width = span.prop('offsetWidth');\n span.css('display', 'none');\n }\n\n element.css('width', width ? width + threshold + 'px' : '');\n\n return originalValue;\n };\n\n ctrl.$parsers.unshift(resize);\n ctrl.$formatters.unshift(resize);\n\n attrs.$observe('placeholder', function(value) {\n if (!ctrl.$modelValue) {\n resize(value);\n }\n });\n }\n };\n}]);\n\n/**\n * @ngdoc directive\n * @name tiBindAttrs\n * @module ngTagsInput\n *\n * @description\n * Binds attributes to expressions. Used internally by tagsInput directive.\n */\ntagsInput.directive('tiBindAttrs', function() {\n return function(scope, element, attrs) {\n scope.$watch(attrs.tiBindAttrs, function(value) {\n angular.forEach(value, function(value, key) {\n /**\n * blake_r - Added to work around the version of jQuery that\n * MAAS currently ships with. Once packaging for jQuery is\n * version >1.9 this can be removed.\n */\n if(key === \"type\") {\n element[0].type = value;\n } else {\n attrs.$set(key, value);\n }\n });\n }, true);\n };\n});\n\n/**\n * @ngdoc service\n * @name tagsInputConfig\n * @module ngTagsInput\n *\n * @description\n * Sets global configuration settings for both tagsInput and autoComplete directives. It's also used internally to parse and\n * initialize options from HTML attributes.\n */\ntagsInput.provider('tagsInputConfig', function() {\n var globalDefaults = {},\n interpolationStatus = {},\n autosizeThreshold = 3;\n\n /**\n * @ngdoc method\n * @name setDefaults\n * @description Sets the default configuration option for a directive.\n * @methodOf tagsInputConfig\n *\n * @param {string} directive Name of the directive to be configured. Must be either 'tagsInput' or 'autoComplete'.\n * @param {object} defaults Object containing options and their values.\n *\n * @returns {object} The service itself for chaining purposes.\n */\n this.setDefaults = function(directive, defaults) {\n globalDefaults[directive] = defaults;\n return this;\n };\n\n /***\n * @ngdoc method\n * @name setActiveInterpolation\n * @description Sets active interpolation for a set of options.\n * @methodOf tagsInputConfig\n *\n * @param {string} directive Name of the directive to be configured. Must be either 'tagsInput' or 'autoComplete'.\n * @param {object} options Object containing which options should have interpolation turned on at all times.\n *\n * @returns {object} The service itself for chaining purposes.\n */\n this.setActiveInterpolation = function(directive, options) {\n interpolationStatus[directive] = options;\n return this;\n };\n\n /***\n * @ngdoc method\n * @name setTextAutosizeThreshold\n * @description Sets the threshold used by the tagsInput directive to re-size the inner input field element based on its contents.\n * @methodOf tagsInputConfig\n *\n * @param {number} threshold Threshold value, in pixels.\n *\n * @returns {object} The service itself for chaining purposes.\n */\n this.setTextAutosizeThreshold = function(threshold) {\n autosizeThreshold = threshold;\n return this;\n };\n\n this.$get = [\"$interpolate\", function($interpolate) {\n var converters = {};\n converters[String] = function(value) { return value; };\n converters[Number] = function(value) { return parseInt(value, 10); };\n converters[Boolean] = function(value) { return value.toLowerCase() === 'true'; };\n converters[RegExp] = function(value) { return new RegExp(value); };\n\n return {\n load: function(directive, scope, attrs, options) {\n var defaultValidator = function() { return true; };\n\n scope.options = {};\n\n angular.forEach(options, function(value, key) {\n var type, localDefault, validator, converter, getDefault, updateValue;\n\n type = value[0];\n localDefault = value[1];\n validator = value[2] || defaultValidator;\n converter = converters[type];\n\n getDefault = function() {\n var globalValue = globalDefaults[directive] && globalDefaults[directive][key];\n return angular.isDefined(globalValue) ? globalValue : localDefault;\n };\n\n updateValue = function(value) {\n scope.options[key] = value && validator(value) ? converter(value) : getDefault();\n };\n\n if (interpolationStatus[directive] && interpolationStatus[directive][key]) {\n attrs.$observe(key, function(value) {\n updateValue(value);\n scope.events.trigger('option-change', { name: key, newValue: value });\n });\n }\n else {\n updateValue(attrs[key] && $interpolate(attrs[key])(scope.$parent));\n }\n });\n },\n getTextAutosizeThreshold: function() {\n return autosizeThreshold;\n }\n };\n }];\n});\n\n\n/***\n * @ngdoc factory\n * @name tiUtil\n * @module ngTagsInput\n *\n * @description\n * Helper methods used internally by the directive. Should not be called directly from user code.\n */\ntagsInput.factory('tiUtil', [\"$timeout\", function($timeout) {\n var self = {};\n\n self.debounce = function(fn, delay) {\n var timeoutId;\n return function() {\n var args = arguments;\n $timeout.cancel(timeoutId);\n timeoutId = $timeout(function() { fn.apply(null, args); }, delay);\n };\n };\n\n self.makeObjectArray = function(array, key) {\n array = array || [];\n if (array.length > 0 && !angular.isObject(array[0])) {\n array.forEach(function(item, index) {\n array[index] = {};\n array[index][key] = item;\n });\n }\n return array;\n };\n\n self.findInObjectArray = function(array, obj, key, comparer) {\n var item = null;\n comparer = comparer || self.defaultComparer;\n\n array.some(function(element) {\n if (comparer(element[key], obj[key])) {\n item = element;\n return true;\n }\n });\n\n return item;\n };\n\n self.defaultComparer = function(a, b) {\n // I'm aware of the internationalization issues regarding toLowerCase()\n // but I couldn't come up with a better solution right now\n return self.safeToString(a).toLowerCase() === self.safeToString(b).toLowerCase();\n };\n\n self.safeHighlight = function(str, value) {\n if (!value) {\n return str;\n }\n\n function escapeRegexChars(str) {\n return str.replace(/([.?*+^$[\\]\\\\(){}|-])/g, '\\\\$1');\n }\n\n str = self.encodeHTML(str);\n value = self.encodeHTML(value);\n\n var expression = new RegExp('&[^;]+;|' + escapeRegexChars(value), 'gi');\n return str.replace(expression, function(match) {\n return match.toLowerCase() === value.toLowerCase() ? '<em>' + match + '</em>' : match;\n });\n };\n\n self.safeToString = function(value) {\n return angular.isUndefined(value) || value == null ? '' : value.toString().trim();\n };\n\n self.encodeHTML = function(value) {\n return self.safeToString(value)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n };\n\n self.handleUndefinedResult = function(fn, valueIfUndefined) {\n return function() {\n var result = fn.apply(null, arguments);\n return angular.isUndefined(result) ? valueIfUndefined : result;\n };\n };\n\n self.replaceSpacesWithDashes = function(str) {\n return self.safeToString(str).replace(/\\s/g, '-');\n };\n\n self.simplePubSub = function() {\n var events = {};\n return {\n on: function(names, handler) {\n names.split(' ').forEach(function(name) {\n if (!events[name]) {\n events[name] = [];\n }\n events[name].push(handler);\n });\n return this;\n },\n trigger: function(name, args) {\n var handlers = events[name] || [];\n handlers.every(function(handler) {\n return self.handleUndefinedResult(handler, true)(args);\n });\n return this;\n }\n };\n };\n\n return self;\n}]);\n\n/* HTML templates */\ntagsInput.run([\"$templateCache\", function($templateCache) {\n $templateCache.put('ngTagsInput/tags-input.html',\n \"<div class=\\\"host\\\" tabindex=\\\"-1\\\" data-ng-click=\\\"eventHandlers.host.click()\\\" ti-transclude-append=\\\"\\\"><div class=\\\"tags\\\" data-ng-class=\\\"{focused: hasFocus}\\\"><ul class=\\\"tag-list\\\"><li class=\\\"tag-item\\\" data-ng-repeat=\\\"tag in tagList.items track by track(tag)\\\" data-ng-class=\\\"{ selected: tag == tagList.selected }\\\"><ti-tag-item data=\\\"tag\\\"></ti-tag-item></li></ul><input class=\\\"input u-no-margin--top\\\" autocomplete=\\\"off\\\" data-ng-model=\\\"newTag.text\\\" data-ng-change=\\\"eventHandlers.input.change(newTag.text)\\\" data-ng-keydown=\\\"eventHandlers.input.keydown($event)\\\" data-ng-focus=\\\"eventHandlers.input.focus($event)\\\" data-ng-blur=\\\"eventHandlers.input.blur($event)\\\" data-ng-paste=\\\"eventHandlers.input.paste($event)\\\" data-ng-trim=\\\"false\\\" data-ng-class=\\\"{'invalid-tag': newTag.invalid}\\\" data-ng-disabled=\\\"disabled\\\" ti-bind-attrs=\\\"{type: options.type, placeholder: options.placeholder, tabindex: options.tabindex, spellcheck: options.spellcheck}\\\" ti-autosize=\\\"\\\"></div></div>\"\n );\n\n $templateCache.put('ngTagsInput/tag-item.html',\n \"<span ng-bind=\\\"$getDisplayText()\\\"></span> <a class=\\\"p-icon--close\\\" data-ng-click=\\\"$removeTag()\\\" data-ng-bind=\\\"$$removeTagSymbol\\\">Remove tag</a>\"\n );\n\n $templateCache.put('ngTagsInput/auto-complete.html',\n \"<div class=\\\"autocomplete\\\" data-ng-if=\\\"suggestionList.visible\\\"><ul class=\\\"p-list suggestion-list\\\"><li class=\\\"suggestion-item\\\" data-ng-repeat=\\\"item in suggestionList.items track by track(item)\\\" data-ng-class=\\\"{selected: item == suggestionList.selected}\\\" data-ng-click=\\\"addSuggestionByIndex($index)\\\" data-ng-mouseenter=\\\"suggestionList.select($index)\\\"><ti-autocomplete-match data=\\\"item\\\"></ti-autocomplete-match></li></ul></div>\"\n );\n\n $templateCache.put('ngTagsInput/auto-complete-match.html',\n \"<span data-ng-bind-html=\\\"$highlight($getDisplayText())\\\"></span>\"\n );\n}]);\n\n}());\n","/*!\n * Angular Virtual Scroll Repeat v2.0.9\n * https://github.com/kamilkp/angular-vs-repeat/\n *\n * Copyright Kamil Pękala\n * http://github.com/kamilkp\n *\n * Released under the MIT License\n * https://opensource.org/licenses/MIT\n *\n * Date: 2018/04/02\n */\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return _sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }\n\n/* global console, setTimeout, module */\n(function (window, angular) {\n /**\n * DESCRIPTION:\n * vsRepeat directive stands for Virtual Scroll Repeat. It turns a standard ngRepeated set of elements in a scrollable container\n * into a component, where the user thinks he has all the elements rendered and all he needs to do is scroll (without any kind of\n * pagination - which most users loath) and at the same time the browser isn't overloaded by that many elements/angular bindings etc.\n * The directive renders only so many elements that can fit into current container's clientHeight/clientWidth.\n * LIMITATIONS:\n * - current version only supports an Array as a right-hand-side object for ngRepeat\n * - all rendered elements must have the same height/width or the sizes of the elements must be known up front\n * USAGE:\n * In order to use the vsRepeat directive you need to place a vs-repeat attribute on a direct parent of an element with ng-repeat\n * example:\n * <div vs-repeat=\"options\">\n * <div ng-repeat=\"item in someArray\">\n * <!-- content -->\n * </div>\n * </div>\n * or:\n * <div vs-repeat=\"options\">\n * <div ng-repeat-start=\"item in someArray\">\n * <!-- content -->\n * </div>\n * <div>\n * <!-- something in the middle -->\n * </div>\n * <div ng-repeat-end>\n * <!-- content -->\n * </div>\n * </div>\n * You can also measure the single element's height/width (including all paddings and margins), and then speficy it as a value\n * of the option's `size` property. This can be used if one wants to override the automatically computed element size.\n * example:\n * <div vs-repeat=\"{size: 50}\"> <!-- the specified element height is 50px -->\n * <div ng-repeat=\"item in someArray\">\n * <!-- content -->\n * </div>\n * </div>\n * IMPORTANT!\n * - the vsRepeat directive must be applied to a direct parent of an element with ngRepeat\n * - the value of vsRepeat attribute is the single element's height/width measured in pixels. If none provided, the directive\n * will compute it automatically\n * OPTIONAL PARAMETERS (attributes):\n * vs-repeat-container=\"selector\" - selector for element containing ng-repeat. (defaults to the current element)\n * OPTIONS:\n * Options shall be passed as an object to the `vs-repeat` attribute e.g.: `<div vs-repeat=\"{scrollParent: 'window', size: 20}\"></div>`\n *\n * Available options:\n * `horizontal` - stack repeated elements horizontally instead of vertically\n * `offset-before` - top/left offset in pixels (defaults to 0)\n * `offset-after` - bottom/right offset in pixels (defaults to 0)\n * `scroll-margin` - how many pixels ahead should elements be rendered while scrolling\n * `latch` - if true, elements will be rendered gradually but won't be removed when scrolled away (defaults to false)\n * `size` - a property name of the items in collection that is a number denoting the element size (in pixels)\n * `autoresize` - use this attribute without vs-size and without specifying element's size. The automatically computed element style will\n * readjust upon window resize if the size is dependable on the viewport size\n * `scrolled-to-end` - callback will be called when the last item of the list is rendered\n * `scrolled-to-end-offset` - set this number to trigger the scrolledToEnd callback n items before the last gets rendered\n * `scrolled-to-beginning` - callback will be called when the first item of the list is rendered\n * `scrolled-to-beginning-offset` - set this number to trigger the scrolledToBeginning callback n items before the first gets rendered\n * EVENTS:\n * - `vsRepeatTrigger` - an event the directive listens for to manually trigger reinitialization\n * - `vsRepeatReinitialized` - an event the directive emits upon reinitialization done\n */\n var closestElement = angular.element.prototype.closest;\n\n if (!closestElement) {\n var matchingFunction = ['matches', 'matchesSelector', 'webkitMatches', 'webkitMatchesSelector', 'msMatches', 'msMatchesSelector', 'mozMatches', 'mozMatchesSelector'].reduce(function (res, prop) {\n var _res;\n\n return (_res = res) !== null && _res !== void 0 ? _res : prop in document.documentElement ? prop : null;\n }, null);\n\n closestElement = function closestElement(selector) {\n var _el;\n\n var el = this[0].parentNode;\n\n while (el !== document.documentElement && el != null && !el[matchingFunction](selector)) {\n el = el.parentNode;\n }\n\n if ((_el = el) === null || _el === void 0 ? void 0 : _el[matchingFunction](selector)) {\n return angular.element(el);\n }\n\n return angular.element();\n };\n }\n\n function getWindowScroll() {\n var _ref, _document$documentEle, _ref2, _document$documentEle2;\n\n if ('pageYOffset' in window) {\n return {\n scrollTop: window.pageYOffset,\n scrollLeft: window.pageXOffset\n };\n }\n\n return {\n scrollTop: (_ref = (_document$documentEle = document.documentElement.scrollTop) !== null && _document$documentEle !== void 0 ? _document$documentEle : document.body.scrollTop) !== null && _ref !== void 0 ? _ref : 0,\n scrollLeft: (_ref2 = (_document$documentEle2 = document.documentElement.scrollLeft) !== null && _document$documentEle2 !== void 0 ? _document$documentEle2 : document.body.scrollLeft) !== null && _ref2 !== void 0 ? _ref2 : 0\n };\n }\n\n function getClientSize(element, sizeProp) {\n if (element === window) {\n return sizeProp === 'clientWidth' ? window.innerWidth : window.innerHeight;\n }\n\n return element[sizeProp];\n }\n\n function getScrollPos(element, scrollProp) {\n return element === window ? getWindowScroll()[scrollProp] : element[scrollProp];\n }\n\n function getScrollOffset(vsElement, scrollElement, isHorizontal) {\n var vsPos = vsElement.getBoundingClientRect()[isHorizontal ? 'left' : 'top'];\n var scrollPos = scrollElement === window ? 0 : scrollElement.getBoundingClientRect()[isHorizontal ? 'left' : 'top'];\n var scrollValue = (scrollElement === window ? getWindowScroll() : scrollElement)[isHorizontal ? 'scrollLeft' : 'scrollTop'];\n return vsPos - scrollPos + scrollValue;\n }\n\n function analyzeNgRepeatUsage(element) {\n var options = ['ng-repeat', 'data-ng-repeat', 'ng-repeat-start', 'data-ng-repeat-start'];\n\n for (var _i = 0; _i < options.length; _i++) {\n var opt = options[_i];\n\n if (element.attr(opt)) {\n return [opt, element.attr(opt), opt.indexOf('-start') >= 0];\n }\n }\n\n throw new Error('angular-vs-repeat: no ng-repeat directive on a child element');\n }\n\n function printDeprecationWarning($element, message) {\n console.warn(\"vs-repeat deprecation: \".concat(message), $element[0]);\n }\n\n function attrDeprecated(attrname, $element) {\n printDeprecationWarning($element, \"\".concat(attrname, \" attribute is deprecated. Pass the options object to vs-repeat attribute instead https://github.com/kamilkp/angular-vs-repeat#options\"));\n }\n\n var defaultOptions = {\n latch: false,\n container: null,\n scrollParent: null,\n size: null,\n offsetBefore: 0,\n offsetAfter: 0,\n scrolledToBeginning: angular.noop,\n scrolledToEnd: angular.noop,\n scrolledToBeginningOffset: 0,\n scrolledToEndOffset: 0,\n scrollMargin: 0,\n horizontal: false,\n autoresize: false,\n hunked: false,\n hunkSize: 0\n };\n var vsRepeatModule = angular.module('vs-repeat', []).directive('vsRepeat', ['$compile', '$parse', function ($compile, $parse) {\n return {\n restrict: 'A',\n scope: true,\n compile: function compile(compileElement, compileAttrs) {\n var compileRepeatContainer = 'vsRepeatContainer' in compileAttrs ? angular.element(compileElement[0].querySelector(compileAttrs.vsRepeatContainer)) : compileElement;\n var repeatContainerChildren = compileRepeatContainer.children();\n var ngRepeatChild = repeatContainerChildren.eq(0);\n var childCloneHtml = ngRepeatChild[0].outerHTML;\n var collectionName = '$vs_collection'; // TODO: make configurable?\n\n ['vsSize', 'vsScrollParent', 'vsSizeProperty', 'vsHorizontal', 'vsOffsetBefore', 'vsOffsetAfter', 'vsScrolledToEndOffset', 'vsScrolledToBeginningOffset', 'vsExcess', 'vsScrollMargin'].forEach(function (attrname) {\n if (attrname in compileAttrs) {\n attrDeprecated(attrname, compileElement);\n }\n });\n\n var _analyzeNgRepeatUsage = analyzeNgRepeatUsage(ngRepeatChild),\n _analyzeNgRepeatUsage2 = _slicedToArray(_analyzeNgRepeatUsage, 3),\n originalNgRepeatAttr = _analyzeNgRepeatUsage2[0],\n ngRepeatExpression = _analyzeNgRepeatUsage2[1],\n isNgRepeatStart = _analyzeNgRepeatUsage2[2];\n\n var expressionMatches = /^\\s*(\\S+)\\s+in\\s+([\\S\\s]+?)(track\\s+by\\s+\\S+)?$/.exec(ngRepeatExpression);\n\n var _expressionMatches = _slicedToArray(expressionMatches, 4),\n lhs = _expressionMatches[1],\n rhs = _expressionMatches[2],\n rhsSuffix = _expressionMatches[3];\n\n if (isNgRepeatStart) {\n var index = 0;\n var repeaterElement = repeatContainerChildren.eq(index);\n\n while (repeaterElement.attr('ng-repeat-end') == null && repeaterElement.attr('data-ng-repeat-end') == null) {\n index++;\n repeaterElement = repeatContainerChildren.eq(index);\n childCloneHtml += repeaterElement[0].outerHTML;\n }\n }\n\n compileRepeatContainer.empty();\n return {\n pre: function pre($scope, $element, $attrs) {\n var _$scope$$eval;\n\n function _parseSize(options) {\n if (typeof options.size === 'number') {\n options.getSize = function () {\n return options.size;\n };\n } else {\n var parsed = $parse(String(options.size));\n\n options.getSize = function (item) {\n return parsed($scope, _defineProperty({}, lhs, item));\n };\n }\n }\n\n $scope.vsRepeat = {\n options: _extends({}, defaultOptions, (_$scope$$eval = $scope.$eval($attrs.vsRepeat)) !== null && _$scope$$eval !== void 0 ? _$scope$$eval : {})\n };\n var options = $scope.vsRepeat.options;\n\n _parseSize(options);\n\n var repeatContainer = angular.isDefined($attrs.vsRepeatContainer) ? angular.element($element[0].querySelector($attrs.vsRepeatContainer)) : $element;\n var childClone = angular.element(childCloneHtml);\n var childTagName = childClone[0].tagName.toLowerCase();\n var originalCollection = [];\n var originalLength;\n var $beforeContent = angular.element('<' + childTagName + ' class=\"vs-repeat-before-content\"></' + childTagName + '>');\n var $afterContent = angular.element('<' + childTagName + ' class=\"vs-repeat-after-content\"></' + childTagName + '>');\n var autosizingRequired = options.size === null;\n var $scrollParent = options.scrollParent ? options.scrollParent === 'window' ? angular.element(window) : closestElement.call(repeatContainer, options.scrollParent) : repeatContainer;\n var clientSize = options.horizontal ? 'clientWidth' : 'clientHeight';\n var offsetSize = options.horizontal ? 'offsetWidth' : 'offsetHeight';\n var scrollSize = options.horizontal ? 'scrollWidth' : 'scrollHeight';\n var scrollPos = options.horizontal ? 'scrollLeft' : 'scrollTop';\n $scope.vsRepeat.totalSize = 0;\n\n if ($scrollParent.length === 0) {\n throw 'Specified scroll parent selector did not match any element';\n }\n\n $scope.vsRepeat.$scrollParent = $scrollParent;\n $scope.vsRepeat.sizesCumulative = [];\n\n if (options.debug) {\n var $debugParent = options.scrollParent === 'window' ? angular.element(document.body) : $scrollParent;\n var $debug = angular.element('<div class=\"vs-repeat-debug-element\"></div>');\n $debug.css('position', options.scrollParent === 'window' ? 'fixed' : 'absolute');\n $debugParent.append($debug);\n $scope.$on('$destroy', function () {\n $debug.remove();\n });\n }\n\n var measuredSize = getClientSize($scrollParent[0], clientSize) || 50;\n\n if (options.horizontal) {\n $beforeContent.css('height', '100%');\n $afterContent.css('height', '100%');\n } else {\n $beforeContent.css('width', '100%');\n $afterContent.css('width', '100%');\n }\n\n if ($attrs.vsRepeatOptions) {\n $scope.$watchCollection($attrs.vsRepeatOptions, function (newOpts) {\n var mergedOptions = _extends({}, options, newOpts);\n\n if (JSON.stringify(mergedOptions) !== JSON.stringify(options)) {\n Object.assign(options, newOpts);\n\n _parseSize(options);\n\n reinitialize();\n }\n });\n }\n\n $scope.$watchCollection(rhs, function () {\n var coll = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n originalCollection = coll;\n refresh();\n });\n\n function refresh() {\n if (!originalCollection || originalCollection.length < 1) {\n $scope[collectionName] = [];\n originalLength = 0;\n $scope.vsRepeat.sizesCumulative = [0];\n } else {\n originalLength = originalCollection.length;\n\n if (options.size) {\n _mapSize();\n } else {\n getFromMeasured();\n }\n }\n\n reinitialize();\n }\n\n function _mapSize() {\n var hardSize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n var sizes = originalCollection.map(function (item) {\n var _hardSize;\n\n return (_hardSize = hardSize) !== null && _hardSize !== void 0 ? _hardSize : options.getSize(item);\n });\n var sum = 0;\n $scope.vsRepeat.sizesCumulative = [0].concat(_toConsumableArray(sizes.map(function (size) {\n return sum += size;\n })));\n }\n\n function getFromMeasured() {\n if (autosizingRequired) {\n $scope.$$postDigest(function () {\n if (repeatContainer[0].offsetHeight || repeatContainer[0].offsetWidth) {\n // element is visible\n var children = repeatContainer.children();\n var i = 0;\n var gotSomething = false;\n var insideStartEndSequence = false;\n\n while (i < children.length) {\n if (children[i].attributes[originalNgRepeatAttr] != null || insideStartEndSequence) {\n if (!gotSomething) {\n measuredSize = 0;\n }\n\n gotSomething = true;\n\n if (children[i][offsetSize]) {\n measuredSize += children[i][offsetSize];\n }\n\n if (isNgRepeatStart) {\n if (children[i].attributes['ng-repeat-end'] != null || children[i].attributes['data-ng-repeat-end'] != null) {\n break;\n } else {\n insideStartEndSequence = true;\n }\n } else {\n break;\n }\n }\n\n i++;\n }\n\n if (gotSomething) {\n _mapSize(measuredSize);\n\n reinitialize();\n autosizingRequired = false;\n\n if ($scope.$root && !$scope.$root.$$phase) {\n $scope.$digest();\n }\n }\n } else {\n var dereg = $scope.$watch(function () {\n if (repeatContainer[0].offsetHeight || repeatContainer[0].offsetWidth) {\n dereg();\n getFromMeasured();\n }\n });\n }\n });\n } else {\n _mapSize(measuredSize);\n }\n }\n\n function getLayoutProps(value) {\n var layoutProp = options.horizontal ? 'width' : 'height';\n return ['', 'min-', 'max-'].reduce(function (acc, prop) {\n return acc[\"\".concat(prop).concat(layoutProp)] = value, acc;\n }, {});\n }\n\n childClone.eq(0).attr(originalNgRepeatAttr, lhs + ' in ' + collectionName + (rhsSuffix ? ' ' + rhsSuffix : ''));\n childClone.addClass('vs-repeat-repeated-element');\n repeatContainer.append($beforeContent);\n repeatContainer.append(childClone);\n $compile(childClone)($scope);\n repeatContainer.append($afterContent);\n $scope.vsRepeat.startIndex = 0;\n $scope.vsRepeat.endIndex = 0;\n\n function scrollHandler() {\n var pos = $scrollParent[0][scrollPos];\n\n if (updateInnerCollection()) {\n $scope.$digest();\n\n if (options._ensureScrollIntegrity) {\n $scrollParent[0][scrollPos] = pos;\n }\n }\n }\n\n $scrollParent.on('scroll', scrollHandler);\n\n function onWindowResize() {\n if (options.autoresize) {\n autosizingRequired = true;\n getFromMeasured();\n\n if ($scope.$root && !$scope.$root.$$phase) {\n $scope.$digest();\n }\n }\n\n if (updateInnerCollection()) {\n $scope.$digest();\n }\n }\n\n angular.element(window).on('resize', onWindowResize);\n $scope.$on('$destroy', function () {\n angular.element(window).off('resize', onWindowResize);\n $scrollParent.off('scroll', scrollHandler);\n });\n $scope.$on('vsRepeatTrigger', refresh);\n $scope.$on('vsRepeatResize', function () {\n autosizingRequired = true;\n getFromMeasured();\n });\n\n var _prevStartIndex, _prevEndIndex, _minStartIndex, _maxEndIndex;\n\n $scope.$on('vsRenderAll', function () {\n if (!options.latch) {\n return;\n }\n\n if ($scope.vsRepeat.endIndex === originalLength) {\n $scope.$emit('vsRenderAllDone');\n return;\n }\n\n setTimeout(function () {\n // var __endIndex = Math.min($scope.vsRepeat.endIndex + (quantum || 1), originalLength);\n var __endIndex = originalLength;\n _maxEndIndex = Math.max(__endIndex, _maxEndIndex);\n $scope.vsRepeat.endIndex = options.latch ? _maxEndIndex : __endIndex;\n $scope[collectionName] = originalCollection.slice($scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex);\n _prevEndIndex = $scope.vsRepeat.endIndex;\n $beforeContent.css(getLayoutProps(0));\n $afterContent.css(getLayoutProps(0));\n $scope.$emit('vsRenderAllDone');\n\n if ($scope.$root && !$scope.$root.$$phase) {\n $scope.$digest();\n }\n });\n });\n\n function reinitialize() {\n _prevStartIndex = void 0;\n _prevEndIndex = void 0;\n _minStartIndex = originalLength;\n _maxEndIndex = 0;\n updateTotalSize($scope.vsRepeat.sizesCumulative[originalLength]);\n updateInnerCollection();\n $scope.$emit('vsRepeatReinitialized', $scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex);\n }\n\n function updateTotalSize(size) {\n $scope.vsRepeat.totalSize = options.offsetBefore + size + options.offsetAfter;\n }\n\n var _prevClientSize;\n\n function reinitOnClientHeightChange() {\n var ch = getClientSize($scrollParent[0], clientSize);\n\n if (ch !== _prevClientSize) {\n reinitialize();\n\n if ($scope.$root && !$scope.$root.$$phase) {\n $scope.$digest();\n }\n }\n\n _prevClientSize = ch;\n }\n\n $scope.$watch(function () {\n if (typeof window.requestAnimationFrame === 'function') {\n window.requestAnimationFrame(reinitOnClientHeightChange);\n } else {\n reinitOnClientHeightChange();\n }\n });\n\n function binaryFind(array, threshold) {\n var a = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;\n var b = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : array.length - 1;\n var d = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;\n\n if (array[a] === threshold) {\n return [a, a, d];\n }\n\n if (array[b] === threshold) {\n return [b, b, d];\n }\n\n if (b - a > 1) {\n var m = Math.floor((a + b) / 2);\n\n if (array[m] > threshold) {\n return binaryFind(array, threshold, a, m, d + 1);\n }\n\n return binaryFind(array, threshold, m, b, d + 1);\n }\n\n return [threshold > array[b] ? b : a, threshold < array[a] ? a : b, d];\n }\n\n function updateInnerCollection() {\n var $scrollPosition = getScrollPos($scrollParent[0], scrollPos);\n var $clientSize = getClientSize($scrollParent[0], clientSize);\n\n if (options.debug) {\n $clientSize /= 2;\n }\n\n var scrollOffset = repeatContainer[0] === $scrollParent[0] ? 0 : getScrollOffset(repeatContainer[0], $scrollParent[0], options.horizontal);\n var __startIndex = $scope.vsRepeat.startIndex;\n var __endIndex = $scope.vsRepeat.endIndex;\n\n if (autosizingRequired && !options.size) {\n __startIndex = 0;\n __endIndex = 1;\n } else {\n _warnMismatch();\n\n var relativeScroll = $scrollPosition - options.offsetBefore - scrollOffset;\n\n var _binaryFind = binaryFind($scope.vsRepeat.sizesCumulative, relativeScroll - options.scrollMargin);\n\n var _binaryFind2 = _slicedToArray(_binaryFind, 1);\n\n __startIndex = _binaryFind2[0];\n __startIndex = Math.max(__startIndex, 0);\n\n var _binaryFind3 = binaryFind($scope.vsRepeat.sizesCumulative, relativeScroll + options.scrollMargin + $clientSize, __startIndex);\n\n var _binaryFind4 = _slicedToArray(_binaryFind3, 2);\n\n __endIndex = _binaryFind4[1];\n __endIndex = Math.min(__endIndex, originalLength);\n }\n\n _minStartIndex = Math.min(__startIndex, _minStartIndex);\n _maxEndIndex = Math.max(__endIndex, _maxEndIndex);\n $scope.vsRepeat.startIndex = options.latch ? _minStartIndex : __startIndex;\n $scope.vsRepeat.endIndex = options.latch ? _maxEndIndex : __endIndex; // Move to the end of the collection if we are now past it\n\n if (_maxEndIndex < $scope.vsRepeat.startIndex) $scope.vsRepeat.startIndex = _maxEndIndex;\n var digestRequired = false;\n\n if (_prevStartIndex == null) {\n digestRequired = true;\n } else if (_prevEndIndex == null) {\n digestRequired = true;\n }\n\n if (!digestRequired) {\n if (options.hunked) {\n if (Math.abs($scope.vsRepeat.startIndex - _prevStartIndex) >= options.hunkSize || $scope.vsRepeat.startIndex === 0 && _prevStartIndex !== 0) {\n digestRequired = true;\n } else if (Math.abs($scope.vsRepeat.endIndex - _prevEndIndex) >= options.hunkSize || $scope.vsRepeat.endIndex === originalLength && _prevEndIndex !== originalLength) {\n digestRequired = true;\n }\n } else {\n digestRequired = $scope.vsRepeat.startIndex !== _prevStartIndex || $scope.vsRepeat.endIndex !== _prevEndIndex;\n }\n }\n\n if (digestRequired) {\n $scope[collectionName] = originalCollection.slice($scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex); // Emit the event\n\n $scope.$emit('vsRepeatInnerCollectionUpdated', $scope.vsRepeat.startIndex, $scope.vsRepeat.endIndex, _prevStartIndex, _prevEndIndex);\n var triggerIndex;\n\n if (options.scrolledToEnd) {\n triggerIndex = originalCollection.length - options.scrolledToEndOffset;\n\n if ($scope.vsRepeat.endIndex >= triggerIndex && _prevEndIndex < triggerIndex || originalCollection.length && $scope.vsRepeat.endIndex === originalCollection.length) {\n $scope.$eval(options.scrolledToEnd);\n }\n }\n\n if (options.scrolledToBeginning) {\n triggerIndex = options.scrolledToBeginningOffset;\n\n if ($scope.vsRepeat.startIndex <= triggerIndex && _prevStartIndex > $scope.vsRepeat.startIndex) {\n $scope.$eval(options.scrolledToBeginning);\n }\n }\n\n _prevStartIndex = $scope.vsRepeat.startIndex;\n _prevEndIndex = $scope.vsRepeat.endIndex;\n var o1 = $scope.vsRepeat.sizesCumulative[$scope.vsRepeat.startIndex] + options.offsetBefore;\n var o2 = $scope.vsRepeat.sizesCumulative[$scope.vsRepeat.startIndex + $scope[collectionName].length] + options.offsetBefore;\n var total = $scope.vsRepeat.totalSize;\n $beforeContent.css(getLayoutProps(o1 + 'px'));\n $afterContent.css(getLayoutProps(total - o2 + 'px'));\n }\n\n return digestRequired;\n }\n\n function _warnMismatch() {\n $scope.$$postDigest(function () {\n window.requestAnimationFrame(function () {\n var expectedSize = $scope.vsRepeat.sizesCumulative[originalLength];\n var compStyle = window.getComputedStyle(repeatContainer[0]);\n var paddings = options.horizontal ? ['paddingLeft', 'paddingRight'] : ['paddingTop', 'paddingBottom'];\n var containerSize = repeatContainer[0][scrollSize] - paddings.reduce(function (acc, prop) {\n return acc + Number(compStyle[prop].slice(0, -2));\n }, 0);\n\n if (repeatContainer[0][scrollSize] && expectedSize !== containerSize) {\n console.warn('vsRepeat: size mismatch. Expected size ' + expectedSize + 'px whereas actual size is ' + containerSize + 'px. Fix vsSize on element:', $element[0]);\n }\n });\n });\n }\n }\n };\n }\n };\n }]);\n angular.element(document.head).append(\"<style id=\\\"angular-vs-repeat-style\\\">\\n\\t \\t.vs-repeat-debug-element {\\n top: 50%;\\n left: 0;\\n right: 0;\\n height: 1px;\\n background: red;\\n z-index: 99999999;\\n box-shadow: 0 0 20px red;\\n }\\n\\n .vs-repeat-debug-element + .vs-repeat-debug-element {\\n display: none;\\n }\\n\\n .vs-repeat-before-content,\\n .vs-repeat-after-content {\\n border: none !important;\\n padding: 0 !important;\\n }\\n </style>\");\n\n if (typeof module !== 'undefined' && module.exports) {\n module.exports = vsRepeatModule.name;\n }\n})(window, window.angular);"],"sourceRoot":""} | ||
1282 | 2 | \ No newline at end of file | 1 | \ No newline at end of file |
1283 | 2 | {"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/maasserver/static/js/angular/3rdparty/ng-tags-input.js","webpack:///./src/maasserver/static/js/angular/3rdparty/vs-repeat.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","r","value","n","__esModule","object","property","prototype","hasOwnProperty","p","s","KEYS","SUPPORTED_INPUT_TYPES","tagsInput","angular","directive","$timeout","$document","$window","tagsInputConfig","tiUtil","validateType","type","indexOf","restrict","require","scope","tags","onTagAdding","onTagAdded","onInvalidTag","onTagRemoving","onTagRemoved","replace","transclude","templateUrl","controller","$scope","$attrs","$element","events","simplePubSub","load","template","String","placeholder","tabindex","Number","removeTagSymbol","fromCharCode","replaceSpacesWithDashes","Boolean","minLength","maxLength","addOnEnter","addOnSpace","addOnComma","addOnBlur","addOnPaste","pasteSplitPattern","RegExp","allowedTagsPattern","enableEditingLastTag","minTags","maxTags","displayProperty","keyProperty","allowLeftoverText","addFromAutocompleteOnly","spellcheck","tagList","options","getTagText","setTagText","tagIsValid","self","tag","safeToString","text","tagText","length","test","findInObjectArray","items","$tag","addText","add","push","trigger","remove","index","splice","clearSelection","select","selected","selectPrior","selectNext","removeSelected","handleUndefinedResult","this","registerAutocomplete","find","addTag","focusInput","getTags","getCurrentTagText","newTag","getOptions","on","handler","registerTagItem","removeTag","disabled","link","element","attrs","ngModelCtrl","setElementValidity","hotkeys","input","validationOptions","$setValidity","hasFocus","$isEmpty","invalid","setText","track","$watch","makeObjectArray","$observe","eventHandlers","change","keydown","$event","focus","blur","activeElement","prop","lostFocusToBrowserWindow","lostFocusToChildElement","contains","paste","getTextData","clipboardData","originalEvent","getData","host","click","$setViewValue","e","triggerHandler","event","shouldAdd","shouldRemove","shouldSelect","shouldEditLastTag","key","keyCode","addKeys","shiftKey","altKey","ctrlKey","metaKey","preventDefault","split","forEach","data","tagsInputCtrl","$$template","$$removeTagSymbol","$getDisplayText","$removeTag","$index","$sce","$q","source","debounceDelay","highlightMatchedText","maxResultsToShow","loadOnDownArrow","loadOnEmpty","loadOnFocus","selectFirstMatch","suggestionList","loadFn","getDifference","lastPromise","getTagId","array1","array2","filter","item","a","b","defaultComparer","reset","visible","query","show","debounce","promise","when","$query","then","slice","registerAutocompleteMatch","getQuery","shouldLoadSuggestions","addSuggestionByIndex","addSuggestion","added","copy","handled","stopImmediatePropagation","root","eq","parent","elementTop","elementHeight","parentHeight","parentScrollTop","scrollToElement","autoCompleteCtrl","autoComplete","$parent","$highlight","safeHighlight","trustAsHtml","ctrl","transcludeFn","clone","append","span","resize","threshold","getTextAutosizeThreshold","css","originalValue","width","isString","$parsers","unshift","$formatters","$modelValue","tiBindAttrs","$set","provider","globalDefaults","interpolationStatus","autosizeThreshold","setDefaults","defaults","setActiveInterpolation","setTextAutosizeThreshold","$get","$interpolate","converters","parseInt","toLowerCase","defaultValidator","localDefault","validator","converter","getDefault","updateValue","globalValue","isDefined","newValue","factory","fn","delay","timeoutId","args","arguments","cancel","apply","array","isObject","obj","comparer","some","str","encodeHTML","expression","escapeRegexChars","match","isUndefined","toString","trim","valueIfUndefined","result","names","every","run","$templateCache","put","window","dde","document","documentElement","matchingFunction","matches","matchesSelector","webkitMatches","webkitMatchesSelector","msMatches","msMatchesSelector","mozMatches","mozMatchesSelector","closestElement","closest","selector","el","parentNode","getWindowScroll","scrollTop","pageYOffset","scrollLeft","pageXOffset","sx","body","getClientSize","sizeProp","innerWidth","innerHeight","vsRepeatModule","$compile","$parse","compile","ngRepeatExpression","expressionMatches","lhs","rhs","rhsSuffix","originalNgRepeatAttr","repeatContainer","vsRepeatContainer","querySelector","ngRepeatChild","children","childCloneHtml","outerHTML","collectionName","isNgRepeatStart","attributesDictionary","vsRepeat","vsOffsetBefore","vsOffsetAfter","vsScrolledToEndOffset","vsScrolledToBeginningOffset","vsExcess","attr","Error","exec","repeaterElement","empty","pre","originalLength","_prevStartIndex","_prevEndIndex","_minStartIndex","_maxEndIndex","_prevClientSize","childClone","childTagName","tagName","originalCollection","$$horizontal","vsHorizontal","$beforeContent","$afterContent","autoSize","sizesPropertyExists","vsSize","vsSizeProperty","$scrollParent","vsScrollParent","$$options","$eval","vsOptions","clientSize","offsetSize","scrollPos","totalSize","console","warn","refresh","sizesCumulative","sizes","map","$new","extend","size","elementSize","$destroy","sum","res","setAutoSize","reinitialize","$$postDigest","offsetHeight","offsetWidth","gotSomething","insideStartEndSequence","attributes","$root","$$phase","$apply","dereg","getLayoutProp","layoutPropPrefix","scrollHandler","updateInnerCollection","$digest","onWindowResize","vsAutoresize","offsetBefore","offsetAfter","$emit","startIndex","endIndex","reinitOnClientHeightChange","ch","scrollProp","vsElement","scrollElement","isHorizontal","$scrollPosition","$clientSize","scrollOffset","getBoundingClientRect","__startIndex","__endIndex","Math","max","floor","excess","min","ceil","latch","digestRequired","hunked","abs","triggerIndex","vsScrolledToEnd","scrolledToEndOffset","vsScrolledToBeginning","scrolledToBeginningOffset","parsed","o1","o2","total","keys","$watchCollection","coll","addClass","$on","off","setTimeout","requestAnimationFrame"],"mappings":"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","file":"vendor-min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","/*!\n * ngTagsInput v2.3.0\n * http://mbenford.github.io/ngTagsInput\n *\n * Copyright (c) 2013-2015 Michael Benford\n * License: MIT\n *\n * Generated at 2015-03-24 00:49:44 -0300\n */\n(function() {\n'use strict';\n\nvar KEYS = {\n backspace: 8,\n tab: 9,\n enter: 13,\n escape: 27,\n space: 32,\n up: 38,\n down: 40,\n left: 37,\n right: 39,\n delete: 46,\n comma: 188\n};\n\nvar MAX_SAFE_INTEGER = 9007199254740991;\nvar SUPPORTED_INPUT_TYPES = ['text', 'email', 'url'];\n\nvar tagsInput = angular.module('ngTagsInput', []);\n\n/**\n * @ngdoc directive\n * @name tagsInput\n * @module ngTagsInput\n *\n * @description\n * Renders an input box with tag editing support.\n *\n * @param {string} ngModel Assignable angular expression to data-bind to.\n * @param {string=} [displayProperty=text] Property to be rendered as the tag label.\n * @param {string=} [keyProperty=text] Property to be used as a unique identifier for the tag.\n * @param {string=} [type=text] Type of the input element. Only 'text', 'email' and 'url' are supported values.\n * @param {number=} tabindex Tab order of the control.\n * @param {string=} [placeholder=Add a tag] Placeholder text for the control.\n * @param {number=} [minLength=3] Minimum length for a new tag.\n * @param {number=} [maxLength=MAX_SAFE_INTEGER] Maximum length allowed for a new tag.\n * @param {number=} [minTags=0] Sets minTags validation error key if the number of tags added is less than minTags.\n * @param {number=} [maxTags=MAX_SAFE_INTEGER] Sets maxTags validation error key if the number of tags added is greater than maxTags.\n * @param {boolean=} [allowLeftoverText=false] Sets leftoverText validation error key if there is any leftover text in\n * the input element when the directive loses focus.\n * @param {string=} [removeTagSymbol=×] Symbol character for the remove tag button.\n * @param {boolean=} [addOnEnter=true] Flag indicating that a new tag will be added on pressing the ENTER key.\n * @param {boolean=} [addOnSpace=false] Flag indicating that a new tag will be added on pressing the SPACE key.\n * @param {boolean=} [addOnComma=true] Flag indicating that a new tag will be added on pressing the COMMA key.\n * @param {boolean=} [addOnBlur=true] Flag indicating that a new tag will be added when the input field loses focus.\n * @param {boolean=} [addOnPaste=false] Flag indicating that the text pasted into the input field will be split into tags.\n * @param {string=} [pasteSplitPattern=,] Regular expression used to split the pasted text into tags.\n * @param {boolean=} [replaceSpacesWithDashes=true] Flag indicating that spaces will be replaced with dashes.\n * @param {string=} [allowedTagsPattern=.+] Regular expression that determines whether a new tag is valid.\n * @param {boolean=} [enableEditingLastTag=false] Flag indicating that the last tag will be moved back into\n * the new tag input box instead of being removed when the backspace key\n * is pressed and the input box is empty.\n * @param {boolean=} [addFromAutocompleteOnly=false] Flag indicating that only tags coming from the autocomplete list will be allowed.\n * When this flag is true, addOnEnter, addOnComma, addOnSpace, addOnBlur and\n * allowLeftoverText values are ignored.\n * @param {boolean=} [spellcheck=true] Flag indicating whether the browser's spellcheck is enabled for the input field or not.\n * @param {expression} onTagAdding Expression to evaluate that will be invoked before adding a new tag. The new tag is available as $tag. This method must return either true or false. If false, the tag will not be added.\n * @param {expression} onTagAdded Expression to evaluate upon adding a new tag. The new tag is available as $tag.\n * @param {expression} onInvalidTag Expression to evaluate when a tag is invalid. The invalid tag is available as $tag.\n * @param {expression} onTagRemoving Expression to evaluate that will be invoked before removing a tag. The tag is available as $tag. This method must return either true or false. If false, the tag will not be removed.\n * @param {expression} onTagRemoved Expression to evaluate upon removing an existing tag. The removed tag is available as $tag.\n */\ntagsInput.directive('tagsInput', [\"$timeout\",\"$document\",\"$window\",\"tagsInputConfig\",\"tiUtil\", function($timeout, $document, $window, tagsInputConfig, tiUtil) {\n function TagList(options, events, onTagAdding, onTagRemoving) {\n var self = {}, getTagText, setTagText, tagIsValid;\n\n getTagText = function(tag) {\n return tiUtil.safeToString(tag[options.displayProperty]);\n };\n\n setTagText = function(tag, text) {\n tag[options.displayProperty] = text;\n };\n\n tagIsValid = function(tag) {\n var tagText = getTagText(tag);\n\n return tagText &&\n tagText.length >= options.minLength &&\n tagText.length <= options.maxLength &&\n options.allowedTagsPattern.test(tagText) &&\n !tiUtil.findInObjectArray(self.items, tag, options.keyProperty || options.displayProperty) &&\n onTagAdding({ $tag: tag });\n };\n\n self.items = [];\n\n self.addText = function(text) {\n var tag = {};\n setTagText(tag, text);\n return self.add(tag);\n };\n\n self.add = function(tag) {\n var tagText = getTagText(tag);\n\n if (options.replaceSpacesWithDashes) {\n tagText = tiUtil.replaceSpacesWithDashes(tagText);\n }\n\n setTagText(tag, tagText);\n\n if (tagIsValid(tag)) {\n self.items.push(tag);\n events.trigger('tag-added', { $tag: tag });\n }\n else if (tagText) {\n events.trigger('invalid-tag', { $tag: tag });\n }\n\n return tag;\n };\n\n self.remove = function(index) {\n var tag = self.items[index];\n\n if (onTagRemoving({ $tag: tag })) {\n self.items.splice(index, 1);\n self.clearSelection();\n events.trigger('tag-removed', { $tag: tag });\n return tag;\n }\n };\n\n self.select = function(index) {\n if (index < 0) {\n index = self.items.length - 1;\n }\n else if (index >= self.items.length) {\n index = 0;\n }\n\n self.index = index;\n self.selected = self.items[index];\n };\n\n self.selectPrior = function() {\n self.select(--self.index);\n };\n\n self.selectNext = function() {\n self.select(++self.index);\n };\n\n self.removeSelected = function() {\n return self.remove(self.index);\n };\n\n self.clearSelection = function() {\n self.selected = null;\n self.index = -1;\n };\n\n self.clearSelection();\n\n return self;\n }\n\n function validateType(type) {\n return SUPPORTED_INPUT_TYPES.indexOf(type) !== -1;\n }\n\n return {\n restrict: 'E',\n require: 'ngModel',\n scope: {\n tags: '=ngModel',\n onTagAdding: '&',\n onTagAdded: '&',\n onInvalidTag: '&',\n onTagRemoving: '&',\n onTagRemoved: '&'\n },\n replace: false,\n transclude: true,\n templateUrl: 'ngTagsInput/tags-input.html',\n controller: [\"$scope\",\"$attrs\",\"$element\", function($scope, $attrs, $element) {\n $scope.events = tiUtil.simplePubSub();\n\n tagsInputConfig.load('tagsInput', $scope, $attrs, {\n template: [String, 'ngTagsInput/tag-item.html'],\n type: [String, 'text', validateType],\n placeholder: [String, 'Add a tag'],\n tabindex: [Number, null],\n removeTagSymbol: [String, String.fromCharCode(215)],\n replaceSpacesWithDashes: [Boolean, true],\n minLength: [Number, 3],\n maxLength: [Number, MAX_SAFE_INTEGER],\n addOnEnter: [Boolean, true],\n addOnSpace: [Boolean, false],\n addOnComma: [Boolean, true],\n addOnBlur: [Boolean, true],\n addOnPaste: [Boolean, false],\n pasteSplitPattern: [RegExp, /,/],\n allowedTagsPattern: [RegExp, /.+/],\n enableEditingLastTag: [Boolean, false],\n minTags: [Number, 0],\n maxTags: [Number, MAX_SAFE_INTEGER],\n displayProperty: [String, 'text'],\n keyProperty: [String, ''],\n allowLeftoverText: [Boolean, false],\n addFromAutocompleteOnly: [Boolean, false],\n spellcheck: [Boolean, true]\n });\n\n $scope.tagList = new TagList($scope.options, $scope.events,\n tiUtil.handleUndefinedResult($scope.onTagAdding, true),\n tiUtil.handleUndefinedResult($scope.onTagRemoving, true));\n\n this.registerAutocomplete = function() {\n var input = $element.find('input');\n\n return {\n addTag: function(tag) {\n return $scope.tagList.add(tag);\n },\n focusInput: function() {\n // blake_r - Stop the focus as this breaks on the\n // version of AngularJS that ships with MAAS.\n //input[0].focus();\n },\n getTags: function() {\n return $scope.tags;\n },\n getCurrentTagText: function() {\n return $scope.newTag.text;\n },\n getOptions: function() {\n return $scope.options;\n },\n on: function(name, handler) {\n $scope.events.on(name, handler);\n return this;\n }\n };\n };\n\n this.registerTagItem = function() {\n return {\n getOptions: function() {\n return $scope.options;\n },\n removeTag: function(index) {\n if ($scope.disabled) {\n return;\n }\n $scope.tagList.remove(index);\n }\n };\n };\n }],\n link: function(scope, element, attrs, ngModelCtrl) {\n var hotkeys = [KEYS.enter, KEYS.comma, KEYS.space, KEYS.backspace, KEYS.delete, KEYS.left, KEYS.right],\n tagList = scope.tagList,\n events = scope.events,\n options = scope.options,\n input = element.find('input'),\n validationOptions = ['minTags', 'maxTags', 'allowLeftoverText'],\n setElementValidity;\n\n setElementValidity = function() {\n ngModelCtrl.$setValidity('maxTags', scope.tags.length <= options.maxTags);\n ngModelCtrl.$setValidity('minTags', scope.tags.length >= options.minTags);\n ngModelCtrl.$setValidity('leftoverText', scope.hasFocus || options.allowLeftoverText ? true : !scope.newTag.text);\n };\n\n ngModelCtrl.$isEmpty = function(value) {\n return !value || !value.length;\n };\n\n scope.newTag = {\n text: '',\n invalid: null,\n setText: function(value) {\n this.text = value;\n events.trigger('input-change', value);\n }\n };\n\n scope.track = function(tag) {\n return tag[options.keyProperty || options.displayProperty];\n };\n\n scope.$watch('tags', function(value) {\n scope.tags = tiUtil.makeObjectArray(value, options.displayProperty);\n tagList.items = scope.tags;\n });\n\n scope.$watch('tags.length', function() {\n setElementValidity();\n });\n\n attrs.$observe('disabled', function(value) {\n scope.disabled = value;\n });\n\n scope.eventHandlers = {\n input: {\n change: function(text) {\n events.trigger('input-change', text);\n },\n keydown: function($event) {\n events.trigger('input-keydown', $event);\n },\n focus: function() {\n if (scope.hasFocus) {\n return;\n }\n\n scope.hasFocus = true;\n events.trigger('input-focus');\n },\n blur: function() {\n $timeout(function() {\n var activeElement = $document.prop('activeElement'),\n lostFocusToBrowserWindow = activeElement === input[0],\n lostFocusToChildElement = element[0].contains(activeElement);\n\n if (lostFocusToBrowserWindow || !lostFocusToChildElement) {\n scope.hasFocus = false;\n events.trigger('input-blur');\n }\n });\n },\n paste: function($event) {\n $event.getTextData = function() {\n var clipboardData = $event.clipboardData || ($event.originalEvent && $event.originalEvent.clipboardData);\n return clipboardData ? clipboardData.getData('text/plain') : $window.clipboardData.getData('Text');\n };\n events.trigger('input-paste', $event);\n }\n },\n host: {\n click: function() {\n if (scope.disabled) {\n return;\n }\n // blake_r - Stop the focus as this breaks on the\n // version of AngularJS that ships with MAAS.\n //input[0].focus();\n }\n }\n };\n\n events\n .on('tag-added', scope.onTagAdded)\n .on('invalid-tag', scope.onInvalidTag)\n .on('tag-removed', scope.onTagRemoved)\n .on('tag-added', function() {\n scope.newTag.setText('');\n })\n .on('tag-added tag-removed', function() {\n // Sets the element to its dirty state\n // In Angular 1.3 this will be replaced with $setDirty.\n ngModelCtrl.$setViewValue(scope.tags);\n })\n .on('invalid-tag', function() {\n scope.newTag.invalid = true;\n })\n .on('option-change', function(e) {\n if (validationOptions.indexOf(e.name) !== -1) {\n setElementValidity();\n }\n })\n .on('input-change', function() {\n tagList.clearSelection();\n scope.newTag.invalid = null;\n })\n .on('input-focus', function() {\n element.triggerHandler('focus');\n ngModelCtrl.$setValidity('leftoverText', true);\n })\n .on('input-blur', function() {\n if (options.addOnBlur && !options.addFromAutocompleteOnly) {\n tagList.addText(scope.newTag.text);\n }\n element.triggerHandler('blur');\n setElementValidity();\n })\n .on('input-keydown', function(event) {\n var key = event.keyCode,\n isModifier = event.shiftKey || event.altKey || event.ctrlKey || event.metaKey,\n addKeys = {},\n shouldAdd, shouldRemove, shouldSelect, shouldEditLastTag;\n\n if (isModifier || hotkeys.indexOf(key) === -1) {\n return;\n }\n\n addKeys[KEYS.enter] = options.addOnEnter;\n addKeys[KEYS.comma] = options.addOnComma;\n addKeys[KEYS.space] = options.addOnSpace;\n\n shouldAdd = !options.addFromAutocompleteOnly && addKeys[key];\n shouldRemove = (key === KEYS.backspace || key === KEYS.delete) && tagList.selected;\n shouldEditLastTag = key === KEYS.backspace && scope.newTag.text.length === 0 && options.enableEditingLastTag;\n shouldSelect = (key === KEYS.backspace || key === KEYS.left || key === KEYS.right) && scope.newTag.text.length === 0 && !options.enableEditingLastTag;\n\n if (shouldAdd) {\n tagList.addText(scope.newTag.text);\n }\n else if (shouldEditLastTag) {\n var tag;\n\n tagList.selectPrior();\n tag = tagList.removeSelected();\n\n if (tag) {\n scope.newTag.setText(tag[options.displayProperty]);\n }\n }\n else if (shouldRemove) {\n tagList.removeSelected();\n }\n else if (shouldSelect) {\n if (key === KEYS.left || key === KEYS.backspace) {\n tagList.selectPrior();\n }\n else if (key === KEYS.right) {\n tagList.selectNext();\n }\n }\n\n if (shouldAdd || shouldSelect || shouldRemove || shouldEditLastTag) {\n event.preventDefault();\n }\n })\n .on('input-paste', function(event) {\n if (options.addOnPaste) {\n var data = event.getTextData();\n var tags = data.split(options.pasteSplitPattern);\n\n if (tags.length > 1) {\n tags.forEach(function(tag) {\n tagList.addText(tag);\n });\n event.preventDefault();\n }\n }\n });\n }\n };\n}]);\n\n\n/**\n * @ngdoc directive\n * @name tiTagItem\n * @module ngTagsInput\n *\n * @description\n * Represents a tag item. Used internally by the tagsInput directive.\n */\ntagsInput.directive('tiTagItem', [\"tiUtil\", function(tiUtil) {\n return {\n restrict: 'E',\n require: '^tagsInput',\n template: '<ng-include src=\"$$template\"></ng-include>',\n scope: { data: '=' },\n link: function(scope, element, attrs, tagsInputCtrl) {\n var tagsInput = tagsInputCtrl.registerTagItem(),\n options = tagsInput.getOptions();\n\n scope.$$template = options.template;\n scope.$$removeTagSymbol = options.removeTagSymbol;\n\n scope.$getDisplayText = function() {\n return tiUtil.safeToString(scope.data[options.displayProperty]);\n };\n scope.$removeTag = function() {\n tagsInput.removeTag(scope.$index);\n };\n\n scope.$watch('$parent.$index', function(value) {\n scope.$index = value;\n });\n }\n };\n}]);\n\n\n/**\n * @ngdoc directive\n * @name autoComplete\n * @module ngTagsInput\n *\n * @description\n * Provides autocomplete support for the tagsInput directive.\n *\n * @param {expression} source Expression to evaluate upon changing the input content. The input value is available as\n * $query. The result of the expression must be a promise that eventually resolves to an\n * array of strings.\n * @param {string=} [displayProperty=text] Property to be rendered as the autocomplete label.\n * @param {number=} [debounceDelay=100] Amount of time, in milliseconds, to wait before evaluating the expression in\n * the source option after the last keystroke.\n * @param {number=} [minLength=3] Minimum number of characters that must be entered before evaluating the expression\n * in the source option.\n * @param {boolean=} [highlightMatchedText=true] Flag indicating that the matched text will be highlighted in the\n * suggestions list.\n * @param {number=} [maxResultsToShow=10] Maximum number of results to be displayed at a time.\n * @param {boolean=} [loadOnDownArrow=false] Flag indicating that the source option will be evaluated when the down arrow\n * key is pressed and the suggestion list is closed. The current input value\n * is available as $query.\n * @param {boolean=} {loadOnEmpty=false} Flag indicating that the source option will be evaluated when the input content\n * becomes empty. The $query variable will be passed to the expression as an empty string.\n * @param {boolean=} {loadOnFocus=false} Flag indicating that the source option will be evaluated when the input element\n * gains focus. The current input value is available as $query.\n * @param {boolean=} [selectFirstMatch=true] Flag indicating that the first match will be automatically selected once\n * the suggestion list is shown.\n * @param {string=} [template=] URL or id of a custom template for rendering each element of the autocomplete list.\n */\ntagsInput.directive('autoComplete', [\"$document\",\"$timeout\",\"$sce\",\"$q\",\"tagsInputConfig\",\"tiUtil\", function($document, $timeout, $sce, $q, tagsInputConfig, tiUtil) {\n function SuggestionList(loadFn, options, events) {\n var self = {}, getDifference, lastPromise, getTagId;\n\n getTagId = function() {\n return options.tagsInput.keyProperty || options.tagsInput.displayProperty;\n };\n\n getDifference = function(array1, array2) {\n return array1.filter(function(item) {\n return !tiUtil.findInObjectArray(array2, item, getTagId(), function(a, b) {\n if (options.tagsInput.replaceSpacesWithDashes) {\n a = tiUtil.replaceSpacesWithDashes(a);\n b = tiUtil.replaceSpacesWithDashes(b);\n }\n return tiUtil.defaultComparer(a, b);\n });\n });\n };\n\n self.reset = function() {\n lastPromise = null;\n\n self.items = [];\n self.visible = false;\n self.index = -1;\n self.selected = null;\n self.query = null;\n };\n self.show = function() {\n if (options.selectFirstMatch) {\n self.select(0);\n }\n else {\n self.selected = null;\n }\n self.visible = true;\n };\n self.load = tiUtil.debounce(function(query, tags) {\n self.query = query;\n\n var promise = $q.when(loadFn({ $query: query }));\n lastPromise = promise;\n\n promise.then(function(items) {\n if (promise !== lastPromise) {\n return;\n }\n\n items = tiUtil.makeObjectArray(items.data || items, getTagId());\n items = getDifference(items, tags);\n self.items = items.slice(0, options.maxResultsToShow);\n\n if (self.items.length > 0) {\n self.show();\n }\n else {\n self.reset();\n }\n });\n }, options.debounceDelay);\n\n self.selectNext = function() {\n self.select(++self.index);\n };\n self.selectPrior = function() {\n self.select(--self.index);\n };\n self.select = function(index) {\n if (index < 0) {\n index = self.items.length - 1;\n }\n else if (index >= self.items.length) {\n index = 0;\n }\n self.index = index;\n self.selected = self.items[index];\n events.trigger('suggestion-selected', index);\n };\n\n self.reset();\n\n return self;\n }\n\n function scrollToElement(root, index) {\n var element = root.find('li').eq(index),\n parent = element.parent(),\n elementTop = element.prop('offsetTop'),\n elementHeight = element.prop('offsetHeight'),\n parentHeight = parent.prop('clientHeight'),\n parentScrollTop = parent.prop('scrollTop');\n\n if (elementTop < parentScrollTop) {\n parent.prop('scrollTop', elementTop);\n }\n else if (elementTop + elementHeight > parentHeight + parentScrollTop) {\n parent.prop('scrollTop', elementTop + elementHeight - parentHeight);\n }\n }\n\n return {\n restrict: 'E',\n require: '^tagsInput',\n scope: { source: '&' },\n templateUrl: 'ngTagsInput/auto-complete.html',\n controller: [\"$scope\",\"$element\",\"$attrs\", function($scope, $element, $attrs) {\n $scope.events = tiUtil.simplePubSub();\n\n tagsInputConfig.load('autoComplete', $scope, $attrs, {\n template: [String, 'ngTagsInput/auto-complete-match.html'],\n debounceDelay: [Number, 100],\n minLength: [Number, 3],\n highlightMatchedText: [Boolean, true],\n maxResultsToShow: [Number, 10],\n loadOnDownArrow: [Boolean, false],\n loadOnEmpty: [Boolean, false],\n loadOnFocus: [Boolean, false],\n selectFirstMatch: [Boolean, true],\n displayProperty: [String, '']\n });\n\n $scope.suggestionList = new SuggestionList($scope.source, $scope.options, $scope.events);\n\n this.registerAutocompleteMatch = function() {\n return {\n getOptions: function() {\n return $scope.options;\n },\n getQuery: function() {\n return $scope.suggestionList.query;\n }\n };\n };\n }],\n link: function(scope, element, attrs, tagsInputCtrl) {\n var hotkeys = [KEYS.enter, KEYS.tab, KEYS.escape, KEYS.up, KEYS.down],\n suggestionList = scope.suggestionList,\n tagsInput = tagsInputCtrl.registerAutocomplete(),\n options = scope.options,\n events = scope.events,\n shouldLoadSuggestions;\n\n options.tagsInput = tagsInput.getOptions();\n\n shouldLoadSuggestions = function(value) {\n return value && value.length >= options.minLength || !value && options.loadOnEmpty;\n };\n\n scope.addSuggestionByIndex = function(index) {\n suggestionList.select(index);\n scope.addSuggestion();\n };\n\n scope.addSuggestion = function() {\n var added = false;\n\n if (suggestionList.selected) {\n tagsInput.addTag(angular.copy(suggestionList.selected));\n suggestionList.reset();\n tagsInput.focusInput();\n\n added = true;\n }\n return added;\n };\n\n scope.track = function(item) {\n return item[options.tagsInput.keyProperty || options.tagsInput.displayProperty];\n };\n\n tagsInput\n .on('tag-added invalid-tag input-blur', function() {\n suggestionList.reset();\n })\n .on('input-change', function(value) {\n if (shouldLoadSuggestions(value)) {\n suggestionList.load(value, tagsInput.getTags());\n }\n else {\n suggestionList.reset();\n }\n })\n .on('input-focus', function() {\n var value = tagsInput.getCurrentTagText();\n if (options.loadOnFocus && shouldLoadSuggestions(value)) {\n suggestionList.load(value, tagsInput.getTags());\n }\n })\n .on('input-keydown', function(event) {\n var key = event.keyCode,\n handled = false;\n\n if (hotkeys.indexOf(key) === -1) {\n return;\n }\n\n if (suggestionList.visible) {\n\n if (key === KEYS.down) {\n suggestionList.selectNext();\n handled = true;\n }\n else if (key === KEYS.up) {\n suggestionList.selectPrior();\n handled = true;\n }\n else if (key === KEYS.escape) {\n suggestionList.reset();\n handled = true;\n }\n else if (key === KEYS.enter || key === KEYS.tab) {\n handled = scope.addSuggestion();\n }\n }\n else {\n if (key === KEYS.down && scope.options.loadOnDownArrow) {\n suggestionList.load(tagsInput.getCurrentTagText(), tagsInput.getTags());\n handled = true;\n }\n }\n\n if (handled) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return false;\n }\n });\n\n events.on('suggestion-selected', function(index) {\n scrollToElement(element, index);\n });\n }\n };\n}]);\n\n\n/**\n * @ngdoc directive\n * @name tiAutocompleteMatch\n * @module ngTagsInput\n *\n * @description\n * Represents an autocomplete match. Used internally by the autoComplete directive.\n */\ntagsInput.directive('tiAutocompleteMatch', [\"$sce\",\"tiUtil\", function($sce, tiUtil) {\n return {\n restrict: 'E',\n require: '^autoComplete',\n template: '<ng-include src=\"$$template\"></ng-include>',\n scope: { data: '=' },\n link: function(scope, element, attrs, autoCompleteCtrl) {\n var autoComplete = autoCompleteCtrl.registerAutocompleteMatch(),\n options = autoComplete.getOptions();\n\n scope.$$template = options.template;\n scope.$index = scope.$parent.$index;\n\n scope.$highlight = function(text) {\n if (options.highlightMatchedText) {\n text = tiUtil.safeHighlight(text, autoComplete.getQuery());\n }\n return $sce.trustAsHtml(text);\n };\n scope.$getDisplayText = function() {\n return tiUtil.safeToString(scope.data[options.displayProperty || options.tagsInput.displayProperty]);\n };\n }\n };\n}]);\n\n\n/**\n * @ngdoc directive\n * @name tiTranscludeAppend\n * @module ngTagsInput\n *\n * @description\n * Re-creates the old behavior of ng-transclude. Used internally by tagsInput directive.\n */\ntagsInput.directive('tiTranscludeAppend', function() {\n return function(scope, element, attrs, ctrl, transcludeFn) {\n transcludeFn(function(clone) {\n element.append(clone);\n });\n };\n});\n\n/**\n * @ngdoc directive\n * @name tiAutosize\n * @module ngTagsInput\n *\n * @description\n * Automatically sets the input's width so its content is always visible. Used internally by tagsInput directive.\n */\ntagsInput.directive('tiAutosize', [\"tagsInputConfig\", function(tagsInputConfig) {\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function(scope, element, attrs, ctrl) {\n var threshold = tagsInputConfig.getTextAutosizeThreshold(),\n span, resize;\n\n span = angular.element('<span class=\"input\"></span>');\n span.css('display', 'none')\n .css('visibility', 'hidden')\n .css('width', 'auto')\n .css('white-space', 'pre');\n\n element.parent().append(span);\n\n resize = function(originalValue) {\n var value = originalValue, width;\n\n if (angular.isString(value) && value.length === 0) {\n value = attrs.placeholder;\n }\n\n if (value) {\n span.text(value);\n span.css('display', '');\n width = span.prop('offsetWidth');\n span.css('display', 'none');\n }\n\n element.css('width', width ? width + threshold + 'px' : '');\n\n return originalValue;\n };\n\n ctrl.$parsers.unshift(resize);\n ctrl.$formatters.unshift(resize);\n\n attrs.$observe('placeholder', function(value) {\n if (!ctrl.$modelValue) {\n resize(value);\n }\n });\n }\n };\n}]);\n\n/**\n * @ngdoc directive\n * @name tiBindAttrs\n * @module ngTagsInput\n *\n * @description\n * Binds attributes to expressions. Used internally by tagsInput directive.\n */\ntagsInput.directive('tiBindAttrs', function() {\n return function(scope, element, attrs) {\n scope.$watch(attrs.tiBindAttrs, function(value) {\n angular.forEach(value, function(value, key) {\n /**\n * blake_r - Added to work around the version of jQuery that\n * MAAS currently ships with. Once packaging for jQuery is\n * version >1.9 this can be removed.\n */\n if(key === \"type\") {\n element[0].type = value;\n } else {\n attrs.$set(key, value);\n }\n });\n }, true);\n };\n});\n\n/**\n * @ngdoc service\n * @name tagsInputConfig\n * @module ngTagsInput\n *\n * @description\n * Sets global configuration settings for both tagsInput and autoComplete directives. It's also used internally to parse and\n * initialize options from HTML attributes.\n */\ntagsInput.provider('tagsInputConfig', function() {\n var globalDefaults = {},\n interpolationStatus = {},\n autosizeThreshold = 3;\n\n /**\n * @ngdoc method\n * @name setDefaults\n * @description Sets the default configuration option for a directive.\n * @methodOf tagsInputConfig\n *\n * @param {string} directive Name of the directive to be configured. Must be either 'tagsInput' or 'autoComplete'.\n * @param {object} defaults Object containing options and their values.\n *\n * @returns {object} The service itself for chaining purposes.\n */\n this.setDefaults = function(directive, defaults) {\n globalDefaults[directive] = defaults;\n return this;\n };\n\n /***\n * @ngdoc method\n * @name setActiveInterpolation\n * @description Sets active interpolation for a set of options.\n * @methodOf tagsInputConfig\n *\n * @param {string} directive Name of the directive to be configured. Must be either 'tagsInput' or 'autoComplete'.\n * @param {object} options Object containing which options should have interpolation turned on at all times.\n *\n * @returns {object} The service itself for chaining purposes.\n */\n this.setActiveInterpolation = function(directive, options) {\n interpolationStatus[directive] = options;\n return this;\n };\n\n /***\n * @ngdoc method\n * @name setTextAutosizeThreshold\n * @description Sets the threshold used by the tagsInput directive to re-size the inner input field element based on its contents.\n * @methodOf tagsInputConfig\n *\n * @param {number} threshold Threshold value, in pixels.\n *\n * @returns {object} The service itself for chaining purposes.\n */\n this.setTextAutosizeThreshold = function(threshold) {\n autosizeThreshold = threshold;\n return this;\n };\n\n this.$get = [\"$interpolate\", function($interpolate) {\n var converters = {};\n converters[String] = function(value) { return value; };\n converters[Number] = function(value) { return parseInt(value, 10); };\n converters[Boolean] = function(value) { return value.toLowerCase() === 'true'; };\n converters[RegExp] = function(value) { return new RegExp(value); };\n\n return {\n load: function(directive, scope, attrs, options) {\n var defaultValidator = function() { return true; };\n\n scope.options = {};\n\n angular.forEach(options, function(value, key) {\n var type, localDefault, validator, converter, getDefault, updateValue;\n\n type = value[0];\n localDefault = value[1];\n validator = value[2] || defaultValidator;\n converter = converters[type];\n\n getDefault = function() {\n var globalValue = globalDefaults[directive] && globalDefaults[directive][key];\n return angular.isDefined(globalValue) ? globalValue : localDefault;\n };\n\n updateValue = function(value) {\n scope.options[key] = value && validator(value) ? converter(value) : getDefault();\n };\n\n if (interpolationStatus[directive] && interpolationStatus[directive][key]) {\n attrs.$observe(key, function(value) {\n updateValue(value);\n scope.events.trigger('option-change', { name: key, newValue: value });\n });\n }\n else {\n updateValue(attrs[key] && $interpolate(attrs[key])(scope.$parent));\n }\n });\n },\n getTextAutosizeThreshold: function() {\n return autosizeThreshold;\n }\n };\n }];\n});\n\n\n/***\n * @ngdoc factory\n * @name tiUtil\n * @module ngTagsInput\n *\n * @description\n * Helper methods used internally by the directive. Should not be called directly from user code.\n */\ntagsInput.factory('tiUtil', [\"$timeout\", function($timeout) {\n var self = {};\n\n self.debounce = function(fn, delay) {\n var timeoutId;\n return function() {\n var args = arguments;\n $timeout.cancel(timeoutId);\n timeoutId = $timeout(function() { fn.apply(null, args); }, delay);\n };\n };\n\n self.makeObjectArray = function(array, key) {\n array = array || [];\n if (array.length > 0 && !angular.isObject(array[0])) {\n array.forEach(function(item, index) {\n array[index] = {};\n array[index][key] = item;\n });\n }\n return array;\n };\n\n self.findInObjectArray = function(array, obj, key, comparer) {\n var item = null;\n comparer = comparer || self.defaultComparer;\n\n array.some(function(element) {\n if (comparer(element[key], obj[key])) {\n item = element;\n return true;\n }\n });\n\n return item;\n };\n\n self.defaultComparer = function(a, b) {\n // I'm aware of the internationalization issues regarding toLowerCase()\n // but I couldn't come up with a better solution right now\n return self.safeToString(a).toLowerCase() === self.safeToString(b).toLowerCase();\n };\n\n self.safeHighlight = function(str, value) {\n if (!value) {\n return str;\n }\n\n function escapeRegexChars(str) {\n return str.replace(/([.?*+^$[\\]\\\\(){}|-])/g, '\\\\$1');\n }\n\n str = self.encodeHTML(str);\n value = self.encodeHTML(value);\n\n var expression = new RegExp('&[^;]+;|' + escapeRegexChars(value), 'gi');\n return str.replace(expression, function(match) {\n return match.toLowerCase() === value.toLowerCase() ? '<em>' + match + '</em>' : match;\n });\n };\n\n self.safeToString = function(value) {\n return angular.isUndefined(value) || value == null ? '' : value.toString().trim();\n };\n\n self.encodeHTML = function(value) {\n return self.safeToString(value)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n };\n\n self.handleUndefinedResult = function(fn, valueIfUndefined) {\n return function() {\n var result = fn.apply(null, arguments);\n return angular.isUndefined(result) ? valueIfUndefined : result;\n };\n };\n\n self.replaceSpacesWithDashes = function(str) {\n return self.safeToString(str).replace(/\\s/g, '-');\n };\n\n self.simplePubSub = function() {\n var events = {};\n return {\n on: function(names, handler) {\n names.split(' ').forEach(function(name) {\n if (!events[name]) {\n events[name] = [];\n }\n events[name].push(handler);\n });\n return this;\n },\n trigger: function(name, args) {\n var handlers = events[name] || [];\n handlers.every(function(handler) {\n return self.handleUndefinedResult(handler, true)(args);\n });\n return this;\n }\n };\n };\n\n return self;\n}]);\n\n/* HTML templates */\ntagsInput.run([\"$templateCache\", function($templateCache) {\n $templateCache.put('ngTagsInput/tags-input.html',\n \"<div class=\\\"host\\\" tabindex=\\\"-1\\\" data-ng-click=\\\"eventHandlers.host.click()\\\" ti-transclude-append=\\\"\\\"><div class=\\\"tags\\\" data-ng-class=\\\"{focused: hasFocus}\\\"><ul class=\\\"tag-list\\\"><li class=\\\"tag-item\\\" data-ng-repeat=\\\"tag in tagList.items track by track(tag)\\\" data-ng-class=\\\"{ selected: tag == tagList.selected }\\\"><ti-tag-item data=\\\"tag\\\"></ti-tag-item></li></ul><input class=\\\"input u-no-margin--top\\\" autocomplete=\\\"off\\\" data-ng-model=\\\"newTag.text\\\" data-ng-change=\\\"eventHandlers.input.change(newTag.text)\\\" data-ng-keydown=\\\"eventHandlers.input.keydown($event)\\\" data-ng-focus=\\\"eventHandlers.input.focus($event)\\\" data-ng-blur=\\\"eventHandlers.input.blur($event)\\\" data-ng-paste=\\\"eventHandlers.input.paste($event)\\\" data-ng-trim=\\\"false\\\" data-ng-class=\\\"{'invalid-tag': newTag.invalid}\\\" data-ng-disabled=\\\"disabled\\\" ti-bind-attrs=\\\"{type: options.type, placeholder: options.placeholder, tabindex: options.tabindex, spellcheck: options.spellcheck}\\\" ti-autosize=\\\"\\\"></div></div>\"\n );\n\n $templateCache.put('ngTagsInput/tag-item.html',\n \"<span ng-bind=\\\"$getDisplayText()\\\"></span> <a class=\\\"p-icon--close\\\" data-ng-click=\\\"$removeTag()\\\" data-ng-bind=\\\"$$removeTagSymbol\\\">Remove tag</a>\"\n );\n\n $templateCache.put('ngTagsInput/auto-complete.html',\n \"<div class=\\\"autocomplete\\\" data-ng-if=\\\"suggestionList.visible\\\"><ul class=\\\"p-list suggestion-list\\\"><li class=\\\"suggestion-item\\\" data-ng-repeat=\\\"item in suggestionList.items track by track(item)\\\" data-ng-class=\\\"{selected: item == suggestionList.selected}\\\" data-ng-click=\\\"addSuggestionByIndex($index)\\\" data-ng-mouseenter=\\\"suggestionList.select($index)\\\"><ti-autocomplete-match data=\\\"item\\\"></ti-autocomplete-match></li></ul></div>\"\n );\n\n $templateCache.put('ngTagsInput/auto-complete-match.html',\n \"<span data-ng-bind-html=\\\"$highlight($getDisplayText())\\\"></span>\"\n );\n}]);\n\n}());\n","//\n// Copyright Kamil Pękala http://github.com/kamilkp\n// Angular Virtual Scroll Repeat v1.1.7 2016/03/08\n//\n\n(function(window, angular) {\n 'use strict';\n /* jshint eqnull:true */\n /* jshint -W038 */\n\n // DESCRIPTION:\n // vsRepeat directive stands for Virtual Scroll Repeat. It turns a standard ngRepeated set of elements in a scrollable container\n // into a component, where the user thinks he has all the elements rendered and all he needs to do is scroll (without any kind of\n // pagination - which most users loath) and at the same time the browser isn't overloaded by that many elements/angular bindings etc.\n // The directive renders only so many elements that can fit into current container's clientHeight/clientWidth.\n\n // LIMITATIONS:\n // - current version only supports an Array as a right-hand-side object for ngRepeat\n // - all rendered elements must have the same height/width or the sizes of the elements must be known up front\n\n // USAGE:\n // In order to use the vsRepeat directive you need to place a vs-repeat attribute on a direct parent of an element with ng-repeat\n // example:\n // <div vs-repeat>\n // <div ng-repeat=\"item in someArray\">\n // <!-- content -->\n // </div>\n // </div>\n //\n // or:\n // <div vs-repeat>\n // <div ng-repeat-start=\"item in someArray\">\n // <!-- content -->\n // </div>\n // <div>\n // <!-- something in the middle -->\n // </div>\n // <div ng-repeat-end>\n // <!-- content -->\n // </div>\n // </div>\n //\n // You can also measure the single element's height/width (including all paddings and margins), and then speficy it as a value\n // of the attribute 'vs-repeat'. This can be used if one wants to override the automatically computed element size.\n // example:\n // <div vs-repeat=\"50\"> <!-- the specified element height is 50px -->\n // <div ng-repeat=\"item in someArray\">\n // <!-- content -->\n // </div>\n // </div>\n //\n // IMPORTANT!\n //\n // - the vsRepeat directive must be applied to a direct parent of an element with ngRepeat\n // - the value of vsRepeat attribute is the single element's height/width measured in pixels. If none provided, the directive\n // will compute it automatically\n\n // OPTIONAL PARAMETERS (attributes):\n // vs-repeat-container=\"selector\" - selector for element containing ng-repeat. (defaults to the current element)\n // vs-scroll-parent=\"selector\" - selector to the scrollable container. The directive will look for a closest parent matching\n // the given selector (defaults to the current element)\n // vs-horizontal - stack repeated elements horizontally instead of vertically\n // vs-offset-before=\"value\" - top/left offset in pixels (defaults to 0)\n // vs-offset-after=\"value\" - bottom/right offset in pixels (defaults to 0)\n // vs-excess=\"value\" - an integer number representing the number of elements to be rendered outside of the current container's viewport\n // (defaults to 2)\n // vs-size - a property name of the items in collection that is a number denoting the element size (in pixels)\n // vs-autoresize - use this attribute without vs-size and without specifying element's size. The automatically computed element style will\n // readjust upon window resize if the size is dependable on the viewport size\n // vs-scrolled-to-end=\"callback\" - callback will be called when the last item of the list is rendered\n // vs-scrolled-to-end-offset=\"integer\" - set this number to trigger the scrolledToEnd callback n items before the last gets rendered\n // vs-scrolled-to-beginning=\"callback\" - callback will be called when the first item of the list is rendered\n // vs-scrolled-to-beginning-offset=\"integer\" - set this number to trigger the scrolledToBeginning callback n items before the first gets rendered\n\n // EVENTS:\n // - 'vsRepeatTrigger' - an event the directive listens for to manually trigger reinitialization\n // - 'vsRepeatReinitialized' - an event the directive emits upon reinitialization done\n\n var dde = document.documentElement,\n matchingFunction = dde.matches ? 'matches' :\n dde.matchesSelector ? 'matchesSelector' :\n dde.webkitMatches ? 'webkitMatches' :\n dde.webkitMatchesSelector ? 'webkitMatchesSelector' :\n dde.msMatches ? 'msMatches' :\n dde.msMatchesSelector ? 'msMatchesSelector' :\n dde.mozMatches ? 'mozMatches' :\n dde.mozMatchesSelector ? 'mozMatchesSelector' : null;\n\n var closestElement = angular.element.prototype.closest || function (selector) {\n var el = this[0].parentNode;\n while (el !== document.documentElement && el != null && !el[matchingFunction](selector)) {\n el = el.parentNode;\n }\n\n if (el && el[matchingFunction](selector)) {\n return angular.element(el);\n }\n else {\n return angular.element();\n }\n };\n\n function getWindowScroll() {\n if ('pageYOffset' in window) {\n return {\n scrollTop: pageYOffset,\n scrollLeft: pageXOffset\n };\n }\n else {\n var sx, sy, d = document, r = d.documentElement, b = d.body;\n sx = r.scrollLeft || b.scrollLeft || 0;\n sy = r.scrollTop || b.scrollTop || 0;\n return {\n scrollTop: sy,\n scrollLeft: sx\n };\n }\n }\n\n function getClientSize(element, sizeProp) {\n if (element === window) {\n return sizeProp === 'clientWidth' ? window.innerWidth : window.innerHeight;\n }\n else {\n return element[sizeProp];\n }\n }\n\n function getScrollPos(element, scrollProp) {\n return element === window ? getWindowScroll()[scrollProp] : element[scrollProp];\n }\n\n function getScrollOffset(vsElement, scrollElement, isHorizontal) {\n var vsPos = vsElement.getBoundingClientRect()[isHorizontal ? 'left' : 'top'];\n var scrollPos = scrollElement === window ? 0 : scrollElement.getBoundingClientRect()[isHorizontal ? 'left' : 'top'];\n var correction = vsPos - scrollPos +\n (scrollElement === window ? getWindowScroll() : scrollElement)[isHorizontal ? 'scrollLeft' : 'scrollTop'];\n\n return correction;\n }\n\n var vsRepeatModule = angular.module('vs-repeat', []).directive('vsRepeat', ['$compile', '$parse', function($compile, $parse) {\n return {\n restrict: 'A',\n scope: true,\n compile: function($element, $attrs) {\n var repeatContainer = angular.isDefined($attrs.vsRepeatContainer) ? angular.element($element[0].querySelector($attrs.vsRepeatContainer)) : $element,\n ngRepeatChild = repeatContainer.children().eq(0),\n ngRepeatExpression,\n childCloneHtml = ngRepeatChild[0].outerHTML,\n expressionMatches,\n lhs,\n rhs,\n rhsSuffix,\n originalNgRepeatAttr,\n collectionName = '$vs_collection',\n isNgRepeatStart = false,\n attributesDictionary = {\n 'vsRepeat': 'elementSize',\n 'vsOffsetBefore': 'offsetBefore',\n 'vsOffsetAfter': 'offsetAfter',\n 'vsScrolledToEndOffset': 'scrolledToEndOffset',\n 'vsScrolledToBeginningOffset': 'scrolledToBeginningOffset',\n 'vsExcess': 'excess'\n };\n\n if (ngRepeatChild.attr('ng-repeat')) {\n originalNgRepeatAttr = 'ng-repeat';\n ngRepeatExpression = ngRepeatChild.attr('ng-repeat');\n }\n else if (ngRepeatChild.attr('data-ng-repeat')) {\n originalNgRepeatAttr = 'data-ng-repeat';\n ngRepeatExpression = ngRepeatChild.attr('data-ng-repeat');\n }\n else if (ngRepeatChild.attr('ng-repeat-start')) {\n isNgRepeatStart = true;\n originalNgRepeatAttr = 'ng-repeat-start';\n ngRepeatExpression = ngRepeatChild.attr('ng-repeat-start');\n }\n else if (ngRepeatChild.attr('data-ng-repeat-start')) {\n isNgRepeatStart = true;\n originalNgRepeatAttr = 'data-ng-repeat-start';\n ngRepeatExpression = ngRepeatChild.attr('data-ng-repeat-start');\n }\n else {\n throw new Error('angular-vs-repeat: no ng-repeat directive on a child element');\n }\n\n expressionMatches = /^\\s*(\\S+)\\s+in\\s+([\\S\\s]+?)(track\\s+by\\s+\\S+)?$/.exec(ngRepeatExpression);\n lhs = expressionMatches[1];\n rhs = expressionMatches[2];\n rhsSuffix = expressionMatches[3];\n\n if (isNgRepeatStart) {\n var index = 0;\n var repeaterElement = repeatContainer.children().eq(0);\n while(repeaterElement.attr('ng-repeat-end') == null && repeaterElement.attr('data-ng-repeat-end') == null) {\n index++;\n repeaterElement = repeatContainer.children().eq(index);\n childCloneHtml += repeaterElement[0].outerHTML;\n }\n }\n\n repeatContainer.empty();\n return {\n pre: function($scope, $element, $attrs) {\n var repeatContainer = angular.isDefined($attrs.vsRepeatContainer) ? angular.element($element[0].querySelector($attrs.vsRepeatContainer)) : $element,\n childClone = angular.element(childCloneHtml),\n childTagName = childClone[0].tagName.toLowerCase(),\n originalCollection = [],\n originalLength,\n $$horizontal = typeof $attrs.vsHorizontal !== 'undefined',\n $beforeContent = angular.element('<' + childTagName + ' class=\"vs-repeat-before-content\"></' + childTagName + '>'),\n $afterContent = angular.element('<' + childTagName + ' class=\"vs-repeat-after-content\"></' + childTagName + '>'),\n autoSize = !$attrs.vsRepeat,\n sizesPropertyExists = !!$attrs.vsSize || !!$attrs.vsSizeProperty,\n $scrollParent = $attrs.vsScrollParent ?\n $attrs.vsScrollParent === 'window' ? angular.element(window) :\n closestElement.call(repeatContainer, $attrs.vsScrollParent) : repeatContainer,\n $$options = 'vsOptions' in $attrs ? $scope.$eval($attrs.vsOptions) : {},\n clientSize = $$horizontal ? 'clientWidth' : 'clientHeight',\n offsetSize = $$horizontal ? 'offsetWidth' : 'offsetHeight',\n scrollPos = $$horizontal ? 'scrollLeft' : 'scrollTop';\n\n $scope.totalSize = 0;\n if (!('vsSize' in $attrs) && 'vsSizeProperty' in $attrs) {\n console.warn('vs-size-property attribute is deprecated. Please use vs-size attribute which also accepts angular expressions.');\n }\n\n if ($scrollParent.length === 0) {\n throw 'Specified scroll parent selector did not match any element';\n }\n $scope.$scrollParent = $scrollParent;\n\n if (sizesPropertyExists) {\n $scope.sizesCumulative = [];\n }\n\n //initial defaults\n $scope.elementSize = (+$attrs.vsRepeat) || getClientSize($scrollParent[0], clientSize) || 50;\n $scope.offsetBefore = 0;\n $scope.offsetAfter = 0;\n $scope.excess = 2;\n\n if ($$horizontal) {\n $beforeContent.css('height', '100%');\n $afterContent.css('height', '100%');\n }\n else {\n $beforeContent.css('width', '100%');\n $afterContent.css('width', '100%');\n }\n\n Object.keys(attributesDictionary).forEach(function(key) {\n if ($attrs[key]) {\n $attrs.$observe(key, function(value) {\n // '+' serves for getting a number from the string as the attributes are always strings\n $scope[attributesDictionary[key]] = +value;\n reinitialize();\n });\n }\n });\n\n\n $scope.$watchCollection(rhs, function(coll) {\n originalCollection = coll || [];\n refresh();\n });\n\n function refresh() {\n if (!originalCollection || originalCollection.length < 1) {\n $scope[collectionName] = [];\n originalLength = 0;\n $scope.sizesCumulative = [0];\n }\n else {\n originalLength = originalCollection.length;\n if (sizesPropertyExists) {\n $scope.sizes = originalCollection.map(function(item) {\n var s = $scope.$new(false);\n angular.extend(s, item);\n s[lhs] = item;\n var size = ($attrs.vsSize || $attrs.vsSizeProperty) ?\n s.$eval($attrs.vsSize || $attrs.vsSizeProperty) :\n $scope.elementSize;\n s.$destroy();\n return size;\n });\n var sum = 0;\n $scope.sizesCumulative = $scope.sizes.map(function(size) {\n var res = sum;\n sum += size;\n return res;\n });\n $scope.sizesCumulative.push(sum);\n }\n else {\n setAutoSize();\n }\n }\n\n reinitialize();\n }\n\n function setAutoSize() {\n if (autoSize) {\n $scope.$$postDigest(function() {\n if (repeatContainer[0].offsetHeight || repeatContainer[0].offsetWidth) { // element is visible\n var children = repeatContainer.children(),\n i = 0,\n gotSomething = false,\n insideStartEndSequence = false;\n\n while (i < children.length) {\n if (children[i].attributes[originalNgRepeatAttr] != null || insideStartEndSequence) {\n if (!gotSomething) {\n $scope.elementSize = 0;\n }\n\n gotSomething = true;\n if (children[i][offsetSize]) {\n $scope.elementSize += children[i][offsetSize];\n }\n\n if (isNgRepeatStart) {\n if (children[i].attributes['ng-repeat-end'] != null || children[i].attributes['data-ng-repeat-end'] != null) {\n break;\n }\n else {\n insideStartEndSequence = true;\n }\n }\n else {\n break;\n }\n }\n i++;\n }\n\n if (gotSomething) {\n reinitialize();\n autoSize = false;\n if ($scope.$root && !$scope.$root.$$phase) {\n $scope.$apply();\n }\n }\n }\n else {\n var dereg = $scope.$watch(function() {\n if (repeatContainer[0].offsetHeight || repeatContainer[0].offsetWidth) {\n dereg();\n setAutoSize();\n }\n });\n }\n });\n }\n }\n\n function getLayoutProp() {\n var layoutPropPrefix = childTagName === 'tr' ? '' : 'min-';\n var layoutProp = $$horizontal ? layoutPropPrefix + 'width' : layoutPropPrefix + 'height';\n return layoutProp;\n }\n\n childClone.eq(0).attr(originalNgRepeatAttr, lhs + ' in ' + collectionName + (rhsSuffix ? ' ' + rhsSuffix : ''));\n childClone.addClass('vs-repeat-repeated-element');\n\n repeatContainer.append($beforeContent);\n repeatContainer.append(childClone);\n $compile(childClone)($scope);\n repeatContainer.append($afterContent);\n\n $scope.startIndex = 0;\n $scope.endIndex = 0;\n\n function scrollHandler() {\n if (updateInnerCollection()) {\n $scope.$digest();\n }\n }\n\n $scrollParent.on('scroll', scrollHandler);\n\n function onWindowResize() {\n if (typeof $attrs.vsAutoresize !== 'undefined') {\n autoSize = true;\n setAutoSize();\n if ($scope.$root && !$scope.$root.$$phase) {\n $scope.$apply();\n }\n }\n if (updateInnerCollection()) {\n $scope.$apply();\n }\n }\n\n angular.element(window).on('resize', onWindowResize);\n $scope.$on('$destroy', function() {\n angular.element(window).off('resize', onWindowResize);\n $scrollParent.off('scroll', scrollHandler);\n });\n\n $scope.$on('vsRepeatTrigger', refresh);\n\n $scope.$on('vsRepeatResize', function() {\n autoSize = true;\n setAutoSize();\n });\n\n var _prevStartIndex,\n _prevEndIndex,\n _minStartIndex,\n _maxEndIndex;\n\n $scope.$on('vsRenderAll', function() {//e , quantum) {\n if($$options.latch) {\n setTimeout(function() {\n // var __endIndex = Math.min($scope.endIndex + (quantum || 1), originalLength);\n var __endIndex = originalLength;\n _maxEndIndex = Math.max(__endIndex, _maxEndIndex);\n $scope.endIndex = $$options.latch ? _maxEndIndex : __endIndex;\n $scope[collectionName] = originalCollection.slice($scope.startIndex, $scope.endIndex);\n _prevEndIndex = $scope.endIndex;\n\n $scope.$$postDigest(function() {\n $beforeContent.css(getLayoutProp(), 0);\n $afterContent.css(getLayoutProp(), 0);\n });\n\n $scope.$apply(function() {\n $scope.$emit('vsRenderAllDone');\n });\n });\n }\n });\n\n function reinitialize() {\n _prevStartIndex = void 0;\n _prevEndIndex = void 0;\n _minStartIndex = originalLength;\n _maxEndIndex = 0;\n updateTotalSize(sizesPropertyExists ?\n $scope.sizesCumulative[originalLength] :\n $scope.elementSize * originalLength\n );\n updateInnerCollection();\n\n $scope.$emit('vsRepeatReinitialized', $scope.startIndex, $scope.endIndex);\n }\n\n function updateTotalSize(size) {\n $scope.totalSize = $scope.offsetBefore + size + $scope.offsetAfter;\n }\n\n var _prevClientSize;\n function reinitOnClientHeightChange() {\n var ch = getClientSize($scrollParent[0], clientSize);\n if (ch !== _prevClientSize) {\n reinitialize();\n if ($scope.$root && !$scope.$root.$$phase) {\n $scope.$apply();\n }\n }\n _prevClientSize = ch;\n }\n\n $scope.$watch(function() {\n if (typeof window.requestAnimationFrame === 'function') {\n window.requestAnimationFrame(reinitOnClientHeightChange);\n }\n else {\n reinitOnClientHeightChange();\n }\n });\n\n function updateInnerCollection() {\n var $scrollPosition = getScrollPos($scrollParent[0], scrollPos);\n var $clientSize = getClientSize($scrollParent[0], clientSize);\n\n var scrollOffset = repeatContainer[0] === $scrollParent[0] ? 0 : getScrollOffset(\n repeatContainer[0],\n $scrollParent[0],\n $$horizontal\n );\n\n var __startIndex = $scope.startIndex;\n var __endIndex = $scope.endIndex;\n\n if (sizesPropertyExists) {\n __startIndex = 0;\n while ($scope.sizesCumulative[__startIndex] < $scrollPosition - $scope.offsetBefore - scrollOffset) {\n __startIndex++;\n }\n if (__startIndex > 0) { __startIndex--; }\n\n // Adjust the start index according to the excess\n __startIndex = Math.max(\n Math.floor(__startIndex - $scope.excess / 2),\n 0\n );\n\n __endIndex = __startIndex;\n while ($scope.sizesCumulative[__endIndex] < $scrollPosition - $scope.offsetBefore - scrollOffset + $clientSize) {\n __endIndex++;\n }\n\n // Adjust the end index according to the excess\n __endIndex = Math.min(\n Math.ceil(__endIndex + $scope.excess / 2),\n originalLength\n );\n }\n else {\n __startIndex = Math.max(\n Math.floor(\n ($scrollPosition - $scope.offsetBefore - scrollOffset) / $scope.elementSize\n ) - $scope.excess / 2,\n 0\n );\n\n __endIndex = Math.min(\n __startIndex + Math.ceil(\n $clientSize / $scope.elementSize\n ) + $scope.excess,\n originalLength\n );\n }\n\n _minStartIndex = Math.min(__startIndex, _minStartIndex);\n _maxEndIndex = Math.max(__endIndex, _maxEndIndex);\n\n $scope.startIndex = $$options.latch ? _minStartIndex : __startIndex;\n $scope.endIndex = $$options.latch ? _maxEndIndex : __endIndex;\n\n var digestRequired = false;\n if (_prevStartIndex == null) {\n digestRequired = true;\n }\n else if (_prevEndIndex == null) {\n digestRequired = true;\n }\n\n if (!digestRequired) {\n if ($$options.hunked) {\n if (Math.abs($scope.startIndex - _prevStartIndex) >= $scope.excess / 2 ||\n ($scope.startIndex === 0 && _prevStartIndex !== 0)) {\n digestRequired = true;\n }\n else if (Math.abs($scope.endIndex - _prevEndIndex) >= $scope.excess / 2 ||\n ($scope.endIndex === originalLength && _prevEndIndex !== originalLength)) {\n digestRequired = true;\n }\n }\n else {\n digestRequired = $scope.startIndex !== _prevStartIndex ||\n $scope.endIndex !== _prevEndIndex;\n }\n }\n\n if (digestRequired) {\n $scope[collectionName] = originalCollection.slice($scope.startIndex, $scope.endIndex);\n\n // Emit the event\n $scope.$emit('vsRepeatInnerCollectionUpdated', $scope.startIndex, $scope.endIndex, _prevStartIndex, _prevEndIndex);\n var triggerIndex;\n if ($attrs.vsScrolledToEnd) {\n triggerIndex = originalCollection.length - ($scope.scrolledToEndOffset || 0);\n if (($scope.endIndex >= triggerIndex && _prevEndIndex < triggerIndex) || (originalCollection.length && $scope.endIndex === originalCollection.length)) {\n $scope.$eval($attrs.vsScrolledToEnd);\n }\n }\n if ($attrs.vsScrolledToBeginning) {\n triggerIndex = $scope.scrolledToBeginningOffset || 0;\n if (($scope.startIndex <= triggerIndex && _prevStartIndex > $scope.startIndex)) {\n $scope.$eval($attrs.vsScrolledToBeginning);\n }\n }\n\n _prevStartIndex = $scope.startIndex;\n _prevEndIndex = $scope.endIndex;\n\n var offsetCalculationString = sizesPropertyExists ?\n '(sizesCumulative[$index + startIndex] + offsetBefore)' :\n '(($index + startIndex) * elementSize + offsetBefore)';\n\n var parsed = $parse(offsetCalculationString);\n var o1 = parsed($scope, {$index: 0});\n var o2 = parsed($scope, {$index: $scope[collectionName].length});\n var total = $scope.totalSize;\n\n $beforeContent.css(getLayoutProp(), o1 + 'px');\n $afterContent.css(getLayoutProp(), (total - o2) + 'px');\n }\n\n return digestRequired;\n }\n }\n };\n }\n };\n }]);\n\n if (typeof module !== 'undefined' && module.exports) {\n module.exports = vsRepeatModule.name;\n }\n})(window, window.angular);\n"],"sourceRoot":""} | ||
1284 | 3 | \ No newline at end of file | 3 | \ No newline at end of file |
1285 | diff --git a/src/maasserver/static/partials/dashboard.html b/src/maasserver/static/partials/dashboard.html | |||
1286 | index 35e670d..b009216 100644 | |||
1287 | --- a/src/maasserver/static/partials/dashboard.html | |||
1288 | +++ b/src/maasserver/static/partials/dashboard.html | |||
1289 | @@ -57,7 +57,7 @@ | |||
1290 | 57 | </td> | 57 | </td> |
1291 | 58 | </tr> | 58 | </tr> |
1292 | 59 | </tbody> | 59 | </tbody> |
1294 | 60 | <tbody vs-repeat="{scrollParent: 'window'}"> | 60 | <tbody vs-repeat vs-scroll-parent="window"> |
1295 | 61 | <tr data-ng-repeat="discovery in discoveredDevices | orderBy:predicate:reverse track by discovery.first_seen" | 61 | <tr data-ng-repeat="discovery in discoveredDevices | orderBy:predicate:reverse track by discovery.first_seen" |
1296 | 62 | data-ng-class="{'is-active' : discovery.first_seen === selectedDevice}"> | 62 | data-ng-class="{'is-active' : discovery.first_seen === selectedDevice}"> |
1297 | 63 | <td class="p-table--network-discovery__name" aria-label="Name" data-ng-if="discovery.first_seen !== selectedDevice"> | 63 | <td class="p-table--network-discovery__name" aria-label="Name" data-ng-if="discovery.first_seen !== selectedDevice"> |
1298 | diff --git a/src/maasserver/static/partials/machines-table.html b/src/maasserver/static/partials/machines-table.html | |||
1299 | index 727d392..1c49dbe 100644 | |||
1300 | --- a/src/maasserver/static/partials/machines-table.html | |||
1301 | +++ b/src/maasserver/static/partials/machines-table.html | |||
1302 | @@ -22,7 +22,7 @@ | |||
1303 | 22 | <th class="u-hide--small u-align--right" role="columnheader" data-ng-click="sortTable('storage')" data-ng-class="{'is-sorted': table.predicate === 'storage', 'sort-asc': table.reverse === false, 'sort-desc': table.reverse === true}" title="Storage (GB)">Storage (GB)</th> | 22 | <th class="u-hide--small u-align--right" role="columnheader" data-ng-click="sortTable('storage')" data-ng-class="{'is-sorted': table.predicate === 'storage', 'sort-asc': table.reverse === false, 'sort-desc': table.reverse === true}" title="Storage (GB)">Storage (GB)</th> |
1304 | 23 | </tr> | 23 | </tr> |
1305 | 24 | </thead> | 24 | </thead> |
1307 | 25 | <tbody vs-repeat="{scrollParent: 'window'}"> | 25 | <tbody vs-repeat vs-scroll-parent="window"> |
1308 | 26 | <tr class="p-table__row" data-ng-repeat="node in table.filteredMachines = (table.machines | nodesFilter:search | orderBy:table.predicate:table.reverse) track by node.system_id" data-ng-class="{ 'table--error': machineHasError({ $machine: node }), 'is-active': node.$selected }"> | 26 | <tr class="p-table__row" data-ng-repeat="node in table.filteredMachines = (table.machines | nodesFilter:search | orderBy:table.predicate:table.reverse) track by node.system_id" data-ng-class="{ 'table--error': machineHasError({ $machine: node }), 'is-active': node.$selected }"> |
1309 | 27 | <td class="u-align--left" aria-label="FQDN" data-ng-if="table.column === 'fqdn'"> | 27 | <td class="u-align--left" aria-label="FQDN" data-ng-if="table.column === 'fqdn'"> |
1310 | 28 | <div class="u-float--left" data-ng-if="!hideCheckboxes"> | 28 | <div class="u-float--left" data-ng-if="!hideCheckboxes"> |
1311 | diff --git a/src/maasserver/static/partials/networks-list.html b/src/maasserver/static/partials/networks-list.html | |||
1312 | index 4517c73..9bdd75e 100644 | |||
1313 | --- a/src/maasserver/static/partials/networks-list.html | |||
1314 | +++ b/src/maasserver/static/partials/networks-list.html | |||
1315 | @@ -171,7 +171,7 @@ | |||
1316 | 171 | <th><div class="u-align--right">Available IPs</div></th> | 171 | <th><div class="u-align--right">Available IPs</div></th> |
1317 | 172 | </tr> | 172 | </tr> |
1318 | 173 | </thead> | 173 | </thead> |
1320 | 174 | <tbody vs-repeat="{scrollParent: 'window'}"> | 174 | <tbody vs-repeat vs-scroll-parent="window"> |
1321 | 175 | <tr data-ng-repeat="row in group.spaces.rows"> | 175 | <tr data-ng-repeat="row in group.spaces.rows"> |
1322 | 176 | <!-- <td class="ng-hide"> | 176 | <!-- <td class="ng-hide"> |
1323 | 177 | <div data-ng-if="row.space_name"> | 177 | <div data-ng-if="row.space_name"> |
1324 | @@ -241,7 +241,7 @@ | |||
1325 | 241 | <th>Space</th> | 241 | <th>Space</th> |
1326 | 242 | </tr> | 242 | </tr> |
1327 | 243 | </thead> | 243 | </thead> |
1329 | 244 | <tbody vs-repeat="{scrollParent: 'window'}"> | 244 | <tbody vs-repeat vs-scroll-parent="window"> |
1330 | 245 | <tr data-ng-repeat="row in group.fabrics.rows"> | 245 | <tr data-ng-repeat="row in group.fabrics.rows"> |
1331 | 246 | <!-- <td class="ng-hide"> | 246 | <!-- <td class="ng-hide"> |
1332 | 247 | <div data-ng-if="row.fabric_name"> | 247 | <div data-ng-if="row.fabric_name"> |
1333 | diff --git a/src/maasserver/static/partials/node-events.html b/src/maasserver/static/partials/node-events.html | |||
1334 | index 75d6772..10c8d3a 100644 | |||
1335 | --- a/src/maasserver/static/partials/node-events.html | |||
1336 | +++ b/src/maasserver/static/partials/node-events.html | |||
1337 | @@ -46,7 +46,7 @@ | |||
1338 | 46 | <th class="col-9">Event</th> | 46 | <th class="col-9">Event</th> |
1339 | 47 | </tr> | 47 | </tr> |
1340 | 48 | </thead> | 48 | </thead> |
1342 | 49 | <tbody vs-repeat="{scrollParent: 'window'}"> | 49 | <tbody vs-repeat vs-scroll-parent="window"> |
1343 | 50 | <tr data-ng-repeat="event in events | filter:search | orderByDate:'created':'id' track by event.id"> | 50 | <tr data-ng-repeat="event in events | filter:search | orderByDate:'created':'id' track by event.id"> |
1344 | 51 | <td class="col-3" title="{$ event.created $}"> | 51 | <td class="col-3" title="{$ event.created $}"> |
1345 | 52 | <span class="p-icon--{$ event.type.level $}"></span> | 52 | <span class="p-icon--{$ event.type.level $}"></span> |
1346 | diff --git a/src/maasserver/static/partials/nodes-list.html b/src/maasserver/static/partials/nodes-list.html | |||
1347 | index 6662a02..354c12f 100644 | |||
1348 | --- a/src/maasserver/static/partials/nodes-list.html | |||
1349 | +++ b/src/maasserver/static/partials/nodes-list.html | |||
1350 | @@ -438,7 +438,7 @@ | |||
1351 | 438 | <th class="p-table__cell">Actions</th> | 438 | <th class="p-table__cell">Actions</th> |
1352 | 439 | </tr> | 439 | </tr> |
1353 | 440 | </thead> | 440 | </thead> |
1355 | 441 | <tbody vs-repeat="{scrollParent: 'window'}"> | 441 | <tbody vs-repeat vs-scroll-parent="window"> |
1356 | 442 | <tr class="p-table__row" data-ng-repeat="interface in device.interfaces"> | 442 | <tr class="p-table__row" data-ng-repeat="interface in device.interfaces"> |
1357 | 443 | <td class="p-table__cell" aria-label="MAC address"> | 443 | <td class="p-table__cell" aria-label="MAC address"> |
1358 | 444 | <div class="p-form-validation u-no-margin--top" data-ng-class="{ 'is-error': macHasError(interface) }"> | 444 | <div class="p-form-validation u-no-margin--top" data-ng-class="{ 'is-error': macHasError(interface) }"> |
1359 | @@ -868,7 +868,7 @@ sudo maas-rack register --url {$ tabs.controllers.registerUrl $} --secret {$ tab | |||
1360 | 868 | </th> | 868 | </th> |
1361 | 869 | </tr> | 869 | </tr> |
1362 | 870 | </thead> | 870 | </thead> |
1364 | 871 | <tbody vs-repeat="{scrollParent: 'window'}"> | 871 | <tbody vs-repeat vs-scroll-parent="window"> |
1365 | 872 | <!-- XXX rvba 2015-02-25 - Need to add e2e test. This really needs lots of tests. --> | 872 | <!-- XXX rvba 2015-02-25 - Need to add e2e test. This really needs lots of tests. --> |
1366 | 873 | <tr class="p-table__row" | 873 | <tr class="p-table__row" |
1367 | 874 | data-ng-repeat="device in tabs.devices.filtered_items = (devices | nodesFilter:tabs.devices.search | orderBy:tabs.devices.predicate:tabs.devices.reverse) track by device.system_id" | 874 | data-ng-repeat="device in tabs.devices.filtered_items = (devices | nodesFilter:tabs.devices.search | orderBy:tabs.devices.predicate:tabs.devices.reverse) track by device.system_id" |
1368 | @@ -1027,7 +1027,7 @@ sudo maas-rack register --url {$ tabs.controllers.registerUrl $} --secret {$ tab | |||
1369 | 1027 | <th class="p-table__cell" role="columnheader" data-ng-click="sortTable('updated', 'controllers')" data-ng-class="{'is-sorted': tabs.controllers.predicate === 'updated', 'sort-asc': tabs.controllers.reverse === false, 'sort-desc': tabs.controllers.reverse === true}">Images Status</th> | 1027 | <th class="p-table__cell" role="columnheader" data-ng-click="sortTable('updated', 'controllers')" data-ng-class="{'is-sorted': tabs.controllers.predicate === 'updated', 'sort-asc': tabs.controllers.reverse === false, 'sort-desc': tabs.controllers.reverse === true}">Images Status</th> |
1370 | 1028 | </tr> | 1028 | </tr> |
1371 | 1029 | </thead> | 1029 | </thead> |
1373 | 1030 | <tbody vs-repeat="{scrollParent: 'window'}"> | 1030 | <tbody vs-repeat vs-scroll-parent="window"> |
1374 | 1031 | <!-- XXX rvba 2015-02-25 - Need to add e2e test. This really needs lots of tests. --> | 1031 | <!-- XXX rvba 2015-02-25 - Need to add e2e test. This really needs lots of tests. --> |
1375 | 1032 | <tr class="p-table__row" | 1032 | <tr class="p-table__row" |
1376 | 1033 | data-ng-repeat="controller in tabs.controllers.filtered_items = (controllers | nodesFilter:tabs.controllers.search | orderBy:tabs.controllers.predicate:tabs.controllers.reverse) track by controller.system_id" | 1033 | data-ng-repeat="controller in tabs.controllers.filtered_items = (controllers | nodesFilter:tabs.controllers.search | orderBy:tabs.controllers.predicate:tabs.controllers.reverse) track by controller.system_id" |
1377 | diff --git a/src/maasserver/static/partials/pods-list.html b/src/maasserver/static/partials/pods-list.html | |||
1378 | index a7ff1f6..a692f91 100644 | |||
1379 | --- a/src/maasserver/static/partials/pods-list.html | |||
1380 | +++ b/src/maasserver/static/partials/pods-list.html | |||
1381 | @@ -133,7 +133,7 @@ | |||
1382 | 133 | <th class="p-table__cell u-align--right" role="columnheader" data-ng-click="sortTable('composed_machines')" data-ng-class="{'is-sorted': predicate === 'composed_machines', 'sort-asc': reverse === false, 'sort-desc': reverse === true}" title="Composed machines">Composed machines</th> | 133 | <th class="p-table__cell u-align--right" role="columnheader" data-ng-click="sortTable('composed_machines')" data-ng-class="{'is-sorted': predicate === 'composed_machines', 'sort-asc': reverse === false, 'sort-desc': reverse === true}" title="Composed machines">Composed machines</th> |
1383 | 134 | </tr> | 134 | </tr> |
1384 | 135 | </thead> | 135 | </thead> |
1386 | 136 | <tbody vs-repeat="{scrollParent: 'window'}"> | 136 | <tbody vs-repeat vs-scroll-parent="window"> |
1387 | 137 | <tr class="p-table__row" data-ng-repeat="pod in filteredItems = (pods | nodesFilter:search | orderBy:predicate:reverse) track by pod.id" data-ng-class="{ selected: pod.$selected, 'is-active': pod.$selected && pod.action_failed }"> | 137 | <tr class="p-table__row" data-ng-repeat="pod in filteredItems = (pods | nodesFilter:search | orderBy:predicate:reverse) track by pod.id" data-ng-class="{ selected: pod.$selected, 'is-active': pod.$selected && pod.action_failed }"> |
1388 | 138 | <td class="p-table__cell" aria-label="Name" title="{$ pod.name $}"> | 138 | <td class="p-table__cell" aria-label="Name" title="{$ pod.name $}"> |
1389 | 139 | <div class="u-float--left" data-ng-if="isSuperUser()"> | 139 | <div class="u-float--left" data-ng-if="isSuperUser()"> |
1390 | diff --git a/src/maasserver/static/partials/switches-table.html b/src/maasserver/static/partials/switches-table.html | |||
1391 | index 371cbba..106a251 100644 | |||
1392 | --- a/src/maasserver/static/partials/switches-table.html | |||
1393 | +++ b/src/maasserver/static/partials/switches-table.html | |||
1394 | @@ -22,7 +22,7 @@ | |||
1395 | 22 | <th class="u-align--right" role="columnheader" data-ng-click="sortTable('serial')" data-ng-class="{'is-sorted': table.predicate === 'serial', 'sort-asc': table.reverse === false, 'sort-desc': table.reverse === true}">Serial</th> | 22 | <th class="u-align--right" role="columnheader" data-ng-click="sortTable('serial')" data-ng-class="{'is-sorted': table.predicate === 'serial', 'sort-asc': table.reverse === false, 'sort-desc': table.reverse === true}">Serial</th> |
1396 | 23 | </tr> | 23 | </tr> |
1397 | 24 | </thead> | 24 | </thead> |
1399 | 25 | <tbody vs-repeat="{scrollParent: 'window'}"> | 25 | <tbody vs-repeat vs-scroll-parent="window"> |
1400 | 26 | <tr | 26 | <tr |
1401 | 27 | data-ng-repeat="node in table.filteredSwitches = (table.switches | nodesFilter:search | orderBy:table.predicate:table.reverse) track by node.system_id" | 27 | data-ng-repeat="node in table.filteredSwitches = (table.switches | nodesFilter:search | orderBy:table.predicate:table.reverse) track by node.system_id" |
1402 | 28 | data-ng-class="{ 'table--error': machineHasError({ $switch_: node }), selected: node.$selected }"> | 28 | data-ng-class="{ 'table--error': machineHasError({ $switch_: node }), selected: node.$selected }"> |
1403 | diff --git a/src/maasserver/static/partials/zones-list.html b/src/maasserver/static/partials/zones-list.html | |||
1404 | index 921db3d..c35cc5e 100755 | |||
1405 | --- a/src/maasserver/static/partials/zones-list.html | |||
1406 | +++ b/src/maasserver/static/partials/zones-list.html | |||
1407 | @@ -54,7 +54,7 @@ | |||
1408 | 54 | <th class="u-align--right">Controllers</th> | 54 | <th class="u-align--right">Controllers</th> |
1409 | 55 | </tr> | 55 | </tr> |
1410 | 56 | </thead> | 56 | </thead> |
1412 | 57 | <tbody vs-repeat="{scrollParent: 'window'}"> | 57 | <tbody vs-repeat vs-scroll-parent="window"> |
1413 | 58 | <tr data-ng-repeat="zone in zones"> | 58 | <tr data-ng-repeat="zone in zones"> |
1414 | 59 | <td aria-label="Name" title="{$ zone.name $}"> | 59 | <td aria-label="Name" title="{$ zone.name $}"> |
1415 | 60 | <a href="#/zone/{$ zone.id $}">{$ zone.name $}</a> | 60 | <a href="#/zone/{$ zone.id $}">{$ zone.name $}</a> |
lgtm!