PageSourceSearch

https://www.webnames.ca/jsbundles/home?v=L70yOjgCQrPDnLOQu0k1Yh1Oggh1c0KqbPlp-V8w4aY1

js webnames.ca collected 2026-10-02 02:54:14 UTC 54,335 bytes, 1,440 lines download raw bytes

1/// NG-DELAY by Brent Vane and others
2/// Used as an attribute to help add a delay from user input on ng-change events
3///  https://github.com/brentvatne/angular-delay/blob/master/src/angular-delay.js
4///  Sample ==>  <input ng-model="search" ng-change="updateResults()" ng-delay="1500" />
5(function (window, angular, undefined) {
6    'use strict';
7    angular.module('ngDelay', [])
8    .directive('ngDelay', ['$timeout', function ($timeout) {
9        return {
10            restrict: 'A',
11            scope: true,
12            compile: function (element, attributes) {
13                var expression = attributes['ngChange'];
14                if (!expression)
15                    return;
16                var ngModel = attributes['ngModel'];
17                if (ngModel) attributes['ngModel'] = '$parent.' + ngModel;
18                attributes['ngChange'] = '$$delay.execute()';
19                return {
20                    post: function (scope, element, attributes) {
21                        scope.$$delay = {
22                            expression: expression,
23                            delay: scope.$eval(attributes['ngDelay']),
24                            execute: function () {
25                                var state = scope.$$delay;
26                                state.then = Date.now();
27                                $timeout(function () {
28                                    if (Date.now() - state.then >= state.delay)
29                                        scope.$parent.$eval(expression);
30                                }, state.delay);
31                            }
32                        };
33                    }
34                }
35            }
36        };
37    }]);
38})(window, window.angular);
39/**
40 * @license AngularJS v1.8.2
vendor: 25,829 bytes, lines 40-730
40
41 * (c) 2010-2020 Google LLC. http://angularjs.org
42 * License: MIT
43 */
44(function(window, angular) {'use strict';
45
46/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
47 *     Any commits to this file should be reviewed with security in mind.  *
48 *   Changes to this file can potentially create security vulnerabilities. *
49 *          An approval from 2 Core members with history of modifying      *
50 *                         this file is required.                          *
51 *                                                                         *
52 *  Does the change somehow allow for arbitrary javascript to be executed? *
53 *    Or allows for someone to change the prototype of built-in objects?   *
54 *     Or gives undesired access to variables likes document or window?    *
55 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
56
57var $sanitizeMinErr = angular.$$minErr('$sanitize');
58var bind;
59var extend;
60var forEach;
61var isArray;
62var isDefined;
63var lowercase;
64var noop;
65var nodeContains;
66var htmlParser;
67var htmlSanitizeWriter;
68
69/**
70 * @ngdoc module
71 * @name ngSanitize
72 * @description
73 *
74 * The `ngSanitize` module provides functionality to sanitize HTML.
75 *
76 * See {@link ngSanitize.$sanitize `$sanitize`} for usage.
77 */
78
79/**
80 * @ngdoc service
81 * @name $sanitize
82 * @kind function
83 *
84 * @description
85 *   Sanitizes an html string by stripping all potentially dangerous tokens.
86 *
87 *   The input is sanitized by parsing the HTML into tokens. All safe tokens (from a trusted URI list) are
88 *   then serialized back to a properly escaped HTML string. This means that no unsafe input can make
89 *   it into the returned string.
90 *
91 *   The trusted URIs for URL sanitization of attribute values is configured using the functions
92 *   `aHrefSanitizationTrustedUrlList` and `imgSrcSanitizationTrustedUrlList` of {@link $compileProvider}.
93 *
94 *   The input may also contain SVG markup if this is enabled via {@link $sanitizeProvider}.
95 *
96 * @param {string} html HTML input.
97 * @returns {string} Sanitized HTML.
98 *
99 * @example
100   <example module="sanitizeExample" deps="angular-sanitize.js" name="sanitize-service">
101   <file name="index.html">
102     <script>
103         angular.module('sanitizeExample', ['ngSanitize'])
104           .controller('ExampleController', ['$scope', '$sce', function($scope, $sce) {
105             $scope.snippet =
106               '<p style="color:blue">an html\n' +
107               '<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' +
108               'snippet</p>';
109             $scope.deliberatelyTrustDangerousSnippet = function() {
110               return $sce.trustAsHtml($scope.snippet);
111             };
112           }]);
113     </script>
114     <div ng-controller="ExampleController">
115        Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
116       <table>
117         <tr>
118           <td>Directive</td>
119           <td>How</td>
120           <td>Source</td>
121           <td>Rendered</td>
122         </tr>
123         <tr id="bind-html-with-sanitize">
124           <td>ng-bind-html</td>
125           <td>Automatically uses $sanitize</td>
126           <td><pre>&lt;div ng-bind-html="snippet"&gt;<br/>&lt;/div&gt;</pre></td>
127           <td><div ng-bind-html="snippet"></div></td>
128         </tr>
129         <tr id="bind-html-with-trust">
130           <td>ng-bind-html</td>
131           <td>Bypass $sanitize by explicitly trusting the dangerous value</td>
132           <td>
133           <pre>&lt;div ng-bind-html="deliberatelyTrustDangerousSnippet()"&gt;
134&lt;/div&gt;</pre>
135           </td>
136           <td><div ng-bind-html="deliberatelyTrustDangerousSnippet()"></div></td>
137         </tr>
138         <tr id="bind-default">
139           <td>ng-bind</td>
140           <td>Automatically escapes</td>
141           <td><pre>&lt;div ng-bind="snippet"&gt;<br/>&lt;/div&gt;</pre></td>
142           <td><div ng-bind="snippet"></div></td>
143         </tr>
144       </table>
145       </div>
146   </file>
147   <file name="protractor.js" type="protractor">
148     it('should sanitize the html snippet by default', function() {
149       expect(element(by.css('#bind-html-with-sanitize div')).getAttribute('innerHTML')).
150         toBe('<p>an html\n<em>click here</em>\nsnippet</p>');
151     });
152
153     it('should inline raw snippet if bound to a trusted value', function() {
154       expect(element(by.css('#bind-html-with-trust div')).getAttribute('innerHTML')).
155         toBe("<p style=\"color:blue\">an html\n" +
156              "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
157              "snippet</p>");
158     });
159
160     it('should escape snippet without any filter', function() {
161       expect(element(by.css('#bind-default div')).getAttribute('innerHTML')).
162         toBe("&lt;p style=\"color:blue\"&gt;an html\n" +
163              "&lt;em onmouseover=\"this.textContent='PWN3D!'\"&gt;click here&lt;/em&gt;\n" +
164              "snippet&lt;/p&gt;");
165     });
166
167     it('should update', function() {
168       element(by.model('snippet')).clear();
169       element(by.model('snippet')).sendKeys('new <b onclick="alert(1)">text</b>');
170       expect(element(by.css('#bind-html-with-sanitize div')).getAttribute('innerHTML')).
171         toBe('new <b>text</b>');
172       expect(element(by.css('#bind-html-with-trust div')).getAttribute('innerHTML')).toBe(
173         'new <b onclick="alert(1)">text</b>');
174       expect(element(by.css('#bind-default div')).getAttribute('innerHTML')).toBe(
175         "new &lt;b onclick=\"alert(1)\"&gt;text&lt;/b&gt;");
176     });
177   </file>
178   </example>
179 */
180
181
182/**
183 * @ngdoc provider
184 * @name $sanitizeProvider
185 * @this
186 *
187 * @description
188 * Creates and configures {@link $sanitize} instance.
189 */
190function $SanitizeProvider() {
191  var hasBeenInstantiated = false;
192  var svgEnabled = false;
193
194  this.$get = ['$$sanitizeUri', function($$sanitizeUri) {
195    hasBeenInstantiated = true;
196    if (svgEnabled) {
197      extend(validElements, svgElements);
198    }
199    return function(html) {
200      var buf = [];
201      htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) {
202        return !/^unsafe:/.test($$sanitizeUri(uri, isImage));
203      }));
204      return buf.join('');
205    };
206  }];
207
208
209  /**
210   * @ngdoc method
211   * @name $sanitizeProvider#enableSvg
212   * @kind function
213   *
214   * @description
215   * Enables a subset of svg to be supported by the sanitizer.
216   *
217   * <div class="alert alert-warning">
218   *   <p>By enabling this setting without taking other precautions, you might expose your
219   *   application to click-hijacking attacks. In these attacks, sanitized svg elements could be positioned
220   *   outside of the containing element and be rendered over other elements on the page (e.g. a login
221   *   link). Such behavior can then result in phishing incidents.</p>
222   *
223   *   <p>To protect against these, explicitly setup `overflow: hidden` css rule for all potential svg
224   *   tags within the sanitized content:</p>
225   *
226   *   <br>
227   *
228   *   <pre><code>
229   *   .rootOfTheIncludedContent svg {
230   *     overflow: hidden !important;
231   *   }
232   *   </code></pre>
233   * </div>
234   *
235   * @param {boolean=} flag Enable or disable SVG support in the sanitizer.
236   * @returns {boolean|$sanitizeProvider} Returns the currently configured value if called
237   *    without an argument or self for chaining otherwise.
238   */
239  this.enableSvg = function(enableSvg) {
240    if (isDefined(enableSvg)) {
241      svgEnabled = enableSvg;
242      return this;
243    } else {
244      return svgEnabled;
245    }
246  };
247
248
249  /**
250   * @ngdoc method
251   * @name $sanitizeProvider#addValidElements
252   * @kind function
253   *
254   * @description
255   * Extends the built-in lists of valid HTML/SVG elements, i.e. elements that are considered safe
256   * and are not stripped off during sanitization. You can extend the following lists of elements:
257   *
258   * - `htmlElements`: A list of elements (tag names) to extend the current list of safe HTML
259   *   elements. HTML elements considered safe will not be removed during sanitization. All other
260   *   elements will be stripped off.
261   *
262   * - `htmlVoidElements`: This is similar to `htmlElements`, but marks the elements as
263   *   "void elements" (similar to HTML
264   *   [void elements](https://rawgit.com/w3c/html/html5.1-2/single-page.html#void-elements)). These
265   *   elements have no end tag and cannot have content.
266   *
267   * - `svgElements`: This is similar to `htmlElements`, but for SVG elements. This list is only
268   *   taken into account if SVG is {@link ngSanitize.$sanitizeProvider#enableSvg enabled} for
269   *   `$sanitize`.
270   *
271   * <div class="alert alert-info">
272   *   This method must be called during the {@link angular.Module#config config} phase. Once the
273   *   `$sanitize` service has been instantiated, this method has no effect.
274   * </div>
275   *
276   * <div class="alert alert-warning">
277   *   Keep in mind that extending the built-in lists of elements may expose your app to XSS or
278   *   other vulnerabilities. Be very mindful of the elements you add.
279   * </div>
280   *
281   * @param {Array<String>|Object} elements - A list of valid HTML elements or an object with one or
282   *   more of the following properties:
283   *   - **htmlElements** - `{Array<String>}` - A list of elements to extend the current list of
284   *     HTML elements.
285   *   - **htmlVoidElements** - `{Array<String>}` - A list of elements to extend the current list of
286   *     void HTML elements; i.e. elements that do not have an end tag.
287   *   - **svgElements** - `{Array<String>}` - A list of elements to extend the current list of SVG
288   *     elements. The list of SVG elements is only taken into account if SVG is
289   *     {@link ngSanitize.$sanitizeProvider#enableSvg enabled} for `$sanitize`.
290   *
291   * Passing an array (`[...]`) is equivalent to passing `{htmlElements: [...]}`.
292   *
293   * @return {$sanitizeProvider} Returns self for chaining.
294   */
295  this.addValidElements = function(elements) {
296    if (!hasBeenInstantiated) {
297      if (isArray(elements)) {
298        elements = {htmlElements: elements};
299      }
300
301      addElementsTo(svgElements, elements.svgElements);
302      addElementsTo(voidElements, elements.htmlVoidElements);
303      addElementsTo(validElements, elements.htmlVoidElements);
304      addElementsTo(validElements, elements.htmlElements);
305    }
306
307    return this;
308  };
309
310
311  /**
312   * @ngdoc method
313   * @name $sanitizeProvider#addValidAttrs
314   * @kind function
315   *
316   * @description
317   * Extends the built-in list of valid attributes, i.e. attributes that are considered safe and are
318   * not stripped off during sanitization.
319   *
320   * **Note**:
321   * The new attributes will not be treated as URI attributes, which means their values will not be
322   * sanitized as URIs using `$compileProvider`'s
323   * {@link ng.$compileProvider#aHrefSanitizationTrustedUrlList aHrefSanitizationTrustedUrlList} and
324   * {@link ng.$compileProvider#imgSrcSanitizationTrustedUrlList imgSrcSanitizationTrustedUrlList}.
325   *
326   * <div class="alert alert-info">
327   *   This method must be called during the {@link angular.Module#config config} phase. Once the
328   *   `$sanitize` service has been instantiated, this method has no effect.
329   * </div>
330   *
331   * <div class="alert alert-warning">
332   *   Keep in mind that extending the built-in list of attributes may expose your app to XSS or
333   *   other vulnerabilities. Be very mindful of the attributes you add.
334   * </div>
335   *
336   * @param {Array<String>} attrs - A list of valid attributes.
337   *
338   * @returns {$sanitizeProvider} Returns self for chaining.
339   */
340  this.addValidAttrs = function(attrs) {
341    if (!hasBeenInstantiated) {
342      extend(validAttrs, arrayToMap(attrs, true));
343    }
344    return this;
345  };
346
347  //////////////////////////////////////////////////////////////////////////////////////////////////
348  // Private stuff
349  //////////////////////////////////////////////////////////////////////////////////////////////////
350
351  bind = angular.bind;
352  extend = angular.extend;
353  forEach = angular.forEach;
354  isArray = angular.isArray;
355  isDefined = angular.isDefined;
356  lowercase = angular.$$lowercase;
357  noop = angular.noop;
358
359  htmlParser = htmlParserImpl;
360  htmlSanitizeWriter = htmlSanitizeWriterImpl;
361
362  nodeContains = window.Node.prototype.contains || /** @this */ function(arg) {
363    // eslint-disable-next-line no-bitwise
364    return !!(this.compareDocumentPosition(arg) & 16);
365  };
366
367  // Regular Expressions for parsing tags and attributes
368  var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
369    // Match everything outside of normal chars and " (quote character)
370    NON_ALPHANUMERIC_REGEXP = /([^#-~ |!])/g;
371
372
373  // Good source of info about elements and attributes
374  // http://dev.w3.org/html5/spec/Overview.html#semantics
375  // http://simon.html5.org/html-elements
376
377  // Safe Void Elements - HTML5
378  // http://dev.w3.org/html5/spec/Overview.html#void-elements
379  var voidElements = stringToMap('area,br,col,hr,img,wbr');
380
381  // Elements that you can, intentionally, leave open (and which close themselves)
382  // http://dev.w3.org/html5/spec/Overview.html#optional-tags
383  var optionalEndTagBlockElements = stringToMap('colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr'),
384      optionalEndTagInlineElements = stringToMap('rp,rt'),
385      optionalEndTagElements = extend({},
386                                              optionalEndTagInlineElements,
387                                              optionalEndTagBlockElements);
388
389  // Safe Block Elements - HTML5
390  var blockElements = extend({}, optionalEndTagBlockElements, stringToMap('address,article,' +
391          'aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' +
392          'h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,section,table,ul'));
393
394  // Inline Elements - HTML5
395  var inlineElements = extend({}, optionalEndTagInlineElements, stringToMap('a,abbr,acronym,b,' +
396          'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,' +
397          'samp,small,span,strike,strong,sub,sup,time,tt,u,var'));
398
399  // SVG Elements
400  // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Elements
401  // Note: the elements animate,animateColor,animateMotion,animateTransform,set are intentionally omitted.
402  // They can potentially allow for arbitrary javascript to be executed. See #11290
403  var svgElements = stringToMap('circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,' +
404          'hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,' +
405          'radialGradient,rect,stop,svg,switch,text,title,tspan');
406
407  // Blocked Elements (will be stripped)
408  var blockedElements = stringToMap('script,style');
409
410  var validElements = extend({},
411                                     voidElements,
412                                     blockElements,
413                                     inlineElements,
414                                     optionalEndTagElements);
415
416  //Attributes that have href and hence need to be sanitized
417  var uriAttrs = stringToMap('background,cite,href,longdesc,src,xlink:href,xml:base');
418
419  var htmlAttrs = stringToMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' +
420      'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,' +
421      'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,' +
422      'scope,scrolling,shape,size,span,start,summary,tabindex,target,title,type,' +
423      'valign,value,vspace,width');
424
425  // SVG attributes (without "id" and "name" attributes)
426  // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes
427  var svgAttrs = stringToMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' +
428      'baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,' +
429      'cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,' +
430      'font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,' +
431      'height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,keySplines,keyTimes,lang,' +
432      'marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mathematical,' +
433      'max,min,offset,opacity,orient,origin,overline-position,overline-thickness,panose-1,' +
434      'path,pathLength,points,preserveAspectRatio,r,refX,refY,repeatCount,repeatDur,' +
435      'requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,stemv,stop-color,' +
436      'stop-opacity,strikethrough-position,strikethrough-thickness,stroke,stroke-dasharray,' +
437      'stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,' +
438      'stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,underline-position,' +
439      'underline-thickness,unicode,unicode-range,units-per-em,values,version,viewBox,visibility,' +
440      'width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,xlink:show,xlink:title,' +
441      'xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,zoomAndPan', true);
442
443  var validAttrs = extend({},
444                                  uriAttrs,
445                                  svgAttrs,
446                                  htmlAttrs);
447
448  function stringToMap(str, lowercaseKeys) {
449    return arrayToMap(str.split(','), lowercaseKeys);
450  }
451
452  function arrayToMap(items, lowercaseKeys) {
453    var obj = {}, i;
454    for (i = 0; i < items.length; i++) {
455      obj[lowercaseKeys ? lowercase(items[i]) : items[i]] = true;
456    }
457    return obj;
458  }
459
460  function addElementsTo(elementsMap, newElements) {
461    if (newElements && newElements.length) {
462      extend(elementsMap, arrayToMap(newElements));
463    }
464  }
465
466  /**
467   * Create an inert document that contains the dirty HTML that needs sanitizing.
468   * We use the DOMParser API by default and fall back to createHTMLDocument if DOMParser is not
469   * available.
470   */
471  var getInertBodyElement /* function(html: string): HTMLBodyElement */ = (function(window, document) {
472    if (isDOMParserAvailable()) {
473      return getInertBodyElement_DOMParser;
474    }
475
476    if (!document || !document.implementation) {
477      throw $sanitizeMinErr('noinert', 'Can\'t create an inert html document');
478    }
479    var inertDocument = document.implementation.createHTMLDocument('inert');
480    var inertBodyElement = (inertDocument.documentElement || inertDocument.getDocumentElement()).querySelector('body');
481    return getInertBodyElement_InertDocument;
482
483    function isDOMParserAvailable() {
484      try {
485        return !!getInertBodyElement_DOMParser('');
486      } catch (e) {
487        return false;
488      }
489    }
490
491    function getInertBodyElement_DOMParser(html) {
492      // We add this dummy element to ensure that the rest of the content is parsed as expected
493      // e.g. leading whitespace is maintained and tags like `<meta>` do not get hoisted to the `<head>` tag.
494      html = '<remove></remove>' + html;
495      try {
496        var body = new window.DOMParser().parseFromString(html, 'text/html').body;
497        body.firstChild.remove();
498        return body;
499      } catch (e) {
500        return undefined;
501      }
502    }
503
504    function getInertBodyElement_InertDocument(html) {
505      inertBodyElement.innerHTML = html;
506
507      // Support: IE 9-11 only
508      // strip custom-namespaced attributes on IE<=11
509      if (document.documentMode) {
510        stripCustomNsAttrs(inertBodyElement);
511      }
512
513      return inertBodyElement;
514    }
515  })(window, window.document);
516
517  /**
518   * @example
519   * htmlParser(htmlString, {
520   *     start: function(tag, attrs) {},
521   *     end: function(tag) {},
522   *     chars: function(text) {},
523   *     comment: function(text) {}
524   * });
525   *
526   * @param {string} html string
527   * @param {object} handler
528   */
529  function htmlParserImpl(html, handler) {
530    if (html === null || html === undefined) {
531      html = '';
532    } else if (typeof html !== 'string') {
533      html = '' + html;
534    }
535
536    var inertBodyElement = getInertBodyElement(html);
537    if (!inertBodyElement) return '';
538
539    //mXSS protection
540    var mXSSAttempts = 5;
541    do {
542      if (mXSSAttempts === 0) {
543        throw $sanitizeMinErr('uinput', 'Failed to sanitize html because the input is unstable');
544      }
545      mXSSAttempts--;
546
547      // trigger mXSS if it is going to happen by reading and writing the innerHTML
548      html = inertBodyElement.innerHTML;
549      inertBodyElement = getInertBodyElement(html);
550    } while (html !== inertBodyElement.innerHTML);
551
552    var node = inertBodyElement.firstChild;
553    while (node) {
554      switch (node.nodeType) {
555        case 1: // ELEMENT_NODE
556          handler.start(node.nodeName.toLowerCase(), attrToMap(node.attributes));
557          break;
558        case 3: // TEXT NODE
559          handler.chars(node.textContent);
560          break;
561      }
562
563      var nextNode;
564      if (!(nextNode = node.firstChild)) {
565        if (node.nodeType === 1) {
566          handler.end(node.nodeName.toLowerCase());
567        }
568        nextNode = getNonDescendant('nextSibling', node);
569        if (!nextNode) {
570          while (nextNode == null) {
571            node = getNonDescendant('parentNode', node);
572            if (node === inertBodyElement) break;
573            nextNode = getNonDescendant('nextSibling', node);
574            if (node.nodeType === 1) {
575              handler.end(node.nodeName.toLowerCase());
576            }
577          }
578        }
579      }
580      node = nextNode;
581    }
582
583    while ((node = inertBodyElement.firstChild)) {
584      inertBodyElement.removeChild(node);
585    }
586  }
587
588  function attrToMap(attrs) {
589    var map = {};
590    for (var i = 0, ii = attrs.length; i < ii; i++) {
591      var attr = attrs[i];
592      map[attr.name] = attr.value;
593    }
594    return map;
595  }
596
597
598  /**
599   * Escapes all potentially dangerous characters, so that the
600   * resulting string can be safely inserted into attribute or
601   * element text.
602   * @param value
603   * @returns {string} escaped text
604   */
605  function encodeEntities(value) {
606    return value.
607      replace(/&/g, '&amp;').
608      replace(SURROGATE_PAIR_REGEXP, function(value) {
609        var hi = value.charCodeAt(0);
610        var low = value.charCodeAt(1);
611        return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
612      }).
613      replace(NON_ALPHANUMERIC_REGEXP, function(value) {
614        return '&#' + value.charCodeAt(0) + ';';
615      }).
616      replace(/</g, '&lt;').
617      replace(/>/g, '&gt;');
618  }
619
620  /**
621   * create an HTML/XML writer which writes to buffer
622   * @param {Array} buf use buf.join('') to get out sanitized html string
623   * @returns {object} in the form of {
624   *     start: function(tag, attrs) {},
625   *     end: function(tag) {},
626   *     chars: function(text) {},
627   *     comment: function(text) {}
628   * }
629   */
630  function htmlSanitizeWriterImpl(buf, uriValidator) {
631    var ignoreCurrentElement = false;
632    var out = bind(buf, buf.push);
633    return {
634      start: function(tag, attrs) {
635        tag = lowercase(tag);
636        if (!ignoreCurrentElement && blockedElements[tag]) {
637          ignoreCurrentElement = tag;
638        }
639        if (!ignoreCurrentElement && validElements[tag] === true) {
640          out('<');
641          out(tag);
642          forEach(attrs, function(value, key) {
643            var lkey = lowercase(key);
644            var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background');
645            if (validAttrs[lkey] === true &&
646              (uriAttrs[lkey] !== true || uriValidator(value, isImage))) {
647              out(' ');
648              out(key);
649              out('="');
650              out(encodeEntities(value));
651              out('"');
652            }
653          });
654          out('>');
655        }
656      },
657      end: function(tag) {
658        tag = lowercase(tag);
659        if (!ignoreCurrentElement && validElements[tag] === true && voidElements[tag] !== true) {
660          out('</');
661          out(tag);
662          out('>');
663        }
664        // eslint-disable-next-line eqeqeq
665        if (tag == ignoreCurrentElement) {
666          ignoreCurrentElement = false;
667        }
668      },
669      chars: function(chars) {
670        if (!ignoreCurrentElement) {
671          out(encodeEntities(chars));
672        }
673      }
674    };
675  }
676
677
678  /**
679   * When IE9-11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1' attribute to declare
680   * ns1 namespace and prefixes the attribute with 'ns1' (e.g. 'ns1:xlink:foo'). This is undesirable since we don't want
681   * to allow any of these custom attributes. This method strips them all.
682   *
683   * @param node Root element to process
684   */
685  function stripCustomNsAttrs(node) {
686    while (node) {
687      if (node.nodeType === window.Node.ELEMENT_NODE) {
688        var attrs = node.attributes;
689        for (var i = 0, l = attrs.length; i < l; i++) {
690          var attrNode = attrs[i];
691          var attrName = attrNode.name.toLowerCase();
692          if (attrName === 'xmlns:ns1' || attrName.lastIndexOf('ns1:', 0) === 0) {
693            node.removeAttributeNode(attrNode);
694            i--;
695            l--;
696          }
697        }
698      }
699
700      var nextNode = node.firstChild;
701      if (nextNode) {
702        stripCustomNsAttrs(nextNode);
703      }
704
705      node = getNonDescendant('nextSibling', node);
706    }
707  }
708
709  function getNonDescendant(propName, node) {
710    // An element is clobbered if its `propName` property points to one of its descendants
711    var nextNode = node[propName];
712    if (nextNode && nodeContains.call(node, nextNode)) {
713      throw $sanitizeMinErr('elclob', 'Failed to sanitize html because the element is clobbered: {0}', node.outerHTML || node.outerText);
714    }
715    return nextNode;
716  }
717}
718
719function sanitizeText(chars) {
720  var buf = [];
721  var writer = htmlSanitizeWriter(buf, noop);
722  writer.chars(chars);
723  return buf.join('');
724}
725
726
727// define ngSanitize module and register $sanitize service
728angular.module('ngSanitize', [])
729  .provider('$sanitize', $SanitizeProvider)
730  .info({ angularVersion: '1.8.
7302
vendor: 7,335 bytes, lines 730-929
730' });
731
732/**
733 * @ngdoc filter
734 * @name linky
735 * @kind function
736 *
737 * @description
738 * Finds links in text input and turns them into html links. Supports `http/https/ftp/sftp/mailto` and
739 * plain email address links.
740 *
741 * Requires the {@link ngSanitize `ngSanitize`} module to be installed.
742 *
743 * @param {string} text Input text.
744 * @param {string} [target] Window (`_blank|_self|_parent|_top`) or named frame to open links in.
745 * @param {object|function(url)} [attributes] Add custom attributes to the link element.
746 *
747 *    Can be one of:
748 *
749 *    - `object`: A map of attributes
750 *    - `function`: Takes the url as a parameter and returns a map of attributes
751 *
752 *    If the map of attributes contains a value for `target`, it overrides the value of
753 *    the target parameter.
754 *
755 *
756 * @returns {string} Html-linkified and {@link $sanitize sanitized} text.
757 *
758 * @usage
759   <span ng-bind-html="linky_expression | linky"></span>
760 *
761 * @example
762   <example module="linkyExample" deps="angular-sanitize.js" name="linky-filter">
763     <file name="index.html">
764       <div ng-controller="ExampleController">
765       Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
766       <table>
767         <tr>
768           <th>Filter</th>
769           <th>Source</th>
770           <th>Rendered</th>
771         </tr>
772         <tr id="linky-filter">
773           <td>linky filter</td>
774           <td>
775             <pre>&lt;div ng-bind-html="snippet | linky"&gt;<br>&lt;/div&gt;</pre>
776           </td>
777           <td>
778             <div ng-bind-html="snippet | linky"></div>
779           </td>
780         </tr>
781         <tr id="linky-target">
782          <td>linky target</td>
783          <td>
784            <pre>&lt;div ng-bind-html="snippetWithSingleURL | linky:'_blank'"&gt;<br>&lt;/div&gt;</pre>
785          </td>
786          <td>
787            <div ng-bind-html="snippetWithSingleURL | linky:'_blank'"></div>
788          </td>
789         </tr>
790         <tr id="linky-custom-attributes">
791          <td>linky custom attributes</td>
792          <td>
793            <pre>&lt;div ng-bind-html="snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}"&gt;<br>&lt;/div&gt;</pre>
794          </td>
795          <td>
796            <div ng-bind-html="snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}"></div>
797          </td>
798         </tr>
799         <tr id="escaped-html">
800           <td>no filter</td>
801           <td><pre>&lt;div ng-bind="snippet"&gt;<br>&lt;/div&gt;</pre></td>
802           <td><div ng-bind="snippet"></div></td>
803         </tr>
804       </table>
805     </file>
806     <file name="script.js">
807       angular.module('linkyExample', ['ngSanitize'])
808         .controller('ExampleController', ['$scope', function($scope) {
809           $scope.snippet =
810             'Pretty text with some links:\n' +
811             'http://angularjs.org/,\n' +
812             'mailto:[email protected],\n' +
813             '[email protected],\n' +
814             'and one more: ftp://127.0.0.1/.';
815           $scope.snippetWithSingleURL = 'http://angularjs.org/';
816         }]);
817     </file>
818     <file name="protractor.js" type="protractor">
819       it('should linkify the snippet with urls', function() {
820         expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
821             toBe('Pretty text with some links: http://angularjs.org/, [email protected], ' +
822                  '[email protected], and one more: ftp://127.0.0.1/.');
823         expect(element.all(by.css('#linky-filter a')).count()).toEqual(4);
824       });
825
826       it('should not linkify snippet without the linky filter', function() {
827         expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()).
828             toBe('Pretty text with some links: http://angularjs.org/, mailto:[email protected], ' +
829                  '[email protected], and one more: ftp://127.0.0.1/.');
830         expect(element.all(by.css('#escaped-html a')).count()).toEqual(0);
831       });
832
833       it('should update', function() {
834         element(by.model('snippet')).clear();
835         element(by.model('snippet')).sendKeys('new http://link.');
836         expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
837             toBe('new http://link.');
838         expect(element.all(by.css('#linky-filter a')).count()).toEqual(1);
839         expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText())
840             .toBe('new http://link.');
841       });
842
843       it('should work with the target property', function() {
844        expect(element(by.id('linky-target')).
845            element(by.binding("snippetWithSingleURL | linky:'_blank'")).getText()).
846            toBe('http://angularjs.org/');
847        expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');
848       });
849
850       it('should optionally add custom attributes', function() {
851        expect(element(by.id('linky-custom-attributes')).
852            element(by.binding("snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}")).getText()).
853            toBe('http://angularjs.org/');
854        expect(element(by.css('#linky-custom-attributes a')).getAttribute('rel')).toEqual('nofollow');
855       });
856     </file>
857   </example>
858 */
859angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
860  var LINKY_URL_REGEXP =
861        /((s?ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i,
862      MAILTO_REGEXP = /^mailto:/i;
863
864  var linkyMinErr = angular.$$minErr('linky');
865  var isDefined = angular.isDefined;
866  var isFunction = angular.isFunction;
867  var isObject = angular.isObject;
868  var isString = angular.isString;
869
870  return function(text, target, attributes) {
871    if (text == null || text === '') return text;
872    if (!isString(text)) throw linkyMinErr('notstring', 'Expected string but received: {0}', text);
873
874    var attributesFn =
875      isFunction(attributes) ? attributes :
876      isObject(attributes) ? function getAttributesObject() {return attributes;} :
877      function getEmptyAttributesObject() {return {};};
878
879    var match;
880    var raw = text;
881    var html = [];
882    var url;
883    var i;
884    while ((match = raw.match(LINKY_URL_REGEXP))) {
885      // We can not end in these as they are sometimes found at the end of the sentence
886      url = match[0];
887      // if we did not match ftp/http/www/mailto then assume mailto
888      if (!match[2] && !match[4]) {
889        url = (match[3] ? 'http://' : 'mailto:') + url;
890      }
891      i = match.index;
892      addText(raw.substr(0, i));
893      addLink(url, match[0].replace(MAILTO_REGEXP, ''));
894      raw = raw.substring(i + match[0].length);
895    }
896    addText(raw);
897    return $sanitize(html.join(''));
898
899    function addText(text) {
900      if (!text) {
901        return;
902      }
903      html.push(sanitizeText(text));
904    }
905
906    function addLink(url, text) {
907      var key, linkAttributes = attributesFn(url);
908      html.push('<a ');
909
910      for (key in linkAttributes) {
911        html.push(key + '="' + linkAttributes[key] + '" ');
912      }
913
914      if (isDefined(target) && !('target' in linkAttributes)) {
915        html.push('target="',
916                  target,
917                  '" ');
918      }
919      html.push('href="',
920                url.replace(/"/g, '&quot;'),
921                '">');
922      addText(text);
923      html.push('</a>');
924    }
925  };
926}]);
927
928
929})(window, window.angular);
930
931/*
932    Webnames Error
933    -----------------------------
934    Module is meant to handle server and client side errors.
935
936Scenarios:
9371.) Unexpected error
938	StatusCode = 500
939
940	Symptoms:
941	- threw out of controller action method
942
943	What should happen:
944	- gets logged as special critical error to investigate
945	- if Angular error handler is present, let that handle the user error
946	- if it's a production environment, allow them to log an error report
947	- if it's local host, display stack trace etc
948
949	Examples:
950	- developer forgets to handle an exception that can be thrown, fixable error occurs (null reference)
951	- the user should be able to report that an error occurred and the error should be investigated
952	- these prohibit the user from continuing their intended action on the site
953
954	Solution:
955	- the user should log an error
956
957	- inline form or link to oops page
958
959
9602.) Expected error
961	StatusCode = 422
962
963	Symptoms:
964	- it was caught in the controller, the StatusCode was manually set to 422
965
966	What should happen:
967	- should be handled in Angular controller, displaying a special message to the user (should/could use the WnErrorHandler)
968	- handle required view state on the promise rejection
969
970	Examples:
971	- server side validation of a domain name fails, return an error object and error message to display to the user
972
973    Author: Akos Sebestyen
974*/
975(function () {
976    "use strict";
977
978    angular.module('WebnamesError', ['ngSanitize'])
979
980        .config(['$httpProvider', function ($httpProvider) {
981            $httpProvider.interceptors.push('WnHttpInterceptor');
982        }])
983
984        .factory('WnHttpInterceptor', ['$log', '$q', '$sce', 'WnErrorHandler', function ($log, $q, $sce, WnErrorHandler) {
985            return {
986                'request': function (config) {
987                    // Add a custom header so our BaseController.cs can recognize that the WebnamesError module is present.
988                    return config;
989                },
990
991                'responseError': function (response) {
992                    // Convert the array buffer data into an object
993                    if (response.data instanceof ArrayBuffer) {
994                        response.data = JSON.parse(String.fromCharCode.apply(null, new Uint8Array(response.data)));
995                    }
996
997                    // Push the error into the error handler directive        
998                    if (response.status === 500 && !!response.data.wnAngularError) {
999                        WnErrorHandler.PushError(!!response.data.debugMode ? $sce.trustAsHtml(response.data.wnAngularError) : response.data.wnAngularError, true);
1000                    }
1001
1002                    return $q.reject(response);
1003                }
1004            }
1005        }]);
1006
1007})();
1008
1009/*
1010 * Webnames Error
1011 * ----------------
1012 * Directives for displaying errors to the user from Angular. 
1013 * 
1014 * Author: Akos Sebestyen
1015 */
1016(function () {
1017    "use strict";
1018
1019    angular.module('WebnamesError')
1020
1021        // you can specify the 'timeout-length' property to determine how long the notification should stay on screen
1022        .directive('wnNotifications', wnNotifications)
1023
1024        // errors for the user to see
1025        .directive('wnErrors', wnErrors)
1026
1027        .directive('helpdeskError', helpdeskError);
1028
1029    function wnNotifications() {
1030        return {
1031            restrict: 'EA',
1032            replace: true,
1033            template: '<div class="alert {{ notification.sCSSClass || \'alert-info\' }} alert-dismissible" data-ng-repeat="notification in wnn.notifications track by notification.id" role="alert">' +
1034                '<button class="close" data-dismiss="alert" aria-label="Close"><i class="fas fa-times"></i></button>' +
1035                '<p data-ng-bind-html="notification.message"></p>' +
1036                '</div>',
1037            controllerAs: 'wnn',
1038            link: function (scope, elem, attrs) {
1039                scope.$emit('wnNotifications loaded');
1040                if (!!attrs.timeoutLength) {
1041                    scope.timeoutLength = attrs.timeoutLength;
1042                }
1043            },
1044            controller: ['$scope', '$timeout', 'WnErrorHandler', function ($scope, $timeout, WnErrorHandler) {
1045                var vm = this;
1046
1047                vm.notifications = WnErrorHandler.Notifications;
1048
1049                $scope.$on('WnNotificationPushed', function (event, id) {
1050                    if (!!$scope.timeoutLength && $scope.timeoutLength > 0) {
1051                        $timeout(function () {
1052                            WnErrorHandler.RemoveById(id);
1053                        }, $scope.timeoutLength * 1000);
1054                    }
1055                });
1056
1057                vm.clear = function (id) {
1058                    WnErrorHandler.RemoveById(id);
1059                }
1060            }]
1061        }
1062    }
1063
1064    function wnErrors() {
1065        return {
1066            restrict: 'EA',
1067            replace: true,
1068            template: '<div id="webnames-error-directive" class="alert alert-danger alert-dismissible" data-ng-repeat="error in wne.errors track by error.id" role="alert">
1068' +
1069                '<button class="close" data-dismiss="alert" aria-label="Close" data-ng-if="!error.isCritical" data-ng-click="wne.clear(error.id)"><i class="fas fa-times"></i></button>' +
1070                '<p data-ng-bind-html="error.message"></p>' +
1071                '<p data-ng-if="error.isCritical">Timestamp: {{error.dtTimestamp | date: "yyyy-MM-dd H:mm:ss.sss"}}</p>' +
1072                '</div>',
1073            link: function (scope) {
1074                scope.$emit('wnErrors loaded');
1075            },
1076            controllerAs: 'wne',
1077            controller: ['$scope', '$timeout', 'WnErrorHandler', function ($scope, $timeout, WnErrorHandler) {
1078                var vm = this;
1079
1080                vm.errors = WnErrorHandler.Errors;
1081
1082                vm.clear = function (id) {
1083                    WnErrorHandler.RemoveById(id);
1084                }
1085            }]
1086        }
1087    }
1088
1089    function helpdeskError() {
1090        return {
1091            restrict: 'EA',
1092            template: '<div class="red-tip">' +
1093                '<h1>Cart Errors</h1>' +
1094                '<h3>Message</h3>' +
1095                '<p>{{message}}</p>' +
1096                '<h3>StackTrace</h3>' +
1097                '<p>{{stackTrace}}</p>' +
1098                '<h3>Suggested Solution</h3>' +
1099                '<p>{{suggestedSolution}}</p>' +
1100                '<h3>Timestamp</h3>' +
1101                '<p>{{dtCreated}}</p>' +
1102                '</div>',
1103            scope: {
1104                error: '='
1105            },
1106            controller: [
1107                '$scope', function ($scope) {
1108                    // When the error object changes, make sure it has all attributes and then display the error
1109                    $scope.$watch('error', function () {
1110                        if ($scope.error &&
1111                            $scope.error.message &&
1112                            $scope.error.stackTrace &&
1113                            $scope.error.suggestedSolution &&
1114                            $scope.error.dtCreated) {
1115                            $scope.message = $scope.error.message;
1116                            $scope.stackTrace = $scope.error.stackTrace;
1117                            $scope.suggestedSolution = $scope.error.suggestedSolution;
1118                            $scope.dtCreated = $scope.error.dtCreated;
1119                        }
1120                    });
1121                }
1122            ]
1123        }
1124    };
1125})();
1126
1127/*
1128    WebnamesError - WnErrorHandler
1129    ------------------
1130    Service used to push messages to the directive which will display them to the user.
1131
1132    Author: Akos Sebestyen
1133 */
1134(function () {
1135    "use strict";
1136
1137    angular.module('WebnamesError')
1138        .service('WnErrorHandler', ['$rootScope', '$timeout', '$window', '$location', '$anchorScroll', 'WnMessage', '$log', function ($rootScope, $timeout, $window, $location, $anchorScroll, WnMessage, $log) {
1139            var service = this;
1140            var messageCount = 0;
1141
1142            var wnNotificationsPresent = false;
1143            var wnErrorsPresent = false;
1144
1145            service.scrollToError = true;
1146            service.Notifications = [];
1147            service.Errors = [];
1148
1149            service.ClearAll = function () {
1150                // Must clear array using length so that references aren't lost
1151                service.Notifications.length = 0;
1152                service.Errors.length = 0;
1153            }
1154
1155            // Use this to push notifications to the user
1156            service.PushNotification = function (errorString, sCSSClass) {
1157                var id = messageCount;
1158                service.Notifications.push(new WnMessage(id, errorString, false, sCSSClass));
1159                $rootScope.$broadcast('WnNotificationPushed', id);
1160                messageCount++;
1161
1162                return service.Notifications[service.Notifications.length - 1];
1163            }
1164
1165            // Use this to push errors to the user
1166            service.PushError = function (errorString, isCritical) {
1167                var id = messageCount;
1168                service.Errors.push(new WnMessage(id, errorString, !!isCritical));
1169                $rootScope.$broadcast('WnErrorPushed', id);
1170                messageCount++;
1171
1172                if (service.scrollToError) {
1173                    $location.hash("webnames-error-directive");
1174                    $anchorScroll();
1175                }
1176
1177                return service.Errors[service.Errors.length - 1];
1178            }
1179
1180            service.GetById = function (id) {
1181                return _.findWhere(service.Notifications, { id: id });
1182            }
1183
1184            service.RemoveById = function (id) {
1185                var index = _.findIndex(service.Notifications, { id: id });
1186
1187                if (index < 0) {
1188                    index = _.findIndex(service.Errors, { id: id });
1189                    if (index > -1 && !service.Errors[index].isCritical) service.Errors.splice(index, 1);
1190                } else {
1191                    service.Notifications.splice(index, 1);
1192                }
1193            }
1194
1195            // TODO: implement parameters
1196            /**
1197             * Redirects client to the robot page.
1198             * @returns {} 
1199             */
1200            service.KillNonRecoverable = function () {
1201                $window.location.href = $window._SmartURL + "error/oops/default.aspx";
1202            }
1203
1204            // Save events from link function of directives for page validation
1205            $rootScope.$on('wnNotifications loaded', function () {
1206                wnNotificationsPresent = true;
1207            });
1208
1209            $rootScope.$on('wnErrors loaded', function () {
1210                wnErrorsPresent = true;
1211            });
1212
1213            // Used for validation of the Angular page
1214            $timeout(function () {
1215                if (!wnErrorsPresent) {
1216                    throw "No 'wnErrors' directive found! You should not use this module without placing this directive on your page first!";
1217                }
1218                if (!wnNotificationsPresent) {
1219                    throw "No 'wnNotifications' directive found! You should not use this module without placing this directive on your page first!";
1220                }
1221            });
1222        }])
1223
1224        .factory('WnMessage', [function () {
1225            function WnMessage(id, message, isCritical, sCSSClass) {
1226                var model = this;
1227
1228                model.id = id;
1229                model.dtTimestamp = new Date();
1230                model.isCritical = isCritical;
1231                model.sCSSClass = sCSSClass || "";
1232
1233                model.message = message;
1234            }
1235
1236            return WnMessage;
1237        }]);
1238})();
1239
1240/*
1241    Webnames Common
1242    --------------------------------
1243    Module to hold common Angular functions
1244    
1245    Author: Akos Sebestyen 2015
1246*/
1247(function () {
1248    "use strict";
1249
1250    angular.module('WebnamesCommon', []);
1251
1252})();
1253
1254
1255/*
1256    Generic Injector
1257    --------------------------------
1258    Used to inject data into Angular on pageload.
1259
1260    The provider exposes a "InjectGenericProperty" method that can be used at config time to get JSON data into the service.
1261
1262    Then you can access the data from GenericInjector.PropBag.yourProperty
1263    
1264    Author: Akos Sebestyen 2015
1265*/
1266(function () {
1267    "use strict";
1268
1269    angular.module('WebnamesCommon')
1270    .provider('GenericInjector', function () {
1271        var _propBag = {};
1272
1273        // Assign the prop bag
1274        var GenericInjector = function () {
1275            this.PropBag = _propBag;            
1276        };
1277
1278        return {
1279            $get: ['$injector', function ($injector) { return $injector.instantiate(GenericInjector) }],
1280            InjectGenericProperty: function (propName, propValue) { _propBag[propName] = propValue}
1281        }
1282    });
1283
1284})();
1285
1286
1287(function () {
1288    "use strict";
1289
1290    angular.module("WebnamesCommon")
1291    .factory("WnFocus", ['$timeout', '$document', function ($timeout, $document) {
1292        return function(id) {
1293            $timeout(function () {
1294                var element = $document.getElementById(id);
1295                if (element)
1296                    element.focus();
1297            });
1298        }                
1299    }]);
1300})();
1301// Scrolls to the top of the given selector. Use offset to offset the value by pixels
1302
1303(function () {
1304    "use strict";
1305
1306    angular.module("WebnamesCommon")
1307    .factory("WnScroll", ['$timeout', function ($timeout) {
1308        return function (selector, offset, animateTime) {
1309            if (!offset) offset = 0;
1310            if (!animateTime) animateTime = 500;
1311            $timeout(function () {
1312                $('html, body').animate({ scrollTop: ($(selector).offset().top + offset) }, animateTime);
1313            });
1314        }
1315    }]);
1316})();
1317// https://gist.github.com/tommaitland/7579618
1318(function () {
1319    angular.module('WebnamesCommon').directive('ngDebounce', ['$timeout', function ($timeout) {
1320        return {
1321            restrict: 'A',
1322            require: 'ngModel',
1323            priority: 99,
1324            link: function (scope, elm, attr, ngModelCtrl) {
1325                if (attr.type === 'radio' || attr.type === 'checkbox') return;
1326
1327                elm.unbind('input');
1328
1329                var debounce;
1330                elm.bind('input', function () {
1331                    $timeout.cancel(debounce);
1332                    debounce = $timeout(function () {
1333                        scope.$apply(function () {
1334                            ngModelCtrl.$setViewValue(elm.val());
1335                        });
1336                    }, attr.ngDebounce || 1000);
1337                });
1338                elm.bind('blur', function () {
1339                    scope.$apply(function () {
1340                        ngModelCtrl.$setViewValue(elm.val());
1341                    });
1342                });
1343            }
1344
1345        }
1346    }]);
1347})();
1348
1349(function () {
1350    "use strict";
1351
1352    angular.module('WebnamesCommon')
1353        .filter('startFrom', function () {
1354
1355            return function (input, start) {
1356                if (input !== undefined && angular.isArray(input)) {
1357                    return input.slice(start);
1358                } else {
1359                    return [];
1360                }
1361            }
1362        })
1363    .filter("getActiveKeys", [function () {
1364        /**
1365         * Takes an object and returns an array of keys where the values are truthy
1366         * @param {Object} obj Flat object of key value pairs
1367         * @returns {Array} array of keys with truthy values
1368         */
1369        return function(obj) {
1370            return _.chain(obj)
1371            .pairs() // Turn object into array of arrays as key value pairs
1372            .filter(function (kvp) { return !!kvp[1] }) // Return all Key-Value pairs where value is truthy
1373            .map(function (kvp) { return kvp[0] }) // Map into an array of just strings of keys
1374            .value();
1375        }
1376    }])
1377    .filter('nullToEnd', function () {
1378        return function (array, key) {
1379            if (!angular.isArray(array)) return;
1380
1381            var present = array.filter(function (item) {
1382                return item[key];
1383            });
1384            var empty = array.filter(function (item) {
1385                return !item[key];
1386            });
1387
1388            return present.concat(empty);
1389        }
1390    })
1391    .run(["$http", function ($http) {
1392        $http.defaults.headers.common['X-XSRF-Token'] =
1393            angular.element(document.querySelector('input[name="__RequestVerificationToken"]')).attr('value');
1394    }]);
1395})();
1396
1397angular.module('homeApp', ['ui.bootstrap', 'WebnamesCommon'])
1398    .controller('homeController', ['$scope', 'GenericInjector', function ($scope, GenericInjector) {
1399        $scope.bWixPromoActive = GenericInjector.PropBag.bWixPromoActive;
1400    }])
1401    .controller('ModalReferral', ['$scope', '$uibModal', '$log', '$http', function ($scope, $uibModal, $log, $http) {
1402        $scope.open = function (size) {
1403            var modalInstance = $uibModal.open({
1404                templateUrl: 'Home/tmpl/referralModal',
1405                controller: ['$scope', '$uibModalInstance', '$log', function ($scope, $uibModalInstance, $log) {
1406                    $log.debug('referralModal');
1407
1408                    $http.post(window._SmartURL + 'Home/CheckReferralValidResult')
1409                        .then(function success(response) {
1410                            $log.debug(response);
1411                            if (response.data.ReferralName == "") {
1412                                $scope.referralResult = "This account is ineligible for the referral credit or the referral ID is incorrect. Referral credits are available for new accounts that are linked to an unregistered email."
1413                            } else {
1414                                $scope.referralResult = "You will automatically receive " + response.data.ReferralCreditAmount + " off your first purchase of " + response.data.ReferralCreditThreshold +  " or more (before taxes, and after discounts). With 500+ domain extensions, powerful Canadian hosting and email, SSL, DNS hosting and more, we've got all the tools you need to make a name for yourself online. Let us know if you need anything, we're standing by to help! ";
1415                            }
1416                        },
1417                        function error(response) {
1418                            alert("Unknown error. Please refresh the page and try again, or contact Support.");
1419                        });
1420
1421                    $scope.ok = function () {
1422                        $log.debug('Close');
1423                        $uibModalInstance.close();
1424                    };
1425
1426                    $scope.cancel = function () {
1427                        $uibModalInstance.dismiss('cancel');
1428                    };
1429                }],
1430                size: size
1431            });
1432        };
1433
1434        $scope.$on('Modal.Referral', function (e) {
1435            $log.debug('Modal.Referral:Open');
1436            $scope.open('lg');
1437        });
1438    //Open as soon as it's loaded.
1439    $scope.open('lg');
1440}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.