1df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov/* 2df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * Copyright (C) 2009 The Android Open Source Project 3df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * 4df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License"); 5df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * you may not use this file except in compliance with the License. 6df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * You may obtain a copy of the License at 7df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * 8df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * http://www.apache.org/licenses/LICENSE-2.0 9df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * 10df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * Unless required by applicable law or agreed to in writing, software 11df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS, 12df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * See the License for the specific language governing permissions and 14df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * limitations under the License. 15df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov */ 16df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov 17df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikovpackage com.android.internal.util; 18df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov 19df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikovimport android.text.TextUtils; 20df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikovimport android.util.Log; 21df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov 22df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikovimport java.text.Collator; 23df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikovimport java.util.ArrayList; 24df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikovimport java.util.Locale; 25df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov 26df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov/** 27df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * An object to convert Chinese character to its corresponding pinyin string. 28df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * For characters with multiple possible pinyin string, only one is selected 29df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * according to collator. Polyphone is not supported in this implementation. 30df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * This class is implemented to achieve the best runtime performance and minimum 31df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * runtime resources with tolerable sacrifice of accuracy. This implementation 32df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * highly depends on zh_CN ICU collation data and must be always synchronized with 33df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * ICU. 34df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov */ 35df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikovpublic class HanziToPinyin { 36df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov private static final String TAG = "HanziToPinyin"; 37df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov 38df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov private static final char[] UNIHANS = { 39df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u5416', '\u54ce', '\u5b89', '\u80ae', '\u51f9', '\u516b', '\u63b0', '\u6273', 40df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u90a6', '\u52f9', '\u9642', '\u5954', '\u4f3b', '\u7680', '\u782d', '\u706c', 41df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u618b', '\u6c43', '\u51ab', '\u7676', '\u5cec', '\u5693', '\u5072', '\u53c2', 42df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u4ed3', '\u64a1', '\u518a', '\u5d7e', '\u564c', '\u6260', '\u62c6', '\u8fbf', 43df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u4f25', '\u6284', '\u8f66', '\u62bb', '\u9637', '\u5403', '\u5145', '\u62bd', 44df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u51fa', '\u640b', '\u5ddb', '\u5205', '\u5439', '\u65fe', '\u8e14', '\u5472', 45df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u4ece', '\u51d1', '\u7c97', '\u6c46', '\u5d14', '\u90a8', '\u6413', '\u5491', 46df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u5446', '\u4e39', '\u5f53', '\u5200', '\u6074', '\u6265', '\u706f', '\u4efe', 47df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u55f2', '\u6541', '\u5201', '\u7239', '\u4e01', '\u4e1f', '\u4e1c', '\u543a', 48df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u5262', '\u8011', '\u5796', '\u5428', '\u591a', '\u59b8', '\u5940', '\u97a5', 49df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u800c', '\u53d1', '\u5e06', '\u531a', '\u98de', '\u5206', '\u4e30', '\u8985', 50df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u4ecf', '\u57ba', '\u7d11', '\u592b', '\u7324', '\u65ee', '\u4f85', '\u5e72', 51df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u5188', '\u768b', '\u6208', '\u7ed9', '\u6839', '\u63ef', '\u55bc', '\u55f0', 52df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u5de5', '\u52fe', '\u4f30', '\u9e39', '\u4e56', '\u5173', '\u5149', '\u5f52', 53df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u4e28', '\u8b34', '\u5459', '\u598e', '\u548d', '\u4f44', '\u592f', '\u8320', 54df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u8bc3', '\u9ed2', '\u62eb', '\u4ea8', '\u53ff', '\u9f41', '\u4e4e', '\u82b1', 55df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u6000', '\u6b22', '\u5ddf', '\u7070', '\u660f', '\u5419', '\u4e0c', '\u52a0', 56df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u620b', '\u6c5f', '\u827d', '\u9636', '\u5dfe', '\u5755', '\u5182', '\u4e29', 57df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u51e5', '\u59e2', '\u5658', '\u519b', '\u5494', '\u5f00', '\u938e', '\u5ffc', 58df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u5c3b', '\u533c', '\u808e', '\u52a5', '\u7a7a', '\u62a0', '\u625d', '\u5938', 59df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u84af', '\u5bbd', '\u5321', '\u4e8f', '\u5764', '\u6269', '\u62c9', '\u4f86', 60df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u5170', '\u5577', '\u635e', '\u4ec2', '\u96f7', '\u8137', '\u68f1', '\u695e', 61df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u550e', '\u4fe9', '\u5afe', '\u826f', '\u8e7d', '\u57d3', '\u53b8', '\u62ce', 62df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u6e9c', '\u9f99', '\u5a04', '\u565c', '\u5b6a', '\u62a1', '\u9831', '\u5988', 63df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u57cb', '\u989f', '\u7264', '\u732b', '\u5445', '\u95e8', '\u6c13', '\u54aa', 64df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u5b80', '\u55b5', '\u4e5c', '\u6c11', '\u540d', '\u8c2c', '\u6478', '\u725f', 65df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u6bcd', '\u62cf', '\u8149', '\u56e1', '\u56d4', '\u5b6c', '\u8bb7', '\u5a1e', 66df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u5ae9', '\u80fd', '\u92b0', '\u62c8', '\u5a18', '\u9e1f', '\u634f', '\u56dc', 67df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u5b81', '\u599e', '\u519c', '\u7fba', '\u5974', '\u597b', '\u9ec1', '\u90cd', 68df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u5662', '\u8bb4', '\u5991', '\u62cd', '\u7705', '\u6c78', '\u629b', '\u5478', 69df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u55b7', '\u5309', '\u4e76', '\u7247', '\u527d', '\u6c15', '\u59d8', '\u4e52', 70df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u948b', '\u5256', '\u4ec6', '\u4e03', '\u6390', '\u5343', '\u545b', '\u6084', 71df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u5207', '\u4eb2', '\u9751', '\u5b86', '\u74d7', '\u533a', '\u5cd1', '\u7094', 72df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u590b', '\u5465', '\u7a63', '\u835b', '\u60f9', '\u4eba', '\u6254', '\u65e5', 73df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u620e', '\u53b9', '\u909a', '\u5827', '\u6875', '\u95f0', '\u633c', '\u4ee8', 74df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u6be2', '\u4e09', '\u6852', '\u63bb', '\u8272', '\u68ee', '\u50e7', '\u6740', 75df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u7b5b', '\u5c71', '\u4f24', '\u5f30', '\u5962', '\u7533', '\u5347', '\u5c38', 76df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u53ce', '\u4e66', '\u5237', '\u8870', '\u95e9', '\u53cc', '\u8c01', '\u542e', 77df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u8bf4', '\u53b6', '\u5fea', '\u51c1', '\u82cf', '\u72fb', '\u590a', '\u5b59', 78df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u5506', '\u4ed6', '\u5b61', '\u574d', '\u6c64', '\u5932', '\u5fd1', '\u81af', 79df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u5254', '\u5929', '\u65eb', '\u6017', '\u5385', '\u70b5', '\u5077', '\u51f8', 80df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u6e4d', '\u63a8', '\u541e', '\u8bac', '\u52b8', '\u6b6a', '\u5f2f', '\u5c23', 81df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u5371', '\u6637', '\u7fc1', '\u631d', '\u4e4c', '\u5915', '\u5477', '\u4ed9', 82df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u4e61', '\u7071', '\u4e9b', '\u5fc3', '\u5174', '\u51f6', '\u4f11', '\u620c', 83df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u5405', '\u75b6', '\u7025', '\u4e2b', '\u54bd', '\u592e', '\u5e7a', '\u503b', 84df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u4e00', '\u4e5a', '\u5e94', '\u5537', '\u4f63', '\u4f18', '\u7ea1', '\u56e6', 85df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u66f0', '\u8480', '\u5e00', '\u707d', '\u5142', '\u7242', '\u50ae', '\u556b', 86df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u9c61', '\u600e', '\u66fd', '\u5412', '\u635a', '\u6cbe', '\u5f20', '\u4f4b', 87df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u8707', '\u8d1e', '\u9eee', '\u4e4b', '\u4e2d', '\u5dde', '\u6731', '\u6293', 88df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u62fd', '\u4e13', '\u5986', '\u96b9', '\u5b92', '\u5353', '\u4ed4', '\u5b97', 89df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov '\u90b9', '\u79df', '\u5297', '\u55fa', '\u5c0a', '\u6628', 90df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov }; 91df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov private final static byte[][] PINYINS = { 92df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {65, 00, 00, 00, 00, 00, }, {65, 73, 00, 00, 00, 00, }, 93df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {65, 78, 00, 00, 00, 00, }, {65, 78, 71, 00, 00, 00, }, 94df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {65, 79, 00, 00, 00, 00, }, {66, 65, 00, 00, 00, 00, }, 95df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {66, 65, 73, 00, 00, 00, }, {66, 65, 78, 00, 00, 00, }, 96df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {66, 65, 78, 71, 00, 00, }, {66, 65, 79, 00, 00, 00, }, 97df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {66, 69, 73, 00, 00, 00, }, {66, 69, 78, 00, 00, 00, }, 98df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {66, 69, 78, 71, 00, 00, }, {66, 73, 00, 00, 00, 00, }, 99df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {66, 73, 65, 78, 00, 00, }, {66, 73, 65, 79, 00, 00, }, 100df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {66, 73, 69, 00, 00, 00, }, {66, 73, 78, 00, 00, 00, }, 101df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {66, 73, 78, 71, 00, 00, }, {66, 79, 00, 00, 00, 00, }, 102df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {66, 85, 00, 00, 00, 00, }, {67, 65, 00, 00, 00, 00, }, 103df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 65, 73, 00, 00, 00, }, {67, 65, 78, 00, 00, 00, }, 104df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 65, 78, 71, 00, 00, }, {67, 65, 79, 00, 00, 00, }, 105df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 69, 00, 00, 00, 00, }, {67, 69, 78, 00, 00, 00, }, 106df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 69, 78, 71, 00, 00, }, {67, 72, 65, 00, 00, 00, }, 107df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 72, 65, 73, 00, 00, }, {67, 72, 65, 78, 00, 00, }, 108df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 72, 65, 78, 71, 00, }, {67, 72, 65, 79, 00, 00, }, 109df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 72, 69, 00, 00, 00, }, {67, 72, 69, 78, 00, 00, }, 110df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 72, 69, 78, 71, 00, }, {67, 72, 73, 00, 00, 00, }, 111df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 72, 79, 78, 71, 00, }, {67, 72, 79, 85, 00, 00, }, 112df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 72, 85, 00, 00, 00, }, {67, 72, 85, 65, 73, 00, }, 113df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 72, 85, 65, 78, 00, }, {67, 72, 85, 65, 78, 71, }, 114df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 72, 85, 73, 00, 00, }, {67, 72, 85, 78, 00, 00, }, 115df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 72, 85, 79, 00, 00, }, {67, 73, 00, 00, 00, 00, }, 116df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 79, 78, 71, 00, 00, }, {67, 79, 85, 00, 00, 00, }, 117df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 85, 00, 00, 00, 00, }, {67, 85, 65, 78, 00, 00, }, 118df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 85, 73, 00, 00, 00, }, {67, 85, 78, 00, 00, 00, }, 119df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {67, 85, 79, 00, 00, 00, }, {68, 65, 00, 00, 00, 00, }, 120df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {68, 65, 73, 00, 00, 00, }, {68, 65, 78, 00, 00, 00, }, 121df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {68, 65, 78, 71, 00, 00, }, {68, 65, 79, 00, 00, 00, }, 122df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {68, 69, 00, 00, 00, 00, }, {68, 69, 78, 00, 00, 00, }, 123df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {68, 69, 78, 71, 00, 00, }, {68, 73, 00, 00, 00, 00, }, 124df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {68, 73, 65, 00, 00, 00, }, {68, 73, 65, 78, 00, 00, }, 125df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {68, 73, 65, 79, 00, 00, }, {68, 73, 69, 00, 00, 00, }, 126df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {68, 73, 78, 71, 00, 00, }, {68, 73, 85, 00, 00, 00, }, 127df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {68, 79, 78, 71, 00, 00, }, {68, 79, 85, 00, 00, 00, }, 128df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {68, 85, 00, 00, 00, 00, }, {68, 85, 65, 78, 00, 00, }, 129df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {68, 85, 73, 00, 00, 00, }, {68, 85, 78, 00, 00, 00, }, 130df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {68, 85, 79, 00, 00, 00, }, {69, 00, 00, 00, 00, 00, }, 131df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {69, 78, 00, 00, 00, 00, }, {69, 78, 71, 00, 00, 00, }, 132df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {69, 82, 00, 00, 00, 00, }, {70, 65, 00, 00, 00, 00, }, 133df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {70, 65, 78, 00, 00, 00, }, {70, 65, 78, 71, 00, 00, }, 134df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {70, 69, 73, 00, 00, 00, }, {70, 69, 78, 00, 00, 00, }, 135df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {70, 69, 78, 71, 00, 00, }, {70, 73, 65, 79, 00, 00, }, 136df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {70, 79, 00, 00, 00, 00, }, {70, 85, 00, 00, 00, 00, }, 137df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {70, 79, 85, 00, 00, 00, }, {70, 85, 00, 00, 00, 00, }, 138df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {71, 85, 73, 00, 00, 00, }, {71, 65, 00, 00, 00, 00, }, 139df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {71, 65, 73, 00, 00, 00, }, {71, 65, 78, 00, 00, 00, }, 140df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {71, 65, 78, 71, 00, 00, }, {71, 65, 79, 00, 00, 00, }, 141df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {71, 69, 00, 00, 00, 00, }, {71, 69, 73, 00, 00, 00, }, 142df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {71, 69, 78, 00, 00, 00, }, {71, 69, 78, 71, 00, 00, }, 143df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {74, 73, 69, 00, 00, 00, }, {71, 69, 00, 00, 00, 00, }, 144df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {71, 79, 78, 71, 00, 00, }, {71, 79, 85, 00, 00, 00, }, 145df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {71, 85, 00, 00, 00, 00, }, {71, 85, 65, 00, 00, 00, }, 146df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {71, 85, 65, 73, 00, 00, }, {71, 85, 65, 78, 00, 00, }, 147df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {71, 85, 65, 78, 71, 00, }, {71, 85, 73, 00, 00, 00, }, 148df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {71, 85, 78, 00, 00, 00, }, {71, 85, 65, 78, 00, 00, }, 149df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {71, 85, 79, 00, 00, 00, }, {72, 65, 00, 00, 00, 00, }, 150df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {72, 65, 73, 00, 00, 00, }, {72, 65, 78, 00, 00, 00, }, 151df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {72, 65, 78, 71, 00, 00, }, {72, 65, 79, 00, 00, 00, }, 152df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {72, 69, 00, 00, 00, 00, }, {72, 69, 73, 00, 00, 00, }, 153df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {72, 69, 78, 00, 00, 00, }, {72, 69, 78, 71, 00, 00, }, 154df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {72, 79, 78, 71, 00, 00, }, {72, 79, 85, 00, 00, 00, }, 155df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {72, 85, 00, 00, 00, 00, }, {72, 85, 65, 00, 00, 00, }, 156df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {72, 85, 65, 73, 00, 00, }, {72, 85, 65, 78, 00, 00, }, 157df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {72, 85, 65, 78, 71, 00, }, {72, 85, 73, 00, 00, 00, }, 158df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {72, 85, 78, 00, 00, 00, }, {72, 85, 79, 00, 00, 00, }, 159df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {74, 73, 00, 00, 00, 00, }, {74, 73, 65, 00, 00, 00, }, 160df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {74, 73, 65, 78, 00, 00, }, {74, 73, 65, 78, 71, 00, }, 161df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {74, 73, 65, 79, 00, 00, }, {74, 73, 69, 00, 00, 00, }, 162df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {74, 73, 78, 00, 00, 00, }, {74, 73, 78, 71, 00, 00, }, 163df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {74, 73, 79, 78, 71, 00, }, {74, 73, 85, 00, 00, 00, }, 164df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {74, 85, 00, 00, 00, 00, }, {74, 85, 65, 78, 00, 00, }, 165df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {74, 85, 69, 00, 00, 00, }, {74, 85, 78, 00, 00, 00, }, 166df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {75, 65, 00, 00, 00, 00, }, {75, 65, 73, 00, 00, 00, }, 167df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {75, 65, 78, 00, 00, 00, }, {75, 65, 78, 71, 00, 00, }, 168df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {75, 65, 79, 00, 00, 00, }, {75, 69, 00, 00, 00, 00, }, 169df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {75, 69, 78, 00, 00, 00, }, {75, 69, 78, 71, 00, 00, }, 170df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {75, 79, 78, 71, 00, 00, }, {75, 79, 85, 00, 00, 00, }, 171df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {75, 85, 00, 00, 00, 00, }, {75, 85, 65, 00, 00, 00, }, 172df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {75, 85, 65, 73, 00, 00, }, {75, 85, 65, 78, 00, 00, }, 173df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {75, 85, 65, 78, 71, 00, }, {75, 85, 73, 00, 00, 00, }, 174df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {75, 85, 78, 00, 00, 00, }, {75, 85, 79, 00, 00, 00, }, 175df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {76, 65, 00, 00, 00, 00, }, {76, 65, 73, 00, 00, 00, }, 176df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {76, 65, 78, 00, 00, 00, }, {76, 65, 78, 71, 00, 00, }, 177df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {76, 65, 79, 00, 00, 00, }, {76, 69, 00, 00, 00, 00, }, 178df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {76, 69, 73, 00, 00, 00, }, {76, 73, 00, 00, 00, 00, }, 179df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {76, 73, 78, 71, 00, 00, }, {76, 69, 78, 71, 00, 00, }, 180df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {76, 73, 00, 00, 00, 00, }, {76, 73, 65, 00, 00, 00, }, 181df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {76, 73, 65, 78, 00, 00, }, {76, 73, 65, 78, 71, 00, }, 182df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {76, 73, 65, 79, 00, 00, }, {76, 73, 69, 00, 00, 00, }, 183df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {76, 73, 78, 00, 00, 00, }, {76, 73, 78, 71, 00, 00, }, 184df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {76, 73, 85, 00, 00, 00, }, {76, 79, 78, 71, 00, 00, }, 185df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {76, 79, 85, 00, 00, 00, }, {76, 85, 00, 00, 00, 00, }, 186df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {76, 85, 65, 78, 00, 00, }, {76, 85, 78, 00, 00, 00, }, 187df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {76, 85, 79, 00, 00, 00, }, {77, 65, 00, 00, 00, 00, }, 188df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {77, 65, 73, 00, 00, 00, }, {77, 65, 78, 00, 00, 00, }, 189df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {77, 65, 78, 71, 00, 00, }, {77, 65, 79, 00, 00, 00, }, 190df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {77, 69, 73, 00, 00, 00, }, {77, 69, 78, 00, 00, 00, }, 191df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {77, 69, 78, 71, 00, 00, }, {77, 73, 00, 00, 00, 00, }, 192df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {77, 73, 65, 78, 00, 00, }, {77, 73, 65, 79, 00, 00, }, 193df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {77, 73, 69, 00, 00, 00, }, {77, 73, 78, 00, 00, 00, }, 194df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {77, 73, 78, 71, 00, 00, }, {77, 73, 85, 00, 00, 00, }, 195df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {77, 79, 00, 00, 00, 00, }, {77, 79, 85, 00, 00, 00, }, 196df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {77, 85, 00, 00, 00, 00, }, {78, 65, 00, 00, 00, 00, }, 197df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {78, 65, 73, 00, 00, 00, }, {78, 65, 78, 00, 00, 00, }, 198df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {78, 65, 78, 71, 00, 00, }, {78, 65, 79, 00, 00, 00, }, 199df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {78, 69, 00, 00, 00, 00, }, {78, 69, 73, 00, 00, 00, }, 200df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {78, 69, 78, 00, 00, 00, }, {78, 69, 78, 71, 00, 00, }, 201df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {78, 73, 00, 00, 00, 00, }, {78, 73, 65, 78, 00, 00, }, 202df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {78, 73, 65, 78, 71, 00, }, {78, 73, 65, 79, 00, 00, }, 203df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {78, 73, 69, 00, 00, 00, }, {78, 73, 78, 00, 00, 00, }, 204df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {78, 73, 78, 71, 00, 00, }, {78, 73, 85, 00, 00, 00, }, 205df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {78, 79, 78, 71, 00, 00, }, {78, 79, 85, 00, 00, 00, }, 206df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {78, 85, 00, 00, 00, 00, }, {78, 85, 65, 78, 00, 00, }, 207df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {78, 85, 78, 00, 00, 00, }, {78, 85, 79, 00, 00, 00, }, 208df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {79, 00, 00, 00, 00, 00, }, {79, 85, 00, 00, 00, 00, }, 209df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {80, 65, 00, 00, 00, 00, }, {80, 65, 73, 00, 00, 00, }, 210df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {80, 65, 78, 00, 00, 00, }, {80, 65, 78, 71, 00, 00, }, 211df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {80, 65, 79, 00, 00, 00, }, {80, 69, 73, 00, 00, 00, }, 212df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {80, 69, 78, 00, 00, 00, }, {80, 69, 78, 71, 00, 00, }, 213df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {80, 73, 00, 00, 00, 00, }, {80, 73, 65, 78, 00, 00, }, 214df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {80, 73, 65, 79, 00, 00, }, {80, 73, 69, 00, 00, 00, }, 215df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {80, 73, 78, 00, 00, 00, }, {80, 73, 78, 71, 00, 00, }, 216df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {80, 79, 00, 00, 00, 00, }, {80, 79, 85, 00, 00, 00, }, 217df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {80, 85, 00, 00, 00, 00, }, {81, 73, 00, 00, 00, 00, }, 218df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {81, 73, 65, 00, 00, 00, }, {81, 73, 65, 78, 00, 00, }, 219df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {81, 73, 65, 78, 71, 00, }, {81, 73, 65, 79, 00, 00, }, 220df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {81, 73, 69, 00, 00, 00, }, {81, 73, 78, 00, 00, 00, }, 221df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {81, 73, 78, 71, 00, 00, }, {81, 73, 79, 78, 71, 00, }, 222df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {81, 73, 85, 00, 00, 00, }, {81, 85, 00, 00, 00, 00, }, 223df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {81, 85, 65, 78, 00, 00, }, {81, 85, 69, 00, 00, 00, }, 224df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {81, 85, 78, 00, 00, 00, }, {82, 65, 78, 00, 00, 00, }, 225df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {82, 65, 78, 71, 00, 00, }, {82, 65, 79, 00, 00, 00, }, 226df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {82, 69, 00, 00, 00, 00, }, {82, 69, 78, 00, 00, 00, }, 227df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {82, 69, 78, 71, 00, 00, }, {82, 73, 00, 00, 00, 00, }, 228df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {82, 79, 78, 71, 00, 00, }, {82, 79, 85, 00, 00, 00, }, 229df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {82, 85, 00, 00, 00, 00, }, {82, 85, 65, 78, 00, 00, }, 230df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {82, 85, 73, 00, 00, 00, }, {82, 85, 78, 00, 00, 00, }, 231df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {82, 85, 79, 00, 00, 00, }, {83, 65, 00, 00, 00, 00, }, 232df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 65, 73, 00, 00, 00, }, {83, 65, 78, 00, 00, 00, }, 233df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 65, 78, 71, 00, 00, }, {83, 65, 79, 00, 00, 00, }, 234df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 69, 00, 00, 00, 00, }, {83, 69, 78, 00, 00, 00, }, 235df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 69, 78, 71, 00, 00, }, {83, 72, 65, 00, 00, 00, }, 236df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 72, 65, 73, 00, 00, }, {83, 72, 65, 78, 00, 00, }, 237df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 72, 65, 78, 71, 00, }, {83, 72, 65, 79, 00, 00, }, 238df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 72, 69, 00, 00, 00, }, {83, 72, 69, 78, 00, 00, }, 239df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 72, 69, 78, 71, 00, }, {83, 72, 73, 00, 00, 00, }, 240df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 72, 79, 85, 00, 00, }, {83, 72, 85, 00, 00, 00, }, 241df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 72, 85, 65, 00, 00, }, {83, 72, 85, 65, 73, 00, }, 242df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 72, 85, 65, 78, 00, }, {83, 72, 85, 65, 78, 71, }, 243df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 72, 85, 73, 00, 00, }, {83, 72, 85, 78, 00, 00, }, 244df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 72, 85, 79, 00, 00, }, {83, 73, 00, 00, 00, 00, }, 245df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 79, 78, 71, 00, 00, }, {83, 79, 85, 00, 00, 00, }, 246df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 85, 00, 00, 00, 00, }, {83, 85, 65, 78, 00, 00, }, 247df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 85, 73, 00, 00, 00, }, {83, 85, 78, 00, 00, 00, }, 248df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {83, 85, 79, 00, 00, 00, }, {84, 65, 00, 00, 00, 00, }, 249df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {84, 65, 73, 00, 00, 00, }, {84, 65, 78, 00, 00, 00, }, 250df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {84, 65, 78, 71, 00, 00, }, {84, 65, 79, 00, 00, 00, }, 251df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {84, 69, 00, 00, 00, 00, }, {84, 69, 78, 71, 00, 00, }, 252df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {84, 73, 00, 00, 00, 00, }, {84, 73, 65, 78, 00, 00, }, 253df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {84, 73, 65, 79, 00, 00, }, {84, 73, 69, 00, 00, 00, }, 254df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {84, 73, 78, 71, 00, 00, }, {84, 79, 78, 71, 00, 00, }, 255df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {84, 79, 85, 00, 00, 00, }, {84, 85, 00, 00, 00, 00, }, 256df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {84, 85, 65, 78, 00, 00, }, {84, 85, 73, 00, 00, 00, }, 257df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {84, 85, 78, 00, 00, 00, }, {84, 85, 79, 00, 00, 00, }, 258df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {87, 65, 00, 00, 00, 00, }, {87, 65, 73, 00, 00, 00, }, 259df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {87, 65, 78, 00, 00, 00, }, {87, 65, 78, 71, 00, 00, }, 260df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {87, 69, 73, 00, 00, 00, }, {87, 69, 78, 00, 00, 00, }, 261df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {87, 69, 78, 71, 00, 00, }, {87, 79, 00, 00, 00, 00, }, 262df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {87, 85, 00, 00, 00, 00, }, {88, 73, 00, 00, 00, 00, }, 263df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {88, 73, 65, 00, 00, 00, }, {88, 73, 65, 78, 00, 00, }, 264df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {88, 73, 65, 78, 71, 00, }, {88, 73, 65, 79, 00, 00, }, 265df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {88, 73, 69, 00, 00, 00, }, {88, 73, 78, 00, 00, 00, }, 266df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {88, 73, 78, 71, 00, 00, }, {88, 73, 79, 78, 71, 00, }, 267df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {88, 73, 85, 00, 00, 00, }, {88, 85, 00, 00, 00, 00, }, 268df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {88, 85, 65, 78, 00, 00, }, {88, 85, 69, 00, 00, 00, }, 269df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {88, 85, 78, 00, 00, 00, }, {89, 65, 00, 00, 00, 00, }, 270df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {89, 65, 78, 00, 00, 00, }, {89, 65, 78, 71, 00, 00, }, 271df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {89, 65, 79, 00, 00, 00, }, {89, 69, 00, 00, 00, 00, }, 272df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {89, 73, 00, 00, 00, 00, }, {89, 73, 78, 00, 00, 00, }, 273df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {89, 73, 78, 71, 00, 00, }, {89, 79, 00, 00, 00, 00, }, 274df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {89, 79, 78, 71, 00, 00, }, {89, 79, 85, 00, 00, 00, }, 275df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {89, 85, 00, 00, 00, 00, }, {89, 85, 65, 78, 00, 00, }, 276df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {89, 85, 69, 00, 00, 00, }, {89, 85, 78, 00, 00, 00, }, 277df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 65, 00, 00, 00, 00, }, {90, 65, 73, 00, 00, 00, }, 278df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 65, 78, 00, 00, 00, }, {90, 65, 78, 71, 00, 00, }, 279df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 65, 79, 00, 00, 00, }, {90, 69, 00, 00, 00, 00, }, 280df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 69, 73, 00, 00, 00, }, {90, 69, 78, 00, 00, 00, }, 281df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 69, 78, 71, 00, 00, }, {90, 72, 65, 00, 00, 00, }, 282df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 72, 65, 73, 00, 00, }, {90, 72, 65, 78, 00, 00, }, 283df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 72, 65, 78, 71, 00, }, {90, 72, 65, 79, 00, 00, }, 284df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 72, 69, 00, 00, 00, }, {90, 72, 69, 78, 00, 00, }, 285df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 72, 69, 78, 71, 00, }, {90, 72, 73, 00, 00, 00, }, 286df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 72, 79, 78, 71, 00, }, {90, 72, 79, 85, 00, 00, }, 287df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 72, 85, 00, 00, 00, }, {90, 72, 85, 65, 00, 00, }, 288df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 72, 85, 65, 73, 00, }, {90, 72, 85, 65, 78, 00, }, 289df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 72, 85, 65, 78, 71, }, {90, 72, 85, 73, 00, 00, }, 290df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 72, 85, 78, 00, 00, }, {90, 72, 85, 79, 00, 00, }, 291df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 73, 00, 00, 00, 00, }, {90, 79, 78, 71, 00, 00, }, 292df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 79, 85, 00, 00, 00, }, {90, 85, 00, 00, 00, 00, }, 293df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 85, 65, 78, 00, 00, }, {90, 85, 73, 00, 00, 00, }, 294df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov {90, 85, 78, 00, 00, 00, }, {90, 85, 79, 00, 00, 00, }, 295df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov 296df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov }; 297df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov 298df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov /** First and last Chinese character with known Pinyin according to zh collation */ 2994256586663f0d045c69ea818db4893b3365b9915Bai Tao private static final String FIRST_PINYIN_UNIHAN = "\u5416"; 3004256586663f0d045c69ea818db4893b3365b9915Bai Tao private static final String LAST_PINYIN_UNIHAN = "\u5497"; 3014256586663f0d045c69ea818db4893b3365b9915Bai Tao /** The first Chinese character in Unicode block */ 3024256586663f0d045c69ea818db4893b3365b9915Bai Tao private static final char FIRST_UNIHAN = '\u3400'; 303df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov private static final Collator COLLATOR = Collator.getInstance(Locale.CHINA); 304df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov 305df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov private static HanziToPinyin sInstance; 306df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov private final boolean mHasChinaCollator; 307df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov 308df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov public static class Token { 309df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov /** 310df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * Separator between target string for each source char 311df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov */ 312df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov public static final String SEPARATOR = " "; 313df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov 3144256586663f0d045c69ea818db4893b3365b9915Bai Tao public static final int LATIN = 1; 315df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov public static final int PINYIN = 2; 316df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov public static final int UNKNOWN = 3; 317df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov 3184256586663f0d045c69ea818db4893b3365b9915Bai Tao public Token() { 3194256586663f0d045c69ea818db4893b3365b9915Bai Tao } 3204256586663f0d045c69ea818db4893b3365b9915Bai Tao 3214256586663f0d045c69ea818db4893b3365b9915Bai Tao public Token(int type, String source, String target) { 3224256586663f0d045c69ea818db4893b3365b9915Bai Tao this.type = type; 3234256586663f0d045c69ea818db4893b3365b9915Bai Tao this.source = source; 3244256586663f0d045c69ea818db4893b3365b9915Bai Tao this.target = target; 3254256586663f0d045c69ea818db4893b3365b9915Bai Tao } 326df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov /** 327df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * Type of this token, ASCII, PINYIN or UNKNOWN. 328df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov */ 329df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov public int type; 330df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov /** 331df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * Original string before translation. 332df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov */ 333df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov public String source; 334df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov /** 335df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * Translated string of source. For Han, target is corresponding Pinyin. 336df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov * Otherwise target is original string in source. 337df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov */ 338df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov public String target; 339df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 340df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov 341df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov protected HanziToPinyin(boolean hasChinaCollator) { 342df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov mHasChinaCollator = hasChinaCollator; 343df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 344df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov 345df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov public static HanziToPinyin getInstance() { 346df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov synchronized(HanziToPinyin.class) { 347df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov if (sInstance != null) { 348df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov return sInstance; 349df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 350df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov // Check if zh_CN collation data is available 351df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov final Locale locale[] = Collator.getAvailableLocales(); 352df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov for (int i = 0; i < locale.length; i++) { 353df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov if (locale[i].equals(Locale.CHINA)) { 354df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov sInstance = new HanziToPinyin(true); 355df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov return sInstance; 356df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 357df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 3584256586663f0d045c69ea818db4893b3365b9915Bai Tao Log.w(TAG, "There is no Chinese collator, HanziToPinyin is disabled"); 359df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov sInstance = new HanziToPinyin(false); 360df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov return sInstance; 361df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 362df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 363df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov 364df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov private Token getToken(char character) { 365df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov Token token = new Token(); 366df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov final String letter = Character.toString(character); 367df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov token.source = letter; 368df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov int offset = -1; 369df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov int cmp; 370df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov if (character < 256) { 3714256586663f0d045c69ea818db4893b3365b9915Bai Tao token.type = Token.LATIN; 3724256586663f0d045c69ea818db4893b3365b9915Bai Tao token.target = letter; 3734256586663f0d045c69ea818db4893b3365b9915Bai Tao return token; 3744256586663f0d045c69ea818db4893b3365b9915Bai Tao } else if (character < FIRST_UNIHAN) { 3754256586663f0d045c69ea818db4893b3365b9915Bai Tao token.type = Token.UNKNOWN; 376df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov token.target = letter; 377df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov return token; 378df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } else { 3794256586663f0d045c69ea818db4893b3365b9915Bai Tao cmp = COLLATOR.compare(letter, FIRST_PINYIN_UNIHAN); 380df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov if (cmp < 0) { 381df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov token.type = Token.UNKNOWN; 382df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov token.target = letter; 383df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov return token; 384df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } else if (cmp == 0) { 385df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov token.type = Token.PINYIN; 386df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov offset = 0; 387df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } else { 3884256586663f0d045c69ea818db4893b3365b9915Bai Tao cmp = COLLATOR.compare(letter, LAST_PINYIN_UNIHAN); 389df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov if (cmp > 0) { 390df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov token.type = Token.UNKNOWN; 391df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov token.target = letter; 392df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov return token; 393df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } else if (cmp == 0) { 394df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov token.type = Token.PINYIN; 395df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov offset = UNIHANS.length - 1; 396df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 397df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 398df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 399df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov 400df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov token.type = Token.PINYIN; 401df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov if (offset < 0) { 402df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov int begin = 0; 403df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov int end = UNIHANS.length - 1; 404df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov while (begin <= end) { 405df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov offset = (begin + end) / 2; 406df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov final String unihan = Character.toString(UNIHANS[offset]); 407df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov cmp = COLLATOR.compare(letter, unihan); 408df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov if (cmp == 0) { 409df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov break; 410df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } else if (cmp > 0) { 411df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov begin = offset + 1; 412df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } else { 413df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov end = offset - 1; 414df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 415df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 416df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 417df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov if (cmp < 0) { 418df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov offset--; 419df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 420df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov StringBuilder pinyin = new StringBuilder(); 421df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov for (int j = 0; j < PINYINS[offset].length && PINYINS[offset][j] != 0; j++) { 422df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov pinyin.append((char)PINYINS[offset][j]); 423df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 424df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov token.target = pinyin.toString(); 425df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov return token; 426df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 427df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov 4284256586663f0d045c69ea818db4893b3365b9915Bai Tao /** 4294256586663f0d045c69ea818db4893b3365b9915Bai Tao * Convert the input to a array of tokens. The sequence of ASCII or Unknown 4304256586663f0d045c69ea818db4893b3365b9915Bai Tao * characters without space will be put into a Token, One Hanzi character 4314256586663f0d045c69ea818db4893b3365b9915Bai Tao * which has pinyin will be treated as a Token. 4324256586663f0d045c69ea818db4893b3365b9915Bai Tao * If these is no China collator, the empty token array is returned. 4334256586663f0d045c69ea818db4893b3365b9915Bai Tao */ 434df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov public ArrayList<Token> get(final String input) { 4354256586663f0d045c69ea818db4893b3365b9915Bai Tao ArrayList<Token> tokens = new ArrayList<Token>(); 436df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov if (!mHasChinaCollator || TextUtils.isEmpty(input)) { 4374256586663f0d045c69ea818db4893b3365b9915Bai Tao // return empty tokens. 4384256586663f0d045c69ea818db4893b3365b9915Bai Tao return tokens; 439df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 440df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov final int inputLength = input.length(); 4414256586663f0d045c69ea818db4893b3365b9915Bai Tao final StringBuilder sb = new StringBuilder(); 4424256586663f0d045c69ea818db4893b3365b9915Bai Tao int tokenType = Token.LATIN; 4434256586663f0d045c69ea818db4893b3365b9915Bai Tao // Go through the input, create a new token when 4444256586663f0d045c69ea818db4893b3365b9915Bai Tao // a. Token type changed 4454256586663f0d045c69ea818db4893b3365b9915Bai Tao // b. Get the Pinyin of current charater. 4464256586663f0d045c69ea818db4893b3365b9915Bai Tao // c. current character is space. 4474256586663f0d045c69ea818db4893b3365b9915Bai Tao for (int i = 0; i < inputLength; i++) { 448df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov final char character = input.charAt(i); 4494256586663f0d045c69ea818db4893b3365b9915Bai Tao if (character == ' ') { 4504256586663f0d045c69ea818db4893b3365b9915Bai Tao if (sb.length() > 0) { 4514256586663f0d045c69ea818db4893b3365b9915Bai Tao addToken(sb, tokens, tokenType); 4524256586663f0d045c69ea818db4893b3365b9915Bai Tao } 4534256586663f0d045c69ea818db4893b3365b9915Bai Tao } else if (character < 256) { 4544256586663f0d045c69ea818db4893b3365b9915Bai Tao if (tokenType != Token.LATIN && sb.length() > 0) { 4554256586663f0d045c69ea818db4893b3365b9915Bai Tao addToken(sb, tokens, tokenType); 4564256586663f0d045c69ea818db4893b3365b9915Bai Tao } 4574256586663f0d045c69ea818db4893b3365b9915Bai Tao tokenType = Token.LATIN; 4584256586663f0d045c69ea818db4893b3365b9915Bai Tao sb.append(character); 4594256586663f0d045c69ea818db4893b3365b9915Bai Tao } else if (character < FIRST_UNIHAN) { 4604256586663f0d045c69ea818db4893b3365b9915Bai Tao if (tokenType != Token.UNKNOWN && sb.length() > 0) { 4614256586663f0d045c69ea818db4893b3365b9915Bai Tao addToken(sb, tokens, tokenType); 4624256586663f0d045c69ea818db4893b3365b9915Bai Tao } 4634256586663f0d045c69ea818db4893b3365b9915Bai Tao tokenType = Token.UNKNOWN; 4644256586663f0d045c69ea818db4893b3365b9915Bai Tao sb.append(character); 465df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } else { 4664256586663f0d045c69ea818db4893b3365b9915Bai Tao Token t = getToken(character); 4674256586663f0d045c69ea818db4893b3365b9915Bai Tao if (t.type == Token.PINYIN) { 4684256586663f0d045c69ea818db4893b3365b9915Bai Tao if (sb.length() > 0) { 4694256586663f0d045c69ea818db4893b3365b9915Bai Tao addToken(sb, tokens, tokenType); 4704256586663f0d045c69ea818db4893b3365b9915Bai Tao } 4714256586663f0d045c69ea818db4893b3365b9915Bai Tao tokens.add(t); 4724256586663f0d045c69ea818db4893b3365b9915Bai Tao tokenType = Token.PINYIN; 4734256586663f0d045c69ea818db4893b3365b9915Bai Tao } else { 4744256586663f0d045c69ea818db4893b3365b9915Bai Tao if (tokenType != t.type && sb.length() > 0) { 4754256586663f0d045c69ea818db4893b3365b9915Bai Tao addToken(sb, tokens, tokenType); 4764256586663f0d045c69ea818db4893b3365b9915Bai Tao } 4774256586663f0d045c69ea818db4893b3365b9915Bai Tao tokenType = t.type; 4784256586663f0d045c69ea818db4893b3365b9915Bai Tao sb.append(character); 479df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 480df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 481df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 4824256586663f0d045c69ea818db4893b3365b9915Bai Tao if (sb.length() > 0) { 4834256586663f0d045c69ea818db4893b3365b9915Bai Tao addToken(sb, tokens, tokenType); 4844256586663f0d045c69ea818db4893b3365b9915Bai Tao } 485df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov return tokens; 486df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov } 4874256586663f0d045c69ea818db4893b3365b9915Bai Tao 4884256586663f0d045c69ea818db4893b3365b9915Bai Tao private void addToken(final StringBuilder sb, final ArrayList<Token> tokens, 4894256586663f0d045c69ea818db4893b3365b9915Bai Tao final int tokenType) { 4904256586663f0d045c69ea818db4893b3365b9915Bai Tao String str = sb.toString(); 4914256586663f0d045c69ea818db4893b3365b9915Bai Tao tokens.add(new Token(tokenType, str, str)); 4924256586663f0d045c69ea818db4893b3365b9915Bai Tao sb.setLength(0); 4934256586663f0d045c69ea818db4893b3365b9915Bai Tao } 4944256586663f0d045c69ea818db4893b3365b9915Bai Tao 495df1549128f26be712c46c88202b97145275f2125Dmitri Plotnikov} 496