diff --git a/rxlib-x/pom.xml b/rxlib-x/pom.xml index e6c613a6..42ac9cd4 100644 --- a/rxlib-x/pom.xml +++ b/rxlib-x/pom.xml @@ -21,6 +21,10 @@ 4.0.3 1.2.21 3.27.2 + 32.1.1-jre + + 1.6.2 + 5.2.2 @@ -65,10 +69,31 @@ - - - - - + + com.google.guava + guava + ${guava.version} + + + + org.ahocorasick + ahocorasick + 0.3.1 + + + org.apache.poi + poi + ${poi.version} + + + org.apache.poi + poi-ooxml + ${poi.version} + + + com.sun.mail + javax.mail + ${javaxMail.version} + diff --git a/rxlib-x/src/main/java/org/rx/crawler/RemoteBrowser.java b/rxlib-x/src/main/java/org/rx/crawler/RemoteBrowser.java index d0a4ee74..34a5dd95 100644 --- a/rxlib-x/src/main/java/org/rx/crawler/RemoteBrowser.java +++ b/rxlib-x/src/main/java/org/rx/crawler/RemoteBrowser.java @@ -4,13 +4,13 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.rx.bean.FlagsEnum; -import org.rx.spring.MiddlewareConfig; import org.rx.core.Linq; import org.rx.core.Reflects; import org.rx.exception.InvalidException; import org.rx.net.Sockets; import org.rx.net.rpc.Remoting; import org.rx.net.rpc.RpcClientConfig; +import org.rx.spring.MiddlewareConfig; import org.rx.spring.SpringContext; import org.rx.util.function.*; diff --git a/rxlib-x/src/main/java/org/rx/jdbc/JdbcExecutor.java b/rxlib-x/src/main/java/org/rx/jdbc/JdbcExecutor.java index 6b63113b..1ca021f6 100644 --- a/rxlib-x/src/main/java/org/rx/jdbc/JdbcExecutor.java +++ b/rxlib-x/src/main/java/org/rx/jdbc/JdbcExecutor.java @@ -25,7 +25,8 @@ import java.util.List; import static org.rx.core.Extends.*; -import static org.rx.core.Sys.*; +import static org.rx.core.Sys.proxy; +import static org.rx.core.Sys.toJsonString; @Slf4j public class JdbcExecutor extends Disposable implements EventPublisher, JdbcExecutable { diff --git a/rxlib-x/src/main/java/org/rx/redis/RateLimiterAdapter.java b/rxlib-x/src/main/java/org/rx/redis/RateLimiterAdapter.java new file mode 100644 index 00000000..9db81b1f --- /dev/null +++ b/rxlib-x/src/main/java/org/rx/redis/RateLimiterAdapter.java @@ -0,0 +1,5 @@ +package org.rx.redis; + +public interface RateLimiterAdapter { + boolean tryAcquire(); +} diff --git a/rxlib-x/src/main/java/org/rx/redis/RedisCache.java b/rxlib-x/src/main/java/org/rx/redis/RedisCache.java index 80a13193..29fdc385 100644 --- a/rxlib-x/src/main/java/org/rx/redis/RedisCache.java +++ b/rxlib-x/src/main/java/org/rx/redis/RedisCache.java @@ -11,10 +11,15 @@ import org.redisson.config.Config; import org.rx.bean.BiTuple; import org.rx.codec.CodecUtil; -import org.rx.core.*; +import org.rx.core.Cache; +import org.rx.core.CachePolicy; +import org.rx.core.RxConfig; +import org.rx.core.Tasks; import org.rx.util.function.BiFunc; -import java.util.*; +import java.util.AbstractMap; +import java.util.HashSet; +import java.util.Set; import java.util.concurrent.TimeUnit; import static org.rx.core.Extends.quietly; diff --git a/rxlib-x/src/main/java/org/rx/redis/RedisRateLimiter.java b/rxlib-x/src/main/java/org/rx/redis/RedisRateLimiter.java new file mode 100644 index 00000000..6f2ef919 --- /dev/null +++ b/rxlib-x/src/main/java/org/rx/redis/RedisRateLimiter.java @@ -0,0 +1,55 @@ +package org.rx.redis; + +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import org.redisson.api.RRateLimiter; +import org.redisson.api.RateIntervalUnit; +import org.redisson.api.RateLimiterConfig; +import org.redisson.api.RateType; +import org.rx.core.Constants; + +@Slf4j +public class RedisRateLimiter implements RateLimiterAdapter { + final RedisCache rCache; + final RRateLimiter limiter; + + public int getPermitsPerSecond() { + return limiter.getConfig().getRate().intValue(); + } + + @Override + public boolean tryAcquire() { + return limiter.tryAcquire(); + } + + public RedisRateLimiter(@NonNull RedisCache rCache, String acquireKey) { + this(rCache, acquireKey, Constants.CPU_THREADS); + } + + public RedisRateLimiter(@NonNull RedisCache rCache, String acquireKey, int permitsPerSecond) { + this.rCache = rCache; + limiter = createLimiter(acquireKey, permitsPerSecond, 1); + } + + RRateLimiter createLimiter(String key, long rate, long rateInterval) { + RRateLimiter limiter = rCache.getClient().getRateLimiter(key); + if (limiter.isExists()) { + RateLimiterConfig config = limiter.getConfig(); + if (config.getRate() == rate && config.getRateInterval() == RateIntervalUnit.SECONDS.toMillis(rateInterval)) { + return limiter; + } + } + + log.info("trySetRate start, {} {}", key, rate); + int retry = 4; + // 循环直到重新配置成功 + while (--retry > 0 && !limiter.trySetRate(RateType.OVERALL, rate, rateInterval, RateIntervalUnit.SECONDS)) { + limiter.delete(); + limiter = rCache.getClient().getRateLimiter(key); + } + if (retry == 0) { + log.warn("trySetRate fail, {} {}", key, rate); + } + return limiter; + } +} diff --git a/rxlib-x/src/main/java/org/rx/redis/RedisUtil.java b/rxlib-x/src/main/java/org/rx/redis/RedisUtil.java index aafe9eac..41390c42 100644 --- a/rxlib-x/src/main/java/org/rx/redis/RedisUtil.java +++ b/rxlib-x/src/main/java/org/rx/redis/RedisUtil.java @@ -1,8 +1,7 @@ package org.rx.redis; -import lombok.RequiredArgsConstructor; +import com.google.common.util.concurrent.RateLimiter; import org.redisson.api.RLock; -import org.redisson.api.RedissonClient; import org.rx.core.Cache; import org.rx.core.Strings; import org.rx.core.Sys; @@ -22,7 +21,14 @@ public static Lock wrapLock(RLock rLock) { }); } - public static Cache wrapCache(String redisUrl) { - return Sys.fallbackProxy(Cache.class, new RedisCache<>(redisUrl), new Lazy<>(() -> Cache.getInstance(MemoryCache.class))); + public static Cache wrapCache(RedisCache rCache) { + return Sys.fallbackProxy(Cache.class, rCache, new Lazy<>(() -> Cache.getInstance(MemoryCache.class))); + } + + public static RateLimiterAdapter wrapRateLimiter(RedisRateLimiter rRateLimiter) { + return Sys.fallbackProxy(RateLimiterAdapter.class, rRateLimiter, new Lazy<>(() -> { + RateLimiter limiter = RateLimiter.create(rRateLimiter.getPermitsPerSecond()); + return () -> limiter.tryAcquire(); + })); } } diff --git a/rxlib-x/src/main/java/org/rx/spring/BeanRegister.java b/rxlib-x/src/main/java/org/rx/spring/BeanRegister.java index 01b693d3..1725bf7e 100644 --- a/rxlib-x/src/main/java/org/rx/spring/BeanRegister.java +++ b/rxlib-x/src/main/java/org/rx/spring/BeanRegister.java @@ -1,15 +1,19 @@ package org.rx.spring; import lombok.extern.slf4j.Slf4j; -import org.rx.core.Cache; -import org.rx.core.IOC; -import org.rx.core.Strings; +import org.rx.core.*; import org.rx.exception.InvalidException; +import org.rx.redis.RateLimiterAdapter; +import org.rx.redis.RedisCache; +import org.rx.redis.RedisRateLimiter; import org.rx.redis.RedisUtil; +import org.rx.util.Servlets; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import static org.rx.core.Extends.ifNull; + @Configuration @Slf4j public class BeanRegister { @@ -17,14 +21,33 @@ public class BeanRegister { @Bean @ConditionalOnProperty(name = REDIS_PROP_NAME) - public Cache redisCache(MiddlewareConfig redisConfig) { - if (Strings.isEmpty(redisConfig.getRedisUrl())) { + public RedisCache redisCache(MiddlewareConfig conf) { + if (Strings.isEmpty(conf.getRedisUrl())) { throw new InvalidException("app.redisUrl is null"); } - Cache cache = RedisUtil.wrapCache(redisConfig.getRedisUrl()); - IOC.register(Cache.class, cache); + RedisCache cache = new RedisCache<>(conf.getRedisUrl()); + IOC.register(Cache.class, RedisUtil.wrapCache(cache)); log.info("register RedisCache ok"); return cache; } + + @Bean + @ConditionalOnProperty(name = REDIS_PROP_NAME) + public RateLimiterAdapter httpRateLimiterAdapter(RedisCache rCache, MiddlewareConfig conf) { + String[] acquireWhiteList = conf.getLimiterWhiteList(); + return () -> { + String clientIp = ifNull(Servlets.requestIp(), "ALL"); + + if (!Arrays.isEmpty(acquireWhiteList) + && Linq.from(acquireWhiteList).any(p -> Strings.startsWith(clientIp, p))) { + return true; + } + + String rk = "RateLimiter:" + clientIp; + RateLimiterAdapter adapter = IOC.weakMap(false) + .computeIfAbsent(rk, k -> RedisUtil.wrapRateLimiter(new RedisRateLimiter(rCache, k, conf.getLimiterPermits()))); + return adapter.tryAcquire(); + }; + } } diff --git a/rxlib-x/src/main/java/org/rx/spring/MiddlewareConfig.java b/rxlib-x/src/main/java/org/rx/spring/MiddlewareConfig.java index f1e2ddaa..18a75dfa 100644 --- a/rxlib-x/src/main/java/org/rx/spring/MiddlewareConfig.java +++ b/rxlib-x/src/main/java/org/rx/spring/MiddlewareConfig.java @@ -2,8 +2,6 @@ import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Data @@ -13,6 +11,7 @@ public class MiddlewareConfig { private String redisUrl; private String storeUrl; + private int limiterPermits = 12; private String limiterWhiteList; diff --git a/rxlib-x/src/main/java/org/rx/util/Helper.java b/rxlib-x/src/main/java/org/rx/util/Helper.java new file mode 100644 index 00000000..df958d4e --- /dev/null +++ b/rxlib-x/src/main/java/org/rx/util/Helper.java @@ -0,0 +1,194 @@ +package org.rx.util; + +import lombok.NonNull; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.rx.core.Numbers; +import org.rx.spring.MiddlewareConfig; +import org.rx.spring.SpringContext; + +import javax.mail.*; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import java.io.InputStream; +import java.io.OutputStream; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.function.Function; + +import static org.rx.core.Extends.eq; +import static org.rx.core.Sys.toJsonString; + +@Slf4j +public class Helper { + public static void sendEmail(String body) { + MiddlewareConfig config = SpringContext.getBean(MiddlewareConfig.class); + Helper.sendEmail(body, config.getSmtpPwd(), config.getSmtpTo()); + } + + public static void sendEmail(String body, @NonNull String password, @NonNull String toEmail) { + final String fromEmail = "17091916400@163.com"; + Properties props = new Properties(); + props.put("mail.smtp.host", "smtp.163.com"); + props.put("mail.smtp.port", "25"); + props.put("mail.smtp.auth", "true"); + Session session = Session.getInstance(props, new Authenticator() { + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(fromEmail, password); + } + }); + + try { + MimeMessage msg = new MimeMessage(session); + msg.addHeader("Content-type", "text/HTML; charset=UTF-8"); + msg.addHeader("format", "flowed"); + msg.addHeader("Content-Transfer-Encoding", "8bit"); + + msg.setFrom(new InternetAddress(fromEmail, "System")); + msg.setReplyTo(InternetAddress.parse("no_reply@f-li.cn", false)); + + msg.setSubject("Notification", "UTF-8"); + msg.setText(body, "UTF-8"); + msg.setSentDate(new Date()); + + msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false)); + Transport.send(msg); + } catch (Exception e) { + log.warn("sendEmail {}", e.getMessage()); + } + } + + public static Map> readExcel(InputStream in, boolean is2003File) { + return readExcel(in, is2003File, false, false); + } + + @SneakyThrows + public static Map> readExcel(InputStream in, boolean is2003File, boolean skipColumn, boolean keepNullRow) { + Map> data = new LinkedHashMap<>(); + FormulaEvaluator evaluator = null; + try (Workbook workbook = is2003File ? new HSSFWorkbook(in) : new XSSFWorkbook(in)) { + for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) { + List rows = new ArrayList<>(); + Sheet sheet = workbook.getSheetAt(sheetIndex); + for (int rowIndex = skipColumn ? 1 : sheet.getFirstRowNum(); rowIndex <= sheet.getLastRowNum(); rowIndex++) { + Row row = sheet.getRow(rowIndex); + if (row == null) { + if (keepNullRow) { + rows.add(null); + } + continue; + } + List cells = new ArrayList<>(); + short firstCellNum = row.getFirstCellNum(); + for (int i = 0; i < row.getLastCellNum(); i++) { + if (i < firstCellNum) { + cells.add(null); + continue; + } + Cell cell = row.getCell(i); + if (cell == null) { + cells.add(null); + continue; + } + + CellType cellType = cell.getCellType(); + if (cellType == CellType.FORMULA) { + if (evaluator == null) { + evaluator = workbook.getCreationHelper().createFormulaEvaluator(); + } + cellType = evaluator.evaluateFormulaCell(cell); + } + Object value; +// System.out.println(i + ":" + cellType); + switch (cellType) { + case NUMERIC: + if (!eq(cell.getCellStyle().getDataFormatString(), "General")) { + value = cell.getDateCellValue(); + } else { + double n = cell.getNumericCellValue(); + boolean b = Numbers.hasPrecision(n); + if (b) { + value = (int) n; + } else { + value = n; + } + //will auto wrap to double +// value = b ? (int) n : n; + } + break; + case BOOLEAN: + value = cell.getBooleanCellValue(); + break; + default: +// value = cell.getStringCellValue(); + if (cell.getCellType() == CellType.ERROR) { + cell.setCellType(CellType.STRING); + log.debug("sheetIndex={} rowIndex={} rowCellLength={} cells={}", sheetIndex, rowIndex, row.getLastCellNum(), toJsonString(cells)); + } + value = cell.toString(); + break; + } + cells.add(value); + } + if (cells.contains(null)) { + log.debug("sheetIndex={} rowIndex={} rowCellLength={} cells={}", sheetIndex, rowIndex, row.getLastCellNum(), toJsonString(cells)); + } + rows.add(cells.toArray()); + } + data.put(sheet.getSheetName(), rows); + } + } + return data; + } + + public static void writeExcel(OutputStream out, boolean is2003File, Map> data) { + writeExcel(out, is2003File, data, null); + } + + @SneakyThrows + public static void writeExcel(OutputStream out, boolean is2003File, Map> data, Function onRow) { + try (Workbook workbook = is2003File ? new HSSFWorkbook() : new XSSFWorkbook()) { + for (Map.Entry> entry : data.entrySet()) { + Sheet sheet = workbook.getSheet(entry.getKey()); + if (sheet == null) { + sheet = workbook.createSheet(entry.getKey()); + } + int rowIndex = 0; + for (Object[] cells : entry.getValue()) { + Row row = sheet.getRow(rowIndex); + if (row == null) { + row = sheet.createRow(rowIndex); + } + for (int i = 0; i < cells.length; i++) { + Cell cell = row.getCell(i); + if (cell == null) { + cell = row.createCell(i); + } + Object val = cells[i]; + if (val == null) { + continue; + } + String value; + if (val instanceof Date) { + value = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(val); + } else { + value = String.valueOf(val); + } + cell.setCellValue(value); + } + if (onRow != null) { + if (row.getRowStyle() == null) { + row.setRowStyle(workbook.createCellStyle()); + } + onRow.apply(row); + } + rowIndex++; + } + } + workbook.write(out); + } + } +} diff --git a/rxlib-x/src/main/java/org/rx/util/pinyin/Engine.java b/rxlib-x/src/main/java/org/rx/util/pinyin/Engine.java new file mode 100644 index 00000000..83da0b9c --- /dev/null +++ b/rxlib-x/src/main/java/org/rx/util/pinyin/Engine.java @@ -0,0 +1,114 @@ +package org.rx.util.pinyin; + + +import org.ahocorasick.trie.Emit; +import org.ahocorasick.trie.Trie; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * 字符串转拼音引擎,支持字典和{@link SegmentationSelector} + * + * Created by guyacong on 2016/12/23. + */ + +final class Engine { + + static final EmitComparator EMIT_COMPARATOR = new EmitComparator(); + + private Engine() { + //no instance + } + + static String toPinyin(final String inputStr, Pinyin.Config config, String separator) { + List pinyinDicts = Collections.unmodifiableList(config.getPinyinDicts()); + Trie trie = Utils.dictsToTrie(config.getPinyinDicts()); + SegmentationSelector selector = config.getSelector(); + + return toPinyin(inputStr, trie, pinyinDicts, separator, selector); + } + + static String toPinyin(final String inputStr, final Trie trie, final List pinyinDictList, + final String separator, final SegmentationSelector selector) { + if (inputStr == null || inputStr.length() == 0) { + return inputStr; + } + + + if (trie == null || selector == null) { + // 没有提供字典或选择器,按单字符转换输出 + StringBuffer resultPinyinStrBuf = new StringBuffer(); + for (int i = 0; i < inputStr.length(); i++) { + resultPinyinStrBuf.append(Pinyin.toPinyin(inputStr.charAt(i))); + if (i != inputStr.length() - 1) { + resultPinyinStrBuf.append(separator); + } + } + return resultPinyinStrBuf.toString(); + } + + List selectedEmits = selector.select(trie.parseText(inputStr)); + + Collections.sort(selectedEmits, EMIT_COMPARATOR); + + StringBuffer resultPinyinStrBuf = new StringBuffer(); + + int nextHitIndex = 0; + + for (int i = 0; i < inputStr.length();) { + // 首先确认是否有以第i个字符作为begin的hit + if (nextHitIndex < selectedEmits.size() && i == selectedEmits.get(nextHitIndex).getStart()) { + // 有以第i个字符作为begin的hit + String[] fromDicts = pinyinFromDict(selectedEmits.get(nextHitIndex).getKeyword(), pinyinDictList); + for (int j = 0; j < fromDicts.length; j++) { + resultPinyinStrBuf.append(fromDicts[j].toUpperCase()); + if (j != fromDicts.length - 1) { + resultPinyinStrBuf.append(separator); + } + } + + i = i + selectedEmits.get(nextHitIndex).size(); + nextHitIndex++; + } else { + // 将第i个字符转为拼音 + resultPinyinStrBuf.append(Pinyin.toPinyin(inputStr.charAt(i))); + i++; + } + + if (i != inputStr.length()) { + resultPinyinStrBuf.append(separator); + } + } + + return resultPinyinStrBuf.toString(); + } + + static String[] pinyinFromDict(String wordInDict, List pinyinDictSet) { + if (pinyinDictSet != null) { + for (PinyinDict dict : pinyinDictSet) { + if (dict != null && dict.words() != null + && dict.words().contains(wordInDict)) { + return dict.toPinyin(wordInDict); + } + } + } + throw new IllegalArgumentException("No pinyin dict contains word: " + wordInDict); + } + + static final class EmitComparator implements Comparator { + + @Override + public int compare(Emit o1, Emit o2) { + if (o1.getStart() == o2.getStart()) { + // 起点相同时,更长的排前面 + return (o1.size() < o2.size()) ? 1 : ((o1.size() == o2.size()) ? 0 : -1); + } else { + // 起点小的放前面 + return (o1.getStart() < o2.getStart()) ? -1 : ((o1.getStart() == o2.getStart()) ? 0 : 1); + } + } + } + +} diff --git a/rxlib-x/src/main/java/org/rx/util/pinyin/ForwardLongestSelector.java b/rxlib-x/src/main/java/org/rx/util/pinyin/ForwardLongestSelector.java new file mode 100644 index 00000000..e95a1d1a --- /dev/null +++ b/rxlib-x/src/main/java/org/rx/util/pinyin/ForwardLongestSelector.java @@ -0,0 +1,43 @@ +package org.rx.util.pinyin; + +import org.ahocorasick.trie.Emit; + +import java.util.*; + +/** + * 正向最大匹配选择器 + * + * Created by guyacong on 2016/12/28. + */ + +final class ForwardLongestSelector implements SegmentationSelector { + + static final Engine.EmitComparator HIT_COMPARATOR = new Engine.EmitComparator(); + + @Override + public List select(final Collection emits) { + if (emits == null) { + return null; + } + + List results = new ArrayList(emits); + + Collections.sort(results, HIT_COMPARATOR); + + int endValueToRemove = -1; + + Set emitToRemove = new TreeSet(); + + for (Emit emit : results) { + if (emit.getStart() > endValueToRemove && emit.getEnd() > endValueToRemove) { + endValueToRemove = emit.getEnd(); + } else { + emitToRemove.add(emit); + } + } + + results.removeAll(emitToRemove); + + return results; + } +} diff --git a/rxlib-x/src/main/java/org/rx/util/pinyin/Pinyin.java b/rxlib-x/src/main/java/org/rx/util/pinyin/Pinyin.java new file mode 100644 index 00000000..426525ed --- /dev/null +++ b/rxlib-x/src/main/java/org/rx/util/pinyin/Pinyin.java @@ -0,0 +1,224 @@ +package org.rx.util.pinyin; + +import org.ahocorasick.trie.Trie; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * https://github.com/promeG/TinyPinyin + * Created by guyacong on 2015/9/28. + */ +public final class Pinyin { + + static Trie mTrieDict = null; + static SegmentationSelector mSelector = null; + static List mPinyinDicts = null; + + private Pinyin() { + } + + /** + * 使用 {@link Config} 初始化Pinyin。 + * + * @param config 相应的设置,传入null则会清空所有的词典 + */ + public static void init(Config config) { + if (config == null) { + // 清空设置 + mPinyinDicts = null; + mTrieDict = null; + mSelector = null; + return; + } + + if (!config.valid()) { + // 忽略无效Config + return; + } + mPinyinDicts = Collections.unmodifiableList(config.getPinyinDicts()); + mTrieDict = Utils.dictsToTrie(config.getPinyinDicts()); + mSelector = config.getSelector(); + } + + /** + * 向Pinyin中追加词典。 + * + * 注意: 若有多个词典,推荐使用性能更优的 {@link Pinyin#init(Config)} 初始化Pinyin。 + * + * @param dict 输入的词典 + */ + public static void add(PinyinDict dict) { + if (dict == null || dict.words() == null || dict.words().size() == 0) { + // 无效字典 + return; + } + init(new Config(mPinyinDicts).with(dict)); + } + + /** + * 返回新的{@link Config} 对象 + * + * @return 新的Config对象 + */ + public static Config newConfig() { + return new Config(null); + } + + /** + * 将输入字符串转为拼音,转换过程中会使用之前设置的用户词典,以字符为单位插入分隔符 + * + * 例: "hello:中国" 在separator为","时,输出: "h,e,l,l,o,:,ZHONG,GUO,!" + * + * @param str 输入字符串 + * @param separator 分隔符 + * @return 中文转为拼音的字符串 + */ + public static String toPinyin(String str, String separator) { + return Engine.toPinyin(str, mTrieDict, mPinyinDicts, separator, mSelector); + } + + + /** + * 将输入字符串转为拼音,转换过程中会使用之前设置的用户词典,以字符为单位插入分隔符 + * + * 例: "hello:中国!" 在separator为","时,输出: "h,e,l,l,o,:,ZHONG,GUO,!" + * + * @param str 输入字符串 + * @param separator 分隔符 + * @param rules 自定义的规则,具有最高优先级 + * @return 中文转为拼音的字符串 + */ + public static String toPinyin(String str, String separator, PinyinRules rules) { + if (rules != null) { + List dicts = new ArrayList(); + dicts.add(rules.toPinyinMapDict()); + if (mPinyinDicts != null) { + dicts.addAll(mPinyinDicts); + } + Config config = new Config(dicts); + + return Engine.toPinyin(str, config, separator); + } else { + return toPinyin(str, separator); + } + } + + /** + * 将输入字符转为拼音 + * + * @param c 输入字符 + * @return return pinyin if c is chinese in uppercase, String.valueOf(c) otherwise. + */ + public static String toPinyin(char c) { + if (isChinese(c)) { + if (c == PinyinData.CHAR_12295) { + return PinyinData.PINYIN_12295; + } else { + return PinyinData.PINYIN_TABLE[getPinyinCode(c)]; + } + } else { + return String.valueOf(c); + } + } + + /** + * 将输入字符转为拼音 + * + * @param c 输入字符 + * @param rules 自定义规则,具有最高优先级 + * @return return pinyin if c is chinese in uppercase, String.valueOf(c) otherwise. + */ + public static String toPinyin(char c, PinyinRules rules) { + if (rules != null && rules.toPinyin(c) != null) { + return rules.toPinyin(c); + } else { + return toPinyin(c); + } + } + + /** + * 判断输入字符是否为汉字 + * + * @param c 输入字符 + * @return return whether c is chinese + */ + public static boolean isChinese(char c) { + return (PinyinData.MIN_VALUE <= c && c <= PinyinData.MAX_VALUE + && getPinyinCode(c) > 0) + || PinyinData.CHAR_12295 == c; + } + + private static int getPinyinCode(char c) { + int offset = c - PinyinData.MIN_VALUE; + if (0 <= offset && offset < PinyinData.PINYIN_CODE_1_OFFSET) { + return decodeIndex(PinyinCode1.PINYIN_CODE_PADDING, PinyinCode1.PINYIN_CODE, offset); + } else if (PinyinData.PINYIN_CODE_1_OFFSET <= offset + && offset < PinyinData.PINYIN_CODE_2_OFFSET) { + return decodeIndex(PinyinCode2.PINYIN_CODE_PADDING, PinyinCode2.PINYIN_CODE, + offset - PinyinData.PINYIN_CODE_1_OFFSET); + } else { + return decodeIndex(PinyinCode3.PINYIN_CODE_PADDING, PinyinCode3.PINYIN_CODE, + offset - PinyinData.PINYIN_CODE_2_OFFSET); + } + } + + private static short decodeIndex(byte[] paddings, byte[] indexes, int offset) { + //CHECKSTYLE:OFF + int index1 = offset / 8; + int index2 = offset % 8; + short realIndex; + realIndex = (short) (indexes[offset] & 0xff); + //CHECKSTYLE:ON + if ((paddings[index1] & PinyinData.BIT_MASKS[index2]) != 0) { + realIndex = (short) (realIndex | PinyinData.PADDING_MASK); + } + return realIndex; + } + + public static final class Config { + + SegmentationSelector mSelector; + + List mPinyinDicts; + + private Config(List dicts) { + if (dicts != null) { + mPinyinDicts = new ArrayList(dicts); + } + + mSelector = new ForwardLongestSelector(); + } + + /** + * 添加字典 + * + * @param dict 字典 + * @return 返回Config对象,支持继续添加字典 + */ + public Config with(PinyinDict dict) { + if (dict != null) { + if (mPinyinDicts == null) { + mPinyinDicts = new ArrayList(); + mPinyinDicts.add(dict); + } else if (!mPinyinDicts.contains(dict)) { + mPinyinDicts.add(dict); + } + } + return this; + } + + boolean valid() { + return getPinyinDicts() != null && getSelector() != null; + } + + SegmentationSelector getSelector() { + return mSelector; + } + + List getPinyinDicts() { + return mPinyinDicts; + } + } +} diff --git a/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinCode1.java b/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinCode1.java new file mode 100644 index 00000000..c0df1618 --- /dev/null +++ b/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinCode1.java @@ -0,0 +1,430 @@ +package org.rx.util.pinyin; + +/** + * Created by guyacong on 2015/9/28. + */ +//CHECKSTYLE:OFF +final class PinyinCode1 { + + private PinyinCode1() { + //no instance + } + + static byte[] PINYIN_CODE_PADDING = new byte[]{-79, 79, -56, 37, -87, 41, 96, 13, -122, 58, 2, + -122, 67, 33, -72, -128, 16, 79, -45, 92, 75, 40, 54, -50, 19, 34, -15, 102, 32, 39, 53, + 25, -55, 37, -62, -23, 28, 47, -88, -105, -123, -86, -97, -105, 26, -96, 0, -52, -105, + -80, 3, 116, 69, 64, 36, 15, 103, 74, -78, -62, 31, 81, 68, 50, -102, -60, 73, 21, -111, + -80, 40, 124, 41, 118, -83, 84, -33, -104, -89, 37, -38, -122, 12, -3, 48, -28, -14, + -24, 2, -36, 89, -64, -120, 66, -100, -96, -103, 96, 12, 40, -128, -105, 49, 26, -33, + 65, -16, -125, 96, 69, 20, -86, 80, 34, -110, -93, 28, 34, 64, 80, -54, 4, 65, 65, 0, 0, + 96, -127, 24, 65, 74, 66, 9, 4, -64, 1, -120, 5, 16, 20, 71, 34, 9, 17, 48, -128, 40, + 52, -62, -14, -128, -125, -128, 41, -64, 62, -108, 35, -115, -115, 1, 9, 16, 48, 24, 16, + -112, 45, -25, -71, 29, 8, -87, 105, 87, -101, -95, -4, -104, -102, 78, 100, -8, -114, + 19, 89, -4, -46, 2, 21, 93, 3, -30, 16, 23, -58, 12, 80, 30, 73, 1, -126, 10, -47, 98, + 47, -103, -114, 12, -120, -116, 112, 112, 89, -121, -83, -84, 38, 10, -128, 2, -55, 12, + 65, 67, -103, 115, 4, 12, -53, -127, 118, 114, -8, 32, 67, -87, 57, 26, 21, 118, -112, + -97, 16, -113, 38, 93, 12, -90, 43, 104, 84, 78, 70, 32, -24, -64, 8, 97, 1, 22, -103, + 114, 24, -121, -52, 72, -26, 10, 92, -117, -56, -88, -127, 16, 69, 40, 64, -46, 12, 5, + 57, -125, -114, 77, 34, 28, -47, 82, -25, -20, -103, -97, -101, 24, 0, 59, 32, 9, 72, + -23, 81, 34, 66, 2, 24, -112, -124, -87, 33, -64, -80, -64, -96, 2, -109, 74, 74, -46, + 41, 4, 34, -127, -126, -120, -104, 65, 10, -64, 88, -73, -59, 86, 122, 0, 112, -96, 18, + -28, -48, -125, 56, -95, -128, -16, 80, 72, 56, -46, -40, 51, -86, 39, -52, -23, 50, 16, + 103, -70, 32, 16, -124, -88, 69, 76, 40, 0, 66, 86, -28, 97, -79, -78, -122, -13, 32, + 10, 126, -68, 46, 1, 37, -60, -51, 107, 76, 10, 72, -109, -3, 87, 6, 0, 26, 71, 65, 9, + 50, -46, -57, -49, 2, -61, -6, -39, 96, -5, 0, 93, 53, -96, 90, 40, 16, -96, 13, 76, 7, + -89, -127, 32, -46, 17, -93, -31, 99, -31, 114, 67, 8, 77, 69, -20, 125, -123, -38, -70, + -89, -77, -126, 42, 5, 26, 35, 84, 15, 22, -116, 20, -97, -126, -114, -99, 46, 1, 67, + -120, 107, 106, -48, -119, -80, 14, -38, 82, -125, 64, -31, -112, 75, 25, 2, 29, 8, -82, + -94, 42, 76, -104, -30, 48, 2, 100, -128, -36, -92, -69, 126, 9, -26, -68, 77, 19, 27, + -126, 1, -99, 102, 82, -127, -44, 93, -91, 121, -60, -76, -64, 69, 66, -120, -19, 37, + 37, -103, 67, -106, -79, 61, -72, 10, 91, 0, 13, -119, 0, 0, 1, 53, 86, -111, 18, 33, + -65, 99, 64, 127, 5, 73, 34, 114, 2, -63, -5, 0, -124, -37, 38, 70, 69, -40, 39, 32, + -128, 64, 64, 121, -2, 64, 51, 7, -53, -94, 5, -94, 6, -20, 49, 8, 93, 97, -121, 53, + -11, 87, -116, 14, 14, -31, -112, 96, -114, 81, -109, -117, 28, 22, 120, -61, 88, -48, + 2, -93, -31, 22, 37, -51, 97, 88, 0, -120, 34, 24, 121, -47, 44, 0, 28, -57, -104, -117, + 18, 36, 7, -35, 96, -101, -19, 106, 2, -64, 50, -88, 115, 66, 54, 65, -64, -117, 4, 68, + 92, 41, 57, 83, -96, 6, 32, 91, 0, -61, -120, -10, 2, 1, 65, -88, 39, 4, -15, -36, -112, + -109, -80, 24, 35, 77, 66, -7, 46, -63, -128, -14, 17, 81, 24, 0, 104, 10, 32, -94, 120, + 98, -120, 8, 75, -12, 72, -62, 6, 110, 36, 67, 14, -74, 96, 1, 25, -31, 41, -111, -56, + 82, 68, 43, -126, 72, 50, 122, -7, -76, 35, 16, 94, -59, -120, 115, 82, -75, -125, -123, + 46, 85, -75, 46, 16, 1, 41, -80, -12, -124, 16, -20, 36, 82, 0, -127, -117, 72, -30, 80, + 36, 72, 22, 15, -124, -54, -70, 32, 100, 49, 52, -127, 72, -127, 16, 33, 20, 1, 42, 98, + 81, 29, -29, 73, 80, -47, 70, -34, 47, -75, 8, -120, 75, -47, 33, 63, 84, -89, -119, 32, + -6, -74, 11, -23, -125, 80, -91, -76, 62, -20, 29, 62, 31, 23, -41, 65, 7, 13, 34, 24, + 68, -62, -79, -37, -125, 27, -56, 112, 47, -119, 21, 7, 57, 24, 15, -28, 6, 98, -83, + -74, 92, -94, 66, 25, 24, 85, 13, 34, 117, -23, 12, 98, 46, 120, 6, 36, -40, 111, 26, 0, + -30, -110, 49, 3, 47, 22, -85, -106, -112, 36, -88, -40, 71, -105, 7, -66, 96, 33, 28, + 58, 56, -92, -92, -80, 77, 48, 2, 0, -96, 24, -107, -2, -120, 67, 33, -28, 24, 66, 32, + 104, 77, 95, 77, 23, 52}; + + + static byte[] PINYIN_CODE = new byte[]{104, 68, -109, -6, 33, 86, 0, 78, 127, 24, 33, 86, -127, + 21, 111, -59, 92, 40, 40, -117, -1, -15, 39, 39, 3, 19, 103, 49, 70, 49, 37, 69, 3, -84, + 69, 110, -84, 100, 19, 25, 41, -118, 96, 99, -3, -122, -127, -122, 87, 105, 43, 32, -81, + -113, -120, 0, 78, 58, 80, -120, -120, -87, -117, -12, 90, 104, 104, -49, 0, -118, -118, + 75, -64, 104, 0, -123, 84, 124, 121, 82, -90, -122, -10, -20, -2, 121, 104, 37, 37, 104, + 106, 0, -57, -118, -6, 103, 85, 88, 92, 69, 0, 0, 41, 0, 39, -127, -47, -126, 0, 39, 0, + 0, -68, -75, 0, 17, 85, 100, 90, 30, -50, 93, 0, 0, 0, 0, -4, -123, 107, 93, -75, -81, + 104, -115, -90, 0, 111, -124, 39, 39, 80, 41, 111, -98, 111, 114, 121, -6, 84, -120, 49, + 54, 98, 98, 99, 90, 99, -6, 99, -127, 70, 79, -110, 57, -123, 111, 104, 32, 118, -51, 0, + 88, -120, 68, -84, 118, -120, 103, 0, 20, 110, 90, 58, -85, 76, 80, 12, 12, -127, 0, 79, + 104, 37, 12, -90, 68, 120, -121, -7, 40, 6, 127, -121, -122, 19, 13, 49, 88, 24, -74, 0, + 25, -112, 39, 57, 127, 90, 87, 87, 30, 119, 69, 12, -4, 93, 96, 63, 57, -80, 104, 34, + 33, 22, 33, 104, -51, -62, 12, -126, 34, 101, -4, -122, -15, 78, 84, -125, -126, 102, + 87, 25, 12, 79, 86, 63, 84, -122, -6, -18, 111, 66, 75, 81, 104, 91, -110, 104, -127, 2, + 84, -127, 90, 82, 94, -121, 11, 36, 90, 60, -122, 110, -128, 126, 111, 53, 114, 24, 80, + 43, 35, 99, 87, 33, 33, -74, 25, 98, 91, 80, -120, 38, 96, -46, 20, 102, -40, -40, 90, + 8, 95, -80, -121, 37, 4, 49, 13, 49, -126, -15, 104, 49, 2, -124, 65, 112, -68, 58, + -120, 21, 4, 14, 34, 48, 80, 63, -120, -105, 110, 101, 64, 126, 115, 14, 75, 35, 111, + 104, 88, -105, 101, -34, 69, -40, 96, -117, 109, 76, -4, 0, -113, 0, -18, 123, 115, -91, + 88, 96, 101, 7, 82, -55, -126, -49, 19, -127, 118, -128, 107, 5, 66, -123, 48, 104, 39, + 92, 37, 75, -111, -123, 92, -94, 104, 38, -102, 106, -87, 106, 39, -60, -120, 95, 110, + 3, -76, -52, 80, -74, 70, 30, 38, 98, 100, -121, 104, 17, -125, 86, -126, 116, -72, 0, + -123, -125, 27, -2, -101, 31, -34, -32, -121, 84, 120, -119, 37, -125, 55, 40, 0, -72, + -117, 41, 68, 37, 75, 20, -48, 114, 15, 73, 111, 85, 51, 77, 3, 95, -99, -103, 84, -114, + 104, 90, -92, -109, -2, -87, 109, 127, -120, 87, 24, -22, 52, 90, 85, -87, -59, -10, 10, + 111, 49, 86, 91, 94, 111, 64, 35, 40, 0, 100, -84, -87, -94, 49, -125, 94, 90, 115, + -117, 89, -22, -125, 16, 64, 85, 87, 99, 3, 11, 111, 91, 14, 38, 33, -123, 19, 117, 102, + 53, -86, 78, -94, 25, -111, 96, 105, 11, 65, 41, 41, -62, 60, 59, -115, 45, 92, -16, 60, + 120, 104, -6, 64, 93, -120, -122, 95, 33, -122, 84, -123, -105, -116, -111, -117, -4, + -40, -74, -113, 83, -73, 50, -88, 127, 70, -112, 12, 84, -117, -49, 23, -125, 125, 103, + -123, 30, 1, 0, 107, 37, -4, 100, -29, -122, 46, -126, -122, 80, 111, 19, 21, 64, 80, + -14, 100, 87, 60, 83, 77, 90, 35, 38, -111, 63, -105, 30, 68, 11, 103, 125, 102, 126, 3, + 100, 110, -125, 95, 124, 31, 90, 14, -123, -111, -59, -127, 104, 90, 98, 49, 73, 27, + -125, -24, 70, 70, 11, 115, -77, -122, 80, 86, 33, -98, 51, 38, 52, 86, 90, 112, 15, + -87, 17, 114, 101, -69, 9, 65, 60, 114, -122, 85, 32, -4, -115, 25, 41, 24, 11, 89, 109, + 102, 57, 56, 79, 82, 19, -126, 57, 116, 60, 0, 18, 41, -28, 117, -89, 53, 109, 119, + -111, -16, 50, 5, 43, 111, 125, -109, 33, -3, -3, 38, 30, 112, 127, 1, 100, 63, 85, -77, + 11, -13, -121, -85, -76, -67, -4, 87, 3, 107, 70, -117, 88, 32, -2, -119, 73, -106, -7, + 85, -91, 33, 106, -83, -6, 62, 32, 80, 127, 83, 126, 43, 67, 58, -123, -118, 29, 86, 87, + -115, 77, -123, -125, 69, -81, 20, 102, 87, 52, 87, -124, -56, 103, -121, -126, -2, -15, + 87, -121, 2, 23, 104, -114, -32, 32, 104, 59, -120, 96, -101, -125, 41, 58, -123, 30, + 116, 0, 18, 3, 17, 58, 40, 31, -93, -40, -121, -4, -61, 84, -42, 2, -40, 33, -82, -89, + -72, -99, 10, 72, 16, 117, -123, 49, 110, 114, 0, 36, -87, 63, 80, -78, 41, 32, 9, 41, + 126, -87, -73, 117, -28, 60, 100, -89, -47, 80, 84, 114, 117, 112, 93, 39, -128, 93, 87, + 106, 74, -108, 74, -59, 71, 33, 80, 74, 80, -121, 71, 49, 100, 100, 39, 39, 59, -4, 71, + 86, -65, 91, 71, 7, -120, -87, -99, 17, 79, -44, 5, -84, 111, 6, 100, -79, 85, 0, -93, + 100, 65, 105, 92, 19, -6, -117, 65, -112, 0, 101, -125, 40, -127, 104, -127, 32, -119, + -65, 8, -44, 112, -65, 94, 8, 27, -119, 27, 116, 103, -119, -65, -121, -65, 101, 95, + -59, -60, 15, 106, 90, -111, -114, -32, 104, -60, 39, 105, -61, -122, -107, 112, -55, + -104, 0, 90, 90, -60, 19, 70, 58, 94, 87, 19, 121, 39, -115, 121, -99, 103, -88, -21, + 90, -56, 70, 87, -82, 86, -125, -120, 41, -63, 33, -6, 102, -114, 50, -120, -84, 1, 66, + -80, 70, 93, -125, 106, 50, 2, -87, 25, -55, -114, 53, 49, 76, -121, -81, -81, -34, 85, + 72, -127, 83, 83, 83, 87, -117, 41, 0, 87, 0, 0, 90, 87, -10, 87, -112, 125, -112, 93, + 62, -10, 4, 93, -101, 71, 5, 41, -127, 59, 112, 112, 119, 60, 66, 60, 12, 12, 44, 86, + -1, 104, -127, -111, -4, 54, 41, 81, -127, 58, 92, 122, 78, -115, -87, 113, -82, -79, + 120, 94, 44, 90, 41, 4, -117, 32, -56, -80, -122, -21, 17, -122, -122, 10, -87, 32, 17, + 32, -120, 103, 98, 60, 44, -98, -103, 76, 80, -123, 42, 5, 30, 48, -108, -122, 107, 48, + 107, -112, 76, -127, 64, -120, -77, -73, 120, 112, 55, 97, -108, -95, -4, 30, 43, 103, + -125, 55, -87, 64, 85, -8, 32, -6, 44, -112, 94, 78, 20, -127, 76, 1, 100, -113, -125, + -127, 20, 100, -117, -128, 38, -125, 76, 73, 84, 103, 90, 38, -125, 96, 124, -112, 44, + -116, 32, 72, -76, -87, 89, 32, -13, -104, -123, 103, -2, -115, 122, 124, -113, -85, + -117, -15, -79, 107, -123, 107, -125, -125, 60, -128, -127, -125, 104, -125, -123, 32, + 52, -53, -87, -120, -87, 99, 5, 8, 100, -126, 84, -68, -82, -120, -106, 90, -123, 70, + -120, -30, -122, 4, 34, 104, -120, -53, -87, -120, -91, -91, -116, -104, 101, 76, 89, + -52, -99, -122, -82, 115, 39, -108, -120, 114, 20, -56, 38, -92, 109, 109, -59, -108, + 98, -116, 1, -76, 21, -61, -94, -90, -112, -59, 70, 95, 95, -111, 84, 104, 98, 82, 38, + -91, -51, -76, -13, 39, -127, 0, -3, -123, 5, 88, 104, -2, 83, -116, 69, -117, 58, 90, + -68, 98, 98, -72, -87, 35, 9, 5, 10, 34, 114, -118, 10, 101, 84, 114, 0, 0, 92, 92, 10, + 49, 0, 93, -16, -117, 61, 96, -7, 3, -19, 90, 100, 56, -118, 2, 14, 122, 11, -46, 38, + 84, -118, 104, 115, -124, -110, -124, -99, 121, 86, 4, 83, 107, -1, 25, -99, 85, 121, + 111, 107, -98, 126, 58, -98, -85, -85, 53, 72, -118, 4, 85, -15, 4, 104, 3, 100, 15, + -40, 4, 39, 91, -4, -39, 22, -109, 38, 84, 126, 8, 39, 85, 78, 122, 90, 78, 11, -109, + -113, 90, 58, -68, -48, 58, -127, 20, 43, 21, -99, 15, 21, 126, -113, -76, 110, -76, 85, + 103, 83, 90, -122, -122, 80, 4, 2, -123, -65, 106, 80, 34, -127, 6, -75, 39, -116, 90, + 95, -121, 6, 84, -127, 77, 1, 85, 0, 33, 112, 77, 68, -87, -127, 3, -87, 99, 99, 100, + 35, -123, 124, -20, 0, -108, 99, -123, 27, -20, 64, -87, 35, 120, 68, -107, 55, 85, 112, + 27, 112, 88, 100, -87, -115, 30, 65, 41, -118, 0, 5, 107, 100, 49, -87, 33, -93, -87, + 100, 100, 112, 49, 49, -81, 3, 4, 4, 0, -89, 72, 87, -117, 24, 24, 24, 24, 24, 2, 57, + 110, 30, -127, 110, 45, 83, 40, 104, 6, 82, 21, 39, 41, -115, 4, 40, 15, 95, -126, -21, + 51, -127, 111, 51, 67, 19, 49, -104, 102, -117, -80, 103, 61, -104, -123, -123, -128, 6, + 68, -108, 58, 38, 39, 110, 3, -9, 103, 114, 49, 59, 38, -90, 66, -127, 0, 119, -57, 111, + -66, 38, 96, 96, 102, -112, 115, -127, 66, 54, 69, -55, 120, -87, 71, 88, 124, 115, 103, + -72, 1, -69, -24, 97, 104, -114, 40, -81, 74, 106, 85, 14, 0, 0, -122, -8, 89, 6, 75, + 86, 77, 112, 68, 113, 47, -6, 121, -123, 106, 84, 84, 34, -50, 47, 85, 45, 71, 81, 120, + -24, 84, 95, 99, -114, -72, 77, 96, -63, 57, -6, 37, 84, 95, 90, -123, 119, 38, 38, -50, + 74, -70, 104, 57, -24, -87, 11, 112, 109, 0, -3, 84, 77, 39, 5, -17, 81, -40, -52, -80, + 8, 110, 63, -121, 39, -121, 126, -80, 104, -6, -10, -112, 103, 48, 80, 95, 115, -46, 86, + -18, 104, 89, 37, 121, -55, 56, 4, -117, 93, 115, 75, 76, -8, -19, 17, 90, 14, 115, 115, + 115, 111, -118, 109, 90, 56, -121, 76, -113, 102, -113, -105, 21, -78, 70, -34, 124, 49, + 87, -128, -6, 80, 77, 106, 124, 85, 104, -82, -112, -57, -60, -123, 102, -127, -121, 96, + 43, 117, 89, -108, 126, -102, 123, 61, 87, 77, 96, 94, 109, 100, -91, 104, 2, -11, 37, + 69, 119, 93, 76, 76, 110, 116, 110, 63, -22, 88, 2, 98, -99, 99, 56, 89, 14, 126, 0, + 122, 0, -101, 76, 0, -127, -32, -52, 108, 114, 112, -78, -8, -66, 96, 77, 38, 34, -87, + -50, -109, 115, -103, 89, 87, -91, 11, -127, 124, -84, 6, -60, -90, 54, 89, 21, 112, + 118, 99, 48, 96, 110, 100, 102, 102, 7, 112, 56, 46, 104, 2, -126, 71, 87, 105, -87, 85, + 60, -105, -54, 35, 84, 119, 99, 71, -6, 63, 0, -69, 0, 100, 71, 0, -91, -84, 56, 119, + 124, 0, 101, -127, -105, 83, 87, 106, 121, -6, 40, 80, 42, 33, 80, -87, -3, 3, -122, + 108, -39, 111, 65, -94, 30, 85, 75, 121, 2, -121, -31, -107, -113, -113, 33, 63, 118, + -81, 1, 89, 88, 74, 84, 81, 53, -122, 121, -6, -6, 61, 58, 58, 78, -112, 14, 53, 47, + 115, 99, -6, -127, 85, -84, 87, -15, 30, -95, 120, 1, 103, -23, -127, 27, -117, -36, + 109, -73, 100, 63, 5, 59, 20, 68, -92, 89, 0, 60, 38, 64, 3, -118, 58, -113, 109, 80, + -48, 32, 111, -127, -95, -122, 120, 112, 67, -121, 31, -101, 11, 111, 106, 117, 102, 83, + -59, 121, 114, 43, 126, 124, 124, 85, 115, -127, -98, -122, 80, 30, 95, 125, 72, -36, + 96, -84, 111, 25, 38, -2, 100, 58, -17, 39, -87, 108, 124, 80, -58, 107, -17, 0, -98, + 85, 111, -122, -77, -103, 26, -128, 64, 102, 115, 1, 94, -3, 27, 109, 52, 119, 90, 2, + 56, -69, 30, 111, -108, 56, 25, 36, 17, 51, 100, -127, -20, 84, -4, 39, 96, -112, -122, + -73, 82, 76, 49, 38, 114, 56, -126, 111, 56, 0, -36, 115, 0, 23, -41, 96, -50, 64, 2, 0, + 69, 14, 5, 5, -85, 53, -127, -53, 51, 51, 59, 63, -6, -123, 39, -123, -112, 59, 24, 26, + -126, 0, 89, -13, -77, 91, 102, 89, 121, 126, 109, -24, 87, 120, 33, 95, -9, 61, -69, + -69, 121, -89, 72, 91, 60, 103, 13, 107, 0, -123, -60, 89, 122, -68, 8, -105, -16, -91, + 89, -127, -120, 34, -98, -107, 89, 49, 114, 90, -83, -2, 85, 95, 32, 58, 116, 98, 84, + -106, -21, 38, -98, 24, 117, 51, 58, 111, 74, 37, -123, 103, 85, -6, 114, -85, 95, 62, + 126, 106, -7, -115, 0, 98, -36, -76, 49, 100, 107, 56, 126, -25, -121, -121, -32, 126, + 126, -6, 77, 119, 104, 39, -123, 112, 2, 109, 97, -101, 111, -17, 60, 91, 91, 75, 59, 0, + 23, -15, -15, 106, -107, -34, 63, 112, 57, -128, 17, 114, 86, 100, 76, -15, 40, -127, + -121, 114, 64, 33, 0, 0, 22, 64, -76, 126, 10, 110, -36, 106, 121, -53, 125, -127, -87, + -79, 0, -47, 89, -53, 100, -87, -76, -78, -53, 58, 36, -11, -15, 88, -128, -53, 85, 76, + -103, 100, 32, 107, 9, 65, -95, 57, 89, -123, 47, 124, -128, -117, -36, 89, 22, -87, 32, + 31, -87, 104, -73, -47, 117, 52, 85, 0, -125, 115, -120, -93, -36, -47, 0, 0, 80, 126, + 106, 3, 49, -35, -125, 126, 91, 106, -48, 72, 72, 75, -110, 112, -119, -14, 114, 49, + 121, 126, 112, 77, 109, -97, 49, 80, 71, 80, -74, 109, -114, 14, -80, 102, 109, 58, 109, + 71, 110, 109, 106, 127, -7, 111, 112, 112, -74, 5, 111, 1, 109, 45, 80, 112, 5, -103, + -7, 112, 112, 77, 71, 71, 71, 72, -71, 126, 104, 112, -75, -75, 71, 99, 71, 68, 38, 100, + -76, 0, 99, 116, 80, 96, 111, 84, 107, -15, 104, 63, -4, -4, -125, -113, 59, -5, 0, 0, + -99, 33, -6, -36, -53, -127, -126, -123, -123, 8, 98, 70, 0, 86, -114, -106, 75, 84, 86, + 12, 59, -111, 123, -105, -106, 14, 92, 63, -120, -127, -101, 63, -120, -125, 59, -87, 6, + 84, 86, -115, -9, -21, 60, -97, 4, 59, -123, 75, 93, -10, 65, 76, -40, 58, -15, -119, + 101, 88, 5, -79, 3, -51, -108, 101, 97, 6, 38, 35, -80, -120, 90, 121, -123, 45, -95, + -78, -78, -76, 5, 0, -19, 0, 92, 69, -127, -108, -76, 48, 38, -89, 92, 106, 120, 74, + -128, 90, 106, 102, 76, 76, 107, 30, 101, 106, 82, 101, 112, 67, 90, -107, 33, 40, 77, + 0, 65, 119, 99, -102, 56, 0, 59, -112, 0, -46, 3, 92, 87, 124, 9, -18, 6, 104, 106, 112, + 95, 45, 28, 99, 2, -16, 84, 6, 109, -114, -126, 63, -68, -92, 96, 37, 32, -121, -127, + -82, -82, -7, 37, 0, 21, 39, 98, 109, -119, 103, -39, 63, 111, 21, 84, -116, 54, -15, + 37, 78, -117, -74, -124, -105, -122, 70, 57, 59, 3, 23, 41, 13, -111, -123, 76, 104, + -123, 104, -18, -127, -114, -6, 26, -117, -40, -103, -108, 60, -97, -40, -125, 74, -121, + 94, 111, 77, -16, 102, 71, -88, 0, 99, -4, 0, 3, 36, 76, -46, 71, 37, 106, 127, 14, -85, + 109, 67, -117, 120, 10, 10, 111, 63, -65, -122, 18, 77, 99, -111, -111, 111, 125, 77, + 102, 100, 10, -127, -63, 33, 72, 75, 3, 87, -122, -122, -125, 118, 94, 43, -125, 0, -89, + 94, 125, -88, 73, 78, 96, -127, -127, -101, 107, 57, 37, 109, -112, 52, 52, 39, -60, 57, + 82, 37, 71, 60, -2, -122, -87, -16, 9, 23, 118, 74, 65, 84, 37, 98, 96, -125, 2, 100, + 100, -111, 65, 112, 81, 90, -79, 0, -92, 33, -16, 13, 36, -76, -76, -24, -4, -63, -53, + -117, 45, 41, -77, 38, -67, 16, -120, 27, 41, 63, 127, -111, 109, 65, 36, -123, -127, + 109, -3, -121, 63, 33, -51, 53, 100, 57, 123, -6, -3, -84, 0, -115, -2, 123, 95, 32, 32, + 6, -7, -101, 70, 83, 6, -53, 75, 75, -106, -107, 38, 76, 76, 59, 62, -51, 86, 125, 59, + 56, 103, 41, 0, 5, -3, -127, -2, -107, 104, -15, 14, 65, -124, 103, 109, 97, 59, -93, + -117, 123, 59, 9, -4, 96, -93, -60, 115, -112, 99, 60, 114, 18, 0, -89, -99, -76, 100, + 59, 80, 123, -78, -78, 19, -87, -81, 9, 32, 98, 100, -89, 6, 0, 39, 12, 0, -116, -116, + 38, 104, -68, -2, -120, -116, 121, 121, -97, 104, 121, 95, -97, 40, -66, -106, 40, 104, + -123, 102, 41, 88, 87, 11, 0, 15, 54, 7, -80, 90, -105, 86, 93, 0, -46, 86, -98, 85, 77, + 112, -65, 52, 76, 76, 103, 1, 0, 101, 101, -6, -61, -61, 106, -128, 36, 56, 120, 65, 58, + 90, 104, 102, 101, 113, 95, 39, 12, 58, 70, 100, 14, 104, -102, -126, 76, 0, -99, 114, + -126, 6, 79, -85, 124, 63, 100, -19, -116, -6, -49, 87, 90, 86, 65, 0, -98, -110, 124, + -6, -112, 35, 12, 104, -124, 61, -116, 12, 85, 125, 85, 66, 54, 13, 65, 5, 35, 82, -21, + 5, 84, 5, -124, -85, 76, 114, -124, 39, 86, -128, 11, -85, 35, -27, -30, 68, -49, -4, + -125, 57, -118, -48, 30, 114, 87, 83, -127, 48, 17, 85, 79, 119, -116, 90, -69, 58, 12, + 90, -120, 100, 90, 81, -122, -23, 72, -127, -106, -122, 102, -121, 114, -58, -18, 38, + 113, -116, -33, 100, -50, 91, 86, 14, 111, 75, 87, 112, 84, 84, 111, 107, 72, 6, -40, + -121, -121, -128, 56, -49, 112, 70, 96, -123, 77, -63, -53, -6, 14, 37, -1, 77, 115, 95, + 82, -124, -40, 8, -51, 90, -80, -112, -112, 39, 8, 32, 101, -4, -122, 102, 49, 92, 80, + -112, -117, 32, -11, 12, 102, 69, -124, 41, -127, 92, 33, -96, -116, -123, 101, -91, + -125, -125, 104, -39, -123, -127, -127, 87, 118, 106, -114, -102, 100, -55, -82, -18, + 100, 110, 100, 30, 87, 106, 38, 107, 5, -112, 50, 80, 119, 76, -77, 99, 10, -123, -75, + -10, 87, 34, -87, 37, 90, -66, 0, 56, -51, 80, -108, -94, 47, 68, -38, -106, -48, 111, + -50, -18, 54, -116, 37, -123, 112, 63, -116, 77, -11, 73, 87, -59, 84, 100, 84, 85, 100, + 111, 49, 111, 76, -87, 87, -117, 4, 45, -6, 87, -115, 70, 33, -76, 2, 77, 77, -77, -59, + 49, -8, -117, -9, 23, -80, 78, 16, 89, 41, -6, 126, 90, 83, 19, 59, 85, 0, -122, 65, + -40, 5, -120, 127, -120, -4, 65, 92, 121, 78, -94, 14, 106, 40, 47, 90, -120, -74, 100, + -93, -97, 106, 99, 0, -87, 65, 87, 0, 122, 107, 32, 37, 68, 101, 102, 84, -48, 47, -126, + 70, 95, 111, 80, 64, 16, -63, 58, 18, 0, 0, 84, -4, 46, -65, 90, -122, 73, 85, -122, + -63, 125, -59, 3, 107, 96, 0, 80, -63, 112, -125, 3, 64, 90, 75, -85, -65, 8, 49, -14, + 80, 76, -118, 121, 5, 0, 10, 95, 70, 107, -110, 102, -15, 85, 112, 107, 15, 17, 38, -79, + -63, -21, 5, -69, 101, -98, 0, -126, 26, -125, 112, 30, 109, -55, 107, -127, 52, -37, + 87, 61, -20, -92, -37, 10, 2, -15, -11, 104, -13, 111, -89, 96, -67, 104, 127, -110, + 109, -40, -87, 63, 107, 100, -121, -117, 33, 27, 112, -43, -91, -53, -127, 121, 121, 5, + -43, -3, 0, 14, 102, 84, -2, 75, 126, -65, 87, 87, -53, -83, -85, 122, 107, 62, -123, + 95, 0, 122, 85, 126, 10, 85, 100, 32, -123, -63, 83, 83, 87, 104, 80, 32, 83, 39, 14, + 32, 54, -3, -85, 124, 0, -37, 70, 104, 24, 2, -38, -34, -69, 66, 40, -121, 48, 111, -11, + 0, 95, -49, 100, 58, 107, 24, -37, 0, 107, -59, 0, -69, 37, 92, -40, 72, -79, 112, -93, + 100, 45, -80, -123, -38, -93, 87, 107, 45, 43, 5, -60, -87, -75, 100, -120, -93, -112, + -122, -115, -115, -105, 114, -112, -112, 54, 55, 90, 11, -112, 89, 91, -61, 49, 58, 10, + -127, 102, -30, 97, 0, 32, 111, -75, 55, -46, -57, 49, -125, 41, 32, 99, -112, -40, 90, + -112, -87, 97, 20, 17, -49, -36, -36, 107, -75, -59, -34, 15, 57, 107, 125, 2, 111, 40, + 3, 71, 50, 78, 16, 102, 119, 104, -120, -114, -60, 104, 59, 119, -111, 105, -121, 68, + 78, 104, 10, 39, 39, 39, 37, -108, 96, 39, 110, 124, 104, 66, 39, 87, 100, 37, 7, 100, + 89, 116, 124, 10, 111, 100, 89, -126, 37, 36, 15, 125, -60, -104, -100, 18, 52, 23, 117, + -127, 112, -127, 106, -60, -104, 1, 115, -125, -125, 90, -34, 19, 124, -63, 0, 112, 111, + 39, -34, -121, -34, -123, 111, 10, -100, -34, 0, -53, 30, -117, 103, 0, 121, 84, -83, + 39, -34, 125, 37, 80, 90, -100, 126, -83, -114, 124, 104, 104, 10, 0, 39, 10, 87, 54, + 74, 49, 98, 60, -72, 74, 40, -9, 87, -117, 90, 35, -108, -124, -124, -117, 80, -106, 98, + 41, 74, 60, 89, -127, 34, 80, 80, 80, 91, -125, 41, 36, 33, 33, 112, 91, 33, -83, 87, + 87, 0, 79, 79, 110, -83, -83, 102, -66, 79, 79, 79, 91, 102, 76, -98, -122, -118, 93, + 102, 93, 93, 93, 93, 39, 106, 38, -109, -40, -121, 80, -37, -117, -15, 29, 85, 14, -117, + -122, 65, 4, 64, -122, 84, 66, 39, 39, -10, -127, 90, 36, 85, -40, 126, 85, 0, -67, 77, + -77, -10, 64, 85, 41, 90, 71, -72, -72, 85, 29, -72, -117, 90, -117, -115, -83, -115, + 41, 85, 35, 74, -40, 32, 76, 87, -87, 77, 0, 0, -78, 104, -6, 12, 84, 112, 37, 111, 41, + 54, -6, 0, 113, 8, 102, 4, 99, 84, -122, 77, -127, -4, 86, 78, -6, 28, -4, -6, 30, -122, + 4, 94, 87, 5, -93, 60, 6, 125, -105, 101, -117, 94, -108, 101, 97, 20, -87, 66, 4, 100, + 90, 94, -126, -80, 75, -18, 110, 57, -99, 113, 4, 121, -9, -56, 3, 66, -80, 38, 0, 70, + 0, -98, 94, -65, 69, 97, 104, 0, 115, -108, -73, 77, 90, 98, 67, -76, -92, 80, 92, 5, + 69, 104, -51, 39, 3, 80, 121, -123, -60, -87, -127, 69, -98, 110, 0, 86, -87, 102, -123, + -124, -75, -123, 77, 77, 111, 103, 21, -2, 7, 87, 87, -46, -87, 110, 87, 119, 60, 37, + 37, 71, 99, -114, 114, 86, 106, 84, -92, -111, -91, -94, 87, 6, -105, 39, 39, 57, 0, + 122, -117, -94, -6, -56, -97, -97, -109, 102, 53, 99, 99, 94, -74, -74, -88, -115, 76, + 37, 109, 106, 70, 112, -124, 80, 102, -15, 100, 50, -122, 13, -109, -115, 70, 126, 102, + 106, -112, 120, 125, 111, 80, 101, 87, 3, 75, 64, 104, -123, 39, 116, 102, 77, -120, + -111, -72, 100, -63, 93, -127, -127, 124, 68, 38, -63, -4, 84, 111, -111, -93, -122, + 100, 100, 80, -111, 30, 54, 15, -108, 0, 111, -6, -77, 71, 74, 85, 82, 25, 59, 15, -122, + 2, -79, 84, 50, -2, -112, 80, 13, 65, 55, -4, 109, -36, 55, -127, 0, 0, 50, -111, -124, + -83, 0, 32, 63, 28, 68, 71, -77, 127, 126, 126, 5, 26, 4, -3, -107, -107, 60, 60, 85, + 111, 20, -78, 88, 29, 20, 0, -123, 100, -91, 126, -81, -83, -83, -121, 62, 76, -106, + -123, 107, 102, -2, 102, -115, 126, 104, 97, -46, 103, 103, 104, 77, 87, -127, 90, -108, + 54, 63, 5, -107, 0, 104, 15, 60, -80, 115, 111, 113, 106, 0, -122, -87, 54, -78, -78, + 65, 107, 85, -117, 32, 107, -98, 100, 80, -46, 5, 34, 52, -75, 65, 65, -36, 100, 100, + 100, -46, 100, 43, 107, 43, -121, 125, -120, 98, 34, 34, -82, 100, -105, -2, -117, 100, + 0, 84, 0, 0, 30, 3, 3, -127, 104, 49, 6, -123, -128, 88, 104, -121, 98, -116, 0, 98, + -121, 90, 115, 14, 39, 21, 68, 43, 83, -36, 39, 86, -23, -123, 85, 121, 58, 80, 127, 60, + 57, -69, -18, -23, 67, 90, -85, -123, -121, 20, -123, 63, -53, 104, 104, -10, -5, -116, + 17, 43, 57, -125, 46, -2, -125, 39, 7, 85, 9, 57, 107, 40, -10, 127, 30, 78, 57, 80, 33, + 30, -6, 120, 109, -65, 72, 120, -125, 95, -60, 80, 83, 90, 104, 9, -10, 0, 100, -21, + 125, 60, -60, -126, 63, 126, -122, 28, -67, -51, 16, 109, 120, -51, 9, 127, -119, 32, + 90, -123, 121, 83, 44, 14, 14, 0, -60, -2, 58, 86, -61, 9, 40, -57, 41, -122, 87, -93, + 93, -10, -39, -125, 19, 19, 92, 93, 102, 124, 110, 110, -127, 106, -15, 68, 120, 106, + -116, -53, 1, 14, 0, 75, 44, 107, 99, 7, -122, 95, -76, 84, 0, -103, 107, 63, -19, 65, + 99, -58, 99, 48, 90, 69, -20, 85, 88, 104, -123, 66, -123, 94, 72, -105, 89, 71, 107, + -103, -20, 68, 110, 21, 19, 37, -94, 14, -127, 3, 41, -110, 109, 75, 50, 41, 1, 111, + 111, -58, 51, 27, 88, 85, -118, 115, 126, -79, 30, -85, -92, 51, -125, -8, 1, -118, + -118, 0, 5, -96, -77, 106, -83, 57, -76, 104, 41, 32, 71, 49, 91, -58, 33, 84, 85, 106, + 0, 104, 14, -3, 90, -81, -81, -83, -76, 0, 107, 87, 68, 109, -87, 68, 106, 98, 100, 68, + 63, -9, -125, 126, -49, 126, 100, -39, -112, 15, 104, -6, -32, 86, -117, 100, 104, 118, + 14, 104, 104, 80, 24, 39, 80, 39, 39, 100, 66, 106, 121, 90, 119, 84, 73, 38, -3, 6, 37, + 63, 127, -115, 61, 90, 63, -60, 87, 121, 34, -30, -120, -125, 104, -60, 5, 78, 34, 21, + 96, -120, 66, 127, -124, -3, 13, 58, -3, 14, 14, 35, 58, -125, 101, 0, 82, 14, -104, 0, + 17, 89, 58, -99, -3, 119, -60, -96, 78, -115, -127, -127, 107, 59, -76, -76, 72, 126, + -123, 126, 126, 104, 104, 104, 104, -128, -128, 32, 92, 127, 69, 100, 100, 111, 38, 23, + 16, 66, 18, -16, 109, -13, 127, 107, 38, 38, -113, 75, -127, -20, -122, 104, 79, 35, 14, + 63, -80, 90, 79, -124, 51, 79, -120, 57, 85, 98, 117, 101, 123, -72, 120, 79, 37, -123, + 95, -120, 71, 49, 0, -94, 49, 61, -22, 85, 0, -6, 33, -123, 49, -121, -94, 111, 90, + -122, -125, 38, -126, 15, 125, 90, 98, 80, -20, 102, 80, 85, -124, -13, 38, 61, -124, + -123, 17, 61, 39, 35, -123, 80, -123, 126, -63, -78, 88, 10, 4, 91, 91, 14, 104, -90, + 12, 60, 68, 92, -127, 12, 12, 32, 59, 62, 62, 93, -6, 57, 54, -123, 79, -66, 85, 83, + 107, 65, -56, -56, -122, 39, 84, -127, 84, 85, 103, 110, 78, -111, -122, -101, 111, 15, + -123, 38, 53, 36, 58, 74, -4, -39, 127, 93, -33, 79, 87, 91, -110, 121, -112, 86, 123, + 58, 50, 84, -24, 33, 44, -117, 104, 10, 34, -56, -15, -105, 122, 101, -104, 8, -30, -46, + -124, -23, 21, 67, 121, 121, -117, 56, -85, 49, -121, 63, 57, 104, 71, 110, 90, -127, + -16, 92, 112, -40, 104, 90, 85, 14, 110, -1, 96, -111, 19, 125, 95, 41, -15, 85, 85, 59, + 0, -111, 74, 0, 0, 104, 38, -43, 98, 39, 85, -91, 118, -99, -52, -123, 90, -85, 66, 125, + 67, 114, -105, 107, 118, 85, 89, 41, 23, 121, 3, 101, 126, 126, 38, -126, 104, 93, 104, + -81, 126, -112, 95, 38, 88, -27, 117, 79, -108, 70, 65, 100, 5, 85, -5, 113, -16, -107, + 61, 126, 77, 0, 69, 100, -112, 27, -46, 114, -66, 109, 109, -116, -66, -97, -2, 113, + 111, 111, -122, 85, -127, -81, 64, 112, 114, -1, 64, 21, 104, -4, 126, 85, 11, -67, 104, + 118, 50, 5, 37, -98, 84, 84, 110, -87, -84, 124, 49, 104, 113, -87, -35, -46, 77, 6, 96, + -4, 84, -56, 49, 85, 11, 61, 53, 33, -62, -87, -127, 105, 105, 92, 60, -6, -105, 65, + -74, 85, -111, -97, -40, 1, 40, 75, 109, 32, -120, 78, 112, -121, -127, -81, 111, -128, + 115, 5, 100, 64, 64, -36, 79, 47, 121, 127, 85, 33, 91, 80, 126, 77, 19, -111, -125, + 109, 65, -117, 24, 37, 61, 11, -1, 24, 58, 105, 76, -46, 114, 88, -115, 67, 125, 46, 2, + 11, 92, 27, 15, 127, -111, 64, -2, 40, 11, 96, 80, 96, -4, 80, 111, 111, 14, 96, 124, + -56, 14, 104, -59, 109, -112, 59, 106, 77, 36, -52, -5, -108, 111, 2, -1, 100, -28, 93, + 114, -111, 23, -88, 86, 0, -98, -98, 6, 100, 114, 52, 52, -6, 102, 50, 125, 0, 102, + -117, 44, 57, 90, -112, -124, 109, 26, 55, 37, 20, -112, 112, 90, 127, 109, 101, -87, + 26, 61, 106, 48, 95, -4, 58, 125, 114, 37, -55, 0, 35, 49, -13, -53, -51, 109, 38, 24, + 24, 24, 53, -56, -40, 127, 69, 5, 45, -67, 105, 6, 119, -118, 126, -112, -85, -24, 50, + -121, 106, -72, 33, 80, 72, -67, -4, -127, 109, 1, -110, 63, -123, -72, -116, -6, -6, + 111, -10, -83, -111, 110, 44, -123, 69, 37, -6, 4, -16, 11, 17, 46, -123, 123, 38, -85, + -10, -98, 126, -2, 37, 106, 106, 85, 85, 58, 59, 76, 74, 74, 52, -115, 27, 89, 83, 86, + -91, -91, 39, 112, -6, 87, -56, -120, -83, 84, 24, -115, 40, 87, 59, 38, -15, 104, 41, + 87, -46, 58, 59, -120, 50, 112, -123, 80, 124, 70, 0, 0, 4, 26, -107, 90, 107, 5, -65, + 104, -81, 27, -114, 123, -62, -93, 2, -81, 100, 103, 86, 38, 111, 106, 57, -61, 2, -61, + 74, -6, -53, -93, -62, 40, -123, -28, -28, 100, 101, 20, -123, 92, -99, 110, 90, -79, + -57, 37, 0, 32, -61, -93, 123, 96, 9, 32, -127, -117, 124, 35, 104, -85, -48, -60, 60, + -115, 94, 94, -116, 96, 113, 84, -125, 95, 41, 15, 85, 37, 83, -122, 96, -125, -3, -128, + -3, 126, 70, -6, -126, 67, 23, -126, -127, 39, -111, -127, -98, 92, 62, 126, 44, 96, + -125, -122, 111, -125, 100, -76, 85, 126, 85, 85, 47, 57, 4, 121, 121, 121, 77, 39, -87, + -65, 121, -87, 84, 56, 15, 65, -119, 33, 104, 104, 32, 121, 85, 100, 40, 40, 23, 124, 3, + -90, -7, 6, 56, 13, 90, 0, 116, 75, 127, 66, -110, 111, -103, 112, 37, 30, 38, 102, + -104, 84, 75, -4, -123, 30, -96, -62, 26, 101, -33, 8, 35, 10, 85, -4, 8, -126, 111, 90, + 5, 85, -15, -123, -112, 77, 75, -128, 37, -127, 100, -99, 15, 34, -117, 81, 121, 113, + -115, 6, 0, -125, -124, 114, 78, -50, 104, 41, -119, -8, 70, 71, -110, -127, -8, 90, + -19, 6, 5, 120, 72, -104, -74, -3, 0, 121, 10, 19, -123, -16, 59, -7, -15, 58, 102, + -125, 124, 101, 10, 115, -40, 104, 63, 38, -15, 115, -53, -53, 36, 99, 40, 4, -56, 41, + -126, 90, 124, -120, 58, 31, -51, -39, -95, 90, -19, 8, -22, -81, -50, 104, -4, -117, + 75, 6, 75, 75, 5, -117, -113, -21, -128, 7, 7, 63, -40, -117, -96, -78, -125, -5, 109, + -93, -34, 20, 120, -4, 117, -96, 39, -122, -124, -35, 100, 100, 5, 44, 74, 117, -109, + 38, 90, 27, 126, -11, -118, 39, -50, 20, 38, 103, -123, -96, 76, 76, -123, -1, 3, -32, + -125, 96, -123, -102, 70, 17, 66, -82, 124, -72, 67, 76, -115, 0, -117, -123, -75, 99, + 83, 57, 90, -46, 59, -123, -124, -127, 126, 87, 0, 2, 75, -28, 55, 20, 99, 64, -125, 37, + 56, 56, -106, -63, -78, -117, -16, -125, 104, 68, 32, -28, 78, 90, 30, 87, -123, 84, + -114, -118, 69, -97, -128, 71, -113, -8, -72, 6, 112, 34, -36, -116, 35, 41, 103, -115, + 21, 124, 21, -114, 104, 125, -72, 51, 75, -91, 55, 9, -125, 124, 60, 0, 78, 0, -16, 35, + -82, -56, -62, 90, 7, -117, 60, 83, 2, -116, 113, -111, 36, 45, -122, 71, 12, -50, -39, + -28, -109, 83, 85, 87, 37, 65, 26, -74, 1, 94, 76, 40, 66, -8, 63, 127, 108, -127, 61, + -5, -6, -22, 41, -4, -80, 103, 99, -115, -124, -84, 103, 104, -128, 32, 68, -71, 23, 59, + 35, 19, -122, 64, -105, 73, 100, 55, -110, -117, 65, -4, -107, 7, 40, -122, -76, 104, 0, + 0, -123, 58, 0, 32, 26, 105, -16, 112, -28, -125, -124, -118, -125, 111, 100, -98, -48, + 119, 16, -15, 80, 23, -110, 96, -58, 64, -36, 30, 39, -111, -125, 104, 47, 118, 15, 101, + 124, 100, 117, 3, 95, 99, 83, -108, 42, -127, 64, -95, -95, 37, -112, -118, -118, 71, + -122, 126, 99, 39, 48, 35, 90, 112, -4, 103, 30, 124, 11, 102, 0, 0, -93, 81, 0, 32, 96, + -77, -111, 99, -123, 101, 0, 109, 6, 40, 42, 126, 55, 55, 20, 41, 15, 9, 55, 26, -108, + 102, 60, -123, -30, 90, -125, 51, 3, 95, 87, 48, 25, -121, -57, 77, 45, -28, 32, 57, + -122, 60, -21, 8, 56, -87, 61, 121, -123, 76, 86, -4, 81, -3, 36, -125, 77, 90, -28, 5, + 30, 124, 96, 84, 79, 35, 100, 35, 41, 7, 102, 18, 51, 59, 30, 32, 56, -83, 39, 44, 109, + 19, 87, 43, 63, -6, 0, 125, -85, 37, 38, 105, -76, -73, -77, -111, 92, 121, 124, 44, 60, + 122, 53, -49, -53, -124, 107, 107, -123, 5, -123, 38, -67, 32, -104, 41, 56, 72, -128, + -53, -53, -127, 32, -106, 16, -124, 106, 101, -4, -83, -127, 107, -115, -12, -12, -91, + 75, 87, 18, -98, 117, 104, 87, 37, 37, 22, -46, 118, 49, 112, 125, 56, -106, -39, -81, + -124, 126, -116, -123, -127, 26, 58, 58, 35, 20, 35, -115, 89, -83, 12, 90, -2, 20, 55, + -113, -117, 75, -7, 0, 75, -39, 0, 90, -76, -123, 52, 57, 112, -2, -119, -125, 93, 109, + -89, -96, -76, 32, -113, 120, -7, 47, -127, 59, 27, 26, 1, -120, 124, -122, 0, -101, 58, + 90, 96, -15, 20, 5, -117, 103, 0, 0, 51, -60, -127, 58, -113, 60, 92, -93, 22, -117, + 103, 17, 103, 103, -40, -128, -127, 18, -34, 96, -123, -122, -96, -53, -125, 90, -82, + 59, 7, 51, -76, -71, 10, -123, -21, 101, -89, 22, 41, 117, -39, 87, -114, -128, -71, + -95, 112, 107, -76, -78, -4, -4, 117, -4, -93, 24, 107, -63, 9, 32, 0, 52, 90, 35, -73, + -114, -60, -87, 117, -75, 59, -108, -87, 65, 76, 59, -123, -115, -93, -87, -47, -123, + 107, 107, -6, 91, -9, -9, 40, -109, 110, 92, 92, 100, 93, 8, 84, -124, 20, 65, -104, + -56, 84, 102, 96, 27, 89, -60, 41, 96, 63, 95, -123, -56, 36, -118, 37, 76, 111, 38, 5, + 7, 95, -123, 76, -85, -36, 14, 33, 65, 76, 104, 93, 24, -108, 100, 75, -6, 71, 89, 76, + -123, -120, 101, 86, 127, 41, 2, -2, 2, -124, 63, -125, 90, 41, -83, 4, 93, 85, -123, 0, + -2, -113, 104, -85, 14, -87, 97, 89, 81, 97, -6, -6, 125, 18, -115, 125, -92, 85, 8, 8, + -93, 111, -93, 80, 71, 38, -83, -126, 121, 90, -126, 111, -125, -123, 83, 66, 71, -121, + 38, 106, 90, -3, 126, 4, -113, 126, 73, -113, 49, 91, -113, -113, 0, -81, -113, 41, 73, + -120, 84, 90, 113, 84, 39, -18, 110, 0, -20, -6, 126, -65, -72, -18, -15, -79, 90, 84, + 96, -120, -120, -40, -109, -128, 104, -79, 34, -125, 0, 104, -6, -123, 83, -13, 83, 126, + 104, 54, 111, 84, -127, -127, -127, -128, 14, 58, -118, -123, 119, 90, 66, 98, 95, 91, + -95, 93, 112, 58, 63, 95, 32, 39, -99, 101, 39, 79, -56, -56, 74, 46, 84, 114, 11, 4, + 120, 8, -122, -97, 38, 121, 84, 114, 107, 33, 96, -55, 127, 86, 0, 121, 104, 85, 91, + 100, 120, 84, 59, 37, -117, 101, 117, 19, 92, 107, 96, -18, -125, -80, 46, 114, -63, + -105, -53, 15, 95, 127, -128, -111, 39, 39, 111, 85, 67, -65, -40, 33, 81, 70, 2, 19, 4, + -121, -78, 87, -99, 66, 34, 39, 125, 125, 96, -98, 95, -123, -121, -123, -121, 33, 69, + 119, 100, 92, 88, 31, 89, 103, 114, 126, 112, 112, -114, 78, 87, -97, -121, 85, 38, 38, + 21, -127, -127, 84, 112, 126, 114, 36, 78, 65, -113, -107, -121, -7, -120, 85, 32, 104, + 85, 1, -6, -120, 107, -125, 104, -123, 3, 78, -81, -84, 33, 79, 89, 117, 0, 96, 99, 104, + 86, 114, 126, 90, -56, -98, 115, 107, 72, 80, 41, 1, -65, -48, -125, -29, 3, 101, 46, + 102, 56, -7, -55, -123, -112, 95, 82, 33, -6, 114, 100, -87, 2, -127, 107, -62, 117, 90, + 114, -51, -53, 49, -40, 127, 126, 10, 112, 96, 43, -83, 87, 58, -120, -12, -81, 74, 85, + 104, -127, -99, 57, 103, 103, -87, 59, 69, 89, 85, 0, -128, 114, 104, 88, 92, 28, -123, + 10, -120, 0, 2, 103, 17, 41, -61, 98, 102, -7, -87, 36, -99, 67, 0, 100, -128, -76, 85, + 15, -78, -47, -73, -75, 31, 60, 100, 41, 113, 113, 4, 103, 99, -118, 121, 115, 41, 26, + 26, 38, -67, 29, 29, 64, -107, 24, 95, 126, 106, -1, 86, -15, 113, 110, 18, -16, 8, 90, + -80, 85, 4, 0, -27, 66, 48, -125, -92, -92, -116, -55, 125, 79, 74, 34, -127, -6, 107, + -111, 79, 69, -92, 0, -61, -78, -51, 62, 80, -53, 12, 124, -120, 41, 0, -120, 12, 6, -9, + 76, 76, 60, -87, 3, -127, -118, 14, 94, 68, 48, 30, 0, 115, 5, -4, 111, 93, 84, 30, 32, + 98, 83, 84, -112, -87, 92, 23, 54, 12, 34, -127, 63, 127, -66, 38, 104, 102, 100, 72, + 104, -6, 41, 94, 66, 0, 0, 0, -94, 32, -66, 101, -69, -58, 49, 112, 113, 85, 11, -122, + 70, 95, 102, 87, 41, 46, -23, 41, 122, 91, 40, -120, 40, 50, 8, 50, -127, 113, 114, 101, + -127, -65, -15, 14, 79, 4, 84, 86, 104, 90, -48, 85, 121, 99, 71, 98, -125, 102, -81, + 19, 77, -63, -128, 109, -123, -111, 114, 0, 71, 41, 119, 0, -87, -76, -125, 37, 50, -3, + 87, -48, 89, 87, -103, -10, 58, 85, -123, 104, 89, -126, -126, 101, 10, -53, 104, 103, + 25, 39, -36, 14, 75, 104, -80, 19, -40, -95, 115, 8, 83, -122, 57, 48, 101, 90, 20, -52, + 93, -6, 8, 16, -65, -128, 50, -127, 86, 110, 37, -117, 75, -105, -48, -34, 109, 63, + -123, 124, 30, 58, 102, 0, -118, 5, 90, -125, 20, 76, -108, -49, -120, 14, -79, 31, 124, + 49, -120, -18, 39, 104, 30, 102, 37, -118, 39, -123, -79, -63, 0, 15, 124, 0, 16, 126, + -123, -78, 70, -76, 0, -87, -93, 109, 41, 98, 44, -6, -125, -6, -87, 38, 88, -125, -87, + 52, 103, -111, 19, 12, 89, 20, 12, 19, -112, 40, 104, 48, 95, -120, -125, -107, 80, 80, + 111, 82, 100, -109, -91, 126, -87, 0, 101, 115, 98, -123, 38, 96, 116, -75, 82, -122, + 118, 107, 61, 106, 80, -99, 17, 3, 3, -116, 104, -113, -103, -123, 2, 69, 25, 25, 124, + -122, -118, 97, 76, -115, 111, 117, 0, 107, 0, 0, 126, 99, 10, -125, 59, -6, -2, 122, + 107, -124, -116, 98, 56, 56, -125, 11, 68, -96, -120, 20, 12, 90, 19, 69, -115, 85, -92, + -79, 87, -6, 81, -114, 93, 51, -84, 3, 68, 110, -63, 9, -78, -16, -116, 63, 96, 71, 119, + 5, 102, 14, 63, 112, -112, -123, 12, 11, 99, -125, 124, 78, -28, -126, 66, -127, 89, + -72, -100, 34, 28, 86, 50, -61, 84, -87, -87, 71, 28, 107, 56, -117, 64, 90, -97, -113, + 41, 32, 83, 80, -120, -87, 19, 0, 0, 61, -123, -94, -85, -125, -113, -80, -87, -6, 19, + -74, 49, -4, -59, -6, -6, 23, 108, 32, 61, 85, -22, 9, -8, 127, -111, 37, 119, -127, + -87, -16, 111, 111, 102, 127, 70, 60, 94, 79, 63, 85, 83, 37, 126, -6, 112, 100, 111, 5, + 104, 28, 12, 45, -88, -6, -113, 90, -108, -94, -110, -110, -128, 105, 86, 86, 36, 2, + -36, 78, 109, -76, 114, -122, 104, 40, -117, -117, 37, -105, -84, -3, -123, -115, 99, + -117, 11, -123, -113, -112, 18, -16, 68, 41, 32, 0, 0, -125, 107, 85, 72, -4, 0, -98, 0, + -73, -123, 0, 0, 0, 0, -16, 32, 0, 75, 28, 76, 103, 90, 80, 80, 73, -126, -111, -125, + 104, 37, 85, 100, 100, 43, 126, 46, 111, 115, 124, 83, 15, 14, 102, -128, 95, 21, 101, + -95, 100, 12, 127, -98, -122, -98, 49, 87, 90, 75, -127, -125}; + +} diff --git a/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinCode2.java b/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinCode2.java new file mode 100644 index 00000000..a83222e6 --- /dev/null +++ b/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinCode2.java @@ -0,0 +1,432 @@ +package org.rx.util.pinyin; + +/** + * Created by guyacong on 2015/9/28. + */ +//CHECKSTYLE:OFF +final class PinyinCode2 { + + private PinyinCode2() { + //no instance + } + + static byte[] PINYIN_CODE_PADDING = new byte[]{-128, -10, -95, 5, 7, 104, -96, 33, -18, 10, -7, + -19, 47, 84, 4, 100, 17, 69, 72, -126, 1, -126, 75, 32, -15, -40, 3, 90, -14, 67, -79, + 93, 36, -10, 6, 0, 112, -7, 113, 65, 8, -93, -31, 0, -46, 4, 48, 4, 72, -122, -118, 68, + -22, -63, 77, 2, 33, 56, -95, -57, 34, -24, 109, -44, -94, 76, 68, 79, 40, -71, -121, + -41, -48, 52, 4, -56, 103, 40, 14, 10, 0, -74, -111, 32, -49, 24, -89, 0, 18, -75, 26, + 127, 37, 23, 40, 43, 62, 50, 44, -61, -126, -65, 9, -86, 102, 4, -94, 67, -34, 113, 67, + -126, 48, -112, 27, 75, -88, -91, 41, -3, -126, -108, 91, -20, -112, 5, 7, -112, -61, + -95, -128, 56, 40, 7, -5, -90, 13, 71, -13, 86, -62, 112, 48, 2, -55, 20, -88, 34, 107, + 110, 46, -8, -27, 105, 47, -59, 41, 2, -86, 2, 95, -13, -54, 100, -28, 66, -128, -41, + 78, 71, -50, 127, 123, 8, 108, 120, -56, -123, -114, 12, 36, -109, 0, 17, -70, 34, 22, + 46, 98, -38, -76, 36, -90, -79, -85, 60, -103, 3, 48, 65, 67, 114, 51, 4, -52, -126, + -78, 97, 6, 126, -128, 17, 0, -85, 10, -124, -102, 79, -128, -112, 18, 23, 99, 22, -127, + -24, 6, -58, 118, 69, 65, 0, 27, 23, 44, -74, 13, -22, -4, 127, -68, -124, -87, -32, + -120, -76, 91, 17, -128, 34, -12, 87, 21, 80, 12, 63, -46, -49, 93, 48, 110, 62, -57, + 28, -126, -71, 45, -94, 62, -70, -92, 102, -122, -73, 99, 15, -117, -120, 40, -72, 70, + 40, -90, -123, 60, 12, -60, 65, 2, 9, 39, -59, 71, 65, 3, 16, 102, -127, 50, 65, 34, + -29, -48, 96, 33, -56, 103, 79, -50, -115, 16, -108, 71, -88, -9, -59, -116, 53, 3, 1, + -32, 46, -8, 0, 45, 90, 30, -128, 38, -94, 66, 17, -122, -8, 100, -128, -67, -53, 17, + -54, 97, -98, 12, 75, -30, 4, 16, 17, 19, 113, 93, -74, -39, 124, 42, 98, -110, -16, + -40, 114, 12, 0, 70, 46, -82, -63, 46, -44, 4, 82, 64, 32, 0, -104, 66, -26, -100, -13, + 19, 27, 112, -120, -56, 66, 8, 16, 48, 5, 34, 8, -64, 3, 120, -118, 41, 65, 26, -104, + -75, 84, -100, -55, 90, 65, -128, -35, -30, -59, -46, 64, 88, -10, -63, -128, 68, 60, 2, + 44, -16, 3, 0, 6, 0, 64, -126, 12, 1, 106, 44, 54, -107, 9, 76, 4, 3, -46, 13, 14, -48, + 39, -25, 116, 99, 18, 94, 27, 112, -84, -107, 6, 96, 6, -104, 10, -31, 120, 4, 80, -102, + 30, 73, 49, 64, 64, -59, -68, 5, -119, 38, 4, 8, 122, -124, -37, 8, -128, 17, 12, -60, + 100, 98, 28, -44, 4, 102, 12, -64, -108, 96, 22, 87, 8, -114, 24, 115, 22, 5, 16, 24, + 77, 16, -116, 9, 69, 48, 33, -94, 32, -17, -11, -54, -57, -19, -16, -102, 10, 34, -88, + 94, -65, -100, -44, 42, 120, -73, -97, 57, -55, -64, -64, 111, -26, 26, 49, -12, 56, 6, + -50, -64, 105, 7, -122, -46, -117, -103, 42, 3, -71, 91, 51, -115, 54, 34, 14, -33, 27, + 3, 72, 35, 96, 6, 103, 22, 3, 38, -94, 126, 66, 23, 48, 72, 64, 8, -70, 112, -122, 40, + 3, -18, 47, -112, 8, -108, -121, 4, 68, 25, -73, 83, 68, 34, -48, 24, -127, 10, 64, -95, + 11, 82, 18, 9, 0, 109, -128, 4, 97, 7, 55, 113, -32, -88, -57, 53, 97, -111, 0, -37, + -74, -112, 32, 32, 46, -109, -48, -84, 24, 48, 73, -88, 92, -33, -56, 50, 37, 74, 109, + 107, 30, -90, 2, -104, -108, 119, -106, -112, -67, -41, 96, 20, -104, -70, 21, 8, -20, + -47, -44, -116, -40, -88, -95, 27, 30, 13, -7, -73, -2, -64, 75, -80, -75, -20, 124, 81, + 51, 26, 64, 15, 6, 91, -24, 5, 90, 57, 50, -37, -14, 99, 36, -124, 122, 53, 90, 122, + -117, 20, 5, 25, 4, -37, -96, 20, -68, 93, 26, 16, 16, 119, 12, -56, 16, -92, 35, 89, + -97, 55, 87, -96, 2, 21, 127, -104, -84, 13, 40, 80, 33, 96, 26, 49, 32, 8, 81, 7, -111, + 83, 65, -64, 48, 16, -100, -80, -1, 39, -16, -109, 12, 24, 29, -29, 31, -52, -110, 51, + 121, 32, -95, 73, -90, -56, -96, 19, 51, 14, 2, 34, 64, 104, 32, -22, -96, -35, 21, -28, + -8, 66, 0, 104, -102, -64, -54, 13, 73, 12, 89, -46, -92, 4, 24, 111, -37, 121, 31, -12, + 76, -128, -104, 64, -78, -126, -127, 65, 16, 32, -52, 20, 49, 120, -23, -68, -123, -54, + -112, -93, -84, -56, 55, 5, -90, 120, 6, -112, 2, 5, 56, -122, 11, 0, 39, -77, -119, + -96, -126, 9, -88, -52, 98, 116, -118, -28, 32, 29, -39, 16, 120, 7, 73, 8, 2, -123, + 104, 48, -96, 115, 16, 64, 93, 20, -16, 123, -74, 65, -100, 11, -32, 7, 81, -111, 92, + 115, 75, 32, 119, 56, -103, 82}; + + + static byte[] PINYIN_CODE = new byte[]{-51, -65, 41, 121, 121, -85, -88, 68, -48, 111, 110, -63, + 50, 96, 96, 107, -125, -14, 67, -127, -122, 103, 41, 47, 111, 50, 80, -63, 63, -127, + -122, -112, 3, 107, 16, 118, -77, -90, 0, 107, -11, 0, 92, 59, -93, 114, 111, 36, -72, + -117, 0, 0, 0, 90, -126, 104, 126, 90, -28, -60, -92, 15, 102, -125, -117, 57, 102, + -125, 9, 30, 112, -112, -55, 52, -126, 102, -122, 125, 93, 85, 124, -4, -69, 55, 112, + 90, 15, 39, -123, 53, 114, 68, -79, 15, 60, 6, 125, 49, 38, 57, -108, 85, 102, -6, -109, + 95, 55, -21, 61, 96, 98, 65, -31, -127, 48, 101, 45, -3, 30, -4, 123, -63, 95, 94, 95, + -113, 75, -2, 101, 65, -126, -125, -107, 0, -78, 18, -120, 0, 85, -6, -85, 126, 109, -4, + 109, 92, 92, 72, 122, -6, 28, 53, 13, 110, 121, -124, 121, 124, -98, 104, 104, 95, -110, + 107, 107, 26, -67, -121, 63, -116, -90, -92, 36, 49, -87, 94, 1, 45, 83, 69, 105, -127, + 56, -89, -76, -84, -60, -77, 34, 52, -108, 41, 60, 16, -76, -118, 41, 124, 41, 127, -62, + -53, -37, 101, 66, -16, -120, 30, 85, 5, 118, -125, 49, 0, 0, -3, 0, 107, 80, 91, -123, + -2, -107, 49, -7, 41, 122, -98, -125, -106, 113, 126, 85, 98, 65, 82, 93, -53, 84, -2, + 10, -81, -79, -2, 87, 20, 83, 126, 75, -91, 114, 47, 73, 37, 60, -61, -117, 37, 52, + -115, -115, 59, 126, -127, -28, 88, 75, -34, 19, -120, 69, 123, 86, 2, 8, 118, 28, 102, + -79, -91, 95, 41, 0, 0, 0, 0, -127, 71, 0, -76, 0, 0, 112, 57, 41, -124, 59, -81, -32, + 106, 85, 54, 32, -107, 96, 37, 93, -117, -107, 104, 0, -7, 100, -89, 87, 126, 59, -127, + 54, 20, 14, 68, 41, -119, 107, -127, -126, -126, 1, -127, -125, -3, 60, 104, 16, 50, 35, + -81, -87, 30, -61, 106, 61, 58, -59, -6, 0, 18, -128, -127, -4, -60, -34, 104, 95, -125, + 106, 80, 1, 100, -6, -60, -128, 107, 46, -127, -98, -9, 62, 41, 0, -59, 110, -123, 106, + -4, -89, -89, 22, -76, 0, 52, -72, -57, 126, -24, -72, -123, 95, 72, 112, -87, 85, -120, + 51, -85, 0, 41, 0, -120, -76, 100, -87, -120, 36, -122, 77, 52, 123, -36, 111, -78, -94, + 0, 87, 0, -117, 89, -80, 107, -125, 106, 110, 107, 88, -32, 20, 32, -93, -117, 45, 35, + 80, 49, 5, 4, 0, 0, 111, -73, -87, 117, -75, 59, -115, 0, -93, -93, -120, -89, -87, 6, + -47, 111, -80, 0, -4, 48, 124, 91, 111, 111, -4, -24, 95, 34, 41, -6, -112, 104, -115, + 85, 95, 86, 111, -101, -92, -100, 48, 85, 81, 104, -6, 121, 38, 0, -100, -111, -100, + -111, 43, 30, 0, 106, 91, 90, 111, -4, 89, 104, 96, 84, 59, -121, -24, 121, 64, 124, 95, + -17, 85, 89, 121, 35, 0, -85, 41, 104, -111, 111, 47, 124, -123, -124, 48, 21, 84, -6, + 21, 21, 77, -117, -4, 38, 27, 38, 27, -122, 54, 54, -87, 55, 111, -87, 107, 57, 57, 49, + -125, -127, -53, -53, 102, -53, 51, 101, 65, 38, 57, 33, 95, 98, 41, 24, -115, -13, -5, + 3, 52, 1, 114, -85, 104, 89, -123, 103, 24, 127, 58, -127, 103, 0, 114, 81, 40, 18, 64, + -121, 33, 106, 66, 51, 126, 52, 104, 58, 72, -124, -85, 18, 72, -125, -125, 41, -24, 73, + -120, 106, 1, 104, 30, -108, -108, 102, 98, 65, 126, 126, 102, 6, -127, 104, -24, 126, + 73, 104, 89, 84, 105, -51, -63, -63, 2, -105, 72, 111, 14, 14, 14, -15, -15, 14, 32, + -65, 0, 0, -15, 0, -126, 126, 23, -51, 75, 98, 80, 15, 87, -117, -51, 114, 3, 71, 0, 59, + -18, -117, 76, 53, 14, 24, 0, -65, 54, 41, 111, 75, 115, -125, 57, 24, -72, -51, -87, + 69, 15, 33, -7, -76, 126, 26, 126, -61, -76, 4, 67, 39, 63, -56, -115, -66, -6, -12, + -49, -6, 60, 87, 43, 86, 14, -44, 0, 90, 37, 70, 1, -6, 106, 85, 111, 101, 3, 99, -108, + 1, 99, 70, 58, -72, 1, 101, 114, 114, 46, 46, -124, 19, 109, 59, 46, -90, -40, 74, 83, + 107, 68, -123, 3, 18, 120, -59, 52, 126, 66, 112, 30, -113, 43, 78, 83, 57, 85, 75, -66, + 3, -6, 32, -22, 112, -4, 84, 84, 98, 49, 17, 100, -124, 38, 84, 0, 0, 60, -123, 38, -4, + -60, 102, 79, 1, -120, 19, -114, 119, 58, 5, -127, 15, 15, 93, 81, -122, 84, 93, -115, + 121, 0, -6, 86, 95, 95, 0, 104, 83, 114, 112, 113, 100, 37, 36, 58, 110, 75, 121, -128, + -6, -51, 16, -63, 57, -59, 84, 39, 65, 14, 30, -123, -18, -21, -115, 115, 101, -79, -63, + 120, 87, -24, -87, -74, 25, 87, 80, 121, -53, -63, 41, -117, 117, 75, 75, 76, 115, -87, + -60, 104, 90, 85, 110, 65, -123, -128, 102, 126, 100, 49, -99, -119, -117, 90, 3, 104, + -126, -122, 5, 20, 126, -60, 12, -113, 41, -90, 110, 102, 119, 93, 82, -65, 49, 121, + -10, 48, 83, -123, 52, -34, 37, -80, -19, 20, -6, 49, -40, -117, 113, -120, 38, -89, 96, + 97, 90, -21, -56, 58, 101, -127, 109, 105, 13, 97, -78, -76, 58, -73, 90, -9, 120, -120, + 106, -121, -122, 104, 126, 126, -107, 37, 106, 80, 120, -125, 101, -82, 49, -127, 80, + 92, 90, 22, -112, -123, 106, 84, 85, -109, -120, -124, -73, 0, 3, 70, 104, -52, -89, + 104, -60, 5, -121, -9, 80, 89, 90, 119, 95, 52, -99, 61, -1, -117, 80, -121, 17, -10, + 98, 93, -123, 106, 124, -55, -128, 76, -5, -22, 84, 4, -79, 104, -126, -120, -4, -124, + -123, -125, 39, -113, 27, 0, 126, -127, -79, 32, 127, 121, -32, 98, -121, -82, 3, 80, + -127, -114, 112, 9, -66, -113, 110, 85, 20, 71, 124, 119, 104, -7, 107, -93, 114, -92, + 112, -87, 99, 90, 84, -87, 46, 87, 104, 111, 69, -91, 111, -121, -126, 39, 82, -63, 54, + 37, -18, 87, 37, 71, -97, -11, -36, 112, -120, 89, 35, -39, 71, 109, 89, 87, 68, 77, 52, + 74, -116, 28, 64, -87, 46, 49, -89, 46, 61, 72, -91, -94, -85, 80, 83, 114, 124, 63, 0, + 20, -125, 127, 27, 90, 105, 92, 40, 44, 99, 47, 127, 103, -105, 78, 112, 75, 70, 115, + 83, -117, 93, -84, 127, 57, -113, 65, -1, 61, -116, -112, 85, 89, -6, 102, 109, 112, + -81, 60, -121, -16, 114, 33, 41, -6, 84, 38, -76, -46, -117, 61, 49, -89, -123, -16, 85, + 50, 65, -15, 58, 111, -40, 111, -76, 93, -60, -120, -80, -74, 106, 53, 4, 123, 111, -39, + 37, -13, 46, 121, 112, -94, 127, 1, 100, -4, 65, -58, -123, 106, -60, 12, 112, 81, 11, + 85, 1, 112, -108, -127, 35, 112, 27, -76, -112, 72, 0, -125, -59, -15, 85, 111, 112, 37, + 37, 16, 124, -120, -125, -29, 111, 3, 68, 4, 72, 87, 124, 20, 83, 83, 63, 80, 81, 17, + 90, 27, 80, 96, 94, 100, 119, 96, -60, -108, -65, 107, 100, 110, 119, -58, 92, -63, 116, + 127, -49, -98, 39, 77, -22, -63, -85, -6, -6, -63, 65, 50, 80, 24, 72, -59, 95, -53, 95, + -127, -17, -125, -125, 121, 87, 88, 104, 106, 126, 39, -122, -125, 125, 59, 111, 14, + -56, 39, 71, 38, 109, -117, -122, 0, 3, -123, 0, 106, 60, -78, -128, 112, -48, 8, 110, + 5, 45, -84, 32, 100, 46, -36, -112, 78, 39, -67, 107, -95, -98, 0, -125, 95, -77, 107, + 92, 0, 0, -9, -121, 107, 60, 112, 56, 112, -85, 102, -61, -114, 38, -108, 58, 57, 76, + -79, 101, 26, -55, 124, 39, 104, -74, -69, -7, 80, -87, 23, 84, 85, 81, -3, 27, 39, 52, + 104, -125, 51, 114, 94, 106, 15, 127, 52, 52, -40, 57, 39, 17, 80, -21, 41, 41, -20, 82, + 25, -57, 115, 65, 114, 125, 85, -112, 63, -123, 107, 90, -122, 122, 96, -112, 61, 63, + 54, 14, -123, 126, 108, 106, 95, -78, -123, 100, 35, -67, 107, 46, -72, -93, -75, 89, + 18, 59, 111, 94, 121, 14, 16, -123, -124, -104, 37, 33, 63, -60, 5, -76, 121, 121, 110, + 32, 83, 109, 108, -67, 1, 111, -13, -127, 99, -123, -6, 85, -127, -76, -72, -78, -121, + 109, 49, -77, -123, 92, -3, -87, 100, 26, -123, 49, 46, 72, -24, 63, 103, 85, -60, 60, + -53, 33, 112, -85, -93, 76, -87, -4, 87, 96, 104, -67, -112, -66, -110, -73, -16, 41, + 127, 127, 39, 95, 124, -96, -125, 100, 44, -83, 53, 64, 101, -124, 49, 107, 119, 94, 41, + 105, 107, 89, 0, 0, 95, -85, -123, 80, -15, 111, -123, -9, 88, 126, -122, 84, -23, -127, + -21, 80, 89, -4, -4, 85, -76, 85, 55, 75, 125, -56, 20, 52, -83, -125, -122, 104, 63, + 78, 58, 59, 34, 98, -98, 0, 34, 71, -120, 22, 116, 14, 32, 32, 32, 41, 69, -7, -81, 80, + 27, 27, 37, -119, 37, 122, -123, -91, 35, 93, 54, 118, 49, 41, -16, 112, 114, -79, 119, + 90, 114, 115, 87, -125, 32, 85, 5, -76, -93, 0, 111, -81, -56, 119, 59, 124, 120, 90, + 111, -87, 39, 97, -80, -67, -112, 109, -101, 24, -85, 65, 103, 5, 124, -85, 32, -67, 58, + 58, 104, 54, -15, -117, 57, 0, -127, -113, -85, -32, 109, -121, 86, 27, -127, 54, 126, + 41, 57, 50, 68, 27, -120, -94, 18, -85, -60, 39, 41, -60, -34, 107, 107, -61, -121, -6, + 14, -127, 114, 17, -107, 83, 61, 106, 106, 74, 48, -128, -120, -93, -114, 2, -7, -113, + 80, 18, 102, -4, 92, 18, -96, 85, 0, 18, -125, 74, -73, -73, -72, -87, 110, 101, -76, + 49, -122, 107, 72, 79, 126, 90, -21, 37, 16, 32, -57, -79, -125, -7, 27, 37, 102, 18, + -128, 87, -76, 0, 112, 107, 15, -87, -120, 89, 107, 54, 80, 90, 123, 114, -120, -78, + -94, 74, 83, 121, -94, 0, 0, 107, -60, -127, -85, -125, 107, 86, -81, 104, -125, 113, + 32, 57, 9, -125, -93, 83, 45, 112, -113, 87, 35, -89, -93, 49, 4, 109, -4, 82, 105, 6, + 100, 114, 0, 22, 117, -75, 100, -87, -60, 58, 59, 59, -123, 32, 0, 114, 6, -120, -93, + -93, -47, 78, -75, 5, 87, 100, 93, 100, 111, -128, 16, -57, 106, 62, 126, 89, 89, 0, + 119, -80, 119, -117, -118, 124, 90, 38, -113, 116, 116, 24, 101, -6, -122, 86, -33, 107, + 81, -9, 104, -76, 45, -15, -112, -21, 100, -112, -20, -51, 34, -83, 107, -110, 75, 106, + 91, -123, 106, 91, 80, -3, 15, 56, 86, -124, -120, -108, -128, 90, 6, 76, 76, -80, -113, + 96, -117, 59, -19, -119, -19, 58, 58, 19, 101, 69, 112, -120, 124, 65, 80, 39, -85, 38, + -10, 0, 121, 48, -93, 68, -123, 95, 92, 5, -82, 124, 101, 89, 94, 87, 106, 84, -121, + 102, 39, 80, 69, 69, 116, -112, 119, -73, 86, -120, 96, -124, -9, 100, 126, 106, -127, + 126, -109, 0, 83, 34, 103, 126, 0, 60, -121, 11, 0, 85, 90, -119, 35, -7, -120, -113, + 68, 78, 111, -16, -92, 32, 121, 87, 38, 15, 121, 0, 41, -92, 98, 98, -115, 89, 85, 100, + 112, -116, 4, 63, 90, -6, 84, 0, 0, 112, 100, 124, -62, -117, 60, 11, 86, -81, -97, 127, + 46, 85, 53, 84, 119, -117, 90, 113, -123, 49, 87, -10, 2, 53, 85, 2, 91, -113, 100, 100, + 104, -115, 111, 94, 8, -15, 100, 0, 38, 33, 34, 0, 0, 0, 0, 36, 115, -98, -122, 73, 99, + 126, 87, -85, 96, 92, 125, -123, -125, 14, 107, -120, 80, 72, 65, 85, -29, -29, 32, 100, + -119, -119, 111, -63, 30, 84, 103, 91, 2, 16, -63, 124, 95, -128, 80, 83, 3, 54, 101, + -82, -120, 0, 95, 103, 10, 121, 114, 86, 0, 0, 15, 80, 73, 60, 34, 32, 114, 20, 125, 90, + 85, 84, 85, 114, 115, 115, 85, 114, 93, -49, -109, 0, 102, 98, -55, -85, 107, 81, 15, 0, + 0, -3, -79, 85, 14, 16, 49, -76, -125, 41, 104, -77, 87, 54, 104, 63, -115, -111, 114, + 121, 104, -123, 5, 80, -83, 112, -24, 11, -119, -67, 0, 33, 52, 123, -125, 85, 85, 85, + 104, 89, 38, 125, 32, 103, -4, 8, 100, 87, -2, -106, 62, 75, 37, -123, 86, 49, -83, 111, + -81, 69, 34, 86, 83, 100, 98, -93, -63, 60, 104, -120, -62, 0, 0, 107, 111, 104, 97, + -93, 58, 119, 24, 54, 85, 6, 49, -85, 126, -120, 90, -80, 80, 104, 90, -128, 126, 0, 0, + -93, 17, 87, -109, 98, -121, 40, 60, 102, 115, -93, 16, 15, -87, -53, 10, 21, 63, -72, + 5, 98, -99, 48, 0, -87, -76, -115, -83, 100, 85, 90, -78, 100, 0, 9, 113, -93, 49, -115, + 69, 105, 0, 35, -60, 60, -93, -120, -93, -80, 52, 111, -119, -93, -23, -124, -19, -128, + 112, 2, 80, 0, -115, -115, 90, 103, 6, 67, 103, 102, -109, 45, 80, -21, 43, -108, 118, + 118, -3, 67, -3, -14, 8, -21, 34, -125, -22, 72, 109, 70, 70, 15, 67, 9, 20, 9, 110, 0, + 72, 99, 37, -33, 37, -11, -118, -52, 57, -51, -91, 12, -66, 84, -65, -51, 12, 84, 100, + 82, 11, 49, -125, 102, 110, 102, 38, -51, 63, -4, 5, 5, -112, 62, 85, -66, -106, -4, 84, + 102, 85, -87, -87, -8, -127, 94, -123, 12, 5, 20, 72, -117, -126, -125, 87, -14, -108, + -117, -109, 41, 85, 11, -73, -122, -69, 24, 80, -87, 75, 69, 27, -124, 85, -87, 72, -82, + -15, -13, 10, 85, 40, 80, -98, 40, 5, 5, 6, 83, 3, 20, 31, 47, 3, -122, -116, 106, -69, + 110, -110, 20, 120, 99, 112, 124, -116, 114, -99, -33, 63, 1, -122, 114, 11, -15, -117, + -40, 38, -19, 86, 75, 121, -80, 85, -15, -40, 38, 110, 101, 113, -117, 58, 20, 102, 87, + -34, 124, 117, -123, 115, -128, -127, 124, 32, 57, 15, 40, 69, -91, 72, 86, 39, -101, + -124, 111, 55, 111, 14, -66, 85, -116, -87, 86, 106, 53, -92, 11, -123, 100, 30, -87, + -123, 87, -120, 112, 85, 102, 6, -6, -40, 16, 106, -87, -82, -125, -3, -97, 100, 109, + -111, -60, 33, 104, -123, -124, 99, -61, 23, 51, 35, -82, 0, -73, 121, -111, 121, 80, + 87, 83, 112, 92, -120, -65, 80, 112, 87, 72, 99, -46, 90, -126, 120, 15, 110, 110, -63, + 30, 102, 55, 20, -55, 122, 112, 51, -69, 112, 57, 111, 39, 114, 0, 104, -125, 44, 114, + -67, -120, -124, -53, 127, 32, 5, 5, 114, 53, 12, -115, 14, 14, 125, 21, -81, 111, 69, + 102, -83, 48, 89, 40, 0, 85, 96, -116, 72, 126, -101, 87, 90, 57, 87, 98, -34, 15, -128, + -31, -61, -82, -46, 106, 40, -76, 57, 87, -60, 9, 124, -46, -73, 87, -6, 4, 96, -58, + -112, -72, -76, 111, 52, 79, 3, 91, 68, -90, 6, -127, 119, 63, 43, 93, -118, 111, -6, + 111, 101, -69, 119, 84, 90, -56, -122, 99, 18, 15, 13, 113, -115, 114, -115, 78, -125, + -63, 58, -15, 80, 124, 87, -3, -80, 57, 104, 3, -10, 65, 90, 96, 85, 20, 48, 101, -126, + 34, -9, 48, -108, 8, 38, 37, 104, -109, -126, -56, 32, -79, 14, -125, -125, -115, 82, + -78, -121, -123, -125, -87, 106, 87, -121, 100, 100, 94, 101, 95, -73, 52, -120, 0, + -107, 98, 10, 80, 88, 102, 86, 118, 107, 39, 95, 8, -18, 0, 59, 107, 127, 81, 77, 37, + 64, 84, 84, 37, -114, -63, 11, 68, 87, 47, 112, 96, 100, 3, 5, -92, -87, 94, 90, -79, + 99, 85, -80, -87, -121, -85, 56, 56, 0, 78, 65, 19, 126, 53, -56, 111, -117, 36, -94, + 81, 38, 80, 65, 41, -113, -18, 37, 121, -6, 77, -97, 33, -6, 13, 78, -76, 49, 105, 100, + 66, 11, -81, 0, -15, -23, -3, -113, 0, 82, 0, 2, 72, -122, 127, 111, -65, -63, 46, 96, + 64, 92, 57, 16, -56, -125, 80, 18, 124, 90, 43, -125, -117, 101, -85, 5, 86, 73, 112, + 103, -46, 121, 107, 111, 125, 19, 27, -79, 0, 15, 56, 102, 81, 84, -121, -121, 107, -69, + 61, -79, 60, -87, -92, 107, 65, -3, 55, -115, -128, 102, 2, 18, 71, 33, -97, -117, 49, + -121, 104, 53, 49, -6, -87, 107, 56, 3, 96, 5, -85, -67, 127, 106, 0, 107, 80, -76, 84, + 62, 0, 123, 98, 4, 59, -81, -83, 2, 52, 125, 107, -7, -120, 83, -121, -79, -127, 0, + -120, 2, 14, 24, 4, 119, 59, -123, 108, 59, 126, 124, 27, 54, 65, 0, 111, -121, 90, 18, + 41, 81, -107, -93, 85, -127, 96, 18, -128, 92, -89, 72, -87, -123, 16, -87, 117, 2, + -127, 107, 54, -95, -78, -76, -87, 117, -93, 107, -60, 88, 85, 105, 60, 117, 124, 103, + 10, 67, -19, 121, -123, -13, 8, 9, -87, 76, 0, -124, -4, 8, -17, 84, 58, 82, -24, 0, 0, + 0, 121, -80, 104, -10, 48, 0, -116, 33, 38, 0, 59, -61, 21, 45, -10, 15, -121, -125, 0, + 48, 107, -6, 87, -77, 63, -24, -61, -117, 13, -81, 123, 84, -15, 58, 82, 107, 100, 93, + 57, 37, 65, 65, 112, 33, 38, 1, 37, 32, 32, 19, 38, 52, 37, 109, 43, -76, 90, 109, 13, + 0, -34, 65, 110, -126, 37, 124, 65, 90, -48, 65, -10, 68, 122, 68, 5, 116, -61, 14, -6, + -79, 98, -79, 33, -51, 114, 83, 90, 99, 65, -122, -122, 5, 80, 90, 65, -51, 0, -21, + -124, 76, 56, -48, -79, 12, -125, 41, -51, -51, 27, 0, 92, 14, 56, -123, -71, -6, -71, + -21, 0, 83, 122, 111, 111, -51, -114, 104, -79, 35, 67, 40, 122, 59, 47, -127, 78, -124, + 37, 33, 74, -89, -127, 30, -79, 67, 72, -81, -124, -124, 40, 20, 67, 67, -15, -36, 58, + 41, 41, -123, 104, 44, -49, 68, 14, -122, -83, 100, 96, -118, -121, 86, 32, 95, -26, + -87, 101, 36, 110, 6, -122, -115, 85, 86, 53, 14, 104, -87, -111, 44, 87, -120, -19, + -15, 93, -108, 48, 90, -6, 58, -125, 82, -123, 63, -117, -127, 85, -117, 65, -126, 96, + 124, 19, -36, -124, 109, -120, 5, 39, 69, 104, -122, 80, 126, 76, 101, 38, -123, 117, + 99, -63, 71, -120, 89, 69, 71, -66, -15, 89, 53, -7, -87, -123, 55, 76, 84, 30, -91, 40, + 124, 87, 104, -16, 127, 105, 59, 85, -69, -81, 38, -127, 65, 3, 38, 14, 14, -56, 102, + 74, 77, 80, 111, 53, 99, -120, 85, 58, 37, -122, -127, 111, 120, 87, -95, 101, 37, 71, + 111, 103, 81, 124, -103, -126, 106, 104, -77, 26, -115, 38, 85, 105, 104, 81, -127, 44, + 8, -89, -79, 31, 40, -26, 65, 56, 17, 59, 127, 16, 37, 51, -73, 104, -111, 40, 127, 125, + 51, 56, 6, 66, -77, -77, -53, -121, 106, 107, 125, 90, -83, -78, -2, -79, -91, 87, 85, + 58, 106, 115, 2, 8, 87, 105, 104, -32, 111, 80, 104, 109, -15, -89, -87, 41, 58, -81, + 65, -81, -94, 17, -127, 38, 101, 96, -122, -124, 0, -87, -128, -94, -127, 65, 87, 107, + 106, 4, 109, 59, 65, -73, -75, -75, 20, 0, 107, -9, 82, 62, 82, 7, 7, -1, 14, 119, 119, + -65, 61, -23, -122, 125, 107, 48, -80, 95, -53, -127, -123, -16, 95, 2, 77, 114, 112, + 14, 78, 40, -4, 85, 2, -119, 114, 125, 114, 120, 53, 114, 89, 103, -9, 114, -123, 2, 92, + 125, -87, -13, 115, -123, -15, 93, -19, -121, -114, 3, 54, 6, 124, 102, -114, -114, + -121, 124, 102, 126, 72, -56, -6, 107, 111, 11, -128, -122, -17, 115, 107, 115, 104, 20, + 78, 115, 4, 126, 100, -125, 115, 111, -98, 83, 92, 60, -21, 90, 3, 38, 60, -76, 126, + -61, -76, -121, 95, -125, -21, 105, 3, -76, 95, -121, 59, 3, 102, -87, -51, 68, 93, 95, + -66, -66, -123, -6, 78, 65, 88, 75, 91, 85, -21, 87, 75, -56, -55, 38, 39, 114, -59, + -21, 84, -58, 58, -63, -65, -111, 87, -104, 39, 101, -124, 102, 37, -128, 56, -125, -99, + -117, 37, 104, 38, -63, -53, -120, -125, -125, -59, 63, 112, 67, 104, -112, -112, 34, + 124, 96, 19, -60, -78, 54, 69, -60, 67, 104, 80, -55, 96, 38, -99, -116, -52, -125, 66, + 101, 100, -53, -122, -68, -127, -124, -63, 56, 34, 112, 124, 63, 37, 55, -116, 77, 78, + 87, 85, -97, -94, -125, 32, 65, 127, 78, -80, 39, 2, -82, 99, -120, -124, -87, -94, 54, + -116, 46, 54, 72, -15, -15, -51, 127, -40, -76, 95, -122, 23, -121, 111, 127, -69, 86, + 92, 126, 108, 0, 46, -125, -63, 72, 120, 96, 64, -98, 95, 19, -65, 95, 82, 81, -58, 40, + -98, -60, 82, -104, 59, 36, -108, 51, 86, 2, -65, -55, -67, 46, 120, 127, 104, 66, -104, + -53, 47, 49, -77, 38, -67, -13, 37, -127, -61, 124, 20, -12, 85, -2, -7, -120, 62, 37, + 47, -83, 35, 87, -111, 103, 95, 69, 84, -81, -98, -125, 103, 2, 126, 126, -125, 102, + -128, -117, 80, 40, -127, -34, 98, 102, -128, -61, -59, 18, -59, -87, 106, -115, 96, + -59, -128, -76, -61, -78, 105, -67, 85, 41, 60, -111, -120, -65, -121, -81, 111, 48, 27, + -115, 39, 104, 37, -123, 120, 37, 107, -117, -121, -123, 55, 73, 2, -123, 123, -128, 7, + 39, 68, -6, -127, -112, 93, 84, 75, -103, -3, 85, 83, -99, 59, -69, 30, 58, -115, -87, + 90, -56, -28, 122, -110, -123, -6, -111, -122, 86, 77, 99, -15, -127, 100, 54, -117, 35, + 75, -21, 100, 0, 87, 82, -53, 124, 4, 111, -108, 75, 75, 63, 125, -125, 77, 90, -51, + -120, -95, 15, -30, -10, -16, -80, -19, -90, -9, 20, -9, 37, 115, 2, -87, -78, 69, 0, + -87, -99, 41, -106, 5, -120, -99, 107, 77, -46, -126, -76, 80, 2, -73, -107, 92, 100, + 70, -16, 85, 0, 119, 48, 86, -2, 0, 80, -2, 0, -106, 89, 6, 32, -92, 119, 111, 89, 86, + -66, -78, 0, 35, 35, 83, -79, 107, -66, 6, 100, 55, -97, 111, 0, 0, -76, 36, -125, 0, + 50, -113, -106, -16, 100, -115, -105, 29, -6, -111, 1, -81, -114, 20, 68, -56, 66, -125, + 115, -79, 2, 54, 6, -80, 11, 106, 74, 84, -6, -74, 78, 65, 94, 11, -6, 36, 18, 100, 67, + 68, -121, 75, -122, 107, 15, -108, 14, 80, 48, -125, 73, 86, 59, 64, -46, -16, -125, 63, + 59, 30, 0, -6, 0, 87, 96, 6, 6, -69, 100, -39, 52, 77, 48, -79, 49, 60, 9, 122, -15, 80, + 25, -89, 55, 65, 86, 85, -85, -21, 80, 114, 74, -127, -108, -95, 0, 1, 108, -117, 32, + -6, 5, -16, -76, -76, -111, -3, 36, 106, -89, 16, -6, -53, -6, 53, -111, 1, 47, 0, -127, + 32, -91, 4, 123, 62, -125, 85, -81, 68, 65, 125, -21, 115, -2, 63, -87, -125, -123, 85, + 127, -2, 75, -125, 111, -115, 115, -128, 125, -89, -108, 41, -127, 6, 59, 83, -124, -15, + -15, 111, -11, -6, 2, -108, -125, 111, 18, -61, -19, -112, 20, 0, -57, 22, 87, -99, -89, + -89, -123, -87, -87, 83, 6, -19, 107, -87, -78, -78, -53, 20, 45, 105, -93, 117, 100, + 39, 39, -87, 13, 35, 113, 49, -6, 57, -69, 90, 102, 87, -123, -6, -123, 13, 41, 39, 0, + 104, 39, 110, -123, 66, 90, 90, -60, -109, -123, 53, -63, -105, 4, 121, -120, 37, 54, + 48, 31, -60, -72, 111, 88, 84, 66, -13, -120, 107, 86, -123, -127, 95, -125, 95, 46, + -121, -125, 92, -97, 63, 60, -128, 61, -6, 102, 105, -107, -80, -76, 19, -121, 60, -123, + -76, 32, 11, -127, 126, 110, 85, 106, -112, -128, -125, 90, 112, 84, 87, 101, 64, 104, + -63, 49, 63, 0, -113, -125, 109, -127, 95, 60, 38, -69, 57, 0, 96, -6, 111, 85, -127, + 49, 32, 96, 126, 54, -87, -32, -40, 60, -87, 9, 113, 64, 117, -89, 16, 111, 111, -87, + 90, 0, 115, 71, 94, 49, 12, 71, -112, 30, 93, 104, 87, 19, -39, 3, 3, -122, 86, 114, + 114, -108, -58, -123, -120, 14, -123, 111, -60, -103, 8, -15, -40, -87, 110, -109, -15, + 6, -80, -53, 37, -39, 0, 101, -105, -123, -123, 41, -117, -112, 58, -127, 37, 69, -123, + -128, 115, 106, -112, -123, -122, 12, 72, 104, -120, 126, -32, 90, 85, -109, -92, 90, + 120, 46, -72, -97, 93, -120, 64, 37, 71, 34, 46, 99, -74, -76, 102, -105, 12, -114, 9, + 7, -127, -123, -123, -97, -88, -16, -108, 19, 40, -107, 111, 52, 0, 0, 104, 85, 15, + -127, 90, 14, -28, -122, -122, -111, 95, 37, 60, 81, -85, -112, 111, -127, 95, -125, + -123, 60, -126, -127, 95, 95, 102, 15, 54, 0, -127, -110, -51, 32, -62, -123, -127, -76, + 52, -127, 107, 81, 3, 27, 0, 104, 125, -1, -127, 54, 89, -7, -123, -113, 69, 0, -72, 54, + -32, 27, 126, 9, -28, 111, 0, -127, 73, 81, 37, -128, 100, -72, 16, 0, 9, -115, -87, + 117, 97, 76, -118, 2, 85, 2, -105, 111, 28, -120, 102, 43, -114, 71, -91, -1, 125, 102, + 15, 10, 102, 19, 111, -120, -123, -2, 66, 84, 107, 102, -123, 43, 102, 66, -123, 44, + -119, 89, 37, -104, 52, 83, 58, -103, -108, -115, 95, 52, 0, -98, 71, 0, 106, 83, 76, + 99, 111, -117, 2, 102, 102, 66, -83, 111, 65, 66, -117, -83, 85, 84, -98, 44, -117, 0, + -100, -78, 37, 53, -13, 119, 52, -2, 2, 71, 119, 119, -1, -87, 41, 39, 90, -4, 41, 119, + -6, -4, 100, 39, 41, -58, -117, 126, -120, -80, -78, 19, -120, -120, 127, 104, 49, -114, + 119, 69, 50, -120, 66, 104, 41, -120, 4, -122, -10, 73, 34, -117, 29, 62, 54, 123, -120, + -111, -120, -120, -120, -90, -16, 111, 38, 93, -66, -120, 0, 72, -127, 89, 6, 53, -127, + -125, -128, 55, 99, -115, 112, 121, 94, 89, 28, -15, 14, -125, 104, 70, 32, 38, 86, 63, + -120, -50, 38, 102, -87, -1, -56, 10, 66, 49, 90, 27, 12, 82, 56, -112, 63, -80, 120, + -30, 90, 101, 83, -126, 96, 83, 39, -65, -9, 0, -125, 2, -78, 0, 15, -73, 107, 4, 38, + 106, 102, 87, 14, 2, 103, 62, -123, -121, 5, 55, 17, 82, -99, -120, 69, -127, 56, 113, + 27, -122, -104, -94, 14, 31, 59, -124, 27, 90, 114, 71, -23, -87, -92, -117, 105, -125, + 112, 69, 86, -123, 37, 53, 39, -120, -105, 89, 34, 68, -126, 100, 95, -101, 93, 40, -99, + 94, 114, 0, -4, 89, -125, -7, -94, -110, 14, 14, 14, 96, 38, 104, 111, -125, -128, 102, + 38, -124, 1, 30, -121, -76, 20, -127, -81, 53, -114, 90, 124, 102, -105, -4, -4, -114, + 45, 105, 112, 27, -117, 20, 120, -1, 75, -73, 58, 89, 21, -125, 0, 15, 55, 88, 87, -10, + -125, 38, 121, 39, -120, 113, 46, 90, 84, 70, 48, -127, -122, 125, 92, -63, 83, 43, + -117, -14, 87, -120, 119, -1, 120, 3, -58, -4, 0, -98, 0, -77, 114, 115, 60, 113, 40, + 95, 85, 21, -124, 101, -36, -4, 89, 52, 100, -20, 72, -87, 14, -113, 41, 31, 38, -120, + -3, -78, -93, -125, 21, -87, 126, 14, 63, 49, 100, -16, 28, 52, -22, -13, 71, 111, -57, + -117, 120, 85, 109, 104, 121, 32, -104, 51, -10, 119, -127, 107, 52, -77, 124, -76, -39, + 56, 52, 0, 56, -90, 73, -84, 89, 20, -60, 31, 59, -83, 58, 65, 90, -125, -56, -98, 57, + -2, 62, 125, 55, -91, 117, 89, -76, 39, 117, 0, -22, -6, -22, 93, -117, 72, -76, 100, + 20, 59, 23, -108, 101, -4, -85, 21, -121, -94, 0, -93, -98, 111, 113, 114, -125, 58, 64, + -60, 40, -127, 0, -6, 63, -117, -121, 83, 51, -121, -4, -96, 63, -76, -76, -125, 75, + 107, 111, -94, -78, 0, -85, -93, -4, 113, -122, 4, -85, 15, 73, -108, -87, 31, -73, 107, + 113, -113, 95, -60, 63, 83, 37, -127, 37, -27, 90, -89, 87, -112, -40, 54, 127, -4, 0, + 14, 8, 84, 30, -110, 16, 86, 14, 53, 106, -87, 38, 58, 0, 6, -87, 93, -117, -9, -53, 51, + 126, -121, -87, 52, 66, -87, 85, 52, 119, 69, -112, 27, 113, -121, -81, -116, 7, 0, 86, + -59, 4, 0, -84, 87, 90, -84, 24, -120, -87, 113, -76, -117, -6, 53, 7, 33, -81, -111, + -120, 109, 0, 24, 24, 60, 15, 16, -59, 120, 95, -111, 121, -125, 117, 48, -87, 90, 90, + -28, 11, 102, 94, 95, 60, 3, 0, 26, -116, 60, -60, 24, 86, 119, -110, -124, -53, 24, 24, + -28, 38, -84, -124, -101, 20, 124, 41, -111, -125, -28, 72, -36, -87, -105, 63, -36, 66, + -93, -60, -60, -118, 85, 100, -124, -118, 110, -127, 30, -121, 98, 113, 119, 111, 115, + 78, 12, 81, 81, 3, -50, -112, 70, -33, 89, -122, 41, 46, -15, 106, 30, 119, -123, -127, + 86, 114, 12, 58, -121, 52, 84, 56, 53, -118, 124, 6, -121, 90, -123, -6, -112, 40, 119, + 124, -89, 85, 90, 90, 37, 11, -120, 4, -80, -120, 34, 93, 101, 90, 75, -125, 57, 41, 39, + -122, 87, -109, -119, 8, -117, -23, 41, -107, -99, -120, 12, 118, 90, -122, -120, 40, + 103, 7, -115, -99, 121, 48, 99, 99, 61, 90, -103, -123, 5, 92, -73, 96, 13, 87, 90, 97, + 69, 15, 66, 106, -89, 90, 5, 95, 111, 67, 69, 49, -124, 88, 126, -115, -123, -125, -116, + 38, -59, -125, -72, 37, 3, 41, 9, 69, 89, 78, 0, 99, 94, 64, 94, 90, 119, 85, 90, 68, + 54, 74, -97, 90, -120, 121, -123, 100, -119, 87, -127, 95, 0, -111, -81, 76, -87, -72, + -84, 40, 5, 34, -6, -6, -114, -6, 78, -4, 87, 40, 80, -6, 61, 78, 94, 79, 13, -115, 23, + 109, 53, -74, -79, -6, 126, 11, 47, -80, -59, -6, -122, 59, -111, 108, -110, 104, -112, + 92, -84, -121, 85, 19, -56, 111, -111, 83, -72, 95, 0, 33, 0, 95, 88, -125, -108, 87, + 18, -59, -127, 73, -122, 63, -56, -58, 112, 90, 10, 49, 3, 15, 124, 99, -111, -59, 80, + 90, 80, 111, 101, -58, -122, -85, -111, 15, 114, 106, 64, 103, -123, 114, 37, 32, 57, + -126, 112, -111, 95, 38, 0, 99, 0, 107, -121, 104, -115, -40, 9, 102, -21, -121, -125, + 55, 5, 45, 114, 86, 43, 85, 15, 61, 90, 114, -125, 95, 17, 121, 116, 63, 87, 52, -125, + -111, 61, 125, 23, 14, 87, 51, -87, 56, 106, 85, -111, -89, -117, -4, -67, -123, -72, + -53, -13, -85, -60, 96, -111, -127, 32, 54, 83, 43, 13, 104, 26, -52, -121, -3, 127, 87, + 85, 0, 94, 8, 96, 126, -2, 123, -105, -123, 32, 24, -81, 111, 83, -83, 47, -106, -125, + 10, 32, 19, 94, 126, 122, -108, 85, -3, 0, 56, 38, 126, 85, 27, -125, -124, 124, -2, 49, + -122, -123, 20, 32, 104, -46, 54, 104, 31, 95, -127, 18, -4, -125, -7, 98, -108, -6, + -16, -87, -53, -89, 90, -108, -99, 110, 95, -89, 87, 32, 0, -76, 32, 107, 23, 88, 87, + -107, -108, -73, 85, 60, -93, -89, -85, -60, -118, 111, 119, -121, 87, 115, 113, -127, + 78, -99, -127, 12, 80, 114, 119, 46, -15, 30, 94, -50, 12, -111, -74, 86, -123, 81, 84, + -120, -125, -33, 41, 87, 93, 90, 90, -85, -109, 37, 85, -123, -122, -121, 8, 90, 41, 34, + 104, -120, 57, 9, 15, -122, -103, 10, 67, 113, 126, -127, 96, -124, -73, -115, -123, 69, + 99, 89, -116, 94, 85, 54, 61, -127, 64, -127, 95, -80, 106, 95, -6, 85, 47, 33, 108, 38, + 80, -59, 40, 13, 40, 61, -79, 5, -111, 126, 78, -72, -115, -112, -108, 88, -125, -59, + -93, 64, -58, -127, 114, 126, 49, 76, 73, 15, 87, 101, -115, 124, 63, -72, 15, -56, 112, + -121, 90, 17, -125, 87, 53, 95, 32, -87, 104, -125, 18, -13, -67, -89, 107, 56, -52, 26, + 90, -83, 32, 123, -124, -4, -2, 124, -123, -108, 89, 90, 94, 89, 6, 89, 6, 20, -10, 120, + 0, 94, 107, 107, 1, 86, 105, -106, 59, 0, 1, 82, 107, -89, 59, -76, 105, 79, 94, 79, 79, + 112, 0, -73, 90, -60, 82, 102, -120, -117, -65, 102, -56, 94, 6, 103, 64, -116, 90, -81, + 100, -128, -107, 103, -113, 111, -123, 3, 82, -93, 41, 49, -15, -69, -79, 6, 82, -87, + 34, 80, 14, -127, 123, 69, -79, -127, -116, -60, -128, -73, -15, -127, -127, -75, 101, + -57, -3, 57, -63, 101, 110, 110, 86, 6, 95, 101, 102, -3, 118, 95, -80, 104, -120, 63, + 94, -3, 104, 87, 15, 7, 7, -4, 124, 56, 87, 104, 101, -3, 87, 111, 99, -122, 60, 112, + 85, 83, 32, 86, 32, -85, -89, 99, -31, -3, 32, 111, 100, 104, 39, 82, 86, 119, 38, 38, + 53, 90, 86, -17, 104, -95, 104, -15, -80, -79, -123, 4, 85, 90, 88, 85, 85, -6, -2, 126, + 126, 41, 27, 119, -124, 125, 53, 85, 61, 30, 38, -120, -125, 96, 39, -14, -111, 78, 126, + 120, 115, 115, 112, 5, -13, 104, -85, 4, 0, -81, -17, -2, 5, 83, 104, 126, 96, 60, 102, + -91, 0, -109, -65, -127, -6, 101, 101, 101, 67, 67, 80, 42, 18, 80, -49, -117, -89, 68, + -112, 99, 34, 114, 114, -23, -15, 38, 49, 4, -126, -117, -128, 41, -91, -74, -127, 60, + -24, -77, -31, -124, -20, 120, -77, -127, -91, -128, 110, -53, 123, 80, -127, 68, 103, + 56, 50, 0, 114, 38, 58, 58, 119, 99, -123, 0, -36, 58, -125, 35, -80, -124, 110, 76, + -83, -78, -123, -34, 66, 80, 99, 67, 109, 0, -85, 114, 38, -82, -11, -120, -117, 14, 63, + 109, 81, 95, -10, 49, 0, 0, 68, 111, 49, -98, -85, -98, 49, -85, 82, -98, -85, -85, 49, + 5, 38, 50, 68, -98, -36, -123, 58, -34, 0, -127, 68, 68, -78, 111, 111, -128, 49, 52, + 104, 52, 49, -128, -128, 16, 104, -89, -127, 3, -107, 26, 96, 63, 124, 125, 104, 12, 89, + 17, -121, 112, 72, 94, 15, 93, 30, 83, 33, 102, -123, 0, 90, 85, 8, -18, -20, -125, 84, + -114, 110, -50, 4, -107, 8, 100, 111, 81, 102, -121, -15, -4, 85, 85, 85, -107, -120, + 58, 37, -122, 127, 90, 37, 80, -121, 67, 58, 85, 6, 20, 4, 65, 11, 103, 58, -112, -103, + -123, -40, -10, -112, 90, -20, -125, 87, -105, -18, -126, 38, -123, 10, -51, 4, 121, + -108, 104, 106, 95, 101, -78, 70, -113, -76, -120, -30, 100, -20, -102, 104, 106, 111, + 96, 70, -123, -123, 93, 93, 80, 3, 92, -14, -42, -112, 0, 37, 66, -123, 53, -63, 90, 53, + 90, -53, -68, -127, 90, 0, -101, 22, 118, -6, -46, -60, -32, -75, 78, 20, 81, 78, 3, + -123, -120, 110, 118, 55, -82, 32, 68, -63, 46, 37, 90, 0, -116, 51, 94, 91, 75, -19, + 37, -44, 90, 71, 75, -37, -46, -15, 102, -73, -87, -85, 127, 53, -122, -84, 46, -15, 16, + -74, -14, 109, -116, 45, 58, 65, -44, -120, -122, -95, 103, 1, 12, 37, 47, 90, 90, -117, + 85, -3, 78, 70, -15, 109, -111, 68, 84, -63, 18, -117, -123, 50, 103, -24, 63, 3, 92, + -46, 41, 44, -48, 114, -122, 16, 77, 23, 71, 102, -125, 80, -123, 111, -126, 73, 14, 33, + 90, 87, -40, -59, 76, 63, 73, 9, -4, -72, 76, 40, 60, 52, -115, 96, 104, 20, -83, -127, + -15, 90, 95, -72, 18, 0, 33, -76, 109, -20, 42, 16, -124, 90, 60, -53, 85, -117, -72, + -123, 107, -72, -123, 97, 46, -81, 69, -16, -40, 42, -83, 53, 107, 89, 63, 83, -123, + -123, 32, 121, 53, 20, 91, 54, 86, 107, 32, 103, 58, -101, -32, 74, -85, 11, 109, -115, + 41, 104, -116, -95, -85, 26, 74, 102, -6, 53, 18, 98, -46, -128, 118, 87, 16, 92, -100, + -95, 100, -76, 121, 115, -73, 4, 118, -75, -40, 115, 36, -4, 83, 106, 118, -81, 106, + -112, -123, -36, 40, -127, 95, 40, -59, -36, -123, -123, 96, -125, 67, -123, 94, 58, + -125, -118, 87, 111, 30, 102, 111, 39, 85, 85, -118, 111, 111, 92, -117, -118, 91, 35, + 35, 35, -118, 39, 59, 41, 39, 65, 58, -7, -7, 105, 122, 65, 43, 47, 86, 84, -121, 60, + 43, 32, 104, 0, -23, 58, 83, 8, 43, 113, 84, 8, 14, -76, -122, -125, 25, -80, -120, 120, + 76, 20, 87, 96, 43, -126, -76, 119, -20, 85, 0, 90, 119, 87, -87, 34, 111, -92, 68, 0, + 80, 20, -61, -39, -117, 125, 40, -111, 15, -65, 67, 0, 9, 30, 104, 51, 25, 26, -77, 57, + 0, 102, 39, 0, 59, -3, -76, 104, -122, -125, -128, -61, -6, -76, -76, 32, 45, 98, -84, + -125, -125, 27, 100, 90, -10, 100, 100, 26, 26, 104, -90, 68, -123, 2, -49, 66, -123, + -122, -16, 78, 104, 31, -59, -60, 93, -4, 111, 111, 34, 93, 72, 86, -6, -66, -112, 126, + 54, -123, 88, 14, 90, 74, 80, 84, -123, -6, 32, 81, -4, 12, 89, -104, -122, -76, -120, + -127, 0, -6, 100, 86, 6, 19, 91, -127, 122, 122, 84, 84, -115, 101, -123, 114, 0, 5, 41, + -65, 99, 85, 13, 113, 49, 106, 110, 15, 104, 0, 80, -87, -15, 77, 87, 33, 25, -120, 52, + 104, 112, 8, -80, 58, 66, 63, -58, 1, -87, 10, -108, -51, -18, 10, 101, -56, 104, 104, + -117, -12, 21, -103, -120, -40, 20, 19, 32, 3, 102, 87, 12, 119, 107, 124, 70, -117, 67, + -36, 93, 121, -10, -63, 90, 38, 102, 14, 80, 90, -113, -65, 83, -1, -65, -65, 6, -112, + -53, -112, 63, 38, 101, -120, -78, 0, -37, 0, 97, 107, 2, 96, -55, -87, 15, 106, 98, -4, + 31, 36, 111, 94, -112, -82, 84, 76, -98, 27, -125, 48, 101, 106, -66, 30, -123, -123, + 90, 111, -120, -112, -124, 126, 106, 30, 82, 15, 17, 39, -66, 69, -122, 0, -120, 98, + 124, -102, 5, 92, 56, -120, 92, 43, 26, -120, 80, 3, 40, 38, 12, -125, 64, 125, -10, + -87, -121, -91, 15, -116, 56, -126, 10, 14, 27, -2, 126, -127, 59, 0, 15, 127, 107, -73, + 107, -4, -121, 55, 106, -68, 119, -121, 102, 72, 80, 41, 71, 90, 12, 106, 115, 14, 21, + 114, 63, 71, 54, 54, 37, 36, 84, 17, 85, 99, -87, -7, -120, -53, -87, -116, -127, 76, 3, + 30, 56, 36, 87, -117, -63, -61, 92, -120, 35, 91, -114, 100, 68, 110, 55, 105, 112, 110, + 55, -126, 79, 110, -33, 34, 87, -92, 90, 77, -53, 81, -122, -48, -51, -111, -94, -85, + 39, 83, 71, 87, -128, 110, 107, 107, 0, 46, -66, -66, 48, 111, -120, 63, 4, 70, -125, + -110, 102, -95, -76, -117, 80, -114, -36, -97, 115, -7, 116, 95, 109, 90, -74, 33, 40, + 50, 45, 126, -62, 23, 6, -87, 71, 20, 112, 10, 0, -116, 85, 0, 63, -122, -7, 59, -121, + -128, 58, 99, 122, 102, -80, 85, -121, 3, 79, 13, -121, 100, -109, -125, -81, 59, 41, + 65, 60, 121, -127, 115, 53, 61, 46, 11, 33, 124, 85, -94, -6, -61, -10, 80, 58, 30, 124, + 100, 104, 66, -6, 78, 27, -49, 0, 75, -118, 67, -73, 0, 0, -61, 0, 0, 68, 107, 107, 107, + 89, 22, 3, -108, 88, 78, 111, 111, 90, -85, 96, 96, -48, 120, 83, 46, 89, 111, -14, -65, + 3, 77, -73, 107, -128, 103, -124, 78, -105, -105, -117, 10, 16, 85, 90, 3, 4, -125, 90, + -72, -72, -17, 87, 119, 119, 120, 100, 71, -120, -112, 88, 37, 96, -5, -120, -60, 125, + 37, -7, 96, 70, -121, -4, 80, 20, 80, -23, -127, 121, 118, -126, 73, 102, -114, 49, 5, + 80, 87, -98, 68, 127, 85, 39, -6, -93, -111, 102, 112, -63, 114, 41, 63, -117, 105, 0, + 2, 32, -112, -98, 0, -124, -77, 80, -22, 0, 51, 106, 39, 46, 39, 114, -125, -92, -30, + -61, 115, 6, 53, 112, -87, -117, 85, 9, 41, 95, 71, -79, -128, -125, -4, -109, -9, 55, + 112, 41, 111, -101}; + +} diff --git a/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinCode3.java b/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinCode3.java new file mode 100644 index 00000000..54c7cd60 --- /dev/null +++ b/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinCode3.java @@ -0,0 +1,429 @@ +package org.rx.util.pinyin; + +/** + * Created by guyacong on 2015/9/28. + */ +//CHECKSTYLE:OFF +class PinyinCode3 { + + private PinyinCode3() { + //no instance + } + + static byte[] PINYIN_CODE_PADDING = new byte[]{-80, 9, 83, 102, -105, 4, 40, 15, -59, -122, 34, + -48, -124, 7, 1, 50, 66, -128, 4, 45, 104, 73, 121, -4, -77, -109, -121, -110, -120, + 110, 52, -34, -119, 42, -119, -128, -54, 46, 52, -68, -108, 25, -113, 53, 9, -113, -70, + 1, 104, 1, -128, 3, -116, 76, 112, -106, 114, 97, 11, -50, 76, -104, 80, -48, 19, -116, + -31, 33, 1, 59, -30, 34, -87, 11, -37, -63, -84, -125, 48, 70, -12, -102, -40, -64, 106, + -83, -34, -67, 32, -62, -14, 107, -101, 33, 31, 12, 78, 113, 59, -120, -22, 35, 20, -56, + 27, 14, 55, -69, -94, 0, 16, 67, -87, -47, 97, -72, 60, 75, -99, 12, -23, 125, -126, + -62, -26, -111, 11, 53, 36, 96, 33, 8, 50, -21, -127, 12, -120, 52, 98, -62, -30, -64, + 56, 85, -64, 58, 20, 37, 11, 4, -58, 46, 44, -45, 11, 64, -64, -47, 126, 4, -125, 74, + 72, 104, -126, 80, 5, -114, -43, -26, 51, -60, -66, -26, -105, -21, -97, -34, -127, 40, + -97, -72, 79, 66, -88, 98, 36, 119, 24, -39, 92, 28, -23, 89, -112, -22, -110, -88, -93, + 100, 21, 23, 118, -96, 98, -12, 75, -52, 96, 12, -8, 34, -79, -19, 5, -118, 103, 41, + 110, -102, 26, 109, 17, -9, 66, 89, -30, -41, -90, 24, 93, -74, -78, -109, -57, 7, 111, + 69, 46, 36, 40, 4, 1, -48, 62, 15, 66, -103, -94, 1, 50, 0, 37, -44, 88, -76, 5, 50, + -128, -90, 103, -37, 36, -108, 11, 101, -71, -17, -52, 82, 89, 69, 24, 56, -103, -59, 4, + -3, 103, -29, 35, 79, -128, 15, 71, -49, -24, -31, 14, -64, -23, 64, 72, 4, -119, 42, + 10, -62, 106, -91, 12, 0, 23, -75, -79, -112, 84, -84, 16, 52, -111, 68, 34, 2, 38, 48, + -118, -36, -51, -120, 1, 36, 81, -54, -75, -127, 37, 8, 48, 119, -126, -25, 110, 86, 4, + 96, 67, -43, 59, -122, 64, 98, -128, -102, 112, 125, 19, 72, -20, 10, 33, 0, 18, 1, 108, + -20, 105, 50, 28, -48, 99, -88, 15, -10, 83, -73, 19, 1, -53, 69, -51, 15, -91, 50, -89, + 122, 97, 79, 45, 96, 102, 13, -92, 84, -93, -58, -94, 10, -102, 4, -108, -110, -95, 84, + 105, -34, 118, -63, 108, -78, 16, 82, -95, -38, -102, -29, 38, -32, 25, 105, 89, 99, 94, + -54, -118, -118, -55, 22, 42, 111, -112, 100, 16, 5, -36, -63, 112, -124, -120, -93, 83, + -96, 65, 92, -34, 71, 85, 66, 97, -30, 97, 32, 53, -18, 110, 60, 108, 12, -40, -113, + 112, 23, -16, -41, -87, 48, -86, 68, 64, -60, -111, -122, 40, 40, 3, 100, 2, -47, -92, + -75, 74, 64, 66, -42, 3, 106, 123, -94, 46, 111, 23, 10, -70, -126, 16, 80, 40, 49, 8, + 112, 66, -100, 48, -119, 34, -94, -92, -128, 84, 42, 33, 20, 1, 8, 21, -92, -116, 37, + 67, -119, 96, 33, 5, 44, 19, -121, 48, -107, 94, -53, -46, 41, 11, 17, -53, 0, -94, 17, + 74, 20, -120, 8, -92, -56, 0, -128, 66, -112, 76, -128, 39, 1, 1, -64, -105, -54, 61, + 11, 33, -120, 96, 78, 7, 25, 32, -37, -92, 2, 125, -30, 56, 26, 3, 66, 41, -15, 108, 51, + -63, -4, -66, -119, -27, -106, -105, 7, 39, -102, 63, 34, 74, -78, 48, -89, 36, -64, + -15, 64, 39, 86, -119, 29, -125, 20, 0, 0, 38, 33, 96, 41, -105, -53, -95, 10, -24, 50, + -20, 2, 42, 68, 32, 25, -62, 83, -38, -100, 123, -20, 106, 23, 3, 0, 57, 32, 20, -26, 8, + -98, -4, 3, 18, -103, -80, 62, 20, 40, 105, 27, -78, -80, 50, 95, 2, -120, 117, -128, + -79, 79, 62, 89, -58, -82, -128, -89, -38, 64, 40, -109, -105, 53, -75, -111, -54, 79, + -43, 8, 33, 20, 89, -126, -56, 41, 118, 63, -15, 89, -111, -19, 120, 7, -111, 113, -28, + 20, 109, -128, 111, 37, -13, -83, -96, -77, -36, -70, 89, -31, -26, -100, 11, 112, 56, + -115, -40, 94, 33, 32, -104, 0, 28, 64, 52, -88, -63, -30, -39, 7, 68, 6, 16, 2, -125, + 12, -64, -83, 64, 23, 105, 41, -119, 24, -123, -120, 9, 42, -49, 68, -128, -66, 56, 12, + -44, 64, 8, -56, -80, 18, -70, 56, 74, 74, -39, -53, -128, 53, 122, -103, 29, 21, 78, + 80, 96, -104, 1, 6, -47, -16, 96, 49, 1, 14, 47, 73, 33, -82, 72, 8, -60, -48, 66, -89, + 96, 122, -12, 119, 12, 39, 13, 80, -75, 20, 6, 41, -28, -116, 32, 16, -47, -126, -107, + -128, -49, -95, 78, -117, 108, -54, -69, 12, -71, 123, -23, 67, 6, 23, 84, -30, -4, 20, + -63, 7, 24, -14, -28, -112, 17, 34, 65, 17, 0, 99, 8, -64, 20, 2, -127, 37, -24, -96, + 119, 104, 73, -126, 58, 42, -124, -31, -109, -1, -16, 51, -11, 40, 64, 29, 113, 80, -76, + 69, -60, 27, 66, 33, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + static byte[] PINYIN_CODE = new byte[]{-21, -7, -7, -50, 48, 85, 86, 114, -124, -125, -127, 21, + 25, 79, -60, 114, 55, -125, -55, 0, 95, -79, 85, 102, -92, 15, 82, 92, 55, 39, 60, -73, + 17, 56, 87, 11, 102, 107, 14, -111, 108, 0, 94, 27, 0, -93, 0, -127, -87, 24, -92, 111, + 0, 107, -53, 66, 94, 84, 69, -120, -16, 3, -85, 49, 85, -10, 3, -121, 46, -122, 80, 73, + 26, 111, 104, -127, -83, 14, -76, 95, 21, 127, -73, -3, -67, 100, -88, -127, 16, 108, + 112, 63, 52, -76, 35, 33, 63, -57, 98, -67, 20, 63, 55, -127, 28, 96, 111, 121, 5, -60, + -77, 51, -122, 23, -9, -124, -60, 49, -37, 126, -114, 106, -125, -39, 41, 106, -98, 36, + 121, 30, -104, -4, -69, 25, 120, -3, 71, -85, -81, -104, 2, 14, -87, 80, -127, -4, 38, + 83, -61, -24, 32, 65, 98, -123, 19, 19, -89, 111, -2, 41, 122, -125, -68, 114, 10, 110, + 4, -76, 10, 126, 77, 64, 85, -115, -107, 82, 17, 86, -98, 47, 19, 99, 95, 90, -115, 59, + 84, 69, 49, 89, 85, 109, 81, 34, -6, -125, 114, 55, -80, 111, 86, 82, -127, 119, 49, 62, + -89, 96, 114, 111, 85, 114, 20, 114, 2, 80, 126, 80, -127, 48, 88, -75, -57, 104, -88, + -124, 24, 37, -3, -85, -108, 112, 56, 64, 60, 97, 14, 126, 55, -85, 83, 68, 89, 102, 90, + 41, -125, -109, 119, 22, 91, 98, 102, 7, 51, 41, 98, 74, -11, 80, -42, 40, -68, 17, -13, + 58, -6, 119, 36, -125, 80, -40, 107, 95, 49, 89, -6, 82, -125, 95, -98, -122, 15, 63, + -60, -93, -121, 118, -58, 2, -1, 87, 0, -24, 87, 52, -72, 104, 95, 90, -87, 104, -95, + -89, -123, 63, -123, -15, 63, 102, -53, 124, 16, 83, 51, 59, 73, 2, -2, 80, -79, 126, + 41, 95, 114, 0, -87, -120, -120, 2, -81, 119, 96, 36, -94, -128, 75, 84, 19, 19, -6, + 118, -76, 52, 73, -66, 114, -11, 111, 98, -127, -119, 96, -53, 0, 52, -119, 0, -36, 20, + 9, 104, 87, 111, -117, -85, -85, 106, -3, 107, -78, 70, 80, 113, -80, 4, 102, 83, -60, + -93, -98, -93, -127, 59, 0, -89, -89, 69, 87, -123, 80, -98, 126, 123, -87, -127, -60, + -89, 123, -73, -127, -46, -76, -125, 0, 0, -89, 5, 89, 104, -75, -62, 17, 121, 121, -76, + -26, -72, -123, 89, -4, 41, 121, 95, 55, 90, 95, 95, -76, 121, 111, 114, -123, -117, + 109, 10, 100, 126, 126, -98, 8, 85, 41, 39, 3, 66, -127, 3, 68, 39, 0, 63, -127, 35, + 111, 93, -112, 119, 126, -61, 96, 54, 86, 31, 39, 104, -69, 88, 84, 77, -23, 38, -4, 81, + 81, 19, 9, -15, 113, 113, -114, -6, 8, 106, -6, 24, 112, -115, 126, -4, -6, -122, 99, + 114, -51, 79, 86, 86, 113, 100, 119, 90, 8, -122, 90, 38, 71, 10, 87, -40, 62, 3, 110, + 124, -10, 38, 110, 115, 112, -117, -87, 90, 8, 124, 101, -15, 20, 87, -120, 66, 17, 19, + 102, 8, 4, 35, 67, -80, 102, 58, 102, 107, -87, 37, 4, -52, 96, 48, 126, 126, -66, 90, + 101, 76, -82, -120, 104, 87, -96, -123, -87, 104, -10, -127, 110, 35, 104, 79, -53, 2, + -1, 107, 100, -123, -67, 0, -127, -126, -46, 49, -6, 92, -82, 3, 34, 109, -126, 73, 35, + 7, 77, 112, 41, 96, 87, 37, -125, 90, 87, -127, 84, 90, -87, -92, 14, 41, 112, 110, + -122, 58, 100, 68, 65, 73, 126, 83, -123, 50, 85, -117, -60, -6, -6, 111, -114, -95, + -61, -3, 49, 85, -74, -87, 67, 66, 61, -97, 93, 112, 111, 9, 85, -15, 80, 75, 104, 112, + 52, 5, -4, 19, -40, 1, 80, -84, 109, 78, 70, 77, 8, -113, 79, 24, 101, 107, 109, 32, 0, + -95, -108, -127, 90, 68, -68, 95, -59, 111, -122, 39, 96, 125, 100, 15, 16, 80, 90, 112, + -63, 80, 90, 18, 90, 110, 110, -65, 86, 107, 39, 39, 60, -120, -111, 64, 90, 112, -98, + -61, -95, 72, 121, 3, 67, -87, 103, 114, -117, -48, -77, 46, 15, 107, -124, 74, -92, + -20, 49, 85, 85, 85, 112, 82, -85, 51, 8, 15, 15, -127, 84, 94, 112, 0, 104, 14, 122, + 60, 104, 72, -49, 115, 121, 85, -69, -55, 104, 81, 107, 63, 111, 25, 0, 0, -67, 0, 33, + 39, 26, 38, 63, 5, -76, 80, -123, 60, 36, -13, 4, -15, 111, -125, -73, -77, 0, -122, + 106, -124, 43, 81, -123, 78, -127, -127, -69, -69, 109, -83, -65, 85, 49, -87, -67, 89, + 0, 127, -66, 88, -53, -112, 49, 3, 62, -123, -16, -16, -123, 4, 17, -83, -21, 107, 85, + -127, -117, 125, 85, -91, -115, -115, 126, 106, 32, -123, 32, 10, 89, 84, 39, 98, 49, 0, + 37, 59, -87, 90, 32, 104, -120, 56, 32, -6, -112, 88, 35, -73, 0, 107, 31, -87, 120, 96, + -85, -120, 120, 90, -66, 90, -6, 15, -125, -61, 114, 17, -128, -113, -122, 18, 115, -57, + 83, -89, -122, -95, -60, -87, 46, -87, 3, -36, -76, 72, 89, -120, -78, -87, -78, 87, + 103, -15, 9, 102, -116, 107, 0, 85, 24, 4, 5, 72, 24, -67, 4, -122, -120, 124, 97, 125, + -27, -18, -27, 91, -122, -53, 80, -57, -57, 39, 92, 100, -111, 112, 0, -80, 96, 41, 87, + 69, -78, -122, 87, 99, 121, 80, 60, 39, 80, 60, -114, 118, 4, 104, 104, 21, 93, 111, 16, + 30, 104, 32, 36, 90, 108, 86, 43, -122, -50, -122, 58, 14, -122, -122, 90, -6, 90, 8, + -123, 12, 0, -121, -114, 112, -63, 31, 5, -37, 126, 8, -126, 75, -80, 57, 10, -19, 102, + -105, 14, 34, 59, -117, 115, 97, 94, -125, 104, -23, 20, 63, 76, 90, 108, -123, -123, 8, + -21, 104, -65, 0, -50, -104, 96, 32, 4, 11, 111, 85, 0, 20, 0, 90, 104, 38, -103, 12, + -124, -126, 54, -53, -122, 80, 96, 17, -120, 107, 106, 23, -82, 0, 0, -116, 59, 0, -97, + -107, -37, 41, -126, -97, 37, -87, -116, 37, -8, 96, 104, 111, 36, -79, 3, 7, -127, 104, + 21, -116, 46, 30, 7, -87, -85, -85, -103, -125, 89, 59, 14, 108, 61, 112, -80, 38, 33, + 40, 76, 16, -84, 33, -18, -18, 85, 112, -73, 109, 100, 72, 64, -123, -117, -6, -127, + -123, 103, -107, 0, 64, 39, 90, 39, 90, 15, 67, -97, 73, 94, 94, 115, 112, 10, 10, 90, + 111, 72, 100, 126, 11, 41, -72, 0, 0, 114, 57, 101, 56, 123, 15, 112, 17, -49, -119, 56, + 8, 74, 38, 25, -37, 107, -122, -4, 123, -103, -85, -93, -87, -127, 39, -72, 104, 67, 90, + 87, 80, 16, 26, -127, -3, 28, 10, 88, 0, -7, -125, -117, -125, -107, -127, 58, 115, 83, + 20, 88, 91, 17, 10, -67, -93, 5, 76, 126, 26, 54, -32, 32, -85, 14, -121, 59, 41, 59, + 14, -93, -7, 17, -123, 0, 41, 76, 39, 7, 90, 20, 36, -94, -78, 85, 87, -93, -127, 57, 0, + 117, 39, -125, -21, 104, 0, 99, 85, 85, 102, 87, 59, 0, 0, 90, 6, 115, -127, -127, -125, + 105, 15, 100, 107, -115, -14, -65, -60, -60, -57, 39, 49, 126, -73, -115, -53, 66, -85, + 102, -123, -114, 85, 32, 80, 85, 65, 111, -93, 77, 72, 0, -20, -127, -55, -10, 101, 4, + 126, -121, 105, 62, -125, -73, 4, -125, 80, -115, 4, -73, -93, 37, 63, 105, -125, 105, + 100, 107, -60, 39, 32, -93, -115, -127, 85, 63, 65, 111, 101, -121, 4, -123, -118, -121, + 51, -115, -123, 34, -127, 102, 58, -107, 63, 33, 122, 5, 96, -123, -122, 107, 100, 41, + -122, 124, 3, 92, 52, -40, -127, -76, -123, -120, 14, 92, 121, 33, 100, -123, 97, 41, + 85, 104, -87, -115, 85, 100, 85, 100, 100, 68, 90, 3, 3, -123, 119, -127, 83, 98, 66, + 119, 30, 61, 95, -122, 104, 12, 98, 106, 32, -6, 75, -127, 98, 106, 77, 86, 99, 102, 50, + 37, 106, 91, -115, 89, -45, 36, 110, -123, 93, 84, 91, 34, 35, 87, 22, -114, 95, 104, + 104, 52, 38, 115, 37, 115, 95, -125, -120, -124, 101, -112, -112, 126, 102, 90, -125, + 67, -80, 63, 101, -87, -46, -21, -121, 93, 39, -117, 5, 124, 75, 104, 4, -128, -10, 14, + 93, 41, 6, 56, -109, 61, -120, 48, -127, 109, 95, 98, 104, 125, 115, 39, 30, -123, 39, + 117, 30, 101, 107, 5, 126, -122, 122, 92, 88, 126, 37, 40, 69, -60, 126, -55, 77, 126, + 100, 93, 103, 80, 13, 66, 38, -89, -120, -99, -102, 84, 111, 63, -127, -123, 12, 52, + -92, 77, -99, 81, 39, 68, 58, 11, 32, 110, 118, -2, 0, 42, 3, 111, 89, 37, -122, 87, 84, + 84, 95, 50, -7, 126, -120, 48, -125, 48, 72, 0, 33, 46, -122, -108, 4, 49, 89, 54, 79, + 96, 85, 38, 57, 104, -50, 106, 66, -15, 47, 32, 36, -114, -127, -6, 59, 45, 80, -117, 1, + -125, -124, 120, -110, -4, -113, -84, -125, -120, 114, -74, 37, 16, 123, -14, 111, 67, + 95, -14, 39, 96, 39, 127, 122, 77, -122, 63, 90, 90, -7, 68, -125, -6, 111, -112, 43, + 85, 126, 106, 3, 87, -48, 36, 87, -120, 101, 100, 118, 96, 96, -28, -6, -52, 103, 80, 0, + 63, -110, 32, -125, 20, 0, 125, -128, 96, 107, -60, 89, -60, 85, -3, 36, -26, 49, 52, 9, + 38, -4, 39, -124, 112, 90, 97, 61, 102, 102, 121, 111, 16, 49, 1, -87, -53, -53, 33, + -127, -54, -125, 120, 124, -85, -77, 24, -24, 105, 85, -113, 5, 5, -121, -127, 104, 121, + -124, -67, 34, 112, 122, 32, 95, 123, 27, 85, 35, 74, -124, -46, -93, 77, 107, -115, + -127, -106, -123, 20, 126, -117, 84, -125, 124, 39, -2, 59, 122, -7, 38, 96, 119, 126, + 59, 54, -4, -127, -123, -120, -85, -31, 104, 2, 126, -15, 126, 122, 104, 104, 32, 9, + -31, -4, -115, 57, 121, -121, 114, -40, 107, -125, 111, -125, 126, 72, -127, 96, 117, + -89, 37, 80, 32, -87, 104, 15, -127, 100, 77, 40, 80, 40, 102, 32, 9, 106, -93, 36, + -128, -127, 124, 117, 104, 59, 126, 100, 72, 100, -127, 68, 90, 12, -127, -122, 119, 61, + 9, 32, -6, 75, 98, 104, 98, -127, 12, -124, 126, -24, -117, 99, -45, 95, 77, -74, 93, + 50, 87, 35, 84, -115, -124, 102, 115, -10, -109, 39, 93, 124, 52, -125, 63, -121, 48, 4, + -128, 14, 104, 104, -99, -89, 39, 103, 39, -122, 126, 37, -120, 37, 122, 58, 101, 5, + 107, 98, 104, -124, 92, 88, 30, 127, 95, -121, -122, 84, 111, -2, 84, 95, 110, 126, -99, + 48, 50, 78, 1, -120, -110, -28, 72, -113, 85, -108, 80, 111, 36, 37, 66, 32, -84, -114, + 54, 59, 37, 104, -52, 36, 67, 125, -125, 90, 97, 103, 80, 77, 111, 96, 32, -112, 3, 100, + 63, -60, -14, 95, -53, 59, 52, 90, 102, 9, 39, -4, -60, -121, -67, -127, -125, -54, 59, + -125, -2, -93, -7, -115, 100, -4, 126, 36, 102, -4, 119, 99, -115, 119, 112, 119, -6, + 85, -128, -83, 112, 72, -78, 71, -124, -6, 38, 87, 62, 78, 14, 41, 87, 87, -123, -123, + 100, 100, 39, 41, 126, 74, 104, 74, 104, -125, 6, 120, 77, 51, 88, 124, -125, -107, 92, + 4, 90, 85, 18, 114, 111, -120, -126, 86, 85, 121, 81, 124, 18, 63, -111, 86, 104, -123, + 10, 31, 112, -15, -50, -15, 101, 76, 110, 66, -53, 49, 94, 124, -97, 115, 115, -53, 3, + -65, -87, -40, 14, 111, -126, 72, -65, -15, 85, 77, -117, -53, 41, 59, 124, 4, 11, -125, + 112, 90, 23, 100, 62, 104, 113, 78, -11, -128, 83, 59, 105, 120, -123, 80, -120, 39, 14, + -112, 80, 107, -14, 15, -68, 57, 38, -99, 85, 67, 104, 38, -65, 115, 14, -76, -81, 126, + 92, -14, -112, -126, 95, 121, -123, 92, 118, -125, 107, 98, -125, 35, 18, 18, 3, 35, 43, + 118, -121, -94, 117, 49, 36, 33, 65, -18, 99, 87, -68, -125, 54, 90, 58, 49, 49, -123, + -127, 127, 72, -121, 93, 47, 114, 10, 116, -94, 87, 25, -127, 38, 2, -117, 90, 101, 23, + 120, -83, 80, 7, 36, -117, -123, -115, 16, 114, 123, 59, 117, 100, 0, 32, 78, 107, -121, + 93, 87, 118, 14, 72, 41, 100, 0, 96, -78, 93, 118, 11, -125, 90, 112, 100, 23, 120, 87, + 7, 127, -128, -123, 83, 59, -11, 15, 101, -120, 105, 80, -125, 14, 39, 67, 107, -99, 57, + -65, 85, 115, 104, 121, -123, -126, 126, -112, -81, -76, 118, -112, 92, -121, 3, -125, + -94, 35, 90, 72, -127, 41, 33, 48, 14, -121, 99, -18, 58, -94, 87, -115, 90, -117, 23, + 120, 100, 117, 114, 123, 32, 107, 93, 38, 85, 35, -48, 93, 85, 37, 115, 37, -127, 86, + 60, -110, -110, -87, -118, 90, -128, 93, -6, 32, 2, 0, 87, 48, -115, 0, 38, 48, 36, 36, + 67, -117, 34, 63, 27, 126, -120, 113, 4, -122, 38, 41, 103, 97, -112, 66, 76, -82, 93, + 56, 51, 85, -128, 52, 106, -117, -125, 6, 60, 47, 53, -76, 4, 59, 3, -112, 64, 4, 38, + 125, -2, -2, 102, 119, 113, 0, 117, 117, -109, -23, 10, -103, 115, 75, -115, 90, 36, + -125, 84, -123, 57, 113, -23, -6, 113, -3, 75, 58, 104, -39, -80, -63, 6, 67, -103, 75, + -126, 48, -19, -5, -120, -117, 67, -123, 90, -21, -117, 32, 20, -40, -117, -87, 98, 104, + -127, 57, 87, -123, 76, 41, 5, -102, -118, 107, 2, -98, 88, 38, -76, 13, -123, -126, 66, + 23, -125, 56, -2, 14, 87, 76, -127, -117, -127, 41, 71, 41, 92, -36, 89, 20, 97, 7, -52, + 41, -84, 109, -123, 40, 89, 0, 57, -125, -6, 83, 80, 47, -122, -127, -36, -117, -117, + -74, -76, -88, 123, -117, 38, 78, 5, 64, 20, -109, -1, -6, 51, -111, 23, -111, -21, + -123, -124, 65, -123, 111, 76, 75, 46, 109, -122, 63, 124, 36, 42, -125, 103, 60, -117, + 90, -109, 67, -14, 16, -28, 64, 30, 73, -125, 60, 55, 85, 57, -3, 126, 65, 64, -127, + -36, -21, -79, 126, 14, 39, -76, -83, 51, 60, 57, 52, 85, -98, -127, -123, -3, 63, -67, + -111, -85, 13, 119, -39, 17, 73, -117, 62, 29, 87, 83, 41, -122, 75, 20, 51, -109, -115, + -115, -81, 57, -2, -2, -7, -83, 75, 52, -99, 119, 57, 14, 14, -120, -117, 41, -2, 75, + 40, -127, 84, 113, -39, -81, -82, -123, -87, -123, 32, 41, 73, 80, -78, -81, 87, 80, + -108, -93, 90, 9, 90, -36, 57, 4, -122, 52, -108, 85, -98, -115, -81, 37, 100, 58, 0, 4, + 64, 76, 76, 100, -92, 0, -73, 2, -127, -117, 60, 0, 0, 100, 0, -110, 4, -77, -91, 76, + -123, 0, 64, 60, 0, 111, 35, 99, 107, -114, 80, 113, 91, 63, 96, 83, 12, 32, -3, 41, 74, + 36, 57, 77, -50, -6, -65, 18, 12, -4, -117, 119, 121, 4, 125, 63, -80, 57, 5, -125, 83, + -99, 4, -16, 11, 102, 102, -19, -120, 15, 77, 6, -121, -123, 102, -108, 104, 1, 39, -10, + 80, 2, -117, -123, 106, -76, -112, 5, -121, 116, -123, -117, -84, 111, 34, 110, 124, + 114, -127, 78, 90, 1, -121, -40, -80, -127, 126, -84, -112, 126, 79, 47, 109, -111, 104, + -16, -4, 108, -39, -10, 105, 11, -74, -22, -84, 18, 16, -127, 101, 87, 43, 50, 46, 96, + 110, 119, 41, 90, -112, 90, 81, 12, 126, 111, 81, 61, 102, -125, 86, 112, -76, -118, 34, + -117, 80, 127, 0, 35, -123, 126, -7, -91, 86, 83, -81, 96, 27, -111, 124, 104, -127, 74, + 80, 111, 87, 119, -89, -18, -87, -87, -76, -81, 35, 99, 107, 96, 57, 12, -117, 77, -74, + 18, 119, 102, -108, -76, -121, -123, 104, 121, -125, -87, 102, 1, 39, 116, -123, -123, + -121, 5, -76, -123, -127, 90, -84, -39, 11, 126, 108, 79, -84, 47, -112, 50, 90, -127, + 81, 41, -18, 112, 86, 126, -76, -127, -81, 91, 102, 48, 48, -15, -107, 15, -95, -95, 48, + 97, 8, 15, 15, 15, 0, 15, 8, 48, 15, 15, 36, 17, -32, -32, -125, 47, 47, 0, 13, 15, 15, + 0, 0, -83, 56, 32, 93, -4, 111, 111, -6, 98, 104, 109, -68, -6, 115, 79, 0, -114, 107, + 64, 114, -121, 113, 99, 83, 84, 57, 77, 111, -126, 0, -121, 112, 80, -85, 38, 35, -40, + 66, -123, 104, -119, -126, 36, 57, 80, 63, -9, 79, 67, 120, 61, 41, 75, 0, -120, 126, + 69, 110, -60, 13, -127, -49, 104, -122, -115, -82, 98, 73, 50, 39, 61, -20, 120, -40, + 75, -119, 96, 98, 21, 110, 89, 3, 70, -120, 3, 63, 63, 71, -120, 64, 71, 104, -127, 69, + 106, 84, 39, 37, 52, 119, 7, 87, -85, 56, 126, -87, 0, -107, 12, 55, -115, 13, 124, 57, + -76, 110, -121, -121, 111, 47, -98, 80, 64, 104, 56, 112, -73, 14, -28, 111, 59, 54, 75, + 54, 100, 43, 38, 64, 111, 39, -125, 110, 114, 77, 15, 109, 77, 86, 125, 3, 60, 56, 80, + 0, 104, 101, 102, 41, -79, 98, 57, 63, 38, 112, 52, 57, -4, 0, 102, 105, 127, 5, 39, 27, + 52, 52, 119, -127, 75, -123, -77, 38, 55, -81, -106, 10, -4, 96, 111, 104, 84, -83, + -117, 39, 14, 102, -68, 90, 54, 124, 126, 62, 80, -58, 15, 15, -95, -87, 112, 110, -73, + -87, 104, 68, 62, -6, 109, 32, 112, 111, -66, 17, 2, 0, -99, 90, -110, 18, 84, 92, -44, + 0, 37, 9, 112, 54, -128, 90, 9, 84, -117, 110, 112, 58, 3, 14, -15, 19, 34, 11, 76, 63, + -110, 103, -81, -99, 107, -120, 39, -103, 111, 92, 115, -1, -123, -127, 98, 120, 92, + -123, 85, 107, -28, -92, -126, -101, -124, -92, 114, 100, 37, 71, 85, -72, 90, 84, 90, + 95, 114, -92, -126, 99, -114, 107, 20, 85, 11, -87, 114, 21, 89, -6, -15, 1, 109, 0, 59, + -110, -10, -94, -40, 36, 110, 21, 88, 58, -117, 109, -2, 104, 71, 100, -63, 21, 11, 77, + 111, -116, 111, 114, 120, -98, 88, 88, 51, 60, -55, 85, 17, 41, -112, -110, -117, 84, + 88, 114, 114, 109, 14, -65, 34, 90, -83, 106, -117, 121, -2, 100, 127, 83, 84, 95, 62, + 14, 91, 14, 29, 80, -124, -65, 32, -81, -9, 58, -61, 103, 26, -101, 87, -61, -110, -99, + -85, 117, 32, 110, -6, 100, 32, 55, -80, 124, 85, 87, 117, -87, 110, 68, 3, -113, -18, + -121, 104, 93, 111, -118, 100, -107, -65, 58, 95, 70, -125, 86, 0, 0, 114, 58, 65, -5, + 75, -105, 112, 102, 52, 82, 40, 57, -55, -91, 47, 40, 110, 69, -123, 87, -124, 37, 106, + 71, -123, -63, -103, 53, -89, -7, -107, 111, 100, 39, -38, 80, -76, -93, 100, 61, -18, + 126, 46, 59, -107, 47, 51, -97, 64, 87, 72, 121, 95, 92, 59, 3, 46, 114, 82, -108, 51, + -60, 5, 40, 55, 114, 109, 4, 124, 111, 60, -124, -13, -91, 111, -87, 119, -91, 104, + -124, 21, -123, 85, 59, 82, -32, 104, -87, -117, 100, 104, -38, 17, 98, 40, 100, -80, + -60, -60, -38, 91, -123, 39, -60, 100, 15, 23, 39, 110, 39, 39, -87, -122, 103, -84, + -87, -121, -121, 91, 104, -83, 60, -128, 68, -87, 3, 115, 90, -125, -123, 6, -75, 90, + -49, 66, 32, -2, -104, 43, -112, 83, 111, 122, 112, 100, -6, -66, -125, 63, 49, 85, 104, + 31, 57, 71, 85, -27, -4, 0, -125, -15, 103, 106, 6, 84, 36, -125, 70, 113, 100, 90, 21, + -50, 91, 77, -115, 75, 101, 106, -4, 8, -127, 12, 34, -33, 86, 114, 104, 0, -15, 109, + 119, 106, -114, 39, 104, -122, -36, 92, 14, -128, 58, -110, 0, -76, 0, 0, 76, -112, -40, + 71, 39, -56, 102, -108, -80, 19, 104, 102, 6, -15, 111, 49, -105, 21, 110, 65, -126, + -125, 39, 39, 67, -117, 126, 57, 35, 96, -128, 10, 115, 14, 38, 41, 39, 20, -120, 38, + 115, -9, 69, -4, 90, 125, -79, -4, 90, -87, 113, -15, 101, 8, 20, -122, 101, 41, -124, + -51, -40, 85, 63, -126, -51, 59, 37, 104, 49, -99, -113, 11, -125, 69, 92, 119, -123, + 38, 80, 96, 19, 39, -52, -126, 106, -114, -121, 39, 33, 69, -53, -89, -127, 111, 95, 12, + 54, -123, 2, 32, 38, 87, 92, 5, -15, 104, -120, 120, -55, -102, 102, 87, 87, 94, -114, + 30, -91, -127, 109, 17, -60, 104, 106, 106, 3, 69, 110, 27, -109, -4, -75, 0, 2, 66, + 112, 19, 39, -106, 3, 89, -127, 94, 118, 64, 55, 103, 100, -122, 71, -72, -63, -92, 78, + 91, 114, 11, 84, 52, 111, 32, 68, 20, 112, -126, 119, 52, 87, 32, 78, -123, 49, 96, 84, + 84, 66, 100, -113, -71, 92, 0, 37, 112, 0, 103, 41, 123, -117, 87, 77, -66, -7, -87, 39, + 19, 37, 95, -87, 62, 0, -120, 0, 71, -79, -107, -117, 33, 112, -125, 94, 66, 61, 33, + -74, 109, -80, 11, -76, -87, 1, -18, -116, -56, -107, -16, 3, -15, 87, 99, -115, -89, 1, + -105, 57, -97, 72, 80, 45, -112, -124, 12, -36, 49, 46, 59, 68, -6, -4, -113, -6, 111, + -121, 105, -65, 33, 65, 85, -85, 61, 102, 55, 41, -125, -76, -61, -76, 122, 16, 91, -94, + -107, -115, 0, -49, 78, 117, 0, 61, 87, 0, -128, -84, 0, -62, -112, 107, 63, -85, 109, + 87, 72, 71, 80, 49, 90, 16, -127, 77, 16, 36, 64, 124, 119, 101, 73, 86, 111, -106, 92, + 125, 80, 90, -128, 30, -1, 35, 119, -98, -28, -52, -2, -2, 120, -125, -128, 124, 103, + -56, -125, 73, -125, 49, -98, 121, 96, 118, -122, -125, 15, -122, -112, 94, 103, -63, + -22, 2, -122, 0, -63, 30, 57, 9, 86, -85, 56, 85, -79, -109, 103, -31, 82, 15, 60, 56, + -3, 96, 48, 45, 20, -21, 57, 14, 25, 94, -112, 84, 107, 125, 66, -79, -112, 55, 30, 51, + 78, 114, -125, -125, -73, 104, 112, 60, -36, 85, -126, 96, -69, -116, 15, 0, 56, 0, 0, + 0, -50, -76, 56, -104, -109, 72, 94, 105, 96, -85, 40, 5, -67, -53, -73, 14, 80, -79, + 63, -2, -128, 106, -76, 5, -106, -3, 53, -6, 33, 60, -67, 109, 32, 87, -120, 16, 41, + -77, 94, 49, -78, 117, -125, 26, -87, 86, 85, -110, 0, 13, 0, 0, -124, -76, 122, -127, + -7, 126, -3, -9, -81, 56, 94, 24, 37, -98, 24, -79, -46, 125, -12, 54, 83, -2, 43, 101, + 60, 88, -115, -123, -106, -83, -122, -91, 74, 59, 117, -127, -125, -122, 62, -77, 107, + 74, -115, -31, 64, -7, 67, 0, 0, 68, 32, -112, -125, 85, 54, -76, -116, 126, 111, -85, + -113, -2, -4, -113, -89, 14, 67, 124, 103, 76, 109, 59, -117, 86, 56, 11, 104, 2, 59, + 98, 66, -120, 118, -115, -127, -36, 57, -128, 1, 18, 107, -98, -34, 95, -125, -125, -3, + 30, -123, -57, -87, -89, -127, -108, -99, 33, -16, -95, 72, 48, 47, -72, 16, 10, -76, 0, + 0, -78, 77, -76, 91, -125, -93, 20, -125, 102, 32, 88, -125, 85, 105, 25, -36, -89, 52, + 4, -21, -73, -108, -75, 119, -36, -115, 60, 41, -93, -121, 91, 104, -125, 68, -128, -9, + -83, 71, -4, 43, 32, 22, 83, 66, -62, -27, 101, 31, 92, 92, 21, 58, -117, 75, 34, -122, + -50, 11, 94, 8, -4, 102, 0, -114, 84, 101, -110, 84, -128, 70, -33, 6, 111, -4, -124, + -4, 102, 20, -108, -9, 21, 20, 113, -108, -51, 59, -126, 65, 110, 67, 20, -80, 48, -4, + -65, 10, 39, 96, 75, 14, -40, -15, 76, 92, -109, -91, 80, -66, 99, 110, 37, -126, 103, + -46, -123, 59, 69, -72, 66, 106, -112, 124, -120, 87, 68, 69, 87, 122, 5, 30, 110, 102, + 96, -55, -124, 27, -123, 104, 32, 39, 60, 3, 106, 17, -120, -91, -7, 84, -94, 62, -85, + -106, 89, 56, -87, 123, 41, 109, 95, 77, 94, 55, -71, 87, 91, -79, -112, -125, 19, 64, + -92, 0, -117, 1, 1, -127, -28, 55, -65, 12, -6, 61, -108, -97, 33, 85, 102, -73, 45, + -115, -121, -123, 87, -116, -128, -18, 59, 68, -125, -117, -61, -112, -1, 107, -112, -3, + 49, 77, 30, -2, -122, 73, 51, 125, 124, 2, 72, -63, -77, -112, 85, -63, -53, -125, 20, + 96, -36, 60, -116, -36, -50, -79, 114, 9, 104, -126, 18, 15, 16, 60, -67, -73, 13, 109, + -120, 63, -109, 96, -79, 32, -115, -83, -7, -76, 75, -93, -7, 52, -3, 62, -128, -89, + 124, -113, -85, 104, 30, 16, -95, 32, 88, 33, 33, -118, 5, 67, 4, -83, -60, 127, -62, + -69, 44, 32, -128, -62, 100, 14, 112, 14, 0, -112, -110, 13, 119, 20, 24, 87, 87, -125, + -56, 86, -56, 71, 124, -46, 0, -16, -108, -80, 15, 14, 20, 115, 105, 96, 115, 82, 41, + 119, 107, -56, 0, -97, -92, -72, 68, 30, 100, 113, 113, 32, 4, -81, 33, 31, -97, 100, + -56, 100, 77, 127, 111, 81, 88, 0, 88, 4, 102, 81, 8, 3, 80, 106, -96, 6, -93, 72, 0, 0, + 65, -36, 56, -112, 115, 6, 44, 105, 71, -6, -98, 60, 105, -13, -111, 85, 126, 32, -15, + 59, 124, 57, 81, 0, -62, 44, 32, 100, 112, 14, 81, 44, 20, 80, 87, 119, -125, -56, -110, + -62, 124, -46, 107, 81, 57, -56, -72, -112, 82, 96, 115, -97, -118, 113, -92, 72, 111, + 100, 33, 85, 81, 127, 100, 100, 32, -93, 4, 126, -96, 6, 115, 65, 56, 6, -111, 124, 90, + 90, -90, 74, 91, -4, 84, 104, 75, 106, 101, 71, 77, 38, 8, -18, -106, 114, 18, -123, + -15, -120, 84, 101, 106, -125, -122, 37, 77, 4, 63, -109, -105, 65, -80, 1, 75, 75, -9, + 19, 90, -127, -76, -78, 36, 92, 76, -77, -53, -124, 41, 76, 87, 80, 107, 84, 92, 32, + -114, -2, 92, 46, 90, 14, 32, 32, 38, -123, -7, 71, 112, -125, 41, 87, -123, -36, 114, + 87, -18, -18, -110, 104, 74, -74, 106, -117, 45, 36, -15, -80, 61, 87, -76, 0, 87, 106, + -120, 101, 13, 32, 39, 100, 106, 111, 64, 111, -78, 80, 80, -36, 74, 54, 3, 125, -122, + 54, 106, 92, 100, 126, 96, 114, 84, 80, 2, 85, 60, -127, 127, 60, 5, 85, 106, 22, 10, + -81, 73, 62, -15, 54, 54, 111, 87, 86, -40, 80, -127, 60, 85, 106, -123, 126, -78, 85, + -87, -87, -87, -115, 115, -123, 55, -116, -48, 104, 6, 100, 0, 99, 93, 99, -127, 102, + 124, -123, 101, -114, 48, 109, -117, 41, 121, 115, -73, 111, 40, 66, 54, 112, -128, 45, + 105, 41, 115, 109, -127, 54, 40, -79, -87, -48, 97, 115, -127, -127, 111, 111, 97, -50, + 89, 27, -51, 81, 86, -20, 114, -87, -87, 101, -80, -89, 3, 10, -61, 65, 59, 113, 84, + -128, 95, -127, -51, 36, 89, 124, 68, -125, -18, -63, -80, -6, 40, -128, 30, 85, 82, + 126, 107, -40, 40, 74, -81, 0, 70, 107, 84, -80, 45, -80, 86, 119, 106, -68, -53, 114, + -79, -61, 18, 84, 80, -96, 106, 85, 104, 2, 58, 62, 87, 111, -76, -78, 57, -127, -20, + 101, 6, -15, 80, 0, 85, -127, -68, -61, -61, -89, -87, -128, 2, 85, 57, -78, -80, 2, 87, + -87, 10, 0, 115, 115, 19, 1, 1, -120, -6, -125, -120, 37, 1, -120, -120, 65, -120, 65, + 85, 85, -109, -60, -59, -59, -19, 103, 65, 126, 103, 96, 68, 12, -125, 12, 63, 72, 84, + 12, 0, -121, 97, -33, 6, 106, 22, 12, -53, -109, 56, 8, 104, 102, 61, 11, -126, 119, + -19, 101, -53, 106, -126, 61, -127, 90, 3, 3, 117, 100, 100, 56, -2, 68, -67, 107, 54, + 66, -2, 96, -105, 13, 57, 127, 19, -96, -117, -95, 90, 16, 9, 104, 3, 3, 115, 89, -51, + -117, -125, 15, 63, -125, 0, 61, 101, 57, 11, 90, -21, 96, 14, -96, 60, -77, 107, -2, + 97, -127, -125, -124, 32, 56, -128, 87, -4, 72, 76, -125, -93, 80, 12, 90, -63, -116, + 96, 80, -2, 112, 33, 0, 16, 98, 35, 80, 96, 11, 61, 101, 114, 95, 14, 80, 126, 41, 76, + 72, 80, 12, 90, 112, 80, 114, 61, -118, -118, 87, 90, 87, -127, 106, 115, 114, 34, -73, + -16, 125, 107, 114, -16, 106, 106, 88, 121, 103, 68, 1, -21, 88, 47, 112, 95, 104, 95, + 102, 50, -98, -6, 113, 111, 78, 8, 75, 63, 58, -21, -9, -80, 37, -120, -89, 115, -2, 77, + 77, 80, -122, 103, 37, 104, 104, -108, 74, -14, -10, -89, 90, -126, 70, 126, -98, -126, + -90, 68, 37, 107, -114, 121, 112, -120, 73, 73, -11, -94, 73, -112, -112, 45, 68, -94, + 100, 112, -4, -108, 53, -119, 0, 104, 23, 64, 77, 77, 100, 127, -111, 109, -117, 100, + 87, 91, 104, 112, 25, 65, 65, -124, -103, -89, -83, -13, 104, -67, -6, 102, 114, -2, + 102, 98, -4, 126, 126, 17, 119, 18, 87, -11, -76, -93, -36, 5, 103, 68, 1, 112, 88, 47, + 95, 95, 78, 102, 75, -6, 8, 50, 113, 111, -76, -80, -9, -120, -122, -126, 68, 115, 107, + -119, -108, 104, -11, 126, 73, 112, 107, 107, -108, 64, 109, 77, -117, 100, 77, -36, + -67, 65, 25, 114, -89, 126, 17, -11, 5, 87, 16, 0, 90, 86, 126, 16, 22, 82, 58, -82, + 103, 96, 34, -117, 16, 49, 80, 101, 102, 51, -112, 26, 83, -79, 85, -83, -13, -13, -79, + 16, 16, 16, -83, 0, 27, 87, 16, 87, 101, 126, 16, 22, -117, 49, 51, 102, -79, -13, 16, + 16, 85, 83, 85, 85, 39, 39, 24, -127, 68, 49, 75, -125, 55, 88, 74, 12, 111, -116, 38, + 106, 83, 83, 55, 106, -120, 104, 125, 14, -122, 61, -79, 48, 67, 49, 10, 39, 76, 111, + 12, 65, -123, -126, 19, 102, 69, 48, 88, 101, 101, 80, 100, -90, 104, 24, 20, -44, 77, + 21, -114, 71, 52, 111, 39, 102, 127, 109, 39, -125, -115, 19, 87, 21, 103, 59, 85, 127, + 80, 105, 77, -29, 127, 121, 125, 67, 126, -125, 120, 115, 92, 86, 80, 102, 30, 50, 60, + 20, 95, 85, -98, -79, 51, 61, 103, 114, -53, 60, -67, 14, 111, 94, -121, 24, -98, -117, + 32, 38, 58, 104, -127, 10, 37, 109, 61, 126, 88, 126, 86, 111, -61, 100, -53, 32, 88, + -73, -108, -47, 39, 68, -127, 75, 92, 74, 85, 12, 111, 38, 83, 106, -125, 39, 10, 49, + 76, 104, 80, 10, 88, 115, -90, -123, 85, 19, 20, 71, 77, 111, -44, -114, 109, 127, 87, + 105, 30, -98, 102, 51, 32, 103, -53, 20, -79, 94, -121, -67, 24, -117, -47, 40, -98, + 109, 88, 86, 6, -40, 14, 20, 71, 112, 85, -125, 100, 2, 90, 87, 81, 91, 86, 18, 92, -69, + 111, 87, 112, 63, 75, 75, 38, 98, -120, -123, -18, 91, 14, 22, 106, 81, -123, 58, -72, + 110, 20, 10, -101, 75, 104, 4, 81, 4, -119, 20, -128, 112, -16, -121, -117, -120, -30, + -117, -15, 118, -126, -80, -125, 58, 90, 101, 39, 14, 75, 75, 49, -79, -69, -14, 61, + -123, 15, 63, 70, 98, 5, 37, -119, 80, 111, 20, 0, 106, -73, 0, 58, 90, -79, -117, 50, + 0, -66, -84, 112, 71, 96, 73, -114, 77, 37, 92, 2, -76, -115, -121, 35, -14, -97, 61, + -94, -111, -108, -6, -6, 100, 85, 26, 100, -122, 102, 84, -14, 49, -14, -4, 85, 125, + -125, -128, 111, 64, 5, 86, -111, -98, 16, 49, 103, 75, -98, 51, -4, 37, -123, -79, -20, + 63, 85, 26, 72, 100, 112, -110, 26, 32, -87, -123, 45, -76, 85, -73, 127, -53, 5, 24, + -13, 49, 4, 14, -123, 111, 95, 122, 20, 52, 89, -81, 126, 75, -79, 75, 123, 59, -123, + 67, 100, -73, 126, -120, 104, 103, 75, 18, -110, 100, -16, -72, 63, 88, -127, 45, -117, + 85, 124, -87, 16, -69, 111, 75, 98, 38, 4, 14, 20, -72, 118, 39, 49, 90, -117, -110, + -120, 75, -30, -126, 104, 58, 89, -69, 106, -123, 122, -73, 111, -14, 16, -87, 37, 100, + 92, 0, -114, -6, -6, -108, -115, -111, 52, 24, -14, -123, -98, 26, 84, 5, -79, -4, 32, + -13, -73, 49, 126, -121, -127, 45, 88, 102, 80, 80, 80, 111, 93, 104, 4, 70, -122, 20, + 14, 48, 64, 63, -103, 111, -2, 120, -102, 96, 73, 99, -14, 14, -108, -5, 111, 54, -77, + 20, 89, 9, 20, 55, -100, 18, -53, -83, -77, -46, 72, 118, 54, 64, 18, -100, -76, 95, 95, + -2, -109, -2, -91, 119, 16, -97, -97, 64, 84, 94, 8, -65, 58, -97, 18, 82, 66, -15, + -112, 82, 8, 64, -19, -15, -65, 90, 80, 15, 4, 0, 94, 103, -127, -16, -119, 34, 30, 64, + -87, 18, -111, 64, -16, 50, -124, 5, -111, 47, -125, 76, 121, -95, -118, -6, -85, -125, + 18, -16, -53, 24, -67, -67, 29, 95, -82, -4, -4, -32, 124, -101, -34, 18, -82, 9, 71, + 71, -46, 119, 85, 71, -111, 71, 71, -118, 33, 111, 111, -87, -116, 90, -4, 107, -111, + -79, 107, 33, 111, 107, -63, -127, -6, -122, -98, 127, 6, -9, -63, 95, 100, 89, -84, + 111, 73, -6, 79, -84, 80, -125, 38, -13, 14, -53, -127, 95, 40, 100, 126, 111, 60, 12, + -127, 6, 119, 75, 66, -127, 111, 77, 6, 30, 113, 74, -53, 92, 37, 83, 112, -15, -76, 81, + 121, -76, 115, 84, 86, -50, 110, 0, 0, 115, 86, 4, 112, -15, -80, 75, 6, 3, -10, 90, 14, + -127, 80, -117, 66, 6, 110, 108, -15, -39, 92, 58, 10, 90, 124, -117, 102, 0, 0, 0, 57, + -122, 42, 120, 88, 80, 3, 80, 66, -120, 106, -82, -73, 69, 104, -6, 19, 80, -123, -7, + 107, 87, 96, 126, 0, 0, -109, 0, 76, -114, 64, -59, 34, 115, 56, 0, 111, -44, -127, 108, + 99, 0, 84, 3, 68, 90, 124, 40, -87, 30, 30, 95, -61, 0, 0, 0, 0, 109, -40, -112, -6, 1, + 88, -44, 46, -127, 66, -1, 102, -121, 70, -94, 85, -40, 104, -97, -76, -118, 33, -120, + -74, -80, -110, -87, -61, -111, -123, -39, 0, 0, 0, 39, 26, 127, 64, 120, 92, -117, -95, + -111, -127, 15, 15, 124, 5, -127, 80, 80, 111, 46, 16, 67, 125, -85, 100, 3, 3, -125, + 14, 77, 101, 90, 23, -125, 110, 75, 121, 0, 21, 0, 81, -125, 114, 84, -20, 26, -79, -69, + 39, 39, 105, -112, 63, 57, 102, 96, 15, -4, -6, 81, 21, 0, -85, 5, -90, 126, -56, -127, + 66, 4, -125, 26, -67, 85, 3, 16, -127, -127, -120, -124, 3, -117, 109, 127, -110, 97, + 17, -115, 4, 88, 20, -123, 98, 52, 125, -106, 32, 32, 83, 107, -81, 98, -58, 85, 0, 88, + 86, 105, 120, -101, 121, 26, 126, 93, 107, 38, -87, 33, 0, 0, 2, 17, -127, 95, -128, 0, + -87, -82, -87, -57, -125, 88, 77, -76, 105, -87, 87, 111, 60, -127, 110, 74, -76, 84, 6, + -108, 6, -10, -39, -76, 110, 124, 90, 6, 10, 120, -15, 58, 107, -122, -109, 80, 80, 69, + 121, 120, -101, -127, -123, 87, 124, 88, 98, 99, -87, -85, -125, -87, 39, 66, 108, 30, + 124, -114, -127, 109, 1, -80, -6, -110, 85, -97, 33, 102, -40, -39, 66, -120, 37, 39, + -112, 86, 67, 14, 33, 64, 81, 80, 23, 77, 3, 90, 125, 5, -124, 15, 26, 5, -6, 57, 105, + 102, -20, -125, -90, 16, 97, 17, -67, -56, 109, 80, 85, 107, 32, -81, -106, 121, 93, + -87, 32, 105, -37, 104, 90, -87, -118, 21, 100, 90, 66, -127, 87, 0, 93, 39, 87, -55, + 10, 112, -123, 121, -4, 90, 86, 81, -125, 39, 111, 89, 105, -117, -115, -15, 124, -125, + 10, 100, 99, -124, 84, 87, 81, -24, 62, -126, -30, -80, -57, 90, 75, 81, -87, 15, -123, + 96, 112, -112, 4, 89, 38, 58, -117, 110, 102, -122, 111, 101, 15, 99, -123, 111, 0, 107, + -115, 84, 80, 103, 2, -123, 100, 118, -123, -127, -82, -120, 12, 64, 119, -73, 17, -52, + 96, 12, -123, 94, -121, 38, -73, 0, 0, 0, -75, -126, -127, 111, 124, 75, 21, 84, -116, + 111, 20, 98, 98, 14, 85, -114, -117, 71, -120, 64, 77, 77, -99, 121, 84, 37, -95, 0, 0, + -76, 19, 41, 90, 3, -128, -16, 0, -4, 11, 66, -76, 6, -125, -117, 71, 99, 112, -6, -87, + 103, -115, -105, 76, -97, 38, -6, -120, -40, 77, -120, -112, -94, 70, -6, 46, 99, -117, + 4, 0, 0, -127, 41, 0, 38, -58, 16, 90, 3, 64, 121, 64, 77, -122, -65, 90, 46, 71, 100, + 115, 112, -14, 114, -63, 121, 107, 75, -51, -117, 0, 25, 84, 96, 107, 112, 96, 82, 39, + 115, 41, 60, 86, 21, -79, -127, 102, -125, -114, 112, -112, 48, 104, 102, 100, -127, + -87, 65, -104, 64, 64, -40, 71, -69, -123, -79, -125, 36, -87, -117, -127, 5, 102, 104, + -24, 38, -123, -83, 15, -77, 14, 45, -113, 111, 84, -115, 106, 59, 49, -123, 104, 122, + 14, 107, 52, 125, 83, -123, -83, 100, -109, -118, 87, 87, 71, -68, -106, 111, 107, -76, + 72, 87, 97, 104, -15, 41, -73, -6, 104, -127, -127, 111, 126, 103, 101, -15, -34, 121, + -60, 107, -61, 63, 113, 111, -89, 20, -76, 115, -78, 45, 113, 107, 105, 4, -87, -75, + -37, -118, -127, 112, -55, 39, -24, 99, 25, 10, -125, 102, 70, -76, 99, 89, 101, -80, + 38, 4, 112, 97, 75, 49, -123, 80, 103, 94, 118, -121, 96, -75, 119, 84, 20, -87, -116, + 121, 77, 111, 87, 64, 84, 6, -58, 3, -97, 11, -16, -4, 46, 99, 112, 52, 121, 115, 77, + 102, 3, 48, -63, 84, 104, 102, 82, -79, -127, 104, -125, 115, 104, 107, -127, -79, -83, + -123, -118, 111, -76, 124, 126, 107, 121, -61, 105, 45, -76, -121, -80, -125, 87, 55, + -125, -125, 100, 55, -76, 110, 51, -127, 16, 51, -19, -120, -114, -120, -125, -60, -60, + 84, -79, 36, -114, -81, -40, -6, -76, -118, -114, -120, -87, 88, 100, -126, -60, -87, + 35, 127, -81, -120, -6, -80, 100, 51, -68, -68, 96, 34, 90, -59, -59, 90, -19, 4, 4, + -52, 90, 87, -94, 4, -59, 38, 87, 90, 4, -59, -69, -69, -53, 126, 0, -110, -43, 86, 125, + 125, -121, 106, 65, 70, 119, 85, -99, 119, 41, -87, -39, 38, 116, 116, 104, -4, -125, + 85, 72, -53, -53, -4, 57, 41, 110, 65, 104, 86, 100, 4, -63, 100, 1, 111, -87, 59, 72, + 24, 106, 3, 100, 59, 3, -125, 57, 24, 104, -63, 58, 100, 72, -76, -123, 86, 90, 90, -56, + -56, 112, 51, 4, 34, 76, -120, -123, -66, 5, 17, 75, 14, 112, 34, 75, 68, -60, -49, 68, + -112, 102, 102, 70, 86, 61, 112, -15, 33, 95, -6, 112, 60, 63, 41, 41, 86, 85, 81, 6, + 66, 75, 69, 4, 38, 39, 110, 39, 68, 84, -39, -120, 127, -117, 100, 71, 49, 85, 87, 100, + -89, 14, 102, 100, 112, 126, 84, 120, 85, 96, 124, 94, 82, 124, -32, -47, -6, 125, -127, + -112, -127, -127, -6, -127, 38, 36, 36, 115, 99, -107, 90, 10, 120, 39, -112, 38, -39, + -117, 66, -80, -80, 41, 5, 90, 106, -36, -118, -36, 47, -97, 111, 41, 104, -40, 55, 47, + 4, -39, 87, 111, 77, 83, 104, 38, -110, 65, 41, -121, 99, 38, 36, 115, 106, -117, -80, + 10, 66, -112, 106, 111, 47, 4, 83, -78, -20, 100, -20, 100, -78, -78, 100, -111, 57, + -80, 57, -78, 100, -111, 107, 3, 17, 107, 113, 45, 115, -115, 90, 113, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0}; + +} diff --git a/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinData.java b/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinData.java new file mode 100644 index 00000000..801505b8 --- /dev/null +++ b/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinData.java @@ -0,0 +1,63 @@ +package org.rx.util.pinyin; + +final class PinyinData { + + static final char MIN_VALUE = 19968; + + static final char MAX_VALUE = 40869; + + static final String PINYIN_12295 = "LING"; + + static final char CHAR_12295 = 12295; + + static final int PINYIN_CODE_1_OFFSET = 7000; + + static final int PINYIN_CODE_2_OFFSET = 7000 * 2; + + static final int[] BIT_MASKS = new int[]{1, 2, 4, 8, 16, 32, 64, 128}; + + static final int PADDING_MASK = 256; + + + private PinyinData() { + //no instance + } + + //CHECKSTYLE:OFF + static final String[] PINYIN_TABLE = new String[]{"", "A", "AI", "AN", "ANG", "AO", "BA", "BAI", + "BAN", "BANG", "BAO", "BEI", "BEN", "BENG", "BI", "BIAN", "BIAO", "BIE", "BIN", "BING", + "BO", "BU", "CA", "CAI", "CAN", "CANG", "CAO", "CE", "CEN", "CENG", "CHA", "CHAI", + "CHAN", "CHANG", "CHAO", "CHE", "CHEN", "CHENG", "CHI", "CHONG", "CHOU", "CHU", "CHUAI", + "CHUAN", "CHUANG", "CHUI", "CHUN", "CHUO", "CI", "CONG", "COU", "CU", "CUAN", "CUI", + "CUN", "CUO", "DA", "DAI", "DAN", "DANG", "DAO", "DE", "DENG", "DI", "DIA", "DIAN", + "DIAO", "DIE", "DING", "DIU", "DONG", "DOU", "DU", "DUAN", "DUI", "DUN", "DUO", "E", + "EI", "EN", "ER", "E^", "FA", "FAN", "FANG", "FEI", "FEN", "FENG", "FO", "FOU", "FU", + "GA", "GAI", "GAN", "GANG", "GAO", "GE", "GEI", "GEN", "GENG", "GONG", "GOU", "GU", + "GUA", "GUAI", "GUAN", "GUANG", "GUI", "GUN", "GUO", "HA", "HAI", "HAN", "HANG", "HAO", + "HE", "HEI", "HEN", "HENG", "HONG", "HOU", "HU", "HUA", "HUAI", "HUAN", "HUANG", "HUI", + "HUN", "HUO", "JI", "JIA", "JIAN", "JIANG", "JIAO", "JIE", "JIN", "JING", "JIONG", + "JIU", "JU", "JUAN", "JUE", "JUN", "KA", "KAI", "KAN", "KANG", "KAO", "KE", "KEN", + "KENG", "KONG", "KOU", "KU", "KUA", "KUAI", "KUAN", "KUANG", "KUI", "KUN", "KUO", "LA", + "LAI", "LAN", "LANG", "LAO", "LE", "LEI", "LENG", "LI", "LIA", "LIAN", "LIANG", "LIAO", + "LIE", "LIN", "LING", "LIU", "LONG", "LOU", "LU", "LUAN", "LUN", "LUO", "LV", "LVE", + "M", "MA", "MAI", "MAN", "MANG", "MAO", "ME", "MEI", "MEN", "MENG", "MI", "MIAN", + "MIAO", "MIE", "MIN", "MING", "MIU", "MO", "MOU", "MU", "NA", "NAI", "NAN", "NANG", + "NAO", "NE", "NEI", "NEN", "NENG", "NG", "NI", "NIAN", "NIANG", "NIAO", "NIE", "NIN", + "NING", "NIU", "NONG", "NOU", "NU", "NUAN", "NUO", "NV", "NVE", "O", "OU", "PA", "PAI", + "PAN", "PANG", "PAO", "PEI", "PEN", "PENG", "PI", "PIAN", "PIAO", "PIE", "PIN", "PING", + "PO", "POU", "PU", "QI", "QIA", "QIAN", "QIANG", "QIAO", "QIE", "QIN", "QING", "QIONG", + "QIU", "QU", "QUAN", "QUE", "QUN", "RAN", "RANG", "RAO", "RE", "REN", "RENG", "RI", + "RONG", "ROU", "RU", "RUAN", "RUI", "RUN", "RUO", "SA", "SAI", "SAN", "SANG", "SAO", + "SE", "SEN", "SENG", "SHA", "SHAI", "SHAN", "SHANG", "SHAO", "SHE", "SHEI", "SHEN", + "SHENG", "SHI", "SHOU", "SHU", "SHUA", "SHUAI", "SHUAN", "SHUANG", "SHUI", "SHUN", + "SHUO", "SI", "SONG", "SOU", "SU", "SUAN", "SUI", "SUN", "SUO", "TA", "TAI", "TAN", + "TANG", "TAO", "TE", "TENG", "TI", "TIAN", "TIAO", "TIE", "TING", "TONG", "TOU", "TU", + "TUAN", "TUI", "TUN", "TUO", "WA", "WAI", "WAN", "WANG", "WEI", "WEN", "WENG", "WO", + "WU", "XI", "XIA", "XIAN", "XIANG", "XIAO", "XIE", "XIN", "XING", "XIONG", "XIU", "XU", + "XUAN", "XUE", "XUN", "YA", "YAN", "YANG", "YAO", "YE", "YI", "YIAO", "YIN", "YING", + "YO", "YONG", "YOU", "YU", "YUAN", "YUE", "YUN", "ZA", "ZAI", "ZAN", "ZANG", "ZAO", + "ZE", "ZEI", "ZEN", "ZENG", "ZHA", "ZHAI", "ZHAN", "ZHANG", "ZHAO", "ZHE", "ZHEI", + "ZHEN", "ZHENG", "ZHI", "ZHONG", "ZHOU", "ZHU", "ZHUA", "ZHUAI", "ZHUAN", "ZHUANG", + "ZHUI", "ZHUN", "ZHUO", "ZI", "ZONG", "ZOU", "ZU", "ZUAN", "ZUI", "ZUN", "ZUO"}; + //CHECKSTYLE:ON +} diff --git a/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinDict.java b/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinDict.java new file mode 100644 index 00000000..4e8b8e1c --- /dev/null +++ b/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinDict.java @@ -0,0 +1,27 @@ +package org.rx.util.pinyin; + +import java.util.Set; + +/** + * 字典接口,字典应保证对{@link PinyinDict#words()}中的所有词,{@link PinyinDict#toPinyin(String)}均返回非null的结果 + * + * Created by guyacong on 2016/12/23. + */ + +public interface PinyinDict { + + /** + * 字典所包含的所有词 + * + * @return 所包含的所有词 + */ + Set words(); + + /** + * 将词转换为拼音 + * + * @param word 词 + * @return 应保证对{@link PinyinDict#words()}中的所有词,{@link PinyinDict#toPinyin(String)}均返回非null的结果 + */ + String[] toPinyin(String word); +} diff --git a/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinMapDict.java b/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinMapDict.java new file mode 100644 index 00000000..bbb59940 --- /dev/null +++ b/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinMapDict.java @@ -0,0 +1,31 @@ +package org.rx.util.pinyin; + +import java.util.Map; +import java.util.Set; + +/** + * 基于{@link Map}的字典实现,利于添加自定义字典 + * + * Created by guyacong on 2016/12/23. + */ + +public abstract class PinyinMapDict implements PinyinDict { + + /** + * Key为字典的词,Value为该词所对应的拼音 + * + * @return 包含词和对应拼音的 {@link Map} + */ + public abstract Map mapping(); + + + @Override + public Set words() { + return mapping() != null ? mapping().keySet() : null; + } + + @Override + public String[] toPinyin(String word) { + return mapping() != null ? mapping().get(word) : null; + } +} diff --git a/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinRules.java b/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinRules.java new file mode 100644 index 00000000..44bc8e18 --- /dev/null +++ b/rxlib-x/src/main/java/org/rx/util/pinyin/PinyinRules.java @@ -0,0 +1,31 @@ +package org.rx.util.pinyin; + +import java.util.HashMap; +import java.util.Map; + +public final class PinyinRules { + private final Map mOverrides = new HashMap(); + + public PinyinRules add(char c, String pinyin) { + mOverrides.put(String.valueOf(c), new String[]{pinyin}); + return this; + } + + public PinyinRules add(String str, String pinyin) { + mOverrides.put(str, new String[]{pinyin}); + return this; + } + + String toPinyin(char c) { + return mOverrides.get(String.valueOf(c))[0]; + } + + PinyinMapDict toPinyinMapDict() { + return new PinyinMapDict() { + @Override + public Map mapping() { + return mOverrides; + } + }; + } +} diff --git a/rxlib-x/src/main/java/org/rx/util/pinyin/SegmentationSelector.java b/rxlib-x/src/main/java/org/rx/util/pinyin/SegmentationSelector.java new file mode 100644 index 00000000..7af0a42e --- /dev/null +++ b/rxlib-x/src/main/java/org/rx/util/pinyin/SegmentationSelector.java @@ -0,0 +1,32 @@ +package org.rx.util.pinyin; + +import org.ahocorasick.trie.Emit; + +import java.util.Collection; +import java.util.List; + +/** + * 分词选择算法应实现的接口 + * + * TODO: 开放此接口,提供更多的预制Selector,也可供使用者实现自定义Selector + * + * Created by guyacong on 2016/12/28. + */ + +interface SegmentationSelector { + + /** + * 从匹配到的所有词中,挑选出合适的词列表 + * + * 例如,词典为:"中国","中国人","人民" + * "中国人民来了" 的emits为:[0,1]中国、[0,2]中国人、[2,3]人民 + * + * 按照正向最大匹配算法,会挑选出:[0,2]中国人 + * + * Waring: 返回的Emit列表中,不能存在交集,如上例中,不能同时返回 [0,2]中国人 和 [2,3]人民 + * + * @param emits 匹配到的所有词 + * @return 返回的Emit列表, 不能存在交集 + */ + List select(Collection emits); +} diff --git a/rxlib-x/src/main/java/org/rx/util/pinyin/Utils.java b/rxlib-x/src/main/java/org/rx/util/pinyin/Utils.java new file mode 100644 index 00000000..2c481c60 --- /dev/null +++ b/rxlib-x/src/main/java/org/rx/util/pinyin/Utils.java @@ -0,0 +1,40 @@ +package org.rx.util.pinyin; + +import org.ahocorasick.trie.Trie; + +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +/** + * Created by guyacong on 2016/12/28. + */ + +final class Utils { + + private Utils() { + //no instance + } + + static Trie dictsToTrie(List pinyinDicts) { + Set all = new TreeSet(); + + Trie.TrieBuilder builder = Trie.builder(); + + if (pinyinDicts != null) { + for (PinyinDict dict : pinyinDicts) { + if (dict != null && dict.words() != null) { + all.addAll(dict.words()); + } + } + if (all.size() > 0) { + for (String key : all) { + builder.addKeyword(key); + } + return builder.build(); + } + } + + return null; + } +} diff --git a/rxlib-x/src/test/java/util/TestUtil.java b/rxlib-x/src/test/java/util/TestUtil.java new file mode 100644 index 00000000..caf11c30 --- /dev/null +++ b/rxlib-x/src/test/java/util/TestUtil.java @@ -0,0 +1,60 @@ +package util; + +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.rx.util.Helper; +import org.rx.util.pinyin.Pinyin; + +@Slf4j +public class TestUtil { + @Test + public void pinyin() { + String l = "小王,abc"; + System.out.println(l.length()); + l = "小范"; + String pyn = Pinyin.toPinyin(l, "_"); + System.out.println(pyn); + + String subject = "什么小范小范,吃饭啦!,好的"; + String pySubject = Pinyin.toPinyin(subject, "_"); + System.out.println(pySubject); + + String n = "小范", n1 = "XIAO_FAN"; + System.out.println(getSubject("今天天气如何", n, n1)); + System.out.println(getSubject("小范,今天天气如何", n, n1)); + System.out.println(getSubject("小饭,今天天气如何", n, n1)); + System.out.println(getSubject("总之呐,小范,今天天气如何", n, n1)); + System.out.println(getSubject("总之呐,小饭,今天天气如何", n, n1)); + } + + String getSubject(String line, String name, String pinyinName) { + if (line.length() <= name.length()) { + return null; + } +// line = new StringBuilder(line).replace(",", "") +// .replace(",", "") +// .toString(); + String s = "_"; + String pinyinLine = Pinyin.toPinyin(line, s); + if (pinyinLine.startsWith(pinyinName)) { + return line.substring(name.length()).trim(); + } + int i = pinyinLine.indexOf(s + pinyinName); + if (i == -1) { + return null; + } + int c = 1; + for (int j = 0; j < i; j++) { + if (pinyinLine.charAt(j) == s.charAt(0)) { + c++; + } + } + log.info("{} -> @{} - {}", pinyinLine, i, c); + return line.substring(c + name.length()).trim(); + } + + @Test + public void email() { + Helper.sendEmail("hw", "abc", "rockywong.chn@qq.com"); + } +}