utils.js 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734
  1. /*!
  2. * @pixi/utils - v6.5.10
  3. * Compiled Thu, 06 Jul 2023 15:25:11 UTC
  4. *
  5. * @pixi/utils is licensed under the MIT License.
  6. * http://www.opensource.org/licenses/mit-license
  7. */
  8. 'use strict';
  9. Object.defineProperty(exports, '__esModule', { value: true });
  10. var settings = require('@pixi/settings');
  11. var eventemitter3 = require('eventemitter3');
  12. var earcut = require('earcut');
  13. var url$1 = require('url');
  14. var constants = require('@pixi/constants');
  15. function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
  16. var eventemitter3__default = /*#__PURE__*/_interopDefaultLegacy(eventemitter3);
  17. var earcut__default = /*#__PURE__*/_interopDefaultLegacy(earcut);
  18. /**
  19. * This file contains redeclared types for Node `url` and `querystring` modules. These modules
  20. * don't provide their own typings but instead are a part of the full Node typings. The purpose of
  21. * this file is to redeclare the required types to avoid having the whole Node types as a
  22. * dependency.
  23. */
  24. var url = {
  25. parse: url$1.parse,
  26. format: url$1.format,
  27. resolve: url$1.resolve,
  28. };
  29. function assertPath(path) {
  30. if (typeof path !== 'string') {
  31. throw new TypeError("Path must be a string. Received " + JSON.stringify(path));
  32. }
  33. }
  34. function removeUrlParams(url) {
  35. var re = url.split('?')[0];
  36. return re.split('#')[0];
  37. }
  38. function escapeRegExp(string) {
  39. return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
  40. }
  41. function replaceAll(str, find, replace) {
  42. return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
  43. }
  44. // Resolves . and .. elements in a path with directory names
  45. function normalizeStringPosix(path, allowAboveRoot) {
  46. var res = '';
  47. var lastSegmentLength = 0;
  48. var lastSlash = -1;
  49. var dots = 0;
  50. var code;
  51. for (var i = 0; i <= path.length; ++i) {
  52. if (i < path.length) {
  53. code = path.charCodeAt(i);
  54. }
  55. else if (code === 47) {
  56. break;
  57. }
  58. else {
  59. code = 47;
  60. }
  61. if (code === 47) {
  62. if (lastSlash === i - 1 || dots === 1) ;
  63. else if (lastSlash !== i - 1 && dots === 2) {
  64. if (res.length < 2
  65. || lastSegmentLength !== 2
  66. || res.charCodeAt(res.length - 1) !== 46
  67. || res.charCodeAt(res.length - 2) !== 46) {
  68. if (res.length > 2) {
  69. var lastSlashIndex = res.lastIndexOf('/');
  70. if (lastSlashIndex !== res.length - 1) {
  71. if (lastSlashIndex === -1) {
  72. res = '';
  73. lastSegmentLength = 0;
  74. }
  75. else {
  76. res = res.slice(0, lastSlashIndex);
  77. lastSegmentLength = res.length - 1 - res.lastIndexOf('/');
  78. }
  79. lastSlash = i;
  80. dots = 0;
  81. continue;
  82. }
  83. }
  84. else if (res.length === 2 || res.length === 1) {
  85. res = '';
  86. lastSegmentLength = 0;
  87. lastSlash = i;
  88. dots = 0;
  89. continue;
  90. }
  91. }
  92. if (allowAboveRoot) {
  93. if (res.length > 0) {
  94. res += '/..';
  95. }
  96. else {
  97. res = '..';
  98. }
  99. lastSegmentLength = 2;
  100. }
  101. }
  102. else {
  103. if (res.length > 0) {
  104. res += "/" + path.slice(lastSlash + 1, i);
  105. }
  106. else {
  107. res = path.slice(lastSlash + 1, i);
  108. }
  109. lastSegmentLength = i - lastSlash - 1;
  110. }
  111. lastSlash = i;
  112. dots = 0;
  113. }
  114. else if (code === 46 && dots !== -1) {
  115. ++dots;
  116. }
  117. else {
  118. dots = -1;
  119. }
  120. }
  121. return res;
  122. }
  123. var path = {
  124. /**
  125. * Converts a path to posix format.
  126. * @param path - The path to convert to posix
  127. */
  128. toPosix: function (path) { return replaceAll(path, '\\', '/'); },
  129. /**
  130. * Checks if the path is a URL
  131. * @param path - The path to check
  132. */
  133. isUrl: function (path) { return (/^https?:/).test(this.toPosix(path)); },
  134. /**
  135. * Checks if the path is a data URL
  136. * @param path - The path to check
  137. */
  138. isDataUrl: function (path) {
  139. // eslint-disable-next-line max-len
  140. return (/^data:([a-z]+\/[a-z0-9-+.]+(;[a-z0-9-.!#$%*+.{}|~`]+=[a-z0-9-.!#$%*+.{}()_|~`]+)*)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s<>]*?)$/i)
  141. .test(path);
  142. },
  143. /**
  144. * Checks if the path has a protocol e.g. http://
  145. * This will return true for windows file paths
  146. * @param path - The path to check
  147. */
  148. hasProtocol: function (path) { return (/^[^/:]+:\//).test(this.toPosix(path)); },
  149. /**
  150. * Returns the protocol of the path e.g. http://, C:/, file:///
  151. * @param path - The path to get the protocol from
  152. */
  153. getProtocol: function (path) {
  154. assertPath(path);
  155. path = this.toPosix(path);
  156. var protocol = '';
  157. var isFile = (/^file:\/\/\//).exec(path);
  158. var isHttp = (/^[^/:]+:\/\//).exec(path);
  159. var isWindows = (/^[^/:]+:\//).exec(path);
  160. if (isFile || isHttp || isWindows) {
  161. var arr = (isFile === null || isFile === void 0 ? void 0 : isFile[0]) || (isHttp === null || isHttp === void 0 ? void 0 : isHttp[0]) || (isWindows === null || isWindows === void 0 ? void 0 : isWindows[0]);
  162. protocol = arr;
  163. path = path.slice(arr.length);
  164. }
  165. return protocol;
  166. },
  167. /**
  168. * Converts URL to an absolute path.
  169. * When loading from a Web Worker, we must use absolute paths.
  170. * If the URL is already absolute we return it as is
  171. * If it's not, we convert it
  172. * @param url - The URL to test
  173. * @param customBaseUrl - The base URL to use
  174. * @param customRootUrl - The root URL to use
  175. */
  176. toAbsolute: function (url, customBaseUrl, customRootUrl) {
  177. if (this.isDataUrl(url))
  178. { return url; }
  179. var baseUrl = removeUrlParams(this.toPosix(customBaseUrl !== null && customBaseUrl !== void 0 ? customBaseUrl : settings.settings.ADAPTER.getBaseUrl()));
  180. var rootUrl = removeUrlParams(this.toPosix(customRootUrl !== null && customRootUrl !== void 0 ? customRootUrl : this.rootname(baseUrl)));
  181. assertPath(url);
  182. url = this.toPosix(url);
  183. // root relative url
  184. if (url.startsWith('/')) {
  185. return path.join(rootUrl, url.slice(1));
  186. }
  187. var absolutePath = this.isAbsolute(url) ? url : this.join(baseUrl, url);
  188. return absolutePath;
  189. },
  190. /**
  191. * Normalizes the given path, resolving '..' and '.' segments
  192. * @param path - The path to normalize
  193. */
  194. normalize: function (path) {
  195. path = this.toPosix(path);
  196. assertPath(path);
  197. if (path.length === 0)
  198. { return '.'; }
  199. var protocol = '';
  200. var isAbsolute = path.startsWith('/');
  201. if (this.hasProtocol(path)) {
  202. protocol = this.rootname(path);
  203. path = path.slice(protocol.length);
  204. }
  205. var trailingSeparator = path.endsWith('/');
  206. // Normalize the path
  207. path = normalizeStringPosix(path, false);
  208. if (path.length > 0 && trailingSeparator)
  209. { path += '/'; }
  210. if (isAbsolute)
  211. { return "/" + path; }
  212. return protocol + path;
  213. },
  214. /**
  215. * Determines if path is an absolute path.
  216. * Absolute paths can be urls, data urls, or paths on disk
  217. * @param path - The path to test
  218. */
  219. isAbsolute: function (path) {
  220. assertPath(path);
  221. path = this.toPosix(path);
  222. if (this.hasProtocol(path))
  223. { return true; }
  224. return path.startsWith('/');
  225. },
  226. /**
  227. * Joins all given path segments together using the platform-specific separator as a delimiter,
  228. * then normalizes the resulting path
  229. * @param segments - The segments of the path to join
  230. */
  231. join: function () {
  232. var arguments$1 = arguments;
  233. var _a;
  234. var segments = [];
  235. for (var _i = 0; _i < arguments.length; _i++) {
  236. segments[_i] = arguments$1[_i];
  237. }
  238. if (segments.length === 0) {
  239. return '.';
  240. }
  241. var joined;
  242. for (var i = 0; i < segments.length; ++i) {
  243. var arg = segments[i];
  244. assertPath(arg);
  245. if (arg.length > 0) {
  246. if (joined === undefined)
  247. { joined = arg; }
  248. else {
  249. var prevArg = (_a = segments[i - 1]) !== null && _a !== void 0 ? _a : '';
  250. if (this.extname(prevArg)) {
  251. joined += "/../" + arg;
  252. }
  253. else {
  254. joined += "/" + arg;
  255. }
  256. }
  257. }
  258. }
  259. if (joined === undefined) {
  260. return '.';
  261. }
  262. return this.normalize(joined);
  263. },
  264. /**
  265. * Returns the directory name of a path
  266. * @param path - The path to parse
  267. */
  268. dirname: function (path) {
  269. assertPath(path);
  270. if (path.length === 0)
  271. { return '.'; }
  272. path = this.toPosix(path);
  273. var code = path.charCodeAt(0);
  274. var hasRoot = code === 47;
  275. var end = -1;
  276. var matchedSlash = true;
  277. var proto = this.getProtocol(path);
  278. var origpath = path;
  279. path = path.slice(proto.length);
  280. for (var i = path.length - 1; i >= 1; --i) {
  281. code = path.charCodeAt(i);
  282. if (code === 47) {
  283. if (!matchedSlash) {
  284. end = i;
  285. break;
  286. }
  287. }
  288. else {
  289. // We saw the first non-path separator
  290. matchedSlash = false;
  291. }
  292. }
  293. // if end is -1 and its a url then we need to add the path back
  294. // eslint-disable-next-line no-nested-ternary
  295. if (end === -1)
  296. { return hasRoot ? '/' : this.isUrl(origpath) ? proto + path : proto; }
  297. if (hasRoot && end === 1)
  298. { return '//'; }
  299. return proto + path.slice(0, end);
  300. },
  301. /**
  302. * Returns the root of the path e.g. /, C:/, file:///, http://domain.com/
  303. * @param path - The path to parse
  304. */
  305. rootname: function (path) {
  306. assertPath(path);
  307. path = this.toPosix(path);
  308. var root = '';
  309. if (path.startsWith('/'))
  310. { root = '/'; }
  311. else {
  312. root = this.getProtocol(path);
  313. }
  314. if (this.isUrl(path)) {
  315. // need to find the first path separator
  316. var index = path.indexOf('/', root.length);
  317. if (index !== -1) {
  318. root = path.slice(0, index);
  319. }
  320. else
  321. { root = path; }
  322. if (!root.endsWith('/'))
  323. { root += '/'; }
  324. }
  325. return root;
  326. },
  327. /**
  328. * Returns the last portion of a path
  329. * @param path - The path to test
  330. * @param ext - Optional extension to remove
  331. */
  332. basename: function (path, ext) {
  333. assertPath(path);
  334. if (ext)
  335. { assertPath(ext); }
  336. path = this.toPosix(path);
  337. var start = 0;
  338. var end = -1;
  339. var matchedSlash = true;
  340. var i;
  341. if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
  342. if (ext.length === path.length && ext === path)
  343. { return ''; }
  344. var extIdx = ext.length - 1;
  345. var firstNonSlashEnd = -1;
  346. for (i = path.length - 1; i >= 0; --i) {
  347. var code = path.charCodeAt(i);
  348. if (code === 47) {
  349. // If we reached a path separator that was not part of a set of path
  350. // separators at the end of the string, stop now
  351. if (!matchedSlash) {
  352. start = i + 1;
  353. break;
  354. }
  355. }
  356. else {
  357. if (firstNonSlashEnd === -1) {
  358. // We saw the first non-path separator, remember this index in case
  359. // we need it if the extension ends up not matching
  360. matchedSlash = false;
  361. firstNonSlashEnd = i + 1;
  362. }
  363. if (extIdx >= 0) {
  364. // Try to match the explicit extension
  365. if (code === ext.charCodeAt(extIdx)) {
  366. if (--extIdx === -1) {
  367. // We matched the extension, so mark this as the end of our path
  368. // component
  369. end = i;
  370. }
  371. }
  372. else {
  373. // Extension does not match, so our result is the entire path
  374. // component
  375. extIdx = -1;
  376. end = firstNonSlashEnd;
  377. }
  378. }
  379. }
  380. }
  381. if (start === end)
  382. { end = firstNonSlashEnd; }
  383. else if (end === -1)
  384. { end = path.length; }
  385. return path.slice(start, end);
  386. }
  387. for (i = path.length - 1; i >= 0; --i) {
  388. if (path.charCodeAt(i) === 47) {
  389. // If we reached a path separator that was not part of a set of path
  390. // separators at the end of the string, stop now
  391. if (!matchedSlash) {
  392. start = i + 1;
  393. break;
  394. }
  395. }
  396. else if (end === -1) {
  397. // We saw the first non-path separator, mark this as the end of our
  398. // path component
  399. matchedSlash = false;
  400. end = i + 1;
  401. }
  402. }
  403. if (end === -1)
  404. { return ''; }
  405. return path.slice(start, end);
  406. },
  407. /**
  408. * Returns the extension of the path, from the last occurrence of the . (period) character to end of string in the last
  409. * portion of the path. If there is no . in the last portion of the path, or if there are no . characters other than
  410. * the first character of the basename of path, an empty string is returned.
  411. * @param path - The path to parse
  412. */
  413. extname: function (path) {
  414. assertPath(path);
  415. path = this.toPosix(path);
  416. var startDot = -1;
  417. var startPart = 0;
  418. var end = -1;
  419. var matchedSlash = true;
  420. // Track the state of characters (if any) we see before our first dot and
  421. // after any path separator we find
  422. var preDotState = 0;
  423. for (var i = path.length - 1; i >= 0; --i) {
  424. var code = path.charCodeAt(i);
  425. if (code === 47) {
  426. // If we reached a path separator that was not part of a set of path
  427. // separators at the end of the string, stop now
  428. if (!matchedSlash) {
  429. startPart = i + 1;
  430. break;
  431. }
  432. continue;
  433. }
  434. if (end === -1) {
  435. // We saw the first non-path separator, mark this as the end of our
  436. // extension
  437. matchedSlash = false;
  438. end = i + 1;
  439. }
  440. if (code === 46) {
  441. // If this is our first dot, mark it as the start of our extension
  442. if (startDot === -1)
  443. { startDot = i; }
  444. else if (preDotState !== 1)
  445. { preDotState = 1; }
  446. }
  447. else if (startDot !== -1) {
  448. // We saw a non-dot and non-path separator before our dot, so we should
  449. // have a good chance at having a non-empty extension
  450. preDotState = -1;
  451. }
  452. }
  453. if (startDot === -1 || end === -1
  454. // We saw a non-dot character immediately before the dot
  455. || preDotState === 0
  456. // The (right-most) trimmed path component is exactly '..'
  457. // eslint-disable-next-line no-mixed-operators
  458. || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
  459. return '';
  460. }
  461. return path.slice(startDot, end);
  462. },
  463. /**
  464. * Parses a path into an object containing the 'root', `dir`, `base`, `ext`, and `name` properties.
  465. * @param path - The path to parse
  466. */
  467. parse: function (path) {
  468. assertPath(path);
  469. var ret = { root: '', dir: '', base: '', ext: '', name: '' };
  470. if (path.length === 0)
  471. { return ret; }
  472. path = this.toPosix(path);
  473. var code = path.charCodeAt(0);
  474. var isAbsolute = this.isAbsolute(path);
  475. var start;
  476. ret.root = this.rootname(path);
  477. if (isAbsolute || this.hasProtocol(path)) {
  478. start = 1;
  479. }
  480. else {
  481. start = 0;
  482. }
  483. var startDot = -1;
  484. var startPart = 0;
  485. var end = -1;
  486. var matchedSlash = true;
  487. var i = path.length - 1;
  488. // Track the state of characters (if any) we see before our first dot and
  489. // after any path separator we find
  490. var preDotState = 0;
  491. // Get non-dir info
  492. for (; i >= start; --i) {
  493. code = path.charCodeAt(i);
  494. if (code === 47) {
  495. // If we reached a path separator that was not part of a set of path
  496. // separators at the end of the string, stop now
  497. if (!matchedSlash) {
  498. startPart = i + 1;
  499. break;
  500. }
  501. continue;
  502. }
  503. if (end === -1) {
  504. // We saw the first non-path separator, mark this as the end of our
  505. // extension
  506. matchedSlash = false;
  507. end = i + 1;
  508. }
  509. if (code === 46) {
  510. // If this is our first dot, mark it as the start of our extension
  511. if (startDot === -1)
  512. { startDot = i; }
  513. else if (preDotState !== 1)
  514. { preDotState = 1; }
  515. }
  516. else if (startDot !== -1) {
  517. // We saw a non-dot and non-path separator before our dot, so we should
  518. // have a good chance at having a non-empty extension
  519. preDotState = -1;
  520. }
  521. }
  522. if (startDot === -1 || end === -1
  523. // We saw a non-dot character immediately before the dot
  524. || preDotState === 0
  525. // The (right-most) trimmed path component is exactly '..'
  526. // eslint-disable-next-line no-mixed-operators
  527. || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
  528. if (end !== -1) {
  529. if (startPart === 0 && isAbsolute)
  530. { ret.base = ret.name = path.slice(1, end); }
  531. else
  532. { ret.base = ret.name = path.slice(startPart, end); }
  533. }
  534. }
  535. else {
  536. if (startPart === 0 && isAbsolute) {
  537. ret.name = path.slice(1, startDot);
  538. ret.base = path.slice(1, end);
  539. }
  540. else {
  541. ret.name = path.slice(startPart, startDot);
  542. ret.base = path.slice(startPart, end);
  543. }
  544. ret.ext = path.slice(startDot, end);
  545. }
  546. ret.dir = this.dirname(path);
  547. return ret;
  548. },
  549. sep: '/',
  550. delimiter: ':'
  551. };
  552. /**
  553. * The prefix that denotes a URL is for a retina asset.
  554. * @static
  555. * @name RETINA_PREFIX
  556. * @memberof PIXI.settings
  557. * @type {RegExp}
  558. * @default /@([0-9\.]+)x/
  559. * @example `@2x`
  560. */
  561. settings.settings.RETINA_PREFIX = /@([0-9\.]+)x/;
  562. /**
  563. * Should the `failIfMajorPerformanceCaveat` flag be enabled as a context option used in the `isWebGLSupported` function.
  564. * If set to true, a WebGL renderer can fail to be created if the browser thinks there could be performance issues when
  565. * using WebGL.
  566. *
  567. * In PixiJS v6 this has changed from true to false by default, to allow WebGL to work in as many scenarios as possible.
  568. * However, some users may have a poor experience, for example, if a user has a gpu or driver version blacklisted by the
  569. * browser.
  570. *
  571. * If your application requires high performance rendering, you may wish to set this to false.
  572. * We recommend one of two options if you decide to set this flag to false:
  573. *
  574. * 1: Use the `pixi.js-legacy` package, which includes a Canvas renderer as a fallback in case high performance WebGL is
  575. * not supported.
  576. *
  577. * 2: Call `isWebGLSupported` (which if found in the PIXI.utils package) in your code before attempting to create a PixiJS
  578. * renderer, and show an error message to the user if the function returns false, explaining that their device & browser
  579. * combination does not support high performance WebGL.
  580. * This is a much better strategy than trying to create a PixiJS renderer and finding it then fails.
  581. * @static
  582. * @name FAIL_IF_MAJOR_PERFORMANCE_CAVEAT
  583. * @memberof PIXI.settings
  584. * @type {boolean}
  585. * @default false
  586. */
  587. settings.settings.FAIL_IF_MAJOR_PERFORMANCE_CAVEAT = false;
  588. var saidHello = false;
  589. var VERSION = '6.5.10';
  590. /**
  591. * Skips the hello message of renderers that are created after this is run.
  592. * @function skipHello
  593. * @memberof PIXI.utils
  594. */
  595. function skipHello() {
  596. saidHello = true;
  597. }
  598. /**
  599. * Logs out the version and renderer information for this running instance of PIXI.
  600. * If you don't want to see this message you can run `PIXI.utils.skipHello()` before
  601. * creating your renderer. Keep in mind that doing that will forever make you a jerk face.
  602. * @static
  603. * @function sayHello
  604. * @memberof PIXI.utils
  605. * @param {string} type - The string renderer type to log.
  606. */
  607. function sayHello(type) {
  608. var _a;
  609. if (saidHello) {
  610. return;
  611. }
  612. if (settings.settings.ADAPTER.getNavigator().userAgent.toLowerCase().indexOf('chrome') > -1) {
  613. var args = [
  614. "\n %c %c %c PixiJS " + VERSION + " - \u2730 " + type + " \u2730 %c %c http://www.pixijs.com/ %c %c \u2665%c\u2665%c\u2665 \n\n",
  615. 'background: #ff66a5; padding:5px 0;',
  616. 'background: #ff66a5; padding:5px 0;',
  617. 'color: #ff66a5; background: #030307; padding:5px 0;',
  618. 'background: #ff66a5; padding:5px 0;',
  619. 'background: #ffc3dc; padding:5px 0;',
  620. 'background: #ff66a5; padding:5px 0;',
  621. 'color: #ff2424; background: #fff; padding:5px 0;',
  622. 'color: #ff2424; background: #fff; padding:5px 0;',
  623. 'color: #ff2424; background: #fff; padding:5px 0;' ];
  624. (_a = globalThis.console).log.apply(_a, args);
  625. }
  626. else if (globalThis.console) {
  627. globalThis.console.log("PixiJS " + VERSION + " - " + type + " - http://www.pixijs.com/");
  628. }
  629. saidHello = true;
  630. }
  631. var supported;
  632. /**
  633. * Helper for checking for WebGL support.
  634. * @memberof PIXI.utils
  635. * @function isWebGLSupported
  636. * @returns {boolean} Is WebGL supported.
  637. */
  638. function isWebGLSupported() {
  639. if (typeof supported === 'undefined') {
  640. supported = (function supported() {
  641. var contextOptions = {
  642. stencil: true,
  643. failIfMajorPerformanceCaveat: settings.settings.FAIL_IF_MAJOR_PERFORMANCE_CAVEAT,
  644. };
  645. try {
  646. if (!settings.settings.ADAPTER.getWebGLRenderingContext()) {
  647. return false;
  648. }
  649. var canvas = settings.settings.ADAPTER.createCanvas();
  650. var gl = (canvas.getContext('webgl', contextOptions)
  651. || canvas.getContext('experimental-webgl', contextOptions));
  652. var success = !!(gl && gl.getContextAttributes().stencil);
  653. if (gl) {
  654. var loseContext = gl.getExtension('WEBGL_lose_context');
  655. if (loseContext) {
  656. loseContext.loseContext();
  657. }
  658. }
  659. gl = null;
  660. return success;
  661. }
  662. catch (e) {
  663. return false;
  664. }
  665. })();
  666. }
  667. return supported;
  668. }
  669. var aliceblue = "#f0f8ff";
  670. var antiquewhite = "#faebd7";
  671. var aqua = "#00ffff";
  672. var aquamarine = "#7fffd4";
  673. var azure = "#f0ffff";
  674. var beige = "#f5f5dc";
  675. var bisque = "#ffe4c4";
  676. var black = "#000000";
  677. var blanchedalmond = "#ffebcd";
  678. var blue = "#0000ff";
  679. var blueviolet = "#8a2be2";
  680. var brown = "#a52a2a";
  681. var burlywood = "#deb887";
  682. var cadetblue = "#5f9ea0";
  683. var chartreuse = "#7fff00";
  684. var chocolate = "#d2691e";
  685. var coral = "#ff7f50";
  686. var cornflowerblue = "#6495ed";
  687. var cornsilk = "#fff8dc";
  688. var crimson = "#dc143c";
  689. var cyan = "#00ffff";
  690. var darkblue = "#00008b";
  691. var darkcyan = "#008b8b";
  692. var darkgoldenrod = "#b8860b";
  693. var darkgray = "#a9a9a9";
  694. var darkgreen = "#006400";
  695. var darkgrey = "#a9a9a9";
  696. var darkkhaki = "#bdb76b";
  697. var darkmagenta = "#8b008b";
  698. var darkolivegreen = "#556b2f";
  699. var darkorange = "#ff8c00";
  700. var darkorchid = "#9932cc";
  701. var darkred = "#8b0000";
  702. var darksalmon = "#e9967a";
  703. var darkseagreen = "#8fbc8f";
  704. var darkslateblue = "#483d8b";
  705. var darkslategray = "#2f4f4f";
  706. var darkslategrey = "#2f4f4f";
  707. var darkturquoise = "#00ced1";
  708. var darkviolet = "#9400d3";
  709. var deeppink = "#ff1493";
  710. var deepskyblue = "#00bfff";
  711. var dimgray = "#696969";
  712. var dimgrey = "#696969";
  713. var dodgerblue = "#1e90ff";
  714. var firebrick = "#b22222";
  715. var floralwhite = "#fffaf0";
  716. var forestgreen = "#228b22";
  717. var fuchsia = "#ff00ff";
  718. var gainsboro = "#dcdcdc";
  719. var ghostwhite = "#f8f8ff";
  720. var goldenrod = "#daa520";
  721. var gold = "#ffd700";
  722. var gray = "#808080";
  723. var green = "#008000";
  724. var greenyellow = "#adff2f";
  725. var grey = "#808080";
  726. var honeydew = "#f0fff0";
  727. var hotpink = "#ff69b4";
  728. var indianred = "#cd5c5c";
  729. var indigo = "#4b0082";
  730. var ivory = "#fffff0";
  731. var khaki = "#f0e68c";
  732. var lavenderblush = "#fff0f5";
  733. var lavender = "#e6e6fa";
  734. var lawngreen = "#7cfc00";
  735. var lemonchiffon = "#fffacd";
  736. var lightblue = "#add8e6";
  737. var lightcoral = "#f08080";
  738. var lightcyan = "#e0ffff";
  739. var lightgoldenrodyellow = "#fafad2";
  740. var lightgray = "#d3d3d3";
  741. var lightgreen = "#90ee90";
  742. var lightgrey = "#d3d3d3";
  743. var lightpink = "#ffb6c1";
  744. var lightsalmon = "#ffa07a";
  745. var lightseagreen = "#20b2aa";
  746. var lightskyblue = "#87cefa";
  747. var lightslategray = "#778899";
  748. var lightslategrey = "#778899";
  749. var lightsteelblue = "#b0c4de";
  750. var lightyellow = "#ffffe0";
  751. var lime = "#00ff00";
  752. var limegreen = "#32cd32";
  753. var linen = "#faf0e6";
  754. var magenta = "#ff00ff";
  755. var maroon = "#800000";
  756. var mediumaquamarine = "#66cdaa";
  757. var mediumblue = "#0000cd";
  758. var mediumorchid = "#ba55d3";
  759. var mediumpurple = "#9370db";
  760. var mediumseagreen = "#3cb371";
  761. var mediumslateblue = "#7b68ee";
  762. var mediumspringgreen = "#00fa9a";
  763. var mediumturquoise = "#48d1cc";
  764. var mediumvioletred = "#c71585";
  765. var midnightblue = "#191970";
  766. var mintcream = "#f5fffa";
  767. var mistyrose = "#ffe4e1";
  768. var moccasin = "#ffe4b5";
  769. var navajowhite = "#ffdead";
  770. var navy = "#000080";
  771. var oldlace = "#fdf5e6";
  772. var olive = "#808000";
  773. var olivedrab = "#6b8e23";
  774. var orange = "#ffa500";
  775. var orangered = "#ff4500";
  776. var orchid = "#da70d6";
  777. var palegoldenrod = "#eee8aa";
  778. var palegreen = "#98fb98";
  779. var paleturquoise = "#afeeee";
  780. var palevioletred = "#db7093";
  781. var papayawhip = "#ffefd5";
  782. var peachpuff = "#ffdab9";
  783. var peru = "#cd853f";
  784. var pink = "#ffc0cb";
  785. var plum = "#dda0dd";
  786. var powderblue = "#b0e0e6";
  787. var purple = "#800080";
  788. var rebeccapurple = "#663399";
  789. var red = "#ff0000";
  790. var rosybrown = "#bc8f8f";
  791. var royalblue = "#4169e1";
  792. var saddlebrown = "#8b4513";
  793. var salmon = "#fa8072";
  794. var sandybrown = "#f4a460";
  795. var seagreen = "#2e8b57";
  796. var seashell = "#fff5ee";
  797. var sienna = "#a0522d";
  798. var silver = "#c0c0c0";
  799. var skyblue = "#87ceeb";
  800. var slateblue = "#6a5acd";
  801. var slategray = "#708090";
  802. var slategrey = "#708090";
  803. var snow = "#fffafa";
  804. var springgreen = "#00ff7f";
  805. var steelblue = "#4682b4";
  806. var tan = "#d2b48c";
  807. var teal = "#008080";
  808. var thistle = "#d8bfd8";
  809. var tomato = "#ff6347";
  810. var turquoise = "#40e0d0";
  811. var violet = "#ee82ee";
  812. var wheat = "#f5deb3";
  813. var white = "#ffffff";
  814. var whitesmoke = "#f5f5f5";
  815. var yellow = "#ffff00";
  816. var yellowgreen = "#9acd32";
  817. var cssColorNames = {
  818. aliceblue: aliceblue,
  819. antiquewhite: antiquewhite,
  820. aqua: aqua,
  821. aquamarine: aquamarine,
  822. azure: azure,
  823. beige: beige,
  824. bisque: bisque,
  825. black: black,
  826. blanchedalmond: blanchedalmond,
  827. blue: blue,
  828. blueviolet: blueviolet,
  829. brown: brown,
  830. burlywood: burlywood,
  831. cadetblue: cadetblue,
  832. chartreuse: chartreuse,
  833. chocolate: chocolate,
  834. coral: coral,
  835. cornflowerblue: cornflowerblue,
  836. cornsilk: cornsilk,
  837. crimson: crimson,
  838. cyan: cyan,
  839. darkblue: darkblue,
  840. darkcyan: darkcyan,
  841. darkgoldenrod: darkgoldenrod,
  842. darkgray: darkgray,
  843. darkgreen: darkgreen,
  844. darkgrey: darkgrey,
  845. darkkhaki: darkkhaki,
  846. darkmagenta: darkmagenta,
  847. darkolivegreen: darkolivegreen,
  848. darkorange: darkorange,
  849. darkorchid: darkorchid,
  850. darkred: darkred,
  851. darksalmon: darksalmon,
  852. darkseagreen: darkseagreen,
  853. darkslateblue: darkslateblue,
  854. darkslategray: darkslategray,
  855. darkslategrey: darkslategrey,
  856. darkturquoise: darkturquoise,
  857. darkviolet: darkviolet,
  858. deeppink: deeppink,
  859. deepskyblue: deepskyblue,
  860. dimgray: dimgray,
  861. dimgrey: dimgrey,
  862. dodgerblue: dodgerblue,
  863. firebrick: firebrick,
  864. floralwhite: floralwhite,
  865. forestgreen: forestgreen,
  866. fuchsia: fuchsia,
  867. gainsboro: gainsboro,
  868. ghostwhite: ghostwhite,
  869. goldenrod: goldenrod,
  870. gold: gold,
  871. gray: gray,
  872. green: green,
  873. greenyellow: greenyellow,
  874. grey: grey,
  875. honeydew: honeydew,
  876. hotpink: hotpink,
  877. indianred: indianred,
  878. indigo: indigo,
  879. ivory: ivory,
  880. khaki: khaki,
  881. lavenderblush: lavenderblush,
  882. lavender: lavender,
  883. lawngreen: lawngreen,
  884. lemonchiffon: lemonchiffon,
  885. lightblue: lightblue,
  886. lightcoral: lightcoral,
  887. lightcyan: lightcyan,
  888. lightgoldenrodyellow: lightgoldenrodyellow,
  889. lightgray: lightgray,
  890. lightgreen: lightgreen,
  891. lightgrey: lightgrey,
  892. lightpink: lightpink,
  893. lightsalmon: lightsalmon,
  894. lightseagreen: lightseagreen,
  895. lightskyblue: lightskyblue,
  896. lightslategray: lightslategray,
  897. lightslategrey: lightslategrey,
  898. lightsteelblue: lightsteelblue,
  899. lightyellow: lightyellow,
  900. lime: lime,
  901. limegreen: limegreen,
  902. linen: linen,
  903. magenta: magenta,
  904. maroon: maroon,
  905. mediumaquamarine: mediumaquamarine,
  906. mediumblue: mediumblue,
  907. mediumorchid: mediumorchid,
  908. mediumpurple: mediumpurple,
  909. mediumseagreen: mediumseagreen,
  910. mediumslateblue: mediumslateblue,
  911. mediumspringgreen: mediumspringgreen,
  912. mediumturquoise: mediumturquoise,
  913. mediumvioletred: mediumvioletred,
  914. midnightblue: midnightblue,
  915. mintcream: mintcream,
  916. mistyrose: mistyrose,
  917. moccasin: moccasin,
  918. navajowhite: navajowhite,
  919. navy: navy,
  920. oldlace: oldlace,
  921. olive: olive,
  922. olivedrab: olivedrab,
  923. orange: orange,
  924. orangered: orangered,
  925. orchid: orchid,
  926. palegoldenrod: palegoldenrod,
  927. palegreen: palegreen,
  928. paleturquoise: paleturquoise,
  929. palevioletred: palevioletred,
  930. papayawhip: papayawhip,
  931. peachpuff: peachpuff,
  932. peru: peru,
  933. pink: pink,
  934. plum: plum,
  935. powderblue: powderblue,
  936. purple: purple,
  937. rebeccapurple: rebeccapurple,
  938. red: red,
  939. rosybrown: rosybrown,
  940. royalblue: royalblue,
  941. saddlebrown: saddlebrown,
  942. salmon: salmon,
  943. sandybrown: sandybrown,
  944. seagreen: seagreen,
  945. seashell: seashell,
  946. sienna: sienna,
  947. silver: silver,
  948. skyblue: skyblue,
  949. slateblue: slateblue,
  950. slategray: slategray,
  951. slategrey: slategrey,
  952. snow: snow,
  953. springgreen: springgreen,
  954. steelblue: steelblue,
  955. tan: tan,
  956. teal: teal,
  957. thistle: thistle,
  958. tomato: tomato,
  959. turquoise: turquoise,
  960. violet: violet,
  961. wheat: wheat,
  962. white: white,
  963. whitesmoke: whitesmoke,
  964. yellow: yellow,
  965. yellowgreen: yellowgreen
  966. };
  967. /**
  968. * Converts a hexadecimal color number to an [R, G, B] array of normalized floats (numbers from 0.0 to 1.0).
  969. * @example
  970. * PIXI.utils.hex2rgb(0xffffff); // returns [1, 1, 1]
  971. * @memberof PIXI.utils
  972. * @function hex2rgb
  973. * @param {number} hex - The hexadecimal number to convert
  974. * @param {number[]} [out=[]] - If supplied, this array will be used rather than returning a new one
  975. * @returns {number[]} An array representing the [R, G, B] of the color where all values are floats.
  976. */
  977. function hex2rgb(hex, out) {
  978. if (out === void 0) { out = []; }
  979. out[0] = ((hex >> 16) & 0xFF) / 255;
  980. out[1] = ((hex >> 8) & 0xFF) / 255;
  981. out[2] = (hex & 0xFF) / 255;
  982. return out;
  983. }
  984. /**
  985. * Converts a hexadecimal color number to a string.
  986. * @example
  987. * PIXI.utils.hex2string(0xffffff); // returns "#ffffff"
  988. * @memberof PIXI.utils
  989. * @function hex2string
  990. * @param {number} hex - Number in hex (e.g., `0xffffff`)
  991. * @returns {string} The string color (e.g., `"#ffffff"`).
  992. */
  993. function hex2string(hex) {
  994. var hexString = hex.toString(16);
  995. hexString = '000000'.substring(0, 6 - hexString.length) + hexString;
  996. return "#" + hexString;
  997. }
  998. /**
  999. * Converts a string to a hexadecimal color number.
  1000. * It can handle:
  1001. * hex strings starting with #: "#ffffff"
  1002. * hex strings starting with 0x: "0xffffff"
  1003. * hex strings without prefix: "ffffff"
  1004. * css colors: "black"
  1005. * @example
  1006. * PIXI.utils.string2hex("#ffffff"); // returns 0xffffff, which is 16777215 as an integer
  1007. * @memberof PIXI.utils
  1008. * @function string2hex
  1009. * @param {string} string - The string color (e.g., `"#ffffff"`)
  1010. * @returns {number} Number in hexadecimal.
  1011. */
  1012. function string2hex(string) {
  1013. if (typeof string === 'string') {
  1014. string = cssColorNames[string.toLowerCase()] || string;
  1015. if (string[0] === '#') {
  1016. string = string.slice(1);
  1017. }
  1018. }
  1019. return parseInt(string, 16);
  1020. }
  1021. /**
  1022. * Converts a color as an [R, G, B] array of normalized floats to a hexadecimal number.
  1023. * @example
  1024. * PIXI.utils.rgb2hex([1, 1, 1]); // returns 0xffffff, which is 16777215 as an integer
  1025. * @memberof PIXI.utils
  1026. * @function rgb2hex
  1027. * @param {number[]} rgb - Array of numbers where all values are normalized floats from 0.0 to 1.0.
  1028. * @returns {number} Number in hexadecimal.
  1029. */
  1030. function rgb2hex(rgb) {
  1031. return (((rgb[0] * 255) << 16) + ((rgb[1] * 255) << 8) + (rgb[2] * 255 | 0));
  1032. }
  1033. /**
  1034. * Corrects PixiJS blend, takes premultiplied alpha into account
  1035. * @memberof PIXI.utils
  1036. * @function mapPremultipliedBlendModes
  1037. * @private
  1038. * @returns {Array<number[]>} Mapped modes.
  1039. */
  1040. function mapPremultipliedBlendModes() {
  1041. var pm = [];
  1042. var npm = [];
  1043. for (var i = 0; i < 32; i++) {
  1044. pm[i] = i;
  1045. npm[i] = i;
  1046. }
  1047. pm[constants.BLEND_MODES.NORMAL_NPM] = constants.BLEND_MODES.NORMAL;
  1048. pm[constants.BLEND_MODES.ADD_NPM] = constants.BLEND_MODES.ADD;
  1049. pm[constants.BLEND_MODES.SCREEN_NPM] = constants.BLEND_MODES.SCREEN;
  1050. npm[constants.BLEND_MODES.NORMAL] = constants.BLEND_MODES.NORMAL_NPM;
  1051. npm[constants.BLEND_MODES.ADD] = constants.BLEND_MODES.ADD_NPM;
  1052. npm[constants.BLEND_MODES.SCREEN] = constants.BLEND_MODES.SCREEN_NPM;
  1053. var array = [];
  1054. array.push(npm);
  1055. array.push(pm);
  1056. return array;
  1057. }
  1058. /**
  1059. * maps premultiply flag and blendMode to adjusted blendMode
  1060. * @memberof PIXI.utils
  1061. * @constant premultiplyBlendMode
  1062. * @type {Array<number[]>}
  1063. */
  1064. var premultiplyBlendMode = mapPremultipliedBlendModes();
  1065. /**
  1066. * changes blendMode according to texture format
  1067. * @memberof PIXI.utils
  1068. * @function correctBlendMode
  1069. * @param {number} blendMode - supposed blend mode
  1070. * @param {boolean} premultiplied - whether source is premultiplied
  1071. * @returns {number} true blend mode for this texture
  1072. */
  1073. function correctBlendMode(blendMode, premultiplied) {
  1074. return premultiplyBlendMode[premultiplied ? 1 : 0][blendMode];
  1075. }
  1076. /**
  1077. * combines rgb and alpha to out array
  1078. * @memberof PIXI.utils
  1079. * @function premultiplyRgba
  1080. * @param {Float32Array|number[]} rgb - input rgb
  1081. * @param {number} alpha - alpha param
  1082. * @param {Float32Array} [out] - output
  1083. * @param {boolean} [premultiply=true] - do premultiply it
  1084. * @returns {Float32Array} vec4 rgba
  1085. */
  1086. function premultiplyRgba(rgb, alpha, out, premultiply) {
  1087. out = out || new Float32Array(4);
  1088. if (premultiply || premultiply === undefined) {
  1089. out[0] = rgb[0] * alpha;
  1090. out[1] = rgb[1] * alpha;
  1091. out[2] = rgb[2] * alpha;
  1092. }
  1093. else {
  1094. out[0] = rgb[0];
  1095. out[1] = rgb[1];
  1096. out[2] = rgb[2];
  1097. }
  1098. out[3] = alpha;
  1099. return out;
  1100. }
  1101. /**
  1102. * premultiplies tint
  1103. * @memberof PIXI.utils
  1104. * @function premultiplyTint
  1105. * @param {number} tint - integer RGB
  1106. * @param {number} alpha - floating point alpha (0.0-1.0)
  1107. * @returns {number} tint multiplied by alpha
  1108. */
  1109. function premultiplyTint(tint, alpha) {
  1110. if (alpha === 1.0) {
  1111. return (alpha * 255 << 24) + tint;
  1112. }
  1113. if (alpha === 0.0) {
  1114. return 0;
  1115. }
  1116. var R = ((tint >> 16) & 0xFF);
  1117. var G = ((tint >> 8) & 0xFF);
  1118. var B = (tint & 0xFF);
  1119. R = ((R * alpha) + 0.5) | 0;
  1120. G = ((G * alpha) + 0.5) | 0;
  1121. B = ((B * alpha) + 0.5) | 0;
  1122. return (alpha * 255 << 24) + (R << 16) + (G << 8) + B;
  1123. }
  1124. /**
  1125. * converts integer tint and float alpha to vec4 form, premultiplies by default
  1126. * @memberof PIXI.utils
  1127. * @function premultiplyTintToRgba
  1128. * @param {number} tint - input tint
  1129. * @param {number} alpha - alpha param
  1130. * @param {Float32Array} [out] - output
  1131. * @param {boolean} [premultiply=true] - do premultiply it
  1132. * @returns {Float32Array} vec4 rgba
  1133. */
  1134. function premultiplyTintToRgba(tint, alpha, out, premultiply) {
  1135. out = out || new Float32Array(4);
  1136. out[0] = ((tint >> 16) & 0xFF) / 255.0;
  1137. out[1] = ((tint >> 8) & 0xFF) / 255.0;
  1138. out[2] = (tint & 0xFF) / 255.0;
  1139. if (premultiply || premultiply === undefined) {
  1140. out[0] *= alpha;
  1141. out[1] *= alpha;
  1142. out[2] *= alpha;
  1143. }
  1144. out[3] = alpha;
  1145. return out;
  1146. }
  1147. /**
  1148. * Generic Mask Stack data structure
  1149. * @memberof PIXI.utils
  1150. * @function createIndicesForQuads
  1151. * @param {number} size - Number of quads
  1152. * @param {Uint16Array|Uint32Array} [outBuffer] - Buffer for output, length has to be `6 * size`
  1153. * @returns {Uint16Array|Uint32Array} - Resulting index buffer
  1154. */
  1155. function createIndicesForQuads(size, outBuffer) {
  1156. if (outBuffer === void 0) { outBuffer = null; }
  1157. // the total number of indices in our array, there are 6 points per quad.
  1158. var totalIndices = size * 6;
  1159. outBuffer = outBuffer || new Uint16Array(totalIndices);
  1160. if (outBuffer.length !== totalIndices) {
  1161. throw new Error("Out buffer length is incorrect, got " + outBuffer.length + " and expected " + totalIndices);
  1162. }
  1163. // fill the indices with the quads to draw
  1164. for (var i = 0, j = 0; i < totalIndices; i += 6, j += 4) {
  1165. outBuffer[i + 0] = j + 0;
  1166. outBuffer[i + 1] = j + 1;
  1167. outBuffer[i + 2] = j + 2;
  1168. outBuffer[i + 3] = j + 0;
  1169. outBuffer[i + 4] = j + 2;
  1170. outBuffer[i + 5] = j + 3;
  1171. }
  1172. return outBuffer;
  1173. }
  1174. function getBufferType(array) {
  1175. if (array.BYTES_PER_ELEMENT === 4) {
  1176. if (array instanceof Float32Array) {
  1177. return 'Float32Array';
  1178. }
  1179. else if (array instanceof Uint32Array) {
  1180. return 'Uint32Array';
  1181. }
  1182. return 'Int32Array';
  1183. }
  1184. else if (array.BYTES_PER_ELEMENT === 2) {
  1185. if (array instanceof Uint16Array) {
  1186. return 'Uint16Array';
  1187. }
  1188. }
  1189. else if (array.BYTES_PER_ELEMENT === 1) {
  1190. if (array instanceof Uint8Array) {
  1191. return 'Uint8Array';
  1192. }
  1193. }
  1194. // TODO map out the rest of the array elements!
  1195. return null;
  1196. }
  1197. /* eslint-disable object-shorthand */
  1198. var map = { Float32Array: Float32Array, Uint32Array: Uint32Array, Int32Array: Int32Array, Uint8Array: Uint8Array };
  1199. function interleaveTypedArrays(arrays, sizes) {
  1200. var outSize = 0;
  1201. var stride = 0;
  1202. var views = {};
  1203. for (var i = 0; i < arrays.length; i++) {
  1204. stride += sizes[i];
  1205. outSize += arrays[i].length;
  1206. }
  1207. var buffer = new ArrayBuffer(outSize * 4);
  1208. var out = null;
  1209. var littleOffset = 0;
  1210. for (var i = 0; i < arrays.length; i++) {
  1211. var size = sizes[i];
  1212. var array = arrays[i];
  1213. /*
  1214. @todo This is unsafe casting but consistent with how the code worked previously. Should it stay this way
  1215. or should and `getBufferTypeUnsafe` function be exposed that throws an Error if unsupported type is passed?
  1216. */
  1217. var type = getBufferType(array);
  1218. if (!views[type]) {
  1219. views[type] = new map[type](buffer);
  1220. }
  1221. out = views[type];
  1222. for (var j = 0; j < array.length; j++) {
  1223. var indexStart = ((j / size | 0) * stride) + littleOffset;
  1224. var index = j % size;
  1225. out[indexStart + index] = array[j];
  1226. }
  1227. littleOffset += size;
  1228. }
  1229. return new Float32Array(buffer);
  1230. }
  1231. // Taken from the bit-twiddle package
  1232. /**
  1233. * Rounds to next power of two.
  1234. * @function nextPow2
  1235. * @memberof PIXI.utils
  1236. * @param {number} v - input value
  1237. * @returns {number} - next rounded power of two
  1238. */
  1239. function nextPow2(v) {
  1240. v += v === 0 ? 1 : 0;
  1241. --v;
  1242. v |= v >>> 1;
  1243. v |= v >>> 2;
  1244. v |= v >>> 4;
  1245. v |= v >>> 8;
  1246. v |= v >>> 16;
  1247. return v + 1;
  1248. }
  1249. /**
  1250. * Checks if a number is a power of two.
  1251. * @function isPow2
  1252. * @memberof PIXI.utils
  1253. * @param {number} v - input value
  1254. * @returns {boolean} `true` if value is power of two
  1255. */
  1256. function isPow2(v) {
  1257. return !(v & (v - 1)) && (!!v);
  1258. }
  1259. /**
  1260. * Computes ceil of log base 2
  1261. * @function log2
  1262. * @memberof PIXI.utils
  1263. * @param {number} v - input value
  1264. * @returns {number} logarithm base 2
  1265. */
  1266. function log2(v) {
  1267. var r = (v > 0xFFFF ? 1 : 0) << 4;
  1268. v >>>= r;
  1269. var shift = (v > 0xFF ? 1 : 0) << 3;
  1270. v >>>= shift;
  1271. r |= shift;
  1272. shift = (v > 0xF ? 1 : 0) << 2;
  1273. v >>>= shift;
  1274. r |= shift;
  1275. shift = (v > 0x3 ? 1 : 0) << 1;
  1276. v >>>= shift;
  1277. r |= shift;
  1278. return r | (v >> 1);
  1279. }
  1280. /**
  1281. * Remove items from a javascript array without generating garbage
  1282. * @function removeItems
  1283. * @memberof PIXI.utils
  1284. * @param {Array<any>} arr - Array to remove elements from
  1285. * @param {number} startIdx - starting index
  1286. * @param {number} removeCount - how many to remove
  1287. */
  1288. function removeItems(arr, startIdx, removeCount) {
  1289. var length = arr.length;
  1290. var i;
  1291. if (startIdx >= length || removeCount === 0) {
  1292. return;
  1293. }
  1294. removeCount = (startIdx + removeCount > length ? length - startIdx : removeCount);
  1295. var len = length - removeCount;
  1296. for (i = startIdx; i < len; ++i) {
  1297. arr[i] = arr[i + removeCount];
  1298. }
  1299. arr.length = len;
  1300. }
  1301. /**
  1302. * Returns sign of number
  1303. * @memberof PIXI.utils
  1304. * @function sign
  1305. * @param {number} n - the number to check the sign of
  1306. * @returns {number} 0 if `n` is 0, -1 if `n` is negative, 1 if `n` is positive
  1307. */
  1308. function sign(n) {
  1309. if (n === 0)
  1310. { return 0; }
  1311. return n < 0 ? -1 : 1;
  1312. }
  1313. var nextUid = 0;
  1314. /**
  1315. * Gets the next unique identifier
  1316. * @memberof PIXI.utils
  1317. * @function uid
  1318. * @returns {number} The next unique identifier to use.
  1319. */
  1320. function uid() {
  1321. return ++nextUid;
  1322. }
  1323. // A map of warning messages already fired
  1324. var warnings = {};
  1325. /**
  1326. * Helper for warning developers about deprecated features & settings.
  1327. * A stack track for warnings is given; useful for tracking-down where
  1328. * deprecated methods/properties/classes are being used within the code.
  1329. * @memberof PIXI.utils
  1330. * @function deprecation
  1331. * @param {string} version - The version where the feature became deprecated
  1332. * @param {string} message - Message should include what is deprecated, where, and the new solution
  1333. * @param {number} [ignoreDepth=3] - The number of steps to ignore at the top of the error stack
  1334. * this is mostly to ignore internal deprecation calls.
  1335. */
  1336. function deprecation(version, message, ignoreDepth) {
  1337. if (ignoreDepth === void 0) { ignoreDepth = 3; }
  1338. // Ignore duplicat
  1339. if (warnings[message]) {
  1340. return;
  1341. }
  1342. /* eslint-disable no-console */
  1343. var stack = new Error().stack;
  1344. // Handle IE < 10 and Safari < 6
  1345. if (typeof stack === 'undefined') {
  1346. console.warn('PixiJS Deprecation Warning: ', message + "\nDeprecated since v" + version);
  1347. }
  1348. else {
  1349. // chop off the stack trace which includes PixiJS internal calls
  1350. stack = stack.split('\n').splice(ignoreDepth).join('\n');
  1351. if (console.groupCollapsed) {
  1352. console.groupCollapsed('%cPixiJS Deprecation Warning: %c%s', 'color:#614108;background:#fffbe6', 'font-weight:normal;color:#614108;background:#fffbe6', message + "\nDeprecated since v" + version);
  1353. console.warn(stack);
  1354. console.groupEnd();
  1355. }
  1356. else {
  1357. console.warn('PixiJS Deprecation Warning: ', message + "\nDeprecated since v" + version);
  1358. console.warn(stack);
  1359. }
  1360. }
  1361. /* eslint-enable no-console */
  1362. warnings[message] = true;
  1363. }
  1364. /**
  1365. * @todo Describe property usage
  1366. * @static
  1367. * @name ProgramCache
  1368. * @memberof PIXI.utils
  1369. * @type {object}
  1370. */
  1371. var ProgramCache = {};
  1372. /**
  1373. * @todo Describe property usage
  1374. * @static
  1375. * @name TextureCache
  1376. * @memberof PIXI.utils
  1377. * @type {object}
  1378. */
  1379. var TextureCache = Object.create(null);
  1380. /**
  1381. * @todo Describe property usage
  1382. * @static
  1383. * @name BaseTextureCache
  1384. * @memberof PIXI.utils
  1385. * @type {object}
  1386. */
  1387. var BaseTextureCache = Object.create(null);
  1388. /**
  1389. * Destroys all texture in the cache
  1390. * @memberof PIXI.utils
  1391. * @function destroyTextureCache
  1392. */
  1393. function destroyTextureCache() {
  1394. var key;
  1395. for (key in TextureCache) {
  1396. TextureCache[key].destroy();
  1397. }
  1398. for (key in BaseTextureCache) {
  1399. BaseTextureCache[key].destroy();
  1400. }
  1401. }
  1402. /**
  1403. * Removes all textures from cache, but does not destroy them
  1404. * @memberof PIXI.utils
  1405. * @function clearTextureCache
  1406. */
  1407. function clearTextureCache() {
  1408. var key;
  1409. for (key in TextureCache) {
  1410. delete TextureCache[key];
  1411. }
  1412. for (key in BaseTextureCache) {
  1413. delete BaseTextureCache[key];
  1414. }
  1415. }
  1416. /**
  1417. * Creates a Canvas element of the given size to be used as a target for rendering to.
  1418. * @class
  1419. * @memberof PIXI.utils
  1420. */
  1421. var CanvasRenderTarget = /** @class */ (function () {
  1422. /**
  1423. * @param width - the width for the newly created canvas
  1424. * @param height - the height for the newly created canvas
  1425. * @param {number} [resolution=PIXI.settings.RESOLUTION] - The resolution / device pixel ratio of the canvas
  1426. */
  1427. function CanvasRenderTarget(width, height, resolution) {
  1428. this.canvas = settings.settings.ADAPTER.createCanvas();
  1429. this.context = this.canvas.getContext('2d');
  1430. this.resolution = resolution || settings.settings.RESOLUTION;
  1431. this.resize(width, height);
  1432. }
  1433. /**
  1434. * Clears the canvas that was created by the CanvasRenderTarget class.
  1435. * @private
  1436. */
  1437. CanvasRenderTarget.prototype.clear = function () {
  1438. this.context.setTransform(1, 0, 0, 1, 0, 0);
  1439. this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
  1440. };
  1441. /**
  1442. * Resizes the canvas to the specified width and height.
  1443. * @param desiredWidth - the desired width of the canvas
  1444. * @param desiredHeight - the desired height of the canvas
  1445. */
  1446. CanvasRenderTarget.prototype.resize = function (desiredWidth, desiredHeight) {
  1447. this.canvas.width = Math.round(desiredWidth * this.resolution);
  1448. this.canvas.height = Math.round(desiredHeight * this.resolution);
  1449. };
  1450. /** Destroys this canvas. */
  1451. CanvasRenderTarget.prototype.destroy = function () {
  1452. this.context = null;
  1453. this.canvas = null;
  1454. };
  1455. Object.defineProperty(CanvasRenderTarget.prototype, "width", {
  1456. /**
  1457. * The width of the canvas buffer in pixels.
  1458. * @member {number}
  1459. */
  1460. get: function () {
  1461. return this.canvas.width;
  1462. },
  1463. set: function (val) {
  1464. this.canvas.width = Math.round(val);
  1465. },
  1466. enumerable: false,
  1467. configurable: true
  1468. });
  1469. Object.defineProperty(CanvasRenderTarget.prototype, "height", {
  1470. /**
  1471. * The height of the canvas buffer in pixels.
  1472. * @member {number}
  1473. */
  1474. get: function () {
  1475. return this.canvas.height;
  1476. },
  1477. set: function (val) {
  1478. this.canvas.height = Math.round(val);
  1479. },
  1480. enumerable: false,
  1481. configurable: true
  1482. });
  1483. return CanvasRenderTarget;
  1484. }());
  1485. /**
  1486. * Trim transparent borders from a canvas
  1487. * @memberof PIXI.utils
  1488. * @function trimCanvas
  1489. * @param {HTMLCanvasElement} canvas - the canvas to trim
  1490. * @returns {object} Trim data
  1491. */
  1492. function trimCanvas(canvas) {
  1493. // https://gist.github.com/remy/784508
  1494. var width = canvas.width;
  1495. var height = canvas.height;
  1496. var context = canvas.getContext('2d', {
  1497. willReadFrequently: true,
  1498. });
  1499. var imageData = context.getImageData(0, 0, width, height);
  1500. var pixels = imageData.data;
  1501. var len = pixels.length;
  1502. var bound = {
  1503. top: null,
  1504. left: null,
  1505. right: null,
  1506. bottom: null,
  1507. };
  1508. var data = null;
  1509. var i;
  1510. var x;
  1511. var y;
  1512. for (i = 0; i < len; i += 4) {
  1513. if (pixels[i + 3] !== 0) {
  1514. x = (i / 4) % width;
  1515. y = ~~((i / 4) / width);
  1516. if (bound.top === null) {
  1517. bound.top = y;
  1518. }
  1519. if (bound.left === null) {
  1520. bound.left = x;
  1521. }
  1522. else if (x < bound.left) {
  1523. bound.left = x;
  1524. }
  1525. if (bound.right === null) {
  1526. bound.right = x + 1;
  1527. }
  1528. else if (bound.right < x) {
  1529. bound.right = x + 1;
  1530. }
  1531. if (bound.bottom === null) {
  1532. bound.bottom = y;
  1533. }
  1534. else if (bound.bottom < y) {
  1535. bound.bottom = y;
  1536. }
  1537. }
  1538. }
  1539. if (bound.top !== null) {
  1540. width = bound.right - bound.left;
  1541. height = bound.bottom - bound.top + 1;
  1542. data = context.getImageData(bound.left, bound.top, width, height);
  1543. }
  1544. return {
  1545. height: height,
  1546. width: width,
  1547. data: data,
  1548. };
  1549. }
  1550. /**
  1551. * Regexp for data URI.
  1552. * Based on: {@link https://github.com/ragingwind/data-uri-regex}
  1553. * @static
  1554. * @constant {RegExp|string} DATA_URI
  1555. * @memberof PIXI
  1556. * @example data:image/png;base64
  1557. */
  1558. var DATA_URI = /^\s*data:(?:([\w-]+)\/([\w+.-]+))?(?:;charset=([\w-]+))?(?:;(base64))?,(.*)/i;
  1559. /**
  1560. * @memberof PIXI.utils
  1561. * @interface DecomposedDataUri
  1562. */
  1563. /**
  1564. * type, eg. `image`
  1565. * @memberof PIXI.utils.DecomposedDataUri#
  1566. * @member {string} mediaType
  1567. */
  1568. /**
  1569. * Sub type, eg. `png`
  1570. * @memberof PIXI.utils.DecomposedDataUri#
  1571. * @member {string} subType
  1572. */
  1573. /**
  1574. * @memberof PIXI.utils.DecomposedDataUri#
  1575. * @member {string} charset
  1576. */
  1577. /**
  1578. * Data encoding, eg. `base64`
  1579. * @memberof PIXI.utils.DecomposedDataUri#
  1580. * @member {string} encoding
  1581. */
  1582. /**
  1583. * The actual data
  1584. * @memberof PIXI.utils.DecomposedDataUri#
  1585. * @member {string} data
  1586. */
  1587. /**
  1588. * Split a data URI into components. Returns undefined if
  1589. * parameter `dataUri` is not a valid data URI.
  1590. * @memberof PIXI.utils
  1591. * @function decomposeDataUri
  1592. * @param {string} dataUri - the data URI to check
  1593. * @returns {PIXI.utils.DecomposedDataUri|undefined} The decomposed data uri or undefined
  1594. */
  1595. function decomposeDataUri(dataUri) {
  1596. var dataUriMatch = DATA_URI.exec(dataUri);
  1597. if (dataUriMatch) {
  1598. return {
  1599. mediaType: dataUriMatch[1] ? dataUriMatch[1].toLowerCase() : undefined,
  1600. subType: dataUriMatch[2] ? dataUriMatch[2].toLowerCase() : undefined,
  1601. charset: dataUriMatch[3] ? dataUriMatch[3].toLowerCase() : undefined,
  1602. encoding: dataUriMatch[4] ? dataUriMatch[4].toLowerCase() : undefined,
  1603. data: dataUriMatch[5],
  1604. };
  1605. }
  1606. return undefined;
  1607. }
  1608. var tempAnchor;
  1609. /**
  1610. * Sets the `crossOrigin` property for this resource based on if the url
  1611. * for this resource is cross-origin. If crossOrigin was manually set, this
  1612. * function does nothing.
  1613. * Nipped from the resource loader!
  1614. * @ignore
  1615. * @param {string} url - The url to test.
  1616. * @param {object} [loc=window.location] - The location object to test against.
  1617. * @returns {string} The crossOrigin value to use (or empty string for none).
  1618. */
  1619. function determineCrossOrigin(url$1, loc) {
  1620. if (loc === void 0) { loc = globalThis.location; }
  1621. // data: and javascript: urls are considered same-origin
  1622. if (url$1.indexOf('data:') === 0) {
  1623. return '';
  1624. }
  1625. // default is window.location
  1626. loc = loc || globalThis.location;
  1627. if (!tempAnchor) {
  1628. tempAnchor = document.createElement('a');
  1629. }
  1630. // let the browser determine the full href for the url of this resource and then
  1631. // parse with the node url lib, we can't use the properties of the anchor element
  1632. // because they don't work in IE9 :(
  1633. tempAnchor.href = url$1;
  1634. var parsedUrl = url.parse(tempAnchor.href);
  1635. var samePort = (!parsedUrl.port && loc.port === '') || (parsedUrl.port === loc.port);
  1636. // if cross origin
  1637. if (parsedUrl.hostname !== loc.hostname || !samePort || parsedUrl.protocol !== loc.protocol) {
  1638. return 'anonymous';
  1639. }
  1640. return '';
  1641. }
  1642. /**
  1643. * get the resolution / device pixel ratio of an asset by looking for the prefix
  1644. * used by spritesheets and image urls
  1645. * @memberof PIXI.utils
  1646. * @function getResolutionOfUrl
  1647. * @param {string} url - the image path
  1648. * @param {number} [defaultValue=1] - the defaultValue if no filename prefix is set.
  1649. * @returns {number} resolution / device pixel ratio of an asset
  1650. */
  1651. function getResolutionOfUrl(url, defaultValue) {
  1652. var resolution = settings.settings.RETINA_PREFIX.exec(url);
  1653. if (resolution) {
  1654. return parseFloat(resolution[1]);
  1655. }
  1656. return defaultValue !== undefined ? defaultValue : 1;
  1657. }
  1658. Object.defineProperty(exports, 'isMobile', {
  1659. enumerable: true,
  1660. get: function () { return settings.isMobile; }
  1661. });
  1662. Object.defineProperty(exports, 'EventEmitter', {
  1663. enumerable: true,
  1664. get: function () { return eventemitter3__default["default"]; }
  1665. });
  1666. Object.defineProperty(exports, 'earcut', {
  1667. enumerable: true,
  1668. get: function () { return earcut__default["default"]; }
  1669. });
  1670. exports.BaseTextureCache = BaseTextureCache;
  1671. exports.CanvasRenderTarget = CanvasRenderTarget;
  1672. exports.DATA_URI = DATA_URI;
  1673. exports.ProgramCache = ProgramCache;
  1674. exports.TextureCache = TextureCache;
  1675. exports.clearTextureCache = clearTextureCache;
  1676. exports.correctBlendMode = correctBlendMode;
  1677. exports.createIndicesForQuads = createIndicesForQuads;
  1678. exports.decomposeDataUri = decomposeDataUri;
  1679. exports.deprecation = deprecation;
  1680. exports.destroyTextureCache = destroyTextureCache;
  1681. exports.determineCrossOrigin = determineCrossOrigin;
  1682. exports.getBufferType = getBufferType;
  1683. exports.getResolutionOfUrl = getResolutionOfUrl;
  1684. exports.hex2rgb = hex2rgb;
  1685. exports.hex2string = hex2string;
  1686. exports.interleaveTypedArrays = interleaveTypedArrays;
  1687. exports.isPow2 = isPow2;
  1688. exports.isWebGLSupported = isWebGLSupported;
  1689. exports.log2 = log2;
  1690. exports.nextPow2 = nextPow2;
  1691. exports.path = path;
  1692. exports.premultiplyBlendMode = premultiplyBlendMode;
  1693. exports.premultiplyRgba = premultiplyRgba;
  1694. exports.premultiplyTint = premultiplyTint;
  1695. exports.premultiplyTintToRgba = premultiplyTintToRgba;
  1696. exports.removeItems = removeItems;
  1697. exports.rgb2hex = rgb2hex;
  1698. exports.sayHello = sayHello;
  1699. exports.sign = sign;
  1700. exports.skipHello = skipHello;
  1701. exports.string2hex = string2hex;
  1702. exports.trimCanvas = trimCanvas;
  1703. exports.uid = uid;
  1704. exports.url = url;
  1705. //# sourceMappingURL=utils.js.map