diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..5906b376 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,24 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "[BUG]" +labels: bug +assignees: godcong + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**Environment** +System: windows/linux/macos +Database: mysql version and fate_db version +Source: source release version or commit hash + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Additional context** +Add any other context about the problem here. +Issues that have not been followed up for more than 14 days may be closed + diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..4ca67adc --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: gomod + directory: / + schedule: + interval: daily \ No newline at end of file diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml new file mode 100644 index 00000000..83f126da --- /dev/null +++ b/.github/workflows/build_linux.yml @@ -0,0 +1,95 @@ +name: Build Linux + +on: + push: + branches: [main] + pull_request: + branches: [main] +env: + UPLOAD_BIN_FILE: true + +jobs: + build: + name: Build + strategy: + matrix: + go-version: [1.19.x] + platform: [ubuntu-latest] + arch: [386, amd64] + runs-on: ${{ matrix.platform }} + steps: + - name: Check out code into the Go module directory + uses: actions/checkout@v3 + + - name: Install Go + uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.go-version }} + + - name: Build ${{ matrix.platform }} ${{ matrix.arch }} with Go + if: (matrix.platform == 'ubuntu-latest' || matrix.platform == 'macos-latest') && matrix.arch == 'amd64' && env.UPLOAD_BIN_FILE + id: build_linux_amd64 + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: "true" + run: | + go mod tidy + export GOARCH=${{ matrix.arch }} + export CGO_ENABLED=1 + echo "FATENAME=fate_$(go env GOOS)_$(go env GOARCH)" >> $GITHUB_ENV + echo "$(go env GOOS) $(go env GOARCH)" + + echo "building" + go build -o fate_$(go env GOOS)_$(go env GOARCH) -v ./cmd/console + + echo "compress" + tar -zcvf fate_$(go env GOOS)_$(go env GOARCH).tar.gz ./fate_$(go env GOOS)_$(go env GOARCH) + + - name: Build ${{ matrix.platform }} ${{ matrix.arch }} with Go + if: matrix.platform == 'ubuntu-latest' && matrix.arch == '386' && env.UPLOAD_BIN_FILE + id: build_linux_386 + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: "true" + run: | + go mod tidy + export GOARCH=${{ matrix.arch }} + export CGO_ENABLED=1 + sudo apt-get install -y gcc-i686-linux-gnu g++-i686-linux-gnu + export AR="/usr/bin/i686-linux-gnu-ar -m32" + export CXX="/usr/bin/i686-linux-gnu-cpp -m32" + export CC="/usr/bin/i686-linux-gnu-gcc -m32" + echo "FATENAME=fate_$(go env GOOS)_$(go env GOARCH)" >> $GITHUB_ENV + echo "$(go env GOOS) $(go env GOARCH)" + + echo "building" + go build -o fate_$(go env GOOS)_$(go env GOARCH) -v ./cmd/console + + echo "compress" + tar -zcvf fate_$(go env GOOS)_$(go env GOARCH).tar.gz ./fate_$(go env GOOS)_$(go env GOARCH) + + - name: Upload Linux + uses: actions/upload-artifact@master + if: (matrix.platform == 'ubuntu-latest' || matrix.platform == 'macos-latest') && env.UPLOAD_BIN_FILE + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: "true" + with: + name: ${{ env.FATENAME }}.tar.gz + path: ${{ env.FATENAME }}.tar.gz + + - name: Create Release + id: create_release_linux + if: (matrix.platform == 'ubuntu-latest' || matrix.platform == 'macos-latest') && env.UPLOAD_BIN_FILE + uses: ncipollo/release-action@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + ACTIONS_ALLOW_UNSECURE_COMMANDS: "true" + with: + artifacts: "${{ env.FATENAME }}.tar.gz" + allowUpdates: true + commit: master + tag: auto_build + body: | + This is only a latest build from master + **Version: https://github.com/babyname/fate/commit/${{ github.sha }}** + token: ${{ secrets.GITHUB_TOKEN }} + draft: false + prerelease: false diff --git a/.github/workflows/build_macos.yml b/.github/workflows/build_macos.yml new file mode 100644 index 00000000..09d789e7 --- /dev/null +++ b/.github/workflows/build_macos.yml @@ -0,0 +1,97 @@ +name: Build Macos + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] +env: + UPLOAD_BIN_FILE: true + +jobs: + + build: + name: Build + strategy: + matrix: + go-version: [ 1.19.x ] + platform: [ macos-latest ] + arch: [ 386, amd64 ] + runs-on: ${{ matrix.platform }} + steps: + - name: Check out code into the Go module directory + uses: actions/checkout@v3 + + - name: Install Go + uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.go-version }} + + - name: Build ${{ matrix.platform }} ${{ matrix.arch }} with Go + if: (matrix.platform == 'ubuntu-latest' || matrix.platform == 'macos-latest') && matrix.arch == 'amd64' && env.UPLOAD_BIN_FILE + id: build_linux_amd64 + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' + run: | + go mod tidy + export GOARCH=${{ matrix.arch }} + export CGO_ENABLED=1 + echo "FATENAME=fate_$(go env GOOS)_$(go env GOARCH)" >> $GITHUB_ENV + echo "$(go env GOOS) $(go env GOARCH)" + + echo "building" + go build -o fate_$(go env GOOS)_$(go env GOARCH) -v ./cmd/console + + echo "compress" + tar -zcvf fate_$(go env GOOS)_$(go env GOARCH).tar.gz ./fate_$(go env GOOS)_$(go env GOARCH) + + - name: Build ${{ matrix.platform }} ${{ matrix.arch }} with Go + if: matrix.platform == 'ubuntu-latest' && matrix.arch == '386' && env.UPLOAD_BIN_FILE + id: build_linux_386 + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' + run: | + go mod tidy + export GOARCH=${{ matrix.arch }} + export CGO_ENABLED=1 + sudo apt-get install -y gcc-i686-linux-gnu g++-i686-linux-gnu + export AR="/usr/bin/i686-linux-gnu-ar -m32" + export CXX="/usr/bin/i686-linux-gnu-cpp -m32" + export CC="/usr/bin/i686-linux-gnu-gcc -m32" + echo "FATENAME=fate_$(go env GOOS)_$(go env GOARCH)" >> $GITHUB_ENV + echo "$(go env GOOS) $(go env GOARCH)" + + echo "building" + go build -o fate_$(go env GOOS)_$(go env GOARCH) -v ./cmd/console + + echo "compress" + tar -zcvf fate_$(go env GOOS)_$(go env GOARCH).tar.gz ./fate_$(go env GOOS)_$(go env GOARCH) + + - name: Upload Linux + uses: actions/upload-artifact@master + if: (matrix.platform == 'ubuntu-latest' || matrix.platform == 'macos-latest') && env.UPLOAD_BIN_FILE + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' + with: + name: ${{ env.FATENAME }}.tar.gz + path: ${{ env.FATENAME }}.tar.gz + + - name: Create Release + id: create_release_linux + if: (matrix.platform == 'ubuntu-latest' || matrix.platform == 'macos-latest') && env.UPLOAD_BIN_FILE + uses: ncipollo/release-action@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' + with: + artifacts: "${{ env.FATENAME }}.tar.gz" + allowUpdates: true + commit: master + tag: auto_build + body: | + This is only a latest build from master + **Version: https://github.com/babyname/fate/commit/${{ github.sha }}** + token: ${{ secrets.GITHUB_TOKEN }} + draft: false + prerelease: false + diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build_windows.yml new file mode 100644 index 00000000..d6a495c3 --- /dev/null +++ b/.github/workflows/build_windows.yml @@ -0,0 +1,97 @@ +name: Build Windows + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] +env: + UPLOAD_BIN_FILE: true + +jobs: + + build: + name: Build + strategy: + matrix: + go-version: [ 1.19.x ] + platform: [ windows-latest ] + arch: [ 386, amd64 ] + runs-on: ${{ matrix.platform }} + steps: + - name: Cleanup pre-installed tools + if: matrix.platform != 'windows-latest' + run: | + # This is a fix for https://github.com/actions/virtual-environments/issues/1918 + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf "/usr/local/share/boost" + sudo rm -rf "$AGENT_TOOLSDIRECTORY" + + - name: Check out code into the Go module directory + uses: actions/checkout@v3 + + - name: Install Go + uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.go-version }} + + - name: Build ${{ matrix.platform }} ${{ matrix.arch }} with Go + if: matrix.platform == 'windows-latest' && matrix.arch == 'amd64' && env.UPLOAD_BIN_FILE + id: build_windows_amd64 + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' + run: | + go mod tidy + set GOARCH=${{ matrix.arch }} + set CGO_ENABLED=1 + echo "FATENAME=fate_windows_amd64" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "building" + go build -o fate_windows_amd64.exe -v ./cmd/console + + echo "compress" + Compress-Archive -Path fate_windows_amd64.exe -DestinationPath fate_windows_amd64.zip + + - name: Build ${{ matrix.platform }} ${{ matrix.arch }} with Go + if: matrix.platform == 'windows-latest' && matrix.arch == '386' && env.UPLOAD_BIN_FILE + id: build_windows_386 + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' + run: | + go mod tidy + set GOARCH=${{ matrix.arch }} + set CGO_ENABLED=1 + echo "FATENAME=fate_windows_386" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "building" + go build -o fate_windows_386.exe -v ./cmd/console + + echo "compress" + Compress-Archive -Path fate_windows_386.exe -DestinationPath fate_windows_386.zip + + - name: Upload Windows + uses: actions/upload-artifact@master + if: matrix.platform == 'windows-latest' && env.UPLOAD_BIN_FILE + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' + with: + name: ${{ env.FATENAME }}.zip + path: ${{ env.FATENAME }}.zip + + - name: Create Release + id: create_release_windows + if: matrix.platform == 'windows-latest' && env.UPLOAD_BIN_FILE + uses: ncipollo/release-action@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' + with: + artifacts: "${{ env.FATENAME }}.zip" + allowUpdates: true + commit: master + tag: auto_build + body: | + This is only a latest build from master + **Version: https://github.com/babyname/fate/commit/${{ github.sha }}** + token: ${{ secrets.GITHUB_TOKEN }} + draft: false + prerelease: false diff --git a/.github/workflows/close-issues.yml b/.github/workflows/close-issues.yml new file mode 100644 index 00000000..cfaf4296 --- /dev/null +++ b/.github/workflows/close-issues.yml @@ -0,0 +1,22 @@ +name: Close inactive issues +on: + schedule: + - cron: "30 1 * * *" + +jobs: + close-issues: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v3 + with: + days-before-issue-stale: 180 + days-before-issue-close: 360 + stale-issue-label: "stale" + stale-issue-message: "This issue is stale because it has been open for 30 days with no activity." + close-issue-message: "This issue was closed because it has been inactive for 60 days since being marked as stale." + days-before-pr-stale: -1 + days-before-pr-close: -1 + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index a1338d68..92129d82 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,34 @@ -# Binaries for programs and plugins +vendor/ +#Ignore thumbnails created by Windows +Thumbs.db +#Ignore files built by Visual Studio +*.obj *.exe -*.dll -*.so -*.dylib - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 -.glide/ +*.pdb +*.user +*.aps +*.pch +*.vspscc +*_i.c +*_p.c +*.ncb +*.suo +*.tlb +*.tlh +*.bak +*.cache +*.ilk +*.log +[Bb]in +#[Dd]ebug*/ +*.lib +*.sbr +obj/ +[Rr]elease*/ +_ReSharper*/ +[Tt]est[Rr]esult* +.vs/ +#Nuget packages folder +packages/ +/.idea +go.sum \ No newline at end of file diff --git a/README.md b/README.md index da388d52..ed86d7f4 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,201 @@ -# fate # -### 开源三才五格起名算法框架 ### -作为一个开源的算命项目这大概是github上第一个了吧 +# 命运起名(Fate) + +![FATE](docs/fate.png) + +![Go](https://github.com/babyname/fate/workflows/Go/badge.svg) +[![GoDoc](https://godoc.org/github.com/babyname/fate?status.svg)](http://godoc.org/github.com/babyname/fate) +[![license](https://img.shields.io/github/license/babyname/fate.svg)](https://github.com/babyname/fate/blob/master/LICENSE) +[![Go Report Card](https://goreportcard.com/badge/github.com/babyname/fate)](https://goreportcard.com/report/github.com/babyname/fate) + +## 现代科学取名工具(A modern science chinese name create tool) + +Github上第一个开源的中文取名项目(The first chinese name create tool in `github`) + +## 目录 + +[TOR] + +### 简介 + +本程序适用于单个姓或双个姓, 起2个名的情况. (如:独孤**, 李张**, 张**, 王**) +一个好名字伴随人的一生, FATE让你取一个好名字. + +### 关于版本 + +特定版本会单独出release,以后每次提交都会生成二进制文件的pre_release提供下载. +最新版使用Sqlite3数据库,不在需要导入数据库文件了. 直接下载下面的Sqlite3数据库到本地就能使用. + +【[v3.5.5下载](https://github.com/babyname/fate/releases/tag/v3.5.5)】 +【[Sqlite3数据库](https://github.com/babyname/fate/releases/download/v3.5.4/fate_sqlite3_database.zip)】 + +【[最新自编译版本](https://github.com/babyname/fate/releases/tag/auto_build)】 +【[旧版SQL数据库文件:20200331](https://github.com/babyname/fate/releases/download/v3.5.1/fate_db_200331.7z)】 + +### 使用方法 + +1. 编写运行go代码,接口调用生成姓名 + + ```go + // 使用前请导入database的数据(测试字库已基本完善, 保险起见生成姓名后可以去一些测名网站验证下) + // 加载配置(具体参数参考example/create_a_name) + cfg := config.Default() + // 生日: + born := chronos.New("2020/01/23 11:31") + // 姓氏: + lastName := "张" + // 第一参数:姓氏 + // 第二参数:生日 + f := fate.NewFate(lastName, born.Solar().Time(), fate.ConfigOption(cfg)) + + e := f.MakeName(context.Background()) + if e != nil { + t.Fatal(e) + } + + ``` + +2. 使用预编译二进制文件生成姓名 + + ```shell + #没有安装go环境的请下载master下的zoneinfo文件和fate二进制文件放一起 + #生成配置文件, 可修改数据库, 及一些基本参数 + fate.exe init + #输出姓名 + fate.exe name -l 张 -b "2020/02/06 15:04" + ``` + +3. ~~针对没有安装Go环境的用户,使用二进制文件在运行前务必把zoneinfo.zip下载并和二进制文件放在一起(不要解压),不然会报错.~~ + ~~[zoneinfo文件](https://github.com/babyname/fate/blob/master/zoneinfo.zip)~~ + 最新编译的版本使用了Go新版编译, 已经不再需要手动下载`zoneinfo.zip`文件了. + +### 常见问题 + +1. 报错: count total error:The system cannot find the path specified + + ```docs + zoneinfo缺失导致的时间转换失败问题(一般发生在windows环境下), + 下载上面的zoneinfo文件并放到执行文件相同的目录下即可解决. + 最新版会检查根目录,已无需重新init. + 地址:https://github.com/babyname/fate/blob/master/zoneinfo.zip + ``` + +2. 如何导入数据(Mysql) + + ```docs + //链接到mysql数据库 + mysql -u用户名 -p密码 + //创建数据库 + CREATE schema `fate` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; + //使用fate数据库 + use fate; + //导入数据库文件 + source /path/to/sql/file; + PS:建议使用Navicat等工具导入,导入速度较快 + ``` + +3. 数据库配置, 替换config.json中相关部分 + - MYSQL配置: + - host填写mysql数据库的地址 + - user填写mysql数据库的用户名 + - pwd填写mysql数据库的密码 + - name填写mysql数据库的库名 + + ```json + "database": { + "host": "127.0.0.1", + "port": "3306", + "user": "root", + "pwd": "111111", + "name": "fate", + "max_idle_con": 0, + "max_open_con": 0, + "driver": "mysql", + "file": "", + "dsn": "", + "show_sql": false, + "show_exec_time": false + }, + ``` + + - SQLITE3配置: + - name填写本地sqlite的数据库名字, 放在fate同一目录下 + + ```json + "database": { + "name": "fate", + "driver": "sqlite3", + }, + ``` + +## 版本计划 + +第一版: +大部分是手动工作,现已废弃 + +第二版: +可自动生成名字字符 + 手工筛选 + +第三版(开发中): + +1. 添加API接口查询(后期可能需要一些WEB方面的工作, 如果有兴趣的可以报名). +2. 完善精简字典库, 并迁移到EntORM. +3. 更完善的查询规则定义. + +第四版(计划中): +优化算法,调整接口,数据库,完善文档以及修复一些bug. + +第七版(计划中): +通过AI,大数据匹配算法,取出更好更佳的名字. + +### 关于FATE + +FATE使用了以下算法,查询字典库自动生成匹配规则的名字. +按照每种算法的准确度,使用程度也有高有低,不会一概而否,也不会偏向单独某种算法. +不会按照个人喜好做出选择. + +- 周易卦象 +- 大衍之数 +- 三才五格 +- 喜用神(平衡用神) +- 生肖用字 +- 八字吉凶 + +目前Fate以六大派为基准综合计算生成名字: + +- 笔划派: 认为笔划全吉, 人生就大吉. 准确度12.5 % +- 三才派: 完全不管笔划吉凶, 只认为天地人三才五行相生, 人生就大吉. 准确度56.6 %. +- 补八字: 完全不管笔划吉凶, 只认为名字补到先天八字命盘欠缺, 人生就大吉. 其实准确度非常低. +- 卦象派: 完全不管笔划吉凶, 只认为名字求出卦象漂亮, 人生就大吉. 准确度40.26 %. +- 天运派: 完全不管笔划吉凶, 只认为名字不要被出生年天运五行所剋, 人生就大吉. 准确度25.32 %. +- 生肖派: 完全不管笔划吉凶, 只认为生肖用对字形, 人生就大吉. 准确度27.55 %. + +目前使用到的一些库: + +- 八字计算(用于计算生辰): +- 字典数据(一个爬虫工具填充字典数据库): + 如果谁有更好用的可以告诉我. + +### 资料查询 + +1. 全国及各省重名查询网址汇总 + + 网友提供:`https://zhuanlan.zhihu.com/p/89654568`(**请谨慎访问非本站点地址**) + [本仓库地址](./docs/chinese_name_query.md) + +## 一些废话 + +在过去的几年中虽然Fate经过了好几个版本的改进, 但是仍然有许多不足之处. +包括生成的名字太多不容易筛选, +有些用户遇到了一些和Go相关的问题, +一些用户不知道如何导入数据库等. +这些问题都只能慢慢想办法去解决. + +还有些用户因为字典库生成的名字中有些字的寓意不好, 你可以手动删掉你不喜欢字, 却来恶意中伤作者. +我想说的是这个字也不是我造的, 你如果有问题可以去找造那个字的人. +如果觉得这个工具不好你可以不用. + +最近一年中因为作者个人原因导致Fate更新缓慢, 在这里向大家道个歉. +大家也知道现在国内的IT环境, 毕竟我也要生活, 生活所迫没有太多时间放在业余的项目上. +我只能尽量抽出时间来完善Fate的规则和代码. +在这里同样要感谢支持我的朋友们, 大家的出发点我相信是一样的. +用这个工具目的都是为了给孩子取一个好名字. \ No newline at end of file diff --git a/README_EN.md b/README_EN.md new file mode 100644 index 00000000..6d5a17bf --- /dev/null +++ b/README_EN.md @@ -0,0 +1,14 @@ +# Fate + +![FATE](docs/fate.png) + +![Go](https://github.com/babyname/fate/workflows/Go/badge.svg) +[![GoDoc](https://godoc.org/github.com/babyname/fate?status.svg)](http://godoc.org/github.com/babyname/fate) +[![license](https://img.shields.io/github/license/babyname/fate.svg)](https://github.com/babyname/fate/blob/master/LICENSE) +[![Go Report Card](https://goreportcard.com/badge/github.com/babyname/fate)](https://goreportcard.com/report/github.com/babyname/fate) + +## Introduce + +A modern science chinese name create tool. +The first chinese name create tool in github +It uses some traditional Chinese algorithms. It is used to get a good name for a newborn baby. \ No newline at end of file diff --git a/bazi.go b/bazi.go new file mode 100644 index 00000000..a6678d7b --- /dev/null +++ b/bazi.go @@ -0,0 +1,219 @@ +package fate + +import ( + "strings" + + "github.com/godcong/chronos" +) + +var diIndex = map[string]int{ + "子": 0, "丑": 1, "寅": 2, "卯": 3, "辰": 4, "巳": 5, "午": 6, "未": 7, "申": 8, "酉": 9, "戌": 10, "亥": 11, +} + +var tianIndex = map[string]int{ + "甲": 0, "乙": 1, "丙": 2, "丁": 3, "戊": 4, "己": 5, "庚": 6, "辛": 7, "壬": 8, "癸": 9, +} + +// 天干强度表 +var tiangan = [][]int{ + {1200, 1200, 1000, 1000, 1000, 1000, 1000, 1000, 1200, 1200}, + {1060, 1060, 1000, 1000, 1100, 1100, 1140, 1140, 1100, 1100}, + {1140, 1140, 1200, 1200, 1060, 1060, 1000, 1000, 1000, 1000}, + {1200, 1200, 1200, 1200, 1000, 1000, 1000, 1000, 1000, 1000}, + {1100, 1100, 1060, 1060, 1100, 1100, 1100, 1100, 1040, 1040}, + {1000, 1000, 1140, 1140, 1140, 1140, 1060, 1060, 1060, 1060}, + {1000, 1000, 1200, 1200, 1200, 1200, 1000, 1000, 1000, 1000}, + {1040, 1040, 1100, 1100, 1160, 1160, 1100, 1100, 1000, 1000}, + {1060, 1060, 1000, 1000, 1000, 1000, 1140, 1140, 1200, 1200}, + {1000, 1000, 1000, 1000, 1000, 1000, 1200, 1200, 1200, 1200}, + {1000, 1000, 1040, 1040, 1140, 1140, 1160, 1160, 1060, 1060}, + {1200, 1200, 1000, 1000, 1000, 1000, 1000, 1000, 1140, 1140}, +} + +// 地支强度表 +var dizhi = []map[string][]int{ + { + "癸": {1200, 1100, 1000, 1000, 1040, 1060, 1000, 1000, 1200, 1200, 1060, 1140}, + }, { + "癸": {360, 330, 300, 300, 312, 318, 300, 300, 360, 360, 318, 342}, + "辛": {200, 228, 200, 200, 230, 212, 200, 220, 228, 248, 232, 200}, + "己": {500, 550, 530, 500, 550, 570, 600, 580, 500, 500, 570, 500}, + }, { + "丙": {300, 300, 360, 360, 318, 342, 360, 330, 300, 300, 342, 318}, + "甲": {840, 742, 798, 840, 770, 700, 700, 728, 742, 700, 700, 840}, + }, { + "乙": {1200, 1060, 1140, 1200, 1100, 1000, 1000, 1040, 1060, 1000, 1000, 1200}, + }, { + "乙": {360, 318, 342, 360, 330, 300, 300, 312, 318, 300, 300, 360}, + "癸": {240, 220, 200, 200, 208, 200, 200, 200, 240, 240, 212, 228}, + "戊": {500, 550, 530, 500, 550, 600, 600, 580, 500, 500, 570, 500}, + }, { + "庚": {300, 342, 300, 300, 330, 300, 300, 330, 342, 360, 348, 300}, + "丙": {700, 700, 840, 840, 742, 840, 840, 798, 700, 700, 728, 742}, + }, { + "丁": {1000, 1000, 1200, 1200, 1060, 1140, 1200, 1100, 1000, 1000, 1040, 1060}, + }, { + "丁": {300, 300, 360, 360, 318, 342, 360, 330, 300, 300, 312, 318}, + "乙": {240, 212, 228, 240, 220, 200, 200, 208, 212, 200, 200, 240}, + "己": {500, 550, 530, 500, 550, 570, 600, 580, 500, 500, 570, 500}, + }, { + "壬": {360, 330, 300, 300, 312, 318, 300, 300, 360, 360, 318, 342}, + "庚": {700, 798, 700, 700, 770, 742, 700, 770, 798, 840, 812, 700}, + }, { + "辛": {1000, 1140, 1000, 1000, 1100, 1060, 1000, 1100, 1140, 1200, 1160, 1000}, + }, { + "辛": {300, 342, 300, 300, 330, 318, 300, 330, 342, 360, 348, 300}, + "丁": {200, 200, 240, 240, 212, 228, 240, 220, 200, 200, 208, 212}, + "戊": {500, 550, 530, 500, 550, 570, 600, 580, 500, 500, 570, 500}, + }, { + "甲": {360, 318, 342, 360, 330, 300, 300, 312, 318, 300, 300, 360}, + "壬": {840, 770, 700, 700, 728, 742, 700, 700, 840, 840, 724, 798}, + }, +} + +var wuXingTianGan = map[string]string{ + "甲": "木", + "乙": "木", + "丙": "火", + "丁": "火", + "戊": "土", + "己": "土", + "庚": "金", + "辛": "金", + "壬": "水", + "癸": "水", +} + +var wuXingDiZhi = map[string]string{ + "子": "水", + "丑": "土", + "寅": "木", + "卯": "木", + "辰": "土", + "巳": "火", + "午": "火", + "未": "土", + "申": "金", + "酉": "金", + "戌": "土", + "亥": "水", +} + +// WuXingTianGan 五行天干 +func WuXingTianGan(s string) string { + return wuXingTianGan[s] +} + +// WuXingDiZhi 五行地支 +func WuXingDiZhi(s string) string { + return wuXingDiZhi[s] +} + +// BaZi ... +type BaZi struct { + baZi []string + wuXing []string + xiyong *XiYong +} + +// NewBazi 创建八字 +func NewBazi(calendar chronos.Calendar) *BaZi { + ec := calendar.Lunar().EightCharacter() + return &BaZi{ + baZi: ec, + wuXing: baziToWuXing(ec), + } +} + +// String ... +func (z *BaZi) String() string { + return strings.Join(z.baZi, "") +} + +// RiZhu 日主 +func (z *BaZi) RiZhu() string { + return z.baZi[4] +} + +func (z *BaZi) calcXiYong() { + z.xiyong = &XiYong{} + // TODO:need fix + z.point().calcSimilar().calcHeterogeneous() // .yongShen().xiShen() +} + +// XiYong 喜用神 +func (z *BaZi) XiYong() *XiYong { + if z.xiyong == nil { + z.calcXiYong() + } + return z.xiyong +} + +// XiYongShen 平衡用神 +func (z *BaZi) XiYongShen() string { + return z.XiYong().Shen() +} + +func (z *BaZi) point() *BaZi { + di := diIndex[z.baZi[3]] + for idx, v := range z.baZi { + if idx%2 == 0 { + z.xiyong.AddFen(WuXingTianGan(v), tiangan[di][tianIndex[v]]) + } else { + dz := dizhi[diIndex[v]] + for k := range dz { + z.xiyong.AddFen(WuXingTianGan(k), dz[k][di]) + } + } + } + return z +} + +func baziToWuXing(bazi []string) []string { + var wx []string + for idx, v := range bazi { + if idx%2 == 0 { + wx = append(wx, WuXingTianGan(v)) + } else { + wx = append(wx, WuXingDiZhi(v)) + } + } + return wx +} + +// 计算同类 +func (z *BaZi) calcSimilar() *BaZi { + for i := range sheng { + if wuXingTianGan[z.RiZhu()] == sheng[i] { + z.xiyong.Similar = append(z.xiyong.Similar, sheng[i]) + z.xiyong.SimilarPoint = z.xiyong.GetFen(sheng[i]) + if i == 0 { + i = len(sheng) - 1 + z.xiyong.Similar = append(z.xiyong.Similar, sheng[i]) + z.xiyong.SimilarPoint += z.xiyong.GetFen(sheng[i]) + } else { + z.xiyong.Similar = append(z.xiyong.Similar, sheng[i-1]) + z.xiyong.SimilarPoint += z.xiyong.GetFen(sheng[i-1]) + } + break + } + } + return z +} + +// 计算异类 +func (z *BaZi) calcHeterogeneous() *BaZi { + for i := range sheng { + for ti := range z.xiyong.Similar { + if z.xiyong.Similar[ti] == sheng[i] { + goto EndSimilar + } + } + z.xiyong.Heterogeneous = append(z.xiyong.Heterogeneous, sheng[i]) + z.xiyong.HeterogeneousPoint += z.xiyong.GetFen(sheng[i]) + EndSimilar: + continue + + } + return z +} diff --git a/bazi_test.go b/bazi_test.go new file mode 100644 index 00000000..237ed714 --- /dev/null +++ b/bazi_test.go @@ -0,0 +1,19 @@ +package fate_test + +import ( + "log" + "testing" + + "github.com/godcong/chronos" + + "github.com/babyname/fate" +) + +func TestPoint(t *testing.T) { + t1 := chronos.New("2020/01/24 15:30") + log.Println(t1.Lunar().EightCharacter()) + + bz := fate.NewBazi(t1) + t.Log(bz.XiYong()) + t.Log(bz.XiYongShen()) +} diff --git a/character.go b/character.go new file mode 100644 index 00000000..f6f35aab --- /dev/null +++ b/character.go @@ -0,0 +1,113 @@ +package fate + +import ( + "crypto/sha256" + "fmt" + + "github.com/xormsharp/builder" + "github.com/xormsharp/xorm" +) + +// Character 字符 +type Character struct { + Hash string `xorm:"pk hash"` + PinYin []string `xorm:"default() notnull pin_yin"` // 拼音 + Ch string `xorm:"default() notnull ch"` // 字符 + ScienceStroke int `xorm:"default(0) notnull science_stroke" json:"science_stroke"` // 科学笔画 + Radical string `xorm:"default() notnull radical"` // 部首 + RadicalStroke int `xorm:"default(0) notnull radical_stroke"` // 部首笔画 + Stroke int `xorm:"default() notnull stroke"` // 总笔画数 + IsKangXi bool `xorm:"default(0) notnull is_kang_xi"` // 是否康熙字典 + KangXi string `xorm:"default() notnull kang_xi"` // 康熙 + KangXiStroke int `xorm:"default(0) notnull kang_xi_stroke"` // 康熙笔画 + SimpleRadical string `xorm:"default() notnull simple_radical"` // 简体部首 + SimpleRadicalStroke int `xorm:"default(0) notnull simple_radical_stroke"` // 简体部首笔画 + SimpleTotalStroke int `xorm:"default(0) notnull simple_total_stroke"` // 简体笔画 + TraditionalRadical string `xorm:"default() notnull traditional_radical"` // 繁体部首 + TraditionalRadicalStroke int `xorm:"default(0) notnull traditional_radical_stroke"` // 繁体部首笔画 + TraditionalTotalStroke int `xorm:"default(0) notnull traditional_total_stroke"` // 简体部首笔画 + NameScience bool `xorm:"default(0) notnull name_science"` // 姓名学 + WuXing string `xorm:"default() notnull wu_xing"` // 五行 + Lucky string `xorm:"default() notnull lucky"` // 吉凶寓意 + Regular bool `xorm:"default(0) notnull regular"` // 常用 + TraditionalCharacter []string `xorm:"default() notnull traditional_character"` // 繁体字 + VariantCharacter []string `xorm:"default() notnull variant_character"` // 异体字 + Comment []string `xorm:"default() notnull comment"` // 解释 +} + +// InsertOrUpdateCharacter ... +func InsertOrUpdateCharacter(engine *xorm.Engine, c *Character) (i int64, e error) { + tmp := new(Character) + b, e := engine.Where("hash = ?", Hash(c.Ch)).Get(tmp) + if e != nil { + return 0, e + } + if !b { + i, e = engine.InsertOne(c) + return + } + i, e = engine.Where("ch = ?", c.Ch).Update(c) + return +} + +func getCharacters(engine *xorm.Engine, fn func(engine *xorm.Engine) *xorm.Session) ([]*Character, error) { + s := fn(engine) + var c []*Character + e := s.Find(&c) + if e == nil { + return c, nil + } + return nil, fmt.Errorf("character list get error:%w", e) +} + +func getCharacter(eng *xorm.Engine, fn func(engine *xorm.Engine) *xorm.Session) (*Character, error) { + s := fn(eng) + var c Character + b, e := s.Get(&c) + if e == nil && b { + return &c, nil + } + return nil, fmt.Errorf("character get error:%w", e) +} + +// CharacterOptions ... +type CharacterOptions func(session *xorm.Session) *xorm.Session + +// Regular ... +func Regular() CharacterOptions { + return func(session *xorm.Session) *xorm.Session { + return session.And("regular = ?", 1) + } +} + +// Stoker ... +func Stoker(s int, options ...CharacterOptions) func(engine *xorm.Engine) *xorm.Session { + return func(engine *xorm.Engine) *xorm.Session { + session := engine.Where("pin_yin IS NOT NULL"). + And(builder.Eq{"science_stroke": s}) + // Or(builder.Eq{"stroke": s}). + // Or(builder.Eq{"kang_xi_stroke": s}). + // Or(builder.Eq{"simple_total_stroke": s}). + // Or(builder.Eq{"traditional_total_stroke": s})) + for _, option := range options { + session = option(session) + } + return session + } + +} + +// Char ... +func Char(name string) func(engine *xorm.Engine) *xorm.Session { + return func(engine *xorm.Engine) *xorm.Session { + return engine.Where(builder.Eq{"ch": name}. + Or(builder.Eq{"kang_xi": name}). + Or(builder.Eq{"traditional_character": name})) + } +} + +// Hash ... +func Hash(url string) string { + sum256 := sha256.Sum256([]byte(url)) + return fmt.Sprintf("%x", sum256) +} diff --git a/cmd/character/main.go b/cmd/character/main.go new file mode 100644 index 00000000..8d2749d9 --- /dev/null +++ b/cmd/character/main.go @@ -0,0 +1,76 @@ +package main + +import ( + "fmt" + "io/ioutil" + "os" + "sort" + "strings" +) + +func loadCharFile(path string) ([]byte, error) { + opened, err := os.Open(path) + if err != nil { + return nil, err + } + return ioutil.ReadAll(opened) +} + +func main() { + path := "" + if len(os.Args) > 1 { + path = os.Args[1] + } + if path == "" { + return + } + fmt.Println("Load", path) + file, err := loadCharFile(path) + if err != nil { + return + } + + codes := []rune(string(file)) + filter := map[rune]bool{} + for _, code := range codes { + if strings.TrimSpace(string(code)) == "" { + continue + } + if filterRune(code) { + continue + } + filter[code] = true + } + var data []rune + for r, b := range filter { + if b { + data = append(data, r) + } + } + + sort.Slice(data, func(i, j int) bool { + return data[i] < data[j] + }) + + if err := writeDataToFile(path+".new", string(data)); err != nil { + return + } + +} + +var filterRunes = []rune{ + '、', +} + +func filterRune(r rune) bool { + for _, filterRune := range filterRunes { + if filterRune == r { + return true + } + } + return false +} + +func writeDataToFile(path string, data string) error { + return ioutil.WriteFile(path, []byte(data), 0755) +} diff --git a/cmd/console/check.go b/cmd/console/check.go new file mode 100644 index 00000000..7c5f8735 --- /dev/null +++ b/cmd/console/check.go @@ -0,0 +1,45 @@ +package main + +import ( + "errors" + "fmt" + "github.com/goextension/log" + "github.com/spf13/cobra" + "os" + "path/filepath" + "runtime" +) + +func cmdCheck() *cobra.Command { + cmd := &cobra.Command{ + Use: "check", + Short: "check the env does correct", + Run: func(cmd *cobra.Command, args []string) { + root := runtime.GOROOT() + log.Infow("check", "GOROOT", runtime.GOROOT()) + if e := zoneCheck(root); e != nil { + log.Fatalw("zoneinfo check failed", "error", e) + } + fmt.Println("check all done!!!") + }, + } + return cmd +} +func zoneCheck(root string) error { + path := filepath.Join(root, "lib", "time") + _, e := os.Stat(filepath.Join(path, "zoneinfo.zip")) + if e != nil && os.IsNotExist(e) { + _, e1 := os.Stat(filepath.Join(getCurrentPath(), "zoneinfo.zip")) + if e1 != nil && os.IsNotExist(e) { + return errors.New("zoneinfo file not found") + } else if e1 != nil { + return fmt.Errorf("found error in current path:%w", e1) + } else { + return nil + } + } else if e != nil { + return fmt.Errorf("found error in go path:%w", e) + } else { + return nil + } +} diff --git a/cmd/console/init.go b/cmd/console/init.go new file mode 100644 index 00000000..d83ed4f2 --- /dev/null +++ b/cmd/console/init.go @@ -0,0 +1,33 @@ +package main + +import ( + "fmt" + "github.com/babyname/fate/config" + "github.com/goextension/log" + "github.com/spf13/cobra" + "path/filepath" +) + +func cmdInit() *cobra.Command { + var path string + cmd := &cobra.Command{ + Use: "init", + Short: "output the init config", + Run: func(cmd *cobra.Command, args []string) { + absPath, e := filepath.Abs(path) + if e != nil { + log.Fatalw("wrong path", "error", e, "path", path) + } + fmt.Printf("config will output to %s\n", filepath.Join(absPath, config.JSONName)) + config.DefaultJSONPath = path + + e = config.OutputConfig(config.DefaultConfig()) + if e != nil { + log.Fatalw("config wrong", "error", e) + } + + }, + } + cmd.Flags().StringVarP(&path, "path", "p", "", "set the output path") + return cmd +} diff --git a/cmd/console/main.go b/cmd/console/main.go new file mode 100644 index 00000000..f090bf72 --- /dev/null +++ b/cmd/console/main.go @@ -0,0 +1,26 @@ +package main + +import "fmt" +import "github.com/spf13/cobra" + +const programName = `fate` +const fateVersion = `0.0.2` + +var rootCmd = &cobra.Command{ + Use: programName, + Short: "call fate command to make name", + Version: fateVersion, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("arguments [command] was not inputted") + }, + DisableSuggestions: false, + SuggestionsMinimumDistance: 1, +} + +func main() { + rootCmd.AddCommand(cmdInit(), cmdName(), cmdCheck(), versionCMD()) + e := rootCmd.Execute() + if e != nil { + panic(e) + } +} diff --git a/cmd/console/name.go b/cmd/console/name.go new file mode 100644 index 00000000..72352138 --- /dev/null +++ b/cmd/console/name.go @@ -0,0 +1,69 @@ +package main + +import ( + "context" + "fmt" + "os" + "path/filepath" + "time" + + "github.com/babyname/fate" + "github.com/babyname/fate/config" + "github.com/godcong/chronos" + "github.com/goextension/log" + "github.com/spf13/cobra" +) + +func cmdName() *cobra.Command { + path := "" + born := "" + last := "" + output := "" + sex := false + cmd := &cobra.Command{ + Use: "name", + Short: "output the name", + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("start", time.Now().String()) + config.DefaultJSONPath = path + cfg := config.LoadConfig() + + if cfg == nil { + log.Warnw("config file not found,use default config") + cfg = config.DefaultConfig() + } + log.Infow("show config info", "data", *cfg) + + if output != "" { + cfg.FileOutput.Path = filepath.Join(output, cfg.FileOutput.Path) + } + + bornTime, e := time.Parse(chronos.DateFormat, born) + if e != nil { + log.Fatalw("parse born failed", "error", e) + } + f := fate.NewFate(last, bornTime, fate.ConfigOption(cfg), fate.SexOption(fate.Sex(sex))) + + e = f.MakeName(context.Background()) + if e != nil { + log.Fatalw("makename failed", "error", e) + } + + fmt.Println("end", time.Now().String()) + }, + } + cmd.Flags().StringVarP(&last, "last", "l", "", "set lastname") + cmd.Flags().StringVarP(&born, "born", "b", time.Now().Format(chronos.DateFormat), "set birth as 2016/01/02 15:04") + cmd.Flags().StringVarP(&path, "path", "p", ".", "set the input config path") + cmd.Flags().StringVarP(&output, "outout", "o", "", "set the output path") + cmd.Flags().BoolVarP(&sex, "sex", "s", false, "set sex of the baby") + return cmd +} + +func getCurrentPath() string { + getwd, err := os.Getwd() + if err != nil { + panic(err) + } + return getwd +} diff --git a/cmd/console/version.go b/cmd/console/version.go new file mode 100644 index 00000000..a2d81e0e --- /dev/null +++ b/cmd/console/version.go @@ -0,0 +1,18 @@ +package main + +import ( + "fmt" + "github.com/babyname/fate" + "github.com/spf13/cobra" +) + +func versionCMD() *cobra.Command { + cmd := &cobra.Command{ + Use: "version", + Short: "print current version to screen", + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("version:", fate.Version) + }, + } + return cmd +} diff --git a/cmd/strokefix/check.go b/cmd/strokefix/check.go new file mode 100644 index 00000000..bba73343 --- /dev/null +++ b/cmd/strokefix/check.go @@ -0,0 +1,131 @@ +package main + +import ( + "crypto/md5" + "encoding/json" + "fmt" + "github.com/babyname/fate" + "github.com/goextension/log" + "github.com/xormsharp/xorm" + "io/ioutil" + "strconv" +) + +type Dict struct { + Jin map[string][]string `json:"jin"` + Mu map[string][]string `json:"mu"` + Huo map[string][]string `json:"huo"` + Shui map[string][]string `json:"shui"` + Tu map[string][]string `json:"tu"` +} + +var dict Dict + +type WuXingFunc func(s string) bool + +func CheckLoader(s string) error { + bytes, e := ioutil.ReadFile(s) + if e != nil { + return e + } + e = json.Unmarshal(bytes, &dict) + if e != nil { + return e + } + + return nil +} + +func CheckVerify(db fate.Database) error { + if err := verifySub(db, dict.Jin, "金"); err != nil { + return err + } + if err := verifySub(db, dict.Mu, "木"); err != nil { + return err + } + if err := verifySub(db, dict.Shui, "水"); err != nil { + return err + } + if err := verifySub(db, dict.Huo, "火"); err != nil { + return err + } + if err := verifySub(db, dict.Tu, "土"); err != nil { + return err + } + + return nil +} + +func verifySub(db fate.Database, m map[string][]string, wx string) error { + count := 0 + eng := db.Database().(*xorm.Engine) + for k, v := range m { + for _, vv := range v { + count++ + character, e := db.GetCharacter(func(eng *xorm.Engine) *xorm.Session { + return eng.Where("ch = ?", vv) + }) + i, _ := strconv.Atoi(k) + if e != nil { + log.Errorw("get character error", "character", vv) + ch := fate.Character{ + Hash: hash(vv), + PinYin: []string{"custom"}, + Ch: vv, + ScienceStroke: i, + Radical: "", + RadicalStroke: 0, + Stroke: 0, + IsKangXi: false, + KangXi: "", + KangXiStroke: 0, + SimpleRadical: "", + SimpleRadicalStroke: 0, + SimpleTotalStroke: 0, + TraditionalRadical: "", + TraditionalRadicalStroke: 0, + TraditionalTotalStroke: 0, + NameScience: true, + WuXing: wx, + Lucky: "", + Regular: false, + TraditionalCharacter: nil, + VariantCharacter: nil, + Comment: []string{"custom"}, + } + _, e := eng.InsertOne(ch) + if e != nil { + log.Error("inser error", "character", ch.Ch) + } + continue + } + if character.WuXing != wx { + if character.WuXing == "" { + //fix wuxing + character.WuXing = wx + } else { + log.Warnw("wrong wuxing", "character", vv, "charwuxing", character.WuXing, "dictwuxing", wx) + } + } + if character.ScienceStroke != i { + log.Warnw("check warning", "character", vv, "db", character.ScienceStroke, "need", k) + //fix stroke + character.ScienceStroke = i + } + update, e := eng.Where("hash = ?", character.Hash).Update(character) + if e != nil { + return e + } + if update != 1 { + //log.Errorw("not updated", "update", update) + } + } + } + log.Infow("total", "count", count) + return nil +} + +func hash(char string) string { + s := md5.Sum([]byte(char)) + return fmt.Sprintf("%x", s) +} diff --git a/cmd/strokefix/main.go b/cmd/strokefix/main.go new file mode 100644 index 00000000..fb2fdaef --- /dev/null +++ b/cmd/strokefix/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "github.com/babyname/fate" + "github.com/babyname/fate/config" + "github.com/xormsharp/xorm" +) + +func main() { + var e error + + cfg := config.DefaultConfig() + db := fate.InitDatabaseWithConfig(*cfg) + + e = db.Sync(fate.Character{}) + if e != nil { + return + } + + e = UpdateFix(db.Database().(*xorm.Engine)) + if e != nil { + panic(e) + } + e = CheckLoader(`E:\project\fate\cmd\strokefix\dict.json`) + if e != nil { + panic(e) + } + e = CheckVerify(db) + if e != nil { + panic(e) + } +} diff --git a/cmd/strokefix/rule.go b/cmd/strokefix/rule.go new file mode 100644 index 00000000..b144c81a --- /dev/null +++ b/cmd/strokefix/rule.go @@ -0,0 +1,116 @@ +package main + +import ( + "github.com/babyname/fate" + "strings" +) + +var charCharList = []string{ + `阧障陇陾階阾降隄隓陞隂陈隯陖隗陠阱陲阼隩阬陳陌隀阠陿隉陉隥陧陁陱阶陂陽陼陪陗陊阪阞陑隭阬陆隡陫陦陂阳防阽陔隄防隕陨陇陑陚隬陉隣陕隝` + + `阺阫隢陹限附陰阮隚隥阪阭陏陳陜陸阦阷阞隫隞隘陒隴隍陶隀隔陀阤隤陬隨除陲降陮阽阩阴陋队隳隊隊隭陮隋隝隴陘阥隆陡陏陫陙陈隧阸陯隑隍` + + `陡陛阸隔阻隑隯陘陃陊除陖隘隫阨阨隌陔阧陵附陟隞队随隌陙陃`, + `邤酆那鄟郐邝邯酃邸邢郟鄧郤郕邚郫鄀郠郂鄝邩酈邽部郚鄽鄹鄚邲鄳郕郥邶邪鄡邡郿邠鄱邞邩邗鄯鄤邯郎鄐郸鄁邓酇郲鄽郩鄴郔郭郜鄻邦鄺郘鄋郦郡` + + `鄷鄇都鄲鄂鄥郣郐郻鄧鄕邒郭郳鄣郷鄆邞鄶邿鄮鄗鄏郗鄒邬郪邷郲郈鄼鄄郙邰鄛邦郱郓邜鄈鄁鄵邮郮邨郠鄌郸阿邾郈鄝郛郄郂鄸邨郴鄲邴邵邥部` + + `邴郧郞郟邘邟鄍郹郖郍鄿邺郰鄘鄶郙邭邛郏郡鄙鄺郑邸鄗鄉邠郀郬邼邖邼鄄郹鄤酁邽鄈鄩邔郦鄰鄇邳郴郝郀邲郃郞鄜邙邭郯邝郜鄑郝邟郣鄐邱鄛` + + `邹郢邻鄷郆郅酂酄鄊郊邓郏郇郊邗郖鄭鄫鄖郉酆酄郵郁郋邧都邶邡`, +} + +func CharChar(ch *fate.Character) bool { + if i := strings.Index(charCharList[0], ch.Ch); i != -1 { + if ch.Stroke != 0 { + ch.ScienceStroke = ch.Stroke + 8 + return true + } + if ch.SimpleTotalStroke != 0 { + ch.ScienceStroke = ch.SimpleTotalStroke + 8 + return true + } + } + + if i := strings.Index(charCharList[0], ch.Ch); i != -1 { + if ch.Stroke != 0 { + ch.ScienceStroke = ch.Stroke + 7 + return true + } + if ch.SimpleTotalStroke != 0 { + ch.ScienceStroke = ch.SimpleTotalStroke + 7 + return true + } + } + + return false +} + +var numberCharList = `一二三四五六七八九十` + +func NumberChar(ch *fate.Character) bool { + if i := strings.Index(numberCharList, ch.Ch); i != -1 { + if ch.Stroke != 0 { + ch.ScienceStroke = ch.Stroke + i + return true + } + if ch.SimpleTotalStroke != 0 { + ch.ScienceStroke = ch.SimpleTotalStroke + i + return true + } + } + return false +} + +var radicalCharList = map[string]int{ + "扌": 1, + "忄": 1, + "氵": 1, + "犭": 1, + "礻": 1, + "王": 1, + "艹": 3, + "衤": 1, + "月": 3, + "辶": 4, +} + +func RadicalChar(ch *fate.Character) bool { + for k, v := range radicalCharList { + if strings.Compare(ch.Radical, k) == 0 { + ch.ScienceStroke = ch.Stroke + v + return true + } + if strings.Compare(ch.SimpleRadical, k) == 0 { + ch.ScienceStroke = ch.SimpleTotalStroke + v + return true + } + } + return false +} + +var fixTable = []func(character *fate.Character) bool{ + RadicalChar, + NumberChar, + CharChar, + DefaultChar, +} + +func fixChar(character *fate.Character) bool { + for _, f := range fixTable { + if f(character) { + return true + } + } + return false +} + +func DefaultChar(character *fate.Character) bool { + if character.KangXiStroke != 0 { + character.ScienceStroke = character.KangXiStroke + } else if character.TraditionalTotalStroke != 0 { + character.ScienceStroke = character.TraditionalTotalStroke + } else if character.Stroke != 0 { + character.ScienceStroke = character.Stroke + } else if character.SimpleTotalStroke != 0 { + character.ScienceStroke = character.SimpleTotalStroke + } else { + return false + } + return true +} diff --git a/cmd/strokefix/update.go b/cmd/strokefix/update.go new file mode 100644 index 00000000..c5f6d9ea --- /dev/null +++ b/cmd/strokefix/update.go @@ -0,0 +1,32 @@ +package main + +import ( + "github.com/babyname/fate" + "github.com/goextension/log" + "github.com/xormsharp/xorm" +) + +func UpdateFix(engine *xorm.Engine) error { + rows, e := engine.Rows(&fate.Character{}) + if e != nil { + return e + } + var ch *fate.Character + for rows.Next() { + ch = &fate.Character{} + e := rows.Scan(ch) + if e != nil { + log.Errorw("fix", "charater", ch.Ch, "error", e) + continue + } + if fixChar(ch) { + _, e := engine.Where("hash = ?", ch.Hash).Cols("science_stroke").Update(ch) + if e != nil { + log.Errorw("update", "charater", ch.Ch, "error", e) + continue + } + log.Infow("updated", "charater", ch.Ch, "stroke", ch.ScienceStroke) + } + } + return nil +} diff --git a/config/config.go b/config/config.go new file mode 100644 index 00000000..bf5939c7 --- /dev/null +++ b/config/config.go @@ -0,0 +1,115 @@ +package config + +import ( + "encoding/json" + "os" + "path/filepath" +) + +const JSONName = "config.json" + +type FilterMode int + +const ( + FilterModeNormal FilterMode = iota + FilterModeHard + FilterModeCustom +) + +type OutputMode int + +const ( + OutputModeLog OutputMode = iota + OutputModeCSV + OutputModelJSON +) + +type FileOutput struct { + OutputMode OutputMode `json:"output_mode"` + Path string `json:"path"` + Heads []string `json:"heads"` +} + +type Config struct { + RunInit bool `json:"run_init"` + FilterMode FilterMode `json:"filter_mode"` + StrokeMax int `json:"stroke_max"` + StrokeMin int `json:"stroke_min"` + HardFilter bool `json:"hard_filter"` + FixBazi bool `json:"fix_bazi"` //八字修正 + SupplyFilter bool `json:"supply_filter"` //过滤补八字 + ZodiacFilter bool `json:"zodiac_filter"` //过滤生肖 + BaguaFilter bool `json:"bagua_filter"` //过滤卦象 + Regular bool `json:"regular"` //常用 + Database Database `json:"database"` + FileOutput FileOutput `json:"file_output"` +} + +var DefaultJSONPath = "" +var DefaultHeads = []string{"姓名", "笔画", "拼音", "喜用神", "八字"} + +func init() { + if DefaultJSONPath == "" { + dir, err := os.Getwd() + if err != nil { + panic(err) + } + s, err := filepath.Abs(dir) + if err != nil { + panic(err) + } + DefaultJSONPath = s + } +} + +func LoadConfig() (c *Config) { + c = &Config{} + def := DefaultConfig() + f := filepath.Join(DefaultJSONPath, JSONName) + bys, e := os.ReadFile(f) + if e != nil { + return def + } + e = json.Unmarshal(bys, &c) + if e != nil { + return def + } + return c +} + +func OutputConfig(config *Config) error { + bys, e := json.MarshalIndent(config, "", " ") + if e != nil { + return e + } + + return os.WriteFile(filepath.Join(DefaultJSONPath, JSONName), bys, 0755) +} + +func DefaultConfig() *Config { + return &Config{ + RunInit: false, + FilterMode: 0, + StrokeMax: 18, + StrokeMin: 3, + HardFilter: false, + FixBazi: false, + SupplyFilter: true, + ZodiacFilter: true, + BaguaFilter: true, + Regular: true, + Database: Database{ + Name: "fate", + MaxIdleCon: 0, + MaxOpenCon: 0, + Driver: "sqlite3", + ShowSQL: false, + ShowExecTime: false, + }, + FileOutput: FileOutput{ + Heads: DefaultHeads, + OutputMode: OutputModeLog, + Path: "name.txt", + }, + } +} diff --git a/config/database.go b/config/database.go new file mode 100644 index 00000000..88245794 --- /dev/null +++ b/config/database.go @@ -0,0 +1,20 @@ +package config + +type Database struct { + Host string `json:"host"` + Port string `json:"port"` + User string `json:"user"` + Pwd string `json:"pwd"` + Name string `json:"name"` + MaxIdleCon int `json:"max_idle_con"` + MaxOpenCon int `json:"max_open_con"` + Driver string `json:"driver"` + File string `json:"file"` + Dsn string `json:"dsn"` + ShowSQL bool `json:"show_sql"` + ShowExecTime bool `json:"show_exec_time"` +} + +func (d *Database) Addr() string { + return d.Host + ":" + d.Port +} diff --git a/data/gua.data b/data/gua.data new file mode 100644 index 00000000..8d39be3e Binary files /dev/null and b/data/gua.data differ diff --git a/database.go b/database.go new file mode 100644 index 00000000..c0b1d436 --- /dev/null +++ b/database.go @@ -0,0 +1,130 @@ +package fate + +import ( + "fmt" + "net/url" + + "github.com/go-sql-driver/mysql" + "github.com/goextension/log" + "github.com/mattn/go-sqlite3" + + "github.com/babyname/fate/config" + + "github.com/xormsharp/xorm" +) + +const mysqlSource = "%s:%s@tcp(%s)/%s?loc=%s&charset=utf8mb4&parseTime=true" +const sqliteSource = "file:%v?cache=shared\u0026_journal=WAL\u0026_fk=1" +const createDatabase = "CREATE DATABASE `%s` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_bin'" + +var _ = mysql.MySQLDriver{} +var _ = sqlite3.SQLiteDriver{} + +// DefaultTableName ... +var DefaultTableName = "fate" + +// Database ... +type Database interface { + Sync(v ...interface{}) error + CountWuGeLucky() (n int64, e error) + InsertOrUpdateWuGeLucky(lucky *WuGeLucky) (n int64, e error) + GetCharacter(fn func(engine *xorm.Engine) *xorm.Session) (*Character, error) + GetCharacters(fn func(engine *xorm.Engine) *xorm.Session) ([]*Character, error) + FilterWuGe(last []*Character, wg chan<- *WuGeLucky) error + Database() interface{} +} + +type xormDatabase struct { + *xorm.Engine +} + +// Database ... +func (db *xormDatabase) Database() interface{} { + return db.Engine +} + +// FilterWuGe ... +func (db *xormDatabase) FilterWuGe(last []*Character, wg chan<- *WuGeLucky) error { + return filterWuGe(db.Engine, last, wg) +} + +// GetCharacters ... +func (db *xormDatabase) GetCharacters(fn func(engine *xorm.Engine) *xorm.Session) ([]*Character, error) { + return getCharacters(db.Engine, fn) +} + +// Sync ... +func (db *xormDatabase) Sync(v ...interface{}) error { + return db.Engine.Sync2(v...) +} + +// GetCharacter ... +func (db *xormDatabase) GetCharacter(fn func(engine *xorm.Engine) *xorm.Session) (*Character, error) { + return getCharacter(db.Engine, fn) +} + +// InsertOrUpdateWuGeLucky ... +func (db *xormDatabase) InsertOrUpdateWuGeLucky(lucky *WuGeLucky) (n int64, e error) { + return insertOrUpdateWuGeLucky(db.Engine, lucky) +} + +// CountWuGeLucky ... +func (db *xormDatabase) CountWuGeLucky() (n int64, e error) { + return countWuGeLucky(db.Engine) +} + +// InitDatabaseWithConfig ... +func InitDatabaseWithConfig(cfg config.Config) Database { + return initDatabaseWithConfig(cfg.Database) +} + +func initDatabaseWithConfig(db config.Database) Database { + engine := initSQL(db) + return &xormDatabase{ + Engine: engine, + } +} + +func databaseLink(database config.Database, schema bool) string { + name := database.Name + if !schema && database.Name != "" { + name = database.Name + } + switch database.Driver { + case "mysql": + return fmt.Sprintf(mysqlSource, database.User, database.Pwd, database.Addr(), name, url.QueryEscape("Asia/Shanghai")) + case "sqlite3": + return fmt.Sprintf(sqliteSource, name) + default: + panic("unsupported database") + } +} + +func initSQL(database config.Database) *xorm.Engine { + link := databaseLink(database, true) + dbEngine, e := xorm.NewEngine(database.Driver, link) + if e != nil { + log.Panicw("connect database failed", "error", e) + } + sql := fmt.Sprintf(createDatabase, database.Name) + _, e = dbEngine.DB().Exec(sql) + if e == nil { + log.Infow("create database failed", "database", DefaultTableName) + dbEngine.Close() + return nil + } + dbEngine.Close() + link = databaseLink(database, false) + eng, e := xorm.NewEngine(database.Driver, link) + if e != nil { + log.Panicw("connect table failed", "error", e) + } + if database.ShowSQL { + eng.ShowSQL(true) + } + + // if database.ShowExecTime { + // eng.ShowExecTime(true) + // } + return eng +} diff --git a/dayan.go b/dayan.go new file mode 100644 index 00000000..90cef82c --- /dev/null +++ b/dayan.go @@ -0,0 +1,123 @@ +package fate + +// Sex ... +type Sex bool + +// SexBoy ... +const ( + SexBoy Sex = false + SexGirl Sex = true +) + +var daYanList = [81]DaYan{ + {Number: 1, Lucky: "吉", SkyNine: "太极之数", Comment: "太极之数,万物开泰,生发无穷,利禄亨通。"}, + {Number: 2, Lucky: "凶", SkyNine: "两仪之数", Comment: "两仪之数,混沌未开,进退保守,志望难达。"}, + {Number: 3, Lucky: "吉", SkyNine: "三才之数", Comment: "三才之数,天地人和,大事大业,繁荣昌隆。"}, + {Number: 4, Lucky: "凶", SkyNine: "四象之数", Comment: "四象之数,待于生发,万事慎重,不具营谋。"}, + {Number: 5, Lucky: "吉", SkyNine: "五行之数", Comment: "五行俱权,循环相生,圆通畅达,福祉无穷。"}, + {Number: 6, Lucky: "吉", SkyNine: "六爻之数", Comment: "六爻之数,发展变化,天赋美德,吉祥安泰。"}, + {Number: 7, Lucky: "吉", SkyNine: "七政之数", Comment: "七政之数,精悍严谨,天赋之力,吉星照耀。"}, + {Number: 8, Lucky: "半吉", SkyNine: "八卦之数", Comment: "八卦之数,乾坎艮震,巽离坤兑,无穷无尽。"}, + {Number: 9, Lucky: "凶", SkyNine: "大成之数", Comment: "大成之数,蕴涵凶险,或成或败,难以把握。"}, + {Number: 10, Lucky: "凶", SkyNine: "终结之数", Comment: "终结之数,雪暗飘零,偶或有成,回顾茫然。"}, + {Number: 11, Lucky: "吉", SkyNine: "旱苗逢雨", Comment: "万物更新,调顺发达,恢弘泽世,繁荣富贵。"}, + {Number: 12, Lucky: "凶", SkyNine: "掘井无泉", Comment: "无理之数,发展薄弱,虽生不足,难酬志向。"}, + {Number: 13, Lucky: "吉", SkyNine: "春日牡丹", Comment: "才艺多能,智谋奇略,忍柔当事,鸣奏大功。"}, + {Number: 14, Lucky: "凶", SkyNine: "破兆", Comment: "家庭缘薄,孤独遭难,谋事不达,悲惨不测。"}, + {Number: 15, Lucky: "吉", SkyNine: "福寿", Comment: "福寿圆满,富贵荣誉,涵养雅量,德高望重。"}, + {Number: 16, Lucky: "吉", SkyNine: "厚重", Comment: "厚重载德,安富尊荣,财官双美,功成名就。"}, + {Number: 17, Lucky: "半吉", SkyNine: "刚强", Comment: "权威刚强,突破万难,如能容忍,必获成功。"}, + {Number: 18, Lucky: "半吉", SkyNine: "铁镜重磨", Comment: "权威显达,博得名利,且养柔德,功成名就。"}, + {Number: 19, Lucky: "凶", SkyNine: "多难", Comment: "风云蔽日,辛苦重来,虽有智谋,万事挫折。"}, + {Number: 20, Lucky: "凶", SkyNine: "屋下藏金", Comment: "非业破运,灾难重重,进退维谷,万事难成。"}, + {Number: 21, Lucky: "吉", Sex: true, SkyNine: "明月中天", Comment: "光风霁月,万物确立,官运亨通,大搏名利。女性不宜此数。"}, + {Number: 22, Lucky: "凶", SkyNine: "秋草逢霜", Comment: "秋草逢霜,困难疾弱,虽出豪杰,人生波折。"}, + {Number: 23, Lucky: "吉", Sex: true, SkyNine: "壮丽", Comment: "旭日东升,壮丽壮观,权威旺盛,功名荣达。女性不宜此数。"}, + {Number: 24, Lucky: "吉", SkyNine: "掘藏得金", Comment: "家门余庆,金钱丰盈,白手成家,财源广进。"}, + {Number: 25, Lucky: "半吉", SkyNine: "荣俊", Comment: "资性英敏,才能奇特,克服傲慢,尚可成功。"}, + {Number: 26, Lucky: "凶", SkyNine: "变怪", Comment: "变怪之谜,英雄豪杰,波澜重叠,而奏大功。"}, + {Number: 27, Lucky: "凶", SkyNine: "增长", Comment: "欲望无止,自我强烈,多受毁谤,尚可成功。"}, + {Number: 28, Lucky: "凶", Sex: true, SkyNine: "阔水浮萍", Comment: "遭难之数,豪杰气概,四海漂泊,终世浮躁。女性不宜此数。"}, + {Number: 29, Lucky: "吉", SkyNine: "智谋", Comment: "智谋优秀,财力归集,名闻海内,成就大业。"}, + {Number: 30, Lucky: "半吉", SkyNine: "非运", Comment: "沉浮不定,凶吉难变,若明若暗,大成大败。"}, + {Number: 31, Lucky: "吉", SkyNine: "春日花开", Comment: "智勇得志,博得名利,统领众人,繁荣富贵。"}, + {Number: 32, Lucky: "吉", SkyNine: "宝马金鞍", Comment: "侥幸多望,贵人得助,财帛如裕,繁荣至上。"}, + {Number: 33, Lucky: "吉", Sex: true, SkyNine: "旭日升天", Comment: "旭日升天,鸾凤相会,名闻天下,隆昌至极。女性不宜此数。"}, + {Number: 34, Lucky: "凶", SkyNine: "破家", Comment: "破家之身,见识短小,辛苦遭逢,灾祸至极。"}, + {Number: 35, Lucky: "吉", SkyNine: "高楼望月", Comment: "温和平静,智达通畅,文昌技艺,奏功洋洋。"}, + {Number: 36, Lucky: "半吉", SkyNine: "波澜重叠", Comment: "波澜重叠,沉浮万状,侠肝义胆,舍己成仁。"}, + {Number: 37, Lucky: "吉", SkyNine: "猛虎出林", Comment: "权威显达,热诚忠信,宜着雅量,终身荣富。"}, + {Number: 38, Lucky: "半吉", SkyNine: "磨铁成针", Comment: "意志薄弱,刻意经营,才识不凡,技艺有成。"}, + {Number: 39, Lucky: "半吉", SkyNine: "富贵荣华", Comment: "富贵荣华,财帛丰盈,暗藏险象,德泽四方。"}, + {Number: 40, Lucky: "凶", SkyNine: "退安", Comment: "智谋胆力,冒险投机,沉浮不定,退保平安。"}, + {Number: 41, Lucky: "吉", Max: true, SkyNine: "有德", Comment: "纯阳独秀,德高望重,和顺畅达,博得名利。此数为最大好运数。"}, + {Number: 42, Lucky: "凶", SkyNine: "寒蝉在柳", Comment: "博识多能,精通世情,如能专心,尚可成功。"}, + {Number: 43, Lucky: "凶", SkyNine: "散财破产", Comment: "散财破产,诸事不遂,虽有智谋,财来财去。"}, + {Number: 44, Lucky: "凶", SkyNine: "烦闷", Comment: "破家亡身,暗藏惨淡,事不如意,乱世怪杰。"}, + {Number: 45, Lucky: "吉", SkyNine: "顺风", Comment: "新生泰和,顺风扬帆,智谋经纬,富贵繁荣。"}, + {Number: 46, Lucky: "凶", SkyNine: "浪里淘金", Comment: "载宝沉舟,浪里淘金,大难尝尽,大功有成。"}, + {Number: 47, Lucky: "吉", SkyNine: "点石成金", Comment: "花开之象,万事如意,祯祥吉庆,天赋幸福。"}, + {Number: 48, Lucky: "吉", SkyNine: "古松立鹤", Comment: "智谋兼备,德量荣达,威望成师,洋洋大观。"}, + {Number: 49, Lucky: "半吉", SkyNine: "转变", Comment: "吉临则吉,凶来则凶,转凶为吉,配好三才。"}, + {Number: 50, Lucky: "半吉", SkyNine: "小舟入海", Comment: "一成一败,吉凶参半,先得庇荫,后遭凄惨。"}, + {Number: 51, Lucky: "半吉", SkyNine: "沉浮", Comment: "盛衰交加,波澜重叠,如能慎始,必获成功。"}, + {Number: 52, Lucky: "吉", SkyNine: "达眼", Comment: "卓识达眼,先见之明,智谋超群,名利双收。"}, + {Number: 53, Lucky: "凶", SkyNine: "曲卷难星", Comment: "外祥内患,外祸内安,先富后贫,先贫后富。"}, + {Number: 54, Lucky: "凶", SkyNine: "石上栽花", Comment: "石上栽花,难得有活,忧闷烦来,辛惨不绝。"}, + {Number: 55, Lucky: "半吉", SkyNine: "善恶", Comment: "善善得恶,恶恶得善,吉到极限,反生凶险。"}, + {Number: 56, Lucky: "凶", SkyNine: "浪里行舟", Comment: "历尽艰辛,四周障碍,万事龃龌,做事难成。"}, + {Number: 57, Lucky: "吉", SkyNine: "日照春松", Comment: "寒雪青松,夜莺吟春,必遭一过,繁荣白事。"}, + {Number: 58, Lucky: "半吉", SkyNine: "晚行遇月", Comment: "沉浮多端,先苦后甜,宽宏扬名,富贵繁荣。"}, + {Number: 59, Lucky: "凶", SkyNine: "寒蝉悲风", Comment: "寒蝉悲风,意志衰退,缺乏忍耐,苦难不休。"}, + {Number: 60, Lucky: "凶", SkyNine: "无谋", Comment: "无谋之人,漂泊不定,晦暝暗黑,动摇不安。"}, + {Number: 61, Lucky: "吉", SkyNine: "牡丹芙蓉", Comment: "牡丹芙蓉,花开富贵,名利双收,定享天赋。"}, + {Number: 62, Lucky: "凶", SkyNine: "衰败", Comment: "衰败之象,内外不和,志望难达,灾祸频来。"}, + {Number: 63, Lucky: "吉", SkyNine: "舟归平海", Comment: "富贵荣华,身心安泰,雨露惠泽,万事亨通。"}, + {Number: 64, Lucky: "凶", SkyNine: "非命", Comment: "骨肉分离,孤独悲愁,难得心安,做事不成。"}, + {Number: 65, Lucky: "吉", SkyNine: "巨流归海", Comment: "天长地久,家运隆昌,福寿绵长,事事成就。"}, + {Number: 66, Lucky: "凶", SkyNine: "岩头步马", Comment: "进退维谷,艰难不堪,等待时机,一跃而起。"}, + {Number: 67, Lucky: "吉", SkyNine: "顺风通达", Comment: "天赋幸运,四通八达,家道繁昌,富贵东来。"}, + {Number: 68, Lucky: "吉", SkyNine: "顺风吹帆", Comment: "智虑周密,集众信达,发明能智,拓展昂进。"}, + {Number: 69, Lucky: "凶", SkyNine: "非业", Comment: "非业非力,精神迫滞,灾害交至,遍偿痛苦。"}, + {Number: 70, Lucky: "凶", SkyNine: "残菊逢霜", Comment: "残菊逢霜,寂寞无碍,惨淡忧愁,晚景凄凉。"}, + {Number: 71, Lucky: "半吉", SkyNine: "石上金花", Comment: "石上金花,内心劳苦,贯彻始终,定可昌隆。"}, + {Number: 72, Lucky: "半吉", SkyNine: "劳苦", Comment: "荣苦相伴,阴云覆月,外表吉祥,内实凶祸。"}, + {Number: 73, Lucky: "半吉", SkyNine: "无勇", Comment: "盛衰交加,徒有高志,天王福祉,终世平安。"}, + {Number: 74, Lucky: "凶", SkyNine: "残菊经霜", Comment: "残菊经霜,秋叶寂寞,无能无智,辛苦繁多。"}, + {Number: 75, Lucky: "凶", SkyNine: "退守", Comment: "退守保吉,发迹甚迟,虽有吉象,无谋难成。"}, + {Number: 76, Lucky: "凶", SkyNine: "离散", Comment: "倾覆离散,骨肉分离,内外不和,虽劳无功。"}, + {Number: 77, Lucky: "半吉", SkyNine: "半吉", Comment: "家庭有悦,半吉半凶,能获援护,陷落不幸。"}, + {Number: 78, Lucky: "凶", SkyNine: "晚苦", Comment: "祸福参半,先天智能,中年发达,晚景困苦。"}, + {Number: 79, Lucky: "凶", SkyNine: "云头望月", Comment: "云头望月,身疲力尽,穷迫不伸,精神不定。"}, + {Number: 80, Lucky: "凶", SkyNine: "遁吉", Comment: "辛苦不绝,早入隐遁,安心立命,化凶转吉。"}, + {Number: 81, Lucky: "吉", SkyNine: "万物回春", Comment: "最吉之数,还本归元,吉祥重叠,富贵尊荣。"}, +} + +// DaYan ... +type DaYan struct { + Number int + Lucky string + Max bool + Sex Sex // male(false),female(true) + SkyNine string + Comment string +} + +// IsNotSuitableSex 女性不宜此数 +func (dy DaYan) IsNotSuitableSex() bool { + return dy.Sex == SexGirl +} + +// IsMax 是否最大好运数 +func (dy DaYan) IsMax() bool { + return dy.Max +} + +// GetDaYan 获取大衍之数 +func GetDaYan(idx int) DaYan { + if idx <= 0 { + panic("wrong idx") + } + i := (idx - 1) % 81 + return daYanList[i] +} diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 00000000..2f7efbea --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-minimal \ No newline at end of file diff --git a/docs/chinese_name_query.md b/docs/chinese_name_query.md new file mode 100644 index 00000000..3acbd39a --- /dev/null +++ b/docs/chinese_name_query.md @@ -0,0 +1,368 @@ +原地址:`https://zhuanlan.zhihu.com/p/89654568` + +提示:只查询你的 **户籍省份** 和 **全国** 两个维度 + + +* * * + +## 全国 + +![](https://pic3.zhimg.com/v2-5f3981bec2c08bff7e9e7a51e23e7646_b.jpg)
全国重名查询截图 + + +提示:一定要注册,并且一个账号每天只能查询十次; **十次够了就不能查询了!** + + **全国** + +[公安部“互联网+政务服务”平台](https://link.zhihu.com/?target=https%3A//zwfw.mps.gov.cn/login.html) + +注意:对于少于10人的姓名,系统不会展示具体数量,可以通过如下方法查询: + +以Chrome浏览器为例: + +右上角->更多工具->开发者工具或者 同时按下Ctrl+Shift+I 进入调试工具 + +![](https://pic1.zhimg.com/v2-2c87c5a95e08f6d31face64cf5992d58_b.jpg)
+ +查询某个名字,例如“蓝天白云” + +在调试器的“网络”(Network)菜单查看系统的返回信息: + +![](https://pic3.zhimg.com/v2-5557435f3b957a06a12b9251a4fae66e_b.jpg)
+ +{"returnCode":"1","returnMsg":"成功","data":[{"xm":"蓝天白云","xb":"2","resultRs":7,"errormesage":null,"errormesagecol":null}]} + +resultRs就是具体的数量了。 + +* * * + + **北京** + +![](https://pic3.zhimg.com/v2-226ec5a406c28e3119cf9b97c63896d2_b.jpg)
+北京市[同名查询](https://link.zhihu.com/?target=https%3A//zwfw.gaj.beijing.gov.cn/rkgl/reserve/checkNameSexNum) + + **查询条件:不需要注册,只需验证码,分男女** + +* * * + +## **上海市** + + +![](https://pic4.zhimg.com/v2-0862fbac3f3cfd197494dcae7e96d53b_b.jpg)
+上海市查询截图![](https://pic1.zhimg.com/v2-a8cfd0cf41791dc2252c208ef4802f6c_b.jpg)
结果截图[上海市重名查询](https://link.zhihu.com/?target=https%3A//rkcs.gaj.sh.gov.cn/rkbyw/xsrcm/queryReq/0) + +查询条件:不需要注册,不需验证码,不分男女 + +* * * + +## 重庆市 + +![](https://pic3.zhimg.com/v2-f924b77b12688532d29b804ba2fe27e6_b.jpg)
查询截图[重庆市重名查询](https://link.zhihu.com/?target=https%3A//wsga.gaj.cq.gov.cn/webchat/%23/name) + +查询条件:不需要注册,不需验证码,不分男女 + +* * * + +## 河南省 + +![](https://pic2.zhimg.com/v2-0e6321f0c25e1b855039e25671a85ec9_b.jpg)
河南省查询结果[河南省重名查询接口](https://link.zhihu.com/?target=http%3A//bsdt.henanga.gov.cn/MainPages/ChaXunZhongXin/SameNameQuery) + +查询条件:不需要注册,需验证码,不分男女 + +* * * + +## 黑龙江省 + +![](https://pic4.zhimg.com/v2-df26d35492f71eb5be64bc35c6916ce7_b.jpg)
黑龙江重名查询结果[黑龙江“互联网+ +公安政务服务”平台](https://link.zhihu.com/?target=http%3A//gafw.hljga.gov.cn/wyc.do%3Fmethod%3DShow) + +上面返回的数据有问题,用下面的链接试试: + +[[黑龙江省]重名查询](https://link.zhihu.com/?target=http%3A//zwfw.hlj.gov.cn/jmopen/webapp/html5/hljscmcx/index.html) + +查询条件:不需要注册,需验证码,不分男女 + +* * * + +## **湖南省** + +![](https://pic1.zhimg.com/v2-97153705b010fa20c1388ac92414265c_b.jpg)
+河南省重名查询截图[湖南省姓名重名查询](https://link.zhihu.com/?target=https%3A//fwpt.hnga.gov.cn/weixin/%23/name) + +查询条件:不需要注册,不需验证码,不分男女 + +* * * + +## +安徽省 + +![](https://pic1.zhimg.com/v2-657c81b646e2aa4d1211033a12017680_b.jpg)
安徽省查询截图 + + + +[安徽省姓名重名查询](https://link.zhihu.com/?target=http%3A//www.ahga.gov.cn%3A8087/was2/was/hall/V1/jsp/st/cyc.jsp%3Ftype%3Dhz%26flag%3D2%23ewt) + +查询条件:不需要注册,需验证码,不分男女 + +* * * + +## 山东省 + +![](https://pic3.zhimg.com/v2-8fd6d505fe97eda5705b394d0a453312_b.jpg)
山东省重名查询截图[重名查询](https://link.zhihu.com/?target=https%3A//www.sdmsjw.gov.cn/populationclient/search.shtml) + +查询条件:不需要注册,需验证码,不分男女,有各个地市的数量分布,功能算是比较好的一个。 + +* * * + +## 江苏省 + +![](https://pic4.zhimg.com/v2-79ca15bbee865e635959308b43145e0f_b.jpg)
查询结果截图 + + + +[重名查询](https://link.zhihu.com/?target=http%3A//www.wjw.jsga.gov.cn/cname/index) + +查询条件:不需要注册,不需验证码,分男女 + +* * * + +广西 + +![](https://pic4.zhimg.com/v2-f66e46e46b54f5b1cfcbef0ae667110f_b.jpg)
广西省重名查询截图[广西公安网上办事服务](https://link.zhihu.com/?target=http%3A//gafw.gat.gxzf.gov.cn/was/hall/V1/jsp/st/cyc.jsp%3Ftype%3Dhz%26flag%3D2) + +查询条件:不需要注册,需验证码、不分男女 + +* * * + +## 甘肃省 + +![](https://pic4.zhimg.com/v2-38e4d9d6f9bad91a0f7dbe0eb6a79b0f_b.jpg)
甘肃省查询截图[新生儿重名查询](https://link.zhihu.com/?target=http%3A//wx.gat.gansu.gov.cn/f/mp/s_10012/h_10172) + +查询条件:不需要注册,需验证码,分男女,需要手机号 + +* * * + +## 吉林省 + +![](https://pic4.zhimg.com/v2-4a0f0d57fa62ceca7f2e6157c598311b_b.jpg)
吉林省查询截图
https://gafw.jl.gov.cn/#/query_sear/name-query + +查询条件:不需要注册,需验证码,不分男女 + +* * * + +## 贵州省 + +![](https://pic3.zhimg.com/v2-edb656ac6081bf56fd64ea588d33f386_b.jpg)
+ + +https://zwfw.gzga.gov.cn/wechat/#/repeat-name-query + +查询条件:不需要注册,不需验证码,结果分男女 + **贵州的是做的最好的!** + +* * * + +## 广东省 + +![](https://pic1.zhimg.com/v2-fe16f25b6a275b6ec6c7945c3e797b3c_b.jpg)
广东省重名查询截图 + + + +[广东省同名查询](https://link.zhihu.com/?target=http%3A//gdzaj.gd.gov.cn/gdza/web/xsecx/xseqmcx.ignore%3Ftype%3Dcmcx) + +查询条件:不需要注册,不需验证码,分男女,可以同时查询3个。 + +* * * + +## 青海省 + +![](https://pic1.zhimg.com/v2-83e0f392d297a23bc6c699cf6d04a7e4_b.jpg)
+ + + +[青海省阳光警务大厅-- +重名查询](https://link.zhihu.com/?target=http%3A//gat.qinghai.gov.cn/stmhwz/bmfw/toCMCX) + +查询条件:不需要登录,不需要验证码! + +* * * + +新疆 + +![](https://pic3.zhimg.com/v2-9e49c326e2ef5055d23066c297468542_b.jpg)
[登录](https://link.zhihu.com/?target=http%3A//puser.xjgat.gov.cn%3A9001/login%3Fclient_id%3DC20180718114207%26redirect_uri%3Dhttp%253A%252F%252Fwww.xjgat.gov.cn%252FAffairs%252Fuum%252Fapi%252Foauth%252Fcallback%252Fcode%26response_type%3Dcode%26scope%3Dopenid%26state%3D145cfc77-1553-43dc-81d7-dfb5cd6fb359) + +查询条件:需要登录,按照相关提示查询即可! + +* * * + +天津 + +![](https://pic1.zhimg.com/v2-1eddf46ee277baa996031afab6a65ff4_b.jpg)
[信息查询](https://link.zhihu.com/?target=http%3A//wx.ga.tj.gov.cn/WeixinWebapp/Index/search.aspx) + +查询条件:必须在微信客户端打开,并且需要登录! + +* * * + +辽宁 + +![](https://pic4.zhimg.com/v2-cd77b8d296585b03ebcbd8f3580fad0f_b.jpg)
+[https://pc.zwfw.gat.ln.gov.cn/query/item/cm](https://link.zhihu.com/?target=https%3A//pc.zwfw.gat.ln.gov.cn/query/item/cm) +查询条件:查询一次可以展示各个地市的重名人数。 + +* * * + +## 山西省 + +![](https://pic2.zhimg.com/v2-b203f87bf2cc5f5028c5559313a97b89_b.jpg)
+ + + +[山西省公安厅审批服务“一网通办”平台](https://link.zhihu.com/?target=http%3A//gat.shanxi.gov.cn/%23/home) + +查询条件:需要登录,查询中心输入验证码! + +* * * + +安徽省 + +![](https://pic1.zhimg.com/v2-60f3e5807738d7d3098b8553b5d02620_b.jpg)
[重名查询](https://link.zhihu.com/?target=http%3A//www.ahga.gov.cn%3A8087/was2/ewt/m/za/uniqename.html) + +查询条件:不需要登录! + +陕西省 + +![](https://pic2.zhimg.com/v2-7dd161c1efa082f945d98c60f7ad69bd_b.jpg)
+ + + +[陕西"互联网+公安政务服务"平台](https://link.zhihu.com/?target=http%3A//wsbs.shxga.gov.cn//webjjbus/cxzx.jsp%3Ftb_style%3D4%23%23%23) + +查询条件:需要登录,查询中心输入验证码! + +* * * + + **四川省** + +![](https://pic3.zhimg.com/v2-b342d4da7785e7aca52e7e2bff15ac2a_b.jpg)
四川省同名查询截图 + + + +[四川公安政务服务网](https://link.zhihu.com/?target=http%3A//scgazwfw.sczwfw.gov.cn/%3FconvenientService%3Dxinshenger) + + +查询条件:不需要注册,不需验证码,不分男女 + +* * * + + **云南省** + +![](https://pic1.zhimg.com/v2-289f533d302355af17eb744bdeeb0c54_b.jpg)
+ + + +[ +http://gazwfw.yn.gov.cn/webchat/#/name](https://link.zhihu.com/?target=http%3A//gazwfw.yn.gov.cn/webchat/%23/name) + +查询条件:不需要注册,不需验证码,区分男女 + +* * * + +宁夏 + +![](https://pic4.zhimg.com/v2-e6069ab520ac40e50a63dbcd0e0ee6cf_b.jpg)
宁夏重名查询 + + + +[宁夏重名查询](https://link.zhihu.com/?target=https%3A//zwfw.gat.nx.gov.cn/wechat/%23/repeat- +name-query) + +查询条件:不需要注册,不需验证码,不分男女 + +江西 + +[[江西省]重名查询](https://link.zhihu.com/?target=http%3A//ganfutong.jiangxi.gov.cn/jmopen/webapp/html5/jxscmcx/index.html) + +查询条件:不需要注册,需验证码,不分男女 + +* * * + +内蒙古 + +[重名查询](https://link.zhihu.com/?target=http%3A//alipaynmg.nmgmhw.com/nmg/cm/) + +查询条件:不需要注册登录 + +* * * + +湖北 + +[湖北公安政务服务平台](https://link.zhihu.com/?target=https%3A//wsgaj.chutianyun.gov.cn/weixin/%23/renameQuery) + +* * * + +浙江 杭州 + +[http://www.hzpolice.gov.cn/weixinWX/Renamecx.aspx](https://link.zhihu.com/?target=http%3A//www.hzpolice.gov.cn/weixinWX/Renamecx.aspx)
+[重名查询 - 网上办事大厅 - 杭州公安局](https://link.zhihu.com/?target=http%3A//service.hzpolice.gov.cn/cmcx/NameSearch.aspx) + +* * * + +福建 + +需要下载“闽政通”app + +[便民服务_福建省人民政府门户网站](https://link.zhihu.com/?target=http%3A//www.fujian.gov.cn/bmfw/) + +公众号 福建治安便民->新生儿取名指引 + +* * * + +海南 + +“海南警方”公众号 警民通->户政 + + + +## 其他信息请参考如下文章: + +[全国及各省姓名重名查询接口汇总](https://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzA5ODQyNjYyNA%3D%3D%26mid%3D2247483785%26idx%3D1%26sn%3D7fb119e435ab3f47242f5f9ca4216c1c%26chksm%3D90908be6a7e702f06f01addfb992eec083616bad8b9454f60f00fe15ab84bd23ae814127288c%26token%3D94067302%26lang%3Dzh_CN%23rd) + diff --git a/docs/ext.md b/docs/ext.md new file mode 100644 index 00000000..b7a4eb68 --- /dev/null +++ b/docs/ext.md @@ -0,0 +1,79 @@ + + +### 其他(补充资料) ### +起名算法: + 算法(进度) 备注 + 五格(95%) 暂用字库已补全 + 三才(95%) 暂用字库已补全 + 八字(100%) 喜用神完成, 补八字完成 + 卦象(100%) 算法完成,起卦完成,吉凶过滤完成。 + 生肖(30%) 生肖获取完成,字库筛选待完成 + 天运(TODO) + +立春: +2019年02月04日 11:14:14 +2020年02月04日 17:03:12 +2021年02月03日 22:58:39 +2022年02月04日 04:50:36 +2023年02月04日 10:42:21 +2024年02月04日 16:26:53 +2025年02月03日 22:10:13 +生肖按八字算从立春开始算起,不到时间则为上一年。 + +1、配合八字命理的喜忌,是起名字的核心所在。 +八字是每个人出生的年、月、日、时,小孩取名的第一步即是分析八字,了解命理五行所缺并找出喜用神,并且据此起名,这是最关键的核心,所有姓名的吉凶预测与取名,都以此为准。 +2、名字用字字义务必吉祥 +中国文字的魅力在于,每个方块字不仅都有其本身的含义,而且还有其特殊的周易诱导含义,名字在很多时候它还会影响到人性格的形成,正所谓“名如其人”。 +所以一个好的名字,务必用字字义吉祥。 +宝宝起名字确实需要考虑很多因素,不仅要考虑读音、字形以及各种禁忌更重要的是要考虑宝宝的生辰八字,因此给孩子起名还是找专家比较好。 +现在这方面比较知名的应该是温雅居士了,温雅居士在宝宝起名方面有着十几年的经验独创易学起名法:排八字、看五行、测五格、配三才、合属相、想寓意、听音律、写字形,在业界目前应该是比较权威的了。 +取名是需要非常系统考虑的,不能只考虑读音一个方面,温雅居士采用的排八字、看五行、测五格、配三才、想寓意、听音律、写字形的综合起名法非常喜欢。 +3、五格数理,特别是主格的数理要为吉数。 +在姓名学中,数理产生许多福祸吉凶的灵动力,对人生影响很大。 +这跟单个姓名用字的笔划好坏无关,准确的福祸吉凶是按照特殊方式计算数理的。 +4、三才配置一定不可以相克。 +三才配置在姓名学中,占有很大的分量。三才配置指的是天格、人格、地格之间的关系。中国传统文化中有顺应天时、地利、人和的行事哲理; +测名过程中,有很多姓名数理不错,但是三才配置不佳,大多表现为运气反复,遇事受阻碍,且感情及财运不好。 +三才配置相生相克的关系定吉凶,同样也影响着一个人事业成功率的高低。 +5、五格配置在姓名学中占有主要位置。 +五格配置是指天格、地格、人格、外格、总格共五格之间的关系。 +天格是由祖先流传而来,单独出现对人生没有多大影响;人格是姓名剖象数理的中心所在,对人生的影响最大; +人格与地格结合的数理则为基础运。地格主要是36岁前的人生,也叫前运力,外格代表人的外围,吉凶无谓。总格是36岁以后的人生,也是后运力。 +6、小孩取名字时还要结合命主的出生方位、父母资料等因素,以达到事半功倍的效果。 + 其实任何事情道理都是一样的,只有适合自己的才是最好的。 + +周易卦象编码参考: + +六十四卦 +# ䷀ ䷁ ䷂ ䷃ ䷄ ䷅ ䷆ ䷇ ䷈ ䷉ ䷊ ䷋ ䷌ ䷍ ䷎ ䷏ +# ䷐ ䷑ ䷒ ䷓ ䷔ ䷕ ䷖ ䷗ ䷘ ䷙ ䷚ ䷛ ䷜ ䷝ ䷞ ䷟ +# ䷠ ䷡ ䷢ ䷣ ䷤ ䷥ ䷦ ䷧ ䷨ ䷩ ䷪ ䷫ ䷬ ䷭ ䷮ ䷯ +# ䷰ ䷱ ䷲ ䷳ ䷴ ䷵ ䷶ ䷷ ䷸ ䷹ ䷺ ䷻ ䷼ ䷽ ䷾ ䷿ + +八卦 +# ☰ ☱ ☲ ☳ ☴ ☵ ☶ ☷ + +四象 +# ⚌ ⚍ ⚎ ⚏ + +两仪 +# ⚋⚊ + +最近看到有人别出心裁说三才不准,并举了一些名人的例子. +然后他倒过来算,发现很符合,很正确. +那我也就呵呵了,按准确度来算,非正即反. +你倒过来算,不准的变准了.那原来准的那些不就不准了. +在我看来事分阴阳,而这接近一半的准确度则恰到其好处. + +所以,遵照传统为自己的宝宝起一个中正平和的名字才是最好的. +从概率论的角度来讲,相交得到的最终结果.其准确度最高. +所以,单纯得拿一种或两种方法来取名是不可取的. +尽量符合多种的名字才是最佳,但并不一定需要全中. +Fate的本意是让起名变得简单,且能取到一个好的名字. +有人会花个十几,几十万取一个名字(周围的真人真事), +但是这个名字好不好你却未必知道. +算法开源就是为了让每个人知道, +这个名字取名过程的来龙去脉. + + + diff --git a/docs/fate.png b/docs/fate.png new file mode 100644 index 00000000..f980ea31 Binary files /dev/null and b/docs/fate.png differ diff --git a/docs/zodiac_shu.md b/docs/zodiac_shu.md new file mode 100644 index 00000000..e549daf1 --- /dev/null +++ b/docs/zodiac_shu.md @@ -0,0 +1,359 @@ +属鼠的人适合的字 + +您如果是属老鼠;首先要了解老鼠的特性,才能了解名字的好坏 +老鼠喜欢披彩衣 ( 漂亮 ) 或戴冠,得王及掌权,喜吃五穀杂粮,能得洞穴或得水或得木则属佳,如又得龙、得猴成三合局,如得猪、得牛成三会局—名字中如有符合下述条件者为好名。 + +一. +老鼠天生喜欢打洞又喜欢黑暗,以便做为藏身之所。所以名字中宜有 「口」、「宀」、「门」、「户」、「广」等字根,代表洞穴可安身立命,得「ㄙ」也可代表翘脚休息。例如:向、右、嘉、宏、宝。 +二. +老鼠在生肖排名为第一生肖,排名最前面的生肖,当然在十二生肖中,当王戴王冠最适合。名字中宜选用有「王」、「令」、「冠」、「壹」、「尊」、「爫」、「亠」、「君」等字最得体。例如:冠、玲、琴、君、帝。 +三. +老鼠之生肖属子,如遇申 ( 猴 )、子 ( 鼠 )、辰 ( 龙 ) 为三合局,如有「申」、「万」、「辕」、「袁」、「辰」、「丽」、「麒」、「麟」的字形,帮助力大,恰是遇贵人运强,财运更加顺畅。例如:振、云、玖、媛、农。 +四. +名字中如有亥 ( 猪 )、子 ( 鼠 )、丑 ( 牛 ) 为三会局,老鼠与猪、牛为三会北方水。三会的力量也有贵人运,对自己也有所帮助。字形中如有「亥」、「豪」、「家」、或「丑」、「牛」、「生」、「纽」会很棒。例如:加、豪、众、聚、生、产。 +五. +老鼠喜欢在夜间活动,字形喜欢有「夕」、「铭」、「名」字边表一生安全,压力少。例如:多、夜、梦、名。 +六. +鼠是一种偏爱五穀杂粮的杂食性动物。因此,名字中适合用以「豆」、「米」、「禾」、「麦」、「梁」、「心」、「艸」、「月」为部首的字。例如:豔、丰、栗、精、秩、秉、、麴、怡、恆、念、恩、朋、期。 +七 +老鼠喜欢披彩衣漂亮,以华丽其身。如果有字根如「彡」、「巾」、「系」、「示」、「衣」、「疋」、「采」边最佳,显得高贵。例如:素、结、囊、裴、席、布、洁、释、彬、彭。 +有"八"或"宀"字(或部首内包含),则环境良好,名利双收,清雅荣贵 +有"米"字、"豆"字、"鱼"字, 福寿兴家,子孙鼎盛; +有"艹"字、"金"字、"玉"字,精明公正,操守廉正; +有"亻"字、"木"字、"月"字,贵人明现,克己 助人; +有"田"字,快乐待人,一生清閒; + +如果生肖属老鼠的人,想要命名且能符合十二生肖的喜用字,以下字库将会为您带来很大的方便。 +生肖属老鼠喜用字库 + +鼠喜 3划 +上、于、口、大、女、子、巾 +鼠喜 4划 +丑、中、丹、云、井、互、元、匀、升、壬、太、户、方、月、水、牛、王 +鼠喜 5划 +世、丘、主、令、充、冬、加、北、卉、古、右、司、台、巨、市、布、本、民、永、玄、玉、生、用、田、由、甲、申、禾、立 +鼠喜 6划 +丞、亥、兆、先、再、匡、同、各、名、后、回、好、如、宇、守、安、曲、有、牟、米、羽、自、舟、衣、西 +鼠喜 7划 +江、池、串、亨、兑、利、助、吾、吕、君、告、吹、吟、妍、妤、孚、宏、局、希、彤、杉、甫、男、秀、见、言、谷、豆、贝、车、辰、里、町 +鼠喜 8划 +沅、沛、汪、沐、沂、玖、事、享、京、儿、函、叔、和、固、奇、姗、孟、宗、定、官、宜、宙、尚、居、岸、帛、店、府、承、服、朋、枋、果、松、知、秉、竺、采、金、长、阜、雨、青、汯 +鼠喜 9划 +育、怡、注、泳、河、波、法、油、治、玥、冠、勃、劲、厚、品、客、宥、屋、帝、度、建、彦、思、扁、柱、柔、架、柚、皇、盈、省、相、眉、科、贞、军、韦、飞、首、泰、柘 +鼠喜10划 +肴、芳、芸、洲、洪、流、津、洞、活、洛、珊、玲、珍、唐、哥、员、唇、娟、家、宫、容、宸、展、峰、师、桐、桀、畔、益、真、祐、神、祝、素、纯、纭、训、财、贡、轩、高、紘 +鼠喜11划 +胞、胤、若、苗、悟、悦、振、海、涓、浚、浴、浩、琉、珮、凰、动、区、商、问、寂、专、将、崇、常、康、彬、彩、启、旋、毫、笛、笙、统、绍、细、绅、翎、袈、访、责、贯、野、鹿、浤、婕、娸、翊 +鼠喜12划 +草、茵、茗、捷、凉、淳、添、清、淇、渊、涵、深、淦、理、现、胜、博、单、乔、婷、媚、富、寓、帧、惠、期、栋、棉、甥、登、发、程、童、粟、紫、丝、络、舒、咏、贺、贵、钧、闳、雅、茜、淀、渌、琇、渺、诒 +鼠喜13划 +莎、莉、莆、挥、援、港、湛、湘、湖、涣、湄、琪、琳、琴、琛、琦、琨、勤、嗣、园、圆、嫁、廉、敬、新、业、楚、榆、毓、督、祺、禄、万、经、绢、圣、裕、诗、诘、农、铃、雷、靖、顿、鼎、粲、豊 +鼠喜14划 +郡、菩、萍、菁、华、溶、源、沧、溪、瑞、瑜、嘉、图、实、彰、旗、榕、荣、榛、槐、睿、硕、祯、福、管、精、绰、绫、绿、纲、绮、绸、绵、纶、维、肇、舞、裴、诵、志、语、诰、豪、宾、辅、铜、铭、铨、阁、领、魁、凤、滕、玮、嫺 +鼠喜15划 +陞、苇、汉、满、瑶、娴、婵、娇、宽、广、庆、慧、莹、稼、穀、稻、缔、纬、緻、缘、谊、谅、谆、论、赏、赋、锋、震、颉、槿、缃、鋐、霈、靓 +鼠喜16划 +乡、蓉、蒲、苍、澄、洁、潭、润、瑾、器、学、寰、桦、橙、树、机、积、颖、糖、萦、翰、臻、兴、亲、谚、谋、谕、豫、录、锦、錡、霖、静、龙、蓁、璇 +鼠喜17划 +隆、蔗、濂、浓、泽、嫔、嵘、檐、爵、禧、穗、糠、绩、聪、襄、谦、阔、隶、鸿、璠、柽、谥 +鼠喜18划 +济、濠、涛、濬、潍、环、瑷、璨、礼、穠、绣、谨、丰、鎔、颛、荞、铠 +鼠喜19划 +蕾、璿、玺、祷、稳、绎、赞、铿、韵、鲸、麒、丽、薆、滢 +鼠喜20划 +藏、怀、瀚、琼、罗、劝、宝、胧、继、觉、警、钟、馨、泷、潆 +鼠喜21划 +藩、艺、藤、珑、樱、誉、跃、铎、露、顾、鹤 +鼠喜22划 +苹、苏、瓖、懿、权、读、沣、孋、穰、镔、龢 +鼠喜23划 +兰、岩、欐、麟、纕 +鼠喜24划 +瓒、让、灵、霭、鑫 +鼠喜25划 +观、镶、钥、黉、靉 +鼠喜26划 +郦、湾、讚 +鼠喜27划 +滦、锣 +鼠喜28划 +豔 +鼠喜30划 +鸾 +********************************************************** + + +属鼠的人不适合的字 + +您如果是属老鼠;首先要了解老鼠不喜欢的情况,才能了解名字的好坏 +属鼠之人不喜欢字有人字边就像 ( 过街鼠,人人喊打 ),避免有火字形因 ( 水火不容 ),避免有马字形 ( 子午正冲 ),避免有羊字形 ( 鼠羊相遇一旦休 ),避免有奔跑字形 ( 逃命 ),避免有太阳字形 ( 不喜欢见日 ) ,如果名字中有以上所举例之字形,就表示名字有破格。 + +一. +属鼠之人避免使用有「羊」、「妹」、「朱」的字形,因为子未相害,「羊鼠相逢一旦休」伤害力也很大。例如:群、达、美、善、羡。 +二. +属鼠之人避免用「辵」、「几」、「弓」、「邑」的字根,因其形如蛇,鼠惧蛇,蛇会吞鼠,遭受到伤害,小人很多。例如:张、邱、邓、那、选、造、达。 +三. +不喜欢当老二,忌用:士、卿、臣、工…………不得志,能力无法施展。 +四. +属鼠之人避免有午或马字之字形,应避免用之,否则犯了对冲,伤害力大。例如:许、竹、腾、骏。 +五. +属鼠之人避免有「火」及「土」之字形,因为子为水,水火相剋土剋水,身心不安。例如:炎、炫、煜、灿、照、熊、燕。 +六. +老鼠也会怕人,所谓人见鼠避喊打,因此。也要避免以「人」、「ㄔ」为部首的字,以免造成伤害。例如:仙、何、佳、俊、值、律、从、彻、徵。 +由于老鼠是习惯在夜晚活动的动物,因此,所谓见光死的避讳,即需要避免使用以「日」为字根的字,否则也亦产生危险。例如:昭、智、书、意、是、晖。 +有"山"字,孤独,六亲无缘,离祖成功; +有"刀"字、"力"字、"弓"字,不利家 庭,晚婚迟得子大吉; +有"土"字,不利健康或忧心劳神; +有"忄"字,多不顺或作风果断; +有"石"字,不利健康; +有"皮"字、"氵"字、"马"字、"酉"字、"火"字、"车"字,忌车怕水或易犯法。 +肖鼠年生人,到岁次肖马年、肖鸡年、肖羊年要小心注意,到岁次肖牛年、肖龙年、肖猴年一帆风顺、成功隆昌。 + +如果生肖属老鼠的人,名字中有以下文字,那代表名字不符合生肖姓名学理论,请您仔细印证,请在下次命名时,儘量避开以下文字就 ok +鼠忌 2划 +丁、二、人 +鼠忌 3划 +士 +鼠忌 4划 +仁、仃、仇、仍、今、介、化、午、夭、孔、巴、日、火 +鼠忌 5划 +以、付、仕、代、仙、仟、卯、央、平、旦、未 +鼠忌 6划 +汀、伙、伊、伍、休、仲、件、任、仰、仳、份、企、光、全、印、合、地、在、圭、妃、寺、早、旨、旬、旭、朴、次、竹、羊、臣、行、仵、价、伂 +鼠忌 7划 +位、住、伫、伴、佛、何、估、佐、佑、伺、伸、似、但、作、伯、低、伶、余、佈、免、坊、址、坍、均、坎、壮、孝、宋、巫、志、攸、杜、赤、辛、佟 +鼠忌 8划 +抑、亚、佯、依、侍、佳、使、供、例、来、佰、佩、仑、佾、侑、兔、味、命、坪、坡、坦、妹、岱、幸、旺、易、昌、昆、昂、明、昀、昏、昊、昇、东、杵、炎、祀、卧、佼、佶、侄、坵、旻、炅、耵 +鼠忌 9划 +肖、拒、沫、亭、亮、信、侯、侠、保、促、俟、俊、俗、俐、係、俞、勉、南、哇、型、垠、垣、垢、城、姜、姿、宣、封、庠、律、徉、春、昭、映、昧、是、星、昱、柯、柏、柳、炫、为、炳、炬、炯、红、美、订、酊、香、俋、昶、炷 +鼠忌10划 +肯、洋、倍、俸、倩、倖、俩、值、倚、倨、俱、倡、候、修、倪、俾、伦、冤、冻、卿、埂、埔、埃、姬、娩、宰、差、徐、恙、时、晋、晏、晃、晁、书、桓、柴、氧、烊、烈、留、羔、耿、袁、袂、酒、钉、马、珋、倢、埕、埒、晟 +鼠忌11划 +邦、那、迎、胡、苎、苣、茉、英、茆、挽、珠、停、假、偃、偌、做、伟、健、偶、侦、倏、冕、曼、唱、域、坚、堆、埠、基、堵、执、婚、张、得、从、悠、教、晚、晤、曹、勗、欲、焉、烯、瓷、祥、羚、聊、袋、许、顶、偈、偅、偩、偮、娅、欷、欸、羕 +鼠忌12划 +邱、迪、悻、傢、傅、备、杰、喜、尧、堪、场、堤、堰、报、堡、复、普、晰、晴、晶、景、智、曾、棚、款、焰、然、善、翔、贷、距、辜、集、冯、傌、媄、焯、羢 +鼠忌13划 +郎、郁、脩、莘、莫、荷、提、扬、佣、傲、传、仅、僇、吗、塑、塘、涂、塚、塔、填、塌、块、坞、妈、微、意、暗、晖、暖、暄、会、楠、杨、歇、照、煜、焕、义、羡、群、详、路、钾、铆、驰、驯、渼、羟 +鼠忌14划 +郝、连、造、逢、菟、署、僧、像、侨、境、垫、墅、寿、彻、榴、歌、熙、熊、监、绽、台、赫、輓、驳、墉、杩 +鼠忌15划 +都、逸、进、慢、漾、漫、亿、仪、僵、价、侬、俭、刘、墟、增、坠、墩、嬉、德、徵、暮、样、槽、楼、欧、羯、蝴、卖、辉、锌、养、驻、驷、驶、驾、驹、鲁、儆、僾、儌、墡、禡、羬 +鼠忌16划 +陈、运、道、达、潜、骂、儒、傧、壁、垦、坛、壅、曆、晓、昙、炽、燕、熹、笃、糕、羲、谘、醒、骆、嶪、烨、羱 +鼠忌17划 +阳、邹、远、优、偿、储、壕、壑、壎、曙、营、灿、镁、鍚、骋、骏、鲜、鲑、邬、蓨、澲、燨 +鼠忌18划 +膳、丛、垒、曜、柠、欤、缮、缯、题、骑、镏、骐 +鼠忌19划 +郑、邓、选、薑、嚥、垄、坜、曝、羶、羹、辞、鹏、鄯、薘、繨 +鼠忌20划 +邺、迈、壤、曦、耀、议、骞、腾、骝 +鼠忌21划 +牺、驱、蓦 +鼠忌22划 +欢、鑑、鞑、骄、骅 +鼠忌23划 +惊、驿、验 +鼠忌24划 +坝、骤、驞 +鼠忌26划 +骥 +鼠忌29划 +骊 +************************************************** +*生肖为老鼠,名字中有正冲字根之现象 +骏、驰、驻、驹、驾、骐、骞、腾、骅、骥、骧、驿、炎、炫、炯、炳、烈、烽、 焜、焦、然、炼、辉、煌、炜、熙、煜、、焕、煦、熔、灯、燕 +子午正冲,水火不容,身心折磨,运途难通,鼠马相遇,财散难聚,亲友反目,情泪重重,本命为水,若如一般术士而言,缺水补火危害大亥。 +*逢相刑字根之现象 +勉、迎、逸、青、明、卿、栋、东、柳、木、育、有、朝 +良缘难求,人际不彰,逢木带洩,逢月带刑。 + +用于名一 + +.个性上:企图心转弱,且易投机取巧,随遇而安。.人际上:表面上热心付出,常随意答应别人条件,却未去执行,终究让人看穿而远离。.感情上:另一半个性较为凶悍,马车夫之恋。.健康上:肠胃稍弱,筋骨不佳,且肝功能稍弱。.婚姻上:另一半生肖忌讳为鼠、猴、鸡。 + + + +用于名二 + +.学业上:依天干五行及阳边字根不同而过程不一,但皆欠缺临门一脚,考运较弱。.事业上:须靠自己,下属宫较弱。.财运上:有财无库,较为浪费,不善理财,易投机。.健康上:筋骨、妇科较差,易有酸痛,流年逢鸡年事事不顺。 + +*名字中带六害(羊)字根之现象 +美、群、仪、洋、羚、羢、善、妹、详、祥、姜、义、未、幸、达、珠、南、翔 +老鼠逢肉现危机,心性、做事险中求。 + +用于名一 + +.个性上:不论是热心、付出或任性,都因个性过直,而容易让人有难相处之感觉。.人际上:不论怎麽做,皆易受到背叛,一生小人不断。.感情上:情路坎坷,真心换绝情,必遇到让其心碎之人。.健康上:易有血液、皮肤过敏之现象,心肺、肠胃,功能皆差,不到三十岁即有腰酸背痛的症状。.婚姻上:此名另一半为任何生肖皆不宜,宜更名,如生肖为牛、鼠者更差。 + + + +用于名二 + +.学业上:坐不住,考运差,学非所用,不喜欢待在家裡。.事业上:无事业宫,易帮倒忙,梧鼠技穷,怀才不遇,有志难伸。.财运上:不善理财,就算阴边字根配合得宜,晚年容易有病缠身的状况。.健康上:肾脏、妇科、泌尿系统易有恶疾,三十岁前筋骨容易酸痛。 + + +*名字中有「土」字根的现象 +土、在、地、均、坤、城、培、基、堂、坚、堉、涂、塘、境、增、墨、壁、垒、筠 +子为水.逢土为剋。 + +用于名一 + +.个性上:委屈求全,把事放在心裡不会说出来,易得忧鬱症,个性较闷,企图心弱。.人际上:男性朋友尚可,但女性则无助力,易形成表象好,暗裡忧。.感情上:委屈求全,另一半个性较强,良缘难求。.健康上:肠胃、脾脏、筋骨不佳,由于常把事情闷在心裡易得忧鬱症,内分泌易失调。.婚姻上:另一半生肖忌讳为鼠、牛、兔、猪。 + + + +用于名二 + +.学业上:依阳边字根不同而结果不同。.事业上:女性下属小六岁以下则无助力,男性则因天干五行及名字的字根不同,而结果不同。.财运上:虽自己花钱省,但往往存到一笔钱却拱手给人花用,钱财不聚,财去人安乐,晚年无福可享,与女儿缘浅。.健康上:易有痛风、筋骨、泌尿系统问题,女性则妇科不顺,易犯刀刑。 + + +*名字逢「肉」字根之现象。 +志、患、念、思、怡、恆、恕、恭、悦、惇、惟、惠、意、愉、爱、愈、慈、慕、慧、虑、庆、宪、月、育、鬱、恬、应 +老鼠逢肉现现危机,心性、做事险中求。 + +用于名一 + +.个性上:过度聪明,想太多,做事易险中求。.人际上:刚开始因朋友尚未看清楚自己而对其有帮助,易获得小便宜,但终究吃大亏。.感情上:易摇摆不定。.健康上:无特别明显病痛,肠胃稍弱。 + + + +用于名二 + +.学业上:女由于心字边皆在名字阴边,学业宫在阳边,所以需依阳边字眼而论好坏吉凶。.事业上:依阳边字根不同而结论不同,但女性下属宫较弱。.财运上:不善理财,若论投资刚开始有小利润,但终究如老鼠吃肉般,最后易有大损失。.健康上:无特别病痛,筋骨、妇科稍弱。 + + +*名字逢「小」字根之现象。 +士、仕、亚、次、小、少、相、卿、叔、仲、季、臣、姿、力、工、二、臣 +老鼠贵为天子逢小为降格,易委屈求全,热心付出但无回报。 + +用于名一 + +.个性上:热心付出,随遇而安,企图心弱,自信不足。.人际上:牺牲奉献,为别人的贵人。.感情上:委屈求全,另一半个性较为凶悍。.健康上:半身;脖子以下,肚脐以上,功能稍弱,骨架不易撑开,心肺功\能稍弱。 + + + +用于名二 + +.学业上:读书事倍功半,难学以致用。.事业上:替别人打江山,为人抬轿,功成身退。.财运上:赚钱别人享受,不善理财,对下属及儿女太好,易被小孩爬到头上。.健康上:无明显疼痛,但筋骨下半身功能稍弱。 + + +*逢「立」字根之现象。 +竑、章、竟、竣、立、童、端、竞、昱、翊 +老鼠站立现危机,有财无库易伤财。 + +用于名一 + +.个性上:自信心不足,不够安定,不稳,欠缺规划能力。.人际上:为别人的贵人,易犯小人。.感情上:爱人在心,口难开,另一半个性较强。.健康上:肠胃、筋骨、心肺功能皆弱。.婚姻上:另一半生肖无特别禁忌,以虎、龙、猴、鸡为佳。 + + + +用于名二 + +.学业上:坐不住,事倍功半,难学以致用,梧鼠技穷。.事业上:工作靠自己,格局受限,下属无力。.财运上:有财无库,不善理财,有钱是非多,状况亦多,财去人安乐。.健康上:无特别明显病痛,筋骨稍弱。 + + +*名字有「日」字根的现象。 +旭、旺、昆、昇、昌、明、易、星、映、春、昭、昱、时、晋、晃、皓、普、智、晖、暖、暘、曆、晓、晔、曜、曦、书、章、竟、耀 +老鼠逢日见光死,五行水火相冲剋。 + +用于名一 + +.个性上:性子过于急躁、不安,有头无尾。.人际上:过于急躁,行事欠缺考虑,易受人利用,而犯小人。.感情上:个性过急,良缘难寻,易把对象给吓跑,另一半个性较凶悍.健康上:肠胃极差,易有过敏体质,泌尿系统及心肺功能皆弱。 + + + +用于名二 + +.学业上:依天干五行不同而过程不同,但皆学非所用。.事业上:无下属可依靠,且工作运不佳,升迁困难。.财运上:不善理财,财去人安乐,晚年子息不孝。.健康上:筋骨、泌尿系统、妇科、血液问题皆差,宜速速更名。 + + +*名字逢「蛇」字根之现象。 +弘、强、延、廷、迪、迺、建、迅、迎、逐、逃、途、通、造、逢、连、进、逸、週、遇、游、运、道、达、远、适、迟、遴、迁、选、迈 + +「」「」部为眼镜蛇或奔跑之蛇。 +「弓」部为杯弓蛇影,引申为蛇。 +「几」部如挂在树上的蛇。 +鼠逢巳蛇心难安,蛇鼠一窝难重重。 + +用于名一 + +.个性上:个性急躁、不安,时而胆小,易想太多。.人际上:一下子这样,一下那样,易使贵人远离,且犯小人。.感情上:良缘难求,婚姻宫不佳。.健康上:肠胃、过敏体质,腰易酸痛,三十五到四十岁后易有水肿现象。 + + + +用于名二 + +.学业上:依天干五行及阳边字根不同结果不一,但容易受过敏体质而影响学习能力。.事业上:就算阳边搭配得宜,工作尚可却易赔了健康。.财运上:不宜玩金钱游戏,不善理财,有钱宜置不动产。.健康上:过敏体质及易有血液、水肿、妇科不佳等症状。 + + +*名字中逢「人」字根之现象。 +仁、介、仍、仕、以、仰、仲、休、任、伯、伸、估、佩、佳、来、依、俊、保、信、修、倍、倢、倩、值、伦、伟、健、杰、传、仅、仪、亿、儒、俪 +过街老鼠,人人喊打。 + +用于名一 + +.个性上:胆小,易想太多,忧柔寡断,企图心及规划能力差。.人际上:耳根子软,易被牵著鼻子走,做事缺乏主见,而贵人远离。.感情上:爱人在心,口难开,另一半个性凶悍。.健康上:肠胃、肝、筋骨不好。.婚姻上:另一半生肖忌讳为鼠、兔、虎、蛇、鸡。 + + + +用于名二 + +.学业上:依名字阳边不同而结论不同。.事业上:依阳边不同而结论不同,但不宜有女性下属。.财运上:有财亦无库,投资金钱游戏必破,妻无助力或不得夫财。.健康上:易伤及脚、筋骨、妇科不佳。 + + +*逢「木」字根之现象。 +杉、材、村、杞、东、林、枝、柄、柏、柳、柔、柱、栩、株、根、桂、桃、桐、梅、梓、梧、棉、棋、森、枫、业、榕、榛、荣、乐、楼、标、樟、树、机 +鼠逢木带刑、冲。(木带卯) + +用于名一 + +.个性上:虽然热心,但常答应别人却做不到,做事慢半拍,标准的没问题先生。.人际上:做事难以让人放心,一付天塌下来都无关紧要的心态,所以会让贵人远离。.感情上:另一半个性过刚,易遭埋怨。.健康上:肠胃稍弱,其馀需看阳边字根而判定。.婚姻上:另一半的生肖忌讳为猴、鸡。 + + + +用于名二 + +.学业上:依名字阳边不同而结论不同。.事业上:对女性下属太好过度付出,其馀事业宫需依阳边字根而定。.财运上:对女性下属太好过度付出,其馀事业宫需依阳边字根而定易有浪费、花费不知节制的现象,财去人安乐。.健康上:筋骨稍弱,无明显病痛。 + + + +*子鼠冲、刑、破、害、合、会的简易对照表 +‧冲 子午相冲 + +.许、驻、腾、驰、冯、驾、驶、骐、骏、驭、驸、骞、骁、骅、騄、骓、蓦、驎、驌、骢、驩、驦、骥、骄、朱、红、火、赤、珠。 + + + + +‧刑 子卯相刑 + +.勉、迎、仰、月、青、朋、卿、印、栋、东、柳、木、服、期、望、明、郁、春、四、林、朝、朗、逸、昂、冕、晚。 + + + + +‧破 子酉相破 + +.雅、鸿、兆、非、飞、耀、翁、雁、翠、鸣、翰、进、翎、鹃、凤、鹤、鹰、莺、羿、翃、习、翔、翡、雄、集、雕、离、壅、十、隽、酥、兑、翎、鹃。 + + + + +‧害 子未相害 + +.子未相害 义、姜、美、翔、详、祥、洋、妹、仪、善、幸、羚、茱、珠、南、达、泽、报、群、味、朱、烊、佯。 + + + + +‧合(申子辰合) + +.环、远、袁、猿、园、坤、侯、神、祖、祐、申、绅、伸、寰、宸、农、震、丽、珑、振、晨、麟、麒、君、贝、云。 + + + + +‧会 亥子丑会 + +.豪、家、缘、象、众、孩、毅、该、核、聚、生、隆、造、物、牧、皓、牲、萨、钮、星。 diff --git a/error.go b/error.go new file mode 100644 index 00000000..db78cc7a --- /dev/null +++ b/error.go @@ -0,0 +1,15 @@ +package fate + +import ( + "fmt" + "strings" +) + +// Wrap ... +func Wrap(err error, msg ...string) error { + if err != nil { + m := strings.Join(msg, " ") + return fmt.Errorf("%s:%w", m, err) + } + return nil +} diff --git a/example/create_a_name/main.go b/example/create_a_name/main.go new file mode 100644 index 00000000..673b479d --- /dev/null +++ b/example/create_a_name/main.go @@ -0,0 +1,79 @@ +package main + +import ( + "context" + "github.com/godcong/chronos" + "github.com/babyname/fate" + "github.com/babyname/fate/config" +) + +func main() { + + //cfg := config.DefaultConfig() 参数如下 + //config.Config{ + // HardFilter: false, + // //输出最大笔画数 + // StrokeMax: 3, + // //输出最小笔画数 + // StrokeMin: 18, + // //立春修正(出生日期为立春当日时间为已过立春八字需修正) + // FixBazi: true, + // //三才五格过滤 + // SupplyFilter: true, + // //生肖过滤 + // ZodiacFilter: true, + // //周易八卦过滤 + // BaguaFilter: true, + // //连接DB: + // Database: config.Database{ + // Host: "localhost", + // Port: "3306", + // User: "root", + // Pwd: "111111", + // Name: "fate", + // MaxIdleCon: 0, + // MaxOpenCon: 0, + // Driver: "mysql", + // File: "", + // Dsn: "", + // ShowSQL: false, + // ShowExecTime: false, + // }, + //}) + //出生日期 + born := chronos.New("2020/01/14 02:45") + //姓氏 + lastName := "张" + cfg := config.DefaultConfig() + cfg.BaguaFilter = true + cfg.ZodiacFilter = true + cfg.SupplyFilter = true + cfg.HardFilter = true + cfg.StrokeMin = 3 + cfg.StrokeMax = 24 + cfg.Database = config.Database{ + Host: "localhost", + Port: "3306", + User: "root", + Pwd: "111111", + Name: "fate", + MaxIdleCon: 0, + MaxOpenCon: 0, + Driver: "mysql", + File: "", + Dsn: "", + ShowSQL: false, + ShowExecTime: false, + } + cfg.FileOutput = config.FileOutput{ + OutputMode: config.OutputModeLog, + Path: "name.log", + } + + f := fate.NewFate(lastName, born.Solar().Time(), fate.ConfigOption(cfg)) + + e := f.MakeName(context.Background()) + if e != nil { + panic(e) + } +} diff --git a/example/update_regular/main.go b/example/update_regular/main.go new file mode 100644 index 00000000..0590e38c --- /dev/null +++ b/example/update_regular/main.go @@ -0,0 +1,14 @@ +package main + +import ( + "github.com/babyname/fate" + "github.com/babyname/fate/config" + "github.com/babyname/fate/regular" +) + +func main() { + c := config.LoadConfig() + db := fate.InitDatabaseWithConfig(*c) + r := regular.New(db) + r.Run() +} diff --git a/fate.go b/fate.go new file mode 100644 index 00000000..79d82f3b --- /dev/null +++ b/fate.go @@ -0,0 +1,345 @@ +package fate + +import ( + "context" + "errors" + "fmt" + "strings" + "time" + + "github.com/goextension/log" + "github.com/xormsharp/xorm" + + "github.com/babyname/fate/config" + + "github.com/godcong/chronos" + "github.com/godcong/yi" +) + +// HandleOutputFunc ... +type HandleOutputFunc func(name Name) + +// HelpContent ... +const HelpContent = "正在使用Fate生成姓名列表,如遇到问题请访问项目地址:https://github.com/babyname/fate获取帮助!" + +// Fate ... +type Fate interface { + MakeName(ctx context.Context) (e error) + XiYong() *XiYong + RunInit() (e error) + RegisterHandle(outputFunc HandleOutputFunc) +} + +type fateImpl struct { + config *config.Config + db Database + out Information + born chronos.Calendar + last []string + lastChar []*Character + names []*Name + nameType int + sex Sex + debug bool + baZi *BaZi + zodiac *Zodiac + handle HandleOutputFunc +} + +// RunInit ... +func (f *fateImpl) RunInit() (e error) { + if f.config.RunInit { + if err := f.db.Sync(WuGeLucky{}); err != nil { + return err + } + + lucky := make(chan *WuGeLucky) + go initWuGe(lucky) + for la := range lucky { + _, e = f.db.InsertOrUpdateWuGeLucky(la) + if e != nil { + return Wrap(e, "insert failed") + } + } + } + return nil +} + +// Options ... +type Options func(f *fateImpl) + +// ConfigOption ... +func ConfigOption(cfg *config.Config) Options { + return func(f *fateImpl) { + f.config = cfg + } +} + +// SexOption ... +func SexOption(sex Sex) Options { + return func(f *fateImpl) { + f.sex = sex + } +} + +// Debug ... +func Debug() Options { + return func(f *fateImpl) { + f.debug = true + } +} + +// NewFate 所有的入口,新建一个fate对象 +func NewFate(lastName string, born time.Time, options ...Options) Fate { + f := &fateImpl{ + last: strings.Split(lastName, ""), + born: chronos.New(born), + } + f.lastChar = make([]*Character, len(f.last)) + if len(f.last) > 2 { + panic("last name was bigger than 2 characters") + } + + for _, op := range options { + op(f) + } + + f.init() + + return f +} + +// RegisterHandle ... +func (f *fateImpl) RegisterHandle(outputFunc HandleOutputFunc) { + f.handle = outputFunc +} + +func (f *fateImpl) getLastCharacter() error { + size := len(f.last) + if size == 0 { + return errors.New("last name was not inputted") + } else if size > 2 { + return fmt.Errorf("%d characters last name was not supported", size) + } else { + // ok + } + + for i, c := range f.last { + character, e := f.db.GetCharacter(Char(c)) + if e != nil { + return e + } + f.lastChar[i] = character + } + return nil +} + +// MakeName ... +func (f *fateImpl) MakeName(ctx context.Context) (e error) { + log.Info(HelpContent) + e = f.out.Head(f.config.FileOutput.Heads...) + if e != nil { + return Wrap(e, "write head failed") + } + defer f.out.Finish() + e = f.RunInit() + if e != nil { + return Wrap(e, "init failed") + } + n, e := f.db.CountWuGeLucky() + if e != nil || n == 0 { + return Wrap(e, "count total error") + } + + e = f.getLastCharacter() + if e != nil { + return Wrap(e, "get char failed") + } + name := make(chan *Name) + go func() { + e := f.getWugeName(name) + if e != nil { + log.Error(e) + } + }() + + var tmpChar []*Character + // supplyFilter := false + for n := range name { + select { + case <-ctx.Done(): + log.Info("end") + return + default: + } + + tmpChar = n.FirstName + tmpChar = append(tmpChar, n.LastName...) + // filter bazi + if f.config.SupplyFilter && !filterXiYong(f.XiYong().Shen(), tmpChar...) { + // log.Infow("supply", "name", n.String()) + continue + } + // filter zodiac + if f.config.ZodiacFilter && !filterZodiac(f.born, n.FirstName...) { + // log.Infow("zodiac", "name", n.String()) + continue + } + // filter bagua + if f.config.BaguaFilter && !filterYao(n.BaGua(), "凶") { + // log.Infow("bagua", "name", n.String()) + continue + } + ben := n.BaGua().Get(yi.BenGua) + bian := n.BaGua().Get(yi.BianGua) + if f.debug { + log.Infow("bazi", "born", f.born.LunarDate(), "time", f.born.Lunar().EightCharacter()) + log.Infow("xiyong", "wuxing", n.WuXing(), "god", f.XiYong().Shen(), "pinheng", f.XiYong()) + log.Infow("ben", "ming", ben.GuaMing, "chu", ben.ChuYaoJiXiong, "er", ben.ErYaoJiXiong, "san", ben.SanYaoJiXiong, "si", ben.SiYaoJiXiong, "wu", ben.WuYaoJiXiong, "liu", ben.ShangYaoJiXiong) + log.Infow("bian", "ming", bian.GuaMing, "chu", bian.ChuYaoJiXiong, "er", bian.ErYaoJiXiong, "san", bian.SanYaoJiXiong, "si", bian.SiYaoJiXiong, "wu", bian.WuYaoJiXiong, "liu", bian.ShangYaoJiXiong) + } + + if err := f.out.Write(*n); err != nil { + return err + } + if f.debug { + log.Infow(n.String(), "笔画", n.Strokes(), "拼音", n.PinYin(), "八字", f.born.Lunar().EightCharacter(), "喜用神", f.XiYong().Shen(), "本卦", ben.GuaMing, "变卦", bian.GuaMing) + } + } + return nil +} + +// XiYong ... +func (f *fateImpl) XiYong() *XiYong { + if f.baZi == nil { + f.baZi = NewBazi(f.born) + } + return f.baZi.XiYong() +} + +func (f *fateImpl) init() { + if f.config == nil { + f.config = config.DefaultConfig() + } + + if f.config.FileOutput.Heads == nil { + f.config.FileOutput.Heads = config.DefaultHeads + } + + f.db = initDatabaseWithConfig(f.config.Database) + f.out = initOutputWithConfig(f.config.FileOutput) +} + +// SetBornData 设定生日 +func (f *fateImpl) SetBornData(t time.Time) { + f.born = chronos.New(t) +} + +func (f *fateImpl) getWugeName(name chan<- *Name) (e error) { + defer func() { + close(name) + }() + lucky := make(chan *WuGeLucky) + go func() { + e = f.db.FilterWuGe(f.lastChar, lucky) + if e != nil { + log.Error(e) + return + } + }() + var f1s []*Character + var f2s []*Character + fsa := map[int][]*Character{} + bazi := NewBazi(f.born) + for l := range lucky { + if f.config.FilterMode == config.FilterModeCustom { + // TODO + } + + if bool(f.sex) && filterSex(l) { + continue + } + + if f.config.HardFilter && hardFilter(l) { + sc := NewSanCai(l.TianGe, l.RenGe, l.DiGe) + if !Check(f.db.Database().(*xorm.Engine), sc, 5) { + continue + } + } + + if f.config.StrokeMin > l.FirstStroke1 || f.config.StrokeMin > l.FirstStroke2 || f.config.StrokeMax < l.FirstStroke1 || f.config.StrokeMax < l.FirstStroke2 { + continue + } + + if f.debug { + log.Infow("lucky", "l1", l.LastStroke1, "l2", l.LastStroke2, "f1", l.FirstStroke1, "f2", l.FirstStroke2) + } + if fsa[l.FirstStroke1] == nil { + if f.config.Regular { + f1s, e = f.db.GetCharacters(Stoker(l.FirstStroke1, Regular())) + } else { + f1s, e = f.db.GetCharacters(Stoker(l.FirstStroke1)) + } + + if e != nil { + return Wrap(e, "first stroke1 error") + } + + fsa[l.FirstStroke1] = f1s + } else { + f1s = fsa[l.FirstStroke1] + } + + if fsa[l.FirstStroke2] == nil { + if f.config.Regular { + f2s, e = f.db.GetCharacters(Stoker(l.FirstStroke2, Regular())) + } else { + f2s, e = f.db.GetCharacters(Stoker(l.FirstStroke2)) + } + + if e != nil { + return Wrap(e, "first stoke2 error") + } + + fsa[l.FirstStroke2] = f2s + } else { + f2s = fsa[l.FirstStroke2] + } + + for _, f1 := range f1s { + if len(f1.PinYin) == 0 { + continue + } + for _, f2 := range f2s { + if len(f2.PinYin) == 0 { + continue + } + n := createName(f, f1, f2) + n.baZi = bazi + name <- n + } + } + } + return nil +} + +func filterSex(lucky *WuGeLucky) bool { + return lucky.ZongSex == true +} + +func isLucky(s string) bool { + if strings.Compare(s, "吉") == 0 || strings.Compare(s, "半吉") == 0 { + return true + } + return false +} + +func hardFilter(lucky *WuGeLucky) bool { + if !isLucky(GetDaYan(lucky.DiGe).Lucky) || + !isLucky(GetDaYan(lucky.RenGe).Lucky) || + !isLucky(GetDaYan(lucky.WaiGe).Lucky) || + !isLucky(GetDaYan(lucky.ZongGe).Lucky) { + return true + } + return false +} diff --git a/fate_test.go b/fate_test.go new file mode 100644 index 00000000..b3ddf917 --- /dev/null +++ b/fate_test.go @@ -0,0 +1,93 @@ +package fate_test + +import ( + "context" + "testing" + + "github.com/godcong/chronos" + + "github.com/babyname/fate" + "github.com/babyname/fate/config" +) + +func init() { + // trait.NewZapFileSugar("fate.log") +} + +func TestFate_RunMakeName(t *testing.T) { + born := chronos.New("2020/02/06 15:45").Solar().Time() + last := "张" + cfg := config.DefaultConfig() + cfg.BaguaFilter = true + cfg.ZodiacFilter = true + cfg.SupplyFilter = true + cfg.HardFilter = true + cfg.StrokeMin = 3 + cfg.StrokeMax = 24 + cfg.Regular = true + cfg.RunInit = false + cfg.FileOutput = config.FileOutput{ + OutputMode: config.OutputModeLog, + Path: "name.log", + } + cfg.Database = config.Database{ + Host: "localhost", + Port: "3306", + User: "root", + Pwd: "111111", + Name: "fate", + MaxIdleCon: 0, + MaxOpenCon: 0, + Driver: "mysql", + File: "", + Dsn: "", + ShowSQL: false, + ShowExecTime: false, + } + f := fate.NewFate(last, born, fate.ConfigOption(cfg), fate.SexOption(fate.SexGirl)) + + // f.SetDB(eng) + e := f.MakeName(context.Background()) + if e != nil { + t.Fatal(e) + } +} + +func TestFate_RunMakeNameWithLocalDatabase(t *testing.T) { + born := chronos.New("2020/02/06 15:45").Solar().Time() + last := "张" + cfg := config.DefaultConfig() + cfg.BaguaFilter = true + cfg.ZodiacFilter = true + cfg.SupplyFilter = true + cfg.HardFilter = true + cfg.StrokeMin = 3 + cfg.StrokeMax = 24 + cfg.Regular = true + cfg.RunInit = false + cfg.FileOutput = config.FileOutput{ + OutputMode: config.OutputModelJSON, + Path: "name.log", + } + cfg.Database = config.Database{ + Host: "localhost", + Port: "3306", + User: "root", + Pwd: "111111", + Name: "fate", + MaxIdleCon: 0, + MaxOpenCon: 0, + Driver: "sqlite3", + File: "", + Dsn: "", + ShowSQL: false, + ShowExecTime: false, + } + f := fate.NewFate(last, born, fate.ConfigOption(cfg), fate.SexOption(fate.SexGirl)) + + // f.SetDB(eng) + e := f.MakeName(context.Background()) + if e != nil { + t.Fatal(e) + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..2148ae9b --- /dev/null +++ b/go.mod @@ -0,0 +1,17 @@ +module github.com/babyname/fate + +require ( + github.com/go-sql-driver/mysql v1.7.1 + github.com/godcong/chronos v1.0.0 + github.com/godcong/yi v1.0.2 + github.com/goextension/log v0.0.2 + github.com/google/uuid v1.3.0 + github.com/mattn/go-sqlite3 v1.14.17 + github.com/rakyll/statik v0.1.6 + github.com/spf13/cobra v1.7.0 + github.com/xormsharp/builder v0.3.8 + github.com/xormsharp/xorm v1.0.4 + go.uber.org/zap v1.24.0 +) + +go 1.16 diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..26062443 --- /dev/null +++ b/go.sum @@ -0,0 +1,144 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= +github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= +github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/godcong/chronos v1.0.0 h1:eAlFcfWsldEPfplQxO7+UqkcWVvE0Fi1SeIkZvG/43A= +github.com/godcong/chronos v1.0.0/go.mod h1:4OsnZGNIqlutzCmguDKhDcM4Vk9E4IU1FgIW+LJer3o= +github.com/godcong/yi v1.0.2 h1:WdaiL78ftYir3f1ITbmJDQR8MR8LDb0wVR2osWoSE9I= +github.com/godcong/yi v1.0.2/go.mod h1:Zml4Arf7CaGyf+VqWtvD2WsozNs6Vi0eyk6zXZbZpR8= +github.com/goextension/log v0.0.2 h1:/KMuT22zzIMHe4qD7rR8dnfXWSFAyp+10pTC4fWLztI= +github.com/goextension/log v0.0.2/go.mod h1:fz72q/d4Iw05nbRSbxgGkGNTne3jxrq2Td5ogfunZak= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= +github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= +github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rakyll/statik v0.1.6 h1:uICcfUXpgqtw2VopbIncslhAmE5hwc4g20TEyEENBNs= +github.com/rakyll/statik v0.1.6/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/xormsharp/builder v0.3.7/go.mod h1:uu4Je618Wz3Qgiu6J20jJQnwEKMLdnN78pV/fsMorgU= +github.com/xormsharp/builder v0.3.8 h1:i0SMthzm4IzbGOxBmI3E7XUE5lVq26aZNWA88Xa69zM= +github.com/xormsharp/builder v0.3.8/go.mod h1:uu4Je618Wz3Qgiu6J20jJQnwEKMLdnN78pV/fsMorgU= +github.com/xormsharp/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:Kq+iDJoMwJOlEhVjPXG6LPtwI9CTcU5mRnJ7U/pO/Yg= +github.com/xormsharp/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:QCBxYu0JaE9AxIva2NkyKAG5oUb9joj6MGehz1PJ1Xw= +github.com/xormsharp/xorm v1.0.4 h1:0t8r9qrgfgz8l+6RiBRsbLiycaIMliMwrpeprwRXA3c= +github.com/xormsharp/xorm v1.0.4/go.mod h1:0hDxtKDWAuaqpiEJpkiyloTzVWaUl9/TR+P031O69KY= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= diff --git a/god.go b/god.go new file mode 100644 index 00000000..4feb4d34 --- /dev/null +++ b/god.go @@ -0,0 +1,12 @@ +package fate + +// LikeUseGod ... +type LikeUseGod struct { + LikeGod string // 喜神 + UseGod string // 用神 + Gold string // 五行:金 + Wood string // 五行:木 + Water string // 五行:水 + Fire string // 五行:火 + Soil string // 五行:土 +} diff --git a/information.go b/information.go new file mode 100644 index 00000000..7100cbb3 --- /dev/null +++ b/information.go @@ -0,0 +1,279 @@ +package fate + +import ( + "bufio" + "encoding/csv" + "encoding/json" + "fmt" + "github.com/babyname/fate/config" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "os" +) + +// Information ... +type Information interface { + Group(b bool) + Write(names ...Name) error + Head(heads ...string) error + Finish() error +} + +type jsonInformation struct { + head []string + path string + file *os.File +} + +// Group ... +func (j *jsonInformation) Group(b bool) { + panic("implement me") +} + +type logInformation struct { + path string + sugar *zap.SugaredLogger + head []string +} + +// Group ... +func (l *logInformation) Group(b bool) { + panic("implement me") +} + +type csvInformation struct { + head []string + path string + file *os.File +} + +// Group ... +func (c *csvInformation) Group(b bool) { + panic("implement me") +} + +// Finish ... +func (l *logInformation) Finish() error { + return l.sugar.Sync() +} + +func initOutputWithConfig(output config.FileOutput) Information { + switch output.OutputMode { + //case config.OutputModelJSON: + // return jsonOutput(output.Path) + case config.OutputModeCSV: + return csvOutput(output.Path) + } + + return logOutput(output.Path) +} + +// Finish ... +func (j *jsonInformation) Finish() error { + return j.file.Close() +} + +// Write ... +func (j *jsonInformation) Write(names ...Name) error { + w := bufio.NewWriter(j.file) + for _, n := range names { + out := headNameJSONOutput(j.head, n, nil) + //output json + _, _ = w.Write(out) + _, _ = w.WriteString(",\n") + } + return w.Flush() + +} + +// Head ... +func (j *jsonInformation) Head(heads ...string) error { + j.head = heads + return nil +} + +func jsonOutput(path string) Information { + file, e := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_SYNC|os.O_RDWR, 0755) + if e != nil { + panic(fmt.Errorf("json output failed:%w", e)) + } + return &jsonInformation{ + path: path, + file: file, + } +} + +// Write ... +func (l *logInformation) Write(names ...Name) error { + for _, n := range names { + out := headNameOutput(l.head, n, func(s string) bool { + return s == "姓名" + }) + l.sugar.Infow(n.String(), out...) + } + return nil +} + +// Head ... +func (l *logInformation) Head(heads ...string) error { + l.head = heads + return nil +} +func logOutput(path string) Information { + if path == "" { + path = "stdout" + } + cfg := zap.NewProductionConfig() + + cfg.EncoderConfig = zapcore.EncoderConfig{ + MessageKey: "name", + LevelKey: "", + TimeKey: "", + NameKey: "", + CallerKey: "", + StacktraceKey: "", + LineEnding: "", + EncodeLevel: nil, + EncodeTime: nil, + EncodeDuration: nil, + EncodeCaller: nil, + EncodeName: nil, + } + cfg.OutputPaths = []string{ + path, + } + + cfg.DisableCaller = true + cfg.DisableStacktrace = true + + logger, e := cfg.Build( + zap.AddCaller(), + zap.AddCallerSkip(1), + ) + if e != nil { + panic(e) + } + return &logInformation{ + path: path, + sugar: logger.Sugar(), + } +} + +func csvOutput(path string) Information { + file, e := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_SYNC|os.O_RDWR, 0755) + if e != nil { + panic(fmt.Errorf("json output failed:%w", e)) + } + + return &csvInformation{ + path: path, + file: file, + } +} + +// Write ... +func (c *csvInformation) Write(names ...Name) error { + w := csv.NewWriter(c.file) + for _, n := range names { + out := nameOutputString(c.head, n) + _ = w.Write(out) + } + w.Flush() + return nil +} + +// Finish ... +func (c *csvInformation) Finish() error { + return c.file.Close() +} + +// Head ... +func (c *csvInformation) Head(heads ...string) (e error) { + c.head = heads + w := csv.NewWriter(c.file) + e = w.Write(heads) + if e != nil { + return e + } + w.Flush() + return nil +} + +func headNameOutput(heads []string, name Name, skip func(string) bool) (out []interface{}) { + for _, h := range heads { + if skip != nil && skip(h) { + continue + } + switch h { + case "姓名": + out = append(out, h, name.String()) + case "笔画": + out = append(out, h, name.Strokes()) + case "拼音": + out = append(out, h, name.PinYin()) + case "喜用神": + out = append(out, h, name.XiYongShen()) + case "八字", "生辰八字": + out = append(out, h, name.BaZi()) + } + } + return +} + +func headNameJSONOutput(heads []string, name Name, skip func(string) bool) (b []byte) { + out := make(map[string]string) + for _, h := range heads { + if skip != nil && skip(h) { + continue + } + switch h { + case "姓名": + out[h] = name.String() + case "笔画": + out[h] = name.Strokes() + case "拼音": + out[h] = name.PinYin() + case "喜用神": + out[h] = name.XiYongShen() + } + } + by, e := json.Marshal(out) + if e != nil { + return nil + } + return by +} + +func headNameOutputString(heads []string, name Name, skip func(string) bool) (out []string) { + for _, h := range heads { + if skip != nil && skip(h) { + continue + } + switch h { + case "姓名": + out = append(out, h, name.String()) + case "笔画": + out = append(out, h, name.Strokes()) + case "拼音": + out = append(out, h, name.PinYin()) + case "喜用神": + out = append(out, h, name.XiYongShen()) + } + } + return +} +func nameOutputString(heads []string, name Name) (out []string) { + for _, h := range heads { + switch h { + case "姓名": + out = append(out, name.String()) + case "笔画": + out = append(out, name.Strokes()) + case "拼音": + out = append(out, name.PinYin()) + case "喜用神": + out = append(out, name.XiYongShen()) + } + } + return +} diff --git a/iterator.go b/iterator.go new file mode 100644 index 00000000..9ee5e8d7 --- /dev/null +++ b/iterator.go @@ -0,0 +1,60 @@ +package fate + +// IteratorFunc ... +type IteratorFunc func(v interface{}) error + +type iterator struct { + data []interface{} + index int +} + +// newIterator ... +func newIterator() *iterator { + return &iterator{ + data: nil, + index: 0, + } +} + +// HasNext check next +func (i *iterator) HasNext() bool { + return i.index < len(i.data) +} + +// Next get next +func (i *iterator) Next() interface{} { + defer func() { + i.index++ + }() + if i.index < len(i.data) { + return i.data[i.index] + } + + return nil +} + +// Reset reset index +func (i *iterator) Reset() { + i.index = 0 +} + +// Add add radical +func (i *iterator) Add(v interface{}) { + i.data = append(i.data, v) +} + +// Size iterator data size +func (i *iterator) Size() int { + return len(i.data) +} + +// Iterator an default iterator +func (i *iterator) Iterator(f IteratorFunc) error { + i.Reset() + for i.HasNext() { + if err := f(i.Next()); err != nil { + return err + } + } + return nil +} diff --git a/log.go b/log.go new file mode 100644 index 00000000..f53047b7 --- /dev/null +++ b/log.go @@ -0,0 +1,9 @@ +package fate + +import ( + "github.com/goextension/log/zap" +) + +func init() { + zap.InitZapSugar() +} diff --git a/martial.go b/martial.go new file mode 100644 index 00000000..0446704a --- /dev/null +++ b/martial.go @@ -0,0 +1,11 @@ +package fate + +// Martial six martials +type Martial struct { + BiHua bool `bson:"bi_hua" json:"bi_hua"` // 笔画 + SanCai bool `bson:"san_cai" json:"san_cai"` // 三才 + BaZi bool `bson:"ba_zi" json:"ba_zi"` // 八字 + GuaXiang bool `bson:"gua_xiang" json:"gua_xiang"` // 卦象 + TianYun bool `bson:"tian_yun" json:"tian_yun"` // 天运 + ShengXiao bool `bson:"sheng_xiao" json:"sheng_xiao"` // 生肖 +} diff --git a/name.go b/name.go new file mode 100644 index 00000000..2f669cfa --- /dev/null +++ b/name.go @@ -0,0 +1,109 @@ +package fate + +import ( + "strconv" + "strings" + + "github.com/godcong/chronos" + "github.com/godcong/yi" +) + +// Name 姓名 +type Name struct { + FirstName []*Character // 名姓 + LastName []*Character + born *chronos.Calendar + baZi *BaZi + baGua *yi.Yi // 周易八卦 + zodiac *Zodiac + zodiacPoint int +} + +// String ... +func (n Name) String() string { + var s string + for _, l := range n.LastName { + s += l.Ch + } + for _, f := range n.FirstName { + s += f.Ch + } + return s +} + +// Strokes ... +func (n Name) Strokes() string { + var s []string + for _, l := range n.LastName { + s = append(s, strconv.Itoa(l.ScienceStroke)) + } + + for _, f := range n.FirstName { + s = append(s, strconv.Itoa(f.ScienceStroke)) + } + return strings.Join(s, ",") +} + +// PinYin ... +func (n Name) PinYin() string { + var s string + for _, l := range n.LastName { + s += "[" + strings.Join(l.PinYin, ",") + "]" + } + + for _, f := range n.FirstName { + s += "[" + strings.Join(f.PinYin, ",") + "]" + } + return s +} + +// WuXing ... +func (n Name) WuXing() string { + var s string + for _, l := range n.LastName { + s += l.WuXing + } + for _, f := range n.FirstName { + s += f.WuXing + } + return s +} + +// XiYongShen ... +func (n Name) XiYongShen() string { + return n.baZi.XiYongShen() +} + +func createName(impl *fateImpl, f1 *Character, f2 *Character) *Name { + lastSize := len(impl.lastChar) + last := make([]*Character, lastSize, lastSize) + copy(last, impl.lastChar) + ff1 := *f1 + ff2 := *f2 + first := []*Character{&ff1, &ff2} + + return &Name{ + FirstName: first, + LastName: last, + } +} + +// BaGua ... +func (n *Name) BaGua() *yi.Yi { + if n.baGua == nil { + lastSize := len(n.LastName) + shang := getStroke(n.LastName[0]) + if lastSize > 1 { + shang += getStroke(n.LastName[1]) + } + xia := getStroke(n.FirstName[0]) + getStroke(n.FirstName[1]) + n.baGua = yi.NumberQiGua(xia, shang, shang+xia) + } + + return n.baGua +} + +// BaZi ... +func (n Name) BaZi() string { + return n.baZi.String() +} diff --git a/name_stroke.go b/name_stroke.go new file mode 100644 index 00000000..5687d802 --- /dev/null +++ b/name_stroke.go @@ -0,0 +1,47 @@ +package fate + +// NameStroke ... +type NameStroke struct { + // ID bson.ObjectId `bson:"_id,omitempty"` + Last1 int `bson:"last_1"` + Last2 int `bson:"last_2"` + First1 int `bson:"first_1"` + First2 int `bson:"first_2"` +} + +type nameStroke struct { + *NameStroke + *SanCai + *WuGe +} + +// SanCaiWuGe ... +type SanCaiWuGe interface { +} + +// SanCaiWuGe 三才五格 +func (s *NameStroke) SanCaiWuGe() SanCaiWuGe { + l1, l2, f1, f2 := s.Last1, s.Last2, s.First1, s.First2 + wuGe := &WuGe{ + tianGe: tianGe(l1, l2, f1, f2), + renGe: renGe(l1, l2, f1, f2), + diGe: diGe(l1, l2, f1, f2), + waiGe: waiGe(l1, l2, f1, f2), + zongGe: zongGe(l1, l2, f1, f2), + } + + sanCai := &SanCai{ + tianCai: sanCaiAttr(wuGe.TianGe()), + tianCaiYinYang: yinYangAttr(wuGe.TianGe()), + renCai: sanCaiAttr(wuGe.RenGe()), + renCaiYinYang: yinYangAttr(wuGe.RenGe()), + diCai: sanCaiAttr(wuGe.DiGe()), + diCaiYingYang: yinYangAttr(wuGe.DiGe()), + } + + return &nameStroke{ + NameStroke: s, + SanCai: sanCai, + WuGe: wuGe, + } +} diff --git a/nayin.go b/nayin.go new file mode 100644 index 00000000..03259331 --- /dev/null +++ b/nayin.go @@ -0,0 +1,15 @@ +package fate + +import "github.com/godcong/chronos" + +// NaYin 纳音 +type NaYin struct { + calendar *chronos.Calendar +} + +// NewNaYin 创建纳音 +func NewNaYin(calendar *chronos.Calendar) *NaYin { + return &NaYin{ + calendar: calendar, + } +} diff --git a/regular/regular.go b/regular/regular.go new file mode 100644 index 00000000..d076e12b --- /dev/null +++ b/regular/regular.go @@ -0,0 +1,122 @@ +package regular + +import ( + "errors" + "fmt" + "strings" + + "github.com/babyname/fate" + "github.com/xormsharp/xorm" +) + +var regularList = map[int]string{ + 1: `一、乙`, + 2: `二、十、丁、厂、七、卜、人、入、八、九、几、儿、了、力、乃、刀、又`, + 3: `三、于、干、亏、士、工、土、才、寸、下、大、丈、与、万、上、小、口、巾、山、千、乞、川、亿、个、勺、久、凡、及、夕、丸、么、广、亡、门、义、之、尸、弓、己、已、子、卫、也、女、飞、刃、习、叉、马、乡`, + 4: `丰、王、井、开、夫、天、无、元、专、云、扎、艺、木、五、支、厅、不、太、犬、区、历、尤、友、匹、车、巨、牙、屯、比、互、切、瓦、止、少、日、中、冈、贝、内、水、见、午、牛、手、毛、气、升、长、仁、什、片、仆、化、仇、币、仍、仅、斤、爪、反、介、父、从、今、凶、分、乏、公、仓、月、氏、勿、欠、风、丹、匀、乌、凤、勾、文、六、方、火、为、斗、忆、订、计、户、认、心、尺、引、丑、巴、孔、队、办、以、允、予、劝、双、书、幻`, + 5: `玉、刊、示、末、未、击、打、巧、正、扑、扒、功、扔、去、甘、世、古、节、本、术、可、丙、左、厉、右、石、布、龙、平、灭、轧、东、卡、北、占、业、旧、帅、归、且、旦、目、叶、甲、申、叮、电、号、田、由、史、只、央、兄、叼、叫、另、叨、叹、四、生、失、禾、丘、付、仗、代、仙、们、仪、白、仔、他、斥、瓜、乎、丛、令、用、甩、印、乐、句、匆、册、犯、外、处、冬、鸟、务、包、饥、主、市、立、闪、兰、半、汁、汇、头、汉、宁、穴、它、讨、写、让、礼、训、必、议、讯、记、永、司、尼、民、出、辽、奶、奴、加、召、皮、边、发、孕、圣、对、台、矛、纠、母、幼、丝`, + 6: `式、刑、动、扛、寺、吉、扣、考、托、老、执、巩、圾、扩、扫、地、扬、场、耳、共、芒、亚、芝、朽、朴、机、权、过、臣、再、协、西、压、厌、在、有、百、存、而、页、匠、夸、夺、灰、达、列、死、成、夹、轨、邪、划、迈、毕、至、此、贞、师、尘、尖、劣、光、当、早、吐、吓、虫、曲、团、同、吊、吃、因、吸、吗、屿、帆、岁、回、岂、刚、则、肉、网、年、朱、先、丢、舌、竹、迁、乔、伟、传、乒、乓、休、伍、伏、优、伐、延、件、任、伤、价、份、华、仰、仿、伙、伪、自、血、向、似、后、行、舟、全、会、杀、合、兆、企、众、爷、伞、创、肌、朵、杂、危、旬、旨、负、各、名、多、争、色、壮、冲、冰、庄、庆、亦、刘、齐、交、次、衣、产、决、充、妄、闭、问、闯、羊、并、关、米、灯、州、汗、污、江、池、汤、忙、兴、宇、守、宅、字、安、讲、军、许、论、农、讽、设、访、寻、那、迅、尽、导、异、孙、阵、阳、收、阶、阴、防、奸、如、妇、好、她、妈、戏、羽、观、欢、买、红、纤、级、约、纪、驰、巡`, + 7: `寿、弄、麦、形、进、戒、吞、远、违、运、扶、抚、坛、技、坏、扰、拒、找、批、扯、址、走、抄、坝、贡、攻、赤、折、抓、扮、抢、孝、均、抛、投、坟、抗、坑、坊、抖、护、壳、志、扭、块、声、把、报、却、劫、芽、花、芹、芬、苍、芳、严、芦、劳、克、苏、杆、杠、杜、材、村、杏、极、李、杨、求、更、束、豆、两、丽、医、辰、励、否、还、歼、来、连、步、坚、旱、盯、呈、时、吴、助、县、里、呆、园、旷、围、呀、吨、足、邮、男、困、吵、串、员、听、吩、吹、呜、吧、吼、别、岗、帐、财、针、钉、告、我、乱、利、秃、秀、私、每、兵、估、体、何、但、伸、作、伯、伶、佣、低、你、住、位、伴、身、皂、佛、近、彻、役、返、余、希、坐、谷、妥、含、邻、岔、肝、肚、肠、龟、免、狂、犹、角、删、条、卵、岛、迎、饭、饮、系、言、冻、状、亩、况、床、库、疗、应、冷、这、序、辛、弃、冶、忘、闲、间、闷、判、灶、灿、弟、汪、沙、汽、沃、泛、沟、没、沈、沉、怀、忧、快、完、宋、宏、牢、究、穷、灾、良、证、启、评、补、初、社、识、诉、诊、词、译、君、灵、即、层、尿、尾、迟、局、改、张、忌、际、陆、阿、陈、阻、附、妙、妖、妨、努、忍、劲、鸡、驱、纯、纱、纳、纲、驳、纵、纷、纸、纹、纺、驴、纽`, + 8: `奉、玩、环、武、青、责、现、表、规、抹、拢、拔、拣、担、坦、押、抽、拐、拖、拍、者、顶、拆、拥、抵、拘、势、抱、垃、拉、拦、拌、幸、招、坡、披、拨、择、抬、其、取、苦、若、茂、苹、苗、英、范、直、茄、茎、茅、林、枝、杯、柜、析、板、松、枪、构、杰、述、枕、丧、或、画、卧、事、刺、枣、雨、卖、矿、码、厕、奔、奇、奋、态、欧、垄、妻、轰、顷、转、斩、轮、软、到、非、叔、肯、齿、些、虎、虏、肾、贤、尚、旺、具、果、味、昆、国、昌、畅、明、易、昂、典、固、忠、咐、呼、鸣、咏、呢、岸、岩、帖、罗、帜、岭、凯、败、贩、购、图、钓、制、知、垂、牧、物、乖、刮、秆、和、季、委、佳、侍、供、使、例、版、侄、侦、侧、凭、侨、佩、货、依、的、迫、质、欣、征、往、爬、彼、径、所、舍、金、命、斧、爸、采、受、乳、贪、念、贫、肤、肺、肢、肿、胀、朋、股、肥、服、胁、周、昏、鱼、兔、狐、忽、狗、备、饰、饱、饲、变、京、享、店、夜、庙、府、底、剂、郊、废、净、盲、放、刻、育、闸、闹、郑、券、卷、单、炒、炊、炕、炎、炉、沫、浅、法、泄、河、沾、泪、油、泊、沿、泡、注、泻、泳、泥、沸、波、泼、泽、治、怖、性、怕、怜、怪、学、宝、宗、定、宜、审、宙、官、空、帘、实、试、郎、诗、肩、房、诚、衬、衫、视、话、诞、询、该、详、建、肃、录、隶、居、届、刷、屈、弦、承、孟、孤、陕、降、限、妹、姑、姐、姓、始、驾、参、艰、线、练、组、细、驶、织、终、驻、驼、绍、经、贯`, + 9: `奏、春、帮、珍、玻、毒、型、挂、封、持、项、垮、挎、城、挠、政、赴、赵、挡、挺、括、拴、拾、挑、指、垫、挣、挤、拼、挖、按、挥、挪、某、甚、革、荐、巷、带、草、茧、茶、荒、茫、荡、荣、故、胡、南、药、标、枯、柄、栋、相、查、柏、柳、柱、柿、栏、树、要、咸、威、歪、研、砖、厘、厚、砌、砍、面、耐、耍、牵、残、殃、轻、鸦、皆、背、战、点、临、览、竖、省、削、尝、是、盼、眨、哄、显、哑、冒、映、星、昨、畏、趴、胃、贵、界、虹、虾、蚁、思、蚂、虽、品、咽、骂、哗、咱、响、哈、咬、咳、哪、炭、峡、罚、贱、贴、骨、钞、钟、钢、钥、钩、卸、缸、拜、看、矩、怎、牲、选、适、秒、香、种、秋、科、重、复、竿、段、便、俩、贷、顺、修、保、促、侮、俭、俗、俘、信、皇、泉、鬼、侵、追、俊、盾、待、律、很、须、叙、剑、逃、食、盆、胆、胜、胞、胖、脉、勉、狭、狮、独、狡、狱、狠、贸、怨、急、饶、蚀、饺、饼、弯、将、奖、哀、亭、亮、度、迹、庭、疮、疯、疫、疤、姿、亲、音、帝、施、闻、阀、阁、差、养、美、姜、叛、送、类、迷、前、首、逆、总、炼、炸、炮、烂、剃、洁、洪、洒、浇、浊、洞、测、洗、活、派、洽、染、济、洋、洲、浑、浓、津、恒、恢、恰、恼、恨、举、觉、宣、室、宫、宪、突、穿、窃、客、冠、语、扁、袄、祖、神、祝、误、诱、说、诵、垦、退、既、屋、昼、费、陡、眉、孩、除、险、院、娃、姥、姨、姻、娇、怒、架、贺、盈、勇、怠、柔、垒、绑、绒、结、绕、骄、绘、给、络、骆、绝、绞、统`, + 10: `耕、耗、艳、泰、珠、班、素、蚕、顽、盏、匪、捞、栽、捕、振、载、赶、起、盐、捎、捏、埋、捉、捆、捐、损、都、哲、逝、捡、换、挽、热、恐、壶、挨、耻、耽、恭、莲、莫、荷、获、晋、恶、真、框、桂、档、桐、株、桥、桃、格、校、核、样、根、索、哥、速、逗、栗、配、翅、辱、唇、夏、础、破、原、套、逐、烈、殊、顾、轿、较、顿、毙、致、柴、桌、虑、监、紧、党、晒、眠、晓、鸭、晃、晌、晕、蚊、哨、哭、恩、唤、啊、唉、罢、峰、圆、贼、贿、钱、钳、钻、铁、铃、铅、缺、氧、特、牺、造、乘、敌、秤、租、积、秧、秩、称、秘、透、笔、笑、笋、债、借、值、倚、倾、倒、倘、俱、倡、候、俯、倍、倦、健、臭、射、躬、息、徒、徐、舰、舱、般、航、途、拿、爹、爱、颂、翁、脆、脂、胸、胳、脏、胶、脑、狸、狼、逢、留、皱、饿、恋、桨、浆、衰、高、席、准、座、脊、症、病、疾、疼、疲、效、离、唐、资、凉、站、剖、竞、部、旁、旅、畜、阅、羞、瓶、拳、粉、料、益、兼、烤、烘、烦、烧、烛、烟、递、涛、浙、涝、酒、涉、消、浩、海、涂、浴、浮、流、润、浪、浸、涨、烫、涌、悟、悄、悔、悦、害、宽、家、宵、宴、宾、窄、容、宰、案、请、朗、诸、读、扇、袜、袖、袍、被、祥、课、谁、调、冤、谅、谈、谊、剥、恳、展、剧、屑、弱、陵、陶、陷、陪、娱、娘、通、能、难、预、桑、绢、绣、验、继`, + 11: `球、理、捧、堵、描、域、掩、捷、排、掉、堆、推、掀、授、教、掏、掠、培、接、控、探、据、掘、职、基、著、勒、黄、萌、萝、菌、菜、萄、菊、萍、菠、营、械、梦、梢、梅、检、梳、梯、桶、救、副、票、戚、爽、聋、袭、盛、雪、辅、辆、虚、雀、堂、常、匙、晨、睁、眯、眼、悬、野、啦、晚、啄、距、跃、略、蛇、累、唱、患、唯、崖、崭、崇、圈、铜、铲、银、甜、梨、犁、移、笨、笼、笛、符、第、敏、做、袋、悠、偿、偶、偷、您、售、停、偏、假、得、衔、盘、船、斜、盒、鸽、悉、欲、彩、领、脚、脖、脸、脱、象、够、猜、猪、猎、猫、猛、馅、馆、凑、减、毫、麻、痒、痕、廊、康、庸、鹿、盗、章、竟、商、族、旋、望、率、着、盖、粘、粗、粒、断、剪、兽、清、添、淋、淹、渠、渐、混、渔、淘、液、淡、深、婆、梁、渗、情、惜、惭、悼、惧、惕、惊、惨、惯、寇、寄、宿、窑、密、谋、谎、祸、谜、逮、敢、屠、弹、随、蛋、隆、隐、婚、婶、颈、绩、绪、续、骑、绳、维、绵、绸、绿`, + 12: `琴、斑、替、款、堪、搭、塔、越、趁、趋、超、提、堤、博、揭、喜、插、揪、搜、煮、援、裁、搁、搂、搅、握、揉、斯、期、欺、联、散、惹、葬、葛、董、葡、敬、葱、落、朝、辜、葵、棒、棋、植、森、椅、椒、棵、棍、棉、棚、棕、惠、惑、逼、厨、厦、硬、确、雁、殖、裂、雄、暂、雅、辈、悲、紫、辉、敞、赏、掌、晴、暑、最、量、喷、晶、喇、遇、喊、景、践、跌、跑、遗、蛙、蛛、蜓、喝、喂、喘、喉、幅、帽、赌、赔、黑、铸、铺、链、销、锁、锄、锅、锈、锋、锐、短、智、毯、鹅、剩、稍、程、稀、税、筐、等、筑、策、筛、筒、答、筋、筝、傲、傅、牌、堡、集、焦、傍、储、奥、街、惩、御、循、艇、舒、番、释、禽、腊、脾、腔、鲁、猾、猴、然、馋、装、蛮、就、痛、童、阔、善、羡、普、粪、尊、道、曾、焰、港、湖、渣、湿、温、渴、滑、湾、渡、游、滋、溉、愤、慌、惰、愧、愉、慨、割、寒、富、窜、窝、窗、遍、裕、裤、裙、谢、谣、谦、属、屡、强、粥、疏、隔、隙、絮、嫂、登、缎、缓、编、骗、缘`, + 13: `瑞、魂、肆、摄、摸、填、搏、塌、鼓、摆、携、搬、摇、搞、塘、摊、蒜、勤、鹊、蓝、墓、幕、蓬、蓄、蒙、蒸、献、禁、楚、想、槐、榆、楼、概、赖、酬、感、碍、碑、碎、碰、碗、碌、雷、零、雾、雹、输、督、龄、鉴、睛、睡、睬、鄙、愚、暖、盟、歇、暗、照、跨、跳、跪、路、跟、遣、蛾、蜂、嗓、置、罪、罩、错、锡、锣、锤、锦、键、锯、矮、辞、稠、愁、筹、签、简、毁、舅、鼠、催、傻、像、躲、微、愈、遥、腰、腥、腹、腾、腿、触、解、酱、痰、廉、新、韵、意、粮、数、煎、塑、慈、煤、煌、满、漠、源、滤、滥、滔、溪、溜、滚、滨、粱、滩、慎、誉、塞、谨、福、群、殿、辟、障、嫌、嫁、叠、缝、缠`, + 14: `静、碧、璃、墙、撇、嘉、摧、截、誓、境、摘、摔、聚、蔽、慕、暮、蔑、模、榴、榜、榨、歌、遭、酷、酿、酸、磁、愿、需、弊、裳、颗、嗽、蜻、蜡、蝇、蜘、赚、锹、锻、舞、稳、算、箩、管、僚、鼻、魄、貌、膜、膊、膀、鲜、疑、馒、裹、敲、豪、膏、遮、腐、瘦、辣、竭、端、旗、精、歉、熄、熔、漆、漂、漫、滴、演、漏、慢、寨、赛、察、蜜、谱、嫩、翠、熊、凳、骡、缩`, + 15: `慧、撕、撒、趣、趟、撑、播、撞、撤、增、聪、鞋、蕉、蔬、横、槽、樱、橡、飘、醋、醉、震、霉、瞒、题、暴、瞎、影、踢、踏、踩、踪、蝶、蝴、嘱、墨、镇、靠、稻、黎、稿、稼、箱、箭、篇、僵、躺、僻、德、艘、膝、膛、熟、摩、颜、毅、糊、遵、潜、潮、懂、额、慰、劈`, + 16: `操、燕、薯、薪、薄、颠、橘、整、融、醒、餐、嘴、蹄、器、赠、默、镜、赞、篮、邀、衡、膨、雕、磨、凝、辨、辩、糖、糕、燃、澡、激、懒、壁、避、缴`, + 17: `戴、擦、鞠、藏、霜、霞、瞧、蹈、螺、穗、繁、辫、赢、糟、糠、燥、臂、翼、骤`, + 18: `鞭、覆、蹦、镰、翻、鹰`, + 19: `警、攀、蹲、颤、瓣、爆、疆`, + 20: `壤、耀、躁、嚼、嚷、籍、魔、灌`, + 21: `蠢、霸、露`, + 22: `囊`, + 23: `罐`, +} + +type regular struct { + db fate.Database + total int + fixed int + unfixed int +} + +// Run ... +func (r *regular) Run() { + e := setAllRegular(r.db, false) + if e != nil { + panic(e) + } + for _, strVal := range regularList { + strVal = strings.TrimSpace(strVal) + strVal = strings.Trim(strVal, ` +`) + strVal = strings.Trim(strVal, "\n") + list := strings.Split(strVal, "、") + if len(list) == 0 { + continue + } + for _, ch := range list { + r.total++ + fmt.Printf("character %s is fixing\n", ch) + if fixRegular(r.db, ch) { + r.fixed++ + } else { + r.unfixed++ + } + } + } + fmt.Printf("fix regular finished(total:%d,fixed:%d,unfixed:%d)\n", r.total, r.fixed, r.unfixed) +} + +// Regular ... +type Regular interface { + Run() +} + +// New ... +func New(database fate.Database) Regular { + return ®ular{ + db: database, + } +} + +func setAllRegular(db fate.Database, regular bool) (e error) { + engine, b := db.Database().(*xorm.Engine) + if !b { + return errors.New("wrong type") + } + if !regular { + _, e = engine.Exec("UPDATE `character` set regular = 0") + } else { + _, e = engine.Exec("UPDATE `character` set regular = 1") + } + if e != nil { + return e + } + return nil +} + +func fixRegular(db fate.Database, ch string) bool { + char, err := db.GetCharacter(fate.Char(ch)) + if err != nil { + fmt.Printf("failed get char(%s) with error (%v)\n", ch, err) + return false + } + char.Regular = true + engine, b := db.Database().(*xorm.Engine) + if !b { + fmt.Println("failed to engine") + return false + } + update, e := engine.Where("hash = ?", char.Hash).UseBool("regular").Update(char) + if e != nil { + fmt.Printf("failed update char(%s) with error (%v)\n", ch, e) + return false + } + if update == 0 { + return false + } + return true +} diff --git a/regular/regular_test.go b/regular/regular_test.go new file mode 100644 index 00000000..d3a42884 --- /dev/null +++ b/regular/regular_test.go @@ -0,0 +1,15 @@ +package regular + +import ( + "github.com/babyname/fate" + "github.com/babyname/fate/config" + "testing" +) + +// TestNew ... +func TestNew(t *testing.T) { + c := config.LoadConfig() + db := fate.InitDatabaseWithConfig(*c) + regular := New(db) + regular.Run() +} diff --git a/sancai.go b/sancai.go new file mode 100644 index 00000000..e9247aff --- /dev/null +++ b/sancai.go @@ -0,0 +1,49 @@ +package fate + +import "github.com/xormsharp/xorm" + +const sanCai = "水木木火火土土金金水" +const yinYang = "阴阳" + +// SanCai ... +type SanCai struct { + tianCai string `bson:"tian_cai"` + tianCaiYinYang string `bson:"tian_cai_yin_yang"` + renCai string `bson:"ren_cai"` + renCaiYinYang string `bson:"ren_cai_yin_yang"` + diCai string `bson:"di_cai"` + diCaiYingYang string `bson:"di_cai_ying_yang"` + fortune string `bson:"fortune"` // 吉凶 + comment string `bson:"comment"` // 说明 +} + +// NewSanCai 新建一个三才对象 +func NewSanCai(tian, ren, di int) *SanCai { + return &SanCai{ + tianCai: sanCaiAttr(tian), + tianCaiYinYang: yinYangAttr(tian), + renCai: sanCaiAttr(ren), + renCaiYinYang: yinYangAttr(ren), + diCai: sanCaiAttr(di), + diCaiYingYang: yinYangAttr(di), + } +} + +// Check 检查三才属性 +func Check(engine *xorm.Engine, cai *SanCai, point int) bool { + wx := FindWuXing(engine, cai.tianCai, cai.renCai, cai.diCai) + if wx.Luck.Point() >= point { + return true + } + return false +} + +// GenerateThreeTalent 计算字符的三才属性 +// 1-2木:1为阳木,2为阴木 3-4火:3为阳火,4为阴火 5-6土:5为阳土,6为阴土 7-8金:7为阳金,8为阴金 9-10水:9为阳水,10为阴水 +func sanCaiAttr(i int) string { + return string([]rune(sanCai)[i%10]) +} + +func yinYangAttr(i int) string { + return string([]rune(yinYang)[i%2]) +} diff --git a/statik/statik.go b/statik/statik.go new file mode 100644 index 00000000..a14141ea --- /dev/null +++ b/statik/statik.go @@ -0,0 +1,13 @@ +// Code generated by statik. DO NOT EDIT. + +// Package statik contains static assets. +package statik + +import ( + "github.com/rakyll/statik/fs" +) + +func init() { + data := "PK\x03\x04\x14\x00\x08\x00\x08\x00\xe5DeO\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00 \x00dayan.dataUT\x05\x00\x01/5\xc1]\x00g\x0e\x98\xf1x\x9c\x9cZ[\x8f\xe2X\x92\xfe/\xf9\xdc\x0f\xd3u\xed\xee\xd7}\xdd\x9d\x97}\\\xed\xc3\xec\xaaVZ\xcd\xf6\xac4;-\xedh\xb5\x12\x86\x04c\x8c\xb1\xc9\xca\xc4`C\x92db.I&\x97\x84\x04c\xc0\xfe1\xed8\x97\xa7\xfa\x0b\xa3s\x0eMb\x9b\xe9\xac\xb6TBe\x07*\xbe\x8a\x88\xf3\xc5\x17\x11\xe7_\xfe\xef\xec\xf7?\xfd\xf8o\x9f\xfe|\xf6\xc3\xb7\xdf\x9c\xfd\xe3O\xff\xfe\xc7\xbf\x9e\xfdp\x06\x86r\xf6\xcd\xd9?\xfd\xe1\x7f\xcf~\xf8\x8f?\xfc\xd7\xff|\xfa\xe6\xec\x9f?\x1d\xfd\xfd\x8f\x7f\xfd\xfd\x7f\xfe\xe9\x13\xfb^\xf7\x1e]K\xe1ZEW\xd3\xb3o\xce\xfe\xe1\xbf\x7f\xfc\xf1\xd3\x9f\xfe\x123|\xd9\x96CW\xc6\xca\x10\xb6\x194g\x8f\xf8\xb2\x0dz\x15\x997x\xb8\xfa\xb2-Cq\x88{\xe7\xa17\xa0\x19\xeb\xe7L\xf6\xec\xff\xbfy\x01\xf5\xe6\x08\x94\xbc\xfc*P\xa1\xdb\x0d7\xf7'@\x1d\x1b\xbel\xcbh\xb5BOe\xd4\xbc\x87m\xe6\xcb\xb6L\x02\x9bf2a\xd0\x82q\x91\x81\nL\xd4\xb4\xa9\xe5\x13\xdf\x8f\x83z\xfb\xdb=\x15\xba\nR\xb4\x93\xa0^\x0c\xecg\xbbChNC\xcf\x83\x8b2\x7f\xec\x87\x9e\xca>]\x8b9n-\x11\xed\x0e\xd5\xcb\xd4*\xc4A\xbd\xfb\xed\x9e\x02\xdb&\xb3\xce\xa9\xf0\x1d\x19\x18\n?\x1fz\x15\x115\x11\xcd\xd0SQ\xbeBe\x8d?j\x90_\x11\xc3!S5\x0e\xea}\nOy\x97\xa4S>\xe5)a\x08f\xa8\x95\xe3\xa0\xeeqe\x82m\x17_\xb6\xd9c\xb3@3\x16\xbe\xca\x13\xdfg\x9e\xea\xe9\xd8QD\x8a\xc5A}H\x91\xe8\xf9G\\\xdc\x9c\xf2\xd4\x91\x81\xa1\xd0\xab0\xbb\x02\xbd\x0e\xe5\x9a\x88&yV\xb1_\x01\x9f'\xba\xa1`\xc7\x81\xb1\x82\xe6\xd38\xa8\x8fir*\x87.\x83\x939\xf5b`\xbex\xf2QV\x0b]\x87L\x07\x07P\xe1Z\x85\x92-@\xa1z\x1b\xe7\xfb$\x93\x89\x83\xfa\xee\x08\x94V\xfazg\x8d@\xeb\x9dt\xd6\x8b\x81%\xce\xda\x87V\x85(c\xda\x94\x19\x90\xd5\x0e\xf76\xd0\xeaB\x9ee\x99\x88\x1d2o`\xba\x8b\xe3\xfa>E\xaew\xfb\xa8h\x9c\xa4\xaa\x17\x03\xa3\x81\xab\x05Z>\x83\xbc\xa4\x8d!CQ\xac\xa1\xa2\x81\x8a5\xb2p\xbel\xcb\xd4\xf2\xc3\x8d\x83J%\xa4w\xe2\xa0\xbe\xfd\xddoG\x857E\xbc\xf9|\x02\xd5\xb1\x81\xfd\xae}\x8f,\x93\xde\xd5\xa9\xbdd\xae\x92\x96\x0cXSAE\x83=\xda\xd7\xb4\xe3\x93\xf2\x08\x9f/\x13\xa8R\xd0:2gD5i\xe6\x96\xda\x83Xb1\x1eG\xf6\x02\xd5\xb8\xaf\xa69\xda\xf1@\xaf\x8a3\x87\xa4[\xd8\xd6\xd1|\x17\xba\xb5\x03Y\xc1\xa4L\x16\xcf T)x\x1dU\xea\xa1w\x85\xcc\x1b4W\"\xa8X\xa6\x18\x85\xd8\x19$\xb5s\xd8\xce\x18\xc8\xc6\x0e_\xb6CW#\xcb\xb9\x88 \xcd?@`\x82QM\xa0JA\xec\xa8\xee \xd3\xc1J't\xd7QT\x8aF\x14\x0f\xba\x16\xc9\xed\x98s\x1a\x1e\x99\xaa\xe0\xc8\xf8\xca\xe1\xe5EC\xedK\xd8}\x0e=\x95\xa1r\xef\xc0\xd1\xa1\xdb\x87R;\x81*\x05\xb3\xe3\x9b\x05\xe4\x0b\xd1<\x1f/\xc1{\xc4\xdb:\xa9\x9d3\x00\x8f]\xac>P\xe9\x91Z>\x0f\xa5\x1az*\xf3\x92\x08e\xf6 \xe5\x06\xa1\xab\xa1\xe7\x04\xa7\x7f\x9b\x82\xd4qO\x87I\x10\xcdp\xfe\n\x9a\x05\xb4\xe90<\xa6c\xcd\xa2\x05[/\x9aB\xad\x1c\x0c$a`\x07\xea^\xc27\x8b\xd0\x95E\xc8\xa0\x97%\xb9\x1d\x8c\xd7\x10h<\xa3\xf2\xa4\xb2b\xa8N\xa4P:\"\xa7\x9f%z\xd5\xa4\xb2\x86\xef\x06'\x80\xa1\xba/\xb2\x054\x0b|\x93y\xa38\xe4\x82\xe0\x12\xf2\x1b\x96\xde\xc2\x93\xbf\xe6\xabTLnQ\xcb\x8f\xe0\xa1w\x95\xd0\xab\x92\xcb\x1d2\xd9\xe1\"\xbeM\xd4\x1e\x955\xd4r\x04\x030\xaa\xe4\x07\xf0E\xbe\x94G\xa8TO\xc8\xcd\x14\x1c\x0e35tUb\xeaT\xaeFQ\xb5\xaeC\xd7\xc27\x0b\x120\x96\xc6\x92\xcf\xc8G\xd6\x84l\x12z\x13o\x16d\xba:\xa0\xa2\x96\x8f\x8aF\x02\xd5\xeb\x1c\xfe\x97?\xff\x14\xa3\xa5\nj\x16C\xf7\x11\xba\xc3X\x0dV\xe8]\x856%\xd4,\x1e\x949\xee\x8c\xf1H\xe5Y_'\x81!\xa4\xb8\x90\x9f\xc8\xd0E`\x7f\xced\xc1\x99\xa3L\x9f\xe9\xbdq\x13=v\xd1UB\xc5\xbcI\xc1\xeb\xb8\xaf\x12Ma\xd5\xa6\xd9\x8c2\xc4\x91\x81W\xb9)\xb5|\\\xf3\x0f\xbc\x0e\xb2Gf\xf7\xa8\xc5\xc5\x84\xe7\xe1\xcb6\x9a\xdf\x9e\x8a\xea\xeb\xbc\x1e\xf7\x1f\xdc\x8dCw\x17+3\x8f\xc8tB\xb7 \x1a\x97+\xfc\x1bp7&\xfd,#,q$L\x0f\xdb\xb6Hz04Fg\xbc}\xf8\n\xcf\xbdKQ{*ub\xea\xe0\x9b\xf1\xcc\x83\xf1\x92\x9a\x83p\xd7\x00\xaf\xc0\xaa\x8b\\\xa5\x17\xb3\xd0\x9db\x9b\xc5\x1c7vHQ\xd9\x99\x1c/\x05\xb5!\xcf\x80u@\x02;\x81\xea}*\xe2 \xda]\x18\x94\"\x90\xc8\xf39\xca\xf4\x89:CW\x8c\xd0Yu\xcc\xedX9T\xd6\xcc]y\x1555\xc8>\xa1\xfc-{\x9cZ\xa0ONs\xd9\x9b\x0f)\x8e\xa8^G\x99\xfb\xa8\x8b\xf8\xabp\xad\x92)K.\xa2\xce\xa8}~\xc8&\x96G>c>\xd0o\x985S\xfe\xbb\xe5\xf9\xcd\xc7\x14xn\xaf\xe9U\xb4\x1c\xa2\x87'\xd4\xb4\x99\xbayd\x1e \xf2=*Va\xeb\xe1\x1c\xefF\xbb\x16\xe8&\x9aHd\xda}\xcd?\xdf\xbd\x8a'\x9e\xec\xb4~\x89\xa6\x0b\xf4<&F\xb4&\ny\xf0\xa2\x8d\xb9{\xd0\xf4\x12\xf5\xb2\xfc@\xda\xe8y\x85\xb6Y4/\xb1\xb4\xda\x14C\xb7\xc6\xfe\x15O\xfa\xba\x94\xff>E\xcas\x16\x8fz\x8e\xbf\n\xb7u\xdc\xcf\xec+u\xc9\x86\xdd\x05\xb5\x0b\xbc\xbd\xd1\xa8\xb9A\xcf+(\xe4\xb9\x9e7`:\x13\x0du\xa2\xad\xff]\xba*\xd9\xba&\x81\x11\x85\xf4\xa4\xa0\xe71\xff\xbfs\x1a\x95\x97`(\xd4\xf2A\xaf\xf3\\sP\xbd\xc2>-sO\xb2E\x03\xba}\xb2p\x12\x90\xd2\xa8w\xaeHIi\x06\xdbL\xdcQ\xa0\xca\xacR\x07f\xb2j\xe3M\x9b\xde\x16\xc2\xad\x19z\xde+\xea\xfd\xed\x9b\x14\x8ak\xdc\xa2\xc3\x07\xc6D\xd7\xd1\x1c\x0b}\x07\xd6.t-\xd4\xb4y\xf8\x9eC\xcfc\xc0J\xc3}4]\x9bI\x9d\xbb\xab\x03*\"\xcfC\xb7\x94@\xf5\xdbY^P:hr\xbcJ\x1e\x1b\xb8<\xf7A\xeeb\xdb\x0d\xb7\xd6!\xa7\xa0;\x0c].\xde\xad\x02\xaa\x97\x89d\xb7\x83q\x0b=)\xa4\xd8f0\x8e\xbe'\x94\x16\x13a\xd3\x16Lw\xe2\x91\x15\x9f\x93\xa4\xf5.\x0d\xc7g\xd7\xb8=gT\x1aG\xc5\xb5\x18+\xd4\x9c\x93D\xab\x7f\x08\x16v&\xd8q\xc0PD\xb3&\xc6\xf3\xb0vqOO\xa0\xfa.\x85\xf0\xd2\xbb\xa8\xe5\xe3\x91J\xd7\xdd\x13\xbc\x05\xf9-t\xe5=Q\xc8\xba\xe8X\xd9\xe3@b\xc5\xbdh\x80\xcbi\x95\x97h&R\xfb\xd9\x04\xaat\x04Ov\x0f\xa0\xd7\xa3T`(\xa1\xbb\x80b\x03\x0cE\xe8f\xd4r\xd8\xa3\xcc\x1b\xd5\xdd\x03\xc8\xcb\xd0\xf5\x84\x95\xe65pvb\x7f\x96\xd8;\xa5\x93\xf20\xd5I\xb1\x0dy\x07=\xafb\x83\xef\x0c\xd3\x02nF\xac\x01X\xb0\xe4%\xe8Y\xd0J\xbc{-2\x16\xf5d\xa2\x8d\xb8\xb5B\xa5G\x90\xcfQn\x90\x00\xf6m:Q\xc3\xabH\x94\x10l\x9bt\xa6\xa1\xd7\x85\xd2M\xb2c\x15\xb4\x89\xf2\x15\xe8\xab\xaf\x0c\x07\xdf\xa7P\xf3\xc4\xf7qs\x1b\xa3\xf1\xcfdR\x10\x06\xe1\x13\xd2\xe7\x1b\xe0z\xe5@\x08d\x99\xc7~W(h(\x0eA/\xa3\xcb\xc4\xc6\xe2}\x1a\x1a\xb7\x9f@[Q\xcbG\xf5vl\xbbSc\x87\xab\x90G\xd9;~\xb8j\xd8q\xa1\x90\x87\xb1\xb2\x0f\xdc\x84\xc5\x8b,F{\xcc\x8b\x11\x18\x95\x13\xf2\xea}\x1a\x1ao\xb3>\x05\xdd\xecHi\x16\x8d\xdd\x91A\xec$\xc07\x19\x11-6'\x9d2)\xc6\xc2W)\xc0tG\x94)\xf1m1q\x80\xea\x80ZM|\xab\xbd\xccL\xfd\x1c\xf5\xf9\xb2\\\xb2\xfe\xee\x08\xf5}\n>G\xa6\x83\xf3}\xd6N\xb7\xfc\x98\x02\xbd\xa0\xf6=m]\xa0\x16\xa7\xcan\x93T<0\xda\xa8.V;y*=2\xae\x08\xe4C\xcb\x8a\x1b\xbb\xd0K\xae\xc7\xd3iv\xd4\xb0H\xa7L%9\xd1{q\x9a\x80\xae\x85G\x93}>\xab=0*\xf8\x92\x0fP\xc7;\x18\xeb\xacF\x1b\xda+E\xf9}\x9a\xb9<\x17x(\xfb\x14\x97\n\xc7\x06\x96Z\xa2\xb1\xe8Li\x86 T\xbc\xf5\xc2\xb5\x0e\x81F2\x06\x1f\x8e\xf4\xa8\xe5\x87\xae\x16n\x13\xfb\xb9\x0f)\x04;2o\x12\x03#\xfe*\\\xabb\xd2!\x06X\x07\x85\x8e\x1a=d\xb5\x90e\xd2\x0d\xd7\x0c\xa5\x01\xaa\xca\xdc\x9a\x10\xec\x1fRLg\xc4\xa6\x90\x94\x1a\xe4s\xb4\x8d860?p\xcd b\x14#L\x1eJ+\xf4FB*$P\xa5\x10\xe7\xa43%\x0b'*Z\xf8\xab\x83ha\x9c\xd9\xad1?\x88\x8b)G\xd7c\x0e\xd3\x05z[E\xad\xc4\x0c\xebC\x8a\xad*\xab\xc2\xbb\x0bX\xcf\xe3\x858\xde\xfcy#\x08r\xe2F\x05_\x93\x0fh\xf3 \xe5n\xd0|w\xe0\x87\xd3\x17\x8b>\xa4\xe0s\xda\xba\x86jt)@\xef\x07$\xab@\xb1\x80{\x9b\xc3V\x15e\x9f\xd0\xb9t v\x81\xf0@P\xa1\xab\x9d \xa8\x0f)d9\xac\x06\xe8Y\x82\xddE\xc2K\xdd!\xbd\n\xa09\x0d\xd7\xbc\x87\x1a/I`\x881\x95\xb8\x1b\x03\x93\x00o\x9e\xe9U\xb0\xef\x1d\xd9x~LyQ\xe6\x97\xaf\xc6\xef6\xb1\x06*\xdb\xe3SM\xf6\x0d\xf6)\xe6\x06\xb9\x1dk~\xf5\x05*\xb1\xde\x936V\xc4\xd81\x84\xebdn\xbf\xbe<=\xa9\xc6cg\x0d;.+\xb2\xc7\xf3\x81\xee\x90QzN\xc8\x92GX/^\xae\xcd ^\xb2\xa7\xa7\xd82\x05{\x87^\x95\xd5\xdf\xe4f\xe6\xd8 \xb4\x13\xae=A\xc9\x16\xd30<\\\x91`\xc4\x85\xb7{`x\xa1\x8a\x13\xd7B\xd3\x0c\xce%)\x1e5qvDc\xcbSw\x08y\x87Z\x06\x95\xa4\xfd\x05\xac \x87G*T\xf9\xb0\xae\\\x03yIv\x0f`$\x8e\xffw)t\xf8\xfeJ\xba}\x8d\xeaQ\xdd\x8b\x9a\x190\x94\x97\x9dwPG\xcd\x07&F\xf3\xb9\xc3\x15\xde\x971\x0b\xd7\x03\xe2\x96\x18G\xf5\xaf\x7f\x03\x00\x00\xff\xff\x01\x00\x00\xff\xff\xecC\xf9\x0c\x01\x00\x00\xff\xffPK\x07\x08eCc q\x0e\x00\x00g\x0e\x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\xb7\x80fO\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00 \x00gua.dataUT\x05\x00\x01Z\xef\xc2]\x00\x8f!p\xdex\x9c\xac}Ko\xea\xda\xb6\xe6_)\xa5\xbdK\xaa\xfb\x96N\xb7TuK%U\xeb4\xee\xd9\xcd\xdd(\x9d\xb3:\xfbJ%\xad\xd6\xd5\x950\xc4\xb1\xcd\xc3@Bp\x08\x90\x84\xf0\nIxx\xc1\x02c\xb0\xf91\xcbcz\xba\xb5\xfeBi\xcei\x8cyz\x82wo-\xc2\xc4\xaf\xcf\xe3\xf1\x8do\x8c\xf9\x1fW\xce\xdcv\xe6\xf6\xd5\x9f\xfe\xe3\xea\xcf\x7f\xfb\xed\xf7\xbf\xfe\xeb\xd7\xdf\xae\xfeD?4Lh\xf5\xae~a\x1f\xff\xf9o_\xaf\xfe\xf4\xdf~\xb9\xfa\xcb\x97\xdf\xf6\xbf\xf1\x97/\xbf\xad\xff\xfe\xbf\xbf\xfc\xe5\xcb\xbf\xff\xfe\xd7\xab?]AA\xb9\xfa\xe5\xea_\xbf\xfe\xf6\x97/\xbf\xd1\x0f\xc8Q\xe8\x07\xff\xe7\xcb\xfa\xff\xc1/\xfc\xeb\xd7\xdf~\xfdB\x16\x89)\xc7|\xfb\xb9\xcc\x82\xdc\xc3\x93'\xff/_\x7f'\x7fju\xe1Nq\xe66\x88\xa9\x9f\xcb\xaccH\xae\xd2\xc3\xdf\xaf\xa1\x9b!\xff\x9d\xa7\xdc\xc53\xb4z?\x12I\xc7,\xe2F\xd6\xab\xbe\xa1\xb2E~\xeaNp\x95\x1e\xfa.\x80\xf5\xfa#\x91\x84V\x17=\xa8\xd0\xcd\xb8\x0b\x99\xfcU\xec;V\x0eiS$\x17~.\xb3H\x9b:\xf3\x07\x10\xfb\x9e]q\x16m\xb0\x1b\xfeo\xcemO\xb8\x83\xfc\x03d\xcbdU\xe1\x1a\xf5\x9b(\xd1\x85\"9\x84\xb3\xaaCA&gx\x9be'\xc3\xce\xffG\"\xe9u\xca \x99`N]\xa5\xc7N\x1b\xaa\x16\xdc\x1a0\x10\xd8\x9d\xfb\xfd\xaf\xbf~\xfd\xbf\xf4\xfaz\xb8\x91\x05\xa1M\x7f\xbe\n\xfd\x82\xb3hc\xe9\x1d\x96\xa6c\xe4\x900\xbc\xfa\xe5\xea\x7f~\xfd_\xbf\xfd;\xb9u\xb3\xc4\xd5/W\xff\xfdo_\x7f\xa5\xffEV\xcd\xb3+\x90Y\xb9%r\xef\xbc\x871\xd4\xde\x1c#\xe3\xcc\x9f\x83\xaf\x85\x1e\xcc||\xf5\xcb\xd5\xff\xf8\x7fl-\xee\ndm\xed\xcd-\x8d\xc8\x91\xed\x19*[\xa82`k\xe9\xb7v\x9f\xe9\x9f\x7f\xfb\x9d\xadu\x172\xd2\xda\x0c@dm>\x07\xad\x9c'\xdc\xb1\xb5\xeck\xbb\xc7\xfd\xf3\x17\xff\x9c\xe52\x9e\xa5\xa0\xf6\x86\x8c\xf4\xcfe\x16\xaf\xaaH{\x81[\xd5_\xfb\xe5\xc0\xd2\x7f\xf3/\xd7k>\xb1S\x86\x16\xb9\xa5\xd0\xea:\xa6\xe9%^\xd8\xd2\x7f\xfbz\xe8\x94 \x86\xd9j\xc7|\xf5\xec\n\xaa)(Y\xfa\xb9\xcc\xbaU\xd91r\x90\x1f:s\xd1?\xb6\xff\xdd\xdd\xc3\xff\xea\xff\xa7\xd5\x03{\xe6\xaf1L\xafSf\xcb\xc8\x9f7K\xfe\xeb\xd5\x7f\xferE\xc1Z<\xfb\xd5\x02\xb1\xe8\x18&\x1a[\xa1W\xeb\xef\xc2\xaf\xd6\xf6{\x05z{\xeb\xbd\x82V\x0f\x8d\xad\xe0S\xfa^\x85_\xa4m\xd8\x85P\x15\x86\x94;y\x01\xbd\xed\xcc3`'\xc8]\xca|\xe2F\x16]\xafx \x05s\xcb1M\xbd\x0c\x9c\xc4\x1e\x8e\x0c\xa4$\x1c\x93\xd8~ff\x16\xf1\xd5M5\x84\x99\x7f<\x81\x99nk\x173^S\x0d>\xbd\xd0\xa5\x8e\x17\x8e\xa9zR\x11=\x8b\xe4]~.y\xc2\x9d\xab|\xe7\xc2LVD5\xc5\xd3\x974\xbaT\xa8\xb9K\xc3\xc0\xe6\x02\x8c8%\xbe\xfb\xb3\xe1\x18$\xe0!\xff\xae\xbd\x07\xc7\x8d\x80\x8d\xf6\xe2\xe9\xcb\xc0\x93\xe2U\x0d\x8d\x8a\x87aC\xd7\xada\xe3\xcc\xeb\x8eY\x82\xc2\x87\xfb\xf1\xc2B\x00fj~.\xab\xe4:*o$\xb0e\xd1\xdbJ#\xa6D\xceA\xd1:\x0c*v5!Pu[\xe4\x92\xba\xb7\xf4\x87\xd3no\x06\x85\xfaQD\xd1\xd3\x8a@\x94\xdbY\x9c\x8d(\xb7\xb3p\x0c\xd3\x15>B\x88\xfa\xfbSV(\xeb\x98\xe6.\xa8\\\xe1#\xfc\x87\xcbp\x05\x92\xe9io\xecwh\x14.\xe3\x91\x10D\xd2\x11\xb8\xa2\xabH 4\xd0\xa8O\xa9\x07\xe1\xfb.\xa8\x18.\xd6\xa0r\x96y$\xab\x8e\xa9b\x95:\xa6\xfb,\x0b\x9f\xe83Q\xe0\x9b@\xdd\xe8\x84\xfc\xe6@\xd9\x98\x9a\x93`\xa3\x89\xd7\x14^\x15\x06rXj 2\xcfK<\xb8oi\xe5\nTG8A\x93\x0d\xb9\xc2\x13w\xb1K\x9cg@\x94\x03\xc7\xe7V'~\xa8\xd8\xea\x82!\xbbU\xc3\x13$\x02\xf0\xb7\x84[5\xd8ay\xa0\xb8\xbe}^*\xcd\xb0\x8cj\xef`k\xb1\xec\x1bV\x06g\xa3\x11+\x03\xf2\x0d]\x0f\xa1\xf1\x9f\x8f\xa3\xd1\x13\x84=\x9f\xa8\xeb\xc1\xa7\x97\xe1\xd0\x13\x04\x18\xd9\xe4F\xab\xeb\xc8\xc4N8\xd6\xbd+\xd8G\xa0H\x9f\xfe\x1a\x8aH\xe9\xba\xa57oq\xed*4 \xaf\x9a\xc44\xf0\xe4\x0b\xe3\x85'\x08\xc1qQMq\xcb6J}\xb0\x07\xec\xde\xd7\xb0\xd4\x84\x8e\xbd\x89\x97\xf2C\xea\xd52\\\xd1\x17\xcd\xc4\xa1my\x82@\xcej\x94g\xbe\x9b\x07x\x0f\x8a'\x08\x9b4h\xd1&\xaes}MQ\xae\x13'\xdb\x9e \xed\x85\x9c\xb1\xdc\xa3\xd4\xc4\x0bR\x12n\xb9\x18+\xe6\xf7j\xd2\xd9\xe8\xf2j\x12\xf1\x9e\xd5Y\x08]\xffp\x1c]$\xca\xe8\\\xef9\xd0\xea,\xfc\x87\x0b\xe3.\xfa\x0bAZ\n\xb6\x16\xdc\xd0\xc8\xa8\x1e'\xee\xb1:\xa3\x08y\x87a\x96\x87\xe0 \x86\xcb4\xc1\xd6\x18&\xbdd\xd11\xcd\x00\xcf\xa7\xad\x19\xe4\x87x\xf2\xb4\x89\xb8\xaa&\xaa)\xce<\xc3\x81\x9c\xe0*qn\x18`\x16\x0f\xef\xf9\x8c\xd2fu#KR\xf7\xde\xcc\x99g6'}\x81Q\x02\xb1\xb8O\x11\x86Y\x8a\x0dl\xfe\xee\x1c\x8ap\x1b6[\x80Ac\x8b\x18\xa5\xd6g\xcc<\x11\xa7j\xc4Y0\xb4\x1c\xf5\x89\xdb\x86\xa8\xa6 Y\x85\xcc\n -\x861\xc7\xe8s\xbaE\xdf\\\xb4>\xa1\xf5I\xee\xfdB\xdeb\xb5N\x03f;N\x0b\x87\xf7?\x97UO[\xe0\xb7\x04\xc9\x14V\x0d\xe2\xa8\x84w\x92\x05?\x1c\xe1\xcb\xb6\x831\xa3O~x\x8dD\x12\x8c\xd5\xdeAT\xf8\xe1\x94\x9f\x05!\xa0\xbb\x90\xc3\xc9\xf6\x85A\x17\x88\xc5}f,\x1aQ\x91\xcc\xd8>\xe9lXhLY`\xb1H\xdc\xfd\x9aXE\xb5\x0c\xe43x\xf0\xcd\x99\xbfl[\xaa\xd0!.\x0f\xc9n\xb3\xf4\x9d\xf1\xb3&?\xe4^[\xee\xd3\x96\n\xfa\x8f\xe1\xb5\xce\xaaq\xd4\x0fn\x1b+To\xfb\x0b\xf7X/\x8e\xd0\xab\x0e\xd5*Y[\xae1\x1f\xba\xe1\x96N\xfa\xb8\xfe# \x1e\x95vtn\xb8\xcbh9F\x1a\xc4>,\xefA,\xfaFy\x0d\xc9\x0bm\xd4>\x9d\xc5\x81\xa8\xf3\xe8\xac]\x1b\x85F\x13\xa8\x8ebAEl\x93;8\xb7\xf0\x88\xf8&\x98[\xe1\xf7\xfa\xb4\xa5\x82\xea\xc81U4\xb9\xf5\x9a\xcf\xeb\x17{\xf3\xe0NGM(7pL\xd5-\xdbX\xab\xd1x\xfba\x1d\xc0W\xfdS\x12\xa70\xf0\xd9 \xdc\x15\xc8\x7f;\x0b\xf6_\xb7\xdd\xe6J\x1e\xebm\xb0\x0b`\x17\x02\x86\x84\xd5$~$\x92\xb8b\xf9\xe0\xb4r\x0co\x8e\xc1c\xca }\x07ry'\xd4\xa6\xe5\x99\x14\xd8\x05TS\xf0pr \xc8\x97{n\xe9\xcdm\xf7\xdd6\xf5\x03y\xcd\xed\xe49yWz\x8bq\xb1\x8a\xb5g\x1f\xa5k\x1e\x19\xd2o(Y\n\n P\x08\xe59\x97\x02x\x97\x0d\xe3\x01\xf0Yl\xd8\x9e\x93\xad\x8dp!\x15\xcb\xc9\xceS\x94\xd8O\xe1B\xca\xcf\xd4\x88\xbd\xd2\xb9\xd2\xcf\xe5=\x14\x94]\xcf\x94\x7f\xe01w`'B\x0b\xd30\xb3\xb8\x9cl\xab\xbbu\xc4\x1d#y\xca\xd6\xe1B\x8a\xe0\x94\x02\xd6\x87\x1f\xaf\x0f\xc5\xdfsp\xfb\x86\xa6\xf7h\xb2F\xd1@q\x8ct<\x07\xba\xc7\x83q\xa0\xe5<\x1el\x17-^S\x85V\x17\xaf\xa48\x80\xc1\x9aB\xde\xc6\x8a\x85\xb3>\x0fvF\xb52!@\xeb\x03\xdacf\x8b\xf0Jr\x16m\xb7j\x04\xd6#\xc2E\xbedP\xa3\xb1q\x91\xac\x88G\xabK\xd8\x16\xb9l\xdaK\xc6{\xbc\xd9xg#G\x7fP\x0d\xce\xff$\x9b\x8a\x9e\x86\xa8\xfe\xe6\x96\x9eqZ\x0f\xf8PVx$F1!@G\x82\xda3\xb4>\x18\xc9NK\x8cEN\x8c\xad$4Uv\xaem\x13z^\x86\xb1}f,\x1acg2c\xbb\x18s\x85\x0f\xaf\xde\x8b\xe5Rg\xbd0\x93\x10~\xca\x8ear\xd9\xa5\x99\x8e\xb4\xb6W\xef9\xf3\xcc:~S\xe0A\xe1\xc1\x98W\xef\xd1@]\x81\x91\xce\xe88\xc7\xba'\x19\xd8s3\x1a]\xa59\xa5A\x0f\xc4~\x11\xb5\xc5\xaec\x9a\xb8\xa2B\xfe\x81\xd9`T\x96\xdc\xe4\x98\x97\xa5'A1\xd6\xe7\xe1\xd5\xb8\xf4\xe8\xbb9Jyx\xf5\x9eW\x7f%9p\xc3$\xdeu\xa1\x06\xd5\x8e\x0b\x9d\xdd>\xcd\x15\x0d\xadH\x9ak/\xfe\x07]w\x8c4q\xd2,\x0b\xb85\xc2Y\x00\xae\x8d\xde\x97\x1a\x88\xcb\xa3Nv\x9b\x03q\xc7\x0b\xc7\x90\x99\x0f\x83\x95\x86\xe5\x1c'\xcc\xbcGZ\xb2\xa7\x1c\x1d\x88Sg\xae\x804\xf51VSH^\\{\xf3\x84;\xf2\xb4\x1fTH?\xf3\xe7\xa7\x0fJ\xb8|\xe9\x18}>\xc3\x882\x0f\xe4b\xa8\x0f`\x95\xa6\x18\xce\xb4\xae\x1e\xe0\xd0B\xd9\xe7\x06]\xff\xf4Gqh\xa3 \xb4z^-\x11\x8b\xd5\xaf%\x82\xfa\x06I\xfd\xd2C\xef\xd1f\x89\x0e\x01\x18\xcd\xac\x90p\xcb\xf8i\x16T\x13\x0b\xd0\xd2\xc10x\xcc\x1d\xfb}\xf4\xadB\xfdl\x8e\x86\x82\xfd\x83*\x0e\x12\xe9Q\xd5\x0d\x97\x17f?;&\x16\xc9\x15\xec\xc0\xfc\x920KzGr\x11K\x13\x18J\xb4t\xf5\x89D\x95$\xb9\x13\xae\xac\x96\xfd2n$\x02g\x08\x85O\x1e\xd5\x9aH\xd2\xf4p9\xe0,\x01\x86\x91\xf3\x12\xcf$2\x18\xbc\xb2\x93&!\x85/B\xaa\xee\xa5\xd3\xef$\xcf t!\x97\x18\xc3\xbaz\x80\xa0\x8b\x84\xeb\x99\xd2\xb5]\xb8\xa2\xb1\x85\xd3\xc9\x98\x94/H&\x92g`\xf6\xc9\xa3\x7fn{\x89Gh<\xf1@\x91\xad\xf5\xb47\xb6\x16Z:\xd2\xa6\xe8I\xe0\xaa\x87\x1a9\x9cN\x92\xe7Cy\x82\x9d\"lD\x8di\xa0\xb0\xb5L\xfa\x8a\x94\x95c\xa472\xcaS \x85[z\xf0\x0f\xcb\xaa\xa3\xbaH3ZN\xfb\x863\x1d\x9cN\x12H\xd2\x94\x01\xc4\xa9'\xdc\xc5\xb5r\x07X\xb8h\xd8\xc4`\xe1\xc2kc\x90\x18/\x14\xf1m\xa8\xab\xec\xd1{\xc2\x1d\xf3>\xd1\xf5\x02\x9d\xc4\xc8`k\xfe\x9b'\x99\xc1\x03\x88\xa0\xe0\xeaT`Io\xd9\xa6X\x10\xf8\xb5\xd3\x99\xc2\x9b\xe5\x89\xb7\xee(\x83'T\xb6+?\xa2\xe7\x92W\x11y|\"\xb9a9\xb7*o\x18\x97u\xb0\x16\x15w\xf9\x9c-\xbd;\xe4\xa8\xd2\xd4/\xf6\xc7\x03\xcc\x1e\xeb\xc5\x01\x98\x18\xac\xd7h\x02\xb5\x11\x1a\x96b\x15\"\x87%\xf2\xec\xe4:\x88}\x9f0\x1f\xa4\x02\xdft:\xb2bk\xb1\xf4\x0e7\xa2\xcf\xafJ\xef\x81\xb5\x8e`0\xd8q\xb3\xef,\x8cw\x8c\x1c\x89\xf3\x97-g\xaerp_e\xb2\xdcT\xf1\xa4\xe5{ *D\xe4!.\x1el\xff\xc8{q\x14\xf1\xa8r\xceK\xdc@\xbe\xec5L\xf6\xf6\x80\x92s;\x16\xfb+\xab\x9a\x92\xab\x1c2:9\xedX+\xfe\x18\x8c\x1e\x16i/^\xa7\xbc)\x82/\xe4x\x90\xdb\xa7\xce\xa2!\x17\x87:\x1bM\xbc\xa6\xea\x98\xf7\xb1l\x94y\x8f\xc6m\x12\x08\xf8l\xbf\xcf\xa5#\xadK\xfe\xa4\xbd\xb8\x1d\x8bu0\x90\x90\x9b\xc3p9\xe6=\x1e\xcd`t\xed}\xcb\xb0[\xcb\x19\xe1\x93\xc3\x19\x1f\xc1\x99\xe0F\x16 \x0b\xffd\xf4\xa4\xabf\xd0\x83\xba\xc3\xb3\x9f\xf6\x80\x8ey\xef\x96R\x1bVv5p\xcc{\x1eS6\xbcEc\xc5\x99g6\x05\x10\xde\x80\xea\x80\xa0Z.\\\xae\xac\x80\xbaz\x80+\x8b\x04U,\xael4q\x85\x0f\xa4\xbd\xa2\xefj,SV\x1d\x93d\xda\x1a0\xd9U\xb8`\x1d\x15/\xa5\x90\xd6f\x8e\x8f\x85\xb3G\xab\xe4\xdb\x8e\x8f8\x8d\xf9\x84\xaa\xac(\xf0R\x1f<.\x8fu\x9b \xf9\x96\xd9\xdb--\xcc)\x908F\xcdK.P=\xb1\xa1\x03;I\xdc^y\xc9\x05\xb5,~\x8a \x83'\xc8k N\xddN\x9e\x95s\x08&\xeamN3\xb5j\x90\xf0\xa9S\xf6\xc5O!f\xf7r3u\x80\"\x8bD\xd4\x99J\xb0=\xcf\xa8\xebx\x1e\x8b\xde\x07;\x81\xe7\x12\xaa\xb7\xf1;\x0dI\x075XS\xeb\xa7\xe1\xe4\xaa\x19,5\xf1\\\xc2si\x13\x0e\x8d\x8e\x88\xa2wt\x17\xeb\x83B\x9e\x96gnD(\xd76b\x9b\xd3\xe1wp\xc2+\xaa\xab\xa7Y\x14\x0c\x9ex\xca\x91\xad.YZ\xcb0\xea\x8b\xbd\x044 \xe72A\xeb\x03\xbb\x8d\xfb\x0dKx#\x06\xa95\xee\n\x8c\xd9\x0d\xbc5\x9e|\x8fe\xa3\x0e\x10\\\x91\x88\x8aEp\x8d&^u\x06\xfa0V\xc1\xa8b\xb9\xd5\x07\xd4\xb8\x0b\x84\xeb\x81\x98\xd8Y\xb4\xc9-12x\xa23+\x0e\xb6\x16H\x94#H~\xb1\xef\x98Y\xe2<\x1e\xed\xdd\nxN\x80\xf9\xc4\x99\xa7\xa0\xaf\xf9\x8dmk6#\x82\x80\xcd\x8d\xbd\xf9\ni/\xb8\xf2\xe4S\x16\xe6\xf7 \x12\xf2\x89v\xe2\x9d3TY\x94\x80B}-\xd1\xe2\x88\xf9\xf5d\xa0e:\xaa\xfc\xd9V\xef\xebCb\xdao\x88ACe\xeb,\xd9\xcf\xb8\x89\x1b 4}\x86N\x92K\xba\xcfa\xd0Z\x87\x18\xb0M \xbf\x81\xdf\xbf\\\xce\x80\xa1\xf1h;=\xac\x8dhC\\,\x91\x06k\xf7\x00[\xd8j\xf78\xca\xe7o\xeby\xb2\"\xce\xdd\xfab\xc5\xd1\xa3c\xaaL\x8f\xc5\xe0\x11\xa6\xca#\"\x7f\xed\x05\xec\x04\xe5o\xa9\x89\xa3m,\x9b\x8c\xef\xa4\x89sW=w\xd5#k\x87T\x12\xf8xCbtj\xe2\xc8Kd\xe4\x90|KN\xa6\xff\xc8\xa2(X\xa5\x82^\xbf\xd3\xbeu\xd1v\xdb\xca\xa6\xab\xc8\xe8\x9372\xd4)\x18i\x03\x9fUh\xe5\x1cS\xf5\x1es\xbez\xa0h\x05\xea\x81\x0bav\x88\xb9\x8a\x82\xd9\x99\xcc\x95cLva\x86\xc6V\xf0\xe9\xc55#\xc7\x98\x84\xbb\x8a\x02[\x17\x0d3\xba\x96\x05.[\xaa\xe1\xda\xbb\xd70\x83\xe6\x8a\x88\x86\xde\xd2\x03\xfb\x91\x9d\x96I\xc8\x8da\xd5\xf5\xad\xd6\xadJ\"\xff\xc0\x12\x9c4YX\x1a;\xc6$,\xb7\xe0\xd3Z\xb0\xbeLJw\xd6X\x86A\x13\xc6\x0c\x1eqv\x1e\xa1\xfb\x8ecL6\xc4X\xc8\xb7^\xec=[\x87\xa8\xadH\\\x9dGm\x81!\xef\xe1j4 >\xbd\x10W\x86\x0c\x12e\xaa\xed\x8c\x9f\x9f\xdb\x19Nv\x8b\xdc6C&6\x81\xdeH\xa4\xac\x88\xe5\x19\xbc\xb0\xbe\x0cW\xcd8\x86\xe2\x95\x1a~\x7fb\"\xe1\x18\x92\x97\xecp x\x0c\x19\xc9e,\xdf\xc0\xc8\xf030n\xfa\x0bf\x1d\xf4\xd98Vq8\xcd\xc3\xdf\xaf\xa0_\x00C\x04c\xd3\x0f\xb2)h,\x9f\xa9\x8b\xf6O\x8a2\x15\xb9\xa3\x9a\xc6\xbd\xba$\x85-\xeb\xb5\xdbH\xfe\xe9%\x91\xdff\xcd\x03\xeb6}X\x89\xce\\\x0fn\xd6e,}\xeb\x10{\x16\x8d\xc9\xf3:(\xeb;\xddp\xa1\xe5\x97cRo{\xb5\x1a\xd4\x1f\xe1fDg\x16L\xa0\x9b\x01\xa9\xeesF\xbd!\x96&\x8c\x90&\xef\xbf4f\xdf<+\xae\x83\xf4\x1bm\xf0\x9f\x90\xe7P\x9e\x07\xce\xce\x99\xbf\x84-$q\xa3\xc2]\x10\x18E\x80\x96\xb6\xb41m\xbf\xff\x84\xb5)\xe4\x8b~o\x9b\\v\x16*y)hc\xb2\xfb\xbc\xe5\xdf#\x06\"d>\xa1\x9a\xde@\x9a\xd6\xa4\x82\xba\xffiH/\xaeqs\x1cxaT\x96\x822\x1a\x87\xa9\xf4\xec\n\x92\x1fhk\xa2\xfaGU\x01Z\x87\x18\xb6HX\x9e\xd9\xa4\x99\x93vM\xa5\xd7T\x83O/\x95\xe3\n\x90\x93\x98J\xd0\x17\x16\x16d\xde\x1e\x93y\xdd\x07\x1e\x8d\xa3\x88\x19 I(O\xd6 \xe1\xca\xa3\x97,\x1e\xe8\xf29\x1d\xd7\xa9\x19\xb7\xf4\xe6\x98o\x8e\xa9\xc2\xb7\x02\xe8\xba_\x944y\xd4h,\xd0\x80\x9c\xe4=L\x83\xe4\x89\xbbA n\xda\xe4N\xad 44\x95Y|\x19\xcb\x9a\x1d\xe2\xd0\xa2`s&\x87\x86\x1eTh\xcdv\x91\xe3\n\x1f\xe1?\\\x08\x1e\xa6+2U?\xbc\xa7\x8d\xba^\xf3\xf9<\xab\x15\xc8~\x16\xed\xa0\xc31\xc2(\xe547\xd3#kW\x9a?~\x86>K.\xf6\x83\x89\xbdg\x1d,\xce\x89\xa5Ug4\xf8\xcfs\x98\x1dwpO.w\x9ea\xb6\x90\xa4\xa4Tj\x87\x84!\xa7\xbb\x94\xebneA\xc7p\x10C\xec\x8a]\xa8V\xa1\x1ad\xcb\xaa\x7fr\xb5\x91\x1f\xb5\x04\x0d\x9f\x97\x19\xa5C|Z\x14\xba\xce\x97\x9c\xe1Qg/\x03\xd5\xf5\xe0\xd3\x08hAm\xe4\xeb\xf8\xe9\xcb\x8cG\x9d-\xc1Z\xf3\x16Z\x8fn5\x0d\xc3\x06\xb9c\xdd\x91\xab\xf4`>Fe\xeb\x18y2\xea\xe0Q\x87\xfd\x00\xb9\x8b\xb9\"\x1b+\xe4*].y\x86\xd1$\xbf\x10\x9a\xe5\x02\xabT\x00\xad\x08X\xa6\xc7\xe1C;\x86\x84FET\xcb\x1d\x81%[\xbci<\xdf\xa40\xb7u<\xea\xf8\x95\xb2U\xfdh\xdb\xef6\xf5A\x95)\x8e\xfd\xddY\xd2\xeb\xb6\x05\x92\xe6\xae\x0f\x1e\x85Lv\xd9;}\x06$\x84\xcb\x0f\xdd\xd2\x1bndY\xf0\x08\xb6\xe0%\x8b\x0c\xb1\x97\x1b\xbdC\xa4\\\x14,\xcf$\xe5\xa0\x95\xdb\xf3\x95\xd5Y\xf0\xe9\xe5\xedu\xab\x1a1;\x94\x91 \x91\xf4j\x80\xcd\x0f._\xb9,\x92\xbc?((\x92(<\xe3,\x8eh-v\xb4=\xaf\xeb\xb5\xaa\xb2_\xb3\x88\xa84\xd1X\xdf\xcd|n\xcey\xa1\x1e\xd5Zlwe\xdew\xa0\x95#\xfe\x99\xf6{\xf8\\\x87\xf4\x8e\x13)N\xb9\xc5j\xe6\x9f7\x93[\xe4sP\xa8n\x8e}\x89M\x9bY\x07(\xb5P\x18\xb5\x01\xcf?\xfeA\xa22\xda\x02\xd0\x83Q\xde\xbd\xaf\xc5\xf2\x95\xad\x1c\x96\xde}\x1d\x01\x13\xfb\x1d\xad\x9eo\x97 \x94\xef\xd0\xf2ub\x9bQ4\xdc\x05th}@g\x01\xf9\x9c[\x1d\xf8&%e\x91,m\xd0\xe2\xe2`\xa9\x10\x11\xa5\xeeA2\xf7\xe3\xc3\xd3\xf8aK\xb3U\x9fQ5r\x04\x86\xeb\x80)\x92\xd0\xd0^\xbd\xea\x1b\xd2^\xa1u\xcd\xe6\xb4\xb9\xdd!\xb6\xb6\x98e\xb0\x05\x06\xad\xdd\xf2\xd8%vif\x1d\xa0\xd1\"\xa1\x15G\x00\xe65U\xca\xa1\xf5\xa1\xff\x18\x0bZr\xdd\x99\xd7qeC\xa3\x85\xbb\x8a\"h4qJn\xe4mv\xad\xfa\xdc\xe2B#\x18Z\xb9\xec-\xef\x90\\v\xad\xd7s\x1b0\xbd\xde'd\xe7L_\xed.\xea\xae\xbe8*\xcc8 \xaa\xf3\xe6\xf3\xb8\xab\x91\xf7<\x0e\xc7`\x7f\x04\xcf?\xb3\x0e\x10e\xd1\xc8\x89\xa1\x01#\xc8\x19M\xd0\xb4\x19\x136$\x08\x0fG\xe0\x13\xc4\xce\x98*_\xf1\xaa\xb6\xe1&.4/\xfb\xcc\x15\x07H.\xd7}\x11\xcfU\x1b\xe1n,})\x03\x89\xfb\xd1\xc6\xddd0\x0f$\xf0\xe1\xa7\xa9T\xf7\x9d\xac\x82\xf6\xd8\xe7\x8e\xb6\xfb\xbbN\xa3\x05w\x93H.\xba\xa5g\xbc\xaaz\x89D\xc0yrN\xdb$\xc7\xad\xd2\xc6\"\x91\xa2e\xf4\x18\x0c\x8f:\xdd\xf3\xb8>,y\xe4\xdddPY\x8d\x0cu\xbaI\x82Q\xba\xce\xb7\xbf\xf3\x98h\xd9'\x94\xa2\xd1\x12C\xb2\x15^{y\xe5z\xfd\xb0`\xa51o\xcc\xba\x91\xfd\x11\x94\xeb\xcc\x99\xdc\xa1o\x0b\xae\xe0\xc7\x9c\xe1L{S\xd6\xa0\xb3)xc\xe6\x19\xeb,\xab\xfb\xe7\xc3WtvK#\xac\xce\x1cC\x81;\xc1'\xb5\x8eu^l\xd9\x196\x01,\xac\x18`0\x8d9\xfb\xcb\xd3\xbeQ\xe9\xe9\x94#\xce\xe1\xa0\x9bf\\UBv\xda\xa0\xa5@K\x05\x86\xc8\xcf\x8f;\x12 \x9f\x1e\x16\xf0\xb0\xf09\x9b\xc14\x10\xc4D\xd4t\x86Y\x18L\x03\xea\xd5k\x98$\xc8_;\xa7H\xa7&H\xc1\x9dp\xcc\x96[5\\Y\xe7\x04\xdb\x9b\x00\x9d\x90\x88>\x9f\xa3I\xec\xa6\xd8xQ\xb9pf\x1d\xa0\x9b\"A\x15G\xbeE\x1c\x9c\xae#\xa3\x10\xcb\xc1\xd1\x9e\xafc\xc9\xf5i\x07\xe7\xb5\x07^\xf3\x197T\xdcP\xfd\x0cg\xf2\xe2\xb5\xb9\xf32\xca\xd1\xb0\xc4\xdc\xed,\\\xbb\xc5\x9c#\xb1\x99\x04W\xf7$YK~\xf3qE\xcb\x14\xe1\xf9\x0e`7XG\x8f\xd70\xdd\xaa\xe1\xac\xea\\ \x9d\\\x06[#\xf1[c\xb6\xff\"\x9c\xe6?\x172V)PR\xb5` + \x00\x95\x04\xbf\xfe\x81Dr\x16\xa3\x95\x1c\xc3t\x16\xef[\xa3]\xf3\xc3SZ\x08\x1e\x10\x1e \x97\"A\x18G\xf1\xe55U\xaf:s\xab\xe9xU\x98\xd4\xf6\\\x88\x0c\xb9\x19\xeacP\xd7\x88\x88\xc9\xe5\xb2[M\xfb\xbd\xdb\xd2;\xb4\xca\x81\x8e3B\xffPM\x13 ISV\xbf\xdb\x9d\xd9u\x9aH/\xa6A\xfct\x16\xaa\xaf\xfb\xaa\xa6\xcf\xa2\x05R/\xb0\xa2\xf332+O\x1b\xb0~\xf1\x1f\x89$J\xbd \xb9\xc8\xc6\x06\x9fY\xa0\xc1\xeaGp\x17@\xc8c\xfb\xc9\x97h\xcbe\x90\x16\x07\xef\xce%\xde\x93\xb8\xc1=\x0e*\xec\x1b7\x18\xfb\xfb?\x88\x83\"\xae\xb3\xd5c3\xb0\xe3qPt\x8a6\xa5\x0b|\x01\xbc\xd9\n\xd2\x9a\xc8)\xbe\xd8\xea8\x8b6\xb6,\xca\xc4\x0f\xfd9\xe7\x13.\xa4\x81\xf8\xb9\xa9\xdc\xb5z>9\xcf\x04\x02A^u\x1ao\xd9w\x10\xa7`\xf5\xb7Z/\x1fTl\xf7Pe\xc4\xa3\xb1Q\xdb\xb4=\xb6\xe5S\x07\xab\x06\xb1|\xf9\"\x03\x18q\xe6\xdb~\x11=\xdc\xe1\x04=TK\xe24n\xf4\xfe\xb2Q\xd7k\xb0\xf5\xdcv\x0c\x99\xbd\xdbY\xec\xb3R\xd1`\x8b\xc3J\xb9\xc2\x07\x1a[n=\xd6@0\xdc\x15\x900\x0d\x94\xbc\xd8~\xe6\xd4\xd8{\x82\xe4\x18\x94\x9e\x99\xcd\xf6\x93\xbe\xa8\x9cQ\xc0\xf2\x0d\xaa\x8e\xf7\xa7\xc9\x91\xa7(\xd7QMa\x9b`x\x82\xc49\xfd\x9e\xc0\xa5\xff\xc85Gz\x0fl\x03\x0d*\x9f8\xc9\x86\xea%\xc2\xa3\xaa\"\xcb1\x82\xe4U\xdf\x02$\xbav\x8bdSf\xe3\xf2\x8c\x92\x00i\x8f\xa4\xe2\x00R\x0c\x92\x8a\x00i4A\xb5\xf7\xb8\xfd\x1a\xb4\xd5\x00Fv\xc0~\xbb\xcf\xed\xa0M5\xa2\xe5\x87J\x14\xb6\xb6f`z\xcdub\x16\xc1p\xd2\x93\x0fh\xe6\xb3\x18\xce\x9d!\x12\xfc\x13\xc8Y\xed3\xa0.\xc4)\xaa\x94\x83ZA\xa4\xb8\xa5=\xf0\xc4[\xb4j\xb0\xf6\xb1\xe0~mr\x92K\xc1\xb3K^\xf1\x80\xe7r\xf2\x8a\xb8\xbc\xda\x08U2\xb1\x90S\xc9@'\x89\x8a]f\xf1\xfdM=\xe8\xa3\xff\x91H\xe2\xe6\xfd\x96\xa0.\xaf\x05\xaa\xd1\x08W\x98\xd7H\x8c\xb4\xc8\xb0\xce\x99\x9d\xce\xf6\xd3\x88r\x96\x1a\x88\x82\x1f\xa4\xac4\xc7H\x1f\x1f\x16\xbd=,b\xf9\xe1-_\xd8v\x1a\xd1\x83\xbcv\xba6t\x12Gm\x06|\x9e\xb4E{\x9c\xf9bB<\xf7\xb2\xc0\xf4:\x9ep\x17wt!\x81\xd3\x1e\xbb\xc5\x01\xa7\x18\xec\x96+|\x90@}\x19\xcb\x10yK\xd5{}\xc1S\xdb\x9f \x93,\x07\xe9\x18H\xeb\x0d\x0e\xb6\xdbV\"\x9c\xddR\xa59\xfc\x13\xd3\xbf!%\xc1bo\x1a\xb4\x16\x9d\x85\xc4f;G7\x07\xedp_K\x15'\xc6^\xbd\x17d\x8e\xce\x9ck\xeb\x0d\xdc\xb9\x01\xf1\xd3ki\xfe,\xa6N\x92\x8er\x8a\x04\x18\xb91\x8bk\x9c\x18\x07&\x96\xbc\xf7\xeb\x8e\xa2H\x80\xa9\x8aw\x17\xeaL\xa4\xad\xdd\xa7\xecUA\xf9/\xd1\x08\xdbg\xb8\xa2\x11\x16\x87\xe1\n\xaf\x8d%\x12-U\x9cy\x06\xdd\x7f\x9e\x1d9-\xaei\xb4\x98\nS\xa5G#\xa7\xdd^\x8b6zH\x91$\x8c\x8d\xbc\xdc\xe9\xe6;M\x98\xbe\x93\xa8\x99\xb8\xa9z\x9b\xd9Y&\xe9\x83\xc1\x9c\xc76\x89\xfd0mJ\x1e\x9c\x9a!y%W\x9c\xc4\xf4\x80\xe4\xe5\xb3\x85@\x7f|Ja\xcc\x05\x9d}\x1e+\x1a:qx,\xe2\xebt\x1dib,_\xa7\x89n\xa1\xe0\x16\n\x01\xdb\xcd9\x87\x1el\xcd\xfdh;\x8b\x1b\xc6\xcd\x9fei\xc8A\xaf\x1f\xc9\xb3\xff\\\x8f\xe0Z\xb4\x9de\x8b\xe5\xf2T,,:\x86\xcaHm\xdf\x0e\x19\xc7\xd4\xc1;\x1bq\x884S\xbc\xf6\x9d\xb3\xad1f\x94\x98[J_\x05\x848\xacR\xe4\x0b\xab\x0f\x0e\xb4\xb9\x0b\x99\xbcS\xefk\xbd\xba\x91\xf6\x12\x03>+\xc5.fc\xa5\xe8\xc5\xb8\xd7\xfe\xd08\xc7\xe8\xbaJ\xd51U\xf4p\xc7n\"c\xca\xb6\x9b\xf6\xbc\xc1\xdb\x14\xda\xe3u;g.\x10XE\xb8\xa4\xea\x08\xdfV\x02\xe5\x82\x9b\xf9\xa4\xda#\x9e\xf1\x0c\xeeG{\xbd\xf4@\x91;\x123\xdbUE\x027#\xb39\xe9\x0b\x12}\x8a\x99]\xde\x88\x073\x97\xf3F\xc41\xd5F\xa0\xc4\xda\x0c\x16\x946\x98i\x12)N\xc7~uK\xe8\x1f\x9f\xd8\xbd\x8d\x99`\xad\xfd\xe6\xf3\x04\xa1a\xff\x11\x8eIi\xb3\xd9O~T\xd1\xd2\xd9C\xe0rL\xc1q\x19\xe1,KxU\xdc\xec\x82sr\xbf\x94E\x1b\x06\x1f\xb4\x12\xf3\xb2\x9f\x01\xf0MS\x06[\xc3\xf2\x0d\xb9\xe0Q\x11) &\xd4\xdd\xf4\x80\x92\x93+\x84wSqKo\xf1p\xb5G q\xe0*\x8e\xf0\xe4[\xacb\x9a\x9c\xc3V\x87\x8eB\xb9\x0d\xb6\nt\xe6\\\xba'<\xf9\x06\xe2\xd4k\xb0\x9dL\xe86\xbc\xe2\x84K\xae;2\xf0\xe4iC\xcc\x04\x19m\xe5\xd8F\x9a[\xfdL~\x9cLg\x0bm\x94\x80\xd9w\x18J\xd0{\x84\xf7\x03\xa4&G8\xb4\x15?\xaf\xc3\xa8H~\xb1b\xe1\xc9\xb7\xad\xbd3N\xc7B<@\xda\xe7\x88\xa2\x81\x14\x87#\n\xaf\xbd\x1cH$\xee\x9f\x06\x046\xb4\xf4\xe3\xc36v'\xc5\xa2\xcc\x90\x00\xe91\xef\xcf\xd8H$\x821\xc0\xa7\x9d\x1a;\xa8Wa\xddx:.\x8f`\x95\xe2\xb2<\xecl\xe9\x8e\xc1\xa8\xff\x8a\x87\x066y\x06\x0f\xfb\xebl1z\xea\xf0\xde\x10\xa0\xfb\x0eM\xa67]Z\xa0>\x9e\x1a\xbe\xc8\x136\xefs8\xd1P\x89\xc3\xe1\x10WU\x9dy\xaf\xb1dqL\x08\x8dj\xdf\xbd\xd7\xc2\xcf\xd0\x06\xd8\xc7+\x1b\xdbQ\x10\x95[\x06\x85S\xdc \xc1\x8c\xab/\xb8\xa2 :\x8c*\x18\x1b\xc1\xf2]Vl\x89\xc4\x8c\xf7\xfa\xe2\xbd\x16B\xdb\x95\xa4Q\xd9\xe2\xa3t@\x17\xc3\x06/\xd8\xf7!\xe8K\x89\xb43%\xdd{-\x80\xea\xcf^\xff\x03\xb6\xac'(\xd8#v\xc2\xd0\xd8\x80\xe7\x1f\xfe\xa8v\xb7\xea\x8c\x11;\xd0\x1c\xc4\nu\x9a\x03\xc7T\x99\xa9\xa1=F\x8f\x81\xfe\xfa\xbc\x8a=}\x81\xb9r.\x1ai\x92\x0c\xa69\xa0\x9aB\x12\x96\xbaV\x89\xcb\xd4h=\xb8\x19;F\xce\xb5\x0d\x9fX\xb0\x13<\xa2o\xa3\xeb\xda\xe9\x80\xf6\xdd\xa1\x1e\xa3w\x84\xcb\xe1\x94\xc5\x04\xf3\xfe\xbf\x05\xbfS\x0e\x0f;\xfeLxe\x04r\xc5G\xd4\xce$\xa2\x0b<\x97W\x93\xf6\x99\x9fhD\xc5\xear\xab\xce\xd0\xd8\x02\xeb\x16:\xf3X\x88\xa2\xbf@L\xf2[\xd3O\xe4\x85[\xbf\x92?\xab\xe2\x94\x05z\xdb\x8fU\xaa\x06\x895y\x82j\xb9\x07s+\xdc\x9a\xc0\x14\xe5\xbc\xd3\xef\xd6\xa7\xc4\xe2\xab`\xb3\xb4\xe8\xea\xc6\xf5\x0d\xaa=\x07\x03\x0c\x88\x9d\xb0E\x9c\xc8rj\x8b\x8c\xba3\xaf\xb0\x83\x07\x03>\xc9K\xf6\xd6$\xd7\xf1\x9a\xc4\xca\xd0\x0f\xb8\xc4\xa9c\x85zG\xe9\xf4\xc0\xe0 \xd1\x11x\x1aD\xca\xab\xb2\n\xb5\xb2\xc2\x95G\xb7\x7f\\\xce\x16\xc9T\x13\xf8\xed\x91H\x1c\xf0\x8b\xd3*W\x9d\xa1\xd1\x04wc\xb6\xca=\xa2\xe7\x12\x8d~\xc5\xb3\xa7\xc6n\x1b\xb4\xb3\xea\xb2x\xf2\xec\x18%g\xfe\xb0\xd3>E\x0c\xc3zW\x07$\xab\x1c\x03\xf8\xb7\xcd]\xb7\x89\x13Y\xb6W\x8f\x0f\xdacm\x07\xdb \x1d\xb5\xa9\xa8\xa6\xe0ns\xd3\x0c\x96H\xf0J\xbf?\x89u\x1e]{\x8fK\x1f\x8c\xdd\xe6\xc6\xaf_\xe6\x1f\xf7\xf9%\x1e8\xc5h\xaa\xab\xce\xa06\xc2z\xbc2?m\xaa\xf3\x8c&\xd6?\x82r-\xe7|2\xe2\xa4\xe8``\x12V\x1d\xd9\\#J\xf4\xadc\xfd#\xd8\xc7\xf1\xacz\x99[\"k\xfd\xd0\xc6\xd6\xfc}\x96\xc2\xe5\x88\xe8\"\x08\x9e<\xf9t\xf8\xba\xb8\xf7#\x91$\xb6\xdc\xc8\xa1\xfe\"\x18\xd2\x1f\xc8\x1d#\xb7\xac\xbci\x93sZWf\xa3;z\xb9\xbc\xe4\x1e\xbf\xc4\x81\xab\x18\xfc\x12\x89\xd8\x9b*\x12ncU\xd3\xbe?R\x9f\xb8\x1e\xb8\xd0\xcd =\x89f\xc7\xb6?:\x10w\x05rE\x9c\xb2\x9c\xb9\xc8\xb9\xb1\x03yr\xc2-\xf1@T\xb7\xbf\xab\xff\x88\xd8\x89W\xf4\xeaO\xccQ\xd1\xf1\xc9\x04Wl\x82l\xa49\xeaH\x8ei\x86^\x02\xd51\x128\x91e \x1b\xc1f\xeb\x03\xfa\x05\x90\xa7\xce\xdc\xff\x02t\xa4\xe0=\x8b\xc2\x15\xca\x0e\xc9U\x85'\xa6\x87\xe7\xf5]\xe6\xfe\xf6 \xa8h\\\xc5j\xbc\xab\xce\\\xe1\xc31b\xcd\xae\xc3\x15\x0bi\x9f\x01\x83\x82W\x12\xd2>\x8fWi\xb7\xdc\x9f\xbf\x93U\xbe\x883\xed}\xd5}\xb4^\xd2\x18\x818E\xdf6\x1b\x1b\xd2 \xd1k\x95\\\xfa\x81\xa0.?\xc6I\xfd0\xbb\x1c1\x1c\x85\xfc8.%\xf6'\x80\"\x8d\x8eI\xec\n\xa8\xac\xedlS\xfc#\x91\xf4\x04\x89\x1c\xb75s\x8cE\xd0\xbf\xc4\x19\xbc\xc5(\x04\xd3\xd3\x05\x9dU\xf4z^EtW%vB\xee{\x9b\xdc&\x99\xb6t=\x90W\x916w\x98\xacr\x88\xb5|,\xd0\xee\x93]\xd1\xa0\x8d\xd5\xd8W\x9d\x81\xae\xc3(\x1fs\xe7U\xaf\xf9\xe4\x19\xcf\x04o\xe1-BC\xaa\xc6HW\x0b\xf94\xb9\xe5\x85*\xbd\x91M\xf6\x0bx%qY\xc5\x85\x8a\xe42\x92\xef\xfd\x1a\xac4\xdd\x12T\x9e.\x02.5\xbc\x92 0 { + return s.GodBook + } + if s.KangxiDictionary > 0 { + return s.KangxiDictionary + } + if s.TraditionalChinese > 0 { + return s.TraditionalChinese + } + if s.SimplifiedChinese > 0 { + return s.SimplifiedChinese + } + return 0 +} diff --git a/version.go b/version.go new file mode 100644 index 00000000..43dc5729 --- /dev/null +++ b/version.go @@ -0,0 +1,4 @@ +package fate + +// Version ... +const Version = "v3.5.7" diff --git a/wuge.go b/wuge.go new file mode 100644 index 00000000..49bf887c --- /dev/null +++ b/wuge.go @@ -0,0 +1,293 @@ +package fate + +import ( + "github.com/goextension/log" + "github.com/google/uuid" + "github.com/xormsharp/xorm" +) + +// WuGe ... +type WuGe struct { + tianGe int + renGe int + diGe int + waiGe int + zongGe int +} + +// ZongGe ... +func (ge *WuGe) ZongGe() int { + return ge.zongGe +} + +// WaiGe ... +func (ge *WuGe) WaiGe() int { + return ge.waiGe +} + +// DiGe ... +func (ge *WuGe) DiGe() int { + return ge.diGe +} + +// RenGe ... +func (ge *WuGe) RenGe() int { + return ge.renGe +} + +// TianGe ... +func (ge *WuGe) TianGe() int { + return ge.tianGe +} + +// CalcWuGe 计算五格 +func CalcWuGe(l1, l2, f1, f2 int) *WuGe { + return &WuGe{ + tianGe: tianGe(l1, l2, f1, f2), + renGe: renGe(l1, l2, f1, f2), + diGe: diGe(l1, l2, f1, f2), + waiGe: waiGe(l1, l2, f1, f2), + zongGe: zongGe(l1, l2, f1, f2), + } +} + +// tianGe input the ScienceStrokes with last name +// 天格(复姓)姓的笔画相加 +// 天格(单姓)姓的笔画上加一 +func tianGe(l1, l2, _, _ int) int { + if l2 == 0 { + return l1 + 1 + } + return l1 + l2 +} + +// renGe input the ScienceStrokes with name +// 人格(复姓)姓氏的第二字的笔画加名的第一字 +// 人格(复姓单名)姓的第二字加名 +// 人格(单姓单名)姓加名 +//  人格(单姓复名)姓加名的第一字 +func renGe(l1, l2, f1, _ int) int { + // 人格(复姓)姓氏的第二字的笔画加名的第一字 + // 人格(复姓单名)姓的第二字加名 + if l2 != 0 { + return l2 + f1 + } + return l1 + f1 +} + +// diGe input the ScienceStrokes with name +// 地格(复姓复名,单姓复名)名字相加 +// 地格(复姓单名,单姓单名)名字+1 +func diGe(_, _, f1, f2 int) int { + if f2 == 0 { + return f1 + 1 + } + return f1 + f2 +} + +// waiGe input the ScienceStrokes with name +// 外格(复姓单名)姓的第一字加笔画数一 +// 外格(复姓复名)姓的第一字和名的最后一定相加的笔画数 +// 外格(单姓复名)一加名的最后一个字 +// 外格(单姓单名)一加一 +func waiGe(l1, l2, _, f2 int) (n int) { + // 单姓单名 + if l2 == 0 && f2 == 0 { + n = 1 + 1 + } + // 单姓复名 + if l2 == 0 && f2 != 0 { + n = 1 + f2 + } + // 复姓单名 + if l2 != 0 && f2 == 0 { + n = l1 + 1 + } + // 复姓复名 + if l2 != 0 && f2 != 0 { + n = l1 + f2 + } + return n +} + +// zongGe input the ScienceStrokes with name +// 总格,姓加名的笔画总数  数理五行分类 +func zongGe(l1, l2, f1, f2 int) int { + // 归1 + zg := (l1 + l2 + f1 + f2) - 1 + if zg < 0 { + zg = zg + 81 + } + return zg%81 + 1 +} + +// Check 格检查 +func (ge *WuGe) Check(ss ...string) bool { + v := map[string]bool{} + if ss == nil { + ss = append(ss, "吉", "半吉") + } + //ignore:tianGe + v[GetDaYan(ge.diGe).Lucky] = false + v[GetDaYan(ge.renGe).Lucky] = false + v[GetDaYan(ge.waiGe).Lucky] = false + v[GetDaYan(ge.zongGe).Lucky] = false + + for l := range v { + for i := range ss { + if ss[i] == l { + v[l] = true + break + } + } + } + for l := range v { + if v[l] == false { + return false + } + } + return true + +} + +// WuGeLucky ... +type WuGeLucky struct { + ID string `xorm:"id pk"` + LastStroke1 int `xorm:"last_stroke_1"` + LastStroke2 int `xorm:"last_stroke_2"` + FirstStroke1 int `xorm:"first_stroke_1"` + FirstStroke2 int `xorm:"first_stroke_2"` + TianGe int `xorm:"tian_ge"` + TianDaYan string `xorm:"tian_da_yan"` + RenGe int `xorm:"ren_ge"` + RenDaYan string `xorm:"ren_da_yan"` + DiGe int `xorm:"di_ge"` + DiDaYan string `xorm:"di_da_yan"` + WaiGe int `xorm:"wai_ge"` + WaiDaYan string `xorm:"wai_da_yan"` + ZongGe int `xorm:"zong_ge"` + ZongDaYan string `xorm:"zong_da_yan"` + ZongLucky bool `xorm:"zong_lucky"` + ZongSex bool `xorm:"zong_sex"` + ZongMax bool `xorm:"zong_max"` +} + +// BeforeInsert ... +func (w *WuGeLucky) BeforeInsert() { + w.ID = uuid.Must(uuid.NewUUID()).String() +} + +func countWuGeLucky(engine *xorm.Engine) (n int64, e error) { + return engine.Table(&WuGeLucky{}).Count() +} + +func insertOrUpdateWuGeLucky(engine *xorm.Engine, lucky *WuGeLucky) (n int64, e error) { + var session = func() *xorm.Session { + return engine.Where("last_stroke_1 = ?", lucky.LastStroke1). + Where("last_stroke_2 = ?", lucky.LastStroke2). + Where("first_stroke_1 = ?", lucky.FirstStroke1). + Where("first_stroke_2 = ?", lucky.FirstStroke2) + } + + n, e = session().Count(&WuGeLucky{}) + if e != nil { + return n, e + } + log.Infow("lucky", lucky) + if n == 0 { + n, e = engine.InsertOne(lucky) + return + } + return session().Update(lucky) +} + +// WuGeMax ... +const WuGeMax = 32 + +func initWuGe(lucky chan<- *WuGeLucky) { + defer func() { + close(lucky) + }() + var wuge *WuGe + for l1 := 1; l1 <= WuGeMax; l1++ { + for l2 := 0; l2 <= WuGeMax; l2++ { + for f1 := 1; f1 <= WuGeMax; f1++ { + for f2 := 1; f2 <= WuGeMax; f2++ { + wuge = CalcWuGe(l1, l2, f1, f2) + lucky <- &WuGeLucky{ + ID: "", + LastStroke1: l1, + LastStroke2: l2, + FirstStroke1: f1, + FirstStroke2: f2, + TianGe: wuge.tianGe, + TianDaYan: GetDaYan(wuge.tianGe).Lucky, + RenGe: wuge.renGe, + RenDaYan: GetDaYan(wuge.renGe).Lucky, + DiGe: wuge.diGe, + DiDaYan: GetDaYan(wuge.diGe).Lucky, + WaiGe: wuge.waiGe, + WaiDaYan: GetDaYan(wuge.waiGe).Lucky, + ZongGe: wuge.zongGe, + ZongDaYan: GetDaYan(wuge.zongGe).Lucky, + ZongLucky: wuge.Check(), + ZongSex: isSex(wuge.zongGe, wuge.waiGe, wuge.renGe, wuge.diGe), + ZongMax: GetDaYan(wuge.zongGe).IsMax(), + } + } + } + } + } +} + +func getStroke(character *Character) int { + if character.ScienceStroke != 0 { + return character.ScienceStroke + } else if character.KangXiStroke != 0 { + return character.KangXiStroke + } else if character.Stroke != 0 { + return character.Stroke + } else if character.SimpleTotalStroke != 0 { + return character.SimpleTotalStroke + } else if character.TraditionalTotalStroke != 0 { + return character.TraditionalTotalStroke + } + return 0 +} + +func isSex(dys ...int) bool { + for _, dy := range dys { + if GetDaYan(dy).Sex { + return true + } + } + return false +} + +func filterWuGe(eng *xorm.Engine, last []*Character, wg chan<- *WuGeLucky) error { + defer func() { + close(wg) + }() + l1 := getStroke(last[0]) + l2 := 0 + if len(last) == 2 { + l2 = getStroke(last[1]) + } + s := eng.Where("last_stroke_1 =?", l1). + And("last_stroke_2 =?", l2). + And("zong_lucky = ?", 1) + rows, e := s.Rows(&WuGeLucky{}) + if e != nil { + return e + } + for rows.Next() { + var tmp WuGeLucky + e := rows.Scan(&tmp) + if e != nil { + return e + } + wg <- &tmp + } + + return nil +} diff --git a/wuge_test.go b/wuge_test.go new file mode 100644 index 00000000..b94632da --- /dev/null +++ b/wuge_test.go @@ -0,0 +1,35 @@ +package fate_test + +import ( + "fmt" + "log" + "testing" + + "github.com/babyname/fate" +) + +// TestWuGe_WaiGe ... +func TestWuGe_WaiGe(t *testing.T) { + l1, l2, f1, f2 := 1, 1, 1, 1 + for i := 0; i < 80000; i++ { + if f2 >= fate.WuGeMax { + f1++ + f2 = 1 + } + if f1 >= fate.WuGeMax { + l2++ + f1 = 1 + } + if l2 >= fate.WuGeMax { + l1++ + l2 = 1 + } + wg := fate.CalcWuGe(l1, l2, f1, f2) + sum := l1 + l2 + f1 + f2 + if wg.ZongGe() != sum { + log.Println(wg.ZongGe() == sum, l1, l2, f1, f2, wg.ZongGe()) + } + fmt.Println("result:", wg.Check()) + f2++ + } +} diff --git a/wuxing.go b/wuxing.go new file mode 100644 index 00000000..11953b16 --- /dev/null +++ b/wuxing.go @@ -0,0 +1,44 @@ +package fate + +import ( + "errors" + + "github.com/xormsharp/xorm" +) + +// Luck ... +type Luck int + +var luckPoint = []string{"大凶", "凶", "凶多于吉", "吉凶参半", "吉多于凶", "吉", "大吉"} + +// Point ... +func (l *Luck) Point() int { + return int(*l) + 1 +} + +// ToLuck ... +func ToLuck(s string) (l Luck, e error) { + for i, luck := range luckPoint { + if luck == s { + return Luck(i), nil + } + } + return Luck(0), errors.New("parse error") +} + +// WuXing 五行:five elements of metal,wood,water,fire and earth +type WuXing struct { + WuXing string `json:"wu_xing"` + Luck Luck `json:"luck"` + Comment string `json:"comment"` +} + +// FindWuXing find a wuxing +func FindWuXing(engine *xorm.Engine, s ...string) *WuXing { + var wx WuXing + _, e := engine.Where("first = ?", s[0]).And("second = ?", s[1]).And("third = ?", s[2]).Get(&wx) + if e != nil { + return nil + } + return &wx +} diff --git a/xiyong.go b/xiyong.go new file mode 100644 index 00000000..051113a3 --- /dev/null +++ b/xiyong.go @@ -0,0 +1,77 @@ +package fate + +import ( + "math" + "strings" +) + +// XiYong 喜用神 +type XiYong struct { + WuXingFen map[string]int + Similar []string // 同类 + SimilarPoint int + Heterogeneous []string // 异类 + HeterogeneousPoint int +} + +var sheng = []string{"木", "火", "土", "金", "水"} +var ke = []string{"木", "土", "水", "火", "金"} + +// AddFen 五行分 +func (xy *XiYong) AddFen(s string, point int) { + if xy.WuXingFen == nil { + xy.WuXingFen = make(map[string]int) + } + + if v, b := xy.WuXingFen[s]; b { + xy.WuXingFen[s] = v + point + } else { + xy.WuXingFen[s] = point + } +} + +// GetFen 取得分 +func (xy *XiYong) GetFen(s string) (point int) { + if xy.WuXingFen == nil { + return 0 + } + if v, b := xy.WuXingFen[s]; b { + return v + } + return 0 +} + +func (xy *XiYong) minFenWuXing(ss ...string) (wx string) { + min := math.MaxInt32 + for _, s := range ss { + if xy.WuXingFen[s] < min { + min = xy.WuXingFen[s] + wx = s + } else if xy.WuXingFen[s] == min { + wx += s + } + } + return +} + +// Shen 喜用神 +func (xy *XiYong) Shen() string { + if !xy.QiangRuo() { + return xy.minFenWuXing(xy.Similar...) + } + return xy.minFenWuXing(xy.Heterogeneous...) +} + +// QiangRuo 八字偏强(true)弱(false) +func (xy *XiYong) QiangRuo() bool { + return xy.SimilarPoint > xy.HeterogeneousPoint +} + +func filterXiYong(yong string, cs ...*Character) (b bool) { + for _, c := range cs { + if strings.Contains(yong, c.WuXing) { + return true + } + } + return false +} diff --git a/yao.go b/yao.go new file mode 100644 index 00000000..c9fc429d --- /dev/null +++ b/yao.go @@ -0,0 +1,38 @@ +package fate + +import "github.com/godcong/yi" + +// GuaYao ... +type GuaYao struct { + Yao string `bson:"er_yao"` // 二爻 + JiXiong string `bson:"er_yao_ji_xiong"` // 二爻吉凶 +} + +func getYao(xiang *yi.GuaXiang, yao int) GuaYao { + switch yao { + case 0: + return GuaYao{Yao: xiang.ChuYao, JiXiong: xiang.ChuYaoJiXiong} + case 1: + return GuaYao{Yao: xiang.ErYao, JiXiong: xiang.ErYaoJiXiong} + case 2: + return GuaYao{Yao: xiang.SanYao, JiXiong: xiang.SanYaoJiXiong} + case 3: + return GuaYao{Yao: xiang.SiYao, JiXiong: xiang.SiYaoJiXiong} + case 4: + return GuaYao{Yao: xiang.WuYao, JiXiong: xiang.WuYaoJiXiong} + case 5: + return GuaYao{Yao: xiang.ShangYao, JiXiong: xiang.ShangYaoJiXiong} + default: + panic("wrong yao") + } +} + +func filterYao(y *yi.Yi, fs ...string) bool { + yao := getYao(y.Get(yi.BianGua), y.BianYao()) + for _, s := range fs { + if yao.JiXiong == s { + return false + } + } + return true +} diff --git a/zhouyi.go b/zhouyi.go new file mode 100644 index 00000000..056b9a46 --- /dev/null +++ b/zhouyi.go @@ -0,0 +1,10 @@ +package fate + +import ( + "github.com/godcong/yi" +) + +// QiGua 起卦 +func QiGua(xia, shang int) *yi.Yi { + return yi.NumberQiGua(shang, xia) +} diff --git a/zhouyi_test.go b/zhouyi_test.go new file mode 100644 index 00000000..a0901798 --- /dev/null +++ b/zhouyi_test.go @@ -0,0 +1,9 @@ +package fate + +import "testing" + +func TestQiGua(t *testing.T) { + yi := QiGua(7, 7) + get := yi.Get(0) + t.Log(get) +} diff --git a/zodiac.go b/zodiac.go new file mode 100644 index 00000000..f2846c94 --- /dev/null +++ b/zodiac.go @@ -0,0 +1,151 @@ +package fate + +import ( + "fmt" + "strings" + + "github.com/godcong/chronos" +) + +// ZodiacPig ... +const ( + ZodiacRat = "鼠" + ZodiacCow = "牛" + ZodiacTiger = "虎" + ZodiacRabbit = "兔" + ZodiacDragon = "龙" + ZodiacSnake = "蛇" + ZodiacHorse = "马" + ZodiacSheep = "羊" + ZodiacMonkey = "猴" + ZodiacChicken = "鸡" + ZodiacDog = "狗" + ZodiacPig = "猪" +) + +// Zodiac 生肖 +type Zodiac struct { + Name string + Xi string // 喜 + XiRadical string + Ji string // 忌 + JiRadical string +} + +var zodiacList = map[string]Zodiac{ + ZodiacRat: { + Name: ZodiacRat, + Ji: `丁丛东为义书二亚亞亭亮人亿仁仃仅仇今介仍从仑仕付仙仟代以仪仰仲仳仵件价任份企伂伊伍休优伙会伟传伦伫伯估伴伶伸伺似但佇佈位低住佐佑何余佛作佟佣佩佯佰佳佶佼佾使侄來例侍侑侖供依侠侦侨侬侯係促俊俋俐俗保俞俟俠信俩俭修俱俸俾倆倍倏倖候倚倡倢倨倩倪倫值偃偅假偈偉偌做停健偩偮偵偶偿傅傌傑備傢傧储傭傲傳僅僇像僑僧僵價僾儀儂億儆儉儌儐儒償優儲光免兔全养冕冤冯冻凍刘劉勉勗化午卖南卧卯印卿叢台合吗味命哇唱善喜嗎嚥在圭地场址均坊坍坎块坚坛坜坝坞坠坡坦坪坵垄型垒垠垢垣垦垫埂埃城埒埔埕域埠執基堅堆堡堤堪堯堰報場堵塊塌塑塔塗塘塚塢填境墅墉墊墜增墟墡墩墾壁壅壇壎壑壕壘壟壢壤壩士壮壯壽备复夭央妃妈妹姜姬姿娅娩婚婭媄媽嬉孔孝宋宣宰寺寿封尧岱嶪巫差巴平幸庠张張彻徉律徐得從復微徵德徹志恙悠悻惊意慢执扬抑报拒挽提揚攸教日旦旨早旬旭时旺旻昀昂昆昇昊昌明昏易昙星映春昧昭是昱昶晁時晃晉晋晏晓晖晚晟晤普景晰晴晶智暄暉暖暗暮曆曇曉曙曜曝曦書曹曼曾會未朴杜来杨杩杰東杵柏柠柯柳柴样桓棚楊楠楼榪榴槽樓樣檸次欢欤欧欲欷欸款歇歌歐歟歡氧汀沫洋涂渼漫漾潛潜澲火灿炅炎炫炬炯炳炷為炽烈烊烨烯焉焕焯焰然煜煥照熊熙熹熾燁燕營燦燨牺犧珋珠瓷留监監祀祥禡竹笃篤糕紅綻繒繕繨红绽缮缯署罵羊美羔羕羚羟羡羢群羥羨義羬羯羱羲羶羹翔耀耵耿聊肖肯胡脩腾膳臣臥臺苎苣苧英茆茉荷莘莫菟营蓦蓨薑薘蝴行袁袂袋訂許詳諮議订议许详谘貸賣贷赤赫距路輓輝辉辛辜辞辭达迈迎运进远连迪选造逢連進逸運道達遠選邁邓那邦邬邱邹邺郁郎郑郝都鄒鄔鄧鄭鄯鄴酊酒醒釘鉀鉚鋅鍚鎂鎦鑑钉钾铆锌镁镏阳陈陳陽集鞑韃頂題顶题養香馬馮馳馴駁駐駒駕駛駟駱駿騁騎騏騫騮騰驀驅驊驕驗驚驛驞驟驥驪马驯驰驱驳驶驷驹驻驾驿骂骄骅骆骊骋验骏骐骑骝骞骤骥魯鮭鮮鲁鲑鲜鵬鹏`, + }, + ZodiacCow: { + Name: ZodiacCow, + Ji: `丁丙业丛丝丬主义习书些亭人亿什仁仃仅仇今介仑仕付仙仟代令以仪仰仲仳仵件价任份企伂伊伍休优伙会伟传伦伫伯估伴伶伸伺似但佇佈佌位低住佐佑佔何余佛作佟佣佩佯佰佳佶佼佾使侄來例侍侑侖供依侦侨侬侯係促俊俋俐俗保俟信俩俪俭修俱俸俾倆倍倏倖候倚倡倢倧倨倩倪倫值偃偅假偈偉偌做停健偩偮偵偶偿傅傌傑備傢傧储傭傲傳僅僇像僑僧僵價僾儀儂億儆儉儌儐儒償優儲儷光全养冈冯准刀刊刑划列刘则刚创初判別别到制刷券刻剀剂則剋前剑剛剧副剴創劃劇劉劍劑劝功加务动励劳势勇動勗勘務勝勞勢勤勵勸匕化午协卓協南占卧县叢古召叱合吗君吟呀味命唬唱善嗎嗣嚥国國场坎坏堤報場增墡壞备夏大天夭央奂奈奎奐奖妈妹姜姝娥婚媄媽嬉它宇宗审宣宰寥審将將岡岱岳峰峻崇崙崟嵘嶪嶸巫差希干年幸庄庇应庠廖式弗弟弥弦弭弯彌彎形彤彥彦彩彪彫彬彭彰影徉御德心必忆忌忍志忙忠快念忻忽怀态怎怔怕怖怜思怡急性怨怪总恃恆恋恐恕恙恢恣恩恬恰恳悄悅悉悍悔悖悟悠悦悬悲悸悻悽情惊惜惟惠惧惭惯想惶愁愃愈愉愍意愚愛感愠愤愧慄慇慈態慌慍慎慚慢慣慧慨慰慷慾憎憐憤憩憶憾懂懇應懋懷懸懼戀戈戎戏戕或战戡截戰戲戴扆扎托扬报挂指捺掛採提揚摎支攸教斌斤断斯斷旋日旦旨早旭时旺旻昀昂昆昇昊昌明昏易昕昙星映春昧昭是昱昶晁時晃晉晋晏晒晓晖晚晟晤晨普景晰晴晶智暄暉暖暗暢暮曆曇曉曙曜曝曦曬書曹曼曾會月有朋服朔朗望朝期朧未末朱杆杉来杨杩杰杵枝架柏柔柠柰栈栩样格桨桿梧棉棕棧棹椅楊楠業榪槳槽樣樱檸櫻欢欣欤欧欲欷欸款歇歌歐歟歡此比氧汀沫洋洧浅淺渼湾準漫漻漾潛潜澎澲灣炅炘炽烊烯照熾燕燨爱爿牆片版牋牌牍牒牘牙牺犧状狀獎玉王玕玖玛玟玡玥玨玫玮环现玲玳玺玼珀珊珍珏珑珖珠班珮珺現琁球琅理琉琏琐琥琦琨琪琮琯琳琴琼瑋瑙瑚瑛瑜瑞瑟瑣瑤瑩瑪瑰瑶璀璃璇璉璋璎璞璧璨環璽璿瓊瓏瓔甯畅番疆直矇矛矜矞矢知矩矫短矯碧示礼礽社祀祁祅祇祈祉祐祕祖祜祝神祟祠祥祭祯祷祸祺祿禁禄禅禍禎福禡禦禧禪禮禱禳秘穿竹笃篤米粽糕系糾紀紂約紅紆紇紈紉紋納紐紓純紗紘紙級紛紜素紡索紧紫紮細紳紵紹紼紾終絃組結絕絜絡絢給絨絪絮統絲絹絻綏經綖綜綠綢綦綪綬維綰綱網綴綵綸綺綻綽綾綿緁緆緇緊緋緒緗緘緞締緣編緩緬緯緲練緹緻縈縉縑縕縝縣縱縴縵縷總績繆繒織繕繚繞繡繨繩繪繫繯繳繹繼繽繾續纏纓纖纘纜纠纡红纣纤纥约级纨纪纫纬纭纯纱纲纳纵纶纷纸纹纺纽纾练组绅细织终绋绍绎经绒结绕绘给绚络绝统绢绣绥继绩绪绫续绮绯绰绳维绵绶绸综绽绾绿缀缁缃缄缅缆缇缈缎缓缔缕编缘缙缜缠缣缤缦缨缪缭缮缯缱缳缴缵网罕署罵羊美羔羕羚羟羡羢群羥羨義羬羯羱羲羶羹羿翁翎習翔翕翩翼耀耵耿聆肯育胖胜胞胡胤胥胧胭胶能脈脉脩腾膠膳臆臥臧芯苎苓苧茅茉莊莘莫莹萦蒋蓦蓨蔣蕙蕥薑薘藏蟉行衣补表衫衬衽衾衿袂袋袍袒袖袗被裁裂装裆裕裘裙補裝裟裤裱裴裸製複褊褋褌褐褓褙褚褛褪褫褲褸襁襟襠襯襴視视訂託許診試詳識議订议许识诊试详責貸費質责质贷费赤赫赶趕路躬軫輝轸辉辛辜辞辭达達邪邺郁郝郡鄢鄯鄴酊醒采釘鉀鋅錼鍚鎂鑫钉钾锌镁阳陀际陇陈陳陽際隴集雉零青鞑韃頂須題顏顶须题颜養馬馮馳馴駁駐駒駕駛駟駱駿騁騎騏騫騰驀驅驊驕驗驚驛驞驟驤驥驪马驯驰驱驳驶驷驹驻驾驿骂骄骅骆骊骋验骏骐骑骞骤骥骧魠魯鮮鲁鲜鷚鷸鹨鹬齒齡齿龄`, + }, + ZodiacTiger: { + Name: ZodiacTiger, + Ji: `一万三严丰临之乏乔乡书二亚亞亨享亭亮人亿仁仅仇今介仍从仑仓仕仗付仙仟代以仪仰仲仳仵件价任份企伂伊伍休优伙会伟传伦伯估伴伶伸伺似佃但佈位低住佐佑何余佛作佟佣佩佰佳佶佼佾使侄來例侍侏侑侖侗供依侠侣侦侨侬侯侶係促俊俋俏俐俗保俞俟俠信俦俩俪俭修俱俸俾倆倉倍倏候倚倡倢倧倨倩倪倫值偃偅假偈偉偌做健偩偮偵偶偿傅傌傑備傢傧储傭傲傳僅僇僎像僑僧僵價僾儀儂億儆儉儌儐儒儔償優儲儷兄光克全兰关兹冉再冏农几凡凤凯凰凱加勗募包化区區华单卖卢卧危卷叠口古句另只召可台史右叶号司各合吉同名后向吕吟含启吳吴吾呂呈告员周味呻命和咕咖咨咸品哈哑員哥哲唐唤售唯唱商啞啟啤善喉喚喜喧喬單嗣嘉嘱器嚥嚴囑回因团园固国图國園圖團圮场坚坤埏堂堅堠堤場增士壹壽处备复夢夭央奈如妃委姬姿娅娇娟婉婚婭媛媴嬌存孙季孫宗宛客宣宸容宾富寿小少尖尚尤尼尾屯岱崇川巡巫已巷巽帆幅幕平庄庭庸延廷建开异弓引弗弘弟张弥弦弭弯弱張強强弼彌彎当彪彭彷役彻往律徐徕得從徠御復循微徵德徹思悠慕慢懂战戰扬拒招挡捐捺提揚搭撰擋攸敦日旦旨早旭时旺旻昀昂昆昇昊昌明昏易昙星映春昧昭是昱昶显晁時晃晉晋晏晒晓晔晖晚晟晤晨普景晰晴晶智暄暉暖暗暢暮暹曄曆曇曉曙曜曝曦曬書曹曼曾替會朵杏来杨杰柏柯柰桐档桥桦梁梦棕棻楊榬槽樺橋檔次欢欤欧欲欷欸款歇歌歐歟歡毕民氾汎沣河治泓泛泡涎渭游湾溒溶漠漫潘潛潜澎灃灣炅炬炯烯照熔熙猿珅琬瑛瓷生甫田由甲申男甸町畅界畏畔留畢略畦番異畴當畸疆疇疊皮皱皺益监監盧知砷示礼礽社祀祁祅祇祈祉祐祕祖祜祝神祟祠祥祭祯祷祸祺祿禁禄禅禍禎福禦禧禪禮禱禳禹禾秀私秉秋种科秒秘租秦秩积称移稀稅程稍税稚稜種稱稳稷稹稼稽稿穆積穗穠穩穫竖米类粟粮粽精糕糖糧素細紳紹結給綜繒绅细绍结给综缯署羡羨耀胡脩臣臥臨臺臻艺艾芃芊芙芝芬芮花芳芷芸芹苍苏苑苒苓苔苗苣若苯英苹苻茂范茉茗茜茱茲茵茶茹荀荃荆草荊荏荐荞荡荷荻莅莆莉莊莎莒莓莘莞莩莫莱莲菁菇菊菖菩華菱菲菽萊萌萍萝萤萧萨萬萱萲落葉著葛董葵蒂蒋蒙蒞蒨蒲蒼蓁蓄蓉蓓蓝蓟蓦蓨蓬蓮蔓蔘蔚蔡蔣蔽蕃蕉蕎蕩蕭蕴薆薇薊薑薛薦薩薪薰薹藉藍藏藝藤藩藻蘇蘊蘋蘩蘭蘴蘿虎虔處虚虛號虫虹蛇蛉蛟蛮蛻蜀蜂蜒蜕蜜蜻蝉蝴蝶螈融螢蟬蠻袁袋袍袖襄視视訊誕誘諮諷謂譁譔讯讽诞诱谓谘谷豆豎豐貝貞財貢責貴貸費貿賀資賈賓賜賢賣賦賴贊贝贞贡财责贤贵贷贸费贺贾资赋赐赖赞起超距躬輝轅辉辕辰農边达迁迅过迈迎运近还进远违连迟迦迪述迷迺送适选逊逑递途逖通速造逢連週進逵逸逻遁遊運過道達違遙遜遞遠遣遥適遲遷選邀邁還邈邊邏邑邓邝邢那邦邬邱邵邹郁郎郝郭都鄉鄒鄔鄞鄧鄺酒酥醒鈿鉀鉅錼鍚鎔鎱鏵鑑钜钾钿铧門閃開閎閑間閔閨閩闆闕關门闪闲闳间闵闺闽阙阳际陈陳陽際靡頁頂項順須頌預頗頡頤題顏顛類顧顯页顶项顺须顾颂预颇颉颐题颜颠風风饌馔香驀驊骅高魯鲁鳳鳴鵑鸣鹃麥麦麵黃黄黍黎鼓龍龙`, + }, + ZodiacRabbit: { + Name: ZodiacRabbit, + Ji: `主丽乌习书买乾人亿仁仅仇今介仑仕付仙仟代令以仪仰仲仳仵件价任份企伂伊伍休优伙会伟传伥伦伯估伴伶伸伺似但佈位低住佐佑何余佛作佟佣佩佰佳佶佼佾使侄來例侍侑侖供依侠侦侨侬侯係促俊俋俐俗保俟俠信俩俪俭修俱俸俾倀倆倍倏候倚倡倢倨倩倪倫值偃偅假偈偉偌做健偩偮偵偶偿傅傌傑備傢傧储傭傲傳僅僇像僑僧僵價僾儀儂億儆儉儌儐儒償優儲儷光全农冠凤凰勗勝化医卖卧双君命咙唬唱嘱嚁嚥嚨囑场坏堤場增壞备大天太夭头婚婴媜嬰存宇安宝实宣宪宸宾寥實寶尤就山岗岱崔崗崷嵺嶍巫帐帝帳庆应庞廖张張录彪心必忆忌忍志忙忠快念忻忽怀态怅怎怔怕怖怜思怡急性怨怪恃恆恋恐恕恢恣恩恬恭息恰恳悄悅悉悍悒悔悖悟悠悦悬悲悵悸悽情惜惟惠惢惧惭惯想惶愁愃愈愉愍意愚愛感愠愤愧愫愿慄慇慈態慌慍慎慕慚慢慣慧慨慰慶慷慾憀憎憐憤憩憲憶憾懂懇應懋懷懸懼懿戀扬振提揚摎攸日旦旨早旬旭时旺旻昀昂昆昇昊昌明昏易昙星映春昧昭是昱显晁時晃晉晋晏晒晓晖晚晟晤晨普景晰晴晶智暄暉暑暖暗暢暮曆曇曉曙曜曝曦曬書曹曼曾會有朔望朝期朧来杨杰柏栖栩桢楊楨槢槽樛欢欤欧欲欷欸款歇歐歙歟歡氏民泷浓涨漉漫漲漻潁潛潜濃瀚瀧炅烏烯照煪熠熤燿爱玉王玖玛玥玫玮环现玲玺珀珊珍珑珝珠班珮珺現球琅理琉琏琐琦琨琪琳琴琼瑋瑙瑚瑛瑜瑞瑟瑣瑤瑩瑪瑰瑶璀璃璇璉璋璎璞璧璨環璽璿瓊瓏瓔甯畅矇碧祀祯禎秘稚穎穠笼簏籠素績繆繒纓纖纤绩缨缪缯署羽羿翁翃翅翊翌翎習翔翕翘翟翠翡翦翮翰翱翳翹翻翼耀聆肯育胖胜胞胡胤胥胧胭胶能脈脉脩腾膠膳臆臥苓苹莫莹莺蓨蔍蕙薑藋蘋袋袖袭裴褶襲西要覃詡譾诩谫豂貝貞財責貴買貸費貽賀賂賄資賈賓賜賠賣質賴賺購賽贝贞财责质购贵贷费贺贻贾贿赂资赐赔赖赚赛趯跃蹟躍輝轆轇辉辘辰農遒遗遺邬郁郑郦鄔鄭酈酉酊酋配酒酗酥酪酬醇醋醍醐醑醒醫醮金釧鈞鈴鉀鉻銀銮銳鋒鋹鋼錄錢錦錯鍊鍚鍵鎮鏡鐘鐵鑑鑽鑾钏钟钢钧钱钾铁铃铬银锋锐错锦键镇镜長长阳陇陽隴雀雄集雙零震青韔順領頤頭題顏願顟顧顯顺顾领颍颐颖题颜飂飛飞駐騛騰驻魯鲁鳥鳳鳴鴒鴗鴛鴦鴻鴿鵑鵠鵡鵬鵰鵲鶖鶧鶯鶴鶼鷚鷥鷲鷸鷹鷺鸐鸕鸚鸝鸞鸟鸣鸬鸯鸳鸶鸽鸾鸿鹂鹃鹄鹉鹊鹏鹣鹤鹦鹨鹫鹬鹭鹰鹿麒麓麗麝麟齡龄龍龐龔龙龚`, + }, + ZodiacDragon: { + Name: ZodiacDragon, + Ji: `万专东严丬丰临义乔乡二亚些亞亭亮人亿什仁仅仇介仑仕付仙仟代令以仪仰仲仳仵件价任份企伂伊伍休优伙伟传伦伯估伴伶伸伺似佃但佈佌位低住佐佑佔何余佛作佟佣佩佰佳佶佼佾使侄來例侍侑侖供依侦侨侬侯係促俊俋俐俗保俟信俩俪俭修俱俸俾倆倍倏候倚倢倨倩倪倫值偃偅假偈偉偌偏做健偩偮偵偶偿傅傌傑備傢傧储傭傮傲傳僅僇像僑僧僵價僾儀儂億儆儉儌儐儒償優儲儷允元兄充先克免兔兢全兰关兹养兽冈冉冊册再冏冕农冤冻准凍减刀刊刑划列刘则刚创删判別利刪别到制刷券刻剀剂則剋前剑剛剧副剴創劃劇劉劍劑劝功加务动助励劳势勇勉動勘務勞募勢勤勵勸匕化匠匡匮匯匱匹区匿區卉华协卓協单卖博占卢卧卯印卿厂厅厢厦厨叠口古句另召可台叱史右叶号司各合吉同名后向吕吟吠含启吳吴吾呀呂呈告员周味命和咕咖咨咸品哈員哥哭哲唐唤售唯唱商問啟啤善喚喜喧喬單嗣嘈嘉嘱器嚴囑回因团园国图圃國園圖團坏坚城埔域堂堅塞壞士壮壯壹壽处备夢夭央奇奖如姍委姗姜姬姿威娅娇娟娩婭嬌孱宁它宅安宋完宏宓官宙宛宜宝实宠审客宣室宥宪宫宬宮宰宴家宸容宽宾宿寂寄寅密寇富寓寞察寥實寧審寬寰寵寶寻寿專尋小少尖尚尤就尼尾局层居屆屈届屋屏属屠屡屢屣層履屬屯山屹岌岑岗岚岛岡岩岭岱岳岷岸峋峒峙峡峦峨峰島峸峻峽崆崇崑崔崗崙崧崴嵐嵘嵩嶸嶺嶽巍巒巖川州巡巢工巧巫巳巴巷巽席幅幕干平广庄庆庇序库应底庖店庙庚府庞度座庫庭庵庶康庸廂廈廉廊廓廕廖廚廟廠廣廩廪廳延廷建开异式弓引弗弘弟张弥弦弭弯弱張強强弼彌彎当彗彧彪彭心必忆忌忍志忙忠快念忻忽怀态怎怔怕怖怜思怡急性怨怪恃恆恋恐恕恢恣恩恬息恰恳悄悅悉悍悔悖悟悠悦悬悲悶悸悽情惊惑惜惟惠惧惭惯想惶愁愃愈愉愍意愚愛感愠愤愧慄慇慈態慌慍慎慕慚慢慣慧慨慰慶慷慾憎憐憤憩憲憶憾懂懇應懋懷懸懼懿戀戈戊戌戍戎戏成戕或战戡截戫戰戲戴戶户房所扁扈扉托抑拒招指挡挽捐捨搭擋支攸敦斌斤断斯新斷旨旮昂春昭晚晟暮曲曹服朗朧木朴权杆杏杜束来杰東松林枝柔柯柳柴柵栅栏桐桓档桥桦桨桿梁梦棚棫棻楚楼榕榴槳槽樓樺橋檔欄權次欢欣欤欧欲欷欸款歇歌歐歟歡此武比毕毧汇沣沪河治泓洞洲浅浔浦涛润淢淺減渭湾準滅滬演漕漠潘潤潯潺澎澜濤瀾灃灣灭炘炯炽然照熔熙熾燃爱爿牆片版牋牌牍牒牘牙牢犀犬状犹狀狂狄狐狗狘狨狩独狮狱猎猛猜猭献猴猶猷猿獂獄獅獎獨獲獵獸獻玕玡玮玼珊珋瑊瑋瑛瓷甫甯田由甲男甸界畎畏畔留畢略異畴當畸疆疇疊益监盛監盧直相矇矛矜矞矢知矩矫短矯礼禅福禪禮禾秀私秉秋种科秒秘租秦秩积称移稀稅程稍税稚稜稢種稱稳稷稹稼稽稿穆積穗穩穫穴究穷空穿突窃窈窍窑窕窗窘窜窟窥窦窮窯窺竄竅竇竊竖竿符箴篇米类粟粮精糊糕糖糟糧細紹結給絨編織纖纤细织绍绒结给编罔罕羊美羚羡羢群羨義羬羲翩聊聞聿肇肖肩胖胞胡胤胥胧胭胶能脈脉脩脯膠膳膺臆臣臥臧臨臺臻舍舒舖艮良艰艱艺艾芃芊芙芝芬花芳芸芽苍苏苑苓苔苗苣若苯英苹苻茂范茅茆茉茙茲茵茶茹荀荆草荊荏荐荞荡荷荻莅莆莉莊莎莒莓莘莞莩莫莱莲获莸菁菇菊菟菩華菱菲萊萌萍萝萤萧萬萱萲落葉葛董葴葵蒂蒋蒙蒞蒲蒼蓁蓄蓉蓓蓝蓦蓨蓬蓮蔓蔘蔚蔡蔣蔽蕃蕉蕊蕎蕕蕙蕥蕩蕭蕴薆薇薑薦薪薰藉藍藏藝藤藩藻蘇蘊蘋蘩蘭蘴蘿虎虔處號虹蜀蜜蝉蝴蝶融螢蟬袋装裕裝襄託試誘誠諮諴謂譁識识试诚诱谓谘谷豆豊豎豐豪貸費資賓賢賣質賽贤质贷费资赛赶超越趕距躬輓輔辅農达迁迈迎运近还进远连迪迷选通造逢連進逵逸運遍道達遠遭遷選邁還邑邓邝邢那邦邪邰邱邵郁郎郑郕郭都鄉鄧鄭鄺酥醴鈿鉀鉅鉚鉞銅鋸鍼鎔鎦鏵鑑钜钺钾钿铆铜铧锯镏門開閎閔閣閨閩閱闆闈闊闕闖關闡闢门问闯闱闳闵闷闺闻闽阁阅阐阔阙陀陇陈陳隇隴雉雪靡頤類颐養馗駥騙騮驀驊驚骅骗骝高魠鳴鷢鷸鷹鸣鹬鹰麥麦麵黃黄黍黎默鼓齒齡齿龄龐`, + }, + ZodiacSnake: { + Name: ZodiacSnake, + Ji: `万丘丞丬丰久乏书争亏些亥亮人亿什仁仅仇今介仍仑仓仕付仙仟代令以仪仰仲仳仵件价任份企伂伊伍休伕众优伙会伟传伦伯估伴伶伸伺似但佈佌位低住佐佑佔何佘余佛作佟佣佩佰佳佶佼佾使侄來例侍侑侖供依侠侦侨侬侯係促俊俋俏俐俗保俟俠信俩俪俭修俱俸俾倆倉倍倏候倚倡倢倨倩倪倫值偃偅假偈偉偌做健偩偮偵偶偿傅傌傑備傢傧储催傭傲傳僅僇像僑僧僵價僾儀儂億儆儉儌儐儒償優儲儷允光入全公兰兹冈冰冲决况冷冻准凉凌凍几凯凱函刀刊刑划列刘则刚创判別利别到制刷券刻剀剂則剋前剑剛剧副剴創劃劇劉劍劑劝功加务动励劳势動勗勘務勞募勢勤勳勵勸匕化北匯卉华协卓協占卢卧卿参參又及友双叔取受变叛召叱号呀命和咳唬唱嚎场堤場塗增壕壮壯壹处备外多够夠夢夥夭央奖委威婚嫁子孔存孙孝孟季孩孫它宣家寅密将將少尔山岂岑岗岚岛岡岩岭岱岳岸峥峰島峻崇崔崖崗崙崢崧嵐嵘嵩嶸嶺嶽巖巫幏幕干平幹幼幾广庄庇廊廣式引弟弥弦弭弱弼彌录彗彪彭悠愛慕慢慮懂戈戎戏戕或戡截戲戴托扬承披拯指挣据掙提揚搋摧據支收攸改攻救敝敢散数數文斤断斯新斷日旦旨早旬旭时旺旻昀昂昆昇昊昌明昏易昕昙星映春昧昭是昱昶昺晁時晃晉晋晏晒晓晔晖晚晟晤普景晰晴晶智暄暉暖暗暢暮暴曄曆曇曉曙曜曦曬書曹曼曾會朦机杆来杨杰杶枝柏染柔树核根桑桨桿梁梦棻楊槳槽樹機橡檖檬次欢欣欤欧欲欷欸款歇歌歐歟歡此步毅比水永氾求汇汉汎汐汝江池汤汪汯汰汲汴汹決沂沅沈沉沍沐沖沙沛沣沥沧沪河沸油治沼沿況泉泊泓法泛泞泠波注泰泳泽洁洋洗洛洞津洪洲洳洵洶洸洺活洽派流浅浈浊济浒浓浙浚浤浦浩浪浮海浸涂涅消涌涛涟涣涤润涨液涵涼淀淇淋淑淙淞淡淥淦淨淩深淳淵混淺添淼清渊渌渙渡渤温港渱游渺渼湃湄湖湛湞湟湧湯湾湿溎源準溥溪溫溱溶滄滋滌滔滚满滥滨滬滸滾滿漂漆漓演漠漢漣漪漫漲漳潔潘潛潜潢潤潭潮澄澎澤澱澲激濁濃濈濕濘濟濠濡濤濫濬濯濱瀚瀝瀰瀴灃灏灝灣炅炉炖炽烯照熾燉燧爐爭爱父爽爾爿牆片版牋牌牒牟状狀猪猭献獎獻玕玡玼球琅琉琥瑑瑛瑯璲畅皓皮益盧直眾睁睜矛矜矞矢矣知矩矫短矯祀祿禄禠禭禹禾秀私秉秋种科秒秘租秦秩积称移稀稅程稍税稚稜種稱稷稹稻稼稽稿穆積穗穟穠穿立竖端竿笋筍筝箏範篆籙米粉粟粮粲精糕糖糠糧紘級素紫絃絨綱緣繒織纂级纲织绒缘缯罕署羡羨耀聚肤能脩膚臥臧臻艮良艰艱艺艾芃芊芋芙芝芥芦芬芮花芷芸芽苏苑苒苓苔苯英苹苻苾茂范茅茉茗茲茶茹荀荃荆草荊荏荞荡荷荻莅莆莉莊莎莒莓莘莞莩莫菇菊華菱菲萌萍萝萧萬萱萲落葛董葵蒂蒋蒙蒞蒨蒲蓓蓝蓦蓨蓫蓬蔓蔘蔚蔡蔣蔽蕉蕎蕓蕥蕩蕭蕴薰藉藍藏藝藤藩蘆蘇蘊蘋蘩蘭蘴蘿虎虑虔處虚虛虞號虢虧蝝袋袖被装裘裝製襐託註試該誘諍變试诤该诱豆豈豎豐豚象豢豥豪豫豬貸質质贷赶趕躬輝辉迷逐逑递遂遇遊遞遯遽邃邪邱郎酒酥鈍鉀銀鋐鋼錄錚鍚鎵鏵鐌鐩钝钢钾铧铮银镓閎闊闳阔阳陀陟陽隧隶隸雉雙雯頓題顱顿颅题風风香驀骸魠魯鲁鴻鷸鸿鹬麥麦黃黄黍黎黑鼓齒齡齿龄`, + }, + ZodiacHorse: { + Name: ZodiacHorse, + Ji: `一丑丞严临乃乔书乳予二亚亞产享仁从仔仿伙会佃但倡允公其冀冈冉再冬冰冲决况冷冻准凉凌凍凑几函勃勗勝北匯单卖厚参參又及友双叔取受变叛叠台后吕启呂告咏咖咭品哈哥唱啟喜喬單嘉嘻器嚥嚴场坏坚堅堤場塗增墩壞壮壯壽复夕外多够夠夥好妙妞姓姬姿娅娸婚婭子孔孕字存孙孚孛孜孝孟季孤学孪孫孰孳學孺孿宁宣宥宪富寧寿尊少尔山岌岗岡岭岳岷峒峡峥峭峻峽崇崎崑崗崙崢崧嵩嶺嶽巍幅平年幼幾庆应庸异当录彷役彻彼往征很律後徐徒得從御復循微徵德徹心必忆忌忍志忙忠快念忻忽怀态怎怔怕怖怜思怡急性怨怪恃恆恋恐恕恢恣恩恬恭息恰恳悄悅悉悍悔悖悟悠悦悬悲悸悽情惇惜惟惠惢惧惭惯想惶愁愃愈愉愍意愚愛感愠愤愧慄慇慈態慌慍慎慕慚慢慣慧慨慰慶慷慾憎憐憤憩憲憶憾懂懇應懋懷懸懼戀战戰扬扭承抒披拒拯挡提揚擋收改攻救教敝敢散敦数數文日旦旨早旭时旺旻昀昂昆昇昊昌明昏易昙星映春昧昭是昶晁時晃晉晋晏晒晓晖晚晤普景晰晴晶智暄暉暖暗暢暮暴曆曇曉曙曜曝曦曬書曹曼曾會月有朋服朔望朝期朧机李杨柏染柵栅桑档棋椅楊槽機檔次步毕水永氾汀求汇汉汎汐汕汛汝江池汤汪汯汰汲汴汶汹決汽汾沂沅沈沉沍沐沖沙沛沥沧沪河沸油治沼沿況泉泊泓法泛泞泠波注泰泳泽洁洋洗洛津洪洲洳洵洶洺活洽派流浅浈浊济浒浓浙浚浡浤浦浩浪浮海浸涂涅消涌涛涟涣涤润涨液涵涼淀淇淋淑淙淞淡淥淦淨淩淮深淳淵混淺添淼清渊渌渙渡渤温渭港渱游渺渼湃湄湊湖湘湛湞湟湣湧湯湾湿溎源準溥溪溫溱溶滄滋滌滔滚满滤滥滨滬滸滾滿漂漆漓演漢漣漪漫漲漳潔潘潛潜潢潤潭潮澄澎澤澱澲澳激濁濃濈濕濘濟濠濡濤濫濬濯濱濾瀑瀚瀝瀰瀴灏灝灣炅烯煦照燕爱父爽爾牛牟牡牢牧物牲牴牵特牽犀犁犊犒犢玥环球琉琦琪環瓷生產甥甫甯田由甲男甸町画畅界畏畔留畛畢略畫異畴當畸畿疆疇疊皓皮监監眸矇矣碁祀祺福禦禹私秘竑範籐籙米籽粉粒粥粲粹精糠紐紘級細絃繒纂纖纤级纽细缯署羞羡羨翃肯育背胖胜胞胡胤胥胧胭胶能脈脉腾膠膳臆臨臺艾苣范荡莅莎莫蒞蓄蕙蕩薇薑藤藩袋袖被裘註詠誌誥諄諮謂變诰谆谓谘賣距迟逑造遇遊遲郁郜郭酒醇醒醜釐鈕鈿鉀鉅鋐錄鍚鑑钜钮钾钿閎闊闳阔阳陇陈陟陳陽隆隴隶隸雙雯靠預題预题駐駿騎騏騰驥驻骏骐骑骥魯鲁鴻鵠鸿鹄麵黍黎黑`, + }, + ZodiacSheep: { + Name: ZodiacSheep, + Ji: `一丑丝丞丬主书乳予二些产享什仁今仔代会伯伶但佌佔作例依係修倡倧光冀冬冰冲决况冶冷冻准凉凌凍凑函刀刊刑划列刘则刚创初判別别到制刷券刻剀剂則剋前剑剛剧副剴創劃劇劉劍劑劝功加务动励劳势勃動勗勘務勝勞勢勤勳勵勸匕北匯十协協卖占厚县古召叱吉君呀告咏唐唬唱嚥国國场坎坏堤場塗增墩壞壮壯壹壽大天太夫央夷夹夾奂奇奈奉奋奎奏奐奕奖套奘奚奮好妞姓姬姿娅婚婭子孔孕字存孙孚孛孜孝孟季孤学孩孪孫孰孳學孺孿它宝审宣宪寥寧審寶寿将將尊崇巨巾市布帅帆师希帛帜帝帥帧師席常幀幟干年幹庄庆庇应康廖式弓弗弟张弥弭弯張彌彎录形彤彥彦彩彪彫彬彭彰影御心必忆忌忍忖志忘忙忠忡快忱念忸忻忽怀态怎怔怕怖怜思怡急性怨怩怪总恂恃恆恋恍恐恕恢恣恩恬恭息恰恳悄悅悉悌悍悒悔悖悟悠悦悬悲悸悽情惇惕惜惟惠惧惭惯想惶愁愃愈愉愍意愚愛感愠愤愧愫慄慇慈態慌慍慎慕慚慢慣慧慨慰慶慷慾憎憐憤憩憲憶憾懂懇應懋懷懸懼懿戀戈戌戎戏成戕或战戡截戰戲戴扆扎托扬扭承抒拒拯挂指捺掛採提揚摎支救教敦文斤断斯斷旋日旦旨早旭时旺旻昀昂昆昇昊昌明昏易昕昙星映春昧昭是昶晁時晃晉晋晏晒晓晖晚晤晨普景晰晴晶智暄暉暖暗暢暧暮暴曆曇曉曖曙曜曝曦曬書曹曼曾會有朋服朔朗望朝期朧杆杉李杨枝架柏染柔柰栩桨桿棕椅楊槳槽樱櫻次欣此比水永求汇汉汎汐汕汝江池汤汪汯汰汲汴汶汹決汽沂沅沈沉沍沐沖沙沛沣沥沧沪河沸油治沼沿況泉泊泓法泛泞泠波注泰泳泽洁洋洗洛津洪洲洳洵洶洸洺活洽派流浅浈浊济浒浓浙浡浤浦浩浪浮海浸涂涅消涌涛涟涣涤润涨液涵涼淀淇淋淑淙淞淡淥淦淨淩淮深淳淵混淺添淼清渊渌渙渡渤温港渱游渺渼湃湄湊湖湘湛湞湟湣湧湯湾湿溎源準溥溪溫溱溶滄滋滌滔滕满滤滥滨滬滸滿漂漆漓演漢漣漪漫漲漳漻潔潘潛潜潞潢潤潭潮澄澈澎澤澱澲澳激濁濃濈濕濘濟濠濡濤濫濬濯濱濾瀑瀚瀝瀰瀴灃灏灝灣炅炜炬炽烯煒照熾爱爿牆片版牋牌牍牒牘牙牛牟牡牢牧物牲牴牵特牽犀犁犊犒犢状犹狀狄狐独狮猛献猶猷獅獎獨獲獻玉王玕玖玟玠玡玥玦玨玫玮环现玲玳玺玼珀珅珊珍珏珑珠珣珩班珮珲珺現琁球琅理琇琉琏琐琛琥琦琨琪琬琮琰琳琴琼琿瑄瑋瑗瑙瑚瑛瑜瑞瑟瑣瑤瑩瑯瑰瑶瑾璀璃璇璉璋璎璞璟璧璨環璽璿瓊瓏瓔瓷生產甥甯畅番疆皓皿监監直眸矇矛矜矞矢知矩矫短矯碧示礼礽社祀祁祅祇祈祉祐祓祕祖祚祜祝神祟祠祥祭祯祷祸祺祿禀禁禄禅禍禎福禦禧禪禮禱禳秘稟穎穠穿竿等範籙籽粽糠系糾紀紂約紅紆紇紈紉紋納紐紓純紗紘紙級紛紜素紡索紧紫紮細紳紵紹紼紾終絃組結絕絜絡絢給絨絪絮統絲絹絻綏經綖綜綠綢綦綪綬維綰綱網綴綵綸綺綻綽綾綿緁緆緇緊緋緒緘緞締緣編緩緬緯緲練緻縈縉縑縕縝縣縱縴縵縷總績繆繈繒織繕繚繞繡繩繪繫繳繹繼繽繾續纏纓纖纘纜纠纡红纣纤纥约级纨纪纫纬纭纯纱纲纳纵纶纷纸纹纺纽纾练组绅细织终绋绍绎经绒结绕绘给绚络绝统绢绣绥继绩绪绫续绮绯绰绳维绵绶绸综绽绾绿缀缁缄缅缆缈缎缓缔缕编缘缙缜缠缣缤缦缨缪缭缮缯缱缴缵网罕署美羚羞羡群羨羿翁翎翕翩翼耀聆聪聰股肯育肴背胖胜胞胡胤胥胧胭胶能脈脉脩膠膳臆臧苓苣范茅荡莅莉莊莎莫获莹萦蒋蒞蔣蕙蕥蕩薑藏蟉衣补表衫衬衽衾衿袁袂袋袍袒袖袗被裁裂装裆裕裘裙補裝裟裤裱裴裸製複褊褋褌褐褓褙褚褛褪褫褲褸襁襄襟襠襯襴視视託診註詠試誌誥諄諮識识诊试诰谆谘責費賣質责质费赶趕距躬車軫輝车轸辉辰迟逑造遊遲邪郁郑郜郡郭鄭酉酒醇醒醜采釐金鈕鉀鉅錄錼鍚鑑钜钮钾長长閨闊闺阔阳陀际陇陈陳陽隆際隴隶隸雉零靠須預頤題顏须预颐颖题颜魠魯鲁鴻鵠鷚鷸鸿鹄鹨鹬黍黎黑齒齡齿龄`, + }, + ZodiacMonkey: { + Name: ZodiacMonkey, + Ji: `丘丬丰争亏些亥什仙众佃佌佔佣例傢催傭像冈冉再准凤凯凱刀刊刑划列刘则刚判別利别到制刷券刻剀剂則剋前剑剛剧副剴劃劇劉劍劑劝功加务动助励劳势勇動勘務勞勢勵勸匕医午卉协卓協单占卢卿叠古召叱号呀和咳唬單嚎嚥场場壕壹处奖委威婚嫁孩它家寅密将將屯山岂岑岗岚岛岡岩岭岱岳岸峥峰島峻崇崔崖崗崙崢崧嵐嵩嶺嶽巖幅幏干平幹幼庄庇庐庸廊廬异式弓引弗弘弟张弥弦弭弯張強强弼彌彎当彗彪彭忻思慢慮戈戎戏戕或战戡截戰戲戴托指挡挣据掙提搋摧擋據支斤断斯斷旨旻昕昙晒晓普晰暮曆曇曉曙曜曝曦曬朗朦杆杶枝柔核档桨桿梁槳槽橡檔檖檬欣此毅比毕沣泓浅浪涌淨淺渭湧準滤演漫潘潛潜澎濠濾灃炅炉炖炘炽烯熾燉燧爐爭爿牆片版牋牌牍牒牘牙状狀狮猪猭献獅獎獻玕玡玼琅琥瑑瑯璲甫田由甲申男甸画界畏畔留畢略番畫異畴當畸疆疇疊皮盂监盘盛盟監盤盧眾睁睜矛矜矞矢矩矫短矯祀福禠禭禾秀私秉秋种科秒秘租秩积称移稀稅程稍税稚稜種稱稳稷稹稻稼稽稿穀積穗穟穩穫穿竖竿筝箏篆米类粉粗粟粮粲粹精糕糖糧素紫細絨綱緣繒織繸纲细织绒缘缯罕署耀肤能膚臧臻艮良艰艱芦芽苏茅莉莊莫莺蒋蒙蓄蓫蔣蕥薑薪藏藩蘆蘇蘴虎虑虔處虚虛虞號虢虧蝝袖装裝製襐襚要覃託試該誘諍謂试诤该诱谓豆豈豎豐豚象豢豥豪豫豬豹貂貌費费赶趕躬近迷逐递遂遞遯遽邃邪邱郎郑鄭配酒酥醒醫金釗釧鈍鈔鈞鈴鈺鈿鉀鉛銀銅銘銳鋒鋼錕錚錢錦錫鍛鍵鍼鍾鎮鎵鏈鏔鏗鏞鏡鏢鐌鐘鐩鐵鐸鑑钊钏钝钞钟钢钧钰钱钾钿铁铃铅铎铜铭铮银链铿锋锐锟锡锦键锺锻镇镓镖镛镜阳陀陈陳陽隧雉静靜靡頓題類顱顿颅题風风駐驻骸魠魯鲁鳳鳴鴛鴻鵬鶯鶴鷸鷹鸚鸞鸣鸳鸾鸿鹏鹤鹦鹬鹰麥麦麵黍黎鼓齒齿`, + }, + ZodiacChicken: { + Name: ZodiacChicken, + Ji: `一东严丬乔乡书些亥亮人什仇代仰伏会伯伶但佌佔例倡兀允元兄充先克兌免兑兔共兽冕冤冻准凍减刀刊刑划列刘则刚创判別利别到制刷券刻剀剂則剋前剑剛剧副剴創劃劇劉劍劑力劝功加务动助劳势勇勉動勗勘務勝勞勢勤勳勸匕北卉协協占卯印卿友古召叱吕君吠启呀呂咸品哑哥哭唬唱啞啟喜喬嘉器嚥嚴国國场坎坏城域場壞壮壯天太夫央夹夾奂奇奉奋奎奏奐奕奖奚奮威娥娩婚子它宋宏宪宬寧将將岳峸崴嶽帝干幹庄庇应异式弗弘弟弥弦弭弯弼彌彎形彧心必忆忌忍志忙忠快念忸忻忽怀态怎怔怕怖怜思怡急性怨怪恃恆恋恐恕恢恣恩恬恭恰恳悄悅悉悍悒悔悖悟悠悦悬悲悸悽情惇惑惜惟惠惧惭惯想惶愁愃愈愉愍意愚愛感愠愤愧慄慇慈態慌慍慎慚慢慣慧慨慰慷慾憎憐憤憩憲憶憾懂懇應懋懷懸懼懿戀戈戊戍戎戏成戕或战戡截戫戰戲戴手托抑指挽提支文斌斤断斯斷旦旨旭旮时旺旻昀昂昆昇昊昌明昏易昙春昧昭晁時晃晉晋晏晒晓晚晟晤普景晰晶智暄暖暗暢暮曇曉曙曝曦曬書曼曾會月有朋服朔朗望朝期朧木本朴权杆杜杨東松枝柏柔柯柳柴栋桓桨桿棚棟棫楊楼榕榴槳槽樓樱樸櫻權欣此武比毧泓浅浤淢淺清減湖湣湾準滅滕漫潛潜灣灭炅炘炽烘烯然照熾燃爱爿牆片版牋牌牍牒牘牙犬状犹狀狂狄狐狗狘狨狩独狮狱猎猛猜猭献猴猶猷猿獂獄獅獎獨獲獵獸獻玉王玕玖玛玟玡玥玫玮环现玲玳玺玼珀珊珋珍珑珠班珺現琁球琅理琉琏琐琥琦琨琪琰琴琼瑀瑊瑋瑙瑚瑛瑜瑞瑟瑣瑤瑩瑪瑯瑰瑶瑷璀璃璇璉璎璞璦璧璨環璽璿瓊瓏瓔甯申畅畎留異盛直相矇矛矜矞矢知矩矫短矯石碧示祀秋秘稢究穿突竿箴糊系素紫絨綻績繒織繕纖纤织绒绩绽缮缯罕署美羚羢群羬聆聊肖肯育肴胖胜胞胡胤胥胧胭胶能脈脉脩腾膠膳臆臧艾芙芽苓茂茅茆茙茯荻莉莊莫获莸莹菟葴蒋蔣蕕蕙蕥薑藏虔蝴袖装裝製託試誌誠諴識识试诚責費質责质费赶越趕躬輓迎逸邪郁郑郕郡鄉鄭酉配酒醍醒金釗鈞鈴鉀鉚鉞銀銘銳鋒錢鍚鍼鍾鎦鎮鐘鑑钊钟钧钱钺钾铃铆铭银锋锐锺镇镏阳陀陇陽隇隴雄雉雯零青題题馗駐駥騮騰驻骝高魠魯鲁鵬鷢鷸鹏鹬鹹默齒齡齿龄`, + }, + ZodiacDog: { + Name: ZodiacDog, + Ji: `业丞丬丰丽义之乌九习书买云些什仁从代会伥佃但佌佔例侦侬俪倀倡偵僇儂儷光冉农冰冲决况冷冻准凉凌凍凤函刀刊刑划列刘则刚判別利别到制刷券刻剀剂則剋前剑剛剧副剴劃劇劉劍劑劝功加务动劳势動勗勘務勞勢勤勳勸匕北匯医卉协協单卖博占双叠古召叱呀和咏咙唱單嚁嚥嚨场場塗增壹复头奖妹委婚婪婴媜嬰子季它安宝实宠宸宾寥實寵寶尤就岷崔崷嵺嶍帐帳幅干幹广庄庇庞庸廖廣异式弓引弗弟张弥弭弯張強强弼彌彎当录彭彻律徐得從復微德徹怅恭悵愿慢慷憀戈戎戏戕或战戡截戰戲戴托扬批承把拯指挡振提揚摎擋支救文斤断斯新斷日旦旨早旭时旺旻昀昂昆昇昊昌明昏易昕昙星映春昧昭是昱昶显晁時晃晉晋晏晒晖晚晤晨普景晰晴晶智暄暉暖暗暢暮暴曆曇曙曜曝曦曨曬曰書曹曼曾會朧木本机权杆杉李杏材村杖杜杞束杨杭杳极构枋析枚果枝枫架柏柑染柔柚查柯柱柴柿标栊栋栏树栖栗校栩株样核根格桀桂桃桐桑桓桔桢档桥桨桿梁梅梓梗梧梨梭梵检棉棋棕棘棚棟棨棲棹椅植椰楊楓楨業極楷榈榔榕榛榜榞榴構槐槙槟槢槳槽樑標樛樟模樣横樱樵樹橋橙機橫檀檔檢檳櫂櫚櫳櫻欄權次欣欽歙此比毕氏民水永求汇汉汎汐汝江池汤汪汯汰汲汴汹決沂沅沈沉沍沐沖沙沛沣沥沧沪河沸油治沼沿況泉泊泓法泛泞泠波注泰泳泷泽洁洋洗洛津洪洲洳洵洶洺活洽派流浅浈浊济浒浓浙浤浦浩浪浮海浸涂涅消涌涑涛涟涤润涨液涵涼淀淇淋淑淙淞淡淥淨淩深淳淵混淺添淼渊渌渡渤温渭港渱游渺渼湃湄湖湘湛湞湟湧湯湾湿溎源準溥溪溫溱溶滄滋滌滔满滤滥滨滬滸滿漂漆漉漓演漢漣漪漫漲漳漻潁潔潘潛潜潢潤潭潮澄澎澤澱澲激濁濃濈濕濘濟濠濡濤濫濬濯濱濾瀑瀚瀝瀧瀰瀴灃灏灝灣炅炘炽烏烯煪熊熠熤熾燿爿牆片版牋牌牍牒牘牙状犹狀狄狐独狭狹猛猜猶獎獨玕玡玼珑珝球琳璎瓏瓔甫田由甲申男甸画畅界畏畔留畢略番畫異畴當畸疆疇疊皓益直相真矛矜矞矢矩矫短矯祀祯祿禄禎福禾秀私秉秋种科秒秘租秦秩积称移稀稅程稍税稚稜種稱稳稷稹稼稽稿穆積穎穗穠穩穫穿竖竿笼筛範篩簏籙籠类粟粮精糕糖糠糧紫細絨繆繒纓细绒缨缪缯罕署羡群羨義羽羿翁翃翅翊翌翎習翔翕翘翟翠翡翦翮翰翱翳翹翺翻翼耀胧臧臻芽苏苹范茅茜荡莅莉莊莎莫莺蒋蒞蓄蔍蔣蕥蕩薑薪藋藏藩蘇蘋蘴袖袭装裘裝裴製褶襲託註詠詡試詩誘誼諦謂識譾识试诗诩诱谊谓谛谫豂豆豎豐貝貞財貢貫責貴買費貽貿賀賂賄資賈賓賜賠賢賣賦質賴賺購賽贊贝贞贡财责贤质购贯贵贸费贺贻贾贿赂资赋赐赔赖赚赛赞赶趕趯跃蹟躍躬轆轇辘辰辱農近迷逑遊遒遗遺邪邬郑郦鄔鄭酈酉酊酋配酒酗酥酪酬酷醇醋醐醑醒醫醮醴鈿鉀鋹錄鍚钦钾钿長长闊阔阳陀陇陈陳陽隴隶隸雀雄雅集雉雙雨雲震霖靡韔順領頤頭題顏願類顟顧顯顺顾领颍颐颖题颜飂飛飞香騛魠魯鲁鳥鳳鳴鴒鴗鴛鴦鴻鴿鵑鵝鵠鵡鵬鵰鵲鶖鶧鶯鶴鶼鷚鷥鷲鷸鷹鷺鸐鸕鸚鸝鸞鸟鸣鸬鸯鸳鸶鸽鸾鸿鹂鹃鹄鹅鹉鹊鹏鹣鹤鹦鹨鹫鹬鹭鹰鹿麒麓麗麝麟麥麦麵黃黄黍黎黑鼓齒齡齿龄龍龐龔龕龙龚龛`, + }, + ZodiacPig: { + Name: ZodiacPig, + Xi: "", + XiRadical: "", + Ji: `一乙几刀力匕三上凡也土大川己已巳干弓之仁什今天太巴引戈支斤日比片牙王爿主乏代刊加功包卉占古召叱央它市布平弘弗旦玉申皮矛矢石示氾光列刑危夷妃州帆式戎早旨旭朵此虫血衣圮托汎伸佔但伯伶别判君呀坎壮希庇廷弟彤形杉系邑礽玖些依例刻券刷到制协卓卷呻坤奇奈宗宛延弦或戕旺易昌昆昂明昀昏昕昊昇枝欣版状直知社祀祁纠初采长忻玕佌旻炘炅罕泓泡泛玫表亮侯係前剋则勇垣奐宣巷帝帅建弭彦春昭映昧是星昱架柏矜祉祈祇禹穿竿紂红纪纫紇约紆羿虹衫风玡玠柰祅紈迅巡芝芽指珊玲珍珀玳倡候修刚奚孙家差席师庭时晋晏晃晁书核栩矩砷祕祐祠祟祖神祝祚纺纱纹素索纯纽级紜纳纸纷翁蚩袁袂衽讯託起躬珅倧扆祜紘紓衿衾邪邦那迎返近范茅苓班琉珮珠乾健凰副务勘曼唱唬婉婚将崇常张强彬彩彫旋晚晤晨曹勗桿烯祥票祭絃统扎绍紼细绅组终羚翌翎聆彪蛉被袒袖袍袋责玼珩埏紵紾袗邵述迦迪能情掛採捺涎浅琅球理现剴创劳喉场堤堠媛嵐巽帧弼彭斯普晰晴晶景智曾棕牌番短结绒绝紫絮丝络给绚絳翕蛟裁裂视诊费贵须邰琁珺牋矞絪絜軫陀郎郁送迷迺莫庄莉提扬琪琳琥琴琦琨勤势园戡暗暉暖暄会杨枫照煜牒祺禄禁经绢绥群蜀蛾蜕蜂裟裙补裘装裕试钾雉零琬琰琝媴絻郡通连速造透逢途準猿瑚瑟瑞瑙瑛瑜署僎划寥廖彰截畅碧禎福祸粽绽綰综绰綾绿紧缀网纲綺绸绵綵纶维绪緇綬臧蜜蜻裳裴裹裸製褚豪宾赶闽溒瑄瑋榬綪緁緆緋綖綦蜒裱魠郭都週逸进慢漫瑶琐玛瑰剧刘剑增审影暮槽桨毅奖莹稼缔练纬緻缄缅编缘缎缓緲緹翩蝴蝶褐复褓褊诞赏质辉驻鲁齿摎漻褌褋褙陈乡运游道达违遁撰潜澎璋璃瑾璀剂勋战历晓曇炽御縑縈县縝縉萤融褪裤褫讽醒骇璇璉縕螈錼阳邹远逊遣遥递蒋璟璞励弥戏戴曙墙矫禧禪绩繆缕总纵縴縵翼襄褸辕鍚鄔蟉襁适迁环璦璨断曜璧织缮绕繚绣繒蝉顏题蕥鎱际郑邓选迟薑璿嚥曝牘璽疆祷繫绎绳绘缴襠襟识赞譔还迈邀藏琼劝曦繽继耀腾龄繾饌邈瓏樱缠续边瓔弯禳衬鷚晒缨纤襴鷸蛮纘逻湾缆驪別壯協狀糾長則帥彥紅紀紉約風剛孫師時晉書紡紗紋純紐級納紙紛訊務將張強統紮紹細紳組終責淺現創勞場幀結絨絕絲絡給絢視診費貴須莊揚勢園會楊楓祿經絹綏蛻補裝試鉀連劃暢禍綻綜綽綠緊綴網綱綢綿綸維緒賓趕閩進瑤瑣瑪劇劉劍審槳獎瑩締練緯緘緬編緣緞緩複誕賞質輝駐魯齒陳鄉運遊達違潛劑勳戰曆曉熾禦縣螢褲諷駭陽鄒遠遜遙遞蔣勵彌戲牆矯績縷總縱轅適遷環斷織繕繞繡蟬題際鄭鄧選遲禱繹繩繪繳識贊還邁瓊勸繼騰齡櫻纏續邊彎襯曬纓纖蠻邏灣纜`, + JiRadical: "", + }, +} + +var zodiacSupportList = map[string]bool{ + ZodiacRat: true, + ZodiacCow: true, + ZodiacTiger: true, + ZodiacRabbit: true, + ZodiacDragon: true, + ZodiacSnake: true, + ZodiacHorse: true, + ZodiacSheep: true, + ZodiacMonkey: true, + ZodiacChicken: true, + ZodiacDog: true, + ZodiacPig: true, +} + +// GetZodiac ... +func GetZodiac(c chronos.Calendar) *Zodiac { + z := chronos.GetZodiac(c.Lunar()) + b := zodiacSupportList[z] + if !b { + fmt.Println("[Warning]生肖:", z, ",该生肖库资料尚未补足") + } + if v, b := zodiacList[z]; b { + return &v + } + return nil +} + +func (z *Zodiac) zodiacJi(character *Character) int { + if strings.IndexRune(z.Ji, []rune(character.Ch)[0]) != -1 { + return -3 + } + return 0 +} + +func filterZodiac(c chronos.Calendar, chars ...*Character) bool { + return GetZodiac(c).PointCheck(3, chars...) +} + +// PointCheck 检查point +func (z *Zodiac) PointCheck(limit int, chars ...*Character) bool { + for _, c := range chars { + if z.Point(c) < limit { + return false + } + } + return true +} + +// Point 喜忌对冲,理论上喜忌都有的话,最好不要选给1,忌给0,喜给5,都没有给3 +func (z *Zodiac) Point(character *Character) int { + dp := 3 + dp += z.zodiacJi(character) + dp += z.zodiacXi(character) + return dp +} + +func (z *Zodiac) zodiacXi(character *Character) int { + if strings.IndexRune(z.Xi, []rune(character.Ch)[0]) != -1 { + return 2 + } + return 0 +}