conflict-detection.js 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126
  1. /*!
  2. * Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com
  3. * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
  4. * Copyright 2024 Fonticons, Inc.
  5. */
  6. (function (global, factory) {
  7. typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
  8. typeof define === 'function' && define.amd ? define(factory) :
  9. (factory());
  10. }(this, (function () { 'use strict';
  11. let _WINDOW = {};
  12. let _DOCUMENT = {};
  13. try {
  14. if (typeof window !== 'undefined') _WINDOW = window;
  15. if (typeof document !== 'undefined') _DOCUMENT = document;
  16. } catch (e) {}
  17. const {
  18. userAgent = ''
  19. } = _WINDOW.navigator || {};
  20. const WINDOW = _WINDOW;
  21. const DOCUMENT = _DOCUMENT;
  22. const IS_BROWSER = !!WINDOW.document;
  23. const IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';
  24. const IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');
  25. const functions = [];
  26. const listener = function () {
  27. DOCUMENT.removeEventListener('DOMContentLoaded', listener);
  28. loaded = 1;
  29. functions.map(fn => fn());
  30. };
  31. let loaded = false;
  32. if (IS_DOM) {
  33. loaded = (DOCUMENT.documentElement.doScroll ? /^loaded|^c/ : /^loaded|^i|^c/).test(DOCUMENT.readyState);
  34. if (!loaded) DOCUMENT.addEventListener('DOMContentLoaded', listener);
  35. }
  36. function domready (fn) {
  37. if (!IS_DOM) return;
  38. loaded ? setTimeout(fn, 0) : functions.push(fn);
  39. }
  40. function report (_ref) {
  41. let {
  42. nodesTested,
  43. nodesFound
  44. } = _ref;
  45. const timedOutTests = {};
  46. for (let key in nodesFound) {
  47. if (!(nodesTested.conflict[key] || nodesTested.noConflict[key])) {
  48. timedOutTests[key] = nodesFound[key];
  49. }
  50. }
  51. const conflictsCount = Object.keys(nodesTested.conflict).length;
  52. if (conflictsCount > 0) {
  53. console.info("%cConflict".concat(conflictsCount > 1 ? 's' : '', " found:"), 'color: darkred; font-size: large');
  54. const data = {};
  55. for (let key in nodesTested.conflict) {
  56. const item = nodesTested.conflict[key];
  57. data[key] = {
  58. 'tagName': item.tagName,
  59. 'src/href': item.src || item.href || 'n/a',
  60. 'innerText excerpt': item.innerText && item.innerText !== '' ? item.innerText.slice(0, 200) + '...' : '(empty)'
  61. };
  62. }
  63. console.table(data);
  64. }
  65. const noConflictsCount = Object.keys(nodesTested.noConflict).length;
  66. if (noConflictsCount > 0) {
  67. console.info("%cNo conflict".concat(noConflictsCount > 1 ? 's' : '', " found with ").concat(noConflictsCount === 1 ? 'this' : 'these', ":"), 'color: green; font-size: large');
  68. const data = {};
  69. for (let key in nodesTested.noConflict) {
  70. const item = nodesTested.noConflict[key];
  71. data[key] = {
  72. 'tagName': item.tagName,
  73. 'src/href': item.src || item.href || 'n/a',
  74. 'innerText excerpt': item.innerText && item.innerText !== '' ? item.innerText.slice(0, 200) + '...' : '(empty)'
  75. };
  76. }
  77. console.table(data);
  78. }
  79. const timeOutCount = Object.keys(timedOutTests).length;
  80. if (timeOutCount > 0) {
  81. console.info("%cLeftovers--we timed out before collecting test results for ".concat(timeOutCount === 1 ? 'this' : 'these', ":"), 'color: blue; font-size: large');
  82. const data = {};
  83. for (let key in timedOutTests) {
  84. const item = timedOutTests[key];
  85. data[key] = {
  86. 'tagName': item.tagName,
  87. 'src/href': item.src || item.href || 'n/a',
  88. 'innerText excerpt': item.innerText && item.innerText !== '' ? item.innerText.slice(0, 200) + '...' : '(empty)'
  89. };
  90. }
  91. console.table(data);
  92. }
  93. }
  94. var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
  95. function createCommonjsModule(fn, module) {
  96. return module = { exports: {} }, fn(module, module.exports), module.exports;
  97. }
  98. var md5 = createCommonjsModule(function (module) {
  99. (function ($) {
  100. /**
  101. * Add integers, wrapping at 2^32.
  102. * This uses 16-bit operations internally to work around bugs in interpreters.
  103. *
  104. * @param {number} x First integer
  105. * @param {number} y Second integer
  106. * @returns {number} Sum
  107. */
  108. function safeAdd(x, y) {
  109. var lsw = (x & 0xffff) + (y & 0xffff);
  110. var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  111. return msw << 16 | lsw & 0xffff;
  112. }
  113. /**
  114. * Bitwise rotate a 32-bit number to the left.
  115. *
  116. * @param {number} num 32-bit number
  117. * @param {number} cnt Rotation count
  118. * @returns {number} Rotated number
  119. */
  120. function bitRotateLeft(num, cnt) {
  121. return num << cnt | num >>> 32 - cnt;
  122. }
  123. /**
  124. * Basic operation the algorithm uses.
  125. *
  126. * @param {number} q q
  127. * @param {number} a a
  128. * @param {number} b b
  129. * @param {number} x x
  130. * @param {number} s s
  131. * @param {number} t t
  132. * @returns {number} Result
  133. */
  134. function md5cmn(q, a, b, x, s, t) {
  135. return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);
  136. }
  137. /**
  138. * Basic operation the algorithm uses.
  139. *
  140. * @param {number} a a
  141. * @param {number} b b
  142. * @param {number} c c
  143. * @param {number} d d
  144. * @param {number} x x
  145. * @param {number} s s
  146. * @param {number} t t
  147. * @returns {number} Result
  148. */
  149. function md5ff(a, b, c, d, x, s, t) {
  150. return md5cmn(b & c | ~b & d, a, b, x, s, t);
  151. }
  152. /**
  153. * Basic operation the algorithm uses.
  154. *
  155. * @param {number} a a
  156. * @param {number} b b
  157. * @param {number} c c
  158. * @param {number} d d
  159. * @param {number} x x
  160. * @param {number} s s
  161. * @param {number} t t
  162. * @returns {number} Result
  163. */
  164. function md5gg(a, b, c, d, x, s, t) {
  165. return md5cmn(b & d | c & ~d, a, b, x, s, t);
  166. }
  167. /**
  168. * Basic operation the algorithm uses.
  169. *
  170. * @param {number} a a
  171. * @param {number} b b
  172. * @param {number} c c
  173. * @param {number} d d
  174. * @param {number} x x
  175. * @param {number} s s
  176. * @param {number} t t
  177. * @returns {number} Result
  178. */
  179. function md5hh(a, b, c, d, x, s, t) {
  180. return md5cmn(b ^ c ^ d, a, b, x, s, t);
  181. }
  182. /**
  183. * Basic operation the algorithm uses.
  184. *
  185. * @param {number} a a
  186. * @param {number} b b
  187. * @param {number} c c
  188. * @param {number} d d
  189. * @param {number} x x
  190. * @param {number} s s
  191. * @param {number} t t
  192. * @returns {number} Result
  193. */
  194. function md5ii(a, b, c, d, x, s, t) {
  195. return md5cmn(c ^ (b | ~d), a, b, x, s, t);
  196. }
  197. /**
  198. * Calculate the MD5 of an array of little-endian words, and a bit length.
  199. *
  200. * @param {Array} x Array of little-endian words
  201. * @param {number} len Bit length
  202. * @returns {Array<number>} MD5 Array
  203. */
  204. function binlMD5(x, len) {
  205. /* append padding */
  206. x[len >> 5] |= 0x80 << len % 32;
  207. x[(len + 64 >>> 9 << 4) + 14] = len;
  208. var i;
  209. var olda;
  210. var oldb;
  211. var oldc;
  212. var oldd;
  213. var a = 1732584193;
  214. var b = -271733879;
  215. var c = -1732584194;
  216. var d = 271733878;
  217. for (i = 0; i < x.length; i += 16) {
  218. olda = a;
  219. oldb = b;
  220. oldc = c;
  221. oldd = d;
  222. a = md5ff(a, b, c, d, x[i], 7, -680876936);
  223. d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);
  224. c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);
  225. b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
  226. a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);
  227. d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
  228. c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
  229. b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);
  230. a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
  231. d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
  232. c = md5ff(c, d, a, b, x[i + 10], 17, -42063);
  233. b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
  234. a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
  235. d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);
  236. c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
  237. b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
  238. a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);
  239. d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
  240. c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);
  241. b = md5gg(b, c, d, a, x[i], 20, -373897302);
  242. a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);
  243. d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);
  244. c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);
  245. b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);
  246. a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);
  247. d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
  248. c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);
  249. b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
  250. a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
  251. d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);
  252. c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
  253. b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
  254. a = md5hh(a, b, c, d, x[i + 5], 4, -378558);
  255. d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
  256. c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
  257. b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);
  258. a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
  259. d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
  260. c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);
  261. b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
  262. a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);
  263. d = md5hh(d, a, b, c, x[i], 11, -358537222);
  264. c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);
  265. b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);
  266. a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);
  267. d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);
  268. c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);
  269. b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);
  270. a = md5ii(a, b, c, d, x[i], 6, -198630844);
  271. d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
  272. c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
  273. b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);
  274. a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
  275. d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
  276. c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);
  277. b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
  278. a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
  279. d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);
  280. c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
  281. b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
  282. a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);
  283. d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
  284. c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);
  285. b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);
  286. a = safeAdd(a, olda);
  287. b = safeAdd(b, oldb);
  288. c = safeAdd(c, oldc);
  289. d = safeAdd(d, oldd);
  290. }
  291. return [a, b, c, d];
  292. }
  293. /**
  294. * Convert an array of little-endian words to a string
  295. *
  296. * @param {Array<number>} input MD5 Array
  297. * @returns {string} MD5 string
  298. */
  299. function binl2rstr(input) {
  300. var i;
  301. var output = '';
  302. var length32 = input.length * 32;
  303. for (i = 0; i < length32; i += 8) {
  304. output += String.fromCharCode(input[i >> 5] >>> i % 32 & 0xff);
  305. }
  306. return output;
  307. }
  308. /**
  309. * Convert a raw string to an array of little-endian words
  310. * Characters >255 have their high-byte silently ignored.
  311. *
  312. * @param {string} input Raw input string
  313. * @returns {Array<number>} Array of little-endian words
  314. */
  315. function rstr2binl(input) {
  316. var i;
  317. var output = [];
  318. output[(input.length >> 2) - 1] = undefined;
  319. for (i = 0; i < output.length; i += 1) {
  320. output[i] = 0;
  321. }
  322. var length8 = input.length * 8;
  323. for (i = 0; i < length8; i += 8) {
  324. output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << i % 32;
  325. }
  326. return output;
  327. }
  328. /**
  329. * Calculate the MD5 of a raw string
  330. *
  331. * @param {string} s Input string
  332. * @returns {string} Raw MD5 string
  333. */
  334. function rstrMD5(s) {
  335. return binl2rstr(binlMD5(rstr2binl(s), s.length * 8));
  336. }
  337. /**
  338. * Calculates the HMAC-MD5 of a key and some data (raw strings)
  339. *
  340. * @param {string} key HMAC key
  341. * @param {string} data Raw input string
  342. * @returns {string} Raw MD5 string
  343. */
  344. function rstrHMACMD5(key, data) {
  345. var i;
  346. var bkey = rstr2binl(key);
  347. var ipad = [];
  348. var opad = [];
  349. var hash;
  350. ipad[15] = opad[15] = undefined;
  351. if (bkey.length > 16) {
  352. bkey = binlMD5(bkey, key.length * 8);
  353. }
  354. for (i = 0; i < 16; i += 1) {
  355. ipad[i] = bkey[i] ^ 0x36363636;
  356. opad[i] = bkey[i] ^ 0x5c5c5c5c;
  357. }
  358. hash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
  359. return binl2rstr(binlMD5(opad.concat(hash), 512 + 128));
  360. }
  361. /**
  362. * Convert a raw string to a hex string
  363. *
  364. * @param {string} input Raw input string
  365. * @returns {string} Hex encoded string
  366. */
  367. function rstr2hex(input) {
  368. var hexTab = '0123456789abcdef';
  369. var output = '';
  370. var x;
  371. var i;
  372. for (i = 0; i < input.length; i += 1) {
  373. x = input.charCodeAt(i);
  374. output += hexTab.charAt(x >>> 4 & 0x0f) + hexTab.charAt(x & 0x0f);
  375. }
  376. return output;
  377. }
  378. /**
  379. * Encode a string as UTF-8
  380. *
  381. * @param {string} input Input string
  382. * @returns {string} UTF8 string
  383. */
  384. function str2rstrUTF8(input) {
  385. return unescape(encodeURIComponent(input));
  386. }
  387. /**
  388. * Encodes input string as raw MD5 string
  389. *
  390. * @param {string} s Input string
  391. * @returns {string} Raw MD5 string
  392. */
  393. function rawMD5(s) {
  394. return rstrMD5(str2rstrUTF8(s));
  395. }
  396. /**
  397. * Encodes input string as Hex encoded string
  398. *
  399. * @param {string} s Input string
  400. * @returns {string} Hex encoded string
  401. */
  402. function hexMD5(s) {
  403. return rstr2hex(rawMD5(s));
  404. }
  405. /**
  406. * Calculates the raw HMAC-MD5 for the given key and data
  407. *
  408. * @param {string} k HMAC key
  409. * @param {string} d Input string
  410. * @returns {string} Raw MD5 string
  411. */
  412. function rawHMACMD5(k, d) {
  413. return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d));
  414. }
  415. /**
  416. * Calculates the Hex encoded HMAC-MD5 for the given key and data
  417. *
  418. * @param {string} k HMAC key
  419. * @param {string} d Input string
  420. * @returns {string} Raw MD5 string
  421. */
  422. function hexHMACMD5(k, d) {
  423. return rstr2hex(rawHMACMD5(k, d));
  424. }
  425. /**
  426. * Calculates MD5 value for a given string.
  427. * If a key is provided, calculates the HMAC-MD5 value.
  428. * Returns a Hex encoded string unless the raw argument is given.
  429. *
  430. * @param {string} string Input string
  431. * @param {string} [key] HMAC key
  432. * @param {boolean} [raw] Raw output switch
  433. * @returns {string} MD5 output
  434. */
  435. function md5(string, key, raw) {
  436. if (!key) {
  437. if (!raw) {
  438. return hexMD5(string);
  439. }
  440. return rawMD5(string);
  441. }
  442. if (!raw) {
  443. return hexHMACMD5(key, string);
  444. }
  445. return rawHMACMD5(key, string);
  446. }
  447. if (module.exports) {
  448. module.exports = md5;
  449. } else {
  450. $.md5 = md5;
  451. }
  452. })(commonjsGlobal);
  453. });
  454. function md5ForNode(node) {
  455. if (null === node || 'object' !== typeof node) return undefined;
  456. if (node.src) {
  457. return md5(node.src);
  458. } else if (node.href) {
  459. return md5(node.href);
  460. } else if (node.innerText && '' !== node.innerText) {
  461. // eslint-disable-line yoda
  462. return md5(node.innerText);
  463. } else {
  464. return undefined;
  465. }
  466. }
  467. const diagScriptId = 'fa-kits-diag';
  468. const nodeUnderTestId = 'fa-kits-node-under-test';
  469. const md5Attr = 'data-md5';
  470. const detectionIgnoreAttr = 'data-fa-detection-ignore';
  471. const timeoutAttr = 'data-fa-detection-timeout';
  472. const resultsCollectionMaxWaitAttr = 'data-fa-detection-results-collection-max-wait';
  473. const silenceErrors = e => {
  474. e.preventDefault();
  475. e.stopPropagation();
  476. };
  477. function pollUntil(_ref) {
  478. let {
  479. fn = () => true,
  480. initialDuration = 1,
  481. maxDuration = WINDOW.FontAwesomeDetection.timeout,
  482. showProgress = false,
  483. progressIndicator
  484. } = _ref;
  485. return new Promise(function (resolve, reject) {
  486. // eslint-disable-line compat/compat
  487. function poll(duration, cumulativeDuration) {
  488. setTimeout(function () {
  489. const result = fn();
  490. if (showProgress) {
  491. console.info(progressIndicator);
  492. }
  493. if (!!result) {
  494. // eslint-disable-line no-extra-boolean-cast
  495. resolve(result);
  496. } else {
  497. const nextDuration = 250;
  498. const nextCumulativeDuration = nextDuration + cumulativeDuration;
  499. if (nextCumulativeDuration <= maxDuration) {
  500. poll(nextDuration, nextCumulativeDuration);
  501. } else {
  502. reject('timeout'); // eslint-disable-line prefer-promise-reject-errors
  503. }
  504. }
  505. }, duration);
  506. }
  507. poll(initialDuration, 0);
  508. });
  509. }
  510. function detectWebfontConflicts() {
  511. const linkTags = Array.from(DOCUMENT.getElementsByTagName('link')).filter(t => !t.hasAttribute(detectionIgnoreAttr));
  512. const styleTags = Array.from(DOCUMENT.getElementsByTagName('style')).filter(t => {
  513. if (t.hasAttribute(detectionIgnoreAttr)) {
  514. return false;
  515. } // If the browser has loaded the FA5 CSS, let's not test that <style> element.
  516. // Its enough that we'll be testing for traces of the corresponding JS being loaded, and testing
  517. // this <style> would only produce a false negative anyway.
  518. if (WINDOW.FontAwesomeConfig && t.innerText.match(new RegExp("svg:not\\(:root\\)\\.".concat(WINDOW.FontAwesomeConfig.replacementClass)))) {
  519. return false;
  520. }
  521. return true;
  522. });
  523. function runDiag(scriptOrLinkTag, md5) {
  524. const diagFrame = DOCUMENT.createElement('iframe'); // Using "visibility: hidden; position: absolute" instead of "display: none;" because
  525. // Firefox will not return the expected results for getComputedStyle if our iframe has display: none.
  526. diagFrame.setAttribute('style', 'visibility: hidden; position: absolute; height: 0; width: 0;');
  527. const testIconId = 'fa-test-icon-' + md5;
  528. const iTag = DOCUMENT.createElement('i');
  529. iTag.setAttribute('class', 'fa fa-coffee');
  530. iTag.setAttribute('id', testIconId);
  531. const diagScript = DOCUMENT.createElement('script');
  532. diagScript.setAttribute('id', diagScriptId); // WARNING: this function will be toString()'d and assigned to innerText of the diag script
  533. // element that we'll be putting into a diagnostic iframe.
  534. // That means that this code won't compile until after the outer script has run and injected
  535. // this code into the iframe. There are some compile time errors that might occur there.
  536. // For example, using single line (double-slash) comments like this one inside that function
  537. // will probably cause it to choke. Chrome will show an error like this:
  538. // Uncaught SyntaxError: Unexpected end of input
  539. const diagScriptFun = (nodeUnderTestId, testIconId, md5, parentOrigin) => {
  540. parent.FontAwesomeDetection.__pollUntil({
  541. fn: () => {
  542. const iEl = document.getElementById(testIconId);
  543. const computedStyle = window.getComputedStyle(iEl);
  544. const fontFamily = computedStyle.getPropertyValue('font-family');
  545. if (!!fontFamily.match(/FontAwesome/) || !!fontFamily.match(/Font Awesome [56]/)) {
  546. return true;
  547. } else {
  548. return false;
  549. }
  550. }
  551. }).then(() => {
  552. const node = document.getElementById(nodeUnderTestId);
  553. parent.postMessage({
  554. type: 'fontawesome-conflict',
  555. technology: 'webfont',
  556. href: node.href,
  557. innerText: node.innerText,
  558. tagName: node.tagName,
  559. md5
  560. }, parentOrigin);
  561. }).catch(function (e) {
  562. const node = document.getElementById(nodeUnderTestId);
  563. if (e === 'timeout') {
  564. parent.postMessage({
  565. type: 'no-conflict',
  566. technology: 'webfont',
  567. href: node.src,
  568. innerText: node.innerText,
  569. tagName: node.tagName,
  570. md5
  571. }, parentOrigin);
  572. } else {
  573. console.error(e);
  574. }
  575. });
  576. };
  577. const parentOrigin = WINDOW.location.origin === 'file://' ? '*' : WINDOW.location.origin;
  578. diagScript.innerText = "(".concat(diagScriptFun.toString(), ")('").concat(nodeUnderTestId, "', '").concat(testIconId || 'foo', "', '").concat(md5, "', '").concat(parentOrigin, "');");
  579. diagFrame.onload = function () {
  580. diagFrame.contentWindow.addEventListener('error', silenceErrors, true);
  581. diagFrame.contentDocument.head.appendChild(diagScript);
  582. diagFrame.contentDocument.head.appendChild(scriptOrLinkTag);
  583. diagFrame.contentDocument.body.appendChild(iTag);
  584. };
  585. domready(() => DOCUMENT.body.appendChild(diagFrame));
  586. }
  587. const cssByMD5 = {};
  588. for (let i = 0; i < linkTags.length; i++) {
  589. const linkUnderTest = DOCUMENT.createElement('link');
  590. linkUnderTest.setAttribute('id', nodeUnderTestId);
  591. linkUnderTest.setAttribute('href', linkTags[i].href);
  592. linkUnderTest.setAttribute('rel', linkTags[i].rel);
  593. const md5ForLink = md5ForNode(linkTags[i]);
  594. linkUnderTest.setAttribute(md5Attr, md5ForLink);
  595. cssByMD5[md5ForLink] = linkTags[i];
  596. runDiag(linkUnderTest, md5ForLink);
  597. }
  598. for (let i = 0; i < styleTags.length; i++) {
  599. var styleUnderTest = DOCUMENT.createElement('style');
  600. styleUnderTest.setAttribute('id', nodeUnderTestId);
  601. const md5ForStyle = md5ForNode(styleTags[i]);
  602. styleUnderTest.setAttribute(md5Attr, md5ForStyle);
  603. styleUnderTest.innerText = styleTags[i].innerText;
  604. cssByMD5[md5ForStyle] = styleTags[i];
  605. runDiag(styleUnderTest, md5ForStyle);
  606. }
  607. return cssByMD5;
  608. }
  609. function detectSvgConflicts(currentScript) {
  610. const scripts = Array.from(DOCUMENT.scripts).filter(t => !t.hasAttribute(detectionIgnoreAttr) && t !== currentScript);
  611. const scriptsByMD5 = {};
  612. for (let scriptIdx = 0; scriptIdx < scripts.length; scriptIdx++) {
  613. const diagFrame = DOCUMENT.createElement('iframe');
  614. diagFrame.setAttribute('style', 'display:none;');
  615. const scriptUnderTest = DOCUMENT.createElement('script');
  616. scriptUnderTest.setAttribute('id', nodeUnderTestId);
  617. const md5ForScript = md5ForNode(scripts[scriptIdx]);
  618. scriptUnderTest.setAttribute(md5Attr, md5ForScript);
  619. scriptsByMD5[md5ForScript] = scripts[scriptIdx];
  620. if (scripts[scriptIdx].src !== '') {
  621. scriptUnderTest.src = scripts[scriptIdx].src;
  622. }
  623. if (scripts[scriptIdx].innerText !== '') {
  624. scriptUnderTest.innerText = scripts[scriptIdx].innerText;
  625. }
  626. scriptUnderTest.async = true;
  627. const diagScript = DOCUMENT.createElement('script');
  628. diagScript.setAttribute('id', diagScriptId);
  629. const parentOrigin = WINDOW.location.origin === 'file://' ? '*' : WINDOW.location.origin;
  630. const diagScriptFun = (nodeUnderTestId, md5, parentOrigin) => {
  631. parent.FontAwesomeDetection.__pollUntil({
  632. fn: () => {
  633. return !!window.FontAwesomeConfig || !!window.FontAwesomeKitConfig;
  634. }
  635. }).then(function () {
  636. const scriptNode = document.getElementById(nodeUnderTestId);
  637. parent.postMessage({
  638. type: 'fontawesome-conflict',
  639. technology: 'js',
  640. src: scriptNode.src,
  641. innerText: scriptNode.innerText,
  642. tagName: scriptNode.tagName,
  643. md5
  644. }, parentOrigin);
  645. }).catch(function (e) {
  646. var scriptNode = document.getElementById(nodeUnderTestId);
  647. if (e === 'timeout') {
  648. parent.postMessage({
  649. type: 'no-conflict',
  650. src: scriptNode.src,
  651. innerText: scriptNode.innerText,
  652. tagName: scriptNode.tagName,
  653. md5
  654. }, parentOrigin);
  655. } else {
  656. console.error(e);
  657. }
  658. });
  659. };
  660. diagScript.innerText = "(".concat(diagScriptFun.toString(), ")('").concat(nodeUnderTestId, "', '").concat(md5ForScript, "', '").concat(parentOrigin, "');");
  661. diagFrame.onload = function () {
  662. diagFrame.contentWindow.addEventListener('error', silenceErrors, true);
  663. diagFrame.contentDocument.head.appendChild(diagScript);
  664. diagFrame.contentDocument.head.appendChild(scriptUnderTest);
  665. };
  666. domready(() => DOCUMENT.body.appendChild(diagFrame));
  667. }
  668. return scriptsByMD5;
  669. }
  670. function setDoneResults(_ref2) {
  671. let {
  672. nodesTested,
  673. nodesFound
  674. } = _ref2;
  675. WINDOW.FontAwesomeDetection = WINDOW.FontAwesomeDetection || {};
  676. WINDOW.FontAwesomeDetection.nodesTested = nodesTested;
  677. WINDOW.FontAwesomeDetection.nodesFound = nodesFound;
  678. WINDOW.FontAwesomeDetection.detectionDone = true;
  679. }
  680. function conflictDetection() {
  681. let report$$1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : () => {};
  682. const nodesTested = {
  683. conflict: {},
  684. noConflict: {}
  685. };
  686. WINDOW.onmessage = function (e) {
  687. if (WINDOW.location.origin === 'file://' || e.origin === WINDOW.location.origin) {
  688. if (e && e.data) {
  689. if (e.data.type === 'fontawesome-conflict') {
  690. nodesTested.conflict[e.data.md5] = e.data;
  691. } else if (e.data.type === 'no-conflict') {
  692. nodesTested.noConflict[e.data.md5] = e.data;
  693. }
  694. }
  695. }
  696. };
  697. const scriptsToTest = detectSvgConflicts(DOCUMENT.currentScript);
  698. const cssToTest = detectWebfontConflicts();
  699. const nodesFound = { ...scriptsToTest,
  700. ...cssToTest
  701. };
  702. const testCount = Object.keys(scriptsToTest).length + Object.keys(cssToTest).length; // The resultsCollectionMaxWait allows for the time between when the tests running under
  703. // child iframes call postMessage with their results, and when the parent window
  704. // receives and handles those events with window.onmessage.
  705. // Making it configurable allows us to test the scenario where this timeout is exceeded.
  706. // Naming it something very different from "timeout" is to help avoid the potential ambiguity between
  707. // these two timeout-related settings.
  708. const masterTimeout = WINDOW.FontAwesomeDetection.timeout + WINDOW.FontAwesomeDetection.resultsCollectionMaxWait;
  709. console.group('Font Awesome Detector');
  710. if (testCount === 0) {
  711. console.info('%cAll Good!', 'color: green; font-size: large');
  712. console.info('We didn\'t find anything that needs testing for conflicts. Ergo, no conflicts.');
  713. } else {
  714. console.info("Testing ".concat(testCount, " possible conflicts."));
  715. console.info("We'll wait about ".concat(Math.round(WINDOW.FontAwesomeDetection.timeout / 10) / 100, " seconds while testing these and\n") + "then up to another ".concat(Math.round(WINDOW.FontAwesomeDetection.resultsCollectionMaxWait / 10) / 100, " to allow the browser time\n") + "to accumulate the results. But we'll probably be outta here way before then.\n\n");
  716. console.info("You can adjust those durations by assigning values to these attributes on the <script> element that loads this detection:");
  717. console.info("\t%c".concat(timeoutAttr, "%c: milliseconds to wait for each test before deciding whether it's a conflict."), 'font-weight: bold;', 'font-size: normal;');
  718. console.info("\t%c".concat(resultsCollectionMaxWaitAttr, "%c: milliseconds to wait for the browser to accumulate test results before giving up."), 'font-weight: bold;', 'font-size: normal;');
  719. pollUntil({
  720. // Give this overall timer a little extra cushion
  721. maxDuration: masterTimeout,
  722. showProgress: true,
  723. progressIndicator: 'waiting...',
  724. fn: () => {
  725. return Object.keys(nodesTested.conflict).length + Object.keys(nodesTested.noConflict).length >= testCount;
  726. }
  727. }).then(() => {
  728. console.info('DONE!');
  729. setDoneResults({
  730. nodesTested,
  731. nodesFound
  732. });
  733. report$$1({
  734. nodesTested,
  735. nodesFound
  736. });
  737. console.groupEnd();
  738. }).catch(e => {
  739. if (e === 'timeout') {
  740. console.info('TIME OUT! We waited until we got tired. Here\'s what we found:');
  741. setDoneResults({
  742. nodesTested,
  743. nodesFound
  744. });
  745. report$$1({
  746. nodesTested,
  747. nodesFound
  748. });
  749. } else {
  750. console.info('Whoops! We hit an error:', e);
  751. console.info('Here\'s what we\'d found up until that error:');
  752. setDoneResults({
  753. nodesTested,
  754. nodesFound
  755. });
  756. report$$1({
  757. nodesTested,
  758. nodesFound
  759. });
  760. }
  761. console.groupEnd();
  762. });
  763. }
  764. } // Allow clients to access, and in some cases, override some properties
  765. const initialConfig = WINDOW.FontAwesomeDetection || {}; // These can be overridden
  766. const _default = {
  767. report,
  768. timeout: +(DOCUMENT.currentScript.getAttribute(timeoutAttr) || "2000"),
  769. resultsCollectionMaxWait: +(DOCUMENT.currentScript.getAttribute(resultsCollectionMaxWaitAttr) || "5000")
  770. };
  771. const _config = { ..._default,
  772. ...initialConfig,
  773. // These cannot be overridden
  774. __pollUntil: pollUntil,
  775. md5ForNode,
  776. detectionDone: false,
  777. nodesTested: null,
  778. nodesFound: null
  779. };
  780. WINDOW.FontAwesomeDetection = _config;
  781. var a = "classic",
  782. r = "sharp",
  783. o = "sharp-duotone";
  784. var et$1 = {
  785. classic: {
  786. 900: "fas",
  787. 400: "far",
  788. normal: "far",
  789. 300: "fal",
  790. 100: "fat"
  791. },
  792. sharp: {
  793. 900: "fass",
  794. 400: "fasr",
  795. 300: "fasl",
  796. 100: "fast"
  797. },
  798. "sharp-duotone": {
  799. 900: "fasds"
  800. }
  801. };
  802. var bt = {
  803. kit: {
  804. fak: "kit",
  805. "fa-kit": "kit"
  806. },
  807. "kit-duotone": {
  808. fakd: "kit-duotone",
  809. "fa-kit-duotone": "kit-duotone"
  810. }
  811. };
  812. var lo = {
  813. classic: {
  814. "fa-brands": "fab",
  815. "fa-duotone": "fad",
  816. "fa-light": "fal",
  817. "fa-regular": "far",
  818. "fa-solid": "fas",
  819. "fa-thin": "fat"
  820. },
  821. sharp: {
  822. "fa-solid": "fass",
  823. "fa-regular": "fasr",
  824. "fa-light": "fasl",
  825. "fa-thin": "fast"
  826. },
  827. "sharp-duotone": {
  828. "fa-solid": "fasds"
  829. }
  830. },
  831. no = {
  832. classic: {
  833. fab: "fa-brands",
  834. fad: "fa-duotone",
  835. fal: "fa-light",
  836. far: "fa-regular",
  837. fas: "fa-solid",
  838. fat: "fa-thin"
  839. },
  840. sharp: {
  841. fass: "fa-solid",
  842. fasr: "fa-regular",
  843. fasl: "fa-light",
  844. fast: "fa-thin"
  845. },
  846. "sharp-duotone": {
  847. fasds: "fa-solid"
  848. }
  849. },
  850. fo = {
  851. classic: {
  852. solid: "fas",
  853. regular: "far",
  854. light: "fal",
  855. thin: "fat",
  856. duotone: "fad",
  857. brands: "fab"
  858. },
  859. sharp: {
  860. solid: "fass",
  861. regular: "fasr",
  862. light: "fasl",
  863. thin: "fast"
  864. },
  865. "sharp-duotone": {
  866. solid: "fasds"
  867. }
  868. },
  869. ho = {
  870. classic: {
  871. fa: "solid",
  872. fas: "solid",
  873. "fa-solid": "solid",
  874. far: "regular",
  875. "fa-regular": "regular",
  876. fal: "light",
  877. "fa-light": "light",
  878. fat: "thin",
  879. "fa-thin": "thin",
  880. fad: "duotone",
  881. "fa-duotone": "duotone",
  882. fab: "brands",
  883. "fa-brands": "brands"
  884. },
  885. sharp: {
  886. fa: "solid",
  887. fass: "solid",
  888. "fa-solid": "solid",
  889. fasr: "regular",
  890. "fa-regular": "regular",
  891. fasl: "light",
  892. "fa-light": "light",
  893. fast: "thin",
  894. "fa-thin": "thin"
  895. },
  896. "sharp-duotone": {
  897. fa: "solid",
  898. fasds: "solid",
  899. "fa-solid": "solid"
  900. }
  901. };
  902. var Io = {
  903. kit: {
  904. "fa-kit": "fak"
  905. },
  906. "kit-duotone": {
  907. "fa-kit-duotone": "fakd"
  908. }
  909. },
  910. Fo = {
  911. kit: {
  912. fak: "fa-kit"
  913. },
  914. "kit-duotone": {
  915. fakd: "fa-kit-duotone"
  916. }
  917. },
  918. So = {
  919. kit: {
  920. kit: "fak"
  921. },
  922. "kit-duotone": {
  923. "kit-duotone": "fakd"
  924. }
  925. };
  926. const PRODUCTION = (() => {
  927. try {
  928. return process.env.NODE_ENV === 'production';
  929. } catch (e$$1) {
  930. return false;
  931. }
  932. })();
  933. function familyProxy(obj) {
  934. // Defaults to the classic family if family is not available
  935. return new Proxy(obj, {
  936. get(target, prop) {
  937. return prop in target ? target[prop] : target[a];
  938. }
  939. });
  940. }
  941. const _PREFIX_TO_STYLE = { ...ho
  942. };
  943. _PREFIX_TO_STYLE[a] = { ...ho[a],
  944. ...bt['kit'],
  945. ...bt['kit-duotone']
  946. };
  947. const PREFIX_TO_STYLE = familyProxy(_PREFIX_TO_STYLE);
  948. const _STYLE_TO_PREFIX = { ...fo
  949. };
  950. _STYLE_TO_PREFIX[a] = { ..._STYLE_TO_PREFIX[a],
  951. ...So['kit'],
  952. ...So['kit-duotone']
  953. };
  954. const STYLE_TO_PREFIX = familyProxy(_STYLE_TO_PREFIX);
  955. const _PREFIX_TO_LONG_STYLE = { ...no
  956. };
  957. _PREFIX_TO_LONG_STYLE[a] = { ..._PREFIX_TO_LONG_STYLE[a],
  958. ...Fo['kit']
  959. };
  960. const PREFIX_TO_LONG_STYLE = familyProxy(_PREFIX_TO_LONG_STYLE);
  961. const _LONG_STYLE_TO_PREFIX = { ...lo
  962. };
  963. _LONG_STYLE_TO_PREFIX[a] = { ..._LONG_STYLE_TO_PREFIX[a],
  964. ...Io['kit']
  965. };
  966. const LONG_STYLE_TO_PREFIX = familyProxy(_LONG_STYLE_TO_PREFIX);
  967. const _FONT_WEIGHT_TO_PREFIX = { ...et$1
  968. };
  969. const FONT_WEIGHT_TO_PREFIX = familyProxy(_FONT_WEIGHT_TO_PREFIX);
  970. const prefixes = new Set();
  971. Object.keys(STYLE_TO_PREFIX[a]).map(prefixes.add.bind(prefixes));
  972. Object.keys(STYLE_TO_PREFIX[r]).map(prefixes.add.bind(prefixes));
  973. Object.keys(STYLE_TO_PREFIX[o]).map(prefixes.add.bind(prefixes));
  974. function bunker(fn) {
  975. try {
  976. for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  977. args[_key - 1] = arguments[_key];
  978. }
  979. fn(...args);
  980. } catch (e) {
  981. if (!PRODUCTION) {
  982. throw e;
  983. }
  984. }
  985. }
  986. bunker(() => {
  987. if (IS_BROWSER && IS_DOM) {
  988. conflictDetection(window.FontAwesomeDetection.report);
  989. }
  990. });
  991. })));