1b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka/*
2b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka * Copyright (C) 2014 The Android Open Source Project
3b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka *
4b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License");
5b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka * you may not use this file except in compliance with the License.
6b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka * You may obtain a copy of the License at
7b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka *
8b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka *      http://www.apache.org/licenses/LICENSE-2.0
9b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka *
10b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software
11b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS,
12b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka * See the License for the specific language governing permissions and
14b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka * limitations under the License.
15b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka */
16b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
17b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaokapackage com.android.inputmethod.keyboard.layout;
18b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
19b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaokaimport com.android.inputmethod.keyboard.layout.Symbols.RtlSymbols;
20b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaokaimport com.android.inputmethod.keyboard.layout.SymbolsShifted.RtlSymbolsShifted;
216959a0f214fc18e314f54213877956d95a1631e8Tadashi G. Takaokaimport com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer;
22b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaokaimport com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
23b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaokaimport com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
249342484e8d573a40f470b6a593df31c602fa4076Ken Wakasaimport com.android.inputmethod.latin.common.Constants;
25b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
26b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaokaimport java.util.Locale;
27b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
28b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaokapublic final class Farsi extends LayoutBase {
29b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka    private static final String LAYOUT_NAME = "farsi";
30b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
316959a0f214fc18e314f54213877956d95a1631e8Tadashi G. Takaoka    public Farsi(final Locale locale) {
326959a0f214fc18e314f54213877956d95a1631e8Tadashi G. Takaoka        super(new FarsiCustomizer(locale), FarsiSymbols.class, FarsiSymbolsShifted.class);
33b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka    }
34b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
35b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka    @Override
36b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka    public String getName() { return LAYOUT_NAME; }
37b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
386959a0f214fc18e314f54213877956d95a1631e8Tadashi G. Takaoka    private static class FarsiCustomizer extends LayoutCustomizer {
396959a0f214fc18e314f54213877956d95a1631e8Tadashi G. Takaoka        FarsiCustomizer(final Locale locale) { super(locale); }
40b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
41b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        @Override
42b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        public ExpectedKey getAlphabetKey() { return FARSI_ALPHABET_KEY; }
43b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
44b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        @Override
45b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        public ExpectedKey getSymbolsKey() { return FARSI_SYMBOLS_KEY; }
46b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
47b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        @Override
48b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        public ExpectedKey getBackToSymbolsKey() { return FARSI_BACK_TO_SYMBOLS_KEY; }
49b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
50b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        @Override
51b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        public ExpectedKey getCurrencyKey() { return CURRENCY_RIAL; }
52b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
53b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        @Override
54b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        public ExpectedKey[] getOtherCurrencyKeys() {
55b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka            return SymbolsShifted.CURRENCIES_OTHER_GENERIC;
56b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        }
57b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
58b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        @Override
59b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) {
60b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka            return EMPTY_KEYS;
61b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        }
62b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
63b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        @Override
64b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        public ExpectedKey[] getRightShiftKeys(final boolean isPhone) {
65b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka            return EMPTY_KEYS;
66b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        }
67b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
68b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        @Override
69722f5c79668369a69d1b519b8fe8dbd17d7ca6a6Tadashi G. Takaoka        public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) {
70722f5c79668369a69d1b519b8fe8dbd17d7ca6a6Tadashi G. Takaoka            if (isPhone) {
71722f5c79668369a69d1b519b8fe8dbd17d7ca6a6Tadashi G. Takaoka                // U+060C: "،" ARABIC COMMA
72722f5c79668369a69d1b519b8fe8dbd17d7ca6a6Tadashi G. Takaoka                return joinKeys(key("\u060C", SETTINGS_KEY));
73722f5c79668369a69d1b519b8fe8dbd17d7ca6a6Tadashi G. Takaoka            }
74dc62c711aaa8f875996a8dd36d8a1726b8b2fb74Tadashi G. Takaoka            // U+060C: "،" ARABIC COMMA
75dc62c711aaa8f875996a8dd36d8a1726b8b2fb74Tadashi G. Takaoka            // U+061F: "؟" ARABIC QUESTION MARK
76dc62c711aaa8f875996a8dd36d8a1726b8b2fb74Tadashi G. Takaoka            // U+061B: "؛" ARABIC SEMICOLON
77dc62c711aaa8f875996a8dd36d8a1726b8b2fb74Tadashi G. Takaoka            return joinKeys(key("\u060C", joinMoreKeys(
78dc62c711aaa8f875996a8dd36d8a1726b8b2fb74Tadashi G. Takaoka                    ":", "!", "\u061F", "\u061B", "-", RtlSymbols.DOUBLE_ANGLE_QUOTES_LR_RTL,
79c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka                    SETTINGS_KEY)));
80722f5c79668369a69d1b519b8fe8dbd17d7ca6a6Tadashi G. Takaoka        }
81722f5c79668369a69d1b519b8fe8dbd17d7ca6a6Tadashi G. Takaoka
82722f5c79668369a69d1b519b8fe8dbd17d7ca6a6Tadashi G. Takaoka        @Override
83b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) {
84b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka            if (isPhone) {
85b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                return super.getKeysRightToSpacebar(isPhone);
86b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka            }
87c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka            return joinKeys(key(".", getPunctuationMoreKeys(isPhone)));
88b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        }
89b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
90b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        @Override
91b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        public ExpectedKey[] getSpaceKeys(final boolean isPhone) {
92139773d0167a2cf09c4b6c2c47aa7d980dc413bdTadashi G. Takaoka            return joinKeys(LANGUAGE_SWITCH_KEY, SPACE_KEY, key(ZWNJ_KEY, ZWJ_KEY));
93b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        }
94b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
95b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        @Override
96b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) {
97b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka            return FARSI_DIACRITICS;
98b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        }
99b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
100b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        // U+0627: "ا" ARABIC LETTER ALEF
101b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        // U+200C: ZERO WIDTH NON-JOINER
102b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        // U+0628: "ب" ARABIC LETTER BEH
103b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        // U+067E: "پ" ARABIC LETTER PEH
104b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        private static final ExpectedKey FARSI_ALPHABET_KEY = key(
105b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                "\u0627\u200C\u0628\u200C\u067E", Constants.CODE_SWITCH_ALPHA_SYMBOL);
106b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        // U+06F3: "۳" EXTENDED ARABIC-INDIC DIGIT THREE
107b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        // U+06F2: "۲" EXTENDED ARABIC-INDIC DIGIT TWO
108b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        // U+06F1: "۱" EXTENDED ARABIC-INDIC DIGIT ONE
109b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        // U+061F: "؟" ARABIC QUESTION MARK
110b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        private static final ExpectedKey FARSI_SYMBOLS_KEY = key(
111b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                "\u06F3\u06F2\u06F1\u061F", Constants.CODE_SWITCH_ALPHA_SYMBOL);
112b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        private static final ExpectedKey FARSI_BACK_TO_SYMBOLS_KEY = key(
113b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                "\u06F3\u06F2\u06F1\u061F", Constants.CODE_SHIFT);
114b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        // U+FDFC: "﷼" RIAL SIGN
115b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        private static final ExpectedKey CURRENCY_RIAL = key("\uFDFC",
116b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                Symbols.CURRENCY_GENERIC_MORE_KEYS);
117b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        private static final ExpectedKey[] FARSI_DIACRITICS = {
118b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                // U+0655: "ٕ" ARABIC HAMZA BELOW
119b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                // U+0652: "ْ" ARABIC SUKUN
120b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                // U+0651: "ّ" ARABIC SHADDA
121b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                // U+064C: "ٌ" ARABIC DAMMATAN
122b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                // U+064D: "ٍ" ARABIC KASRATAN
123b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                // U+064B: "ً" ARABIC FATHATAN
124b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                // U+0654: "ٔ" ARABIC HAMZA ABOVE
125b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                // U+0656: "ٖ" ARABIC SUBSCRIPT ALEF
126b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                // U+0670: "ٰ" ARABIC LETTER SUPERSCRIPT ALEF
127b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                // U+0653: "ٓ" ARABIC MADDAH ABOVE
128b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                // U+064F: "ُ" ARABIC DAMMA
129b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                // U+0650: "ِ" ARABIC KASRA
130b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                // U+064E: "َ" ARABIC FATHA
131b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                // U+0640: "ـ" ARABIC TATWEEL
132b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                moreKey(" \u0655", "\u0655"), moreKey(" \u0652", "\u0652"),
133b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                moreKey(" \u0651", "\u0651"), moreKey(" \u064C", "\u064C"),
134b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                moreKey(" \u064D", "\u064D"), moreKey(" \u064B", "\u064B"),
135b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                moreKey(" \u0654", "\u0654"), moreKey(" \u0656", "\u0656"),
136b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                moreKey(" \u0670", "\u0670"), moreKey(" \u0653", "\u0653"),
137b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                moreKey(" \u064F", "\u064F"), moreKey(" \u0650", "\u0650"),
138b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                moreKey(" \u064E", "\u064E"), moreKey("\u0640\u0640\u0640", "\u0640")
139b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        };
140b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka    }
141b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
142b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka    @Override
143b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka    ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) {
144b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        if (isPhone) {
145b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka            return ALPHABET_COMMON;
146b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        }
147b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON);
148b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        // U+0622: "آ" ARABIC LETTER ALEF WITH MADDA ABOVE
1496d44cb512239a11572ec18b850d609bacc3267beTadashi G. Takaoka        builder.insertKeysAtRow(3, 10, "\u0622");
150b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        return builder.build();
151b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka    }
152b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
153b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka    @Override
154b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka    ExpectedKey[][] getCommonAlphabetShiftLayout(final boolean isPhone, final int elementId) {
155b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        return null;
156b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka    }
157b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
158b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka    private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder()
159b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka            .setKeysOfRow(1,
160b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0636: "ض" ARABIC LETTER DAD
161b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F1: "۱" EXTENDED ARABIC-INDIC DIGIT ONE
162b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    key("\u0636", joinMoreKeys("\u06F1", "1")),
163b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0635: "ص" ARABIC LETTER SAD
164b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F2: "۲" EXTENDED ARABIC-INDIC DIGIT TWO
165b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    key("\u0635", joinMoreKeys("\u06F2", "2")),
166b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+062B: "ث" ARABIC LETTER THEH
167b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F3: "۳" EXTENDED ARABIC-INDIC DIGIT THREE
168b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    key("\u062B", joinMoreKeys("\u06F3", "3")),
169b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0642: "ق" ARABIC LETTER QAF
170b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F4: "۴" EXTENDED ARABIC-INDIC DIGIT FOUR
171b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    key("\u0642", joinMoreKeys("\u06F4", "4")),
172b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0641: "ف" ARABIC LETTER FEH
173b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F5: "۵" EXTENDED ARABIC-INDIC DIGIT FIVE
174b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    key("\u0641", joinMoreKeys("\u06F5", "5")),
175b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+063A: "غ" ARABIC LETTER GHAIN
176b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F6: "۶" EXTENDED ARABIC-INDIC DIGIT SIX
177b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    key("\u063A", joinMoreKeys("\u06F6", "6")),
178b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0639: "ع" ARABIC LETTER AIN
179b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F7: "۷" EXTENDED ARABIC-INDIC DIGIT SEVEN
180b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    key("\u0639", joinMoreKeys("\u06F7", "7")),
181b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0647: "ه" ARABIC LETTER HEH
182b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+FEEB: "ﻫ" ARABIC LETTER HEH INITIAL FORM
183b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0647/U+200D: ARABIC LETTER HEH + ZERO WIDTH JOINER
184b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0647/U+0654: ARABIC LETTER HEH + ARABIC HAMZA ABOVE
185b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0629: "ة" ARABIC LETTER TEH MARBUTA
186b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F8: "۸" EXTENDED ARABIC-INDIC DIGIT EIGHT
187b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    key("\u0647", joinMoreKeys(moreKey("\uFEEB", "\u0647\u200D"), "\u0647\u0654",
188b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                            "\u0629", "\u06F8", "8")),
189b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+062E: "خ" ARABIC LETTER KHAH
190b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F9: "۹" EXTENDED ARABIC-INDIC DIGIT NINE
191b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    key("\u062E", joinMoreKeys("\u06F9", "9")),
192b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+062D: "ح" ARABIC LETTER HAH
193b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F0: "۰" EXTENDED ARABIC-INDIC DIGIT ZERO
194b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    key("\u062D", joinMoreKeys("\u06F0", "0")),
195b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+062C: "ج" ARABIC LETTER JEEM
1966d44cb512239a11572ec18b850d609bacc3267beTadashi G. Takaoka                    "\u062C")
197b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka            .setKeysOfRow(2,
198b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0634: "ش" ARABIC LETTER SHEEN
199b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0633: "س" ARABIC LETTER SEEN
2006d44cb512239a11572ec18b850d609bacc3267beTadashi G. Takaoka                    "\u0634", "\u0633",
201b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06CC: "ی" ARABIC LETTER FARSI YEH
202b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0626: "ئ" ARABIC LETTER YEH WITH HAMZA ABOVE
203b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+064A: "ي" ARABIC LETTER YEH
204b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+FBE8: "ﯨ" ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM
205b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0649: "ى" ARABIC LETTER ALEF MAKSURA
206b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    key("\u06CC", joinMoreKeys("\u0626", "\u064A", moreKey("\uFBE8", "\u0649"))),
207b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0628: "ب" ARABIC LETTER BEH
208b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0644: "ل" ARABIC LETTER LAM
2096d44cb512239a11572ec18b850d609bacc3267beTadashi G. Takaoka                    "\u0628", "\u0644",
210b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0627: "ا" ARABIC LETTER ALEF
211b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0671: "ٱ" ARABIC LETTER ALEF WASLA
212b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0621: "ء" ARABIC LETTER HAMZA
213b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0622: "آ" ARABIC LETTER ALEF WITH MADDA ABOVE
214b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0623: "أ" ARABIC LETTER ALEF WITH HAMZA ABOVE
215b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0625: "إ" ARABIC LETTER ALEF WITH HAMZA BELOW
216b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    key("\u0627", joinMoreKeys("\u0671", "\u0621", "\u0622", "\u0623", "\u0625")),
217b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+062A: "ت" ARABIC LETTER TEH
218b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0629: "ة": ARABIC LETTER TEH MARBUTA
219b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    key("\u062A", moreKey("\u0629")),
220b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0646: "ن" ARABIC LETTER NOON
221b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0645: "م" ARABIC LETTER MEEM
2226d44cb512239a11572ec18b850d609bacc3267beTadashi G. Takaoka                    "\u0646", "\u0645",
223b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06A9: "ک" ARABIC LETTER KEHEH
224b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0643: "ك" ARABIC LETTER KAF
225b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    key("\u06A9", moreKey("\u0643")),
226b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06AF: "گ" ARABIC LETTER GAF
2276d44cb512239a11572ec18b850d609bacc3267beTadashi G. Takaoka                    "\u06AF")
2286d44cb512239a11572ec18b850d609bacc3267beTadashi G. Takaoka            .setKeysOfRow(3,
229b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0638: "ظ" ARABIC LETTER ZAH
230b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0637: "ط" ARABIC LETTER TAH
231b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0698: "ژ" ARABIC LETTER JEH
232b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0632: "ز" ARABIC LETTER ZAIN
233b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0631: "ر" ARABIC LETTER REH
234b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0630: "ذ" ARABIC LETTER THAL
235b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+062F: "د" ARABIC LETTER DAL
236b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+067E: "پ" ARABIC LETTER PEH
237b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    "\u0638", "\u0637", "\u0698", "\u0632", "\u0631", "\u0630", "\u062F", "\u067E",
238b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0648: "و" ARABIC LETTER WAW
239b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0624: "ؤ" ARABIC LETTER WAW WITH HAMZA ABOVE
240b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    key("\u0648", moreKey("\u0624")),
241b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+0686: "چ" ARABIC LETTER TCHEH
2426d44cb512239a11572ec18b850d609bacc3267beTadashi G. Takaoka                    "\u0686")
243b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka            .build();
244b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
245b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka    private static class FarsiSymbols extends RtlSymbols {
246b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        public FarsiSymbols(final LayoutCustomizer customizer) {
247b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka            super(customizer);
248b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        }
249b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
250b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        @Override
251b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        public ExpectedKey[][] getLayout(final boolean isPhone) {
252b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka            return new ExpectedKeyboardBuilder(super.getLayout(isPhone))
253b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F1: "۱" EXTENDED ARABIC-INDIC DIGIT ONE
254b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+00B9: "¹" SUPERSCRIPT ONE
255b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+00BD: "½" VULGAR FRACTION ONE HALF
256b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+2153: "⅓" VULGAR FRACTION ONE THIRD
257b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+00BC: "¼" VULGAR FRACTION ONE QUARTER
258b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+215B: "⅛" VULGAR FRACTION ONE EIGHTH
259b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("1", key("\u06F1",
260b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                            joinMoreKeys("1", "\u00B9", "\u00BD", "\u2153", "\u00BC", "\u215B")))
261b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F2: "۲" EXTENDED ARABIC-INDIC DIGIT TWO
262b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+00B2: "²" SUPERSCRIPT TWO
263b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+2154: "⅔" VULGAR FRACTION TWO THIRDS
264b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("2", key("\u06F2", joinMoreKeys("2", "\u00B2", "\u2154")))
265b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F3: "۳" EXTENDED ARABIC-INDIC DIGIT THREE
266b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+00B3: "³" SUPERSCRIPT THREE
267b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+00BE: "¾" VULGAR FRACTION THREE QUARTERS
268b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+215C: "⅜" VULGAR FRACTION THREE EIGHTHS
269b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("3", key("\u06F3",
270b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                            joinMoreKeys("3", "\u00B3", "\u00BE", "\u215C")))
271b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F4: "۴" EXTENDED ARABIC-INDIC DIGIT FOUR
272b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+2074: "⁴" SUPERSCRIPT FOUR
273b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("4", key("\u06F4", joinMoreKeys("4", "\u2074")))
274b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F5: "۵" EXTENDED ARABIC-INDIC DIGIT FIVE
275b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+215D: "⅝" VULGAR FRACTION FIVE EIGHTHS
276b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("5", key("\u06F5", joinMoreKeys("5", "\u215D")))
277b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F6: "۶" EXTENDED ARABIC-INDIC DIGIT SIX
278b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("6", key("\u06F6", moreKey("6")))
279b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F7: "۷" EXTENDED ARABIC-INDIC DIGIT SEVEN
280b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+215E: "⅞" VULGAR FRACTION SEVEN EIGHTHS
281b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("7", key("\u06F7", joinMoreKeys("7", "\u215E")))
282b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F8: "۸" EXTENDED ARABIC-INDIC DIGIT EIGHT
283b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("8", key("\u06F8", moreKey("8")))
284b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F9: "۹" EXTENDED ARABIC-INDIC DIGIT NINE
285b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("9", key("\u06F9", moreKey("9")))
286b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+066C: "٬" ARABIC THOUSANDS SEPARATOR
287b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("@", key("\u066C", moreKey("@")))
288b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+066B: "٫" ARABIC DECIMAL SEPARATOR
289b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("#", key("\u066B", moreKey("#")))
290b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+06F0: "۰" EXTENDED ARABIC-INDIC DIGIT ZERO
291b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+066B: "٫" ARABIC DECIMAL SEPARATOR
292b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+066C: "٬" ARABIC THOUSANDS SEPARATOR
293b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+207F: "ⁿ" SUPERSCRIPT LATIN SMALL LETTER N
294b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+2205: "∅" EMPTY SET
295b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("0", key("\u06F0",
296b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                            joinMoreKeys("0", "\u066B", "\u066C", "\u207F", "\u2205")))
297b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+066A: "٪" ARABIC PERCENT SIGN
298b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+2030: "‰" PER MILLE SIGN
299b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("%", key("\u066A", joinMoreKeys("%", "\u2030")))
300b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
301b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
302b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+2264: "≤" LESS-THAN OR EQUAL TO
303b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("\"", key("\u00AB", "\u00BB", joinMoreKeys(
304b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                            DOUBLE_QUOTES_9LR, DOUBLE_ANGLE_QUOTES_LR_RTL)))
305b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
306b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
307b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+2265: "≥" GREATER-THAN EQUAL TO
308b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("'", key("\u00BB", "\u00AB", joinMoreKeys(
309b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                            SINGLE_QUOTES_9LR, SINGLE_ANGLE_QUOTES_LR_RTL)))
310b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+061B: "؛" ARABIC SEMICOLON
311b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel(";", key("\u061B", moreKey(";")))
312b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+061F: "؟" ARABIC QUESTION MARK
313b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+00BF: "¿" INVERTED QUESTION MARK
314b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("?", key("\u061F", joinMoreKeys("?", "\u00BF")))
315b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+060C: "،" ARABIC COMMA
316270bd39af44c4f6e1056d591c12a6a017125e5d4Tadashi G. Takaoka                    .replaceKeyOfLabel(",", "\u060C")
317b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+FD3E: "﴾" ORNATE LEFT PARENTHESIS
318b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+FD3F: "﴿" ORNATE RIGHT PARENTHESIS
319b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("(", key("(", ")",
320b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                            moreKey("\uFD3E", "\uFD3F"), moreKey("<", ">"), moreKey("{", "}"),
321b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                            moreKey("[", "]")))
322b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+FD3F: "﴿" ORNATE RIGHT PARENTHESIS
323b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+FD3E: "﴾" ORNATE LEFT PARENTHESIS
324b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel(")", key(")", "(",
325b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                            moreKey("\uFD3F", "\uFD3E"), moreKey(">", "<"), moreKey("}", "{"),
326b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                            moreKey("]", "[")))
327b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+2605: "★" BLACK STAR
328b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+066D: "٭" ARABIC FIVE POINTED STAR
329b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .setMoreKeysOf("*", "\u2605", "\u066D")
330b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .build();
331b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        }
332b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka    }
333b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
334b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka    private static class FarsiSymbolsShifted extends RtlSymbolsShifted {
335b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        public FarsiSymbolsShifted(final LayoutCustomizer customizer) {
336b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka            super(customizer);
337b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        }
338b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka
339b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        @Override
340b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        public ExpectedKey[][] getLayout(final boolean isPhone) {
341b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka            return new ExpectedKeyboardBuilder(super.getLayout(isPhone))
342b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+2022: "•" BULLET
343b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+266A: "♪" EIGHTH NOTE
344b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .setMoreKeysOf("\u2022", "\u266A")
345b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+060C: "،" ARABIC COMMA
346270bd39af44c4f6e1056d591c12a6a017125e5d4Tadashi G. Takaoka                    .replaceKeyOfLabel(",", "\u060C")
347b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
348b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
349b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+2264: "≤" LESS-THAN OR EQUAL TO
350b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel("<", key("\u00AB", "\u00BB",
351b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                            moreKey("\u2039", "\u203A"), moreKey("\u2264", "\u2265"),
352b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                            moreKey("<", ">")))
353b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
354b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
355b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    // U+2265: "≥" GREATER-THAN EQUAL TO
356b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .replaceKeyOfLabel(">", key("\u00BB", "\u00AB",
357b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                            moreKey("\u203A", "\u2039"), moreKey("\u2265", "\u2264"),
358b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                            moreKey(">", "<")))
359b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka                    .build();
360b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka        }
361b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka    }
362b8f8d2ceb87c2aaa39f1f278a6e10215ecaffc24Tadashi G. Takaoka}
363