1/** 2 * what-input - A global utility for tracking the current input method (mouse, keyboard or touch). 3 * @version v4.2.0 4 * @link https://github.com/ten1seven/what-input 5 * @license MIT 6 */ 7(function webpackUniversalModuleDefinition(root, factory) { 8 if(typeof exports === 'object' && typeof module === 'object') 9 module.exports = factory(); 10 else if(typeof define === 'function' && define.amd) 11 define("whatInput", [], factory); 12 else if(typeof exports === 'object') 13 exports["whatInput"] = factory(); 14 else 15 root["whatInput"] = factory(); 16})(this, function() { 17return /******/ (function(modules) { // webpackBootstrap 18/******/ // The module cache 19/******/ var installedModules = {}; 20 21/******/ // The require function 22/******/ function __webpack_require__(moduleId) { 23 24/******/ // Check if module is in cache 25/******/ if(installedModules[moduleId]) 26/******/ return installedModules[moduleId].exports; 27 28/******/ // Create a new module (and put it into the cache) 29/******/ var module = installedModules[moduleId] = { 30/******/ exports: {}, 31/******/ id: moduleId, 32/******/ loaded: false 33/******/ }; 34 35/******/ // Execute the module function 36/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 37 38/******/ // Flag the module as loaded 39/******/ module.loaded = true; 40 41/******/ // Return the exports of the module 42/******/ return module.exports; 43/******/ } 44 45 46/******/ // expose the modules object (__webpack_modules__) 47/******/ __webpack_require__.m = modules; 48 49/******/ // expose the module cache 50/******/ __webpack_require__.c = installedModules; 51 52/******/ // __webpack_public_path__ 53/******/ __webpack_require__.p = ""; 54 55/******/ // Load entry module and return exports 56/******/ return __webpack_require__(0); 57/******/ }) 58/************************************************************************/ 59/******/ ([ 60/* 0 */ 61/***/ (function(module, exports) { 62 63 'use strict'; 64 65 module.exports = function () { 66 /* 67 * variables 68 */ 69 70 // last used input type 71 var currentInput = 'initial'; 72 73 // last used input intent 74 var currentIntent = null; 75 76 // cache document.documentElement 77 var doc = document.documentElement; 78 79 // form input types 80 var formInputs = ['input', 'select', 'textarea']; 81 82 var functionList = []; 83 84 // list of modifier keys commonly used with the mouse and 85 // can be safely ignored to prevent false keyboard detection 86 var ignoreMap = [16, // shift 87 17, // control 88 18, // alt 89 91, // Windows key / left Apple cmd 90 93 // Windows menu / right Apple cmd 91 ]; 92 93 // list of keys for which we change intent even for form inputs 94 var changeIntentMap = [9 // tab 95 ]; 96 97 // mapping of events to input types 98 var inputMap = { 99 keydown: 'keyboard', 100 mousedown: 'mouse', 101 mousemove: 'mouse', 102 MSPointerDown: 'pointer', 103 MSPointerMove: 'pointer', 104 pointerdown: 'pointer', 105 pointermove: 'pointer', 106 touchstart: 'touch' 107 }; 108 109 // array of all used input types 110 var inputTypes = []; 111 112 // boolean: true if touch buffer is active 113 var isBuffering = false; 114 115 // boolean: true if the page is being scrolled 116 var isScrolling = false; 117 118 // store current mouse position 119 var mousePos = { 120 x: null, 121 y: null 122 }; 123 124 // map of IE 10 pointer events 125 var pointerMap = { 126 2: 'touch', 127 3: 'touch', // treat pen like touch 128 4: 'mouse' 129 }; 130 131 var supportsPassive = false; 132 133 try { 134 var opts = Object.defineProperty({}, 'passive', { 135 get: function get() { 136 supportsPassive = true; 137 } 138 }); 139 140 window.addEventListener('test', null, opts); 141 } catch (e) {} 142 143 /* 144 * set up 145 */ 146 147 var setUp = function setUp() { 148 // add correct mouse wheel event mapping to `inputMap` 149 inputMap[detectWheel()] = 'mouse'; 150 151 addListeners(); 152 setInput(); 153 }; 154 155 /* 156 * events 157 */ 158 159 var addListeners = function addListeners() { 160 // `pointermove`, `MSPointerMove`, `mousemove` and mouse wheel event binding 161 // can only demonstrate potential, but not actual, interaction 162 // and are treated separately 163 164 // pointer events (mouse, pen, touch) 165 if (window.PointerEvent) { 166 doc.addEventListener('pointerdown', updateInput); 167 doc.addEventListener('pointermove', setIntent); 168 } else if (window.MSPointerEvent) { 169 doc.addEventListener('MSPointerDown', updateInput); 170 doc.addEventListener('MSPointerMove', setIntent); 171 } else { 172 // mouse events 173 doc.addEventListener('mousedown', updateInput); 174 doc.addEventListener('mousemove', setIntent); 175 176 // touch events 177 if ('ontouchstart' in window) { 178 doc.addEventListener('touchstart', touchBuffer); 179 doc.addEventListener('touchend', touchBuffer); 180 } 181 } 182 183 // mouse wheel 184 doc.addEventListener(detectWheel(), setIntent, supportsPassive ? { passive: true } : false); 185 186 // keyboard events 187 doc.addEventListener('keydown', updateInput); 188 }; 189 190 // checks conditions before updating new input 191 var updateInput = function updateInput(event) { 192 // only execute if the touch buffer timer isn't running 193 if (!isBuffering) { 194 var eventKey = event.which; 195 var value = inputMap[event.type]; 196 if (value === 'pointer') value = pointerType(event); 197 198 if (currentInput !== value || currentIntent !== value) { 199 var activeElem = document.activeElement; 200 var activeInput = false; 201 var notFormInput = activeElem && activeElem.nodeName && formInputs.indexOf(activeElem.nodeName.toLowerCase()) === -1; 202 203 if (notFormInput || changeIntentMap.indexOf(eventKey) !== -1) { 204 activeInput = true; 205 } 206 207 if (value === 'touch' || 208 // ignore mouse modifier keys 209 value === 'mouse' || 210 // don't switch if the current element is a form input 211 value === 'keyboard' && eventKey && activeInput && ignoreMap.indexOf(eventKey) === -1) { 212 // set the current and catch-all variable 213 currentInput = currentIntent = value; 214 215 setInput(); 216 } 217 } 218 } 219 }; 220
221 // updates the doc and `inputTypes` array with new input 222 var setInput = function setInput() { 223 doc.setAttribute('data-whatinput', currentInput); 224 doc.setAttribute('data-whatintent', currentInput); 225 226 if (inputTypes.indexOf(currentInput) === -1) { 227 inputTypes.push(currentInput); 228 doc.className += ' whatinput-types-' + currentInput; 229 } 230 231 fireFunctions('input'); 232 }; 233 234 // updates input intent for `mousemove` and `pointermove` 235 var setIntent = function setIntent(event) { 236 // test to see if `mousemove` happened relative to the screen 237 // to detect scrolling versus mousemove 238 if (mousePos['x'] !== event.screenX || mousePos['y'] !== event.screenY) { 239 isScrolling = false; 240 241 mousePos['x'] = event.screenX; 242 mousePos['y'] = event.screenY; 243 } else { 244 isScrolling = true; 245 } 246 247 // only execute if the touch buffer timer isn't running 248 // or scrolling isn't happening 249 if (!isBuffering && !isScrolling) { 250 var value = inputMap[event.type]; 251 if (value === 'pointer') value = pointerType(event); 252 253 if (currentIntent !== value) { 254 currentIntent = value; 255 256 doc.setAttribute('data-whatintent', currentIntent); 257 258 fireFunctions('intent'); 259 } 260 } 261 }; 262 263 // buffers touch events because they frequently also fire mouse events 264 var touchBuffer = function touchBuffer(event) { 265 if (event.type === 'touchstart') { 266 isBuffering = false; 267 268 // set the current input 269 updateInput(event); 270 } else { 271 isBuffering = true; 272 } 273 }; 274 275 var fireFunctions = function fireFunctions(type) { 276 for (var i = 0, len = functionList.length; i < len; i++) { 277 if (functionList[i].type === type) { 278 functionList[i].function.call(undefined, currentIntent); 279 } 280 } 281 }; 282 283 /* 284 * utilities 285 */ 286 287 var pointerType = function pointerType(event) { 288 if (typeof event.pointerType === 'number') { 289 return pointerMap[event.pointerType]; 290 } else { 291 // treat pen like touch 292 return event.pointerType === 'pen' ? 'touch' : event.pointerType; 293 } 294 }; 295 296 // detect version of mouse wheel event to use 297 // via https://developer.mozilla.org/en-US/docs/Web/Events/wheel 298 var detectWheel = function detectWheel() { 299 var wheelType = void 0; 300 301 // Modern browsers support "wheel" 302 if ('onwheel' in document.createElement('div')) { 303 wheelType = 'wheel'; 304 } else { 305 // Webkit and IE support at least "mousewheel" 306 // or assume that remaining browsers are older Firefox 307 wheelType = document.onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll'; 308 } 309 310 return wheelType; 311 }; 312 313 /* 314 * init 315 */ 316 317 // don't start script unless browser cuts the mustard 318 // (also passes if polyfills are used) 319 if ('addEventListener' in window && Array.prototype.indexOf) { 320 setUp(); 321 } 322 323 /* 324 * api 325 */ 326 327 return { 328 // returns string: the current input type 329 // opt: 'loose'|'strict' 330 // 'strict' (default): returns the same value as the `data-whatinput` attribute 331 // 'loose': includes `data-whatintent` value if it's more current than `data-whatinput` 332 ask: function ask(opt) { 333 return opt === 'loose' ? currentIntent : currentInput; 334 }, 335 336 // returns array: all the detected input types 337 types: function types() { 338 return inputTypes; 339 }, 340 341 // overwrites ignored keys with provided array 342 ignoreKeys: function ignoreKeys(arr) { 343 ignoreMap = arr; 344 }, 345 346 // attach functions to input and intent "events" 347 // funct: function to fire on change 348 // eventType: 'input'|'intent' 349 onChange: function onChange(funct, eventType) { 350 functionList.push({ 351 function: funct, 352 type: eventType 353 }); 354 } 355 }; 356 }(); 357 358/***/ }) 359/******/ ]) 360}); 361; 362//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlcyI6WyJhc3NldHNfc2l0ZV9jb3JlX3ZpbGxlL2pzL2xpYi93aGF0LWlucHV0LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxyXG4gKiB3aGF0LWlucHV0IC0gQSBnbG9iYWwgdXRpbGl0eSBmb3IgdHJhY2tpbmcgdGhlIGN1cnJlbnQgaW5wdXQgbWV0aG9kIChtb3VzZSwga2V5Ym9hcmQgb3IgdG91Y2gpLlxyXG4gKiBAdmVyc2lvbiB2NC4yLjBcclxuICogQGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3RlbjFzZXZlbi93aGF0LWlucHV0XHJcbiAqIEBsaWNlbnNlIE1JVFxyXG4gKi9cclxuKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcclxuXHRpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcpXHJcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcclxuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcclxuXHRcdGRlZmluZShcIndoYXRJbnB1dFwiLCBbXSwgZmFjdG9yeSk7XHJcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXHJcblx0XHRleHBvcnRzW1wid2hhdElucHV0XCJdID0gZmFjdG9yeSgpO1xyXG5cdGVsc2VcclxuXHRcdHJvb3RbXCJ3aGF0SW5wdXRcIl0gPSBmYWN0b3J5KCk7XHJcbn0pKHRoaXMsIGZ1bmN0aW9uKCkge1xyXG5yZXR1cm4gLyoqKioqKi8gKGZ1bmN0aW9uKG1vZHVsZXMpIHsgLy8gd2VicGFja0Jvb3RzdHJhcFxyXG4vKioqKioqLyBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcclxuLyoqKioqKi8gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xyXG5cclxuLyoqKioqKi8gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxyXG4vKioqKioqLyBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcclxuXHJcbi8qKioqKiovIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcclxuLyoqKioqKi8gXHRcdGlmKGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdKVxyXG4vKioqKioqLyBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcclxuXHJcbi8qKioqKiovIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9k
362dWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxyXG4vKioqKioqLyBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xyXG4vKioqKioqLyBcdFx0XHRleHBvcnRzOiB7fSxcclxuLyoqKioqKi8gXHRcdFx0aWQ6IG1vZHVsZUlkLFxyXG4vKioqKioqLyBcdFx0XHRsb2FkZWQ6IGZhbHNlXHJcbi8qKioqKiovIFx0XHR9O1xyXG5cclxuLyoqKioqKi8gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxyXG4vKioqKioqLyBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XHJcblxyXG4vKioqKioqLyBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxyXG4vKioqKioqLyBcdFx0bW9kdWxlLmxvYWRlZCA9IHRydWU7XHJcblxyXG4vKioqKioqLyBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcclxuLyoqKioqKi8gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcclxuLyoqKioqKi8gXHR9XHJcblxyXG5cclxuLyoqKioqKi8gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxyXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XHJcblxyXG4vKioqKioqLyBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXHJcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcclxuXHJcbi8qKioqKiovIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cclxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xyXG5cclxuLyoqKioqKi8gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcclxuLyoqKioqKi8gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuLyoqKioqKi8gfSlcclxuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyoqKioqKi8gKFtcclxuLyogMCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XHJcblxyXG5cdCd1c2Ugc3RyaWN0JztcclxuXHJcblx0bW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XHJcblx0ICAvKlxyXG5cdCAgICogdmFyaWFibGVzXHJcblx0ICAgKi9cclxuXHJcblx0ICAvLyBsYXN0IHVzZWQgaW5wdXQgdHlwZVxyXG5cdCAgdmFyIGN1cnJlbnRJbnB1dCA9ICdpbml0aWFsJztcclxuXHJcblx0ICAvLyBsYXN0IHVzZWQgaW5wdXQgaW50ZW50XHJcblx0ICB2YXIgY3VycmVudEludGVudCA9IG51bGw7XHJcblxyXG5cdCAgLy8gY2FjaGUgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50XHJcblx0ICB2YXIgZG9jID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xyXG5cclxuXHQgIC8vIGZvcm0gaW5wdXQgdHlwZXNcclxuXHQgIHZhciBmb3JtSW5wdXRzID0gWydpbnB1dCcsICdzZWxlY3QnLCAndGV4dGFyZWEnXTtcclxuXHJcblx0ICB2YXIgZnVuY3Rpb25MaXN0ID0gW107XHJcblxyXG5cdCAgLy8gbGlzdCBvZiBtb2RpZmllciBrZXlzIGNvbW1vbmx5IHVzZWQgd2l0aCB0aGUgbW91c2UgYW5kXHJcblx0ICAvLyBjYW4gYmUgc2FmZWx5IGlnbm9yZWQgdG8gcHJldmVudCBmYWxzZSBrZXlib2FyZCBkZXRlY3Rpb25cclxuXHQgIHZhciBpZ25vcmVNYXAgPSBbMTYsIC8vIHNoaWZ0XHJcblx0ICAxNywgLy8gY29udHJvbFxyXG5cdCAgMTgsIC8vIGFsdFxyXG5cdCAgOTEsIC8vIFdpbmRvd3Mga2V5IC8gbGVmdCBBcHBsZSBjbWRcclxuXHQgIDkzIC8vIFdpbmRvd3MgbWVudSAvIHJpZ2h0IEFwcGxlIGNtZFxyXG5cdCAgXTtcclxuXHJcblx0ICAvLyBsaXN0IG9mIGtleXMgZm9yIHdoaWNoIHdlIGNoYW5nZSBpbnRlbnQgZXZlbiBmb3IgZm9ybSBpbnB1dHNcclxuXHQgIHZhciBjaGFuZ2VJbnRlbnRNYXAgPSBbOSAvLyB0YWJcclxuXHQgIF07XHJcblxyXG5cdCAgLy8gbWFwcGluZyBvZiBldmVudHMgdG8gaW5wdXQgdHlwZXNcclxuXHQgIHZhciBpbnB1dE1hcCA9IHtcclxuXHQgICAga2V5ZG93bjogJ2tleWJvYXJkJyxcclxuXHQgICAgbW91c2Vkb3duOiAnbW91c2UnLFxyXG5cdCAgICBtb3VzZW1vdmU6ICdtb3VzZScsXHJcblx0ICAgIE1TUG9pbnRlckRvd246ICdwb2ludGVyJyxcclxuXHQgICAgTVNQb2ludGVyTW92ZTogJ3BvaW50ZXInLFxyXG5cdCAgICBwb2ludGVyZG93bjogJ3BvaW50ZXInLFxyXG5cdCAgICBwb2ludGVybW92ZTogJ3BvaW50ZXInLFxyXG5cdCAgICB0b3VjaHN0YXJ0OiAndG91Y2gnXHJcblx0ICB9O1xyXG5cclxuXHQgIC8vIGFycmF5IG9mIGFsbCB1c2VkIGlucHV0IHR5cGVzXHJcblx0ICB2YXIgaW5wdXRUeXBlcyA9IFtdO1xyXG5cclxuXHQgIC8vIGJvb2xlYW46IHRydWUgaWYgdG91Y2ggYnVmZmVyIGlzIGFjdGl2ZVxyXG5cdCAgdmFyIGlzQnVmZmVyaW5nID0gZmFsc2U7XHJcblxyXG5cdCAgLy8gYm9vbGVhbjogdHJ1ZSBpZiB0aGUgcGFnZSBpcyBiZWluZyBzY3JvbGxlZFxyXG5cdCAgdmFyIGlzU2Nyb2xsaW5nID0gZmFsc2U7XHJcblxyXG5cdCAgLy8gc3RvcmUgY3VycmVudCBtb3VzZSBwb3NpdGlvblxyXG5cdCAgdmFyIG1vdXNlUG9zID0ge1xyXG5cdCAgICB4OiBudWxsLFxyXG5cdCAgICB5OiBudWxsXHJcblx0ICB9O1xyXG5cclxuXHQgIC8vIG1hcCBvZiBJRSAxMCBwb2ludGVyIGV2ZW50c1xyXG5cdCAgdmFyIHBvaW50ZXJNYXAgPSB7XHJcblx0ICAgIDI6ICd0b3VjaCcsXHJcblx0ICAgIDM6ICd0b3VjaCcsIC8vIHRyZWF0IHBlbiBsaWtlIHRvdWNoXHJcblx0ICAgIDQ6ICdtb3VzZSdcclxuXHQgIH07XHJcblxyXG5cdCAgdmFyIHN1cHBvcnRzUGFzc2l2ZSA9IGZhbHNlO1xyXG5cclxuXHQgIHRyeSB7XHJcblx0ICAgIHZhciBvcHRzID0gT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAncGFzc2l2ZScsIHtcclxuXHQgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcclxuXHQgICAgICAgIHN1cHBvcnRzUGFzc2l2ZSA9IHRydWU7XHJcblx0ICAgICAgfVxyXG5cdCAgICB9KTtcclxuXHJcblx0ICAgIHdpbmRvdy5hZGR
362FdmVudExpc3RlbmVyKCd0ZXN0JywgbnVsbCwgb3B0cyk7XHJcblx0ICB9IGNhdGNoIChlKSB7fVxyXG5cclxuXHQgIC8qXHJcblx0ICAgKiBzZXQgdXBcclxuXHQgICAqL1xyXG5cclxuXHQgIHZhciBzZXRVcCA9IGZ1bmN0aW9uIHNldFVwKCkge1xyXG5cdCAgICAvLyBhZGQgY29ycmVjdCBtb3VzZSB3aGVlbCBldmVudCBtYXBwaW5nIHRvIGBpbnB1dE1hcGBcclxuXHQgICAgaW5wdXRNYXBbZGV0ZWN0V2hlZWwoKV0gPSAnbW91c2UnO1xyXG5cclxuXHQgICAgYWRkTGlzdGVuZXJzKCk7XHJcblx0ICAgIHNldElucHV0KCk7XHJcblx0ICB9O1xyXG5cclxuXHQgIC8qXHJcblx0ICAgKiBldmVudHNcclxuXHQgICAqL1xyXG5cclxuXHQgIHZhciBhZGRMaXN0ZW5lcnMgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcnMoKSB7XHJcblx0ICAgIC8vIGBwb2ludGVybW92ZWAsIGBNU1BvaW50ZXJNb3ZlYCwgYG1vdXNlbW92ZWAgYW5kIG1vdXNlIHdoZWVsIGV2ZW50IGJpbmRpbmdcclxuXHQgICAgLy8gY2FuIG9ubHkgZGVtb25zdHJhdGUgcG90ZW50aWFsLCBidXQgbm90IGFjdHVhbCwgaW50ZXJhY3Rpb25cclxuXHQgICAgLy8gYW5kIGFyZSB0cmVhdGVkIHNlcGFyYXRlbHlcclxuXHJcblx0ICAgIC8vIHBvaW50ZXIgZXZlbnRzIChtb3VzZSwgcGVuLCB0b3VjaClcclxuXHQgICAgaWYgKHdpbmRvdy5Qb2ludGVyRXZlbnQpIHtcclxuXHQgICAgICBkb2MuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCB1cGRhdGVJbnB1dCk7XHJcblx0ICAgICAgZG9jLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgc2V0SW50ZW50KTtcclxuXHQgICAgfSBlbHNlIGlmICh3aW5kb3cuTVNQb2ludGVyRXZlbnQpIHtcclxuXHQgICAgICBkb2MuYWRkRXZlbnRMaXN0ZW5lcignTVNQb2ludGVyRG93bicsIHVwZGF0ZUlucHV0KTtcclxuXHQgICAgICBkb2MuYWRkRXZlbnRMaXN0ZW5lcignTVNQb2ludGVyTW92ZScsIHNldEludGVudCk7XHJcblx0ICAgIH0gZWxzZSB7XHJcblx0ICAgICAgLy8gbW91c2UgZXZlbnRzXHJcblx0ICAgICAgZG9jLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHVwZGF0ZUlucHV0KTtcclxuXHQgICAgICBkb2MuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgc2V0SW50ZW50KTtcclxuXHJcblx0ICAgICAgLy8gdG91Y2ggZXZlbnRzXHJcblx0ICAgICAgaWYgKCdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdykge1xyXG5cdCAgICAgICAgZG9jLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCB0b3VjaEJ1ZmZlcik7XHJcblx0ICAgICAgICBkb2MuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0b3VjaEJ1ZmZlcik7XHJcblx0ICAgICAgfVxyXG5cdCAgICB9XHJcblxyXG5cdCAgICAvLyBtb3VzZSB3aGVlbFxyXG5cdCAgICBkb2MuYWRkRXZlbnRMaXN0ZW5lcihkZXRlY3RXaGVlbCgpLCBzZXRJbnRlbnQsIHN1cHBvcnRzUGFzc2l2ZSA/IHsgcGFzc2l2ZTogdHJ1ZSB9IDogZmFsc2UpO1xyXG5cclxuXHQgICAgLy8ga2V5Ym9hcmQgZXZlbnRzXHJcblx0ICAgIGRvYy5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdXBkYXRlSW5wdXQpO1xyXG5cdCAgfTtcclxuXHJcblx0ICAvLyBjaGVja3MgY29uZGl0aW9ucyBiZWZvcmUgdXBkYXRpbmcgbmV3IGlucHV0XHJcblx0ICB2YXIgdXBkYXRlSW5wdXQgPSBmdW5jdGlvbiB1cGRhdGVJbnB1dChldmVudCkge1xyXG5cdCAgICAvLyBvbmx5IGV4ZWN1dGUgaWYgdGhlIHRvdWNoIGJ1ZmZlciB0aW1lciBpc24ndCBydW5uaW5nXHJcblx0ICAgIGlmICghaXNCdWZmZXJpbmcpIHtcclxuXHQgICAgICB2YXIgZXZlbnRLZXkgPSBldmVudC53aGljaDtcclxuXHQgICAgICB2YXIgdmFsdWUgPSBpbnB1dE1hcFtldmVudC50eXBlXTtcclxuXHQgICAgICBpZiAodmFsdWUgPT09ICdwb2ludGVyJykgdmFsdWUgPSBwb2ludGVyVHlwZShldmVudCk7XHJcblxyXG5cdCAgICAgIGlmIChjdXJyZW50SW5wdXQgIT09IHZhbHVlIHx8IGN1cnJlbnRJbnRlbnQgIT09IHZhbHVlKSB7XHJcblx0ICAgICAgICB2Y
362XIgYWN0aXZlRWxlbSA9IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XHJcblx0ICAgICAgICB2YXIgYWN0aXZlSW5wdXQgPSBmYWxzZTtcclxuXHQgICAgICAgIHZhciBub3RGb3JtSW5wdXQgPSBhY3RpdmVFbGVtICYmIGFjdGl2ZUVsZW0ubm9kZU5hbWUgJiYgZm9ybUlucHV0cy5pbmRleE9mKGFjdGl2ZUVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSkgPT09IC0xO1xyXG5cclxuXHQgICAgICAgIGlmIChub3RGb3JtSW5wdXQgfHwgY2hhbmdlSW50ZW50TWFwLmluZGV4T2YoZXZlbnRLZXkpICE9PSAtMSkge1xyXG5cdCAgICAgICAgICBhY3RpdmVJbnB1dCA9IHRydWU7XHJcblx0ICAgICAgICB9XHJcblxyXG5cdCAgICAgICAgaWYgKHZhbHVlID09PSAndG91Y2gnIHx8XHJcblx0ICAgICAgICAvLyBpZ25vcmUgbW91c2UgbW9kaWZpZXIga2V5c1xyXG5cdCAgICAgICAgdmFsdWUgPT09ICdtb3VzZScgfHxcclxuXHQgICAgICAgIC8vIGRvbid0IHN3aXRjaCBpZiB0aGUgY3VycmVudCBlbGVtZW50IGlzIGEgZm9ybSBpbnB1dFxyXG5cdCAgICAgICAgdmFsdWUgPT09ICdrZXlib2FyZCcgJiYgZXZlbnRLZXkgJiYgYWN0aXZlSW5wdXQgJiYgaWdub3JlTWFwLmluZGV4T2YoZXZlbnRLZXkpID09PSAtMSkge1xyXG5cdCAgICAgICAgICAvLyBzZXQgdGhlIGN1cnJlbnQgYW5kIGNhdGNoLWFsbCB2YXJpYWJsZVxyXG5cdCAgICAgICAgICBjdXJyZW50SW5wdXQgPSBjdXJyZW50SW50ZW50ID0gdmFsdWU7XHJcblxyXG5cdCAgICAgICAgICBzZXRJbnB1dCgpO1xyXG5cdCAgICAgICAgfVxyXG5cdCAgICAgIH1cclxuXHQgICAgfVxyXG5cdCAgfTtcclxuXHJcblx0ICAvLyB1cGRhdGVzIHRoZSBkb2MgYW5kIGBpbnB1dFR5cGVzYCBhcnJheSB3aXRoIG5ldyBpbnB1dFxyXG5cdCAgdmFyIHNldElucHV0ID0gZnVuY3Rpb24gc2V0SW5wdXQoKSB7XHJcblx0ICAgIGRvYy5zZXRBdHRyaWJ1dGUoJ2RhdGEtd2hhdGlucHV0JywgY3VycmVudElucHV0KTtcclxuXHQgICAgZG9jLnNldEF0dHJpYnV0ZSgnZGF0YS13aGF0aW50ZW50JywgY3VycmVudElucHV0KTtcclxuXHJcblx0ICAgIGlmIChpbnB1dFR5cGVzLmluZGV4T2YoY3VycmVudElucHV0KSA9PT0gLTEpIHtcclxuXHQgICAgICBpbnB1dFR5cGVzLnB1c2goY3VycmVudElucHV0KTtcclxuXHQgICAgICBkb2MuY2xhc3NOYW1lICs9ICcgd2hhdGlucHV0LXR5cGVzLScgKyBjdXJyZW50SW5wdXQ7XHJcblx0ICAgIH1cclxuXHJcblx0ICAgIGZpcmVGdW5jdGlvbnMoJ2lucHV0Jyk7XHJcblx0ICB9O1xyXG5cclxuXHQgIC8vIHVwZGF0ZXMgaW5wdXQgaW50ZW50IGZvciBgbW91c2Vtb3ZlYCBhbmQgYHBvaW50ZXJtb3ZlYFxyXG5cdCAgdmFyIHNldEludGVudCA9IGZ1bmN0aW9uIHNldEludGVudChldmVudCkge1xyXG5cdCAgICAvLyB0ZXN0IHRvIHNlZSBpZiBgbW91c2Vtb3ZlYCBoYXBwZW5lZCByZWxhdGl2ZSB0byB0aGUgc2NyZWVuXHJcblx0ICAgIC8vIHRvIGRldGVjdCBzY3JvbGxpbmcgdmVyc3VzIG1vdXNlbW92ZVxyXG5cdCAgICBpZiAobW91c2VQb3NbJ3gnXSAhPT0gZXZlbnQuc2NyZWVuWCB8fCBtb3VzZVBvc1sneSddICE9PSBldmVudC5zY3JlZW5ZKSB7XHJcblx0ICAgICAgaXNTY3JvbGxpbmcgPSBmYWxzZTtcclxuXHJcblx0ICAgICAgbW91c2VQb3NbJ3gnXSA9IGV2ZW50LnNjcmVlblg7XHJcblx0ICAgICAgbW91c2VQb3NbJ3knXSA9IGV2ZW50LnNjcmVlblk7XHJcblx0ICAgIH0gZWxzZSB7XHJcblx0ICAgICAgaXNTY3JvbGxpbmcgPSB0cnVlO1xyXG5cdCAgICB9XHJcblxyXG5cdCAgICAvLyBvbmx5IGV4ZWN1dGUgaWYgdGhlIHRvdWNoIGJ1ZmZlciB0aW1lciBpc24ndCBydW5uaW5nXHJcblx0ICAgIC8vIG9yIHNjcm9sbGluZyBpc24ndCBoYXBwZW5pbmdcclxuXHQgICAgaWYgKCFpc0J1ZmZlcmluZyAmJiAhaXNTY3JvbGxpbmcpIHtcclxuXHQgICAgICB2YXIgdmFsdWUgPSBpbnB1dE1hcFtldmVudC50eXBlXTtcclxuXHQgICAgICBpZiAodmFsdWUgPT09ICdwb2ludGVyJykgdmFsdWUgPSBwb2ludGVyVHlwZShldmVudCk7XHJcblxyXG5cdCAgICAgIGlmIChjdXJyZW50SW50ZW50ICE9PSB2YWx1ZSkge1xyXG5cdCAgICAgICAgY3VycmVudEludGVudCA9IHZhbHVlO1xyXG5cclxuXHQgICAgICAgIGRvYy5zZXRBdHRyaWJ1dGUoJ2RhdGEtd2hhdGludGVudCcsIGN1cnJlbnRJbnRlbnQpO1xyXG5cclxuXHQgICAgICAgIGZpcmVGdW5jdGlvbnMoJ2ludGVudCcpO1xyXG5cdCAgICAgIH1cclxuXHQgICAgfVxyXG5cdCAgfTtcclxuXHJcblx0ICAvLyBidWZmZXJzIHRvdWNoIGV2ZW50cyBiZWNhdXNlIHRoZXkgZnJlcXVlbnRseSBhbHNvIGZpcmUgbW91c2UgZXZlbnRzXHJcblx0ICB2YXIgdG91Y2hCdWZmZXIgPSBmdW5jdGlvbiB0b3VjaEJ1ZmZlcihldmVudCkge1xyXG5cdCAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ3RvdWNoc3RhcnQnKSB7XHJcblx0ICAgICAgaXNCdWZmZXJpbmcgPSBmYWxzZTtcclxuXHJcblx0ICAgICAgLy8gc2V0IHRoZSBjdXJyZW50IGlucHV0XHJcblx0ICAgICAgdXBkYXRlSW5wdXQoZXZlbnQpO1xyXG5cdCAgICB9IGVsc2Uge1xyXG5cdCAgICAgIGlzQnVmZmVyaW5nID0gdHJ1ZTtcclxuXHQgICAgfVxyXG5cdCAgfTtcclxuXHJcblx0ICB2YXIgZmlyZUZ1bmN0aW9ucyA9IGZ1bmN0aW9uIGZpcmVGdW5jdGlvbnModHlwZSkge1xyXG5cdCAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gZnVuY3Rpb25MaXN0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcblx0ICAgICAgaWYgKGZ1bmN0aW9uTGlzdFtpXS50eXBlID09PSB0eXBlKSB7XHJcblx0ICAgICAgICBmdW5jdGlvbkxpc3RbaV0uZnVuY3Rpb24uY2FsbCh1bmRlZmluZWQsIGN1cnJlbnRJbnRlbnQpO1xyXG5cdCAgICAgIH1cclxuXHQgICAgfVxyXG5cdCAgfTtcclxuXHJcblx0ICAvKlxyXG5cdCAgICogdXRpbGl0aWVzXHJcblx0ICAgKi9cclxuXHJcblx0ICB2YXIgcG9pbnRlclR5cGUgPSBmdW5jdGlvbiBwb2ludGVyVHlwZShldmVudCkge1xyXG5cdCAgICBpZiAodHlwZW9mIGV2ZW50LnBvaW50ZXJUeXBlID09PSAnbnVtYmVyJykge1xyXG5cdCAgICAgI
362HJldHVybiBwb2ludGVyTWFwW2V2ZW50LnBvaW50ZXJUeXBlXTtcclxuXHQgICAgfSBlbHNlIHtcclxuXHQgICAgICAvLyB0cmVhdCBwZW4gbGlrZSB0b3VjaFxyXG5cdCAgICAgIHJldHVybiBldmVudC5wb2ludGVyVHlwZSA9PT0gJ3BlbicgPyAndG91Y2gnIDogZXZlbnQucG9pbnRlclR5cGU7XHJcblx0ICAgIH1cclxuXHQgIH07XHJcblxyXG5cdCAgLy8gZGV0ZWN0IHZlcnNpb24gb2YgbW91c2Ugd2hlZWwgZXZlbnQgdG8gdXNlXHJcblx0ICAvLyB2aWEgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvRXZlbnRzL3doZWVsXHJcblx0ICB2YXIgZGV0ZWN0V2hlZWwgPSBmdW5jdGlvbiBkZXRlY3RXaGVlbCgpIHtcclxuXHQgICAgdmFyIHdoZWVsVHlwZSA9IHZvaWQgMDtcclxuXHJcblx0ICAgIC8vIE1vZGVybiBicm93c2VycyBzdXBwb3J0IFwid2hlZWxcIlxyXG5cdCAgICBpZiAoJ29ud2hlZWwnIGluIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpKSB7XHJcblx0ICAgICAgd2hlZWxUeXBlID0gJ3doZWVsJztcclxuXHQgICAgfSBlbHNlIHtcclxuXHQgICAgICAvLyBXZWJraXQgYW5kIElFIHN1cHBvcnQgYXQgbGVhc3QgXCJtb3VzZXdoZWVsXCJcclxuXHQgICAgICAvLyBvciBhc3N1bWUgdGhhdCByZW1haW5pbmcgYnJvd3NlcnMgYXJlIG9sZGVyIEZpcmVmb3hcclxuXHQgICAgICB3aGVlbFR5cGUgPSBkb2N1bWVudC5vbm1vdXNld2hlZWwgIT09IHVuZGVmaW5lZCA/ICdtb3VzZXdoZWVsJyA6ICdET01Nb3VzZVNjcm9sbCc7XHJcblx0ICAgIH1cclxuXHJcblx0ICAgIHJldHVybiB3aGVlbFR5cGU7XHJcblx0ICB9O1xyXG5cclxuXHQgIC8qXHJcblx0ICAgKiBpbml0XHJcblx0ICAgKi9cclxuXHJcblx0ICAvLyBkb24ndCBzdGFydCBzY3JpcHQgdW5sZXNzIGJyb3dzZXIgY3V0cyB0aGUgbXVzdGFyZFxyXG5cdCAgLy8gKGFsc28gcGFzc2VzIGlmIHBvbHlmaWxscyBhcmUgdXNlZClcclxuXHQgIGlmICgnYWRkRXZlbnRMaXN0ZW5lcicgaW4gd2luZG93ICYmIEFycmF5LnByb3RvdHlwZS5pbmRleE9mKSB7XHJcblx0ICAgIHNldFVwKCk7XHJcblx0ICB9XHJcblxyXG5cdCAgLypcclxuXHQgICAqIGFwaVxyXG5cdCAgICovXHJcblxyXG5cdCAgcmV0dXJuIHtcclxuXHQgICAgLy8gcmV0dXJucyBzdHJpbmc6IHRoZSBjdXJyZW50IGlucHV0IHR5cGVcclxuXHQgICAgLy8gb3B0OiAnbG9vc2UnfCdzdHJpY3QnXHJcblx0ICAgIC8vICdzdHJpY3QnIChkZWZhdWx0KTogcmV0dXJucyB0aGUgc2FtZSB2YWx1ZSBhcyB0aGUgYGRhdGEtd2hhdGlucHV0YCBhdHRyaWJ1dGVcclxuXHQgICAgLy8gJ2xvb3NlJzogaW5jbHVkZXMgYGRhdGEtd2hhdGludGVudGAgdmFsdWUgaWYgaXQncyBtb3JlIGN1cnJlbnQgdGhhbiBgZGF0YS13aGF0aW5wdXRgXHJcblx0ICAgIGFzazogZnVuY3Rpb24gYXNrKG9wdCkge1xyXG5cdCAgICAgIHJldHVybiBvcHQgPT09ICdsb29zZScgPyBjdXJyZW50SW50ZW50IDogY3VycmVudElucHV0O1xyXG5cdCAgICB9LFxyXG5cclxuXHQgICAgLy8gcmV0dXJucyBhcnJheTogYWxsIHRoZSBkZXRlY3RlZCBpbnB1dCB0eXBlc1xyXG5cdCAgICB0eXBlczogZnVuY3Rpb24gdHlwZXMoKSB7XHJcblx0ICAgICAgcmV0dXJuIGlucHV0VHlwZXM7XHJcblx0ICAgIH0sXHJcblxyXG5cdCAgICAvLyBvdmVyd3JpdGVzIGlnbm9yZWQga2V5cyB3aXRoIHByb3ZpZGVkIGFycmF5XHJcblx0ICAgIGlnbm9yZUtleXM6IGZ1bmN0aW9uIGlnbm9yZUtleXMoYXJyKSB7XHJcblx0ICAgICAgaWdub3JlTWFwID0gYXJyO1xyXG5cdCAgICB9LFxyXG5cclxuXHQgICAgLy8gYXR0YWNoIGZ1bmN0aW9ucyB0byBpbnB1dCBhbmQgaW50ZW50IFwiZXZlbnRzXCJcclxuXHQgICAgLy8gZnVuY3Q6IGZ1bmN0aW9uIHRvIGZpcmUgb24gY2hhbmdlXHJcblx0ICAgIC8vIGV2ZW50VHlwZTogJ2lucHV0J3wnaW50ZW50J1xyXG5cdCAgICBvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UoZnVuY3QsIGV2ZW50VHlwZSkge1xyXG5cdCAgICAgIGZ1bmN0aW9uTGlzdC5wdXNoKHtcclxuXHQgICAgICAgIGZ1bmN0aW9uOiBmdW5jdCxcclxuXHQgICAgICAgIHR5cGU6IGV2ZW50VHlwZVxyXG5cdCAgICAgIH0pO1xyXG5cdCAgICB9XHJcblx0ICB9O1xyXG5cdH0oKTtcclxuXHJcbi8qKiovIH0pXHJcbi8qKioqKiovIF0pXHJcbn0pO1xyXG47Il0sImZpbGUiOiJhc3NldHNfc2l0ZV9jb3JlX3ZpbGxlL2pzL2xpYi93aGF0LWlucHV0Lm1pbi5qcyJ9
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.