/**
* $Revision $
* $Date $
*
* Copyright (C) 2005-2010 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.community.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.BreakIterator;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.EncoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.net.QuotedPrintableCodec;
import org.jivesoftware.util.*;
public class StringUtils extends org.apache.commons.lang.StringUtils
{
private static final Logger Log = LoggerFactory.getLogger(StringUtils.class);
private static final char QUOTE_ENCODE[] = """.toCharArray();
private static final char AMP_ENCODE[] = "&".toCharArray();
private static final char LT_ENCODE[] = "<".toCharArray();
private static final char GT_ENCODE[] = ">".toCharArray();
private static final char APOS_ENCODE[] = "'".toCharArray();
private static Pattern basicAddressPattern;
private static Pattern validUserPattern;
private static Pattern domainPattern;
private static Pattern ipDomainPattern;
private static Pattern tldPattern;
private static final String EMAIL_DOMAINS = "com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum|mobi";
private static final Pattern WHITESPACE = Pattern.compile("(\\s| )*");
private static final Pattern URL_SAFE = Pattern.compile("([^0-9A-Za-z\\-\\_]+)");
private static final char HEX_ENC_CHARS[] = "abcdefABCDEF012345678".toCharArray();
private static MessageDigest digest = null;
private static final char base[];
private static final int indexes[];
private static final char CA[];
private static final int IA[];
private static final BitSet allowed_query;
private static SecureRandom randGen = new SecureRandom();
private static char numbersAndLetters[] = "0123456789abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
private static final char zeroArray[] = "0000000000000000000000000000000000000000000000000000000000000000".toCharArray();
public static final String OTHER_SAFE_CHARACTERS = "!'\",.?*@`~-+_=/\\:$";
private static char WS_ARRAY[];
private static Map HTML_ENTITY_MAP;
private static final String PLAIN_ASCII = "AaEeIiOoUuAaEeIiOoUuYyAaEeIiOoUuYyAaOoAaEeIiOoUuYyAaCc";
private static final String UNICODE = "\300\340\310\350\314\354\322\362\331\371\301\341\311\351\315\355\323\363\332\372\335\375\302\342\312\352\316\356\324\364\333\373\u0176\u0177\303\343\325\365\304\344\313\353\317\357\326\366\334\374\u0178\377\305\345\307\347";
public static String getValidEmailDomains()
{
return "com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum|mobi";
}
private StringUtils()
{
}
public static String replace(String string, String oldString, String newString)
{
if(string == null)
return null;
if(newString == null)
return string;
int i = 0;
if((i = string.indexOf(oldString, i)) >= 0)
{
char string2[] = string.toCharArray();
char newString2[] = newString.toCharArray();
int oLength = oldString.length();
StringBuffer buf = new StringBuffer(string2.length);
buf.append(string2, 0, i).append(newString2);
i += oLength;
int j;
for(j = i; (i = string.indexOf(oldString, i)) > 0; j = i)
{
buf.append(string2, j, i - j).append(newString2);
i += oLength;
}
buf.append(string2, j, string2.length - j);
return buf.toString();
} else
{
return string;
}
}
public static String replaceIgnoreCase(String line, String oldString, String newString)
{
if(line == null)
return null;
String lcLine = line.toLowerCase();
String lcOldString = oldString.toLowerCase();
int i = 0;
if((i = lcLine.indexOf(lcOldString, i)) >= 0)
{
char line2[] = line.toCharArray();
char newString2[] = newString.toCharArray();
int oLength = oldString.length();
StringBuffer buf = new StringBuffer(line2.length);
buf.append(line2, 0, i).append(newString2);
i += oLength;
int j;
for(j = i; (i = lcLine.indexOf(lcOldString, i)) > 0; j = i)
{
buf.append(line2, j, i - j).append(newString2);
i += oLength;
}
buf.append(line2, j, line2.length - j);
return buf.toString();
} else
{
return line;
}
}
public static String replaceIgnoreCase(String line, String oldString, String newString, int count[])
{
if(line == null)
return null;
String lcLine = line.toLowerCase();
String lcOldString = oldString.toLowerCase();
int i = 0;
if((i = lcLine.indexOf(lcOldString, i)) >= 0)
{
int counter = 1;
char line2[] = line.toCharArray();
char newString2[] = newString.toCharArray();
int oLength = oldString.length();
StringBuffer buf = new StringBuffer(line2.length);
buf.append(line2, 0, i).append(newString2);
i += oLength;
int j;
for(j = i; (i = lcLine.indexOf(lcOldString, i)) > 0; j = i)
{
counter++;
buf.append(line2, j, i - j).append(newString2);
i += oLength;
}
buf.append(line2, j, line2.length - j);
count[0] = counter;
return buf.toString();
} else
{
return line;
}
}
public static String replace(String line, String oldString, String newString, int count[])
{
if(line == null)
return null;
int i = 0;
if((i = line.indexOf(oldString, i)) >= 0)
{
int counter = 1;
char line2[] = line.toCharArray();
char newString2[] = newString.toCharArray();
int oLength = oldString.length();
StringBuffer buf = new StringBuffer(line2.length);
buf.append(line2, 0, i).append(newString2);
i += oLength;
int j;
for(j = i; (i = line.indexOf(oldString, i)) > 0; j = i)
{
counter++;
buf.append(line2, j, i - j).append(newString2);
i += oLength;
}
buf.append(line2, j, line2.length - j);
count[0] = counter;
return buf.toString();
} else
{
return line;
}
}
public static String stripTags(String in)
{
if(in == null)
return null;
else
return stripTags(in, false);
}
public static String stripTags(String in, boolean stripBRTag)
{
if(in == null)
return null;
int i = 0;
int last = 0;
char input[] = in.toCharArray();
int len = input.length;
StringBuffer out = new StringBuffer((int)((double)len * 1.3D));
for(; i < len; i++)
{
char ch = input[i];
if(ch > '>')
continue;
if(ch == '<')
{
if(!stripBRTag && i + 3 < len && input[i + 1] == 'b' && input[i + 2] == 'r' && input[i + 3] == '>')
{
i += 3;
continue;
}
if(i > last)
{
if(last > 0)
out.append(" ");
out.append(input, last, i - last);
}
last = i + 1;
continue;
}
if(ch == '>')
last = i + 1;
}
if(last == 0)
return in;
if(i > last)
out.append(input, last, i - last);
return out.toString();
}
public static String escapeHTMLTags(String in)
{
if(in == null)
return null;
int i = 0;
int last = 0;
char input[] = in.toCharArray();
int len = input.length;
StringBuffer out = new StringBuffer((int)((double)len * 1.3D));
for(; i < len; i++)
{
char ch = input[i];
if(ch > '>')
continue;
if(ch == '<')
{
if(i > last)
out.append(input, last, i - last);
last = i + 1;
out.append(LT_ENCODE);
continue;
}
if(ch == '>')
{
if(i > last)
out.append(input, last, i - last);
last = i + 1;
out.append(GT_ENCODE);
continue;
}
if(ch == '"')
{
if(i > last)
out.append(input, last, i - last);
last = i + 1;
out.append(QUOTE_ENCODE);
continue;
}
if(ch != '&')
continue;
if(i > last)
out.append(input, last, i - last);
last = i + 1;
out.append(AMP_ENCODE);
}
if(last == 0)
return in;
if(i > last)
out.append(input, last, i - last);
return out.toString();
}
public static synchronized String hash(String data)
{
if(digest == null)
try
{
digest = MessageDigest.getInstance("MD5");
}
catch(NoSuchAlgorithmException nsae)
{
Log.error("Failed to load the MD5 MessageDigest. Jive will be unable to function normally.", nsae);
}
try
{
digest.update(data.getBytes("utf-8"));
}
catch(UnsupportedEncodingException e)
{
Log.error(e.toString());
throw new UnsupportedOperationException((new StringBuilder()).append("Error computing hash: ").append(e.getMessage()).toString());
}
return encodeHex(digest.digest());
}
public static synchronized String hash(char data[])
{
return hash(new String(data));
}
public static String encodeHex(byte bytes[])
{
return new String(Hex.encodeHex(bytes));
}
public static byte[] decodeHex(String hex)
{
if(hex == null)
return null;
try
{
return Hex.decodeHex(hex.toCharArray());
}
catch(DecoderException e)
{
Log.error(e.toString());
}
return null;
}
public static String encodeBase64(String data)
{
byte bytes[] = null;
try
{
bytes = data.getBytes("UTF-8");
}
catch(UnsupportedEncodingException uee)
{
Log.error(uee.toString());
}
return encodeBase64(bytes);
}
public static String decodeBase64(String data)
{
try
{
byte decoded[];
byte bytes[] = data.getBytes("UTF-8");
decoded = decodeBase64(bytes);
if(decoded == null)
return "";
return new String(decoded, "UTF-8");
}
catch(Exception uee)
{
Log.error(uee.toString());
}
return "";
}
public static String encodeAlphaNumeric(long toEncode)
{
if(toEncode < 0L)
throw new UnsupportedOperationException("Encoding of negative numbers is not supported");
if(toEncode == 0L)
return "0";
StringBuffer buff = new StringBuffer();
for(; toEncode != 0L; toEncode /= base.length)
buff.append(base[(int)(toEncode % (long)base.length)]);
return buff.reverse().toString();
}
public static long decodeAlphaNumeric(String encoded)
{
if(encoded.equals("0"))
return 0L;
StringBuffer buff = (new StringBuffer(encoded)).reverse();
long result = 0L;
for(int i = 0; i < buff.length(); i++)
{
char current = buff.charAt(i);
long currentVal = indexes[current];
result += currentVal * (long)Math.pow(base.length, i);
}
if(result < 0L)
throw new IllegalArgumentException((new StringBuilder()).append("Input string ").append(encoded).append(" did not decode to a positive long value.").toString());
else
return result;
}
public static String encodeBase64(byte data[])
{
boolean lineSep = false;
int sLen = data == null ? 0 : data.length;
if(sLen == 0)
return "";
int eLen = (sLen / 3) * 3;
int cCnt = (sLen - 1) / 3 + 1 << 2;
int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0);
char dArr[] = new char[dLen];
int s = 0;
int d = 0;
int cc = 0;
do
{
if(s >= eLen)
break;
int i = (data[s++] & 0xff) << 16 | (data[s++] & 0xff) << 8 | data[s++] & 0xff;
dArr[d++] = CA[i >>> 18 & 0x3f];
dArr[d++] = CA[i >>> 12 & 0x3f];
dArr[d++] = CA[i >>> 6 & 0x3f];
dArr[d++] = CA[i & 0x3f];
if(lineSep && ++cc == 19 && d < dLen - 2)
{
dArr[d++] = '\r';
dArr[d++] = '\n';
cc = 0;
}
} while(true);
int left = sLen - eLen;
if(left > 0)
{
int i = (data[eLen] & 0xff) << 10 | (left != 2 ? 0 : (data[sLen - 1] & 0xff) << 2);
dArr[dLen - 4] = CA[i >> 12];
dArr[dLen - 3] = CA[i >>> 6 & 0x3f];
dArr[dLen - 2] = left != 2 ? '=' : CA[i & 0x3f];
dArr[dLen - 1] = '=';
}
return new String(dArr);
}
public static byte[] decodeBase64(byte bytes[])
{
int sLen = bytes.length;
int sepCnt = 0;
for(int i = 0; i < sLen; i++)
if(IA[bytes[i] & 0xff] < 0)
sepCnt++;
if((sLen - sepCnt) % 4 != 0)
return null;
int pad = 0;
int i = sLen;
do
{
if(i <= 1 || IA[bytes[--i] & 0xff] > 0)
break;
if(bytes[i] == 61)
pad++;
} while(true);
int len = ((sLen - sepCnt) * 6 >> 3) - pad;
byte dArr[] = new byte[len];
int s = 0;
int d = 0;
do
{
if(d >= len)
break;
i = 0;
for(int j = 0; j < 4; j++)
{
int c = IA[bytes[s++] & 0xff];
if(c >= 0)
i |= c << 18 - j * 6;
else
j--;
}
dArr[d++] = (byte)(i >> 16);
if(d < len)
{
dArr[d++] = (byte)(i >> 8);
if(d < len)
dArr[d++] = (byte)i;
}
} while(true);
return dArr;
}
public static String URLEncode(String original, String charset)
throws UnsupportedEncodingException
{
if(original == null)
return null;
byte octets[];
try
{
octets = original.getBytes(charset);
}
catch(UnsupportedEncodingException error)
{
throw new UnsupportedEncodingException();
}
StringBuffer buf = new StringBuffer(octets.length);
byte arr$[] = octets;
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; i$++)
{
byte octet = arr$[i$];
char c = (char)octet;
if(allowed_query.get(c))
{
buf.append(c);
} else
{
buf.append('%');
char hexadecimal = Character.forDigit(octet >> 4 & 0xf, 16);
buf.append(Character.toUpperCase(hexadecimal));
hexadecimal = Character.forDigit(octet & 0xf, 16);
buf.append(Character.toUpperCase(hexadecimal));
}
}
return buf.toString();
}
public static String URLEncode(String string)
{
try
{
return URLEncoder.encode(string, "UTF-8");
}
catch(UnsupportedEncodingException uee)
{
Log.warn("URL encoding failed." + uee);
}
return string;
}
public static String[] toLowerCaseWordArray(String text)
{
if(text == null || text.length() == 0)
return new String[0];
ArrayList wordList = new ArrayList();
BreakIterator boundary = BreakIterator.getWordInstance();
boundary.setText(text);
int start = 0;
for(int end = boundary.next(); end != -1; end = boundary.next())
{
String tmp = text.substring(start, end).trim();
tmp = replace(tmp, "+", "");
tmp = replace(tmp, "/", "");
tmp = replace(tmp, "\\", "");
tmp = replace(tmp, "#", "");
tmp = replace(tmp, "*", "");
tmp = replace(tmp, ")", "");
tmp = replace(tmp, "(", "");
tmp = replace(tmp, "&", "");
if(tmp.length() > 0)
wordList.add(tmp);
start = end;
}
return (String[])wordList.toArray(new String[wordList.size()]);
}
public static String randomString(int length)
{
if(length < 1)
return null;
char randBuffer[] = new char[length];
for(int i = 0; i < randBuffer.length; i++)
randBuffer[i] = numbersAndLetters[randGen.nextInt(71)];
return new String(randBuffer);
}
public static String chop(String string, int length)
{
if(string == null)
return null;
if(length <= 0)
throw new IllegalArgumentException("Length must be > 0");
if(string.length() <= length + 2)
{
return string;
} else
{
StringBuffer buf = new StringBuffer(string.substring(0, length));
buf.append("...");
return buf.toString();
}
}
public static String chopAtWord(String string, int length, int minLength)
{
if(length < 2)
throw new IllegalArgumentException((new StringBuilder()).append("Length specified (").append(length).append(") must be > 2").toString());
if(minLength >= length)
throw new IllegalArgumentException("minLength must be smaller than length");
int sLength = string != null ? string.length() : -1;
if(sLength < 1)
return string;
if(minLength != -1 && sLength < minLength)
return string;
if(minLength == -1 && sLength < length)
return string;
char charArray[] = string.toCharArray();
if(sLength > length)
{
sLength = length;
for(int i = 0; i < sLength - 1; i++)
{
if(charArray[i] == '\r' && charArray[i + 1] == '\n')
return string.substring(0, i + 1);
if(charArray[i] == '\n')
return string.substring(0, i);
}
if(charArray[sLength - 1] == '\n')
return string.substring(0, sLength - 1);
for(int i = sLength - 1; i > 0; i--)
if(charArray[i] == ' ')
return string.substring(0, i).trim();
} else
if(minLength != -1 && sLength > minLength)
{
for(int i = 0; i < minLength; i++)
if(charArray[i] == ' ')
return string;
}
if(minLength > -1 && minLength <= string.length())
return string.substring(0, minLength);
else
return string.substring(0, length);
}
public static String chopAtWord(String string, int length)
{
return chopAtWord(string, length, -1);
}
public static String chopAtWordsAround(String input, String wordList[], int numChars)
{
if(input == null || "".equals(input.trim()) || wordList == null || wordList.length == 0 || numChars == 0)
return "";
String lc = input.toLowerCase();
String arr$[] = wordList;
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; i$++)
{
String aWordList = arr$[i$];
int pos = lc.indexOf(aWordList);
if(pos > -1)
{
int beginIdx = pos - numChars;
if(beginIdx < 0)
beginIdx = 0;
int endIdx = pos + numChars;
if(endIdx > input.length() - 1)
endIdx = input.length() - 1;
char chars[];
for(chars = input.toCharArray(); beginIdx > 0 && chars[beginIdx] != ' ' && chars[beginIdx] != '\n' && chars[beginIdx] != '\r'; beginIdx--);
for(; endIdx < input.length() && chars[endIdx] != ' ' && chars[endIdx] != '\n' && chars[endIdx] != '\r'; endIdx++);
return input.substring(beginIdx, endIdx);
}
}
return input.substring(0, input.length() < 200 ? input.length() : 200);
}
public static String wordWrap(String input, int width, Locale locale)
{
if(input == null)
return "";
if(width < 5)
return input;
if(width >= input.length())
return input;
if(locale == null)
locale = JiveGlobals.getLocale();
StringBuffer buf = new StringBuffer(input);
boolean endOfLine = false;
int lineStart = 0;
for(int i = 0; i < buf.length(); i++)
{
if(buf.charAt(i) == '\n')
{
lineStart = i + 1;
endOfLine = true;
}
if(i <= (lineStart + width) - 1)
continue;
if(!endOfLine)
{
int limit = i - lineStart - 1;
BreakIterator breaks = BreakIterator.getLineInstance(locale);
breaks.setText(buf.substring(lineStart, i));
int end = breaks.last();
if(end == limit + 1 && !Character.isWhitespace(buf.charAt(lineStart + end)))
end = breaks.preceding(end - 1);
if(end != -1 && end == limit + 1)
{
buf.replace(lineStart + end, lineStart + end + 1, "\n");
lineStart += end;
continue;
}
if(end != -1 && end != 0)
{
buf.insert(lineStart + end, '\n');
lineStart = lineStart + end + 1;
} else
{
buf.insert(i, '\n');
lineStart = i + 1;
}
} else
{
buf.insert(i, '\n');
lineStart = i + 1;
endOfLine = false;
}
}
return buf.toString();
}
public static String highlightWords(String string, String words[], String startHighlight, String endHighlight)
{
if(string == null || words == null || startHighlight == null || endHighlight == null)
return null;
StringBuffer regexp = new StringBuffer();
regexp.append("(?i)\\b(");
for(int x = 0; x < words.length; x++)
{
words[x] = words[x].replaceAll("([\\$\\?\\|\\/\\.\\}\\{])", "\\\\$1");
regexp.append(words[x]);
if(x != words.length - 1)
regexp.append("|");
}
regexp.append(")");
return string.replaceAll(regexp.toString(), (new StringBuilder()).append(startHighlight).append("$1").append(endHighlight).toString());
}
public static String escapeForSQL(String string)
{
if(string == null)
return null;
if(string.length() == 0)
return string;
char input[] = string.toCharArray();
int i = 0;
int last = 0;
int len = input.length;
StringBuffer out = null;
for(; i < len; i++)
{
char ch = input[i];
if(ch != '\'')
continue;
if(out == null)
out = new StringBuffer(len + 2);
if(i > last)
out.append(input, last, i - last);
last = i + 1;
out.append('\'').append('\'');
}
if(out == null)
return string;
if(i > last)
out.append(input, last, i - last);
return out.toString();
}
public static String escapeForXML(String string)
{
if(string == null)
return null;
int i = 0;
int last = 0;
char input[] = string.toCharArray();
int len = input.length;
StringBuffer out = new StringBuffer((int)((double)len * 1.3D));
for(; i < len; i++)
{
char ch = input[i];
if(ch > '>')
continue;
if(ch == '<')
{
if(i > last)
out.append(input, last, i - last);
last = i + 1;
out.append(LT_ENCODE);
continue;
}
if(ch == '>')
{
if(i > last)
out.append(input, last, i - last);
last = i + 1;
out.append(GT_ENCODE);
continue;
}
if(ch == '&')
{
if(i > last)
out.append(input, last, i - last);
last = i + 1;
out.append(AMP_ENCODE);
continue;
}
if(ch == '"')
{
if(i > last)
out.append(input, last, i - last);
last = i + 1;
out.append(QUOTE_ENCODE);
continue;
}
if(ch == '\n' || ch == '\r' || ch == '\t' || ch >= ' ')
continue;
if(i > last)
out.append(input, last, i - last);
last = i + 1;
}
if(last == 0)
return string;
if(i > last)
out.append(input, last, i - last);
return out.toString();
}
public static String escapeEntitiesInXmlString(String xmlString)
{
xmlString = xmlString.replaceAll("&", String.valueOf(AMP_ENCODE));
return xmlString;
}
public static String unescapeFromXML(String string)
{
string = replace(string, "<", "<");
string = replace(string, ">", ">");
string = replace(string, """, "\"");
return replace(string, "&", "&");
}
public static String zeroPadString(String string, int length)
{
if(string == null || string.length() > length)
{
return string;
} else
{
StringBuffer buf = new StringBuffer(length);
buf.append(zeroArray, 0, length - string.length()).append(string);
return buf.toString();
}
}
public static String dateToMillis(Date date)
{
return Long.toString(date.getTime());
}
public static boolean isValidEmailAddress(String addr)
{
if(addr == null)
return false;
addr = addr.trim();
if(addr.length() == 0)
return false;
Matcher matcher = basicAddressPattern.matcher(addr);
if(!matcher.matches())
return false;
String userPart = matcher.group(1);
String domainPart = matcher.group(2);
matcher = validUserPattern.matcher(userPart);
if(!matcher.matches())
return false;
matcher = ipDomainPattern.matcher(domainPart);
if(matcher.matches())
{
for(int i = 1; i < 5; i++)
{
String num = matcher.group(i);
if(num == null)
return false;
if(Integer.parseInt(num) > 254)
return false;
}
return true;
}
matcher = domainPattern.matcher(domainPart);
if(matcher.matches())
{
String tld = matcher.group(matcher.groupCount());
matcher = tldPattern.matcher(tld);
return tld.length() == 3 || matcher.matches();
} else
{
return "localhost".equals(domainPart);
}
}
public static String removeIgnorableCharacters(String input)
{
if(input == null)
return input;
StringBuffer buf = new StringBuffer();
char chars[] = input.toCharArray();
int i = 0;
for(int n = input.length(); i < n; i++)
if(!Character.isIdentifierIgnorable(chars[i]))
buf.append(chars[i]);
return buf.toString();
}
public static String getSpacer(String spacer, int num)
{
if(num <= 1)
return spacer;
if(spacer == null || "".equals(spacer))
return spacer;
StringBuffer buf = new StringBuffer(spacer.length() * num);
for(int i = 0; i < num; i++)
buf.append(spacer);
return buf.toString();
}
public static String abbreviate(String str, int maxWidth)
{
if(null == str)
return null;
if(str.length() <= maxWidth)
return str;
else
return (new StringBuilder()).append(chopAtWord(str, maxWidth)).append("...").toString();
}
/**
* @deprecated Method getTimeFromLong is deprecated
*/
public static String getTimeFromLong(long time)
{
return getTimeFromLong(time, 2);
}
/**
* @deprecated Method getTimeFromLong is deprecated
*/
public static String getTimeFromLong(long time, int limit)
{
return (new DateUtils()).displayFriendly(time, limit);
}
public static boolean containsNonAlphanumeric(String str)
{
char testChars[] = str.toCharArray();
char arr$[] = testChars;
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; i$++)
{
char testChar = arr$[i$];
if(!Character.isLetterOrDigit(testChar))
return true;
}
return false;
}
public static String stripWhitespace(String str)
{
if(str == null)
return null;
Matcher matcher = WHITESPACE.matcher(str);
StringBuffer buffer = new StringBuffer();
for(; matcher.find(); matcher.appendReplacement(buffer, ""));
matcher.appendTail(buffer);
return buffer.toString();
}
public static boolean areEqualIgnoreCase(String s1, String s2)
{
if(s1 == null && s2 == null)
return true;
if(s1 != null)
{
s1 = s1.toLowerCase();
return s2 != null && s1.equals(s2.toLowerCase());
} else
{
return false;
}
}
public static InputStream asStream(String data)
{
return new ByteArrayInputStream(data.getBytes());
}
public static String removeTag(String s, String html)
{
return removeTag(s, new StringBuilder(html)).toString();
}
private static StringBuilder removeSimpleTag(StringBuilder body, String tag)
{
return replaceAll(body, (new StringBuilder()).append("<").append(tag).append(" />").toString(), "");
}
public static StringBuilder removeTag(String s, StringBuilder html)
{
String tagBegin = (new StringBuilder()).append("<").append(s).append(" ").toString();
String tagEnd = (new StringBuilder()).append("</").append(s).append(">").toString();
int start = html.indexOf(tagBegin);
do
{
if(start == -1)
break;
int end = html.indexOf(tagEnd, start + 1);
if(end != -1)
{
html.replace(start, end, "");
start = html.indexOf(tagBegin);
}
} while(true);
return html;
}
public static StringBuilder removeTags(StringBuilder html, String tags[])
{
String arr$[] = tags;
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; i$++)
{
String tag = arr$[i$];
removeSimpleTag(html, tag);
removeTag(tag, html);
}
return html;
}
private static String removeSimpleTag(String body, String tag)
{
String htmlTag = (new StringBuilder()).append("<").append(tag).append(" />").toString();
return body.replace(htmlTag, "");
}
public static List occurs(String token, String s)
{
List locations = new ArrayList();
int i = 0;
do
{
if(i == -1)
break;
i = s.indexOf(token, i);
if(i != -1)
{
locations.add(Integer.valueOf(i));
i += token.length();
}
} while(true);
return locations;
}
public static String upperCaseFirstChar(String s)
{
String first = String.valueOf(s.charAt(0));
first = first.toUpperCase();
StringBuilder builder = new StringBuilder();
builder.append(first);
builder.append(s.substring(1));
return builder.toString();
}
public static boolean isWebSafeString(String str)
{
return isWebSafeString(str, "!'\",.?*@`~-+_=/\\:$");
}
public static boolean isWebSafeString(String str, String otherSafeCharacters)
{
if(str == null)
throw new NullPointerException("String to be tested cannot be null");
int sz = str.length();
for(int i = 0; i < sz; i++)
{
char iChar = str.charAt(i);
if(Character.isLetterOrDigit(iChar) || Character.isSpaceChar(iChar))
continue;
boolean found = false;
int j = 0;
do
{
if(j >= otherSafeCharacters.length())
break;
char other = otherSafeCharacters.charAt(j);
if(other == iChar)
{
found = true;
break;
}
j++;
} while(true);
if(!found)
return false;
}
return true;
}
public static String asString(List list)
{
if(list == null || list.isEmpty())
return "";
StringBuilder builder = new StringBuilder();
for(Iterator i$ = list.iterator(); i$.hasNext(); builder.append(","))
{
long a = ((Long)i$.next()).longValue();
builder.append(a);
}
if(builder.charAt(builder.length() - 1) == ',')
builder.deleteCharAt(builder.length() - 1);
return builder.toString();
}
public static List asList(String string)
{
if(string == null || "".equals(string))
return new ArrayList();
String tokens[] = string.split(",");
ArrayList list = new ArrayList();
String arr$[] = tokens;
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; i$++)
{
String t = arr$[i$];
try
{
long value = Long.parseLong(t);
list.add(Long.valueOf(value));
}
catch(NumberFormatException e) { }
}
return list;
}
public static String lowerFirstChar(String name)
{
String result = name;
if(name != null && name.length() > 1)
result = (new StringBuilder()).append(name.substring(0, 1).toLowerCase()).append(name.substring(1, name.length())).toString();
return result;
}
public static boolean isEqualToAnyOf(String s, String values[])
{
String arr$[] = values;
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; i$++)
{
String value = arr$[i$];
if(s.equals(value))
return true;
}
return false;
}
public static boolean isEqualToAnyOf(char c, char values[])
{
char arr$[] = values;
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; i$++)
{
char value = arr$[i$];
if(c == value)
return true;
}
return false;
}
public static boolean isEqualToAnyOfIgnoreCase(String s, String values[])
{
s = s.toLowerCase();
String arr$[] = values;
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; i$++)
{
String value = arr$[i$];
if(s.equals(value.toLowerCase()))
return true;
}
return false;
}
public static String replaceAll(String text, String token, String repl)
{
return replaceAll(new StringBuilder(text), token, repl).toString();
}
public static String join(List elements, String joinWith)
{
if(elements == null || elements.size() == 0)
return null;
StringBuilder buffer = new StringBuilder(56);
for(Iterator i$ = elements.iterator(); i$.hasNext(); buffer.append(joinWith))
{
String str = (String)i$.next();
buffer.append(str);
}
return buffer.toString();
}
public static String join(String elements[], String joinWith)
{
if(elements == null || elements.length == 0)
return null;
StringBuilder buffer = new StringBuilder(56);
String arr$[] = elements;
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; i$++)
{
String str = arr$[i$];
buffer.append(str);
buffer.append(joinWith);
}
return buffer.toString();
}
public static StringBuilder replaceAll(StringBuilder text, String token, String repl)
{
int tokSize = token.length();
int i = 0;
do
{
if(i == -1)
break;
i = text.indexOf(token, i);
if(i != -1)
{
text.replace(i, i + tokSize, repl);
i += repl.length();
}
} while(true);
return text;
}
public static String replaceAllKeys(String text, Map store)
{
StringBuilder stb = new StringBuilder(text);
return replaceAllKeys(stb, store).toString();
}
public static StringBuilder replaceAllKeys(StringBuilder stb, Map store)
{
List uuids = new ArrayList(store.keySet());
int loopCount = 0;
label0:
for(int maxLoops = uuids.size(); uuids.size() > 0 && loopCount < maxLoops; loopCount++)
{
Iterator i$ = store.keySet().iterator();
do
{
if(!i$.hasNext())
continue label0;
String uuid = (String)i$.next();
String value = (String)store.get(uuid);
int idx = stb.indexOf(uuid);
if(idx != -1)
{
stb.replace(idx, idx + uuid.length(), value);
uuids.remove(uuid);
}
} while(true);
}
return stb;
}
public static String replaceHtmlEntitiesWithValueOpt(String stb)
{
int size = stb.length();
StringReplacementHolder holder = new StringReplacementHolder(stb);
int start = -1;
for(int i = 0; i < size; i++)
{
if(start == -1 && stb.charAt(i) == '&')
{
start = i;
continue;
}
if(isEqualToAnyOf(stb.charAt(i), new char[] {
' ', '\r', '\n'
}))
{
start = -1;
continue;
}
if(start == -1 || stb.charAt(i) != ';')
continue;
String key = stb.substring(start, i + 1);
if(HTML_ENTITY_MAP.containsKey(key))
holder.addReplacement(start, i + 1, (String)HTML_ENTITY_MAP.get(key));
start = -1;
}
return holder.apply();
}
public static String replaceHtmlEntitiesWithEmptyString(String stb)
{
Iterator i$ = HTML_ENTITY_MAP.keySet().iterator();
do
{
if(!i$.hasNext())
break;
String key = (String)i$.next();
if(stb.contains(key))
stb = stb.replaceAll(key, "");
} while(true);
i$ = HTML_ENTITY_MAP.values().iterator();
do
{
if(!i$.hasNext())
break;
String value = (String)i$.next();
if(stb.contains(value))
stb = stb.replaceAll(value, "");
} while(true);
return stb;
}
public static String getSpacer(char spacer, int num)
{
if(spacer == ' ' && num < WS_ARRAY.length)
return new String(WS_ARRAY, 0, num);
char space[] = new char[num];
for(int i = 0; i < space.length; i++)
space[i] = spacer;
return new String(space);
}
public static boolean startsWithAnyOf(String s, String values[])
{
return startsWithAnyOf(s, ((Collection) (Arrays.asList(values))));
}
public static boolean startsWithAnyOf(String s, Collection values)
{
if(s == null)
return false;
for(Iterator i$ = values.iterator(); i$.hasNext();)
{
String value = (String)i$.next();
if(s.startsWith(value))
return true;
}
return false;
}
public static Map createMap(Object keys[], Object values[])
{
Map map = new HashMap();
if(keys.length != values.length)
return map;
for(int i = 0; i < keys.length; i++)
map.put(keys[i], values[i]);
return map;
}
public static boolean endsWithAnyOf(String s, String values[])
{
return endsWithAnyOf(s, ((Collection) (Arrays.asList(values))));
}
public static boolean endsWithAnyOf(String s, Collection values)
{
if(s == null)
return false;
for(Iterator i$ = values.iterator(); i$.hasNext();)
{
String value = (String)i$.next();
if(s.endsWith(value))
return true;
}
return false;
}
public static boolean containsAnyOf(String s, String values[])
{
return containsAnyOf(s, ((Collection) (Arrays.asList(values))));
}
public static boolean containsAnyOf(String s, Collection values)
{
if(s == null)
return false;
for(Iterator i$ = values.iterator(); i$.hasNext();)
{
String value = (String)i$.next();
if(s.contains(value))
return true;
}
return false;
}
public static String URLDecode(String original, String charset)
{
original = original.replace('+', ' ');
int idx = original.indexOf('%');
if(idx != -1 && idx <= original.length() - 3 && isEqualToAnyOf(original.charAt(idx + 1), HEX_ENC_CHARS) && isEqualToAnyOf(original.charAt(idx + 2), HEX_ENC_CHARS))
try
{
String decoded = URLDecoder.decode(original, charset);
return decoded.replace('+', ' ');
}
catch(Exception e)
{
e.printStackTrace();
}
return original.replace('+', ' ');
}
public static String getShortDateFormat(Date date, Locale locale)
{
if(date == null)
return "";
DateFormat shortDateFormat;
if(locale != null)
shortDateFormat = DateFormat.getDateInstance(3, locale);
else
shortDateFormat = DateFormat.getDateInstance(3);
return shortDateFormat.format(date);
}
public static String setURLParameter(String url, String paramName, String paramValue)
{
Map urlParameters = new LinkedHashMap();
StringTokenizer queryStringTokenizer = new StringTokenizer(url, "?");
String baseURL = queryStringTokenizer.nextToken();
boolean isNewParameter = true;
if(queryStringTokenizer.hasMoreTokens())
{
String strQueryString = queryStringTokenizer.nextToken();
if(strQueryString != null)
{
for(StringTokenizer tokenizerNameValuePair = new StringTokenizer(strQueryString, "&"); tokenizerNameValuePair.hasMoreTokens();)
try
{
String strNameValuePair = tokenizerNameValuePair.nextToken();
StringTokenizer tokenizerValue = new StringTokenizer(strNameValuePair, "=");
String pName = tokenizerValue.nextToken();
String pValue = tokenizerValue.nextToken();
if(paramName.equals(pName))
{
pValue = paramValue;
isNewParameter = false;
}
urlParameters.put(pName, pValue);
}
catch(Throwable t) { }
}
}
StringBuilder urlBuilder = (new StringBuilder(baseURL)).append("?");
Iterator params = urlParameters.keySet().iterator();
do
{
if(!params.hasNext())
break;
String pName = (String)params.next();
String pValue = (String)urlParameters.get(pName);
urlBuilder.append(pName).append("=").append(pValue);
if(params.hasNext())
urlBuilder.append("&");
} while(true);
if(isNewParameter)
urlBuilder.append("&").append(paramName).append("=").append(paramValue);
return urlBuilder.toString();
}
public static boolean isASCIIURLSafe(String str)
{
return str != null && !"".equals(str.trim()) && !URL_SAFE.matcher(str).find();
}
public static String makeURLSafe(String str)
{
return makeURLSafe(str, '-');
}
public static String makeURLSafe(String str, char replacement)
{
if(str == null || !isASCIIURLSafe(String.valueOf(replacement)))
return null;
String trimmed = str.trim();
boolean ascii = str.trim().replaceAll((new StringBuilder()).append("([\\p{Punct}&&[^\\").append(replacement).append("]]+)").toString(), "").replaceAll((new StringBuilder()).append("([^A-Za-z\\").append(replacement).append("]+)").toString(), String.valueOf(replacement)).toLowerCase().replaceAll((new StringBuilder()).append("").append(replacement).toString(), "").replaceAll(" ", "").length() > 0;
if(ascii)
{
trimmed = trimmed.replaceAll((new StringBuilder()).append("([\\p{Punct}&&[^\\").append(replacement).append("]]+)").toString(), "").replaceAll((new StringBuilder()).append("([^0-9A-Za-z\\").append(replacement).append("]+)").toString(), String.valueOf(replacement)).toLowerCase();
if(trimmed.length() > 1 && (replacement == trimmed.charAt(0) || replacement == trimmed.charAt(trimmed.length() - 1)))
{
StringBuffer buf = new StringBuffer(trimmed);
if(replacement == buf.charAt(0))
buf.deleteCharAt(0);
if(replacement == buf.charAt(buf.length() - 1))
buf.deleteCharAt(buf.length() - 1);
trimmed = buf.toString();
}
} else
{
boolean hasLetters = str.trim().replaceAll((new StringBuilder()).append("([\\p{Punct}&&[^\\").append(replacement).append("]]+)").toString(), "").replaceAll((new StringBuilder()).append("([^\\p{L}\\p{Nd}\\").append(replacement).append("]+)").toString(), String.valueOf(replacement)).replaceAll((new StringBuilder()).append("").append(replacement).toString(), "").replaceAll(" ", "").length() > 0;
if(hasLetters)
{
trimmed = str.trim();
boolean cantLowercase = trimmed.replaceAll((new StringBuilder()).append("([\\p{Punct}&&[^\\").append(replacement).append("]]+)").toString(), "").replaceAll((new StringBuilder()).append("([^\\p{Lo}\\").append(replacement).append("]+)").toString(), String.valueOf(replacement)).replaceAll((new StringBuilder()).append("").append(replacement).toString(), "").replaceAll(" ", "").length() > 0;
trimmed = trimmed.replaceAll((new StringBuilder()).append("([\\p{Punct}&&[^\\").append(replacement).append("]]+)").toString(), "").replaceAll((new StringBuilder()).append("([^\\p{L}\\p{Nd}\\").append(replacement).append("]+)").toString(), String.valueOf(replacement));
if(!cantLowercase)
trimmed = trimmed.toLowerCase();
} else
{
trimmed = trimmed.toLowerCase();
}
}
return "".equals(trimmed) || "-".equals(trimmed) ? String.valueOf(Math.abs(str.hashCode())) : trimmed;
}
public static String encodeVCard(String toEncode)
{
return encodeVCard(toEncode, false);
}
public static String encodeVCard(String toEncode, boolean isQuotedPrintable)
{
if(toEncode == null)
return toEncode;
String quotedPrintable = toEncode.replace(";", "\\;");
if(isQuotedPrintable)
{
QuotedPrintableCodec codec = new QuotedPrintableCodec();
try
{
quotedPrintable = codec.encode(quotedPrintable);
}
catch(EncoderException e)
{
throw new RuntimeException("Error encoding vcard", e);
}
}
return quotedPrintable;
}
public static char[] clearOutofRangeXmlChars(String text)
{
char chars[] = text.toCharArray();
for(int i = 0; i < chars.length; i++)
if(chars[i] != '\t' && chars[i] != '\n' && chars[i] != '\r' && (chars[i] < ' ' || chars[i] > '\uD7FF') && (chars[i] < '\uE000' || chars[i] > '\uFFFD') && (chars[i] < '\0' || chars[i] > '\0'))
chars[i] = ' ';
return chars;
}
public static String[] slice(String source[], int start, int end)
{
if(source == null)
return null;
if(start == end)
return new String[0];
int e = Math.max(start, end);
e = Math.min(e, source.length);
int s = Math.min(start, end);
String newArray[] = new String[e - s];
int i = 0;
for(; s < e; s++)
newArray[i++] = source[s];
return newArray;
}
public static String[] slice(String source[], int start)
{
if(source == null)
return null;
else
return slice(source, start, source.length);
}
public static boolean isNullOrEmpty(String test)
{
return test == null || test.equals("");
}
public static String convertNonAscii(String s)
{
if(s == null)
return null;
StringBuffer sb = new StringBuffer();
int n = s.length();
for(int i = 0; i < n; i++)
{
char c = s.charAt(i);
int pos = "\300\340\310\350\314\354\322\362\331\371\301\341\311\351\315\355\323\363\332\372\335\375\302\342\312\352\316\356\324\364\333\373\u0176\u0177\303\343\325\365\304\344\313\353\317\357\326\366\334\374\u0178\377\305\345\307\347".indexOf(c);
if(pos > -1)
sb.append("AaEeIiOoUuAaEeIiOoUuYyAaEeIiOoUuYyAaOoAaEeIiOoUuYyAaCc".charAt(pos));
else
sb.append(c);
}
return sb.toString();
}
public static boolean isRegex(String s)
{
return s.indexOf('*') != -1 || s.indexOf('\\') != -1 || s.indexOf('^') != -1 || s.indexOf('.') != -1 || s.indexOf('$') != -1 || s.indexOf('[') != -1 && s.indexOf(']') != -1 || s.indexOf('{') != -1 && s.indexOf('}') != -1;
}
static
{
String basicAddress = "^([\\w\\.-]+)@([\\w\\.-]+)$";
String specialChars = "\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
String validChars = (new StringBuilder()).append("[^ \f\n\r\t").append(specialChars).append("]").toString();
String atom = (new StringBuilder()).append(validChars).append("+").toString();
String quotedUser = "(\"[^\"]+\")";
String word = (new StringBuilder()).append("(").append(atom).append("|").append(quotedUser).append(")").toString();
String validUser = (new StringBuilder()).append("^").append(word).append("(\\.").append(word).append(")*$").toString();
String domain = (new StringBuilder()).append("^").append(atom).append("(\\.").append(atom).append(")+$").toString();
String ipDomain = "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$";
String knownTLDs = "^\\.(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum|mobi)$";
basicAddressPattern = Pattern.compile(basicAddress, 2);
validUserPattern = Pattern.compile(validUser, 2);
domainPattern = Pattern.compile(domain, 2);
ipDomainPattern = Pattern.compile(ipDomain, 2);
tldPattern = Pattern.compile(knownTLDs, 2);
base = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
indexes = new int[256];
Arrays.fill(indexes, -1);
int i = 0;
for(int iS = base.length; i < iS; i++)
indexes[base[i]] = i;
CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
IA = new int[256];
Arrays.fill(IA, -1);
i = 0;
for(int iS = CA.length; i < iS; i++)
IA[CA[i]] = i;
IA[61] = 0;
allowed_query = new BitSet(256);
for(i = 48; i <= 57; i++)
allowed_query.set(i);
for(i = 97; i <= 122; i++)
allowed_query.set(i);
for(i = 65; i <= 90; i++)
allowed_query.set(i);
allowed_query.set(45);
allowed_query.set(95);
allowed_query.set(46);
allowed_query.set(33);
allowed_query.set(126);
allowed_query.set(42);
allowed_query.set(39);
allowed_query.set(40);
allowed_query.set(41);
WS_ARRAY = new char[256];
for(i = 0; i < WS_ARRAY.length; i++)
WS_ARRAY[i] = ' ';
HTML_ENTITY_MAP = new HashMap();
HTML_ENTITY_MAP.put(" ", "\240");
HTML_ENTITY_MAP.put(" ", "\240");
HTML_ENTITY_MAP.put("¡", "\241");
HTML_ENTITY_MAP.put("¡", "\241");
HTML_ENTITY_MAP.put("¢", "\242");
HTML_ENTITY_MAP.put("¢", "\242");
HTML_ENTITY_MAP.put("£", "\243");
HTML_ENTITY_MAP.put("£", "\243");
HTML_ENTITY_MAP.put("¤", "\244");
HTML_ENTITY_MAP.put("¤", "\244");
HTML_ENTITY_MAP.put("¥", "\245");
HTML_ENTITY_MAP.put("¥", "\245");
HTML_ENTITY_MAP.put("¦", "\246");
HTML_ENTITY_MAP.put("¦", "\246");
HTML_ENTITY_MAP.put("§", "\247");
HTML_ENTITY_MAP.put("§", "\247");
HTML_ENTITY_MAP.put("¨", "\250");
HTML_ENTITY_MAP.put("¨", "\250");
HTML_ENTITY_MAP.put("©", "\251");
HTML_ENTITY_MAP.put("©", "\251");
HTML_ENTITY_MAP.put("ª", "\252");
HTML_ENTITY_MAP.put("ª", "\252");
HTML_ENTITY_MAP.put("«", "\253");
HTML_ENTITY_MAP.put("«", "\253");
HTML_ENTITY_MAP.put("¬", "\254");
HTML_ENTITY_MAP.put("¬", "\254");
HTML_ENTITY_MAP.put("", "\255");
HTML_ENTITY_MAP.put("", "\255");
HTML_ENTITY_MAP.put("®", "\256");
HTML_ENTITY_MAP.put("®", "\256");
HTML_ENTITY_MAP.put("¯", "\257");
HTML_ENTITY_MAP.put("¯", "\257");
HTML_ENTITY_MAP.put("°", "\260");
HTML_ENTITY_MAP.put("°", "\260");
HTML_ENTITY_MAP.put("±", "\261");
HTML_ENTITY_MAP.put("±", "\261");
HTML_ENTITY_MAP.put("²", "\262");
HTML_ENTITY_MAP.put("²", "\262");
HTML_ENTITY_MAP.put("³", "\263");
HTML_ENTITY_MAP.put("³", "\263");
HTML_ENTITY_MAP.put("´", "\264");
HTML_ENTITY_MAP.put("´", "\264");
HTML_ENTITY_MAP.put("µ", "\265");
HTML_ENTITY_MAP.put("µ", "\265");
HTML_ENTITY_MAP.put("¶", "\266");
HTML_ENTITY_MAP.put("¶", "\266");
HTML_ENTITY_MAP.put("·", "\267");
HTML_ENTITY_MAP.put("·", "\267");
HTML_ENTITY_MAP.put("¸", "\270");
HTML_ENTITY_MAP.put("¸", "\270");
HTML_ENTITY_MAP.put("¹", "\271");
HTML_ENTITY_MAP.put("¹", "\271");
HTML_ENTITY_MAP.put("º", "\272");
HTML_ENTITY_MAP.put("º", "\272");
HTML_ENTITY_MAP.put("»", "\273");
HTML_ENTITY_MAP.put("»", "\273");
HTML_ENTITY_MAP.put("¼", "\274");
HTML_ENTITY_MAP.put("¼", "\274");
HTML_ENTITY_MAP.put("½", "\275");
HTML_ENTITY_MAP.put("½", "\275");
HTML_ENTITY_MAP.put("¾", "\276");
HTML_ENTITY_MAP.put("¾", "\276");
HTML_ENTITY_MAP.put("¿", "\277");
HTML_ENTITY_MAP.put("¿", "\277");
HTML_ENTITY_MAP.put("À", "\300");
HTML_ENTITY_MAP.put("À", "\300");
HTML_ENTITY_MAP.put("Á", "\301");
HTML_ENTITY_MAP.put("Á", "\301");
HTML_ENTITY_MAP.put("Â", "\302");
HTML_ENTITY_MAP.put("Â", "\302");
HTML_ENTITY_MAP.put("Ã", "\303");
HTML_ENTITY_MAP.put("Ã", "\303");
HTML_ENTITY_MAP.put("Ä", "\304");
HTML_ENTITY_MAP.put("Ä", "\304");
HTML_ENTITY_MAP.put("Å", "\305");
HTML_ENTITY_MAP.put("Å", "\305");
HTML_ENTITY_MAP.put("Æ", "\306");
HTML_ENTITY_MAP.put("Æ", "\306");
HTML_ENTITY_MAP.put("Ç", "\307");
HTML_ENTITY_MAP.put("Ç", "\307");
HTML_ENTITY_MAP.put("È", "\310");
HTML_ENTITY_MAP.put("È", "\310");
HTML_ENTITY_MAP.put("É", "\311");
HTML_ENTITY_MAP.put("É", "\311");
HTML_ENTITY_MAP.put("Ê", "\312");
HTML_ENTITY_MAP.put("Ê", "\312");
HTML_ENTITY_MAP.put("Ë", "\313");
HTML_ENTITY_MAP.put("Ë", "\313");
HTML_ENTITY_MAP.put("Ì", "\314");
HTML_ENTITY_MAP.put("Ì", "\314");
HTML_ENTITY_MAP.put("Í", "\315");
HTML_ENTITY_MAP.put("Í", "\315");
HTML_ENTITY_MAP.put("Î", "\316");
HTML_ENTITY_MAP.put("Î", "\316");
HTML_ENTITY_MAP.put("Ï", "\317");
HTML_ENTITY_MAP.put("Ï", "\317");
HTML_ENTITY_MAP.put("Ð", "\320");
HTML_ENTITY_MAP.put("Ð", "\320");
HTML_ENTITY_MAP.put("Ñ", "\321");
HTML_ENTITY_MAP.put("Ñ", "\321");
HTML_ENTITY_MAP.put("Ò", "\322");
HTML_ENTITY_MAP.put("Ò", "\322");
HTML_ENTITY_MAP.put("Ó", "\323");
HTML_ENTITY_MAP.put("Ó", "\323");
HTML_ENTITY_MAP.put("Ô", "\324");
HTML_ENTITY_MAP.put("Ô", "\324");
HTML_ENTITY_MAP.put("Õ", "\325");
HTML_ENTITY_MAP.put("Õ", "\325");
HTML_ENTITY_MAP.put("Ö", "\326");
HTML_ENTITY_MAP.put("Ö", "\326");
HTML_ENTITY_MAP.put("×", "\327");
HTML_ENTITY_MAP.put("×", "\327");
HTML_ENTITY_MAP.put("Ø", "\330");
HTML_ENTITY_MAP.put("Ø", "\330");
HTML_ENTITY_MAP.put("Ù", "\331");
HTML_ENTITY_MAP.put("Ù", "\331");
HTML_ENTITY_MAP.put("Ú", "\332");
HTML_ENTITY_MAP.put("Ú", "\332");
HTML_ENTITY_MAP.put("Û", "\333");
HTML_ENTITY_MAP.put("Û", "\333");
HTML_ENTITY_MAP.put("Ü", "\334");
HTML_ENTITY_MAP.put("Ü", "\334");
HTML_ENTITY_MAP.put("Ý", "\335");
HTML_ENTITY_MAP.put("Ý", "\335");
HTML_ENTITY_MAP.put("Þ", "\336");
HTML_ENTITY_MAP.put("Þ", "\336");
HTML_ENTITY_MAP.put("ß", "\337");
HTML_ENTITY_MAP.put("ß", "\337");
HTML_ENTITY_MAP.put("à", "\340");
HTML_ENTITY_MAP.put("à", "\340");
HTML_ENTITY_MAP.put("á", "\341");
HTML_ENTITY_MAP.put("á", "\341");
HTML_ENTITY_MAP.put("â", "\342");
HTML_ENTITY_MAP.put("â", "\342");
HTML_ENTITY_MAP.put("ã", "\343");
HTML_ENTITY_MAP.put("ã", "\343");
HTML_ENTITY_MAP.put("ä", "\344");
HTML_ENTITY_MAP.put("ä", "\344");
HTML_ENTITY_MAP.put("å", "\345");
HTML_ENTITY_MAP.put("å", "\345");
HTML_ENTITY_MAP.put("æ", "\346");
HTML_ENTITY_MAP.put("æ", "\346");
HTML_ENTITY_MAP.put("ç", "\347");
HTML_ENTITY_MAP.put("ç", "\347");
HTML_ENTITY_MAP.put("è", "\350");
HTML_ENTITY_MAP.put("è", "\350");
HTML_ENTITY_MAP.put("é", "\351");
HTML_ENTITY_MAP.put("é", "\351");
HTML_ENTITY_MAP.put("ê", "\352");
HTML_ENTITY_MAP.put("ê", "\352");
HTML_ENTITY_MAP.put("ë", "\353");
HTML_ENTITY_MAP.put("ë", "\353");
HTML_ENTITY_MAP.put("ì", "\354");
HTML_ENTITY_MAP.put("ì", "\354");
HTML_ENTITY_MAP.put("í", "\355");
HTML_ENTITY_MAP.put("í", "\355");
HTML_ENTITY_MAP.put("î", "\356");
HTML_ENTITY_MAP.put("î", "\356");
HTML_ENTITY_MAP.put("ï", "\357");
HTML_ENTITY_MAP.put("ï", "\357");
HTML_ENTITY_MAP.put("ð", "\360");
HTML_ENTITY_MAP.put("ð", "\360");
HTML_ENTITY_MAP.put("ñ", "\361");
HTML_ENTITY_MAP.put("ñ", "\361");
HTML_ENTITY_MAP.put("ò", "\362");
HTML_ENTITY_MAP.put("ò", "\362");
HTML_ENTITY_MAP.put("ó", "\363");
HTML_ENTITY_MAP.put("ó", "\363");
HTML_ENTITY_MAP.put("ô", "\364");
HTML_ENTITY_MAP.put("ô", "\364");
HTML_ENTITY_MAP.put("õ", "\365");
HTML_ENTITY_MAP.put("õ", "\365");
HTML_ENTITY_MAP.put("ö", "\366");
HTML_ENTITY_MAP.put("ö", "\366");
HTML_ENTITY_MAP.put("÷", "\367");
HTML_ENTITY_MAP.put("÷", "\367");
HTML_ENTITY_MAP.put("ø", "\370");
HTML_ENTITY_MAP.put("ø", "\370");
HTML_ENTITY_MAP.put("ù", "\371");
HTML_ENTITY_MAP.put("ù", "\371");
HTML_ENTITY_MAP.put("ú", "\372");
HTML_ENTITY_MAP.put("ú", "\372");
HTML_ENTITY_MAP.put("û", "\373");
HTML_ENTITY_MAP.put("û", "\373");
HTML_ENTITY_MAP.put("ü", "\374");
HTML_ENTITY_MAP.put("ü", "\374");
HTML_ENTITY_MAP.put("ý", "\375");
HTML_ENTITY_MAP.put("ý", "\375");
HTML_ENTITY_MAP.put("þ", "\376");
HTML_ENTITY_MAP.put("þ", "\376");
HTML_ENTITY_MAP.put("ÿ", "\377");
HTML_ENTITY_MAP.put("ÿ", "\377");
HTML_ENTITY_MAP.put("ƒ", "\u0192");
HTML_ENTITY_MAP.put("ƒ", "\u0192");
HTML_ENTITY_MAP.put("Α", "\u0391");
HTML_ENTITY_MAP.put("Α", "\u0391");
HTML_ENTITY_MAP.put("Β", "\u0392");
HTML_ENTITY_MAP.put("Β", "\u0392");
HTML_ENTITY_MAP.put("Γ", "\u0393");
HTML_ENTITY_MAP.put("Γ", "\u0393");
HTML_ENTITY_MAP.put("Δ", "\u0394");
HTML_ENTITY_MAP.put("Δ", "\u0394");
HTML_ENTITY_MAP.put("Ε", "\u0395");
HTML_ENTITY_MAP.put("Ε", "\u0395");
HTML_ENTITY_MAP.put("Ζ", "\u0396");
HTML_ENTITY_MAP.put("Ζ", "\u0396");
HTML_ENTITY_MAP.put("Η", "\u0397");
HTML_ENTITY_MAP.put("Η", "\u0397");
HTML_ENTITY_MAP.put("Θ", "\u0398");
HTML_ENTITY_MAP.put("Θ", "\u0398");
HTML_ENTITY_MAP.put("Ι", "\u0399");
HTML_ENTITY_MAP.put("Ι", "\u0399");
HTML_ENTITY_MAP.put("Κ", "\u039A");
HTML_ENTITY_MAP.put("Κ", "\u039A");
HTML_ENTITY_MAP.put("Λ", "\u039B");
HTML_ENTITY_MAP.put("Λ", "\u039B");
HTML_ENTITY_MAP.put("Μ", "\u039C");
HTML_ENTITY_MAP.put("Μ", "\u039C");
HTML_ENTITY_MAP.put("Ν", "\u039D");
HTML_ENTITY_MAP.put("Ν", "\u039D");
HTML_ENTITY_MAP.put("Ξ", "\u039E");
HTML_ENTITY_MAP.put("Ξ", "\u039E");
HTML_ENTITY_MAP.put("Ο", "\u039F");
HTML_ENTITY_MAP.put("Ο", "\u039F");
HTML_ENTITY_MAP.put("Π", "\u03A0");
HTML_ENTITY_MAP.put("Π", "\u03A0");
HTML_ENTITY_MAP.put("Ρ", "\u03A1");
HTML_ENTITY_MAP.put("Ρ", "\u03A1");
HTML_ENTITY_MAP.put("Σ", "\u03A3");
HTML_ENTITY_MAP.put("Σ", "\u03A3");
HTML_ENTITY_MAP.put("Τ", "\u03A4");
HTML_ENTITY_MAP.put("Τ", "\u03A4");
HTML_ENTITY_MAP.put("Υ", "\u03A5");
HTML_ENTITY_MAP.put("Υ", "\u03A5");
HTML_ENTITY_MAP.put("Φ", "\u03A6");
HTML_ENTITY_MAP.put("Φ", "\u03A6");
HTML_ENTITY_MAP.put("Χ", "\u03A7");
HTML_ENTITY_MAP.put("Χ", "\u03A7");
HTML_ENTITY_MAP.put("Ψ", "\u03A8");
HTML_ENTITY_MAP.put("Ψ", "\u03A8");
HTML_ENTITY_MAP.put("Ω", "\u03A9");
HTML_ENTITY_MAP.put("Ω", "\u03A9");
HTML_ENTITY_MAP.put("α", "\u03B1");
HTML_ENTITY_MAP.put("α", "\u03B1");
HTML_ENTITY_MAP.put("β", "\u03B2");
HTML_ENTITY_MAP.put("β", "\u03B2");
HTML_ENTITY_MAP.put("γ", "\u03B3");
HTML_ENTITY_MAP.put("γ", "\u03B3");
HTML_ENTITY_MAP.put("δ", "\u03B4");
HTML_ENTITY_MAP.put("δ", "\u03B4");
HTML_ENTITY_MAP.put("ε", "\u03B5");
HTML_ENTITY_MAP.put("ε", "\u03B5");
HTML_ENTITY_MAP.put("ζ", "\u03B6");
HTML_ENTITY_MAP.put("ζ", "\u03B6");
HTML_ENTITY_MAP.put("η", "\u03B7");
HTML_ENTITY_MAP.put("η", "\u03B7");
HTML_ENTITY_MAP.put("θ", "\u03B8");
HTML_ENTITY_MAP.put("θ", "\u03B8");
HTML_ENTITY_MAP.put("ι", "\u03B9");
HTML_ENTITY_MAP.put("ι", "\u03B9");
HTML_ENTITY_MAP.put("κ", "\u03BA");
HTML_ENTITY_MAP.put("κ", "\u03BA");
HTML_ENTITY_MAP.put("λ", "\u03BB");
HTML_ENTITY_MAP.put("λ", "\u03BB");
HTML_ENTITY_MAP.put("μ", "\u03BC");
HTML_ENTITY_MAP.put("μ", "\u03BC");
HTML_ENTITY_MAP.put("ν", "\u03BD");
HTML_ENTITY_MAP.put("ν", "\u03BD");
HTML_ENTITY_MAP.put("ξ", "\u03BE");
HTML_ENTITY_MAP.put("ξ", "\u03BE");
HTML_ENTITY_MAP.put("ο", "\u03BF");
HTML_ENTITY_MAP.put("ο", "\u03BF");
HTML_ENTITY_MAP.put("π", "\u03C0");
HTML_ENTITY_MAP.put("π", "\u03C0");
HTML_ENTITY_MAP.put("ρ", "\u03C1");
HTML_ENTITY_MAP.put("ρ", "\u03C1");
HTML_ENTITY_MAP.put("ς", "\u03C2");
HTML_ENTITY_MAP.put("ς", "\u03C2");
HTML_ENTITY_MAP.put("σ", "\u03C3");
HTML_ENTITY_MAP.put("σ", "\u03C3");
HTML_ENTITY_MAP.put("τ", "\u03C4");
HTML_ENTITY_MAP.put("τ", "\u03C4");
HTML_ENTITY_MAP.put("υ", "\u03C5");
HTML_ENTITY_MAP.put("υ", "\u03C5");
HTML_ENTITY_MAP.put("φ", "\u03C6");
HTML_ENTITY_MAP.put("φ", "\u03C6");
HTML_ENTITY_MAP.put("χ", "\u03C7");
HTML_ENTITY_MAP.put("χ", "\u03C7");
HTML_ENTITY_MAP.put("ψ", "\u03C8");
HTML_ENTITY_MAP.put("ψ", "\u03C8");
HTML_ENTITY_MAP.put("ω", "\u03C9");
HTML_ENTITY_MAP.put("ω", "\u03C9");
HTML_ENTITY_MAP.put("ϑ", "\u03D1");
HTML_ENTITY_MAP.put("ϑ", "\u03D1");
HTML_ENTITY_MAP.put("ϒ", "\u03D2");
HTML_ENTITY_MAP.put("ϒ", "\u03D2");
HTML_ENTITY_MAP.put("ϖ", "\u03D6");
HTML_ENTITY_MAP.put("ϖ", "\u03D6");
HTML_ENTITY_MAP.put("•", "\u2022");
HTML_ENTITY_MAP.put("•", "\u2022");
HTML_ENTITY_MAP.put("…", "\u2026");
HTML_ENTITY_MAP.put("…", "\u2026");
HTML_ENTITY_MAP.put("′", "\u2032");
HTML_ENTITY_MAP.put("′", "\u2032");
HTML_ENTITY_MAP.put("″", "\u2033");
HTML_ENTITY_MAP.put("″", "\u2033");
HTML_ENTITY_MAP.put("‾", "\u203E");
HTML_ENTITY_MAP.put("‾", "\u203E");
HTML_ENTITY_MAP.put("⁄", "\u2044");
HTML_ENTITY_MAP.put("⁄", "\u2044");
HTML_ENTITY_MAP.put("℘", "\u2118");
HTML_ENTITY_MAP.put("℘", "\u2118");
HTML_ENTITY_MAP.put("ℑ", "\u2111");
HTML_ENTITY_MAP.put("ℑ", "\u2111");
HTML_ENTITY_MAP.put("ℜ", "\u211C");
HTML_ENTITY_MAP.put("ℜ", "\u211C");
HTML_ENTITY_MAP.put("™", "\u2122");
HTML_ENTITY_MAP.put("™", "\u2122");
HTML_ENTITY_MAP.put("ℵ", "\u2135");
HTML_ENTITY_MAP.put("ℵ", "\u2135");
HTML_ENTITY_MAP.put("←", "\u2190");
HTML_ENTITY_MAP.put("←", "\u2190");
HTML_ENTITY_MAP.put("↑", "\u2191");
HTML_ENTITY_MAP.put("↑", "\u2191");
HTML_ENTITY_MAP.put("→", "\u2192");
HTML_ENTITY_MAP.put("→", "\u2192");
HTML_ENTITY_MAP.put("↓", "\u2193");
HTML_ENTITY_MAP.put("↓", "\u2193");
HTML_ENTITY_MAP.put("↔", "\u2194");
HTML_ENTITY_MAP.put("↔", "\u2194");
HTML_ENTITY_MAP.put("↵", "\u21B5");
HTML_ENTITY_MAP.put("↵", "\u21B5");
HTML_ENTITY_MAP.put("⇐", "\u21D0");
HTML_ENTITY_MAP.put("⇐", "\u21D0");
HTML_ENTITY_MAP.put("⇑", "\u21D1");
HTML_ENTITY_MAP.put("⇑", "\u21D1");
HTML_ENTITY_MAP.put("⇒", "\u21D2");
HTML_ENTITY_MAP.put("⇒", "\u21D2");
HTML_ENTITY_MAP.put("⇓", "\u21D3");
HTML_ENTITY_MAP.put("⇓", "\u21D3");
HTML_ENTITY_MAP.put("⇔", "\u21D4");
HTML_ENTITY_MAP.put("⇔", "\u21D4");
HTML_ENTITY_MAP.put("∀", "\u2200");
HTML_ENTITY_MAP.put("∀", "\u2200");
HTML_ENTITY_MAP.put("∂", "\u2202");
HTML_ENTITY_MAP.put("∂", "\u2202");
HTML_ENTITY_MAP.put("∃", "\u2203");
HTML_ENTITY_MAP.put("∃", "\u2203");
HTML_ENTITY_MAP.put("∅", "\u2205");
HTML_ENTITY_MAP.put("∅", "\u2205");
HTML_ENTITY_MAP.put("∇", "\u2207");
HTML_ENTITY_MAP.put("∇", "\u2207");
HTML_ENTITY_MAP.put("∈", "\u2208");
HTML_ENTITY_MAP.put("∈", "\u2208");
HTML_ENTITY_MAP.put("∉", "\u2209");
HTML_ENTITY_MAP.put("∉", "\u2209");
HTML_ENTITY_MAP.put("∋", "\u220B");
HTML_ENTITY_MAP.put("∋", "\u220B");
HTML_ENTITY_MAP.put("∏", "\u220F");
HTML_ENTITY_MAP.put("∏", "\u220F");
HTML_ENTITY_MAP.put("∑", "\u2211");
HTML_ENTITY_MAP.put("∑", "\u2211");
HTML_ENTITY_MAP.put("−", "\u2212");
HTML_ENTITY_MAP.put("−", "\u2212");
HTML_ENTITY_MAP.put("∗", "\u2217");
HTML_ENTITY_MAP.put("∗", "\u2217");
HTML_ENTITY_MAP.put("√", "\u221A");
HTML_ENTITY_MAP.put("√", "\u221A");
HTML_ENTITY_MAP.put("∝", "\u221D");
HTML_ENTITY_MAP.put("∝", "\u221D");
HTML_ENTITY_MAP.put("∞", "\u221E");
HTML_ENTITY_MAP.put("∞", "\u221E");
HTML_ENTITY_MAP.put("∠", "\u2220");
HTML_ENTITY_MAP.put("∠", "\u2220");
HTML_ENTITY_MAP.put("∧", "\u2227");
HTML_ENTITY_MAP.put("∧", "\u2227");
HTML_ENTITY_MAP.put("∨", "\u2228");
HTML_ENTITY_MAP.put("∨", "\u2228");
HTML_ENTITY_MAP.put("∩", "\u2229");
HTML_ENTITY_MAP.put("∩", "\u2229");
HTML_ENTITY_MAP.put("∪", "\u222A");
HTML_ENTITY_MAP.put("∪", "\u222A");
HTML_ENTITY_MAP.put("∫", "\u222B");
HTML_ENTITY_MAP.put("∫", "\u222B");
HTML_ENTITY_MAP.put("∴", "\u2234");
HTML_ENTITY_MAP.put("∴", "\u2234");
HTML_ENTITY_MAP.put("∼", "\u223C");
HTML_ENTITY_MAP.put("∼", "\u223C");
HTML_ENTITY_MAP.put("≅", "\u2245");
HTML_ENTITY_MAP.put("≅", "\u2245");
HTML_ENTITY_MAP.put("≈", "\u2248");
HTML_ENTITY_MAP.put("≈", "\u2248");
HTML_ENTITY_MAP.put("≠", "\u2260");
HTML_ENTITY_MAP.put("≠", "\u2260");
HTML_ENTITY_MAP.put("≡", "\u2261");
HTML_ENTITY_MAP.put("≡", "\u2261");
HTML_ENTITY_MAP.put("≤", "\u2264");
HTML_ENTITY_MAP.put("≤", "\u2264");
HTML_ENTITY_MAP.put("≥", "\u2265");
HTML_ENTITY_MAP.put("≥", "\u2265");
HTML_ENTITY_MAP.put("⊂", "\u2282");
HTML_ENTITY_MAP.put("⊂", "\u2282");
HTML_ENTITY_MAP.put("⊃", "\u2283");
HTML_ENTITY_MAP.put("⊃", "\u2283");
HTML_ENTITY_MAP.put("⊆", "\u2286");
HTML_ENTITY_MAP.put("⊆", "\u2286");
HTML_ENTITY_MAP.put("⊇", "\u2287");
HTML_ENTITY_MAP.put("⊇", "\u2287");
HTML_ENTITY_MAP.put("⊕", "\u2295");
HTML_ENTITY_MAP.put("⊕", "\u2295");
HTML_ENTITY_MAP.put("⊗", "\u2297");
HTML_ENTITY_MAP.put("⊗", "\u2297");
HTML_ENTITY_MAP.put("⊥", "\u22A5");
HTML_ENTITY_MAP.put("⊥", "\u22A5");
HTML_ENTITY_MAP.put("⋅", "\u22C5");
HTML_ENTITY_MAP.put("⋅", "\u22C5");
HTML_ENTITY_MAP.put("⌈", "\u2308");
HTML_ENTITY_MAP.put("⌈", "\u2308");
HTML_ENTITY_MAP.put("⌉", "\u2309");
HTML_ENTITY_MAP.put("⌉", "\u2309");
HTML_ENTITY_MAP.put("⌊", "\u230A");
HTML_ENTITY_MAP.put("⌊", "\u230A");
HTML_ENTITY_MAP.put("⌋", "\u230B");
HTML_ENTITY_MAP.put("⌋", "\u230B");
HTML_ENTITY_MAP.put("〈", "\u2329");
HTML_ENTITY_MAP.put("〈", "\u2329");
HTML_ENTITY_MAP.put("〉", "\u232A");
HTML_ENTITY_MAP.put("〉", "\u232A");
HTML_ENTITY_MAP.put("◊", "\u25CA");
HTML_ENTITY_MAP.put("◊", "\u25CA");
HTML_ENTITY_MAP.put("♠", "\u2660");
HTML_ENTITY_MAP.put("♠", "\u2660");
HTML_ENTITY_MAP.put("♣", "\u2663");
HTML_ENTITY_MAP.put("♣", "\u2663");
HTML_ENTITY_MAP.put("♥", "\u2665");
HTML_ENTITY_MAP.put("♥", "\u2665");
HTML_ENTITY_MAP.put("♦", "\u2666");
HTML_ENTITY_MAP.put("♦", "\u2666");
HTML_ENTITY_MAP.put("Œ", "\u0152");
HTML_ENTITY_MAP.put("Œ", "\u0152");
HTML_ENTITY_MAP.put("œ", "\u0153");
HTML_ENTITY_MAP.put("œ", "\u0153");
HTML_ENTITY_MAP.put("Š", "\u0160");
HTML_ENTITY_MAP.put("Š", "\u0160");
HTML_ENTITY_MAP.put("š", "\u0161");
HTML_ENTITY_MAP.put("š", "\u0161");
HTML_ENTITY_MAP.put("Ÿ", "\u0178");
HTML_ENTITY_MAP.put("Ÿ", "\u0178");
HTML_ENTITY_MAP.put("ˆ", "\u02C6");
HTML_ENTITY_MAP.put("ˆ", "\u02C6");
HTML_ENTITY_MAP.put("˜", "\u02DC");
HTML_ENTITY_MAP.put("˜", "\u02DC");
HTML_ENTITY_MAP.put(" ", "\u2002");
HTML_ENTITY_MAP.put(" ", "\u2002");
HTML_ENTITY_MAP.put(" ", "\u2003");
HTML_ENTITY_MAP.put(" ", "\u2003");
HTML_ENTITY_MAP.put(" ", "\u2009");
HTML_ENTITY_MAP.put(" ", "\u2009");
HTML_ENTITY_MAP.put("", "\u200C");
HTML_ENTITY_MAP.put("", "\u200C");
HTML_ENTITY_MAP.put("", "\u200D");
HTML_ENTITY_MAP.put("", "\u200D");
HTML_ENTITY_MAP.put("", "\u200E");
HTML_ENTITY_MAP.put("", "\u200E");
HTML_ENTITY_MAP.put("", "\u200F");
HTML_ENTITY_MAP.put("", "\u200F");
HTML_ENTITY_MAP.put("–", "\u2013");
HTML_ENTITY_MAP.put("–", "\u2013");
HTML_ENTITY_MAP.put("—", "\u2014");
HTML_ENTITY_MAP.put("—", "\u2014");
HTML_ENTITY_MAP.put("‘", "\u2018");
HTML_ENTITY_MAP.put("‘", "\u2018");
HTML_ENTITY_MAP.put("’", "\u2019");
HTML_ENTITY_MAP.put("’", "\u2019");
HTML_ENTITY_MAP.put("‚", "\u201A");
HTML_ENTITY_MAP.put("‚", "\u201A");
HTML_ENTITY_MAP.put("“", "\u201C");
HTML_ENTITY_MAP.put("“", "\u201C");
HTML_ENTITY_MAP.put("”", "\u201D");
HTML_ENTITY_MAP.put("”", "\u201D");
HTML_ENTITY_MAP.put("„", "\u201E");
HTML_ENTITY_MAP.put("„", "\u201E");
HTML_ENTITY_MAP.put("†", "\u2020");
HTML_ENTITY_MAP.put("†", "\u2020");
HTML_ENTITY_MAP.put("‡", "\u2021");
HTML_ENTITY_MAP.put("‡", "\u2021");
HTML_ENTITY_MAP.put("‰", "\u2030");
HTML_ENTITY_MAP.put("‰", "\u2030");
HTML_ENTITY_MAP.put("‹", "\u2039");
HTML_ENTITY_MAP.put("‹", "\u2039");
HTML_ENTITY_MAP.put("›", "\u203A");
HTML_ENTITY_MAP.put("›", "\u203A");
HTML_ENTITY_MAP.put("€", "\u20AC");
HTML_ENTITY_MAP.put("€", "\u20AC");
}
}