From 3fbbfcc8f509c352c58dc8a126220b49b72ed5a0 Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期五, 26 九月 2025 09:15:46 +0800
Subject: [PATCH] ocr图像处理功能开发
---
src/main/java/com/xindao/ocr/smartjavaai/factory/TableRecModelFactory.java | 107
src/main/java/com/xindao/ocr/swingui/swing/utils/GenerateCustomizeComponent.java | 122
src/main/java/com/xindao/ocr/swingui/swing/jpanel/MultipleAreaProcessPanel.java | 1166 +
src/main/java/com/xindao/ocr/smartjavaai/config/PlateRecModelConfig.java | 32
src/main/java/com/xindao/ocr/smartjavaai/model/table/TableStructureModel.java | 65
src/main/java/com/xindao/ocr/smartjavaai/model/common/recognize/OcrCommonRecModel.java | 129
src/main/java/com/xindao/ocr/smartjavaai/model/plate/PlateRecModel.java | 116
src/main/java/com/xindao/ocr/smartjavaai/opencv/OcrNDArrayUtils.java | 228
src/main/java/com/xindao/ocr/swingui/excel/ContractNumberExcelData.java | 18
src/main/java/com/xindao/ocr/smartjavaai/enums/CommonRecModelEnum.java | 32
src/main/java/com/xindao/ocr/swingui/swing/FileProcessorApp.java | 100
src/main/java/com/xindao/ocr/smartjavaai/config/PlateDetModelConfig.java | 40
src/main/java/com/xindao/ocr/smartjavaai/enums/AngleEnum.java | 38
src/main/java/com/xindao/ocr/smartjavaai/enums/CommonDetModelEnum.java | 32
src/main/java/com/xindao/ocr/smartjavaai/enums/PlateType.java | 45
src/main/java/com/xindao/ocr/smartjavaai/model/table/CommonTableStructureModel.java | 163
src/main/java/com/xindao/ocr/smartjavaai/entity/TableStructureResult.java | 33
src/main/resources/PP_OCRv5/PP-OCRv5_mobile_rec_infer/PP-OCRv5_mobile_rec_infer.onnx | 0
src/main/java/com/xindao/ocr/smartjavaai/model/plate/Yolov5PlateDetModel.java | 238
LICENSE | 127
src/main/java/com/xindao/ocr/smartjavaai/model/common/detect/criteria/OcrCommonDetCriterialFactory.java | 53
src/main/java/com/xindao/ocr/smartjavaai/model/common/recognize/OcrCommonRecModelImpl.java | 502
src/main/resources/PP_OCRv5/PP-OCRv5_server_rec_infer/dict.txt | 18383 +++++++++++++++++++++++
src/main/java/com/xindao/ocr/smartjavaai/config/DirectionModelConfig.java | 33
src/main/java/com/xindao/ocr/smartjavaai/enums/DirectionModelEnum.java | 32
src/main/java/com/xindao/ocr/smartjavaai/factory/OcrModelFactory.java | 223
src/main/java/com/xindao/ocr/smartjavaai/model/table/TableRecognizer.java | 485
src/main/resources/PP_OCRv5/PP-LCNet_x0_25_textline_ori_infer/PP-LCNet_x0_25_textline_ori_infer.onnx | 0
src/main/java/com/xindao/ocr/swingui/dto/OcrDTO.java | 10
src/main/resources/logback-spring.xml | 63
src/main/java/com/xindao/ocr/smartjavaai/config/OcrRecOptions.java | 31
src/main/java/com/xindao/ocr/smartjavaai/model/plate/criteria/PlateRecCriterialFactory.java | 42
src/main/java/com/xindao/ocr/smartjavaai/model/plate/translator/CRNNPlateRecTranslator.java | 88
src/main/java/com/xindao/ocr/swingui/config/SwingAppConfig.java | 31
src/main/java/com/xindao/ocr/smartjavaai/model/common/detect/OcrCommonDetModelImpl.java | 244
src/main/java/com/xindao/ocr/swingui/swing/jpanel/PdfPreviewPanel.java | 202
src/main/java/com/xindao/ocr/smartjavaai/utils/CrossRangeCellMeta.java | 42
src/main/java/com/xindao/ocr/smartjavaai/entity/OcrBox.java | 72
src/main/java/com/xindao/ocr/swingui/swing/utils/FileNameValidator.java | 81
src/main/java/com/xindao/ocr/smartjavaai/model/table/criteria/StructureCriteriaFactory.java | 56
src/main/java/com/xindao/ocr/swingui/controller/OcrController.java | 25
src/main/java/com/xindao/ocr/smartjavaai/exception/OcrException.java | 30
src/main/java/com/xindao/ocr/smartjavaai/entity/OcrItem.java | 54
src/main/java/com/xindao/ocr/smartjavaai/factory/PlateModelFactory.java | 164
src/main/java/com/xindao/ocr/smartjavaai/model/common/detect/OcrCommonDetModel.java | 104
src/main/java/com/xindao/ocr/smartjavaai/model/common/direction/OcrDirectionModel.java | 112
src/main/java/com/xindao/ocr/smartjavaai/entity/RotatedBox.java | 46
src/main/resources/PP_OCRv5/PP-OCRv5_server_rec_infer/PP-OCRv5_server_rec.onnx | 0
src/main/java/com/xindao/ocr/smartjavaai/enums/TableStructureModelEnum.java | 30
src/main/java/com/xindao/ocr/smartjavaai/config/OcrRecModelConfig.java | 37
src/main/java/com/xindao/ocr/smartjavaai/utils/ConvertHtml2Excel.java | 236
src/main/java/com/xindao/ocr/smartjavaai/model/plate/translator/Yolov8PlateDetectTranslator.java | 188
.gitignore | 41
src/main/java/com/xindao/ocr/smartjavaai/model/common/recognize/criteria/OcrCommonRecCriterialFactory.java | 51
src/main/java/com/xindao/ocr/smartjavaai/entity/ImageInfo.java | 50
src/main/java/com/xindao/ocr/smartjavaai/utils/OcrUtils.java | 455
src/main/java/com/xindao/ocr/smartjavaai/entity/IdCardInfo.java | 12
src/main/java/com/xindao/ocr/swingui/service/OcrService.java | 195
src/main/java/com/xindao/ocr/smartjavaai/model/plate/PlateDetModel.java | 112
pom.xml | 426
src/main/java/com/xindao/ocr/smartjavaai/model/plate/translator/Yolov7PlateDetectTranslator.java | 192
src/main/java/com/xindao/ocr/smartjavaai/config/OcrDetModelConfig.java | 26
src/main/java/com/xindao/ocr/smartjavaai/model/table/translator/TableStructTranslator.java | 191
src/main/java/com/xindao/ocr/smartjavaai/model/plate/translator/Yolo5PlateDetectTranslator.java | 194
src/main/java/com/xindao/ocr/swingui/swing/jpanel/ContractNumberProcessPanel.java | 645
src/main/resources/PP_OCRv5/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx | 0
src/main/java/com/xindao/ocr/smartjavaai/entity/RotatedBoxCompX.java | 47
src/main/java/com/xindao/ocr/swingui/swing/utils/ToFile.java | 179
src/main/java/com/xindao/ocr/smartjavaai/config/TableStructureConfig.java | 25
src/main/java/com/xindao/ocr/smartjavaai/model/common/detect/translator/PPOCRDetTranslator.java | 536
src/main/resources/PP_OCRv5/PP-OCRv5_mobile_rec_infer/dict.txt | 18383 +++++++++++++++++++++++
src/main/java/com/xindao/ocr/smartjavaai/enums/PlateDetModelEnum.java | 28
src/main/java/com/xindao/ocr/smartjavaai/model/common/direction/translator/PpWordRotateTranslator.java | 105
src/main/java/com/xindao/ocr/smartjavaai/entity/DirectionInfo.java | 41
src/main/java/com/xindao/ocr/smartjavaai/model/common/direction/PPOCRMobileV2ClsModel.java | 393
src/main/java/com/xindao/ocr/smartjavaai/model/plate/CRNNPlateRecModel.java | 325
src/main/java/com/xindao/ocr/smartjavaai/entity/OcrInfo.java | 37
/dev/null | 4
src/main/java/com/xindao/ocr/smartjavaai/model/common/direction/criteria/DirectionCriteriaFactory.java | 57
src/main/java/com/xindao/ocr/swingui/constant/OcrSwingConstants.java | 26
src/main/java/com/xindao/ocr/OcrToolApplication.java | 16
src/main/java/com/xindao/ocr/smartjavaai/enums/PlateRecModelEnum.java | 26
src/main/java/com/xindao/ocr/smartjavaai/model/plate/criteria/PlateDetCriterialFactory.java | 71
src/main/java/com/xindao/ocr/smartjavaai/entity/PlateResult.java | 35
src/main/java/com/xindao/ocr/smartjavaai/model/common/recognize/translator/PPOCRRecTranslator.java | 129
src/main/resources/application.yml | 2
src/main/java/com/xindao/ocr/smartjavaai/entity/PlateInfo.java | 45
87 files changed, 47,625 insertions(+), 5 deletions(-)
diff --git a/.gitignore b/.gitignore
index 32858aa..e57eabf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,42 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
+
+logs/
+target/
+
*.class
# Mobile Tools for Java (J2ME)
@@ -9,4 +48,4 @@
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
-hs_err_pid*
+hs_err_pid*
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..90ea373
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,127 @@
+ 鏈ㄥ叞瀹芥澗璁稿彲璇�, 绗�2鐗�
+
+ 鏈ㄥ叞瀹芥澗璁稿彲璇侊紝 绗�2鐗�
+ 2020骞�1鏈� http://license.coscl.org.cn/MulanPSL2
+
+
+ 鎮ㄥ鈥滆蒋浠垛�濈殑澶嶅埗銆佷娇鐢ㄣ�佷慨鏀瑰強鍒嗗彂鍙楁湪鍏板鏉捐鍙瘉锛岀2鐗堬紙鈥滄湰璁稿彲璇佲�濓級鐨勫涓嬫潯娆剧殑绾︽潫锛�
+
+ 0. 瀹氫箟
+
+ 鈥滆蒋浠垛�濇槸鎸囩敱鈥滆础鐚�濇瀯鎴愮殑璁稿彲鍦ㄢ�滄湰璁稿彲璇佲�濅笅鐨勭▼搴忓拰鐩稿叧鏂囨。鐨勯泦鍚堛��
+
+ 鈥滆础鐚�濇槸鎸囩敱浠讳竴鈥滆础鐚�呪�濊鍙湪鈥滄湰璁稿彲璇佲�濅笅鐨勫彈鐗堟潈娉曚繚鎶ょ殑浣滃搧銆�
+
+ 鈥滆础鐚�呪�濇槸鎸囧皢鍙楃増鏉冩硶淇濇姢鐨勪綔鍝佽鍙湪鈥滄湰璁稿彲璇佲�濅笅鐨勮嚜鐒朵汉鎴栤�滄硶浜哄疄浣撯�濄��
+
+ 鈥滄硶浜哄疄浣撯�濇槸鎸囨彁浜よ础鐚殑鏈烘瀯鍙婂叾鈥滃叧鑱斿疄浣撯�濄��
+
+ 鈥滃叧鑱斿疄浣撯�濇槸鎸囷紝瀵光�滄湰璁稿彲璇佲�濅笅鐨勮涓烘柟鑰岃█锛屾帶鍒躲�佸彈鎺у埗鎴栦笌鍏跺叡鍚屽彈鎺у埗鐨勬満鏋勶紝姝ゅ鐨勬帶鍒舵槸鎸囨湁鍙楁帶鏂规垨鍏卞悓鍙楁帶鏂硅嚦灏�50%鐩存帴鎴栭棿鎺ョ殑鎶曠エ鏉冦�佽祫閲戞垨鍏朵粬鏈変环璇佸埜銆�
+
+ 1. 鎺堜簣鐗堟潈璁稿彲
+
+ 姣忎釜鈥滆础鐚�呪�濇牴鎹�滄湰璁稿彲璇佲�濇巿浜堟偍姘镐箙鎬х殑銆佸叏鐞冩�х殑銆佸厤璐圭殑銆侀潪鐙崰鐨勩�佷笉鍙挙閿�鐨勭増鏉冭鍙紝鎮ㄥ彲浠ュ鍒躲�佷娇鐢ㄣ�佷慨鏀广�佸垎鍙戝叾鈥滆础鐚�濓紝涓嶈淇敼涓庡惁銆�
+
+ 2. 鎺堜簣涓撳埄璁稿彲
+
+ 姣忎釜鈥滆础鐚�呪�濇牴鎹�滄湰璁稿彲璇佲�濇巿浜堟偍姘镐箙鎬х殑銆佸叏鐞冩�х殑銆佸厤璐圭殑銆侀潪鐙崰鐨勩�佷笉鍙挙閿�鐨勶紙鏍规嵁鏈潯瑙勫畾鎾ら攢闄ゅ锛変笓鍒╄鍙紝渚涙偍鍒堕�犮�佸鎵樺埗閫犮�佷娇鐢ㄣ�佽璇洪攢鍞�侀攢鍞�佽繘鍙e叾鈥滆础鐚�濇垨浠ュ叾浠栨柟寮忚浆绉诲叾鈥滆础鐚�濄�傚墠杩颁笓鍒╄鍙粎闄愪簬鈥滆础鐚�呪�濈幇鍦ㄦ垨灏嗘潵鎷ユ湁鎴栨帶鍒剁殑鍏垛�滆础鐚�濇湰韬垨鍏垛�滆础鐚�濅笌璁稿彲鈥滆础鐚�濇椂鐨勨�滆蒋浠垛�濈粨鍚堣�屽皢蹇呯劧浼氫镜鐘殑涓撳埄鏉冨埄瑕佹眰锛屼笉鍖呮嫭瀵光�滆础鐚�濈殑淇敼鎴栧寘鍚�滆础鐚�濈殑鍏朵粬缁撳悎銆傚鏋滄偍鎴栨偍鐨勨�滃叧鑱斿疄浣撯�濈洿鎺ユ垨闂存帴鍦帮紝灏扁�滆蒋浠垛�濇垨鍏朵腑鐨勨�滆础鐚�濆浠讳綍浜哄彂璧蜂笓鍒╀镜鏉冭瘔璁硷紙鍖呮嫭鍙嶈瘔鎴栦氦鍙夎瘔璁硷級鎴栧叾浠栦笓鍒╃淮鏉冭鍔紝鎸囨帶鍏朵镜鐘笓鍒╂潈锛屽垯鈥滄湰璁稿彲璇佲�濇巿浜堟偍瀵光�滆蒋浠垛�濈殑涓撳埄璁稿彲鑷偍鎻愯捣璇夎鎴栧彂璧风淮鏉冭鍔ㄤ箣鏃ョ粓姝€��
+
+ 3. 鏃犲晢鏍囪鍙�
+
+ 鈥滄湰璁稿彲璇佲�濅笉鎻愪緵瀵光�滆础鐚�呪�濈殑鍟嗗搧鍚嶇О銆佸晢鏍囥�佹湇鍔℃爣蹇楁垨浜у搧鍚嶇О鐨勫晢鏍囪鍙紝浣嗘偍涓烘弧瓒崇4鏉¤瀹氱殑澹版槑涔夊姟鑰屽繀椤讳娇鐢ㄩ櫎澶栥��
+
+ 4. 鍒嗗彂闄愬埗
+
+ 鎮ㄥ彲浠ュ湪浠讳綍濯掍粙涓皢鈥滆蒋浠垛�濅互婧愮▼搴忓舰寮忔垨鍙墽琛屽舰寮忛噸鏂板垎鍙戯紝涓嶈淇敼涓庡惁锛屼絾鎮ㄥ繀椤诲悜鎺ユ敹鑰呮彁渚涒�滄湰璁稿彲璇佲�濈殑鍓湰锛屽苟淇濈暀鈥滆蒋浠垛�濅腑鐨勭増鏉冦�佸晢鏍囥�佷笓鍒╁強鍏嶈矗澹版槑銆�
+
+ 5. 鍏嶈矗澹版槑涓庤矗浠婚檺鍒�
+
+ 鈥滆蒋浠垛�濆強鍏朵腑鐨勨�滆础鐚�濆湪鎻愪緵鏃朵笉甯︿换浣曟槑绀烘垨榛樼ず鐨勬媴淇濄�傚湪浠讳綍鎯呭喌涓嬶紝鈥滆础鐚�呪�濇垨鐗堟潈鎵�鏈夎�呬笉瀵逛换浣曚汉鍥犱娇鐢ㄢ�滆蒋浠垛�濇垨鍏朵腑鐨勨�滆础鐚�濊�屽紩鍙戠殑浠讳綍鐩存帴鎴栭棿鎺ユ崯澶辨壙鎷呰矗浠伙紝涓嶈鍥犱綍绉嶅師鍥犲鑷存垨鑰呭熀浜庝綍绉嶆硶寰嬬悊璁�,鍗充娇鍏舵浘琚缓璁湁姝ょ鎹熷け鐨勫彲鑳芥�с��
+
+ 6. 璇█
+ 鈥滄湰璁稿彲璇佲�濅互涓嫳鏂囧弻璇〃杩帮紝涓嫳鏂囩増鏈叿鏈夊悓绛夋硶寰嬫晥鍔涖�傚鏋滀腑鑻辨枃鐗堟湰瀛樺湪浠讳綍鍐茬獊涓嶄竴鑷达紝浠ヤ腑鏂囩増涓哄噯銆�
+
+ 鏉℃缁撴潫
+
+ 濡備綍灏嗘湪鍏板鏉捐鍙瘉锛岀2鐗堬紝搴旂敤鍒版偍鐨勮蒋浠�
+
+ 濡傛灉鎮ㄥ笇鏈涘皢鏈ㄥ叞瀹芥澗璁稿彲璇侊紝绗�2鐗堬紝搴旂敤鍒版偍鐨勬柊杞欢锛屼负浜嗘柟渚挎帴鏀惰�呮煡闃咃紝寤鸿鎮ㄥ畬鎴愬涓嬩笁姝ワ細
+
+ 1锛� 璇锋偍琛ュ厖濡備笅澹版槑涓殑绌虹櫧锛屽寘鎷蒋浠跺悕銆佽蒋浠剁殑棣栨鍙戣〃骞翠唤浠ュ強鎮ㄤ綔涓虹増鏉冧汉鐨勫悕瀛楋紱
+
+ 2锛� 璇锋偍鍦ㄨ蒋浠跺寘鐨勪竴绾х洰褰曚笅鍒涘缓浠モ�淟ICENSE鈥濅负鍚嶇殑鏂囦欢锛屽皢鏁翠釜璁稿彲璇佹枃鏈斁鍏ヨ鏂囦欢涓紱
+
+ 3锛� 璇峰皢濡備笅澹版槑鏂囨湰鏀惧叆姣忎釜婧愭枃浠剁殑澶撮儴娉ㄩ噴涓��
+
+ Copyright (c) 2025 DengWenJie
+ SmartJavaAI is licensed under Mulan PSL v2.
+ You can use this software according to the terms and conditions of the Mulan PSL v2.
+ You may obtain a copy of Mulan PSL v2 at:
+ http://license.coscl.org.cn/MulanPSL2
+ THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ See the Mulan PSL v2 for more details.
+
+
+ Mulan Permissive Software License锛孷ersion 2
+
+ Mulan Permissive Software License锛孷ersion 2 (Mulan PSL v2)
+ January 2020 http://license.coscl.org.cn/MulanPSL2
+
+ Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions:
+
+ 0. Definition
+
+ Software means the program and related documents which are licensed under this License and comprise all Contribution(s).
+
+ Contribution means the copyrightable work licensed by a particular Contributor under this License.
+
+ Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License.
+
+ Legal Entity means the entity making a Contribution and all its Affiliates.
+
+ Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, 鈥榗ontrol鈥� means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity.
+
+ 1. Grant of Copyright License
+
+ Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not.
+
+ 2. Grant of Patent License
+
+ Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken.
+
+ 3. No Trademark License
+
+ 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 in Section 4.
+
+ 4. Distribution Restriction
+
+ You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software.
+
+ 5. Disclaimer of Warranty and Limitation of Liability
+
+ THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT鈥橲 CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+ 6. Language
+
+ THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL.
+
+ END OF THE TERMS AND CONDITIONS
+
+ How to Apply the Mulan Permissive Software License锛孷ersion 2 (Mulan PSL v2) to Your Software
+
+ To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps:
+
+ i Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner;
+
+ ii Create a file named 鈥淟ICENSE鈥� which contains the whole context of this License in the first directory of your software package;
+
+ iii Attach the statement to the appropriate annotated syntax at the beginning of each source file.
+
+
+ Copyright (c) 2025 DengWenJie
+ SmartJavaAI is licensed under Mulan PSL v2.
+ You can use this software according to the terms and conditions of the Mulan PSL v2.
+ You may obtain a copy of Mulan PSL v2 at:
+ http://license.coscl.org.cn/MulanPSL2
+ THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ See the Mulan PSL v2 for more details.
diff --git a/README.md b/README.md
deleted file mode 100644
index ab44498..0000000
--- a/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-## ocr-tool
-
-OCR鍥惧儚璇嗗埆宸ュ叿
-
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..dd1c349
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,426 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>com.xindao.ocr</groupId>
+ <artifactId>ocr-tool</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <properties>
+ <java.version>1.8</java.version>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+
+ <maven.compiler.source>8</maven.compiler.source>
+ <maven.compiler.target>8</maven.compiler.target>
+
+ <springboot.version>2.6.13</springboot.version>
+ <djl.version>0.32.0</djl.version>
+ <spring-boot.version>2.6.13</spring-boot.version>
+ <easyexcel.version>3.3.4</easyexcel.version>
+
+ <smartjavaai.version>1.0.24</smartjavaai.version>
+
+ <javacv.version>1.5.10</javacv.version>
+
+ <javacv.platform.macosx-arm64>macosx-arm64</javacv.platform.macosx-arm64>
+ <javacv.platform.linux-x86_64>linux-x86_64</javacv.platform.linux-x86_64>
+ <javacv.platform.linux-arm64>linux-arm64</javacv.platform.linux-arm64>
+ <javacv.platform.windows-x86_64>windows-x86_64</javacv.platform.windows-x86_64>
+
+ <djl.platform.windows-x86_64>win-x86_64</djl.platform.windows-x86_64>
+ <djl.platform.linux-x86_64>linux-x86_64</djl.platform.linux-x86_64>
+ <djl.platform.linux-aarch64>linux-aarch64</djl.platform.linux-aarch64>
+ <djl.platform.osx-aarch64>osx-aarch64</djl.platform.osx-aarch64>
+ </properties>
+
+ <url>https://github.com/geekwenjie/SmartJavaAI</url>
+ <licenses>
+ <license>
+ <name>MIT License</name>
+ <url>https://opensource.org/licenses/MIT</url>
+ </license>
+ </licenses>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ <version>${springboot.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.alibaba</groupId>
+ <artifactId>easyexcel</artifactId>
+ <version>${easyexcel.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>7.4.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-beanutils</groupId>
+ <artifactId>commons-beanutils</artifactId>
+ <version>1.9.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.9</version>
+ </dependency>
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <version>1.18.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.7.30</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ <version>1.9.0</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.17.0</version>
+ </dependency>
+ <!-- Apache Commons Pool2 -->
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-pool2</artifactId>
+ <version>2.12.0</version>
+ </dependency>
+ <dependency>
+ <groupId>cn.hutool</groupId>
+ <artifactId>hutool-system</artifactId>
+ <version>5.8.16</version>
+ </dependency>
+ <dependency>
+ <groupId>cn.hutool</groupId>
+ <artifactId>hutool-setting</artifactId>
+ <version>5.8.16</version>
+ </dependency>
+ <dependency>
+ <groupId>com.alibaba</groupId>
+ <artifactId>fastjson</artifactId>
+ <version>1.2.83</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.pdfbox</groupId>
+ <artifactId>pdfbox</artifactId>
+ <version>2.0.28</version>
+ </dependency>
+
+
+
+ <!--OCR鐩稿叧渚濊禆-->
+ <dependency>
+ <groupId>cn.smartjavaai</groupId>
+ <artifactId>common</artifactId>
+ <version>${smartjavaai.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>dom4j</groupId>
+ <artifactId>dom4j</artifactId>
+ <version>1.6.1</version>
+ </dependency>
+ <dependency>
+ <groupId>ai.djl</groupId>
+ <artifactId>api</artifactId>
+ <version>${djl.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>ai.djl</groupId>
+ <artifactId>model-zoo</artifactId>
+ <version>${djl.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>ai.djl.huggingface</groupId>
+ <artifactId>tokenizers</artifactId>
+ <version>${djl.version}</version>
+ </dependency>
+ <!-- MXNet -->
+ <dependency>
+ <groupId>ai.djl.mxnet</groupId>
+ <artifactId>mxnet-model-zoo</artifactId>
+ <version>${djl.version}</version>
+ </dependency>
+ <!-- Pytorch -->
+ <dependency>
+ <groupId>ai.djl.pytorch</groupId>
+ <artifactId>pytorch-model-zoo</artifactId>
+ <version>${djl.version}</version>
+ </dependency>
+ <!-- TensorFlow -->
+ <dependency>
+ <groupId>ai.djl.tensorflow</groupId>
+ <artifactId>tensorflow-model-zoo</artifactId>
+ <version>${djl.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>ai.djl.pytorch</groupId>
+ <artifactId>pytorch-engine</artifactId>
+ <version>${djl.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>ai.djl.tensorflow</groupId>
+ <artifactId>tensorflow-engine</artifactId>
+ <version>${djl.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>ai.djl.mxnet</groupId>
+ <artifactId>mxnet-engine</artifactId>
+ <version>${djl.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>ai.djl.onnxruntime</groupId>
+ <artifactId>onnxruntime-engine</artifactId>
+ <version>${djl.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>ai.djl.opencv</groupId>
+ <artifactId>opencv</artifactId>
+ <version>${djl.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>gov.nist.math</groupId>
+ <artifactId>jama</artifactId>
+ <version>1.0.3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.bytedeco</groupId>
+ <artifactId>javacv</artifactId>
+ <version>1.5.10</version>
+ </dependency>
+ <dependency>
+ <groupId>ai.djl.pytorch</groupId>
+ <artifactId>pytorch-jni</artifactId>
+ <version>2.5.1-0.32.0</version>
+ <scope>runtime</scope>
+ </dependency>
+ <!-- windows骞冲彴 (淇濈暀瀵瑰簲骞冲彴鐨勯厤缃紝鍙互鍑忓皬鍖呭ぇ灏�)-->
+ <dependency>
+ <groupId>org.bytedeco</groupId>
+ <artifactId>javacpp</artifactId>
+ <version>${javacv.version}</version>
+ <classifier>${javacv.platform.windows-x86_64}</classifier>
+ </dependency>
+
+ <dependency>
+ <groupId>org.bytedeco</groupId>
+ <artifactId>openblas</artifactId>
+ <version>0.3.26-1.5.10</version>
+ <classifier>${javacv.platform.windows-x86_64}</classifier>
+ </dependency>
+
+ <dependency>
+ <groupId>org.bytedeco</groupId>
+ <artifactId>opencv</artifactId>
+ <version>4.9.0-1.5.10</version>
+ <classifier>${javacv.platform.windows-x86_64}</classifier>
+ </dependency>
+
+ <dependency>
+ <groupId>ai.djl.pytorch</groupId>
+ <artifactId>pytorch-native-cpu</artifactId>
+ <classifier>${djl.platform.windows-x86_64}</classifier>
+ <version>2.5.1</version>
+ <scope>runtime</scope>
+ </dependency>
+
+
+
+ <!-- linux x86 骞冲彴 (淇濈暀瀵瑰簲骞冲彴鐨勯厤缃紝鍙互鍑忓皬鍖呭ぇ灏�)-->
+ <!-- <dependency>-->
+ <!-- <groupId>org.bytedeco</groupId>-->
+ <!-- <artifactId>javacpp</artifactId>-->
+ <!-- <version>${javacv.version}</version>-->
+ <!-- <classifier>${javacv.platform.linux-x86_64}</classifier>-->
+ <!-- </dependency>-->
+ <!-- <dependency>-->
+ <!-- <groupId>org.bytedeco</groupId>-->
+ <!-- <artifactId>ffmpeg</artifactId>-->
+ <!-- <version>6.1.1-1.5.10</version>-->
+ <!-- <classifier>${javacv.platform.linux-x86_64}</classifier>-->
+ <!-- </dependency>-->
+
+ <!-- <dependency>-->
+ <!-- <groupId>org.bytedeco</groupId>-->
+ <!-- <artifactId>openblas</artifactId>-->
+ <!-- <version>0.3.26-1.5.10</version>-->
+ <!-- <classifier>${javacv.platform.linux-x86_64}</classifier>-->
+ <!-- </dependency>-->
+
+ <!-- <dependency>-->
+ <!-- <groupId>org.bytedeco</groupId>-->
+ <!-- <artifactId>opencv</artifactId>-->
+ <!-- <version>4.9.0-1.5.10</version>-->
+ <!-- <classifier>${javacv.platform.linux-x86_64}</classifier>-->
+ <!-- </dependency>-->
+
+ <!-- <dependency>-->
+ <!-- <groupId>ai.djl.pytorch</groupId>-->
+ <!-- <artifactId>pytorch-native-cpu</artifactId>-->
+ <!-- <classifier>${djl.platform.linux-x86_64}</classifier>-->
+ <!-- <version>2.5.1</version>-->
+ <!-- <scope>runtime</scope>-->
+ <!-- </dependency>-->
+ <!-- <dependency>-->
+ <!-- <groupId>ai.djl.pytorch</groupId>-->
+ <!-- <artifactId>pytorch-native-cpu-precxx11</artifactId>-->
+ <!-- <classifier>${djl.platform.linux-x86_64}</classifier>-->
+ <!-- <version>2.5.1</version>-->
+ <!-- <scope>runtime</scope>-->
+ <!-- </dependency>-->
+
+
+ <!-- macOS M绯诲垪 骞冲彴 (淇濈暀瀵瑰簲骞冲彴鐨勯厤缃紝鍙互鍑忓皬鍖呭ぇ灏�)-->
+ <!-- <dependency>-->
+ <!-- <groupId>org.bytedeco</groupId>-->
+ <!-- <artifactId>javacpp</artifactId>-->
+ <!-- <version>${javacv.version}</version>-->
+ <!-- <classifier>${javacv.platform.macosx-arm64}</classifier>-->
+ <!-- </dependency>-->
+ <!-- <dependency>-->
+ <!-- <groupId>org.bytedeco</groupId>-->
+ <!-- <artifactId>ffmpeg</artifactId>-->
+ <!-- <version>6.1.1-1.5.10</version>-->
+ <!-- <classifier>${javacv.platform.macosx-arm64}</classifier>-->
+ <!-- </dependency>-->
+
+ <!-- <dependency>-->
+ <!-- <groupId>org.bytedeco</groupId>-->
+ <!-- <artifactId>openblas</artifactId>-->
+ <!-- <version>0.3.26-1.5.10</version>-->
+ <!-- <classifier>${javacv.platform.macosx-arm64}</classifier>-->
+ <!-- </dependency>-->
+
+ <!-- <dependency>-->
+ <!-- <groupId>org.bytedeco</groupId>-->
+ <!-- <artifactId>opencv</artifactId>-->
+ <!-- <version>4.9.0-1.5.10</version>-->
+ <!-- <classifier>${javacv.platform.macosx-arm64}</classifier>-->
+ <!-- </dependency>-->
+
+ <!-- <dependency>-->
+ <!-- <groupId>ai.djl.pytorch</groupId>-->
+ <!-- <artifactId>pytorch-native-cpu</artifactId>-->
+ <!-- <classifier>${djl.platform.osx-aarch64}</classifier>-->
+ <!-- <version>2.5.1</version>-->
+ <!-- <scope>runtime</scope>-->
+ <!-- </dependency>-->
+
+
+ <!-- linux aarch64 骞冲彴 (淇濈暀瀵瑰簲骞冲彴鐨勯厤缃紝鍙互鍑忓皬鍖呭ぇ灏�)-->
+ <!-- <dependency>-->
+ <!-- <groupId>org.bytedeco</groupId>-->
+ <!-- <artifactId>javacpp</artifactId>-->
+ <!-- <version>${javacv.version}</version>-->
+ <!-- <classifier>${javacv.platform.linux-arm64}</classifier>-->
+ <!-- </dependency>-->
+
+ <!-- <dependency>-->
+ <!-- <groupId>org.bytedeco</groupId>-->
+ <!-- <artifactId>ffmpeg</artifactId>-->
+ <!-- <version>6.1.1-1.5.10</version>-->
+ <!-- <classifier>${javacv.platform.linux-arm64}</classifier>-->
+ <!-- </dependency>-->
+
+ <!-- <dependency>-->
+ <!-- <groupId>org.bytedeco</groupId>-->
+ <!-- <artifactId>openblas</artifactId>-->
+ <!-- <version>0.3.26-1.5.10</version>-->
+ <!-- <classifier>${javacv.platform.linux-arm64}</classifier>-->
+ <!-- </dependency>-->
+
+ <!-- <dependency>-->
+ <!-- <groupId>org.bytedeco</groupId>-->
+ <!-- <artifactId>opencv</artifactId>-->
+ <!-- <version>4.9.0-1.5.10</version>-->
+ <!-- <classifier>${javacv.platform.linux-arm64}</classifier>-->
+ <!-- </dependency>-->
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>logback-spring.xml</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>false</filtering>
+ <includes>
+ <include>PP_OCRv5/**</include>
+ </includes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ <encoding>UTF-8</encoding>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${spring-boot.version}</version>
+ <configuration>
+ <mainClass>com.xindao.ocr.OcrToolApplication</mainClass>
+ </configuration>
+ <executions>
+ <execution>
+ <id>repackage</id>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+
+ <!-- 蹇呴』娣诲姞锛歋CM淇℃伅 -->
+ <scm>
+ <connection>scm:git:git://github.com/geekwenjie/SmartJavaAI.git</connection>
+ <developerConnection>scm:git:ssh://github.com/geekwenjie/SmartJavaAI.git</developerConnection>
+ <url>http://github.com/geekwenjie/SmartJavaAI/tree/master</url>
+ </scm>
+
+ <developers>
+ <developer>
+ <name>dengwenjie</name>
+ <email>775747758@qq.com</email>
+ <roles>
+ <role>Project Manager</role>
+ <role>Architect</role>
+ </roles>
+ </developer>
+ </developers>
+
+</project>
\ No newline at end of file
diff --git a/src/main/java/com/xindao/ocr/OcrToolApplication.java b/src/main/java/com/xindao/ocr/OcrToolApplication.java
new file mode 100644
index 0000000..7644f86
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/OcrToolApplication.java
@@ -0,0 +1,16 @@
+package com.xindao.ocr;
+
+import org.springframework.boot.WebApplicationType;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+
+@SpringBootApplication
+public class OcrToolApplication {
+
+ public static void main(String[] args) {
+ SpringApplicationBuilder builder = new SpringApplicationBuilder(OcrToolApplication.class);
+ builder.headless(false).web(WebApplicationType.NONE).run(args);
+ System.out.println("OCR Tool Application is running...");
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/config/DirectionModelConfig.java b/src/main/java/com/xindao/ocr/smartjavaai/config/DirectionModelConfig.java
new file mode 100644
index 0000000..153d96e
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/config/DirectionModelConfig.java
@@ -0,0 +1,33 @@
+package com.xindao.ocr.smartjavaai.config;
+
+import cn.smartjavaai.common.config.ModelConfig;
+import com.xindao.ocr.smartjavaai.enums.DirectionModelEnum;
+import com.xindao.ocr.smartjavaai.model.common.detect.OcrCommonDetModel;
+import lombok.Data;
+
+/**
+ * 鏂囨湰鏂瑰悜鍒嗙被妯″瀷閰嶇疆
+ * @author dwj
+ * @date 2025/4/22
+ */
+@Data
+public class DirectionModelConfig extends ModelConfig {
+
+ /**
+ * 妯″瀷
+ */
+ private DirectionModelEnum modelEnum;
+
+ /**
+ * 妫�娴嬫ā鍨嬭矾寰�
+ */
+ private String modelPath;
+
+ /**
+ * 鏂囨湰妫�娴嬫ā鍨�
+ */
+ private OcrCommonDetModel textDetModel;
+
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/config/OcrDetModelConfig.java b/src/main/java/com/xindao/ocr/smartjavaai/config/OcrDetModelConfig.java
new file mode 100644
index 0000000..b4a0d66
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/config/OcrDetModelConfig.java
@@ -0,0 +1,26 @@
+package com.xindao.ocr.smartjavaai.config;
+
+import cn.smartjavaai.common.config.ModelConfig;
+import com.xindao.ocr.smartjavaai.enums.CommonDetModelEnum;
+import lombok.Data;
+
+/**
+ * OCR妫�娴嬫ā鍨嬮厤缃�
+ * @author dwj
+ * @date 2025/4/22
+ */
+@Data
+public class OcrDetModelConfig extends ModelConfig {
+
+ /**
+ * 妯″瀷
+ */
+ private CommonDetModelEnum modelEnum;
+
+ /**
+ * 妫�娴嬫ā鍨嬭矾寰�
+ */
+ private String detModelPath;
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/config/OcrRecModelConfig.java b/src/main/java/com/xindao/ocr/smartjavaai/config/OcrRecModelConfig.java
new file mode 100644
index 0000000..0e146ae
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/config/OcrRecModelConfig.java
@@ -0,0 +1,37 @@
+package com.xindao.ocr.smartjavaai.config;
+
+import cn.smartjavaai.common.config.ModelConfig;
+import com.xindao.ocr.smartjavaai.enums.CommonRecModelEnum;
+import com.xindao.ocr.smartjavaai.model.common.detect.OcrCommonDetModel;
+import com.xindao.ocr.smartjavaai.model.common.direction.OcrDirectionModel;
+import lombok.Data;
+
+/**
+ * OCR璇嗗埆妯″瀷閰嶇疆
+ * @author dwj
+ * @date 2025/4/22
+ */
+@Data
+public class OcrRecModelConfig extends ModelConfig {
+
+ /**
+ * 璇嗗埆妯″瀷
+ */
+ private CommonRecModelEnum recModelEnum;
+
+ /**
+ * 璇嗗埆妯″瀷璺緞
+ */
+ private String recModelPath;
+
+ /**
+ * 鏂囨湰妫�娴嬫ā鍨�
+ */
+ private OcrCommonDetModel textDetModel;
+
+ /**
+ * 鏂囨湰鏂瑰悜妯″瀷
+ */
+ private OcrDirectionModel directionModel;
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/config/OcrRecOptions.java b/src/main/java/com/xindao/ocr/smartjavaai/config/OcrRecOptions.java
new file mode 100644
index 0000000..1dfe777
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/config/OcrRecOptions.java
@@ -0,0 +1,31 @@
+package com.xindao.ocr.smartjavaai.config;
+
+import lombok.Data;
+
+/**
+ * OCR 璇嗗埆閰嶇疆
+ *
+ * @author dwj
+ */
+@Data
+public class OcrRecOptions {
+
+ /**
+ * 鏄惁杩涜鏂囨湰鏂瑰悜鐭
+ */
+ private boolean enableDirectionCorrect = false;
+
+ /**
+ * 鏄惁杩涜缁撴灉鍒嗚
+ */
+ private boolean enableLineSplit = true;
+
+
+ public OcrRecOptions(boolean enableDirectionCorrect, boolean enableLineSplit) {
+ this.enableDirectionCorrect = enableDirectionCorrect;
+ this.enableLineSplit = enableLineSplit;
+ }
+
+ public OcrRecOptions() {
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/config/PlateDetModelConfig.java b/src/main/java/com/xindao/ocr/smartjavaai/config/PlateDetModelConfig.java
new file mode 100644
index 0000000..6802a14
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/config/PlateDetModelConfig.java
@@ -0,0 +1,40 @@
+package com.xindao.ocr.smartjavaai.config;
+
+import cn.smartjavaai.common.config.ModelConfig;
+import com.xindao.ocr.smartjavaai.enums.PlateDetModelEnum;
+import lombok.Data;
+
+/**
+ * 杞︾墝妫�娴嬫ā鍨嬮厤缃�
+ * @author dwj
+ */
+@Data
+public class PlateDetModelConfig extends ModelConfig {
+
+ /**
+ * 妯″瀷
+ */
+ private PlateDetModelEnum modelEnum;
+
+ /**
+ * 妫�娴嬫ā鍨嬭矾寰�
+ */
+ private String modelPath;
+
+ /**
+ * 缃俊搴﹂槇鍊�
+ */
+ private float confidenceThreshold;
+
+ /**
+ * iou闃堝��
+ */
+ private float iouThreshold;
+
+ /**
+ * 妫�娴嬬粨鏋滄暟閲�
+ */
+ private int topK;
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/config/PlateRecModelConfig.java b/src/main/java/com/xindao/ocr/smartjavaai/config/PlateRecModelConfig.java
new file mode 100644
index 0000000..fa23814
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/config/PlateRecModelConfig.java
@@ -0,0 +1,32 @@
+package com.xindao.ocr.smartjavaai.config;
+
+import cn.smartjavaai.common.config.ModelConfig;
+import com.xindao.ocr.smartjavaai.enums.PlateRecModelEnum;
+import com.xindao.ocr.smartjavaai.model.plate.PlateDetModel;
+import lombok.Data;
+
+/**
+ * 杞︾墝璇嗗埆妯″瀷閰嶇疆
+ * @author dwj
+ */
+@Data
+public class PlateRecModelConfig extends ModelConfig {
+
+ /**
+ * 妯″瀷
+ */
+ private PlateRecModelEnum modelEnum;
+
+ /**
+ * 妫�娴嬫ā鍨嬭矾寰�
+ */
+ private String modelPath;
+
+ /**
+ * 杞︾墝妫�娴嬫ā鍨�
+ */
+ private PlateDetModel plateDetModel;
+
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/config/TableStructureConfig.java b/src/main/java/com/xindao/ocr/smartjavaai/config/TableStructureConfig.java
new file mode 100644
index 0000000..902a737
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/config/TableStructureConfig.java
@@ -0,0 +1,25 @@
+package com.xindao.ocr.smartjavaai.config;
+
+import cn.smartjavaai.common.config.ModelConfig;
+import com.xindao.ocr.smartjavaai.enums.TableStructureModelEnum;
+import lombok.Data;
+
+/**
+ * OCR琛ㄦ牸缁撴瀯璇嗗埆妯″瀷閰嶇疆
+ * @author dwj
+ */
+@Data
+public class TableStructureConfig extends ModelConfig {
+
+ /**
+ * 妯″瀷
+ */
+ private TableStructureModelEnum modelEnum;
+
+ /**
+ * 妫�娴嬫ā鍨嬭矾寰�
+ */
+ private String modelPath;
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/entity/DirectionInfo.java b/src/main/java/com/xindao/ocr/smartjavaai/entity/DirectionInfo.java
new file mode 100644
index 0000000..ee1cbd3
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/entity/DirectionInfo.java
@@ -0,0 +1,41 @@
+package com.xindao.ocr.smartjavaai.entity;
+
+/**
+ * 鏂瑰悜妫�娴嬬粨鏋�
+ * @author Calvin
+ * @mail 179209347@qq.com
+ * @website www.aias.top
+ */
+public class DirectionInfo {
+
+ /**
+ * 鏂瑰悜 0 90 180 270
+ */
+ private String name;
+
+ /**
+ * 缃俊搴�
+ */
+ private Double prob;
+
+ public DirectionInfo(String name, Double prob) {
+ this.name = name;
+ this.prob = prob;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Double getProb() {
+ return prob;
+ }
+
+ public void setProb(Double prob) {
+ this.prob = prob;
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/entity/IdCardInfo.java b/src/main/java/com/xindao/ocr/smartjavaai/entity/IdCardInfo.java
new file mode 100644
index 0000000..6f50b64
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/entity/IdCardInfo.java
@@ -0,0 +1,12 @@
+package com.xindao.ocr.smartjavaai.entity;
+
+/**
+ * 韬唤璇佷俊鎭�
+ * @author dwj
+ * @date 2025/5/22
+ */
+public class IdCardInfo {
+
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/entity/ImageInfo.java b/src/main/java/com/xindao/ocr/smartjavaai/entity/ImageInfo.java
new file mode 100644
index 0000000..df96ccc
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/entity/ImageInfo.java
@@ -0,0 +1,50 @@
+package com.xindao.ocr.smartjavaai.entity;
+
+import ai.djl.modality.cv.Image;
+import ai.djl.ndarray.NDArray;
+/**
+ * 鍥惧儚淇℃伅
+ */
+public class ImageInfo {
+ private String name;
+ private Double prob;
+ private Image image;
+ private NDArray box;
+
+ public ImageInfo(Image image, NDArray box) {
+ this.image = image;
+ this.box = box;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Double getProb() {
+ return prob;
+ }
+
+ public void setProb(Double prob) {
+ this.prob = prob;
+ }
+
+ public Image getImage() {
+ return image;
+ }
+
+ public void setImage(Image image) {
+ this.image = image;
+ }
+
+ public NDArray getBox() {
+ return box;
+ }
+
+ public void setBox(NDArray box) {
+ this.box = box;
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/entity/OcrBox.java b/src/main/java/com/xindao/ocr/smartjavaai/entity/OcrBox.java
new file mode 100644
index 0000000..0c89bd9
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/entity/OcrBox.java
@@ -0,0 +1,72 @@
+package com.xindao.ocr.smartjavaai.entity;
+
+import cn.smartjavaai.common.entity.DetectionRectangle;
+import cn.smartjavaai.common.entity.Point;
+import lombok.Data;
+
+/**
+ * OCR 妫�娴嬫
+ * @author dwj
+ * @date 2025/5/20
+ */
+@Data
+public class OcrBox {
+
+ /**
+ * 宸︿笂瑙�
+ */
+ private Point topLeft;
+
+ /**
+ * 鍙充笂瑙�
+ */
+ private Point topRight;
+
+ /**
+ * 鍙充笅瑙�
+ */
+ private Point bottomRight;
+
+ /**
+ * 宸︿笅瑙�
+ */
+ private Point bottomLeft;
+
+ public OcrBox(Point topLeft, Point topRight, Point bottomRight, Point bottomLeft) {
+ this.topLeft = topLeft;
+ this.topRight = topRight;
+ this.bottomRight = bottomRight;
+ this.bottomLeft = bottomLeft;
+ }
+
+ public OcrBox() {
+ }
+
+ public float[] toFloatArray() {
+ return new float[]{
+ (float)topLeft.getX(), (float)topLeft.getY(),
+ (float)topRight.getX(), (float)topRight.getY(),
+ (float)bottomRight.getX(), (float)bottomRight.getY(),
+ (float)bottomLeft.getX(), (float)bottomLeft.getY()
+ };
+ }
+
+ /**
+ * 杞崲涓� DetectionRectangle锛屼娇鐢ㄦ渶灏忓鍖呯煩褰�
+ */
+ public DetectionRectangle toDetectionRectangle() {
+ float[] pts = toFloatArray();
+ float minX = Math.min(Math.min(pts[0], pts[2]), Math.min(pts[4], pts[6]));
+ float minY = Math.min(Math.min(pts[1], pts[3]), Math.min(pts[5], pts[7]));
+ float maxX = Math.max(Math.max(pts[0], pts[2]), Math.max(pts[4], pts[6]));
+ float maxY = Math.max(Math.max(pts[1], pts[3]), Math.max(pts[5], pts[7]));
+ DetectionRectangle rect = new DetectionRectangle();
+ rect.setX((int) minX);
+ rect.setY((int) minY);
+ rect.setWidth((int) (maxX - minX));
+ rect.setHeight((int) (maxY - minY));
+ return rect;
+ }
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/entity/OcrInfo.java b/src/main/java/com/xindao/ocr/smartjavaai/entity/OcrInfo.java
new file mode 100644
index 0000000..8a80bc9
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/entity/OcrInfo.java
@@ -0,0 +1,37 @@
+package com.xindao.ocr.smartjavaai.entity;
+
+import lombok.Data;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * OCR淇℃伅
+ * @author dwj
+ * @date 2025/5/20
+ */
+@Data
+public class OcrInfo {
+
+ private List<List<OcrItem>> lineList;
+
+ private List<OcrItem> ocrItemList;
+
+ private String fullText;
+
+ private String base64Img;
+
+
+ public OcrInfo(List<List<OcrItem>> lineList, String fullText) {
+ this.lineList = lineList;
+ this.fullText = fullText;
+ }
+ public OcrInfo() {
+ }
+
+ public List<OcrItem> flattenLines() {
+ return lineList.stream()
+ .flatMap(List::stream)
+ .collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/entity/OcrItem.java b/src/main/java/com/xindao/ocr/smartjavaai/entity/OcrItem.java
new file mode 100644
index 0000000..cb672d2
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/entity/OcrItem.java
@@ -0,0 +1,54 @@
+package com.xindao.ocr.smartjavaai.entity;
+
+import com.xindao.ocr.smartjavaai.enums.AngleEnum;
+import lombok.Data;
+
+/**
+ * @author dwj
+ * @date 2025/5/20
+ */
+@Data
+public class OcrItem {
+
+ /**
+ * 璇嗗埆妗�
+ */
+ private OcrBox ocrBox;
+
+ /**
+ * 鏂囨湰
+ */
+ private String text;
+
+ /**
+ * 鏂瑰悜
+ */
+ private AngleEnum angle;
+
+ /**
+ * 妫�娴嬪緱鍒�
+ */
+ private float score;
+
+
+ public OcrItem(OcrBox ocrBox, String text) {
+ this.ocrBox = ocrBox;
+ this.text = text;
+ }
+
+ public OcrItem() {
+ }
+
+ public OcrItem(OcrBox ocrBox, String text, AngleEnum angle) {
+ this.ocrBox = ocrBox;
+ this.text = text;
+ this.angle = angle;
+ }
+
+ public OcrItem(OcrBox ocrBox, AngleEnum angle, float score) {
+ this.ocrBox = ocrBox;
+ this.angle = angle;
+ this.score = score;
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/entity/PlateInfo.java b/src/main/java/com/xindao/ocr/smartjavaai/entity/PlateInfo.java
new file mode 100644
index 0000000..defe9ca
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/entity/PlateInfo.java
@@ -0,0 +1,45 @@
+package com.xindao.ocr.smartjavaai.entity;
+
+import cn.smartjavaai.common.entity.DetectionRectangle;
+import com.xindao.ocr.smartjavaai.enums.PlateType;
+import lombok.Data;
+
+/**
+ * 杞︾墝璇嗗埆淇℃伅
+ * @author dwj
+ */
+@Data
+public class PlateInfo {
+
+ /**
+ * 杞︾墝绫诲瀷
+ */
+ private PlateType plateType;
+
+ /**
+ * 杞︾墝鍙风爜
+ */
+ private String plateNumber;
+
+ /**
+ * 杞︾墝棰滆壊
+ */
+ private String plateColor;
+
+ /**
+ * 妫�娴嬩綅缃俊鎭�
+ */
+ private DetectionRectangle detectionRectangle;
+
+ /**
+ * 杞︾墝4瑙掑潗鏍�
+ */
+ private OcrBox box;
+
+ /**
+ * 妫�娴嬪緱鍒�
+ */
+ private float score;
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/entity/PlateResult.java b/src/main/java/com/xindao/ocr/smartjavaai/entity/PlateResult.java
new file mode 100644
index 0000000..539ae09
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/entity/PlateResult.java
@@ -0,0 +1,35 @@
+package com.xindao.ocr.smartjavaai.entity;
+
+import lombok.Data;
+
+/**
+ * @author dwj
+ */
+@Data
+public class PlateResult {
+
+ /**
+ * 杞︾墝鍙风爜
+ */
+ private String plateNo;
+
+ /**
+ * 杞︾墝棰滆壊
+ */
+ private String plateColor;
+
+ public PlateResult(String plateNo, String plateColor) {
+ this.plateNo = plateNo;
+ this.plateColor = plateColor;
+ }
+
+
+ @Override
+ public String toString() {
+ return "PlateResult{" +
+ "plateNo='" + plateNo + '\'' +
+ ", plateColor='" + plateColor + '\'' +
+ '}';
+ }
+}
+
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/entity/RotatedBox.java b/src/main/java/com/xindao/ocr/smartjavaai/entity/RotatedBox.java
new file mode 100644
index 0000000..2fd3dea
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/entity/RotatedBox.java
@@ -0,0 +1,46 @@
+package com.xindao.ocr.smartjavaai.entity;
+
+import ai.djl.ndarray.NDArray;
+/**
+ * 鏃嬭浆妫�娴嬫
+ */
+public class RotatedBox implements Comparable<RotatedBox> {
+ private NDArray box;
+ private String text;
+
+ public RotatedBox(NDArray box, String text) {
+ this.box = box;
+ this.text = text;
+ }
+
+ /**
+ * 灏嗗乏涓婅 Y 鍧愭爣鍗囧簭鎺掑簭
+ *
+ * @param o
+ * @return
+ */
+ @Override
+ public int compareTo(RotatedBox o) {
+ NDArray lowBox = this.getBox();
+ NDArray highBox = o.getBox();
+ float lowY = lowBox.toFloatArray()[1];
+ float highY = highBox.toFloatArray()[1];
+ return (lowY < highY) ? -1 : 1;
+ }
+
+ public NDArray getBox() {
+ return box;
+ }
+
+ public void setBox(NDArray box) {
+ this.box = box;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/entity/RotatedBoxCompX.java b/src/main/java/com/xindao/ocr/smartjavaai/entity/RotatedBoxCompX.java
new file mode 100644
index 0000000..d56a4f3
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/entity/RotatedBoxCompX.java
@@ -0,0 +1,47 @@
+package com.xindao.ocr.smartjavaai.entity;
+
+import ai.djl.ndarray.NDArray;
+
+/**
+ * 鏃嬭浆妫�娴嬫 - 鏀寔宸︿笂瑙� X 鍧愭爣鍗囧簭鎺掑簭
+ */
+public class RotatedBoxCompX implements Comparable<RotatedBoxCompX> {
+ private NDArray box;
+ private String text;
+
+ public RotatedBoxCompX(NDArray box, String text) {
+ this.box = box;
+ this.text = text;
+ }
+
+ /**
+ * 灏嗗乏涓婅 X 鍧愭爣鍗囧簭鎺掑簭
+ *
+ * @param o
+ * @return
+ */
+ @Override
+ public int compareTo(RotatedBoxCompX o) {
+ NDArray leftBox = this.getBox();
+ NDArray rightBox = o.getBox();
+ float leftX = leftBox.toFloatArray()[0];
+ float rightX = rightBox.toFloatArray()[0];
+ return (leftX < rightX) ? -1 : 1;
+ }
+
+ public NDArray getBox() {
+ return box;
+ }
+
+ public void setBox(NDArray box) {
+ this.box = box;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/entity/TableStructureResult.java b/src/main/java/com/xindao/ocr/smartjavaai/entity/TableStructureResult.java
new file mode 100644
index 0000000..e13df38
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/entity/TableStructureResult.java
@@ -0,0 +1,33 @@
+package com.xindao.ocr.smartjavaai.entity;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author dwj
+ */
+@Data
+public class TableStructureResult {
+
+ private List<OcrItem> ocrItemList;
+
+ private List<String> tableTagList;
+
+ private String html;
+
+
+ public TableStructureResult(List<OcrItem> ocrItemList, List<String> tableTagList) {
+ this.ocrItemList = ocrItemList;
+ this.tableTagList = tableTagList;
+ }
+
+ public TableStructureResult() {
+ }
+
+ public TableStructureResult(List<OcrItem> ocrItemList, List<String> tableTagList, String html) {
+ this.ocrItemList = ocrItemList;
+ this.tableTagList = tableTagList;
+ this.html = html;
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/enums/AngleEnum.java b/src/main/java/com/xindao/ocr/smartjavaai/enums/AngleEnum.java
new file mode 100644
index 0000000..7df895f
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/enums/AngleEnum.java
@@ -0,0 +1,38 @@
+package com.xindao.ocr.smartjavaai.enums;
+
+/**
+ * 鏂囨湰鏂瑰悜
+ * @author dwj
+ * @date 2025/5/23
+ */
+public enum AngleEnum {
+
+ ANGLE_0("0"),
+ ANGLE_90("90"),
+ ANGLE_180("180"),
+ ANGLE_270("270");
+
+ private final String value;
+
+ AngleEnum(String value) {
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public static AngleEnum fromValue(String value) {
+ for (AngleEnum angle : values()) {
+ if (angle.value.equals(value)) {
+ return angle;
+ }
+ }
+ throw new IllegalArgumentException("Invalid angle value: " + value);
+ }
+
+ @Override
+ public String toString() {
+ return value + "掳";
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/enums/CommonDetModelEnum.java b/src/main/java/com/xindao/ocr/smartjavaai/enums/CommonDetModelEnum.java
new file mode 100644
index 0000000..e279cd8
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/enums/CommonDetModelEnum.java
@@ -0,0 +1,32 @@
+package com.xindao.ocr.smartjavaai.enums;
+
+/**
+ * OCR妫�娴嬫ā鍨嬫灇涓�
+ * @author dwj
+ */
+public enum CommonDetModelEnum {
+
+ PP_OCR_V5_SERVER_DET_MODEL,
+
+ PP_OCR_V5_MOBILE_DET_MODEL,
+
+ PP_OCR_V4_SERVER_DET_MODEL,
+
+ PP_OCR_V4_MOBILE_DET_MODEL;
+
+
+ /**
+ * 鏍规嵁鍚嶇О鑾峰彇鏋氫妇 (蹇界暐澶у皬鍐欏拰涓嬪垝绾垮彉浣�)
+ */
+ public static CommonDetModelEnum fromName(String name) {
+ String formatted = name.trim().toUpperCase().replaceAll("[-_]", "");
+ for (CommonDetModelEnum model : values()) {
+ if (model.name().replaceAll("_", "").equals(formatted)) {
+ return model;
+ }
+ }
+ throw new IllegalArgumentException("鏈煡妯″瀷鍚嶇О: " + name);
+ }
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/enums/CommonRecModelEnum.java b/src/main/java/com/xindao/ocr/smartjavaai/enums/CommonRecModelEnum.java
new file mode 100644
index 0000000..d43b01e
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/enums/CommonRecModelEnum.java
@@ -0,0 +1,32 @@
+package com.xindao.ocr.smartjavaai.enums;
+
+/**
+ * OCR璇嗗埆妯″瀷鏋氫妇
+ * @author dwj
+ */
+public enum CommonRecModelEnum {
+
+ PP_OCR_V5_SERVER_REC_MODEL,
+
+ PP_OCR_V5_MOBILE_REC_MODEL,
+
+ PP_OCR_V4_SERVER_REC_MODEL,
+
+ PP_OCR_V4_MOBILE_REC_MODEL;
+
+
+ /**
+ * 鏍规嵁鍚嶇О鑾峰彇鏋氫妇 (蹇界暐澶у皬鍐欏拰涓嬪垝绾垮彉浣�)
+ */
+ public static CommonRecModelEnum fromName(String name) {
+ String formatted = name.trim().toUpperCase().replaceAll("[-_]", "");
+ for (CommonRecModelEnum model : values()) {
+ if (model.name().replaceAll("_", "").equals(formatted)) {
+ return model;
+ }
+ }
+ throw new IllegalArgumentException("鏈煡妯″瀷鍚嶇О: " + name);
+ }
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/enums/DirectionModelEnum.java b/src/main/java/com/xindao/ocr/smartjavaai/enums/DirectionModelEnum.java
new file mode 100644
index 0000000..12d4f1a
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/enums/DirectionModelEnum.java
@@ -0,0 +1,32 @@
+package com.xindao.ocr.smartjavaai.enums;
+
+/**
+ * OCR鏂囨湰鏂瑰悜鍒嗙被妯″瀷鏋氫妇
+ * @author dwj
+ * @date 2025/4/4
+ */
+public enum DirectionModelEnum {
+
+ CH_PPOCR_MOBILE_V2_CLS,
+
+ PP_LCNET_X0_25,
+
+ PP_LCNET_X1_0;
+
+
+
+ /**
+ * 鏍规嵁鍚嶇О鑾峰彇鏋氫妇 (蹇界暐澶у皬鍐欏拰涓嬪垝绾垮彉浣�)
+ */
+ public static DirectionModelEnum fromName(String name) {
+ String formatted = name.trim().toUpperCase().replaceAll("[-_]", "");
+ for (DirectionModelEnum model : values()) {
+ if (model.name().replaceAll("_", "").equals(formatted)) {
+ return model;
+ }
+ }
+ throw new IllegalArgumentException("鏈煡妯″瀷鍚嶇О: " + name);
+ }
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/enums/PlateDetModelEnum.java b/src/main/java/com/xindao/ocr/smartjavaai/enums/PlateDetModelEnum.java
new file mode 100644
index 0000000..f18deb9
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/enums/PlateDetModelEnum.java
@@ -0,0 +1,28 @@
+package com.xindao.ocr.smartjavaai.enums;
+
+/**
+ * 杞︾墝妫�娴嬫ā鍨嬫灇涓�
+ * @author dwj
+ */
+public enum PlateDetModelEnum {
+
+ YOLOV5,
+
+ YOLOV7;
+
+
+ /**
+ * 鏍规嵁鍚嶇О鑾峰彇鏋氫妇 (蹇界暐澶у皬鍐欏拰涓嬪垝绾垮彉浣�)
+ */
+ public static PlateDetModelEnum fromName(String name) {
+ String formatted = name.trim().toUpperCase().replaceAll("[-_]", "");
+ for (PlateDetModelEnum model : values()) {
+ if (model.name().replaceAll("_", "").equals(formatted)) {
+ return model;
+ }
+ }
+ throw new IllegalArgumentException("鏈煡妯″瀷鍚嶇О: " + name);
+ }
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/enums/PlateRecModelEnum.java b/src/main/java/com/xindao/ocr/smartjavaai/enums/PlateRecModelEnum.java
new file mode 100644
index 0000000..293c482
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/enums/PlateRecModelEnum.java
@@ -0,0 +1,26 @@
+package com.xindao.ocr.smartjavaai.enums;
+
+/**
+ * 杞︾墝璇嗗埆妯″瀷鏋氫妇
+ * @author dwj
+ */
+public enum PlateRecModelEnum {
+
+ PLATE_REC_CRNN;
+
+
+ /**
+ * 鏍规嵁鍚嶇О鑾峰彇鏋氫妇 (蹇界暐澶у皬鍐欏拰涓嬪垝绾垮彉浣�)
+ */
+ public static PlateRecModelEnum fromName(String name) {
+ String formatted = name.trim().toUpperCase().replaceAll("[-_]", "");
+ for (PlateRecModelEnum model : values()) {
+ if (model.name().replaceAll("_", "").equals(formatted)) {
+ return model;
+ }
+ }
+ throw new IllegalArgumentException("鏈煡妯″瀷鍚嶇О: " + name);
+ }
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/enums/PlateType.java b/src/main/java/com/xindao/ocr/smartjavaai/enums/PlateType.java
new file mode 100644
index 0000000..4dcdbc8
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/enums/PlateType.java
@@ -0,0 +1,45 @@
+package com.xindao.ocr.smartjavaai.enums;
+
+/**
+ * @author dwj
+ */
+public enum PlateType {
+
+ SINGLE("single", "鍗曞眰"),
+ DOUBLE("double", "鍙屽眰"),
+ UNKNOWN("unknown", "鏈煡");
+
+ private final String className;
+ private final String description;
+
+ PlateType(String className, String description) {
+ this.className = className;
+ this.description = description;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+
+
+
+ /**
+ * 鏍规嵁value鑾峰彇瀵瑰簲鐨凱lateType
+ * @param className
+ * @return PlateType
+ */
+ public static PlateType fromClassName(String className) {
+ for (PlateType type : values()) {
+ if (type.className.equals(className)) {
+ return type;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/enums/TableStructureModelEnum.java b/src/main/java/com/xindao/ocr/smartjavaai/enums/TableStructureModelEnum.java
new file mode 100644
index 0000000..8b6cbd2
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/enums/TableStructureModelEnum.java
@@ -0,0 +1,30 @@
+package com.xindao.ocr.smartjavaai.enums;
+
+/**
+ * OCR琛ㄦ牸缁撴瀯妯″瀷鏋氫妇
+ * @author dwj
+ */
+public enum TableStructureModelEnum {
+
+ SLANET,
+ //SLANEXT_WIRED,
+ SLANET_PLUS;
+
+
+
+
+ /**
+ * 鏍规嵁鍚嶇О鑾峰彇鏋氫妇 (蹇界暐澶у皬鍐欏拰涓嬪垝绾垮彉浣�)
+ */
+ public static TableStructureModelEnum fromName(String name) {
+ String formatted = name.trim().toUpperCase().replaceAll("[-_]", "");
+ for (TableStructureModelEnum model : values()) {
+ if (model.name().replaceAll("_", "").equals(formatted)) {
+ return model;
+ }
+ }
+ throw new IllegalArgumentException("鏈煡妯″瀷鍚嶇О: " + name);
+ }
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/exception/OcrException.java b/src/main/java/com/xindao/ocr/smartjavaai/exception/OcrException.java
new file mode 100644
index 0000000..ef6c1b7
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/exception/OcrException.java
@@ -0,0 +1,30 @@
+package com.xindao.ocr.smartjavaai.exception;
+
+/**
+ * OCR寮傚父
+ * @author dwj
+ * @date 2025/4/4
+ */
+public class OcrException extends RuntimeException{
+
+ public OcrException() {
+ super();
+ }
+
+ public OcrException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+
+ public OcrException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public OcrException(String message) {
+ super(message);
+ }
+
+ public OcrException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/factory/OcrModelFactory.java b/src/main/java/com/xindao/ocr/smartjavaai/factory/OcrModelFactory.java
new file mode 100644
index 0000000..7ddccb0
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/factory/OcrModelFactory.java
@@ -0,0 +1,223 @@
+package com.xindao.ocr.smartjavaai.factory;
+
+import cn.smartjavaai.common.config.Config;
+import com.xindao.ocr.smartjavaai.config.DirectionModelConfig;
+import com.xindao.ocr.smartjavaai.config.OcrDetModelConfig;
+import com.xindao.ocr.smartjavaai.config.OcrRecModelConfig;
+import com.xindao.ocr.smartjavaai.enums.CommonDetModelEnum;
+import com.xindao.ocr.smartjavaai.enums.CommonRecModelEnum;
+import com.xindao.ocr.smartjavaai.enums.DirectionModelEnum;
+import com.xindao.ocr.smartjavaai.exception.OcrException;
+import com.xindao.ocr.smartjavaai.model.common.detect.OcrCommonDetModel;
+import com.xindao.ocr.smartjavaai.model.common.detect.OcrCommonDetModelImpl;
+import com.xindao.ocr.smartjavaai.model.common.direction.OcrDirectionModel;
+import com.xindao.ocr.smartjavaai.model.common.direction.PPOCRMobileV2ClsModel;
+import com.xindao.ocr.smartjavaai.model.common.recognize.OcrCommonRecModel;
+import com.xindao.ocr.smartjavaai.model.common.recognize.OcrCommonRecModelImpl;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * OCR妯″瀷宸ュ巶
+ * @author dwj
+ */
+@Slf4j
+public class OcrModelFactory {
+
+ // 浣跨敤 volatile 鍜屽弻閲嶆鏌ラ攣瀹氭潵纭繚绾跨▼瀹夊叏鐨勫崟渚嬫ā寮�
+ private static volatile OcrModelFactory instance;
+
+ private static final ConcurrentHashMap<CommonDetModelEnum, OcrCommonDetModel> commonDetModelMap = new ConcurrentHashMap<>();
+
+
+ private static final ConcurrentHashMap<CommonRecModelEnum, OcrCommonRecModel> commonRecModelMap = new ConcurrentHashMap<>();
+
+ private static final ConcurrentHashMap<DirectionModelEnum, OcrDirectionModel> directionModelMap = new ConcurrentHashMap<>();
+
+ /**
+ * 妫�娴嬫ā鍨嬫敞鍐岃〃
+ */
+ private static final Map<CommonDetModelEnum, Class<? extends OcrCommonDetModel>> commonDetRegistry =
+ new ConcurrentHashMap<>();
+
+ /**
+ * 璇嗗埆妯″瀷娉ㄥ唽琛�
+ */
+ private static final Map<CommonRecModelEnum, Class<? extends OcrCommonRecModel>> commonRecRegistry =
+ new ConcurrentHashMap<>();
+
+ /**
+ * 鏂瑰悜鍒嗙被妯″瀷娉ㄥ唽琛�
+ */
+ private static final Map<DirectionModelEnum, Class<? extends OcrDirectionModel>> directionRegistry =
+ new ConcurrentHashMap<>();
+
+
+ public static OcrModelFactory getInstance() {
+ if (instance == null) {
+ synchronized (OcrModelFactory.class) {
+ if (instance == null) {
+ instance = new OcrModelFactory();
+ }
+ }
+ }
+ return instance;
+ }
+
+
+
+ /**
+ * 娉ㄥ唽閫氱敤妫�娴嬫ā鍨�
+ * @param detModelEnum
+ * @param clazz
+ */
+ private static void registerCommonDetModel(CommonDetModelEnum detModelEnum, Class<? extends OcrCommonDetModel> clazz) {
+ commonDetRegistry.put(detModelEnum, clazz);
+ }
+
+ /**
+ * 娉ㄥ唽閫氱敤璇嗗埆妯″瀷
+ * @param recModelEnum
+ * @param clazz
+ */
+ private static void registerCommonRecModel(CommonRecModelEnum recModelEnum, Class<? extends OcrCommonRecModel> clazz) {
+ commonRecRegistry.put(recModelEnum, clazz);
+ }
+
+ /**
+ * 娉ㄥ唽閫氱敤鏂瑰悜鍒嗙被妯″瀷
+ * @param directionModelEnum
+ * @param clazz
+ */
+ private static void registerDirectionModel(DirectionModelEnum directionModelEnum, Class<? extends OcrDirectionModel> clazz) {
+ directionRegistry.put(directionModelEnum, clazz);
+ }
+
+
+ /**
+ * 鑾峰彇妫�娴嬫ā鍨嬶紙閫氳繃閰嶇疆锛�
+ * @param config
+ * @return
+ */
+ public OcrCommonDetModel getDetModel(OcrDetModelConfig config) {
+ if(Objects.isNull(config) || Objects.isNull(config.getModelEnum())){
+ throw new OcrException("鏈厤缃甇CR妯″瀷");
+ }
+ return commonDetModelMap.computeIfAbsent(config.getModelEnum(), k -> {
+ return createCommonDetModel(config);
+ });
+ }
+
+ /**
+ * 鑾峰彇璇嗗埆妯″瀷锛堥�氳繃閰嶇疆锛�
+ * @param config
+ * @return
+ */
+ public OcrCommonRecModel getRecModel(OcrRecModelConfig config) {
+ if(Objects.isNull(config) || Objects.isNull(config.getRecModelEnum())){
+ throw new OcrException("鏈厤缃甇CR妯″瀷");
+ }
+ return commonRecModelMap.computeIfAbsent(config.getRecModelEnum(), k -> {
+ return createCommonRecModel(config);
+ });
+ }
+
+ /**
+ * 鑾峰彇妯″瀷锛堥�氳繃閰嶇疆锛�
+ * @param config
+ * @return
+ */
+ public OcrDirectionModel getDirectionModel(DirectionModelConfig config) {
+ if(Objects.isNull(config) || Objects.isNull(config.getModelEnum())){
+ throw new OcrException("鏈厤缃甇CR妯″瀷");
+ }
+ return directionModelMap.computeIfAbsent(config.getModelEnum(), k -> {
+ return createDirectionModel(config);
+ });
+ }
+
+
+
+ /**
+ * 鍒涘缓OCR閫氱敤妫�娴嬫ā鍨�
+ * @param config
+ * @return
+ */
+ private OcrCommonDetModel createCommonDetModel(OcrDetModelConfig config) {
+ Class<?> clazz = commonDetRegistry.get(config.getModelEnum());
+ if(clazz == null){
+ throw new OcrException("Unsupported model");
+ }
+ OcrCommonDetModel model = null;
+ try {
+ model = (OcrCommonDetModel) clazz.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ throw new OcrException(e);
+ }
+ model.loadModel(config);
+ return model;
+ }
+
+
+ /**
+ * 鍒涘缓OCR閫氱敤璇嗗埆妯″瀷
+ * @param config
+ * @return
+ */
+ private OcrCommonRecModel createCommonRecModel(OcrRecModelConfig config) {
+ Class<?> clazz = commonRecRegistry.get(config.getRecModelEnum());
+ if(clazz == null){
+ throw new OcrException("Unsupported model");
+ }
+ OcrCommonRecModel model = null;
+ try {
+ model = (OcrCommonRecModel) clazz.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ throw new OcrException(e);
+ }
+ model.loadModel(config);
+ return model;
+ }
+
+ /**
+ * 鍒涘缓OCR鏂瑰悜鍒嗙被妯″瀷
+ * @param config
+ * @return
+ */
+ private OcrDirectionModel createDirectionModel(DirectionModelConfig config) {
+ Class<?> clazz = directionRegistry.get(config.getModelEnum());
+ if(clazz == null){
+ throw new OcrException("Unsupported model");
+ }
+ OcrDirectionModel model = null;
+ try {
+ model = (OcrDirectionModel) clazz.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ throw new OcrException(e);
+ }
+ model.loadModel(config);
+ return model;
+ }
+
+
+ // 鍒濆鍖栭粯璁ょ畻娉�
+ static {
+ //閫氱敤-妫�娴嬫ā鍨�
+ registerCommonDetModel(CommonDetModelEnum.PP_OCR_V5_SERVER_DET_MODEL, OcrCommonDetModelImpl.class);
+ registerCommonDetModel(CommonDetModelEnum.PP_OCR_V5_MOBILE_DET_MODEL, OcrCommonDetModelImpl.class);
+ registerCommonDetModel(CommonDetModelEnum.PP_OCR_V4_SERVER_DET_MODEL, OcrCommonDetModelImpl.class);
+ registerCommonDetModel(CommonDetModelEnum.PP_OCR_V4_MOBILE_DET_MODEL, OcrCommonDetModelImpl.class);
+ registerCommonRecModel(CommonRecModelEnum.PP_OCR_V5_SERVER_REC_MODEL, OcrCommonRecModelImpl.class);
+ registerCommonRecModel(CommonRecModelEnum.PP_OCR_V5_MOBILE_REC_MODEL, OcrCommonRecModelImpl.class);
+ registerCommonRecModel(CommonRecModelEnum.PP_OCR_V4_SERVER_REC_MODEL, OcrCommonRecModelImpl.class);
+ registerCommonRecModel(CommonRecModelEnum.PP_OCR_V4_MOBILE_REC_MODEL, OcrCommonRecModelImpl.class);
+ registerDirectionModel(DirectionModelEnum.CH_PPOCR_MOBILE_V2_CLS, PPOCRMobileV2ClsModel.class);
+ registerDirectionModel(DirectionModelEnum.PP_LCNET_X0_25, PPOCRMobileV2ClsModel.class);
+ registerDirectionModel(DirectionModelEnum.PP_LCNET_X1_0, PPOCRMobileV2ClsModel.class);
+ log.debug("缂撳瓨鐩綍锛歿}", Config.getCachePath());
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/factory/PlateModelFactory.java b/src/main/java/com/xindao/ocr/smartjavaai/factory/PlateModelFactory.java
new file mode 100644
index 0000000..d20df83
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/factory/PlateModelFactory.java
@@ -0,0 +1,164 @@
+package com.xindao.ocr.smartjavaai.factory;
+
+import cn.smartjavaai.common.config.Config;
+import com.xindao.ocr.smartjavaai.config.PlateDetModelConfig;
+import com.xindao.ocr.smartjavaai.config.PlateRecModelConfig;
+import com.xindao.ocr.smartjavaai.enums.PlateDetModelEnum;
+import com.xindao.ocr.smartjavaai.enums.PlateRecModelEnum;
+import com.xindao.ocr.smartjavaai.exception.OcrException;
+import com.xindao.ocr.smartjavaai.model.plate.CRNNPlateRecModel;
+import com.xindao.ocr.smartjavaai.model.plate.PlateDetModel;
+import com.xindao.ocr.smartjavaai.model.plate.PlateRecModel;
+import com.xindao.ocr.smartjavaai.model.plate.Yolov5PlateDetModel;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 杞︾墝璇嗗埆妯″瀷宸ュ巶
+ * @author dwj
+ */
+@Slf4j
+public class PlateModelFactory {
+
+ // 浣跨敤 volatile 鍜屽弻閲嶆鏌ラ攣瀹氭潵纭繚绾跨▼瀹夊叏鐨勫崟渚嬫ā寮�
+ private static volatile PlateModelFactory instance;
+
+ /**
+ * 妯″瀷缂撳瓨
+ */
+ private static final ConcurrentHashMap<PlateDetModelEnum, PlateDetModel> detModelMap = new ConcurrentHashMap<>();
+
+ /**
+ * 妯″瀷缂撳瓨
+ */
+ private static final ConcurrentHashMap<PlateRecModelEnum, PlateRecModel> recModelMap = new ConcurrentHashMap<>();
+
+
+ /**
+ * 妯″瀷娉ㄥ唽琛�
+ */
+ private static final Map<PlateDetModelEnum, Class<? extends PlateDetModel>> detModelRegistry =
+ new ConcurrentHashMap<>();
+
+ /**
+ * 妯″瀷娉ㄥ唽琛�
+ */
+ private static final Map<PlateRecModelEnum, Class<? extends PlateRecModel>> recModelRegistry =
+ new ConcurrentHashMap<>();
+
+
+ public static PlateModelFactory getInstance() {
+ if (instance == null) {
+ synchronized (PlateModelFactory.class) {
+ if (instance == null) {
+ instance = new PlateModelFactory();
+ }
+ }
+ }
+ return instance;
+ }
+
+
+
+ /**
+ * 娉ㄥ唽妯″瀷
+ * @param plateDetModelEnum
+ * @param clazz
+ */
+ private static void registerDetModel(PlateDetModelEnum plateDetModelEnum, Class<? extends PlateDetModel> clazz) {
+ detModelRegistry.put(plateDetModelEnum, clazz);
+ }
+
+ /**
+ * 娉ㄥ唽妯″瀷
+ * @param plateRecModelEnum
+ * @param clazz
+ */
+ private static void registerRecModel(PlateRecModelEnum plateRecModelEnum, Class<? extends PlateRecModel> clazz) {
+ recModelRegistry.put(plateRecModelEnum, clazz);
+ }
+
+
+ /**
+ * 鑾峰彇妯″瀷
+ * @param config
+ * @return
+ */
+ public PlateDetModel getDetModel(PlateDetModelConfig config) {
+ if(Objects.isNull(config) || Objects.isNull(config.getModelEnum())){
+ throw new OcrException("鏈厤缃甇CR妯″瀷");
+ }
+ return detModelMap.computeIfAbsent(config.getModelEnum(), k -> {
+ return createDetModel(config);
+ });
+ }
+
+ /**
+ * 鑾峰彇妯″瀷
+ * @param config
+ * @return
+ */
+ public PlateRecModel getRecModel(PlateRecModelConfig config) {
+ if(Objects.isNull(config) || Objects.isNull(config.getModelEnum())){
+ throw new OcrException("鏈厤缃甇CR妯″瀷");
+ }
+ return recModelMap.computeIfAbsent(config.getModelEnum(), k -> {
+ return createRecModel(config);
+ });
+ }
+
+
+
+ /**
+ * 鍒涘缓妫�娴嬫ā鍨�
+ * @param config
+ * @return
+ */
+ private PlateDetModel createDetModel(PlateDetModelConfig config) {
+ Class<?> clazz = detModelRegistry.get(config.getModelEnum());
+ if(clazz == null){
+ throw new OcrException("Unsupported model");
+ }
+ PlateDetModel model = null;
+ try {
+ model = (PlateDetModel) clazz.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ throw new OcrException(e);
+ }
+ model.loadModel(config);
+ return model;
+ }
+
+ /**
+ * 鍒涘缓璇嗗埆妯″瀷
+ * @param config
+ * @return
+ */
+ private PlateRecModel createRecModel(PlateRecModelConfig config) {
+ Class<?> clazz = recModelRegistry.get(config.getModelEnum());
+ if(clazz == null){
+ throw new OcrException("Unsupported model");
+ }
+ PlateRecModel model = null;
+ try {
+ model = (PlateRecModel) clazz.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ throw new OcrException(e);
+ }
+ model.loadModel(config);
+ return model;
+ }
+
+
+ // 鍒濆鍖栭粯璁ょ畻娉�
+ static {
+ registerDetModel(PlateDetModelEnum.YOLOV5, Yolov5PlateDetModel.class);
+ registerDetModel(PlateDetModelEnum.YOLOV7, Yolov5PlateDetModel.class);
+ registerRecModel(PlateRecModelEnum.PLATE_REC_CRNN, CRNNPlateRecModel.class);
+ log.debug("缂撳瓨鐩綍锛歿}", Config.getCachePath());
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/factory/TableRecModelFactory.java b/src/main/java/com/xindao/ocr/smartjavaai/factory/TableRecModelFactory.java
new file mode 100644
index 0000000..ac679a6
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/factory/TableRecModelFactory.java
@@ -0,0 +1,107 @@
+package com.xindao.ocr.smartjavaai.factory;
+
+import cn.smartjavaai.common.config.Config;
+import com.xindao.ocr.smartjavaai.config.TableStructureConfig;
+import com.xindao.ocr.smartjavaai.enums.TableStructureModelEnum;
+import com.xindao.ocr.smartjavaai.exception.OcrException;
+import com.xindao.ocr.smartjavaai.model.table.CommonTableStructureModel;
+import com.xindao.ocr.smartjavaai.model.table.TableStructureModel;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * OCR 琛ㄦ牸璇嗗埆妯″瀷宸ュ巶
+ * @author dwj
+ */
+@Slf4j
+public class TableRecModelFactory {
+
+ // 浣跨敤 volatile 鍜屽弻閲嶆鏌ラ攣瀹氭潵纭繚绾跨▼瀹夊叏鐨勫崟渚嬫ā寮�
+ private static volatile TableRecModelFactory instance;
+
+ /**
+ * 妯″瀷缂撳瓨
+ */
+ private static final ConcurrentHashMap<TableStructureModelEnum, TableStructureModel> tableStructureModelMap = new ConcurrentHashMap<>();
+
+
+ /**
+ * 妯″瀷娉ㄥ唽琛�
+ */
+ private static final Map<TableStructureModelEnum, Class<? extends TableStructureModel>> tableStructureRegistry =
+ new ConcurrentHashMap<>();
+
+
+ public static TableRecModelFactory getInstance() {
+ if (instance == null) {
+ synchronized (TableRecModelFactory.class) {
+ if (instance == null) {
+ instance = new TableRecModelFactory();
+ }
+ }
+ }
+ return instance;
+ }
+
+
+
+ /**
+ * 娉ㄥ唽妯″瀷
+ * @param tableStructureModelEnum
+ * @param clazz
+ */
+ private static void registerTableStructureModel(TableStructureModelEnum tableStructureModelEnum, Class<? extends TableStructureModel> clazz) {
+ tableStructureRegistry.put(tableStructureModelEnum, clazz);
+ }
+
+
+ /**
+ * 鑾峰彇妯″瀷锛堥�氳繃閰嶇疆锛�
+ * @param config
+ * @return
+ */
+ public TableStructureModel getTableStructureModel(TableStructureConfig config) {
+ if(Objects.isNull(config) || Objects.isNull(config.getModelEnum())){
+ throw new OcrException("鏈厤缃甇CR妯″瀷");
+ }
+ return tableStructureModelMap.computeIfAbsent(config.getModelEnum(), k -> {
+ return createTableStructureModel(config);
+ });
+ }
+
+
+
+ /**
+ * 鍒涘缓妯″瀷
+ * @param config
+ * @return
+ */
+ private TableStructureModel createTableStructureModel(TableStructureConfig config) {
+ Class<?> clazz = tableStructureRegistry.get(config.getModelEnum());
+ if(clazz == null){
+ throw new OcrException("Unsupported model");
+ }
+ TableStructureModel model = null;
+ try {
+ model = (TableStructureModel) clazz.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ throw new OcrException(e);
+ }
+ model.loadModel(config);
+ return model;
+ }
+
+
+
+
+ // 鍒濆鍖栭粯璁ょ畻娉�
+ static {
+ registerTableStructureModel(TableStructureModelEnum.SLANET, CommonTableStructureModel.class);
+ registerTableStructureModel(TableStructureModelEnum.SLANET_PLUS, CommonTableStructureModel.class);
+ log.debug("缂撳瓨鐩綍锛歿}", Config.getCachePath());
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/common/detect/OcrCommonDetModel.java b/src/main/java/com/xindao/ocr/smartjavaai/model/common/detect/OcrCommonDetModel.java
new file mode 100644
index 0000000..2cf0bdd
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/common/detect/OcrCommonDetModel.java
@@ -0,0 +1,104 @@
+package com.xindao.ocr.smartjavaai.model.common.detect;
+
+import ai.djl.inference.Predictor;
+import ai.djl.modality.cv.Image;
+import ai.djl.ndarray.NDList;
+import com.xindao.ocr.smartjavaai.config.OcrDetModelConfig;
+import com.xindao.ocr.smartjavaai.entity.OcrBox;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+
+import java.awt.image.BufferedImage;
+import java.util.List;
+
+/**
+ * OCR 閫氱敤妫�娴嬫ā鍨�
+ * @author dwj
+ */
+public interface OcrCommonDetModel extends AutoCloseable{
+
+ /**
+ * 鍔犺浇妯″瀷
+ * @param config
+ */
+ void loadModel(OcrDetModelConfig config); // 鍔犺浇妯″瀷
+
+ /**
+ * 鏂囨湰妫�娴�
+ * @param imagePath 鍥剧墖璺緞
+ * @return
+ */
+ default List<OcrBox> detect(String imagePath) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 鏂囨湰妫�娴�
+ * @param image BufferedImage
+ * @return
+ */
+ default List<OcrBox> detect(BufferedImage image) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 鏂囨湰妫�娴�
+ * @param imageData 鍥剧墖瀛楄妭鏁扮粍
+ * @return
+ */
+ default List<OcrBox> detect(byte[] imageData) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 鏂囨湰妫�娴�
+ * @param image DJL Image
+ * @return
+ */
+ default List<OcrBox> detect(Image image){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 妫�娴嬪苟缁樺埗缁撴灉
+ * @param imagePath 鍥剧墖杈撳叆璺緞锛堝寘鍚枃浠跺悕绉帮級
+ * @param outputPath 鍥剧墖杈撳嚭璺緞锛堝寘鍚枃浠跺悕绉帮級
+ */
+ default void detectAndDraw(String imagePath, String outputPath) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 妫�娴嬪苟缁樺埗缁撴灉
+ * @param sourceImage
+ * @return
+ */
+ default BufferedImage detectAndDraw(BufferedImage sourceImage){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 鏂囨湰妫�娴嬶紙鎵归噺锛�
+ * @param imageList BufferedImage
+ * @return
+ */
+ default List<List<OcrBox>> batchDetect(List<BufferedImage> imageList) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 鏂囨湰妫�娴嬶紙鎵归噺锛�
+ * @param imageList DJL Image
+ * @return
+ */
+ default List<List<OcrBox>> batchDetectDJLImage(List<Image> imageList){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ default GenericObjectPool<Predictor<Image, NDList>> getPool(){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/common/detect/OcrCommonDetModelImpl.java b/src/main/java/com/xindao/ocr/smartjavaai/model/common/detect/OcrCommonDetModelImpl.java
new file mode 100644
index 0000000..7a93fb6
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/common/detect/OcrCommonDetModelImpl.java
@@ -0,0 +1,244 @@
+package com.xindao.ocr.smartjavaai.model.common.detect;
+
+import ai.djl.MalformedModelException;
+import ai.djl.engine.Engine;
+import ai.djl.inference.Predictor;
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.ImageFactory;
+import ai.djl.ndarray.NDList;
+import ai.djl.ndarray.NDManager;
+import ai.djl.repository.zoo.Criteria;
+import ai.djl.repository.zoo.ModelNotFoundException;
+import ai.djl.repository.zoo.ModelZoo;
+import ai.djl.repository.zoo.ZooModel;
+import cn.smartjavaai.common.pool.PredictorFactory;
+import cn.smartjavaai.common.utils.FileUtils;
+import cn.smartjavaai.common.utils.ImageUtils;
+import cn.smartjavaai.common.utils.OpenCVUtils;
+import com.xindao.ocr.smartjavaai.config.OcrDetModelConfig;
+import com.xindao.ocr.smartjavaai.entity.OcrBox;
+import com.xindao.ocr.smartjavaai.exception.OcrException;
+import com.xindao.ocr.smartjavaai.model.common.detect.criteria.OcrCommonDetCriterialFactory;
+import com.xindao.ocr.smartjavaai.utils.OcrUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+import org.opencv.core.Mat;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * ocr閫氱敤妫�娴嬫ā鍨嬪疄鐜扮被
+ * @author dwj
+ */
+@Slf4j
+public class OcrCommonDetModelImpl implements OcrCommonDetModel{
+
+ private GenericObjectPool<Predictor<Image, NDList>> detPredictorPool;
+
+ private ZooModel<Image, NDList> detectionModel;
+
+ private OcrDetModelConfig config;
+
+ @Override
+ public void loadModel(OcrDetModelConfig config){
+ if(StringUtils.isBlank(config.getDetModelPath())){
+ throw new OcrException("modelPath is null");
+ }
+ this.config = config;
+ //鍒濆鍖� 妫�娴婥riteria
+ Criteria<Image, NDList> detCriteria = OcrCommonDetCriterialFactory.createCriteria(config);
+ try{
+ detectionModel = ModelZoo.loadModel(detCriteria);
+ // 鍒涘缓姹犲瓙锛氭瘡涓嚎绋嬬嫭浜� Predictor
+ this.detPredictorPool = new GenericObjectPool<>(new PredictorFactory<>(detectionModel));
+ int predictorPoolSize = config.getPredictorPoolSize();
+ if(config.getPredictorPoolSize() <= 0){
+ predictorPoolSize = Runtime.getRuntime().availableProcessors(); // 榛樿绛変簬CPU鏍稿績鏁�
+ }
+ detPredictorPool.setMaxTotal(predictorPoolSize);
+ log.debug("褰撳墠璁惧: " + detectionModel.getNDManager().getDevice());
+ log.debug("褰撳墠寮曟搸: " + Engine.getInstance().getEngineName());
+ log.debug("妯″瀷鎺ㄧ悊鍣ㄧ嚎绋嬫睜鏈�澶ф暟閲�: " + predictorPoolSize);
+ } catch (IOException | ModelNotFoundException | MalformedModelException e) {
+ throw new OcrException("妫�娴嬫ā鍨嬪姞杞藉け璐�", e);
+ }
+ }
+
+ @Override
+ public List<OcrBox> detect(String imagePath){
+ if(!FileUtils.isFileExists(imagePath)){
+ throw new OcrException("鍥惧儚鏂囦欢涓嶅瓨鍦�");
+ }
+ Image img = null;
+ try {
+ img = ImageFactory.getInstance().fromFile(Paths.get(imagePath));
+ } catch (IOException e) {
+ throw new OcrException("鏃犳晥鐨勫浘鐗�", e);
+ }
+ List<OcrBox> ocrBoxList = detect(img);
+ ((Mat)img.getWrappedImage()).release();
+ return ocrBoxList;
+ }
+
+ @Override
+ public List<OcrBox> detect(Image image){
+ List<Image> imageList = Collections.singletonList(image);
+ List<List<OcrBox>> result = batchDetectDJLImage(imageList);
+ return result.get(0);
+ }
+
+ @Override
+ public void detectAndDraw(String imagePath, String outputPath) {
+ if(!FileUtils.isFileExists(imagePath)){
+ throw new OcrException("鍥惧儚鏂囦欢涓嶅瓨鍦�");
+ }
+ try {
+ Image img = ImageFactory.getInstance().fromFile(Paths.get(imagePath));
+ List<OcrBox> boxList = detect(img);
+ if(Objects.isNull(boxList) || boxList.isEmpty()){
+ throw new OcrException("鏈娴嬪埌鏂囧瓧");
+ }
+ OcrUtils.drawRect((Mat)img.getWrappedImage(), boxList);
+ Path output = Paths.get(outputPath);
+ log.debug("Saving to {}", output.toAbsolutePath().toString());
+ img.save(Files.newOutputStream(output), "png");
+ ((Mat) img.getWrappedImage()).release();
+ } catch (IOException e) {
+ throw new OcrException(e);
+ }
+ }
+
+
+ @Override
+ public List<OcrBox> detect(BufferedImage image) {
+ if(!ImageUtils.isImageValid(image)){
+ throw new OcrException("鍥惧儚鏃犳晥");
+ }
+ Image img = ImageFactory.getInstance().fromImage(OpenCVUtils.image2Mat(image));
+ List<OcrBox> ocrBoxList = detect(img);
+ ((Mat)img.getWrappedImage()).release();
+ return ocrBoxList;
+ }
+
+ @Override
+ public List<OcrBox> detect(byte[] imageData) {
+ if(Objects.isNull(imageData)){
+ throw new OcrException("鍥惧儚鏃犳晥");
+ }
+ try {
+ BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageData));
+ return detect(image);
+ } catch (IOException e) {
+ throw new OcrException("閿欒鐨勫浘鍍�", e);
+ }
+ }
+
+ @Override
+ public BufferedImage detectAndDraw(BufferedImage sourceImage) {
+ if(!ImageUtils.isImageValid(sourceImage)){
+ throw new OcrException("鍥惧儚鏃犳晥");
+ }
+ Image img = ImageFactory.getInstance().fromImage(OpenCVUtils.image2Mat(sourceImage));
+ List<OcrBox> ocrBoxList = detect(img);
+ if(Objects.isNull(ocrBoxList) || ocrBoxList.isEmpty()){
+ throw new OcrException("鏈娴嬪埌鏂囧瓧");
+ }
+ OcrUtils.drawRect((Mat)img.getWrappedImage(), ocrBoxList);
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ // 璋冪敤 save 鏂规硶灏� Image 鍐欏叆瀛楄妭娴�
+ img.save(outputStream, "png");
+ // 灏嗗瓧鑺傛祦杞崲涓� BufferedImage
+ byte[] imageBytes = outputStream.toByteArray();
+ return ImageIO.read(new ByteArrayInputStream(imageBytes));
+ } catch (IOException e) {
+ throw new OcrException("瀵煎嚭鍥剧墖澶辫触", e);
+ } finally {
+ if (img != null){
+ ((Mat) img.getWrappedImage()).release();
+ }
+ }
+ }
+
+ @Override
+ public List<List<OcrBox>> batchDetect(List<BufferedImage> imageList) {
+ List<Image> djlImageList = new ArrayList<>(imageList.size());
+ try {
+ for (BufferedImage bufferedImage : imageList) {
+ djlImageList.add(ImageFactory.getInstance().fromImage(OpenCVUtils.image2Mat(bufferedImage)));
+ }
+ return batchDetectDJLImage(djlImageList);
+ } catch (Exception e) {
+ throw new OcrException(e);
+ } finally {
+ djlImageList.forEach(image -> ((Mat)image.getWrappedImage()).release());
+ }
+ }
+
+ @Override
+ public List<List<OcrBox>> batchDetectDJLImage(List<Image> imageList) {
+ if(!ImageUtils.isAllImageSizeEqual(imageList)){
+ throw new OcrException("鍥剧墖灏哄涓嶄竴鑷�");
+ }
+ Predictor<Image, NDList> predictor = null;
+ try (NDManager manager = NDManager.newBaseManager()) {
+ predictor = detPredictorPool.borrowObject();
+ List<NDList> result = predictor.batchPredict(imageList);
+ result.forEach(ndList -> ndList.attach(manager));
+ return OcrUtils.convertToOcrBox(result);
+ } catch (Exception e) {
+ throw new OcrException("OCR妫�娴嬮敊璇�", e);
+ }finally {
+ if (predictor != null) {
+ try {
+ detPredictorPool.returnObject(predictor); //褰掕繕
+ } catch (Exception e) {
+ log.warn("褰掕繕Predictor澶辫触", e);
+ try {
+ predictor.close(); // 褰掕繕澶辫触鎵嶉攢姣�
+ } catch (Exception ex) {
+ log.error("鍏抽棴Predictor澶辫触", ex);
+ }
+ }
+ }
+
+ }
+ }
+
+ @Override
+ public GenericObjectPool<Predictor<Image, NDList>> getPool() {
+ return detPredictorPool;
+ }
+
+ @Override
+ public void close() throws Exception {
+ try {
+ if (detPredictorPool != null) {
+ detPredictorPool.close();
+ }
+ } catch (Exception e) {
+ log.warn("鍏抽棴 predictorPool 澶辫触", e);
+ }
+ try {
+ if (detectionModel != null) {
+ detectionModel.close();
+ }
+ } catch (Exception e) {
+ log.warn("鍏抽棴 model 澶辫触", e);
+ }
+ }
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/common/detect/criteria/OcrCommonDetCriterialFactory.java b/src/main/java/com/xindao/ocr/smartjavaai/model/common/detect/criteria/OcrCommonDetCriterialFactory.java
new file mode 100644
index 0000000..ca62e00
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/common/detect/criteria/OcrCommonDetCriterialFactory.java
@@ -0,0 +1,53 @@
+package com.xindao.ocr.smartjavaai.model.common.detect.criteria;
+
+import ai.djl.Device;
+import ai.djl.modality.cv.Image;
+import ai.djl.ndarray.NDList;
+import ai.djl.repository.zoo.Criteria;
+import ai.djl.training.util.ProgressBar;
+import cn.smartjavaai.common.enums.DeviceEnum;
+import com.xindao.ocr.smartjavaai.config.OcrDetModelConfig;
+import com.xindao.ocr.smartjavaai.enums.CommonDetModelEnum;
+import com.xindao.ocr.smartjavaai.model.common.detect.translator.PPOCRDetTranslator;
+import org.apache.commons.lang3.StringUtils;
+
+import java.nio.file.Paths;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author dwj
+ * @date 2025/7/8
+ */
+public class OcrCommonDetCriterialFactory {
+
+
+ public static Criteria<Image, NDList> createCriteria(OcrDetModelConfig config) {
+ Device device = null;
+ if(!Objects.isNull(config.getDevice())){
+ device = config.getDevice() == DeviceEnum.CPU ? Device.cpu() : Device.gpu(config.getGpuId());
+ }
+ Criteria<Image, NDList> criteria = null;
+ ConcurrentHashMap params = new ConcurrentHashMap<String, String>();
+ params.putAll(config.getCustomParams());
+ if(StringUtils.isNotBlank(config.getBatchifier())){
+ params.put("batchifier", config.getBatchifier());
+ }
+ if(config.getModelEnum() == CommonDetModelEnum.PP_OCR_V5_SERVER_DET_MODEL ||
+ config.getModelEnum() == CommonDetModelEnum.PP_OCR_V5_MOBILE_DET_MODEL ||
+ config.getModelEnum() == CommonDetModelEnum.PP_OCR_V4_SERVER_DET_MODEL ||
+ config.getModelEnum() == CommonDetModelEnum.PP_OCR_V4_MOBILE_DET_MODEL
+ ){
+ criteria =
+ Criteria.builder()
+ .optEngine("OnnxRuntime")
+ .setTypes(Image.class, NDList.class)
+ .optModelPath(Paths.get(config.getDetModelPath()))
+ .optTranslator(new PPOCRDetTranslator(params))
+ .optDevice(device)
+ .optProgress(new ProgressBar())
+ .build();
+ }
+ return criteria;
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/common/detect/translator/PPOCRDetTranslator.java b/src/main/java/com/xindao/ocr/smartjavaai/model/common/detect/translator/PPOCRDetTranslator.java
new file mode 100644
index 0000000..5e6d08e
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/common/detect/translator/PPOCRDetTranslator.java
@@ -0,0 +1,536 @@
+package com.xindao.ocr.smartjavaai.model.common.detect.translator;
+
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.util.NDImageUtils;
+import ai.djl.ndarray.NDArray;
+import ai.djl.ndarray.NDArrays;
+import ai.djl.ndarray.NDList;
+import ai.djl.ndarray.NDManager;
+import ai.djl.ndarray.index.NDIndex;
+import ai.djl.ndarray.types.DataType;
+import ai.djl.ndarray.types.Shape;
+import ai.djl.translate.Batchifier;
+import ai.djl.translate.Translator;
+import ai.djl.translate.TranslatorContext;
+import com.xindao.ocr.smartjavaai.opencv.OcrNDArrayUtils;
+import org.opencv.core.*;
+import org.opencv.imgproc.Imgproc;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 鏂囧瓧妫�娴嬪墠鍚庡鐞�
+ *
+ * @author Calvin
+ * @mail 179209347@qq.com
+ * @website www.aias.top
+ */
+public class PPOCRDetTranslator implements Translator<Image, NDList> {
+ // det_algorithm == "DB"
+ private final float thresh = 0.3f;
+ private final boolean use_dilation = false;
+ private final String score_mode = "fast";
+ private final String box_type = "quad";
+
+ //妫�娴嬬殑鍥惧儚杈归暱闄愬埗
+ private final int limit_side_len;
+ //杈撳嚭鐨勬渶澶ф枃鏈鏁伴噺
+ private final int max_candidates;
+ //鏂囨湰妗嗘渶灏忓昂瀵搁槇鍊�
+ private final int min_size;
+ //鏂囨湰妗嗙殑鍒嗘暟闃堝��
+ private final float box_thresh;
+
+ /**
+ * 杩欎釜鍙傛暟鏄娴嬪悗澶勭悊鏃舵帶鍒舵枃鏈澶у皬鐨勶紝榛樿1.6锛屽彲浠ュ皾璇曟敼鎴�2.5鎴栬�呮洿澶э紝鍙嶄箣锛屽鏋滆寰楁枃鏈涓嶅绱у噾锛屼篃鍙互鎶婅鍙傛暟璋冨皬銆�
+ * 妫�娴嬫澶у皬杩囦簬绱ц创鏂囧瓧鎴栨娴嬫杩囧ぇ锛屽彲浠ヨ皟鏁磀b_unclip_ratio杩欎釜鍙傛暟锛屽姞澶у弬鏁板彲浠ユ墿澶ф娴嬫锛屽噺灏忓弬鏁板彲浠ュ噺灏忔娴嬫澶у皬锛�
+ */
+ private final float unclip_ratio;
+ private float ratio_h;
+ private float ratio_w;
+ private int img_height;
+ private int img_width;
+
+ private String batchifier;
+
+ public PPOCRDetTranslator(Map<String, ?> arguments) {
+ limit_side_len =
+ arguments.containsKey("limit_side_len")
+ ? Integer.parseInt(arguments.get("limit_side_len").toString())
+ : 960;
+ max_candidates =
+ arguments.containsKey("max_candidates")
+ ? Integer.parseInt(arguments.get("max_candidates").toString())
+ : 1000;
+ min_size =
+ arguments.containsKey("min_size")
+ ? Integer.parseInt(arguments.get("min_size").toString())
+ : 3;
+ box_thresh =
+ arguments.containsKey("box_thresh")
+ ? Float.parseFloat(arguments.get("box_thresh").toString())
+ : 0.6f; // 0.5f
+ unclip_ratio =
+ arguments.containsKey("unclip_ratio")
+ ? Float.parseFloat(arguments.get("unclip_ratio").toString())
+ : 1.6f;
+
+ batchifier = arguments.containsKey("batchifier")
+ ? arguments.get("batchifier").toString()
+ : "stack";
+ }
+
+ @Override
+ public NDList processOutput(TranslatorContext ctx, NDList list) {
+ NDManager manager = ctx.getNDManager();
+ NDArray pred = list.get(0);
+ pred = pred.squeeze();
+ NDArray segmentation = pred.gt(thresh); // thresh=0.3 .mul(255f)
+
+ segmentation = segmentation.toType(DataType.UINT8, true);
+ Shape shape = segmentation.getShape();
+ int rows = (int) shape.get(0);
+ int cols = (int) shape.get(1);
+
+ Mat newMask = new Mat();
+ if (this.use_dilation) {
+ Mat mask = new Mat();
+ //convert from NDArray to Mat
+ Mat srcMat = OcrNDArrayUtils.uint8NDArrayToMat(segmentation);
+ // size 瓒婂皬锛岃厫铓�鐨勫崟浣嶈秺灏忥紝鍥剧墖瓒婃帴杩戝師鍥�
+ // Mat dilation_kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(2, 2));
+ Mat dilation_kernel = OcrNDArrayUtils.uint8ArrayToMat(new byte[][]{{1, 1}, {1, 1}});
+ /**
+ * 鑶ㄨ儉璇存槑锛� 鍥惧儚鐨勪竴閮ㄥ垎鍖哄煙涓庢寚瀹氱殑鏍歌繘琛屽嵎绉紝 姹傛牳鐨勬渶`澶鍊煎苟璧嬪�肩粰鎸囧畾鍖哄煙銆� 鑶ㄨ儉鍙互鐞嗚В涓哄浘鍍忎腑`楂樹寒鍖哄煙`鐨�'棰嗗煙鎵╁ぇ'銆�
+ * 鎰忔�濇槸楂樹寒閮ㄥ垎浼氫镜铓�涓嶆槸楂樹寒鐨勯儴鍒嗭紝浣块珮浜儴鍒嗚秺鏉ヨ秺澶氥��
+ */
+ Imgproc.dilate(srcMat, mask, dilation_kernel);
+ //destination Matrix
+ Scalar scalar = new Scalar(255);
+ Core.multiply(mask, scalar, newMask);
+ // release Mat
+ mask.release();
+ srcMat.release();
+ dilation_kernel.release();
+ } else {
+ Mat srcMat = OcrNDArrayUtils.uint8NDArrayToMat(segmentation);
+ //destination Matrix
+ Scalar scalar = new Scalar(255);
+ Core.multiply(srcMat, scalar, newMask);
+ // release Mat
+ srcMat.release();
+ }
+
+ NDArray boxes = boxes_from_bitmap(manager, pred, newMask);
+
+ //boxes[:, :, 0] = boxes[:, :, 0] / ratio_w
+ NDArray boxes1 = boxes.get(":, :, 0").div(ratio_w);
+ boxes.set(new NDIndex(":, :, 0"), boxes1);
+ //boxes[:, :, 1] = boxes[:, :, 1] / ratio_h
+ NDArray boxes2 = boxes.get(":, :, 1").div(ratio_h);
+ boxes.set(new NDIndex(":, :, 1"), boxes2);
+
+ NDList dt_boxes = this.filter_tag_det_res(boxes);
+
+ dt_boxes.detach();
+
+ // release Mat
+ newMask.release();
+
+ return dt_boxes;
+ }
+
+
+ private NDList filter_tag_det_res(NDArray dt_boxes) {
+ NDList boxesList = new NDList();
+
+ int num = (int) dt_boxes.getShape().get(0);
+ for (int i = 0; i < num; i++) {
+ NDArray box = dt_boxes.get(i);
+ box = order_points_clockwise(box);
+ box = clip_det_res(box);
+ float[] box0 = box.get(0).toFloatArray();
+ float[] box1 = box.get(1).toFloatArray();
+ float[] box3 = box.get(3).toFloatArray();
+ int rect_width = (int) Math.sqrt(Math.pow(box1[0] - box0[0], 2) + Math.pow(box1[1] - box0[1], 2));
+ int rect_height = (int) Math.sqrt(Math.pow(box3[0] - box0[0], 2) + Math.pow(box3[1] - box0[1], 2));
+ if (rect_width <= 3 || rect_height <= 3)
+ continue;
+ boxesList.add(box);
+ }
+
+ return boxesList;
+ }
+
+ private NDArray clip_det_res(NDArray points) {
+ for (int i = 0; i < points.getShape().get(0); i++) {
+ int value = Math.max((int) points.get(i, 0).toFloatArray()[0], 0);
+ value = Math.min(value, img_width - 1);
+ points.set(new NDIndex(i + ",0"), value);
+ value = Math.max((int) points.get(i, 1).toFloatArray()[0], 0);
+ value = Math.min(value, img_height - 1);
+ points.set(new NDIndex(i + ",1"), value);
+ }
+
+ return points;
+ }
+
+ /**
+ * sort the points based on their x-coordinates
+ * 椤烘椂閽�
+ *
+ * @param pts
+ * @return
+ */
+
+ private NDArray order_points_clockwise(NDArray pts) {
+ NDList list = new NDList();
+ long[] indexes = pts.get(":, 0").argSort().toLongArray();
+
+ // grab the left-most and right-most points from the sorted
+ // x-roodinate points
+ Shape s1 = pts.getShape();
+ NDArray leftMost1 = pts.get(indexes[0] + ",:");
+ NDArray leftMost2 = pts.get(indexes[1] + ",:");
+ NDArray leftMost = leftMost1.concat(leftMost2).reshape(2, 2);
+ NDArray rightMost1 = pts.get(indexes[2] + ",:");
+ NDArray rightMost2 = pts.get(indexes[3] + ",:");
+ NDArray rightMost = rightMost1.concat(rightMost2).reshape(2, 2);
+
+ // now, sort the left-most coordinates according to their
+ // y-coordinates so we can grab the top-left and bottom-left
+ // points, respectively
+ indexes = leftMost.get(":, 1").argSort().toLongArray();
+ NDArray lt = leftMost.get(indexes[0] + ",:");
+ NDArray lb = leftMost.get(indexes[1] + ",:");
+ indexes = rightMost.get(":, 1").argSort().toLongArray();
+ NDArray rt = rightMost.get(indexes[0] + ",:");
+ NDArray rb = rightMost.get(indexes[1] + ",:");
+
+ list.add(lt);
+ list.add(rt);
+ list.add(rb);
+ list.add(lb);
+
+ NDArray rect = NDArrays.concat(list).reshape(4, 2);
+ return rect;
+ }
+
+ /**
+ * Get boxes from the binarized image predicted by DB
+ *
+ * @param manager
+ * @param pred the binarized image predicted by DB.
+ * @param bitmap new 'pred' after threshold filtering.
+ */
+ private NDArray boxes_from_bitmap(NDManager manager, NDArray pred, Mat bitmap) {
+ int dest_height = (int) pred.getShape().get(0);
+ int dest_width = (int) pred.getShape().get(1);
+ int height = bitmap.rows();
+ int width = bitmap.cols();
+
+ List<MatOfPoint> contours = new ArrayList<>();
+ Mat hierarchy = new Mat();
+ // 瀵绘壘杞粨
+ Imgproc.findContours(
+ bitmap,
+ contours,
+ hierarchy,
+ Imgproc.RETR_LIST,
+ Imgproc.CHAIN_APPROX_SIMPLE);
+
+ int num_contours = Math.min(contours.size(), max_candidates);
+ NDList boxList = new NDList();
+ float[] scores = new float[num_contours];
+
+ for (int index = 0; index < num_contours; index++) {
+ MatOfPoint contour = contours.get(index);
+ MatOfPoint2f newContour = new MatOfPoint2f(contour.toArray());
+ float[][] pointsArr = new float[4][2];
+ int sside = get_mini_boxes(newContour, pointsArr);
+ if (sside < this.min_size)
+ continue;
+ NDArray points = manager.create(pointsArr);
+ float score = box_score_fast(manager, pred, points);
+ if (score < this.box_thresh)
+ continue;
+
+ NDArray box = unclip(manager, points); // TODO get_mini_boxes(box)
+
+ // box[:, 0] = np.clip(np.round(box[:, 0] / width * dest_width), 0, dest_width)
+ NDArray boxes1 = box.get(":,0").div(width).mul(dest_width).round().clip(0, dest_width);
+ box.set(new NDIndex(":, 0"), boxes1);
+ // box[:, 1] = np.clip(np.round(box[:, 1] / height * dest_height), 0, dest_height)
+ NDArray boxes2 = box.get(":,1").div(height).mul(dest_height).round().clip(0, dest_height);
+ box.set(new NDIndex(":, 1"), boxes2);
+
+ boxList.add(box);
+ scores[index] = score;
+
+ // release memory
+ contour.release();
+ newContour.release();
+ }
+
+ NDArray boxes = NDArrays.stack(boxList);
+
+ // release
+ hierarchy.release();
+
+ return boxes;
+ }
+
+ /**
+ * Shrink or expand the boxaccording to 'unclip_ratio'
+ *
+ * @param points The predicted box.
+ * @return uncliped box
+ */
+ private NDArray unclip(NDManager manager, NDArray points) {
+ points = order_points_clockwise(points);
+ float[] pointsArr = points.toFloatArray();
+ float[] lt = java.util.Arrays.copyOfRange(pointsArr, 0, 2);
+ float[] lb = java.util.Arrays.copyOfRange(pointsArr, 6, 8);
+
+ float[] rt = java.util.Arrays.copyOfRange(pointsArr, 2, 4);
+ float[] rb = java.util.Arrays.copyOfRange(pointsArr, 4, 6);
+
+ float width = distance(lt, rt);
+ float height = distance(lt, lb);
+
+ if (width > height) {
+ float k = (lt[1] - rt[1]) / (lt[0] - rt[0]); // y = k * x + b
+
+ float delta_dis = height;
+ float delta_x = (float) Math.sqrt((delta_dis * delta_dis) / (k * k + 1));
+ float delta_y = Math.abs(k * delta_x);
+
+ if (k > 0) {
+ pointsArr[0] = lt[0] - delta_x + delta_y;
+ pointsArr[1] = lt[1] - delta_y - delta_x;
+ pointsArr[2] = rt[0] + delta_x + delta_y;
+ pointsArr[3] = rt[1] + delta_y - delta_x;
+
+ pointsArr[4] = rb[0] + delta_x - delta_y;
+ pointsArr[5] = rb[1] + delta_y + delta_x;
+ pointsArr[6] = lb[0] - delta_x - delta_y;
+ pointsArr[7] = lb[1] - delta_y + delta_x;
+ } else {
+ pointsArr[0] = lt[0] - delta_x - delta_y;
+ pointsArr[1] = lt[1] + delta_y - delta_x;
+ pointsArr[2] = rt[0] + delta_x - delta_y;
+ pointsArr[3] = rt[1] - delta_y - delta_x;
+
+ pointsArr[4] = rb[0] + delta_x + delta_y;
+ pointsArr[5] = rb[1] - delta_y + delta_x;
+ pointsArr[6] = lb[0] - delta_x + delta_y;
+ pointsArr[7] = lb[1] + delta_y + delta_x;
+ }
+ } else {
+ float k = (lt[1] - rt[1]) / (lt[0] - rt[0]); // y = k * x + b
+
+ float delta_dis = width;
+ float delta_y = (float) Math.sqrt((delta_dis * delta_dis) / (k * k + 1));
+ float delta_x = Math.abs(k * delta_y);
+
+ if (k > 0) {
+ pointsArr[0] = lt[0] + delta_x - delta_y;
+ pointsArr[1] = lt[1] - delta_y - delta_x;
+ pointsArr[2] = rt[0] + delta_x + delta_y;
+ pointsArr[3] = rt[1] - delta_y + delta_x;
+
+ pointsArr[4] = rb[0] - delta_x + delta_y;
+ pointsArr[5] = rb[1] + delta_y + delta_x;
+ pointsArr[6] = lb[0] - delta_x - delta_y;
+ pointsArr[7] = lb[1] + delta_y - delta_x;
+ } else {
+ pointsArr[0] = lt[0] - delta_x - delta_y;
+ pointsArr[1] = lt[1] - delta_y + delta_x;
+ pointsArr[2] = rt[0] - delta_x + delta_y;
+ pointsArr[3] = rt[1] - delta_y - delta_x;
+
+ pointsArr[4] = rb[0] + delta_x + delta_y;
+ pointsArr[5] = rb[1] + delta_y - delta_x;
+ pointsArr[6] = lb[0] + delta_x - delta_y;
+ pointsArr[7] = lb[1] + delta_y + delta_x;
+ }
+ }
+ points = manager.create(pointsArr).reshape(4, 2);
+
+ return points;
+ }
+
+ private float distance(float[] point1, float[] point2) {
+ float disX = point1[0] - point2[0];
+ float disY = point1[1] - point2[1];
+ float dis = (float) Math.sqrt(disX * disX + disY * disY);
+ return dis;
+ }
+
+ /**
+ * Get boxes from the contour or box.
+ *
+ * @param contour The predicted contour.
+ * @param pointsArr The predicted box.
+ * @return smaller side of box
+ */
+ private int get_mini_boxes(MatOfPoint2f contour, float[][] pointsArr) {
+ // https://blog.csdn.net/qq_37385726/article/details/82313558
+ // bounding_box[1] - rect 杩斿洖鐭╁舰鐨勯暱鍜屽
+ RotatedRect rect = Imgproc.minAreaRect(contour);
+ Mat points = new Mat();
+ Imgproc.boxPoints(rect, points);
+
+ float[][] fourPoints = new float[4][2];
+ for (int row = 0; row < 4; row++) {
+ fourPoints[row][0] = (float) points.get(row, 0)[0];
+ fourPoints[row][1] = (float) points.get(row, 1)[0];
+ }
+
+ float[] tmpPoint = new float[2];
+ for (int i = 0; i < 4; i++) {
+ for (int j = i + 1; j < 4; j++) {
+ if (fourPoints[j][0] < fourPoints[i][0]) {
+ tmpPoint[0] = fourPoints[i][0];
+ tmpPoint[1] = fourPoints[i][1];
+ fourPoints[i][0] = fourPoints[j][0];
+ fourPoints[i][1] = fourPoints[j][1];
+ fourPoints[j][0] = tmpPoint[0];
+ fourPoints[j][1] = tmpPoint[1];
+ }
+ }
+ }
+
+ int index_1 = 0;
+ int index_2 = 1;
+ int index_3 = 2;
+ int index_4 = 3;
+
+ if (fourPoints[1][1] > fourPoints[0][1]) {
+ index_1 = 0;
+ index_4 = 1;
+ } else {
+ index_1 = 1;
+ index_4 = 0;
+ }
+
+ if (fourPoints[3][1] > fourPoints[2][1]) {
+ index_2 = 2;
+ index_3 = 3;
+ } else {
+ index_2 = 3;
+ index_3 = 2;
+ }
+
+ pointsArr[0] = fourPoints[index_1];
+ pointsArr[1] = fourPoints[index_2];
+ pointsArr[2] = fourPoints[index_3];
+ pointsArr[3] = fourPoints[index_4];
+
+ int height = rect.boundingRect().height;
+ int width = rect.boundingRect().width;
+ int sside = Math.min(height, width);
+
+ // release
+ points.release();
+
+ return sside;
+ }
+
+ /**
+ * Calculate the score of box.
+ *
+ * @param bitmap The binarized image predicted by DB.
+ * @param points The predicted box
+ * @return
+ */
+ private float box_score_fast(NDManager manager, NDArray bitmap, NDArray points) {
+ NDArray box = points.get(":");
+ long h = bitmap.getShape().get(0);
+ long w = bitmap.getShape().get(1);
+ // xmin = np.clip(np.floor(box[:, 0].min()).astype(np.int), 0, w - 1)
+ int xmin = box.get(":, 0").min().floor().clip(0, w - 1).toType(DataType.INT32, true).toIntArray()[0];
+ int xmax = box.get(":, 0").max().ceil().clip(0, w - 1).toType(DataType.INT32, true).toIntArray()[0];
+ int ymin = box.get(":, 1").min().floor().clip(0, h - 1).toType(DataType.INT32, true).toIntArray()[0];
+ int ymax = box.get(":, 1").max().ceil().clip(0, h - 1).toType(DataType.INT32, true).toIntArray()[0];
+
+ NDArray mask = manager.zeros(new Shape(ymax - ymin + 1, xmax - xmin + 1), DataType.UINT8);
+
+ box.set(new NDIndex(":, 0"), box.get(":, 0").sub(xmin));
+ box.set(new NDIndex(":, 1"), box.get(":, 1").sub(ymin));
+
+ //mask - convert from NDArray to Mat
+ Mat maskMat = OcrNDArrayUtils.uint8NDArrayToMat(mask);
+
+ //mask - convert from NDArray to Mat - 4 rows, 2 cols
+ Mat boxMat = OcrNDArrayUtils.floatNDArrayToMat(box, CvType.CV_32S);
+
+// boxMat.reshape(1, new int[]{1, 4, 2});
+ List<MatOfPoint> pts = new ArrayList<>();
+ MatOfPoint matOfPoint = OcrNDArrayUtils.matToMatOfPoint(boxMat); // new MatOfPoint(boxMat);
+ pts.add(matOfPoint);
+ Imgproc.fillPoly(maskMat, pts, new Scalar(1));
+
+
+ NDArray subBitMap = bitmap.get(ymin + ":" + (ymax + 1) + "," + xmin + ":" + (xmax + 1));
+ Mat bitMapMat = OcrNDArrayUtils.floatNDArrayToMat(subBitMap);
+
+ Scalar score = Core.mean(bitMapMat, maskMat);
+ float scoreValue = (float) score.val[0];
+ // release
+ maskMat.release();
+ boxMat.release();
+ bitMapMat.release();
+
+ return scoreValue;
+ }
+
+ @Override
+ public NDList processInput(TranslatorContext ctx, Image input) {
+ NDArray img = input.toNDArray(ctx.getNDManager());
+ int h = input.getHeight();
+ int w = input.getWidth();
+ img_height = h;
+ img_width = w;
+
+ // limit the max side
+ float ratio = 1.0f;
+ if (Math.max(h, w) > limit_side_len) {
+ if (h > w) {
+ ratio = (float) limit_side_len / (float) h;
+ } else {
+ ratio = (float) limit_side_len / (float) w;
+ }
+ }
+
+ int resize_h = (int) (h * ratio);
+ int resize_w = (int) (w * ratio);
+
+ resize_h = Math.round((float) resize_h / 32f) * 32;
+ resize_w = Math.round((float) resize_w / 32f) * 32;
+
+ ratio_h = resize_h / (float) h;
+ ratio_w = resize_w / (float) w;
+
+ img = NDImageUtils.resize(img, resize_w, resize_h);
+
+ img = NDImageUtils.toTensor(img);
+
+ img =
+ NDImageUtils.normalize(
+ img,
+ new float[]{0.485f, 0.456f, 0.406f},
+ new float[]{0.229f, 0.224f, 0.225f});
+
+// img = img.expandDims(0);
+
+ return new NDList(img);
+ }
+
+ @Override
+ public Batchifier getBatchifier() {
+ return Batchifier.fromString(batchifier);
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/common/direction/OcrDirectionModel.java b/src/main/java/com/xindao/ocr/smartjavaai/model/common/direction/OcrDirectionModel.java
new file mode 100644
index 0000000..34d95b8
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/common/direction/OcrDirectionModel.java
@@ -0,0 +1,112 @@
+package com.xindao.ocr.smartjavaai.model.common.direction;
+
+import ai.djl.inference.Predictor;
+import ai.djl.modality.cv.Image;
+import com.xindao.ocr.smartjavaai.config.DirectionModelConfig;
+import com.xindao.ocr.smartjavaai.entity.DirectionInfo;
+import com.xindao.ocr.smartjavaai.entity.OcrBox;
+import com.xindao.ocr.smartjavaai.entity.OcrItem;
+import com.xindao.ocr.smartjavaai.model.common.detect.OcrCommonDetModel;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+import org.opencv.core.Mat;
+
+import java.awt.image.BufferedImage;
+import java.util.List;
+
+/**
+ * OCR 鏂囨湰鏂瑰悜鍒嗙被妯″瀷
+ * @author dwj
+ */
+public interface OcrDirectionModel extends AutoCloseable{
+
+ default void setTextDetModel(OcrCommonDetModel detModel){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ default OcrCommonDetModel getTextDetModel(){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 鍔犺浇妯″瀷
+ * @param config
+ */
+ void loadModel(DirectionModelConfig config); // 鍔犺浇妯″瀷
+
+ /**
+ * 鏂囨湰鏂瑰悜妫�娴�
+ * @param imagePath 鍥剧墖璺緞
+ * @return
+ */
+ default List<OcrItem> detect(String imagePath) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 鏂囨湰鏂瑰悜妫�娴�
+ * @param image BufferedImage
+ * @return
+ */
+ default List<OcrItem> detect(BufferedImage image) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 鏂囨湰鏂瑰悜妫�娴�
+ * @param imageData 鍥剧墖瀛楄妭鏁扮粍
+ * @return
+ */
+ default List<OcrItem> detect(byte[] imageData) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 鏂囨湰鏂瑰悜妫�娴�
+ * @param image
+ * @return
+ */
+ default List<OcrItem> detect(Image image) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 鏂囨湰鏂瑰悜妫�娴嬶紙鍩轰簬妫�娴嬬粨鏋滐級
+ * @param boxList
+ * @param srcMat
+ * @param manager
+ * @return
+ */
+ default List<OcrItem> detect(List<OcrBox> boxList, Mat srcMat) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ default List<List<OcrItem>> batchDetect(List<List<OcrBox>> boxList, List<Mat> srcMatList) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 妫�娴嬪苟缁樺埗缁撴灉
+ * @param imagePath 鍥剧墖杈撳叆璺緞锛堝寘鍚枃浠跺悕绉帮級
+ * @param outputPath 鍥剧墖杈撳嚭璺緞锛堝寘鍚枃浠跺悕绉帮級
+ */
+ default void detectAndDraw(String imagePath, String outputPath) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 妫�娴嬪苟缁樺埗缁撴灉
+ * @param sourceImage
+ * @return
+ */
+ default BufferedImage detectAndDraw(BufferedImage sourceImage){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ default GenericObjectPool<Predictor<Image, DirectionInfo>> getPool() {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/common/direction/PPOCRMobileV2ClsModel.java b/src/main/java/com/xindao/ocr/smartjavaai/model/common/direction/PPOCRMobileV2ClsModel.java
new file mode 100644
index 0000000..7852a7d
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/common/direction/PPOCRMobileV2ClsModel.java
@@ -0,0 +1,393 @@
+package com.xindao.ocr.smartjavaai.model.common.direction;
+
+import ai.djl.MalformedModelException;
+import ai.djl.engine.Engine;
+import ai.djl.inference.Predictor;
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.ImageFactory;
+import ai.djl.ndarray.NDManager;
+import ai.djl.repository.zoo.Criteria;
+import ai.djl.repository.zoo.ModelNotFoundException;
+import ai.djl.repository.zoo.ModelZoo;
+import ai.djl.repository.zoo.ZooModel;
+import cn.smartjavaai.common.pool.PredictorFactory;
+import cn.smartjavaai.common.utils.FileUtils;
+import cn.smartjavaai.common.utils.ImageUtils;
+import cn.smartjavaai.common.utils.OpenCVUtils;
+import com.xindao.ocr.smartjavaai.config.DirectionModelConfig;
+import com.xindao.ocr.smartjavaai.entity.DirectionInfo;
+import com.xindao.ocr.smartjavaai.entity.OcrBox;
+import com.xindao.ocr.smartjavaai.entity.OcrItem;
+import com.xindao.ocr.smartjavaai.enums.AngleEnum;
+import com.xindao.ocr.smartjavaai.exception.OcrException;
+import com.xindao.ocr.smartjavaai.model.common.detect.OcrCommonDetModel;
+import com.xindao.ocr.smartjavaai.model.common.direction.criteria.DirectionCriteriaFactory;
+import com.xindao.ocr.smartjavaai.utils.OcrUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+import org.opencv.core.Mat;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * PPOCRMobileV2Model 鏂瑰悜鍒嗙被妯″瀷
+ * @author dwj
+ * @date 2025/4/21
+ */
+@Slf4j
+public class PPOCRMobileV2ClsModel implements OcrDirectionModel {
+
+
+ private GenericObjectPool<Predictor<Image, DirectionInfo>> predictorPool;
+
+ private DirectionModelConfig config;
+
+ private ZooModel<Image, DirectionInfo> model;
+
+ private OcrCommonDetModel textDetModel;
+
+
+ @Override
+ public void loadModel(DirectionModelConfig config){
+ if(StringUtils.isBlank(config.getModelPath())){
+ throw new OcrException("modelPath is null");
+ }
+ this.config = config;
+ this.textDetModel = config.getTextDetModel();
+ ConcurrentHashMap params = new ConcurrentHashMap<String, String>();
+ if(StringUtils.isNotBlank(config.getBatchifier())){
+ params.put("batchifier", config.getBatchifier());
+ }
+ Criteria<Image, DirectionInfo> criteria = DirectionCriteriaFactory.createCriteria(config);
+ try{
+ model = ModelZoo.loadModel(criteria);
+ // 鍒涘缓姹犲瓙锛氭瘡涓嚎绋嬬嫭浜� Predictor
+ this.predictorPool = new GenericObjectPool<>(new PredictorFactory<>(model));
+ int predictorPoolSize = config.getPredictorPoolSize();
+ if(config.getPredictorPoolSize() <= 0){
+ predictorPoolSize = Runtime.getRuntime().availableProcessors(); // 榛樿绛変簬CPU鏍稿績鏁�
+ }
+ predictorPool.setMaxTotal(predictorPoolSize);
+ log.debug("褰撳墠璁惧: " + model.getNDManager().getDevice());
+ log.debug("褰撳墠寮曟搸: " + Engine.getInstance().getEngineName());
+ log.debug("妯″瀷鎺ㄧ悊鍣ㄧ嚎绋嬫睜鏈�澶ф暟閲�: " + predictorPoolSize);
+ } catch (IOException | ModelNotFoundException | MalformedModelException e) {
+ throw new OcrException("妯″瀷鍔犺浇澶辫触", e);
+ }
+ }
+
+ @Override
+ public List<OcrItem> detect(String imagePath){
+ if(!FileUtils.isFileExists(imagePath)){
+ throw new OcrException("鍥惧儚鏂囦欢涓嶅瓨鍦�");
+ }
+ Image img = null;
+ try {
+ img = ImageFactory.getInstance().fromFile(Paths.get(imagePath));
+ return detect(img);
+ } catch (IOException e) {
+ throw new OcrException("鏃犳晥鐨勫浘鐗�", e);
+ }finally {
+ if(img != null){
+ ((Mat)img.getWrappedImage()).release();
+ }
+ }
+ }
+
+
+ @Override
+ public List<OcrItem> detect(Image image){
+ if(Objects.isNull(textDetModel)){
+ throw new OcrException("textDetModel is null");
+ }
+ //妫�娴嬫枃鏈�
+ List<OcrBox> boxeList = textDetModel.detect(image);
+ if(Objects.isNull(boxeList) || boxeList.isEmpty()){
+ throw new OcrException("鏈娴嬪埌鏂囨湰");
+ }
+ Mat srcMat = (Mat) image.getWrappedImage();
+ return detect(boxeList, srcMat);
+ }
+
+
+// /**
+// * 鍩轰簬鏂囨湰妗嗘娴嬫柟鍚�
+// * @param box
+// * @param srcMat
+// * @param predictor
+// * @param manager
+// * @return
+// */
+// private OcrItem detect(OcrBox box, Mat srcMat, Predictor<Image, DirectionInfo> predictor, NDManager manager){
+// if(Objects.isNull(box)){
+// throw new OcrException("box鍙傛暟涓虹┖");
+// }
+// try {
+// //閫忚鍙樻崲鍙婅鍓�
+// Image subImg = OcrUtils.transformAndCrop(srcMat, box);
+// DirectionInfo directionInfo = null;
+// String angle;
+// //楂樺姣� > 1.5 绾靛悜
+// if (subImg.getHeight() * 1.0 / subImg.getWidth() > 1.5) {
+// //鏃嬭浆鍥剧墖90搴�
+// subImg = OcrUtils.rotateImg(manager, subImg);
+// //妫�娴嬫柟鍚�
+// directionInfo = predictor.predict(subImg);
+// if (directionInfo.getName().equalsIgnoreCase("Rotate")) {
+// angle = "270";
+// } else {
+// angle = "90";
+// }
+// }else{ //妯悜
+// directionInfo = predictor.predict(subImg);
+// if (directionInfo.getName().equalsIgnoreCase("No Rotate")) {
+// angle = "0";
+// } else {
+// angle = "180";
+// }
+// }
+// ((Mat)subImg.getWrappedImage()).release();
+// return new OcrItem(box, AngleEnum.fromValue(angle), directionInfo.getProb().floatValue());
+// } catch (Exception e) {
+// throw new OcrException("OCR妫�娴嬮敊璇�", e);
+// }
+// }
+
+ @Override
+ public List<OcrItem> detect(List<OcrBox> boxList,Mat srcMat){
+ if(Objects.isNull(boxList) || boxList.isEmpty()){
+ throw new OcrException("boxList涓虹┖");
+ }
+ List<List<OcrItem>> ocrItemList = batchDetect(Collections.singletonList(boxList), Collections.singletonList(srcMat));
+ if(Objects.isNull(ocrItemList) || ocrItemList.isEmpty()){
+ throw new OcrException("鏂瑰悜妫�娴嬪け璐�");
+ }
+ return ocrItemList.get(0);
+ }
+
+ @Override
+ public void detectAndDraw(String imagePath, String outputPath) {
+ if(!FileUtils.isFileExists(imagePath)){
+ throw new OcrException("鍥惧儚鏂囦欢涓嶅瓨鍦�");
+ }
+ Image img = null;
+ try {
+ img = ImageFactory.getInstance().fromFile(Paths.get(imagePath));
+ List<OcrItem> itemList = detect(img);
+ if(Objects.isNull(itemList) || itemList.isEmpty()){
+ throw new OcrException("鏈娴嬪埌鏂囧瓧");
+ }
+ OcrUtils.drawRectWithText((Mat) img.getWrappedImage(), itemList);
+ Path output = Paths.get(outputPath);
+ log.debug("Saving to {}", output.toAbsolutePath().toString());
+ img.save(Files.newOutputStream(output), "png");
+ } catch (IOException e) {
+ throw new OcrException(e);
+ } finally {
+ if (img != null){
+ ((Mat)img.getWrappedImage()).release();
+ }
+ }
+ }
+
+ @Override
+ public List<OcrItem> detect(BufferedImage image) {
+ if(!ImageUtils.isImageValid(image)){
+ throw new OcrException("鍥惧儚鏃犳晥");
+ }
+ Image img = ImageFactory.getInstance().fromImage(OpenCVUtils.image2Mat(image));
+ List<OcrItem> ocrItemList = detect(img);
+ ((Mat)img.getWrappedImage()).release();
+ return ocrItemList;
+ }
+
+ @Override
+ public List<OcrItem> detect(byte[] imageData) {
+ if(Objects.isNull(imageData)){
+ throw new OcrException("鍥惧儚鏃犳晥");
+ }
+ try {
+ BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageData));
+ return detect(image);
+ } catch (IOException e) {
+ throw new OcrException("閿欒鐨勫浘鍍�", e);
+ }
+ }
+
+ @Override
+ public BufferedImage detectAndDraw(BufferedImage sourceImage) {
+ if(!ImageUtils.isImageValid(sourceImage)){
+ throw new OcrException("鍥惧儚鏃犳晥");
+ }
+ Image img = ImageFactory.getInstance().fromImage(OpenCVUtils.image2Mat(sourceImage));
+ List<OcrItem> ocrItemList = detect(img);
+ if(Objects.isNull(ocrItemList) || ocrItemList.isEmpty()){
+ throw new OcrException("鏈娴嬪埌鏂囧瓧");
+ }
+ OcrUtils.drawRectWithText((Mat) img.getWrappedImage(), ocrItemList);
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ // 璋冪敤 save 鏂规硶灏� Image 鍐欏叆瀛楄妭娴�
+ img.save(outputStream, "png");
+ // 灏嗗瓧鑺傛祦杞崲涓� BufferedImage
+ byte[] imageBytes = outputStream.toByteArray();
+ return ImageIO.read(new ByteArrayInputStream(imageBytes));
+ } catch (IOException e) {
+ throw new OcrException("瀵煎嚭鍥剧墖澶辫触", e);
+ } finally {
+ if (img != null){
+ ((Mat) img.getWrappedImage()).release();
+ }
+ }
+ }
+
+ @Override
+ public List<List<OcrItem>> batchDetect(List<List<OcrBox>> boxList, List<Mat> srcMatList) {
+ if(CollectionUtils.isEmpty(boxList)){
+ throw new OcrException("boxList 涓嶈兘涓虹┖");
+ }
+ if(CollectionUtils.isEmpty(srcMatList)){
+ throw new OcrException("srcMatList 涓嶈兘涓虹┖");
+ }
+ //妫�鏌ュ弬鏁�
+ for (int i = 0; i < srcMatList.size(); i++) {
+ List<OcrBox> ocrBoxes = boxList.get(i);
+ Mat mat = srcMatList.get(i);
+ if (ocrBoxes == null) {
+ throw new OcrException("绗� " + i + " 涓� boxList 涓� null");
+ }
+ if (ocrBoxes.isEmpty()) {
+ throw new OcrException("绗� " + i + " 涓� boxList 娌℃湁妫�娴嬬粨鏋�");
+ }
+ if (mat.empty()) {
+ throw new OcrException("绗� " + i + " 寮犲浘鐗囦负绌� Mat");
+ }
+ }
+ List<Image> imageList = new ArrayList<Image>();
+ List<Boolean> isRotatedList = new ArrayList<Boolean>();
+ int index = 0;
+ try (NDManager manager = model.getNDManager().newSubManager()){
+ for(int i = 0; i < srcMatList.size(); i++){
+ for (int j = 0; j < boxList.get(i).size(); j++){
+ //閫忚鍙樻崲鍙婅鍓�
+ Image subImg = OcrUtils.transformAndCrop(srcMatList.get(i), boxList.get(i).get(j));
+ //楂樺姣� > 1.5 绾靛悜
+ if (subImg.getHeight() * 1.0 / subImg.getWidth() > 1.5) {
+ //鏃嬭浆鍥剧墖90搴�
+ subImg = OcrUtils.rotateImg(manager, subImg);
+ isRotatedList.add(true);
+ imageList.add(subImg);
+ }else{
+ isRotatedList.add(false);
+ imageList.add(subImg);
+ }
+ index++;
+ }
+ }
+ List<List<OcrItem>> result = new ArrayList<>();
+ List<DirectionInfo> directionInfos = batchDetect(imageList);
+ if(CollectionUtils.isEmpty(directionInfos)){
+ throw new OcrException("鏂瑰悜妫�娴嬪け璐�");
+ }
+ index = 0;
+ for(int i = 0; i < srcMatList.size(); i++){
+ List<OcrItem> ocrItemList = new ArrayList<>();
+ for (int j = 0; j < boxList.get(i).size(); j++){
+ DirectionInfo directionInfo = directionInfos.get(index);
+ if(Objects.isNull(directionInfo)){
+ throw new OcrException("鏂瑰悜妫�娴嬪け璐�: 绗�" + i + "寮犲浘鐗�, 绗�" + j + "涓枃鏈潡锛屾湭妫�娴嬪埌鏂瑰悜");
+ }
+ String angle;
+ if(isRotatedList.get(index)){
+ if (directionInfo.getName().equalsIgnoreCase("Rotate")) {
+ angle = "270";
+ } else {
+ angle = "90";
+ }
+ }else{
+ if (directionInfo.getName().equalsIgnoreCase("No Rotate")) {
+ angle = "0";
+ } else {
+ angle = "180";
+ }
+ }
+ OcrItem ocrItem = new OcrItem(boxList.get(i).get(j), AngleEnum.fromValue(angle), directionInfo.getProb().floatValue());
+ ocrItemList.add(ocrItem);
+ index++;
+ }
+ result.add(ocrItemList);
+ }
+ return result;
+ }
+ }
+
+ private List<DirectionInfo> batchDetect(List<Image> imageList) {
+ Predictor<Image, DirectionInfo> predictor = null;
+ try {
+ predictor = predictorPool.borrowObject();
+ return predictor.batchPredict(imageList);
+ } catch (Exception e) {
+ throw new OcrException("OCR妫�娴嬮敊璇�", e);
+ }finally {
+ if (predictor != null) {
+ try {
+ predictorPool.returnObject(predictor); //褰掕繕
+ } catch (Exception e) {
+ log.warn("褰掕繕Predictor澶辫触", e);
+ try {
+ predictor.close(); // 褰掕繕澶辫触鎵嶉攢姣�
+ } catch (Exception ex) {
+ log.error("鍏抽棴Predictor澶辫触", ex);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void setTextDetModel(OcrCommonDetModel detModel) {
+ this.textDetModel = detModel;
+ }
+
+ @Override
+ public OcrCommonDetModel getTextDetModel() {
+ return textDetModel;
+ }
+
+ @Override
+ public GenericObjectPool<Predictor<Image, DirectionInfo>> getPool() {
+ return predictorPool;
+ }
+
+ @Override
+ public void close() throws Exception {
+ try {
+ if (predictorPool != null) {
+ predictorPool.close();
+ }
+ } catch (Exception e) {
+ log.warn("鍏抽棴 predictorPool 澶辫触", e);
+ }
+ try {
+ if (model != null) {
+ model.close();
+ }
+ } catch (Exception e) {
+ log.warn("鍏抽棴 model 澶辫触", e);
+ }
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/common/direction/criteria/DirectionCriteriaFactory.java b/src/main/java/com/xindao/ocr/smartjavaai/model/common/direction/criteria/DirectionCriteriaFactory.java
new file mode 100644
index 0000000..e22d5ab
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/common/direction/criteria/DirectionCriteriaFactory.java
@@ -0,0 +1,57 @@
+package com.xindao.ocr.smartjavaai.model.common.direction.criteria;
+
+import ai.djl.Device;
+import ai.djl.modality.cv.Image;
+import ai.djl.repository.zoo.Criteria;
+import ai.djl.training.util.ProgressBar;
+import cn.smartjavaai.common.enums.DeviceEnum;
+import com.xindao.ocr.smartjavaai.config.DirectionModelConfig;
+import com.xindao.ocr.smartjavaai.entity.DirectionInfo;
+import com.xindao.ocr.smartjavaai.enums.DirectionModelEnum;
+import com.xindao.ocr.smartjavaai.model.common.direction.translator.PpWordRotateTranslator;
+import org.apache.commons.lang3.StringUtils;
+
+import java.nio.file.Paths;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 琛屾柟鍚戝垎绫�
+ * @author dwj
+ */
+public class DirectionCriteriaFactory {
+
+ public static Criteria<Image, DirectionInfo> createCriteria(DirectionModelConfig config) {
+ Device device = null;
+ if(!Objects.isNull(config.getDevice())){
+ device = config.getDevice() == DeviceEnum.CPU ? Device.cpu() : Device.gpu(config.getGpuId());
+ }
+ Criteria<Image, DirectionInfo> criteria = null;
+ ConcurrentHashMap params = new ConcurrentHashMap<String, String>();
+ params.putAll(config.getCustomParams());
+ if(StringUtils.isNotBlank(config.getBatchifier())){
+ params.put("batchifier", config.getBatchifier());
+ }
+ if(config.getModelEnum() == DirectionModelEnum.CH_PPOCR_MOBILE_V2_CLS){
+ params.put("resizeWidth", 192);
+ params.put("resizeHeight", 48);
+ }else if (config.getModelEnum() == DirectionModelEnum.PP_LCNET_X0_25){
+ params.put("resizeWidth", 160);
+ params.put("resizeHeight", 80);
+ }else if (config.getModelEnum() == DirectionModelEnum.PP_LCNET_X1_0){
+ params.put("resizeWidth", 160);
+ params.put("resizeHeight", 80);
+ }
+ criteria =
+ Criteria.builder()
+ .optEngine("OnnxRuntime")
+ .setTypes(Image.class, DirectionInfo.class)
+ .optModelPath(Paths.get(config.getModelPath()))
+ .optDevice(device)
+ .optTranslator(new PpWordRotateTranslator(params))
+ .optProgress(new ProgressBar())
+ .build();
+ return criteria;
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/common/direction/translator/PpWordRotateTranslator.java b/src/main/java/com/xindao/ocr/smartjavaai/model/common/direction/translator/PpWordRotateTranslator.java
new file mode 100644
index 0000000..cd48156
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/common/direction/translator/PpWordRotateTranslator.java
@@ -0,0 +1,105 @@
+package com.xindao.ocr.smartjavaai.model.common.direction.translator;
+
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.util.NDImageUtils;
+import ai.djl.ndarray.NDArray;
+import ai.djl.ndarray.NDList;
+import ai.djl.ndarray.index.NDIndex;
+import ai.djl.ndarray.types.Shape;
+import ai.djl.translate.Batchifier;
+import ai.djl.translate.Translator;
+import ai.djl.translate.TranslatorContext;
+import com.xindao.ocr.smartjavaai.entity.DirectionInfo;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 鏂瑰悜妫�娴�
+ *
+ * @author Calvin
+ * @mail 179209347@qq.com
+ * @website www.aias.top
+ */
+public class PpWordRotateTranslator implements Translator<Image, DirectionInfo> {
+ List<String> classes = Arrays.asList("No Rotate", "Rotate");
+
+ private String batchifier;
+
+ private int resizeHeight;
+
+ private int resizeWidth;
+
+ public PpWordRotateTranslator(Map<String, ?> arguments) {
+ batchifier = arguments.containsKey("batchifier")
+ ? arguments.get("batchifier").toString()
+ : "padding";
+
+ resizeWidth = arguments.containsKey("resizeWidth")
+ ? (Integer) arguments.get("resizeWidth")
+ : 192;
+
+ resizeHeight = arguments.containsKey("resizeHeight")
+ ? (Integer) arguments.get("resizeHeight")
+ : 48;
+ }
+
+ @Override
+ public DirectionInfo processOutput(TranslatorContext ctx, NDList list) {
+ NDArray prob = list.singletonOrThrow();
+ float[] res = prob.toFloatArray();
+ int maxIndex = 0;
+ if (res[1] > res[0]) {
+ maxIndex = 1;
+ }
+
+ return new DirectionInfo(classes.get(maxIndex), Double.valueOf(res[maxIndex]));
+ }
+
+// public NDList processInput2(TranslatorContext ctx, Image input){
+// NDArray img = input.toNDArray(ctx.getNDManager());
+// img = NDImageUtils.resize(img, 192, 48);
+// img = NDImageUtils.toTensor(img).sub(0.5F).div(0.5F);
+// img = img.expandDims(0);
+// return new NDList(new NDArray[]{img});
+// }
+
+ @Override
+ public NDList processInput(TranslatorContext ctx, Image input) {
+ NDArray img = input.toNDArray(ctx.getNDManager());
+ int imgC = 3;
+ int imgH = resizeHeight;
+ int imgW = resizeWidth;
+
+ NDArray array = ctx.getNDManager().zeros(new Shape(imgC, imgH, imgW));
+
+ int h = input.getHeight();
+ int w = input.getWidth();
+ int resized_w = 0;
+
+ float ratio = (float) w / (float) h;
+ if (Math.ceil(imgH * ratio) > imgW) {
+ resized_w = imgW;
+ } else {
+ resized_w = (int) (Math.ceil(imgH * ratio));
+ }
+
+ img = NDImageUtils.resize(img, resized_w, imgH);
+
+ img = NDImageUtils.toTensor(img).sub(0.5F).div(0.5F);
+ // img = img.transpose(2, 0, 1);
+
+ array.set(new NDIndex(":,:,0:" + resized_w), img);
+
+// array = array.expandDims(0);
+
+ return new NDList(new NDArray[]{array});
+ }
+
+ @Override
+ public Batchifier getBatchifier() {
+ return Batchifier.fromString(batchifier);
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/common/recognize/OcrCommonRecModel.java b/src/main/java/com/xindao/ocr/smartjavaai/model/common/recognize/OcrCommonRecModel.java
new file mode 100644
index 0000000..bde760f
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/common/recognize/OcrCommonRecModel.java
@@ -0,0 +1,129 @@
+package com.xindao.ocr.smartjavaai.model.common.recognize;
+
+import ai.djl.inference.Predictor;
+import ai.djl.modality.cv.Image;
+import com.xindao.ocr.smartjavaai.config.OcrRecModelConfig;
+import com.xindao.ocr.smartjavaai.config.OcrRecOptions;
+import com.xindao.ocr.smartjavaai.entity.OcrInfo;
+import com.xindao.ocr.smartjavaai.model.common.detect.OcrCommonDetModel;
+import com.xindao.ocr.smartjavaai.model.common.direction.OcrDirectionModel;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+
+import java.awt.image.BufferedImage;
+import java.util.List;
+
+/**
+ * OCR 閫氱敤璇嗗埆妯″瀷
+ * @author dwj
+ */
+public interface OcrCommonRecModel extends AutoCloseable{
+
+ default void setTextDetModel(OcrCommonDetModel detModel){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ default OcrCommonDetModel getTextDetModel(){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ default void setDirectionModel(OcrDirectionModel directionModel){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ default OcrDirectionModel getDirectionModel(){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 鍔犺浇妯″瀷
+ * @param config
+ */
+ void loadModel(OcrRecModelConfig config); // 鍔犺浇妯″瀷
+
+ /**
+ * 鏂囨湰璇嗗埆
+ * @param imagePath 鍥剧墖璺緞
+ * @return
+ */
+ default OcrInfo recognize(String imagePath, OcrRecOptions options) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 鏂囨湰璇嗗埆
+ * @param image
+ * @return
+ */
+ default OcrInfo recognize(Image image, OcrRecOptions options) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 鏂囨湰妫�娴�
+ * @param image BufferedImage
+ * @return
+ */
+ default OcrInfo recognize(BufferedImage image, OcrRecOptions options) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 鏂囨湰妫�娴�
+ * @param imageData 鍥剧墖瀛楄妭鏁扮粍
+ * @return
+ */
+ default OcrInfo recognize(byte[] imageData, OcrRecOptions options) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 璇嗗埆骞剁粯鍒剁粨鏋�
+ * @param imagePath
+ * @param outputPath
+ */
+ default void recognizeAndDraw(String imagePath, String outputPath, int fontSize, OcrRecOptions options) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 璇嗗埆骞剁粯鍒剁粨鏋�
+ * @param sourceImage
+ * @return
+ */
+ default BufferedImage recognizeAndDraw(BufferedImage sourceImage, int fontSize, OcrRecOptions options){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+ /**
+ * 璇嗗埆骞剁粯鍒禕ase64缁撴灉
+ * @param imageData 鍥剧墖瀛楄妭鏁扮粍
+ * @return
+ */
+ default String recognizeAndDrawToBase64(byte[] imageData, int fontSize, OcrRecOptions options){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 璇嗗埆骞剁粯鍒剁粨鏋�
+ * @param imageData 鍥剧墖瀛楄妭鏁扮粍
+ * @return
+ */
+ default OcrInfo recognizeAndDraw(byte[] imageData, int fontSize, OcrRecOptions options){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ default List<OcrInfo> batchRecognize(List<BufferedImage> imageList, OcrRecOptions options) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ default List<OcrInfo> batchRecognizeDJLImage(List<Image> imageList, OcrRecOptions options) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ default GenericObjectPool<Predictor<Image, String>> getPool() {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/common/recognize/OcrCommonRecModelImpl.java b/src/main/java/com/xindao/ocr/smartjavaai/model/common/recognize/OcrCommonRecModelImpl.java
new file mode 100644
index 0000000..728d85e
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/common/recognize/OcrCommonRecModelImpl.java
@@ -0,0 +1,502 @@
+package com.xindao.ocr.smartjavaai.model.common.recognize;
+
+import ai.djl.MalformedModelException;
+import ai.djl.engine.Engine;
+import ai.djl.inference.Predictor;
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.ImageFactory;
+import ai.djl.ndarray.NDArray;
+import ai.djl.ndarray.NDManager;
+import ai.djl.repository.zoo.Criteria;
+import ai.djl.repository.zoo.ModelNotFoundException;
+import ai.djl.repository.zoo.ModelZoo;
+import ai.djl.repository.zoo.ZooModel;
+import cn.hutool.core.img.ImgUtil;
+import cn.smartjavaai.common.pool.PredictorFactory;
+import cn.smartjavaai.common.utils.FileUtils;
+import cn.smartjavaai.common.utils.ImageUtils;
+import cn.smartjavaai.common.utils.OpenCVUtils;
+import com.xindao.ocr.smartjavaai.config.OcrRecModelConfig;
+import com.xindao.ocr.smartjavaai.config.OcrRecOptions;
+import com.xindao.ocr.smartjavaai.entity.*;
+import com.xindao.ocr.smartjavaai.exception.OcrException;
+import com.xindao.ocr.smartjavaai.model.common.detect.OcrCommonDetModel;
+import com.xindao.ocr.smartjavaai.model.common.direction.OcrDirectionModel;
+import com.xindao.ocr.smartjavaai.model.common.recognize.criteria.OcrCommonRecCriterialFactory;
+import com.xindao.ocr.smartjavaai.utils.OcrUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+import org.opencv.core.Mat;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * PPOCRV5 璇嗗埆妯″瀷
+ *
+ * @author dwj
+ */
+@Slf4j
+public class OcrCommonRecModelImpl implements OcrCommonRecModel {
+
+ private GenericObjectPool<Predictor<Image, String>> recPredictorPool;
+
+ private OcrRecModelConfig config;
+
+ private ZooModel<Image, String> recognitionModel;
+
+ private OcrDirectionModel directionModel;
+
+ private OcrCommonDetModel textDetModel;
+
+ @Override
+ public void loadModel(OcrRecModelConfig config) {
+ if (StringUtils.isBlank(config.getRecModelPath())) {
+ throw new OcrException("recModelPath is null");
+ }
+ this.config = config;
+ this.directionModel = config.getDirectionModel();
+ this.textDetModel = config.getTextDetModel();
+ //鍒濆鍖� 璇嗗埆Criteria
+ Criteria<Image, String> recCriteria = OcrCommonRecCriterialFactory.createCriteria(config);
+ try {
+ recognitionModel = ModelZoo.loadModel(recCriteria);
+ this.recPredictorPool = new GenericObjectPool<>(new PredictorFactory<>(recognitionModel));
+ int predictorPoolSize = config.getPredictorPoolSize();
+ if (config.getPredictorPoolSize() <= 0) {
+ predictorPoolSize = Runtime.getRuntime().availableProcessors(); // 榛樿绛変簬CPU鏍稿績鏁�
+ }
+ recPredictorPool.setMaxTotal(predictorPoolSize);
+ log.debug("褰撳墠璁惧: " + recognitionModel.getNDManager().getDevice());
+ log.debug("褰撳墠寮曟搸: " + Engine.getInstance().getEngineName());
+ log.debug("妯″瀷鎺ㄧ悊鍣ㄧ嚎绋嬫睜鏈�澶ф暟閲�: " + predictorPoolSize);
+ } catch (IOException | ModelNotFoundException | MalformedModelException e) {
+ throw new OcrException("璇嗗埆妯″瀷鍔犺浇澶辫触", e);
+ }
+
+ }
+
+
+ @Override
+ public OcrInfo recognize(String imagePath, OcrRecOptions options) {
+ if (StringUtils.isBlank(config.getRecModelPath())) {
+ throw new OcrException("recModelPath涓虹┖锛屾棤娉曡瘑鍒�");
+ }
+ if (!FileUtils.isFileExists(imagePath)) {
+ throw new OcrException("鍥惧儚鏂囦欢涓嶅瓨鍦�");
+ }
+ Image img = null;
+ try {
+ img = ImageFactory.getInstance().fromFile(Paths.get(imagePath));
+ return recognize(img, options);
+ } catch (IOException e) {
+ throw new OcrException("鏃犳晥鐨勫浘鐗�", e);
+ } finally {
+ if (img != null) {
+ ((Mat) img.getWrappedImage()).release();
+ }
+ }
+ }
+
+ /**
+ * @param image
+ * @param options
+ * @return
+ */
+ @Override
+ public OcrInfo recognize(Image image, OcrRecOptions options) {
+ List<OcrInfo> result = batchRecognizeDJLImage(Collections.singletonList(image), options);
+ if (CollectionUtils.isEmpty(result)) {
+ throw new OcrException("OCR璇嗗埆缁撴灉涓虹┖");
+ }
+ return result.get(0);
+ }
+
+
+ /**
+ * 鎵归噺鐭鏂囨湰妗�
+ *
+ * @param boxList
+ * @param srcMat
+ * @param manager
+ * @return
+ */
+ private List<Image> batchAlign(List<OcrBox> boxList, Mat srcMat, NDManager manager) {
+ List<Image> imageList = new ArrayList<>(boxList.size());
+ for (int i = 0; i < boxList.size(); i++) {
+ //閫忚鍙樻崲 + 瑁佸壀
+ Image subImg = OcrUtils.transformAndCrop(srcMat, boxList.get(i));
+ //ImageUtils.saveImage(subImg, i + "crop.png", "build/output");
+ //楂樺姣� > 1.5
+ if (subImg.getHeight() * 1.0 / subImg.getWidth() > 1.5) {
+ //鏃嬭浆鍥剧墖90搴�
+ subImg = OcrUtils.rotateImg(manager, subImg);
+ //ImageUtils.saveImage(subImg, i + "rotate.png", "build/output");
+ }
+ imageList.add(subImg);
+ }
+ return imageList;
+ }
+
+ /**
+ * 鎵归噺鐭鏂囨湰妗�
+ *
+ * @param itemList
+ * @param srcMat
+ * @param manager
+ * @return
+ */
+ private List<Image> batchAlignWithDirection(List<OcrItem> itemList, Mat srcMat, NDManager manager) {
+ List<Image> imageList = new ArrayList<>(itemList.size());
+ for (OcrItem ocrItem : itemList) {
+ //鏀惧皠鍙樻崲+瑁佸壀
+ Image subImage = OcrUtils.transformAndCrop(srcMat, ocrItem.getOcrBox());
+ //ImageUtils.saveImage(subImage, UUID.randomUUID().toString() + "_aaa.png", "build/output");
+ //绾犳鏂囨湰妗�
+ subImage = OcrUtils.rotateImg(subImage, ocrItem.getAngle());
+ imageList.add(subImage);
+ }
+ return imageList;
+ }
+
+
+// private RotatedBox recognize(OcrBox box,Mat srcMat,Predictor<Image, String> recPredictor,NDManager manager){
+// try {
+// //閫忚鍙樻崲 + 瑁佸壀
+// Image subImg = OcrUtils.transformAndCrop(srcMat, box);
+// //ImageUtils.saveImage(subImg, i + "crop.png", "build/output");
+// //楂樺姣� > 1.5
+// if (subImg.getHeight() * 1.0 / subImg.getWidth() > 1.5) {
+// //鏃嬭浆鍥剧墖90搴�
+// subImg = OcrUtils.rotateImg(manager, subImg);
+// //ImageUtils.saveImage(subImg, i + "rotate.png", "build/output");
+// }
+// String name = recPredictor.predict(subImg);
+// ((Mat)subImg.getWrappedImage()).release();
+// NDArray pointsArray = manager.create(box.toFloatArray());
+// return new RotatedBox(pointsArray, name);
+// } catch (Exception e) {
+// throw new OcrException("OCR妫�娴嬮敊璇�", e);
+// }
+// }
+
+
+ /**
+ * 鍚庡鐞嗭細鎺掑簭,鍒嗚
+ *
+ * @param rotatedBoxes
+ */
+ private OcrInfo postProcessOcrResult(List<RotatedBox> rotatedBoxes, OcrRecOptions ocrRecOptions) {
+ //涓嶅垎琛�
+ if (!ocrRecOptions.isEnableLineSplit()) {
+ return OcrUtils.convertRotatedBoxesToOcrItems(rotatedBoxes);
+ }
+ //Y鍧愭爣鍗囧簭鎺掑簭
+ List<RotatedBox> initList = new ArrayList<>();
+ for (RotatedBox result : rotatedBoxes) {
+ initList.add(result);
+ }
+ Collections.sort(initList);
+ //澶氳鏂囨湰妗嗙殑闆嗗悎
+ List<ArrayList<RotatedBoxCompX>> lines = new ArrayList<>();
+ List<RotatedBoxCompX> line = new ArrayList<>();
+ RotatedBoxCompX firstBox = new RotatedBoxCompX(initList.get(0).getBox(), initList.get(0).getText());
+ line.add(firstBox);
+ lines.add((ArrayList) line);
+ //鍒嗚鍒ゆ柇
+ for (int i = 1; i < initList.size(); i++) {
+ RotatedBoxCompX tmpBox = new RotatedBoxCompX(initList.get(i).getBox(), initList.get(i).getText());
+ float y1 = firstBox.getBox().toFloatArray()[1];
+ float y2 = tmpBox.getBox().toFloatArray()[1];
+ float dis = Math.abs(y2 - y1);
+ if (dis < 20) { // 璁や负鏄悓 1 琛� - Considered to be in the same line
+ line.add(tmpBox);
+ } else { // 鎹㈣ - Line break
+ firstBox = tmpBox;
+ Collections.sort(line);
+ line = new ArrayList<>();
+ line.add(firstBox);
+ lines.add((ArrayList) line);
+ }
+ }
+ return OcrUtils.convertToOcrInfo(lines);
+ }
+
+
+ @Override
+ public void recognizeAndDraw(String imagePath, String outputPath, int fontSize, OcrRecOptions options) {
+ if (!FileUtils.isFileExists(imagePath)) {
+ throw new OcrException("鍥惧儚鏂囦欢涓嶅瓨鍦�");
+ }
+ try {
+ Image img = ImageFactory.getInstance().fromFile(Paths.get(imagePath));
+ OcrInfo ocrInfo = recognize(img, options);
+ if (Objects.isNull(ocrInfo) || Objects.isNull(ocrInfo.getLineList()) || ocrInfo.getLineList().isEmpty()) {
+ throw new OcrException("鏈娴嬪埌鏂囧瓧");
+ }
+ Mat wrappedImage = (Mat) img.getWrappedImage();
+ BufferedImage bufferedImage = OpenCVUtils.mat2Image(wrappedImage);
+ OcrUtils.drawRectWithText(bufferedImage, ocrInfo, fontSize);
+ ImageUtils.saveImage(bufferedImage, outputPath);
+ wrappedImage.release();
+ } catch (IOException e) {
+ throw new OcrException(e);
+ }
+ }
+
+ @Override
+ public OcrInfo recognize(BufferedImage image, OcrRecOptions options) {
+ if (!ImageUtils.isImageValid(image)) {
+ throw new OcrException("鍥惧儚鏃犳晥");
+ }
+ Image img = ImageFactory.getInstance().fromImage(OpenCVUtils.image2Mat(image));
+ OcrInfo ocrInfo = recognize(img, options);
+ ((Mat) img.getWrappedImage()).release();
+ return ocrInfo;
+ }
+
+ @Override
+ public OcrInfo recognize(byte[] imageData, OcrRecOptions options) {
+ if (Objects.isNull(imageData)) {
+ throw new OcrException("鍥惧儚鏃犳晥");
+ }
+ try {
+ BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageData));
+ return recognize(image, options);
+ } catch (IOException e) {
+ throw new OcrException("閿欒鐨勫浘鍍�", e);
+ }
+ }
+
+ @Override
+ public BufferedImage recognizeAndDraw(BufferedImage sourceImage, int fontSize, OcrRecOptions options) {
+ if (!ImageUtils.isImageValid(sourceImage)) {
+ throw new OcrException("鍥惧儚鏃犳晥");
+ }
+ Image img = ImageFactory.getInstance().fromImage(OpenCVUtils.image2Mat(sourceImage));
+ OcrInfo ocrInfo = recognize(img, options);
+ if (Objects.isNull(ocrInfo) || Objects.isNull(ocrInfo.getLineList()) || ocrInfo.getLineList().isEmpty()) {
+ throw new OcrException("鏈娴嬪埌鏂囧瓧");
+ }
+ OcrUtils.drawRectWithText(sourceImage, ocrInfo, fontSize);
+ return sourceImage;
+ }
+
+ @Override
+ public String recognizeAndDrawToBase64(byte[] imageData, int fontSize, OcrRecOptions options) {
+ if (Objects.isNull(imageData)) {
+ throw new OcrException("鍥惧儚鏃犳晥");
+ }
+ OcrInfo ocrInfo = recognize(imageData, options);
+ if (Objects.isNull(ocrInfo) || Objects.isNull(ocrInfo.getLineList()) || ocrInfo.getLineList().isEmpty()) {
+ throw new OcrException("鏈娴嬪埌鏂囧瓧");
+ }
+ try {
+ BufferedImage sourceImage = ImageIO.read(new ByteArrayInputStream(imageData));
+ OcrUtils.drawRectWithText(sourceImage, ocrInfo, fontSize);
+ return ImgUtil.toBase64(sourceImage, "png");
+ } catch (IOException e) {
+ throw new OcrException("瀵煎嚭鍥剧墖澶辫触", e);
+ }
+ }
+
+ @Override
+ public OcrInfo recognizeAndDraw(byte[] imageData, int fontSize, OcrRecOptions options) {
+ if (Objects.isNull(imageData)) {
+ throw new OcrException("鍥惧儚鏃犳晥");
+ }
+ OcrInfo ocrInfo = recognize(imageData, options);
+ if (Objects.isNull(ocrInfo) || Objects.isNull(ocrInfo.getLineList()) || ocrInfo.getLineList().isEmpty()) {
+ throw new OcrException("鏈娴嬪埌鏂囧瓧");
+ }
+ try {
+ BufferedImage sourceImage = ImageIO.read(new ByteArrayInputStream(imageData));
+ OcrUtils.drawRectWithText(sourceImage, ocrInfo, fontSize);
+ ocrInfo.setBase64Img(ImgUtil.toBase64(sourceImage, "png"));
+ return ocrInfo;
+ } catch (IOException e) {
+ throw new OcrException("瀵煎嚭鍥剧墖澶辫触", e);
+ }
+ }
+
+ @Override
+ public List<OcrInfo> batchRecognize(List<BufferedImage> imageList, OcrRecOptions options) {
+ List<Image> djlImageList = new ArrayList<>(imageList.size());
+ try {
+ for (BufferedImage bufferedImage : imageList) {
+ djlImageList.add(ImageFactory.getInstance().fromImage(OpenCVUtils.image2Mat(bufferedImage)));
+ }
+ return batchRecognizeDJLImage(djlImageList, options);
+ } catch (Exception e) {
+ throw new OcrException(e);
+ } finally {
+ djlImageList.forEach(image -> ((Mat) image.getWrappedImage()).release());
+ }
+ }
+
+ @Override
+ public List<OcrInfo> batchRecognizeDJLImage(List<Image> imageList, OcrRecOptions options) {
+ if (Objects.isNull(textDetModel)) {
+ throw new OcrException("textDetModel is null");
+ }
+ OcrRecOptions ocrRecOptions = options;
+ if (Objects.isNull(options)) {
+ ocrRecOptions = new OcrRecOptions();
+ }
+ if (CollectionUtils.isEmpty(imageList)) {
+ throw new OcrException("imageList is empty");
+ }
+ //妫�娴嬫枃鏈�
+ List<List<OcrBox>> boxeList = textDetModel.batchDetectDJLImage(imageList);
+ if (CollectionUtils.isEmpty(boxeList) || boxeList.size() != imageList.size()) {
+ throw new OcrException("鏈娴嬪埌鏂囨湰");
+ }
+ Predictor<Image, String> predictor = null;
+ List<OcrInfo> ocrInfoList = new ArrayList<OcrInfo>();
+ try (NDManager manager = NDManager.newBaseManager()) {
+ predictor = recPredictorPool.borrowObject();
+ List<Image> allImageAlignList = new ArrayList<Image>();
+ //妫�娴嬫柟鍚�
+ if (ocrRecOptions.isEnableDirectionCorrect()) {
+ if (Objects.isNull(directionModel)) {
+ throw new OcrException("璇烽厤缃柟鍚戞ā鍨�");
+ }
+ List<Mat> matList = imageList.stream()
+ .map(image -> (Mat) image.getWrappedImage())
+ .collect(Collectors.toList());
+ List<List<OcrItem>> ocrItemList = directionModel.batchDetect(boxeList, matList);
+ if (CollectionUtils.isEmpty(ocrItemList) || ocrItemList.size() != imageList.size()) {
+ throw new OcrException("鏂瑰悜妫�娴嬪け璐�");
+ }
+ allImageAlignList = new ArrayList<Image>();
+ for (int i = 0; i < ocrItemList.size(); i++) {
+ Mat srcMat = (Mat) imageList.get(i).getWrappedImage();
+ List<Image> imageAlignList = batchAlignWithDirection(ocrItemList.get(i), srcMat, manager);
+// for(int j = 0; j < imageAlignList.size(); j++){
+// ImageUtils.saveImage(imageAlignList.get(j),"dir-"+i+"-"+j+".png","/Users/xxx/Downloads/testing33");
+// }
+ allImageAlignList.addAll(imageAlignList);
+ }
+ } else {
+ for (int i = 0; i < boxeList.size(); i++) {
+ Mat srcMat = (Mat) imageList.get(i).getWrappedImage();
+ List<Image> imageAlignList = batchAlign(boxeList.get(i), srcMat, manager);
+// for(int j = 0; j < imageAlignList.size(); j++){
+// ImageUtils.saveImage(imageAlignList.get(j),i+"-"+j+".png","/Users/xxx/Downloads/testing33");
+// }
+ allImageAlignList.addAll(imageAlignList);
+ }
+ }
+ List<String> textList = batchRecognize(allImageAlignList);
+ int textIndex = 0;
+ for (int i = 0; i < boxeList.size(); i++) {
+ List<RotatedBox> rotatedBoxes = new ArrayList<>();
+ for (int j = 0; j < boxeList.get(i).size(); j++) {
+ if (textIndex >= textList.size()) {
+ throw new OcrException("璇嗗埆澶辫触: 绗�" + i + "寮犲浘鐗�, 绗�" + j + "涓枃鏈潡锛屾湭璇嗗埆鍒版枃鏈�");
+ }
+ OcrBox box = boxeList.get(i).get(j);
+ NDArray pointsArray = manager.create(box.toFloatArray());
+ rotatedBoxes.add(new RotatedBox(pointsArray, textList.get(textIndex)));
+ textIndex++;
+ }
+ OcrInfo ocrInfo = postProcessOcrResult(rotatedBoxes, ocrRecOptions);
+ ocrInfoList.add(ocrInfo);
+ }
+ return ocrInfoList;
+ } catch (Exception e) {
+ throw new OcrException("OCR妫�娴嬮敊璇�", e);
+ } finally {
+ if (predictor != null) {
+ try {
+ recPredictorPool.returnObject(predictor); //褰掕繕
+ } catch (Exception e) {
+ log.warn("褰掕繕Predictor澶辫触", e);
+ try {
+ predictor.close(); // 褰掕繕澶辫触鎵嶉攢姣�
+ } catch (Exception ex) {
+ log.error("鍏抽棴Predictor澶辫触", ex);
+ }
+ }
+ }
+ }
+ }
+
+ private List<String> batchRecognize(List<Image> imageAlignList) {
+ Predictor<Image, String> predictor = null;
+ try {
+ predictor = recPredictorPool.borrowObject();
+ List<String> textList = predictor.batchPredict(imageAlignList);
+ imageAlignList.forEach(subImg -> ((Mat) subImg.getWrappedImage()).release());
+ return textList;
+ } catch (Exception e) {
+ throw new OcrException("OCR妫�娴嬮敊璇�", e);
+ } finally {
+ if (predictor != null) {
+ try {
+ recPredictorPool.returnObject(predictor); //褰掕繕
+ } catch (Exception e) {
+ log.warn("褰掕繕Predictor澶辫触", e);
+ try {
+ predictor.close(); // 褰掕繕澶辫触鎵嶉攢姣�
+ } catch (Exception ex) {
+ log.error("鍏抽棴Predictor澶辫触", ex);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void setTextDetModel(OcrCommonDetModel detModel) {
+ this.textDetModel = detModel;
+ }
+
+ @Override
+ public OcrCommonDetModel getTextDetModel() {
+ return textDetModel;
+ }
+
+ @Override
+ public void setDirectionModel(OcrDirectionModel directionModel) {
+ this.directionModel = directionModel;
+ }
+
+ @Override
+ public OcrDirectionModel getDirectionModel() {
+ return directionModel;
+ }
+
+
+ public GenericObjectPool<Predictor<Image, String>> getRecPredictorPool() {
+ return recPredictorPool;
+ }
+
+ @Override
+ public void close() throws Exception {
+ try {
+ if (recPredictorPool != null) {
+ recPredictorPool.close();
+ }
+ } catch (Exception e) {
+ log.warn("鍏抽棴 predictorPool 澶辫触", e);
+ }
+ try {
+ if (recognitionModel != null) {
+ recognitionModel.close();
+ }
+ } catch (Exception e) {
+ log.warn("鍏抽棴 model 澶辫触", e);
+ }
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/common/recognize/criteria/OcrCommonRecCriterialFactory.java b/src/main/java/com/xindao/ocr/smartjavaai/model/common/recognize/criteria/OcrCommonRecCriterialFactory.java
new file mode 100644
index 0000000..30b349c
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/common/recognize/criteria/OcrCommonRecCriterialFactory.java
@@ -0,0 +1,51 @@
+package com.xindao.ocr.smartjavaai.model.common.recognize.criteria;
+
+import ai.djl.Device;
+import ai.djl.modality.cv.Image;
+import ai.djl.repository.zoo.Criteria;
+import ai.djl.training.util.ProgressBar;
+import cn.smartjavaai.common.enums.DeviceEnum;
+import com.xindao.ocr.smartjavaai.config.OcrRecModelConfig;
+import com.xindao.ocr.smartjavaai.enums.CommonRecModelEnum;
+import com.xindao.ocr.smartjavaai.model.common.recognize.translator.PPOCRRecTranslator;
+import org.apache.commons.lang3.StringUtils;
+
+import java.nio.file.Paths;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author dwj
+ * @date 2025/7/8
+ */
+public class OcrCommonRecCriterialFactory {
+
+
+ public static Criteria<Image, String> createCriteria(OcrRecModelConfig config) {
+ Device device = null;
+ if(!Objects.isNull(config.getDevice())){
+ device = config.getDevice() == DeviceEnum.CPU ? Device.cpu() : Device.gpu(config.getGpuId());
+ }
+ Criteria<Image, String> criteria = null;
+ ConcurrentHashMap params = new ConcurrentHashMap<String, String>();
+ params.putAll(config.getCustomParams());
+ if(StringUtils.isNotBlank(config.getBatchifier())){
+ params.put("batchifier", config.getBatchifier());
+ }
+ if(config.getRecModelEnum() == CommonRecModelEnum.PP_OCR_V5_SERVER_REC_MODEL ||
+ config.getRecModelEnum() == CommonRecModelEnum.PP_OCR_V5_MOBILE_REC_MODEL ||
+ config.getRecModelEnum() == CommonRecModelEnum.PP_OCR_V4_SERVER_REC_MODEL ||
+ config.getRecModelEnum() == CommonRecModelEnum.PP_OCR_V4_MOBILE_REC_MODEL ){
+ criteria =
+ Criteria.builder()
+ .optEngine("OnnxRuntime")
+ .setTypes(Image.class, String.class)
+ .optModelPath(Paths.get(config.getRecModelPath()))
+ .optTranslator(new PPOCRRecTranslator(params))
+ .optProgress(new ProgressBar())
+ .optDevice(device)
+ .build();
+ }
+ return criteria;
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/common/recognize/translator/PPOCRRecTranslator.java b/src/main/java/com/xindao/ocr/smartjavaai/model/common/recognize/translator/PPOCRRecTranslator.java
new file mode 100644
index 0000000..7987568
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/common/recognize/translator/PPOCRRecTranslator.java
@@ -0,0 +1,129 @@
+package com.xindao.ocr.smartjavaai.model.common.recognize.translator;
+
+import ai.djl.Model;
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.util.NDImageUtils;
+import ai.djl.ndarray.NDArray;
+import ai.djl.ndarray.NDList;
+import ai.djl.ndarray.index.NDIndex;
+import ai.djl.ndarray.types.DataType;
+import ai.djl.ndarray.types.Shape;
+import ai.djl.translate.Batchifier;
+import ai.djl.translate.Translator;
+import ai.djl.translate.TranslatorContext;
+import ai.djl.util.Utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 鏂囧瓧璇嗗埆鍓嶅悗澶勭悊
+ *
+ */
+public class PPOCRRecTranslator implements Translator<Image, String> {
+ private List<String> table;
+ private final boolean use_space_char;
+
+ private String batchifier;
+
+ public PPOCRRecTranslator(Map<String, ?> arguments) {
+ use_space_char =
+ arguments.containsKey("use_space_char")
+ ? Boolean.parseBoolean(arguments.get("use_space_char").toString())
+ : true;
+ batchifier = arguments.containsKey("batchifier")
+ ? arguments.get("batchifier").toString()
+ : "padding";
+ }
+
+ @Override
+ public void prepare(TranslatorContext ctx) throws IOException {
+ Model model = ctx.getModel();
+ try (InputStream is = model.getArtifact("dict.txt").openStream()) {
+ table = Utils.readLines(is, true);
+ table.add(0, "blank");
+ if(use_space_char){
+ table.add(" ");
+ table.add(" ");
+ }
+ else{
+ table.add("");
+ table.add("");
+ }
+
+ }
+ }
+
+ @Override
+ public String processOutput(TranslatorContext ctx, NDList list) throws IOException {
+ StringBuilder sb = new StringBuilder();
+ NDArray tokens = list.singletonOrThrow();
+
+// long[] indices = tokens.get(0).argMax(1).toLongArray();
+ long[] indices = tokens.argMax(1).toLongArray();
+ boolean[] selection = new boolean[indices.length];
+ Arrays.fill(selection, true);
+ for (int i = 1; i < indices.length; i++) {
+ if (indices[i] == indices[i - 1]) {
+ selection[i] = false;
+ }
+ }
+
+ // 瀛楃缃俊搴�
+// float[] probs = new float[indices.length];
+// for (int row = 0; row < indices.length; row++) {
+// NDArray value = tokens.get(0).get(new NDIndex(""+ row +":" + (row + 1) +"," + indices[row] +":" + ( indices[row] + 1)));
+// probs[row] = value.toFloatArray()[0];
+// }
+
+ int lastIdx = 0;
+ for (int i = 0; i < indices.length; i++) {
+ if (selection[i] == true && indices[i] > 0 && !(i > 0 && indices[i] == lastIdx)) {
+ sb.append(table.get((int) indices[i]));
+ }
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public NDList processInput(TranslatorContext ctx, Image input) {
+ NDArray img = input.toNDArray(ctx.getNDManager(), Image.Flag.COLOR);
+ int imgC = 3;
+ int imgH = 48;
+ int imgW = 320;
+
+ float max_wh_ratio = (float) imgW / (float) imgH;
+
+ int h = input.getHeight();
+ int w = input.getWidth();
+ float wh_ratio = (float) w / (float) h;
+
+ max_wh_ratio = Math.max(max_wh_ratio,wh_ratio);
+ imgW = (int)(imgH * max_wh_ratio);
+
+ int resized_w;
+ if (Math.ceil(imgH * wh_ratio) > imgW) {
+ resized_w = imgW;
+ } else {
+ resized_w = (int) (Math.ceil(imgH * wh_ratio));
+ }
+ NDArray resized_image = NDImageUtils.resize(img, resized_w, imgH);
+ resized_image = resized_image.transpose(2, 0, 1).toType(DataType.FLOAT32,false);
+ resized_image.divi(255f).subi(0.5f).divi(0.5f);
+ NDArray padding_im = ctx.getNDManager().zeros(new Shape(imgC, imgH, imgW), DataType.FLOAT32);
+ padding_im.set(new NDIndex(":,:,0:" + resized_w), resized_image);
+
+ padding_im = padding_im.flip(0);
+// padding_im = padding_im.expandDims(0);
+ return new NDList(padding_im);
+ }
+
+ @Override
+ public Batchifier getBatchifier() {
+ return Batchifier.fromString(batchifier);
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/plate/CRNNPlateRecModel.java b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/CRNNPlateRecModel.java
new file mode 100644
index 0000000..bec5e4c
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/CRNNPlateRecModel.java
@@ -0,0 +1,325 @@
+package com.xindao.ocr.smartjavaai.model.plate;
+
+import ai.djl.MalformedModelException;
+import ai.djl.engine.Engine;
+import ai.djl.inference.Predictor;
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.ImageFactory;
+import ai.djl.modality.cv.output.DetectedObjects;
+import ai.djl.repository.zoo.Criteria;
+import ai.djl.repository.zoo.ModelNotFoundException;
+import ai.djl.repository.zoo.ModelZoo;
+import ai.djl.repository.zoo.ZooModel;
+import cn.smartjavaai.common.entity.DetectionRectangle;
+import cn.smartjavaai.common.entity.R;
+import cn.smartjavaai.common.pool.PredictorFactory;
+import cn.smartjavaai.common.utils.Base64ImageUtils;
+import cn.smartjavaai.common.utils.FileUtils;
+import cn.smartjavaai.common.utils.ImageUtils;
+import cn.smartjavaai.common.utils.OpenCVUtils;
+import com.xindao.ocr.smartjavaai.config.PlateRecModelConfig;
+import com.xindao.ocr.smartjavaai.entity.PlateInfo;
+import com.xindao.ocr.smartjavaai.entity.PlateResult;
+import com.xindao.ocr.smartjavaai.enums.PlateType;
+import com.xindao.ocr.smartjavaai.exception.OcrException;
+import com.xindao.ocr.smartjavaai.model.plate.criteria.PlateRecCriterialFactory;
+import com.xindao.ocr.smartjavaai.utils.OcrUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+import org.opencv.core.Core;
+import org.opencv.core.Mat;
+import org.opencv.core.Rect;
+import org.opencv.core.Size;
+import org.opencv.imgproc.Imgproc;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author dwj
+ */
+@Slf4j
+public class CRNNPlateRecModel implements PlateRecModel{
+
+
+ private GenericObjectPool<Predictor<Image, PlateResult>> recPredictorPool;
+
+ private ZooModel<Image, PlateResult> recModel;
+
+ private PlateRecModelConfig config;
+
+ @Override
+ public void loadModel(PlateRecModelConfig config) {
+ if(StringUtils.isBlank(config.getModelPath())){
+ throw new OcrException("modelPath is null");
+ }
+ this.config = config;
+ //鍒濆鍖� 妫�娴婥riteria
+ Criteria<Image, PlateResult> detCriteria = PlateRecCriterialFactory.createCriteria(config);
+ try{
+ recModel = ModelZoo.loadModel(detCriteria);
+ // 鍒涘缓姹犲瓙锛氭瘡涓嚎绋嬬嫭浜� Predictor
+ this.recPredictorPool = new GenericObjectPool<>(new PredictorFactory<>(recModel));
+ int predictorPoolSize = config.getPredictorPoolSize();
+ if(config.getPredictorPoolSize() <= 0){
+ predictorPoolSize = Runtime.getRuntime().availableProcessors(); // 榛樿绛変簬CPU鏍稿績鏁�
+ }
+ recPredictorPool.setMaxTotal(predictorPoolSize);
+ log.debug("褰撳墠璁惧: " + recModel.getNDManager().getDevice());
+ log.debug("褰撳墠寮曟搸: " + Engine.getInstance().getEngineName());
+ log.debug("妯″瀷鎺ㄧ悊鍣ㄧ嚎绋嬫睜鏈�澶ф暟閲�: " + predictorPoolSize);
+ } catch (IOException | ModelNotFoundException | MalformedModelException e) {
+ throw new OcrException("妫�娴嬫ā鍨嬪姞杞藉け璐�", e);
+ }
+ }
+
+ @Override
+ public R<List<PlateInfo>> recognize(String imagePath) {
+ if(!FileUtils.isFileExists(imagePath)){
+ return R.fail(R.Status.FILE_NOT_FOUND);
+ }
+ Image img = null;
+ try {
+ img = ImageFactory.getInstance().fromFile(Paths.get(imagePath));
+ R<List<PlateInfo>> plateResult = recognize(img);
+ return plateResult;
+ } catch (IOException e) {
+ throw new OcrException("鏃犳晥鐨勫浘鐗�", e);
+ } finally {
+ ((Mat)img.getWrappedImage()).release();
+ }
+ }
+
+ @Override
+ public R<List<PlateInfo>> recognizeBase64(String base64Image) {
+ if(StringUtils.isBlank(base64Image)){
+ return R.fail(R.Status.INVALID_IMAGE);
+ }
+ byte[] imageData = Base64ImageUtils.base64ToImage(base64Image);
+ return recognize(imageData);
+ }
+
+ @Override
+ public R<List<PlateInfo>> recognize(BufferedImage image) {
+ if(!ImageUtils.isImageValid(image)){
+ return R.fail(R.Status.INVALID_IMAGE);
+ }
+ Image img = ImageFactory.getInstance().fromImage(OpenCVUtils.image2Mat(image));
+ R<List<PlateInfo>> plateResult = recognize(img);
+ ((Mat)img.getWrappedImage()).release();
+ return plateResult;
+ }
+
+ @Override
+ public R<List<PlateInfo>> recognize(byte[] imageData) {
+ if(Objects.isNull(imageData)){
+ return R.fail(R.Status.INVALID_IMAGE);
+ }
+ return recognize(new ByteArrayInputStream(imageData));
+ }
+
+ @Override
+ public R<List<PlateInfo>> recognize(Image image) {
+ if(Objects.isNull(config.getPlateDetModel())){
+ return R.fail(R.Status.PARAM_ERROR.getCode(), "鏈寚瀹氳溅鐗屾娴嬫ā鍨�");
+ }
+ DetectedObjects detectedObjects = config.getPlateDetModel().detect(image);
+ if(Objects.isNull(detectedObjects) || detectedObjects.getNumberOfObjects() == 0){
+ return R.fail(R.Status.NO_OBJECT_DETECTED);
+ }
+ List<PlateInfo> plateInfoList = OcrUtils.convertToPlateInfo(detectedObjects, image);
+ Predictor<Image, PlateResult> predictor = null;
+ try {
+ predictor = recPredictorPool.borrowObject();
+ for (PlateInfo plateInfo : plateInfoList){
+ DetectionRectangle detectionRectangle = plateInfo.getDetectionRectangle();
+// Image subImage = image.getSubImage(detectionRectangle.getX(), detectionRectangle.getY(), detectionRectangle.getWidth(), detectionRectangle.getHeight());
+ //閫忚鍙樻崲
+ Image subImage = OcrUtils.transformAndCrop((Mat)image.getWrappedImage(), plateInfo.getBox());
+ //鍙屽眰杞︾墝
+ if(plateInfo.getPlateType() == PlateType.DOUBLE){
+ Mat mergeImage = getSplitMerge((Mat)subImage.getWrappedImage());
+ subImage = ImageFactory.getInstance().fromImage(mergeImage);
+ }
+ PlateResult plateResult = predictor.predict(subImage);
+ if(Objects.nonNull(plateResult)){
+ plateInfo.setPlateNumber(plateResult.getPlateNo());
+ plateInfo.setPlateColor(plateResult.getPlateColor());
+ }
+ }
+ return R.ok(plateInfoList);
+ } catch (Exception e) {
+ throw new OcrException("杞︾墝璇嗗埆閿欒", e);
+ }finally {
+ if (predictor != null) {
+ try {
+ recPredictorPool.returnObject(predictor); //褰掕繕
+ } catch (Exception e) {
+ log.warn("褰掕繕Predictor澶辫触", e);
+ try {
+ predictor.close(); // 褰掕繕澶辫触鎵嶉攢姣�
+ } catch (Exception ex) {
+ log.error("鍏抽棴Predictor澶辫触", ex);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 鍙屽眰杞︾墝杩涜鍒嗗壊鍚庤瘑鍒�
+ * @param img
+ * @return
+ */
+ private Mat getSplitMerge(Mat img) {
+ int h = img.rows();
+ int w = img.cols();
+
+ // 涓婂崐閮ㄥ垎锛氶珮搴︾殑鍓� 5/12
+ Rect upperRect = new Rect(0, 0, w, (int)(5.0 / 12 * h));
+ Mat imgUpper = new Mat(img, upperRect);
+
+ // 涓嬪崐閮ㄥ垎锛氶珮搴︿粠 1/3 寮�濮�
+ Rect lowerRect = new Rect(0, (int)(1.0 / 3 * h), w, h - (int)(1.0 / 3 * h));
+ Mat imgLower = new Mat(img, lowerRect);
+
+ // 灏嗕笂鍗婇儴鍒� resize 鍒颁笌涓嬪崐閮ㄥ垎鐩稿悓澶у皬
+ Mat resizedUpper = new Mat();
+ Size lowerSize = imgLower.size();
+ Imgproc.resize(imgUpper, resizedUpper, lowerSize);
+
+ // 姘村钩鎷兼帴锛堝皢涓婁笅鎷兼垚宸﹀彸锛�
+ List<Mat> mergeList = new ArrayList<>();
+ mergeList.add(resizedUpper);
+ mergeList.add(imgLower);
+
+ Mat merged = new Mat();
+ Core.hconcat(mergeList, merged);
+ return merged;
+ }
+
+ @Override
+ public PlateResult recognizeCropped(Image image) {
+ Predictor<Image, PlateResult> predictor = null;
+ try {
+ predictor = recPredictorPool.borrowObject();
+ return predictor.predict(image);
+ } catch (Exception e) {
+ throw new OcrException("杞︾墝妫�娴嬮敊璇�", e);
+ }finally {
+ if (predictor != null) {
+ try {
+ recPredictorPool.returnObject(predictor); //褰掕繕
+ } catch (Exception e) {
+ log.warn("褰掕繕Predictor澶辫触", e);
+ try {
+ predictor.close(); // 褰掕繕澶辫触鎵嶉攢姣�
+ } catch (Exception ex) {
+ log.error("鍏抽棴Predictor澶辫触", ex);
+ }
+ }
+ }
+
+ }
+ }
+
+ @Override
+ public R<List<PlateInfo>> recognize(InputStream inputStream) {
+ if(Objects.isNull(inputStream)){
+ return R.fail(R.Status.INVALID_IMAGE);
+ }
+ Image img = null;
+ try {
+ img = ImageFactory.getInstance().fromInputStream(inputStream);
+ return recognize(img);
+ } catch (IOException e) {
+ throw new OcrException("鏃犳晥鍥剧墖杈撳叆娴�", e);
+ } finally {
+ if (img != null){
+ ((Mat)img.getWrappedImage()).release();
+ }
+ }
+ }
+
+ @Override
+ public R<Void> recognizeAndDraw(String imagePath, String outputPath) {
+ if(!FileUtils.isFileExists(imagePath)){
+ return R.fail(R.Status.FILE_NOT_FOUND);
+ }
+ Image img = null;
+ try {
+ img = ImageFactory.getInstance().fromFile(Paths.get(imagePath));
+ R<List<PlateInfo>> plateResult = recognize(img);
+ if(!plateResult.isSuccess()){
+ return R.fail(plateResult.getCode(), plateResult.getMessage());
+ }
+ if(CollectionUtils.isEmpty(plateResult.getData())){
+ return R.fail(R.Status.NO_OBJECT_DETECTED);
+ }
+ BufferedImage bufferedImage = OpenCVUtils.mat2Image((Mat)img.getWrappedImage());
+ OcrUtils.drawPlateInfo(bufferedImage, plateResult.getData());
+ ImageIO.write(bufferedImage, "png", new File(outputPath));
+ return R.ok();
+ } catch (IOException e) {
+ throw new OcrException(e);
+ } finally {
+ if (img != null){
+ ((Mat)img.getWrappedImage()).release();
+ }
+ }
+ }
+
+ @Override
+ public R<BufferedImage> recognizeAndDraw(BufferedImage sourceImage) {
+ if(!ImageUtils.isImageValid(sourceImage)){
+ return R.fail(R.Status.INVALID_IMAGE);
+ }
+ try {
+ R<List<PlateInfo>> plateResult = recognize(sourceImage);
+ if(!plateResult.isSuccess()){
+ return R.fail(plateResult.getCode(), plateResult.getMessage());
+ }
+ if(CollectionUtils.isEmpty(plateResult.getData())){
+ return R.fail(R.Status.NO_OBJECT_DETECTED);
+ }
+ OcrUtils.drawPlateInfo(sourceImage, plateResult.getData());
+ return R.ok(sourceImage);
+ } catch (Exception e) {
+ throw new OcrException("瀵煎嚭鍥剧墖澶辫触", e);
+ }
+ }
+
+
+ @Override
+ public GenericObjectPool<Predictor<Image, PlateResult>> getPool() {
+ return recPredictorPool;
+ }
+
+ @Override
+ public void close() throws Exception {
+ try {
+ if (recPredictorPool != null) {
+ recPredictorPool.close();
+ }
+ } catch (Exception e) {
+ log.warn("鍏抽棴 predictorPool 澶辫触", e);
+ }
+ try {
+ if (recModel != null) {
+ recModel.close();
+ }
+ } catch (Exception e) {
+ log.warn("鍏抽棴 model 澶辫触", e);
+ }
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/plate/PlateDetModel.java b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/PlateDetModel.java
new file mode 100644
index 0000000..872836a
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/PlateDetModel.java
@@ -0,0 +1,112 @@
+package com.xindao.ocr.smartjavaai.model.plate;
+
+import ai.djl.inference.Predictor;
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.output.DetectedObjects;
+import cn.smartjavaai.common.entity.R;
+import com.xindao.ocr.smartjavaai.config.PlateDetModelConfig;
+import com.xindao.ocr.smartjavaai.entity.PlateInfo;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+
+import java.awt.image.BufferedImage;
+import java.io.InputStream;
+import java.util.List;
+
+/**
+ * 杞︾墝妫�娴嬫ā鍨�
+ * @author dwj
+ */
+public interface PlateDetModel extends AutoCloseable{
+
+ /**
+ * 鍔犺浇妯″瀷
+ * @param config
+ */
+ void loadModel(PlateDetModelConfig config); // 鍔犺浇妯″瀷
+
+ /**
+ * 杞︾墝妫�娴�
+ * @param imagePath 鍥剧墖璺緞
+ * @return
+ */
+ default R<List<PlateInfo>> detect(String imagePath) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 杞︾墝妫�娴�
+ * @param inputStream
+ * @return
+ */
+ default R<List<PlateInfo>> detect(InputStream inputStream) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 杞︾墝妫�娴�
+ * @param base64Image
+ * @return
+ */
+ default R<List<PlateInfo>> detectBase64(String base64Image){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 杞︾墝妫�娴�
+ * @param image BufferedImage
+ * @return
+ */
+ default R<List<PlateInfo>> detect(BufferedImage image) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 杞︾墝妫�娴�
+ * @param imageData 鍥剧墖瀛楄妭鏁扮粍
+ * @return
+ */
+ default R<List<PlateInfo>> detect(byte[] imageData) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 杞︾墝妫�娴�
+ * @param image DJL Image
+ * @return
+ */
+ default DetectedObjects detect(Image image){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 妫�娴嬪苟缁樺埗缁撴灉
+ * @param imagePath 鍥剧墖杈撳叆璺緞锛堝寘鍚枃浠跺悕绉帮級
+ * @param outputPath 鍥剧墖杈撳嚭璺緞锛堝寘鍚枃浠跺悕绉帮級
+ */
+ default R<Void> detectAndDraw(String imagePath, String outputPath) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 妫�娴嬪苟缁樺埗缁撴灉
+ * @param sourceImage
+ * @return
+ */
+ default R<BufferedImage> detectAndDraw(BufferedImage sourceImage){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ default GenericObjectPool<Predictor<Image, DetectedObjects>> getPool(){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/plate/PlateRecModel.java b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/PlateRecModel.java
new file mode 100644
index 0000000..0660cf9
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/PlateRecModel.java
@@ -0,0 +1,116 @@
+package com.xindao.ocr.smartjavaai.model.plate;
+
+import ai.djl.inference.Predictor;
+import ai.djl.modality.cv.Image;
+import cn.smartjavaai.common.entity.R;
+import com.xindao.ocr.smartjavaai.config.PlateRecModelConfig;
+import com.xindao.ocr.smartjavaai.entity.PlateInfo;
+import com.xindao.ocr.smartjavaai.entity.PlateResult;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+
+import java.awt.image.BufferedImage;
+import java.io.InputStream;
+import java.util.List;
+
+/**
+ * 杞︾墝璇嗗埆妯″瀷
+ * @author dwj
+ */
+public interface PlateRecModel extends AutoCloseable{
+
+ /**
+ * 鍔犺浇妯″瀷
+ * @param config
+ */
+ void loadModel(PlateRecModelConfig config); // 鍔犺浇妯″瀷
+
+ /**
+ * 杞︾墝璇嗗埆
+ * @param imagePath 鍥剧墖璺緞
+ * @return
+ */
+ default R<List<PlateInfo>> recognize(String imagePath) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 杞︾墝璇嗗埆
+ * @param inputStream
+ * @return
+ */
+ default R<List<PlateInfo>> recognize(InputStream inputStream) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 杞︾墝璇嗗埆
+ * @param base64Image
+ * @return
+ */
+ default R<List<PlateInfo>> recognizeBase64(String base64Image){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 杞︾墝璇嗗埆
+ * @param image BufferedImage
+ * @return
+ */
+ default R<List<PlateInfo>> recognize(BufferedImage image) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 杞︾墝璇嗗埆
+ * @param imageData 鍥剧墖瀛楄妭鏁扮粍
+ * @return
+ */
+ default R<List<PlateInfo>> recognize(byte[] imageData) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 杞︾墝璇嗗埆
+ * @param image DJL Image
+ * @return
+ */
+ default R<List<PlateInfo>> recognize(Image image){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 璇嗗埆瑁佸壀鍚庣殑鍥剧墖
+ * @return
+ */
+ default PlateResult recognizeCropped(Image image){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 妫�娴嬪苟缁樺埗缁撴灉
+ * @param imagePath 鍥剧墖杈撳叆璺緞锛堝寘鍚枃浠跺悕绉帮級
+ * @param outputPath 鍥剧墖杈撳嚭璺緞锛堝寘鍚枃浠跺悕绉帮級
+ */
+ default R<Void> recognizeAndDraw(String imagePath, String outputPath) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 妫�娴嬪苟缁樺埗缁撴灉
+ * @param sourceImage
+ * @return
+ */
+ default R<BufferedImage> recognizeAndDraw(BufferedImage sourceImage){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ default GenericObjectPool<Predictor<Image, PlateResult>> getPool() {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/plate/Yolov5PlateDetModel.java b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/Yolov5PlateDetModel.java
new file mode 100644
index 0000000..53f8165
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/Yolov5PlateDetModel.java
@@ -0,0 +1,238 @@
+package com.xindao.ocr.smartjavaai.model.plate;
+
+import ai.djl.MalformedModelException;
+import ai.djl.engine.Engine;
+import ai.djl.inference.Predictor;
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.ImageFactory;
+import ai.djl.modality.cv.output.DetectedObjects;
+import ai.djl.repository.zoo.Criteria;
+import ai.djl.repository.zoo.ModelNotFoundException;
+import ai.djl.repository.zoo.ModelZoo;
+import ai.djl.repository.zoo.ZooModel;
+import cn.smartjavaai.common.entity.R;
+import cn.smartjavaai.common.pool.PredictorFactory;
+import cn.smartjavaai.common.utils.Base64ImageUtils;
+import cn.smartjavaai.common.utils.FileUtils;
+import cn.smartjavaai.common.utils.ImageUtils;
+import cn.smartjavaai.common.utils.OpenCVUtils;
+import com.xindao.ocr.smartjavaai.config.PlateDetModelConfig;
+import com.xindao.ocr.smartjavaai.entity.PlateInfo;
+import com.xindao.ocr.smartjavaai.exception.OcrException;
+import com.xindao.ocr.smartjavaai.model.plate.criteria.PlateDetCriterialFactory;
+import com.xindao.ocr.smartjavaai.utils.OcrUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+import org.opencv.core.Mat;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Yolov5 杞︾墝妫�娴嬫ā鍨�
+ * @author dwj
+ * @date 2025/7/23
+ */
+@Slf4j
+public class Yolov5PlateDetModel implements PlateDetModel{
+
+ private GenericObjectPool<Predictor<Image, DetectedObjects>> detPredictorPool;
+
+ private ZooModel<Image, DetectedObjects> detectionModel;
+
+ private PlateDetModelConfig config;
+
+ @Override
+ public void loadModel(PlateDetModelConfig config) {
+ if(StringUtils.isBlank(config.getModelPath())){
+ throw new OcrException("modelPath is null");
+ }
+ this.config = config;
+ //鍒濆鍖� 妫�娴婥riteria
+ Criteria<Image, DetectedObjects> detCriteria = PlateDetCriterialFactory.createCriteria(config);
+ try{
+ detectionModel = ModelZoo.loadModel(detCriteria);
+ // 鍒涘缓姹犲瓙锛氭瘡涓嚎绋嬬嫭浜� Predictor
+ this.detPredictorPool = new GenericObjectPool<>(new PredictorFactory<>(detectionModel));
+ int predictorPoolSize = config.getPredictorPoolSize();
+ if(config.getPredictorPoolSize() <= 0){
+ predictorPoolSize = Runtime.getRuntime().availableProcessors(); // 榛樿绛変簬CPU鏍稿績鏁�
+ }
+ detPredictorPool.setMaxTotal(predictorPoolSize);
+ log.debug("褰撳墠璁惧: " + detectionModel.getNDManager().getDevice());
+ log.debug("褰撳墠寮曟搸: " + Engine.getInstance().getEngineName());
+ log.debug("妯″瀷鎺ㄧ悊鍣ㄧ嚎绋嬫睜鏈�澶ф暟閲�: " + predictorPoolSize);
+ } catch (IOException | ModelNotFoundException | MalformedModelException e) {
+ throw new OcrException("妫�娴嬫ā鍨嬪姞杞藉け璐�", e);
+ }
+ }
+
+ @Override
+ public R<List<PlateInfo>> detect(String imagePath) {
+ if(!FileUtils.isFileExists(imagePath)){
+ return R.fail(R.Status.FILE_NOT_FOUND);
+ }
+ Image img = null;
+ try {
+ img = ImageFactory.getInstance().fromFile(Paths.get(imagePath));
+ } catch (IOException e) {
+ throw new OcrException("鏃犳晥鐨勫浘鐗�", e);
+ }
+ DetectedObjects detectedObjects = detect(img);
+ if (Objects.isNull(detectedObjects) || detectedObjects.getNumberOfObjects() == 0){
+ return R.fail(R.Status.NO_OBJECT_DETECTED);
+ }
+ List<PlateInfo> plateInfoList = OcrUtils.convertToPlateInfo(detectedObjects, img);
+ ((Mat)img.getWrappedImage()).release();
+ return R.ok(plateInfoList);
+ }
+
+ @Override
+ public R<List<PlateInfo>> detectBase64(String base64Image) {
+ if(StringUtils.isBlank(base64Image)){
+ return R.fail(R.Status.INVALID_IMAGE);
+ }
+ byte[] imageData = Base64ImageUtils.base64ToImage(base64Image);
+ return detect(imageData);
+ }
+
+ @Override
+ public R<List<PlateInfo>> detect(BufferedImage image) {
+ if(!ImageUtils.isImageValid(image)){
+ return R.fail(R.Status.INVALID_IMAGE);
+ }
+ Image img = ImageFactory.getInstance().fromImage(OpenCVUtils.image2Mat(image));
+ DetectedObjects detectedObjects = detect(img);
+ if (Objects.isNull(detectedObjects) || detectedObjects.getNumberOfObjects() == 0){
+ return R.fail(R.Status.NO_OBJECT_DETECTED);
+ }
+ List<PlateInfo> plateInfoList = OcrUtils.convertToPlateInfo(detectedObjects, img);
+ ((Mat)img.getWrappedImage()).release();
+ return R.ok(plateInfoList);
+ }
+
+ @Override
+ public R<List<PlateInfo>> detect(byte[] imageData) {
+ if(Objects.isNull(imageData)){
+ return R.fail(R.Status.INVALID_IMAGE);
+ }
+ return detect(new ByteArrayInputStream(imageData));
+ }
+
+ @Override
+ public DetectedObjects detect(Image image) {
+ Predictor<Image, DetectedObjects> predictor = null;
+ try {
+ predictor = detPredictorPool.borrowObject();
+ return predictor.predict(image);
+ } catch (Exception e) {
+ throw new OcrException("杞︾墝妫�娴嬮敊璇�", e);
+ }finally {
+ if (predictor != null) {
+ try {
+ detPredictorPool.returnObject(predictor); //褰掕繕
+ } catch (Exception e) {
+ log.warn("褰掕繕Predictor澶辫触", e);
+ try {
+ predictor.close(); // 褰掕繕澶辫触鎵嶉攢姣�
+ } catch (Exception ex) {
+ log.error("鍏抽棴Predictor澶辫触", ex);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public R<List<PlateInfo>> detect(InputStream inputStream) {
+ if(Objects.isNull(inputStream)){
+ return R.fail(R.Status.INVALID_IMAGE);
+ }
+ try {
+ Image img = ImageFactory.getInstance().fromInputStream(inputStream);
+ DetectedObjects detection = detect(img);
+ List<PlateInfo> plateInfoList = OcrUtils.convertToPlateInfo(detection, img);
+ ((Mat)img.getWrappedImage()).release();
+ return R.ok(plateInfoList);
+ } catch (IOException e) {
+ throw new OcrException("鏃犳晥鍥剧墖杈撳叆娴�", e);
+ }
+ }
+
+ @Override
+ public R<Void> detectAndDraw(String imagePath, String outputPath) {
+ if(!FileUtils.isFileExists(imagePath)){
+ return R.fail(R.Status.FILE_NOT_FOUND);
+ }
+ try {
+ Image img = ImageFactory.getInstance().fromFile(Paths.get(imagePath));
+ DetectedObjects detectedObjects = detect(img);
+ if(Objects.isNull(detectedObjects) || detectedObjects.getNumberOfObjects() == 0){
+ return R.fail(R.Status.NO_FACE_DETECTED);
+ }
+ img.drawBoundingBoxes(detectedObjects);
+ Path output = Paths.get(outputPath);
+ log.debug("Saving to {}", output.toAbsolutePath().toString());
+ img.save(Files.newOutputStream(output), "png");
+ return R.ok();
+ } catch (IOException e) {
+ throw new OcrException(e);
+ }
+ }
+
+ @Override
+ public R<BufferedImage> detectAndDraw(BufferedImage sourceImage) {
+ if(!ImageUtils.isImageValid(sourceImage)){
+ return R.fail(R.Status.INVALID_IMAGE);
+ }
+ Image img = ImageFactory.getInstance().fromImage(OpenCVUtils.image2Mat(sourceImage));
+ DetectedObjects detectedObjects = detect(img);
+ if(Objects.isNull(detectedObjects) || detectedObjects.getNumberOfObjects() == 0){
+ return R.fail(R.Status.NO_FACE_DETECTED);
+ }
+ img.drawBoundingBoxes(detectedObjects);
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ // 璋冪敤 save 鏂规硶灏� Image 鍐欏叆瀛楄妭娴�
+ img.save(outputStream, "png");
+ // 灏嗗瓧鑺傛祦杞崲涓� BufferedImage
+ byte[] imageBytes = outputStream.toByteArray();
+ return R.ok(ImageIO.read(new ByteArrayInputStream(imageBytes)));
+ } catch (IOException e) {
+ throw new OcrException("瀵煎嚭鍥剧墖澶辫触", e);
+ }
+ }
+
+ @Override
+ public GenericObjectPool<Predictor<Image, DetectedObjects>> getPool() {
+ return detPredictorPool;
+ }
+
+ @Override
+ public void close() throws Exception {
+ try {
+ if (detPredictorPool != null) {
+ detPredictorPool.close();
+ }
+ } catch (Exception e) {
+ log.warn("鍏抽棴 predictorPool 澶辫触", e);
+ }
+ try {
+ if (detectionModel != null) {
+ detectionModel.close();
+ }
+ } catch (Exception e) {
+ log.warn("鍏抽棴 model 澶辫触", e);
+ }
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/plate/criteria/PlateDetCriterialFactory.java b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/criteria/PlateDetCriterialFactory.java
new file mode 100644
index 0000000..f54fafc
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/criteria/PlateDetCriterialFactory.java
@@ -0,0 +1,71 @@
+package com.xindao.ocr.smartjavaai.model.plate.criteria;
+
+import ai.djl.Device;
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.output.DetectedObjects;
+import ai.djl.repository.zoo.Criteria;
+import ai.djl.training.util.ProgressBar;
+import cn.smartjavaai.common.enums.DeviceEnum;
+import com.xindao.ocr.smartjavaai.config.PlateDetModelConfig;
+import com.xindao.ocr.smartjavaai.enums.PlateDetModelEnum;
+import com.xindao.ocr.smartjavaai.model.plate.translator.Yolo5PlateDetectTranslator;
+import com.xindao.ocr.smartjavaai.model.plate.translator.Yolov7PlateDetectTranslator;
+import org.apache.commons.lang3.StringUtils;
+
+import java.nio.file.Paths;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author dwj
+ * @date 2025/7/8
+ */
+public class PlateDetCriterialFactory {
+
+
+ public static Criteria<Image, DetectedObjects> createCriteria(PlateDetModelConfig config) {
+ Device device = null;
+ if(!Objects.isNull(config.getDevice())){
+ device = config.getDevice() == DeviceEnum.CPU ? Device.cpu() : Device.gpu(config.getGpuId());
+ }
+ Criteria<Image, DetectedObjects> criteria = null;
+ ConcurrentHashMap params = new ConcurrentHashMap<String, String>();
+ params.putAll(config.getCustomParams());
+ if(StringUtils.isNotBlank(config.getBatchifier())){
+ params.put("batchifier", config.getBatchifier());
+ }
+ if(config.getModelEnum() == PlateDetModelEnum.YOLOV5){
+ criteria =
+ Criteria.builder()
+ .optEngine("OnnxRuntime")
+ .setTypes(Image.class, DetectedObjects.class)
+ .optModelPath(Paths.get(config.getModelPath()))
+ .optTranslator(new Yolo5PlateDetectTranslator(params))
+ .optDevice(device)
+ .optProgress(new ProgressBar())
+ .build();
+ }else if (config.getModelEnum() == PlateDetModelEnum.YOLOV7){
+ criteria =
+ Criteria.builder()
+ .optEngine("OnnxRuntime")
+ .setTypes(Image.class, DetectedObjects.class)
+ .optModelPath(Paths.get(config.getModelPath()))
+ .optTranslator(new Yolov7PlateDetectTranslator(params))
+ .optDevice(device)
+ .optProgress(new ProgressBar())
+ .build();
+ }
+// else if (config.getModelEnum() == PlateDetModelEnum.YOLOV8){
+// criteria =
+// Criteria.builder()
+// .optEngine("OnnxRuntime")
+// .setTypes(Image.class, DetectedObjects.class)
+// .optModelPath(Paths.get(config.getModelPath()))
+// .optTranslator(new Yolov8PlateDetectTranslator(params))
+// .optDevice(device)
+// .optProgress(new ProgressBar())
+// .build();
+// }
+ return criteria;
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/plate/criteria/PlateRecCriterialFactory.java b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/criteria/PlateRecCriterialFactory.java
new file mode 100644
index 0000000..f53c9c2
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/criteria/PlateRecCriterialFactory.java
@@ -0,0 +1,42 @@
+package com.xindao.ocr.smartjavaai.model.plate.criteria;
+
+import ai.djl.Device;
+import ai.djl.modality.cv.Image;
+import ai.djl.repository.zoo.Criteria;
+import ai.djl.training.util.ProgressBar;
+import cn.smartjavaai.common.enums.DeviceEnum;
+import com.xindao.ocr.smartjavaai.config.PlateRecModelConfig;
+import com.xindao.ocr.smartjavaai.entity.PlateResult;
+import com.xindao.ocr.smartjavaai.enums.PlateRecModelEnum;
+import com.xindao.ocr.smartjavaai.model.plate.translator.CRNNPlateRecTranslator;
+
+import java.nio.file.Paths;
+import java.util.Objects;
+
+/**
+ * @author dwj
+ * @date 2025/7/8
+ */
+public class PlateRecCriterialFactory {
+
+
+ public static Criteria<Image, PlateResult> createCriteria(PlateRecModelConfig config) {
+ Device device = null;
+ if(!Objects.isNull(config.getDevice())){
+ device = config.getDevice() == DeviceEnum.CPU ? Device.cpu() : Device.gpu(config.getGpuId());
+ }
+ Criteria<Image, PlateResult> criteria = null;
+ if(config.getModelEnum() == PlateRecModelEnum.PLATE_REC_CRNN){
+ criteria =
+ Criteria.builder()
+ .optEngine("OnnxRuntime")
+ .setTypes(Image.class, PlateResult.class)
+ .optModelPath(Paths.get(config.getModelPath()))
+ .optTranslator(new CRNNPlateRecTranslator())
+ .optDevice(device)
+ .optProgress(new ProgressBar())
+ .build();
+ }
+ return criteria;
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/plate/translator/CRNNPlateRecTranslator.java b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/translator/CRNNPlateRecTranslator.java
new file mode 100644
index 0000000..ed1d64d
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/translator/CRNNPlateRecTranslator.java
@@ -0,0 +1,88 @@
+package com.xindao.ocr.smartjavaai.model.plate.translator;
+
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.util.NDImageUtils;
+import ai.djl.ndarray.NDArray;
+import ai.djl.ndarray.NDList;
+import ai.djl.ndarray.NDManager;
+import ai.djl.ndarray.types.DataType;
+import ai.djl.translate.Batchifier;
+import ai.djl.translate.Translator;
+import ai.djl.translate.TranslatorContext;
+import com.xindao.ocr.smartjavaai.entity.PlateResult;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author dwj
+ */
+public class CRNNPlateRecTranslator implements Translator<Image, PlateResult> {
+
+ private static final String plateName = "#浜勃娲ユ笣鍐�鏅嬭挋杈藉悏榛戣嫃娴欑殩闂借担椴佽鲍閯傛箻绮ゆ鐞煎窛璐典簯钘忛檿鐢橀潚瀹佹柊瀛﹁娓境鎸備娇棰嗘皯鑸嵄0123456789ABCDEFGHJKLMNPQRSTUVWXYZ闄╁搧";
+ private static final String[] plateColors = {"榛戣壊", "钃濊壊", "缁胯壊", "鐧借壊", "榛勮壊"};
+ private static final float MEAN = 0.588f;
+ private static final float STD = 0.193f;
+
+ @Override
+ public NDList processInput(TranslatorContext ctx, Image input) {
+ NDManager manager = ctx.getNDManager();
+
+ // Resize to (168, 48)
+ NDArray array = input.toNDArray(manager, Image.Flag.COLOR);
+ array = NDImageUtils.resize(array, 168, 48);
+
+ // Normalize
+ array = array.toType(DataType.FLOAT32, false)
+ .div(255f)
+ .sub(MEAN)
+ .div(STD);
+
+ // HWC to CHW
+ array = array.transpose(2, 0, 1);
+ array = array.expandDims(0); // batch dimension
+
+ return new NDList(array);
+ }
+
+ @Override
+ public PlateResult processOutput(TranslatorContext ctx, NDList list) {
+ NDArray plateOutput = list.get(0); // shape: [1, T, num_classes]
+ NDArray colorOutput = list.get(1); // shape: [1, num_colors]
+
+ int[] plateIdx = plateOutput.argMax(-1)
+ .toType(DataType.INT32, false)
+ .toIntArray();
+ int colorIdx = colorOutput.argMax(1).toType(DataType.INT32, false).toIntArray()[0];
+
+ String plateNo = decodePlate(plateIdx);
+ String plateColor = plateColors[colorIdx];
+
+ return new PlateResult(plateNo, plateColor);
+ }
+
+ private String decodePlate(int[] preds) {
+ int pre = 0;
+ List<Integer> newPreds = new ArrayList<>();
+ for (int idx : preds) {
+ if (idx != 0 && idx != pre) {
+ newPreds.add(idx);
+ }
+ pre = idx;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ for (int i : newPreds) {
+ if (i >= 0 && i < plateName.length()) {
+ sb.append(plateName.charAt(i));
+ }
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public Batchifier getBatchifier() {
+ return null; // 闈炴壒閲忎换鍔�
+ }
+}
+
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/plate/translator/Yolo5PlateDetectTranslator.java b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/translator/Yolo5PlateDetectTranslator.java
new file mode 100644
index 0000000..6a2ebdf
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/translator/Yolo5PlateDetectTranslator.java
@@ -0,0 +1,194 @@
+package com.xindao.ocr.smartjavaai.model.plate.translator;
+
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.output.BoundingBox;
+import ai.djl.modality.cv.output.DetectedObjects;
+import ai.djl.modality.cv.output.Landmark;
+import ai.djl.modality.cv.output.Point;
+import ai.djl.ndarray.NDArray;
+import ai.djl.ndarray.NDArrays;
+import ai.djl.ndarray.NDList;
+import ai.djl.ndarray.NDManager;
+import ai.djl.ndarray.types.DataType;
+import ai.djl.translate.Batchifier;
+import ai.djl.translate.Translator;
+import ai.djl.translate.TranslatorContext;
+import cn.smartjavaai.common.utils.LetterBoxUtils;
+import cn.smartjavaai.common.utils.NMSUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author dwj
+ */
+public class Yolo5PlateDetectTranslator implements Translator<Image, DetectedObjects> {
+
+ private int inputSize = 640;
+ private float minConfThreshold = 0.3f;
+ private float iouThreshold = 0.5f;
+
+ private float confThreshold = 0;
+
+ private int imageWidth;
+ private int imageHeight;
+
+ private int topK;
+
+ public Yolo5PlateDetectTranslator(Map<String, ?> arguments) {
+ confThreshold =
+ arguments.containsKey("confThreshold")
+ ? Integer.parseInt(arguments.get("confThreshold").toString())
+ : 0.3f;
+
+ iouThreshold =
+ arguments.containsKey("iouThreshold")
+ ? Integer.parseInt(arguments.get("iouThreshold").toString())
+ : 0.5f;
+
+ topK = arguments.containsKey("topk")
+ ? Integer.parseInt(arguments.get("topk").toString())
+ : 100;
+ }
+
+ @Override
+ public NDList processInput(TranslatorContext ctx, Image input) {
+ NDManager manager = ctx.getNDManager();
+ NDArray array = input.toNDArray(manager, Image.Flag.COLOR);
+ imageWidth = (int) array.getShape().get(1);
+ imageHeight = (int) array.getShape().get(0);
+ //Letter box resize 640x640 with padding (淇濇寔姣斾緥锛岃ˉ杈圭紭)
+ LetterBoxUtils.ResizeResult letterBoxResult = LetterBoxUtils.letterbox(manager, array, inputSize, inputSize, 114f, LetterBoxUtils.PaddingPosition.CENTER);
+ ctx.setAttachment("letterBoxResult", letterBoxResult);
+ array = letterBoxResult.image;
+ // 杞负 float32 涓斿綊涓�鍖栧埌 0~1
+ array = array.toType(DataType.FLOAT32, false).div(255f); // HWC
+ // HWC -> CHW
+ array = array.transpose(2, 0, 1); // CHW
+ return new NDList(array.expandDims(0));
+ }
+
+ @Override
+ public DetectedObjects processOutput(TranslatorContext ctx, NDList list) {
+ NDManager manager = ctx.getNDManager();
+ LetterBoxUtils.ResizeResult letterBoxResult = (LetterBoxUtils.ResizeResult)ctx.getAttachment("letterBoxResult");
+ //[x_center, y_center, w, h, obj_conf, 8涓叧閿偣, class1_conf, class2_conf]
+ //鐩爣缃俊搴� obj_conf 5:13 鍏抽敭鐐� [13:15]鍒嗙被寰楀垎锛氬崟灞傝溅鐗� / 鍙屽眰杞︾墝
+ NDArray dets = list.singletonOrThrow();
+ //缃俊搴﹁繃婊� (1,25200, 15)
+ NDArray dets0 = dets.get(0);
+ NDArray conf = dets0.get(":, 4"); // shape [N]
+ NDArray mask = conf.gt(minConfThreshold);
+ //绛涢�夊嚭绗﹀悎鏉′欢鐨勬(17,15)
+ NDArray detsFiltered = dets0.get(mask); // 绛涙帀浣庣疆淇″害
+
+ //鎶婂垎绫诲緱鍒� [13:15] * 缃俊搴� [4:5] 鍋氳仈鍚堟鐜�
+ NDArray clsLogits = detsFiltered.get(":, 13:15"); // (N, 2)
+ NDArray confFiltered = detsFiltered.get(":, 4").reshape(-1, 1); // (N, 1)
+ clsLogits = clsLogits.mul(confFiltered); // (N, 2)锛屽彉鎴� obj_conf * class_conf
+
+ NDArray jointScore = clsLogits.max(new int[]{1}); // shape (N,)
+ // 鑱斿悎杩囨护
+ NDArray jointMask = jointScore.gt(confThreshold);
+ detsFiltered = detsFiltered.get(jointMask);
+
+ if (detsFiltered.isEmpty()) {
+ return new DetectedObjects(Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
+ }
+
+ clsLogits = clsLogits.get(jointMask);
+
+
+ //涓績鐐规 [x,y,w,h] 鉃� 宸︿笂鍙充笅 [x1,y1,x2,y2]
+ NDArray xywh = detsFiltered.get(":, 0:4"); // (N, 4)
+ NDArray halfWH = xywh.get(":, 2:4").div(2); // (N, 2)
+ NDArray xy1 = xywh.get(":, 0:2").sub(halfWH); // (N, 2)
+ NDArray xy2 = xywh.get(":, 0:2").add(halfWH); // (N, 2)
+ NDArray boxes = NDArrays.concat(new NDList(xy1, xy2), 1); // (N, 4)
+
+ // 鍒嗙被寰楀垎鏈�澶у�硷細score (N, 1)锛屽搴旂被鍒� index (N, 1)
+ NDArray scores = clsLogits.max(new int[]{1}, true); // (N, 1)
+ NDArray indices = clsLogits.argMax(1).reshape(-1, 1).toType(DataType.FLOAT32, false); // (N, 1)
+
+ // 鍏抽敭鐐瑰潗鏍� [5:13]
+ NDArray keyPoints = detsFiltered.get(":, 5:13"); // (N, 8)
+
+ // 鎷兼垚鏈�缁堢粨鏋滐細(x1, y1, x2, y2, score, 8鍏抽敭鐐�, index)
+ NDArray output = NDArrays.concat(new NDList(boxes, scores, keyPoints, indices), 1); // (N, 14)
+
+ // NMS 杩囨护鎺夐噸鍙犳
+ int[] keepIndices = NMSUtils.nms(boxes, scores.squeeze(), iouThreshold); // scores.squeeze() 鉃� (N,)銆�
+ if (keepIndices.length == 0) {
+ return new DetectedObjects(Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
+ }
+ NDArray kept = output.get(manager.create(keepIndices));
+ // 濡傛灉瓒呰繃 topK锛屽垯鎴柇
+ if (keepIndices.length > topK) {
+ int[] topkIndices = new int[topK];
+ System.arraycopy(keepIndices, 0, topkIndices, 0, topK);
+ keepIndices = topkIndices;
+ }
+ //鎭㈠鍘熷浘鍧愭爣锛堥櫎鍥炴瘮渚嬶紝鍑忔帀 padding锛�
+ NDArray restored = LetterBoxUtils.restoreBox(kept, letterBoxResult.r, letterBoxResult.left, letterBoxResult.top, 5,8);
+
+ List<String> classNames = new ArrayList<>();
+ List<Double> probabilities = new ArrayList<>();
+ List<BoundingBox> boundingBoxes = new ArrayList<>();
+
+ float[] flatData = restored.toFloatArray();
+ long[] shape = restored.getShape().getShape(); // 姣斿 (N, 14)
+ int rows = (int) shape[0];
+ int cols = (int) shape[1];
+
+ // 鎶婁竴缁存暟缁勯噸缁勪负浜岀淮鏁扮粍
+ float[][] data = new float[rows][cols];
+ for (int i = 0; i < rows; i++) {
+ System.arraycopy(flatData, i * cols, data[i], 0, cols);
+ }
+
+ for (float[] row : data) {
+ // row缁撴瀯锛�(x1, y1, x2, y2, score, kp1,..., kp8, classIndex)
+ float x1 = row[0];
+ float y1 = row[1];
+ float x2 = row[2];
+ float y2 = row[3];
+ float score = row[4];
+ int classIndex = (int) row[13];
+
+ double prob = score;
+ String className = classIndex == 0 ? "single" : "double";
+
+ // 杞浉瀵瑰潗鏍囷紝DJL鐨凴ectangle鐢ㄦ瘮渚嬪潗鏍囷紙0~1锛�
+ double rectX = x1 / imageWidth;
+ double rectY = y1 / imageHeight;
+ double rectW = (x2 - x1) / imageWidth;
+ double rectH = (y2 - y1) / imageHeight;
+
+ // 鏋勫缓 Polygon 鍥涗釜瑙掔偣
+ List<Point> pointsSrc = new ArrayList<>();
+ pointsSrc.add(new Point(row[5], row[6]));
+ pointsSrc.add(new Point(row[7], row[8]));
+ pointsSrc.add(new Point(row[9], row[10]));
+ pointsSrc.add(new Point(row[11], row[12]));
+
+ Landmark box = new Landmark(rectX, rectY, rectW, rectH, pointsSrc);
+ classNames.add(className);
+ probabilities.add(prob);
+ boundingBoxes.add(box);
+ }
+ DetectedObjects detectedObjects = new DetectedObjects(classNames, probabilities, boundingBoxes);
+ return detectedObjects;
+
+ }
+
+ @Override
+ public Batchifier getBatchifier() {
+ return null;
+ }
+
+
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/plate/translator/Yolov7PlateDetectTranslator.java b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/translator/Yolov7PlateDetectTranslator.java
new file mode 100644
index 0000000..895a853
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/translator/Yolov7PlateDetectTranslator.java
@@ -0,0 +1,192 @@
+package com.xindao.ocr.smartjavaai.model.plate.translator;
+
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.output.BoundingBox;
+import ai.djl.modality.cv.output.DetectedObjects;
+import ai.djl.modality.cv.output.Landmark;
+import ai.djl.modality.cv.output.Point;
+import ai.djl.ndarray.NDArray;
+import ai.djl.ndarray.NDArrays;
+import ai.djl.ndarray.NDList;
+import ai.djl.ndarray.NDManager;
+import ai.djl.ndarray.types.DataType;
+import ai.djl.translate.Batchifier;
+import ai.djl.translate.Translator;
+import ai.djl.translate.TranslatorContext;
+import cn.smartjavaai.common.utils.LetterBoxUtils;
+import cn.smartjavaai.common.utils.NMSUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author dwj
+ */
+public class Yolov7PlateDetectTranslator implements Translator<Image, DetectedObjects> {
+
+ private int inputSize = 640;
+ private float minConfThreshold = 0.3f;
+ private float iouThreshold = 0.5f;
+
+ private float confThreshold = 0;
+
+ private int imageWidth;
+ private int imageHeight;
+
+ private int topK;
+
+ private LetterBoxUtils.ResizeResult letterBoxResult;
+
+ public Yolov7PlateDetectTranslator(Map<String, ?> arguments) {
+ confThreshold =
+ arguments.containsKey("confThreshold")
+ ? Integer.parseInt(arguments.get("confThreshold").toString())
+ : 0.3f;
+
+ iouThreshold =
+ arguments.containsKey("iouThreshold")
+ ? Integer.parseInt(arguments.get("iouThreshold").toString())
+ : 0.5f;
+
+ topK = arguments.containsKey("topk")
+ ? Integer.parseInt(arguments.get("topk").toString())
+ : 100;
+ }
+
+ @Override
+ public NDList processInput(TranslatorContext ctx, Image input) {
+ NDManager manager = ctx.getNDManager();
+ NDArray array = input.toNDArray(manager, Image.Flag.COLOR);
+ imageWidth = (int) array.getShape().get(1);
+ imageHeight = (int) array.getShape().get(0);
+ //Letter box resize 640x640 with padding (淇濇寔姣斾緥锛岃ˉ杈圭紭)
+ letterBoxResult = LetterBoxUtils.letterbox(manager, array, inputSize, inputSize, 114f, LetterBoxUtils.PaddingPosition.CENTER);
+ array = letterBoxResult.image;
+ // 杞负 float32 涓斿綊涓�鍖栧埌 0~1
+ array = array.toType(DataType.FLOAT32, false).div(255f); // HWC
+ // HWC -> CHW
+ array = array.transpose(2, 0, 1); // CHW
+ return new NDList(array.expandDims(0));
+ }
+
+ @Override
+ public DetectedObjects processOutput(TranslatorContext ctx, NDList list) {
+ NDManager manager = ctx.getNDManager();
+ int num_cls = 2;
+ //[x_center, y_center, w, h, obj_conf, class1_conf, class2_conf,8涓叧閿偣]
+ //鐩爣缃俊搴� obj_conf 5:13 鍏抽敭鐐� [13:15]鍒嗙被寰楀垎锛氬崟灞傝溅鐗� / 鍙屽眰杞︾墝
+ NDArray dets = list.singletonOrThrow();
+ //缃俊搴﹁繃婊� (1,25200, 15)
+ NDArray dets0 = dets.get(0);
+ NDArray conf = dets0.get(":, 4"); // shape [N]
+ NDArray mask = conf.gt(minConfThreshold);
+ //绛涢�夊嚭绗﹀悎鏉′欢鐨勬(17,15)
+ NDArray detsFiltered = dets0.get(mask); // 绛涙帀浣庣疆淇″害
+
+ //鎶婂垎绫诲緱鍒� [5:7] * 缃俊搴� [4:5] 鍋氳仈鍚堟鐜�
+ NDArray clsLogits = detsFiltered.get(":, 5:7"); // (N, 2)
+ NDArray confFiltered = detsFiltered.get(":, 4").reshape(-1, 1); // (N, 1)
+ clsLogits = clsLogits.mul(confFiltered); // (N, 2)锛屽彉鎴� obj_conf * class_conf
+
+ NDArray jointScore = clsLogits.max(new int[]{1}); // shape (N,)
+ // 鑱斿悎杩囨护
+ NDArray jointMask = jointScore.gt(confThreshold);
+ detsFiltered = detsFiltered.get(jointMask);
+ clsLogits = clsLogits.get(jointMask);
+
+
+ //涓績鐐规 [x,y,w,h] 鉃� 宸︿笂鍙充笅 [x1,y1,x2,y2]
+ NDArray xywh = detsFiltered.get(":, 0:4"); // (N, 4)
+ NDArray halfWH = xywh.get(":, 2:4").div(2); // (N, 2)
+ NDArray xy1 = xywh.get(":, 0:2").sub(halfWH); // (N, 2)
+ NDArray xy2 = xywh.get(":, 0:2").add(halfWH); // (N, 2)
+ NDArray boxes = NDArrays.concat(new NDList(xy1, xy2), 1); // (N, 4)
+
+ // 鍒嗙被寰楀垎鏈�澶у�硷細score (N, 1)锛屽搴旂被鍒� index (N, 1)
+ NDArray scores = clsLogits.max(new int[]{1}, true); // (N, 1)
+ NDArray indices = clsLogits.argMax(1).reshape(-1, 1).toType(DataType.FLOAT32, false); // (N, 1)
+
+ // 鍏抽敭鐐瑰潗鏍� [7,8,10,11,13,14,16,17]
+ NDArray keyPoints = NDArrays.concat(new NDList(
+ detsFiltered.get(":, 7:8"),
+ detsFiltered.get(":, 8:9"),
+ detsFiltered.get(":, 10:11"),
+ detsFiltered.get(":, 11:12"),
+ detsFiltered.get(":, 13:14"),
+ detsFiltered.get(":, 14:15"),
+ detsFiltered.get(":, 16:17"),
+ detsFiltered.get(":, 17:18")
+ ), 1); // 鎷兼垚 (N, 8)
+
+ // 鎷兼垚鏈�缁堢粨鏋滐細(x1, y1, x2, y2, score, 8鍏抽敭鐐�, index)
+ NDArray output = NDArrays.concat(new NDList(boxes, scores, keyPoints, indices), 1); // (N, 14)
+
+ // NMS 杩囨护鎺夐噸鍙犳
+ int[] keepIndices = NMSUtils.nms(boxes, scores.squeeze(), iouThreshold); // scores.squeeze() 鉃� (N,)
+ NDArray kept = output.get(manager.create(keepIndices));
+ // 濡傛灉瓒呰繃 topK锛屽垯鎴柇
+ if (keepIndices.length > topK) {
+ int[] topkIndices = new int[topK];
+ System.arraycopy(keepIndices, 0, topkIndices, 0, topK);
+ keepIndices = topkIndices;
+ }
+ //鎭㈠鍘熷浘鍧愭爣锛堥櫎鍥炴瘮渚嬶紝鍑忔帀 padding锛�
+ NDArray restored = LetterBoxUtils.restoreBox(kept, letterBoxResult.r, letterBoxResult.left, letterBoxResult.top, 5,8);
+
+ List<String> classNames = new ArrayList<>();
+ List<Double> probabilities = new ArrayList<>();
+ List<BoundingBox> boundingBoxes = new ArrayList<>();
+
+ float[] flatData = restored.toFloatArray();
+ long[] shape = restored.getShape().getShape(); // 姣斿 (N, 14)
+ int rows = (int) shape[0];
+ int cols = (int) shape[1];
+
+ // 鎶婁竴缁存暟缁勯噸缁勪负浜岀淮鏁扮粍
+ float[][] data = new float[rows][cols];
+ for (int i = 0; i < rows; i++) {
+ System.arraycopy(flatData, i * cols, data[i], 0, cols);
+ }
+
+ for (float[] row : data) {
+ // row缁撴瀯锛�(x1, y1, x2, y2, score, kp1,..., kp8, classIndex)
+ float x1 = row[0];
+ float y1 = row[1];
+ float x2 = row[2];
+ float y2 = row[3];
+ float score = row[4];
+ int classIndex = (int) row[13];
+
+ double prob = score;
+ String className = classIndex == 0 ? "single" : "double";
+
+ // 杞浉瀵瑰潗鏍囷紝DJL鐨凴ectangle鐢ㄦ瘮渚嬪潗鏍囷紙0~1锛�
+ double rectX = x1 / imageWidth;
+ double rectY = y1 / imageHeight;
+ double rectW = (x2 - x1) / imageWidth;
+ double rectH = (y2 - y1) / imageHeight;
+
+ // 鏋勫缓 Polygon 鍥涗釜瑙掔偣
+ List<Point> pointsSrc = new ArrayList<>();
+ pointsSrc.add(new Point(row[5], row[6]));
+ pointsSrc.add(new Point(row[7], row[8]));
+ pointsSrc.add(new Point(row[9], row[10]));
+ pointsSrc.add(new Point(row[11], row[12]));
+
+ Landmark box = new Landmark(rectX, rectY, rectW, rectH, pointsSrc);
+ classNames.add(className);
+ probabilities.add(prob);
+ boundingBoxes.add(box);
+ }
+ DetectedObjects detectedObjects = new DetectedObjects(classNames, probabilities, boundingBoxes);
+ return detectedObjects;
+
+ }
+
+ @Override
+ public Batchifier getBatchifier() {
+ return null;
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/plate/translator/Yolov8PlateDetectTranslator.java b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/translator/Yolov8PlateDetectTranslator.java
new file mode 100644
index 0000000..2babb29
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/plate/translator/Yolov8PlateDetectTranslator.java
@@ -0,0 +1,188 @@
+package com.xindao.ocr.smartjavaai.model.plate.translator;
+
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.output.BoundingBox;
+import ai.djl.modality.cv.output.DetectedObjects;
+import ai.djl.modality.cv.output.Rectangle;
+import ai.djl.ndarray.NDArray;
+import ai.djl.ndarray.NDArrays;
+import ai.djl.ndarray.NDList;
+import ai.djl.ndarray.NDManager;
+import ai.djl.ndarray.types.DataType;
+import ai.djl.translate.Batchifier;
+import ai.djl.translate.Translator;
+import ai.djl.translate.TranslatorContext;
+import cn.smartjavaai.common.utils.LetterBoxUtils;
+import cn.smartjavaai.common.utils.NMSUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author dwj
+ */
+public class Yolov8PlateDetectTranslator implements Translator<Image, DetectedObjects> {
+
+ private int inputSize = 640;
+ private float minConfThreshold = 0.3f;
+ private float iouThreshold = 0.5f;
+
+ private float confThreshold = 0;
+
+ private int imageWidth;
+ private int imageHeight;
+
+ private int topK;
+
+ private LetterBoxUtils.ResizeResult letterBoxResult;
+
+ public Yolov8PlateDetectTranslator(Map<String, ?> arguments) {
+ confThreshold =
+ arguments.containsKey("confThreshold")
+ ? Integer.parseInt(arguments.get("confThreshold").toString())
+ : 0.3f;
+
+ iouThreshold =
+ arguments.containsKey("iouThreshold")
+ ? Integer.parseInt(arguments.get("iouThreshold").toString())
+ : 0.5f;
+
+ topK = arguments.containsKey("topk")
+ ? Integer.parseInt(arguments.get("topk").toString())
+ : 100;
+ }
+
+ @Override
+ public NDList processInput(TranslatorContext ctx, Image input) {
+ NDManager manager = ctx.getNDManager();
+ NDArray array = input.toNDArray(manager, Image.Flag.COLOR);
+ imageWidth = (int) array.getShape().get(1);
+ imageHeight = (int) array.getShape().get(0);
+ //Letter box resize 640x640 with padding (淇濇寔姣斾緥锛岃ˉ杈圭紭)
+ letterBoxResult = LetterBoxUtils.letterbox(manager, array, inputSize, inputSize, 114f, LetterBoxUtils.PaddingPosition.CENTER);
+ array = letterBoxResult.image;
+ // 杞负 float32 涓斿綊涓�鍖栧埌 0~1
+ array = array.toType(DataType.FLOAT32, false).div(255f); // HWC
+ // HWC -> CHW
+ array = array.transpose(2, 0, 1); // CHW
+ return new NDList(array.expandDims(0));
+ }
+
+ @Override
+ public DetectedObjects processOutput(TranslatorContext ctx, NDList list) {
+ NDManager manager = ctx.getNDManager();
+
+ NDArray preds = list.get(0); // shape: (1, 6, 8400)
+ preds = preds.squeeze(0).transpose(1, 0); // shape: (8400, 6)
+
+ // preds shape: (8400, 6)
+ NDArray classScores = preds.get(":, 4:6"); // shape: (8400, 2)
+
+ // 鑾峰彇姣忚鏈�澶у�硷紙瀵瑰簲 Python 鐨� .amax(1)锛�
+ NDArray maxScores = classScores.max(new int[]{1}); // shape: (8400,)
+
+ // 鏋勯�� mask锛歴core > conf
+ NDArray confMask = maxScores.gt(minConfThreshold); // shape: (8400,)
+
+ // 搴旂敤 mask 绛涢��
+ preds = preds.get(confMask); // shape: (N_filtered, 6)
+
+ if (preds.isEmpty()) {
+ return null;
+ }
+
+ // 鎻愬彇 box (xywh)锛岃浆鎹负 xyxy
+ NDArray boxes = preds.get(":, 0:4"); // shape: (N, 4)
+ boxes = xywh2xyxy(boxes); // 鑷畾涔夊嚱鏁帮細center xywh -> xyxy
+
+ // 1. 寰楀垎鍜岀被鍒储寮�
+ NDArray scoresAndClasses = preds.get(":, 4:6"); // shape (num, 2)
+ NDArray scores = scoresAndClasses.max(new int[]{1}, true); // keepDim = true
+ NDArray index = scoresAndClasses.argMax(1).expandDims(1); // 鏈�澶у�肩储寮曪紝绫诲埆锛宻hape (num, 1)
+
+ // 4. 鎷兼帴
+ NDArray result = NDArrays.concat(new NDList(boxes, scores, index), 1); // 鍦ㄥ垪鏂瑰悜鎷兼帴
+
+ // NMS 杩囨护鎺夐噸鍙犳
+ int[] keepIndices = NMSUtils.nms(boxes, scores.squeeze(), iouThreshold); // scores.squeeze() 鉃� (N,)
+ NDArray kept = result.get(manager.create(keepIndices));
+ // 濡傛灉瓒呰繃 topK锛屽垯鎴柇
+ if (keepIndices.length > topK) {
+ int[] topkIndices = new int[topK];
+ System.arraycopy(keepIndices, 0, topkIndices, 0, topK);
+ keepIndices = topkIndices;
+ }
+ //鎭㈠鍘熷浘鍧愭爣锛堥櫎鍥炴瘮渚嬶紝鍑忔帀 padding锛�
+ NDArray restored = LetterBoxUtils.restoreBox(kept, letterBoxResult.r, letterBoxResult.left, letterBoxResult.top, 5,0);
+
+ List<String> classNames = new ArrayList<>();
+ List<Double> probabilities = new ArrayList<>();
+ List<BoundingBox> boundingBoxes = new ArrayList<>();
+
+ float[] flatData = restored.toFloatArray();
+ long[] shape = restored.getShape().getShape(); // 姣斿 (N, 14)
+ int rows = (int) shape[0];
+ int cols = (int) shape[1];
+
+ // 鎶婁竴缁存暟缁勯噸缁勪负浜岀淮鏁扮粍
+ float[][] data = new float[rows][cols];
+ for (int i = 0; i < rows; i++) {
+ System.arraycopy(flatData, i * cols, data[i], 0, cols);
+ }
+
+ for (float[] row : data) {
+ // row缁撴瀯锛�(x1, y1, x2, y2, score, classIndex)
+ float x1 = row[0];
+ float y1 = row[1];
+ float x2 = row[2];
+ float y2 = row[3];
+ float score = row[4];
+ int classIndex = (int) row[5];
+
+ double prob = score;
+ String className = classIndex == 0 ? "single" : "double";
+
+ // 杞浉瀵瑰潗鏍囷紝DJL鐨凴ectangle鐢ㄦ瘮渚嬪潗鏍囷紙0~1锛�
+ double rectX = x1 / imageWidth;
+ double rectY = y1 / imageHeight;
+ double rectW = (x2 - x1) / imageWidth;
+ double rectH = (y2 - y1) / imageHeight;
+
+ // 鏋勫缓 Polygon 鍥涗釜瑙掔偣
+// List<Point> pointsSrc = new ArrayList<>();
+// pointsSrc.add(new Point(row[5], row[6]));
+// pointsSrc.add(new Point(row[7], row[8]));
+// pointsSrc.add(new Point(row[9], row[10]));
+// pointsSrc.add(new Point(row[11], row[12]));
+
+ Rectangle rectangle = new Rectangle(rectX, rectY, rectW, rectH);
+ classNames.add(className);
+ probabilities.add(prob);
+ boundingBoxes.add(rectangle);
+ }
+ DetectedObjects detectedObjects = new DetectedObjects(classNames, probabilities, boundingBoxes);
+ return detectedObjects;
+
+ }
+
+ @Override
+ public Batchifier getBatchifier() {
+ return null;
+ }
+
+
+
+ public static NDArray xywh2xyxy(NDArray xywh) {
+ NDArray x = xywh.get(":, 0");
+ NDArray y = xywh.get(":, 1");
+ NDArray w = xywh.get(":, 2").div(2);
+ NDArray h = xywh.get(":, 3").div(2);
+ NDArray x1 = x.sub(w);
+ NDArray y1 = y.sub(h);
+ NDArray x2 = x.add(w);
+ NDArray y2 = y.add(h);
+ return NDArrays.stack(new NDList(x1, y1, x2, y2), 1);
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/table/CommonTableStructureModel.java b/src/main/java/com/xindao/ocr/smartjavaai/model/table/CommonTableStructureModel.java
new file mode 100644
index 0000000..7fb4915
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/table/CommonTableStructureModel.java
@@ -0,0 +1,163 @@
+package com.xindao.ocr.smartjavaai.model.table;
+
+import ai.djl.MalformedModelException;
+import ai.djl.engine.Engine;
+import ai.djl.inference.Predictor;
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.ImageFactory;
+import ai.djl.repository.zoo.Criteria;
+import ai.djl.repository.zoo.ModelNotFoundException;
+import ai.djl.repository.zoo.ModelZoo;
+import ai.djl.repository.zoo.ZooModel;
+import cn.smartjavaai.common.entity.R;
+import cn.smartjavaai.common.pool.PredictorFactory;
+import cn.smartjavaai.common.utils.FileUtils;
+import cn.smartjavaai.common.utils.ImageUtils;
+import cn.smartjavaai.common.utils.OpenCVUtils;
+import com.xindao.ocr.smartjavaai.config.TableStructureConfig;
+import com.xindao.ocr.smartjavaai.entity.TableStructureResult;
+import com.xindao.ocr.smartjavaai.exception.OcrException;
+import com.xindao.ocr.smartjavaai.model.table.criteria.StructureCriteriaFactory;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+import org.opencv.core.Mat;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.Objects;
+
+/**
+ * 琛ㄦ牸缁撴瀯妯″瀷
+ * @author dwj
+ */
+@Slf4j
+public class CommonTableStructureModel implements TableStructureModel{
+
+ private ZooModel<Image, TableStructureResult> model;
+
+ private GenericObjectPool<Predictor<Image, TableStructureResult>> predictorPool;
+
+ @Override
+ public void loadModel(TableStructureConfig config) {
+ if(StringUtils.isBlank(config.getModelPath())){
+ throw new OcrException("modelPath is null");
+ }
+ Criteria<Image, TableStructureResult> criteria = StructureCriteriaFactory.createCriteria(config);
+ try{
+ model = ModelZoo.loadModel(criteria);
+ // 鍒涘缓姹犲瓙锛氭瘡涓嚎绋嬬嫭浜� Predictor
+ this.predictorPool = new GenericObjectPool<>(new PredictorFactory<>(model));
+ int predictorPoolSize = config.getPredictorPoolSize();
+ if(config.getPredictorPoolSize() <= 0){
+ predictorPoolSize = Runtime.getRuntime().availableProcessors(); // 榛樿绛変簬CPU鏍稿績鏁�
+ }
+ predictorPool.setMaxTotal(predictorPoolSize);
+ log.debug("褰撳墠璁惧: " + model.getNDManager().getDevice());
+ log.debug("褰撳墠寮曟搸: " + Engine.getInstance().getEngineName());
+ log.debug("妯″瀷鎺ㄧ悊鍣ㄧ嚎绋嬫睜鏈�澶ф暟閲�: " + predictorPoolSize);
+ } catch (IOException | ModelNotFoundException | MalformedModelException e) {
+ throw new OcrException("琛ㄦ牸缁撴瀯璇嗗埆妯″瀷鍔犺浇澶辫触", e);
+ }
+ }
+
+ @Override
+ public R<TableStructureResult> detect(BufferedImage image) {
+ if(!ImageUtils.isImageValid(image)){
+ return R.fail(R.Status.INVALID_IMAGE);
+ }
+ Image img = null;
+ try {
+ img = ImageFactory.getInstance().fromImage(OpenCVUtils.image2Mat(image));
+ return detect(img);
+ } catch (Exception e) {
+ throw new OcrException(e);
+ } finally {
+ if(Objects.nonNull(img)){
+ ((Mat)img.getWrappedImage()).release();
+ }
+ }
+ }
+
+ @Override
+ public R<TableStructureResult> detect(String imagePath) {
+ if(!FileUtils.isFileExists(imagePath)){
+ return R.fail(R.Status.FILE_NOT_FOUND);
+ }
+ Image img = null;
+ try {
+ img = ImageFactory.getInstance().fromFile(Paths.get(imagePath));
+ return detect(img);
+ } catch (IOException e) {
+ throw new OcrException("鏃犳晥鐨勫浘鐗�", e);
+ } finally {
+ if (Objects.nonNull(img)){
+ ((Mat)img.getWrappedImage()).release();
+ }
+ }
+ }
+
+ @Override
+ public R<TableStructureResult> detect(byte[] imageData) {
+ if(Objects.isNull(imageData)){
+ return R.fail(R.Status.INVALID_IMAGE);
+ }
+ try {
+ BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageData));
+ return detect(image);
+ } catch (IOException e) {
+ throw new OcrException("閿欒鐨勫浘鍍�", e);
+ }
+ }
+
+ @Override
+ public R<TableStructureResult> detect(Image image) {
+ Predictor<Image, TableStructureResult> predictor = null;
+ try {
+ predictor = predictorPool.borrowObject();
+ TableStructureResult result = predictor.predict(image);
+ return R.ok(result);
+ } catch (Exception e) {
+ throw new OcrException("OCR妫�娴嬮敊璇�", e);
+ }finally {
+ if (predictor != null) {
+ try {
+ predictorPool.returnObject(predictor); //褰掕繕
+ } catch (Exception e) {
+ log.warn("褰掕繕Predictor澶辫触", e);
+ try {
+ predictor.close(); // 褰掕繕澶辫触鎵嶉攢姣�
+ } catch (Exception ex) {
+ log.error("鍏抽棴Predictor澶辫触", ex);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public GenericObjectPool<Predictor<Image, TableStructureResult>> getPool() {
+ return predictorPool;
+ }
+
+ @Override
+ public void close() throws Exception {
+ try {
+ if (predictorPool != null) {
+ predictorPool.close();
+ }
+ } catch (Exception e) {
+ log.warn("鍏抽棴 predictorPool 澶辫触", e);
+ }
+ try {
+ if (model != null) {
+ model.close();
+ }
+ } catch (Exception e) {
+ log.warn("鍏抽棴 model 澶辫触", e);
+ }
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/table/TableRecognizer.java b/src/main/java/com/xindao/ocr/smartjavaai/model/table/TableRecognizer.java
new file mode 100644
index 0000000..b43bad9
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/table/TableRecognizer.java
@@ -0,0 +1,485 @@
+package com.xindao.ocr.smartjavaai.model.table;
+
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.ImageFactory;
+import cn.smartjavaai.common.entity.DetectionRectangle;
+import cn.smartjavaai.common.entity.R;
+import cn.smartjavaai.common.utils.FileUtils;
+import cn.smartjavaai.common.utils.ImageUtils;
+import cn.smartjavaai.common.utils.OpenCVUtils;
+import com.xindao.ocr.smartjavaai.config.OcrRecOptions;
+import com.xindao.ocr.smartjavaai.entity.OcrBox;
+import com.xindao.ocr.smartjavaai.entity.OcrInfo;
+import com.xindao.ocr.smartjavaai.entity.OcrItem;
+import com.xindao.ocr.smartjavaai.entity.TableStructureResult;
+import com.xindao.ocr.smartjavaai.exception.OcrException;
+import com.xindao.ocr.smartjavaai.model.common.detect.OcrCommonDetModel;
+import com.xindao.ocr.smartjavaai.model.common.direction.OcrDirectionModel;
+import com.xindao.ocr.smartjavaai.model.common.recognize.OcrCommonRecModel;
+import com.xindao.ocr.smartjavaai.utils.ConvertHtml2Excel;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.opencv.core.Mat;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Paths;
+import java.util.*;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 琛ㄦ牸鍐呭璇嗗埆鍣�
+ * @author dwj
+ */
+@Slf4j
+public class TableRecognizer {
+
+ private OcrCommonDetModel textDetector;
+ private TableStructureModel tableStructureModel;
+ private OcrCommonRecModel textRecModel;
+ private OcrDirectionModel directionModel;
+
+ private TableRecognizer(Builder builder) {
+ this.tableStructureModel = builder.tableStructureModel;
+ this.textRecModel = builder.textRecModel;
+ this.directionModel = builder.directionModel;
+ this.textDetector = builder.textDetector;
+ textRecModel.setTextDetModel(textDetector);
+ textRecModel.setDirectionModel(directionModel);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ // 閾惧紡璁剧疆鏂囨湰璇嗗埆妯″瀷
+ public TableRecognizer withTextRecModel(OcrCommonRecModel textRecModel) {
+ this.textRecModel = textRecModel;
+ return this;
+ }
+
+ // 閾惧紡璁剧疆琛ㄦ牸缁撴瀯妯″瀷
+ public TableRecognizer withStructureModel(TableStructureModel tableStructureModel) {
+ this.tableStructureModel = tableStructureModel;
+ return this;
+ }
+
+ /**
+ * 琛ㄦ牸璇嗗埆
+ * @param image
+ * @return
+ */
+ public R<TableStructureResult> recognize(Image image) {
+ //琛ㄦ牸缁撴瀯璇嗗埆
+ R<TableStructureResult> result = tableStructureModel.detect(image);
+ if(!result.isSuccess()){
+ return R.fail(result.getCode(), result.getMessage());
+ }
+ //鏂囨湰妫�娴�+鏂囧瓧璇嗗埆
+ boolean enableDirectionCorrect = directionModel == null ? false : true;
+ OcrRecOptions options = new OcrRecOptions(enableDirectionCorrect, false);
+ OcrInfo ocrInfo = textRecModel.recognize(image, options);
+ List<String> tableContentList = buildTable(result.getData(), ocrInfo);
+ String html = convertHtml(result.getData().getTableTagList(), tableContentList);
+ result.getData().setHtml(html);
+ return result;
+ }
+
+
+ /**
+ * 琛ㄦ牸璇嗗埆
+ * @param image
+ * @return
+ */
+ public R<TableStructureResult> recognize(BufferedImage image) {
+ if(!ImageUtils.isImageValid(image)){
+ return R.fail(R.Status.INVALID_IMAGE);
+ }
+ Image img = null;
+ try {
+ img = ImageFactory.getInstance().fromImage(OpenCVUtils.image2Mat(image));
+ return recognize(img);
+ } catch (Exception e) {
+ throw new OcrException(e);
+ } finally {
+ if(Objects.nonNull(img)){
+ ((Mat)img.getWrappedImage()).release();
+ }
+ }
+ }
+
+ /**
+ * 琛ㄦ牸璇嗗埆
+ * @param imagePath
+ * @return
+ */
+ public R<TableStructureResult> recognize(String imagePath) {
+ if(!FileUtils.isFileExists(imagePath)){
+ return R.fail(R.Status.FILE_NOT_FOUND);
+ }
+ Image img = null;
+ try {
+ img = ImageFactory.getInstance().fromFile(Paths.get(imagePath));
+ return recognize(img);
+ } catch (IOException e) {
+ throw new OcrException("鏃犳晥鐨勫浘鐗�", e);
+ } finally {
+ if (Objects.nonNull(img)){
+ ((Mat)img.getWrappedImage()).release();
+ }
+ }
+ }
+
+
+ /**
+ * 琛ㄦ牸璇嗗埆
+ * @param imageData
+ * @return
+ */
+ public R<TableStructureResult> recognize(byte[] imageData) {
+ if(Objects.isNull(imageData)){
+ return R.fail(R.Status.INVALID_IMAGE);
+ }
+ try {
+ BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageData));
+ return recognize(image);
+ } catch (IOException e) {
+ throw new OcrException("閿欒鐨勫浘鍍�", e);
+ }
+ }
+
+ /**
+ * 缁樺埗琛ㄦ牸
+ * @param tableStructureResult
+ * @param image
+ * @param savePath
+ */
+ public void drawTable(TableStructureResult tableStructureResult, BufferedImage image, String savePath){
+ if(Objects.isNull(tableStructureResult) || CollectionUtils.isEmpty(tableStructureResult.getTableTagList())){
+ throw new OcrException("琛ㄦ牸缁撴瀯涓虹┖");
+ }
+ for (int i = 0; i < tableStructureResult.getOcrItemList().size(); i++){
+ OcrItem item = tableStructureResult.getOcrItemList().get(i);
+ DetectionRectangle detectionRectangle = item.getOcrBox().toDetectionRectangle();
+ ImageUtils.drawImageRectWithText(image, detectionRectangle, i + "", Color.RED);
+ }
+ ImageUtils.saveImage(image, savePath);
+ }
+
+
+ /**
+ * 缁樺埗琛ㄦ牸
+ * @param tableStructureResult
+ * @param image
+ * @return
+ */
+ public BufferedImage drawTable(TableStructureResult tableStructureResult, BufferedImage image){
+ if(Objects.isNull(tableStructureResult) || CollectionUtils.isEmpty(tableStructureResult.getTableTagList())){
+ throw new OcrException("琛ㄦ牸缁撴瀯涓虹┖");
+ }
+ for (int i = 0; i < tableStructureResult.getOcrItemList().size(); i++){
+ OcrItem item = tableStructureResult.getOcrItemList().get(i);
+ DetectionRectangle detectionRectangle = item.getOcrBox().toDetectionRectangle();
+ ImageUtils.drawImageRectWithText(image, detectionRectangle, i + "", Color.RED);
+ }
+ return image;
+ }
+
+ /**
+ * 鍒犻櫎 HTML 涓涓�涓� <style> ... </style> 娈佃惤
+ * @param html 鍘熷 HTML
+ * @return 鍘绘帀 <style> 鐨� HTML
+ */
+ public static String removeStyleBlock(String html) {
+ String lowerHtml = html.toLowerCase();
+ int styleStart = lowerHtml.indexOf("<style");
+ if (styleStart == -1) {
+ return html; // 娌℃湁 style锛岃繑鍥炲師鏂�
+ }
+ int styleEnd = lowerHtml.indexOf("</style>", styleStart);
+ if (styleEnd == -1) {
+ return html; // 娌¢棴鍚堟爣绛撅紝涓嶅鐞�
+ }
+ styleEnd += "</style>".length();
+ // 鍘绘帀 style 鍧�
+ return html.substring(0, styleStart) + html.substring(styleEnd);
+ }
+
+
+ /**
+ * 瀵煎嚭 Excel
+ * @param html
+ * @param out
+ */
+ public void exportExcel(String html, OutputStream out){
+ String content = removeStyleBlock(html);
+ content = content.replace("<html><body>", "");
+ content = content.replace("</body></html>", "");
+ try (HSSFWorkbook workbook = ConvertHtml2Excel.table2Excel(content)){
+ workbook.write(out);
+ out.flush();
+ } catch (Exception e) {
+ throw new OcrException("瀵煎嚭excel澶辫触锛岃妫�鏌ヨ〃缁撴瀯鏄惁璇嗗埆姝g‘");
+ }
+ }
+
+ /**
+ * 瀵煎嚭 Excel
+ * @param html
+ * @param savePath
+ */
+ public void exportExcel(String html, String savePath){
+ String content = removeStyleBlock(html);
+ content = content.replace("<html><body>", "");
+ content = content.replace("</body></html>", "");
+ try (HSSFWorkbook workbook = ConvertHtml2Excel.table2Excel(content)){
+ workbook.write(new File(savePath));
+ } catch (Exception e) {
+ throw new OcrException("瀵煎嚭excel澶辫触锛岃妫�鏌ヨ〃缁撴瀯鏄惁璇嗗埆姝g‘");
+ }
+ }
+
+
+ /**
+ * 鏋勫缓琛ㄦ牸
+ * @param tableStructureResult
+ * @param ocrInfo
+ * @return
+ */
+ public List<String> buildTable(TableStructureResult tableStructureResult, OcrInfo ocrInfo) {
+ // 鑾峰彇 Cell 涓� 鏂囨湰妫�娴嬫 鐨勫搴斿叧绯�(1:N)銆�
+ Map<Integer, List<Integer>> matched = new ConcurrentHashMap<>();
+ List<OcrItem> ocrItems = ocrInfo.getOcrItemList();
+
+ for (int i = 0; i < ocrItems.size(); i++) {
+ OcrBox ocrBox = ocrItems.get(i).getOcrBox();
+ int[] box_1 = {
+ (int)ocrBox.getTopLeft().getX(),
+ (int)ocrBox.getTopLeft().getY(),
+ (int)ocrBox.getBottomRight().getX(),
+ (int)ocrBox.getBottomRight().getY()
+ };
+ // 鑾峰彇涓や袱cell涔嬮棿鐨凩1璺濈鍜� 1- IOU
+ List<Pair<Float, Float>> distances = new ArrayList<>();
+ for (OcrItem cell : tableStructureResult.getOcrItemList()) {
+ OcrBox cellBox = cell.getOcrBox();
+ int[] box_2 = {
+ (int)cellBox.getTopLeft().getX(),
+ (int)cellBox.getTopLeft().getY(),
+ (int)cellBox.getBottomRight().getX(),
+ (int)cellBox.getBottomRight().getY()
+ };
+ float distance = distance(box_1, box_2);
+ float iou = 1 - computeIou(box_1, box_2);
+ distances.add(Pair.of(distance, iou));
+ }
+ // 鏍规嵁璺濈鍜孖OU鎸戦�夋渶"杩�"鐨刢ell
+ Pair<Float, Float> nearest = sorted(distances);
+
+ // 鑾峰彇鏈�灏忚窛绂诲搴旂殑涓嬫爣id锛屼篃绛変环浜巆ell鐨勪笅鏍噄d 锛坉istances鍒楄〃鏄牴鎹亶鍘哻ells鐢熸垚鐨勶級
+ int id = 0;
+ for (int idx = 0; idx < distances.size(); idx++) {
+ Pair<Float, Float> current = distances.get(idx);
+ if (current.getLeft().floatValue() == nearest.getLeft().floatValue()
+ && current.getRight().floatValue() == nearest.getRight().floatValue()) {
+ id = idx;
+ break;
+ }
+ }
+ if (!matched.containsKey(id)) {
+ List<Integer> textIds = new ArrayList<>();
+ textIds.add(i);
+ // cell id, text id list (dt_boxes index list)
+ matched.put(id, textIds);
+ } else {
+ matched.get(id).add(i);
+ }
+ }
+
+ List<String> cell_contents = new ArrayList<>();
+ List<Double> probs = new ArrayList<>();
+ for (int i = 0; i < tableStructureResult.getOcrItemList().size(); i++) {
+ List<Integer> textIds = matched.get(i);
+ List<String> contents = new ArrayList<>();
+ String content = "";
+ if (textIds != null) {
+ for (Integer id : textIds) {
+ contents.add(ocrItems.get(id).getText());
+ }
+ content = StringUtils.join(contents, " ");
+ }
+ cell_contents.add(content);
+ probs.add(-1.0);
+ }
+ return cell_contents;
+ }
+
+ /**
+ * 璁$畻娆у紡璺濈
+ * Calculate L1 distance
+ *
+ * @param box_1
+ * @param box_2
+ * @return
+ */
+ private int distance(int[] box_1, int[] box_2) {
+ int x1 = box_1[0];
+ int y1 = box_1[1];
+ int x2 = box_1[2];
+ int y2 = box_1[3];
+ int x3 = box_2[0];
+ int y3 = box_2[1];
+ int x4 = box_2[2];
+ int y4 = box_2[3];
+ int dis = Math.abs(x3 - x1) + Math.abs(y3 - y1) + Math.abs(x4 - x2) + Math.abs(y4 - y2);
+ int dis_2 = Math.abs(x3 - x1) + Math.abs(y3 - y1);
+ int dis_3 = Math.abs(x4 - x2) + Math.abs(y4 - y2);
+ return dis + Math.min(dis_2, dis_3);
+ }
+
+ /**
+ * 璁$畻浜ゅ苟姣�
+ * computing IoU
+ *
+ * @param rec1: (y0, x0, y1, x1), which reflects (top, left, bottom, right)
+ * @param rec2: (y0, x0, y1, x1)
+ * @return scala value of IoU
+ */
+ private float computeIou(int[] rec1, int[] rec2) {
+ // computing area of each rectangles
+ int S_rec1 = (rec1[2] - rec1[0]) * (rec1[3] - rec1[1]);
+ int S_rec2 = (rec2[2] - rec2[0]) * (rec2[3] - rec2[1]);
+
+ // computing the sum_area
+ int sum_area = S_rec1 + S_rec2;
+
+ // find the each edge of intersect rectangle
+ int left_line = Math.max(rec1[1], rec2[1]);
+ int right_line = Math.min(rec1[3], rec2[3]);
+ int top_line = Math.max(rec1[0], rec2[0]);
+ int bottom_line = Math.min(rec1[2], rec2[2]);
+
+ // judge if there is an intersect
+ if (left_line >= right_line || top_line >= bottom_line) {
+ return 0.0f;
+ } else {
+ float intersect = (right_line - left_line) * (bottom_line - top_line);
+ return (intersect / (sum_area - intersect)) * 1.0f;
+ }
+ }
+
+ /**
+ * 璺濈鎺掑簭
+ * Distance sorted
+ *
+ * @param distances
+ * @return
+ */
+ private Pair<Float, Float> sorted(List<Pair<Float, Float>> distances) {
+ Comparator<Pair<Float, Float>> comparator =
+ new Comparator<Pair<Float, Float>>() {
+ @Override
+ public int compare(Pair<Float, Float> a1, Pair<Float, Float> a2) {
+ // 棣栧厛鏍规嵁IoU鎺掑簭
+ if (a1.getRight().floatValue() > a2.getRight().floatValue()) {
+ return 1;
+ } else if (a1.getRight().floatValue() == a2.getRight().floatValue()) {
+ // 鐒跺悗鏍规嵁L1璺濈鎺掑簭
+ if (a1.getLeft().floatValue() > a2.getLeft().floatValue()) {
+ return 1;
+ }
+ return -1;
+ }
+ return -1;
+ }
+ };
+
+ // 璺濈鎺掑簭
+ List<Pair<Float, Float>> newDistances = new ArrayList<>();
+ CollectionUtils.addAll(newDistances, new Object[distances.size()]);
+ Collections.copy(newDistances, distances);
+ Collections.sort(newDistances, comparator);
+ return newDistances.get(0);
+ }
+
+ /**
+ * 鐢熸垚琛ㄦ牸html
+ * Generate table html
+ *
+ * @param pred_structures
+ * @param cell_contents
+ * @return
+ */
+ public String convertHtml(List<String> pred_structures, List<String> cell_contents) {
+ StringBuffer html = new StringBuffer();
+ // 娣诲姞缁熶竴鐨勬牱寮忥紙鍙�夋斁鍒�<head>涓級
+ html.append("<style>\n");
+ html.append("table { border-collapse: collapse; }\n");
+ html.append("td, th, table { border: 1px solid black; padding: 5px; }\n");
+ html.append("</style>\n");
+ int td_index = 0;
+ for (String tag : pred_structures) {
+ if (tag.contains("<td></td>")) {
+ String content = cell_contents.get(td_index);
+ html.append("<td>");
+ html.append(content);
+ html.append("</td>");
+ td_index++;
+ continue;
+ }
+ html.append(tag);
+ }
+ return html.toString();
+ }
+
+
+ public static class Builder {
+ private TableStructureModel tableStructureModel;
+ private OcrCommonRecModel textRecModel;
+ private OcrDirectionModel directionModel;
+ private OcrCommonDetModel textDetector;
+
+ public Builder withStructureModel(TableStructureModel model) {
+ this.tableStructureModel = model;
+ return this;
+ }
+
+ public Builder withTextRecModel(OcrCommonRecModel model) {
+ this.textRecModel = model;
+ return this;
+ }
+
+ public Builder withDirectionModel(OcrDirectionModel model) {
+ this.directionModel = model;
+ return this;
+ }
+
+ public Builder withTextDetModel(OcrCommonDetModel model) {
+ this.textDetector = model;
+ return this;
+ }
+
+ public TableRecognizer build() {
+ if (this.tableStructureModel == null) {
+ throw new IllegalStateException("tableStructureModel 鏈缃�");
+ }
+ if (this.textDetector == null) {
+ throw new IllegalStateException("textDetector 鏈缃�");
+ }
+ if (this.textRecModel == null) {
+ throw new IllegalStateException("textRecModel 鏈缃�");
+ }
+ return new TableRecognizer(this);
+ }
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/table/TableStructureModel.java b/src/main/java/com/xindao/ocr/smartjavaai/model/table/TableStructureModel.java
new file mode 100644
index 0000000..99b2c53
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/table/TableStructureModel.java
@@ -0,0 +1,65 @@
+package com.xindao.ocr.smartjavaai.model.table;
+
+import ai.djl.inference.Predictor;
+import ai.djl.modality.cv.Image;
+import cn.smartjavaai.common.entity.R;
+import com.xindao.ocr.smartjavaai.config.TableStructureConfig;
+import com.xindao.ocr.smartjavaai.entity.TableStructureResult;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+
+import java.awt.image.BufferedImage;
+
+/**
+ * 琛ㄦ牸缁撴瀯璇嗗埆妯″瀷
+ * @author dwj
+ */
+public interface TableStructureModel extends AutoCloseable{
+
+ /**
+ * 鍔犺浇妯″瀷
+ * @param config
+ */
+ void loadModel(TableStructureConfig config);
+
+
+ /**
+ * 琛ㄦ牸缁撴瀯妫�娴�
+ * @param image
+ * @return
+ */
+ default R<TableStructureResult> detect(BufferedImage image){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 琛ㄦ牸缁撴瀯妫�娴�
+ * @param imagePath 鍥剧墖璺緞
+ * @return
+ */
+ default R<TableStructureResult> detect(String imagePath) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ /**
+ * 琛ㄦ牸缁撴瀯妫�娴�
+ * @param imageData 鍥剧墖瀛楄妭鏁扮粍
+ * @return
+ */
+ default R<TableStructureResult> detect(byte[] imageData) {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+
+ /**
+ * 琛ㄦ牸缁撴瀯妫�娴�
+ * @param image DJL Image
+ * @return
+ */
+ default R<TableStructureResult> detect(Image image){
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+
+ default GenericObjectPool<Predictor<Image, TableStructureResult>> getPool() {
+ throw new UnsupportedOperationException("榛樿涓嶆敮鎸佽鍔熻兘");
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/table/criteria/StructureCriteriaFactory.java b/src/main/java/com/xindao/ocr/smartjavaai/model/table/criteria/StructureCriteriaFactory.java
new file mode 100644
index 0000000..cf48fb0
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/table/criteria/StructureCriteriaFactory.java
@@ -0,0 +1,56 @@
+package com.xindao.ocr.smartjavaai.model.table.criteria;
+
+import ai.djl.Device;
+import ai.djl.modality.cv.Image;
+import ai.djl.repository.zoo.Criteria;
+import ai.djl.training.util.ProgressBar;
+import cn.smartjavaai.common.enums.DeviceEnum;
+import com.xindao.ocr.smartjavaai.config.TableStructureConfig;
+import com.xindao.ocr.smartjavaai.entity.TableStructureResult;
+import com.xindao.ocr.smartjavaai.enums.TableStructureModelEnum;
+import com.xindao.ocr.smartjavaai.model.table.translator.TableStructTranslator;
+
+import java.nio.file.Paths;
+import java.util.Objects;
+
+/**
+ * @author dwj
+ * @date 2025/7/10
+ */
+public class StructureCriteriaFactory {
+
+
+ public static Criteria<Image, TableStructureResult> createCriteria(TableStructureConfig config) {
+ Device device = null;
+ if(!Objects.isNull(config.getDevice())){
+ device = config.getDevice() == DeviceEnum.CPU ? Device.cpu() : Device.gpu(config.getGpuId());
+ }
+ Criteria<Image, TableStructureResult> criteria = null;
+ if(config.getModelEnum() == TableStructureModelEnum.SLANET){
+ criteria =
+ Criteria.builder()
+ .optEngine("OnnxRuntime")
+ .setTypes(Image.class, TableStructureResult.class)
+ .optModelPath(Paths.get(config.getModelPath()))
+ .optOption("removePass", "repeated_fc_relu_fuse_pass")
+ .optDevice(device)
+ .optTranslator(new TableStructTranslator())
+ .optProgress(new ProgressBar())
+ .build();
+ }else if(config.getModelEnum() == TableStructureModelEnum.SLANET_PLUS){
+ criteria =
+ Criteria.builder()
+ .optEngine("OnnxRuntime")
+ .setTypes(Image.class, TableStructureResult.class)
+ .optModelPath(Paths.get(config.getModelPath()))
+ .optOption("removePass", "repeated_fc_relu_fuse_pass")
+ .optDevice(device)
+ .optTranslator(new TableStructTranslator())
+ .optProgress(new ProgressBar())
+ .build();
+ }
+ return criteria;
+ }
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/model/table/translator/TableStructTranslator.java b/src/main/java/com/xindao/ocr/smartjavaai/model/table/translator/TableStructTranslator.java
new file mode 100644
index 0000000..f822df8
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/model/table/translator/TableStructTranslator.java
@@ -0,0 +1,191 @@
+package com.xindao.ocr.smartjavaai.model.table.translator;
+
+import ai.djl.Model;
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.util.NDImageUtils;
+import ai.djl.ndarray.NDArray;
+import ai.djl.ndarray.NDList;
+import ai.djl.ndarray.index.NDIndex;
+import ai.djl.ndarray.types.DataType;
+import ai.djl.ndarray.types.Shape;
+import ai.djl.translate.Batchifier;
+import ai.djl.translate.Translator;
+import ai.djl.translate.TranslatorContext;
+import ai.djl.util.Utils;
+import cn.smartjavaai.common.entity.Point;
+import com.xindao.ocr.smartjavaai.entity.OcrBox;
+import com.xindao.ocr.smartjavaai.entity.OcrItem;
+import com.xindao.ocr.smartjavaai.entity.TableStructureResult;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 琛ㄦ牸璇嗗埆鐨勫墠鍚庡鐞�
+ */
+public class TableStructTranslator implements Translator<Image, TableStructureResult> {
+
+ private final int maxLength = 488;
+ private int height;
+ private int width;
+ private float scale = 1.0f;
+ private float xScale;
+ private float yScale;
+ private List<String> dict;
+ private String beg_str = "sos";
+ private String end_str = "eos";
+ private List<String> td_token = new ArrayList<>();
+
+ @Override
+ public void prepare(TranslatorContext ctx) throws IOException {
+ Model model = ctx.getModel();
+ try (InputStream is = model.getArtifact("table_structure_dict_ch.txt").openStream()) {
+ dict = Utils.readLines(is, false);
+ dict.add(0,beg_str);
+ if(dict.contains("<td>"))
+ dict.remove("<td>");
+ if(!dict.contains("<td></td>"))
+ dict.add("<td></td>");
+ dict.add(end_str);
+ }
+
+ td_token.add("<td>");
+ td_token.add("<td");
+ td_token.add("<td></td>");
+ }
+
+ @Override
+ public NDList processInput(TranslatorContext ctx, Image input) {
+ NDArray img = input.toNDArray(ctx.getNDManager(), Image.Flag.COLOR);
+ height = input.getHeight();
+ width = input.getWidth();
+
+ img = ResizeTableImage(img, height, width, maxLength);
+ img = PaddingTableImage(ctx, img, maxLength);
+
+ img = img.transpose(2, 0, 1).div(255).flip(0);
+ img = NDImageUtils.normalize(
+ img, new float[]{0.485f, 0.456f, 0.406f}, new float[]{0.229f, 0.224f, 0.225f});
+ img = img.expandDims(0);
+ return new NDList(img);
+ }
+
+ @Override
+ public TableStructureResult processOutput(TranslatorContext ctx, NDList list) {
+ NDArray bbox_preds = list.get(0);
+ NDArray structure_probs = list.get(1);
+
+ NDArray structure_idx = structure_probs.argMax(2);
+ structure_probs = structure_probs.max(new int[]{2});
+
+ List<List<String>> structure_batch_list = new ArrayList<>();
+ List<List<NDArray>> bbox_batch_list = new ArrayList<>();
+ List<List<NDArray>> result_score_list = new ArrayList<>();
+
+ // get ignored tokens
+ int beg_idx = dict.indexOf(beg_str);
+ int end_idx = dict.indexOf(end_str);
+
+ long batch_size = structure_idx.size(0);
+ for (int batch_idx = 0; batch_idx < batch_size; batch_idx++) {
+ List<String> structure_list = new ArrayList<>();
+ List<NDArray> bbox_list = new ArrayList<>();
+ List<NDArray> score_list = new ArrayList<>();
+
+ long len = structure_idx.get(batch_idx).size();
+ for (int idx = 0; idx < len; idx++) {
+ int char_idx = (int) structure_idx.get(batch_idx).get(idx).toLongArray()[0];
+ if (idx > 0 && char_idx == end_idx) {
+ break;
+ }
+// if (char_idx == beg_idx || char_idx == end_idx) {
+// continue;
+// }
+ String text = dict.get(char_idx);
+ if(td_token.indexOf(text)>-1){
+ NDArray bbox = bbox_preds.get(batch_idx, idx);
+// bbox.set(new NDIndex("0::2"), bbox.get(new NDIndex("0::2")));
+// bbox.set(new NDIndex("1::2"), bbox.get(new NDIndex("1::2")));
+ bbox_list.add(bbox);
+ }
+ structure_list.add(text);
+ score_list.add(structure_probs.get(batch_idx, idx));
+ }
+
+ structure_batch_list.add(structure_list); // structure_str
+ bbox_batch_list.add(bbox_list);
+ result_score_list.add(score_list);
+ }
+ List<String> structure_str_list =structure_batch_list.get(0);
+ List<NDArray> bbox_list = bbox_batch_list.get(0);
+ List<NDArray> score_list = result_score_list.get(0);
+
+ structure_str_list.add(0,"<html>");
+ structure_str_list.add(1,"<body>");
+ structure_str_list.add(2,"<table>");
+ structure_str_list.add("</table>");
+ structure_str_list.add("</body>");
+ structure_str_list.add("</html>");
+
+ List<OcrItem> ocrItemList = new ArrayList<>();
+
+ for (int i = 0; i < bbox_list.size(); i++) {
+ NDArray box = bbox_list.get(i);
+ float[] arr = new float[4];
+ arr[0] = box.get(new NDIndex("0::2")).min().toFloatArray()[0];
+ arr[1] = box.get(new NDIndex("1::2")).min().toFloatArray()[0];
+ arr[2] = box.get(new NDIndex("0::2")).max().toFloatArray()[0];
+ arr[3] = box.get(new NDIndex("1::2")).max().toFloatArray()[0];
+
+ Point topLeft = new Point(arr[0] * xScale * width, arr[1] * yScale * height);
+ Point topRight = new Point(arr[2] * xScale * width, arr[1] * yScale * height);
+ Point bottomRight = new Point(arr[2] * xScale * width, arr[3] * yScale * height);
+ Point bottomLeft = new Point(arr[0] * xScale * width, arr[3] * yScale * height);
+
+
+ OcrBox ocrBox = new OcrBox(topLeft, topRight, bottomRight, bottomLeft);
+ //String tag = structure_str_list.get(i + 3); // 鍓嶉潰鍔犱簡<html><body><table> 鎵�浠ュ亸绉�+3
+ float score = score_list.get(i).toFloatArray()[0]; // 鑾峰彇姣忎釜缁撴瀯token鐨勫緱鍒�
+ OcrItem item = new OcrItem();
+ item.setOcrBox(ocrBox);
+ item.setScore(score);
+ //item.setTableTag(tag);
+ ocrItemList.add(item);
+ }
+ return new TableStructureResult(ocrItemList, structure_str_list);
+ }
+
+ @Override
+ public Batchifier getBatchifier() {
+ return null;
+ }
+
+ private NDArray ResizeTableImage(NDArray img, int height, int width, int maxLen) {
+ int localMax = Math.max(height, width);
+ float ratio = maxLen * 1.0f / localMax;
+ int resize_h = (int) (height * ratio);
+ int resize_w = (int) (width * ratio);
+ scale = ratio;
+
+ if(width > height){
+ xScale = 1f;
+ yScale = (float)width /(float)height;
+ } else{
+ xScale = (float)height /(float)width;
+ yScale = 1f;
+ }
+
+ img = NDImageUtils.resize(img, resize_w, resize_h);
+ return img;
+ }
+
+ private NDArray PaddingTableImage(TranslatorContext ctx, NDArray img, int maxLen) {
+ NDArray paddingImg = ctx.getNDManager().zeros(new Shape(maxLen, maxLen, 3), DataType.UINT8);
+ paddingImg.set(
+ new NDIndex("0:" + img.getShape().get(0) + ",0:" + img.getShape().get(1) + ",:"), img);
+ return paddingImg;
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/opencv/OcrNDArrayUtils.java b/src/main/java/com/xindao/ocr/smartjavaai/opencv/OcrNDArrayUtils.java
new file mode 100644
index 0000000..dd51ed7
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/opencv/OcrNDArrayUtils.java
@@ -0,0 +1,228 @@
+package com.xindao.ocr.smartjavaai.opencv;
+
+import ai.djl.ndarray.NDArray;
+import org.opencv.core.CvType;
+import org.opencv.core.Mat;
+import org.opencv.core.MatOfPoint;
+import org.opencv.core.Point;
+
+import java.util.ArrayList;
+import java.util.List;
+/**
+ * NDArray Utils
+ *
+ */
+public class OcrNDArrayUtils {
+ /**
+ * Mat To MatOfPoint
+ * @param mat
+ * @return
+ */
+ public static MatOfPoint matToMatOfPoint(Mat mat) {
+ int rows = mat.rows();
+ MatOfPoint matOfPoint = new MatOfPoint();
+
+ List<Point> list = new ArrayList<>();
+ for (int i = 0; i < rows; i++) {
+ Point point = new Point((float) mat.get(i, 0)[0], (float) mat.get(i, 1)[0]);
+ list.add(point);
+ }
+ matOfPoint.fromList(list);
+
+ return matOfPoint;
+ }
+
+ /**
+ * float NDArray To float[][] Array
+ * @param ndArray
+ * @return
+ */
+ public static float[][] floatNDArrayToArray(NDArray ndArray) {
+ int rows = (int) (ndArray.getShape().get(0));
+ int cols = (int) (ndArray.getShape().get(1));
+ float[][] arr = new float[rows][cols];
+
+ float[] arrs = ndArray.toFloatArray();
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ arr[i][j] = arrs[i * cols + j];
+ }
+ }
+ return arr;
+ }
+
+ /**
+ * Mat To double[][] Array
+ * @param mat
+ * @return
+ */
+ public static double[][] matToDoubleArray(Mat mat) {
+ int rows = mat.rows();
+ int cols = mat.cols();
+
+ double[][] doubles = new double[rows][cols];
+
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ doubles[i][j] = mat.get(i, j)[0];
+ }
+ }
+
+ return doubles;
+ }
+
+ /**
+ * Mat To float[][] Array
+ * @param mat
+ * @return
+ */
+ public static float[][] matToFloatArray(Mat mat) {
+ int rows = mat.rows();
+ int cols = mat.cols();
+
+ float[][] floats = new float[rows][cols];
+
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ floats[i][j] = (float) mat.get(i, j)[0];
+ }
+ }
+
+ return floats;
+ }
+
+ /**
+ * Mat To byte[][] Array
+ * @param mat
+ * @return
+ */
+ public static byte[][] matToUint8Array(Mat mat) {
+ int rows = mat.rows();
+ int cols = mat.cols();
+
+ byte[][] bytes = new byte[rows][cols];
+
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ bytes[i][j] = (byte) mat.get(i, j)[0];
+ }
+ }
+
+ return bytes;
+ }
+
+ /**
+ * float NDArray To float[][] Array
+ * @param ndArray
+ * @param cvType
+ * @return
+ */
+ public static Mat floatNDArrayToMat(NDArray ndArray, int cvType) {
+ int rows = (int) (ndArray.getShape().get(0));
+ int cols = (int) (ndArray.getShape().get(1));
+ Mat mat = new Mat(rows, cols, cvType);
+
+ float[] arrs = ndArray.toFloatArray();
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ mat.put(i, j, arrs[i * cols + j]);
+ }
+ }
+ return mat;
+ }
+
+ /**
+ * float NDArray To Mat
+ * @param ndArray
+ * @return
+ */
+ public static Mat floatNDArrayToMat(NDArray ndArray) {
+ int rows = (int) (ndArray.getShape().get(0));
+ int cols = (int) (ndArray.getShape().get(1));
+ Mat mat = new Mat(rows, cols, CvType.CV_32F);
+
+ float[] arrs = ndArray.toFloatArray();
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ mat.put(i, j, arrs[i * cols + j]);
+ }
+ }
+
+ return mat;
+
+ }
+
+ /**
+ * uint8 NDArray To Mat
+ * @param ndArray
+ * @return
+ */
+ public static Mat uint8NDArrayToMat(NDArray ndArray) {
+ int rows = (int) (ndArray.getShape().get(0));
+ int cols = (int) (ndArray.getShape().get(1));
+ Mat mat = new Mat(rows, cols, CvType.CV_8U);
+
+ byte[] arrs = ndArray.toByteArray();
+
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ mat.put(i, j, arrs[i * cols + j]);
+ }
+ }
+ return mat;
+ }
+
+ /**
+ * float[][] Array To Mat
+ * @param arr
+ * @return
+ */
+ public static Mat floatArrayToMat(float[][] arr) {
+ int rows = arr.length;
+ int cols = arr[0].length;
+ Mat mat = new Mat(rows, cols, CvType.CV_32F);
+
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ mat.put(i, j, arr[i][j]);
+ }
+ }
+
+ return mat;
+ }
+
+ /**
+ * byte[][] Array To Mat
+ * @param arr
+ * @return
+ */
+ public static Mat uint8ArrayToMat(byte[][] arr) {
+ int rows = arr.length;
+ int cols = arr[0].length;
+ Mat mat = new Mat(rows, cols, CvType.CV_8U);
+
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ mat.put(i, j, arr[i][j]);
+ }
+ }
+
+ return mat;
+ }
+
+ /**
+ * List To Mat
+ * @param points
+ * @return
+ */
+ public static Mat toMat(List<ai.djl.modality.cv.output.Point> points) {
+ Mat mat = new Mat(points.size(), 2, CvType.CV_32F);
+ for (int i = 0; i < points.size(); i++) {
+ ai.djl.modality.cv.output.Point point = points.get(i);
+ mat.put(i, 0, (float) point.getX());
+ mat.put(i, 1, (float) point.getY());
+ }
+
+ return mat;
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/utils/ConvertHtml2Excel.java b/src/main/java/com/xindao/ocr/smartjavaai/utils/ConvertHtml2Excel.java
new file mode 100644
index 0000000..8933659
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/utils/ConvertHtml2Excel.java
@@ -0,0 +1,236 @@
+package com.xindao.ocr.smartjavaai.utils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.poi.hssf.usermodel.*;
+import org.apache.poi.ss.usermodel.BorderStyle;
+import org.apache.poi.ss.usermodel.CellType;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Auther: xiaoqiang
+ * @Date: 2020/12/9 9:16
+ * @Description:
+ */
+public class ConvertHtml2Excel {
+
+ /**
+ * html琛ㄦ牸杞琫xcel
+ *
+ * @param tableHtml 濡�
+ * <table>
+ * ..
+ * </table>
+ * @return
+ */
+ public static HSSFWorkbook table2Excel(String tableHtml) {
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFSheet sheet = wb.createSheet();
+ List<CrossRangeCellMeta> crossRowEleMetaLs = new ArrayList<>();
+ int rowIndex = 0;
+ try {
+ Document data = DocumentHelper.parseText(tableHtml);
+ // 鐢熸垚琛ㄥご
+ Element thead = data.getRootElement().element("thead");
+ HSSFCellStyle titleStyle = getTitleStyle(wb);
+ int ls=0;//鍒楁暟
+ if (thead != null) {
+ List<Element> trLs = thead.elements("tr");
+ for (Element trEle : trLs) {
+ HSSFRow row = sheet.createRow(rowIndex);
+ List<Element> thLs = trEle.elements("td");
+ ls=thLs.size();
+ makeRowCell(thLs, rowIndex, row, 0, titleStyle, crossRowEleMetaLs);
+ rowIndex++;
+ }
+ }
+ // 鐢熸垚琛ㄤ綋
+ Element tbody = data.getRootElement().element("tbody");
+ HSSFCellStyle contentStyle = getContentStyle(wb);
+ if (tbody != null) {
+ List<Element> trLs = tbody.elements("tr");
+ for (Element trEle : trLs) {
+ HSSFRow row = sheet.createRow(rowIndex);
+ List<Element> thLs = trEle.elements("th");
+ int cellIndex = makeRowCell(thLs, rowIndex, row, 0, titleStyle, crossRowEleMetaLs);
+ List<Element> tdLs = trEle.elements("td");
+ makeRowCell(tdLs, rowIndex, row, cellIndex, contentStyle, crossRowEleMetaLs);
+ rowIndex++;
+ }
+ }
+ // 鍚堝苟琛ㄥご
+ for (CrossRangeCellMeta crcm : crossRowEleMetaLs) {
+ sheet.addMergedRegion(new CellRangeAddress(crcm.getFirstRow(), crcm.getLastRow(), crcm.getFirstCol(), crcm.getLastCol()));
+ setRegionStyle(sheet, new CellRangeAddress(crcm.getFirstRow(), crcm.getLastRow(), crcm.getFirstCol(), crcm.getLastCol()),titleStyle);
+ }
+ for(int i=0;i<sheet.getRow(0).getPhysicalNumberOfCells();i++){
+ sheet.autoSizeColumn(i, true);//璁剧疆鍒楀
+ if(sheet.getColumnWidth(i)<255*256){
+ sheet.setColumnWidth(i, sheet.getColumnWidth(i) < 9000 ? 9000 : sheet.getColumnWidth(i));
+ }else{
+ sheet.setColumnWidth(i, 15000);
+ }
+ }
+ } catch (DocumentException e) {
+ e.printStackTrace();
+ }
+
+ return wb;
+ }
+
+ /**
+ * 鐢熶骇琛屽唴瀹�
+ *
+ * @return 鏈�鍚庝竴鍒楃殑cell index
+ */
+ /**
+ * @param tdLs th鎴栬�卼d闆嗗悎
+ * @param rowIndex 琛屽彿
+ * @param row POI琛屽璞�
+ * @param startCellIndex
+ * @param cellStyle 鏍峰紡
+ * @param crossRowEleMetaLs 璺ㄨ鍏冩暟鎹泦鍚�
+ * @return
+ */
+ private static int makeRowCell(List<Element> tdLs, int rowIndex, HSSFRow row, int startCellIndex, HSSFCellStyle cellStyle,
+ List<CrossRangeCellMeta> crossRowEleMetaLs) {
+ int i = startCellIndex;
+ for (int eleIndex = 0; eleIndex < tdLs.size(); i++, eleIndex++) {
+ int captureCellSize = getCaptureCellSize(rowIndex, i, crossRowEleMetaLs);
+ while (captureCellSize > 0) {
+ for (int j = 0; j < captureCellSize; j++) {// 褰撳墠琛岃法鍒楀鐞嗭紙琛ュ崟鍏冩牸锛�
+ row.createCell(i);
+ i++;
+ }
+ captureCellSize = getCaptureCellSize(rowIndex, i, crossRowEleMetaLs);
+ }
+ Element thEle = tdLs.get(eleIndex);
+ String val = thEle.getTextTrim();
+ if (StringUtils.isBlank(val)) {
+ Element e = thEle.element("a");
+ if (e != null) {
+ val = e.getTextTrim();
+ }
+ }
+ HSSFCell c = row.createCell(i);
+ if (NumberUtils.isNumber(val)) {
+ c.setCellValue(Double.parseDouble(val));
+ c.setCellType(CellType.NUMERIC);
+ } else {
+ c.setCellValue(val);
+ }
+ int rowSpan = NumberUtils.toInt(thEle.attributeValue("rowspan"), 1);
+ int colSpan = NumberUtils.toInt(thEle.attributeValue("colspan"), 1);
+ c.setCellStyle(cellStyle);
+ if (rowSpan > 1 || colSpan > 1) { // 瀛樺湪璺ㄨ鎴栬法鍒�
+ crossRowEleMetaLs.add(new CrossRangeCellMeta(rowIndex, i, rowSpan, colSpan));
+ }
+ if (colSpan > 1) {// 褰撳墠琛岃法鍒楀鐞嗭紙琛ュ崟鍏冩牸锛�
+ for (int j = 1; j < colSpan; j++) {
+ i++;
+ row.createCell(i);
+ }
+ }
+ }
+ return i;
+ }
+
+ /**
+ * 璁剧疆鍚堝苟鍗曞厓鏍肩殑杈规鏍峰紡
+ *
+ * @param sheet
+ * @param region
+ * @param cs
+ */
+ public static void setRegionStyle(HSSFSheet sheet, CellRangeAddress region, HSSFCellStyle cs) {
+ for (int i = region.getFirstRow(); i <= region.getLastRow(); i++) {
+ HSSFRow row = sheet.getRow(i);
+ for (int j = region.getFirstColumn(); j <= region.getLastColumn(); j++) {
+ HSSFCell cell = row.getCell(j);
+ cell.setCellStyle(cs);
+ }
+ }
+ }
+
+ /**
+ * 鑾峰緱鍥爎owSpan鍗犳嵁鐨勫崟鍏冩牸
+ *
+ * @param rowIndex 琛屽彿
+ * @param colIndex 鍒楀彿
+ * @param crossRowEleMetaLs 璺ㄨ鍒楀厓鏁版嵁
+ * @return 褰撳墠琛屽湪鏌愬垪闇�瑕佸崰鎹崟鍏冩牸
+ */
+ private static int getCaptureCellSize(int rowIndex, int colIndex, List<CrossRangeCellMeta> crossRowEleMetaLs) {
+ int captureCellSize = 0;
+ for (CrossRangeCellMeta crossRangeCellMeta : crossRowEleMetaLs) {
+ if (crossRangeCellMeta.getFirstRow() < rowIndex && crossRangeCellMeta.getLastRow() >= rowIndex) {
+ if (crossRangeCellMeta.getFirstCol() <= colIndex && crossRangeCellMeta.getLastCol() >= colIndex) {
+ captureCellSize = crossRangeCellMeta.getLastCol() - colIndex + 1;
+ }
+ }
+ }
+ return captureCellSize;
+ }
+
+ /**
+ * 鑾峰緱鏍囬鏍峰紡
+ *
+ * @param workbook
+ * @return
+ */
+ private static HSSFCellStyle getTitleStyle(HSSFWorkbook workbook) {
+ //short titlebackgroundcolor = IndexedColors.GREY_25_PERCENT.index;
+ short fontSize = 12;
+ String fontName = "瀹嬩綋";
+ HSSFCellStyle style = workbook.createCellStyle();
+ style.setVerticalAlignment(VerticalAlignment.CENTER);
+ style.setAlignment(HorizontalAlignment.CENTER);
+ style.setBorderBottom(BorderStyle.THIN); //涓嬭竟妗�
+ style.setBorderLeft(BorderStyle.THIN);//宸﹁竟妗�
+ style.setBorderTop(BorderStyle.THIN);//涓婅竟妗�
+ style.setBorderRight(BorderStyle.THIN);//鍙宠竟妗�
+ //style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+ //style.setFillForegroundColor(titlebackgroundcolor);// 鑳屾櫙鑹�
+
+ HSSFFont font = workbook.createFont();
+ font.setFontName(fontName);
+ font.setFontHeightInPoints(fontSize);
+ font.setBold(true);
+ style.setFont(font);
+ return style;
+ }
+
+ /**
+ * 鑾峰緱鍐呭鏍峰紡
+ *
+ * @param wb
+ * @return
+ */
+ private static HSSFCellStyle getContentStyle(HSSFWorkbook wb) {
+ short fontSize = 12;
+ String fontName = "瀹嬩綋";
+ HSSFCellStyle style = wb.createCellStyle();
+ style.setBorderBottom(BorderStyle.THIN); //涓嬭竟妗�
+ style.setBorderLeft(BorderStyle.THIN);//宸﹁竟妗�
+ style.setBorderTop(BorderStyle.THIN);//涓婅竟妗�
+ style.setBorderRight(BorderStyle.THIN);//鍙宠竟妗�
+ HSSFFont font = wb.createFont();
+ font.setFontName(fontName);
+ font.setFontHeightInPoints(fontSize);
+ style.setFont(font);
+ style.setAlignment(HorizontalAlignment.CENTER);//姘村钩灞呬腑
+ style.setVerticalAlignment(VerticalAlignment.CENTER);//鍨傜洿灞呬腑
+ style.setWrapText(true);
+ return style;
+ }
+}
+
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/utils/CrossRangeCellMeta.java b/src/main/java/com/xindao/ocr/smartjavaai/utils/CrossRangeCellMeta.java
new file mode 100644
index 0000000..c63c283
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/utils/CrossRangeCellMeta.java
@@ -0,0 +1,42 @@
+package com.xindao.ocr.smartjavaai.utils;
+
+/**
+ * @Auther: xiaoqiang
+ * @Date: 2020/12/9 9:17
+ * @Description:
+ */
+public class CrossRangeCellMeta {
+ public CrossRangeCellMeta(int firstRowIndex, int firstColIndex, int rowSpan, int colSpan) {
+ super();
+ this.firstRowIndex = firstRowIndex;
+ this.firstColIndex = firstColIndex;
+ this.rowSpan = rowSpan;
+ this.colSpan = colSpan;
+ }
+
+ private int firstRowIndex;
+ private int firstColIndex;
+ private int rowSpan;// 璺ㄨ秺琛屾暟
+ private int colSpan;// 璺ㄨ秺鍒楁暟
+
+ public int getFirstRow() {
+ return firstRowIndex;
+ }
+
+ public int getLastRow() {
+ return firstRowIndex + rowSpan - 1;
+ }
+
+ public int getFirstCol() {
+ return firstColIndex;
+ }
+
+ public int getLastCol() {
+ return firstColIndex + colSpan - 1;
+ }
+
+ public int getColSpan(){
+ return colSpan;
+ }
+}
+
diff --git a/src/main/java/com/xindao/ocr/smartjavaai/utils/OcrUtils.java b/src/main/java/com/xindao/ocr/smartjavaai/utils/OcrUtils.java
new file mode 100644
index 0000000..b6a37ef
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/smartjavaai/utils/OcrUtils.java
@@ -0,0 +1,455 @@
+package com.xindao.ocr.smartjavaai.utils;
+
+import ai.djl.modality.cv.Image;
+import ai.djl.modality.cv.ImageFactory;
+import ai.djl.modality.cv.output.BoundingBox;
+import ai.djl.modality.cv.output.DetectedObjects;
+import ai.djl.modality.cv.output.Landmark;
+import ai.djl.modality.cv.util.NDImageUtils;
+import ai.djl.ndarray.NDArray;
+import ai.djl.ndarray.NDList;
+import ai.djl.ndarray.NDManager;
+import ai.djl.opencv.OpenCVImageFactory;
+import cn.smartjavaai.common.entity.DetectionRectangle;
+import cn.smartjavaai.common.entity.Point;
+import cn.smartjavaai.common.utils.ImageUtils;
+import cn.smartjavaai.common.utils.OpenCVUtils;
+import cn.smartjavaai.common.utils.PointUtils;
+import com.xindao.ocr.smartjavaai.entity.*;
+import com.xindao.ocr.smartjavaai.enums.AngleEnum;
+import com.xindao.ocr.smartjavaai.enums.PlateType;
+import com.xindao.ocr.smartjavaai.opencv.OcrNDArrayUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.opencv.core.Mat;
+import org.opencv.core.Scalar;
+import org.opencv.imgproc.Imgproc;
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.util.*;
+import java.util.List;
+
+/**
+ * @author dwj
+ * @date 2025/4/22
+ */
+@Slf4j
+public class OcrUtils {
+
+
+ /**
+ * 杞崲涓篛crBox
+ * @param dt_boxes
+ * @return
+ */
+ public static List<OcrBox> convertToOcrBox(NDList dt_boxes) {
+ List<OcrBox> boxList = new ArrayList<>();
+ for (NDArray box : dt_boxes) {
+ float[] pointsArr = box.toFloatArray();
+ OcrBox ocrBox = new OcrBox(
+ new Point(pointsArr[0], pointsArr[1]),
+ new Point(pointsArr[2], pointsArr[3]),
+ new Point(pointsArr[4], pointsArr[5]),
+ new Point(pointsArr[6], pointsArr[7])
+ );
+ boxList.add(ocrBox);
+ }
+ return boxList;
+ }
+
+ /**
+ * 杞崲涓篛crBox
+ * @param ndLists
+ * @return
+ */
+ public static List<List<OcrBox>> convertToOcrBox(List<NDList> ndLists) {
+ if (ndLists == null || ndLists.isEmpty()) {
+ return Collections.emptyList();
+ }
+ List<List<OcrBox>> boxLists = new ArrayList<>();
+ for (NDList dt_boxes : ndLists) {
+ boxLists.add(convertToOcrBox(dt_boxes));
+ }
+ return boxLists;
+ }
+
+
+
+
+ /**
+ * 鍥剧墖鏃嬭浆
+ *
+ * @param manager
+ * @param image
+ * @return
+ */
+ public static Image rotateImg(NDManager manager, Image image) {
+ NDArray rotated = NDImageUtils.rotate90(image.toNDArray(manager), 1);
+ return ImageFactory.getInstance().fromNDArray(rotated);
+ }
+
+ /**
+ * 閫嗘椂閽堟棆杞浘鐗�
+ *
+ * @param image
+ * @param times
+ * @return
+ */
+ public static Image rotateImg(Image image, int times) {
+ try (NDManager manager = NDManager.newBaseManager()) {
+ NDArray rotated = NDImageUtils.rotate90(image.toNDArray(manager), times);
+ return OpenCVImageFactory.getInstance().fromNDArray(rotated);
+ }
+ }
+
+
+ /**
+ * 閫嗘椂閽堟棆杞浘鐗�
+ *
+ * @param image
+ * @param angleEnum
+ * @return
+ */
+ public static Image rotateImg(Image image, AngleEnum angleEnum) {
+ try (NDManager manager = NDManager.newBaseManager()) {
+ int times = 0;
+ switch (angleEnum) {
+ case ANGLE_90:
+ times = 1;
+ break;
+ case ANGLE_180:
+ times = 2;
+ break;
+ case ANGLE_270:
+ times = 3;
+ break;
+ }
+ NDArray rotated = NDImageUtils.rotate90(image.toNDArray(manager), times);
+ return OpenCVImageFactory.getInstance().fromNDArray(rotated);
+ }
+ }
+
+
+ /**
+ * 杞崲涓篛crInfo
+ * @param lines
+ * @return
+ */
+ public static OcrInfo convertToOcrInfo(List<ArrayList<RotatedBoxCompX>> lines){
+ if(Objects.isNull(lines) || lines.size() == 0){
+ return null;
+ }
+ List<List<OcrItem>> lineList = new ArrayList<List<OcrItem>>();
+ String fullText = "";
+ for(ArrayList<RotatedBoxCompX> boxList : lines){
+ List<OcrItem> line = new ArrayList<OcrItem>();
+ for(RotatedBoxCompX box : boxList){
+ float[] pointsArr = box.getBox().toFloatArray();
+ float[] lt = Arrays.copyOfRange(pointsArr, 0, 2);
+ float[] rt = Arrays.copyOfRange(pointsArr, 2, 4);
+ float[] rb = Arrays.copyOfRange(pointsArr, 4, 6);
+ float[] lb = Arrays.copyOfRange(pointsArr, 6, 8);
+ OcrBox ocrBox = new OcrBox(new Point(lt[0], lt[1]), new Point(rt[0], rt[1]), new Point(rb[0], rb[1]), new Point(lb[0], lb[1]));
+ OcrItem ocrItem = new OcrItem(ocrBox, box.getText());
+ line.add(ocrItem);
+ String text = box.getText();
+ if(text.trim().equals(""))
+ continue;
+ fullText += text + " ";
+ }
+ lineList.add(line);
+ fullText += '\n';
+ }
+ return new OcrInfo(lineList, fullText);
+ }
+
+ public static OcrInfo convertRotatedBoxesToOcrItems(List<RotatedBox> rotatedBoxes) {
+ OcrInfo ocrInfo = new OcrInfo();
+ List<OcrItem> ocrItems = new ArrayList<>();
+ StringBuilder fullText = new StringBuilder();
+ for (RotatedBox rotatedBox : rotatedBoxes) {
+ NDArray box = rotatedBox.getBox();
+ float[] points = box.toFloatArray();
+ Point topLeft = new Point(points[0], points[1]);
+ Point topRight = new Point(points[2], points[3]);
+ Point bottomRight = new Point(points[4], points[5]);
+ Point bottomLeft = new Point(points[6], points[7]);
+
+ OcrBox ocrBox = new OcrBox(topLeft, topRight, bottomRight, bottomLeft);
+ String text = rotatedBox.getText();
+
+ OcrItem item = new OcrItem();
+ item.setOcrBox(ocrBox);
+ item.setText(text);
+ ocrItems.add(item);
+ fullText.append(text + " ");
+ }
+ if (fullText.length() > 0) {
+ fullText.deleteCharAt(fullText.length() - 1);
+ }
+ ocrInfo.setOcrItemList(ocrItems);
+ ocrInfo.setFullText(fullText.toString());
+ return ocrInfo;
+ }
+
+
+ /**
+ * 閫忚鍙樻崲 + 瑁佸壀
+ * @param srcMat
+ * @param landMarks
+ * @return
+ */
+ public static Image transformAndCrop(Mat srcMat, List<ai.djl.modality.cv.output.Point> landMarks){
+ if (landMarks == null || landMarks.size() != 4) {
+ throw new IllegalArgumentException("蹇呴』鎻愪緵4涓叧閿偣");
+ }
+
+ // 姝ラ 1锛氭帓搴忎负 宸︿笂銆佸彸涓娿�佸彸涓嬨�佸乏涓�
+ List<ai.djl.modality.cv.output.Point> ordered = PointUtils.orderPoints(landMarks);
+
+ ai.djl.modality.cv.output.Point lt = ordered.get(0);
+ ai.djl.modality.cv.output.Point rt = ordered.get(1);
+ ai.djl.modality.cv.output.Point rb = ordered.get(2);
+ ai.djl.modality.cv.output.Point lb = ordered.get(3);
+
+ // 姝ラ 2锛氳绠楃洰鏍囧浘鍍忓昂瀵革紙瀹姐�侀珮锛�
+ int img_crop_width = (int) Math.max(
+ PointUtils.distance(lt, rt),
+ PointUtils.distance(rb, lb)
+ );
+ int img_crop_height = (int) Math.max(
+ PointUtils.distance(lt, lb),
+ PointUtils.distance(rt, rb)
+ );
+
+ // 姝ラ 3锛氭瀯閫犵洰鏍囧潗鏍囩偣
+ List<ai.djl.modality.cv.output.Point> dstPoints = Arrays.asList(
+ new ai.djl.modality.cv.output.Point(0, 0),
+ new ai.djl.modality.cv.output.Point(img_crop_width, 0),
+ new ai.djl.modality.cv.output.Point(img_crop_width, img_crop_height),
+ new ai.djl.modality.cv.output.Point(0, img_crop_height)
+ );
+
+ // 姝ラ 4锛氶�忚鍙樻崲
+ Mat srcPoint2f = OcrNDArrayUtils.toMat(ordered);
+ Mat dstPoint2f = OcrNDArrayUtils.toMat(dstPoints);
+ Mat cvMat = OpenCVUtils.perspectiveTransform(srcMat, srcPoint2f, dstPoint2f);
+
+ // 姝ラ 5锛氳浆涓� DJL Image + 瑁佸壀
+ Image subImg = OpenCVImageFactory.getInstance().fromImage(cvMat);
+ subImg = subImg.getSubImage(0, 0, img_crop_width, img_crop_height);
+
+ // 閲婃斁璧勬簮
+ cvMat.release();
+ srcPoint2f.release();
+ dstPoint2f.release();
+
+ return subImg;
+ }
+
+
+
+ /**
+ * 閫忚鍙樻崲+瑁佸壀
+ * @param srcMat
+ * @param box
+ * @return
+ */
+ public static Image transformAndCrop(Mat srcMat, OcrBox box){
+ float[] pointsArr = box.toFloatArray();
+ float[] lt = Arrays.copyOfRange(pointsArr, 0, 2);
+ float[] rt = Arrays.copyOfRange(pointsArr, 2, 4);
+ float[] rb = Arrays.copyOfRange(pointsArr, 4, 6);
+ float[] lb = Arrays.copyOfRange(pointsArr, 6, 8);
+ int img_crop_width = (int) Math.max(PointUtils.distance(lt, rt), PointUtils.distance(rb, lb));
+ int img_crop_height = (int) Math.max(PointUtils.distance(lt, lb), PointUtils.distance(rt, rb));
+ List<ai.djl.modality.cv.output.Point> srcPoints = new ArrayList<>();
+ srcPoints.add(new ai.djl.modality.cv.output.Point(lt[0], lt[1]));
+ srcPoints.add(new ai.djl.modality.cv.output.Point(rt[0], rt[1]));
+ srcPoints.add(new ai.djl.modality.cv.output.Point(rb[0], rb[1]));
+ srcPoints.add(new ai.djl.modality.cv.output.Point(lb[0], lb[1]));
+ List<ai.djl.modality.cv.output.Point> dstPoints = new ArrayList<>();
+ dstPoints.add(new ai.djl.modality.cv.output.Point(0, 0));
+ dstPoints.add(new ai.djl.modality.cv.output.Point(img_crop_width, 0));
+ dstPoints.add(new ai.djl.modality.cv.output.Point(img_crop_width, img_crop_height));
+ dstPoints.add(new ai.djl.modality.cv.output.Point(0, img_crop_height));
+ Mat srcPoint2f = OcrNDArrayUtils.toMat(srcPoints);
+ Mat dstPoint2f = OcrNDArrayUtils.toMat(dstPoints);
+ //閫忚鍙樻崲
+ Mat cvMat = OpenCVUtils.perspectiveTransform(srcMat, srcPoint2f, dstPoint2f);
+ Image subImg = OpenCVImageFactory.getInstance().fromImage(cvMat);
+ //ImageUtils.saveImage(subImg, i + ".png", "build/output");
+ //鍙樻崲鍚庤鍓�
+ subImg = subImg.getSubImage(0, 0, img_crop_width, img_crop_height);
+ cvMat.release();
+ srcPoint2f.release();
+ dstPoint2f.release();
+ return subImg;
+ }
+
+ /**
+ * 缁樺埗鏂囨湰妗�
+ *
+ * @param mat
+ * @param boxList
+ */
+ public static void drawRect(Mat mat, List<OcrBox> boxList) {
+ for(OcrBox ocrBox : boxList){
+ Imgproc.line(mat, ocrBox.getTopLeft().toCvPoint(), ocrBox.getTopRight().toCvPoint(), new Scalar(0, 255, 0), 1);
+ Imgproc.line(mat, ocrBox.getTopRight().toCvPoint(), ocrBox.getBottomRight().toCvPoint(), new Scalar(0, 255, 0),1);
+ Imgproc.line(mat, ocrBox.getBottomRight().toCvPoint(), ocrBox.getBottomLeft().toCvPoint(), new Scalar(0, 255, 0),1);
+ Imgproc.line(mat, ocrBox.getBottomLeft().toCvPoint(), ocrBox.getTopLeft().toCvPoint(), new Scalar(0, 255, 0), 1);
+ }
+ }
+
+
+ /**
+ * 缁樺埗鏂囨湰妗嗗強鏂囨湰
+ * @param image
+ * @param ocrInfo
+ */
+ public static void drawRectWithText(BufferedImage image, OcrInfo ocrInfo, int fontSize) {
+ // 灏嗙粯鍒跺浘鍍忚浆鎹负Graphics2D
+ Graphics2D g = (Graphics2D) image.getGraphics();
+ try {
+ Font font = new Font("妤蜂綋", Font.PLAIN, fontSize);
+ g.setFont(font);
+ g.setColor(new Color(0, 0, 255));
+ // 澹版槑鐢荤瑪灞炴�� 锛氱矖 缁嗭紙鍗曚綅鍍忕礌锛夋湯绔棤淇グ 鎶樼嚎澶勫憟灏栬
+ BasicStroke bStroke = new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
+ g.setStroke(bStroke);
+ List<OcrItem> ocrItemList = ocrInfo.getOcrItemList();
+ if(CollectionUtils.isNotEmpty(ocrInfo.getLineList())){
+ ocrItemList = ocrInfo.flattenLines();
+ }
+ for(OcrItem item : ocrItemList){
+ OcrBox box = item.getOcrBox();
+ int[] xPoints = {
+ (int)box.getTopLeft().getX(),
+ (int)box.getTopRight().getX(),
+ (int)box.getBottomRight().getX(),
+ (int)box.getBottomLeft().getX(),
+ (int)box.getTopLeft().getX()
+ };
+ int[] yPoints = {
+ (int)box.getTopLeft().getY(),
+ (int)box.getTopRight().getY(),
+ (int)box.getBottomRight().getY(),
+ (int)box.getBottomLeft().getY(),
+ (int)box.getTopLeft().getY()
+ };
+ g.drawPolyline(xPoints, yPoints, 5);
+ g.drawString(item.getText(), xPoints[0], yPoints[0]);
+ }
+ } finally {
+ g.dispose();
+ }
+ }
+
+
+ /**
+ * 缁樺埗鏂囨湰妗嗗強鏂囨湰
+ * @param srcMat
+ * @param itemList
+ */
+ public static void drawRectWithText(Mat srcMat, List<OcrItem> itemList) {
+ for(OcrItem item : itemList){
+ OcrBox ocrBox = item.getOcrBox();
+ Imgproc.line(srcMat, ocrBox.getTopLeft().toCvPoint(), ocrBox.getTopRight().toCvPoint(), new Scalar(0, 255, 0), 1);
+ Imgproc.line(srcMat, ocrBox.getTopRight().toCvPoint(), ocrBox.getBottomRight().toCvPoint(), new Scalar(0, 255, 0),1);
+ Imgproc.line(srcMat, ocrBox.getBottomRight().toCvPoint(), ocrBox.getBottomLeft().toCvPoint(), new Scalar(0, 255, 0),1);
+ Imgproc.line(srcMat, ocrBox.getBottomLeft().toCvPoint(), ocrBox.getTopLeft().toCvPoint(), new Scalar(0, 255, 0), 1);
+ // 涓枃涔辩爜
+ Imgproc.putText(srcMat, item.getAngle().getValue(), ocrBox.getTopLeft().toCvPoint(), Imgproc.FONT_HERSHEY_SCRIPT_SIMPLEX, 1.0, new Scalar(0, 255, 0), 1);
+ }
+ }
+
+ public static List<PlateInfo> convertToPlateInfo(DetectedObjects detectedObjects, Image image) {
+ List<PlateInfo> plateInfoList = new ArrayList<>();
+ Iterator iterator = detectedObjects.items().iterator();
+ int index = 0;
+ while(iterator.hasNext()) {
+ DetectedObjects.DetectedObject result = (DetectedObjects.DetectedObject)iterator.next();
+ BoundingBox box = result.getBoundingBox();
+ List<Point> keyPoints = new ArrayList<Point>();
+ if(box instanceof Landmark){
+ box.getBounds().getPath().forEach(point -> {
+ keyPoints.add(new Point(point.getX(), point.getY()));
+ });
+ }
+ int x = (int)(box.getBounds().getX() * image.getWidth());
+ int y = (int)(box.getBounds().getY() * image.getHeight());
+ int width = (int)(box.getBounds().getWidth() * image.getWidth());
+ int height = (int)(box.getBounds().getHeight() * image.getHeight());
+ // 淇杈圭晫锛岄槻姝㈣秺鐣�
+ if (x < 0) x = 0;
+ if (y < 0) y = 0;
+ if (x + width > image.getWidth()) width = image.getWidth() - x;
+ if (y + height > image.getHeight()) height = image.getHeight() - y;
+ PlateInfo plateInfo = new PlateInfo();
+ plateInfo.setPlateType(PlateType.fromClassName(detectedObjects.getClassNames().get(index)));
+ plateInfo.setScore(detectedObjects.getProbabilities().get(index).floatValue());
+ plateInfo.setDetectionRectangle(new DetectionRectangle(x, y, width, height));
+ OcrBox ocrBox = new OcrBox(keyPoints.get(0), keyPoints.get(1), keyPoints.get(2), keyPoints.get(3));
+ plateInfo.setBox(ocrBox);
+ plateInfoList.add(plateInfo);
+ index++;
+ }
+ return plateInfoList;
+ }
+
+ /**
+ * 缁樺埗杞︾墝淇℃伅
+ * @param srcMat
+ * @param plateInfoList
+ */
+ public static void drawPlateInfo(Mat srcMat, List<PlateInfo> plateInfoList) {
+ for(PlateInfo plateInfo : plateInfoList){
+ OcrBox ocrBox = plateInfo.getBox();
+ Imgproc.line(srcMat, ocrBox.getTopLeft().toCvPoint(), ocrBox.getTopRight().toCvPoint(), new Scalar(0, 0, 255), 1);
+ Imgproc.line(srcMat, ocrBox.getTopRight().toCvPoint(), ocrBox.getBottomRight().toCvPoint(), new Scalar(0, 0, 255),1);
+ Imgproc.line(srcMat, ocrBox.getBottomRight().toCvPoint(), ocrBox.getBottomLeft().toCvPoint(), new Scalar(0, 0, 255),1);
+ Imgproc.line(srcMat, ocrBox.getBottomLeft().toCvPoint(), ocrBox.getTopLeft().toCvPoint(), new Scalar(0, 0, 255), 1);
+ // 涓枃涔辩爜
+ ImageUtils.putTextWithBackground(srcMat, plateInfo.getPlateNumber() + " " + plateInfo.getPlateColor(), ocrBox.getTopLeft().toCvPoint(), new Scalar(255, 255, 255), new Scalar(0, 0, 0), 1);
+ }
+ }
+
+ /**
+ * 鍦ㄥ浘鍍忎笂缁樺埗甯︾櫧鑹茶儗鏅�侀粦鑹叉枃瀛楃殑鏂囨湰
+ */
+ public static void drawPlateInfo(BufferedImage image, List<PlateInfo> plateInfoList) {
+ // 灏嗙粯鍒跺浘鍍忚浆鎹负Graphics2D
+ Graphics2D graphics = (Graphics2D) image.getGraphics();
+ try {
+ graphics.setColor(Color.RED);// 杈规棰滆壊
+ graphics.setStroke(new BasicStroke(2)); // 绾垮2鍍忕礌
+ graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON); // 鎶楅敮榻�
+ int stroke = 2;
+ for(PlateInfo plateInfo : plateInfoList){
+ DetectionRectangle rectangle = plateInfo.getDetectionRectangle();
+ graphics.setColor(Color.RED);// 杈规棰滆壊
+ //缁樺埗杞︾墝妗�
+ graphics.drawRect(rectangle.getX(), rectangle.getY(), rectangle.getWidth(), rectangle.getHeight());
+ graphics.setColor(Color.BLACK);// 瀛椾綋棰滆壊
+ ImageUtils.drawText(graphics, plateInfo.getPlateNumber() + " " + plateInfo.getPlateColor(), rectangle.getX(), rectangle.getY(), stroke, 4);
+ OcrBox ocrBox = plateInfo.getBox();
+ //缁樺埗鍏抽敭鐐�
+ graphics.setColor(Color.BLUE);
+ graphics.drawRect((int)ocrBox.getTopLeft().getX(), (int)ocrBox.getTopLeft().getY(), 2, 2);
+ graphics.setColor(Color.GREEN);
+ graphics.drawRect((int)ocrBox.getTopRight().getX(), (int)ocrBox.getTopRight().getY(), 2, 2);
+ graphics.setColor(Color.RED);
+ graphics.drawRect((int)ocrBox.getBottomLeft().getX(), (int)ocrBox.getBottomLeft().getY(), 2, 2);
+ graphics.setColor(Color.CYAN);
+ graphics.drawRect((int)ocrBox.getBottomRight().getX(), (int)ocrBox.getBottomRight().getY(), 2, 2);
+ }
+ } finally {
+ graphics.dispose();
+ }
+ }
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/swingui/config/SwingAppConfig.java b/src/main/java/com/xindao/ocr/swingui/config/SwingAppConfig.java
new file mode 100644
index 0000000..8b7ea36
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/swingui/config/SwingAppConfig.java
@@ -0,0 +1,31 @@
+package com.xindao.ocr.swingui.config;
+
+import com.xindao.ocr.swingui.swing.FileProcessorApp;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.stereotype.Component;
+
+import javax.swing.*;
+
+/**
+ * Swing搴旂敤绋嬪簭閰嶇疆绫伙紝璐熻矗鍦⊿pring瀹瑰櫒鍒濆鍖栧畬鎴愬悗鍚姩Swing鐣岄潰
+ */
+@Component
+public class SwingAppConfig implements ApplicationListener<ContextRefreshedEvent> {
+
+ @Override
+ public void onApplicationEvent(ContextRefreshedEvent event) {
+ // 纭繚鍦⊿wing浜嬩欢璋冨害绾跨▼涓惎鍔║I
+ SwingUtilities.invokeLater(() -> {
+ try {
+ // 浠嶴pring涓婁笅鏂囪幏鍙朏ileProcessorApp瀹炰緥
+ // 鐢变簬@PostConstruct娉ㄨВ锛孲pring浼氳嚜鍔ㄨ皟鐢╥nitialize()鏂规硶杩涜鍒濆鍖�
+ FileProcessorApp fileProcessorApp = event.getApplicationContext().getBean(FileProcessorApp.class);
+ System.out.println("Swing鐣岄潰宸查�氳繃Spring瀹瑰櫒鑷姩鍒濆鍖�");
+ } catch (Exception e) {
+ System.err.println("Swing鐣岄潰鍒濆鍖栧け璐�: " + e.getMessage());
+ e.printStackTrace();
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/xindao/ocr/swingui/constant/OcrSwingConstants.java b/src/main/java/com/xindao/ocr/swingui/constant/OcrSwingConstants.java
new file mode 100644
index 0000000..f250fa6
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/swingui/constant/OcrSwingConstants.java
@@ -0,0 +1,26 @@
+package com.xindao.ocr.swingui.constant;
+
+import java.io.File;
+
+/**
+ * swing绐楀彛鐢ㄥ埌鐨勫父閲忕被
+ */
+public class OcrSwingConstants {
+
+ /**
+ * ocr鎴彇鍥剧墖鐨勭紦瀛樿矾寰�
+ */
+ public static final File cacheDir = new File(new File(System.getProperty("user.home")), ".paddle_ocr_images_cache");
+
+ /**
+ * 澶氬尯鍩熼厤缃枃浠朵繚瀛樿矾寰�
+ */
+ public static final File pdfToolDir = new File(new File(System.getProperty("user.home")), ".pdf_ocr_tool");
+
+ /**
+ * ocr鎵ц鏂囦欢淇濆瓨璺緞
+ */
+ public static final File ocrDir = new File(new File(System.getProperty("user.home")), ".paddle_ocr_cache");
+
+
+}
diff --git a/src/main/java/com/xindao/ocr/swingui/controller/OcrController.java b/src/main/java/com/xindao/ocr/swingui/controller/OcrController.java
new file mode 100644
index 0000000..153b780
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/swingui/controller/OcrController.java
@@ -0,0 +1,25 @@
+package com.xindao.ocr.swingui.controller;
+
+import com.xindao.ocr.swingui.dto.OcrDTO;
+import com.xindao.ocr.swingui.service.OcrService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/ocr")
+public class OcrController {
+
+ @Autowired
+ private OcrService ocrService;
+
+ @PostMapping("/recognize")
+ public String recognizeText(@RequestBody OcrDTO ocrDTO) {
+ // 杩欓噷搴旇璋冪敤OCR妯″瀷杩涜鏂囨湰璇嗗埆
+ // 鐢变簬鍏蜂綋瀹炵幇渚濊禆浜嶰CR搴擄紝杩欓噷浠呰繑鍥炰竴涓┖鍒楄〃浣滀负绀轰緥
+ return ocrService.ocr(ocrDTO.getImagePath());
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/swingui/dto/OcrDTO.java b/src/main/java/com/xindao/ocr/swingui/dto/OcrDTO.java
new file mode 100644
index 0000000..321a47f
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/swingui/dto/OcrDTO.java
@@ -0,0 +1,10 @@
+package com.xindao.ocr.swingui.dto;
+
+import lombok.Data;
+
+@Data
+public class OcrDTO {
+
+ private String imagePath;
+
+}
diff --git a/src/main/java/com/xindao/ocr/swingui/excel/ContractNumberExcelData.java b/src/main/java/com/xindao/ocr/swingui/excel/ContractNumberExcelData.java
new file mode 100644
index 0000000..b9b7234
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/swingui/excel/ContractNumberExcelData.java
@@ -0,0 +1,18 @@
+package com.xindao.ocr.swingui.excel;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@ColumnWidth(30) // 璁剧疆鍒楀
+public class ContractNumberExcelData {
+
+ @ExcelProperty(value = "鍚堝悓缂栧彿")
+ private String contractNumber;
+
+}
diff --git a/src/main/java/com/xindao/ocr/swingui/service/OcrService.java b/src/main/java/com/xindao/ocr/swingui/service/OcrService.java
new file mode 100644
index 0000000..ff1cd8c
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/swingui/service/OcrService.java
@@ -0,0 +1,195 @@
+package com.xindao.ocr.swingui.service;
+
+import cn.smartjavaai.common.enums.DeviceEnum;
+import com.alibaba.fastjson.JSONObject;
+import com.xindao.ocr.smartjavaai.config.DirectionModelConfig;
+import com.xindao.ocr.smartjavaai.config.OcrDetModelConfig;
+import com.xindao.ocr.smartjavaai.config.OcrRecModelConfig;
+import com.xindao.ocr.smartjavaai.config.OcrRecOptions;
+import com.xindao.ocr.smartjavaai.entity.OcrInfo;
+import com.xindao.ocr.smartjavaai.enums.CommonDetModelEnum;
+import com.xindao.ocr.smartjavaai.enums.CommonRecModelEnum;
+import com.xindao.ocr.smartjavaai.enums.DirectionModelEnum;
+import com.xindao.ocr.smartjavaai.factory.OcrModelFactory;
+import com.xindao.ocr.smartjavaai.model.common.detect.OcrCommonDetModel;
+import com.xindao.ocr.smartjavaai.model.common.direction.OcrDirectionModel;
+import com.xindao.ocr.smartjavaai.model.common.recognize.OcrCommonRecModel;
+import com.xindao.ocr.swingui.constant.OcrSwingConstants;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class OcrService {
+
+ public static DeviceEnum device = DeviceEnum.CPU;
+
+ private final static String MAIN_PP_DIR = "PP_OCRv5";
+
+ private OcrCommonRecModel recModel;
+
+ /**
+ * 鍒濆鍖栧姞杞給cr妯″瀷
+ */
+ @PostConstruct
+ private void init() {
+ log.info("澶嶅埗ocr鏂囦欢鍒版湰鍦扮敤鎴风紦瀛�...");
+ // 澶嶅埗PP_OCRv5鐩綍鍒版湰鍦扮紦瀛�
+ copyPaddleCppToCache();
+ try {
+ recModel = getRecModel();
+ } catch (IOException e) {
+ log.error("鍔犺浇OCR妯″瀷澶辫触: {}", e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 澶嶅埗resources涓殑Paddle_CPP鐩綍鍒版湰鍦扮紦瀛�
+ */
+ private void copyPaddleCppToCache() {
+ try {
+ // 鍒涘缓缂撳瓨鐩綍 - 浣跨敤鐢ㄦ埛涓荤洰褰曢伩鍏嶆潈闄愰棶棰�
+ File cacheDir = OcrSwingConstants.ocrDir;
+ if (!cacheDir.exists()) {
+ cacheDir.mkdirs();
+ }
+
+ // 鑾峰彇resources涓殑Paddle_CPP鐩綍璧勬簮
+ PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
+ Resource[] resources = resolver.getResources("classpath:"+MAIN_PP_DIR+"/**");
+
+ // 澶嶅埗鎵�鏈夎祫婧愬埌缂撳瓨鐩綍锛屼繚鎸佺洰褰曠粨鏋�
+ for (Resource resource : resources) {
+ String resourcePath = resource.getURL().getPath();
+ // 鑾峰彇鐩稿浜嶱addle_CPP鐨勮矾寰�
+ int startIndex = resourcePath.indexOf(MAIN_PP_DIR) + MAIN_PP_DIR.length();
+ String relativePath = resourcePath.substring(startIndex);
+ // 澶勭悊Windows璺緞鍒嗛殧绗�
+ relativePath = relativePath.replace('/', File.separatorChar);
+ // 鍒涘缓鐩爣鏂囦欢
+ File destFile = new File(cacheDir, relativePath);
+ // 濡傛灉鏄洰褰曪紝鍒涘缓鐩綍
+ if (resource.isReadable() && resource.contentLength() == 0 && relativePath.endsWith(File.separator)) {
+ if (!destFile.exists()) {
+ destFile.mkdirs();
+ log.info("鍒涘缓鐩綍: {}", destFile.getAbsolutePath());
+ }
+ } else if (resource.isReadable()) {
+ // 纭繚鐖剁洰褰曞瓨鍦�
+ File parentDir = destFile.getParentFile();
+ if (parentDir != null && !parentDir.exists()) {
+ parentDir.mkdirs();
+ }
+ // 澶嶅埗鏂囦欢
+ Files.copy(resource.getInputStream(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
+ log.info("澶嶅埗璧勬簮: {} 鍒� {}", relativePath, destFile.getAbsolutePath());
+ }
+ }
+
+ } catch (IOException e) {
+ log.error("澶嶅埗PP_OCRv5鐩綍鍒扮紦瀛樺け璐�: {}", e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+
+ /**
+ * 鑾峰彇 resources 涓嬫ā鍨嬫枃浠剁殑缁濆璺緞
+ *
+ * @param relativePath 鐩稿浜� resources 鐨勮矾寰�
+ */
+ private String getModelPath(String relativePath) throws IOException {
+ String localPath = null;
+ try{
+ new ClassPathResource(relativePath).getFile().getAbsolutePath();
+ }catch (IOException e){
+ // 濡傛灉鎵句笉鍒版枃浠讹紝鍒欏皾璇曚粠鏈湴缂撳瓨鐩綍鑾峰彇
+ localPath = getLocalPath(relativePath);
+ File modelFile = new File(localPath);
+ if (!modelFile.exists()) {
+ throw new IOException("妯″瀷鏂囦欢涓嶅瓨鍦�: " + localPath);
+ }
+ } finally {
+ log.info("OCR妯″瀷鏂囦欢璺緞: {}", localPath);
+ }
+ return localPath;
+ }
+
+ /**
+ * 鑾峰彇 resources 涓嬫ā鍨嬫枃浠剁殑鐢ㄦ埛鏈湴璺緞
+ *
+ * @param relativePath 鐩稿浜� resources 鐨勮矾寰�
+ */
+ private String getLocalPath(String relativePath) {
+ return new File(OcrSwingConstants.ocrDir,File.separator + relativePath).getAbsolutePath();
+ }
+
+ public OcrCommonRecModel getRecModel() throws IOException {
+ OcrRecModelConfig recModelConfig = new OcrRecModelConfig();
+ recModelConfig.setRecModelEnum(CommonRecModelEnum.PP_OCR_V5_MOBILE_REC_MODEL);
+ recModelConfig.setRecModelPath(
+ getModelPath("PP-OCRv5_server_rec_infer/PP-OCRv5_server_rec.onnx")
+ );
+ recModelConfig.setDevice(device);
+ recModelConfig.setTextDetModel(getDetectionModel());
+ return OcrModelFactory.getInstance().getRecModel(recModelConfig);
+ }
+
+ public OcrCommonDetModel getDetectionModel() throws IOException {
+ OcrDetModelConfig config = new OcrDetModelConfig();
+ config.setModelEnum(CommonDetModelEnum.PP_OCR_V5_MOBILE_DET_MODEL);
+ config.setDetModelPath(
+ getModelPath("PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx")
+ );
+ config.setDevice(device);
+ return OcrModelFactory.getInstance().getDetModel(config);
+ }
+
+ public OcrDirectionModel getDirectionModel() throws IOException {
+ DirectionModelConfig directionModelConfig = new DirectionModelConfig();
+ directionModelConfig.setModelEnum(DirectionModelEnum.PP_LCNET_X0_25);
+ directionModelConfig.setModelPath(
+ getModelPath("PP-LCNet_x0_25_textline_ori_infer/PP-LCNet_x0_25_textline_ori_infer.onnx")
+ );
+ directionModelConfig.setDevice(device);
+ return OcrModelFactory.getInstance().getDirectionModel(directionModelConfig);
+ }
+
+ public OcrCommonRecModel getRecModelWithDirection() throws IOException {
+ OcrRecModelConfig recModelConfig = new OcrRecModelConfig();
+ recModelConfig.setRecModelEnum(CommonRecModelEnum.PP_OCR_V5_MOBILE_REC_MODEL);
+ recModelConfig.setRecModelPath(
+ getModelPath("PP-OCRv5_mobile_rec_infer/PP-OCRv5_mobile_rec_infer.onnx")
+ );
+ recModelConfig.setDevice(device);
+ recModelConfig.setTextDetModel(getDetectionModel());
+ recModelConfig.setDirectionModel(getDirectionModel());
+ return OcrModelFactory.getInstance().getRecModel(recModelConfig);
+ }
+
+ public String ocr(String url) {
+ String fullText = null;
+ try {
+ OcrRecOptions options = new OcrRecOptions(false, true);
+ OcrInfo ocrInfo = recModel.recognize(url, options);
+ log.info("OCR璇嗗埆缁撴灉锛歿}", JSONObject.toJSONString(ocrInfo));
+ fullText = ocrInfo.getFullText();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return fullText;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/xindao/ocr/swingui/swing/FileProcessorApp.java b/src/main/java/com/xindao/ocr/swingui/swing/FileProcessorApp.java
new file mode 100644
index 0000000..44ccc19
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/swingui/swing/FileProcessorApp.java
@@ -0,0 +1,100 @@
+package com.xindao.ocr.swingui.swing;
+
+import com.xindao.ocr.swingui.service.OcrService;
+import com.xindao.ocr.swingui.swing.jpanel.ContractNumberProcessPanel;
+import com.xindao.ocr.swingui.swing.jpanel.MultipleAreaProcessPanel;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.context.annotation.Scope;
+
+import javax.annotation.PostConstruct;
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+
+@org.springframework.stereotype.Component
+@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) // 璁剧疆涓哄師鍨嬩綔鐢ㄥ煙锛屾瘡娆¤幏鍙栧垱寤烘柊瀹炰緥
+public class FileProcessorApp extends JFrame {
+
+ @Autowired
+ private OcrService ocrService;
+
+ private static final Font DEFAULT_FONT;
+
+ // 棰滆壊瀹氫箟
+ private static final Color BACKGROUND_COLOR = new Color(245, 245, 247);
+ private static final Color TEXT_COLOR = new Color(51, 51, 51);
+ private static final Color PRIMARY_COLOR = new Color(66, 133, 244);
+ private static final Color TEXT_LIGHT = new Color(102, 102, 102);
+
+ static {
+ // 瀛椾綋璁剧疆
+ if (isFontAvailable("Microsoft YaHei")) {
+ DEFAULT_FONT = new Font("Microsoft YaHei", Font.PLAIN, 12);
+ } else if (isFontAvailable("SimHei")) {
+ DEFAULT_FONT = new Font("SimHei", Font.PLAIN, 12);
+ } else if (isFontAvailable("WenQuanYi Micro Hei")) {
+ DEFAULT_FONT = new Font("WenQuanYi Micro Hei", Font.PLAIN, 12);
+ } else {
+ DEFAULT_FONT = new Font(Font.SANS_SERIF, Font.PLAIN, 12);
+ }
+ }
+
+ private static boolean isFontAvailable(String fontName) {
+ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ String[] fontNames = ge.getAvailableFontFamilyNames();
+ for (String name : fontNames) {
+ if (name.equals(fontName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public FileProcessorApp() {
+ setTitle("OCR鍥惧儚澶勭悊宸ュ叿");
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ setSize(850, 700);
+ setLocationRelativeTo(null);
+ setResizable(true);
+
+ // 璁剧疆鍏ㄥ眬瀛椾綋鍜岃儗鏅�
+ setFont(DEFAULT_FONT);
+ getContentPane().setBackground(BACKGROUND_COLOR);
+ }
+
+ /**
+ * 浣跨敤@PostConstruct纭繚渚濊禆娉ㄥ叆瀹屾垚鍚庡啀鍒濆鍖朥I
+ * 閬垮厤鏋勯�犲嚱鏁颁腑鐩存帴浣跨敤@Autowired鐨勫瓧娈靛鑷磏ull鍊�
+ */
+ @PostConstruct
+ public void initialize() {
+ initUI();
+ setVisible(true);
+ }
+
+ private void initUI() {
+ // 涓婚潰鏉夸娇鐢ㄨ竟鐣屽竷灞�
+ JPanel mainPanel = new JPanel(new BorderLayout(15, 15));
+ mainPanel.setBorder(new EmptyBorder(15, 15, 15, 15));
+ mainPanel.setBackground(BACKGROUND_COLOR);
+
+ // 鍒涘缓鏍囩椤甸潰鏉�
+ JTabbedPane tabbedPane = new JTabbedPane();
+ tabbedPane.setFont(DEFAULT_FONT);
+
+ JPanel mainTab = new ContractNumberProcessPanel(BACKGROUND_COLOR, PRIMARY_COLOR, TEXT_COLOR,TEXT_LIGHT,DEFAULT_FONT,this,ocrService).initPanel();
+ JPanel extensionPanel = new MultipleAreaProcessPanel(this,ocrService,BACKGROUND_COLOR, PRIMARY_COLOR, TEXT_COLOR, DEFAULT_FONT).initPanel();
+ // 娣诲姞鏍囩椤靛埌鏍囩闈㈡澘
+ tabbedPane.addTab("鏂囦欢澶勭悊", null, mainTab, "");
+ tabbedPane.addTab("澶氬尯鍩熻瘑鍒�", null, extensionPanel, "");
+
+ // 娣诲姞鏍囩闈㈡澘鍒颁富闈㈡澘
+ mainPanel.add(tabbedPane, BorderLayout.CENTER);
+
+ // 璁剧疆鍐呭闈㈡澘
+ setContentPane(mainPanel);
+
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/swingui/swing/jpanel/ContractNumberProcessPanel.java b/src/main/java/com/xindao/ocr/swingui/swing/jpanel/ContractNumberProcessPanel.java
new file mode 100644
index 0000000..112b9bd
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/swingui/swing/jpanel/ContractNumberProcessPanel.java
@@ -0,0 +1,645 @@
+package com.xindao.ocr.swingui.swing.jpanel;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.support.ExcelTypeEnum;
+import com.xindao.ocr.swingui.constant.OcrSwingConstants;
+import com.xindao.ocr.swingui.excel.ContractNumberExcelData;
+import com.xindao.ocr.swingui.service.OcrService;
+import com.xindao.ocr.swingui.swing.FileProcessorApp;
+import com.xindao.ocr.swingui.swing.utils.FileNameValidator;
+import com.xindao.ocr.swingui.swing.utils.GenerateCustomizeComponent;
+import com.xindao.ocr.swingui.swing.utils.ToFile;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.rendering.PDFRenderer;
+import org.apache.poi.util.IOUtils;
+
+import javax.swing.*;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.LineBorder;
+import javax.swing.filechooser.FileFilter;
+import java.awt.*;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.prefs.Preferences;
+
+/**
+ * 鍚堝悓缂栧彿澶勭悊闈㈡澘
+ */
+public class ContractNumberProcessPanel {
+
+ private final OcrService ocrService;
+ private final List<File> selectedFiles = new ArrayList<>();
+ private final Preferences prefs;
+ private final Font DEFAULT_FONT;
+
+ private JTextArea logArea;
+ private JLabel filesLabel;
+ private JLabel outputDirLabel;
+ private JLabel lastSelectionLabel; // 鏂板锛氱敤浜庢樉绀轰笂娆¢�夋嫨淇℃伅鐨勬爣绛�
+ private File outputDirectory;
+
+ private final Color BACKGROUND_COLOR;
+ private final Color PRIMARY_COLOR;
+ private final Color TEXT_COLOR;
+ private final Color TEXT_LIGHT;
+
+
+ // PDF鍖哄煙閫夋嫨鐩稿叧鐨勫亸濂借缃敭
+ private static final String PREF_PDF_PAGE = "lastPdfPage";
+ private static final String PREF_PDF_X = "lastPdfX";
+ private static final String PREF_PDF_Y = "lastPdfY";
+ private static final String PREF_PDF_WIDTH = "lastPdfWidth";
+ private static final String PREF_PDF_HEIGHT = "lastPdfHeight";
+
+ private final FileProcessorApp supper;
+
+ AtomicInteger fileIndex = new AtomicInteger(1);
+
+ public ContractNumberProcessPanel(
+ Color BACKGROUND_COLOR,
+ Color PRIMARY_COLOR,
+ Color TEXT_COLOR,
+ Color TEXT_LIGHT,
+ Font font,
+ FileProcessorApp supper,
+ OcrService ocrService){
+ this.BACKGROUND_COLOR = BACKGROUND_COLOR;
+ this.PRIMARY_COLOR = PRIMARY_COLOR;
+ this.TEXT_COLOR = TEXT_COLOR;
+ this.TEXT_LIGHT = TEXT_LIGHT;
+
+ this.DEFAULT_FONT = font;
+ this.supper = supper;
+ this.ocrService = ocrService;
+ this.prefs = Preferences.userNodeForPackage(ContractNumberProcessPanel.class);
+
+ }
+
+ public JPanel initPanel() {
+ // 鍒濆鍖栭潰鏉�
+ // 绗竴涓爣绛鹃〉锛氭枃浠跺鐞嗗拰鏃ュ織锛堝悎骞跺埌涓�涓爣绛鹃〉锛�
+ JPanel mainTab = new JPanel(new BorderLayout(15, 15));
+ mainTab.setBorder(new EmptyBorder(15, 15, 15, 15));
+ mainTab.setBackground(BACKGROUND_COLOR);
+
+ // 椤堕儴鍗$墖锛氭枃浠堕�夋嫨鍖哄煙
+ JPanel topCard = GenerateCustomizeComponent.createCardPanel();
+ topCard.setLayout(new BoxLayout(topCard, BoxLayout.Y_AXIS));
+ topCard.setBorder(new EmptyBorder(20, 20, 20, 20));
+
+ // 娣诲姞鏍囬 - 淇敼涓哄眳涓樉绀�
+ JPanel titlePanel = new JPanel(new GridBagLayout());
+ titlePanel.setOpaque(false);
+ JLabel titleLabel = new JLabel("鍚堝悓缂栧彿璇嗗埆");
+ titleLabel.setFont(new Font(DEFAULT_FONT.getName(), Font.BOLD, 18));
+ titleLabel.setForeground(PRIMARY_COLOR);
+ titleLabel.setBorder(new EmptyBorder(0, 0, 15, 0));
+ titlePanel.add(titleLabel);
+
+ topCard.add(titlePanel);
+ topCard.add(Box.createVerticalStrut(10));
+
+ // 鏂囦欢閫夋嫨鍖哄煙
+ JPanel fileSelectionPanel = GenerateCustomizeComponent.createStyledPanel(new FlowLayout(FlowLayout.LEFT, 10, 10));
+ JButton selectFilesBtn = GenerateCustomizeComponent.createStyledButton("閫夋嫨鏂囦欢...",DEFAULT_FONT);
+ filesLabel = new JLabel("鏈�夋嫨鏂囦欢");
+ filesLabel.setFont(DEFAULT_FONT);
+ filesLabel.setForeground(TEXT_COLOR);
+ fileSelectionPanel.add(selectFilesBtn);
+ fileSelectionPanel.add(filesLabel);
+
+ // 杈撳嚭鐩綍閫夋嫨鍖哄煙
+ JPanel outputDirPanel = GenerateCustomizeComponent.createStyledPanel(new FlowLayout(FlowLayout.LEFT, 10, 10));
+ JButton selectOutputDirBtn = GenerateCustomizeComponent.createStyledButton("閫夋嫨杈撳嚭鐩綍...",DEFAULT_FONT);
+ outputDirLabel = new JLabel("鏈�夋嫨杈撳嚭鐩綍");
+ outputDirLabel.setFont(DEFAULT_FONT);
+ outputDirLabel.setForeground(TEXT_COLOR);
+ outputDirPanel.add(selectOutputDirBtn);
+ outputDirPanel.add(outputDirLabel);
+
+ // PDF鍖哄煙閫夋嫨鎸夐挳鍜屼笂娆¢�夋嫨淇℃伅 - 淇敼涓轰竴琛屾樉绀�
+ JPanel pdfSelectionPanel = GenerateCustomizeComponent.createStyledPanel(new FlowLayout(FlowLayout.LEFT, 10, 10));
+ JButton selectPdfAreaBtn = GenerateCustomizeComponent.createStyledButton("閫夋嫨PDF鍖哄煙...",DEFAULT_FONT);
+ pdfSelectionPanel.add(selectPdfAreaBtn);
+
+ // 涓婃閫夋嫨鐨凱DF鍖哄煙淇℃伅 - 浣跨敤鎴愬憳鍙橀噺寮曠敤
+ lastSelectionLabel = new JLabel("涓婃閫夋嫨: 鏃�");
+ lastSelectionLabel.setFont(DEFAULT_FONT);
+ lastSelectionLabel.setForeground(TEXT_LIGHT);
+ pdfSelectionPanel.add(lastSelectionLabel);
+
+ // 澶勭悊鎸夐挳
+ JPanel processBtnPanel = GenerateCustomizeComponent.createStyledPanel(new FlowLayout(FlowLayout.CENTER, 0, 15));
+ JButton processBtn = GenerateCustomizeComponent.createPrimaryButton("澶勭悊鏂囦欢",DEFAULT_FONT);
+ processBtnPanel.add(processBtn);
+
+ // 娣诲姞鍒伴《閮ㄥ崱鐗�
+ topCard.add(fileSelectionPanel);
+ topCard.add(Box.createVerticalStrut(10));
+ topCard.add(outputDirPanel);
+ topCard.add(Box.createVerticalStrut(10));
+ topCard.add(pdfSelectionPanel);
+ topCard.add(Box.createVerticalStrut(15));
+ topCard.add(processBtnPanel);
+
+ // 搴曢儴鍗$墖锛氭棩蹇楀尯鍩�
+ JPanel bottomCard = GenerateCustomizeComponent.createCardPanel();
+ bottomCard.setLayout(new BorderLayout());
+ bottomCard.setBorder(new EmptyBorder(15, 15, 15, 15));
+
+
+ JLabel logTitleLabel = new JLabel("澶勭悊鏃ュ織");
+ logTitleLabel.setFont(new Font(DEFAULT_FONT.getName(), Font.BOLD, 14));
+ logTitleLabel.setForeground(TEXT_COLOR);
+ logTitleLabel.setBorder(new EmptyBorder(0, 0, 10, 0));
+
+ logArea = new JTextArea();
+ logArea.setEditable(false);
+ logArea.setLineWrap(true);
+ logArea.setSize(-1,100);
+ logArea.setFont(DEFAULT_FONT);
+ logArea.setBackground(new Color(250, 250, 250));
+ logArea.setBorder(new CompoundBorder(
+ new LineBorder(new Color(220, 220, 220)),
+ new EmptyBorder(5, 5, 5, 5)
+ ));
+
+ JScrollPane scrollPane = new JScrollPane(logArea);
+ scrollPane.setBorder(null);
+ scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+
+ bottomCard.add(logTitleLabel, BorderLayout.NORTH);
+ bottomCard.add(scrollPane, BorderLayout.CENTER);
+
+ // 娣诲姞椤堕儴鍗$墖鍜屽簳閮ㄥ崱鐗囧埌涓绘爣绛鹃〉
+ mainTab.add(topCard, BorderLayout.NORTH);
+ mainTab.add(bottomCard, BorderLayout.CENTER);
+
+ // 娣诲姞浜嬩欢鐩戝惉鍣�
+ selectFilesBtn.addActionListener(e -> selectFiles());
+ selectOutputDirBtn.addActionListener(e -> selectOutputDirectory());
+ processBtn.addActionListener(e -> processFiles());
+ selectPdfAreaBtn.addActionListener(e -> selectPdfArea());
+
+
+ loadLastPaths();
+ showLastPdfSelectionInfo();
+
+ return mainTab;
+ }
+
+ private void selectFiles() {
+ JFileChooser fileChooser = new JFileChooser();
+ setComponentFont(fileChooser, DEFAULT_FONT);
+
+ String lastFilePath = prefs.get("lastFilepath", "");
+ if (!lastFilePath.isEmpty()) {
+ File lastFile = new File(lastFilePath);
+ if (lastFile.exists()) {
+ fileChooser.setCurrentDirectory(lastFile.getParentFile());
+ }
+ }
+
+ fileChooser.setMultiSelectionEnabled(true);
+ fileChooser.setDialogTitle("閫夋嫨瑕佸鐞嗙殑鏂囦欢");
+ styleFileChooser(fileChooser);
+
+ int result = fileChooser.showOpenDialog(supper);
+ if (result == JFileChooser.APPROVE_OPTION) {
+ selectedFiles.clear();
+ File[] files = fileChooser.getSelectedFiles();
+ selectedFiles.addAll(Arrays.asList(files));
+ filesLabel.setText("宸查�夋嫨 " + selectedFiles.size() + " 涓枃浠�");
+ log("宸查�夋嫨 " + selectedFiles.size() + " 涓枃浠�");
+
+ if (files.length > 0) {
+ prefs.put("lastFilepath", files[0].getAbsolutePath());
+ }
+ }
+ }
+
+ private void setComponentFont(Component component, Font font) {
+ component.setFont(font);
+ if (component instanceof Container) {
+ for (Component child : ((Container) component).getComponents()) {
+ setComponentFont(child, font);
+ }
+ }
+ }
+
+ // 缇庡寲鏂囦欢閫夋嫨鍣�
+ private void styleFileChooser(JFileChooser chooser) {
+ chooser.setBackground(BACKGROUND_COLOR);
+ chooser.setForeground(TEXT_COLOR);
+
+ // 璁剧疆鎸夐挳鏍峰紡
+ for (Component comp : chooser.getComponents()) {
+ if (comp instanceof JButton) {
+ JButton btn = (JButton) comp;
+ btn.setFont(DEFAULT_FONT);
+ btn.setBorder(new EmptyBorder(5, 10, 5, 10));
+ btn.setFocusPainted(false);
+ }
+ setComponentFont(comp, DEFAULT_FONT);
+ }
+ }
+
+ private void selectOutputDirectory() {
+ JFileChooser dirChooser = new JFileChooser();
+ setComponentFont(dirChooser, DEFAULT_FONT);
+
+ String lastDirPath = prefs.get("lastOutputDir", "");
+ if (!lastDirPath.isEmpty()) {
+ File lastDir = new File(lastDirPath);
+ if (lastDir.exists() && lastDir.isDirectory()) {
+ dirChooser.setCurrentDirectory(lastDir);
+ }
+ }
+
+ dirChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ dirChooser.setDialogTitle("閫夋嫨杈撳嚭鐩綍");
+ styleFileChooser(dirChooser);
+
+ int result = dirChooser.showOpenDialog(supper);
+ if (result == JFileChooser.APPROVE_OPTION) {
+ outputDirectory = dirChooser.getSelectedFile();
+ outputDirLabel.setText(outputDirectory.getAbsolutePath());
+ log("宸查�夋嫨杈撳嚭鐩綍: " + outputDirectory.getAbsolutePath());
+
+ prefs.put("lastOutputDir", outputDirectory.getAbsolutePath());
+ }
+ }
+
+
+ /**
+ * 澶勭悊鍚堝悓缂栧彿鏂规硶
+ */
+ private void processFiles() {
+ if (selectedFiles.isEmpty()) {
+ JOptionPane.showMessageDialog(supper, "璇峰厛閫夋嫨瑕佸鐞嗙殑鏂囦欢", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+ return;
+ }
+
+ if (outputDirectory == null || !outputDirectory.exists()) {
+ JOptionPane.showMessageDialog(supper, "璇峰厛閫夋嫨鏈夋晥鐨勮緭鍑虹洰褰�", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+ return;
+ }
+
+ log("寮�濮嬪鐞嗘枃浠�...");
+ //璇嗗埆鍒扮殑鍚堝悓缂栧彿鍒楄〃
+ final List<ContractNumberExcelData> contractNumberList = new CopyOnWriteArrayList<>();
+
+ new Thread(() -> {
+ int successCount = 0;
+ int failCount = 0;
+ int processCount = 0;
+
+ for (File file : selectedFiles) {
+ processCount++;
+ try {
+ //鎴彇pdf閫夊尯鍥惧儚
+ String pathStr = capturePdfArea(file, prefs);
+// ToFile.preprocessImage(pathStr);
+ //璇诲彇鍥惧儚鍐呭
+ String ocrFullText = FileNameValidator.validateAndCleanFileName(ocrService.ocr(pathStr.replaceFirst("/", "")));
+ //鑾峰彇璇嗗埆鍒扮殑绗竴涓唴瀹�
+ String text = file.getName().replace(".pdf","");
+ if(StringUtils.isNotBlank(ocrFullText) && !StringUtils.equals(ocrFullText,text)){
+ text = ocrFullText;
+ String finalText = text;
+ //濡傛灉鍚堝悓缂栧彿閲嶅锛屽垯鍦ㄦ枃浠跺悕鍚庡姞涓�涓簭鍙�
+ if(contractNumberList.stream().anyMatch(f -> f.getContractNumber().equals(finalText))){
+ text+="("+ fileIndex.get() +")";
+ fileIndex.getAndIncrement();
+ }
+ //灏嗚瘑鍒殑鍐呭璁剧疆涓烘枃浠跺悕锛屽鍑哄埌鎸囧畾鐩綍
+ String outputFileName = text + ".pdf";
+ File outputFile = new File(outputDirectory, outputFileName);
+ if (!outputFile.getParentFile().exists()) {
+ outputFile.getParentFile().mkdirs();
+ }
+ IOUtils.copy(Files.newInputStream(file.toPath()),outputFile);
+ }
+ successCount++;
+ contractNumberList.add(new ContractNumberExcelData(text));
+ log("澶勭悊鎴愬姛("+processCount+"/"+selectedFiles.size()+"): " + file.getName());
+ } catch (Exception e) {
+ failCount++;
+ e.printStackTrace();
+ log("澶勭悊澶辫触: " + file.getName() + " - " + e.getMessage());
+ }finally {
+ //鍒犻櫎涓存椂鐩綍
+ ToFile.deleteTempFiles(OcrSwingConstants.cacheDir);
+ }
+ }
+
+ //瀵煎嚭璇嗗埆鍒扮殑鍚堝悓缂栧彿鍒楄〃
+ try {
+ String outputExcelFileName = "鍚堝悓缂栧彿鍒楄〃_" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + ExcelTypeEnum.XLSX.getValue();
+ File outputExcelFile = new File(outputDirectory, outputExcelFileName);
+ if (!outputExcelFile.getParentFile().exists()) {
+ outputExcelFile.getParentFile().mkdirs();
+ }
+ EasyExcel.write(outputExcelFile, ContractNumberExcelData.class).sheet().doWrite(contractNumberList);
+ log("鏂囦欢宸插鍑哄埌: " + outputExcelFile.getAbsolutePath());
+ } catch (Exception e) {
+ log("瀵煎嚭鍚堝悓缂栧彿鍒楄〃澶辫触: " + e.getMessage());
+ }
+
+ log("澶勭悊瀹屾垚 - 鎴愬姛: " + successCount + ", 澶辫触: " + failCount);
+ int finalSuccessCount = successCount;
+ int finalFailCount = failCount;
+ SwingUtilities.invokeLater(() ->
+ JOptionPane.showMessageDialog(supper,
+ "澶勭悊瀹屾垚\n鎴愬姛: " + finalSuccessCount + "\n澶辫触: " + finalFailCount,
+ "澶勭悊缁撴灉", JOptionPane.INFORMATION_MESSAGE)
+ );
+ }).start();
+ }
+
+ // 鍔犺浇涓婃鐨凱DF鍖哄煙閫夋嫨淇℃伅
+ private Map<String, Object> loadLastPdfSelectionInfo() {
+ Map<String, Object> info = new HashMap<>();
+
+ int pageNumber = prefs.getInt(PREF_PDF_PAGE, 0);
+ float x = prefs.getFloat(PREF_PDF_X, 0);
+ float y = prefs.getFloat(PREF_PDF_Y, 0);
+ float width = prefs.getFloat(PREF_PDF_WIDTH, 0);
+ float height = prefs.getFloat(PREF_PDF_HEIGHT, 0);
+
+ info.put("page", pageNumber);
+ info.put("x", x);
+ info.put("y", y);
+ info.put("width", width);
+ info.put("height", height);
+
+ return info;
+ }
+
+ // PDF鍖哄煙閫夋嫨鍔熻兘
+ private void selectPdfArea() {
+ // 妫�鏌ユ槸鍚︽湁涓婃閫夋嫨鐨凱DF淇℃伅
+ Map<String, Object> lastSelection = loadLastPdfSelectionInfo();
+ File pdfFile = null;
+ int defaultPage = 0;
+ boolean hasReSelection = true;
+ // 濡傛灉鏈変笂娆¢�夋嫨鐨勪俊鎭紝璇㈤棶鐢ㄦ埛鏄惁浣跨敤
+ if (!lastSelection.isEmpty()) {
+ int option = JOptionPane.showConfirmDialog(supper,
+ "鏄惁浣跨敤涓婃閫夋嫨鐨勫尯鍩�?",
+ "涓婃閫夋嫨", JOptionPane.YES_NO_OPTION);
+
+ if (option == JOptionPane.YES_OPTION) {
+ hasReSelection = false; // 鐢ㄦ埛閫夋嫨浣跨敤涓婃鐨勬枃浠�
+ }
+ }
+
+ // 濡傛灉娌℃湁涓婃閫夋嫨鐨勬枃浠舵垨鐢ㄦ埛涓嶄娇鐢ㄤ笂娆$殑鏂囦欢锛屽垯璁╃敤鎴烽�夋嫨鏂版枃浠�
+ if (hasReSelection) {
+ JFileChooser fileChooser = new JFileChooser();
+ setComponentFont(fileChooser, DEFAULT_FONT);
+ styleFileChooser(fileChooser);
+
+ // 杩囨护鍙樉绀篜DF鏂囦欢
+ fileChooser.setFileFilter(new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return f.isDirectory() || f.getName().toLowerCase().endsWith(".pdf");
+ }
+
+ @Override
+ public String getDescription() {
+ return "PDF鏂囦欢 (*.pdf)";
+ }
+ });
+
+ fileChooser.setDialogTitle("閫夋嫨PDF鏂囦欢");
+
+ int result = fileChooser.showOpenDialog(supper);
+ if (result != JFileChooser.APPROVE_OPTION) {
+ return;
+ }
+
+ pdfFile = fileChooser.getSelectedFile();
+ if (!pdfFile.getName().toLowerCase().endsWith(".pdf")) {
+ JOptionPane.showMessageDialog(supper, "璇烽�夋嫨PDF鏂囦欢", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+ return;
+ }
+
+ // 鍔犺浇PDF骞舵樉绀洪�夋嫨闈㈡澘
+ try (PDDocument document = PDDocument.load(Files.newInputStream(pdfFile.toPath()))) {
+ int totalPages = document.getNumberOfPages();
+ // 榛樿绗竴椤�
+ // 璁╃敤鎴疯緭鍏ラ〉鐮侊紝榛樿浣跨敤涓婃鐨勯〉鐮�
+ String pageStr = JOptionPane.showInputDialog(supper,
+ "璇疯緭鍏ヨ閫夋嫨鍖哄煙鐨勯〉鐮�(鍏�"+totalPages+"椤�):",
+ "杈撳叆椤电爜",
+ JOptionPane.PLAIN_MESSAGE,
+ null,
+ null,
+ String.valueOf(defaultPage + 1)).toString();
+
+ if (pageStr == null || pageStr.trim().isEmpty()) {
+ return;
+ }
+
+ int pageNumber;
+ try {
+ pageNumber = Integer.parseInt(pageStr.trim()) - 1; // PDFBox椤电爜浠�0寮�濮�
+ } catch (NumberFormatException e) {
+ JOptionPane.showMessageDialog(supper, "璇疯緭鍏ユ湁鏁堢殑椤电爜", "閿欒", JOptionPane.ERROR_MESSAGE);
+ return;
+ }
+ if (pageNumber < 0 || pageNumber >= totalPages) {
+ JOptionPane.showMessageDialog(supper, "椤电爜瓒呭嚭鑼冨洿", "閿欒", JOptionPane.ERROR_MESSAGE);
+ return;
+ }
+
+ // 鑾峰彇PDF椤甸潰灏哄
+ float pdfWidth = document.getPage(pageNumber).getMediaBox().getWidth();
+ float pdfHeight = document.getPage(pageNumber).getMediaBox().getHeight();
+
+ // 鑾峰彇涓婃閫夋嫨鐨勫尯鍩燂紙濡傛灉瀛樺湪涓旀槸褰撳墠鏂囦欢鍜岄〉闈級
+ Rectangle2D lastArea = null;
+ if (!lastSelection.isEmpty() && pageNumber == (int)lastSelection.get("page")) {
+ float x = (float)lastSelection.get("x");
+ float y = (float)lastSelection.get("y");
+ float width = (float)lastSelection.get("width");
+ float height = (float)lastSelection.get("height");
+
+ // 杞崲涓篜DF鍧愭爣绯荤粺鐨勫尯鍩燂紙鏈缉鏀剧殑锛�
+ lastArea = new Rectangle2D.Float(x, y, width, height);
+ }
+
+ // 鍒涘缓PDF棰勮鍜屽尯鍩熼�夋嫨瀵硅瘽妗�
+ JDialog pdfDialog = new JDialog(supper, "閫夋嫨PDF璇嗗埆鍖哄煙 - " + pdfFile.getName(), true);
+ pdfDialog.setSize(639, 850);
+ pdfDialog.setLocationRelativeTo(supper);
+
+ // 鍒涘缓PDF棰勮闈㈡澘锛屼紶鍏ヤ笂娆¢�夋嫨鐨勫尯鍩�
+ PdfPreviewPanel previewPanel = new PdfPreviewPanel(document, pageNumber, lastArea);
+ // 鍒涘缓鍙粴鍔ㄧ殑PDF棰勮闈㈡澘
+ JScrollPane scrollablePreview = new JScrollPane(previewPanel);
+ scrollablePreview.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ scrollablePreview.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+ scrollablePreview.setPreferredSize(new Dimension(599, 750));
+ scrollablePreview.getVerticalScrollBar().setUnitIncrement(16); // 璁剧疆婊氬姩閫熷害
+ scrollablePreview.setBorder(BorderFactory.createEtchedBorder());
+ pdfDialog.add(scrollablePreview, BorderLayout.CENTER);
+
+ // 鍒涘缓搴曢儴鎸夐挳闈㈡澘
+ JPanel buttonPanel = new JPanel();
+ JButton confirmBtn = GenerateCustomizeComponent.createPrimaryButton("纭閫夋嫨",DEFAULT_FONT);
+ JButton cancelBtn = GenerateCustomizeComponent.createStyledButton("鍙栨秷",DEFAULT_FONT);
+
+ confirmBtn.addActionListener(e -> {
+ Rectangle2D selection = previewPanel.getSelection();
+ if (selection != null) {
+ // 杞崲涓篜DF鍧愭爣锛堣�冭檻缂╂斁鍜屽钩绉伙級
+ Point translation = previewPanel.getTranslation();
+ float scale = previewPanel.getScale();
+
+ // 璁$畻閫夋嫨鍖哄煙鍦≒DF鏂囨。涓殑瀹為檯鍧愭爣
+ float pdfX = (float)((selection.getX() - translation.x) / scale);
+ float pdfY = (float)((selection.getY() - translation.y) / scale);
+ float pdfWidthSel = (float)(selection.getWidth() / scale);
+ float pdfHeightSel = (float)(selection.getHeight() / scale);
+
+ // 淇濆瓨閫夋嫨淇℃伅
+ savePdfSelectionInfo(pageNumber, pdfX, pdfY, pdfWidthSel, pdfHeightSel);
+
+ String coordsInfo = String.format(
+ "鏂扮殑鍖哄煙鍧愭爣: X: %.2f, Y: %.2f, W: %.2f, H: %.2f",
+ pdfX, pdfY, pdfWidthSel, pdfHeightSel
+ );
+
+ log(coordsInfo);
+// JOptionPane.showMessageDialog(pdfDialog, "纭閫夋嫨璇ュ尯鍩�?", "鍖哄煙鍧愭爣", JOptionPane.INFORMATION_MESSAGE);
+ } else {
+ JOptionPane.showMessageDialog(pdfDialog, "璇峰厛閫夋嫨鍖哄煙", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+ return;
+ }
+ pdfDialog.dispose();
+ });
+
+ cancelBtn.addActionListener(e -> pdfDialog.dispose());
+
+ buttonPanel.add(confirmBtn);
+ buttonPanel.add(cancelBtn);
+ pdfDialog.add(buttonPanel, BorderLayout.SOUTH);
+
+ pdfDialog.setVisible(true);
+
+ } catch (Exception e) {
+ log("鍔犺浇PDF澶辫触: " + e.getMessage());
+ JOptionPane.showMessageDialog(supper, "鍔犺浇PDF澶辫触: " + e.getMessage(), "閿欒", JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ }
+
+
+ // 淇濆瓨PDF鍖哄煙閫夋嫨淇℃伅鍒板亸濂借缃�
+ private void savePdfSelectionInfo(int pageNumber, float x, float y, float width, float height) {
+// prefs.put(PREF_PDF_PATH, pdfFile.getAbsolutePath());
+ prefs.putInt(PREF_PDF_PAGE, pageNumber);
+ prefs.putFloat(PREF_PDF_X, x);
+ prefs.putFloat(PREF_PDF_Y, y);
+ prefs.putFloat(PREF_PDF_WIDTH, width);
+ prefs.putFloat(PREF_PDF_HEIGHT, height);
+
+ // 鏇存柊鐣岄潰鏄剧ず
+ showLastPdfSelectionInfo();
+ }
+
+ private void loadLastPaths() {
+ String lastDirPath = prefs.get("lastOutputDir", "");
+ if (!lastDirPath.isEmpty()) {
+ File lastDir = new File(lastDirPath);
+ if (lastDir.exists() && lastDir.isDirectory()) {
+ outputDirectory = lastDir;
+ outputDirLabel.setText(outputDirectory.getAbsolutePath());
+ log("宸插姞杞戒笂娆′娇鐢ㄧ殑杈撳嚭鐩綍: " + outputDirectory.getAbsolutePath());
+ }
+ }
+ }
+
+ // 鏄剧ず涓婃閫夋嫨鐨凱DF鍖哄煙淇℃伅 - 淇浜嗙被鍨嬭浆鎹㈤棶棰�
+ private void showLastPdfSelectionInfo() {
+
+ float x = prefs.getFloat(PREF_PDF_X, 0);
+ float y = prefs.getFloat(PREF_PDF_Y, 0);
+ float width = prefs.getFloat(PREF_PDF_WIDTH, 0);
+ float height = prefs.getFloat(PREF_PDF_HEIGHT, 0);
+
+ String info = String.format("涓婃閫夋嫨鍖哄煙: - X: %.2f, Y: %.2f, W: %.2f, H: %.2f",
+ x, y, width, height);
+
+ // 鐩存帴浣跨敤鎴愬憳鍙橀噺鏇存柊涓婃閫夋嫨淇℃伅锛岄伩鍏嶇粍浠舵煡鎵�
+ lastSelectionLabel.setText(info);
+ log(info);
+ }
+
+ private void log(final String message) {
+ SwingUtilities.invokeLater(() -> {
+ String timestamp = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
+ logArea.append("["+timestamp+"] "+message + "\n");
+ logArea.setCaretPosition(logArea.getDocument().getLength());
+ });
+ }
+
+ /**
+ * 鎴彇pdf鏂囦欢鎸囧畾鍖哄煙鐨勫浘鍍�
+ * @param pdfFile pdf鏂囦欢
+ * @param prefs 閫夊尯淇℃伅
+ */
+ private String capturePdfArea(File pdfFile, Preferences prefs) throws IOException {
+ try (PDDocument document = PDDocument.load(Files.newInputStream(pdfFile.toPath()))) {
+ int page = prefs.getInt(PREF_PDF_PAGE, 0); // 杞崲涓虹敤鎴峰弸濂界殑椤电爜锛堜粠1寮�濮嬶級
+ float x = prefs.getFloat(PREF_PDF_X, 0);
+ float y = prefs.getFloat(PREF_PDF_Y, 0);
+ float width = prefs.getFloat(PREF_PDF_WIDTH, 0);
+ float height = prefs.getFloat(PREF_PDF_HEIGHT, 0);
+ if (page < 0 || page > document.getNumberOfPages()) {
+ throw new IllegalArgumentException("椤电爜瓒呭嚭鑼冨洿: " + page);
+ }
+ PDFRenderer pdfRenderer = new PDFRenderer(document);
+ BufferedImage pageImage = pdfRenderer.renderImage(page);
+ document.close();
+ BufferedImage croppedImage = cropImage(pageImage, (int) x, (int) y, (int) width, (int) height);
+ //淇濆瓨鍥剧墖
+ File cacheDir = OcrSwingConstants.cacheDir;
+ String outputFilePath =cacheDir.getAbsolutePath() + File.separator + UUID.randomUUID() + ".png";
+ boolean saved = ToFile.saveImage(croppedImage, outputFilePath, "png");
+ if(saved){
+ return outputFilePath;
+ }
+ return "";
+ }
+ }
+
+ /**
+ * 瑁佸壀鍥惧儚鎸囧畾鍖哄煙
+ * @param originalImage 鍘熷鍥惧儚
+ * @param x 宸︿笂瑙� x 鍧愭爣
+ * @param y 宸︿笂瑙� y 鍧愭爣
+ * @param width 瑁佸壀瀹藉害
+ * @param height 瑁佸壀楂樺害
+ * @return 瑁佸壀鍚庣殑鍥惧儚
+ */
+ private static BufferedImage cropImage(BufferedImage originalImage, int x, int y, int width, int height) {
+ return originalImage.getSubimage(x, y, width, height);
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/swingui/swing/jpanel/MultipleAreaProcessPanel.java b/src/main/java/com/xindao/ocr/swingui/swing/jpanel/MultipleAreaProcessPanel.java
new file mode 100644
index 0000000..e18d844
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/swingui/swing/jpanel/MultipleAreaProcessPanel.java
@@ -0,0 +1,1166 @@
+package com.xindao.ocr.swingui.swing.jpanel;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.support.ExcelTypeEnum;
+import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import com.xindao.ocr.swingui.constant.OcrSwingConstants;
+import com.xindao.ocr.swingui.service.OcrService;
+import com.xindao.ocr.swingui.swing.FileProcessorApp;
+import com.xindao.ocr.swingui.swing.utils.FileNameValidator;
+import com.xindao.ocr.swingui.swing.utils.GenerateCustomizeComponent;
+import com.xindao.ocr.swingui.swing.utils.ToFile;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.rendering.PDFRenderer;
+
+import javax.swing.*;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.LineBorder;
+import javax.swing.filechooser.FileNameExtensionFilter;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * 澶氬尯鍩熷鐞嗛潰鏉�
+ */
+public class MultipleAreaProcessPanel {
+
+ private Color BACKGROUND_COLOR;
+ private Color PRIMARY_COLOR;
+ private Color TEXT_COLOR;
+ private DefaultListModel<String> batchFileListModel;
+ private JList<String> batchFileList;
+ private JTextArea batchLogArea;
+ private List<RectArea> selectedAreas; // 鐢ㄤ簬瀛樺偍閫夋嫨鐨勫尯鍩熶俊鎭�
+ private OcrService ocrService;
+
+ private Font DEFAULT_FONT;
+ private FileProcessorApp supper;
+
+ public MultipleAreaProcessPanel(
+ FileProcessorApp supper,
+ OcrService ocrService,
+ Color BACKGROUND_COLOR,
+ Color PRIMARY_COLOR,
+ Color TEXT_COLOR,
+ Font DEFAULT_FONT) {
+ this.BACKGROUND_COLOR = BACKGROUND_COLOR;
+ this.PRIMARY_COLOR = PRIMARY_COLOR;
+ this.TEXT_COLOR = TEXT_COLOR;
+
+ this.supper = supper;
+ this.ocrService = ocrService;
+ this.DEFAULT_FONT = DEFAULT_FONT;
+
+ }
+
+ public JPanel initPanel() {
+ // 鍒涘缓鍔熻兘鎵╁睍鏍囩椤�
+ JPanel extensionPanel = new JPanel(new BorderLayout(15, 15));
+ extensionPanel.setBorder(new EmptyBorder(15, 15, 15, 15));
+ extensionPanel.setBackground(BACKGROUND_COLOR);
+
+ // 椤堕儴鍗$墖锛氭壒閲忓鐞嗘搷浣滃尯鍩�
+ JPanel topCard2 = GenerateCustomizeComponent.createCardPanel();
+ topCard2.setLayout(new BoxLayout(topCard2, BoxLayout.Y_AXIS));
+ topCard2.setBorder(new EmptyBorder(20, 20, 20, 20));
+
+ // 娣诲姞鏍囬 - 灞呬腑鏄剧ず
+ JPanel titlePanel2 = new JPanel(new GridBagLayout());
+ titlePanel2.setOpaque(false);
+ JLabel titleLabel2 = new JLabel("PDF澶氬尯鍩熸枃鏈瘑鍒�");
+ titleLabel2.setFont(new Font(DEFAULT_FONT.getName(), Font.BOLD, 18));
+ titleLabel2.setForeground(PRIMARY_COLOR);
+ titleLabel2.setBorder(new EmptyBorder(0, 0, 15, 0));
+ titlePanel2.add(titleLabel2);
+
+ topCard2.add(titlePanel2);
+ topCard2.add(Box.createVerticalStrut(10));
+
+ // 鎵归噺澶勭悊鎸夐挳鍖哄煙
+ JPanel batchTopPanel = GenerateCustomizeComponent.createStyledPanel(new FlowLayout(FlowLayout.LEFT, 10, 10));
+
+ JButton selectBatchFilesBtn = GenerateCustomizeComponent.createStyledButton("閫夋嫨PDF鏂囦欢", DEFAULT_FONT);
+ JButton selectBatchAreaBtn = GenerateCustomizeComponent.createStyledButton("閫夋嫨PDF鍖哄煙", DEFAULT_FONT);
+ JButton removeSelectedBtn = GenerateCustomizeComponent.createStyledButton("绉婚櫎閫変腑鏂囦欢", DEFAULT_FONT);
+ JButton clearAllBtn = GenerateCustomizeComponent.createStyledButton("娓呯┖鍒楄〃", DEFAULT_FONT);
+ JButton exportBatchBtn = GenerateCustomizeComponent.createPrimaryButton("澶勭悊鏂囦欢", DEFAULT_FONT);
+
+ batchTopPanel.add(selectBatchFilesBtn);
+ batchTopPanel.add(selectBatchAreaBtn);
+ batchTopPanel.add(removeSelectedBtn);
+ batchTopPanel.add(clearAllBtn);
+ batchTopPanel.add(exportBatchBtn);
+
+ // 宸查�夋嫨鏂囦欢鍒楄〃鍖哄煙
+ JPanel fileListPanel = GenerateCustomizeComponent.createStyledPanel(new BorderLayout());
+ fileListPanel.setBorder(new EmptyBorder(10, 0, 0, 0));
+
+ JLabel fileListTitleLabel = new JLabel("宸查�夋嫨鐨凱DF鏂囦欢");
+ fileListTitleLabel.setFont(new Font(DEFAULT_FONT.getName(), Font.BOLD, 14));
+ fileListTitleLabel.setForeground(TEXT_COLOR);
+ fileListTitleLabel.setBorder(new EmptyBorder(0, 0, 5, 0));
+
+ batchFileListModel = new DefaultListModel<>();
+ batchFileList = new JList<>(batchFileListModel);
+ batchFileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+ batchFileList.setFont(DEFAULT_FONT);
+ JScrollPane fileListScrollPane = new JScrollPane(batchFileList);
+ fileListScrollPane.setPreferredSize(new Dimension(-1, 150));
+ fileListScrollPane.setBorder(new CompoundBorder(
+ new LineBorder(new Color(220, 220, 220)),
+ new EmptyBorder(5, 5, 5, 5)));
+
+ fileListPanel.add(fileListTitleLabel, BorderLayout.NORTH);
+ fileListPanel.add(fileListScrollPane, BorderLayout.CENTER);
+
+ // 娣诲姞鍒伴《閮ㄥ崱鐗�
+ topCard2.add(batchTopPanel);
+ topCard2.add(fileListPanel);
+
+ // 搴曢儴鍗$墖锛氭壒閲忓鐞嗘棩蹇楀尯鍩�
+ JPanel bottomCard2 = GenerateCustomizeComponent.createCardPanel();
+ bottomCard2.setLayout(new BorderLayout());
+ bottomCard2.setBorder(new EmptyBorder(15, 15, 15, 15));
+
+ JLabel logTitleLabel2 = new JLabel("澶勭悊鏃ュ織");
+ logTitleLabel2.setFont(new Font(DEFAULT_FONT.getName(), Font.BOLD, 14));
+ logTitleLabel2.setForeground(TEXT_COLOR);
+ logTitleLabel2.setBorder(new EmptyBorder(0, 0, 10, 0));
+
+ batchLogArea = new JTextArea();
+ batchLogArea.setEditable(false);
+ batchLogArea.setLineWrap(true);
+ batchLogArea.setFont(DEFAULT_FONT);
+ batchLogArea.setBackground(new Color(250, 250, 250));
+ batchLogArea.setBorder(new CompoundBorder(
+ new LineBorder(new Color(220, 220, 220)),
+ new EmptyBorder(5, 5, 5, 5)));
+
+ JScrollPane logScrollPane = new JScrollPane(batchLogArea);
+ logScrollPane.setBorder(null);
+ logScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+
+ bottomCard2.add(logTitleLabel2, BorderLayout.NORTH);
+ bottomCard2.add(logScrollPane, BorderLayout.CENTER);
+
+ // 娣诲姞椤堕儴鍗$墖鍜屽簳閮ㄥ崱鐗囧埌鍔熻兘鎵╁睍鏍囩椤�
+ extensionPanel.add(topCard2, BorderLayout.NORTH);
+ extensionPanel.add(bottomCard2, BorderLayout.CENTER);
+
+ // 娣诲姞浜嬩欢鐩戝惉鍣�
+ // 涓烘壒閲忓鐞嗘寜閽坊鍔犱簨浠剁洃鍚櫒
+ selectBatchFilesBtn.addActionListener(e -> selectBatchFiles());
+ selectBatchAreaBtn.addActionListener(e -> loadLastSelectedAreas());
+ removeSelectedBtn.addActionListener(e -> removeSelectedBatchFiles());
+ clearAllBtn.addActionListener(e -> clearAllBatchFiles());
+ exportBatchBtn.addActionListener(e -> batchProcessAndExport());
+
+ // 娣诲姞涓�浜涘垵濮嬫棩蹇椾俊鎭紝楠岃瘉鏃ュ織鍖哄煙鏄惁姝e父宸ヤ綔
+ appendLog("PDF澶氬尯鍩熸枃鏈瘑鍒伐鍏峰凡鍒濆鍖�");
+ appendLog("璇烽�夋嫨PDF鏂囦欢骞惰缃瘑鍒尯鍩�");
+
+ return extensionPanel;
+ }
+
+ /**
+ * 鎵归噺澶勭悊鏂囦欢鏂规硶
+ */
+ private void batchProcessAndExport(){
+ if (batchFileListModel.isEmpty()) {
+ JOptionPane.showMessageDialog(supper, "璇峰厛閫夋嫨瑕佸鐞嗙殑鏂囦欢", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+ return;
+ }
+
+ if (selectedAreas == null || selectedAreas.isEmpty()) {
+ JOptionPane.showMessageDialog(supper, "璇峰厛閫夋嫨PDF鍖哄煙", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+ return;
+ }
+
+ // 鏄剧ず鏂囦欢閫夋嫨瀵硅瘽妗嗚鐢ㄦ埛閫夋嫨杈撳嚭鐩綍
+ JFileChooser dirChooser = new JFileChooser();
+ dirChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ dirChooser.setDialogTitle("閫夋嫨杈撳嚭鐩綍");
+ int result = dirChooser.showDialog(null, "閫夋嫨");
+ if (result != JFileChooser.APPROVE_OPTION) {
+ appendLog("鐢ㄦ埛鍙栨秷浜嗚緭鍑虹洰褰曢�夋嫨");
+ return;
+ }
+ File outputDirectory = dirChooser.getSelectedFile();
+ appendLog("杈撳嚭鐩綍: " + outputDirectory.getAbsolutePath());
+
+ appendLog("寮�濮嬪鐞嗘枃浠�...");
+
+ // 鍒涘缓涓�涓嚎绋嬫睜鏉ュ苟琛屽鐞嗘枃浠�
+ SwingWorker<Void, String> worker = new SwingWorker<Void, String>() {
+ @Override
+ protected Void doInBackground() {
+ int processedCount = 0;
+ int successCount = 0;
+ int failCount = 0;
+
+ //鍒濆鍖杄xcel琛ㄥご
+ List<List<String>> tableHeader = new ArrayList<>();
+ selectedAreas.forEach(s->tableHeader.add(Collections.singletonList(s.getName())));
+
+ //璇嗗埆鍒扮殑鏁版嵁
+ List<List<String>> tableData = new ArrayList<>();
+
+ // 閬嶅巻鎵�鏈夐�夋嫨鐨勬枃浠�
+ for (int i = 0; i < batchFileListModel.size(); i++) {
+ String listItem = batchFileListModel.getElementAt(i);
+ // 浠庡垪琛ㄩ」涓彁鍙栨枃浠惰矾寰勶紙鍋囪鏍煎紡涓� "鏂囦欢鍚� (璺緞)"锛�
+ int startIndex = listItem.lastIndexOf('(') + 1;
+ int endIndex = listItem.lastIndexOf(')');
+ if (startIndex > 0 && endIndex > startIndex) {
+ String filePath = listItem.substring(startIndex, endIndex);
+ File pdfFile = new File(filePath);
+ processedCount++;
+
+ try {
+ // 澶勭悊鍗曚釜PDF鏂囦欢
+ List<String> ocrResults = processSinglePdfFile(pdfFile, outputDirectory);
+ tableData.add(ocrResults);
+ successCount++;
+ appendLog("鏂囦欢澶勭悊鎴愬姛(" + processedCount + "/" + batchFileListModel.size() + "): " + pdfFile.getName());
+ } catch (Exception e) {
+ failCount++;
+ appendLog("鏂囦欢澶勭悊澶辫触: " + pdfFile.getName() + " - " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+ }
+
+ //瀵煎嚭excel鏂囦欢
+ try {
+ String outputExcelFileName = "璇嗗埆缁撴灉_" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + ExcelTypeEnum.XLSX.getValue();
+ File outputExcelFile = new File(outputDirectory, outputExcelFileName);
+ if (!outputExcelFile.getParentFile().exists()) {
+ outputExcelFile.getParentFile().mkdirs();
+ }
+ EasyExcel.write(outputExcelFile)
+ .head(tableHeader)
+ .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
+ .sheet()
+ .doWrite(tableData);
+ appendLog("鏂囦欢宸插鍑哄埌: " + outputExcelFile.getAbsolutePath());
+ } catch (Exception e) {
+ appendLog("鏂囦欢瀵煎嚭澶辫触: " + e.getMessage());
+ }
+ // 杈撳嚭澶勭悊缁熻淇℃伅
+ publish("鎴愬姛: " + successCount + ",閿欒: " + failCount);
+ return null;
+ }
+
+ @Override
+ protected void process(List<String> chunks) {
+ for (String message : chunks) {
+ appendLog(message);
+ }
+ }
+
+ @Override
+ protected void done() {
+ appendLog("鎵�鏈夋枃浠跺鐞嗗畬鎴�");
+ }
+ };
+
+ worker.execute();
+ }
+
+ /**
+ * 澶勭悊鍗曚釜PDF鏂囦欢
+ */
+ private List<String> processSinglePdfFile(File pdfFile, File outputDirectory) throws IOException {
+ // 纭繚杈撳嚭鐩綍瀛樺湪
+ if (!outputDirectory.exists()) {
+ outputDirectory.mkdirs();
+ }
+
+ // 鍒涘缓褰撳墠PDF鏂囦欢鐨勭粨鏋滅洰褰�
+ String fileNameWithoutExt = pdfFile.getName().substring(0, pdfFile.getName().lastIndexOf('.'));
+
+ // 鍔犺浇PDF鏂囨。
+ PDDocument document = null;
+ try {
+ document = PDDocument.load(pdfFile);
+ PDFRenderer renderer = new PDFRenderer(document);
+
+ List<String> ocrResults = new ArrayList<>();
+
+ // 澶勭悊姣忎釜宸查�夋嫨鐨勫尯鍩�
+ for (RectArea area : selectedAreas) {
+ int pageIndex = area.getPageIndex();
+ if (pageIndex >= document.getNumberOfPages()) {
+ appendLog("璀﹀憡: 鍖哄煙\"" + area.getName() + "\"鎸囧畾鐨勯〉鐮佷笉瀛樺湪锛屽皢璺宠繃姝ゅ尯鍩�");
+ continue;
+ }
+
+ // 娓叉煋褰撳墠椤�
+ BufferedImage pageImage = renderer.renderImageWithDPI(pageIndex, 72);
+ // 鎴彇鍖哄煙鍥惧儚
+ BufferedImage areaImage = extractAreaImage(pageImage, area);
+
+ // 缂撳瓨鍖哄煙鍥惧儚
+ //淇濆瓨鍥剧墖
+ File cacheDir = OcrSwingConstants.cacheDir;
+ String outputFilePath =cacheDir.getAbsolutePath() + File.separator + UUID.randomUUID() + ".png";
+ boolean saved = ToFile.saveImage(areaImage, outputFilePath, "png");
+// ImageIO.write(areaImage, "PNG", areaImageFile);
+ if(saved){
+ // 瀵瑰尯鍩熷浘鍍忚繘琛孫CR璇嗗埆
+ String ocrResult = recognizeAreaText(new File(outputFilePath));
+ ocrResults.add(ocrResult);
+ }
+ }
+ return ocrResults;
+ } finally {
+ if (document != null) {
+ document.close();
+ }
+ //鍒犻櫎涓存椂鐩綍
+ ToFile.deleteTempFiles(OcrSwingConstants.cacheDir);
+ }
+ }
+
+ /**
+ * 浠庨〉闈㈠浘鍍忎腑鎴彇鎸囧畾鍖哄煙鐨勫浘鍍�
+ */
+ private BufferedImage extractAreaImage(BufferedImage pageImage, RectArea area) {
+ // 纭繚鎴彇鍖哄煙鍦ㄥ浘鍍忚寖鍥村唴
+ int x = Math.max(0, area.getX());
+ int y = Math.max(0, area.getY());
+ int width = Math.min(area.getWidth(), pageImage.getWidth() - x);
+ int height = Math.min(area.getHeight(), pageImage.getHeight() - y);
+
+ // 鍒涘缓鎴彇鐨勫浘鍍�
+ return pageImage.getSubimage(x, y, width, height);
+ }
+
+ /**
+ * 瀵瑰尯鍩熷浘鍍忚繘琛孫CR鏂囨湰璇嗗埆,杩斿洖璇嗗埆鍒扮殑绗竴涓粨鏋�
+ */
+ private String recognizeAreaText(File imageFile) throws IOException {
+ // 浣跨敤ocrService杩涜鏂囨湰璇嗗埆
+ String fullText = ocrService.ocr(imageFile.getAbsolutePath());
+ if(fullText != null && !fullText.isEmpty()){
+ fullText = FileNameValidator.validateAndCleanFileName(fullText);
+ }
+ return fullText;
+ }
+
+
+ // 鐢ㄤ簬瀛樺偍閫夋嫨鐨凱DF妯℃澘鏂囦欢璺緞
+ private String selectedTemplatePdfPath = null;
+
+ // 鐢ㄤ簬JSON搴忓垪鍖栧拰鍙嶅簭鍒楀寲鐨凮bjectMapper
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
+ // 瀛樺偍鍖哄煙淇℃伅鐨勯厤缃枃浠惰矾寰�
+ private static final String CONFIG_DIR = OcrSwingConstants.pdfToolDir.getAbsolutePath();
+ private static final String CONFIG_FILE = "template_areas.json";
+
+ /**
+ * 琛ㄧずPDF涓殑涓�涓煩褰㈠尯鍩�
+ * 鏀寔JSON搴忓垪鍖栧拰鍙嶅簭鍒楀寲
+ */
+ public static class RectArea {
+ private int pageIndex; // 椤电爜绱㈠紩
+ private int x; // GUI涓殑宸︿笂瑙抶鍍忕礌鍧愭爣
+ private int y; // GUI涓殑宸︿笂瑙抷鍍忕礌鍧愭爣
+ private int width; // GUI涓殑瀹藉害鍍忕礌
+ private int height; // GUI涓殑楂樺害鍍忕礌
+ private String name; // 鍖哄煙鍚嶇О
+ private float pdfX; // PDF涓殑宸︿笂瑙抶鍧愭爣锛堢偣锛�
+ private float pdfY; // PDF涓殑宸︿笂瑙抷鍧愭爣锛堢偣锛�
+ private float pdfWidth; // PDF涓殑瀹藉害锛堢偣锛�
+ private float pdfHeight;// PDF涓殑楂樺害锛堢偣锛�
+
+ // 鏃犲弬鏋勯�犲嚱鏁帮紝鐢ㄤ簬JSON鍙嶅簭鍒楀寲
+ public RectArea() {
+ }
+
+ public RectArea(int pageIndex, int x, int y, int width, int height, String name) {
+ this.pageIndex = pageIndex;
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ this.name = name;
+ // 杩欎簺PDF鍧愭爣浼氬湪杞崲鏃惰缃�
+ this.pdfX = 0;
+ this.pdfY = 0;
+ this.pdfWidth = 0;
+ this.pdfHeight = 0;
+ }
+
+ // 璁剧疆PDF鍧愭爣
+ public void setPdfCoordinates(float pdfX, float pdfY, float pdfWidth, float pdfHeight) {
+ this.pdfX = pdfX;
+ this.pdfY = pdfY;
+ this.pdfWidth = pdfWidth;
+ this.pdfHeight = pdfHeight;
+ }
+
+ @Override
+ public String toString() {
+ return "椤甸潰" + (pageIndex + 1) + " - " + name +
+ " [PDF: (" + String.format("%.2f", pdfX) + "," +
+ String.format("%.2f", pdfY) + "," +
+ String.format("%.2f", pdfWidth) + "," +
+ String.format("%.2f", pdfHeight) + ")]";
+ }
+
+ // Getters and setters for JSON serialization
+ public int getPageIndex() {
+ return pageIndex;
+ }
+
+ public void setPageIndex(int pageIndex) {
+ this.pageIndex = pageIndex;
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ public int getY() {
+ return y;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public float getPdfX() {
+ return pdfX;
+ }
+
+ public void setPdfX(float pdfX) {
+ this.pdfX = pdfX;
+ }
+
+ public float getPdfY() {
+ return pdfY;
+ }
+
+ public void setPdfY(float pdfY) {
+ this.pdfY = pdfY;
+ }
+
+ public float getPdfWidth() {
+ return pdfWidth;
+ }
+
+ public void setPdfWidth(float pdfWidth) {
+ this.pdfWidth = pdfWidth;
+ }
+
+ public float getPdfHeight() {
+ return pdfHeight;
+ }
+
+ public void setPdfHeight(float pdfHeight) {
+ this.pdfHeight = pdfHeight;
+ }
+ }
+
+ /**
+ * 灏濊瘯鍔犺浇涓婃淇濆瓨鐨勫尯鍩熶俊鎭紝璇㈤棶鐢ㄦ埛鏄惁浣跨敤
+ */
+ private void selectBatchPdfArea() {
+ selectBatchPdfArea(true);
+ }
+
+ /**
+ * 灏濊瘯鍔犺浇涓婃淇濆瓨鐨勫尯鍩熶俊鎭紝璇㈤棶鐢ㄦ埛鏄惁浣跨敤
+ */
+ private void loadLastSelectedAreas() {
+ try {
+ File configDir = new File(CONFIG_DIR);
+ File configFile = new File(configDir, CONFIG_FILE);
+
+ if (!configFile.exists()) {
+ // 娌℃湁閰嶇疆鏂囦欢锛屾墽琛屽師濮嬬殑閫夋嫨娴佺▼
+ selectBatchPdfArea(true);
+ return;
+ }
+
+ // 鐩存帴璇诲彇鍖哄煙鍒楄〃锛屼笉鍐嶅叧鑱旀ā鏉挎枃浠�
+ TypeReference<List<RectArea>> typeRef = new TypeReference<List<RectArea>>() {};
+ List<RectArea> areas = objectMapper.readValue(configFile, typeRef);
+
+ if (areas.isEmpty()) {
+ // 閰嶇疆鏂囦欢涓虹┖锛屾墽琛屽師濮嬬殑閫夋嫨娴佺▼
+ selectBatchPdfArea(true);
+ return;
+ }
+
+ // 璇㈤棶鐢ㄦ埛鏄惁浣跨敤涓婃鐨勫尯鍩熼厤缃�
+ int choice = JOptionPane.showConfirmDialog(
+ null, // 浣跨敤null浣滀负鐖剁粍浠�
+ "妫�娴嬪埌涓婃淇濆瓨鐨勫尯鍩熼厤缃紝鏄惁浣跨敤锛焅n\n" +
+ "鍖哄煙鏁伴噺: " + areas.size() + " 涓�",
+ "浣跨敤涓婃鐨勫尯鍩熼厤缃�",
+ JOptionPane.YES_NO_OPTION,
+ JOptionPane.QUESTION_MESSAGE
+ );
+
+ if (choice == JOptionPane.YES_OPTION) {
+ // 鐢ㄦ埛閫夋嫨浣跨敤涓婃鐨勯厤缃紝浣嗕笉璁剧疆selectedTemplatePdfPath
+ selectedAreas = areas;
+ appendLog("宸插姞杞戒笂娆′繚瀛樼殑鍖哄煙閰嶇疆");
+
+ // 鍦ㄦ棩蹇椾腑鏄剧ず姣忎釜鍖哄煙鐨勪俊鎭�
+// for (RectArea area : selectedAreas) {
+// appendLog("鍖哄煙: " + area.toString());
+// }
+ } else {
+ // 鐢ㄦ埛閫夋嫨涓嶄娇鐢ㄤ笂娆$殑閰嶇疆锛屾墽琛屽師濮嬬殑閫夋嫨娴佺▼
+ appendLog("鐢ㄦ埛閫夋嫨涓嶄娇鐢ㄤ笂娆$殑鍖哄煙閰嶇疆");
+ selectBatchPdfArea(false);
+ }
+ } catch (Exception e) {
+ appendLog("鍔犺浇涓婃淇濆瓨鐨勫尯鍩熼厤缃け璐�: " + e.getMessage());
+ e.printStackTrace();
+ // 鍙戠敓寮傚父鏃讹紝缁х画浣跨敤鍘熷鐨勯�夋嫨娴佺▼
+ selectBatchPdfArea(true);
+ }
+ }
+
+ /**
+ * 淇濆瓨鍖哄煙淇℃伅鍒伴厤缃枃浠�
+ */
+ private void saveAreasToConfig() {
+ if (selectedAreas == null || selectedAreas.isEmpty()) {
+ return;
+ }
+
+ try {
+ // 鍒涘缓閰嶇疆鐩綍
+ File configDir = new File(CONFIG_DIR);
+ if (!configDir.exists()) {
+ configDir.mkdirs();
+ }
+
+ // 鐩存帴淇濆瓨鍖哄煙鍒楄〃锛屼笉鍐嶅叧鑱旀ā鏉挎枃浠�
+ File configFile = new File(configDir, CONFIG_FILE);
+ objectMapper.writeValue(configFile, selectedAreas);
+ appendLog("鍖哄煙閰嶇疆宸蹭繚瀛樺埌鏂囦欢");
+ } catch (Exception e) {
+ appendLog("淇濆瓨鍖哄煙閰嶇疆澶辫触: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 浠庨厤缃枃浠跺姞杞藉尯鍩熶俊鎭�
+ */
+ private List<RectArea> loadAreasFromConfig(String templatePath) {
+ List<RectArea> areas = new ArrayList<>();
+
+ try {
+ File configDir = new File(CONFIG_DIR);
+ File configFile = new File(configDir, CONFIG_FILE);
+
+ if (!configFile.exists()) {
+ return areas;
+ }
+
+ // 鐩存帴璇诲彇鍖哄煙鍒楄〃锛屼笉鍐嶆鏌ユā鏉胯矾寰�
+ TypeReference<List<RectArea>> typeRef = new TypeReference<List<RectArea>>() {};
+ areas = objectMapper.readValue(configFile, typeRef);
+
+ if (!areas.isEmpty()) {
+ appendLog("宸插姞杞� " + areas.size() + " 涓繚瀛樼殑鍖哄煙閰嶇疆");
+ }
+ } catch (Exception e) {
+ appendLog("鍔犺浇鍖哄煙閰嶇疆澶辫触: " + e.getMessage());
+ e.printStackTrace();
+ }
+
+ return areas;
+ }
+
+ /**
+ * 閫夋嫨PDF鍖哄煙鏂规硶
+ * @param loadSavedAreas 鏄惁灏濊瘯鍔犺浇宸蹭繚瀛樼殑鍖哄煙閰嶇疆
+ */
+ private void selectBatchPdfArea(boolean loadSavedAreas) {
+ // 鍒涘缓鏂囦欢閫夋嫨鍣ㄩ�夋嫨妯℃澘PDF
+ JFileChooser fileChooser = new JFileChooser();
+ fileChooser.setFileFilter(new FileNameExtensionFilter("PDF鏂囦欢 (*.pdf)", "pdf"));
+ int result = fileChooser.showOpenDialog(supper);
+
+ if (result == JFileChooser.APPROVE_OPTION) {
+ File selectedFile = fileChooser.getSelectedFile();
+ selectedTemplatePdfPath = selectedFile.getAbsolutePath();
+
+ // 鏄惁灏濊瘯鍔犺浇宸蹭繚瀛樼殑鍖哄煙閰嶇疆
+ if (loadSavedAreas) {
+ // 棣栧厛灏濊瘯鍔犺浇宸蹭繚瀛樼殑鍖哄煙閰嶇疆
+ List<RectArea> savedAreas = loadAreasFromConfig(selectedTemplatePdfPath);
+
+ if (!savedAreas.isEmpty()) {
+ // 濡傛灉鏈変繚瀛樼殑鍖哄煙淇℃伅锛岀洿鎺ヤ娇鐢�
+ selectedAreas = savedAreas;
+ appendLog("浣跨敤宸蹭繚瀛樼殑鍖哄煙閰嶇疆");
+
+ return;
+ }
+ // 濡傛灉灏濊瘯鍔犺浇浣嗘病鏈変繚瀛樼殑鍖哄煙淇℃伅锛岀户缁墽琛屼笅闈㈢殑浠g爜鎵撳紑瀵硅瘽妗�
+ }
+
+ // 鏃犺loadSavedAreas鏄粈涔堝�硷紝鍙娌℃湁淇濆瓨鐨勫尯鍩熶俊鎭垨鐢ㄦ埛閫夋嫨涓嶅姞杞藉凡淇濆瓨鐨勯厤缃紝閮芥墦寮�鍖哄煙閫夋嫨瀵硅瘽妗�
+ PdfAreaSelectionDialog dialog = new PdfAreaSelectionDialog(selectedTemplatePdfPath);
+ dialog.setModal(true);
+ dialog.setVisible(true);
+
+ if (dialog.isConfirmed()) {
+ // 鑾峰彇鐢ㄦ埛閫夋嫨鐨勫尯鍩�
+ selectedAreas = dialog.getSelectedAreas();
+ appendLog("宸查�夋嫨 " + selectedAreas.size() + " 涓狿DF鍖哄煙");
+
+ // 淇濆瓨鐢ㄦ埛閫夋嫨鐨勫尯鍩熼厤缃�
+ saveAreasToConfig();
+ }
+ } else {
+ appendLog("鐢ㄦ埛鍙栨秷浜嗘ā鏉縋DF閫夋嫨");
+ }
+ }
+
+ /**
+ * PDF鍖哄煙閫夋嫨瀵硅瘽妗�
+ */
+ private class PdfAreaSelectionDialog extends JDialog {
+ private PDDocument document;
+ private int totalPages;
+ private int currentPageIndex = 0;
+ private List<RectArea> areas = new ArrayList<>();
+ private boolean confirmed = false;
+ private JPanel pdfPreviewPanel;
+ private DefaultListModel<String> areaListModel;
+ private JList<String> areaList;
+ private BufferedImage currentImage; // 褰撳墠椤甸潰鐨勫浘鍍�
+
+ public PdfAreaSelectionDialog(String pdfPath) {
+ setTitle("閫夋嫨PDF璇嗗埆鍖哄煙");
+ setSize(900, 700);
+ setLocationRelativeTo(null);
+
+ try {
+ // 鍔犺浇PDF鏂囨。
+ document = PDDocument.load(new File(pdfPath));
+ totalPages = document.getNumberOfPages();
+
+ // 灏濊瘯浠庨厤缃枃浠跺姞杞藉凡淇濆瓨鐨勫尯鍩熶俊鎭�
+ List<RectArea> savedAreas = loadAreasFromConfig(pdfPath);
+ if (!savedAreas.isEmpty()) {
+ areas = savedAreas;
+ appendLog("宸插姞杞� " + savedAreas.size() + " 涓繚瀛樼殑鍖哄煙閰嶇疆鍒扮紪杈戝璇濇");
+ }
+ } catch (IOException ex) {
+ appendLog("鍔犺浇PDF澶辫触: " + ex.getMessage());
+ JOptionPane.showMessageDialog(this, "鍔犺浇PDF澶辫触: " + ex.getMessage(), "閿欒", JOptionPane.ERROR_MESSAGE);
+ dispose();
+ return;
+ }
+
+ // 鍒涘缓涓婚潰鏉�
+ JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
+ mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
+
+ // 鍒涘缓PDF棰勮鍖哄煙
+ JPanel previewPanel = new JPanel(new BorderLayout(5, 5));
+
+ // 椤甸潰鎺у埗鎸夐挳
+ JPanel pageControlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 5));
+ JButton prevPageBtn = new JButton("涓婁竴椤�");
+ JButton nextPageBtn = new JButton("涓嬩竴椤�");
+ JLabel pageLabel = new JLabel("椤甸潰: 1 / " + totalPages);
+
+ pageControlPanel.add(prevPageBtn);
+ pageControlPanel.add(pageLabel);
+ pageControlPanel.add(nextPageBtn);
+
+ // 鍒涘缓鍙粴鍔ㄧ殑PDF棰勮闈㈡澘
+ JScrollPane scrollablePreview = new JScrollPane();
+ scrollablePreview.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ scrollablePreview.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+ scrollablePreview.setPreferredSize(new Dimension(639, 700));
+ scrollablePreview.getVerticalScrollBar().setUnitIncrement(16); // 璁剧疆婊氬姩閫熷害
+ scrollablePreview.setBorder(BorderFactory.createEtchedBorder());
+
+ // PDF棰勮闈㈡澘
+ pdfPreviewPanel = new JPanel() {
+ private Point startPoint;
+ private Point endPoint;
+ private boolean isDrawing = false;
+
+ @Override
+ protected void paintComponent(Graphics g) {
+ super.paintComponent(g);
+ // 棣栧厛缁樺埗PDF鍥惧儚
+ if (currentImage != null) {
+ g.drawImage(currentImage, 0, 0, this);
+ }
+
+ // 缁樺埗閫夋嫨妗嗭紙杩涜涓殑閫夋嫨锛�
+ if (isDrawing && startPoint != null && endPoint != null) {
+ // 缁樺埗閫夋嫨妗�
+ Graphics2D g2d = (Graphics2D) g;
+ g2d.setColor(new Color(255, 0, 0, 100)); // 浣跨敤绾㈣壊濉厖锛屾洿瀹规槗鐪嬪埌
+ int x = Math.min(startPoint.x, endPoint.x);
+ int y = Math.min(startPoint.y, endPoint.y);
+ int width = Math.abs(endPoint.x - startPoint.x);
+ int height = Math.abs(endPoint.y - startPoint.y);
+ g2d.fillRect(x, y, width, height);
+ g2d.setColor(Color.RED); // 绾㈣壊杈规
+ g2d.setStroke(new BasicStroke(2)); // 鍔犵矖杈规
+ g2d.drawRect(x, y, width, height);
+ }
+
+ // 缁樺埗宸蹭繚瀛樼殑鍖哄煙
+ for (RectArea area : areas) {
+ if (area.pageIndex == currentPageIndex) {
+ Graphics2D g2d = (Graphics2D) g;
+ g2d.setColor(new Color(0, 255, 0, 80)); // 缁胯壊鍗婇�忔槑濉厖
+ g2d.fillRect(area.x, area.y, area.width, area.height);
+ g2d.setColor(Color.GREEN); // 缁胯壊杈规
+ g2d.setStroke(new BasicStroke(2)); // 鍔犵矖杈规
+ g2d.drawRect(area.x, area.y, area.width, area.height);
+
+ // 鏄剧ず鍖哄煙鍚嶇О
+ g2d.setColor(Color.BLUE);
+ g2d.setFont(new Font("瀹嬩綋", Font.BOLD, 12));
+ g2d.drawString(area.name, area.x + 5, area.y + 15);
+ }
+ }
+ }
+
+ { // 鍒濆鍖栭紶鏍囦簨浠�
+ addMouseListener(new java.awt.event.MouseAdapter() {
+ @Override
+ public void mousePressed(java.awt.event.MouseEvent e) {
+ startPoint = e.getPoint();
+ endPoint = e.getPoint();
+ isDrawing = true;
+ }
+
+ @Override
+ public void mouseReleased(java.awt.event.MouseEvent e) {
+ endPoint = e.getPoint();
+ isDrawing = false;
+
+ // 璁$畻閫夋嫨鐨勫尯鍩�
+ int x = Math.min(startPoint.x, endPoint.x);
+ int y = Math.min(startPoint.y, endPoint.y);
+ int width = Math.abs(endPoint.x - startPoint.x);
+ int height = Math.abs(endPoint.y - startPoint.y);
+
+ // 濡傛灉閫夋嫨鐨勫尯鍩熻冻澶熷ぇ锛屾坊鍔犲埌鍒楄〃
+ if (width > 10 && height > 10) {
+ // 纭繚瀵硅瘽妗嗗湪鏈�涓婂眰
+ SwingUtilities.invokeLater(() -> {
+ String areaName = JOptionPane.showInputDialog(
+ PdfAreaSelectionDialog.this,
+ "璇疯緭鍏ュ尯鍩熷悕绉�:",
+ "鍖哄煙鍚嶇О",
+ JOptionPane.PLAIN_MESSAGE);
+ if (areaName != null && !areaName.trim().isEmpty()) {
+ // 鍒涘缓鏂板尯鍩�
+ RectArea newArea = new RectArea(currentPageIndex, x, y, width, height,
+ areaName.trim());
+ areas.add(newArea);
+
+ // 绔嬪嵆杞崲涓篜DF鍧愭爣
+ try {
+ PDPage page = document.getPage(currentPageIndex);
+ org.apache.pdfbox.pdmodel.common.PDRectangle mediaBox = page.getMediaBox();
+ float pageWidth = mediaBox.getWidth();
+ float pageHeight = mediaBox.getHeight();
+
+ // 浣跨敤褰撳墠宸叉覆鏌撶殑鍥惧儚灏哄杩涜杞崲
+ if (currentImage != null) {
+ int imageWidth = currentImage.getWidth();
+ int imageHeight = currentImage.getHeight();
+
+ float xScaleFactor = pageWidth / imageWidth;
+ float yScaleFactor = pageHeight / imageHeight;
+
+ float pdfX = x * xScaleFactor;
+ float pdfY = pageHeight - (y + height) * yScaleFactor;
+ float pdfWidth = width * xScaleFactor;
+ float pdfHeight = height * yScaleFactor;
+
+ newArea.setPdfCoordinates(pdfX, pdfY, pdfWidth, pdfHeight);
+ }
+ } catch (Exception ex) {
+ appendLog("娣诲姞鍖哄煙鏃跺潗鏍囪浆鎹㈠け璐�: " + ex.getMessage());
+ }
+
+ updateAreaList();
+ pdfPreviewPanel.repaint();
+ }
+ });
+ }
+
+ repaint();
+ }
+ });
+
+ addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
+ @Override
+ public void mouseDragged(java.awt.event.MouseEvent e) {
+ endPoint = e.getPoint();
+ repaint();
+ }
+ });
+ }
+ };
+ pdfPreviewPanel.setSize(new Dimension(599,750));
+ scrollablePreview.setViewportView(pdfPreviewPanel);
+
+ // 鍒涘缓甯﹁鐩栧眰鐨勯瑙堥潰鏉�
+ JPanel previewWithOverlay = new JPanel(new BorderLayout());
+ previewWithOverlay.add(scrollablePreview, BorderLayout.CENTER);
+
+ // 鍔犺浇绗竴椤�
+ loadPage(currentPageIndex);
+
+ // 椤甸潰鎺у埗浜嬩欢
+ prevPageBtn.addActionListener(e -> {
+ if (currentPageIndex > 0) {
+ currentPageIndex--;
+ loadPage(currentPageIndex);
+ pageLabel.setText("椤甸潰: " + (currentPageIndex + 1) + " / " + totalPages);
+ }
+ });
+
+ nextPageBtn.addActionListener(e -> {
+ if (currentPageIndex < totalPages - 1) {
+ currentPageIndex++;
+ loadPage(currentPageIndex);
+ pageLabel.setText("椤甸潰: " + (currentPageIndex + 1) + " / " + totalPages);
+ }
+ });
+
+ // 娣诲姞鍒伴瑙堥潰鏉�
+ previewPanel.add(pageControlPanel, BorderLayout.NORTH);
+ previewPanel.add(previewWithOverlay, BorderLayout.CENTER);
+
+ // 鍒涘缓鍖哄煙鍒楄〃鍜屾帶鍒舵寜閽�
+ JPanel rightPanel = new JPanel(new BorderLayout(5, 5));
+ rightPanel.setPreferredSize(new Dimension(250, -1));
+
+ // 鍖哄煙鍒楄〃
+ JPanel areaListPanel = new JPanel(new BorderLayout(5, 5));
+ JLabel areaListLabel = new JLabel("宸查�夋嫨鐨勫尯鍩�");
+ areaListModel = new DefaultListModel<>();
+ areaList = new JList<>(areaListModel);
+ JScrollPane areaListScrollPane = new JScrollPane(areaList);
+ areaListScrollPane.setPreferredSize(new Dimension(-1, 200));
+
+ areaListPanel.add(areaListLabel, BorderLayout.NORTH);
+ areaListPanel.add(areaListScrollPane, BorderLayout.CENTER);
+
+ // 鎺у埗鎸夐挳
+ JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
+ JButton removeAreaBtn = new JButton("绉婚櫎閫変腑鍖哄煙");
+ JButton clearAreasBtn = new JButton("娓呯┖鎵�鏈夊尯鍩�");
+
+ controlPanel.add(removeAreaBtn);
+ controlPanel.add(clearAreasBtn);
+
+ // 纭鍜屽彇娑堟寜閽�
+ JPanel confirmPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 10));
+ JButton confirmBtn = new JButton("纭");
+ JButton cancelBtn = new JButton("鍙栨秷");
+
+ // 娓叉煋鏃朵娇鐢ㄧ殑DPI鍊�
+ final float RENDER_DPI = 72.0f;
+ // PDF榛樿DPI
+ final float PDF_DPI = 72.0f;
+ // 鍍忕礌鍒癙DF鐐圭殑杞崲鍥犲瓙
+ float pixelToPointFactor = PDF_DPI / RENDER_DPI;
+
+ confirmPanel.add(confirmBtn);
+ confirmPanel.add(cancelBtn);
+
+ // 娣诲姞鍒板彸渚ч潰鏉�
+ rightPanel.add(areaListPanel, BorderLayout.NORTH);
+ rightPanel.add(controlPanel, BorderLayout.CENTER);
+ rightPanel.add(confirmPanel, BorderLayout.SOUTH);
+
+ // 娣诲姞鍒颁富闈㈡澘
+ mainPanel.add(previewPanel, BorderLayout.CENTER);
+ mainPanel.add(rightPanel, BorderLayout.EAST);
+
+ // 娣诲姞浜嬩欢鐩戝惉鍣�
+ removeAreaBtn.addActionListener(e -> {
+ int[] selectedIndices = areaList.getSelectedIndices();
+ if (selectedIndices != null && selectedIndices.length > 0) {
+ // 浠庡悗寰�鍓嶅垹闄わ紝閬垮厤绱㈠紩娣蜂贡
+ for (int i = selectedIndices.length - 1; i >= 0; i--) {
+ areas.remove(selectedIndices[i]);
+ }
+ updateAreaList();
+ pdfPreviewPanel.repaint(); // 閲嶇粯棰勮闈㈡澘浠ユ洿鏂板尯鍩熸樉绀�
+ }
+ });
+
+ clearAreasBtn.addActionListener(e -> {
+ areas.clear();
+ updateAreaList();
+ pdfPreviewPanel.repaint(); // 閲嶇粯棰勮闈㈡澘浠ユ竻闄ゆ墍鏈夊尯鍩�
+ });
+
+ confirmBtn.addActionListener(e -> {
+ // 鍦ㄧ‘璁や箣鍓嶏紝灏嗘墍鏈夊尯鍩熺殑GUI鍧愭爣杞崲涓篜DF鍧愭爣
+ try {
+ if (areas.isEmpty()) {
+ appendLog("娌℃湁閫夋嫨浠讳綍鍖哄煙锛屾棤闇�杞崲鍧愭爣");
+ } else {
+ for (RectArea area : areas) {
+ PDPage page = document.getPage(area.pageIndex);
+ // 鑾峰彇PDF椤甸潰鐨勫獟浣撴锛堝疄闄呭昂瀵革級
+ org.apache.pdfbox.pdmodel.common.PDRectangle mediaBox = page.getMediaBox();
+ float pageWidth = mediaBox.getWidth(); // PDF椤甸潰瀹藉害锛堢偣锛�
+ float pageHeight = mediaBox.getHeight(); // PDF椤甸潰楂樺害锛堢偣锛�
+ // appendLog("PDF椤甸潰灏哄: 瀹藉害=" + pageWidth + "鐐�, 楂樺害=" + pageHeight + "鐐�");
+
+ // 閲嶆柊娓叉煋褰撳墠椤甸潰浠ヨ幏鍙栧噯纭殑鍥惧儚灏哄
+ PDFRenderer renderer = new PDFRenderer(document);
+ BufferedImage pageImage = renderer.renderImageWithDPI(area.pageIndex, RENDER_DPI);
+ int imageWidth = pageImage.getWidth(); // 娓叉煋鍥惧儚瀹藉害锛堝儚绱狅級
+ int imageHeight = pageImage.getHeight(); // 娓叉煋鍥惧儚楂樺害锛堝儚绱狅級
+ // appendLog("娓叉煋鍥惧儚灏哄: 瀹藉害=" + imageWidth + "鍍忕礌, 楂樺害=" + imageHeight + "鍍忕礌");
+
+ // 璁$畻姘村钩鍜屽瀭鐩存柟鍚戠殑杞崲鍥犲瓙锛堝儚绱犲埌鐐癸級
+ float xScaleFactor = pageWidth / imageWidth;
+ float yScaleFactor = pageHeight / imageHeight;
+ // appendLog("杞崲鍥犲瓙: x=" + xScaleFactor + ", y=" + yScaleFactor);
+
+ // 杞崲x鍧愭爣鍜屽搴︼紙姘村钩鏂瑰悜锛�
+ float pdfX = area.x * xScaleFactor;
+ float pdfWidth = area.width * xScaleFactor;
+
+ // 杞崲y鍧愭爣锛堣�冭檻鍧愭爣绯绘柟鍚戝樊寮傦級
+ // PDF鍧愭爣绯诲師鐐瑰湪宸︿笅瑙掞紝Swing鍦ㄥ乏涓婅
+ float pdfY = area.y * yScaleFactor;
+ float pdfHeight = area.height * yScaleFactor;
+
+ // 璁剧疆PDF鍧愭爣
+ area.setPdfCoordinates(pdfX, pdfY, pdfWidth, pdfHeight);
+ // appendLog("杞崲鍚庣殑PDF鍧愭爣: (" + pdfX + "," + pdfY + "," + pdfWidth + "," +
+ // pdfHeight + ")");
+ }
+ // 鏇存柊鍖哄煙鍒楄〃锛岀‘淇濇樉绀烘渶鏂扮殑PDF鍧愭爣
+ updateAreaList();
+ }
+ } catch (Exception ex) {
+ appendLog("鍧愭爣杞崲澶辫触: " + ex.getMessage());
+ ex.printStackTrace(); // 鎵撳嵃寮傚父鍫嗘爤锛屾柟渚胯皟璇�
+ }
+ confirmed = true;
+ dispose();
+ });
+
+ cancelBtn.addActionListener(e -> {
+ confirmed = false;
+ dispose();
+ });
+
+ setContentPane(mainPanel);
+ }
+
+ // 鍔犺浇PDF椤甸潰
+ private void loadPage(int pageIndex) {
+ try {
+ PDFRenderer renderer = new PDFRenderer(document);
+ currentImage = renderer.renderImageWithDPI(pageIndex, 72);
+ // 璁剧疆闈㈡澘鐨勯閫夊ぇ灏忎负鍥惧儚澶у皬
+ pdfPreviewPanel.setPreferredSize(new Dimension(currentImage.getWidth(), currentImage.getHeight()));
+ pdfPreviewPanel.revalidate();
+ pdfPreviewPanel.repaint();
+ } catch (IOException ex) {
+ appendLog("鍔犺浇PDF椤甸潰澶辫触: " + ex.getMessage());
+ }
+ }
+
+ // 鏇存柊鍖哄煙鍒楄〃
+ private void updateAreaList() {
+ areaListModel.clear();
+ for (RectArea area : areas) {
+ areaListModel.addElement(area.toString());
+ }
+ // 纭繚棰勮闈㈡澘姝g‘鏄剧ず褰撳墠椤甸潰鐨勬墍鏈夊尯鍩�
+ pdfPreviewPanel.repaint();
+ }
+
+ // 鑾峰彇鐢ㄦ埛鏄惁纭浜嗛�夋嫨
+ public boolean isConfirmed() {
+ return confirmed;
+ }
+
+ // 閲嶅啓dispose鏂规硶浠ョ‘淇濆叧闂璓DF鏂囨。
+ @Override
+ public void dispose() {
+ super.dispose();
+ if (document != null) {
+ try {
+ document.close();
+ } catch (Exception e) {
+ // 蹇界暐鍏抽棴寮傚父
+ }
+ }
+ }
+
+ // 鑾峰彇鐢ㄦ埛閫夋嫨鐨勫尯鍩熷垪琛�
+ public List<RectArea> getSelectedAreas() {
+ return new ArrayList<>(areas);
+ }
+ }
+
+ /**
+ * 閫夋嫨PDF鏂囦欢鏂规硶
+ */
+ private void selectBatchFiles() {
+ // 鍒涘缓鏂囦欢閫夋嫨鍣�
+ JFileChooser fileChooser = new JFileChooser();
+ // 璁剧疆澶氶�夋ā寮�
+ fileChooser.setMultiSelectionEnabled(true);
+ // 璁剧疆鏂囦欢杩囨护鍣紝鍙樉绀篜DF鏂囦欢
+ fileChooser.setFileFilter(new FileNameExtensionFilter("PDF鏂囦欢 (*.pdf)", "pdf"));
+
+ // 鏄剧ず鏂囦欢閫夋嫨瀵硅瘽妗�
+ int result = fileChooser.showOpenDialog(supper);
+
+ if (result == JFileChooser.APPROVE_OPTION) {
+ // 鑾峰彇鐢ㄦ埛閫夋嫨鐨勬枃浠�
+ File[] selectedFiles = fileChooser.getSelectedFiles();
+
+ if (selectedFiles != null && selectedFiles.length > 0) {
+ int addedCount = 0;
+
+ // 閬嶅巻閫夋嫨鐨勬枃浠跺苟娣诲姞鍒板垪琛�
+ for (File file : selectedFiles) {
+ String filePath = file.getAbsolutePath();
+ String fileName = file.getName();
+
+ // 妫�鏌ユ枃浠舵槸鍚﹀凡缁忓湪鍒楄〃涓�
+ boolean isExist = false;
+ for (int i = 0; i < batchFileListModel.size(); i++) {
+ if (batchFileListModel.getElementAt(i).contains(filePath)) {
+ isExist = true;
+ break;
+ }
+ }
+
+ if (!isExist) {
+ // 灏嗘枃浠舵坊鍔犲埌鍒楄〃涓紝鏄剧ず鏂囦欢鍚嶅拰璺緞
+ batchFileListModel.addElement(fileName + " (" + filePath + ")");
+ addedCount++;
+ }
+ }
+
+ // 璁板綍鏃ュ織
+ appendLog("鎴愬姛娣诲姞 " + addedCount + " 涓狿DF鏂囦欢鍒板垪琛�");
+ }
+ } else {
+ // 鐢ㄦ埛鍙栨秷浜嗛�夋嫨
+ appendLog("鐢ㄦ埛鍙栨秷浜嗘枃浠堕�夋嫨");
+ }
+ }
+
+ /**
+ * 绉婚櫎閫変腑鐨凱DF鏂囦欢
+ */
+ private void removeSelectedBatchFiles() {
+ // 鑾峰彇閫変腑鐨勭储寮�
+ int[] selectedIndices = batchFileList.getSelectedIndices();
+
+ if (selectedIndices != null && selectedIndices.length > 0) {
+ // 浠庡悗寰�鍓嶅垹闄わ紝閬垮厤绱㈠紩娣蜂贡
+ for (int i = selectedIndices.length - 1; i >= 0; i--) {
+ batchFileListModel.remove(selectedIndices[i]);
+ }
+
+ // 璁板綍鏃ュ織
+ appendLog("鎴愬姛绉婚櫎 " + selectedIndices.length + " 涓�変腑鐨凱DF鏂囦欢");
+ } else {
+ // 娌℃湁閫変腑浠讳綍鏂囦欢
+ appendLog("璇峰厛閫夋嫨瑕佺Щ闄ょ殑PDF鏂囦欢");
+ }
+ }
+
+ /**
+ * 娓呯┖鎵�鏈塒DF鏂囦欢鍒楄〃
+ */
+ private void clearAllBatchFiles() {
+ if (batchFileListModel.size() > 0) {
+ // 璁板綍瑕佹竻绌虹殑鏂囦欢鏁伴噺
+ int fileCount = batchFileListModel.size();
+ // 娓呯┖鍒楄〃
+ batchFileListModel.clear();
+ // 璁板綍鏃ュ織
+ appendLog("鎴愬姛娓呯┖鎵�鏈� " + fileCount + " 涓狿DF鏂囦欢");
+ } else {
+ // 鍒楄〃宸茬粡涓虹┖
+ appendLog("鏂囦欢鍒楄〃宸茬粡涓虹┖");
+ }
+ }
+
+ /**
+ * 鍚戞棩蹇楀尯鍩熸坊鍔犱俊鎭�
+ */
+ public void appendLog(String message) {
+ SwingUtilities.invokeLater(() -> {
+ String timestamp = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date());
+ batchLogArea.append("[" + timestamp + "] " + message + "\n");
+ // 鑷姩婊氬姩鍒板簳閮�
+ batchLogArea.setCaretPosition(batchLogArea.getDocument().getLength());
+ });
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/swingui/swing/jpanel/PdfPreviewPanel.java b/src/main/java/com/xindao/ocr/swingui/swing/jpanel/PdfPreviewPanel.java
new file mode 100644
index 0000000..8ef2e43
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/swingui/swing/jpanel/PdfPreviewPanel.java
@@ -0,0 +1,202 @@
+package com.xindao.ocr.swingui.swing.jpanel;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.rendering.PDFRenderer;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionAdapter;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+public class PdfPreviewPanel extends JPanel {
+ private PDDocument document;
+ private int pageNumber;
+ private BufferedImage pageImage;
+ private Rectangle2D selection = null;
+ private Rectangle2D lastSelection = null; // 涓婃閫夋嫨鐨勫尯鍩�
+ private Point startDrag = null;
+ private float scale = 1.0f;
+ private Point translation = new Point(0, 0); // 骞崇Щ閲�
+ private Point lastDragPoint = null;
+ private float pdfWidth;
+ private float pdfHeight;
+ private boolean isDraggingPage = false; // 鏄惁姝e湪鎷栨嫿椤甸潰
+
+ private static final Color SELECTION_COLOR = new Color(255, 193, 7, 100); // 鍗婇�忔槑榛勮壊
+ private static final Color LAST_SELECTION_COLOR = new Color(76, 175, 80, 100); // 鍗婇�忔槑缁胯壊锛岀敤浜庢爣璇嗕笂娆¢�夋嫨鐨勫尯鍩�
+
+ public PdfPreviewPanel(PDDocument doc, int pageNum, Rectangle2D lastArea) throws IOException {
+ this.document = doc;
+ this.pageNumber = pageNum;
+ this.lastSelection = lastArea;
+
+ // 娓叉煋PDF椤甸潰涓哄浘鐗�
+ PDFRenderer renderer = new PDFRenderer(doc);
+ pageImage = renderer.renderImage(pageNumber);
+
+ // 鑾峰彇PDF椤甸潰灏哄
+ pdfWidth = pageImage.getWidth();
+ pdfHeight = pageImage.getHeight();
+
+ // 濡傛灉鏈変笂娆¢�夋嫨鐨勫尯鍩燂紝榛樿閫変腑
+ if (lastSelection != null) {
+ this.selection = lastSelection;
+ }
+
+ // 娣诲姞榧犳爣鐩戝惉鍣ㄥ鐞嗛�夋嫨鍜屾嫋鎷�
+ addMouseListener(new MouseAdapter() {
+ @Override
+ public void mousePressed(MouseEvent e) {
+ // 妫�鏌ョ偣鍑讳綅缃槸鍚﹀湪PDF椤甸潰涓�
+ Rectangle2D pageBounds = getPageBounds();
+ if (pageBounds.contains(e.getPoint())) {
+ // 妫�鏌ユ槸鍚︾偣鍑诲湪閫夋嫨鍖哄煙鍐�
+ if (selection != null && selection.contains(e.getPoint())) {
+ startDrag = e.getPoint();
+ isDraggingPage = false;
+ } else {
+ // 寮�濮嬫柊鐨勯�夋嫨
+ startDrag = e.getPoint();
+ selection = null;
+ isDraggingPage = false;
+ }
+ } else {
+ // 鐐瑰嚮鍦ㄩ〉闈㈠锛屽噯澶囨嫋鎷芥暣涓〉闈�
+ lastDragPoint = e.getPoint();
+ isDraggingPage = true;
+ }
+ repaint();
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ startDrag = null;
+ lastDragPoint = null;
+ isDraggingPage = false;
+ repaint();
+ }
+ });
+
+ addMouseMotionListener(new MouseMotionAdapter() {
+ @Override
+ public void mouseDragged(MouseEvent e) {
+ if (isDraggingPage && lastDragPoint != null) {
+ // 鎷栨嫿鏁翠釜椤甸潰
+ int dx = e.getX() - lastDragPoint.x;
+ int dy = e.getY() - lastDragPoint.y;
+ translation.x += dx;
+ translation.y += dy;
+ lastDragPoint = e.getPoint();
+ repaint();
+ } else if (startDrag != null) {
+ // 鎷栨嫿閫夋嫨鍖哄煙
+ Point endDrag = e.getPoint();
+ selection = createRectangle(startDrag, endDrag);
+ repaint();
+ }
+ }
+ });
+
+ // 璁剧疆闈㈡澘棣栭�夊ぇ灏�
+ setPreferredSize(new Dimension(pageImage.getWidth(), pageImage.getHeight()));
+ }
+
+ // 鑾峰彇PDF椤甸潰鍦ㄩ潰鏉夸腑鐨勮竟鐣�
+ private Rectangle2D getPageBounds() {
+ return new Rectangle2D.Double(
+ translation.getX(),
+ translation.getY(),
+ pageImage.getWidth() * scale,
+ pageImage.getHeight() * scale
+ );
+ }
+
+ private Rectangle2D createRectangle(Point p1, Point p2) {
+ int x = Math.min(p1.x, p2.x);
+ int y = Math.min(p1.y, p2.y);
+ int width = Math.abs(p1.x - p2.x);
+ int height = Math.abs(p1.y - p2.y);
+ return new Rectangle2D.Double(x, y, width, height);
+ }
+
+ @Override
+ protected void paintComponent(Graphics g) {
+ super.paintComponent(g);
+ Graphics2D g2 = (Graphics2D) g;
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+
+ // 缁樺埗鑳屾櫙
+ g2.setColor(new Color(240, 240, 240));
+ g2.fillRect(0, 0, getWidth(), getHeight());
+
+ // 缁樺埗PDF椤甸潰
+ if (pageImage != null) {
+ // 淇濆瓨褰撳墠鍙樻崲
+ AffineTransform originalTransform = g2.getTransform();
+
+ // 搴旂敤骞崇Щ鍜岀缉鏀�
+ g2.translate(translation.x, translation.y);
+ g2.scale(scale, scale);
+
+ // 缁樺埗PDF鍥惧儚
+ g2.drawImage(pageImage, 0, 0, null);
+
+ // 缁樺埗涓婃閫夋嫨鐨勫尯鍩燂紙濡傛灉鏈夛級
+ if (lastSelection != null && (selection == null || !selection.equals(lastSelection))) {
+ g2.setColor(LAST_SELECTION_COLOR);
+ g2.fill(lastSelection);
+ g2.setColor(new Color(76, 175, 80));
+ g2.setStroke(new BasicStroke(1));
+ g2.draw(lastSelection);
+ }
+
+ // 缁樺埗褰撳墠閫夋嫨鍖哄煙
+ if (selection != null) {
+ // 杞崲閫夋嫨鍖哄煙鍧愭爣鍒癙DF鍧愭爣绯荤粺
+ Rectangle2D pdfSelection = new Rectangle2D.Double(
+ selection.getX() - translation.x,
+ selection.getY() - translation.y,
+ selection.getWidth(),
+ selection.getHeight()
+ );
+ pdfSelection = new Rectangle2D.Double(
+ pdfSelection.getX() / scale,
+ pdfSelection.getY() / scale,
+ pdfSelection.getWidth() / scale,
+ pdfSelection.getHeight() / scale
+ );
+
+ g2.setColor(SELECTION_COLOR);
+ g2.fill(pdfSelection);
+ g2.setColor(Color.ORANGE);
+ g2.setStroke(new BasicStroke(2));
+ g2.draw(pdfSelection);
+ }
+
+ // 鎭㈠鍙樻崲
+ g2.setTransform(originalTransform);
+ }
+ }
+
+ public Rectangle2D getSelection() {
+ return selection;
+ }
+
+ public float getScale() {
+ return scale;
+ }
+
+ public Point getTranslation() {
+ return translation;
+ }
+
+ public float getPdfHeight() {
+ return pdfHeight;
+ }
+ }
diff --git a/src/main/java/com/xindao/ocr/swingui/swing/utils/FileNameValidator.java b/src/main/java/com/xindao/ocr/swingui/swing/utils/FileNameValidator.java
new file mode 100644
index 0000000..cd7027c
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/swingui/swing/utils/FileNameValidator.java
@@ -0,0 +1,81 @@
+package com.xindao.ocr.swingui.swing.utils;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public class FileNameValidator {
+
+ // Windows绯荤粺涓嶅厑璁稿嚭鐜板湪鏂囦欢鍚嶄腑鐨勫瓧绗�
+ private static final Set<Character> ILLEGAL_CHARACTERS;
+ // Windows绯荤粺淇濈暀鐨勬枃浠跺悕
+ private static final Set<String> RESERVED_NAMES;
+
+ static {
+ // 鍒濆鍖栭潪娉曞瓧绗﹂泦
+ ILLEGAL_CHARACTERS = new HashSet<>(Arrays.asList(
+ '/', '\'', '"', '\\', '*', ':', '?', '<', '>', '|'
+ ));
+
+ // 鍒濆鍖栦繚鐣欐枃浠跺悕绉伴泦鍚�
+ RESERVED_NAMES = new HashSet<>(Arrays.asList(
+ "con", "prn", "aux", "nul",
+ "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9",
+ "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9"
+ ));
+ }
+
+ /**
+ * 鏍¢獙骞舵竻鐞嗘枃浠跺悕锛屼娇鍏剁鍚圵indows鍛藉悕瑙勫垯
+ * @param fileName 鍘熷鏂囦欢鍚�
+ * @param replacement 鐢ㄤ簬鏇挎崲闈炴硶瀛楃鐨勫悎娉曞瓧绗�
+ * @return 澶勭悊鍚庣殑鍚堟硶鏂囦欢鍚�
+ */
+ public static String validateAndCleanFileName(String fileName, char replacement) {
+ if (fileName == null || fileName.trim().isEmpty()) {
+ return "unnamed";
+ }
+
+ // 绉婚櫎棣栧熬绌烘牸
+ String cleaned = fileName.trim();
+
+ // 鏇挎崲闈炴硶瀛楃
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < cleaned.length(); i++) {
+ char c = cleaned.charAt(i);
+ sb.append(ILLEGAL_CHARACTERS.contains(c) ? replacement : c);
+ }
+ cleaned = sb.toString();
+
+ // 妫�鏌ユ槸鍚︽槸淇濈暀鏂囦欢鍚嶏紙涓嶅尯鍒嗗ぇ灏忓啓锛�
+ int dotIndex = cleaned.indexOf('.');
+ String nameWithoutExtension = dotIndex != -1 ? cleaned.substring(0, dotIndex) : cleaned;
+ if (RESERVED_NAMES.contains(nameWithoutExtension.toLowerCase())) {
+ cleaned = replacement + cleaned;
+ }
+
+ // 澶勭悊鍙寘鍚偣鎴栫┖鏍肩殑鎯呭喌
+ if (cleaned.replaceAll("[./\\\\ ]", "").isEmpty()) {
+ cleaned = "file" + replacement + cleaned;
+ }
+
+ // 澶勭悊浠ョ偣缁撳熬鐨勬儏鍐�
+ while (cleaned.endsWith(".")) {
+ cleaned = cleaned.substring(0, cleaned.length() - 1) + replacement;
+ }
+
+ // 闄愬埗鏂囦欢鍚嶉暱搴︼紙Windows閫氬父闄愬埗涓�255涓瓧绗︼級
+ if (cleaned.length() > 255) {
+ cleaned = cleaned.substring(0, 255);
+ }
+
+ return cleaned;
+ }
+
+ /**
+ * 閲嶈浇鏂规硶锛屼娇鐢ㄤ笅鍒掔嚎浣滀负榛樿鏇挎崲瀛楃
+ */
+ public static String validateAndCleanFileName(String fileName) {
+ return validateAndCleanFileName(fileName, '_');
+ }
+}
diff --git a/src/main/java/com/xindao/ocr/swingui/swing/utils/GenerateCustomizeComponent.java b/src/main/java/com/xindao/ocr/swingui/swing/utils/GenerateCustomizeComponent.java
new file mode 100644
index 0000000..fe285ab
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/swingui/swing/utils/GenerateCustomizeComponent.java
@@ -0,0 +1,122 @@
+package com.xindao.ocr.swingui.swing.utils;
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+import java.awt.geom.RoundRectangle2D;
+
+/**
+ * 鐢熸垚鑷畾涔変富閿伐鍏风被
+ */
+public class GenerateCustomizeComponent {
+
+ private static final Color PRIMARY_LIGHT = new Color(100, 150, 255);
+ private static final Color PRIMARY_COLOR = new Color(66, 133, 244);
+ private static final Color TEXT_COLOR = new Color(51, 51, 51);
+
+ private static final Color SECONDARY_COLOR = new Color(76, 175, 80);
+ private static final Color CARD_COLOR = new Color(255, 255, 255);
+
+ // 鍒涘缓鍗$墖寮忛潰鏉匡紙甯﹂槾褰卞拰鍦嗚锛�
+ public static JPanel createCardPanel() {
+ JPanel panel = new JPanel() {
+ @Override
+ protected void paintComponent(Graphics g) {
+ super.paintComponent(g);
+ Graphics2D g2d = (Graphics2D) g.create();
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+
+ // 缁樺埗鑳屾櫙
+ g2d.setColor(CARD_COLOR);
+ g2d.fill(new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), 10, 10));
+
+ // 缁樺埗闃村奖
+ g2d.setColor(new Color(0, 0, 0, 10));
+ for (int i = 0; i < 3; i++) {
+ g2d.draw(new RoundRectangle2D.Double(i, i, getWidth() - 2*i, getHeight() - 2*i, 10, 10));
+ }
+
+ g2d.dispose();
+ }
+ };
+ panel.setOpaque(false);
+ panel.setBackground(CARD_COLOR);
+ return panel;
+ }
+
+
+ // 鍒涘缓鏍峰紡鍖栭潰鏉�
+ public static JPanel createStyledPanel(LayoutManager layout) {
+ JPanel panel = new JPanel(layout);
+ panel.setOpaque(false);
+ return panel;
+ }
+
+ // 鍒涘缓涓昏鎸夐挳锛堝己璋冭壊锛�
+ public static JButton createPrimaryButton(String text,Font DEFAULT_FONT) {
+ JButton button = new JButton(text) {
+ @Override
+ protected void paintComponent(Graphics g) {
+ Graphics2D g2d = (Graphics2D) g.create();
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+
+ // 娓愬彉鑳屾櫙
+ GradientPaint gradient;
+ if (getModel().isPressed()) {
+ gradient = new GradientPaint(0, 0, PRIMARY_COLOR.darker(), 0, getHeight(), PRIMARY_COLOR.darker().darker());
+ } else if (getModel().isRollover()) {
+ gradient = new GradientPaint(0, 0, PRIMARY_LIGHT, 0, getHeight(), PRIMARY_COLOR);
+ } else {
+ gradient = new GradientPaint(0, 0, PRIMARY_COLOR, 0, getHeight(), PRIMARY_LIGHT);
+ }
+
+ g2d.setPaint(gradient);
+ g2d.fill(new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), 6, 6));
+ super.paintComponent(g);
+ g2d.dispose();
+ }
+ };
+
+ button.setFont(new Font(DEFAULT_FONT.getName(), Font.BOLD, 14));
+ button.setForeground(Color.WHITE);
+ button.setBorder(new EmptyBorder(8, 15, 8, 15));
+ button.setContentAreaFilled(false);
+ button.setFocusPainted(false);
+ button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+
+ return button;
+ }
+
+ // 鍒涘缓鏍峰紡鍖栨寜閽�
+ public static JButton createStyledButton(String text,Font font) {
+ JButton button = new JButton(text) {
+ @Override
+ protected void paintComponent(Graphics g) {
+ Graphics2D g2d = (Graphics2D) g.create();
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+
+ if (getModel().isPressed()) {
+ g2d.setColor(new Color(230, 230, 230));
+ } else if (getModel().isRollover()) {
+ g2d.setColor(new Color(240, 240, 240));
+ } else {
+ g2d.setColor(new Color(235, 235, 235));
+ }
+
+ g2d.fill(new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), 6, 6));
+ super.paintComponent(g);
+ g2d.dispose();
+ }
+ };
+
+ button.setFont(font);
+ button.setForeground(TEXT_COLOR);
+ button.setBorder(new EmptyBorder(8, 15, 8, 15));
+ button.setContentAreaFilled(false);
+ button.setFocusPainted(false);
+ button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+
+ return button;
+ }
+
+}
diff --git a/src/main/java/com/xindao/ocr/swingui/swing/utils/ToFile.java b/src/main/java/com/xindao/ocr/swingui/swing/utils/ToFile.java
new file mode 100644
index 0000000..7894d88
--- /dev/null
+++ b/src/main/java/com/xindao/ocr/swingui/swing/utils/ToFile.java
@@ -0,0 +1,179 @@
+package com.xindao.ocr.swingui.swing.utils;
+
+import org.bytedeco.opencv.global.opencv_imgcodecs;
+import org.bytedeco.opencv.global.opencv_imgproc;
+import org.bytedeco.opencv.opencv_core.Mat;
+import org.bytedeco.opencv.opencv_core.Size;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.nio.file.Files;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * @author sy
+ * @date 2022/11/23 22:03
+ */
+public class ToFile {
+
+ /**
+ * MultipartFile杞現ile
+ * @param file
+ * @return
+ * @throws IOException
+ */
+ public static File multipartFiletoFile(MultipartFile file) throws IOException {
+ File toFile = null;
+ if((!file.equals("")) && (file.getSize() > 0)) {
+ String filePath = "/tmp/img";
+ if(!new File(filePath).exists()) {
+ new File(filePath).mkdirs();
+ }
+ InputStream inputStream = file.getInputStream();
+ String fileFullName = file.getOriginalFilename();
+ String fileName = fileFullName.substring(0, fileFullName.lastIndexOf("."));
+ String prefix = fileFullName.substring(fileFullName.lastIndexOf("."));
+ toFile = new File(filePath + fileName + "_" + System.currentTimeMillis() + prefix);
+ intputStreamToFile(inputStream, toFile);
+ inputStream.close();
+ }
+ return toFile;
+ }
+
+ /**
+ * 鑾峰彇鏂囦欢娴�
+ * @param inputStream
+ * @param file
+ */
+ private static void intputStreamToFile(InputStream inputStream, File file) {
+ try (OutputStream outputStream = new FileOutputStream(file)) {
+ int bytesRead = 0;
+ byte[] buffer = new byte[8192];
+ while((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
+ outputStream.write(buffer, 0, bytesRead);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 鍒犻櫎涓存椂鏂囦欢
+ * @param file
+ */
+ public static void deleteTempFile(File file) {
+ if(Optional.ofNullable(file).isPresent()) {
+ File del = new File(file.toURI());
+ del.delete();
+ }
+ }
+
+ /**
+ * 鍒犻櫎涓存椂鐩綍涓嬬殑鎵�鏈夋枃浠�
+ * @param cacheDir
+ */
+ public static void deleteTempFiles(File cacheDir) {
+ //鍒犻櫎涓存椂鐩綍
+ if (cacheDir.exists() && cacheDir.isDirectory()) {
+ for (File tempFile : Objects.requireNonNull(cacheDir.listFiles())) {
+ if (tempFile.isFile()) {
+ try {
+ Files.delete(tempFile.toPath());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+
+ /**
+ * 淇濆瓨鍥惧儚鍒版寚瀹氳矾寰�
+ * @param image 鍥惧儚瀵硅薄
+ * @param filePath 淇濆瓨璺緞
+ * @param formatName 鍥惧儚鏍煎紡锛堝 "png", "jpg"锛�
+ * @return 鏄惁淇濆瓨鎴愬姛
+ */
+ public static boolean saveImage(BufferedImage image, String filePath, String formatName) {
+ if (image == null || filePath == null || formatName == null) {
+ System.err.println("鍙傛暟涓嶈兘涓虹┖");
+ return false;
+ }
+
+ try {
+ // 鍒涘缓鏂囦欢瀵硅薄
+ File outputFile = new File(filePath);
+
+ // 纭繚鐖剁洰褰曞瓨鍦�
+ File parentDir = outputFile.getParentFile();
+ if (parentDir != null && !parentDir.exists()) {
+ parentDir.mkdirs(); // 閫掑綊鍒涘缓鐩綍
+ }
+
+ // 淇濆瓨鍥剧墖
+ return ImageIO.write(image, formatName, outputFile);
+ } catch (IOException e) {
+ System.err.println("淇濆瓨鍥剧墖澶辫触锛�" + e.getMessage());
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * 棰勫鐞嗗浘鍍忎互鎻愰珮OCR璇嗗埆鐜�
+ * @param inputPath 杈撳叆鍥惧儚璺緞
+ */
+ public static void preprocessImage(String inputPath) {
+ Mat src = opencv_imgcodecs.imread(inputPath);
+ if (src.empty()) {
+ System.err.println("鏃犳硶璇诲彇鍥惧儚: " + inputPath);
+ return ;
+ }
+
+ // 1. 鐏板害鍖�
+ Mat gray = new Mat();
+ opencv_imgproc.cvtColor(src, gray, opencv_imgproc.COLOR_BGR2GRAY);
+
+ // 2. 杞婚噺鍘诲櫔锛堥伩鍏嶈繃搴︽ā绯奌鐨勮竟缂橈級
+// Mat blurred = new Mat();
+// opencv_imgproc.GaussianBlur(gray, blurred, new Size(1, 1), 0); // 缂╁皬妯$硦鏍革紝淇濈暀瀛楃缁嗚妭
+
+ // 3. 瀵规瘮搴﹀寮猴紙鏀圭敤CLAHE锛屾洿绮剧粏鎺у埗瀵规瘮搴︼級
+ Mat enhanced = new Mat();
+ opencv_imgproc.createCLAHE(3, new Size(3, 3)).apply(gray, enhanced); // clipLimit璋冩暣瀵规瘮搴﹀己搴�
+
+// // 4. 浜屽�煎寲锛堣皟鏁撮槇鍊煎弬鏁帮紝璁〩鐨勮疆寤撴洿閿愬埄锛�
+// Mat binary = new Mat();
+// opencv_imgproc.adaptiveThreshold(
+// enhanced,
+// binary,
+// 255,
+// opencv_imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,
+// opencv_imgproc.THRESH_BINARY_INV,
+// 3, // blockSize缂╁皬锛屾彁鍗囧眬閮ㄩ槇鍊肩簿搴�
+// 3 // C鍊艰皟鏁达紝鎺у埗闃堝�煎亸绉�
+// );
+//
+// // 5. 褰㈡�佸鎿嶄綔锛堣啫鑳�+鑵愯殌锛岃H鐨勭瑪鐢绘洿绮楀.锛�
+// Mat kernel = opencv_imgproc.getStructuringElement(opencv_imgproc.MORPH_RECT, new Size(1, 1)); // 澧炲ぇ鏍稿昂瀵�
+// Mat morph = new Mat();
+// opencv_imgproc.dilate(binary, morph,kernel); // 鍏堣啫鑳�锛堝姞绮楀瓧绗︼級
+// opencv_imgproc.erode(morph, morph,kernel); // 鍐嶈厫铓�锛堜慨澶嶈啫鑳�鍚庣殑杈圭紭锛屼繚鎸佸瓧绗﹀舰鐘讹級
+
+ // 淇濆瓨骞堕噴鏀捐祫婧�
+ opencv_imgcodecs.imwrite(inputPath, enhanced);
+ src.release();
+ gray.release();
+// blurred.release();
+ enhanced.release();
+// binary.release();
+// kernel.release();
+// morph.release();
+
+ }
+
+}
diff --git a/src/main/resources/PP_OCRv5/PP-LCNet_x0_25_textline_ori_infer/PP-LCNet_x0_25_textline_ori_infer.onnx b/src/main/resources/PP_OCRv5/PP-LCNet_x0_25_textline_ori_infer/PP-LCNet_x0_25_textline_ori_infer.onnx
new file mode 100644
index 0000000..83264b9
--- /dev/null
+++ b/src/main/resources/PP_OCRv5/PP-LCNet_x0_25_textline_ori_infer/PP-LCNet_x0_25_textline_ori_infer.onnx
Binary files differ
diff --git a/src/main/resources/PP_OCRv5/PP-OCRv5_mobile_rec_infer/PP-OCRv5_mobile_rec_infer.onnx b/src/main/resources/PP_OCRv5/PP-OCRv5_mobile_rec_infer/PP-OCRv5_mobile_rec_infer.onnx
new file mode 100644
index 0000000..191fbe5
--- /dev/null
+++ b/src/main/resources/PP_OCRv5/PP-OCRv5_mobile_rec_infer/PP-OCRv5_mobile_rec_infer.onnx
Binary files differ
diff --git a/src/main/resources/PP_OCRv5/PP-OCRv5_mobile_rec_infer/dict.txt b/src/main/resources/PP_OCRv5/PP-OCRv5_mobile_rec_infer/dict.txt
new file mode 100644
index 0000000..567898b
--- /dev/null
+++ b/src/main/resources/PP_OCRv5/PP-OCRv5_mobile_rec_infer/dict.txt
@@ -0,0 +1,18383 @@
+銆�
+涓�
+涔�
+浜�
+鍗�
+涓�
+鍘�
+涓�
+鍗�
+鍏�
+浜�
+鍏�
+鍎�
+鍖�
+鍑�
+涔�
+鍒�
+浜�
+鍒�
+鍔�
+涔�
+鍙�
+涓�
+骞�
+浜�
+浜�
+宸�
+鍦�
+澹�
+鎵�
+涓�
+瀵�
+澶�
+涓�
+涓�
+涓�
+涓�
+灏�
+鍙�
+灞�
+宸�
+鍗�
+涔�
+宸�
+浜�
+涓�
+澶�
+涔�
+涔�
+鍕�
+鍑�
+涓�
+鍙�
+骞�
+浜�
+闂�
+涓�
+涔�
+涔�
+灏�
+宸�
+宸�
+宸�
+寮�
+瀛�
+鍗�
+涔�
+濂�
+鍒�
+椋�
+涔�
+鍙�
+椹�
+涔�
+涓�
+鐜�
+寮�
+浜�
+澶�
+澶�
+鍏�
+鏃�
+浜�
+涓�
+涓�
+鎵�
+鑹�
+鏈�
+浜�
+鏀�
+鍘�
+涓�
+鐘�
+澶�
+鍖�
+鍘�
+姝�
+鍙�
+灏�
+鍖�
+杞�
+宸�
+鐗�
+灞�
+鎴�
+姣�
+浜�
+鍒�
+鐡�
+姝�
+灏�
+鏇�
+鏃�
+涓�
+璐�
+鍐�
+鍐�
+姘�
+瑙�
+鍗�
+鐗�
+鎵�
+姘�
+姣�
+澹�
+鍗�
+澶�
+闀�
+浠�
+浠�
+鐗�
+浠�
+鍖�
+浠�
+甯�
+浠�
+浠�
+鏂�
+鐖�
+鍙�
+浠�
+鐖�
+浠�
+浠�
+浠�
+鍑�
+鍒�
+涔�
+鍏�
+浠�
+鏈�
+姘�
+鍕�
+娆�
+椋�
+涓�
+鍖�
+涔�
+鍕�
+鍑�
+鍏�
+鏂�
+浜�
+鏂�
+鐏�
+涓�
+鏂�
+蹇�
+璁�
+璁�
+鎴�
+璁�
+鍐�
+璁�
+蹇�
+灏�
+寮�
+涓�
+宸�
+瀛�
+闃�
+鍔�
+浠�
+鍏�
+浜�
+閭�
+鍔�
+鍙�
+涔�
+骞�
+鐜�
+鍒�
+鏈�
+鏈�
+绀�
+鍑�
+鎵�
+宸�
+姝�
+鎵�
+鍗�
+鎵�
+鍔�
+鎵�
+鍘�
+鐢�
+涓�
+鑹�
+鍙�
+鑺�
+鏈�
+鏈�
+鍙�
+涓�
+宸�
+鍘�
+鐭�
+鍙�
+甯�
+澶�
+鎴�
+榫�
+骞�
+鐏�
+杞�
+涓�
+鍗�
+鍖�
+鍗�
+鍑�
+鍗�
+涓�
+鏃�
+甯�
+褰�
+鏃�
+鐩�
+涓�
+鍙�
+鐢�
+鐢�
+鍙�
+鐢�
+鍙�
+鐢�
+鐢�
+鍙�
+鍙�
+鍙�
+澶�
+鍏�
+鍙�
+鍙�
+鍙�
+鍙�
+鍙�
+鍙�
+鍙�
+鍐�
+鐨�
+鍑�
+鍥�
+鍥�
+鐢�
+鐭�
+澶�
+涔�
+绂�
+涓�
+浠�
+浠�
+浠�
+浠�
+浠�
+浠�
+鐧�
+浠�
+浠�
+鏂�
+鐡�
+涔�
+涓�
+浠�
+鐢�
+鐢�
+鍗�
+灏�
+涔�
+鍙�
+鍖�
+鍐�
+鍗�
+鐘�
+澶�
+澶�
+鍐�
+楦�
+鍔�
+鍖�
+楗�
+涓�
+甯�
+绔�
+鍐�
+鐜�
+闂�
+鍏�
+鍗�
+姹�
+姹�
+澶�
+姹�
+瀹�
+绌�
+瀹�
+璁�
+鍐�
+璁�
+绀�
+璁�
+璁�
+蹇�
+璁�
+璁�
+姘�
+鍙�
+灏�
+姘�
+寮�
+寮�
+鍑�
+杈�
+濂�
+濂�
+鍙�
+鍔�
+鐨�
+杈�
+瀛�
+鍙�
+鍦�
+瀵�
+鍙�
+鐭�
+绾�
+姣�
+骞�
+涓�
+閭�
+寮�
+杩�
+鍒�
+鎴�
+鍔�
+鎵�
+瀵�
+鍚�
+鎵�
+鑰�
+鎵�
+鑰�
+宸�
+鍦�
+鎵�
+鎵�
+鎵�
+鍦�
+鍦�
+鎵�
+鑰�
+鑺�
+鍏�
+鑺�
+浜�
+鑺�
+鏈�
+鏈�
+鏈�
+鏉�
+杩�
+鑷�
+鍚�
+鍐�
+鍗�
+瑗�
+鍘�
+鍘�
+鎴�
+鍦�
+鐧�
+鏈�
+瀛�
+鑰�
+椤�
+鍖�
+澶�
+澶�
+鐏�
+杈�
+鍒�
+姝�
+鎴�
+澶�
+澶�
+杞�
+閭�
+灏�
+鍒�
+杩�
+姣�
+鑷�
+姝�
+璐�
+甯�
+灏�
+灏�
+鍔�
+鍏�
+褰�
+鏃�
+鍚�
+鍚�
+鍚�
+铏�
+鏇�
+鍥�
+鍚�
+鍚�
+鍚�
+鍚�
+鍥�
+鍚�
+鍚�
+鍚�
+灞�
+灞�
+宀�
+甯�
+鍥�
+宀�
+鍒�
+鍒�
+缃�
+鑲�
+骞�
+鏈�
+鍏�
+涓�
+寤�
+鑸�
+绔�
+杩�
+涔�
+杩�
+浼�
+浼�
+涔�
+涔�
+浼�
+浼�
+浼�
+浼�
+鑷�
+浼�
+寤�
+浠�
+浠�
+浠�
+浼�
+浠�
+浼�
+浠�
+鍗�
+浠�
+浠�
+浼�
+浼�
+鑷�
+浼�
+琛�
+鍚�
+浼�
+鍚�
+琛�
+鑸�
+鍏�
+浼�
+鏉�
+鍚�
+鍏�
+浼�
+浼�
+鐖�
+浼�
+鍒�
+鑲�
+鑲�
+鏈�
+鏉�
+鍗�
+鏃�
+鏃�
+鏃�
+璐�
+鍖�
+鍚�
+鍚�
+澶�
+浜�
+鑹�
+澹�
+鍐�
+濡�
+鍐�
+搴�
+搴�
+浜�
+鍒�
+榻�
+浜�
+琛�
+娆�
+浜�
+鍐�
+浜�
+鍏�
+濡�
+闂�
+闂�
+闂�
+缇�
+骞�
+鍏�
+绫�
+鐏�
+宸�
+姹�
+姹�
+姹�
+姹�
+姹�
+姹�
+姹�
+蹇�
+鍏�
+瀹�
+瀹�
+瀹�
+瀛�
+瀹�
+璁�
+璁�
+鍐�
+璁�
+璁�
+璁�
+璁�
+璁�
+鍐�
+璁�
+璁�
+璁�
+璇�
+瀵�
+閭�
+杩�
+灏�
+瀵�
+寮�
+寮�
+瀛�
+闃�
+闃�
+鏀�
+闃�
+闃�
+闃�
+濂�
+濡�
+濡�
+濡�
+濂�
+濂�
+濡�
+鎴�
+缇�
+瑙�
+娆�
+涔�
+绾�
+椹�
+绾�
+椹�
+绾�
+绾�
+绾�
+椹�
+绾�
+宸�
+瀵�
+寮�
+楹�
+鐜�
+鐜�
+褰�
+杩�
+鎴�
+鍚�
+杩�
+杩�
+闊�
+杩�
+鎵�
+鎶�
+鍧�
+鎶�
+鍧�
+鎶�
+鎵�
+鎵�
+鎷�
+鎵�
+鎵�
+鍧�
+鎵�
+璧�
+鎶�
+璐�
+姹�
+鍧�
+鏀�
+璧�
+鎶�
+鎶�
+鎵�
+鎶�
+鎵�
+鎶�
+瀛�
+鍧�
+鍧�
+鎶�
+鎶�
+鎶�
+鍧�
+鍧�
+鎶�
+鍧�
+鎶�
+鎶�
+澹�
+蹇�
+鍧�
+鎵�
+澹�
+鎶�
+鎶�
+鎷�
+鍗�
+鎶�
+鍔�
+鑺�
+鑺�
+鑻�
+鑺�
+鑺�
+鑺�
+鑺�
+鑺�
+鑻�
+鑺�
+涓�
+鑺�
+鑺�
+鍔�
+鍏�
+鑺�
+鑻�
+鏉�
+鏉�
+鏉�
+鏉�
+鏉�
+鏉�
+鏉�
+鏉�
+宸�
+鏋�
+鏉�
+鏉�
+姹�
+鐢�
+鍖�
+鏇�
+鏉�
+鍚�
+璞�
+涓�
+閰�
+涓�
+鍖�
+杈�
+鍔�
+鍚�
+杩�
+灏�
+姝�
+鏉�
+杩�
+杞�
+姝�
+鍗�
+鍧�
+鑲�
+鏃�
+鐩�
+鍛�
+鏃�
+鍚�
+鍔�
+鍘�
+閲�
+鍛�
+鍚�
+鍚�
+鍛�
+鍥�
+鏃�
+鍥�
+鍛�
+鍚�
+瓒�
+閭�
+鐢�
+鍥�
+鍚�
+涓�
+鍛�
+鍛�
+鍚�
+鍚�
+鍚�
+鍛�
+鍚�
+鍚�
+鍛�
+鍚�
+鍚�
+閭�
+鍚�
+鍥�
+鍒�
+鍚�
+宀�
+宀�
+甯�
+璐�
+閽�
+閽�
+鐗�
+鍛�
+鎴�
+涔�
+鍒�
+绉�
+绉�
+绉�
+姣�
+鍏�
+浼�
+浣�
+浣�
+浣�
+浣�
+浣�
+浼�
+浣�
+浣�
+浼�
+浼�
+浣�
+浣�
+浣�
+浣�
+浣�
+浼�
+韬�
+鐨�
+浼�
+浣�
+鍥�
+杩�
+褰�
+褰�
+杩�
+浣�
+甯�
+鍧�
+璋�
+濡�
+鍚�
+閭�
+宀�
+鑲�
+鑲�
+鑲�
+鑲�
+鑲�
+榫�
+鐢�
+鍏�
+鐙�
+鐘�
+鐙�
+瑙�
+鍒�
+鏉�
+褰�
+鍗�
+鐏�
+宀�
+鍒�
+杩�
+楗�
+楗�
+绯�
+瑷�
+鍐�
+鐘�
+浜�
+鍐�
+搴�
+搴�
+搴�
+鐤�
+鍚�
+搴�
+杩�
+鍐�
+搴�
+搴�
+杈�
+寮�
+鍐�
+蹇�
+闂�
+闂�
+闂�
+闂�
+鍒�
+鍏�
+鐏�
+鐏�
+鐏�
+寮�
+姹�
+娌�
+娌�
+姹�
+娌�
+娌�
+姹�
+娌�
+娌�
+姹�
+娉�
+娌�
+娌�
+娌�
+娌�
+娌�
+娌�
+娌�
+鎬�
+蹇�
+蹇�
+蹇�
+瀹�
+瀹�
+瀹�
+鐗�
+绌�
+绌�
+鐏�
+鑹�
+璇�
+鍚�
+璇�
+琛�
+鍒�
+绀�
+绁�
+璇�
+璇�
+璇�
+缃�
+璇�
+璇�
+璇�
+鍚�
+鐏�
+鍗�
+灞�
+灞�
+灏�
+灏�
+杩�
+灞�
+鏀�
+寮�
+蹇�
+闄�
+闄�
+闃�
+闄�
+闃�
+闄�
+鍧�
+濡�
+濡�
+濡�
+濮�
+濡�
+濡�
+鍔�
+蹇�
+鍔�
+鐭�
+楦�
+绾�
+椹�
+绾�
+绾�
+绾�
+绾�
+椹�
+绾�
+绾�
+绾�
+绾�
+绾�
+椹�
+绾�
+濂�
+鐜�
+鐜�
+姝�
+闈�
+璐�
+鐜�
+鐜�
+琛�
+瑙�
+鎶�
+鍗�
+鍧�
+鍧�
+鎷�
+鎷�
+鎷�
+鍧�
+鎷�
+鍧�
+鎷�
+鍧�
+鎶�
+鎶�
+鎷�
+鎷�
+鑰�
+鎷�
+椤�
+鎷�
+鎷�
+鎷�
+鎶�
+鎷�
+鍔�
+鎶�
+鎷�
+鍨�
+鎷�
+鎷�
+骞�
+鎷�
+鎷�
+鎷�
+鎷�
+鎷�
+鍧�
+鎶�
+鎷�
+鎷�
+鎶�
+鎷�
+鎷�
+鍏�
+鍙�
+鑼�
+鑻�
+鏄�
+鑻�
+鑻�
+鑼�
+鑻�
+鑻�
+鑻�
+鑻�
+鑻�
+鑻�
+鑼�
+鐩�
+鑼�
+鑼�
+鑼�
+鑻�
+鑼�
+鏋�
+鏋�
+鏋�
+鏉�
+鏋�
+鏌�
+鏋�
+鏋�
+鏉�
+鏉�
+鏋�
+鏋�
+鏋�
+鏉�
+鏉�
+杩�
+鏋�
+涓�
+鎴�
+鐢�
+鍗�
+浜�
+鍒�
+鏋�
+闆�
+鍗�
+閮�
+鐭�
+鐭�
+鐮�
+鍘�
+濂�
+濂�
+濂�
+濂�
+鎬�
+娆�
+娈�
+鍨�
+濡�
+杞�
+椤�
+杞�
+鏂�
+杞�
+杞�
+鍒�
+闈�
+鍙�
+姝�
+鑲�
+榻�
+浜�
+鍗�
+铏�
+铏�
+鑲�
+璐�
+灏�
+鏃�
+鍏�
+鍛�
+鏋�
+鏄�
+鍥�
+鍝�
+鍜�
+鏄�
+鍛�
+鐣�
+鏄�
+鏄�
+鍜�
+鏄�
+杩�
+鍏�
+鍥�
+蹇�
+鍛�
+鍜�
+鍜�
+鍜�
+鍛�
+楦�
+鍜�
+鍛�
+鍜�
+鍜�
+宀�
+宀�
+甯�
+缃�
+甯�
+甯�
+宀�
+鍑�
+璐�
+璐�
+璐�
+璐�
+璐�
+璐�
+鍥�
+閽�
+鍒�
+鐭�
+杩�
+姘�
+鍨�
+鐗�
+鐗�
+涔�
+鍒�
+绉�
+鍜�
+瀛�
+濮�
+绉�
+浣�
+渚�
+宀�
+渚�
+浣�
+渚�
+渚�
+渚�
+鐗�
+渚�
+渚�
+渚�
+渚�
+鍑�
+渚�
+浣�
+璐�
+渚�
+渚�
+鍗�
+鐨�
+杩�
+璐�
+娆�
+寰�
+寰�
+鐖�
+褰�
+寰�
+鎵�
+鑸�
+閲�
+鍒�
+鍛�
+鑲�
+鏂�
+鐖�
+閲�
+瑙�
+鍙�
+涔�
+璐�
+蹇�
+璐�
+蹇�
+鑲�
+鑲�
+鑲�
+鑲�
+鑳�
+鏈�
+鑲�
+鑲�
+鑲�
+鑲�
+鏈�
+鑳�
+鍛�
+鏄�
+楸�
+鍏�
+鐙�
+蹇�
+鐙�
+鐙�
+澶�
+楗�
+楗�
+楗�
+鍙�
+浜�
+浜�
+搴�
+搴�
+澶�
+搴�
+搴�
+搴�
+鐤�
+鐤�
+鐤�
+鍓�
+鍗�
+閮�
+搴�
+搴�
+鍑�
+鐩�
+鏀�
+鍒�
+鑲�
+姘�
+闂�
+闂�
+閮�
+鍒�
+鍗�
+鍗�
+鐐�
+鐐�
+鐐�
+鐐�
+鐐�
+鐐�
+娌�
+娴�
+娉�
+娉�
+娌�
+娌�
+娌�
+娉�
+娌�
+娌�
+娉�
+娌�
+娉�
+娉�
+娉�
+娉�
+娉�
+娉�
+娉�
+娉�
+娌�
+娌�
+娉�
+娉�
+娉�
+娌�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+瀛�
+瀹�
+瀹�
+瀹�
+瀹�
+瀹�
+瀹�
+瀹�
+瀹�
+绌�
+甯�
+瀹�
+瀹�
+璇�
+閮�
+璇�
+鑲�
+鎴�
+璇�
+琛�
+琛�
+瑙�
+绁�
+璇�
+璇�
+璇�
+璇�
+璇�
+璇�
+寤�
+鑲�
+褰�
+闅�
+甯�
+灞�
+灞�
+灞�
+鍒�
+灞�
+寮�
+寮�
+寮�
+鎵�
+瀛�
+闄�
+闄�
+瀛�
+闄�
+闄�
+鍑�
+闄�
+濡�
+濮�
+濮�
+濮�
+濡�
+濮�
+濮�
+杩�
+椹�
+鍙�
+鍙�
+鑹�
+绾�
+缁�
+缁�
+缁�
+缁�
+椹�
+缁�
+椹�
+缁�
+椹�
+缁�
+椹�
+缁�
+缁�
+缁�
+璐�
+濂�
+璐�
+濂�
+鏄�
+甯�
+鐜�
+鐝�
+鐜�
+鐜�
+姣�
+鍨�
+鎷�
+鎸�
+灏�
+鎸�
+鎷�
+鎷�
+椤�
+鍨�
+鎸�
+鍩�
+鎸�
+鎸�
+鏀�
+璧�
+璧�
+鎸�
+鎷�
+鍝�
+鎸�
+鎷�
+鍨�
+鎷�
+鎷�
+鎸�
+鍨�
+鎸�
+鍨�
+鎸�
+鎸�
+鎷�
+鎸�
+鎸�
+鎸�
+鎸�
+鎷�
+鏌�
+鐢�
+鑽�
+鑼�
+闈�
+鑼�
+鑽�
+宸�
+甯�
+鑽�
+鑼�
+鑼�
+鑼�
+鑽�
+鑼�
+鑽�
+鑽�
+鑽�
+鑽�
+鏁�
+鑳�
+鑽�
+鑽�
+鍗�
+鑽�
+鏍�
+鏍�
+鏌�
+鏋�
+鏌�
+鏍�
+鐩�
+鏌�
+鏌�
+鏍�
+鏌�
+鏌�
+鏌�
+鏍�
+鏌�
+鏍�
+鍕�
+瑕�
+鏌�
+鍜�
+濞�
+姝�
+鐮�
+鐮�
+鍘�
+鍘�
+鐮�
+鐮�
+娉�
+鐮�
+鐮�
+闈�
+鑰�
+鑰�
+鐗�
+楦�
+娈�
+娈�
+杞�
+杞�
+楦�
+鐨�
+闊�
+鑳�
+鎴�
+鐐�
+铏�
+涓�
+瑙�
+绔�
+鐪�
+鍓�
+灏�
+鏄�
+鐩�
+鏄�
+鐩�
+鐪�
+鍝�
+鍝�
+鍝�
+鏄�
+鍐�
+鏄�
+鏄�
+鏄�
+鍜�
+鏄�
+鐣�
+瓒�
+鑳�
+璐�
+鐣�
+铏�
+铏�
+铓�
+鎬�
+铓�
+铏�
+鍝�
+鍜�
+楠�
+鍕�
+鍝�
+鍜�
+鍝�
+鍝�
+鍝�
+鍜�
+鍜�
+鍜�
+鍝�
+鍝�
+鐐�
+宄�
+缃�
+璐�
+璐�
+璐�
+楠�
+骞�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+鍗�
+缂�
+鎷�
+鐪�
+鐭�
+姣�
+姘�
+鎬�
+鐗�
+閫�
+閫�
+绉�
+棣�
+绉�
+绉�
+绉�
+閲�
+澶�
+绔�
+娈�
+渚�
+淇�
+璐�
+椤�
+淇�
+淇�
+淇�
+淇�
+淇�
+淇�
+渚�
+淇�
+淇�
+淇�
+淇�
+鐨�
+娉�
+楝�
+渚�
+绂�
+渚�
+杩�
+淇�
+鐩�
+寰�
+寰�
+琛�
+寰�
+寰�
+椤�
+鍙�
+鍓�
+閫�
+椋�
+鐩�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑴�
+鑳�
+鍕�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+璐�
+鎬�
+鎬�
+楗�
+楗�
+铓�
+楗�
+楗�
+宄�
+寮�
+灏�
+濂�
+鍝�
+浜�
+浜�
+搴�
+杩�
+搴�
+鐤�
+鐤�
+鐤�
+鐤�
+鍜�
+濮�
+浜�
+闊�
+甯�
+鏂�
+闂�
+闂�
+闂�
+闃�
+闃�
+宸�
+鍏�
+缇�
+濮�
+鍙�
+閫�
+绫�
+杩�
+绫�
+濞�
+鍓�
+棣�
+閫�
+鍏�
+鎬�
+鐐�
+鐐�
+鐑�
+鐐�
+鐐�
+鐑�
+鍓�
+娲�
+娲�
+娲�
+娲�
+鏌�
+娴�
+娴�
+娲�
+娴�
+娲�
+娲�
+娲�
+娲�
+鏌�
+娲�
+娴�
+娴�
+娲�
+娲�
+娴�
+娴�
+娲�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+涓�
+瑙�
+瀹�
+瀹�
+瀹�
+瀹�
+瀹�
+绐�
+绌�
+绐�
+瀹�
+璇�
+鍐�
+璇�
+璇�
+鎵�
+琚�
+绁�
+绁�
+绁�
+绁�
+璇�
+璇�
+璇�
+璇�
+璇�
+鍨�
+閫�
+鏃�
+灞�
+鏄�
+灞�
+灞�
+璐�
+闄�
+閫�
+鐪�
+瀛�
+闄�
+闄�
+闄�
+闄�
+濞�
+濮�
+濮�
+濮�
+濞�
+濮�
+濞�
+鎬�
+鏋�
+璐�
+鐩�
+鍕�
+鎬�
+鐧�
+铓�
+鏌�
+鍨�
+缁�
+缁�
+缁�
+缁�
+楠�
+缁�
+缁�
+缁�
+楠�
+缁�
+缁�
+缁�
+楠�
+缁�
+鑰�
+鑰�
+鑰�
+鑰�
+鑹�
+娉�
+绉�
+鐝�
+鐝�
+绱�
+鍖�
+铓�
+椤�
+鐩�
+鍖�
+鎹�
+鏍�
+鎹�
+鍩�
+鎹�
+鎸�
+杞�
+璧�
+璧�
+鐩�
+鎹�
+鎹�
+鎹�
+鍩�
+鎹�
+鎹�
+鎹�
+鎹�
+琚�
+鎹�
+閮�
+鍝�
+閫�
+鎹�
+鎸�
+鎹�
+鎸�
+鎸�
+鐑�
+鎭�
+鎹�
+澹�
+鎹�
+鍩�
+鎸�
+鑰�
+鑰�
+鑰�
+鑱�
+鎭�
+鑾�
+鑾�
+鑾�
+鑾�
+鑾�
+鑽�
+鑾�
+鏅�
+鎭�
+鑾�
+鑾�
+鐪�
+妗�
+姊�
+妗�
+妗�
+鏍�
+妗�
+妗�
+鏍�
+妗�
+妗�
+鏍�
+妗�
+鏍�
+妗�
+鏍�
+鏍�
+鏍�
+鏍�
+绱�
+鍝�
+閫�
+閫�
+鏍�
+璐�
+閰�
+閰�
+缈�
+杈�
+鍞�
+澶�
+鐮�
+鐮�
+鐮�
+纭�
+鐮�
+鍘�
+濂�
+閫�
+鐑�
+娈�
+娈�
+椤�
+杞�
+杈�
+椤�
+姣�
+鑷�
+鏌�
+妗�
+铏�
+鐩�
+绱�
+鍏�
+閫�
+鏅�
+鐪�
+鏅�
+鍝�
+鍞�
+楦�
+鏅�
+鍝�
+鏅�
+鍓�
+鏅�
+铓�
+鐣�
+铓�
+铓�
+铓�
+铓�
+鍝�
+鍝�
+鍦�
+鍝�
+鍝�
+鎭�
+楦�
+鍞�
+鍞�
+鍝�
+鍞�
+鍟�
+鍞�
+鍞�
+缃�
+宄�
+宄�
+宄�
+鍦�
+宄�
+璐�
+璐�
+璧�
+璧�
+閽�
+閽�
+閽�
+閽�
+閾�
+閾�
+閾�
+缂�
+姘�
+姘�
+鐗�
+鐗�
+閫�
+涔�
+鏁�
+绉�
+绉�
+绉�
+绉�
+绉�
+绉�
+绉�
+閫�
+绗�
+绗�
+绗�
+鍊�
+鍊�
+鍊�
+鍊�
+淇�
+鍊�
+鍊�
+鍊�
+淇�
+鍊�
+鍊�
+璧�
+淇�
+鍊�
+鍊�
+鍋�
+鑷�
+灏�
+韬�
+鎭�
+鍊�
+寰�
+寰�
+娈�
+鑸�
+鑸�
+鑸�
+鑸�
+閫�
+鎷�
+鑰�
+鐖�
+鑸�
+鐖�
+璞�
+璞�
+棰�
+棰�
+缈�
+鑳�
+鑴�
+鑴�
+鑳�
+鑳�
+鑴�
+鑴�
+鑳�
+鑴�
+鑴�
+閫�
+鐙�
+鐙�
+鍗�
+閫�
+楦�
+鐣�
+楦�
+鐨�
+楗�
+棣�
+鍑�
+鍑�
+鎭�
+妗�
+娴�
+琛�
+琛�
+楂�
+閮�
+甯�
+鍑�
+搴�
+鐥�
+鐥�
+鐤�
+鏂�
+鐤�
+鐤�
+鐤�
+鑴�
+鏁�
+绂�
+绱�
+鍞�
+鐡�
+璧�
+鍑�
+绔�
+鍓�
+绔�
+閮�
+鏃�
+鏃�
+鐣�
+闃�
+缇�
+缇�
+鐡�
+鎷�
+绮�
+鏂�
+鐩�
+鍏�
+鐑�
+鐑�
+鐑�
+鐑�
+鐑�
+鐑�
+鐑�
+閫�
+娑�
+娴�
+娑�
+娴�
+閰�
+娑�
+娑�
+娑�
+娴�
+娴�
+娑�
+娴�
+娴�
+娑�
+娑�
+娴�
+娑�
+娑�
+娑�
+娴�
+娴�
+娑�
+鐑�
+娑�
+娑�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+瀹�
+瀹�
+瀹�
+瀹�
+瀹�
+瀹�
+绐�
+绐�
+瀹�
+瀹�
+妗�
+璇�
+鏈�
+璇�
+璇�
+璇�
+鎵�
+璇�
+琚�
+琚�
+琚�
+琚�
+绁�
+璇�
+鍐�
+璋�
+璋�
+鍐�
+璋�
+璋�
+璋�
+璋�
+鍓�
+鎭�
+灞�
+鍓�
+灞�
+寮�
+闄�
+绁�
+闄�
+闄�
+闄�
+濞�
+濞�
+鎭�
+濞�
+濞�
+閫�
+鑳�
+闅�
+棰�
+妗�
+缁�
+缁�
+楠�
+缁�
+楠�
+鐞�
+鐞�
+鐞�
+鐞�
+鐞�
+鎹�
+鍫�
+鎺�
+鎻�
+鍩�
+鎹�
+鎺�
+鎹�
+鎺�
+鐒�
+鎺�
+鎹�
+璧�
+鍫�
+鎺�
+鍩�
+鎺�
+鎺�
+鎹�
+鏁�
+鎺�
+鎺�
+鎺�
+鎺�
+鍩�
+鎺�
+鎺�
+鎺�
+鎺�
+鎹�
+鎺�
+鎺�
+鑱�
+鍩�
+鑱�
+鍕�
+鑱�
+濞�
+钁�
+鑿�
+鍕�
+榛�
+鑿�
+钀�
+钀�
+鑿�
+钀�
+鑿�
+钀�
+鑿�
+鑿�
+钀�
+鑿�
+钀�
+钀�
+涔�
+钀�
+钀�
+鑿�
+姊�
+褰�
+姊�
+濠�
+姊�
+姊�
+姊�
+姊�
+妫�
+姊�
+姊�
+妗�
+姊�
+鏁�
+鏇�
+鍓�
+绁�
+閰�
+閰�
+鍘�
+鎴�
+纭�
+纭�
+濂�
+鐩�
+鐖�
+鑱�
+琚�
+鐩�
+鍖�
+闆�
+杈�
+杈�
+棰�
+铏�
+褰�
+闆�
+鍫�
+甯�
+鐪�
+鍖�
+鏅�
+鐫�
+鐪�
+鐪�
+鎮�
+閲�
+鍟�
+鍟�
+鏇�
+鏅�
+鏅�
+鍟�
+鍟�
+璺�
+瓒�
+鍟�
+璺�
+鐣�
+铓�
+铔�
+铔�
+鍞�
+绱�
+閯�
+鍞�
+鎮�
+鍟�
+鍞�
+鍞�
+鍟�
+鍟�
+鍟�
+宕�
+宕�
+宕�
+閫�
+宕�
+甯�
+宕�
+宕�
+宕�
+濠�
+鍦�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+鐭�
+鐢�
+绉�
+姊�
+鐘�
+绉�
+绉�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+鏁�
+鍋�
+琚�
+鎮�
+鍋�
+鍋�
+鍋�
+鍋�
+鎮�
+鍞�
+鍋�
+鍋�
+韬�
+鍏�
+鍋�
+琛�
+寰�
+寰�
+寰�
+琛�
+鐩�
+鑸�
+鑸�
+鑸�
+鏂�
+鐩�
+楦�
+鏁�
+鎮�
+娆�
+褰�
+棰�
+鑴�
+鑴�
+鑴�
+璞�
+鑴�
+鑴�
+璞�
+澶�
+閫�
+鐚�
+鐚�
+鐚�
+鐚�
+鍑�
+鐚�
+鐚�
+绁�
+棣�
+棣�
+鍑�
+鍑�
+姣�
+鐑�
+搴�
+楹�
+搴�
+鐥�
+鐥�
+鐥�
+寤�
+搴�
+搴�
+楣�
+鐩�
+绔�
+绔�
+鍟�
+鏃�
+鏃�
+鏈�
+鐜�
+闃�
+闃�
+鐫�
+缇�
+鐩�
+鐪�
+绮�
+绮�
+绮�
+鏂�
+鍓�
+鍏�
+鐒�
+鐒�
+娓�
+娣�
+楦�
+娣�
+娑�
+娣�
+娓�
+娓�
+娣�
+娣�
+娣�
+娣�
+娣�
+娓�
+娣�
+娓�
+娣�
+娣�
+娑�
+娣�
+娣�
+娣�
+娣�
+娑�
+娑�
+濠�
+姊�
+娓�
+鎯�
+鎯�
+鎯�
+鎮�
+鎯�
+鎯�
+鎯�
+鎯�
+鎯�
+鎮�
+鎯�
+鎯�
+鎯�
+瀵�
+瀵�
+瀵�
+瀵�
+瀹�
+绐�
+绐�
+瀵�
+璋�
+璋�
+璋�
+璋�
+琚�
+绁�
+绁�
+璋�
+璋�
+璋�
+閫�
+鏁�
+灏�
+灞�
+寮�
+闅�
+鍫�
+闅�
+铔�
+闅�
+闅�
+闅�
+濠�
+濠�
+濠�
+棰�
+棰�
+缁�
+缁�
+缁�
+楠�
+缁�
+缁�
+缁�
+缁�
+缁�
+缁�
+缁�
+缁�
+缁�
+缂�
+宸�
+鐞�
+鐞�
+鐞�
+鐞�
+鏂�
+鏇�
+鎻�
+娆�
+鍫�
+濉�
+鎼�
+鍫�
+鎻�
+瓒�
+瓒�
+瓒�
+瓒�
+鎻�
+鍫�
+鎻�
+鍗�
+鎻�
+鍠�
+褰�
+鎻�
+鎻�
+鎻�
+鎼�
+鐓�
+鎻�
+鎼�
+瑁�
+鎼�
+鎼�
+鎼�
+鎼�
+澹�
+鎻�
+鎼�
+鎻�
+鏂�
+鏈�
+娆�
+鑱�
+钁�
+鏁�
+鎯�
+钁�
+鍕�
+钁�
+钁�
+钁�
+鏁�
+钁�
+钂�
+钂�
+钀�
+闊�
+鏈�
+杈�
+钁�
+妫�
+妫�
+妫�
+妞�
+妞�
+妫�
+鐒�
+妞�
+妞�
+妫�
+妫�
+妞�
+妫�
+妫�
+妫�
+妫�
+姒�
+妞�
+鎯�
+鎯�
+閫�
+绮�
+妫�
+閰�
+閰�
+鍘�
+鍘�
+纭�
+纭�
+纭�
+纭�
+闆�
+娈�
+瑁�
+闆�
+棰�
+闆�
+鏆�
+闆�
+缈�
+杈�
+鎮�
+绱�
+鍑�
+杈�
+鏁�
+妫�
+璧�
+鎺�
+鏅�
+鐫�
+鏆�
+鏈�
+鏅�
+閲�
+榧�
+鍠�
+鍠�
+鏅�
+鍠�
+閬�
+鍠�
+閬�
+鏅�
+鏅�
+鐣�
+璺�
+璺�
+璺�
+璺�
+璺�
+閬�
+铔�
+铔�
+铚�
+铚�
+铔�
+鍠�
+楣�
+鍠�
+鍠�
+鍠�
+鍠�
+鍟�
+鍠�
+宓�
+骞�
+甯�
+璧�
+璧�
+璧�
+璧�
+璧�
+榛�
+閾�
+閾�
+閾�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+鐢�
+鎺�
+鐭�
+鏅�
+姘�
+姣�
+姘�
+楣�
+鍓�
+绋�
+绋�
+绋�
+绋�
+绛�
+绛�
+绛�
+绛�
+绛�
+绛�
+绛�
+绛�
+绛�
+绛�
+鍌�
+鍌�
+鐗�
+鍫�
+闆�
+鐒�
+鍌�
+鍌�
+鐨�
+鐨�
+绮�
+濂�
+琛�
+鎯�
+寰�
+寰�
+鑹�
+鑸�
+閫�
+鐣�
+閲�
+绂�
+鑵�
+鑴�
+鑵�
+鑵�
+鑵�
+椴�
+鐚�
+鐚�
+鐚�
+鐚�
+鎯�
+鐒�
+棣�
+棣�
+瑁�
+铔�
+灏�
+鏁�
+鏂�
+鐥�
+鐥�
+鐥�
+鐥�
+绔�
+绔�
+闃�
+鍠�
+缈�
+缇�
+鏅�
+绮�
+灏�
+濂�
+閬�
+閬�
+鏇�
+鐒�
+娓�
+婊�
+婀�
+婀�
+娓�
+娓�
+娓�
+婀�
+娓�
+娓�
+婧�
+婧�
+婊�
+婀�
+娓�
+婀�
+娓�
+娓�
+婊�
+娓�
+婧�
+鎰�
+鎱�
+鎯�
+鎰�
+鎰�
+鎯�
+鎰�
+鎰�
+鎱�
+鍓�
+瀵�
+瀵�
+瀵�
+绐�
+绐�
+绐�
+绐�
+绐�
+閬�
+闆�
+瑁�
+瑁�
+瑁�
+绂�
+绂�
+璋�
+璋�
+璋�
+璋�
+鐘�
+灞�
+灞�
+寮�
+绮�
+鐤�
+闅�
+闅�
+闅�
+濯�
+绲�
+瀚�
+濯�
+濠�
+鐧�
+缂�
+缂�
+缂�
+缂�
+缂�
+缂�
+缂�
+楠�
+缂�
+楠�
+缂�
+鐟�
+楣�
+鐟�
+鐟�
+鐟�
+榄�
+鑲�
+鎽�
+鎽�
+濉�
+鎼�
+濉�
+榧�
+鎽�
+鎼�
+鎼�
+鎽�
+鎼�
+濉�
+鎽�
+鑱�
+鏂�
+钂�
+鍕�
+闈�
+闈�
+楣�
+钃�
+澧�
+骞�
+钃�
+钃�
+钂�
+钃�
+钂�
+钂�
+鐚�
+妞�
+绂�
+妤�
+妤�
+姒�
+鎯�
+妲�
+姒�
+妤�
+姒�
+璧�
+閰�
+閰�
+鎰�
+纰�
+纰�
+纰�
+纰�
+纰�
+纰�
+纰�
+灏�
+闆�
+闆�
+闆�
+闆�
+杈�
+杈�
+杈�
+鐫�
+棰�
+榫�
+閴�
+鐫�
+鐫�
+鐫�
+鐬�
+鐫�
+鐫�
+鐫�
+鍡�
+閯�
+鍡�
+鎰�
+鏆�
+鐩�
+姝�
+鏆�
+鏆�
+鐓�
+鐣�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+閬�
+铚�
+铚�
+铔�
+铚�
+铚�
+鍡�
+鍡�
+鍡�
+缃�
+缃�
+缃�
+缃�
+铚�
+骞�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+鐭�
+杈�
+绋�
+绋�
+棰�
+鎰�
+绛�
+绛�
+绠�
+绛�
+姣�
+鑸�
+榧�
+鍌�
+鍌�
+鍍�
+韬�
+榄�
+琛�
+寰�
+鎰�
+閬�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+楣�
+鑵�
+鑵�
+椴�
+鐚�
+棰�
+瑙�
+瑙�
+鐓�
+闆�
+棣�
+棣�
+閰�
+绂�
+鐥�
+寤�
+鐥�
+鐥�
+寤�
+闈�
+鏂�
+闊�
+鎰�
+瑾�
+绮�
+鏁�
+鐓�
+濉�
+鎱�
+鐓�
+鐓�
+婊�
+婕�
+婊�
+婧�
+婊�
+婊�
+婊�
+婧�
+婧�
+婕�
+婊�
+婧�
+婧�
+婊�
+婧�
+婧�
+绮�
+婊�
+鎱�
+瑾�
+濉�
+瀵�
+绐�
+绐�
+瀵�
+璋�
+瑜�
+瑁�
+绂�
+璋�
+缇�
+娈�
+杈�
+闅�
+濯�
+瀚�
+瀚�
+瀚�
+鍙�
+缂�
+缂�
+缂�
+缂�
+鍓�
+闈�
+纰�
+鐠�
+璧�
+鐔�
+澧�
+澧�
+鍢�
+鎽�
+璧�
+鎴�
+瑾�
+澧�
+鎽�
+鎽�
+鎾�
+鑱�
+鎱�
+鏆�
+鎽�
+钄�
+钄�
+钄�
+钄�
+钄�
+钄�
+鐔�
+钄�
+鍏�
+妯�
+妲�
+姒�
+姒�
+姒�
+姒�
+姝�
+閬�
+閰�
+閰�
+閰�
+閰�
+纰�
+纰�
+纰�
+纾�
+鎰�
+闇�
+杈�
+杈�
+闆�
+瑁�
+棰�
+鐬�
+澧�
+鍡�
+韪�
+铚�
+铚�
+铦�
+铚�
+铦�
+鍢�
+鍢�
+璧�
+閿�
+閿�
+闀�
+鑸�
+鑸�
+绋�
+鐔�
+绠�
+绠�
+绠�
+绠�
+绠�
+鑸�
+鍍�
+鍍�
+榧�
+榄�
+榄�
+璨�
+鑶�
+鑶�
+鑶�
+椴�
+鐤�
+瀛�
+棣�
+瑁�
+鏁�
+璞�
+鑶�
+閬�
+鑵�
+鐦�
+鐦�
+鐦�
+杈�
+褰�
+绔�
+绔�
+鏃�
+绮�
+绮�
+姝�
+寮�
+鐔�
+鐔�
+鐓�
+娼�
+婕�
+婕�
+婕�
+婕�
+婊�
+婕�
+婕�
+婕�
+鎱�
+鎱�
+瀵�
+璧�
+瀵�
+瀵�
+铚�
+瀵�
+璋�
+鑲�
+瑜�
+瑜�
+璋�
+闅�
+瀚�
+缈�
+鐔�
+鍑�
+楠�
+缂�
+鎱�
+鎾�
+鎾�
+鎾�
+鎾�
+瓒�
+瓒�
+鎾�
+鎾�
+鎾�
+鎾�
+鎿�
+澧�
+鎾�
+鎾�
+澧�
+鎾�
+鑱�
+闉�
+闉�
+钑�
+钑�
+钄�
+钑�
+妯�
+妲�
+妯�
+姗�
+妯�
+姗�
+鏁�
+璞�
+椋�
+閱�
+閱�
+閱�
+纾�
+纾�
+纾�
+纰�
+闇�
+闇�
+闇�
+鐬�
+棰�
+鏆�
+鐬�
+鍢�
+鍢�
+鍢�
+鍢�
+褰�
+韪�
+韪�
+韪�
+韪�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+鍢�
+鍢�
+骞�
+澧�
+闀�
+闀�
+闀�
+闈�
+绋�
+绋�
+榛�
+绋�
+绋�
+绠�
+绡�
+绠�
+绡�
+鍍�
+韬�
+鍍�
+寰�
+鑹�
+鑶�
+鑶�
+椴�
+椴�
+鐔�
+鎽�
+瑜�
+鐦�
+鐦�
+鐦�
+鍑�
+棰�
+姣�
+绯�
+閬�
+鎲�
+娼�
+婢�
+娼�
+娼�
+椴�
+婢�
+娼�
+婢�
+婢�
+婢�
+鎳�
+鎲�
+鎳�
+鎲�
+棰�
+缈�
+瑜�
+璋�
+楣�
+鎲�
+鎱�
+鍔�
+灞�
+璞�
+缂�
+鎾�
+鎿�
+鎿�
+鎿�
+鐕�
+钑�
+钖�
+钖�
+钖�
+鎿�
+钖�
+钖�
+棰�
+缈�
+鍣�
+姗�
+姗�
+姗�
+鏁�
+铻�
+鐡�
+閱�
+闇�
+闇�
+杈�
+鍐�
+椁�
+鍢�
+韪�
+韫�
+韫�
+锜�
+铻�
+鍣�
+鍣�
+楣�
+璧�
+榛�
+榛�
+闀�
+璧�
+绌�
+绡�
+绡�
+绡�
+绡�
+鍎�
+閭�
+琛�
+鑶�
+闆�
+椴�
+纾�
+鐦�
+鐦�
+鍑�
+杈�
+杈�
+绯�
+绯�
+绯�
+鐕�
+婵�
+婢�
+婵�
+鎳�
+鎲�
+鎳�
+绐�
+澹�
+閬�
+缂�
+缂�
+鎴�
+鎿�
+钘�
+闉�
+钘�
+钘�
+妾�
+妾�
+妾�
+绀�
+纾�
+闇�
+闇�
+鐬�
+鐬�
+鐬�
+鐬�
+鐬�
+鐬�
+鏇�
+韫�
+韫�
+铻�
+锜�
+锜�
+鍤�
+璧�
+绌�
+榄�
+绨�
+绨�
+绻�
+寰�
+鐖�
+鏈�
+鑷�
+槌�
+鐧�
+杈�
+璧�
+绯�
+绯�
+鐕�
+鎳�
+璞�
+鑷�
+鑷�
+缈�
+楠�
+钘�
+闉�
+钘�
+瑕�
+鐬�
+韫�
+鍤�
+闀�
+缈�
+槌�
+楣�
+鐎�
+瑗�
+鐠�
+鎴�
+瀛�
+璀�
+铇�
+钘�
+鏀�
+鏇�
+韫�
+韫�
+韫�
+宸�
+绨�
+绨�
+锜�
+棰�
+闈�
+鐧�
+鐡�
+缇�
+槌�
+鐖�
+鐤�
+楝�
+澹�
+棣�
+鑰�
+韬�
+锠�
+鍤�
+鍤�
+宸�
+绫�
+槌�
+榄�
+绯�
+鐏�
+璀�
+锠�
+闇�
+闇�
+闇�
+韬�
+榛�
+楂�
+璧�
+鍥�
+闀�
+鐡�
+缃�
+鐭�
+涔�
+涔�
+鍏�
+寮�
+瀛�
+瀛�
+骞�
+浜�
+闊�
+寤�
+涓�
+鍗�
+浠�
+鍘�
+浠�
+浠�
+浠�
+鍏�
+鍒�
+鐖�
+鍗�
+闂�
+璁�
+灏�
+澶�
+鐖�
+姣�
+閭�
+閭�
+鑹�
+鑹�
+鏈�
+鍙�
+鍖�
+涓�
+鍖�
+鍔�
+鍗�
+鍙�
+鍙�
+浠�
+浠�
+浠�
+浠�
+浠�
+浠�
+鍗�
+姘�
+鐘�
+鍒�
+閭�
+閭�
+姹�
+璁�
+璁�
+璁�
+璁�
+灏�
+闃�
+灏�
+寮�
+椹�
+鍖�
+鑰�
+鐜�
+鐜�
+閭�
+鍦�
+鍦�
+鍦�
+鎵�
+鍦�
+鍦�
+鍦�
+鎵�
+鍦�
+鍦�
+鑺�
+鑺�
+鑺�
+鑺�
+鑺�
+鑺�
+鑺�
+浜�
+鍘�
+澶�
+鎴�
+灏�
+涔�
+鏃�
+鏇�
+宀�
+灞�
+鍑�
+鍥�
+閽�
+缂�
+姘�
+姘�
+鐗�
+浼�
+浼�
+浼�
+浣�
+浠�
+浼�
+浼�
+浼�
+浼�
+鍥�
+姹�
+鍒�
+澶�
+鏃�
+鍒�
+鐘�
+鐘�
+鑸�
+鍑�
+閭�
+楗�
+姹�
+姹�
+姹�
+姹�
+姹�
+姹�
+蹇�
+蹇�
+璁�
+璁�
+绁�
+璁�
+鑱�
+鑹�
+鍘�
+闃�
+闃�
+闃�
+涓�
+濡�
+鐗�
+绾�
+绾�
+绾�
+绾�
+鐜�
+鐜�
+鎶�
+鎶�
+鍦�
+鍧�
+鍧�
+鍧�
+鎶�
+鎶�
+悃�
+鑺�
+閭�
+鑺�
+鑺�
+鑻�
+鑻�
+鑺�
+鑺�
+鑻�
+鑺�
+鑻�
+鑻�
+鑺�
+鑺�
+鑺�
+鑺�
+鑻�
+鑻�
+鑻�
+鏉�
+鏉�
+鏉�
+鏉�
+蹇�
+瀛�
+閭�
+閭�
+鐭�
+濂�
+璞�
+蹇�
+娆�
+杞�
+杩�
+閭�
+蹇�
+鍗�
+閭�
+鏃�
+鍛�
+鍛�
+鍛�
+鍛�
+鍛�
+鍛�
+鏃�
+鍚�
+鐢�
+铏�
+鍛�
+鍚�
+鍚�
+鍚�
+甯�
+宀�
+宀�
+宀�
+宀�
+宀�
+鍏�
+鍥�
+鍥�
+閽�
+閽�
+閽�
+杩�
+姘�
+姘�
+鐗�
+浣�
+閭�
+鏀�
+浣�
+浣�
+浣�
+浣�
+浼�
+褰�
+浣�
+浣�
+瀛�
+璞�
+鍧�
+鑲�
+閭�
+濂�
+鍔�
+鐙�
+鐙�
+楦�
+閭�
+楗�
+楗�
+楗�
+楗�
+楗�
+浜�
+搴�
+搴�
+鐤�
+鐤�
+鑲�
+闂�
+闂�
+闂�
+缇�
+鐐�
+娌�
+娌�
+娌�
+娌�
+娌�
+娌�
+娌�
+姹�
+姹�
+娌�
+姹�
+娌�
+姹�
+姹�
+娌�
+娌�
+娉�
+鎬�
+鎬�
+蹇�
+蹇�
+蹇�
+鎬�
+蹇�
+蹇�
+鎬�
+蹇�
+蹇�
+璇�
+璇�
+璇�
+璇�
+璇�
+璇�
+璇�
+瀛�
+闄�
+闄�
+闄�
+闄�
+濡�
+濡�
+濡�
+濡�
+濡�
+濡�
+濡�
+濡�
+濮�
+濡�
+閭�
+鍔�
+鍒�
+鐢�
+閭�
+绾�
+绾�
+绾�
+绾�
+绾�
+鐜�
+鐜�
+鐜�
+鐜�
+鐜�
+鐜�
+鐜�
+鐩�
+蹇�
+鍖�
+鍧�
+鎶�
+鎷�
+鍧�
+鎷�
+鍨�
+鎶�
+鍔�
+鎷�
+鎷�
+鍧�
+鍧�
+悃�
+鍧�
+鍧�
+鎶�
+鍧�
+鑰�
+鑻�
+鑻�
+鑻�
+鑼�
+鑻�
+鑻�
+鑻�
+鑻�
+鑻�
+鑼�
+鑻�
+鑻�
+鑼�
+鑼�
+鑼�
+鑼�
+鑼�
+鑼�
+鑼�
+鑻�
+鏋�
+鏋�
+鏉�
+鏉�
+鏋�
+鏉�
+鏋�
+鏋�
+鏋�
+鏉�
+鏉�
+鏉�
+鐭�
+鐮�
+鍒�
+濂�
+鐡�
+娈�
+閮�
+杞�
+閮�
+楦�
+鐩�
+鏄�
+鏄�
+鏉�
+鏄�
+鍜�
+鍛�
+鏄�
+鏄�
+鏃�
+鏄�
+鐐�
+鍜�
+鐣�
+铏�
+鍜�
+鍛�
+榛�
+鍛�
+鍛�
+鍜�
+鍜�
+鍜�
+鍛�
+鍛�
+鍛�
+鍜�
+宀�
+宀�
+宀�
+宀�
+甯�
+宀�
+宄�
+鍒�
+杩�
+宀�
+鍓�
+甯�
+宄�
+娌�
+鍥�
+缃�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閭�
+杩�
+鐗�
+绔�
+杩�
+浣�
+浣�
+浣�
+渚�
+渚�
+鑷�
+宀�
+渚�
+渚�
+渚�
+渚�
+浣�
+浣�
+渚�
+浣�
+浣�
+渚�
+甯�
+闃�
+渚�
+寰�
+鍒�
+閮�
+鎬�
+绫�
+鐡�
+鎴�
+鑲�
+鋸�
+鑲�
+鑲�
+鑲�
+鍓�
+杩�
+閮�
+鐙�
+鐙�
+鐙�
+鐙�
+鍜�
+鐐�
+鏋�
+楗�
+楗�
+鍐�
+鍐�
+搴�
+鐤�
+鐤�
+鐤�
+鍏�
+濡�
+鍔�
+鐐�
+瓞壖
+鐐�
+鐐�
+鐐�
+鐐�
+娉�
+娌�
+娉�
+娉�
+娉�
+娉�
+娉�
+娉�
+娉�
+娉�
+娉�
+娉�
+娌�
+娉�
+娉�
+娉�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+悚�
+鎬�
+鎬�
+鎬�
+瀹�
+绌�
+瀹�
+璇�
+璇�
+璇�
+璇�
+鎴�
+璇�
+鎴�
+閮�
+琛�
+绁�
+绁�
+绁�
+绁�
+璇�
+璇�
+璇�
+璇�
+璇�
+璇�
+璇�
+璇�
+璇�
+鎴�
+瀛�
+浜�
+闄�
+濡�
+濡�
+濮�
+甯�
+寮�
+瀛�
+椹�
+铏�
+杩�
+杩�
+缁�
+缁�
+缁�
+椹�
+椹�
+缁�
+缁�
+椹�
+楠�
+鐢�
+鐝�
+鐝�
+鐝�
+鐝�
+鐜�
+鐝�
+椤�
+鐝�
+鐝�
+鎷�
+鍨�
+鎸�
+鍨�
+鎸�
+鍨�
+璧�
+璐�
+鍨�
+鍨�
+閮�
+鍨�
+鍨�
+鎸�
+鍨�
+鑼�
+鑽�
+鑽�
+璐�
+鑽�
+鑾�
+鑼�
+鑼�
+鑼�
+鑾�
+鑽�
+鑼�
+鑽�
+鑽�
+鑽�
+鑽�
+鑽�
+鑼�
+鑽�
+鑼�
+鑼�
+鍨�
+鑽�
+鑽�
+鑽�
+鑽�
+鍓�
+鑽�
+鑼�
+鑽�
+鑽�
+鏌�
+鏍�
+鏌�
+鏌�
+鏍�
+鏌�
+鏋�
+鏍�
+鏌�
+鏋�
+鏌�
+鏋�
+鏌�
+鏌�
+鏍�
+鏌�
+鏍�
+鏋�
+鏌�
+鏌�
+鏋�
+鏌�
+鍓�
+閰�
+閮�
+鐢�
+鐮�
+鐮�
+鐮�
+鏂�
+鐮�
+鐮�
+濂�
+鑰�
+铏�
+娈�
+娈�
+娈�
+娈�
+杞�
+杞�
+杞�
+杞�
+杞�
+铏�
+姣�
+瑙�
+灏�
+鍝�
+鐪�
+鐪�
+馉硱
+閮�
+鐪�
+鐪�
+鐪�
+绂�
+鍝�
+鍜�
+鏇�
+鏄�
+鏄�
+鏄�
+鍜�
+鍝�
+鍝�
+鐣�
+姣�
+鍛�
+鑳�
+鐣�
+鐣�
+铏�
+铏�
+鐩�
+鍜�
+鍝�
+鍓�
+閮�
+鍜�
+鍥�
+鍜�
+鍝�
+鍝�
+鍝�
+鍜�
+鍜�
+鍜�
+鍝�
+鍝�
+鍝�
+宄�
+宄�
+缃�
+甯�
+宄�
+宄�
+宄�
+宄�
+璐�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+姘�
+姘�
+鐗�
+閮�
+绉�
+绉�
+绔�
+绗�
+绗�
+淇�
+淇�
+淇�
+淇�
+鍙�
+鍨�
+鐗�
+淇�
+淇�
+鐨�
+淇�
+淇�
+閫�
+寰�
+寰�
+鑸�
+淇�
+閮�
+淇�
+閮�
+鐖�
+閮�
+鐡�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鏈�
+鑳�
+楦�
+鍖�
+鐙�
+鐙�
+椋�
+鐙�
+鐙�
+瑷�
+閫�
+鏄�
+楗�
+楗�
+楗�
+鑳�
+瀛�
+濞�
+寮�
+濂�
+搴�
+鐤�
+鐤�
+鐤�
+鐤�
+搴�
+绔�
+褰�
+椋�
+闂�
+闂�
+闂�
+闃�
+缇�
+杩�
+绫�
+閰�
+鐐�
+鐐�
+鐐�
+鐐�
+鐑�
+鐐�
+鐑�
+娲�
+娲�
+娲�
+娲�
+娴�
+娲�
+娲�
+娲�
+娑�
+娲�
+娲�
+娴�
+娲�
+娲�
+娴�
+娴�
+娴�
+娲�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+瀹�
+鎵�
+琛�
+琛�
+琛�
+琚�
+绁�
+绁�
+绁�
+绁�
+璇�
+绁�
+绁�
+璇�
+璇�
+楦�
+鏄�
+閮�
+鍜�
+寮�
+鐗�
+鑳�
+闄�
+闄�
+濞�
+濮�
+濞�
+濮�
+濮�
+濮�
+濮�
+鎬�
+缇�
+鐐�
+鐭�
+缁�
+楠�
+楠�
+缁�
+缁�
+楠�
+鑰�
+鎸�
+鐝�
+鐝�
+椤�
+鐝�
+鐝�
+鐝�
+鐝�
+鐝�
+鐞�
+鐝�
+鏁�
+鎭�
+鍩�
+鍩�
+鍩�
+鍩�
+鍩�
+鎸�
+鑰�
+鑰�
+鍩�
+鎹�
+璐�
+鍨�
+鎹�
+鐩�
+鑽�
+鑾�
+鑾�
+鑾�
+鑾�
+鑾�
+鑾�
+鑾�
+鑾�
+鑽�
+鑾�
+鑽�
+鑾�
+鑽�
+鑾�
+鑾�
+鑾�
+鑾�
+娓�
+楦�
+鑾�
+鏍�
+鏍�
+閮�
+妗�
+妗�
+妗�
+妗�
+妗�
+姊�
+鏍�
+妗�
+妗�
+妗�
+妗�
+鏍�
+妗�
+鏍�
+閫�
+閫�
+褰�
+楝�
+璞�
+閰�
+閫�
+鍘�
+瀛�
+鐮�
+鐮�
+鐮�
+鐮�
+鐮�
+鐮�
+鐮�
+鐮�
+鐮�
+鍓�
+鐮�
+杞�
+杞�
+杈�
+楦�
+瓒�
+榫�
+楦�
+铏�
+閫�
+鐪�
+鍞�
+鏅�
+鐪�
+鐪�
+鍝�
+鍝�
+鍞�
+鏅�
+鏅�
+楦�
+瓒�
+瓒�
+鐣�
+铓�
+铓�
+铓�
+铓�
+铓�
+铓�
+铓�
+鍞�
+鍦�
+鍞�
+鍞�
+鐩�
+鍞�
+宕�
+宕�
+缃�
+缃�
+宄�
+瑙�
+璧�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+浈�
+閾�
+姘�
+姘�
+姘�
+姣�
+鑸�
+绉�
+绉�
+鐩�
+绗�
+绗�
+绗�
+绗�
+绗�
+淇�
+鍊�
+淇�
+鍋�
+淇�
+淇�
+鍊�
+鍊�
+鎭�
+鍊�
+鍊�
+淇�
+鍊�
+闅�
+闅�
+鍊�
+鍊�
+鑷�
+鐨�
+閮�
+鍊�
+琛�
+棰�
+寰�
+鑸�
+閲�
+濂�
+琛�
+鑳�
+鑳�
+鑳�
+鑳�
+鑴�
+鑳�
+鏈�
+鑴�
+鑳�
+楦�
+鐜�
+楦�
+鐙�
+鐚�
+鐙�
+鐚�
+鐙�
+閫�
+妗�
+琚�
+楗�
+鍑�
+鏍�
+鎸�
+浜�
+鐤�
+鐤�
+鐤�
+鐤�
+鐥�
+鐤�
+鐥�
+鐥�
+琛�
+鍑�
+棰�
+鎭�
+鏃�
+鏃�
+鏃�
+闃�
+闃�
+瑷�
+闃�
+鎭�
+绮�
+鏈�
+閮�
+鐑�
+鐑�
+鐑�
+鐑�
+鍓�
+閮�
+鐑�
+娑�
+娴�
+娑�
+娑�
+濞�
+娑�
+娑�
+娴�
+娑�
+娴�
+娑�
+娴�
+娴�
+娴�
+娴�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+瀹�
+绐�
+鍓�
+璇�
+鍐�
+璇�
+琚�
+琚�
+绁�
+璇�
+璋�
+璋�
+璋�
+璋�
+灞�
+灞�
+闄�
+鍕�
+濂�
+鐗�
+铓�
+闄�
+濮�
+濞�
+濞�
+濞�
+濞�
+濞�
+濞�
+濞�
+濞�
+濠�
+鐣�
+閫�
+缁�
+楠�
+缁�
+楠�
+缁�
+缁�
+缁�
+楠�
+閭�
+楦�
+褰�
+鑰�
+鐒�
+鑸�
+鐞�
+鐞�
+楹�
+鎻�
+鍩�
+鍩�
+鎹�
+鎺�
+鎺�
+鍩�
+鍩�
+璧�
+鍩�
+鎹�
+閫�
+鍩�
+鍫�
+鍫�
+鎺�
+楦�
+鎺�
+鎹�
+鎺�
+鍫�
+鎺�
+鎹�
+鎺�
+鎮�
+鍩�
+鍩�
+鎺�
+鎺�
+鑱�
+鑿�
+钀�
+鑿�
+鍫�
+钀�
+钀�
+鑿�
+鑿�
+钀�
+钀�
+钀�
+妫�
+鑿�
+鑿�
+钀�
+钀�
+鑿�
+鑿�
+鑿�
+鑿�
+鑿�
+钀�
+鑿�
+鑿�
+姊�
+姊�
+姊�
+瑙�
+妗�
+妗�
+姊�
+妫�
+妗�
+妫�
+鍟�
+閮�
+鍖�
+鏁�
+璞�
+閯�
+閰�
+閰�
+鎴�
+纭�
+纭�
+纭�
+纭�
+纭�
+纭�
+纭�
+纭�
+楦�
+鐡�
+鍖�
+鍘�
+榫�
+娈�
+娈�
+娈�
+璧�
+闆�
+杈�
+鍫�
+鐪�
+鐪�
+鍟�
+鏅�
+鏅�
+鐪�
+鐪�
+鐪�
+鍦�
+鍠�
+鍠�
+鍟�
+鍕�
+鏅�
+鍞�
+鏅�
+鍐�
+鍟�
+鐣�
+瓒�
+鍟�
+璺�
+铓�
+铔�
+铔�
+铔�
+铓�
+铔�
+鍦�
+铓�
+铔�
+铔�
+铓�
+鍟�
+鍟�
+鍞�
+鍟�
+鍞�
+鍞�
+鍟�
+鍟�
+鍟�
+鍟�
+鍞�
+鍞�
+鍟�
+甯�
+宕�
+宕�
+甯�
+宕�
+宕�
+宕�
+璧�
+璧�
+璧�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+姘�
+鐗�
+楦�
+绉�
+閫�
+绗�
+绛�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+鍋�
+鍋�
+鍋�
+鍋�
+鍌�
+鍋�
+鍋�
+鐨�
+鐨�
+楦�
+寰�
+鑸�
+鑸�
+鑸�
+鑸�
+榫�
+缈�
+鑴�
+鑴�
+鑴�
+鍖�
+鐚�
+鐚�
+鐚�
+鐚�
+鏂�
+鐚�
+棣�
+棣�
+棣�
+楦�
+瀛�
+搴�
+搴�
+鐥�
+鐥�
+鐤�
+缈�
+鏃�
+鏃�
+琚�
+闃�
+闃�
+闃�
+闃�
+闃�
+闃�
+闃�
+缇�
+绮�
+绮�
+鏁�
+鐒�
+鐑�
+鐒�
+鐑�
+鐒�
+鐑�
+鐒�
+娓�
+娓�
+娣�
+娣�
+娣�
+娓�
+娑�
+娣�
+鎸�
+娣�
+娑�
+娓�
+娣�
+娣�
+娣�
+娑�
+娣�
+娑�
+娓�
+娣�
+鎯�
+鎮�
+鎮�
+鎯�
+鎯�
+鎮�
+鎯�
+鎯�
+鎯�
+鎯�
+绐�
+璋�
+璋�
+鎵�
+鐨�
+璋�
+瑁�
+琚�
+瑁�
+璋�
+璋�
+璋�
+璋�
+璋�
+璋�
+璋�
+璋�
+閫�
+閮�
+闅�
+绮�
+闅�
+闅�
+濠�
+濠�
+濠�
+濞�
+濠�
+濠�
+鑳�
+琚�
+缈�
+鎭�
+娆�
+缁�
+楠�
+缁�
+缁�
+缁�
+楠�
+缁�
+楠�
+缁�
+缁�
+缁�
+缁�
+楠�
+缂�
+鑰�
+鐞�
+鐞�
+鐞�
+鐞�
+鐟�
+鐞�
+鐞�
+鐞�
+闈�
+鐞�
+鐞�
+鐞�
+鐞�
+鐞�
+鐞�
+杈�
+榧�
+鎻�
+鍫�
+鎼�
+鎻�
+鎻�
+鍫�
+瓒�
+鎻�
+棰�
+濉�
+鎻�
+鑰�
+鎻�
+铔�
+铔�
+濉�
+鎽�
+鎻�
+鎺�
+鑱�
+钁�
+钁�
+闈�
+闈�
+钁�
+钁�
+钁�
+钀�
+钁�
+钁�
+钁�
+钂�
+钀�
+鎴�
+钁�
+妤�
+妫�
+妞�
+妫�
+妞�
+妫�
+璧�
+妞�
+妞�
+妞�
+妫�
+妞�
+楣�
+瑕�
+閰�
+閰�
+閰�
+楣�
+鍘�
+娈�
+娈�
+闆�
+闆�
+杈�
+杈�
+妞�
+杈�
+杈�
+鏂�
+鐫�
+鐫�
+鐫�
+鐫�
+鎴�
+鍠�
+鍡�
+鍠�
+鍠�
+鍠�
+鏅�
+鍠�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+鍠�
+鍠�
+鍟�
+鍡�
+鍠�
+鍡�
+鍠�
+鍡�
+鍠�
+鍠�
+鍠�
+宓�
+宓�
+宕�
+閬�
+瑭�
+宓�
+宕�
+宓�
+宓�
+宓�
+宓�
+宓�
+骞�
+宓�
+璧�
+閾�
+閾�
+閾�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+鎺�
+鐭�
+姘�
+姣�
+姣�
+鐘�
+鐘�
+鐘�
+楣�
+鐘�
+宓�
+榛�
+绋�
+绋�
+绛�
+绛�
+绛�
+鍌�
+鍌�
+鑸�
+鐗�
+鍌�
+鍌�
+閬�
+鍌�
+閬�
+寰�
+濯�
+鐣�
+寮�
+棰�
+缈�
+閲�
+楣�
+鑸�
+璨�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+楸�
+椴�
+椴�
+棰�
+鐚�
+鐚�
+鐚�
+椋�
+瑙�
+瑙�
+鐚�
+棰�
+椋�
+棣�
+棣�
+浜�
+鑴�
+瑁�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+璧�
+绔�
+鐡�
+鍟�
+棰�
+楣�
+闃�
+闃�
+闃�
+绮�
+閬�
+瀛�
+鐒�
+鐒�
+鐒�
+鐒�
+楣�
+婀�
+娓�
+婀�
+婀�
+婀�
+娓�
+婀�
+婀�
+婧�
+婀�
+婧�
+婀�
+婀�
+婀�
+娓�
+婀�
+婊�
+鎰�
+鎯�
+鎰�
+鎯�
+鎰�
+鎰�
+鎰�
+鍠�
+瀵�
+璋�
+鎵�
+瑁�
+瑁�
+瑁�
+绁�
+绁�
+璋�
+骞�
+璋�
+璋�
+璋�
+閬�
+瀛�
+寮�
+宸�
+楠�
+濯�
+濯�
+濠�
+宸�
+缈�
+鐨�
+濠�
+楠�
+缂�
+缂�
+缂�
+褰�
+缂�
+缂�
+缂�
+缂�
+缂�
+缂�
+椋�
+鑰�
+鐟�
+鐟�
+鐟�
+鐟�
+鐟�
+鐟�
+閬�
+楠�
+闊�
+楂�
+濉�
+閯�
+瓒�
+瓒�
+鎽�
+鎽�
+铚�
+鎼�
+鎼�
+鎼�
+鎼�
+鎼�
+鎽�
+褰�
+姣�
+鎼�
+鎼�
+钃�
+鎴�
+钃�
+閯�
+闈�
+钃�
+钃�
+楣�
+钂�
+钃�
+钃�
+钃�
+钂�
+钃�
+钃�
+钂�
+钂�
+钃�
+钂�
+钂�
+钂�
+钂�
+钂�
+钃�
+棰�
+妤�
+妤�
+妤�
+妤�
+妤�
+妤�
+妞�
+妲�
+妤�
+鐨�
+姒�
+妲�
+姒�
+妤�
+妤�
+妤�
+妞�
+瑁�
+鍓�
+鐢�
+閰�
+閰�
+閰�
+閰�
+铚�
+纰�
+纰�
+纭�
+纰�
+纰�
+纰�
+纰�
+楣�
+杈�
+榫�
+榫�
+瑷�
+绮�
+铏�
+鐫�
+鍡�
+闊�
+鍡�
+鍡�
+鐫�
+鐫�
+闆�
+鐫�
+鍢�
+鍡�
+鍡�
+鍡�
+鍡�
+鍡�
+鎴�
+鍡�
+鐓�
+鏆�
+閬�
+鏆�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+铔�
+铚�
+铚�
+铚�
+铚�
+鐣�
+铔�
+鍡�
+鍡�
+鍡�
+鍡�
+鍡�
+鍡�
+鍡�
+鍡�
+鍡�
+鍡�
+鍡�
+缃�
+宓�
+宓�
+宓�
+楠�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+闆�
+姘�
+鐘�
+姝�
+绋�
+绋�
+绋�
+绛�
+绛�
+绛�
+绛�
+绛�
+鐗�
+鐓�
+鏁�
+寰�
+鎰�
+鑹�
+瑙�
+姣�
+璨�
+璨�
+璨�
+棰�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+濉�
+濯�
+瑭�
+椴�
+椴�
+椴�
+椴�
+绋�
+椴�
+椴�
+鑲�
+楣�
+椋�
+瑙�
+閬�
+棣�
+楣�
+浜�
+鐦�
+鐥�
+鐥�
+鐥�
+鐦�
+鐦�
+鐦�
+楹�
+瑁�
+姝�
+鏃�
+闆�
+闃�
+闃�
+闃�
+缇�
+璞�
+绮�
+鐚�
+鐓�
+鐓�
+鐓�
+鐓�
+鐓�
+鐓�
+鐓�
+婊�
+婧�
+婧�
+婕�
+婊�
+婧�
+婧�
+婧�
+瑁�
+婧�
+婧�
+婊�
+婊�
+婧�
+婊�
+婊�
+婊�
+婧�
+婊�
+婊�
+婧�
+婊�
+鎰�
+鎱�
+鎱�
+椴�
+楠�
+绐�
+绐�
+绐�
+瑁�
+瑜�
+瑁�
+瑁�
+瑁�
+绂�
+璋�
+璋�
+濯�
+瀚�
+濯�
+瀚�
+瀚�
+濯�
+缂�
+缂�
+缂�
+杈�
+楠�
+缂�
+缂�
+缂�
+缂�
+楠�
+鑰�
+鐠�
+鐟�
+鐟�
+鐛�
+瑙�
+鎱�
+瀚�
+闊�
+鍙�
+楂�
+鎽�
+澧�
+鎾�
+鎽�
+鎾�
+缈�
+韪�
+鎽�
+澧�
+澧�
+姒�
+缍�
+钄�
+钄�
+闈�
+闈�
+闉�
+闈�
+鐢�
+钄�
+钄�
+钄�
+鎴�
+钑�
+钄�
+钃�
+鏂�
+楣�
+钃�
+姒�
+姒�
+姒�
+姒�
+姒�
+妲�
+姒�
+妲�
+妲�
+妲�
+姒�
+鍍�
+閰�
+閰�
+閰�
+鍘�
+纰�
+纰�
+纰�
+纰�
+纾�
+鑷�
+璞�
+娈�
+闇�
+闇�
+杈�
+铚�
+瑁�
+缈�
+榫�
+榫�
+鐫�
+鋪�
+鐫�
+鍢�
+鍢�
+鍢�
+鍢�
+鍢�
+鏆�
+鏆�
+韪�
+韪�
+铚�
+铚�
+铚�
+铦�
+铚�
+铚�
+铚�
+铚�
+铚�
+铻�
+铚�
+鍢�
+鍢�
+楣�
+鍢�
+鍢�
+鍢�
+鍡�
+鍢�
+缃�
+缃�
+骞�
+宥�
+骞�
+璧�
+缃�
+楠�
+楠�
+楣�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+闀�
+闀�
+鐘�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+姣�
+鍍�
+鍎�
+鍍�
+鍍�
+鍔�
+鍍�
+榄�
+榄�
+鐫�
+鑹�
+閯�
+鑶�
+鑶�
+椴�
+椴�
+椴�
+椴�
+椴�
+鐛�
+瑙�
+闆�
+澶�
+棣�
+閵�
+濉�
+楹�
+鐦�
+鐦�
+鐦�
+鐦�
+寤�
+闊�
+鏃�
+鑶�
+闃�
+閯�
+椴�
+绮�
+绮�
+绮�
+绯�
+妲�
+楣�
+鐔�
+鐔�
+娼�
+婕�
+婊�
+婕�
+婕�
+娼�
+娼�
+婕�
+婕�
+婕�
+婕�
+婢�
+娼�
+鎱�
+鎼�
+绐�
+瀵�
+缍�
+璋�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+璋�
+璋�
+璋�
+鏆�
+灞�
+楣�
+瀚�
+瀚�
+瀚�
+瀚�
+瀚�
+瀚�
+瀚�
+榧�
+缈�
+鐬�
+楣�
+楠�
+缂�
+缂�
+缂�
+缂�
+楠�
+缂�
+缂�
+鑰�
+鑰�
+鐟�
+鐠�
+鐠�
+鐠�
+鐠�
+鐠�
+鐠�
+濂�
+楂�
+楂�
+鎾�
+鎾�
+璧�
+鎾�
+閶�
+鎾�
+鎾�
+澧�
+鑱�
+瑙�
+闉�
+钑�
+闉�
+钑�
+钑�
+钑�
+钑�
+钑�
+鐬�
+钑�
+钑�
+璧�
+妲�
+妯�
+妲�
+妯�
+妯�
+妯�
+妲�
+閱�
+閱�
+闈�
+榄�
+椁�
+纾�
+纾�
+闇�
+杈�
+榫�
+榫�
+瑙�
+鐬�
+鐬�
+鐬�
+鍢�
+鍣�
+鍣�
+棰�
+鏆�
+鍣�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+铦�
+铦�
+铦�
+铦�
+铦�
+铻�
+铦�
+铦�
+铦�
+鍣�
+鍢�
+棰�
+鍣�
+鍣�
+鍣�
+鍣�
+鍣�
+鍣�
+棰�
+骞�
+骞�
+宥�
+宥�
+楠�
+楠�
+楠�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+绋�
+绠�
+绡�
+绡�
+绡�
+绡�
+鐗�
+鍎�
+寰�
+纾�
+铏�
+楣�
+鑶�
+婊�
+椴�
+椴�
+椴�
+椴�
+椴�
+椴�
+椴�
+鐛�
+鐛�
+瑙�
+棣�
+棣�
+楹�
+寤�
+鐦�
+鐦�
+鐦�
+鐦�
+榻�
+缇�
+缇�
+馥粭
+閬�
+绯�
+绯�
+绯�
+鐔�
+鐔�
+鐔�
+婢�
+婢�
+娼�
+娼�
+娼�
+閶�
+娼�
+娼�
+娼�
+鎲�
+鎲�
+瀵�
+绐�
+璋�
+瑜�
+瑜�
+瑜�
+璋�
+鐔�
+灞�
+瀣�
+鍕�
+鎴�
+铦�
+缂�
+缂�
+缂�
+楠�
+鐣�
+鑰�
+鑰�
+鑰�
+鐠�
+鐠�
+闈�
+鐠�
+鐠�
+鑱�
+铻�
+楂�
+楂�
+楂�
+鎿�
+鐔�
+鐢�
+鎿�
+绺�
+纾�
+棰�
+钑�
+闉�
+棰�
+钖�
+钖�
+妾�
+钖�
+钖�
+钖�
+钖�
+妯�
+姗�
+姗�
+妯�
+妾�
+姗�
+妯�
+妯�
+姗�
+澧�
+姗�
+缈�
+閱�
+閱�
+閱�
+閱�
+纾�
+璧�
+椋�
+娈�
+闇�
+闇�
+闇�
+閷�
+杈�
+鑷�
+閬�
+姘�
+鐬�
+鐬�
+鐬�
+鍤�
+鍤�
+鍣�
+鏆�
+韫�
+韪�
+韪�
+韪�
+韫�
+韫�
+铻�
+锜�
+铻�
+铻�
+铻�
+铻�
+铻�
+鍣�
+鍣�
+鍣�
+鍣�
+鍣�
+缃�
+鍦�
+洇�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+姘�
+姘�
+鎲�
+绌�
+绡�
+绡�
+绡�
+绡�
+绡�
+鐩�
+鍔�
+缈�
+榄�
+榄�
+寰�
+姝�
+鑶�
+鑶�
+鑶�
+椴�
+椴�
+椴�
+椴�
+椴�
+椴�
+椴�
+椴�
+鐛�
+鐛�
+鐛�
+閭�
+楣�
+寤�
+璧�
+鐦�
+寤�
+鐦�
+鐦�
+鐦�
+鐧�
+鐦�
+鏂�
+楹�
+楹�
+瀣�
+澹�
+缇�
+绯�
+鐬�
+鐢�
+鐕�
+鐕�
+鐕�
+鐕�
+婵�
+婵�
+娼�
+婢�
+婢�
+婢�
+婢�
+婵�
+瑜�
+瀵�
+绐�
+瑜�
+绂�
+瀣�
+鐘�
+闅�
+瀣�
+棰�
+缂�
+缂�
+缂�
+鐠�
+鐠�
+鐠�
+鐠�
+铻�
+鎿�
+澹�
+瑙�
+缃�
+鎿�
+钖�
+闉�
+闉�
+钖�
+钖�
+钘�
+钘�
+妾�
+妾�
+鎳�
+閱�
+缈�
+绀�
+纾�
+楣�
+榫�
+榫�
+璞�
+澹�
+榛�
+鍤�
+鍤�
+韫�
+韫�
+韫�
+锜�
+铻�
+铻�
+鐤�
+铻�
+锜�
+鍤�
+缇�
+缃�
+缃�
+宥�
+榛�
+榛�
+楂�
+楂�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+缃�
+榛�
+绨�
+绡�
+绡�
+绨�
+绨�
+榧�
+榛�
+鍎�
+楣�
+榧�
+鐨�
+榄�
+榫�
+绻�
+璨�
+閭�
+璨�
+鑷�
+鑶�
+鑷�
+鑷�
+椴�
+椴�
+槌�
+槌�
+槌�
+槌�
+槌�
+铻�
+鐕�
+楣�
+瑗�
+绯�
+绺�
+鑶�
+鐧�
+楹�
+鎳�
+婵�
+婵�
+婵�
+婵�
+婵�
+韫�
+璎�
+閭�
+瑗�
+妾�
+鎿�
+瀛�
+闅�
+瀣�
+锜�
+楣�
+閸�
+閺�
+槌�
+楝�
+楝�
+鐬�
+闉�
+闉�
+闉�
+闉�
+闉�
+钘�
+钘�
+钘�
+閱�
+韫�
+绀�
+鐕�
+椁�
+鐬�
+鏇�
+棰�
+鏇�
+韬�
+韫�
+楣�
+锜�
+锜�
+锜�
+锜�
+楣�
+榛�
+榛�
+楂�
+楂�
+闀�
+闀�
+闀�
+棣�
+绨�
+绨�
+榧�
+闆�
+鑹�
+槌�
+槌�
+槌�
+鐧�
+鐧�
+鐧�
+鐧�
+绯�
+韫�
+閹�
+鎳�
+褰�
+閭�
+楝�
+鏀�
+鏀�
+闉�
+闉�
+钘�
+铇�
+铇�
+楹�
+閱�
+閱�
+閰�
+闇�
+闇�
+闇�
+榛�
+鍤�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+锠�
+锠�
+锜�
+锠�
+榛�
+楂�
+楂�
+闀�
+绫�
+绫�
+榻�
+榄�
+鑹�
+槌�
+槌�
+槌�
+槌�
+槌�
+楹�
+閺�
+缇�
+愀�
+鐎�
+鐎�
+鐎�
+瑗�
+璋�
+瑗�
+楠�
+缂�
+鐡�
+鏀�
+铇�
+铇�
+閱�
+闇�
+閰�
+鐭�
+鏇�
+韬�
+榧�
+宸�
+榛�
+榛�
+榛�
+闀�
+闀�
+榛�
+绾�
+鐠�
+榧�
+鑷�
+槌�
+槌�
+槌�
+鐛�
+瀛�
+楠�
+鐡�
+榧�
+閱�
+绀�
+棰�
+鏇�
+槌�
+鐧�
+楹�
+澶�
+鐖�
+鐏�
+绂�
+閻�
+缇�
+锠�
+鑰�
+鎳�
+铇�
+楣�
+闇�
+姘�
+楗�
+韬�
+楂�
+闀�
+绌�
+楗�
+楝�
+楝�
+瓒�
+鏀�
+鏀�
+棰�
+韬�
+榧�
+鐧�
+楹�
+锠�
+锠�
+韬�
+琛�
+閼�
+鐏�
+瑗�
+绾�
+楝�
+鏀�
+鍥�
+棣�
+鎴�
+鐖�
+榻�
+浜�
+灏�
+褰�
+鍗�
+娈�
+馉櫠
+姣�
+閭�
+鎴�
+鍦�
+姘�
+浼�
+浠�
+鍐�
+姘�
+姹�
+姘�
+蹇�
+瀹�
+璁�
+鎵�
+鍦�
+鍦�
+鑺�
+鑺�
+鏈�
+鏈�
+皎櫢
+閭�
+鍚�
+鍚�
+灞�
+灞�
+杈�
+閽�
+浠�
+浼�
+浼�
+鐧�
+鐢�
+閭�
+鐘�
+鍐�
+閭�
+闂�
+姹�
+錅�
+璁�
+瀛�
+绾�
+鐜�
+鐜�
+鐜�
+鐜�
+鍒�
+鍧�
+鍧�
+鎵�
+鍧�
+鎵�
+悃�
+姣�
+鑺�
+鑺�
+鑻�
+鑻�
+鑺�
+鑺�
+鑺�
+鑺�
+鏉�
+鏉�
+鏉�
+鏉�
+鏉�
+灏�
+灏�
+杞�
+鍧�
+鑺�
+鏃�
+鏃�
+鍛�
+銜�
+宀�
+宀�
+宀�
+鍛�
+鍐�
+瑙�
+宀�
+浼�
+銘�
+浼�
+浣�
+浼�
+浣�
+椋�
+鐙�
+闂�
+姹�
+姹�
+穑矘
+穑矖
+娌�
+娌�
+姹�
+愠�
+娌�
+蹇�
+蹇�
+蹇�
+绁�
+璇�
+閭�
+璇�
+璇�
+灞�
+宀�
+闃�
+洧�
+闃�
+濡�
+濡�
+皎殨
+绾�
+椹�
+绾�
+绾�
+鐜�
+鐜�
+鐜�
+鐜�
+閭�
+閭�
+鍧�
+鍧�
+鍧�
+鍧�
+寮�
+鑰�
+洧�
+穰瓬
+鑼�
+鑻�
+鑻�
+鑻�
+鏋�
+悱�
+鏋�
+鏋�
+鐭�
+鐭�
+鍖�
+鏃�
+鏄�
+鏄�
+鏄�
+鏄�
+鍜�
+鍜�
+鍜�
+宀�
+宀�
+宀�
+宀�
+宄�
+銦�
+鍥�
+閽�
+閽�
+閽�
+鐗�
+浣�
+鍨�
+渚�
+渚�
+浣�
+浣�
+闅�
+銘�
+渚�
+浣�
+渚�
+閮�
+鑸�
+閮�
+閮�
+鏀�
+鑲�
+鑲�
+鑲�
+鐙�
+鐙�
+楗�
+蹇�
+鏂�
+鐐�
+鐐�
+娉�
+娌�
+娉�
+娉�
+娉�
+娉�
+鎬�
+宄�
+绌�
+绁�
+绁�
+楦�
+寮�
+寮�
+闄�
+闄�
+鍗�
+涔�
+濡�
+濮�
+杩�
+鍙�
+椹�
+鋵�
+椹�
+缁�
+缁�
+鐮�
+鑰�
+銢�
+鐜�
+鐝�
+鐝�
+鐝�
+鐜�
+鐝�
+鐜�
+闊�
+鍨�
+鍨�
+鍨�
+鍨�
+鍩�
+鍨�
+鑰�
+鍨�
+鍨�
+鍨�
+鍨�
+鎸�
+鍨�
+鍨�
+鎷�
+鑽�
+鑽�
+鑽�
+鑽�
+鑼�
+鑼�
+鑽�
+鑼�
+鑽�
+鑼�
+穰啊
+鑼�
+鑽�
+悱�
+鏌�
+鏌�
+鏌�
+鏋�
+鏍�
+鏌�
+閮�
+鍓�
+浯�
+杩�
+鍘�
+鐮�
+鐮�
+鐮�
+鑰�
+濂�
+涠�
+杞�
+杞�
+杞�
+杞�
+鏄�
+鏄�
+鐩�
+鍜�
+鍜�
+鏄�
+鏄�
+鍝�
+鏄�
+鏄�
+鏄�
+鍜�
+鏄�
+铏�
+铏�
+鍝�
+宄�
+鑰�
+宄�
+宄�
+宄�
+甯�
+閽�
+閽�
+閽�
+閽�
+閽�
+鐭�
+绉�
+淇�
+鑸�
+淇�
+淇�
+淇�
+鍨�
+琛�
+鑸�
+寮�
+渚�
+楦�
+鋸�
+鑳�
+穰櫠
+鑳�
+鑳�
+鑳�
+鏈�
+椋�
+瑷�
+楗�
+搴�
+鐤�
+鐐�
+鐐�
+愣�
+娲�
+娲�
+娲�
+娲�
+愠�
+娉�
+娴�
+娴�
+娲�
+娲�
+娲�
+娲�
+娲�
+娲�
+娲�
+娴�
+愠�
+娲�
+娲�
+鎭�
+瀹�
+绐�
+鎵�
+琚�
+绁�
+绁�
+绁�
+鍙�
+闄�
+闄�
+濞�
+濮�
+濮�
+濮�
+濮�
+濮�
+鏋�
+缁�
+楠�
+褰�
+楠�
+鎭�
+鐝�
+鐝�
+鐝�
+鐞�
+鐜�
+鐝�
+鐝�
+鐝�
+鐝�
+鐝�
+鐝�
+鐝�
+鐝�
+鍩�
+鍨�
+鍨�
+鍩�
+鍨�
+鍩�
+鍩�
+鑾�
+鑼�
+閯�
+鑾�
+鑾�
+鋼�
+鑾�
+鏍�
+妗�
+妗�
+姊�
+鏍�
+姊�
+鏍�
+閰�
+閰�
+鐮�
+鐮�
+鐮�
+鐮�
+纭�
+鎭�
+缈�
+閮�
+皎悎
+杈�
+杈�
+鍓�
+璧�
+鍝�
+鏅�
+鏅�
+鍞�
+鍝�
+鍝�
+鍐�
+鏅�
+鏅�
+鏅�
+鐣�
+铓�
+铓�
+甯�
+宕�
+宄�
+宕�
+甯�
+宕�
+璧�
+閽�
+鐪�
+鐢�
+绗�
+鍊�
+鍊�
+鑴�
+鍊�
+鍊�
+鍊�
+鍊�
+鍊�
+琛�
+铏�
+鑸�
+鑸�
+鑸�
+鐡�
+楝�
+楦�
+鑴�
+鏈�
+鑳�
+铏�
+楸�
+鐙�
+宄�
+鐙�
+鐪�
+鍕�
+鐥�
+鐤�
+鐥�
+绔�
+缇�
+缇�
+妗�
+鏁�
+鐑�
+鐑�
+鐑�
+鐑�
+娑�
+娴�
+娴�
+娴�
+娑�
+娑�
+娑�
+娴�
+娴�
+娴�
+娴�
+娴�
+娑�
+鎮�
+鎮�
+鎮�
+瀹�
+绐�
+绐�
+绐�
+鎵�
+鎵�
+琚�
+琚�
+琚�
+绁�
+闅�
+鍫�
+鐤�
+皎簷
+闄�
+鐑�
+鐮�
+銢�
+鍝�
+缈�
+缈�
+鍓�
+缁�
+楠�
+鋫�
+鐞�
+鐝�
+鐝�
+鐞�
+鐞�
+鐞�
+鐝�
+鎺�
+鍫�
+鍫�
+鍩�
+鎺�
+鍩�
+鍫�
+鏅�
+鎺�
+鍩�
+澹�
+銠�
+鑱�
+鑿�
+钀�
+鑿�
+鑾�
+鋼�
+鍕�
+鋼�
+钀�
+鑿�
+鑿�
+鑿�
+钀�
+鋼�
+鑿�
+鋼�
+姊�
+姊�
+妗�
+姊�
+妗�
+姊�
+姊�
+妗�
+鏁�
+鍘�
+纭�
+纭�
+纭�
+纭�
+纭�
+鍕�
+浯�
+榫�
+閫�
+鍞�
+鍟�
+缈�
+惬�
+鏅�
+鐣�
+瓒�
+璺�
+铔�
+铓�
+铓�
+鍟�
+鋷�
+宕�
+宕�
+宕�
+宕�
+宕�
+宕�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+鐗�
+鐗�
+绋�
+绗�
+绗�
+鍋�
+鍋�
+楦�
+鍋�
+鍋�
+鍋�
+憧�
+閯�
+鍋�
+寰�
+琛�
+鑸�
+鑸�
+楦�
+鎮�
+閯�
+鐡�
+錆�
+鑴�
+鑴�
+鑴�
+鋸�
+楸�
+鐚�
+鐚�
+鐚�
+瑙�
+馉叅
+搴�
+搴�
+搴�
+鐥�
+浯�
+绔�
+鍫�
+闃�
+缇�
+缇�
+鐒�
+鐑�
+鐒�
+娣�
+娣�
+娣�
+娣�
+娣�
+婀�
+娑�
+悭�
+鎯�
+鎯�
+鎮�
+鎯�
+瀵�
+閫�
+琚�
+瑁�
+绁�
+璋�
+鑹�
+寮�
+寮�
+闅�
+濠�
+濞�
+濠�
+濯�
+濠�
+濠�
+濠�
+濠�
+濠�
+濠�
+濠�
+缁�
+楠�
+绲�
+鐝�
+鐞�
+鐞�
+鐞�
+鐞�
+鐞�
+鍫�
+鍫�
+鎻�
+銠�
+鍫�
+鍠�
+鍫�
+濉�
+鍫�
+绲�
+稹帤
+钁�
+鎯�
+钀�
+钁�
+闈�
+钁�
+钂�
+钂�
+閯�
+钂�
+钃�
+钀�
+钂�
+钁�
+钁�
+閯�
+钂�
+钁�
+钂�
+钀�
+妫�
+妫�
+妫�
+妞�
+妞�
+楣�
+妞�
+妫�
+妫�
+妫�
+妞�
+妤�
+鐢�
+閰�
+瑙�
+濂�
+鐨�
+纭�
+娆�
+瑭�
+杈�
+妫�
+榫�
+榛�
+鐗�
+鐫�
+鏅�
+鏅�
+鏅�
+皈抗
+铔�
+鐣�
+鏂�
+鍠�
+宕�
+宓�
+宕�
+宓�
+宕�
+宓�
+缈�
+鍦�
+鍦�
+璧�
+娣�
+璧�
+閾�
+閾�
+皎眹
+閿�
+閿�
+閿�
+閿�
+鐘�
+棰�
+绋�
+绛�
+绛�
+绛�
+绛�
+绛�
+鍌�
+鍌�
+缈�
+鍌�
+鍌�
+鑸�
+鐣�
+鑴�
+鑵�
+鋹�
+鑵�
+鑵�
+椴�
+鐚�
+鐚�
+愫�
+棣�
+閯�
+寤�
+寤�
+閯�
+绮�
+閬�
+鏃�
+鐒�
+娆�
+穑福
+婧�
+婧�
+婀�
+娓�
+婀�
+愦�
+娓�
+婧�
+娓�
+婧�
+婀�
+婀�
+婧�
+鎰�
+鎰�
+鏁�
+鐢�
+妫�
+鎵�
+瑁�
+绁�
+濠�
+濯�
+濯�
+銢�
+濯�
+濯�
+濯�
+姣�
+鐭�
+缂�
+缂�
+楠�
+鐟�
+鐟�
+鐟�
+鐟�
+浯�
+鐟�
+鐟�
+鐟�
+鐟�
+黏
+鐟�
+鐟�
+宥�
+鐟�
+閬�
+楂�
+濉�
+鍫�
+璧�
+鎽�
+濉�
+鎼�
+鎼�
+钂�
+钂�
+钃�
+钄�
+钃�
+钃�
+钂�
+钃�
+妞�
+妤�
+姒�
+姒�
+妤�
+妤�
+妤�
+姒�
+妞�
+妤�
+姝�
+纰�
+纰�
+纰�
+鋬�
+纭�
+閯�
+杈�
+榫�
+瑙�
+洌�
+鏆�
+楣�
+悻�
+鏆�
+璺�
+铚�
+铚�
+宓�
+璧�
+楠�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+绋�
+绋�
+鋮�
+绛�
+绛�
+绛�
+绛�
+绛�
+鍌�
+楣�
+鍍�
+鑹�
+鑹�
+璋�
+璨�
+鑵�
+鑵�
+鑵�
+椴�
+椴�
+椴�
+洳�
+椴�
+闆�
+鐚�
+椋�
+瑙�
+穰澕
+棣�
+瑁�
+寤�
+鐦�
+鐦�
+閯�
+楣�
+閯�
+楹�
+閯�
+闃�
+鐓�
+鐓�
+鐓�
+鐓�
+鐓�
+鐓�
+婊�
+婧�
+婧�
+婊�
+婊�
+婧�
+婧�
+婕�
+婊�
+婊�
+婊�
+鎰�
+鎱�
+鎱�
+濉�
+瑁�
+绂�
+绂�
+绂�
+绂�
+璋�
+楣�
+鎰�
+瀚�
+濯�
+鎴�
+鎴�
+缂�
+鑰�
+鐟�
+鐟�
+鐟�
+鐟�
+鐟�
+鏂�
+鎽�
+澧�
+澧�
+澧�
+澧�
+鎽�
+閵�
+稹悡
+澧�
+鎾�
+闈�
+闉�
+钄�
+钄�
+钃�
+钄�
+钄�
+鍢�
+姒�
+姒�
+妲�
+穑棆
+妲�
+姒�
+鐤�
+閰�
+閰�
+閰�
+閰�
+纰�
+鋬�
+纰�
+馥敳
+纰�
+纰�
+鍔�
+浯�
+澶�
+鐬�
+楣�
+悻�
+璺�
+铚�
+骞�
+宥�
+鍦�
+皎睆
+閿�
+閿�
+閿�
+閿�
+閿�
+闀�
+闀�
+闀�
+棣�
+楣�
+绠�
+绠�
+鍔�
+鍍�
+鍍�
+鍍�
+鍍�
+妲�
+銠�
+椴�
+椴�
+椴�
+椴�
+椴�
+椴�
+皓骄
+澶�
+鐛�
+椋�
+鍑�
+寤�
+寤�
+鐦�
+鐦�
+鐦�
+椴�
+閯�
+鐔�
+婕�
+婕�
+娼�
+婕�
+娼�
+婕�
+婕�
+憬�
+婕�
+婕�
+婕�
+鎱�
+绐�
+绐�
+惝�
+瑜�
+绂�
+绂�
+闅�
+瀚�
+瀚�
+瀚�
+瀚�
+慊�
+楹�
+鐠�
+婕�
+鍙�
+澧�
+澧�
+澧�
+鍔�
+钖�
+钑�
+钄�
+榧�
+妲�
+楣�
+纾�
+纾�
+娈�
+鎱�
+闇�
+鏆�
+鏆�
+鏆�
+韪�
+韪�
+錀�
+铦�
+铦�
+铦�
+鍣�
+鍣�
+鍣�
+缃�
+宥�
+宥�
+銧�
+宥�
+宥�
+闀�
+闀�
+闀�
+闀�
+闀�
+绋�
+鍎�
+鐨�
+鐨�
+浯�
+鑹�
+鑹�
+楣�
+皓緝
+椴�
+椴�
+椴�
+姗�
+瑙�
+楣�
+楣�
+绯�
+绯�
+缈�
+楣�
+楣�
+鐔�
+娼�
+娼�
+愕�
+婢�
+婢�
+鐟�
+娼�
+娼�
+娼�
+鎲�
+鎲�
+鎴�
+瑜�
+绂�
+瀚�
+閬�
+鐠�
+鐠�
+鐠�
+鎲�
+鎿�
+閯�
+钖�
+闉�
+榛�
+钑�
+钖�
+钑�
+姗�
+姗�
+姗�
+閱�
+瑙�
+纾�
+馥暍
+纾�
+璞�
+楣�
+铏�
+鏆�
+鏇�
+鏇�
+悻�
+韫�
+韪�
+錀�
+铻�
+鐤�
+銧�
+骞�
+宥�
+皎睉
+棣�
+绌�
+绡�
+绡�
+绨�
+榧�
+琛�
+鐩�
+铻�
+绺�
+椴�
+椴�
+椴�
+椴�
+椴�
+浜�
+鐧�
+鐦�
+缇�
+绯�
+鐕�
+鐔�
+鐕�
+鐕�
+鐕�
+婵�
+婵�
+婢�
+婢�
+婢�
+婢�
+婢�
+鎲�
+鎲�
+鎳�
+榛�
+瀣�
+楣�
+缈�
+鐠�
+黏┙
+鐠�
+鐠�
+楂�
+鎿�
+钖�
+钖�
+妾�
+娅�
+妾�
+閱�
+绻�
+纾�
+纾�
+鐬�
+鐬�
+韫�
+锜�
+銟�
+闀�
+闀�
+闀�
+皎睌
+鐭�
+绌�
+绌�
+绌�
+绨�
+绨�
+绨�
+鍎�
+榄�
+鏂�
+鑹�
+璋�
+洳�
+椴�
+椴�
+槌�
+槌�
+槌�
+槌�
+鐛�
+錀�
+棣�
+瑗�
+瑗�
+铻�
+鐢�
+瀣�
+瀣�
+穰垺
+鐡�
+閲�
+楝�
+鐖�
+闉�
+闉�
+钘�
+钘�
+钘�
+楣�
+妾�
+榛�
+绀�
+绀�
+馥枿
+韫�
+韫�
+锜�
+錀�
+鍤�
+楂�
+闀�
+闀�
+閰�
+棣�
+绨�
+绨�
+绨�
+榧�
+榧�
+鐨�
+鑷�
+洳�
+槌�
+槌�
+楣�
+楣�
+鐧�
+穰拲
+鏃�
+缈�
+鍐�
+鋷�
+鐎�
+鐎�
+鐎�
+瑗�
+浯�
+鍤�
+惆�
+楝�
+閱�
+韫�
+锠�
+缈�
+槌�
+鍎�
+鍎�
+榧�
+皓緦
+槌�
+槌�
+楹�
+楹�
+锠�
+褰�
+瀣�
+楝�
+铇�
+娆�
+閱�
+棰�
+鐢�
+皎煚
+宸�
+閰�
+楂�
+鐘�
+皎瓑
+愀�
+鐖�
+鐎�
+鐎�
+鐎�
+鐎�
+瑗�
+瀛�
+楠�
+鑰�
+黏珘
+鐡�
+楝�
+瓒�
+缃�
+榧�
+槌�
+槌�
+槌�
+鐖�
+鐖�
+鐏�
+闊�
+绯�
+铇�
+绀�
+楣�
+韬�
+鐨�
+榫�
+槌�
+浜�
+绫�
+榧�
+鐜�
+閱�
+榻�
+瑙�
+锠�
+瓞
+瓞嚂
+瓞
+瓞槗
+皤瓱
+皤
+皤嚟
+皤悇
+皤捣
+瓞嚈
+瓞!
+皤俯
+皤槣
+瓞槝
+皤槤
+瓞▊
+瓞��
+瓞��
+瓞
+皤崳
+瓞3
+瓞┙
+瓞
+瓞瘈
+皤皼
+瓞车
+瓞扯
+皤爦
+瓞崨
+榭�
+瓞湰
+皙劲
+皙ò
+皤摟
+瓞
+瓞
+瓞
+瓞槨
+瓞辰
+瓞槱
+皤劎
+皙煗
+瓞崵
+皤
+瓞湳
+瓞偐
+皤爢
+瓞寳
+皤憽
+皙ǘ
+瓞
+瓞
+瓞
+瓞
+瓞瓉
+皤⒏
+皤棫
+瓞妶
+瓞拡
+瓞晨
+皤劏
+瓞槴
+皤畠
+榭�
+瓞睎
+瓞熃
+皤摨
+皤煿
+皤熂
+瓞嚬
+瓞崱
+瓞
+皤嵂
+瓞
+皤嵅
+瓞瘞
+瓞槵
+瓞槶
+瓞磦
+皤槮
+皤焻
+瓞槸
+皤槯
+皙;
+瓞儕
+瓞窌
+皤悙
+瓞辜
+皤秶
+皤柈
+榭�
+瓞瓓
+皤摱
+瓞瓗
+皤柉
+瓞睙
+皤洯
+皤贩
+瓞
+瓞姢
+瓞磧
+皤槰
+瓞
+瓞挃
+瓞◣
+皤悡
+皤珖
+皤摴
+瓞瓪
+瓞瓫
+瓞晜
+瓞秼
+瓞秿
+皤敹
+皤寑
+皤柍
+皤槳
+皤槵
+皤灘
+皙
+瓞笜
+瓞挆
+皤殩
+瓞
+皤殨
+瓞稅
+瓞稄
+瓞笟
+瓞
+瓞檪
+瓞
+瓞福
+皤嵔
+瓞磰
+瓞灍
+皤煢
+瓞簣
+皤牅
+皙
+瓞
+瓞
+皤棿
+瓞甫
+皤劮
+瓞
+瓞
+皤攳
+瓞
+瓞
+皤攷
+瓞釜
+瓞稛
+瓞稜
+瓞定
+皤劯
+瓞焷
+瓞檴
+瓞董
+瓞懂
+瓞檵
+瓞簱
+皤毉
+寤�
+钄�
+鍏�
+骞�
+骞�
+铏�
+绾�
+鑸�
+钀�
+闊�
+鍎�
+鍊�
+寤�
+闁�
+缇�
+琛�
+椋�
+缈�
+棣�
+閯�
+璞�
+闁�
+鐒�
+闆�
+灏�
+钘�
+寤�
+鍗�
+姝�
+鏇�
+杌�
+璨�
+宀�
+瑕�
+姘�
+闀�
+鍍�
+骞�
+鍍�
+寰�
+渚�
+鍊�
+棰�
+鐑�
+槌�
+鐖�
+楝�
+鎲�
+瑷�
+瑷�
+瑾�
+璀�
+閱�
+闅�
+杈�
+閯�
+鍕�
+闆�
+鏇�
+鎿�
+鎾�
+绡�
+琛�
+鍘�
+榫�
+婊�
+杌�
+鏉�
+鐩�
+妤�
+鑸�
+甯�
+姝�
+钁�
+闆�
+铏�
+琛�
+闅�
+鍢�
+鍢�
+鍊�
+鍎�
+鍙�
+鐖�
+妯�
+铏�
+榧�
+槌�
+鍕�
+椋�
+楗�
+棣�
+闁�
+铇�
+鍖�
+褰�
+闋�
+婕�
+瀵�
+瑷�
+瀵�
+璁�
+绂�
+瑷�
+璀�
+瑷�
+瑷�
+榻�
+閬�
+閭�
+鐧�
+楂�
+鑱�
+灏�
+鑷�
+棰�
+妾�
+绯�
+绲�
+鍕�
+闉�
+鍩�
+鎿�
+鎺�
+鍫�
+鎻�
+浜�
+妯�
+姗�
+娆�
+閬�
+鍗�
+澹�
+鍘�
+闋�
+瑾�
+濂�
+閬�
+澶�
+杌�
+鍫�
+鍔�
+閭�
+鐣�
+璨�
+甯�
+濉�
+鐣�
+鍣�
+绫�
+鍤�
+锜�
+楹�
+鍦�
+绯�
+鍡�
+宥�
+姝�
+杩�
+璞�
+鍓�
+鍓�
+缍�
+纭�
+閬�
+鍠�
+鍋�
+鍌�
+鍎�
+鍌�
+鍍�
+鍊�
+鑿�
+鍍�
+鍤�
+寰�
+鏈�
+娈�
+闁�
+琛�
+鐖�
+鍌�
+鍓�
+闆�
+璨�
+澹�
+琛�
+濡�
+鑾�
+鎱�
+鍔�
+榻�
+鐢�
+闁�
+鍟�
+闂�
+闂�
+鐕�
+婀�
+鑸�
+璎�
+璜�
+杌�
+瑷�
+瑷�
+瑷�
+璜�
+瑷�
+杈�
+璜�
+瑷�
+瑷�
+瑷�
+灏�
+鐩�
+鍎�
+灏�
+瀛�
+闄�
+闄�
+闅�
+闄�
+濠�
+濯�
+鎴�
+瑙�
+姝�
+璨�
+绱�
+棣�
+绾�
+绺�
+棣�
+绱�
+绱�
+绱�
+棣�
+绱�
+澹�
+楹�
+鐟�
+閫�
+閬�
+閬�
+闊�
+閬�
+鎾�
+澹�
+缃�
+澹�
+鎽�
+鎿�
+璨�
+鍨�
+澹�
+鎽�
+鎺�
+鎼�
+澧�
+璀�
+娈�
+濉�
+鑱�
+鍫�
+鎿�
+钑�
+钁�
+钂�
+鍤�
+铇�
+鍕�
+铇�
+鍥�
+妤�
+妤�
+鍏�
+楹�
+閱�
+鍕�
+閭�
+娈�
+渚�
+閫�
+杌�
+楣�
+婊�
+鍫�
+鏅�
+绺�
+瑁�
+鍢�
+鍦�
+鏇�
+鍦�
+鍣�
+閮�
+鐫�
+鍝�
+鑱�
+鍡�
+鍡�
+褰�
+宥�
+宕�
+甯�
+璨�
+閲�
+閲�
+浜�
+楂�
+鍌�
+寰�
+椁�
+绌�
+閯�
+鑵�
+榫�
+鐚�
+鐙�
+姊�
+宄�
+椋�
+椋�
+淇�
+绻�
+鍑�
+鐙�
+鐣�
+搴�
+鐧�
+鎳�
+閫�
+寤�
+闁�
+闁�
+闁�
+鎮�
+绔�
+鐕�
+鐎�
+娣�
+婊�
+婧�
+婊�
+鐎�
+鎳�
+鎲�
+绐�
+璀�
+鍟�
+瑭�
+瑁�
+璀�
+瑭�
+瑷�
+瑷�
+瑭�
+璀�
+闈�
+灞�
+閬�
+寮�
+闅�
+闄�
+闄�
+澧�
+鍕�
+榉�
+绶�
+椹�
+绱�
+绱�
+缍�
+绱�
+椐�
+绺�
+绱�
+绱�
+绱�
+绱�
+椹�
+绱�
+鐠�
+璨�
+鐝�
+閷�
+瑕�
+鏀�
+鎻�
+鎿�
+闋�
+鎿�
+鍕�
+鏀�
+鎿�
+鎾�
+鎿�
+铇�
+绡�
+鑾�
+妯�
+娅�
+闂�
+楝�
+妲�
+妤�
+妲�
+鍠�
+鐣�
+妫�
+璩�
+楝�
+绀�
+绀�
+纰�
+鍘�
+濂�
+鎱�
+姝�
+姣�
+澹�
+杞�
+闋�
+杞�
+鏂�
+杓�
+杌�
+榻�
+铏�
+鑵�
+璩�
+鍦�
+鏆�
+鍤�
+槌�
+缇�
+骞�
+宥�
+鍑�
+鏁�
+璩�
+璨�
+璨�
+璩�
+璨�
+鍦�
+閲�
+瑁�
+棰�
+淇�
+鍍�
+鍋�
+鍋�
+鎲�
+鍍�
+璨�
+璩�
+寰�
+鎹�
+瑕�
+璨�
+璨�
+鑶�
+鑵�
+鑴�
+楠�
+鑴�
+榄�
+鐛�
+鍌�
+椋�
+椋�
+椋�
+璁�
+榫�
+寤�
+鐦�
+鍔�
+寤�
+闁�
+楝�
+閯�
+鎹�
+鍠�
+鐖�
+娣�
+婵�
+鐎�
+娼�
+婢�
+鎲�
+瀛�
+瀵�
+瀵�
+瀵�
+绨�
+瀵�
+瑭�
+瑭�
+瑾�
+瑗�
+瑕�
+瑭�
+瑾�
+瑭�
+瑭�
+瑭�
+瑭�
+鑲�
+閷�
+闅�
+褰�
+鐎�
+闄�
+椐�
+鍙�
+鑹�
+缍�
+绶�
+绲�
+绱�
+绱�
+椐�
+绻�
+椐�
+绲�
+椐�
+绲�
+椐�
+绱�
+绻�
+缍�
+璨�
+璨�
+骞�
+闋�
+鎸�
+鎾�
+瓒�
+鎿�
+澧�
+鎿�
+鎻�
+钖�
+甯�
+绻�
+钑�
+姒�
+钁�
+鐔�
+楝�
+钄�
+钘�
+妯�
+妫�
+妫�
+娆�
+妾�
+妯�
+楣�
+纾�
+纭�
+楹�
+鐗�
+榉�
+娈�
+杌�
+杓�
+榇�
+鎴�
+榛�
+鑷�
+瑕�
+绔�
+鍢�
+鍟�
+椤�
+璨�
+铦�
+锜�
+铻�
+闆�
+椐�
+鍕�
+鍢�
+闊�
+鍠�
+宄�
+缃�
+璩�
+璨�
+璨�
+閳�
+閳�
+閳�
+閸�
+閻�
+閶�
+閳�
+閼�
+娆�
+閳�
+閳�
+閳�
+姘�
+姘�
+閬�
+閬�
+绋�
+闉�
+寰�
+瑜�
+鍊�
+璨�
+闋�
+鍎�
+闋�
+楝�
+鍔�
+鏈�
+鑶�
+鍕�
+鐙�
+鐛�
+鐛�
+鐛�
+璨�
+椁�
+楗�
+铦�
+椁�
+椁�
+宸�
+褰�
+灏�
+濂�
+鐦�
+鐦�
+瑕�
+闁�
+鑱�
+闁�
+闁�
+闁�
+椁�
+钖�
+椤�
+濠�
+绺�
+鐓�
+鐖�
+鐖�
+绐�
+娼�
+鐏�
+婢�
+婵�
+娓�
+鐎�
+婵�
+娓�
+婵�
+鎯�
+鑸�
+瑕�
+鎲�
+绔�
+瑾�
+瑾�
+瑾�
+瑗�
+瑾�
+瑾�
+瑾�
+瑾�
+瑾�
+澧�
+鏅�
+璨�
+閬�
+闅�
+闅�
+瀣�
+璩�
+澹�
+缍�
+绲�
+绲�
+绻�
+椹�
+绻�
+绲�
+绲�
+椐�
+绲�
+绲�
+绲�
+椐�
+绲�
+鑹�
+锠�
+闋�
+鐩�
+鎾�
+杓�
+瓒�
+楣�
+鎼�
+鎾�
+鎽�
+鍓�
+鐔�
+鎼�
+澹�
+鑱�
+钀�
+钃�
+鐛�
+绌�
+鎯�
+鍣�
+鐟�
+槎�
+妾�
+姗�
+妯�
+妯�
+妯�
+璩�
+绀�
+绀�
+椤�
+杞�
+杓�
+闋�
+鏂�
+绶�
+鎱�
+鐩�
+绶�
+榛�
+鏇�
+鏇�
+鍢�
+榇�
+鏆�
+榇�
+缃�
+鍦�
+璩�
+璩�
+璩�
+璐�
+閷�
+閴�
+閼�
+閴�
+閻�
+閳�
+閴�
+鐘�
+鏁�
+绌�
+绋�
+绛�
+鍌�
+鍌�
+璩�
+鑹�
+鑹�
+鑱�
+鎰�
+闋�
+闋�
+鑷�
+楂�
+鑷�
+鑶�
+鑵�
+鑶�
+榇�
+榇�
+鐨�
+椁�
+椁�
+鎴�
+妲�
+婕�
+婧�
+鐧�
+榻�
+闆�
+璩�
+绔�
+闁�
+鐓�
+鐕�
+鐕�
+閬�
+婵�
+婢�
+娓�
+濉�
+婊�
+娼�
+婢�
+婕�
+鐕�
+婢�
+鎲�
+瀵�
+鍌�
+璩�
+绔�
+璜�
+璜�
+璜�
+璁�
+瑾�
+瑗�
+瑾�
+瑾�
+瑾�
+璜�
+璜�
+璜�
+瑾�
+鎳�
+鍔�
+闆�
+闋�
+绲�
+缍�
+椹�
+绻�
+椐�
+鐟�
+鎿�
+鎿�
+鎽�
+鑱�
+铇�
+铻�
+鐕�
+钑�
+钖�
+澶�
+妾�
+閱�
+纰�
+鑱�
+瑗�
+杓�
+杓�
+椤�
+鎳�
+韬�
+绾�
+鍥�
+鍢�
+宥�
+閭�
+瀣�
+閵�
+閻�
+閶�
+閵�
+閵�
+閺�
+閵�
+鐭�
+绌�
+绫�
+鍎�
+杌�
+閲�
+閵�
+鐩�
+榇�
+鏂�
+闋�
+鑷�
+鐛�
+椁�
+椁�
+鐧�
+閺�
+闁�
+闂�
+钃�
+鏂�
+鐛�
+榇�
+婕�
+娣�
+婕�
+婢�
+婊�
+鎱�
+鎳�
+椹�
+鎱�
+鎱�
+璎�
+璜�
+璎�
+璜�
+绂�
+绂�
+璎�
+璜�
+璎�
+褰�
+澧�
+闅�
+闅�
+瀣�
+闋�
+闋�
+绺�
+绶�
+绾�
+楱�
+缍�
+绻�
+缍�
+缍�
+缍�
+缍�
+缍�
+缍�
+绶�
+缍�
+鐡�
+瓒�
+鏀�
+鏀�
+鎿�
+鎽�
+鏀�
+鑱�
+钄�
+闊�
+姗�
+纰�
+闋�
+闈�
+鏆�
+缈�
+杓�
+閼�
+杓�
+璩�
+鐫�
+鍣�
+鐤�
+韪�
+閬�
+榈�
+璩�
+璩�
+璐�
+璩�
+璩�
+閼�
+閶�
+閺�
+閵�
+閹�
+閶�
+閸�
+閵�
+閶�
+閶�
+閶�
+榈�
+绡�
+绡�
+鍎�
+鎳�
+绂�
+閲�
+鑷�
+榄�
+鎲�
+楗�
+楗�
+瑁�
+锠�
+闂�
+绯�
+婊�
+婵�
+娼�
+婵�
+鐏�
+鎲�
+绔�
+绐�
+瑜�
+绂�
+璎�
+璎�
+璎�
+璎�
+灞�
+灞�
+绶�
+绾�
+绶�
+绶�
+绶�
+绶�
+绺�
+楱�
+绶�
+楱�
+绶�
+榈�
+鏀�
+鎿�
+瑗�
+鏀�
+榈�
+钘�
+婵�
+鎳�
+鐭�
+鐛�
+娆�
+妯�
+璩�
+绀�
+灏�
+闇�
+杓�
+杓�
+杓�
+闋�
+榻�
+閼�
+韫�
+铦�
+閷�
+閷�
+閷�
+閼�
+閷�
+閷�
+閷�
+閸�
+閶�
+閷�
+杈�
+闋�
+绫�
+绨�
+绫�
+绨�
+鑶�
+榈�
+楱�
+楫�
+绌�
+瑙�
+闆�
+楗�
+椁�
+閱�
+璎�
+绯�
+鏁�
+婊�
+婵�
+婵�
+鐏�
+婵�
+鐏�
+璀�
+绐�
+瀵�
+璎�
+璎�
+闂�
+绺�
+绺�
+绾�
+绻�
+璐�
+澧�
+琛�
+钘�
+妾�
+閲�
+椤�
+杞�
+杓�
+椤�
+韪�
+锠�
+锠�
+锜�
+璩�
+閸�
+閸�
+閸�
+绌�
+绫�
+绨�
+杓�
+楫�
+楗�
+鐎�
+璩�
+璀�
+璀�
+楱�
+绺�
+鏀�
+鑱�
+钘�
+娅�
+椋�
+榛�
+鐬�
+椤�
+鍥�
+閹�
+閹�
+閹�
+绨�
+榀�
+榀�
+鐧�
+鐧�
+椤�
+榀�
+鐎�
+椤�
+璀�
+槎�
+绻�
+椤�
+杞�
+楦�
+璐�
+閺�
+璐�
+绫�
+绫�
+榀�
+鐧�
+杈�
+鐎�
+鎳�
+绻�
+绻�
+鐭�
+璐�
+榘�
+杈�
+璐�
+椹�
+鍥�
+閻�
+榘�
+榉�
+宸�
+椤�
+鐧�
+楸�
+楝�
+楸�
+韬�
+璐�
+閼�
+闊�
+闁�
+瑷�
+鍕�
+鑺�
+閯�
+瑷�
+瑷�
+瑷�
+瑷�
+棣�
+鐠�
+澹�
+鎹�
+钖�
+鍘�
+閲�
+鍌�
+鍊�
+鍌�
+鐛�
+鐛�
+槌�
+閯�
+椁�
+鎳�
+璎�
+瑭�
+瑷�
+绱�
+绱�
+绱�
+绱�
+鐠�
+鎽�
+濉�
+悌�
+钑�
+钘�
+鑾�
+钀�
+钃�
+纾�
+濂�
+姝�
+杌�
+閯�
+鍢�
+鍥�
+鍤�
+鏆�
+鍞�
+骞�
+宄�
+宓�
+鍦�
+閲�
+閲�
+閲�
+鍍�
+槌�
+閯�
+椋�
+椁�
+椋�
+椋�
+椋�
+寤�
+鐧�
+闂�
+闁�
+闁�
+鐓�
+鐏�
+婕�
+娓�
+娼�
+鎲�
+鎱�
+鎰�
+鎮�
+鎰�
+瑭�
+瑷�
+瑭�
+瑭�
+璎�
+瑭�
+瑭�
+闅�
+闄�
+瀚�
+瀚�
+瀣�
+鍓�
+绱�
+绱�
+绱�
+缍�
+绱�
+鐟�
+鍖�
+澹�
+鎿�
+铇�
+钄�
+濉�
+鐓�
+娅�
+姊�
+妫�
+妯�
+纰�
+鐢�
+閮�
+杌�
+槌�
+鏇�
+锜�
+榛�
+鍤�
+鍣�
+宸�
+鍔�
+鍓�
+宥�
+閲�
+閲�
+閲�
+閲�
+閲�
+閲�
+鍎�
+鍎�
+鍎�
+鍔�
+鎱�
+绯�
+鎴�
+鑶�
+閭�
+姊�
+椁�
+椋�
+鐧�
+鐦�
+鐓�
+鐔�
+鐔�
+鐎�
+鐎�
+婵�
+娑�
+悭�
+鎳�
+瑾�
+瑾�
+瑭�
+瑭�
+瑭�
+閯�
+绂�
+瑾�
+瑭�
+瑭�
+瑭�
+瑭�
+璜�
+瑭�
+璜�
+瑭�
+椐�
+绱�
+绱�
+绱�
+椐�
+椐�
+绺�
+绲�
+椹�
+椐�
+鐡�
+闋�
+鍩�
+鎾�
+鎾�
+璩�
+澹�
+鎾�
+鑾�
+璨�
+钃�
+钑�
+钖�
+钖�
+鍫�
+婊�
+鐘�
+钑�
+钘�
+钃�
+钑�
+钁�
+娅�
+娅�
+娅�
+娅�
+妾�
+閰�
+纭�
+纰�
+娈�
+杌�
+杌�
+杞�
+杌�
+杌�
+锠�
+瑕�
+鐬�
+鍢�
+鍡�
+鍣�
+鍓�
+閯�
+鍣�
+鍣�
+宥�
+骞�
+宥�
+璨�
+閳�
+閳�
+閶�
+閳�
+閳�
+閹�
+閳�
+閳�
+绡�
+鍎�
+鍎�
+鍎�
+鑵�
+鑷�
+鑴�
+榇�
+鐛�
+棰�
+鐚�
+椁�
+椁�
+椁�
+瀛�
+瀛�
+鐧�
+鐦�
+棰�
+闂�
+闁�
+闂�
+闁�
+鐔�
+鐑�
+娴�
+婢�
+婊�
+娼�
+婵�
+鎱�
+鎳�
+鎰�
+鎯�
+鎯�
+瑾�
+绂�
+瑾�
+瑾�
+榇�
+濠�
+瀣�
+鎳�
+绲�
+椹�
+椹�
+绲�
+绲�
+椐�
+闋�
+鐠�
+鐞�
+濉�
+濉�
+鍫�
+璐�
+钂�
+钀�
+钑�
+榇�
+钂�
+姗�
+妤�
+姒�
+妾�
+閭�
+绀�
+绀�
+杌�
+杓�
+杓�
+槎�
+韬�
+榻�
+楦�
+鐭�
+鍢�
+榇�
+铚�
+鍡�
+宥�
+宕�
+瑕�
+璩�
+閳�
+閴�
+閳�
+閴�
+閳�
+閴�
+閴�
+閴�
+閳�
+閳�
+閴�
+閼�
+閴�
+閳�
+閴�
+閴�
+閴�
+閳�
+閳�
+閺�
+閻�
+姘�
+绛�
+闋�
+寰�
+鑶�
+榇�
+鐠�
+榇�
+鐛�
+瑁�
+椁�
+娆�
+鏀�
+鐧�
+鐥�
+闋�
+闁�
+楝�
+瑾�
+闁�
+閯�
+鐕�
+鐕�
+鐕�
+娣�
+婕�
+娼�
+鎱�
+璜�
+璜�
+绂�
+璜�
+璜�
+璜�
+璜�
+瑾�
+濯�
+瀚�
+缍�
+椹�
+缍�
+楱�
+缍�
+绺�
+缍�
+椐�
+榉�
+鐕�
+鐠�
+楹�
+鎿�
+鎽�
+榉�
+鎾�
+鎱�
+鎽�
+绺�
+妲�
+瑕�
+娆�
+鍡�
+鍖�
+纭�
+纾�
+榇�
+榫�
+娈�
+娈�
+璩�
+杓�
+濉�
+鍢�
+鍥�
+鍤�
+韫�
+锠�
+锠�
+锜�
+骞�
+骞�
+璩�
+璩�
+璩�
+閵�
+閴�
+閶�
+閻�
+閵�
+閹�
+閸�
+閵�
+閵�
+閶�
+閺�
+閵�
+閹�
+閴�
+閵�
+閴�
+閷�
+閵�
+閴�
+閵�
+閵�
+閵�
+閵�
+榇�
+绌�
+绠�
+绫�
+鍍�
+鍍�
+鐨�
+榇�
+鑹�
+榫�
+鐜�
+鐛�
+椁�
+椁�
+楦�
+闂�
+闁�
+闁�
+闁�
+楝�
+闁�
+闁�
+缇�
+绯�
+鐕�
+婕�
+鐎�
+婢�
+鎰�
+鎲�
+璜�
+璜�
+鐨�
+璎�
+瑗�
+璎�
+璜�
+璜�
+璜�
+璁�
+璜�
+璜�
+璜�
+绯�
+瀣�
+缍�
+楱�
+缍�
+绶�
+绶�
+楱�
+绶�
+楱�
+缍�
+缍�
+缍�
+缍�
+椹�
+绶�
+闈�
+杓�
+榛�
+闋�
+鎾�
+锜�
+澹�
+钄�
+娅�
+娆�
+璩�
+榈�
+楦�
+娈�
+杓�
+杓�
+妲�
+杓�
+杓�
+鐬�
+韬�
+铔�
+锜�
+铻�
+锠�
+鍢�
+宥�
+宥�
+璩�
+閶�
+閷�
+閺�
+閶�
+閶�
+閶�
+閶�
+閵�
+閻�
+閵�
+閶�
+閶�
+閷�
+鐘�
+榈�
+绡�
+鐗�
+鍎�
+鍎�
+鍎�
+瀣�
+闋�
+榈�
+榄�
+榄�
+榄�
+娼�
+棰�
+瑙�
+鐔�
+椁�
+椁�
+瑜�
+鑷�
+鐧�
+鐧�
+璩�
+闋�
+榉�
+闂�
+闂�
+闂�
+榈�
+鎲�
+鍤�
+璎�
+瑜�
+瑗�
+璁�
+璎�
+璎�
+璎�
+楱�
+宸�
+缈�
+楱�
+绶�
+绶�
+绶�
+绶�
+绶�
+绶�
+绶�
+绺�
+绶�
+楗�
+鑰�
+椹�
+闊�
+鏀�
+鎿�
+杞�
+椹�
+槎�
+钖�
+铇�
+閹�
+闋�
+娅�
+娅�
+纾�
+纾�
+榈�
+杓�
+榻�
+榻�
+闊�
+鍥�
+韬�
+韫�
+韬�
+韬�
+鍣�
+閸�
+閷�
+閷�
+閸�
+閷�
+閷�
+閷�
+閸�
+閷�
+閷�
+閷�
+瑕�
+闋�
+楫�
+楫�
+楫�
+楸�
+绌�
+楫�
+楫�
+榈�
+棰�
+楗�
+槎�
+鐦�
+闂�
+闂�
+闂�
+鐏�
+鐎�
+娼�
+鐏�
+婢�
+鎳�
+楸�
+楱�
+绔�
+璎�
+璎�
+瀣�
+瀣�
+绺�
+绺�
+绺�
+杞�
+楱�
+绺�
+绺�
+绺�
+绺�
+楱�
+瑕�
+闊�
+闈�
+鏀�
+钖�
+钘�
+槎�
+妾�
+娅�
+閲�
+娈�
+闇�
+杞�
+榻�
+榻�
+鐬�
+鏇�
+韬�
+锜�
+槎�
+鍤�
+缇�
+璩�
+缃�
+槎�
+閸�
+閸�
+閸�
+閸�
+閸�
+閺�
+閹�
+閺�
+绨�
+绡�
+绨�
+绫�
+鑷�
+楫�
+楫�
+楸�
+楫�
+楸�
+楗�
+閼�
+鐦�
+闂�
+楫�
+绯�
+榉�
+鐎�
+婵�
+璀�
+瑜�
+璀�
+璁�
+璀�
+槎�
+瀣�
+槎�
+椹�
+绺�
+绺�
+绺�
+绾�
+椹�
+绻�
+绻�
+鑰�
+鐡�
+鎿�
+鎿�
+鏀�
+鑱�
+瑕�
+闊�
+闉�
+铇�
+璩�
+妾�
+闈�
+榄�
+楗�
+杞�
+榻�
+榻�
+瑕�
+椤�
+韬�
+韬�
+锠�
+铻�
+椤�
+鍤�
+椤�
+閼�
+閹�
+閹�
+閹�
+閹�
+閹�
+閹�
+閼�
+绨�
+榉�
+榀�
+楸�
+榘�
+榘�
+榘�
+榀�
+榀�
+瑙�
+楗�
+楗�
+榻�
+璁�
+瑗�
+璀�
+灞�
+绾�
+绻�
+绻�
+椹�
+鎿�
+椤�
+椤�
+钘�
+娅�
+娅�
+璐�
+椋�
+閺�
+杞�
+锜�
+閻�
+閺�
+閺�
+閺�
+閺�
+閺�
+閺�
+閺�
+閺�
+姘�
+绌�
+榄�
+榀�
+榀�
+榀�
+榀�
+榀�
+榀�
+榀�
+榀�
+鐛�
+榉�
+璐�
+鐧�
+鏂�
+鐎�
+椤�
+绻�
+绻�
+绻�
+铇�
+榉�
+榻�
+榻�
+韬�
+韫�
+缇�
+閻�
+閻�
+閻�
+閻�
+閼�
+閼�
+閺�
+閻�
+绫�
+榉�
+楸�
+榘�
+榀�
+榘�
+榘�
+榘�
+榀�
+榉�
+鎳�
+榉�
+榘�
+闊�
+椤�
+榉�
+浯�
+楂�
+閼�
+閻�
+閻�
+璁�
+榘�
+榘�
+榘�
+鐧�
+鏀�
+闈�
+韬�
+楂�
+楂�
+閼�
+绫�
+榘�
+榘�
+楸�
+榘�
+楸�
+璁�
+椹�
+绾�
+鐡�
+榧�
+榛�
+榛�
+閼�
+閼�
+鑷�
+楸�
+楸�
+楸�
+椹�
+椤�
+楸�
+鐧�
+鐏�
+楦�
+閼�
+瓒�
+椤�
+韬�
+楗�
+鎴�
+鎴�
+瑷�
+瑷�
+閲�
+淇�
+闁�
+婢�
+瑷�
+瑷�
+瑭�
+绱�
+绾�
+鐟�
+鍓�
+濉�
+澹�
+鍩�
+鎾�
+钄�
+姒�
+杌�
+杌�
+鍜�
+銧�
+瑕�
+銘�
+棰�
+闁�
+娼�
+婀�
+婢�
+娴�
+璜�
+绂�
+瑭�
+瑭�
+瑭�
+灞�
+褰�
+绱�
+棣�
+棣�
+绱�
+绱�
+椐�
+绱�
+鐟�
+钖�
+妫�
+杌�
+鏆�
+鏅�
+宕�
+閲�
+閲�
+閸�
+閸�
+閯�
+鐛�
+椋�
+宥�
+瑭�
+瑭�
+閯�
+槌�
+闅�
+闅�
+濞�
+閫�
+椐�
+椐�
+椐�
+绲�
+楱�
+洚�
+绱�
+绱�
+鐡�
+闊�
+澧�
+濉�
+钖�
+钑�
+钄�
+钁�
+槌�
+榫�
+杌�
+杌�
+杞�
+杌�
+鐫�
+鏇�
+鍣�
+閳�
+閳�
+閴�
+閶�
+閲�
+閷�
+閳�
+閳�
+閳�
+鍊�
+鑹�
+槎�
+棰�
+椁�
+婀�
+婧�
+婊�
+瑜�
+绲�
+椐�
+绲�
+椐�
+缍�
+缍�
+椹�
+鍕�
+鐠�
+稹憤
+鋼�
+钖�
+钘�
+妞�
+姊�
+闋�
+纭�
+杓�
+杓�
+杓�
+璨�
+鍡�
+鏇�
+鏆�
+閯�
+骞�
+杓�
+宥�
+璐�
+閴�
+閴�
+閼�
+閴�
+閴�
+閴�
+鍍�
+榇�
+榄�
+椁�
+鐕�
+婧�
+绀�
+绐�
+瑗�
+椐�
+绲�
+缍�
+楱�
+缍�
+鐠�
+澧�
+澹�
+鑱�
+铇�
+鍕�
+缃�
+妾�
+妫�
+鍘�
+鋬�
+纾�
+绀�
+榇�
+榻�
+闋�
+寤�
+鍑�
+浜�
+鏋�
+灞�
+鍖�
+鍖�
+绱�
+绱�
+鐤�
+娈�
+璁�
+瑙�
+鍏�
+瀹�
+銜�
+銧�
+鏍�
+浣�
+浣�
+鍛�
+鏁�
+鍐�
+鍧�
+鍍�
+鎬�
+鎮�
+鍐�
+澶�
+鎴�
+鐗�
+濡�
+瀣�
+鎽�
+閲�
+鏀�
+瑷�
+琛�
+琛�
+寮�
+鍠�
+鍥�
+銧�
+棰�
+绉�
+鍊�
+楂�
+浣�
+鏈�
+姘�
+姹�
+浣�
+涓�
+绔�
+姹�
+姹�
+鐣�
+濮�
+寤�
+鎸�
+琛�
+鎼�
+闃�
+鎾�
+鍩�
+闃�
+瑾�
+銜�
+鍗�
+鍒�
+鍒�
+鍒�
+鑺�
+铇�
+妗�
+妲�
+鑽�
+鐛�
+鍞�
+鑴�
+鐨�
+褰�
+楂�
+鐤�
+鍒�
+閴�
+閼�
+娉�
+鐗�
+鎭�
+妫�
+娲�
+姹�
+鐏�
+鐑�
+鑿�
+绂�
+渚�
+璺�
+鍧�
+鐜�
+濮�
+濡�
+缈�
+鎼�
+鏌�
+鎷�
+鐗�
+瑙�
+鍊�
+鎶�
+鐩�
+妗�
+鍌�
+閫�
+鑲�
+鑿�
+宕�
+宕�
+鍛�
+铏�
+鍢�
+璎�
+瑭�
+銦�
+宓�
+宸�
+宸�
+闆�
+绋�
+鍜�
+宥�
+濡�
+濮�
+寤�
+寰�
+椁�
+鎺�
+瀵�
+鍞�
+閫�
+鏄�
+鍏�
+鸠爮
+浜�
+浜�
+錁�
+娣�
+鍔�
+鍖�
+愠�
+鐏�
+娲�
+闇�
+娣�
+瑷�
+鎭�
+绠�
+灞�
+绲�
+鍦�
+鏃�
+鐝�
+鎺�
+鍨�
+鑹�
+鑼�
+鏌�
+鏍�
+鏌�
+鏍�
+妗�
+鏌�
+闊�
+鎻�
+鏄�
+闁�
+楝�
+鍐�
+鏆�
+鍤�
+鍊�
+馉窗
+鍋�
+鍠�
+榻�
+娆�
+姒�
+銘�
+鍎�
+鏁�
+鏁�
+鑲�
+鑴�
+錁�
+琛�
+璺�
+韫�
+鐮�
+绀�
+钖�
+楝�
+鎭�
+鎬�
+鍗�
+錁�
+璩�
+濠�
+鐣�
+鎻�
+缍�
+杓�
+鎭�
+韬�
+鏅�
+妫�
+瑕�
+鎱�
+缈�
+鑴�
+妲�
+悒�
+铻�
+锜�
+悚�
+闄�
+宄�
+宄�
+涔�
+妞�
+鍜�
+绛�
+淇�
+闋�
+鍕�
+錉�
+韬�
+鎱�
+鎷�
+悃�
+鎸�
+鑴�
+鑳�
+鑲�
+璨�
+憬�
+鐣�
+娣�
+鎮�
+钃�
+鍔�
+鍌�
+娑�
+缂�
+鑿�
+鐓�
+娣�
+婀�
+瑾�
+鐚�
+閱�
+璁�
+銤�
+瀵�
+瀛�
+妗�
+姣�
+鐟�
+鐠�
+鐟�
+悒�
+鎼�
+鎼�
+钄�
+鎯�
+妤�
+妲�
+鎹�
+寤�
+鎱�
+鎱�
+鐬�
+鍩�
+鐣�
+铏�
+绋�
+妫�
+鐘�
+杩�
+濯�
+鍏�
+鑸�
+鎱�
+缍�
+鑵�
+皓搻
+澶�
+璞�
+璨�
+婀�
+娓�
+搴�
+钄�
+鑿�
+鏈�
+鐫�
+瑙�
+楹�
+閲�
+閵�
+鐥�
+娈�
+濠�
+婊�
+婀�
+愦�
+妯�
+椤�
+銤�
+绐�
+绐�
+鐞�
+娆�
+澧�
+瓒�
+闅�
+鎰�
+鎻�
+鎻�
+鐓�
+鏈�
+悛�
+濉�
+钄�
+钄�
+绋�
+妫�
+纰�
+妞�
+鍋�
+銜�
+寤�
+寤�
+榇�
+鍐�
+銤�
+鏅�
+榧�
+椁�
+椁�
+鍡�
+璜�
+恪�
+璩�
+绛�
+绛�
+绛�
+鏍�
+鏆�
+鐨�
+韪�
+铦�
+悛�
+鐕�
+閬�
+濯�
+鍢�
+搴�
+绐�
+鐗�
+鐗�
+绐�
+寰�
+鍍�
+甯�
+瑁�
+寮�
+褰�
+鐤�
+澹�
+鐡�
+浒�
+鐨�
+鎿�
+悌�
+悌�
+鏀�
+鎳�
+闉�
+骞�
+惝�
+閰�
+瑭�
+閱�
+鎺�
+韪�
+慵�
+鐩�
+纾�
+瑕�
+鍊�
+悻�
+鐓�
+鐓�
+鏅�
+闂�
+鐐�
+璺�
+錀�
+锠�
+瀵�
+杈�
+绋�
+绌�
+鐕�
+璀�
+鐦�
+鐧�
+椤�
+楠�
+鐚�
+铦�
+绋�
+鐥�
+鐧�
+浜�
+恽�
+闊�
+娉�
+閬�
+鏄�
+韬�
+鑷�
+缇�
+悻�
+鏇�
+鐤�
+鍕�
+鐞�
+鐡�
+黏嫯
+鐔�
+鐗�
+鎼�
+璎�
+鍫�
+楣�
+楣�
+鐭�
+鐕�
+楂�
+黏亥
+杈�
+鏃�
+稹殎
+娼�
+鐮�
+瑭�
+瀚�
+娅�
+鎾�
+澧�
+璀�
+闉�
+闉�
+钑�
+姗�
+铇�
+閱�
+璀�
+璺�
+韫�
+铚�
+锠�
+绋�
+娈�
+鎯�
+鍘�
+瑗�
+鐧�
+鋳�
+椁�
+娼�
+鐧�
+椤�
+榉�
+钘�
+娅�
+铻�
+韫�
+锜�
+璀�
+绨�
+褰�
+鐞�
+榈�
+椁�
+椁�
+绨�
+绮�
+鐕�
+绶�
+骞�
+韫�
+绮�
+绌�
+鑷�
+绫�
+绻�
+椋�
+瀛�
+锠�
+鐕�
+铦�
+绋�
+绌�
+鎯�
+瑕�
+閼�
+鎴�
+闃�
+鍓�
+甯�
+宸�
+浜�
+浣�
+绔�
+绌�
+宀�
+铏�
+穰崙
+缇�
+鍟�
+濮�
+銟�
+琚�
+琚�
+閫�
+銙�
+鐘�
+姘�
+鍋�
+鐢�
+缃�
+鍐�
+濮�
+铦�
+鐞�
+鐟�
+灏�
+姊�
+鏂�
+鏂�
+鏂�
+鏆�
+姣�
+铦�
+鍚�
+鍝�
+宄�
+绮�
+绔�
+鐙�
+绉�
+鐑�
+愠�
+琚�
+鐩�
+娑�
+钂�
+纰�
+锠�
+鍞�
+鍊�
+鍎�
+闆�
+鐨�
+鑷�
+琛�
+涠�
+鑷�
+鐛�
+鐥�
+鐨�
+婀�
+婢�
+婵�
+濉�
+瑗�
+濞�
+鍕�
+鍕�
+鎴�
+寤�
+寤�
+鐪�
+瑕�
+鍕�
+鍟�
+鍣�
+鍌�
+鎸�
+悭�
+鎯�
+鎱�
+闄�
+钑�
+钀�
+钑�
+铇�
+钘�
+娅�
+绠�
+妲�
+鍟�
+韫�
+铓�
+鐥�
+铔�
+铚�
+鐦�
+閬�
+閱�
+椋�
+鍐�
+绨�
+鏋�
+鏌�
+妾�
+妤�
+鐭�
+妞�
+鍢�
+鐛�
+绮�
+鋱�
+璜�
+榻�
+鍫�
+鐤�
+闆�
+绉�
+绋�
+妲�
+鎼�
+寤�
+鍙�
+鍢�
+铚�
+绛�
+绡�
+楹�
+绯�
+绶�
+鐠�
+楂�
+鑷�
+椁�
+鍓�
+姗�
+缃�
+铚�
+鐭�
+鎲�
+缈�
+楗�
+鐬�
+缇�
+缇�
+鐖�
+绻�
+楱�
+楝�
+楱�
+钄�
+錉�
+绨�
+韬�
+韫�
+錆�
+璨�
+榧�
+楹�
+濉�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銈�
+銈�
+銈�
+銈�
+銈�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锝�
+锞�
+锞�
+锞�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+鍐�
+姘�
+绯�
+绲�
+妤�
+甯�
+鎴�
+搴�
+榛�
+鍥�
+绶�
+瑾�
+澹�
+姝�
+姣�
+浜�
+鎮�
+鍦�
+鎵�
+鍥�
+鐐�
+澹�
+闅�
+鏍�
+鍠�
+椐�
+濉�
+绺�
+鑹�
+蹇�
+妗�
+绌�
+浠�
+渚�
+绠�
+銈�
+銈�
+銈�
+銉�
+銉�
+銏�
+涓�
+涓�
+涓�
+浜�
+浠�
+浼�
+渚�
+淇�
+鍊�
+鍊�
+鍊�
+鍋�
+鍋�
+鍍�
+鍎�
+鍏�
+鍏�
+鍐�
+鍐�
+鍑�
+鍑�
+鍑�
+鍒�
+鍓�
+鍓�
+鍓�
+鍔�
+鍔�
+鍕�
+鍕�
+鍖�
+鍖�
+鍖�
+鍗�
+鍗�
+鍘�
+鍙�
+鍛�
+鍛�
+鍛�
+鍛�
+鍞�
+鍠�
+鍠�
+鍠�
+鍣�
+鍣�
+鍤�
+鍥�
+鍥�
+鍦�
+鍦�
+鍫�
+鍫�
+濉�
+濉�
+濉�
+澧�
+澧�
+澹�
+澹�
+澹�
+澶�
+濂�
+濮�
+濞�
+瀚�
+瀣�
+瀣�
+瀛�
+瀹�
+瀹�
+瀹�
+瀵�
+瀵�
+瀵�
+灏�
+灏�
+宄�
+宕�
+宥�
+宸�
+宸�
+宸�
+宸�
+甯�
+骞�
+搴�
+寤�
+寤�
+寮�
+寮�
+寮�
+寮�
+寮�
+寰�
+寰�
+寰�
+蹇�
+鎭�
+鎮�
+鎯�
+鎳�
+鎳�
+鎴�
+鎴�
+鎴�
+鎵�
+鎶�
+鎶�
+鎷�
+鎷�
+鎷�
+鎷�
+鎸�
+鎸�
+鎹�
+鎹�
+鎺�
+鎺�
+鎺�
+鎻�
+鎻�
+鎻�
+鎽�
+鎾�
+鎾�
+鏂�
+鏂�
+鏃�
+鏃�
+鏅�
+鏅�
+鏆�
+鏆�
+鏇�
+鏉�
+鏉�
+鏉�
+鏉�
+鏋�
+鏋�
+鏋�
+鏌�
+鏍�
+鏍�
+妗�
+妗�
+妗�
+姊�
+姊�
+姊�
+姊�
+妞�
+妞�
+妞�
+妤�
+妤�
+妤�
+姒�
+姒�
+妲�
+妲�
+妲�
+妲�
+妯�
+妯�
+妯�
+姗�
+妾�
+娆�
+姝�
+姝�
+姝�
+姝�
+姝�
+姣�
+娌�
+娌�
+娴�
+娑�
+娓�
+娓�
+娓�
+娓�
+娓�
+婧�
+婊�
+婕�
+娼�
+婢�
+鐎�
+鐎�
+鐒�
+鐒�
+鐓�
+鐓�
+鐓�
+鐕�
+鐖�
+鐘�
+鐙�
+鐚�
+鐛�
+鐛�
+鐝�
+鐟�
+鐢�
+鐣�
+鐣�
+鐣�
+鐣�
+鐣�
+鐥�
+鐧�
+鐧�
+鐪�
+鐪�
+鐮�
+纰�
+绀�
+绂�
+绂�
+绋�
+绌�
+绌�
+绔�
+绔�
+绔�
+绗�
+绛�
+绛�
+绛�
+绠�
+绠�
+绠�
+绡�
+绡�
+绨�
+绫�
+绮�
+绮�
+绮�
+绮�
+绯�
+绱�
+绲�
+绲�
+绲�
+绲�
+绲�
+缍�
+缍�
+缍�
+绶�
+绺�
+绺�
+绺�
+绺�
+绻�
+绻�
+绻�
+绻�
+绻�
+绾�
+绾�
+缃�
+缃�
+缃�
+缇�
+缇�
+缇�
+鑱�
+鑱�
+鑱�
+鑱�
+鑴�
+鑴�
+鑶�
+鑶�
+鑷�
+鑷�
+鑷�
+鑸�
+鑸�
+鑸�
+鑸�
+鑺�
+鑻�
+鑼�
+鑽�
+鑽�
+鑾�
+鑾�
+鑿�
+钀�
+钄�
+钖�
+钖�
+钖�
+钖�
+铇�
+铔�
+铦�
+铦�
+锜�
+琛�
+琛�
+琚�
+琚�
+琚�
+琚�
+琚�
+瑁�
+瑁�
+瑁�
+瑜�
+瑜�
+瑗�
+瑗�
+瑕�
+瑕�
+瑕�
+瑕�
+瑷�
+瑷�
+璜�
+璜�
+璜�
+璜�
+璜�
+璀�
+璀�
+璁�
+璞�
+璞�
+璞�
+璩�
+璩�
+璐�
+韬�
+韬�
+杌�
+杌�
+杓�
+杈�
+杈�
+杈�
+杈�
+閫�
+閬�
+閬�
+閭�
+閮�
+閰�
+閱�
+閱�
+閱�
+閲�
+閴�
+閴�
+閴�
+閴�
+閴�
+閵�
+閵�
+閵�
+閶�
+閶�
+閶�
+閷�
+閷�
+閷�
+閷�
+閷�
+閸�
+閸�
+閸�
+閹�
+閹�
+閹�
+閹�
+閻�
+閻�
+閻�
+閼�
+閼�
+閼�
+閼�
+闁�
+闁�
+闁�
+闂�
+闄�
+闄�
+闅�
+闅�
+闆�
+闆�
+闇�
+闈�
+闈�
+闈�
+闈�
+闉�
+闉�
+闋�
+闋�
+闋�
+闋�
+椤�
+椤�
+椁�
+楗�
+椐�
+椐�
+椐�
+楱�
+楱�
+楱�
+楂�
+楂�
+楂�
+楂�
+榀�
+榀�
+榀�
+榘�
+榘�
+榘�
+槌�
+榇�
+榇�
+榈�
+榈�
+榈�
+槎�
+楣�
+楹�
+楹�
+楹�
+榛�
+榛�
+榧�
+榻�
+榫�
+绺�
+锜�
+鍧�
+绁�
+榧�
+楸�
+铔�
+灞�
+鍛�
+鐓�
+鍚�
+鎵�
+铓�
+閵�
+灏�
+澶�
+榈�
+寰�
+瀵�
+褰�
+鑸�
+婀�
+楹�
+閸�
+宕�
+楸�
+鐩�
+鎷�
+鐟�
+鑼�
+鐒�
+濂�
+椹�
+楸�
+鐮�
+鐥�
+寤�
+鍍�
+鐦�
+楸�
+鎿�
+宥�
+娣�
+璺�
+娴�
+濯�
+鐠�
+鐓�
+妾�
+濯�
+宄�
+韬�
+閴�
+濉�
+锜�
+榀�
+寮�
+鐑�
+榈�
+濡�
+瀛�
+铓�
+鎭�
+杓�
+寤�
+鐢�
+鏇�
+鐩�
+楱�
+鍥�
+楸�
+鑼�
+钁�
+閫�
+鐙�
+宕�
+瓒�
+鍑�
+缇�
+楫�
+鏄�
+妤�
+娓�
+鍦�
+楹�
+灞�
+閸�
+钁�
+娌�
+鐖�
+骞�
+绛�
+瀵�
+閵�
+璨�
+閹�
+鐔�
+鏄�
+閸�
+澧�
+鎰�
+纾�
+鍤�
+绋�
+鐝�
+閲�
+娈�
+閸�
+洳�
+钑�
+閻�
+鍍�
+浣�
+杓�
+鍐�
+瑗�
+璩�
+鐚�
+杈�
+绲�
+纾�
+闊�
+铻�
+璀�
+绀�
+閶�
+榄�
+鍤�
+妫�
+鐗�
+鏁�
+鏌�
+鐡�
+榄�
+宸�
+杞�
+瑗�
+鏋�
+楦�
+閫�
+閷�
+绺�
+甯�
+楱�
+濯�
+鍩�
+閯�
+钀�
+绁�
+鏃�
+瑭�
+槎�
+鐕�
+鍗�
+閵�
+搴�
+浼�
+姘�
+宓�
+鎸�
+鐓�
+绐�
+閻�
+楫�
+楸�
+榘�
+瀣�
+璀�
+璜�
+鑴�
+鎮�
+宕�
+闃�
+鍏�
+琚�
+鍐�
+澹�
+鍜�
+绀�
+瀛�
+鐥�
+鍩�
+鑲�
+榘�
+楫�
+婵�
+濉�
+鍑�
+钂�
+鍣�
+妗�
+宄�
+鐒�
+槎�
+閶�
+缍�
+槎�
+鐔�
+姣�
+鍜�
+鍢�
+鐫�
+绻�
+铯�
+鐦�
+閴�
+钄�
+绉�
+绶�
+铦�
+韬�
+锜�
+绻�
+鍥�
+澧�
+涔�
+鑳�
+婵�
+鐦�
+姒�
+閼�
+閻�
+宥�
+鐢�
+鍧�
+閵�
+钂�
+鐫�
+淇�
+椁�
+姒�
+钃�
+鐩�
+鍫�
+閸�
+鑻�
+宸�
+铓�
+鏆�
+鐔�
+瀣�
+澧�
+閺�
+鎴�
+鑿�
+鑶�
+鐔�
+鐫�
+鏍�
+鎹�
+姒�
+閸�
+鏇�
+鐘�
+闊�
+琚�
+鋿�
+鐒�
+鍠�
+楂�
+鐤�
+愦�
+渚�
+璨�
+钑�
+绂�
+钑�
+鍥�
+鏆�
+鍎�
+浣�
+鏌�
+銗�
+榘�
+鑻�
+楸�
+璎�
+閬�
+鐪�
+閼�
+缇�
+椤�
+闄�
+閵�
+榛�
+鑻�
+钂�
+妫�
+鍎�
+鍜�
+鎶�
+琛�
+妫�
+鐒�
+鑴�
+楹�
+鐜�
+鍩�
+娣�
+榛�
+娣�
+褰�
+楫�
+娌�
+绯�
+鍘�
+妤�
+宥�
+绨�
+妾�
+楸�
+宥�
+寤�
+鍗�
+妯�
+璐�
+閰�
+绫�
+娌�
+鏅�
+璜�
+钑�
+濡�
+閯�
+钂�
+濂�
+鎶�
+钃�
+钖�
+楸�
+宸�
+錆�
+浜�
+瀵�
+妲�
+瑾�
+楹�
+钑�
+婧�
+铇�
+姒�
+鏂�
+鏆�
+鐐�
+鎷�
+濞�
+绻�
+姗�
+瀵�
+鐖�
+楗�
+鎮�
+榀�
+褰�
+鐪�
+钁�
+瀣�
+鍩�
+鐛�
+棣�
+婧�
+鐎�
+鐔�
+纭�
+閳�
+妯�
+杓�
+榘�
+钄�
+娓�
+婢�
+鍡�
+鏃�
+绫�
+濯�
+鐕�
+鍎�
+闋�
+缂�
+淇�
+閫�
+楸�
+閮�
+姝�
+鏉�
+鐝�
+鏉�
+閱�
+榘�
+榈�
+閻�
+楫�
+宸�
+鑽�
+钖�
+鍥�
+韫�
+鐛�
+绂�
+閹�
+姒�
+鍍�
+缍�
+灏�
+鏁�
+鏇�
+瑜�
+楝�
+浜�
+閺�
+钃�
+瑁�
+楸�
+钖�
+榘�
+绠�
+楝�
+绺�
+鐠�
+鐢�
+鑼�
+杈�
+宀�
+瑕�
+婊�
+榀�
+閼�
+鍥�
+鑸�
+婧�
+鎷�
+鑿�
+鏁�
+铏�
+缍�
+铦�
+閱�
+绂�
+璩�
+寤�
+绲�
+妲�
+寰�
+閹�
+鏇�
+锠�
+鎹�
+鍫�
+鑾�
+钃�
+鏁�
+绂�
+娅�
+缍�
+鐎�
+閫�
+娴�
+纰�
+鍒�
+閫�
+鍓�
+姘�
+鑿�
+濞�
+铚�
+宓�
+绯�
+铻�
+璀�
+閺�
+宓�
+鐟�
+闅�
+妾�
+绶�
+鐣�
+鐮�
+绨�
+褰�
+榘�
+楱�
+绐�
+鍤�
+宓�
+灏�
+闋�
+妲�
+铏�
+閱�
+宸�
+褰�
+鍋�
+鐣�
+楸�
+濡�
+濉�
+鐣�
+閳�
+閷�
+纾�
+鎽�
+褰�
+鐠�
+鍥�
+瀵�
+鑰�
+楫�
+铇�
+寮�
+鐒�
+椋�
+鎴�
+濉�
+鍎�
+妲�
+鍣�
+榄�
+绂�
+浣�
+鍜�
+鐩�
+鐟�
+閴�
+鐫�
+閺�
+榧�
+閮�
+榄�
+鏈�
+婊�
+娓�
+婊�
+鐔�
+閱�
+閹�
+瑜�
+楝�
+宸�
+铻�
+鐪�
+閲�
+鏌�
+澹�
+宄�
+濮�
+鍞�
+楫�
+閳�
+瀚�
+澹�
+娲�
+榛�
+浼�
+鍫�
+宥�
+楫�
+闉�
+婕�
+閴�
+楫�
+澹�
+闃�
+濡�
+鐭�
+鐛�
+鍊�
+閵�
+榇�
+姗�
+鍑�
+鍝�
+灞�
+鍋�
+鐟�
+濯�
+娣�
+椹�
+妞�
+璧�
+钖�
+绯�
+纰�
+婵�
+閲�
+鏅�
+绾�
+瀵�
+闁�
+姝�
+鍛�
+槎�
+灞�
+娅�
+鐘�
+鏃�
+銠�
+榫�
+缈�
+铻�
+瑾�
+琛�
+娉�
+杌�
+榈�
+鑽�
+鍤�
+纭�
+妗�
+瑜�
+绛�
+榘�
+绉�
+鎴�
+杞�
+楝�
+椋�
+鍗�
+鏆�
+鐙�
+鎼�
+濞�
+閺�
+婧�
+姣�
+娣�
+璎�
+椁�
+榈�
+槌�
+楫�
+鐙�
+姘�
+杞�
+濡�
+琚�
+钃�
+姊�
+濞�
+鐗�
+绋�
+鍏�
+鐜�
+鐓�
+鍍�
+槎�
+楝�
+宕�
+閴�
+榀�
+铓�
+搴�
+榈�
+鍧�
+娈�
+鎮�
+鐔�
+鏁�
+閸�
+鏇�
+鎰�
+鎼�
+濮�
+鐮�
+妲�
+鑷�
+闊�
+闈�
+楦�
+钖�
+铏�
+锠�
+鍟�
+槎�
+鑻�
+婊�
+瑜�
+浠�
+鑳�
+鎲�
+閮�
+鐑�
+椹�
+鍐�
+鏋�
+澶�
+鎼�
+鍖�
+鐩�
+娅�
+闇�
+楹�
+璨�
+鍣�
+鍡�
+绗�
+鏅�
+鍐�
+閵�
+姣�
+鎱�
+鍥�
+闁�
+濞�
+搴�
+澹�
+棣�
+妗�
+鍏�
+钁�
+渚�
+鐓�
+閻�
+钘�
+榉�
+宓�
+閫�
+寮�
+鍖�
+閻�
+寤�
+鐮�
+瀛�
+鐏�
+浼�
+鍏�
+榇�
+婢�
+骞�
+鏃�
+鍕�
+绀�
+濠�
+楸�
+濞�
+閵�
+鍚�
+閸�
+浠�
+槌�
+褰�
+濞�
+鏄�
+榘�
+鍓�
+浣�
+閴�
+鍋�
+榘�
+璁�
+姗�
+鍟�
+宀�
+瀛�
+閲�
+涔�
+閳�
+婕�
+妾�
+鍩�
+绁�
+鐖�
+绂�
+楸�
+愀�
+姊�
+鐕�
+闇�
+鐐�
+椋�
+锠�
+鍕�
+榈�
+鍎�
+閻�
+鍞�
+寤�
+鍤�
+宓�
+澧�
+绱�
+鎼�
+鐦�
+鐨�
+楦�
+鐎�
+绮�
+鎾�
+宸�
+姊�
+鍟�
+鐪�
+璜�
+澶�
+鍍�
+閸�
+瑁�
+楫�
+鍑�
+椋�
+鐏�
+姗�
+瀚�
+绛�
+鍜�
+绮�
+鐡�
+鐠�
+浼�
+闁�
+鍌�
+榛�
+璎�
+椹�
+姗�
+铔�
+瀵�
+锠�
+鐬�
+鏃�
+缈�
+纭�
+瀵�
+闊�
+妤�
+榘�
+鏈�
+渚�
+榈�
+鎰�
+绁�
+鍘�
+涓�
+鐩�
+璎�
+榄�
+鍟�
+闁�
+鏇�
+鏋�
+缃�
+鍗�
+妯�
+榉�
+榀�
+閶�
+纾�
+鏋�
+鏀�
+锠�
+绌�
+鍤�
+妾�
+瓒�
+濂�
+閶�
+妾�
+钖�
+宄�
+鍜�
+瑷�
+闊�
+閼�
+楦�
+鍞�
+鎹�
+楦�
+瑾�
+缃�
+鐠�
+鏆�
+澶�
+璩�
+闉�
+閳�
+鐏�
+楫�
+鎳�
+绫�
+鏄�
+闄�
+瑗�
+楫�
+閳�
+鍥�
+濠�
+鑹�
+璨�
+浒�
+濮�
+绂�
+鍫�
+閶�
+浠�
+閺�
+璎�
+閼�
+蹇�
+铇�
+璎�
+瑙�
+濂�
+鐙�
+娉�
+妗�
+椋�
+鍨�
+鍟�
+鍤�
+榀�
+钂�
+姒�
+寰�
+鐠�
+鎻�
+娆�
+榄�
+鑿�
+鐜�
+槌�
+寤�
+渚�
+宀�
+宀�
+閶�
+鍑�
+褰�
+宕�
+濯�
+鍊�
+榈�
+鐮�
+榉�
+楸�
+楫�
+绻�
+鎽�
+璐�
+纾�
+閷�
+鐥�
+绮�
+鑳�
+濂�
+濉�
+鐎�
+楦�
+鍟�
+濞�
+闇�
+澹�
+宄�
+鐢�
+寤�
+瑕�
+榘�
+鐚�
+楸�
+鐩�
+瑁�
+鏉�
+姝�
+婢�
+铇�
+宓�
+灏�
+鏃�
+閴�
+閹�
+璞�
+鍑�
+姒�
+绂�
+榫�
+鎮�
+榉�
+楫�
+鍚�
+鍠�
+宀�
+鍚�
+婕�
+闋�
+璞�
+宸�
+閼�
+閱�
+鐔�
+鎳�
+婀�
+妾�
+闊�
+鎴�
+绶�
+閻�
+铳�
+绶�
+楫�
+濯�
+鐖�
+宸�
+瑜�
+閻�
+鏄�
+鎵�
+閸�
+鑺�
+锜�
+瀣�
+绯�
+鍚�
+濉�
+璀�
+鍐�
+閺�
+宥�
+鍡�
+妞�
+濮�
+闁�
+瑜�
+閷�
+鐜�
+绗�
+绡�
+钀�
+槎�
+铻�
+楫�
+榘�
+鑴�
+鍟�
+鏉�
+钃�
+灏�
+濞�
+娈�
+娣�
+铦�
+钃�
+褰�
+鍤�
+閵�
+鍥�
+鍧�
+娣�
+槎�
+楸�
+鍠�
+鐕�
+鑲�
+濮�
+寤�
+绂�
+绫�
+杩�
+宓�
+鍫�
+锜�
+鎲�
+寤�
+铚�
+绶�
+鍞�
+绔�
+宕�
+鐠�
+绮�
+鏍�
+缃�
+姊�
+璨�
+钘�
+铚�
+瑷�
+鏂�
+鐓�
+棣�
+濡�
+闁�
+鐤�
+澶�
+閹�
+鑶�
+婢�
+鍢�
+鍤�
+闈�
+閹�
+榘�
+绌�
+鐑�
+绺�
+瑜�
+鐤�
+澹�
+婧�
+鍦�
+鍜�
+榀�
+榀�
+纾�
+鐜�
+鐝�
+鏈�
+铓�
+婵�
+钖�
+鍤�
+涓�
+瀚�
+榀�
+妞�
+榘�
+鍒�
+锠�
+韪�
+鐎�
+鐞�
+榘�
+鐟�
+鑲�
+銗�
+娆�
+濯�
+绔�
+璁�
+穑噳
+瑁�
+绶�
+寤�
+榻�
+鍙�
+淇�
+鍘�
+婊�
+閷�
+榉�
+榀�
+鏀�
+濮�
+钄�
+骞�
+绺�
+灞�
+榀�
+闆�
+绾�
+瀚�
+宓�
+灞�
+宥�
+璺�
+閶�
+钑�
+绡�
+淇�
+娣�
+鏆�
+閺�
+鎲�
+鐜�
+婧�
+绗�
+绯�
+鍕�
+闁�
+娌�
+鍜�
+閴�
+铇�
+淇�
+宕�
+姣�
+鑻�
+鎺�
+榇�
+钀�
+淇�
+灞�
+钂�
+鑹�
+鍓�
+鎱�
+鏈�
+鏋�
+姘�
+鐚�
+鐢�
+绠�
+璀�
+璐�
+杩�
+閳�
+閸�
+閸�
+閺�
+闈�
+椁�
+涓�
+涓�
+浠�
+浠�
+浼�
+浼�
+浠�
+浼�
+浼�
+浣�
+浣�
+渚�
+渚�
+浣�
+浣�
+浣�
+渚�
+渚�
+淇�
+渚�
+淇�
+渚�
+渚�
+淇�
+鍊�
+鍊�
+鍊�
+鍊�
+鍊�
+鍊�
+淇�
+鍊�
+鍋�
+鍋�
+鍋�
+鍋�
+鍋�
+鍋�
+鍋�
+鍋�
+鍋�
+鍋�
+鍋�
+鍌�
+鍌�
+鍌�
+鍌�
+鍌�
+鍌�
+鍌�
+鍋�
+鍌�
+鍌�
+鍌�
+鍍�
+鍌�
+鍍�
+鍍�
+鍌�
+鍍�
+鍌�
+鍍�
+鍍�
+鍍�
+鍍�
+鍍�
+鍍�
+鍍�
+鍎�
+鍎�
+鍍�
+鍍�
+鍍�
+鍎�
+鍍�
+鍎�
+鍎�
+鍎�
+鍎�
+鍎�
+鍎�
+鍎�
+鍎�
+鍎�
+鍎�
+鍐�
+鍐�
+鍐�
+鍑�
+鍑�
+鍑�
+鍒�
+鍒�
+鍒�
+鍒�
+鍒�
+鍒�
+鍒�
+鍓�
+鍒�
+鍓�
+鍓�
+鍓�
+鍓�
+鍓�
+鍓�
+鍓�
+鍓�
+鍓�
+鍓�
+鍔�
+鍔�
+鍔�
+鍔�
+鍔�
+鍔�
+鍔�
+鍕�
+鍖�
+鍖�
+鍖�
+鍖�
+鍖�
+鍖�
+鍗�
+鍗�
+鍘�
+鍘�
+鍘�
+鍘�
+鍘�
+鍘�
+鍘�
+鍘�
+鍚�
+鍚�
+鍚�
+鍛�
+鍜�
+鍛�
+鍛�
+鍛�
+鍛�
+鍛�
+鑼�
+鍜�
+鍜�
+鍜�
+鍝�
+鍜�
+鍜�
+鍞�
+鍞�
+鍞�
+鍝�
+鍞�
+鍞�
+鍝�
+鍞�
+鍞�
+鍟�
+鍞�
+鍟�
+鍟�
+鍞�
+鍞�
+鍠�
+鍠�
+鍠�
+鍣�
+鍠�
+鍠�
+鍟�
+鍠�
+鍡�
+鍡�
+鍡�
+鍡�
+鍠�
+鍠�
+鍡�
+鍡�
+鍡�
+鍢�
+鍢�
+鍡�
+鍢�
+鍢�
+鍢�
+鍡�
+鍢�
+鍢�
+鍡�
+鍣�
+鍣�
+鍣�
+鍣�
+鍢�
+鍢�
+鍢�
+鍣�
+鍣�
+鍣�
+鍣�
+鍣�
+鍤�
+鍤�
+鍤�
+鍤�
+鍤�
+鍤�
+鍤�
+鍤�
+鍤�
+鍤�
+鍤�
+鍤�
+鍥�
+鍥�
+鍥�
+鍥�
+鍦�
+鍦�
+鍦�
+鍧�
+鍧�
+鍧�
+鍧�
+鍨�
+鍧�
+鍨�
+鍨�
+鍨�
+鍨�
+鍨�
+鍨�
+鍩�
+鍩�
+鍫�
+鍫�
+濉�
+鍫�
+濉�
+濉�
+濉�
+濉�
+濉�
+澧�
+濉�
+濉�
+澧�
+濉�
+澧�
+澧�
+澹�
+澧�
+澹�
+澹�
+澹�
+澹�
+澹�
+澶�
+澶�
+澶�
+澶�
+濂�
+濂�
+濂�
+濂�
+濂�
+濡�
+濡�
+濡�
+濡�
+濡�
+濮�
+濮�
+銡�
+濮�
+濮�
+濮�
+濞�
+濠�
+濠�
+濠�
+濠�
+濠�
+濯�
+濯�
+濯�
+濠�
+濯�
+濯�
+濯�
+濯�
+濞�
+瀚�
+瀚�
+濯�
+濯�
+瀚�
+瀚�
+瀚�
+瀚�
+瀚�
+瀚�
+瀚�
+瀚�
+瀣�
+瀣�
+瀣�
+瀣�
+瀣�
+瀛�
+灞�
+瀛�
+瀛�
+瀹�
+瀹�
+瀵�
+瀵�
+瀵�
+瀵�
+瀵�
+瀵�
+瀵�
+灏�
+灏�
+灏�
+灏�
+灏�
+灞�
+灞�
+灞�
+灞�
+灞�
+灞�
+灞�
+宀�
+宀�
+宀�
+宀�
+宀�
+宀�
+宀�
+宀�
+宀�
+宄�
+宄�
+宄�
+宄�
+宄�
+宄�
+宄�
+宄�
+宕�
+宕�
+宕�
+宕�
+宕�
+宕�
+宕�
+宓�
+宓�
+宕�
+宕�
+宓�
+宓�
+宓�
+宓�
+宓�
+宥�
+宓�
+宥�
+宓�
+宓�
+宥�
+宥�
+宥�
+宓�
+宥�
+宥�
+宥�
+宥�
+宥�
+宥�
+宥�
+宥�
+宥�
+宸�
+宸�
+宸�
+宸�
+宸�
+甯�
+甯�
+甯�
+甯�
+甯�
+甯�
+甯�
+甯�
+甯�
+骞�
+骞�
+骞�
+骞�
+骞�
+骞�
+骞�
+骞�
+骞�
+骞�
+骞�
+搴�
+搴�
+搴�
+搴�
+搴�
+搴�
+搴�
+搴�
+搴�
+搴�
+搴�
+搴�
+寤�
+寤�
+寤�
+寤�
+寤�
+寤�
+绶�
+寤�
+寤�
+寤�
+寤�
+锠�
+寤�
+寮�
+寮�
+寮�
+寮�
+寮�
+寮�
+褰�
+褰�
+褰�
+褰�
+褰�
+褰�
+褰�
+褰�
+寰�
+寰�
+寰�
+寰�
+寰�
+寰�
+蹇�
+蹇�
+蹇�
+蹇�
+蹇�
+蹇�
+蹇�
+蹇�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+鎯�
+鎯�
+鎯�
+鎮�
+鎯�
+鎮�
+鎯�
+鎯�
+鎯�
+鎰�
+鎰�
+鎰�
+鎯�
+鎰�
+鎯�
+鎯�
+鎯�
+鎱�
+鎱�
+鎰�
+鎰�
+鎰�
+鎰�
+鎰�
+鎱�
+鎱�
+鎱�
+鎱�
+鎱�
+鎱�
+鎲�
+鎱�
+鎱�
+鎱�
+鎱�
+鎲�
+鎱�
+鎲�
+鎲�
+鎲�
+鎲�
+鎲�
+鎲�
+鎲�
+鎲�
+鎲�
+鎲�
+鎲�
+鎳�
+鎲�
+鎳�
+鎳�
+鎲�
+鎲�
+鎲�
+鎲�
+鎳�
+鎳�
+鎳�
+鎳�
+鎳�
+鎳�
+鎳�
+鎳�
+鎳�
+鎳�
+鎳�
+鎴�
+鎴�
+鎴�
+鎴�
+鎴�
+閰�
+鎴�
+鎵�
+鎵�
+鎵�
+鎵�
+鎵�
+鎶�
+鎶�
+鎶�
+鎶�
+鎵�
+鎶�
+鎶�
+鎷�
+鎶�
+鎶�
+鎶�
+鎶�
+鎸�
+鎸�
+鎸�
+鎷�
+鎷�
+鎸�
+鎸�
+鎷�
+鎸�
+鎷�
+鎹�
+鎸�
+鎸�
+鎻�
+鎹�
+鎸�
+鎸�
+鎹�
+鎸�
+鎹�
+鎹�
+鎹�
+鎺�
+鎺�
+鎺�
+鎺�
+鎹�
+鎺�
+鎹�
+鎺�
+鎺�
+鎺�
+鎻�
+鎻�
+鎻�
+鎻�
+鎻�
+鎻�
+鎻�
+鎽�
+鎻�
+鎻�
+鎻�
+鎻�
+鎻�
+鎻�
+鎼�
+鎼�
+鎼�
+鎼�
+鎼�
+鎼�
+鎼�
+鎼�
+鎼�
+鎼�
+鎽�
+鎼�
+鎼�
+鎽�
+鎽�
+鎽�
+鎽�
+鎽�
+鎽�
+鎽�
+鎽�
+鎽�
+鎽�
+鎽�
+鎾�
+鎾�
+鎾�
+鎾�
+鎾�
+鎾�
+鎾�
+鎾�
+鎿�
+鎿�
+鎿�
+鎿�
+鎾�
+鎿�
+鎿�
+鎿�
+鎿�
+鎿�
+鎿�
+鎿�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏂�
+鏂�
+鏂�
+鏂�
+鏂�
+鏂�
+鏂�
+鏂�
+鏂�
+鏃�
+鏃�
+鏃�
+鏃�
+鏃�
+鏄�
+鏄�
+鏄�
+鏅�
+鏅�
+鏅�
+鏅�
+鏅�
+鏆�
+鏆�
+鏆�
+鏆�
+鏆�
+鏆�
+鏆�
+鏇�
+鏇�
+鏇�
+鏇�
+鏇�
+鏇�
+鏇�
+鏇�
+鏈�
+鏈�
+鏈�
+鏈�
+鏈�
+鏈�
+鏈�
+鏈�
+鏈�
+鏈�
+鏉�
+鏉�
+鏉�
+鏉�
+鏋�
+鏉�
+鏋�
+鏋�
+鏌�
+鏋�
+鏋�
+鏌�
+鏌�
+鏌�
+鏌�
+鏌�
+鏌�
+鏌�
+鏌�
+鏌�
+鏌�
+鏍�
+妗�
+妗�
+鏍�
+鏍�
+鏍�
+鏍�
+鏍�
+鏍�
+鏍�
+姊�
+姊�
+姊�
+妗�
+姊�
+妤�
+姊�
+姊�
+妗�
+姊�
+妞�
+妞�
+妫�
+妫�
+妫�
+妫�
+妞�
+妤�
+妫�
+妞�
+妫�
+妤�
+妤�
+妤�
+妤�
+妤�
+妤�
+妤�
+妤�
+妤�
+妞�
+妤�
+妤�
+妤�
+妤�
+姒�
+妲�
+姒�
+姒�
+姒�
+姒�
+姒�
+姒�
+姒�
+妲�
+姒�
+姒�
+妲�
+妲�
+妯�
+妯�
+妲�
+妲�
+妯�
+妯�
+妲�
+妯�
+妲�
+妯�
+妲�
+姗�
+妯�
+姗�
+姗�
+妯�
+姗�
+姗�
+姗�
+姗�
+妯�
+姗�
+妾�
+妾�
+妾�
+妾�
+姗�
+妾�
+妾�
+妾�
+妾�
+娅�
+妾�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+姝�
+姝�
+姝�
+姝�
+姝�
+姝�
+姝�
+姝�
+姝�
+姝�
+鑲�
+娈�
+娈�
+娈�
+娈�
+娈�
+娈�
+娈�
+娈�
+娈�
+娈�
+娈�
+娈�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姘�
+姘�
+姘�
+姘�
+姘�
+姹�
+姹�
+姹�
+姹�
+姹�
+娌�
+姹�
+姹�
+娌�
+姹�
+姹�
+娉�
+娌�
+娌�
+娉�
+娌�
+娉�
+娉�
+娉�
+娌�
+娲�
+娲�
+娲�
+娴�
+娴�
+娲�
+娑�
+娴�
+娴�
+娑�
+娑�
+娴�
+娑�
+娑�
+娑�
+娣�
+娑�
+娣�
+娓�
+娣�
+娑�
+娣�
+娑�
+娣�
+婀�
+婀�
+婀�
+婀�
+娓�
+婀�
+娓�
+娓�
+婀�
+娓�
+娓�
+婀�
+婀�
+娓�
+娓�
+婀�
+婀�
+婀�
+娓�
+婧�
+婊�
+婧�
+婧�
+婊�
+婧�
+婧�
+婊�
+婊�
+婊�
+婕�
+婕�
+婕�
+娼�
+婕�
+婕�
+婕�
+婕�
+婊�
+婕�
+娼�
+婊�
+娼�
+婕�
+娼�
+婕�
+婵�
+婢�
+婢�
+娼�
+娼�
+婢�
+娼�
+娼�
+娼�
+娼�
+娼�
+婢�
+娼�
+婵�
+婵�
+婵�
+婵�
+婢�
+婢�
+鐎�
+婵�
+婢�
+婵�
+婵�
+婵�
+婵�
+婵�
+婵�
+鐎�
+鐎�
+婵�
+鐎�
+婵�
+鐎�
+鐎�
+鐎�
+鐎�
+鐎�
+鐎�
+鐎�
+鐎�
+鐏�
+鐎�
+鐎�
+鐎�
+鐏�
+鐏�
+鐏�
+鐏�
+鐏�
+鐏�
+鐏�
+鐏�
+鐏�
+鐐�
+鐐�
+鐑�
+鐑�
+缂�
+鐒�
+鐑�
+鐒�
+鐒�
+鐒�
+鐓�
+鐓�
+鐓�
+鐔�
+鐔�
+鐔�
+鐔�
+鐔�
+鐕�
+鐕�
+鐔�
+鐕�
+鐕�
+鐖�
+鐖�
+鐖�
+鐖�
+鐖�
+鐖�
+鐖�
+鐗�
+鐗�
+鐗�
+鐗�
+鐗�
+鐗�
+鐗�
+鐗�
+鐗�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐚�
+鐙�
+鐚�
+鐚�
+鐚�
+鐙�
+鐚�
+鐚�
+鐚�
+鐚�
+鐚�
+鐚�
+鐚�
+鐚�
+鐚�
+鐚�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐜�
+鐜�
+鐜�
+鐜�
+鐜�
+鐝�
+鐝�
+鐞�
+鐟�
+鐠�
+鐟�
+鐠�
+鐟�
+鐠�
+鐡�
+鐡�
+鐡�
+鐡�
+鐡�
+鐡�
+鐡�
+鐡�
+鐡�
+鐡�
+鐡�
+鐢�
+鐢�
+鐢�
+鐢�
+鐢�
+鐢�
+鐢�
+鐢�
+鐢�
+鐢�
+鐢�
+鐣�
+鐣�
+鐣�
+鐤�
+鐤�
+鐥�
+鐤�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐦�
+鐥�
+鐥�
+鐥�
+鐦�
+鐦�
+鐦�
+鐦�
+鐦�
+鐦�
+鐦�
+鐧�
+鐧�
+鐧�
+鐧�
+鐧�
+鐧�
+鐧�
+鐧�
+鐨�
+鐨�
+鐨�
+鐨�
+鐨�
+鐨�
+鐨�
+鐨�
+鐩�
+鐩�
+鐩�
+鐩�
+鐩�
+鐩�
+鐪�
+鐪�
+鐩�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐫�
+鐫�
+鐫�
+鐫�
+鐫�
+鐫�
+鐫�
+鐫�
+鐫�
+鐫�
+鐫�
+鐫�
+鐬�
+鐫�
+鐬�
+鐫�
+鐫�
+鐬�
+鐬�
+鐬�
+鐬�
+鐬�
+鐬�
+鐬�
+鐬�
+鐬�
+鐬�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐮�
+鐮�
+鐮�
+鐮�
+鐮�
+纭�
+纭�
+纭�
+纭�
+纭�
+纭�
+纭�
+纰�
+纰�
+纰�
+纰�
+纭�
+纰�
+纰�
+纾�
+纾�
+纾�
+纾�
+纾�
+纾�
+纾�
+纾�
+纾�
+纾�
+纾�
+纾�
+纾�
+绀�
+绀�
+绀�
+绀�
+绀�
+绀�
+绀�
+绀�
+绀�
+绀�
+绀�
+绁�
+绁�
+绁�
+绁�
+绁�
+绁�
+绁�
+绁�
+绁�
+绁�
+绁�
+绁�
+绁�
+绂�
+绂�
+绂�
+绂�
+绂�
+绂�
+绂�
+绂�
+绂�
+姝�
+绉�
+绉�
+绉�
+绉�
+绉�
+绉�
+绉�
+绉�
+绋�
+绋�
+绋�
+绌�
+绋�
+绋�
+绌�
+绌�
+绌�
+绌�
+绌�
+绌�
+绌�
+绌�
+绌�
+绌�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绔�
+绔�
+绔�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+绛�
+绛�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绡�
+绠�
+绠�
+绡�
+绡�
+绡�
+绡�
+绡�
+绡�
+绨�
+绡�
+绡�
+绡�
+绨�
+绡�
+绨�
+绨�
+绡�
+绡�
+绨�
+绨�
+绨�
+绨�
+绨�
+绨�
+绨�
+绨�
+绨�
+绨�
+绨�
+绨�
+绫�
+绫�
+绫�
+绫�
+绫�
+绫�
+绫�
+绫�
+绫�
+绫�
+绫�
+绮�
+绮�
+绮�
+绯�
+绯�
+绯�
+绯�
+绱�
+绱�
+绱�
+绱�
+绱�
+绱�
+绱�
+绲�
+绱�
+绲�
+绲�
+绲�
+绲�
+绲�
+绲�
+绲�
+缍�
+缍�
+绲�
+缍�
+绲�
+绲�
+缍�
+缍�
+绶�
+缍�
+绶�
+绶�
+绶�
+绶�
+绶�
+缍�
+缍�
+绶�
+绶�
+绶�
+绶�
+绺�
+绶�
+绶�
+绶�
+绺�
+绺�
+绺�
+绺�
+绺�
+绺�
+绺�
+绺�
+绻�
+绺�
+椤�
+绻�
+绺�
+绺�
+绻�
+绻�
+绺�
+绶�
+绺�
+绺�
+绺�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绾�
+绾�
+绾�
+绾�
+绾�
+绾�
+绾�
+缂�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+鑰�
+鑰�
+鑰�
+鑰�
+鑰�
+鑰�
+鑱�
+鑱�
+鑱�
+鑱�
+鑱�
+鑲�
+鑲�
+鑲�
+鑲�
+鑲�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑴�
+鑳�
+鑴�
+鑳�
+鑳�
+鑴�
+鑴�
+鑴�
+鑴�
+鑴�
+鑴�
+鑴�
+鑵�
+鑵�
+鑵�
+鑵�
+鑴�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+鏈�
+鑵�
+鑵�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑷�
+鑶�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑸�
+鑸�
+鑸�
+鑸�
+鑸�
+鑸�
+鑸�
+鑹�
+鑹�
+鑹�
+鑹�
+鑹�
+鑹�
+鑹�
+鑹�
+鑹�
+鑹�
+鑺�
+鑺�
+鑺�
+鑺�
+鑺�
+鑻�
+鑺�
+鑺�
+鑺�
+鑺�
+鑺�
+鑻�
+鑻�
+鑻�
+鑻�
+鑻�
+鑻�
+鑻�
+鑼�
+鑼�
+鑼�
+鑼�
+鑼�
+鑽�
+鑼�
+鑽�
+鑼�
+鑼�
+鑼�
+鑼�
+鑼�
+鑾�
+鑾�
+鑾�
+鑽�
+鑾�
+鑽�
+鑾�
+鑾�
+鑽�
+鑾�
+鑾�
+鑾�
+鑾�
+鑽�
+鑾�
+鑿�
+钀�
+鑿�
+鑿�
+鑿�
+鑿�
+鑿�
+鑿�
+鑿�
+鑿�
+钀�
+鑿�
+鑿�
+鑿�
+钃�
+钀�
+钁�
+钁�
+钁�
+钁�
+钀�
+钁�
+钁�
+钄�
+钁�
+钀�
+钀�
+钀�
+钁�
+鑿�
+钁�
+钀�
+钁�
+钁�
+钁�
+钃�
+钂�
+钂�
+钂�
+钂�
+钂�
+钂�
+钃�
+钂�
+钂�
+钂�
+钂�
+钂�
+钄�
+钄�
+钄�
+钄�
+钄�
+钄�
+钄�
+钃�
+钃�
+钃�
+钄�
+钃�
+钃�
+钃�
+钄�
+钃�
+钄�
+钃�
+钄�
+钄�
+钄�
+钃�
+钄�
+钃�
+钄�
+钄�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钖�
+钖�
+钖�
+钖�
+钖�
+钖�
+钖�
+钑�
+钖�
+钑�
+钖�
+钖�
+钖�
+钖�
+钖�
+钘�
+钘�
+钘�
+钘�
+钖�
+钖�
+钘�
+钘�
+钘�
+钘�
+钘�
+钖�
+钖�
+钘�
+钘�
+钘�
+钘�
+钘�
+钘�
+钘�
+钘�
+钘�
+钘�
+钘�
+钘�
+钘�
+铇�
+钘�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铏�
+铇�
+铇�
+铇�
+铇�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铓�
+铓�
+铓�
+铓�
+铓�
+铓�
+铓�
+铓�
+铓�
+铓�
+铔�
+铔�
+铔�
+铔�
+铓�
+铓�
+铓�
+铔�
+铓�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铚�
+铔�
+铚�
+铔�
+铔�
+铚�
+铔�
+铚�
+铦�
+铚�
+铦�
+铚�
+铦�
+铦�
+铚�
+铚�
+铚�
+铚�
+铚�
+铚�
+铦�
+铚�
+铚�
+铚�
+铚�
+铚�
+铦�
+铦�
+锜�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铻�
+铻�
+铻�
+铻�
+铻�
+铻�
+铻�
+铦�
+铻�
+铻�
+铻�
+铻�
+铻�
+铻�
+铻�
+铻�
+铻�
+铻�
+锜�
+锜�
+锜�
+铻�
+铻�
+铻�
+铻�
+锜�
+锜�
+锜�
+锜�
+锜�
+锜�
+锜�
+锜�
+锜�
+锜�
+铻�
+锜�
+锜�
+锠�
+锜�
+锠�
+锜�
+锠�
+锠�
+锜�
+锠�
+锜�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+琛�
+琛�
+琛�
+琛�
+琛�
+琛�
+琛�
+琚�
+琛�
+琛�
+琚�
+琚�
+琚�
+琚�
+琚�
+琚�
+琚�
+琚�
+琚�
+琚�
+琚�
+琚�
+瑁�
+琚�
+琚�
+瑁�
+琚�
+琚�
+琚�
+瑁�
+瑁�
+瑁�
+瑁�
+瑁�
+瑁�
+瑁�
+瑁�
+瑁�
+瑁�
+瑁�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑗�
+瑜�
+瑗�
+瑜�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑕�
+瑕�
+瑕�
+瑕�
+瑕�
+瑕�
+瑕�
+瑕�
+瑕�
+瑕�
+瑕�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑷�
+瑷�
+瑷�
+瑷�
+瑷�
+瑭�
+瑷�
+瑭�
+瑭�
+瑭�
+瑭�
+瑷�
+瑾�
+瑭�
+瑾�
+瑾�
+瑾�
+瑾�
+璜�
+瑾�
+璜�
+璜�
+瑾�
+璜�
+璜�
+璜�
+璜�
+璜�
+璜�
+璎�
+璎�
+璎�
+璎�
+璎�
+璎�
+璎�
+璎�
+璎�
+璎�
+璎�
+璎�
+璎�
+璀�
+璎�
+璎�
+璎�
+璎�
+璎�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璁�
+璁�
+璁�
+璁�
+璁�
+璁�
+璁�
+璋�
+璋�
+璋�
+璋�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璨�
+璨�
+璨�
+璨�
+璨�
+璨�
+璨�
+璨�
+璨�
+璨�
+璨�
+璩�
+璩�
+璩�
+璩�
+璩�
+璩�
+璐�
+璐�
+璐�
+璧�
+璧�
+璧�
+璧�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+韪�
+璺�
+韪�
+韪�
+韪�
+韪�
+璺�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韬�
+韬�
+韬�
+韬�
+韬�
+韬�
+韬�
+韬�
+韬�
+韬�
+韬�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杓�
+杌�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杈�
+杩�
+杩�
+杩�
+杩�
+杩�
+杩�
+杩�
+杩�
+杩�
+閫�
+閫�
+閬�
+閬�
+閬�
+閬�
+閭�
+閭�
+閬�
+閭�
+閭�
+閭�
+閭�
+閭�
+閭�
+閮�
+閮�
+閮�
+閮�
+閮�
+閮�
+閮�
+閮�
+閮�
+閮�
+閮�
+閯�
+閮�
+閯�
+閮�
+閮�
+閯�
+閯�
+閮�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閰�
+閰�
+閰�
+閰�
+閰�
+閰�
+閰�
+閰�
+閰�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閲�
+閲�
+閲�
+閲�
+閲�
+閲�
+閳�
+閳�
+閳�
+閲�
+閳�
+閴�
+閴�
+閴�
+閳�
+閴�
+閵�
+閵�
+閵�
+閴�
+閵�
+閶�
+閶�
+閶�
+閶�
+閶�
+閶�
+閶�
+閶�
+閷�
+閷�
+閷�
+閷�
+閶�
+閹�
+閹�
+閹�
+閸�
+閸�
+閸�
+閸�
+閸�
+閹�
+閹�
+閹�
+閹�
+閹�
+閹�
+閺�
+閺�
+閺�
+閺�
+閺�
+閻�
+閻�
+閺�
+閻�
+閻�
+閻�
+閻�
+閻�
+閻�
+閻�
+閻�
+閼�
+閼�
+閼�
+閼�
+閼�
+閽�
+閽�
+閽�
+閽�
+闀�
+闀�
+闀�
+闀�
+闁�
+闁�
+闁�
+闁�
+闂�
+闂�
+闂�
+闁�
+闂�
+闂�
+闂�
+闂�
+闂�
+闂�
+闂�
+闃�
+闃�
+闃�
+闃�
+闃�
+闃�
+闃�
+闃�
+闄�
+闄�
+闄�
+闄�
+闄�
+闄�
+闅�
+闄�
+闅�
+闅�
+闅�
+闅�
+闅�
+闅�
+闆�
+闆�
+闆�
+闆�
+闆�
+闆�
+闆�
+闆�
+闆�
+闆�
+闆�
+闇�
+闇�
+闇�
+闇�
+闇�
+闇�
+闇�
+闇�
+闇�
+闇�
+闇�
+闇�
+闇�
+闈�
+闈�
+闈�
+闈�
+闈�
+闈�
+闈�
+闉�
+闉�
+闉�
+闈�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闋�
+闋�
+闋�
+闋�
+闋�
+闋�
+闋�
+闋�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+棰�
+棰�
+棰�
+棰�
+棰�
+棰�
+椋�
+椋�
+椋�
+椋�
+椋�
+椋�
+椋�
+椁�
+椁�
+椋�
+椁�
+椁�
+椁�
+椁�
+椁�
+椁�
+椁�
+椁�
+椁�
+椁�
+椁�
+椁�
+椁�
+楗�
+楗�
+楗�
+楗�
+楗�
+楗�
+楗�
+楗�
+棣�
+棣�
+棣�
+棣�
+棣�
+棣�
+椐�
+棣�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+椹�
+楱�
+椹�
+椹�
+椹�
+椹�
+椹�
+椹�
+椹�
+椹�
+椹�
+楠�
+楠�
+楠�
+楠�
+楠�
+楠�
+楂�
+楂�
+楂�
+楂�
+楂�
+楂�
+楂�
+楂�
+楂�
+楂�
+楂�
+楂�
+楝�
+楂�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+榄�
+榄�
+榄�
+榄�
+榄�
+榄�
+榄�
+榄�
+榄�
+榄�
+楫�
+楫�
+榄�
+榄�
+榄�
+楫�
+楫�
+楫�
+楫�
+楫�
+楫�
+楫�
+楫�
+榀�
+楫�
+楫�
+榀�
+榀�
+榀�
+榀�
+榀�
+榀�
+榘�
+榘�
+榘�
+榀�
+榘�
+榘�
+榘�
+楸�
+榘�
+楸�
+楸�
+榘�
+楸�
+楸�
+楸�
+楸�
+楸�
+楸�
+楸�
+楸�
+楸�
+楸�
+槌�
+槌�
+槌�
+槌�
+槌�
+槌�
+槌�
+槌�
+槌�
+榇�
+槌�
+槌�
+榇�
+榇�
+榇�
+榇�
+榇�
+榇�
+榇�
+榇�
+榇�
+榇�
+榈�
+榈�
+榇�
+榇�
+榇�
+榇�
+榈�
+榈�
+榇�
+榈�
+榇�
+榈�
+榈�
+榈�
+榈�
+榈�
+榈�
+榈�
+榈�
+榈�
+槎�
+槎�
+槎�
+槎�
+榈�
+槎�
+榈�
+槎�
+槎�
+榈�
+榈�
+榈�
+榈�
+槎�
+榈�
+榈�
+槎�
+榈�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+榉�
+榉�
+榉�
+榉�
+槎�
+榉�
+榉�
+槎�
+榉�
+槎�
+槎�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+楦�
+榉�
+楦�
+楦�
+楦�
+楦�
+楦�
+楦�
+楦�
+榉�
+榉�
+楦�
+楦�
+楦�
+楦�
+楦�
+楦�
+楦�
+楦�
+楦�
+楣�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榫�
+榫�
+鍫�
+绀�
+钂�
+钂�
+鍏�
+鍏�
+鍏�
+鍏�
+鍏�
+鍏�
+鍡�
+鐡�
+蹇�
+鎿�
+姘�
+绌�
+鎿�
+璀�
+!
+"
+#
+$
+%
+&
+'
+(
+)
+*
++
+,
+-
+.
+/
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+:
+;
+<
+=
+>
+?
+A
+B
+C
+D
+E
+F
+G
+H
+I
+J
+K
+L
+M
+N
+O
+P
+Q
+R
+S
+T
+U
+V
+W
+X
+Y
+Z
+[
+]
+_
+`
+a
+b
+c
+d
+e
+f
+g
+h
+i
+j
+k
+l
+m
+n
+o
+p
+q
+r
+s
+t
+u
+v
+w
+x
+y
+z
+漏
+掳
+虏
+麓
+陆
+脕
+脛
+脜
+脟
+脠
+脡
+脥
+脫
+脰
+脳
+脺
+脽
+脿
+谩
+芒
+茫
+盲
+氓
+忙
+莽
+猫
+茅
+锚
+毛
+铆
+冒
+帽
+貌
+贸
+么
+玫
+枚
+酶
+煤
+没
+眉
+媒
+膩
+膬
+膮
+膰
+膶
+膷
+膽
+膿
+臈
+臋
+臒
+墨
+谋
+艁
+艂
+艅
+艌
+艒
+艡
+艦
+艧
+艩
+拧
+牛
+奴
+偶
+沤
+啪
+葮
+葯
+葲
+螖
+伪
+位
+渭
+蠁
+袚
+袨
+邪
+胁
+谢
+芯
+褉
+褋
+褌
+褟
+峄�
+鈥�
+鈥�
+鈥�
+鈥�
+鈥�
+鈥�
+鈩�
+鈫�
+鈭�
+鈭�
+鈻�
+鈽�
+銆�
+銆�
+銆�
+銆�
+銆�
+銆�
+銆�
+銆�
+銆�
+銆�
+銆�
+銆�
+銆�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+菐
+菕
+臎
+菒
+矛
+菙
+霉
+菛
+菢
+菤
+菧
+銆�
+銆�
+銆�
+銆�
+鈥�
+{
+}
+\
+|
+@
+^
+~
+梅
+鈭�
+鈭�
+鈰�
+路
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+卤
+鈭�
+鈭�
+鈭�
+鈻�
+鈯�
+鈯�
+鈯�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈭�
+鈭�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+卢
+鈯�
+鈯�
+鈯�
+鈫�
+鈫�
+鈬�
+鈬�
+鈬�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈯�
+鈭�
+鈭�
+鈭�
+鈭�
+鈥�
+鈥�
+鈭�
+鈯�
+鈯�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+庐
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈩�
+惟
+鈩�
+鈩�
+鈱�
+鈩�
+鈪�
+鈲�
+鈲�
+垄
+鈧�
+拢
+楼
+锟�
+鈧�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+陋
+潞
+鈦�
+鹿
+鲁
+鈦�
+鈦�
+鈦�
+鈦�
+鈦�
+鈦�
+鈦�
+鈦�
+鈦�
+鈦�
+鈦�
+鈦�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈿�
+鈿�
+鈿�
+鉁�
+鉁�
+鉁�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+螒
+螔
+螕
+螘
+螙
+螚
+螛
+螜
+螝
+螞
+螠
+螡
+螢
+螣
+螤
+巍
+危
+韦
+违
+桅
+围
+唯
+尾
+纬
+未
+蔚
+味
+畏
+胃
+喂
+魏
+谓
+尉
+慰
+蟺
+蟻
+蟽
+蟿
+蠀
+蠂
+蠄
+蠅
+蠍
+蠎
+蠏
+蠒
+鈻�
+蠔
+习
+媳
+洗
+系
+蠞
+蠟
+蠠
+蠣
+稀
+息
+希
+悉
+膝
+夕
+惜
+熄
+烯
+溪
+汐
+犀
+檄
+袭
+席
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈩�
+鈩�
+鈩�
+鈩�
+鈩�
+鈩�
+鈩�
+鈩�
+鈱�
+鈱�
+鈱�
+鈱�
+鈳�
+陇
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈫�
+鈫�
+鈫�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鈶�
+鈶�
+鈶�
+鈶�
+鈶�
+鈶�
+鈶�
+鈶�
+鈶�
+鈶�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鈱�
+鈱�
+鈱�
+鈳�
+鈱�
+鈱�
+鈴�
+鈱�
+鈱�
+鈱�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈻�
+鈻�
+鈼�
+鈴�
+鈴�
+鈴�
+蓯
+蓱
+蓲
+蓳
+蓴
+蓵
+蓶
+蓷
+蓸
+蓹
+蓺
+蓻
+蓽
+蓾
+蔀
+蔁
+蔂
+伞
+散
+桑
+嗓
+丧
+搔
+骚
+扫
+嫂
+瑟
+色
+涩
+森
+僧
+莎
+砂
+杀
+刹
+沙
+纱
+傻
+啥
+煞
+筛
+晒
+珊
+苫
+杉
+山
+删
+煽
+蕗
+蕘
+蕚
+蕛
+蕜
+蕝
+蕟
+蕠
+蕡
+蕢
+蕣
+蕥
+蕦
+蕧
+蕩
+蕪
+蕫
+蕬
+蕭
+蕮
+蕯
+蕰
+蕱
+蕳
+蕵
+蕶
+蕷
+蕸
+蕼
+蕽
+蕿
+薀
+薁
+省
+盛
+剩
+胜
+圣
+师
+失
+狮
+施
+湿
+诗
+尸
+虱
+十
+石
+鈹�
+茙
+脙
+鈼�
+鈻�
+锝�
+饾憿
+銆�
+銆�
+锔�
+鈥�
+锕�
+饾湏
+鈥�
+鈭�
+茠
+啷�
+鉁�
+袝
+鈼�
+銆�
+饾挶
+饾渾
+鉄�
+锕�
+鈼�
+鈺�
+鞓�
+藗
+鈱�
+饾潕
+鈻�
+鈻�
+鈻�
+鈼�
+銆�
+鈻�
+鈻�
+饾挳
+鈥�
+鈧�
+饧�
+銆�
+猸�
+鈺�
+鉄�
+鞙�
+猬�
+岷�
+鈼�
+铮�
+鈻�
+涓�
+锔�
+鈼�
+鈥�
+饾湆
+鈪�
+鈻�
+鈦�
+锕�
+馃榿
+馃槀
+馃槂
+馃槃
+馃槄
+馃槅
+馃槈
+馃槉
+馃構
+馃槍
+馃槏
+馃槒
+馃槖
+馃槗
+馃様
+馃槚
+馃槝
+馃槡
+馃槣
+馃槤
+馃槥
+馃槧
+馃槨
+馃槩
+馃槪
+馃槫
+馃槬
+馃槰
+馃槱
+馃槳
+馃槴
+馃槶
+馃槹
+馃槺
+馃槻
+馃槼
+馃樀
+馃樂
+馃樃
+馃樄
+馃樅
+馃樆
+馃樇
+馃樈
+馃樉
+馃樋
+馃檧
+馃檯
+馃檰
+馃檱
+馃檲
+馃檳
+馃檴
+馃檵
+馃檶
+馃檷
+馃檸
+馃檹
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+馃殌
+馃殐
+馃殑
+馃殔
+馃殗
+馃殙
+馃殞
+馃殢
+馃殤
+馃殥
+馃殦
+馃殨
+馃殫
+馃殭
+馃殮
+馃殺
+馃殼
+馃殽
+馃毀
+馃毃
+馃毄
+馃毆
+馃毇
+馃毈
+馃毉
+馃毑
+馃毝
+馃毠
+馃毢
+馃毣
+馃毤
+馃毥
+馃毦
+馃泙
+鈸�
+馃叞
+馃叡
+馃吘
+馃吙
+馃啂
+馃啈
+馃啋
+馃啌
+馃啍
+馃啎
+馃問
+馃啑
+馃啒
+馃啓
+馃啔
+馃嚛馃嚜
+馃嚞馃嚙
+馃嚚馃嚦
+馃嚡馃嚨
+馃嚝馃嚪
+馃嚢馃嚪
+馃嚜馃嚫
+馃嚠馃嚬
+馃嚪馃嚭
+馃嚭馃嚫
+馃垇
+鈩�
+鈱�
+鈱�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈼�
+鈼�
+鈼�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈿�
+鈿�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+猡�
+猡�
+猬�
+猬�
+猬�
+猬�
+猸�
+銆�
+銆�
+銑�
+銑�
+馃��
+馃儚
+馃寑
+馃寔
+馃寕
+馃寖
+馃寗
+馃寘
+馃寙
+馃寚
+馃寛
+馃寜
+馃寠
+馃寢
+馃寣
+馃審
+馃寫
+馃寭
+馃寯
+馃寱
+馃寵
+馃寷
+馃専
+馃尃
+馃尠
+馃尡
+馃尨
+馃尩
+馃尫
+馃尭
+馃尮
+馃尯
+馃尰
+馃尲
+馃尳
+馃尵
+馃尶
+馃崁
+馃崄
+馃崅
+馃崈
+馃崉
+馃崊
+馃崋
+馃崌
+馃崍
+馃崏
+馃崐
+馃崒
+馃崓
+馃崕
+馃崗
+馃崙
+馃崚
+馃崜
+馃崝
+馃崟
+馃崠
+馃崡
+馃崢
+馃崣
+馃崥
+馃崨
+馃崪
+馃崫
+馃崬
+馃崯
+馃崰
+馃崱
+馃崲
+馃崳
+馃崵
+馃崶
+馃崷
+馃崸
+馃崹
+馃崺
+馃崻
+馃崼
+馃崿
+馃嵀
+馃嵁
+馃嵂
+馃嵃
+馃嵄
+馃嵅
+馃嵆
+馃嵈
+馃嵉
+馃嵍
+馃嵎
+馃嵏
+馃嵐
+馃嵑
+馃嵒
+馃巰
+馃巵
+馃巶
+馃巸
+馃巹
+馃巺
+馃巻
+馃巼
+馃巿
+馃帀
+馃帄
+馃帇
+馃帉
+馃帊
+馃帋
+馃帍
+馃帎
+馃帒
+馃帓
+馃帗
+馃帬
+馃帯
+馃帰
+馃帲
+馃帳
+馃帴
+馃帵
+馃帶
+馃帹
+馃帺
+馃帾
+馃帿
+馃幀
+馃幁
+馃幃
+馃幆
+馃幇
+馃幈
+馃幉
+馃幊
+馃幋
+馃幍
+馃幎
+馃幏
+馃幐
+馃幑
+馃幒
+馃幓
+馃幖
+馃幗
+馃幘
+馃幙
+馃弨
+馃弫
+馃弬
+馃弮
+馃弰
+馃弳
+馃張
+馃強
+馃彔
+馃彙
+馃彚
+馃彛
+馃彞
+馃彟
+馃彠
+馃彣
+馃彥
+馃彧
+馃彨
+馃彫
+馃彮
+馃彯
+馃彲
+馃彴
+馃悓
+馃悕
+馃悗
+馃悜
+馃悞
+馃悢
+馃悧
+馃悩
+馃悪
+馃悮
+馃悰
+馃悳
+馃悵
+馃悶
+馃悷
+馃悹
+馃悺
+馃悽
+馃悾
+馃悿
+馃惀
+馃惁
+馃惂
+馃惃
+馃惄
+馃惈
+馃惉
+馃惌
+馃惍
+馃惎
+馃惏
+馃惐
+馃惒
+馃惓
+馃惔
+馃惖
+馃惗
+馃惙
+馃惛
+馃惞
+馃惡
+馃惢
+馃惣
+馃惤
+馃惥
+馃憖
+馃憘
+馃憙
+馃憚
+馃憛
+馃憜
+馃憞
+馃憟
+馃憠
+馃憡
+馃憢
+馃憣
+馃憤
+馃憥
+馃憦
+馃憪
+馃憫
+馃憭
+馃憮
+馃憯
+馃憰
+馃憱
+馃憲
+馃憳
+馃憴
+馃憵
+馃憶
+馃憸
+馃憹
+馃憺
+馃憻
+馃憼
+馃憽
+馃憿
+馃懀
+馃懁
+馃懄
+馃懅
+馃懆
+馃懇
+馃應
+馃懌
+馃懏
+馃懐
+馃懓
+馃懕
+馃懖
+馃懗
+馃懘
+馃懙
+馃懚
+馃懛
+馃懜
+馃懝
+馃懞
+馃懟
+馃懠
+馃懡
+馃懢
+馃懣
+馃拃
+馃拋
+馃拏
+馃拑
+馃拕
+馃拝
+馃拞
+馃拠
+馃拡
+馃拤
+馃拪
+馃拫
+馃拰
+馃拲
+馃拵
+馃拸
+馃拹
+馃拺
+馃拻
+馃挀
+馃挃
+馃挄
+馃挅
+馃挆
+馃挊
+馃挋
+馃挌
+馃挍
+馃挏
+馃挐
+馃挒
+馃挓
+馃挔
+馃挕
+馃挗
+馃挘
+馃挙
+馃挜
+馃挦
+馃挧
+馃挩
+馃挬
+馃挭
+馃挮
+馃挰
+馃挳
+馃挴
+馃挵
+馃挷
+馃挸
+馃挻
+馃挼
+馃捀
+馃捁
+馃捄
+馃捇
+馃捈
+馃捊
+馃捑
+馃捒
+馃搥
+馃搧
+馃搨
+馃搩
+馃搫
+馃搮
+馃搯
+馃搰
+馃搱
+馃搲
+馃搳
+馃搵
+馃搶
+馃搷
+馃搸
+馃搹
+馃搻
+馃搼
+馃搾
+馃摀
+馃摂
+馃摃
+馃摉
+馃摋
+馃摌
+馃摍
+馃摎
+馃摏
+馃摐
+馃摑
+馃摓
+馃摕
+馃摖
+馃摗
+馃摙
+馃摚
+馃摛
+馃摜
+馃摝
+馃摟
+馃摠
+馃摡
+馃摢
+馃摣
+馃摦
+馃摪
+馃摫
+馃摬
+馃摮
+馃摯
+馃摱
+馃摲
+馃摴
+馃摵
+馃摶
+馃摷
+馃攦
+馃攰
+馃攱
+馃攲
+馃攳
+馃攷
+馃攺
+馃攼
+馃攽
+馃敀
+馃敁
+馃敂
+馃敄
+馃敆
+馃敇
+馃敊
+馃敋
+馃敍
+馃敎
+馃敐
+馃敒
+馃敓
+馃敔
+馃敗
+馃敘
+馃敚
+馃敜
+馃敟
+馃敠
+馃敡
+馃敤
+馃敥
+馃敧
+馃敨
+馃敭
+馃敮
+馃敯
+馃敱
+馃敳
+馃敵
+馃敶
+馃數
+馃敹
+馃敺
+馃敻
+馃敼
+馃敽
+馃敾
+馃敿
+馃斀
+馃晲
+馃晳
+馃晵
+馃晸
+馃晹
+馃晻
+馃晼
+馃晽
+馃晿
+馃暀
+馃暁
+馃暃
+馃椈
+馃椉
+馃椊
+馃椌
+馃椏
+馃榾
+馃槆
+馃槇
+馃槑
+馃槓
+馃槕
+馃槙
+馃槜
+馃槞
+馃槢
+馃槦
+馃槮
+馃槯
+馃槵
+馃槷
+馃槸
+馃槾
+馃樁
+馃殎
+馃殏
+馃殕
+馃殘
+馃殜
+馃殟
+馃殠
+馃殣
+馃殧
+馃殩
+馃殬
+馃殯
+馃殰
+馃殱
+馃殲
+馃殶
+馃殸
+馃殹
+馃殻
+馃殾
+馃毊
+馃毌
+馃毎
+馃毐
+馃毘
+馃毚
+馃毜
+馃毞
+馃毟
+馃毧
+馃泚
+馃泜
+馃泝
+馃泟
+馃泤
+馃實
+馃寧
+馃寪
+馃寬
+馃寲
+馃寳
+馃寴
+馃寶
+馃寽
+馃対
+馃尀
+馃尣
+馃尦
+馃崑
+馃崘
+馃嵓
+馃弴
+馃弶
+馃彜
+馃悁
+馃悂
+馃悅
+馃悆
+馃悇
+馃悈
+馃悊
+馃悋
+馃悎
+馃悏
+馃悐
+馃悑
+馃悘
+馃悙
+馃悡
+馃悤
+馃悥
+馃惇
+馃懃
+馃懍
+馃懎
+馃挱
+馃挾
+馃挿
+馃摤
+馃摥
+馃摨
+馃摰
+馃攢
+馃攣
+馃攤
+馃攧
+馃攨
+馃攩
+馃攪
+馃攭
+馃敃
+馃敩
+馃敪
+馃暅
+馃暆
+馃暈
+馃暉
+馃暊
+馃暋
+馃暍
+馃暎
+馃暏
+馃暐
+馃暒
+馃暓
diff --git a/src/main/resources/PP_OCRv5/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx b/src/main/resources/PP_OCRv5/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx
new file mode 100644
index 0000000..9429aea
--- /dev/null
+++ b/src/main/resources/PP_OCRv5/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx
Binary files differ
diff --git a/src/main/resources/PP_OCRv5/PP-OCRv5_server_rec_infer/PP-OCRv5_server_rec.onnx b/src/main/resources/PP_OCRv5/PP-OCRv5_server_rec_infer/PP-OCRv5_server_rec.onnx
new file mode 100644
index 0000000..3e6b41f
--- /dev/null
+++ b/src/main/resources/PP_OCRv5/PP-OCRv5_server_rec_infer/PP-OCRv5_server_rec.onnx
Binary files differ
diff --git a/src/main/resources/PP_OCRv5/PP-OCRv5_server_rec_infer/dict.txt b/src/main/resources/PP_OCRv5/PP-OCRv5_server_rec_infer/dict.txt
new file mode 100644
index 0000000..567898b
--- /dev/null
+++ b/src/main/resources/PP_OCRv5/PP-OCRv5_server_rec_infer/dict.txt
@@ -0,0 +1,18383 @@
+銆�
+涓�
+涔�
+浜�
+鍗�
+涓�
+鍘�
+涓�
+鍗�
+鍏�
+浜�
+鍏�
+鍎�
+鍖�
+鍑�
+涔�
+鍒�
+浜�
+鍒�
+鍔�
+涔�
+鍙�
+涓�
+骞�
+浜�
+浜�
+宸�
+鍦�
+澹�
+鎵�
+涓�
+瀵�
+澶�
+涓�
+涓�
+涓�
+涓�
+灏�
+鍙�
+灞�
+宸�
+鍗�
+涔�
+宸�
+浜�
+涓�
+澶�
+涔�
+涔�
+鍕�
+鍑�
+涓�
+鍙�
+骞�
+浜�
+闂�
+涓�
+涔�
+涔�
+灏�
+宸�
+宸�
+宸�
+寮�
+瀛�
+鍗�
+涔�
+濂�
+鍒�
+椋�
+涔�
+鍙�
+椹�
+涔�
+涓�
+鐜�
+寮�
+浜�
+澶�
+澶�
+鍏�
+鏃�
+浜�
+涓�
+涓�
+鎵�
+鑹�
+鏈�
+浜�
+鏀�
+鍘�
+涓�
+鐘�
+澶�
+鍖�
+鍘�
+姝�
+鍙�
+灏�
+鍖�
+杞�
+宸�
+鐗�
+灞�
+鎴�
+姣�
+浜�
+鍒�
+鐡�
+姝�
+灏�
+鏇�
+鏃�
+涓�
+璐�
+鍐�
+鍐�
+姘�
+瑙�
+鍗�
+鐗�
+鎵�
+姘�
+姣�
+澹�
+鍗�
+澶�
+闀�
+浠�
+浠�
+鐗�
+浠�
+鍖�
+浠�
+甯�
+浠�
+浠�
+鏂�
+鐖�
+鍙�
+浠�
+鐖�
+浠�
+浠�
+浠�
+鍑�
+鍒�
+涔�
+鍏�
+浠�
+鏈�
+姘�
+鍕�
+娆�
+椋�
+涓�
+鍖�
+涔�
+鍕�
+鍑�
+鍏�
+鏂�
+浜�
+鏂�
+鐏�
+涓�
+鏂�
+蹇�
+璁�
+璁�
+鎴�
+璁�
+鍐�
+璁�
+蹇�
+灏�
+寮�
+涓�
+宸�
+瀛�
+闃�
+鍔�
+浠�
+鍏�
+浜�
+閭�
+鍔�
+鍙�
+涔�
+骞�
+鐜�
+鍒�
+鏈�
+鏈�
+绀�
+鍑�
+鎵�
+宸�
+姝�
+鎵�
+鍗�
+鎵�
+鍔�
+鎵�
+鍘�
+鐢�
+涓�
+鑹�
+鍙�
+鑺�
+鏈�
+鏈�
+鍙�
+涓�
+宸�
+鍘�
+鐭�
+鍙�
+甯�
+澶�
+鎴�
+榫�
+骞�
+鐏�
+杞�
+涓�
+鍗�
+鍖�
+鍗�
+鍑�
+鍗�
+涓�
+鏃�
+甯�
+褰�
+鏃�
+鐩�
+涓�
+鍙�
+鐢�
+鐢�
+鍙�
+鐢�
+鍙�
+鐢�
+鐢�
+鍙�
+鍙�
+鍙�
+澶�
+鍏�
+鍙�
+鍙�
+鍙�
+鍙�
+鍙�
+鍙�
+鍙�
+鍐�
+鐨�
+鍑�
+鍥�
+鍥�
+鐢�
+鐭�
+澶�
+涔�
+绂�
+涓�
+浠�
+浠�
+浠�
+浠�
+浠�
+浠�
+鐧�
+浠�
+浠�
+鏂�
+鐡�
+涔�
+涓�
+浠�
+鐢�
+鐢�
+鍗�
+灏�
+涔�
+鍙�
+鍖�
+鍐�
+鍗�
+鐘�
+澶�
+澶�
+鍐�
+楦�
+鍔�
+鍖�
+楗�
+涓�
+甯�
+绔�
+鍐�
+鐜�
+闂�
+鍏�
+鍗�
+姹�
+姹�
+澶�
+姹�
+瀹�
+绌�
+瀹�
+璁�
+鍐�
+璁�
+绀�
+璁�
+璁�
+蹇�
+璁�
+璁�
+姘�
+鍙�
+灏�
+姘�
+寮�
+寮�
+鍑�
+杈�
+濂�
+濂�
+鍙�
+鍔�
+鐨�
+杈�
+瀛�
+鍙�
+鍦�
+瀵�
+鍙�
+鐭�
+绾�
+姣�
+骞�
+涓�
+閭�
+寮�
+杩�
+鍒�
+鎴�
+鍔�
+鎵�
+瀵�
+鍚�
+鎵�
+鑰�
+鎵�
+鑰�
+宸�
+鍦�
+鎵�
+鎵�
+鎵�
+鍦�
+鍦�
+鎵�
+鑰�
+鑺�
+鍏�
+鑺�
+浜�
+鑺�
+鏈�
+鏈�
+鏈�
+鏉�
+杩�
+鑷�
+鍚�
+鍐�
+鍗�
+瑗�
+鍘�
+鍘�
+鎴�
+鍦�
+鐧�
+鏈�
+瀛�
+鑰�
+椤�
+鍖�
+澶�
+澶�
+鐏�
+杈�
+鍒�
+姝�
+鎴�
+澶�
+澶�
+杞�
+閭�
+灏�
+鍒�
+杩�
+姣�
+鑷�
+姝�
+璐�
+甯�
+灏�
+灏�
+鍔�
+鍏�
+褰�
+鏃�
+鍚�
+鍚�
+鍚�
+铏�
+鏇�
+鍥�
+鍚�
+鍚�
+鍚�
+鍚�
+鍥�
+鍚�
+鍚�
+鍚�
+灞�
+灞�
+宀�
+甯�
+鍥�
+宀�
+鍒�
+鍒�
+缃�
+鑲�
+骞�
+鏈�
+鍏�
+涓�
+寤�
+鑸�
+绔�
+杩�
+涔�
+杩�
+浼�
+浼�
+涔�
+涔�
+浼�
+浼�
+浼�
+浼�
+鑷�
+浼�
+寤�
+浠�
+浠�
+浠�
+浼�
+浠�
+浼�
+浠�
+鍗�
+浠�
+浠�
+浼�
+浼�
+鑷�
+浼�
+琛�
+鍚�
+浼�
+鍚�
+琛�
+鑸�
+鍏�
+浼�
+鏉�
+鍚�
+鍏�
+浼�
+浼�
+鐖�
+浼�
+鍒�
+鑲�
+鑲�
+鏈�
+鏉�
+鍗�
+鏃�
+鏃�
+鏃�
+璐�
+鍖�
+鍚�
+鍚�
+澶�
+浜�
+鑹�
+澹�
+鍐�
+濡�
+鍐�
+搴�
+搴�
+浜�
+鍒�
+榻�
+浜�
+琛�
+娆�
+浜�
+鍐�
+浜�
+鍏�
+濡�
+闂�
+闂�
+闂�
+缇�
+骞�
+鍏�
+绫�
+鐏�
+宸�
+姹�
+姹�
+姹�
+姹�
+姹�
+姹�
+姹�
+蹇�
+鍏�
+瀹�
+瀹�
+瀹�
+瀛�
+瀹�
+璁�
+璁�
+鍐�
+璁�
+璁�
+璁�
+璁�
+璁�
+鍐�
+璁�
+璁�
+璁�
+璇�
+瀵�
+閭�
+杩�
+灏�
+瀵�
+寮�
+寮�
+瀛�
+闃�
+闃�
+鏀�
+闃�
+闃�
+闃�
+濂�
+濡�
+濡�
+濡�
+濂�
+濂�
+濡�
+鎴�
+缇�
+瑙�
+娆�
+涔�
+绾�
+椹�
+绾�
+椹�
+绾�
+绾�
+绾�
+椹�
+绾�
+宸�
+瀵�
+寮�
+楹�
+鐜�
+鐜�
+褰�
+杩�
+鎴�
+鍚�
+杩�
+杩�
+闊�
+杩�
+鎵�
+鎶�
+鍧�
+鎶�
+鍧�
+鎶�
+鎵�
+鎵�
+鎷�
+鎵�
+鎵�
+鍧�
+鎵�
+璧�
+鎶�
+璐�
+姹�
+鍧�
+鏀�
+璧�
+鎶�
+鎶�
+鎵�
+鎶�
+鎵�
+鎶�
+瀛�
+鍧�
+鍧�
+鎶�
+鎶�
+鎶�
+鍧�
+鍧�
+鎶�
+鍧�
+鎶�
+鎶�
+澹�
+蹇�
+鍧�
+鎵�
+澹�
+鎶�
+鎶�
+鎷�
+鍗�
+鎶�
+鍔�
+鑺�
+鑺�
+鑻�
+鑺�
+鑺�
+鑺�
+鑺�
+鑺�
+鑻�
+鑺�
+涓�
+鑺�
+鑺�
+鍔�
+鍏�
+鑺�
+鑻�
+鏉�
+鏉�
+鏉�
+鏉�
+鏉�
+鏉�
+鏉�
+鏉�
+宸�
+鏋�
+鏉�
+鏉�
+姹�
+鐢�
+鍖�
+鏇�
+鏉�
+鍚�
+璞�
+涓�
+閰�
+涓�
+鍖�
+杈�
+鍔�
+鍚�
+杩�
+灏�
+姝�
+鏉�
+杩�
+杞�
+姝�
+鍗�
+鍧�
+鑲�
+鏃�
+鐩�
+鍛�
+鏃�
+鍚�
+鍔�
+鍘�
+閲�
+鍛�
+鍚�
+鍚�
+鍛�
+鍥�
+鏃�
+鍥�
+鍛�
+鍚�
+瓒�
+閭�
+鐢�
+鍥�
+鍚�
+涓�
+鍛�
+鍛�
+鍚�
+鍚�
+鍚�
+鍛�
+鍚�
+鍚�
+鍛�
+鍚�
+鍚�
+閭�
+鍚�
+鍥�
+鍒�
+鍚�
+宀�
+宀�
+甯�
+璐�
+閽�
+閽�
+鐗�
+鍛�
+鎴�
+涔�
+鍒�
+绉�
+绉�
+绉�
+姣�
+鍏�
+浼�
+浣�
+浣�
+浣�
+浣�
+浣�
+浼�
+浣�
+浣�
+浼�
+浼�
+浣�
+浣�
+浣�
+浣�
+浣�
+浼�
+韬�
+鐨�
+浼�
+浣�
+鍥�
+杩�
+褰�
+褰�
+杩�
+浣�
+甯�
+鍧�
+璋�
+濡�
+鍚�
+閭�
+宀�
+鑲�
+鑲�
+鑲�
+鑲�
+鑲�
+榫�
+鐢�
+鍏�
+鐙�
+鐘�
+鐙�
+瑙�
+鍒�
+鏉�
+褰�
+鍗�
+鐏�
+宀�
+鍒�
+杩�
+楗�
+楗�
+绯�
+瑷�
+鍐�
+鐘�
+浜�
+鍐�
+搴�
+搴�
+搴�
+鐤�
+鍚�
+搴�
+杩�
+鍐�
+搴�
+搴�
+杈�
+寮�
+鍐�
+蹇�
+闂�
+闂�
+闂�
+闂�
+鍒�
+鍏�
+鐏�
+鐏�
+鐏�
+寮�
+姹�
+娌�
+娌�
+姹�
+娌�
+娌�
+姹�
+娌�
+娌�
+姹�
+娉�
+娌�
+娌�
+娌�
+娌�
+娌�
+娌�
+娌�
+鎬�
+蹇�
+蹇�
+蹇�
+瀹�
+瀹�
+瀹�
+鐗�
+绌�
+绌�
+鐏�
+鑹�
+璇�
+鍚�
+璇�
+琛�
+鍒�
+绀�
+绁�
+璇�
+璇�
+璇�
+缃�
+璇�
+璇�
+璇�
+鍚�
+鐏�
+鍗�
+灞�
+灞�
+灏�
+灏�
+杩�
+灞�
+鏀�
+寮�
+蹇�
+闄�
+闄�
+闃�
+闄�
+闃�
+闄�
+鍧�
+濡�
+濡�
+濡�
+濮�
+濡�
+濡�
+鍔�
+蹇�
+鍔�
+鐭�
+楦�
+绾�
+椹�
+绾�
+绾�
+绾�
+绾�
+椹�
+绾�
+绾�
+绾�
+绾�
+绾�
+椹�
+绾�
+濂�
+鐜�
+鐜�
+姝�
+闈�
+璐�
+鐜�
+鐜�
+琛�
+瑙�
+鎶�
+鍗�
+鍧�
+鍧�
+鎷�
+鎷�
+鎷�
+鍧�
+鎷�
+鍧�
+鎷�
+鍧�
+鎶�
+鎶�
+鎷�
+鎷�
+鑰�
+鎷�
+椤�
+鎷�
+鎷�
+鎷�
+鎶�
+鎷�
+鍔�
+鎶�
+鎷�
+鍨�
+鎷�
+鎷�
+骞�
+鎷�
+鎷�
+鎷�
+鎷�
+鎷�
+鍧�
+鎶�
+鎷�
+鎷�
+鎶�
+鎷�
+鎷�
+鍏�
+鍙�
+鑼�
+鑻�
+鏄�
+鑻�
+鑻�
+鑼�
+鑻�
+鑻�
+鑻�
+鑻�
+鑻�
+鑻�
+鑼�
+鐩�
+鑼�
+鑼�
+鑼�
+鑻�
+鑼�
+鏋�
+鏋�
+鏋�
+鏉�
+鏋�
+鏌�
+鏋�
+鏋�
+鏉�
+鏉�
+鏋�
+鏋�
+鏋�
+鏉�
+鏉�
+杩�
+鏋�
+涓�
+鎴�
+鐢�
+鍗�
+浜�
+鍒�
+鏋�
+闆�
+鍗�
+閮�
+鐭�
+鐭�
+鐮�
+鍘�
+濂�
+濂�
+濂�
+濂�
+鎬�
+娆�
+娈�
+鍨�
+濡�
+杞�
+椤�
+杞�
+鏂�
+杞�
+杞�
+鍒�
+闈�
+鍙�
+姝�
+鑲�
+榻�
+浜�
+鍗�
+铏�
+铏�
+鑲�
+璐�
+灏�
+鏃�
+鍏�
+鍛�
+鏋�
+鏄�
+鍥�
+鍝�
+鍜�
+鏄�
+鍛�
+鐣�
+鏄�
+鏄�
+鍜�
+鏄�
+杩�
+鍏�
+鍥�
+蹇�
+鍛�
+鍜�
+鍜�
+鍜�
+鍛�
+楦�
+鍜�
+鍛�
+鍜�
+鍜�
+宀�
+宀�
+甯�
+缃�
+甯�
+甯�
+宀�
+鍑�
+璐�
+璐�
+璐�
+璐�
+璐�
+璐�
+鍥�
+閽�
+鍒�
+鐭�
+杩�
+姘�
+鍨�
+鐗�
+鐗�
+涔�
+鍒�
+绉�
+鍜�
+瀛�
+濮�
+绉�
+浣�
+渚�
+宀�
+渚�
+浣�
+渚�
+渚�
+渚�
+鐗�
+渚�
+渚�
+渚�
+渚�
+鍑�
+渚�
+浣�
+璐�
+渚�
+渚�
+鍗�
+鐨�
+杩�
+璐�
+娆�
+寰�
+寰�
+鐖�
+褰�
+寰�
+鎵�
+鑸�
+閲�
+鍒�
+鍛�
+鑲�
+鏂�
+鐖�
+閲�
+瑙�
+鍙�
+涔�
+璐�
+蹇�
+璐�
+蹇�
+鑲�
+鑲�
+鑲�
+鑲�
+鑳�
+鏈�
+鑲�
+鑲�
+鑲�
+鑲�
+鏈�
+鑳�
+鍛�
+鏄�
+楸�
+鍏�
+鐙�
+蹇�
+鐙�
+鐙�
+澶�
+楗�
+楗�
+楗�
+鍙�
+浜�
+浜�
+搴�
+搴�
+澶�
+搴�
+搴�
+搴�
+鐤�
+鐤�
+鐤�
+鍓�
+鍗�
+閮�
+搴�
+搴�
+鍑�
+鐩�
+鏀�
+鍒�
+鑲�
+姘�
+闂�
+闂�
+閮�
+鍒�
+鍗�
+鍗�
+鐐�
+鐐�
+鐐�
+鐐�
+鐐�
+鐐�
+娌�
+娴�
+娉�
+娉�
+娌�
+娌�
+娌�
+娉�
+娌�
+娌�
+娉�
+娌�
+娉�
+娉�
+娉�
+娉�
+娉�
+娉�
+娉�
+娉�
+娌�
+娌�
+娉�
+娉�
+娉�
+娌�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+瀛�
+瀹�
+瀹�
+瀹�
+瀹�
+瀹�
+瀹�
+瀹�
+瀹�
+绌�
+甯�
+瀹�
+瀹�
+璇�
+閮�
+璇�
+鑲�
+鎴�
+璇�
+琛�
+琛�
+瑙�
+绁�
+璇�
+璇�
+璇�
+璇�
+璇�
+璇�
+寤�
+鑲�
+褰�
+闅�
+甯�
+灞�
+灞�
+灞�
+鍒�
+灞�
+寮�
+寮�
+寮�
+鎵�
+瀛�
+闄�
+闄�
+瀛�
+闄�
+闄�
+鍑�
+闄�
+濡�
+濮�
+濮�
+濮�
+濡�
+濮�
+濮�
+杩�
+椹�
+鍙�
+鍙�
+鑹�
+绾�
+缁�
+缁�
+缁�
+缁�
+椹�
+缁�
+椹�
+缁�
+椹�
+缁�
+椹�
+缁�
+缁�
+缁�
+璐�
+濂�
+璐�
+濂�
+鏄�
+甯�
+鐜�
+鐝�
+鐜�
+鐜�
+姣�
+鍨�
+鎷�
+鎸�
+灏�
+鎸�
+鎷�
+鎷�
+椤�
+鍨�
+鎸�
+鍩�
+鎸�
+鎸�
+鏀�
+璧�
+璧�
+鎸�
+鎷�
+鍝�
+鎸�
+鎷�
+鍨�
+鎷�
+鎷�
+鎸�
+鍨�
+鎸�
+鍨�
+鎸�
+鎸�
+鎷�
+鎸�
+鎸�
+鎸�
+鎸�
+鎷�
+鏌�
+鐢�
+鑽�
+鑼�
+闈�
+鑼�
+鑽�
+宸�
+甯�
+鑽�
+鑼�
+鑼�
+鑼�
+鑽�
+鑼�
+鑽�
+鑽�
+鑽�
+鑽�
+鏁�
+鑳�
+鑽�
+鑽�
+鍗�
+鑽�
+鏍�
+鏍�
+鏌�
+鏋�
+鏌�
+鏍�
+鐩�
+鏌�
+鏌�
+鏍�
+鏌�
+鏌�
+鏌�
+鏍�
+鏌�
+鏍�
+鍕�
+瑕�
+鏌�
+鍜�
+濞�
+姝�
+鐮�
+鐮�
+鍘�
+鍘�
+鐮�
+鐮�
+娉�
+鐮�
+鐮�
+闈�
+鑰�
+鑰�
+鐗�
+楦�
+娈�
+娈�
+杞�
+杞�
+楦�
+鐨�
+闊�
+鑳�
+鎴�
+鐐�
+铏�
+涓�
+瑙�
+绔�
+鐪�
+鍓�
+灏�
+鏄�
+鐩�
+鏄�
+鐩�
+鐪�
+鍝�
+鍝�
+鍝�
+鏄�
+鍐�
+鏄�
+鏄�
+鏄�
+鍜�
+鏄�
+鐣�
+瓒�
+鑳�
+璐�
+鐣�
+铏�
+铏�
+铓�
+鎬�
+铓�
+铏�
+鍝�
+鍜�
+楠�
+鍕�
+鍝�
+鍜�
+鍝�
+鍝�
+鍝�
+鍜�
+鍜�
+鍜�
+鍝�
+鍝�
+鐐�
+宄�
+缃�
+璐�
+璐�
+璐�
+楠�
+骞�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+鍗�
+缂�
+鎷�
+鐪�
+鐭�
+姣�
+姘�
+鎬�
+鐗�
+閫�
+閫�
+绉�
+棣�
+绉�
+绉�
+绉�
+閲�
+澶�
+绔�
+娈�
+渚�
+淇�
+璐�
+椤�
+淇�
+淇�
+淇�
+淇�
+淇�
+淇�
+渚�
+淇�
+淇�
+淇�
+淇�
+鐨�
+娉�
+楝�
+渚�
+绂�
+渚�
+杩�
+淇�
+鐩�
+寰�
+寰�
+琛�
+寰�
+寰�
+椤�
+鍙�
+鍓�
+閫�
+椋�
+鐩�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑴�
+鑳�
+鍕�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+璐�
+鎬�
+鎬�
+楗�
+楗�
+铓�
+楗�
+楗�
+宄�
+寮�
+灏�
+濂�
+鍝�
+浜�
+浜�
+搴�
+杩�
+搴�
+鐤�
+鐤�
+鐤�
+鐤�
+鍜�
+濮�
+浜�
+闊�
+甯�
+鏂�
+闂�
+闂�
+闂�
+闃�
+闃�
+宸�
+鍏�
+缇�
+濮�
+鍙�
+閫�
+绫�
+杩�
+绫�
+濞�
+鍓�
+棣�
+閫�
+鍏�
+鎬�
+鐐�
+鐐�
+鐑�
+鐐�
+鐐�
+鐑�
+鍓�
+娲�
+娲�
+娲�
+娲�
+鏌�
+娴�
+娴�
+娲�
+娴�
+娲�
+娲�
+娲�
+娲�
+鏌�
+娲�
+娴�
+娴�
+娲�
+娲�
+娴�
+娴�
+娲�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+涓�
+瑙�
+瀹�
+瀹�
+瀹�
+瀹�
+瀹�
+绐�
+绌�
+绐�
+瀹�
+璇�
+鍐�
+璇�
+璇�
+鎵�
+琚�
+绁�
+绁�
+绁�
+绁�
+璇�
+璇�
+璇�
+璇�
+璇�
+鍨�
+閫�
+鏃�
+灞�
+鏄�
+灞�
+灞�
+璐�
+闄�
+閫�
+鐪�
+瀛�
+闄�
+闄�
+闄�
+闄�
+濞�
+濮�
+濮�
+濮�
+濞�
+濮�
+濞�
+鎬�
+鏋�
+璐�
+鐩�
+鍕�
+鎬�
+鐧�
+铓�
+鏌�
+鍨�
+缁�
+缁�
+缁�
+缁�
+楠�
+缁�
+缁�
+缁�
+楠�
+缁�
+缁�
+缁�
+楠�
+缁�
+鑰�
+鑰�
+鑰�
+鑰�
+鑹�
+娉�
+绉�
+鐝�
+鐝�
+绱�
+鍖�
+铓�
+椤�
+鐩�
+鍖�
+鎹�
+鏍�
+鎹�
+鍩�
+鎹�
+鎸�
+杞�
+璧�
+璧�
+鐩�
+鎹�
+鎹�
+鎹�
+鍩�
+鎹�
+鎹�
+鎹�
+鎹�
+琚�
+鎹�
+閮�
+鍝�
+閫�
+鎹�
+鎸�
+鎹�
+鎸�
+鎸�
+鐑�
+鎭�
+鎹�
+澹�
+鎹�
+鍩�
+鎸�
+鑰�
+鑰�
+鑰�
+鑱�
+鎭�
+鑾�
+鑾�
+鑾�
+鑾�
+鑾�
+鑽�
+鑾�
+鏅�
+鎭�
+鑾�
+鑾�
+鐪�
+妗�
+姊�
+妗�
+妗�
+鏍�
+妗�
+妗�
+鏍�
+妗�
+妗�
+鏍�
+妗�
+鏍�
+妗�
+鏍�
+鏍�
+鏍�
+鏍�
+绱�
+鍝�
+閫�
+閫�
+鏍�
+璐�
+閰�
+閰�
+缈�
+杈�
+鍞�
+澶�
+鐮�
+鐮�
+鐮�
+纭�
+鐮�
+鍘�
+濂�
+閫�
+鐑�
+娈�
+娈�
+椤�
+杞�
+杈�
+椤�
+姣�
+鑷�
+鏌�
+妗�
+铏�
+鐩�
+绱�
+鍏�
+閫�
+鏅�
+鐪�
+鏅�
+鍝�
+鍞�
+楦�
+鏅�
+鍝�
+鏅�
+鍓�
+鏅�
+铓�
+鐣�
+铓�
+铓�
+铓�
+铓�
+鍝�
+鍝�
+鍦�
+鍝�
+鍝�
+鎭�
+楦�
+鍞�
+鍞�
+鍝�
+鍞�
+鍟�
+鍞�
+鍞�
+缃�
+宄�
+宄�
+宄�
+鍦�
+宄�
+璐�
+璐�
+璧�
+璧�
+閽�
+閽�
+閽�
+閽�
+閾�
+閾�
+閾�
+缂�
+姘�
+姘�
+鐗�
+鐗�
+閫�
+涔�
+鏁�
+绉�
+绉�
+绉�
+绉�
+绉�
+绉�
+绉�
+閫�
+绗�
+绗�
+绗�
+鍊�
+鍊�
+鍊�
+鍊�
+淇�
+鍊�
+鍊�
+鍊�
+淇�
+鍊�
+鍊�
+璧�
+淇�
+鍊�
+鍊�
+鍋�
+鑷�
+灏�
+韬�
+鎭�
+鍊�
+寰�
+寰�
+娈�
+鑸�
+鑸�
+鑸�
+鑸�
+閫�
+鎷�
+鑰�
+鐖�
+鑸�
+鐖�
+璞�
+璞�
+棰�
+棰�
+缈�
+鑳�
+鑴�
+鑴�
+鑳�
+鑳�
+鑴�
+鑴�
+鑳�
+鑴�
+鑴�
+閫�
+鐙�
+鐙�
+鍗�
+閫�
+楦�
+鐣�
+楦�
+鐨�
+楗�
+棣�
+鍑�
+鍑�
+鎭�
+妗�
+娴�
+琛�
+琛�
+楂�
+閮�
+甯�
+鍑�
+搴�
+鐥�
+鐥�
+鐤�
+鏂�
+鐤�
+鐤�
+鐤�
+鑴�
+鏁�
+绂�
+绱�
+鍞�
+鐡�
+璧�
+鍑�
+绔�
+鍓�
+绔�
+閮�
+鏃�
+鏃�
+鐣�
+闃�
+缇�
+缇�
+鐡�
+鎷�
+绮�
+鏂�
+鐩�
+鍏�
+鐑�
+鐑�
+鐑�
+鐑�
+鐑�
+鐑�
+鐑�
+閫�
+娑�
+娴�
+娑�
+娴�
+閰�
+娑�
+娑�
+娑�
+娴�
+娴�
+娑�
+娴�
+娴�
+娑�
+娑�
+娴�
+娑�
+娑�
+娑�
+娴�
+娴�
+娑�
+鐑�
+娑�
+娑�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+瀹�
+瀹�
+瀹�
+瀹�
+瀹�
+瀹�
+绐�
+绐�
+瀹�
+瀹�
+妗�
+璇�
+鏈�
+璇�
+璇�
+璇�
+鎵�
+璇�
+琚�
+琚�
+琚�
+琚�
+绁�
+璇�
+鍐�
+璋�
+璋�
+鍐�
+璋�
+璋�
+璋�
+璋�
+鍓�
+鎭�
+灞�
+鍓�
+灞�
+寮�
+闄�
+绁�
+闄�
+闄�
+闄�
+濞�
+濞�
+鎭�
+濞�
+濞�
+閫�
+鑳�
+闅�
+棰�
+妗�
+缁�
+缁�
+楠�
+缁�
+楠�
+鐞�
+鐞�
+鐞�
+鐞�
+鐞�
+鎹�
+鍫�
+鎺�
+鎻�
+鍩�
+鎹�
+鎺�
+鎹�
+鎺�
+鐒�
+鎺�
+鎹�
+璧�
+鍫�
+鎺�
+鍩�
+鎺�
+鎺�
+鎹�
+鏁�
+鎺�
+鎺�
+鎺�
+鎺�
+鍩�
+鎺�
+鎺�
+鎺�
+鎺�
+鎹�
+鎺�
+鎺�
+鑱�
+鍩�
+鑱�
+鍕�
+鑱�
+濞�
+钁�
+鑿�
+鍕�
+榛�
+鑿�
+钀�
+钀�
+鑿�
+钀�
+鑿�
+钀�
+鑿�
+鑿�
+钀�
+鑿�
+钀�
+钀�
+涔�
+钀�
+钀�
+鑿�
+姊�
+褰�
+姊�
+濠�
+姊�
+姊�
+姊�
+姊�
+妫�
+姊�
+姊�
+妗�
+姊�
+鏁�
+鏇�
+鍓�
+绁�
+閰�
+閰�
+鍘�
+鎴�
+纭�
+纭�
+濂�
+鐩�
+鐖�
+鑱�
+琚�
+鐩�
+鍖�
+闆�
+杈�
+杈�
+棰�
+铏�
+褰�
+闆�
+鍫�
+甯�
+鐪�
+鍖�
+鏅�
+鐫�
+鐪�
+鐪�
+鎮�
+閲�
+鍟�
+鍟�
+鏇�
+鏅�
+鏅�
+鍟�
+鍟�
+璺�
+瓒�
+鍟�
+璺�
+鐣�
+铓�
+铔�
+铔�
+鍞�
+绱�
+閯�
+鍞�
+鎮�
+鍟�
+鍞�
+鍞�
+鍟�
+鍟�
+鍟�
+宕�
+宕�
+宕�
+閫�
+宕�
+甯�
+宕�
+宕�
+宕�
+濠�
+鍦�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+鐭�
+鐢�
+绉�
+姊�
+鐘�
+绉�
+绉�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+鏁�
+鍋�
+琚�
+鎮�
+鍋�
+鍋�
+鍋�
+鍋�
+鎮�
+鍞�
+鍋�
+鍋�
+韬�
+鍏�
+鍋�
+琛�
+寰�
+寰�
+寰�
+琛�
+鐩�
+鑸�
+鑸�
+鑸�
+鏂�
+鐩�
+楦�
+鏁�
+鎮�
+娆�
+褰�
+棰�
+鑴�
+鑴�
+鑴�
+璞�
+鑴�
+鑴�
+璞�
+澶�
+閫�
+鐚�
+鐚�
+鐚�
+鐚�
+鍑�
+鐚�
+鐚�
+绁�
+棣�
+棣�
+鍑�
+鍑�
+姣�
+鐑�
+搴�
+楹�
+搴�
+鐥�
+鐥�
+鐥�
+寤�
+搴�
+搴�
+楣�
+鐩�
+绔�
+绔�
+鍟�
+鏃�
+鏃�
+鏈�
+鐜�
+闃�
+闃�
+鐫�
+缇�
+鐩�
+鐪�
+绮�
+绮�
+绮�
+鏂�
+鍓�
+鍏�
+鐒�
+鐒�
+娓�
+娣�
+楦�
+娣�
+娑�
+娣�
+娓�
+娓�
+娣�
+娣�
+娣�
+娣�
+娣�
+娓�
+娣�
+娓�
+娣�
+娣�
+娑�
+娣�
+娣�
+娣�
+娣�
+娑�
+娑�
+濠�
+姊�
+娓�
+鎯�
+鎯�
+鎯�
+鎮�
+鎯�
+鎯�
+鎯�
+鎯�
+鎯�
+鎮�
+鎯�
+鎯�
+鎯�
+瀵�
+瀵�
+瀵�
+瀵�
+瀹�
+绐�
+绐�
+瀵�
+璋�
+璋�
+璋�
+璋�
+琚�
+绁�
+绁�
+璋�
+璋�
+璋�
+閫�
+鏁�
+灏�
+灞�
+寮�
+闅�
+鍫�
+闅�
+铔�
+闅�
+闅�
+闅�
+濠�
+濠�
+濠�
+棰�
+棰�
+缁�
+缁�
+缁�
+楠�
+缁�
+缁�
+缁�
+缁�
+缁�
+缁�
+缁�
+缁�
+缁�
+缂�
+宸�
+鐞�
+鐞�
+鐞�
+鐞�
+鏂�
+鏇�
+鎻�
+娆�
+鍫�
+濉�
+鎼�
+鍫�
+鎻�
+瓒�
+瓒�
+瓒�
+瓒�
+鎻�
+鍫�
+鎻�
+鍗�
+鎻�
+鍠�
+褰�
+鎻�
+鎻�
+鎻�
+鎼�
+鐓�
+鎻�
+鎼�
+瑁�
+鎼�
+鎼�
+鎼�
+鎼�
+澹�
+鎻�
+鎼�
+鎻�
+鏂�
+鏈�
+娆�
+鑱�
+钁�
+鏁�
+鎯�
+钁�
+鍕�
+钁�
+钁�
+钁�
+鏁�
+钁�
+钂�
+钂�
+钀�
+闊�
+鏈�
+杈�
+钁�
+妫�
+妫�
+妫�
+妞�
+妞�
+妫�
+鐒�
+妞�
+妞�
+妫�
+妫�
+妞�
+妫�
+妫�
+妫�
+妫�
+姒�
+妞�
+鎯�
+鎯�
+閫�
+绮�
+妫�
+閰�
+閰�
+鍘�
+鍘�
+纭�
+纭�
+纭�
+纭�
+闆�
+娈�
+瑁�
+闆�
+棰�
+闆�
+鏆�
+闆�
+缈�
+杈�
+鎮�
+绱�
+鍑�
+杈�
+鏁�
+妫�
+璧�
+鎺�
+鏅�
+鐫�
+鏆�
+鏈�
+鏅�
+閲�
+榧�
+鍠�
+鍠�
+鏅�
+鍠�
+閬�
+鍠�
+閬�
+鏅�
+鏅�
+鐣�
+璺�
+璺�
+璺�
+璺�
+璺�
+閬�
+铔�
+铔�
+铚�
+铚�
+铔�
+鍠�
+楣�
+鍠�
+鍠�
+鍠�
+鍠�
+鍟�
+鍠�
+宓�
+骞�
+甯�
+璧�
+璧�
+璧�
+璧�
+璧�
+榛�
+閾�
+閾�
+閾�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+鐢�
+鎺�
+鐭�
+鏅�
+姘�
+姣�
+姘�
+楣�
+鍓�
+绋�
+绋�
+绋�
+绋�
+绛�
+绛�
+绛�
+绛�
+绛�
+绛�
+绛�
+绛�
+绛�
+绛�
+鍌�
+鍌�
+鐗�
+鍫�
+闆�
+鐒�
+鍌�
+鍌�
+鐨�
+鐨�
+绮�
+濂�
+琛�
+鎯�
+寰�
+寰�
+鑹�
+鑸�
+閫�
+鐣�
+閲�
+绂�
+鑵�
+鑴�
+鑵�
+鑵�
+鑵�
+椴�
+鐚�
+鐚�
+鐚�
+鐚�
+鎯�
+鐒�
+棣�
+棣�
+瑁�
+铔�
+灏�
+鏁�
+鏂�
+鐥�
+鐥�
+鐥�
+鐥�
+绔�
+绔�
+闃�
+鍠�
+缈�
+缇�
+鏅�
+绮�
+灏�
+濂�
+閬�
+閬�
+鏇�
+鐒�
+娓�
+婊�
+婀�
+婀�
+娓�
+娓�
+娓�
+婀�
+娓�
+娓�
+婧�
+婧�
+婊�
+婀�
+娓�
+婀�
+娓�
+娓�
+婊�
+娓�
+婧�
+鎰�
+鎱�
+鎯�
+鎰�
+鎰�
+鎯�
+鎰�
+鎰�
+鎱�
+鍓�
+瀵�
+瀵�
+瀵�
+绐�
+绐�
+绐�
+绐�
+绐�
+閬�
+闆�
+瑁�
+瑁�
+瑁�
+绂�
+绂�
+璋�
+璋�
+璋�
+璋�
+鐘�
+灞�
+灞�
+寮�
+绮�
+鐤�
+闅�
+闅�
+闅�
+濯�
+绲�
+瀚�
+濯�
+濠�
+鐧�
+缂�
+缂�
+缂�
+缂�
+缂�
+缂�
+缂�
+楠�
+缂�
+楠�
+缂�
+鐟�
+楣�
+鐟�
+鐟�
+鐟�
+榄�
+鑲�
+鎽�
+鎽�
+濉�
+鎼�
+濉�
+榧�
+鎽�
+鎼�
+鎼�
+鎽�
+鎼�
+濉�
+鎽�
+鑱�
+鏂�
+钂�
+鍕�
+闈�
+闈�
+楣�
+钃�
+澧�
+骞�
+钃�
+钃�
+钂�
+钃�
+钂�
+钂�
+鐚�
+妞�
+绂�
+妤�
+妤�
+姒�
+鎯�
+妲�
+姒�
+妤�
+姒�
+璧�
+閰�
+閰�
+鎰�
+纰�
+纰�
+纰�
+纰�
+纰�
+纰�
+纰�
+灏�
+闆�
+闆�
+闆�
+闆�
+杈�
+杈�
+杈�
+鐫�
+棰�
+榫�
+閴�
+鐫�
+鐫�
+鐫�
+鐬�
+鐫�
+鐫�
+鐫�
+鍡�
+閯�
+鍡�
+鎰�
+鏆�
+鐩�
+姝�
+鏆�
+鏆�
+鐓�
+鐣�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+閬�
+铚�
+铚�
+铔�
+铚�
+铚�
+鍡�
+鍡�
+鍡�
+缃�
+缃�
+缃�
+缃�
+铚�
+骞�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+鐭�
+杈�
+绋�
+绋�
+棰�
+鎰�
+绛�
+绛�
+绠�
+绛�
+姣�
+鑸�
+榧�
+鍌�
+鍌�
+鍍�
+韬�
+榄�
+琛�
+寰�
+鎰�
+閬�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+楣�
+鑵�
+鑵�
+椴�
+鐚�
+棰�
+瑙�
+瑙�
+鐓�
+闆�
+棣�
+棣�
+閰�
+绂�
+鐥�
+寤�
+鐥�
+鐥�
+寤�
+闈�
+鏂�
+闊�
+鎰�
+瑾�
+绮�
+鏁�
+鐓�
+濉�
+鎱�
+鐓�
+鐓�
+婊�
+婕�
+婊�
+婧�
+婊�
+婊�
+婊�
+婧�
+婧�
+婕�
+婊�
+婧�
+婧�
+婊�
+婧�
+婧�
+绮�
+婊�
+鎱�
+瑾�
+濉�
+瀵�
+绐�
+绐�
+瀵�
+璋�
+瑜�
+瑁�
+绂�
+璋�
+缇�
+娈�
+杈�
+闅�
+濯�
+瀚�
+瀚�
+瀚�
+鍙�
+缂�
+缂�
+缂�
+缂�
+鍓�
+闈�
+纰�
+鐠�
+璧�
+鐔�
+澧�
+澧�
+鍢�
+鎽�
+璧�
+鎴�
+瑾�
+澧�
+鎽�
+鎽�
+鎾�
+鑱�
+鎱�
+鏆�
+鎽�
+钄�
+钄�
+钄�
+钄�
+钄�
+钄�
+鐔�
+钄�
+鍏�
+妯�
+妲�
+姒�
+姒�
+姒�
+姒�
+姝�
+閬�
+閰�
+閰�
+閰�
+閰�
+纰�
+纰�
+纰�
+纾�
+鎰�
+闇�
+杈�
+杈�
+闆�
+瑁�
+棰�
+鐬�
+澧�
+鍡�
+韪�
+铚�
+铚�
+铦�
+铚�
+铦�
+鍢�
+鍢�
+璧�
+閿�
+閿�
+闀�
+鑸�
+鑸�
+绋�
+鐔�
+绠�
+绠�
+绠�
+绠�
+绠�
+鑸�
+鍍�
+鍍�
+榧�
+榄�
+榄�
+璨�
+鑶�
+鑶�
+鑶�
+椴�
+鐤�
+瀛�
+棣�
+瑁�
+鏁�
+璞�
+鑶�
+閬�
+鑵�
+鐦�
+鐦�
+鐦�
+杈�
+褰�
+绔�
+绔�
+鏃�
+绮�
+绮�
+姝�
+寮�
+鐔�
+鐔�
+鐓�
+娼�
+婕�
+婕�
+婕�
+婕�
+婊�
+婕�
+婕�
+婕�
+鎱�
+鎱�
+瀵�
+璧�
+瀵�
+瀵�
+铚�
+瀵�
+璋�
+鑲�
+瑜�
+瑜�
+璋�
+闅�
+瀚�
+缈�
+鐔�
+鍑�
+楠�
+缂�
+鎱�
+鎾�
+鎾�
+鎾�
+鎾�
+瓒�
+瓒�
+鎾�
+鎾�
+鎾�
+鎾�
+鎿�
+澧�
+鎾�
+鎾�
+澧�
+鎾�
+鑱�
+闉�
+闉�
+钑�
+钑�
+钄�
+钑�
+妯�
+妲�
+妯�
+姗�
+妯�
+姗�
+鏁�
+璞�
+椋�
+閱�
+閱�
+閱�
+纾�
+纾�
+纾�
+纰�
+闇�
+闇�
+闇�
+鐬�
+棰�
+鏆�
+鐬�
+鍢�
+鍢�
+鍢�
+鍢�
+褰�
+韪�
+韪�
+韪�
+韪�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+鍢�
+鍢�
+骞�
+澧�
+闀�
+闀�
+闀�
+闈�
+绋�
+绋�
+榛�
+绋�
+绋�
+绠�
+绡�
+绠�
+绡�
+鍍�
+韬�
+鍍�
+寰�
+鑹�
+鑶�
+鑶�
+椴�
+椴�
+鐔�
+鎽�
+瑜�
+鐦�
+鐦�
+鐦�
+鍑�
+棰�
+姣�
+绯�
+閬�
+鎲�
+娼�
+婢�
+娼�
+娼�
+椴�
+婢�
+娼�
+婢�
+婢�
+婢�
+鎳�
+鎲�
+鎳�
+鎲�
+棰�
+缈�
+瑜�
+璋�
+楣�
+鎲�
+鎱�
+鍔�
+灞�
+璞�
+缂�
+鎾�
+鎿�
+鎿�
+鎿�
+鐕�
+钑�
+钖�
+钖�
+钖�
+鎿�
+钖�
+钖�
+棰�
+缈�
+鍣�
+姗�
+姗�
+姗�
+鏁�
+铻�
+鐡�
+閱�
+闇�
+闇�
+杈�
+鍐�
+椁�
+鍢�
+韪�
+韫�
+韫�
+锜�
+铻�
+鍣�
+鍣�
+楣�
+璧�
+榛�
+榛�
+闀�
+璧�
+绌�
+绡�
+绡�
+绡�
+绡�
+鍎�
+閭�
+琛�
+鑶�
+闆�
+椴�
+纾�
+鐦�
+鐦�
+鍑�
+杈�
+杈�
+绯�
+绯�
+绯�
+鐕�
+婵�
+婢�
+婵�
+鎳�
+鎲�
+鎳�
+绐�
+澹�
+閬�
+缂�
+缂�
+鎴�
+鎿�
+钘�
+闉�
+钘�
+钘�
+妾�
+妾�
+妾�
+绀�
+纾�
+闇�
+闇�
+鐬�
+鐬�
+鐬�
+鐬�
+鐬�
+鐬�
+鏇�
+韫�
+韫�
+铻�
+锜�
+锜�
+鍤�
+璧�
+绌�
+榄�
+绨�
+绨�
+绻�
+寰�
+鐖�
+鏈�
+鑷�
+槌�
+鐧�
+杈�
+璧�
+绯�
+绯�
+鐕�
+鎳�
+璞�
+鑷�
+鑷�
+缈�
+楠�
+钘�
+闉�
+钘�
+瑕�
+鐬�
+韫�
+鍤�
+闀�
+缈�
+槌�
+楣�
+鐎�
+瑗�
+鐠�
+鎴�
+瀛�
+璀�
+铇�
+钘�
+鏀�
+鏇�
+韫�
+韫�
+韫�
+宸�
+绨�
+绨�
+锜�
+棰�
+闈�
+鐧�
+鐡�
+缇�
+槌�
+鐖�
+鐤�
+楝�
+澹�
+棣�
+鑰�
+韬�
+锠�
+鍤�
+鍤�
+宸�
+绫�
+槌�
+榄�
+绯�
+鐏�
+璀�
+锠�
+闇�
+闇�
+闇�
+韬�
+榛�
+楂�
+璧�
+鍥�
+闀�
+鐡�
+缃�
+鐭�
+涔�
+涔�
+鍏�
+寮�
+瀛�
+瀛�
+骞�
+浜�
+闊�
+寤�
+涓�
+鍗�
+浠�
+鍘�
+浠�
+浠�
+浠�
+鍏�
+鍒�
+鐖�
+鍗�
+闂�
+璁�
+灏�
+澶�
+鐖�
+姣�
+閭�
+閭�
+鑹�
+鑹�
+鏈�
+鍙�
+鍖�
+涓�
+鍖�
+鍔�
+鍗�
+鍙�
+鍙�
+浠�
+浠�
+浠�
+浠�
+浠�
+浠�
+鍗�
+姘�
+鐘�
+鍒�
+閭�
+閭�
+姹�
+璁�
+璁�
+璁�
+璁�
+灏�
+闃�
+灏�
+寮�
+椹�
+鍖�
+鑰�
+鐜�
+鐜�
+閭�
+鍦�
+鍦�
+鍦�
+鎵�
+鍦�
+鍦�
+鍦�
+鎵�
+鍦�
+鍦�
+鑺�
+鑺�
+鑺�
+鑺�
+鑺�
+鑺�
+鑺�
+浜�
+鍘�
+澶�
+鎴�
+灏�
+涔�
+鏃�
+鏇�
+宀�
+灞�
+鍑�
+鍥�
+閽�
+缂�
+姘�
+姘�
+鐗�
+浼�
+浼�
+浼�
+浣�
+浠�
+浼�
+浼�
+浼�
+浼�
+鍥�
+姹�
+鍒�
+澶�
+鏃�
+鍒�
+鐘�
+鐘�
+鑸�
+鍑�
+閭�
+楗�
+姹�
+姹�
+姹�
+姹�
+姹�
+姹�
+蹇�
+蹇�
+璁�
+璁�
+绁�
+璁�
+鑱�
+鑹�
+鍘�
+闃�
+闃�
+闃�
+涓�
+濡�
+鐗�
+绾�
+绾�
+绾�
+绾�
+鐜�
+鐜�
+鎶�
+鎶�
+鍦�
+鍧�
+鍧�
+鍧�
+鎶�
+鎶�
+悃�
+鑺�
+閭�
+鑺�
+鑺�
+鑻�
+鑻�
+鑺�
+鑺�
+鑻�
+鑺�
+鑻�
+鑻�
+鑺�
+鑺�
+鑺�
+鑺�
+鑻�
+鑻�
+鑻�
+鏉�
+鏉�
+鏉�
+鏉�
+蹇�
+瀛�
+閭�
+閭�
+鐭�
+濂�
+璞�
+蹇�
+娆�
+杞�
+杩�
+閭�
+蹇�
+鍗�
+閭�
+鏃�
+鍛�
+鍛�
+鍛�
+鍛�
+鍛�
+鍛�
+鏃�
+鍚�
+鐢�
+铏�
+鍛�
+鍚�
+鍚�
+鍚�
+甯�
+宀�
+宀�
+宀�
+宀�
+宀�
+鍏�
+鍥�
+鍥�
+閽�
+閽�
+閽�
+杩�
+姘�
+姘�
+鐗�
+浣�
+閭�
+鏀�
+浣�
+浣�
+浣�
+浣�
+浼�
+褰�
+浣�
+浣�
+瀛�
+璞�
+鍧�
+鑲�
+閭�
+濂�
+鍔�
+鐙�
+鐙�
+楦�
+閭�
+楗�
+楗�
+楗�
+楗�
+楗�
+浜�
+搴�
+搴�
+鐤�
+鐤�
+鑲�
+闂�
+闂�
+闂�
+缇�
+鐐�
+娌�
+娌�
+娌�
+娌�
+娌�
+娌�
+娌�
+姹�
+姹�
+娌�
+姹�
+娌�
+姹�
+姹�
+娌�
+娌�
+娉�
+鎬�
+鎬�
+蹇�
+蹇�
+蹇�
+鎬�
+蹇�
+蹇�
+鎬�
+蹇�
+蹇�
+璇�
+璇�
+璇�
+璇�
+璇�
+璇�
+璇�
+瀛�
+闄�
+闄�
+闄�
+闄�
+濡�
+濡�
+濡�
+濡�
+濡�
+濡�
+濡�
+濡�
+濮�
+濡�
+閭�
+鍔�
+鍒�
+鐢�
+閭�
+绾�
+绾�
+绾�
+绾�
+绾�
+鐜�
+鐜�
+鐜�
+鐜�
+鐜�
+鐜�
+鐜�
+鐩�
+蹇�
+鍖�
+鍧�
+鎶�
+鎷�
+鍧�
+鎷�
+鍨�
+鎶�
+鍔�
+鎷�
+鎷�
+鍧�
+鍧�
+悃�
+鍧�
+鍧�
+鎶�
+鍧�
+鑰�
+鑻�
+鑻�
+鑻�
+鑼�
+鑻�
+鑻�
+鑻�
+鑻�
+鑻�
+鑼�
+鑻�
+鑻�
+鑼�
+鑼�
+鑼�
+鑼�
+鑼�
+鑼�
+鑼�
+鑻�
+鏋�
+鏋�
+鏉�
+鏉�
+鏋�
+鏉�
+鏋�
+鏋�
+鏋�
+鏉�
+鏉�
+鏉�
+鐭�
+鐮�
+鍒�
+濂�
+鐡�
+娈�
+閮�
+杞�
+閮�
+楦�
+鐩�
+鏄�
+鏄�
+鏉�
+鏄�
+鍜�
+鍛�
+鏄�
+鏄�
+鏃�
+鏄�
+鐐�
+鍜�
+鐣�
+铏�
+鍜�
+鍛�
+榛�
+鍛�
+鍛�
+鍜�
+鍜�
+鍜�
+鍛�
+鍛�
+鍛�
+鍜�
+宀�
+宀�
+宀�
+宀�
+甯�
+宀�
+宄�
+鍒�
+杩�
+宀�
+鍓�
+甯�
+宄�
+娌�
+鍥�
+缃�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閭�
+杩�
+鐗�
+绔�
+杩�
+浣�
+浣�
+浣�
+渚�
+渚�
+鑷�
+宀�
+渚�
+渚�
+渚�
+渚�
+浣�
+浣�
+渚�
+浣�
+浣�
+渚�
+甯�
+闃�
+渚�
+寰�
+鍒�
+閮�
+鎬�
+绫�
+鐡�
+鎴�
+鑲�
+鋸�
+鑲�
+鑲�
+鑲�
+鍓�
+杩�
+閮�
+鐙�
+鐙�
+鐙�
+鐙�
+鍜�
+鐐�
+鏋�
+楗�
+楗�
+鍐�
+鍐�
+搴�
+鐤�
+鐤�
+鐤�
+鍏�
+濡�
+鍔�
+鐐�
+瓞壖
+鐐�
+鐐�
+鐐�
+鐐�
+娉�
+娌�
+娉�
+娉�
+娉�
+娉�
+娉�
+娉�
+娉�
+娉�
+娉�
+娉�
+娌�
+娉�
+娉�
+娉�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+悚�
+鎬�
+鎬�
+鎬�
+瀹�
+绌�
+瀹�
+璇�
+璇�
+璇�
+璇�
+鎴�
+璇�
+鎴�
+閮�
+琛�
+绁�
+绁�
+绁�
+绁�
+璇�
+璇�
+璇�
+璇�
+璇�
+璇�
+璇�
+璇�
+璇�
+鎴�
+瀛�
+浜�
+闄�
+濡�
+濡�
+濮�
+甯�
+寮�
+瀛�
+椹�
+铏�
+杩�
+杩�
+缁�
+缁�
+缁�
+椹�
+椹�
+缁�
+缁�
+椹�
+楠�
+鐢�
+鐝�
+鐝�
+鐝�
+鐝�
+鐜�
+鐝�
+椤�
+鐝�
+鐝�
+鎷�
+鍨�
+鎸�
+鍨�
+鎸�
+鍨�
+璧�
+璐�
+鍨�
+鍨�
+閮�
+鍨�
+鍨�
+鎸�
+鍨�
+鑼�
+鑽�
+鑽�
+璐�
+鑽�
+鑾�
+鑼�
+鑼�
+鑼�
+鑾�
+鑽�
+鑼�
+鑽�
+鑽�
+鑽�
+鑽�
+鑽�
+鑼�
+鑽�
+鑼�
+鑼�
+鍨�
+鑽�
+鑽�
+鑽�
+鑽�
+鍓�
+鑽�
+鑼�
+鑽�
+鑽�
+鏌�
+鏍�
+鏌�
+鏌�
+鏍�
+鏌�
+鏋�
+鏍�
+鏌�
+鏋�
+鏌�
+鏋�
+鏌�
+鏌�
+鏍�
+鏌�
+鏍�
+鏋�
+鏌�
+鏌�
+鏋�
+鏌�
+鍓�
+閰�
+閮�
+鐢�
+鐮�
+鐮�
+鐮�
+鏂�
+鐮�
+鐮�
+濂�
+鑰�
+铏�
+娈�
+娈�
+娈�
+娈�
+杞�
+杞�
+杞�
+杞�
+杞�
+铏�
+姣�
+瑙�
+灏�
+鍝�
+鐪�
+鐪�
+馉硱
+閮�
+鐪�
+鐪�
+鐪�
+绂�
+鍝�
+鍜�
+鏇�
+鏄�
+鏄�
+鏄�
+鍜�
+鍝�
+鍝�
+鐣�
+姣�
+鍛�
+鑳�
+鐣�
+鐣�
+铏�
+铏�
+鐩�
+鍜�
+鍝�
+鍓�
+閮�
+鍜�
+鍥�
+鍜�
+鍝�
+鍝�
+鍝�
+鍜�
+鍜�
+鍜�
+鍝�
+鍝�
+鍝�
+宄�
+宄�
+缃�
+甯�
+宄�
+宄�
+宄�
+宄�
+璐�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+姘�
+姘�
+鐗�
+閮�
+绉�
+绉�
+绔�
+绗�
+绗�
+淇�
+淇�
+淇�
+淇�
+鍙�
+鍨�
+鐗�
+淇�
+淇�
+鐨�
+淇�
+淇�
+閫�
+寰�
+寰�
+鑸�
+淇�
+閮�
+淇�
+閮�
+鐖�
+閮�
+鐡�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鏈�
+鑳�
+楦�
+鍖�
+鐙�
+鐙�
+椋�
+鐙�
+鐙�
+瑷�
+閫�
+鏄�
+楗�
+楗�
+楗�
+鑳�
+瀛�
+濞�
+寮�
+濂�
+搴�
+鐤�
+鐤�
+鐤�
+鐤�
+搴�
+绔�
+褰�
+椋�
+闂�
+闂�
+闂�
+闃�
+缇�
+杩�
+绫�
+閰�
+鐐�
+鐐�
+鐐�
+鐐�
+鐑�
+鐐�
+鐑�
+娲�
+娲�
+娲�
+娲�
+娴�
+娲�
+娲�
+娲�
+娑�
+娲�
+娲�
+娴�
+娲�
+娲�
+娴�
+娴�
+娴�
+娲�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+瀹�
+鎵�
+琛�
+琛�
+琛�
+琚�
+绁�
+绁�
+绁�
+绁�
+璇�
+绁�
+绁�
+璇�
+璇�
+楦�
+鏄�
+閮�
+鍜�
+寮�
+鐗�
+鑳�
+闄�
+闄�
+濞�
+濮�
+濞�
+濮�
+濮�
+濮�
+濮�
+鎬�
+缇�
+鐐�
+鐭�
+缁�
+楠�
+楠�
+缁�
+缁�
+楠�
+鑰�
+鎸�
+鐝�
+鐝�
+椤�
+鐝�
+鐝�
+鐝�
+鐝�
+鐝�
+鐞�
+鐝�
+鏁�
+鎭�
+鍩�
+鍩�
+鍩�
+鍩�
+鍩�
+鎸�
+鑰�
+鑰�
+鍩�
+鎹�
+璐�
+鍨�
+鎹�
+鐩�
+鑽�
+鑾�
+鑾�
+鑾�
+鑾�
+鑾�
+鑾�
+鑾�
+鑾�
+鑽�
+鑾�
+鑽�
+鑾�
+鑽�
+鑾�
+鑾�
+鑾�
+鑾�
+娓�
+楦�
+鑾�
+鏍�
+鏍�
+閮�
+妗�
+妗�
+妗�
+妗�
+妗�
+姊�
+鏍�
+妗�
+妗�
+妗�
+妗�
+鏍�
+妗�
+鏍�
+閫�
+閫�
+褰�
+楝�
+璞�
+閰�
+閫�
+鍘�
+瀛�
+鐮�
+鐮�
+鐮�
+鐮�
+鐮�
+鐮�
+鐮�
+鐮�
+鐮�
+鍓�
+鐮�
+杞�
+杞�
+杈�
+楦�
+瓒�
+榫�
+楦�
+铏�
+閫�
+鐪�
+鍞�
+鏅�
+鐪�
+鐪�
+鍝�
+鍝�
+鍞�
+鏅�
+鏅�
+楦�
+瓒�
+瓒�
+鐣�
+铓�
+铓�
+铓�
+铓�
+铓�
+铓�
+铓�
+鍞�
+鍦�
+鍞�
+鍞�
+鐩�
+鍞�
+宕�
+宕�
+缃�
+缃�
+宄�
+瑙�
+璧�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閽�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+浈�
+閾�
+姘�
+姘�
+姘�
+姣�
+鑸�
+绉�
+绉�
+鐩�
+绗�
+绗�
+绗�
+绗�
+绗�
+淇�
+鍊�
+淇�
+鍋�
+淇�
+淇�
+鍊�
+鍊�
+鎭�
+鍊�
+鍊�
+淇�
+鍊�
+闅�
+闅�
+鍊�
+鍊�
+鑷�
+鐨�
+閮�
+鍊�
+琛�
+棰�
+寰�
+鑸�
+閲�
+濂�
+琛�
+鑳�
+鑳�
+鑳�
+鑳�
+鑴�
+鑳�
+鏈�
+鑴�
+鑳�
+楦�
+鐜�
+楦�
+鐙�
+鐚�
+鐙�
+鐚�
+鐙�
+閫�
+妗�
+琚�
+楗�
+鍑�
+鏍�
+鎸�
+浜�
+鐤�
+鐤�
+鐤�
+鐤�
+鐥�
+鐤�
+鐥�
+鐥�
+琛�
+鍑�
+棰�
+鎭�
+鏃�
+鏃�
+鏃�
+闃�
+闃�
+瑷�
+闃�
+鎭�
+绮�
+鏈�
+閮�
+鐑�
+鐑�
+鐑�
+鐑�
+鍓�
+閮�
+鐑�
+娑�
+娴�
+娑�
+娑�
+濞�
+娑�
+娑�
+娴�
+娑�
+娴�
+娑�
+娴�
+娴�
+娴�
+娴�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+瀹�
+绐�
+鍓�
+璇�
+鍐�
+璇�
+琚�
+琚�
+绁�
+璇�
+璋�
+璋�
+璋�
+璋�
+灞�
+灞�
+闄�
+鍕�
+濂�
+鐗�
+铓�
+闄�
+濮�
+濞�
+濞�
+濞�
+濞�
+濞�
+濞�
+濞�
+濞�
+濠�
+鐣�
+閫�
+缁�
+楠�
+缁�
+楠�
+缁�
+缁�
+缁�
+楠�
+閭�
+楦�
+褰�
+鑰�
+鐒�
+鑸�
+鐞�
+鐞�
+楹�
+鎻�
+鍩�
+鍩�
+鎹�
+鎺�
+鎺�
+鍩�
+鍩�
+璧�
+鍩�
+鎹�
+閫�
+鍩�
+鍫�
+鍫�
+鎺�
+楦�
+鎺�
+鎹�
+鎺�
+鍫�
+鎺�
+鎹�
+鎺�
+鎮�
+鍩�
+鍩�
+鎺�
+鎺�
+鑱�
+鑿�
+钀�
+鑿�
+鍫�
+钀�
+钀�
+鑿�
+鑿�
+钀�
+钀�
+钀�
+妫�
+鑿�
+鑿�
+钀�
+钀�
+鑿�
+鑿�
+鑿�
+鑿�
+鑿�
+钀�
+鑿�
+鑿�
+姊�
+姊�
+姊�
+瑙�
+妗�
+妗�
+姊�
+妫�
+妗�
+妫�
+鍟�
+閮�
+鍖�
+鏁�
+璞�
+閯�
+閰�
+閰�
+鎴�
+纭�
+纭�
+纭�
+纭�
+纭�
+纭�
+纭�
+纭�
+楦�
+鐡�
+鍖�
+鍘�
+榫�
+娈�
+娈�
+娈�
+璧�
+闆�
+杈�
+鍫�
+鐪�
+鐪�
+鍟�
+鏅�
+鏅�
+鐪�
+鐪�
+鐪�
+鍦�
+鍠�
+鍠�
+鍟�
+鍕�
+鏅�
+鍞�
+鏅�
+鍐�
+鍟�
+鐣�
+瓒�
+鍟�
+璺�
+铓�
+铔�
+铔�
+铔�
+铓�
+铔�
+鍦�
+铓�
+铔�
+铔�
+铓�
+鍟�
+鍟�
+鍞�
+鍟�
+鍞�
+鍞�
+鍟�
+鍟�
+鍟�
+鍟�
+鍞�
+鍞�
+鍟�
+甯�
+宕�
+宕�
+甯�
+宕�
+宕�
+宕�
+璧�
+璧�
+璧�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+姘�
+鐗�
+楦�
+绉�
+閫�
+绗�
+绛�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+鍋�
+鍋�
+鍋�
+鍋�
+鍌�
+鍋�
+鍋�
+鐨�
+鐨�
+楦�
+寰�
+鑸�
+鑸�
+鑸�
+鑸�
+榫�
+缈�
+鑴�
+鑴�
+鑴�
+鍖�
+鐚�
+鐚�
+鐚�
+鐚�
+鏂�
+鐚�
+棣�
+棣�
+棣�
+楦�
+瀛�
+搴�
+搴�
+鐥�
+鐥�
+鐤�
+缈�
+鏃�
+鏃�
+琚�
+闃�
+闃�
+闃�
+闃�
+闃�
+闃�
+闃�
+缇�
+绮�
+绮�
+鏁�
+鐒�
+鐑�
+鐒�
+鐑�
+鐒�
+鐑�
+鐒�
+娓�
+娓�
+娣�
+娣�
+娣�
+娓�
+娑�
+娣�
+鎸�
+娣�
+娑�
+娓�
+娣�
+娣�
+娣�
+娑�
+娣�
+娑�
+娓�
+娣�
+鎯�
+鎮�
+鎮�
+鎯�
+鎯�
+鎮�
+鎯�
+鎯�
+鎯�
+鎯�
+绐�
+璋�
+璋�
+鎵�
+鐨�
+璋�
+瑁�
+琚�
+瑁�
+璋�
+璋�
+璋�
+璋�
+璋�
+璋�
+璋�
+璋�
+閫�
+閮�
+闅�
+绮�
+闅�
+闅�
+濠�
+濠�
+濠�
+濞�
+濠�
+濠�
+鑳�
+琚�
+缈�
+鎭�
+娆�
+缁�
+楠�
+缁�
+缁�
+缁�
+楠�
+缁�
+楠�
+缁�
+缁�
+缁�
+缁�
+楠�
+缂�
+鑰�
+鐞�
+鐞�
+鐞�
+鐞�
+鐟�
+鐞�
+鐞�
+鐞�
+闈�
+鐞�
+鐞�
+鐞�
+鐞�
+鐞�
+鐞�
+杈�
+榧�
+鎻�
+鍫�
+鎼�
+鎻�
+鎻�
+鍫�
+瓒�
+鎻�
+棰�
+濉�
+鎻�
+鑰�
+鎻�
+铔�
+铔�
+濉�
+鎽�
+鎻�
+鎺�
+鑱�
+钁�
+钁�
+闈�
+闈�
+钁�
+钁�
+钁�
+钀�
+钁�
+钁�
+钁�
+钂�
+钀�
+鎴�
+钁�
+妤�
+妫�
+妞�
+妫�
+妞�
+妫�
+璧�
+妞�
+妞�
+妞�
+妫�
+妞�
+楣�
+瑕�
+閰�
+閰�
+閰�
+楣�
+鍘�
+娈�
+娈�
+闆�
+闆�
+杈�
+杈�
+妞�
+杈�
+杈�
+鏂�
+鐫�
+鐫�
+鐫�
+鐫�
+鎴�
+鍠�
+鍡�
+鍠�
+鍠�
+鍠�
+鏅�
+鍠�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+鍠�
+鍠�
+鍟�
+鍡�
+鍠�
+鍡�
+鍠�
+鍡�
+鍠�
+鍠�
+鍠�
+宓�
+宓�
+宕�
+閬�
+瑭�
+宓�
+宕�
+宓�
+宓�
+宓�
+宓�
+宓�
+骞�
+宓�
+璧�
+閾�
+閾�
+閾�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+鎺�
+鐭�
+姘�
+姣�
+姣�
+鐘�
+鐘�
+鐘�
+楣�
+鐘�
+宓�
+榛�
+绋�
+绋�
+绛�
+绛�
+绛�
+鍌�
+鍌�
+鑸�
+鐗�
+鍌�
+鍌�
+閬�
+鍌�
+閬�
+寰�
+濯�
+鐣�
+寮�
+棰�
+缈�
+閲�
+楣�
+鑸�
+璨�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+楸�
+椴�
+椴�
+棰�
+鐚�
+鐚�
+鐚�
+椋�
+瑙�
+瑙�
+鐚�
+棰�
+椋�
+棣�
+棣�
+浜�
+鑴�
+瑁�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+璧�
+绔�
+鐡�
+鍟�
+棰�
+楣�
+闃�
+闃�
+闃�
+绮�
+閬�
+瀛�
+鐒�
+鐒�
+鐒�
+鐒�
+楣�
+婀�
+娓�
+婀�
+婀�
+婀�
+娓�
+婀�
+婀�
+婧�
+婀�
+婧�
+婀�
+婀�
+婀�
+娓�
+婀�
+婊�
+鎰�
+鎯�
+鎰�
+鎯�
+鎰�
+鎰�
+鎰�
+鍠�
+瀵�
+璋�
+鎵�
+瑁�
+瑁�
+瑁�
+绁�
+绁�
+璋�
+骞�
+璋�
+璋�
+璋�
+閬�
+瀛�
+寮�
+宸�
+楠�
+濯�
+濯�
+濠�
+宸�
+缈�
+鐨�
+濠�
+楠�
+缂�
+缂�
+缂�
+褰�
+缂�
+缂�
+缂�
+缂�
+缂�
+缂�
+椋�
+鑰�
+鐟�
+鐟�
+鐟�
+鐟�
+鐟�
+鐟�
+閬�
+楠�
+闊�
+楂�
+濉�
+閯�
+瓒�
+瓒�
+鎽�
+鎽�
+铚�
+鎼�
+鎼�
+鎼�
+鎼�
+鎼�
+鎽�
+褰�
+姣�
+鎼�
+鎼�
+钃�
+鎴�
+钃�
+閯�
+闈�
+钃�
+钃�
+楣�
+钂�
+钃�
+钃�
+钃�
+钂�
+钃�
+钃�
+钂�
+钂�
+钃�
+钂�
+钂�
+钂�
+钂�
+钂�
+钃�
+棰�
+妤�
+妤�
+妤�
+妤�
+妤�
+妤�
+妞�
+妲�
+妤�
+鐨�
+姒�
+妲�
+姒�
+妤�
+妤�
+妤�
+妞�
+瑁�
+鍓�
+鐢�
+閰�
+閰�
+閰�
+閰�
+铚�
+纰�
+纰�
+纭�
+纰�
+纰�
+纰�
+纰�
+楣�
+杈�
+榫�
+榫�
+瑷�
+绮�
+铏�
+鐫�
+鍡�
+闊�
+鍡�
+鍡�
+鐫�
+鐫�
+闆�
+鐫�
+鍢�
+鍡�
+鍡�
+鍡�
+鍡�
+鍡�
+鎴�
+鍡�
+鐓�
+鏆�
+閬�
+鏆�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+铔�
+铚�
+铚�
+铚�
+铚�
+鐣�
+铔�
+鍡�
+鍡�
+鍡�
+鍡�
+鍡�
+鍡�
+鍡�
+鍡�
+鍡�
+鍡�
+鍡�
+缃�
+宓�
+宓�
+宓�
+楠�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+闆�
+姘�
+鐘�
+姝�
+绋�
+绋�
+绋�
+绛�
+绛�
+绛�
+绛�
+绛�
+鐗�
+鐓�
+鏁�
+寰�
+鎰�
+鑹�
+瑙�
+姣�
+璨�
+璨�
+璨�
+棰�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+濉�
+濯�
+瑭�
+椴�
+椴�
+椴�
+椴�
+绋�
+椴�
+椴�
+鑲�
+楣�
+椋�
+瑙�
+閬�
+棣�
+楣�
+浜�
+鐦�
+鐥�
+鐥�
+鐥�
+鐦�
+鐦�
+鐦�
+楹�
+瑁�
+姝�
+鏃�
+闆�
+闃�
+闃�
+闃�
+缇�
+璞�
+绮�
+鐚�
+鐓�
+鐓�
+鐓�
+鐓�
+鐓�
+鐓�
+鐓�
+婊�
+婧�
+婧�
+婕�
+婊�
+婧�
+婧�
+婧�
+瑁�
+婧�
+婧�
+婊�
+婊�
+婧�
+婊�
+婊�
+婊�
+婧�
+婊�
+婊�
+婧�
+婊�
+鎰�
+鎱�
+鎱�
+椴�
+楠�
+绐�
+绐�
+绐�
+瑁�
+瑜�
+瑁�
+瑁�
+瑁�
+绂�
+璋�
+璋�
+濯�
+瀚�
+濯�
+瀚�
+瀚�
+濯�
+缂�
+缂�
+缂�
+杈�
+楠�
+缂�
+缂�
+缂�
+缂�
+楠�
+鑰�
+鐠�
+鐟�
+鐟�
+鐛�
+瑙�
+鎱�
+瀚�
+闊�
+鍙�
+楂�
+鎽�
+澧�
+鎾�
+鎽�
+鎾�
+缈�
+韪�
+鎽�
+澧�
+澧�
+姒�
+缍�
+钄�
+钄�
+闈�
+闈�
+闉�
+闈�
+鐢�
+钄�
+钄�
+钄�
+鎴�
+钑�
+钄�
+钃�
+鏂�
+楣�
+钃�
+姒�
+姒�
+姒�
+姒�
+姒�
+妲�
+姒�
+妲�
+妲�
+妲�
+姒�
+鍍�
+閰�
+閰�
+閰�
+鍘�
+纰�
+纰�
+纰�
+纰�
+纾�
+鑷�
+璞�
+娈�
+闇�
+闇�
+杈�
+铚�
+瑁�
+缈�
+榫�
+榫�
+鐫�
+鋪�
+鐫�
+鍢�
+鍢�
+鍢�
+鍢�
+鍢�
+鏆�
+鏆�
+韪�
+韪�
+铚�
+铚�
+铚�
+铦�
+铚�
+铚�
+铚�
+铚�
+铚�
+铻�
+铚�
+鍢�
+鍢�
+楣�
+鍢�
+鍢�
+鍢�
+鍡�
+鍢�
+缃�
+缃�
+骞�
+宥�
+骞�
+璧�
+缃�
+楠�
+楠�
+楣�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+闀�
+闀�
+鐘�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+姣�
+鍍�
+鍎�
+鍍�
+鍍�
+鍔�
+鍍�
+榄�
+榄�
+鐫�
+鑹�
+閯�
+鑶�
+鑶�
+椴�
+椴�
+椴�
+椴�
+椴�
+鐛�
+瑙�
+闆�
+澶�
+棣�
+閵�
+濉�
+楹�
+鐦�
+鐦�
+鐦�
+鐦�
+寤�
+闊�
+鏃�
+鑶�
+闃�
+閯�
+椴�
+绮�
+绮�
+绮�
+绯�
+妲�
+楣�
+鐔�
+鐔�
+娼�
+婕�
+婊�
+婕�
+婕�
+娼�
+娼�
+婕�
+婕�
+婕�
+婕�
+婢�
+娼�
+鎱�
+鎼�
+绐�
+瀵�
+缍�
+璋�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+璋�
+璋�
+璋�
+鏆�
+灞�
+楣�
+瀚�
+瀚�
+瀚�
+瀚�
+瀚�
+瀚�
+瀚�
+榧�
+缈�
+鐬�
+楣�
+楠�
+缂�
+缂�
+缂�
+缂�
+楠�
+缂�
+缂�
+鑰�
+鑰�
+鐟�
+鐠�
+鐠�
+鐠�
+鐠�
+鐠�
+鐠�
+濂�
+楂�
+楂�
+鎾�
+鎾�
+璧�
+鎾�
+閶�
+鎾�
+鎾�
+澧�
+鑱�
+瑙�
+闉�
+钑�
+闉�
+钑�
+钑�
+钑�
+钑�
+钑�
+鐬�
+钑�
+钑�
+璧�
+妲�
+妯�
+妲�
+妯�
+妯�
+妯�
+妲�
+閱�
+閱�
+闈�
+榄�
+椁�
+纾�
+纾�
+闇�
+杈�
+榫�
+榫�
+瑙�
+鐬�
+鐬�
+鐬�
+鍢�
+鍣�
+鍣�
+棰�
+鏆�
+鍣�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+铦�
+铦�
+铦�
+铦�
+铦�
+铻�
+铦�
+铦�
+铦�
+鍣�
+鍢�
+棰�
+鍣�
+鍣�
+鍣�
+鍣�
+鍣�
+鍣�
+棰�
+骞�
+骞�
+宥�
+宥�
+楠�
+楠�
+楠�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+绋�
+绠�
+绡�
+绡�
+绡�
+绡�
+鐗�
+鍎�
+寰�
+纾�
+铏�
+楣�
+鑶�
+婊�
+椴�
+椴�
+椴�
+椴�
+椴�
+椴�
+椴�
+鐛�
+鐛�
+瑙�
+棣�
+棣�
+楹�
+寤�
+鐦�
+鐦�
+鐦�
+鐦�
+榻�
+缇�
+缇�
+馥粭
+閬�
+绯�
+绯�
+绯�
+鐔�
+鐔�
+鐔�
+婢�
+婢�
+娼�
+娼�
+娼�
+閶�
+娼�
+娼�
+娼�
+鎲�
+鎲�
+瀵�
+绐�
+璋�
+瑜�
+瑜�
+瑜�
+璋�
+鐔�
+灞�
+瀣�
+鍕�
+鎴�
+铦�
+缂�
+缂�
+缂�
+楠�
+鐣�
+鑰�
+鑰�
+鑰�
+鐠�
+鐠�
+闈�
+鐠�
+鐠�
+鑱�
+铻�
+楂�
+楂�
+楂�
+鎿�
+鐔�
+鐢�
+鎿�
+绺�
+纾�
+棰�
+钑�
+闉�
+棰�
+钖�
+钖�
+妾�
+钖�
+钖�
+钖�
+钖�
+妯�
+姗�
+姗�
+妯�
+妾�
+姗�
+妯�
+妯�
+姗�
+澧�
+姗�
+缈�
+閱�
+閱�
+閱�
+閱�
+纾�
+璧�
+椋�
+娈�
+闇�
+闇�
+闇�
+閷�
+杈�
+鑷�
+閬�
+姘�
+鐬�
+鐬�
+鐬�
+鍤�
+鍤�
+鍣�
+鏆�
+韫�
+韪�
+韪�
+韪�
+韫�
+韫�
+铻�
+锜�
+铻�
+铻�
+铻�
+铻�
+铻�
+鍣�
+鍣�
+鍣�
+鍣�
+鍣�
+缃�
+鍦�
+洇�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+姘�
+姘�
+鎲�
+绌�
+绡�
+绡�
+绡�
+绡�
+绡�
+鐩�
+鍔�
+缈�
+榄�
+榄�
+寰�
+姝�
+鑶�
+鑶�
+鑶�
+椴�
+椴�
+椴�
+椴�
+椴�
+椴�
+椴�
+椴�
+鐛�
+鐛�
+鐛�
+閭�
+楣�
+寤�
+璧�
+鐦�
+寤�
+鐦�
+鐦�
+鐦�
+鐧�
+鐦�
+鏂�
+楹�
+楹�
+瀣�
+澹�
+缇�
+绯�
+鐬�
+鐢�
+鐕�
+鐕�
+鐕�
+鐕�
+婵�
+婵�
+娼�
+婢�
+婢�
+婢�
+婢�
+婵�
+瑜�
+瀵�
+绐�
+瑜�
+绂�
+瀣�
+鐘�
+闅�
+瀣�
+棰�
+缂�
+缂�
+缂�
+鐠�
+鐠�
+鐠�
+鐠�
+铻�
+鎿�
+澹�
+瑙�
+缃�
+鎿�
+钖�
+闉�
+闉�
+钖�
+钖�
+钘�
+钘�
+妾�
+妾�
+鎳�
+閱�
+缈�
+绀�
+纾�
+楣�
+榫�
+榫�
+璞�
+澹�
+榛�
+鍤�
+鍤�
+韫�
+韫�
+韫�
+锜�
+铻�
+铻�
+鐤�
+铻�
+锜�
+鍤�
+缇�
+缃�
+缃�
+宥�
+榛�
+榛�
+楂�
+楂�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+闀�
+缃�
+榛�
+绨�
+绡�
+绡�
+绨�
+绨�
+榧�
+榛�
+鍎�
+楣�
+榧�
+鐨�
+榄�
+榫�
+绻�
+璨�
+閭�
+璨�
+鑷�
+鑶�
+鑷�
+鑷�
+椴�
+椴�
+槌�
+槌�
+槌�
+槌�
+槌�
+铻�
+鐕�
+楣�
+瑗�
+绯�
+绺�
+鑶�
+鐧�
+楹�
+鎳�
+婵�
+婵�
+婵�
+婵�
+婵�
+韫�
+璎�
+閭�
+瑗�
+妾�
+鎿�
+瀛�
+闅�
+瀣�
+锜�
+楣�
+閸�
+閺�
+槌�
+楝�
+楝�
+鐬�
+闉�
+闉�
+闉�
+闉�
+闉�
+钘�
+钘�
+钘�
+閱�
+韫�
+绀�
+鐕�
+椁�
+鐬�
+鏇�
+棰�
+鏇�
+韬�
+韫�
+楣�
+锜�
+锜�
+锜�
+锜�
+楣�
+榛�
+榛�
+楂�
+楂�
+闀�
+闀�
+闀�
+棣�
+绨�
+绨�
+榧�
+闆�
+鑹�
+槌�
+槌�
+槌�
+鐧�
+鐧�
+鐧�
+鐧�
+绯�
+韫�
+閹�
+鎳�
+褰�
+閭�
+楝�
+鏀�
+鏀�
+闉�
+闉�
+钘�
+铇�
+铇�
+楹�
+閱�
+閱�
+閰�
+闇�
+闇�
+闇�
+榛�
+鍤�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+锠�
+锠�
+锜�
+锠�
+榛�
+楂�
+楂�
+闀�
+绫�
+绫�
+榻�
+榄�
+鑹�
+槌�
+槌�
+槌�
+槌�
+槌�
+楹�
+閺�
+缇�
+愀�
+鐎�
+鐎�
+鐎�
+瑗�
+璋�
+瑗�
+楠�
+缂�
+鐡�
+鏀�
+铇�
+铇�
+閱�
+闇�
+閰�
+鐭�
+鏇�
+韬�
+榧�
+宸�
+榛�
+榛�
+榛�
+闀�
+闀�
+榛�
+绾�
+鐠�
+榧�
+鑷�
+槌�
+槌�
+槌�
+鐛�
+瀛�
+楠�
+鐡�
+榧�
+閱�
+绀�
+棰�
+鏇�
+槌�
+鐧�
+楹�
+澶�
+鐖�
+鐏�
+绂�
+閻�
+缇�
+锠�
+鑰�
+鎳�
+铇�
+楣�
+闇�
+姘�
+楗�
+韬�
+楂�
+闀�
+绌�
+楗�
+楝�
+楝�
+瓒�
+鏀�
+鏀�
+棰�
+韬�
+榧�
+鐧�
+楹�
+锠�
+锠�
+韬�
+琛�
+閼�
+鐏�
+瑗�
+绾�
+楝�
+鏀�
+鍥�
+棣�
+鎴�
+鐖�
+榻�
+浜�
+灏�
+褰�
+鍗�
+娈�
+馉櫠
+姣�
+閭�
+鎴�
+鍦�
+姘�
+浼�
+浠�
+鍐�
+姘�
+姹�
+姘�
+蹇�
+瀹�
+璁�
+鎵�
+鍦�
+鍦�
+鑺�
+鑺�
+鏈�
+鏈�
+皎櫢
+閭�
+鍚�
+鍚�
+灞�
+灞�
+杈�
+閽�
+浠�
+浼�
+浼�
+鐧�
+鐢�
+閭�
+鐘�
+鍐�
+閭�
+闂�
+姹�
+錅�
+璁�
+瀛�
+绾�
+鐜�
+鐜�
+鐜�
+鐜�
+鍒�
+鍧�
+鍧�
+鎵�
+鍧�
+鎵�
+悃�
+姣�
+鑺�
+鑺�
+鑻�
+鑻�
+鑺�
+鑺�
+鑺�
+鑺�
+鏉�
+鏉�
+鏉�
+鏉�
+鏉�
+灏�
+灏�
+杞�
+鍧�
+鑺�
+鏃�
+鏃�
+鍛�
+銜�
+宀�
+宀�
+宀�
+鍛�
+鍐�
+瑙�
+宀�
+浼�
+銘�
+浼�
+浣�
+浼�
+浣�
+椋�
+鐙�
+闂�
+姹�
+姹�
+穑矘
+穑矖
+娌�
+娌�
+姹�
+愠�
+娌�
+蹇�
+蹇�
+蹇�
+绁�
+璇�
+閭�
+璇�
+璇�
+灞�
+宀�
+闃�
+洧�
+闃�
+濡�
+濡�
+皎殨
+绾�
+椹�
+绾�
+绾�
+鐜�
+鐜�
+鐜�
+鐜�
+閭�
+閭�
+鍧�
+鍧�
+鍧�
+鍧�
+寮�
+鑰�
+洧�
+穰瓬
+鑼�
+鑻�
+鑻�
+鑻�
+鏋�
+悱�
+鏋�
+鏋�
+鐭�
+鐭�
+鍖�
+鏃�
+鏄�
+鏄�
+鏄�
+鏄�
+鍜�
+鍜�
+鍜�
+宀�
+宀�
+宀�
+宀�
+宄�
+銦�
+鍥�
+閽�
+閽�
+閽�
+鐗�
+浣�
+鍨�
+渚�
+渚�
+浣�
+浣�
+闅�
+銘�
+渚�
+浣�
+渚�
+閮�
+鑸�
+閮�
+閮�
+鏀�
+鑲�
+鑲�
+鑲�
+鐙�
+鐙�
+楗�
+蹇�
+鏂�
+鐐�
+鐐�
+娉�
+娌�
+娉�
+娉�
+娉�
+娉�
+鎬�
+宄�
+绌�
+绁�
+绁�
+楦�
+寮�
+寮�
+闄�
+闄�
+鍗�
+涔�
+濡�
+濮�
+杩�
+鍙�
+椹�
+鋵�
+椹�
+缁�
+缁�
+鐮�
+鑰�
+銢�
+鐜�
+鐝�
+鐝�
+鐝�
+鐜�
+鐝�
+鐜�
+闊�
+鍨�
+鍨�
+鍨�
+鍨�
+鍩�
+鍨�
+鑰�
+鍨�
+鍨�
+鍨�
+鍨�
+鎸�
+鍨�
+鍨�
+鎷�
+鑽�
+鑽�
+鑽�
+鑽�
+鑼�
+鑼�
+鑽�
+鑼�
+鑽�
+鑼�
+穰啊
+鑼�
+鑽�
+悱�
+鏌�
+鏌�
+鏌�
+鏋�
+鏍�
+鏌�
+閮�
+鍓�
+浯�
+杩�
+鍘�
+鐮�
+鐮�
+鐮�
+鑰�
+濂�
+涠�
+杞�
+杞�
+杞�
+杞�
+鏄�
+鏄�
+鐩�
+鍜�
+鍜�
+鏄�
+鏄�
+鍝�
+鏄�
+鏄�
+鏄�
+鍜�
+鏄�
+铏�
+铏�
+鍝�
+宄�
+鑰�
+宄�
+宄�
+宄�
+甯�
+閽�
+閽�
+閽�
+閽�
+閽�
+鐭�
+绉�
+淇�
+鑸�
+淇�
+淇�
+淇�
+鍨�
+琛�
+鑸�
+寮�
+渚�
+楦�
+鋸�
+鑳�
+穰櫠
+鑳�
+鑳�
+鑳�
+鏈�
+椋�
+瑷�
+楗�
+搴�
+鐤�
+鐐�
+鐐�
+愣�
+娲�
+娲�
+娲�
+娲�
+愠�
+娉�
+娴�
+娴�
+娲�
+娲�
+娲�
+娲�
+娲�
+娲�
+娲�
+娴�
+愠�
+娲�
+娲�
+鎭�
+瀹�
+绐�
+鎵�
+琚�
+绁�
+绁�
+绁�
+鍙�
+闄�
+闄�
+濞�
+濮�
+濮�
+濮�
+濮�
+濮�
+鏋�
+缁�
+楠�
+褰�
+楠�
+鎭�
+鐝�
+鐝�
+鐝�
+鐞�
+鐜�
+鐝�
+鐝�
+鐝�
+鐝�
+鐝�
+鐝�
+鐝�
+鐝�
+鍩�
+鍨�
+鍨�
+鍩�
+鍨�
+鍩�
+鍩�
+鑾�
+鑼�
+閯�
+鑾�
+鑾�
+鋼�
+鑾�
+鏍�
+妗�
+妗�
+姊�
+鏍�
+姊�
+鏍�
+閰�
+閰�
+鐮�
+鐮�
+鐮�
+鐮�
+纭�
+鎭�
+缈�
+閮�
+皎悎
+杈�
+杈�
+鍓�
+璧�
+鍝�
+鏅�
+鏅�
+鍞�
+鍝�
+鍝�
+鍐�
+鏅�
+鏅�
+鏅�
+鐣�
+铓�
+铓�
+甯�
+宕�
+宄�
+宕�
+甯�
+宕�
+璧�
+閽�
+鐪�
+鐢�
+绗�
+鍊�
+鍊�
+鑴�
+鍊�
+鍊�
+鍊�
+鍊�
+鍊�
+琛�
+铏�
+鑸�
+鑸�
+鑸�
+鐡�
+楝�
+楦�
+鑴�
+鏈�
+鑳�
+铏�
+楸�
+鐙�
+宄�
+鐙�
+鐪�
+鍕�
+鐥�
+鐤�
+鐥�
+绔�
+缇�
+缇�
+妗�
+鏁�
+鐑�
+鐑�
+鐑�
+鐑�
+娑�
+娴�
+娴�
+娴�
+娑�
+娑�
+娑�
+娴�
+娴�
+娴�
+娴�
+娴�
+娑�
+鎮�
+鎮�
+鎮�
+瀹�
+绐�
+绐�
+绐�
+鎵�
+鎵�
+琚�
+琚�
+琚�
+绁�
+闅�
+鍫�
+鐤�
+皎簷
+闄�
+鐑�
+鐮�
+銢�
+鍝�
+缈�
+缈�
+鍓�
+缁�
+楠�
+鋫�
+鐞�
+鐝�
+鐝�
+鐞�
+鐞�
+鐞�
+鐝�
+鎺�
+鍫�
+鍫�
+鍩�
+鎺�
+鍩�
+鍫�
+鏅�
+鎺�
+鍩�
+澹�
+銠�
+鑱�
+鑿�
+钀�
+鑿�
+鑾�
+鋼�
+鍕�
+鋼�
+钀�
+鑿�
+鑿�
+鑿�
+钀�
+鋼�
+鑿�
+鋼�
+姊�
+姊�
+妗�
+姊�
+妗�
+姊�
+姊�
+妗�
+鏁�
+鍘�
+纭�
+纭�
+纭�
+纭�
+纭�
+鍕�
+浯�
+榫�
+閫�
+鍞�
+鍟�
+缈�
+惬�
+鏅�
+鐣�
+瓒�
+璺�
+铔�
+铓�
+铓�
+鍟�
+鋷�
+宕�
+宕�
+宕�
+宕�
+宕�
+宕�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+閾�
+鐗�
+鐗�
+绋�
+绗�
+绗�
+鍋�
+鍋�
+楦�
+鍋�
+鍋�
+鍋�
+憧�
+閯�
+鍋�
+寰�
+琛�
+鑸�
+鑸�
+楦�
+鎮�
+閯�
+鐡�
+錆�
+鑴�
+鑴�
+鑴�
+鋸�
+楸�
+鐚�
+鐚�
+鐚�
+瑙�
+馉叅
+搴�
+搴�
+搴�
+鐥�
+浯�
+绔�
+鍫�
+闃�
+缇�
+缇�
+鐒�
+鐑�
+鐒�
+娣�
+娣�
+娣�
+娣�
+娣�
+婀�
+娑�
+悭�
+鎯�
+鎯�
+鎮�
+鎯�
+瀵�
+閫�
+琚�
+瑁�
+绁�
+璋�
+鑹�
+寮�
+寮�
+闅�
+濠�
+濞�
+濠�
+濯�
+濠�
+濠�
+濠�
+濠�
+濠�
+濠�
+濠�
+缁�
+楠�
+绲�
+鐝�
+鐞�
+鐞�
+鐞�
+鐞�
+鐞�
+鍫�
+鍫�
+鎻�
+銠�
+鍫�
+鍠�
+鍫�
+濉�
+鍫�
+绲�
+稹帤
+钁�
+鎯�
+钀�
+钁�
+闈�
+钁�
+钂�
+钂�
+閯�
+钂�
+钃�
+钀�
+钂�
+钁�
+钁�
+閯�
+钂�
+钁�
+钂�
+钀�
+妫�
+妫�
+妫�
+妞�
+妞�
+楣�
+妞�
+妫�
+妫�
+妫�
+妞�
+妤�
+鐢�
+閰�
+瑙�
+濂�
+鐨�
+纭�
+娆�
+瑭�
+杈�
+妫�
+榫�
+榛�
+鐗�
+鐫�
+鏅�
+鏅�
+鏅�
+皈抗
+铔�
+鐣�
+鏂�
+鍠�
+宕�
+宓�
+宕�
+宓�
+宕�
+宓�
+缈�
+鍦�
+鍦�
+璧�
+娣�
+璧�
+閾�
+閾�
+皎眹
+閿�
+閿�
+閿�
+閿�
+鐘�
+棰�
+绋�
+绛�
+绛�
+绛�
+绛�
+绛�
+鍌�
+鍌�
+缈�
+鍌�
+鍌�
+鑸�
+鐣�
+鑴�
+鑵�
+鋹�
+鑵�
+鑵�
+椴�
+鐚�
+鐚�
+愫�
+棣�
+閯�
+寤�
+寤�
+閯�
+绮�
+閬�
+鏃�
+鐒�
+娆�
+穑福
+婧�
+婧�
+婀�
+娓�
+婀�
+愦�
+娓�
+婧�
+娓�
+婧�
+婀�
+婀�
+婧�
+鎰�
+鎰�
+鏁�
+鐢�
+妫�
+鎵�
+瑁�
+绁�
+濠�
+濯�
+濯�
+銢�
+濯�
+濯�
+濯�
+姣�
+鐭�
+缂�
+缂�
+楠�
+鐟�
+鐟�
+鐟�
+鐟�
+浯�
+鐟�
+鐟�
+鐟�
+鐟�
+黏
+鐟�
+鐟�
+宥�
+鐟�
+閬�
+楂�
+濉�
+鍫�
+璧�
+鎽�
+濉�
+鎼�
+鎼�
+钂�
+钂�
+钃�
+钄�
+钃�
+钃�
+钂�
+钃�
+妞�
+妤�
+姒�
+姒�
+妤�
+妤�
+妤�
+姒�
+妞�
+妤�
+姝�
+纰�
+纰�
+纰�
+鋬�
+纭�
+閯�
+杈�
+榫�
+瑙�
+洌�
+鏆�
+楣�
+悻�
+鏆�
+璺�
+铚�
+铚�
+宓�
+璧�
+楠�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+閿�
+绋�
+绋�
+鋮�
+绛�
+绛�
+绛�
+绛�
+绛�
+鍌�
+楣�
+鍍�
+鑹�
+鑹�
+璋�
+璨�
+鑵�
+鑵�
+鑵�
+椴�
+椴�
+椴�
+洳�
+椴�
+闆�
+鐚�
+椋�
+瑙�
+穰澕
+棣�
+瑁�
+寤�
+鐦�
+鐦�
+閯�
+楣�
+閯�
+楹�
+閯�
+闃�
+鐓�
+鐓�
+鐓�
+鐓�
+鐓�
+鐓�
+婊�
+婧�
+婧�
+婊�
+婊�
+婧�
+婧�
+婕�
+婊�
+婊�
+婊�
+鎰�
+鎱�
+鎱�
+濉�
+瑁�
+绂�
+绂�
+绂�
+绂�
+璋�
+楣�
+鎰�
+瀚�
+濯�
+鎴�
+鎴�
+缂�
+鑰�
+鐟�
+鐟�
+鐟�
+鐟�
+鐟�
+鏂�
+鎽�
+澧�
+澧�
+澧�
+澧�
+鎽�
+閵�
+稹悡
+澧�
+鎾�
+闈�
+闉�
+钄�
+钄�
+钃�
+钄�
+钄�
+鍢�
+姒�
+姒�
+妲�
+穑棆
+妲�
+姒�
+鐤�
+閰�
+閰�
+閰�
+閰�
+纰�
+鋬�
+纰�
+馥敳
+纰�
+纰�
+鍔�
+浯�
+澶�
+鐬�
+楣�
+悻�
+璺�
+铚�
+骞�
+宥�
+鍦�
+皎睆
+閿�
+閿�
+閿�
+閿�
+閿�
+闀�
+闀�
+闀�
+棣�
+楣�
+绠�
+绠�
+鍔�
+鍍�
+鍍�
+鍍�
+鍍�
+妲�
+銠�
+椴�
+椴�
+椴�
+椴�
+椴�
+椴�
+皓骄
+澶�
+鐛�
+椋�
+鍑�
+寤�
+寤�
+鐦�
+鐦�
+鐦�
+椴�
+閯�
+鐔�
+婕�
+婕�
+娼�
+婕�
+娼�
+婕�
+婕�
+憬�
+婕�
+婕�
+婕�
+鎱�
+绐�
+绐�
+惝�
+瑜�
+绂�
+绂�
+闅�
+瀚�
+瀚�
+瀚�
+瀚�
+慊�
+楹�
+鐠�
+婕�
+鍙�
+澧�
+澧�
+澧�
+鍔�
+钖�
+钑�
+钄�
+榧�
+妲�
+楣�
+纾�
+纾�
+娈�
+鎱�
+闇�
+鏆�
+鏆�
+鏆�
+韪�
+韪�
+錀�
+铦�
+铦�
+铦�
+鍣�
+鍣�
+鍣�
+缃�
+宥�
+宥�
+銧�
+宥�
+宥�
+闀�
+闀�
+闀�
+闀�
+闀�
+绋�
+鍎�
+鐨�
+鐨�
+浯�
+鑹�
+鑹�
+楣�
+皓緝
+椴�
+椴�
+椴�
+姗�
+瑙�
+楣�
+楣�
+绯�
+绯�
+缈�
+楣�
+楣�
+鐔�
+娼�
+娼�
+愕�
+婢�
+婢�
+鐟�
+娼�
+娼�
+娼�
+鎲�
+鎲�
+鎴�
+瑜�
+绂�
+瀚�
+閬�
+鐠�
+鐠�
+鐠�
+鎲�
+鎿�
+閯�
+钖�
+闉�
+榛�
+钑�
+钖�
+钑�
+姗�
+姗�
+姗�
+閱�
+瑙�
+纾�
+馥暍
+纾�
+璞�
+楣�
+铏�
+鏆�
+鏇�
+鏇�
+悻�
+韫�
+韪�
+錀�
+铻�
+鐤�
+銧�
+骞�
+宥�
+皎睉
+棣�
+绌�
+绡�
+绡�
+绨�
+榧�
+琛�
+鐩�
+铻�
+绺�
+椴�
+椴�
+椴�
+椴�
+椴�
+浜�
+鐧�
+鐦�
+缇�
+绯�
+鐕�
+鐔�
+鐕�
+鐕�
+鐕�
+婵�
+婵�
+婢�
+婢�
+婢�
+婢�
+婢�
+鎲�
+鎲�
+鎳�
+榛�
+瀣�
+楣�
+缈�
+鐠�
+黏┙
+鐠�
+鐠�
+楂�
+鎿�
+钖�
+钖�
+妾�
+娅�
+妾�
+閱�
+绻�
+纾�
+纾�
+鐬�
+鐬�
+韫�
+锜�
+銟�
+闀�
+闀�
+闀�
+皎睌
+鐭�
+绌�
+绌�
+绌�
+绨�
+绨�
+绨�
+鍎�
+榄�
+鏂�
+鑹�
+璋�
+洳�
+椴�
+椴�
+槌�
+槌�
+槌�
+槌�
+鐛�
+錀�
+棣�
+瑗�
+瑗�
+铻�
+鐢�
+瀣�
+瀣�
+穰垺
+鐡�
+閲�
+楝�
+鐖�
+闉�
+闉�
+钘�
+钘�
+钘�
+楣�
+妾�
+榛�
+绀�
+绀�
+馥枿
+韫�
+韫�
+锜�
+錀�
+鍤�
+楂�
+闀�
+闀�
+閰�
+棣�
+绨�
+绨�
+绨�
+榧�
+榧�
+鐨�
+鑷�
+洳�
+槌�
+槌�
+楣�
+楣�
+鐧�
+穰拲
+鏃�
+缈�
+鍐�
+鋷�
+鐎�
+鐎�
+鐎�
+瑗�
+浯�
+鍤�
+惆�
+楝�
+閱�
+韫�
+锠�
+缈�
+槌�
+鍎�
+鍎�
+榧�
+皓緦
+槌�
+槌�
+楹�
+楹�
+锠�
+褰�
+瀣�
+楝�
+铇�
+娆�
+閱�
+棰�
+鐢�
+皎煚
+宸�
+閰�
+楂�
+鐘�
+皎瓑
+愀�
+鐖�
+鐎�
+鐎�
+鐎�
+鐎�
+瑗�
+瀛�
+楠�
+鑰�
+黏珘
+鐡�
+楝�
+瓒�
+缃�
+榧�
+槌�
+槌�
+槌�
+鐖�
+鐖�
+鐏�
+闊�
+绯�
+铇�
+绀�
+楣�
+韬�
+鐨�
+榫�
+槌�
+浜�
+绫�
+榧�
+鐜�
+閱�
+榻�
+瑙�
+锠�
+瓞
+瓞嚂
+瓞
+瓞槗
+皤瓱
+皤
+皤嚟
+皤悇
+皤捣
+瓞嚈
+瓞!
+皤俯
+皤槣
+瓞槝
+皤槤
+瓞▊
+瓞��
+瓞��
+瓞
+皤崳
+瓞3
+瓞┙
+瓞
+瓞瘈
+皤皼
+瓞车
+瓞扯
+皤爦
+瓞崨
+榭�
+瓞湰
+皙劲
+皙ò
+皤摟
+瓞
+瓞
+瓞
+瓞槨
+瓞辰
+瓞槱
+皤劎
+皙煗
+瓞崵
+皤
+瓞湳
+瓞偐
+皤爢
+瓞寳
+皤憽
+皙ǘ
+瓞
+瓞
+瓞
+瓞
+瓞瓉
+皤⒏
+皤棫
+瓞妶
+瓞拡
+瓞晨
+皤劏
+瓞槴
+皤畠
+榭�
+瓞睎
+瓞熃
+皤摨
+皤煿
+皤熂
+瓞嚬
+瓞崱
+瓞
+皤嵂
+瓞
+皤嵅
+瓞瘞
+瓞槵
+瓞槶
+瓞磦
+皤槮
+皤焻
+瓞槸
+皤槯
+皙;
+瓞儕
+瓞窌
+皤悙
+瓞辜
+皤秶
+皤柈
+榭�
+瓞瓓
+皤摱
+瓞瓗
+皤柉
+瓞睙
+皤洯
+皤贩
+瓞
+瓞姢
+瓞磧
+皤槰
+瓞
+瓞挃
+瓞◣
+皤悡
+皤珖
+皤摴
+瓞瓪
+瓞瓫
+瓞晜
+瓞秼
+瓞秿
+皤敹
+皤寑
+皤柍
+皤槳
+皤槵
+皤灘
+皙
+瓞笜
+瓞挆
+皤殩
+瓞
+皤殨
+瓞稅
+瓞稄
+瓞笟
+瓞
+瓞檪
+瓞
+瓞福
+皤嵔
+瓞磰
+瓞灍
+皤煢
+瓞簣
+皤牅
+皙
+瓞
+瓞
+皤棿
+瓞甫
+皤劮
+瓞
+瓞
+皤攳
+瓞
+瓞
+皤攷
+瓞釜
+瓞稛
+瓞稜
+瓞定
+皤劯
+瓞焷
+瓞檴
+瓞董
+瓞懂
+瓞檵
+瓞簱
+皤毉
+寤�
+钄�
+鍏�
+骞�
+骞�
+铏�
+绾�
+鑸�
+钀�
+闊�
+鍎�
+鍊�
+寤�
+闁�
+缇�
+琛�
+椋�
+缈�
+棣�
+閯�
+璞�
+闁�
+鐒�
+闆�
+灏�
+钘�
+寤�
+鍗�
+姝�
+鏇�
+杌�
+璨�
+宀�
+瑕�
+姘�
+闀�
+鍍�
+骞�
+鍍�
+寰�
+渚�
+鍊�
+棰�
+鐑�
+槌�
+鐖�
+楝�
+鎲�
+瑷�
+瑷�
+瑾�
+璀�
+閱�
+闅�
+杈�
+閯�
+鍕�
+闆�
+鏇�
+鎿�
+鎾�
+绡�
+琛�
+鍘�
+榫�
+婊�
+杌�
+鏉�
+鐩�
+妤�
+鑸�
+甯�
+姝�
+钁�
+闆�
+铏�
+琛�
+闅�
+鍢�
+鍢�
+鍊�
+鍎�
+鍙�
+鐖�
+妯�
+铏�
+榧�
+槌�
+鍕�
+椋�
+楗�
+棣�
+闁�
+铇�
+鍖�
+褰�
+闋�
+婕�
+瀵�
+瑷�
+瀵�
+璁�
+绂�
+瑷�
+璀�
+瑷�
+瑷�
+榻�
+閬�
+閭�
+鐧�
+楂�
+鑱�
+灏�
+鑷�
+棰�
+妾�
+绯�
+绲�
+鍕�
+闉�
+鍩�
+鎿�
+鎺�
+鍫�
+鎻�
+浜�
+妯�
+姗�
+娆�
+閬�
+鍗�
+澹�
+鍘�
+闋�
+瑾�
+濂�
+閬�
+澶�
+杌�
+鍫�
+鍔�
+閭�
+鐣�
+璨�
+甯�
+濉�
+鐣�
+鍣�
+绫�
+鍤�
+锜�
+楹�
+鍦�
+绯�
+鍡�
+宥�
+姝�
+杩�
+璞�
+鍓�
+鍓�
+缍�
+纭�
+閬�
+鍠�
+鍋�
+鍌�
+鍎�
+鍌�
+鍍�
+鍊�
+鑿�
+鍍�
+鍤�
+寰�
+鏈�
+娈�
+闁�
+琛�
+鐖�
+鍌�
+鍓�
+闆�
+璨�
+澹�
+琛�
+濡�
+鑾�
+鎱�
+鍔�
+榻�
+鐢�
+闁�
+鍟�
+闂�
+闂�
+鐕�
+婀�
+鑸�
+璎�
+璜�
+杌�
+瑷�
+瑷�
+瑷�
+璜�
+瑷�
+杈�
+璜�
+瑷�
+瑷�
+瑷�
+灏�
+鐩�
+鍎�
+灏�
+瀛�
+闄�
+闄�
+闅�
+闄�
+濠�
+濯�
+鎴�
+瑙�
+姝�
+璨�
+绱�
+棣�
+绾�
+绺�
+棣�
+绱�
+绱�
+绱�
+棣�
+绱�
+澹�
+楹�
+鐟�
+閫�
+閬�
+閬�
+闊�
+閬�
+鎾�
+澹�
+缃�
+澹�
+鎽�
+鎿�
+璨�
+鍨�
+澹�
+鎽�
+鎺�
+鎼�
+澧�
+璀�
+娈�
+濉�
+鑱�
+鍫�
+鎿�
+钑�
+钁�
+钂�
+鍤�
+铇�
+鍕�
+铇�
+鍥�
+妤�
+妤�
+鍏�
+楹�
+閱�
+鍕�
+閭�
+娈�
+渚�
+閫�
+杌�
+楣�
+婊�
+鍫�
+鏅�
+绺�
+瑁�
+鍢�
+鍦�
+鏇�
+鍦�
+鍣�
+閮�
+鐫�
+鍝�
+鑱�
+鍡�
+鍡�
+褰�
+宥�
+宕�
+甯�
+璨�
+閲�
+閲�
+浜�
+楂�
+鍌�
+寰�
+椁�
+绌�
+閯�
+鑵�
+榫�
+鐚�
+鐙�
+姊�
+宄�
+椋�
+椋�
+淇�
+绻�
+鍑�
+鐙�
+鐣�
+搴�
+鐧�
+鎳�
+閫�
+寤�
+闁�
+闁�
+闁�
+鎮�
+绔�
+鐕�
+鐎�
+娣�
+婊�
+婧�
+婊�
+鐎�
+鎳�
+鎲�
+绐�
+璀�
+鍟�
+瑭�
+瑁�
+璀�
+瑭�
+瑷�
+瑷�
+瑭�
+璀�
+闈�
+灞�
+閬�
+寮�
+闅�
+闄�
+闄�
+澧�
+鍕�
+榉�
+绶�
+椹�
+绱�
+绱�
+缍�
+绱�
+椐�
+绺�
+绱�
+绱�
+绱�
+绱�
+椹�
+绱�
+鐠�
+璨�
+鐝�
+閷�
+瑕�
+鏀�
+鎻�
+鎿�
+闋�
+鎿�
+鍕�
+鏀�
+鎿�
+鎾�
+鎿�
+铇�
+绡�
+鑾�
+妯�
+娅�
+闂�
+楝�
+妲�
+妤�
+妲�
+鍠�
+鐣�
+妫�
+璩�
+楝�
+绀�
+绀�
+纰�
+鍘�
+濂�
+鎱�
+姝�
+姣�
+澹�
+杞�
+闋�
+杞�
+鏂�
+杓�
+杌�
+榻�
+铏�
+鑵�
+璩�
+鍦�
+鏆�
+鍤�
+槌�
+缇�
+骞�
+宥�
+鍑�
+鏁�
+璩�
+璨�
+璨�
+璩�
+璨�
+鍦�
+閲�
+瑁�
+棰�
+淇�
+鍍�
+鍋�
+鍋�
+鎲�
+鍍�
+璨�
+璩�
+寰�
+鎹�
+瑕�
+璨�
+璨�
+鑶�
+鑵�
+鑴�
+楠�
+鑴�
+榄�
+鐛�
+鍌�
+椋�
+椋�
+椋�
+璁�
+榫�
+寤�
+鐦�
+鍔�
+寤�
+闁�
+楝�
+閯�
+鎹�
+鍠�
+鐖�
+娣�
+婵�
+鐎�
+娼�
+婢�
+鎲�
+瀛�
+瀵�
+瀵�
+瀵�
+绨�
+瀵�
+瑭�
+瑭�
+瑾�
+瑗�
+瑕�
+瑭�
+瑾�
+瑭�
+瑭�
+瑭�
+瑭�
+鑲�
+閷�
+闅�
+褰�
+鐎�
+闄�
+椐�
+鍙�
+鑹�
+缍�
+绶�
+绲�
+绱�
+绱�
+椐�
+绻�
+椐�
+绲�
+椐�
+绲�
+椐�
+绱�
+绻�
+缍�
+璨�
+璨�
+骞�
+闋�
+鎸�
+鎾�
+瓒�
+鎿�
+澧�
+鎿�
+鎻�
+钖�
+甯�
+绻�
+钑�
+姒�
+钁�
+鐔�
+楝�
+钄�
+钘�
+妯�
+妫�
+妫�
+娆�
+妾�
+妯�
+楣�
+纾�
+纭�
+楹�
+鐗�
+榉�
+娈�
+杌�
+杓�
+榇�
+鎴�
+榛�
+鑷�
+瑕�
+绔�
+鍢�
+鍟�
+椤�
+璨�
+铦�
+锜�
+铻�
+闆�
+椐�
+鍕�
+鍢�
+闊�
+鍠�
+宄�
+缃�
+璩�
+璨�
+璨�
+閳�
+閳�
+閳�
+閸�
+閻�
+閶�
+閳�
+閼�
+娆�
+閳�
+閳�
+閳�
+姘�
+姘�
+閬�
+閬�
+绋�
+闉�
+寰�
+瑜�
+鍊�
+璨�
+闋�
+鍎�
+闋�
+楝�
+鍔�
+鏈�
+鑶�
+鍕�
+鐙�
+鐛�
+鐛�
+鐛�
+璨�
+椁�
+楗�
+铦�
+椁�
+椁�
+宸�
+褰�
+灏�
+濂�
+鐦�
+鐦�
+瑕�
+闁�
+鑱�
+闁�
+闁�
+闁�
+椁�
+钖�
+椤�
+濠�
+绺�
+鐓�
+鐖�
+鐖�
+绐�
+娼�
+鐏�
+婢�
+婵�
+娓�
+鐎�
+婵�
+娓�
+婵�
+鎯�
+鑸�
+瑕�
+鎲�
+绔�
+瑾�
+瑾�
+瑾�
+瑗�
+瑾�
+瑾�
+瑾�
+瑾�
+瑾�
+澧�
+鏅�
+璨�
+閬�
+闅�
+闅�
+瀣�
+璩�
+澹�
+缍�
+绲�
+绲�
+绻�
+椹�
+绻�
+绲�
+绲�
+椐�
+绲�
+绲�
+绲�
+椐�
+绲�
+鑹�
+锠�
+闋�
+鐩�
+鎾�
+杓�
+瓒�
+楣�
+鎼�
+鎾�
+鎽�
+鍓�
+鐔�
+鎼�
+澹�
+鑱�
+钀�
+钃�
+鐛�
+绌�
+鎯�
+鍣�
+鐟�
+槎�
+妾�
+姗�
+妯�
+妯�
+妯�
+璩�
+绀�
+绀�
+椤�
+杞�
+杓�
+闋�
+鏂�
+绶�
+鎱�
+鐩�
+绶�
+榛�
+鏇�
+鏇�
+鍢�
+榇�
+鏆�
+榇�
+缃�
+鍦�
+璩�
+璩�
+璩�
+璐�
+閷�
+閴�
+閼�
+閴�
+閻�
+閳�
+閴�
+鐘�
+鏁�
+绌�
+绋�
+绛�
+鍌�
+鍌�
+璩�
+鑹�
+鑹�
+鑱�
+鎰�
+闋�
+闋�
+鑷�
+楂�
+鑷�
+鑶�
+鑵�
+鑶�
+榇�
+榇�
+鐨�
+椁�
+椁�
+鎴�
+妲�
+婕�
+婧�
+鐧�
+榻�
+闆�
+璩�
+绔�
+闁�
+鐓�
+鐕�
+鐕�
+閬�
+婵�
+婢�
+娓�
+濉�
+婊�
+娼�
+婢�
+婕�
+鐕�
+婢�
+鎲�
+瀵�
+鍌�
+璩�
+绔�
+璜�
+璜�
+璜�
+璁�
+瑾�
+瑗�
+瑾�
+瑾�
+瑾�
+璜�
+璜�
+璜�
+瑾�
+鎳�
+鍔�
+闆�
+闋�
+绲�
+缍�
+椹�
+绻�
+椐�
+鐟�
+鎿�
+鎿�
+鎽�
+鑱�
+铇�
+铻�
+鐕�
+钑�
+钖�
+澶�
+妾�
+閱�
+纰�
+鑱�
+瑗�
+杓�
+杓�
+椤�
+鎳�
+韬�
+绾�
+鍥�
+鍢�
+宥�
+閭�
+瀣�
+閵�
+閻�
+閶�
+閵�
+閵�
+閺�
+閵�
+鐭�
+绌�
+绫�
+鍎�
+杌�
+閲�
+閵�
+鐩�
+榇�
+鏂�
+闋�
+鑷�
+鐛�
+椁�
+椁�
+鐧�
+閺�
+闁�
+闂�
+钃�
+鏂�
+鐛�
+榇�
+婕�
+娣�
+婕�
+婢�
+婊�
+鎱�
+鎳�
+椹�
+鎱�
+鎱�
+璎�
+璜�
+璎�
+璜�
+绂�
+绂�
+璎�
+璜�
+璎�
+褰�
+澧�
+闅�
+闅�
+瀣�
+闋�
+闋�
+绺�
+绶�
+绾�
+楱�
+缍�
+绻�
+缍�
+缍�
+缍�
+缍�
+缍�
+缍�
+绶�
+缍�
+鐡�
+瓒�
+鏀�
+鏀�
+鎿�
+鎽�
+鏀�
+鑱�
+钄�
+闊�
+姗�
+纰�
+闋�
+闈�
+鏆�
+缈�
+杓�
+閼�
+杓�
+璩�
+鐫�
+鍣�
+鐤�
+韪�
+閬�
+榈�
+璩�
+璩�
+璐�
+璩�
+璩�
+閼�
+閶�
+閺�
+閵�
+閹�
+閶�
+閸�
+閵�
+閶�
+閶�
+閶�
+榈�
+绡�
+绡�
+鍎�
+鎳�
+绂�
+閲�
+鑷�
+榄�
+鎲�
+楗�
+楗�
+瑁�
+锠�
+闂�
+绯�
+婊�
+婵�
+娼�
+婵�
+鐏�
+鎲�
+绔�
+绐�
+瑜�
+绂�
+璎�
+璎�
+璎�
+璎�
+灞�
+灞�
+绶�
+绾�
+绶�
+绶�
+绶�
+绶�
+绺�
+楱�
+绶�
+楱�
+绶�
+榈�
+鏀�
+鎿�
+瑗�
+鏀�
+榈�
+钘�
+婵�
+鎳�
+鐭�
+鐛�
+娆�
+妯�
+璩�
+绀�
+灏�
+闇�
+杓�
+杓�
+杓�
+闋�
+榻�
+閼�
+韫�
+铦�
+閷�
+閷�
+閷�
+閼�
+閷�
+閷�
+閷�
+閸�
+閶�
+閷�
+杈�
+闋�
+绫�
+绨�
+绫�
+绨�
+鑶�
+榈�
+楱�
+楫�
+绌�
+瑙�
+闆�
+楗�
+椁�
+閱�
+璎�
+绯�
+鏁�
+婊�
+婵�
+婵�
+鐏�
+婵�
+鐏�
+璀�
+绐�
+瀵�
+璎�
+璎�
+闂�
+绺�
+绺�
+绾�
+绻�
+璐�
+澧�
+琛�
+钘�
+妾�
+閲�
+椤�
+杞�
+杓�
+椤�
+韪�
+锠�
+锠�
+锜�
+璩�
+閸�
+閸�
+閸�
+绌�
+绫�
+绨�
+杓�
+楫�
+楗�
+鐎�
+璩�
+璀�
+璀�
+楱�
+绺�
+鏀�
+鑱�
+钘�
+娅�
+椋�
+榛�
+鐬�
+椤�
+鍥�
+閹�
+閹�
+閹�
+绨�
+榀�
+榀�
+鐧�
+鐧�
+椤�
+榀�
+鐎�
+椤�
+璀�
+槎�
+绻�
+椤�
+杞�
+楦�
+璐�
+閺�
+璐�
+绫�
+绫�
+榀�
+鐧�
+杈�
+鐎�
+鎳�
+绻�
+绻�
+鐭�
+璐�
+榘�
+杈�
+璐�
+椹�
+鍥�
+閻�
+榘�
+榉�
+宸�
+椤�
+鐧�
+楸�
+楝�
+楸�
+韬�
+璐�
+閼�
+闊�
+闁�
+瑷�
+鍕�
+鑺�
+閯�
+瑷�
+瑷�
+瑷�
+瑷�
+棣�
+鐠�
+澹�
+鎹�
+钖�
+鍘�
+閲�
+鍌�
+鍊�
+鍌�
+鐛�
+鐛�
+槌�
+閯�
+椁�
+鎳�
+璎�
+瑭�
+瑷�
+绱�
+绱�
+绱�
+绱�
+鐠�
+鎽�
+濉�
+悌�
+钑�
+钘�
+鑾�
+钀�
+钃�
+纾�
+濂�
+姝�
+杌�
+閯�
+鍢�
+鍥�
+鍤�
+鏆�
+鍞�
+骞�
+宄�
+宓�
+鍦�
+閲�
+閲�
+閲�
+鍍�
+槌�
+閯�
+椋�
+椁�
+椋�
+椋�
+椋�
+寤�
+鐧�
+闂�
+闁�
+闁�
+鐓�
+鐏�
+婕�
+娓�
+娼�
+鎲�
+鎱�
+鎰�
+鎮�
+鎰�
+瑭�
+瑷�
+瑭�
+瑭�
+璎�
+瑭�
+瑭�
+闅�
+闄�
+瀚�
+瀚�
+瀣�
+鍓�
+绱�
+绱�
+绱�
+缍�
+绱�
+鐟�
+鍖�
+澹�
+鎿�
+铇�
+钄�
+濉�
+鐓�
+娅�
+姊�
+妫�
+妯�
+纰�
+鐢�
+閮�
+杌�
+槌�
+鏇�
+锜�
+榛�
+鍤�
+鍣�
+宸�
+鍔�
+鍓�
+宥�
+閲�
+閲�
+閲�
+閲�
+閲�
+閲�
+鍎�
+鍎�
+鍎�
+鍔�
+鎱�
+绯�
+鎴�
+鑶�
+閭�
+姊�
+椁�
+椋�
+鐧�
+鐦�
+鐓�
+鐔�
+鐔�
+鐎�
+鐎�
+婵�
+娑�
+悭�
+鎳�
+瑾�
+瑾�
+瑭�
+瑭�
+瑭�
+閯�
+绂�
+瑾�
+瑭�
+瑭�
+瑭�
+瑭�
+璜�
+瑭�
+璜�
+瑭�
+椐�
+绱�
+绱�
+绱�
+椐�
+椐�
+绺�
+绲�
+椹�
+椐�
+鐡�
+闋�
+鍩�
+鎾�
+鎾�
+璩�
+澹�
+鎾�
+鑾�
+璨�
+钃�
+钑�
+钖�
+钖�
+鍫�
+婊�
+鐘�
+钑�
+钘�
+钃�
+钑�
+钁�
+娅�
+娅�
+娅�
+娅�
+妾�
+閰�
+纭�
+纰�
+娈�
+杌�
+杌�
+杞�
+杌�
+杌�
+锠�
+瑕�
+鐬�
+鍢�
+鍡�
+鍣�
+鍓�
+閯�
+鍣�
+鍣�
+宥�
+骞�
+宥�
+璨�
+閳�
+閳�
+閶�
+閳�
+閳�
+閹�
+閳�
+閳�
+绡�
+鍎�
+鍎�
+鍎�
+鑵�
+鑷�
+鑴�
+榇�
+鐛�
+棰�
+鐚�
+椁�
+椁�
+椁�
+瀛�
+瀛�
+鐧�
+鐦�
+棰�
+闂�
+闁�
+闂�
+闁�
+鐔�
+鐑�
+娴�
+婢�
+婊�
+娼�
+婵�
+鎱�
+鎳�
+鎰�
+鎯�
+鎯�
+瑾�
+绂�
+瑾�
+瑾�
+榇�
+濠�
+瀣�
+鎳�
+绲�
+椹�
+椹�
+绲�
+绲�
+椐�
+闋�
+鐠�
+鐞�
+濉�
+濉�
+鍫�
+璐�
+钂�
+钀�
+钑�
+榇�
+钂�
+姗�
+妤�
+姒�
+妾�
+閭�
+绀�
+绀�
+杌�
+杓�
+杓�
+槎�
+韬�
+榻�
+楦�
+鐭�
+鍢�
+榇�
+铚�
+鍡�
+宥�
+宕�
+瑕�
+璩�
+閳�
+閴�
+閳�
+閴�
+閳�
+閴�
+閴�
+閴�
+閳�
+閳�
+閴�
+閼�
+閴�
+閳�
+閴�
+閴�
+閴�
+閳�
+閳�
+閺�
+閻�
+姘�
+绛�
+闋�
+寰�
+鑶�
+榇�
+鐠�
+榇�
+鐛�
+瑁�
+椁�
+娆�
+鏀�
+鐧�
+鐥�
+闋�
+闁�
+楝�
+瑾�
+闁�
+閯�
+鐕�
+鐕�
+鐕�
+娣�
+婕�
+娼�
+鎱�
+璜�
+璜�
+绂�
+璜�
+璜�
+璜�
+璜�
+瑾�
+濯�
+瀚�
+缍�
+椹�
+缍�
+楱�
+缍�
+绺�
+缍�
+椐�
+榉�
+鐕�
+鐠�
+楹�
+鎿�
+鎽�
+榉�
+鎾�
+鎱�
+鎽�
+绺�
+妲�
+瑕�
+娆�
+鍡�
+鍖�
+纭�
+纾�
+榇�
+榫�
+娈�
+娈�
+璩�
+杓�
+濉�
+鍢�
+鍥�
+鍤�
+韫�
+锠�
+锠�
+锜�
+骞�
+骞�
+璩�
+璩�
+璩�
+閵�
+閴�
+閶�
+閻�
+閵�
+閹�
+閸�
+閵�
+閵�
+閶�
+閺�
+閵�
+閹�
+閴�
+閵�
+閴�
+閷�
+閵�
+閴�
+閵�
+閵�
+閵�
+閵�
+榇�
+绌�
+绠�
+绫�
+鍍�
+鍍�
+鐨�
+榇�
+鑹�
+榫�
+鐜�
+鐛�
+椁�
+椁�
+楦�
+闂�
+闁�
+闁�
+闁�
+楝�
+闁�
+闁�
+缇�
+绯�
+鐕�
+婕�
+鐎�
+婢�
+鎰�
+鎲�
+璜�
+璜�
+鐨�
+璎�
+瑗�
+璎�
+璜�
+璜�
+璜�
+璁�
+璜�
+璜�
+璜�
+绯�
+瀣�
+缍�
+楱�
+缍�
+绶�
+绶�
+楱�
+绶�
+楱�
+缍�
+缍�
+缍�
+缍�
+椹�
+绶�
+闈�
+杓�
+榛�
+闋�
+鎾�
+锜�
+澹�
+钄�
+娅�
+娆�
+璩�
+榈�
+楦�
+娈�
+杓�
+杓�
+妲�
+杓�
+杓�
+鐬�
+韬�
+铔�
+锜�
+铻�
+锠�
+鍢�
+宥�
+宥�
+璩�
+閶�
+閷�
+閺�
+閶�
+閶�
+閶�
+閶�
+閵�
+閻�
+閵�
+閶�
+閶�
+閷�
+鐘�
+榈�
+绡�
+鐗�
+鍎�
+鍎�
+鍎�
+瀣�
+闋�
+榈�
+榄�
+榄�
+榄�
+娼�
+棰�
+瑙�
+鐔�
+椁�
+椁�
+瑜�
+鑷�
+鐧�
+鐧�
+璩�
+闋�
+榉�
+闂�
+闂�
+闂�
+榈�
+鎲�
+鍤�
+璎�
+瑜�
+瑗�
+璁�
+璎�
+璎�
+璎�
+楱�
+宸�
+缈�
+楱�
+绶�
+绶�
+绶�
+绶�
+绶�
+绶�
+绶�
+绺�
+绶�
+楗�
+鑰�
+椹�
+闊�
+鏀�
+鎿�
+杞�
+椹�
+槎�
+钖�
+铇�
+閹�
+闋�
+娅�
+娅�
+纾�
+纾�
+榈�
+杓�
+榻�
+榻�
+闊�
+鍥�
+韬�
+韫�
+韬�
+韬�
+鍣�
+閸�
+閷�
+閷�
+閸�
+閷�
+閷�
+閷�
+閸�
+閷�
+閷�
+閷�
+瑕�
+闋�
+楫�
+楫�
+楫�
+楸�
+绌�
+楫�
+楫�
+榈�
+棰�
+楗�
+槎�
+鐦�
+闂�
+闂�
+闂�
+鐏�
+鐎�
+娼�
+鐏�
+婢�
+鎳�
+楸�
+楱�
+绔�
+璎�
+璎�
+瀣�
+瀣�
+绺�
+绺�
+绺�
+杞�
+楱�
+绺�
+绺�
+绺�
+绺�
+楱�
+瑕�
+闊�
+闈�
+鏀�
+钖�
+钘�
+槎�
+妾�
+娅�
+閲�
+娈�
+闇�
+杞�
+榻�
+榻�
+鐬�
+鏇�
+韬�
+锜�
+槎�
+鍤�
+缇�
+璩�
+缃�
+槎�
+閸�
+閸�
+閸�
+閸�
+閸�
+閺�
+閹�
+閺�
+绨�
+绡�
+绨�
+绫�
+鑷�
+楫�
+楫�
+楸�
+楫�
+楸�
+楗�
+閼�
+鐦�
+闂�
+楫�
+绯�
+榉�
+鐎�
+婵�
+璀�
+瑜�
+璀�
+璁�
+璀�
+槎�
+瀣�
+槎�
+椹�
+绺�
+绺�
+绺�
+绾�
+椹�
+绻�
+绻�
+鑰�
+鐡�
+鎿�
+鎿�
+鏀�
+鑱�
+瑕�
+闊�
+闉�
+铇�
+璩�
+妾�
+闈�
+榄�
+楗�
+杞�
+榻�
+榻�
+瑕�
+椤�
+韬�
+韬�
+锠�
+铻�
+椤�
+鍤�
+椤�
+閼�
+閹�
+閹�
+閹�
+閹�
+閹�
+閹�
+閼�
+绨�
+榉�
+榀�
+楸�
+榘�
+榘�
+榘�
+榀�
+榀�
+瑙�
+楗�
+楗�
+榻�
+璁�
+瑗�
+璀�
+灞�
+绾�
+绻�
+绻�
+椹�
+鎿�
+椤�
+椤�
+钘�
+娅�
+娅�
+璐�
+椋�
+閺�
+杞�
+锜�
+閻�
+閺�
+閺�
+閺�
+閺�
+閺�
+閺�
+閺�
+閺�
+姘�
+绌�
+榄�
+榀�
+榀�
+榀�
+榀�
+榀�
+榀�
+榀�
+榀�
+鐛�
+榉�
+璐�
+鐧�
+鏂�
+鐎�
+椤�
+绻�
+绻�
+绻�
+铇�
+榉�
+榻�
+榻�
+韬�
+韫�
+缇�
+閻�
+閻�
+閻�
+閻�
+閼�
+閼�
+閺�
+閻�
+绫�
+榉�
+楸�
+榘�
+榀�
+榘�
+榘�
+榘�
+榀�
+榉�
+鎳�
+榉�
+榘�
+闊�
+椤�
+榉�
+浯�
+楂�
+閼�
+閻�
+閻�
+璁�
+榘�
+榘�
+榘�
+鐧�
+鏀�
+闈�
+韬�
+楂�
+楂�
+閼�
+绫�
+榘�
+榘�
+楸�
+榘�
+楸�
+璁�
+椹�
+绾�
+鐡�
+榧�
+榛�
+榛�
+閼�
+閼�
+鑷�
+楸�
+楸�
+楸�
+椹�
+椤�
+楸�
+鐧�
+鐏�
+楦�
+閼�
+瓒�
+椤�
+韬�
+楗�
+鎴�
+鎴�
+瑷�
+瑷�
+閲�
+淇�
+闁�
+婢�
+瑷�
+瑷�
+瑭�
+绱�
+绾�
+鐟�
+鍓�
+濉�
+澹�
+鍩�
+鎾�
+钄�
+姒�
+杌�
+杌�
+鍜�
+銧�
+瑕�
+銘�
+棰�
+闁�
+娼�
+婀�
+婢�
+娴�
+璜�
+绂�
+瑭�
+瑭�
+瑭�
+灞�
+褰�
+绱�
+棣�
+棣�
+绱�
+绱�
+椐�
+绱�
+鐟�
+钖�
+妫�
+杌�
+鏆�
+鏅�
+宕�
+閲�
+閲�
+閸�
+閸�
+閯�
+鐛�
+椋�
+宥�
+瑭�
+瑭�
+閯�
+槌�
+闅�
+闅�
+濞�
+閫�
+椐�
+椐�
+椐�
+绲�
+楱�
+洚�
+绱�
+绱�
+鐡�
+闊�
+澧�
+濉�
+钖�
+钑�
+钄�
+钁�
+槌�
+榫�
+杌�
+杌�
+杞�
+杌�
+鐫�
+鏇�
+鍣�
+閳�
+閳�
+閴�
+閶�
+閲�
+閷�
+閳�
+閳�
+閳�
+鍊�
+鑹�
+槎�
+棰�
+椁�
+婀�
+婧�
+婊�
+瑜�
+绲�
+椐�
+绲�
+椐�
+缍�
+缍�
+椹�
+鍕�
+鐠�
+稹憤
+鋼�
+钖�
+钘�
+妞�
+姊�
+闋�
+纭�
+杓�
+杓�
+杓�
+璨�
+鍡�
+鏇�
+鏆�
+閯�
+骞�
+杓�
+宥�
+璐�
+閴�
+閴�
+閼�
+閴�
+閴�
+閴�
+鍍�
+榇�
+榄�
+椁�
+鐕�
+婧�
+绀�
+绐�
+瑗�
+椐�
+绲�
+缍�
+楱�
+缍�
+鐠�
+澧�
+澹�
+鑱�
+铇�
+鍕�
+缃�
+妾�
+妫�
+鍘�
+鋬�
+纾�
+绀�
+榇�
+榻�
+闋�
+寤�
+鍑�
+浜�
+鏋�
+灞�
+鍖�
+鍖�
+绱�
+绱�
+鐤�
+娈�
+璁�
+瑙�
+鍏�
+瀹�
+銜�
+銧�
+鏍�
+浣�
+浣�
+鍛�
+鏁�
+鍐�
+鍧�
+鍍�
+鎬�
+鎮�
+鍐�
+澶�
+鎴�
+鐗�
+濡�
+瀣�
+鎽�
+閲�
+鏀�
+瑷�
+琛�
+琛�
+寮�
+鍠�
+鍥�
+銧�
+棰�
+绉�
+鍊�
+楂�
+浣�
+鏈�
+姘�
+姹�
+浣�
+涓�
+绔�
+姹�
+姹�
+鐣�
+濮�
+寤�
+鎸�
+琛�
+鎼�
+闃�
+鎾�
+鍩�
+闃�
+瑾�
+銜�
+鍗�
+鍒�
+鍒�
+鍒�
+鑺�
+铇�
+妗�
+妲�
+鑽�
+鐛�
+鍞�
+鑴�
+鐨�
+褰�
+楂�
+鐤�
+鍒�
+閴�
+閼�
+娉�
+鐗�
+鎭�
+妫�
+娲�
+姹�
+鐏�
+鐑�
+鑿�
+绂�
+渚�
+璺�
+鍧�
+鐜�
+濮�
+濡�
+缈�
+鎼�
+鏌�
+鎷�
+鐗�
+瑙�
+鍊�
+鎶�
+鐩�
+妗�
+鍌�
+閫�
+鑲�
+鑿�
+宕�
+宕�
+鍛�
+铏�
+鍢�
+璎�
+瑭�
+銦�
+宓�
+宸�
+宸�
+闆�
+绋�
+鍜�
+宥�
+濡�
+濮�
+寤�
+寰�
+椁�
+鎺�
+瀵�
+鍞�
+閫�
+鏄�
+鍏�
+鸠爮
+浜�
+浜�
+錁�
+娣�
+鍔�
+鍖�
+愠�
+鐏�
+娲�
+闇�
+娣�
+瑷�
+鎭�
+绠�
+灞�
+绲�
+鍦�
+鏃�
+鐝�
+鎺�
+鍨�
+鑹�
+鑼�
+鏌�
+鏍�
+鏌�
+鏍�
+妗�
+鏌�
+闊�
+鎻�
+鏄�
+闁�
+楝�
+鍐�
+鏆�
+鍤�
+鍊�
+馉窗
+鍋�
+鍠�
+榻�
+娆�
+姒�
+銘�
+鍎�
+鏁�
+鏁�
+鑲�
+鑴�
+錁�
+琛�
+璺�
+韫�
+鐮�
+绀�
+钖�
+楝�
+鎭�
+鎬�
+鍗�
+錁�
+璩�
+濠�
+鐣�
+鎻�
+缍�
+杓�
+鎭�
+韬�
+鏅�
+妫�
+瑕�
+鎱�
+缈�
+鑴�
+妲�
+悒�
+铻�
+锜�
+悚�
+闄�
+宄�
+宄�
+涔�
+妞�
+鍜�
+绛�
+淇�
+闋�
+鍕�
+錉�
+韬�
+鎱�
+鎷�
+悃�
+鎸�
+鑴�
+鑳�
+鑲�
+璨�
+憬�
+鐣�
+娣�
+鎮�
+钃�
+鍔�
+鍌�
+娑�
+缂�
+鑿�
+鐓�
+娣�
+婀�
+瑾�
+鐚�
+閱�
+璁�
+銤�
+瀵�
+瀛�
+妗�
+姣�
+鐟�
+鐠�
+鐟�
+悒�
+鎼�
+鎼�
+钄�
+鎯�
+妤�
+妲�
+鎹�
+寤�
+鎱�
+鎱�
+鐬�
+鍩�
+鐣�
+铏�
+绋�
+妫�
+鐘�
+杩�
+濯�
+鍏�
+鑸�
+鎱�
+缍�
+鑵�
+皓搻
+澶�
+璞�
+璨�
+婀�
+娓�
+搴�
+钄�
+鑿�
+鏈�
+鐫�
+瑙�
+楹�
+閲�
+閵�
+鐥�
+娈�
+濠�
+婊�
+婀�
+愦�
+妯�
+椤�
+銤�
+绐�
+绐�
+鐞�
+娆�
+澧�
+瓒�
+闅�
+鎰�
+鎻�
+鎻�
+鐓�
+鏈�
+悛�
+濉�
+钄�
+钄�
+绋�
+妫�
+纰�
+妞�
+鍋�
+銜�
+寤�
+寤�
+榇�
+鍐�
+銤�
+鏅�
+榧�
+椁�
+椁�
+鍡�
+璜�
+恪�
+璩�
+绛�
+绛�
+绛�
+鏍�
+鏆�
+鐨�
+韪�
+铦�
+悛�
+鐕�
+閬�
+濯�
+鍢�
+搴�
+绐�
+鐗�
+鐗�
+绐�
+寰�
+鍍�
+甯�
+瑁�
+寮�
+褰�
+鐤�
+澹�
+鐡�
+浒�
+鐨�
+鎿�
+悌�
+悌�
+鏀�
+鎳�
+闉�
+骞�
+惝�
+閰�
+瑭�
+閱�
+鎺�
+韪�
+慵�
+鐩�
+纾�
+瑕�
+鍊�
+悻�
+鐓�
+鐓�
+鏅�
+闂�
+鐐�
+璺�
+錀�
+锠�
+瀵�
+杈�
+绋�
+绌�
+鐕�
+璀�
+鐦�
+鐧�
+椤�
+楠�
+鐚�
+铦�
+绋�
+鐥�
+鐧�
+浜�
+恽�
+闊�
+娉�
+閬�
+鏄�
+韬�
+鑷�
+缇�
+悻�
+鏇�
+鐤�
+鍕�
+鐞�
+鐡�
+黏嫯
+鐔�
+鐗�
+鎼�
+璎�
+鍫�
+楣�
+楣�
+鐭�
+鐕�
+楂�
+黏亥
+杈�
+鏃�
+稹殎
+娼�
+鐮�
+瑭�
+瀚�
+娅�
+鎾�
+澧�
+璀�
+闉�
+闉�
+钑�
+姗�
+铇�
+閱�
+璀�
+璺�
+韫�
+铚�
+锠�
+绋�
+娈�
+鎯�
+鍘�
+瑗�
+鐧�
+鋳�
+椁�
+娼�
+鐧�
+椤�
+榉�
+钘�
+娅�
+铻�
+韫�
+锜�
+璀�
+绨�
+褰�
+鐞�
+榈�
+椁�
+椁�
+绨�
+绮�
+鐕�
+绶�
+骞�
+韫�
+绮�
+绌�
+鑷�
+绫�
+绻�
+椋�
+瀛�
+锠�
+鐕�
+铦�
+绋�
+绌�
+鎯�
+瑕�
+閼�
+鎴�
+闃�
+鍓�
+甯�
+宸�
+浜�
+浣�
+绔�
+绌�
+宀�
+铏�
+穰崙
+缇�
+鍟�
+濮�
+銟�
+琚�
+琚�
+閫�
+銙�
+鐘�
+姘�
+鍋�
+鐢�
+缃�
+鍐�
+濮�
+铦�
+鐞�
+鐟�
+灏�
+姊�
+鏂�
+鏂�
+鏂�
+鏆�
+姣�
+铦�
+鍚�
+鍝�
+宄�
+绮�
+绔�
+鐙�
+绉�
+鐑�
+愠�
+琚�
+鐩�
+娑�
+钂�
+纰�
+锠�
+鍞�
+鍊�
+鍎�
+闆�
+鐨�
+鑷�
+琛�
+涠�
+鑷�
+鐛�
+鐥�
+鐨�
+婀�
+婢�
+婵�
+濉�
+瑗�
+濞�
+鍕�
+鍕�
+鎴�
+寤�
+寤�
+鐪�
+瑕�
+鍕�
+鍟�
+鍣�
+鍌�
+鎸�
+悭�
+鎯�
+鎱�
+闄�
+钑�
+钀�
+钑�
+铇�
+钘�
+娅�
+绠�
+妲�
+鍟�
+韫�
+铓�
+鐥�
+铔�
+铚�
+鐦�
+閬�
+閱�
+椋�
+鍐�
+绨�
+鏋�
+鏌�
+妾�
+妤�
+鐭�
+妞�
+鍢�
+鐛�
+绮�
+鋱�
+璜�
+榻�
+鍫�
+鐤�
+闆�
+绉�
+绋�
+妲�
+鎼�
+寤�
+鍙�
+鍢�
+铚�
+绛�
+绡�
+楹�
+绯�
+绶�
+鐠�
+楂�
+鑷�
+椁�
+鍓�
+姗�
+缃�
+铚�
+鐭�
+鎲�
+缈�
+楗�
+鐬�
+缇�
+缇�
+鐖�
+绻�
+楱�
+楝�
+楱�
+钄�
+錉�
+绨�
+韬�
+韫�
+錆�
+璨�
+榧�
+楹�
+濉�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銇�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銈�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銈�
+銈�
+銈�
+銈�
+銈�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+銉�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锞�
+锝�
+锞�
+锞�
+锞�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+鍐�
+姘�
+绯�
+绲�
+妤�
+甯�
+鎴�
+搴�
+榛�
+鍥�
+绶�
+瑾�
+澹�
+姝�
+姣�
+浜�
+鎮�
+鍦�
+鎵�
+鍥�
+鐐�
+澹�
+闅�
+鏍�
+鍠�
+椐�
+濉�
+绺�
+鑹�
+蹇�
+妗�
+绌�
+浠�
+渚�
+绠�
+銈�
+銈�
+銈�
+銉�
+銉�
+銏�
+涓�
+涓�
+涓�
+浜�
+浠�
+浼�
+渚�
+淇�
+鍊�
+鍊�
+鍊�
+鍋�
+鍋�
+鍍�
+鍎�
+鍏�
+鍏�
+鍐�
+鍐�
+鍑�
+鍑�
+鍑�
+鍒�
+鍓�
+鍓�
+鍓�
+鍔�
+鍔�
+鍕�
+鍕�
+鍖�
+鍖�
+鍖�
+鍗�
+鍗�
+鍘�
+鍙�
+鍛�
+鍛�
+鍛�
+鍛�
+鍞�
+鍠�
+鍠�
+鍠�
+鍣�
+鍣�
+鍤�
+鍥�
+鍥�
+鍦�
+鍦�
+鍫�
+鍫�
+濉�
+濉�
+濉�
+澧�
+澧�
+澹�
+澹�
+澹�
+澶�
+濂�
+濮�
+濞�
+瀚�
+瀣�
+瀣�
+瀛�
+瀹�
+瀹�
+瀹�
+瀵�
+瀵�
+瀵�
+灏�
+灏�
+宄�
+宕�
+宥�
+宸�
+宸�
+宸�
+宸�
+甯�
+骞�
+搴�
+寤�
+寤�
+寮�
+寮�
+寮�
+寮�
+寮�
+寰�
+寰�
+寰�
+蹇�
+鎭�
+鎮�
+鎯�
+鎳�
+鎳�
+鎴�
+鎴�
+鎴�
+鎵�
+鎶�
+鎶�
+鎷�
+鎷�
+鎷�
+鎷�
+鎸�
+鎸�
+鎹�
+鎹�
+鎺�
+鎺�
+鎺�
+鎻�
+鎻�
+鎻�
+鎽�
+鎾�
+鎾�
+鏂�
+鏂�
+鏃�
+鏃�
+鏅�
+鏅�
+鏆�
+鏆�
+鏇�
+鏉�
+鏉�
+鏉�
+鏉�
+鏋�
+鏋�
+鏋�
+鏌�
+鏍�
+鏍�
+妗�
+妗�
+妗�
+姊�
+姊�
+姊�
+姊�
+妞�
+妞�
+妞�
+妤�
+妤�
+妤�
+姒�
+姒�
+妲�
+妲�
+妲�
+妲�
+妯�
+妯�
+妯�
+姗�
+妾�
+娆�
+姝�
+姝�
+姝�
+姝�
+姝�
+姣�
+娌�
+娌�
+娴�
+娑�
+娓�
+娓�
+娓�
+娓�
+娓�
+婧�
+婊�
+婕�
+娼�
+婢�
+鐎�
+鐎�
+鐒�
+鐒�
+鐓�
+鐓�
+鐓�
+鐕�
+鐖�
+鐘�
+鐙�
+鐚�
+鐛�
+鐛�
+鐝�
+鐟�
+鐢�
+鐣�
+鐣�
+鐣�
+鐣�
+鐣�
+鐥�
+鐧�
+鐧�
+鐪�
+鐪�
+鐮�
+纰�
+绀�
+绂�
+绂�
+绋�
+绌�
+绌�
+绔�
+绔�
+绔�
+绗�
+绛�
+绛�
+绛�
+绠�
+绠�
+绠�
+绡�
+绡�
+绨�
+绫�
+绮�
+绮�
+绮�
+绮�
+绯�
+绱�
+绲�
+绲�
+绲�
+绲�
+绲�
+缍�
+缍�
+缍�
+绶�
+绺�
+绺�
+绺�
+绺�
+绻�
+绻�
+绻�
+绻�
+绻�
+绾�
+绾�
+缃�
+缃�
+缃�
+缇�
+缇�
+缇�
+鑱�
+鑱�
+鑱�
+鑱�
+鑴�
+鑴�
+鑶�
+鑶�
+鑷�
+鑷�
+鑷�
+鑸�
+鑸�
+鑸�
+鑸�
+鑺�
+鑻�
+鑼�
+鑽�
+鑽�
+鑾�
+鑾�
+鑿�
+钀�
+钄�
+钖�
+钖�
+钖�
+钖�
+铇�
+铔�
+铦�
+铦�
+锜�
+琛�
+琛�
+琚�
+琚�
+琚�
+琚�
+琚�
+瑁�
+瑁�
+瑁�
+瑜�
+瑜�
+瑗�
+瑗�
+瑕�
+瑕�
+瑕�
+瑕�
+瑷�
+瑷�
+璜�
+璜�
+璜�
+璜�
+璜�
+璀�
+璀�
+璁�
+璞�
+璞�
+璞�
+璩�
+璩�
+璐�
+韬�
+韬�
+杌�
+杌�
+杓�
+杈�
+杈�
+杈�
+杈�
+閫�
+閬�
+閬�
+閭�
+閮�
+閰�
+閱�
+閱�
+閱�
+閲�
+閴�
+閴�
+閴�
+閴�
+閴�
+閵�
+閵�
+閵�
+閶�
+閶�
+閶�
+閷�
+閷�
+閷�
+閷�
+閷�
+閸�
+閸�
+閸�
+閹�
+閹�
+閹�
+閹�
+閻�
+閻�
+閻�
+閼�
+閼�
+閼�
+閼�
+闁�
+闁�
+闁�
+闂�
+闄�
+闄�
+闅�
+闅�
+闆�
+闆�
+闇�
+闈�
+闈�
+闈�
+闈�
+闉�
+闉�
+闋�
+闋�
+闋�
+闋�
+椤�
+椤�
+椁�
+楗�
+椐�
+椐�
+椐�
+楱�
+楱�
+楱�
+楂�
+楂�
+楂�
+楂�
+榀�
+榀�
+榀�
+榘�
+榘�
+榘�
+槌�
+榇�
+榇�
+榈�
+榈�
+榈�
+槎�
+楣�
+楹�
+楹�
+楹�
+榛�
+榛�
+榧�
+榻�
+榫�
+绺�
+锜�
+鍧�
+绁�
+榧�
+楸�
+铔�
+灞�
+鍛�
+鐓�
+鍚�
+鎵�
+铓�
+閵�
+灏�
+澶�
+榈�
+寰�
+瀵�
+褰�
+鑸�
+婀�
+楹�
+閸�
+宕�
+楸�
+鐩�
+鎷�
+鐟�
+鑼�
+鐒�
+濂�
+椹�
+楸�
+鐮�
+鐥�
+寤�
+鍍�
+鐦�
+楸�
+鎿�
+宥�
+娣�
+璺�
+娴�
+濯�
+鐠�
+鐓�
+妾�
+濯�
+宄�
+韬�
+閴�
+濉�
+锜�
+榀�
+寮�
+鐑�
+榈�
+濡�
+瀛�
+铓�
+鎭�
+杓�
+寤�
+鐢�
+鏇�
+鐩�
+楱�
+鍥�
+楸�
+鑼�
+钁�
+閫�
+鐙�
+宕�
+瓒�
+鍑�
+缇�
+楫�
+鏄�
+妤�
+娓�
+鍦�
+楹�
+灞�
+閸�
+钁�
+娌�
+鐖�
+骞�
+绛�
+瀵�
+閵�
+璨�
+閹�
+鐔�
+鏄�
+閸�
+澧�
+鎰�
+纾�
+鍤�
+绋�
+鐝�
+閲�
+娈�
+閸�
+洳�
+钑�
+閻�
+鍍�
+浣�
+杓�
+鍐�
+瑗�
+璩�
+鐚�
+杈�
+绲�
+纾�
+闊�
+铻�
+璀�
+绀�
+閶�
+榄�
+鍤�
+妫�
+鐗�
+鏁�
+鏌�
+鐡�
+榄�
+宸�
+杞�
+瑗�
+鏋�
+楦�
+閫�
+閷�
+绺�
+甯�
+楱�
+濯�
+鍩�
+閯�
+钀�
+绁�
+鏃�
+瑭�
+槎�
+鐕�
+鍗�
+閵�
+搴�
+浼�
+姘�
+宓�
+鎸�
+鐓�
+绐�
+閻�
+楫�
+楸�
+榘�
+瀣�
+璀�
+璜�
+鑴�
+鎮�
+宕�
+闃�
+鍏�
+琚�
+鍐�
+澹�
+鍜�
+绀�
+瀛�
+鐥�
+鍩�
+鑲�
+榘�
+楫�
+婵�
+濉�
+鍑�
+钂�
+鍣�
+妗�
+宄�
+鐒�
+槎�
+閶�
+缍�
+槎�
+鐔�
+姣�
+鍜�
+鍢�
+鐫�
+绻�
+铯�
+鐦�
+閴�
+钄�
+绉�
+绶�
+铦�
+韬�
+锜�
+绻�
+鍥�
+澧�
+涔�
+鑳�
+婵�
+鐦�
+姒�
+閼�
+閻�
+宥�
+鐢�
+鍧�
+閵�
+钂�
+鐫�
+淇�
+椁�
+姒�
+钃�
+鐩�
+鍫�
+閸�
+鑻�
+宸�
+铓�
+鏆�
+鐔�
+瀣�
+澧�
+閺�
+鎴�
+鑿�
+鑶�
+鐔�
+鐫�
+鏍�
+鎹�
+姒�
+閸�
+鏇�
+鐘�
+闊�
+琚�
+鋿�
+鐒�
+鍠�
+楂�
+鐤�
+愦�
+渚�
+璨�
+钑�
+绂�
+钑�
+鍥�
+鏆�
+鍎�
+浣�
+鏌�
+銗�
+榘�
+鑻�
+楸�
+璎�
+閬�
+鐪�
+閼�
+缇�
+椤�
+闄�
+閵�
+榛�
+鑻�
+钂�
+妫�
+鍎�
+鍜�
+鎶�
+琛�
+妫�
+鐒�
+鑴�
+楹�
+鐜�
+鍩�
+娣�
+榛�
+娣�
+褰�
+楫�
+娌�
+绯�
+鍘�
+妤�
+宥�
+绨�
+妾�
+楸�
+宥�
+寤�
+鍗�
+妯�
+璐�
+閰�
+绫�
+娌�
+鏅�
+璜�
+钑�
+濡�
+閯�
+钂�
+濂�
+鎶�
+钃�
+钖�
+楸�
+宸�
+錆�
+浜�
+瀵�
+妲�
+瑾�
+楹�
+钑�
+婧�
+铇�
+姒�
+鏂�
+鏆�
+鐐�
+鎷�
+濞�
+绻�
+姗�
+瀵�
+鐖�
+楗�
+鎮�
+榀�
+褰�
+鐪�
+钁�
+瀣�
+鍩�
+鐛�
+棣�
+婧�
+鐎�
+鐔�
+纭�
+閳�
+妯�
+杓�
+榘�
+钄�
+娓�
+婢�
+鍡�
+鏃�
+绫�
+濯�
+鐕�
+鍎�
+闋�
+缂�
+淇�
+閫�
+楸�
+閮�
+姝�
+鏉�
+鐝�
+鏉�
+閱�
+榘�
+榈�
+閻�
+楫�
+宸�
+鑽�
+钖�
+鍥�
+韫�
+鐛�
+绂�
+閹�
+姒�
+鍍�
+缍�
+灏�
+鏁�
+鏇�
+瑜�
+楝�
+浜�
+閺�
+钃�
+瑁�
+楸�
+钖�
+榘�
+绠�
+楝�
+绺�
+鐠�
+鐢�
+鑼�
+杈�
+宀�
+瑕�
+婊�
+榀�
+閼�
+鍥�
+鑸�
+婧�
+鎷�
+鑿�
+鏁�
+铏�
+缍�
+铦�
+閱�
+绂�
+璩�
+寤�
+绲�
+妲�
+寰�
+閹�
+鏇�
+锠�
+鎹�
+鍫�
+鑾�
+钃�
+鏁�
+绂�
+娅�
+缍�
+鐎�
+閫�
+娴�
+纰�
+鍒�
+閫�
+鍓�
+姘�
+鑿�
+濞�
+铚�
+宓�
+绯�
+铻�
+璀�
+閺�
+宓�
+鐟�
+闅�
+妾�
+绶�
+鐣�
+鐮�
+绨�
+褰�
+榘�
+楱�
+绐�
+鍤�
+宓�
+灏�
+闋�
+妲�
+铏�
+閱�
+宸�
+褰�
+鍋�
+鐣�
+楸�
+濡�
+濉�
+鐣�
+閳�
+閷�
+纾�
+鎽�
+褰�
+鐠�
+鍥�
+瀵�
+鑰�
+楫�
+铇�
+寮�
+鐒�
+椋�
+鎴�
+濉�
+鍎�
+妲�
+鍣�
+榄�
+绂�
+浣�
+鍜�
+鐩�
+鐟�
+閴�
+鐫�
+閺�
+榧�
+閮�
+榄�
+鏈�
+婊�
+娓�
+婊�
+鐔�
+閱�
+閹�
+瑜�
+楝�
+宸�
+铻�
+鐪�
+閲�
+鏌�
+澹�
+宄�
+濮�
+鍞�
+楫�
+閳�
+瀚�
+澹�
+娲�
+榛�
+浼�
+鍫�
+宥�
+楫�
+闉�
+婕�
+閴�
+楫�
+澹�
+闃�
+濡�
+鐭�
+鐛�
+鍊�
+閵�
+榇�
+姗�
+鍑�
+鍝�
+灞�
+鍋�
+鐟�
+濯�
+娣�
+椹�
+妞�
+璧�
+钖�
+绯�
+纰�
+婵�
+閲�
+鏅�
+绾�
+瀵�
+闁�
+姝�
+鍛�
+槎�
+灞�
+娅�
+鐘�
+鏃�
+銠�
+榫�
+缈�
+铻�
+瑾�
+琛�
+娉�
+杌�
+榈�
+鑽�
+鍤�
+纭�
+妗�
+瑜�
+绛�
+榘�
+绉�
+鎴�
+杞�
+楝�
+椋�
+鍗�
+鏆�
+鐙�
+鎼�
+濞�
+閺�
+婧�
+姣�
+娣�
+璎�
+椁�
+榈�
+槌�
+楫�
+鐙�
+姘�
+杞�
+濡�
+琚�
+钃�
+姊�
+濞�
+鐗�
+绋�
+鍏�
+鐜�
+鐓�
+鍍�
+槎�
+楝�
+宕�
+閴�
+榀�
+铓�
+搴�
+榈�
+鍧�
+娈�
+鎮�
+鐔�
+鏁�
+閸�
+鏇�
+鎰�
+鎼�
+濮�
+鐮�
+妲�
+鑷�
+闊�
+闈�
+楦�
+钖�
+铏�
+锠�
+鍟�
+槎�
+鑻�
+婊�
+瑜�
+浠�
+鑳�
+鎲�
+閮�
+鐑�
+椹�
+鍐�
+鏋�
+澶�
+鎼�
+鍖�
+鐩�
+娅�
+闇�
+楹�
+璨�
+鍣�
+鍡�
+绗�
+鏅�
+鍐�
+閵�
+姣�
+鎱�
+鍥�
+闁�
+濞�
+搴�
+澹�
+棣�
+妗�
+鍏�
+钁�
+渚�
+鐓�
+閻�
+钘�
+榉�
+宓�
+閫�
+寮�
+鍖�
+閻�
+寤�
+鐮�
+瀛�
+鐏�
+浼�
+鍏�
+榇�
+婢�
+骞�
+鏃�
+鍕�
+绀�
+濠�
+楸�
+濞�
+閵�
+鍚�
+閸�
+浠�
+槌�
+褰�
+濞�
+鏄�
+榘�
+鍓�
+浣�
+閴�
+鍋�
+榘�
+璁�
+姗�
+鍟�
+宀�
+瀛�
+閲�
+涔�
+閳�
+婕�
+妾�
+鍩�
+绁�
+鐖�
+绂�
+楸�
+愀�
+姊�
+鐕�
+闇�
+鐐�
+椋�
+锠�
+鍕�
+榈�
+鍎�
+閻�
+鍞�
+寤�
+鍤�
+宓�
+澧�
+绱�
+鎼�
+鐦�
+鐨�
+楦�
+鐎�
+绮�
+鎾�
+宸�
+姊�
+鍟�
+鐪�
+璜�
+澶�
+鍍�
+閸�
+瑁�
+楫�
+鍑�
+椋�
+鐏�
+姗�
+瀚�
+绛�
+鍜�
+绮�
+鐡�
+鐠�
+浼�
+闁�
+鍌�
+榛�
+璎�
+椹�
+姗�
+铔�
+瀵�
+锠�
+鐬�
+鏃�
+缈�
+纭�
+瀵�
+闊�
+妤�
+榘�
+鏈�
+渚�
+榈�
+鎰�
+绁�
+鍘�
+涓�
+鐩�
+璎�
+榄�
+鍟�
+闁�
+鏇�
+鏋�
+缃�
+鍗�
+妯�
+榉�
+榀�
+閶�
+纾�
+鏋�
+鏀�
+锠�
+绌�
+鍤�
+妾�
+瓒�
+濂�
+閶�
+妾�
+钖�
+宄�
+鍜�
+瑷�
+闊�
+閼�
+楦�
+鍞�
+鎹�
+楦�
+瑾�
+缃�
+鐠�
+鏆�
+澶�
+璩�
+闉�
+閳�
+鐏�
+楫�
+鎳�
+绫�
+鏄�
+闄�
+瑗�
+楫�
+閳�
+鍥�
+濠�
+鑹�
+璨�
+浒�
+濮�
+绂�
+鍫�
+閶�
+浠�
+閺�
+璎�
+閼�
+蹇�
+铇�
+璎�
+瑙�
+濂�
+鐙�
+娉�
+妗�
+椋�
+鍨�
+鍟�
+鍤�
+榀�
+钂�
+姒�
+寰�
+鐠�
+鎻�
+娆�
+榄�
+鑿�
+鐜�
+槌�
+寤�
+渚�
+宀�
+宀�
+閶�
+鍑�
+褰�
+宕�
+濯�
+鍊�
+榈�
+鐮�
+榉�
+楸�
+楫�
+绻�
+鎽�
+璐�
+纾�
+閷�
+鐥�
+绮�
+鑳�
+濂�
+濉�
+鐎�
+楦�
+鍟�
+濞�
+闇�
+澹�
+宄�
+鐢�
+寤�
+瑕�
+榘�
+鐚�
+楸�
+鐩�
+瑁�
+鏉�
+姝�
+婢�
+铇�
+宓�
+灏�
+鏃�
+閴�
+閹�
+璞�
+鍑�
+姒�
+绂�
+榫�
+鎮�
+榉�
+楫�
+鍚�
+鍠�
+宀�
+鍚�
+婕�
+闋�
+璞�
+宸�
+閼�
+閱�
+鐔�
+鎳�
+婀�
+妾�
+闊�
+鎴�
+绶�
+閻�
+铳�
+绶�
+楫�
+濯�
+鐖�
+宸�
+瑜�
+閻�
+鏄�
+鎵�
+閸�
+鑺�
+锜�
+瀣�
+绯�
+鍚�
+濉�
+璀�
+鍐�
+閺�
+宥�
+鍡�
+妞�
+濮�
+闁�
+瑜�
+閷�
+鐜�
+绗�
+绡�
+钀�
+槎�
+铻�
+楫�
+榘�
+鑴�
+鍟�
+鏉�
+钃�
+灏�
+濞�
+娈�
+娣�
+铦�
+钃�
+褰�
+鍤�
+閵�
+鍥�
+鍧�
+娣�
+槎�
+楸�
+鍠�
+鐕�
+鑲�
+濮�
+寤�
+绂�
+绫�
+杩�
+宓�
+鍫�
+锜�
+鎲�
+寤�
+铚�
+绶�
+鍞�
+绔�
+宕�
+鐠�
+绮�
+鏍�
+缃�
+姊�
+璨�
+钘�
+铚�
+瑷�
+鏂�
+鐓�
+棣�
+濡�
+闁�
+鐤�
+澶�
+閹�
+鑶�
+婢�
+鍢�
+鍤�
+闈�
+閹�
+榘�
+绌�
+鐑�
+绺�
+瑜�
+鐤�
+澹�
+婧�
+鍦�
+鍜�
+榀�
+榀�
+纾�
+鐜�
+鐝�
+鏈�
+铓�
+婵�
+钖�
+鍤�
+涓�
+瀚�
+榀�
+妞�
+榘�
+鍒�
+锠�
+韪�
+鐎�
+鐞�
+榘�
+鐟�
+鑲�
+銗�
+娆�
+濯�
+绔�
+璁�
+穑噳
+瑁�
+绶�
+寤�
+榻�
+鍙�
+淇�
+鍘�
+婊�
+閷�
+榉�
+榀�
+鏀�
+濮�
+钄�
+骞�
+绺�
+灞�
+榀�
+闆�
+绾�
+瀚�
+宓�
+灞�
+宥�
+璺�
+閶�
+钑�
+绡�
+淇�
+娣�
+鏆�
+閺�
+鎲�
+鐜�
+婧�
+绗�
+绯�
+鍕�
+闁�
+娌�
+鍜�
+閴�
+铇�
+淇�
+宕�
+姣�
+鑻�
+鎺�
+榇�
+钀�
+淇�
+灞�
+钂�
+鑹�
+鍓�
+鎱�
+鏈�
+鏋�
+姘�
+鐚�
+鐢�
+绠�
+璀�
+璐�
+杩�
+閳�
+閸�
+閸�
+閺�
+闈�
+椁�
+涓�
+涓�
+浠�
+浠�
+浼�
+浼�
+浠�
+浼�
+浼�
+浣�
+浣�
+渚�
+渚�
+浣�
+浣�
+浣�
+渚�
+渚�
+淇�
+渚�
+淇�
+渚�
+渚�
+淇�
+鍊�
+鍊�
+鍊�
+鍊�
+鍊�
+鍊�
+淇�
+鍊�
+鍋�
+鍋�
+鍋�
+鍋�
+鍋�
+鍋�
+鍋�
+鍋�
+鍋�
+鍋�
+鍋�
+鍌�
+鍌�
+鍌�
+鍌�
+鍌�
+鍌�
+鍌�
+鍋�
+鍌�
+鍌�
+鍌�
+鍍�
+鍌�
+鍍�
+鍍�
+鍌�
+鍍�
+鍌�
+鍍�
+鍍�
+鍍�
+鍍�
+鍍�
+鍍�
+鍍�
+鍎�
+鍎�
+鍍�
+鍍�
+鍍�
+鍎�
+鍍�
+鍎�
+鍎�
+鍎�
+鍎�
+鍎�
+鍎�
+鍎�
+鍎�
+鍎�
+鍎�
+鍐�
+鍐�
+鍐�
+鍑�
+鍑�
+鍑�
+鍒�
+鍒�
+鍒�
+鍒�
+鍒�
+鍒�
+鍒�
+鍓�
+鍒�
+鍓�
+鍓�
+鍓�
+鍓�
+鍓�
+鍓�
+鍓�
+鍓�
+鍓�
+鍓�
+鍔�
+鍔�
+鍔�
+鍔�
+鍔�
+鍔�
+鍔�
+鍕�
+鍖�
+鍖�
+鍖�
+鍖�
+鍖�
+鍖�
+鍗�
+鍗�
+鍘�
+鍘�
+鍘�
+鍘�
+鍘�
+鍘�
+鍘�
+鍘�
+鍚�
+鍚�
+鍚�
+鍛�
+鍜�
+鍛�
+鍛�
+鍛�
+鍛�
+鍛�
+鑼�
+鍜�
+鍜�
+鍜�
+鍝�
+鍜�
+鍜�
+鍞�
+鍞�
+鍞�
+鍝�
+鍞�
+鍞�
+鍝�
+鍞�
+鍞�
+鍟�
+鍞�
+鍟�
+鍟�
+鍞�
+鍞�
+鍠�
+鍠�
+鍠�
+鍣�
+鍠�
+鍠�
+鍟�
+鍠�
+鍡�
+鍡�
+鍡�
+鍡�
+鍠�
+鍠�
+鍡�
+鍡�
+鍡�
+鍢�
+鍢�
+鍡�
+鍢�
+鍢�
+鍢�
+鍡�
+鍢�
+鍢�
+鍡�
+鍣�
+鍣�
+鍣�
+鍣�
+鍢�
+鍢�
+鍢�
+鍣�
+鍣�
+鍣�
+鍣�
+鍣�
+鍤�
+鍤�
+鍤�
+鍤�
+鍤�
+鍤�
+鍤�
+鍤�
+鍤�
+鍤�
+鍤�
+鍤�
+鍥�
+鍥�
+鍥�
+鍥�
+鍦�
+鍦�
+鍦�
+鍧�
+鍧�
+鍧�
+鍧�
+鍨�
+鍧�
+鍨�
+鍨�
+鍨�
+鍨�
+鍨�
+鍨�
+鍩�
+鍩�
+鍫�
+鍫�
+濉�
+鍫�
+濉�
+濉�
+濉�
+濉�
+濉�
+澧�
+濉�
+濉�
+澧�
+濉�
+澧�
+澧�
+澹�
+澧�
+澹�
+澹�
+澹�
+澹�
+澹�
+澶�
+澶�
+澶�
+澶�
+濂�
+濂�
+濂�
+濂�
+濂�
+濡�
+濡�
+濡�
+濡�
+濡�
+濮�
+濮�
+銡�
+濮�
+濮�
+濮�
+濞�
+濠�
+濠�
+濠�
+濠�
+濠�
+濯�
+濯�
+濯�
+濠�
+濯�
+濯�
+濯�
+濯�
+濞�
+瀚�
+瀚�
+濯�
+濯�
+瀚�
+瀚�
+瀚�
+瀚�
+瀚�
+瀚�
+瀚�
+瀚�
+瀣�
+瀣�
+瀣�
+瀣�
+瀣�
+瀛�
+灞�
+瀛�
+瀛�
+瀹�
+瀹�
+瀵�
+瀵�
+瀵�
+瀵�
+瀵�
+瀵�
+瀵�
+灏�
+灏�
+灏�
+灏�
+灏�
+灞�
+灞�
+灞�
+灞�
+灞�
+灞�
+灞�
+宀�
+宀�
+宀�
+宀�
+宀�
+宀�
+宀�
+宀�
+宀�
+宄�
+宄�
+宄�
+宄�
+宄�
+宄�
+宄�
+宄�
+宕�
+宕�
+宕�
+宕�
+宕�
+宕�
+宕�
+宓�
+宓�
+宕�
+宕�
+宓�
+宓�
+宓�
+宓�
+宓�
+宥�
+宓�
+宥�
+宓�
+宓�
+宥�
+宥�
+宥�
+宓�
+宥�
+宥�
+宥�
+宥�
+宥�
+宥�
+宥�
+宥�
+宥�
+宸�
+宸�
+宸�
+宸�
+宸�
+甯�
+甯�
+甯�
+甯�
+甯�
+甯�
+甯�
+甯�
+甯�
+骞�
+骞�
+骞�
+骞�
+骞�
+骞�
+骞�
+骞�
+骞�
+骞�
+骞�
+搴�
+搴�
+搴�
+搴�
+搴�
+搴�
+搴�
+搴�
+搴�
+搴�
+搴�
+搴�
+寤�
+寤�
+寤�
+寤�
+寤�
+寤�
+绶�
+寤�
+寤�
+寤�
+寤�
+锠�
+寤�
+寮�
+寮�
+寮�
+寮�
+寮�
+寮�
+褰�
+褰�
+褰�
+褰�
+褰�
+褰�
+褰�
+褰�
+寰�
+寰�
+寰�
+寰�
+寰�
+寰�
+蹇�
+蹇�
+蹇�
+蹇�
+蹇�
+蹇�
+蹇�
+蹇�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎬�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎭�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+鎮�
+鎯�
+鎯�
+鎯�
+鎮�
+鎯�
+鎮�
+鎯�
+鎯�
+鎯�
+鎰�
+鎰�
+鎰�
+鎯�
+鎰�
+鎯�
+鎯�
+鎯�
+鎱�
+鎱�
+鎰�
+鎰�
+鎰�
+鎰�
+鎰�
+鎱�
+鎱�
+鎱�
+鎱�
+鎱�
+鎱�
+鎲�
+鎱�
+鎱�
+鎱�
+鎱�
+鎲�
+鎱�
+鎲�
+鎲�
+鎲�
+鎲�
+鎲�
+鎲�
+鎲�
+鎲�
+鎲�
+鎲�
+鎲�
+鎳�
+鎲�
+鎳�
+鎳�
+鎲�
+鎲�
+鎲�
+鎲�
+鎳�
+鎳�
+鎳�
+鎳�
+鎳�
+鎳�
+鎳�
+鎳�
+鎳�
+鎳�
+鎳�
+鎴�
+鎴�
+鎴�
+鎴�
+鎴�
+閰�
+鎴�
+鎵�
+鎵�
+鎵�
+鎵�
+鎵�
+鎶�
+鎶�
+鎶�
+鎶�
+鎵�
+鎶�
+鎶�
+鎷�
+鎶�
+鎶�
+鎶�
+鎶�
+鎸�
+鎸�
+鎸�
+鎷�
+鎷�
+鎸�
+鎸�
+鎷�
+鎸�
+鎷�
+鎹�
+鎸�
+鎸�
+鎻�
+鎹�
+鎸�
+鎸�
+鎹�
+鎸�
+鎹�
+鎹�
+鎹�
+鎺�
+鎺�
+鎺�
+鎺�
+鎹�
+鎺�
+鎹�
+鎺�
+鎺�
+鎺�
+鎻�
+鎻�
+鎻�
+鎻�
+鎻�
+鎻�
+鎻�
+鎽�
+鎻�
+鎻�
+鎻�
+鎻�
+鎻�
+鎻�
+鎼�
+鎼�
+鎼�
+鎼�
+鎼�
+鎼�
+鎼�
+鎼�
+鎼�
+鎼�
+鎽�
+鎼�
+鎼�
+鎽�
+鎽�
+鎽�
+鎽�
+鎽�
+鎽�
+鎽�
+鎽�
+鎽�
+鎽�
+鎽�
+鎾�
+鎾�
+鎾�
+鎾�
+鎾�
+鎾�
+鎾�
+鎾�
+鎿�
+鎿�
+鎿�
+鎿�
+鎾�
+鎿�
+鎿�
+鎿�
+鎿�
+鎿�
+鎿�
+鎿�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏀�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏁�
+鏂�
+鏂�
+鏂�
+鏂�
+鏂�
+鏂�
+鏂�
+鏂�
+鏂�
+鏃�
+鏃�
+鏃�
+鏃�
+鏃�
+鏄�
+鏄�
+鏄�
+鏅�
+鏅�
+鏅�
+鏅�
+鏅�
+鏆�
+鏆�
+鏆�
+鏆�
+鏆�
+鏆�
+鏆�
+鏇�
+鏇�
+鏇�
+鏇�
+鏇�
+鏇�
+鏇�
+鏇�
+鏈�
+鏈�
+鏈�
+鏈�
+鏈�
+鏈�
+鏈�
+鏈�
+鏈�
+鏈�
+鏉�
+鏉�
+鏉�
+鏉�
+鏋�
+鏉�
+鏋�
+鏋�
+鏌�
+鏋�
+鏋�
+鏌�
+鏌�
+鏌�
+鏌�
+鏌�
+鏌�
+鏌�
+鏌�
+鏌�
+鏌�
+鏍�
+妗�
+妗�
+鏍�
+鏍�
+鏍�
+鏍�
+鏍�
+鏍�
+鏍�
+姊�
+姊�
+姊�
+妗�
+姊�
+妤�
+姊�
+姊�
+妗�
+姊�
+妞�
+妞�
+妫�
+妫�
+妫�
+妫�
+妞�
+妤�
+妫�
+妞�
+妫�
+妤�
+妤�
+妤�
+妤�
+妤�
+妤�
+妤�
+妤�
+妤�
+妞�
+妤�
+妤�
+妤�
+妤�
+姒�
+妲�
+姒�
+姒�
+姒�
+姒�
+姒�
+姒�
+姒�
+妲�
+姒�
+姒�
+妲�
+妲�
+妯�
+妯�
+妲�
+妲�
+妯�
+妯�
+妲�
+妯�
+妲�
+妯�
+妲�
+姗�
+妯�
+姗�
+姗�
+妯�
+姗�
+姗�
+姗�
+姗�
+妯�
+姗�
+妾�
+妾�
+妾�
+妾�
+姗�
+妾�
+妾�
+妾�
+妾�
+娅�
+妾�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娅�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+娆�
+姝�
+姝�
+姝�
+姝�
+姝�
+姝�
+姝�
+姝�
+姝�
+姝�
+鑲�
+娈�
+娈�
+娈�
+娈�
+娈�
+娈�
+娈�
+娈�
+娈�
+娈�
+娈�
+娈�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姣�
+姘�
+姘�
+姘�
+姘�
+姘�
+姹�
+姹�
+姹�
+姹�
+姹�
+娌�
+姹�
+姹�
+娌�
+姹�
+姹�
+娉�
+娌�
+娌�
+娉�
+娌�
+娉�
+娉�
+娉�
+娌�
+娲�
+娲�
+娲�
+娴�
+娴�
+娲�
+娑�
+娴�
+娴�
+娑�
+娑�
+娴�
+娑�
+娑�
+娑�
+娣�
+娑�
+娣�
+娓�
+娣�
+娑�
+娣�
+娑�
+娣�
+婀�
+婀�
+婀�
+婀�
+娓�
+婀�
+娓�
+娓�
+婀�
+娓�
+娓�
+婀�
+婀�
+娓�
+娓�
+婀�
+婀�
+婀�
+娓�
+婧�
+婊�
+婧�
+婧�
+婊�
+婧�
+婧�
+婊�
+婊�
+婊�
+婕�
+婕�
+婕�
+娼�
+婕�
+婕�
+婕�
+婕�
+婊�
+婕�
+娼�
+婊�
+娼�
+婕�
+娼�
+婕�
+婵�
+婢�
+婢�
+娼�
+娼�
+婢�
+娼�
+娼�
+娼�
+娼�
+娼�
+婢�
+娼�
+婵�
+婵�
+婵�
+婵�
+婢�
+婢�
+鐎�
+婵�
+婢�
+婵�
+婵�
+婵�
+婵�
+婵�
+婵�
+鐎�
+鐎�
+婵�
+鐎�
+婵�
+鐎�
+鐎�
+鐎�
+鐎�
+鐎�
+鐎�
+鐎�
+鐎�
+鐏�
+鐎�
+鐎�
+鐎�
+鐏�
+鐏�
+鐏�
+鐏�
+鐏�
+鐏�
+鐏�
+鐏�
+鐏�
+鐐�
+鐐�
+鐑�
+鐑�
+缂�
+鐒�
+鐑�
+鐒�
+鐒�
+鐒�
+鐓�
+鐓�
+鐓�
+鐔�
+鐔�
+鐔�
+鐔�
+鐔�
+鐕�
+鐕�
+鐔�
+鐕�
+鐕�
+鐖�
+鐖�
+鐖�
+鐖�
+鐖�
+鐖�
+鐖�
+鐗�
+鐗�
+鐗�
+鐗�
+鐗�
+鐗�
+鐗�
+鐗�
+鐗�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐘�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐙�
+鐚�
+鐙�
+鐚�
+鐚�
+鐚�
+鐙�
+鐚�
+鐚�
+鐚�
+鐚�
+鐚�
+鐚�
+鐚�
+鐚�
+鐚�
+鐚�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐛�
+鐜�
+鐜�
+鐜�
+鐜�
+鐜�
+鐝�
+鐝�
+鐞�
+鐟�
+鐠�
+鐟�
+鐠�
+鐟�
+鐠�
+鐡�
+鐡�
+鐡�
+鐡�
+鐡�
+鐡�
+鐡�
+鐡�
+鐡�
+鐡�
+鐡�
+鐢�
+鐢�
+鐢�
+鐢�
+鐢�
+鐢�
+鐢�
+鐢�
+鐢�
+鐢�
+鐢�
+鐣�
+鐣�
+鐣�
+鐤�
+鐤�
+鐥�
+鐤�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐥�
+鐦�
+鐥�
+鐥�
+鐥�
+鐦�
+鐦�
+鐦�
+鐦�
+鐦�
+鐦�
+鐦�
+鐧�
+鐧�
+鐧�
+鐧�
+鐧�
+鐧�
+鐧�
+鐧�
+鐨�
+鐨�
+鐨�
+鐨�
+鐨�
+鐨�
+鐨�
+鐨�
+鐩�
+鐩�
+鐩�
+鐩�
+鐩�
+鐩�
+鐪�
+鐪�
+鐩�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐪�
+鐫�
+鐫�
+鐫�
+鐫�
+鐫�
+鐫�
+鐫�
+鐫�
+鐫�
+鐫�
+鐫�
+鐫�
+鐬�
+鐫�
+鐬�
+鐫�
+鐫�
+鐬�
+鐬�
+鐬�
+鐬�
+鐬�
+鐬�
+鐬�
+鐬�
+鐬�
+鐬�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐭�
+鐮�
+鐮�
+鐮�
+鐮�
+鐮�
+纭�
+纭�
+纭�
+纭�
+纭�
+纭�
+纭�
+纰�
+纰�
+纰�
+纰�
+纭�
+纰�
+纰�
+纾�
+纾�
+纾�
+纾�
+纾�
+纾�
+纾�
+纾�
+纾�
+纾�
+纾�
+纾�
+纾�
+绀�
+绀�
+绀�
+绀�
+绀�
+绀�
+绀�
+绀�
+绀�
+绀�
+绀�
+绁�
+绁�
+绁�
+绁�
+绁�
+绁�
+绁�
+绁�
+绁�
+绁�
+绁�
+绁�
+绁�
+绂�
+绂�
+绂�
+绂�
+绂�
+绂�
+绂�
+绂�
+绂�
+姝�
+绉�
+绉�
+绉�
+绉�
+绉�
+绉�
+绉�
+绉�
+绋�
+绋�
+绋�
+绌�
+绋�
+绋�
+绌�
+绌�
+绌�
+绌�
+绌�
+绌�
+绌�
+绌�
+绌�
+绌�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绐�
+绔�
+绔�
+绔�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+绗�
+绛�
+绛�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绠�
+绡�
+绠�
+绠�
+绡�
+绡�
+绡�
+绡�
+绡�
+绡�
+绨�
+绡�
+绡�
+绡�
+绨�
+绡�
+绨�
+绨�
+绡�
+绡�
+绨�
+绨�
+绨�
+绨�
+绨�
+绨�
+绨�
+绨�
+绨�
+绨�
+绨�
+绨�
+绫�
+绫�
+绫�
+绫�
+绫�
+绫�
+绫�
+绫�
+绫�
+绫�
+绫�
+绮�
+绮�
+绮�
+绯�
+绯�
+绯�
+绯�
+绱�
+绱�
+绱�
+绱�
+绱�
+绱�
+绱�
+绲�
+绱�
+绲�
+绲�
+绲�
+绲�
+绲�
+绲�
+绲�
+缍�
+缍�
+绲�
+缍�
+绲�
+绲�
+缍�
+缍�
+绶�
+缍�
+绶�
+绶�
+绶�
+绶�
+绶�
+缍�
+缍�
+绶�
+绶�
+绶�
+绶�
+绺�
+绶�
+绶�
+绶�
+绺�
+绺�
+绺�
+绺�
+绺�
+绺�
+绺�
+绺�
+绻�
+绺�
+椤�
+绻�
+绺�
+绺�
+绻�
+绻�
+绺�
+绶�
+绺�
+绺�
+绺�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绻�
+绾�
+绾�
+绾�
+绾�
+绾�
+绾�
+绾�
+缂�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缃�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缇�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+缈�
+鑰�
+鑰�
+鑰�
+鑰�
+鑰�
+鑰�
+鑱�
+鑱�
+鑱�
+鑱�
+鑱�
+鑲�
+鑲�
+鑲�
+鑲�
+鑲�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑳�
+鑴�
+鑳�
+鑴�
+鑳�
+鑳�
+鑴�
+鑴�
+鑴�
+鑴�
+鑴�
+鑴�
+鑴�
+鑵�
+鑵�
+鑵�
+鑵�
+鑴�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+鑵�
+鏈�
+鑵�
+鑵�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑶�
+鑷�
+鑶�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑷�
+鑸�
+鑸�
+鑸�
+鑸�
+鑸�
+鑸�
+鑸�
+鑹�
+鑹�
+鑹�
+鑹�
+鑹�
+鑹�
+鑹�
+鑹�
+鑹�
+鑹�
+鑺�
+鑺�
+鑺�
+鑺�
+鑺�
+鑻�
+鑺�
+鑺�
+鑺�
+鑺�
+鑺�
+鑻�
+鑻�
+鑻�
+鑻�
+鑻�
+鑻�
+鑻�
+鑼�
+鑼�
+鑼�
+鑼�
+鑼�
+鑽�
+鑼�
+鑽�
+鑼�
+鑼�
+鑼�
+鑼�
+鑼�
+鑾�
+鑾�
+鑾�
+鑽�
+鑾�
+鑽�
+鑾�
+鑾�
+鑽�
+鑾�
+鑾�
+鑾�
+鑾�
+鑽�
+鑾�
+鑿�
+钀�
+鑿�
+鑿�
+鑿�
+鑿�
+鑿�
+鑿�
+鑿�
+鑿�
+钀�
+鑿�
+鑿�
+鑿�
+钃�
+钀�
+钁�
+钁�
+钁�
+钁�
+钀�
+钁�
+钁�
+钄�
+钁�
+钀�
+钀�
+钀�
+钁�
+鑿�
+钁�
+钀�
+钁�
+钁�
+钁�
+钃�
+钂�
+钂�
+钂�
+钂�
+钂�
+钂�
+钃�
+钂�
+钂�
+钂�
+钂�
+钂�
+钄�
+钄�
+钄�
+钄�
+钄�
+钄�
+钄�
+钃�
+钃�
+钃�
+钄�
+钃�
+钃�
+钃�
+钄�
+钃�
+钄�
+钃�
+钄�
+钄�
+钄�
+钃�
+钄�
+钃�
+钄�
+钄�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钑�
+钖�
+钖�
+钖�
+钖�
+钖�
+钖�
+钖�
+钑�
+钖�
+钑�
+钖�
+钖�
+钖�
+钖�
+钖�
+钘�
+钘�
+钘�
+钘�
+钖�
+钖�
+钘�
+钘�
+钘�
+钘�
+钘�
+钖�
+钖�
+钘�
+钘�
+钘�
+钘�
+钘�
+钘�
+钘�
+钘�
+钘�
+钘�
+钘�
+钘�
+钘�
+铇�
+钘�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铇�
+铏�
+铇�
+铇�
+铇�
+铇�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铏�
+铓�
+铓�
+铓�
+铓�
+铓�
+铓�
+铓�
+铓�
+铓�
+铓�
+铔�
+铔�
+铔�
+铔�
+铓�
+铓�
+铓�
+铔�
+铓�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铔�
+铚�
+铔�
+铚�
+铔�
+铔�
+铚�
+铔�
+铚�
+铦�
+铚�
+铦�
+铚�
+铦�
+铦�
+铚�
+铚�
+铚�
+铚�
+铚�
+铚�
+铦�
+铚�
+铚�
+铚�
+铚�
+铚�
+铦�
+铦�
+锜�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铦�
+铻�
+铻�
+铻�
+铻�
+铻�
+铻�
+铻�
+铦�
+铻�
+铻�
+铻�
+铻�
+铻�
+铻�
+铻�
+铻�
+铻�
+铻�
+锜�
+锜�
+锜�
+铻�
+铻�
+铻�
+铻�
+锜�
+锜�
+锜�
+锜�
+锜�
+锜�
+锜�
+锜�
+锜�
+锜�
+铻�
+锜�
+锜�
+锠�
+锜�
+锠�
+锜�
+锠�
+锠�
+锜�
+锠�
+锜�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+锠�
+琛�
+琛�
+琛�
+琛�
+琛�
+琛�
+琛�
+琚�
+琛�
+琛�
+琚�
+琚�
+琚�
+琚�
+琚�
+琚�
+琚�
+琚�
+琚�
+琚�
+琚�
+琚�
+瑁�
+琚�
+琚�
+瑁�
+琚�
+琚�
+琚�
+瑁�
+瑁�
+瑁�
+瑁�
+瑁�
+瑁�
+瑁�
+瑁�
+瑁�
+瑁�
+瑁�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑜�
+瑗�
+瑜�
+瑗�
+瑜�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑗�
+瑕�
+瑕�
+瑕�
+瑕�
+瑕�
+瑕�
+瑕�
+瑕�
+瑕�
+瑕�
+瑕�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑙�
+瑷�
+瑷�
+瑷�
+瑷�
+瑷�
+瑭�
+瑷�
+瑭�
+瑭�
+瑭�
+瑭�
+瑷�
+瑾�
+瑭�
+瑾�
+瑾�
+瑾�
+瑾�
+璜�
+瑾�
+璜�
+璜�
+瑾�
+璜�
+璜�
+璜�
+璜�
+璜�
+璜�
+璎�
+璎�
+璎�
+璎�
+璎�
+璎�
+璎�
+璎�
+璎�
+璎�
+璎�
+璎�
+璎�
+璀�
+璎�
+璎�
+璎�
+璎�
+璎�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璀�
+璁�
+璁�
+璁�
+璁�
+璁�
+璁�
+璁�
+璋�
+璋�
+璋�
+璋�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璞�
+璨�
+璨�
+璨�
+璨�
+璨�
+璨�
+璨�
+璨�
+璨�
+璨�
+璨�
+璩�
+璩�
+璩�
+璩�
+璩�
+璩�
+璐�
+璐�
+璐�
+璧�
+璧�
+璧�
+璧�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+瓒�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+璺�
+韪�
+璺�
+韪�
+韪�
+韪�
+韪�
+璺�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韪�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韫�
+韬�
+韬�
+韬�
+韬�
+韬�
+韬�
+韬�
+韬�
+韬�
+韬�
+韬�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杌�
+杓�
+杌�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杓�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杞�
+杈�
+杩�
+杩�
+杩�
+杩�
+杩�
+杩�
+杩�
+杩�
+杩�
+閫�
+閫�
+閬�
+閬�
+閬�
+閬�
+閭�
+閭�
+閬�
+閭�
+閭�
+閭�
+閭�
+閭�
+閭�
+閮�
+閮�
+閮�
+閮�
+閮�
+閮�
+閮�
+閮�
+閮�
+閮�
+閮�
+閯�
+閮�
+閯�
+閮�
+閮�
+閯�
+閯�
+閮�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閯�
+閰�
+閰�
+閰�
+閰�
+閰�
+閰�
+閰�
+閰�
+閰�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閱�
+閲�
+閲�
+閲�
+閲�
+閲�
+閲�
+閳�
+閳�
+閳�
+閲�
+閳�
+閴�
+閴�
+閴�
+閳�
+閴�
+閵�
+閵�
+閵�
+閴�
+閵�
+閶�
+閶�
+閶�
+閶�
+閶�
+閶�
+閶�
+閶�
+閷�
+閷�
+閷�
+閷�
+閶�
+閹�
+閹�
+閹�
+閸�
+閸�
+閸�
+閸�
+閸�
+閹�
+閹�
+閹�
+閹�
+閹�
+閹�
+閺�
+閺�
+閺�
+閺�
+閺�
+閻�
+閻�
+閺�
+閻�
+閻�
+閻�
+閻�
+閻�
+閻�
+閻�
+閻�
+閼�
+閼�
+閼�
+閼�
+閼�
+閽�
+閽�
+閽�
+閽�
+闀�
+闀�
+闀�
+闀�
+闁�
+闁�
+闁�
+闁�
+闂�
+闂�
+闂�
+闁�
+闂�
+闂�
+闂�
+闂�
+闂�
+闂�
+闂�
+闃�
+闃�
+闃�
+闃�
+闃�
+闃�
+闃�
+闃�
+闄�
+闄�
+闄�
+闄�
+闄�
+闄�
+闅�
+闄�
+闅�
+闅�
+闅�
+闅�
+闅�
+闅�
+闆�
+闆�
+闆�
+闆�
+闆�
+闆�
+闆�
+闆�
+闆�
+闆�
+闆�
+闇�
+闇�
+闇�
+闇�
+闇�
+闇�
+闇�
+闇�
+闇�
+闇�
+闇�
+闇�
+闇�
+闈�
+闈�
+闈�
+闈�
+闈�
+闈�
+闈�
+闉�
+闉�
+闉�
+闈�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闉�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闊�
+闋�
+闋�
+闋�
+闋�
+闋�
+闋�
+闋�
+闋�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+椤�
+棰�
+棰�
+棰�
+棰�
+棰�
+棰�
+椋�
+椋�
+椋�
+椋�
+椋�
+椋�
+椋�
+椁�
+椁�
+椋�
+椁�
+椁�
+椁�
+椁�
+椁�
+椁�
+椁�
+椁�
+椁�
+椁�
+椁�
+椁�
+椁�
+楗�
+楗�
+楗�
+楗�
+楗�
+楗�
+楗�
+楗�
+棣�
+棣�
+棣�
+棣�
+棣�
+棣�
+椐�
+棣�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+椐�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+楱�
+椹�
+楱�
+椹�
+椹�
+椹�
+椹�
+椹�
+椹�
+椹�
+椹�
+椹�
+楠�
+楠�
+楠�
+楠�
+楠�
+楠�
+楂�
+楂�
+楂�
+楂�
+楂�
+楂�
+楂�
+楂�
+楂�
+楂�
+楂�
+楂�
+楝�
+楂�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+楝�
+榄�
+榄�
+榄�
+榄�
+榄�
+榄�
+榄�
+榄�
+榄�
+榄�
+楫�
+楫�
+榄�
+榄�
+榄�
+楫�
+楫�
+楫�
+楫�
+楫�
+楫�
+楫�
+楫�
+榀�
+楫�
+楫�
+榀�
+榀�
+榀�
+榀�
+榀�
+榀�
+榘�
+榘�
+榘�
+榀�
+榘�
+榘�
+榘�
+楸�
+榘�
+楸�
+楸�
+榘�
+楸�
+楸�
+楸�
+楸�
+楸�
+楸�
+楸�
+楸�
+楸�
+楸�
+槌�
+槌�
+槌�
+槌�
+槌�
+槌�
+槌�
+槌�
+槌�
+榇�
+槌�
+槌�
+榇�
+榇�
+榇�
+榇�
+榇�
+榇�
+榇�
+榇�
+榇�
+榇�
+榈�
+榈�
+榇�
+榇�
+榇�
+榇�
+榈�
+榈�
+榇�
+榈�
+榇�
+榈�
+榈�
+榈�
+榈�
+榈�
+榈�
+榈�
+榈�
+榈�
+槎�
+槎�
+槎�
+槎�
+榈�
+槎�
+榈�
+槎�
+槎�
+榈�
+榈�
+榈�
+榈�
+槎�
+榈�
+榈�
+槎�
+榈�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+槎�
+榉�
+榉�
+榉�
+榉�
+槎�
+榉�
+榉�
+槎�
+榉�
+槎�
+槎�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+榉�
+楦�
+榉�
+楦�
+楦�
+楦�
+楦�
+楦�
+楦�
+楦�
+榉�
+榉�
+楦�
+楦�
+楦�
+楦�
+楦�
+楦�
+楦�
+楦�
+楦�
+楣�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+楹�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榛�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榧�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榻�
+榫�
+榫�
+鍫�
+绀�
+钂�
+钂�
+鍏�
+鍏�
+鍏�
+鍏�
+鍏�
+鍏�
+鍡�
+鐡�
+蹇�
+鎿�
+姘�
+绌�
+鎿�
+璀�
+!
+"
+#
+$
+%
+&
+'
+(
+)
+*
++
+,
+-
+.
+/
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+:
+;
+<
+=
+>
+?
+A
+B
+C
+D
+E
+F
+G
+H
+I
+J
+K
+L
+M
+N
+O
+P
+Q
+R
+S
+T
+U
+V
+W
+X
+Y
+Z
+[
+]
+_
+`
+a
+b
+c
+d
+e
+f
+g
+h
+i
+j
+k
+l
+m
+n
+o
+p
+q
+r
+s
+t
+u
+v
+w
+x
+y
+z
+漏
+掳
+虏
+麓
+陆
+脕
+脛
+脜
+脟
+脠
+脡
+脥
+脫
+脰
+脳
+脺
+脽
+脿
+谩
+芒
+茫
+盲
+氓
+忙
+莽
+猫
+茅
+锚
+毛
+铆
+冒
+帽
+貌
+贸
+么
+玫
+枚
+酶
+煤
+没
+眉
+媒
+膩
+膬
+膮
+膰
+膶
+膷
+膽
+膿
+臈
+臋
+臒
+墨
+谋
+艁
+艂
+艅
+艌
+艒
+艡
+艦
+艧
+艩
+拧
+牛
+奴
+偶
+沤
+啪
+葮
+葯
+葲
+螖
+伪
+位
+渭
+蠁
+袚
+袨
+邪
+胁
+谢
+芯
+褉
+褋
+褌
+褟
+峄�
+鈥�
+鈥�
+鈥�
+鈥�
+鈥�
+鈥�
+鈩�
+鈫�
+鈭�
+鈭�
+鈻�
+鈽�
+銆�
+銆�
+銆�
+銆�
+銆�
+銆�
+銆�
+銆�
+銆�
+銆�
+銆�
+銆�
+銆�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锛�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+锝�
+菐
+菕
+臎
+菒
+矛
+菙
+霉
+菛
+菢
+菤
+菧
+銆�
+銆�
+銆�
+銆�
+鈥�
+{
+}
+\
+|
+@
+^
+~
+梅
+鈭�
+鈭�
+鈰�
+路
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+卤
+鈭�
+鈭�
+鈭�
+鈻�
+鈯�
+鈯�
+鈯�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈭�
+鈭�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+卢
+鈯�
+鈯�
+鈯�
+鈫�
+鈫�
+鈬�
+鈬�
+鈬�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈯�
+鈭�
+鈭�
+鈭�
+鈭�
+鈥�
+鈥�
+鈭�
+鈯�
+鈯�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+庐
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈩�
+惟
+鈩�
+鈩�
+鈱�
+鈩�
+鈪�
+鈲�
+鈲�
+垄
+鈧�
+拢
+楼
+锟�
+鈧�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+陋
+潞
+鈦�
+鹿
+鲁
+鈦�
+鈦�
+鈦�
+鈦�
+鈦�
+鈦�
+鈦�
+鈦�
+鈦�
+鈦�
+鈦�
+鈦�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈪�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈿�
+鈿�
+鈿�
+鉁�
+鉁�
+鉁�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+螒
+螔
+螕
+螘
+螙
+螚
+螛
+螜
+螝
+螞
+螠
+螡
+螢
+螣
+螤
+巍
+危
+韦
+违
+桅
+围
+唯
+尾
+纬
+未
+蔚
+味
+畏
+胃
+喂
+魏
+谓
+尉
+慰
+蟺
+蟻
+蟽
+蟿
+蠀
+蠂
+蠄
+蠅
+蠍
+蠎
+蠏
+蠒
+鈻�
+蠔
+习
+媳
+洗
+系
+蠞
+蠟
+蠠
+蠣
+稀
+息
+希
+悉
+膝
+夕
+惜
+熄
+烯
+溪
+汐
+犀
+檄
+袭
+席
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈭�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈮�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈯�
+鈩�
+鈩�
+鈩�
+鈩�
+鈩�
+鈩�
+鈩�
+鈩�
+鈱�
+鈱�
+鈱�
+鈱�
+鈳�
+陇
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈧�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈫�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈬�
+鈫�
+鈫�
+鈫�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈽�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鈿�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鈶�
+鈶�
+鈶�
+鈶�
+鈶�
+鈶�
+鈶�
+鈶�
+鈶�
+鈶�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鉃�
+鈱�
+鈱�
+鈱�
+鈳�
+鈱�
+鈱�
+鈴�
+鈱�
+鈱�
+鈱�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈳�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈻�
+鈻�
+鈼�
+鈴�
+鈴�
+鈴�
+蓯
+蓱
+蓲
+蓳
+蓴
+蓵
+蓶
+蓷
+蓸
+蓹
+蓺
+蓻
+蓽
+蓾
+蔀
+蔁
+蔂
+伞
+散
+桑
+嗓
+丧
+搔
+骚
+扫
+嫂
+瑟
+色
+涩
+森
+僧
+莎
+砂
+杀
+刹
+沙
+纱
+傻
+啥
+煞
+筛
+晒
+珊
+苫
+杉
+山
+删
+煽
+蕗
+蕘
+蕚
+蕛
+蕜
+蕝
+蕟
+蕠
+蕡
+蕢
+蕣
+蕥
+蕦
+蕧
+蕩
+蕪
+蕫
+蕬
+蕭
+蕮
+蕯
+蕰
+蕱
+蕳
+蕵
+蕶
+蕷
+蕸
+蕼
+蕽
+蕿
+薀
+薁
+省
+盛
+剩
+胜
+圣
+师
+失
+狮
+施
+湿
+诗
+尸
+虱
+十
+石
+鈹�
+茙
+脙
+鈼�
+鈻�
+锝�
+饾憿
+銆�
+銆�
+锔�
+鈥�
+锕�
+饾湏
+鈥�
+鈭�
+茠
+啷�
+鉁�
+袝
+鈼�
+銆�
+饾挶
+饾渾
+鉄�
+锕�
+鈼�
+鈺�
+鞓�
+藗
+鈱�
+饾潕
+鈻�
+鈻�
+鈻�
+鈼�
+銆�
+鈻�
+鈻�
+饾挳
+鈥�
+鈧�
+饧�
+銆�
+猸�
+鈺�
+鉄�
+鞙�
+猬�
+岷�
+鈼�
+铮�
+鈻�
+涓�
+锔�
+鈼�
+鈥�
+饾湆
+鈪�
+鈻�
+鈦�
+锕�
+馃榿
+馃槀
+馃槂
+馃槃
+馃槄
+馃槅
+馃槈
+馃槉
+馃構
+馃槍
+馃槏
+馃槒
+馃槖
+馃槗
+馃様
+馃槚
+馃槝
+馃槡
+馃槣
+馃槤
+馃槥
+馃槧
+馃槨
+馃槩
+馃槪
+馃槫
+馃槬
+馃槰
+馃槱
+馃槳
+馃槴
+馃槶
+馃槹
+馃槺
+馃槻
+馃槼
+馃樀
+馃樂
+馃樃
+馃樄
+馃樅
+馃樆
+馃樇
+馃樈
+馃樉
+馃樋
+馃檧
+馃檯
+馃檰
+馃檱
+馃檲
+馃檳
+馃檴
+馃檵
+馃檶
+馃檷
+馃檸
+馃檹
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉁�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+鉂�
+馃殌
+馃殐
+馃殑
+馃殔
+馃殗
+馃殙
+馃殞
+馃殢
+馃殤
+馃殥
+馃殦
+馃殨
+馃殫
+馃殭
+馃殮
+馃殺
+馃殼
+馃殽
+馃毀
+馃毃
+馃毄
+馃毆
+馃毇
+馃毈
+馃毉
+馃毑
+馃毝
+馃毠
+馃毢
+馃毣
+馃毤
+馃毥
+馃毦
+馃泙
+鈸�
+馃叞
+馃叡
+馃吘
+馃吙
+馃啂
+馃啈
+馃啋
+馃啌
+馃啍
+馃啎
+馃問
+馃啑
+馃啒
+馃啓
+馃啔
+馃嚛馃嚜
+馃嚞馃嚙
+馃嚚馃嚦
+馃嚡馃嚨
+馃嚝馃嚪
+馃嚢馃嚪
+馃嚜馃嚫
+馃嚠馃嚬
+馃嚪馃嚭
+馃嚭馃嚫
+馃垇
+鈩�
+鈱�
+鈱�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈴�
+鈼�
+鈼�
+鈼�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈾�
+鈿�
+鈿�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+鉀�
+猡�
+猡�
+猬�
+猬�
+猬�
+猬�
+猸�
+銆�
+銆�
+銑�
+銑�
+馃��
+馃儚
+馃寑
+馃寔
+馃寕
+馃寖
+馃寗
+馃寘
+馃寙
+馃寚
+馃寛
+馃寜
+馃寠
+馃寢
+馃寣
+馃審
+馃寫
+馃寭
+馃寯
+馃寱
+馃寵
+馃寷
+馃専
+馃尃
+馃尠
+馃尡
+馃尨
+馃尩
+馃尫
+馃尭
+馃尮
+馃尯
+馃尰
+馃尲
+馃尳
+馃尵
+馃尶
+馃崁
+馃崄
+馃崅
+馃崈
+馃崉
+馃崊
+馃崋
+馃崌
+馃崍
+馃崏
+馃崐
+馃崒
+馃崓
+馃崕
+馃崗
+馃崙
+馃崚
+馃崜
+馃崝
+馃崟
+馃崠
+馃崡
+馃崢
+馃崣
+馃崥
+馃崨
+馃崪
+馃崫
+馃崬
+馃崯
+馃崰
+馃崱
+馃崲
+馃崳
+馃崵
+馃崶
+馃崷
+馃崸
+馃崹
+馃崺
+馃崻
+馃崼
+馃崿
+馃嵀
+馃嵁
+馃嵂
+馃嵃
+馃嵄
+馃嵅
+馃嵆
+馃嵈
+馃嵉
+馃嵍
+馃嵎
+馃嵏
+馃嵐
+馃嵑
+馃嵒
+馃巰
+馃巵
+馃巶
+馃巸
+馃巹
+馃巺
+馃巻
+馃巼
+馃巿
+馃帀
+馃帄
+馃帇
+馃帉
+馃帊
+馃帋
+馃帍
+馃帎
+馃帒
+馃帓
+馃帗
+馃帬
+馃帯
+馃帰
+馃帲
+馃帳
+馃帴
+馃帵
+馃帶
+馃帹
+馃帺
+馃帾
+馃帿
+馃幀
+馃幁
+馃幃
+馃幆
+馃幇
+馃幈
+馃幉
+馃幊
+馃幋
+馃幍
+馃幎
+馃幏
+馃幐
+馃幑
+馃幒
+馃幓
+馃幖
+馃幗
+馃幘
+馃幙
+馃弨
+馃弫
+馃弬
+馃弮
+馃弰
+馃弳
+馃張
+馃強
+馃彔
+馃彙
+馃彚
+馃彛
+馃彞
+馃彟
+馃彠
+馃彣
+馃彥
+馃彧
+馃彨
+馃彫
+馃彮
+馃彯
+馃彲
+馃彴
+馃悓
+馃悕
+馃悗
+馃悜
+馃悞
+馃悢
+馃悧
+馃悩
+馃悪
+馃悮
+馃悰
+馃悳
+馃悵
+馃悶
+馃悷
+馃悹
+馃悺
+馃悽
+馃悾
+馃悿
+馃惀
+馃惁
+馃惂
+馃惃
+馃惄
+馃惈
+馃惉
+馃惌
+馃惍
+馃惎
+馃惏
+馃惐
+馃惒
+馃惓
+馃惔
+馃惖
+馃惗
+馃惙
+馃惛
+馃惞
+馃惡
+馃惢
+馃惣
+馃惤
+馃惥
+馃憖
+馃憘
+馃憙
+馃憚
+馃憛
+馃憜
+馃憞
+馃憟
+馃憠
+馃憡
+馃憢
+馃憣
+馃憤
+馃憥
+馃憦
+馃憪
+馃憫
+馃憭
+馃憮
+馃憯
+馃憰
+馃憱
+馃憲
+馃憳
+馃憴
+馃憵
+馃憶
+馃憸
+馃憹
+馃憺
+馃憻
+馃憼
+馃憽
+馃憿
+馃懀
+馃懁
+馃懄
+馃懅
+馃懆
+馃懇
+馃應
+馃懌
+馃懏
+馃懐
+馃懓
+馃懕
+馃懖
+馃懗
+馃懘
+馃懙
+馃懚
+馃懛
+馃懜
+馃懝
+馃懞
+馃懟
+馃懠
+馃懡
+馃懢
+馃懣
+馃拃
+馃拋
+馃拏
+馃拑
+馃拕
+馃拝
+馃拞
+馃拠
+馃拡
+馃拤
+馃拪
+馃拫
+馃拰
+馃拲
+馃拵
+馃拸
+馃拹
+馃拺
+馃拻
+馃挀
+馃挃
+馃挄
+馃挅
+馃挆
+馃挊
+馃挋
+馃挌
+馃挍
+馃挏
+馃挐
+馃挒
+馃挓
+馃挔
+馃挕
+馃挗
+馃挘
+馃挙
+馃挜
+馃挦
+馃挧
+馃挩
+馃挬
+馃挭
+馃挮
+馃挰
+馃挳
+馃挴
+馃挵
+馃挷
+馃挸
+馃挻
+馃挼
+馃捀
+馃捁
+馃捄
+馃捇
+馃捈
+馃捊
+馃捑
+馃捒
+馃搥
+馃搧
+馃搨
+馃搩
+馃搫
+馃搮
+馃搯
+馃搰
+馃搱
+馃搲
+馃搳
+馃搵
+馃搶
+馃搷
+馃搸
+馃搹
+馃搻
+馃搼
+馃搾
+馃摀
+馃摂
+馃摃
+馃摉
+馃摋
+馃摌
+馃摍
+馃摎
+馃摏
+馃摐
+馃摑
+馃摓
+馃摕
+馃摖
+馃摗
+馃摙
+馃摚
+馃摛
+馃摜
+馃摝
+馃摟
+馃摠
+馃摡
+馃摢
+馃摣
+馃摦
+馃摪
+馃摫
+馃摬
+馃摮
+馃摯
+馃摱
+馃摲
+馃摴
+馃摵
+馃摶
+馃摷
+馃攦
+馃攰
+馃攱
+馃攲
+馃攳
+馃攷
+馃攺
+馃攼
+馃攽
+馃敀
+馃敁
+馃敂
+馃敄
+馃敆
+馃敇
+馃敊
+馃敋
+馃敍
+馃敎
+馃敐
+馃敒
+馃敓
+馃敔
+馃敗
+馃敘
+馃敚
+馃敜
+馃敟
+馃敠
+馃敡
+馃敤
+馃敥
+馃敧
+馃敨
+馃敭
+馃敮
+馃敯
+馃敱
+馃敳
+馃敵
+馃敶
+馃數
+馃敹
+馃敺
+馃敻
+馃敼
+馃敽
+馃敾
+馃敿
+馃斀
+馃晲
+馃晳
+馃晵
+馃晸
+馃晹
+馃晻
+馃晼
+馃晽
+馃晿
+馃暀
+馃暁
+馃暃
+馃椈
+馃椉
+馃椊
+馃椌
+馃椏
+馃榾
+馃槆
+馃槇
+馃槑
+馃槓
+馃槕
+馃槙
+馃槜
+馃槞
+馃槢
+馃槦
+馃槮
+馃槯
+馃槵
+馃槷
+馃槸
+馃槾
+馃樁
+馃殎
+馃殏
+馃殕
+馃殘
+馃殜
+馃殟
+馃殠
+馃殣
+馃殧
+馃殩
+馃殬
+馃殯
+馃殰
+馃殱
+馃殲
+馃殶
+馃殸
+馃殹
+馃殻
+馃殾
+馃毊
+馃毌
+馃毎
+馃毐
+馃毘
+馃毚
+馃毜
+馃毞
+馃毟
+馃毧
+馃泚
+馃泜
+馃泝
+馃泟
+馃泤
+馃實
+馃寧
+馃寪
+馃寬
+馃寲
+馃寳
+馃寴
+馃寶
+馃寽
+馃対
+馃尀
+馃尣
+馃尦
+馃崑
+馃崘
+馃嵓
+馃弴
+馃弶
+馃彜
+馃悁
+馃悂
+馃悅
+馃悆
+馃悇
+馃悈
+馃悊
+馃悋
+馃悎
+馃悏
+馃悐
+馃悑
+馃悘
+馃悙
+馃悡
+馃悤
+馃悥
+馃惇
+馃懃
+馃懍
+馃懎
+馃挱
+馃挾
+馃挿
+馃摤
+馃摥
+馃摨
+馃摰
+馃攢
+馃攣
+馃攤
+馃攧
+馃攨
+馃攩
+馃攪
+馃攭
+馃敃
+馃敩
+馃敪
+馃暅
+馃暆
+馃暈
+馃暉
+馃暊
+馃暋
+馃暍
+馃暎
+馃暏
+馃暐
+馃暒
+馃暓
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 0000000..a7afc92
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,2 @@
+server:
+ port: 8080
diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000..4d5397f
--- /dev/null
+++ b/src/main/resources/logback-spring.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="false" scan="false">
+ <property name="log.path" value="logs/${project.artifactId}"/>
+ <!-- 褰╄壊鏃ュ織鏍煎紡 -->
+ <property name="CONSOLE_LOG_PATTERN"
+ value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
+ <!-- 褰╄壊鏃ュ織渚濊禆鐨勬覆鏌撶被 -->
+ <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
+ <conversionRule conversionWord="wex"
+ converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
+ <conversionRule conversionWord="wEx"
+ converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
+ <!-- Console log output -->
+ <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+ </encoder>
+ </appender>
+
+ <!-- Log file debug output -->
+ <appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${log.path}/debug.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+ <fileNamePattern>${log.path}/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+ <maxFileSize>50MB</maxFileSize>
+ <maxHistory>30</maxHistory>
+ </rollingPolicy>
+ <encoder>
+ <pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <!-- Log file error output -->
+ <appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${log.path}/error.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+ <fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+ <maxFileSize>50MB</maxFileSize>
+ <maxHistory>30</maxHistory>
+ </rollingPolicy>
+ <encoder>
+ <pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
+ </encoder>
+ <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+ <level>ERROR</level>
+ </filter>
+ </appender>
+
+ <logger name="org.activiti.engine.impl.db" level="DEBUG">
+ <appender-ref ref="debug"/>
+ </logger>
+
+ <!--nacos 蹇冭烦 INFO 灞忚斀-->
+ <logger name="com.alibaba.nacos" level="OFF">
+ <appender-ref ref="error"/>
+ </logger>
+
+ <!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
+ <root level="INFO">
+ <appender-ref ref="console"/>
+ <appender-ref ref="debug"/>
+ </root>
+</configuration>
--
Gitblit v1.9.3