/**@license setplus: a lightweight HTML editor
 * @author  Levente Hunyadi
 * @version 0.2.0
 * @remarks Copyright (C) 2010-2011 Levente Hunyadi
 * @remarks Licensed under GNU/GPLv3, see http://www.gnu.org/licenses/gpl-3.0.html
 * @see     http://hunyadi.info.hu/projects/setplus
 **/

/*
* setplus: a lightweight HTML editor
* Copyright 2010-2011 Levente Hunyadi
*
* setplus is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* setplus is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with setplus.  If not, see <http://www.gnu.org/licenses/>.
*/

(function ($) {
	function entityToChar(entityname) {
		return new Element('span', {
			'html': '&' + entityname + ';'
		}).get('text');
	}

	setplus.SymbolsMap = new Class({
		'initialize': function () {
			/**
			* Extends a character map with a code range.
			* @param map The character map which relates characters to character definitions.
			* @param base The character code of the first element in the character definition collection.
			* @param items Array of character definition strings to add to the character map.
			*/
			function _extend(map, base, items) {
				for (var k = 0; k < items.length; k++) {
					map[String.fromCharCode(base + k)] = [items[k].clean()];  // trim and remove unnecessary whitespace, wrap in array
				}
			}

			var _from = function (item) { return Function.from(' ' + item + ' ')(); };  // prevents constant inlining

			var SYM_AND = _from('and');
			var SYM_OR = _from('or');
			var SYM_NOT = _from('not');

			var SYM_DIGIT = _from('Digit');
			var SYM_LATIN = _from('Latin');
			var SYM_GREEK = _from('Greek');

			var SYM_CAP = 'Capital letter ';
			var SYM_SMALL = 'Small letter ';
			var SYM_LATIN_CAP = SYM_LATIN + SYM_CAP;
			var SYM_LATIN_SMALL = SYM_LATIN + SYM_SMALL;
			var SYM_GREEK_CAP = SYM_GREEK + SYM_CAP;
			var SYM_GREEK_SMALL = SYM_GREEK + SYM_SMALL;
			var SYM_WITH = _from('with');
			var SYM_WITH_ACUTE = SYM_WITH + 'acute';
			var SYM_WITH_BREVE = SYM_WITH + 'breve';
			var SYM_WITH_CARON = SYM_WITH + 'caron';
			var SYM_WITH_CEDILLA = SYM_WITH + 'cedilla';
			var SYM_WITH_CIRCUMFLEX = SYM_WITH + 'circumflex';
			var SYM_WITH_COMMABELOW = SYM_WITH + 'comma below';
			var SYM_WITH_CURL = SYM_WITH + 'curl';
			var SYM_WITH_DIAERESIS = SYM_WITH + 'diaeresis';
			var SYM_WITH_DOTABOVE = SYM_WITH + 'dot above';
			var SYM_WITH_DOUBLEACUTE = SYM_WITH + 'double acute';
			var SYM_WITH_DOUBLEGRAVE = SYM_WITH + 'double grave';
			var SYM_WITH_GRAVE = SYM_WITH + 'grave';
			var SYM_WITH_HOOK = SYM_WITH + 'hook';
			var SYM_WITH_HORN = SYM_WITH + 'horn';
			var SYM_WITH_INVERTEDBREVE = SYM_WITH + 'inverted breve';
			var SYM_WITH_MACRON = SYM_WITH + 'macron';
			var SYM_WITH_MIDDLEDOT = SYM_WITH + 'middle dot';
			var SYM_WITH_OGONEK = SYM_WITH + 'ogonek';
			var SYM_WITH_RINGABOVE = SYM_WITH + 'ring above';
			var SYM_WITH_STROKE = SYM_WITH + 'stroke';
			var SYM_WITH_TILDE = SYM_WITH + 'tilde';
			var SYM_WITH_TOPBAR = SYM_WITH + 'top bar';

			var SYM_WITH_DIAERESIS_AND_MACRON = SYM_WITH + 'diaeresis' + SYM_AND + 'macron';
			var SYM_WITH_DIAERESIS_AND_ACUTE = SYM_WITH + 'diaeresis' + SYM_AND + 'acute';
			var SYM_WITH_DIAERESIS_AND_CARON = SYM_WITH + 'diaeresis' + SYM_AND + 'caron';
			var SYM_WITH_DIAERESIS_AND_GRAVE = SYM_WITH + 'diaeresis' + SYM_AND + 'grave';
			var SYM_WITH_DOTABOVE_AND_MACRON = SYM_WITH + 'dot above' + SYM_AND + 'macron';
			var SYM_WITH_OGONEK_AND_MACRON = SYM_WITH + 'ogonek' + SYM_AND + 'macron';
			var SYM_WITH_RINGABOVE_AND_ACUTE = SYM_WITH + 'ring above' + SYM_AND + 'acute';
			var SYM_WITH_STROKE_AND_ACUTE = SYM_WITH + 'stroke' + SYM_AND + 'acute';
			var SYM_WITH_TILDE_AND_MACRON = SYM_WITH + 'tilde' + SYM_AND + 'macron';

			var SYM_LESS_THAN = _from('less-than');
			var SYM_GREATER_THAN = _from('greater-than');
			var SYM_EQUAL_TO = _from('equal to');
			var SYM_EQUIVALENT_TO = _from('equivalent to');
			var SYM_ELEMENT_OF = _from('element of');
			var SYM_CONTAINS = _from('contains');
			var SYM_SQUARE = _from('square');
			var SYM_OPERATOR = _from('operator');
			var SYM_VERTICAL_BAR_AT_END_OF_HORZ_STROKE = 'vertical bar at end of horizontal stroke';

			var symbols = {};

			// '\u0020':'Space',
			_extend(symbols, 33, [
				'Exclamation mark',
				'Quotation mark',
				'Number sign',
				'Dollar sign',
				'Percent sign',
				'Ampersand',
				'Apostrophe',
				'Left parenthesis',
				'Right parenthesis',
				'Asterisk',
				'Plus sign',
				'Comma',
				'Hyphen-minus',
				'Full stop',
				'Slash',
				SYM_DIGIT + 'Zero',
				SYM_DIGIT + 'One',
				SYM_DIGIT + 'Two',
				SYM_DIGIT + 'Three',
				SYM_DIGIT + 'Four',
				SYM_DIGIT + 'Five',
				SYM_DIGIT + 'Six',
				SYM_DIGIT + 'Seven',
				SYM_DIGIT + 'Eight',
				SYM_DIGIT + 'Nine',
				'Colon',
				'Semicolon',
				SYM_LESS_THAN + 'sign',
				'Equal sign',
				SYM_GREATER_THAN + 'sign',
				'Question mark',
				'At sign',
				SYM_LATIN_CAP + 'A',
				SYM_LATIN_CAP + 'B',
				SYM_LATIN_CAP + 'C',
				SYM_LATIN_CAP + 'D',
				SYM_LATIN_CAP + 'E',
				SYM_LATIN_CAP + 'F',
				SYM_LATIN_CAP + 'G',
				SYM_LATIN_CAP + 'H',
				SYM_LATIN_CAP + 'I',
				SYM_LATIN_CAP + 'J',
				SYM_LATIN_CAP + 'K',
				SYM_LATIN_CAP + 'L',
				SYM_LATIN_CAP + 'M',
				SYM_LATIN_CAP + 'N',
				SYM_LATIN_CAP + 'O',
				SYM_LATIN_CAP + 'P',
				SYM_LATIN_CAP + 'Q',
				SYM_LATIN_CAP + 'R',
				SYM_LATIN_CAP + 'S',
				SYM_LATIN_CAP + 'T',
				SYM_LATIN_CAP + 'U',
				SYM_LATIN_CAP + 'V',
				SYM_LATIN_CAP + 'W',
				SYM_LATIN_CAP + 'X',
				SYM_LATIN_CAP + 'Y',
				SYM_LATIN_CAP + 'Z',
				'Left Square Bracket',
				'Backslash',
				'Right Square Bracket',
				'Circumflex accent',
				'Low line',
				'Grave accent',
				SYM_LATIN_SMALL + 'A',
				SYM_LATIN_SMALL + 'B',
				SYM_LATIN_SMALL + 'C',
				SYM_LATIN_SMALL + 'D',
				SYM_LATIN_SMALL + 'E',
				SYM_LATIN_SMALL + 'F',
				SYM_LATIN_SMALL + 'G',
				SYM_LATIN_SMALL + 'H',
				SYM_LATIN_SMALL + 'I',
				SYM_LATIN_SMALL + 'J',
				SYM_LATIN_SMALL + 'K',
				SYM_LATIN_SMALL + 'L',
				SYM_LATIN_SMALL + 'M',
				SYM_LATIN_SMALL + 'N',
				SYM_LATIN_SMALL + 'O',
				SYM_LATIN_SMALL + 'P',
				SYM_LATIN_SMALL + 'Q',
				SYM_LATIN_SMALL + 'R',
				SYM_LATIN_SMALL + 'S',
				SYM_LATIN_SMALL + 'T',
				SYM_LATIN_SMALL + 'U',
				SYM_LATIN_SMALL + 'V',
				SYM_LATIN_SMALL + 'W',
				SYM_LATIN_SMALL + 'X',
				SYM_LATIN_SMALL + 'Y',
				SYM_LATIN_SMALL + 'Z',
				'Left Curly Bracket',
				'Vertical bar',
				'Right Curly Bracket',
				'Tilde'
			]);  // last item = 126

			_extend(symbols, 161, [
				'Inverted Exclamation Mark',
				'Cent sign',
				'Pound sign',
				'Currency sign',
				'Yen sign',
				'Broken bar',
				'Section sign',
				'Diaeresis',
				'Copyright sign',
				'Feminine Ordinal Indicator',
				'Left-pointing double angle quotation mark',
				'Not sign'
			]);  // last item = 172

			// '\u00AD':'Soft hyphen',
			_extend(symbols, 174, [
				'Registered sign',
				'Macron',
				'Degree symbol',
				'Plus-minus sign',
				'Superscript two',
				'Superscript three',
				'Acute accent',
				'Micro sign',
				'Pilcrow sign',
				'Middle dot',
				'Cedilla',
				'Superscript one',
				'Masculine ordinal indicator',
				'Right-pointing double-angle quotation mark',
				'Vulgar fraction one quarter',
				'Vulgar fraction one half',
				'Vulgar fraction three quarters',
				'Inverted Question Mark',
				SYM_LATIN_CAP + 'A' + SYM_WITH_GRAVE,
				SYM_LATIN_CAP + 'A' + SYM_WITH_ACUTE,
				SYM_LATIN_CAP + 'A' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_CAP + 'A' + SYM_WITH_TILDE,
				SYM_LATIN_CAP + 'A' + SYM_WITH_DIAERESIS,
				SYM_LATIN_CAP + 'A' + SYM_WITH_RINGABOVE,
				SYM_LATIN_CAP + 'AE',
				SYM_LATIN_CAP + 'C' + SYM_WITH_CEDILLA,
				SYM_LATIN_CAP + 'E' + SYM_WITH_GRAVE,
				SYM_LATIN_CAP + 'E' + SYM_WITH_ACUTE,
				SYM_LATIN_CAP + 'E' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_CAP + 'E' + SYM_WITH_DIAERESIS,
				SYM_LATIN_CAP + 'I' + SYM_WITH_GRAVE,
				SYM_LATIN_CAP + 'I' + SYM_WITH_ACUTE,
				SYM_LATIN_CAP + 'I' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_CAP + 'I' + SYM_WITH_DIAERESIS,
				SYM_LATIN_CAP + 'Eth',
				SYM_LATIN_CAP + 'N' + SYM_WITH_TILDE,
				SYM_LATIN_CAP + 'O' + SYM_WITH_GRAVE,
				SYM_LATIN_CAP + 'O' + SYM_WITH_ACUTE,
				SYM_LATIN_CAP + 'O' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_CAP + 'O' + SYM_WITH_TILDE,
				SYM_LATIN_CAP + 'O' + SYM_WITH_DIAERESIS,
				'Multiplication sign',
				SYM_LATIN_CAP + 'O' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'U' + SYM_WITH_GRAVE,
				SYM_LATIN_CAP + 'U' + SYM_WITH_ACUTE,
				SYM_LATIN_CAP + 'U' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_CAP + 'U' + SYM_WITH_DIAERESIS,
				SYM_LATIN_CAP + 'Y' + SYM_WITH_ACUTE,
				SYM_LATIN_CAP + 'Thorn',
				SYM_LATIN_SMALL + 'sharp S',
				SYM_LATIN_SMALL + 'A' + SYM_WITH_GRAVE,
				SYM_LATIN_SMALL + 'A' + SYM_WITH_ACUTE,
				SYM_LATIN_SMALL + 'A' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_SMALL + 'A' + SYM_WITH_TILDE,
				SYM_LATIN_SMALL + 'A' + SYM_WITH_DIAERESIS,
				SYM_LATIN_SMALL + 'A' + SYM_WITH_RINGABOVE,
				SYM_LATIN_SMALL + 'AE',
				SYM_LATIN_SMALL + 'C' + SYM_WITH_CEDILLA,
				SYM_LATIN_SMALL + 'E' + SYM_WITH_GRAVE,
				SYM_LATIN_SMALL + 'E' + SYM_WITH_ACUTE,
				SYM_LATIN_SMALL + 'E' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_SMALL + 'E' + SYM_WITH_DIAERESIS,
				SYM_LATIN_SMALL + 'I' + SYM_WITH_GRAVE,
				SYM_LATIN_SMALL + 'I' + SYM_WITH_ACUTE,
				SYM_LATIN_SMALL + 'I' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_SMALL + 'I' + SYM_WITH_DIAERESIS,
				SYM_LATIN_SMALL + 'Eth',
				SYM_LATIN_SMALL + 'N' + SYM_WITH_TILDE,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_GRAVE,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_ACUTE,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_TILDE,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_DIAERESIS,
				'Division sign',
				SYM_LATIN_SMALL + 'O' + SYM_WITH_STROKE,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_GRAVE,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_ACUTE,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_DIAERESIS,
				SYM_LATIN_SMALL + 'Y' + SYM_WITH_ACUTE,
				SYM_LATIN_SMALL + 'Thorn',
				SYM_LATIN_SMALL + 'Y' + SYM_WITH_DIAERESIS,
				SYM_LATIN_CAP + 'A' + SYM_WITH_MACRON,
				SYM_LATIN_SMALL + 'A' + SYM_WITH_MACRON,
				SYM_LATIN_CAP + 'A' + SYM_WITH_BREVE,
				SYM_LATIN_SMALL + 'A' + SYM_WITH_BREVE,
				SYM_LATIN_CAP + 'A' + SYM_WITH_OGONEK,
				SYM_LATIN_SMALL + 'A' + SYM_WITH_OGONEK,
				SYM_LATIN_CAP + 'C' + SYM_WITH_ACUTE,
				SYM_LATIN_SMALL + 'C' + SYM_WITH_ACUTE,
				SYM_LATIN_CAP + 'C' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_SMALL + 'C' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_CAP + 'C' + SYM_WITH_DOTABOVE,
				SYM_LATIN_SMALL + 'C' + SYM_WITH_DOTABOVE,
				SYM_LATIN_CAP + 'C' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'C' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'D' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'D' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'D' + SYM_WITH_STROKE,
				SYM_LATIN_SMALL + 'D' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'E' + SYM_WITH_MACRON,
				SYM_LATIN_SMALL + 'E' + SYM_WITH_MACRON,
				SYM_LATIN_CAP + 'E' + SYM_WITH_BREVE,
				SYM_LATIN_SMALL + 'E' + SYM_WITH_BREVE,
				SYM_LATIN_CAP + 'E' + SYM_WITH_DOTABOVE,
				SYM_LATIN_SMALL + 'E' + SYM_WITH_DOTABOVE,
				SYM_LATIN_CAP + 'E' + SYM_WITH_OGONEK,
				SYM_LATIN_SMALL + 'E' + SYM_WITH_OGONEK,
				SYM_LATIN_CAP + 'E' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'E' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'G' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_SMALL + 'G' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_CAP + 'G' + SYM_WITH_BREVE,
				SYM_LATIN_SMALL + 'G' + SYM_WITH_BREVE,
				SYM_LATIN_CAP + 'G' + SYM_WITH_DOTABOVE,
				SYM_LATIN_SMALL + 'G' + SYM_WITH_DOTABOVE,
				SYM_LATIN_CAP + 'G' + SYM_WITH_CEDILLA,
				SYM_LATIN_SMALL + 'G' + SYM_WITH_CEDILLA,
				SYM_LATIN_CAP + 'H' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_SMALL + 'H' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_CAP + 'H' + SYM_WITH_STROKE,
				SYM_LATIN_SMALL + 'H' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'I' + SYM_WITH_TILDE,
				SYM_LATIN_SMALL + 'I' + SYM_WITH_TILDE,
				SYM_LATIN_CAP + 'I' + SYM_WITH_MACRON,
				SYM_LATIN_SMALL + 'I' + SYM_WITH_MACRON,
				SYM_LATIN_CAP + 'I' + SYM_WITH_BREVE,
				SYM_LATIN_SMALL + 'I' + SYM_WITH_BREVE,
				SYM_LATIN_CAP + 'I' + SYM_WITH_OGONEK,
				SYM_LATIN_SMALL + 'I' + SYM_WITH_OGONEK,
				SYM_LATIN_CAP + 'I' + SYM_WITH_DOTABOVE,
				SYM_LATIN_SMALL + 'dotless I',
				SYM_LATIN + 'Capital Ligature IJ',
				SYM_LATIN + 'Small Ligature IJ',
				SYM_LATIN_CAP + 'J' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_SMALL + 'J' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_CAP + 'K' + SYM_WITH_CEDILLA,
				SYM_LATIN_SMALL + 'K' + SYM_WITH_CEDILLA,
				SYM_LATIN_SMALL + 'Kra',
				SYM_LATIN_CAP + 'L' + SYM_WITH_ACUTE,
				SYM_LATIN_SMALL + 'L' + SYM_WITH_ACUTE,
				SYM_LATIN_CAP + 'L' + SYM_WITH_CEDILLA,
				SYM_LATIN_SMALL + 'L' + SYM_WITH_CEDILLA,
				SYM_LATIN_CAP + 'L' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'L' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'L' + SYM_WITH_MIDDLEDOT,
				SYM_LATIN_SMALL + 'L' + SYM_WITH_MIDDLEDOT,
				SYM_LATIN_CAP + 'L' + SYM_WITH_STROKE,
				SYM_LATIN_SMALL + 'L' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'N' + SYM_WITH_ACUTE,
				SYM_LATIN_SMALL + 'N' + SYM_WITH_ACUTE,
				SYM_LATIN_CAP + 'N' + SYM_WITH_CEDILLA,
				SYM_LATIN_SMALL + 'N' + SYM_WITH_CEDILLA,
				SYM_LATIN_CAP + 'N' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'N' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'N preceded by apostrophe',
				SYM_LATIN_CAP + 'Eng',
				SYM_LATIN_SMALL + 'Eng',
				SYM_LATIN_CAP + 'O' + SYM_WITH_MACRON,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_MACRON,
				SYM_LATIN_CAP + 'O' + SYM_WITH_BREVE,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_BREVE,
				SYM_LATIN_CAP + 'O' + SYM_WITH_DOUBLEACUTE,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_DOUBLEACUTE,
				SYM_LATIN + 'Capital Ligature OE',
				SYM_LATIN + 'Small Ligature OE',
				SYM_LATIN_CAP + 'R' + SYM_WITH_ACUTE,
				SYM_LATIN_SMALL + 'R' + SYM_WITH_ACUTE,
				SYM_LATIN_CAP + 'R' + SYM_WITH_CEDILLA,
				SYM_LATIN_SMALL + 'R' + SYM_WITH_CEDILLA,
				SYM_LATIN_CAP + 'R' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'R' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'S' + SYM_WITH_ACUTE,
				SYM_LATIN_SMALL + 'S' + SYM_WITH_ACUTE,
				SYM_LATIN_CAP + 'S' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_SMALL + 'S' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_CAP + 'S' + SYM_WITH_CEDILLA,
				SYM_LATIN_SMALL + 'S' + SYM_WITH_CEDILLA,
				SYM_LATIN_CAP + 'S' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'S' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'T' + SYM_WITH_CEDILLA,
				SYM_LATIN_SMALL + 'T' + SYM_WITH_CEDILLA,
				SYM_LATIN_CAP + 'T' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'T' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'T' + SYM_WITH_STROKE,
				SYM_LATIN_SMALL + 'T' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'U' + SYM_WITH_TILDE,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_TILDE,
				SYM_LATIN_CAP + 'U' + SYM_WITH_MACRON,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_MACRON,
				SYM_LATIN_CAP + 'U' + SYM_WITH_BREVE,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_BREVE,
				SYM_LATIN_CAP + 'U' + SYM_WITH_RINGABOVE,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_RINGABOVE,
				SYM_LATIN_CAP + 'U' + SYM_WITH_DOUBLEACUTE,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_DOUBLEACUTE,
				SYM_LATIN_CAP + 'U' + SYM_WITH_OGONEK,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_OGONEK,
				SYM_LATIN_CAP + 'W' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_SMALL + 'W' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_CAP + 'Y' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_SMALL + 'Y' + SYM_WITH_CIRCUMFLEX,
				SYM_LATIN_CAP + 'Y' + SYM_WITH_DIAERESIS,
				SYM_LATIN_CAP + 'Z' + SYM_WITH_ACUTE,
				SYM_LATIN_SMALL + 'Z' + SYM_WITH_ACUTE,
				SYM_LATIN_CAP + 'Z' + SYM_WITH_DOTABOVE,
				SYM_LATIN_SMALL + 'Z' + SYM_WITH_DOTABOVE,
				SYM_LATIN_CAP + 'Z' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'Z' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'long S',
				SYM_LATIN_SMALL + 'B' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'B' + SYM_WITH_HOOK,
				SYM_LATIN_CAP + 'B' + SYM_WITH_TOPBAR,
				SYM_LATIN_SMALL + 'B' + SYM_WITH_TOPBAR,
				SYM_LATIN_CAP + 'Tone Six',
				SYM_LATIN_SMALL + 'Tone Six',
				SYM_LATIN_CAP + 'Open O',
				SYM_LATIN_CAP + 'C' + SYM_WITH_HOOK,
				SYM_LATIN_SMALL + 'C' + SYM_WITH_HOOK,
				SYM_LATIN_CAP + 'African D',
				SYM_LATIN_CAP + 'D' + SYM_WITH_HOOK,
				SYM_LATIN_CAP + 'D' + SYM_WITH_TOPBAR,
				SYM_LATIN_SMALL + 'D' + SYM_WITH_TOPBAR,
				SYM_LATIN_SMALL + 'Turned Delta',
				SYM_LATIN_CAP + 'Reversed E',
				SYM_LATIN_CAP + 'Schwa',
				SYM_LATIN_CAP + 'Open E',
				SYM_LATIN_CAP + 'F' + SYM_WITH_HOOK,
				SYM_LATIN_SMALL + 'F' + SYM_WITH_HOOK,
				SYM_LATIN_CAP + 'G' + SYM_WITH_HOOK,
				SYM_LATIN_CAP + 'Gamma',
				SYM_LATIN_SMALL + 'HV',
				SYM_LATIN_CAP + 'Iota',
				SYM_LATIN_CAP + 'I' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'K' + SYM_WITH_HOOK,
				SYM_LATIN_SMALL + 'K' + SYM_WITH_HOOK,
				SYM_LATIN_SMALL + 'L' + SYM_WITH + 'bar',
				SYM_LATIN_SMALL + 'Lambda' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'Turned M',
				SYM_LATIN_CAP + 'N' + SYM_WITH + 'left hook',
				SYM_LATIN_SMALL + 'N' + SYM_WITH + 'long right leg',
				SYM_LATIN_CAP + 'O' + SYM_WITH + 'middle tilde',
				SYM_LATIN_CAP + 'O' + SYM_WITH_HORN,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_HORN,
				SYM_LATIN_CAP + 'OI (= ' + SYM_LATIN_CAP + 'Gha)',
				SYM_LATIN_SMALL + 'OI (= ' + SYM_LATIN_SMALL + 'Gha)',
				SYM_LATIN_CAP + 'P' + SYM_WITH_HOOK,
				SYM_LATIN_SMALL + 'P' + SYM_WITH_HOOK,
				SYM_LATIN + 'Letter YR',
				SYM_LATIN_CAP + 'Tone Two',
				SYM_LATIN_SMALL + 'Tone Two',
				SYM_LATIN_CAP + 'Esh',
				SYM_LATIN + 'Letter Reversed Esh Loop',
				SYM_LATIN_SMALL + 'T' + SYM_WITH + 'palatal hook',
				SYM_LATIN_CAP + 'T' + SYM_WITH_HOOK,
				SYM_LATIN_SMALL + 'T' + SYM_WITH_HOOK,
				SYM_LATIN_CAP + 'T' + SYM_WITH + 'retroflex hook',
				SYM_LATIN_CAP + 'U' + SYM_WITH_HORN,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_HORN,
				SYM_LATIN_CAP + 'Upsilon',
				SYM_LATIN_CAP + 'V' + SYM_WITH_HOOK,
				SYM_LATIN_CAP + 'Y' + SYM_WITH_HOOK,
				SYM_LATIN_SMALL + 'Y' + SYM_WITH_HOOK,
				SYM_LATIN_CAP + 'Z' + SYM_WITH_STROKE,
				SYM_LATIN_SMALL + 'Z' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'Ezh',
				SYM_LATIN_CAP + 'Ezh reversed',
				SYM_LATIN_SMALL + 'Ezh reversed',
				SYM_LATIN_SMALL + 'Ezh' + SYM_WITH + 'tail',
				SYM_LATIN + 'Letter Two' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'Tone Five',
				SYM_LATIN_SMALL + 'Tone Five',
				SYM_LATIN + 'Letter Inverted Glottal Stop' + SYM_WITH_STROKE,
				SYM_LATIN + 'Letter Wynn',
				SYM_LATIN + 'Letter Dental Click',
				SYM_LATIN + 'Letter Lateral Click',
				SYM_LATIN + 'Letter Alveolar Click',
				SYM_LATIN + 'Letter Retroflex Click',
				SYM_LATIN_CAP + 'DZ' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'D' + SYM_WITH + 'Small Letter Z' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'DZ' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'LJ',
				SYM_LATIN_CAP + 'L' + SYM_WITH + 'Small Letter J',
				SYM_LATIN_SMALL + 'LJ',
				SYM_LATIN_CAP + 'NJ',
				SYM_LATIN_CAP + 'N' + SYM_WITH + 'Small Letter J',
				SYM_LATIN_SMALL + 'NJ',
				SYM_LATIN_CAP + 'A' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'A' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'I' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'I' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'O' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'U' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'U' + SYM_WITH_DIAERESIS_AND_MACRON,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_DIAERESIS_AND_MACRON,
				SYM_LATIN_CAP + 'U' + SYM_WITH_DIAERESIS_AND_ACUTE,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_DIAERESIS_AND_ACUTE,
				SYM_LATIN_CAP + 'U' + SYM_WITH_DIAERESIS_AND_CARON,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_DIAERESIS_AND_CARON,
				SYM_LATIN_CAP + 'U' + SYM_WITH_DIAERESIS_AND_GRAVE,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_DIAERESIS_AND_GRAVE,
				SYM_LATIN_SMALL + 'Turned E',
				SYM_LATIN_CAP + 'A' + SYM_WITH_DIAERESIS_AND_MACRON,
				SYM_LATIN_SMALL + 'A' + SYM_WITH_DIAERESIS_AND_MACRON,
				SYM_LATIN_CAP + 'A' + SYM_WITH_DOTABOVE_AND_MACRON,
				SYM_LATIN_SMALL + 'A' + SYM_WITH_DOTABOVE_AND_MACRON,
				SYM_LATIN_CAP + 'AE' + SYM_WITH_MACRON,
				SYM_LATIN_SMALL + 'AE' + SYM_WITH_MACRON,
				SYM_LATIN_CAP + 'G' + SYM_WITH_STROKE,
				SYM_LATIN_SMALL + 'G' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'G' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'G' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'K' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'K' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'O' + SYM_WITH_OGONEK,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_OGONEK,
				SYM_LATIN_CAP + 'O' + SYM_WITH_OGONEK_AND_MACRON,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_OGONEK_AND_MACRON,
				SYM_LATIN_CAP + 'Ezh' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'Ezh' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'J' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'DZ',
				SYM_LATIN_CAP + 'D' + SYM_WITH + 'Small Letter Z',
				SYM_LATIN_SMALL + 'DZ',
				SYM_LATIN_CAP + 'G' + SYM_WITH_ACUTE,
				SYM_LATIN_SMALL + 'G' + SYM_WITH_ACUTE,
				SYM_LATIN_CAP + 'Hwair',
				SYM_LATIN_CAP + 'Wynn',
				SYM_LATIN_CAP + 'N' + SYM_WITH_GRAVE,
				SYM_LATIN_SMALL + 'N' + SYM_WITH_GRAVE,
				SYM_LATIN_CAP + 'A' + SYM_WITH_RINGABOVE_AND_ACUTE,
				SYM_LATIN_SMALL + 'A' + SYM_WITH_RINGABOVE_AND_ACUTE,
				SYM_LATIN_CAP + 'AE' + SYM_WITH_ACUTE,
				SYM_LATIN_SMALL + 'AE' + SYM_WITH_ACUTE,
				SYM_LATIN_CAP + 'O' + SYM_WITH_STROKE_AND_ACUTE,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_STROKE_AND_ACUTE,
				SYM_LATIN_CAP + 'A' + SYM_WITH_DOUBLEGRAVE,
				SYM_LATIN_SMALL + 'A' + SYM_WITH_DOUBLEGRAVE,
				SYM_LATIN_CAP + 'A' + SYM_WITH_INVERTEDBREVE,
				SYM_LATIN_SMALL + 'A' + SYM_WITH_INVERTEDBREVE,
				SYM_LATIN_CAP + 'E' + SYM_WITH_DOUBLEGRAVE,
				SYM_LATIN_SMALL + 'E' + SYM_WITH_DOUBLEGRAVE,
				SYM_LATIN_CAP + 'E' + SYM_WITH_INVERTEDBREVE,
				SYM_LATIN_SMALL + 'E' + SYM_WITH_INVERTEDBREVE,
				SYM_LATIN_CAP + 'I' + SYM_WITH_DOUBLEGRAVE,
				SYM_LATIN_SMALL + 'I' + SYM_WITH_DOUBLEGRAVE,
				SYM_LATIN_CAP + 'I' + SYM_WITH_INVERTEDBREVE,
				SYM_LATIN_SMALL + 'I' + SYM_WITH_INVERTEDBREVE,
				SYM_LATIN_CAP + 'O' + SYM_WITH_DOUBLEGRAVE,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_DOUBLEGRAVE,
				SYM_LATIN_CAP + 'O' + SYM_WITH_INVERTEDBREVE,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_INVERTEDBREVE,
				SYM_LATIN_CAP + 'R' + SYM_WITH_DOUBLEGRAVE,
				SYM_LATIN_SMALL + 'R' + SYM_WITH_DOUBLEGRAVE,
				SYM_LATIN_CAP + 'R' + SYM_WITH_INVERTEDBREVE,
				SYM_LATIN_SMALL + 'R' + SYM_WITH_INVERTEDBREVE,
				SYM_LATIN_CAP + 'U' + SYM_WITH_DOUBLEGRAVE,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_DOUBLEGRAVE,
				SYM_LATIN_CAP + 'U' + SYM_WITH_INVERTEDBREVE,
				SYM_LATIN_SMALL + 'U' + SYM_WITH_INVERTEDBREVE,
				SYM_LATIN_CAP + 'S' + SYM_WITH_COMMABELOW,
				SYM_LATIN_SMALL + 'S' + SYM_WITH_COMMABELOW,
				SYM_LATIN_CAP + 'T' + SYM_WITH_COMMABELOW,
				SYM_LATIN_SMALL + 'T' + SYM_WITH_COMMABELOW,
				SYM_LATIN_CAP + 'Yogh',
				SYM_LATIN_SMALL + 'Yogh',
				SYM_LATIN_CAP + 'H' + SYM_WITH_CARON,
				SYM_LATIN_SMALL + 'H' + SYM_WITH_CARON,
				SYM_LATIN_CAP + 'N' + SYM_WITH + 'long right leg',
				SYM_LATIN_SMALL + 'D' + SYM_WITH_CURL,
				SYM_LATIN_CAP + 'OU',
				SYM_LATIN_SMALL + 'OU',
				SYM_LATIN_CAP + 'Z' + SYM_WITH_HOOK,
				SYM_LATIN_SMALL + 'Z' + SYM_WITH_HOOK,
				SYM_LATIN_CAP + 'A' + SYM_WITH_DOTABOVE,
				SYM_LATIN_SMALL + 'A' + SYM_WITH_DOTABOVE,
				SYM_LATIN_CAP + 'E' + SYM_WITH_CEDILLA,
				SYM_LATIN_SMALL + 'E' + SYM_WITH_CEDILLA,
				SYM_LATIN_CAP + 'O' + SYM_WITH_DIAERESIS_AND_MACRON,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_DIAERESIS_AND_MACRON,
				SYM_LATIN_CAP + 'O' + SYM_WITH_TILDE_AND_MACRON,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_TILDE_AND_MACRON,
				SYM_LATIN_CAP + 'O' + SYM_WITH_DOTABOVE,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_DOTABOVE,
				SYM_LATIN_CAP + 'O' + SYM_WITH_DOTABOVE_AND_MACRON,
				SYM_LATIN_SMALL + 'O' + SYM_WITH_DOTABOVE_AND_MACRON,
				SYM_LATIN_CAP + 'Y' + SYM_WITH_MACRON,
				SYM_LATIN_SMALL + 'Y' + SYM_WITH_MACRON,
				SYM_LATIN_SMALL + 'L' + SYM_WITH_CURL,
				SYM_LATIN_SMALL + 'N' + SYM_WITH_CURL,
				SYM_LATIN_SMALL + 'T' + SYM_WITH_CURL,
				SYM_LATIN_SMALL + 'Dotless J',
				SYM_LATIN_SMALL + 'DB Diagraph',
				SYM_LATIN_SMALL + 'QP Diagraph',
				SYM_LATIN_CAP + 'A' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'C' + SYM_WITH_STROKE,
				SYM_LATIN_SMALL + 'C' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'L' + SYM_WITH + 'bar',
				SYM_LATIN_CAP + 'T' + SYM_WITH + 'diagonal stroke',
				SYM_LATIN_SMALL + 'S' + SYM_WITH + 'swash tail',
				SYM_LATIN_SMALL + 'Z' + SYM_WITH + 'swash tail',
				SYM_LATIN_CAP + 'Glottal Stop',
				SYM_LATIN_SMALL + 'Glottal Stop',
				SYM_LATIN_CAP + 'B' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'U bar',
				SYM_LATIN_CAP + 'Turned V',
				SYM_LATIN_CAP + 'E' + SYM_WITH_STROKE,
				SYM_LATIN_SMALL + 'E' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'J' + SYM_WITH_STROKE,
				SYM_LATIN_SMALL + 'J' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'Q' + SYM_WITH + 'hook tail',
				SYM_LATIN_SMALL + 'Q' + SYM_WITH + 'hook tail',
				SYM_LATIN_CAP + 'R' + SYM_WITH_STROKE,
				SYM_LATIN_SMALL + 'R' + SYM_WITH_STROKE,
				SYM_LATIN_CAP + 'Y' + SYM_WITH_STROKE,
				SYM_LATIN_SMALL + 'Y' + SYM_WITH_STROKE
			]);  // last item = 591

			_extend(symbols, 913, [
				SYM_GREEK_CAP + 'Alpha',
				SYM_GREEK_CAP + 'Beta',
				SYM_GREEK_CAP + 'Gamma',
				SYM_GREEK_CAP + 'Delta',
				SYM_GREEK_CAP + 'Epsilon',
				SYM_GREEK_CAP + 'Zeta',
				SYM_GREEK_CAP + 'Eta',
				SYM_GREEK_CAP + 'Theta',
				SYM_GREEK_CAP + 'Iota',
				SYM_GREEK_CAP + 'Kappa',
				SYM_GREEK_CAP + 'Lambda',
				SYM_GREEK_CAP + 'Mu',
				SYM_GREEK_CAP + 'Nu',
				SYM_GREEK_CAP + 'Xi',
				SYM_GREEK_CAP + 'Omicron',
				SYM_GREEK_CAP + 'Pi',
				SYM_GREEK_CAP + 'Rho'
			]);  // last item = 929

			_extend(symbols, 931, [
				SYM_GREEK_CAP + 'Sigma',
				SYM_GREEK_CAP + 'Tau',
				SYM_GREEK_CAP + 'Upsilon',
				SYM_GREEK_CAP + 'Phi',
				SYM_GREEK_CAP + 'Chi',
				SYM_GREEK_CAP + 'Psi',
				SYM_GREEK_CAP + 'Omega',
				SYM_GREEK_CAP + 'Iota' + SYM_WITH_DIAERESIS,
				SYM_GREEK_CAP + 'Upsilon' + SYM_WITH_DIAERESIS,
				SYM_GREEK_SMALL + 'Alpha' + SYM_WITH_ACUTE,
				SYM_GREEK_SMALL + 'Epsilon' + SYM_WITH_ACUTE,
				SYM_GREEK_SMALL + 'Eta' + SYM_WITH_ACUTE,
				SYM_GREEK_SMALL + 'Iota' + SYM_WITH_ACUTE,
				SYM_GREEK_SMALL + 'Upsilon' + SYM_WITH_DIAERESIS_AND_ACUTE,
				SYM_GREEK_SMALL + 'Alpha',
				SYM_GREEK_SMALL + 'Beta',
				SYM_GREEK_SMALL + 'Gamma',
				SYM_GREEK_SMALL + 'Delta',
				SYM_GREEK_SMALL + 'Epsilon',
				SYM_GREEK_SMALL + 'Zeta',
				SYM_GREEK_SMALL + 'Eta',
				SYM_GREEK_SMALL + 'Theta',
				SYM_GREEK_SMALL + 'Iota',
				SYM_GREEK_SMALL + 'Kappa',
				SYM_GREEK_SMALL + 'Lambda',
				SYM_GREEK_SMALL + 'Mu',
				SYM_GREEK_SMALL + 'Nu',
				SYM_GREEK_SMALL + 'Xi',
				SYM_GREEK_SMALL + 'Omicron',
				SYM_GREEK_SMALL + 'Pi',
				SYM_GREEK_SMALL + 'Rho',
				SYM_GREEK_SMALL + 'Final Sigma',
				SYM_GREEK_SMALL + 'Sigma',
				SYM_GREEK_SMALL + 'Tau',
				SYM_GREEK_SMALL + 'Upsilon',
				SYM_GREEK_SMALL + 'Phi',
				SYM_GREEK_SMALL + 'Chi',
				SYM_GREEK_SMALL + 'Psi',
				SYM_GREEK_SMALL + 'Omega',
				SYM_GREEK_SMALL + 'Iota' + SYM_WITH_DIAERESIS,
				SYM_GREEK_SMALL + 'Upsilon' + SYM_WITH_DIAERESIS,
				SYM_GREEK_SMALL + 'Omicron' + SYM_WITH_ACUTE,
				SYM_GREEK_SMALL + 'Upsilon' + SYM_WITH_ACUTE,
				SYM_GREEK_SMALL + 'Omega' + SYM_WITH_ACUTE
			]);  // last item = 974

			_extend(symbols, 8704, [
				'for all',
				'complement',
				'partial differential',
				'there exists',
				'there does' + SYM_NOT + 'exist',
				'empty set',
				'increment',
				'nabla',
				SYM_ELEMENT_OF,
				SYM_NOT + 'an' + SYM_ELEMENT_OF,
				'small' + SYM_ELEMENT_OF,
				SYM_CONTAINS + 'as member',
				'does' + SYM_NOT + 'contain as member',
				'small' + SYM_CONTAINS + 'as member',
				'end of proof',
				'n-ary product',
				'n-ary coproduct',
				'n-ary summation',
				'minus sign',
				'minus-or-plus sign',
				'dot plus',
				'division slash',
				'set minus',
				'asterisk' + SYM_OPERATOR,
				'ring' + SYM_OPERATOR,
				'bullet' + SYM_OPERATOR,
				SYM_SQUARE + 'root',
				'cube root',
				'fourth root',
				'proportional to',
				'infinity',
				'right angle',
				'angle',
				'measured angle',
				'spherical angle',
				'divides',
				'does' + SYM_NOT + 'divide',
				'parallel to',
				SYM_NOT + 'parallel to',
				'logical' + SYM_AND,
				'logical' + SYM_OR,
				'intersection',
				'union',
				'integral',
				'double integral',
				'triple integral',
				'contour integral',
				'surface integral',
				'volume integral',
				'clockwise integral',
				'clockwise contour integral',
				'anticlockwise contour integral',
				'therefore',
				'because',
				'ratio',
				'proportion',
				'dot minus',
				'excess',
				'geometric proportion',
				'homothetic',
				'tilde' + SYM_OPERATOR,
				'reversed tilde',
				'inverted lazy s',
				'sine wave',
				'wreath product',
				SYM_NOT + 'tilde',
				'minus tilde',
				'asymptotically' + SYM_EQUAL_TO,
				SYM_NOT + 'asymptotically' + SYM_EQUAL_TO,
				'approximately' + SYM_EQUAL_TO,
				'approximately but' + SYM_NOT + 'actually' + SYM_EQUAL_TO,
				'neither approximately nor actually' + SYM_EQUAL_TO,
				'almost' + SYM_EQUAL_TO,
				SYM_NOT + 'almost' + SYM_EQUAL_TO,
				'almost equal' + SYM_OR + SYM_EQUAL_TO,
				'triple tilde',
				'all' + SYM_EQUAL_TO,
				'equivalent to',
				'geometrically' + SYM_EQUIVALENT_TO,
				'difference between',
				'approaches the limit',
				'geometrically' + SYM_EQUAL_TO,
				'approximately' + SYM_EQUAL_TO + SYM_OR + 'the image of',
				'image of' + SYM_OR + 'approximately' + SYM_EQUAL_TO,
				'colon equals',
				'equals colon',
				'ring in' + SYM_EQUAL_TO,
				'ring' + SYM_EQUAL_TO,
				'corresponds to',
				'estimates',
				'equiangular to',
				'star equals',
				'delta' + SYM_EQUAL_TO,
				SYM_EQUAL_TO + 'by definition',
				'measured by',
				'questioned' + SYM_EQUAL_TO,
				SYM_NOT + SYM_EQUAL_TO,
				'identical to',
				SYM_NOT + 'identical to',
				'strictly' + SYM_EQUIVALENT_TO,
				SYM_LESS_THAN + SYM_OR + SYM_EQUAL_TO,
				SYM_GREATER_THAN + SYM_OR + SYM_EQUAL_TO,
				SYM_LESS_THAN + 'over' + SYM_EQUAL_TO,
				SYM_GREATER_THAN + 'over' + SYM_EQUAL_TO,
				SYM_LESS_THAN + 'but' + SYM_NOT + SYM_EQUAL_TO,
				SYM_GREATER_THAN + 'but' + SYM_NOT + SYM_EQUAL_TO,
				'much' + SYM_LESS_THAN,
				'much' + SYM_GREATER_THAN,
				'between',
				SYM_NOT + SYM_EQUIVALENT_TO,
				SYM_NOT + SYM_LESS_THAN,
				SYM_NOT + SYM_GREATER_THAN,
				'neither' + SYM_LESS_THAN + 'nor' + SYM_EQUAL_TO,
				'neither' + SYM_GREATER_THAN + 'nor' + SYM_EQUAL_TO,
				SYM_LESS_THAN + SYM_OR + SYM_EQUIVALENT_TO,
				SYM_GREATER_THAN + SYM_OR + SYM_EQUIVALENT_TO,
				'neither' + SYM_LESS_THAN + 'nor' + SYM_EQUIVALENT_TO,
				'neither' + SYM_GREATER_THAN + 'nor' + SYM_EQUIVALENT_TO,
				SYM_LESS_THAN + SYM_OR + SYM_GREATER_THAN,
				SYM_GREATER_THAN + SYM_OR + SYM_LESS_THAN,
				'neither' + SYM_LESS_THAN + 'nor' + SYM_GREATER_THAN,
				'neither' + SYM_GREATER_THAN + 'nor' + SYM_LESS_THAN,
				'precedes',
				'succeeds',
				'precedes' + SYM_OR + SYM_EQUAL_TO,
				'succeeds' + SYM_OR + SYM_EQUAL_TO,
				'precedes' + SYM_OR + SYM_EQUIVALENT_TO,
				'succeeds' + SYM_OR + SYM_EQUIVALENT_TO,
				'does' + SYM_NOT + 'precede',
				'does' + SYM_NOT + 'succeed',
				'subset of',
				'superset of',
				SYM_NOT + 'a subset of',
				SYM_NOT + 'a superset of',
				'subset of' + SYM_OR + SYM_EQUAL_TO,
				'superset of' + SYM_OR + SYM_EQUAL_TO,
				'neither a subset of nor' + SYM_EQUAL_TO,
				'neither a superset of nor' + SYM_EQUAL_TO,
				'subset of' + SYM_WITH + SYM_NOT + SYM_EQUAL_TO,
				'superset of' + SYM_WITH + SYM_NOT + SYM_EQUAL_TO,
				'multiset',
				'multiset multiplication',
				'multiset union',
				SYM_SQUARE + 'image of',
				SYM_SQUARE + 'original of',
				SYM_SQUARE + 'image of' + SYM_OR + SYM_EQUAL_TO,
				SYM_SQUARE + 'original of' + SYM_OR + SYM_EQUAL_TO,
				SYM_SQUARE + 'cap',
				SYM_SQUARE + 'cup',
				'circled plus',
				'circled minus',
				'circled times',
				'circled division slash',
				'circled dot' + SYM_OPERATOR,
				'circled ring' + SYM_OPERATOR,
				'circled asterisk' + SYM_OPERATOR,
				'circled equals',
				'circled dash',
				'squared plus',
				'squared minus',
				'squared times',
				'squared dot' + SYM_OPERATOR,
				'right tack',
				'left tack',
				'down tack',
				'up tack',
				'assertion',
				'models',
				'true',
				'forces',
				'triple vertical bar right turnstile',
				'double vertical bar double right turnstile',
				'does' + SYM_NOT + 'prove',
				SYM_NOT + 'true',
				'does' + SYM_NOT + 'force',
				'negated double vertical bar double right turnstile',
				'precedes under relation',
				'succeeds under relation',
				'normal subgroup of',
				SYM_CONTAINS + 'as normal subgroup',
				'normal subgroup of' + SYM_OR + SYM_EQUAL_TO,
				SYM_CONTAINS + 'as normal subgroup' + SYM_OR + SYM_EQUAL_TO,
				'original of',
				'image of',
				'multimap',
				'hermitian conjugate matrix',
				'intercalate',
				'xor',
				'nand',
				'nor',
				'right angle' + SYM_WITH + 'arc',
				'right triangle',
				'n-ary logical' + SYM_AND,
				'n-ary logical' + SYM_OR,
				'n-ary intersection',
				'n-ary union',
				'diamond' + SYM_OPERATOR,
				'dot' + SYM_OPERATOR,
				'star' + SYM_OPERATOR,
				'division times',
				'bowtie',
				'left normal factor semidirect product',
				'right normal factor semidirect product',
				'left semidirect product',
				'right semidirect product',
				'reversed tilde equals',
				'curly logical' + SYM_OR,
				'curly logical' + SYM_AND,
				'double subset',
				'double superset',
				'double intersection',
				'double union',
				'pitchfork',
				'equal' + SYM_AND + 'parallel to',
				SYM_LESS_THAN + SYM_WITH + 'dot',
				SYM_GREATER_THAN + SYM_WITH + 'dot',
				'very much' + SYM_LESS_THAN,
				'very much' + SYM_GREATER_THAN,
				SYM_LESS_THAN + SYM_EQUAL_TO + SYM_OR + SYM_GREATER_THAN,
				SYM_GREATER_THAN + SYM_EQUAL_TO + SYM_OR + SYM_LESS_THAN,
				SYM_EQUAL_TO + SYM_OR + SYM_LESS_THAN,
				SYM_EQUAL_TO + SYM_OR + SYM_GREATER_THAN,
				SYM_EQUAL_TO + SYM_OR + 'precedes',
				SYM_EQUAL_TO + SYM_OR + 'succeeds',
				'does' + SYM_NOT + 'precede' + SYM_OR + 'equal',
				'does' + SYM_NOT + 'succeed' + SYM_OR + 'equal',
				SYM_NOT + SYM_SQUARE + 'image of' + SYM_OR + SYM_EQUAL_TO,
				SYM_NOT + SYM_SQUARE + 'original of' + SYM_OR + SYM_EQUAL_TO,
				SYM_SQUARE + 'image of' + SYM_OR + SYM_NOT + SYM_EQUAL_TO,
				SYM_SQUARE + 'original of' + SYM_OR + SYM_NOT + SYM_EQUAL_TO,
				SYM_LESS_THAN + ' but' + SYM_NOT + SYM_EQUIVALENT_TO,
				SYM_GREATER_THAN + ' but' + SYM_NOT + SYM_EQUIVALENT_TO,
				'precedes but' + SYM_NOT + SYM_EQUIVALENT_TO,
				'succeeds but' + SYM_NOT + SYM_EQUIVALENT_TO,
				SYM_NOT + 'normal subgroup of',
				'does' + SYM_NOT + 'contain as normal subgroup',
				SYM_NOT + 'normal subgroup of' + SYM_OR + SYM_EQUAL_TO,
				'does' + SYM_NOT + 'contain as normal subgroup' + SYM_OR + 'equal',
				'vertical ellipsis',
				'midline horizontal ellipsis',
				'up right diagonal ellipsis',
				'down right diagonal ellipsis',
				SYM_ELEMENT_OF + SYM_WITH + 'long horizontal stroke',
				SYM_ELEMENT_OF + SYM_WITH + SYM_VERTICAL_BAR_AT_END_OF_HORZ_STROKE,
				'small' + SYM_ELEMENT_OF + SYM_WITH + SYM_VERTICAL_BAR_AT_END_OF_HORZ_STROKE,
				SYM_ELEMENT_OF + SYM_WITH_DOTABOVE,
				SYM_ELEMENT_OF + SYM_WITH + 'overbar',
				'small' + SYM_ELEMENT_OF + SYM_WITH + 'overbar',
				SYM_ELEMENT_OF + SYM_WITH + 'underbar',
				SYM_ELEMENT_OF + SYM_WITH + 'two horizontal strokes',
				SYM_CONTAINS + SYM_WITH + 'long horizontal stroke',
				SYM_CONTAINS + SYM_WITH + SYM_VERTICAL_BAR_AT_END_OF_HORZ_STROKE,
				'small' + SYM_CONTAINS + SYM_WITH + SYM_VERTICAL_BAR_AT_END_OF_HORZ_STROKE,
				SYM_CONTAINS + SYM_WITH + 'overbar',
				'small' + SYM_CONTAINS + SYM_WITH + 'overbar',
				'z notation bag membership'
			]);  // last item = 8959

			// add HTML4 entities
			['amp','gt','lt','quot','acute','cedil','circ','macr','middot','tilde','uml','Aacute','aacute','Acirc','acirc','AElig','aelig','Agrave','agrave','Aring','aring','Atilde','atilde','Auml','auml','Ccedil','ccedil','Eacute','eacute','Ecirc','ecirc','Egrave','egrave','ETH','eth','Euml','euml','Iacute','iacute','Icirc','icirc','Igrave','igrave','Iuml','iuml','Ntilde','ntilde','Oacute','oacute','Ocirc','ocirc','OElig','oelig','Ograve','ograve','Oslash','oslash','Otilde','otilde','Ouml','ouml','Scaron','scaron','szlig','THORN','thorn','Uacute','uacute','Ucirc','ucirc','Ugrave','ugrave','Uuml','uuml','Yacute','yacute','yuml','Yuml','cent','curren','euro','pound','yen','brvbar','bull','copy','dagger','Dagger','frasl','hellip','iexcl','image','iquest','lrm','mdash','ndash','not','oline','ordf','ordm','para','permil','prime','Prime','real','reg','rlm','sect','shy','sup1','trade','weierp','bdquo','laquo','ldquo','lsaquo','lsquo','raquo','rdquo','rsaquo','rsquo','sbquo','emsp','ensp','nbsp','thinsp','zwj','zwnj','deg','divide','frac12','frac14','frac34','ge','le','minus','sup2','sup3','times','alefsym','and','ang','asymp','cap','cong','cup','empty','equiv','exist','fnof','forall','infin','int','isin','lang','lceil','lfloor','lowast','micro','nabla','ne','ni','notin','nsub','oplus','or','otimes','part','perp','plusmn','prod','prop','radic','rang','rceil','rfloor','sdot','sim','sub','sube','sum','sup','supe','there4','Alpha','alpha','Beta','beta','Chi','chi','Delta','delta','Epsilon','epsilon','Eta','eta','Gamma','gamma','Iota','iota','Kappa','kappa','Lambda','lambda','Mu','mu','Nu','nu','Omega','omega','Omicron','omicron','Phi','phi','Pi','pi','piv','Psi','psi','Rho','rho','Sigma','sigma','sigmaf','Tau','tau','Theta','theta','thetasym','upsih','Upsilon','upsilon','Xi','xi','Zeta','zeta','crarr','darr','dArr','harr','hArr','larr','lArr','rarr','rArr','uarr','uArr','clubs','diams','hearts','spades','loz'].each(function (entityname) {
				var character = entityToChar(entityname);
				symbols[character] = Array.from(symbols[character]).include(entityname);
			});

			/**
			* Gives a textual description of a unicode character.
			*/
			this.symbols = symbols;
		},

		/**
		* Finds the symbols that match a search query.
		* @return An object with unicode characters as keys and description texts as values.
		*/
		'find': function (text) {
			var exprs = text.clean().split(' ').map(function (item) {  // remove redundant spaces and split string into parts
				return new RegExp('\\b' + item.escapeRegExp(), 'i');  // escape special characters in regular expression and match only at start of word
			});

			// looks in symbol table
			var symbolchars = Object.filter(this.symbols, function(values) {
				return exprs.every(function (expr) {  // return only symbols whose description matches every item of query
					return values.some(function (value) {
						return expr.test(value);
					});
				});
			});

			// look in HTML entity table
			var entityexpr = Number.from(text) ? '&#' + text + ';' : text.replace(/^&?(.+?);?$/, '$1');
			var entitychar = entityToChar(entityexpr);

			var entitychars = {};
			if (entitychar.length == 1) {  // entity name could be resolved into character
				entitychars[entitychar] = entityexpr;
			}

			return Object.merge(entitychars, symbolchars);
		}
	});

	setplus.SymbolsDialog = new Class({
		'Extends': setplus.EditorDialog,

		'initialize': function () {
			var self = this;
			self.parent();

			self._title.adopt(
				new Element('span', {
					'class': 'setplus-symbols-title'
				})
			);

			// initialize symbol map
			var map = new setplus.SymbolsMap();

			var searchbox, preview, description, results;
			self._content.adopt(
				new Element('div', {
					'class': 'setplus-symbols-header'
				}).adopt(
					new Element('div').adopt(
						new Element('span', {
							'class': 'setplus-symbols-search'
						}),
						new Element('span', {
							'html': ':&nbsp;'
						}),
						// search query text box
						searchbox = new Element('input', {
							'type': 'text'
						})
					),
					preview = new Element('div', {
						'class': 'setplus-symbols-preview'
					}),
					description = new Element('span')
				),
				// results container
				results = new Element('div', {
					'class': 'setplus-symbols-matched',
					'events': {
						'click': function (event) {
							if (results.getChildren().contains(event.target)) {
								self.invoke(function (editor) {
									// insert symbol
									editor.pasteplain($(event.target).get('text'));

									// close pop-up window
									self.hide();
								});
							}
						},
						'mouseover': function (event) {
							if (results.getChildren().contains(event.target)) {
								var character = $(event.target).get('html');
								preview.set('html', character);
								description.set('html', $(event.target).get('title') + ' [&amp;#'+character.charCodeAt(0)+';]');
							}
						},
						'mouseout': function () {
							preview.set('html', '');
							description.set('html', '');
						}
					}
				})
			);

			/**
			* Updates the result set container.
			*/
			function _update() {
				results.empty();
				results.adopt(
					Object.values(
						Object.map(map.find(searchbox.get('value')), function (value, key) {
							return new Element('span', {
								'class': 'setplus-symbols-symbol',
								'title': value,
								'text': key,
								'unselectable': 'on'  // Internet Explorer
							});
						})
					)
				);
			}
			_update();

			// launch auto-search timer when user makes changes to search box
			var timer;
			searchbox.addEvents({
				'input': function () {
					window.clearTimeout(timer);
					timer = window.setTimeout(_update, 200);
				}
			});
		}
	});
})(document.id);