PageSourceSearch

https://www.mairie-blagnac.fr/typo3conf/ext/cim_package_blagnac/Re…/js/lib/hunt.min.js?1696236357

js mairie-blagnac.fr collected 2026-10-02 10:21:46 UTC 17,895 bytes, 250 lines download raw bytes

1/* Hunt v4.1.0 - 2017 Jeremias Menichelli - MIT License */
2(function (global, factory) {
3  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
4  typeof define === 'function' && define.amd ? define(factory) :
5  (global.Hunt = factory());
6}(this, (function () { 'use strict';
7
8  var DEFAULT_THROTTLE_INTERVAL = 100;
9
10  /**
11   * Fallback function
12   * @method noop
13   * @returns {undefined}
14   */
15  var noop = function() {};
16
17  /**
18   * Prevents unnecessary calls through time interval polling
19   * @method throttle
20   * @param {Function} fn
21   * @returns {Function}
22   */
23  var throttle = function(fn, interval) {
24    var inThrottle;
25    var lastFunc;
26    var lastRan;
27
28    return function() {
29      var args = arguments;
30
31      if (inThrottle === true) {
32        clearTimeout(lastFunc);
33        lastFunc = setTimeout(function () {
34          if (Date.now() - lastRan >= interval) {
35            fn.apply(this, args);
36            lastRan = Date.now();
37          }
38        }, interval - (Date.now() - lastRan));
39      } else {
40        fn.apply(this, args);
41        lastRan = Date.now();
42        inThrottle = true;
43      }
44    };
45  };
46
47  /**
48   * Assign throttled actions and add listeners
49   * @param {Number} throttleInterval
50   * @method _connect
51   */
52  var _connect = function(throttleInterval) {
53    // throttle actions
54    this._throttledHuntElements = throttle(this._huntElements.bind(this), throttleInterval);
55    this._throttledUpdateMetrics = throttle(this._updateMetrics.bind(this), throttleInterval);
56
57    // add listeners
58    window.addEventListener('scroll', this._throttledHuntElements);
59    window.addEventListener('resize', this._throttledUpdateMetrics);
60
61    // run first check
62    this._huntElements();
63  };
64
65  /**
66   * Constructor for element that should be hunted
67   * @constructor Hunted
68   * @param {Node} element
69   * @param {Object} config
70   */
71  var Hunted = function(element, config) {
72    this.element = element;
73
74    // instantiate element as not visible
75    this.visible = false;
76
77    for (var prop in config) {
78      if (Object.hasOwnProperty.call(config, prop)) {
79        this[prop] = config[prop];
80      }
81    }
82
83    if (typeof element.dataset !== 'undefined') {
84      // replace options with dataset if present
85      if (typeof element.dataset.huntPersist !== 'undefined') {
86        try {
87          this.persist = JSON.parse(element.dataset.huntPersist);
88        } catch (e) {
89          console.log('hunt: invalid data-hunt-persist value', e);
90        }
91      }
92
93      if (typeof element.dataset.huntOffset !== 'undefined') {
94        try {
95          this.offset = JSON.parse(element.dataset.huntOffset);
96        } catch (e) {
97          console.log('hunt: invalid data-hunt-offset value', e);
98        }
99      }
100    }
101  };
102
103  // by default offset is zero
104  Hunted.prototype.offset = 0;
105
106  // by default trigger events only once
107  Hunted.prototype.persist = false;
108
109  // fallback enter function to avoid sanity check
110  Hunted.prototype.enter = noop;
111
112  // fallback leave function to avoid sanity check
113  Hunted.prototype.leave = noop;
114
115  /**
116   * Creates and initializes observer
117   * @constructor HuntObserver
118   * @param {Node|Array} elements
119   * @param {Object} options
120   */
121  var HuntObserver = function(elements, options) {
122    // sanity check for first argument
123    if (elements instanceof Node === false && typeof elements.length !== 'number') {
124      throw new TypeError('hunt: observer first argument should be a node or a list of nodes');
125    }
126
127    // sanity check for second argument
128    if (typeof options !== 'object') {
129      throw new TypeError('hunt: observer second argument should be an object');
130    }
131
132    // treat single node as array
133    if (elements instanceof Node === true) {
134      elements = [ elements ];
135    }
136
137    // track viewport height internally
138    this._viewportHeight = window.innerHeight;
139
140    // add elements to general hunted array
141    this._huntedElements = [];
142
143    var i = 0;
144    var len = elements.length;
145
146    for (; i < len; i++) {
147      this._huntedElements.push(new Hunted(elements[i], options));
148    }
149
150    // set up throttle interval
151    var throttleInterval = options.throttleInterval || DEFAULT_THROTTLE_INTERVAL;
152
153    // connect observer and pass in throttle interval
154    _connect.call(this, throttleInterval);
155
156    i = len = null;
157
158    // Return observer instance
159    return this;
160  };
161
162  /**
163   * Checks if hunted elements are visible and apply callbacks
164   * @method _huntElements
165   */
166  HuntObserver.prototype._huntElements = function() {
167    var len = this._huntedElements.length;
168    var hunted;
169    var rect;
170    var isOnViewport;
171
172    while (len) {
173      --len;
174
175      hunted = this._huntedElements[len];
176      rect = hunted.element.getBoundingClientRect();
177      isOnViewport = rect.top - hunted.offset < this._viewportHe
177ight && rect.top >= -(rect.height + hunted.offset);
178
179      /*
180       * trigger (enter) event if element comes from a non visible state and the scrolled
181       * viewport has reached the visible range of the element without exceeding it
182       */
183      if (hunted.visible === false && isOnViewport === true) {
184          hunted.enter.call(null, hunted.element);
185          hunted.visible = true;
186
187          // when the leave callback method is not set and hunting should not persist remove element
188          if (hunted.leave === noop && hunted.persist !== true) {
189            this._huntedElements.splice(len, 1);
190
191            // end observer activity when there are no more elements
192            if (this._huntedElements.length === 0) {
193              this.disconnect();
194            }
195          }
196        }
197
198      /*
199       * trigger (out) event if element comes from a visible state
200       * and it's out of the visible range its bottom or top limit
201       */
202      if (hunted.visible === true && isOnViewport === false) {
203        hunted.leave.call(null, hunted.element);
204        hunted.visible = false;
205
206        // when hunting should not persist remove element
207        if (hunted.persist !== true) {
208          this._huntedElements.splice(len, 1);
209
210          // end observer activity when there are no more elements
211          if (this._huntedElements.length === 0) {
212            this.disconnect();
213          }
214        }
215      }
216    }
217
218    len = hunted = rect = isOnViewport = null;
219  };
220
221  /**
222   * _huntElements public alias
223   * @method trigger
224   */
225  HuntObserver.prototype.trigger = HuntObserver.prototype._huntElements;
226
227  /**
228   * Update viewport tracked height and runs a check
229   * @method _updateMetrics
230   */
231  HuntObserver.prototype._updateMetrics = function() {
232    this._viewportHeight = window.innerHeight;
233    this._huntElements();
234  };
235
236  /**
237   * Remove listeners
238   * @method disconnect
239   */
240  HuntObserver.prototype.disconnect = function() {
241    // remove listeners
242    window.removeEventListener('scroll', this._throttledHuntElements);
243    window.removeEventListener('resize', this._throttledUpdateMetrics);
244  };
245
246  return HuntObserver;
247
248})));
249
250//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlcyI6WyJhc3NldHNfc2l0ZV9jb3JlX3ZpbGxlL2pzL2xpYi9odW50LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIEh1bnQgdjQuMS4wIC0gMjAxNyBKZXJlbWlhcyBNZW5pY2hlbGxpIC0gTUlUIExpY2Vuc2UgKi9cclxuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcclxuICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKSA6XHJcbiAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKGZhY3RvcnkpIDpcclxuICAoZ2xvYmFsLkh1bnQgPSBmYWN0b3J5KCkpO1xyXG59KHRoaXMsIChmdW5jdGlvbiAoKSB7ICd1c2Ugc3RyaWN0JztcclxuXHJcbiAgdmFyIERFRkFVTFRfVEhST1RUTEVfSU5URVJWQUwgPSAxMDA7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZhbGxiYWNrIGZ1bmN0aW9uXHJcbiAgICogQG1ldGhvZCBub29wXHJcbiAgICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICAgKi9cclxuICB2YXIgbm9vcCA9IGZ1bmN0aW9uKCkge307XHJcblxyXG4gIC8qKlxyXG4gICAqIFByZXZlbnRzIHVubmVjZXNzYXJ5IGNhbGxzIHRocm91Z2ggdGltZSBpbnRlcnZhbCBwb2xsaW5nXHJcbiAgICogQG1ldGhvZCB0aHJvdHRsZVxyXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXHJcbiAgICogQHJldHVybnMge0Z1bmN0aW9ufVxyXG4gICAqL1xyXG4gIHZhciB0aHJvdHRsZSA9IGZ1bmN0aW9uKGZuLCBpbnRlcnZhbCkge1xyXG4gICAgdmFyIGluVGhyb3R0bGU7XHJcbiAgICB2YXIgbGFzdEZ1bmM7XHJcbiAgICB2YXIgbGFzdFJhbjtcclxuXHJcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XHJcbiAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xyXG5cclxuICAgICAgaWYgKGluVGhyb3R0bGUgPT09IHRydWUpIHtcclxuICAgICAgICBjbGVhclRpbWVvdXQobGFzdEZ1bmMpO1xyXG4gICAgICAgIGxhc3RGdW5jID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICBpZiAoRGF0ZS5ub3coKSAtIGxhc3RSYW4gPj0gaW50ZXJ2YWwpIHtcclxuICAgICAgICAgICAgZm4uYXBwbHkodGhpcywgYXJncyk7XHJcbiAgICAgICAgICAgIGxhc3RSYW4gPSBEYXRlLm5vdygpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0sIGludGVydmFsIC0gKERhdGUubm93KCkgLSBsYXN0UmFuKSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgZm4uYXBwbHkodGhpcywgYXJncyk7XHJcbiAgICAgICAgbGFzdFJhbiA9IERhdGUubm93KCk7XHJcbiAgICAgICAgaW5UaHJvdHRsZSA9IHRydWU7XHJcbiAgICAgIH1cclxuICAgIH07XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogQXNzaWduIHRocm90dGxlZCBhY3Rpb25zIGFuZCBhZGQgbGlzdGVuZXJzXHJcbiAgICogQHBhcmFtIHtOdW1iZXJ9IHRocm90dGxlSW50ZXJ2YWxcclxuICAgKiBAbWV0aG9kIF9jb25uZWN0XHJcbiAgICovXHJcbiAgdmFyIF9jb25uZWN0ID0gZnVuY3Rpb24odGhyb3R0bGVJbnRlcnZhbCkge1xyXG4gICAgLy8gdGhyb3R0bGUgYW
250N0aW9uc1xyXG4gICAgdGhpcy5fdGhyb3R0bGVkSHVudEVsZW1lbnRzID0gdGhyb3R0bGUodGhpcy5faHVudEVsZW1lbnRzLmJpbmQodGhpcyksIHRocm90dGxlSW50ZXJ2YWwpO1xyXG4gICAgdGhpcy5fdGhyb3R0bGVkVXBkYXRlTWV0cmljcyA9IHRocm90dGxlKHRoaXMuX3VwZGF0ZU1ldHJpY3MuYmluZCh0aGlzKSwgdGhyb3R0bGVJbnRlcnZhbCk7XHJcblxyXG4gICAgLy8gYWRkIGxpc3RlbmVyc1xyXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuX3Rocm90dGxlZEh1bnRFbGVtZW50cyk7XHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5fdGhyb3R0bGVkVXBkYXRlTWV0cmljcyk7XHJcblxyXG4gICAgLy8gcnVuIGZpcnN0IGNoZWNrXHJcbiAgICB0aGlzLl9odW50RWxlbWVudHMoKTtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBDb25zdHJ1Y3RvciBmb3IgZWxlbWVudCB0aGF0IHNob3VsZCBiZSBodW50ZWRcclxuICAgKiBAY29uc3RydWN0b3IgSHVudGVkXHJcbiAgICogQHBhcmFtIHtOb2RlfSBlbGVtZW50XHJcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZ1xyXG4gICAqL1xyXG4gIHZhciBIdW50ZWQgPSBmdW5jdGlvbihlbGVtZW50LCBjb25maWcpIHtcclxuICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XHJcblxyXG4gICAgLy8gaW5zdGFudGlhdGUgZWxlbWVudCBhcyBub3QgdmlzaWJsZVxyXG4gICAgdGhpcy52aXNpYmxlID0gZmFsc2U7XHJcblxyXG4gICAgZm9yICh2YXIgcHJvcCBpbiBjb25maWcpIHtcclxuICAgICAgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKGNvbmZpZywgcHJvcCkpIHtcclxuICAgICAgICB0aGlzW3Byb3BdID0gY29uZmlnW3Byb3BdO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGVvZiBlbGVtZW50LmRhdGFzZXQgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgIC8vIHJlcGxhY2Ugb3B0aW9ucyB3aXRoIGRhdGFzZXQgaWYgcHJlc2VudFxyXG4gICAgICBpZiAodHlwZW9mIGVsZW1lbnQuZGF0YXNldC5odW50UGVyc2lzdCAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgdGhpcy5wZXJzaXN0ID0gSlNPTi5wYXJzZShlbGVtZW50LmRhdGFzZXQuaHVudFBlcnNpc3QpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgIGNvbnNvbGUubG9nKCdodW50OiBpbnZhbGlkIGRhdGEtaHVudC1wZXJzaXN0IHZhbHVlJywgZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodHlwZW9mIGVsZW1lbnQuZGF0YXNldC5odW50T2Zmc2V0ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICB0aGlzLm9mZnNldCA9IEpTT04ucGFyc2UoZWxlbWVudC5kYXRhc2V0Lmh1bnRPZmZzZXQpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgIGNvbnNvbGUubG9nKCdodW50OiBpbnZhbGlkIGRhdGEtaHVudC1vZmZzZXQgdmFsdWUnLCBlKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9O1xyXG5cclxuICAvLyBieSBkZWZhdWx0IG9mZnNldCBpcyB6ZXJvXHJcbiAgSHVudGVkLnByb3RvdHlwZS5vZmZzZXQgPSAwO1xyXG5cclxuICAvLyBieSBkZWZhdWx0IHRyaWdnZXIgZXZlbnRzIG9ubHkgb25jZVxyXG4gIEh1bnRlZC5wcm90b3R5cGUucGVyc2lzdCA9IGZhbHNlO1xyXG5cclxuICAvLyBmYWxsYmFjayBlbnRlciBmdW5jdGlvbiB0byBhdm9pZCBzYW5pdHkgY2hlY2tcclxuICBIdW50ZWQucHJvdG90eXBlLmVudGVyID0gbm9vcDtcclxuXHJcbiAgLy8gZmFsbGJhY2sgbGVhdmUgZnVuY3Rpb24gdG8gYXZvaWQgc2FuaXR5IGNoZWNrXHJcbiAgSHVudGVkLnByb3RvdHlwZS5sZWF2ZSA9IG5vb3A7XHJcblxyXG4gIC8qKlxyXG4gICAqIENyZWF0ZXMgYW5kIGluaXRpYWxpemVzIG9ic2VydmVyXHJcbiAgICogQGNvbnN0cnVjdG9yIEh1bnRPYnNlcnZlclxyXG4gICAqIEBwYXJhbSB7Tm9kZXxBcnJheX0gZWxlbWVudHNcclxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xyXG4gICAqL1xyXG4gIHZhciBIdW50T2JzZXJ2ZXIgPSBmdW5jdGlvbihlbGVtZW50cywgb3B0aW9ucykge1xyXG4gICAgLy8gc2FuaXR5IGNoZWNrIGZvciBmaXJzdCBhcmd1bWVudFxyXG4gICAgaWYgKGVsZW1lbnRzIGluc3RhbmNlb2YgTm9kZSA9PT0gZmFsc2UgJiYgdHlwZW9mIGVsZW1lbnRzLmxlbmd0aCAhPT0gJ251bWJlcicpIHtcclxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaHVudDogb2JzZXJ2ZXIgZmlyc3QgYXJndW1lbnQgc2hvdWxkIGJlIGEgbm9kZSBvciBhIGxpc3Qgb2Ygbm9kZXMnKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBzYW5pdHkgY2hlY2sgZm9yIHNlY29uZCBhcmd1bWVudFxyXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0Jykge1xyXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdodW50OiBvYnNlcnZlciBzZWNvbmQgYXJndW1lbnQgc2hvdWxkIGJlIGFuIG9iamVjdCcpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHRyZWF0IHNpbmdsZSBub2RlIGFzIGFycmF5XHJcbiAgICBpZiAoZWxlbWVudHMgaW5zdGFuY2VvZiBOb2RlID09PSB0cnVlKSB7XHJcbiAgICAgIGVsZW1lbnRzID0gWyBlbGVtZW50cyBdO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHRyYWNrIHZpZXdwb3J0IGhlaWdodCBpbnRlcm5hbGx5XHJcbiAgICB0aGlzLl92aWV3cG9ydEhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcclxuXHJcbiAgICAvLyBhZGQgZWxlbWVudHMgdG8gZ2VuZXJhbCBodW50ZWQgYXJyYXlcclxuICAgIHRoaXMuX2h1bnRlZEVsZW1lbnRzID0gW107XHJcblxyXG4gICAgdmFyIGkgPSAwO1xyXG4gICAgdmFyIGxlbiA9IGVsZW1lbnRzLmxlbmd0aDtcclxuXHJcbiAgICBmb3IgKDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgIHRoaXMuX2h1bnRlZEVsZW1lbnRzLnB1c2gobmV3IEh1bnRlZChlbGVtZW50c1tpXSwgb3B0aW9ucykpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHNldCB1cCB0aHJvdHRsZSBpbnRlcnZhbFxyXG4gICAgdmFyIHRocm90dGxlSW50ZXJ2YWwgPSBvcHRpb25zLnRocm90dGxlSW50ZXJ2YWwgfHwgREVGQVVMVF9USFJPVFRMRV9JTlRFUlZBTDtcclxuXHJcbiAgICAvLyBjb25uZWN0IG9ic2VydmVyIGFuZCBwYXNzIGluIHRocm90dGxlIGludGVydmFsXHJcbiAgICBfY29ubmVjdC5jYWxsKHRoaXMsIHR
250ocm90dGxlSW50ZXJ2YWwpO1xyXG5cclxuICAgIGkgPSBsZW4gPSBudWxsO1xyXG5cclxuICAgIC8vIFJldHVybiBvYnNlcnZlciBpbnN0YW5jZVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2tzIGlmIGh1bnRlZCBlbGVtZW50cyBhcmUgdmlzaWJsZSBhbmQgYXBwbHkgY2FsbGJhY2tzXHJcbiAgICogQG1ldGhvZCBfaHVudEVsZW1lbnRzXHJcbiAgICovXHJcbiAgSHVudE9ic2VydmVyLnByb3RvdHlwZS5faHVudEVsZW1lbnRzID0gZnVuY3Rpb24oKSB7XHJcbiAgICB2YXIgbGVuID0gdGhpcy5faHVudGVkRWxlbWVudHMubGVuZ3RoO1xyXG4gICAgdmFyIGh1bnRlZDtcclxuICAgIHZhciByZWN0O1xyXG4gICAgdmFyIGlzT25WaWV3cG9ydDtcclxuXHJcbiAgICB3aGlsZSAobGVuKSB7XHJcbiAgICAgIC0tbGVuO1xyXG5cclxuICAgICAgaHVudGVkID0gdGhpcy5faHVudGVkRWxlbWVudHNbbGVuXTtcclxuICAgICAgcmVjdCA9IGh1bnRlZC5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICBpc09uVmlld3BvcnQgPSByZWN0LnRvcCAtIGh1bnRlZC5vZmZzZXQgPCB0aGlzLl92aWV3cG9ydEhlaWdodCAmJiByZWN0LnRvcCA+PSAtKHJlY3QuaGVpZ2h0ICsgaHVudGVkLm9mZnNldCk7XHJcblxyXG4gICAgICAvKlxyXG4gICAgICAgKiB0cmlnZ2VyIChlbnRlcikgZXZlbnQgaWYgZWxlbWVudCBjb21lcyBmcm9tIGEgbm9uIHZpc2libGUgc3RhdGUgYW5kIHRoZSBzY3JvbGxlZFxyXG4gICAgICAgKiB2aWV3cG9ydCBoYXMgcmVhY2hlZCB0aGUgdmlzaWJsZSByYW5nZSBvZiB0aGUgZWxlbWVudCB3aXRob3V0IGV4Y2VlZGluZyBpdFxyXG4gICAgICAgKi9cclxuICAgICAgaWYgKGh1bnRlZC52aXNpYmxlID09PSBmYWxzZSAmJiBpc09uVmlld3BvcnQgPT09IHRydWUpIHtcclxuICAgICAgICAgIGh1bnRlZC5lbnRlci5jYWxsKG51bGwsIGh1bnRlZC5lbGVtZW50KTtcclxuICAgICAgICAgIGh1bnRlZC52aXNpYmxlID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAvLyB3aGVuIHRoZSBsZWF2ZSBjYWxsYmFjayBtZXRob2QgaXMgbm90IHNldCBhbmQgaHVudGluZyBzaG91bGQgbm90IHBlcnNpc3QgcmVtb3ZlIGVsZW1lbnRcclxuICAgICAgICAgIGlmIChodW50ZWQubGVhdmUgPT09IG5vb3AgJiYgaHVudGVkLnBlcnNpc3QgIT09IHRydWUpIHtcclxuICAgICAgICAgICAgdGhpcy5faHVudGVkRWxlbWVudHMuc3BsaWNlKGxlbiwgMSk7XHJcblxyXG4gICAgICAgICAgICAvLyBlbmQgb2JzZXJ2ZXIgYWN0aXZpdHkgd2hlbiB0aGVyZSBhcmUgbm8gbW9yZSBlbGVtZW50c1xyXG4gICAgICAgICAgICBpZiAodGhpcy5faHVudGVkRWxlbWVudHMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5kaXNjb25uZWN0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAvKlxyXG4gICAgICAgKiB0cmlnZ2VyIChvdXQpIGV2ZW50IGlmIGVsZW1lbnQgY29tZXMgZnJvbSBhIHZpc2libGUgc3RhdGVcclxuICAgICAgICogYW5kIGl0J3Mgb3V0IG9mIHRoZSB2aXNpYmxlIHJhbmdlIGl0cyBib3R0b20gb3IgdG9wIGxpbWl0XHJcbiAgICAgICAqL1xyXG4gICAgICBpZiAoaHVudGVkLnZpc2libGUgPT09IHRydWUgJiYgaXNPblZpZXdwb3J0ID09PSBmYWxzZSkge1xyXG4gICAgICAgIGh1bnRlZC5sZWF2ZS5jYWxsKG51bGwsIGh1bnRlZC5lbGVtZW50KTtcclxuICAgICAgICBodW50ZWQudmlzaWJsZSA9IGZhbHNlO1xyXG5cclxuICAgICAgICAvLyB3aGVuIGh1bnRpbmcgc2hvdWxkIG5vdCBwZXJzaXN0IHJlbW92ZSBlbGVtZW50XHJcbiAgICAgICAgaWYgKGh1bnRlZC5wZXJzaXN0ICE9PSB0cnVlKSB7XHJcbiAgICAgICAgICB0aGlzLl9odW50ZWRFbGVtZW50cy5zcGxpY2UobGVuLCAxKTtcclxuXHJcbiAgICAgICAgICAvLyBlbmQgb2JzZXJ2ZXIgYWN0aXZpdHkgd2hlbiB0aGVyZSBhcmUgbm8gbW9yZSBlbGVtZW50c1xyXG4gICAgICAgICAgaWYgKHRoaXMuX2h1bnRlZEVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICB0aGlzLmRpc2Nvbm5lY3QoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBsZW4gPSBodW50ZWQgPSByZWN0ID0gaXNPblZpZXdwb3J0ID0gbnVsbDtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBfaHVudEVsZW1lbnRzIHB1YmxpYyBhbGlhc1xyXG4gICAqIEBtZXRob2QgdHJpZ2dlclxyXG4gICAqL1xyXG4gIEh1bnRPYnNlcnZlci5wcm90b3R5cGUudHJpZ2dlciA9IEh1bnRPYnNlcnZlci5wcm90b3R5cGUuX2h1bnRFbGVtZW50cztcclxuXHJcbiAgLyoqXHJcbiAgICogVXBkYXRlIHZpZXdwb3J0IHRyYWNrZWQgaGVpZ2h0IGFuZCBydW5zIGEgY2hlY2tcclxuICAgKiBAbWV0aG9kIF91cGRhdGVNZXRyaWNzXHJcbiAgICovXHJcbiAgSHVudE9ic2VydmVyLnByb3RvdHlwZS5fdXBkYXRlTWV0cmljcyA9IGZ1bmN0aW9uKCkge1xyXG4gICAgdGhpcy5fdmlld3BvcnRIZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7XHJcbiAgICB0aGlzLl9odW50RWxlbWVudHMoKTtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBSZW1vdmUgbGlzdGVuZXJzXHJcbiAgICogQG1ldGhvZCBkaXNjb25uZWN0XHJcbiAgICovXHJcbiAgSHVudE9ic2VydmVyLnByb3RvdHlwZS5kaXNjb25uZWN0ID0gZnVuY3Rpb24oKSB7XHJcbiAgICAvLyByZW1vdmUgbGlzdGVuZXJzXHJcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5fdGhyb3R0bGVkSHVudEVsZW1lbnRzKTtcclxuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLl90aHJvdHRsZWRVcGRhdGVNZXRyaWNzKTtcclxuICB9O1xyXG5cclxuICByZXR1cm4gSHVudE9ic2VydmVyO1xyXG5cclxufSkpKTtcclxuIl0sImZpbGUiOiJhc3NldHNfc2l0ZV9jb3JlX3ZpbGxlL2pzL2xpYi9odW50Lm1pbi5qcyJ9

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.