1.5.5 // RAM Optimization, etc. Merge Gitee PR!28 from upd/1.5.5

This commit is contained in:
ShikiSuen 2022-05-09 14:52:33 +00:00 committed by Gitee
commit afa2dd2feb
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
39 changed files with 502 additions and 436 deletions

16
AUTHORS
View File

@ -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.

View File

@ -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)

View File

@ -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>

View File

@ -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.";

View File

@ -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 SuenLukhnos の Gramambular C++ エンジンを Swift で再開発したものである)。"; "VW8-s5-Wpn.title" = "ボポモフォエンジン開発Lukhnos Liu。\n入力状態管理システム開発Zonble Yang。\nmacOS 版威注音の開発Shiki Suen, Isaac Xen, Hiraku Wang, など。\n威注音語彙データの維持Shiki Suen。\nMegrez 辞書処理エンジンShiki SuenLukhnos の 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.";

View File

@ -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.";

View File

@ -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.";

View File

@ -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 重写而得。

View File

@ -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 重寫而得。

View File

@ -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 SuenLukhnos の Gramambular C++ エンジンを Swift で再開発したものである)。 Megrez 辞書処理エンジンShiki SuenLukhnos の Gramambular C++ エンジンを Swift で再開発したものである)。

View File

@ -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.

View File

@ -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;

View File

@ -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()];

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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)
} }

View File

@ -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())
} }

View File

@ -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()
} }

View File

@ -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
}() }()

View File

@ -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)
} }

View File

@ -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

View File

@ -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
}
} }
} }
} }

View File

@ -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
}
} }
} }
} }

View File

@ -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
}
}
}

View File

@ -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
}
} }
} }
} }

View File

@ -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
} }

View File

@ -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)
} }
} }
} }

View File

@ -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"/>

View File

@ -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.";

View File

@ -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 SuenLukhnos の Gramambular C++ エンジンを Swift で再開発したものである)。"; "lblCredits.title" = "ボポモフォエンジン開発Lukhnos Liu。\n入力状態管理システム開発Zonble Yang。\nmacOS 版威注音の開発Shiki Suen, Isaac Xen, Hiraku Wang, など。\n威注音語彙データの維持Shiki Suen。\nMegrez 辞書処理エンジンShiki SuenLukhnos の Gramambular C++ エンジンを Swift で再開発したものである)。";

View File

@ -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 重写而得。";

View File

@ -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 重寫而得。";

View File

@ -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>

View File

@ -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>

View File

@ -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 = "";

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
</Workspace>

View File

@ -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>