window.data = [];
window.ranges = [];

function getCodepointDescription(codepoint, name) {
	codepoint = parseInt(codepoint);
	return name + ' ' + ctos([codepoint]);
}

function mergeNewAndLegacyNames(data_file_name, data_file_legacy_name) {
	if (data_file_legacy_name && data_file_legacy_name != '')
		return data_file_name + ' (' + data_file_legacy_name + ')';
	return data_file_name;
}

function getRangeFunctionForName(name) {
	return function(codepoint) {
		return getCodepointDescription(codepoint, name);
	}
}

function initUnicodeData(completion) {
	var client = new XMLHttpRequest();
	client.open('GET', 'UnicodeData.txt');
	client.onreadystatechange = function() { 
		if (client.readyState == 4 && client.status == 200) {
			var dataStrings = client.responseText.split('\n');
			window.data = [];
			for (var i in dataStrings) {
				var data_line = dataStrings[i].split(';');
				if (data_line[1].endsWith(', First>')) {
					window.ranges.push([
						parseInt('0x' + data_line[0]),
						parseInt('0x' + dataStrings[parseInt(i)+1].split(';')[0]),
						getRangeFunctionForName(data_line[1].substring(1, data_line[1].length - 8))
					]);
				} else if (data_line[1].endsWith(', Last>')) {
					continue;
				} else {
					window.data[parseInt('0x' + data_line[0])] = getCodepointDescription(
						'0x' + data_line[0],
						mergeNewAndLegacyNames(data_line[1], data_line[10])
					);
				}
			}
			completion();
		}
	}
	client.send();
}

function getUnicodeData(codepoint) {
	if (window.data[codepoint])
		return window.data[codepoint] + getHanEntry(codepoint);
	for (var i in window.ranges) {
		var range = window.ranges[i];
		if (codepoint >= range[0] && codepoint <= range[1])
			return range[2](codepoint) + getHanEntry(codepoint);
	}
	return getCodepointDescription(codepoint, 'Unknown') + getHanEntry(codepoint);
}

function getSearchString(codepoint) {
	return getUnicodeData(codepoint).toUpperCase();
}

function searchCodepoints(str) {
	var results = [];
	var count = 0;

	str = str.toUpperCase();
	if (str.indexOf('U+') != -1) {
		results.push(parseInt(str.replace('U+', '0x')));
		++count;
	} else if (!isNaN(parseInt('0x' + str))) {
		results.push(parseInt('0x' + str));
		results.push(parseInt(str));
		count += 2;
	}

	for (var codepoint in window.data) {
		var name = getSearchString(codepoint);
		if (name.includes(str)) {
			results.push(parseInt(codepoint));
			if (++count >= 256)
				break;
		}
	}
	if (count < 256 || codepoint > 0x3400) {
		for (var codepoint in window.han_meanings) {
			var name = getSearchString(codepoint);
			if (name.includes(str)) {
				results.push(parseInt(codepoint));
				if (++count >= 256)
					break;
			}
		}
	}
	return results;
}
@@ -1973,270 +1973,458 @@
 %5B%5D;%0A
+%0A
 %09var 
-count = 0;%0A%0A%09str
+deduplicate = function(a) %7B%0A%09%09var temp = %7B%7D;%0A%09%09for (var i = 0; i %3C a.length; i++)%0A%09%09%09temp%5Ba%5Bi%5D%5D
  = 
-s
 tr
-.toUpperCase();%0A%09if (str.indexOf('U+') != -1) %7B%0A%09%09results.push(parseInt(str.replace('U+', '0x')));%0A%09%09++count;%0A%09%7D else if (!isNaN(parseInt('0x' + str))) %7B%0A%09%09results.push(parseInt('0x' + str));%0A%09%09results.push(parseInt(str));%0A%09%09count += 2
+ue;%0A%09%09var r = %5B%5D;%0A%09%09for (var k in temp)%0A%09%09%09r.push(parseInt(k));%0A%09%09return r;%0A%09%7D%0A%09var reachedMaxResults = function() %7B%0A%09%09if (results.length %3C 256)%0A%09%09%09return false;%0A%09%09results = deduplicate(results);%0A%09%09if (results.length %3C 256)%0A%09%09%09return false;%0A%09%09return true;%0A%09%7D%0A%0A%09str = str.toUpperCase();%0A%09if (str.startsWith('U+')) %7B%0A%09%09str = str.replace('U+', '')
 ;%0A%09%7D
@@ -2465,28 +2465,36 @@
 ta) %7B%0A%09%09var 
-name
+searchString
  = getSearch
@@ -2514,28 +2514,63 @@
 int);%0A%09%09if (
-name
+searchString.includes(str) %7C%7C codepoint
 .includes(st
@@ -2616,38 +2616,43 @@
 t));%0A%09%09%09if (
-++count %3E= 256
+reachedMaxResults()
 )%0A%09%09%09%09break;
@@ -2668,19 +2668,28 @@
 if (
-count %3C 256
+!reachedMaxResults()
  %7C%7C 
@@ -2764,20 +2764,28 @@
 %0A%09%09%09var 
-name
+searchString
  = getSe
@@ -2814,20 +2814,55 @@
 %0A%09%09%09if (
-name
+searchString.includes(str) %7C%7C codepoint
 .include
@@ -2922,22 +2922,27 @@
 if (
-++count %3E= 256
+reachedMaxResults()
 )%0A%09%09
@@ -2959,24 +2959,57 @@
 %09%09%09%7D%0A%09%09%7D%0A%09%7D%0A
+%09results = deduplicate(results);%0A
 %09return resu

Fix search results