Merge pull request #54 from ShikiSuen/upd/1.3.4
v1.3.4 // Maintenance release, fixing certain behaviors with UserPhrases.
This commit is contained in:
commit
8eaab3da31
|
@ -67,7 +67,7 @@
|
||||||
<window title="vChewing Installer" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" animationBehavior="default" titlebarAppearsTransparent="YES" id="371">
|
<window title="vChewing Installer" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" animationBehavior="default" titlebarAppearsTransparent="YES" id="371">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||||
<rect key="contentRect" x="335" y="390" width="533" height="457"/>
|
<rect key="contentRect" x="335" y="390" width="533" height="457"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1055"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="1600" height="875"/>
|
||||||
<value key="minSize" type="size" width="533" height="457"/>
|
<value key="minSize" type="size" width="533" height="457"/>
|
||||||
<value key="maxSize" type="size" width="533" height="457"/>
|
<value key="maxSize" type="size" width="533" height="457"/>
|
||||||
<view key="contentView" id="372">
|
<view key="contentView" id="372">
|
||||||
|
@ -271,7 +271,6 @@ Gw
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="appCopyrightLabel" destination="03l-rN-zf9" id="XS5-cZ-k9H"/>
|
<outlet property="appCopyrightLabel" destination="03l-rN-zf9" id="XS5-cZ-k9H"/>
|
||||||
<outlet property="appEULAContent" destination="47J-tO-8TZ" id="kRU-X2-8kX"/>
|
<outlet property="appEULAContent" destination="47J-tO-8TZ" id="kRU-X2-8kX"/>
|
||||||
<outlet property="appNameLabel" destination="bzR-Oa-BZa" id="swF-1l-dhS"/>
|
|
||||||
<outlet property="appVersionLabel" destination="z1m-8k-Z63" id="75X-uy-0Iz"/>
|
<outlet property="appVersionLabel" destination="z1m-8k-Z63" id="75X-uy-0Iz"/>
|
||||||
<outlet property="cancelButton" destination="592" id="710"/>
|
<outlet property="cancelButton" destination="592" id="710"/>
|
||||||
<outlet property="installButton" destination="575" id="709"/>
|
<outlet property="installButton" destination="575" id="709"/>
|
||||||
|
@ -283,7 +282,7 @@ Gw
|
||||||
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="gHl-Hx-eQn">
|
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="gHl-Hx-eQn">
|
||||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
<rect key="contentRect" x="283" y="305" width="480" height="180"/>
|
<rect key="contentRect" x="283" y="305" width="480" height="180"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1055"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="1600" height="875"/>
|
||||||
<view key="contentView" id="wAe-c8-Vh9">
|
<view key="contentView" id="wAe-c8-Vh9">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="480" height="180"/>
|
<rect key="frame" x="0.0" y="0.0" width="480" height="180"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13150" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
|
<dependencies>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13150"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<objects>
|
||||||
|
<customObject id="-2" userLabel="File's Owner" customClass="ShareViewController" customModuleProvider="target">
|
||||||
|
<connections>
|
||||||
|
<outlet property="view" destination="1" id="2"/>
|
||||||
|
</connections>
|
||||||
|
</customObject>
|
||||||
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
|
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="388" height="202"/>
|
||||||
|
<subviews>
|
||||||
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1uM-r7-H1c">
|
||||||
|
<rect key="frame" x="302" y="3" width="82" height="32"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Send" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="2l4-PO-we5">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<string key="keyEquivalent">D</string>
|
||||||
|
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="send:" target="-2" id="yic-EC-GGk"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="NVE-vN-dkz">
|
||||||
|
<rect key="frame" x="224" y="3" width="82" height="32"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="60" id="cP1-hK-9ZX"/>
|
||||||
|
</constraints>
|
||||||
|
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6Up-t3-mwm">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<string key="keyEquivalent" base64-UTF8="YES">
|
||||||
|
Gw
|
||||||
|
</string>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="cancel:" target="-2" id="Qav-AK-DGt"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aNc-0i-CWK">
|
||||||
|
<rect key="frame" x="140" y="170" width="108" height="17"/>
|
||||||
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="My Service Title" id="0xp-rC-2gr">
|
||||||
|
<font key="font" metaFont="systemBold"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="4M6-D5-WIf">
|
||||||
|
<rect key="frame" x="110" y="170" width="22" height="22"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" constant="22" id="BOe-aZ-Njc"/>
|
||||||
|
<constraint firstAttribute="height" constant="22" id="zLg-1a-wlZ"/>
|
||||||
|
</constraints>
|
||||||
|
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="q3u-Am-ZIA"/>
|
||||||
|
</imageView>
|
||||||
|
</subviews>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="1uM-r7-H1c" firstAttribute="leading" secondItem="NVE-vN-dkz" secondAttribute="trailing" constant="8" id="1UO-J1-LbJ"/>
|
||||||
|
<constraint firstItem="NVE-vN-dkz" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="3N9-qo-UfS"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="1uM-r7-H1c" secondAttribute="bottom" constant="10" id="4wH-De-nMF"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="NVE-vN-dkz" secondAttribute="bottom" constant="10" id="USG-Gg-of3"/>
|
||||||
|
<constraint firstItem="1uM-r7-H1c" firstAttribute="leading" secondItem="NVE-vN-dkz" secondAttribute="trailing" constant="8" id="a8N-vS-Ew9"/>
|
||||||
|
<constraint firstItem="aNc-0i-CWK" firstAttribute="centerY" secondItem="4M6-D5-WIf" secondAttribute="centerY" constant="2.5" id="ilP-G0-GVG"/>
|
||||||
|
<constraint firstItem="NVE-vN-dkz" firstAttribute="width" secondItem="1uM-r7-H1c" secondAttribute="width" id="qPo-ky-Fcw"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="1uM-r7-H1c" secondAttribute="trailing" constant="10" id="qfT-cw-QQ2"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="aNc-0i-CWK" secondAttribute="centerX" id="uV3-Wn-RA3"/>
|
||||||
|
<constraint firstItem="aNc-0i-CWK" firstAttribute="leading" secondItem="4M6-D5-WIf" secondAttribute="trailing" constant="10" id="vFR-5i-Dvo"/>
|
||||||
|
<constraint firstItem="aNc-0i-CWK" firstAttribute="top" secondItem="1" secondAttribute="top" constant="15" id="vpR-tf-ebx"/>
|
||||||
|
</constraints>
|
||||||
|
</customView>
|
||||||
|
</objects>
|
||||||
|
</document>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>icon</string>
|
||||||
|
<key>NSExtension</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExtensionAttributes</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExtensionActivationRule</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExtensionActivationSupportsText</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>NSExtensionPointIdentifier</key>
|
||||||
|
<string>com.apple.share-services</string>
|
||||||
|
<key>NSExtensionPrincipalClass</key>
|
||||||
|
<string>$(PRODUCT_MODULE_NAME).ShareViewController</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.security.temporary-exception.mach-register.global-name</key>
|
||||||
|
<string>org_atelierInmu_inputmethod_vChewing</string>
|
||||||
|
<key>com.apple.security.app-sandbox</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.files.user-selected.read-only</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -0,0 +1,41 @@
|
||||||
|
//
|
||||||
|
// ShareViewController.swift
|
||||||
|
// KeyboardExtension
|
||||||
|
//
|
||||||
|
// Created by ShikiSuen on 2022/2/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
|
||||||
|
class ShareViewController: NSViewController {
|
||||||
|
|
||||||
|
override var nibName: NSNib.Name? {
|
||||||
|
return NSNib.Name("ShareViewController")
|
||||||
|
}
|
||||||
|
|
||||||
|
override func loadView() {
|
||||||
|
super.loadView()
|
||||||
|
|
||||||
|
// Insert code here to customize the view
|
||||||
|
let item = self.extensionContext!.inputItems[0] as! NSExtensionItem
|
||||||
|
if let attachments = item.attachments {
|
||||||
|
NSLog("Attachments = %@", attachments as NSArray)
|
||||||
|
} else {
|
||||||
|
NSLog("No Attachments")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func send(_ sender: AnyObject?) {
|
||||||
|
let outputItem = NSExtensionItem()
|
||||||
|
// Complete implementation by setting the appropriate value on the output item
|
||||||
|
|
||||||
|
let outputItems = [outputItem]
|
||||||
|
self.extensionContext!.completeRequest(returningItems: outputItems, completionHandler: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func cancel(_ sender: AnyObject?) {
|
||||||
|
let cancelError = NSError(domain: NSCocoaErrorDomain, code: NSUserCancelledError, userInfo: nil)
|
||||||
|
self.extensionContext!.cancelRequest(withError: cancelError)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Binary file not shown.
|
@ -8,48 +8,48 @@
|
||||||
<string>vChewingKeyLayout</string>
|
<string>vChewingKeyLayout</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.0</string>
|
<string>1.0</string>
|
||||||
<key>KLInfo_Zhuyin Dachen</key>
|
<key>KLInfo_vChewingDachen</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>TICapsLockLanguageSwitchCapable</key>
|
<key>TICapsLockLanguageSwitchCapable</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>TISInputSourceID</key>
|
<key>TISInputSourceID</key>
|
||||||
<string>org.atelierInmu.keyboardlayout.vChewingKeyLayout.zhuyindachen</string>
|
<string>org.atelierInmu.keyboardlayout.vChewingKeyLayout.vChewingDachen</string>
|
||||||
<key>TISIntendedLanguage</key>
|
<key>TISIntendedLanguage</key>
|
||||||
<string>zh-Hanb</string>
|
<string>zh-Hanb</string>
|
||||||
</dict>
|
</dict>
|
||||||
<key>KLInfo_Zhuyin ETen</key>
|
<key>KLInfo_vChewingETen</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>TICapsLockLanguageSwitchCapable</key>
|
<key>TICapsLockLanguageSwitchCapable</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>TISInputSourceID</key>
|
<key>TISInputSourceID</key>
|
||||||
<string>org.atelierInmu.keyboardlayout.vChewingKeyLayout.zhuyineten</string>
|
<string>org.atelierInmu.keyboardlayout.vChewingKeyLayout.vChewingETen</string>
|
||||||
<key>TISIntendedLanguage</key>
|
<key>TISIntendedLanguage</key>
|
||||||
<string>zh-Hanb</string>
|
<string>zh-Hanb</string>
|
||||||
</dict>
|
</dict>
|
||||||
<key>KLInfo_Zhuyin IBM</key>
|
<key>KLInfo_vChewingIBM</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>TICapsLockLanguageSwitchCapable</key>
|
<key>TICapsLockLanguageSwitchCapable</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>TISInputSourceID</key>
|
<key>TISInputSourceID</key>
|
||||||
<string>org.atelierInmu.keyboardlayout.vChewingKeyLayout.zhuyinibm</string>
|
<string>org.atelierInmu.keyboardlayout.vChewingKeyLayout.vChewingIBM</string>
|
||||||
<key>TISIntendedLanguage</key>
|
<key>TISIntendedLanguage</key>
|
||||||
<string>zh-Hanb</string>
|
<string>zh-Hanb</string>
|
||||||
</dict>
|
</dict>
|
||||||
<key>KLInfo_Zhuyin MiTAC</key>
|
<key>KLInfo_vChewingMiTAC</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>TICapsLockLanguageSwitchCapable</key>
|
<key>TICapsLockLanguageSwitchCapable</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>TISInputSourceID</key>
|
<key>TISInputSourceID</key>
|
||||||
<string>org.atelierInmu.keyboardlayout.vChewingKeyLayout.zhuyinmitac</string>
|
<string>org.atelierInmu.keyboardlayout.vChewingKeyLayout.vChewingMiTAC</string>
|
||||||
<key>TISIntendedLanguage</key>
|
<key>TISIntendedLanguage</key>
|
||||||
<string>zh-Hanb</string>
|
<string>zh-Hanb</string>
|
||||||
</dict>
|
</dict>
|
||||||
<key>KLInfo_Zhuyin Seigyou</key>
|
<key>KLInfo_vChewingSeigyou</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>TICapsLockLanguageSwitchCapable</key>
|
<key>TICapsLockLanguageSwitchCapable</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>TISInputSourceID</key>
|
<key>TISInputSourceID</key>
|
||||||
<string>org.atelierInmu.keyboardlayout.vChewingKeyLayout.zhuyinseigyou</string>
|
<string>org.atelierInmu.keyboardlayout.vChewingKeyLayout.vChewingSeigyou</string>
|
||||||
<key>TISIntendedLanguage</key>
|
<key>TISIntendedLanguage</key>
|
||||||
<string>zh-Hanb</string>
|
<string>zh-Hanb</string>
|
||||||
</dict>
|
</dict>
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.1" encoding="UTF-8"?>
|
<?xml version="1.1" encoding="UTF-8"?>
|
||||||
<!DOCTYPE keyboard SYSTEM "file://localhost/System/Library/DTDs/KeyboardLayout.dtd">
|
<!DOCTYPE keyboard SYSTEM "file://localhost/System/Library/DTDs/KeyboardLayout.dtd">
|
||||||
<!--Last edited by Ukelele version 351 on 2022-02-14 at 17:15 (GMT+8)-->
|
<!--Last edited by Ukelele version 351 on 2022-02-14 at 17:15 (GMT+8)-->
|
||||||
<keyboard group="126" id="-1524" name="Zhuyin Dachen" maxout="1">
|
<keyboard group="126" id="-1524" name="vChewing Dachen" maxout="1">
|
||||||
<layouts>
|
<layouts>
|
||||||
<layout first="0" last="17" mapSet="16c" modifiers="f4"/>
|
<layout first="0" last="17" mapSet="16c" modifiers="f4"/>
|
||||||
<layout first="18" last="18" mapSet="a88" modifiers="f4"/>
|
<layout first="18" last="18" mapSet="a88" modifiers="f4"/>
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.1" encoding="UTF-8"?>
|
<?xml version="1.1" encoding="UTF-8"?>
|
||||||
<!DOCTYPE keyboard SYSTEM "file://localhost/System/Library/DTDs/KeyboardLayout.dtd">
|
<!DOCTYPE keyboard SYSTEM "file://localhost/System/Library/DTDs/KeyboardLayout.dtd">
|
||||||
<!--Last edited by Ukelele version 351 on 2022-02-14 at 17:29 (GMT+8)-->
|
<!--Last edited by Ukelele version 351 on 2022-02-14 at 17:29 (GMT+8)-->
|
||||||
<keyboard group="126" id="-2369" name="Zhuyin ETen" maxout="1">
|
<keyboard group="126" id="-2369" name="vChewing ETen" maxout="1">
|
||||||
<layouts>
|
<layouts>
|
||||||
<layout first="0" last="17" mapSet="16c" modifiers="f4"/>
|
<layout first="0" last="17" mapSet="16c" modifiers="f4"/>
|
||||||
<layout first="18" last="18" mapSet="a88" modifiers="f4"/>
|
<layout first="18" last="18" mapSet="a88" modifiers="f4"/>
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.1" encoding="UTF-8"?>
|
<?xml version="1.1" encoding="UTF-8"?>
|
||||||
<!DOCTYPE keyboard SYSTEM "file://localhost/System/Library/DTDs/KeyboardLayout.dtd">
|
<!DOCTYPE keyboard SYSTEM "file://localhost/System/Library/DTDs/KeyboardLayout.dtd">
|
||||||
<!--Last edited by Ukelele version 351 on 2022-02-14 at 17:36 (GMT+8)-->
|
<!--Last edited by Ukelele version 351 on 2022-02-14 at 17:36 (GMT+8)-->
|
||||||
<keyboard group="126" id="-28630" name="Zhuyin IBM" maxout="1">
|
<keyboard group="126" id="-28630" name="vChewing IBM" maxout="1">
|
||||||
<layouts>
|
<layouts>
|
||||||
<layout first="0" last="17" mapSet="16c" modifiers="f4"/>
|
<layout first="0" last="17" mapSet="16c" modifiers="f4"/>
|
||||||
<layout first="18" last="18" mapSet="a88" modifiers="f4"/>
|
<layout first="18" last="18" mapSet="a88" modifiers="f4"/>
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.1" encoding="UTF-8"?>
|
<?xml version="1.1" encoding="UTF-8"?>
|
||||||
<!DOCTYPE keyboard SYSTEM "file://localhost/System/Library/DTDs/KeyboardLayout.dtd">
|
<!DOCTYPE keyboard SYSTEM "file://localhost/System/Library/DTDs/KeyboardLayout.dtd">
|
||||||
<!--Last edited by Ukelele version 351 on 2022-02-14 at 17:15 (GMT+8)-->
|
<!--Last edited by Ukelele version 351 on 2022-02-14 at 17:15 (GMT+8)-->
|
||||||
<keyboard group="126" id="-7969" name="Zhuyin MiTAC" maxout="1">
|
<keyboard group="126" id="-7969" name="vChewing MiTAC" maxout="1">
|
||||||
<layouts>
|
<layouts>
|
||||||
<layout first="0" last="17" mapSet="16c" modifiers="f4"/>
|
<layout first="0" last="17" mapSet="16c" modifiers="f4"/>
|
||||||
<layout first="18" last="18" mapSet="a88" modifiers="f4"/>
|
<layout first="18" last="18" mapSet="a88" modifiers="f4"/>
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.1" encoding="UTF-8"?>
|
<?xml version="1.1" encoding="UTF-8"?>
|
||||||
<!DOCTYPE keyboard SYSTEM "file://localhost/System/Library/DTDs/KeyboardLayout.dtd">
|
<!DOCTYPE keyboard SYSTEM "file://localhost/System/Library/DTDs/KeyboardLayout.dtd">
|
||||||
<!--Last edited by Ukelele version 351 on 2022-02-14 at 17:40 (GMT+8)-->
|
<!--Last edited by Ukelele version 351 on 2022-02-14 at 17:40 (GMT+8)-->
|
||||||
<keyboard group="126" id="-17519" name="Zhuyin Seigyou" maxout="1">
|
<keyboard group="126" id="-17519" name="vChewing Seigyou" maxout="1">
|
||||||
<layouts>
|
<layouts>
|
||||||
<layout first="0" last="17" mapSet="16c" modifiers="f4"/>
|
<layout first="0" last="17" mapSet="16c" modifiers="f4"/>
|
||||||
<layout first="18" last="18" mapSet="a88" modifiers="f4"/>
|
<layout first="18" last="18" mapSet="a88" modifiers="f4"/>
|
Binary file not shown.
|
@ -1 +1 @@
|
||||||
Subproject commit 36a71ee9d2e58611cd8466a1908f0a30274e261e
|
Subproject commit 6dc73cd3edd47c85089db8f58e92f0c821e67ed6
|
|
@ -142,8 +142,8 @@ struct VersionUpdateApi {
|
||||||
@objc(AppDelegate)
|
@objc(AppDelegate)
|
||||||
class AppDelegate: NSObject, NSApplicationDelegate, ctlNonModalAlertWindowDelegate, FSEventStreamHelperDelegate {
|
class AppDelegate: NSObject, NSApplicationDelegate, ctlNonModalAlertWindowDelegate, FSEventStreamHelperDelegate {
|
||||||
func helper(_ helper: FSEventStreamHelper, didReceive events: [FSEventStreamHelper.Event]) {
|
func helper(_ helper: FSEventStreamHelper, didReceive events: [FSEventStreamHelper.Event]) {
|
||||||
// 拖一秒鐘再重載,畢竟有些有特殊需求的使用者可能會想使用巨型自訂語彙檔案。
|
// 拖 100ms 再重載,畢竟有些有特殊需求的使用者可能會想使用巨型自訂語彙檔案。
|
||||||
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
|
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) {
|
||||||
if Preferences.shouldAutoReloadUserDataFiles {
|
if Preferences.shouldAutoReloadUserDataFiles {
|
||||||
mgrLangModel.loadUserPhrases()
|
mgrLangModel.loadUserPhrases()
|
||||||
mgrLangModel.loadUserPhraseReplacement()
|
mgrLangModel.loadUserPhraseReplacement()
|
||||||
|
@ -159,7 +159,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, ctlNonModalAlertWindowDelega
|
||||||
private var ctlAboutWindowInstance: ctlAboutWindow? // New About Window
|
private var ctlAboutWindowInstance: ctlAboutWindow? // New About Window
|
||||||
private var checkTask: URLSessionTask?
|
private var checkTask: URLSessionTask?
|
||||||
private var updateNextStepURL: URL?
|
private var updateNextStepURL: URL?
|
||||||
private var fsStreamHelper = FSEventStreamHelper(path: mgrLangModel.dataFolderPath, queue: DispatchQueue(label: "User Phrases"))
|
private var fsStreamHelper = FSEventStreamHelper(path: mgrLangModel.dataFolderPath, queue: DispatchQueue(label: "vChewing User Phrases"))
|
||||||
|
|
||||||
// 補上 dealloc
|
// 補上 dealloc
|
||||||
deinit {
|
deinit {
|
||||||
|
|
|
@ -182,9 +182,9 @@ class InputState: NSObject {
|
||||||
let (exactEnd, _) = (composingBuffer as NSString).characterIndex(from: markedRange.location + markedRange.length)
|
let (exactEnd, _) = (composingBuffer as NSString).characterIndex(from: markedRange.location + markedRange.length)
|
||||||
let selectedReadings = readings[exactBegin..<exactEnd]
|
let selectedReadings = readings[exactBegin..<exactEnd]
|
||||||
let joined = selectedReadings.joined(separator: "-")
|
let joined = selectedReadings.joined(separator: "-")
|
||||||
let exist = mgrLangModel.checkIfExist(userPhrase: text, key: joined)
|
let exist = mgrLangModel.checkIfUserPhraseExist(userPhrase: text, mode: ctlInputMethod.currentKeyHandler.inputMode, key: joined)
|
||||||
if exist {
|
if exist {
|
||||||
return String(format: NSLocalizedString("\"%@\" already exists.", comment: ""), text)
|
return String(format: NSLocalizedString("\"%@\" already exists, ENTER to boost its priority.", comment: ""), text)
|
||||||
}
|
}
|
||||||
|
|
||||||
return String(format: NSLocalizedString("\"%@\" selected. ENTER to add user phrase.", comment: ""), text)
|
return String(format: NSLocalizedString("\"%@\" selected. ENTER to add user phrase.", comment: ""), text)
|
||||||
|
@ -246,12 +246,16 @@ class InputState: NSObject {
|
||||||
if markedRange.length > kMaxMarkRangeLength {
|
if markedRange.length > kMaxMarkRangeLength {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
return markedRange.length >= kMinMarkRangeLength && markedRange.length <= kMaxMarkRangeLength
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc var chkIfUserPhraseExists: Bool {
|
||||||
let text = (composingBuffer as NSString).substring(with: markedRange)
|
let text = (composingBuffer as NSString).substring(with: markedRange)
|
||||||
let (exactBegin, _) = (composingBuffer as NSString).characterIndex(from: markedRange.location)
|
let (exactBegin, _) = (composingBuffer as NSString).characterIndex(from: markedRange.location)
|
||||||
let (exactEnd, _) = (composingBuffer as NSString).characterIndex(from: markedRange.location + markedRange.length)
|
let (exactEnd, _) = (composingBuffer as NSString).characterIndex(from: markedRange.location + markedRange.length)
|
||||||
let selectedReadings = readings[exactBegin..<exactEnd]
|
let selectedReadings = readings[exactBegin..<exactEnd]
|
||||||
let joined = selectedReadings.joined(separator: "-")
|
let joined = selectedReadings.joined(separator: "-")
|
||||||
return mgrLangModel.checkIfExist(userPhrase: text, key: joined) == false
|
return mgrLangModel.checkIfUserPhraseExist(userPhrase: text, mode: ctlInputMethod.currentKeyHandler.inputMode, key: joined) == true
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc var userPhrase: String {
|
@objc var userPhrase: String {
|
||||||
|
|
|
@ -17,28 +17,23 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "Mandarin.h"
|
|
||||||
#import "Gramambular.h"
|
#import "Gramambular.h"
|
||||||
#import "vChewingLM.h"
|
|
||||||
#import "UserOverrideModel.h"
|
|
||||||
#import "mgrLangModel_Privates.h"
|
|
||||||
#import "KeyHandler.h"
|
#import "KeyHandler.h"
|
||||||
|
#import "LMInstantiator.h"
|
||||||
|
#import "Mandarin.h"
|
||||||
|
#import "mgrLangModel_Privates.h"
|
||||||
|
#import "UserOverrideModel.h"
|
||||||
#import "vChewing-Swift.h"
|
#import "vChewing-Swift.h"
|
||||||
#import <string>
|
#import <string>
|
||||||
|
|
||||||
// C++ namespace usages
|
|
||||||
using namespace std;
|
|
||||||
using namespace Taiyan::Mandarin;
|
|
||||||
using namespace Taiyan::Gramambular;
|
|
||||||
using namespace vChewing;
|
|
||||||
|
|
||||||
InputMode imeModeCHT = @"org.atelierInmu.inputmethod.vChewing.IMECHT";
|
InputMode imeModeCHT = @"org.atelierInmu.inputmethod.vChewing.IMECHT";
|
||||||
InputMode imeModeCHS = @"org.atelierInmu.inputmethod.vChewing.IMECHS";
|
InputMode imeModeCHS = @"org.atelierInmu.inputmethod.vChewing.IMECHS";
|
||||||
InputMode imeModeNULL = @"org.atelierInmu.inputmethod.vChewing.IMENULL";
|
InputMode imeModeNULL = @"org.atelierInmu.inputmethod.vChewing.IMENULL";
|
||||||
|
|
||||||
static const double kEpsilon = 0.000001;
|
static const double kEpsilon = 0.000001;
|
||||||
|
|
||||||
static double FindHighestScore(const vector<NodeAnchor> &nodes, double epsilon) {
|
static double FindHighestScore(const std::vector<Taiyan::Gramambular::NodeAnchor> &nodes, double epsilon) {
|
||||||
double highestScore = 0.0;
|
double highestScore = 0.0;
|
||||||
for (auto ni = nodes.begin(), ne = nodes.end(); ni != ne; ++ni) {
|
for (auto ni = nodes.begin(), ne = nodes.end(); ni != ne; ++ni) {
|
||||||
double score = ni->node->highestUnigramScore();
|
double score = ni->node->highestUnigramScore();
|
||||||
|
@ -49,16 +44,15 @@ static double FindHighestScore(const vector<NodeAnchor> &nodes, double epsilon)
|
||||||
return highestScore + epsilon;
|
return highestScore + epsilon;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort helper
|
class NodeAnchorDescendingSorter {
|
||||||
class NodeAnchorDescendingSorter
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
bool operator()(const NodeAnchor &a, const NodeAnchor &b) const {
|
bool operator()(const Taiyan::Gramambular::NodeAnchor &a, const Taiyan::Gramambular::NodeAnchor &b) const
|
||||||
|
{
|
||||||
return a.node->key().length() > b.node->key().length();
|
return a.node->key().length() > b.node->key().length();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// if DEBUG is defined, a DOT file (GraphViz format) will be written to the
|
;// if DEBUG is defined, a DOT file (GraphViz format) will be written to the
|
||||||
// specified path every time the grid is walked
|
// specified path every time the grid is walked
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
|
@ -71,7 +65,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
Taiyan::Mandarin::BopomofoReadingBuffer *_bpmfReadingBuffer;
|
Taiyan::Mandarin::BopomofoReadingBuffer *_bpmfReadingBuffer;
|
||||||
|
|
||||||
// language model
|
// language model
|
||||||
vChewing::vChewingLM *_languageModel;
|
vChewing::LMInstantiator *_languageModel;
|
||||||
|
|
||||||
// user override model
|
// user override model
|
||||||
vChewing::UserOverrideModel *_userOverrideModel;
|
vChewing::UserOverrideModel *_userOverrideModel;
|
||||||
|
@ -96,8 +90,8 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
- (void)setInputMode:(NSString *)value
|
- (void)setInputMode:(NSString *)value
|
||||||
{
|
{
|
||||||
NSString *newInputMode;
|
NSString *newInputMode;
|
||||||
vChewingLM *newLanguageModel;
|
vChewing::LMInstantiator *newLanguageModel;
|
||||||
UserOverrideModel *newUserOverrideModel;
|
vChewing::UserOverrideModel *newUserOverrideModel;
|
||||||
|
|
||||||
if ([value isKindOfClass:[NSString class]] && [value isEqual:imeModeCHS]) {
|
if ([value isKindOfClass:[NSString class]] && [value isEqual:imeModeCHS]) {
|
||||||
newInputMode = imeModeCHS;
|
newInputMode = imeModeCHS;
|
||||||
|
@ -120,7 +114,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
|
|
||||||
if (_builder) {
|
if (_builder) {
|
||||||
delete _builder;
|
delete _builder;
|
||||||
_builder = new BlockReadingBuilder(_languageModel);
|
_builder = new Taiyan::Gramambular::BlockReadingBuilder(_languageModel);
|
||||||
_builder->setJoinSeparator("-");
|
_builder->setJoinSeparator("-");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +140,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self) {
|
if (self) {
|
||||||
_bpmfReadingBuffer = new BopomofoReadingBuffer(BopomofoKeyboardLayout::StandardLayout());
|
_bpmfReadingBuffer = new Taiyan::Mandarin::BopomofoReadingBuffer(Taiyan::Mandarin::BopomofoKeyboardLayout::StandardLayout());
|
||||||
|
|
||||||
// create the lattice builder
|
// create the lattice builder
|
||||||
_languageModel = [mgrLangModel lmCHT];
|
_languageModel = [mgrLangModel lmCHT];
|
||||||
|
@ -154,7 +148,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
_languageModel->setCNSEnabled(Preferences.cns11643Enabled);
|
_languageModel->setCNSEnabled(Preferences.cns11643Enabled);
|
||||||
_userOverrideModel = [mgrLangModel userOverrideModelCHT];
|
_userOverrideModel = [mgrLangModel userOverrideModelCHT];
|
||||||
|
|
||||||
_builder = new BlockReadingBuilder(_languageModel);
|
_builder = new Taiyan::Gramambular::BlockReadingBuilder(_languageModel);
|
||||||
|
|
||||||
// each Mandarin syllable is separated by a hyphen
|
// each Mandarin syllable is separated by a hyphen
|
||||||
_builder->setJoinSeparator("-");
|
_builder->setJoinSeparator("-");
|
||||||
|
@ -168,31 +162,31 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
NSInteger layout = Preferences.keyboardLayout;
|
NSInteger layout = Preferences.keyboardLayout;
|
||||||
switch (layout) {
|
switch (layout) {
|
||||||
case KeyboardLayoutStandard:
|
case KeyboardLayoutStandard:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::StandardLayout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::StandardLayout());
|
||||||
break;
|
break;
|
||||||
case KeyboardLayoutEten:
|
case KeyboardLayoutEten:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::ETenLayout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::ETenLayout());
|
||||||
break;
|
break;
|
||||||
case KeyboardLayoutHsu:
|
case KeyboardLayoutHsu:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::HsuLayout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::HsuLayout());
|
||||||
break;
|
break;
|
||||||
case KeyboardLayoutEten26:
|
case KeyboardLayoutEten26:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::ETen26Layout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::ETen26Layout());
|
||||||
break;
|
break;
|
||||||
case KeyboardLayoutIBM:
|
case KeyboardLayoutIBM:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::IBMLayout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::IBMLayout());
|
||||||
break;
|
break;
|
||||||
case KeyboardLayoutMiTAC:
|
case KeyboardLayoutMiTAC:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::MiTACLayout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::MiTACLayout());
|
||||||
break;
|
break;
|
||||||
case KeyboardLayoutFakeSeigyou:
|
case KeyboardLayoutFakeSeigyou:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::FakeSeigyouLayout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::FakeSeigyouLayout());
|
||||||
break;
|
break;
|
||||||
case KeyboardLayoutHanyuPinyin:
|
case KeyboardLayoutHanyuPinyin:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::HanyuPinyinLayout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::HanyuPinyinLayout());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(BopomofoKeyboardLayout::StandardLayout());
|
_bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::StandardLayout());
|
||||||
Preferences.keyboardLayout = KeyboardLayoutStandard;
|
Preferences.keyboardLayout = KeyboardLayoutStandard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,8 +194,8 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
- (void)fixNodeWithValue:(NSString *)value
|
- (void)fixNodeWithValue:(NSString *)value
|
||||||
{
|
{
|
||||||
size_t cursorIndex = [self _actualCandidateCursorIndex];
|
size_t cursorIndex = [self _actualCandidateCursorIndex];
|
||||||
string stringValue = [value UTF8String];
|
std::string stringValue(value.UTF8String);
|
||||||
NodeAnchor selectedNode = _builder->grid().fixNodeSelectedCandidate(cursorIndex, stringValue);
|
Taiyan::Gramambular::NodeAnchor selectedNode = _builder->grid().fixNodeSelectedCandidate(cursorIndex, stringValue);
|
||||||
if (!Preferences.useSCPCTypingMode) { // 不要針對逐字選字模式啟用臨時半衰記憶模型。
|
if (!Preferences.useSCPCTypingMode) { // 不要針對逐字選字模式啟用臨時半衰記憶模型。
|
||||||
// If the length of the readings and the characters do not match,
|
// If the length of the readings and the characters do not match,
|
||||||
// it often means it is a special symbol and it should not be stored
|
// it often means it is a special symbol and it should not be stored
|
||||||
|
@ -234,10 +228,10 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
_walkedNodes.clear();
|
_walkedNodes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (string)_currentLayout
|
- (std::string)_currentLayout
|
||||||
{
|
{
|
||||||
NSString *keyboardLayoutName = Preferences.keyboardLayoutName;
|
NSString *keyboardLayoutName = Preferences.keyboardLayoutName;
|
||||||
string layout = string(keyboardLayoutName.UTF8String) + string("_");
|
std::string layout = std::string(keyboardLayoutName.UTF8String) + std::string("_");
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +342,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
composeReading |= (!_bpmfReadingBuffer->isEmpty() && ([input isSpace] || [input isEnterCharCode] || [input isEnter]));
|
composeReading |= (!_bpmfReadingBuffer->isEmpty() && ([input isSpace] || [input isEnterCharCode] || [input isEnter]));
|
||||||
if (composeReading) {
|
if (composeReading) {
|
||||||
// combine the reading
|
// combine the reading
|
||||||
string reading = _bpmfReadingBuffer->syllable().composedString();
|
std::string reading = _bpmfReadingBuffer->syllable().composedString();
|
||||||
|
|
||||||
// see if we have a unigram for this
|
// see if we have a unigram for this
|
||||||
if (!_languageModel->hasUnigramsForKey(reading)) {
|
if (!_languageModel->hasUnigramsForKey(reading)) {
|
||||||
|
@ -365,12 +359,12 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
NSString *poppedText = [self _popOverflowComposingTextAndWalk];
|
NSString *poppedText = [self _popOverflowComposingTextAndWalk];
|
||||||
|
|
||||||
// get user override model suggestion
|
// get user override model suggestion
|
||||||
string overrideValue = (Preferences.useSCPCTypingMode) ? "" :
|
std::string overrideValue = (Preferences.useSCPCTypingMode) ? "" :
|
||||||
_userOverrideModel->suggest(_walkedNodes, _builder->cursorIndex(), [[NSDate date] timeIntervalSince1970]);
|
_userOverrideModel->suggest(_walkedNodes, _builder->cursorIndex(), [[NSDate date] timeIntervalSince1970]);
|
||||||
|
|
||||||
if (!overrideValue.empty()) {
|
if (!overrideValue.empty()) {
|
||||||
size_t cursorIndex = [self _actualCandidateCursorIndex];
|
size_t cursorIndex = [self _actualCandidateCursorIndex];
|
||||||
vector<NodeAnchor> nodes = _builder->grid().nodesCrossingOrEndingAt(cursorIndex);
|
std::vector<Taiyan::Gramambular::NodeAnchor> nodes = _builder->grid().nodesCrossingOrEndingAt(cursorIndex);
|
||||||
double highestScore = FindHighestScore(nodes, kEpsilon);
|
double highestScore = FindHighestScore(nodes, kEpsilon);
|
||||||
_builder->grid().overrideNodeScoreForSelectedCandidate(cursorIndex, overrideValue, static_cast<float>(highestScore));
|
_builder->grid().overrideNodeScoreForSelectedCandidate(cursorIndex, overrideValue, static_cast<float>(highestScore));
|
||||||
}
|
}
|
||||||
|
@ -411,13 +405,13 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Space and Down, plus PageUp / PageDn / PageLeft / PageRight.
|
// MARK: Space and Down, plus PageUp / PageDn / PageLeft / PageRight.
|
||||||
// keyCode 125 = Down, charCode 32 = Space
|
// keyCode 125 = Down, charCode 32 = Space
|
||||||
if (_bpmfReadingBuffer->isEmpty() &&
|
if (_bpmfReadingBuffer->isEmpty() &&
|
||||||
[state isKindOfClass:[InputStateNotEmpty class]] &&
|
[state isKindOfClass:[InputStateNotEmpty class]] &&
|
||||||
([input isExtraChooseCandidateKey] || [input isExtraChooseCandidateKeyReverse]
|
([input isExtraChooseCandidateKey] || [input isExtraChooseCandidateKeyReverse]
|
||||||
|| [input isSpace] || [input isPageDown] || [input isPageUp]
|
|| [input isSpace] || [input isPageDown] || [input isPageUp]
|
||||||
|| (input.useVerticalMode && ([input isVerticalModeOnlyChooseCandidateKey])))) {
|
|| (input.useVerticalMode && ([input isVerticalModeOnlyChooseCandidateKey])))) {
|
||||||
if ([input isSpace]) {
|
if ([input isSpace]) {
|
||||||
// if the spacebar is NOT set to be a selection key
|
// if the spacebar is NOT set to be a selection key
|
||||||
if ([input isShiftHold] || !Preferences.chooseCandidateUsingSpace) {
|
if ([input isShiftHold] || !Preferences.chooseCandidateUsingSpace) {
|
||||||
|
@ -521,7 +515,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
InputStateSymbolTable *symbolState = [[InputStateSymbolTable alloc] initWithNode:root useVerticalMode:input.useVerticalMode];
|
InputStateSymbolTable *symbolState = [[InputStateSymbolTable alloc] initWithNode:root useVerticalMode:input.useVerticalMode];
|
||||||
stateCallback(symbolState);
|
stateCallback(symbolState);
|
||||||
return YES;
|
return YES;
|
||||||
// if (_languageModel->hasUnigramsForKey(string("_punctuation_list"))) {
|
// if (_languageModel->hasUnigramsForKey("_punctuation_list"))) {
|
||||||
// if (_bpmfReadingBuffer->isEmpty()) {
|
// if (_bpmfReadingBuffer->isEmpty()) {
|
||||||
// _builder->insertReadingAtCursor(string("_punctuation_list"));
|
// _builder->insertReadingAtCursor(string("_punctuation_list"));
|
||||||
// NSString *poppedText = [self _popOverflowComposingTextAndWalk];
|
// NSString *poppedText = [self _popOverflowComposingTextAndWalk];
|
||||||
|
@ -540,28 +534,30 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
// MARK: Punctuation
|
// MARK: Punctuation
|
||||||
// if nothing is matched, see if it's a punctuation key for current layout.
|
// if nothing is matched, see if it's a punctuation key for current layout.
|
||||||
|
|
||||||
string punctuationNamePrefix;
|
std::string punctuationNamePrefix;
|
||||||
if ([input isControlHold]) {
|
if ([input isControlHold]) {
|
||||||
punctuationNamePrefix = string("_ctrl_punctuation_");
|
punctuationNamePrefix = std::string("_ctrl_punctuation_");
|
||||||
} else if (Preferences.halfWidthPunctuationEnabled) {
|
} else if (Preferences.halfWidthPunctuationEnabled) {
|
||||||
punctuationNamePrefix = string("_half_punctuation_");
|
punctuationNamePrefix = std::string("_half_punctuation_");
|
||||||
} else {
|
} else {
|
||||||
punctuationNamePrefix = string("_punctuation_");
|
punctuationNamePrefix = std::string("_punctuation_");
|
||||||
}
|
}
|
||||||
string layout = [self _currentLayout];
|
std::string layout = [self _currentLayout];
|
||||||
string customPunctuation = punctuationNamePrefix + layout + string(1, (char) charCode);
|
std::string customPunctuation = punctuationNamePrefix + layout + std::string(1, (char) charCode);
|
||||||
if ([self _handlePunctuation:customPunctuation state:state usingVerticalMode:input.useVerticalMode stateCallback:stateCallback errorCallback:errorCallback]) {
|
if ([self _handlePunctuation:customPunctuation state:state usingVerticalMode:input.useVerticalMode stateCallback:stateCallback errorCallback:errorCallback]) {
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if nothing is matched, see if it's a punctuation key.
|
// if nothing is matched, see if it's a punctuation key.
|
||||||
string punctuation = punctuationNamePrefix + string(1, (char) charCode);
|
std::string punctuation = punctuationNamePrefix + std::string(1, (char) charCode);
|
||||||
if ([self _handlePunctuation:punctuation state:state usingVerticalMode:input.useVerticalMode stateCallback:stateCallback errorCallback:errorCallback]) {
|
if ([self _handlePunctuation:punctuation state:state usingVerticalMode:input.useVerticalMode stateCallback:stateCallback errorCallback:errorCallback]) {
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((char) charCode >= 'A' && (char) charCode <= 'Z') {
|
// Lukhnos 這裡的處理反而會使得 Apple 倚天注音動態鍵盤佈局「敲不了半形大寫英文」的缺點曝露無疑,所以注釋掉。
|
||||||
string letter = string("_letter_") + string(1, (char) charCode);
|
// 至於他試圖用這種處理來解決的上游 UPR293 的問題,其實針對詞庫檔案的排序做點手腳就可以解決。威注音本來也就是這麼做的。
|
||||||
|
if (/*[state isKindOfClass:[InputStateNotEmpty class]] && */(char) charCode >= 'A' && (char) charCode <= 'Z') {
|
||||||
|
std::string letter = std::string("_letter_") + std::string(1, (char) charCode);
|
||||||
if ([self _handlePunctuation:letter state:state usingVerticalMode:input.useVerticalMode stateCallback:stateCallback errorCallback:errorCallback]) {
|
if ([self _handlePunctuation:letter state:state usingVerticalMode:input.useVerticalMode stateCallback:stateCallback errorCallback:errorCallback]) {
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
@ -845,7 +841,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)_handlePunctuation:(string)customPunctuation state:(InputState *)state usingVerticalMode:(BOOL)useVerticalMode stateCallback:(void (^)(InputState *))stateCallback errorCallback:(void (^)(void))errorCallback
|
- (BOOL)_handlePunctuation:(std::string)customPunctuation state:(InputState *)state usingVerticalMode:(BOOL)useVerticalMode stateCallback:(void (^)(InputState *))stateCallback errorCallback:(void (^)(void))errorCallback
|
||||||
{
|
{
|
||||||
if (!_languageModel->hasUnigramsForKey(customPunctuation)) {
|
if (!_languageModel->hasUnigramsForKey(customPunctuation)) {
|
||||||
return NO;
|
return NO;
|
||||||
|
@ -1150,23 +1146,23 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Preferences.useSCPCTypingMode) {
|
if (Preferences.useSCPCTypingMode) {
|
||||||
string layout = [self _currentLayout];
|
std::string layout = [self _currentLayout];
|
||||||
string punctuationNamePrefix;
|
std::string punctuationNamePrefix;
|
||||||
if ([input isControlHold]) {
|
if ([input isControlHold]) {
|
||||||
punctuationNamePrefix = string("_ctrl_punctuation_");
|
punctuationNamePrefix = std::string("_ctrl_punctuation_");
|
||||||
} else if (Preferences.halfWidthPunctuationEnabled) {
|
} else if (Preferences.halfWidthPunctuationEnabled) {
|
||||||
punctuationNamePrefix = string("_half_punctuation_");
|
punctuationNamePrefix = std::string("_half_punctuation_");
|
||||||
} else {
|
} else {
|
||||||
punctuationNamePrefix = string("_punctuation_");
|
punctuationNamePrefix = std::string("_punctuation_");
|
||||||
}
|
}
|
||||||
string customPunctuation = punctuationNamePrefix + layout + string(1, (char) charCode);
|
std::string customPunctuation = punctuationNamePrefix + layout + std::string(1, (char) charCode);
|
||||||
string punctuation = punctuationNamePrefix + string(1, (char) charCode);
|
std::string punctuation = punctuationNamePrefix + std::string(1, (char) charCode);
|
||||||
|
|
||||||
BOOL shouldAutoSelectCandidate = _bpmfReadingBuffer->isValidKey((char) charCode) || _languageModel->hasUnigramsForKey(customPunctuation) ||
|
BOOL shouldAutoSelectCandidate = _bpmfReadingBuffer->isValidKey((char) charCode) || _languageModel->hasUnigramsForKey(customPunctuation) ||
|
||||||
_languageModel->hasUnigramsForKey(punctuation);
|
_languageModel->hasUnigramsForKey(punctuation);
|
||||||
|
|
||||||
if (!shouldAutoSelectCandidate && (char) charCode >= 'A' && (char) charCode <= 'Z') {
|
if (!shouldAutoSelectCandidate && (char) charCode >= 'A' && (char) charCode <= 'Z') {
|
||||||
string letter = string("_letter_") + string(1, (char) charCode);
|
std::string letter = std::string("_letter_") + std::string(1, (char) charCode);
|
||||||
if (_languageModel->hasUnigramsForKey(letter)) {
|
if (_languageModel->hasUnigramsForKey(letter)) {
|
||||||
shouldAutoSelectCandidate = YES;
|
shouldAutoSelectCandidate = YES;
|
||||||
}
|
}
|
||||||
|
@ -1206,9 +1202,9 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
// we must do some Unicode codepoint counting to find the actual cursor location for the client
|
// we must do some Unicode codepoint counting to find the actual cursor location for the client
|
||||||
// i.e. we need to take UTF-16 into consideration, for which a surrogate pair takes 2 UniChars
|
// i.e. we need to take UTF-16 into consideration, for which a surrogate pair takes 2 UniChars
|
||||||
// locations
|
// locations
|
||||||
for (vector<NodeAnchor>::iterator wi = _walkedNodes.begin(), we = _walkedNodes.end(); wi != we; ++wi) {
|
for (std::vector<Taiyan::Gramambular::NodeAnchor>::iterator wi = _walkedNodes.begin(), we = _walkedNodes.end(); wi != we; ++wi) {
|
||||||
if ((*wi).node) {
|
if ((*wi).node) {
|
||||||
string nodeStr = (*wi).node->currentKeyValue().value;
|
std::string nodeStr = (*wi).node->currentKeyValue().value;
|
||||||
NSString *valueString = [NSString stringWithUTF8String:nodeStr.c_str()];
|
NSString *valueString = [NSString stringWithUTF8String:nodeStr.c_str()];
|
||||||
[composingBuffer appendString:valueString];
|
[composingBuffer appendString:valueString];
|
||||||
|
|
||||||
|
@ -1274,7 +1270,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
// retrieve the most likely trellis, i.e. a Maximum Likelihood Estimation
|
// retrieve the most likely trellis, i.e. a Maximum Likelihood Estimation
|
||||||
// of the best possible Mandarain characters given the input syllables,
|
// of the best possible Mandarain characters given the input syllables,
|
||||||
// using the Viterbi algorithm implemented in the Gramambular library
|
// using the Viterbi algorithm implemented in the Gramambular library
|
||||||
Walker walker(&_builder->grid());
|
Taiyan::Gramambular::Walker walker(&_builder->grid());
|
||||||
|
|
||||||
// the reverse walk traces the trellis from the end
|
// the reverse walk traces the trellis from the end
|
||||||
_walkedNodes = walker.reverseWalk(_builder->grid().width());
|
_walkedNodes = walker.reverseWalk(_builder->grid().width());
|
||||||
|
@ -1284,7 +1280,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
|
|
||||||
// if DEBUG is defined, a GraphViz file is written to kGraphVizOutputfile
|
// if DEBUG is defined, a GraphViz file is written to kGraphVizOutputfile
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
string dotDump = _builder->grid().dumpDOT();
|
std::string dotDump = _builder->grid().dumpDOT();
|
||||||
NSString *dotStr = [NSString stringWithUTF8String:dotDump.c_str()];
|
NSString *dotStr = [NSString stringWithUTF8String:dotDump.c_str()];
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
|
|
||||||
|
@ -1307,7 +1303,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
|
|
||||||
if (_builder->grid().width() > (size_t) composingBufferSize) {
|
if (_builder->grid().width() > (size_t) composingBufferSize) {
|
||||||
if (_walkedNodes.size() > 0) {
|
if (_walkedNodes.size() > 0) {
|
||||||
NodeAnchor &anchor = _walkedNodes[0];
|
Taiyan::Gramambular::NodeAnchor &anchor = _walkedNodes[0];
|
||||||
poppedText = [NSString stringWithUTF8String:anchor.node->currentKeyValue().value.c_str()];
|
poppedText = [NSString stringWithUTF8String:anchor.node->currentKeyValue().value.c_str()];
|
||||||
_builder->removeHeadReadings(anchor.spanningLength);
|
_builder->removeHeadReadings(anchor.spanningLength);
|
||||||
}
|
}
|
||||||
|
@ -1322,15 +1318,15 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
NSMutableArray *candidatesArray = [[NSMutableArray alloc] init];
|
NSMutableArray *candidatesArray = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
size_t cursorIndex = [self _actualCandidateCursorIndex];
|
size_t cursorIndex = [self _actualCandidateCursorIndex];
|
||||||
vector<NodeAnchor> nodes = _builder->grid().nodesCrossingOrEndingAt(cursorIndex);
|
std::vector<Taiyan::Gramambular::NodeAnchor> nodes = _builder->grid().nodesCrossingOrEndingAt(cursorIndex);
|
||||||
|
|
||||||
// sort the nodes, so that longer nodes (representing longer phrases) are placed at the top of the candidate list
|
// sort the nodes, so that longer nodes (representing longer phrases) are placed at the top of the candidate list
|
||||||
stable_sort(nodes.begin(), nodes.end(), NodeAnchorDescendingSorter());
|
stable_sort(nodes.begin(), nodes.end(), NodeAnchorDescendingSorter());
|
||||||
|
|
||||||
// then use the C++ trick to retrieve the candidates for each node at/crossing the cursor
|
// then use the C++ trick to retrieve the candidates for each node at/crossing the cursor
|
||||||
for (vector<NodeAnchor>::iterator ni = nodes.begin(), ne = nodes.end(); ni != ne; ++ni) {
|
for (std::vector<Taiyan::Gramambular::NodeAnchor>::iterator ni = nodes.begin(), ne = nodes.end(); ni != ne; ++ni) {
|
||||||
const vector<KeyValuePair> &candidates = (*ni).node->candidates();
|
const std::vector<Taiyan::Gramambular::KeyValuePair> &candidates = (*ni).node->candidates();
|
||||||
for (vector<KeyValuePair>::const_iterator ci = candidates.begin(), ce = candidates.end(); ci != ce; ++ci) {
|
for (std::vector<Taiyan::Gramambular::KeyValuePair>::const_iterator ci = candidates.begin(), ce = candidates.end(); ci != ce; ++ci) {
|
||||||
[candidatesArray addObject:[NSString stringWithUTF8String:(*ci).value.c_str()]];
|
[candidatesArray addObject:[NSString stringWithUTF8String:(*ci).value.c_str()]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1359,8 +1355,8 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
- (NSArray *)_currentReadings
|
- (NSArray *)_currentReadings
|
||||||
{
|
{
|
||||||
NSMutableArray *readingsArray = [[NSMutableArray alloc] init];
|
NSMutableArray *readingsArray = [[NSMutableArray alloc] init];
|
||||||
vector<std::string> v = _builder->readings();
|
std::vector<std::string> v = _builder->readings();
|
||||||
for (vector<std::string>::iterator it_i = v.begin(); it_i != v.end(); ++it_i) {
|
for (std::vector<std::string>::iterator it_i = v.begin(); it_i != v.end(); ++it_i) {
|
||||||
[readingsArray addObject:[NSString stringWithUTF8String:it_i->c_str()]];
|
[readingsArray addObject:[NSString stringWithUTF8String:it_i->c_str()]];
|
||||||
}
|
}
|
||||||
return readingsArray;
|
return readingsArray;
|
||||||
|
@ -1368,9 +1364,9 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
|
||||||
|
|
||||||
- (nullable InputState *)buildAssociatePhraseStateWithKey:(NSString *)key useVerticalMode:(BOOL)useVerticalMode
|
- (nullable InputState *)buildAssociatePhraseStateWithKey:(NSString *)key useVerticalMode:(BOOL)useVerticalMode
|
||||||
{
|
{
|
||||||
string cppKey = string(key.UTF8String);
|
std::string cppKey = std::string(key.UTF8String);
|
||||||
if (_languageModel->hasAssociatedPhrasesForKey(cppKey)) {
|
if (_languageModel->hasAssociatedPhrasesForKey(cppKey)) {
|
||||||
vector<string> phrases = _languageModel->associatedPhrasesForKey(cppKey);
|
std::vector<std::string> phrases = _languageModel->associatedPhrasesForKey(cppKey);
|
||||||
NSMutableArray <NSString *> *array = [NSMutableArray array];
|
NSMutableArray <NSString *> *array = [NSMutableArray array];
|
||||||
for (auto phrase: phrases) {
|
for (auto phrase: phrases) {
|
||||||
NSString *item = [[NSString alloc] initWithUTF8String:phrase.c_str()];
|
NSString *item = [[NSString alloc] initWithUTF8String:phrase.c_str()];
|
||||||
|
|
|
@ -37,7 +37,7 @@ class LMConsolidator
|
||||||
public:
|
public:
|
||||||
static bool CheckPragma(const char *path);
|
static bool CheckPragma(const char *path);
|
||||||
static bool FixEOF(const char *path);
|
static bool FixEOF(const char *path);
|
||||||
static bool ConsolidateContent(const char *path, bool shouldsort);
|
static bool ConsolidateContent(const char *path, bool shouldsort, bool shouldCheckPragma);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace vChewing
|
} // namespace vChewing
|
||||||
|
|
|
@ -71,8 +71,8 @@ bool LMConsolidator::FixEOF(const char *path)
|
||||||
} // END: EOF FIXER.
|
} // END: EOF FIXER.
|
||||||
|
|
||||||
// CONTENT CONSOLIDATOR. CREDIT: Shiki Suen.
|
// CONTENT CONSOLIDATOR. CREDIT: Shiki Suen.
|
||||||
bool LMConsolidator::ConsolidateContent(const char *path, bool shouldsort) {
|
bool LMConsolidator::ConsolidateContent(const char *path, bool shouldsort, bool shouldCheckPragma) {
|
||||||
if (LMConsolidator::CheckPragma(path) && !shouldsort){
|
if (LMConsolidator::CheckPragma(path) && !shouldsort && shouldCheckPragma){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,13 @@ class ctlInputMethod: IMKInputController {
|
||||||
private var keyHandler: KeyHandler = KeyHandler()
|
private var keyHandler: KeyHandler = KeyHandler()
|
||||||
private var state: InputState = InputState.Empty()
|
private var state: InputState = InputState.Empty()
|
||||||
|
|
||||||
|
// 想讓 keyHandler 能夠被外界調查狀態與參數的話,就得對 keyHandler 做常態處理。
|
||||||
|
// 這樣 InputState 可以藉由這個 ctlInputMethod 了解到當前的輸入模式是簡體中文還是繁體中文。
|
||||||
|
// 然而,要是直接對 keyHandler 做常態處理的話,反而會導致 keyHandlerInput 無法協同處理。
|
||||||
|
// 所以才需要「currentKeyHandler」這個假 keyHandler。
|
||||||
|
// 這個「currentKeyHandler」僅用來讓其他模組知道當前的輸入模式是什麼模式,除此之外別無屌用。
|
||||||
|
static var currentKeyHandler: KeyHandler = KeyHandler()
|
||||||
|
|
||||||
// MARK: - IMKInputController methods
|
// MARK: - IMKInputController methods
|
||||||
|
|
||||||
override init!(server: IMKServer!, delegate: Any!, client inputClient: Any!) {
|
override init!(server: IMKServer!, delegate: Any!, client inputClient: Any!) {
|
||||||
|
@ -157,6 +164,8 @@ class ctlInputMethod: IMKInputController {
|
||||||
keyHandler.inputMode = newInputMode
|
keyHandler.inputMode = newInputMode
|
||||||
self.handle(state: .Empty(), client: client)
|
self.handle(state: .Empty(), client: client)
|
||||||
}
|
}
|
||||||
|
// 讓外界知道目前的簡繁體輸入模式。
|
||||||
|
ctlInputMethod.currentKeyHandler.inputMode = keyHandler.inputMode
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - IMKServerInput protocol methods
|
// MARK: - IMKServerInput protocol methods
|
||||||
|
@ -603,7 +612,7 @@ extension ctlInputMethod: KeyHandlerDelegate {
|
||||||
if !state.validToWrite {
|
if !state.validToWrite {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
mgrLangModel.writeUserPhrase(state.userPhrase, inputMode: keyHandler.inputMode)
|
mgrLangModel.writeUserPhrase(state.userPhrase, inputMode: keyHandler.inputMode, areWeDuplicating: state.chkIfUserPhraseExists)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,22 +17,22 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef VCHEWINGLM_H
|
#ifndef LMInstantiator_H
|
||||||
#define VCHEWINGLM_H
|
#define LMInstantiator_H
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "UserPhrasesLM.h"
|
|
||||||
#include "ParselessLM.h"
|
|
||||||
#include "CNSLM.h"
|
|
||||||
#include "PhraseReplacementMap.h"
|
|
||||||
#include "AssociatedPhrases.h"
|
#include "AssociatedPhrases.h"
|
||||||
|
#include "CNSLM.h"
|
||||||
|
#include "ParselessLM.h"
|
||||||
|
#include "PhraseReplacementMap.h"
|
||||||
|
#include "UserPhrasesLM.h"
|
||||||
|
#include <stdio.h>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
namespace vChewing {
|
namespace vChewing {
|
||||||
|
|
||||||
using namespace Taiyan::Gramambular;
|
using namespace Taiyan::Gramambular;
|
||||||
|
|
||||||
/// vChewingLM is a facade for managing a set of models including
|
/// LMInstantiator is a facade for managing a set of models including
|
||||||
/// the input method language model, user phrases and excluded phrases.
|
/// the input method language model, user phrases and excluded phrases.
|
||||||
///
|
///
|
||||||
/// It is the primary model class that the input controller and grammar builder
|
/// It is the primary model class that the input controller and grammar builder
|
||||||
|
@ -41,7 +41,7 @@ using namespace Taiyan::Gramambular;
|
||||||
/// if there are valid unigrams, and use returned unigrams to produce the final
|
/// if there are valid unigrams, and use returned unigrams to produce the final
|
||||||
/// results.
|
/// results.
|
||||||
///
|
///
|
||||||
/// vChewingLM combine and transform the unigrams from the primary language
|
/// LMInstantiator combine and transform the unigrams from the primary language
|
||||||
/// model and user phrases. The process is
|
/// model and user phrases. The process is
|
||||||
///
|
///
|
||||||
/// 1) Get the original unigrams.
|
/// 1) Get the original unigrams.
|
||||||
|
@ -54,10 +54,10 @@ using namespace Taiyan::Gramambular;
|
||||||
/// model while launching and to load the user phrases anytime if the custom
|
/// model while launching and to load the user phrases anytime if the custom
|
||||||
/// files are modified. It does not keep the reference of the data pathes but
|
/// files are modified. It does not keep the reference of the data pathes but
|
||||||
/// you have to pass the paths when you ask it to do loading.
|
/// you have to pass the paths when you ask it to do loading.
|
||||||
class vChewingLM : public LanguageModel {
|
class LMInstantiator : public Taiyan::Gramambular::LanguageModel {
|
||||||
public:
|
public:
|
||||||
vChewingLM();
|
LMInstantiator();
|
||||||
~vChewingLM();
|
~LMInstantiator();
|
||||||
|
|
||||||
/// Asks to load the primary language model at the given path.
|
/// Asks to load the primary language model at the given path.
|
||||||
/// @param languageModelPath The path of the language model.
|
/// @param languageModelPath The path of the language model.
|
||||||
|
@ -83,14 +83,14 @@ public:
|
||||||
void loadPhraseReplacementMap(const char* phraseReplacementPath);
|
void loadPhraseReplacementMap(const char* phraseReplacementPath);
|
||||||
|
|
||||||
/// Not implemented since we do not have data to provide bigram function.
|
/// Not implemented since we do not have data to provide bigram function.
|
||||||
const vector<Bigram> bigramsForKeys(const string& preceedingKey, const string& key);
|
const std::vector<Taiyan::Gramambular::Bigram> bigramsForKeys(const std::string& preceedingKey, const std::string& key);
|
||||||
/// Returns a list of available unigram for the given key.
|
/// Returns a list of available unigram for the given key.
|
||||||
/// @param key A string represents the BPMF reading or a symbol key. For
|
/// @param key A std::string represents the BPMF reading or a symbol key. For
|
||||||
/// example, it you pass "ㄇㄚ", it returns "嗎", "媽", and so on.
|
/// example, it you pass "ㄇㄚ", it returns "嗎", "媽", and so on.
|
||||||
const vector<Unigram> unigramsForKey(const string& key);
|
const std::vector<Taiyan::Gramambular::Unigram> unigramsForKey(const std::string& key);
|
||||||
/// If the model has unigrams for the given key.
|
/// If the model has unigrams for the given key.
|
||||||
/// @param key The key.
|
/// @param key The key.
|
||||||
bool hasUnigramsForKey(const string& key);
|
bool hasUnigramsForKey(const std::string& key);
|
||||||
|
|
||||||
/// Enables or disables phrase replacement.
|
/// Enables or disables phrase replacement.
|
||||||
void setPhraseReplacementEnabled(bool enabled);
|
void setPhraseReplacementEnabled(bool enabled);
|
||||||
|
@ -107,10 +107,10 @@ public:
|
||||||
/// If the external converted is enabled or not.
|
/// If the external converted is enabled or not.
|
||||||
bool externalConverterEnabled();
|
bool externalConverterEnabled();
|
||||||
/// Sets a lambda to let the values of unigrams could be converted by it.
|
/// Sets a lambda to let the values of unigrams could be converted by it.
|
||||||
void setExternalConverter(std::function<string(string)> externalConverter);
|
void setExternalConverter(std::function<std::string(std::string)> externalConverter);
|
||||||
|
|
||||||
const vector<std::string> associatedPhrasesForKey(const string& key);
|
const std::vector<std::string> associatedPhrasesForKey(const std::string& key);
|
||||||
bool hasAssociatedPhrasesForKey(const string& key);
|
bool hasAssociatedPhrasesForKey(const std::string& key);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -121,9 +121,9 @@ protected:
|
||||||
/// @param insertedValues The values for unigrams already in the results.
|
/// @param insertedValues The values for unigrams already in the results.
|
||||||
/// It helps to prevent duplicated unigrams. Please note that the method
|
/// It helps to prevent duplicated unigrams. Please note that the method
|
||||||
/// has a side effect that it inserts values to `insertedValues`.
|
/// has a side effect that it inserts values to `insertedValues`.
|
||||||
const vector<Unigram> filterAndTransformUnigrams(const vector<Unigram> unigrams,
|
const std::vector<Taiyan::Gramambular::Unigram> filterAndTransformUnigrams(const std::vector<Taiyan::Gramambular::Unigram> unigrams,
|
||||||
const std::unordered_set<string>& excludedValues,
|
const std::unordered_set<std::string>& excludedValues,
|
||||||
std::unordered_set<string>& insertedValues);
|
std::unordered_set<std::string>& insertedValues);
|
||||||
|
|
||||||
ParselessLM m_languageModel;
|
ParselessLM m_languageModel;
|
||||||
CNSLM m_cnsModel;
|
CNSLM m_cnsModel;
|
||||||
|
@ -134,7 +134,7 @@ protected:
|
||||||
bool m_phraseReplacementEnabled;
|
bool m_phraseReplacementEnabled;
|
||||||
bool m_cnsEnabled;
|
bool m_cnsEnabled;
|
||||||
bool m_externalConverterEnabled;
|
bool m_externalConverterEnabled;
|
||||||
std::function<string(string)> m_externalConverter;
|
std::function<std::string(std::string)> m_externalConverter;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,17 +17,17 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "vChewingLM.h"
|
#include "LMInstantiator.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
using namespace vChewing;
|
namespace vChewing {
|
||||||
|
|
||||||
vChewingLM::vChewingLM()
|
LMInstantiator::LMInstantiator()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
vChewingLM::~vChewingLM()
|
LMInstantiator::~LMInstantiator()
|
||||||
{
|
{
|
||||||
m_languageModel.close();
|
m_languageModel.close();
|
||||||
m_userPhrases.close();
|
m_userPhrases.close();
|
||||||
|
@ -37,7 +37,7 @@ vChewingLM::~vChewingLM()
|
||||||
m_associatedPhrases.close();
|
m_associatedPhrases.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void vChewingLM::loadLanguageModel(const char* languageModelDataPath)
|
void LMInstantiator::loadLanguageModel(const char* languageModelDataPath)
|
||||||
{
|
{
|
||||||
if (languageModelDataPath) {
|
if (languageModelDataPath) {
|
||||||
m_languageModel.close();
|
m_languageModel.close();
|
||||||
|
@ -45,12 +45,12 @@ void vChewingLM::loadLanguageModel(const char* languageModelDataPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vChewingLM::isDataModelLoaded()
|
bool LMInstantiator::isDataModelLoaded()
|
||||||
{
|
{
|
||||||
return m_languageModel.isLoaded();
|
return m_languageModel.isLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
void vChewingLM::loadCNSData(const char* cnsDataPath)
|
void LMInstantiator::loadCNSData(const char* cnsDataPath)
|
||||||
{
|
{
|
||||||
if (cnsDataPath) {
|
if (cnsDataPath) {
|
||||||
m_cnsModel.close();
|
m_cnsModel.close();
|
||||||
|
@ -58,12 +58,12 @@ void vChewingLM::loadCNSData(const char* cnsDataPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vChewingLM::isCNSDataLoaded()
|
bool LMInstantiator::isCNSDataLoaded()
|
||||||
{
|
{
|
||||||
return m_cnsModel.isLoaded();
|
return m_cnsModel.isLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
void vChewingLM::loadUserPhrases(const char* userPhrasesDataPath,
|
void LMInstantiator::loadUserPhrases(const char* userPhrasesDataPath,
|
||||||
const char* excludedPhrasesDataPath)
|
const char* excludedPhrasesDataPath)
|
||||||
{
|
{
|
||||||
if (userPhrasesDataPath) {
|
if (userPhrasesDataPath) {
|
||||||
|
@ -76,7 +76,7 @@ void vChewingLM::loadUserPhrases(const char* userPhrasesDataPath,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vChewingLM::loadUserAssociatedPhrases(const char *userAssociatedPhrasesPath)
|
void LMInstantiator::loadUserAssociatedPhrases(const char *userAssociatedPhrasesPath)
|
||||||
{
|
{
|
||||||
if (userAssociatedPhrasesPath) {
|
if (userAssociatedPhrasesPath) {
|
||||||
m_associatedPhrases.close();
|
m_associatedPhrases.close();
|
||||||
|
@ -84,7 +84,7 @@ void vChewingLM::loadUserAssociatedPhrases(const char *userAssociatedPhrasesPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vChewingLM::loadPhraseReplacementMap(const char* phraseReplacementPath)
|
void LMInstantiator::loadPhraseReplacementMap(const char* phraseReplacementPath)
|
||||||
{
|
{
|
||||||
if (phraseReplacementPath) {
|
if (phraseReplacementPath) {
|
||||||
m_phraseReplacement.close();
|
m_phraseReplacement.close();
|
||||||
|
@ -92,49 +92,49 @@ void vChewingLM::loadPhraseReplacementMap(const char* phraseReplacementPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const vector<Bigram> vChewingLM::bigramsForKeys(const string& preceedingKey, const string& key)
|
const std::vector<Taiyan::Gramambular::Bigram> LMInstantiator::bigramsForKeys(const std::string& preceedingKey, const std::string& key)
|
||||||
{
|
{
|
||||||
return vector<Bigram>();
|
return std::vector<Taiyan::Gramambular::Bigram>();
|
||||||
}
|
}
|
||||||
|
|
||||||
const vector<Unigram> vChewingLM::unigramsForKey(const string& key)
|
const std::vector<Taiyan::Gramambular::Unigram> LMInstantiator::unigramsForKey(const std::string& key)
|
||||||
{
|
{
|
||||||
if (key == " ") {
|
if (key == " ") {
|
||||||
vector<Unigram> spaceUnigrams;
|
std::vector<Taiyan::Gramambular::Unigram> spaceUnigrams;
|
||||||
Unigram g;
|
Taiyan::Gramambular::Unigram g;
|
||||||
g.keyValue.key = " ";
|
g.keyValue.key = " ";
|
||||||
g.keyValue.value= " ";
|
g.keyValue.value = " ";
|
||||||
g.score = 0;
|
g.score = 0;
|
||||||
spaceUnigrams.push_back(g);
|
spaceUnigrams.push_back(g);
|
||||||
return spaceUnigrams;
|
return spaceUnigrams;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Unigram> allUnigrams;
|
std::vector<Taiyan::Gramambular::Unigram> allUnigrams;
|
||||||
vector<Unigram> userUnigrams;
|
std::vector<Taiyan::Gramambular::Unigram> userUnigrams;
|
||||||
vector<Unigram> cnsUnigrams;
|
std::vector<Taiyan::Gramambular::Unigram> cnsUnigrams;
|
||||||
|
|
||||||
unordered_set<string> excludedValues;
|
std::unordered_set<std::string> excludedValues;
|
||||||
unordered_set<string> insertedValues;
|
std::unordered_set<std::string> insertedValues;
|
||||||
|
|
||||||
if (m_excludedPhrases.hasUnigramsForKey(key)) {
|
if (m_excludedPhrases.hasUnigramsForKey(key)) {
|
||||||
vector<Unigram> excludedUnigrams = m_excludedPhrases.unigramsForKey(key);
|
std::vector<Taiyan::Gramambular::Unigram> excludedUnigrams = m_excludedPhrases.unigramsForKey(key);
|
||||||
transform(excludedUnigrams.begin(), excludedUnigrams.end(),
|
transform(excludedUnigrams.begin(), excludedUnigrams.end(),
|
||||||
inserter(excludedValues, excludedValues.end()),
|
inserter(excludedValues, excludedValues.end()),
|
||||||
[](const Unigram& u) { return u.keyValue.value; });
|
[](const Taiyan::Gramambular::Unigram& u) { return u.keyValue.value; });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_userPhrases.hasUnigramsForKey(key)) {
|
if (m_userPhrases.hasUnigramsForKey(key)) {
|
||||||
vector<Unigram> rawUserUnigrams = m_userPhrases.unigramsForKey(key);
|
std::vector<Taiyan::Gramambular::Unigram> rawUserUnigrams = m_userPhrases.unigramsForKey(key);
|
||||||
userUnigrams = filterAndTransformUnigrams(rawUserUnigrams, excludedValues, insertedValues);
|
userUnigrams = filterAndTransformUnigrams(rawUserUnigrams, excludedValues, insertedValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_languageModel.hasUnigramsForKey(key)) {
|
if (m_languageModel.hasUnigramsForKey(key)) {
|
||||||
vector<Unigram> rawGlobalUnigrams = m_languageModel.unigramsForKey(key);
|
std::vector<Taiyan::Gramambular::Unigram> rawGlobalUnigrams = m_languageModel.unigramsForKey(key);
|
||||||
allUnigrams = filterAndTransformUnigrams(rawGlobalUnigrams, excludedValues, insertedValues);
|
allUnigrams = filterAndTransformUnigrams(rawGlobalUnigrams, excludedValues, insertedValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_cnsModel.hasUnigramsForKey(key) && m_cnsEnabled) {
|
if (m_cnsModel.hasUnigramsForKey(key) && m_cnsEnabled) {
|
||||||
vector<Unigram> rawCNSUnigrams = m_cnsModel.unigramsForKey(key);
|
std::vector<Taiyan::Gramambular::Unigram> rawCNSUnigrams = m_cnsModel.unigramsForKey(key);
|
||||||
cnsUnigrams = filterAndTransformUnigrams(rawCNSUnigrams, excludedValues, insertedValues);
|
cnsUnigrams = filterAndTransformUnigrams(rawCNSUnigrams, excludedValues, insertedValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ const vector<Unigram> vChewingLM::unigramsForKey(const string& key)
|
||||||
return allUnigrams;
|
return allUnigrams;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vChewingLM::hasUnigramsForKey(const string& key)
|
bool LMInstantiator::hasUnigramsForKey(const std::string& key)
|
||||||
{
|
{
|
||||||
if (key == " ") {
|
if (key == " ") {
|
||||||
return true;
|
return true;
|
||||||
|
@ -156,65 +156,65 @@ bool vChewingLM::hasUnigramsForKey(const string& key)
|
||||||
return unigramsForKey(key).size() > 0;
|
return unigramsForKey(key).size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vChewingLM::setPhraseReplacementEnabled(bool enabled)
|
void LMInstantiator::setPhraseReplacementEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
m_phraseReplacementEnabled = enabled;
|
m_phraseReplacementEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vChewingLM::phraseReplacementEnabled()
|
bool LMInstantiator::phraseReplacementEnabled()
|
||||||
{
|
{
|
||||||
return m_phraseReplacementEnabled;
|
return m_phraseReplacementEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vChewingLM::setCNSEnabled(bool enabled)
|
void LMInstantiator::setCNSEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
m_cnsEnabled = enabled;
|
m_cnsEnabled = enabled;
|
||||||
}
|
}
|
||||||
bool vChewingLM::cnsEnabled()
|
bool LMInstantiator::cnsEnabled()
|
||||||
{
|
{
|
||||||
return m_cnsEnabled;
|
return m_cnsEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vChewingLM::setExternalConverterEnabled(bool enabled)
|
void LMInstantiator::setExternalConverterEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
m_externalConverterEnabled = enabled;
|
m_externalConverterEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vChewingLM::externalConverterEnabled()
|
bool LMInstantiator::externalConverterEnabled()
|
||||||
{
|
{
|
||||||
return m_externalConverterEnabled;
|
return m_externalConverterEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vChewingLM::setExternalConverter(std::function<string(string)> externalConverter)
|
void LMInstantiator::setExternalConverter(std::function<std::string(std::string)> externalConverter)
|
||||||
{
|
{
|
||||||
m_externalConverter = externalConverter;
|
m_externalConverter = externalConverter;
|
||||||
}
|
}
|
||||||
|
|
||||||
const vector<Unigram> vChewingLM::filterAndTransformUnigrams(const vector<Unigram> unigrams, const unordered_set<string>& excludedValues, unordered_set<string>& insertedValues)
|
const std::vector<Taiyan::Gramambular::Unigram> LMInstantiator::filterAndTransformUnigrams(const std::vector<Taiyan::Gramambular::Unigram> unigrams, const std::unordered_set<std::string>& excludedValues, std::unordered_set<std::string>& insertedValues)
|
||||||
{
|
{
|
||||||
vector<Unigram> results;
|
std::vector<Taiyan::Gramambular::Unigram> results;
|
||||||
|
|
||||||
for (auto&& unigram : unigrams) {
|
for (auto&& unigram : unigrams) {
|
||||||
// excludedValues filters out the unigrams with the original value.
|
// excludedValues filters out the unigrams with the original value.
|
||||||
// insertedValues filters out the ones with the converted value
|
// insertedValues filters out the ones with the converted value
|
||||||
string originalValue = unigram.keyValue.value;
|
std::string originalValue = unigram.keyValue.value;
|
||||||
if (excludedValues.find(originalValue) != excludedValues.end()) {
|
if (excludedValues.find(originalValue) != excludedValues.end()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
string value = originalValue;
|
std::string value = originalValue;
|
||||||
if (m_phraseReplacementEnabled) {
|
if (m_phraseReplacementEnabled) {
|
||||||
string replacement = m_phraseReplacement.valueForKey(value);
|
std::string replacement = m_phraseReplacement.valueForKey(value);
|
||||||
if (replacement != "") {
|
if (replacement != "") {
|
||||||
value = replacement;
|
value = replacement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_externalConverterEnabled && m_externalConverter) {
|
if (m_externalConverterEnabled && m_externalConverter) {
|
||||||
string replacement = m_externalConverter(value);
|
std::string replacement = m_externalConverter(value);
|
||||||
value = replacement;
|
value = replacement;
|
||||||
}
|
}
|
||||||
if (insertedValues.find(value) == insertedValues.end()) {
|
if (insertedValues.find(value) == insertedValues.end()) {
|
||||||
Unigram g;
|
Taiyan::Gramambular::Unigram g;
|
||||||
g.keyValue.value = value;
|
g.keyValue.value = value;
|
||||||
g.keyValue.key = unigram.keyValue.key;
|
g.keyValue.key = unigram.keyValue.key;
|
||||||
g.score = unigram.score;
|
g.score = unigram.score;
|
||||||
|
@ -225,12 +225,14 @@ const vector<Unigram> vChewingLM::filterAndTransformUnigrams(const vector<Unigra
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
const vector<std::string> vChewingLM::associatedPhrasesForKey(const string& key)
|
const std::vector<std::string> LMInstantiator::associatedPhrasesForKey(const std::string& key)
|
||||||
{
|
{
|
||||||
return m_associatedPhrases.valuesForKey(key);
|
return m_associatedPhrases.valuesForKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vChewingLM::hasAssociatedPhrasesForKey(const string& key)
|
bool LMInstantiator::hasAssociatedPhrasesForKey(const std::string& key)
|
||||||
{
|
{
|
||||||
return m_associatedPhrases.hasValuesForKey(key);
|
return m_associatedPhrases.hasValuesForKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace vChewing
|
|
@ -59,12 +59,7 @@ bool AssociatedPhrases::open(const char *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
LMConsolidator::FixEOF(path);
|
LMConsolidator::FixEOF(path);
|
||||||
|
LMConsolidator::ConsolidateContent(path, Preferences.shouldAutoSortAssociatedPhrasesOnLoad, true);
|
||||||
if (Preferences.shouldAutoSortAssociatedPhrasesOnLoad) {
|
|
||||||
LMConsolidator::ConsolidateContent(path, true);
|
|
||||||
} else {
|
|
||||||
LMConsolidator::ConsolidateContent(path, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = ::open(path, O_RDONLY);
|
fd = ::open(path, O_RDONLY);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
|
|
|
@ -45,8 +45,8 @@ public:
|
||||||
void close();
|
void close();
|
||||||
void dump();
|
void dump();
|
||||||
|
|
||||||
virtual const vector<Bigram> bigramsForKeys(const string& preceedingKey, const string& key);
|
virtual const std::vector<Taiyan::Gramambular::Bigram> bigramsForKeys(const string& preceedingKey, const string& key);
|
||||||
virtual const vector<Unigram> unigramsForKey(const string& key);
|
virtual const std::vector<Taiyan::Gramambular::Unigram> unigramsForKey(const string& key);
|
||||||
virtual bool hasUnigramsForKey(const string& key);
|
virtual bool hasUnigramsForKey(const string& key);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -281,14 +281,14 @@ void vChewing::CoreLM::dump()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const vector<Bigram> vChewing::CoreLM::bigramsForKeys(const string& preceedingKey, const string& key)
|
const std::vector<Taiyan::Gramambular::Bigram> vChewing::CoreLM::bigramsForKeys(const string& preceedingKey, const string& key)
|
||||||
{
|
{
|
||||||
return vector<Bigram>();
|
return std::vector<Taiyan::Gramambular::Bigram>();
|
||||||
}
|
}
|
||||||
|
|
||||||
const vector<Unigram> vChewing::CoreLM::unigramsForKey(const string& key)
|
const std::vector<Taiyan::Gramambular::Unigram> vChewing::CoreLM::unigramsForKey(const string& key)
|
||||||
{
|
{
|
||||||
vector<Unigram> v;
|
std::vector<Taiyan::Gramambular::Unigram> v;
|
||||||
map<const char *, vector<Row> >::const_iterator i = keyRowMap.find(key.c_str());
|
map<const char *, vector<Row> >::const_iterator i = keyRowMap.find(key.c_str());
|
||||||
|
|
||||||
if (i != keyRowMap.end()) {
|
if (i != keyRowMap.end()) {
|
||||||
|
|
|
@ -54,12 +54,7 @@ bool PhraseReplacementMap::open(const char *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
LMConsolidator::FixEOF(path);
|
LMConsolidator::FixEOF(path);
|
||||||
|
LMConsolidator::ConsolidateContent(path, Preferences.shouldAutoSortPhraseReplacementMapOnLoad, true);
|
||||||
if (Preferences.shouldAutoSortPhraseReplacementMapOnLoad) {
|
|
||||||
LMConsolidator::ConsolidateContent(path, true);
|
|
||||||
} else {
|
|
||||||
LMConsolidator::ConsolidateContent(path, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = ::open(path, O_RDONLY);
|
fd = ::open(path, O_RDONLY);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
|
|
|
@ -23,7 +23,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
using namespace vChewing;
|
namespace vChewing {
|
||||||
|
|
||||||
// About 20 generations.
|
// About 20 generations.
|
||||||
static const double DecayThreshould = 1.0 / 1048576.0;
|
static const double DecayThreshould = 1.0 / 1048576.0;
|
||||||
|
@ -33,8 +33,8 @@ static double Score(size_t eventCount,
|
||||||
double eventTimestamp,
|
double eventTimestamp,
|
||||||
double timestamp,
|
double timestamp,
|
||||||
double lambda);
|
double lambda);
|
||||||
static bool IsEndingPunctuation(const string& value);
|
static bool IsEndingPunctuation(const std::string& value);
|
||||||
static string WalkedNodesToKey(const std::vector<NodeAnchor>& walkedNodes,
|
static std::string WalkedNodesToKey(const std::vector<Taiyan::Gramambular::NodeAnchor>& walkedNodes,
|
||||||
size_t cursorIndex);
|
size_t cursorIndex);
|
||||||
|
|
||||||
UserOverrideModel::UserOverrideModel(size_t capacity, double decayConstant)
|
UserOverrideModel::UserOverrideModel(size_t capacity, double decayConstant)
|
||||||
|
@ -43,11 +43,11 @@ UserOverrideModel::UserOverrideModel(size_t capacity, double decayConstant)
|
||||||
m_decayExponent = log(0.5) / decayConstant;
|
m_decayExponent = log(0.5) / decayConstant;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserOverrideModel::observe(const std::vector<NodeAnchor>& walkedNodes,
|
void UserOverrideModel::observe(const std::vector<Taiyan::Gramambular::NodeAnchor>& walkedNodes,
|
||||||
size_t cursorIndex,
|
size_t cursorIndex,
|
||||||
const string& candidate,
|
const std::string& candidate,
|
||||||
double timestamp) {
|
double timestamp) {
|
||||||
string key = WalkedNodesToKey(walkedNodes, cursorIndex);
|
std::string key = WalkedNodesToKey(walkedNodes, cursorIndex);
|
||||||
auto mapIter = m_lruMap.find(key);
|
auto mapIter = m_lruMap.find(key);
|
||||||
if (mapIter == m_lruMap.end()) {
|
if (mapIter == m_lruMap.end()) {
|
||||||
auto keyValuePair = KeyObservationPair(key, Observation());
|
auto keyValuePair = KeyObservationPair(key, Observation());
|
||||||
|
@ -76,20 +76,20 @@ void UserOverrideModel::observe(const std::vector<NodeAnchor>& walkedNodes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string UserOverrideModel::suggest(const std::vector<NodeAnchor>& walkedNodes,
|
std::string UserOverrideModel::suggest(const std::vector<Taiyan::Gramambular::NodeAnchor>& walkedNodes,
|
||||||
size_t cursorIndex,
|
size_t cursorIndex,
|
||||||
double timestamp) {
|
double timestamp) {
|
||||||
string key = WalkedNodesToKey(walkedNodes, cursorIndex);
|
std::string key = WalkedNodesToKey(walkedNodes, cursorIndex);
|
||||||
auto mapIter = m_lruMap.find(key);
|
auto mapIter = m_lruMap.find(key);
|
||||||
if (mapIter == m_lruMap.end()) {
|
if (mapIter == m_lruMap.end()) {
|
||||||
return string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto listIter = mapIter->second;
|
auto listIter = mapIter->second;
|
||||||
auto& keyValuePair = *listIter;
|
auto& keyValuePair = *listIter;
|
||||||
const Observation& observation = keyValuePair.second;
|
const Observation& observation = keyValuePair.second;
|
||||||
|
|
||||||
string candidate;
|
std::string candidate;
|
||||||
double score = 0.0;
|
double score = 0.0;
|
||||||
for (auto i = observation.overrides.begin();
|
for (auto i = observation.overrides.begin();
|
||||||
i != observation.overrides.end();
|
i != observation.overrides.end();
|
||||||
|
@ -112,7 +112,7 @@ string UserOverrideModel::suggest(const std::vector<NodeAnchor>& walkedNodes,
|
||||||
return candidate;
|
return candidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserOverrideModel::Observation::update(const string& candidate,
|
void UserOverrideModel::Observation::update(const std::string& candidate,
|
||||||
double timestamp) {
|
double timestamp) {
|
||||||
count++;
|
count++;
|
||||||
auto& o = overrides[candidate];
|
auto& o = overrides[candidate];
|
||||||
|
@ -134,16 +134,16 @@ static double Score(size_t eventCount,
|
||||||
return prob * decay;
|
return prob * decay;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsEndingPunctuation(const string& value) {
|
static bool IsEndingPunctuation(const std::string& value) {
|
||||||
return value == "," || value == "。" || value== "!" || value == "?" ||
|
return value == "," || value == "。" || value== "!" || value == "?" ||
|
||||||
value == "」" || value == "』" || value== "”" || value == "’";
|
value == "」" || value == "』" || value== "”" || value == "’";
|
||||||
}
|
}
|
||||||
static string WalkedNodesToKey(const std::vector<NodeAnchor>& walkedNodes,
|
static std::string WalkedNodesToKey(const std::vector<Taiyan::Gramambular::NodeAnchor>& walkedNodes,
|
||||||
size_t cursorIndex) {
|
size_t cursorIndex) {
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
std::vector<NodeAnchor> n;
|
std::vector<Taiyan::Gramambular::NodeAnchor> n;
|
||||||
size_t ll = 0;
|
size_t ll = 0;
|
||||||
for (std::vector<NodeAnchor>::const_iterator i = walkedNodes.begin();
|
for (std::vector<Taiyan::Gramambular::NodeAnchor>::const_iterator i = walkedNodes.begin();
|
||||||
i != walkedNodes.end();
|
i != walkedNodes.end();
|
||||||
++i) {
|
++i) {
|
||||||
const auto& nn = *i;
|
const auto& nn = *i;
|
||||||
|
@ -154,19 +154,19 @@ static string WalkedNodesToKey(const std::vector<NodeAnchor>& walkedNodes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<NodeAnchor>::const_reverse_iterator r = n.rbegin();
|
std::vector<Taiyan::Gramambular::NodeAnchor>::const_reverse_iterator r = n.rbegin();
|
||||||
|
|
||||||
if (r == n.rend()) {
|
if (r == n.rend()) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
string current = (*r).node->currentKeyValue().key;
|
std::string current = (*r).node->currentKeyValue().key;
|
||||||
++r;
|
++r;
|
||||||
|
|
||||||
s.clear();
|
s.clear();
|
||||||
s.str(std::string());
|
s.str(std::string());
|
||||||
if (r != n.rend()) {
|
if (r != n.rend()) {
|
||||||
string value = (*r).node->currentKeyValue().value;
|
std::string value = (*r).node->currentKeyValue().value;
|
||||||
if (IsEndingPunctuation(value)) {
|
if (IsEndingPunctuation(value)) {
|
||||||
s << "()";
|
s << "()";
|
||||||
r = n.rend();
|
r = n.rend();
|
||||||
|
@ -181,12 +181,12 @@ static string WalkedNodesToKey(const std::vector<NodeAnchor>& walkedNodes,
|
||||||
} else {
|
} else {
|
||||||
s << "()";
|
s << "()";
|
||||||
}
|
}
|
||||||
string prev = s.str();
|
std::string prev = s.str();
|
||||||
|
|
||||||
s.clear();
|
s.clear();
|
||||||
s.str(std::string());
|
s.str(std::string());
|
||||||
if (r != n.rend()) {
|
if (r != n.rend()) {
|
||||||
string value = (*r).node->currentKeyValue().value;
|
std::string value = (*r).node->currentKeyValue().value;
|
||||||
if (IsEndingPunctuation(value)) {
|
if (IsEndingPunctuation(value)) {
|
||||||
s << "()";
|
s << "()";
|
||||||
r = n.rend();
|
r = n.rend();
|
||||||
|
@ -201,7 +201,7 @@ static string WalkedNodesToKey(const std::vector<NodeAnchor>& walkedNodes,
|
||||||
} else {
|
} else {
|
||||||
s << "()";
|
s << "()";
|
||||||
}
|
}
|
||||||
string anterior = s.str();
|
std::string anterior = s.str();
|
||||||
|
|
||||||
s.clear();
|
s.clear();
|
||||||
s.str(std::string());
|
s.str(std::string());
|
||||||
|
@ -209,3 +209,5 @@ static string WalkedNodesToKey(const std::vector<NodeAnchor>& walkedNodes,
|
||||||
|
|
||||||
return s.str();
|
return s.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace vChewing
|
||||||
|
|
|
@ -22,7 +22,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "Gramambular.h"
|
#include "Gramambular.h"
|
||||||
|
|
||||||
|
@ -34,12 +33,12 @@ class UserOverrideModel {
|
||||||
public:
|
public:
|
||||||
UserOverrideModel(size_t capacity, double decayConstant);
|
UserOverrideModel(size_t capacity, double decayConstant);
|
||||||
|
|
||||||
void observe(const std::vector<NodeAnchor>& walkedNodes,
|
void observe(const std::vector<Taiyan::Gramambular::NodeAnchor>& walkedNodes,
|
||||||
size_t cursorIndex,
|
size_t cursorIndex,
|
||||||
const string& candidate,
|
const std::string& candidate,
|
||||||
double timestamp);
|
double timestamp);
|
||||||
|
|
||||||
string suggest(const std::vector<NodeAnchor>& walkedNodes,
|
std::string suggest(const std::vector<Taiyan::Gramambular::NodeAnchor>& walkedNodes,
|
||||||
size_t cursorIndex,
|
size_t cursorIndex,
|
||||||
double timestamp);
|
double timestamp);
|
||||||
|
|
||||||
|
@ -56,7 +55,7 @@ private:
|
||||||
std::map<std::string, Override> overrides;
|
std::map<std::string, Override> overrides;
|
||||||
|
|
||||||
Observation() : count(0) {}
|
Observation() : count(0) {}
|
||||||
void update(const string& candidate, double timestamp);
|
void update(const std::string& candidate, double timestamp);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::pair<std::string, Observation> KeyObservationPair;
|
typedef std::pair<std::string, Observation> KeyObservationPair;
|
||||||
|
@ -67,7 +66,7 @@ private:
|
||||||
std::map<std::string, std::list<KeyObservationPair>::iterator> m_lruMap;
|
std::map<std::string, std::list<KeyObservationPair>::iterator> m_lruMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace vChewing
|
}; // namespace vChewing
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -60,12 +60,7 @@ bool UserPhrasesLM::open(const char *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
LMConsolidator::FixEOF(path);
|
LMConsolidator::FixEOF(path);
|
||||||
|
LMConsolidator::ConsolidateContent(path, Preferences.shouldAutoSortUserPhrasesAndExclListOnLoad, true);
|
||||||
if (Preferences.shouldAutoSortUserPhrasesAndExclListOnLoad) {
|
|
||||||
LMConsolidator::ConsolidateContent(path, true);
|
|
||||||
} else {
|
|
||||||
LMConsolidator::ConsolidateContent(path, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = ::open(path, O_RDONLY);
|
fd = ::open(path, O_RDONLY);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
|
|
|
@ -32,8 +32,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
+ (BOOL)checkIfUserLanguageModelFilesExist;
|
+ (BOOL)checkIfUserLanguageModelFilesExist;
|
||||||
+ (BOOL)checkIfUserDataFolderExists;
|
+ (BOOL)checkIfUserDataFolderExists;
|
||||||
|
|
||||||
+ (BOOL)checkIfUserPhraseExist:(NSString *)userPhrase key:(NSString *)key NS_SWIFT_NAME(checkIfExist(userPhrase:key:));
|
+ (BOOL)checkIfUserPhraseExist:(NSString *)userPhrase inputMode:(InputMode)mode key:(NSString *)key NS_SWIFT_NAME(checkIfUserPhraseExist(userPhrase:mode:key:));
|
||||||
+ (BOOL)writeUserPhrase:(NSString *)userPhrase inputMode:(InputMode)mode;
|
+ (BOOL)writeUserPhrase:(NSString *)userPhrase inputMode:(InputMode)mode areWeDuplicating:(BOOL)areWeDuplicating;
|
||||||
+ (void)setPhraseReplacementEnabled:(BOOL)phraseReplacementEnabled;
|
+ (void)setPhraseReplacementEnabled:(BOOL)phraseReplacementEnabled;
|
||||||
+ (void)setCNSEnabled:(BOOL)cnsEnabled;
|
+ (void)setCNSEnabled:(BOOL)cnsEnabled;
|
||||||
+ (NSString *)userPhrasesDataPath:(InputMode)mode;
|
+ (NSString *)userPhrasesDataPath:(InputMode)mode;
|
||||||
|
|
|
@ -20,17 +20,15 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
|
||||||
#import "mgrLangModel.h"
|
#import "mgrLangModel.h"
|
||||||
#import "mgrLangModel_Privates.h"
|
#import "mgrLangModel_Privates.h"
|
||||||
#import "vChewing-Swift.h"
|
#import "vChewing-Swift.h"
|
||||||
|
#import "LMConsolidator.h"
|
||||||
using namespace std;
|
|
||||||
using namespace vChewing;
|
|
||||||
|
|
||||||
static const int kUserOverrideModelCapacity = 500;
|
static const int kUserOverrideModelCapacity = 500;
|
||||||
static const double kObservedOverrideHalflife = 5400.0;
|
static const double kObservedOverrideHalflife = 5400.0;
|
||||||
|
|
||||||
static vChewingLM gLangModelCHT;
|
static vChewing::LMInstantiator gLangModelCHT;
|
||||||
static vChewingLM gLangModelCHS;
|
static vChewing::LMInstantiator gLangModelCHS;
|
||||||
static UserOverrideModel gUserOverrideModelCHT(kUserOverrideModelCapacity, kObservedOverrideHalflife);
|
static vChewing::UserOverrideModel gUserOverrideModelCHT(kUserOverrideModelCapacity, kObservedOverrideHalflife);
|
||||||
static UserOverrideModel gUserOverrideModelCHS(kUserOverrideModelCapacity, kObservedOverrideHalflife);
|
static vChewing::UserOverrideModel gUserOverrideModelCHS(kUserOverrideModelCapacity, kObservedOverrideHalflife);
|
||||||
|
|
||||||
static NSString *const kUserDataTemplateName = @"template-data";
|
static NSString *const kUserDataTemplateName = @"template-data";
|
||||||
static NSString *const kUserAssDataTemplateName = @"template-data";
|
static NSString *const kUserAssDataTemplateName = @"template-data";
|
||||||
|
@ -40,7 +38,7 @@ static NSString *const kTemplateExtension = @".txt";
|
||||||
|
|
||||||
@implementation mgrLangModel
|
@implementation mgrLangModel
|
||||||
|
|
||||||
static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, vChewingLM &lm)
|
static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, vChewing::LMInstantiator &lm)
|
||||||
{
|
{
|
||||||
Class cls = NSClassFromString(@"ctlInputMethod");
|
Class cls = NSClassFromString(@"ctlInputMethod");
|
||||||
NSString *dataPath = [[NSBundle bundleForClass:cls] pathForResource:filenameWithoutExtension ofType:@"txt"];
|
NSString *dataPath = [[NSBundle bundleForClass:cls] pathForResource:filenameWithoutExtension ofType:@"txt"];
|
||||||
|
@ -206,10 +204,10 @@ static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, vChewing
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (BOOL)checkIfUserPhraseExist:(NSString *)userPhrase key:(NSString *)key NS_SWIFT_NAME(checkIfExist(userPhrase:key:))
|
+ (BOOL)checkIfUserPhraseExist:(NSString *)userPhrase inputMode:(InputMode)mode key:(NSString *)key NS_SWIFT_NAME(checkIfUserPhraseExist(userPhrase:mode:key:))
|
||||||
{
|
{
|
||||||
string unigramKey = string(key.UTF8String);
|
string unigramKey = string(key.UTF8String);
|
||||||
vector<Unigram> unigrams = gLangModelCHT.unigramsForKey(unigramKey);
|
vector<vChewing::Unigram> unigrams = [mode isEqualToString:imeModeCHT] ? gLangModelCHT.unigramsForKey(unigramKey): gLangModelCHS.unigramsForKey(unigramKey);
|
||||||
string userPhraseString = string(userPhrase.UTF8String);
|
string userPhraseString = string(userPhrase.UTF8String);
|
||||||
for (auto unigram: unigrams) {
|
for (auto unigram: unigrams) {
|
||||||
if (unigram.keyValue.value == userPhraseString) {
|
if (unigram.keyValue.value == userPhraseString) {
|
||||||
|
@ -219,7 +217,7 @@ static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, vChewing
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (BOOL)writeUserPhrase:(NSString *)userPhrase inputMode:(InputMode)mode;
|
+ (BOOL)writeUserPhrase:(NSString *)userPhrase inputMode:(InputMode)mode areWeDuplicating:(BOOL)areWeDuplicating
|
||||||
{
|
{
|
||||||
if (![self checkIfUserLanguageModelFilesExist]) {
|
if (![self checkIfUserLanguageModelFilesExist]) {
|
||||||
return NO;
|
return NO;
|
||||||
|
@ -251,6 +249,11 @@ static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, vChewing
|
||||||
// [currentMarkedPhrase appendString:@"\n"];
|
// [currentMarkedPhrase appendString:@"\n"];
|
||||||
// }
|
// }
|
||||||
[currentMarkedPhrase appendString:userPhrase];
|
[currentMarkedPhrase appendString:userPhrase];
|
||||||
|
if (areWeDuplicating) {
|
||||||
|
// Do not use ASCII characters to comment here.
|
||||||
|
// Otherwise, it will be scrambled by HYPY2BPMF module shipped in the vChewing Phrase Editor.
|
||||||
|
[currentMarkedPhrase appendString:@"\t#𝙾𝚟𝚎𝚛𝚛𝚒𝚍𝚎"];
|
||||||
|
}
|
||||||
[currentMarkedPhrase appendString:@"\n"];
|
[currentMarkedPhrase appendString:@"\n"];
|
||||||
|
|
||||||
NSFileHandle *writeFile = [NSFileHandle fileHandleForUpdatingAtPath:path];
|
NSFileHandle *writeFile = [NSFileHandle fileHandleForUpdatingAtPath:path];
|
||||||
|
@ -262,9 +265,14 @@ static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, vChewing
|
||||||
[writeFile writeData:data];
|
[writeFile writeData:data];
|
||||||
[writeFile closeFile];
|
[writeFile closeFile];
|
||||||
|
|
||||||
// We use FSEventStream to monitor the change of the user phrase folder,
|
// We enforce the format consolidation here, since the pragma header will let the UserPhraseLM bypasses the consolidating process on load.
|
||||||
// so we don't have to load data here.
|
vChewing::LMConsolidator::ConsolidateContent([path UTF8String], Preferences.shouldAutoSortUserPhrasesAndExclListOnLoad, false);
|
||||||
// [self loadUserPhrases];
|
|
||||||
|
// We use FSEventStream to monitor the change of the user phrase folder,
|
||||||
|
// so we don't have to load data here unless FSEventStream is disabled by user.
|
||||||
|
if (!Preferences.shouldAutoReloadUserDataFiles) {
|
||||||
|
[self loadUserPhrases];
|
||||||
|
}
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,12 +314,12 @@ static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, vChewing
|
||||||
return [[NSBundle bundleForClass:cls] pathForResource:@"char-kanji-cns" ofType:@"txt"];
|
return [[NSBundle bundleForClass:cls] pathForResource:@"char-kanji-cns" ofType:@"txt"];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (vChewingLM *)lmCHT
|
+ (vChewing::LMInstantiator *)lmCHT
|
||||||
{
|
{
|
||||||
return &gLangModelCHT;
|
return &gLangModelCHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (vChewingLM *)lmCHS
|
+ (vChewing::LMInstantiator *)lmCHS
|
||||||
{
|
{
|
||||||
return &gLangModelCHS;
|
return &gLangModelCHS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,13 +19,13 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
|
||||||
|
|
||||||
#import "mgrLangModel.h"
|
#import "mgrLangModel.h"
|
||||||
#import "UserOverrideModel.h"
|
#import "UserOverrideModel.h"
|
||||||
#import "vChewingLM.h"
|
#import "LMInstantiator.h"
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface mgrLangModel ()
|
@interface mgrLangModel ()
|
||||||
@property (class, readonly, nonatomic) vChewing::vChewingLM *lmCHT;
|
@property (class, readonly, nonatomic) vChewing::LMInstantiator *lmCHT;
|
||||||
@property (class, readonly, nonatomic) vChewing::vChewingLM *lmCHS;
|
@property (class, readonly, nonatomic) vChewing::LMInstantiator *lmCHS;
|
||||||
@property (class, readonly, nonatomic) vChewing::UserOverrideModel *userOverrideModelCHS;
|
@property (class, readonly, nonatomic) vChewing::UserOverrideModel *userOverrideModelCHS;
|
||||||
@property (class, readonly, nonatomic) vChewing::UserOverrideModel *userOverrideModelCHT;
|
@property (class, readonly, nonatomic) vChewing::UserOverrideModel *userOverrideModelCHT;
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -17,82 +17,77 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef Bigram_h
|
#ifndef BIGRAM_H_
|
||||||
#define Bigram_h
|
#define BIGRAM_H_
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "KeyValuePair.h"
|
#include "KeyValuePair.h"
|
||||||
|
|
||||||
namespace Taiyan {
|
namespace Taiyan {
|
||||||
namespace Gramambular {
|
namespace Gramambular {
|
||||||
class Bigram {
|
class Bigram {
|
||||||
public:
|
public:
|
||||||
Bigram();
|
Bigram();
|
||||||
|
|
||||||
KeyValuePair preceedingKeyValue;
|
KeyValuePair preceedingKeyValue;
|
||||||
KeyValuePair keyValue;
|
KeyValuePair keyValue;
|
||||||
double score;
|
double score;
|
||||||
|
|
||||||
bool operator==(const Bigram& inAnother) const;
|
bool operator==(const Bigram& another) const;
|
||||||
bool operator<(const Bigram& inAnother) const;
|
bool operator<(const Bigram& another) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ostream& operator<<(ostream& inStream, const Bigram& inGram)
|
inline std::ostream& operator<<(std::ostream& stream, const Bigram& gram) {
|
||||||
{
|
std::streamsize p = stream.precision();
|
||||||
streamsize p = inStream.precision();
|
stream.precision(6);
|
||||||
inStream.precision(6);
|
stream << "(" << gram.keyValue << "|" << gram.preceedingKeyValue << ","
|
||||||
inStream << "(" << inGram.keyValue << "|" <<inGram.preceedingKeyValue << "," << inGram.score << ")";
|
<< gram.score << ")";
|
||||||
inStream.precision(p);
|
stream.precision(p);
|
||||||
return inStream;
|
return stream;
|
||||||
}
|
|
||||||
|
|
||||||
inline ostream& operator<<(ostream& inStream, const vector<Bigram>& inGrams)
|
|
||||||
{
|
|
||||||
inStream << "[" << inGrams.size() << "]=>{";
|
|
||||||
|
|
||||||
size_t index = 0;
|
|
||||||
|
|
||||||
for (vector<Bigram>::const_iterator gi = inGrams.begin() ; gi != inGrams.end() ; ++gi, ++index) {
|
|
||||||
inStream << index << "=>";
|
|
||||||
inStream << *gi;
|
|
||||||
if (gi + 1 != inGrams.end()) {
|
|
||||||
inStream << ",";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inStream << "}";
|
|
||||||
return inStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Bigram::Bigram()
|
|
||||||
: score(0.0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Bigram::operator==(const Bigram& inAnother) const
|
|
||||||
{
|
|
||||||
return preceedingKeyValue == inAnother.preceedingKeyValue && keyValue == inAnother.keyValue && score == inAnother.score;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Bigram::operator<(const Bigram& inAnother) const
|
|
||||||
{
|
|
||||||
if (preceedingKeyValue < inAnother.preceedingKeyValue) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (preceedingKeyValue == inAnother.preceedingKeyValue) {
|
|
||||||
if (keyValue < inAnother.keyValue) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (keyValue == inAnother.keyValue) {
|
|
||||||
return score < inAnother.score;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& stream,
|
||||||
|
const std::vector<Bigram>& grams) {
|
||||||
|
stream << "[" << grams.size() << "]=>{";
|
||||||
|
|
||||||
|
size_t index = 0;
|
||||||
|
|
||||||
|
for (std::vector<Bigram>::const_iterator gi = grams.begin();
|
||||||
|
gi != grams.end(); ++gi, ++index) {
|
||||||
|
stream << index << "=>";
|
||||||
|
stream << *gi;
|
||||||
|
if (gi + 1 != grams.end()) {
|
||||||
|
stream << ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stream << "}";
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Bigram::Bigram() : score(0.0) {}
|
||||||
|
|
||||||
|
inline bool Bigram::operator==(const Bigram& another) const {
|
||||||
|
return preceedingKeyValue == another.preceedingKeyValue &&
|
||||||
|
keyValue == another.keyValue && score == another.score;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Bigram::operator<(const Bigram& another) const {
|
||||||
|
if (preceedingKeyValue < another.preceedingKeyValue) {
|
||||||
|
return true;
|
||||||
|
} else if (preceedingKeyValue == another.preceedingKeyValue) {
|
||||||
|
if (keyValue < another.keyValue) {
|
||||||
|
return true;
|
||||||
|
} else if (keyValue == another.keyValue) {
|
||||||
|
return score < another.score;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} // namespace Gramambular
|
||||||
|
} // namespace Taiyan
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,202 +17,190 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BlockReadingBuilder_h
|
#ifndef BLOCKREADINGBUILDER_H_
|
||||||
#define BlockReadingBuilder_h
|
#define BLOCKREADINGBUILDER_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Grid.h"
|
#include "Grid.h"
|
||||||
#include "LanguageModel.h"
|
#include "LanguageModel.h"
|
||||||
|
|
||||||
namespace Taiyan {
|
namespace Taiyan {
|
||||||
namespace Gramambular {
|
namespace Gramambular {
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
class BlockReadingBuilder {
|
class BlockReadingBuilder {
|
||||||
public:
|
public:
|
||||||
BlockReadingBuilder(LanguageModel *inLM);
|
explicit BlockReadingBuilder(LanguageModel* lm);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
size_t length() const;
|
size_t length() const;
|
||||||
size_t cursorIndex() const;
|
size_t cursorIndex() const;
|
||||||
void setCursorIndex(size_t inNewIndex);
|
void setCursorIndex(size_t newIndex);
|
||||||
void insertReadingAtCursor(const string& inReading);
|
void insertReadingAtCursor(const std::string& reading);
|
||||||
bool deleteReadingBeforeCursor(); // backspace
|
bool deleteReadingBeforeCursor(); // backspace
|
||||||
bool deleteReadingAfterCursor(); // delete
|
bool deleteReadingAfterCursor(); // delete
|
||||||
|
|
||||||
bool removeHeadReadings(size_t count);
|
bool removeHeadReadings(size_t count);
|
||||||
|
|
||||||
void setJoinSeparator(const string& separator);
|
void setJoinSeparator(const std::string& separator);
|
||||||
const string joinSeparator() const;
|
const std::string joinSeparator() const;
|
||||||
|
|
||||||
vector<string> readings() const;
|
std::vector<std::string> readings() const;
|
||||||
|
|
||||||
Grid& grid();
|
Grid& grid();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void build();
|
void build();
|
||||||
|
|
||||||
static const string Join(vector<string>::const_iterator begin, vector<string>::const_iterator end, const string& separator);
|
static const std::string Join(std::vector<std::string>::const_iterator begin,
|
||||||
|
std::vector<std::string>::const_iterator end,
|
||||||
|
const std::string& separator);
|
||||||
|
|
||||||
//最多使用六個字組成一個詞
|
// 最多使用六個字組成一個詞
|
||||||
static const size_t MaximumBuildSpanLength = 6;
|
static const size_t MaximumBuildSpanLength = 6;
|
||||||
|
|
||||||
size_t m_cursorIndex;
|
size_t m_cursorIndex;
|
||||||
vector<string> m_readings;
|
std::vector<std::string> m_readings;
|
||||||
|
|
||||||
Grid m_grid;
|
Grid m_grid;
|
||||||
LanguageModel *m_LM;
|
LanguageModel* m_LM;
|
||||||
string m_joinSeparator;
|
std::string m_joinSeparator;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline BlockReadingBuilder::BlockReadingBuilder(LanguageModel *inLM)
|
inline BlockReadingBuilder::BlockReadingBuilder(LanguageModel* lm)
|
||||||
: m_LM(inLM)
|
: m_LM(lm), m_cursorIndex(0) {}
|
||||||
, m_cursorIndex(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void BlockReadingBuilder::clear()
|
inline void BlockReadingBuilder::clear() {
|
||||||
{
|
m_cursorIndex = 0;
|
||||||
m_cursorIndex = 0;
|
m_readings.clear();
|
||||||
m_readings.clear();
|
m_grid.clear();
|
||||||
m_grid.clear();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t BlockReadingBuilder::length() const
|
inline size_t BlockReadingBuilder::length() const { return m_readings.size(); }
|
||||||
{
|
|
||||||
return m_readings.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t BlockReadingBuilder::cursorIndex() const
|
inline size_t BlockReadingBuilder::cursorIndex() const { return m_cursorIndex; }
|
||||||
{
|
|
||||||
return m_cursorIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void BlockReadingBuilder::setCursorIndex(size_t inNewIndex)
|
inline void BlockReadingBuilder::setCursorIndex(size_t newIndex) {
|
||||||
{
|
m_cursorIndex = newIndex > m_readings.size() ? m_readings.size() : newIndex;
|
||||||
m_cursorIndex = inNewIndex > m_readings.size() ? m_readings.size() : inNewIndex;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline void BlockReadingBuilder::insertReadingAtCursor(const string& inReading)
|
inline void BlockReadingBuilder::insertReadingAtCursor(
|
||||||
{
|
const std::string& reading) {
|
||||||
m_readings.insert(m_readings.begin() + m_cursorIndex, inReading);
|
m_readings.insert(m_readings.begin() + m_cursorIndex, reading);
|
||||||
|
|
||||||
m_grid.expandGridByOneAtLocation(m_cursorIndex);
|
m_grid.expandGridByOneAtLocation(m_cursorIndex);
|
||||||
build();
|
build();
|
||||||
m_cursorIndex++;
|
m_cursorIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline vector<string> BlockReadingBuilder::readings() const
|
inline std::vector<std::string> BlockReadingBuilder::readings() const {
|
||||||
{
|
return m_readings;
|
||||||
return m_readings;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline bool BlockReadingBuilder::deleteReadingBeforeCursor()
|
inline bool BlockReadingBuilder::deleteReadingBeforeCursor() {
|
||||||
{
|
if (!m_cursorIndex) {
|
||||||
if (!m_cursorIndex) {
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
m_readings.erase(m_readings.begin() + m_cursorIndex - 1, m_readings.begin() + m_cursorIndex);
|
m_readings.erase(m_readings.begin() + m_cursorIndex - 1,
|
||||||
|
m_readings.begin() + m_cursorIndex);
|
||||||
|
m_cursorIndex--;
|
||||||
|
m_grid.shrinkGridByOneAtLocation(m_cursorIndex);
|
||||||
|
build();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool BlockReadingBuilder::deleteReadingAfterCursor() {
|
||||||
|
if (m_cursorIndex == m_readings.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_readings.erase(m_readings.begin() + m_cursorIndex,
|
||||||
|
m_readings.begin() + m_cursorIndex + 1);
|
||||||
|
m_grid.shrinkGridByOneAtLocation(m_cursorIndex);
|
||||||
|
build();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool BlockReadingBuilder::removeHeadReadings(size_t count) {
|
||||||
|
if (count > length()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
if (m_cursorIndex) {
|
||||||
m_cursorIndex--;
|
m_cursorIndex--;
|
||||||
m_grid.shrinkGridByOneAtLocation(m_cursorIndex);
|
|
||||||
build();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
m_readings.erase(m_readings.begin(), m_readings.begin() + 1);
|
||||||
|
m_grid.shrinkGridByOneAtLocation(0);
|
||||||
|
build();
|
||||||
|
}
|
||||||
|
|
||||||
inline bool BlockReadingBuilder::deleteReadingAfterCursor()
|
return true;
|
||||||
{
|
}
|
||||||
if (m_cursorIndex == m_readings.size()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_readings.erase(m_readings.begin() + m_cursorIndex, m_readings.begin() + m_cursorIndex + 1);
|
inline void BlockReadingBuilder::setJoinSeparator(
|
||||||
m_grid.shrinkGridByOneAtLocation(m_cursorIndex);
|
const std::string& separator) {
|
||||||
build();
|
m_joinSeparator = separator;
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline bool BlockReadingBuilder::removeHeadReadings(size_t count)
|
inline const std::string BlockReadingBuilder::joinSeparator() const {
|
||||||
{
|
return m_joinSeparator;
|
||||||
if (count > length()) {
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < count; i++) {
|
inline Grid& BlockReadingBuilder::grid() { return m_grid; }
|
||||||
if (m_cursorIndex) {
|
|
||||||
m_cursorIndex--;
|
|
||||||
}
|
|
||||||
m_readings.erase(m_readings.begin(), m_readings.begin() + 1);
|
|
||||||
m_grid.shrinkGridByOneAtLocation(0);
|
|
||||||
build();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
inline void BlockReadingBuilder::build() {
|
||||||
}
|
if (!m_LM) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
inline void BlockReadingBuilder::setJoinSeparator(const string& separator)
|
size_t begin = 0;
|
||||||
{
|
size_t end = m_cursorIndex + MaximumBuildSpanLength;
|
||||||
m_joinSeparator = separator;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const string BlockReadingBuilder::joinSeparator() const
|
if (m_cursorIndex < MaximumBuildSpanLength) {
|
||||||
{
|
begin = 0;
|
||||||
return m_joinSeparator;
|
} else {
|
||||||
}
|
begin = m_cursorIndex - MaximumBuildSpanLength;
|
||||||
|
}
|
||||||
|
|
||||||
inline Grid& BlockReadingBuilder::grid()
|
if (end > m_readings.size()) {
|
||||||
{
|
end = m_readings.size();
|
||||||
return m_grid;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline void BlockReadingBuilder::build()
|
for (size_t p = begin; p < end; p++) {
|
||||||
{
|
for (size_t q = 1; q <= MaximumBuildSpanLength && p + q <= end; q++) {
|
||||||
if (!m_LM) {
|
std::string combinedReading = Join(
|
||||||
return;
|
m_readings.begin() + p, m_readings.begin() + p + q, m_joinSeparator);
|
||||||
}
|
if (!m_grid.hasNodeAtLocationSpanningLengthMatchingKey(p, q,
|
||||||
|
combinedReading)) {
|
||||||
|
std::vector<Unigram> unigrams = m_LM->unigramsForKey(combinedReading);
|
||||||
|
|
||||||
size_t begin = 0;
|
if (unigrams.size() > 0) {
|
||||||
size_t end = m_cursorIndex + MaximumBuildSpanLength;
|
Node n(combinedReading, unigrams, std::vector<Bigram>());
|
||||||
|
m_grid.insertNode(n, p, q);
|
||||||
if (m_cursorIndex < MaximumBuildSpanLength) {
|
|
||||||
begin = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
begin = m_cursorIndex - MaximumBuildSpanLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end > m_readings.size()) {
|
|
||||||
end = m_readings.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t p = begin ; p < end ; p++) {
|
|
||||||
for (size_t q = 1 ; q <= MaximumBuildSpanLength && p+q <= end ; q++) {
|
|
||||||
string combinedReading = Join(m_readings.begin() + p, m_readings.begin() + p + q, m_joinSeparator);
|
|
||||||
if (!m_grid.hasNodeAtLocationSpanningLengthMatchingKey(p, q, combinedReading)) {
|
|
||||||
vector<Unigram> unigrams = m_LM->unigramsForKey(combinedReading);
|
|
||||||
|
|
||||||
if (unigrams.size() > 0) {
|
|
||||||
Node n(combinedReading, unigrams, vector<Bigram>());
|
|
||||||
m_grid.insertNode(n, p, q);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const string BlockReadingBuilder::Join(vector<string>::const_iterator begin, vector<string>::const_iterator end, const string& separator)
|
|
||||||
{
|
|
||||||
string result;
|
|
||||||
for (vector<string>::const_iterator iter = begin ; iter != end ; ) {
|
|
||||||
result += *iter;
|
|
||||||
++iter;
|
|
||||||
if (iter != end) {
|
|
||||||
result += separator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const std::string BlockReadingBuilder::Join(
|
||||||
|
std::vector<std::string>::const_iterator begin,
|
||||||
|
std::vector<std::string>::const_iterator end,
|
||||||
|
const std::string& separator) {
|
||||||
|
std::string result;
|
||||||
|
for (std::vector<std::string>::const_iterator iter = begin; iter != end;) {
|
||||||
|
result += *iter;
|
||||||
|
++iter;
|
||||||
|
if (iter != end) {
|
||||||
|
result += separator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} // namespace Gramambular
|
||||||
|
} // namespace Taiyan
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,8 +17,8 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef Gramambular_h
|
#ifndef GRAMAMBULAR_H_
|
||||||
#define Gramambular_h
|
#define GRAMAMBULAR_H_
|
||||||
|
|
||||||
#include "Bigram.h"
|
#include "Bigram.h"
|
||||||
#include "BlockReadingBuilder.h"
|
#include "BlockReadingBuilder.h"
|
||||||
|
|
|
@ -17,248 +17,207 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef Grid_h
|
#ifndef GRID_H_
|
||||||
#define Grid_h
|
#define GRID_H_
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "NodeAnchor.h"
|
#include "NodeAnchor.h"
|
||||||
#include "Span.h"
|
#include "Span.h"
|
||||||
|
|
||||||
namespace Taiyan {
|
namespace Taiyan {
|
||||||
namespace Gramambular {
|
namespace Gramambular {
|
||||||
|
|
||||||
class Grid {
|
class Grid {
|
||||||
public:
|
public:
|
||||||
void clear();
|
void clear();
|
||||||
void insertNode(const Node& inNode, size_t inLocation, size_t inSpanningLength);
|
void insertNode(const Node& node, size_t location, size_t spanningLength);
|
||||||
bool hasNodeAtLocationSpanningLengthMatchingKey(size_t inLocation, size_t inSpanningLength, const string& inKey);
|
bool hasNodeAtLocationSpanningLengthMatchingKey(size_t location,
|
||||||
|
size_t spanningLength,
|
||||||
|
const std::string& key);
|
||||||
|
|
||||||
void expandGridByOneAtLocation(size_t inLocation);
|
void expandGridByOneAtLocation(size_t location);
|
||||||
void shrinkGridByOneAtLocation(size_t inLocation);
|
void shrinkGridByOneAtLocation(size_t location);
|
||||||
|
|
||||||
size_t width() const;
|
size_t width() const;
|
||||||
vector<NodeAnchor> nodesEndingAt(size_t inLocation);
|
std::vector<NodeAnchor> nodesEndingAt(size_t location);
|
||||||
vector<NodeAnchor> nodesCrossingOrEndingAt(size_t inLocation);
|
std::vector<NodeAnchor> nodesCrossingOrEndingAt(size_t location);
|
||||||
|
|
||||||
// "Freeze" the node with the unigram that represents the selected candidate value.
|
// "Freeze" the node with the unigram that represents the selected candidate
|
||||||
// After this, the node that contains the unigram will always be evaluated to that
|
// value. After this, the node that contains the unigram will always be
|
||||||
// unigram, while all other overlapping nodes will be reset to their initial state
|
// evaluated to that unigram, while all other overlapping nodes will be reset
|
||||||
// (that is, if any of those nodes were "frozen" or fixed, they will be unfrozen.)
|
// to their initial state (that is, if any of those nodes were "frozen" or
|
||||||
NodeAnchor fixNodeSelectedCandidate(size_t location, const string& value);
|
// fixed, they will be unfrozen.)
|
||||||
|
NodeAnchor fixNodeSelectedCandidate(size_t location,
|
||||||
|
const std::string& value);
|
||||||
|
|
||||||
// Similar to fixNodeSelectedCandidate, but instead of "freezing" the node, only
|
// Similar to fixNodeSelectedCandidate, but instead of "freezing" the node,
|
||||||
// boost the unigram that represents the value with an overriding score. This
|
// only boost the unigram that represents the value with an overriding score.
|
||||||
// has the same side effect as fixNodeSelectedCandidate, which is that all other
|
// This has the same side effect as fixNodeSelectedCandidate, which is that
|
||||||
// overlapping nodes will be reset to their initial state.
|
// all other overlapping nodes will be reset to their initial state.
|
||||||
void overrideNodeScoreForSelectedCandidate(size_t location, const string& value, float overridingScore);
|
void overrideNodeScoreForSelectedCandidate(size_t location,
|
||||||
|
const std::string& value,
|
||||||
|
float overridingScore);
|
||||||
|
|
||||||
const string dumpDOT();
|
std::string dumpDOT();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
vector<Span> m_spans;
|
std::vector<Span> m_spans;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void Grid::clear()
|
inline void Grid::clear() { m_spans.clear(); }
|
||||||
{
|
|
||||||
m_spans.clear();
|
inline void Grid::insertNode(const Node& node, size_t location,
|
||||||
|
size_t spanningLength) {
|
||||||
|
if (location >= m_spans.size()) {
|
||||||
|
size_t diff = location - m_spans.size() + 1;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < diff; i++) {
|
||||||
|
m_spans.push_back(Span());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline void Grid::insertNode(const Node& inNode, size_t inLocation, size_t inSpanningLength)
|
m_spans[location].insertNodeOfLength(node, spanningLength);
|
||||||
{
|
}
|
||||||
if (inLocation >= m_spans.size()) {
|
|
||||||
size_t diff = inLocation - m_spans.size() + 1;
|
|
||||||
|
|
||||||
for (size_t i = 0 ; i < diff ; i++) {
|
inline bool Grid::hasNodeAtLocationSpanningLengthMatchingKey(
|
||||||
m_spans.push_back(Span());
|
size_t location, size_t spanningLength, const std::string& key) {
|
||||||
}
|
if (location > m_spans.size()) {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
m_spans[inLocation].insertNodeOfLength(inNode, inSpanningLength);
|
const Node* n = m_spans[location].nodeOfLength(spanningLength);
|
||||||
}
|
if (!n) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool Grid::hasNodeAtLocationSpanningLengthMatchingKey(size_t inLocation, size_t inSpanningLength, const string& inKey)
|
return key == n->key();
|
||||||
{
|
}
|
||||||
if (inLocation > m_spans.size()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Node *n = m_spans[inLocation].nodeOfLength(inSpanningLength);
|
inline void Grid::expandGridByOneAtLocation(size_t location) {
|
||||||
if (!n) {
|
if (!location || location == m_spans.size()) {
|
||||||
return false;
|
m_spans.insert(m_spans.begin() + location, Span());
|
||||||
}
|
} else {
|
||||||
|
m_spans.insert(m_spans.begin() + location, Span());
|
||||||
return inKey == n->key();
|
for (size_t i = 0; i < location; i++) {
|
||||||
}
|
// zaps overlapping spans
|
||||||
|
m_spans[i].removeNodeOfLengthGreaterThan(location - i);
|
||||||
inline void Grid::expandGridByOneAtLocation(size_t inLocation)
|
|
||||||
{
|
|
||||||
if (!inLocation || inLocation == m_spans.size()) {
|
|
||||||
m_spans.insert(m_spans.begin() + inLocation, Span());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_spans.insert(m_spans.begin() + inLocation, Span());
|
|
||||||
for (size_t i = 0 ; i < inLocation ; i++) {
|
|
||||||
// zaps overlapping spans
|
|
||||||
m_spans[i].removeNodeOfLengthGreaterThan(inLocation - i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Grid::shrinkGridByOneAtLocation(size_t inLocation)
|
|
||||||
{
|
|
||||||
if (inLocation >= m_spans.size()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_spans.erase(m_spans.begin() + inLocation);
|
|
||||||
for (size_t i = 0 ; i < inLocation ; i++) {
|
|
||||||
// zaps overlapping spans
|
|
||||||
m_spans[i].removeNodeOfLengthGreaterThan(inLocation - i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t Grid::width() const
|
|
||||||
{
|
|
||||||
return m_spans.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline vector<NodeAnchor> Grid::nodesEndingAt(size_t inLocation)
|
|
||||||
{
|
|
||||||
vector<NodeAnchor> result;
|
|
||||||
|
|
||||||
if (m_spans.size() && inLocation <= m_spans.size()) {
|
|
||||||
for (size_t i = 0 ; i < inLocation ; i++) {
|
|
||||||
Span& span = m_spans[i];
|
|
||||||
if (i + span.maximumLength() >= inLocation) {
|
|
||||||
Node *np = span.nodeOfLength(inLocation - i);
|
|
||||||
if (np) {
|
|
||||||
NodeAnchor na;
|
|
||||||
na.node = np;
|
|
||||||
na.location = i;
|
|
||||||
na.spanningLength = inLocation - i;
|
|
||||||
|
|
||||||
result.push_back(na);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline vector<NodeAnchor> Grid::nodesCrossingOrEndingAt(size_t inLocation)
|
|
||||||
{
|
|
||||||
vector<NodeAnchor> result;
|
|
||||||
|
|
||||||
if (m_spans.size() && inLocation <= m_spans.size()) {
|
|
||||||
for (size_t i = 0 ; i < inLocation ; i++) {
|
|
||||||
Span& span = m_spans[i];
|
|
||||||
|
|
||||||
if (i + span.maximumLength() >= inLocation) {
|
|
||||||
|
|
||||||
for (size_t j = 1, m = span.maximumLength(); j <= m ; j++) {
|
|
||||||
|
|
||||||
if (i + j < inLocation) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Node *np = span.nodeOfLength(j);
|
|
||||||
if (np) {
|
|
||||||
NodeAnchor na;
|
|
||||||
na.node = np;
|
|
||||||
na.location = i;
|
|
||||||
na.spanningLength = inLocation - i;
|
|
||||||
|
|
||||||
result.push_back(na);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For nodes found at the location, fix their currently-selected candidate using the supplied string value.
|
|
||||||
inline NodeAnchor Grid::fixNodeSelectedCandidate(size_t location, const string& value)
|
|
||||||
{
|
|
||||||
vector<NodeAnchor> nodes = nodesCrossingOrEndingAt(location);
|
|
||||||
NodeAnchor node;
|
|
||||||
for (auto nodeAnchor : nodes) {
|
|
||||||
auto candidates = nodeAnchor.node->candidates();
|
|
||||||
|
|
||||||
// Reset the candidate-fixed state of every node at the location.
|
|
||||||
const_cast<Node*>(nodeAnchor.node)->resetCandidate();
|
|
||||||
|
|
||||||
for (size_t i = 0, c = candidates.size(); i < c; ++i) {
|
|
||||||
if (candidates[i].value == value) {
|
|
||||||
const_cast<Node*>(nodeAnchor.node)->selectCandidateAtIndex(i);
|
|
||||||
node = nodeAnchor;
|
|
||||||
break;;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Grid::overrideNodeScoreForSelectedCandidate(size_t location, const string& value, float overridingScore)
|
|
||||||
{
|
|
||||||
vector<NodeAnchor> nodes = nodesCrossingOrEndingAt(location);
|
|
||||||
for (auto nodeAnchor : nodes) {
|
|
||||||
auto candidates = nodeAnchor.node->candidates();
|
|
||||||
|
|
||||||
// Reset the candidate-fixed state of every node at the location.
|
|
||||||
const_cast<Node*>(nodeAnchor.node)->resetCandidate();
|
|
||||||
|
|
||||||
for (size_t i = 0, c = candidates.size(); i < c; ++i) {
|
|
||||||
if (candidates[i].value == value) {
|
|
||||||
const_cast<Node*>(nodeAnchor.node)->selectFloatingCandidateAtIndex(i, overridingScore);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const string Grid::dumpDOT()
|
|
||||||
{
|
|
||||||
stringstream sst;
|
|
||||||
sst << "digraph {" << endl;
|
|
||||||
sst << "graph [ rankdir=LR ];" << endl;
|
|
||||||
sst << "BOS;" << endl;
|
|
||||||
|
|
||||||
for (size_t p = 0 ; p < m_spans.size() ; p++) {
|
|
||||||
Span& span = m_spans[p];
|
|
||||||
for (size_t ni = 0 ; ni <= span.maximumLength() ; ni++) {
|
|
||||||
Node* np = span.nodeOfLength(ni);
|
|
||||||
if (np) {
|
|
||||||
if (!p) {
|
|
||||||
sst << "BOS -> " << np->currentKeyValue().value << ";" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
sst << np->currentKeyValue().value << ";" << endl;
|
|
||||||
|
|
||||||
if (p + ni < m_spans.size()) {
|
|
||||||
Span& dstSpan = m_spans[p+ni];
|
|
||||||
for (size_t q = 0 ; q <= dstSpan.maximumLength() ; q++) {
|
|
||||||
Node *dn = dstSpan.nodeOfLength(q);
|
|
||||||
if (dn) {
|
|
||||||
sst << np->currentKeyValue().value << " -> " << dn->currentKeyValue().value << ";" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p + ni == m_spans.size()) {
|
|
||||||
sst << np->currentKeyValue().value << " -> " << "EOS;" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sst << "EOS;" << endl;
|
|
||||||
sst << "}";
|
|
||||||
return sst.str();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Grid::shrinkGridByOneAtLocation(size_t location) {
|
||||||
|
if (location >= m_spans.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_spans.erase(m_spans.begin() + location);
|
||||||
|
for (size_t i = 0; i < location; i++) {
|
||||||
|
// zaps overlapping spans
|
||||||
|
m_spans[i].removeNodeOfLengthGreaterThan(location - i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t Grid::width() const { return m_spans.size(); }
|
||||||
|
|
||||||
|
inline std::vector<NodeAnchor> Grid::nodesEndingAt(size_t location) {
|
||||||
|
std::vector<NodeAnchor> result;
|
||||||
|
|
||||||
|
if (m_spans.size() && location <= m_spans.size()) {
|
||||||
|
for (size_t i = 0; i < location; i++) {
|
||||||
|
Span& span = m_spans[i];
|
||||||
|
if (i + span.maximumLength() >= location) {
|
||||||
|
Node* np = span.nodeOfLength(location - i);
|
||||||
|
if (np) {
|
||||||
|
NodeAnchor na;
|
||||||
|
na.node = np;
|
||||||
|
na.location = i;
|
||||||
|
na.spanningLength = location - i;
|
||||||
|
|
||||||
|
result.push_back(na);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::vector<NodeAnchor> Grid::nodesCrossingOrEndingAt(size_t location) {
|
||||||
|
std::vector<NodeAnchor> result;
|
||||||
|
|
||||||
|
if (m_spans.size() && location <= m_spans.size()) {
|
||||||
|
for (size_t i = 0; i < location; i++) {
|
||||||
|
Span& span = m_spans[i];
|
||||||
|
|
||||||
|
if (i + span.maximumLength() >= location) {
|
||||||
|
for (size_t j = 1, m = span.maximumLength(); j <= m; j++) {
|
||||||
|
if (i + j < location) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* np = span.nodeOfLength(j);
|
||||||
|
if (np) {
|
||||||
|
NodeAnchor na;
|
||||||
|
na.node = np;
|
||||||
|
na.location = i;
|
||||||
|
na.spanningLength = location - i;
|
||||||
|
|
||||||
|
result.push_back(na);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For nodes found at the location, fix their currently-selected candidate using
|
||||||
|
// the supplied string value.
|
||||||
|
inline NodeAnchor Grid::fixNodeSelectedCandidate(size_t location,
|
||||||
|
const std::string& value) {
|
||||||
|
std::vector<NodeAnchor> nodes = nodesCrossingOrEndingAt(location);
|
||||||
|
NodeAnchor node;
|
||||||
|
for (auto nodeAnchor : nodes) {
|
||||||
|
auto candidates = nodeAnchor.node->candidates();
|
||||||
|
|
||||||
|
// Reset the candidate-fixed state of every node at the location.
|
||||||
|
const_cast<Node*>(nodeAnchor.node)->resetCandidate();
|
||||||
|
|
||||||
|
for (size_t i = 0, c = candidates.size(); i < c; ++i) {
|
||||||
|
if (candidates[i].value == value) {
|
||||||
|
const_cast<Node*>(nodeAnchor.node)->selectCandidateAtIndex(i);
|
||||||
|
node = nodeAnchor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Grid::overrideNodeScoreForSelectedCandidate(
|
||||||
|
size_t location, const std::string& value, float overridingScore) {
|
||||||
|
std::vector<NodeAnchor> nodes = nodesCrossingOrEndingAt(location);
|
||||||
|
for (auto nodeAnchor : nodes) {
|
||||||
|
auto candidates = nodeAnchor.node->candidates();
|
||||||
|
|
||||||
|
// Reset the candidate-fixed state of every node at the location.
|
||||||
|
const_cast<Node*>(nodeAnchor.node)->resetCandidate();
|
||||||
|
|
||||||
|
for (size_t i = 0, c = candidates.size(); i < c; ++i) {
|
||||||
|
if (candidates[i].value == value) {
|
||||||
|
const_cast<Node*>(nodeAnchor.node)
|
||||||
|
->selectFloatingCandidateAtIndex(i, overridingScore);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Gramambular
|
||||||
|
} // namespace Taiyan
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
// Copyright (c) 2011 and onwards The OpenVanilla Project (MIT License).
|
||||||
|
// All possible vChewing-specific modifications are (c) 2021 and onwards The vChewing Project (MIT-NTL 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Grid.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Taiyan {
|
||||||
|
namespace Gramambular {
|
||||||
|
|
||||||
|
std::string Grid::dumpDOT() {
|
||||||
|
std::stringstream sst;
|
||||||
|
sst << "digraph {" << std::endl;
|
||||||
|
sst << "graph [ rankdir=LR ];" << std::endl;
|
||||||
|
sst << "BOS;" << std::endl;
|
||||||
|
|
||||||
|
for (size_t p = 0; p < m_spans.size(); p++) {
|
||||||
|
Span& span = m_spans[p];
|
||||||
|
for (size_t ni = 0; ni <= span.maximumLength(); ni++) {
|
||||||
|
Node* np = span.nodeOfLength(ni);
|
||||||
|
if (np) {
|
||||||
|
if (!p) {
|
||||||
|
sst << "BOS -> " << np->currentKeyValue().value << ";" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
sst << np->currentKeyValue().value << ";" << std::endl;
|
||||||
|
|
||||||
|
if (p + ni < m_spans.size()) {
|
||||||
|
Span& dstSpan = m_spans[p + ni];
|
||||||
|
for (size_t q = 0; q <= dstSpan.maximumLength(); q++) {
|
||||||
|
Node* dn = dstSpan.nodeOfLength(q);
|
||||||
|
if (dn) {
|
||||||
|
sst << np->currentKeyValue().value << " -> "
|
||||||
|
<< dn->currentKeyValue().value << ";" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p + ni == m_spans.size()) {
|
||||||
|
sst << np->currentKeyValue().value << " -> "
|
||||||
|
<< "EOS;" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sst << "EOS;" << std::endl;
|
||||||
|
sst << "}";
|
||||||
|
return sst.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Gramambular
|
||||||
|
} // namespace Taiyan
|
|
@ -17,47 +17,43 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef KeyValuePair_h
|
#ifndef KEYVALUEPAIR_H_
|
||||||
#define KeyValuePair_h
|
#define KEYVALUEPAIR_H_
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Taiyan {
|
namespace Taiyan {
|
||||||
namespace Gramambular {
|
namespace Gramambular {
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
class KeyValuePair {
|
class KeyValuePair {
|
||||||
public:
|
public:
|
||||||
string key;
|
std::string key;
|
||||||
string value;
|
std::string value;
|
||||||
|
|
||||||
bool operator==(const KeyValuePair& inAnother) const;
|
bool operator==(const KeyValuePair& another) const;
|
||||||
bool operator<(const KeyValuePair& inAnother) const;
|
bool operator<(const KeyValuePair& another) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ostream& operator<<(ostream& inStream, const KeyValuePair& inPair)
|
inline std::ostream& operator<<(std::ostream& stream,
|
||||||
{
|
const KeyValuePair& pair) {
|
||||||
inStream << "(" << inPair.key << "," << inPair.value << ")";
|
stream << "(" << pair.key << "," << pair.value << ")";
|
||||||
return inStream;
|
return stream;
|
||||||
}
|
|
||||||
|
|
||||||
inline bool KeyValuePair::operator==(const KeyValuePair& inAnother) const
|
|
||||||
{
|
|
||||||
return key == inAnother.key && value == inAnother.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool KeyValuePair::operator<(const KeyValuePair& inAnother) const
|
|
||||||
{
|
|
||||||
if (key < inAnother.key) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (key == inAnother.key) {
|
|
||||||
return value < inAnother.value;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool KeyValuePair::operator==(const KeyValuePair& another) const {
|
||||||
|
return key == another.key && value == another.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool KeyValuePair::operator<(const KeyValuePair& another) const {
|
||||||
|
if (key < another.key) {
|
||||||
|
return true;
|
||||||
|
} else if (key == another.key) {
|
||||||
|
return value < another.value;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} // namespace Gramambular
|
||||||
|
} // namespace Taiyan
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,28 +17,28 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LanguageModel_h
|
#ifndef LANGUAGEMODEL_H_
|
||||||
#define LanguageModel_h
|
#define LANGUAGEMODEL_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Bigram.h"
|
#include "Bigram.h"
|
||||||
#include "Unigram.h"
|
#include "Unigram.h"
|
||||||
|
|
||||||
namespace Taiyan {
|
namespace Taiyan {
|
||||||
namespace Gramambular {
|
namespace Gramambular {
|
||||||
|
|
||||||
using namespace std;
|
class LanguageModel {
|
||||||
|
public:
|
||||||
class LanguageModel {
|
virtual ~LanguageModel() {}
|
||||||
public:
|
|
||||||
virtual ~LanguageModel() {}
|
|
||||||
|
|
||||||
virtual const vector<Bigram> bigramsForKeys(const string &preceedingKey, const string& key) = 0;
|
|
||||||
virtual const vector<Unigram> unigramsForKey(const string &key) = 0;
|
|
||||||
virtual bool hasUnigramsForKey(const string& key) = 0;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
virtual const std::vector<Bigram> bigramsForKeys(
|
||||||
|
const std::string& preceedingKey, const std::string& key) = 0;
|
||||||
|
virtual const std::vector<Unigram> unigramsForKey(const std::string& key) = 0;
|
||||||
|
virtual bool hasUnigramsForKey(const std::string& key) = 0;
|
||||||
|
};
|
||||||
|
} // namespace Gramambular
|
||||||
|
} // namespace Taiyan
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,208 +17,198 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef Node_h
|
#ifndef NODE_H_
|
||||||
#define Node_h
|
#define NODE_H_
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "LanguageModel.h"
|
#include "LanguageModel.h"
|
||||||
|
|
||||||
namespace Taiyan {
|
namespace Taiyan {
|
||||||
namespace Gramambular {
|
namespace Gramambular {
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
class Node {
|
class Node {
|
||||||
public:
|
public:
|
||||||
Node();
|
Node();
|
||||||
Node(const string& inKey, const vector<Unigram>& inUnigrams, const vector<Bigram>& inBigrams);
|
Node(const std::string& key, const std::vector<Unigram>& unigrams,
|
||||||
|
const std::vector<Bigram>& bigrams);
|
||||||
|
|
||||||
void primeNodeWithPreceedingKeyValues(const vector<KeyValuePair>& inKeyValues);
|
void primeNodeWithPreceedingKeyValues(
|
||||||
|
const std::vector<KeyValuePair>& keyValues);
|
||||||
|
|
||||||
bool isCandidateFixed() const;
|
bool isCandidateFixed() const;
|
||||||
const vector<KeyValuePair>& candidates() const;
|
const std::vector<KeyValuePair>& candidates() const;
|
||||||
void selectCandidateAtIndex(size_t inIndex = 0, bool inFix = true);
|
void selectCandidateAtIndex(size_t index = 0, bool fix = true);
|
||||||
void resetCandidate();
|
void resetCandidate();
|
||||||
void selectFloatingCandidateAtIndex(size_t index, double score);
|
void selectFloatingCandidateAtIndex(size_t index, double score);
|
||||||
|
|
||||||
const string& key() const;
|
const std::string& key() const;
|
||||||
double score() const;
|
double score() const;
|
||||||
// double scoreForCandidate(string &candidate) const; // Prevents the override model to remember symbols with scode -X or lower.
|
double scoreForCandidate(const std::string& candidate) const;
|
||||||
const KeyValuePair currentKeyValue() const;
|
const KeyValuePair currentKeyValue() const;
|
||||||
double highestUnigramScore() const;
|
double highestUnigramScore() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const LanguageModel* m_LM;
|
const LanguageModel* m_LM;
|
||||||
|
|
||||||
string m_key;
|
std::string m_key;
|
||||||
double m_score;
|
double m_score;
|
||||||
|
|
||||||
vector<Unigram> m_unigrams;
|
std::vector<Unigram> m_unigrams;
|
||||||
vector<KeyValuePair> m_candidates;
|
std::vector<KeyValuePair> m_candidates;
|
||||||
map<string, size_t> m_valueUnigramIndexMap;
|
std::map<std::string, size_t> m_valueUnigramIndexMap;
|
||||||
map<KeyValuePair, vector<Bigram> > m_preceedingGramBigramMap;
|
std::map<KeyValuePair, std::vector<Bigram> > m_preceedingGramBigramMap;
|
||||||
|
|
||||||
bool m_candidateFixed;
|
bool m_candidateFixed;
|
||||||
size_t m_selectedUnigramIndex;
|
size_t m_selectedUnigramIndex;
|
||||||
|
|
||||||
friend ostream& operator<<(ostream& inStream, const Node& inNode);
|
friend std::ostream& operator<<(std::ostream& stream, const Node& node);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ostream& operator<<(ostream& inStream, const Node& inNode)
|
inline std::ostream& operator<<(std::ostream& stream, const Node& node) {
|
||||||
{
|
stream << "(node,key:" << node.m_key
|
||||||
inStream << "(node,key:" << inNode.m_key << ",fixed:" << (inNode.m_candidateFixed ? "true" : "false")
|
<< ",fixed:" << (node.m_candidateFixed ? "true" : "false")
|
||||||
<< ",selected:" << inNode.m_selectedUnigramIndex
|
<< ",selected:" << node.m_selectedUnigramIndex << ","
|
||||||
<< "," << inNode.m_unigrams << ")";
|
<< node.m_unigrams << ")";
|
||||||
return inStream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Node::Node()
|
inline Node::Node()
|
||||||
: m_candidateFixed(false)
|
: m_candidateFixed(false), m_selectedUnigramIndex(0), m_score(0.0) {}
|
||||||
, m_selectedUnigramIndex(0)
|
|
||||||
, m_score(0.0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Node::Node(const string& inKey, const vector<Unigram>& inUnigrams, const vector<Bigram>& inBigrams)
|
inline Node::Node(const std::string& key, const std::vector<Unigram>& unigrams,
|
||||||
: m_key(inKey)
|
const std::vector<Bigram>& bigrams)
|
||||||
, m_unigrams(inUnigrams)
|
: m_key(key),
|
||||||
, m_candidateFixed(false)
|
m_unigrams(unigrams),
|
||||||
, m_selectedUnigramIndex(0)
|
m_candidateFixed(false),
|
||||||
, m_score(0.0)
|
m_selectedUnigramIndex(0),
|
||||||
{
|
m_score(0.0) {
|
||||||
stable_sort(m_unigrams.begin(), m_unigrams.end(), Unigram::ScoreCompare);
|
stable_sort(m_unigrams.begin(), m_unigrams.end(), Unigram::ScoreCompare);
|
||||||
|
|
||||||
if (m_unigrams.size()) {
|
if (m_unigrams.size()) {
|
||||||
m_score = m_unigrams[0].score;
|
m_score = m_unigrams[0].score;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (vector<Unigram>::const_iterator ui = m_unigrams.begin() ; ui != m_unigrams.end() ; ++ui) {
|
for (std::vector<Unigram>::const_iterator ui = m_unigrams.begin();
|
||||||
m_valueUnigramIndexMap[(*ui).keyValue.value] = i;
|
ui != m_unigrams.end(); ++ui) {
|
||||||
i++;
|
m_valueUnigramIndexMap[(*ui).keyValue.value] = i;
|
||||||
|
i++;
|
||||||
|
|
||||||
m_candidates.push_back((*ui).keyValue);
|
m_candidates.push_back((*ui).keyValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (vector<Bigram>::const_iterator bi = inBigrams.begin() ; bi != inBigrams.end() ; ++bi) {
|
for (std::vector<Bigram>::const_iterator bi = bigrams.begin();
|
||||||
m_preceedingGramBigramMap[(*bi).preceedingKeyValue].push_back(*bi);
|
bi != bigrams.end(); ++bi) {
|
||||||
}
|
m_preceedingGramBigramMap[(*bi).preceedingKeyValue].push_back(*bi);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline void Node::primeNodeWithPreceedingKeyValues(const vector<KeyValuePair>& inKeyValues)
|
inline void Node::primeNodeWithPreceedingKeyValues(
|
||||||
{
|
const std::vector<KeyValuePair>& keyValues) {
|
||||||
size_t newIndex = m_selectedUnigramIndex;
|
size_t newIndex = m_selectedUnigramIndex;
|
||||||
double max = m_score;
|
double max = m_score;
|
||||||
|
|
||||||
if (!isCandidateFixed()) {
|
if (!isCandidateFixed()) {
|
||||||
for (vector<KeyValuePair>::const_iterator kvi = inKeyValues.begin() ; kvi != inKeyValues.end() ; ++kvi) {
|
for (std::vector<KeyValuePair>::const_iterator kvi = keyValues.begin();
|
||||||
map<KeyValuePair, vector<Bigram> >::const_iterator f = m_preceedingGramBigramMap.find(*kvi);
|
kvi != keyValues.end(); ++kvi) {
|
||||||
if (f != m_preceedingGramBigramMap.end()) {
|
std::map<KeyValuePair, std::vector<Bigram> >::const_iterator f =
|
||||||
const vector<Bigram>& bigrams = (*f).second;
|
m_preceedingGramBigramMap.find(*kvi);
|
||||||
|
if (f != m_preceedingGramBigramMap.end()) {
|
||||||
|
const std::vector<Bigram>& bigrams = (*f).second;
|
||||||
|
|
||||||
for (vector<Bigram>::const_iterator bi = bigrams.begin() ; bi != bigrams.end() ; ++bi) {
|
for (std::vector<Bigram>::const_iterator bi = bigrams.begin();
|
||||||
const Bigram& bigram = *bi;
|
bi != bigrams.end(); ++bi) {
|
||||||
if (bigram.score > max) {
|
const Bigram& bigram = *bi;
|
||||||
map<string, size_t>::const_iterator uf = m_valueUnigramIndexMap.find((*bi).keyValue.value);
|
if (bigram.score > max) {
|
||||||
if (uf != m_valueUnigramIndexMap.end()) {
|
std::map<std::string, size_t>::const_iterator uf =
|
||||||
newIndex = (*uf).second;
|
m_valueUnigramIndexMap.find((*bi).keyValue.value);
|
||||||
max = bigram.score;
|
if (uf != m_valueUnigramIndexMap.end()) {
|
||||||
}
|
newIndex = (*uf).second;
|
||||||
}
|
max = bigram.score;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_score != max) {
|
|
||||||
m_score = max;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newIndex != m_selectedUnigramIndex) {
|
|
||||||
m_selectedUnigramIndex = newIndex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline bool Node::isCandidateFixed() const
|
if (m_score != max) {
|
||||||
{
|
m_score = max;
|
||||||
return m_candidateFixed;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline const vector<KeyValuePair>& Node::candidates() const
|
if (newIndex != m_selectedUnigramIndex) {
|
||||||
{
|
m_selectedUnigramIndex = newIndex;
|
||||||
return m_candidates;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Node::selectCandidateAtIndex(size_t inIndex, bool inFix)
|
|
||||||
{
|
|
||||||
if (inIndex >= m_unigrams.size()) {
|
|
||||||
m_selectedUnigramIndex = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_selectedUnigramIndex = inIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_candidateFixed = inFix;
|
|
||||||
m_score = 99;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Node::resetCandidate()
|
|
||||||
{
|
|
||||||
m_selectedUnigramIndex = 0;
|
|
||||||
m_candidateFixed = 0;
|
|
||||||
if (m_unigrams.size()) {
|
|
||||||
m_score = m_unigrams[0].score;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Node::selectFloatingCandidateAtIndex(size_t index, double score) {
|
|
||||||
if (index >= m_unigrams.size()) {
|
|
||||||
m_selectedUnigramIndex = 0;
|
|
||||||
} else {
|
|
||||||
m_selectedUnigramIndex = index;
|
|
||||||
}
|
|
||||||
m_candidateFixed = false;
|
|
||||||
m_score = score;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const string& Node::key() const
|
|
||||||
{
|
|
||||||
return m_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double Node::score() const
|
|
||||||
{
|
|
||||||
return m_score;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prevents the override model to remember symbols with scode -X or lower.
|
|
||||||
// inline double Node::scoreForCandidate(string &candidate) const
|
|
||||||
// {
|
|
||||||
// for (auto unigram : m_unigrams) {
|
|
||||||
// if (unigram.keyValue.value == candidate) {
|
|
||||||
// return unigram.score;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return 0.0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
inline double Node::highestUnigramScore() const {
|
|
||||||
if (m_unigrams.empty()) {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
return m_unigrams[0].score;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const KeyValuePair Node::currentKeyValue() const
|
|
||||||
{
|
|
||||||
if(m_selectedUnigramIndex >= m_unigrams.size()) {
|
|
||||||
return KeyValuePair();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return m_candidates[m_selectedUnigramIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool Node::isCandidateFixed() const { return m_candidateFixed; }
|
||||||
|
|
||||||
|
inline const std::vector<KeyValuePair>& Node::candidates() const {
|
||||||
|
return m_candidates;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Node::selectCandidateAtIndex(size_t index, bool fix) {
|
||||||
|
if (index >= m_unigrams.size()) {
|
||||||
|
m_selectedUnigramIndex = 0;
|
||||||
|
} else {
|
||||||
|
m_selectedUnigramIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_candidateFixed = fix;
|
||||||
|
m_score = 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Node::resetCandidate() {
|
||||||
|
m_selectedUnigramIndex = 0;
|
||||||
|
m_candidateFixed = 0;
|
||||||
|
if (m_unigrams.size()) {
|
||||||
|
m_score = m_unigrams[0].score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Node::selectFloatingCandidateAtIndex(size_t index, double score) {
|
||||||
|
if (index >= m_unigrams.size()) {
|
||||||
|
m_selectedUnigramIndex = 0;
|
||||||
|
} else {
|
||||||
|
m_selectedUnigramIndex = index;
|
||||||
|
}
|
||||||
|
m_candidateFixed = false;
|
||||||
|
m_score = score;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const std::string& Node::key() const { return m_key; }
|
||||||
|
|
||||||
|
inline double Node::score() const { return m_score; }
|
||||||
|
|
||||||
|
// Prevents the override model to remember symbols with scode -X or lower.
|
||||||
|
//inline double Node::scoreForCandidate(const std::string& candidate) const {
|
||||||
|
// for (auto unigram : m_unigrams) {
|
||||||
|
// if (unigram.keyValue.value == candidate) {
|
||||||
|
// return unigram.score;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return 0.0;
|
||||||
|
//}
|
||||||
|
|
||||||
|
inline double Node::highestUnigramScore() const {
|
||||||
|
if (m_unigrams.empty()) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
return m_unigrams[0].score;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const KeyValuePair Node::currentKeyValue() const {
|
||||||
|
if (m_selectedUnigramIndex >= m_unigrams.size()) {
|
||||||
|
return KeyValuePair();
|
||||||
|
} else {
|
||||||
|
return m_candidates[m_selectedUnigramIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace Gramambular
|
||||||
|
} // namespace Taiyan
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,55 +17,48 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef NodeAnchor_h
|
#ifndef NODEANCHOR_H_
|
||||||
#define NodeAnchor_h
|
#define NODEANCHOR_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "Node.h"
|
#include "Node.h"
|
||||||
|
|
||||||
namespace Taiyan {
|
namespace Taiyan {
|
||||||
namespace Gramambular {
|
namespace Gramambular {
|
||||||
class NodeAnchor {
|
|
||||||
public:
|
|
||||||
NodeAnchor();
|
|
||||||
const Node *node;
|
|
||||||
size_t location;
|
|
||||||
size_t spanningLength;
|
|
||||||
double accumulatedScore;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline NodeAnchor::NodeAnchor()
|
struct NodeAnchor {
|
||||||
: node(0)
|
const Node* node = nullptr;
|
||||||
, location(0)
|
size_t location = 0;
|
||||||
, spanningLength(0)
|
size_t spanningLength = 0;
|
||||||
, accumulatedScore(0.0)
|
double accumulatedScore = 0.0;
|
||||||
{
|
};
|
||||||
}
|
|
||||||
|
|
||||||
inline ostream& operator<<(ostream& inStream, const NodeAnchor& inAnchor)
|
inline std::ostream& operator<<(std::ostream& stream,
|
||||||
{
|
const NodeAnchor& anchor) {
|
||||||
inStream << "{@(" << inAnchor.location << "," << inAnchor.spanningLength << "),";
|
stream << "{@(" << anchor.location << "," << anchor.spanningLength << "),";
|
||||||
if (inAnchor.node) {
|
if (anchor.node) {
|
||||||
inStream << *(inAnchor.node);
|
stream << *(anchor.node);
|
||||||
}
|
} else {
|
||||||
else {
|
stream << "null";
|
||||||
inStream << "null";
|
|
||||||
}
|
|
||||||
inStream << "}";
|
|
||||||
return inStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ostream& operator<<(ostream& inStream, const vector<NodeAnchor>& inAnchor)
|
|
||||||
{
|
|
||||||
for (vector<NodeAnchor>::const_iterator i = inAnchor.begin() ; i != inAnchor.end() ; ++i) {
|
|
||||||
inStream << *i;
|
|
||||||
if (i + 1 != inAnchor.end()) {
|
|
||||||
inStream << "<-";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return inStream;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
stream << "}";
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& stream,
|
||||||
|
const std::vector<NodeAnchor>& anchor) {
|
||||||
|
for (std::vector<NodeAnchor>::const_iterator i = anchor.begin();
|
||||||
|
i != anchor.end(); ++i) {
|
||||||
|
stream << *i;
|
||||||
|
if (i + 1 != anchor.end()) {
|
||||||
|
stream << "<-";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
} // namespace Gramambular
|
||||||
|
} // namespace Taiyan
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,88 +17,77 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef Span_h
|
#ifndef SPAN_H_
|
||||||
#define Span_h
|
#define SPAN_H_
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "Node.h"
|
#include "Node.h"
|
||||||
|
|
||||||
namespace Taiyan {
|
namespace Taiyan {
|
||||||
namespace Gramambular {
|
namespace Gramambular {
|
||||||
class Span {
|
class Span {
|
||||||
public:
|
public:
|
||||||
Span();
|
void clear();
|
||||||
|
void insertNodeOfLength(const Node& node, size_t length);
|
||||||
|
void removeNodeOfLengthGreaterThan(size_t length);
|
||||||
|
|
||||||
void clear();
|
Node* nodeOfLength(size_t length);
|
||||||
void insertNodeOfLength(const Node& inNode, size_t inLength);
|
size_t maximumLength() const;
|
||||||
void removeNodeOfLengthGreaterThan(size_t inLength);
|
|
||||||
|
|
||||||
Node* nodeOfLength(size_t inLength);
|
protected:
|
||||||
size_t maximumLength() const;
|
std::map<size_t, Node> m_lengthNodeMap;
|
||||||
|
size_t m_maximumLength = 0;
|
||||||
|
};
|
||||||
|
|
||||||
protected:
|
inline void Span::clear() {
|
||||||
map<size_t, Node> m_lengthNodeMap;
|
m_lengthNodeMap.clear();
|
||||||
size_t m_maximumLength;
|
m_maximumLength = 0;
|
||||||
};
|
}
|
||||||
|
|
||||||
inline Span::Span()
|
inline void Span::insertNodeOfLength(const Node& node, size_t length) {
|
||||||
: m_maximumLength(0)
|
m_lengthNodeMap[length] = node;
|
||||||
{
|
if (length > m_maximumLength) {
|
||||||
}
|
m_maximumLength = length;
|
||||||
|
|
||||||
inline void Span::clear()
|
|
||||||
{
|
|
||||||
m_lengthNodeMap.clear();
|
|
||||||
m_maximumLength = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Span::insertNodeOfLength(const Node& inNode, size_t inLength)
|
|
||||||
{
|
|
||||||
m_lengthNodeMap[inLength] = inNode;
|
|
||||||
if (inLength > m_maximumLength) {
|
|
||||||
m_maximumLength = inLength;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Span::removeNodeOfLengthGreaterThan(size_t inLength)
|
|
||||||
{
|
|
||||||
if (inLength > m_maximumLength) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t max = 0;
|
|
||||||
set<size_t> removeSet;
|
|
||||||
for (map<size_t, Node>::iterator i = m_lengthNodeMap.begin(), e = m_lengthNodeMap.end() ; i != e ; ++i) {
|
|
||||||
if ((*i).first > inLength) {
|
|
||||||
removeSet.insert((*i).first);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ((*i).first > max) {
|
|
||||||
max = (*i).first;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (set<size_t>::iterator i = removeSet.begin(), e = removeSet.end(); i != e; ++i) {
|
|
||||||
m_lengthNodeMap.erase(*i);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_maximumLength = max;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Node* Span::nodeOfLength(size_t inLength)
|
|
||||||
{
|
|
||||||
map<size_t, Node>::iterator f = m_lengthNodeMap.find(inLength);
|
|
||||||
return f == m_lengthNodeMap.end() ? 0 : &(*f).second;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t Span::maximumLength() const
|
|
||||||
{
|
|
||||||
return m_maximumLength;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Span::removeNodeOfLengthGreaterThan(size_t length) {
|
||||||
|
if (length > m_maximumLength) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t max = 0;
|
||||||
|
std::set<size_t> removeSet;
|
||||||
|
for (std::map<size_t, Node>::iterator i = m_lengthNodeMap.begin(),
|
||||||
|
e = m_lengthNodeMap.end();
|
||||||
|
i != e; ++i) {
|
||||||
|
if ((*i).first > length) {
|
||||||
|
removeSet.insert((*i).first);
|
||||||
|
} else {
|
||||||
|
if ((*i).first > max) {
|
||||||
|
max = (*i).first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::set<size_t>::iterator i = removeSet.begin(), e = removeSet.end();
|
||||||
|
i != e; ++i) {
|
||||||
|
m_lengthNodeMap.erase(*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_maximumLength = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Node* Span::nodeOfLength(size_t length) {
|
||||||
|
std::map<size_t, Node>::iterator f = m_lengthNodeMap.find(length);
|
||||||
|
return f == m_lengthNodeMap.end() ? 0 : &(*f).second;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t Span::maximumLength() const { return m_maximumLength; }
|
||||||
|
} // namespace Gramambular
|
||||||
|
} // namespace Taiyan
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,80 +17,75 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef Unigram_h
|
#ifndef UNIGRAM_H_
|
||||||
#define Unigram_h
|
#define UNIGRAM_H_
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "KeyValuePair.h"
|
#include "KeyValuePair.h"
|
||||||
|
|
||||||
namespace Taiyan {
|
namespace Taiyan {
|
||||||
namespace Gramambular {
|
namespace Gramambular {
|
||||||
class Unigram {
|
|
||||||
public:
|
|
||||||
Unigram();
|
|
||||||
|
|
||||||
KeyValuePair keyValue;
|
class Unigram {
|
||||||
double score;
|
public:
|
||||||
|
Unigram();
|
||||||
|
|
||||||
bool operator==(const Unigram& inAnother) const;
|
KeyValuePair keyValue;
|
||||||
bool operator<(const Unigram& inAnother) const;
|
double score;
|
||||||
|
|
||||||
static bool ScoreCompare(const Unigram& a, const Unigram& b);
|
bool operator==(const Unigram& another) const;
|
||||||
};
|
bool operator<(const Unigram& another) const;
|
||||||
|
|
||||||
inline ostream& operator<<(ostream& inStream, const Unigram& inGram)
|
static bool ScoreCompare(const Unigram& a, const Unigram& b);
|
||||||
{
|
};
|
||||||
streamsize p = inStream.precision();
|
|
||||||
inStream.precision(6);
|
|
||||||
inStream << "(" << inGram.keyValue << "," << inGram.score << ")";
|
|
||||||
inStream.precision(p);
|
|
||||||
return inStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ostream& operator<<(ostream& inStream, const vector<Unigram>& inGrams)
|
inline std::ostream& operator<<(std::ostream& stream, const Unigram& gram) {
|
||||||
{
|
std::streamsize p = stream.precision();
|
||||||
inStream << "[" << inGrams.size() << "]=>{";
|
stream.precision(6);
|
||||||
|
stream << "(" << gram.keyValue << "," << gram.score << ")";
|
||||||
size_t index = 0;
|
stream.precision(p);
|
||||||
|
return stream;
|
||||||
for (vector<Unigram>::const_iterator gi = inGrams.begin() ; gi != inGrams.end() ; ++gi, ++index) {
|
|
||||||
inStream << index << "=>";
|
|
||||||
inStream << *gi;
|
|
||||||
if (gi + 1 != inGrams.end()) {
|
|
||||||
inStream << ",";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inStream << "}";
|
|
||||||
return inStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Unigram::Unigram()
|
|
||||||
: score(0.0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Unigram::operator==(const Unigram& inAnother) const
|
|
||||||
{
|
|
||||||
return keyValue == inAnother.keyValue && score == inAnother.score;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Unigram::operator<(const Unigram& inAnother) const
|
|
||||||
{
|
|
||||||
if (keyValue < inAnother.keyValue) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (keyValue == inAnother.keyValue) {
|
|
||||||
return score < inAnother.score;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Unigram::ScoreCompare(const Unigram& a, const Unigram& b)
|
|
||||||
{
|
|
||||||
return a.score > b.score;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& stream,
|
||||||
|
const std::vector<Unigram>& grams) {
|
||||||
|
stream << "[" << grams.size() << "]=>{";
|
||||||
|
|
||||||
|
size_t index = 0;
|
||||||
|
|
||||||
|
for (std::vector<Unigram>::const_iterator gi = grams.begin();
|
||||||
|
gi != grams.end(); ++gi, ++index) {
|
||||||
|
stream << index << "=>";
|
||||||
|
stream << *gi;
|
||||||
|
if (gi + 1 != grams.end()) {
|
||||||
|
stream << ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stream << "}";
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Unigram::Unigram() : score(0.0) {}
|
||||||
|
|
||||||
|
inline bool Unigram::operator==(const Unigram& another) const {
|
||||||
|
return keyValue == another.keyValue && score == another.score;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Unigram::operator<(const Unigram& another) const {
|
||||||
|
if (keyValue < another.keyValue) {
|
||||||
|
return true;
|
||||||
|
} else if (keyValue == another.keyValue) {
|
||||||
|
return score < another.score;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Unigram::ScoreCompare(const Unigram& a, const Unigram& b) {
|
||||||
|
return a.score > b.score;
|
||||||
|
}
|
||||||
|
} // namespace Gramambular
|
||||||
|
} // namespace Taiyan
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,67 +17,69 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABI
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef Walker_h
|
#ifndef WALKER_H_
|
||||||
#define Walker_h
|
#define WALKER_H_
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "Grid.h"
|
#include "Grid.h"
|
||||||
|
|
||||||
namespace Taiyan {
|
namespace Taiyan {
|
||||||
namespace Gramambular {
|
namespace Gramambular {
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
class Walker {
|
class Walker {
|
||||||
public:
|
public:
|
||||||
Walker(Grid* inGrid);
|
explicit Walker(Grid* inGrid);
|
||||||
const vector<NodeAnchor> reverseWalk(size_t inLocation, double inAccumulatedScore = 0.0);
|
const std::vector<NodeAnchor> reverseWalk(size_t location,
|
||||||
|
double accumulatedScore = 0.0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Grid* m_grid;
|
Grid* m_grid;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Walker::Walker(Grid* inGrid)
|
inline Walker::Walker(Grid* inGrid) : m_grid(inGrid) {}
|
||||||
: m_grid(inGrid)
|
|
||||||
{
|
inline const std::vector<NodeAnchor> Walker::reverseWalk(
|
||||||
|
size_t location, double accumulatedScore) {
|
||||||
|
if (!location || location > m_grid->width()) {
|
||||||
|
return std::vector<NodeAnchor>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::vector<NodeAnchor> > paths;
|
||||||
|
|
||||||
|
std::vector<NodeAnchor> nodes = m_grid->nodesEndingAt(location);
|
||||||
|
|
||||||
|
for (std::vector<NodeAnchor>::iterator ni = nodes.begin(); ni != nodes.end();
|
||||||
|
++ni) {
|
||||||
|
if (!(*ni).node) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const vector<NodeAnchor> Walker::reverseWalk(size_t inLocation, double inAccumulatedScore)
|
(*ni).accumulatedScore = accumulatedScore + (*ni).node->score();
|
||||||
{
|
|
||||||
if (!inLocation || inLocation > m_grid->width()) {
|
|
||||||
return vector<NodeAnchor>();
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<vector<NodeAnchor> > paths;
|
std::vector<NodeAnchor> path =
|
||||||
|
reverseWalk(location - (*ni).spanningLength, (*ni).accumulatedScore);
|
||||||
|
path.insert(path.begin(), *ni);
|
||||||
|
|
||||||
vector<NodeAnchor> nodes = m_grid->nodesEndingAt(inLocation);
|
paths.push_back(path);
|
||||||
|
}
|
||||||
|
|
||||||
for (vector<NodeAnchor>::iterator ni = nodes.begin() ; ni != nodes.end() ; ++ni) {
|
if (!paths.size()) {
|
||||||
if (!(*ni).node) {
|
return std::vector<NodeAnchor>();
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
(*ni).accumulatedScore = inAccumulatedScore + (*ni).node->score();
|
std::vector<NodeAnchor>* result = &*(paths.begin());
|
||||||
|
for (std::vector<std::vector<NodeAnchor> >::iterator pi = paths.begin();
|
||||||
vector<NodeAnchor> path = reverseWalk(inLocation - (*ni).spanningLength, (*ni).accumulatedScore);
|
pi != paths.end(); ++pi) {
|
||||||
path.insert(path.begin(), *ni);
|
if ((*pi).back().accumulatedScore > result->back().accumulatedScore) {
|
||||||
|
result = &*pi;
|
||||||
paths.push_back(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!paths.size()) {
|
|
||||||
return vector<NodeAnchor>();
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<NodeAnchor>* result = &*(paths.begin());
|
|
||||||
for (vector<vector<NodeAnchor> >::iterator pi = paths.begin() ; pi != paths.end() ; ++pi) {
|
|
||||||
if ((*pi).back().accumulatedScore > result->back().accumulatedScore) {
|
|
||||||
result = &*pi;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return *result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return *result;
|
||||||
}
|
}
|
||||||
|
} // namespace Gramambular
|
||||||
|
} // namespace Taiyan
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
182
Source/README
182
Source/README
|
@ -1,182 +0,0 @@
|
||||||
.
|
|
||||||
├── AppDelegate.swift
|
|
||||||
├── Base.lproj
|
|
||||||
│ ├── Credits.rtf
|
|
||||||
│ ├── InfoPlist.strings
|
|
||||||
│ ├── Localizable.strings
|
|
||||||
│ ├── MainMenu.xib
|
|
||||||
│ ├── preferences.xib
|
|
||||||
│ ├── template-data.txt
|
|
||||||
│ ├── template-exclude-phrases-plain-bpmf.txt
|
|
||||||
│ ├── template-exclude-phrases.txt
|
|
||||||
│ └── template-phrases-replacement.txt
|
|
||||||
├── Data
|
|
||||||
│ ├── BPMFBase.txt
|
|
||||||
│ ├── BPMFMappings.txt
|
|
||||||
│ ├── BPMFPunctuations.txt
|
|
||||||
│ ├── Makefile
|
|
||||||
│ ├── PhraseFreq.txt
|
|
||||||
│ ├── README
|
|
||||||
│ ├── Symbols.txt
|
|
||||||
│ ├── associated-phrases.cin
|
|
||||||
│ ├── bin
|
|
||||||
│ │ ├── C_Version
|
|
||||||
│ │ │ ├── Makefile
|
|
||||||
│ │ │ ├── count.bash
|
|
||||||
│ │ │ └── count.occurrence.c
|
|
||||||
│ │ ├── README
|
|
||||||
│ │ ├── Sample_Prep
|
|
||||||
│ │ │ ├── build.bash
|
|
||||||
│ │ │ └── filter.bash
|
|
||||||
│ │ ├── bpmfmap.py
|
|
||||||
│ │ ├── buildFreq.py
|
|
||||||
│ │ ├── cook-plain-bpmf.py
|
|
||||||
│ │ ├── cook.py
|
|
||||||
│ │ ├── cook_util.py
|
|
||||||
│ │ ├── count.bash
|
|
||||||
│ │ ├── count.occurrence.py
|
|
||||||
│ │ ├── disabled
|
|
||||||
│ │ │ ├── BIG5toUTF8.pl
|
|
||||||
│ │ │ ├── bpmfmap_human.py
|
|
||||||
│ │ │ ├── build4wlist.bash
|
|
||||||
│ │ │ ├── buildFreq.bash
|
|
||||||
│ │ │ ├── cook.rb
|
|
||||||
│ │ │ ├── count.occurrence.pl
|
|
||||||
│ │ │ ├── countphrase.bash
|
|
||||||
│ │ │ ├── randomShuffle.bash
|
|
||||||
│ │ │ ├── typocorrection.bash
|
|
||||||
│ │ │ └── utf8length.pl
|
|
||||||
│ │ ├── nonCJK_filter.py
|
|
||||||
│ │ ├── self-score-test.py
|
|
||||||
│ │ └── textpool.rc
|
|
||||||
│ ├── data-plain-bpmf.txt
|
|
||||||
│ ├── data.txt
|
|
||||||
│ ├── exclusion.txt
|
|
||||||
│ ├── heterophony1.list
|
|
||||||
│ ├── heterophony2.list
|
|
||||||
│ ├── heterophony3.list
|
|
||||||
│ ├── memo
|
|
||||||
│ │ ├── blacklist.txt
|
|
||||||
│ │ ├── covered_by_others.txt
|
|
||||||
│ │ ├── covered_by_singles.txt
|
|
||||||
│ │ └── falsecount.txt
|
|
||||||
│ └── phrase.occ
|
|
||||||
├── Engine
|
|
||||||
│ ├── AssociatedPhrases.cpp
|
|
||||||
│ ├── AssociatedPhrases.h
|
|
||||||
│ ├── CMakeLists.txt
|
|
||||||
│ ├── Gramambular
|
|
||||||
│ │ ├── Bigram.h
|
|
||||||
│ │ ├── BlockReadingBuilder.h
|
|
||||||
│ │ ├── Gramambular.h
|
|
||||||
│ │ ├── Grid.h
|
|
||||||
│ │ ├── KeyValuePair.h
|
|
||||||
│ │ ├── LanguageModel.h
|
|
||||||
│ │ ├── Node.h
|
|
||||||
│ │ ├── NodeAnchor.h
|
|
||||||
│ │ ├── Span.h
|
|
||||||
│ │ ├── Unigram.h
|
|
||||||
│ │ └── Walker.h
|
|
||||||
│ ├── KeyValueBlobReader.cpp
|
|
||||||
│ ├── KeyValueBlobReader.h
|
|
||||||
│ ├── KeyValueBlobReaderTest.cpp
|
|
||||||
│ ├── Mandarin
|
|
||||||
│ │ ├── CMakeLists.txt
|
|
||||||
│ │ ├── Mandarin.cpp
|
|
||||||
│ │ ├── Mandarin.h
|
|
||||||
│ │ └── MandarinTest.cpp
|
|
||||||
│ ├── McBopomofoLM.cpp
|
|
||||||
│ ├── McBopomofoLM.h
|
|
||||||
│ ├── ParselessLM.cpp
|
|
||||||
│ ├── ParselessLM.h
|
|
||||||
│ ├── ParselessLMBenchmark.cpp
|
|
||||||
│ ├── ParselessLMTest.cpp
|
|
||||||
│ ├── ParselessPhraseDB.cpp
|
|
||||||
│ ├── ParselessPhraseDB.h
|
|
||||||
│ ├── ParselessPhraseDBTest.cpp
|
|
||||||
│ ├── PhraseReplacementMap.cpp
|
|
||||||
│ ├── PhraseReplacementMap.h
|
|
||||||
│ ├── PhraseReplacementMapTest.cpp
|
|
||||||
│ ├── UserOverrideModel.cpp
|
|
||||||
│ ├── UserOverrideModel.h
|
|
||||||
│ ├── UserPhrasesLM.cpp
|
|
||||||
│ ├── UserPhrasesLM.h
|
|
||||||
│ └── UserPhrasesLMTest.cpp
|
|
||||||
├── Images
|
|
||||||
│ ├── Bopomofo.tiff
|
|
||||||
│ ├── Bopomofo@2x.tiff
|
|
||||||
│ ├── Images.xcassets
|
|
||||||
│ │ ├── AlertIcon.imageset
|
|
||||||
│ │ │ ├── 128X128.png
|
|
||||||
│ │ │ ├── 192x192.png
|
|
||||||
│ │ │ ├── 64X64.png
|
|
||||||
│ │ │ └── Contents.json
|
|
||||||
│ │ ├── AppIcon.appiconset
|
|
||||||
│ │ │ ├── 1024X1024.png
|
|
||||||
│ │ │ ├── 128X128.png
|
|
||||||
│ │ │ ├── 16X16.png
|
|
||||||
│ │ │ ├── 256X256.png
|
|
||||||
│ │ │ ├── 32X32.png
|
|
||||||
│ │ │ ├── 512X512.png
|
|
||||||
│ │ │ ├── 64X64.png
|
|
||||||
│ │ │ └── Contents.json
|
|
||||||
│ │ └── Contents.json
|
|
||||||
│ ├── PlainBopomofo.tiff
|
|
||||||
│ └── PlainBopomofo@2x.tiff
|
|
||||||
├── InputMethodController.swift
|
|
||||||
├── InputState.swift
|
|
||||||
├── Installer
|
|
||||||
│ ├── AppDelegate.swift
|
|
||||||
│ ├── ArchiveUtil.swift
|
|
||||||
│ ├── Base.lproj
|
|
||||||
│ │ └── MainMenu.xib
|
|
||||||
│ ├── BundleTranslocate.h
|
|
||||||
│ ├── BundleTranslocate.m
|
|
||||||
│ ├── Installer-Info.plist
|
|
||||||
│ ├── Installer-Prefix.pch
|
|
||||||
│ ├── McBopomofoInstaller-Bridging-Header.h
|
|
||||||
│ ├── NotarizedArchives
|
|
||||||
│ │ └── README.md
|
|
||||||
│ ├── en.lproj
|
|
||||||
│ │ ├── InfoPlist.strings
|
|
||||||
│ │ ├── License.rtf
|
|
||||||
│ │ └── Localizable.strings
|
|
||||||
│ └── zh-Hant.lproj
|
|
||||||
│ ├── InfoPlist.strings
|
|
||||||
│ ├── License.rtf
|
|
||||||
│ ├── Localizable.strings
|
|
||||||
│ └── MainMenu.xib
|
|
||||||
├── KeyHandler.h
|
|
||||||
├── KeyHandler.mm
|
|
||||||
├── KeyHandlerInput.swift
|
|
||||||
├── LanguageModelManager+Privates.h
|
|
||||||
├── LanguageModelManager.h
|
|
||||||
├── LanguageModelManager.mm
|
|
||||||
├── McBopomofo-Bridging-Header.h
|
|
||||||
├── McBopomofo-Info.plist
|
|
||||||
├── McBopomofo-Prefix.pch
|
|
||||||
├── NonModalAlertWindowController.swift
|
|
||||||
├── NonModalAlertWindowController.xib
|
|
||||||
├── Preferences.swift
|
|
||||||
├── PreferencesWindowController.swift
|
|
||||||
├── README
|
|
||||||
├── Tools
|
|
||||||
│ ├── genRTF.py
|
|
||||||
│ └── tistool.m
|
|
||||||
├── en.lproj
|
|
||||||
│ ├── Credits.rtf
|
|
||||||
│ ├── InfoPlist.strings
|
|
||||||
│ └── Localizable.strings
|
|
||||||
├── main.swift
|
|
||||||
└── zh-Hant.lproj
|
|
||||||
├── Credits.rtf
|
|
||||||
├── InfoPlist.strings
|
|
||||||
├── Localizable.strings
|
|
||||||
├── MainMenu.xib
|
|
||||||
├── preferences.xib
|
|
||||||
├── template-data.txt
|
|
||||||
├── template-exclude-phrases-plain-bpmf.txt
|
|
||||||
├── template-exclude-phrases.txt
|
|
||||||
└── template-phrases-replacement.txt
|
|
||||||
|
|
||||||
22 directories, 157 files
|
|
|
@ -24,7 +24,7 @@
|
||||||
"\"%@\" length must ≥ 2 for a user phrase." = "\"%@\" length must ≥ 2 for a user phrase.";
|
"\"%@\" length must ≥ 2 for a user phrase." = "\"%@\" length must ≥ 2 for a user phrase.";
|
||||||
"\"%@\" length should ≤ %d for a user phrase." = "\"%@\" length should ≤ %d for a user phrase.";
|
"\"%@\" length should ≤ %d for a user phrase." = "\"%@\" length should ≤ %d for a user phrase.";
|
||||||
"\"%@\" selected. ENTER to add user phrase." = "\"%@\" selected. ENTER to add user phrase.";
|
"\"%@\" selected. ENTER to add user phrase." = "\"%@\" selected. ENTER to add user phrase.";
|
||||||
"\"%@\" already exists." = "\"%@\" already exists.";
|
"\"%@\" already exists, ENTER to boost its priority." = "\"%@\" already exists, ENTER to boost its priority.";
|
||||||
"Edit Phrase Replacement Table…" = "Edit Phrase Replacement Table…";
|
"Edit Phrase Replacement Table…" = "Edit Phrase Replacement Table…";
|
||||||
"Use Phrase Replacement" = "Use Phrase Replacement";
|
"Use Phrase Replacement" = "Use Phrase Replacement";
|
||||||
"Candidates keys cannot be empty." = "Candidates keys cannot be empty.";
|
"Candidates keys cannot be empty." = "Candidates keys cannot be empty.";
|
||||||
|
|
Binary file not shown.
|
@ -24,7 +24,7 @@
|
||||||
"\"%@\" length must ≥ 2 for a user phrase." = "\"%@\" length must ≥ 2 for a user phrase.";
|
"\"%@\" length must ≥ 2 for a user phrase." = "\"%@\" length must ≥ 2 for a user phrase.";
|
||||||
"\"%@\" length should ≤ %d for a user phrase." = "\"%@\" length should ≤ %d for a user phrase.";
|
"\"%@\" length should ≤ %d for a user phrase." = "\"%@\" length should ≤ %d for a user phrase.";
|
||||||
"\"%@\" selected. ENTER to add user phrase." = "\"%@\" selected. ENTER to add user phrase.";
|
"\"%@\" selected. ENTER to add user phrase." = "\"%@\" selected. ENTER to add user phrase.";
|
||||||
"\"%@\" already exists." = "\"%@\" already exists.";
|
"\"%@\" already exists, ENTER to boost its priority." = "\"%@\" already exists, ENTER to boost its priority.";
|
||||||
"Edit Phrase Replacement Table…" = "Edit Phrase Replacement Table…";
|
"Edit Phrase Replacement Table…" = "Edit Phrase Replacement Table…";
|
||||||
"Use Phrase Replacement" = "Use Phrase Replacement";
|
"Use Phrase Replacement" = "Use Phrase Replacement";
|
||||||
"Candidates keys cannot be empty." = "Candidates keys cannot be empty.";
|
"Candidates keys cannot be empty." = "Candidates keys cannot be empty.";
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
"\"%@\" length must ≥ 2 for a user phrase." = "「%@」もう1つ文字のお選びを。";
|
"\"%@\" length must ≥ 2 for a user phrase." = "「%@」もう1つ文字のお選びを。";
|
||||||
"\"%@\" length should ≤ %d for a user phrase." = "「%@」文字数過剰で登録不可、%d 文字以内にして下さい。";
|
"\"%@\" length should ≤ %d for a user phrase." = "「%@」文字数過剰で登録不可、%d 文字以内にして下さい。";
|
||||||
"\"%@\" selected. ENTER to add user phrase." = "「%@」を ENTER で辞書に登録。";
|
"\"%@\" selected. ENTER to add user phrase." = "「%@」を ENTER で辞書に登録。";
|
||||||
"\"%@\" already exists." = "「%@」は既存語彙である。";
|
"\"%@\" already exists, ENTER to boost its priority." = "「%@」は既存語彙であり、ENTER で最優先にする。";
|
||||||
"Edit Phrase Replacement Table…" = "言葉置換表を編集…";
|
"Edit Phrase Replacement Table…" = "言葉置換表を編集…";
|
||||||
"Use Phrase Replacement" = "言葉置換機能";
|
"Use Phrase Replacement" = "言葉置換機能";
|
||||||
"Candidates keys cannot be empty." = "言選り用キー陣列に何かキーをご登録ください。";
|
"Candidates keys cannot be empty." = "言選り用キー陣列に何かキーをご登録ください。";
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
"\"%@\" length must ≥ 2 for a user phrase." = "「%@」字数不足以自订语汇。";
|
"\"%@\" length must ≥ 2 for a user phrase." = "「%@」字数不足以自订语汇。";
|
||||||
"\"%@\" length should ≤ %d for a user phrase." = "「%@」字数超过 %d、无法自订。";
|
"\"%@\" length should ≤ %d for a user phrase." = "「%@」字数超过 %d、无法自订。";
|
||||||
"\"%@\" selected. ENTER to add user phrase." = "「%@」敲 Enter 添入自订语汇。";
|
"\"%@\" selected. ENTER to add user phrase." = "「%@」敲 Enter 添入自订语汇。";
|
||||||
"\"%@\" already exists." = "「%@」已存在。";
|
"\"%@\" already exists, ENTER to boost its priority." = "「%@」已存在,敲 ENTER 以提升其权重。";
|
||||||
"Edit Phrase Replacement Table…" = "编辑语汇置换表…";
|
"Edit Phrase Replacement Table…" = "编辑语汇置换表…";
|
||||||
"Use Phrase Replacement" = "使用语汇置换";
|
"Use Phrase Replacement" = "使用语汇置换";
|
||||||
"Candidates keys cannot be empty." = "您必须指定选字键。";
|
"Candidates keys cannot be empty." = "您必须指定选字键。";
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
"\"%@\" length must ≥ 2 for a user phrase." = "「%@」字數不足以自訂語彙。";
|
"\"%@\" length must ≥ 2 for a user phrase." = "「%@」字數不足以自訂語彙。";
|
||||||
"\"%@\" length should ≤ %d for a user phrase." = "「%@」字數超過 %d、無法自訂。";
|
"\"%@\" length should ≤ %d for a user phrase." = "「%@」字數超過 %d、無法自訂。";
|
||||||
"\"%@\" selected. ENTER to add user phrase." = "「%@」敲 Enter 添入自訂語彙。";
|
"\"%@\" selected. ENTER to add user phrase." = "「%@」敲 Enter 添入自訂語彙。";
|
||||||
"\"%@\" already exists." = "「%@」已存在。";
|
"\"%@\" already exists, ENTER to boost its priority." = "「%@」已存在,敲 ENTER 以提升其權重。";
|
||||||
"Edit Phrase Replacement Table…" = "編輯語彙置換表…";
|
"Edit Phrase Replacement Table…" = "編輯語彙置換表…";
|
||||||
"Use Phrase Replacement" = "使用語彙置換";
|
"Use Phrase Replacement" = "使用語彙置換";
|
||||||
"Candidates keys cannot be empty." = "您必須指定選字鍵。";
|
"Candidates keys cannot be empty." = "您必須指定選字鍵。";
|
||||||
|
|
|
@ -86,7 +86,7 @@ extension RangeReplaceableCollection where Element: Hashable {
|
||||||
|
|
||||||
let menuItem_vChewingDachen = NSMenuItem()
|
let menuItem_vChewingDachen = NSMenuItem()
|
||||||
menuItem_vChewingDachen.title = String(format: NSLocalizedString("vChewing Dachen (Not Finished Yet)", comment: ""))
|
menuItem_vChewingDachen.title = String(format: NSLocalizedString("vChewing Dachen (Not Finished Yet)", comment: ""))
|
||||||
menuItem_vChewingDachen.representedObject = String("org.atelierInmu.keyboardlayout.vChewingKeyLayout.zhuyindachen")
|
menuItem_vChewingDachen.representedObject = String("org.atelierInmu.keyboardlayout.vChewingKeyLayout.vChewingDachen")
|
||||||
basisKeyboardLayoutButton.menu?.addItem(menuItem_vChewingDachen)
|
basisKeyboardLayoutButton.menu?.addItem(menuItem_vChewingDachen)
|
||||||
|
|
||||||
let basisKeyboardLayoutID = Preferences.basisKeyboardLayout
|
let basisKeyboardLayoutID = Preferences.basisKeyboardLayout
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
<key>UpdateInfoSite</key>
|
<key>UpdateInfoSite</key>
|
||||||
<string>https://gitee.com/vchewing/vChewing-macOS</string>
|
<string>https://gitee.com/vchewing/vChewing-macOS</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1922</string>
|
<string>1923</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.3.3</string>
|
<string>1.3.4</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
5B11328927B94CFB00E58451 /* AppleKeyboardConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B11328827B94CFB00E58451 /* AppleKeyboardConverter.swift */; };
|
5B11328927B94CFB00E58451 /* AppleKeyboardConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B11328827B94CFB00E58451 /* AppleKeyboardConverter.swift */; };
|
||||||
5B2DB16F27AF6891006D874E /* data-chs.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5B2DB16D27AF6891006D874E /* data-chs.txt */; };
|
5B2DB16F27AF6891006D874E /* data-chs.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5B2DB16D27AF6891006D874E /* data-chs.txt */; };
|
||||||
5B2DB17027AF6891006D874E /* data-cht.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5B2DB16E27AF6891006D874E /* data-cht.txt */; };
|
5B2DB17027AF6891006D874E /* data-cht.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5B2DB16E27AF6891006D874E /* data-cht.txt */; };
|
||||||
5B30F11327BA568800484E24 /* vChewingKeyLayout.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */; };
|
|
||||||
5B62A31727AE73A700A19448 /* unzip.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A30927AE73A700A19448 /* unzip.m */; };
|
5B62A31727AE73A700A19448 /* unzip.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A30927AE73A700A19448 /* unzip.m */; };
|
||||||
5B62A31827AE73A700A19448 /* zip.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A30A27AE73A700A19448 /* zip.m */; };
|
5B62A31827AE73A700A19448 /* zip.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A30A27AE73A700A19448 /* zip.m */; };
|
||||||
5B62A31927AE73A700A19448 /* ioapi.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A30B27AE73A700A19448 /* ioapi.m */; };
|
5B62A31927AE73A700A19448 /* ioapi.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A30B27AE73A700A19448 /* ioapi.m */; };
|
||||||
|
@ -50,6 +49,12 @@
|
||||||
5BD05C6827B2BBEF004C4F1D /* Content.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6327B2BBEF004C4F1D /* Content.swift */; };
|
5BD05C6827B2BBEF004C4F1D /* Content.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6327B2BBEF004C4F1D /* Content.swift */; };
|
||||||
5BD05C6927B2BBEF004C4F1D /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6427B2BBEF004C4F1D /* WindowController.swift */; };
|
5BD05C6927B2BBEF004C4F1D /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6427B2BBEF004C4F1D /* WindowController.swift */; };
|
||||||
5BD05C6A27B2BBEF004C4F1D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6527B2BBEF004C4F1D /* ViewController.swift */; };
|
5BD05C6A27B2BBEF004C4F1D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6527B2BBEF004C4F1D /* ViewController.swift */; };
|
||||||
|
5BDC5CAB27C2873D00E1CCE2 /* Grid.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC5CAA27C2873D00E1CCE2 /* Grid.mm */; };
|
||||||
|
5BDC5CB327C28E8B00E1CCE2 /* icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 5BDC5CB227C28E8B00E1CCE2 /* icon.icns */; };
|
||||||
|
5BDC5CB527C28E8B00E1CCE2 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC5CB427C28E8B00E1CCE2 /* ShareViewController.swift */; };
|
||||||
|
5BDC5CB827C28E8B00E1CCE2 /* ShareViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BDC5CB627C28E8B00E1CCE2 /* ShareViewController.xib */; };
|
||||||
|
5BDC5CBD27C28E8B00E1CCE2 /* KeyboardExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 5BDC5CB027C28E8B00E1CCE2 /* KeyboardExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
|
5BDC5CC227C2941F00E1CCE2 /* vChewingKeyLayout.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */; };
|
||||||
5BDCBB2E27B4E67A00D0CC59 /* vChewingPhraseEditor.app in Resources */ = {isa = PBXBuildFile; fileRef = 5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */; };
|
5BDCBB2E27B4E67A00D0CC59 /* vChewingPhraseEditor.app in Resources */ = {isa = PBXBuildFile; fileRef = 5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */; };
|
||||||
5BE78BD927B3775B005EA1BE /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE78BD827B37750005EA1BE /* ctlAboutWindow.swift */; };
|
5BE78BD927B3775B005EA1BE /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE78BD827B37750005EA1BE /* ctlAboutWindow.swift */; };
|
||||||
5BE78BDD27B3776D005EA1BE /* frmAboutWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BE78BDA27B37764005EA1BE /* frmAboutWindow.xib */; };
|
5BE78BDD27B3776D005EA1BE /* frmAboutWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BE78BDA27B37764005EA1BE /* frmAboutWindow.xib */; };
|
||||||
|
@ -68,7 +73,7 @@
|
||||||
6ACC3D442793701600F1B140 /* ParselessPhraseDB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6ACC3D402793701600F1B140 /* ParselessPhraseDB.cpp */; };
|
6ACC3D442793701600F1B140 /* ParselessPhraseDB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6ACC3D402793701600F1B140 /* ParselessPhraseDB.cpp */; };
|
||||||
6ACC3D452793701600F1B140 /* ParselessLM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6ACC3D422793701600F1B140 /* ParselessLM.cpp */; };
|
6ACC3D452793701600F1B140 /* ParselessLM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6ACC3D422793701600F1B140 /* ParselessLM.cpp */; };
|
||||||
D41355D8278D74B5005E5CBD /* mgrLangModel.mm in Sources */ = {isa = PBXBuildFile; fileRef = D41355D7278D7409005E5CBD /* mgrLangModel.mm */; };
|
D41355D8278D74B5005E5CBD /* mgrLangModel.mm in Sources */ = {isa = PBXBuildFile; fileRef = D41355D7278D7409005E5CBD /* mgrLangModel.mm */; };
|
||||||
D41355DB278E6D17005E5CBD /* vChewingLM.mm in Sources */ = {isa = PBXBuildFile; fileRef = D41355D9278E6D17005E5CBD /* vChewingLM.mm */; };
|
D41355DB278E6D17005E5CBD /* LMInstantiator.mm in Sources */ = {isa = PBXBuildFile; fileRef = D41355D9278E6D17005E5CBD /* LMInstantiator.mm */; };
|
||||||
D41355DE278EA3ED005E5CBD /* UserPhrasesLM.mm in Sources */ = {isa = PBXBuildFile; fileRef = D41355DC278EA3ED005E5CBD /* UserPhrasesLM.mm */; };
|
D41355DE278EA3ED005E5CBD /* UserPhrasesLM.mm in Sources */ = {isa = PBXBuildFile; fileRef = D41355DC278EA3ED005E5CBD /* UserPhrasesLM.mm */; };
|
||||||
D427F76C278CA2B0004A2160 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D427F76B278CA1BA004A2160 /* AppDelegate.swift */; };
|
D427F76C278CA2B0004A2160 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D427F76B278CA1BA004A2160 /* AppDelegate.swift */; };
|
||||||
D44FB74D2792189A003C80A6 /* PhraseReplacementMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = D44FB74B2792189A003C80A6 /* PhraseReplacementMap.mm */; };
|
D44FB74D2792189A003C80A6 /* PhraseReplacementMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = D44FB74B2792189A003C80A6 /* PhraseReplacementMap.mm */; };
|
||||||
|
@ -96,6 +101,13 @@
|
||||||
remoteGlobalIDString = 5BD05BB727B2A429004C4F1D;
|
remoteGlobalIDString = 5BD05BB727B2A429004C4F1D;
|
||||||
remoteInfo = vChewingPhraseEditor;
|
remoteInfo = vChewingPhraseEditor;
|
||||||
};
|
};
|
||||||
|
5BDC5CBB27C28E8B00E1CCE2 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 6A0D4E9415FC0CFA00ABF4B3 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 5BDC5CAF27C28E8B00E1CCE2;
|
||||||
|
remoteInfo = KeyboardExtension;
|
||||||
|
};
|
||||||
6A38BC2515FC131100A8A51F /* PBXContainerItemProxy */ = {
|
6A38BC2515FC131100A8A51F /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = 6A0D4E9415FC0CFA00ABF4B3 /* Project object */;
|
containerPortal = 6A0D4E9415FC0CFA00ABF4B3 /* Project object */;
|
||||||
|
@ -112,6 +124,20 @@
|
||||||
};
|
};
|
||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
5BDC5CBE27C28E8B00E1CCE2 /* Embed App Extensions */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "";
|
||||||
|
dstSubfolderSpec = 13;
|
||||||
|
files = (
|
||||||
|
5BDC5CBD27C28E8B00E1CCE2 /* KeyboardExtension.appex in Embed App Extensions */,
|
||||||
|
);
|
||||||
|
name = "Embed App Extensions";
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
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>"; };
|
||||||
|
@ -195,6 +221,13 @@
|
||||||
5BD05C6327B2BBEF004C4F1D /* Content.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Content.swift; sourceTree = "<group>"; };
|
5BD05C6327B2BBEF004C4F1D /* Content.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Content.swift; sourceTree = "<group>"; };
|
||||||
5BD05C6427B2BBEF004C4F1D /* WindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = "<group>"; };
|
5BD05C6427B2BBEF004C4F1D /* WindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = "<group>"; };
|
||||||
5BD05C6527B2BBEF004C4F1D /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
5BD05C6527B2BBEF004C4F1D /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
||||||
|
5BDC5CAA27C2873D00E1CCE2 /* Grid.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Grid.mm; sourceTree = "<group>"; };
|
||||||
|
5BDC5CB027C28E8B00E1CCE2 /* KeyboardExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = KeyboardExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
5BDC5CB227C28E8B00E1CCE2 /* icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = icon.icns; sourceTree = "<group>"; };
|
||||||
|
5BDC5CB427C28E8B00E1CCE2 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
|
||||||
|
5BDC5CB727C28E8B00E1CCE2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ShareViewController.xib; sourceTree = "<group>"; };
|
||||||
|
5BDC5CB927C28E8B00E1CCE2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
5BDC5CBA27C28E8B00E1CCE2 /* KeyboardExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = KeyboardExtension.entitlements; sourceTree = "<group>"; };
|
||||||
5BDCBB4227B4F6C600D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/MainMenu.strings"; sourceTree = "<group>"; };
|
5BDCBB4227B4F6C600D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/MainMenu.strings"; sourceTree = "<group>"; };
|
||||||
5BDCBB4327B4F6C600D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/frmAboutWindow.strings"; sourceTree = "<group>"; };
|
5BDCBB4327B4F6C600D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/frmAboutWindow.strings"; sourceTree = "<group>"; };
|
||||||
5BDCBB4527B4F6C600D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "Source/WindowNIBs/zh-Hant.lproj/frmPrefWindow.strings"; sourceTree = "<group>"; };
|
5BDCBB4527B4F6C600D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "Source/WindowNIBs/zh-Hant.lproj/frmPrefWindow.strings"; sourceTree = "<group>"; };
|
||||||
|
@ -243,8 +276,8 @@
|
||||||
6ACC3D432793701600F1B140 /* ParselessLM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParselessLM.h; sourceTree = "<group>"; };
|
6ACC3D432793701600F1B140 /* ParselessLM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParselessLM.h; sourceTree = "<group>"; };
|
||||||
D41355D6278D7409005E5CBD /* mgrLangModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mgrLangModel.h; sourceTree = "<group>"; };
|
D41355D6278D7409005E5CBD /* mgrLangModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mgrLangModel.h; sourceTree = "<group>"; };
|
||||||
D41355D7278D7409005E5CBD /* mgrLangModel.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = mgrLangModel.mm; sourceTree = "<group>"; };
|
D41355D7278D7409005E5CBD /* mgrLangModel.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = mgrLangModel.mm; sourceTree = "<group>"; };
|
||||||
D41355D9278E6D17005E5CBD /* vChewingLM.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = vChewingLM.mm; sourceTree = "<group>"; };
|
D41355D9278E6D17005E5CBD /* LMInstantiator.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = LMInstantiator.mm; sourceTree = "<group>"; };
|
||||||
D41355DA278E6D17005E5CBD /* vChewingLM.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = vChewingLM.h; sourceTree = "<group>"; };
|
D41355DA278E6D17005E5CBD /* LMInstantiator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LMInstantiator.h; sourceTree = "<group>"; };
|
||||||
D41355DC278EA3ED005E5CBD /* UserPhrasesLM.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = UserPhrasesLM.mm; sourceTree = "<group>"; };
|
D41355DC278EA3ED005E5CBD /* UserPhrasesLM.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = UserPhrasesLM.mm; sourceTree = "<group>"; };
|
||||||
D41355DD278EA3ED005E5CBD /* UserPhrasesLM.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UserPhrasesLM.h; sourceTree = "<group>"; };
|
D41355DD278EA3ED005E5CBD /* UserPhrasesLM.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UserPhrasesLM.h; sourceTree = "<group>"; };
|
||||||
D427A9BF25ED28CC005D43E0 /* vChewing-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "vChewing-Bridging-Header.h"; sourceTree = "<group>"; };
|
D427A9BF25ED28CC005D43E0 /* vChewing-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "vChewing-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
|
@ -280,6 +313,13 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
5BDC5CAD27C28E8B00E1CCE2 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
6A0D4E9F15FC0D2D00ABF4B3 /* Frameworks */ = {
|
6A0D4E9F15FC0D2D00ABF4B3 /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -297,14 +337,6 @@
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
5B30F10727BA501900484E24 /* KeyLayouts */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */,
|
|
||||||
);
|
|
||||||
path = KeyLayouts;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
5B62A30127AE732800A19448 /* 3rdParty */ = {
|
5B62A30127AE732800A19448 /* 3rdParty */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -423,12 +455,12 @@
|
||||||
5B62A32427AE757300A19448 /* LangModelRelated */ = {
|
5B62A32427AE757300A19448 /* LangModelRelated */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
D41355D9278E6D17005E5CBD /* LMInstantiator.mm */,
|
||||||
|
D41355DA278E6D17005E5CBD /* LMInstantiator.h */,
|
||||||
D41355D6278D7409005E5CBD /* mgrLangModel.h */,
|
D41355D6278D7409005E5CBD /* mgrLangModel.h */,
|
||||||
D495583A27A5C6C4006ADE1C /* mgrLangModel_Privates.h */,
|
D495583A27A5C6C4006ADE1C /* mgrLangModel_Privates.h */,
|
||||||
D41355D7278D7409005E5CBD /* mgrLangModel.mm */,
|
D41355D7278D7409005E5CBD /* mgrLangModel.mm */,
|
||||||
5B62A32527AE758000A19448 /* SubLanguageModels */,
|
5B62A32527AE758000A19448 /* SubLanguageModels */,
|
||||||
D41355D9278E6D17005E5CBD /* vChewingLM.mm */,
|
|
||||||
D41355DA278E6D17005E5CBD /* vChewingLM.h */,
|
|
||||||
);
|
);
|
||||||
path = LangModelRelated;
|
path = LangModelRelated;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -459,7 +491,6 @@
|
||||||
5B62A33027AE78E500A19448 /* Resources */ = {
|
5B62A33027AE78E500A19448 /* Resources */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
5B30F10727BA501900484E24 /* KeyLayouts */,
|
|
||||||
6A0D4EEE15FC0DA600ABF4B3 /* Images */,
|
6A0D4EEE15FC0DA600ABF4B3 /* Images */,
|
||||||
5BBBB76E27AED70B0023B93A /* MenuIcons */,
|
5BBBB76E27AED70B0023B93A /* MenuIcons */,
|
||||||
5BBBB75C27AED54C0023B93A /* SoundFiles */,
|
5BBBB75C27AED54C0023B93A /* SoundFiles */,
|
||||||
|
@ -596,6 +627,19 @@
|
||||||
path = Resources;
|
path = Resources;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
5BDC5CB127C28E8B00E1CCE2 /* KeyboardExtension */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */,
|
||||||
|
5BDC5CB227C28E8B00E1CCE2 /* icon.icns */,
|
||||||
|
5BDC5CB427C28E8B00E1CCE2 /* ShareViewController.swift */,
|
||||||
|
5BDC5CB627C28E8B00E1CCE2 /* ShareViewController.xib */,
|
||||||
|
5BDC5CB927C28E8B00E1CCE2 /* Info.plist */,
|
||||||
|
5BDC5CBA27C28E8B00E1CCE2 /* KeyboardExtension.entitlements */,
|
||||||
|
);
|
||||||
|
path = KeyboardExtension;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
6A0D4E9215FC0CFA00ABF4B3 = {
|
6A0D4E9215FC0CFA00ABF4B3 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -603,6 +647,7 @@
|
||||||
6ACA41E715FC1D9000935EF6 /* Installer */,
|
6ACA41E715FC1D9000935EF6 /* Installer */,
|
||||||
6A0D4EC215FC0D3C00ABF4B3 /* Source */,
|
6A0D4EC215FC0D3C00ABF4B3 /* Source */,
|
||||||
5BD05BB927B2A429004C4F1D /* UserPhraseEditor */,
|
5BD05BB927B2A429004C4F1D /* UserPhraseEditor */,
|
||||||
|
5BDC5CB127C28E8B00E1CCE2 /* KeyboardExtension */,
|
||||||
6A0D4EA315FC0D2D00ABF4B3 /* Products */,
|
6A0D4EA315FC0D2D00ABF4B3 /* Products */,
|
||||||
D47D73C127A7200500255A50 /* Frameworks */,
|
D47D73C127A7200500255A50 /* Frameworks */,
|
||||||
);
|
);
|
||||||
|
@ -614,6 +659,7 @@
|
||||||
6A0D4EA215FC0D2D00ABF4B3 /* vChewing.app */,
|
6A0D4EA215FC0D2D00ABF4B3 /* vChewing.app */,
|
||||||
6ACA41CB15FC1D7500935EF6 /* vChewingInstaller.app */,
|
6ACA41CB15FC1D7500935EF6 /* vChewingInstaller.app */,
|
||||||
5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */,
|
5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */,
|
||||||
|
5BDC5CB027C28E8B00E1CCE2 /* KeyboardExtension.appex */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -663,6 +709,7 @@
|
||||||
6A0D4F1515FC0EB100ABF4B3 /* BlockReadingBuilder.h */,
|
6A0D4F1515FC0EB100ABF4B3 /* BlockReadingBuilder.h */,
|
||||||
6A0D4F1615FC0EB100ABF4B3 /* Gramambular.h */,
|
6A0D4F1615FC0EB100ABF4B3 /* Gramambular.h */,
|
||||||
6A0D4F1715FC0EB100ABF4B3 /* Grid.h */,
|
6A0D4F1715FC0EB100ABF4B3 /* Grid.h */,
|
||||||
|
5BDC5CAA27C2873D00E1CCE2 /* Grid.mm */,
|
||||||
6A0D4F1815FC0EB100ABF4B3 /* KeyValuePair.h */,
|
6A0D4F1815FC0EB100ABF4B3 /* KeyValuePair.h */,
|
||||||
6A0D4F1915FC0EB100ABF4B3 /* LanguageModel.h */,
|
6A0D4F1915FC0EB100ABF4B3 /* LanguageModel.h */,
|
||||||
6A0D4F1A15FC0EB100ABF4B3 /* Node.h */,
|
6A0D4F1A15FC0EB100ABF4B3 /* Node.h */,
|
||||||
|
@ -734,6 +781,23 @@
|
||||||
productReference = 5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */;
|
productReference = 5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
|
5BDC5CAF27C28E8B00E1CCE2 /* KeyboardExtension */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 5BDC5CC127C28E8B00E1CCE2 /* Build configuration list for PBXNativeTarget "KeyboardExtension" */;
|
||||||
|
buildPhases = (
|
||||||
|
5BDC5CAC27C28E8B00E1CCE2 /* Sources */,
|
||||||
|
5BDC5CAD27C28E8B00E1CCE2 /* Frameworks */,
|
||||||
|
5BDC5CAE27C28E8B00E1CCE2 /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = KeyboardExtension;
|
||||||
|
productName = KeyboardExtension;
|
||||||
|
productReference = 5BDC5CB027C28E8B00E1CCE2 /* KeyboardExtension.appex */;
|
||||||
|
productType = "com.apple.product-type.app-extension";
|
||||||
|
};
|
||||||
6A0D4EA115FC0D2D00ABF4B3 /* vChewing */ = {
|
6A0D4EA115FC0D2D00ABF4B3 /* vChewing */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 6A0D4EC015FC0D2E00ABF4B3 /* Build configuration list for PBXNativeTarget "vChewing" */;
|
buildConfigurationList = 6A0D4EC015FC0D2E00ABF4B3 /* Build configuration list for PBXNativeTarget "vChewing" */;
|
||||||
|
@ -741,12 +805,14 @@
|
||||||
6A0D4E9E15FC0D2D00ABF4B3 /* Sources */,
|
6A0D4E9E15FC0D2D00ABF4B3 /* Sources */,
|
||||||
6A0D4E9F15FC0D2D00ABF4B3 /* Frameworks */,
|
6A0D4E9F15FC0D2D00ABF4B3 /* Frameworks */,
|
||||||
6A0D4EA015FC0D2D00ABF4B3 /* Resources */,
|
6A0D4EA015FC0D2D00ABF4B3 /* Resources */,
|
||||||
|
5BDC5CBE27C28E8B00E1CCE2 /* Embed App Extensions */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
5B0AF8B327B2C4E20096FE54 /* PBXTargetDependency */,
|
5B0AF8B327B2C4E20096FE54 /* PBXTargetDependency */,
|
||||||
6A38BC2615FC131100A8A51F /* PBXTargetDependency */,
|
6A38BC2615FC131100A8A51F /* PBXTargetDependency */,
|
||||||
|
5BDC5CBC27C28E8B00E1CCE2 /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
name = vChewing;
|
name = vChewing;
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
|
@ -790,6 +856,10 @@
|
||||||
LastSwiftMigration = 1320;
|
LastSwiftMigration = 1320;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
|
5BDC5CAF27C28E8B00E1CCE2 = {
|
||||||
|
CreatedOnToolsVersion = 13.2;
|
||||||
|
ProvisioningStyle = Automatic;
|
||||||
|
};
|
||||||
6A0D4EA115FC0D2D00ABF4B3 = {
|
6A0D4EA115FC0D2D00ABF4B3 = {
|
||||||
LastSwiftMigration = 1240;
|
LastSwiftMigration = 1240;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
|
@ -821,6 +891,7 @@
|
||||||
6A0D4EA115FC0D2D00ABF4B3 /* vChewing */,
|
6A0D4EA115FC0D2D00ABF4B3 /* vChewing */,
|
||||||
6ACA41CA15FC1D7500935EF6 /* vChewingInstaller */,
|
6ACA41CA15FC1D7500935EF6 /* vChewingInstaller */,
|
||||||
5BD05BB727B2A429004C4F1D /* vChewingPhraseEditor */,
|
5BD05BB727B2A429004C4F1D /* vChewingPhraseEditor */,
|
||||||
|
5BDC5CAF27C28E8B00E1CCE2 /* KeyboardExtension */,
|
||||||
6A38BC2115FC12FD00A8A51F /* Data */,
|
6A38BC2115FC12FD00A8A51F /* Data */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -838,6 +909,16 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
5BDC5CAE27C28E8B00E1CCE2 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
5BDC5CB827C28E8B00E1CCE2 /* ShareViewController.xib in Resources */,
|
||||||
|
5BDC5CC227C2941F00E1CCE2 /* vChewingKeyLayout.bundle in Resources */,
|
||||||
|
5BDC5CB327C28E8B00E1CCE2 /* icon.icns in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
6A0D4EA015FC0D2D00ABF4B3 /* Resources */ = {
|
6A0D4EA015FC0D2D00ABF4B3 /* Resources */ = {
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -858,7 +939,6 @@
|
||||||
5BBBB77627AED70B0023B93A /* MenuIcon-TCVIM.png in Resources */,
|
5BBBB77627AED70B0023B93A /* MenuIcon-TCVIM.png in Resources */,
|
||||||
6A187E2616004C5900466B2E /* MainMenu.xib in Resources */,
|
6A187E2616004C5900466B2E /* MainMenu.xib in Resources */,
|
||||||
5BBBB75F27AED54C0023B93A /* Beep.m4a in Resources */,
|
5BBBB75F27AED54C0023B93A /* Beep.m4a in Resources */,
|
||||||
5B30F11327BA568800484E24 /* vChewingKeyLayout.bundle in Resources */,
|
|
||||||
5B2DB16F27AF6891006D874E /* data-chs.txt in Resources */,
|
5B2DB16F27AF6891006D874E /* data-chs.txt in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -913,6 +993,14 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
5BDC5CAC27C28E8B00E1CCE2 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
5BDC5CB527C28E8B00E1CCE2 /* ShareViewController.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
6A0D4E9E15FC0D2D00ABF4B3 /* Sources */ = {
|
6A0D4E9E15FC0D2D00ABF4B3 /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -937,12 +1025,13 @@
|
||||||
5B11328927B94CFB00E58451 /* AppleKeyboardConverter.swift in Sources */,
|
5B11328927B94CFB00E58451 /* AppleKeyboardConverter.swift in Sources */,
|
||||||
5B62A31827AE73A700A19448 /* zip.m in Sources */,
|
5B62A31827AE73A700A19448 /* zip.m in Sources */,
|
||||||
5B62A32E27AE78B000A19448 /* CNSLM.mm in Sources */,
|
5B62A32E27AE78B000A19448 /* CNSLM.mm in Sources */,
|
||||||
D41355DB278E6D17005E5CBD /* vChewingLM.mm in Sources */,
|
D41355DB278E6D17005E5CBD /* LMInstantiator.mm in Sources */,
|
||||||
5B62A31A27AE73A700A19448 /* mztools.m in Sources */,
|
5B62A31A27AE73A700A19448 /* mztools.m in Sources */,
|
||||||
5B62A32927AE77D100A19448 /* FSEventStreamHelper.swift in Sources */,
|
5B62A32927AE77D100A19448 /* FSEventStreamHelper.swift in Sources */,
|
||||||
D47F7DD3278C1263002F9DD7 /* UserOverrideModel.cpp in Sources */,
|
D47F7DD3278C1263002F9DD7 /* UserOverrideModel.cpp in Sources */,
|
||||||
5B62A33627AE795800A19448 /* PreferencesModule.swift in Sources */,
|
5B62A33627AE795800A19448 /* PreferencesModule.swift in Sources */,
|
||||||
5B62A33827AE79CD00A19448 /* NSStringUtils.swift in Sources */,
|
5B62A33827AE79CD00A19448 /* NSStringUtils.swift in Sources */,
|
||||||
|
5BDC5CAB27C2873D00E1CCE2 /* Grid.mm in Sources */,
|
||||||
5B62A33227AE792F00A19448 /* InputSourceHelper.swift in Sources */,
|
5B62A33227AE792F00A19448 /* InputSourceHelper.swift in Sources */,
|
||||||
5B62A34927AE7CD900A19448 /* TooltipController.swift in Sources */,
|
5B62A34927AE7CD900A19448 /* TooltipController.swift in Sources */,
|
||||||
6A0D4F4515FC0EB100ABF4B3 /* Mandarin.cpp in Sources */,
|
6A0D4F4515FC0EB100ABF4B3 /* Mandarin.cpp in Sources */,
|
||||||
|
@ -979,6 +1068,11 @@
|
||||||
target = 5BD05BB727B2A429004C4F1D /* vChewingPhraseEditor */;
|
target = 5BD05BB727B2A429004C4F1D /* vChewingPhraseEditor */;
|
||||||
targetProxy = 5B0AF8B227B2C4E20096FE54 /* PBXContainerItemProxy */;
|
targetProxy = 5B0AF8B227B2C4E20096FE54 /* PBXContainerItemProxy */;
|
||||||
};
|
};
|
||||||
|
5BDC5CBC27C28E8B00E1CCE2 /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 5BDC5CAF27C28E8B00E1CCE2 /* KeyboardExtension */;
|
||||||
|
targetProxy = 5BDC5CBB27C28E8B00E1CCE2 /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
6A38BC2615FC131100A8A51F /* PBXTargetDependency */ = {
|
6A38BC2615FC131100A8A51F /* PBXTargetDependency */ = {
|
||||||
isa = PBXTargetDependency;
|
isa = PBXTargetDependency;
|
||||||
target = 6A38BC2115FC12FD00A8A51F /* Data */;
|
target = 6A38BC2115FC12FD00A8A51F /* Data */;
|
||||||
|
@ -1046,6 +1140,14 @@
|
||||||
name = Main.storyboard;
|
name = Main.storyboard;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
5BDC5CB627C28E8B00E1CCE2 /* ShareViewController.xib */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
5BDC5CB727C28E8B00E1CCE2 /* Base */,
|
||||||
|
);
|
||||||
|
name = ShareViewController.xib;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
5BE78BDA27B37764005EA1BE /* frmAboutWindow.xib */ = {
|
5BE78BDA27B37764005EA1BE /* frmAboutWindow.xib */ = {
|
||||||
isa = PBXVariantGroup;
|
isa = PBXVariantGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -1147,7 +1249,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 = 1922;
|
CURRENT_PROJECT_VERSION = 1923;
|
||||||
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;
|
||||||
|
@ -1166,7 +1268,7 @@
|
||||||
INFOPLIST_KEY_NSPrincipalClass = NSApplication;
|
INFOPLIST_KEY_NSPrincipalClass = NSApplication;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
||||||
MARKETING_VERSION = 1.3.3;
|
MARKETING_VERSION = 1.3.4;
|
||||||
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;
|
||||||
|
@ -1199,7 +1301,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 = 1922;
|
CURRENT_PROJECT_VERSION = 1923;
|
||||||
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;
|
||||||
|
@ -1213,7 +1315,7 @@
|
||||||
INFOPLIST_KEY_NSPrincipalClass = NSApplication;
|
INFOPLIST_KEY_NSPrincipalClass = NSApplication;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
||||||
MARKETING_VERSION = 1.3.3;
|
MARKETING_VERSION = 1.3.4;
|
||||||
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;
|
||||||
|
@ -1225,6 +1327,102 @@
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
5BDC5CBF27C28E8B00E1CCE2 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = KeyboardExtension/KeyboardExtension.entitlements;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
CURRENT_PROJECT_VERSION = 1923;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
DEVELOPMENT_ASSET_PATHS = KeyboardExtension/vChewingKeyLayout.bundle;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = KeyboardExtension/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = KeyboardExtension;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks";
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 12.1;
|
||||||
|
MARKETING_VERSION = 1.3.4;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing.KeyboardExtension;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
5BDC5CC027C28E8B00E1CCE2 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = KeyboardExtension/KeyboardExtension.entitlements;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
CURRENT_PROJECT_VERSION = 1923;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
DEVELOPMENT_ASSET_PATHS = KeyboardExtension/vChewingKeyLayout.bundle;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = KeyboardExtension/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = KeyboardExtension;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks";
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 12.1;
|
||||||
|
MARKETING_VERSION = 1.3.4;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing.KeyboardExtension;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
6A0D4E9915FC0CFA00ABF4B3 /* Debug */ = {
|
6A0D4E9915FC0CFA00ABF4B3 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
@ -1311,6 +1509,7 @@
|
||||||
6A0D4EBE15FC0D2E00ABF4B3 /* Debug */ = {
|
6A0D4EBE15FC0D2E00ABF4B3 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||||
|
@ -1327,8 +1526,8 @@
|
||||||
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 = 1922;
|
CURRENT_PROJECT_VERSION = 1923;
|
||||||
DEVELOPMENT_ASSET_PATHS = Source/Resources/KeyLayouts/vChewingKeyLayout.bundle;
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
@ -1359,7 +1558,7 @@
|
||||||
INFOPLIST_FILE = "Source/Resources/IME-Info.plist";
|
INFOPLIST_FILE = "Source/Resources/IME-Info.plist";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
||||||
MARKETING_VERSION = 1.3.3;
|
MARKETING_VERSION = 1.3.4;
|
||||||
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)";
|
||||||
|
@ -1375,6 +1574,7 @@
|
||||||
6A0D4EBF15FC0D2E00ABF4B3 /* Release */ = {
|
6A0D4EBF15FC0D2E00ABF4B3 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||||
|
@ -1391,9 +1591,9 @@
|
||||||
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 = 1922;
|
CURRENT_PROJECT_VERSION = 1923;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
DEVELOPMENT_ASSET_PATHS = Source/Resources/KeyLayouts/vChewingKeyLayout.bundle;
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
|
@ -1417,7 +1617,7 @@
|
||||||
INFOPLIST_FILE = "Source/Resources/IME-Info.plist";
|
INFOPLIST_FILE = "Source/Resources/IME-Info.plist";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
||||||
MARKETING_VERSION = 1.3.3;
|
MARKETING_VERSION = 1.3.4;
|
||||||
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 = "";
|
||||||
|
@ -1500,7 +1700,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 = 1922;
|
CURRENT_PROJECT_VERSION = 1923;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
@ -1522,7 +1722,7 @@
|
||||||
INFOPLIST_FILE = "Installer/Installer-Info.plist";
|
INFOPLIST_FILE = "Installer/Installer-Info.plist";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
||||||
MARKETING_VERSION = 1.3.3;
|
MARKETING_VERSION = 1.3.4;
|
||||||
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)";
|
||||||
|
@ -1550,7 +1750,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 = 1922;
|
CURRENT_PROJECT_VERSION = 1923;
|
||||||
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;
|
||||||
|
@ -1566,7 +1766,7 @@
|
||||||
INFOPLIST_FILE = "Installer/Installer-Info.plist";
|
INFOPLIST_FILE = "Installer/Installer-Info.plist";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
|
||||||
MARKETING_VERSION = 1.3.3;
|
MARKETING_VERSION = 1.3.4;
|
||||||
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 = "";
|
||||||
|
@ -1589,6 +1789,15 @@
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
|
5BDC5CC127C28E8B00E1CCE2 /* Build configuration list for PBXNativeTarget "KeyboardExtension" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
5BDC5CBF27C28E8B00E1CCE2 /* Debug */,
|
||||||
|
5BDC5CC027C28E8B00E1CCE2 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
6A0D4E9715FC0CFA00ABF4B3 /* Build configuration list for PBXProject "vChewing" */ = {
|
6A0D4E9715FC0CFA00ABF4B3 /* Build configuration list for PBXProject "vChewing" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
|
|
Loading…
Reference in New Issue