- commit
- 5969d9ccdd5a86e2610eb71b21a9b5cd0ee37bc6
- parent
- 079edb6dd315fa143609fc3bcfba9a87ae68816f
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2018-02-03 13:06
build
Diffstat
| A | babel.js | 12946 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 files changed, 12946 insertions, 0 deletions
diff --git a/babel.js b/babel.js
@@ -0,0 +1,12946 @@
-1 1 (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-1 2 /*!
-1 3 calcNames 1.2, compute the Name and Description property values for a DOM node
-1 4 Returns an object with 'name' and 'desc' properties.
-1 5 Authored by Bryan Garaventa plus contrabutions by Tobias Bengfort
-1 6 Distributed under the terms of the Open Source Initiative OSI - MIT License
-1 7 */
-1 8
-1 9 var calcNames = function(node, fnc, preventVisualARIASelfCSSRef) {
-1 10 if (!node || node.nodeType !== 1) {
-1 11 return;
-1 12 }
-1 13
-1 14 var trim = function(str) {
-1 15 if (typeof str !== 'string') {
-1 16 return '';
-1 17 }
-1 18
-1 19 return str.replace(/^\s+|\s+$/g, '');
-1 20 };
-1 21
-1 22 var walkDOM = function(node, fn, refNode) {
-1 23 if (!node) {
-1 24 return;
-1 25 }
-1 26 fn(node);
-1 27
-1 28 if (!isException(node, refNode)) {
-1 29 node = node.firstChild;
-1 30
-1 31 while (node) {
-1 32 walkDOM(node, fn, refNode);
-1 33 node = node.nextSibling;
-1 34 }
-1 35 }
-1 36 };
-1 37
-1 38 var isFocusable = function(node) {
-1 39 var nodeName = node.nodeName.toLowerCase();
-1 40
-1 41 if (node.getAttribute('tabindex')) {
-1 42 return true;
-1 43 }
-1 44 if (nodeName === 'a' && node.getAttribute('href')) {
-1 45 return true;
-1 46 }
-1 47 if (['input', 'select', 'button'].indexOf(nodeName) !== -1 && node.getAttribute('type') !== 'hidden') {
-1 48 return true;
-1 49 }
-1 50 return false;
-1 51 };
-1 52
-1 53 var isException = function(node, refNode) {
-1 54 if (!refNode || !node || refNode.nodeType !== 1 || node.nodeType !== 1) {
-1 55 return false;
-1 56 }
-1 57
-1 58 var list1 = {
-1 59 roles: ['link', 'button', 'checkbox', 'option', 'radio', 'switch', 'tab', 'treeitem', 'menuitem', 'menuitemcheckbox', 'menuitemradio', 'cell', 'columnheader', 'rowheader', 'tooltip', 'heading'],
-1 60 tags: ['a', 'button', 'summary', 'input', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'menuitem', 'option', 'td', 'th']
-1 61 };
-1 62
-1 63 var list2 = {
-1 64 roles: ['application', 'alert', 'log', 'marquee', 'timer', 'alertdialog', 'dialog', 'banner', 'complementary', 'form', 'main', 'navigation', 'region', 'search', 'article', 'document', 'feed', 'figure', 'img', 'math', 'toolbar', 'menu', 'menubar', 'grid', 'listbox', 'radiogroup', 'textbox', 'searchbox', 'spinbutton', 'scrollbar', 'slider', 'tablist', 'tabpanel', 'tree', 'treegrid', 'separator'],
-1 65 tags: ['article', 'aside', 'body', 'select', 'datalist', 'optgroup', 'dialog', 'figure', 'footer', 'form', 'header', 'hr', 'img', 'textarea', 'input', 'main', 'math', 'menu', 'nav', 'section']
-1 66 };
-1 67
-1 68 var list3 = {
-1 69 roles: ['combobox', 'term', 'definition', 'directory', 'list', 'group', 'note', 'status', 'table', 'rowgroup', 'row', 'contentinfo'],
-1 70 tags: ['dl', 'ul', 'ol', 'dd', 'details', 'output', 'table', 'thead', 'tbody', 'tfoot', 'tr']
-1 71 };
-1 72
-1 73 var inList = function(node, list) {
-1 74 var role = node.getAttribute('role');
-1 75 var tag = node.nodeName.toLowerCase();
-1 76 return (
-1 77 list.roles.indexOf(role) >= 0 ||
-1 78 (!role && list2.tags.indexOf(tag) >= 0)
-1 79 );
-1 80 };
-1 81
-1 82 if (inList(node, list2)) {
-1 83 return true;
-1 84 } else if (inList(node, list3)) {
-1 85 if (node === refNode) {
-1 86 return !isFocusable(node);
-1 87 } else {
-1 88 return !inList(refNode, list1);
-1 89 }
-1 90 } else {
-1 91 return false;
-1 92 }
-1 93 };
-1 94
-1 95 var isHidden = function(node, refNode) {
-1 96 if (node.nodeType !== 1 || node == refNode) {
-1 97 return false;
-1 98 }
-1 99
-1 100 if (node.getAttribute('aria-hidden') === 'true') {
-1 101 return true;
-1 102 }
-1 103
-1 104 var style = {};
-1 105 if (document.defaultView && document.defaultView.getComputedStyle) {
-1 106 style = document.defaultView.getComputedStyle(node, '');
-1 107 } else if (node.currentStyle) {
-1 108 style = node.currentStyle;
-1 109 }
-1 110 if (style['display'] === 'none' || style['visibility'] === 'hidden') {
-1 111 return true;
-1 112 }
-1 113
-1 114 return false;
-1 115 };
-1 116
-1 117 var getCSSText = function(node, refNode) {
-1 118 if (node.nodeType !== 1 || node == refNode || ['input', 'select', 'textarea', 'img', 'iframe'].indexOf(node.nodeName.toLowerCase()) !== -1) {
-1 119 return {before: '', after: ''};
-1 120 }
-1 121
-1 122 var getText = function(node, position) {
-1 123 var text = document.defaultView.getComputedStyle(node, position).getPropertyValue('content').replace(/^\"|\"$/g, '');
-1 124 if (!text || text === 'none') {
-1 125 return '';
-1 126 } else {
-1 127 return text;
-1 128 }
-1 129 };
-1 130
-1 131 if (document.defaultView && document.defaultView.getComputedStyle) {
-1 132 return {
-1 133 before: getText(node, ':before'),
-1 134 after: getText(node, ':after')
-1 135 };
-1 136 } else {
-1 137 return {before: '', after: ''};
-1 138 }
-1 139 };
-1 140
-1 141 var hasParentLabel = function(node, noLabel, refNode) {
-1 142 while (node && node !== refNode) {
-1 143 node = node.parentNode;
-1 144
-1 145 if (node.getAttribute) {
-1 146 if (['presentation', 'none'].indexOf(node.getAttribute('role')) === -1) {
-1 147 if (!noLabel && node.getAttribute('aria-label')) {
-1 148 return true;
-1 149 }
-1 150 if (isHidden(node, refNode)) {
-1 151 return true;
-1 152 }
-1 153 }
-1 154 }
-1 155 }
-1 156
-1 157 return false;
-1 158 };
-1 159
-1 160 var walk = function(refNode, stop, skip) {
-1 161 var fullName = '';
-1 162 var nodes = [];
-1 163 var cssOP = {
-1 164 before: '',
-1 165 after: ''
-1 166 };
-1 167
-1 168 if (nodes.indexOf(refNode) === -1) {
-1 169 nodes.push(refNode);
-1 170 cssOP = getCSSText(refNode, null);
-1 171
-1 172 // Enabled in Visual ARIA to prevent self referencing by Visual ARIA tooltips
-1 173 if (preventVisualARIASelfCSSRef) {
-1 174 if (cssOP.before.indexOf(' [ARIA] ') !== -1 || cssOP.before.indexOf(' aria-') !== -1)
-1 175 cssOP.before = '';
-1 176 if (cssOP.after.indexOf(' [ARIA] ') !== -1 || cssOP.after.indexOf(' aria-') !== -1)
-1 177 cssOP.after = '';
-1 178 }
-1 179 }
-1 180
-1 181 walkDOM(refNode, function(node) {
-1 182 if (skip || !node || (isHidden(node, refNode))) {
-1 183 return;
-1 184 }
-1 185
-1 186 var name = '';
-1 187 var cssO = {
-1 188 before: '',
-1 189 after: ''
-1 190 };
-1 191
-1 192 var parent = refNode === node ? node : node.parentNode;
-1 193 if (nodes.indexOf(parent) === -1) {
-1 194 nodes.push(parent);
-1 195 cssO = getCSSText(parent, refNode);
-1 196
-1 197 // Enabled in Visual ARIA to prevent self referencing by Visual ARIA tooltips
-1 198 if (preventVisualARIASelfCSSRef) {
-1 199 if (cssO.before.indexOf(' [ARIA] ') !== -1 || cssO.before.indexOf(' aria-') !== -1)
-1 200 cssO.before = '';
-1 201 if (cssO.after.indexOf(' [ARIA] ') !== -1 || cssO.after.indexOf(' aria-') !== -1)
-1 202 cssO.after = '';
-1 203 }
-1 204
-1 205 }
-1 206
-1 207 if (node.nodeType === 1) {
-1 208 var aLabelledby = node.getAttribute('aria-labelledby') || '';
-1 209 var aLabel = node.getAttribute('aria-label') || '';
-1 210 var nTitle = node.getAttribute('title') || '';
-1 211 var rolePresentation = ['presentation', 'none'].indexOf(node.getAttribute('role')) !== -1;
-1 212
-1 213 if (!node.firstChild || (node == refNode && (aLabelledby || aLabel)) || (node.firstChild && node != refNode && aLabel)) {
-1 214 if (!stop && node === refNode && aLabelledby) {
-1 215 if (!rolePresentation) {
-1 216 var ids = aLabelledby.split(/\s+/);
-1 217 var parts = [];
-1 218
-1 219 for (var i = 0; i < ids.length; i++) {
-1 220 var element = document.getElementById(ids[i]);
-1 221 parts.push(walk(element, true, skip));
-1 222 }
-1 223 name = parts.join(' ');
-1 224 }
-1 225
-1 226 if (name || rolePresentation) {
-1 227 skip = true;
-1 228 }
-1 229 }
-1 230
-1 231 /*!@ Add values of custom controls here if recursive controls with values */
-1 232
-1 233 if (!name && !rolePresentation && aLabel) {
-1 234 name = aLabel;
-1 235
-1 236 if (name && node === refNode) {
-1 237 skip = true;
-1 238 }
-1 239 }
-1 240
-1 241 if (!name && !rolePresentation && ['input', 'select', 'textarea'].indexOf(node.nodeName.toLowerCase()) !== -1 && node.id && document.querySelectorAll('label[for="' + node.id + '"]').length) {
-1 242 var label = document.querySelector('label[for="' + node.id + '"]');
-1 243 name = walk(label, true, skip);
-1 244 }
-1 245
-1 246 if (!name && !rolePresentation && node.nodeName.toLowerCase() == 'img' && node.getAttribute('alt')) {
-1 247 name = node.getAttribute('alt');
-1 248 }
-1 249
-1 250 if (!name && !rolePresentation && nTitle) {
-1 251 name = nTitle;
-1 252 }
-1 253 }
-1 254 } else if (node.nodeType === 3) {
-1 255 name = node.data;
-1 256 }
-1 257
-1 258 name = cssO.before + name + cssO.after;
-1 259
-1 260 if (name && !hasParentLabel(node, false, refNode)) {
-1 261 fullName += name;
-1 262 }
-1 263 }, refNode);
-1 264
-1 265 fullName = cssOP.before + fullName + cssOP.after;
-1 266 return fullName;
-1 267 };
-1 268
-1 269 if (isHidden(node, document.body) || hasParentLabel(node, true, document.body)) {
-1 270 return;
-1 271 }
-1 272
-1 273 var accName = walk(node, false);
-1 274 var accDesc = '';
-1 275
-1 276 if (['presentation', 'none'].indexOf(node.getAttribute('role')) === -1) {
-1 277 var desc = '';
-1 278
-1 279 var title = node.getAttribute('title') || '';
-1 280 if (title) {
-1 281 if (!accName) {
-1 282 accName = title;
-1 283 } else {
-1 284 accDesc = title;
-1 285 }
-1 286 }
-1 287
-1 288 var describedby = node.getAttribute('aria-describedby') || '';
-1 289 if (describedby) {
-1 290 var ids = describedby.split(/\s+/);
-1 291 var parts = [];
-1 292
-1 293 for (var j = 0; j < ids.length; j++) {
-1 294 var element = document.getElementById(ids[j]);
-1 295 parts.push(walk(element, true));
-1 296 }
-1 297
-1 298 if (parts.length) {
-1 299 accDesc = parts.join(' ');
-1 300 }
-1 301 }
-1 302 }
-1 303
-1 304 accName = trim(accName.replace(/\s+/g, ' '));
-1 305 accDesc = trim(accDesc.replace(/\s+/g, ' '));
-1 306
-1 307 if (accName === accDesc) {
-1 308 accDesc = '';
-1 309 }
-1 310
-1 311 var props = {
-1 312 name: accName,
-1 313 desc: accDesc
-1 314 };
-1 315
-1 316 if (fnc && typeof fnc == 'function') {
-1 317 return fnc.apply(node, [
-1 318 node,
-1 319 props
-1 320 ]);
-1 321 } else {
-1 322 return props;
-1 323 }
-1 324 };
-1 325
-1 326 // Customize returned string
-1 327
-1 328 var getNames = function(node) {
-1 329 var props = calcNames(node);
-1 330 return 'accName: "' + props.name + '"\n\naccDesc: "' + props.desc + '"';
-1 331 };
-1 332
-1 333 if (typeof module === 'object' && module.exports) {
-1 334 module.exports = {
-1 335 getNames: getNames,
-1 336 calcNames: calcNames,
-1 337 };
-1 338 }
-1 339 },{}],2:[function(require,module,exports){
-1 340 (function (global){
-1 341 global.goog = {
-1 342 provide: function() {},
-1 343 require: function() {},
-1 344 };
-1 345 global.axs = {
-1 346 browserUtils: {},
-1 347 color: {},
-1 348 dom: {},
-1 349 utils: {},
-1 350 properties: {},
-1 351 };
-1 352
-1 353 require('accessibility-developer-tools/src/js/AccessibilityUtils');
-1 354 require('accessibility-developer-tools/src/js/BrowserUtils');
-1 355 require('accessibility-developer-tools/src/js/Color');
-1 356 require('accessibility-developer-tools/src/js/DOMUtils');
-1 357 require('accessibility-developer-tools/src/js/Properties');
-1 358
-1 359 module.exports = global.axs;
-1 360
-1 361 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-1 362 },{"accessibility-developer-tools/src/js/AccessibilityUtils":3,"accessibility-developer-tools/src/js/BrowserUtils":4,"accessibility-developer-tools/src/js/Color":5,"accessibility-developer-tools/src/js/DOMUtils":6,"accessibility-developer-tools/src/js/Properties":7}],3:[function(require,module,exports){
-1 363 // Copyright 2012 Google Inc.
-1 364 //
-1 365 // Licensed under the Apache License, Version 2.0 (the "License");
-1 366 // you may not use this file except in compliance with the License.
-1 367 // You may obtain a copy of the License at
-1 368 //
-1 369 // http://www.apache.org/licenses/LICENSE-2.0
-1 370 //
-1 371 // Unless required by applicable law or agreed to in writing, software
-1 372 // distributed under the License is distributed on an "AS IS" BASIS,
-1 373 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-1 374 // See the License for the specific language governing permissions and
-1 375 // limitations under the License.
-1 376
-1 377 goog.require('axs.browserUtils');
-1 378 goog.require('axs.color');
-1 379 goog.require('axs.color.Color');
-1 380 goog.require('axs.constants');
-1 381 goog.require('axs.dom');
-1 382
-1 383 goog.provide('axs.utils');
-1 384
-1 385 /**
-1 386 * @const
-1 387 * @type {string}
-1 388 */
-1 389 axs.utils.FOCUSABLE_ELEMENTS_SELECTOR =
-1 390 'input:not([type=hidden]):not([disabled]),' +
-1 391 'select:not([disabled]),' +
-1 392 'textarea:not([disabled]),' +
-1 393 'button:not([disabled]),' +
-1 394 'a[href],' +
-1 395 'iframe,' +
-1 396 '[tabindex]';
-1 397
-1 398 /**
-1 399 * Elements that can have labels: https://html.spec.whatwg.org/multipage/forms.html#category-label
-1 400 * @const
-1 401 * @type {string}
-1 402 */
-1 403 axs.utils.LABELABLE_ELEMENTS_SELECTOR =
-1 404 'button,' +
-1 405 'input:not([type=hidden]),' +
-1 406 'keygen,' +
-1 407 'meter,' +
-1 408 'output,' +
-1 409 'progress,' +
-1 410 'select,' +
-1 411 'textarea';
-1 412
-1 413
-1 414 /**
-1 415 * @param {Element} element
-1 416 * @return {boolean}
-1 417 */
-1 418 axs.utils.elementIsTransparent = function(element) {
-1 419 return element.style.opacity == '0';
-1 420 };
-1 421
-1 422 /**
-1 423 * @param {Element} element
-1 424 * @return {boolean}
-1 425 */
-1 426 axs.utils.elementHasZeroArea = function(element) {
-1 427 var rect = element.getBoundingClientRect();
-1 428 var width = rect.right - rect.left;
-1 429 var height = rect.top - rect.bottom;
-1 430 if (!width || !height)
-1 431 return true;
-1 432 return false;
-1 433 };
-1 434
-1 435 /**
-1 436 * @param {Element} element
-1 437 * @return {boolean}
-1 438 */
-1 439 axs.utils.elementIsOutsideScrollArea = function(element) {
-1 440 var parent = axs.dom.parentElement(element);
-1 441
-1 442 var defaultView = element.ownerDocument.defaultView;
-1 443 while (parent != defaultView.document.body) {
-1 444 if (axs.utils.isClippedBy(element, parent))
-1 445 return true;
-1 446
-1 447 if (axs.utils.canScrollTo(element, parent) && !axs.utils.elementIsOutsideScrollArea(parent))
-1 448 return false;
-1 449
-1 450 parent = axs.dom.parentElement(parent);
-1 451 }
-1 452
-1 453 return !axs.utils.canScrollTo(element, defaultView.document.body);
-1 454 };
-1 455
-1 456 /**
-1 457 * Checks whether it's possible to scroll to the given element within the given container.
-1 458 * Assumes that |container| is an ancestor of |element|.
-1 459 * If |container| cannot be scrolled, returns True if the element is within its bounding client
-1 460 * rect.
-1 461 * @param {Element} element
-1 462 * @param {Element} container
-1 463 * @return {boolean} True iff it's possible to scroll to |element| within |container|.
-1 464 */
-1 465 axs.utils.canScrollTo = function(element, container) {
-1 466 var rect = element.getBoundingClientRect();
-1 467 var containerRect = container.getBoundingClientRect();
-1 468 if (container == container.ownerDocument.body) {
-1 469 var absoluteTop = containerRect.top;
-1 470 var absoluteLeft = containerRect.left;
-1 471 } else {
-1 472 var absoluteTop = containerRect.top - container.scrollTop;
-1 473 var absoluteLeft = containerRect.left - container.scrollLeft;
-1 474 }
-1 475 var containerScrollArea =
-1 476 { top: absoluteTop,
-1 477 bottom: absoluteTop + container.scrollHeight,
-1 478 left: absoluteLeft,
-1 479 right: absoluteLeft + container.scrollWidth };
-1 480
-1 481 if (rect.right < containerScrollArea.left || rect.bottom < containerScrollArea.top ||
-1 482 rect.left > containerScrollArea.right || rect.top > containerScrollArea.bottom) {
-1 483 return false;
-1 484 }
-1 485
-1 486 var defaultView = element.ownerDocument.defaultView;
-1 487 var style = defaultView.getComputedStyle(container);
-1 488
-1 489 if (rect.left > containerRect.right || rect.top > containerRect.bottom) {
-1 490 return (style.overflow == 'scroll' || style.overflow == 'auto' ||
-1 491 container instanceof defaultView.HTMLBodyElement);
-1 492 }
-1 493
-1 494 return true;
-1 495 };
-1 496
-1 497 /**
-1 498 * Checks whether the given element is clipped by the given container.
-1 499 * Assumes that |container| is an ancestor of |element|.
-1 500 * @param {Element} element
-1 501 * @param {Element} container
-1 502 * @return {boolean} True iff |element| is clipped by |container|.
-1 503 */
-1 504 axs.utils.isClippedBy = function(element, container) {
-1 505 var rect = element.getBoundingClientRect();
-1 506 var containerRect = container.getBoundingClientRect();
-1 507 var containerTop = containerRect.top;
-1 508 var containerLeft = containerRect.left;
-1 509 var containerScrollArea =
-1 510 { top: containerTop - container.scrollTop,
-1 511 bottom: containerTop - container.scrollTop + container.scrollHeight,
-1 512 left: containerLeft - container.scrollLeft,
-1 513 right: containerLeft - container.scrollLeft + container.scrollWidth };
-1 514
-1 515 var defaultView = element.ownerDocument.defaultView;
-1 516 var style = defaultView.getComputedStyle(container);
-1 517
-1 518 if ((rect.right < containerRect.left || rect.bottom < containerRect.top ||
-1 519 rect.left > containerRect.right || rect.top > containerRect.bottom) &&
-1 520 style.overflow == 'hidden') {
-1 521 return true;
-1 522 }
-1 523
-1 524 if (rect.right < containerScrollArea.left || rect.bottom < containerScrollArea.top)
-1 525 return (style.overflow != 'visible');
-1 526
-1 527 return false;
-1 528 };
-1 529
-1 530 /**
-1 531 * @param {Node} ancestor A potential ancestor of |node|.
-1 532 * @param {Node} node
-1 533 * @return {boolean} true if |ancestor| is an ancestor of |node| (including
-1 534 * |ancestor| === |node|).
-1 535 */
-1 536 axs.utils.isAncestor = function(ancestor, node) {
-1 537 if (node == null)
-1 538 return false;
-1 539 if (node === ancestor)
-1 540 return true;
-1 541
-1 542 var parentNode = axs.dom.composedParentNode(node);
-1 543 return axs.utils.isAncestor(ancestor, parentNode);
-1 544 };
-1 545
-1 546 /**
-1 547 * @param {Element} element
-1 548 * @return {Array.<Element>} An array of any non-transparent elements which
-1 549 * overlap the given element.
-1 550 */
-1 551 axs.utils.overlappingElements = function(element) {
-1 552 if (axs.utils.elementHasZeroArea(element))
-1 553 return null;
-1 554
-1 555 var overlappingElements = [];
-1 556 var clientRects = element.getClientRects();
-1 557 for (var i = 0; i < clientRects.length; i++) {
-1 558 var rect = clientRects[i];
-1 559 var center_x = (rect.left + rect.right) / 2;
-1 560 var center_y = (rect.top + rect.bottom) / 2;
-1 561 var elementAtPoint = document.elementFromPoint(center_x, center_y);
-1 562
-1 563 if (elementAtPoint == null || elementAtPoint == element ||
-1 564 axs.utils.isAncestor(elementAtPoint, element) ||
-1 565 axs.utils.isAncestor(element, elementAtPoint)) {
-1 566 continue;
-1 567 }
-1 568
-1 569 var overlappingElementStyle = window.getComputedStyle(elementAtPoint, null);
-1 570 if (!overlappingElementStyle)
-1 571 continue;
-1 572
-1 573 var overlappingElementBg = axs.utils.getBgColor(overlappingElementStyle,
-1 574 elementAtPoint);
-1 575 if (overlappingElementBg && overlappingElementBg.alpha > 0 &&
-1 576 overlappingElements.indexOf(elementAtPoint) < 0) {
-1 577 overlappingElements.push(elementAtPoint);
-1 578 }
-1 579 }
-1 580
-1 581 return overlappingElements;
-1 582 };
-1 583
-1 584 /**
-1 585 * @param {Element} element
-1 586 * @return {boolean}
-1 587 */
-1 588 axs.utils.elementIsHtmlControl = function(element) {
-1 589 var defaultView = element.ownerDocument.defaultView;
-1 590
-1 591 // HTML control
-1 592 if (element instanceof defaultView.HTMLButtonElement)
-1 593 return true;
-1 594 if (element instanceof defaultView.HTMLInputElement)
-1 595 return true;
-1 596 if (element instanceof defaultView.HTMLSelectElement)
-1 597 return true;
-1 598 if (element instanceof defaultView.HTMLTextAreaElement)
-1 599 return true;
-1 600
-1 601 return false;
-1 602 };
-1 603
-1 604 /**
-1 605 * @param {Element} element
-1 606 * @return {boolean}
-1 607 */
-1 608 axs.utils.elementIsAriaWidget = function(element) {
-1 609 if (element.hasAttribute('role')) {
-1 610 var roleValue = element.getAttribute('role');
-1 611 // TODO is this correct?
-1 612 if (roleValue) {
-1 613 var role = axs.constants.ARIA_ROLES[roleValue];
-1 614 if (role && 'widget' in role['allParentRolesSet'])
-1 615 return true;
-1 616 }
-1 617 }
-1 618 return false;
-1 619 };
-1 620
-1 621 /**
-1 622 * @param {Element} element
-1 623 * @return {boolean}
-1 624 */
-1 625 axs.utils.elementIsVisible = function(element) {
-1 626 if (axs.utils.elementIsTransparent(element))
-1 627 return false;
-1 628 if (axs.utils.elementHasZeroArea(element))
-1 629 return false;
-1 630 if (axs.utils.elementIsOutsideScrollArea(element))
-1 631 return false;
-1 632
-1 633 var overlappingElements = axs.utils.overlappingElements(element);
-1 634 if (overlappingElements.length)
-1 635 return false;
-1 636
-1 637 return true;
-1 638 };
-1 639
-1 640 /**
-1 641 * @param {CSSStyleDeclaration} style
-1 642 * @return {boolean}
-1 643 */
-1 644 axs.utils.isLargeFont = function(style) {
-1 645 var fontSize = style.fontSize;
-1 646 var bold = style.fontWeight == 'bold';
-1 647 var matches = fontSize.match(/(\d+)px/);
-1 648 if (matches) {
-1 649 var fontSizePx = parseInt(matches[1], 10);
-1 650 var bodyStyle = window.getComputedStyle(document.body, null);
-1 651 var bodyFontSize = bodyStyle.fontSize;
-1 652 matches = bodyFontSize.match(/(\d+)px/);
-1 653 if (matches) {
-1 654 var bodyFontSizePx = parseInt(matches[1], 10);
-1 655 var boldLarge = bodyFontSizePx * 1.2;
-1 656 var large = bodyFontSizePx * 1.5;
-1 657 } else {
-1 658 var boldLarge = 19.2;
-1 659 var large = 24;
-1 660 }
-1 661 return (bold && fontSizePx >= boldLarge || fontSizePx >= large);
-1 662 }
-1 663 matches = fontSize.match(/(\d+)em/);
-1 664 if (matches) {
-1 665 var fontSizeEm = parseInt(matches[1], 10);
-1 666 if (bold && fontSizeEm >= 1.2 || fontSizeEm >= 1.5)
-1 667 return true;
-1 668 return false;
-1 669 }
-1 670 matches = fontSize.match(/(\d+)%/);
-1 671 if (matches) {
-1 672 var fontSizePercent = parseInt(matches[1], 10);
-1 673 if (bold && fontSizePercent >= 120 || fontSizePercent >= 150)
-1 674 return true;
-1 675 return false;
-1 676 }
-1 677 matches = fontSize.match(/(\d+)pt/);
-1 678 if (matches) {
-1 679 var fontSizePt = parseInt(matches[1], 10);
-1 680 if (bold && fontSizePt >= 14 || fontSizePt >= 18)
-1 681 return true;
-1 682 return false;
-1 683 }
-1 684 return false;
-1 685 };
-1 686
-1 687 /**
-1 688 * @param {CSSStyleDeclaration} style
-1 689 * @param {Element} element
-1 690 * @return {?axs.color.Color}
-1 691 */
-1 692 axs.utils.getBgColor = function(style, element) {
-1 693 var bgColorString = style.backgroundColor;
-1 694 var bgColor = axs.color.parseColor(bgColorString);
-1 695 if (!bgColor)
-1 696 return null;
-1 697
-1 698 if (style.opacity < 1)
-1 699 bgColor.alpha = bgColor.alpha * style.opacity;
-1 700
-1 701 if (bgColor.alpha < 1) {
-1 702 var parentBg = axs.utils.getParentBgColor(element);
-1 703 if (parentBg == null)
-1 704 return null;
-1 705
-1 706 bgColor = axs.color.flattenColors(bgColor, parentBg);
-1 707 }
-1 708 return bgColor;
-1 709 };
-1 710
-1 711 /**
-1 712 * Gets the effective background color of the parent of |element|.
-1 713 * @param {Element} element
-1 714 * @return {?axs.color.Color}
-1 715 */
-1 716 axs.utils.getParentBgColor = function(element) {
-1 717 /** @type {Element} */ var parent = element;
-1 718 var bgStack = [];
-1 719 var foundSolidColor = null;
-1 720 while ((parent = axs.dom.parentElement(parent))) {
-1 721 var computedStyle = window.getComputedStyle(parent, null);
-1 722 if (!computedStyle)
-1 723 continue;
-1 724
-1 725 var parentBg = axs.color.parseColor(computedStyle.backgroundColor);
-1 726 if (!parentBg)
-1 727 continue;
-1 728
-1 729 if (computedStyle.opacity < 1)
-1 730 parentBg.alpha = parentBg.alpha * computedStyle.opacity;
-1 731
-1 732 if (parentBg.alpha == 0)
-1 733 continue;
-1 734
-1 735 bgStack.push(parentBg);
-1 736
-1 737 if (parentBg.alpha == 1) {
-1 738 foundSolidColor = true;
-1 739 break;
-1 740 }
-1 741 }
-1 742
-1 743 if (!foundSolidColor)
-1 744 bgStack.push(new axs.color.Color(255, 255, 255, 1));
-1 745
-1 746 var bg = bgStack.pop();
-1 747 while (bgStack.length) {
-1 748 var fg = bgStack.pop();
-1 749 bg = axs.color.flattenColors(fg, bg);
-1 750 }
-1 751 return bg;
-1 752 };
-1 753
-1 754 /**
-1 755 * @param {CSSStyleDeclaration} style
-1 756 * @param {Element} element
-1 757 * @param {axs.color.Color} bgColor The background color, which may come from
-1 758 * another element (such as a parent element), for flattening into the
-1 759 * foreground color.
-1 760 * @return {?axs.color.Color}
-1 761 */
-1 762 axs.utils.getFgColor = function(style, element, bgColor) {
-1 763 var fgColorString = style.color;
-1 764 var fgColor = axs.color.parseColor(fgColorString);
-1 765 if (!fgColor)
-1 766 return null;
-1 767
-1 768 if (fgColor.alpha < 1)
-1 769 fgColor = axs.color.flattenColors(fgColor, bgColor);
-1 770
-1 771 if (style.opacity < 1) {
-1 772 var parentBg = axs.utils.getParentBgColor(element);
-1 773 fgColor.alpha = fgColor.alpha * style.opacity;
-1 774 fgColor = axs.color.flattenColors(fgColor, parentBg);
-1 775 }
-1 776
-1 777 return fgColor;
-1 778 };
-1 779
-1 780 /**
-1 781 * @param {Element} element
-1 782 * @return {?number}
-1 783 */
-1 784 axs.utils.getContrastRatioForElement = function(element) {
-1 785 var style = window.getComputedStyle(element, null);
-1 786 return axs.utils.getContrastRatioForElementWithComputedStyle(style, element);
-1 787 };
-1 788
-1 789 /**
-1 790 * @param {CSSStyleDeclaration} style
-1 791 * @param {Element} element
-1 792 * @return {?number}
-1 793 */
-1 794 axs.utils.getContrastRatioForElementWithComputedStyle = function(style, element) {
-1 795 if (axs.utils.isElementHidden(element))
-1 796 return null;
-1 797
-1 798 var bgColor = axs.utils.getBgColor(style, element);
-1 799 if (!bgColor)
-1 800 return null;
-1 801
-1 802 var fgColor = axs.utils.getFgColor(style, element, bgColor);
-1 803 if (!fgColor)
-1 804 return null;
-1 805
-1 806 return axs.color.calculateContrastRatio(fgColor, bgColor);
-1 807 };
-1 808
-1 809 /**
-1 810 * @param {Element} element
-1 811 * @return {boolean}
-1 812 */
-1 813 axs.utils.isNativeTextElement = function(element) {
-1 814 var tagName = element.tagName.toLowerCase();
-1 815 var type = element.type ? element.type.toLowerCase() : '';
-1 816 if (tagName == 'textarea')
-1 817 return true;
-1 818 if (tagName != 'input')
-1 819 return false;
-1 820
-1 821 switch (type) {
-1 822 case 'email':
-1 823 case 'number':
-1 824 case 'password':
-1 825 case 'search':
-1 826 case 'text':
-1 827 case 'tel':
-1 828 case 'url':
-1 829 case '':
-1 830 return true;
-1 831 default:
-1 832 return false;
-1 833 }
-1 834 };
-1 835
-1 836 /**
-1 837 * @param {number} contrastRatio
-1 838 * @param {CSSStyleDeclaration} style
-1 839 * @param {boolean=} opt_strict Whether to use AA (false) or AAA (true) level
-1 840 * @return {boolean}
-1 841 */
-1 842 axs.utils.isLowContrast = function(contrastRatio, style, opt_strict) {
-1 843 // Round to nearest 0.1
-1 844 var roundedContrastRatio = (Math.round(contrastRatio * 10) / 10);
-1 845 if (!opt_strict) {
-1 846 return roundedContrastRatio < 3.0 ||
-1 847 (!axs.utils.isLargeFont(style) && roundedContrastRatio < 4.5);
-1 848 } else {
-1 849 return roundedContrastRatio < 4.5 ||
-1 850 (!axs.utils.isLargeFont(style) && roundedContrastRatio < 7.0);
-1 851 }
-1 852 };
-1 853
-1 854 /**
-1 855 * @param {Element} element
-1 856 * @return {boolean}
-1 857 */
-1 858 axs.utils.hasLabel = function(element) {
-1 859 var tagName = element.tagName.toLowerCase();
-1 860 var type = element.type ? element.type.toLowerCase() : '';
-1 861
-1 862 if (element.hasAttribute('aria-label'))
-1 863 return true;
-1 864 if (element.hasAttribute('title'))
-1 865 return true;
-1 866 if (tagName == 'img' && element.hasAttribute('alt'))
-1 867 return true;
-1 868 if (tagName == 'input' && type == 'image' && element.hasAttribute('alt'))
-1 869 return true;
-1 870 if (tagName == 'input' && (type == 'submit' || type == 'reset'))
-1 871 return true;
-1 872
-1 873 // There's a separate audit that makes sure this points to an actual element or elements.
-1 874 if (element.hasAttribute('aria-labelledby'))
-1 875 return true;
-1 876
-1 877 if (element.hasAttribute('id')) {
-1 878 var labelsFor = document.querySelectorAll('label[for="' + element.id + '"]');
-1 879 if (labelsFor.length > 0)
-1 880 return true;
-1 881 }
-1 882
-1 883 var parent = axs.dom.parentElement(element);
-1 884 while (parent) {
-1 885 if (parent.tagName.toLowerCase() == 'label') {
-1 886 var parentLabel = /** HTMLLabelElement */ parent;
-1 887 if (parentLabel.control == element)
-1 888 return true;
-1 889 }
-1 890 parent = axs.dom.parentElement(parent);
-1 891 }
-1 892 return false;
-1 893 };
-1 894
-1 895 /**
-1 896 * Determine if this element natively supports being disabled (i.e. via the `disabled` attribute.
-1 897 * Disabled here means that the element should be considered disabled according to specification.
-1 898 * This element may or may not be effectively disabled in practice as this is dependent on implementation.
-1 899 *
-1 900 * @param {Element} element An element to check.
-1 901 * @return {boolean} true If the element supports being natively disabled.
-1 902 */
-1 903 axs.utils.isNativelyDisableable = function(element) {
-1 904 var tagName = element.tagName.toUpperCase();
-1 905 return (tagName in axs.constants.NATIVELY_DISABLEABLE);
-1 906 };
-1 907
-1 908 /**
-1 909 * Determine if this element is disabled directly or indirectly by a disabled ancestor.
-1 910 * Disabled here means that the element should be considered disabled according to specification.
-1 911 * This element may or may not be effectively disabled in practice as this is dependent on implementation.
-1 912 *
-1 913 * @param {Element} element An element to check.
-1 914 * @param {boolean=} ignoreAncestors If true do not check for disabled ancestors.
-1 915 * @return {boolean} true if the element or one of its ancestors is disabled.
-1 916 */
-1 917 axs.utils.isElementDisabled = function(element, ignoreAncestors) {
-1 918 var selector = ignoreAncestors ? '[aria-disabled=true]' : '[aria-disabled=true], [aria-disabled=true] *';
-1 919 if (axs.browserUtils.matchSelector(element, selector)) {
-1 920 return true;
-1 921 }
-1 922 if (!axs.utils.isNativelyDisableable(element) ||
-1 923 axs.browserUtils.matchSelector(element, 'fieldset>legend:first-of-type *')) {
-1 924 return false;
-1 925 }
-1 926 for (var next = element; next !== null; next = axs.dom.parentElement(next)) {
-1 927 if (next.hasAttribute('disabled')) {
-1 928 return true;
-1 929 }
-1 930 if (ignoreAncestors) {
-1 931 return false;
-1 932 }
-1 933 }
-1 934 return false;
-1 935 };
-1 936
-1 937 /**
-1 938 * @param {Element} element An element to check.
-1 939 * @return {boolean} True if the element is hidden from accessibility.
-1 940 */
-1 941 axs.utils.isElementHidden = function(element) {
-1 942 if (!(element instanceof element.ownerDocument.defaultView.HTMLElement))
-1 943 return false;
-1 944
-1 945 if (element.hasAttribute('chromevoxignoreariahidden'))
-1 946 var chromevoxignoreariahidden = true;
-1 947
-1 948 var style = window.getComputedStyle(element, null);
-1 949 if (style.display == 'none' || style.visibility == 'hidden')
-1 950 return true;
-1 951
-1 952 if (element.hasAttribute('aria-hidden') &&
-1 953 element.getAttribute('aria-hidden').toLowerCase() == 'true') {
-1 954 return !chromevoxignoreariahidden;
-1 955 }
-1 956
-1 957 return false;
-1 958 };
-1 959
-1 960 /**
-1 961 * @param {Element} element An element to check.
-1 962 * @return {boolean} True if the element or one of its ancestors is
-1 963 * hidden from accessibility.
-1 964 */
-1 965 axs.utils.isElementOrAncestorHidden = function(element) {
-1 966 if (axs.utils.isElementHidden(element))
-1 967 return true;
-1 968
-1 969 if (axs.dom.parentElement(element))
-1 970 return axs.utils.isElementOrAncestorHidden(axs.dom.parentElement(element));
-1 971 else
-1 972 return false;
-1 973 };
-1 974
-1 975 /**
-1 976 * @param {Element} element An element to check
-1 977 * @return {boolean} True if the given element is an inline element, false
-1 978 * otherwise.
-1 979 */
-1 980 axs.utils.isInlineElement = function(element) {
-1 981 var tagName = element.tagName.toUpperCase();
-1 982 return axs.constants.InlineElements[tagName];
-1 983 };
-1 984
-1 985 /**
-1 986 *
-1 987 * Gets role details from an element.
-1 988 * @param {Element} element The DOM element whose role we want.
-1 989 * @param {boolean=} implicit if true then implicit semantics will be considered if there is no role attribute.
-1 990 *
-1 991 * @return {Object}
-1 992 */
-1 993 axs.utils.getRoles = function(element, implicit) {
-1 994 if (!element || element.nodeType !== Node.ELEMENT_NODE || (!element.hasAttribute('role') && !implicit))
-1 995 return null;
-1 996 var roleValue = element.getAttribute('role');
-1 997 if (!roleValue && implicit)
-1 998 roleValue = axs.properties.getImplicitRole(element);
-1 999 if (!roleValue) // role='' or implicit role came up empty
-1 1000 return null;
-1 1001 var roleNames = roleValue.split(' ');
-1 1002 var result = { roles: [], valid: false };
-1 1003 for (var i = 0; i < roleNames.length; i++) {
-1 1004 var role = roleNames[i];
-1 1005 var ariaRole = axs.constants.ARIA_ROLES[role];
-1 1006 var roleObject = { 'name': role };
-1 1007 if (ariaRole && !ariaRole.abstract) {
-1 1008 roleObject.details = ariaRole;
-1 1009 if (!result.applied) {
-1 1010 result.applied = roleObject;
-1 1011 }
-1 1012 roleObject.valid = result.valid = true;
-1 1013 } else {
-1 1014 roleObject.valid = false;
-1 1015 }
-1 1016 result.roles.push(roleObject);
-1 1017 }
-1 1018
-1 1019 return result;
-1 1020 };
-1 1021
-1 1022 /**
-1 1023 * @param {!string} propertyName
-1 1024 * @param {!string} value
-1 1025 * @param {!Element} element
-1 1026 * @return {!Object}
-1 1027 */
-1 1028 axs.utils.getAriaPropertyValue = function(propertyName, value, element) {
-1 1029 var propertyKey = propertyName.replace(/^aria-/, '');
-1 1030 var property = axs.constants.ARIA_PROPERTIES[propertyKey];
-1 1031 var result = { 'name': propertyName, 'rawValue': value };
-1 1032 if (!property) {
-1 1033 result.valid = false;
-1 1034 result.reason = '"' + propertyName + '" is not a valid ARIA property';
-1 1035 return result;
-1 1036 }
-1 1037
-1 1038 var propertyType = property.valueType;
-1 1039 if (!propertyType) {
-1 1040 result.valid = false;
-1 1041 result.reason = '"' + propertyName + '" is not a valid ARIA property';
-1 1042 return result;
-1 1043 }
-1 1044
-1 1045 switch (propertyType) {
-1 1046 case "idref":
-1 1047 var isValid = axs.utils.isValidIDRefValue(value, element);
-1 1048 result.valid = isValid.valid;
-1 1049 result.reason = isValid.reason;
-1 1050 result.idref = isValid.idref;
-1 1051 // falls through
-1 1052 case "idref_list":
-1 1053 var idrefValues = value.split(/\s+/);
-1 1054 result.valid = true;
-1 1055 for (var i = 0; i < idrefValues.length; i++) {
-1 1056 var refIsValid = axs.utils.isValidIDRefValue(idrefValues[i], element);
-1 1057 if (!refIsValid.valid)
-1 1058 result.valid = false;
-1 1059 if (result.values)
-1 1060 result.values.push(refIsValid);
-1 1061 else
-1 1062 result.values = [refIsValid];
-1 1063 }
-1 1064 return result;
-1 1065 case "integer":
-1 1066 var validNumber = axs.utils.isValidNumber(value);
-1 1067 if (!validNumber.valid) {
-1 1068 result.valid = false;
-1 1069 result.reason = validNumber.reason;
-1 1070 return result;
-1 1071 }
-1 1072 if (Math.floor(validNumber.value) !== validNumber.value) {
-1 1073 result.valid = false;
-1 1074 result.reason = '' + value + ' is not a whole integer';
-1 1075 } else {
-1 1076 result.valid = true;
-1 1077 result.value = validNumber.value;
-1 1078 }
-1 1079 return result;
-1 1080 case "decimal":
-1 1081 case "number":
-1 1082 var validNumber = axs.utils.isValidNumber(value);
-1 1083 result.valid = validNumber.valid;
-1 1084 if (!validNumber.valid) {
-1 1085 result.reason = validNumber.reason;
-1 1086 return result;
-1 1087 }
-1 1088 result.value = validNumber.value;
-1 1089 return result;
-1 1090 case "string":
-1 1091 result.valid = true;
-1 1092 result.value = value;
-1 1093 return result;
-1 1094 case "token":
-1 1095 var validTokenValue = axs.utils.isValidTokenValue(propertyName, value.toLowerCase());
-1 1096 if (validTokenValue.valid) {
-1 1097 result.valid = true;
-1 1098 result.value = validTokenValue.value;
-1 1099 return result;
-1 1100 } else {
-1 1101 result.valid = false;
-1 1102 result.value = value;
-1 1103 result.reason = validTokenValue.reason;
-1 1104 return result;
-1 1105 }
-1 1106 // falls through
-1 1107 case "token_list":
-1 1108 var tokenValues = value.split(/\s+/);
-1 1109 result.valid = true;
-1 1110 for (var i = 0; i < tokenValues.length; i++) {
-1 1111 var validTokenValue = axs.utils.isValidTokenValue(propertyName, tokenValues[i].toLowerCase());
-1 1112 if (!validTokenValue.valid) {
-1 1113 result.valid = false;
-1 1114 if (result.reason) {
-1 1115 result.reason = [ result.reason ];
-1 1116 result.reason.push(validTokenValue.reason);
-1 1117 } else {
-1 1118 result.reason = validTokenValue.reason;
-1 1119 result.possibleValues = validTokenValue.possibleValues;
-1 1120 }
-1 1121 }
-1 1122 // TODO (more structured result)
-1 1123 if (result.values)
-1 1124 result.values.push(validTokenValue.value);
-1 1125 else
-1 1126 result.values = [validTokenValue.value];
-1 1127 }
-1 1128 return result;
-1 1129 case "tristate":
-1 1130 var validTristate = axs.utils.isPossibleValue(value.toLowerCase(), axs.constants.MIXED_VALUES, propertyName);
-1 1131 if (validTristate.valid) {
-1 1132 result.valid = true;
-1 1133 result.value = validTristate.value;
-1 1134 } else {
-1 1135 result.valid = false;
-1 1136 result.value = value;
-1 1137 result.reason = validTristate.reason;
-1 1138 }
-1 1139 return result;
-1 1140 case "boolean":
-1 1141 var validBoolean = axs.utils.isValidBoolean(value);
-1 1142 if (validBoolean.valid) {
-1 1143 result.valid = true;
-1 1144 result.value = validBoolean.value;
-1 1145 } else {
-1 1146 result.valid = false;
-1 1147 result.value = value;
-1 1148 result.reason = validBoolean.reason;
-1 1149 }
-1 1150 return result;
-1 1151 }
-1 1152 result.valid = false;
-1 1153 result.reason = 'Not a valid ARIA property';
-1 1154 return result;
-1 1155 };
-1 1156
-1 1157 /**
-1 1158 * @param {string} propertyName The name of the property.
-1 1159 * @param {string} value The value to check.
-1 1160 * @return {!Object}
-1 1161 */
-1 1162 axs.utils.isValidTokenValue = function(propertyName, value) {
-1 1163 var propertyKey = propertyName.replace(/^aria-/, '');
-1 1164 var propertyDetails = axs.constants.ARIA_PROPERTIES[propertyKey];
-1 1165 var possibleValues = propertyDetails.valuesSet;
-1 1166 return axs.utils.isPossibleValue(value, possibleValues, propertyName);
-1 1167 };
-1 1168
-1 1169 /**
-1 1170 * @param {string} value
-1 1171 * @param {Object.<string, boolean>} possibleValues
-1 1172 * @param {string} propertyName The name of the property.
-1 1173 * @return {!Object}
-1 1174 */
-1 1175 axs.utils.isPossibleValue = function(value, possibleValues, propertyName) {
-1 1176 if (!possibleValues[value])
-1 1177 return { 'valid': false,
-1 1178 'value': value,
-1 1179 'reason': '"' + value + '" is not a valid value for ' + propertyName,
-1 1180 'possibleValues': Object.keys(possibleValues) };
-1 1181 return { 'valid': true, 'value': value };
-1 1182 };
-1 1183
-1 1184 /**
-1 1185 * @param {string} value
-1 1186 * @return {!Object}
-1 1187 */
-1 1188 axs.utils.isValidBoolean = function(value) {
-1 1189 try {
-1 1190 var parsedValue = JSON.parse(value);
-1 1191 } catch (e) {
-1 1192 parsedValue = '';
-1 1193 }
-1 1194 if (typeof(parsedValue) != 'boolean')
-1 1195 return { 'valid': false,
-1 1196 'value': value,
-1 1197 'reason': '"' + value + '" is not a true/false value' };
-1 1198 return { 'valid': true, 'value': parsedValue };
-1 1199 };
-1 1200
-1 1201 /**
-1 1202 * @param {string} value
-1 1203 * @param {!Element} element
-1 1204 * @return {!Object}
-1 1205 */
-1 1206 axs.utils.isValidIDRefValue = function(value, element) {
-1 1207 if (value.length == 0)
-1 1208 return { 'valid': true, 'idref': value };
-1 1209 if (!element.ownerDocument.getElementById(value))
-1 1210 return { 'valid': false,
-1 1211 'idref': value,
-1 1212 'reason': 'No element with ID "' + value + '"' };
-1 1213 return { 'valid': true, 'idref': value };
-1 1214 };
-1 1215
-1 1216 /**
-1 1217 * Tests if a number is real number for a11y purposes.
-1 1218 * Must be a real, numerical, decimal value; heavily inspired by
-1 1219 * http://www.w3.org/TR/wai-aria/states_and_properties#valuetype_number
-1 1220 * @param {string} value
-1 1221 * @return {!Object}
-1 1222 */
-1 1223 axs.utils.isValidNumber = function(value) {
-1 1224 var failResult = {
-1 1225 'valid': false,
-1 1226 'value': value,
-1 1227 'reason': '"' + value + '" is not a number'
-1 1228 };
-1 1229 if (!value) {
-1 1230 return failResult;
-1 1231 }
-1 1232 if (/^0x/i.test(value)) {
-1 1233 failResult.reason = '"' + value + '" is not a decimal number'; // hex is not accepted
-1 1234 return failResult;
-1 1235 }
-1 1236 var parsedValue = value * 1;
-1 1237 if (!isFinite(parsedValue)) {
-1 1238 return failResult;
-1 1239 }
-1 1240 return { 'valid': true, 'value': parsedValue };
-1 1241 };
-1 1242
-1 1243 /**
-1 1244 * @param {Element} element
-1 1245 * @return {boolean}
-1 1246 */
-1 1247 axs.utils.isElementImplicitlyFocusable = function(element) {
-1 1248 var defaultView = element.ownerDocument.defaultView;
-1 1249
-1 1250 if (element instanceof defaultView.HTMLAnchorElement ||
-1 1251 element instanceof defaultView.HTMLAreaElement)
-1 1252 return element.hasAttribute('href');
-1 1253 if (element instanceof defaultView.HTMLInputElement ||
-1 1254 element instanceof defaultView.HTMLSelectElement ||
-1 1255 element instanceof defaultView.HTMLTextAreaElement ||
-1 1256 element instanceof defaultView.HTMLButtonElement ||
-1 1257 element instanceof defaultView.HTMLIFrameElement)
-1 1258 return !element.disabled;
-1 1259 return false;
-1 1260 };
-1 1261
-1 1262 /**
-1 1263 * Returns an array containing the values of the given JSON-compatible object.
-1 1264 * (Simply ignores any function values.)
-1 1265 * @param {Object} obj
-1 1266 * @return {Array}
-1 1267 */
-1 1268 axs.utils.values = function(obj) {
-1 1269 var values = [];
-1 1270 for (var key in obj) {
-1 1271 if (obj.hasOwnProperty(key) && typeof obj[key] != 'function')
-1 1272 values.push(obj[key]);
-1 1273 }
-1 1274 return values;
-1 1275 };
-1 1276
-1 1277 /**
-1 1278 * Returns an object containing the same keys and values as the given
-1 1279 * JSON-compatible object. (Simply ignores any function values.)
-1 1280 * @param {Object} obj
-1 1281 * @return {Object}
-1 1282 */
-1 1283 axs.utils.namedValues = function(obj) {
-1 1284 var values = {};
-1 1285 for (var key in obj) {
-1 1286 if (obj.hasOwnProperty(key) && typeof obj[key] != 'function')
-1 1287 values[key] = obj[key];
-1 1288 }
-1 1289 return values;
-1 1290 };
-1 1291
-1 1292 /**
-1 1293 * Escapes a given ID to be used in a CSS selector
-1 1294 *
-1 1295 * @private
-1 1296 * @param {!string} id The ID to be escaped
-1 1297 * @return {string} The escaped ID
-1 1298 */
-1 1299 function escapeId(id) {
-1 1300 return id.replace(/[^a-zA-Z0-9_-]/g,function(match) { return '\\' + match; });
-1 1301 }
-1 1302
-1 1303 /** Gets a CSS selector text for a DOM object.
-1 1304 * @param {Node} obj The DOM object.
-1 1305 * @return {string} CSS selector text for the DOM object.
-1 1306 */
-1 1307 axs.utils.getQuerySelectorText = function(obj) {
-1 1308 if (obj == null || obj.tagName == 'HTML') {
-1 1309 return 'html';
-1 1310 } else if (obj.tagName == 'BODY') {
-1 1311 return 'body';
-1 1312 }
-1 1313
-1 1314 if (obj.hasAttribute) {
-1 1315 if (obj.id) {
-1 1316 return '#' + escapeId(obj.id);
-1 1317 }
-1 1318
-1 1319 if (obj.className) {
-1 1320 var selector = '';
-1 1321 for (var i = 0; i < obj.classList.length; i++)
-1 1322 selector += '.' + obj.classList[i];
-1 1323
-1 1324 var total = 0;
-1 1325 if (obj.parentNode) {
-1 1326 for (i = 0; i < obj.parentNode.children.length; i++) {
-1 1327 var similar = obj.parentNode.children[i];
-1 1328 if (axs.browserUtils.matchSelector(similar, selector))
-1 1329 total++;
-1 1330 if (similar === obj)
-1 1331 break;
-1 1332 }
-1 1333 } else {
-1 1334 total = 1;
-1 1335 }
-1 1336
-1 1337 if (total == 1) {
-1 1338 return axs.utils.getQuerySelectorText(obj.parentNode) +
-1 1339 ' > ' + selector;
-1 1340 }
-1 1341 }
-1 1342
-1 1343 if (obj.parentNode) {
-1 1344 var similarTags = obj.parentNode.children;
-1 1345 var total = 1;
-1 1346 var i = 0;
-1 1347 while (similarTags[i] !== obj) {
-1 1348 if (similarTags[i].tagName == obj.tagName) {
-1 1349 total++;
-1 1350 }
-1 1351 i++;
-1 1352 }
-1 1353
-1 1354 var next = '';
-1 1355 if (obj.parentNode.tagName != 'BODY') {
-1 1356 next = axs.utils.getQuerySelectorText(obj.parentNode) +
-1 1357 ' > ';
-1 1358 }
-1 1359
-1 1360 if (total == 1) {
-1 1361 return next +
-1 1362 obj.tagName;
-1 1363 } else {
-1 1364 return next +
-1 1365 obj.tagName +
-1 1366 ':nth-of-type(' + total + ')';
-1 1367 }
-1 1368 }
-1 1369
-1 1370 } else if (obj.selectorText) {
-1 1371 return obj.selectorText;
-1 1372 }
-1 1373
-1 1374 return '';
-1 1375 };
-1 1376
-1 1377 /**
-1 1378 * Gets elements that refer to this element in an ARIA attribute that takes an ID reference list or
-1 1379 * single ID reference.
-1 1380 * @param {Element} element a potential referent.
-1 1381 * @param {string=} opt_attributeName Name of an ARIA attribute to limit the results to, e.g. 'aria-owns'.
-1 1382 * @return {NodeList} The elements that refer to this element or null.
-1 1383 */
-1 1384 axs.utils.getAriaIdReferrers = function(element, opt_attributeName) {
-1 1385 var propertyToSelector = function(propertyKey) {
-1 1386 var propertyDetails = axs.constants.ARIA_PROPERTIES[propertyKey];
-1 1387 if (propertyDetails) {
-1 1388 if (propertyDetails.valueType === ('idref')) {
-1 1389 return '[aria-' + propertyKey + '=\'' + id + '\']';
-1 1390 } else if (propertyDetails.valueType === ('idref_list')) {
-1 1391 return '[aria-' + propertyKey + '~=\'' + id + '\']';
-1 1392 }
-1 1393 }
-1 1394 return '';
-1 1395 };
-1 1396 if (!element)
-1 1397 return null;
-1 1398 var id = element.id;
-1 1399 if (!id)
-1 1400 return null;
-1 1401 id = id.replace(/'/g, "\\'"); // make it safe to use in a selector
-1 1402
-1 1403 if (opt_attributeName) {
-1 1404 var propertyKey = opt_attributeName.replace(/^aria-/, '');
-1 1405 var referrerQuery = propertyToSelector(propertyKey);
-1 1406 if (referrerQuery) {
-1 1407 return element.ownerDocument.querySelectorAll(referrerQuery);
-1 1408 }
-1 1409 } else {
-1 1410 var selectors = [];
-1 1411 for (var propertyKey in axs.constants.ARIA_PROPERTIES) {
-1 1412 var referrerQuery = propertyToSelector(propertyKey);
-1 1413 if (referrerQuery) {
-1 1414 selectors.push(referrerQuery);
-1 1415 }
-1 1416 }
-1 1417 return element.ownerDocument.querySelectorAll(selectors.join(','));
-1 1418 }
-1 1419 return null;
-1 1420 };
-1 1421
-1 1422 /**
-1 1423 * Gets elements that refer to this element in an HTML attribute that takes an ID reference list or
-1 1424 * single ID reference.
-1 1425 * @param {Element} element a potential referent.
-1 1426 * @return {NodeList} The elements that refer to this element.
-1 1427 */
-1 1428 axs.utils.getHtmlIdReferrers = function(element) {
-1 1429 if (!element)
-1 1430 return null;
-1 1431 var id = element.id;
-1 1432 if (!id)
-1 1433 return null;
-1 1434 id = id.replace(/'/g, "\\'"); // make it safe to use in a selector
-1 1435 var selectorTemplates = [
-1 1436 '[contextmenu=\'{id}\']',
-1 1437 '[itemref~=\'{id}\']',
-1 1438 'button[form=\'{id}\']',
-1 1439 'button[menu=\'{id}\']',
-1 1440 'fieldset[form=\'{id}\']',
-1 1441 'input[form=\'{id}\']',
-1 1442 'input[list=\'{id}\']',
-1 1443 'keygen[form=\'{id}\']',
-1 1444 'label[for=\'{id}\']',
-1 1445 'label[form=\'{id}\']',
-1 1446 'menuitem[command=\'{id}\']',
-1 1447 'object[form=\'{id}\']',
-1 1448 'output[for~=\'{id}\']',
-1 1449 'output[form=\'{id}\']',
-1 1450 'select[form=\'{id}\']',
-1 1451 'td[headers~=\'{id}\']',
-1 1452 'textarea[form=\'{id}\']',
-1 1453 'tr[headers~=\'{id}\']'];
-1 1454 var selectors = selectorTemplates.map(function(selector) {
-1 1455 return selector.replace('\{id\}', id);
-1 1456 });
-1 1457 return element.ownerDocument.querySelectorAll(selectors.join(','));
-1 1458 };
-1 1459
-1 1460 /**
-1 1461 * Gets a list of all IDs this element references in either ARIA or HTML attributes.
-1 1462 *
-1 1463 * @param {Element} element The element to check for idref attributes.
-1 1464 * @returns {Array.<string>} Any IDs this element references.
-1 1465 */
-1 1466 axs.utils.getReferencedIds = function(element) {
-1 1467 var result = [];
-1 1468 var addResult = function(ids) {
-1 1469 if (ids) {
-1 1470 if (ids.indexOf(' ') > 0) {
-1 1471 result = result.concat(attrib.value.split(' '));
-1 1472 } else {
-1 1473 result.push(ids);
-1 1474 }
-1 1475 }
-1 1476 };
-1 1477 for (var i = 0; i < element.attributes.length; i++) {
-1 1478 var tagName = element.tagName.toLowerCase();
-1 1479 var attrib = element.attributes[i];
-1 1480 if (attrib.specified) {
-1 1481 var attribName = attrib.name;
-1 1482 var ariaAttr = attribName.match(/aria-(.+)/);
-1 1483 if (ariaAttr) {
-1 1484 var details = axs.constants.ARIA_PROPERTIES[ariaAttr[1]];
-1 1485 if (details && (details.valueType === ('idref') || details.valueType === ('idref_list'))) {
-1 1486 addResult(attrib.value);
-1 1487 }
-1 1488 continue;
-1 1489 }
-1 1490 switch (attribName) {
-1 1491 case 'contextmenu':
-1 1492 case 'itemref':
-1 1493 addResult(attrib.value);
-1 1494 break;
-1 1495 case 'form':
-1 1496 if (tagName == 'button' || tagName == 'fieldset' || tagName == 'input' ||
-1 1497 tagName == 'keygen' || tagName == 'label' || tagName == 'object' ||
-1 1498 tagName == 'output' || tagName == 'select' || tagName == 'textarea') {
-1 1499 addResult(attrib.value);
-1 1500 }
-1 1501 break;
-1 1502 case 'for':
-1 1503 if (tagName == 'label' || tagName == 'output') {
-1 1504 addResult(attrib.value);
-1 1505 }
-1 1506 break;
-1 1507 case 'menu':
-1 1508 if (tagName == 'button') {
-1 1509 addResult(attrib.value);
-1 1510 }
-1 1511 break;
-1 1512 case 'list':
-1 1513 if (tagName == 'input') {
-1 1514 addResult(attrib.value);
-1 1515 }
-1 1516 break;
-1 1517 case 'command':
-1 1518 if (tagName == 'menuitem') {
-1 1519 addResult(attrib.value);
-1 1520 }
-1 1521 break;
-1 1522 case 'headers':
-1 1523 if (tagName == 'td' || tagName == 'tr') {
-1 1524 addResult(attrib.value);
-1 1525 }
-1 1526 break;
-1 1527 }
-1 1528 }
-1 1529 }
-1 1530 return result;
-1 1531 };
-1 1532
-1 1533 /**
-1 1534 * Gets elements that refer to this element in an attribute that takes an ID reference list or
-1 1535 * single ID reference.
-1 1536 * @param {Element} element a potential referent.
-1 1537 * @return {Array<Element>} The elements that refer to this element.
-1 1538 */
-1 1539 axs.utils.getIdReferrers = function(element) {
-1 1540 var result = [];
-1 1541 var referrers = axs.utils.getHtmlIdReferrers(element);
-1 1542 if (referrers) {
-1 1543 result = result.concat(Array.prototype.slice.call(referrers));
-1 1544 }
-1 1545 referrers = axs.utils.getAriaIdReferrers(element);
-1 1546 if (referrers) {
-1 1547 result = result.concat(Array.prototype.slice.call(referrers));
-1 1548 }
-1 1549 return result;
-1 1550 };
-1 1551
-1 1552 /**
-1 1553 * Gets elements which this element refers to in the given attribute.
-1 1554 * @param {!string} attributeName Name of an ARIA attribute, e.g. 'aria-owns'.
-1 1555 * @param {Element} element The DOM element which has the ARIA attribute.
-1 1556 * @return {!Array.<Element>} An array of elements that are referred to by this element.
-1 1557 * @example
-1 1558 * var owner = document.body.appendChild(document.createElement("div"));
-1 1559 * var owned = document.body.appendChild(document.createElement("div"));
-1 1560 * owner.setAttribute("aria-owns", "kungfu");
-1 1561 * owned.setAttribute("id", "kungfu");
-1 1562 * console.log(axs.utils.getIdReferents("aria-owns", owner)[0] === owned); // This will log 'true'
-1 1563 */
-1 1564 axs.utils.getIdReferents = function(attributeName, element) {
-1 1565 var result = [];
-1 1566 var propertyKey = attributeName.replace(/^aria-/, '');
-1 1567 var property = axs.constants.ARIA_PROPERTIES[propertyKey];
-1 1568 if (!property || !element.hasAttribute(attributeName))
-1 1569 return result;
-1 1570 var propertyType = property.valueType;
-1 1571 if (propertyType === 'idref_list' || propertyType === 'idref') {
-1 1572 var ownerDocument = element.ownerDocument;
-1 1573 var ids = element.getAttribute(attributeName);
-1 1574 ids = ids.split(/\s+/);
-1 1575 for (var i = 0, len = ids.length; i < len; i++) {
-1 1576 var next = ownerDocument.getElementById(ids[i]);
-1 1577 if (next) {
-1 1578 result[result.length] = next;
-1 1579 }
-1 1580 }
-1 1581 }
-1 1582 return result;
-1 1583 };
-1 1584
-1 1585 /**
-1 1586 * Gets a subset of 'axs.constants.ARIA_PROPERTIES' filtered by 'valueType'.
-1 1587 * @param {!Array.<string>} valueTypes Types to match, e.g. ['idref_list'].
-1 1588 * @return {Object.<string, Object>} axs.constants.ARIA_PROPERTIES which match.
-1 1589 */
-1 1590 axs.utils.getAriaPropertiesByValueType = function(valueTypes) {
-1 1591 var result = {};
-1 1592 for (var propertyName in axs.constants.ARIA_PROPERTIES) {
-1 1593 var property = axs.constants.ARIA_PROPERTIES[propertyName];
-1 1594 if (property && valueTypes.indexOf(property.valueType) >= 0) {
-1 1595 result[propertyName] = property;
-1 1596 }
-1 1597 }
-1 1598 return result;
-1 1599 };
-1 1600
-1 1601 /**
-1 1602 * Builds a selector that matches an element with any of these ARIA properties.
-1 1603 * @param {Object.<string, Object>} ariaProperties axs.constants.ARIA_PROPERTIES
-1 1604 * @return {!string} The selector.
-1 1605 */
-1 1606 axs.utils.getSelectorForAriaProperties = function(ariaProperties) {
-1 1607 var propertyNames = Object.keys(/** @type {!Object} */(ariaProperties));
-1 1608 var result = propertyNames.map(function(propertyName) {
-1 1609 return '[aria-' + propertyName + ']';
-1 1610 });
-1 1611 result.sort(); // facilitates reading long selectors and unit testing
-1 1612 return result.join(',');
-1 1613 };
-1 1614
-1 1615 /**
-1 1616 * Finds descendants of this element which implement the given ARIA role.
-1 1617 * Will look for descendants with implicit or explicit role.
-1 1618 * @param {Element} element an HTML DOM element.
-1 1619 * @param {string} role The role you seek.
-1 1620 * @return {!Array.<Element>} An array of matching elements.
-1 1621 * @example
-1 1622 * var container = document.createElement("div");
-1 1623 * var button = document.createElement("button");
-1 1624 * var span = document.createElement("span");
-1 1625 * span.setAttribute("role", "button");
-1 1626 * container.appendChild(button);
-1 1627 * container.appendChild(span);
-1 1628 * var result = axs.utils.findDescendantsWithRole(container, "button"); // result is an array containing both 'button' and 'span'
-1 1629 */
-1 1630 axs.utils.findDescendantsWithRole = function(element, role) {
-1 1631 if (!(element && role))
-1 1632 return [];
-1 1633 var selector = axs.properties.getSelectorForRole(role);
-1 1634 if (!selector)
-1 1635 return [];
-1 1636 var result = element.querySelectorAll(selector);
-1 1637 if (result) { // Convert NodeList to Array; methinks 80/20 that's what callers want.
-1 1638 result = Array.prototype.map.call(result, function(item) { return item; });
-1 1639 } else {
-1 1640 return [];
-1 1641 }
-1 1642 return result;
-1 1643 };
-1 1644
-1 1645 },{}],4:[function(require,module,exports){
-1 1646 // Copyright 2013 Google Inc.
-1 1647 //
-1 1648 // Licensed under the Apache License, Version 2.0 (the "License");
-1 1649 // you may not use this file except in compliance with the License.
-1 1650 // You may obtain a copy of the License at
-1 1651 //
-1 1652 // http://www.apache.org/licenses/LICENSE-2.0
-1 1653 //
-1 1654 // Unless required by applicable law or agreed to in writing, software
-1 1655 // distributed under the License is distributed on an "AS IS" BASIS,
-1 1656 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-1 1657 // See the License for the specific language governing permissions and
-1 1658 // limitations under the License.
-1 1659
-1 1660 goog.provide('axs.browserUtils');
-1 1661
-1 1662 /**
-1 1663 * Use Webkit matcher when matches() is not supported.
-1 1664 * Use Firefox matcher when Webkit is not supported.
-1 1665 * Use IE matcher when neither webkit nor Firefox supported.
-1 1666 * @param {Element} element
-1 1667 * @param {string} selector
-1 1668 * @return {boolean} true if the element matches the selector
-1 1669 */
-1 1670 axs.browserUtils.matchSelector = function(element, selector) {
-1 1671 if (element.matches)
-1 1672 return element.matches(selector);
-1 1673 if (element.webkitMatchesSelector)
-1 1674 return element.webkitMatchesSelector(selector);
-1 1675 if (element.mozMatchesSelector)
-1 1676 return element.mozMatchesSelector(selector);
-1 1677 if (element.msMatchesSelector)
-1 1678 return element.msMatchesSelector(selector);
-1 1679 return false;
-1 1680 };
-1 1681
-1 1682 },{}],5:[function(require,module,exports){
-1 1683 // Copyright 2015 Google Inc.
-1 1684 //
-1 1685 // Licensed under the Apache License, Version 2.0 (the "License");
-1 1686 // you may not use this file except in compliance with the License.
-1 1687 // You may obtain a copy of the License at
-1 1688 //
-1 1689 // http://www.apache.org/licenses/LICENSE-2.0
-1 1690 //
-1 1691 // Unless required by applicable law or agreed to in writing, software
-1 1692 // distributed under the License is distributed on an "AS IS" BASIS,
-1 1693 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-1 1694 // See the License for the specific language governing permissions and
-1 1695 // limitations under the License.
-1 1696
-1 1697 goog.provide('axs.color');
-1 1698 goog.provide('axs.color.Color');
-1 1699
-1 1700 /**
-1 1701 * @constructor
-1 1702 * @param {number} red
-1 1703 * @param {number} green
-1 1704 * @param {number} blue
-1 1705 * @param {number} alpha
-1 1706 */
-1 1707 axs.color.Color = function(red, green, blue, alpha) {
-1 1708 /** @type {number} */
-1 1709 this.red = red;
-1 1710
-1 1711 /** @type {number} */
-1 1712 this.green = green;
-1 1713
-1 1714 /** @type {number} */
-1 1715 this.blue = blue;
-1 1716
-1 1717 /** @type {number} */
-1 1718 this.alpha = alpha;
-1 1719 };
-1 1720
-1 1721 /**
-1 1722 * @constructor
-1 1723 * See https://en.wikipedia.org/wiki/YCbCr for more information.
-1 1724 * @param {Array.<number>} coords The YCbCr values as a 3 element array, in the order [luma, Cb, Cr].
-1 1725 * All numbers are in the range [0, 1].
-1 1726 */
-1 1727 axs.color.YCbCr = function(coords) {
-1 1728 /** @type {number} */
-1 1729 this.luma = this.z = coords[0];
-1 1730
-1 1731 /** @type {number} */
-1 1732 this.Cb = this.x = coords[1];
-1 1733
-1 1734 /** @type {number} */
-1 1735 this.Cr = this.y = coords[2];
-1 1736 };
-1 1737
-1 1738 axs.color.YCbCr.prototype = {
-1 1739 /**
-1 1740 * @param {number} scalar
-1 1741 * @return {axs.color.YCbCr} This color multiplied by the given scalar
-1 1742 */
-1 1743 multiply: function(scalar) {
-1 1744 var result = [ this.luma * scalar, this.Cb * scalar, this.Cr * scalar ];
-1 1745 return new axs.color.YCbCr(result);
-1 1746 },
-1 1747
-1 1748 /**
-1 1749 * @param {axs.color.YCbCr} other
-1 1750 * @return {axs.color.YCbCr} This plus other
-1 1751 */
-1 1752 add: function(other) {
-1 1753 var result = [ this.luma + other.luma, this.Cb + other.Cb, this.Cr + other.Cr ];
-1 1754 return new axs.color.YCbCr(result);
-1 1755 },
-1 1756
-1 1757 /**
-1 1758 * @param {axs.color.YCbCr} other
-1 1759 * @return {axs.color.YCbCr} This minus other
-1 1760 */
-1 1761 subtract: function(other) {
-1 1762 var result = [ this.luma - other.luma, this.Cb - other.Cb, this.Cr - other.Cr ];
-1 1763 return new axs.color.YCbCr(result);
-1 1764 }
-1 1765
-1 1766 };
-1 1767
-1 1768
-1 1769 /**
-1 1770 * Calculate the contrast ratio between the two given colors. Returns the ratio
-1 1771 * to 1, for example for two two colors with a contrast ratio of 21:1, this
-1 1772 * function will return 21.
-1 1773 * @param {axs.color.Color} fgColor
-1 1774 * @param {axs.color.Color} bgColor
-1 1775 * @return {!number}
-1 1776 */
-1 1777 axs.color.calculateContrastRatio = function(fgColor, bgColor) {
-1 1778 if (fgColor.alpha < 1)
-1 1779 fgColor = axs.color.flattenColors(fgColor, bgColor);
-1 1780
-1 1781 var fgLuminance = axs.color.calculateLuminance(fgColor);
-1 1782 var bgLuminance = axs.color.calculateLuminance(bgColor);
-1 1783 var contrastRatio = (Math.max(fgLuminance, bgLuminance) + 0.05) /
-1 1784 (Math.min(fgLuminance, bgLuminance) + 0.05);
-1 1785 return contrastRatio;
-1 1786 };
-1 1787
-1 1788 /**
-1 1789 * Calculate the luminance of the given color using the WCAG algorithm.
-1 1790 * @param {axs.color.Color} color
-1 1791 * @return {number}
-1 1792 */
-1 1793 axs.color.calculateLuminance = function(color) {
-1 1794 /* var rSRGB = color.red / 255;
-1 1795 var gSRGB = color.green / 255;
-1 1796 var bSRGB = color.blue / 255;
-1 1797
-1 1798 var r = rSRGB <= 0.03928 ? rSRGB / 12.92 : Math.pow(((rSRGB + 0.055)/1.055), 2.4);
-1 1799 var g = gSRGB <= 0.03928 ? gSRGB / 12.92 : Math.pow(((gSRGB + 0.055)/1.055), 2.4);
-1 1800 var b = bSRGB <= 0.03928 ? bSRGB / 12.92 : Math.pow(((bSRGB + 0.055)/1.055), 2.4);
-1 1801
-1 1802 return 0.2126 * r + 0.7152 * g + 0.0722 * b; */
-1 1803 var ycc = axs.color.toYCbCr(color);
-1 1804 return ycc.luma;
-1 1805 };
-1 1806
-1 1807 /**
-1 1808 * Compute the luminance ratio between two luminance values.
-1 1809 * @param {number} luminance1
-1 1810 * @param {number} luminance2
-1 1811 */
-1 1812 axs.color.luminanceRatio = function(luminance1, luminance2) {
-1 1813 return (Math.max(luminance1, luminance2) + 0.05) /
-1 1814 (Math.min(luminance1, luminance2) + 0.05);
-1 1815 };
-1 1816
-1 1817 /**
-1 1818 * @param {string} colorString The color string from CSS.
-1 1819 * @return {?axs.color.Color}
-1 1820 */
-1 1821 axs.color.parseColor = function(colorString) {
-1 1822 if (colorString === "transparent") {
-1 1823 return new axs.color.Color(0, 0, 0, 0);
-1 1824 }
-1 1825 var rgbRegex = /^rgb\((\d+), (\d+), (\d+)\)$/;
-1 1826 var match = colorString.match(rgbRegex);
-1 1827
-1 1828 if (match) {
-1 1829 var r = parseInt(match[1], 10);
-1 1830 var g = parseInt(match[2], 10);
-1 1831 var b = parseInt(match[3], 10);
-1 1832 var a = 1;
-1 1833 return new axs.color.Color(r, g, b, a);
-1 1834 }
-1 1835
-1 1836 var rgbaRegex = /^rgba\((\d+), (\d+), (\d+), (\d*(\.\d+)?)\)/;
-1 1837 match = colorString.match(rgbaRegex);
-1 1838 if (match) {
-1 1839 var r = parseInt(match[1], 10);
-1 1840 var g = parseInt(match[2], 10);
-1 1841 var b = parseInt(match[3], 10);
-1 1842 var a = parseFloat(match[4]);
-1 1843 return new axs.color.Color(r, g, b, a);
-1 1844 }
-1 1845
-1 1846 return null;
-1 1847 };
-1 1848
-1 1849 /**
-1 1850 * @param {number} value The value of a color channel, 0 <= value <= 0xFF
-1 1851 * @return {!string}
-1 1852 */
-1 1853 axs.color.colorChannelToString = function(value) {
-1 1854 value = Math.round(value);
-1 1855 if (value <= 0xF)
-1 1856 return '0' + value.toString(16);
-1 1857 return value.toString(16);
-1 1858 };
-1 1859
-1 1860 /**
-1 1861 * @param {axs.color.Color} color
-1 1862 * @return {!string}
-1 1863 */
-1 1864 axs.color.colorToString = function(color) {
-1 1865 if (color.alpha == 1) {
-1 1866 return '#' + axs.color.colorChannelToString(color.red) +
-1 1867 axs.color.colorChannelToString(color.green) + axs.color.colorChannelToString(color.blue);
-1 1868 }
-1 1869 else
-1 1870 return 'rgba(' + [color.red, color.green, color.blue, color.alpha].join(',') + ')';
-1 1871 };
-1 1872
-1 1873 /**
-1 1874 * Compute a desired luminance given a given luminance and a desired contrast ratio.
-1 1875 * @param {number} luminance The given luminance.
-1 1876 * @param {number} contrast The desired contrast ratio.
-1 1877 * @param {boolean} higher Whether the desired luminance is higher or lower than the given luminance.
-1 1878 * @return {number} The desired luminance.
-1 1879 */
-1 1880 axs.color.luminanceFromContrastRatio = function(luminance, contrast, higher) {
-1 1881 if (higher) {
-1 1882 var newLuminance = (luminance + 0.05) * contrast - 0.05;
-1 1883 return newLuminance;
-1 1884 } else {
-1 1885 var newLuminance = (luminance + 0.05) / contrast - 0.05;
-1 1886 return newLuminance;
-1 1887 }
-1 1888 };
-1 1889
-1 1890 /**
-1 1891 * Given a color in YCbCr format and a desired luminance, pick a new color with the desired luminance which is
-1 1892 * as close as possible to the original color.
-1 1893 * @param {axs.color.YCbCr} ycc The original color in YCbCr form.
-1 1894 * @param {number} luma The desired luminance
-1 1895 * @return {!axs.color.Color} A new color in RGB.
-1 1896 */
-1 1897 axs.color.translateColor = function(ycc, luma) {
-1 1898 var endpoint = (luma > ycc.luma) ? axs.color.WHITE_YCC : axs.color.BLACK_YCC;
-1 1899 var cubeFaces = (endpoint == axs.color.WHITE_YCC) ? axs.color.YCC_CUBE_FACES_WHITE
-1 1900 : axs.color.YCC_CUBE_FACES_BLACK;
-1 1901
-1 1902 var a = new axs.color.YCbCr([0, ycc.Cb, ycc.Cr]);
-1 1903 var b = new axs.color.YCbCr([1, ycc.Cb, ycc.Cr]);
-1 1904 var line = { a: a, b: b };
-1 1905
-1 1906 var intersection = null;
-1 1907 for (var i = 0; i < cubeFaces.length; i++) {
-1 1908 var cubeFace = cubeFaces[i];
-1 1909 intersection = axs.color.findIntersection(line, cubeFace);
-1 1910 // If intersection within [0, 1] in Z axis, it is within the cube.
-1 1911 if (intersection.z >= 0 && intersection.z <= 1)
-1 1912 break;
-1 1913 }
-1 1914 if (!intersection) {
-1 1915 // Should never happen
-1 1916 throw "Couldn't find intersection with YCbCr color cube for Cb=" + ycc.Cb + ", Cr=" + ycc.Cr + ".";
-1 1917 }
-1 1918 if (intersection.x != ycc.x || intersection.y != ycc.y) {
-1 1919 // Should never happen
-1 1920 throw "Intersection has wrong Cb/Cr values.";
-1 1921 }
-1 1922
-1 1923 // If intersection.luma is closer to endpoint than desired luma, then luma is inside cube
-1 1924 // and we can immediately return new value.
-1 1925 if (Math.abs(endpoint.luma - intersection.luma) < Math.abs(endpoint.luma - luma)) {
-1 1926 var translatedColor = [luma, ycc.Cb, ycc.Cr];
-1 1927 return axs.color.fromYCbCrArray(translatedColor);
-1 1928 }
-1 1929
-1 1930 // Otherwise, translate from intersection towards white/black such that luma is correct.
-1 1931 var dLuma = luma - intersection.luma;
-1 1932 var scale = dLuma / (endpoint.luma - intersection.luma);
-1 1933 var translatedColor = [ luma,
-1 1934 intersection.Cb - (intersection.Cb * scale),
-1 1935 intersection.Cr - (intersection.Cr * scale) ];
-1 1936
-1 1937 return axs.color.fromYCbCrArray(translatedColor);
-1 1938 };
-1 1939
-1 1940 /** @typedef {{fg: string, bg: string, contrast: string}} */
-1 1941 axs.color.SuggestedColors;
-1 1942
-1 1943 /**
-1 1944 * @param {axs.color.Color} bgColor
-1 1945 * @param {axs.color.Color} fgColor
-1 1946 * @param {Object.<string, number>} desiredContrastRatios A map of label to desired contrast ratio.
-1 1947 * @return {Object.<string, axs.color.SuggestedColors>}
-1 1948 */
-1 1949 axs.color.suggestColors = function(bgColor, fgColor, desiredContrastRatios) {
-1 1950 var colors = {};
-1 1951 var bgLuminance = axs.color.calculateLuminance(bgColor);
-1 1952 var fgLuminance = axs.color.calculateLuminance(fgColor);
-1 1953
-1 1954 var fgLuminanceIsHigher = fgLuminance > bgLuminance;
-1 1955 var fgYCbCr = axs.color.toYCbCr(fgColor);
-1 1956 var bgYCbCr = axs.color.toYCbCr(bgColor);
-1 1957 for (var desiredLabel in desiredContrastRatios) {
-1 1958 var desiredContrast = desiredContrastRatios[desiredLabel];
-1 1959
-1 1960 var desiredFgLuminance = axs.color.luminanceFromContrastRatio(bgLuminance, desiredContrast + 0.02, fgLuminanceIsHigher);
-1 1961 if (desiredFgLuminance <= 1 && desiredFgLuminance >= 0) {
-1 1962 var newFgColor = axs.color.translateColor(fgYCbCr, desiredFgLuminance);
-1 1963 var newContrastRatio = axs.color.calculateContrastRatio(newFgColor, bgColor);
-1 1964 var suggestedColors = {};
-1 1965 suggestedColors.fg = /** @type {!string} */ (axs.color.colorToString(newFgColor));
-1 1966 suggestedColors.bg = /** @type {!string} */ (axs.color.colorToString(bgColor));
-1 1967 suggestedColors.contrast = /** @type {!string} */ (newContrastRatio.toFixed(2));
-1 1968 colors[desiredLabel] = /** @type {axs.color.SuggestedColors} */ (suggestedColors);
-1 1969 continue;
-1 1970 }
-1 1971
-1 1972 var desiredBgLuminance = axs.color.luminanceFromContrastRatio(fgLuminance, desiredContrast + 0.02, !fgLuminanceIsHigher);
-1 1973 if (desiredBgLuminance <= 1 && desiredBgLuminance >= 0) {
-1 1974 var newBgColor = axs.color.translateColor(bgYCbCr, desiredBgLuminance);
-1 1975 var newContrastRatio = axs.color.calculateContrastRatio(fgColor, newBgColor);
-1 1976 var suggestedColors = {};
-1 1977 suggestedColors.bg = /** @type {!string} */ (axs.color.colorToString(newBgColor));
-1 1978 suggestedColors.fg = /** @type {!string} */ (axs.color.colorToString(fgColor));
-1 1979 suggestedColors.contrast = /** @type {!string} */ (newContrastRatio.toFixed(2));
-1 1980 colors[desiredLabel] = /** @type {axs.color.SuggestedColors} */ (suggestedColors);
-1 1981 }
-1 1982 }
-1 1983 return colors;
-1 1984 };
-1 1985
-1 1986 /**
-1 1987 * Combine the two given color according to alpha blending.
-1 1988 * @param {axs.color.Color} fgColor
-1 1989 * @param {axs.color.Color} bgColor
-1 1990 * @return {axs.color.Color}
-1 1991 */
-1 1992 axs.color.flattenColors = function(fgColor, bgColor) {
-1 1993 var alpha = fgColor.alpha;
-1 1994 var r = ((1 - alpha) * bgColor.red) + (alpha * fgColor.red);
-1 1995 var g = ((1 - alpha) * bgColor.green) + (alpha * fgColor.green);
-1 1996 var b = ((1 - alpha) * bgColor.blue) + (alpha * fgColor.blue);
-1 1997 var a = fgColor.alpha + (bgColor.alpha * (1 - fgColor.alpha));
-1 1998
-1 1999 return new axs.color.Color(r, g, b, a);
-1 2000 };
-1 2001
-1 2002 /**
-1 2003 * Multiply the given vector by the given matrix.
-1 2004 * @param {Array.<Array.<number>>} matrix A 3x3 matrix
-1 2005 * @param {Array.<number>} vector A 3-element vector
-1 2006 * @return {Array.<number>} A 3-element vector
-1 2007 */
-1 2008 axs.color.multiplyMatrixVector = function(matrix, vector) {
-1 2009 var a = matrix[0][0];
-1 2010 var b = matrix[0][1];
-1 2011 var c = matrix[0][2];
-1 2012 var d = matrix[1][0];
-1 2013 var e = matrix[1][1];
-1 2014 var f = matrix[1][2];
-1 2015 var g = matrix[2][0];
-1 2016 var h = matrix[2][1];
-1 2017 var k = matrix[2][2];
-1 2018
-1 2019 var x = vector[0];
-1 2020 var y = vector[1];
-1 2021 var z = vector[2];
-1 2022
-1 2023 return [
-1 2024 a*x + b*y + c*z,
-1 2025 d*x + e*y + f*z,
-1 2026 g*x + h*y + k*z
-1 2027 ];
-1 2028 };
-1 2029
-1 2030 /**
-1 2031 * Convert a given RGB color to YCbCr.
-1 2032 * @param {axs.color.Color} color
-1 2033 * @return {axs.color.YCbCr}
-1 2034 */
-1 2035 axs.color.toYCbCr = function(color) {
-1 2036 var rSRGB = color.red / 255;
-1 2037 var gSRGB = color.green / 255;
-1 2038 var bSRGB = color.blue / 255;
-1 2039
-1 2040 var r = rSRGB <= 0.03928 ? rSRGB / 12.92 : Math.pow(((rSRGB + 0.055)/1.055), 2.4);
-1 2041 var g = gSRGB <= 0.03928 ? gSRGB / 12.92 : Math.pow(((gSRGB + 0.055)/1.055), 2.4);
-1 2042 var b = bSRGB <= 0.03928 ? bSRGB / 12.92 : Math.pow(((bSRGB + 0.055)/1.055), 2.4);
-1 2043
-1 2044 return new axs.color.YCbCr(axs.color.multiplyMatrixVector(axs.color.YCC_MATRIX, [r, g, b]));
-1 2045 };
-1 2046
-1 2047 /**
-1 2048 * @param {axs.color.YCbCr} ycc
-1 2049 * @return {!axs.color.Color}
-1 2050 */
-1 2051 axs.color.fromYCbCr = function(ycc) {
-1 2052 return axs.color.fromYCbCrArray([ycc.luma, ycc.Cb, ycc.Cr]);
-1 2053 };
-1 2054
-1 2055 /**
-1 2056 * Convert a color from a YCbCr color (as a vector) to an RGB color
-1 2057 * @param {Array.<number>} yccArray
-1 2058 * @return {!axs.color.Color}
-1 2059 */
-1 2060 axs.color.fromYCbCrArray = function(yccArray) {
-1 2061 var rgb = axs.color.multiplyMatrixVector(axs.color.INVERTED_YCC_MATRIX, yccArray);
-1 2062
-1 2063 var r = rgb[0];
-1 2064 var g = rgb[1];
-1 2065 var b = rgb[2];
-1 2066 var rSRGB = r <= 0.00303949 ? (r * 12.92) : (Math.pow(r, (1/2.4)) * 1.055) - 0.055;
-1 2067 var gSRGB = g <= 0.00303949 ? (g * 12.92) : (Math.pow(g, (1/2.4)) * 1.055) - 0.055;
-1 2068 var bSRGB = b <= 0.00303949 ? (b * 12.92) : (Math.pow(b, (1/2.4)) * 1.055) - 0.055;
-1 2069
-1 2070 var red = Math.min(Math.max(Math.round(rSRGB * 255), 0), 255);
-1 2071 var green = Math.min(Math.max(Math.round(gSRGB * 255), 0), 255);
-1 2072 var blue = Math.min(Math.max(Math.round(bSRGB * 255), 0), 255);
-1 2073
-1 2074 return new axs.color.Color(red, green, blue, 1);
-1 2075 };
-1 2076
-1 2077 /**
-1 2078 * Returns an RGB to YCbCr conversion matrix for the given kR, kB constants.
-1 2079 * @param {number} kR
-1 2080 * @param {number} kB
-1 2081 * @return {Array.<Array.<number>>}
-1 2082 */
-1 2083 axs.color.RGBToYCbCrMatrix = function(kR, kB) {
-1 2084 return [
-1 2085 [
-1 2086 kR,
-1 2087 (1 - kR - kB),
-1 2088 kB
-1 2089 ],
-1 2090 [
-1 2091 -kR/(2 - 2*kB),
-1 2092 (kR + kB - 1)/(2 - 2*kB),
-1 2093 (1 - kB)/(2 - 2*kB)
-1 2094 ],
-1 2095 [
-1 2096 (1 - kR)/(2 - 2*kR),
-1 2097 (kR + kB - 1)/(2 - 2*kR),
-1 2098 -kB/(2 - 2*kR)
-1 2099 ]
-1 2100 ];
-1 2101 };
-1 2102
-1 2103 /**
-1 2104 * Return the inverse of the given 3x3 matrix.
-1 2105 * @param {Array.<Array.<number>>} matrix
-1 2106 * @return Array.<Array.<number>> The inverse of the given matrix.
-1 2107 */
-1 2108 axs.color.invert3x3Matrix = function(matrix) {
-1 2109 var a = matrix[0][0];
-1 2110 var b = matrix[0][1];
-1 2111 var c = matrix[0][2];
-1 2112 var d = matrix[1][0];
-1 2113 var e = matrix[1][1];
-1 2114 var f = matrix[1][2];
-1 2115 var g = matrix[2][0];
-1 2116 var h = matrix[2][1];
-1 2117 var k = matrix[2][2];
-1 2118
-1 2119 var A = (e*k - f*h);
-1 2120 var B = (f*g - d*k);
-1 2121 var C = (d*h - e*g);
-1 2122 var D = (c*h - b*k);
-1 2123 var E = (a*k - c*g);
-1 2124 var F = (g*b - a*h);
-1 2125 var G = (b*f - c*e);
-1 2126 var H = (c*d - a*f);
-1 2127 var K = (a*e - b*d);
-1 2128
-1 2129 var det = a * (e*k - f*h) - b * (k*d - f*g) + c * (d*h - e*g);
-1 2130 var z = 1/det;
-1 2131
-1 2132 return axs.color.scalarMultiplyMatrix([
-1 2133 [ A, D, G ],
-1 2134 [ B, E, H ],
-1 2135 [ C, F, K ]
-1 2136 ], z);
-1 2137 };
-1 2138
-1 2139 /** @typedef {{ a: axs.color.YCbCr, b: axs.color.YCbCr }} */
-1 2140 axs.color.Line;
-1 2141
-1 2142 /** @typedef {{ p0: axs.color.YCbCr, p1: axs.color.YCbCr, p2: axs.color.YCbCr }} */
-1 2143 axs.color.Plane;
-1 2144
-1 2145 /**
-1 2146 * Find the intersection between a line and a plane using
-1 2147 * http://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection#Parametric_form
-1 2148 * @param {axs.color.Line} l
-1 2149 * @param {axs.color.Plane} p
-1 2150 * @return {axs.color.YCbCr}
-1 2151 */
-1 2152 axs.color.findIntersection = function(l, p) {
-1 2153 var lhs = [ l.a.x - p.p0.x, l.a.y - p.p0.y, l.a.z - p.p0.z ];
-1 2154
-1 2155 var matrix = [ [ l.a.x - l.b.x, p.p1.x - p.p0.x, p.p2.x - p.p0.x ],
-1 2156 [ l.a.y - l.b.y, p.p1.y - p.p0.y, p.p2.y - p.p0.y ],
-1 2157 [ l.a.z - l.b.z, p.p1.z - p.p0.z, p.p2.z - p.p0.z ] ];
-1 2158 var invertedMatrix = axs.color.invert3x3Matrix(matrix);
-1 2159
-1 2160 var tuv = axs.color.multiplyMatrixVector(invertedMatrix, lhs);
-1 2161 var t = tuv[0];
-1 2162
-1 2163 var result = l.a.add(l.b.subtract(l.a).multiply(t));
-1 2164 return result;
-1 2165 };
-1 2166
-1 2167 /**
-1 2168 * Multiply a matrix by a scalar.
-1 2169 * @param {Array.<Array.<number>>} matrix A 3x3 matrix.
-1 2170 * @param {number} scalar
-1 2171 * @return {Array.<Array.<number>>}
-1 2172 */
-1 2173 axs.color.scalarMultiplyMatrix = function(matrix, scalar) {
-1 2174 var result = [];
-1 2175
-1 2176 for (var i = 0; i < 3; i++)
-1 2177 result[i] = axs.color.scalarMultiplyVector(matrix[i], scalar);
-1 2178
-1 2179 return result;
-1 2180 };
-1 2181
-1 2182 /**
-1 2183 * Multiply a vector by a scalar.
-1 2184 * @param {Array.<number>} vector
-1 2185 * @param {number} scalar
-1 2186 * @return {Array.<number>} vector
-1 2187 */
-1 2188 axs.color.scalarMultiplyVector = function(vector, scalar) {
-1 2189 var result = [];
-1 2190 for (var i = 0; i < vector.length; i++)
-1 2191 result[i] = vector[i] * scalar;
-1 2192 return result;
-1 2193 };
-1 2194
-1 2195 axs.color.kR = 0.2126;
-1 2196 axs.color.kB = 0.0722;
-1 2197 axs.color.YCC_MATRIX = axs.color.RGBToYCbCrMatrix(axs.color.kR, axs.color.kB);
-1 2198 axs.color.INVERTED_YCC_MATRIX = axs.color.invert3x3Matrix(axs.color.YCC_MATRIX);
-1 2199
-1 2200 axs.color.BLACK = new axs.color.Color(0, 0, 0, 1.0);
-1 2201 axs.color.BLACK_YCC = axs.color.toYCbCr(axs.color.BLACK);
-1 2202 axs.color.WHITE = new axs.color.Color(255, 255, 255, 1.0);
-1 2203 axs.color.WHITE_YCC = axs.color.toYCbCr(axs.color.WHITE);
-1 2204 axs.color.RED = new axs.color.Color(255, 0, 0, 1.0);
-1 2205 axs.color.RED_YCC = axs.color.toYCbCr(axs.color.RED);
-1 2206 axs.color.GREEN = new axs.color.Color(0, 255, 0, 1.0);
-1 2207 axs.color.GREEN_YCC = axs.color.toYCbCr(axs.color.GREEN);
-1 2208 axs.color.BLUE = new axs.color.Color(0, 0, 255, 1.0);
-1 2209 axs.color.BLUE_YCC = axs.color.toYCbCr(axs.color.BLUE);
-1 2210 axs.color.CYAN = new axs.color.Color(0, 255, 255, 1.0);
-1 2211 axs.color.CYAN_YCC = axs.color.toYCbCr(axs.color.CYAN);
-1 2212 axs.color.MAGENTA = new axs.color.Color(255, 0, 255, 1.0);
-1 2213 axs.color.MAGENTA_YCC = axs.color.toYCbCr(axs.color.MAGENTA);
-1 2214 axs.color.YELLOW = new axs.color.Color(255, 255, 0, 1.0);
-1 2215 axs.color.YELLOW_YCC = axs.color.toYCbCr(axs.color.YELLOW);
-1 2216
-1 2217 axs.color.YCC_CUBE_FACES_BLACK = [ { p0: axs.color.BLACK_YCC, p1: axs.color.RED_YCC, p2: axs.color.GREEN_YCC },
-1 2218 { p0: axs.color.BLACK_YCC, p1: axs.color.GREEN_YCC, p2: axs.color.BLUE_YCC },
-1 2219 { p0: axs.color.BLACK_YCC, p1: axs.color.BLUE_YCC, p2: axs.color.RED_YCC } ];
-1 2220 axs.color.YCC_CUBE_FACES_WHITE = [ { p0: axs.color.WHITE_YCC, p1: axs.color.CYAN_YCC, p2: axs.color.MAGENTA_YCC },
-1 2221 { p0: axs.color.WHITE_YCC, p1: axs.color.MAGENTA_YCC, p2: axs.color.YELLOW_YCC },
-1 2222 { p0: axs.color.WHITE_YCC, p1: axs.color.YELLOW_YCC, p2: axs.color.CYAN_YCC } ];
-1 2223
-1 2224 },{}],6:[function(require,module,exports){
-1 2225 // Copyright 2015 Google Inc.
-1 2226 //
-1 2227 // Licensed under the Apache License, Version 2.0 (the "License");
-1 2228 // you may not use this file except in compliance with the License.
-1 2229 // You may obtain a copy of the License at
-1 2230 //
-1 2231 // http://www.apache.org/licenses/LICENSE-2.0
-1 2232 //
-1 2233 // Unless required by applicable law or agreed to in writing, software
-1 2234 // distributed under the License is distributed on an "AS IS" BASIS,
-1 2235 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-1 2236 // See the License for the specific language governing permissions and
-1 2237 // limitations under the License.
-1 2238
-1 2239 goog.provide('axs.dom');
-1 2240
-1 2241 /**
-1 2242 * Returns the nearest ancestor which is an Element.
-1 2243 * @param {Node} node
-1 2244 * @return {?Element}
-1 2245 */
-1 2246 axs.dom.parentElement = function(node) {
-1 2247 if (!node)
-1 2248 return null;
-1 2249
-1 2250 var parentNode = axs.dom.composedParentNode(node);
-1 2251 if (!parentNode)
-1 2252 return null;
-1 2253
-1 2254 switch (parentNode.nodeType) {
-1 2255 case Node.ELEMENT_NODE:
-1 2256 return /** @type {Element} */ (parentNode);
-1 2257 default:
-1 2258 return axs.dom.parentElement(parentNode);
-1 2259 }
-1 2260 };
-1 2261
-1 2262 /**
-1 2263 * Returns the shadow host of a document fragment if it is a Shadow DOM fragment
-1 2264 * otherwise returns `null`.
-1 2265 * @param {DocumentFragment} fragment
-1 2266 * @return {?Element}
-1 2267 */
-1 2268 axs.dom.shadowHost = function(fragment) {
-1 2269 // If host exists, this is a Shadow DOM fragment.
-1 2270 if ('host' in fragment)
-1 2271 return fragment.host;
-1 2272 else
-1 2273 return null;
-1 2274 };
-1 2275
-1 2276 /**
-1 2277 * Returns the given Node's parent in the composed tree.
-1 2278 * @param {Node} node
-1 2279 * @return {?Node}
-1 2280 */
-1 2281 axs.dom.composedParentNode = function(node) {
-1 2282 if (!node)
-1 2283 return null;
-1 2284 if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE)
-1 2285 return axs.dom.shadowHost(/** @type {DocumentFragment} */ (node));
-1 2286
-1 2287 var parentNode = node.parentNode;
-1 2288 if (!parentNode)
-1 2289 return null;
-1 2290
-1 2291 if (parentNode.nodeType === Node.DOCUMENT_FRAGMENT_NODE)
-1 2292 return axs.dom.shadowHost(/** @type {DocumentFragment} */ (parentNode));
-1 2293
-1 2294 if (!parentNode.shadowRoot)
-1 2295 return parentNode;
-1 2296
-1 2297 // Shadow DOM v1
-1 2298 if (node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.TEXT_NODE) {
-1 2299 var assignedSlot = node.assignedSlot;
-1 2300 if (HTMLSlotElement && assignedSlot instanceof HTMLSlotElement)
-1 2301 return axs.dom.composedParentNode(assignedSlot);
-1 2302 }
-1 2303
-1 2304 // Shadow DOM v0
-1 2305 if (typeof node.getDestinationInsertionPoints === 'function') {
-1 2306 var insertionPoints = node.getDestinationInsertionPoints();
-1 2307 if (insertionPoints.length > 0)
-1 2308 return axs.dom.composedParentNode(insertionPoints[insertionPoints.length - 1]);
-1 2309 }
-1 2310
-1 2311 return null;
-1 2312 };
-1 2313
-1 2314 /**
-1 2315 * Return the corresponding element for the given node.
-1 2316 * @param {Node} node
-1 2317 * @return {Element}
-1 2318 * @suppress {checkTypes}
-1 2319 */
-1 2320 axs.dom.asElement = function(node) {
-1 2321 /** @type {Element} */ var element;
-1 2322 switch (node.nodeType) {
-1 2323 case Node.COMMENT_NODE:
-1 2324 return null; // Skip comments
-1 2325 case Node.ELEMENT_NODE:
-1 2326 element = /** (@type {Element}) */ node;
-1 2327 if (element.localName == 'script' ||
-1 2328 element.localName == 'template')
-1 2329 return null; // Skip script-supporting elements
-1 2330 return element;
-1 2331 case Node.DOCUMENT_FRAGMENT_NODE:
-1 2332 return node.host;
-1 2333 case Node.TEXT_NODE:
-1 2334 return axs.dom.parentElement(node);
-1 2335 default:
-1 2336 console.warn('Unhandled node type: ', node.nodeType);
-1 2337 }
-1 2338 return null;
-1 2339 };
-1 2340
-1 2341 /**
-1 2342 * Recursively walk the composed tree from |node|, aborting if |end| is encountered.
-1 2343 * @param {Node} node
-1 2344 * @param {?Node} end
-1 2345 * @param {{preorder: (function (Node, Object):boolean|undefined),
-1 2346 * postorder: (function (Node, Object)|undefined)}} callbacks
-1 2347 * Callbacks to be called for each element traversed, excluding
-1 2348 * |end|. Possible callbacks are |preorder|, called before descending into
-1 2349 * child nodes, and |postorder| called after all child nodes have been
-1 2350 * traversed. If |preorder| returns false, its child nodes will not be
-1 2351 * traversed.
-1 2352 * @param {Object} parentFlags
-1 2353 * @param {ShadowRoot=} opt_shadowRoot The nearest ShadowRoot ancestor, if any.
-1 2354 * @return {boolean} Whether |end| was found, if provided.
-1 2355 */
-1 2356 axs.dom.composedTreeSearch = function(node, end, callbacks, parentFlags, opt_shadowRoot) {
-1 2357 if (node === end)
-1 2358 return true;
-1 2359
-1 2360 if (node.nodeType == Node.ELEMENT_NODE)
-1 2361 var element = /** @type {Element} */ (node);
-1 2362
-1 2363 var found = false;
-1 2364 var flags = Object.create(parentFlags);
-1 2365
-1 2366 // Descend into node:
-1 2367 // If it has a ShadowRoot, ignore all child elements - these will be picked
-1 2368 // up by the <content> or <shadow> elements. Descend straight into the
-1 2369 // ShadowRoot.
-1 2370 if (element) {
-1 2371 var localName = element.localName;
-1 2372 if (flags.collectIdRefs) {
-1 2373 flags.idrefs = axs.utils.getReferencedIds(element);
-1 2374 }
-1 2375 if (!flags.disabled || (localName === 'legend') && axs.browserUtils.matchSelector(element, 'fieldset>legend:first-of-type')) {
-1 2376 flags.disabled = axs.utils.isElementDisabled(element, true);
-1 2377 }
-1 2378 if (!flags.hidden) {
-1 2379 flags.hidden = axs.utils.isElementHidden(element);
-1 2380 }
-1 2381 if (callbacks.preorder) {
-1 2382 if (!callbacks.preorder(element, flags))
-1 2383 return found;
-1 2384 }
-1 2385 // NOTE: grunt qunit DOES NOT support Shadow DOM, so if changing this
-1 2386 // code, be sure to run the tests in the browser before committing.
-1 2387 var shadowRoot = element.shadowRoot || element.webkitShadowRoot;
-1 2388 if (shadowRoot) {
-1 2389 flags.level++;
-1 2390 found = axs.dom.composedTreeSearch(shadowRoot,
-1 2391 end,
-1 2392 callbacks,
-1 2393 flags,
-1 2394 shadowRoot);
-1 2395 if (element && callbacks.postorder && !found)
-1 2396 callbacks.postorder(element, flags);
-1 2397 return found;
-1 2398 }
-1 2399
-1 2400 // If it is a <content> element, descend into distributed elements - these
-1 2401 // are elements from outside the shadow root which are rendered inside the
-1 2402 // shadow DOM.
-1 2403 if (localName == 'content' && typeof element.getDistributedNodes === 'function') {
-1 2404 var content = /** @type {HTMLContentElement} */ (element);
-1 2405 var distributedNodes = content.getDistributedNodes();
-1 2406 for (var i = 0; i < distributedNodes.length && !found; i++) {
-1 2407 found = axs.dom.composedTreeSearch(distributedNodes[i],
-1 2408 end,
-1 2409 callbacks,
-1 2410 flags,
-1 2411 opt_shadowRoot);
-1 2412 }
-1 2413 if (callbacks.postorder && !found)
-1 2414 callbacks.postorder.call(null, element, flags);
-1 2415 return found;
-1 2416 }
-1 2417 }
-1 2418
-1 2419
-1 2420
-1 2421 // If it is neither the parent of a ShadowRoot, a <content> element, nor
-1 2422 // a <shadow> element recurse normally.
-1 2423 var child = node.firstChild;
-1 2424 while (child != null && !found) {
-1 2425 found = axs.dom.composedTreeSearch(child,
-1 2426 end,
-1 2427 callbacks,
-1 2428 flags,
-1 2429 opt_shadowRoot);
-1 2430 child = child.nextSibling;
-1 2431 }
-1 2432
-1 2433 if (element && callbacks.postorder && !found)
-1 2434 callbacks.postorder.call(null, element, flags);
-1 2435 return found;
-1 2436 };
-1 2437
-1 2438 },{}],7:[function(require,module,exports){
-1 2439 // Copyright 2012 Google Inc.
-1 2440 //
-1 2441 // Licensed under the Apache License, Version 2.0 (the "License");
-1 2442 // you may not use this file except in compliance with the License.
-1 2443 // You may obtain a copy of the License at
-1 2444 //
-1 2445 // http://www.apache.org/licenses/LICENSE-2.0
-1 2446 //
-1 2447 // Unless required by applicable law or agreed to in writing, software
-1 2448 // distributed under the License is distributed on an "AS IS" BASIS,
-1 2449 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-1 2450 // See the License for the specific language governing permissions and
-1 2451 // limitations under the License.
-1 2452
-1 2453 goog.require('axs.browserUtils');
-1 2454 goog.require('axs.color');
-1 2455 goog.require('axs.dom');
-1 2456 goog.require('axs.utils');
-1 2457
-1 2458 goog.provide('axs.properties');
-1 2459
-1 2460 /**
-1 2461 * @const
-1 2462 * @type {string}
-1 2463 */
-1 2464 axs.properties.TEXT_CONTENT_XPATH = './/text()[normalize-space(.)!=""]/parent::*[name()!="script"]';
-1 2465
-1 2466 /**
-1 2467 * @param {Element} element
-1 2468 * @return {Object.<string, Object>}
-1 2469 */
-1 2470 axs.properties.getFocusProperties = function(element) {
-1 2471 var focusProperties = {};
-1 2472 var tabindex = element.getAttribute('tabindex');
-1 2473 if (tabindex != undefined) {
-1 2474 focusProperties['tabindex'] = { value: tabindex, valid: true };
-1 2475 } else {
-1 2476 if (axs.utils.isElementImplicitlyFocusable(element))
-1 2477 focusProperties['implicitlyFocusable'] = { value: true, valid: true };
-1 2478 }
-1 2479 if (Object.keys(focusProperties).length == 0)
-1 2480 return null;
-1 2481 var transparent = axs.utils.elementIsTransparent(element);
-1 2482 var zeroArea = axs.utils.elementHasZeroArea(element);
-1 2483 var outsideScrollArea = axs.utils.elementIsOutsideScrollArea(element);
-1 2484 var overlappingElements = axs.utils.overlappingElements(element);
-1 2485 if (transparent || zeroArea || outsideScrollArea || overlappingElements.length > 0) {
-1 2486 var hidden = axs.utils.isElementOrAncestorHidden(element);
-1 2487 var visibleProperties = { value: false,
-1 2488 valid: hidden };
-1 2489 if (transparent)
-1 2490 visibleProperties['transparent'] = true;
-1 2491 if (zeroArea)
-1 2492 visibleProperties['zeroArea'] = true;
-1 2493 if (outsideScrollArea)
-1 2494 visibleProperties['outsideScrollArea'] = true;
-1 2495 if (overlappingElements && overlappingElements.length > 0)
-1 2496 visibleProperties['overlappingElements'] = overlappingElements;
-1 2497 var hiddenProperties = { value: hidden, valid: hidden };
-1 2498 if (hidden)
-1 2499 hiddenProperties['reason'] = axs.properties.getHiddenReason(element);
-1 2500 visibleProperties['hidden'] = hiddenProperties;
-1 2501 focusProperties['visible'] = visibleProperties;
-1 2502 } else {
-1 2503 focusProperties['visible'] = { value: true, valid: true };
-1 2504 }
-1 2505
-1 2506 return focusProperties;
-1 2507 };
-1 2508
-1 2509 /**
-1 2510 * @typedef {{ property: string,
-1 2511 * on: Element }}
-1 2512 *
-1 2513 * property examples: 'display: none', 'visibility: hidden', 'aria-hidden'
-1 2514 */
-1 2515 axs.properties.hiddenReason;
-1 2516
-1 2517 /**
-1 2518 * Determine the reason an element is not visible.
-1 2519 * Will give the CSS rule or attribute and the element/ancestor it is set on.
-1 2520 * @param {Element} element
-1 2521 * @return {?axs.properties.hiddenReason}
-1 2522 */
-1 2523 axs.properties.getHiddenReason = function(element) {
-1 2524 if (!element || !(element instanceof element.ownerDocument.defaultView.HTMLElement))
-1 2525 return null;
-1 2526
-1 2527 if (element.hasAttribute('chromevoxignoreariahidden'))
-1 2528 var chromevoxignoreariahidden = true;
-1 2529
-1 2530 var style = window.getComputedStyle(element, null);
-1 2531 if (style.display == 'none')
-1 2532 return { 'property': 'display: none',
-1 2533 'on': element };
-1 2534
-1 2535 if (style.visibility == 'hidden')
-1 2536 return { 'property': 'visibility: hidden',
-1 2537 'on': element };
-1 2538
-1 2539 if (element.hasAttribute('aria-hidden') &&
-1 2540 element.getAttribute('aria-hidden').toLowerCase() == 'true') {
-1 2541 if (!chromevoxignoreariahidden)
-1 2542 return { 'property': 'aria-hidden',
-1 2543 'on': element };
-1 2544 }
-1 2545
-1 2546 return axs.properties.getHiddenReason(axs.dom.parentElement(element));
-1 2547 };
-1 2548
-1 2549
-1 2550 /**
-1 2551 * @param {Element} element
-1 2552 * @return {Object.<string, Object>}
-1 2553 */
-1 2554 axs.properties.getColorProperties = function(element) {
-1 2555 var colorProperties = {};
-1 2556 var contrastRatioProperties =
-1 2557 axs.properties.getContrastRatioProperties(element);
-1 2558 if (contrastRatioProperties)
-1 2559 colorProperties['contrastRatio'] = contrastRatioProperties;
-1 2560 if (Object.keys(colorProperties).length == 0)
-1 2561 return null;
-1 2562 return colorProperties;
-1 2563 };
-1 2564
-1 2565 /**
-1 2566 * Determines whether the given element has a text node as a direct descendant.
-1 2567 * @param {Element} element
-1 2568 * @return {boolean}
-1 2569 */
-1 2570 axs.properties.hasDirectTextDescendant = function(element) {
-1 2571 var ownerDocument;
-1 2572 if (element.nodeType == Node.DOCUMENT_NODE)
-1 2573 ownerDocument = element;
-1 2574 else
-1 2575 ownerDocument = element.ownerDocument;
-1 2576 if (ownerDocument.evaluate) {
-1 2577 return hasDirectTextDescendantXpath();
-1 2578 }
-1 2579 return hasDirectTextDescendantTreeWalker();
-1 2580
-1 2581 /**
-1 2582 * Determines whether element has a text node as a direct descendant.
-1 2583 * This method uses XPath on HTML DOM which is not universally supported.
-1 2584 * @return {boolean}
-1 2585 */
-1 2586 function hasDirectTextDescendantXpath() {
-1 2587 var selectorResults = ownerDocument.evaluate(axs.properties.TEXT_CONTENT_XPATH,
-1 2588 element,
-1 2589 null,
-1 2590 XPathResult.ANY_TYPE,
-1 2591 null);
-1 2592 for (var resultElement = selectorResults.iterateNext();
-1 2593 resultElement != null;
-1 2594 resultElement = selectorResults.iterateNext()) {
-1 2595 if (resultElement !== element)
-1 2596 continue;
-1 2597 return true;
-1 2598 }
-1 2599 return false;
-1 2600 }
-1 2601
-1 2602 /**
-1 2603 * Determines whether element has a text node as a direct descendant.
-1 2604 * This method uses TreeWalker as a fallback (at time of writing no version
-1 2605 * of IE (including IE11) supports XPath in the HTML DOM).
-1 2606 * @return {boolean}
-1 2607 */
-1 2608 function hasDirectTextDescendantTreeWalker() {
-1 2609 var treeWalker = ownerDocument.createTreeWalker(element,
-1 2610 NodeFilter.SHOW_TEXT,
-1 2611 null,
-1 2612 false);
-1 2613 while (treeWalker.nextNode()) {
-1 2614 var resultElement = treeWalker.currentNode;
-1 2615 var parent = resultElement.parentNode;
-1 2616 // Handle elements hosted in <template>.content.
-1 2617 parent = parent.host || parent;
-1 2618 var tagName = parent.tagName.toLowerCase();
-1 2619 var value = resultElement.nodeValue.trim();
-1 2620 if (value && tagName !== 'script' && element !== resultElement)
-1 2621 return true;
-1 2622 }
-1 2623 return false;
-1 2624 }
-1 2625 };
-1 2626
-1 2627 /**
-1 2628 * @param {Element} element
-1 2629 * @return {Object.<string, Object>}
-1 2630 */
-1 2631 axs.properties.getContrastRatioProperties = function(element) {
-1 2632 if (!axs.properties.hasDirectTextDescendant(element))
-1 2633 return null;
-1 2634
-1 2635 var contrastRatioProperties = {};
-1 2636 var style = window.getComputedStyle(element, null);
-1 2637 var bgColor = axs.utils.getBgColor(style, element);
-1 2638 if (!bgColor)
-1 2639 return null;
-1 2640
-1 2641 contrastRatioProperties['backgroundColor'] = axs.color.colorToString(bgColor);
-1 2642 var fgColor = axs.utils.getFgColor(style, element, bgColor);
-1 2643 contrastRatioProperties['foregroundColor'] = axs.color.colorToString(fgColor);
-1 2644 var contrast = axs.utils.getContrastRatioForElementWithComputedStyle(style, element);
-1 2645 if (!contrast)
-1 2646 return null;
-1 2647 contrastRatioProperties['value'] = contrast.toFixed(2);
-1 2648 if (axs.utils.isLowContrast(contrast, style))
-1 2649 contrastRatioProperties['alert'] = true;
-1 2650
-1 2651 var levelAAContrast = axs.utils.isLargeFont(style) ? 3.0 : 4.5;
-1 2652 var levelAAAContrast = axs.utils.isLargeFont(style) ? 4.5 : 7.0;
-1 2653 var desiredContrastRatios = {};
-1 2654 if (levelAAContrast > contrast)
-1 2655 desiredContrastRatios['AA'] = levelAAContrast;
-1 2656 if (levelAAAContrast > contrast)
-1 2657 desiredContrastRatios['AAA'] = levelAAAContrast;
-1 2658
-1 2659 if (!Object.keys(desiredContrastRatios).length)
-1 2660 return contrastRatioProperties;
-1 2661
-1 2662 var suggestedColors = axs.color.suggestColors(bgColor, fgColor, desiredContrastRatios);
-1 2663 if (suggestedColors && Object.keys(suggestedColors).length)
-1 2664 contrastRatioProperties['suggestedColors'] = suggestedColors;
-1 2665 return contrastRatioProperties;
-1 2666 };
-1 2667
-1 2668 /**
-1 2669 * @param {Node} node
-1 2670 * @param {!Object} textAlternatives The properties object to fill in
-1 2671 * @param {boolean=} opt_recursive Whether this is a recursive call or not
-1 2672 * @param {boolean=} opt_force Whether to return text alternatives for this
-1 2673 * element regardless of its hidden state.
-1 2674 * @return {?string} The calculated text alternative for the given element
-1 2675 */
-1 2676 axs.properties.findTextAlternatives = function(node, textAlternatives, opt_recursive, opt_force) {
-1 2677 var recursive = opt_recursive || false;
-1 2678
-1 2679 /** @type {Element} */ var element = axs.dom.asElement(node);
-1 2680 if (!element)
-1 2681 return null;
-1 2682
-1 2683 // 1. Skip hidden elements unless the author specifies to use them via an aria-labelledby or
-1 2684 // aria-describedby being used in the current computation.
-1 2685 if (!opt_force && axs.utils.isElementOrAncestorHidden(element))
-1 2686 return null;
-1 2687
-1 2688 // if this is a text node, just return text content.
-1 2689 if (node.nodeType == Node.TEXT_NODE) {
-1 2690 var textContentValue = {};
-1 2691 textContentValue.type = 'text';
-1 2692 textContentValue.text = node.textContent;
-1 2693 textContentValue.lastWord = axs.properties.getLastWord(textContentValue.text);
-1 2694 textAlternatives['content'] = textContentValue;
-1 2695
-1 2696 return node.textContent;
-1 2697 }
-1 2698
-1 2699 var computedName = null;
-1 2700
-1 2701 if (!recursive) {
-1 2702 // 2A. The aria-labelledby attribute takes precedence as the element's text alternative
-1 2703 // unless this computation is already occurring as the result of a recursive aria-labelledby
-1 2704 // declaration.
-1 2705 computedName = axs.properties.getTextFromAriaLabelledby(element, textAlternatives);
-1 2706 }
-1 2707
-1 2708 // 2A. If aria-labelledby is empty or undefined, the aria-label attribute, which defines an
-1 2709 // explicit text string, is used.
-1 2710 if (element.hasAttribute('aria-label')) {
-1 2711 var ariaLabelValue = {};
-1 2712 ariaLabelValue.type = 'text';
-1 2713 ariaLabelValue.text = element.getAttribute('aria-label');
-1 2714 ariaLabelValue.lastWord = axs.properties.getLastWord(ariaLabelValue.text);
-1 2715 if (computedName)
-1 2716 ariaLabelValue.unused = true;
-1 2717 else if (!(recursive && axs.utils.elementIsHtmlControl(element)))
-1 2718 computedName = ariaLabelValue.text;
-1 2719 textAlternatives['ariaLabel'] = ariaLabelValue;
-1 2720 }
-1 2721
-1 2722 // 2A. If aria-labelledby and aria-label are both empty or undefined, and if the element is not
-1 2723 // marked as presentational (role="presentation", check for the presence of an equivalent host
-1 2724 // language attribute or element for associating a label, and use those mechanisms to determine
-1 2725 // a text alternative.
-1 2726 if (!element.hasAttribute('role') || element.getAttribute('role') != 'presentation') {
-1 2727 computedName = axs.properties.getTextFromHostLanguageAttributes(element,
-1 2728 textAlternatives,
-1 2729 computedName,
-1 2730 recursive);
-1 2731 }
-1 2732
-1 2733 // 2B (HTML version).
-1 2734 if (recursive && axs.utils.elementIsHtmlControl(element)) {
-1 2735 var defaultView = element.ownerDocument.defaultView;
-1 2736
-1 2737 // include the value of the embedded control as part of the text alternative in the
-1 2738 // following manner:
-1 2739 if (element instanceof defaultView.HTMLInputElement) {
-1 2740 // If the embedded control is a text field, use its value.
-1 2741 var inputElement = /** @type {HTMLInputElement} */ (element);
-1 2742 if (inputElement.type == 'text') {
-1 2743 if (inputElement.value && inputElement.value.length > 0)
-1 2744 textAlternatives['controlValue'] = { 'text': inputElement.value };
-1 2745 }
-1 2746 // If the embedded control is a range (e.g. a spinbutton or slider), use the value of the
-1 2747 // aria-valuetext attribute if available, or otherwise the value of the aria-valuenow
-1 2748 // attribute.
-1 2749 if (inputElement.type == 'range')
-1 2750 textAlternatives['controlValue'] = { 'text': inputElement.value };
-1 2751 }
-1 2752 // If the embedded control is a menu, use the text alternative of the chosen menu item.
-1 2753 // If the embedded control is a select or combobox, use the chosen option.
-1 2754 if (element instanceof defaultView.HTMLSelectElement) {
-1 2755 var inputElement = /** @type {HTMLSelectElement} */ (element);
-1 2756 textAlternatives['controlValue'] = { 'text': inputElement.value };
-1 2757 }
-1 2758
-1 2759 if (textAlternatives['controlValue']) {
-1 2760 var controlValue = textAlternatives['controlValue'];
-1 2761 if (computedName)
-1 2762 controlValue.unused = true;
-1 2763 else
-1 2764 computedName = controlValue.text;
-1 2765 }
-1 2766 }
-1 2767
-1 2768 // 2B (ARIA version).
-1 2769 if (recursive && axs.utils.elementIsAriaWidget(element)) {
-1 2770 var role = element.getAttribute('role');
-1 2771 // If the embedded control is a text field, use its value.
-1 2772 if (role == 'textbox') {
-1 2773 if (element.textContent && element.textContent.length > 0)
-1 2774 textAlternatives['controlValue'] = { 'text': element.textContent };
-1 2775 }
-1 2776 // If the embedded control is a range (e.g. a spinbutton or slider), use the value of the
-1 2777 // aria-valuetext attribute if available, or otherwise the value of the aria-valuenow
-1 2778 // attribute.
-1 2779 if (role == 'slider' || role == 'spinbutton') {
-1 2780 if (element.hasAttribute('aria-valuetext'))
-1 2781 textAlternatives['controlValue'] = { 'text': element.getAttribute('aria-valuetext') };
-1 2782 else if (element.hasAttribute('aria-valuenow'))
-1 2783 textAlternatives['controlValue'] = { 'value': element.getAttribute('aria-valuenow'),
-1 2784 'text': '' + element.getAttribute('aria-valuenow') };
-1 2785 }
-1 2786 // If the embedded control is a menu, use the text alternative of the chosen menu item.
-1 2787 if (role == 'menu') {
-1 2788 var menuitems = element.querySelectorAll('[role=menuitemcheckbox], [role=menuitemradio]');
-1 2789 var selectedMenuitems = [];
-1 2790 for (var i = 0; i < menuitems.length; i++) {
-1 2791 if (menuitems[i].getAttribute('aria-checked') == 'true')
-1 2792 selectedMenuitems.push(menuitems[i]);
-1 2793 }
-1 2794 if (selectedMenuitems.length > 0) {
-1 2795 var selectedMenuText = '';
-1 2796 for (var i = 0; i < selectedMenuitems.length; i++) {
-1 2797 selectedMenuText += axs.properties.findTextAlternatives(selectedMenuitems[i], {}, true);
-1 2798 if (i < selectedMenuitems.length - 1)
-1 2799 selectedMenuText += ', ';
-1 2800 }
-1 2801 textAlternatives['controlValue'] = { 'text': selectedMenuText };
-1 2802 }
-1 2803 }
-1 2804 // If the embedded control is a select or combobox, use the chosen option.
-1 2805 if (role == 'combobox' || role == 'select') {
-1 2806 // TODO
-1 2807 textAlternatives['controlValue'] = { 'text': 'TODO' };
-1 2808 }
-1 2809
-1 2810 if (textAlternatives['controlValue']) {
-1 2811 var controlValue = textAlternatives['controlValue'];
-1 2812 if (computedName)
-1 2813 controlValue.unused = true;
-1 2814 else
-1 2815 computedName = controlValue.text;
-1 2816 }
-1 2817 }
-1 2818
-1 2819 // 2C. Otherwise, if the attributes checked in rules A and B didn't provide results, text is
-1 2820 // collected from descendant content if the current element's role allows "Name From: contents."
-1 2821 var hasRole = element.hasAttribute('role');
-1 2822 var canGetNameFromContents = true;
-1 2823 if (hasRole) {
-1 2824 var roleName = element.getAttribute('role');
-1 2825 // if element has a role, check that it allows "Name From: contents"
-1 2826 var role = axs.constants.ARIA_ROLES[roleName];
-1 2827 if (role && (!role.namefrom || role.namefrom.indexOf('contents') < 0))
-1 2828 canGetNameFromContents = false;
-1 2829 }
-1 2830 var textFromContent = axs.properties.getTextFromDescendantContent(element, opt_force);
-1 2831 if (textFromContent && canGetNameFromContents) {
-1 2832 var textFromContentValue = {};
-1 2833 textFromContentValue.type = 'text';
-1 2834 textFromContentValue.text = textFromContent;
-1 2835 textFromContentValue.lastWord = axs.properties.getLastWord(textFromContentValue.text);
-1 2836 if (computedName)
-1 2837 textFromContentValue.unused = true;
-1 2838 else
-1 2839 computedName = textFromContent;
-1 2840 textAlternatives['content'] = textFromContentValue;
-1 2841 }
-1 2842
-1 2843 // 2D. The last resort is to use text from a tooltip attribute (such as the title attribute in
-1 2844 // HTML). This is used only if nothing else, including subtree content, has provided results.
-1 2845 if (element.hasAttribute('title')) {
-1 2846 var titleValue = {};
-1 2847 titleValue.type = 'string';
-1 2848 titleValue.valid = true;
-1 2849 titleValue.text = element.getAttribute('title');
-1 2850 titleValue.lastWord = axs.properties.getLastWord(titleValue.lastWord);
-1 2851 if (computedName)
-1 2852 titleValue.unused = true;
-1 2853 else
-1 2854 computedName = titleValue.text;
-1 2855 textAlternatives['title'] = titleValue;
-1 2856 }
-1 2857
-1 2858 if (Object.keys(textAlternatives).length == 0 && computedName == null)
-1 2859 return null;
-1 2860
-1 2861 return computedName;
-1 2862 };
-1 2863
-1 2864 /**
-1 2865 * @param {Element} element
-1 2866 * @param {boolean=} opt_force Whether to return text alternatives for this
-1 2867 * element regardless of its hidden state.
-1 2868 * @return {?string}
-1 2869 */
-1 2870 axs.properties.getTextFromDescendantContent = function(element, opt_force) {
-1 2871 var children = element.childNodes;
-1 2872 var childrenTextContent = [];
-1 2873 for (var i = 0; i < children.length; i++) {
-1 2874 var childTextContent = axs.properties.findTextAlternatives(children[i], {}, true, opt_force);
-1 2875 if (childTextContent)
-1 2876 childrenTextContent.push(childTextContent.trim());
-1 2877 }
-1 2878 if (childrenTextContent.length) {
-1 2879 var result = '';
-1 2880 // Empty children are allowed, but collapse all of them
-1 2881 for (var i = 0; i < childrenTextContent.length; i++)
-1 2882 result = [result, childrenTextContent[i]].join(' ').trim();
-1 2883 return result;
-1 2884 }
-1 2885 return null;
-1 2886 };
-1 2887
-1 2888 /**
-1 2889 * @param {Element} element
-1 2890 * @param {Object} textAlternatives
-1 2891 * @return {?string}
-1 2892 */
-1 2893 axs.properties.getTextFromAriaLabelledby = function(element, textAlternatives) {
-1 2894 var computedName = null;
-1 2895 if (!element.hasAttribute('aria-labelledby'))
-1 2896 return computedName;
-1 2897
-1 2898 var labelledbyAttr = element.getAttribute('aria-labelledby');
-1 2899 var labelledbyIds = labelledbyAttr.split(/\s+/);
-1 2900 var labelledbyValue = {};
-1 2901 labelledbyValue.valid = true;
-1 2902 var labelledbyText = [];
-1 2903 var labelledbyValues = [];
-1 2904 for (var i = 0; i < labelledbyIds.length; i++) {
-1 2905 var labelledby = {};
-1 2906 labelledby.type = 'element';
-1 2907 var labelledbyId = labelledbyIds[i];
-1 2908 labelledby.value = labelledbyId;
-1 2909 var labelledbyElement = document.getElementById(labelledbyId);
-1 2910 if (!labelledbyElement) {
-1 2911 labelledby.valid = false;
-1 2912 labelledbyValue.valid = false;
-1 2913 labelledby.errorMessage = { 'messageKey': 'noElementWithId', 'args': [labelledbyId] };
-1 2914 } else {
-1 2915 labelledby.valid = true;
-1 2916 labelledby.text = axs.properties.findTextAlternatives(labelledbyElement, {}, true, true);
-1 2917 labelledby.lastWord = axs.properties.getLastWord(labelledby.text);
-1 2918 labelledbyText.push(labelledby.text);
-1 2919 labelledby.element = labelledbyElement;
-1 2920 }
-1 2921 labelledbyValues.push(labelledby);
-1 2922 }
-1 2923 if (labelledbyValues.length > 0) {
-1 2924 labelledbyValues[labelledbyValues.length - 1].last = true;
-1 2925 labelledbyValue.values = labelledbyValues;
-1 2926 labelledbyValue.text = labelledbyText.join(' ');
-1 2927 labelledbyValue.lastWord = axs.properties.getLastWord(labelledbyValue.text);
-1 2928 computedName = labelledbyValue.text;
-1 2929 textAlternatives['ariaLabelledby'] = labelledbyValue;
-1 2930 }
-1 2931
-1 2932 return computedName;
-1 2933 };
-1 2934
-1 2935
-1 2936 /**
-1 2937 * Determine the text description/label for an element.
-1 2938 * For example will attempt to find the alt text for an image or label text for a form control.
-1 2939 * @param {!Element} element
-1 2940 * @param {!Object} textAlternatives An object that will be updated with information.
-1 2941 * @param {?string} existingComputedname
-1 2942 * @param {boolean} recursive Whether this method is being called recursively as described in
-1 2943 * http://www.w3.org/TR/wai-aria/roles#textalternativecomputation section 2A.
-1 2944 * @return {Object}
-1 2945 */
-1 2946 axs.properties.getTextFromHostLanguageAttributes = function(element,
-1 2947 textAlternatives,
-1 2948 existingComputedname,
-1 2949 recursive) {
-1 2950 var computedName = existingComputedname;
-1 2951 if (axs.browserUtils.matchSelector(element, 'img') && element.hasAttribute('alt')) {
-1 2952 var altValue = {};
-1 2953 altValue.type = 'string';
-1 2954 altValue.valid = true;
-1 2955 altValue.text = element.getAttribute('alt');
-1 2956 if (computedName)
-1 2957 altValue.unused = true;
-1 2958 else
-1 2959 computedName = altValue.text;
-1 2960 textAlternatives['alt'] = altValue;
-1 2961 }
-1 2962
-1 2963 var controlsSelector = ['input:not([type="hidden"]):not([disabled])',
-1 2964 'select:not([disabled])',
-1 2965 'textarea:not([disabled])',
-1 2966 'button:not([disabled])',
-1 2967 'video:not([disabled])'].join(', ');
-1 2968 if (axs.browserUtils.matchSelector(element, controlsSelector) && !recursive) {
-1 2969 if (element.hasAttribute('id')) {
-1 2970 var labelForQuerySelector = 'label[for="' + element.id + '"]';
-1 2971 var labelsFor = document.querySelectorAll(labelForQuerySelector);
-1 2972 var labelForValue = {};
-1 2973 var labelForValues = [];
-1 2974 var labelForText = [];
-1 2975 for (var i = 0; i < labelsFor.length; i++) {
-1 2976 var labelFor = {};
-1 2977 labelFor.type = 'element';
-1 2978 var label = labelsFor[i];
-1 2979 var labelText = axs.properties.findTextAlternatives(label, {}, true);
-1 2980 if (labelText && labelText.trim().length > 0) {
-1 2981 labelFor.text = labelText.trim();
-1 2982 labelForText.push(labelText.trim());
-1 2983 }
-1 2984 labelFor.element = label;
-1 2985 labelForValues.push(labelFor);
-1 2986 }
-1 2987 if (labelForValues.length > 0) {
-1 2988 labelForValues[labelForValues.length - 1].last = true;
-1 2989 labelForValue.values = labelForValues;
-1 2990 labelForValue.text = labelForText.join(' ');
-1 2991 labelForValue.lastWord = axs.properties.getLastWord(labelForValue.text);
-1 2992 if (computedName)
-1 2993 labelForValue.unused = true;
-1 2994 else
-1 2995 computedName = labelForValue.text;
-1 2996 textAlternatives['labelFor'] = labelForValue;
-1 2997 }
-1 2998 }
-1 2999
-1 3000 var parent = axs.dom.parentElement(element);
-1 3001 var labelWrappedValue = {};
-1 3002 while (parent) {
-1 3003 if (parent.tagName.toLowerCase() == 'label') {
-1 3004 var parentLabel = /** @type {HTMLLabelElement} */ (parent);
-1 3005 if (parentLabel.control == element) {
-1 3006 labelWrappedValue.type = 'element';
-1 3007 labelWrappedValue.text = axs.properties.findTextAlternatives(parentLabel, {}, true);
-1 3008 labelWrappedValue.lastWord = axs.properties.getLastWord(labelWrappedValue.text);
-1 3009 labelWrappedValue.element = parentLabel;
-1 3010 break;
-1 3011 }
-1 3012 }
-1 3013 parent = axs.dom.parentElement(parent);
-1 3014 }
-1 3015 if (labelWrappedValue.text) {
-1 3016 if (computedName)
-1 3017 labelWrappedValue.unused = true;
-1 3018 else
-1 3019 computedName = labelWrappedValue.text;
-1 3020 textAlternatives['labelWrapped'] = labelWrappedValue;
-1 3021 }
-1 3022 // If all else fails input of type image can fall back to its alt text
-1 3023 if (axs.browserUtils.matchSelector(element, 'input[type="image"]') && element.hasAttribute('alt')) {
-1 3024 var altValue = {};
-1 3025 altValue.type = 'string';
-1 3026 altValue.valid = true;
-1 3027 altValue.text = element.getAttribute('alt');
-1 3028 if (computedName)
-1 3029 altValue.unused = true;
-1 3030 else
-1 3031 computedName = altValue.text;
-1 3032 textAlternatives['alt'] = altValue;
-1 3033 }
-1 3034 if (!Object.keys(textAlternatives).length)
-1 3035 textAlternatives['noLabel'] = true;
-1 3036 }
-1 3037 return computedName;
-1 3038 };
-1 3039
-1 3040 /**
-1 3041 * @param {?string} text
-1 3042 * @return {?string}
-1 3043 */
-1 3044 axs.properties.getLastWord = function(text) {
-1 3045 if (!text)
-1 3046 return null;
-1 3047
-1 3048 // TODO: this makes a lot of assumptions.
-1 3049 var lastSpace = text.lastIndexOf(' ') + 1;
-1 3050 var MAXLENGTH = 10;
-1 3051 var cutoff = text.length - MAXLENGTH;
-1 3052 var wordStart = lastSpace > cutoff ? lastSpace : cutoff;
-1 3053 return text.substring(wordStart);
-1 3054 };
-1 3055
-1 3056 /**
-1 3057 * @param {Node} node
-1 3058 * @return {Object}
-1 3059 */
-1 3060 axs.properties.getTextProperties = function(node) {
-1 3061 var textProperties = {};
-1 3062 var computedName = axs.properties.findTextAlternatives(node, textProperties, false, true);
-1 3063
-1 3064 if (Object.keys(textProperties).length == 0) {
-1 3065 /** @type {Element} */ var element = axs.dom.asElement(node);
-1 3066 if (element && axs.browserUtils.matchSelector(element, 'img')) {
-1 3067 var altValue = {};
-1 3068 altValue.valid = false;
-1 3069 altValue.errorMessage = 'No alt value provided';
-1 3070 textProperties['alt'] = altValue;
-1 3071
-1 3072 var src = element.src;
-1 3073 if (typeof src == 'string') {
-1 3074 var parts = src.split('/');
-1 3075 var filename = parts.pop();
-1 3076 var filenameValue = { text: filename };
-1 3077 textProperties['filename'] = filenameValue;
-1 3078 computedName = filename;
-1 3079 }
-1 3080 }
-1 3081
-1 3082 if (!computedName)
-1 3083 return null;
-1 3084 }
-1 3085
-1 3086 textProperties.hasProperties = Boolean(Object.keys(textProperties).length);
-1 3087 textProperties.computedText = computedName;
-1 3088 textProperties.lastWord = axs.properties.getLastWord(computedName);
-1 3089 return textProperties;
-1 3090 };
-1 3091
-1 3092 /**
-1 3093 * Finds any ARIA attributes (roles, states and properties) explicitly set on this element.
-1 3094 * @param {Element} element
-1 3095 * @return {Object}
-1 3096 */
-1 3097 axs.properties.getAriaProperties = function(element) {
-1 3098 var ariaProperties = {};
-1 3099 var statesAndProperties = axs.properties.getGlobalAriaProperties(element);
-1 3100
-1 3101 for (var property in axs.constants.ARIA_PROPERTIES) {
-1 3102 var attributeName = 'aria-' + property;
-1 3103 if (element.hasAttribute(attributeName)) {
-1 3104 var propertyValue = element.getAttribute(attributeName);
-1 3105 statesAndProperties[attributeName] =
-1 3106 axs.utils.getAriaPropertyValue(attributeName, propertyValue, element);
-1 3107 }
-1 3108 }
-1 3109 if (Object.keys(statesAndProperties).length > 0)
-1 3110 ariaProperties['properties'] = axs.utils.values(statesAndProperties);
-1 3111
-1 3112 var roles = axs.utils.getRoles(element);
-1 3113 if (!roles) {
-1 3114 if (Object.keys(ariaProperties).length)
-1 3115 return ariaProperties;
-1 3116 return null;
-1 3117 }
-1 3118 ariaProperties['roles'] = roles;
-1 3119 if (!roles.valid || !roles['roles'])
-1 3120 return ariaProperties;
-1 3121
-1 3122 var roleDetails = roles['roles'];
-1 3123 for (var i = 0; i < roleDetails.length; i++) {
-1 3124 var role = roleDetails[i];
-1 3125 if (!role.details || !role.details.propertiesSet)
-1 3126 continue;
-1 3127 for (var property in role.details.propertiesSet) {
-1 3128 if (property in statesAndProperties)
-1 3129 continue;
-1 3130 if (element.hasAttribute(property)) {
-1 3131 var propertyValue = element.getAttribute(property);
-1 3132 statesAndProperties[property] =
-1 3133 axs.utils.getAriaPropertyValue(property, propertyValue, element);
-1 3134 if ('values' in statesAndProperties[property]) {
-1 3135 var values = statesAndProperties[property].values;
-1 3136 values[values.length - 1].isLast = true;
-1 3137 }
-1 3138 } else if (role.details.requiredPropertiesSet[property]) {
-1 3139 statesAndProperties[property] =
-1 3140 { 'name': property, 'valid': false, 'reason': 'Required property not set' };
-1 3141 }
-1 3142 }
-1 3143 }
-1 3144 if (Object.keys(statesAndProperties).length > 0)
-1 3145 ariaProperties['properties'] = axs.utils.values(statesAndProperties);
-1 3146 if (Object.keys(ariaProperties).length > 0)
-1 3147 return ariaProperties;
-1 3148 return null;
-1 3149 };
-1 3150
-1 3151 /**
-1 3152 * Gets the ARIA properties found on this element which apply to all elements, not just elements with ARIA roles.
-1 3153 * @param {Element} element
-1 3154 * @return {!Object}
-1 3155 */
-1 3156 axs.properties.getGlobalAriaProperties = function(element) {
-1 3157 var globalProperties = {};
-1 3158 for (var property in axs.constants.GLOBAL_PROPERTIES) {
-1 3159 if (element.hasAttribute(property)) {
-1 3160 var propertyValue = element.getAttribute(property);
-1 3161 globalProperties[property] =
-1 3162 axs.utils.getAriaPropertyValue(property, propertyValue, element);
-1 3163 }
-1 3164 }
-1 3165 return globalProperties;
-1 3166 };
-1 3167
-1 3168 /**
-1 3169 * @param {Element} element
-1 3170 * @return {Object.<string, Object>}
-1 3171 */
-1 3172 axs.properties.getVideoProperties = function(element) {
-1 3173 var videoSelector = 'video';
-1 3174 if (!axs.browserUtils.matchSelector(element, videoSelector))
-1 3175 return null;
-1 3176 var videoProperties = {};
-1 3177 videoProperties['captionTracks'] = axs.properties.getTrackElements(element, 'captions');
-1 3178 videoProperties['descriptionTracks'] = axs.properties.getTrackElements(element, 'descriptions');
-1 3179 videoProperties['chapterTracks'] = axs.properties.getTrackElements(element, 'chapters');
-1 3180 // error if no text alternatives?
-1 3181 return videoProperties;
-1 3182 };
-1 3183
-1 3184 /**
-1 3185 * @param {Element} element
-1 3186 * @param {string} kind
-1 3187 * @return {Object}
-1 3188 */
-1 3189 axs.properties.getTrackElements = function(element, kind) {
-1 3190 // error if resource is not available
-1 3191 var trackElements = element.querySelectorAll('track[kind=' + kind + ']');
-1 3192 var result = {};
-1 3193 if (!trackElements.length) {
-1 3194 result.valid = false;
-1 3195 result.reason = { 'messageKey': 'noTracksProvided', 'args': [[kind]] };
-1 3196 return result;
-1 3197 }
-1 3198 result.valid = true;
-1 3199 var values = [];
-1 3200 for (var i = 0; i < trackElements.length; i++) {
-1 3201 var trackElement = {};
-1 3202 var src = trackElements[i].getAttribute('src');
-1 3203 var srcLang = trackElements[i].getAttribute('srcLang');
-1 3204 var label = trackElements[i].getAttribute('label');
-1 3205 if (!src) {
-1 3206 trackElement.valid = false;
-1 3207 trackElement.reason = { 'messageKey': 'noSrcProvided' };
-1 3208 } else {
-1 3209 trackElement.valid = true;
-1 3210 trackElement.src = src;
-1 3211 }
-1 3212 var name = '';
-1 3213 if (label) {
-1 3214 name += label;
-1 3215 if (srcLang)
-1 3216 name += ' ';
-1 3217 }
-1 3218 if (srcLang)
-1 3219 name += '(' + srcLang + ')';
-1 3220 if (name == '')
-1 3221 name = '[' + { 'messageKey': 'unnamed' } + ']';
-1 3222 trackElement.name = name;
-1 3223 values.push(trackElement);
-1 3224 }
-1 3225 result.values = values;
-1 3226 return result;
-1 3227 };
-1 3228
-1 3229 /**
-1 3230 * @param {Node} node
-1 3231 * @return {Object.<string, Object>}
-1 3232 */
-1 3233 axs.properties.getAllProperties = function(node) {
-1 3234 /** @type {Element} */ var element = axs.dom.asElement(node);
-1 3235 if (!element)
-1 3236 return {};
-1 3237
-1 3238 var allProperties = {};
-1 3239 allProperties['ariaProperties'] = axs.properties.getAriaProperties(element);
-1 3240 allProperties['colorProperties'] = axs.properties.getColorProperties(element);
-1 3241 allProperties['focusProperties'] = axs.properties.getFocusProperties(element);
-1 3242 allProperties['textProperties'] = axs.properties.getTextProperties(node);
-1 3243 allProperties['videoProperties'] = axs.properties.getVideoProperties(element);
-1 3244 return allProperties;
-1 3245 };
-1 3246
-1 3247 (function() {
-1 3248 /**
-1 3249 * Helper for implicit semantic functionality.
-1 3250 * Can be made part of the public API if need be.
-1 3251 * @param {Element} element
-1 3252 * @return {?axs.constants.HtmlInfo}
-1 3253 */
-1 3254 function getHtmlInfo(element) {
-1 3255 if (!element)
-1 3256 return null;
-1 3257 var tagName = element.tagName;
-1 3258 if (!tagName)
-1 3259 return null;
-1 3260 tagName = tagName.toUpperCase();
-1 3261 var infos = axs.constants.TAG_TO_IMPLICIT_SEMANTIC_INFO[tagName];
-1 3262 if (!infos || !infos.length)
-1 3263 return null;
-1 3264 var defaultInfo = null; // will contain the info with no specific selector if no others match
-1 3265 for (var i = 0, len = infos.length; i < len; i++) {
-1 3266 var htmlInfo = infos[i];
-1 3267 if (htmlInfo.selector) {
-1 3268 if (axs.browserUtils.matchSelector(element, htmlInfo.selector))
-1 3269 return htmlInfo;
-1 3270 } else {
-1 3271 defaultInfo = htmlInfo;
-1 3272 }
-1 3273 }
-1 3274 return defaultInfo;
-1 3275 }
-1 3276
-1 3277 /**
-1 3278 * @param {Element} element
-1 3279 * @return {string} role
-1 3280 */
-1 3281 axs.properties.getImplicitRole = function(element) {
-1 3282 var htmlInfo = getHtmlInfo(element);
-1 3283 if (htmlInfo)
-1 3284 return htmlInfo.role;
-1 3285 return '';
-1 3286 };
-1 3287
-1 3288 /**
-1 3289 * Determine if this element can take ANY ARIA attributes including roles, state and properties.
-1 3290 * If false then even global attributes should not be used.
-1 3291 * @param {Element} element
-1 3292 * @return {boolean}
-1 3293 */
-1 3294 axs.properties.canTakeAriaAttributes = function(element) {
-1 3295 var htmlInfo = getHtmlInfo(element);
-1 3296 if (htmlInfo)
-1 3297 return !htmlInfo.reserved;
-1 3298 return true;
-1 3299 };
-1 3300 })();
-1 3301
-1 3302 /**
-1 3303 * This lists the ARIA attributes that are supported implicitly by native properties of this element.
-1 3304 *
-1 3305 * @param {Element} element The element to check.
-1 3306 * @return {!Array.<string>} An array of ARIA attributes.
-1 3307 *
-1 3308 * example:
-1 3309 * var element = document.createElement("input");
-1 3310 * element.setAttribute("type", "range");
-1 3311 * var supported = axs.properties.getNativelySupportedAttributes(element); // an array of ARIA attributes
-1 3312 * console.log(supported.indexOf("aria-valuemax") >=0); // logs 'true'
-1 3313 */
-1 3314 axs.properties.getNativelySupportedAttributes = function(element) {
-1 3315 var result = [];
-1 3316 if (!element) {
-1 3317 return result;
-1 3318 }
-1 3319 var testElement = element.cloneNode(false); // gets rid of expandos
-1 3320 var ariaAttributes = Object.keys(/** @type {!Object} */(axs.constants.ARIA_TO_HTML_ATTRIBUTE));
-1 3321 for (var i = 0; i < ariaAttributes.length; i++) {
-1 3322 var ariaAttribute = ariaAttributes[i];
-1 3323 var nativeAttribute = axs.constants.ARIA_TO_HTML_ATTRIBUTE[ariaAttribute];
-1 3324 if (nativeAttribute in testElement) {
-1 3325 result[result.length] = ariaAttribute;
-1 3326 }
-1 3327 }
-1 3328 return result;
-1 3329 };
-1 3330
-1 3331 (function() {
-1 3332 var roleToSelectorCache = {}; // performance optimization, cache results from getSelectorForRole
-1 3333
-1 3334 /**
-1 3335 * Build a selector that will match elements which implicity or explicitly have this role.
-1 3336 * Note that the selector will probably not look elegant but it will work.
-1 3337 * @param {string} role
-1 3338 * @return {string} selector
-1 3339 */
-1 3340 axs.properties.getSelectorForRole = function(role) {
-1 3341 if (!role)
-1 3342 return '';
-1 3343 if (roleToSelectorCache[role] && roleToSelectorCache.hasOwnProperty(role))
-1 3344 return roleToSelectorCache[role];
-1 3345 var selectors = ['[role="' + role + '"]'];
-1 3346 var tagNames = Object.keys(/** @type {!Object} */(axs.constants.TAG_TO_IMPLICIT_SEMANTIC_INFO));
-1 3347 tagNames.forEach(function(tagName) {
-1 3348 var htmlInfos = axs.constants.TAG_TO_IMPLICIT_SEMANTIC_INFO[tagName];
-1 3349 if (htmlInfos && htmlInfos.length) {
-1 3350 for (var i = 0; i < htmlInfos.length; i++) {
-1 3351 var htmlInfo = htmlInfos[i];
-1 3352 if (htmlInfo.role === role) {
-1 3353 if (htmlInfo.selector) {
-1 3354 selectors[selectors.length] = htmlInfo.selector;
-1 3355 } else {
-1 3356 selectors[selectors.length] = tagName; // Selectors API is not case sensitive.
-1 3357 break; // No need to continue adding selectors since we will match the tag itself.
-1 3358 }
-1 3359 }
-1 3360 }
-1 3361 }
-1 3362 });
-1 3363 return (roleToSelectorCache[role] = selectors.join(','));
-1 3364 };
-1 3365 })();
-1 3366
-1 3367 },{}],8:[function(require,module,exports){
-1 3368 var query = require('./lib/query.js');
-1 3369 var name = require('./lib/name.js');
-1 3370
-1 3371 module.exports = {
-1 3372 getRole: query.getRole,
-1 3373 getAttribute: query.getAttribute,
-1 3374 getName: name.getName,
-1 3375 getDescription: name.getDescription,
-1 3376
-1 3377 matches: query.matches,
-1 3378 querySelector: query.querySelector,
-1 3379 querySelectorAll: query.querySelectorAll,
-1 3380 closest: query.closest,
-1 3381 };
-1 3382
-1 3383 },{"./lib/name.js":10,"./lib/query.js":11}],9:[function(require,module,exports){
-1 3384 exports.attributes = {
-1 3385 // widget
-1 3386 'autocomplete': 'token',
-1 3387 'checked': 'tristate',
-1 3388 'current': 'token',
-1 3389 'disabled': 'bool',
-1 3390 'expanded': 'bool-undefined',
-1 3391 'haspopup': 'token',
-1 3392 'hidden': 'bool', // !
-1 3393 'invalid': 'token',
-1 3394 'keyshortcuts': 'string',
-1 3395 'label': 'string',
-1 3396 'level': 'int',
-1 3397 'modal': 'bool',
-1 3398 'multiline': 'bool',
-1 3399 'multiselectable': 'bool',
-1 3400 'orientation': 'token',
-1 3401 'placeholder': 'string',
-1 3402 'pressed': 'tristate',
-1 3403 'readonly': 'bool',
-1 3404 'required': 'bool',
-1 3405 'roledescription': 'string',
-1 3406 'selected': 'bool-undefined',
-1 3407 'valuemax': 'number',
-1 3408 'valuemin': 'number',
-1 3409 'valuenow': 'number',
-1 3410 'valuetext': 'string',
-1 3411
-1 3412 // live
-1 3413 'atomic': 'bool',
-1 3414 'busy': 'bool',
-1 3415 'live': 'token',
-1 3416 'relevant': 'token-list',
-1 3417
-1 3418 // dragndrop
-1 3419 'dropeffect': 'token-list',
-1 3420 'grabbed': 'bool-undefined',
-1 3421
-1 3422 // relationship
-1 3423 'activedescendant': 'id',
-1 3424 'colcount': 'int',
-1 3425 'colindex': 'int',
-1 3426 'colspan': 'int',
-1 3427 'controls': 'id-list',
-1 3428 'describedby': 'id-list',
-1 3429 'details': 'id',
-1 3430 'errormessage': 'id',
-1 3431 'flowto': 'id-list',
-1 3432 'labelledby': 'id-list',
-1 3433 'owns': 'id-list',
-1 3434 'posinset': 'int',
-1 3435 'rowcount': 'int',
-1 3436 'rowindex': 'int',
-1 3437 'rowspan': 'int',
-1 3438 'setsize': 'int',
-1 3439 'sort': 'token',
-1 3440 };
-1 3441
-1 3442 // https://www.w3.org/TR/html-aria/#docconformance
-1 3443 exports.extraSelectors = {
-1 3444 article: ['article'],
-1 3445 button: [
-1 3446 'button',
-1 3447 'input[type="button"]',
-1 3448 'input[type="image"]',
-1 3449 'input[type="reset"]',
-1 3450 'input[type="submit"]',
-1 3451 'summary',
-1 3452 ],
-1 3453 cell: ['td'],
-1 3454 checkbox: ['input[type="checkbox"]'],
-1 3455 combobox: [
-1 3456 'input[type="email"][list]',
-1 3457 'input[type="search"][list]',
-1 3458 'input[type="tel"][list]',
-1 3459 'input[type="text"][list]',
-1 3460 'input[type="url"][list]',
-1 3461 ],
-1 3462 complementary: ['aside'],
-1 3463 definition: ['dd'],
-1 3464 dialog: ['dialog'],
-1 3465 document: ['body'],
-1 3466 figure: ['figure'],
-1 3467 form: ['form[aria-label]', 'form[aria-labelledby]'],
-1 3468 group: ['details', 'optgroup'],
-1 3469 heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
-1 3470 img: ['img:not([alt=""])'],
-1 3471 link: ['a[href]', 'area[href]', 'link[href]'],
-1 3472 list: ['dl', 'ol', 'ul'],
-1 3473 listitem: ['dt', 'ul > li', 'ol > li'],
-1 3474 main: ['main'],
-1 3475 math: ['math'],
-1 3476 menuitemcheckbox: ['menuitem[type="checkbox"]'],
-1 3477 menuitem: ['menuitem[type="command"]'],
-1 3478 menuitemradio: ['menuitem[type="radio"]'],
-1 3479 menu: ['menu[type="context"]'],
-1 3480 navigation: ['nav'],
-1 3481 option: ['option'],
-1 3482 progressbar: ['progress'],
-1 3483 radio: ['input[type="radio"]'],
-1 3484 region: ['section'],
-1 3485 rowgroup: ['tbody', 'thead', 'tfoot'],
-1 3486 row: ['tr'],
-1 3487 searchbox: ['input[type="search"]:not([list])'],
-1 3488 separator: ['hr'],
-1 3489 slider: ['input[type="range"]'],
-1 3490 spinbutton: ['input[type="number"]'],
-1 3491 status: ['output'],
-1 3492 table: ['table'],
-1 3493 textbox: [
-1 3494 'input[type="email"]:not([list])',
-1 3495 'input[type="tel"]:not([list])',
-1 3496 'input[type="text"]:not([list])',
-1 3497 'input[type="url"]:not([list])',
-1 3498 'textarea',
-1 3499 ],
-1 3500
-1 3501 // if scope is missing, it is calculated automatically
-1 3502 rowheader: ['th[scope="row"]'],
-1 3503 columnheader: ['th[scope="col"]'],
-1 3504 };
-1 3505
-1 3506 exports.scoped = [
-1 3507 'article *', 'aside *', 'main *', 'nav *', 'section *',
-1 3508 ].join(',');
-1 3509
-1 3510 // https://www.w3.org/TR/wai-aria/roles
-1 3511 var subRoles = {
-1 3512 cell: ['gridcell', 'rowheader'],
-1 3513 command: ['button', 'link', 'menuitem'],
-1 3514 composite: ['grid', 'select', 'spinbutton', 'tablist'],
-1 3515 img: ['doc-cover'],
-1 3516 input: ['checkbox', 'option', 'radio', 'slider', 'spinbutton', 'textbox'],
-1 3517 landmark: [
-1 3518 'banner',
-1 3519 'complementary',
-1 3520 'contentinfo',
-1 3521 'doc-acknowledgments',
-1 3522 'doc-afterword',
-1 3523 'doc-appendix',
-1 3524 'doc-bibliography',
-1 3525 'doc-chapter',
-1 3526 'doc-conclusion',
-1 3527 'doc-credits',
-1 3528 'doc-endnotes',
-1 3529 'doc-epilogue',
-1 3530 'doc-errata',
-1 3531 'doc-foreword',
-1 3532 'doc-glossary',
-1 3533 'doc-introduction',
-1 3534 'doc-part',
-1 3535 'doc-preface',
-1 3536 'doc-prologue',
-1 3537 'form',
-1 3538 'main',
-1 3539 'navigation',
-1 3540 'region',
-1 3541 'search',
-1 3542 ],
-1 3543 range: ['progressbar', 'scrollbar', 'slider', 'spinbutton'],
-1 3544 roletype: ['structure', 'widget', 'window'],
-1 3545 section: [
-1 3546 'alert',
-1 3547 'cell',
-1 3548 'definition',
-1 3549 'doc-abstract',
-1 3550 'doc-colophon',
-1 3551 'doc-credit',
-1 3552 'doc-dedication',
-1 3553 'doc-epigraph',
-1 3554 'doc-example',
-1 3555 'doc-footnote',
-1 3556 'doc-qna',
-1 3557 'figure',
-1 3558 'group',
-1 3559 'img',
-1 3560 'landmark',
-1 3561 'list',
-1 3562 'listitem',
-1 3563 'log',
-1 3564 'marquee',
-1 3565 'math',
-1 3566 'note',
-1 3567 'status',
-1 3568 'table',
-1 3569 'tabpanel',
-1 3570 'term',
-1 3571 'tooltip',
-1 3572 ],
-1 3573 sectionhead: [
-1 3574 'columnheader',
-1 3575 'doc-subtitle',
-1 3576 'heading',
-1 3577 'rowheader',
-1 3578 'tab',
-1 3579 ],
-1 3580 select: ['combobox', 'listbox', 'menu', 'radiogroup', 'tree'],
-1 3581 separator: ['doc-pagebreak'],
-1 3582 structure: [
-1 3583 'application',
-1 3584 'document',
-1 3585 'none',
-1 3586 'presentation',
-1 3587 'rowgroup',
-1 3588 'section',
-1 3589 'sectionhead',
-1 3590 'separator',
-1 3591 ],
-1 3592 table: ['grid'],
-1 3593 textbox: ['searchbox'],
-1 3594 widget: [
-1 3595 'command',
-1 3596 'composite',
-1 3597 'gridcell',
-1 3598 'input',
-1 3599 'range',
-1 3600 'row',
-1 3601 'separator',
-1 3602 'tab',
-1 3603 ],
-1 3604 window: ['dialog'],
-1 3605 alert: ['alertdialog'],
-1 3606 checkbox: ['menuitemcheckbox', 'switch'],
-1 3607 dialog: ['alertdialog'],
-1 3608 gridcell: ['columnheader', 'rowheader'],
-1 3609 menuitem: ['menuitemcheckbox'],
-1 3610 menuitemcheckbox: ['menuitemradio'],
-1 3611 option: ['treeitem'],
-1 3612 radio: ['menuitemradio'],
-1 3613 status: ['timer'],
-1 3614 grid: ['treegrid'],
-1 3615 menu: ['menubar'],
-1 3616 tree: ['treegrid'],
-1 3617 document: ['article'],
-1 3618 group: ['row', 'select', 'toolbar'],
-1 3619 link: ['doc-backlink', 'doc-biblioref', 'doc-glossref', 'doc-noteref'],
-1 3620 list: ['directory', 'feed'],
-1 3621 listitem: ['doc-biblioentry', 'doc-endnote', 'treeitem'],
-1 3622 navigation: ['doc-index', 'doc-pagelist', 'doc-toc'],
-1 3623 note: ['doc-notice', 'doc-tip'],
-1 3624 };
-1 3625
-1 3626 var getSubRoles = function(role) {
-1 3627 var children = subRoles[role] || [];
-1 3628 var descendents = children.map(getSubRoles);
-1 3629
-1 3630 var result = [role];
-1 3631
-1 3632 descendents.forEach(function(list) {
-1 3633 list.forEach(function(r) {
-1 3634 if (result.indexOf(r) === -1) {
-1 3635 result.push(r);
-1 3636 }
-1 3637 });
-1 3638 });
-1 3639
-1 3640 return result;
-1 3641 };
-1 3642
-1 3643 exports.subRoles = {};
-1 3644 for (var role in subRoles) {
-1 3645 exports.subRoles[role] = getSubRoles(role);
-1 3646 }
-1 3647
-1 3648 exports.nameFromContents = [
-1 3649 'button',
-1 3650 'checkbox',
-1 3651 'columnheader',
-1 3652 'doc-backlink',
-1 3653 'doc-biblioref',
-1 3654 'doc-glossref',
-1 3655 'doc-noteref',
-1 3656 'gridcell',
-1 3657 'heading',
-1 3658 'link',
-1 3659 'menuitem',
-1 3660 'menuitemcheckbox',
-1 3661 'menuitemradio',
-1 3662 'option',
-1 3663 'radio',
-1 3664 'row',
-1 3665 'rowgroup',
-1 3666 'rowheader',
-1 3667 'sectionhead',
-1 3668 'tab',
-1 3669 'tooltip',
-1 3670 'treeitem',
-1 3671 'switch',
-1 3672 ];
-1 3673
-1 3674 exports.labelable = [
-1 3675 'button',
-1 3676 'input:not([type="hidden"])',
-1 3677 'keygen',
-1 3678 'meter',
-1 3679 'output',
-1 3680 'progress',
-1 3681 'select',
-1 3682 'textarea',
-1 3683 ];
-1 3684
-1 3685 },{}],10:[function(require,module,exports){
-1 3686 var constants = require('./constants.js');
-1 3687 var query = require('./query.js');
-1 3688
-1 3689 var getPseudoContent = function(node, selector) {
-1 3690 var styles = window.getComputedStyle(node, selector);
-1 3691 var ret = styles.getPropertyValue('content');
-1 3692 if (ret === 'none' || ret.substr(0, 4) === '-moz') {
-1 3693 return '';
-1 3694 } else {
-1 3695 return ret
-1 3696 .replace(/^["']/, '')
-1 3697 .replace(/["']$/, '');
-1 3698 }
-1 3699 };
-1 3700
-1 3701 var getContent = function(root, referenced) {
-1 3702 var ret = getPseudoContent(root, ':before');
-1 3703 var node = root.firstChild;
-1 3704 while (node) {
-1 3705 if (node.nodeType === node.TEXT_NODE) {
-1 3706 ret += node.textContent;
-1 3707 } else if (node.nodeType === node.ELEMENT_NODE) {
-1 3708 ret += getName(node, true, referenced);
-1 3709 }
-1 3710 node = node.nextSibling;
-1 3711 }
-1 3712 ret += getPseudoContent(root, ':after');
-1 3713 return ret;
-1 3714 };
-1 3715
-1 3716 var allowNameFromContent = function(el) {
-1 3717 var role = query.getRole(el);
-1 3718 return !role || constants.nameFromContents.indexOf(role) !== -1;
-1 3719 };
-1 3720
-1 3721 var isLabelable = function(el) {
-1 3722 var selector = constants.labelable.join(',');
-1 3723 return el.matches(selector);
-1 3724 };
-1 3725
-1 3726 // Control.labels is part of the standard, but not supported in most browsers
-1 3727 var getLabelNode = function(node) {
-1 3728 if (node.id) {
-1 3729 var selector = 'label[for="' + node.id + '"]';
-1 3730 var label = document.querySelector(selector);
-1 3731 if (label) {
-1 3732 return label;
-1 3733 }
-1 3734 }
-1 3735
-1 3736 var p = node.parentNode;
-1 3737 while (p) {
-1 3738 if (p.tagName === 'LABEL') {
-1 3739 return p;
-1 3740 }
-1 3741 p = p.parentNode;
-1 3742 }
-1 3743 };
-1 3744
-1 3745 // http://www.ssbbartgroup.com/blog/how-the-w3c-text-alternative-computation-works/
-1 3746 // https://www.w3.org/TR/accname-aam-1.1/#h-mapping_additional_nd_te
-1 3747 var getName = function(el, recursive, referenced) {
-1 3748 var ret;
-1 3749
-1 3750 if (query.getAttribute(el, 'hidden', referenced)) {
-1 3751 return '';
-1 3752 }
-1 3753 if (query.matches(el, 'presentation')) {
-1 3754 return getContent(el, referenced);
-1 3755 }
-1 3756 if (!recursive && el.matches('[aria-labelledby]')) {
-1 3757 var ids = el.getAttribute('aria-labelledby').split(/\s+/);
-1 3758 var strings = ids.map(function(id) {
-1 3759 var label = document.getElementById(id);
-1 3760 return getName(label, true, label);
-1 3761 });
-1 3762 ret = strings.join(' ');
-1 3763 }
-1 3764 if (!ret && el.matches('[aria-label]')) {
-1 3765 ret = el.getAttribute('aria-label');
-1 3766 }
-1 3767 if (!query.matches(el, 'presentation')) {
-1 3768 if (!ret && isLabelable(el)) {
-1 3769 var label = getLabelNode(el);
-1 3770 if (label) {
-1 3771 ret = getName(label, recursive, label);
-1 3772 }
-1 3773 }
-1 3774 if (!ret) {
-1 3775 ret = el.getAttribute('placeholder');
-1 3776 }
-1 3777 // figcaption
-1 3778 if (!ret) {
-1 3779 ret = el.getAttribute('alt');
-1 3780 }
-1 3781 // caption
-1 3782 // table
-1 3783 }
-1 3784 if (!ret) {
-1 3785 // FIXME: distinguish different input types
-1 3786 ret = el.value;
-1 3787 }
-1 3788 if (!ret && (recursive || allowNameFromContent(el))) {
-1 3789 ret = getContent(el, referenced);
-1 3790 }
-1 3791 if (!ret) {
-1 3792 ret = el.getAttribute('title');
-1 3793 }
-1 3794
-1 3795 return (ret || '').trim().replace(/\s+/g, ' ');
-1 3796 };
-1 3797
-1 3798 var getDescription = function(el) {
-1 3799 var ret = '';
-1 3800
-1 3801 if (el.matches('[aria-describedby]')) {
-1 3802 var ids = el.getAttribute('aria-describedby').split(/\s+/);
-1 3803 var strings = ids.map(function(id) {
-1 3804 var label = document.getElementById(id);
-1 3805 return getName(label, true, label);
-1 3806 });
-1 3807 ret = strings.join(' ');
-1 3808 } else if (el.title) {
-1 3809 ret = el.title;
-1 3810 } else if (el.placeholder) {
-1 3811 ret = el.placeholder;
-1 3812 }
-1 3813
-1 3814 return ret;
-1 3815 };
-1 3816
-1 3817 module.exports = {
-1 3818 getName: getName,
-1 3819 getDescription: getDescription,
-1 3820 };
-1 3821
-1 3822 },{"./constants.js":9,"./query.js":11}],11:[function(require,module,exports){
-1 3823 var constants = require('./constants.js');
-1 3824 var util = require('./util.js');
-1 3825
-1 3826 var getSubRoles = function(roles) {
-1 3827 return [].concat.apply([], roles.map(function(role) {
-1 3828 return constants.subRoles[role] || [role];
-1 3829 }));
-1 3830 };
-1 3831
-1 3832 // candidates can be passed for performance optimization
-1 3833 var _getRole = function(el, candidates) {
-1 3834 if (el.hasAttribute('role')) {
-1 3835 return el.getAttribute('role');
-1 3836 }
-1 3837 for (var role in constants.extraSelectors) {
-1 3838 var selector = constants.extraSelectors[role].join(',');
-1 3839 if ((!candidates || candidates.indexOf(role) !== -1) && el.matches(selector)) {
-1 3840 return role;
-1 3841 }
-1 3842 }
-1 3843
-1 3844 if (!candidates ||
-1 3845 candidates.indexOf('banner') !== -1 ||
-1 3846 candidates.indexOf('contentinfo') !== -1) {
-1 3847 var scoped = el.matches(constants.scoped);
-1 3848
-1 3849 if (el.matches('header') && !scoped) {
-1 3850 return 'banner';
-1 3851 }
-1 3852 if (el.matches('footer') && !scoped) {
-1 3853 return 'contentinfo';
-1 3854 }
-1 3855 }
-1 3856 };
-1 3857
-1 3858 var getAttribute = function(el, key, _hiddenRoot) {
-1 3859 if (key === 'hidden' && el === _hiddenRoot) { // used for name calculation
-1 3860 return false;
-1 3861 }
-1 3862
-1 3863 var type = constants.attributes[key];
-1 3864 var raw = el.getAttribute('aria-' + key);
-1 3865
-1 3866 if (raw) {
-1 3867 if (type === 'bool') {
-1 3868 return raw === 'true';
-1 3869 } else if (type === 'tristate') {
-1 3870 return raw === 'true' ? true : raw === 'false' ? false : 'mixed';
-1 3871 } else if (type === 'bool-undefined') {
-1 3872 return raw === 'true' ? true : raw === 'false' ? false : undefined;
-1 3873 } else if (type === 'id-list') {
-1 3874 return raw.split(/\s+/);
-1 3875 } else if (type === 'integer') {
-1 3876 return parseInt(raw);
-1 3877 } else if (type === 'number') {
-1 3878 return parseFloat(raw);
-1 3879 } else if (type === 'token-list') {
-1 3880 return raw.split(/\s+/);
-1 3881 } else {
-1 3882 return raw;
-1 3883 }
-1 3884 }
-1 3885
-1 3886 if (key === 'level') {
-1 3887 for (var i = 1; i <= 6; i++) {
-1 3888 if (el.tagName === 'H' + i) {
-1 3889 return i;
-1 3890 }
-1 3891 }
-1 3892 } else if (key === 'disabled') {
-1 3893 return el.disabled;
-1 3894 } else if (key === 'placeholder') {
-1 3895 return el.placeholder;
-1 3896 } else if (key === 'required') {
-1 3897 return el.required;
-1 3898 } else if (key === 'readonly') {
-1 3899 return el.readOnly && !el.isContentEditable;
-1 3900 } else if (key === 'hidden') {
-1 3901 var style = window.getComputedStyle(el);
-1 3902 if (el.hidden || style.display === 'none' || style.visibility === 'hidden') {
-1 3903 return true;
-1 3904 } else if (el.clientHeight === 0) { // rough check for performance
-1 3905 return el.parentNode && getAttribute(el.parentNode, 'hidden', _hiddenRoot);
-1 3906 }
-1 3907 } else if (key === 'invalid' && el.checkValidity) {
-1 3908 return el.checkValidity();
-1 3909 }
-1 3910
-1 3911 if (type === 'bool' || type === 'tristate') {
-1 3912 return false;
-1 3913 }
-1 3914 };
-1 3915
-1 3916 var matches = function(el, selector) {
-1 3917 var actual;
-1 3918
-1 3919 if (selector.substr(0, 1) === ':') {
-1 3920 var attr = selector.substr(1);
-1 3921 return getAttribute(el, attr);
-1 3922 } else if (selector.substr(0, 1) === '[') {
-1 3923 var match = /\[([a-z]+)="(.*)"\]/.exec(selector);
-1 3924 actual = getAttribute(el, match[1]);
-1 3925 var rawValue = match[2];
-1 3926 return actual.toString() == rawValue;
-1 3927 } else {
-1 3928 var candidates = getSubRoles(selector.split(','));
-1 3929 actual = _getRole(el, candidates);
-1 3930 return candidates.indexOf(actual) != -1;
-1 3931 }
-1 3932 };
-1 3933
-1 3934 var _querySelector = function(all) {
-1 3935 return function(root, role) {
-1 3936 var results = [];
-1 3937 util.walkDOM(root, function(node) {
-1 3938 if (node.nodeType === node.ELEMENT_NODE) {
-1 3939 // FIXME: skip hidden elements
-1 3940 if (matches(node, role)) {
-1 3941 results.push(node);
-1 3942 if (!all) {
-1 3943 return false;
-1 3944 }
-1 3945 }
-1 3946 }
-1 3947 });
-1 3948 return all ? results : results[0];
-1 3949 };
-1 3950 };
-1 3951
-1 3952 var closest = function(el, selector) {
-1 3953 return util.searchUp(el, function(candidate) {
-1 3954 return matches(candidate, selector);
-1 3955 });
-1 3956 };
-1 3957
-1 3958 module.exports = {
-1 3959 getRole: function(el) {
-1 3960 return _getRole(el);
-1 3961 },
-1 3962 getAttribute: getAttribute,
-1 3963 matches: matches,
-1 3964 querySelector: _querySelector(),
-1 3965 querySelectorAll: _querySelector(true),
-1 3966 closest: closest,
-1 3967 };
-1 3968
-1 3969 },{"./constants.js":9,"./util.js":12}],12:[function(require,module,exports){
-1 3970 var walkDOM = function(root, fn) {
-1 3971 if (fn(root) === false) {
-1 3972 return false;
-1 3973 }
-1 3974 var node = root.firstChild;
-1 3975 while (node) {
-1 3976 if (walkDOM(node, fn) === false) {
-1 3977 return false;
-1 3978 }
-1 3979 node = node.nextSibling;
-1 3980 }
-1 3981 };
-1 3982
-1 3983 var searchUp = function(el, test) {
-1 3984 var candidate = el.parentElement;
-1 3985 if (candidate) {
-1 3986 if (test(candidate)) {
-1 3987 return candidate;
-1 3988 } else {
-1 3989 return searchUp(candidate, test);
-1 3990 }
-1 3991 }
-1 3992 };
-1 3993
-1 3994 module.exports = {
-1 3995 walkDOM: walkDOM,
-1 3996 searchUp: searchUp,
-1 3997 };
-1 3998
-1 3999 },{}],13:[function(require,module,exports){
-1 4000 /*! aXe v2.6.1
-1 4001 * Copyright (c) 2017 Deque Systems, Inc.
-1 4002 *
-1 4003 * Your use of this Source Code Form is subject to the terms of the Mozilla Public
-1 4004 * License, v. 2.0. If a copy of the MPL was not distributed with this
-1 4005 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
-1 4006 *
-1 4007 * This entire copyright notice must appear in every copy of this file you
-1 4008 * distribute or in any file that contains substantial portions of this source
-1 4009 * code.
-1 4010 */
-1 4011 (function axeFunction(window) {
-1 4012 var global = window;
-1 4013 var document = window.document;
-1 4014 'use strict';
-1 4015 var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-1 4016 return typeof obj;
-1 4017 } : function(obj) {
-1 4018 return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-1 4019 };
-1 4020 var axe = axe || {};
-1 4021 axe.version = '2.6.1';
-1 4022 if (typeof define === 'function' && define.amd) {
-1 4023 define([], function() {
-1 4024 'use strict';
-1 4025 return axe;
-1 4026 });
-1 4027 }
-1 4028 if ((typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object' && module.exports && typeof axeFunction.toString === 'function') {
-1 4029 axe.source = '(' + axeFunction.toString() + ')(typeof window === "object" ? window : this);';
-1 4030 module.exports = axe;
-1 4031 }
-1 4032 if (typeof window.getComputedStyle === 'function') {
-1 4033 window.axe = axe;
-1 4034 }
-1 4035 var commons;
-1 4036 function SupportError(error) {
-1 4037 this.name = 'SupportError';
-1 4038 this.cause = error.cause;
-1 4039 this.message = '`' + error.cause + '` - feature unsupported in your environment.';
-1 4040 if (error.ruleId) {
-1 4041 this.ruleId = error.ruleId;
-1 4042 this.message += ' Skipping ' + this.ruleId + ' rule.';
-1 4043 }
-1 4044 this.stack = new Error().stack;
-1 4045 }
-1 4046 SupportError.prototype = Object.create(Error.prototype);
-1 4047 SupportError.prototype.constructor = SupportError;
-1 4048 'use strict';
-1 4049 var utils = axe.utils = {};
-1 4050 'use strict';
-1 4051 var helpers = {};
-1 4052 'use strict';
-1 4053 var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-1 4054 return typeof obj;
-1 4055 } : function(obj) {
-1 4056 return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-1 4057 };
-1 4058 function getDefaultConfiguration(audit) {
-1 4059 'use strict';
-1 4060 var config;
-1 4061 if (audit) {
-1 4062 config = axe.utils.clone(audit);
-1 4063 config.commons = audit.commons;
-1 4064 } else {
-1 4065 config = {};
-1 4066 }
-1 4067 config.reporter = config.reporter || null;
-1 4068 config.rules = config.rules || [];
-1 4069 config.checks = config.checks || [];
-1 4070 config.data = Object.assign({
-1 4071 checks: {},
-1 4072 rules: {}
-1 4073 }, config.data);
-1 4074 return config;
-1 4075 }
-1 4076 function unpackToObject(collection, audit, method) {
-1 4077 'use strict';
-1 4078 var i, l;
-1 4079 for (i = 0, l = collection.length; i < l; i++) {
-1 4080 audit[method](collection[i]);
-1 4081 }
-1 4082 }
-1 4083 function Audit(audit) {
-1 4084 this.brand = 'axe';
-1 4085 this.application = 'axeAPI';
-1 4086 this.tagExclude = [ 'experimental' ];
-1 4087 this.defaultConfig = audit;
-1 4088 this._init();
-1 4089 }
-1 4090 Audit.prototype._init = function() {
-1 4091 var audit = getDefaultConfiguration(this.defaultConfig);
-1 4092 axe.commons = commons = audit.commons;
-1 4093 this.reporter = audit.reporter;
-1 4094 this.commands = {};
-1 4095 this.rules = [];
-1 4096 this.checks = {};
-1 4097 unpackToObject(audit.rules, this, 'addRule');
-1 4098 unpackToObject(audit.checks, this, 'addCheck');
-1 4099 this.data = {};
-1 4100 this.data.checks = audit.data && audit.data.checks || {};
-1 4101 this.data.rules = audit.data && audit.data.rules || {};
-1 4102 this.data.failureSummaries = audit.data && audit.data.failureSummaries || {};
-1 4103 this.data.incompleteFallbackMessage = audit.data && audit.data.incompleteFallbackMessage || '';
-1 4104 this._constructHelpUrls();
-1 4105 };
-1 4106 Audit.prototype.registerCommand = function(command) {
-1 4107 'use strict';
-1 4108 this.commands[command.id] = command.callback;
-1 4109 };
-1 4110 Audit.prototype.addRule = function(spec) {
-1 4111 'use strict';
-1 4112 if (spec.metadata) {
-1 4113 this.data.rules[spec.id] = spec.metadata;
-1 4114 }
-1 4115 var rule = this.getRule(spec.id);
-1 4116 if (rule) {
-1 4117 rule.configure(spec);
-1 4118 } else {
-1 4119 this.rules.push(new Rule(spec, this));
-1 4120 }
-1 4121 };
-1 4122 Audit.prototype.addCheck = function(spec) {
-1 4123 'use strict';
-1 4124 var metadata = spec.metadata;
-1 4125 if ((typeof metadata === 'undefined' ? 'undefined' : _typeof(metadata)) === 'object') {
-1 4126 this.data.checks[spec.id] = metadata;
-1 4127 if (_typeof(metadata.messages) === 'object') {
-1 4128 Object.keys(metadata.messages).filter(function(prop) {
-1 4129 return metadata.messages.hasOwnProperty(prop) && typeof metadata.messages[prop] === 'string';
-1 4130 }).forEach(function(prop) {
-1 4131 if (metadata.messages[prop].indexOf('function') === 0) {
-1 4132 metadata.messages[prop] = new Function('return ' + metadata.messages[prop] + ';')();
-1 4133 }
-1 4134 });
-1 4135 }
-1 4136 }
-1 4137 if (this.checks[spec.id]) {
-1 4138 this.checks[spec.id].configure(spec);
-1 4139 } else {
-1 4140 this.checks[spec.id] = new Check(spec);
-1 4141 }
-1 4142 };
-1 4143 Audit.prototype.run = function(context, options, resolve, reject) {
-1 4144 'use strict';
-1 4145 this.validateOptions(options);
-1 4146 var q = axe.utils.queue();
-1 4147 this.rules.forEach(function(rule) {
-1 4148 if (axe.utils.ruleShouldRun(rule, context, options)) {
-1 4149 if (options.performanceTimer) {
-1 4150 var markEnd = 'mark_rule_end_' + rule.id;
-1 4151 var markStart = 'mark_rule_start_' + rule.id;
-1 4152 axe.utils.performanceTimer.mark(markStart);
-1 4153 }
-1 4154 q.defer(function(res, rej) {
-1 4155 rule.run(context, options, function(out) {
-1 4156 if (options.performanceTimer) {
-1 4157 axe.utils.performanceTimer.mark(markEnd);
-1 4158 axe.utils.performanceTimer.measure('rule_' + rule.id, markStart, markEnd);
-1 4159 }
-1 4160 res(out);
-1 4161 }, function(err) {
-1 4162 if (!options.debug) {
-1 4163 var errResult = Object.assign(new RuleResult(rule), {
-1 4164 result: axe.constants.CANTTELL,
-1 4165 description: 'An error occured while running this rule',
-1 4166 message: err.message,
-1 4167 stack: err.stack,
-1 4168 error: err
-1 4169 });
-1 4170 res(errResult);
-1 4171 } else {
-1 4172 rej(err);
-1 4173 }
-1 4174 });
-1 4175 });
-1 4176 }
-1 4177 });
-1 4178 q.then(function(results) {
-1 4179 resolve(results.filter(function(result) {
-1 4180 return !!result;
-1 4181 }));
-1 4182 }).catch(reject);
-1 4183 };
-1 4184 Audit.prototype.after = function(results, options) {
-1 4185 'use strict';
-1 4186 var rules = this.rules;
-1 4187 return results.map(function(ruleResult) {
-1 4188 var rule = axe.utils.findBy(rules, 'id', ruleResult.id);
-1 4189 return rule.after(ruleResult, options);
-1 4190 });
-1 4191 };
-1 4192 Audit.prototype.getRule = function(ruleId) {
-1 4193 return this.rules.find(function(rule) {
-1 4194 return rule.id === ruleId;
-1 4195 });
-1 4196 };
-1 4197 Audit.prototype.validateOptions = function(options) {
-1 4198 'use strict';
-1 4199 var audit = this;
-1 4200 if (_typeof(options.runOnly) === 'object') {
-1 4201 var only = options.runOnly;
-1 4202 if (only.type === 'rule' && Array.isArray(only.value)) {
-1 4203 only.value.forEach(function(ruleId) {
-1 4204 if (!audit.getRule(ruleId)) {
-1 4205 throw new Error('unknown rule `' + ruleId + '` in options.runOnly');
-1 4206 }
-1 4207 });
-1 4208 } else if (Array.isArray(only.value) && only.value.length > 0) {
-1 4209 var tags = [].concat(only.value);
-1 4210 audit.rules.forEach(function(rule) {
-1 4211 var tagPos, i, l;
-1 4212 if (!tags) {
-1 4213 return;
-1 4214 }
-1 4215 for (i = 0, l = rule.tags.length; i < l; i++) {
-1 4216 tagPos = tags.indexOf(rule.tags[i]);
-1 4217 if (tagPos !== -1) {
-1 4218 tags.splice(tagPos, 1);
-1 4219 }
-1 4220 }
-1 4221 });
-1 4222 if (tags.length !== 0) {
-1 4223 throw new Error('could not find tags `' + tags.join('`, `') + '`');
-1 4224 }
-1 4225 }
-1 4226 }
-1 4227 if (_typeof(options.rules) === 'object') {
-1 4228 Object.keys(options.rules).forEach(function(ruleId) {
-1 4229 if (!audit.getRule(ruleId)) {
-1 4230 throw new Error('unknown rule `' + ruleId + '` in options.rules');
-1 4231 }
-1 4232 });
-1 4233 }
-1 4234 return options;
-1 4235 };
-1 4236 Audit.prototype.setBranding = function(branding) {
-1 4237 'use strict';
-1 4238 var previous = {
-1 4239 brand: this.brand,
-1 4240 application: this.application
-1 4241 };
-1 4242 if (branding && branding.hasOwnProperty('brand') && branding.brand && typeof branding.brand === 'string') {
-1 4243 this.brand = branding.brand;
-1 4244 }
-1 4245 if (branding && branding.hasOwnProperty('application') && branding.application && typeof branding.application === 'string') {
-1 4246 this.application = branding.application;
-1 4247 }
-1 4248 this._constructHelpUrls(previous);
-1 4249 };
-1 4250 function getHelpUrl(_ref, ruleId, version) {
-1 4251 var brand = _ref.brand, application = _ref.application;
-1 4252 return axe.constants.helpUrlBase + brand + '/' + (version || axe.version.substring(0, axe.version.lastIndexOf('.'))) + '/' + ruleId + '?application=' + application;
-1 4253 }
-1 4254 Audit.prototype._constructHelpUrls = function() {
-1 4255 var _this = this;
-1 4256 var previous = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
-1 4257 var version = (axe.version.match(/^[1-9][0-9]*\.[0-9]+/) || [ 'x.y' ])[0];
-1 4258 this.rules.forEach(function(rule) {
-1 4259 if (!_this.data.rules[rule.id]) {
-1 4260 _this.data.rules[rule.id] = {};
-1 4261 }
-1 4262 var metaData = _this.data.rules[rule.id];
-1 4263 if (typeof metaData.helpUrl !== 'string' || previous && metaData.helpUrl === getHelpUrl(previous, rule.id, version)) {
-1 4264 metaData.helpUrl = getHelpUrl(_this, rule.id, version);
-1 4265 }
-1 4266 });
-1 4267 };
-1 4268 Audit.prototype.resetRulesAndChecks = function() {
-1 4269 'use strict';
-1 4270 this._init();
-1 4271 };
-1 4272 'use strict';
-1 4273 function CheckResult(check) {
-1 4274 'use strict';
-1 4275 this.id = check.id;
-1 4276 this.data = null;
-1 4277 this.relatedNodes = [];
-1 4278 this.result = null;
-1 4279 }
-1 4280 'use strict';
-1 4281 function createExecutionContext(spec) {
-1 4282 'use strict';
-1 4283 if (typeof spec === 'string') {
-1 4284 return new Function('return ' + spec + ';')();
-1 4285 }
-1 4286 return spec;
-1 4287 }
-1 4288 function Check(spec) {
-1 4289 if (spec) {
-1 4290 this.id = spec.id;
-1 4291 this.configure(spec);
-1 4292 }
-1 4293 }
-1 4294 Check.prototype.enabled = true;
-1 4295 Check.prototype.run = function(node, options, resolve, reject) {
-1 4296 'use strict';
-1 4297 options = options || {};
-1 4298 var enabled = options.hasOwnProperty('enabled') ? options.enabled : this.enabled, checkOptions = options.options || this.options;
-1 4299 if (enabled) {
-1 4300 var checkResult = new CheckResult(this);
-1 4301 var checkHelper = axe.utils.checkHelper(checkResult, options, resolve, reject);
-1 4302 var result;
-1 4303 try {
-1 4304 result = this.evaluate.call(checkHelper, node, checkOptions);
-1 4305 } catch (e) {
-1 4306 reject(e);
-1 4307 return;
-1 4308 }
-1 4309 if (!checkHelper.isAsync) {
-1 4310 checkResult.result = result;
-1 4311 setTimeout(function() {
-1 4312 resolve(checkResult);
-1 4313 }, 0);
-1 4314 }
-1 4315 } else {
-1 4316 resolve(null);
-1 4317 }
-1 4318 };
-1 4319 Check.prototype.configure = function(spec) {
-1 4320 var _this = this;
-1 4321 [ 'options', 'enabled' ].filter(function(prop) {
-1 4322 return spec.hasOwnProperty(prop);
-1 4323 }).forEach(function(prop) {
-1 4324 return _this[prop] = spec[prop];
-1 4325 });
-1 4326 [ 'evaluate', 'after' ].filter(function(prop) {
-1 4327 return spec.hasOwnProperty(prop);
-1 4328 }).forEach(function(prop) {
-1 4329 return _this[prop] = createExecutionContext(spec[prop]);
-1 4330 });
-1 4331 };
-1 4332 'use strict';
-1 4333 var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-1 4334 return typeof obj;
-1 4335 } : function(obj) {
-1 4336 return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-1 4337 };
-1 4338 function pushUniqueFrame(collection, frame) {
-1 4339 'use strict';
-1 4340 if (axe.utils.isHidden(frame)) {
-1 4341 return;
-1 4342 }
-1 4343 var fr = axe.utils.findBy(collection, 'node', frame);
-1 4344 if (!fr) {
-1 4345 collection.push({
-1 4346 node: frame,
-1 4347 include: [],
-1 4348 exclude: []
-1 4349 });
-1 4350 }
-1 4351 }
-1 4352 function pushUniqueFrameSelector(context, type, selectorArray) {
-1 4353 'use strict';
-1 4354 context.frames = context.frames || [];
-1 4355 var result, frame;
-1 4356 var frames = document.querySelectorAll(selectorArray.shift());
-1 4357 frameloop: for (var i = 0, l = frames.length; i < l; i++) {
-1 4358 frame = frames[i];
-1 4359 for (var j = 0, l2 = context.frames.length; j < l2; j++) {
-1 4360 if (context.frames[j].node === frame) {
-1 4361 context.frames[j][type].push(selectorArray);
-1 4362 break frameloop;
-1 4363 }
-1 4364 }
-1 4365 result = {
-1 4366 node: frame,
-1 4367 include: [],
-1 4368 exclude: []
-1 4369 };
-1 4370 if (selectorArray) {
-1 4371 result[type].push(selectorArray);
-1 4372 }
-1 4373 context.frames.push(result);
-1 4374 }
-1 4375 }
-1 4376 function normalizeContext(context) {
-1 4377 'use strict';
-1 4378 if (context && (typeof context === 'undefined' ? 'undefined' : _typeof(context)) === 'object' || context instanceof NodeList) {
-1 4379 if (context instanceof Node) {
-1 4380 return {
-1 4381 include: [ context ],
-1 4382 exclude: []
-1 4383 };
-1 4384 }
-1 4385 if (context.hasOwnProperty('include') || context.hasOwnProperty('exclude')) {
-1 4386 return {
-1 4387 include: context.include && +context.include.length ? context.include : [ document ],
-1 4388 exclude: context.exclude || []
-1 4389 };
-1 4390 }
-1 4391 if (context.length === +context.length) {
-1 4392 return {
-1 4393 include: context,
-1 4394 exclude: []
-1 4395 };
-1 4396 }
-1 4397 }
-1 4398 if (typeof context === 'string') {
-1 4399 return {
-1 4400 include: [ context ],
-1 4401 exclude: []
-1 4402 };
-1 4403 }
-1 4404 return {
-1 4405 include: [ document ],
-1 4406 exclude: []
-1 4407 };
-1 4408 }
-1 4409 function parseSelectorArray(context, type) {
-1 4410 'use strict';
-1 4411 var item, result = [];
-1 4412 for (var i = 0, l = context[type].length; i < l; i++) {
-1 4413 item = context[type][i];
-1 4414 if (typeof item === 'string') {
-1 4415 result = result.concat(axe.utils.toArray(document.querySelectorAll(item)));
-1 4416 break;
-1 4417 } else if (item && item.length && !(item instanceof Node)) {
-1 4418 if (item.length > 1) {
-1 4419 pushUniqueFrameSelector(context, type, item);
-1 4420 } else {
-1 4421 result = result.concat(axe.utils.toArray(document.querySelectorAll(item[0])));
-1 4422 }
-1 4423 } else {
-1 4424 result.push(item);
-1 4425 }
-1 4426 }
-1 4427 return result.filter(function(r) {
-1 4428 return r;
-1 4429 });
-1 4430 }
-1 4431 function validateContext(context) {
-1 4432 'use strict';
-1 4433 if (context.include.length === 0) {
-1 4434 if (context.frames.length === 0) {
-1 4435 var env = axe.utils.respondable.isInFrame() ? 'frame' : 'page';
-1 4436 return new Error('No elements found for include in ' + env + ' Context');
-1 4437 }
-1 4438 context.frames.forEach(function(frame, i) {
-1 4439 if (frame.include.length === 0) {
-1 4440 return new Error('No elements found for include in Context of frame ' + i);
-1 4441 }
-1 4442 });
-1 4443 }
-1 4444 }
-1 4445 function Context(spec) {
-1 4446 'use strict';
-1 4447 var self = this;
-1 4448 this.frames = [];
-1 4449 this.initiator = spec && typeof spec.initiator === 'boolean' ? spec.initiator : true;
-1 4450 this.page = false;
-1 4451 spec = normalizeContext(spec);
-1 4452 this.exclude = spec.exclude;
-1 4453 this.include = spec.include;
-1 4454 this.include = parseSelectorArray(this, 'include');
-1 4455 this.exclude = parseSelectorArray(this, 'exclude');
-1 4456 axe.utils.select('frame, iframe', this).forEach(function(frame) {
-1 4457 if (isNodeInContext(frame, self)) {
-1 4458 pushUniqueFrame(self.frames, frame);
-1 4459 }
-1 4460 });
-1 4461 if (this.include.length === 1 && this.include[0] === document) {
-1 4462 this.page = true;
-1 4463 }
-1 4464 var err = validateContext(this);
-1 4465 if (err instanceof Error) {
-1 4466 throw err;
-1 4467 }
-1 4468 }
-1 4469 'use strict';
-1 4470 function RuleResult(rule) {
-1 4471 'use strict';
-1 4472 this.id = rule.id;
-1 4473 this.result = axe.constants.NA;
-1 4474 this.pageLevel = rule.pageLevel;
-1 4475 this.impact = null;
-1 4476 this.nodes = [];
-1 4477 }
-1 4478 'use strict';
-1 4479 function Rule(spec, parentAudit) {
-1 4480 'use strict';
-1 4481 this._audit = parentAudit;
-1 4482 this.id = spec.id;
-1 4483 this.selector = spec.selector || '*';
-1 4484 this.excludeHidden = typeof spec.excludeHidden === 'boolean' ? spec.excludeHidden : true;
-1 4485 this.enabled = typeof spec.enabled === 'boolean' ? spec.enabled : true;
-1 4486 this.pageLevel = typeof spec.pageLevel === 'boolean' ? spec.pageLevel : false;
-1 4487 this.any = spec.any || [];
-1 4488 this.all = spec.all || [];
-1 4489 this.none = spec.none || [];
-1 4490 this.tags = spec.tags || [];
-1 4491 if (spec.matches) {
-1 4492 this.matches = createExecutionContext(spec.matches);
-1 4493 }
-1 4494 }
-1 4495 Rule.prototype.matches = function() {
-1 4496 'use strict';
-1 4497 return true;
-1 4498 };
-1 4499 Rule.prototype.gather = function(context) {
-1 4500 'use strict';
-1 4501 var elements = axe.utils.select(this.selector, context);
-1 4502 if (this.excludeHidden) {
-1 4503 return elements.filter(function(element) {
-1 4504 return !axe.utils.isHidden(element);
-1 4505 });
-1 4506 }
-1 4507 return elements;
-1 4508 };
-1 4509 Rule.prototype.runChecks = function(type, node, options, resolve, reject) {
-1 4510 'use strict';
-1 4511 var self = this;
-1 4512 var checkQueue = axe.utils.queue();
-1 4513 this[type].forEach(function(c) {
-1 4514 var check = self._audit.checks[c.id || c];
-1 4515 var option = axe.utils.getCheckOption(check, self.id, options);
-1 4516 checkQueue.defer(function(res, rej) {
-1 4517 check.run(node, option, res, rej);
-1 4518 });
-1 4519 });
-1 4520 checkQueue.then(function(results) {
-1 4521 results = results.filter(function(check) {
-1 4522 return check;
-1 4523 });
-1 4524 resolve({
-1 4525 type: type,
-1 4526 results: results
-1 4527 });
-1 4528 }).catch(reject);
-1 4529 };
-1 4530 Rule.prototype.run = function(context, options, resolve, reject) {
-1 4531 var _this = this;
-1 4532 var q = axe.utils.queue();
-1 4533 var ruleResult = new RuleResult(this);
-1 4534 var nodes = void 0;
-1 4535 try {
-1 4536 nodes = this.gather(context).filter(function(node) {
-1 4537 return _this.matches(node);
-1 4538 });
-1 4539 } catch (error) {
-1 4540 reject(new SupportError({
-1 4541 cause: error,
-1 4542 ruleId: this.id
-1 4543 }));
-1 4544 return;
-1 4545 }
-1 4546 if (options.performanceTimer) {
-1 4547 axe.log('gather (', nodes.length, '):', axe.utils.performanceTimer.timeElapsed() + 'ms');
-1 4548 }
-1 4549 nodes.forEach(function(node) {
-1 4550 q.defer(function(resolveNode, rejectNode) {
-1 4551 var checkQueue = axe.utils.queue();
-1 4552 checkQueue.defer(function(res, rej) {
-1 4553 _this.runChecks('any', node, options, res, rej);
-1 4554 });
-1 4555 checkQueue.defer(function(res, rej) {
-1 4556 _this.runChecks('all', node, options, res, rej);
-1 4557 });
-1 4558 checkQueue.defer(function(res, rej) {
-1 4559 _this.runChecks('none', node, options, res, rej);
-1 4560 });
-1 4561 checkQueue.then(function(results) {
-1 4562 if (results.length) {
-1 4563 var hasResults = false, result = {};
-1 4564 results.forEach(function(r) {
-1 4565 var res = r.results.filter(function(result) {
-1 4566 return result;
-1 4567 });
-1 4568 result[r.type] = res;
-1 4569 if (res.length) {
-1 4570 hasResults = true;
-1 4571 }
-1 4572 });
-1 4573 if (hasResults) {
-1 4574 result.node = new axe.utils.DqElement(node, options);
-1 4575 ruleResult.nodes.push(result);
-1 4576 }
-1 4577 }
-1 4578 resolveNode();
-1 4579 }).catch(function(err) {
-1 4580 return rejectNode(err);
-1 4581 });
-1 4582 });
-1 4583 });
-1 4584 q.then(function() {
-1 4585 return resolve(ruleResult);
-1 4586 }).catch(function(error) {
-1 4587 return reject(error);
-1 4588 });
-1 4589 };
-1 4590 function findAfterChecks(rule) {
-1 4591 'use strict';
-1 4592 return axe.utils.getAllChecks(rule).map(function(c) {
-1 4593 var check = rule._audit.checks[c.id || c];
-1 4594 return check && typeof check.after === 'function' ? check : null;
-1 4595 }).filter(Boolean);
-1 4596 }
-1 4597 function findCheckResults(nodes, checkID) {
-1 4598 'use strict';
-1 4599 var checkResults = [];
-1 4600 nodes.forEach(function(nodeResult) {
-1 4601 var checks = axe.utils.getAllChecks(nodeResult);
-1 4602 checks.forEach(function(checkResult) {
-1 4603 if (checkResult.id === checkID) {
-1 4604 checkResults.push(checkResult);
-1 4605 }
-1 4606 });
-1 4607 });
-1 4608 return checkResults;
-1 4609 }
-1 4610 function filterChecks(checks) {
-1 4611 'use strict';
-1 4612 return checks.filter(function(check) {
-1 4613 return check.filtered !== true;
-1 4614 });
-1 4615 }
-1 4616 function sanitizeNodes(result) {
-1 4617 'use strict';
-1 4618 var checkTypes = [ 'any', 'all', 'none' ];
-1 4619 var nodes = result.nodes.filter(function(detail) {
-1 4620 var length = 0;
-1 4621 checkTypes.forEach(function(type) {
-1 4622 detail[type] = filterChecks(detail[type]);
-1 4623 length += detail[type].length;
-1 4624 });
-1 4625 return length > 0;
-1 4626 });
-1 4627 if (result.pageLevel && nodes.length) {
-1 4628 nodes = [ nodes.reduce(function(a, b) {
-1 4629 if (a) {
-1 4630 checkTypes.forEach(function(type) {
-1 4631 a[type].push.apply(a[type], b[type]);
-1 4632 });
-1 4633 return a;
-1 4634 }
-1 4635 }) ];
-1 4636 }
-1 4637 return nodes;
-1 4638 }
-1 4639 Rule.prototype.after = function(result, options) {
-1 4640 'use strict';
-1 4641 var afterChecks = findAfterChecks(this);
-1 4642 var ruleID = this.id;
-1 4643 afterChecks.forEach(function(check) {
-1 4644 var beforeResults = findCheckResults(result.nodes, check.id);
-1 4645 var option = axe.utils.getCheckOption(check, ruleID, options);
-1 4646 var afterResults = check.after(beforeResults, option);
-1 4647 beforeResults.forEach(function(item) {
-1 4648 if (afterResults.indexOf(item) === -1) {
-1 4649 item.filtered = true;
-1 4650 }
-1 4651 });
-1 4652 });
-1 4653 result.nodes = sanitizeNodes(result);
-1 4654 return result;
-1 4655 };
-1 4656 Rule.prototype.configure = function(spec) {
-1 4657 'use strict';
-1 4658 if (spec.hasOwnProperty('selector')) {
-1 4659 this.selector = spec.selector;
-1 4660 }
-1 4661 if (spec.hasOwnProperty('excludeHidden')) {
-1 4662 this.excludeHidden = typeof spec.excludeHidden === 'boolean' ? spec.excludeHidden : true;
-1 4663 }
-1 4664 if (spec.hasOwnProperty('enabled')) {
-1 4665 this.enabled = typeof spec.enabled === 'boolean' ? spec.enabled : true;
-1 4666 }
-1 4667 if (spec.hasOwnProperty('pageLevel')) {
-1 4668 this.pageLevel = typeof spec.pageLevel === 'boolean' ? spec.pageLevel : false;
-1 4669 }
-1 4670 if (spec.hasOwnProperty('any')) {
-1 4671 this.any = spec.any;
-1 4672 }
-1 4673 if (spec.hasOwnProperty('all')) {
-1 4674 this.all = spec.all;
-1 4675 }
-1 4676 if (spec.hasOwnProperty('none')) {
-1 4677 this.none = spec.none;
-1 4678 }
-1 4679 if (spec.hasOwnProperty('tags')) {
-1 4680 this.tags = spec.tags;
-1 4681 }
-1 4682 if (spec.hasOwnProperty('matches')) {
-1 4683 if (typeof spec.matches === 'string') {
-1 4684 this.matches = new Function('return ' + spec.matches + ';')();
-1 4685 } else {
-1 4686 this.matches = spec.matches;
-1 4687 }
-1 4688 }
-1 4689 };
-1 4690 'use strict';
-1 4691 (function(axe) {
-1 4692 var definitions = [ {
-1 4693 name: 'NA',
-1 4694 value: 'inapplicable',
-1 4695 priority: 0,
-1 4696 group: 'inapplicable'
-1 4697 }, {
-1 4698 name: 'PASS',
-1 4699 value: 'passed',
-1 4700 priority: 1,
-1 4701 group: 'passes'
-1 4702 }, {
-1 4703 name: 'CANTTELL',
-1 4704 value: 'cantTell',
-1 4705 priority: 2,
-1 4706 group: 'incomplete'
-1 4707 }, {
-1 4708 name: 'FAIL',
-1 4709 value: 'failed',
-1 4710 priority: 3,
-1 4711 group: 'violations'
-1 4712 } ];
-1 4713 var constants = {
-1 4714 helpUrlBase: 'https://dequeuniversity.com/rules/',
-1 4715 results: [],
-1 4716 resultGroups: [],
-1 4717 resultGroupMap: {},
-1 4718 impact: Object.freeze([ 'minor', 'moderate', 'serious', 'critical' ])
-1 4719 };
-1 4720 definitions.forEach(function(definition) {
-1 4721 var name = definition.name;
-1 4722 var value = definition.value;
-1 4723 var priority = definition.priority;
-1 4724 var group = definition.group;
-1 4725 constants[name] = value;
-1 4726 constants[name + '_PRIO'] = priority;
-1 4727 constants[name + '_GROUP'] = group;
-1 4728 constants.results[priority] = value;
-1 4729 constants.resultGroups[priority] = group;
-1 4730 constants.resultGroupMap[value] = group;
-1 4731 });
-1 4732 Object.freeze(constants.results);
-1 4733 Object.freeze(constants.resultGroups);
-1 4734 Object.freeze(constants.resultGroupMap);
-1 4735 Object.freeze(constants);
-1 4736 Object.defineProperty(axe, 'constants', {
-1 4737 value: constants,
-1 4738 enumerable: true,
-1 4739 configurable: false,
-1 4740 writable: false
-1 4741 });
-1 4742 })(axe);
-1 4743 'use strict';
-1 4744 var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-1 4745 return typeof obj;
-1 4746 } : function(obj) {
-1 4747 return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-1 4748 };
-1 4749 axe.log = function() {
-1 4750 'use strict';
-1 4751 if ((typeof console === 'undefined' ? 'undefined' : _typeof(console)) === 'object' && console.log) {
-1 4752 Function.prototype.apply.call(console.log, console, arguments);
-1 4753 }
-1 4754 };
-1 4755 'use strict';
-1 4756 var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-1 4757 return typeof obj;
-1 4758 } : function(obj) {
-1 4759 return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-1 4760 };
-1 4761 axe.a11yCheck = function(context, options, callback) {
-1 4762 'use strict';
-1 4763 if (typeof options === 'function') {
-1 4764 callback = options;
-1 4765 options = {};
-1 4766 }
-1 4767 if (!options || (typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object') {
-1 4768 options = {};
-1 4769 }
-1 4770 var audit = axe._audit;
-1 4771 if (!audit) {
-1 4772 throw new Error('No audit configured');
-1 4773 }
-1 4774 options.reporter = options.reporter || audit.reporter || 'v2';
-1 4775 if (options.performanceTimer) {
-1 4776 axe.utils.performanceTimer.start();
-1 4777 }
-1 4778 var reporter = axe.getReporter(options.reporter);
-1 4779 axe._runRules(context, options, function(results) {
-1 4780 var res = reporter(results, options, callback);
-1 4781 if (res !== undefined) {
-1 4782 if (options.performanceTimer) {
-1 4783 axe.utils.performanceTimer.end();
-1 4784 }
-1 4785 callback(res);
-1 4786 }
-1 4787 }, axe.log);
-1 4788 };
-1 4789 'use strict';
-1 4790 function cleanupPlugins(resolve, reject) {
-1 4791 'use strict';
-1 4792 if (!axe._audit) {
-1 4793 throw new Error('No audit configured');
-1 4794 }
-1 4795 var q = axe.utils.queue();
-1 4796 var cleanupErrors = [];
-1 4797 Object.keys(axe.plugins).forEach(function(key) {
-1 4798 q.defer(function(res) {
-1 4799 var rej = function rej(err) {
-1 4800 cleanupErrors.push(err);
-1 4801 res();
-1 4802 };
-1 4803 try {
-1 4804 axe.plugins[key].cleanup(res, rej);
-1 4805 } catch (err) {
-1 4806 rej(err);
-1 4807 }
-1 4808 });
-1 4809 });
-1 4810 axe.utils.toArray(document.querySelectorAll('frame, iframe')).forEach(function(frame) {
-1 4811 q.defer(function(res, rej) {
-1 4812 return axe.utils.sendCommandToFrame(frame, {
-1 4813 command: 'cleanup-plugin'
-1 4814 }, res, rej);
-1 4815 });
-1 4816 });
-1 4817 q.then(function(results) {
-1 4818 if (cleanupErrors.length === 0) {
-1 4819 resolve(results);
-1 4820 } else {
-1 4821 reject(cleanupErrors);
-1 4822 }
-1 4823 }).catch(reject);
-1 4824 }
-1 4825 axe.cleanup = cleanupPlugins;
-1 4826 'use strict';
-1 4827 function configureChecksRulesAndBranding(spec) {
-1 4828 'use strict';
-1 4829 var audit;
-1 4830 audit = axe._audit;
-1 4831 if (!audit) {
-1 4832 throw new Error('No audit configured');
-1 4833 }
-1 4834 if (spec.reporter && (typeof spec.reporter === 'function' || reporters[spec.reporter])) {
-1 4835 audit.reporter = spec.reporter;
-1 4836 }
-1 4837 if (spec.checks) {
-1 4838 spec.checks.forEach(function(check) {
-1 4839 audit.addCheck(check);
-1 4840 });
-1 4841 }
-1 4842 if (spec.rules) {
-1 4843 spec.rules.forEach(function(rule) {
-1 4844 audit.addRule(rule);
-1 4845 });
-1 4846 }
-1 4847 if (typeof spec.branding !== 'undefined') {
-1 4848 audit.setBranding(spec.branding);
-1 4849 } else {
-1 4850 audit._constructHelpUrls();
-1 4851 }
-1 4852 if (spec.tagExclude) {
-1 4853 audit.tagExclude = spec.tagExclude;
-1 4854 }
-1 4855 }
-1 4856 axe.configure = configureChecksRulesAndBranding;
-1 4857 'use strict';
-1 4858 axe.getRules = function(tags) {
-1 4859 'use strict';
-1 4860 tags = tags || [];
-1 4861 var matchingRules = !tags.length ? axe._audit.rules : axe._audit.rules.filter(function(item) {
-1 4862 return !!tags.filter(function(tag) {
-1 4863 return item.tags.indexOf(tag) !== -1;
-1 4864 }).length;
-1 4865 });
-1 4866 var ruleData = axe._audit.data.rules || {};
-1 4867 return matchingRules.map(function(matchingRule) {
-1 4868 var rd = ruleData[matchingRule.id] || {};
-1 4869 return {
-1 4870 ruleId: matchingRule.id,
-1 4871 description: rd.description,
-1 4872 help: rd.help,
-1 4873 helpUrl: rd.helpUrl,
-1 4874 tags: matchingRule.tags
-1 4875 };
-1 4876 });
-1 4877 };
-1 4878 'use strict';
-1 4879 function runCommand(data, keepalive, callback) {
-1 4880 'use strict';
-1 4881 var resolve = callback;
-1 4882 var reject = function reject(err) {
-1 4883 if (err instanceof Error === false) {
-1 4884 err = new Error(err);
-1 4885 }
-1 4886 callback(err);
-1 4887 };
-1 4888 var context = data && data.context || {};
-1 4889 if (context.hasOwnProperty('include') && !context.include.length) {
-1 4890 context.include = [ document ];
-1 4891 }
-1 4892 var options = data && data.options || {};
-1 4893 switch (data.command) {
-1 4894 case 'rules':
-1 4895 return runRules(context, options, resolve, reject);
-1 4896
-1 4897 case 'cleanup-plugin':
-1 4898 return cleanupPlugins(resolve, reject);
-1 4899
-1 4900 default:
-1 4901 if (axe._audit && axe._audit.commands && axe._audit.commands[data.command]) {
-1 4902 return axe._audit.commands[data.command](data, callback);
-1 4903 }
-1 4904 }
-1 4905 }
-1 4906 axe._load = function(audit) {
-1 4907 'use strict';
-1 4908 axe.utils.respondable.subscribe('axe.ping', function(data, keepalive, respond) {
-1 4909 respond({
-1 4910 axe: true
-1 4911 });
-1 4912 });
-1 4913 axe.utils.respondable.subscribe('axe.start', runCommand);
-1 4914 axe._audit = new Audit(audit);
-1 4915 };
-1 4916 'use strict';
-1 4917 var axe = axe || {};
-1 4918 axe.plugins = {};
-1 4919 function Plugin(spec) {
-1 4920 'use strict';
-1 4921 this._run = spec.run;
-1 4922 this._collect = spec.collect;
-1 4923 this._registry = {};
-1 4924 spec.commands.forEach(function(command) {
-1 4925 axe._audit.registerCommand(command);
-1 4926 });
-1 4927 }
-1 4928 Plugin.prototype.run = function() {
-1 4929 'use strict';
-1 4930 return this._run.apply(this, arguments);
-1 4931 };
-1 4932 Plugin.prototype.collect = function() {
-1 4933 'use strict';
-1 4934 return this._collect.apply(this, arguments);
-1 4935 };
-1 4936 Plugin.prototype.cleanup = function(done) {
-1 4937 'use strict';
-1 4938 var q = axe.utils.queue();
-1 4939 var that = this;
-1 4940 Object.keys(this._registry).forEach(function(key) {
-1 4941 q.defer(function(done) {
-1 4942 that._registry[key].cleanup(done);
-1 4943 });
-1 4944 });
-1 4945 q.then(function() {
-1 4946 done();
-1 4947 });
-1 4948 };
-1 4949 Plugin.prototype.add = function(impl) {
-1 4950 'use strict';
-1 4951 this._registry[impl.id] = impl;
-1 4952 };
-1 4953 axe.registerPlugin = function(plugin) {
-1 4954 'use strict';
-1 4955 axe.plugins[plugin.id] = new Plugin(plugin);
-1 4956 };
-1 4957 'use strict';
-1 4958 var reporters = {};
-1 4959 var defaultReporter;
-1 4960 axe.getReporter = function(reporter) {
-1 4961 'use strict';
-1 4962 if (typeof reporter === 'string' && reporters[reporter]) {
-1 4963 return reporters[reporter];
-1 4964 }
-1 4965 if (typeof reporter === 'function') {
-1 4966 return reporter;
-1 4967 }
-1 4968 return defaultReporter;
-1 4969 };
-1 4970 axe.addReporter = function registerReporter(name, cb, isDefault) {
-1 4971 'use strict';
-1 4972 reporters[name] = cb;
-1 4973 if (isDefault) {
-1 4974 defaultReporter = cb;
-1 4975 }
-1 4976 };
-1 4977 'use strict';
-1 4978 function resetConfiguration() {
-1 4979 'use strict';
-1 4980 var audit = axe._audit;
-1 4981 if (!audit) {
-1 4982 throw new Error('No audit configured');
-1 4983 }
-1 4984 audit.resetRulesAndChecks();
-1 4985 }
-1 4986 axe.reset = resetConfiguration;
-1 4987 'use strict';
-1 4988 function runRules(context, options, resolve, reject) {
-1 4989 'use strict';
-1 4990 try {
-1 4991 context = new Context(context);
-1 4992 } catch (e) {
-1 4993 return reject(e);
-1 4994 }
-1 4995 var q = axe.utils.queue();
-1 4996 var audit = axe._audit;
-1 4997 if (options.performanceTimer) {
-1 4998 axe.utils.performanceTimer.auditStart();
-1 4999 }
-1 5000 if (context.frames.length && options.iframes !== false) {
-1 5001 q.defer(function(res, rej) {
-1 5002 axe.utils.collectResultsFromFrames(context, options, 'rules', null, res, rej);
-1 5003 });
-1 5004 }
-1 5005 var scrollState = void 0;
-1 5006 q.defer(function(res, rej) {
-1 5007 if (options.restoreScroll) {
-1 5008 scrollState = axe.utils.getScrollState();
-1 5009 }
-1 5010 audit.run(context, options, res, rej);
-1 5011 });
-1 5012 q.then(function(data) {
-1 5013 try {
-1 5014 if (scrollState) {
-1 5015 axe.utils.setScrollState(scrollState);
-1 5016 }
-1 5017 if (options.performanceTimer) {
-1 5018 axe.utils.performanceTimer.auditEnd();
-1 5019 }
-1 5020 var results = axe.utils.mergeResults(data.map(function(d) {
-1 5021 return {
-1 5022 results: d
-1 5023 };
-1 5024 }));
-1 5025 if (context.initiator) {
-1 5026 results = audit.after(results, options);
-1 5027 results.forEach(axe.utils.publishMetaData);
-1 5028 results = results.map(axe.utils.finalizeRuleResult);
-1 5029 }
-1 5030 try {
-1 5031 resolve(results);
-1 5032 } catch (e) {
-1 5033 axe.log(e);
-1 5034 }
-1 5035 } catch (e) {
-1 5036 reject(e);
-1 5037 }
-1 5038 }).catch(reject);
-1 5039 }
-1 5040 axe._runRules = runRules;
-1 5041 'use strict';
-1 5042 var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-1 5043 return typeof obj;
-1 5044 } : function(obj) {
-1 5045 return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-1 5046 };
-1 5047 function isContext(potential) {
-1 5048 'use strict';
-1 5049 switch (true) {
-1 5050 case typeof potential === 'string':
-1 5051 case Array.isArray(potential):
-1 5052 case Node && potential instanceof Node:
-1 5053 case NodeList && potential instanceof NodeList:
-1 5054 return true;
-1 5055
-1 5056 case (typeof potential === 'undefined' ? 'undefined' : _typeof(potential)) !== 'object':
-1 5057 return false;
-1 5058
-1 5059 case potential.include !== undefined:
-1 5060 case potential.exclude !== undefined:
-1 5061 case typeof potential.length === 'number':
-1 5062 return true;
-1 5063
-1 5064 default:
-1 5065 return false;
-1 5066 }
-1 5067 }
-1 5068 var noop = function noop() {};
-1 5069 function normalizeRunParams(context, options, callback) {
-1 5070 'use strict';
-1 5071 var typeErr = new TypeError('axe.run arguments are invalid');
-1 5072 if (!isContext(context)) {
-1 5073 if (callback !== undefined) {
-1 5074 throw typeErr;
-1 5075 }
-1 5076 callback = options;
-1 5077 options = context;
-1 5078 context = document;
-1 5079 }
-1 5080 if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object') {
-1 5081 if (callback !== undefined) {
-1 5082 throw typeErr;
-1 5083 }
-1 5084 callback = options;
-1 5085 options = {};
-1 5086 }
-1 5087 if (typeof callback !== 'function' && callback !== undefined) {
-1 5088 throw typeErr;
-1 5089 }
-1 5090 return {
-1 5091 context: context,
-1 5092 options: options,
-1 5093 callback: callback || noop
-1 5094 };
-1 5095 }
-1 5096 axe.run = function(context, options, callback) {
-1 5097 'use strict';
-1 5098 if (!axe._audit) {
-1 5099 throw new Error('No audit configured');
-1 5100 }
-1 5101 var args = normalizeRunParams(context, options, callback);
-1 5102 context = args.context;
-1 5103 options = args.options;
-1 5104 callback = args.callback;
-1 5105 options.reporter = options.reporter || axe._audit.reporter || 'v1';
-1 5106 if (options.performanceTimer) {
-1 5107 axe.utils.performanceTimer.start();
-1 5108 }
-1 5109 var p = void 0;
-1 5110 var reject = noop;
-1 5111 var resolve = noop;
-1 5112 if (window.Promise && callback === noop) {
-1 5113 p = new Promise(function(_resolve, _reject) {
-1 5114 reject = _reject;
-1 5115 resolve = _resolve;
-1 5116 });
-1 5117 }
-1 5118 axe._runRules(context, options, function(rawResults) {
-1 5119 var respond = function respond(results) {
-1 5120 try {
-1 5121 callback(null, results);
-1 5122 } catch (e) {
-1 5123 axe.log(e);
-1 5124 }
-1 5125 resolve(results);
-1 5126 };
-1 5127 if (options.performanceTimer) {
-1 5128 axe.utils.performanceTimer.end();
-1 5129 }
-1 5130 try {
-1 5131 var reporter = axe.getReporter(options.reporter);
-1 5132 var results = reporter(rawResults, options, respond);
-1 5133 if (results !== undefined) {
-1 5134 respond(results);
-1 5135 }
-1 5136 } catch (err) {
-1 5137 callback(err);
-1 5138 reject(err);
-1 5139 }
-1 5140 }, function(err) {
-1 5141 callback(err);
-1 5142 reject(err);
-1 5143 });
-1 5144 return p;
-1 5145 };
-1 5146 'use strict';
-1 5147 helpers.failureSummary = function failureSummary(nodeData) {
-1 5148 'use strict';
-1 5149 var failingChecks = {};
-1 5150 failingChecks.none = nodeData.none.concat(nodeData.all);
-1 5151 failingChecks.any = nodeData.any;
-1 5152 return Object.keys(failingChecks).map(function(key) {
-1 5153 if (!failingChecks[key].length) {
-1 5154 return;
-1 5155 }
-1 5156 var sum = axe._audit.data.failureSummaries[key];
-1 5157 if (sum && typeof sum.failureMessage === 'function') {
-1 5158 return sum.failureMessage(failingChecks[key].map(function(check) {
-1 5159 return check.message || '';
-1 5160 }));
-1 5161 }
-1 5162 }).filter(function(i) {
-1 5163 return i !== undefined;
-1 5164 }).join('\n\n');
-1 5165 };
-1 5166 'use strict';
-1 5167 helpers.incompleteFallbackMessage = function incompleteFallbackMessage() {
-1 5168 'use strict';
-1 5169 return axe._audit.data.incompleteFallbackMessage();
-1 5170 };
-1 5171 'use strict';
-1 5172 var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-1 5173 return typeof obj;
-1 5174 } : function(obj) {
-1 5175 return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-1 5176 };
-1 5177 function normalizeRelatedNodes(node, options) {
-1 5178 'use strict';
-1 5179 [ 'any', 'all', 'none' ].forEach(function(type) {
-1 5180 if (!Array.isArray(node[type])) {
-1 5181 return;
-1 5182 }
-1 5183 node[type].filter(function(checkRes) {
-1 5184 return Array.isArray(checkRes.relatedNodes);
-1 5185 }).forEach(function(checkRes) {
-1 5186 checkRes.relatedNodes = checkRes.relatedNodes.map(function(relatedNode) {
-1 5187 var res = {
-1 5188 html: relatedNode.source
-1 5189 };
-1 5190 if (options.elementRef && !relatedNode.fromFrame) {
-1 5191 res.element = relatedNode.element;
-1 5192 }
-1 5193 if (options.selectors !== false || relatedNode.fromFrame) {
-1 5194 res.target = relatedNode.selector;
-1 5195 }
-1 5196 if (options.xpath) {
-1 5197 res.xpath = relatedNode.xpath;
-1 5198 }
-1 5199 return res;
-1 5200 });
-1 5201 });
-1 5202 });
-1 5203 }
-1 5204 var resultKeys = axe.constants.resultGroups;
-1 5205 helpers.processAggregate = function(results, options) {
-1 5206 var resultObject = axe.utils.aggregateResult(results);
-1 5207 resultObject.timestamp = new Date().toISOString();
-1 5208 resultObject.url = window.location.href;
-1 5209 resultKeys.forEach(function(key) {
-1 5210 if (options.resultTypes && !options.resultTypes.includes(key)) {
-1 5211 (resultObject[key] || []).forEach(function(ruleResult) {
-1 5212 if (Array.isArray(ruleResult.nodes) && ruleResult.nodes.length > 0) {
-1 5213 ruleResult.nodes = [ ruleResult.nodes[0] ];
-1 5214 }
-1 5215 });
-1 5216 }
-1 5217 resultObject[key] = (resultObject[key] || []).map(function(ruleResult) {
-1 5218 ruleResult = Object.assign({}, ruleResult);
-1 5219 if (Array.isArray(ruleResult.nodes) && ruleResult.nodes.length > 0) {
-1 5220 ruleResult.nodes = ruleResult.nodes.map(function(subResult) {
-1 5221 if (_typeof(subResult.node) === 'object') {
-1 5222 subResult.html = subResult.node.source;
-1 5223 if (options.elementRef && !subResult.node.fromFrame) {
-1 5224 subResult.element = subResult.node.element;
-1 5225 }
-1 5226 if (options.selectors !== false || subResult.node.fromFrame) {
-1 5227 subResult.target = subResult.node.selector;
-1 5228 }
-1 5229 if (options.xpath) {
-1 5230 subResult.xpath = subResult.node.xpath;
-1 5231 }
-1 5232 }
-1 5233 delete subResult.result;
-1 5234 delete subResult.node;
-1 5235 normalizeRelatedNodes(subResult, options);
-1 5236 return subResult;
-1 5237 });
-1 5238 }
-1 5239 resultKeys.forEach(function(key) {
-1 5240 return delete ruleResult[key];
-1 5241 });
-1 5242 delete ruleResult.pageLevel;
-1 5243 delete ruleResult.result;
-1 5244 return ruleResult;
-1 5245 });
-1 5246 });
-1 5247 return resultObject;
-1 5248 };
-1 5249 'use strict';
-1 5250 axe.addReporter('na', function(results, options, callback) {
-1 5251 'use strict';
-1 5252 if (typeof options === 'function') {
-1 5253 callback = options;
-1 5254 options = {};
-1 5255 }
-1 5256 var out = helpers.processAggregate(results, options);
-1 5257 callback({
-1 5258 violations: out.violations,
-1 5259 passes: out.passes,
-1 5260 incomplete: out.incomplete,
-1 5261 inapplicable: out.inapplicable,
-1 5262 timestamp: out.timestamp,
-1 5263 url: out.url
-1 5264 });
-1 5265 });
-1 5266 'use strict';
-1 5267 axe.addReporter('no-passes', function(results, options, callback) {
-1 5268 'use strict';
-1 5269 if (typeof options === 'function') {
-1 5270 callback = options;
-1 5271 options = {};
-1 5272 }
-1 5273 options.resultTypes = [ 'violations' ];
-1 5274 var out = helpers.processAggregate(results, options);
-1 5275 callback({
-1 5276 violations: out.violations,
-1 5277 timestamp: out.timestamp,
-1 5278 url: out.url
-1 5279 });
-1 5280 });
-1 5281 'use strict';
-1 5282 axe.addReporter('raw', function(results, options, callback) {
-1 5283 'use strict';
-1 5284 if (typeof options === 'function') {
-1 5285 callback = options;
-1 5286 options = {};
-1 5287 }
-1 5288 callback(results);
-1 5289 });
-1 5290 'use strict';
-1 5291 axe.addReporter('v1', function(results, options, callback) {
-1 5292 'use strict';
-1 5293 if (typeof options === 'function') {
-1 5294 callback = options;
-1 5295 options = {};
-1 5296 }
-1 5297 var out = helpers.processAggregate(results, options);
-1 5298 out.violations.forEach(function(result) {
-1 5299 return result.nodes.forEach(function(nodeResult) {
-1 5300 nodeResult.failureSummary = helpers.failureSummary(nodeResult);
-1 5301 });
-1 5302 });
-1 5303 callback({
-1 5304 violations: out.violations,
-1 5305 passes: out.passes,
-1 5306 incomplete: out.incomplete,
-1 5307 inapplicable: out.inapplicable,
-1 5308 timestamp: out.timestamp,
-1 5309 url: out.url
-1 5310 });
-1 5311 });
-1 5312 'use strict';
-1 5313 axe.addReporter('v2', function(results, options, callback) {
-1 5314 'use strict';
-1 5315 if (typeof options === 'function') {
-1 5316 callback = options;
-1 5317 options = {};
-1 5318 }
-1 5319 var out = helpers.processAggregate(results, options);
-1 5320 callback({
-1 5321 violations: out.violations,
-1 5322 passes: out.passes,
-1 5323 incomplete: out.incomplete,
-1 5324 inapplicable: out.inapplicable,
-1 5325 timestamp: out.timestamp,
-1 5326 url: out.url
-1 5327 });
-1 5328 }, true);
-1 5329 'use strict';
-1 5330 axe.utils.aggregate = function(map, values, initial) {
-1 5331 values = values.slice();
-1 5332 if (initial) {
-1 5333 values.push(initial);
-1 5334 }
-1 5335 var sorting = values.map(function(val) {
-1 5336 return map.indexOf(val);
-1 5337 }).sort();
-1 5338 return map[sorting.pop()];
-1 5339 };
-1 5340 'use strict';
-1 5341 var _axe$constants = axe.constants, CANTTELL_PRIO = _axe$constants.CANTTELL_PRIO, FAIL_PRIO = _axe$constants.FAIL_PRIO;
-1 5342 var checkMap = [];
-1 5343 checkMap[axe.constants.PASS_PRIO] = true;
-1 5344 checkMap[axe.constants.CANTTELL_PRIO] = null;
-1 5345 checkMap[axe.constants.FAIL_PRIO] = false;
-1 5346 var checkTypes = [ 'any', 'all', 'none' ];
-1 5347 function anyAllNone(obj, functor) {
-1 5348 return checkTypes.reduce(function(out, type) {
-1 5349 out[type] = (obj[type] || []).map(function(val) {
-1 5350 return functor(val, type);
-1 5351 });
-1 5352 return out;
-1 5353 }, {});
-1 5354 }
-1 5355 axe.utils.aggregateChecks = function(nodeResOriginal) {
-1 5356 var nodeResult = Object.assign({}, nodeResOriginal);
-1 5357 anyAllNone(nodeResult, function(check, type) {
-1 5358 var i = checkMap.indexOf(check.result);
-1 5359 check.priority = i !== -1 ? i : axe.constants.CANTTELL_PRIO;
-1 5360 if (type === 'none') {
-1 5361 check.priority = 4 - check.priority;
-1 5362 }
-1 5363 });
-1 5364 var priorities = {
-1 5365 all: nodeResult.all.reduce(function(a, b) {
-1 5366 return Math.max(a, b.priority);
-1 5367 }, 0),
-1 5368 none: nodeResult.none.reduce(function(a, b) {
-1 5369 return Math.max(a, b.priority);
-1 5370 }, 0),
-1 5371 any: nodeResult.any.reduce(function(a, b) {
-1 5372 return Math.min(a, b.priority);
-1 5373 }, 4) % 4
-1 5374 };
-1 5375 nodeResult.priority = Math.max(priorities.all, priorities.none, priorities.any);
-1 5376 var impacts = [];
-1 5377 checkTypes.forEach(function(type) {
-1 5378 nodeResult[type] = nodeResult[type].filter(function(check) {
-1 5379 return check.priority === nodeResult.priority && check.priority === priorities[type];
-1 5380 });
-1 5381 nodeResult[type].forEach(function(check) {
-1 5382 return impacts.push(check.impact);
-1 5383 });
-1 5384 });
-1 5385 if ([ CANTTELL_PRIO, FAIL_PRIO ].includes(nodeResult.priority)) {
-1 5386 nodeResult.impact = axe.utils.aggregate(axe.constants.impact, impacts);
-1 5387 } else {
-1 5388 nodeResult.impact = null;
-1 5389 }
-1 5390 anyAllNone(nodeResult, function(c) {
-1 5391 delete c.result;
-1 5392 delete c.priority;
-1 5393 });
-1 5394 nodeResult.result = axe.constants.results[nodeResult.priority];
-1 5395 delete nodeResult.priority;
-1 5396 return nodeResult;
-1 5397 };
-1 5398 'use strict';
-1 5399 (function() {
-1 5400 axe.utils.aggregateNodeResults = function(nodeResults) {
-1 5401 var ruleResult = {};
-1 5402 nodeResults = nodeResults.map(function(nodeResult) {
-1 5403 if (nodeResult.any && nodeResult.all && nodeResult.none) {
-1 5404 return axe.utils.aggregateChecks(nodeResult);
-1 5405 } else if (Array.isArray(nodeResult.node)) {
-1 5406 return axe.utils.finalizeRuleResult(nodeResult);
-1 5407 } else {
-1 5408 throw new TypeError('Invalid Result type');
-1 5409 }
-1 5410 });
-1 5411 if (nodeResults && nodeResults.length) {
-1 5412 var resultList = nodeResults.map(function(node) {
-1 5413 return node.result;
-1 5414 });
-1 5415 ruleResult.result = axe.utils.aggregate(axe.constants.results, resultList, ruleResult.result);
-1 5416 } else {
-1 5417 ruleResult.result = 'inapplicable';
-1 5418 }
-1 5419 axe.constants.resultGroups.forEach(function(group) {
-1 5420 return ruleResult[group] = [];
-1 5421 });
-1 5422 nodeResults.forEach(function(nodeResult) {
-1 5423 var groupName = axe.constants.resultGroupMap[nodeResult.result];
-1 5424 ruleResult[groupName].push(nodeResult);
-1 5425 });
-1 5426 var impactGroup = axe.constants.FAIL_GROUP;
-1 5427 if (ruleResult[impactGroup].length === 0) {
-1 5428 impactGroup = axe.constants.CANTTELL_GROUP;
-1 5429 }
-1 5430 if (ruleResult[impactGroup].length > 0) {
-1 5431 var impactList = ruleResult[impactGroup].map(function(failure) {
-1 5432 return failure.impact;
-1 5433 });
-1 5434 ruleResult.impact = axe.utils.aggregate(axe.constants.impact, impactList) || null;
-1 5435 } else {
-1 5436 ruleResult.impact = null;
-1 5437 }
-1 5438 return ruleResult;
-1 5439 };
-1 5440 })();
-1 5441 'use strict';
-1 5442 function copyToGroup(resultObject, subResult, group) {
-1 5443 var resultCopy = Object.assign({}, subResult);
-1 5444 resultCopy.nodes = (resultCopy[group] || []).concat();
-1 5445 axe.constants.resultGroups.forEach(function(group) {
-1 5446 delete resultCopy[group];
-1 5447 });
-1 5448 resultObject[group].push(resultCopy);
-1 5449 }
-1 5450 axe.utils.aggregateResult = function(results) {
-1 5451 var resultObject = {};
-1 5452 axe.constants.resultGroups.forEach(function(groupName) {
-1 5453 return resultObject[groupName] = [];
-1 5454 });
-1 5455 results.forEach(function(subResult) {
-1 5456 if (subResult.error) {
-1 5457 copyToGroup(resultObject, subResult, axe.constants.CANTTELL_GROUP);
-1 5458 } else if (subResult.result === axe.constants.NA) {
-1 5459 copyToGroup(resultObject, subResult, axe.constants.NA_GROUP);
-1 5460 } else {
-1 5461 axe.constants.resultGroups.forEach(function(group) {
-1 5462 if (Array.isArray(subResult[group]) && subResult[group].length > 0) {
-1 5463 copyToGroup(resultObject, subResult, group);
-1 5464 }
-1 5465 });
-1 5466 }
-1 5467 });
-1 5468 return resultObject;
-1 5469 };
-1 5470 'use strict';
-1 5471 function areStylesSet(el, styles, stopAt) {
-1 5472 'use strict';
-1 5473 var styl = window.getComputedStyle(el, null);
-1 5474 var set = false;
-1 5475 if (!styl) {
-1 5476 return false;
-1 5477 }
-1 5478 styles.forEach(function(att) {
-1 5479 if (styl.getPropertyValue(att.property) === att.value) {
-1 5480 set = true;
-1 5481 }
-1 5482 });
-1 5483 if (set) {
-1 5484 return true;
-1 5485 }
-1 5486 if (el.nodeName.toUpperCase() === stopAt.toUpperCase() || !el.parentNode) {
-1 5487 return false;
-1 5488 }
-1 5489 return areStylesSet(el.parentNode, styles, stopAt);
-1 5490 }
-1 5491 axe.utils.areStylesSet = areStylesSet;
-1 5492 'use strict';
-1 5493 axe.utils.checkHelper = function checkHelper(checkResult, options, resolve, reject) {
-1 5494 'use strict';
-1 5495 return {
-1 5496 isAsync: false,
-1 5497 async: function async() {
-1 5498 this.isAsync = true;
-1 5499 return function(result) {
-1 5500 if (result instanceof Error === false) {
-1 5501 checkResult.result = result;
-1 5502 resolve(checkResult);
-1 5503 } else {
-1 5504 reject(result);
-1 5505 }
-1 5506 };
-1 5507 },
-1 5508 data: function data(_data) {
-1 5509 checkResult.data = _data;
-1 5510 },
-1 5511 relatedNodes: function relatedNodes(nodes) {
-1 5512 nodes = nodes instanceof Node ? [ nodes ] : axe.utils.toArray(nodes);
-1 5513 checkResult.relatedNodes = nodes.map(function(element) {
-1 5514 return new axe.utils.DqElement(element, options);
-1 5515 });
-1 5516 }
-1 5517 };
-1 5518 };
-1 5519 'use strict';
-1 5520 var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-1 5521 return typeof obj;
-1 5522 } : function(obj) {
-1 5523 return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-1 5524 };
-1 5525 axe.utils.clone = function(obj) {
-1 5526 'use strict';
-1 5527 var index, length, out = obj;
-1 5528 if (obj !== null && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object') {
-1 5529 if (Array.isArray(obj)) {
-1 5530 out = [];
-1 5531 for (index = 0, length = obj.length; index < length; index++) {
-1 5532 out[index] = axe.utils.clone(obj[index]);
-1 5533 }
-1 5534 } else {
-1 5535 out = {};
-1 5536 for (index in obj) {
-1 5537 out[index] = axe.utils.clone(obj[index]);
-1 5538 }
-1 5539 }
-1 5540 }
-1 5541 return out;
-1 5542 };
-1 5543 'use strict';
-1 5544 function err(message, node) {
-1 5545 'use strict';
-1 5546 return new Error(message + ': ' + axe.utils.getSelector(node));
-1 5547 }
-1 5548 axe.utils.sendCommandToFrame = function(node, parameters, resolve, reject) {
-1 5549 'use strict';
-1 5550 var win = node.contentWindow;
-1 5551 if (!win) {
-1 5552 axe.log('Frame does not have a content window', node);
-1 5553 resolve(null);
-1 5554 return;
-1 5555 }
-1 5556 var timeout = setTimeout(function() {
-1 5557 timeout = setTimeout(function() {
-1 5558 var errMsg = err('No response from frame', node);
-1 5559 if (!parameters.debug) {
-1 5560 axe.log(errMsg);
-1 5561 resolve(null);
-1 5562 } else {
-1 5563 reject(errMsg);
-1 5564 }
-1 5565 }, 0);
-1 5566 }, 500);
-1 5567 axe.utils.respondable(win, 'axe.ping', null, undefined, function() {
-1 5568 clearTimeout(timeout);
-1 5569 timeout = setTimeout(function() {
-1 5570 reject(err('Axe in frame timed out', node));
-1 5571 }, 3e4);
-1 5572 axe.utils.respondable(win, 'axe.start', parameters, undefined, function(data) {
-1 5573 clearTimeout(timeout);
-1 5574 if (data instanceof Error === false) {
-1 5575 resolve(data);
-1 5576 } else {
-1 5577 reject(data);
-1 5578 }
-1 5579 });
-1 5580 });
-1 5581 };
-1 5582 function collectResultsFromFrames(context, options, command, parameter, resolve, reject) {
-1 5583 'use strict';
-1 5584 var q = axe.utils.queue();
-1 5585 var frames = context.frames;
-1 5586 frames.forEach(function(frame) {
-1 5587 var params = {
-1 5588 options: options,
-1 5589 command: command,
-1 5590 parameter: parameter,
-1 5591 context: {
-1 5592 initiator: false,
-1 5593 page: context.page,
-1 5594 include: frame.include || [],
-1 5595 exclude: frame.exclude || []
-1 5596 }
-1 5597 };
-1 5598 q.defer(function(res, rej) {
-1 5599 var node = frame.node;
-1 5600 axe.utils.sendCommandToFrame(node, params, function(data) {
-1 5601 if (data) {
-1 5602 return res({
-1 5603 results: data,
-1 5604 frameElement: node,
-1 5605 frame: axe.utils.getSelector(node)
-1 5606 });
-1 5607 }
-1 5608 res(null);
-1 5609 }, rej);
-1 5610 });
-1 5611 });
-1 5612 q.then(function(data) {
-1 5613 resolve(axe.utils.mergeResults(data, options));
-1 5614 }).catch(reject);
-1 5615 }
-1 5616 axe.utils.collectResultsFromFrames = collectResultsFromFrames;
-1 5617 'use strict';
-1 5618 axe.utils.contains = function(node, otherNode) {
-1 5619 'use strict';
-1 5620 if (typeof node.contains === 'function') {
-1 5621 return node.contains(otherNode);
-1 5622 }
-1 5623 return !!(node.compareDocumentPosition(otherNode) & 16);
-1 5624 };
-1 5625 'use strict';
-1 5626 function truncate(str, maxLength) {
-1 5627 maxLength = maxLength || 300;
-1 5628 if (str.length > maxLength) {
-1 5629 var index = str.indexOf('>');
-1 5630 str = str.substring(0, index + 1);
-1 5631 }
-1 5632 return str;
-1 5633 }
-1 5634 function getSource(element) {
-1 5635 var source = element.outerHTML;
-1 5636 if (!source && typeof XMLSerializer === 'function') {
-1 5637 source = new XMLSerializer().serializeToString(element);
-1 5638 }
-1 5639 return truncate(source || '');
-1 5640 }
-1 5641 function DqElement(element, options, spec) {
-1 5642 this._fromFrame = !!spec;
-1 5643 this.spec = spec || {};
-1 5644 if (options && options.absolutePaths) {
-1 5645 this._options = {
-1 5646 toRoot: true
-1 5647 };
-1 5648 }
-1 5649 this.source = this.spec.source !== undefined ? this.spec.source : getSource(element);
-1 5650 this._element = element;
-1 5651 }
-1 5652 DqElement.prototype = {
-1 5653 get selector() {
-1 5654 return this.spec.selector || [ axe.utils.getSelector(this.element, this._options) ];
-1 5655 },
-1 5656 get xpath() {
-1 5657 return this.spec.xpath || [ axe.utils.getXpath(this.element) ];
-1 5658 },
-1 5659 get element() {
-1 5660 return this._element;
-1 5661 },
-1 5662 get fromFrame() {
-1 5663 return this._fromFrame;
-1 5664 },
-1 5665 toJSON: function toJSON() {
-1 5666 'use strict';
-1 5667 return {
-1 5668 selector: this.selector,
-1 5669 source: this.source,
-1 5670 xpath: this.xpath
-1 5671 };
-1 5672 }
-1 5673 };
-1 5674 DqElement.fromFrame = function(node, options, frame) {
-1 5675 node.selector.unshift(frame.selector);
-1 5676 node.xpath.unshift(frame.xpath);
-1 5677 return new axe.utils.DqElement(frame.element, options, node);
-1 5678 };
-1 5679 axe.utils.DqElement = DqElement;
-1 5680 'use strict';
-1 5681 axe.utils.matchesSelector = function() {
-1 5682 'use strict';
-1 5683 var method;
-1 5684 function getMethod(win) {
-1 5685 var index, candidate, elProto = win.Element.prototype, candidates = [ 'matches', 'matchesSelector', 'mozMatchesSelector', 'webkitMatchesSelector', 'msMatchesSelector' ], length = candidates.length;
-1 5686 for (index = 0; index < length; index++) {
-1 5687 candidate = candidates[index];
-1 5688 if (elProto[candidate]) {
-1 5689 return candidate;
-1 5690 }
-1 5691 }
-1 5692 }
-1 5693 return function(node, selector) {
-1 5694 if (!method || !node[method]) {
-1 5695 method = getMethod(node.ownerDocument.defaultView);
-1 5696 }
-1 5697 return node[method](selector);
-1 5698 };
-1 5699 }();
-1 5700 'use strict';
-1 5701 axe.utils.escapeSelector = function(value) {
-1 5702 'use strict';
-1 5703 var string = String(value);
-1 5704 var length = string.length;
-1 5705 var index = -1;
-1 5706 var codeUnit;
-1 5707 var result = '';
-1 5708 var firstCodeUnit = string.charCodeAt(0);
-1 5709 while (++index < length) {
-1 5710 codeUnit = string.charCodeAt(index);
-1 5711 if (codeUnit == 0) {
-1 5712 throw new Error('INVALID_CHARACTER_ERR');
-1 5713 }
-1 5714 if (codeUnit >= 1 && codeUnit <= 31 || codeUnit >= 127 && codeUnit <= 159 || index == 0 && codeUnit >= 48 && codeUnit <= 57 || index == 1 && codeUnit >= 48 && codeUnit <= 57 && firstCodeUnit == 45) {
-1 5715 result += '\\' + codeUnit.toString(16) + ' ';
-1 5716 continue;
-1 5717 }
-1 5718 if (index == 1 && codeUnit == 45 && firstCodeUnit == 45) {
-1 5719 result += '\\' + string.charAt(index);
-1 5720 continue;
-1 5721 }
-1 5722 if (codeUnit >= 128 || codeUnit == 45 || codeUnit == 95 || codeUnit >= 48 && codeUnit <= 57 || codeUnit >= 65 && codeUnit <= 90 || codeUnit >= 97 && codeUnit <= 122) {
-1 5723 result += string.charAt(index);
-1 5724 continue;
-1 5725 }
-1 5726 result += '\\' + string.charAt(index);
-1 5727 }
-1 5728 return result;
-1 5729 };
-1 5730 'use strict';
-1 5731 axe.utils.extendMetaData = function(to, from) {
-1 5732 Object.assign(to, from);
-1 5733 Object.keys(from).filter(function(prop) {
-1 5734 return typeof from[prop] === 'function';
-1 5735 }).forEach(function(prop) {
-1 5736 to[prop] = null;
-1 5737 try {
-1 5738 to[prop] = from[prop](to);
-1 5739 } catch (e) {}
-1 5740 });
-1 5741 };
-1 5742 'use strict';
-1 5743 axe.utils.finalizeRuleResult = function(ruleResult) {
-1 5744 Object.assign(ruleResult, axe.utils.aggregateNodeResults(ruleResult.nodes));
-1 5745 delete ruleResult.nodes;
-1 5746 return ruleResult;
-1 5747 };
-1 5748 'use strict';
-1 5749 var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-1 5750 return typeof obj;
-1 5751 } : function(obj) {
-1 5752 return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-1 5753 };
-1 5754 axe.utils.findBy = function(array, key, value) {
-1 5755 if (Array.isArray(array)) {
-1 5756 return array.find(function(obj) {
-1 5757 return (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && obj[key] === value;
-1 5758 });
-1 5759 }
-1 5760 };
-1 5761 'use strict';
-1 5762 axe.utils.getAllChecks = function getAllChecks(object) {
-1 5763 'use strict';
-1 5764 var result = [];
-1 5765 return result.concat(object.any || []).concat(object.all || []).concat(object.none || []);
-1 5766 };
-1 5767 'use strict';
-1 5768 axe.utils.getCheckOption = function(check, ruleID, options) {
-1 5769 var ruleCheckOption = ((options.rules && options.rules[ruleID] || {}).checks || {})[check.id];
-1 5770 var checkOption = (options.checks || {})[check.id];
-1 5771 var enabled = check.enabled;
-1 5772 var opts = check.options;
-1 5773 if (checkOption) {
-1 5774 if (checkOption.hasOwnProperty('enabled')) {
-1 5775 enabled = checkOption.enabled;
-1 5776 }
-1 5777 if (checkOption.hasOwnProperty('options')) {
-1 5778 opts = checkOption.options;
-1 5779 }
-1 5780 }
-1 5781 if (ruleCheckOption) {
-1 5782 if (ruleCheckOption.hasOwnProperty('enabled')) {
-1 5783 enabled = ruleCheckOption.enabled;
-1 5784 }
-1 5785 if (ruleCheckOption.hasOwnProperty('options')) {
-1 5786 opts = ruleCheckOption.options;
-1 5787 }
-1 5788 }
-1 5789 return {
-1 5790 enabled: enabled,
-1 5791 options: opts,
-1 5792 absolutePaths: options.absolutePaths
-1 5793 };
-1 5794 };
-1 5795 'use strict';
-1 5796 var _slicedToArray = function() {
-1 5797 function sliceIterator(arr, i) {
-1 5798 var _arr = [];
-1 5799 var _n = true;
-1 5800 var _d = false;
-1 5801 var _e = undefined;
-1 5802 try {
-1 5803 for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
-1 5804 _arr.push(_s.value);
-1 5805 if (i && _arr.length === i) {
-1 5806 break;
-1 5807 }
-1 5808 }
-1 5809 } catch (err) {
-1 5810 _d = true;
-1 5811 _e = err;
-1 5812 } finally {
-1 5813 try {
-1 5814 if (!_n && _i['return']) {
-1 5815 _i['return']();
-1 5816 }
-1 5817 } finally {
-1 5818 if (_d) {
-1 5819 throw _e;
-1 5820 }
-1 5821 }
-1 5822 }
-1 5823 return _arr;
-1 5824 }
-1 5825 return function(arr, i) {
-1 5826 if (Array.isArray(arr)) {
-1 5827 return arr;
-1 5828 } else if (Symbol.iterator in Object(arr)) {
-1 5829 return sliceIterator(arr, i);
-1 5830 } else {
-1 5831 throw new TypeError('Invalid attempt to destructure non-iterable instance');
-1 5832 }
-1 5833 };
-1 5834 }();
-1 5835 function isMostlyNumbers() {
-1 5836 var str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
-1 5837 return str.length !== 0 && (str.match(/[0-9]/g) || '').length >= str.length / 2;
-1 5838 }
-1 5839 function splitString(str, splitIndex) {
-1 5840 return [ str.substring(0, splitIndex), str.substring(splitIndex) ];
-1 5841 }
-1 5842 function uriParser(url) {
-1 5843 var original = url;
-1 5844 var protocol = '', domain = '', port = '', path = '', query = '', hash = '';
-1 5845 if (url.includes('#')) {
-1 5846 var _splitString = splitString(url, url.indexOf('#'));
-1 5847 var _splitString2 = _slicedToArray(_splitString, 2);
-1 5848 url = _splitString2[0];
-1 5849 hash = _splitString2[1];
-1 5850 }
-1 5851 if (url.includes('?')) {
-1 5852 var _splitString3 = splitString(url, url.indexOf('?'));
-1 5853 var _splitString4 = _slicedToArray(_splitString3, 2);
-1 5854 url = _splitString4[0];
-1 5855 query = _splitString4[1];
-1 5856 }
-1 5857 if (url.includes('://')) {
-1 5858 var _url$split = url.split('://');
-1 5859 var _url$split2 = _slicedToArray(_url$split, 2);
-1 5860 protocol = _url$split2[0];
-1 5861 url = _url$split2[1];
-1 5862 var _splitString5 = splitString(url, url.indexOf('/'));
-1 5863 var _splitString6 = _slicedToArray(_splitString5, 2);
-1 5864 domain = _splitString6[0];
-1 5865 url = _splitString6[1];
-1 5866 } else if (url.substr(0, 2) === '//') {
-1 5867 url = url.substr(2);
-1 5868 var _splitString7 = splitString(url, url.indexOf('/'));
-1 5869 var _splitString8 = _slicedToArray(_splitString7, 2);
-1 5870 domain = _splitString8[0];
-1 5871 url = _splitString8[1];
-1 5872 }
-1 5873 if (domain.substr(0, 4) === 'www.') {
-1 5874 domain = domain.substr(4);
-1 5875 }
-1 5876 if (domain && domain.includes(':')) {
-1 5877 var _splitString9 = splitString(domain, domain.indexOf(':'));
-1 5878 var _splitString10 = _slicedToArray(_splitString9, 2);
-1 5879 domain = _splitString10[0];
-1 5880 port = _splitString10[1];
-1 5881 }
-1 5882 path = url;
-1 5883 return {
-1 5884 original: original,
-1 5885 protocol: protocol,
-1 5886 domain: domain,
-1 5887 port: port,
-1 5888 path: path,
-1 5889 query: query,
-1 5890 hash: hash
-1 5891 };
-1 5892 }
-1 5893 axe.utils.getFriendlyUriEnd = function getFriendlyUriEnd() {
-1 5894 var uri = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
-1 5895 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-1 5896 if (uri.length <= 1 || uri.substr(0, 5) === 'data:' || uri.substr(0, 11) === 'javascript:' || uri.includes('?')) {
-1 5897 return;
-1 5898 }
-1 5899 var currentDomain = options.currentDomain, _options$maxLength = options.maxLength, maxLength = _options$maxLength === undefined ? 25 : _options$maxLength;
-1 5900 var _uriParser = uriParser(uri), path = _uriParser.path, domain = _uriParser.domain, hash = _uriParser.hash;
-1 5901 var pathEnd = path.substr(path.substr(0, path.length - 2).lastIndexOf('/') + 1);
-1 5902 if (hash) {
-1 5903 if (pathEnd && (pathEnd + hash).length <= maxLength) {
-1 5904 return pathEnd + hash;
-1 5905 } else if (pathEnd.length < 2 && hash.length > 2 && hash.length <= maxLength) {
-1 5906 return hash;
-1 5907 } else {
-1 5908 return;
-1 5909 }
-1 5910 } else if (domain && domain.length < maxLength && path.length <= 1) {
-1 5911 return domain + path;
-1 5912 }
-1 5913 if (path === '/' + pathEnd && domain && currentDomain && domain !== currentDomain && (domain + path).length <= maxLength) {
-1 5914 return domain + path;
-1 5915 }
-1 5916 var lastDotIndex = pathEnd.lastIndexOf('.');
-1 5917 if ((lastDotIndex === -1 || lastDotIndex > 1) && (lastDotIndex !== -1 || pathEnd.length > 2) && pathEnd.length <= maxLength && !pathEnd.match(/index(\.[a-zA-Z]{2-4})?/) && !isMostlyNumbers(pathEnd)) {
-1 5918 return pathEnd;
-1 5919 }
-1 5920 };
-1 5921 'use strict';
-1 5922 function _toConsumableArray(arr) {
-1 5923 if (Array.isArray(arr)) {
-1 5924 for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
-1 5925 arr2[i] = arr[i];
-1 5926 }
-1 5927 return arr2;
-1 5928 } else {
-1 5929 return Array.from(arr);
-1 5930 }
-1 5931 }
-1 5932 var escapeSelector = axe.utils.escapeSelector;
-1 5933 var isXHTML = void 0;
-1 5934 function isUncommonClassName(className) {
-1 5935 return ![ 'focus', 'hover', 'hidden', 'visible', 'dirty', 'touched', 'valid', 'disable', 'enable', 'active', 'col-' ].find(function(str) {
-1 5936 return className.includes(str);
-1 5937 });
-1 5938 }
-1 5939 function getDistinctClassList(elm) {
-1 5940 if (!elm.classList || elm.classList.length === 0) {
-1 5941 return [];
-1 5942 }
-1 5943 var siblings = elm.parentNode && Array.from(elm.parentNode.children || '') || [];
-1 5944 return siblings.reduce(function(classList, childElm) {
-1 5945 if (elm === childElm) {
-1 5946 return classList;
-1 5947 } else {
-1 5948 return classList.filter(function(classItem) {
-1 5949 return !childElm.classList.contains(classItem);
-1 5950 });
-1 5951 }
-1 5952 }, Array.from(elm.classList).filter(isUncommonClassName));
-1 5953 }
-1 5954 var commonNodes = [ 'div', 'span', 'p', 'b', 'i', 'u', 'strong', 'em', 'h2', 'h3' ];
-1 5955 function getNthChildString(elm, selector) {
-1 5956 var siblings = elm.parentNode && Array.from(elm.parentNode.children || '') || [];
-1 5957 var hasMatchingSiblings = siblings.find(function(sibling) {
-1 5958 return sibling !== elm && axe.utils.matchesSelector(sibling, selector);
-1 5959 });
-1 5960 if (hasMatchingSiblings) {
-1 5961 var nthChild = 1 + siblings.indexOf(elm);
-1 5962 return ':nth-child(' + nthChild + ')';
-1 5963 } else {
-1 5964 return '';
-1 5965 }
-1 5966 }
-1 5967 var createSelector = {
-1 5968 getElmId: function getElmId(elm) {
-1 5969 if (!elm.getAttribute('id')) {
-1 5970 return;
-1 5971 }
-1 5972 var id = '#' + escapeSelector(elm.getAttribute('id') || '');
-1 5973 if (!id.match(/player_uid_/) && document.querySelectorAll(id).length === 1) {
-1 5974 return id;
-1 5975 }
-1 5976 },
-1 5977 getCustomElm: function getCustomElm(elm, _ref) {
-1 5978 var isCustomElm = _ref.isCustomElm, nodeName = _ref.nodeName;
-1 5979 if (isCustomElm) {
-1 5980 return nodeName;
-1 5981 }
-1 5982 },
-1 5983 getElmRoleProp: function getElmRoleProp(elm) {
-1 5984 if (elm.hasAttribute('role')) {
-1 5985 return '[role="' + escapeSelector(elm.getAttribute('role')) + '"]';
-1 5986 }
-1 5987 },
-1 5988 getUncommonElm: function getUncommonElm(elm, _ref2) {
-1 5989 var isCommonElm = _ref2.isCommonElm, isCustomElm = _ref2.isCustomElm, nodeName = _ref2.nodeName;
-1 5990 if (!isCommonElm && !isCustomElm) {
-1 5991 if (nodeName === 'input' && elm.hasAttribute('type')) {
-1 5992 nodeName += '[type="' + elm.type + '"]';
-1 5993 }
-1 5994 return nodeName;
-1 5995 }
-1 5996 },
-1 5997 getElmNameProp: function getElmNameProp(elm) {
-1 5998 if (!elm.hasAttribute('id') && elm.name) {
-1 5999 return '[name="' + escapeSelector(elm.name) + '"]';
-1 6000 }
-1 6001 },
-1 6002 getDistinctClass: function getDistinctClass(elm, _ref3) {
-1 6003 var distinctClassList = _ref3.distinctClassList;
-1 6004 if (distinctClassList.length > 0 && distinctClassList.length < 3) {
-1 6005 return '.' + distinctClassList.map(escapeSelector).join('.');
-1 6006 }
-1 6007 },
-1 6008 getFileRefProp: function getFileRefProp(elm) {
-1 6009 var attr = void 0;
-1 6010 if (elm.hasAttribute('href')) {
-1 6011 attr = 'href';
-1 6012 } else if (elm.hasAttribute('src')) {
-1 6013 attr = 'src';
-1 6014 } else {
-1 6015 return;
-1 6016 }
-1 6017 var friendlyUriEnd = axe.utils.getFriendlyUriEnd(elm.getAttribute(attr));
-1 6018 if (friendlyUriEnd) {
-1 6019 return '[' + attr + '$="' + encodeURI(friendlyUriEnd) + '"]';
-1 6020 }
-1 6021 },
-1 6022 getCommonName: function getCommonName(elm, _ref4) {
-1 6023 var nodeName = _ref4.nodeName, isCommonElm = _ref4.isCommonElm;
-1 6024 if (isCommonElm) {
-1 6025 return nodeName;
-1 6026 }
-1 6027 }
-1 6028 };
-1 6029 function getElmFeatures(elm, featureCount) {
-1 6030 if (typeof isXHTML === 'undefined') {
-1 6031 isXHTML = axe.utils.isXHTML(document);
-1 6032 }
-1 6033 var nodeName = escapeSelector(isXHTML ? elm.localName : elm.nodeName.toLowerCase());
-1 6034 var classList = Array.from(elm.classList) || [];
-1 6035 var props = {
-1 6036 nodeName: nodeName,
-1 6037 classList: classList,
-1 6038 isCustomElm: nodeName.includes('-'),
-1 6039 isCommonElm: commonNodes.includes(nodeName),
-1 6040 distinctClassList: getDistinctClassList(elm)
-1 6041 };
-1 6042 return [ createSelector.getCustomElm, createSelector.getElmRoleProp, createSelector.getUncommonElm, createSelector.getElmNameProp, createSelector.getDistinctClass, createSelector.getFileRefProp, createSelector.getCommonName ].reduce(function(features, func) {
-1 6043 if (features.length === featureCount) {
-1 6044 return features;
-1 6045 }
-1 6046 var feature = func(elm, props);
-1 6047 if (feature) {
-1 6048 if (!feature[0].match(/[a-z]/)) {
-1 6049 features.push(feature);
-1 6050 } else {
-1 6051 features.unshift(feature);
-1 6052 }
-1 6053 }
-1 6054 return features;
-1 6055 }, []);
-1 6056 }
-1 6057 axe.utils.getSelector = function createUniqueSelector(elm) {
-1 6058 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-1 6059 if (!elm) {
-1 6060 return '';
-1 6061 }
-1 6062 var selector = void 0, addParent = void 0;
-1 6063 var _options$isUnique = options.isUnique, isUnique = _options$isUnique === undefined ? false : _options$isUnique;
-1 6064 var idSelector = createSelector.getElmId(elm);
-1 6065 var _options$featureCount = options.featureCount, featureCount = _options$featureCount === undefined ? 2 : _options$featureCount, _options$minDepth = options.minDepth, minDepth = _options$minDepth === undefined ? 1 : _options$minDepth, _options$toRoot = options.toRoot, toRoot = _options$toRoot === undefined ? false : _options$toRoot, _options$childSelecto = options.childSelectors, childSelectors = _options$childSelecto === undefined ? [] : _options$childSelecto;
-1 6066 if (idSelector) {
-1 6067 selector = idSelector;
-1 6068 isUnique = true;
-1 6069 } else {
-1 6070 selector = getElmFeatures(elm, featureCount).join('');
-1 6071 selector += getNthChildString(elm, selector);
-1 6072 isUnique = options.isUnique || document.querySelectorAll(selector).length === 1;
-1 6073 if (!isUnique && elm === document.documentElement) {
-1 6074 selector += ':root';
-1 6075 }
-1 6076 addParent = minDepth !== 0 || !isUnique;
-1 6077 }
-1 6078 var selectorParts = [ selector ].concat(_toConsumableArray(childSelectors));
-1 6079 if (elm.parentElement && (toRoot || addParent)) {
-1 6080 return createUniqueSelector(elm.parentNode, {
-1 6081 toRoot: toRoot,
-1 6082 isUnique: isUnique,
-1 6083 childSelectors: selectorParts,
-1 6084 featureCount: 1,
-1 6085 minDepth: minDepth - 1
-1 6086 });
-1 6087 } else {
-1 6088 return selectorParts.join(' > ');
-1 6089 }
-1 6090 };
-1 6091 'use strict';
-1 6092 function getXPathArray(node, path) {
-1 6093 var sibling, count;
-1 6094 if (!node) {
-1 6095 return [];
-1 6096 }
-1 6097 if (!path && node.nodeType === 9) {
-1 6098 path = [ {
-1 6099 str: 'html'
-1 6100 } ];
-1 6101 return path;
-1 6102 }
-1 6103 path = path || [];
-1 6104 if (node.parentNode && node.parentNode !== node) {
-1 6105 path = getXPathArray(node.parentNode, path);
-1 6106 }
-1 6107 if (node.previousSibling) {
-1 6108 count = 1;
-1 6109 sibling = node.previousSibling;
-1 6110 do {
-1 6111 if (sibling.nodeType === 1 && sibling.nodeName === node.nodeName) {
-1 6112 count++;
-1 6113 }
-1 6114 sibling = sibling.previousSibling;
-1 6115 } while (sibling);
-1 6116 if (count === 1) {
-1 6117 count = null;
-1 6118 }
-1 6119 } else if (node.nextSibling) {
-1 6120 sibling = node.nextSibling;
-1 6121 do {
-1 6122 if (sibling.nodeType === 1 && sibling.nodeName === node.nodeName) {
-1 6123 count = 1;
-1 6124 sibling = null;
-1 6125 } else {
-1 6126 count = null;
-1 6127 sibling = sibling.previousSibling;
-1 6128 }
-1 6129 } while (sibling);
-1 6130 }
-1 6131 if (node.nodeType === 1) {
-1 6132 var element = {};
-1 6133 element.str = node.nodeName.toLowerCase();
-1 6134 var id = node.getAttribute && axe.utils.escapeSelector(node.getAttribute('id'));
-1 6135 if (id && node.ownerDocument.querySelectorAll('#' + id).length === 1) {
-1 6136 element.id = node.getAttribute('id');
-1 6137 }
-1 6138 if (count > 1) {
-1 6139 element.count = count;
-1 6140 }
-1 6141 path.push(element);
-1 6142 }
-1 6143 return path;
-1 6144 }
-1 6145 function xpathToString(xpathArray) {
-1 6146 return xpathArray.reduce(function(str, elm) {
-1 6147 if (elm.id) {
-1 6148 return '/' + elm.str + '[@id=\'' + elm.id + '\']';
-1 6149 } else {
-1 6150 return str + ('/' + elm.str) + (elm.count > 0 ? '[' + elm.count + ']' : '');
-1 6151 }
-1 6152 }, '');
-1 6153 }
-1 6154 axe.utils.getXpath = function getXpath(node) {
-1 6155 var xpathArray = getXPathArray(node);
-1 6156 return xpathToString(xpathArray);
-1 6157 };
-1 6158 'use strict';
-1 6159 var styleSheet;
-1 6160 function injectStyle(style) {
-1 6161 'use strict';
-1 6162 if (styleSheet && styleSheet.parentNode) {
-1 6163 if (styleSheet.styleSheet === undefined) {
-1 6164 styleSheet.appendChild(document.createTextNode(style));
-1 6165 } else {
-1 6166 styleSheet.styleSheet.cssText += style;
-1 6167 }
-1 6168 return styleSheet;
-1 6169 }
-1 6170 if (!style) {
-1 6171 return;
-1 6172 }
-1 6173 var head = document.head || document.getElementsByTagName('head')[0];
-1 6174 styleSheet = document.createElement('style');
-1 6175 styleSheet.type = 'text/css';
-1 6176 if (styleSheet.styleSheet === undefined) {
-1 6177 styleSheet.appendChild(document.createTextNode(style));
-1 6178 } else {
-1 6179 styleSheet.styleSheet.cssText = style;
-1 6180 }
-1 6181 head.appendChild(styleSheet);
-1 6182 return styleSheet;
-1 6183 }
-1 6184 axe.utils.injectStyle = injectStyle;
-1 6185 'use strict';
-1 6186 axe.utils.isHidden = function isHidden(el, recursed) {
-1 6187 'use strict';
-1 6188 if (el.nodeType === 9) {
-1 6189 return false;
-1 6190 }
-1 6191 var style = window.getComputedStyle(el, null);
-1 6192 if (!style || !el.parentNode || style.getPropertyValue('display') === 'none' || !recursed && style.getPropertyValue('visibility') === 'hidden' || el.getAttribute('aria-hidden') === 'true') {
-1 6193 return true;
-1 6194 }
-1 6195 return axe.utils.isHidden(el.parentNode, true);
-1 6196 };
-1 6197 'use strict';
-1 6198 axe.utils.isXHTML = function(doc) {
-1 6199 'use strict';
-1 6200 if (!doc.createElement) {
-1 6201 return false;
-1 6202 }
-1 6203 return doc.createElement('A').localName === 'A';
-1 6204 };
-1 6205 'use strict';
-1 6206 function pushFrame(resultSet, options, frameElement, frameSelector) {
-1 6207 'use strict';
-1 6208 var frameXpath = axe.utils.getXpath(frameElement);
-1 6209 var frameSpec = {
-1 6210 element: frameElement,
-1 6211 selector: frameSelector,
-1 6212 xpath: frameXpath
-1 6213 };
-1 6214 resultSet.forEach(function(res) {
-1 6215 res.node = axe.utils.DqElement.fromFrame(res.node, options, frameSpec);
-1 6216 var checks = axe.utils.getAllChecks(res);
-1 6217 if (checks.length) {
-1 6218 checks.forEach(function(check) {
-1 6219 check.relatedNodes = check.relatedNodes.map(function(node) {
-1 6220 return axe.utils.DqElement.fromFrame(node, options, frameSpec);
-1 6221 });
-1 6222 });
-1 6223 }
-1 6224 });
-1 6225 }
-1 6226 function spliceNodes(target, to) {
-1 6227 'use strict';
-1 6228 var firstFromFrame = to[0].node, sorterResult, t;
-1 6229 for (var i = 0, l = target.length; i < l; i++) {
-1 6230 t = target[i].node;
-1 6231 sorterResult = axe.utils.nodeSorter(t.element, firstFromFrame.element);
-1 6232 if (sorterResult > 0 || sorterResult === 0 && firstFromFrame.selector.length < t.selector.length) {
-1 6233 target.splice.apply(target, [ i, 0 ].concat(to));
-1 6234 return;
-1 6235 }
-1 6236 }
-1 6237 target.push.apply(target, to);
-1 6238 }
-1 6239 function normalizeResult(result) {
-1 6240 'use strict';
-1 6241 if (!result || !result.results) {
-1 6242 return null;
-1 6243 }
-1 6244 if (!Array.isArray(result.results)) {
-1 6245 return [ result.results ];
-1 6246 }
-1 6247 if (!result.results.length) {
-1 6248 return null;
-1 6249 }
-1 6250 return result.results;
-1 6251 }
-1 6252 axe.utils.mergeResults = function mergeResults(frameResults, options) {
-1 6253 'use strict';
-1 6254 var result = [];
-1 6255 frameResults.forEach(function(frameResult) {
-1 6256 var results = normalizeResult(frameResult);
-1 6257 if (!results || !results.length) {
-1 6258 return;
-1 6259 }
-1 6260 results.forEach(function(ruleResult) {
-1 6261 if (ruleResult.nodes && frameResult.frame) {
-1 6262 pushFrame(ruleResult.nodes, options, frameResult.frameElement, frameResult.frame);
-1 6263 }
-1 6264 var res = axe.utils.findBy(result, 'id', ruleResult.id);
-1 6265 if (!res) {
-1 6266 result.push(ruleResult);
-1 6267 } else {
-1 6268 if (ruleResult.nodes.length) {
-1 6269 spliceNodes(res.nodes, ruleResult.nodes);
-1 6270 }
-1 6271 }
-1 6272 });
-1 6273 });
-1 6274 return result;
-1 6275 };
-1 6276 'use strict';
-1 6277 axe.utils.nodeSorter = function nodeSorter(a, b) {
-1 6278 'use strict';
-1 6279 if (a === b) {
-1 6280 return 0;
-1 6281 }
-1 6282 if (a.compareDocumentPosition(b) & 4) {
-1 6283 return -1;
-1 6284 }
-1 6285 return 1;
-1 6286 };
-1 6287 'use strict';
-1 6288 utils.performanceTimer = function() {
-1 6289 'use strict';
-1 6290 function now() {
-1 6291 if (window.performance && window.performance) {
-1 6292 return window.performance.now();
-1 6293 }
-1 6294 }
-1 6295 var originalTime = null;
-1 6296 var lastRecordedTime = now();
-1 6297 return {
-1 6298 start: function start() {
-1 6299 this.mark('mark_axe_start');
-1 6300 },
-1 6301 end: function end() {
-1 6302 this.mark('mark_axe_end');
-1 6303 this.measure('axe', 'mark_axe_start', 'mark_axe_end');
-1 6304 this.logMeasures('axe');
-1 6305 },
-1 6306 auditStart: function auditStart() {
-1 6307 this.mark('mark_audit_start');
-1 6308 },
-1 6309 auditEnd: function auditEnd() {
-1 6310 this.mark('mark_audit_end');
-1 6311 this.measure('audit_start_to_end', 'mark_audit_start', 'mark_audit_end');
-1 6312 this.logMeasures();
-1 6313 },
-1 6314 mark: function mark(markName) {
-1 6315 if (window.performance && window.performance.mark !== undefined) {
-1 6316 window.performance.mark(markName);
-1 6317 }
-1 6318 },
-1 6319 measure: function measure(measureName, startMark, endMark) {
-1 6320 if (window.performance && window.performance.measure !== undefined) {
-1 6321 window.performance.measure(measureName, startMark, endMark);
-1 6322 }
-1 6323 },
-1 6324 logMeasures: function logMeasures(measureName) {
-1 6325 function log(req) {
-1 6326 axe.log('Measure ' + req.name + ' took ' + req.duration + 'ms');
-1 6327 }
-1 6328 if (window.performance && window.performance.getEntriesByType !== undefined) {
-1 6329 var measures = window.performance.getEntriesByType('measure');
-1 6330 for (var i = 0; i < measures.length; ++i) {
-1 6331 var req = measures[i];
-1 6332 if (req.name === measureName) {
-1 6333 log(req);
-1 6334 return;
-1 6335 }
-1 6336 log(req);
-1 6337 }
-1 6338 }
-1 6339 },
-1 6340 timeElapsed: function timeElapsed() {
-1 6341 return now() - lastRecordedTime;
-1 6342 },
-1 6343 reset: function reset() {
-1 6344 if (!originalTime) {
-1 6345 originalTime = now();
-1 6346 }
-1 6347 lastRecordedTime = now();
-1 6348 }
-1 6349 };
-1 6350 }();
-1 6351 'use strict';
-1 6352 if (typeof Object.assign !== 'function') {
-1 6353 (function() {
-1 6354 Object.assign = function(target) {
-1 6355 'use strict';
-1 6356 if (target === undefined || target === null) {
-1 6357 throw new TypeError('Cannot convert undefined or null to object');
-1 6358 }
-1 6359 var output = Object(target);
-1 6360 for (var index = 1; index < arguments.length; index++) {
-1 6361 var source = arguments[index];
-1 6362 if (source !== undefined && source !== null) {
-1 6363 for (var nextKey in source) {
-1 6364 if (source.hasOwnProperty(nextKey)) {
-1 6365 output[nextKey] = source[nextKey];
-1 6366 }
-1 6367 }
-1 6368 }
-1 6369 }
-1 6370 return output;
-1 6371 };
-1 6372 })();
-1 6373 }
-1 6374 if (!Array.prototype.find) {
-1 6375 Object.defineProperty(Array.prototype, 'find', {
-1 6376 value: function value(predicate) {
-1 6377 if (this === null) {
-1 6378 throw new TypeError('Array.prototype.find called on null or undefined');
-1 6379 }
-1 6380 if (typeof predicate !== 'function') {
-1 6381 throw new TypeError('predicate must be a function');
-1 6382 }
-1 6383 var list = Object(this);
-1 6384 var length = list.length >>> 0;
-1 6385 var thisArg = arguments[1];
-1 6386 var value;
-1 6387 for (var i = 0; i < length; i++) {
-1 6388 value = list[i];
-1 6389 if (predicate.call(thisArg, value, i, list)) {
-1 6390 return value;
-1 6391 }
-1 6392 }
-1 6393 return undefined;
-1 6394 }
-1 6395 });
-1 6396 }
-1 6397 axe.utils.pollyfillElementsFromPoint = function() {
-1 6398 if (document.elementsFromPoint) {
-1 6399 return document.elementsFromPoint;
-1 6400 }
-1 6401 if (document.msElementsFromPoint) {
-1 6402 return document.msElementsFromPoint;
-1 6403 }
-1 6404 var usePointer = function() {
-1 6405 var element = document.createElement('x');
-1 6406 element.style.cssText = 'pointer-events:auto';
-1 6407 return element.style.pointerEvents === 'auto';
-1 6408 }();
-1 6409 var cssProp = usePointer ? 'pointer-events' : 'visibility';
-1 6410 var cssDisableVal = usePointer ? 'none' : 'hidden';
-1 6411 var style = document.createElement('style');
-1 6412 style.innerHTML = usePointer ? '* { pointer-events: all }' : '* { visibility: visible }';
-1 6413 return function(x, y) {
-1 6414 var current, i, d;
-1 6415 var elements = [];
-1 6416 var previousPointerEvents = [];
-1 6417 document.head.appendChild(style);
-1 6418 while ((current = document.elementFromPoint(x, y)) && elements.indexOf(current) === -1) {
-1 6419 elements.push(current);
-1 6420 previousPointerEvents.push({
-1 6421 value: current.style.getPropertyValue(cssProp),
-1 6422 priority: current.style.getPropertyPriority(cssProp)
-1 6423 });
-1 6424 current.style.setProperty(cssProp, cssDisableVal, 'important');
-1 6425 }
-1 6426 for (i = previousPointerEvents.length; !!(d = previousPointerEvents[--i]); ) {
-1 6427 elements[i].style.setProperty(cssProp, d.value ? d.value : '', d.priority);
-1 6428 }
-1 6429 document.head.removeChild(style);
-1 6430 return elements;
-1 6431 };
-1 6432 };
-1 6433 if (typeof window.addEventListener === 'function') {
-1 6434 document.elementsFromPoint = axe.utils.pollyfillElementsFromPoint();
-1 6435 }
-1 6436 if (!Array.prototype.includes) {
-1 6437 Object.defineProperty(Array.prototype, 'includes', {
-1 6438 value: function value(searchElement) {
-1 6439 'use strict';
-1 6440 var O = Object(this);
-1 6441 var len = parseInt(O.length, 10) || 0;
-1 6442 if (len === 0) {
-1 6443 return false;
-1 6444 }
-1 6445 var n = parseInt(arguments[1], 10) || 0;
-1 6446 var k;
-1 6447 if (n >= 0) {
-1 6448 k = n;
-1 6449 } else {
-1 6450 k = len + n;
-1 6451 if (k < 0) {
-1 6452 k = 0;
-1 6453 }
-1 6454 }
-1 6455 var currentElement;
-1 6456 while (k < len) {
-1 6457 currentElement = O[k];
-1 6458 if (searchElement === currentElement || searchElement !== searchElement && currentElement !== currentElement) {
-1 6459 return true;
-1 6460 }
-1 6461 k++;
-1 6462 }
-1 6463 return false;
-1 6464 }
-1 6465 });
-1 6466 }
-1 6467 if (!Array.prototype.some) {
-1 6468 Object.defineProperty(Array.prototype, 'some', {
-1 6469 value: function value(fun) {
-1 6470 'use strict';
-1 6471 if (this == null) {
-1 6472 throw new TypeError('Array.prototype.some called on null or undefined');
-1 6473 }
-1 6474 if (typeof fun !== 'function') {
-1 6475 throw new TypeError();
-1 6476 }
-1 6477 var t = Object(this);
-1 6478 var len = t.length >>> 0;
-1 6479 var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
-1 6480 for (var i = 0; i < len; i++) {
-1 6481 if (i in t && fun.call(thisArg, t[i], i, t)) {
-1 6482 return true;
-1 6483 }
-1 6484 }
-1 6485 return false;
-1 6486 }
-1 6487 });
-1 6488 }
-1 6489 if (!Array.from) {
-1 6490 Object.defineProperty(Array, 'from', {
-1 6491 value: function() {
-1 6492 var toStr = Object.prototype.toString;
-1 6493 var isCallable = function isCallable(fn) {
-1 6494 return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
-1 6495 };
-1 6496 var toInteger = function toInteger(value) {
-1 6497 var number = Number(value);
-1 6498 if (isNaN(number)) {
-1 6499 return 0;
-1 6500 }
-1 6501 if (number === 0 || !isFinite(number)) {
-1 6502 return number;
-1 6503 }
-1 6504 return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
-1 6505 };
-1 6506 var maxSafeInteger = Math.pow(2, 53) - 1;
-1 6507 var toLength = function toLength(value) {
-1 6508 var len = toInteger(value);
-1 6509 return Math.min(Math.max(len, 0), maxSafeInteger);
-1 6510 };
-1 6511 return function from(arrayLike) {
-1 6512 var C = this;
-1 6513 var items = Object(arrayLike);
-1 6514 if (arrayLike == null) {
-1 6515 throw new TypeError('Array.from requires an array-like object - not null or undefined');
-1 6516 }
-1 6517 var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
-1 6518 var T;
-1 6519 if (typeof mapFn !== 'undefined') {
-1 6520 if (!isCallable(mapFn)) {
-1 6521 throw new TypeError('Array.from: when provided, the second argument must be a function');
-1 6522 }
-1 6523 if (arguments.length > 2) {
-1 6524 T = arguments[2];
-1 6525 }
-1 6526 }
-1 6527 var len = toLength(items.length);
-1 6528 var A = isCallable(C) ? Object(new C(len)) : new Array(len);
-1 6529 var k = 0;
-1 6530 var kValue;
-1 6531 while (k < len) {
-1 6532 kValue = items[k];
-1 6533 if (mapFn) {
-1 6534 A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
-1 6535 } else {
-1 6536 A[k] = kValue;
-1 6537 }
-1 6538 k += 1;
-1 6539 }
-1 6540 A.length = len;
-1 6541 return A;
-1 6542 };
-1 6543 }()
-1 6544 });
-1 6545 }
-1 6546 if (!String.prototype.includes) {
-1 6547 String.prototype.includes = function(search, start) {
-1 6548 if (typeof start !== 'number') {
-1 6549 start = 0;
-1 6550 }
-1 6551 if (start + search.length > this.length) {
-1 6552 return false;
-1 6553 } else {
-1 6554 return this.indexOf(search, start) !== -1;
-1 6555 }
-1 6556 };
-1 6557 }
-1 6558 'use strict';
-1 6559 var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-1 6560 return typeof obj;
-1 6561 } : function(obj) {
-1 6562 return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-1 6563 };
-1 6564 function getIncompleteReason(checkData, messages) {
-1 6565 function getDefaultMsg(messages) {
-1 6566 if (messages.incomplete && messages.incomplete.default) {
-1 6567 return messages.incomplete.default;
-1 6568 } else {
-1 6569 return helpers.incompleteFallbackMessage();
-1 6570 }
-1 6571 }
-1 6572 if (checkData && checkData.missingData) {
-1 6573 try {
-1 6574 var msg = messages.incomplete[checkData.missingData[0].reason];
-1 6575 if (!msg) {
-1 6576 throw new Error();
-1 6577 }
-1 6578 return msg;
-1 6579 } catch (e) {
-1 6580 if (typeof checkData.missingData === 'string') {
-1 6581 return messages.incomplete[checkData.missingData];
-1 6582 } else {
-1 6583 return getDefaultMsg(messages);
-1 6584 }
-1 6585 }
-1 6586 } else {
-1 6587 return getDefaultMsg(messages);
-1 6588 }
-1 6589 }
-1 6590 function extender(checksData, shouldBeTrue) {
-1 6591 'use strict';
-1 6592 return function(check) {
-1 6593 var sourceData = checksData[check.id] || {};
-1 6594 var messages = sourceData.messages || {};
-1 6595 var data = Object.assign({}, sourceData);
-1 6596 delete data.messages;
-1 6597 if (check.result === undefined) {
-1 6598 if (_typeof(messages.incomplete) === 'object') {
-1 6599 data.message = function() {
-1 6600 return getIncompleteReason(check.data, messages);
-1 6601 };
-1 6602 } else {
-1 6603 data.message = messages.incomplete;
-1 6604 }
-1 6605 } else {
-1 6606 data.message = check.result === shouldBeTrue ? messages.pass : messages.fail;
-1 6607 }
-1 6608 axe.utils.extendMetaData(check, data);
-1 6609 };
-1 6610 }
-1 6611 axe.utils.publishMetaData = function(ruleResult) {
-1 6612 'use strict';
-1 6613 var checksData = axe._audit.data.checks || {};
-1 6614 var rulesData = axe._audit.data.rules || {};
-1 6615 var rule = axe.utils.findBy(axe._audit.rules, 'id', ruleResult.id) || {};
-1 6616 ruleResult.tags = axe.utils.clone(rule.tags || []);
-1 6617 var shouldBeTrue = extender(checksData, true);
-1 6618 var shouldBeFalse = extender(checksData, false);
-1 6619 ruleResult.nodes.forEach(function(detail) {
-1 6620 detail.any.forEach(shouldBeTrue);
-1 6621 detail.all.forEach(shouldBeTrue);
-1 6622 detail.none.forEach(shouldBeFalse);
-1 6623 });
-1 6624 axe.utils.extendMetaData(ruleResult, axe.utils.clone(rulesData[ruleResult.id] || {}));
-1 6625 };
-1 6626 'use strict';
-1 6627 var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-1 6628 return typeof obj;
-1 6629 } : function(obj) {
-1 6630 return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-1 6631 };
-1 6632 (function() {
-1 6633 'use strict';
-1 6634 function noop() {}
-1 6635 function funcGuard(f) {
-1 6636 if (typeof f !== 'function') {
-1 6637 throw new TypeError('Queue methods require functions as arguments');
-1 6638 }
-1 6639 }
-1 6640 function queue() {
-1 6641 var tasks = [];
-1 6642 var started = 0;
-1 6643 var remaining = 0;
-1 6644 var completeQueue = noop;
-1 6645 var complete = false;
-1 6646 var err;
-1 6647 var defaultFail = function defaultFail(e) {
-1 6648 err = e;
-1 6649 setTimeout(function() {
-1 6650 if (err !== undefined && err !== null) {
-1 6651 axe.log('Uncaught error (of queue)', err);
-1 6652 }
-1 6653 }, 1);
-1 6654 };
-1 6655 var failed = defaultFail;
-1 6656 function createResolve(i) {
-1 6657 return function(r) {
-1 6658 tasks[i] = r;
-1 6659 remaining -= 1;
-1 6660 if (!remaining && completeQueue !== noop) {
-1 6661 complete = true;
-1 6662 completeQueue(tasks);
-1 6663 }
-1 6664 };
-1 6665 }
-1 6666 function abort(msg) {
-1 6667 completeQueue = noop;
-1 6668 failed(msg);
-1 6669 return tasks;
-1 6670 }
-1 6671 function pop() {
-1 6672 var length = tasks.length;
-1 6673 for (;started < length; started++) {
-1 6674 var task = tasks[started];
-1 6675 try {
-1 6676 task.call(null, createResolve(started), abort);
-1 6677 } catch (e) {
-1 6678 abort(e);
-1 6679 }
-1 6680 }
-1 6681 }
-1 6682 var q = {
-1 6683 defer: function defer(fn) {
-1 6684 if ((typeof fn === 'undefined' ? 'undefined' : _typeof(fn)) === 'object' && fn.then && fn.catch) {
-1 6685 var defer = fn;
-1 6686 fn = function fn(resolve, reject) {
-1 6687 defer.then(resolve).catch(reject);
-1 6688 };
-1 6689 }
-1 6690 funcGuard(fn);
-1 6691 if (err !== undefined) {
-1 6692 return;
-1 6693 } else if (complete) {
-1 6694 throw new Error('Queue already completed');
-1 6695 }
-1 6696 tasks.push(fn);
-1 6697 ++remaining;
-1 6698 pop();
-1 6699 return q;
-1 6700 },
-1 6701 then: function then(fn) {
-1 6702 funcGuard(fn);
-1 6703 if (completeQueue !== noop) {
-1 6704 throw new Error('queue `then` already set');
-1 6705 }
-1 6706 if (!err) {
-1 6707 completeQueue = fn;
-1 6708 if (!remaining) {
-1 6709 complete = true;
-1 6710 completeQueue(tasks);
-1 6711 }
-1 6712 }
-1 6713 return q;
-1 6714 },
-1 6715 catch: function _catch(fn) {
-1 6716 funcGuard(fn);
-1 6717 if (failed !== defaultFail) {
-1 6718 throw new Error('queue `catch` already set');
-1 6719 }
-1 6720 if (!err) {
-1 6721 failed = fn;
-1 6722 } else {
-1 6723 fn(err);
-1 6724 err = null;
-1 6725 }
-1 6726 return q;
-1 6727 },
-1 6728 abort: abort
-1 6729 };
-1 6730 return q;
-1 6731 }
-1 6732 axe.utils.queue = queue;
-1 6733 })();
-1 6734 'use strict';
-1 6735 var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-1 6736 return typeof obj;
-1 6737 } : function(obj) {
-1 6738 return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-1 6739 };
-1 6740 (function(exports) {
-1 6741 'use strict';
-1 6742 var messages = {}, subscribers = {}, errorTypes = Object.freeze([ 'EvalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError' ]);
-1 6743 function _getSource() {
-1 6744 var application = 'axe', version = '', src;
-1 6745 if (typeof axe !== 'undefined' && axe._audit && !axe._audit.application) {
-1 6746 application = axe._audit.application;
-1 6747 }
-1 6748 if (typeof axe !== 'undefined') {
-1 6749 version = axe.version;
-1 6750 }
-1 6751 src = application + '.' + version;
-1 6752 return src;
-1 6753 }
-1 6754 function verify(postedMessage) {
-1 6755 if ((typeof postedMessage === 'undefined' ? 'undefined' : _typeof(postedMessage)) === 'object' && typeof postedMessage.uuid === 'string' && postedMessage._respondable === true) {
-1 6756 var messageSource = _getSource();
-1 6757 return postedMessage._source === messageSource || postedMessage._source === 'axe.x.y.z' || messageSource === 'axe.x.y.z';
-1 6758 }
-1 6759 return false;
-1 6760 }
-1 6761 function post(win, topic, message, uuid, keepalive, callback) {
-1 6762 var error;
-1 6763 if (message instanceof Error) {
-1 6764 error = {
-1 6765 name: message.name,
-1 6766 message: message.message,
-1 6767 stack: message.stack
-1 6768 };
-1 6769 message = undefined;
-1 6770 }
-1 6771 var data = {
-1 6772 uuid: uuid,
-1 6773 topic: topic,
-1 6774 message: message,
-1 6775 error: error,
-1 6776 _respondable: true,
-1 6777 _source: _getSource(),
-1 6778 _keepalive: keepalive
-1 6779 };
-1 6780 if (typeof callback === 'function') {
-1 6781 messages[uuid] = callback;
-1 6782 }
-1 6783 win.postMessage(JSON.stringify(data), '*');
-1 6784 }
-1 6785 function respondable(win, topic, message, keepalive, callback) {
-1 6786 var id = uuid.v1();
-1 6787 post(win, topic, message, id, keepalive, callback);
-1 6788 }
-1 6789 respondable.subscribe = function(topic, callback) {
-1 6790 subscribers[topic] = callback;
-1 6791 };
-1 6792 respondable.isInFrame = function(win) {
-1 6793 win = win || window;
-1 6794 return !!win.frameElement;
-1 6795 };
-1 6796 function createResponder(source, topic, uuid) {
-1 6797 return function(message, keepalive, callback) {
-1 6798 post(source, topic, message, uuid, keepalive, callback);
-1 6799 };
-1 6800 }
-1 6801 function publish(target, data, keepalive) {
-1 6802 var topic = data.topic;
-1 6803 var subscriber = subscribers[topic];
-1 6804 if (subscriber) {
-1 6805 var responder = createResponder(target, null, data.uuid);
-1 6806 subscriber(data.message, keepalive, responder);
-1 6807 }
-1 6808 }
-1 6809 function buildErrorObject(error) {
-1 6810 var msg = error.message || 'Unknown error occurred';
-1 6811 var errorName = errorTypes.includes(error.name) ? error.name : 'Error';
-1 6812 var ErrConstructor = window[errorName] || Error;
-1 6813 if (error.stack) {
-1 6814 msg += '\n' + error.stack.replace(error.message, '');
-1 6815 }
-1 6816 return new ErrConstructor(msg);
-1 6817 }
-1 6818 function parseMessage(dataString) {
-1 6819 var data;
-1 6820 if (typeof dataString !== 'string') {
-1 6821 return;
-1 6822 }
-1 6823 try {
-1 6824 data = JSON.parse(dataString);
-1 6825 } catch (ex) {}
-1 6826 if (!verify(data)) {
-1 6827 return;
-1 6828 }
-1 6829 if (_typeof(data.error) === 'object') {
-1 6830 data.error = buildErrorObject(data.error);
-1 6831 } else {
-1 6832 data.error = undefined;
-1 6833 }
-1 6834 return data;
-1 6835 }
-1 6836 if (typeof window.addEventListener === 'function') {
-1 6837 window.addEventListener('message', function(e) {
-1 6838 var data = parseMessage(e.data);
-1 6839 if (!data) {
-1 6840 return;
-1 6841 }
-1 6842 var uuid = data.uuid;
-1 6843 var keepalive = data._keepalive;
-1 6844 var callback = messages[uuid];
-1 6845 if (callback) {
-1 6846 var result = data.error || data.message;
-1 6847 var responder = createResponder(e.source, data.topic, uuid);
-1 6848 callback(result, keepalive, responder);
-1 6849 if (!keepalive) {
-1 6850 delete messages[uuid];
-1 6851 }
-1 6852 }
-1 6853 if (!data.error) {
-1 6854 try {
-1 6855 publish(e.source, data, keepalive);
-1 6856 } catch (err) {
-1 6857 post(e.source, data.topic, err, uuid, false);
-1 6858 }
-1 6859 }
-1 6860 }, false);
-1 6861 }
-1 6862 exports.respondable = respondable;
-1 6863 })(utils);
-1 6864 'use strict';
-1 6865 function matchTags(rule, runOnly) {
-1 6866 'use strict';
-1 6867 var include, exclude, matching;
-1 6868 var defaultExclude = axe._audit && axe._audit.tagExclude ? axe._audit.tagExclude : [];
-1 6869 if (runOnly.hasOwnProperty('include') || runOnly.hasOwnProperty('exclude')) {
-1 6870 include = runOnly.include || [];
-1 6871 include = Array.isArray(include) ? include : [ include ];
-1 6872 exclude = runOnly.exclude || [];
-1 6873 exclude = Array.isArray(exclude) ? exclude : [ exclude ];
-1 6874 exclude = exclude.concat(defaultExclude.filter(function(tag) {
-1 6875 return include.indexOf(tag) === -1;
-1 6876 }));
-1 6877 } else {
-1 6878 include = Array.isArray(runOnly) ? runOnly : [ runOnly ];
-1 6879 exclude = defaultExclude.filter(function(tag) {
-1 6880 return include.indexOf(tag) === -1;
-1 6881 });
-1 6882 }
-1 6883 matching = include.some(function(tag) {
-1 6884 return rule.tags.indexOf(tag) !== -1;
-1 6885 });
-1 6886 if (matching || include.length === 0 && rule.enabled !== false) {
-1 6887 return exclude.every(function(tag) {
-1 6888 return rule.tags.indexOf(tag) === -1;
-1 6889 });
-1 6890 } else {
-1 6891 return false;
-1 6892 }
-1 6893 }
-1 6894 axe.utils.ruleShouldRun = function(rule, context, options) {
-1 6895 'use strict';
-1 6896 var runOnly = options.runOnly || {};
-1 6897 var ruleOptions = (options.rules || {})[rule.id];
-1 6898 if (rule.pageLevel && !context.page) {
-1 6899 return false;
-1 6900 } else if (runOnly.type === 'rule') {
-1 6901 return runOnly.values.indexOf(rule.id) !== -1;
-1 6902 } else if (ruleOptions && typeof ruleOptions.enabled === 'boolean') {
-1 6903 return ruleOptions.enabled;
-1 6904 } else if (runOnly.type === 'tag' && runOnly.values) {
-1 6905 return matchTags(rule, runOnly.values);
-1 6906 } else {
-1 6907 return matchTags(rule, []);
-1 6908 }
-1 6909 };
-1 6910 'use strict';
-1 6911 function getScroll(elm) {
-1 6912 var style = window.getComputedStyle(elm);
-1 6913 var visibleOverflowY = style.getPropertyValue('overflow-y') === 'visible';
-1 6914 var visibleOverflowX = style.getPropertyValue('overflow-x') === 'visible';
-1 6915 if (!visibleOverflowY && elm.scrollHeight > elm.clientHeight || !visibleOverflowX && elm.scrollWidth > elm.clientWidth) {
-1 6916 return {
-1 6917 elm: elm,
-1 6918 top: elm.scrollTop,
-1 6919 left: elm.scrollLeft
-1 6920 };
-1 6921 }
-1 6922 }
-1 6923 function setScroll(elm, top, left) {
-1 6924 if (elm === window) {
-1 6925 return elm.scroll(top, left);
-1 6926 } else {
-1 6927 elm.scrollTop = top;
-1 6928 elm.scrollLeft = left;
-1 6929 }
-1 6930 }
-1 6931 function getElmScrollRecursive(root) {
-1 6932 return Array.from(root.children).reduce(function(scrolls, elm) {
-1 6933 var scroll = getScroll(elm);
-1 6934 if (scroll) {
-1 6935 scrolls.push(scroll);
-1 6936 }
-1 6937 return scrolls.concat(getElmScrollRecursive(elm));
-1 6938 }, []);
-1 6939 }
-1 6940 axe.utils.getScrollState = function getScrollState() {
-1 6941 var win = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window;
-1 6942 var root = win.document.documentElement;
-1 6943 var windowScroll = [ win.pageXOffset !== undefined ? {
-1 6944 elm: win,
-1 6945 top: win.pageYOffset,
-1 6946 left: win.pageXOffset
-1 6947 } : {
-1 6948 elm: root,
-1 6949 top: root.scrollTop,
-1 6950 left: root.scrollLeft
-1 6951 } ];
-1 6952 return windowScroll.concat(getElmScrollRecursive(document.body));
-1 6953 };
-1 6954 axe.utils.setScrollState = function setScrollState(scrollState) {
-1 6955 scrollState.forEach(function(_ref) {
-1 6956 var elm = _ref.elm, top = _ref.top, left = _ref.left;
-1 6957 return setScroll(elm, top, left);
-1 6958 });
-1 6959 };
-1 6960 'use strict';
-1 6961 function getDeepest(collection) {
-1 6962 'use strict';
-1 6963 return collection.sort(function(a, b) {
-1 6964 if (axe.utils.contains(a, b)) {
-1 6965 return 1;
-1 6966 }
-1 6967 return -1;
-1 6968 })[0];
-1 6969 }
-1 6970 function isNodeInContext(node, context) {
-1 6971 'use strict';
-1 6972 var include = context.include && getDeepest(context.include.filter(function(candidate) {
-1 6973 return axe.utils.contains(candidate, node);
-1 6974 }));
-1 6975 var exclude = context.exclude && getDeepest(context.exclude.filter(function(candidate) {
-1 6976 return axe.utils.contains(candidate, node);
-1 6977 }));
-1 6978 if (!exclude && include || exclude && axe.utils.contains(exclude, include)) {
-1 6979 return true;
-1 6980 }
-1 6981 return false;
-1 6982 }
-1 6983 function pushNode(result, nodes, context) {
-1 6984 'use strict';
-1 6985 for (var i = 0, l = nodes.length; i < l; i++) {
-1 6986 if (result.indexOf(nodes[i]) === -1 && isNodeInContext(nodes[i], context)) {
-1 6987 result.push(nodes[i]);
-1 6988 }
-1 6989 }
-1 6990 }
-1 6991 axe.utils.select = function select(selector, context) {
-1 6992 'use strict';
-1 6993 var result = [], candidate;
-1 6994 for (var i = 0, l = context.include.length; i < l; i++) {
-1 6995 candidate = context.include[i];
-1 6996 if (candidate.nodeType === candidate.ELEMENT_NODE && axe.utils.matchesSelector(candidate, selector)) {
-1 6997 pushNode(result, [ candidate ], context);
-1 6998 }
-1 6999 pushNode(result, candidate.querySelectorAll(selector), context);
-1 7000 }
-1 7001 return result.sort(axe.utils.nodeSorter);
-1 7002 };
-1 7003 'use strict';
-1 7004 axe.utils.toArray = function(thing) {
-1 7005 'use strict';
-1 7006 return Array.prototype.slice.call(thing);
-1 7007 };
-1 7008 'use strict';
-1 7009 var uuid;
-1 7010 (function(_global) {
-1 7011 var _rng;
-1 7012 var _crypto = _global.crypto || _global.msCrypto;
-1 7013 if (!_rng && _crypto && _crypto.getRandomValues) {
-1 7014 var _rnds8 = new Uint8Array(16);
-1 7015 _rng = function whatwgRNG() {
-1 7016 _crypto.getRandomValues(_rnds8);
-1 7017 return _rnds8;
-1 7018 };
-1 7019 }
-1 7020 if (!_rng) {
-1 7021 var _rnds = new Array(16);
-1 7022 _rng = function _rng() {
-1 7023 for (var i = 0, r; i < 16; i++) {
-1 7024 if ((i & 3) === 0) {
-1 7025 r = Math.random() * 4294967296;
-1 7026 }
-1 7027 _rnds[i] = r >>> ((i & 3) << 3) & 255;
-1 7028 }
-1 7029 return _rnds;
-1 7030 };
-1 7031 }
-1 7032 var BufferClass = typeof _global.Buffer == 'function' ? _global.Buffer : Array;
-1 7033 var _byteToHex = [];
-1 7034 var _hexToByte = {};
-1 7035 for (var i = 0; i < 256; i++) {
-1 7036 _byteToHex[i] = (i + 256).toString(16).substr(1);
-1 7037 _hexToByte[_byteToHex[i]] = i;
-1 7038 }
-1 7039 function parse(s, buf, offset) {
-1 7040 var i = buf && offset || 0, ii = 0;
-1 7041 buf = buf || [];
-1 7042 s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) {
-1 7043 if (ii < 16) {
-1 7044 buf[i + ii++] = _hexToByte[oct];
-1 7045 }
-1 7046 });
-1 7047 while (ii < 16) {
-1 7048 buf[i + ii++] = 0;
-1 7049 }
-1 7050 return buf;
-1 7051 }
-1 7052 function unparse(buf, offset) {
-1 7053 var i = offset || 0, bth = _byteToHex;
-1 7054 return bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + '-' + bth[buf[i++]] + bth[buf[i++]] + '-' + bth[buf[i++]] + bth[buf[i++]] + '-' + bth[buf[i++]] + bth[buf[i++]] + '-' + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]];
-1 7055 }
-1 7056 var _seedBytes = _rng();
-1 7057 var _nodeId = [ _seedBytes[0] | 1, _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5] ];
-1 7058 var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 16383;
-1 7059 var _lastMSecs = 0, _lastNSecs = 0;
-1 7060 function v1(options, buf, offset) {
-1 7061 var i = buf && offset || 0;
-1 7062 var b = buf || [];
-1 7063 options = options || {};
-1 7064 var clockseq = options.clockseq != null ? options.clockseq : _clockseq;
-1 7065 var msecs = options.msecs != null ? options.msecs : new Date().getTime();
-1 7066 var nsecs = options.nsecs != null ? options.nsecs : _lastNSecs + 1;
-1 7067 var dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 1e4;
-1 7068 if (dt < 0 && options.clockseq == null) {
-1 7069 clockseq = clockseq + 1 & 16383;
-1 7070 }
-1 7071 if ((dt < 0 || msecs > _lastMSecs) && options.nsecs == null) {
-1 7072 nsecs = 0;
-1 7073 }
-1 7074 if (nsecs >= 1e4) {
-1 7075 throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
-1 7076 }
-1 7077 _lastMSecs = msecs;
-1 7078 _lastNSecs = nsecs;
-1 7079 _clockseq = clockseq;
-1 7080 msecs += 122192928e5;
-1 7081 var tl = ((msecs & 268435455) * 1e4 + nsecs) % 4294967296;
-1 7082 b[i++] = tl >>> 24 & 255;
-1 7083 b[i++] = tl >>> 16 & 255;
-1 7084 b[i++] = tl >>> 8 & 255;
-1 7085 b[i++] = tl & 255;
-1 7086 var tmh = msecs / 4294967296 * 1e4 & 268435455;
-1 7087 b[i++] = tmh >>> 8 & 255;
-1 7088 b[i++] = tmh & 255;
-1 7089 b[i++] = tmh >>> 24 & 15 | 16;
-1 7090 b[i++] = tmh >>> 16 & 255;
-1 7091 b[i++] = clockseq >>> 8 | 128;
-1 7092 b[i++] = clockseq & 255;
-1 7093 var node = options.node || _nodeId;
-1 7094 for (var n = 0; n < 6; n++) {
-1 7095 b[i + n] = node[n];
-1 7096 }
-1 7097 return buf ? buf : unparse(b);
-1 7098 }
-1 7099 function v4(options, buf, offset) {
-1 7100 var i = buf && offset || 0;
-1 7101 if (typeof options == 'string') {
-1 7102 buf = options == 'binary' ? new BufferClass(16) : null;
-1 7103 options = null;
-1 7104 }
-1 7105 options = options || {};
-1 7106 var rnds = options.random || (options.rng || _rng)();
-1 7107 rnds[6] = rnds[6] & 15 | 64;
-1 7108 rnds[8] = rnds[8] & 63 | 128;
-1 7109 if (buf) {
-1 7110 for (var ii = 0; ii < 16; ii++) {
-1 7111 buf[i + ii] = rnds[ii];
-1 7112 }
-1 7113 }
-1 7114 return buf || unparse(rnds);
-1 7115 }
-1 7116 uuid = v4;
-1 7117 uuid.v1 = v1;
-1 7118 uuid.v4 = v4;
-1 7119 uuid.parse = parse;
-1 7120 uuid.unparse = unparse;
-1 7121 uuid.BufferClass = BufferClass;
-1 7122 })(window);
-1 7123 'use strict';
-1 7124 axe._load({
-1 7125 data: {
-1 7126 rules: {
-1 7127 accesskeys: {
-1 7128 description: 'Ensures every accesskey attribute value is unique',
-1 7129 help: 'accesskey attribute value must be unique'
-1 7130 },
-1 7131 'area-alt': {
-1 7132 description: 'Ensures <area> elements of image maps have alternate text',
-1 7133 help: 'Active <area> elements must have alternate text'
-1 7134 },
-1 7135 'aria-allowed-attr': {
-1 7136 description: 'Ensures ARIA attributes are allowed for an element\'s role',
-1 7137 help: 'Elements must only use allowed ARIA attributes'
-1 7138 },
-1 7139 'aria-hidden-body': {
-1 7140 description: 'Ensures aria-hidden=\'true\' is not present on the document body.',
-1 7141 help: 'aria-hidden=\'true\' must not be present on the document body'
-1 7142 },
-1 7143 'aria-required-attr': {
-1 7144 description: 'Ensures elements with ARIA roles have all required ARIA attributes',
-1 7145 help: 'Required ARIA attributes must be provided'
-1 7146 },
-1 7147 'aria-required-children': {
-1 7148 description: 'Ensures elements with an ARIA role that require child roles contain them',
-1 7149 help: 'Certain ARIA roles must contain particular children'
-1 7150 },
-1 7151 'aria-required-parent': {
-1 7152 description: 'Ensures elements with an ARIA role that require parent roles are contained by them',
-1 7153 help: 'Certain ARIA roles must be contained by particular parents'
-1 7154 },
-1 7155 'aria-roles': {
-1 7156 description: 'Ensures all elements with a role attribute use a valid value',
-1 7157 help: 'ARIA roles used must conform to valid values'
-1 7158 },
-1 7159 'aria-valid-attr-value': {
-1 7160 description: 'Ensures all ARIA attributes have valid values',
-1 7161 help: 'ARIA attributes must conform to valid values'
-1 7162 },
-1 7163 'aria-valid-attr': {
-1 7164 description: 'Ensures attributes that begin with aria- are valid ARIA attributes',
-1 7165 help: 'ARIA attributes must conform to valid names'
-1 7166 },
-1 7167 'audio-caption': {
-1 7168 description: 'Ensures <audio> elements have captions',
-1 7169 help: '<audio> elements must have a captions track'
-1 7170 },
-1 7171 blink: {
-1 7172 description: 'Ensures <blink> elements are not used',
-1 7173 help: '<blink> elements are deprecated and must not be used'
-1 7174 },
-1 7175 'button-name': {
-1 7176 description: 'Ensures buttons have discernible text',
-1 7177 help: 'Buttons must have discernible text'
-1 7178 },
-1 7179 bypass: {
-1 7180 description: 'Ensures each page has at least one mechanism for a user to bypass navigation and jump straight to the content',
-1 7181 help: 'Page must have means to bypass repeated blocks'
-1 7182 },
-1 7183 checkboxgroup: {
-1 7184 description: 'Ensures related <input type="checkbox"> elements have a group and that that group designation is consistent',
-1 7185 help: 'Checkbox inputs with the same name attribute value must be part of a group'
-1 7186 },
-1 7187 'color-contrast': {
-1 7188 description: 'Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds',
-1 7189 help: 'Elements must have sufficient color contrast'
-1 7190 },
-1 7191 'definition-list': {
-1 7192 description: 'Ensures <dl> elements are structured correctly',
-1 7193 help: '<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script> or <template> elements'
-1 7194 },
-1 7195 dlitem: {
-1 7196 description: 'Ensures <dt> and <dd> elements are contained by a <dl>',
-1 7197 help: '<dt> and <dd> elements must be contained by a <dl>'
-1 7198 },
-1 7199 'document-title': {
-1 7200 description: 'Ensures each HTML document contains a non-empty <title> element',
-1 7201 help: 'Documents must have <title> element to aid in navigation'
-1 7202 },
-1 7203 'duplicate-id': {
-1 7204 description: 'Ensures every id attribute value is unique',
-1 7205 help: 'id attribute value must be unique'
-1 7206 },
-1 7207 'empty-heading': {
-1 7208 description: 'Ensures headings have discernible text',
-1 7209 help: 'Headings must not be empty'
-1 7210 },
-1 7211 'frame-title-unique': {
-1 7212 description: 'Ensures <iframe> and <frame> elements contain a unique title attribute',
-1 7213 help: 'Frames must have a unique title attribute'
-1 7214 },
-1 7215 'frame-title': {
-1 7216 description: 'Ensures <iframe> and <frame> elements contain a non-empty title attribute',
-1 7217 help: 'Frames must have title attribute'
-1 7218 },
-1 7219 'heading-order': {
-1 7220 description: 'Ensures the order of headings is semantically correct',
-1 7221 help: 'Heading levels should only increase by one'
-1 7222 },
-1 7223 'hidden-content': {
-1 7224 description: 'Informs users about hidden content.',
-1 7225 help: 'Hidden content on the page cannot be analyzed'
-1 7226 },
-1 7227 'href-no-hash': {
-1 7228 description: 'Ensures that href values are valid link references to promote only using anchors as links',
-1 7229 help: 'Anchors must only be used as links with valid URLs or URL fragments'
-1 7230 },
-1 7231 'html-has-lang': {
-1 7232 description: 'Ensures every HTML document has a lang attribute',
-1 7233 help: '<html> element must have a lang attribute'
-1 7234 },
-1 7235 'html-lang-valid': {
-1 7236 description: 'Ensures the lang attribute of the <html> element has a valid value',
-1 7237 help: '<html> element must have a valid value for the lang attribute'
-1 7238 },
-1 7239 'image-alt': {
-1 7240 description: 'Ensures <img> elements have alternate text or a role of none or presentation',
-1 7241 help: 'Images must have alternate text'
-1 7242 },
-1 7243 'image-redundant-alt': {
-1 7244 description: 'Ensure button and link text is not repeated as image alternative',
-1 7245 help: 'Text of buttons and links should not be repeated in the image alternative'
-1 7246 },
-1 7247 'input-image-alt': {
-1 7248 description: 'Ensures <input type="image"> elements have alternate text',
-1 7249 help: 'Image buttons must have alternate text'
-1 7250 },
-1 7251 'label-title-only': {
-1 7252 description: 'Ensures that every form element is not solely labeled using the title or aria-describedby attributes',
-1 7253 help: 'Form elements should have a visible label'
-1 7254 },
-1 7255 label: {
-1 7256 description: 'Ensures every form element has a label',
-1 7257 help: 'Form elements must have labels'
-1 7258 },
-1 7259 'landmark-main-is-top-level': {
-1 7260 description: 'The main landmark should not be contained in another landmark',
-1 7261 help: 'Main landmark is not at top level'
-1 7262 },
-1 7263 'landmark-one-main': {
-1 7264 description: 'Ensures a navigation point to the primary content of the page. If the page contains iframes, each iframe should contain either no main landmarks or just one.',
-1 7265 help: 'Page must contain one main landmark.'
-1 7266 },
-1 7267 'layout-table': {
-1 7268 description: 'Ensures presentational <table> elements do not use <th>, <caption> elements or the summary attribute',
-1 7269 help: 'Layout tables must not use data table elements'
-1 7270 },
-1 7271 'link-in-text-block': {
-1 7272 description: 'Links can be distinguished without relying on color',
-1 7273 help: 'Links must be distinguished from surrounding text in a way that does not rely on color'
-1 7274 },
-1 7275 'link-name': {
-1 7276 description: 'Ensures links have discernible text',
-1 7277 help: 'Links must have discernible text'
-1 7278 },
-1 7279 list: {
-1 7280 description: 'Ensures that lists are structured correctly',
-1 7281 help: '<ul> and <ol> must only directly contain <li>, <script> or <template> elements'
-1 7282 },
-1 7283 listitem: {
-1 7284 description: 'Ensures <li> elements are used semantically',
-1 7285 help: '<li> elements must be contained in a <ul> or <ol>'
-1 7286 },
-1 7287 marquee: {
-1 7288 description: 'Ensures <marquee> elements are not used',
-1 7289 help: '<marquee> elements are deprecated and must not be used'
-1 7290 },
-1 7291 'meta-refresh': {
-1 7292 description: 'Ensures <meta http-equiv="refresh"> is not used',
-1 7293 help: 'Timed refresh must not exist'
-1 7294 },
-1 7295 'meta-viewport-large': {
-1 7296 description: 'Ensures <meta name="viewport"> can scale a significant amount',
-1 7297 help: 'Users should be able to zoom and scale the text up to 500%'
-1 7298 },
-1 7299 'meta-viewport': {
-1 7300 description: 'Ensures <meta name="viewport"> does not disable text scaling and zooming',
-1 7301 help: 'Zooming and scaling must not be disabled'
-1 7302 },
-1 7303 'object-alt': {
-1 7304 description: 'Ensures <object> elements have alternate text',
-1 7305 help: '<object> elements must have alternate text'
-1 7306 },
-1 7307 'p-as-heading': {
-1 7308 description: 'Ensure p elements are not used to style headings',
-1 7309 help: 'Bold, italic text and font-size are not used to style p elements as a heading'
-1 7310 },
-1 7311 radiogroup: {
-1 7312 description: 'Ensures related <input type="radio"> elements have a group and that the group designation is consistent',
-1 7313 help: 'Radio inputs with the same name attribute value must be part of a group'
-1 7314 },
-1 7315 region: {
-1 7316 description: 'Ensures all content is contained within a landmark region',
-1 7317 help: 'Content should be contained in a landmark region'
-1 7318 },
-1 7319 'scope-attr-valid': {
-1 7320 description: 'Ensures the scope attribute is used correctly on tables',
-1 7321 help: 'scope attribute should be used correctly'
-1 7322 },
-1 7323 'server-side-image-map': {
-1 7324 description: 'Ensures that server-side image maps are not used',
-1 7325 help: 'Server-side image maps must not be used'
-1 7326 },
-1 7327 'skip-link': {
-1 7328 description: 'Ensures the first link on the page is a skip link',
-1 7329 help: 'The page should have a skip link as its first link'
-1 7330 },
-1 7331 tabindex: {
-1 7332 description: 'Ensures tabindex attribute values are not greater than 0',
-1 7333 help: 'Elements should not have tabindex greater than zero'
-1 7334 },
-1 7335 'table-duplicate-name': {
-1 7336 description: 'Ensure that tables do not have the same summary and caption',
-1 7337 help: 'The <caption> element should not contain the same text as the summary attribute'
-1 7338 },
-1 7339 'table-fake-caption': {
-1 7340 description: 'Ensure that tables with a caption use the <caption> element.',
-1 7341 help: 'Data or header cells should not be used to give caption to a data table.'
-1 7342 },
-1 7343 'td-has-header': {
-1 7344 description: 'Ensure that each non-empty data cell in a large table has one or more table headers',
-1 7345 help: 'All non-empty td element in table larger than 3 by 3 must have an associated table header'
-1 7346 },
-1 7347 'td-headers-attr': {
-1 7348 description: 'Ensure that each cell in a table using the headers refers to another cell in that table',
-1 7349 help: 'All cells in a table element that use the headers attribute must only refer to other cells of that same table'
-1 7350 },
-1 7351 'th-has-data-cells': {
-1 7352 description: 'Ensure that each table header in a data table refers to data cells',
-1 7353 help: 'All th elements and elements with role=columnheader/rowheader must have data cells they describe'
-1 7354 },
-1 7355 'valid-lang': {
-1 7356 description: 'Ensures lang attributes have valid values',
-1 7357 help: 'lang attribute must have a valid value'
-1 7358 },
-1 7359 'video-caption': {
-1 7360 description: 'Ensures <video> elements have captions',
-1 7361 help: '<video> elements must have captions'
-1 7362 },
-1 7363 'video-description': {
-1 7364 description: 'Ensures <video> elements have audio descriptions',
-1 7365 help: '<video> elements must have an audio description track'
-1 7366 }
-1 7367 },
-1 7368 checks: {
-1 7369 accesskeys: {
-1 7370 impact: 'serious',
-1 7371 messages: {
-1 7372 pass: function anonymous(it) {
-1 7373 var out = 'Accesskey attribute value is unique';
-1 7374 return out;
-1 7375 },
-1 7376 fail: function anonymous(it) {
-1 7377 var out = 'Document has multiple elements with the same accesskey';
-1 7378 return out;
-1 7379 }
-1 7380 }
-1 7381 },
-1 7382 'non-empty-alt': {
-1 7383 impact: 'critical',
-1 7384 messages: {
-1 7385 pass: function anonymous(it) {
-1 7386 var out = 'Element has a non-empty alt attribute';
-1 7387 return out;
-1 7388 },
-1 7389 fail: function anonymous(it) {
-1 7390 var out = 'Element has no alt attribute or the alt attribute is empty';
-1 7391 return out;
-1 7392 }
-1 7393 }
-1 7394 },
-1 7395 'non-empty-title': {
-1 7396 impact: 'serious',
-1 7397 messages: {
-1 7398 pass: function anonymous(it) {
-1 7399 var out = 'Element has a title attribute';
-1 7400 return out;
-1 7401 },
-1 7402 fail: function anonymous(it) {
-1 7403 var out = 'Element has no title attribute or the title attribute is empty';
-1 7404 return out;
-1 7405 }
-1 7406 }
-1 7407 },
-1 7408 'aria-label': {
-1 7409 impact: 'serious',
-1 7410 messages: {
-1 7411 pass: function anonymous(it) {
-1 7412 var out = 'aria-label attribute exists and is not empty';
-1 7413 return out;
-1 7414 },
-1 7415 fail: function anonymous(it) {
-1 7416 var out = 'aria-label attribute does not exist or is empty';
-1 7417 return out;
-1 7418 }
-1 7419 }
-1 7420 },
-1 7421 'aria-labelledby': {
-1 7422 impact: 'serious',
-1 7423 messages: {
-1 7424 pass: function anonymous(it) {
-1 7425 var out = 'aria-labelledby attribute exists and references elements that are visible to screen readers';
-1 7426 return out;
-1 7427 },
-1 7428 fail: function anonymous(it) {
-1 7429 var out = 'aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty or not visible';
-1 7430 return out;
-1 7431 }
-1 7432 }
-1 7433 },
-1 7434 'aria-allowed-attr': {
-1 7435 impact: 'critical',
-1 7436 messages: {
-1 7437 pass: function anonymous(it) {
-1 7438 var out = 'ARIA attributes are used correctly for the defined role';
-1 7439 return out;
-1 7440 },
-1 7441 fail: function anonymous(it) {
-1 7442 var out = 'ARIA attribute' + (it.data && it.data.length > 1 ? 's are' : ' is') + ' not allowed:';
-1 7443 var arr1 = it.data;
-1 7444 if (arr1) {
-1 7445 var value, i1 = -1, l1 = arr1.length - 1;
-1 7446 while (i1 < l1) {
-1 7447 value = arr1[i1 += 1];
-1 7448 out += ' ' + value;
-1 7449 }
-1 7450 }
-1 7451 return out;
-1 7452 }
-1 7453 }
-1 7454 },
-1 7455 'aria-hidden-body': {
-1 7456 impact: 'critical',
-1 7457 messages: {
-1 7458 pass: function anonymous(it) {
-1 7459 var out = 'No aria-hidden attribute is present on document body';
-1 7460 return out;
-1 7461 },
-1 7462 fail: function anonymous(it) {
-1 7463 var out = 'aria-hidden=true should not be present on the document body';
-1 7464 return out;
-1 7465 }
-1 7466 }
-1 7467 },
-1 7468 'aria-required-attr': {
-1 7469 impact: 'critical',
-1 7470 messages: {
-1 7471 pass: function anonymous(it) {
-1 7472 var out = 'All required ARIA attributes are present';
-1 7473 return out;
-1 7474 },
-1 7475 fail: function anonymous(it) {
-1 7476 var out = 'Required ARIA attribute' + (it.data && it.data.length > 1 ? 's' : '') + ' not present:';
-1 7477 var arr1 = it.data;
-1 7478 if (arr1) {
-1 7479 var value, i1 = -1, l1 = arr1.length - 1;
-1 7480 while (i1 < l1) {
-1 7481 value = arr1[i1 += 1];
-1 7482 out += ' ' + value;
-1 7483 }
-1 7484 }
-1 7485 return out;
-1 7486 }
-1 7487 }
-1 7488 },
-1 7489 'aria-required-children': {
-1 7490 impact: 'critical',
-1 7491 messages: {
-1 7492 pass: function anonymous(it) {
-1 7493 var out = 'Required ARIA children are present';
-1 7494 return out;
-1 7495 },
-1 7496 fail: function anonymous(it) {
-1 7497 var out = 'Required ARIA ' + (it.data && it.data.length > 1 ? 'children' : 'child') + ' role not present:';
-1 7498 var arr1 = it.data;
-1 7499 if (arr1) {
-1 7500 var value, i1 = -1, l1 = arr1.length - 1;
-1 7501 while (i1 < l1) {
-1 7502 value = arr1[i1 += 1];
-1 7503 out += ' ' + value;
-1 7504 }
-1 7505 }
-1 7506 return out;
-1 7507 }
-1 7508 }
-1 7509 },
-1 7510 'aria-required-parent': {
-1 7511 impact: 'critical',
-1 7512 messages: {
-1 7513 pass: function anonymous(it) {
-1 7514 var out = 'Required ARIA parent role present';
-1 7515 return out;
-1 7516 },
-1 7517 fail: function anonymous(it) {
-1 7518 var out = 'Required ARIA parent' + (it.data && it.data.length > 1 ? 's' : '') + ' role not present:';
-1 7519 var arr1 = it.data;
-1 7520 if (arr1) {
-1 7521 var value, i1 = -1, l1 = arr1.length - 1;
-1 7522 while (i1 < l1) {
-1 7523 value = arr1[i1 += 1];
-1 7524 out += ' ' + value;
-1 7525 }
-1 7526 }
-1 7527 return out;
-1 7528 }
-1 7529 }
-1 7530 },
-1 7531 invalidrole: {
-1 7532 impact: 'critical',
-1 7533 messages: {
-1 7534 pass: function anonymous(it) {
-1 7535 var out = 'ARIA role is valid';
-1 7536 return out;
-1 7537 },
-1 7538 fail: function anonymous(it) {
-1 7539 var out = 'Role must be one of the valid ARIA roles';
-1 7540 return out;
-1 7541 }
-1 7542 }
-1 7543 },
-1 7544 abstractrole: {
-1 7545 impact: 'serious',
-1 7546 messages: {
-1 7547 pass: function anonymous(it) {
-1 7548 var out = 'Abstract roles are not used';
-1 7549 return out;
-1 7550 },
-1 7551 fail: function anonymous(it) {
-1 7552 var out = 'Abstract roles cannot be directly used';
-1 7553 return out;
-1 7554 }
-1 7555 }
-1 7556 },
-1 7557 'aria-valid-attr-value': {
-1 7558 impact: 'critical',
-1 7559 messages: {
-1 7560 pass: function anonymous(it) {
-1 7561 var out = 'ARIA attribute values are valid';
-1 7562 return out;
-1 7563 },
-1 7564 fail: function anonymous(it) {
-1 7565 var out = 'Invalid ARIA attribute value' + (it.data && it.data.length > 1 ? 's' : '') + ':';
-1 7566 var arr1 = it.data;
-1 7567 if (arr1) {
-1 7568 var value, i1 = -1, l1 = arr1.length - 1;
-1 7569 while (i1 < l1) {
-1 7570 value = arr1[i1 += 1];
-1 7571 out += ' ' + value;
-1 7572 }
-1 7573 }
-1 7574 return out;
-1 7575 }
-1 7576 }
-1 7577 },
-1 7578 'aria-errormessage': {
-1 7579 impact: 'critical',
-1 7580 messages: {
-1 7581 pass: function anonymous(it) {
-1 7582 var out = 'Uses a supported aria-errormessage technique';
-1 7583 return out;
-1 7584 },
-1 7585 fail: function anonymous(it) {
-1 7586 var out = 'aria-errormessage value' + (it.data && it.data.length > 1 ? 's' : '') + ' ';
-1 7587 var arr1 = it.data;
-1 7588 if (arr1) {
-1 7589 var value, i1 = -1, l1 = arr1.length - 1;
-1 7590 while (i1 < l1) {
-1 7591 value = arr1[i1 += 1];
-1 7592 out += ' `' + value;
-1 7593 }
-1 7594 }
-1 7595 out += '` must use a technique to announce the message (e.g., aria-live, aria-describedby, role=alert, etc.)';
-1 7596 return out;
-1 7597 }
-1 7598 }
-1 7599 },
-1 7600 'aria-valid-attr': {
-1 7601 impact: 'critical',
-1 7602 messages: {
-1 7603 pass: function anonymous(it) {
-1 7604 var out = 'ARIA attribute name' + (it.data && it.data.length > 1 ? 's' : '') + ' are valid';
-1 7605 return out;
-1 7606 },
-1 7607 fail: function anonymous(it) {
-1 7608 var out = 'Invalid ARIA attribute name' + (it.data && it.data.length > 1 ? 's' : '') + ':';
-1 7609 var arr1 = it.data;
-1 7610 if (arr1) {
-1 7611 var value, i1 = -1, l1 = arr1.length - 1;
-1 7612 while (i1 < l1) {
-1 7613 value = arr1[i1 += 1];
-1 7614 out += ' ' + value;
-1 7615 }
-1 7616 }
-1 7617 return out;
-1 7618 }
-1 7619 }
-1 7620 },
-1 7621 caption: {
-1 7622 impact: 'critical',
-1 7623 messages: {
-1 7624 pass: function anonymous(it) {
-1 7625 var out = 'The multimedia element has a captions track';
-1 7626 return out;
-1 7627 },
-1 7628 fail: function anonymous(it) {
-1 7629 var out = 'The multimedia element does not have a captions track';
-1 7630 return out;
-1 7631 },
-1 7632 incomplete: function anonymous(it) {
-1 7633 var out = 'A captions track for this element could not be found';
-1 7634 return out;
-1 7635 }
-1 7636 }
-1 7637 },
-1 7638 'is-on-screen': {
-1 7639 impact: 'serious',
-1 7640 messages: {
-1 7641 pass: function anonymous(it) {
-1 7642 var out = 'Element is not visible';
-1 7643 return out;
-1 7644 },
-1 7645 fail: function anonymous(it) {
-1 7646 var out = 'Element is visible';
-1 7647 return out;
-1 7648 }
-1 7649 }
-1 7650 },
-1 7651 'non-empty-if-present': {
-1 7652 impact: 'critical',
-1 7653 messages: {
-1 7654 pass: function anonymous(it) {
-1 7655 var out = 'Element ';
-1 7656 if (it.data) {
-1 7657 out += 'has a non-empty value attribute';
-1 7658 } else {
-1 7659 out += 'does not have a value attribute';
-1 7660 }
-1 7661 return out;
-1 7662 },
-1 7663 fail: function anonymous(it) {
-1 7664 var out = 'Element has a value attribute and the value attribute is empty';
-1 7665 return out;
-1 7666 }
-1 7667 }
-1 7668 },
-1 7669 'non-empty-value': {
-1 7670 impact: 'critical',
-1 7671 messages: {
-1 7672 pass: function anonymous(it) {
-1 7673 var out = 'Element has a non-empty value attribute';
-1 7674 return out;
-1 7675 },
-1 7676 fail: function anonymous(it) {
-1 7677 var out = 'Element has no value attribute or the value attribute is empty';
-1 7678 return out;
-1 7679 }
-1 7680 }
-1 7681 },
-1 7682 'button-has-visible-text': {
-1 7683 impact: 'critical',
-1 7684 messages: {
-1 7685 pass: function anonymous(it) {
-1 7686 var out = 'Element has inner text that is visible to screen readers';
-1 7687 return out;
-1 7688 },
-1 7689 fail: function anonymous(it) {
-1 7690 var out = 'Element does not have inner text that is visible to screen readers';
-1 7691 return out;
-1 7692 }
-1 7693 }
-1 7694 },
-1 7695 'role-presentation': {
-1 7696 impact: 'minor',
-1 7697 messages: {
-1 7698 pass: function anonymous(it) {
-1 7699 var out = 'Element\'s default semantics were overriden with role="presentation"';
-1 7700 return out;
-1 7701 },
-1 7702 fail: function anonymous(it) {
-1 7703 var out = 'Element\'s default semantics were not overridden with role="presentation"';
-1 7704 return out;
-1 7705 }
-1 7706 }
-1 7707 },
-1 7708 'role-none': {
-1 7709 impact: 'minor',
-1 7710 messages: {
-1 7711 pass: function anonymous(it) {
-1 7712 var out = 'Element\'s default semantics were overriden with role="none"';
-1 7713 return out;
-1 7714 },
-1 7715 fail: function anonymous(it) {
-1 7716 var out = 'Element\'s default semantics were not overridden with role="none"';
-1 7717 return out;
-1 7718 }
-1 7719 }
-1 7720 },
-1 7721 'focusable-no-name': {
-1 7722 impact: 'serious',
-1 7723 messages: {
-1 7724 pass: function anonymous(it) {
-1 7725 var out = 'Element is not in tab order or has accessible text';
-1 7726 return out;
-1 7727 },
-1 7728 fail: function anonymous(it) {
-1 7729 var out = 'Element is in tab order and does not have accessible text';
-1 7730 return out;
-1 7731 }
-1 7732 }
-1 7733 },
-1 7734 'internal-link-present': {
-1 7735 impact: 'serious',
-1 7736 messages: {
-1 7737 pass: function anonymous(it) {
-1 7738 var out = 'Valid skip link found';
-1 7739 return out;
-1 7740 },
-1 7741 fail: function anonymous(it) {
-1 7742 var out = 'No valid skip link found';
-1 7743 return out;
-1 7744 }
-1 7745 }
-1 7746 },
-1 7747 'header-present': {
-1 7748 impact: 'serious',
-1 7749 messages: {
-1 7750 pass: function anonymous(it) {
-1 7751 var out = 'Page has a header';
-1 7752 return out;
-1 7753 },
-1 7754 fail: function anonymous(it) {
-1 7755 var out = 'Page does not have a header';
-1 7756 return out;
-1 7757 }
-1 7758 }
-1 7759 },
-1 7760 landmark: {
-1 7761 impact: 'serious',
-1 7762 messages: {
-1 7763 pass: function anonymous(it) {
-1 7764 var out = 'Page has a landmark region';
-1 7765 return out;
-1 7766 },
-1 7767 fail: function anonymous(it) {
-1 7768 var out = 'Page does not have a landmark region';
-1 7769 return out;
-1 7770 }
-1 7771 }
-1 7772 },
-1 7773 'group-labelledby': {
-1 7774 impact: 'critical',
-1 7775 messages: {
-1 7776 pass: function anonymous(it) {
-1 7777 var out = 'All elements with the name "' + it.data.name + '" reference the same element with aria-labelledby';
-1 7778 return out;
-1 7779 },
-1 7780 fail: function anonymous(it) {
-1 7781 var out = 'All elements with the name "' + it.data.name + '" do not reference the same element with aria-labelledby';
-1 7782 return out;
-1 7783 }
-1 7784 }
-1 7785 },
-1 7786 fieldset: {
-1 7787 impact: 'critical',
-1 7788 messages: {
-1 7789 pass: function anonymous(it) {
-1 7790 var out = 'Element is contained in a fieldset';
-1 7791 return out;
-1 7792 },
-1 7793 fail: function anonymous(it) {
-1 7794 var out = '';
-1 7795 var code = it.data && it.data.failureCode;
-1 7796 if (code === 'no-legend') {
-1 7797 out += 'Fieldset does not have a legend as its first child';
-1 7798 } else if (code === 'empty-legend') {
-1 7799 out += 'Legend does not have text that is visible to screen readers';
-1 7800 } else if (code === 'mixed-inputs') {
-1 7801 out += 'Fieldset contains unrelated inputs';
-1 7802 } else if (code === 'no-group-label') {
-1 7803 out += 'ARIA group does not have aria-label or aria-labelledby';
-1 7804 } else if (code === 'group-mixed-inputs') {
-1 7805 out += 'ARIA group contains unrelated inputs';
-1 7806 } else {
-1 7807 out += 'Element does not have a containing fieldset or ARIA group';
-1 7808 }
-1 7809 return out;
-1 7810 }
-1 7811 }
-1 7812 },
-1 7813 'color-contrast': {
-1 7814 impact: 'serious',
-1 7815 messages: {
-1 7816 pass: function anonymous(it) {
-1 7817 var out = 'Element has sufficient color contrast of ' + it.data.contrastRatio;
-1 7818 return out;
-1 7819 },
-1 7820 fail: function anonymous(it) {
-1 7821 var out = 'Element has insufficient color contrast of ' + it.data.contrastRatio + ' (foreground color: ' + it.data.fgColor + ', background color: ' + it.data.bgColor + ', font size: ' + it.data.fontSize + ', font weight: ' + it.data.fontWeight + '). Expected contrast ratio of ' + it.data.expectedContrastRatio;
-1 7822 return out;
-1 7823 },
-1 7824 incomplete: {
-1 7825 bgImage: 'Element\'s background color could not be determined due to a background image',
-1 7826 bgGradient: 'Element\'s background color could not be determined due to a background gradient',
-1 7827 imgNode: 'Element\'s background color could not be determined because element contains an image node',
-1 7828 bgOverlap: 'Element\'s background color could not be determined because it is overlapped by another element',
-1 7829 fgAlpha: 'Element\'s foreground color could not be determined because of alpha transparency',
-1 7830 elmPartiallyObscured: 'Element\'s background color could not be determined because it\'s partially obscured by another element',
-1 7831 elmPartiallyObscuring: 'Element\'s background color could not be determined because it partially overlaps other elements',
-1 7832 outsideViewport: 'Element\'s background color could not be determined because it\'s outside the viewport',
-1 7833 equalRatio: 'Element has a 1:1 contrast ratio with the background',
-1 7834 default: 'Unable to determine contrast ratio'
-1 7835 }
-1 7836 }
-1 7837 },
-1 7838 'structured-dlitems': {
-1 7839 impact: 'serious',
-1 7840 messages: {
-1 7841 pass: function anonymous(it) {
-1 7842 var out = 'When not empty, element has both <dt> and <dd> elements';
-1 7843 return out;
-1 7844 },
-1 7845 fail: function anonymous(it) {
-1 7846 var out = 'When not empty, element does not have at least one <dt> element followed by at least one <dd> element';
-1 7847 return out;
-1 7848 }
-1 7849 }
-1 7850 },
-1 7851 'only-dlitems': {
-1 7852 impact: 'serious',
-1 7853 messages: {
-1 7854 pass: function anonymous(it) {
-1 7855 var out = 'List element only has direct children that are allowed inside <dt> or <dd> elements';
-1 7856 return out;
-1 7857 },
-1 7858 fail: function anonymous(it) {
-1 7859 var out = 'List element has direct children that are not allowed inside <dt> or <dd> elements';
-1 7860 return out;
-1 7861 }
-1 7862 }
-1 7863 },
-1 7864 dlitem: {
-1 7865 impact: 'serious',
-1 7866 messages: {
-1 7867 pass: function anonymous(it) {
-1 7868 var out = 'Description list item has a <dl> parent element';
-1 7869 return out;
-1 7870 },
-1 7871 fail: function anonymous(it) {
-1 7872 var out = 'Description list item does not have a <dl> parent element';
-1 7873 return out;
-1 7874 }
-1 7875 }
-1 7876 },
-1 7877 'doc-has-title': {
-1 7878 impact: 'serious',
-1 7879 messages: {
-1 7880 pass: function anonymous(it) {
-1 7881 var out = 'Document has a non-empty <title> element';
-1 7882 return out;
-1 7883 },
-1 7884 fail: function anonymous(it) {
-1 7885 var out = 'Document does not have a non-empty <title> element';
-1 7886 return out;
-1 7887 }
-1 7888 }
-1 7889 },
-1 7890 'duplicate-id': {
-1 7891 impact: 'moderate',
-1 7892 messages: {
-1 7893 pass: function anonymous(it) {
-1 7894 var out = 'Document has no elements that share the same id attribute';
-1 7895 return out;
-1 7896 },
-1 7897 fail: function anonymous(it) {
-1 7898 var out = 'Document has multiple elements with the same id attribute: ' + it.data;
-1 7899 return out;
-1 7900 }
-1 7901 }
-1 7902 },
-1 7903 'has-visible-text': {
-1 7904 impact: 'minor',
-1 7905 messages: {
-1 7906 pass: function anonymous(it) {
-1 7907 var out = 'Element has text that is visible to screen readers';
-1 7908 return out;
-1 7909 },
-1 7910 fail: function anonymous(it) {
-1 7911 var out = 'Element does not have text that is visible to screen readers';
-1 7912 return out;
-1 7913 }
-1 7914 }
-1 7915 },
-1 7916 'unique-frame-title': {
-1 7917 impact: 'serious',
-1 7918 messages: {
-1 7919 pass: function anonymous(it) {
-1 7920 var out = 'Element\'s title attribute is unique';
-1 7921 return out;
-1 7922 },
-1 7923 fail: function anonymous(it) {
-1 7924 var out = 'Element\'s title attribute is not unique';
-1 7925 return out;
-1 7926 }
-1 7927 }
-1 7928 },
-1 7929 'heading-order': {
-1 7930 impact: 'moderate',
-1 7931 messages: {
-1 7932 pass: function anonymous(it) {
-1 7933 var out = 'Heading order valid';
-1 7934 return out;
-1 7935 },
-1 7936 fail: function anonymous(it) {
-1 7937 var out = 'Heading order invalid';
-1 7938 return out;
-1 7939 }
-1 7940 }
-1 7941 },
-1 7942 'hidden-content': {
-1 7943 impact: 'minor',
-1 7944 messages: {
-1 7945 pass: function anonymous(it) {
-1 7946 var out = 'All content on the page has been analyzed.';
-1 7947 return out;
-1 7948 },
-1 7949 fail: function anonymous(it) {
-1 7950 var out = 'There were problems analyzing the content on this page.';
-1 7951 return out;
-1 7952 },
-1 7953 incomplete: function anonymous(it) {
-1 7954 var out = 'There is hidden content on the page that was not analyzed. You will need to trigger the display of this content in order to analyze it.';
-1 7955 return out;
-1 7956 }
-1 7957 }
-1 7958 },
-1 7959 'href-no-hash': {
-1 7960 impact: 'moderate',
-1 7961 messages: {
-1 7962 pass: function anonymous(it) {
-1 7963 var out = 'Anchor does not have an href value of #';
-1 7964 return out;
-1 7965 },
-1 7966 fail: function anonymous(it) {
-1 7967 var out = 'Anchor has an href value of #';
-1 7968 return out;
-1 7969 }
-1 7970 }
-1 7971 },
-1 7972 'has-lang': {
-1 7973 impact: 'serious',
-1 7974 messages: {
-1 7975 pass: function anonymous(it) {
-1 7976 var out = 'The <html> element has a lang attribute';
-1 7977 return out;
-1 7978 },
-1 7979 fail: function anonymous(it) {
-1 7980 var out = 'The <html> element does not have a lang attribute';
-1 7981 return out;
-1 7982 }
-1 7983 }
-1 7984 },
-1 7985 'valid-lang': {
-1 7986 impact: 'serious',
-1 7987 messages: {
-1 7988 pass: function anonymous(it) {
-1 7989 var out = 'Value of lang attribute is included in the list of valid languages';
-1 7990 return out;
-1 7991 },
-1 7992 fail: function anonymous(it) {
-1 7993 var out = 'Value of lang attribute not included in the list of valid languages';
-1 7994 return out;
-1 7995 }
-1 7996 }
-1 7997 },
-1 7998 'has-alt': {
-1 7999 impact: 'critical',
-1 8000 messages: {
-1 8001 pass: function anonymous(it) {
-1 8002 var out = 'Element has an alt attribute';
-1 8003 return out;
-1 8004 },
-1 8005 fail: function anonymous(it) {
-1 8006 var out = 'Element does not have an alt attribute';
-1 8007 return out;
-1 8008 }
-1 8009 }
-1 8010 },
-1 8011 'duplicate-img-label': {
-1 8012 impact: 'minor',
-1 8013 messages: {
-1 8014 pass: function anonymous(it) {
-1 8015 var out = 'Element does not duplicate existing text in <img> alt text';
-1 8016 return out;
-1 8017 },
-1 8018 fail: function anonymous(it) {
-1 8019 var out = 'Element contains <img> element with alt text that duplicates existing text';
-1 8020 return out;
-1 8021 }
-1 8022 }
-1 8023 },
-1 8024 'title-only': {
-1 8025 impact: 'serious',
-1 8026 messages: {
-1 8027 pass: function anonymous(it) {
-1 8028 var out = 'Form element does not solely use title attribute for its label';
-1 8029 return out;
-1 8030 },
-1 8031 fail: function anonymous(it) {
-1 8032 var out = 'Only title used to generate label for form element';
-1 8033 return out;
-1 8034 }
-1 8035 }
-1 8036 },
-1 8037 'implicit-label': {
-1 8038 impact: 'critical',
-1 8039 messages: {
-1 8040 pass: function anonymous(it) {
-1 8041 var out = 'Form element has an implicit (wrapped) <label>';
-1 8042 return out;
-1 8043 },
-1 8044 fail: function anonymous(it) {
-1 8045 var out = 'Form element does not have an implicit (wrapped) <label>';
-1 8046 return out;
-1 8047 }
-1 8048 }
-1 8049 },
-1 8050 'explicit-label': {
-1 8051 impact: 'critical',
-1 8052 messages: {
-1 8053 pass: function anonymous(it) {
-1 8054 var out = 'Form element has an explicit <label>';
-1 8055 return out;
-1 8056 },
-1 8057 fail: function anonymous(it) {
-1 8058 var out = 'Form element does not have an explicit <label>';
-1 8059 return out;
-1 8060 }
-1 8061 }
-1 8062 },
-1 8063 'help-same-as-label': {
-1 8064 impact: 'minor',
-1 8065 messages: {
-1 8066 pass: function anonymous(it) {
-1 8067 var out = 'Help text (title or aria-describedby) does not duplicate label text';
-1 8068 return out;
-1 8069 },
-1 8070 fail: function anonymous(it) {
-1 8071 var out = 'Help text (title or aria-describedby) text is the same as the label text';
-1 8072 return out;
-1 8073 }
-1 8074 }
-1 8075 },
-1 8076 'multiple-label': {
-1 8077 impact: 'serious',
-1 8078 messages: {
-1 8079 pass: function anonymous(it) {
-1 8080 var out = 'Form element does not have multiple <label> elements';
-1 8081 return out;
-1 8082 },
-1 8083 fail: function anonymous(it) {
-1 8084 var out = 'Form element has multiple <label> elements';
-1 8085 return out;
-1 8086 }
-1 8087 }
-1 8088 },
-1 8089 'main-is-top-level': {
-1 8090 impact: 'moderate',
-1 8091 messages: {
-1 8092 pass: function anonymous(it) {
-1 8093 var out = 'The main landmark is at the top level.';
-1 8094 return out;
-1 8095 },
-1 8096 fail: function anonymous(it) {
-1 8097 var out = 'The main landmark is contained in another landmark.';
-1 8098 return out;
-1 8099 }
-1 8100 }
-1 8101 },
-1 8102 'has-at-least-one-main': {
-1 8103 impact: 'moderate',
-1 8104 messages: {
-1 8105 pass: function anonymous(it) {
-1 8106 var out = 'Document has at least one main landmark';
-1 8107 return out;
-1 8108 },
-1 8109 fail: function anonymous(it) {
-1 8110 var out = 'Document has no main landmarks';
-1 8111 return out;
-1 8112 }
-1 8113 }
-1 8114 },
-1 8115 'has-no-more-than-one-main': {
-1 8116 impact: 'moderate',
-1 8117 messages: {
-1 8118 pass: function anonymous(it) {
-1 8119 var out = 'Document has no more than one main landmark';
-1 8120 return out;
-1 8121 },
-1 8122 fail: function anonymous(it) {
-1 8123 var out = 'Document has more than one main landmark';
-1 8124 return out;
-1 8125 }
-1 8126 }
-1 8127 },
-1 8128 'has-th': {
-1 8129 impact: 'serious',
-1 8130 messages: {
-1 8131 pass: function anonymous(it) {
-1 8132 var out = 'Layout table does not use <th> elements';
-1 8133 return out;
-1 8134 },
-1 8135 fail: function anonymous(it) {
-1 8136 var out = 'Layout table uses <th> elements';
-1 8137 return out;
-1 8138 }
-1 8139 }
-1 8140 },
-1 8141 'has-caption': {
-1 8142 impact: 'serious',
-1 8143 messages: {
-1 8144 pass: function anonymous(it) {
-1 8145 var out = 'Layout table does not use <caption> element';
-1 8146 return out;
-1 8147 },
-1 8148 fail: function anonymous(it) {
-1 8149 var out = 'Layout table uses <caption> element';
-1 8150 return out;
-1 8151 }
-1 8152 }
-1 8153 },
-1 8154 'has-summary': {
-1 8155 impact: 'serious',
-1 8156 messages: {
-1 8157 pass: function anonymous(it) {
-1 8158 var out = 'Layout table does not use summary attribute';
-1 8159 return out;
-1 8160 },
-1 8161 fail: function anonymous(it) {
-1 8162 var out = 'Layout table uses summary attribute';
-1 8163 return out;
-1 8164 }
-1 8165 }
-1 8166 },
-1 8167 'link-in-text-block': {
-1 8168 impact: 'serious',
-1 8169 messages: {
-1 8170 pass: function anonymous(it) {
-1 8171 var out = 'Links can be distinguished from surrounding text in a way that does not rely on color';
-1 8172 return out;
-1 8173 },
-1 8174 fail: function anonymous(it) {
-1 8175 var out = 'Links can not be distinguished from surrounding text in a way that does not rely on color';
-1 8176 return out;
-1 8177 },
-1 8178 incomplete: {
-1 8179 bgContrast: 'Element\'s contrast ratio could not be determined. Check for a distinct hover/focus style',
-1 8180 bgImage: 'Element\'s contrast ratio could not be determined due to a background image',
-1 8181 bgGradient: 'Element\'s contrast ratio could not be determined due to a background gradient',
-1 8182 imgNode: 'Element\'s contrast ratio could not be determined because element contains an image node',
-1 8183 bgOverlap: 'Element\'s contrast ratio could not be determined because of element overlap',
-1 8184 default: 'Unable to determine contrast ratio'
-1 8185 }
-1 8186 }
-1 8187 },
-1 8188 'only-listitems': {
-1 8189 impact: 'serious',
-1 8190 messages: {
-1 8191 pass: function anonymous(it) {
-1 8192 var out = 'List element only has direct children that are allowed inside <li> elements';
-1 8193 return out;
-1 8194 },
-1 8195 fail: function anonymous(it) {
-1 8196 var out = 'List element has direct children that are not allowed inside <li> elements';
-1 8197 return out;
-1 8198 }
-1 8199 }
-1 8200 },
-1 8201 listitem: {
-1 8202 impact: 'serious',
-1 8203 messages: {
-1 8204 pass: function anonymous(it) {
-1 8205 var out = 'List item has a <ul>, <ol> or role="list" parent element';
-1 8206 return out;
-1 8207 },
-1 8208 fail: function anonymous(it) {
-1 8209 var out = 'List item does not have a <ul>, <ol> or role="list" parent element';
-1 8210 return out;
-1 8211 }
-1 8212 }
-1 8213 },
-1 8214 'meta-refresh': {
-1 8215 impact: 'critical',
-1 8216 messages: {
-1 8217 pass: function anonymous(it) {
-1 8218 var out = '<meta> tag does not immediately refresh the page';
-1 8219 return out;
-1 8220 },
-1 8221 fail: function anonymous(it) {
-1 8222 var out = '<meta> tag forces timed refresh of page';
-1 8223 return out;
-1 8224 }
-1 8225 }
-1 8226 },
-1 8227 'meta-viewport-large': {
-1 8228 impact: 'minor',
-1 8229 messages: {
-1 8230 pass: function anonymous(it) {
-1 8231 var out = '<meta> tag does not prevent significant zooming on mobile devices';
-1 8232 return out;
-1 8233 },
-1 8234 fail: function anonymous(it) {
-1 8235 var out = '<meta> tag limits zooming on mobile devices';
-1 8236 return out;
-1 8237 }
-1 8238 }
-1 8239 },
-1 8240 'meta-viewport': {
-1 8241 impact: 'critical',
-1 8242 messages: {
-1 8243 pass: function anonymous(it) {
-1 8244 var out = '<meta> tag does not disable zooming on mobile devices';
-1 8245 return out;
-1 8246 },
-1 8247 fail: function anonymous(it) {
-1 8248 var out = '<meta> tag disables zooming on mobile devices';
-1 8249 return out;
-1 8250 }
-1 8251 }
-1 8252 },
-1 8253 'p-as-heading': {
-1 8254 impact: 'serious',
-1 8255 messages: {
-1 8256 pass: function anonymous(it) {
-1 8257 var out = '<p> elements are not styled as headings';
-1 8258 return out;
-1 8259 },
-1 8260 fail: function anonymous(it) {
-1 8261 var out = 'Heading elements should be used instead of styled p elements';
-1 8262 return out;
-1 8263 }
-1 8264 }
-1 8265 },
-1 8266 region: {
-1 8267 impact: 'moderate',
-1 8268 messages: {
-1 8269 pass: function anonymous(it) {
-1 8270 var out = 'Content contained by ARIA landmark';
-1 8271 return out;
-1 8272 },
-1 8273 fail: function anonymous(it) {
-1 8274 var out = 'Content not contained by an ARIA landmark';
-1 8275 return out;
-1 8276 }
-1 8277 }
-1 8278 },
-1 8279 'html5-scope': {
-1 8280 impact: 'moderate',
-1 8281 messages: {
-1 8282 pass: function anonymous(it) {
-1 8283 var out = 'Scope attribute is only used on table header elements (<th>)';
-1 8284 return out;
-1 8285 },
-1 8286 fail: function anonymous(it) {
-1 8287 var out = 'In HTML 5, scope attributes may only be used on table header elements (<th>)';
-1 8288 return out;
-1 8289 }
-1 8290 }
-1 8291 },
-1 8292 'scope-value': {
-1 8293 impact: 'critical',
-1 8294 messages: {
-1 8295 pass: function anonymous(it) {
-1 8296 var out = 'Scope attribute is used correctly';
-1 8297 return out;
-1 8298 },
-1 8299 fail: function anonymous(it) {
-1 8300 var out = 'The value of the scope attribute may only be \'row\' or \'col\'';
-1 8301 return out;
-1 8302 }
-1 8303 }
-1 8304 },
-1 8305 exists: {
-1 8306 impact: 'minor',
-1 8307 messages: {
-1 8308 pass: function anonymous(it) {
-1 8309 var out = 'Element does not exist';
-1 8310 return out;
-1 8311 },
-1 8312 fail: function anonymous(it) {
-1 8313 var out = 'Element exists';
-1 8314 return out;
-1 8315 }
-1 8316 }
-1 8317 },
-1 8318 'skip-link': {
-1 8319 impact: 'moderate',
-1 8320 messages: {
-1 8321 pass: function anonymous(it) {
-1 8322 var out = 'Valid skip link found';
-1 8323 return out;
-1 8324 },
-1 8325 fail: function anonymous(it) {
-1 8326 var out = 'No valid skip link found';
-1 8327 return out;
-1 8328 }
-1 8329 }
-1 8330 },
-1 8331 tabindex: {
-1 8332 impact: 'serious',
-1 8333 messages: {
-1 8334 pass: function anonymous(it) {
-1 8335 var out = 'Element does not have a tabindex greater than 0';
-1 8336 return out;
-1 8337 },
-1 8338 fail: function anonymous(it) {
-1 8339 var out = 'Element has a tabindex greater than 0';
-1 8340 return out;
-1 8341 }
-1 8342 }
-1 8343 },
-1 8344 'same-caption-summary': {
-1 8345 impact: 'minor',
-1 8346 messages: {
-1 8347 pass: function anonymous(it) {
-1 8348 var out = 'Content of summary attribute and <caption> are not duplicated';
-1 8349 return out;
-1 8350 },
-1 8351 fail: function anonymous(it) {
-1 8352 var out = 'Content of summary attribute and <caption> element are identical';
-1 8353 return out;
-1 8354 }
-1 8355 }
-1 8356 },
-1 8357 'caption-faked': {
-1 8358 impact: 'serious',
-1 8359 messages: {
-1 8360 pass: function anonymous(it) {
-1 8361 var out = 'The first row of a table is not used as a caption';
-1 8362 return out;
-1 8363 },
-1 8364 fail: function anonymous(it) {
-1 8365 var out = 'The first row of the table should be a caption instead of a table cell';
-1 8366 return out;
-1 8367 }
-1 8368 }
-1 8369 },
-1 8370 'td-has-header': {
-1 8371 impact: 'critical',
-1 8372 messages: {
-1 8373 pass: function anonymous(it) {
-1 8374 var out = 'All non-empty data cells have table headers';
-1 8375 return out;
-1 8376 },
-1 8377 fail: function anonymous(it) {
-1 8378 var out = 'Some non-empty data cells do not have table headers';
-1 8379 return out;
-1 8380 }
-1 8381 }
-1 8382 },
-1 8383 'td-headers-attr': {
-1 8384 impact: 'serious',
-1 8385 messages: {
-1 8386 pass: function anonymous(it) {
-1 8387 var out = 'The headers attribute is exclusively used to refer to other cells in the table';
-1 8388 return out;
-1 8389 },
-1 8390 fail: function anonymous(it) {
-1 8391 var out = 'The headers attribute is not exclusively used to refer to other cells in the table';
-1 8392 return out;
-1 8393 }
-1 8394 }
-1 8395 },
-1 8396 'th-has-data-cells': {
-1 8397 impact: 'serious',
-1 8398 messages: {
-1 8399 pass: function anonymous(it) {
-1 8400 var out = 'All table header cells refer to data cells';
-1 8401 return out;
-1 8402 },
-1 8403 fail: function anonymous(it) {
-1 8404 var out = 'Not all table header cells refer to data cells';
-1 8405 return out;
-1 8406 },
-1 8407 incomplete: function anonymous(it) {
-1 8408 var out = 'Table data cells are missing or empty';
-1 8409 return out;
-1 8410 }
-1 8411 }
-1 8412 },
-1 8413 description: {
-1 8414 impact: 'critical',
-1 8415 messages: {
-1 8416 pass: function anonymous(it) {
-1 8417 var out = 'The multimedia element has an audio description track';
-1 8418 return out;
-1 8419 },
-1 8420 fail: function anonymous(it) {
-1 8421 var out = 'The multimedia element does not have an audio description track';
-1 8422 return out;
-1 8423 },
-1 8424 incomplete: function anonymous(it) {
-1 8425 var out = 'An audio description track for this element could not be found';
-1 8426 return out;
-1 8427 }
-1 8428 }
-1 8429 }
-1 8430 },
-1 8431 failureSummaries: {
-1 8432 any: {
-1 8433 failureMessage: function anonymous(it) {
-1 8434 var out = 'Fix any of the following:';
-1 8435 var arr1 = it;
-1 8436 if (arr1) {
-1 8437 var value, i1 = -1, l1 = arr1.length - 1;
-1 8438 while (i1 < l1) {
-1 8439 value = arr1[i1 += 1];
-1 8440 out += '\n ' + value.split('\n').join('\n ');
-1 8441 }
-1 8442 }
-1 8443 return out;
-1 8444 }
-1 8445 },
-1 8446 none: {
-1 8447 failureMessage: function anonymous(it) {
-1 8448 var out = 'Fix all of the following:';
-1 8449 var arr1 = it;
-1 8450 if (arr1) {
-1 8451 var value, i1 = -1, l1 = arr1.length - 1;
-1 8452 while (i1 < l1) {
-1 8453 value = arr1[i1 += 1];
-1 8454 out += '\n ' + value.split('\n').join('\n ');
-1 8455 }
-1 8456 }
-1 8457 return out;
-1 8458 }
-1 8459 }
-1 8460 },
-1 8461 incompleteFallbackMessage: function anonymous(it) {
-1 8462 var out = 'aXe couldn\'t tell the reason. Time to break out the element inspector!';
-1 8463 return out;
-1 8464 }
-1 8465 },
-1 8466 rules: [ {
-1 8467 id: 'accesskeys',
-1 8468 selector: '[accesskey]',
-1 8469 excludeHidden: false,
-1 8470 tags: [ 'wcag2a', 'wcag211', 'cat.keyboard' ],
-1 8471 all: [],
-1 8472 any: [],
-1 8473 none: [ 'accesskeys' ]
-1 8474 }, {
-1 8475 id: 'area-alt',
-1 8476 selector: 'map area[href]',
-1 8477 excludeHidden: false,
-1 8478 tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag111', 'section508', 'section508.22.a' ],
-1 8479 all: [],
-1 8480 any: [ 'non-empty-alt', 'non-empty-title', 'aria-label', 'aria-labelledby' ],
-1 8481 none: []
-1 8482 }, {
-1 8483 id: 'aria-allowed-attr',
-1 8484 matches: function matches(node) {
-1 8485 var role = node.getAttribute('role');
-1 8486 if (!role) {
-1 8487 role = axe.commons.aria.implicitRole(node);
-1 8488 }
-1 8489 var allowed = axe.commons.aria.allowedAttr(role);
-1 8490 if (role && allowed) {
-1 8491 var aria = /^aria-/;
-1 8492 if (node.hasAttributes()) {
-1 8493 var attrs = node.attributes;
-1 8494 for (var i = 0, l = attrs.length; i < l; i++) {
-1 8495 if (aria.test(attrs[i].name)) {
-1 8496 return true;
-1 8497 }
-1 8498 }
-1 8499 }
-1 8500 }
-1 8501 return false;
-1 8502 },
-1 8503 tags: [ 'cat.aria', 'wcag2a', 'wcag411', 'wcag412' ],
-1 8504 all: [],
-1 8505 any: [ 'aria-allowed-attr' ],
-1 8506 none: []
-1 8507 }, {
-1 8508 id: 'aria-hidden-body',
-1 8509 selector: 'body',
-1 8510 excludeHidden: false,
-1 8511 tags: [ 'cat.aria', 'wcag2a', 'wcag412' ],
-1 8512 all: [],
-1 8513 any: [ 'aria-hidden-body' ],
-1 8514 none: []
-1 8515 }, {
-1 8516 id: 'aria-required-attr',
-1 8517 selector: '[role]',
-1 8518 tags: [ 'cat.aria', 'wcag2a', 'wcag411', 'wcag412' ],
-1 8519 all: [],
-1 8520 any: [ 'aria-required-attr' ],
-1 8521 none: []
-1 8522 }, {
-1 8523 id: 'aria-required-children',
-1 8524 selector: '[role]',
-1 8525 tags: [ 'cat.aria', 'wcag2a', 'wcag131' ],
-1 8526 all: [],
-1 8527 any: [ 'aria-required-children' ],
-1 8528 none: []
-1 8529 }, {
-1 8530 id: 'aria-required-parent',
-1 8531 selector: '[role]',
-1 8532 tags: [ 'cat.aria', 'wcag2a', 'wcag131' ],
-1 8533 all: [],
-1 8534 any: [ 'aria-required-parent' ],
-1 8535 none: []
-1 8536 }, {
-1 8537 id: 'aria-roles',
-1 8538 selector: '[role]',
-1 8539 tags: [ 'cat.aria', 'wcag2a', 'wcag131', 'wcag411', 'wcag412' ],
-1 8540 all: [],
-1 8541 any: [],
-1 8542 none: [ 'invalidrole', 'abstractrole' ]
-1 8543 }, {
-1 8544 id: 'aria-valid-attr-value',
-1 8545 matches: function matches(node) {
-1 8546 var aria = /^aria-/;
-1 8547 if (node.hasAttributes()) {
-1 8548 var attrs = node.attributes;
-1 8549 for (var i = 0, l = attrs.length; i < l; i++) {
-1 8550 if (aria.test(attrs[i].name)) {
-1 8551 return true;
-1 8552 }
-1 8553 }
-1 8554 }
-1 8555 return false;
-1 8556 },
-1 8557 tags: [ 'cat.aria', 'wcag2a', 'wcag131', 'wcag411', 'wcag412' ],
-1 8558 all: [ {
-1 8559 options: [],
-1 8560 id: 'aria-valid-attr-value'
-1 8561 }, 'aria-errormessage' ],
-1 8562 any: [],
-1 8563 none: []
-1 8564 }, {
-1 8565 id: 'aria-valid-attr',
-1 8566 matches: function matches(node) {
-1 8567 var aria = /^aria-/;
-1 8568 if (node.hasAttributes()) {
-1 8569 var attrs = node.attributes;
-1 8570 for (var i = 0, l = attrs.length; i < l; i++) {
-1 8571 if (aria.test(attrs[i].name)) {
-1 8572 return true;
-1 8573 }
-1 8574 }
-1 8575 }
-1 8576 return false;
-1 8577 },
-1 8578 tags: [ 'cat.aria', 'wcag2a', 'wcag411' ],
-1 8579 all: [],
-1 8580 any: [ {
-1 8581 options: [],
-1 8582 id: 'aria-valid-attr'
-1 8583 } ],
-1 8584 none: []
-1 8585 }, {
-1 8586 id: 'audio-caption',
-1 8587 selector: 'audio',
-1 8588 excludeHidden: false,
-1 8589 tags: [ 'cat.time-and-media', 'wcag2a', 'wcag122', 'section508', 'section508.22.a' ],
-1 8590 all: [],
-1 8591 any: [],
-1 8592 none: [ 'caption' ]
-1 8593 }, {
-1 8594 id: 'blink',
-1 8595 selector: 'blink',
-1 8596 excludeHidden: false,
-1 8597 tags: [ 'cat.time-and-media', 'wcag2a', 'wcag222', 'section508', 'section508.22.j' ],
-1 8598 all: [],
-1 8599 any: [],
-1 8600 none: [ 'is-on-screen' ]
-1 8601 }, {
-1 8602 id: 'button-name',
-1 8603 selector: 'button, [role="button"], input[type="button"], input[type="submit"], input[type="reset"]',
-1 8604 tags: [ 'cat.name-role-value', 'wcag2a', 'wcag412', 'section508', 'section508.22.a' ],
-1 8605 all: [],
-1 8606 any: [ 'non-empty-if-present', 'non-empty-value', 'button-has-visible-text', 'aria-label', 'aria-labelledby', 'role-presentation', 'role-none' ],
-1 8607 none: [ 'focusable-no-name' ]
-1 8608 }, {
-1 8609 id: 'bypass',
-1 8610 selector: 'html',
-1 8611 pageLevel: true,
-1 8612 matches: function matches(node) {
-1 8613 return !!node.querySelector('a[href]');
-1 8614 },
-1 8615 tags: [ 'cat.keyboard', 'wcag2a', 'wcag241', 'section508', 'section508.22.o' ],
-1 8616 all: [],
-1 8617 any: [ 'internal-link-present', 'header-present', 'landmark' ],
-1 8618 none: []
-1 8619 }, {
-1 8620 id: 'checkboxgroup',
-1 8621 selector: 'input[type=checkbox][name]',
-1 8622 tags: [ 'cat.forms', 'best-practice' ],
-1 8623 all: [],
-1 8624 any: [ 'group-labelledby', 'fieldset' ],
-1 8625 none: []
-1 8626 }, {
-1 8627 id: 'color-contrast',
-1 8628 matches: function matches(node) {
-1 8629 var nodeName = node.nodeName.toUpperCase(), nodeType = node.type, doc = document;
-1 8630 if (node.getAttribute('aria-disabled') === 'true' || axe.commons.dom.findUp(node, '[aria-disabled="true"]')) {
-1 8631 return false;
-1 8632 }
-1 8633 if (nodeName === 'INPUT') {
-1 8634 return [ 'hidden', 'range', 'color', 'checkbox', 'radio', 'image' ].indexOf(nodeType) === -1 && !node.disabled;
-1 8635 }
-1 8636 if (nodeName === 'SELECT') {
-1 8637 return !!node.options.length && !node.disabled;
-1 8638 }
-1 8639 if (nodeName === 'TEXTAREA') {
-1 8640 return !node.disabled;
-1 8641 }
-1 8642 if (nodeName === 'OPTION') {
-1 8643 return false;
-1 8644 }
-1 8645 if (nodeName === 'BUTTON' && node.disabled || axe.commons.dom.findUp(node, 'button[disabled]')) {
-1 8646 return false;
-1 8647 }
-1 8648 if (nodeName === 'FIELDSET' && node.disabled || axe.commons.dom.findUp(node, 'fieldset[disabled]')) {
-1 8649 return false;
-1 8650 }
-1 8651 var nodeParentLabel = axe.commons.dom.findUp(node, 'label');
-1 8652 if (nodeName === 'LABEL' || nodeParentLabel) {
-1 8653 var relevantNode = node;
-1 8654 if (nodeParentLabel) {
-1 8655 relevantNode = nodeParentLabel;
-1 8656 }
-1 8657 var candidate = relevantNode.htmlFor && doc.getElementById(relevantNode.htmlFor);
-1 8658 if (candidate && candidate.disabled) {
-1 8659 return false;
-1 8660 }
-1 8661 var candidate = relevantNode.querySelector('input:not([type="hidden"]):not([type="image"])' + ':not([type="button"]):not([type="submit"]):not([type="reset"]), select, textarea');
-1 8662 if (candidate && candidate.disabled) {
-1 8663 return false;
-1 8664 }
-1 8665 }
-1 8666 if (node.getAttribute('id')) {
-1 8667 var id = axe.commons.utils.escapeSelector(node.getAttribute('id'));
-1 8668 var _candidate = doc.querySelector('[aria-labelledby~="' + id + '"]');
-1 8669 if (_candidate && _candidate.hasAttribute('disabled')) {
-1 8670 return false;
-1 8671 }
-1 8672 }
-1 8673 if (axe.commons.text.visible(node, false, true) === '') {
-1 8674 return false;
-1 8675 }
-1 8676 var range = document.createRange(), childNodes = node.childNodes, length = childNodes.length, child, index;
-1 8677 for (index = 0; index < length; index++) {
-1 8678 child = childNodes[index];
-1 8679 if (child.nodeType === 3 && axe.commons.text.sanitize(child.nodeValue) !== '') {
-1 8680 range.selectNodeContents(child);
-1 8681 }
-1 8682 }
-1 8683 var rects = range.getClientRects();
-1 8684 length = rects.length;
-1 8685 for (index = 0; index < length; index++) {
-1 8686 if (axe.commons.dom.visuallyOverlaps(rects[index], node)) {
-1 8687 return true;
-1 8688 }
-1 8689 }
-1 8690 return false;
-1 8691 },
-1 8692 excludeHidden: false,
-1 8693 options: {
-1 8694 noScroll: false
-1 8695 },
-1 8696 tags: [ 'cat.color', 'wcag2aa', 'wcag143' ],
-1 8697 all: [],
-1 8698 any: [ 'color-contrast' ],
-1 8699 none: []
-1 8700 }, {
-1 8701 id: 'definition-list',
-1 8702 selector: 'dl:not([role])',
-1 8703 tags: [ 'cat.structure', 'wcag2a', 'wcag131' ],
-1 8704 all: [],
-1 8705 any: [],
-1 8706 none: [ 'structured-dlitems', 'only-dlitems' ]
-1 8707 }, {
-1 8708 id: 'dlitem',
-1 8709 selector: 'dd:not([role]), dt:not([role])',
-1 8710 tags: [ 'cat.structure', 'wcag2a', 'wcag131' ],
-1 8711 all: [],
-1 8712 any: [ 'dlitem' ],
-1 8713 none: []
-1 8714 }, {
-1 8715 id: 'document-title',
-1 8716 selector: 'html',
-1 8717 matches: function matches(node) {
-1 8718 return node.ownerDocument.defaultView.self === node.ownerDocument.defaultView.top;
-1 8719 },
-1 8720 tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag242' ],
-1 8721 all: [],
-1 8722 any: [ 'doc-has-title' ],
-1 8723 none: []
-1 8724 }, {
-1 8725 id: 'duplicate-id',
-1 8726 selector: '[id]',
-1 8727 excludeHidden: false,
-1 8728 tags: [ 'cat.parsing', 'wcag2a', 'wcag411' ],
-1 8729 all: [],
-1 8730 any: [ 'duplicate-id' ],
-1 8731 none: []
-1 8732 }, {
-1 8733 id: 'empty-heading',
-1 8734 selector: 'h1, h2, h3, h4, h5, h6, [role="heading"]',
-1 8735 enabled: true,
-1 8736 tags: [ 'cat.name-role-value', 'best-practice' ],
-1 8737 all: [],
-1 8738 any: [ 'has-visible-text', 'role-presentation', 'role-none' ],
-1 8739 none: []
-1 8740 }, {
-1 8741 id: 'frame-title-unique',
-1 8742 selector: 'frame[title]:not([title=\'\']), iframe[title]:not([title=\'\'])',
-1 8743 matches: function matches(node) {
-1 8744 var title = node.getAttribute('title');
-1 8745 return !!(title ? axe.commons.text.sanitize(title).trim() : '');
-1 8746 },
-1 8747 tags: [ 'cat.text-alternatives', 'best-practice' ],
-1 8748 all: [],
-1 8749 any: [],
-1 8750 none: [ 'unique-frame-title' ]
-1 8751 }, {
-1 8752 id: 'frame-title',
-1 8753 selector: 'frame, iframe',
-1 8754 tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag241', 'section508', 'section508.22.i' ],
-1 8755 all: [],
-1 8756 any: [ 'aria-label', 'aria-labelledby', 'non-empty-title', 'role-presentation', 'role-none' ],
-1 8757 none: []
-1 8758 }, {
-1 8759 id: 'heading-order',
-1 8760 selector: 'h1,h2,h3,h4,h5,h6,[role=heading]',
-1 8761 enabled: false,
-1 8762 tags: [ 'cat.semantics', 'best-practice' ],
-1 8763 all: [],
-1 8764 any: [ 'heading-order' ],
-1 8765 none: []
-1 8766 }, {
-1 8767 id: 'hidden-content',
-1 8768 selector: '*',
-1 8769 excludeHidden: false,
-1 8770 tags: [ 'experimental', 'review-item' ],
-1 8771 all: [],
-1 8772 any: [ 'hidden-content' ],
-1 8773 none: [],
-1 8774 enabled: false
-1 8775 }, {
-1 8776 id: 'href-no-hash',
-1 8777 selector: 'a[href]',
-1 8778 enabled: false,
-1 8779 tags: [ 'cat.semantics', 'best-practice' ],
-1 8780 all: [],
-1 8781 any: [ 'href-no-hash' ],
-1 8782 none: []
-1 8783 }, {
-1 8784 id: 'html-has-lang',
-1 8785 selector: 'html',
-1 8786 tags: [ 'cat.language', 'wcag2a', 'wcag311' ],
-1 8787 all: [],
-1 8788 any: [ 'has-lang' ],
-1 8789 none: []
-1 8790 }, {
-1 8791 id: 'html-lang-valid',
-1 8792 selector: 'html[lang]',
-1 8793 tags: [ 'cat.language', 'wcag2a', 'wcag311' ],
-1 8794 all: [],
-1 8795 any: [],
-1 8796 none: [ 'valid-lang' ]
-1 8797 }, {
-1 8798 id: 'image-alt',
-1 8799 selector: 'img, [role=\'img\']',
-1 8800 tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag111', 'section508', 'section508.22.a' ],
-1 8801 all: [],
-1 8802 any: [ 'has-alt', 'aria-label', 'aria-labelledby', 'non-empty-title', 'role-presentation', 'role-none' ],
-1 8803 none: []
-1 8804 }, {
-1 8805 id: 'image-redundant-alt',
-1 8806 selector: 'button, [role="button"], a[href], p, li, td, th',
-1 8807 tags: [ 'cat.text-alternatives', 'best-practice' ],
-1 8808 all: [],
-1 8809 any: [],
-1 8810 none: [ 'duplicate-img-label' ]
-1 8811 }, {
-1 8812 id: 'input-image-alt',
-1 8813 selector: 'input[type="image"]',
-1 8814 tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag111', 'section508', 'section508.22.a' ],
-1 8815 all: [],
-1 8816 any: [ 'non-empty-alt', 'aria-label', 'aria-labelledby', 'non-empty-title' ],
-1 8817 none: []
-1 8818 }, {
-1 8819 id: 'label-title-only',
-1 8820 selector: 'input:not([type=\'hidden\']):not([type=\'image\']):not([type=\'button\']):not([type=\'submit\']):not([type=\'reset\']), select, textarea',
-1 8821 enabled: false,
-1 8822 tags: [ 'cat.forms', 'best-practice' ],
-1 8823 all: [],
-1 8824 any: [],
-1 8825 none: [ 'title-only' ]
-1 8826 }, {
-1 8827 id: 'label',
-1 8828 selector: 'input:not([type=\'hidden\']):not([type=\'image\']):not([type=\'button\']):not([type=\'submit\']):not([type=\'reset\']), select, textarea',
-1 8829 tags: [ 'cat.forms', 'wcag2a', 'wcag332', 'wcag131', 'section508', 'section508.22.n' ],
-1 8830 all: [],
-1 8831 any: [ 'aria-label', 'aria-labelledby', 'implicit-label', 'explicit-label', 'non-empty-title' ],
-1 8832 none: [ 'help-same-as-label', 'multiple-label' ]
-1 8833 }, {
-1 8834 id: 'landmark-main-is-top-level',
-1 8835 selector: 'main,[role=main]',
-1 8836 tags: [ 'best-practice' ],
-1 8837 all: [],
-1 8838 any: [ 'main-is-top-level' ],
-1 8839 none: []
-1 8840 }, {
-1 8841 id: 'landmark-one-main',
-1 8842 selector: 'html',
-1 8843 tags: [ 'best-practice' ],
-1 8844 all: [ 'has-at-least-one-main', 'has-no-more-than-one-main' ],
-1 8845 any: [],
-1 8846 none: []
-1 8847 }, {
-1 8848 id: 'layout-table',
-1 8849 selector: 'table',
-1 8850 matches: function matches(node) {
-1 8851 return !axe.commons.table.isDataTable(node);
-1 8852 },
-1 8853 tags: [ 'cat.semantics', 'wcag2a', 'wcag131' ],
-1 8854 all: [],
-1 8855 any: [],
-1 8856 none: [ 'has-th', 'has-caption', 'has-summary' ]
-1 8857 }, {
-1 8858 id: 'link-in-text-block',
-1 8859 selector: 'a[href]:not([role]), *[role=link]',
-1 8860 matches: function matches(node) {
-1 8861 var text = axe.commons.text.sanitize(node.textContent);
-1 8862 if (!text) {
-1 8863 return false;
-1 8864 }
-1 8865 if (!axe.commons.dom.isVisible(node, false)) {
-1 8866 return false;
-1 8867 }
-1 8868 return axe.commons.dom.isInTextBlock(node);
-1 8869 },
-1 8870 excludeHidden: false,
-1 8871 tags: [ 'cat.color', 'experimental', 'wcag2a', 'wcag141' ],
-1 8872 all: [ 'link-in-text-block' ],
-1 8873 any: [],
-1 8874 none: []
-1 8875 }, {
-1 8876 id: 'link-name',
-1 8877 selector: 'a[href]:not([role="button"]), [role=link][href]',
-1 8878 tags: [ 'cat.name-role-value', 'wcag2a', 'wcag111', 'wcag412', 'wcag244', 'section508', 'section508.22.a' ],
-1 8879 all: [],
-1 8880 any: [ 'has-visible-text', 'aria-label', 'aria-labelledby', 'role-presentation', 'role-none' ],
-1 8881 none: [ 'focusable-no-name' ]
-1 8882 }, {
-1 8883 id: 'list',
-1 8884 selector: 'ul:not([role]), ol:not([role])',
-1 8885 tags: [ 'cat.structure', 'wcag2a', 'wcag131' ],
-1 8886 all: [],
-1 8887 any: [],
-1 8888 none: [ 'only-listitems' ]
-1 8889 }, {
-1 8890 id: 'listitem',
-1 8891 selector: 'li:not([role])',
-1 8892 tags: [ 'cat.structure', 'wcag2a', 'wcag131' ],
-1 8893 all: [],
-1 8894 any: [ 'listitem' ],
-1 8895 none: []
-1 8896 }, {
-1 8897 id: 'marquee',
-1 8898 selector: 'marquee',
-1 8899 excludeHidden: false,
-1 8900 tags: [ 'cat.parsing', 'wcag2a', 'wcag222' ],
-1 8901 all: [],
-1 8902 any: [],
-1 8903 none: [ 'is-on-screen' ]
-1 8904 }, {
-1 8905 id: 'meta-refresh',
-1 8906 selector: 'meta[http-equiv="refresh"]',
-1 8907 excludeHidden: false,
-1 8908 tags: [ 'cat.time', 'wcag2a', 'wcag2aaa', 'wcag221', 'wcag224', 'wcag325' ],
-1 8909 all: [],
-1 8910 any: [ 'meta-refresh' ],
-1 8911 none: []
-1 8912 }, {
-1 8913 id: 'meta-viewport-large',
-1 8914 selector: 'meta[name="viewport"]',
-1 8915 excludeHidden: false,
-1 8916 tags: [ 'cat.sensory-and-visual-cues', 'best-practice' ],
-1 8917 all: [],
-1 8918 any: [ {
-1 8919 options: {
-1 8920 scaleMinimum: 5,
-1 8921 lowerBound: 2
-1 8922 },
-1 8923 id: 'meta-viewport-large'
-1 8924 } ],
-1 8925 none: []
-1 8926 }, {
-1 8927 id: 'meta-viewport',
-1 8928 selector: 'meta[name="viewport"]',
-1 8929 excludeHidden: false,
-1 8930 tags: [ 'cat.sensory-and-visual-cues', 'wcag2aa', 'wcag144' ],
-1 8931 all: [],
-1 8932 any: [ {
-1 8933 options: {
-1 8934 scaleMinimum: 2
-1 8935 },
-1 8936 id: 'meta-viewport'
-1 8937 } ],
-1 8938 none: []
-1 8939 }, {
-1 8940 id: 'object-alt',
-1 8941 selector: 'object',
-1 8942 tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag111', 'section508', 'section508.22.a' ],
-1 8943 all: [],
-1 8944 any: [ 'has-visible-text', 'aria-label', 'aria-labelledby', 'non-empty-title' ],
-1 8945 none: []
-1 8946 }, {
-1 8947 id: 'p-as-heading',
-1 8948 selector: 'p',
-1 8949 matches: function matches(node) {
-1 8950 var children = Array.from(node.parentNode.childNodes);
-1 8951 var nodeText = node.textContent.trim();
-1 8952 var isSentence = /[.!?:;](?![.!?:;])/g;
-1 8953 if (nodeText.length === 0 || (nodeText.match(isSentence) || []).length >= 2) {
-1 8954 return false;
-1 8955 }
-1 8956 var siblingsAfter = children.slice(children.indexOf(node) + 1).filter(function(elm) {
-1 8957 return elm.nodeName.toUpperCase() === 'P' && elm.textContent.trim() !== '';
-1 8958 });
-1 8959 return siblingsAfter.length !== 0;
-1 8960 },
-1 8961 tags: [ 'cat.semantics', 'wcag2a', 'wcag131', 'experimental' ],
-1 8962 all: [ {
-1 8963 options: {
-1 8964 margins: [ {
-1 8965 weight: 150,
-1 8966 italic: true
-1 8967 }, {
-1 8968 weight: 150,
-1 8969 size: 1.15
-1 8970 }, {
-1 8971 italic: true,
-1 8972 size: 1.15
-1 8973 }, {
-1 8974 size: 1.4
-1 8975 } ]
-1 8976 },
-1 8977 id: 'p-as-heading'
-1 8978 } ],
-1 8979 any: [],
-1 8980 none: []
-1 8981 }, {
-1 8982 id: 'radiogroup',
-1 8983 selector: 'input[type=radio][name]',
-1 8984 tags: [ 'cat.forms', 'best-practice' ],
-1 8985 all: [],
-1 8986 any: [ 'group-labelledby', 'fieldset' ],
-1 8987 none: []
-1 8988 }, {
-1 8989 id: 'region',
-1 8990 selector: 'html',
-1 8991 pageLevel: true,
-1 8992 enabled: false,
-1 8993 tags: [ 'cat.keyboard', 'best-practice' ],
-1 8994 all: [],
-1 8995 any: [ 'region' ],
-1 8996 none: []
-1 8997 }, {
-1 8998 id: 'scope-attr-valid',
-1 8999 selector: 'td[scope], th[scope]',
-1 9000 enabled: true,
-1 9001 tags: [ 'cat.tables', 'best-practice' ],
-1 9002 all: [ 'html5-scope', 'scope-value' ],
-1 9003 any: [],
-1 9004 none: []
-1 9005 }, {
-1 9006 id: 'server-side-image-map',
-1 9007 selector: 'img[ismap]',
-1 9008 tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag211', 'section508', 'section508.22.f' ],
-1 9009 all: [],
-1 9010 any: [],
-1 9011 none: [ 'exists' ]
-1 9012 }, {
-1 9013 id: 'skip-link',
-1 9014 selector: 'a[href]',
-1 9015 pageLevel: true,
-1 9016 enabled: false,
-1 9017 tags: [ 'cat.keyboard', 'best-practice' ],
-1 9018 all: [],
-1 9019 any: [ 'skip-link' ],
-1 9020 none: []
-1 9021 }, {
-1 9022 id: 'tabindex',
-1 9023 selector: '[tabindex]',
-1 9024 tags: [ 'cat.keyboard', 'best-practice' ],
-1 9025 all: [],
-1 9026 any: [ 'tabindex' ],
-1 9027 none: []
-1 9028 }, {
-1 9029 id: 'table-duplicate-name',
-1 9030 selector: 'table',
-1 9031 tags: [ 'cat.tables', 'best-practice' ],
-1 9032 all: [],
-1 9033 any: [],
-1 9034 none: [ 'same-caption-summary' ]
-1 9035 }, {
-1 9036 id: 'table-fake-caption',
-1 9037 selector: 'table',
-1 9038 matches: function matches(node) {
-1 9039 return axe.commons.table.isDataTable(node);
-1 9040 },
-1 9041 tags: [ 'cat.tables', 'experimental', 'wcag2a', 'wcag131', 'section508', 'section508.22.g' ],
-1 9042 all: [ 'caption-faked' ],
-1 9043 any: [],
-1 9044 none: []
-1 9045 }, {
-1 9046 id: 'td-has-header',
-1 9047 selector: 'table',
-1 9048 matches: function matches(node) {
-1 9049 if (axe.commons.table.isDataTable(node)) {
-1 9050 var tableArray = axe.commons.table.toArray(node);
-1 9051 return tableArray.length >= 3 && tableArray[0].length >= 3 && tableArray[1].length >= 3 && tableArray[2].length >= 3;
-1 9052 }
-1 9053 return false;
-1 9054 },
-1 9055 tags: [ 'cat.tables', 'experimental', 'wcag2a', 'wcag131', 'section508', 'section508.22.g' ],
-1 9056 all: [ 'td-has-header' ],
-1 9057 any: [],
-1 9058 none: []
-1 9059 }, {
-1 9060 id: 'td-headers-attr',
-1 9061 selector: 'table',
-1 9062 tags: [ 'cat.tables', 'wcag2a', 'wcag131', 'section508', 'section508.22.g' ],
-1 9063 all: [ 'td-headers-attr' ],
-1 9064 any: [],
-1 9065 none: []
-1 9066 }, {
-1 9067 id: 'th-has-data-cells',
-1 9068 selector: 'table',
-1 9069 matches: function matches(node) {
-1 9070 return axe.commons.table.isDataTable(node);
-1 9071 },
-1 9072 tags: [ 'cat.tables', 'wcag2a', 'wcag131', 'section508', 'section508.22.g' ],
-1 9073 all: [ 'th-has-data-cells' ],
-1 9074 any: [],
-1 9075 none: []
-1 9076 }, {
-1 9077 id: 'valid-lang',
-1 9078 selector: '[lang]:not(html), [xml\\:lang]:not(html)',
-1 9079 tags: [ 'cat.language', 'wcag2aa', 'wcag312' ],
-1 9080 all: [],
-1 9081 any: [],
-1 9082 none: [ 'valid-lang' ]
-1 9083 }, {
-1 9084 id: 'video-caption',
-1 9085 selector: 'video',
-1 9086 excludeHidden: false,
-1 9087 tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag122', 'wcag123', 'section508', 'section508.22.a' ],
-1 9088 all: [],
-1 9089 any: [],
-1 9090 none: [ 'caption' ]
-1 9091 }, {
-1 9092 id: 'video-description',
-1 9093 selector: 'video',
-1 9094 excludeHidden: false,
-1 9095 tags: [ 'cat.text-alternatives', 'wcag2aa', 'wcag125', 'section508', 'section508.22.b' ],
-1 9096 all: [],
-1 9097 any: [],
-1 9098 none: [ 'description' ]
-1 9099 } ],
-1 9100 checks: [ {
-1 9101 id: 'abstractrole',
-1 9102 evaluate: function evaluate(node, options) {
-1 9103 return axe.commons.aria.getRoleType(node.getAttribute('role')) === 'abstract';
-1 9104 }
-1 9105 }, {
-1 9106 id: 'aria-allowed-attr',
-1 9107 evaluate: function evaluate(node, options) {
-1 9108 var invalid = [];
-1 9109 var attr, attrName, allowed, role = node.getAttribute('role'), attrs = node.attributes;
-1 9110 if (!role) {
-1 9111 role = axe.commons.aria.implicitRole(node);
-1 9112 }
-1 9113 allowed = axe.commons.aria.allowedAttr(role);
-1 9114 if (role && allowed) {
-1 9115 for (var i = 0, l = attrs.length; i < l; i++) {
-1 9116 attr = attrs[i];
-1 9117 attrName = attr.name;
-1 9118 if (axe.commons.aria.validateAttr(attrName) && allowed.indexOf(attrName) === -1) {
-1 9119 invalid.push(attrName + '="' + attr.nodeValue + '"');
-1 9120 }
-1 9121 }
-1 9122 }
-1 9123 if (invalid.length) {
-1 9124 this.data(invalid);
-1 9125 return false;
-1 9126 }
-1 9127 return true;
-1 9128 }
-1 9129 }, {
-1 9130 id: 'aria-hidden-body',
-1 9131 evaluate: function evaluate(node, options) {
-1 9132 return node.getAttribute('aria-hidden') !== 'true';
-1 9133 }
-1 9134 }, {
-1 9135 id: 'aria-errormessage',
-1 9136 evaluate: function evaluate(node, options) {
-1 9137 options = Array.isArray(options) ? options : [];
-1 9138 var attr = node.getAttribute('aria-errormessage'), hasAttr = node.hasAttribute('aria-errormessage');
-1 9139 var doc = document;
-1 9140 function validateAttrValue() {
-1 9141 var idref = attr && doc.getElementById(attr);
-1 9142 if (idref) {
-1 9143 return idref.getAttribute('role') === 'alert' || idref.getAttribute('aria-live') === 'assertive' || axe.utils.tokenList(node.getAttribute('aria-describedby') || '').indexOf(attr) > -1;
-1 9144 }
-1 9145 }
-1 9146 if (options.indexOf(attr) === -1 && hasAttr) {
-1 9147 if (!validateAttrValue()) {
-1 9148 this.data(attr);
-1 9149 return false;
-1 9150 }
-1 9151 }
-1 9152 return true;
-1 9153 }
-1 9154 }, {
-1 9155 id: 'invalidrole',
-1 9156 evaluate: function evaluate(node, options) {
-1 9157 return !axe.commons.aria.isValidRole(node.getAttribute('role'));
-1 9158 }
-1 9159 }, {
-1 9160 id: 'aria-required-attr',
-1 9161 evaluate: function evaluate(node, options) {
-1 9162 var missing = [];
-1 9163 if (node.hasAttributes()) {
-1 9164 var attr, role = node.getAttribute('role'), required = axe.commons.aria.requiredAttr(role);
-1 9165 if (role && required) {
-1 9166 for (var i = 0, l = required.length; i < l; i++) {
-1 9167 attr = required[i];
-1 9168 if (!node.getAttribute(attr)) {
-1 9169 missing.push(attr);
-1 9170 }
-1 9171 }
-1 9172 }
-1 9173 }
-1 9174 if (missing.length) {
-1 9175 this.data(missing);
-1 9176 return false;
-1 9177 }
-1 9178 return true;
-1 9179 }
-1 9180 }, {
-1 9181 id: 'aria-required-children',
-1 9182 evaluate: function evaluate(node, options) {
-1 9183 var requiredOwned = axe.commons.aria.requiredOwned, implicitNodes = axe.commons.aria.implicitNodes, matchesSelector = axe.commons.utils.matchesSelector, idrefs = axe.commons.dom.idrefs;
-1 9184 function owns(node, role, ariaOwned) {
-1 9185 if (node === null) {
-1 9186 return false;
-1 9187 }
-1 9188 var implicit = implicitNodes(role), selector = [ '[role="' + role + '"]' ];
-1 9189 if (implicit) {
-1 9190 selector = selector.concat(implicit);
-1 9191 }
-1 9192 selector = selector.join(',');
-1 9193 return ariaOwned ? matchesSelector(node, selector) || !!node.querySelector(selector) : !!node.querySelector(selector);
-1 9194 }
-1 9195 function ariaOwns(nodes, role) {
-1 9196 var index, length;
-1 9197 for (index = 0, length = nodes.length; index < length; index++) {
-1 9198 if (nodes[index] === null) {
-1 9199 continue;
-1 9200 }
-1 9201 if (owns(nodes[index], role, true)) {
-1 9202 return true;
-1 9203 }
-1 9204 }
-1 9205 return false;
-1 9206 }
-1 9207 function missingRequiredChildren(node, childRoles, all, role) {
-1 9208 var i, l = childRoles.length, missing = [], ownedElements = idrefs(node, 'aria-owns');
-1 9209 for (i = 0; i < l; i++) {
-1 9210 var r = childRoles[i];
-1 9211 if (owns(node, r) || ariaOwns(ownedElements, r)) {
-1 9212 if (!all) {
-1 9213 return null;
-1 9214 }
-1 9215 } else {
-1 9216 if (all) {
-1 9217 missing.push(r);
-1 9218 }
-1 9219 }
-1 9220 }
-1 9221 if (role === 'combobox') {
-1 9222 var textboxIndex = missing.indexOf('textbox');
-1 9223 var textTypeInputs = [ 'text', 'search', 'email', 'url', 'tel' ];
-1 9224 if (textboxIndex >= 0 && node.tagName === 'INPUT' && textTypeInputs.includes(node.type)) {
-1 9225 missing.splice(textboxIndex, 1);
-1 9226 }
-1 9227 var listboxIndex = missing.indexOf('listbox');
-1 9228 var expanded = node.getAttribute('aria-expanded');
-1 9229 if (listboxIndex >= 0 && (!expanded || expanded === 'false')) {
-1 9230 missing.splice(listboxIndex, 1);
-1 9231 }
-1 9232 }
-1 9233 if (missing.length) {
-1 9234 return missing;
-1 9235 }
-1 9236 if (!all && childRoles.length) {
-1 9237 return childRoles;
-1 9238 }
-1 9239 return null;
-1 9240 }
-1 9241 var role = node.getAttribute('role');
-1 9242 var required = requiredOwned(role);
-1 9243 if (!required) {
-1 9244 return true;
-1 9245 }
-1 9246 var all = false;
-1 9247 var childRoles = required.one;
-1 9248 if (!childRoles) {
-1 9249 var all = true;
-1 9250 childRoles = required.all;
-1 9251 }
-1 9252 var missing = missingRequiredChildren(node, childRoles, all, role);
-1 9253 if (!missing) {
-1 9254 return true;
-1 9255 }
-1 9256 this.data(missing);
-1 9257 return false;
-1 9258 }
-1 9259 }, {
-1 9260 id: 'aria-required-parent',
-1 9261 evaluate: function evaluate(node, options) {
-1 9262 function getSelector(role) {
-1 9263 var impliedNative = axe.commons.aria.implicitNodes(role) || [];
-1 9264 return impliedNative.concat('[role="' + role + '"]').join(',');
-1 9265 }
-1 9266 function getMissingContext(element, requiredContext, includeElement) {
-1 9267 var index, length, role = element.getAttribute('role'), missing = [];
-1 9268 if (!requiredContext) {
-1 9269 requiredContext = axe.commons.aria.requiredContext(role);
-1 9270 }
-1 9271 if (!requiredContext) {
-1 9272 return null;
-1 9273 }
-1 9274 for (index = 0, length = requiredContext.length; index < length; index++) {
-1 9275 if (includeElement && axe.utils.matchesSelector(element, getSelector(requiredContext[index]))) {
-1 9276 return null;
-1 9277 }
-1 9278 if (axe.commons.dom.findUp(element, getSelector(requiredContext[index]))) {
-1 9279 return null;
-1 9280 } else {
-1 9281 missing.push(requiredContext[index]);
-1 9282 }
-1 9283 }
-1 9284 return missing;
-1 9285 }
-1 9286 function getAriaOwners(element) {
-1 9287 var owners = [], o = null;
-1 9288 while (element) {
-1 9289 if (element.getAttribute('id')) {
-1 9290 var id = axe.commons.utils.escapeSelector(element.getAttribute('id'));
-1 9291 o = document.querySelector('[aria-owns~=' + id + ']');
-1 9292 if (o) {
-1 9293 owners.push(o);
-1 9294 }
-1 9295 }
-1 9296 element = element.parentElement;
-1 9297 }
-1 9298 return owners.length ? owners : null;
-1 9299 }
-1 9300 var missingParents = getMissingContext(node);
-1 9301 if (!missingParents) {
-1 9302 return true;
-1 9303 }
-1 9304 var owners = getAriaOwners(node);
-1 9305 if (owners) {
-1 9306 for (var i = 0, l = owners.length; i < l; i++) {
-1 9307 missingParents = getMissingContext(owners[i], missingParents, true);
-1 9308 if (!missingParents) {
-1 9309 return true;
-1 9310 }
-1 9311 }
-1 9312 }
-1 9313 this.data(missingParents);
-1 9314 return false;
-1 9315 }
-1 9316 }, {
-1 9317 id: 'aria-valid-attr-value',
-1 9318 evaluate: function evaluate(node, options) {
-1 9319 options = Array.isArray(options) ? options : [];
-1 9320 var invalid = [], aria = /^aria-/;
-1 9321 var attr, attrName, attrs = node.attributes;
-1 9322 var skipAttrs = [ 'aria-errormessage' ];
-1 9323 for (var i = 0, l = attrs.length; i < l; i++) {
-1 9324 attr = attrs[i];
-1 9325 attrName = attr.name;
-1 9326 if (!skipAttrs.includes(attrName)) {
-1 9327 if (options.indexOf(attrName) === -1 && aria.test(attrName) && !axe.commons.aria.validateAttrValue(node, attrName)) {
-1 9328 invalid.push(attrName + '="' + attr.nodeValue + '"');
-1 9329 }
-1 9330 }
-1 9331 }
-1 9332 if (invalid.length) {
-1 9333 this.data(invalid);
-1 9334 return false;
-1 9335 }
-1 9336 return true;
-1 9337 },
-1 9338 options: []
-1 9339 }, {
-1 9340 id: 'aria-valid-attr',
-1 9341 evaluate: function evaluate(node, options) {
-1 9342 options = Array.isArray(options) ? options : [];
-1 9343 var invalid = [], aria = /^aria-/;
-1 9344 var attr, attrs = node.attributes;
-1 9345 for (var i = 0, l = attrs.length; i < l; i++) {
-1 9346 attr = attrs[i].name;
-1 9347 if (options.indexOf(attr) === -1 && aria.test(attr) && !axe.commons.aria.validateAttr(attr)) {
-1 9348 invalid.push(attr);
-1 9349 }
-1 9350 }
-1 9351 if (invalid.length) {
-1 9352 this.data(invalid);
-1 9353 return false;
-1 9354 }
-1 9355 return true;
-1 9356 },
-1 9357 options: []
-1 9358 }, {
-1 9359 id: 'color-contrast',
-1 9360 evaluate: function evaluate(node, options) {
-1 9361 if (!axe.commons.dom.isVisible(node, false)) {
-1 9362 return true;
-1 9363 }
-1 9364 var noScroll = !!(options || {}).noScroll;
-1 9365 var bgNodes = [], bgColor = axe.commons.color.getBackgroundColor(node, bgNodes, noScroll), fgColor = axe.commons.color.getForegroundColor(node, noScroll);
-1 9366 var nodeStyle = window.getComputedStyle(node);
-1 9367 var fontSize = parseFloat(nodeStyle.getPropertyValue('font-size'));
-1 9368 var fontWeight = nodeStyle.getPropertyValue('font-weight');
-1 9369 var bold = [ 'bold', 'bolder', '600', '700', '800', '900' ].indexOf(fontWeight) !== -1;
-1 9370 var cr = axe.commons.color.hasValidContrastRatio(bgColor, fgColor, fontSize, bold);
-1 9371 var truncatedResult = Math.floor(cr.contrastRatio * 100) / 100;
-1 9372 var missing;
-1 9373 if (bgColor === null) {
-1 9374 missing = axe.commons.color.incompleteData.get('bgColor');
-1 9375 }
-1 9376 var equalRatio = false;
-1 9377 if (truncatedResult === 1) {
-1 9378 equalRatio = true;
-1 9379 missing = axe.commons.color.incompleteData.set('bgColor', 'equalRatio');
-1 9380 }
-1 9381 var data = {
-1 9382 fgColor: fgColor ? fgColor.toHexString() : undefined,
-1 9383 bgColor: bgColor ? bgColor.toHexString() : undefined,
-1 9384 contrastRatio: cr ? truncatedResult : undefined,
-1 9385 fontSize: (fontSize * 72 / 96).toFixed(1) + 'pt',
-1 9386 fontWeight: bold ? 'bold' : 'normal',
-1 9387 missingData: missing,
-1 9388 expectedContrastRatio: cr.expectedContrastRatio + ':1'
-1 9389 };
-1 9390 this.data(data);
-1 9391 if (fgColor === null || bgColor === null || equalRatio) {
-1 9392 missing = null;
-1 9393 axe.commons.color.incompleteData.clear();
-1 9394 this.relatedNodes(bgNodes);
-1 9395 return undefined;
-1 9396 } else if (!cr.isValid) {
-1 9397 this.relatedNodes(bgNodes);
-1 9398 }
-1 9399 return cr.isValid;
-1 9400 }
-1 9401 }, {
-1 9402 id: 'link-in-text-block',
-1 9403 evaluate: function evaluate(node, options) {
-1 9404 var color = axe.commons.color;
-1 9405 function getContrast(color1, color2) {
-1 9406 var c1lum = color1.getRelativeLuminance();
-1 9407 var c2lum = color2.getRelativeLuminance();
-1 9408 return (Math.max(c1lum, c2lum) + .05) / (Math.min(c1lum, c2lum) + .05);
-1 9409 }
-1 9410 var blockLike = [ 'block', 'list-item', 'table', 'flex', 'grid', 'inline-block' ];
-1 9411 function isBlock(elm) {
-1 9412 var display = window.getComputedStyle(elm).getPropertyValue('display');
-1 9413 return blockLike.indexOf(display) !== -1 || display.substr(0, 6) === 'table-';
-1 9414 }
-1 9415 if (isBlock(node)) {
-1 9416 return false;
-1 9417 }
-1 9418 var parentBlock = node.parentNode;
-1 9419 while (parentBlock.nodeType === 1 && !isBlock(parentBlock)) {
-1 9420 parentBlock = parentBlock.parentNode;
-1 9421 }
-1 9422 this.relatedNodes([ parentBlock ]);
-1 9423 if (color.elementIsDistinct(node, parentBlock)) {
-1 9424 return true;
-1 9425 } else {
-1 9426 var nodeColor, parentColor;
-1 9427 nodeColor = color.getForegroundColor(node);
-1 9428 parentColor = color.getForegroundColor(parentBlock);
-1 9429 if (!nodeColor || !parentColor) {
-1 9430 return undefined;
-1 9431 }
-1 9432 var contrast = getContrast(nodeColor, parentColor);
-1 9433 if (contrast === 1) {
-1 9434 return true;
-1 9435 } else if (contrast >= 3) {
-1 9436 axe.commons.color.incompleteData.set('fgColor', 'bgContrast');
-1 9437 this.data({
-1 9438 missingData: axe.commons.color.incompleteData.get('fgColor')
-1 9439 });
-1 9440 axe.commons.color.incompleteData.clear();
-1 9441 return undefined;
-1 9442 }
-1 9443 nodeColor = color.getBackgroundColor(node);
-1 9444 parentColor = color.getBackgroundColor(parentBlock);
-1 9445 if (!nodeColor || !parentColor || getContrast(nodeColor, parentColor) >= 3) {
-1 9446 var reason = void 0;
-1 9447 if (!nodeColor || !parentColor) {
-1 9448 reason = axe.commons.color.incompleteData.get('bgColor');
-1 9449 } else {
-1 9450 reason = 'bgContrast';
-1 9451 }
-1 9452 axe.commons.color.incompleteData.set('fgColor', reason);
-1 9453 this.data({
-1 9454 missingData: axe.commons.color.incompleteData.get('fgColor')
-1 9455 });
-1 9456 axe.commons.color.incompleteData.clear();
-1 9457 return undefined;
-1 9458 }
-1 9459 }
-1 9460 return false;
-1 9461 }
-1 9462 }, {
-1 9463 id: 'fieldset',
-1 9464 evaluate: function evaluate(node, options) {
-1 9465 var failureCode, self = this;
-1 9466 function getUnrelatedElements(parent, name) {
-1 9467 return axe.commons.utils.toArray(parent.querySelectorAll('select,textarea,button,input:not([name="' + name + '"]):not([type="hidden"])'));
-1 9468 }
-1 9469 function checkFieldset(group, name) {
-1 9470 var firstNode = group.firstElementChild;
-1 9471 if (!firstNode || firstNode.nodeName.toUpperCase() !== 'LEGEND') {
-1 9472 self.relatedNodes([ group ]);
-1 9473 failureCode = 'no-legend';
-1 9474 return false;
-1 9475 }
-1 9476 if (!axe.commons.text.accessibleText(firstNode)) {
-1 9477 self.relatedNodes([ firstNode ]);
-1 9478 failureCode = 'empty-legend';
-1 9479 return false;
-1 9480 }
-1 9481 var otherElements = getUnrelatedElements(group, name);
-1 9482 if (otherElements.length) {
-1 9483 self.relatedNodes(otherElements);
-1 9484 failureCode = 'mixed-inputs';
-1 9485 return false;
-1 9486 }
-1 9487 return true;
-1 9488 }
-1 9489 function checkARIAGroup(group, name) {
-1 9490 var hasLabelledByText = axe.commons.dom.idrefs(group, 'aria-labelledby').some(function(element) {
-1 9491 return element && axe.commons.text.accessibleText(element);
-1 9492 });
-1 9493 var ariaLabel = group.getAttribute('aria-label');
-1 9494 if (!hasLabelledByText && !(ariaLabel && axe.commons.text.sanitize(ariaLabel))) {
-1 9495 self.relatedNodes(group);
-1 9496 failureCode = 'no-group-label';
-1 9497 return false;
-1 9498 }
-1 9499 var otherElements = getUnrelatedElements(group, name);
-1 9500 if (otherElements.length) {
-1 9501 self.relatedNodes(otherElements);
-1 9502 failureCode = 'group-mixed-inputs';
-1 9503 return false;
-1 9504 }
-1 9505 return true;
-1 9506 }
-1 9507 function spliceCurrentNode(nodes, current) {
-1 9508 return axe.commons.utils.toArray(nodes).filter(function(candidate) {
-1 9509 return candidate !== current;
-1 9510 });
-1 9511 }
-1 9512 function runCheck(element) {
-1 9513 var name = axe.commons.utils.escapeSelector(node.name);
-1 9514 var matchingNodes = document.querySelectorAll('input[type="' + axe.commons.utils.escapeSelector(node.type) + '"][name="' + name + '"]');
-1 9515 if (matchingNodes.length < 2) {
-1 9516 return true;
-1 9517 }
-1 9518 var fieldset = axe.commons.dom.findUp(element, 'fieldset');
-1 9519 var group = axe.commons.dom.findUp(element, '[role="group"]' + (node.type === 'radio' ? ',[role="radiogroup"]' : ''));
-1 9520 if (!group && !fieldset) {
-1 9521 failureCode = 'no-group';
-1 9522 self.relatedNodes(spliceCurrentNode(matchingNodes, element));
-1 9523 return false;
-1 9524 }
-1 9525 return fieldset ? checkFieldset(fieldset, name) : checkARIAGroup(group, name);
-1 9526 }
-1 9527 var data = {
-1 9528 name: node.getAttribute('name'),
-1 9529 type: node.getAttribute('type')
-1 9530 };
-1 9531 var result = runCheck(node);
-1 9532 if (!result) {
-1 9533 data.failureCode = failureCode;
-1 9534 }
-1 9535 this.data(data);
-1 9536 return result;
-1 9537 },
-1 9538 after: function after(results, options) {
-1 9539 var seen = {};
-1 9540 return results.filter(function(result) {
-1 9541 if (result.result) {
-1 9542 return true;
-1 9543 }
-1 9544 var data = result.data;
-1 9545 if (data) {
-1 9546 seen[data.type] = seen[data.type] || {};
-1 9547 if (!seen[data.type][data.name]) {
-1 9548 seen[data.type][data.name] = [ data ];
-1 9549 return true;
-1 9550 }
-1 9551 var hasBeenSeen = seen[data.type][data.name].some(function(candidate) {
-1 9552 return candidate.failureCode === data.failureCode;
-1 9553 });
-1 9554 if (!hasBeenSeen) {
-1 9555 seen[data.type][data.name].push(data);
-1 9556 }
-1 9557 return !hasBeenSeen;
-1 9558 }
-1 9559 return false;
-1 9560 });
-1 9561 }
-1 9562 }, {
-1 9563 id: 'group-labelledby',
-1 9564 evaluate: function evaluate(node, options) {
-1 9565 this.data({
-1 9566 name: node.getAttribute('name'),
-1 9567 type: node.getAttribute('type')
-1 9568 });
-1 9569 var matchingNodes = document.querySelectorAll('input[type="' + axe.commons.utils.escapeSelector(node.type) + '"][name="' + axe.commons.utils.escapeSelector(node.name) + '"]');
-1 9570 if (matchingNodes.length <= 1) {
-1 9571 return true;
-1 9572 }
-1 9573 return [].map.call(matchingNodes, function(m) {
-1 9574 var l = m.getAttribute('aria-labelledby');
-1 9575 return l ? l.split(/\s+/) : [];
-1 9576 }).reduce(function(prev, curr) {
-1 9577 return prev.filter(function(n) {
-1 9578 return curr.indexOf(n) !== -1;
-1 9579 });
-1 9580 }).filter(function(n) {
-1 9581 var labelNode = document.getElementById(n);
-1 9582 return labelNode && axe.commons.text.accessibleText(labelNode);
-1 9583 }).length !== 0;
-1 9584 },
-1 9585 after: function after(results, options) {
-1 9586 var seen = {};
-1 9587 return results.filter(function(result) {
-1 9588 var data = result.data;
-1 9589 if (data) {
-1 9590 seen[data.type] = seen[data.type] || {};
-1 9591 if (!seen[data.type][data.name]) {
-1 9592 seen[data.type][data.name] = true;
-1 9593 return true;
-1 9594 }
-1 9595 }
-1 9596 return false;
-1 9597 });
-1 9598 }
-1 9599 }, {
-1 9600 id: 'accesskeys',
-1 9601 evaluate: function evaluate(node, options) {
-1 9602 if (axe.commons.dom.isVisible(node, false)) {
-1 9603 this.data(node.getAttribute('accesskey'));
-1 9604 this.relatedNodes([ node ]);
-1 9605 }
-1 9606 return true;
-1 9607 },
-1 9608 after: function after(results, options) {
-1 9609 var seen = {};
-1 9610 return results.filter(function(r) {
-1 9611 if (!r.data) {
-1 9612 return false;
-1 9613 }
-1 9614 var key = r.data.toUpperCase();
-1 9615 if (!seen[key]) {
-1 9616 seen[key] = r;
-1 9617 r.relatedNodes = [];
-1 9618 return true;
-1 9619 }
-1 9620 seen[key].relatedNodes.push(r.relatedNodes[0]);
-1 9621 return false;
-1 9622 }).map(function(r) {
-1 9623 r.result = !!r.relatedNodes.length;
-1 9624 return r;
-1 9625 });
-1 9626 }
-1 9627 }, {
-1 9628 id: 'focusable-no-name',
-1 9629 evaluate: function evaluate(node, options) {
-1 9630 var tabIndex = node.getAttribute('tabindex'), isFocusable = axe.commons.dom.isFocusable(node) && tabIndex > -1;
-1 9631 if (!isFocusable) {
-1 9632 return false;
-1 9633 }
-1 9634 return !axe.commons.text.accessibleText(node);
-1 9635 }
-1 9636 }, {
-1 9637 id: 'has-at-least-one-main',
-1 9638 evaluate: function evaluate(node, options) {
-1 9639 var mains = document.querySelectorAll('main,[role=main]');
-1 9640 this.data(!!mains[0]);
-1 9641 return !!mains[0];
-1 9642 },
-1 9643 after: function after(results, options) {
-1 9644 var hasMain = false;
-1 9645 for (var i = 0; i < results.length && !hasMain; i++) {
-1 9646 hasMain = results[i].data;
-1 9647 }
-1 9648 for (var i = 0; i < results.length; i++) {
-1 9649 results[i].result = hasMain;
-1 9650 }
-1 9651 return results;
-1 9652 }
-1 9653 }, {
-1 9654 id: 'has-no-more-than-one-main',
-1 9655 evaluate: function evaluate(node, options) {
-1 9656 var mains = document.querySelectorAll('main,[role=main]');
-1 9657 return mains.length <= 1;
-1 9658 }
-1 9659 }, {
-1 9660 id: 'main-is-top-level',
-1 9661 evaluate: function evaluate(node, options) {
-1 9662 var landmarks = axe.commons.aria.getRolesByType('landmark');
-1 9663 var parent = node.parentNode;
-1 9664 while (parent) {
-1 9665 if (parent.nodeType === 1) {
-1 9666 var role = parent.getAttribute('role');
-1 9667 if (!role && parent.tagName.toLowerCase() !== 'form') {
-1 9668 role = axe.commons.aria.implicitRole(parent);
-1 9669 }
-1 9670 if (role && landmarks.includes(role)) {
-1 9671 return false;
-1 9672 }
-1 9673 }
-1 9674 parent = parent.parentNode;
-1 9675 }
-1 9676 return true;
-1 9677 }
-1 9678 }, {
-1 9679 id: 'tabindex',
-1 9680 evaluate: function evaluate(node, options) {
-1 9681 return node.tabIndex <= 0;
-1 9682 }
-1 9683 }, {
-1 9684 id: 'duplicate-img-label',
-1 9685 evaluate: function evaluate(node, options) {
-1 9686 var imgs = node.querySelectorAll('img');
-1 9687 var text = axe.commons.text.visible(node, true).toLowerCase();
-1 9688 if (text === '') {
-1 9689 return false;
-1 9690 }
-1 9691 for (var i = 0, len = imgs.length; i < len; i++) {
-1 9692 var img = imgs[i];
-1 9693 var imgAlt = axe.commons.text.accessibleText(img).toLowerCase();
-1 9694 if (imgAlt === text && img.getAttribute('role') !== 'presentation' && axe.commons.dom.isVisible(img)) {
-1 9695 return true;
-1 9696 }
-1 9697 }
-1 9698 return false;
-1 9699 }
-1 9700 }, {
-1 9701 id: 'explicit-label',
-1 9702 evaluate: function evaluate(node, options) {
-1 9703 if (node.getAttribute('id')) {
-1 9704 var id = axe.commons.utils.escapeSelector(node.getAttribute('id'));
-1 9705 var label = document.querySelector('label[for="' + id + '"]');
-1 9706 if (label) {
-1 9707 return !!axe.commons.text.accessibleText(label);
-1 9708 }
-1 9709 }
-1 9710 return false;
-1 9711 }
-1 9712 }, {
-1 9713 id: 'help-same-as-label',
-1 9714 evaluate: function evaluate(node, options) {
-1 9715 var labelText = axe.commons.text.label(node), check = node.getAttribute('title');
-1 9716 if (!labelText) {
-1 9717 return false;
-1 9718 }
-1 9719 if (!check) {
-1 9720 check = '';
-1 9721 if (node.getAttribute('aria-describedby')) {
-1 9722 var ref = axe.commons.dom.idrefs(node, 'aria-describedby');
-1 9723 check = ref.map(function(thing) {
-1 9724 return thing ? axe.commons.text.accessibleText(thing) : '';
-1 9725 }).join('');
-1 9726 }
-1 9727 }
-1 9728 return axe.commons.text.sanitize(check) === axe.commons.text.sanitize(labelText);
-1 9729 },
-1 9730 enabled: false
-1 9731 }, {
-1 9732 id: 'implicit-label',
-1 9733 evaluate: function evaluate(node, options) {
-1 9734 var label = axe.commons.dom.findUp(node, 'label');
-1 9735 if (label) {
-1 9736 return !!axe.commons.text.accessibleText(label);
-1 9737 }
-1 9738 return false;
-1 9739 }
-1 9740 }, {
-1 9741 id: 'multiple-label',
-1 9742 evaluate: function evaluate(node, options) {
-1 9743 var id = axe.commons.utils.escapeSelector(node.getAttribute('id'));
-1 9744 var labels = Array.from(document.querySelectorAll('label[for="' + id + '"]'));
-1 9745 var parent = node.parentNode;
-1 9746 if (labels.length) {
-1 9747 labels = labels.filter(function(label, index) {
-1 9748 if (index === 0 && !axe.commons.dom.isVisible(label, true) || axe.commons.dom.isVisible(label, true)) {
-1 9749 return label;
-1 9750 }
-1 9751 });
-1 9752 }
-1 9753 while (parent) {
-1 9754 if (parent.tagName === 'LABEL' && labels.indexOf(parent) === -1) {
-1 9755 labels.push(parent);
-1 9756 }
-1 9757 parent = parent.parentNode;
-1 9758 }
-1 9759 this.relatedNodes(labels);
-1 9760 return labels.length > 1;
-1 9761 }
-1 9762 }, {
-1 9763 id: 'title-only',
-1 9764 evaluate: function evaluate(node, options) {
-1 9765 var labelText = axe.commons.text.label(node);
-1 9766 return !labelText && !!(node.getAttribute('title') || node.getAttribute('aria-describedby'));
-1 9767 }
-1 9768 }, {
-1 9769 id: 'has-lang',
-1 9770 evaluate: function evaluate(node, options) {
-1 9771 return !!(node.getAttribute('lang') || node.getAttribute('xml:lang') || '').trim();
-1 9772 }
-1 9773 }, {
-1 9774 id: 'valid-lang',
-1 9775 evaluate: function evaluate(node, options) {
-1 9776 function getBaseLang(lang) {
-1 9777 return lang.trim().split('-')[0].toLowerCase();
-1 9778 }
-1 9779 var langs, invalid;
-1 9780 langs = (options ? options : axe.commons.utils.validLangs()).map(getBaseLang);
-1 9781 invalid = [ 'lang', 'xml:lang' ].reduce(function(invalid, langAttr) {
-1 9782 var langVal = node.getAttribute(langAttr);
-1 9783 if (typeof langVal !== 'string') {
-1 9784 return invalid;
-1 9785 }
-1 9786 var baselangVal = getBaseLang(langVal);
-1 9787 if (baselangVal !== '' && langs.indexOf(baselangVal) === -1) {
-1 9788 invalid.push(langAttr + '="' + node.getAttribute(langAttr) + '"');
-1 9789 }
-1 9790 return invalid;
-1 9791 }, []);
-1 9792 if (invalid.length) {
-1 9793 this.data(invalid);
-1 9794 return true;
-1 9795 }
-1 9796 return false;
-1 9797 }
-1 9798 }, {
-1 9799 id: 'dlitem',
-1 9800 evaluate: function evaluate(node, options) {
-1 9801 return node.parentNode.tagName.toUpperCase() === 'DL';
-1 9802 }
-1 9803 }, {
-1 9804 id: 'has-listitem',
-1 9805 evaluate: function evaluate(node, options) {
-1 9806 var children = node.children;
-1 9807 if (children.length === 0) {
-1 9808 return true;
-1 9809 }
-1 9810 for (var i = 0; i < children.length; i++) {
-1 9811 if (children[i].nodeName.toUpperCase() === 'LI') {
-1 9812 return false;
-1 9813 }
-1 9814 }
-1 9815 return true;
-1 9816 }
-1 9817 }, {
-1 9818 id: 'listitem',
-1 9819 evaluate: function evaluate(node, options) {
-1 9820 if ([ 'UL', 'OL' ].indexOf(node.parentNode.nodeName.toUpperCase()) !== -1) {
-1 9821 return true;
-1 9822 }
-1 9823 return node.parentNode.getAttribute('role') === 'list';
-1 9824 }
-1 9825 }, {
-1 9826 id: 'only-dlitems',
-1 9827 evaluate: function evaluate(node, options) {
-1 9828 var child, nodeName, bad = [], children = node.childNodes, permitted = [ 'STYLE', 'META', 'LINK', 'MAP', 'AREA', 'SCRIPT', 'DATALIST', 'TEMPLATE' ], hasNonEmptyTextNode = false;
-1 9829 for (var i = 0; i < children.length; i++) {
-1 9830 child = children[i];
-1 9831 var nodeName = child.nodeName.toUpperCase();
-1 9832 if (child.nodeType === 1 && nodeName !== 'DT' && nodeName !== 'DD' && permitted.indexOf(nodeName) === -1) {
-1 9833 bad.push(child);
-1 9834 } else if (child.nodeType === 3 && child.nodeValue.trim() !== '') {
-1 9835 hasNonEmptyTextNode = true;
-1 9836 }
-1 9837 }
-1 9838 if (bad.length) {
-1 9839 this.relatedNodes(bad);
-1 9840 }
-1 9841 var retVal = !!bad.length || hasNonEmptyTextNode;
-1 9842 return retVal;
-1 9843 }
-1 9844 }, {
-1 9845 id: 'only-listitems',
-1 9846 evaluate: function evaluate(node, options) {
-1 9847 var child, nodeName, bad = [], children = node.childNodes, permitted = [ 'STYLE', 'META', 'LINK', 'MAP', 'AREA', 'SCRIPT', 'DATALIST', 'TEMPLATE' ], hasNonEmptyTextNode = false;
-1 9848 for (var i = 0; i < children.length; i++) {
-1 9849 child = children[i];
-1 9850 nodeName = child.nodeName.toUpperCase();
-1 9851 if (child.nodeType === 1 && nodeName !== 'LI' && permitted.indexOf(nodeName) === -1) {
-1 9852 bad.push(child);
-1 9853 } else if (child.nodeType === 3 && child.nodeValue.trim() !== '') {
-1 9854 hasNonEmptyTextNode = true;
-1 9855 }
-1 9856 }
-1 9857 if (bad.length) {
-1 9858 this.relatedNodes(bad);
-1 9859 }
-1 9860 return !!bad.length || hasNonEmptyTextNode;
-1 9861 }
-1 9862 }, {
-1 9863 id: 'structured-dlitems',
-1 9864 evaluate: function evaluate(node, options) {
-1 9865 var children = node.children;
-1 9866 if (!children || !children.length) {
-1 9867 return false;
-1 9868 }
-1 9869 var hasDt = false, hasDd = false, nodeName;
-1 9870 for (var i = 0; i < children.length; i++) {
-1 9871 nodeName = children[i].nodeName.toUpperCase();
-1 9872 if (nodeName === 'DT') {
-1 9873 hasDt = true;
-1 9874 }
-1 9875 if (hasDt && nodeName === 'DD') {
-1 9876 return false;
-1 9877 }
-1 9878 if (nodeName === 'DD') {
-1 9879 hasDd = true;
-1 9880 }
-1 9881 }
-1 9882 return hasDt || hasDd;
-1 9883 }
-1 9884 }, {
-1 9885 id: 'caption',
-1 9886 evaluate: function evaluate(node, options) {
-1 9887 var tracks = node.querySelectorAll('track');
-1 9888 if (tracks.length) {
-1 9889 for (var i = 0; i < tracks.length; i++) {
-1 9890 var kind = tracks[i].getAttribute('kind');
-1 9891 if (kind && kind === 'captions') {
-1 9892 return false;
-1 9893 }
-1 9894 }
-1 9895 return true;
-1 9896 }
-1 9897 return undefined;
-1 9898 }
-1 9899 }, {
-1 9900 id: 'description',
-1 9901 evaluate: function evaluate(node, options) {
-1 9902 var tracks = node.querySelectorAll('track');
-1 9903 if (tracks.length) {
-1 9904 for (var i = 0; i < tracks.length; i++) {
-1 9905 var kind = tracks[i].getAttribute('kind');
-1 9906 if (kind && kind === 'descriptions') {
-1 9907 return false;
-1 9908 }
-1 9909 }
-1 9910 return true;
-1 9911 }
-1 9912 return undefined;
-1 9913 }
-1 9914 }, {
-1 9915 id: 'meta-viewport-large',
-1 9916 evaluate: function evaluate(node, options) {
-1 9917 options = options || {};
-1 9918 var params, content = node.getAttribute('content') || '', parsedParams = content.split(/[;,]/), result = {}, minimum = options.scaleMinimum || 2, lowerBound = options.lowerBound || false;
-1 9919 for (var i = 0, l = parsedParams.length; i < l; i++) {
-1 9920 params = parsedParams[i].split('=');
-1 9921 var key = params.shift().toLowerCase();
-1 9922 if (key && params.length) {
-1 9923 result[key.trim()] = params.shift().trim().toLowerCase();
-1 9924 }
-1 9925 }
-1 9926 if (lowerBound && result['maximum-scale'] && parseFloat(result['maximum-scale']) < lowerBound) {
-1 9927 return true;
-1 9928 }
-1 9929 if (!lowerBound && result['user-scalable'] === 'no') {
-1 9930 return false;
-1 9931 }
-1 9932 if (result['maximum-scale'] && parseFloat(result['maximum-scale']) < minimum) {
-1 9933 return false;
-1 9934 }
-1 9935 return true;
-1 9936 },
-1 9937 options: {
-1 9938 scaleMinimum: 5,
-1 9939 lowerBound: 2
-1 9940 }
-1 9941 }, {
-1 9942 id: 'meta-viewport',
-1 9943 evaluate: function evaluate(node, options) {
-1 9944 options = options || {};
-1 9945 var params, content = node.getAttribute('content') || '', parsedParams = content.split(/[;,]/), result = {}, minimum = options.scaleMinimum || 2, lowerBound = options.lowerBound || false;
-1 9946 for (var i = 0, l = parsedParams.length; i < l; i++) {
-1 9947 params = parsedParams[i].split('=');
-1 9948 var key = params.shift().toLowerCase();
-1 9949 if (key && params.length) {
-1 9950 result[key.trim()] = params.shift().trim().toLowerCase();
-1 9951 }
-1 9952 }
-1 9953 if (lowerBound && result['maximum-scale'] && parseFloat(result['maximum-scale']) < lowerBound) {
-1 9954 return true;
-1 9955 }
-1 9956 if (!lowerBound && result['user-scalable'] === 'no') {
-1 9957 return false;
-1 9958 }
-1 9959 if (result['maximum-scale'] && parseFloat(result['maximum-scale']) < minimum) {
-1 9960 return false;
-1 9961 }
-1 9962 return true;
-1 9963 },
-1 9964 options: {
-1 9965 scaleMinimum: 2
-1 9966 }
-1 9967 }, {
-1 9968 id: 'header-present',
-1 9969 evaluate: function evaluate(node, options) {
-1 9970 return !!node.querySelector('h1, h2, h3, h4, h5, h6, [role="heading"]');
-1 9971 }
-1 9972 }, {
-1 9973 id: 'heading-order',
-1 9974 evaluate: function evaluate(node, options) {
-1 9975 var ariaHeadingLevel = node.getAttribute('aria-level');
-1 9976 if (ariaHeadingLevel !== null) {
-1 9977 this.data(parseInt(ariaHeadingLevel, 10));
-1 9978 return true;
-1 9979 }
-1 9980 var headingLevel = node.tagName.match(/H(\d)/);
-1 9981 if (headingLevel) {
-1 9982 this.data(parseInt(headingLevel[1], 10));
-1 9983 return true;
-1 9984 }
-1 9985 return true;
-1 9986 },
-1 9987 after: function after(results, options) {
-1 9988 if (results.length < 2) {
-1 9989 return results;
-1 9990 }
-1 9991 var prevLevel = results[0].data;
-1 9992 for (var i = 1; i < results.length; i++) {
-1 9993 if (results[i].result && results[i].data > prevLevel + 1) {
-1 9994 results[i].result = false;
-1 9995 }
-1 9996 prevLevel = results[i].data;
-1 9997 }
-1 9998 return results;
-1 9999 }
-1 10000 }, {
-1 10001 id: 'href-no-hash',
-1 10002 evaluate: function evaluate(node, options) {
-1 10003 var href = node.getAttribute('href');
-1 10004 if (href === '#') {
-1 10005 return false;
-1 10006 }
-1 10007 return true;
-1 10008 }
-1 10009 }, {
-1 10010 id: 'internal-link-present',
-1 10011 evaluate: function evaluate(node, options) {
-1 10012 return !!node.querySelector('a[href^="#"]');
-1 10013 }
-1 10014 }, {
-1 10015 id: 'landmark',
-1 10016 evaluate: function evaluate(node, options) {
-1 10017 return node.getElementsByTagName('main').length > 0 || !!node.querySelector('[role="main"]');
-1 10018 }
-1 10019 }, {
-1 10020 id: 'meta-refresh',
-1 10021 evaluate: function evaluate(node, options) {
-1 10022 var content = node.getAttribute('content') || '', parsedParams = content.split(/[;,]/);
-1 10023 return content === '' || parsedParams[0] === '0';
-1 10024 }
-1 10025 }, {
-1 10026 id: 'p-as-heading',
-1 10027 evaluate: function evaluate(node, options) {
-1 10028 var siblings = Array.from(node.parentNode.children);
-1 10029 var currentIndex = siblings.indexOf(node);
-1 10030 options = options || {};
-1 10031 var margins = options.margins || [];
-1 10032 var nextSibling = siblings.slice(currentIndex + 1).find(function(elm) {
-1 10033 return elm.nodeName.toUpperCase() === 'P';
-1 10034 });
-1 10035 var prevSibling = siblings.slice(0, currentIndex).reverse().find(function(elm) {
-1 10036 return elm.nodeName.toUpperCase() === 'P';
-1 10037 });
-1 10038 function getTextContainer(elm) {
-1 10039 var nextNode = elm;
-1 10040 var outerText = elm.textContent.trim();
-1 10041 var innerText = outerText;
-1 10042 while (innerText === outerText && nextNode !== undefined) {
-1 10043 var i = -1;
-1 10044 elm = nextNode;
-1 10045 if (elm.children.length === 0) {
-1 10046 return elm;
-1 10047 }
-1 10048 do {
-1 10049 i++;
-1 10050 innerText = elm.children[i].textContent.trim();
-1 10051 } while (innerText === '' && i + 1 < elm.children.length);
-1 10052 nextNode = elm.children[i];
-1 10053 }
-1 10054 return elm;
-1 10055 }
-1 10056 function normalizeFontWeight(weight) {
-1 10057 switch (weight) {
-1 10058 case 'lighter':
-1 10059 return 100;
-1 10060
-1 10061 case 'normal':
-1 10062 return 400;
-1 10063
-1 10064 case 'bold':
-1 10065 return 700;
-1 10066
-1 10067 case 'bolder':
-1 10068 return 900;
-1 10069 }
-1 10070 weight = parseInt(weight);
-1 10071 return !isNaN(weight) ? weight : 400;
-1 10072 }
-1 10073 function getStyleValues(node) {
-1 10074 var style = window.getComputedStyle(getTextContainer(node));
-1 10075 return {
-1 10076 fontWeight: normalizeFontWeight(style.getPropertyValue('font-weight')),
-1 10077 fontSize: parseInt(style.getPropertyValue('font-size')),
-1 10078 isItalic: style.getPropertyValue('font-style') === 'italic'
-1 10079 };
-1 10080 }
-1 10081 function isHeaderStyle(styleA, styleB, margins) {
-1 10082 return margins.reduce(function(out, margin) {
-1 10083 return out || (!margin.size || styleA.fontSize / margin.size > styleB.fontSize) && (!margin.weight || styleA.fontWeight - margin.weight > styleB.fontWeight) && (!margin.italic || styleA.isItalic && !styleB.isItalic);
-1 10084 }, false);
-1 10085 }
-1 10086 var currStyle = getStyleValues(node);
-1 10087 var nextStyle = nextSibling ? getStyleValues(nextSibling) : null;
-1 10088 var prevStyle = prevSibling ? getStyleValues(prevSibling) : null;
-1 10089 if (!nextStyle || !isHeaderStyle(currStyle, nextStyle, margins)) {
-1 10090 return true;
-1 10091 }
-1 10092 var blockquote = axe.commons.dom.findUp(node, 'blockquote');
-1 10093 if (blockquote && blockquote.nodeName.toUpperCase() === 'BLOCKQUOTE') {
-1 10094 return undefined;
-1 10095 }
-1 10096 if (prevStyle && !isHeaderStyle(currStyle, prevStyle, margins)) {
-1 10097 return undefined;
-1 10098 }
-1 10099 return false;
-1 10100 },
-1 10101 options: {
-1 10102 margins: [ {
-1 10103 weight: 150,
-1 10104 italic: true
-1 10105 }, {
-1 10106 weight: 150,
-1 10107 size: 1.15
-1 10108 }, {
-1 10109 italic: true,
-1 10110 size: 1.15
-1 10111 }, {
-1 10112 size: 1.4
-1 10113 } ]
-1 10114 }
-1 10115 }, {
-1 10116 id: 'region',
-1 10117 evaluate: function evaluate(node, options) {
-1 10118 var landmarkRoles = axe.commons.aria.getRolesByType('landmark'), firstLink = node.querySelector('a[href]');
-1 10119 var implicitLandmarks = landmarkRoles.reduce(function(arr, role) {
-1 10120 return arr.concat(axe.commons.aria.implicitNodes(role));
-1 10121 }, []).filter(function(r) {
-1 10122 return r !== null;
-1 10123 });
-1 10124 function isSkipLink(n) {
-1 10125 return firstLink && axe.commons.dom.getElementByReference(firstLink, 'href') && firstLink === n;
-1 10126 }
-1 10127 function isLandmark(node) {
-1 10128 if (node.hasAttribute('role')) {
-1 10129 return landmarkRoles.includes(node.getAttribute('role').toLowerCase());
-1 10130 } else {
-1 10131 return implicitLandmarks.some(function(implicitSelector) {
-1 10132 return axe.utils.matchesSelector(node, implicitSelector);
-1 10133 });
-1 10134 }
-1 10135 }
-1 10136 function checkRegion(n) {
-1 10137 if (isLandmark(n)) {
-1 10138 return null;
-1 10139 }
-1 10140 if (isSkipLink(n)) {
-1 10141 return getViolatingChildren(n);
-1 10142 }
-1 10143 if (axe.commons.dom.isVisible(n, true) && (axe.commons.text.visible(n, true, true) || axe.commons.dom.isVisualContent(n))) {
-1 10144 return n;
-1 10145 }
-1 10146 return getViolatingChildren(n);
-1 10147 }
-1 10148 function getViolatingChildren(n) {
-1 10149 var children = axe.commons.utils.toArray(n.children);
-1 10150 if (children.length === 0) {
-1 10151 return [];
-1 10152 }
-1 10153 return children.map(checkRegion).filter(function(c) {
-1 10154 return c !== null;
-1 10155 }).reduce(function(a, b) {
-1 10156 return a.concat(b);
-1 10157 }, []);
-1 10158 }
-1 10159 var v = getViolatingChildren(node);
-1 10160 this.relatedNodes(v);
-1 10161 return !v.length;
-1 10162 },
-1 10163 after: function after(results, options) {
-1 10164 return [ results[0] ];
-1 10165 }
-1 10166 }, {
-1 10167 id: 'skip-link',
-1 10168 evaluate: function evaluate(node, options) {
-1 10169 var target = axe.commons.dom.getElementByReference(node, 'href');
-1 10170 return !!target && axe.commons.dom.isFocusable(target);
-1 10171 },
-1 10172 after: function after(results, options) {
-1 10173 return [ results[0] ];
-1 10174 }
-1 10175 }, {
-1 10176 id: 'unique-frame-title',
-1 10177 evaluate: function evaluate(node, options) {
-1 10178 var title = axe.commons.text.sanitize(node.title).trim().toLowerCase();
-1 10179 this.data(title);
-1 10180 return true;
-1 10181 },
-1 10182 after: function after(results, options) {
-1 10183 var titles = {};
-1 10184 results.forEach(function(r) {
-1 10185 titles[r.data] = titles[r.data] !== undefined ? ++titles[r.data] : 0;
-1 10186 });
-1 10187 results.forEach(function(r) {
-1 10188 r.result = !!titles[r.data];
-1 10189 });
-1 10190 return results;
-1 10191 }
-1 10192 }, {
-1 10193 id: 'aria-label',
-1 10194 evaluate: function evaluate(node, options) {
-1 10195 var label = node.getAttribute('aria-label');
-1 10196 return !!(label ? axe.commons.text.sanitize(label).trim() : '');
-1 10197 }
-1 10198 }, {
-1 10199 id: 'aria-labelledby',
-1 10200 evaluate: function evaluate(node, options) {
-1 10201 var getIdRefs = axe.commons.dom.idrefs;
-1 10202 return getIdRefs(node, 'aria-labelledby').some(function(elm) {
-1 10203 return elm && axe.commons.text.accessibleText(elm, true);
-1 10204 });
-1 10205 }
-1 10206 }, {
-1 10207 id: 'button-has-visible-text',
-1 10208 evaluate: function evaluate(node, options) {
-1 10209 var nodeName = node.nodeName.toUpperCase();
-1 10210 var role = node.getAttribute('role');
-1 10211 var label = void 0;
-1 10212 if (nodeName === 'BUTTON' || role === 'button' && nodeName !== 'INPUT') {
-1 10213 label = axe.commons.text.accessibleText(node);
-1 10214 this.data(label);
-1 10215 return !!label;
-1 10216 } else {
-1 10217 return false;
-1 10218 }
-1 10219 }
-1 10220 }, {
-1 10221 id: 'doc-has-title',
-1 10222 evaluate: function evaluate(node, options) {
-1 10223 var title = document.title;
-1 10224 return !!(title ? axe.commons.text.sanitize(title).trim() : '');
-1 10225 }
-1 10226 }, {
-1 10227 id: 'duplicate-id',
-1 10228 evaluate: function evaluate(node, options) {
-1 10229 if (!node.getAttribute('id').trim()) {
-1 10230 return true;
-1 10231 }
-1 10232 var id = axe.commons.utils.escapeSelector(node.getAttribute('id'));
-1 10233 var matchingNodes = document.querySelectorAll('[id="' + id + '"]');
-1 10234 var related = [];
-1 10235 for (var i = 0; i < matchingNodes.length; i++) {
-1 10236 if (matchingNodes[i] !== node) {
-1 10237 related.push(matchingNodes[i]);
-1 10238 }
-1 10239 }
-1 10240 if (related.length) {
-1 10241 this.relatedNodes(related);
-1 10242 }
-1 10243 this.data(node.getAttribute('id'));
-1 10244 return matchingNodes.length <= 1;
-1 10245 },
-1 10246 after: function after(results, options) {
-1 10247 var uniqueIds = [];
-1 10248 return results.filter(function(r) {
-1 10249 if (uniqueIds.indexOf(r.data) === -1) {
-1 10250 uniqueIds.push(r.data);
-1 10251 return true;
-1 10252 }
-1 10253 return false;
-1 10254 });
-1 10255 }
-1 10256 }, {
-1 10257 id: 'exists',
-1 10258 evaluate: function evaluate(node, options) {
-1 10259 return true;
-1 10260 }
-1 10261 }, {
-1 10262 id: 'has-alt',
-1 10263 evaluate: function evaluate(node, options) {
-1 10264 var nn = node.nodeName.toLowerCase();
-1 10265 return node.hasAttribute('alt') && (nn === 'img' || nn === 'input' || nn === 'area');
-1 10266 }
-1 10267 }, {
-1 10268 id: 'has-visible-text',
-1 10269 evaluate: function evaluate(node, options) {
-1 10270 return axe.commons.text.accessibleText(node).length > 0;
-1 10271 }
-1 10272 }, {
-1 10273 id: 'is-on-screen',
-1 10274 evaluate: function evaluate(node, options) {
-1 10275 return axe.commons.dom.isVisible(node, false) && !axe.commons.dom.isOffscreen(node);
-1 10276 }
-1 10277 }, {
-1 10278 id: 'non-empty-alt',
-1 10279 evaluate: function evaluate(node, options) {
-1 10280 var label = node.getAttribute('alt');
-1 10281 return !!(label ? axe.commons.text.sanitize(label).trim() : '');
-1 10282 }
-1 10283 }, {
-1 10284 id: 'non-empty-if-present',
-1 10285 evaluate: function evaluate(node, options) {
-1 10286 var nodeName = node.nodeName.toUpperCase();
-1 10287 var type = (node.getAttribute('type') || '').toLowerCase();
-1 10288 var label = node.getAttribute('value');
-1 10289 this.data(label);
-1 10290 if (nodeName === 'INPUT' && [ 'submit', 'reset' ].indexOf(type) !== -1) {
-1 10291 return label === null;
-1 10292 }
-1 10293 return false;
-1 10294 }
-1 10295 }, {
-1 10296 id: 'non-empty-title',
-1 10297 evaluate: function evaluate(node, options) {
-1 10298 var title = node.getAttribute('title');
-1 10299 return !!(title ? axe.commons.text.sanitize(title).trim() : '');
-1 10300 }
-1 10301 }, {
-1 10302 id: 'non-empty-value',
-1 10303 evaluate: function evaluate(node, options) {
-1 10304 var label = node.getAttribute('value');
-1 10305 return !!(label ? axe.commons.text.sanitize(label).trim() : '');
-1 10306 }
-1 10307 }, {
-1 10308 id: 'role-none',
-1 10309 evaluate: function evaluate(node, options) {
-1 10310 return node.getAttribute('role') === 'none';
-1 10311 }
-1 10312 }, {
-1 10313 id: 'role-presentation',
-1 10314 evaluate: function evaluate(node, options) {
-1 10315 return node.getAttribute('role') === 'presentation';
-1 10316 }
-1 10317 }, {
-1 10318 id: 'caption-faked',
-1 10319 evaluate: function evaluate(node, options) {
-1 10320 var table = axe.commons.table.toGrid(node);
-1 10321 var firstRow = table[0];
-1 10322 if (table.length <= 1 || firstRow.length <= 1 || node.rows.length <= 1) {
-1 10323 return true;
-1 10324 }
-1 10325 return firstRow.reduce(function(out, curr, i) {
-1 10326 return out || curr !== firstRow[i + 1] && firstRow[i + 1] !== undefined;
-1 10327 }, false);
-1 10328 }
-1 10329 }, {
-1 10330 id: 'has-caption',
-1 10331 evaluate: function evaluate(node, options) {
-1 10332 return !!node.caption;
-1 10333 }
-1 10334 }, {
-1 10335 id: 'has-summary',
-1 10336 evaluate: function evaluate(node, options) {
-1 10337 return !!node.summary;
-1 10338 }
-1 10339 }, {
-1 10340 id: 'has-th',
-1 10341 evaluate: function evaluate(node, options) {
-1 10342 var row, cell, badCells = [];
-1 10343 for (var rowIndex = 0, rowLength = node.rows.length; rowIndex < rowLength; rowIndex++) {
-1 10344 row = node.rows[rowIndex];
-1 10345 for (var cellIndex = 0, cellLength = row.cells.length; cellIndex < cellLength; cellIndex++) {
-1 10346 cell = row.cells[cellIndex];
-1 10347 if (cell.nodeName.toUpperCase() === 'TH' || [ 'rowheader', 'columnheader' ].indexOf(cell.getAttribute('role')) !== -1) {
-1 10348 badCells.push(cell);
-1 10349 }
-1 10350 }
-1 10351 }
-1 10352 if (badCells.length) {
-1 10353 this.relatedNodes(badCells);
-1 10354 return true;
-1 10355 }
-1 10356 return false;
-1 10357 }
-1 10358 }, {
-1 10359 id: 'html5-scope',
-1 10360 evaluate: function evaluate(node, options) {
-1 10361 if (!axe.commons.dom.isHTML5(document)) {
-1 10362 return true;
-1 10363 }
-1 10364 return node.nodeName.toUpperCase() === 'TH';
-1 10365 }
-1 10366 }, {
-1 10367 id: 'same-caption-summary',
-1 10368 evaluate: function evaluate(node, options) {
-1 10369 return !!(node.summary && node.caption) && node.summary === axe.commons.text.accessibleText(node.caption);
-1 10370 }
-1 10371 }, {
-1 10372 id: 'scope-value',
-1 10373 evaluate: function evaluate(node, options) {
-1 10374 options = options || {};
-1 10375 var value = node.getAttribute('scope').toLowerCase();
-1 10376 var validVals = [ 'row', 'col', 'rowgroup', 'colgroup' ] || options.values;
-1 10377 return validVals.indexOf(value) !== -1;
-1 10378 }
-1 10379 }, {
-1 10380 id: 'td-has-header',
-1 10381 evaluate: function evaluate(node, options) {
-1 10382 var tableUtils = axe.commons.table;
-1 10383 var badCells = [];
-1 10384 var cells = tableUtils.getAllCells(node);
-1 10385 cells.forEach(function(cell) {
-1 10386 if (axe.commons.dom.hasContent(cell) && tableUtils.isDataCell(cell) && !axe.commons.aria.label(cell)) {
-1 10387 var hasHeaders = tableUtils.getHeaders(cell);
-1 10388 hasHeaders = hasHeaders.reduce(function(hasHeaders, header) {
-1 10389 return hasHeaders || header !== null && !!axe.commons.dom.hasContent(header);
-1 10390 }, false);
-1 10391 if (!hasHeaders) {
-1 10392 badCells.push(cell);
-1 10393 }
-1 10394 }
-1 10395 });
-1 10396 if (badCells.length) {
-1 10397 this.relatedNodes(badCells);
-1 10398 return false;
-1 10399 }
-1 10400 return true;
-1 10401 }
-1 10402 }, {
-1 10403 id: 'td-headers-attr',
-1 10404 evaluate: function evaluate(node, options) {
-1 10405 var cells = [];
-1 10406 for (var rowIndex = 0, rowLength = node.rows.length; rowIndex < rowLength; rowIndex++) {
-1 10407 var row = node.rows[rowIndex];
-1 10408 for (var cellIndex = 0, cellLength = row.cells.length; cellIndex < cellLength; cellIndex++) {
-1 10409 cells.push(row.cells[cellIndex]);
-1 10410 }
-1 10411 }
-1 10412 var ids = cells.reduce(function(ids, cell) {
-1 10413 if (cell.getAttribute('id')) {
-1 10414 ids.push(cell.getAttribute('id'));
-1 10415 }
-1 10416 return ids;
-1 10417 }, []);
-1 10418 var badCells = cells.reduce(function(badCells, cell) {
-1 10419 var isSelf, notOfTable;
-1 10420 var headers = (cell.getAttribute('headers') || '').split(/\s/).reduce(function(headers, header) {
-1 10421 header = header.trim();
-1 10422 if (header) {
-1 10423 headers.push(header);
-1 10424 }
-1 10425 return headers;
-1 10426 }, []);
-1 10427 if (headers.length !== 0) {
-1 10428 if (cell.getAttribute('id')) {
-1 10429 isSelf = headers.indexOf(cell.getAttribute('id').trim()) !== -1;
-1 10430 }
-1 10431 notOfTable = headers.reduce(function(fail, header) {
-1 10432 return fail || ids.indexOf(header) === -1;
-1 10433 }, false);
-1 10434 if (isSelf || notOfTable) {
-1 10435 badCells.push(cell);
-1 10436 }
-1 10437 }
-1 10438 return badCells;
-1 10439 }, []);
-1 10440 if (badCells.length > 0) {
-1 10441 this.relatedNodes(badCells);
-1 10442 return false;
-1 10443 } else {
-1 10444 return true;
-1 10445 }
-1 10446 }
-1 10447 }, {
-1 10448 id: 'th-has-data-cells',
-1 10449 evaluate: function evaluate(node, options) {
-1 10450 var tableUtils = axe.commons.table;
-1 10451 var cells = tableUtils.getAllCells(node);
-1 10452 var checkResult = this;
-1 10453 var reffedHeaders = [];
-1 10454 cells.forEach(function(cell) {
-1 10455 var headers = cell.getAttribute('headers');
-1 10456 if (headers) {
-1 10457 reffedHeaders = reffedHeaders.concat(headers.split(/\s+/));
-1 10458 }
-1 10459 var ariaLabel = cell.getAttribute('aria-labelledby');
-1 10460 if (ariaLabel) {
-1 10461 reffedHeaders = reffedHeaders.concat(ariaLabel.split(/\s+/));
-1 10462 }
-1 10463 });
-1 10464 var headers = cells.filter(function(cell) {
-1 10465 if (axe.commons.text.sanitize(cell.textContent) === '') {
-1 10466 return false;
-1 10467 }
-1 10468 return cell.nodeName.toUpperCase() === 'TH' || [ 'rowheader', 'columnheader' ].indexOf(cell.getAttribute('role')) !== -1;
-1 10469 });
-1 10470 var tableGrid = tableUtils.toGrid(node);
-1 10471 var out = headers.reduce(function(res, header) {
-1 10472 if (header.getAttribute('id') && reffedHeaders.includes(header.getAttribute('id'))) {
-1 10473 return !res ? res : true;
-1 10474 }
-1 10475 var hasCell = false;
-1 10476 var pos = tableUtils.getCellPosition(header, tableGrid);
-1 10477 if (tableUtils.isColumnHeader(header)) {
-1 10478 hasCell = tableUtils.traverse('down', pos, tableGrid).reduce(function(out, cell) {
-1 10479 return out || axe.commons.dom.hasContent(cell) && !tableUtils.isColumnHeader(cell);
-1 10480 }, false);
-1 10481 }
-1 10482 if (!hasCell && tableUtils.isRowHeader(header)) {
-1 10483 hasCell = tableUtils.traverse('right', pos, tableGrid).reduce(function(out, cell) {
-1 10484 return out || axe.commons.dom.hasContent(cell) && !tableUtils.isRowHeader(cell);
-1 10485 }, false);
-1 10486 }
-1 10487 if (!hasCell) {
-1 10488 checkResult.relatedNodes(header);
-1 10489 }
-1 10490 return res && hasCell;
-1 10491 }, true);
-1 10492 return out ? true : undefined;
-1 10493 }
-1 10494 }, {
-1 10495 id: 'hidden-content',
-1 10496 evaluate: function evaluate(node, options) {
-1 10497 var styles = window.getComputedStyle(node);
-1 10498 var whitelist = [ 'SCRIPT', 'HEAD', 'TITLE', 'NOSCRIPT', 'STYLE', 'TEMPLATE' ];
-1 10499 if (!whitelist.includes(node.tagName.toUpperCase()) && axe.commons.dom.hasContent(node)) {
-1 10500 if (styles.getPropertyValue('display') === 'none') {
-1 10501 return undefined;
-1 10502 } else if (styles.getPropertyValue('visibility') === 'hidden') {
-1 10503 if (node.parentNode) {
-1 10504 var parentStyle = window.getComputedStyle(node.parentNode);
-1 10505 }
-1 10506 if (!parentStyle || parentStyle.getPropertyValue('visibility') !== 'hidden') {
-1 10507 return undefined;
-1 10508 }
-1 10509 }
-1 10510 }
-1 10511 return true;
-1 10512 }
-1 10513 } ],
-1 10514 commons: function() {
-1 10515 var commons = {};
-1 10516 var aria = commons.aria = {}, lookupTable = aria.lookupTable = {};
-1 10517 lookupTable.attributes = {
-1 10518 'aria-activedescendant': {
-1 10519 type: 'idref'
-1 10520 },
-1 10521 'aria-atomic': {
-1 10522 type: 'boolean',
-1 10523 values: [ 'true', 'false' ]
-1 10524 },
-1 10525 'aria-autocomplete': {
-1 10526 type: 'nmtoken',
-1 10527 values: [ 'inline', 'list', 'both', 'none' ]
-1 10528 },
-1 10529 'aria-busy': {
-1 10530 type: 'boolean',
-1 10531 values: [ 'true', 'false' ]
-1 10532 },
-1 10533 'aria-checked': {
-1 10534 type: 'nmtoken',
-1 10535 values: [ 'true', 'false', 'mixed', 'undefined' ]
-1 10536 },
-1 10537 'aria-colcount': {
-1 10538 type: 'int'
-1 10539 },
-1 10540 'aria-colindex': {
-1 10541 type: 'int'
-1 10542 },
-1 10543 'aria-colspan': {
-1 10544 type: 'int'
-1 10545 },
-1 10546 'aria-controls': {
-1 10547 type: 'idrefs'
-1 10548 },
-1 10549 'aria-current': {
-1 10550 type: 'nmtoken',
-1 10551 values: [ 'page', 'step', 'location', 'date', 'time', 'true', 'false' ]
-1 10552 },
-1 10553 'aria-describedby': {
-1 10554 type: 'idrefs'
-1 10555 },
-1 10556 'aria-disabled': {
-1 10557 type: 'boolean',
-1 10558 values: [ 'true', 'false' ]
-1 10559 },
-1 10560 'aria-dropeffect': {
-1 10561 type: 'nmtokens',
-1 10562 values: [ 'copy', 'move', 'reference', 'execute', 'popup', 'none' ]
-1 10563 },
-1 10564 'aria-errormessage': {
-1 10565 type: 'idref'
-1 10566 },
-1 10567 'aria-expanded': {
-1 10568 type: 'nmtoken',
-1 10569 values: [ 'true', 'false', 'undefined' ]
-1 10570 },
-1 10571 'aria-flowto': {
-1 10572 type: 'idrefs'
-1 10573 },
-1 10574 'aria-grabbed': {
-1 10575 type: 'nmtoken',
-1 10576 values: [ 'true', 'false', 'undefined' ]
-1 10577 },
-1 10578 'aria-haspopup': {
-1 10579 type: 'nmtoken',
-1 10580 values: [ 'true', 'false', 'menu', 'listbox', 'tree', 'grid', 'dialog' ]
-1 10581 },
-1 10582 'aria-hidden': {
-1 10583 type: 'boolean',
-1 10584 values: [ 'true', 'false' ]
-1 10585 },
-1 10586 'aria-invalid': {
-1 10587 type: 'nmtoken',
-1 10588 values: [ 'true', 'false', 'spelling', 'grammar' ]
-1 10589 },
-1 10590 'aria-keyshortcuts': {
-1 10591 type: 'string'
-1 10592 },
-1 10593 'aria-label': {
-1 10594 type: 'string'
-1 10595 },
-1 10596 'aria-labelledby': {
-1 10597 type: 'idrefs'
-1 10598 },
-1 10599 'aria-level': {
-1 10600 type: 'int'
-1 10601 },
-1 10602 'aria-live': {
-1 10603 type: 'nmtoken',
-1 10604 values: [ 'off', 'polite', 'assertive' ]
-1 10605 },
-1 10606 'aria-modal': {
-1 10607 type: 'boolean',
-1 10608 values: [ 'true', 'false' ]
-1 10609 },
-1 10610 'aria-multiline': {
-1 10611 type: 'boolean',
-1 10612 values: [ 'true', 'false' ]
-1 10613 },
-1 10614 'aria-multiselectable': {
-1 10615 type: 'boolean',
-1 10616 values: [ 'true', 'false' ]
-1 10617 },
-1 10618 'aria-orientation': {
-1 10619 type: 'nmtoken',
-1 10620 values: [ 'horizontal', 'vertical' ]
-1 10621 },
-1 10622 'aria-owns': {
-1 10623 type: 'idrefs'
-1 10624 },
-1 10625 'aria-placeholder': {
-1 10626 type: 'string'
-1 10627 },
-1 10628 'aria-posinset': {
-1 10629 type: 'int'
-1 10630 },
-1 10631 'aria-pressed': {
-1 10632 type: 'nmtoken',
-1 10633 values: [ 'true', 'false', 'mixed', 'undefined' ]
-1 10634 },
-1 10635 'aria-readonly': {
-1 10636 type: 'boolean',
-1 10637 values: [ 'true', 'false' ]
-1 10638 },
-1 10639 'aria-relevant': {
-1 10640 type: 'nmtokens',
-1 10641 values: [ 'additions', 'removals', 'text', 'all' ]
-1 10642 },
-1 10643 'aria-required': {
-1 10644 type: 'boolean',
-1 10645 values: [ 'true', 'false' ]
-1 10646 },
-1 10647 'aria-rowcount': {
-1 10648 type: 'int'
-1 10649 },
-1 10650 'aria-rowindex': {
-1 10651 type: 'int'
-1 10652 },
-1 10653 'aria-rowspan': {
-1 10654 type: 'int'
-1 10655 },
-1 10656 'aria-selected': {
-1 10657 type: 'nmtoken',
-1 10658 values: [ 'true', 'false', 'undefined' ]
-1 10659 },
-1 10660 'aria-setsize': {
-1 10661 type: 'int'
-1 10662 },
-1 10663 'aria-sort': {
-1 10664 type: 'nmtoken',
-1 10665 values: [ 'ascending', 'descending', 'other', 'none' ]
-1 10666 },
-1 10667 'aria-valuemax': {
-1 10668 type: 'decimal'
-1 10669 },
-1 10670 'aria-valuemin': {
-1 10671 type: 'decimal'
-1 10672 },
-1 10673 'aria-valuenow': {
-1 10674 type: 'decimal'
-1 10675 },
-1 10676 'aria-valuetext': {
-1 10677 type: 'string'
-1 10678 }
-1 10679 };
-1 10680 lookupTable.globalAttributes = [ 'aria-atomic', 'aria-busy', 'aria-controls', 'aria-current', 'aria-describedby', 'aria-disabled', 'aria-dropeffect', 'aria-flowto', 'aria-grabbed', 'aria-haspopup', 'aria-hidden', 'aria-invalid', 'aria-keyshortcuts', 'aria-label', 'aria-labelledby', 'aria-live', 'aria-owns', 'aria-relevant' ];
-1 10681 lookupTable.role = {
-1 10682 alert: {
-1 10683 type: 'widget',
-1 10684 attributes: {
-1 10685 allowed: [ 'aria-expanded' ]
-1 10686 },
-1 10687 owned: null,
-1 10688 nameFrom: [ 'author' ],
-1 10689 context: null
-1 10690 },
-1 10691 alertdialog: {
-1 10692 type: 'widget',
-1 10693 attributes: {
-1 10694 allowed: [ 'aria-expanded', 'aria-modal' ]
-1 10695 },
-1 10696 owned: null,
-1 10697 nameFrom: [ 'author' ],
-1 10698 context: null
-1 10699 },
-1 10700 application: {
-1 10701 type: 'landmark',
-1 10702 attributes: {
-1 10703 allowed: [ 'aria-expanded' ]
-1 10704 },
-1 10705 owned: null,
-1 10706 nameFrom: [ 'author' ],
-1 10707 context: null
-1 10708 },
-1 10709 article: {
-1 10710 type: 'structure',
-1 10711 attributes: {
-1 10712 allowed: [ 'aria-expanded', 'aria-posinset', 'aria-setsize' ]
-1 10713 },
-1 10714 owned: null,
-1 10715 nameFrom: [ 'author' ],
-1 10716 context: null,
-1 10717 implicit: [ 'article' ]
-1 10718 },
-1 10719 banner: {
-1 10720 type: 'landmark',
-1 10721 attributes: {
-1 10722 allowed: [ 'aria-expanded' ]
-1 10723 },
-1 10724 owned: null,
-1 10725 nameFrom: [ 'author' ],
-1 10726 context: null,
-1 10727 implicit: [ 'header' ]
-1 10728 },
-1 10729 button: {
-1 10730 type: 'widget',
-1 10731 attributes: {
-1 10732 allowed: [ 'aria-expanded', 'aria-pressed' ]
-1 10733 },
-1 10734 owned: null,
-1 10735 nameFrom: [ 'author', 'contents' ],
-1 10736 context: null,
-1 10737 implicit: [ 'button', 'input[type="button"]', 'input[type="image"]', 'input[type="reset"]', 'input[type="submit"]', 'summary' ]
-1 10738 },
-1 10739 cell: {
-1 10740 type: 'structure',
-1 10741 attributes: {
-1 10742 allowed: [ 'aria-colindex', 'aria-colspan', 'aria-rowindex', 'aria-rowspan' ]
-1 10743 },
-1 10744 owned: null,
-1 10745 nameFrom: [ 'author', 'contents' ],
-1 10746 context: [ 'row' ],
-1 10747 implicit: [ 'td', 'th' ]
-1 10748 },
-1 10749 checkbox: {
-1 10750 type: 'widget',
-1 10751 attributes: {
-1 10752 allowed: [ 'aria-checked', 'aria-required' ]
-1 10753 },
-1 10754 owned: null,
-1 10755 nameFrom: [ 'author', 'contents' ],
-1 10756 context: null,
-1 10757 implicit: [ 'input[type="checkbox"]' ]
-1 10758 },
-1 10759 columnheader: {
-1 10760 type: 'structure',
-1 10761 attributes: {
-1 10762 allowed: [ 'aria-colindex', 'aria-colspan', 'aria-expanded', 'aria-rowindex', 'aria-rowspan', 'aria-required', 'aria-readonly', 'aria-selected', 'aria-sort' ]
-1 10763 },
-1 10764 owned: null,
-1 10765 nameFrom: [ 'author', 'contents' ],
-1 10766 context: [ 'row' ],
-1 10767 implicit: [ 'th' ]
-1 10768 },
-1 10769 combobox: {
-1 10770 type: 'composite',
-1 10771 attributes: {
-1 10772 allowed: [ 'aria-expanded', 'aria-autocomplete', 'aria-required', 'aria-activedescendant', 'aria-orientation' ]
-1 10773 },
-1 10774 owned: {
-1 10775 all: [ 'listbox', 'textbox' ]
-1 10776 },
-1 10777 nameFrom: [ 'author' ],
-1 10778 context: null
-1 10779 },
-1 10780 command: {
-1 10781 nameFrom: [ 'author' ],
-1 10782 type: 'abstract'
-1 10783 },
-1 10784 complementary: {
-1 10785 type: 'landmark',
-1 10786 attributes: {
-1 10787 allowed: [ 'aria-expanded' ]
-1 10788 },
-1 10789 owned: null,
-1 10790 nameFrom: [ 'author' ],
-1 10791 context: null,
-1 10792 implicit: [ 'aside' ]
-1 10793 },
-1 10794 composite: {
-1 10795 nameFrom: [ 'author' ],
-1 10796 type: 'abstract'
-1 10797 },
-1 10798 contentinfo: {
-1 10799 type: 'landmark',
-1 10800 attributes: {
-1 10801 allowed: [ 'aria-expanded' ]
-1 10802 },
-1 10803 owned: null,
-1 10804 nameFrom: [ 'author' ],
-1 10805 context: null,
-1 10806 implicit: [ 'footer' ]
-1 10807 },
-1 10808 definition: {
-1 10809 type: 'structure',
-1 10810 attributes: {
-1 10811 allowed: [ 'aria-expanded' ]
-1 10812 },
-1 10813 owned: null,
-1 10814 nameFrom: [ 'author' ],
-1 10815 context: null,
-1 10816 implicit: [ 'dd', 'dfn' ]
-1 10817 },
-1 10818 dialog: {
-1 10819 type: 'widget',
-1 10820 attributes: {
-1 10821 allowed: [ 'aria-expanded', 'aria-modal' ]
-1 10822 },
-1 10823 owned: null,
-1 10824 nameFrom: [ 'author' ],
-1 10825 context: null,
-1 10826 implicit: [ 'dialog' ]
-1 10827 },
-1 10828 directory: {
-1 10829 type: 'structure',
-1 10830 attributes: {
-1 10831 allowed: [ 'aria-expanded' ]
-1 10832 },
-1 10833 owned: null,
-1 10834 nameFrom: [ 'author', 'contents' ],
-1 10835 context: null
-1 10836 },
-1 10837 document: {
-1 10838 type: 'structure',
-1 10839 attributes: {
-1 10840 allowed: [ 'aria-expanded' ]
-1 10841 },
-1 10842 owned: null,
-1 10843 nameFrom: [ 'author' ],
-1 10844 context: null,
-1 10845 implicit: [ 'body' ]
-1 10846 },
-1 10847 feed: {
-1 10848 type: 'structure',
-1 10849 attributes: {
-1 10850 allowed: [ 'aria-expanded' ]
-1 10851 },
-1 10852 owned: {
-1 10853 one: [ 'article' ]
-1 10854 },
-1 10855 nameFrom: [ 'author' ],
-1 10856 context: null
-1 10857 },
-1 10858 form: {
-1 10859 type: 'landmark',
-1 10860 attributes: {
-1 10861 allowed: [ 'aria-expanded' ]
-1 10862 },
-1 10863 owned: null,
-1 10864 nameFrom: [ 'author' ],
-1 10865 context: null,
-1 10866 implicit: [ 'form' ]
-1 10867 },
-1 10868 grid: {
-1 10869 type: 'composite',
-1 10870 attributes: {
-1 10871 allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-colcount', 'aria-level', 'aria-multiselectable', 'aria-readonly', 'aria-rowcount' ]
-1 10872 },
-1 10873 owned: {
-1 10874 one: [ 'rowgroup', 'row' ]
-1 10875 },
-1 10876 nameFrom: [ 'author' ],
-1 10877 context: null,
-1 10878 implicit: [ 'table' ]
-1 10879 },
-1 10880 gridcell: {
-1 10881 type: 'widget',
-1 10882 attributes: {
-1 10883 allowed: [ 'aria-colindex', 'aria-colspan', 'aria-expanded', 'aria-rowindex', 'aria-rowspan', 'aria-selected', 'aria-readonly', 'aria-required' ]
-1 10884 },
-1 10885 owned: null,
-1 10886 nameFrom: [ 'author', 'contents' ],
-1 10887 context: [ 'row' ],
-1 10888 implicit: [ 'td', 'th' ]
-1 10889 },
-1 10890 group: {
-1 10891 type: 'structure',
-1 10892 attributes: {
-1 10893 allowed: [ 'aria-activedescendant', 'aria-expanded' ]
-1 10894 },
-1 10895 owned: null,
-1 10896 nameFrom: [ 'author' ],
-1 10897 context: null,
-1 10898 implicit: [ 'details', 'optgroup' ]
-1 10899 },
-1 10900 heading: {
-1 10901 type: 'structure',
-1 10902 attributes: {
-1 10903 allowed: [ 'aria-level', 'aria-expanded' ]
-1 10904 },
-1 10905 owned: null,
-1 10906 nameFrom: [ 'author', 'contents' ],
-1 10907 context: null,
-1 10908 implicit: [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ]
-1 10909 },
-1 10910 img: {
-1 10911 type: 'structure',
-1 10912 attributes: {
-1 10913 allowed: [ 'aria-expanded' ]
-1 10914 },
-1 10915 owned: null,
-1 10916 nameFrom: [ 'author' ],
-1 10917 context: null,
-1 10918 implicit: [ 'img' ]
-1 10919 },
-1 10920 input: {
-1 10921 nameFrom: [ 'author' ],
-1 10922 type: 'abstract'
-1 10923 },
-1 10924 landmark: {
-1 10925 nameFrom: [ 'author' ],
-1 10926 type: 'abstract'
-1 10927 },
-1 10928 link: {
-1 10929 type: 'widget',
-1 10930 attributes: {
-1 10931 allowed: [ 'aria-expanded' ]
-1 10932 },
-1 10933 owned: null,
-1 10934 nameFrom: [ 'author', 'contents' ],
-1 10935 context: null,
-1 10936 implicit: [ 'a[href]' ]
-1 10937 },
-1 10938 list: {
-1 10939 type: 'structure',
-1 10940 attributes: {
-1 10941 allowed: [ 'aria-expanded' ]
-1 10942 },
-1 10943 owned: {
-1 10944 all: [ 'listitem' ]
-1 10945 },
-1 10946 nameFrom: [ 'author' ],
-1 10947 context: null,
-1 10948 implicit: [ 'ol', 'ul', 'dl' ]
-1 10949 },
-1 10950 listbox: {
-1 10951 type: 'composite',
-1 10952 attributes: {
-1 10953 allowed: [ 'aria-activedescendant', 'aria-multiselectable', 'aria-required', 'aria-expanded', 'aria-orientation' ]
-1 10954 },
-1 10955 owned: {
-1 10956 all: [ 'option' ]
-1 10957 },
-1 10958 nameFrom: [ 'author' ],
-1 10959 context: null,
-1 10960 implicit: [ 'select' ]
-1 10961 },
-1 10962 listitem: {
-1 10963 type: 'structure',
-1 10964 attributes: {
-1 10965 allowed: [ 'aria-level', 'aria-posinset', 'aria-setsize', 'aria-expanded' ]
-1 10966 },
-1 10967 owned: null,
-1 10968 nameFrom: [ 'author', 'contents' ],
-1 10969 context: [ 'list' ],
-1 10970 implicit: [ 'li', 'dt' ]
-1 10971 },
-1 10972 log: {
-1 10973 type: 'widget',
-1 10974 attributes: {
-1 10975 allowed: [ 'aria-expanded' ]
-1 10976 },
-1 10977 owned: null,
-1 10978 nameFrom: [ 'author' ],
-1 10979 context: null
-1 10980 },
-1 10981 main: {
-1 10982 type: 'landmark',
-1 10983 attributes: {
-1 10984 allowed: [ 'aria-expanded' ]
-1 10985 },
-1 10986 owned: null,
-1 10987 nameFrom: [ 'author' ],
-1 10988 context: null,
-1 10989 implicit: [ 'main' ]
-1 10990 },
-1 10991 marquee: {
-1 10992 type: 'widget',
-1 10993 attributes: {
-1 10994 allowed: [ 'aria-expanded' ]
-1 10995 },
-1 10996 owned: null,
-1 10997 nameFrom: [ 'author' ],
-1 10998 context: null
-1 10999 },
-1 11000 math: {
-1 11001 type: 'structure',
-1 11002 attributes: {
-1 11003 allowed: [ 'aria-expanded' ]
-1 11004 },
-1 11005 owned: null,
-1 11006 nameFrom: [ 'author' ],
-1 11007 context: null,
-1 11008 implicit: [ 'math' ]
-1 11009 },
-1 11010 menu: {
-1 11011 type: 'composite',
-1 11012 attributes: {
-1 11013 allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-orientation' ]
-1 11014 },
-1 11015 owned: {
-1 11016 one: [ 'menuitem', 'menuitemradio', 'menuitemcheckbox' ]
-1 11017 },
-1 11018 nameFrom: [ 'author' ],
-1 11019 context: null,
-1 11020 implicit: [ 'menu[type="context"]' ]
-1 11021 },
-1 11022 menubar: {
-1 11023 type: 'composite',
-1 11024 attributes: {
-1 11025 allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-orientation' ]
-1 11026 },
-1 11027 owned: null,
-1 11028 nameFrom: [ 'author' ],
-1 11029 context: null
-1 11030 },
-1 11031 menuitem: {
-1 11032 type: 'widget',
-1 11033 attributes: {
-1 11034 allowed: [ 'aria-posinset', 'aria-setsize', 'aria-expanded' ]
-1 11035 },
-1 11036 owned: null,
-1 11037 nameFrom: [ 'author', 'contents' ],
-1 11038 context: [ 'menu', 'menubar' ],
-1 11039 implicit: [ 'menuitem[type="command"]' ]
-1 11040 },
-1 11041 menuitemcheckbox: {
-1 11042 type: 'widget',
-1 11043 attributes: {
-1 11044 allowed: [ 'aria-checked', 'aria-posinset', 'aria-setsize' ]
-1 11045 },
-1 11046 owned: null,
-1 11047 nameFrom: [ 'author', 'contents' ],
-1 11048 context: [ 'menu', 'menubar' ],
-1 11049 implicit: [ 'menuitem[type="checkbox"]' ]
-1 11050 },
-1 11051 menuitemradio: {
-1 11052 type: 'widget',
-1 11053 attributes: {
-1 11054 allowed: [ 'aria-checked', 'aria-selected', 'aria-posinset', 'aria-setsize' ]
-1 11055 },
-1 11056 owned: null,
-1 11057 nameFrom: [ 'author', 'contents' ],
-1 11058 context: [ 'menu', 'menubar' ],
-1 11059 implicit: [ 'menuitem[type="radio"]' ]
-1 11060 },
-1 11061 navigation: {
-1 11062 type: 'landmark',
-1 11063 attributes: {
-1 11064 allowed: [ 'aria-expanded' ]
-1 11065 },
-1 11066 owned: null,
-1 11067 nameFrom: [ 'author' ],
-1 11068 context: null,
-1 11069 implicit: [ 'nav' ]
-1 11070 },
-1 11071 none: {
-1 11072 type: 'structure',
-1 11073 attributes: null,
-1 11074 owned: null,
-1 11075 nameFrom: [ 'author' ],
-1 11076 context: null
-1 11077 },
-1 11078 note: {
-1 11079 type: 'structure',
-1 11080 attributes: {
-1 11081 allowed: [ 'aria-expanded' ]
-1 11082 },
-1 11083 owned: null,
-1 11084 nameFrom: [ 'author' ],
-1 11085 context: null
-1 11086 },
-1 11087 option: {
-1 11088 type: 'widget',
-1 11089 attributes: {
-1 11090 allowed: [ 'aria-selected', 'aria-posinset', 'aria-setsize', 'aria-checked' ]
-1 11091 },
-1 11092 owned: null,
-1 11093 nameFrom: [ 'author', 'contents' ],
-1 11094 context: [ 'listbox' ],
-1 11095 implicit: [ 'option' ]
-1 11096 },
-1 11097 presentation: {
-1 11098 type: 'structure',
-1 11099 attributes: null,
-1 11100 owned: null,
-1 11101 nameFrom: [ 'author' ],
-1 11102 context: null
-1 11103 },
-1 11104 progressbar: {
-1 11105 type: 'widget',
-1 11106 attributes: {
-1 11107 allowed: [ 'aria-valuetext', 'aria-valuenow', 'aria-valuemax', 'aria-valuemin' ]
-1 11108 },
-1 11109 owned: null,
-1 11110 nameFrom: [ 'author' ],
-1 11111 context: null,
-1 11112 implicit: [ 'progress' ]
-1 11113 },
-1 11114 radio: {
-1 11115 type: 'widget',
-1 11116 attributes: {
-1 11117 allowed: [ 'aria-checked', 'aria-selected', 'aria-posinset', 'aria-setsize', 'aria-required' ]
-1 11118 },
-1 11119 owned: null,
-1 11120 nameFrom: [ 'author', 'contents' ],
-1 11121 context: null,
-1 11122 implicit: [ 'input[type="radio"]' ]
-1 11123 },
-1 11124 radiogroup: {
-1 11125 type: 'composite',
-1 11126 attributes: {
-1 11127 allowed: [ 'aria-activedescendant', 'aria-required', 'aria-expanded' ]
-1 11128 },
-1 11129 owned: {
-1 11130 all: [ 'radio' ]
-1 11131 },
-1 11132 nameFrom: [ 'author' ],
-1 11133 context: null
-1 11134 },
-1 11135 range: {
-1 11136 nameFrom: [ 'author' ],
-1 11137 type: 'abstract'
-1 11138 },
-1 11139 region: {
-1 11140 type: 'landmark',
-1 11141 attributes: {
-1 11142 allowed: [ 'aria-expanded' ]
-1 11143 },
-1 11144 owned: null,
-1 11145 nameFrom: [ 'author' ],
-1 11146 context: null,
-1 11147 implicit: [ 'section[aria-label]', 'section[aria-labelledby]', 'section[title]' ]
-1 11148 },
-1 11149 roletype: {
-1 11150 type: 'abstract'
-1 11151 },
-1 11152 row: {
-1 11153 type: 'structure',
-1 11154 attributes: {
-1 11155 allowed: [ 'aria-activedescendant', 'aria-colindex', 'aria-expanded', 'aria-level', 'aria-selected', 'aria-rowindex' ]
-1 11156 },
-1 11157 owned: {
-1 11158 one: [ 'cell', 'columnheader', 'rowheader', 'gridcell' ]
-1 11159 },
-1 11160 nameFrom: [ 'author', 'contents' ],
-1 11161 context: [ 'rowgroup', 'grid', 'treegrid', 'table' ],
-1 11162 implicit: [ 'tr' ]
-1 11163 },
-1 11164 rowgroup: {
-1 11165 type: 'structure',
-1 11166 attributes: {
-1 11167 allowed: [ 'aria-activedescendant', 'aria-expanded' ]
-1 11168 },
-1 11169 owned: {
-1 11170 all: [ 'row' ]
-1 11171 },
-1 11172 nameFrom: [ 'author', 'contents' ],
-1 11173 context: [ 'grid', 'table' ],
-1 11174 implicit: [ 'tbody', 'thead', 'tfoot' ]
-1 11175 },
-1 11176 rowheader: {
-1 11177 type: 'structure',
-1 11178 attributes: {
-1 11179 allowed: [ 'aria-colindex', 'aria-colspan', 'aria-expanded', 'aria-rowindex', 'aria-rowspan', 'aria-required', 'aria-readonly', 'aria-selected', 'aria-sort' ]
-1 11180 },
-1 11181 owned: null,
-1 11182 nameFrom: [ 'author', 'contents' ],
-1 11183 context: [ 'row' ],
-1 11184 implicit: [ 'th' ]
-1 11185 },
-1 11186 scrollbar: {
-1 11187 type: 'widget',
-1 11188 attributes: {
-1 11189 required: [ 'aria-controls', 'aria-valuenow', 'aria-valuemax', 'aria-valuemin' ],
-1 11190 allowed: [ 'aria-valuetext', 'aria-orientation' ]
-1 11191 },
-1 11192 owned: null,
-1 11193 nameFrom: [ 'author' ],
-1 11194 context: null
-1 11195 },
-1 11196 search: {
-1 11197 type: 'landmark',
-1 11198 attributes: {
-1 11199 allowed: [ 'aria-expanded' ]
-1 11200 },
-1 11201 owned: null,
-1 11202 nameFrom: [ 'author' ],
-1 11203 context: null
-1 11204 },
-1 11205 searchbox: {
-1 11206 type: 'widget',
-1 11207 attributes: {
-1 11208 allowed: [ 'aria-activedescendant', 'aria-autocomplete', 'aria-multiline', 'aria-readonly', 'aria-required', 'aria-placeholder' ]
-1 11209 },
-1 11210 owned: null,
-1 11211 nameFrom: [ 'author' ],
-1 11212 context: null,
-1 11213 implicit: [ 'input[type="search"]' ]
-1 11214 },
-1 11215 section: {
-1 11216 nameFrom: [ 'author', 'contents' ],
-1 11217 type: 'abstract'
-1 11218 },
-1 11219 sectionhead: {
-1 11220 nameFrom: [ 'author', 'contents' ],
-1 11221 type: 'abstract'
-1 11222 },
-1 11223 select: {
-1 11224 nameFrom: [ 'author' ],
-1 11225 type: 'abstract'
-1 11226 },
-1 11227 separator: {
-1 11228 type: 'structure',
-1 11229 attributes: {
-1 11230 allowed: [ 'aria-expanded', 'aria-orientation' ]
-1 11231 },
-1 11232 owned: null,
-1 11233 nameFrom: [ 'author' ],
-1 11234 context: null,
-1 11235 implicit: [ 'hr' ]
-1 11236 },
-1 11237 slider: {
-1 11238 type: 'widget',
-1 11239 attributes: {
-1 11240 allowed: [ 'aria-valuetext', 'aria-orientation' ],
-1 11241 required: [ 'aria-valuenow', 'aria-valuemax', 'aria-valuemin' ]
-1 11242 },
-1 11243 owned: null,
-1 11244 nameFrom: [ 'author' ],
-1 11245 context: null,
-1 11246 implicit: [ 'input[type="range"]' ]
-1 11247 },
-1 11248 spinbutton: {
-1 11249 type: 'widget',
-1 11250 attributes: {
-1 11251 allowed: [ 'aria-valuetext', 'aria-required' ],
-1 11252 required: [ 'aria-valuenow', 'aria-valuemax', 'aria-valuemin' ]
-1 11253 },
-1 11254 owned: null,
-1 11255 nameFrom: [ 'author' ],
-1 11256 context: null,
-1 11257 implicit: [ 'input[type="number"]' ]
-1 11258 },
-1 11259 status: {
-1 11260 type: 'widget',
-1 11261 attributes: {
-1 11262 allowed: [ 'aria-expanded' ]
-1 11263 },
-1 11264 owned: null,
-1 11265 nameFrom: [ 'author' ],
-1 11266 context: null,
-1 11267 implicit: [ 'output' ]
-1 11268 },
-1 11269 structure: {
-1 11270 type: 'abstract'
-1 11271 },
-1 11272 switch: {
-1 11273 type: 'widget',
-1 11274 attributes: {
-1 11275 required: [ 'aria-checked' ]
-1 11276 },
-1 11277 owned: null,
-1 11278 nameFrom: [ 'author', 'contents' ],
-1 11279 context: null
-1 11280 },
-1 11281 tab: {
-1 11282 type: 'widget',
-1 11283 attributes: {
-1 11284 allowed: [ 'aria-selected', 'aria-expanded', 'aria-setsize', 'aria-posinset' ]
-1 11285 },
-1 11286 owned: null,
-1 11287 nameFrom: [ 'author', 'contents' ],
-1 11288 context: [ 'tablist' ]
-1 11289 },
-1 11290 table: {
-1 11291 type: 'structure',
-1 11292 attributes: {
-1 11293 allowed: [ 'aria-colcount', 'aria-rowcount' ]
-1 11294 },
-1 11295 owned: {
-1 11296 one: [ 'rowgroup', 'row' ]
-1 11297 },
-1 11298 nameFrom: [ 'author' ],
-1 11299 context: null,
-1 11300 implicit: [ 'table' ]
-1 11301 },
-1 11302 tablist: {
-1 11303 type: 'composite',
-1 11304 attributes: {
-1 11305 allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-level', 'aria-multiselectable', 'aria-orientation' ]
-1 11306 },
-1 11307 owned: {
-1 11308 all: [ 'tab' ]
-1 11309 },
-1 11310 nameFrom: [ 'author' ],
-1 11311 context: null
-1 11312 },
-1 11313 tabpanel: {
-1 11314 type: 'widget',
-1 11315 attributes: {
-1 11316 allowed: [ 'aria-expanded' ]
-1 11317 },
-1 11318 owned: null,
-1 11319 nameFrom: [ 'author' ],
-1 11320 context: null
-1 11321 },
-1 11322 term: {
-1 11323 type: 'structure',
-1 11324 attributes: {
-1 11325 allowed: [ 'aria-expanded' ]
-1 11326 },
-1 11327 owned: null,
-1 11328 nameFrom: [ 'author', 'contents' ],
-1 11329 context: null,
-1 11330 implicit: [ 'dt' ]
-1 11331 },
-1 11332 text: {
-1 11333 type: 'structure',
-1 11334 owned: null,
-1 11335 nameFrom: [ 'author', 'contents' ],
-1 11336 context: null
-1 11337 },
-1 11338 textbox: {
-1 11339 type: 'widget',
-1 11340 attributes: {
-1 11341 allowed: [ 'aria-activedescendant', 'aria-autocomplete', 'aria-multiline', 'aria-readonly', 'aria-required', 'aria-placeholder' ]
-1 11342 },
-1 11343 owned: null,
-1 11344 nameFrom: [ 'author' ],
-1 11345 context: null,
-1 11346 implicit: [ 'input[type="text"]', 'input[type="email"]', 'input[type="password"]', 'input[type="tel"]', 'input[type="url"]', 'input:not([type])', 'textarea' ]
-1 11347 },
-1 11348 timer: {
-1 11349 type: 'widget',
-1 11350 attributes: {
-1 11351 allowed: [ 'aria-expanded' ]
-1 11352 },
-1 11353 owned: null,
-1 11354 nameFrom: [ 'author' ],
-1 11355 context: null
-1 11356 },
-1 11357 toolbar: {
-1 11358 type: 'structure',
-1 11359 attributes: {
-1 11360 allowed: [ 'aria-activedescendant', 'aria-expanded' ]
-1 11361 },
-1 11362 owned: null,
-1 11363 nameFrom: [ 'author' ],
-1 11364 context: null,
-1 11365 implicit: [ 'menu[type="toolbar"]' ]
-1 11366 },
-1 11367 tooltip: {
-1 11368 type: 'widget',
-1 11369 attributes: {
-1 11370 allowed: [ 'aria-expanded' ]
-1 11371 },
-1 11372 owned: null,
-1 11373 nameFrom: [ 'author', 'contents' ],
-1 11374 context: null
-1 11375 },
-1 11376 tree: {
-1 11377 type: 'composite',
-1 11378 attributes: {
-1 11379 allowed: [ 'aria-activedescendant', 'aria-multiselectable', 'aria-required', 'aria-expanded', 'aria-orientation' ]
-1 11380 },
-1 11381 owned: {
-1 11382 all: [ 'treeitem' ]
-1 11383 },
-1 11384 nameFrom: [ 'author' ],
-1 11385 context: null
-1 11386 },
-1 11387 treegrid: {
-1 11388 type: 'composite',
-1 11389 attributes: {
-1 11390 allowed: [ 'aria-activedescendant', 'aria-colcount', 'aria-expanded', 'aria-level', 'aria-multiselectable', 'aria-readonly', 'aria-required', 'aria-rowcount', 'aria-orientation' ]
-1 11391 },
-1 11392 owned: {
-1 11393 one: [ 'rowgroup', 'row' ]
-1 11394 },
-1 11395 nameFrom: [ 'author' ],
-1 11396 context: null
-1 11397 },
-1 11398 treeitem: {
-1 11399 type: 'widget',
-1 11400 attributes: {
-1 11401 allowed: [ 'aria-checked', 'aria-selected', 'aria-expanded', 'aria-level', 'aria-posinset', 'aria-setsize' ]
-1 11402 },
-1 11403 owned: null,
-1 11404 nameFrom: [ 'author', 'contents' ],
-1 11405 context: [ 'group', 'tree' ]
-1 11406 },
-1 11407 widget: {
-1 11408 type: 'abstract'
-1 11409 },
-1 11410 window: {
-1 11411 nameFrom: [ 'author' ],
-1 11412 type: 'abstract'
-1 11413 }
-1 11414 };
-1 11415 var color = {};
-1 11416 commons.color = color;
-1 11417 var dom = commons.dom = {};
-1 11418 var table = commons.table = {};
-1 11419 var text = commons.text = {};
-1 11420 var utils = commons.utils = axe.utils;
-1 11421 aria.requiredAttr = function(role) {
-1 11422 'use strict';
-1 11423 var roles = aria.lookupTable.role[role], attr = roles && roles.attributes && roles.attributes.required;
-1 11424 return attr || [];
-1 11425 };
-1 11426 aria.allowedAttr = function(role) {
-1 11427 'use strict';
-1 11428 var roles = aria.lookupTable.role[role], attr = roles && roles.attributes && roles.attributes.allowed || [], requiredAttr = roles && roles.attributes && roles.attributes.required || [];
-1 11429 return attr.concat(aria.lookupTable.globalAttributes).concat(requiredAttr);
-1 11430 };
-1 11431 aria.validateAttr = function(att) {
-1 11432 'use strict';
-1 11433 return !!aria.lookupTable.attributes[att];
-1 11434 };
-1 11435 aria.validateAttrValue = function(node, attr) {
-1 11436 'use strict';
-1 11437 var matches, list, doc = document, value = node.getAttribute(attr), attrInfo = aria.lookupTable.attributes[attr];
-1 11438 if (!attrInfo) {
-1 11439 return true;
-1 11440 }
-1 11441 switch (attrInfo.type) {
-1 11442 case 'boolean':
-1 11443 case 'nmtoken':
-1 11444 return typeof value === 'string' && attrInfo.values.indexOf(value.toLowerCase()) !== -1;
-1 11445
-1 11446 case 'nmtokens':
-1 11447 list = axe.utils.tokenList(value);
-1 11448 return list.reduce(function(result, token) {
-1 11449 return result && attrInfo.values.indexOf(token) !== -1;
-1 11450 }, list.length !== 0);
-1 11451
-1 11452 case 'idref':
-1 11453 return !!(value && doc.getElementById(value));
-1 11454
-1 11455 case 'idrefs':
-1 11456 list = axe.utils.tokenList(value);
-1 11457 return list.reduce(function(result, token) {
-1 11458 return !!(result && doc.getElementById(token));
-1 11459 }, list.length !== 0);
-1 11460
-1 11461 case 'string':
-1 11462 return true;
-1 11463
-1 11464 case 'decimal':
-1 11465 matches = value.match(/^[-+]?([0-9]*)\.?([0-9]*)$/);
-1 11466 return !!(matches && (matches[1] || matches[2]));
-1 11467
-1 11468 case 'int':
-1 11469 return /^[-+]?[0-9]+$/.test(value);
-1 11470 }
-1 11471 };
-1 11472 aria.label = function(node) {
-1 11473 var ref, candidate;
-1 11474 if (node.getAttribute('aria-labelledby')) {
-1 11475 ref = dom.idrefs(node, 'aria-labelledby');
-1 11476 candidate = ref.map(function(thing) {
-1 11477 return thing ? text.visible(thing, true) : '';
-1 11478 }).join(' ').trim();
-1 11479 if (candidate) {
-1 11480 return candidate;
-1 11481 }
-1 11482 }
-1 11483 candidate = node.getAttribute('aria-label');
-1 11484 if (candidate) {
-1 11485 candidate = text.sanitize(candidate).trim();
-1 11486 if (candidate) {
-1 11487 return candidate;
-1 11488 }
-1 11489 }
-1 11490 return null;
-1 11491 };
-1 11492 aria.isValidRole = function(role) {
-1 11493 'use strict';
-1 11494 if (aria.lookupTable.role[role]) {
-1 11495 return true;
-1 11496 }
-1 11497 return false;
-1 11498 };
-1 11499 aria.getRolesWithNameFromContents = function() {
-1 11500 return Object.keys(aria.lookupTable.role).filter(function(r) {
-1 11501 return aria.lookupTable.role[r].nameFrom && aria.lookupTable.role[r].nameFrom.indexOf('contents') !== -1;
-1 11502 });
-1 11503 };
-1 11504 aria.getRolesByType = function(roleType) {
-1 11505 return Object.keys(aria.lookupTable.role).filter(function(r) {
-1 11506 return aria.lookupTable.role[r].type === roleType;
-1 11507 });
-1 11508 };
-1 11509 aria.getRoleType = function(role) {
-1 11510 var r = aria.lookupTable.role[role];
-1 11511 return r && r.type || null;
-1 11512 };
-1 11513 aria.requiredOwned = function(role) {
-1 11514 'use strict';
-1 11515 var owned = null, roles = aria.lookupTable.role[role];
-1 11516 if (roles) {
-1 11517 owned = axe.utils.clone(roles.owned);
-1 11518 }
-1 11519 return owned;
-1 11520 };
-1 11521 aria.requiredContext = function(role) {
-1 11522 'use strict';
-1 11523 var context = null, roles = aria.lookupTable.role[role];
-1 11524 if (roles) {
-1 11525 context = axe.utils.clone(roles.context);
-1 11526 }
-1 11527 return context;
-1 11528 };
-1 11529 aria.implicitNodes = function(role) {
-1 11530 'use strict';
-1 11531 var implicit = null, roles = aria.lookupTable.role[role];
-1 11532 if (roles && roles.implicit) {
-1 11533 implicit = axe.utils.clone(roles.implicit);
-1 11534 }
-1 11535 return implicit;
-1 11536 };
-1 11537 aria.implicitRole = function(node) {
-1 11538 'use strict';
-1 11539 var isValidImplicitRole = function isValidImplicitRole(set, role) {
-1 11540 var validForNodeType = function validForNodeType(implicitNodeTypeSelector) {
-1 11541 return axe.utils.matchesSelector(node, implicitNodeTypeSelector);
-1 11542 };
-1 11543 if (role.implicit && role.implicit.some(validForNodeType)) {
-1 11544 set.push(role.name);
-1 11545 }
-1 11546 return set;
-1 11547 };
-1 11548 var sortRolesByOptimalAriaContext = function sortRolesByOptimalAriaContext(roles, ariaAttributes) {
-1 11549 var getScore = function getScore(role) {
-1 11550 var allowedAriaAttributes = aria.allowedAttr(role);
-1 11551 return allowedAriaAttributes.reduce(function(score, attribute) {
-1 11552 return score + (ariaAttributes.indexOf(attribute) > -1 ? 1 : 0);
-1 11553 }, 0);
-1 11554 };
-1 11555 var scored = roles.map(function(role) {
-1 11556 return {
-1 11557 score: getScore(role),
-1 11558 name: role
-1 11559 };
-1 11560 });
-1 11561 var sorted = scored.sort(function(scoredRoleA, scoredRoleB) {
-1 11562 return scoredRoleB.score - scoredRoleA.score;
-1 11563 });
-1 11564 return sorted.map(function(sortedRole) {
-1 11565 return sortedRole.name;
-1 11566 });
-1 11567 };
-1 11568 var roles = Object.keys(aria.lookupTable.role).map(function(role) {
-1 11569 var lookup = aria.lookupTable.role[role];
-1 11570 return {
-1 11571 name: role,
-1 11572 implicit: lookup && lookup.implicit
-1 11573 };
-1 11574 });
-1 11575 var availableImplicitRoles = roles.reduce(isValidImplicitRole, []);
-1 11576 if (!availableImplicitRoles.length) {
-1 11577 return null;
-1 11578 }
-1 11579 var nodeAttributes = node.attributes;
-1 11580 var ariaAttributes = [];
-1 11581 for (var i = 0, j = nodeAttributes.length; i < j; i++) {
-1 11582 var attr = nodeAttributes[i];
-1 11583 if (attr.name.match(/^aria-/)) {
-1 11584 ariaAttributes.push(attr.name);
-1 11585 }
-1 11586 }
-1 11587 return sortRolesByOptimalAriaContext(availableImplicitRoles, ariaAttributes).shift();
-1 11588 };
-1 11589 color.Color = function(red, green, blue, alpha) {
-1 11590 this.red = red;
-1 11591 this.green = green;
-1 11592 this.blue = blue;
-1 11593 this.alpha = alpha;
-1 11594 this.toHexString = function() {
-1 11595 var redString = Math.round(this.red).toString(16);
-1 11596 var greenString = Math.round(this.green).toString(16);
-1 11597 var blueString = Math.round(this.blue).toString(16);
-1 11598 return '#' + (this.red > 15.5 ? redString : '0' + redString) + (this.green > 15.5 ? greenString : '0' + greenString) + (this.blue > 15.5 ? blueString : '0' + blueString);
-1 11599 };
-1 11600 var rgbRegex = /^rgb\((\d+), (\d+), (\d+)\)$/;
-1 11601 var rgbaRegex = /^rgba\((\d+), (\d+), (\d+), (\d*(\.\d+)?)\)/;
-1 11602 this.parseRgbString = function(colorString) {
-1 11603 if (colorString === 'transparent') {
-1 11604 this.red = 0;
-1 11605 this.green = 0;
-1 11606 this.blue = 0;
-1 11607 this.alpha = 0;
-1 11608 return;
-1 11609 }
-1 11610 var match = colorString.match(rgbRegex);
-1 11611 if (match) {
-1 11612 this.red = parseInt(match[1], 10);
-1 11613 this.green = parseInt(match[2], 10);
-1 11614 this.blue = parseInt(match[3], 10);
-1 11615 this.alpha = 1;
-1 11616 return;
-1 11617 }
-1 11618 match = colorString.match(rgbaRegex);
-1 11619 if (match) {
-1 11620 this.red = parseInt(match[1], 10);
-1 11621 this.green = parseInt(match[2], 10);
-1 11622 this.blue = parseInt(match[3], 10);
-1 11623 this.alpha = parseFloat(match[4]);
-1 11624 return;
-1 11625 }
-1 11626 };
-1 11627 this.getRelativeLuminance = function() {
-1 11628 var rSRGB = this.red / 255;
-1 11629 var gSRGB = this.green / 255;
-1 11630 var bSRGB = this.blue / 255;
-1 11631 var r = rSRGB <= .03928 ? rSRGB / 12.92 : Math.pow((rSRGB + .055) / 1.055, 2.4);
-1 11632 var g = gSRGB <= .03928 ? gSRGB / 12.92 : Math.pow((gSRGB + .055) / 1.055, 2.4);
-1 11633 var b = bSRGB <= .03928 ? bSRGB / 12.92 : Math.pow((bSRGB + .055) / 1.055, 2.4);
-1 11634 return .2126 * r + .7152 * g + .0722 * b;
-1 11635 };
-1 11636 };
-1 11637 color.flattenColors = function(fgColor, bgColor) {
-1 11638 var alpha = fgColor.alpha;
-1 11639 var r = (1 - alpha) * bgColor.red + alpha * fgColor.red;
-1 11640 var g = (1 - alpha) * bgColor.green + alpha * fgColor.green;
-1 11641 var b = (1 - alpha) * bgColor.blue + alpha * fgColor.blue;
-1 11642 var a = fgColor.alpha + bgColor.alpha * (1 - fgColor.alpha);
-1 11643 return new color.Color(r, g, b, a);
-1 11644 };
-1 11645 color.getContrast = function(bgColor, fgColor) {
-1 11646 if (!fgColor || !bgColor) {
-1 11647 return null;
-1 11648 }
-1 11649 if (fgColor.alpha < 1) {
-1 11650 fgColor = color.flattenColors(fgColor, bgColor);
-1 11651 }
-1 11652 var bL = bgColor.getRelativeLuminance();
-1 11653 var fL = fgColor.getRelativeLuminance();
-1 11654 return (Math.max(fL, bL) + .05) / (Math.min(fL, bL) + .05);
-1 11655 };
-1 11656 color.hasValidContrastRatio = function(bg, fg, fontSize, isBold) {
-1 11657 var contrast = color.getContrast(bg, fg);
-1 11658 var isSmallFont = isBold && Math.ceil(fontSize * 72) / 96 < 14 || !isBold && Math.ceil(fontSize * 72) / 96 < 18;
-1 11659 var expectedContrastRatio = isSmallFont ? 4.5 : 3;
-1 11660 return {
-1 11661 isValid: contrast > expectedContrastRatio,
-1 11662 contrastRatio: contrast,
-1 11663 expectedContrastRatio: expectedContrastRatio
-1 11664 };
-1 11665 };
-1 11666 function _getFonts(style) {
-1 11667 return style.getPropertyValue('font-family').split(/[,;]/g).map(function(font) {
-1 11668 return font.trim().toLowerCase();
-1 11669 });
-1 11670 }
-1 11671 function elementIsDistinct(node, ancestorNode) {
-1 11672 var nodeStyle = window.getComputedStyle(node);
-1 11673 if (nodeStyle.getPropertyValue('background-image') !== 'none') {
-1 11674 return true;
-1 11675 }
-1 11676 var hasBorder = [ 'border-bottom', 'border-top', 'outline' ].reduce(function(result, edge) {
-1 11677 var borderClr = new color.Color();
-1 11678 borderClr.parseRgbString(nodeStyle.getPropertyValue(edge + '-color'));
-1 11679 return result || nodeStyle.getPropertyValue(edge + '-style') !== 'none' && parseFloat(nodeStyle.getPropertyValue(edge + '-width')) > 0 && borderClr.alpha !== 0;
-1 11680 }, false);
-1 11681 if (hasBorder) {
-1 11682 return true;
-1 11683 }
-1 11684 var parentStyle = window.getComputedStyle(ancestorNode);
-1 11685 if (_getFonts(nodeStyle)[0] !== _getFonts(parentStyle)[0]) {
-1 11686 return true;
-1 11687 }
-1 11688 var hasStyle = [ 'text-decoration-line', 'text-decoration-style', 'font-weight', 'font-style', 'font-size' ].reduce(function(result, cssProp) {
-1 11689 return result || nodeStyle.getPropertyValue(cssProp) !== parentStyle.getPropertyValue(cssProp);
-1 11690 }, false);
-1 11691 var tDec = nodeStyle.getPropertyValue('text-decoration');
-1 11692 if (tDec.split(' ').length < 3) {
-1 11693 hasStyle = hasStyle || tDec !== parentStyle.getPropertyValue('text-decoration');
-1 11694 }
-1 11695 return hasStyle;
-1 11696 }
-1 11697 color.elementIsDistinct = elementIsDistinct;
-1 11698 var graphicNodes = [ 'IMG', 'CANVAS', 'OBJECT', 'IFRAME', 'VIDEO', 'SVG' ];
-1 11699 function elmHasImage(elm, style) {
-1 11700 var nodeName = elm.nodeName.toUpperCase();
-1 11701 if (graphicNodes.includes(nodeName)) {
-1 11702 axe.commons.color.incompleteData.set('bgColor', 'imgNode');
-1 11703 return true;
-1 11704 }
-1 11705 style = style || window.getComputedStyle(elm);
-1 11706 var bgImageStyle = style.getPropertyValue('background-image');
-1 11707 var hasBgImage = bgImageStyle !== 'none';
-1 11708 if (hasBgImage) {
-1 11709 var hasGradient = /gradient/.test(bgImageStyle);
-1 11710 axe.commons.color.incompleteData.set('bgColor', hasGradient ? 'bgGradient' : 'bgImage');
-1 11711 }
-1 11712 return hasBgImage;
-1 11713 }
-1 11714 function getBgColor(elm, elmStyle) {
-1 11715 elmStyle = elmStyle || window.getComputedStyle(elm);
-1 11716 var bgColor = new color.Color();
-1 11717 bgColor.parseRgbString(elmStyle.getPropertyValue('background-color'));
-1 11718 if (bgColor.alpha !== 0) {
-1 11719 var opacity = elmStyle.getPropertyValue('opacity');
-1 11720 bgColor.alpha = bgColor.alpha * opacity;
-1 11721 }
-1 11722 return bgColor;
-1 11723 }
-1 11724 function contentOverlapping(targetElement, bgNode) {
-1 11725 var targetRect = targetElement.getClientRects()[0];
-1 11726 var obscuringElements = document.elementsFromPoint(targetRect.left, targetRect.top);
-1 11727 if (obscuringElements) {
-1 11728 for (var i = 0; i < obscuringElements.length; i++) {
-1 11729 if (obscuringElements[i] !== targetElement && obscuringElements[i] === bgNode) {
-1 11730 return true;
-1 11731 }
-1 11732 }
-1 11733 }
-1 11734 return false;
-1 11735 }
-1 11736 function calculateObscuringAlpha(elmIndex, elmStack, originalElm) {
-1 11737 var totalAlpha = 0;
-1 11738 if (elmIndex > 0) {
-1 11739 for (var i = elmIndex - 1; i >= 0; i--) {
-1 11740 var bgElm = elmStack[i];
-1 11741 var bgElmStyle = window.getComputedStyle(bgElm);
-1 11742 var bgColor = getBgColor(bgElm, bgElmStyle);
-1 11743 if (bgColor.alpha && contentOverlapping(originalElm, bgElm)) {
-1 11744 totalAlpha += bgColor.alpha;
-1 11745 } else {
-1 11746 elmStack.splice(i, 1);
-1 11747 }
-1 11748 }
-1 11749 }
-1 11750 return totalAlpha;
-1 11751 }
-1 11752 function elmPartiallyObscured(elm, bgElm, bgColor) {
-1 11753 var obscured = elm !== bgElm && !dom.visuallyContains(elm, bgElm) && bgColor.alpha !== 0;
-1 11754 if (obscured) {
-1 11755 axe.commons.color.incompleteData.set('bgColor', 'elmPartiallyObscured');
-1 11756 }
-1 11757 return obscured;
-1 11758 }
-1 11759 function includeMissingElements(elmStack, elm) {
-1 11760 var elementMap = {
-1 11761 TD: [ 'TR', 'TBODY' ],
-1 11762 TH: [ 'TR', 'THEAD' ],
-1 11763 INPUT: [ 'LABEL' ]
-1 11764 };
-1 11765 var tagArray = elmStack.map(function(elm) {
-1 11766 return elm.tagName;
-1 11767 });
-1 11768 var bgNodes = elmStack;
-1 11769 for (var candidate in elementMap) {
-1 11770 if (tagArray.includes(candidate)) {
-1 11771 for (var candidateIndex in elementMap[candidate]) {
-1 11772 if (candidate.hasOwnProperty(candidateIndex)) {
-1 11773 var ancestorMatch = axe.commons.dom.findUp(elm, elementMap[candidate][candidateIndex]);
-1 11774 if (ancestorMatch && elmStack.indexOf(ancestorMatch) === -1) {
-1 11775 var overlaps = axe.commons.dom.visuallyOverlaps(elm.getBoundingClientRect(), ancestorMatch);
-1 11776 if (overlaps) {
-1 11777 bgNodes.splice(tagArray.indexOf(candidate) + 1, 0, ancestorMatch);
-1 11778 }
-1 11779 }
-1 11780 if (elm.tagName === elementMap[candidate][candidateIndex] && tagArray.indexOf(elm.tagName) === -1) {
-1 11781 bgNodes.splice(tagArray.indexOf(candidate) + 1, 0, elm);
-1 11782 }
-1 11783 }
-1 11784 }
-1 11785 }
-1 11786 }
-1 11787 return bgNodes;
-1 11788 }
-1 11789 function sortPageBackground(elmStack) {
-1 11790 var bodyIndex = elmStack.indexOf(document.body);
-1 11791 var bgNodes = elmStack;
-1 11792 if (bodyIndex > 1 && !elmHasImage(document.documentElement) && getBgColor(document.documentElement).alpha === 0) {
-1 11793 bgNodes.splice(bodyIndex, 1);
-1 11794 bgNodes.splice(elmStack.indexOf(document.documentElement), 1);
-1 11795 bgNodes.push(document.body);
-1 11796 }
-1 11797 return bgNodes;
-1 11798 }
-1 11799 color.getCoords = function(rect) {
-1 11800 var x = void 0, y = void 0;
-1 11801 if (rect.left > window.innerWidth) {
-1 11802 return;
-1 11803 }
-1 11804 if (rect.top > window.innerHeight) {
-1 11805 return;
-1 11806 }
-1 11807 x = Math.min(Math.ceil(rect.left + rect.width / 2), window.innerWidth - 1);
-1 11808 y = Math.min(Math.ceil(rect.top + rect.height / 2), window.innerHeight - 1);
-1 11809 return {
-1 11810 x: x,
-1 11811 y: y
-1 11812 };
-1 11813 };
-1 11814 color.getRectStack = function(elm) {
-1 11815 var boundingCoords = color.getCoords(elm.getBoundingClientRect());
-1 11816 if (boundingCoords) {
-1 11817 var rects = Array.from(elm.getClientRects());
-1 11818 var boundingStack = Array.from(document.elementsFromPoint(boundingCoords.x, boundingCoords.y));
-1 11819 if (rects && rects.length > 1) {
-1 11820 var filteredArr = rects.filter(function(rect) {
-1 11821 return rect.width && rect.width > 0;
-1 11822 }).map(function(rect) {
-1 11823 var coords = color.getCoords(rect);
-1 11824 if (coords) {
-1 11825 return Array.from(document.elementsFromPoint(coords.x, coords.y));
-1 11826 }
-1 11827 });
-1 11828 filteredArr.splice(0, 0, boundingStack);
-1 11829 return filteredArr;
-1 11830 } else {
-1 11831 return [ boundingStack ];
-1 11832 }
-1 11833 }
-1 11834 return null;
-1 11835 };
-1 11836 color.filteredRectStack = function(elm) {
-1 11837 var rectStack = color.getRectStack(elm);
-1 11838 if (rectStack && rectStack.length === 1) {
-1 11839 return rectStack[0];
-1 11840 } else if (rectStack && rectStack.length > 1) {
-1 11841 var boundingStack = rectStack.shift();
-1 11842 var isSame = void 0;
-1 11843 rectStack.forEach(function(rectList, index) {
-1 11844 if (index === 0) {
-1 11845 return;
-1 11846 }
-1 11847 var rectA = rectStack[index - 1], rectB = rectStack[index];
-1 11848 isSame = rectA.every(function(element, elementIndex) {
-1 11849 return element === rectB[elementIndex];
-1 11850 }) || boundingStack.includes(elm);
-1 11851 });
-1 11852 if (!isSame) {
-1 11853 axe.commons.color.incompleteData.set('bgColor', 'elmPartiallyObscuring');
-1 11854 return null;
-1 11855 }
-1 11856 return rectStack[0];
-1 11857 } else {
-1 11858 axe.commons.color.incompleteData.set('bgColor', 'outsideViewport');
-1 11859 return null;
-1 11860 }
-1 11861 };
-1 11862 color.getBackgroundStack = function(elm) {
-1 11863 var elmStack = color.filteredRectStack(elm);
-1 11864 if (elmStack === null) {
-1 11865 return null;
-1 11866 }
-1 11867 elmStack = includeMissingElements(elmStack, elm);
-1 11868 elmStack = dom.reduceToElementsBelowFloating(elmStack, elm);
-1 11869 elmStack = sortPageBackground(elmStack);
-1 11870 var elmIndex = elmStack.indexOf(elm);
-1 11871 if (calculateObscuringAlpha(elmIndex, elmStack, elm) >= .99) {
-1 11872 axe.commons.color.incompleteData.set('bgColor', 'bgOverlap');
-1 11873 return null;
-1 11874 }
-1 11875 return elmIndex !== -1 ? elmStack : null;
-1 11876 };
-1 11877 color.getBackgroundColor = function(elm) {
-1 11878 var bgElms = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
-1 11879 var noScroll = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
-1 11880 if (noScroll !== true) {
-1 11881 var alignToTop = elm.clientHeight - 2 >= window.innerHeight * 2;
-1 11882 elm.scrollIntoView(alignToTop);
-1 11883 }
-1 11884 var bgColors = [];
-1 11885 var elmStack = color.getBackgroundStack(elm);
-1 11886 (elmStack || []).some(function(bgElm) {
-1 11887 var bgElmStyle = window.getComputedStyle(bgElm);
-1 11888 var bgColor = getBgColor(bgElm, bgElmStyle);
-1 11889 if (elmPartiallyObscured(elm, bgElm, bgColor) || elmHasImage(bgElm, bgElmStyle)) {
-1 11890 bgColors = null;
-1 11891 bgElms.push(bgElm);
-1 11892 return true;
-1 11893 }
-1 11894 if (bgColor.alpha !== 0) {
-1 11895 bgElms.push(bgElm);
-1 11896 bgColors.push(bgColor);
-1 11897 return bgColor.alpha === 1;
-1 11898 } else {
-1 11899 return false;
-1 11900 }
-1 11901 });
-1 11902 if (bgColors !== null && elmStack !== null) {
-1 11903 bgColors.push(new color.Color(255, 255, 255, 1));
-1 11904 var colors = bgColors.reduce(color.flattenColors);
-1 11905 return colors;
-1 11906 }
-1 11907 return null;
-1 11908 };
-1 11909 dom.isOpaque = function(node) {
-1 11910 var style = window.getComputedStyle(node);
-1 11911 return elmHasImage(node, style) || getBgColor(node, style).alpha === 1;
-1 11912 };
-1 11913 color.getForegroundColor = function(node, noScroll) {
-1 11914 var nodeStyle = window.getComputedStyle(node);
-1 11915 var fgColor = new color.Color();
-1 11916 fgColor.parseRgbString(nodeStyle.getPropertyValue('color'));
-1 11917 var opacity = nodeStyle.getPropertyValue('opacity');
-1 11918 fgColor.alpha = fgColor.alpha * opacity;
-1 11919 if (fgColor.alpha === 1) {
-1 11920 return fgColor;
-1 11921 }
-1 11922 var bgColor = color.getBackgroundColor(node, [], noScroll);
-1 11923 if (bgColor === null) {
-1 11924 var reason = axe.commons.color.incompleteData.get('bgColor');
-1 11925 axe.commons.color.incompleteData.set('fgColor', reason);
-1 11926 return null;
-1 11927 }
-1 11928 return color.flattenColors(fgColor, bgColor);
-1 11929 };
-1 11930 color.incompleteData = function() {
-1 11931 var data = {};
-1 11932 return {
-1 11933 set: function set(key, reason) {
-1 11934 if (typeof key !== 'string') {
-1 11935 throw new Error('Incomplete data: key must be a string');
-1 11936 }
-1 11937 if (reason) {
-1 11938 data[key] = reason;
-1 11939 }
-1 11940 return data[key];
-1 11941 },
-1 11942 get: function get(key) {
-1 11943 return data[key];
-1 11944 },
-1 11945 clear: function clear() {
-1 11946 data = {};
-1 11947 }
-1 11948 };
-1 11949 }();
-1 11950 dom.reduceToElementsBelowFloating = function(elements, targetNode) {
-1 11951 var floatingPositions = [ 'fixed', 'sticky' ], finalElements = [], targetFound = false, index, currentNode, style;
-1 11952 for (index = 0; index < elements.length; ++index) {
-1 11953 currentNode = elements[index];
-1 11954 if (currentNode === targetNode) {
-1 11955 targetFound = true;
-1 11956 }
-1 11957 style = window.getComputedStyle(currentNode);
-1 11958 if (!targetFound && floatingPositions.indexOf(style.position) !== -1) {
-1 11959 finalElements = [];
-1 11960 continue;
-1 11961 }
-1 11962 finalElements.push(currentNode);
-1 11963 }
-1 11964 return finalElements;
-1 11965 };
-1 11966 dom.findUp = function(element, target) {
-1 11967 'use strict';
-1 11968 var parent, matches = document.querySelectorAll(target), length = matches.length;
-1 11969 if (!length) {
-1 11970 return null;
-1 11971 }
-1 11972 matches = axe.utils.toArray(matches);
-1 11973 parent = element.parentNode;
-1 11974 while (parent && matches.indexOf(parent) === -1) {
-1 11975 parent = parent.parentNode;
-1 11976 }
-1 11977 return parent;
-1 11978 };
-1 11979 dom.getElementByReference = function(node, attr) {
-1 11980 'use strict';
-1 11981 var candidate, fragment = node.getAttribute(attr), doc = document;
-1 11982 if (fragment && fragment.charAt(0) === '#') {
-1 11983 fragment = fragment.substring(1);
-1 11984 candidate = doc.getElementById(fragment);
-1 11985 if (candidate) {
-1 11986 return candidate;
-1 11987 }
-1 11988 candidate = doc.getElementsByName(fragment);
-1 11989 if (candidate.length) {
-1 11990 return candidate[0];
-1 11991 }
-1 11992 }
-1 11993 return null;
-1 11994 };
-1 11995 dom.getElementCoordinates = function(element) {
-1 11996 'use strict';
-1 11997 var scrollOffset = dom.getScrollOffset(document), xOffset = scrollOffset.left, yOffset = scrollOffset.top, coords = element.getBoundingClientRect();
-1 11998 return {
-1 11999 top: coords.top + yOffset,
-1 12000 right: coords.right + xOffset,
-1 12001 bottom: coords.bottom + yOffset,
-1 12002 left: coords.left + xOffset,
-1 12003 width: coords.right - coords.left,
-1 12004 height: coords.bottom - coords.top
-1 12005 };
-1 12006 };
-1 12007 dom.getScrollOffset = function(element) {
-1 12008 'use strict';
-1 12009 if (!element.nodeType && element.document) {
-1 12010 element = element.document;
-1 12011 }
-1 12012 if (element.nodeType === 9) {
-1 12013 var docElement = element.documentElement, body = element.body;
-1 12014 return {
-1 12015 left: docElement && docElement.scrollLeft || body && body.scrollLeft || 0,
-1 12016 top: docElement && docElement.scrollTop || body && body.scrollTop || 0
-1 12017 };
-1 12018 }
-1 12019 return {
-1 12020 left: element.scrollLeft,
-1 12021 top: element.scrollTop
-1 12022 };
-1 12023 };
-1 12024 dom.getViewportSize = function(win) {
-1 12025 'use strict';
-1 12026 var body, doc = win.document, docElement = doc.documentElement;
-1 12027 if (win.innerWidth) {
-1 12028 return {
-1 12029 width: win.innerWidth,
-1 12030 height: win.innerHeight
-1 12031 };
-1 12032 }
-1 12033 if (docElement) {
-1 12034 return {
-1 12035 width: docElement.clientWidth,
-1 12036 height: docElement.clientHeight
-1 12037 };
-1 12038 }
-1 12039 body = doc.body;
-1 12040 return {
-1 12041 width: body.clientWidth,
-1 12042 height: body.clientHeight
-1 12043 };
-1 12044 };
-1 12045 dom.hasContent = function hasContent(elm) {
-1 12046 var skipItems = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
-1 12047 if (elm.textContent.trim() || aria.label(elm)) {
-1 12048 return true;
-1 12049 }
-1 12050 var contentElms = elm.querySelectorAll('*');
-1 12051 for (var i = 0; i < contentElms.length; i++) {
-1 12052 if (skipItems.indexOf(contentElms[i]) === -1 && aria.label(contentElms[i]) || dom.isVisualContent(contentElms[i])) {
-1 12053 return true;
-1 12054 }
-1 12055 }
-1 12056 return false;
-1 12057 };
-1 12058 dom.idrefs = function(node, attr) {
-1 12059 'use strict';
-1 12060 var index, length, doc = document, result = [], idrefs = node.getAttribute(attr);
-1 12061 if (idrefs) {
-1 12062 idrefs = axe.utils.tokenList(idrefs);
-1 12063 for (index = 0, length = idrefs.length; index < length; index++) {
-1 12064 result.push(doc.getElementById(idrefs[index]));
-1 12065 }
-1 12066 }
-1 12067 return result;
-1 12068 };
-1 12069 dom.isFocusable = function(el) {
-1 12070 'use strict';
-1 12071 if (dom.isNativelyFocusable(el)) {
-1 12072 return true;
-1 12073 }
-1 12074 var tabindex = el.getAttribute('tabindex');
-1 12075 if (tabindex && !isNaN(parseInt(tabindex, 10))) {
-1 12076 return true;
-1 12077 }
-1 12078 return false;
-1 12079 };
-1 12080 dom.isNativelyFocusable = function(el) {
-1 12081 'use strict';
-1 12082 if (!el || el.disabled || !dom.isVisible(el) && el.nodeName.toUpperCase() !== 'AREA') {
-1 12083 return false;
-1 12084 }
-1 12085 switch (el.nodeName.toUpperCase()) {
-1 12086 case 'A':
-1 12087 case 'AREA':
-1 12088 if (el.href) {
-1 12089 return true;
-1 12090 }
-1 12091 break;
-1 12092
-1 12093 case 'INPUT':
-1 12094 return el.type !== 'hidden';
-1 12095
-1 12096 case 'TEXTAREA':
-1 12097 case 'SELECT':
-1 12098 case 'DETAILS':
-1 12099 case 'BUTTON':
-1 12100 return true;
-1 12101 }
-1 12102 return false;
-1 12103 };
-1 12104 dom.isHTML5 = function(doc) {
-1 12105 var node = doc.doctype;
-1 12106 if (node === null) {
-1 12107 return false;
-1 12108 }
-1 12109 return node.name === 'html' && !node.publicId && !node.systemId;
-1 12110 };
-1 12111 function walkDomNode(node, functor) {
-1 12112 'use strict';
-1 12113 var shouldWalk = functor(node);
-1 12114 node = node.firstChild;
-1 12115 while (node) {
-1 12116 if (shouldWalk !== false) {
-1 12117 walkDomNode(node, functor);
-1 12118 }
-1 12119 node = node.nextSibling;
-1 12120 }
-1 12121 }
-1 12122 var blockLike = [ 'block', 'list-item', 'table', 'flex', 'grid', 'inline-block' ];
-1 12123 function isBlock(elm) {
-1 12124 'use strict';
-1 12125 var display = window.getComputedStyle(elm).getPropertyValue('display');
-1 12126 return blockLike.indexOf(display) !== -1 || display.substr(0, 6) === 'table-';
-1 12127 }
-1 12128 dom.isInTextBlock = function isInTextBlock(node) {
-1 12129 'use strict';
-1 12130 if (isBlock(node)) {
-1 12131 return false;
-1 12132 }
-1 12133 var parentBlock = node.parentNode;
-1 12134 while (parentBlock.nodeType === 1 && !isBlock(parentBlock)) {
-1 12135 parentBlock = parentBlock.parentNode;
-1 12136 }
-1 12137 var parentText = '';
-1 12138 var linkText = '';
-1 12139 var inBrBlock = 0;
-1 12140 walkDomNode(parentBlock, function(currNode) {
-1 12141 if (inBrBlock === 2) {
-1 12142 return false;
-1 12143 }
-1 12144 if (currNode.nodeType === 3) {
-1 12145 parentText += currNode.nodeValue;
-1 12146 }
-1 12147 if (currNode.nodeType !== 1) {
-1 12148 return;
-1 12149 }
-1 12150 var nodeName = (currNode.nodeName || '').toUpperCase();
-1 12151 if ([ 'BR', 'HR' ].indexOf(nodeName) !== -1) {
-1 12152 if (inBrBlock === 0) {
-1 12153 parentText = '';
-1 12154 linkText = '';
-1 12155 } else {
-1 12156 inBrBlock = 2;
-1 12157 }
-1 12158 } else if (currNode.style.display === 'none' || currNode.style.overflow === 'hidden' || [ '', null, 'none' ].indexOf(currNode.style.float) === -1 || [ '', null, 'relative' ].indexOf(currNode.style.position) === -1) {
-1 12159 return false;
-1 12160 } else if (nodeName === 'A' && currNode.href || (currNode.getAttribute('role') || '').toLowerCase() === 'link') {
-1 12161 if (currNode === node) {
-1 12162 inBrBlock = 1;
-1 12163 }
-1 12164 linkText += currNode.textContent;
-1 12165 return false;
-1 12166 }
-1 12167 });
-1 12168 parentText = axe.commons.text.sanitize(parentText);
-1 12169 linkText = axe.commons.text.sanitize(linkText);
-1 12170 return parentText.length > linkText.length;
-1 12171 };
-1 12172 dom.isNode = function(element) {
-1 12173 'use strict';
-1 12174 return element instanceof Node;
-1 12175 };
-1 12176 dom.isOffscreen = function(element) {
-1 12177 'use strict';
-1 12178 var noParentScrolled = function noParentScrolled(element, offset) {
-1 12179 element = element.parentNode;
-1 12180 while (element.nodeName.toLowerCase() !== 'html') {
-1 12181 if (element.scrollTop) {
-1 12182 offset += element.scrollTop;
-1 12183 if (offset >= 0) {
-1 12184 return false;
-1 12185 }
-1 12186 }
-1 12187 element = element.parentNode;
-1 12188 }
-1 12189 return true;
-1 12190 };
-1 12191 var leftBoundary, docElement = document.documentElement, dir = window.getComputedStyle(document.body || docElement).getPropertyValue('direction'), coords = dom.getElementCoordinates(element);
-1 12192 if (coords.bottom < 0 && noParentScrolled(element, coords.bottom)) {
-1 12193 return true;
-1 12194 }
-1 12195 if (coords.left === 0 && coords.right === 0) {
-1 12196 return false;
-1 12197 }
-1 12198 if (dir === 'ltr') {
-1 12199 if (coords.right <= 0) {
-1 12200 return true;
-1 12201 }
-1 12202 } else {
-1 12203 leftBoundary = Math.max(docElement.scrollWidth, dom.getViewportSize(window).width);
-1 12204 if (coords.left >= leftBoundary) {
-1 12205 return true;
-1 12206 }
-1 12207 }
-1 12208 return false;
-1 12209 };
-1 12210 function isClipped(clip) {
-1 12211 'use strict';
-1 12212 var matches = clip.match(/rect\s*\(([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px\s*\)/);
-1 12213 if (matches && matches.length === 5) {
-1 12214 return matches[3] - matches[1] <= 0 && matches[2] - matches[4] <= 0;
-1 12215 }
-1 12216 return false;
-1 12217 }
-1 12218 dom.isVisible = function(el, screenReader, recursed) {
-1 12219 'use strict';
-1 12220 var style, nodeName = el.nodeName.toUpperCase(), parent = el.parentNode;
-1 12221 if (el.nodeType === 9) {
-1 12222 return true;
-1 12223 }
-1 12224 style = window.getComputedStyle(el, null);
-1 12225 if (style === null) {
-1 12226 return false;
-1 12227 }
-1 12228 if (style.getPropertyValue('display') === 'none' || nodeName.toUpperCase() === 'STYLE' || nodeName.toUpperCase() === 'SCRIPT' || !screenReader && isClipped(style.getPropertyValue('clip')) || !recursed && (style.getPropertyValue('visibility') === 'hidden' || !screenReader && dom.isOffscreen(el)) || screenReader && el.getAttribute('aria-hidden') === 'true') {
-1 12229 return false;
-1 12230 }
-1 12231 if (parent) {
-1 12232 return dom.isVisible(parent, screenReader, true);
-1 12233 }
-1 12234 return false;
-1 12235 };
-1 12236 var visualRoles = [ 'checkbox', 'img', 'radio', 'range', 'slider', 'spinbutton', 'textbox' ];
-1 12237 dom.isVisualContent = function(element) {
-1 12238 var role = element.getAttribute('role');
-1 12239 if (role) {
-1 12240 return visualRoles.indexOf(role) !== -1;
-1 12241 }
-1 12242 switch (element.tagName.toUpperCase()) {
-1 12243 case 'IMG':
-1 12244 case 'IFRAME':
-1 12245 case 'OBJECT':
-1 12246 case 'VIDEO':
-1 12247 case 'AUDIO':
-1 12248 case 'CANVAS':
-1 12249 case 'SVG':
-1 12250 case 'MATH':
-1 12251 case 'BUTTON':
-1 12252 case 'SELECT':
-1 12253 case 'TEXTAREA':
-1 12254 case 'KEYGEN':
-1 12255 case 'PROGRESS':
-1 12256 case 'METER':
-1 12257 return true;
-1 12258
-1 12259 case 'INPUT':
-1 12260 return element.type !== 'hidden';
-1 12261
-1 12262 default:
-1 12263 return false;
-1 12264 }
-1 12265 };
-1 12266 dom.visuallyContains = function(node, parent) {
-1 12267 var rectBound = node.getBoundingClientRect();
-1 12268 var margin = .01;
-1 12269 var rect = {
-1 12270 top: rectBound.top + margin,
-1 12271 bottom: rectBound.bottom - margin,
-1 12272 left: rectBound.left + margin,
-1 12273 right: rectBound.right - margin
-1 12274 };
-1 12275 var parentRect = parent.getBoundingClientRect();
-1 12276 var parentTop = parentRect.top;
-1 12277 var parentLeft = parentRect.left;
-1 12278 var parentScrollArea = {
-1 12279 top: parentTop - parent.scrollTop,
-1 12280 bottom: parentTop - parent.scrollTop + parent.scrollHeight,
-1 12281 left: parentLeft - parent.scrollLeft,
-1 12282 right: parentLeft - parent.scrollLeft + parent.scrollWidth
-1 12283 };
-1 12284 var style = window.getComputedStyle(parent);
-1 12285 if (style.getPropertyValue('display') === 'inline') {
-1 12286 return true;
-1 12287 }
-1 12288 if (rect.left < parentScrollArea.left && rect.left < parentRect.left || rect.top < parentScrollArea.top && rect.top < parentRect.top || rect.right > parentScrollArea.right && rect.right > parentRect.right || rect.bottom > parentScrollArea.bottom && rect.bottom > parentRect.bottom) {
-1 12289 return false;
-1 12290 }
-1 12291 if (rect.right > parentRect.right || rect.bottom > parentRect.bottom) {
-1 12292 return style.overflow === 'scroll' || style.overflow === 'auto' || style.overflow === 'hidden' || parent instanceof HTMLBodyElement || parent instanceof HTMLHtmlElement;
-1 12293 }
-1 12294 return true;
-1 12295 };
-1 12296 dom.visuallyOverlaps = function(rect, parent) {
-1 12297 var parentRect = parent.getBoundingClientRect();
-1 12298 var parentTop = parentRect.top;
-1 12299 var parentLeft = parentRect.left;
-1 12300 var parentScrollArea = {
-1 12301 top: parentTop - parent.scrollTop,
-1 12302 bottom: parentTop - parent.scrollTop + parent.scrollHeight,
-1 12303 left: parentLeft - parent.scrollLeft,
-1 12304 right: parentLeft - parent.scrollLeft + parent.scrollWidth
-1 12305 };
-1 12306 if (rect.left > parentScrollArea.right && rect.left > parentRect.right || rect.top > parentScrollArea.bottom && rect.top > parentRect.bottom || rect.right < parentScrollArea.left && rect.right < parentRect.left || rect.bottom < parentScrollArea.top && rect.bottom < parentRect.top) {
-1 12307 return false;
-1 12308 }
-1 12309 var style = window.getComputedStyle(parent);
-1 12310 if (rect.left > parentRect.right || rect.top > parentRect.bottom) {
-1 12311 return style.overflow === 'scroll' || style.overflow === 'auto' || parent instanceof HTMLBodyElement || parent instanceof HTMLHtmlElement;
-1 12312 }
-1 12313 return true;
-1 12314 };
-1 12315 table.getAllCells = function(tableElm) {
-1 12316 var rowIndex, cellIndex, rowLength, cellLength;
-1 12317 var cells = [];
-1 12318 for (rowIndex = 0, rowLength = tableElm.rows.length; rowIndex < rowLength; rowIndex++) {
-1 12319 for (cellIndex = 0, cellLength = tableElm.rows[rowIndex].cells.length; cellIndex < cellLength; cellIndex++) {
-1 12320 cells.push(tableElm.rows[rowIndex].cells[cellIndex]);
-1 12321 }
-1 12322 }
-1 12323 return cells;
-1 12324 };
-1 12325 table.getCellPosition = function(cell, tableGrid) {
-1 12326 var rowIndex, index;
-1 12327 if (!tableGrid) {
-1 12328 tableGrid = table.toGrid(dom.findUp(cell, 'table'));
-1 12329 }
-1 12330 for (rowIndex = 0; rowIndex < tableGrid.length; rowIndex++) {
-1 12331 if (tableGrid[rowIndex]) {
-1 12332 index = tableGrid[rowIndex].indexOf(cell);
-1 12333 if (index !== -1) {
-1 12334 return {
-1 12335 x: index,
-1 12336 y: rowIndex
-1 12337 };
-1 12338 }
-1 12339 }
-1 12340 }
-1 12341 };
-1 12342 table.getHeaders = function(cell) {
-1 12343 if (cell.hasAttribute('headers')) {
-1 12344 return commons.dom.idrefs(cell, 'headers');
-1 12345 }
-1 12346 var tableGrid = commons.table.toGrid(commons.dom.findUp(cell, 'table'));
-1 12347 var position = commons.table.getCellPosition(cell, tableGrid);
-1 12348 var rowHeaders = table.traverse('left', position, tableGrid).filter(function(cell) {
-1 12349 return table.isRowHeader(cell);
-1 12350 });
-1 12351 var colHeaders = table.traverse('up', position, tableGrid).filter(function(cell) {
-1 12352 return table.isColumnHeader(cell);
-1 12353 });
-1 12354 return [].concat(rowHeaders, colHeaders).reverse();
-1 12355 };
-1 12356 table.getScope = function(cell) {
-1 12357 var scope = cell.getAttribute('scope');
-1 12358 var role = cell.getAttribute('role');
-1 12359 if (cell instanceof Element === false || [ 'TD', 'TH' ].indexOf(cell.nodeName.toUpperCase()) === -1) {
-1 12360 throw new TypeError('Expected TD or TH element');
-1 12361 }
-1 12362 if (role === 'columnheader') {
-1 12363 return 'col';
-1 12364 } else if (role === 'rowheader') {
-1 12365 return 'row';
-1 12366 } else if (scope === 'col' || scope === 'row') {
-1 12367 return scope;
-1 12368 } else if (cell.nodeName.toUpperCase() !== 'TH') {
-1 12369 return false;
-1 12370 }
-1 12371 var tableGrid = table.toGrid(dom.findUp(cell, 'table'));
-1 12372 var pos = table.getCellPosition(cell);
-1 12373 var headerRow = tableGrid[pos.y].reduce(function(headerRow, cell) {
-1 12374 return headerRow && cell.nodeName.toUpperCase() === 'TH';
-1 12375 }, true);
-1 12376 if (headerRow) {
-1 12377 return 'col';
-1 12378 }
-1 12379 var headerCol = tableGrid.map(function(col) {
-1 12380 return col[pos.x];
-1 12381 }).reduce(function(headerCol, cell) {
-1 12382 return headerCol && cell.nodeName.toUpperCase() === 'TH';
-1 12383 }, true);
-1 12384 if (headerCol) {
-1 12385 return 'row';
-1 12386 }
-1 12387 return 'auto';
-1 12388 };
-1 12389 table.isColumnHeader = function(element) {
-1 12390 return [ 'col', 'auto' ].indexOf(table.getScope(element)) !== -1;
-1 12391 };
-1 12392 table.isDataCell = function(cell) {
-1 12393 if (!cell.children.length && !cell.textContent.trim()) {
-1 12394 return false;
-1 12395 }
-1 12396 return cell.nodeName.toUpperCase() === 'TD';
-1 12397 };
-1 12398 table.isDataTable = function(node) {
-1 12399 var role = node.getAttribute('role');
-1 12400 if ((role === 'presentation' || role === 'none') && !dom.isFocusable(node)) {
-1 12401 return false;
-1 12402 }
-1 12403 if (node.getAttribute('contenteditable') === 'true' || dom.findUp(node, '[contenteditable="true"]')) {
-1 12404 return true;
-1 12405 }
-1 12406 if (role === 'grid' || role === 'treegrid' || role === 'table') {
-1 12407 return true;
-1 12408 }
-1 12409 if (commons.aria.getRoleType(role) === 'landmark') {
-1 12410 return true;
-1 12411 }
-1 12412 if (node.getAttribute('datatable') === '0') {
-1 12413 return false;
-1 12414 }
-1 12415 if (node.getAttribute('summary')) {
-1 12416 return true;
-1 12417 }
-1 12418 if (node.tHead || node.tFoot || node.caption) {
-1 12419 return true;
-1 12420 }
-1 12421 for (var childIndex = 0, childLength = node.children.length; childIndex < childLength; childIndex++) {
-1 12422 if (node.children[childIndex].nodeName.toUpperCase() === 'COLGROUP') {
-1 12423 return true;
-1 12424 }
-1 12425 }
-1 12426 var cells = 0;
-1 12427 var rowLength = node.rows.length;
-1 12428 var row, cell;
-1 12429 var hasBorder = false;
-1 12430 for (var rowIndex = 0; rowIndex < rowLength; rowIndex++) {
-1 12431 row = node.rows[rowIndex];
-1 12432 for (var cellIndex = 0, cellLength = row.cells.length; cellIndex < cellLength; cellIndex++) {
-1 12433 cell = row.cells[cellIndex];
-1 12434 if (cell.nodeName.toUpperCase() === 'TH') {
-1 12435 return true;
-1 12436 }
-1 12437 if (!hasBorder && (cell.offsetWidth !== cell.clientWidth || cell.offsetHeight !== cell.clientHeight)) {
-1 12438 hasBorder = true;
-1 12439 }
-1 12440 if (cell.getAttribute('scope') || cell.getAttribute('headers') || cell.getAttribute('abbr')) {
-1 12441 return true;
-1 12442 }
-1 12443 if ([ 'columnheader', 'rowheader' ].indexOf(cell.getAttribute('role')) !== -1) {
-1 12444 return true;
-1 12445 }
-1 12446 if (cell.children.length === 1 && cell.children[0].nodeName.toUpperCase() === 'ABBR') {
-1 12447 return true;
-1 12448 }
-1 12449 cells++;
-1 12450 }
-1 12451 }
-1 12452 if (node.getElementsByTagName('table').length) {
-1 12453 return false;
-1 12454 }
-1 12455 if (rowLength < 2) {
-1 12456 return false;
-1 12457 }
-1 12458 var sampleRow = node.rows[Math.ceil(rowLength / 2)];
-1 12459 if (sampleRow.cells.length === 1 && sampleRow.cells[0].colSpan === 1) {
-1 12460 return false;
-1 12461 }
-1 12462 if (sampleRow.cells.length >= 5) {
-1 12463 return true;
-1 12464 }
-1 12465 if (hasBorder) {
-1 12466 return true;
-1 12467 }
-1 12468 var bgColor, bgImage;
-1 12469 for (rowIndex = 0; rowIndex < rowLength; rowIndex++) {
-1 12470 row = node.rows[rowIndex];
-1 12471 if (bgColor && bgColor !== window.getComputedStyle(row).getPropertyValue('background-color')) {
-1 12472 return true;
-1 12473 } else {
-1 12474 bgColor = window.getComputedStyle(row).getPropertyValue('background-color');
-1 12475 }
-1 12476 if (bgImage && bgImage !== window.getComputedStyle(row).getPropertyValue('background-image')) {
-1 12477 return true;
-1 12478 } else {
-1 12479 bgImage = window.getComputedStyle(row).getPropertyValue('background-image');
-1 12480 }
-1 12481 }
-1 12482 if (rowLength >= 20) {
-1 12483 return true;
-1 12484 }
-1 12485 if (dom.getElementCoordinates(node).width > dom.getViewportSize(window).width * .95) {
-1 12486 return false;
-1 12487 }
-1 12488 if (cells < 10) {
-1 12489 return false;
-1 12490 }
-1 12491 if (node.querySelector('object, embed, iframe, applet')) {
-1 12492 return false;
-1 12493 }
-1 12494 return true;
-1 12495 };
-1 12496 table.isHeader = function(cell) {
-1 12497 if (table.isColumnHeader(cell) || table.isRowHeader(cell)) {
-1 12498 return true;
-1 12499 }
-1 12500 if (cell.getAttribute('id')) {
-1 12501 var id = axe.utils.escapeSelector(cell.getAttribute('id'));
-1 12502 return !!document.querySelector('[headers~="' + id + '"]');
-1 12503 }
-1 12504 return false;
-1 12505 };
-1 12506 table.isRowHeader = function(cell) {
-1 12507 return [ 'row', 'auto' ].includes(table.getScope(cell));
-1 12508 };
-1 12509 table.toGrid = function(node) {
-1 12510 var table = [];
-1 12511 var rows = node.rows;
-1 12512 for (var i = 0, rowLength = rows.length; i < rowLength; i++) {
-1 12513 var cells = rows[i].cells;
-1 12514 table[i] = table[i] || [];
-1 12515 var columnIndex = 0;
-1 12516 for (var j = 0, cellLength = cells.length; j < cellLength; j++) {
-1 12517 for (var colSpan = 0; colSpan < cells[j].colSpan; colSpan++) {
-1 12518 for (var rowSpan = 0; rowSpan < cells[j].rowSpan; rowSpan++) {
-1 12519 table[i + rowSpan] = table[i + rowSpan] || [];
-1 12520 while (table[i + rowSpan][columnIndex]) {
-1 12521 columnIndex++;
-1 12522 }
-1 12523 table[i + rowSpan][columnIndex] = cells[j];
-1 12524 }
-1 12525 columnIndex++;
-1 12526 }
-1 12527 }
-1 12528 }
-1 12529 return table;
-1 12530 };
-1 12531 table.toArray = table.toGrid;
-1 12532 (function(table) {
-1 12533 var traverseTable = function traverseTable(dir, position, tableGrid, callback) {
-1 12534 var result;
-1 12535 var cell = tableGrid[position.y] ? tableGrid[position.y][position.x] : undefined;
-1 12536 if (!cell) {
-1 12537 return [];
-1 12538 }
-1 12539 if (typeof callback === 'function') {
-1 12540 result = callback(cell, position, tableGrid);
-1 12541 if (result === true) {
-1 12542 return [ cell ];
-1 12543 }
-1 12544 }
-1 12545 result = traverseTable(dir, {
-1 12546 x: position.x + dir.x,
-1 12547 y: position.y + dir.y
-1 12548 }, tableGrid, callback);
-1 12549 result.unshift(cell);
-1 12550 return result;
-1 12551 };
-1 12552 table.traverse = function(dir, startPos, tableGrid, callback) {
-1 12553 if (Array.isArray(startPos)) {
-1 12554 callback = tableGrid;
-1 12555 tableGrid = startPos;
-1 12556 startPos = {
-1 12557 x: 0,
-1 12558 y: 0
-1 12559 };
-1 12560 }
-1 12561 if (typeof dir === 'string') {
-1 12562 switch (dir) {
-1 12563 case 'left':
-1 12564 dir = {
-1 12565 x: -1,
-1 12566 y: 0
-1 12567 };
-1 12568 break;
-1 12569
-1 12570 case 'up':
-1 12571 dir = {
-1 12572 x: 0,
-1 12573 y: -1
-1 12574 };
-1 12575 break;
-1 12576
-1 12577 case 'right':
-1 12578 dir = {
-1 12579 x: 1,
-1 12580 y: 0
-1 12581 };
-1 12582 break;
-1 12583
-1 12584 case 'down':
-1 12585 dir = {
-1 12586 x: 0,
-1 12587 y: 1
-1 12588 };
-1 12589 break;
-1 12590 }
-1 12591 }
-1 12592 return traverseTable(dir, {
-1 12593 x: startPos.x + dir.x,
-1 12594 y: startPos.y + dir.y
-1 12595 }, tableGrid, callback);
-1 12596 };
-1 12597 })(table);
-1 12598 var defaultButtonValues = {
-1 12599 submit: 'Submit',
-1 12600 reset: 'Reset'
-1 12601 };
-1 12602 var inputTypes = [ 'text', 'search', 'tel', 'url', 'email', 'date', 'time', 'number', 'range', 'color' ];
-1 12603 var phrasingElements = [ 'A', 'EM', 'STRONG', 'SMALL', 'MARK', 'ABBR', 'DFN', 'I', 'B', 'S', 'U', 'CODE', 'VAR', 'SAMP', 'KBD', 'SUP', 'SUB', 'Q', 'CITE', 'SPAN', 'BDO', 'BDI', 'BR', 'WBR', 'INS', 'DEL', 'IMG', 'EMBED', 'OBJECT', 'IFRAME', 'MAP', 'AREA', 'SCRIPT', 'NOSCRIPT', 'RUBY', 'VIDEO', 'AUDIO', 'INPUT', 'TEXTAREA', 'SELECT', 'BUTTON', 'LABEL', 'OUTPUT', 'DATALIST', 'KEYGEN', 'PROGRESS', 'COMMAND', 'CANVAS', 'TIME', 'METER' ];
-1 12604 function findLabel(element) {
-1 12605 var ref = null;
-1 12606 if (element.getAttribute('id')) {
-1 12607 var id = axe.utils.escapeSelector(element.getAttribute('id'));
-1 12608 ref = document.querySelector('label[for="' + id + '"]');
-1 12609 if (ref) {
-1 12610 return ref;
-1 12611 }
-1 12612 }
-1 12613 ref = dom.findUp(element, 'label');
-1 12614 return ref;
-1 12615 }
-1 12616 function isButton(element) {
-1 12617 return [ 'button', 'reset', 'submit' ].indexOf(element.type) !== -1;
-1 12618 }
-1 12619 function isInput(element) {
-1 12620 var nodeName = element.nodeName.toUpperCase();
-1 12621 return nodeName === 'TEXTAREA' || nodeName === 'SELECT' || nodeName === 'INPUT' && element.type.toLowerCase() !== 'hidden';
-1 12622 }
-1 12623 function shouldCheckSubtree(element) {
-1 12624 return [ 'BUTTON', 'SUMMARY', 'A' ].indexOf(element.nodeName.toUpperCase()) !== -1;
-1 12625 }
-1 12626 function shouldNeverCheckSubtree(element) {
-1 12627 return [ 'TABLE', 'FIGURE' ].indexOf(element.nodeName.toUpperCase()) !== -1;
-1 12628 }
-1 12629 function formValueText(element) {
-1 12630 var nodeName = element.nodeName.toUpperCase();
-1 12631 if (nodeName === 'INPUT') {
-1 12632 if (!element.hasAttribute('type') || inputTypes.indexOf(element.getAttribute('type').toLowerCase()) !== -1 && element.value) {
-1 12633 return element.value;
-1 12634 }
-1 12635 return '';
-1 12636 }
-1 12637 if (nodeName === 'SELECT') {
-1 12638 var opts = element.options;
-1 12639 if (opts && opts.length) {
-1 12640 var returnText = '';
-1 12641 for (var i = 0; i < opts.length; i++) {
-1 12642 if (opts[i].selected) {
-1 12643 returnText += ' ' + opts[i].text;
-1 12644 }
-1 12645 }
-1 12646 return text.sanitize(returnText);
-1 12647 }
-1 12648 return '';
-1 12649 }
-1 12650 if (nodeName === 'TEXTAREA' && element.value) {
-1 12651 return element.value;
-1 12652 }
-1 12653 return '';
-1 12654 }
-1 12655 function checkDescendant(element, nodeName) {
-1 12656 var candidate = element.querySelector(nodeName.toLowerCase());
-1 12657 if (candidate) {
-1 12658 return text.accessibleText(candidate);
-1 12659 }
-1 12660 return '';
-1 12661 }
-1 12662 function isEmbeddedControl(e) {
-1 12663 if (!e) {
-1 12664 return false;
-1 12665 }
-1 12666 switch (e.nodeName.toUpperCase()) {
-1 12667 case 'SELECT':
-1 12668 case 'TEXTAREA':
-1 12669 return true;
-1 12670
-1 12671 case 'INPUT':
-1 12672 return !e.hasAttribute('type') || inputTypes.indexOf(e.getAttribute('type').toLowerCase()) !== -1;
-1 12673
-1 12674 default:
-1 12675 return false;
-1 12676 }
-1 12677 }
-1 12678 function shouldCheckAlt(element) {
-1 12679 var nodeName = element.nodeName.toUpperCase();
-1 12680 return nodeName === 'INPUT' && element.type.toLowerCase() === 'image' || [ 'IMG', 'APPLET', 'AREA' ].indexOf(nodeName) !== -1;
-1 12681 }
-1 12682 function nonEmptyText(t) {
-1 12683 return !!text.sanitize(t);
-1 12684 }
-1 12685 text.accessibleText = function(element, inLabelledByContext) {
-1 12686 var accessibleNameComputation;
-1 12687 var encounteredNodes = [];
-1 12688 function getInnerText(element, inLabelledByContext, inControlContext) {
-1 12689 var nodes = element.childNodes;
-1 12690 var returnText = '';
-1 12691 var node;
-1 12692 for (var i = 0; i < nodes.length; i++) {
-1 12693 node = nodes[i];
-1 12694 if (node.nodeType === 3) {
-1 12695 returnText += node.textContent;
-1 12696 } else if (node.nodeType === 1) {
-1 12697 if (phrasingElements.indexOf(node.nodeName.toUpperCase()) === -1) {
-1 12698 returnText += ' ';
-1 12699 }
-1 12700 returnText += accessibleNameComputation(nodes[i], inLabelledByContext, inControlContext);
-1 12701 }
-1 12702 }
-1 12703 return returnText;
-1 12704 }
-1 12705 function getLayoutTableText(element) {
-1 12706 if (!axe.commons.table.isDataTable(element) && axe.commons.table.getAllCells(element).length === 1) {
-1 12707 return getInnerText(element, false, false).trim();
-1 12708 }
-1 12709 return '';
-1 12710 }
-1 12711 function checkNative(element, inLabelledByContext, inControlContext) {
-1 12712 var returnText = '';
-1 12713 var nodeName = element.nodeName.toUpperCase();
-1 12714 if (shouldCheckSubtree(element)) {
-1 12715 returnText = getInnerText(element, false, false) || '';
-1 12716 if (nonEmptyText(returnText)) {
-1 12717 return returnText;
-1 12718 }
-1 12719 }
-1 12720 if (nodeName === 'FIGURE') {
-1 12721 returnText = checkDescendant(element, 'figcaption');
-1 12722 if (nonEmptyText(returnText)) {
-1 12723 return returnText;
-1 12724 }
-1 12725 }
-1 12726 if (nodeName === 'TABLE') {
-1 12727 returnText = checkDescendant(element, 'caption');
-1 12728 if (nonEmptyText(returnText)) {
-1 12729 return returnText;
-1 12730 }
-1 12731 returnText = element.getAttribute('title') || element.getAttribute('summary') || getLayoutTableText(element) || '';
-1 12732 if (nonEmptyText(returnText)) {
-1 12733 return returnText;
-1 12734 }
-1 12735 }
-1 12736 if (shouldCheckAlt(element)) {
-1 12737 return element.getAttribute('alt') || '';
-1 12738 }
-1 12739 if (isInput(element) && !inControlContext) {
-1 12740 if (isButton(element)) {
-1 12741 return element.value || element.title || defaultButtonValues[element.type] || '';
-1 12742 }
-1 12743 var labelElement = findLabel(element);
-1 12744 if (labelElement) {
-1 12745 return accessibleNameComputation(labelElement, inLabelledByContext, true);
-1 12746 }
-1 12747 }
-1 12748 return '';
-1 12749 }
-1 12750 function checkARIA(element, inLabelledByContext, inControlContext) {
-1 12751 if (!inLabelledByContext && element.hasAttribute('aria-labelledby')) {
-1 12752 return text.sanitize(dom.idrefs(element, 'aria-labelledby').map(function(l) {
-1 12753 if (element === l) {
-1 12754 encounteredNodes.pop();
-1 12755 }
-1 12756 return accessibleNameComputation(l, true, element !== l);
-1 12757 }).join(' '));
-1 12758 }
-1 12759 if (!(inControlContext && isEmbeddedControl(element)) && element.hasAttribute('aria-label')) {
-1 12760 return text.sanitize(element.getAttribute('aria-label'));
-1 12761 }
-1 12762 return '';
-1 12763 }
-1 12764 accessibleNameComputation = function accessibleNameComputation(element, inLabelledByContext, inControlContext) {
-1 12765 'use strict';
-1 12766 var returnText;
-1 12767 if (element === null || encounteredNodes.indexOf(element) !== -1) {
-1 12768 return '';
-1 12769 } else if (!inLabelledByContext && !dom.isVisible(element, true)) {
-1 12770 return '';
-1 12771 }
-1 12772 encounteredNodes.push(element);
-1 12773 var role = element.getAttribute('role');
-1 12774 returnText = checkARIA(element, inLabelledByContext, inControlContext);
-1 12775 if (nonEmptyText(returnText)) {
-1 12776 return returnText;
-1 12777 }
-1 12778 returnText = checkNative(element, inLabelledByContext, inControlContext);
-1 12779 if (nonEmptyText(returnText)) {
-1 12780 return returnText;
-1 12781 }
-1 12782 if (inControlContext) {
-1 12783 returnText = formValueText(element);
-1 12784 if (nonEmptyText(returnText)) {
-1 12785 return returnText;
-1 12786 }
-1 12787 }
-1 12788 if (!shouldNeverCheckSubtree(element) && (!role || aria.getRolesWithNameFromContents().indexOf(role) !== -1)) {
-1 12789 returnText = getInnerText(element, inLabelledByContext, inControlContext);
-1 12790 if (nonEmptyText(returnText)) {
-1 12791 return returnText;
-1 12792 }
-1 12793 }
-1 12794 if (element.hasAttribute('title')) {
-1 12795 return element.getAttribute('title');
-1 12796 }
-1 12797 return '';
-1 12798 };
-1 12799 return text.sanitize(accessibleNameComputation(element, inLabelledByContext));
-1 12800 };
-1 12801 text.label = function(node) {
-1 12802 var ref, candidate;
-1 12803 candidate = aria.label(node);
-1 12804 if (candidate) {
-1 12805 return candidate;
-1 12806 }
-1 12807 if (node.getAttribute('id')) {
-1 12808 var id = axe.commons.utils.escapeSelector(node.getAttribute('id'));
-1 12809 ref = document.querySelector('label[for="' + id + '"]');
-1 12810 candidate = ref && text.visible(ref, true);
-1 12811 if (candidate) {
-1 12812 return candidate;
-1 12813 }
-1 12814 }
-1 12815 ref = dom.findUp(node, 'label');
-1 12816 candidate = ref && text.visible(ref, true);
-1 12817 if (candidate) {
-1 12818 return candidate;
-1 12819 }
-1 12820 return null;
-1 12821 };
-1 12822 text.sanitize = function(str) {
-1 12823 'use strict';
-1 12824 return str.replace(/\r\n/g, '\n').replace(/\u00A0/g, ' ').replace(/[\s]{2,}/g, ' ').trim();
-1 12825 };
-1 12826 text.visible = function(element, screenReader, noRecursing) {
-1 12827 'use strict';
-1 12828 var index, child, nodeValue, childNodes = element.childNodes, length = childNodes.length, result = '';
-1 12829 for (index = 0; index < length; index++) {
-1 12830 child = childNodes[index];
-1 12831 if (child.nodeType === 3) {
-1 12832 nodeValue = child.nodeValue;
-1 12833 if (nodeValue && dom.isVisible(element, screenReader)) {
-1 12834 result += child.nodeValue;
-1 12835 }
-1 12836 } else if (!noRecursing) {
-1 12837 result += text.visible(child, screenReader);
-1 12838 }
-1 12839 }
-1 12840 return text.sanitize(result);
-1 12841 };
-1 12842 axe.utils.toArray = function(thing) {
-1 12843 'use strict';
-1 12844 return Array.prototype.slice.call(thing);
-1 12845 };
-1 12846 axe.utils.tokenList = function(str) {
-1 12847 'use strict';
-1 12848 return str.trim().replace(/\s{2,}/g, ' ').split(' ');
-1 12849 };
-1 12850 var langs = [ 'aa', 'ab', 'ae', 'af', 'ak', 'am', 'an', 'ar', 'as', 'av', 'ay', 'az', 'ba', 'be', 'bg', 'bh', 'bi', 'bm', 'bn', 'bo', 'br', 'bs', 'ca', 'ce', 'ch', 'co', 'cr', 'cs', 'cu', 'cv', 'cy', 'da', 'de', 'dv', 'dz', 'ee', 'el', 'en', 'eo', 'es', 'et', 'eu', 'fa', 'ff', 'fi', 'fj', 'fo', 'fr', 'fy', 'ga', 'gd', 'gl', 'gn', 'gu', 'gv', 'ha', 'he', 'hi', 'ho', 'hr', 'ht', 'hu', 'hy', 'hz', 'ia', 'id', 'ie', 'ig', 'ii', 'ik', 'in', 'io', 'is', 'it', 'iu', 'iw', 'ja', 'ji', 'jv', 'jw', 'ka', 'kg', 'ki', 'kj', 'kk', 'kl', 'km', 'kn', 'ko', 'kr', 'ks', 'ku', 'kv', 'kw', 'ky', 'la', 'lb', 'lg', 'li', 'ln', 'lo', 'lt', 'lu', 'lv', 'mg', 'mh', 'mi', 'mk', 'ml', 'mn', 'mo', 'mr', 'ms', 'mt', 'my', 'na', 'nb', 'nd', 'ne', 'ng', 'nl', 'nn', 'no', 'nr', 'nv', 'ny', 'oc', 'oj', 'om', 'or', 'os', 'pa', 'pi', 'pl', 'ps', 'pt', 'qu', 'rm', 'rn', 'ro', 'ru', 'rw', 'sa', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sk', 'sl', 'sm', 'sn', 'so', 'sq', 'sr', 'ss', 'st', 'su', 'sv', 'sw', 'ta', 'te', 'tg', 'th', 'ti', 'tk', 'tl', 'tn', 'to', 'tr', 'ts', 'tt', 'tw', 'ty', 'ug', 'uk', 'ur', 'uz', 've', 'vi', 'vo', 'wa', 'wo', 'xh', 'yi', 'yo', 'za', 'zh', 'zu', 'aaa', 'aab', 'aac', 'aad', 'aae', 'aaf', 'aag', 'aah', 'aai', 'aak', 'aal', 'aam', 'aan', 'aao', 'aap', 'aaq', 'aas', 'aat', 'aau', 'aav', 'aaw', 'aax', 'aaz', 'aba', 'abb', 'abc', 'abd', 'abe', 'abf', 'abg', 'abh', 'abi', 'abj', 'abl', 'abm', 'abn', 'abo', 'abp', 'abq', 'abr', 'abs', 'abt', 'abu', 'abv', 'abw', 'abx', 'aby', 'abz', 'aca', 'acb', 'acd', 'ace', 'acf', 'ach', 'aci', 'ack', 'acl', 'acm', 'acn', 'acp', 'acq', 'acr', 'acs', 'act', 'acu', 'acv', 'acw', 'acx', 'acy', 'acz', 'ada', 'adb', 'add', 'ade', 'adf', 'adg', 'adh', 'adi', 'adj', 'adl', 'adn', 'ado', 'adp', 'adq', 'adr', 'ads', 'adt', 'adu', 'adw', 'adx', 'ady', 'adz', 'aea', 'aeb', 'aec', 'aed', 'aee', 'aek', 'ael', 'aem', 'aen', 'aeq', 'aer', 'aes', 'aeu', 'aew', 'aey', 'aez', 'afa', 'afb', 'afd', 'afe', 'afg', 'afh', 'afi', 'afk', 'afn', 'afo', 'afp', 'afs', 'aft', 'afu', 'afz', 'aga', 'agb', 'agc', 'agd', 'age', 'agf', 'agg', 'agh', 'agi', 'agj', 'agk', 'agl', 'agm', 'agn', 'ago', 'agp', 'agq', 'agr', 'ags', 'agt', 'agu', 'agv', 'agw', 'agx', 'agy', 'agz', 'aha', 'ahb', 'ahg', 'ahh', 'ahi', 'ahk', 'ahl', 'ahm', 'ahn', 'aho', 'ahp', 'ahr', 'ahs', 'aht', 'aia', 'aib', 'aic', 'aid', 'aie', 'aif', 'aig', 'aih', 'aii', 'aij', 'aik', 'ail', 'aim', 'ain', 'aio', 'aip', 'aiq', 'air', 'ais', 'ait', 'aiw', 'aix', 'aiy', 'aja', 'ajg', 'aji', 'ajn', 'ajp', 'ajt', 'aju', 'ajw', 'ajz', 'akb', 'akc', 'akd', 'ake', 'akf', 'akg', 'akh', 'aki', 'akj', 'akk', 'akl', 'akm', 'ako', 'akp', 'akq', 'akr', 'aks', 'akt', 'aku', 'akv', 'akw', 'akx', 'aky', 'akz', 'ala', 'alc', 'ald', 'ale', 'alf', 'alg', 'alh', 'ali', 'alj', 'alk', 'all', 'alm', 'aln', 'alo', 'alp', 'alq', 'alr', 'als', 'alt', 'alu', 'alv', 'alw', 'alx', 'aly', 'alz', 'ama', 'amb', 'amc', 'ame', 'amf', 'amg', 'ami', 'amj', 'amk', 'aml', 'amm', 'amn', 'amo', 'amp', 'amq', 'amr', 'ams', 'amt', 'amu', 'amv', 'amw', 'amx', 'amy', 'amz', 'ana', 'anb', 'anc', 'and', 'ane', 'anf', 'ang', 'anh', 'ani', 'anj', 'ank', 'anl', 'anm', 'ann', 'ano', 'anp', 'anq', 'anr', 'ans', 'ant', 'anu', 'anv', 'anw', 'anx', 'any', 'anz', 'aoa', 'aob', 'aoc', 'aod', 'aoe', 'aof', 'aog', 'aoh', 'aoi', 'aoj', 'aok', 'aol', 'aom', 'aon', 'aor', 'aos', 'aot', 'aou', 'aox', 'aoz', 'apa', 'apb', 'apc', 'apd', 'ape', 'apf', 'apg', 'aph', 'api', 'apj', 'apk', 'apl', 'apm', 'apn', 'apo', 'app', 'apq', 'apr', 'aps', 'apt', 'apu', 'apv', 'apw', 'apx', 'apy', 'apz', 'aqa', 'aqc', 'aqd', 'aqg', 'aql', 'aqm', 'aqn', 'aqp', 'aqr', 'aqt', 'aqz', 'arb', 'arc', 'ard', 'are', 'arh', 'ari', 'arj', 'ark', 'arl', 'arn', 'aro', 'arp', 'arq', 'arr', 'ars', 'art', 'aru', 'arv', 'arw', 'arx', 'ary', 'arz', 'asa', 'asb', 'asc', 'asd', 'ase', 'asf', 'asg', 'ash', 'asi', 'asj', 'ask', 'asl', 'asn', 'aso', 'asp', 'asq', 'asr', 'ass', 'ast', 'asu', 'asv', 'asw', 'asx', 'asy', 'asz', 'ata', 'atb', 'atc', 'atd', 'ate', 'atg', 'ath', 'ati', 'atj', 'atk', 'atl', 'atm', 'atn', 'ato', 'atp', 'atq', 'atr', 'ats', 'att', 'atu', 'atv', 'atw', 'atx', 'aty', 'atz', 'aua', 'aub', 'auc', 'aud', 'aue', 'auf', 'aug', 'auh', 'aui', 'auj', 'auk', 'aul', 'aum', 'aun', 'auo', 'aup', 'auq', 'aur', 'aus', 'aut', 'auu', 'auw', 'aux', 'auy', 'auz', 'avb', 'avd', 'avi', 'avk', 'avl', 'avm', 'avn', 'avo', 'avs', 'avt', 'avu', 'avv', 'awa', 'awb', 'awc', 'awd', 'awe', 'awg', 'awh', 'awi', 'awk', 'awm', 'awn', 'awo', 'awr', 'aws', 'awt', 'awu', 'awv', 'aww', 'awx', 'awy', 'axb', 'axe', 'axg', 'axk', 'axl', 'axm', 'axx', 'aya', 'ayb', 'ayc', 'ayd', 'aye', 'ayg', 'ayh', 'ayi', 'ayk', 'ayl', 'ayn', 'ayo', 'ayp', 'ayq', 'ayr', 'ays', 'ayt', 'ayu', 'ayx', 'ayy', 'ayz', 'aza', 'azb', 'azc', 'azd', 'azg', 'azj', 'azm', 'azn', 'azo', 'azt', 'azz', 'baa', 'bab', 'bac', 'bad', 'bae', 'baf', 'bag', 'bah', 'bai', 'baj', 'bal', 'ban', 'bao', 'bap', 'bar', 'bas', 'bat', 'bau', 'bav', 'baw', 'bax', 'bay', 'baz', 'bba', 'bbb', 'bbc', 'bbd', 'bbe', 'bbf', 'bbg', 'bbh', 'bbi', 'bbj', 'bbk', 'bbl', 'bbm', 'bbn', 'bbo', 'bbp', 'bbq', 'bbr', 'bbs', 'bbt', 'bbu', 'bbv', 'bbw', 'bbx', 'bby', 'bbz', 'bca', 'bcb', 'bcc', 'bcd', 'bce', 'bcf', 'bcg', 'bch', 'bci', 'bcj', 'bck', 'bcl', 'bcm', 'bcn', 'bco', 'bcp', 'bcq', 'bcr', 'bcs', 'bct', 'bcu', 'bcv', 'bcw', 'bcy', 'bcz', 'bda', 'bdb', 'bdc', 'bdd', 'bde', 'bdf', 'bdg', 'bdh', 'bdi', 'bdj', 'bdk', 'bdl', 'bdm', 'bdn', 'bdo', 'bdp', 'bdq', 'bdr', 'bds', 'bdt', 'bdu', 'bdv', 'bdw', 'bdx', 'bdy', 'bdz', 'bea', 'beb', 'bec', 'bed', 'bee', 'bef', 'beg', 'beh', 'bei', 'bej', 'bek', 'bem', 'beo', 'bep', 'beq', 'ber', 'bes', 'bet', 'beu', 'bev', 'bew', 'bex', 'bey', 'bez', 'bfa', 'bfb', 'bfc', 'bfd', 'bfe', 'bff', 'bfg', 'bfh', 'bfi', 'bfj', 'bfk', 'bfl', 'bfm', 'bfn', 'bfo', 'bfp', 'bfq', 'bfr', 'bfs', 'bft', 'bfu', 'bfw', 'bfx', 'bfy', 'bfz', 'bga', 'bgb', 'bgc', 'bgd', 'bge', 'bgf', 'bgg', 'bgi', 'bgj', 'bgk', 'bgl', 'bgm', 'bgn', 'bgo', 'bgp', 'bgq', 'bgr', 'bgs', 'bgt', 'bgu', 'bgv', 'bgw', 'bgx', 'bgy', 'bgz', 'bha', 'bhb', 'bhc', 'bhd', 'bhe', 'bhf', 'bhg', 'bhh', 'bhi', 'bhj', 'bhk', 'bhl', 'bhm', 'bhn', 'bho', 'bhp', 'bhq', 'bhr', 'bhs', 'bht', 'bhu', 'bhv', 'bhw', 'bhx', 'bhy', 'bhz', 'bia', 'bib', 'bic', 'bid', 'bie', 'bif', 'big', 'bij', 'bik', 'bil', 'bim', 'bin', 'bio', 'bip', 'biq', 'bir', 'bit', 'biu', 'biv', 'biw', 'bix', 'biy', 'biz', 'bja', 'bjb', 'bjc', 'bjd', 'bje', 'bjf', 'bjg', 'bjh', 'bji', 'bjj', 'bjk', 'bjl', 'bjm', 'bjn', 'bjo', 'bjp', 'bjq', 'bjr', 'bjs', 'bjt', 'bju', 'bjv', 'bjw', 'bjx', 'bjy', 'bjz', 'bka', 'bkb', 'bkc', 'bkd', 'bkf', 'bkg', 'bkh', 'bki', 'bkj', 'bkk', 'bkl', 'bkm', 'bkn', 'bko', 'bkp', 'bkq', 'bkr', 'bks', 'bkt', 'bku', 'bkv', 'bkw', 'bkx', 'bky', 'bkz', 'bla', 'blb', 'blc', 'bld', 'ble', 'blf', 'blg', 'blh', 'bli', 'blj', 'blk', 'bll', 'blm', 'bln', 'blo', 'blp', 'blq', 'blr', 'bls', 'blt', 'blv', 'blw', 'blx', 'bly', 'blz', 'bma', 'bmb', 'bmc', 'bmd', 'bme', 'bmf', 'bmg', 'bmh', 'bmi', 'bmj', 'bmk', 'bml', 'bmm', 'bmn', 'bmo', 'bmp', 'bmq', 'bmr', 'bms', 'bmt', 'bmu', 'bmv', 'bmw', 'bmx', 'bmy', 'bmz', 'bna', 'bnb', 'bnc', 'bnd', 'bne', 'bnf', 'bng', 'bni', 'bnj', 'bnk', 'bnl', 'bnm', 'bnn', 'bno', 'bnp', 'bnq', 'bnr', 'bns', 'bnt', 'bnu', 'bnv', 'bnw', 'bnx', 'bny', 'bnz', 'boa', 'bob', 'boe', 'bof', 'bog', 'boh', 'boi', 'boj', 'bok', 'bol', 'bom', 'bon', 'boo', 'bop', 'boq', 'bor', 'bot', 'bou', 'bov', 'bow', 'box', 'boy', 'boz', 'bpa', 'bpb', 'bpd', 'bpg', 'bph', 'bpi', 'bpj', 'bpk', 'bpl', 'bpm', 'bpn', 'bpo', 'bpp', 'bpq', 'bpr', 'bps', 'bpt', 'bpu', 'bpv', 'bpw', 'bpx', 'bpy', 'bpz', 'bqa', 'bqb', 'bqc', 'bqd', 'bqf', 'bqg', 'bqh', 'bqi', 'bqj', 'bqk', 'bql', 'bqm', 'bqn', 'bqo', 'bqp', 'bqq', 'bqr', 'bqs', 'bqt', 'bqu', 'bqv', 'bqw', 'bqx', 'bqy', 'bqz', 'bra', 'brb', 'brc', 'brd', 'brf', 'brg', 'brh', 'bri', 'brj', 'brk', 'brl', 'brm', 'brn', 'bro', 'brp', 'brq', 'brr', 'brs', 'brt', 'bru', 'brv', 'brw', 'brx', 'bry', 'brz', 'bsa', 'bsb', 'bsc', 'bse', 'bsf', 'bsg', 'bsh', 'bsi', 'bsj', 'bsk', 'bsl', 'bsm', 'bsn', 'bso', 'bsp', 'bsq', 'bsr', 'bss', 'bst', 'bsu', 'bsv', 'bsw', 'bsx', 'bsy', 'bta', 'btb', 'btc', 'btd', 'bte', 'btf', 'btg', 'bth', 'bti', 'btj', 'btk', 'btl', 'btm', 'btn', 'bto', 'btp', 'btq', 'btr', 'bts', 'btt', 'btu', 'btv', 'btw', 'btx', 'bty', 'btz', 'bua', 'bub', 'buc', 'bud', 'bue', 'buf', 'bug', 'buh', 'bui', 'buj', 'buk', 'bum', 'bun', 'buo', 'bup', 'buq', 'bus', 'but', 'buu', 'buv', 'buw', 'bux', 'buy', 'buz', 'bva', 'bvb', 'bvc', 'bvd', 'bve', 'bvf', 'bvg', 'bvh', 'bvi', 'bvj', 'bvk', 'bvl', 'bvm', 'bvn', 'bvo', 'bvp', 'bvq', 'bvr', 'bvt', 'bvu', 'bvv', 'bvw', 'bvx', 'bvy', 'bvz', 'bwa', 'bwb', 'bwc', 'bwd', 'bwe', 'bwf', 'bwg', 'bwh', 'bwi', 'bwj', 'bwk', 'bwl', 'bwm', 'bwn', 'bwo', 'bwp', 'bwq', 'bwr', 'bws', 'bwt', 'bwu', 'bww', 'bwx', 'bwy', 'bwz', 'bxa', 'bxb', 'bxc', 'bxd', 'bxe', 'bxf', 'bxg', 'bxh', 'bxi', 'bxj', 'bxk', 'bxl', 'bxm', 'bxn', 'bxo', 'bxp', 'bxq', 'bxr', 'bxs', 'bxu', 'bxv', 'bxw', 'bxx', 'bxz', 'bya', 'byb', 'byc', 'byd', 'bye', 'byf', 'byg', 'byh', 'byi', 'byj', 'byk', 'byl', 'bym', 'byn', 'byo', 'byp', 'byq', 'byr', 'bys', 'byt', 'byv', 'byw', 'byx', 'byy', 'byz', 'bza', 'bzb', 'bzc', 'bzd', 'bze', 'bzf', 'bzg', 'bzh', 'bzi', 'bzj', 'bzk', 'bzl', 'bzm', 'bzn', 'bzo', 'bzp', 'bzq', 'bzr', 'bzs', 'bzt', 'bzu', 'bzv', 'bzw', 'bzx', 'bzy', 'bzz', 'caa', 'cab', 'cac', 'cad', 'cae', 'caf', 'cag', 'cah', 'cai', 'caj', 'cak', 'cal', 'cam', 'can', 'cao', 'cap', 'caq', 'car', 'cas', 'cau', 'cav', 'caw', 'cax', 'cay', 'caz', 'cba', 'cbb', 'cbc', 'cbd', 'cbe', 'cbg', 'cbh', 'cbi', 'cbj', 'cbk', 'cbl', 'cbn', 'cbo', 'cbq', 'cbr', 'cbs', 'cbt', 'cbu', 'cbv', 'cbw', 'cby', 'cca', 'ccc', 'ccd', 'cce', 'ccg', 'cch', 'ccj', 'ccl', 'ccm', 'ccn', 'cco', 'ccp', 'ccq', 'ccr', 'ccs', 'cda', 'cdc', 'cdd', 'cde', 'cdf', 'cdg', 'cdh', 'cdi', 'cdj', 'cdm', 'cdn', 'cdo', 'cdr', 'cds', 'cdy', 'cdz', 'cea', 'ceb', 'ceg', 'cek', 'cel', 'cen', 'cet', 'cfa', 'cfd', 'cfg', 'cfm', 'cga', 'cgc', 'cgg', 'cgk', 'chb', 'chc', 'chd', 'chf', 'chg', 'chh', 'chj', 'chk', 'chl', 'chm', 'chn', 'cho', 'chp', 'chq', 'chr', 'cht', 'chw', 'chx', 'chy', 'chz', 'cia', 'cib', 'cic', 'cid', 'cie', 'cih', 'cik', 'cim', 'cin', 'cip', 'cir', 'ciw', 'ciy', 'cja', 'cje', 'cjh', 'cji', 'cjk', 'cjm', 'cjn', 'cjo', 'cjp', 'cjr', 'cjs', 'cjv', 'cjy', 'cka', 'ckb', 'ckh', 'ckl', 'ckn', 'cko', 'ckq', 'ckr', 'cks', 'ckt', 'cku', 'ckv', 'ckx', 'cky', 'ckz', 'cla', 'clc', 'cld', 'cle', 'clh', 'cli', 'clj', 'clk', 'cll', 'clm', 'clo', 'clt', 'clu', 'clw', 'cly', 'cma', 'cmc', 'cme', 'cmg', 'cmi', 'cmk', 'cml', 'cmm', 'cmn', 'cmo', 'cmr', 'cms', 'cmt', 'cna', 'cnb', 'cnc', 'cng', 'cnh', 'cni', 'cnk', 'cnl', 'cno', 'cns', 'cnt', 'cnu', 'cnw', 'cnx', 'coa', 'cob', 'coc', 'cod', 'coe', 'cof', 'cog', 'coh', 'coj', 'cok', 'col', 'com', 'con', 'coo', 'cop', 'coq', 'cot', 'cou', 'cov', 'cow', 'cox', 'coy', 'coz', 'cpa', 'cpb', 'cpc', 'cpe', 'cpf', 'cpg', 'cpi', 'cpn', 'cpo', 'cpp', 'cps', 'cpu', 'cpx', 'cpy', 'cqd', 'cqu', 'cra', 'crb', 'crc', 'crd', 'crf', 'crg', 'crh', 'cri', 'crj', 'crk', 'crl', 'crm', 'crn', 'cro', 'crp', 'crq', 'crr', 'crs', 'crt', 'crv', 'crw', 'crx', 'cry', 'crz', 'csa', 'csb', 'csc', 'csd', 'cse', 'csf', 'csg', 'csh', 'csi', 'csj', 'csk', 'csl', 'csm', 'csn', 'cso', 'csq', 'csr', 'css', 'cst', 'csu', 'csv', 'csw', 'csy', 'csz', 'cta', 'ctc', 'ctd', 'cte', 'ctg', 'cth', 'ctl', 'ctm', 'ctn', 'cto', 'ctp', 'cts', 'ctt', 'ctu', 'ctz', 'cua', 'cub', 'cuc', 'cug', 'cuh', 'cui', 'cuj', 'cuk', 'cul', 'cum', 'cuo', 'cup', 'cuq', 'cur', 'cus', 'cut', 'cuu', 'cuv', 'cuw', 'cux', 'cvg', 'cvn', 'cwa', 'cwb', 'cwd', 'cwe', 'cwg', 'cwt', 'cya', 'cyb', 'cyo', 'czh', 'czk', 'czn', 'czo', 'czt', 'daa', 'dac', 'dad', 'dae', 'daf', 'dag', 'dah', 'dai', 'daj', 'dak', 'dal', 'dam', 'dao', 'dap', 'daq', 'dar', 'das', 'dau', 'dav', 'daw', 'dax', 'day', 'daz', 'dba', 'dbb', 'dbd', 'dbe', 'dbf', 'dbg', 'dbi', 'dbj', 'dbl', 'dbm', 'dbn', 'dbo', 'dbp', 'dbq', 'dbr', 'dbt', 'dbu', 'dbv', 'dbw', 'dby', 'dcc', 'dcr', 'dda', 'ddd', 'dde', 'ddg', 'ddi', 'ddj', 'ddn', 'ddo', 'ddr', 'dds', 'ddw', 'dec', 'ded', 'dee', 'def', 'deg', 'deh', 'dei', 'dek', 'del', 'dem', 'den', 'dep', 'deq', 'der', 'des', 'dev', 'dez', 'dga', 'dgb', 'dgc', 'dgd', 'dge', 'dgg', 'dgh', 'dgi', 'dgk', 'dgl', 'dgn', 'dgo', 'dgr', 'dgs', 'dgt', 'dgu', 'dgw', 'dgx', 'dgz', 'dha', 'dhd', 'dhg', 'dhi', 'dhl', 'dhm', 'dhn', 'dho', 'dhr', 'dhs', 'dhu', 'dhv', 'dhw', 'dhx', 'dia', 'dib', 'dic', 'did', 'dif', 'dig', 'dih', 'dii', 'dij', 'dik', 'dil', 'dim', 'din', 'dio', 'dip', 'diq', 'dir', 'dis', 'dit', 'diu', 'diw', 'dix', 'diy', 'diz', 'dja', 'djb', 'djc', 'djd', 'dje', 'djf', 'dji', 'djj', 'djk', 'djl', 'djm', 'djn', 'djo', 'djr', 'dju', 'djw', 'dka', 'dkk', 'dkl', 'dkr', 'dks', 'dkx', 'dlg', 'dlk', 'dlm', 'dln', 'dma', 'dmb', 'dmc', 'dmd', 'dme', 'dmg', 'dmk', 'dml', 'dmm', 'dmn', 'dmo', 'dmr', 'dms', 'dmu', 'dmv', 'dmw', 'dmx', 'dmy', 'dna', 'dnd', 'dne', 'dng', 'dni', 'dnj', 'dnk', 'dnn', 'dnr', 'dnt', 'dnu', 'dnv', 'dnw', 'dny', 'doa', 'dob', 'doc', 'doe', 'dof', 'doh', 'doi', 'dok', 'dol', 'don', 'doo', 'dop', 'doq', 'dor', 'dos', 'dot', 'dov', 'dow', 'dox', 'doy', 'doz', 'dpp', 'dra', 'drb', 'drc', 'drd', 'dre', 'drg', 'drh', 'dri', 'drl', 'drn', 'dro', 'drq', 'drr', 'drs', 'drt', 'dru', 'drw', 'dry', 'dsb', 'dse', 'dsh', 'dsi', 'dsl', 'dsn', 'dso', 'dsq', 'dta', 'dtb', 'dtd', 'dth', 'dti', 'dtk', 'dtm', 'dtn', 'dto', 'dtp', 'dtr', 'dts', 'dtt', 'dtu', 'dty', 'dua', 'dub', 'duc', 'dud', 'due', 'duf', 'dug', 'duh', 'dui', 'duj', 'duk', 'dul', 'dum', 'dun', 'duo', 'dup', 'duq', 'dur', 'dus', 'duu', 'duv', 'duw', 'dux', 'duy', 'duz', 'dva', 'dwa', 'dwl', 'dwr', 'dws', 'dwu', 'dww', 'dwy', 'dya', 'dyb', 'dyd', 'dyg', 'dyi', 'dym', 'dyn', 'dyo', 'dyu', 'dyy', 'dza', 'dzd', 'dze', 'dzg', 'dzl', 'dzn', 'eaa', 'ebg', 'ebk', 'ebo', 'ebr', 'ebu', 'ecr', 'ecs', 'ecy', 'eee', 'efa', 'efe', 'efi', 'ega', 'egl', 'ego', 'egx', 'egy', 'ehu', 'eip', 'eit', 'eiv', 'eja', 'eka', 'ekc', 'eke', 'ekg', 'eki', 'ekk', 'ekl', 'ekm', 'eko', 'ekp', 'ekr', 'eky', 'ele', 'elh', 'eli', 'elk', 'elm', 'elo', 'elp', 'elu', 'elx', 'ema', 'emb', 'eme', 'emg', 'emi', 'emk', 'emm', 'emn', 'emo', 'emp', 'ems', 'emu', 'emw', 'emx', 'emy', 'ena', 'enb', 'enc', 'end', 'enf', 'enh', 'enl', 'enm', 'enn', 'eno', 'enq', 'enr', 'enu', 'env', 'enw', 'enx', 'eot', 'epi', 'era', 'erg', 'erh', 'eri', 'erk', 'ero', 'err', 'ers', 'ert', 'erw', 'ese', 'esg', 'esh', 'esi', 'esk', 'esl', 'esm', 'esn', 'eso', 'esq', 'ess', 'esu', 'esx', 'esy', 'etb', 'etc', 'eth', 'etn', 'eto', 'etr', 'ets', 'ett', 'etu', 'etx', 'etz', 'euq', 'eve', 'evh', 'evn', 'ewo', 'ext', 'eya', 'eyo', 'eza', 'eze', 'faa', 'fab', 'fad', 'faf', 'fag', 'fah', 'fai', 'faj', 'fak', 'fal', 'fam', 'fan', 'fap', 'far', 'fat', 'fau', 'fax', 'fay', 'faz', 'fbl', 'fcs', 'fer', 'ffi', 'ffm', 'fgr', 'fia', 'fie', 'fil', 'fip', 'fir', 'fit', 'fiu', 'fiw', 'fkk', 'fkv', 'fla', 'flh', 'fli', 'fll', 'fln', 'flr', 'fly', 'fmp', 'fmu', 'fnb', 'fng', 'fni', 'fod', 'foi', 'fom', 'fon', 'for', 'fos', 'fox', 'fpe', 'fqs', 'frc', 'frd', 'frk', 'frm', 'fro', 'frp', 'frq', 'frr', 'frs', 'frt', 'fse', 'fsl', 'fss', 'fub', 'fuc', 'fud', 'fue', 'fuf', 'fuh', 'fui', 'fuj', 'fum', 'fun', 'fuq', 'fur', 'fut', 'fuu', 'fuv', 'fuy', 'fvr', 'fwa', 'fwe', 'gaa', 'gab', 'gac', 'gad', 'gae', 'gaf', 'gag', 'gah', 'gai', 'gaj', 'gak', 'gal', 'gam', 'gan', 'gao', 'gap', 'gaq', 'gar', 'gas', 'gat', 'gau', 'gav', 'gaw', 'gax', 'gay', 'gaz', 'gba', 'gbb', 'gbc', 'gbd', 'gbe', 'gbf', 'gbg', 'gbh', 'gbi', 'gbj', 'gbk', 'gbl', 'gbm', 'gbn', 'gbo', 'gbp', 'gbq', 'gbr', 'gbs', 'gbu', 'gbv', 'gbw', 'gbx', 'gby', 'gbz', 'gcc', 'gcd', 'gce', 'gcf', 'gcl', 'gcn', 'gcr', 'gct', 'gda', 'gdb', 'gdc', 'gdd', 'gde', 'gdf', 'gdg', 'gdh', 'gdi', 'gdj', 'gdk', 'gdl', 'gdm', 'gdn', 'gdo', 'gdq', 'gdr', 'gds', 'gdt', 'gdu', 'gdx', 'gea', 'geb', 'gec', 'ged', 'geg', 'geh', 'gei', 'gej', 'gek', 'gel', 'gem', 'geq', 'ges', 'gev', 'gew', 'gex', 'gey', 'gez', 'gfk', 'gft', 'gfx', 'gga', 'ggb', 'ggd', 'gge', 'ggg', 'ggk', 'ggl', 'ggn', 'ggo', 'ggr', 'ggt', 'ggu', 'ggw', 'gha', 'ghc', 'ghe', 'ghh', 'ghk', 'ghl', 'ghn', 'gho', 'ghr', 'ghs', 'ght', 'gia', 'gib', 'gic', 'gid', 'gie', 'gig', 'gih', 'gil', 'gim', 'gin', 'gio', 'gip', 'giq', 'gir', 'gis', 'git', 'giu', 'giw', 'gix', 'giy', 'giz', 'gji', 'gjk', 'gjm', 'gjn', 'gjr', 'gju', 'gka', 'gke', 'gkn', 'gko', 'gkp', 'gku', 'glc', 'gld', 'glh', 'gli', 'glj', 'glk', 'gll', 'glo', 'glr', 'glu', 'glw', 'gly', 'gma', 'gmb', 'gmd', 'gme', 'gmg', 'gmh', 'gml', 'gmm', 'gmn', 'gmq', 'gmu', 'gmv', 'gmw', 'gmx', 'gmy', 'gmz', 'gna', 'gnb', 'gnc', 'gnd', 'gne', 'gng', 'gnh', 'gni', 'gnk', 'gnl', 'gnm', 'gnn', 'gno', 'gnq', 'gnr', 'gnt', 'gnu', 'gnw', 'gnz', 'goa', 'gob', 'goc', 'god', 'goe', 'gof', 'gog', 'goh', 'goi', 'goj', 'gok', 'gol', 'gom', 'gon', 'goo', 'gop', 'goq', 'gor', 'gos', 'got', 'gou', 'gow', 'gox', 'goy', 'goz', 'gpa', 'gpe', 'gpn', 'gqa', 'gqi', 'gqn', 'gqr', 'gqu', 'gra', 'grb', 'grc', 'grd', 'grg', 'grh', 'gri', 'grj', 'grk', 'grm', 'gro', 'grq', 'grr', 'grs', 'grt', 'gru', 'grv', 'grw', 'grx', 'gry', 'grz', 'gse', 'gsg', 'gsl', 'gsm', 'gsn', 'gso', 'gsp', 'gss', 'gsw', 'gta', 'gti', 'gtu', 'gua', 'gub', 'guc', 'gud', 'gue', 'guf', 'gug', 'guh', 'gui', 'guk', 'gul', 'gum', 'gun', 'guo', 'gup', 'guq', 'gur', 'gus', 'gut', 'guu', 'guv', 'guw', 'gux', 'guz', 'gva', 'gvc', 'gve', 'gvf', 'gvj', 'gvl', 'gvm', 'gvn', 'gvo', 'gvp', 'gvr', 'gvs', 'gvy', 'gwa', 'gwb', 'gwc', 'gwd', 'gwe', 'gwf', 'gwg', 'gwi', 'gwj', 'gwm', 'gwn', 'gwr', 'gwt', 'gwu', 'gww', 'gwx', 'gxx', 'gya', 'gyb', 'gyd', 'gye', 'gyf', 'gyg', 'gyi', 'gyl', 'gym', 'gyn', 'gyr', 'gyy', 'gza', 'gzi', 'gzn', 'haa', 'hab', 'hac', 'had', 'hae', 'haf', 'hag', 'hah', 'hai', 'haj', 'hak', 'hal', 'ham', 'han', 'hao', 'hap', 'haq', 'har', 'has', 'hav', 'haw', 'hax', 'hay', 'haz', 'hba', 'hbb', 'hbn', 'hbo', 'hbu', 'hca', 'hch', 'hdn', 'hds', 'hdy', 'hea', 'hed', 'heg', 'heh', 'hei', 'hem', 'hgm', 'hgw', 'hhi', 'hhr', 'hhy', 'hia', 'hib', 'hid', 'hif', 'hig', 'hih', 'hii', 'hij', 'hik', 'hil', 'him', 'hio', 'hir', 'hit', 'hiw', 'hix', 'hji', 'hka', 'hke', 'hkk', 'hks', 'hla', 'hlb', 'hld', 'hle', 'hlt', 'hlu', 'hma', 'hmb', 'hmc', 'hmd', 'hme', 'hmf', 'hmg', 'hmh', 'hmi', 'hmj', 'hmk', 'hml', 'hmm', 'hmn', 'hmp', 'hmq', 'hmr', 'hms', 'hmt', 'hmu', 'hmv', 'hmw', 'hmx', 'hmy', 'hmz', 'hna', 'hnd', 'hne', 'hnh', 'hni', 'hnj', 'hnn', 'hno', 'hns', 'hnu', 'hoa', 'hob', 'hoc', 'hod', 'hoe', 'hoh', 'hoi', 'hoj', 'hok', 'hol', 'hom', 'hoo', 'hop', 'hor', 'hos', 'hot', 'hov', 'how', 'hoy', 'hoz', 'hpo', 'hps', 'hra', 'hrc', 'hre', 'hrk', 'hrm', 'hro', 'hrp', 'hrr', 'hrt', 'hru', 'hrw', 'hrx', 'hrz', 'hsb', 'hsh', 'hsl', 'hsn', 'hss', 'hti', 'hto', 'hts', 'htu', 'htx', 'hub', 'huc', 'hud', 'hue', 'huf', 'hug', 'huh', 'hui', 'huj', 'huk', 'hul', 'hum', 'huo', 'hup', 'huq', 'hur', 'hus', 'hut', 'huu', 'huv', 'huw', 'hux', 'huy', 'huz', 'hvc', 'hve', 'hvk', 'hvn', 'hvv', 'hwa', 'hwc', 'hwo', 'hya', 'hyx', 'iai', 'ian', 'iap', 'iar', 'iba', 'ibb', 'ibd', 'ibe', 'ibg', 'ibh', 'ibi', 'ibl', 'ibm', 'ibn', 'ibr', 'ibu', 'iby', 'ica', 'ich', 'icl', 'icr', 'ida', 'idb', 'idc', 'idd', 'ide', 'idi', 'idr', 'ids', 'idt', 'idu', 'ifa', 'ifb', 'ife', 'iff', 'ifk', 'ifm', 'ifu', 'ify', 'igb', 'ige', 'igg', 'igl', 'igm', 'ign', 'igo', 'igs', 'igw', 'ihb', 'ihi', 'ihp', 'ihw', 'iin', 'iir', 'ijc', 'ije', 'ijj', 'ijn', 'ijo', 'ijs', 'ike', 'iki', 'ikk', 'ikl', 'iko', 'ikp', 'ikr', 'iks', 'ikt', 'ikv', 'ikw', 'ikx', 'ikz', 'ila', 'ilb', 'ilg', 'ili', 'ilk', 'ill', 'ilm', 'ilo', 'ilp', 'ils', 'ilu', 'ilv', 'ilw', 'ima', 'ime', 'imi', 'iml', 'imn', 'imo', 'imr', 'ims', 'imy', 'inb', 'inc', 'ine', 'ing', 'inh', 'inj', 'inl', 'inm', 'inn', 'ino', 'inp', 'ins', 'int', 'inz', 'ior', 'iou', 'iow', 'ipi', 'ipo', 'iqu', 'iqw', 'ira', 'ire', 'irh', 'iri', 'irk', 'irn', 'iro', 'irr', 'iru', 'irx', 'iry', 'isa', 'isc', 'isd', 'ise', 'isg', 'ish', 'isi', 'isk', 'ism', 'isn', 'iso', 'isr', 'ist', 'isu', 'itb', 'itc', 'itd', 'ite', 'iti', 'itk', 'itl', 'itm', 'ito', 'itr', 'its', 'itt', 'itv', 'itw', 'itx', 'ity', 'itz', 'ium', 'ivb', 'ivv', 'iwk', 'iwm', 'iwo', 'iws', 'ixc', 'ixl', 'iya', 'iyo', 'iyx', 'izh', 'izi', 'izr', 'izz', 'jaa', 'jab', 'jac', 'jad', 'jae', 'jaf', 'jah', 'jaj', 'jak', 'jal', 'jam', 'jan', 'jao', 'jaq', 'jar', 'jas', 'jat', 'jau', 'jax', 'jay', 'jaz', 'jbe', 'jbi', 'jbj', 'jbk', 'jbn', 'jbo', 'jbr', 'jbt', 'jbu', 'jbw', 'jcs', 'jct', 'jda', 'jdg', 'jdt', 'jeb', 'jee', 'jeg', 'jeh', 'jei', 'jek', 'jel', 'jen', 'jer', 'jet', 'jeu', 'jgb', 'jge', 'jgk', 'jgo', 'jhi', 'jhs', 'jia', 'jib', 'jic', 'jid', 'jie', 'jig', 'jih', 'jii', 'jil', 'jim', 'jio', 'jiq', 'jit', 'jiu', 'jiv', 'jiy', 'jje', 'jjr', 'jka', 'jkm', 'jko', 'jkp', 'jkr', 'jku', 'jle', 'jls', 'jma', 'jmb', 'jmc', 'jmd', 'jmi', 'jml', 'jmn', 'jmr', 'jms', 'jmw', 'jmx', 'jna', 'jnd', 'jng', 'jni', 'jnj', 'jnl', 'jns', 'job', 'jod', 'jog', 'jor', 'jos', 'jow', 'jpa', 'jpr', 'jpx', 'jqr', 'jra', 'jrb', 'jrr', 'jrt', 'jru', 'jsl', 'jua', 'jub', 'juc', 'jud', 'juh', 'jui', 'juk', 'jul', 'jum', 'jun', 'juo', 'jup', 'jur', 'jus', 'jut', 'juu', 'juw', 'juy', 'jvd', 'jvn', 'jwi', 'jya', 'jye', 'jyy', 'kaa', 'kab', 'kac', 'kad', 'kae', 'kaf', 'kag', 'kah', 'kai', 'kaj', 'kak', 'kam', 'kao', 'kap', 'kaq', 'kar', 'kav', 'kaw', 'kax', 'kay', 'kba', 'kbb', 'kbc', 'kbd', 'kbe', 'kbf', 'kbg', 'kbh', 'kbi', 'kbj', 'kbk', 'kbl', 'kbm', 'kbn', 'kbo', 'kbp', 'kbq', 'kbr', 'kbs', 'kbt', 'kbu', 'kbv', 'kbw', 'kbx', 'kby', 'kbz', 'kca', 'kcb', 'kcc', 'kcd', 'kce', 'kcf', 'kcg', 'kch', 'kci', 'kcj', 'kck', 'kcl', 'kcm', 'kcn', 'kco', 'kcp', 'kcq', 'kcr', 'kcs', 'kct', 'kcu', 'kcv', 'kcw', 'kcx', 'kcy', 'kcz', 'kda', 'kdc', 'kdd', 'kde', 'kdf', 'kdg', 'kdh', 'kdi', 'kdj', 'kdk', 'kdl', 'kdm', 'kdn', 'kdo', 'kdp', 'kdq', 'kdr', 'kdt', 'kdu', 'kdv', 'kdw', 'kdx', 'kdy', 'kdz', 'kea', 'keb', 'kec', 'ked', 'kee', 'kef', 'keg', 'keh', 'kei', 'kej', 'kek', 'kel', 'kem', 'ken', 'keo', 'kep', 'keq', 'ker', 'kes', 'ket', 'keu', 'kev', 'kew', 'kex', 'key', 'kez', 'kfa', 'kfb', 'kfc', 'kfd', 'kfe', 'kff', 'kfg', 'kfh', 'kfi', 'kfj', 'kfk', 'kfl', 'kfm', 'kfn', 'kfo', 'kfp', 'kfq', 'kfr', 'kfs', 'kft', 'kfu', 'kfv', 'kfw', 'kfx', 'kfy', 'kfz', 'kga', 'kgb', 'kgc', 'kgd', 'kge', 'kgf', 'kgg', 'kgh', 'kgi', 'kgj', 'kgk', 'kgl', 'kgm', 'kgn', 'kgo', 'kgp', 'kgq', 'kgr', 'kgs', 'kgt', 'kgu', 'kgv', 'kgw', 'kgx', 'kgy', 'kha', 'khb', 'khc', 'khd', 'khe', 'khf', 'khg', 'khh', 'khi', 'khj', 'khk', 'khl', 'khn', 'kho', 'khp', 'khq', 'khr', 'khs', 'kht', 'khu', 'khv', 'khw', 'khx', 'khy', 'khz', 'kia', 'kib', 'kic', 'kid', 'kie', 'kif', 'kig', 'kih', 'kii', 'kij', 'kil', 'kim', 'kio', 'kip', 'kiq', 'kis', 'kit', 'kiu', 'kiv', 'kiw', 'kix', 'kiy', 'kiz', 'kja', 'kjb', 'kjc', 'kjd', 'kje', 'kjf', 'kjg', 'kjh', 'kji', 'kjj', 'kjk', 'kjl', 'kjm', 'kjn', 'kjo', 'kjp', 'kjq', 'kjr', 'kjs', 'kjt', 'kju', 'kjv', 'kjx', 'kjy', 'kjz', 'kka', 'kkb', 'kkc', 'kkd', 'kke', 'kkf', 'kkg', 'kkh', 'kki', 'kkj', 'kkk', 'kkl', 'kkm', 'kkn', 'kko', 'kkp', 'kkq', 'kkr', 'kks', 'kkt', 'kku', 'kkv', 'kkw', 'kkx', 'kky', 'kkz', 'kla', 'klb', 'klc', 'kld', 'kle', 'klf', 'klg', 'klh', 'kli', 'klj', 'klk', 'kll', 'klm', 'kln', 'klo', 'klp', 'klq', 'klr', 'kls', 'klt', 'klu', 'klv', 'klw', 'klx', 'kly', 'klz', 'kma', 'kmb', 'kmc', 'kmd', 'kme', 'kmf', 'kmg', 'kmh', 'kmi', 'kmj', 'kmk', 'kml', 'kmm', 'kmn', 'kmo', 'kmp', 'kmq', 'kmr', 'kms', 'kmt', 'kmu', 'kmv', 'kmw', 'kmx', 'kmy', 'kmz', 'kna', 'knb', 'knc', 'knd', 'kne', 'knf', 'kng', 'kni', 'knj', 'knk', 'knl', 'knm', 'knn', 'kno', 'knp', 'knq', 'knr', 'kns', 'knt', 'knu', 'knv', 'knw', 'knx', 'kny', 'knz', 'koa', 'koc', 'kod', 'koe', 'kof', 'kog', 'koh', 'koi', 'koj', 'kok', 'kol', 'koo', 'kop', 'koq', 'kos', 'kot', 'kou', 'kov', 'kow', 'kox', 'koy', 'koz', 'kpa', 'kpb', 'kpc', 'kpd', 'kpe', 'kpf', 'kpg', 'kph', 'kpi', 'kpj', 'kpk', 'kpl', 'kpm', 'kpn', 'kpo', 'kpp', 'kpq', 'kpr', 'kps', 'kpt', 'kpu', 'kpv', 'kpw', 'kpx', 'kpy', 'kpz', 'kqa', 'kqb', 'kqc', 'kqd', 'kqe', 'kqf', 'kqg', 'kqh', 'kqi', 'kqj', 'kqk', 'kql', 'kqm', 'kqn', 'kqo', 'kqp', 'kqq', 'kqr', 'kqs', 'kqt', 'kqu', 'kqv', 'kqw', 'kqx', 'kqy', 'kqz', 'kra', 'krb', 'krc', 'krd', 'kre', 'krf', 'krh', 'kri', 'krj', 'krk', 'krl', 'krm', 'krn', 'kro', 'krp', 'krr', 'krs', 'krt', 'kru', 'krv', 'krw', 'krx', 'kry', 'krz', 'ksa', 'ksb', 'ksc', 'ksd', 'kse', 'ksf', 'ksg', 'ksh', 'ksi', 'ksj', 'ksk', 'ksl', 'ksm', 'ksn', 'kso', 'ksp', 'ksq', 'ksr', 'kss', 'kst', 'ksu', 'ksv', 'ksw', 'ksx', 'ksy', 'ksz', 'kta', 'ktb', 'ktc', 'ktd', 'kte', 'ktf', 'ktg', 'kth', 'kti', 'ktj', 'ktk', 'ktl', 'ktm', 'ktn', 'kto', 'ktp', 'ktq', 'ktr', 'kts', 'ktt', 'ktu', 'ktv', 'ktw', 'ktx', 'kty', 'ktz', 'kub', 'kuc', 'kud', 'kue', 'kuf', 'kug', 'kuh', 'kui', 'kuj', 'kuk', 'kul', 'kum', 'kun', 'kuo', 'kup', 'kuq', 'kus', 'kut', 'kuu', 'kuv', 'kuw', 'kux', 'kuy', 'kuz', 'kva', 'kvb', 'kvc', 'kvd', 'kve', 'kvf', 'kvg', 'kvh', 'kvi', 'kvj', 'kvk', 'kvl', 'kvm', 'kvn', 'kvo', 'kvp', 'kvq', 'kvr', 'kvs', 'kvt', 'kvu', 'kvv', 'kvw', 'kvx', 'kvy', 'kvz', 'kwa', 'kwb', 'kwc', 'kwd', 'kwe', 'kwf', 'kwg', 'kwh', 'kwi', 'kwj', 'kwk', 'kwl', 'kwm', 'kwn', 'kwo', 'kwp', 'kwq', 'kwr', 'kws', 'kwt', 'kwu', 'kwv', 'kww', 'kwx', 'kwy', 'kwz', 'kxa', 'kxb', 'kxc', 'kxd', 'kxe', 'kxf', 'kxh', 'kxi', 'kxj', 'kxk', 'kxl', 'kxm', 'kxn', 'kxo', 'kxp', 'kxq', 'kxr', 'kxs', 'kxt', 'kxu', 'kxv', 'kxw', 'kxx', 'kxy', 'kxz', 'kya', 'kyb', 'kyc', 'kyd', 'kye', 'kyf', 'kyg', 'kyh', 'kyi', 'kyj', 'kyk', 'kyl', 'kym', 'kyn', 'kyo', 'kyp', 'kyq', 'kyr', 'kys', 'kyt', 'kyu', 'kyv', 'kyw', 'kyx', 'kyy', 'kyz', 'kza', 'kzb', 'kzc', 'kzd', 'kze', 'kzf', 'kzg', 'kzh', 'kzi', 'kzj', 'kzk', 'kzl', 'kzm', 'kzn', 'kzo', 'kzp', 'kzq', 'kzr', 'kzs', 'kzt', 'kzu', 'kzv', 'kzw', 'kzx', 'kzy', 'kzz', 'laa', 'lab', 'lac', 'lad', 'lae', 'laf', 'lag', 'lah', 'lai', 'laj', 'lak', 'lal', 'lam', 'lan', 'lap', 'laq', 'lar', 'las', 'lau', 'law', 'lax', 'lay', 'laz', 'lba', 'lbb', 'lbc', 'lbe', 'lbf', 'lbg', 'lbi', 'lbj', 'lbk', 'lbl', 'lbm', 'lbn', 'lbo', 'lbq', 'lbr', 'lbs', 'lbt', 'lbu', 'lbv', 'lbw', 'lbx', 'lby', 'lbz', 'lcc', 'lcd', 'lce', 'lcf', 'lch', 'lcl', 'lcm', 'lcp', 'lcq', 'lcs', 'lda', 'ldb', 'ldd', 'ldg', 'ldh', 'ldi', 'ldj', 'ldk', 'ldl', 'ldm', 'ldn', 'ldo', 'ldp', 'ldq', 'lea', 'leb', 'lec', 'led', 'lee', 'lef', 'leg', 'leh', 'lei', 'lej', 'lek', 'lel', 'lem', 'len', 'leo', 'lep', 'leq', 'ler', 'les', 'let', 'leu', 'lev', 'lew', 'lex', 'ley', 'lez', 'lfa', 'lfn', 'lga', 'lgb', 'lgg', 'lgh', 'lgi', 'lgk', 'lgl', 'lgm', 'lgn', 'lgq', 'lgr', 'lgt', 'lgu', 'lgz', 'lha', 'lhh', 'lhi', 'lhl', 'lhm', 'lhn', 'lhp', 'lhs', 'lht', 'lhu', 'lia', 'lib', 'lic', 'lid', 'lie', 'lif', 'lig', 'lih', 'lii', 'lij', 'lik', 'lil', 'lio', 'lip', 'liq', 'lir', 'lis', 'liu', 'liv', 'liw', 'lix', 'liy', 'liz', 'lja', 'lje', 'lji', 'ljl', 'ljp', 'ljw', 'ljx', 'lka', 'lkb', 'lkc', 'lkd', 'lke', 'lkh', 'lki', 'lkj', 'lkl', 'lkm', 'lkn', 'lko', 'lkr', 'lks', 'lkt', 'lku', 'lky', 'lla', 'llb', 'llc', 'lld', 'lle', 'llf', 'llg', 'llh', 'lli', 'llj', 'llk', 'lll', 'llm', 'lln', 'llo', 'llp', 'llq', 'lls', 'llu', 'llx', 'lma', 'lmb', 'lmc', 'lmd', 'lme', 'lmf', 'lmg', 'lmh', 'lmi', 'lmj', 'lmk', 'lml', 'lmm', 'lmn', 'lmo', 'lmp', 'lmq', 'lmr', 'lmu', 'lmv', 'lmw', 'lmx', 'lmy', 'lmz', 'lna', 'lnb', 'lnd', 'lng', 'lnh', 'lni', 'lnj', 'lnl', 'lnm', 'lnn', 'lno', 'lns', 'lnu', 'lnw', 'lnz', 'loa', 'lob', 'loc', 'loe', 'lof', 'log', 'loh', 'loi', 'loj', 'lok', 'lol', 'lom', 'lon', 'loo', 'lop', 'loq', 'lor', 'los', 'lot', 'lou', 'lov', 'low', 'lox', 'loy', 'loz', 'lpa', 'lpe', 'lpn', 'lpo', 'lpx', 'lra', 'lrc', 'lre', 'lrg', 'lri', 'lrk', 'lrl', 'lrm', 'lrn', 'lro', 'lrr', 'lrt', 'lrv', 'lrz', 'lsa', 'lsd', 'lse', 'lsg', 'lsh', 'lsi', 'lsl', 'lsm', 'lso', 'lsp', 'lsr', 'lss', 'lst', 'lsy', 'ltc', 'ltg', 'lth', 'lti', 'ltn', 'lto', 'lts', 'ltu', 'lua', 'luc', 'lud', 'lue', 'luf', 'lui', 'luj', 'luk', 'lul', 'lum', 'lun', 'luo', 'lup', 'luq', 'lur', 'lus', 'lut', 'luu', 'luv', 'luw', 'luy', 'luz', 'lva', 'lvk', 'lvs', 'lvu', 'lwa', 'lwe', 'lwg', 'lwh', 'lwl', 'lwm', 'lwo', 'lwt', 'lwu', 'lww', 'lya', 'lyg', 'lyn', 'lzh', 'lzl', 'lzn', 'lzz', 'maa', 'mab', 'mad', 'mae', 'maf', 'mag', 'mai', 'maj', 'mak', 'mam', 'man', 'map', 'maq', 'mas', 'mat', 'mau', 'mav', 'maw', 'max', 'maz', 'mba', 'mbb', 'mbc', 'mbd', 'mbe', 'mbf', 'mbh', 'mbi', 'mbj', 'mbk', 'mbl', 'mbm', 'mbn', 'mbo', 'mbp', 'mbq', 'mbr', 'mbs', 'mbt', 'mbu', 'mbv', 'mbw', 'mbx', 'mby', 'mbz', 'mca', 'mcb', 'mcc', 'mcd', 'mce', 'mcf', 'mcg', 'mch', 'mci', 'mcj', 'mck', 'mcl', 'mcm', 'mcn', 'mco', 'mcp', 'mcq', 'mcr', 'mcs', 'mct', 'mcu', 'mcv', 'mcw', 'mcx', 'mcy', 'mcz', 'mda', 'mdb', 'mdc', 'mdd', 'mde', 'mdf', 'mdg', 'mdh', 'mdi', 'mdj', 'mdk', 'mdl', 'mdm', 'mdn', 'mdp', 'mdq', 'mdr', 'mds', 'mdt', 'mdu', 'mdv', 'mdw', 'mdx', 'mdy', 'mdz', 'mea', 'meb', 'mec', 'med', 'mee', 'mef', 'meg', 'meh', 'mei', 'mej', 'mek', 'mel', 'mem', 'men', 'meo', 'mep', 'meq', 'mer', 'mes', 'met', 'meu', 'mev', 'mew', 'mey', 'mez', 'mfa', 'mfb', 'mfc', 'mfd', 'mfe', 'mff', 'mfg', 'mfh', 'mfi', 'mfj', 'mfk', 'mfl', 'mfm', 'mfn', 'mfo', 'mfp', 'mfq', 'mfr', 'mfs', 'mft', 'mfu', 'mfv', 'mfw', 'mfx', 'mfy', 'mfz', 'mga', 'mgb', 'mgc', 'mgd', 'mge', 'mgf', 'mgg', 'mgh', 'mgi', 'mgj', 'mgk', 'mgl', 'mgm', 'mgn', 'mgo', 'mgp', 'mgq', 'mgr', 'mgs', 'mgt', 'mgu', 'mgv', 'mgw', 'mgx', 'mgy', 'mgz', 'mha', 'mhb', 'mhc', 'mhd', 'mhe', 'mhf', 'mhg', 'mhh', 'mhi', 'mhj', 'mhk', 'mhl', 'mhm', 'mhn', 'mho', 'mhp', 'mhq', 'mhr', 'mhs', 'mht', 'mhu', 'mhw', 'mhx', 'mhy', 'mhz', 'mia', 'mib', 'mic', 'mid', 'mie', 'mif', 'mig', 'mih', 'mii', 'mij', 'mik', 'mil', 'mim', 'min', 'mio', 'mip', 'miq', 'mir', 'mis', 'mit', 'miu', 'miw', 'mix', 'miy', 'miz', 'mja', 'mjb', 'mjc', 'mjd', 'mje', 'mjg', 'mjh', 'mji', 'mjj', 'mjk', 'mjl', 'mjm', 'mjn', 'mjo', 'mjp', 'mjq', 'mjr', 'mjs', 'mjt', 'mju', 'mjv', 'mjw', 'mjx', 'mjy', 'mjz', 'mka', 'mkb', 'mkc', 'mke', 'mkf', 'mkg', 'mkh', 'mki', 'mkj', 'mkk', 'mkl', 'mkm', 'mkn', 'mko', 'mkp', 'mkq', 'mkr', 'mks', 'mkt', 'mku', 'mkv', 'mkw', 'mkx', 'mky', 'mkz', 'mla', 'mlb', 'mlc', 'mld', 'mle', 'mlf', 'mlh', 'mli', 'mlj', 'mlk', 'mll', 'mlm', 'mln', 'mlo', 'mlp', 'mlq', 'mlr', 'mls', 'mlu', 'mlv', 'mlw', 'mlx', 'mlz', 'mma', 'mmb', 'mmc', 'mmd', 'mme', 'mmf', 'mmg', 'mmh', 'mmi', 'mmj', 'mmk', 'mml', 'mmm', 'mmn', 'mmo', 'mmp', 'mmq', 'mmr', 'mmt', 'mmu', 'mmv', 'mmw', 'mmx', 'mmy', 'mmz', 'mna', 'mnb', 'mnc', 'mnd', 'mne', 'mnf', 'mng', 'mnh', 'mni', 'mnj', 'mnk', 'mnl', 'mnm', 'mnn', 'mno', 'mnp', 'mnq', 'mnr', 'mns', 'mnt', 'mnu', 'mnv', 'mnw', 'mnx', 'mny', 'mnz', 'moa', 'moc', 'mod', 'moe', 'mof', 'mog', 'moh', 'moi', 'moj', 'mok', 'mom', 'moo', 'mop', 'moq', 'mor', 'mos', 'mot', 'mou', 'mov', 'mow', 'mox', 'moy', 'moz', 'mpa', 'mpb', 'mpc', 'mpd', 'mpe', 'mpg', 'mph', 'mpi', 'mpj', 'mpk', 'mpl', 'mpm', 'mpn', 'mpo', 'mpp', 'mpq', 'mpr', 'mps', 'mpt', 'mpu', 'mpv', 'mpw', 'mpx', 'mpy', 'mpz', 'mqa', 'mqb', 'mqc', 'mqe', 'mqf', 'mqg', 'mqh', 'mqi', 'mqj', 'mqk', 'mql', 'mqm', 'mqn', 'mqo', 'mqp', 'mqq', 'mqr', 'mqs', 'mqt', 'mqu', 'mqv', 'mqw', 'mqx', 'mqy', 'mqz', 'mra', 'mrb', 'mrc', 'mrd', 'mre', 'mrf', 'mrg', 'mrh', 'mrj', 'mrk', 'mrl', 'mrm', 'mrn', 'mro', 'mrp', 'mrq', 'mrr', 'mrs', 'mrt', 'mru', 'mrv', 'mrw', 'mrx', 'mry', 'mrz', 'msb', 'msc', 'msd', 'mse', 'msf', 'msg', 'msh', 'msi', 'msj', 'msk', 'msl', 'msm', 'msn', 'mso', 'msp', 'msq', 'msr', 'mss', 'mst', 'msu', 'msv', 'msw', 'msx', 'msy', 'msz', 'mta', 'mtb', 'mtc', 'mtd', 'mte', 'mtf', 'mtg', 'mth', 'mti', 'mtj', 'mtk', 'mtl', 'mtm', 'mtn', 'mto', 'mtp', 'mtq', 'mtr', 'mts', 'mtt', 'mtu', 'mtv', 'mtw', 'mtx', 'mty', 'mua', 'mub', 'muc', 'mud', 'mue', 'mug', 'muh', 'mui', 'muj', 'muk', 'mul', 'mum', 'mun', 'muo', 'mup', 'muq', 'mur', 'mus', 'mut', 'muu', 'muv', 'mux', 'muy', 'muz', 'mva', 'mvb', 'mvd', 'mve', 'mvf', 'mvg', 'mvh', 'mvi', 'mvk', 'mvl', 'mvm', 'mvn', 'mvo', 'mvp', 'mvq', 'mvr', 'mvs', 'mvt', 'mvu', 'mvv', 'mvw', 'mvx', 'mvy', 'mvz', 'mwa', 'mwb', 'mwc', 'mwd', 'mwe', 'mwf', 'mwg', 'mwh', 'mwi', 'mwj', 'mwk', 'mwl', 'mwm', 'mwn', 'mwo', 'mwp', 'mwq', 'mwr', 'mws', 'mwt', 'mwu', 'mwv', 'mww', 'mwx', 'mwy', 'mwz', 'mxa', 'mxb', 'mxc', 'mxd', 'mxe', 'mxf', 'mxg', 'mxh', 'mxi', 'mxj', 'mxk', 'mxl', 'mxm', 'mxn', 'mxo', 'mxp', 'mxq', 'mxr', 'mxs', 'mxt', 'mxu', 'mxv', 'mxw', 'mxx', 'mxy', 'mxz', 'myb', 'myc', 'myd', 'mye', 'myf', 'myg', 'myh', 'myi', 'myj', 'myk', 'myl', 'mym', 'myn', 'myo', 'myp', 'myq', 'myr', 'mys', 'myt', 'myu', 'myv', 'myw', 'myx', 'myy', 'myz', 'mza', 'mzb', 'mzc', 'mzd', 'mze', 'mzg', 'mzh', 'mzi', 'mzj', 'mzk', 'mzl', 'mzm', 'mzn', 'mzo', 'mzp', 'mzq', 'mzr', 'mzs', 'mzt', 'mzu', 'mzv', 'mzw', 'mzx', 'mzy', 'mzz', 'naa', 'nab', 'nac', 'nad', 'nae', 'naf', 'nag', 'nah', 'nai', 'naj', 'nak', 'nal', 'nam', 'nan', 'nao', 'nap', 'naq', 'nar', 'nas', 'nat', 'naw', 'nax', 'nay', 'naz', 'nba', 'nbb', 'nbc', 'nbd', 'nbe', 'nbf', 'nbg', 'nbh', 'nbi', 'nbj', 'nbk', 'nbm', 'nbn', 'nbo', 'nbp', 'nbq', 'nbr', 'nbs', 'nbt', 'nbu', 'nbv', 'nbw', 'nbx', 'nby', 'nca', 'ncb', 'ncc', 'ncd', 'nce', 'ncf', 'ncg', 'nch', 'nci', 'ncj', 'nck', 'ncl', 'ncm', 'ncn', 'nco', 'ncp', 'ncq', 'ncr', 'ncs', 'nct', 'ncu', 'ncx', 'ncz', 'nda', 'ndb', 'ndc', 'ndd', 'ndf', 'ndg', 'ndh', 'ndi', 'ndj', 'ndk', 'ndl', 'ndm', 'ndn', 'ndp', 'ndq', 'ndr', 'nds', 'ndt', 'ndu', 'ndv', 'ndw', 'ndx', 'ndy', 'ndz', 'nea', 'neb', 'nec', 'ned', 'nee', 'nef', 'neg', 'neh', 'nei', 'nej', 'nek', 'nem', 'nen', 'neo', 'neq', 'ner', 'nes', 'net', 'neu', 'nev', 'new', 'nex', 'ney', 'nez', 'nfa', 'nfd', 'nfl', 'nfr', 'nfu', 'nga', 'ngb', 'ngc', 'ngd', 'nge', 'ngf', 'ngg', 'ngh', 'ngi', 'ngj', 'ngk', 'ngl', 'ngm', 'ngn', 'ngo', 'ngp', 'ngq', 'ngr', 'ngs', 'ngt', 'ngu', 'ngv', 'ngw', 'ngx', 'ngy', 'ngz', 'nha', 'nhb', 'nhc', 'nhd', 'nhe', 'nhf', 'nhg', 'nhh', 'nhi', 'nhk', 'nhm', 'nhn', 'nho', 'nhp', 'nhq', 'nhr', 'nht', 'nhu', 'nhv', 'nhw', 'nhx', 'nhy', 'nhz', 'nia', 'nib', 'nic', 'nid', 'nie', 'nif', 'nig', 'nih', 'nii', 'nij', 'nik', 'nil', 'nim', 'nin', 'nio', 'niq', 'nir', 'nis', 'nit', 'niu', 'niv', 'niw', 'nix', 'niy', 'niz', 'nja', 'njb', 'njd', 'njh', 'nji', 'njj', 'njl', 'njm', 'njn', 'njo', 'njr', 'njs', 'njt', 'nju', 'njx', 'njy', 'njz', 'nka', 'nkb', 'nkc', 'nkd', 'nke', 'nkf', 'nkg', 'nkh', 'nki', 'nkj', 'nkk', 'nkm', 'nkn', 'nko', 'nkp', 'nkq', 'nkr', 'nks', 'nkt', 'nku', 'nkv', 'nkw', 'nkx', 'nkz', 'nla', 'nlc', 'nle', 'nlg', 'nli', 'nlj', 'nlk', 'nll', 'nln', 'nlo', 'nlq', 'nlr', 'nlu', 'nlv', 'nlw', 'nlx', 'nly', 'nlz', 'nma', 'nmb', 'nmc', 'nmd', 'nme', 'nmf', 'nmg', 'nmh', 'nmi', 'nmj', 'nmk', 'nml', 'nmm', 'nmn', 'nmo', 'nmp', 'nmq', 'nmr', 'nms', 'nmt', 'nmu', 'nmv', 'nmw', 'nmx', 'nmy', 'nmz', 'nna', 'nnb', 'nnc', 'nnd', 'nne', 'nnf', 'nng', 'nnh', 'nni', 'nnj', 'nnk', 'nnl', 'nnm', 'nnn', 'nnp', 'nnq', 'nnr', 'nns', 'nnt', 'nnu', 'nnv', 'nnw', 'nnx', 'nny', 'nnz', 'noa', 'noc', 'nod', 'noe', 'nof', 'nog', 'noh', 'noi', 'noj', 'nok', 'nol', 'nom', 'non', 'noo', 'nop', 'noq', 'nos', 'not', 'nou', 'nov', 'now', 'noy', 'noz', 'npa', 'npb', 'npg', 'nph', 'npi', 'npl', 'npn', 'npo', 'nps', 'npu', 'npx', 'npy', 'nqg', 'nqk', 'nql', 'nqm', 'nqn', 'nqo', 'nqq', 'nqy', 'nra', 'nrb', 'nrc', 'nre', 'nrf', 'nrg', 'nri', 'nrk', 'nrl', 'nrm', 'nrn', 'nrp', 'nrr', 'nrt', 'nru', 'nrx', 'nrz', 'nsa', 'nsc', 'nsd', 'nse', 'nsf', 'nsg', 'nsh', 'nsi', 'nsk', 'nsl', 'nsm', 'nsn', 'nso', 'nsp', 'nsq', 'nsr', 'nss', 'nst', 'nsu', 'nsv', 'nsw', 'nsx', 'nsy', 'nsz', 'ntd', 'nte', 'ntg', 'nti', 'ntj', 'ntk', 'ntm', 'nto', 'ntp', 'ntr', 'nts', 'ntu', 'ntw', 'ntx', 'nty', 'ntz', 'nua', 'nub', 'nuc', 'nud', 'nue', 'nuf', 'nug', 'nuh', 'nui', 'nuj', 'nuk', 'nul', 'num', 'nun', 'nuo', 'nup', 'nuq', 'nur', 'nus', 'nut', 'nuu', 'nuv', 'nuw', 'nux', 'nuy', 'nuz', 'nvh', 'nvm', 'nvo', 'nwa', 'nwb', 'nwc', 'nwe', 'nwg', 'nwi', 'nwm', 'nwo', 'nwr', 'nwx', 'nwy', 'nxa', 'nxd', 'nxe', 'nxg', 'nxi', 'nxk', 'nxl', 'nxm', 'nxn', 'nxo', 'nxq', 'nxr', 'nxu', 'nxx', 'nyb', 'nyc', 'nyd', 'nye', 'nyf', 'nyg', 'nyh', 'nyi', 'nyj', 'nyk', 'nyl', 'nym', 'nyn', 'nyo', 'nyp', 'nyq', 'nyr', 'nys', 'nyt', 'nyu', 'nyv', 'nyw', 'nyx', 'nyy', 'nza', 'nzb', 'nzi', 'nzk', 'nzm', 'nzs', 'nzu', 'nzy', 'nzz', 'oaa', 'oac', 'oar', 'oav', 'obi', 'obk', 'obl', 'obm', 'obo', 'obr', 'obt', 'obu', 'oca', 'och', 'oco', 'ocu', 'oda', 'odk', 'odt', 'odu', 'ofo', 'ofs', 'ofu', 'ogb', 'ogc', 'oge', 'ogg', 'ogo', 'ogu', 'oht', 'ohu', 'oia', 'oin', 'ojb', 'ojc', 'ojg', 'ojp', 'ojs', 'ojv', 'ojw', 'oka', 'okb', 'okd', 'oke', 'okg', 'okh', 'oki', 'okj', 'okk', 'okl', 'okm', 'okn', 'oko', 'okr', 'oks', 'oku', 'okv', 'okx', 'ola', 'old', 'ole', 'olk', 'olm', 'olo', 'olr', 'olt', 'olu', 'oma', 'omb', 'omc', 'ome', 'omg', 'omi', 'omk', 'oml', 'omn', 'omo', 'omp', 'omq', 'omr', 'omt', 'omu', 'omv', 'omw', 'omx', 'ona', 'onb', 'one', 'ong', 'oni', 'onj', 'onk', 'onn', 'ono', 'onp', 'onr', 'ons', 'ont', 'onu', 'onw', 'onx', 'ood', 'oog', 'oon', 'oor', 'oos', 'opa', 'opk', 'opm', 'opo', 'opt', 'opy', 'ora', 'orc', 'ore', 'org', 'orh', 'orn', 'oro', 'orr', 'ors', 'ort', 'oru', 'orv', 'orw', 'orx', 'ory', 'orz', 'osa', 'osc', 'osi', 'oso', 'osp', 'ost', 'osu', 'osx', 'ota', 'otb', 'otd', 'ote', 'oti', 'otk', 'otl', 'otm', 'otn', 'oto', 'otq', 'otr', 'ots', 'ott', 'otu', 'otw', 'otx', 'oty', 'otz', 'oua', 'oub', 'oue', 'oui', 'oum', 'oun', 'ovd', 'owi', 'owl', 'oyb', 'oyd', 'oym', 'oyy', 'ozm', 'paa', 'pab', 'pac', 'pad', 'pae', 'paf', 'pag', 'pah', 'pai', 'pak', 'pal', 'pam', 'pao', 'pap', 'paq', 'par', 'pas', 'pat', 'pau', 'pav', 'paw', 'pax', 'pay', 'paz', 'pbb', 'pbc', 'pbe', 'pbf', 'pbg', 'pbh', 'pbi', 'pbl', 'pbn', 'pbo', 'pbp', 'pbr', 'pbs', 'pbt', 'pbu', 'pbv', 'pby', 'pbz', 'pca', 'pcb', 'pcc', 'pcd', 'pce', 'pcf', 'pcg', 'pch', 'pci', 'pcj', 'pck', 'pcl', 'pcm', 'pcn', 'pcp', 'pcr', 'pcw', 'pda', 'pdc', 'pdi', 'pdn', 'pdo', 'pdt', 'pdu', 'pea', 'peb', 'ped', 'pee', 'pef', 'peg', 'peh', 'pei', 'pej', 'pek', 'pel', 'pem', 'peo', 'pep', 'peq', 'pes', 'pev', 'pex', 'pey', 'pez', 'pfa', 'pfe', 'pfl', 'pga', 'pgd', 'pgg', 'pgi', 'pgk', 'pgl', 'pgn', 'pgs', 'pgu', 'pgy', 'pgz', 'pha', 'phd', 'phg', 'phh', 'phi', 'phk', 'phl', 'phm', 'phn', 'pho', 'phq', 'phr', 'pht', 'phu', 'phv', 'phw', 'pia', 'pib', 'pic', 'pid', 'pie', 'pif', 'pig', 'pih', 'pii', 'pij', 'pil', 'pim', 'pin', 'pio', 'pip', 'pir', 'pis', 'pit', 'piu', 'piv', 'piw', 'pix', 'piy', 'piz', 'pjt', 'pka', 'pkb', 'pkc', 'pkg', 'pkh', 'pkn', 'pko', 'pkp', 'pkr', 'pks', 'pkt', 'pku', 'pla', 'plb', 'plc', 'pld', 'ple', 'plf', 'plg', 'plh', 'plj', 'plk', 'pll', 'pln', 'plo', 'plp', 'plq', 'plr', 'pls', 'plt', 'plu', 'plv', 'plw', 'ply', 'plz', 'pma', 'pmb', 'pmc', 'pmd', 'pme', 'pmf', 'pmh', 'pmi', 'pmj', 'pmk', 'pml', 'pmm', 'pmn', 'pmo', 'pmq', 'pmr', 'pms', 'pmt', 'pmu', 'pmw', 'pmx', 'pmy', 'pmz', 'pna', 'pnb', 'pnc', 'pne', 'png', 'pnh', 'pni', 'pnj', 'pnk', 'pnl', 'pnm', 'pnn', 'pno', 'pnp', 'pnq', 'pnr', 'pns', 'pnt', 'pnu', 'pnv', 'pnw', 'pnx', 'pny', 'pnz', 'poc', 'pod', 'poe', 'pof', 'pog', 'poh', 'poi', 'pok', 'pom', 'pon', 'poo', 'pop', 'poq', 'pos', 'pot', 'pov', 'pow', 'pox', 'poy', 'poz', 'ppa', 'ppe', 'ppi', 'ppk', 'ppl', 'ppm', 'ppn', 'ppo', 'ppp', 'ppq', 'ppr', 'pps', 'ppt', 'ppu', 'pqa', 'pqe', 'pqm', 'pqw', 'pra', 'prb', 'prc', 'prd', 'pre', 'prf', 'prg', 'prh', 'pri', 'prk', 'prl', 'prm', 'prn', 'pro', 'prp', 'prq', 'prr', 'prs', 'prt', 'pru', 'prw', 'prx', 'pry', 'prz', 'psa', 'psc', 'psd', 'pse', 'psg', 'psh', 'psi', 'psl', 'psm', 'psn', 'pso', 'psp', 'psq', 'psr', 'pss', 'pst', 'psu', 'psw', 'psy', 'pta', 'pth', 'pti', 'ptn', 'pto', 'ptp', 'ptq', 'ptr', 'ptt', 'ptu', 'ptv', 'ptw', 'pty', 'pua', 'pub', 'puc', 'pud', 'pue', 'puf', 'pug', 'pui', 'puj', 'puk', 'pum', 'puo', 'pup', 'puq', 'pur', 'put', 'puu', 'puw', 'pux', 'puy', 'puz', 'pwa', 'pwb', 'pwg', 'pwi', 'pwm', 'pwn', 'pwo', 'pwr', 'pww', 'pxm', 'pye', 'pym', 'pyn', 'pys', 'pyu', 'pyx', 'pyy', 'pzn', 'qaa..qtz', 'qua', 'qub', 'quc', 'qud', 'quf', 'qug', 'quh', 'qui', 'quk', 'qul', 'qum', 'qun', 'qup', 'quq', 'qur', 'qus', 'quv', 'quw', 'qux', 'quy', 'quz', 'qva', 'qvc', 'qve', 'qvh', 'qvi', 'qvj', 'qvl', 'qvm', 'qvn', 'qvo', 'qvp', 'qvs', 'qvw', 'qvy', 'qvz', 'qwa', 'qwc', 'qwe', 'qwh', 'qwm', 'qws', 'qwt', 'qxa', 'qxc', 'qxh', 'qxl', 'qxn', 'qxo', 'qxp', 'qxq', 'qxr', 'qxs', 'qxt', 'qxu', 'qxw', 'qya', 'qyp', 'raa', 'rab', 'rac', 'rad', 'raf', 'rag', 'rah', 'rai', 'raj', 'rak', 'ral', 'ram', 'ran', 'rao', 'rap', 'raq', 'rar', 'ras', 'rat', 'rau', 'rav', 'raw', 'rax', 'ray', 'raz', 'rbb', 'rbk', 'rbl', 'rbp', 'rcf', 'rdb', 'rea', 'reb', 'ree', 'reg', 'rei', 'rej', 'rel', 'rem', 'ren', 'rer', 'res', 'ret', 'rey', 'rga', 'rge', 'rgk', 'rgn', 'rgr', 'rgs', 'rgu', 'rhg', 'rhp', 'ria', 'rie', 'rif', 'ril', 'rim', 'rin', 'rir', 'rit', 'riu', 'rjg', 'rji', 'rjs', 'rka', 'rkb', 'rkh', 'rki', 'rkm', 'rkt', 'rkw', 'rma', 'rmb', 'rmc', 'rmd', 'rme', 'rmf', 'rmg', 'rmh', 'rmi', 'rmk', 'rml', 'rmm', 'rmn', 'rmo', 'rmp', 'rmq', 'rmr', 'rms', 'rmt', 'rmu', 'rmv', 'rmw', 'rmx', 'rmy', 'rmz', 'rna', 'rnd', 'rng', 'rnl', 'rnn', 'rnp', 'rnr', 'rnw', 'roa', 'rob', 'roc', 'rod', 'roe', 'rof', 'rog', 'rol', 'rom', 'roo', 'rop', 'ror', 'rou', 'row', 'rpn', 'rpt', 'rri', 'rro', 'rrt', 'rsb', 'rsi', 'rsl', 'rsm', 'rtc', 'rth', 'rtm', 'rts', 'rtw', 'rub', 'ruc', 'rue', 'ruf', 'rug', 'ruh', 'rui', 'ruk', 'ruo', 'rup', 'ruq', 'rut', 'ruu', 'ruy', 'ruz', 'rwa', 'rwk', 'rwm', 'rwo', 'rwr', 'rxd', 'rxw', 'ryn', 'rys', 'ryu', 'rzh', 'saa', 'sab', 'sac', 'sad', 'sae', 'saf', 'sah', 'sai', 'saj', 'sak', 'sal', 'sam', 'sao', 'sap', 'saq', 'sar', 'sas', 'sat', 'sau', 'sav', 'saw', 'sax', 'say', 'saz', 'sba', 'sbb', 'sbc', 'sbd', 'sbe', 'sbf', 'sbg', 'sbh', 'sbi', 'sbj', 'sbk', 'sbl', 'sbm', 'sbn', 'sbo', 'sbp', 'sbq', 'sbr', 'sbs', 'sbt', 'sbu', 'sbv', 'sbw', 'sbx', 'sby', 'sbz', 'sca', 'scb', 'sce', 'scf', 'scg', 'sch', 'sci', 'sck', 'scl', 'scn', 'sco', 'scp', 'scq', 'scs', 'sct', 'scu', 'scv', 'scw', 'scx', 'sda', 'sdb', 'sdc', 'sde', 'sdf', 'sdg', 'sdh', 'sdj', 'sdk', 'sdl', 'sdm', 'sdn', 'sdo', 'sdp', 'sdr', 'sds', 'sdt', 'sdu', 'sdv', 'sdx', 'sdz', 'sea', 'seb', 'sec', 'sed', 'see', 'sef', 'seg', 'seh', 'sei', 'sej', 'sek', 'sel', 'sem', 'sen', 'seo', 'sep', 'seq', 'ser', 'ses', 'set', 'seu', 'sev', 'sew', 'sey', 'sez', 'sfb', 'sfe', 'sfm', 'sfs', 'sfw', 'sga', 'sgb', 'sgc', 'sgd', 'sge', 'sgg', 'sgh', 'sgi', 'sgj', 'sgk', 'sgl', 'sgm', 'sgn', 'sgo', 'sgp', 'sgr', 'sgs', 'sgt', 'sgu', 'sgw', 'sgx', 'sgy', 'sgz', 'sha', 'shb', 'shc', 'shd', 'she', 'shg', 'shh', 'shi', 'shj', 'shk', 'shl', 'shm', 'shn', 'sho', 'shp', 'shq', 'shr', 'shs', 'sht', 'shu', 'shv', 'shw', 'shx', 'shy', 'shz', 'sia', 'sib', 'sid', 'sie', 'sif', 'sig', 'sih', 'sii', 'sij', 'sik', 'sil', 'sim', 'sio', 'sip', 'siq', 'sir', 'sis', 'sit', 'siu', 'siv', 'siw', 'six', 'siy', 'siz', 'sja', 'sjb', 'sjd', 'sje', 'sjg', 'sjk', 'sjl', 'sjm', 'sjn', 'sjo', 'sjp', 'sjr', 'sjs', 'sjt', 'sju', 'sjw', 'ska', 'skb', 'skc', 'skd', 'ske', 'skf', 'skg', 'skh', 'ski', 'skj', 'skk', 'skm', 'skn', 'sko', 'skp', 'skq', 'skr', 'sks', 'skt', 'sku', 'skv', 'skw', 'skx', 'sky', 'skz', 'sla', 'slc', 'sld', 'sle', 'slf', 'slg', 'slh', 'sli', 'slj', 'sll', 'slm', 'sln', 'slp', 'slq', 'slr', 'sls', 'slt', 'slu', 'slw', 'slx', 'sly', 'slz', 'sma', 'smb', 'smc', 'smd', 'smf', 'smg', 'smh', 'smi', 'smj', 'smk', 'sml', 'smm', 'smn', 'smp', 'smq', 'smr', 'sms', 'smt', 'smu', 'smv', 'smw', 'smx', 'smy', 'smz', 'snb', 'snc', 'sne', 'snf', 'sng', 'snh', 'sni', 'snj', 'snk', 'snl', 'snm', 'snn', 'sno', 'snp', 'snq', 'snr', 'sns', 'snu', 'snv', 'snw', 'snx', 'sny', 'snz', 'soa', 'sob', 'soc', 'sod', 'soe', 'sog', 'soh', 'soi', 'soj', 'sok', 'sol', 'son', 'soo', 'sop', 'soq', 'sor', 'sos', 'sou', 'sov', 'sow', 'sox', 'soy', 'soz', 'spb', 'spc', 'spd', 'spe', 'spg', 'spi', 'spk', 'spl', 'spm', 'spn', 'spo', 'spp', 'spq', 'spr', 'sps', 'spt', 'spu', 'spv', 'spx', 'spy', 'sqa', 'sqh', 'sqj', 'sqk', 'sqm', 'sqn', 'sqo', 'sqq', 'sqr', 'sqs', 'sqt', 'squ', 'sra', 'srb', 'src', 'sre', 'srf', 'srg', 'srh', 'sri', 'srk', 'srl', 'srm', 'srn', 'sro', 'srq', 'srr', 'srs', 'srt', 'sru', 'srv', 'srw', 'srx', 'sry', 'srz', 'ssa', 'ssb', 'ssc', 'ssd', 'sse', 'ssf', 'ssg', 'ssh', 'ssi', 'ssj', 'ssk', 'ssl', 'ssm', 'ssn', 'sso', 'ssp', 'ssq', 'ssr', 'sss', 'sst', 'ssu', 'ssv', 'ssx', 'ssy', 'ssz', 'sta', 'stb', 'std', 'ste', 'stf', 'stg', 'sth', 'sti', 'stj', 'stk', 'stl', 'stm', 'stn', 'sto', 'stp', 'stq', 'str', 'sts', 'stt', 'stu', 'stv', 'stw', 'sty', 'sua', 'sub', 'suc', 'sue', 'sug', 'sui', 'suj', 'suk', 'sul', 'sum', 'suq', 'sur', 'sus', 'sut', 'suv', 'suw', 'sux', 'suy', 'suz', 'sva', 'svb', 'svc', 'sve', 'svk', 'svm', 'svr', 'svs', 'svx', 'swb', 'swc', 'swf', 'swg', 'swh', 'swi', 'swj', 'swk', 'swl', 'swm', 'swn', 'swo', 'swp', 'swq', 'swr', 'sws', 'swt', 'swu', 'swv', 'sww', 'swx', 'swy', 'sxb', 'sxc', 'sxe', 'sxg', 'sxk', 'sxl', 'sxm', 'sxn', 'sxo', 'sxr', 'sxs', 'sxu', 'sxw', 'sya', 'syb', 'syc', 'syd', 'syi', 'syk', 'syl', 'sym', 'syn', 'syo', 'syr', 'sys', 'syw', 'syx', 'syy', 'sza', 'szb', 'szc', 'szd', 'sze', 'szg', 'szl', 'szn', 'szp', 'szs', 'szv', 'szw', 'taa', 'tab', 'tac', 'tad', 'tae', 'taf', 'tag', 'tai', 'taj', 'tak', 'tal', 'tan', 'tao', 'tap', 'taq', 'tar', 'tas', 'tau', 'tav', 'taw', 'tax', 'tay', 'taz', 'tba', 'tbb', 'tbc', 'tbd', 'tbe', 'tbf', 'tbg', 'tbh', 'tbi', 'tbj', 'tbk', 'tbl', 'tbm', 'tbn', 'tbo', 'tbp', 'tbq', 'tbr', 'tbs', 'tbt', 'tbu', 'tbv', 'tbw', 'tbx', 'tby', 'tbz', 'tca', 'tcb', 'tcc', 'tcd', 'tce', 'tcf', 'tcg', 'tch', 'tci', 'tck', 'tcl', 'tcm', 'tcn', 'tco', 'tcp', 'tcq', 'tcs', 'tct', 'tcu', 'tcw', 'tcx', 'tcy', 'tcz', 'tda', 'tdb', 'tdc', 'tdd', 'tde', 'tdf', 'tdg', 'tdh', 'tdi', 'tdj', 'tdk', 'tdl', 'tdm', 'tdn', 'tdo', 'tdq', 'tdr', 'tds', 'tdt', 'tdu', 'tdv', 'tdx', 'tdy', 'tea', 'teb', 'tec', 'ted', 'tee', 'tef', 'teg', 'teh', 'tei', 'tek', 'tem', 'ten', 'teo', 'tep', 'teq', 'ter', 'tes', 'tet', 'teu', 'tev', 'tew', 'tex', 'tey', 'tfi', 'tfn', 'tfo', 'tfr', 'tft', 'tga', 'tgb', 'tgc', 'tgd', 'tge', 'tgf', 'tgg', 'tgh', 'tgi', 'tgj', 'tgn', 'tgo', 'tgp', 'tgq', 'tgr', 'tgs', 'tgt', 'tgu', 'tgv', 'tgw', 'tgx', 'tgy', 'tgz', 'thc', 'thd', 'the', 'thf', 'thh', 'thi', 'thk', 'thl', 'thm', 'thn', 'thp', 'thq', 'thr', 'ths', 'tht', 'thu', 'thv', 'thw', 'thx', 'thy', 'thz', 'tia', 'tic', 'tid', 'tie', 'tif', 'tig', 'tih', 'tii', 'tij', 'tik', 'til', 'tim', 'tin', 'tio', 'tip', 'tiq', 'tis', 'tit', 'tiu', 'tiv', 'tiw', 'tix', 'tiy', 'tiz', 'tja', 'tjg', 'tji', 'tjl', 'tjm', 'tjn', 'tjo', 'tjs', 'tju', 'tjw', 'tka', 'tkb', 'tkd', 'tke', 'tkf', 'tkg', 'tkk', 'tkl', 'tkm', 'tkn', 'tkp', 'tkq', 'tkr', 'tks', 'tkt', 'tku', 'tkv', 'tkw', 'tkx', 'tkz', 'tla', 'tlb', 'tlc', 'tld', 'tlf', 'tlg', 'tlh', 'tli', 'tlj', 'tlk', 'tll', 'tlm', 'tln', 'tlo', 'tlp', 'tlq', 'tlr', 'tls', 'tlt', 'tlu', 'tlv', 'tlw', 'tlx', 'tly', 'tma', 'tmb', 'tmc', 'tmd', 'tme', 'tmf', 'tmg', 'tmh', 'tmi', 'tmj', 'tmk', 'tml', 'tmm', 'tmn', 'tmo', 'tmp', 'tmq', 'tmr', 'tms', 'tmt', 'tmu', 'tmv', 'tmw', 'tmy', 'tmz', 'tna', 'tnb', 'tnc', 'tnd', 'tne', 'tnf', 'tng', 'tnh', 'tni', 'tnk', 'tnl', 'tnm', 'tnn', 'tno', 'tnp', 'tnq', 'tnr', 'tns', 'tnt', 'tnu', 'tnv', 'tnw', 'tnx', 'tny', 'tnz', 'tob', 'toc', 'tod', 'toe', 'tof', 'tog', 'toh', 'toi', 'toj', 'tol', 'tom', 'too', 'top', 'toq', 'tor', 'tos', 'tou', 'tov', 'tow', 'tox', 'toy', 'toz', 'tpa', 'tpc', 'tpe', 'tpf', 'tpg', 'tpi', 'tpj', 'tpk', 'tpl', 'tpm', 'tpn', 'tpo', 'tpp', 'tpq', 'tpr', 'tpt', 'tpu', 'tpv', 'tpw', 'tpx', 'tpy', 'tpz', 'tqb', 'tql', 'tqm', 'tqn', 'tqo', 'tqp', 'tqq', 'tqr', 'tqt', 'tqu', 'tqw', 'tra', 'trb', 'trc', 'trd', 'tre', 'trf', 'trg', 'trh', 'tri', 'trj', 'trk', 'trl', 'trm', 'trn', 'tro', 'trp', 'trq', 'trr', 'trs', 'trt', 'tru', 'trv', 'trw', 'trx', 'try', 'trz', 'tsa', 'tsb', 'tsc', 'tsd', 'tse', 'tsf', 'tsg', 'tsh', 'tsi', 'tsj', 'tsk', 'tsl', 'tsm', 'tsp', 'tsq', 'tsr', 'tss', 'tst', 'tsu', 'tsv', 'tsw', 'tsx', 'tsy', 'tsz', 'tta', 'ttb', 'ttc', 'ttd', 'tte', 'ttf', 'ttg', 'tth', 'tti', 'ttj', 'ttk', 'ttl', 'ttm', 'ttn', 'tto', 'ttp', 'ttq', 'ttr', 'tts', 'ttt', 'ttu', 'ttv', 'ttw', 'tty', 'ttz', 'tua', 'tub', 'tuc', 'tud', 'tue', 'tuf', 'tug', 'tuh', 'tui', 'tuj', 'tul', 'tum', 'tun', 'tuo', 'tup', 'tuq', 'tus', 'tut', 'tuu', 'tuv', 'tuw', 'tux', 'tuy', 'tuz', 'tva', 'tvd', 'tve', 'tvk', 'tvl', 'tvm', 'tvn', 'tvo', 'tvs', 'tvt', 'tvu', 'tvw', 'tvy', 'twa', 'twb', 'twc', 'twd', 'twe', 'twf', 'twg', 'twh', 'twl', 'twm', 'twn', 'two', 'twp', 'twq', 'twr', 'twt', 'twu', 'tww', 'twx', 'twy', 'txa', 'txb', 'txc', 'txe', 'txg', 'txh', 'txi', 'txj', 'txm', 'txn', 'txo', 'txq', 'txr', 'txs', 'txt', 'txu', 'txx', 'txy', 'tya', 'tye', 'tyh', 'tyi', 'tyj', 'tyl', 'tyn', 'typ', 'tyr', 'tys', 'tyt', 'tyu', 'tyv', 'tyx', 'tyz', 'tza', 'tzh', 'tzj', 'tzl', 'tzm', 'tzn', 'tzo', 'tzx', 'uam', 'uan', 'uar', 'uba', 'ubi', 'ubl', 'ubr', 'ubu', 'uby', 'uda', 'ude', 'udg', 'udi', 'udj', 'udl', 'udm', 'udu', 'ues', 'ufi', 'uga', 'ugb', 'uge', 'ugn', 'ugo', 'ugy', 'uha', 'uhn', 'uis', 'uiv', 'uji', 'uka', 'ukg', 'ukh', 'ukk', 'ukl', 'ukp', 'ukq', 'uks', 'uku', 'ukw', 'uky', 'ula', 'ulb', 'ulc', 'ule', 'ulf', 'uli', 'ulk', 'ull', 'ulm', 'uln', 'ulu', 'ulw', 'uma', 'umb', 'umc', 'umd', 'umg', 'umi', 'umm', 'umn', 'umo', 'ump', 'umr', 'ums', 'umu', 'una', 'und', 'une', 'ung', 'unk', 'unm', 'unn', 'unp', 'unr', 'unu', 'unx', 'unz', 'uok', 'upi', 'upv', 'ura', 'urb', 'urc', 'ure', 'urf', 'urg', 'urh', 'uri', 'urj', 'urk', 'url', 'urm', 'urn', 'uro', 'urp', 'urr', 'urt', 'uru', 'urv', 'urw', 'urx', 'ury', 'urz', 'usa', 'ush', 'usi', 'usk', 'usp', 'usu', 'uta', 'ute', 'utp', 'utr', 'utu', 'uum', 'uun', 'uur', 'uuu', 'uve', 'uvh', 'uvl', 'uwa', 'uya', 'uzn', 'uzs', 'vaa', 'vae', 'vaf', 'vag', 'vah', 'vai', 'vaj', 'val', 'vam', 'van', 'vao', 'vap', 'var', 'vas', 'vau', 'vav', 'vay', 'vbb', 'vbk', 'vec', 'ved', 'vel', 'vem', 'veo', 'vep', 'ver', 'vgr', 'vgt', 'vic', 'vid', 'vif', 'vig', 'vil', 'vin', 'vis', 'vit', 'viv', 'vka', 'vki', 'vkj', 'vkk', 'vkl', 'vkm', 'vko', 'vkp', 'vkt', 'vku', 'vlp', 'vls', 'vma', 'vmb', 'vmc', 'vmd', 'vme', 'vmf', 'vmg', 'vmh', 'vmi', 'vmj', 'vmk', 'vml', 'vmm', 'vmp', 'vmq', 'vmr', 'vms', 'vmu', 'vmv', 'vmw', 'vmx', 'vmy', 'vmz', 'vnk', 'vnm', 'vnp', 'vor', 'vot', 'vra', 'vro', 'vrs', 'vrt', 'vsi', 'vsl', 'vsv', 'vto', 'vum', 'vun', 'vut', 'vwa', 'waa', 'wab', 'wac', 'wad', 'wae', 'waf', 'wag', 'wah', 'wai', 'waj', 'wak', 'wal', 'wam', 'wan', 'wao', 'wap', 'waq', 'war', 'was', 'wat', 'wau', 'wav', 'waw', 'wax', 'way', 'waz', 'wba', 'wbb', 'wbe', 'wbf', 'wbh', 'wbi', 'wbj', 'wbk', 'wbl', 'wbm', 'wbp', 'wbq', 'wbr', 'wbs', 'wbt', 'wbv', 'wbw', 'wca', 'wci', 'wdd', 'wdg', 'wdj', 'wdk', 'wdu', 'wdy', 'wea', 'wec', 'wed', 'weg', 'weh', 'wei', 'wem', 'wen', 'weo', 'wep', 'wer', 'wes', 'wet', 'weu', 'wew', 'wfg', 'wga', 'wgb', 'wgg', 'wgi', 'wgo', 'wgu', 'wgw', 'wgy', 'wha', 'whg', 'whk', 'whu', 'wib', 'wic', 'wie', 'wif', 'wig', 'wih', 'wii', 'wij', 'wik', 'wil', 'wim', 'win', 'wir', 'wit', 'wiu', 'wiv', 'wiw', 'wiy', 'wja', 'wji', 'wka', 'wkb', 'wkd', 'wkl', 'wku', 'wkw', 'wky', 'wla', 'wlc', 'wle', 'wlg', 'wli', 'wlk', 'wll', 'wlm', 'wlo', 'wlr', 'wls', 'wlu', 'wlv', 'wlw', 'wlx', 'wly', 'wma', 'wmb', 'wmc', 'wmd', 'wme', 'wmh', 'wmi', 'wmm', 'wmn', 'wmo', 'wms', 'wmt', 'wmw', 'wmx', 'wnb', 'wnc', 'wnd', 'wne', 'wng', 'wni', 'wnk', 'wnm', 'wnn', 'wno', 'wnp', 'wnu', 'wnw', 'wny', 'woa', 'wob', 'woc', 'wod', 'woe', 'wof', 'wog', 'woi', 'wok', 'wom', 'won', 'woo', 'wor', 'wos', 'wow', 'woy', 'wpc', 'wra', 'wrb', 'wrd', 'wrg', 'wrh', 'wri', 'wrk', 'wrl', 'wrm', 'wrn', 'wro', 'wrp', 'wrr', 'wrs', 'wru', 'wrv', 'wrw', 'wrx', 'wry', 'wrz', 'wsa', 'wsg', 'wsi', 'wsk', 'wsr', 'wss', 'wsu', 'wsv', 'wtf', 'wth', 'wti', 'wtk', 'wtm', 'wtw', 'wua', 'wub', 'wud', 'wuh', 'wul', 'wum', 'wun', 'wur', 'wut', 'wuu', 'wuv', 'wux', 'wuy', 'wwa', 'wwb', 'wwo', 'wwr', 'www', 'wxa', 'wxw', 'wya', 'wyb', 'wyi', 'wym', 'wyr', 'wyy', 'xaa', 'xab', 'xac', 'xad', 'xae', 'xag', 'xai', 'xaj', 'xak', 'xal', 'xam', 'xan', 'xao', 'xap', 'xaq', 'xar', 'xas', 'xat', 'xau', 'xav', 'xaw', 'xay', 'xba', 'xbb', 'xbc', 'xbd', 'xbe', 'xbg', 'xbi', 'xbj', 'xbm', 'xbn', 'xbo', 'xbp', 'xbr', 'xbw', 'xbx', 'xby', 'xcb', 'xcc', 'xce', 'xcg', 'xch', 'xcl', 'xcm', 'xcn', 'xco', 'xcr', 'xct', 'xcu', 'xcv', 'xcw', 'xcy', 'xda', 'xdc', 'xdk', 'xdm', 'xdo', 'xdy', 'xeb', 'xed', 'xeg', 'xel', 'xem', 'xep', 'xer', 'xes', 'xet', 'xeu', 'xfa', 'xga', 'xgb', 'xgd', 'xgf', 'xgg', 'xgi', 'xgl', 'xgm', 'xgn', 'xgr', 'xgu', 'xgw', 'xha', 'xhc', 'xhd', 'xhe', 'xhr', 'xht', 'xhu', 'xhv', 'xia', 'xib', 'xii', 'xil', 'xin', 'xip', 'xir', 'xis', 'xiv', 'xiy', 'xjb', 'xjt', 'xka', 'xkb', 'xkc', 'xkd', 'xke', 'xkf', 'xkg', 'xkh', 'xki', 'xkj', 'xkk', 'xkl', 'xkn', 'xko', 'xkp', 'xkq', 'xkr', 'xks', 'xkt', 'xku', 'xkv', 'xkw', 'xkx', 'xky', 'xkz', 'xla', 'xlb', 'xlc', 'xld', 'xle', 'xlg', 'xli', 'xln', 'xlo', 'xlp', 'xls', 'xlu', 'xly', 'xma', 'xmb', 'xmc', 'xmd', 'xme', 'xmf', 'xmg', 'xmh', 'xmj', 'xmk', 'xml', 'xmm', 'xmn', 'xmo', 'xmp', 'xmq', 'xmr', 'xms', 'xmt', 'xmu', 'xmv', 'xmw', 'xmx', 'xmy', 'xmz', 'xna', 'xnb', 'xnd', 'xng', 'xnh', 'xni', 'xnk', 'xnn', 'xno', 'xnr', 'xns', 'xnt', 'xnu', 'xny', 'xnz', 'xoc', 'xod', 'xog', 'xoi', 'xok', 'xom', 'xon', 'xoo', 'xop', 'xor', 'xow', 'xpa', 'xpc', 'xpe', 'xpg', 'xpi', 'xpj', 'xpk', 'xpm', 'xpn', 'xpo', 'xpp', 'xpq', 'xpr', 'xps', 'xpt', 'xpu', 'xpy', 'xqa', 'xqt', 'xra', 'xrb', 'xrd', 'xre', 'xrg', 'xri', 'xrm', 'xrn', 'xrq', 'xrr', 'xrt', 'xru', 'xrw', 'xsa', 'xsb', 'xsc', 'xsd', 'xse', 'xsh', 'xsi', 'xsj', 'xsl', 'xsm', 'xsn', 'xso', 'xsp', 'xsq', 'xsr', 'xss', 'xsu', 'xsv', 'xsy', 'xta', 'xtb', 'xtc', 'xtd', 'xte', 'xtg', 'xth', 'xti', 'xtj', 'xtl', 'xtm', 'xtn', 'xto', 'xtp', 'xtq', 'xtr', 'xts', 'xtt', 'xtu', 'xtv', 'xtw', 'xty', 'xtz', 'xua', 'xub', 'xud', 'xug', 'xuj', 'xul', 'xum', 'xun', 'xuo', 'xup', 'xur', 'xut', 'xuu', 'xve', 'xvi', 'xvn', 'xvo', 'xvs', 'xwa', 'xwc', 'xwd', 'xwe', 'xwg', 'xwj', 'xwk', 'xwl', 'xwo', 'xwr', 'xwt', 'xww', 'xxb', 'xxk', 'xxm', 'xxr', 'xxt', 'xya', 'xyb', 'xyj', 'xyk', 'xyl', 'xyt', 'xyy', 'xzh', 'xzm', 'xzp', 'yaa', 'yab', 'yac', 'yad', 'yae', 'yaf', 'yag', 'yah', 'yai', 'yaj', 'yak', 'yal', 'yam', 'yan', 'yao', 'yap', 'yaq', 'yar', 'yas', 'yat', 'yau', 'yav', 'yaw', 'yax', 'yay', 'yaz', 'yba', 'ybb', 'ybd', 'ybe', 'ybh', 'ybi', 'ybj', 'ybk', 'ybl', 'ybm', 'ybn', 'ybo', 'ybx', 'yby', 'ych', 'ycl', 'ycn', 'ycp', 'yda', 'ydd', 'yde', 'ydg', 'ydk', 'yds', 'yea', 'yec', 'yee', 'yei', 'yej', 'yel', 'yen', 'yer', 'yes', 'yet', 'yeu', 'yev', 'yey', 'yga', 'ygi', 'ygl', 'ygm', 'ygp', 'ygr', 'ygs', 'ygu', 'ygw', 'yha', 'yhd', 'yhl', 'yhs', 'yia', 'yif', 'yig', 'yih', 'yii', 'yij', 'yik', 'yil', 'yim', 'yin', 'yip', 'yiq', 'yir', 'yis', 'yit', 'yiu', 'yiv', 'yix', 'yiy', 'yiz', 'yka', 'ykg', 'yki', 'ykk', 'ykl', 'ykm', 'ykn', 'yko', 'ykr', 'ykt', 'yku', 'yky', 'yla', 'ylb', 'yle', 'ylg', 'yli', 'yll', 'ylm', 'yln', 'ylo', 'ylr', 'ylu', 'yly', 'yma', 'ymb', 'ymc', 'ymd', 'yme', 'ymg', 'ymh', 'ymi', 'ymk', 'yml', 'ymm', 'ymn', 'ymo', 'ymp', 'ymq', 'ymr', 'yms', 'ymt', 'ymx', 'ymz', 'yna', 'ynd', 'yne', 'yng', 'ynh', 'ynk', 'ynl', 'ynn', 'yno', 'ynq', 'yns', 'ynu', 'yob', 'yog', 'yoi', 'yok', 'yol', 'yom', 'yon', 'yos', 'yot', 'yox', 'yoy', 'ypa', 'ypb', 'ypg', 'yph', 'ypk', 'ypm', 'ypn', 'ypo', 'ypp', 'ypz', 'yra', 'yrb', 'yre', 'yri', 'yrk', 'yrl', 'yrm', 'yrn', 'yro', 'yrs', 'yrw', 'yry', 'ysc', 'ysd', 'ysg', 'ysl', 'ysn', 'yso', 'ysp', 'ysr', 'yss', 'ysy', 'yta', 'ytl', 'ytp', 'ytw', 'yty', 'yua', 'yub', 'yuc', 'yud', 'yue', 'yuf', 'yug', 'yui', 'yuj', 'yuk', 'yul', 'yum', 'yun', 'yup', 'yuq', 'yur', 'yut', 'yuu', 'yuw', 'yux', 'yuy', 'yuz', 'yva', 'yvt', 'ywa', 'ywg', 'ywl', 'ywn', 'ywq', 'ywr', 'ywt', 'ywu', 'yww', 'yxa', 'yxg', 'yxl', 'yxm', 'yxu', 'yxy', 'yyr', 'yyu', 'yyz', 'yzg', 'yzk', 'zaa', 'zab', 'zac', 'zad', 'zae', 'zaf', 'zag', 'zah', 'zai', 'zaj', 'zak', 'zal', 'zam', 'zao', 'zap', 'zaq', 'zar', 'zas', 'zat', 'zau', 'zav', 'zaw', 'zax', 'zay', 'zaz', 'zbc', 'zbe', 'zbl', 'zbt', 'zbw', 'zca', 'zch', 'zdj', 'zea', 'zeg', 'zeh', 'zen', 'zga', 'zgb', 'zgh', 'zgm', 'zgn', 'zgr', 'zhb', 'zhd', 'zhi', 'zhn', 'zhw', 'zhx', 'zia', 'zib', 'zik', 'zil', 'zim', 'zin', 'zir', 'ziw', 'ziz', 'zka', 'zkb', 'zkd', 'zkg', 'zkh', 'zkk', 'zkn', 'zko', 'zkp', 'zkr', 'zkt', 'zku', 'zkv', 'zkz', 'zle', 'zlj', 'zlm', 'zln', 'zlq', 'zls', 'zlw', 'zma', 'zmb', 'zmc', 'zmd', 'zme', 'zmf', 'zmg', 'zmh', 'zmi', 'zmj', 'zmk', 'zml', 'zmm', 'zmn', 'zmo', 'zmp', 'zmq', 'zmr', 'zms', 'zmt', 'zmu', 'zmv', 'zmw', 'zmx', 'zmy', 'zmz', 'zna', 'znd', 'zne', 'zng', 'znk', 'zns', 'zoc', 'zoh', 'zom', 'zoo', 'zoq', 'zor', 'zos', 'zpa', 'zpb', 'zpc', 'zpd', 'zpe', 'zpf', 'zpg', 'zph', 'zpi', 'zpj', 'zpk', 'zpl', 'zpm', 'zpn', 'zpo', 'zpp', 'zpq', 'zpr', 'zps', 'zpt', 'zpu', 'zpv', 'zpw', 'zpx', 'zpy', 'zpz', 'zqe', 'zra', 'zrg', 'zrn', 'zro', 'zrp', 'zrs', 'zsa', 'zsk', 'zsl', 'zsm', 'zsr', 'zsu', 'zte', 'ztg', 'ztl', 'ztm', 'ztn', 'ztp', 'ztq', 'zts', 'ztt', 'ztu', 'ztx', 'zty', 'zua', 'zuh', 'zum', 'zun', 'zuy', 'zwa', 'zxx', 'zyb', 'zyg', 'zyj', 'zyn', 'zyp', 'zza', 'zzj' ];
-1 12851 axe.utils.validLangs = function() {
-1 12852 'use strict';
-1 12853 return langs;
-1 12854 };
-1 12855 return commons;
-1 12856 }()
-1 12857 });
-1 12858 })(typeof window === 'object' ? window : this);
-1 12859 },{}],14:[function(require,module,exports){
-1 12860 var ariaApi = require('aria-api');
-1 12861 var accdc = require('../lib/accdc');
-1 12862 var axe = require('axe-core');
-1 12863 var axs = require('../lib/axs');
-1 12864
-1 12865 var form = document.querySelector('#ba-form');
-1 12866 var preview = document.querySelector('#ba-preview');
-1 12867 var results = document.querySelector('#ba-results');
-1 12868
-1 12869 var implementations = {
-1 12870 'aria-api': function(el) {
-1 12871 return {
-1 12872 name: ariaApi.getName(el),
-1 12873 desc: ariaApi.getDescription(el)
-1 12874 };
-1 12875 },
-1 12876 'accdc': accdc.calcNames,
-1 12877 'axe': function(el) {
-1 12878 return {
-1 12879 name: axe.commons.text.accessibleText(el),
-1 12880 desc: null,
-1 12881 };
-1 12882 },
-1 12883 'axs': function(el) {
-1 12884 return {
-1 12885 name: axs.properties.findTextAlternatives(el, {}),
-1 12886 desc: null,
-1 12887 };
-1 12888 },
-1 12889 };
-1 12890
-1 12891 var createTd = function(text) {
-1 12892 var td = document.createElement('td');
-1 12893 td.textContent = text;
-1 12894 return td;
-1 12895 };
-1 12896
-1 12897 var run = function(html) {
-1 12898 preview.innerHTML = html;
-1 12899 results.innerHTML = '';
-1 12900
-1 12901 return Promise.all(Object.keys(implementations).map(function(key) {
-1 12902 var promise;
-1 12903
-1 12904 try {
-1 12905 p = implementations[key](preview);
-1 12906 promise = Promise.resolve(p);
-1 12907 } catch (error) {
-1 12908 promise = Promise.resolve({
-1 12909 name: error,
-1 12910 description: error,
-1 12911 });
-1 12912 }
-1 12913
-1 12914 return promise.then(function(result) {
-1 12915 var tr = document.createElement('tr');
-1 12916
-1 12917 tr.appendChild(createTd(key));
-1 12918 tr.appendChild(createTd(result.name));
-1 12919 tr.appendChild(createTd(result.desc));
-1 12920
-1 12921 results.appendChild(tr);
-1 12922 });
-1 12923 }));
-1 12924 };
-1 12925
-1 12926 location.search.substr(1).split('&').forEach(function(part) {
-1 12927 var p = part.split('=');
-1 12928 if (p[0] === 'input') {
-1 12929 var html = decodeURIComponent(p[1].replace(/\+/g, ' '));
-1 12930 form.input.value = html;
-1 12931 run(html);
-1 12932 }
-1 12933 });
-1 12934
-1 12935 // https://stackoverflow.com/questions/454202
-1 12936 var resize = function(event) {
-1 12937 /* 0-timeout to get the already changed text */
-1 12938 setTimeout(function() {
-1 12939 event.target.style.height = 'auto';
-1 12940 event.target.style.height = event.target.scrollHeight + 5 + 'px';
-1 12941 }, 0);
-1 12942 };
-1 12943 form.input.addEventListener('keydown', resize);
-1 12944 resize({target: form.input});
-1 12945
-1 12946 },{"../lib/accdc":1,"../lib/axs":2,"aria-api":8,"axe-core":13}]},{},[14]);