UNPKG

karma

Version:

Spectacular Test Runner for JavaScript.

1,930 lines (1,801 loc) 75.9 kB
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ module.exports = { VERSION: '%KARMA_VERSION%', KARMA_URL_ROOT: '%KARMA_URL_ROOT%', KARMA_PROXY_PATH: '%KARMA_PROXY_PATH%', BROWSER_SOCKET_TIMEOUT: '%BROWSER_SOCKET_TIMEOUT%', CONTEXT_URL: 'context.html' } },{}],2:[function(require,module,exports){ var stringify = require('../common/stringify') var constant = require('./constants') var util = require('../common/util') function Karma (updater, socket, iframe, opener, navigator, location, document) { this.updater = updater var startEmitted = false var self = this var queryParams = util.parseQueryParams(location.search) var browserId = queryParams.id || util.generateId('manual-') var displayName = queryParams.displayName var returnUrl = queryParams['return_url' + ''] || null var resultsBufferLimit = 50 var resultsBuffer = [] // This is a no-op if not running with a Trusted Types CSP policy, and // lets tests declare that they trust the way that karma creates and handles // URLs. // // More info about the proposed Trusted Types standard at // https://github.com/WICG/trusted-types var policy = { createURL: function (s) { return s }, createScriptURL: function (s) { return s } } var trustedTypes = window.trustedTypes || window.TrustedTypes if (trustedTypes) { policy = trustedTypes.createPolicy('karma', policy) if (!policy.createURL) { // Install createURL for newer browsers. Only browsers that implement an // old version of the spec require createURL. // Should be safe to delete all reference to createURL by // February 2020. // https://github.com/WICG/trusted-types/pull/204 policy.createURL = function (s) { return s } } } // To start we will signal the server that we are not reconnecting. If the socket loses // connection and was able to reconnect to the Karma server we will get a // second 'connect' event. There we will pass 'true' and that will be passed to the // Karma server then, so that Karma can differentiate between a socket client // econnect and a full browser reconnect. var socketReconnect = false this.VERSION = constant.VERSION this.config = {} // Expose for testing purposes as there is no global socket.io // registry anymore. this.socket = socket // Set up postMessage bindings for current window // DEV: These are to allow windows in separate processes execute local tasks // Electron is one of these environments if (window.addEventListener) { window.addEventListener('message', function handleMessage (evt) { // Resolve the origin of our message var origin = evt.origin || evt.originalEvent.origin // If the message isn't from our host, then reject it if (origin !== window.location.origin) { return } // Take action based on the message type var method = evt.data.__karmaMethod if (method) { if (!self[method]) { self.error('Received `postMessage` for "' + method + '" but the method doesn\'t exist') return } self[method].apply(self, evt.data.__karmaArguments) } }, false) } var childWindow = null function navigateContextTo (url) { if (self.config.useIframe === false) { // run in new window if (self.config.runInParent === false) { // If there is a window already open, then close it // DEV: In some environments (e.g. Electron), we don't have setter access for location if (childWindow !== null && childWindow.closed !== true) { // The onbeforeunload listener was added by context to catch // unexpected navigations while running tests. childWindow.onbeforeunload = undefined childWindow.close() } childWindow = opener(url) if (childWindow === null) { self.error('Opening a new tab/window failed, probably because pop-ups are blocked.') } // run context on parent element (client_with_context) // using window.__karma__.scriptUrls to get the html element strings and load them dynamically } else if (url !== 'about:blank') { var loadScript = function (idx) { if (idx < window.__karma__.scriptUrls.length) { var parser = new DOMParser() // Revert escaped characters with special roles in HTML before parsing var string = window.__karma__.scriptUrls[idx] .replace(/\\x3C/g, '<') .replace(/\\x3E/g, '>') var doc = parser.parseFromString(string, 'text/html') var ele = doc.head.firstChild || doc.body.firstChild // script elements created by DomParser are marked as unexecutable, // create a new script element manually and copy necessary properties // so it is executable if (ele.tagName && ele.tagName.toLowerCase() === 'script') { var tmp = ele ele = document.createElement('script') ele.src = policy.createScriptURL(tmp.src) ele.crossOrigin = tmp.crossOrigin } ele.onload = function () { loadScript(idx + 1) } document.body.appendChild(ele) } else { window.__karma__.loaded() } } loadScript(0) } // run in iframe } else { // The onbeforeunload listener was added by the context to catch // unexpected navigations while running tests. iframe.contentWindow.onbeforeunload = undefined iframe.src = policy.createURL(url) } } this.log = function (type, args) { var values = [] for (var i = 0; i < args.length; i++) { values.push(this.stringify(args[i], 3)) } this.info({ log: values.join(', '), type: type }) } this.stringify = stringify function getLocation (url, lineno, colno) { var location = '' if (url !== undefined) { location += url } if (lineno !== undefined) { location += ':' + lineno } if (colno !== undefined) { location += ':' + colno } return location } // error during js file loading (most likely syntax error) // we are not going to execute at all. `window.onerror` callback. this.error = function (messageOrEvent, source, lineno, colno, error) { var message if (typeof messageOrEvent === 'string') { message = messageOrEvent var location = getLocation(source, lineno, colno) if (location !== '') { message += '\nat ' + location } if (error && error.stack) { message += '\n\n' + error.stack } } else { // create an object with the string representation of the message to // ensure all its content is properly transferred to the console log message = { message: messageOrEvent, str: messageOrEvent.toString() } } socket.emit('karma_error', message) self.updater.updateTestStatus('karma_error ' + message) this.complete() return false } this.result = function (originalResult) { var convertedResult = {} // Convert all array-like objects to real arrays. for (var propertyName in originalResult) { if (Object.prototype.hasOwnProperty.call(originalResult, propertyName)) { var propertyValue = originalResult[propertyName] if (Object.prototype.toString.call(propertyValue) === '[object Array]') { convertedResult[propertyName] = Array.prototype.slice.call(propertyValue) } else { convertedResult[propertyName] = propertyValue } } } if (!startEmitted) { socket.emit('start', { total: null }) self.updater.updateTestStatus('start') startEmitted = true } if (resultsBufferLimit === 1) { self.updater.updateTestStatus('result') return socket.emit('result', convertedResult) } resultsBuffer.push(convertedResult) if (resultsBuffer.length === resultsBufferLimit) { socket.emit('result', resultsBuffer) self.updater.updateTestStatus('result') resultsBuffer = [] } } this.complete = function (result) { if (resultsBuffer.length) { socket.emit('result', resultsBuffer) resultsBuffer = [] } socket.emit('complete', result || {}) if (this.config.clearContext) { navigateContextTo('about:blank') } else { self.updater.updateTestStatus('complete') } if (returnUrl) { var isReturnUrlAllowed = false for (var i = 0; i < this.config.allowedReturnUrlPatterns.length; i++) { var allowedReturnUrlPattern = new RegExp(this.config.allowedReturnUrlPatterns[i]) if (allowedReturnUrlPattern.test(returnUrl)) { isReturnUrlAllowed = true break } } if (!isReturnUrlAllowed) { throw new Error( 'Security: Navigation to '.concat( returnUrl, ' was blocked to prevent malicious exploits.' ) ) } location.href = returnUrl } } this.info = function (info) { // TODO(vojta): introduce special API for this if (!startEmitted && util.isDefined(info.total)) { socket.emit('start', info) startEmitted = true } else { socket.emit('info', info) } } socket.on('execute', function (cfg) { self.updater.updateTestStatus('execute') // reset startEmitted and reload the iframe startEmitted = false self.config = cfg navigateContextTo(constant.CONTEXT_URL) if (self.config.clientDisplayNone) { [].forEach.call(document.querySelectorAll('#banner, #browsers'), function (el) { el.style.display = 'none' }) } // clear the console before run // works only on FF (Safari, Chrome do not allow to clear console from js source) if (window.console && window.console.clear) { window.console.clear() } }) socket.on('stop', function () { this.complete() }.bind(this)) // Report the browser name and Id. Note that this event can also fire if the connection has // been temporarily lost, but the socket reconnected automatically. Read more in the docs: // https://socket.io/docs/client-api/#Event-%E2%80%98connect%E2%80%99 socket.on('connect', function () { socket.io.engine.on('upgrade', function () { resultsBufferLimit = 1 // Flush any results which were buffered before the upgrade to WebSocket protocol. if (resultsBuffer.length > 0) { socket.emit('result', resultsBuffer) resultsBuffer = [] } }) var info = { name: navigator.userAgent, id: browserId, isSocketReconnect: socketReconnect } if (displayName) { info.displayName = displayName } socket.emit('register', info) socketReconnect = true }) } module.exports = Karma },{"../common/stringify":5,"../common/util":6,"./constants":1}],3:[function(require,module,exports){ /* global io */ /* eslint-disable no-new */ var Karma = require('./karma') var StatusUpdater = require('./updater') var util = require('../common/util') var constants = require('./constants') var KARMA_URL_ROOT = constants.KARMA_URL_ROOT var KARMA_PROXY_PATH = constants.KARMA_PROXY_PATH var BROWSER_SOCKET_TIMEOUT = constants.BROWSER_SOCKET_TIMEOUT // Connect to the server using socket.io https://socket.io/ var socket = io(location.host, { reconnectionDelay: 500, reconnectionDelayMax: Infinity, timeout: BROWSER_SOCKET_TIMEOUT, path: KARMA_PROXY_PATH + KARMA_URL_ROOT.slice(1) + 'socket.io', 'sync disconnect on unload': true, useNativeTimers: true }) // instantiate the updater of the view var updater = new StatusUpdater(socket, util.elm('title'), util.elm('banner'), util.elm('browsers')) window.karma = new Karma(updater, socket, util.elm('context'), window.open, window.navigator, window.location, window.document) },{"../common/util":6,"./constants":1,"./karma":2,"./updater":4}],4:[function(require,module,exports){ var VERSION = require('./constants').VERSION function StatusUpdater (socket, titleElement, bannerElement, browsersElement) { function updateBrowsersInfo (browsers) { if (!browsersElement) { return } var status // clear browsersElement while (browsersElement.firstChild) { browsersElement.removeChild(browsersElement.firstChild) } for (var i = 0; i < browsers.length; i++) { status = browsers[i].isConnected ? 'idle' : 'executing' var li = document.createElement('li') li.setAttribute('class', status) li.textContent = browsers[i].name + ' is ' + status browsersElement.appendChild(li) } } var connectionText = 'never-connected' var testText = 'loading' var pingText = '' function updateBanner () { if (!titleElement || !bannerElement) { return } titleElement.textContent = 'Karma v ' + VERSION + ' - ' + connectionText + '; test: ' + testText + '; ' + pingText bannerElement.className = connectionText === 'connected' ? 'online' : 'offline' } function updateConnectionStatus (connectionStatus) { connectionText = connectionStatus || connectionText updateBanner() } function updateTestStatus (testStatus) { testText = testStatus || testText updateBanner() } function updatePingStatus (pingStatus) { pingText = pingStatus || pingText updateBanner() } socket.on('connect', function () { updateConnectionStatus('connected') }) socket.on('disconnect', function () { updateConnectionStatus('disconnected') }) socket.on('reconnecting', function (sec) { updateConnectionStatus('reconnecting in ' + sec + ' seconds') }) socket.on('reconnect', function () { updateConnectionStatus('reconnected') }) socket.on('reconnect_failed', function () { updateConnectionStatus('reconnect_failed') }) socket.on('info', updateBrowsersInfo) socket.on('disconnect', function () { updateBrowsersInfo([]) }) socket.on('ping', function () { updatePingStatus('ping...') }) socket.on('pong', function (latency) { updatePingStatus('ping ' + latency + 'ms') }) return { updateTestStatus: updateTestStatus } } module.exports = StatusUpdater },{"./constants":1}],5:[function(require,module,exports){ var serialize = null try { serialize = require('dom-serialize') } catch (e) { // Ignore failure on IE8 } var instanceOf = require('./util').instanceOf function isNode (obj) { return (obj.tagName || obj.nodeName) && obj.nodeType } function stringify (obj, depth) { if (depth === 0) { return '...' } if (obj === null) { return 'null' } switch (typeof obj) { case 'symbol': return obj.toString() case 'string': return "'" + obj + "'" case 'undefined': return 'undefined' case 'function': try { // function abc(a, b, c) { /* code goes here */ } // -> function abc(a, b, c) { ... } return obj.toString().replace(/\{[\s\S]*\}/, '{ ... }') } catch (err) { if (err instanceof TypeError) { // Support older browsers return 'function ' + (obj.name || '') + '() { ... }' } else { throw err } } case 'boolean': return obj ? 'true' : 'false' case 'object': var strs = [] if (instanceOf(obj, 'Array')) { strs.push('[') for (var i = 0, ii = obj.length; i < ii; i++) { if (i) { strs.push(', ') } strs.push(stringify(obj[i], depth - 1)) } strs.push(']') } else if (instanceOf(obj, 'Date')) { return obj.toString() } else if (instanceOf(obj, 'Text')) { return obj.nodeValue } else if (instanceOf(obj, 'Comment')) { return '<!--' + obj.nodeValue + '-->' } else if (obj.outerHTML) { return obj.outerHTML } else if (isNode(obj)) { if (serialize) { return serialize(obj) } else { return 'Skipping stringify, no support for dom-serialize' } } else if (instanceOf(obj, 'Error')) { return obj.toString() + '\n' + obj.stack } else { var constructor = 'Object' if (obj.constructor && typeof obj.constructor === 'function') { constructor = obj.constructor.name } strs.push(constructor) strs.push('{') var first = true for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { if (first) { first = false } else { strs.push(', ') } strs.push(key + ': ' + stringify(obj[key], depth - 1)) } } strs.push('}') } return strs.join('') default: return obj } } module.exports = stringify },{"./util":6,"dom-serialize":8}],6:[function(require,module,exports){ exports.instanceOf = function (value, constructorName) { return Object.prototype.toString.apply(value) === '[object ' + constructorName + ']' } exports.elm = function (id) { return document.getElementById(id) } exports.generateId = function (prefix) { return prefix + Math.floor(Math.random() * 10000) } exports.isUndefined = function (value) { return typeof value === 'undefined' } exports.isDefined = function (value) { return !exports.isUndefined(value) } exports.parseQueryParams = function (locationSearch) { var params = {} var pairs = locationSearch.slice(1).split('&') var keyValue for (var i = 0; i < pairs.length; i++) { keyValue = pairs[i].split('=') params[decodeURIComponent(keyValue[0])] = decodeURIComponent(keyValue[1]) } return params } },{}],7:[function(require,module,exports){ (function (global){ var NativeCustomEvent = global.CustomEvent; function useNative () { try { var p = new NativeCustomEvent('cat', { detail: { foo: 'bar' } }); return 'cat' === p.type && 'bar' === p.detail.foo; } catch (e) { } return false; } /** * Cross-browser `CustomEvent` constructor. * * https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent.CustomEvent * * @public */ module.exports = useNative() ? NativeCustomEvent : // IE >= 9 'undefined' !== typeof document && 'function' === typeof document.createEvent ? function CustomEvent (type, params) { var e = document.createEvent('CustomEvent'); if (params) { e.initCustomEvent(type, params.bubbles, params.cancelable, params.detail); } else { e.initCustomEvent(type, false, false, void 0); } return e; } : // IE <= 8 function CustomEvent (type, params) { var e = document.createEventObject(); e.type = type; if (params) { e.bubbles = Boolean(params.bubbles); e.cancelable = Boolean(params.cancelable); e.detail = params.detail; } else { e.bubbles = false; e.cancelable = false; e.detail = void 0; } return e; } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],8:[function(require,module,exports){ /** * Module dependencies. */ var extend = require('extend'); var encode = require('ent/encode'); var CustomEvent = require('custom-event'); var voidElements = require('void-elements'); /** * Module exports. */ exports = module.exports = serialize; exports.serializeElement = serializeElement; exports.serializeAttribute = serializeAttribute; exports.serializeText = serializeText; exports.serializeComment = serializeComment; exports.serializeDocument = serializeDocument; exports.serializeDoctype = serializeDoctype; exports.serializeDocumentFragment = serializeDocumentFragment; exports.serializeNodeList = serializeNodeList; /** * Serializes any DOM node. Returns a string. * * @param {Node} node - DOM Node to serialize * @param {String} [context] - optional arbitrary "context" string to use (useful for event listeners) * @param {Function} [fn] - optional callback function to use in the "serialize" event for this call * @param {EventTarget} [eventTarget] - optional EventTarget instance to emit the "serialize" event on (defaults to `node`) * return {String} * @public */ function serialize (node, context, fn, eventTarget) { if (!node) return ''; if ('function' === typeof context) { fn = context; context = null; } if (!context) context = null; var rtn; var nodeType = node.nodeType; if (!nodeType && 'number' === typeof node.length) { // assume it's a NodeList or Array of Nodes rtn = exports.serializeNodeList(node, context, fn); } else { if ('function' === typeof fn) { // one-time "serialize" event listener node.addEventListener('serialize', fn, false); } // emit a custom "serialize" event on `node`, in case there // are event listeners for custom serialization of this node var e = new CustomEvent('serialize', { bubbles: true, cancelable: true, detail: { serialize: null, context: context } }); e.serializeTarget = node; var target = eventTarget || node; var cancelled = !target.dispatchEvent(e); // `e.detail.serialize` can be set to a: // String - returned directly // Node - goes through serializer logic instead of `node` // Anything else - get Stringified first, and then returned directly var s = e.detail.serialize; if (s != null) { if ('string' === typeof s) { rtn = s; } else if ('number' === typeof s.nodeType) { // make it go through the serialization logic rtn = serialize(s, context, null, target); } else { rtn = String(s); } } else if (!cancelled) { // default serialization logic switch (nodeType) { case 1 /* element */: rtn = exports.serializeElement(node, context, eventTarget); break; case 2 /* attribute */: rtn = exports.serializeAttribute(node); break; case 3 /* text */: rtn = exports.serializeText(node); break; case 8 /* comment */: rtn = exports.serializeComment(node); break; case 9 /* document */: rtn = exports.serializeDocument(node, context, eventTarget); break; case 10 /* doctype */: rtn = exports.serializeDoctype(node); break; case 11 /* document fragment */: rtn = exports.serializeDocumentFragment(node, context, eventTarget); break; } } if ('function' === typeof fn) { node.removeEventListener('serialize', fn, false); } } return rtn || ''; } /** * Serialize an Attribute node. */ function serializeAttribute (node, opts) { return node.name + '="' + encode(node.value, extend({ named: true }, opts)) + '"'; } /** * Serialize a DOM element. */ function serializeElement (node, context, eventTarget) { var c, i, l; var name = node.nodeName.toLowerCase(); // opening tag var r = '<' + name; // attributes for (i = 0, c = node.attributes, l = c.length; i < l; i++) { r += ' ' + exports.serializeAttribute(c[i]); } r += '>'; // child nodes r += exports.serializeNodeList(node.childNodes, context, null, eventTarget); // closing tag, only for non-void elements if (!voidElements[name]) { r += '</' + name + '>'; } return r; } /** * Serialize a text node. */ function serializeText (node, opts) { return encode(node.nodeValue, extend({ named: true, special: { '<': true, '>': true, '&': true } }, opts)); } /** * Serialize a comment node. */ function serializeComment (node) { return '<!--' + node.nodeValue + '-->'; } /** * Serialize a Document node. */ function serializeDocument (node, context, eventTarget) { return exports.serializeNodeList(node.childNodes, context, null, eventTarget); } /** * Serialize a DOCTYPE node. * See: http://stackoverflow.com/a/10162353 */ function serializeDoctype (node) { var r = '<!DOCTYPE ' + node.name; if (node.publicId) { r += ' PUBLIC "' + node.publicId + '"'; } if (!node.publicId && node.systemId) { r += ' SYSTEM'; } if (node.systemId) { r += ' "' + node.systemId + '"'; } r += '>'; return r; } /** * Serialize a DocumentFragment instance. */ function serializeDocumentFragment (node, context, eventTarget) { return exports.serializeNodeList(node.childNodes, context, null, eventTarget); } /** * Serialize a NodeList/Array of nodes. */ function serializeNodeList (list, context, fn, eventTarget) { var r = ''; for (var i = 0, l = list.length; i < l; i++) { r += serialize(list[i], context, fn, eventTarget); } return r; } },{"custom-event":7,"ent/encode":9,"extend":11,"void-elements":13}],9:[function(require,module,exports){ var punycode = require('punycode'); var revEntities = require('./reversed.json'); module.exports = encode; function encode (str, opts) { if (typeof str !== 'string') { throw new TypeError('Expected a String'); } if (!opts) opts = {}; var numeric = true; if (opts.named) numeric = false; if (opts.numeric !== undefined) numeric = opts.numeric; var special = opts.special || { '"': true, "'": true, '<': true, '>': true, '&': true }; var codePoints = punycode.ucs2.decode(str); var chars = []; for (var i = 0; i < codePoints.length; i++) { var cc = codePoints[i]; var c = punycode.ucs2.encode([ cc ]); var e = revEntities[cc]; if (e && (cc >= 127 || special[c]) && !numeric) { chars.push('&' + (/;$/.test(e) ? e : e + ';')); } else if (cc < 32 || cc >= 127 || special[c]) { chars.push('&#' + cc + ';'); } else { chars.push(c); } } return chars.join(''); } },{"./reversed.json":10,"punycode":12}],10:[function(require,module,exports){ module.exports={ "9": "Tab;", "10": "NewLine;", "33": "excl;", "34": "quot;", "35": "num;", "36": "dollar;", "37": "percnt;", "38": "amp;", "39": "apos;", "40": "lpar;", "41": "rpar;", "42": "midast;", "43": "plus;", "44": "comma;", "46": "period;", "47": "sol;", "58": "colon;", "59": "semi;", "60": "lt;", "61": "equals;", "62": "gt;", "63": "quest;", "64": "commat;", "91": "lsqb;", "92": "bsol;", "93": "rsqb;", "94": "Hat;", "95": "UnderBar;", "96": "grave;", "123": "lcub;", "124": "VerticalLine;", "125": "rcub;", "160": "NonBreakingSpace;", "161": "iexcl;", "162": "cent;", "163": "pound;", "164": "curren;", "165": "yen;", "166": "brvbar;", "167": "sect;", "168": "uml;", "169": "copy;", "170": "ordf;", "171": "laquo;", "172": "not;", "173": "shy;", "174": "reg;", "175": "strns;", "176": "deg;", "177": "pm;", "178": "sup2;", "179": "sup3;", "180": "DiacriticalAcute;", "181": "micro;", "182": "para;", "183": "middot;", "184": "Cedilla;", "185": "sup1;", "186": "ordm;", "187": "raquo;", "188": "frac14;", "189": "half;", "190": "frac34;", "191": "iquest;", "192": "Agrave;", "193": "Aacute;", "194": "Acirc;", "195": "Atilde;", "196": "Auml;", "197": "Aring;", "198": "AElig;", "199": "Ccedil;", "200": "Egrave;", "201": "Eacute;", "202": "Ecirc;", "203": "Euml;", "204": "Igrave;", "205": "Iacute;", "206": "Icirc;", "207": "Iuml;", "208": "ETH;", "209": "Ntilde;", "210": "Ograve;", "211": "Oacute;", "212": "Ocirc;", "213": "Otilde;", "214": "Ouml;", "215": "times;", "216": "Oslash;", "217": "Ugrave;", "218": "Uacute;", "219": "Ucirc;", "220": "Uuml;", "221": "Yacute;", "222": "THORN;", "223": "szlig;", "224": "agrave;", "225": "aacute;", "226": "acirc;", "227": "atilde;", "228": "auml;", "229": "aring;", "230": "aelig;", "231": "ccedil;", "232": "egrave;", "233": "eacute;", "234": "ecirc;", "235": "euml;", "236": "igrave;", "237": "iacute;", "238": "icirc;", "239": "iuml;", "240": "eth;", "241": "ntilde;", "242": "ograve;", "243": "oacute;", "244": "ocirc;", "245": "otilde;", "246": "ouml;", "247": "divide;", "248": "oslash;", "249": "ugrave;", "250": "uacute;", "251": "ucirc;", "252": "uuml;", "253": "yacute;", "254": "thorn;", "255": "yuml;", "256": "Amacr;", "257": "amacr;", "258": "Abreve;", "259": "abreve;", "260": "Aogon;", "261": "aogon;", "262": "Cacute;", "263": "cacute;", "264": "Ccirc;", "265": "ccirc;", "266": "Cdot;", "267": "cdot;", "268": "Ccaron;", "269": "ccaron;", "270": "Dcaron;", "271": "dcaron;", "272": "Dstrok;", "273": "dstrok;", "274": "Emacr;", "275": "emacr;", "278": "Edot;", "279": "edot;", "280": "Eogon;", "281": "eogon;", "282": "Ecaron;", "283": "ecaron;", "284": "Gcirc;", "285": "gcirc;", "286": "Gbreve;", "287": "gbreve;", "288": "Gdot;", "289": "gdot;", "290": "Gcedil;", "292": "Hcirc;", "293": "hcirc;", "294": "Hstrok;", "295": "hstrok;", "296": "Itilde;", "297": "itilde;", "298": "Imacr;", "299": "imacr;", "302": "Iogon;", "303": "iogon;", "304": "Idot;", "305": "inodot;", "306": "IJlig;", "307": "ijlig;", "308": "Jcirc;", "309": "jcirc;", "310": "Kcedil;", "311": "kcedil;", "312": "kgreen;", "313": "Lacute;", "314": "lacute;", "315": "Lcedil;", "316": "lcedil;", "317": "Lcaron;", "318": "lcaron;", "319": "Lmidot;", "320": "lmidot;", "321": "Lstrok;", "322": "lstrok;", "323": "Nacute;", "324": "nacute;", "325": "Ncedil;", "326": "ncedil;", "327": "Ncaron;", "328": "ncaron;", "329": "napos;", "330": "ENG;", "331": "eng;", "332": "Omacr;", "333": "omacr;", "336": "Odblac;", "337": "odblac;", "338": "OElig;", "339": "oelig;", "340": "Racute;", "341": "racute;", "342": "Rcedil;", "343": "rcedil;", "344": "Rcaron;", "345": "rcaron;", "346": "Sacute;", "347": "sacute;", "348": "Scirc;", "349": "scirc;", "350": "Scedil;", "351": "scedil;", "352": "Scaron;", "353": "scaron;", "354": "Tcedil;", "355": "tcedil;", "356": "Tcaron;", "357": "tcaron;", "358": "Tstrok;", "359": "tstrok;", "360": "Utilde;", "361": "utilde;", "362": "Umacr;", "363": "umacr;", "364": "Ubreve;", "365": "ubreve;", "366": "Uring;", "367": "uring;", "368": "Udblac;", "369": "udblac;", "370": "Uogon;", "371": "uogon;", "372": "Wcirc;", "373": "wcirc;", "374": "Ycirc;", "375": "ycirc;", "376": "Yuml;", "377": "Zacute;", "378": "zacute;", "379": "Zdot;", "380": "zdot;", "381": "Zcaron;", "382": "zcaron;", "402": "fnof;", "437": "imped;", "501": "gacute;", "567": "jmath;", "710": "circ;", "711": "Hacek;", "728": "breve;", "729": "dot;", "730": "ring;", "731": "ogon;", "732": "tilde;", "733": "DiacriticalDoubleAcute;", "785": "DownBreve;", "913": "Alpha;", "914": "Beta;", "915": "Gamma;", "916": "Delta;", "917": "Epsilon;", "918": "Zeta;", "919": "Eta;", "920": "Theta;", "921": "Iota;", "922": "Kappa;", "923": "Lambda;", "924": "Mu;", "925": "Nu;", "926": "Xi;", "927": "Omicron;", "928": "Pi;", "929": "Rho;", "931": "Sigma;", "932": "Tau;", "933": "Upsilon;", "934": "Phi;", "935": "Chi;", "936": "Psi;", "937": "Omega;", "945": "alpha;", "946": "beta;", "947": "gamma;", "948": "delta;", "949": "epsilon;", "950": "zeta;", "951": "eta;", "952": "theta;", "953": "iota;", "954": "kappa;", "955": "lambda;", "956": "mu;", "957": "nu;", "958": "xi;", "959": "omicron;", "960": "pi;", "961": "rho;", "962": "varsigma;", "963": "sigma;", "964": "tau;", "965": "upsilon;", "966": "phi;", "967": "chi;", "968": "psi;", "969": "omega;", "977": "vartheta;", "978": "upsih;", "981": "varphi;", "982": "varpi;", "988": "Gammad;", "989": "gammad;", "1008": "varkappa;", "1009": "varrho;", "1013": "varepsilon;", "1014": "bepsi;", "1025": "IOcy;", "1026": "DJcy;", "1027": "GJcy;", "1028": "Jukcy;", "1029": "DScy;", "1030": "Iukcy;", "1031": "YIcy;", "1032": "Jsercy;", "1033": "LJcy;", "1034": "NJcy;", "1035": "TSHcy;", "1036": "KJcy;", "1038": "Ubrcy;", "1039": "DZcy;", "1040": "Acy;", "1041": "Bcy;", "1042": "Vcy;", "1043": "Gcy;", "1044": "Dcy;", "1045": "IEcy;", "1046": "ZHcy;", "1047": "Zcy;", "1048": "Icy;", "1049": "Jcy;", "1050": "Kcy;", "1051": "Lcy;", "1052": "Mcy;", "1053": "Ncy;", "1054": "Ocy;", "1055": "Pcy;", "1056": "Rcy;", "1057": "Scy;", "1058": "Tcy;", "1059": "Ucy;", "1060": "Fcy;", "1061": "KHcy;", "1062": "TScy;", "1063": "CHcy;", "1064": "SHcy;", "1065": "SHCHcy;", "1066": "HARDcy;", "1067": "Ycy;", "1068": "SOFTcy;", "1069": "Ecy;", "1070": "YUcy;", "1071": "YAcy;", "1072": "acy;", "1073": "bcy;", "1074": "vcy;", "1075": "gcy;", "1076": "dcy;", "1077": "iecy;", "1078": "zhcy;", "1079": "zcy;", "1080": "icy;", "1081": "jcy;", "1082": "kcy;", "1083": "lcy;", "1084": "mcy;", "1085": "ncy;", "1086": "ocy;", "1087": "pcy;", "1088": "rcy;", "1089": "scy;", "1090": "tcy;", "1091": "ucy;", "1092": "fcy;", "1093": "khcy;", "1094": "tscy;", "1095": "chcy;", "1096": "shcy;", "1097": "shchcy;", "1098": "hardcy;", "1099": "ycy;", "1100": "softcy;", "1101": "ecy;", "1102": "yucy;", "1103": "yacy;", "1105": "iocy;", "1106": "djcy;", "1107": "gjcy;", "1108": "jukcy;", "1109": "dscy;", "1110": "iukcy;", "1111": "yicy;", "1112": "jsercy;", "1113": "ljcy;", "1114": "njcy;", "1115": "tshcy;", "1116": "kjcy;", "1118": "ubrcy;", "1119": "dzcy;", "8194": "ensp;", "8195": "emsp;", "8196": "emsp13;", "8197": "emsp14;", "8199": "numsp;", "8200": "puncsp;", "8201": "ThinSpace;", "8202": "VeryThinSpace;", "8203": "ZeroWidthSpace;", "8204": "zwnj;", "8205": "zwj;", "8206": "lrm;", "8207": "rlm;", "8208": "hyphen;", "8211": "ndash;", "8212": "mdash;", "8213": "horbar;", "8214": "Vert;", "8216": "OpenCurlyQuote;", "8217": "rsquor;", "8218": "sbquo;", "8220": "OpenCurlyDoubleQuote;", "8221": "rdquor;", "8222": "ldquor;", "8224": "dagger;", "8225": "ddagger;", "8226": "bullet;", "8229": "nldr;", "8230": "mldr;", "8240": "permil;", "8241": "pertenk;", "8242": "prime;", "8243": "Prime;", "8244": "tprime;", "8245": "bprime;", "8249": "lsaquo;", "8250": "rsaquo;", "8254": "OverBar;", "8257": "caret;", "8259": "hybull;", "8260": "frasl;", "8271": "bsemi;", "8279": "qprime;", "8287": "MediumSpace;", "8288": "NoBreak;", "8289": "ApplyFunction;", "8290": "it;", "8291": "InvisibleComma;", "8364": "euro;", "8411": "TripleDot;", "8412": "DotDot;", "8450": "Copf;", "8453": "incare;", "8458": "gscr;", "8459": "Hscr;", "8460": "Poincareplane;", "8461": "quaternions;", "8462": "planckh;", "8463": "plankv;", "8464": "Iscr;", "8465": "imagpart;", "8466": "Lscr;", "8467": "ell;", "8469": "Nopf;", "8470": "numero;", "8471": "copysr;", "8472": "wp;", "8473": "primes;", "8474": "rationals;", "8475": "Rscr;", "8476": "Rfr;", "8477": "Ropf;", "8478": "rx;", "8482": "trade;", "8484": "Zopf;", "8487": "mho;", "8488": "Zfr;", "8489": "iiota;", "8492": "Bscr;", "8493": "Cfr;", "8495": "escr;", "8496": "expectation;", "8497": "Fscr;", "8499": "phmmat;", "8500": "oscr;", "8501": "aleph;", "8502": "beth;", "8503": "gimel;", "8504": "daleth;", "8517": "DD;", "8518": "DifferentialD;", "8519": "exponentiale;", "8520": "ImaginaryI;", "8531": "frac13;", "8532": "frac23;", "8533": "frac15;", "8534": "frac25;", "8535": "frac35;", "8536": "frac45;", "8537": "frac16;", "8538": "frac56;", "8539": "frac18;", "8540": "frac38;", "8541": "frac58;", "8542": "frac78;", "8592": "slarr;", "8593": "uparrow;", "8594": "srarr;", "8595": "ShortDownArrow;", "8596": "leftrightarrow;", "8597": "varr;", "8598": "UpperLeftArrow;", "8599": "UpperRightArrow;", "8600": "searrow;", "8601": "swarrow;", "8602": "nleftarrow;", "8603": "nrightarrow;", "8605": "rightsquigarrow;", "8606": "twoheadleftarrow;", "8607": "Uarr;", "8608": "twoheadrightarrow;", "8609": "Darr;", "8610": "leftarrowtail;", "8611": "rightarrowtail;", "8612": "mapstoleft;", "8613": "UpTeeArrow;", "8614": "RightTeeArrow;", "8615": "mapstodown;", "8617": "larrhk;", "8618": "rarrhk;", "8619": "looparrowleft;", "8620": "rarrlp;", "8621": "leftrightsquigarrow;", "8622": "nleftrightarrow;", "8624": "lsh;", "8625": "rsh;", "8626": "ldsh;", "8627": "rdsh;", "8629": "crarr;", "8630": "curvearrowleft;", "8631": "curvearrowright;", "8634": "olarr;", "8635": "orarr;", "8636": "lharu;", "8637": "lhard;", "8638": "upharpoonright;", "8639": "upharpoonleft;", "8640": "RightVector;", "8641": "rightharpoondown;", "8642": "RightDownVector;", "8643": "LeftDownVector;", "8644": "rlarr;", "8645": "UpArrowDownArrow;", "8646": "lrarr;", "8647": "llarr;", "8648": "uuarr;", "8649": "rrarr;", "8650": "downdownarrows;", "8651": "ReverseEquilibrium;", "8652": "rlhar;", "8653": "nLeftarrow;", "8654": "nLeftrightarrow;", "8655": "nRightarrow;", "8656": "Leftarrow;", "8657": "Uparrow;", "8658": "Rightarrow;", "8659": "Downarrow;", "8660": "Leftrightarrow;", "8661": "vArr;", "8662": "nwArr;", "8663": "neArr;", "8664": "seArr;", "8665": "swArr;", "8666": "Lleftarrow;", "8667": "Rrightarrow;", "8669": "zigrarr;", "8676": "LeftArrowBar;", "8677": "RightArrowBar;", "8693": "duarr;", "8701": "loarr;", "8702": "roarr;", "8703": "hoarr;", "8704": "forall;", "8705": "complement;", "8706": "PartialD;", "8707": "Exists;", "8708": "NotExists;", "8709": "varnothing;", "8711": "nabla;", "8712": "isinv;", "8713": "notinva;", "8715": "SuchThat;", "8716": "NotReverseElement;", "8719": "Product;", "8720": "Coproduct;", "8721": "sum;", "8722": "minus;", "8723": "mp;", "8724": "plusdo;", "8726": "ssetmn;", "8727": "lowast;", "8728": "SmallCircle;", "8730": "Sqrt;", "8733": "vprop;", "8734": "infin;", "8735": "angrt;", "8736": "angle;", "8737": "measuredangle;", "8738": "angsph;", "8739": "VerticalBar;", "8740": "nsmid;", "8741": "spar;", "8742": "nspar;", "8743": "wedge;", "8744": "vee;", "8745": "cap;", "8746": "cup;", "8747": "Integral;", "8748": "Int;", "8749": "tint;", "8750": "oint;", "8751": "DoubleContourIntegral;", "8752": "Cconint;", "8753": "cwint;", "8754": "cwconint;", "8755": "CounterClockwiseContourIntegral;", "8756": "therefore;", "8757": "because;", "8758": "ratio;", "8759": "Proportion;", "8760": "minusd;", "8762": "mDDot;", "8763": "homtht;", "8764": "Tilde;", "8765": "bsim;", "8766": "mstpos;", "8767": "acd;", "8768": "wreath;", "8769": "nsim;", "8770": "esim;", "8771": "TildeEqual;", "8772": "nsimeq;", "8773": "TildeFullEqual;", "8774": "simne;", "8775": "NotTildeFullEqual;", "8776": "TildeTilde;", "8777": "NotTildeTilde;", "8778": "approxeq;", "8779": "apid;", "8780": "bcong;", "8781": "CupCap;", "8782": "HumpDownHump;", "8783": "HumpEqual;", "8784": "esdot;", "8785": "eDot;", "8786": "fallingdotseq;", "8787": "risingdotseq;", "8788": "coloneq;", "8789": "eqcolon;", "8790": "eqcirc;", "8791": "cire;", "8793": "wedgeq;", "8794": "veeeq;", "8796": "trie;", "8799": "questeq;", "8800": "NotEqual;", "8801": "equiv;", "8802": "NotCongruent;", "8804": "leq;", "8805": "GreaterEqual;", "8806": "LessFullEqual;", "8807": "GreaterFullEqual;", "8808": "lneqq;", "8809": "gneqq;", "8810": "NestedLessLess;", "8811": "NestedGreaterGreater;", "8812": "twixt;", "8813": "NotCupCap;", "8814": "NotLess;", "8815": "NotGreater;", "8816": "NotLessEqual;", "8817": "NotGreaterEqual;", "8818": "lsim;", "8819": "gtrsim;", "8820": "NotLessTilde;", "8821": "NotGreaterTilde;", "8822": "lg;", "8823": "gtrless;", "8824": "ntlg;", "8825": "ntgl;", "8826": "Precedes;", "8827": "Succeeds;", "8828": "PrecedesSlantEqual;", "8829": "SucceedsSlantEqual;", "8830": "prsim;", "8831": "succsim;", "8832": "nprec;", "8833": "nsucc;", "8834": "subset;", "8835": "supset;", "8836": "nsub;", "8837": "nsup;", "8838": "SubsetEqual;", "8839": "supseteq;", "8840": "nsubseteq;", "8841": "nsupseteq;", "8842": "subsetneq;", "8843": "supsetneq;", "8845": "cupdot;", "8846": "uplus;", "8847": "SquareSubset;", "8848": "SquareSuperset;", "8849": "SquareSubsetEqual;", "8850": "SquareSupersetEqual;", "8851": "SquareIntersection;", "8852": "SquareUnion;", "8853": "oplus;", "8854": "ominus;", "8855": "otimes;", "8856": "osol;", "8857": "odot;", "8858": "ocir;", "8859": "oast;", "8861": "odash;", "8862": "plusb;", "8863": "minusb;", "8864": "timesb;", "8865": "sdotb;", "8866": "vdash;", "8867": "LeftTee;", "8868": "top;", "8869": "UpTee;", "8871": "models;", "8872": "vDash;", "8873": "Vdash;", "8874": "Vvdash;", "8875": "VDash;", "8876": "nvdash;", "8877": "nvDash;", "8878": "nVdash;", "8879": "nVDash;", "8880": "prurel;", "8882": "vltri;", "8883": "vrtri;", "8884": "trianglelefteq;", "8885": "trianglerighteq;", "8886": "origof;", "8887": "imof;", "8888": "mumap;", "8889": "hercon;", "8890": "intercal;", "8891": "veebar;", "8893": "barvee;", "8894": "angrtvb;", "8895": "lrtri;", "8896": "xwedge;", "8897": "xvee;", "8898": "xcap;", "8899": "xcup;", "8900": "diamond;", "8901": "sdot;", "8902": "Star;", "8903": "divonx;", "8904": "bowtie;", "8905": "ltimes;", "8906": "rtimes;", "8907": "lthree;", "8908": "rthree;", "8909": "bsime;", "8910": "cuvee;", "8911": "cuwed;", "8912": "Subset;", "8913": "Supset;", "8914": "Cap;", "8915": "Cup;", "8916": "pitchfork;", "8917": "epar;", "8918": "ltdot;", "8919": "gtrdot;", "8920": "Ll;", "8921": "ggg;", "8922": "LessEqualGreater;", "8923": "gtreqless;", "8926": "curlyeqprec;", "8927": "curlyeqsucc;", "8928": "nprcue;", "8929": "nsccue;", "8930": "nsqsube;", "8931": "nsqsupe;", "8934": "lnsim;", "8935": "gnsim;", "8936": "prnsim;", "8937": "succnsim;", "8938": "ntriangleleft;", "8939": "ntriangleright;", "8940": "ntrianglelefteq;", "8941": "ntrianglerighteq;", "8942": "vellip;", "8943": "ctdot;", "8944": "utdot;", "8945": "dtdot;", "8946": "disin;", "8947": "isinsv;", "8948": "isins;", "8949": "isindot;", "8950": "notinvc;", "8951": "notinvb;", "8953": "isinE;", "8954": "nisd;", "8955": "xnis;", "8956": "nis;", "8957": "notnivc;", "8958": "notnivb;", "8965": "barwedge;", "8966": "doublebarwedge;", "8968": "LeftCeiling;", "8969": "RightCeiling;", "8970": "lfloor;", "8971": "RightFloor;", "8972": "drcrop;", "8973": "dlcrop;", "8974": "urcrop;", "8975": "ulcrop;", "8976": "bnot;", "8978": "profline;", "8979": "profsurf;", "8981": "telrec;", "8982": "target;", "8988": "ulcorner;", "8989": "urcorner;", "8990": "llcorner;", "8991": "lrcorner;", "8994": "sfrown;", "8995": "ssmile;", "9005": "cylcty;", "9006": "profalar;", "9014": "topbot;", "9021": "ovbar;", "9023": "solbar;", "9084": "angzarr;", "9136": "lmoustache;", "9137": "rmoustache;", "9140": "tbrk;", "9141": "UnderBracket;", "9142": "bbrktbrk;", "9180": "OverParenthesis;", "9181": "UnderParenthesis;", "9182": "OverBrace;", "9183": "UnderBrace;", "9186": "trpezium;", "9191": "elinters;", "9251": "blank;", "9416": "oS;", "9472": "HorizontalLine;", "9474": "boxv;", "9484": "boxdr;", "9488": "boxdl;", "9492": "boxur;", "9496": "boxul;", "9500": "boxvr;", "9508": "boxvl;", "9516": "boxhd;", "9524": "boxhu;", "9532": "boxvh;", "9552": "boxH;", "9553": "boxV;", "9554": "boxdR;", "9555": "boxDr;", "9556": "boxDR;", "9557": "boxdL;", "9558": "boxDl;", "9559": "boxDL;", "9560": "boxuR;", "9561": "boxUr;", "9562": "boxUR;", "9563": "boxuL;", "9564": "boxUl;", "9565": "boxUL;", "9566": "boxvR;", "9567": "boxVr;", "9568": "boxVR;", "9569": "boxvL;", "9570": "boxVl;", "9571": "boxVL;", "9572": "boxHd;", "9573": "boxhD;", "9574": "boxHD;", "9575": "boxHu;", "9576": "boxhU;", "9577": "boxHU;", "9578": "boxvH;", "9579": "boxVh;", "9580": "boxVH;", "9600": "uhblk;", "9604": "lhblk;", "9608": "block;", "9617": "blk14;", "9618": "blk12;", "9619": "blk34;", "9633": "square;", "9642": "squf;", "9643": "EmptyVerySmallSquare;", "9645": "rect;", "9646": "marker;", "9649": "fltns;", "9651": "xutri;", "9652": "utrif;", "9653": "utri;", "9656": "rtrif;", "9657": "triangleright;", "9661": "xdtri;", "9662": "dtrif;", "9663": "triangledown;", "9666": "ltrif;", "9667": "triangleleft;", "9674": "lozenge;", "9675": "cir;", "9708": "tridot;", "9711": "xcirc;", "9720": "ultri;", "9721": "urtri;", "9722": "lltri;", "9723": "EmptySmallSquare;", "9724": "FilledSmallSquare;", "9733": "starf;", "9734": "star;", "9742": "phone;", "9792": "female;", "9794": "male;", "9824": "spadesuit;", "9827": "clubsuit;", "9829": "heartsuit;", "9830": "diams;", "9834": "sung;", "9837": "flat;", "9838": "natural;", "9839": "sharp;", "10003": "checkmark;", "10007": "cross;", "10016": "maltese;", "10038": "sext;", "10072": "VerticalSeparator;", "10098": "lbbrk;", "10099": "rbbrk;", "10184": "bsolhsub;", "10185": "suphsol;", "10214": "lobrk;", "10215": "robrk;", "10216": "LeftAngleBracket;", "10217": "RightAngleBracket;", "10218": "Lang;", "10219": "Rang;", "10220": "loang;", "10221": "roang;", "10229": "xlarr;", "10230": "xrarr;", "10231": "xharr;", "10232": "xlArr;", "10233": "xrArr;", "10234": "xhArr;", "10236": "xmap;", "10239": "dzigrarr;", "10498": "nvlArr;", "10499": "nvrArr;", "10500": "nvHarr;", "10501": "Map;", "10508": "lbarr;", "10509": "rbarr;", "10510": "lBarr;", "10511": "rBarr;", "10512": "RBarr;", "10513": "DDotrahd;", "10514": "UpArrowBar;", "10515": "DownArrowBar;", "10518": "Rarrtl;", "10521": "latail;", "10522": "ratail;", "10523": "lAtail;", "10524": "rAtail;", "10525": "larrfs;", "10526": "rarrfs;", "10527": "larrbfs;", "10528": "rarrbfs;", "10531": "nwarhk;", "10532": "nearhk;", "10533": "searhk;", "10534": "swarhk;", "10535": "nwnear;", "10536": "toea;", "10537": "tosa;", "10538": "swnwar;", "10547": "rarrc;", "10549": "cudarrr;", "10550": "ldca;", "10551": "rdca;", "10552": "cudarrl;", "10553": "larrpl;", "10556": "curarrm;", "10557": "cularrp;", "10565": "rarrpl;", "10568": "harrcir;", "10569": "Uarrocir;", "10570": "lurdshar;", "10571": "ldrushar;", "10574": "LeftRightVector;", "10575": "RightUpDownVector;", "10576": "DownLeftRightVector;", "10577": "LeftUpDownVector;", "10578": "LeftVectorBar;", "10579": "RightVectorBa