UNPKG

@limetech/lime-elements

Version:
1,655 lines (1,513 loc) • 172 kB
import { r as registerInstance, c as createEvent, h, a as getElement } from './index-DBTJNfo7.js'; import { t as translate } from './translations-DVRaJQvC.js'; import { d as defaultSchema, u as unified, r as rehypeParse, a as rehypeSanitize, v as visit, b as rehypeStringify } from './index-CJ0GYrWG.js'; import './_commonjsHelpers-BFTU3MAI.js'; /** * * @param fileName * @param url */ function detectExtension(fileName, url) { const pathLike = fileName || url; if (!pathLike) { return 'unknown'; } const extension = pathLike.split('.').pop().toLowerCase(); const extensionsToTypes = { pdf: 'pdf', jpg: 'image', jpeg: 'image', heic: 'image', bmp: 'image', png: 'image', gif: 'image', svg: 'image', svgz: 'image', ep: 'image', eps: 'image', avi: 'video', flv: 'video', h264: 'video', mov: 'video', mp4: 'video', mwv: 'video', mkv: 'video', mp3: 'audio', wav: 'audio', wma: 'audio', ogg: 'audio', txt: 'text', json: 'text', html: 'text', xml: 'text', eml: 'email', // Word doc: 'office', docx: 'office', odt: 'office', dot: 'office', dotx: 'office', docm: 'office', // not supported dotm: 'office', // not yet tested // Presentation pot: 'office', // not tested ppt: 'office', pptx: 'office', odp: 'office', potx: 'office', // not supported potm: 'office', // not supported pps: 'office', ppsx: 'office', ppsm: 'office', // not supported pptm: 'office', // not supported ppam: 'office', // not tested pages: 'office', // not supported (Apple) // Spreadsheet xls: 'office', xlsx: 'office', xlsm: 'office', xlsb: 'office', ods: 'office', csv: 'office', // not supported numbers: 'office', // not supported (Apple) }; return extensionsToTypes[extension] || 'unknown'; } class Fullscreen { constructor(element) { this.requestFullscreen = () => { if (this.enter) { this.enter(); } }; this.exitFullscreen = () => { if (this.exit) { this.exit.bind(window.document)(); } }; this.toggle = () => { const doc = window.document; const isFullscreen = doc.fullscreenElement || doc.mozFullScreenElement || doc.webkitFullscreenElement || doc.msFullscreenElement; if (isFullscreen) { this.exitFullscreen(); } else { this.requestFullscreen(); } }; this.enter = element.requestFullscreen || element.msRequestFullscreen || element.mozRequestFullScreen || element.webkitRequestFullscreen; this.enter = this.enter.bind(element); const doc = window.document; this.exit = doc.exitFullscreen || doc.msExitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen; } isSupported() { return !!this.requestFullscreen; } } const textEncoder = new TextEncoder(); const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; // Use a lookup table to find the index. const base64Lookup = new Uint8Array(256); for (var i = 0; i < base64Chars.length; i++) { base64Lookup[base64Chars.charCodeAt(i)] = i; } function decodeBase64(base64) { let bufferLength = Math.ceil(base64.length / 4) * 3; const len = base64.length; let p = 0; if (base64.length % 4 === 3) { bufferLength--; } else if (base64.length % 4 === 2) { bufferLength -= 2; } else if (base64[base64.length - 1] === '=') { bufferLength--; if (base64[base64.length - 2] === '=') { bufferLength--; } } const arrayBuffer = new ArrayBuffer(bufferLength); const bytes = new Uint8Array(arrayBuffer); for (let i = 0; i < len; i += 4) { let encoded1 = base64Lookup[base64.charCodeAt(i)]; let encoded2 = base64Lookup[base64.charCodeAt(i + 1)]; let encoded3 = base64Lookup[base64.charCodeAt(i + 2)]; let encoded4 = base64Lookup[base64.charCodeAt(i + 3)]; bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); } return arrayBuffer; } function getDecoder(charset) { charset = charset || 'utf8'; let decoder; try { decoder = new TextDecoder(charset); } catch (err) { decoder = new TextDecoder('windows-1252'); } return decoder; } /** * Converts a Blob into an ArrayBuffer * @param {Blob} blob Blob to convert * @returns {ArrayBuffer} Converted value */ async function blobToArrayBuffer(blob) { if ('arrayBuffer' in blob) { return await blob.arrayBuffer(); } const fr = new FileReader(); return new Promise((resolve, reject) => { fr.onload = function (e) { resolve(e.target.result); }; fr.onerror = function (e) { reject(fr.error); }; fr.readAsArrayBuffer(blob); }); } function getHex(c) { if ( (c >= 0x30 /* 0 */ && c <= 0x39) /* 9 */ || (c >= 0x61 /* a */ && c <= 0x66) /* f */ || (c >= 0x41 /* A */ && c <= 0x46) /* F */ ) { return String.fromCharCode(c); } return false; } /** * Decode a complete mime word encoded string * * @param {String} str Mime word encoded string * @return {String} Decoded unicode string */ function decodeWord(charset, encoding, str) { // RFC2231 added language tag to the encoding // see: https://tools.ietf.org/html/rfc2231#section-5 // this implementation silently ignores this tag let splitPos = charset.indexOf('*'); if (splitPos >= 0) { charset = charset.substr(0, splitPos); } encoding = encoding.toUpperCase(); let byteStr; if (encoding === 'Q') { str = str // remove spaces between = and hex char, this might indicate invalidly applied line splitting .replace(/=\s+([0-9a-fA-F])/g, '=$1') // convert all underscores to spaces .replace(/[_\s]/g, ' '); let buf = textEncoder.encode(str); let encodedBytes = []; for (let i = 0, len = buf.length; i < len; i++) { let c = buf[i]; if (i <= len - 2 && c === 0x3d /* = */) { let c1 = getHex(buf[i + 1]); let c2 = getHex(buf[i + 2]); if (c1 && c2) { let c = parseInt(c1 + c2, 16); encodedBytes.push(c); i += 2; continue; } } encodedBytes.push(c); } byteStr = new ArrayBuffer(encodedBytes.length); let dataView = new DataView(byteStr); for (let i = 0, len = encodedBytes.length; i < len; i++) { dataView.setUint8(i, encodedBytes[i]); } } else if (encoding === 'B') { byteStr = decodeBase64(str.replace(/[^a-zA-Z0-9\+\/=]+/g, '')); } else { // keep as is, convert ArrayBuffer to unicode string, assume utf8 byteStr = textEncoder.encode(str); } return getDecoder(charset).decode(byteStr); } function decodeWords(str) { let joinString = true; while (true) { let result = (str || '') .toString() // find base64 words that can be joined .replace( /(=\?([^?]+)\?[Bb]\?([^?]*)\?=)\s*(?==\?([^?]+)\?[Bb]\?[^?]*\?=)/g, (match, left, chLeft, encodedLeftStr, chRight) => { if (!joinString) { return match; } // only mark b64 chunks to be joined if charsets match and left side does not end with = if (chLeft === chRight && encodedLeftStr.length % 4 === 0 && !/=$/.test(encodedLeftStr)) { // set a joiner marker return left + '__\x00JOIN\x00__'; } return match; } ) // find QP words that can be joined .replace( /(=\?([^?]+)\?[Qq]\?[^?]*\?=)\s*(?==\?([^?]+)\?[Qq]\?[^?]*\?=)/g, (match, left, chLeft, chRight) => { if (!joinString) { return match; } // only mark QP chunks to be joined if charsets match if (chLeft === chRight) { // set a joiner marker return left + '__\x00JOIN\x00__'; } return match; } ) // join base64 encoded words .replace(/(\?=)?__\x00JOIN\x00__(=\?([^?]+)\?[QqBb]\?)?/g, '') // remove spaces between mime encoded words .replace(/(=\?[^?]+\?[QqBb]\?[^?]*\?=)\s+(?==\?[^?]+\?[QqBb]\?[^?]*\?=)/g, '$1') // decode words .replace(/=\?([\w_\-*]+)\?([QqBb])\?([^?]*)\?=/g, (m, charset, encoding, text) => decodeWord(charset, encoding, text) ); if (joinString && result.indexOf('\ufffd') >= 0) { // text contains \ufffd (EF BF BD), so unicode conversion failed, retry without joining strings joinString = false; } else { return result; } } } function decodeURIComponentWithCharset(encodedStr, charset) { charset = charset || 'utf-8'; let encodedBytes = []; for (let i = 0; i < encodedStr.length; i++) { let c = encodedStr.charAt(i); if (c === '%' && /^[a-f0-9]{2}/i.test(encodedStr.substr(i + 1, 2))) { // encoded sequence let byte = encodedStr.substr(i + 1, 2); i += 2; encodedBytes.push(parseInt(byte, 16)); } else if (c.charCodeAt(0) > 126) { c = textEncoder.encode(c); for (let j = 0; j < c.length; j++) { encodedBytes.push(c[j]); } } else { // "normal" char encodedBytes.push(c.charCodeAt(0)); } } const byteStr = new ArrayBuffer(encodedBytes.length); const dataView = new DataView(byteStr); for (let i = 0, len = encodedBytes.length; i < len; i++) { dataView.setUint8(i, encodedBytes[i]); } return getDecoder(charset).decode(byteStr); } function decodeParameterValueContinuations(header) { // handle parameter value continuations // https://tools.ietf.org/html/rfc2231#section-3 // preprocess values let paramKeys = new Map(); Object.keys(header.params).forEach(key => { let match = key.match(/\*((\d+)\*?)?$/); if (!match) { // nothing to do here, does not seem like a continuation param return; } let actualKey = key.substr(0, match.index).toLowerCase(); let nr = Number(match[2]) || 0; let paramVal; if (!paramKeys.has(actualKey)) { paramVal = { charset: false, values: [] }; paramKeys.set(actualKey, paramVal); } else { paramVal = paramKeys.get(actualKey); } let value = header.params[key]; if (nr === 0 && match[0].charAt(match[0].length - 1) === '*' && (match = value.match(/^([^']*)'[^']*'(.*)$/))) { paramVal.charset = match[1] || 'utf-8'; value = match[2]; } paramVal.values.push({ nr, value }); // remove the old reference delete header.params[key]; }); paramKeys.forEach((paramVal, key) => { header.params[key] = decodeURIComponentWithCharset( paramVal.values .sort((a, b) => a.nr - b.nr) .map(a => a.value) .join(''), paramVal.charset ); }); } class PassThroughDecoder { constructor() { this.chunks = []; } update(line) { this.chunks.push(line); this.chunks.push('\n'); } finalize() { // convert an array of arraybuffers into a blob and then back into a single arraybuffer return blobToArrayBuffer(new Blob(this.chunks, { type: 'application/octet-stream' })); } } class Base64Decoder { constructor(opts) { opts = opts || {}; this.decoder = opts.decoder || new TextDecoder(); this.maxChunkSize = 100 * 1024; this.chunks = []; this.remainder = ''; } update(buffer) { let str = this.decoder.decode(buffer); if (/[^a-zA-Z0-9+\/]/.test(str)) { str = str.replace(/[^a-zA-Z0-9+\/]+/g, ''); } this.remainder += str; if (this.remainder.length >= this.maxChunkSize) { let allowedBytes = Math.floor(this.remainder.length / 4) * 4; let base64Str; if (allowedBytes === this.remainder.length) { base64Str = this.remainder; this.remainder = ''; } else { base64Str = this.remainder.substr(0, allowedBytes); this.remainder = this.remainder.substr(allowedBytes); } if (base64Str.length) { this.chunks.push(decodeBase64(base64Str)); } } } finalize() { if (this.remainder && !/^=+$/.test(this.remainder)) { this.chunks.push(decodeBase64(this.remainder)); } return blobToArrayBuffer(new Blob(this.chunks, { type: 'application/octet-stream' })); } } // Regex patterns compiled once for performance const VALID_QP_REGEX = /^=[a-f0-9]{2}$/i; const QP_SPLIT_REGEX = /(?==[a-f0-9]{2})/i; const SOFT_LINE_BREAK_REGEX = /=\r?\n/g; const PARTIAL_QP_ENDING_REGEX = /=[a-fA-F0-9]?$/; class QPDecoder { constructor(opts) { opts = opts || {}; this.decoder = opts.decoder || new TextDecoder(); this.maxChunkSize = 100 * 1024; this.remainder = ''; this.chunks = []; } decodeQPBytes(encodedBytes) { let buf = new ArrayBuffer(encodedBytes.length); let dataView = new DataView(buf); for (let i = 0, len = encodedBytes.length; i < len; i++) { dataView.setUint8(i, parseInt(encodedBytes[i], 16)); } return buf; } decodeChunks(str) { // unwrap newlines str = str.replace(SOFT_LINE_BREAK_REGEX, ''); let list = str.split(QP_SPLIT_REGEX); let encodedBytes = []; for (let part of list) { if (part.charAt(0) !== '=') { if (encodedBytes.length) { this.chunks.push(this.decodeQPBytes(encodedBytes)); encodedBytes = []; } this.chunks.push(part); continue; } if (part.length === 3) { // Validate that this is actually a valid QP sequence if (VALID_QP_REGEX.test(part)) { encodedBytes.push(part.substr(1)); } else { // Not a valid QP sequence, treat as literal text if (encodedBytes.length) { this.chunks.push(this.decodeQPBytes(encodedBytes)); encodedBytes = []; } this.chunks.push(part); } continue; } if (part.length > 3) { // First 3 chars should be a valid QP sequence const firstThree = part.substr(0, 3); if (VALID_QP_REGEX.test(firstThree)) { encodedBytes.push(part.substr(1, 2)); this.chunks.push(this.decodeQPBytes(encodedBytes)); encodedBytes = []; part = part.substr(3); this.chunks.push(part); } else { // Not a valid QP sequence, treat entire part as literal if (encodedBytes.length) { this.chunks.push(this.decodeQPBytes(encodedBytes)); encodedBytes = []; } this.chunks.push(part); } } } if (encodedBytes.length) { this.chunks.push(this.decodeQPBytes(encodedBytes)); encodedBytes = []; } } update(buffer) { // expect full lines, so add line terminator as well let str = this.decoder.decode(buffer) + '\n'; str = this.remainder + str; if (str.length < this.maxChunkSize) { this.remainder = str; return; } this.remainder = ''; let partialEnding = str.match(PARTIAL_QP_ENDING_REGEX); if (partialEnding) { if (partialEnding.index === 0) { this.remainder = str; return; } this.remainder = str.substr(partialEnding.index); str = str.substr(0, partialEnding.index); } this.decodeChunks(str); } finalize() { if (this.remainder.length) { this.decodeChunks(this.remainder); this.remainder = ''; } // convert an array of arraybuffers into a blob and then back into a single arraybuffer return blobToArrayBuffer(new Blob(this.chunks, { type: 'application/octet-stream' })); } } class MimeNode { constructor(options) { this.options = options || {}; this.postalMime = this.options.postalMime; this.root = !!this.options.parentNode; this.childNodes = []; if (this.options.parentNode) { this.parentNode = this.options.parentNode; this.depth = this.parentNode.depth + 1; if (this.depth > this.options.maxNestingDepth) { throw new Error(`Maximum MIME nesting depth of ${this.options.maxNestingDepth} levels exceeded`); } this.options.parentNode.childNodes.push(this); } else { this.depth = 0; } this.state = 'header'; this.headerLines = []; this.headerSize = 0; // RFC 2046 Section 5.1.5: multipart/digest defaults to message/rfc822 const parentMultipartType = this.options.parentMultipartType || null; const defaultContentType = parentMultipartType === 'digest' ? 'message/rfc822' : 'text/plain'; this.contentType = { value: defaultContentType, default: true }; this.contentTransferEncoding = { value: '8bit' }; this.contentDisposition = { value: '' }; this.headers = []; this.contentDecoder = false; } setupContentDecoder(transferEncoding) { if (/base64/i.test(transferEncoding)) { this.contentDecoder = new Base64Decoder(); } else if (/quoted-printable/i.test(transferEncoding)) { this.contentDecoder = new QPDecoder({ decoder: getDecoder(this.contentType.parsed.params.charset) }); } else { this.contentDecoder = new PassThroughDecoder(); } } async finalize() { if (this.state === 'finished') { return; } if (this.state === 'header') { this.processHeaders(); } // remove self from boundary listing let boundaries = this.postalMime.boundaries; for (let i = boundaries.length - 1; i >= 0; i--) { let boundary = boundaries[i]; if (boundary.node === this) { boundaries.splice(i, 1); break; } } await this.finalizeChildNodes(); this.content = this.contentDecoder ? await this.contentDecoder.finalize() : null; this.state = 'finished'; } async finalizeChildNodes() { for (let childNode of this.childNodes) { await childNode.finalize(); } } // Strip RFC 822 comments (parenthesized text) from structured header values stripComments(str) { let result = ''; let depth = 0; let escaped = false; let inQuote = false; for (let i = 0; i < str.length; i++) { const chr = str.charAt(i); if (escaped) { if (depth === 0) { result += chr; } escaped = false; continue; } if (chr === '\\') { escaped = true; if (depth === 0) { result += chr; } continue; } if (chr === '"' && depth === 0) { inQuote = !inQuote; result += chr; continue; } if (!inQuote) { if (chr === '(') { depth++; continue; } if (chr === ')' && depth > 0) { depth--; continue; } } if (depth === 0) { result += chr; } } return result; } parseStructuredHeader(str) { // Strip RFC 822 comments before parsing str = this.stripComments(str); let response = { value: false, params: {} }; let key = false; let value = ''; let stage = 'value'; let quote = false; let escaped = false; let chr; for (let i = 0, len = str.length; i < len; i++) { chr = str.charAt(i); switch (stage) { case 'key': if (chr === '=') { key = value.trim().toLowerCase(); stage = 'value'; value = ''; break; } value += chr; break; case 'value': if (escaped) { value += chr; } else if (chr === '\\') { escaped = true; continue; } else if (quote && chr === quote) { quote = false; } else if (!quote && chr === '"') { quote = chr; } else if (!quote && chr === ';') { if (key === false) { response.value = value.trim(); } else { response.params[key] = value.trim(); } stage = 'key'; value = ''; } else { value += chr; } escaped = false; break; } } // finalize remainder value = value.trim(); if (stage === 'value') { if (key === false) { // default value response.value = value; } else { // subkey value response.params[key] = value; } } else if (value) { // treat as key without value, see emptykey: // Header-Key: somevalue; key=value; emptykey response.params[value.toLowerCase()] = ''; } if (response.value) { response.value = response.value.toLowerCase(); } // convert Parameter Value Continuations into single strings decodeParameterValueContinuations(response); return response; } decodeFlowedText(str, delSp) { return ( str .split(/\r?\n/) // remove soft linebreaks // soft linebreaks are added after space symbols .reduce((previousValue, currentValue) => { if (/ $/.test(previousValue) && !/(^|\n)-- $/.test(previousValue)) { if (delSp) { // delsp adds space to text to be able to fold it // these spaces can be removed once the text is unfolded return previousValue.slice(0, -1) + currentValue; } else { return previousValue + currentValue; } } else { return previousValue + '\n' + currentValue; } }) // remove whitespace stuffing // http://tools.ietf.org/html/rfc3676#section-4.4 .replace(/^ /gm, '') ); } getTextContent() { if (!this.content) { return ''; } let str = getDecoder(this.contentType.parsed.params.charset).decode(this.content); if (/^flowed$/i.test(this.contentType.parsed.params.format)) { str = this.decodeFlowedText(str, /^yes$/i.test(this.contentType.parsed.params.delsp)); } return str; } processHeaders() { // First pass: merge folded headers (backward iteration) for (let i = this.headerLines.length - 1; i >= 0; i--) { let line = this.headerLines[i]; if (i && /^\s/.test(line)) { this.headerLines[i - 1] += '\n' + line; this.headerLines.splice(i, 1); } } // Initialize rawHeaderLines to store unmodified lines this.rawHeaderLines = []; // Second pass: process headers (MUST be backward to maintain this.headers order) // The existing code iterates backward and postal-mime.js calls .reverse() // We must preserve this behavior to avoid breaking changes for (let i = this.headerLines.length - 1; i >= 0; i--) { let rawLine = this.headerLines[i]; // Extract key from raw line for rawHeaderLines let sep = rawLine.indexOf(':'); let rawKey = sep < 0 ? rawLine.trim() : rawLine.substr(0, sep).trim(); // Store raw line with lowercase key this.rawHeaderLines.push({ key: rawKey.toLowerCase(), line: rawLine }); // Normalize for this.headers (existing behavior - order preserved) let normalizedLine = rawLine.replace(/\s+/g, ' '); sep = normalizedLine.indexOf(':'); let key = sep < 0 ? normalizedLine.trim() : normalizedLine.substr(0, sep).trim(); let value = sep < 0 ? '' : normalizedLine.substr(sep + 1).trim(); this.headers.push({ key: key.toLowerCase(), originalKey: key, value }); switch (key.toLowerCase()) { case 'content-type': if (this.contentType.default) { this.contentType = { value, parsed: {} }; } break; case 'content-transfer-encoding': this.contentTransferEncoding = { value, parsed: {} }; break; case 'content-disposition': this.contentDisposition = { value, parsed: {} }; break; case 'content-id': this.contentId = value; break; case 'content-description': this.contentDescription = value; break; } } this.contentType.parsed = this.parseStructuredHeader(this.contentType.value); this.contentType.multipart = /^multipart\//i.test(this.contentType.parsed.value) ? this.contentType.parsed.value.substr(this.contentType.parsed.value.indexOf('/') + 1) : false; if (this.contentType.multipart && this.contentType.parsed.params.boundary) { // add self to boundary terminator listing this.postalMime.boundaries.push({ value: textEncoder.encode(this.contentType.parsed.params.boundary), node: this }); } this.contentDisposition.parsed = this.parseStructuredHeader(this.contentDisposition.value); this.contentTransferEncoding.encoding = this.contentTransferEncoding.value .toLowerCase() .split(/[^\w-]/) .shift(); this.setupContentDecoder(this.contentTransferEncoding.encoding); } feed(line) { switch (this.state) { case 'header': if (!line.length) { this.state = 'body'; return this.processHeaders(); } this.headerSize += line.length; if (this.headerSize > this.options.maxHeadersSize) { let error = new Error(`Maximum header size of ${this.options.maxHeadersSize} bytes exceeded`); throw error; } this.headerLines.push(getDecoder().decode(line)); break; case 'body': { // add line to body this.contentDecoder.update(line); } } } } // Entity map from https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references const htmlEntities = { '&AElig': '\u00C6', '&AElig;': '\u00C6', '&AMP': '\u0026', '&AMP;': '\u0026', '&Aacute': '\u00C1', '&Aacute;': '\u00C1', '&Abreve;': '\u0102', '&Acirc': '\u00C2', '&Acirc;': '\u00C2', '&Acy;': '\u0410', '&Afr;': '\uD835\uDD04', '&Agrave': '\u00C0', '&Agrave;': '\u00C0', '&Alpha;': '\u0391', '&Amacr;': '\u0100', '&And;': '\u2A53', '&Aogon;': '\u0104', '&Aopf;': '\uD835\uDD38', '&ApplyFunction;': '\u2061', '&Aring': '\u00C5', '&Aring;': '\u00C5', '&Ascr;': '\uD835\uDC9C', '&Assign;': '\u2254', '&Atilde': '\u00C3', '&Atilde;': '\u00C3', '&Auml': '\u00C4', '&Auml;': '\u00C4', '&Backslash;': '\u2216', '&Barv;': '\u2AE7', '&Barwed;': '\u2306', '&Bcy;': '\u0411', '&Because;': '\u2235', '&Bernoullis;': '\u212C', '&Beta;': '\u0392', '&Bfr;': '\uD835\uDD05', '&Bopf;': '\uD835\uDD39', '&Breve;': '\u02D8', '&Bscr;': '\u212C', '&Bumpeq;': '\u224E', '&CHcy;': '\u0427', '&COPY': '\u00A9', '&COPY;': '\u00A9', '&Cacute;': '\u0106', '&Cap;': '\u22D2', '&CapitalDifferentialD;': '\u2145', '&Cayleys;': '\u212D', '&Ccaron;': '\u010C', '&Ccedil': '\u00C7', '&Ccedil;': '\u00C7', '&Ccirc;': '\u0108', '&Cconint;': '\u2230', '&Cdot;': '\u010A', '&Cedilla;': '\u00B8', '&CenterDot;': '\u00B7', '&Cfr;': '\u212D', '&Chi;': '\u03A7', '&CircleDot;': '\u2299', '&CircleMinus;': '\u2296', '&CirclePlus;': '\u2295', '&CircleTimes;': '\u2297', '&ClockwiseContourIntegral;': '\u2232', '&CloseCurlyDoubleQuote;': '\u201D', '&CloseCurlyQuote;': '\u2019', '&Colon;': '\u2237', '&Colone;': '\u2A74', '&Congruent;': '\u2261', '&Conint;': '\u222F', '&ContourIntegral;': '\u222E', '&Copf;': '\u2102', '&Coproduct;': '\u2210', '&CounterClockwiseContourIntegral;': '\u2233', '&Cross;': '\u2A2F', '&Cscr;': '\uD835\uDC9E', '&Cup;': '\u22D3', '&CupCap;': '\u224D', '&DD;': '\u2145', '&DDotrahd;': '\u2911', '&DJcy;': '\u0402', '&DScy;': '\u0405', '&DZcy;': '\u040F', '&Dagger;': '\u2021', '&Darr;': '\u21A1', '&Dashv;': '\u2AE4', '&Dcaron;': '\u010E', '&Dcy;': '\u0414', '&Del;': '\u2207', '&Delta;': '\u0394', '&Dfr;': '\uD835\uDD07', '&DiacriticalAcute;': '\u00B4', '&DiacriticalDot;': '\u02D9', '&DiacriticalDoubleAcute;': '\u02DD', '&DiacriticalGrave;': '\u0060', '&DiacriticalTilde;': '\u02DC', '&Diamond;': '\u22C4', '&DifferentialD;': '\u2146', '&Dopf;': '\uD835\uDD3B', '&Dot;': '\u00A8', '&DotDot;': '\u20DC', '&DotEqual;': '\u2250', '&DoubleContourIntegral;': '\u222F', '&DoubleDot;': '\u00A8', '&DoubleDownArrow;': '\u21D3', '&DoubleLeftArrow;': '\u21D0', '&DoubleLeftRightArrow;': '\u21D4', '&DoubleLeftTee;': '\u2AE4', '&DoubleLongLeftArrow;': '\u27F8', '&DoubleLongLeftRightArrow;': '\u27FA', '&DoubleLongRightArrow;': '\u27F9', '&DoubleRightArrow;': '\u21D2', '&DoubleRightTee;': '\u22A8', '&DoubleUpArrow;': '\u21D1', '&DoubleUpDownArrow;': '\u21D5', '&DoubleVerticalBar;': '\u2225', '&DownArrow;': '\u2193', '&DownArrowBar;': '\u2913', '&DownArrowUpArrow;': '\u21F5', '&DownBreve;': '\u0311', '&DownLeftRightVector;': '\u2950', '&DownLeftTeeVector;': '\u295E', '&DownLeftVector;': '\u21BD', '&DownLeftVectorBar;': '\u2956', '&DownRightTeeVector;': '\u295F', '&DownRightVector;': '\u21C1', '&DownRightVectorBar;': '\u2957', '&DownTee;': '\u22A4', '&DownTeeArrow;': '\u21A7', '&Downarrow;': '\u21D3', '&Dscr;': '\uD835\uDC9F', '&Dstrok;': '\u0110', '&ENG;': '\u014A', '&ETH': '\u00D0', '&ETH;': '\u00D0', '&Eacute': '\u00C9', '&Eacute;': '\u00C9', '&Ecaron;': '\u011A', '&Ecirc': '\u00CA', '&Ecirc;': '\u00CA', '&Ecy;': '\u042D', '&Edot;': '\u0116', '&Efr;': '\uD835\uDD08', '&Egrave': '\u00C8', '&Egrave;': '\u00C8', '&Element;': '\u2208', '&Emacr;': '\u0112', '&EmptySmallSquare;': '\u25FB', '&EmptyVerySmallSquare;': '\u25AB', '&Eogon;': '\u0118', '&Eopf;': '\uD835\uDD3C', '&Epsilon;': '\u0395', '&Equal;': '\u2A75', '&EqualTilde;': '\u2242', '&Equilibrium;': '\u21CC', '&Escr;': '\u2130', '&Esim;': '\u2A73', '&Eta;': '\u0397', '&Euml': '\u00CB', '&Euml;': '\u00CB', '&Exists;': '\u2203', '&ExponentialE;': '\u2147', '&Fcy;': '\u0424', '&Ffr;': '\uD835\uDD09', '&FilledSmallSquare;': '\u25FC', '&FilledVerySmallSquare;': '\u25AA', '&Fopf;': '\uD835\uDD3D', '&ForAll;': '\u2200', '&Fouriertrf;': '\u2131', '&Fscr;': '\u2131', '&GJcy;': '\u0403', '&GT': '\u003E', '&GT;': '\u003E', '&Gamma;': '\u0393', '&Gammad;': '\u03DC', '&Gbreve;': '\u011E', '&Gcedil;': '\u0122', '&Gcirc;': '\u011C', '&Gcy;': '\u0413', '&Gdot;': '\u0120', '&Gfr;': '\uD835\uDD0A', '&Gg;': '\u22D9', '&Gopf;': '\uD835\uDD3E', '&GreaterEqual;': '\u2265', '&GreaterEqualLess;': '\u22DB', '&GreaterFullEqual;': '\u2267', '&GreaterGreater;': '\u2AA2', '&GreaterLess;': '\u2277', '&GreaterSlantEqual;': '\u2A7E', '&GreaterTilde;': '\u2273', '&Gscr;': '\uD835\uDCA2', '&Gt;': '\u226B', '&HARDcy;': '\u042A', '&Hacek;': '\u02C7', '&Hat;': '\u005E', '&Hcirc;': '\u0124', '&Hfr;': '\u210C', '&HilbertSpace;': '\u210B', '&Hopf;': '\u210D', '&HorizontalLine;': '\u2500', '&Hscr;': '\u210B', '&Hstrok;': '\u0126', '&HumpDownHump;': '\u224E', '&HumpEqual;': '\u224F', '&IEcy;': '\u0415', '&IJlig;': '\u0132', '&IOcy;': '\u0401', '&Iacute': '\u00CD', '&Iacute;': '\u00CD', '&Icirc': '\u00CE', '&Icirc;': '\u00CE', '&Icy;': '\u0418', '&Idot;': '\u0130', '&Ifr;': '\u2111', '&Igrave': '\u00CC', '&Igrave;': '\u00CC', '&Im;': '\u2111', '&Imacr;': '\u012A', '&ImaginaryI;': '\u2148', '&Implies;': '\u21D2', '&Int;': '\u222C', '&Integral;': '\u222B', '&Intersection;': '\u22C2', '&InvisibleComma;': '\u2063', '&InvisibleTimes;': '\u2062', '&Iogon;': '\u012E', '&Iopf;': '\uD835\uDD40', '&Iota;': '\u0399', '&Iscr;': '\u2110', '&Itilde;': '\u0128', '&Iukcy;': '\u0406', '&Iuml': '\u00CF', '&Iuml;': '\u00CF', '&Jcirc;': '\u0134', '&Jcy;': '\u0419', '&Jfr;': '\uD835\uDD0D', '&Jopf;': '\uD835\uDD41', '&Jscr;': '\uD835\uDCA5', '&Jsercy;': '\u0408', '&Jukcy;': '\u0404', '&KHcy;': '\u0425', '&KJcy;': '\u040C', '&Kappa;': '\u039A', '&Kcedil;': '\u0136', '&Kcy;': '\u041A', '&Kfr;': '\uD835\uDD0E', '&Kopf;': '\uD835\uDD42', '&Kscr;': '\uD835\uDCA6', '&LJcy;': '\u0409', '&LT': '\u003C', '&LT;': '\u003C', '&Lacute;': '\u0139', '&Lambda;': '\u039B', '&Lang;': '\u27EA', '&Laplacetrf;': '\u2112', '&Larr;': '\u219E', '&Lcaron;': '\u013D', '&Lcedil;': '\u013B', '&Lcy;': '\u041B', '&LeftAngleBracket;': '\u27E8', '&LeftArrow;': '\u2190', '&LeftArrowBar;': '\u21E4', '&LeftArrowRightArrow;': '\u21C6', '&LeftCeiling;': '\u2308', '&LeftDoubleBracket;': '\u27E6', '&LeftDownTeeVector;': '\u2961', '&LeftDownVector;': '\u21C3', '&LeftDownVectorBar;': '\u2959', '&LeftFloor;': '\u230A', '&LeftRightArrow;': '\u2194', '&LeftRightVector;': '\u294E', '&LeftTee;': '\u22A3', '&LeftTeeArrow;': '\u21A4', '&LeftTeeVector;': '\u295A', '&LeftTriangle;': '\u22B2', '&LeftTriangleBar;': '\u29CF', '&LeftTriangleEqual;': '\u22B4', '&LeftUpDownVector;': '\u2951', '&LeftUpTeeVector;': '\u2960', '&LeftUpVector;': '\u21BF', '&LeftUpVectorBar;': '\u2958', '&LeftVector;': '\u21BC', '&LeftVectorBar;': '\u2952', '&Leftarrow;': '\u21D0', '&Leftrightarrow;': '\u21D4', '&LessEqualGreater;': '\u22DA', '&LessFullEqual;': '\u2266', '&LessGreater;': '\u2276', '&LessLess;': '\u2AA1', '&LessSlantEqual;': '\u2A7D', '&LessTilde;': '\u2272', '&Lfr;': '\uD835\uDD0F', '&Ll;': '\u22D8', '&Lleftarrow;': '\u21DA', '&Lmidot;': '\u013F', '&LongLeftArrow;': '\u27F5', '&LongLeftRightArrow;': '\u27F7', '&LongRightArrow;': '\u27F6', '&Longleftarrow;': '\u27F8', '&Longleftrightarrow;': '\u27FA', '&Longrightarrow;': '\u27F9', '&Lopf;': '\uD835\uDD43', '&LowerLeftArrow;': '\u2199', '&LowerRightArrow;': '\u2198', '&Lscr;': '\u2112', '&Lsh;': '\u21B0', '&Lstrok;': '\u0141', '&Lt;': '\u226A', '&Map;': '\u2905', '&Mcy;': '\u041C', '&MediumSpace;': '\u205F', '&Mellintrf;': '\u2133', '&Mfr;': '\uD835\uDD10', '&MinusPlus;': '\u2213', '&Mopf;': '\uD835\uDD44', '&Mscr;': '\u2133', '&Mu;': '\u039C', '&NJcy;': '\u040A', '&Nacute;': '\u0143', '&Ncaron;': '\u0147', '&Ncedil;': '\u0145', '&Ncy;': '\u041D', '&NegativeMediumSpace;': '\u200B', '&NegativeThickSpace;': '\u200B', '&NegativeThinSpace;': '\u200B', '&NegativeVeryThinSpace;': '\u200B', '&NestedGreaterGreater;': '\u226B', '&NestedLessLess;': '\u226A', '&NewLine;': '\u000A', '&Nfr;': '\uD835\uDD11', '&NoBreak;': '\u2060', '&NonBreakingSpace;': '\u00A0', '&Nopf;': '\u2115', '&Not;': '\u2AEC', '&NotCongruent;': '\u2262', '&NotCupCap;': '\u226D', '&NotDoubleVerticalBar;': '\u2226', '&NotElement;': '\u2209', '&NotEqual;': '\u2260', '&NotEqualTilde;': '\u2242\u0338', '&NotExists;': '\u2204', '&NotGreater;': '\u226F', '&NotGreaterEqual;': '\u2271', '&NotGreaterFullEqual;': '\u2267\u0338', '&NotGreaterGreater;': '\u226B\u0338', '&NotGreaterLess;': '\u2279', '&NotGreaterSlantEqual;': '\u2A7E\u0338', '&NotGreaterTilde;': '\u2275', '&NotHumpDownHump;': '\u224E\u0338', '&NotHumpEqual;': '\u224F\u0338', '&NotLeftTriangle;': '\u22EA', '&NotLeftTriangleBar;': '\u29CF\u0338', '&NotLeftTriangleEqual;': '\u22EC', '&NotLess;': '\u226E', '&NotLessEqual;': '\u2270', '&NotLessGreater;': '\u2278', '&NotLessLess;': '\u226A\u0338', '&NotLessSlantEqual;': '\u2A7D\u0338', '&NotLessTilde;': '\u2274', '&NotNestedGreaterGreater;': '\u2AA2\u0338', '&NotNestedLessLess;': '\u2AA1\u0338', '&NotPrecedes;': '\u2280', '&NotPrecedesEqual;': '\u2AAF\u0338', '&NotPrecedesSlantEqual;': '\u22E0', '&NotReverseElement;': '\u220C', '&NotRightTriangle;': '\u22EB', '&NotRightTriangleBar;': '\u29D0\u0338', '&NotRightTriangleEqual;': '\u22ED', '&NotSquareSubset;': '\u228F\u0338', '&NotSquareSubsetEqual;': '\u22E2', '&NotSquareSuperset;': '\u2290\u0338', '&NotSquareSupersetEqual;': '\u22E3', '&NotSubset;': '\u2282\u20D2', '&NotSubsetEqual;': '\u2288', '&NotSucceeds;': '\u2281', '&NotSucceedsEqual;': '\u2AB0\u0338', '&NotSucceedsSlantEqual;': '\u22E1', '&NotSucceedsTilde;': '\u227F\u0338', '&NotSuperset;': '\u2283\u20D2', '&NotSupersetEqual;': '\u2289', '&NotTilde;': '\u2241', '&NotTildeEqual;': '\u2244', '&NotTildeFullEqual;': '\u2247', '&NotTildeTilde;': '\u2249', '&NotVerticalBar;': '\u2224', '&Nscr;': '\uD835\uDCA9', '&Ntilde': '\u00D1', '&Ntilde;': '\u00D1', '&Nu;': '\u039D', '&OElig;': '\u0152', '&Oacute': '\u00D3', '&Oacute;': '\u00D3', '&Ocirc': '\u00D4', '&Ocirc;': '\u00D4', '&Ocy;': '\u041E', '&Odblac;': '\u0150', '&Ofr;': '\uD835\uDD12', '&Ograve': '\u00D2', '&Ograve;': '\u00D2', '&Omacr;': '\u014C', '&Omega;': '\u03A9', '&Omicron;': '\u039F', '&Oopf;': '\uD835\uDD46', '&OpenCurlyDoubleQuote;': '\u201C', '&OpenCurlyQuote;': '\u2018', '&Or;': '\u2A54', '&Oscr;': '\uD835\uDCAA', '&Oslash': '\u00D8', '&Oslash;': '\u00D8', '&Otilde': '\u00D5', '&Otilde;': '\u00D5', '&Otimes;': '\u2A37', '&Ouml': '\u00D6', '&Ouml;': '\u00D6', '&OverBar;': '\u203E', '&OverBrace;': '\u23DE', '&OverBracket;': '\u23B4', '&OverParenthesis;': '\u23DC', '&PartialD;': '\u2202', '&Pcy;': '\u041F', '&Pfr;': '\uD835\uDD13', '&Phi;': '\u03A6', '&Pi;': '\u03A0', '&PlusMinus;': '\u00B1', '&Poincareplane;': '\u210C', '&Popf;': '\u2119', '&Pr;': '\u2ABB', '&Precedes;': '\u227A', '&PrecedesEqual;': '\u2AAF', '&PrecedesSlantEqual;': '\u227C', '&PrecedesTilde;': '\u227E', '&Prime;': '\u2033', '&Product;': '\u220F', '&Proportion;': '\u2237', '&Proportional;': '\u221D', '&Pscr;': '\uD835\uDCAB', '&Psi;': '\u03A8', '&QUOT': '\u0022', '&QUOT;': '\u0022', '&Qfr;': '\uD835\uDD14', '&Qopf;': '\u211A', '&Qscr;': '\uD835\uDCAC', '&RBarr;': '\u2910', '&REG': '\u00AE', '&REG;': '\u00AE', '&Racute;': '\u0154', '&Rang;': '\u27EB', '&Rarr;': '\u21A0', '&Rarrtl;': '\u2916', '&Rcaron;': '\u0158', '&Rcedil;': '\u0156', '&Rcy;': '\u0420', '&Re;': '\u211C', '&ReverseElement;': '\u220B', '&ReverseEquilibrium;': '\u21CB', '&ReverseUpEquilibrium;': '\u296F', '&Rfr;': '\u211C', '&Rho;': '\u03A1', '&RightAngleBracket;': '\u27E9', '&RightArrow;': '\u2192', '&RightArrowBar;': '\u21E5', '&RightArrowLeftArrow;': '\u21C4', '&RightCeiling;': '\u2309', '&RightDoubleBracket;': '\u27E7', '&RightDownTeeVector;': '\u295D', '&RightDownVector;': '\u21C2', '&RightDownVectorBar;': '\u2955', '&RightFloor;': '\u230B', '&RightTee;': '\u22A2', '&RightTeeArrow;': '\u21A6', '&RightTeeVector;': '\u295B', '&RightTriangle;': '\u22B3', '&RightTriangleBar;': '\u29D0', '&RightTriangleEqual;': '\u22B5', '&RightUpDownVector;': '\u294F', '&RightUpTeeVector;': '\u295C', '&RightUpVector;': '\u21BE', '&RightUpVectorBar;': '\u2954', '&RightVector;': '\u21C0', '&RightVectorBar;': '\u2953', '&Rightarrow;': '\u21D2', '&Ropf;': '\u211D', '&RoundImplies;': '\u2970', '&Rrightarrow;': '\u21DB', '&Rscr;': '\u211B', '&Rsh;': '\u21B1', '&RuleDelayed;': '\u29F4', '&SHCHcy;': '\u0429', '&SHcy;': '\u0428', '&SOFTcy;': '\u042C', '&Sacute;': '\u015A', '&Sc;': '\u2ABC', '&Scaron;': '\u0160', '&Scedil;': '\u015E', '&Scirc;': '\u015C', '&Scy;': '\u0421', '&Sfr;': '\uD835\uDD16', '&ShortDownArrow;': '\u2193', '&ShortLeftArrow;': '\u2190', '&ShortRightArrow;': '\u2192', '&ShortUpArrow;': '\u2191', '&Sigma;': '\u03A3', '&SmallCircle;': '\u2218', '&Sopf;': '\uD835\uDD4A', '&Sqrt;': '\u221A', '&Square;': '\u25A1', '&SquareIntersection;': '\u2293', '&SquareSubset;': '\u228F', '&SquareSubsetEqual;': '\u2291', '&SquareSuperset;': '\u2290', '&SquareSupersetEqual;': '\u2292', '&SquareUnion;': '\u2294', '&Sscr;': '\uD835\uDCAE', '&Star;': '\u22C6', '&Sub;': '\u22D0', '&Subset;': '\u22D0', '&SubsetEqual;': '\u2286', '&Succeeds;': '\u227B', '&SucceedsEqual;': '\u2AB0', '&SucceedsSlantEqual;': '\u227D', '&SucceedsTilde;': '\u227F', '&SuchThat;': '\u220B', '&Sum;': '\u2211', '&Sup;': '\u22D1', '&Superset;': '\u2283', '&SupersetEqual;': '\u2287', '&Supset;': '\u22D1', '&THORN': '\u00DE', '&THORN;': '\u00DE', '&TRADE;': '\u2122', '&TSHcy;': '\u040B', '&TScy;': '\u0426', '&Tab;': '\u0009', '&Tau;': '\u03A4', '&Tcaron;': '\u0164', '&Tcedil;': '\u0162', '&Tcy;': '\u0422', '&Tfr;': '\uD835\uDD17', '&Therefore;': '\u2234', '&Theta;': '\u0398', '&ThickSpace;': '\u205F\u200A', '&ThinSpace;': '\u2009', '&Tilde;': '\u223C', '&TildeEqual;': '\u2243', '&TildeFullEqual;': '\u2245', '&TildeTilde;': '\u2248', '&Topf;': '\uD835\uDD4B', '&TripleDot;': '\u20DB', '&Tscr;': '\uD835\uDCAF', '&Tstrok;': '\u0166', '&Uacute': '\u00DA', '&Uacute;': '\u00DA', '&Uarr;': '\u219F', '&Uarrocir;': '\u2949', '&Ubrcy;': '\u040E', '&Ubreve;': '\u016C', '&Ucirc': '\u00DB', '&Ucirc;': '\u00DB', '&Ucy;': '\u0423', '&Udblac;': '\u0170', '&Ufr;': '\uD835\uDD18', '&Ugrave': '\u00D9', '&Ugrave;': '\u00D9', '&Umacr;': '\u016A', '&UnderBar;': '\u005F', '&UnderBrace;': '\u23DF', '&UnderBracket;': '\u23B5', '&UnderParenthesis;': '\u23DD', '&Union;': '\u22C3', '&UnionPlus;': '\u228E', '&Uogon;': '\u0172', '&Uopf;': '\uD835\uDD4C', '&UpArrow;': '\u2191', '&UpArrowBar;': '\u2912', '&UpArrowDownArrow;': '\u21C5', '&UpDownArrow;': '\u2195', '&UpEquilibrium;': '\u296E', '&UpTee;': '\u22A5', '&UpTeeArrow;': '\u21A5', '&Uparrow;': '\u21D1', '&Updownarrow;': '\u21D5', '&UpperLeftArrow;': '\u2196', '&UpperRightArrow;': '\u2197', '&Upsi;': '\u03D2', '&Upsilon;': '\u03A5', '&Uring;': '\u016E', '&Uscr;': '\uD835\uDCB0', '&Utilde;': '\u0168', '&Uuml': '\u00DC', '&Uuml;': '\u00DC', '&VDash;': '\u22AB', '&Vbar;': '\u2AEB', '&Vcy;': '\u0412', '&Vdash;': '\u22A9', '&Vdashl;': '\u2AE6', '&Vee;': '\u22C1', '&Verbar;': '\u2016', '&Vert;': '\u2016', '&VerticalBar;': '\u2223', '&VerticalLine;': '\u007C', '&VerticalSeparator;': '\u2758', '&VerticalTilde;': '\u2240', '&VeryThinSpace;': '\u200A', '&Vfr;': '\uD835\uDD19', '&Vopf;': '\uD835\uDD4D', '&Vscr;': '\uD835\uDCB1', '&Vvdash;': '\u22AA', '&Wcirc;': '\u0174', '&Wedge;': '\u22C0', '&Wfr;': '\uD835\uDD1A', '&Wopf;': '\uD835\uDD4E', '&Wscr;': '\uD835\uDCB2', '&Xfr;': '\uD835\uDD1B', '&Xi;': '\u039E', '&Xopf;': '\uD835\uDD4F', '&Xscr;': '\uD835\uDCB3', '&YAcy;': '\u042F', '&YIcy;': '\u0407', '&YUcy;': '\u042E', '&Yacute': '\u00DD', '&Yacute;': '\u00DD', '&Ycirc;': '\u0176', '&Ycy;': '\u042B', '&Yfr;': '\uD835\uDD1C', '&Yopf;': '\uD835\uDD50', '&Yscr;': '\uD835\uDCB4', '&Yuml;': '\u0178', '&ZHcy;': '\u0416', '&Zacute;': '\u0179', '&Zcaron;': '\u017D', '&Zcy;': '\u0417', '&Zdot;': '\u017B', '&ZeroWidthSpace;': '\u200B', '&Zeta;': '\u0396', '&Zfr;': '\u2128', '&Zopf;': '\u2124', '&Zscr;': '\uD835\uDCB5', '&aacute': '\u00E1', '&aacute;': '\u00E1', '&abreve;': '\u0103', '&ac;': '\u223E', '&acE;': '\u223E\u0333', '&acd;': '\u223F', '&acirc': '\u00E2', '&acirc;': '\u00E2', '&acute': '\u00B4', '&acute;': '\u00B4', '&acy;': '\u0430', '&aelig': '\u00E6', '&aelig;': '\u00E6', '&af;': '\u2061', '&afr;': '\uD835\uDD1E', '&agrave': '\u00E0', '&agrave;': '\u00E0', '&alefsym;': '\u2135', '&aleph;': '\u2135', '&alpha;': '\u03B1', '&amacr;': '\u0101', '&amalg;': '\u2A3F', '&amp': '\u0026', '&amp;': '\u0026', '&and;': '\u2227', '&andand;': '\u2A55', '&andd;': '\u2A5C', '&andslope;': '\u2A58', '&andv;': '\u2A5A', '&ang;': '\u2220', '&ange;': '\u29A4', '&angle;': '\u2220', '&angmsd;': '\u2221', '&angmsdaa;': '\u29A8', '&angmsdab;': '\u29A9', '&angmsdac;': '\u29AA', '&angmsdad;': '\u29AB', '&angmsdae;': '\u29AC', '&angmsdaf;': '\u29AD', '&angmsdag;': '\u29AE', '&angmsdah;': '\u29AF', '&angrt;': '\u221F', '&angrtvb;': '\u22BE', '&angrtvbd;': '\u299D', '&angsph;': '\u2222', '&angst;': '\u00C5', '&angzarr;': '\u237C', '&aogon;': '\u0105', '&aopf;': '\uD835\uDD52', '&ap;': '\u2248', '&apE;': '\u2A70', '&apacir;': '\u2A6F', '&ape;': '\u224A', '&apid;': '\u224B', '&apos;': '\u0027', '&approx;': '\u2248', '&approxeq;': '\u224A',