Pre Merge pull request !27 from ShikiSuen/upd/1.5.5
This commit is contained in:
commit
c4c483f982
16
AUTHORS
16
AUTHORS
|
@ -1,11 +1,15 @@
|
||||||
$ Main contributors and volunteers of this repository (vChewing for macOS):
|
$ Main contributors and volunteers of this repository (vChewing for macOS):
|
||||||
|
|
||||||
Shiki Suen // Main developer of vChewing for macOS.
|
- Shiki Suen // Main developer of vChewing for macOS.
|
||||||
Hiraku Wang // Technical assistant in Cocoa.
|
- Hiraku Wang // Technical reinforcement in Cocoa during the Object-Cpp dev period of this project.
|
||||||
|
- Isaac Xen // Technical reinforcement in Swift: SFX Module and StringView Ranges Extension.
|
||||||
|
|
||||||
$ Contributors and volunteeres of the upstream repo, having no responsibility in discussing anything in the current repo:
|
$ Contributors and volunteeres of the upstream repo, having no responsibility in discussing anything in the current repo:
|
||||||
|
|
||||||
Mengjuei Hsieh // McBopomofo for macOS 1.x main developer and architect.
|
- Mengjuei Hsieh // McBopomofo for macOS 1.x main developer and architect.
|
||||||
Zonble Yang // McBopomofo for macOS 2.x architect.
|
- Zonble Yang // McBopomofo for macOS 2.x architect, especially state-based IME behavior management.
|
||||||
Lukhnos D Liu // Mandarin and Gramambular engine developer.
|
- Lukhnos D Liu // Developer of the Mandarin syllable input processor.
|
||||||
|
|
||||||
|
$ Special thanks to:
|
||||||
|
|
||||||
|
- All supporters from Cocoaheads Taipei and Mobile01 community.
|
||||||
|
|
|
@ -356,7 +356,7 @@ func weightAndSort(_ arrStructUncalculated: [Entry], isCHS: Bool) -> [Entry] {
|
||||||
weight = -13
|
weight = -13
|
||||||
case 0: // 墊底低頻漢字與詞語
|
case 0: // 墊底低頻漢字與詞語
|
||||||
weight = log10(
|
weight = log10(
|
||||||
fscale ** (Float(entry.valPhrase.count) / 3.0 - 1.0) * 0.5 / norm)
|
fscale ** (Float(entry.valPhrase.count) / 3.0 - 1.0) * 0.25 / norm)
|
||||||
default:
|
default:
|
||||||
weight = log10(
|
weight = log10(
|
||||||
fscale ** (Float(entry.valPhrase.count) / 3.0 - 1.0)
|
fscale ** (Float(entry.valPhrase.count) / 3.0 - 1.0)
|
||||||
|
|
|
@ -198,7 +198,7 @@
|
||||||
<textFieldCell key="cell" selectable="YES" id="VW8-s5-Wpn">
|
<textFieldCell key="cell" selectable="YES" id="VW8-s5-Wpn">
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
<string key="title">McBopomofo Engine by Mengjuei Hsieh, Lukhnos Liu, Zonble Yang, et al.
|
<string key="title">McBopomofo Engine by Mengjuei Hsieh, Lukhnos Liu, Zonble Yang, et al.
|
||||||
vChewing macOS Development: Shiki Suen, Hiraku Wang, etc.
vChewing Phrase Database Maintained by Shiki Suen.</string>
|
vChewing macOS Development: Shiki Suen, Isaac Xen, Hiraku Wang, etc.
vChewing Phrase Database Maintained by Shiki Suen.</string>
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
|
|
|
@ -56,8 +56,8 @@
|
||||||
/* Class = "NSTextFieldCell"; title = "Derived from OpenVanilla McBopopmofo Project."; ObjectID = "QYf-Nf-hoi"; */
|
/* Class = "NSTextFieldCell"; title = "Derived from OpenVanilla McBopopmofo Project."; ObjectID = "QYf-Nf-hoi"; */
|
||||||
"QYf-Nf-hoi.title" = "Derived from OpenVanilla McBopopmofo Project.";
|
"QYf-Nf-hoi.title" = "Derived from OpenVanilla McBopopmofo Project.";
|
||||||
|
|
||||||
/* Class = "NSTextFieldCell"; title = "Mandarin Syllable Composer Engine by Lukhnos Liu.\nInput State Management Architecture by Zonble Yang.\nvChewing macOS Development: Shiki Suen, Hiraku Wang, etc.\nvChewing Phrase Database Maintained by Shiki Suen.\nMegrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine."; ObjectID = "VW8-s5-Wpn"; */
|
/* Class = "NSTextFieldCell"; title = "Mandarin Syllable Composer Engine by Lukhnos Liu.\nInput State Management Architecture by Zonble Yang.\nvChewing macOS Development: Shiki Suen, Isaac Xen, Hiraku Wang, etc.\nvChewing Phrase Database Maintained by Shiki Suen.\nMegrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine."; ObjectID = "VW8-s5-Wpn"; */
|
||||||
"VW8-s5-Wpn.title" = "Mandarin Syllable Composer Engine by Lukhnos Liu.\nInput State Management Architecture by Zonble Yang.\nvChewing macOS Development: Shiki Suen, Hiraku Wang, etc.\nvChewing Phrase Database Maintained by Shiki Suen.\nMegrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine.";
|
"VW8-s5-Wpn.title" = "Mandarin Syllable Composer Engine by Lukhnos Liu.\nInput State Management Architecture by Zonble Yang.\nvChewing macOS Development: Shiki Suen, Isaac Xen, Hiraku Wang, etc.\nvChewing Phrase Database Maintained by Shiki Suen.\nMegrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine.";
|
||||||
|
|
||||||
/* Class = "NSTextFieldCell"; title = "Placeholder for showing copyright information."; ObjectID = "eo3-TK-0rB"; */
|
/* Class = "NSTextFieldCell"; title = "Placeholder for showing copyright information."; ObjectID = "eo3-TK-0rB"; */
|
||||||
// "eo3-TK-0rB.title" = "Placeholder for showing copyright information.";
|
// "eo3-TK-0rB.title" = "Placeholder for showing copyright information.";
|
||||||
|
|
|
@ -56,8 +56,8 @@
|
||||||
/* Class = "NSTextFieldCell"; title = "Derived from OpenVanilla McBopopmofo Project."; ObjectID = "QYf-Nf-hoi"; */
|
/* Class = "NSTextFieldCell"; title = "Derived from OpenVanilla McBopopmofo Project."; ObjectID = "QYf-Nf-hoi"; */
|
||||||
"QYf-Nf-hoi.title" = "OpenVanilla 小麦注音プロジェクトから派生。";
|
"QYf-Nf-hoi.title" = "OpenVanilla 小麦注音プロジェクトから派生。";
|
||||||
|
|
||||||
/* Class = "NSTextFieldCell"; title = "Mandarin Syllable Composer Engine by Lukhnos Liu.\nInput State Management Architecture by Zonble Yang.\nvChewing macOS Development: Shiki Suen, Hiraku Wang, etc.\nvChewing Phrase Database Maintained by Shiki Suen.\nMegrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine."; ObjectID = "VW8-s5-Wpn"; */
|
/* Class = "NSTextFieldCell"; title = "Mandarin Syllable Composer Engine by Lukhnos Liu.\nInput State Management Architecture by Zonble Yang.\nvChewing macOS Development: Shiki Suen, Isaac Xen, Hiraku Wang, etc.\nvChewing Phrase Database Maintained by Shiki Suen.\nMegrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine."; ObjectID = "VW8-s5-Wpn"; */
|
||||||
"VW8-s5-Wpn.title" = "ボポモフォエンジン開発:Lukhnos Liu。\n入力状態管理システム開発:Zonble Yang。\nmacOS 版威注音の開発:Shiki Suen, Hiraku Wang, など。\n威注音語彙データの維持:Shiki Suen。\nMegrez 辞書処理エンジン:Shiki Suen(Lukhnos の Gramambular C++ エンジンを Swift で再開発したものである)。";
|
"VW8-s5-Wpn.title" = "ボポモフォエンジン開発:Lukhnos Liu。\n入力状態管理システム開発:Zonble Yang。\nmacOS 版威注音の開発:Shiki Suen, Isaac Xen, Hiraku Wang, など。\n威注音語彙データの維持:Shiki Suen。\nMegrez 辞書処理エンジン:Shiki Suen(Lukhnos の Gramambular C++ エンジンを Swift で再開発したものである)。";
|
||||||
|
|
||||||
/* Class = "NSTextFieldCell"; title = "Placeholder for showing copyright information."; ObjectID = "eo3-TK-0rB"; */
|
/* Class = "NSTextFieldCell"; title = "Placeholder for showing copyright information."; ObjectID = "eo3-TK-0rB"; */
|
||||||
"eo3-TK-0rB.title" = "Placeholder for showing copyright information.";
|
"eo3-TK-0rB.title" = "Placeholder for showing copyright information.";
|
||||||
|
|
|
@ -56,9 +56,9 @@
|
||||||
/* Class = "NSTextFieldCell"; title = "Derived from OpenVanilla McBopopmofo Project."; ObjectID = "QYf-Nf-hoi"; */
|
/* Class = "NSTextFieldCell"; title = "Derived from OpenVanilla McBopopmofo Project."; ObjectID = "QYf-Nf-hoi"; */
|
||||||
"QYf-Nf-hoi.title" = "该专案由 OpenVanilla 小麦注音专案衍生而来。";
|
"QYf-Nf-hoi.title" = "该专案由 OpenVanilla 小麦注音专案衍生而来。";
|
||||||
|
|
||||||
/* Class = "NSTextFieldCell"; title = "McBopomofo Engine by Mengjuei Hsieh, Lukhnos Liu, Zonble Yang, et al.\nvChewing macOS Development: Shiki Suen, Hiraku Wang, etc.
|
/* Class = "NSTextFieldCell"; title = "McBopomofo Engine by Mengjuei Hsieh, Lukhnos Liu, Zonble Yang, et al.\nvChewing macOS Development: Shiki Suen, Isaac Xen, Hiraku Wang, etc.
|
||||||
vChewing Phrase Database Maintained by Shiki Suen."; ObjectID = "VW8-s5-Wpn"; */
|
vChewing Phrase Database Maintained by Shiki Suen."; ObjectID = "VW8-s5-Wpn"; */
|
||||||
"VW8-s5-Wpn.title" = "注音拼音输入处理引擎研发:Lukhnos Liu。\n输入法状态管理引擎研发:Zonble Yang。\n威注音 macOS 程式研发:Shiki Suen, Hiraku Wang, 等。\n威注音词库维护:Shiki Suen。\n天权星语汇引擎:Shiki Suen,用 Swift 将 Lukhnos 的 C++ Gramambular 重写而得。";
|
"VW8-s5-Wpn.title" = "注音拼音输入处理引擎研发:Lukhnos Liu。\n输入法状态管理引擎研发:Zonble Yang。\n威注音 macOS 程式研发:Shiki Suen, Isaac Xen, Hiraku Wang, 等。\n威注音词库维护:Shiki Suen。\n天权星语汇引擎:Shiki Suen,用 Swift 将 Lukhnos 的 C++ Gramambular 重写而得。";
|
||||||
|
|
||||||
/* Class = "NSTextFieldCell"; title = "Placeholder for showing copyright information."; ObjectID = "eo3-TK-0rB"; */
|
/* Class = "NSTextFieldCell"; title = "Placeholder for showing copyright information."; ObjectID = "eo3-TK-0rB"; */
|
||||||
// "eo3-TK-0rB.title" = "Placeholder for showing copyright information.";
|
// "eo3-TK-0rB.title" = "Placeholder for showing copyright information.";
|
||||||
|
|
|
@ -56,9 +56,9 @@
|
||||||
/* Class = "NSTextFieldCell"; title = "Derived from OpenVanilla McBopopmofo Project."; ObjectID = "QYf-Nf-hoi"; */
|
/* Class = "NSTextFieldCell"; title = "Derived from OpenVanilla McBopopmofo Project."; ObjectID = "QYf-Nf-hoi"; */
|
||||||
"QYf-Nf-hoi.title" = "該專案由 OpenVanilla 小麥注音專案衍生而來。";
|
"QYf-Nf-hoi.title" = "該專案由 OpenVanilla 小麥注音專案衍生而來。";
|
||||||
|
|
||||||
/* Class = "NSTextFieldCell"; title = "McBopomofo Engine by Mengjuei Hsieh, Lukhnos Liu, Zonble Yang, et al.\nvChewing macOS Development: Shiki Suen, Hiraku Wang, etc.
|
/* Class = "NSTextFieldCell"; title = "McBopomofo Engine by Mengjuei Hsieh, Lukhnos Liu, Zonble Yang, et al.\nvChewing macOS Development: Shiki Suen, Isaac Xen, Hiraku Wang, etc.
|
||||||
vChewing Phrase Database Maintained by Shiki Suen."; ObjectID = "VW8-s5-Wpn"; */
|
vChewing Phrase Database Maintained by Shiki Suen."; ObjectID = "VW8-s5-Wpn"; */
|
||||||
"VW8-s5-Wpn.title" = "注音拼音輸入處理引擎研發:Lukhnos Liu。\n輸入法狀態管理引擎研發:Zonble Yang。\n威注音 macOS 程式研發:Shiki Suen, Hiraku Wang, 等。\n威注音詞庫維護:Shiki Suen。\n天權星語彙引擎:Shiki Suen,用 Swift 將 Lukhnos 的 C++ Gramambular 重寫而得。";
|
"VW8-s5-Wpn.title" = "注音拼音輸入處理引擎研發:Lukhnos Liu。\n輸入法狀態管理引擎研發:Zonble Yang。\n威注音 macOS 程式研發:Shiki Suen, Isaac Xen, Hiraku Wang, 等。\n威注音詞庫維護:Shiki Suen。\n天權星語彙引擎:Shiki Suen,用 Swift 將 Lukhnos 的 C++ Gramambular 重寫而得。";
|
||||||
|
|
||||||
/* Class = "NSTextFieldCell"; title = "Placeholder for showing copyright information."; ObjectID = "eo3-TK-0rB"; */
|
/* Class = "NSTextFieldCell"; title = "Placeholder for showing copyright information."; ObjectID = "eo3-TK-0rB"; */
|
||||||
// "eo3-TK-0rB.title" = "Placeholder for showing copyright information.";
|
// "eo3-TK-0rB.title" = "Placeholder for showing copyright information.";
|
||||||
|
|
|
@ -5,7 +5,7 @@ vChewing macOS: MIT-NTL License 麻理(去商标)授权合约
|
||||||
© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project.
|
© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project.
|
||||||
注音拼音输入处理引擎研发:Lukhnos Liu。
|
注音拼音输入处理引擎研发:Lukhnos Liu。
|
||||||
输入法状态管理引擎研发:Zonble Yang。
|
输入法状态管理引擎研发:Zonble Yang。
|
||||||
威注音 macOS 程式研发:Shiki Suen, Hiraku Wang, 等。
|
威注音 macOS 程式研发:Shiki Suen, Isaac Xen, Hiraku Wang, 等。
|
||||||
威注音词库维护:Shiki Suen。
|
威注音词库维护:Shiki Suen。
|
||||||
天权星语汇引擎:Shiki Suen,用 Swift 将 Lukhnos 的 C++ Gramambular 重写而得。
|
天权星语汇引擎:Shiki Suen,用 Swift 将 Lukhnos 的 C++ Gramambular 重写而得。
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ vChewing macOS: MIT-NTL License 麻理(去商標)授權合約
|
||||||
© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project.
|
© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project.
|
||||||
注音拼音輸入處理引擎研發:Lukhnos Liu。
|
注音拼音輸入處理引擎研發:Lukhnos Liu。
|
||||||
輸入法狀態管理引擎研發:Zonble Yang。
|
輸入法狀態管理引擎研發:Zonble Yang。
|
||||||
威注音 macOS 程式研發:Shiki Suen, Hiraku Wang, 等。
|
威注音 macOS 程式研發:Shiki Suen, Isaac Xen, Hiraku Wang, 等。
|
||||||
威注音詞庫維護:Shiki Suen。
|
威注音詞庫維護:Shiki Suen。
|
||||||
天權星語彙引擎:Shiki Suen,用 Swift 將 Lukhnos 的 C++ Gramambular 重寫而得。
|
天權星語彙引擎:Shiki Suen,用 Swift 將 Lukhnos 的 C++ Gramambular 重寫而得。
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ vChewing macOS: MIT商標不許可ライセンス (MIT-NTL License)
|
||||||
|
|
||||||
ボポモフォエンジン開発:Lukhnos Liu。
|
ボポモフォエンジン開発:Lukhnos Liu。
|
||||||
入力状態管理システム開発:Zonble Yang。
|
入力状態管理システム開発:Zonble Yang。
|
||||||
macOS 版威注音の開発:Shiki Suen, Hiraku Wang, など。
|
macOS 版威注音の開発:Shiki Suen, Isaac Xen, Hiraku Wang, など。
|
||||||
威注音語彙データの維持:Shiki Suen。
|
威注音語彙データの維持:Shiki Suen。
|
||||||
Megrez 辞書処理エンジン:Shiki Suen(Lukhnos の Gramambular C++ エンジンを Swift で再開発したものである)。
|
Megrez 辞書処理エンジン:Shiki Suen(Lukhnos の Gramambular C++ エンジンを Swift で再開発したものである)。
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ vChewing macOS: MIT-NTL License
|
||||||
© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project.
|
© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project.
|
||||||
Mandarin Syllable Composer Engine by Lukhnos Liu.
|
Mandarin Syllable Composer Engine by Lukhnos Liu.
|
||||||
Input State Management Architecture by Zonble Yang.
|
Input State Management Architecture by Zonble Yang.
|
||||||
vChewing macOS Development: Shiki Suen, Hiraku Wang, etc.
|
vChewing macOS Development: Shiki Suen, Isaac Xen, Hiraku Wang, etc.
|
||||||
vChewing Phrase Database Maintained by Shiki Suen.
|
vChewing Phrase Database Maintained by Shiki Suen.
|
||||||
Megrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine.
|
Megrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine.
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
+ (BOOL)isBufferEmpty;
|
+ (BOOL)isBufferEmpty;
|
||||||
+ (void)clearBuffer;
|
+ (void)clearBuffer;
|
||||||
+ (void)combineReadingKey:(UniChar)charCode;
|
+ (void)combineReadingKey:(UniChar)charCode;
|
||||||
+ (BOOL)checkWhetherToneMarkerConfirms;
|
+ (BOOL)hasToneMarker;
|
||||||
|
+ (BOOL)hasToneMarkerOnly;
|
||||||
+ (NSString *)getSyllableComposition;
|
+ (NSString *)getSyllableComposition;
|
||||||
+ (void)doBackSpaceToBuffer;
|
+ (void)doBackSpaceToBuffer;
|
||||||
+ (NSString *)getComposition;
|
+ (NSString *)getComposition;
|
||||||
|
|
|
@ -52,11 +52,16 @@ static Mandarin::BopomofoReadingBuffer *PhoneticBuffer;
|
||||||
PhoneticBuffer->combineKey((char)charCode);
|
PhoneticBuffer->combineKey((char)charCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (BOOL)checkWhetherToneMarkerConfirms
|
+ (BOOL)hasToneMarker
|
||||||
{
|
{
|
||||||
return PhoneticBuffer->hasToneMarker();
|
return PhoneticBuffer->hasToneMarker();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (BOOL)hasToneMarkerOnly
|
||||||
|
{
|
||||||
|
return PhoneticBuffer->hasToneMarkerOnly();
|
||||||
|
}
|
||||||
|
|
||||||
+ (NSString *)getSyllableComposition
|
+ (NSString *)getSyllableComposition
|
||||||
{
|
{
|
||||||
return [NSString stringWithUTF8String:PhoneticBuffer->syllable().composedString().c_str()];
|
return [NSString stringWithUTF8String:PhoneticBuffer->syllable().composedString().c_str()];
|
||||||
|
|
|
@ -569,6 +569,12 @@ extern "C" class BopomofoReadingBuffer
|
||||||
return syllable_.hasToneMarker();
|
return syllable_.hasToneMarker();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hasToneMarkerOnly() const
|
||||||
|
{
|
||||||
|
return syllable_.hasToneMarker() &&
|
||||||
|
!(syllable_.hasConsonant() || syllable_.hasMiddleVowel() || syllable_.hasVowel());
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const BopomofoKeyboardLayout *layout_;
|
const BopomofoKeyboardLayout *layout_;
|
||||||
BPMF syllable_;
|
BPMF syllable_;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 4065cb727373ab12a3401eb3526e4a6208671e59
|
Subproject commit 4f922087d6c20964a59f7838e05ae82beef493d1
|
|
@ -61,16 +61,16 @@ enum KeyCode: UInt16 {
|
||||||
case kF8 = 100
|
case kF8 = 100
|
||||||
case kF9 = 101
|
case kF9 = 101
|
||||||
case kF11 = 103
|
case kF11 = 103
|
||||||
case kF13 = 105
|
case kF13 = 105 // PrtSc
|
||||||
case kF16 = 106
|
case kF16 = 106
|
||||||
case kF14 = 107
|
case kF14 = 107
|
||||||
case kF10 = 109
|
case kF10 = 109
|
||||||
case kF12 = 111
|
case kF12 = 111
|
||||||
case kF15 = 113
|
case kF15 = 113
|
||||||
case kHelp = 114
|
case kHelp = 114 // Insert
|
||||||
case kHome = 115
|
case kHome = 115
|
||||||
case kPageUp = 116
|
case kPageUp = 116
|
||||||
case kWindowDelete = 117 // Renamed from "kForwardDelete" to avoid nomenclatural confusions.
|
case kWindowsDelete = 117 // Renamed from "kForwardDelete" to avoid nomenclatural confusions.
|
||||||
case kF4 = 118
|
case kF4 = 118
|
||||||
case kEnd = 119
|
case kEnd = 119
|
||||||
case kF2 = 120
|
case kF2 = 120
|
||||||
|
@ -82,6 +82,33 @@ enum KeyCode: UInt16 {
|
||||||
case kUpArrow = 126
|
case kUpArrow = 126
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum KeyCodeBlackListed: UInt16 {
|
||||||
|
case kF17 = 64
|
||||||
|
case kVolumeUp = 72
|
||||||
|
case kVolumeDown = 73
|
||||||
|
case kMute = 74
|
||||||
|
case kF18 = 79
|
||||||
|
case kF19 = 80
|
||||||
|
case kF20 = 90
|
||||||
|
case kF5 = 96
|
||||||
|
case kF6 = 97
|
||||||
|
case kF7 = 98
|
||||||
|
case kF3 = 99
|
||||||
|
case kF8 = 100
|
||||||
|
case kF9 = 101
|
||||||
|
case kF11 = 103
|
||||||
|
case kF13 = 105 // PrtSc
|
||||||
|
case kF16 = 106
|
||||||
|
case kF14 = 107
|
||||||
|
case kF10 = 109
|
||||||
|
case kF12 = 111
|
||||||
|
case kF15 = 113
|
||||||
|
case kHelp = 114 // Insert
|
||||||
|
case kF4 = 118
|
||||||
|
case kF2 = 120
|
||||||
|
case kF1 = 122
|
||||||
|
}
|
||||||
|
|
||||||
// CharCodes: https://theasciicode.com.ar/ascii-control-characters/horizontal-tab-ascii-code-9.html
|
// CharCodes: https://theasciicode.com.ar/ascii-control-characters/horizontal-tab-ascii-code-9.html
|
||||||
enum CharCode: UInt /* 16 */ {
|
enum CharCode: UInt /* 16 */ {
|
||||||
case yajuusenpai = 114_514_191_191_810_893
|
case yajuusenpai = 114_514_191_191_810_893
|
||||||
|
@ -172,6 +199,26 @@ class InputHandler: NSObject {
|
||||||
"<\(super.description) inputText:\(String(describing: inputText)), inputTextIgnoringModifiers:\(String(describing: inputTextIgnoringModifiers)) charCode:\(charCode), keyCode:\(keyCode), flags:\(flags), cursorForwardKey:\(cursorForwardKey), cursorBackwardKey:\(cursorBackwardKey), extraChooseCandidateKey:\(extraChooseCandidateKey), extraChooseCandidateKeyReverse:\(extraChooseCandidateKeyReverse), absorbedArrowKey:\(absorbedArrowKey), verticalModeOnlyChooseCandidateKey:\(verticalModeOnlyChooseCandidateKey), emacsKey:\(emacsKey), useVerticalMode:\(useVerticalMode)>"
|
"<\(super.description) inputText:\(String(describing: inputText)), inputTextIgnoringModifiers:\(String(describing: inputTextIgnoringModifiers)) charCode:\(charCode), keyCode:\(keyCode), flags:\(flags), cursorForwardKey:\(cursorForwardKey), cursorBackwardKey:\(cursorBackwardKey), extraChooseCandidateKey:\(extraChooseCandidateKey), extraChooseCandidateKeyReverse:\(extraChooseCandidateKeyReverse), absorbedArrowKey:\(absorbedArrowKey), verticalModeOnlyChooseCandidateKey:\(verticalModeOnlyChooseCandidateKey), emacsKey:\(emacsKey), useVerticalMode:\(useVerticalMode)>"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 除了 ANSI charCode 以外,其餘一律過濾掉,免得純 Swift 版 KeyHandler 被餵屎。
|
||||||
|
var isInvalidInput: Bool {
|
||||||
|
switch charCode {
|
||||||
|
case 0x20...0xFF: // ANSI charCode 範圍
|
||||||
|
return false
|
||||||
|
default:
|
||||||
|
if isReservedKey, !isKeyCodeBlacklisted {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var isKeyCodeBlacklisted: Bool {
|
||||||
|
guard let code = KeyCodeBlackListed(rawValue: keyCode) else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return code.rawValue != KeyCode.kNone.rawValue
|
||||||
|
}
|
||||||
|
|
||||||
var isShiftHold: Bool {
|
var isShiftHold: Bool {
|
||||||
flags.contains([.shift])
|
flags.contains([.shift])
|
||||||
}
|
}
|
||||||
|
@ -269,7 +316,7 @@ class InputHandler: NSObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
var isDelete: Bool {
|
var isDelete: Bool {
|
||||||
KeyCode(rawValue: keyCode) == KeyCode.kWindowDelete
|
KeyCode(rawValue: keyCode) == KeyCode.kWindowsDelete
|
||||||
}
|
}
|
||||||
|
|
||||||
var isCursorBackward: Bool {
|
var isCursorBackward: Bool {
|
||||||
|
|
|
@ -115,12 +115,12 @@ class KeyHandler: NSObject {
|
||||||
// MARK: - Functions dealing with Megrez.
|
// MARK: - Functions dealing with Megrez.
|
||||||
|
|
||||||
func walk() {
|
func walk() {
|
||||||
// Retrieve the most likely trellis, i.e. a Maximum Likelihood Estimation
|
// Retrieve the most likely grid, i.e. a Maximum Likelihood Estimation
|
||||||
// of the best possible Mandarin characters given the input syllables,
|
// of the best possible Mandarin characters given the input syllables,
|
||||||
// using the Viterbi algorithm implemented in the Gramambular library
|
// using the Viterbi algorithm implemented in the Megrez library
|
||||||
let walker = Megrez.Walker(grid: _builder.grid())
|
let walker = Megrez.Walker(grid: _builder.grid())
|
||||||
|
|
||||||
// the reverse walk traces the trellis from the end
|
// the reverse walk traces the grid from the end
|
||||||
let walked: [Megrez.NodeAnchor] = walker.reverseWalk(at: _builder.grid().width())
|
let walked: [Megrez.NodeAnchor] = walker.reverseWalk(at: _builder.grid().width())
|
||||||
|
|
||||||
// then we use ".reversed()" to reverse the nodes so that we get the forward-walked nodes
|
// then we use ".reversed()" to reverse the nodes so that we get the forward-walked nodes
|
||||||
|
|
|
@ -46,6 +46,14 @@ extension KeyHandler {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 提前過濾掉一些不合規的按鍵訊號輸入,免得相關按鍵訊號被送給 Megrez 引發輸入法崩潰。
|
||||||
|
if input.isInvalidInput {
|
||||||
|
IME.prtDebugIntel("550BCF7B: KeyHandler just refused an invalid input.")
|
||||||
|
errorCallback()
|
||||||
|
stateCallback(state)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Ignore the input if the composing buffer is empty with no reading
|
// Ignore the input if the composing buffer is empty with no reading
|
||||||
// and there is some function key combination.
|
// and there is some function key combination.
|
||||||
let isFunctionKey: Bool =
|
let isFunctionKey: Bool =
|
||||||
|
@ -56,7 +64,7 @@ extension KeyHandler {
|
||||||
|
|
||||||
// MARK: Caps Lock processing.
|
// MARK: Caps Lock processing.
|
||||||
|
|
||||||
// If Caps Lock is ON, temporarily disable bopomofo.
|
// If Caps Lock is ON, temporarily disable phonetic reading.
|
||||||
// Note: Alphanumerical mode processing.
|
// Note: Alphanumerical mode processing.
|
||||||
if input.isBackSpace || input.isEnter || input.isAbsorbedArrowKey || input.isExtraChooseCandidateKey
|
if input.isBackSpace || input.isEnter || input.isAbsorbedArrowKey || input.isExtraChooseCandidateKey
|
||||||
|| input.isExtraChooseCandidateKeyReverse || input.isCursorForward || input.isCursorBackward
|
|| input.isExtraChooseCandidateKeyReverse || input.isCursorForward || input.isCursorBackward
|
||||||
|
@ -135,23 +143,26 @@ extension KeyHandler {
|
||||||
|
|
||||||
// MARK: Handle BPMF Keys.
|
// MARK: Handle BPMF Keys.
|
||||||
|
|
||||||
var composeReading = false
|
var keyConsumedByReading = false
|
||||||
let skipPhoneticHandling = input.isReservedKey || input.isControlHold || input.isOptionHold
|
let skipPhoneticHandling = input.isReservedKey || input.isControlHold || input.isOptionHold
|
||||||
|
|
||||||
// See if Phonetic reading is valid.
|
// See if Phonetic reading is valid.
|
||||||
if !skipPhoneticHandling && Composer.chkKeyValidity(charCode) {
|
if !skipPhoneticHandling && Composer.chkKeyValidity(charCode) {
|
||||||
Composer.combineReadingKey(charCode)
|
Composer.combineReadingKey(charCode)
|
||||||
|
keyConsumedByReading = true
|
||||||
|
|
||||||
// If we have a tone marker, we have to insert the reading to the
|
// If we have a tone marker, we have to insert the reading to the
|
||||||
// builder in other words, if we don't have a tone marker, we just
|
// builder in other words, if we don't have a tone marker, we just
|
||||||
// update the composing buffer.
|
// update the composing buffer.
|
||||||
composeReading = Composer.checkWhetherToneMarkerConfirms()
|
let composeReading = Composer.hasToneMarker()
|
||||||
if !composeReading {
|
if !composeReading {
|
||||||
stateCallback(buildInputtingState())
|
stateCallback(buildInputtingState())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var composeReading = Composer.hasToneMarker() || Composer.hasToneMarkerOnly()
|
||||||
|
|
||||||
// See if we have composition if Enter/Space is hit and buffer is not empty.
|
// See if we have composition if Enter/Space is hit and buffer is not empty.
|
||||||
// We use "|=" conditioning so that the tone marker key is also taken into account.
|
// We use "|=" conditioning so that the tone marker key is also taken into account.
|
||||||
// However, Swift does not support "|=".
|
// However, Swift does not support "|=".
|
||||||
|
@ -159,17 +170,19 @@ extension KeyHandler {
|
||||||
if composeReading {
|
if composeReading {
|
||||||
let reading = Composer.getSyllableComposition()
|
let reading = Composer.getSyllableComposition()
|
||||||
|
|
||||||
|
// See whether we have a unigram for this...
|
||||||
if !ifLangModelHasUnigrams(forKey: reading) {
|
if !ifLangModelHasUnigrams(forKey: reading) {
|
||||||
IME.prtDebugIntel("B49C0979:語彙庫內無「\(reading)」的匹配記錄。")
|
IME.prtDebugIntel("B49C0979:語彙庫內無「\(reading)」的匹配記錄。")
|
||||||
errorCallback()
|
errorCallback()
|
||||||
stateCallback(buildInputtingState())
|
Composer.clearBuffer()
|
||||||
|
stateCallback((getBuilderLength() == 0) ? InputState.EmptyIgnoringPreviousState() : buildInputtingState())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... and insert it into the lattice grid...
|
// ... and insert it into the grid...
|
||||||
insertReadingToBuilderAtCursor(reading: reading)
|
insertReadingToBuilderAtCursor(reading: reading)
|
||||||
|
|
||||||
// ... then walk the lattice grid...
|
// ... then walk the grid...
|
||||||
let poppedText = popOverflowComposingTextAndWalk()
|
let poppedText = popOverflowComposingTextAndWalk()
|
||||||
|
|
||||||
// ... get and tweak override model suggestion if possible...
|
// ... get and tweak override model suggestion if possible...
|
||||||
|
@ -210,6 +223,16 @@ extension KeyHandler {
|
||||||
stateCallback(choosingCandidates)
|
stateCallback(choosingCandidates)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true // Telling the client that the key is consumed.
|
||||||
|
}
|
||||||
|
|
||||||
|
// The only possibility for this to be true is that the Phonetic reading
|
||||||
|
// already has a tone marker but the last key is *not* a tone marker key. An
|
||||||
|
// example is the sequence "6u" with the Standard layout, which produces "ㄧˊ"
|
||||||
|
// but does not compose. Only sequences such as "ㄧˊ", "ˊㄧˊ", "ˊㄧˇ", or "ˊㄧ "
|
||||||
|
// would compose.
|
||||||
|
if keyConsumedByReading {
|
||||||
|
stateCallback(buildInputtingState())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,7 +341,9 @@ extension KeyHandler {
|
||||||
|
|
||||||
if input.isEnter {
|
if input.isEnter {
|
||||||
return (input.isCommandHold && input.isControlHold)
|
return (input.isCommandHold && input.isControlHold)
|
||||||
? handleCtrlCommandEnter(state: state, stateCallback: stateCallback, errorCallback: errorCallback)
|
? (input.isOptionHold
|
||||||
|
? handleCtrlOptionCommandEnter(state: state, stateCallback: stateCallback, errorCallback: errorCallback)
|
||||||
|
: handleCtrlCommandEnter(state: state, stateCallback: stateCallback, errorCallback: errorCallback))
|
||||||
: handleEnter(state: state, stateCallback: stateCallback, errorCallback: errorCallback)
|
: handleEnter(state: state, stateCallback: stateCallback, errorCallback: errorCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -268,7 +268,7 @@ extension KeyHandler {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - CMD+Enter 鍵處理
|
// MARK: - CMD+Enter 鍵處理(注音文)
|
||||||
|
|
||||||
func handleCtrlCommandEnter(
|
func handleCtrlCommandEnter(
|
||||||
state: InputState,
|
state: InputState,
|
||||||
|
@ -292,6 +292,38 @@ extension KeyHandler {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - CMD+Alt+Enter 鍵處理(網頁 Ruby 注音文標記)
|
||||||
|
|
||||||
|
func handleCtrlOptionCommandEnter(
|
||||||
|
state: InputState,
|
||||||
|
stateCallback: @escaping (InputState) -> Void,
|
||||||
|
errorCallback _: @escaping () -> Void
|
||||||
|
) -> Bool {
|
||||||
|
if !(state is InputState.Inputting) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var composed = ""
|
||||||
|
|
||||||
|
for theAnchor in _walkedNodes {
|
||||||
|
if let node = theAnchor.node {
|
||||||
|
let key = node.currentKeyValue().key.replacingOccurrences(of: "-", with: " ")
|
||||||
|
let value = node.currentKeyValue().value
|
||||||
|
if key.contains("_") { // 不要給標點符號等特殊元素加注音
|
||||||
|
composed += value
|
||||||
|
} else {
|
||||||
|
composed += "<ruby>\(value)<rp>(</rp><rt>\(key)</rt><rp>)</rp></ruby>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clear()
|
||||||
|
|
||||||
|
stateCallback(InputState.Committing(poppedText: composed))
|
||||||
|
stateCallback(InputState.Empty())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - 處理 Backspace (macOS Delete) 按鍵行為
|
// MARK: - 處理 Backspace (macOS Delete) 按鍵行為
|
||||||
|
|
||||||
func handleBackspace(
|
func handleBackspace(
|
||||||
|
@ -303,7 +335,9 @@ extension KeyHandler {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if Composer.isBufferEmpty() {
|
if Composer.hasToneMarkerOnly() {
|
||||||
|
Composer.clearBuffer()
|
||||||
|
} else if Composer.isBufferEmpty() {
|
||||||
if getBuilderCursorIndex() >= 0 {
|
if getBuilderCursorIndex() >= 0 {
|
||||||
deleteBuilderReadingInFrontOfCursor()
|
deleteBuilderReadingInFrontOfCursor()
|
||||||
walk()
|
walk()
|
||||||
|
@ -462,7 +496,7 @@ extension KeyHandler {
|
||||||
if !Composer.isBufferEmpty() {
|
if !Composer.isBufferEmpty() {
|
||||||
Composer.clearBuffer()
|
Composer.clearBuffer()
|
||||||
if getBuilderLength() == 0 {
|
if getBuilderLength() == 0 {
|
||||||
stateCallback(InputState.Empty())
|
stateCallback(InputState.EmptyIgnoringPreviousState())
|
||||||
} else {
|
} else {
|
||||||
stateCallback(buildInputtingState())
|
stateCallback(buildInputtingState())
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class IME: NSObject {
|
||||||
|
|
||||||
static func prtDebugIntel(_ strPrint: String) {
|
static func prtDebugIntel(_ strPrint: String) {
|
||||||
if mgrPrefs.isDebugModeEnabled {
|
if mgrPrefs.isDebugModeEnabled {
|
||||||
NSLog("vChewingErrorCallback: %@", strPrint)
|
NSLog("vChewingDebug: %@", strPrint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,14 +64,12 @@ public class IME: NSObject {
|
||||||
// MARK: - Initializing Language Models.
|
// MARK: - Initializing Language Models.
|
||||||
|
|
||||||
static func initLangModels(userOnly: Bool) {
|
static func initLangModels(userOnly: Bool) {
|
||||||
DispatchQueue.global(qos: .userInitiated).async {
|
// mgrLangModel 的 loadUserPhrases 等函數在自動讀取 dataFolderPath 時,
|
||||||
// mgrLangModel 的 loadUserPhrases 等函數在自動讀取 dataFolderPath 時,
|
// 如果發現自訂目錄不可用,則會自動抹去自訂目錄設定、改採預設目錄。
|
||||||
// 如果發現自訂目錄不可用,則會自動抹去自訂目錄設定、改採預設目錄。
|
// 所以這裡不需要特別處理。
|
||||||
// 所以這裡不需要特別處理。
|
mgrLangModel.loadUserAssociatesData()
|
||||||
mgrLangModel.loadUserAssociatedPhrases()
|
mgrLangModel.loadUserPhraseReplacement()
|
||||||
mgrLangModel.loadUserPhraseReplacement()
|
mgrLangModel.loadUserPhrasesData()
|
||||||
mgrLangModel.loadUserPhrases()
|
|
||||||
}
|
|
||||||
if !userOnly {
|
if !userOnly {
|
||||||
// mgrLangModel.loadDataModels()
|
// mgrLangModel.loadDataModels()
|
||||||
}
|
}
|
||||||
|
|
|
@ -407,10 +407,19 @@ extension ctlInputMethod {
|
||||||
candidates.sort {
|
candidates.sort {
|
||||||
$0.count > $1.count
|
$0.count > $1.count
|
||||||
}
|
}
|
||||||
// If there is a candidate which is too long, we use the vertical
|
if let candidateFirst = candidates.first {
|
||||||
// candidate list window automatically.
|
// If there is a candidate which is too long, we use the vertical
|
||||||
if candidates.first?.count ?? 0 > 8 {
|
// candidate list window automatically.
|
||||||
// return true // 禁用這一項。威注音回頭會換候選窗格。
|
if candidateFirst.count > 8 {
|
||||||
|
// return true // 禁用這一項。威注音回頭會換候選窗格。
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果是顏文字選單的話,則強行使用縱排候選字窗。
|
||||||
|
// 有些顏文字會比較長,所以這裡用 for 判斷。
|
||||||
|
for candidate in candidates {
|
||||||
|
if ["顏文字", "颜文字"].contains(candidate), mgrPrefs.symbolInputEnabled {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -135,7 +135,7 @@ extension ctlInputMethod {
|
||||||
if optionKeyPressed || !mgrPrefs.shouldAutoReloadUserDataFiles {
|
if optionKeyPressed || !mgrPrefs.shouldAutoReloadUserDataFiles {
|
||||||
menu.addItem(
|
menu.addItem(
|
||||||
withTitle: NSLocalizedString("Reload User Phrases", comment: ""),
|
withTitle: NSLocalizedString("Reload User Phrases", comment: ""),
|
||||||
action: #selector(reloadUserPhrases(_:)), keyEquivalent: ""
|
action: #selector(reloadUserPhrasesData(_:)), keyEquivalent: ""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +346,7 @@ extension ctlInputMethod {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func reloadUserPhrases(_: Any?) {
|
@objc func reloadUserPhrasesData(_: Any?) {
|
||||||
IME.initLangModels(userOnly: true)
|
IME.initLangModels(userOnly: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,12 @@ import Foundation
|
||||||
|
|
||||||
// 簡體中文模式與繁體中文模式共用全字庫擴展模組,故單獨處理。
|
// 簡體中文模式與繁體中文模式共用全字庫擴展模組,故單獨處理。
|
||||||
// 塞在 LMInstantiator 內的話,每個模式都會讀入一份全字庫,會多佔用 100MB 記憶體。
|
// 塞在 LMInstantiator 內的話,每個模式都會讀入一份全字庫,會多佔用 100MB 記憶體。
|
||||||
private var lmCNS = vChewing.LMLite(consolidate: false)
|
private var lmCNS = vChewing.LMCoreEX(
|
||||||
private var lmSymbols = vChewing.LMCore(reverse: true, consolidate: false, defaultScore: -13.0, forceDefaultScore: true)
|
reverse: true, consolidate: false, defaultScore: -11.0, forceDefaultScore: false
|
||||||
|
)
|
||||||
|
private var lmSymbols = vChewing.LMCoreEX(
|
||||||
|
reverse: true, consolidate: false, defaultScore: -13.0, forceDefaultScore: false
|
||||||
|
)
|
||||||
|
|
||||||
extension vChewing {
|
extension vChewing {
|
||||||
/// LMInstantiator is a facade for managing a set of models including
|
/// LMInstantiator is a facade for managing a set of models including
|
||||||
|
@ -62,26 +66,35 @@ extension vChewing {
|
||||||
public var isCNSEnabled = false
|
public var isCNSEnabled = false
|
||||||
public var isSymbolEnabled = false
|
public var isSymbolEnabled = false
|
||||||
|
|
||||||
/// 介紹一下三個通用的語言模組型別:
|
/// 介紹一下幾個通用的語言模組型別:
|
||||||
/// LMCore 是全功能通用型的模組,每一筆辭典記錄以 key 為注音、以 [Unigram] 陣列作為記錄內容。
|
/// ----------------------
|
||||||
|
/// LMCoreEX 是全功能通用型的模組,每一筆辭典記錄以 key 為注音、以 [Unigram] 陣列作為記錄內容。
|
||||||
/// 比較適合那種每筆記錄都有不同的權重數值的語言模組,雖然也可以強制施加權重數值就是了。
|
/// 比較適合那種每筆記錄都有不同的權重數值的語言模組,雖然也可以強制施加權重數值就是了。
|
||||||
/// 然而缺點是:哪怕你強制施加權重數值,也不會減輕記憶體佔用。
|
/// LMCoreEX 的辭典陣列不承載 Unigram 本體、而是承載索引範圍,這樣可以節約記憶體。
|
||||||
/// 至於像全字庫這樣所有記錄都使用同一權重數值的模組,可以用 LMLite 以節省記憶體佔用。
|
/// 一個 LMCoreEX 就可以滿足威注音幾乎所有語言模組副本的需求,當然也有這兩個例外:
|
||||||
/// LMLite 的辭典內不會存儲權重資料,只會在每次讀取記錄時施加您給定的權重數值。
|
/// LMReplacements 與 LMAssociates 分別擔當語彙置換表資料與使用者聯想詞的資料承載工作。
|
||||||
/// LMLite 與 LMCore 都會用到多執行緒、以加速載入(不然的話,全部資料載入會耗費八秒左右)。
|
|
||||||
/// LMReplacements 與 LMAssociates 均為特種模組,分別擔當語彙置換表資料與使用者聯想詞的資料承載工作。
|
|
||||||
|
|
||||||
// 聲明原廠語言模組
|
// 聲明原廠語言模組
|
||||||
/// Reverse 的話,第一欄是注音,第二欄是對應的漢字,第三欄是可能的權重。
|
/// Reverse 的話,第一欄是注音,第二欄是對應的漢字,第三欄是可能的權重。
|
||||||
/// 不 Reverse 的話,第一欄是漢字,第二欄是對應的注音,第三欄是可能的權重。
|
/// 不 Reverse 的話,第一欄是漢字,第二欄是對應的注音,第三欄是可能的權重。
|
||||||
var lmCore = LMCore(reverse: false, consolidate: false, defaultScore: -9.5, forceDefaultScore: false)
|
var lmCore = LMCoreEX(
|
||||||
var lmMisc = LMCore(reverse: true, consolidate: false, defaultScore: -1, forceDefaultScore: false)
|
reverse: false, consolidate: false, defaultScore: -9.9, forceDefaultScore: false
|
||||||
|
)
|
||||||
|
var lmMisc = LMCoreEX(
|
||||||
|
reverse: true, consolidate: false, defaultScore: -1.0, forceDefaultScore: false
|
||||||
|
)
|
||||||
|
|
||||||
// 聲明使用者語言模組。
|
// 聲明使用者語言模組。
|
||||||
// 使用者語言模組使用多執行緒的話,可能會導致一些問題。有時間再仔細排查看看。
|
// 使用者語言模組使用多執行緒的話,可能會導致一些問題。有時間再仔細排查看看。
|
||||||
var lmUserPhrases = LMLite(consolidate: true)
|
var lmUserPhrases = LMCoreEX(
|
||||||
var lmFiltered = LMLite(consolidate: true)
|
reverse: true, consolidate: true, defaultScore: 0, forceDefaultScore: true
|
||||||
var lmUserSymbols = LMLite(consolidate: true)
|
)
|
||||||
|
var lmFiltered = LMCoreEX(
|
||||||
|
reverse: true, consolidate: true, defaultScore: 0, forceDefaultScore: true
|
||||||
|
)
|
||||||
|
var lmUserSymbols = LMCoreEX(
|
||||||
|
reverse: true, consolidate: true, defaultScore: -12.0, forceDefaultScore: true
|
||||||
|
)
|
||||||
var lmReplacements = LMReplacments()
|
var lmReplacements = LMReplacments()
|
||||||
var lmAssociates = LMAssociates()
|
var lmAssociates = LMAssociates()
|
||||||
|
|
||||||
|
@ -90,7 +103,7 @@ extension vChewing {
|
||||||
|
|
||||||
// 以下這些函數命名暫時保持原樣,等弒神行動徹底結束了再調整。
|
// 以下這些函數命名暫時保持原樣,等弒神行動徹底結束了再調整。
|
||||||
|
|
||||||
public func isDataModelLoaded() -> Bool { lmCore.isLoaded() }
|
public func isLanguageModelLoaded() -> Bool { lmCore.isLoaded() }
|
||||||
public func loadLanguageModel(path: String) {
|
public func loadLanguageModel(path: String) {
|
||||||
if FileManager.default.isReadableFile(atPath: path) {
|
if FileManager.default.isReadableFile(atPath: path) {
|
||||||
lmCore.open(path)
|
lmCore.open(path)
|
||||||
|
@ -130,7 +143,7 @@ extension vChewing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func loadUserPhrases(path: String, filterPath: String) {
|
public func loadUserPhrasesData(path: String, filterPath: String) {
|
||||||
if FileManager.default.isReadableFile(atPath: path) {
|
if FileManager.default.isReadableFile(atPath: path) {
|
||||||
lmUserPhrases.close()
|
lmUserPhrases.close()
|
||||||
lmUserPhrases.open(path)
|
lmUserPhrases.open(path)
|
||||||
|
@ -157,7 +170,7 @@ extension vChewing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func loadUserAssociatedPhrases(path: String) {
|
public func loadUserAssociatesData(path: String) {
|
||||||
if FileManager.default.isReadableFile(atPath: path) {
|
if FileManager.default.isReadableFile(atPath: path) {
|
||||||
lmAssociates.close()
|
lmAssociates.close()
|
||||||
lmAssociates.open(path)
|
lmAssociates.open(path)
|
||||||
|
@ -167,7 +180,7 @@ extension vChewing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func loadPhraseReplacementMap(path: String) {
|
public func loadReplacementsData(path: String) {
|
||||||
if FileManager.default.isReadableFile(atPath: path) {
|
if FileManager.default.isReadableFile(atPath: path) {
|
||||||
lmReplacements.close()
|
lmReplacements.close()
|
||||||
lmReplacements.open(path)
|
lmReplacements.open(path)
|
||||||
|
@ -201,7 +214,7 @@ extension vChewing {
|
||||||
// 用 reversed 指令讓使用者語彙檔案內的詞條優先順序隨著行數增加而逐漸增高。
|
// 用 reversed 指令讓使用者語彙檔案內的詞條優先順序隨著行數增加而逐漸增高。
|
||||||
// 這樣一來就可以在就地新增語彙時徹底複寫優先權。
|
// 這樣一來就可以在就地新增語彙時徹底複寫優先權。
|
||||||
// 將兩句差分也是為了讓 rawUserUnigrams 的類型不受可能的影響。
|
// 將兩句差分也是為了讓 rawUserUnigrams 的類型不受可能的影響。
|
||||||
rawAllUnigrams += lmUserPhrases.unigramsFor(key: key, score: 0.0).reversed()
|
rawAllUnigrams += lmUserPhrases.unigramsFor(key: key).reversed()
|
||||||
if lmUserPhrases.unigramsFor(key: key).isEmpty {
|
if lmUserPhrases.unigramsFor(key: key).isEmpty {
|
||||||
IME.prtDebugIntel("Not found in UserPhrasesUnigram(\(lmUserPhrases.count)): \(key)")
|
IME.prtDebugIntel("Not found in UserPhrasesUnigram(\(lmUserPhrases.count)): \(key)")
|
||||||
}
|
}
|
||||||
|
@ -211,11 +224,11 @@ extension vChewing {
|
||||||
rawAllUnigrams += lmCore.unigramsFor(key: key)
|
rawAllUnigrams += lmCore.unigramsFor(key: key)
|
||||||
|
|
||||||
if isCNSEnabled {
|
if isCNSEnabled {
|
||||||
rawAllUnigrams += lmCNS.unigramsFor(key: key, score: -11)
|
rawAllUnigrams += lmCNS.unigramsFor(key: key)
|
||||||
}
|
}
|
||||||
|
|
||||||
if isSymbolEnabled {
|
if isSymbolEnabled {
|
||||||
rawAllUnigrams += lmUserSymbols.unigramsFor(key: key, score: -12.0)
|
rawAllUnigrams += lmUserSymbols.unigramsFor(key: key)
|
||||||
if lmUserSymbols.unigramsFor(key: key).isEmpty {
|
if lmUserSymbols.unigramsFor(key: key).isEmpty {
|
||||||
IME.prtDebugIntel("Not found in UserSymbolUnigram(\(lmUserSymbols.count)): \(key)")
|
IME.prtDebugIntel("Not found in UserSymbolUnigram(\(lmUserSymbols.count)): \(key)")
|
||||||
}
|
}
|
||||||
|
@ -232,15 +245,6 @@ extension vChewing {
|
||||||
filteredPairs.insert(unigram.keyValue)
|
filteredPairs.insert(unigram.keyValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
var debugOutput = "\n"
|
|
||||||
for neta in rawAllUnigrams {
|
|
||||||
debugOutput += "RAW: \(neta.keyValue.key) \(neta.keyValue.value) \(neta.score)\n"
|
|
||||||
}
|
|
||||||
if debugOutput == "\n" {
|
|
||||||
debugOutput = "RAW: No match found in all unigrams."
|
|
||||||
}
|
|
||||||
IME.prtDebugIntel(debugOutput)
|
|
||||||
|
|
||||||
return filterAndTransform(
|
return filterAndTransform(
|
||||||
unigrams: rawAllUnigrams,
|
unigrams: rawAllUnigrams,
|
||||||
filter: filteredPairs, inserted: &insertedPairs
|
filter: filteredPairs, inserted: &insertedPairs
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||||
// Refactored from the ObjCpp-version of this class by:
|
// StringView Ranges extension by (c) 2022 and onwards Isaac Xen (MIT License).
|
||||||
// (c) 2011 and onwards The OpenVanilla Project (MIT License).
|
|
||||||
/*
|
/*
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -28,18 +27,19 @@ import Foundation
|
||||||
|
|
||||||
extension vChewing {
|
extension vChewing {
|
||||||
@frozen public struct LMAssociates {
|
@frozen public struct LMAssociates {
|
||||||
var keyValueMap: [String: [Megrez.KeyValuePair]] = [:]
|
var rangeMap: [String: [Range<String.Index>]] = [:]
|
||||||
|
var strData: String = ""
|
||||||
|
|
||||||
public var count: Int {
|
public var count: Int {
|
||||||
keyValueMap.count
|
rangeMap.count
|
||||||
}
|
}
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
keyValueMap = [:]
|
rangeMap = [:]
|
||||||
}
|
}
|
||||||
|
|
||||||
public func isLoaded() -> Bool {
|
public func isLoaded() -> Bool {
|
||||||
!keyValueMap.isEmpty
|
!rangeMap.isEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult public mutating func open(_ path: String) -> Bool {
|
@discardableResult public mutating func open(_ path: String) -> Bool {
|
||||||
|
@ -50,53 +50,40 @@ extension vChewing {
|
||||||
LMConsolidator.fixEOF(path: path)
|
LMConsolidator.fixEOF(path: path)
|
||||||
LMConsolidator.consolidate(path: path, pragma: true)
|
LMConsolidator.consolidate(path: path, pragma: true)
|
||||||
|
|
||||||
var arrData: [String] = []
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
arrData = try String(contentsOfFile: path, encoding: .utf8).components(separatedBy: "\n")
|
strData = try String(contentsOfFile: path, encoding: .utf8).replacingOccurrences(of: "\t", with: " ")
|
||||||
|
strData.ranges(splitBy: "\n").forEach {
|
||||||
|
let neta = strData[$0].components(separatedBy: " ")
|
||||||
|
if neta.count >= 2 {
|
||||||
|
let theKey = neta[0]
|
||||||
|
if !neta[0].isEmpty, !neta[1].isEmpty, theKey.first != "#" {
|
||||||
|
let theValue = $0
|
||||||
|
rangeMap[theKey, default: []].append(theValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
IME.prtDebugIntel("\(error)")
|
IME.prtDebugIntel("\(error)")
|
||||||
IME.prtDebugIntel("↑ Exception happened when reading Associated Phrases data.")
|
IME.prtDebugIntel("↑ Exception happened when reading data at: \(path).")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
for (lineID, lineContent) in arrData.enumerated() {
|
|
||||||
if !lineContent.hasPrefix("#") {
|
|
||||||
let lineContent = lineContent.replacingOccurrences(of: "\t", with: " ")
|
|
||||||
if lineContent.components(separatedBy: " ").count < 2 {
|
|
||||||
if lineContent != "", lineContent != " " {
|
|
||||||
IME.prtDebugIntel("Line #\(lineID + 1) Wrecked: \(lineContent)")
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var currentKV = Megrez.KeyValuePair()
|
|
||||||
for (unitID, unitContent) in lineContent.components(separatedBy: " ").enumerated() {
|
|
||||||
switch unitID {
|
|
||||||
case 0:
|
|
||||||
currentKV.key = unitContent
|
|
||||||
case 1:
|
|
||||||
currentKV.value = unitContent
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
keyValueMap[currentKV.key, default: []].append(currentKV)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func close() {
|
public mutating func close() {
|
||||||
if isLoaded() {
|
if isLoaded() {
|
||||||
keyValueMap.removeAll()
|
rangeMap.removeAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func dump() {
|
public func dump() {
|
||||||
var strDump = ""
|
var strDump = ""
|
||||||
for entry in keyValueMap {
|
for entry in rangeMap {
|
||||||
let rows: [Megrez.KeyValuePair] = entry.value
|
let netaRanges: [Range<String.Index>] = entry.value
|
||||||
for row in rows {
|
for netaRange in netaRanges {
|
||||||
let addline = row.key + " " + row.value + "\n"
|
let neta = strData[netaRange]
|
||||||
|
let addline = neta + "\n"
|
||||||
strDump += addline
|
strDump += addline
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,17 +91,33 @@ extension vChewing {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func valuesFor(key: String) -> [String]? {
|
public func valuesFor(key: String) -> [String]? {
|
||||||
var v: [String] = []
|
var pairs: [String] = []
|
||||||
if let matched = keyValueMap[key] {
|
if let arrRangeRecords: [Range<String.Index>] = rangeMap[key] {
|
||||||
for entry in matched as [Megrez.KeyValuePair] {
|
for netaRange in arrRangeRecords {
|
||||||
v.append(entry.value)
|
let neta = strData[netaRange].components(separatedBy: " ")
|
||||||
|
let theValue: String = neta[1]
|
||||||
|
pairs.append(theValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v
|
return pairs
|
||||||
}
|
}
|
||||||
|
|
||||||
public func hasValuesFor(key: String) -> Bool {
|
public func hasValuesFor(key: String) -> Bool {
|
||||||
keyValueMap[key] != nil
|
rangeMap[key] != nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - StringView Ranges Extension (by Isaac Xen)
|
||||||
|
|
||||||
|
extension String {
|
||||||
|
fileprivate func ranges(splitBy separator: Element) -> [Range<String.Index>] {
|
||||||
|
var startIndex = startIndex
|
||||||
|
return split(separator: separator).reduce(into: []) { ranges, substring in
|
||||||
|
_ = range(of: substring, range: startIndex..<endIndex).map { range in
|
||||||
|
ranges.append(range)
|
||||||
|
startIndex = range.upperBound
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||||
|
// StringView Ranges extension by (c) 2022 and onwards Isaac Xen (MIT License).
|
||||||
/*
|
/*
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -22,27 +23,31 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// 威注音重新設計原廠詞庫語言模組。不排序,但使用 Swift 內建的 String 處理。
|
/// 與之前的 LMCore 不同,LMCoreEX 不在辭典內記錄實體,而是記錄 range 範圍。
|
||||||
|
/// 需要資料的時候,直接拿 range 去 strData 取資料。
|
||||||
|
/// 資料記錄原理與上游 C++ 的 ParselessLM 差不多,但用的是 Swift 原生手段。
|
||||||
|
/// 主要時間消耗仍在 For 迴圈,但這個算法可以顯著減少記憶體佔用。
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension vChewing {
|
extension vChewing {
|
||||||
@frozen public struct LMCore {
|
@frozen public struct LMCoreEX {
|
||||||
var keyValueScoreMap: [String: [Megrez.Unigram]] = [:]
|
var rangeMap: [String: [Range<String.Index>]] = [:]
|
||||||
|
var strData: String = ""
|
||||||
var shouldReverse: Bool = false
|
var shouldReverse: Bool = false
|
||||||
var allowConsolidation: Bool = false
|
var allowConsolidation: Bool = false
|
||||||
var defaultScore: Double = 0
|
var defaultScore: Double = 0
|
||||||
var shouldForceDefaultScore: Bool = false
|
var shouldForceDefaultScore: Bool = false
|
||||||
|
|
||||||
public var count: Int {
|
public var count: Int {
|
||||||
keyValueScoreMap.count
|
rangeMap.count
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
reverse: Bool = false, consolidate: Bool = false, defaultScore scoreDefault: Double = 0,
|
reverse: Bool = false, consolidate: Bool = false, defaultScore scoreDefault: Double = 0,
|
||||||
forceDefaultScore: Bool = false
|
forceDefaultScore: Bool = false
|
||||||
) {
|
) {
|
||||||
keyValueScoreMap = [:]
|
rangeMap = [:]
|
||||||
allowConsolidation = consolidate
|
allowConsolidation = consolidate
|
||||||
shouldReverse = reverse
|
shouldReverse = reverse
|
||||||
defaultScore = scoreDefault
|
defaultScore = scoreDefault
|
||||||
|
@ -50,7 +55,7 @@ extension vChewing {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func isLoaded() -> Bool {
|
public func isLoaded() -> Bool {
|
||||||
!keyValueScoreMap.isEmpty
|
!rangeMap.isEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult public mutating func open(_ path: String) -> Bool {
|
@discardableResult public mutating func open(_ path: String) -> Bool {
|
||||||
|
@ -63,64 +68,30 @@ extension vChewing {
|
||||||
LMConsolidator.consolidate(path: path, pragma: true)
|
LMConsolidator.consolidate(path: path, pragma: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
var arrData: [String] = []
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
arrData = try String(contentsOfFile: path, encoding: .utf8).components(separatedBy: "\n")
|
strData = try String(contentsOfFile: path, encoding: .utf8).replacingOccurrences(of: "\t", with: " ")
|
||||||
|
strData.ranges(splitBy: "\n").forEach {
|
||||||
|
let neta = strData[$0].components(separatedBy: " ")
|
||||||
|
if neta.count >= 2 {
|
||||||
|
let theKey = shouldReverse ? neta[1] : neta[0]
|
||||||
|
if !neta[0].isEmpty, !neta[1].isEmpty, theKey.first != "#" {
|
||||||
|
let theValue = $0
|
||||||
|
rangeMap[theKey, default: []].append(theValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
IME.prtDebugIntel("\(error)")
|
IME.prtDebugIntel("\(error)")
|
||||||
IME.prtDebugIntel("↑ Exception happened when reading Associated Phrases data.")
|
IME.prtDebugIntel("↑ Exception happened when reading data at: \(path).")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
for (lineID, lineContent) in arrData.enumerated() {
|
|
||||||
if !lineContent.hasPrefix("#") {
|
|
||||||
let lineContent = lineContent.replacingOccurrences(of: "\t", with: " ")
|
|
||||||
if lineContent.components(separatedBy: " ").count < 2 {
|
|
||||||
if lineContent != "", lineContent != " " {
|
|
||||||
IME.prtDebugIntel("Line #\(lineID + 1) Wrecked: \(lineContent)")
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var currentUnigram = Megrez.Unigram(keyValue: Megrez.KeyValuePair(), score: defaultScore)
|
|
||||||
var columnOne = ""
|
|
||||||
var columnTwo = ""
|
|
||||||
for (unitID, unitContent) in lineContent.components(separatedBy: " ").enumerated() {
|
|
||||||
switch unitID {
|
|
||||||
case 0:
|
|
||||||
columnOne = unitContent
|
|
||||||
case 1:
|
|
||||||
columnTwo = unitContent
|
|
||||||
case 2:
|
|
||||||
if !shouldForceDefaultScore {
|
|
||||||
if let unitContentConverted = Double(unitContent) {
|
|
||||||
currentUnigram.score = unitContentConverted
|
|
||||||
} else {
|
|
||||||
IME.prtDebugIntel("Line #\(lineID) Score Data Wrecked: \(lineContent)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 標點符號的頻率最好鎖定一下。
|
|
||||||
if columnOne.contains("_punctuation_") {
|
|
||||||
currentUnigram.score -= (Double(lineID) * 0.000001)
|
|
||||||
}
|
|
||||||
let kvPair =
|
|
||||||
shouldReverse
|
|
||||||
? Megrez.KeyValuePair(key: columnTwo, value: columnOne)
|
|
||||||
: Megrez.KeyValuePair(key: columnOne, value: columnTwo)
|
|
||||||
currentUnigram.keyValue = kvPair
|
|
||||||
let key = shouldReverse ? columnTwo : columnOne
|
|
||||||
keyValueScoreMap[key, default: []].append(currentUnigram)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func close() {
|
public mutating func close() {
|
||||||
if isLoaded() {
|
if isLoaded() {
|
||||||
keyValueScoreMap.removeAll()
|
rangeMap.removeAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,10 +99,11 @@ extension vChewing {
|
||||||
|
|
||||||
public func dump() {
|
public func dump() {
|
||||||
var strDump = ""
|
var strDump = ""
|
||||||
for entry in keyValueScoreMap {
|
for entry in rangeMap {
|
||||||
let rows: [Megrez.Unigram] = entry.value
|
let netaRanges: [Range<String.Index>] = entry.value
|
||||||
for row in rows {
|
for netaRange in netaRanges {
|
||||||
let addline = row.keyValue.key + " " + row.keyValue.value + " " + String(row.score) + "\n"
|
let neta = strData[netaRange]
|
||||||
|
let addline = neta + "\n"
|
||||||
strDump += addline
|
strDump += addline
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,11 +117,41 @@ extension vChewing {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func unigramsFor(key: String) -> [Megrez.Unigram] {
|
public func unigramsFor(key: String) -> [Megrez.Unigram] {
|
||||||
keyValueScoreMap[key] ?? [Megrez.Unigram]()
|
var grams: [Megrez.Unigram] = []
|
||||||
|
if let arrRangeRecords: [Range<String.Index>] = rangeMap[key] {
|
||||||
|
for netaRange in arrRangeRecords {
|
||||||
|
let neta = strData[netaRange].components(separatedBy: " ")
|
||||||
|
let theValue: String = shouldReverse ? neta[0] : neta[1]
|
||||||
|
let kvPair = Megrez.KeyValuePair(key: key, value: theValue)
|
||||||
|
var theScore = defaultScore
|
||||||
|
if neta.count >= 3, !shouldForceDefaultScore {
|
||||||
|
theScore = .init(neta[2]) ?? defaultScore
|
||||||
|
}
|
||||||
|
if theScore > 0 {
|
||||||
|
theScore *= -1 // 應對可能忘記寫負號的情形
|
||||||
|
}
|
||||||
|
grams.append(Megrez.Unigram(keyValue: kvPair, score: theScore))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return grams
|
||||||
}
|
}
|
||||||
|
|
||||||
public func hasUnigramsFor(key: String) -> Bool {
|
public func hasUnigramsFor(key: String) -> Bool {
|
||||||
keyValueScoreMap[key] != nil
|
rangeMap[key] != nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - StringView Ranges Extension (by Isaac Xen)
|
||||||
|
|
||||||
|
extension String {
|
||||||
|
fileprivate func ranges(splitBy separator: Element) -> [Range<String.Index>] {
|
||||||
|
var startIndex = startIndex
|
||||||
|
return split(separator: separator).reduce(into: []) { ranges, substring in
|
||||||
|
_ = range(of: substring, range: startIndex..<endIndex).map { range in
|
||||||
|
ranges.append(range)
|
||||||
|
startIndex = range.upperBound
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,124 +0,0 @@
|
||||||
// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
|
||||||
// Refactored from the ObjCpp-version of this class by:
|
|
||||||
// (c) 2011 and onwards The OpenVanilla Project (MIT License).
|
|
||||||
/*
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
subject to the following conditions:
|
|
||||||
|
|
||||||
1. The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
2. No trademark license is granted to use the trade names, trademarks, service
|
|
||||||
marks, or product names of Contributor, except as required to fulfill notice
|
|
||||||
requirements above.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
extension vChewing {
|
|
||||||
@frozen public struct LMLite {
|
|
||||||
var keyValueMap: [String: [Megrez.KeyValuePair]] = [:]
|
|
||||||
var allowConsolidation = false
|
|
||||||
|
|
||||||
public var count: Int {
|
|
||||||
keyValueMap.count
|
|
||||||
}
|
|
||||||
|
|
||||||
public init(consolidate: Bool = false) {
|
|
||||||
keyValueMap = [:]
|
|
||||||
allowConsolidation = consolidate
|
|
||||||
}
|
|
||||||
|
|
||||||
public func isLoaded() -> Bool {
|
|
||||||
!keyValueMap.isEmpty
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult public mutating func open(_ path: String) -> Bool {
|
|
||||||
if isLoaded() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if allowConsolidation {
|
|
||||||
LMConsolidator.fixEOF(path: path)
|
|
||||||
LMConsolidator.consolidate(path: path, pragma: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
var arrData: [String] = []
|
|
||||||
|
|
||||||
do {
|
|
||||||
arrData = try String(contentsOfFile: path, encoding: .utf8).components(separatedBy: "\n")
|
|
||||||
} catch {
|
|
||||||
IME.prtDebugIntel("\(error)")
|
|
||||||
IME.prtDebugIntel("↑ Exception happened when reading Associated Phrases data.")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for (lineID, lineContent) in arrData.enumerated() {
|
|
||||||
if !lineContent.hasPrefix("#") {
|
|
||||||
let lineContent = lineContent.replacingOccurrences(of: "\t", with: " ")
|
|
||||||
if lineContent.components(separatedBy: " ").count < 2 {
|
|
||||||
if lineContent != "", lineContent != " " {
|
|
||||||
IME.prtDebugIntel("Line #\(lineID + 1) Wrecked: \(lineContent)")
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var currentKV = Megrez.KeyValuePair()
|
|
||||||
for (unitID, unitContent) in lineContent.components(separatedBy: " ").enumerated() {
|
|
||||||
switch unitID {
|
|
||||||
case 0:
|
|
||||||
currentKV.value = unitContent
|
|
||||||
case 1:
|
|
||||||
currentKV.key = unitContent
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
keyValueMap[currentKV.key, default: []].append(currentKV)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
public mutating func close() {
|
|
||||||
if isLoaded() {
|
|
||||||
keyValueMap.removeAll()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func dump() {
|
|
||||||
var strDump = ""
|
|
||||||
for entry in keyValueMap {
|
|
||||||
let rows: [Megrez.KeyValuePair] = entry.value
|
|
||||||
for row in rows {
|
|
||||||
let addline = row.key + " " + row.value + "\n"
|
|
||||||
strDump += addline
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IME.prtDebugIntel(strDump)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func unigramsFor(key: String, score givenScore: Double = 0.0) -> [Megrez.Unigram] {
|
|
||||||
var v: [Megrez.Unigram] = []
|
|
||||||
if let matched = keyValueMap[key] {
|
|
||||||
for entry in matched as [Megrez.KeyValuePair] {
|
|
||||||
v.append(Megrez.Unigram(keyValue: entry, score: givenScore))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
public func hasUnigramsFor(key: String) -> Bool {
|
|
||||||
keyValueMap[key] != nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,5 @@
|
||||||
// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||||
// Refactored from the ObjCpp-version of this class by:
|
// StringView Ranges extension by (c) 2022 and onwards Isaac Xen (MIT License).
|
||||||
// (c) 2011 and onwards The OpenVanilla Project (MIT License).
|
|
||||||
/*
|
/*
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -28,18 +27,19 @@ import Foundation
|
||||||
|
|
||||||
extension vChewing {
|
extension vChewing {
|
||||||
@frozen public struct LMReplacments {
|
@frozen public struct LMReplacments {
|
||||||
var keyValueMap: [String: String] = [:]
|
var rangeMap: [String: Range<String.Index>] = [:]
|
||||||
|
var strData: String = ""
|
||||||
|
|
||||||
public var count: Int {
|
public var count: Int {
|
||||||
keyValueMap.count
|
rangeMap.count
|
||||||
}
|
}
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
keyValueMap = [:]
|
rangeMap = [:]
|
||||||
}
|
}
|
||||||
|
|
||||||
public func isLoaded() -> Bool {
|
public func isLoaded() -> Bool {
|
||||||
!keyValueMap.isEmpty
|
!rangeMap.isEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult public mutating func open(_ path: String) -> Bool {
|
@discardableResult public mutating func open(_ path: String) -> Bool {
|
||||||
|
@ -50,58 +50,68 @@ extension vChewing {
|
||||||
LMConsolidator.fixEOF(path: path)
|
LMConsolidator.fixEOF(path: path)
|
||||||
LMConsolidator.consolidate(path: path, pragma: true)
|
LMConsolidator.consolidate(path: path, pragma: true)
|
||||||
|
|
||||||
var arrData: [String] = []
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
arrData = try String(contentsOfFile: path, encoding: .utf8).components(separatedBy: "\n")
|
strData = try String(contentsOfFile: path, encoding: .utf8).replacingOccurrences(of: "\t", with: " ")
|
||||||
|
strData.ranges(splitBy: "\n").forEach {
|
||||||
|
let neta = strData[$0].components(separatedBy: " ")
|
||||||
|
if neta.count >= 2 {
|
||||||
|
let theKey = neta[0]
|
||||||
|
if !neta[0].isEmpty, !neta[1].isEmpty, theKey.first != "#" {
|
||||||
|
let theValue = $0
|
||||||
|
rangeMap[theKey] = theValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
IME.prtDebugIntel("\(error)")
|
IME.prtDebugIntel("\(error)")
|
||||||
IME.prtDebugIntel("↑ Exception happened when reading Associated Phrases data.")
|
IME.prtDebugIntel("↑ Exception happened when reading data at: \(path).")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
for (lineID, lineContent) in arrData.enumerated() {
|
|
||||||
if !lineContent.hasPrefix("#") {
|
|
||||||
let lineContent = lineContent.replacingOccurrences(of: "\t", with: " ")
|
|
||||||
if lineContent.components(separatedBy: " ").count < 2 {
|
|
||||||
if lineContent != "", lineContent != " " {
|
|
||||||
IME.prtDebugIntel("Line #\(lineID + 1) Wrecked: \(lineContent)")
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var currentKV = Megrez.KeyValuePair()
|
|
||||||
for (unitID, unitContent) in lineContent.components(separatedBy: " ").enumerated() {
|
|
||||||
switch unitID {
|
|
||||||
case 0:
|
|
||||||
currentKV.key = unitContent
|
|
||||||
case 1:
|
|
||||||
currentKV.value = unitContent
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
keyValueMap[currentKV.key] = currentKV.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func close() {
|
public mutating func close() {
|
||||||
if isLoaded() {
|
if isLoaded() {
|
||||||
keyValueMap.removeAll()
|
rangeMap.removeAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func dump() {
|
public func dump() {
|
||||||
var strDump = ""
|
var strDump = ""
|
||||||
for entry in keyValueMap {
|
for entry in rangeMap {
|
||||||
strDump += entry.key + " " + entry.value + "\n"
|
strDump += strData[entry.value] + "\n"
|
||||||
}
|
}
|
||||||
IME.prtDebugIntel(strDump)
|
IME.prtDebugIntel(strDump)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func valuesFor(key: String) -> String {
|
public func valuesFor(key: String) -> String {
|
||||||
keyValueMap[key] ?? ""
|
guard let range = rangeMap[key] else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
let arrNeta = strData[range].components(separatedBy: " ")
|
||||||
|
guard arrNeta.count >= 2 else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return String(arrNeta[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
public func hasValuesFor(key: String) -> Bool {
|
||||||
|
rangeMap[key] != nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - StringView Ranges Extension (by Isaac Xen)
|
||||||
|
|
||||||
|
extension String {
|
||||||
|
fileprivate func ranges(splitBy separator: Element) -> [Range<String.Index>] {
|
||||||
|
var startIndex = startIndex
|
||||||
|
return split(separator: separator).reduce(into: []) { ranges, substring in
|
||||||
|
_ = range(of: substring, range: startIndex..<endIndex).map { range in
|
||||||
|
ranges.append(range)
|
||||||
|
startIndex = range.upperBound
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,27 +51,25 @@ class mgrLangModel: NSObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func loadDataModels() {
|
public static func loadDataModels() {
|
||||||
DispatchQueue.global(qos: .userInitiated).async {
|
if !gLangModelCHT.isCNSDataLoaded() {
|
||||||
if !gLangModelCHT.isCNSDataLoaded() {
|
gLangModelCHT.loadCNSData(path: getBundleDataPath("char-kanji-cns"))
|
||||||
gLangModelCHT.loadCNSData(path: getBundleDataPath("char-kanji-cns"))
|
|
||||||
}
|
|
||||||
if !gLangModelCHT.isMiscDataLoaded() {
|
|
||||||
gLangModelCHT.loadMiscData(path: getBundleDataPath("data-zhuyinwen"))
|
|
||||||
}
|
|
||||||
if !gLangModelCHT.isSymbolDataLoaded() {
|
|
||||||
gLangModelCHT.loadSymbolData(path: getBundleDataPath("data-symbols"))
|
|
||||||
}
|
|
||||||
if !gLangModelCHS.isCNSDataLoaded() {
|
|
||||||
gLangModelCHS.loadCNSData(path: getBundleDataPath("char-kanji-cns"))
|
|
||||||
}
|
|
||||||
if !gLangModelCHS.isMiscDataLoaded() {
|
|
||||||
gLangModelCHS.loadMiscData(path: getBundleDataPath("data-zhuyinwen"))
|
|
||||||
}
|
|
||||||
if !gLangModelCHS.isSymbolDataLoaded() {
|
|
||||||
gLangModelCHS.loadSymbolData(path: getBundleDataPath("data-symbols"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if !gLangModelCHT.isDataModelLoaded() {
|
if !gLangModelCHT.isMiscDataLoaded() {
|
||||||
|
gLangModelCHT.loadMiscData(path: getBundleDataPath("data-zhuyinwen"))
|
||||||
|
}
|
||||||
|
if !gLangModelCHT.isSymbolDataLoaded() {
|
||||||
|
gLangModelCHT.loadSymbolData(path: getBundleDataPath("data-symbols"))
|
||||||
|
}
|
||||||
|
if !gLangModelCHS.isCNSDataLoaded() {
|
||||||
|
gLangModelCHS.loadCNSData(path: getBundleDataPath("char-kanji-cns"))
|
||||||
|
}
|
||||||
|
if !gLangModelCHS.isMiscDataLoaded() {
|
||||||
|
gLangModelCHS.loadMiscData(path: getBundleDataPath("data-zhuyinwen"))
|
||||||
|
}
|
||||||
|
if !gLangModelCHS.isSymbolDataLoaded() {
|
||||||
|
gLangModelCHS.loadSymbolData(path: getBundleDataPath("data-symbols"))
|
||||||
|
}
|
||||||
|
if !gLangModelCHT.isLanguageModelLoaded() {
|
||||||
NotifierController.notify(
|
NotifierController.notify(
|
||||||
message: String(
|
message: String(
|
||||||
format: "%@", NSLocalizedString("Loading CHT Core Dict...", comment: "")
|
format: "%@", NSLocalizedString("Loading CHT Core Dict...", comment: "")
|
||||||
|
@ -84,7 +82,7 @@ class mgrLangModel: NSObject {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if !gLangModelCHS.isDataModelLoaded() {
|
if !gLangModelCHS.isLanguageModelLoaded() {
|
||||||
NotifierController.notify(
|
NotifierController.notify(
|
||||||
message: String(
|
message: String(
|
||||||
format: "%@", NSLocalizedString("Loading CHS Core Dict...", comment: "")
|
format: "%@", NSLocalizedString("Loading CHS Core Dict...", comment: "")
|
||||||
|
@ -101,18 +99,16 @@ class mgrLangModel: NSObject {
|
||||||
|
|
||||||
public static func loadDataModel(_ mode: InputMode) {
|
public static func loadDataModel(_ mode: InputMode) {
|
||||||
if mode == InputMode.imeModeCHS {
|
if mode == InputMode.imeModeCHS {
|
||||||
DispatchQueue.global(qos: .userInitiated).async {
|
if !gLangModelCHS.isMiscDataLoaded() {
|
||||||
if !gLangModelCHS.isMiscDataLoaded() {
|
gLangModelCHS.loadMiscData(path: getBundleDataPath("data-zhuyinwen"))
|
||||||
gLangModelCHS.loadMiscData(path: getBundleDataPath("data-zhuyinwen"))
|
|
||||||
}
|
|
||||||
if !gLangModelCHS.isSymbolDataLoaded() {
|
|
||||||
gLangModelCHS.loadSymbolData(path: getBundleDataPath("data-symbols"))
|
|
||||||
}
|
|
||||||
if !gLangModelCHS.isCNSDataLoaded() {
|
|
||||||
gLangModelCHS.loadCNSData(path: getBundleDataPath("char-kanji-cns"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if !gLangModelCHS.isDataModelLoaded() {
|
if !gLangModelCHS.isSymbolDataLoaded() {
|
||||||
|
gLangModelCHS.loadSymbolData(path: getBundleDataPath("data-symbols"))
|
||||||
|
}
|
||||||
|
if !gLangModelCHS.isCNSDataLoaded() {
|
||||||
|
gLangModelCHS.loadCNSData(path: getBundleDataPath("char-kanji-cns"))
|
||||||
|
}
|
||||||
|
if !gLangModelCHS.isLanguageModelLoaded() {
|
||||||
NotifierController.notify(
|
NotifierController.notify(
|
||||||
message: String(
|
message: String(
|
||||||
format: "%@", NSLocalizedString("Loading CHS Core Dict...", comment: "")
|
format: "%@", NSLocalizedString("Loading CHS Core Dict...", comment: "")
|
||||||
|
@ -126,18 +122,16 @@ class mgrLangModel: NSObject {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if mode == InputMode.imeModeCHT {
|
} else if mode == InputMode.imeModeCHT {
|
||||||
DispatchQueue.global(qos: .userInitiated).async {
|
if !gLangModelCHT.isMiscDataLoaded() {
|
||||||
if !gLangModelCHT.isMiscDataLoaded() {
|
gLangModelCHT.loadMiscData(path: getBundleDataPath("data-zhuyinwen"))
|
||||||
gLangModelCHT.loadMiscData(path: getBundleDataPath("data-zhuyinwen"))
|
|
||||||
}
|
|
||||||
if !gLangModelCHT.isSymbolDataLoaded() {
|
|
||||||
gLangModelCHT.loadSymbolData(path: getBundleDataPath("data-symbols"))
|
|
||||||
}
|
|
||||||
if !gLangModelCHT.isCNSDataLoaded() {
|
|
||||||
gLangModelCHT.loadCNSData(path: getBundleDataPath("char-kanji-cns"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if !gLangModelCHT.isDataModelLoaded() {
|
if !gLangModelCHT.isSymbolDataLoaded() {
|
||||||
|
gLangModelCHT.loadSymbolData(path: getBundleDataPath("data-symbols"))
|
||||||
|
}
|
||||||
|
if !gLangModelCHT.isCNSDataLoaded() {
|
||||||
|
gLangModelCHT.loadCNSData(path: getBundleDataPath("char-kanji-cns"))
|
||||||
|
}
|
||||||
|
if !gLangModelCHT.isLanguageModelLoaded() {
|
||||||
NotifierController.notify(
|
NotifierController.notify(
|
||||||
message: String(
|
message: String(
|
||||||
format: "%@", NSLocalizedString("Loading CHT Core Dict...", comment: "")
|
format: "%@", NSLocalizedString("Loading CHT Core Dict...", comment: "")
|
||||||
|
@ -153,12 +147,12 @@ class mgrLangModel: NSObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func loadUserPhrases() {
|
public static func loadUserPhrasesData() {
|
||||||
gLangModelCHT.loadUserPhrases(
|
gLangModelCHT.loadUserPhrasesData(
|
||||||
path: userPhrasesDataPath(InputMode.imeModeCHT),
|
path: userPhrasesDataPath(InputMode.imeModeCHT),
|
||||||
filterPath: excludedPhrasesDataPath(InputMode.imeModeCHT)
|
filterPath: excludedPhrasesDataPath(InputMode.imeModeCHT)
|
||||||
)
|
)
|
||||||
gLangModelCHS.loadUserPhrases(
|
gLangModelCHS.loadUserPhrasesData(
|
||||||
path: userPhrasesDataPath(InputMode.imeModeCHS),
|
path: userPhrasesDataPath(InputMode.imeModeCHS),
|
||||||
filterPath: excludedPhrasesDataPath(InputMode.imeModeCHS)
|
filterPath: excludedPhrasesDataPath(InputMode.imeModeCHS)
|
||||||
)
|
)
|
||||||
|
@ -166,20 +160,20 @@ class mgrLangModel: NSObject {
|
||||||
gLangModelCHS.loadUserSymbolData(path: userSymbolDataPath(InputMode.imeModeCHS))
|
gLangModelCHS.loadUserSymbolData(path: userSymbolDataPath(InputMode.imeModeCHS))
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func loadUserAssociatedPhrases() {
|
public static func loadUserAssociatesData() {
|
||||||
gLangModelCHT.loadUserAssociatedPhrases(
|
gLangModelCHT.loadUserAssociatesData(
|
||||||
path: mgrLangModel.userAssociatedPhrasesDataPath(InputMode.imeModeCHT)
|
path: mgrLangModel.userAssociatedPhrasesDataPath(InputMode.imeModeCHT)
|
||||||
)
|
)
|
||||||
gLangModelCHS.loadUserAssociatedPhrases(
|
gLangModelCHS.loadUserAssociatesData(
|
||||||
path: mgrLangModel.userAssociatedPhrasesDataPath(InputMode.imeModeCHS)
|
path: mgrLangModel.userAssociatedPhrasesDataPath(InputMode.imeModeCHS)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func loadUserPhraseReplacement() {
|
public static func loadUserPhraseReplacement() {
|
||||||
gLangModelCHT.loadPhraseReplacementMap(
|
gLangModelCHT.loadReplacementsData(
|
||||||
path: mgrLangModel.phraseReplacementDataPath(InputMode.imeModeCHT)
|
path: mgrLangModel.phraseReplacementDataPath(InputMode.imeModeCHT)
|
||||||
)
|
)
|
||||||
gLangModelCHS.loadPhraseReplacementMap(
|
gLangModelCHS.loadReplacementsData(
|
||||||
path: mgrLangModel.phraseReplacementDataPath(InputMode.imeModeCHS)
|
path: mgrLangModel.phraseReplacementDataPath(InputMode.imeModeCHS)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -430,7 +424,7 @@ class mgrLangModel: NSObject {
|
||||||
// We use FSEventStream to monitor possible changes of the user phrase folder, hence the
|
// We use FSEventStream to monitor possible changes of the user phrase folder, hence the
|
||||||
// lack of the needs of manually load data here unless FSEventStream is disabled by user.
|
// lack of the needs of manually load data here unless FSEventStream is disabled by user.
|
||||||
if !mgrPrefs.shouldAutoReloadUserDataFiles {
|
if !mgrPrefs.shouldAutoReloadUserDataFiles {
|
||||||
loadUserPhrases()
|
loadUserPhrasesData()
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,6 +116,7 @@ struct suiPrefPaneDictionary: View {
|
||||||
Toggle(LocalizedStringKey("Enable CNS11643 Support (2022-01-27)"), isOn: $selEnableCNS11643)
|
Toggle(LocalizedStringKey("Enable CNS11643 Support (2022-01-27)"), isOn: $selEnableCNS11643)
|
||||||
.onChange(of: selEnableCNS11643) { value in
|
.onChange(of: selEnableCNS11643) { value in
|
||||||
mgrPrefs.cns11643Enabled = value
|
mgrPrefs.cns11643Enabled = value
|
||||||
|
mgrLangModel.setCNSEnabled(value)
|
||||||
}
|
}
|
||||||
Toggle(
|
Toggle(
|
||||||
LocalizedStringKey("Enable symbol input support (incl. certain emoji symbols)"),
|
LocalizedStringKey("Enable symbol input support (incl. certain emoji symbols)"),
|
||||||
|
@ -123,6 +124,7 @@ struct suiPrefPaneDictionary: View {
|
||||||
)
|
)
|
||||||
.onChange(of: selEnableSymbolInputSupport) { value in
|
.onChange(of: selEnableSymbolInputSupport) { value in
|
||||||
mgrPrefs.symbolInputEnabled = value
|
mgrPrefs.symbolInputEnabled = value
|
||||||
|
mgrLangModel.setSymbolEnabled(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="20037" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="19529" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="19529"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="20037"/>
|
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
|
@ -58,7 +57,7 @@
|
||||||
<textFieldCell key="cell" selectable="YES" id="lblCredits">
|
<textFieldCell key="cell" selectable="YES" id="lblCredits">
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
<string key="title">McBopomofo Engine by Mengjuei Hsieh, Lukhnos Liu, Zonble Yang, et al.
|
<string key="title">McBopomofo Engine by Mengjuei Hsieh, Lukhnos Liu, Zonble Yang, et al.
|
||||||
vChewing macOS Development: Shiki Suen, Hiraku Wang, etc.
|
vChewing macOS Development: Shiki Suen, Isaac Xen, Hiraku Wang, etc.
|
||||||
vChewing Phrase Database Maintained by Shiki Suen.</string>
|
vChewing Phrase Database Maintained by Shiki Suen.</string>
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -125,7 +124,7 @@ DQ
|
||||||
<rect key="frame" x="91" y="143" width="427" height="183"/>
|
<rect key="frame" x="91" y="143" width="427" height="183"/>
|
||||||
<clipView key="contentView" drawsBackground="NO" id="35U-hd-B9v">
|
<clipView key="contentView" drawsBackground="NO" id="35U-hd-B9v">
|
||||||
<rect key="frame" x="1" y="1" width="425" height="181"/>
|
<rect key="frame" x="1" y="1" width="425" height="181"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textView editable="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" smartInsertDelete="YES" id="cEu-uC-XnV" userLabel="appEULAContent">
|
<textView editable="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" smartInsertDelete="YES" id="cEu-uC-XnV" userLabel="appEULAContent">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="425" height="181"/>
|
<rect key="frame" x="0.0" y="0.0" width="425" height="181"/>
|
||||||
|
|
|
@ -23,5 +23,5 @@
|
||||||
/* Class = "NSTextFieldCell"; title = "© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project."; ObjectID = "lblCopyright"; */
|
/* Class = "NSTextFieldCell"; title = "© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project."; ObjectID = "lblCopyright"; */
|
||||||
// "lblCopyright.title" = "© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project.";
|
// "lblCopyright.title" = "© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project.";
|
||||||
|
|
||||||
/* Class = "NSTextFieldCell"; title = "Mandarin Syllable Composer Engine by Lukhnos Liu.\nInput State Management Architecture by Zonble Yang.\nvChewing macOS Development: Shiki Suen, Hiraku Wang, etc.\nvChewing Phrase Database Maintained by Shiki Suen.\nMegrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine."; ObjectID = "lblCredits"; */
|
/* Class = "NSTextFieldCell"; title = "Mandarin Syllable Composer Engine by Lukhnos Liu.\nInput State Management Architecture by Zonble Yang.\nvChewing macOS Development: Shiki Suen, Isaac Xen, Hiraku Wang, etc.\nvChewing Phrase Database Maintained by Shiki Suen.\nMegrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine."; ObjectID = "lblCredits"; */
|
||||||
"lblCredits.title" = "Mandarin Syllable Composer Engine by Lukhnos Liu.\nInput State Management Architecture by Zonble Yang.\nvChewing macOS Development: Shiki Suen, Hiraku Wang, etc.\nvChewing Phrase Database Maintained by Shiki Suen.\nMegrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine.";
|
"lblCredits.title" = "Mandarin Syllable Composer Engine by Lukhnos Liu.\nInput State Management Architecture by Zonble Yang.\nvChewing macOS Development: Shiki Suen, Isaac Xen, Hiraku Wang, etc.\nvChewing Phrase Database Maintained by Shiki Suen.\nMegrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine.";
|
||||||
|
|
|
@ -23,5 +23,5 @@
|
||||||
/* Class = "NSTextFieldCell"; title = "© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project."; ObjectID = "lblCopyright"; */
|
/* Class = "NSTextFieldCell"; title = "© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project."; ObjectID = "lblCopyright"; */
|
||||||
// "lblCopyright.title" = "© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project.";
|
// "lblCopyright.title" = "© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project.";
|
||||||
|
|
||||||
/* Class = "NSTextFieldCell"; title = "Mandarin Syllable Composer Engine by Lukhnos Liu.\nInput State Management Architecture by Zonble Yang.\nvChewing macOS Development: Shiki Suen, Hiraku Wang, etc.\nvChewing Phrase Database Maintained by Shiki Suen.\nMegrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine."; ObjectID = "lblCredits"; */
|
/* Class = "NSTextFieldCell"; title = "Mandarin Syllable Composer Engine by Lukhnos Liu.\nInput State Management Architecture by Zonble Yang.\nvChewing macOS Development: Shiki Suen, Isaac Xen, Hiraku Wang, etc.\nvChewing Phrase Database Maintained by Shiki Suen.\nMegrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine."; ObjectID = "lblCredits"; */
|
||||||
"lblCredits.title" = "ボポモフォエンジン開発:Lukhnos Liu。\n入力状態管理システム開発:Zonble Yang。\nmacOS 版威注音の開発:Shiki Suen, Hiraku Wang, など。\n威注音語彙データの維持:Shiki Suen。\nMegrez 辞書処理エンジン:Shiki Suen(Lukhnos の Gramambular C++ エンジンを Swift で再開発したものである)。";
|
"lblCredits.title" = "ボポモフォエンジン開発:Lukhnos Liu。\n入力状態管理システム開発:Zonble Yang。\nmacOS 版威注音の開発:Shiki Suen, Isaac Xen, Hiraku Wang, など。\n威注音語彙データの維持:Shiki Suen。\nMegrez 辞書処理エンジン:Shiki Suen(Lukhnos の Gramambular C++ エンジンを Swift で再開発したものである)。";
|
||||||
|
|
|
@ -23,5 +23,5 @@
|
||||||
/* Class = "NSTextFieldCell"; title = "© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project."; ObjectID = "lblCopyright"; */
|
/* Class = "NSTextFieldCell"; title = "© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project."; ObjectID = "lblCopyright"; */
|
||||||
// "lblCopyright.title" = "© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project.";
|
// "lblCopyright.title" = "© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project.";
|
||||||
|
|
||||||
/* Class = "NSTextFieldCell"; title = "Mandarin Syllable Composer Engine by Lukhnos Liu.\nInput State Management Architecture by Zonble Yang.\nvChewing macOS Development: Shiki Suen, Hiraku Wang, etc.\nvChewing Phrase Database Maintained by Shiki Suen.\nMegrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine."; ObjectID = "lblCredits"; */
|
/* Class = "NSTextFieldCell"; title = "Mandarin Syllable Composer Engine by Lukhnos Liu.\nInput State Management Architecture by Zonble Yang.\nvChewing macOS Development: Shiki Suen, Isaac Xen, Hiraku Wang, etc.\nvChewing Phrase Database Maintained by Shiki Suen.\nMegrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine."; ObjectID = "lblCredits"; */
|
||||||
"lblCredits.title" = "注音拼音输入处理引擎研发:Lukhnos Liu。\n输入法状态管理引擎研发:Zonble Yang。\n威注音 macOS 程式研发:Shiki Suen, Hiraku Wang, 等。\n威注音词库维护:Shiki Suen。\n天权星语汇引擎:Shiki Suen,用 Swift 将 Lukhnos 的 C++ Gramambular 重写而得。";
|
"lblCredits.title" = "注音拼音输入处理引擎研发:Lukhnos Liu。\n输入法状态管理引擎研发:Zonble Yang。\n威注音 macOS 程式研发:Shiki Suen, Isaac Xen, Hiraku Wang, 等。\n威注音词库维护:Shiki Suen。\n天权星语汇引擎:Shiki Suen,用 Swift 将 Lukhnos 的 C++ Gramambular 重写而得。";
|
||||||
|
|
|
@ -23,5 +23,5 @@
|
||||||
/* Class = "NSTextFieldCell"; title = "© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project."; ObjectID = "lblCopyright"; */
|
/* Class = "NSTextFieldCell"; title = "© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project."; ObjectID = "lblCopyright"; */
|
||||||
// "lblCopyright.title" = "© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project.";
|
// "lblCopyright.title" = "© 2011-2022 OpenVanilla Project & © 2021-2022 vChewing Project.";
|
||||||
|
|
||||||
/* Class = "NSTextFieldCell"; title = "Mandarin Syllable Composer Engine by Lukhnos Liu.\nInput State Management Architecture by Zonble Yang.\nvChewing macOS Development: Shiki Suen, Hiraku Wang, etc.\nvChewing Phrase Database Maintained by Shiki Suen.\nMegrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine."; ObjectID = "lblCredits"; */
|
/* Class = "NSTextFieldCell"; title = "Mandarin Syllable Composer Engine by Lukhnos Liu.\nInput State Management Architecture by Zonble Yang.\nvChewing macOS Development: Shiki Suen, Isaac Xen, Hiraku Wang, etc.\nvChewing Phrase Database Maintained by Shiki Suen.\nMegrez is a rewritten unigram engine by Shiki Suen using Swift, replacing Lukhnos' C++ Gramambular engine."; ObjectID = "lblCredits"; */
|
||||||
"lblCredits.title" = "注音拼音輸入處理引擎研發:Lukhnos Liu。\n輸入法狀態管理引擎研發:Zonble Yang。\n威注音 macOS 程式研發:Shiki Suen, Hiraku Wang, 等。\n威注音詞庫維護:Shiki Suen。\n天權星語彙引擎:Shiki Suen,用 Swift 將 Lukhnos 的 C++ Gramambular 重寫而得。";
|
"lblCredits.title" = "注音拼音輸入處理引擎研發:Lukhnos Liu。\n輸入法狀態管理引擎研發:Zonble Yang。\n威注音 macOS 程式研發:Shiki Suen, Isaac Xen, Hiraku Wang, 等。\n威注音詞庫維護:Shiki Suen。\n天權星語彙引擎:Shiki Suen,用 Swift 將 Lukhnos 的 C++ Gramambular 重寫而得。";
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.5.4</string>
|
<string>1.5.5</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1954</string>
|
<string>1955</string>
|
||||||
<key>UpdateInfoEndpoint</key>
|
<key>UpdateInfoEndpoint</key>
|
||||||
<string>https://gitee.com/vchewing/vChewing-macOS/raw/main/Update-Info.plist</string>
|
<string>https://gitee.com/vchewing/vChewing-macOS/raw/main/Update-Info.plist</string>
|
||||||
<key>UpdateInfoSite</key>
|
<key>UpdateInfoSite</key>
|
||||||
|
|
|
@ -726,7 +726,7 @@
|
||||||
<key>USE_HFS+_COMPRESSION</key>
|
<key>USE_HFS+_COMPRESSION</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>VERSION</key>
|
<key>VERSION</key>
|
||||||
<string>1.5.4</string>
|
<string>1.5.5</string>
|
||||||
</dict>
|
</dict>
|
||||||
<key>TYPE</key>
|
<key>TYPE</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
5B00A230282011980058E5DB /* lmLite.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B00A22F282011980058E5DB /* lmLite.swift */; };
|
|
||||||
5B0AF8B527B2C8290096FE54 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B0AF8B427B2C8290096FE54 /* StringExtension.swift */; };
|
5B0AF8B527B2C8290096FE54 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B0AF8B427B2C8290096FE54 /* StringExtension.swift */; };
|
||||||
5B11328927B94CFB00E58451 /* AppleKeyboardConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B11328827B94CFB00E58451 /* AppleKeyboardConverter.swift */; };
|
5B11328927B94CFB00E58451 /* AppleKeyboardConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B11328827B94CFB00E58451 /* AppleKeyboardConverter.swift */; };
|
||||||
5B27AD6A27CB1F9B000ED75B /* data-symbols.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5B27AD6827CB1F9B000ED75B /* data-symbols.txt */; };
|
5B27AD6A27CB1F9B000ED75B /* data-symbols.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5B27AD6827CB1F9B000ED75B /* data-symbols.txt */; };
|
||||||
|
@ -48,10 +47,10 @@
|
||||||
5B782EC4280C243C007276DE /* KeyHandler_HandleCandidate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B782EC3280C243C007276DE /* KeyHandler_HandleCandidate.swift */; };
|
5B782EC4280C243C007276DE /* KeyHandler_HandleCandidate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B782EC3280C243C007276DE /* KeyHandler_HandleCandidate.swift */; };
|
||||||
5B7BC4B027AFFBE800F66C24 /* frmPrefWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5B7BC4AE27AFFBE800F66C24 /* frmPrefWindow.xib */; };
|
5B7BC4B027AFFBE800F66C24 /* frmPrefWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5B7BC4AE27AFFBE800F66C24 /* frmPrefWindow.xib */; };
|
||||||
5B7F225D2808501000DDD3CB /* KeyHandler_HandleInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B7F225C2808501000DDD3CB /* KeyHandler_HandleInput.swift */; };
|
5B7F225D2808501000DDD3CB /* KeyHandler_HandleInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B7F225C2808501000DDD3CB /* KeyHandler_HandleInput.swift */; };
|
||||||
|
5B887F302826AEA400B6651E /* lmCoreEX.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B887F2F2826AEA400B6651E /* lmCoreEX.swift */; };
|
||||||
5B949BD92816DC5400D87B5D /* LineReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B949BD82816DC5400D87B5D /* LineReader.swift */; };
|
5B949BD92816DC5400D87B5D /* LineReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B949BD82816DC5400D87B5D /* LineReader.swift */; };
|
||||||
5B949BDB2816DDBC00D87B5D /* LMConsolidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B949BDA2816DDBC00D87B5D /* LMConsolidator.swift */; };
|
5B949BDB2816DDBC00D87B5D /* LMConsolidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B949BDA2816DDBC00D87B5D /* LMConsolidator.swift */; };
|
||||||
5BA0DF312817857D009E73BB /* lmUserOverride.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA0DF2E2817857D009E73BB /* lmUserOverride.swift */; };
|
5BA0DF312817857D009E73BB /* lmUserOverride.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA0DF2E2817857D009E73BB /* lmUserOverride.swift */; };
|
||||||
5BA0DF322817857D009E73BB /* lmCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA0DF2F2817857D009E73BB /* lmCore.swift */; };
|
|
||||||
5BA9FD0F27FEDB6B002DE248 /* suiPrefPaneGeneral.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA9FD0A27FEDB6B002DE248 /* suiPrefPaneGeneral.swift */; };
|
5BA9FD0F27FEDB6B002DE248 /* suiPrefPaneGeneral.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA9FD0A27FEDB6B002DE248 /* suiPrefPaneGeneral.swift */; };
|
||||||
5BA9FD1027FEDB6B002DE248 /* suiPrefPaneKeyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA9FD0B27FEDB6B002DE248 /* suiPrefPaneKeyboard.swift */; };
|
5BA9FD1027FEDB6B002DE248 /* suiPrefPaneKeyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA9FD0B27FEDB6B002DE248 /* suiPrefPaneKeyboard.swift */; };
|
||||||
5BA9FD1127FEDB6B002DE248 /* ctlPrefUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA9FD0C27FEDB6B002DE248 /* ctlPrefUI.swift */; };
|
5BA9FD1127FEDB6B002DE248 /* ctlPrefUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA9FD0C27FEDB6B002DE248 /* ctlPrefUI.swift */; };
|
||||||
|
@ -161,7 +160,6 @@
|
||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
5B00A22F282011980058E5DB /* lmLite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = lmLite.swift; sourceTree = "<group>"; usesTabs = 0; };
|
|
||||||
5B04305327B529D800CB65BC /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
5B04305327B529D800CB65BC /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
||||||
5B04305427B529D800CB65BC /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
5B04305427B529D800CB65BC /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||||
5B04305527B529D800CB65BC /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/MainMenu.strings"; sourceTree = "<group>"; };
|
5B04305527B529D800CB65BC /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/MainMenu.strings"; sourceTree = "<group>"; };
|
||||||
|
@ -225,10 +223,10 @@
|
||||||
5B7BC4AF27AFFBE800F66C24 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/frmPrefWindow.xib; sourceTree = "<group>"; };
|
5B7BC4AF27AFFBE800F66C24 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/frmPrefWindow.xib; sourceTree = "<group>"; };
|
||||||
5B7BC4B227AFFC0B00F66C24 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/frmPrefWindow.strings; sourceTree = "<group>"; };
|
5B7BC4B227AFFC0B00F66C24 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/frmPrefWindow.strings; sourceTree = "<group>"; };
|
||||||
5B7F225C2808501000DDD3CB /* KeyHandler_HandleInput.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = KeyHandler_HandleInput.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5B7F225C2808501000DDD3CB /* KeyHandler_HandleInput.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = KeyHandler_HandleInput.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||||
|
5B887F2F2826AEA400B6651E /* lmCoreEX.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = lmCoreEX.swift; sourceTree = "<group>"; usesTabs = 0; };
|
||||||
5B949BD82816DC5400D87B5D /* LineReader.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = LineReader.swift; sourceTree = "<group>"; usesTabs = 0; };
|
5B949BD82816DC5400D87B5D /* LineReader.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = LineReader.swift; sourceTree = "<group>"; usesTabs = 0; };
|
||||||
5B949BDA2816DDBC00D87B5D /* LMConsolidator.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = LMConsolidator.swift; sourceTree = "<group>"; usesTabs = 0; };
|
5B949BDA2816DDBC00D87B5D /* LMConsolidator.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = LMConsolidator.swift; sourceTree = "<group>"; usesTabs = 0; };
|
||||||
5BA0DF2E2817857D009E73BB /* lmUserOverride.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = lmUserOverride.swift; sourceTree = "<group>"; usesTabs = 0; };
|
5BA0DF2E2817857D009E73BB /* lmUserOverride.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = lmUserOverride.swift; sourceTree = "<group>"; usesTabs = 0; };
|
||||||
5BA0DF2F2817857D009E73BB /* lmCore.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = lmCore.swift; sourceTree = "<group>"; usesTabs = 0; };
|
|
||||||
5BA9FD0A27FEDB6B002DE248 /* suiPrefPaneGeneral.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = suiPrefPaneGeneral.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5BA9FD0A27FEDB6B002DE248 /* suiPrefPaneGeneral.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = suiPrefPaneGeneral.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||||
5BA9FD0B27FEDB6B002DE248 /* suiPrefPaneKeyboard.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = suiPrefPaneKeyboard.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5BA9FD0B27FEDB6B002DE248 /* suiPrefPaneKeyboard.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = suiPrefPaneKeyboard.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||||
5BA9FD0C27FEDB6B002DE248 /* ctlPrefUI.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlPrefUI.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5BA9FD0C27FEDB6B002DE248 /* ctlPrefUI.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlPrefUI.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||||
|
@ -393,8 +391,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
5B407309281672610023DFFF /* lmAssociates.swift */,
|
5B407309281672610023DFFF /* lmAssociates.swift */,
|
||||||
5BA0DF2F2817857D009E73BB /* lmCore.swift */,
|
5B887F2F2826AEA400B6651E /* lmCoreEX.swift */,
|
||||||
5B00A22F282011980058E5DB /* lmLite.swift */,
|
|
||||||
5B40730A281672610023DFFF /* lmReplacements.swift */,
|
5B40730A281672610023DFFF /* lmReplacements.swift */,
|
||||||
5BA0DF2E2817857D009E73BB /* lmUserOverride.swift */,
|
5BA0DF2E2817857D009E73BB /* lmUserOverride.swift */,
|
||||||
);
|
);
|
||||||
|
@ -1077,7 +1074,6 @@
|
||||||
5B707CE827D9F4590099EF99 /* OpenCCBridge.swift in Sources */,
|
5B707CE827D9F4590099EF99 /* OpenCCBridge.swift in Sources */,
|
||||||
D427F76C278CA2B0004A2160 /* AppDelegate.swift in Sources */,
|
D427F76C278CA2B0004A2160 /* AppDelegate.swift in Sources */,
|
||||||
5BA9FD4527FEF3C9002DE248 /* ToolbarItemStyleViewController.swift in Sources */,
|
5BA9FD4527FEF3C9002DE248 /* ToolbarItemStyleViewController.swift in Sources */,
|
||||||
5BA0DF322817857D009E73BB /* lmCore.swift in Sources */,
|
|
||||||
5BA9FD4127FEF3C8002DE248 /* PreferencesStyle.swift in Sources */,
|
5BA9FD4127FEF3C8002DE248 /* PreferencesStyle.swift in Sources */,
|
||||||
5B7F225D2808501000DDD3CB /* KeyHandler_HandleInput.swift in Sources */,
|
5B7F225D2808501000DDD3CB /* KeyHandler_HandleInput.swift in Sources */,
|
||||||
5BA9FD1227FEDB6B002DE248 /* suiPrefPaneExperience.swift in Sources */,
|
5BA9FD1227FEDB6B002DE248 /* suiPrefPaneExperience.swift in Sources */,
|
||||||
|
@ -1088,6 +1084,7 @@
|
||||||
5BA9FD4827FEF3C9002DE248 /* PreferencesWindowController.swift in Sources */,
|
5BA9FD4827FEF3C9002DE248 /* PreferencesWindowController.swift in Sources */,
|
||||||
5BD0113B28180D6100609769 /* LMInstantiator.swift in Sources */,
|
5BD0113B28180D6100609769 /* LMInstantiator.swift in Sources */,
|
||||||
D4E569DC27A34D0E00AC2CEF /* CTools.m in Sources */,
|
D4E569DC27A34D0E00AC2CEF /* CTools.m in Sources */,
|
||||||
|
5B887F302826AEA400B6651E /* lmCoreEX.swift in Sources */,
|
||||||
5BA9FD4627FEF3C9002DE248 /* Container.swift in Sources */,
|
5BA9FD4627FEF3C9002DE248 /* Container.swift in Sources */,
|
||||||
D47F7DD0278C0897002F9DD7 /* ctlNonModalAlertWindow.swift in Sources */,
|
D47F7DD0278C0897002F9DD7 /* ctlNonModalAlertWindow.swift in Sources */,
|
||||||
5B38F5A2281E2E49007D5F5D /* 0_Megrez.swift in Sources */,
|
5B38F5A2281E2E49007D5F5D /* 0_Megrez.swift in Sources */,
|
||||||
|
@ -1130,7 +1127,6 @@
|
||||||
5B62A34827AE7CD900A19448 /* ctlCandidateVertical.swift in Sources */,
|
5B62A34827AE7CD900A19448 /* ctlCandidateVertical.swift in Sources */,
|
||||||
5BA9FD4027FEF3C8002DE248 /* Localization.swift in Sources */,
|
5BA9FD4027FEF3C8002DE248 /* Localization.swift in Sources */,
|
||||||
5BA9FD1327FEDB6B002DE248 /* suiPrefPaneDictionary.swift in Sources */,
|
5BA9FD1327FEDB6B002DE248 /* suiPrefPaneDictionary.swift in Sources */,
|
||||||
5B00A230282011980058E5DB /* lmLite.swift in Sources */,
|
|
||||||
5BBBB77A27AEDC690023B93A /* clsSFX.swift in Sources */,
|
5BBBB77A27AEDC690023B93A /* clsSFX.swift in Sources */,
|
||||||
5BA9FD4727FEF3C9002DE248 /* PreferencesStyleController.swift in Sources */,
|
5BA9FD4727FEF3C9002DE248 /* PreferencesStyleController.swift in Sources */,
|
||||||
5BF8423127BAA942008E7E4C /* vChewingKanjiConverter.swift in Sources */,
|
5BF8423127BAA942008E7E4C /* vChewingKanjiConverter.swift in Sources */,
|
||||||
|
@ -1336,7 +1332,7 @@
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 1954;
|
CURRENT_PROJECT_VERSION = 1955;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
@ -1359,7 +1355,7 @@
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
||||||
MARKETING_VERSION = 1.5.4;
|
MARKETING_VERSION = 1.5.5;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor;
|
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor;
|
||||||
|
@ -1392,7 +1388,7 @@
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 1954;
|
CURRENT_PROJECT_VERSION = 1955;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
@ -1411,7 +1407,7 @@
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
||||||
MARKETING_VERSION = 1.5.4;
|
MARKETING_VERSION = 1.5.5;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor;
|
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor;
|
||||||
|
@ -1526,7 +1522,7 @@
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 1954;
|
CURRENT_PROJECT_VERSION = 1955;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
@ -1561,7 +1557,7 @@
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
||||||
MARKETING_VERSION = 1.5.4;
|
MARKETING_VERSION = 1.5.5;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing;
|
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
@ -1593,7 +1589,7 @@
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 1954;
|
CURRENT_PROJECT_VERSION = 1955;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
|
@ -1623,7 +1619,7 @@
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
||||||
MARKETING_VERSION = 1.5.4;
|
MARKETING_VERSION = 1.5.5;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing;
|
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
@ -1706,7 +1702,7 @@
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 1954;
|
CURRENT_PROJECT_VERSION = 1955;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
@ -1731,7 +1727,7 @@
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
||||||
MARKETING_VERSION = 1.5.4;
|
MARKETING_VERSION = 1.5.5;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "org.atelierInmu.vChewing.${PRODUCT_NAME:rfc1034identifier}";
|
PRODUCT_BUNDLE_IDENTIFIER = "org.atelierInmu.vChewing.${PRODUCT_NAME:rfc1034identifier}";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
@ -1758,7 +1754,7 @@
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 1954;
|
CURRENT_PROJECT_VERSION = 1955;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
@ -1778,7 +1774,7 @@
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
||||||
MARKETING_VERSION = 1.5.4;
|
MARKETING_VERSION = 1.5.5;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "org.atelierInmu.vChewing.${PRODUCT_NAME:rfc1034identifier}";
|
PRODUCT_BUNDLE_IDENTIFIER = "org.atelierInmu.vChewing.${PRODUCT_NAME:rfc1034identifier}";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
</Workspace>
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "1320"
|
||||||
|
version = "1.3">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES">
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
|
<Testables>
|
||||||
|
</Testables>
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
<PathRunnable
|
||||||
|
runnableDebuggingMode = "0"
|
||||||
|
BundleIdentifier = "org.atelierInmu.inputmethod.vChewing"
|
||||||
|
FilePath = "~/Library/Input Methods/vChewing.app">
|
||||||
|
</PathRunnable>
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
Loading…
Reference in New Issue