From a724b98c02b1375b51ad5773b54a7a4237d5d931 Mon Sep 17 00:00:00 2001 From: minagawah Date: Tue, 15 Mar 2022 07:43:35 +0900 Subject: [PATCH] feat: Added more Feng-Shui calculations --- Cargo.toml | 5 +- README.md | 239 ++++++---- docs/bagua.md | 127 ++++++ docs/compass.md | 286 ++++++++++++ docs/examples/Cargo.toml | 32 ++ docs/examples/FengShui.js | 613 +++++++++++++++++++++++++ docs/examples/bagua.jsx | 134 ++++++ docs/examples/bagua_info.jsx | 115 +++++ docs/examples/chart.jsx | 50 +++ docs/examples/index.md | 298 +++++++++++++ docs/examples/jiuxing.jsx | 258 +++++++++++ docs/examples/lib.rs | 201 +++++++++ docs/examples/north.jsx | 94 ++++ docs/examples/twentyfour.jsx | 147 ++++++ docs/examples/twentyfour_info.jsx | 147 ++++++ docs/examples/utils.js | 139 ++++++ docs/ganzhi.md | 264 +++++++++++ docs/jiuxing.md | 301 +++++++++++++ docs/planet.md | 68 +++ docs/sample_bagua.png | Bin 0 -> 37134 bytes docs/sample_shengsi.png | Bin 0 -> 19737 bytes docs/sample_twentyfour.png | Bin 0 -> 66642 bytes docs/shengsi.md | 104 +++++ docs/solar_terms.md | 56 +++ docs/time.md | 44 ++ json/bagua.json | 2 +- json/ganzhi_branches.json | 24 +- json/ganzhi_stems.json | 20 +- json/jiuxing.json | 2 +- json/planet.json | 132 +++--- json/wuxing.json | 60 +-- screenshot.png | Bin 0 -> 72401 bytes screenshot2.png | Bin 0 -> 73744 bytes src/bagua.rs | 139 +++++- src/compass.rs | 486 ++++++++++++++++++++ src/constants.rs | 128 ------ src/ganzhi.rs | 275 ++++++++++-- src/jiuxing.rs | 719 +++++++++++++++++++++++++++++- src/language.rs | 17 +- src/lib.rs | 8 +- src/planet.rs | 68 ++- src/shengsi.rs | 267 +++++++++++ src/solar_terms.rs | 45 +- src/test_mods.rs | 61 +++ src/utils.rs | 42 +- src/wuxing.rs | 29 +- tricky.png | Bin 0 -> 38671 bytes 47 files changed, 5868 insertions(+), 378 deletions(-) create mode 100644 docs/bagua.md create mode 100644 docs/compass.md create mode 100644 docs/examples/Cargo.toml create mode 100644 docs/examples/FengShui.js create mode 100644 docs/examples/bagua.jsx create mode 100644 docs/examples/bagua_info.jsx create mode 100644 docs/examples/chart.jsx create mode 100644 docs/examples/index.md create mode 100644 docs/examples/jiuxing.jsx create mode 100644 docs/examples/lib.rs create mode 100644 docs/examples/north.jsx create mode 100644 docs/examples/twentyfour.jsx create mode 100644 docs/examples/twentyfour_info.jsx create mode 100644 docs/examples/utils.js create mode 100644 docs/ganzhi.md create mode 100644 docs/jiuxing.md create mode 100644 docs/planet.md create mode 100644 docs/sample_bagua.png create mode 100644 docs/sample_shengsi.png create mode 100644 docs/sample_twentyfour.png create mode 100644 docs/shengsi.md create mode 100644 docs/solar_terms.md create mode 100644 docs/time.md create mode 100644 screenshot.png create mode 100644 screenshot2.png create mode 100644 src/compass.rs delete mode 100644 src/constants.rs create mode 100644 src/shengsi.rs create mode 100644 src/test_mods.rs create mode 100644 tricky.png diff --git a/Cargo.toml b/Cargo.toml index 34cff55..ecd624a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mikaboshi" -version = "0.4.1" +version = "0.5.0" edition = "2018" [dependencies] @@ -13,3 +13,6 @@ sowngwala = { git = "https://github.com/minagawah/sowngwala", version = "0.4.0" [dev-dependencies] approx_eq = "0.1.8" +js-sys = "0.3.52" +wasm-bindgen = { version = "0.2.70", features = ["serde-serialize"] } +wasm-bindgen-test = "0.3.13" diff --git a/README.md b/README.md index 99b25c4..40d5add 100644 --- a/README.md +++ b/README.md @@ -1,121 +1,187 @@ # mikaboshi -## About +![screenshot](./screenshot.png) +![screenshot2](./screenshot2.png) -`mikaboshi` provides basic calculations for Chinese astrology, known as _Bazi_. -The name `mikaboshi` derives from a Marvel character, -[Amatsu-mikaboshi](https://marvel.fandom.com/wiki/Amatsu-Mikaboshi_(Earth-616)), -or one of goddesses in Shinto who equates to Lucifer in the west. -It literally means "the shinning star in the sky". +## 1. About + +__"mikaboshi"__ is a Rust library for 風水 (风水) (_Feng-Shui_) calculations. +As such, it provides commonly used calculation logic +for basic Chinese astrological concepts such as: + +- [八卦 (Ba-Gua)](./docs/bagua.md) +- [干支 (Gan-Zhi)](./docs/ganzhi.md) +- [九星 (Jiu-Xing)](./docs/jiuxing.md) +- [二十四节气 (Er-Shi-Si Jie-Qi)](./docs/solar_terms.md) +- [二十四山向 (Er-Shi-Si Shan-Xiang)](./docs/compass.md) +- [生死衰旺 (Sheng-Si Shuai-Wang)](./docs/shengsi.md) + +As you may have noticed that sample codes in +[samples](./docs/examples/index.md) +are that of a WASM (WebAssembly) app, +it does not always have to be a Rust app when using the library. +It is amazing how you could easily link +your codes written in Rust to JS apps +when provided as a WASM app. + +The name __"mikaboshi"__ derives from a _Marvel_ character +_["Amatsu-Mikaboshi"](https://marvel.fandom.com/wiki/Amatsu-Mikaboshi_(Earth-616))_ +or one of the goddesses in _Shinto_. _"Amatsu-Mikaboshi"_ means +_"The Shinning Star in the Sky"_ when literally translated, +which reminds us of _Lucifer_ in the west. + +This library depends on +_[sowngwala](https://github.com/minagawah/sowngwala/)_ +for calculating sun's position. +It also use some structs from +_[sowngwala](https://github.com/minagawah/sowngwala/)_, +namely, _`Date`_, _`DateTime`_, _`Time`_, and _`Month`_ +with which you need to specify as arguments for some functions. +Also, they are re-exported for public use. + +__What Makes The Program Tricky?__ + +So, the library expects you to have +a Feng-Shui board with 9 boxes drawn on a device screen. +1 empty box in the middle surrounded by 8 boxes. +360 divided by 8, makes it 45 degrees for each. +See how it goes when pointing "N" (north): + +(When pointing "N") +1st row ‐‐> "NW", "N", and "NE" +2nd row ‐‐> "W", (middle), and "E" +3rd row ‐‐> "SW", "S", and "SE" + +![tricky device rotation](./tricky.png) + +However, it gets tricky when device rotates. +Say, the device rotates for 45 degrees clockwise. +It now points to "NE" (north-east): + +(When pointing "NE") +1st row ‐‐> "N", "NE", and "E" +2nd row ‐‐> "NW", (middle), and "SE" +3rd row ‐‐> "W", "SW", and "S" + +As you can imagine, when the above is expressed in a Rust program, +we need `Vec` and `HashMap`, and that is why we have +many `Vec` and `HashMap` as to map variations +that manifest per compass direction +(usually 8, but sometimes 9 when center is concerned). +This is so, not only for compass directions, +but for Feng-Shui mappings as well. +Whenever we calculate positions for Feng-Shui elements, +the positions are provided in `Vec` or `HashMap` +so that they will have 8 or 9 patterns. -## Important +## 2. Examples -`mikaboshi` depends on -[sowngwala](https://github.com/minagawah/sowngwala/) -for many structs and functions. -When you work with `mikaboshi`, you need some structs from `sowngwala`. -For some functions in `mikaboshi` expects `DateTime` of `sowngwala` as arguments. -As such, `mikaboshi` is re-exporting date & time related structs from `sowngwala`: +[A few examples](./docs/examples/index.md) which may or may not help... -```rust -pub use sowngwala::time::{ - Month, - Date, - Time, - DateTime, -}; + +## 3. Documentation + +You may: + +```bash +cargo doc ``` -Refer to the source codes of `sowngwala` for specifications: -https://github.com/minagawah/sowngwala/blob/main/src/time.rs +however, you will probably get more from documentations bellow: -## Calculation +### [八卦 (Bagua)](./docs/bagua.md) -- Longitude of the sun is that of 0:00 midnight for the given day -- Day changes at 0:00 midnight +- [Bagua](./docs/bagua.md#baguabagua) +- [BaguaRawData](./docs/bagua.md#baguabaguarawdata) +- [BAGUA](./docs/bagua.md#baguabagua) +- [BAGUA_START_NORTH_INDEXES](./docs/bagua.md#baguabagua_start_north_indexes) +- [BAGUA_START_NORTH](./docs/bagua.md#baguabagua_start_north) +- [get_bagua_start_north](./docs/bagua.md#baguaget_bagua_start_north) -## Usage +### [二十四山向 (Er-Shi-Si Shan-Xiang)](./docs/compass.md) -### `ut_from_local()` +- [Direction](./docs/compass.md#compassdirection) +- [TwentyFourType](./docs/compass.md#compasstwentyfourtype) +- [DIRECTIONS](./docs/compass.md#compassdirections) +- [OPPOSITE_DIRECTION](./docs/compass.md#compassopposite_direction) +- [DIRECTION_POSITIONS_IN_CHART](./docs/compass.md#compassdirection_positions_in_chart) +- [TWENTYFOUR_DIRECTIONS_TO_INDEX](./docs/compass.md#compasstwentyfour_directions_to_index) +- [TWENTYFOUR_INDEX_TO_DIRECTIONS](./docs/compass.md#compasstwentyfour_index_to_directions) +- [TWENTYFOUR_ORDER_START_NORTH](./docs/compass.md#compasstwentyfour_order_start_north) +- [TWENTYFOUR_SECTORS](./docs/compass.md#compasstwentyfour_sectors) +- [get_direction_positions_in_chart](./docs/compass.md#compassget_direction_positions_in_chart) +- [get_opposite_direction](./docs/compass.md#compassget_opposite_direction) +- [get_twentyfour_data_from_direction](./docs/compass.md#compassget_twentyfour_data_from_direction) +- [get_twentyfour_data_from_index](./docs/compass.md#compassget_twentyfour_data_from_index) +- [get_twentyfour_direction_from_degrees](./docs/compass.md#compassget_twentyfour_direction_from_degrees) +- [get_twentyfour_direction_from_direction](./docs/compass.md#compassget_twentyfour_direction_from_direction) +- [get_twentyfour_direction_from_index](./docs/compass.md#compassget_twentyfour_direction_from_index) +- [get_twentyfour_index_from_direction](./docs/compass.md#compassget_twentyfour_index_from_direction) -You may convert your local time into _UT_: +### [干支 (Gan-Zhi)](./docs/ganzhi.md) -```rust -use mikaboshi::time::{ - Month, - DateTime, - ut_from_local, -}; +- [Stem](./docs/ganzhi.md#ganzhistem) +- [Branch](./docs/ganzhi.md#ganzhibranch) +- [StemRawData](./docs/ganzhi.md#ganzhistemrawdata) +- [BranchRawData](./docs/ganzhi.md#ganzhibranchrawdata) +- [GanZhi](./docs/ganzhi.md#ganzhiganzhi) +- [Bazi](./docs/ganzhi.md#ganzhibazi) +- [STEMS](./docs/ganzhi.md#ganzhistems) +- [BRANCHES](./docs/ganzhi.md#ganzhibranches) +- [GANZHI_SEXAGESIMAL](./docs/ganzhi.md#ganzhiganzhi_sexagesimal) +- [HOUR_STEM_TABLE](./docs/ganzhi.md#ganzhihour_stem_table) +- [Bazi::from_local](./docs/ganzhi.md#ganzhibazifrom_local) -let zone: i8 = 9; +### [九星 (Jiu-Xing)](./docs/jiuxing.md) -let local = DateTime { - year: 2021, - month: Month::Jul, - day: 7.0, - hour: 0, - min: 0, - sec: 0.0, -}; +- [JiuXing](./docs/jiuxing.md#jiuxingjiuxing) +- [JiuXingRawData](./docs/jiuxing.md#jiuxingjiuxingrawdata) +- [XiaGuaTu](./docs/jiuxing.md#jiuxingxiaguatu) +- [DIRECTION_TO_JIU_XING](./docs/jiuxing.md#jiuxingdirection_to_jiu_xing) +- [JIU_XING](./docs/jiuxing.md#jiuxingjiu_xing) +- [JIU_XING_DI_PAN_POSITIONS](./docs/jiuxing.md#jiuxingjiu_xing_di_pan_positions) +- [get_jiuxing_dipan_positions_from_direction](./docs/jiuxing.md#jiuxingget_jiuxing_dipan_positions_from_direction) +- [get_jiuxing_from_index](./docs/jiuxing.md#jiuxingget_jiuxing_from_index) +- [normalize_jiuxing](./docs/jiuxing.md#jiuxingnormalize_jiuxing) +- [fly_flying_stars](./docs/jiuxing.md#jiuxingfly_flying_stars) +- [get_xiaguatu_from_unpan_index](./docs/jiuxing.md#jiuxingget_xiaguatu_from_unpan_index) -let ut: DateTime = ut_from_local(&local, zone); -println!("ut: {:?}", ut); +### [生死衰旺 (Sheng-Si Shuai-Wang)](./docs/shengsi.md) -// { -// year: 2021, -// month: Jul, -// day: 6.0, -// hour: 14, -// min: 57, -// sec: 17.13778432735566 -// } -``` +- [ShengSi](./docs/shengsi.md#shengsishengsi) +- [ShengSiYearlyAlloc](./docs/shengsi.md#shengsishengsiyearalloc) +- [SHENG_SI](./docs/shengsi.md#shengsisheng_si) +- [SHENG_SI_ALLOC](./docs/shengsi.md#shengsisheng_si_alloc) +- [get_shengsi_mapping](./docs/shengsi.md#shengsiget_shengsi_mapping) -### `Bazi::from_local()` +### [二十四节气 (Er-Shi-Si Jie-Qi) and 立春 (Li-Chun)](./docs/solar_terms.md) -You can easily calculate for _Bazi_: +- [get_last_term](./docs/solar_terms.md#solar_termsget_last_term) +- [get_lichun](./docs/solar_terms.md#solar_termsget_lichun) -```rust -use mikaboshi::time::{ Month, DateTime }; -use mikaboshi::ganzhi::{ Bazi, GanZhi }; +### [Planets](./docs/planet.md) -let zone: i8 = 9; +- [Planet](./docs/planet.md#planet) +- [PlanetRawData](./docs/planet.md#planetrawdata) +- [PLANETS](./docs/planet.md#planets) -let lt = DateTime { - year: 2021, - month: Month::Jul, - day: 7.0, - hour: 0, - min: 0, - sec: 0.0, -}; -let bazi: Bazi = Bazi::from_local(<, zone); +### [Time](./docs/time.md) -let year: GanZhi = bazi.year; -let month: GanZhi = bazi.month; -let day: GanZhi = bazi.day; -let hour: GanZhi = bazi.hour; +- [Date](./docs/time.md#timedate) +- [DateTime](./docs/time.md#timedatetime) +- [Time](./docs/time.md#timetime) +- [ut_from_local](./docs/time.md#timeut_from_local) -println!("年: {} ({})", year.alphabet(), year.alphabet_ja()); -println!("月: {} ({})", month.alphabet(), month.alphabet_ja()); -println!("日: {} ({})", day.alphabet(), day.alphabet_ja()); -println!("時: {} ({})", hour.alphabet(), hour.alphabet_ja()); -// 年: 辛丑 (かのと・うし) -// 月: 甲午 (きのえ・うま) -// 日: 乙卯 (きのと・う) -// 時: 癸未 (みずのと・ひつじ) -``` - -## Test +## 4. Test ``` RUST_BACKTRACE=1 cargo test -vv -- --nocapture ``` -## Dislaimer +## 5. Dislaimer There is absolutely no gurantee about the accuracy of the service, information, or calculated results provided by the program, @@ -127,6 +193,7 @@ for which the author of the program shall not be liable. It shall be your own responsibility to ensure the service, information, or calculated results meet your specific requirements. -## License + +## 6. License MIT license ([LICENSE](LICENSE)) diff --git a/docs/bagua.md b/docs/bagua.md new file mode 100644 index 0000000..b44637d --- /dev/null +++ b/docs/bagua.md @@ -0,0 +1,127 @@ +# 八卦 (Bagua) + +Source: [src/bagua.rs](../src/bagua.rs) + +![sample_bagua](./sample_bagua.png) + +Although 八卦 (Ba-Gua) is a concept in 易経 (I-Ching), +when used in Feng-Shui, it is often associated with 九星 (Jiu-Xing). +While everthing in this world is (said to be) divided into either 陰 (Yin) +or 陽 (Yang), each could be further divided into lesser Yin and Yang. +For Yang, some may be abundant in Yang. Or, some may slightly lean toward Yin. +This goes for Yin as well. Here, the initial Yin and Yang, +now divided into 4, or becomes 4 patterns. Then, for each, +there are further divisions, and for this time, it now makes it 8 patterns. +Ancient Chinese had a specific term for these 8 patterns, +and it is called, 八卦 (Ba-Gua), or "8 Gua". + +[0] 坎 (Kan) +[1] 坤 (Kun) +[2] 震 (Zhen) +[3] 巽 (Xun) +[4] 乾 (Qian) +[5] 兌 (Dui) +[6] 艮 (Gen) +[7] 離 (Li) + + +## bagua::Bagua + +A struct representing 卦 (Gua) and stores its attributes. + +```rust +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Bagua { + pub num: u8, + pub name: Language, + pub direction: String, + pub element: u8, +} +``` + +## bagua::BaguaRawData + +A temporary struct for loading JSON data when defining a static const `BAGUA`. + +```rust +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct BaguaRawData { + pub num: u8, + pub name: LanguageData, + pub direction: String, + pub element: u8, +} +``` + +## bagua::BAGUA + +`Vec` + +A static vector with 9 items, each represents 卦 (Gua) of 八卦 (Ba-Gua), +or what known as "Eight Trigrams". Each stores associated attributes +for the 卦 (Gua), and are in the order of Ba-Gua Numbers. For instance, +坎 (Kan) is the first in Ba-Gua, so it comes first in the vector. +However, be careful when you refer to each 卦 (Gua) as the program +refers 卦 (Gua) not by Ba-Gua Numbers, but by vector indexes. +For 坎 (Kan), for instance, while it has the Ba-Gua Number of 1, +it is referred as 0 because that is the index is for 坎 (Kan). + +[0] 坎 (1 = Kan) +[1] 坤 (2 = Kun) +[2] 震 (3 = Zhen) +[3] 巽 (4 = Xun) +[4] 中 (5 = Zhong) +[5] 乾 (6 = Qian) +[6] 兌 (7 = Dui) +[7] 艮 (8 = Gen) +[8] 離 (9 = Li) + +For attributes details stored in the vector is found in JSON file: +[json/bagua.json](../json/bagua.json) + +## bagua::BAGUA_START_NORTH_INDEXES + +`Vec` + +Another static vector for 八卦 (Ba-Gua) (and is `Vec`). +However, this time, it has only 8 items because this is used +for compass rotation. When using a compass, only 8 directions matter, +and the middle does not mean anything. When 八卦 (Ba-Gua) are +placed in 洛書 (Lo-Shu) order, 中 (Zhong) comes in the middle. +So, 中 (Zhong) is missing for this vector. For 八卦 (Ba-Gua), +it begins with 坎 (Kan) which resides in the north +when they are placed in Lo-Shu order. Moving clockwise, +what you see next in the north-east, is 艮 (Gen). +Then, comes 震 (3 = Zhen) which is in the east, and, so on. + +[0] 坎 (1 = Kan) +[1] 艮 (8 = Gen) +[2] 震 (3 = Zhen) +[3] 巽 (4 = Xun) +[4] 離 (9 = Li) +[5] 坤 (2 = Kun) +[6] 兌 (7 = Dui) +[7] 乾 (6 = Qian) + +## bagua::BAGUA_START_NORTH + +`Vec` + +While the order is the same as `BAGUA_START_NORTH_INDEXES`, +for this time, it is `Vec` instead of `Vec`. + +## bagua::get_bagua_start_north + +A getter for `BAGUA_START_NORTH`. + +Example: +```rust +use mikaboshi::bagua::{get_bagua_start_north, Bagua}; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn xx(index: usize) -> JsValue { + let bagua: Option<&Bagua> = get_bagua_start_north(index); + JsValue::from_serde(&bagua).unwrap() +} +``` diff --git a/docs/compass.md b/docs/compass.md new file mode 100644 index 0000000..ac9d38a --- /dev/null +++ b/docs/compass.md @@ -0,0 +1,286 @@ +# 二十四山向 (Er-Shi-Si Shan-Xiang) + +Source: [src/compass.rs](../src/compass.rs) + +![sample_twentyfour](./sample_twentyfour.png) + +A module for compass directions. When dividing 360 degrees into 8, +we get 45 degrees. Ancient Chinese further divided them each into 3 +(called "sectors"), each having 15 degrees. Meaning, there are +24 sectors as a total. This is called, 二十四山向 (Er-Shi-Si Shan-Xiang). +Not only for 8 directions, but these 24 directions (sectors) +are used in Feng-Shui, and this is the module for these directions. + +Reference: +- [二十四山 - Wiki](https://ja.wikipedia.org/wiki/%E4%BA%8C%E5%8D%81%E5%9B%9B%E5%B1%B1) + + +## compass::Direction + +A struct representing compass direction. +For each direction, there are 3 sectors. + +Example: +```rust +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct Direction { + pub direction: String, + pub sector: usize, +} +``` + +## compass::TwentyFourType + +二十四山向 (Er-Shi-Si Shan-Xiang) can be either 卦 (Gua), 干 (Gan), or 支 (Zhi). + +```rust +pub enum TwentyFourType<'a> { + Bagua(&'a Bagua), + Stem(&'a Stem), + Branch(&'a Branch), +} +``` + +## compass::DIRECTIONS + +`[&str; 8]` + +An array for 8 directions. + +```rust +pub const DIRECTIONS: [&str; 8] = + ["n", "ne", "e", "se", "s", "sw", "w", "nw"]; +``` + +## compass::OPPOSITE_DIRECTION + +`HashMap<&str, &str>` + +A hash map for the opposite direction. + +## compass::DIRECTION_POSITIONS_IN_CHART + +`HashMap<&str, [&str; 9]>` + +A hash map with 9 items. +Say, we have 9 boxes displayed on a device screen. +Except for the box in the middle, we have 8 boxes +around the middle to represent 8 compass directions. +When facing "n" (north), for the first row, +we have "nw", "n", and "ne". For the second row, +we have "w", "", and "e" (where "" being the middle box). +For the last, we have "sw", "s", and "se". + +[0] nw [1] n [2] ne +[3] w [4] [5] e +[6] sw [7] s [8] se + +Now, consider when the device rotates. +Depending on which direction the device is facing, +we have different labels. For all 8 directions, +this HashMap provides a map for the positions. + +## compass::TWENTYFOUR_DIRECTIONS_TO_INDEX + +`HashMap` + +A HashMap mapping direction (combination of "direction" and "sector") +to the corresponding index. + +n2: 0 +n3: 1 +ne1: 2 +ne2: 3 +... +... + +## compass::TWENTYFOUR_INDEX_TO_DIRECTIONS + +`Vec` + +An array with 24 items, for each represents +each in 二十四山向 (Er-Shi-Si Shan-Xiang). +Note, the array begins with "N2" +(and "N1" is stored at the very last, or [23]). + +0: Direction { direction: "n", sector: 2 } +1: Direction { direction: "n", sector: 3 } +2: Direction { direction: "ne", sector: 1 } +3: Direction { direction: "ne", sector: 2 } +... +... + +## compass::TWENTYFOUR_ORDER_START_NORTH + +`[(usize, usize); 24]` + +An array with 24 items, each being a tuple. For each tuple, +the first represents the type of "二十四山向" (Er-Shi-Si Shan-Xiang), +and the second is the index of the type. +The type being: [0] BAGUA, [1] STEM, or [2] BRANCH. + +(2, 0) --> [0] 子 +(1, 9) --> [9] 癸 +(2, 1) --> [1] 丑 +(0, 7) --> [7] 艮 +(2, 2) --> [2] 寅 +(1, 0) --> [0] 甲 +... +... + +## compass::TWENTYFOUR_SECTORS + +`[u8; 24]` + +An array with 24 items. Imagine having a circlar disc displayed +on a device screen. When dividing 360 by 8 directions, we get +45 degrees for each. When each direction is further divided +into 3, then each is called a "sector", and it has 15 degrees +for each "sector". Sectors are placed in clockwise order +(left to right) for each direction, so that you see +the sector 1 being placed on your very left. Then, you see +the sector 2 in the middle, and the sector 3 on your right. +Imagine the device pointing north. On the circular disc, +what you see at the very top is the sector 2 of "N" (north), +denoted as "N2". On your left, you see "N1". +On your right, "N3". + +When we want to express all the 24 sectors, we want +an array with 24 items. For the first item in the array [0], +it is convenient to have "N2". Then, for the second item +in the array [1], we want "N3". For [2], we want "NE1". +For [3], we want "NE2". And, so on. As you can imagine, +"N1" comes to the very last in the array, or [23]. + +2 --> n +3 --> n +1 --> ne +2 --> ne +3 --> ne +1 --> e +... +... + +## compass::get_direction_positions_in_chart + +An getter for `DIRECTION_POSITIONS_IN_CHART`. + +Example: + +```rust +use mikaboshi::compass::get_direction_positions_in_chart; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn xx(direction: &str) -> JsValue { + JsValue::from( + (match get_direction_positions_in_chart(direction) { + Some(positions) => positions.to_vec(), + _ => Vec::new(), + }) + .into_iter() + .map(JsValue::from) + .collect::(), + ) +} +``` + +## compass::get_opposite_direction + +A getter for `OPPOSITE_DIRECTION`. + +Example: + +```rust +use mikaboshi::compass::get_opposite_direction; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn xx(direction: &str) -> JsValue { + JsValue::from(get_opposite_direction(direction)) +} +``` + +## compass::get_twentyfour_data_from_direction + +From the given direction and sector, returns `TwentyFourType`. + +Example: + +```rust +use mikaboshi::compass::{get_twentyfour_data_from_direction, TwentyFourType}; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn xx(direction: &str, sector: usize) -> JsValue { + let t_type: TwentyFourType = get_twentyfour_data_from_direction(direction, sector); + match t_type { + TwentyFourType::Bagua(bagua) => JsValue::from_serde(bagua).unwrap(), + TwentyFourType::Stem(stem) => JsValue::from_serde(stem).unwrap(), + TwentyFourType::Branch(branch) => JsValue::from_serde(branch).unwrap(), + } +} +``` + +## compass::get_twentyfour_data_from_index + +From index, simply returns the corresponding `TwentyFourType`. + +Example: + +```rust +use mikaboshi::compass::{get_twentyfour_data_from_index, TwentyFourType}; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn xx(index: usize) -> JsValue { + let t_type: TwentyFourType = get_twentyfour_data_from_index(index); + match t_type { + TwentyFourType::Bagua(bagua) => JsValue::from_serde(bagua).unwrap(), + TwentyFourType::Stem(stem) => JsValue::from_serde(stem).unwrap(), + TwentyFourType::Branch(branch) => JsValue::from_serde(branch).unwrap(), + } +} +``` + +## compass::get_twentyfour_direction_from_degrees + +From the given degrees, returns the corresponding `Direction`. + +Example: + +```rust +use mikaboshi::compass::{get_twentyfour_direction_from_degrees, Direction}; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn xx(degrees: f32) -> JsValue { + let dir: Direction = get_twentyfour_direction_from_degrees(degrees); + JsValue::from_serde(&dir).unwrap() +} +``` + +## compass::get_twentyfour_direction_from_direction + +From the given direction and sector, returns `Direction`. + +## compass::get_twentyfour_direction_from_index + +Example: + +```rust +use mikaboshi::compass::{get_twentyfour_direction_from_index, Direction}; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn xx(index: usize) -> JsValue { + let dir: &Direction = get_twentyfour_direction_from_index(index); + JsValue::from_serde(dir).unwrap() +} +``` + +## compass::get_twentyfour_index_from_direction + +From the given direction and sector, finds the corresponding index +in `TWENTYFOUR_DIRECTIONS_TO_INDEX` + diff --git a/docs/examples/Cargo.toml b/docs/examples/Cargo.toml new file mode 100644 index 0000000..2b37665 --- /dev/null +++ b/docs/examples/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "" +version = "0.1.0" +authors = [""] +edition = "2018" + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +console_error_panic_hook = "^0.1.6" +js-sys = "0.3.52" +mikaboshi = { git = "https://github.com/minagawah/mikaboshi", version = "0.5.0" } +serde = { version = "1.0.127", features = ["derive"] } +wasm-bindgen = { version = "0.2.70", features = ["serde-serialize"] } + +# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size +# compared to the default allocator's ~10K. It is slower than the default +# allocator, however. +# +# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now. +wee_alloc = { version = "0.4.5", optional = true } + +[dev-dependencies] +wasm-bindgen-test = "0.3.13" + +[profile.release] +# Tell `rustc` to optimize for small code size. +opt-level = "s" + +[package.metadata.wasm-pack.profile.release] +wasm-opt = false diff --git a/docs/examples/FengShui.js b/docs/examples/FengShui.js new file mode 100644 index 0000000..efb6787 --- /dev/null +++ b/docs/examples/FengShui.js @@ -0,0 +1,613 @@ +/** + * A context provider to load a WASM app ("voi-feng-shui" in our case). + * Once `FengShuiContext` is set in the parent component, you can use + * `useFengShui` in child components to access the given properties. + * To start with, it requies data in `profile`, however, `profile` + * is managed in `ProfilesProvider`. For two providers cannot + * communicate to each other, we have `useFengShuiSync` + * to serve the purpose. For any components handling `profile`, + * we run `useFengShuiSync` in there, and it will automatically + * @namespace FengShui + */ + +import React, { + useContext, + createContext, + useEffect, + useState, + useCallback, + useRef, +} from 'react'; + +import moment from 'moment'; +import init, { + // 八卦 (Ba-Gua) + get_bagua_start_north as wasm_get_bagua_start_north, + + // 二十四山向 (Er-Shi Si-Shan Xiang) + get_twentyfour_direction_from_index as wasm_get_twentyfour_direction_from_index, + get_twentyfour_direction_from_degrees as wasm_get_twentyfour_direction_from_degrees, + get_twentyfour_data_from_index as wasm_get_twentyfour_data_from_index, + get_twentyfour_data_from_direction as wasm_get_twentyfour_data_from_direction, + + // 干支 (Gan-Zhi) + get_bazi as wasm_get_bazi, + get_lichun as wasm_get_lichun, + + // 九星 (Jiu-Xings) + get_jiuxing_from_index as wasm_get_jiuxing_from_index, + get_unpan_xing_index as wasm_get_unpan_xing_index, + get_xiaguatu_from_unpan_index as wasm_get_xiaguatu_from_unpan_index, + get_jiuxing_dipan_positions_from_direction as wasm_get_jiuxing_dipan_positions_from_direction, + + // 生死衰旺 (Sheng-Si Shuai-Wang) + get_shengsi_mapping as wasm_get_shengsi_mapping, +} from 'voi-feng-shui'; + +import { DATETIME_FORMAT, BAZI_TYPE_KEYS, GANZHI_TYPE_KEYS } from '@/constants'; +import { int, noop, get_utc_offset_in_hours } from '@/lib/utils'; + +import { + useProfiles, + get_first_valid_profile_from_profiles, +} from '@/contexts/Profiles'; + +const WASM_PATH = + NODE_ENV === 'production' + ? 'wasm/voi-feng-shui/voi-feng-shui_bg.wasm' + : void 0; + +// console.log('[useFengShui] WASM_PATH: ', WASM_PATH); + +const DATETIME_KEYS = Object.keys(DATETIME_FORMAT); +const DATE_KEYS = DATETIME_KEYS.filter( + key => + key.indexOf('year') > -1 || + key.indexOf('month') > -1 || + key.indexOf('day') > -1 +); + +/** @public */ +export const has_valid_profile = (p = {}) => + p.localtime && p.direction && p.sector; + +// ---------------------------------------------------------------- +// FengShuiContext +// ---------------------------------------------------------------- + +/** + * @typedef FengShui.FengShuiContext + * @property {boolean} ready + * @property {Object} profile + * @property {Object} bazi + * @property {Object} lichun + * @property {Object} unpan_xing + * @property {Object} shan_xing + * @property {Object} xiang_xing + * @property {Function} update + * @property {FengShui.FengShuiContext.get_bagua_start_north} + * @property {FengShui.FengShuiContext.get_direction_positions_in_chart} - NOT IN USE + * @property {FengShui.FengShuiContext.get_opposite_direction} - NOT IN USE + * @property {FengShui.FengShuiContext.get_twentyfour_direction_from_index} + * @property {FengShui.FengShuiContext.get_twentyfour_direction_from_degrees} + * @property {FengShui.FengShuiContext.get_twentyfour_data_from_index} + * @property {FengShui.FengShuiContext.get_twentyfour_data_from_direction} + * @property {FengShui.FengShuiContext.get_bazi} get_bazi + * @property {FengShui.FengShuiContext.get_lichun} get_lichun + * @property {FengShui.FengShuiContext.get_unpan_xing_index} + * @property {FengShui.FengShuiContext.get_jiuxing_from_index} + * @property {FengShui.FengShuiContext.get_xiaguatu_from_unpan_index} + * @property {FengShui.FengShuiContext.get_jiuxing_dipan_positions_from_direction} + * @property {FengShui.FengShuiContext.get_shengsi_mapping} + */ +const FengShuiContext = createContext({ + ready: false, + profile: null, // localtime, direction, sector + bazi: null, + lichun: null, + unpan_xing: null, // 運盤星 + shan_xing: null, // 山星 + xiang_xing: null, // 向星 + update: noop, + + // 八卦 (Ba-Gua) + get_bagua_start_north: noop, + + // 二十四山向 (Er-Shi Si-Shan Xiang) + get_twentyfour_direction_from_index: noop, + get_twentyfour_direction_from_degrees: noop, + get_twentyfour_data_from_index: noop, + get_twentyfour_data_from_direction: noop, + + // 干支 (Gan-Zhi) + get_bazi: noop, + get_lichun: noop, + + // 九星 (Jiu-Xings) + unpan_xing_index: noop, + get_xiaguatu_from_unpan_index: noop, + get_jiuxing_dipan_positions_from_direction: noop, + + // 生死衰旺 (Sheng-Si Shuai-Wang) + get_shengsi_mapping: noop, +}); + +// ---------------------------------------------------------------- +// FengShuiProvider +// ---------------------------------------------------------------- + +/** + * @typedef FengShui.FengShuiProvider + * @function + */ +export const FengShuiProvider = props => { + const [ready, setReady] = useState(false); + const [profile, setProfile] = useState(null); + const [bazi, setBazi] = useState(null); + const [lichun, setLiChun] = useState(null); + const [unpan_xing, setUnPanXing] = useState(null); + const [shan_xing, setShanXing] = useState(null); + const [xiang_xing, setXiangXing] = useState(null); + + // ================================================================ + // 八卦 (Bagua) + // ================================================================ + + /** + * A simple accessor for values stored in `BAGUA_START_NORTH`. + * @typedef FengShui.FengShuiContext.get_bagua_start_north + * @function + */ + + /** + * @type {FengShui.FengShuiContext.get_bagua_start_north} + */ + const get_bagua_start_north = useCallback( + dir => { + return ready && wasm_get_bagua_start_north(dir); + }, + [ready] + ); + + // ================================================================ + // 二十四山向 (Er-Shi Si-Shan Xiang) + // ================================================================ + + /** + * From the index, returns `Direction`. + * @typedef FengShui.FengShuiContext.get_twentyfour_direction_from_index + * @function + * @param {number} [index] + * @returns {Object} - { direction, sector } + */ + + /** + * @type {FengShui.FengShuiContext.get_twentyfour_direction_from_index} + */ + const get_twentyfour_direction_from_index = useCallback( + index => { + return ready && wasm_get_twentyfour_direction_from_index(index); + }, + [ready] + ); + + /** + * From `degrees`, returns `Direction` (for 二十四山向; Er-Shi Si-Shan Xiang). + * @typedef FengShui.FengShuiContext.get_twentyfour_direction_from_degrees + * @function + * @param {number} [degrees=0] + * @returns {Object} - { direction, sector } + */ + + /** + * @type {FengShui.FengShuiContext.get_twentyfour_direction_from_degrees} + */ + const get_twentyfour_direction_from_degrees = useCallback( + degrees => { + return ready && wasm_get_twentyfour_direction_from_degrees(degrees); + }, + [ready] + ); + + /** + * From index, returns `TwentyFourType`. + * @typedef FengShui.FengShuiContext.get_twentyfour_data_from_index + * @function + * @param {number} [index] + * @returns {Bagua|Stem|Branch} - TwentyFourType + */ + + /** + * @type {FengShui.FengShuiContext.get_twentyfour_data_from_index} + */ + const get_twentyfour_data_from_index = useCallback( + index => { + return ready && wasm_get_twentyfour_data_from_index(index); + }, + [ready] + ); + + /** + * From `direction`, returns `TwentyFourType`. + * @typedef FengShui.FengShuiContext.get_twentyfour_data_from_direction + * @function + * @param {number} [index] + * @returns {Bagua|Stem|Branch} - TwentyFourType + */ + + /** + * @type {FengShui.FengShuiContext.get_twentyfour_data_from_direction} + */ + const get_twentyfour_data_from_direction = useCallback( + (dir, sec) => { + return ready && wasm_get_twentyfour_data_from_direction(dir, sec); + }, + [ready] + ); + + // ================================================================ + // 干支 (Gan-Zhi) + // ================================================================ + + /** + * From `t` (localtime), calculates for 八字 (Bazi). + * Internally mapped to: get_bazi + * @typedef FengShui.FengShuiContext.get_bazi + * @function + * @param {Object} [t] - localtime (as a momemt object) + * @returns {Object} - Bazi + */ + + /** @type {FengShui.FengShuiContext.get_bazi} */ + const get_bazi = useCallback( + t => { + return ( + ready && + normalize_bazi_data(wasm_get_bazi(datetime_params_from_localtime(t))) + ); + }, + [ready] + ); + + /** + * From `year`, calculates for 立春 (Li-Chun). + * Internally mapped to: get_lichun + * @typedef FengShui.FengShuiContext.get_lichun + * @function + * @param {number} [y] - year + * @returns {string} - Li-Chun + */ + + /** @type {FengShui.FengShuiContext.get_lichun} */ + const get_lichun = useCallback( + y => { + return ready && y && wasm_get_lichun(~~y); + }, + [ready] + ); + + // ================================================================ + // 九星 (Jiu-Xing) + // ================================================================ + + /** + * A simple accessor for values stored in `JIU_XING`. + * @typedef FengShui.FengShuiContext.get_jiuxing_from_index + * @function + * @param {Object} [index] - Jiu-Xing index + * @returns {Object} - JiuXing + */ + + /** @type {FengShui.FengShuiContext.get_jiuxing_from_index} */ + const get_jiuxing_from_index = useCallback( + index => { + return ready && wasm_get_jiuxing_from_index(index); + }, + [ready] + ); + + /** + * From: (1) `current` (current localtime), and + * (2) `lichun` (立春 (Li-Chun) for the year), + * returns 運盤星 (Un-Pan Xing) index. + * @typedef FengShui.FengShuiContext.get_unpan_xing_index + * @function + * @param {Object} [current] - Current localtime + * @param {Object} [lichun] - Li-Chun (for the year) + * @returns {number} - Un-Pan Xing index + */ + + /** @type {FengShui.FengShuiContext.get_unpan_xing_index} */ + const get_unpan_xing_index = useCallback( + params => { + const { current, lichun } = params; + return ( + ready && + wasm_get_unpan_xing_index( + date_params_from_localtime(current), + date_params_from_localtime(lichun) + ) + ); + }, + [ready] + ); + + /** + * Takes 運盤星 (Un-Pan Xing) information and 向星 (Xiang-Xing) + * information, and returns 下卦図 (Xia-Gua-Tu). + * For 運盤星 (Un-Pan Xing), we need 2 kinds: 運盤 (Un-Pan) + * which is currently in the center, and 洛書 (Lo-Shu) order + * in its re-arranged form. For 向星 (Xiang-Xing), + * we want `direction` and `sector`. + * @typedef FengShui.FengShuiContext.get_xiaguatu_from_unpan_index + * @function + * @param {Object} arg + * @param {number} arg.unpan_xing_center - 運盤星 (Un-Pan Xing) index + * @param {Array} arg.unpan_xing_order - Jiu-Xing Order + * @param {string} arg.xiang_xing_direction - Direction for 向星 (Xiang-Xing) + * @param {number} arg.xiang_xing_sector - Sector for both 山星 (Shan-Xing) and 向星 (Xiang-Xing) + * @returns {Object} + */ + + /** @type {FengShui.FengShuiContext.get_xiaguatu_from_unpan_index} */ + const get_xiaguatu_from_unpan_index = useCallback( + params => { + return ( + ready && + wasm_get_xiaguatu_from_unpan_index({ + ...params, + unpan_xing_order: params.unpan_xing_order || [ + 5, 0, 7, 6, 4, 2, 1, 8, 3, + ], + }) + ); + }, + [ready] + ); + + /** + * A simple accessor for values stored in `JIU_XING_DI_PAN_POSITIONS`. + * @type {FengShui.FengShuiContext.get_jiuxing_dipan_positions_from_direction} + */ + const get_jiuxing_dipan_positions_from_direction = useCallback( + dir => { + return ready && wasm_get_jiuxing_dipan_positions_from_direction(dir); + }, + [ready] + ); + + // ================================================================ + // 生死衰旺 (Sheng-Si Shuai-Wang) + // ================================================================ + + /** + * When provided with 運盤 (Un-Pan) index and the current chart, + * returns the corresponding 生死衰旺 (Sheng-Si Shuai-Wang). + * @typedef FengShui.FengShuiContext.get_shengsi_mapping + * @function + * @param {Object} arg + * @param {number} arg.unpan_id - 運盤星 (Un-Pan Xing) index + * @param {Array} arg.unpan_xing_chart - 運盤星 (Un-Pan Xing) index + * @returns {Object} + */ + + /** @type {FengShui.FengShuiContext.get_shengsi_mapping} */ + const get_shengsi_mapping = useCallback( + params => { + return ( + ready && + wasm_get_shengsi_mapping({ + ...params, + unpan_xing_chart: params.unpan_xing_chart || [ + 5, 0, 7, 6, 4, 2, 1, 8, 3, + ], + }) + ); + }, + [ready] + ); + + // ================================================================ + // MAIN FOR THE CONTEXT PROVIDER + // ================================================================ + + /** @private */ + const _set = useCallback( + (prof = {}) => { + const { localtime: current, direction, sector } = prof; + + if (ready && current && direction) { + const lichun_0 = get_lichun(current.year()); + const lichun = moment(lichun_0); + const center = get_unpan_xing_index({ current, lichun }); + + const xgtu = get_xiaguatu_from_unpan_index({ + unpan_xing_center: center, + xiang_xing_direction: direction, + xiang_xing_sector: sector, + }); + + setBazi( + normalize_bazi_data( + wasm_get_bazi(datetime_params_from_localtime(current)) + ) + ); + setLiChun(lichun); + setUnPanXing(xgtu.unpan_xing); + setShanXing(xgtu.shan_xing); + setXiangXing(xgtu.xiang_xing); + } + }, + [ready, profile?.locatltime, profile?.direction] + ); + + /** + * @typedef FengShui.FengShuiContext.update + * @function + */ + + /** @type {FengShui.FengShuiContext.update} */ + const update = useCallback( + prof => { + if (ready) { + if (!has_valid_profile(prof)) { + throw new Error( + '[FengShuiContext] Need a valid profile for the argument' + ); + } + setProfile(prof); + _set(prof); + } + }, + [ready, _set] + ); + + useEffect(() => { + if (ready !== true) { + init(WASM_PATH) + .then(() => { + setReady(true); + }) + .catch(err => { + throw err; + }); + } + }, [props?.localtime, props?.direction]); + + return ( + + ); +}; + +// ---------------------------------------------------------------- +// useFengShui +// ---------------------------------------------------------------- + +/** + * @typedef FengShui.useFengShui + * @function + */ +export const useFengShui = () => useContext(FengShuiContext); + +// ---------------------------------------------------------------- +// useFengShuiSync (hook) +// ---------------------------------------------------------------- + +/** + * Syncing the latest primary profile to FengShuiContext.profile + * @typedef FengShui.useFengShuiSync + * @function + */ +export const useFengShuiSync = () => { + const { profiles } = useProfiles(); + const { ready, update } = useFengShui(); + const [hasProfile, setHasProfile] = useState(false); + + useEffect(() => { + const p = get_first_valid_profile_from_profiles(profiles); + if (p) { + const t = p.localtime.format('YYYY-MM-DD'); + const dir = `${p.direction}${p.sector}`; + // console.log(`[FengShuiContext] (useFengShuiSync) localtime: ${t}`); + // console.log(`[FengShuiContext] (useFengShuiSync) dir: ${dir}`); + + setHasProfile(true); + update(p); + } else { + // console.log('[FengShuiContext] No valid profiles...'); + setHasProfile(false); + } + }, [ready, profiles]); + + return hasProfile; +}; + +// ---------------------------------------------------------------- +// All the others +// ---------------------------------------------------------------- + +/** + * @private + * @param {Object} t - Moment object in localtime + explicit UTC offset + */ +function date_params_from_localtime(t) { + if (!t) throw new Error("No 'localtime' specified for FengShui"); + + return { + ...DATE_KEYS.reduce((acc, key) => { + acc[key] = int(t.format(DATETIME_FORMAT[key])); + return acc; + }, {}), + }; +} + +/** + * @private + * @param {Object} t - Moment object in localtime + explicit UTC offset + */ +function datetime_params_from_localtime(t) { + if (!t) throw new Error("No 'localtime' specified for FengShui"); + + return { + ...DATETIME_KEYS.reduce((acc, key) => { + acc[key] = int(t.format(DATETIME_FORMAT[key])); + return acc; + }, {}), + zone: get_utc_offset_in_hours(t), + }; +} + +/** + * @private + */ +function normalize_bazi_data(orig) { + const hash = { __orig: { ...orig } }; + + // 'year', 'month', 'hour', 'day' + BAZI_TYPE_KEYS.forEach(bazi_key => { + hash[bazi_key] = { + __obj: orig[bazi_key][bazi_key], + }; + + // 'stem', 'branch' + GANZHI_TYPE_KEYS.forEach(ganzhi_key => { + hash[bazi_key][ganzhi_key] = { + kanji: orig[bazi_key][ganzhi_key].name.zh_cn.alphabet, + yomi: orig[bazi_key][ganzhi_key].name.ja.alphabet, + }; + }); + + hash[ + bazi_key + ].kanji = `${hash[bazi_key].stem.kanji}${hash[bazi_key].branch.kanji}`; + hash[ + bazi_key + ].yomi = `${hash[bazi_key].stem.yomi}${hash[bazi_key].branch.yomi}`; + }); + + return hash; +} diff --git a/docs/examples/bagua.jsx b/docs/examples/bagua.jsx new file mode 100644 index 0000000..5cd51f9 --- /dev/null +++ b/docs/examples/bagua.jsx @@ -0,0 +1,134 @@ +/** + * SVG Pie Drawing + * https://medium.com/hackernoon/a-simple-pie-chart-in-svg-dbdd653b6936 + */ +import React, { useRef, useMemo, useEffect, useCallback } from 'react'; +import { compose, tap } from 'ramda'; +import tw, { css } from 'twin.macro'; +import Snap from 'snapsvg-cjs'; + +import { RADIAN_45, RADIAN_90, Z_INDEX_FENGSHUI_BAGUA } from '@/constants'; +import { int, rad_to_deg, normalize_angle, get_position } from '@/lib/utils'; + +import { useWorld } from '@/contexts/World'; +import { useDeviceOrientation } from '@/contexts/DeviceOrientation'; + +const FILL_COLOR = '#ef4444'; +const STROKE_COLOR = '#ffffff'; +const OUTER_RATIO = 0.8; + +const wrapperStyle = css` + ${tw`absolute w-full flex flex-col justify-center items-center`} + z-index: ${Z_INDEX_FENGSHUI_BAGUA}; +`; + +export const FengShuiBagua = () => { + const { worldInfo: world } = useWorld(); + const deviceOrientation = useDeviceOrientation(); + + const snap = useRef(null); + + const chart_w = world?.chart?.width; + const chart_h = world?.chart?.height; + const alpha = deviceOrientation?.alpha; + + const draw = useCallback( + ({ index }) => { + const s = snap.current && Snap(snap.current); + + if (s) { + const beg = get_position(index * RADIAN_45, OUTER_RATIO); + const end = get_position(index * RADIAN_45 + RADIAN_45, OUTER_RATIO); + const large = end.deg - beg.deg > 180 ? 1 : 0; + + // Remember, the whole wrapper is rotated later + // by 112.5 (= 90 + 45/2), degrees so that + // the first slice which originally sits + // at the 3 o'clock position will come + // to the 12 o'clock position. + // + // Also, we apply `viewbox="-1 -1 2 2"` for the SVG, + // meaning, the origin of SVG is situated + // at the very center of the wrapper. + // That is to say, we have `x = 0`. + // When we have `x = 1`, it means `x` is reaching + // all the way at the right edge of the wrapper. + // + // For each slice, we use SVG's arc function + // which is defined as: + // + // A rx ry x-axis-rotation large-arc-flag sweep-flag x y + // + // At first, we will first move (`M`) to where + // it is close to the right edge of the screen. + // If `OUTER_RATIO = 0.8`, it will probably + // be like `M0.8,0`. Next, for the arc, we will + // probably have `A0.8,0.8 0 0,1 0.56,0.56`. + // So, it is an arc having `0.8` for the radius, + // and it will draw the arc for 45 degrees. + // Lastly, we have `L0,0` to go back to the origin, + // otherwise, it won't fill (with given color) + // the region surrounded by the path. + + const path = [ + `M${beg.x},${beg.y}`, + `A${OUTER_RATIO},${OUTER_RATIO} 0 ${large},1 ${end.x},${end.y}`, + `L0,0`, + ].join(' '); + + const fill = + index === 0 + ? { + fill: FILL_COLOR, + } + : {}; + + s.path(path).attr({ + ...fill, + stroke: STROKE_COLOR, + strokeWidth: world?.stroke_size, + }); + } + }, + [chart_w] + ); + + const baguaStyle = useMemo(() => { + const rotation = normalize_angle( + alpha - rad_to_deg(Math.PI / 2 + RADIAN_45 / 2) + ); + return css` + width: ${chart_w}px; + height: ${chart_h}px; + transform: rotate(${rotation}deg); + `; + }, [chart_w, alpha]); + + useEffect(() => { + const s = snap.current && Snap(snap.current); + if (s) { + [...new Array(8)].map((_, i) => { + draw({ index: i }); + }); + } + }, [chart_w, draw]); + + return ( +
+ +
+ ); +}; + +// const pos = []; +// pos[0] = get_position(index * RADIAN_45, OUTER_RATIO); +// pos[1] = get_position(index * RADIAN_45 + RADIAN_45, OUTER_RATIO); +// pos[2] = get_position(index * RADIAN_45 + RADIAN_45, INNER_RATIO); +// pos[3] = get_position(index * RADIAN_45, INNER_RATIO); +// +// const path = [ +// `M${pos[0].x},${pos[0].y}`, +// `L${pos[1].x},${pos[1].y}`, +// `L${pos[2].x},${pos[2].y}`, +// `L${pos[3].x},${pos[3].y}`, +// ].join(' '); diff --git a/docs/examples/bagua_info.jsx b/docs/examples/bagua_info.jsx new file mode 100644 index 0000000..2b8d0fe --- /dev/null +++ b/docs/examples/bagua_info.jsx @@ -0,0 +1,115 @@ +/** + * SVG Pie Drawing + * https://medium.com/hackernoon/a-simple-pie-chart-in-svg-dbdd653b6936 + */ +import React, { + useRef, + useState, + useMemo, + useEffect, + useCallback, +} from 'react'; +import { compose, tap } from 'ramda'; +import tw, { css } from 'twin.macro'; + +import { RADIAN_45, RADIAN_90, Z_INDEX_FENGSHUI_BAGUA_INFO } from '@/constants'; +import { + fixed, + deg_to_rad, + get_position_clock, + gen_code_12, +} from '@/lib/utils'; + +import { useWorld } from '@/contexts/World'; +import { useDeviceOrientation } from '@/contexts/DeviceOrientation'; +import { useFengShui } from '@/contexts/FengShui'; +import { BaguaIcon } from '@/components/icons/bagua'; + +const RADIUS_RATIO = 0.66; +const ICON_RATIO = 0.094; +const RADIAN_45_HALF = RADIAN_45 / 2; + +const fix2 = fixed(2); +const fix3 = fixed(3); + +export const FengShuiBaguaInfo = () => { + const { worldInfo: world } = useWorld(); + const deviceOrientation = useDeviceOrientation(); + const { ready, get_bagua_start_north } = useFengShui(); + + const [boxes, setBoxes] = useState([]); + + const chart_w = world?.chart?.width; + const chart_h = world?.chart?.height; + const alpha = deviceOrientation?.alpha || 0; + + const wrapperStyle = useMemo( + () => css` + ${tw`absolute text-white`} + width: ${chart_w}px; + height: ${chart_h}px; + `, + [chart_w] + ); + + const update = useCallback( + index => { + const chart_w_half = chart_w / 2; + const chart_h_half = chart_h / 2; + const icon_size = fix3(chart_w_half * ICON_RATIO); + const angle = index * RADIAN_45 + deg_to_rad(alpha); + const radius = chart_w_half * RADIUS_RATIO; + const pos = get_position_clock(angle, radius, { + x: chart_w_half, + y: chart_h_half, + }); + const z_index = Z_INDEX_FENGSHUI_BAGUA_INFO + index * 1; + const style = css` + ${tw`absolute flex flex-col justify-center items-center`} + top: ${fix2(pos.y)}px; + left: ${fix2(pos.x)}px; + z-index: ${z_index}; + font-size: ${world?.text_lg}px; + line-height: 1em; + transform: translate(-50%, -50%); + `; + return { icon_size, style }; + }, + [chart_w, alpha] + ); + + useEffect(() => { + if (ready) { + setBoxes( + [...new Array(8)].map((_, index) => { + const bagua = get_bagua_start_north(index); + const name = bagua?.name; + return name + ? { + key: gen_code_12(), + en: name.en, + ch: name.zh_cn?.alphabet, + } + : {}; + }) + ); + } + }, [ready]); + + useEffect(() => { + if (ready && chart_w > 0) { + setBoxes(prev => prev.map((p, i) => ({ ...p, ...update(i) }))); + } + }, [ready, chart_w, alpha, update]); + + return ( +
+ {boxes.map((box, i) => ( +
+ +
{box.ch}
+
+ ))} +
+ ); +}; diff --git a/docs/examples/chart.jsx b/docs/examples/chart.jsx new file mode 100644 index 0000000..a1a05e1 --- /dev/null +++ b/docs/examples/chart.jsx @@ -0,0 +1,50 @@ +import React, { useMemo } from 'react'; +import tw, { css } from 'twin.macro'; + +import { gen_code_12 } from '@/lib/utils'; +import { useErrors } from '@/contexts/Errors'; +import { useWorld } from '@/contexts/World'; +import { useFengShuiSync } from '@/contexts/FengShui'; + +import { FengShuiTwentyFour } from '@/components/fengshui/twentyfour'; +import { FengShuiTwentyFourInfo } from '@/components/fengshui/twentyfour_info'; +import { FengShuiCircle } from '@/components/fengshui/circle'; +import { FengShuiNorth } from '@/components/fengshui/north'; +import { FengShuiJiuXing } from '@/components/fengshui/jiuxing'; + +const wrapperStyleBase = tw`flex-none relative overflow-hidden w-full flex flex-col justify-center items-center`; + +export const ChartChart = () => { + const { errors } = useErrors(); + const { worldInfo: world } = useWorld(); + + const chart_w = world?.chart?.width; + const chart_h = world?.chart?.height; + + const wrapperStyle = useMemo( + () => css` + width: ${chart_w || 0}px; + height: ${chart_h || 0}px; + `, + [chart_w] + ); + + // Sync the latest primary profile to FengShuiContext.profile + useFengShuiSync(); + + return errors.length ? ( +
+ {errors.map(err => ( +
{err.error}
+ ))} +
+ ) : ( +
+ + + + + +
+ ); +}; diff --git a/docs/examples/index.md b/docs/examples/index.md new file mode 100644 index 0000000..8d434de --- /dev/null +++ b/docs/examples/index.md @@ -0,0 +1,298 @@ +# Examples + +[1. Example Rust + React Codes](#1-example-rust-react-codes) +[2. Setups for WASM Apps in Webpack](#2-setups-for-wasm-apps-in-webpack) +[3. Using WASM Apps from React](#3-using-wasm-apps-from-react) +[4. Feng-Shui Examples](#4-feng-shui-examples) +    [4-1. `src/contexts/FengShui.js`](#4-1-srccontextsfengshuijs) +    [4-2. `src/components/fengshui/jiuxing.jsx`](#4-2-srccomponentsfengshuijiuxingjsx) + +## 1. Example Rust + React Codes + +I picked up some files from one of the real-world projects of mine. +In this project, I have Rust codes in `src_for_wasm` and React codes in `src`. + +Rust +- [src_for_wasm/Cargo.toml](./Cargo.toml) +- [src_for_wasm/lib.rs](./lib.rs) +Acts like a proxy to all the public functions provided by _mikaboshi_. + +React +- [src/contexts/FengShui.js](FengShui.js) +A context provider set to the React app top, and delegates functions provided by `src_for_wasm/lib.rs`. +- [src/components/chart/chart.jsx](chart.jsx) +Provides a layout for Feng-Shui chart which contains a several child components such as `src/components/fengshui/jiuxing.jsx`, `src/components/twentyfour.jsx`, and so forth. +- [src/components/fengshui/bagua_info.jsx](bagua_info.jsx) +- [src/components/fengshui/bagua.jsx](bagua.jsx) +- [src/components/fengshui/jiuxing.jsx](jiuxing.jsx) +- [src/components/fengshui/north.jsx](north.jsx) +- [src/components/fengshui/twentyfour_info.jsx](twentyfour_info.jsx) +- [src/components/fengshui/twentyfour.jsx](twentyfour.jsx) +- [src/lib/utils.js](utils.js) + + +## 2. Setups for WASM Apps in Webpack + +For how you can serve a WASM app, you may want to check out +one of my other projects, +_[perlin-experiment](https://github.com/minagawah/perlin-experiment)_. +Setups are about the same. + + +## 3. Using WASM Apps from React + +When using a WASM app from React, you need to first +asynchronously wait for the module to be ready. + +```js +import React, { useContext, createContext, useEffect, useState } from 'react'; +import init, { order_pizza } from 'wasm-pizza'; + +const WASM_PATH = + NODE_ENV === 'production' + ? 'wasm/wasm-pizza/wasm-pizza_bg.wasm' + : void 0; + +const PizzaContext = createContext({ + ready: false, + orderPizza: () => {}, +}); + +export const PizzaProvider = () => { + const [ready, setReady] = useState(false); + + useEffect(() => { + if (ready !== true) { + init(WASM_PATH) + .then(() => { + setReady(true); + }) + .catch(err => { + throw err; + }); + } + }, []); + + const orderPizza = params => { + return order_pizza(params); + }; + + return ( + +}; + +export const usePizza = () => useContext(PizzaContext); +``` + +Notice that we import `init` from `wasm-pizza` which is a compiled WASM app +provided as a NPM module. As mentioned in the previous section, +[take a look at one of my projects](https://github.com/minagawah/perlin-experiment) +for it explains how. + +Now, you may use the provider: + +`src/App.jsx` + +```js +ReactDOM.render( + + + , + document.getElementById('root') +); +``` + +From one of your components, you call the method: + +```js +import { usePizza } from '@/contexts/Pizza'; + +export const Order = () => { + const { ready, orderPizza } = usePizza(); + const [pizza, setPizza] = useState(null); + + useEffect(() => { + setPizza( + orderPizza() + ); + }, [ready]) + + return
{pizza}
; +}; +``` + +## 4. Feng-Shui Examples + +For example files provided at the beginning, +I will explain key features found in the codes. +Although it is the usage from React, +I believe you will at least get ideas +when using _mikaboshi_ for your projects. + + +### 4-1. `src/contexts/FengShui.js` + +Source: [src/contexts/FengShui.js](FengShui.js) + +`src/contexts/FengShui.js` is a React context provider, +and it provides `FengShuiContext`. +For resources provided by `FengShuiContext` +will be accessible for any child components +when using `useFengShui()`. + +```js +const FengShuiContext = createContext({ + ready: false, + profile: null, // localtime, direction, sector + bazi: null, + lichun: null, + unpan_xing: null, // 運盤星 + shan_xing: null, // 山星 + xiang_xing: null, // 向星 + update: noop, + ... + ... + ... +}); +``` + +`src/contexts/FengShui.js` loads a WASM app (`src_for_wasm/lib/rs`). +Since it loads the WASM app asynchronously, +components must wait for `ready` to become `true` +for all the features to become available. + +For `profile` is not actually peculiar to `src/contexts/FengShui.js`, +but is something managed in another provider `src/contexts/Profiles.js`. +Since there is no way for 2 providers to communicate, +we run `useFengShuiSync()` somewhere in one of the components +to sync the contents of `profile`. + +`_set()` runs when the content of `profile` changes: + +```js + const _set = useCallback( + (prof = {}) => { + const { localtime: current, direction, sector } = prof; + + if (ready && current && direction) { + const lichun_0 = get_lichun(current.year()); + const lichun = moment(lichun_0); + const center = get_unpan_xing_index({ current, lichun }); + + const xgtu = get_xiaguatu_from_unpan_index({ + unpan_xing_center: center, + xiang_xing_direction: direction, + xiang_xing_sector: sector, + }); + + setBazi( + normalize_bazi_data( + wasm_get_bazi(datetime_params_from_localtime(current)) + ) + ); + setLiChun(lichun); + setUnPanXing(xgtu.unpan_xing); + setShanXing(xgtu.shan_xing); + setXiangXing(xgtu.xiang_xing); + } + }, + [ready, profile?.locatltime, profile?.direction] + ); +``` + +In the above, using _mikaboshi_'s `get_xiaguatu_from_unpan_index()` +to obtain 下卦図 (Xia-Gua-Tu). For 3 arguments required, +we already have `xiang_xing_direction` and `xiang_xing_sector` +in `profile`, but for `unpan_xing_center` needs a preparation. + +For `unpan_xing_center`, we run `get_unpan_xing_index()`. +And, again, it requires another preparation for `lichun`, +and we run `get_lichun()` for `lichun`. + + +### 4-2. `src/components/fengshui/jiuxing.jsx` + +Source: [src/components/fengshui/jiuxing.jsx](jiuxing.jsx) + +`jiuxing.jsx` is one of the child components wrapped in `FengShuiContext` provider. +Here is how it starts: + +```js +export const FengShuiJiuXing = () => { + const { worldInfo: world } = useWorld(); + const deviceOrientation = useDeviceOrientation(); + const { + ready, + unpan_xing, + shan_xing, + xiang_xing, + get_xiaguatu_from_unpan_index, + get_jiuxing_dipan_positions_from_direction, + get_twentyfour_direction_from_degrees, + get_shengsi_mapping, + } = useFengShui(); +``` + +As mentioned, using `useFengShui()`, will get you an access +for resources provided by `FengShuiContext`. + +Let's continue. + +```js + const { direction: curr_dir } = get_twentyfour_direction_from_degrees( + 360 - alpha + ); +``` + +Now, we are using `get_twentyfour_direction_from_degrees()`. + +For a given angle (in degrees), +`get_twentyfour_direction_from_degrees()` +returns `direction` and `sector`. + +`direction` is a compass direction represented +in a lower case string (e.g. `n`, `ne`, `e`, `se`, etc.). + +`sector` is special concept unique to +[二十四山向 (Er-Shi-Si Shan-Xiang)](../compass.md). +For each compass direction is further divided into 3 sectors, +represented in a number `1`, `2`, or `3`. + +Yet, for the above example, this time, +we are getting `direction` only, +and naming it: `curr_dir` + +```js + const u_id = unpan_xing.center; + + // When calculating for 下卦図 (Xia-Gua-Tu), not only + // the current 運盤星 (Un-Pan Xing), but we also want + // all 九星 (Jiu-Xing) in the 洛書 (Lo-Shu) order. + // Although we have `JIU_XING_DI_PAN_POSITIONS` + // which defines 洛書 (Lo-Shu) order, we want it + // in re-arranged order for the current device rotation, + // and that is what we pass for the second argument + // of `get_xiaguatu_from_unpan_index()`. + const u_order = get_jiuxing_dipan_positions_from_direction(curr_dir); + + // Now, calculate for 下卦図 (Xia-Gua-Tu). + const xiagua = get_xiaguatu_from_unpan_index({ + unpan_xing_center: u_id, + unpan_xing_order: u_order, + xiang_xing_direction: xiang_xing.direction, + xiang_xing_sector: xiang_xing.sector, + }); +``` + +As mentioned before, `unpan_xing` (運盤星; Un-Pan Xing) +is managed in `src/contexts/FengShui.js`, +and we simply want to refer to it. +The same goes for `shan_xing` (山星; Shan-Xing), +and `xiang_xing` (向星; Xiang-Xing), +and we expect that we already have the values +stored in `src/contexts/FengShui.js`. diff --git a/docs/examples/jiuxing.jsx b/docs/examples/jiuxing.jsx new file mode 100644 index 0000000..3ac38aa --- /dev/null +++ b/docs/examples/jiuxing.jsx @@ -0,0 +1,258 @@ +/** + * This component renders 下卦図 (Xia-Gua-Tu) + * (also known as 飞星図; Fei-Xing-Tu; "Flying Star Chart"). + * Like any other Feng-Shui charts, it consists of 9 boxes. + * Each box holds 3 different kinds of 九星 (Jiu-Xing), + * namely, + * 運盤星 (Un-Pan Xing) at the BOTTOM CENTER, + * 山星 (Shan-Xing) at the TOP LEFT, and + * 向星 (Xiang-Xing) at the TOP RIGHT. + * It also displays (in each box) the star's + * 生死衰旺 (Sheng-Si Shuai-Wang) status. + */ +import React, { + useRef, + useState, + useMemo, + useEffect, + useCallback, +} from 'react'; +import { compose, tap } from 'ramda'; +import tw, { css } from 'twin.macro'; + +import { Z_INDEX_FENGSHUI_JIU_XING_BOXES } from '@/constants'; +import { fixed, gen_code_12 } from '@/lib/utils'; + +import { useWorld } from '@/contexts/World'; +import { useDeviceOrientation } from '@/contexts/DeviceOrientation'; +import { useFengShui } from '@/contexts/FengShui'; + +const BOX_RATIO = 0.55; + +const SHENG_SI_COLOR = { + si: tw`bg-tomato-dark text-gray-100`, + shuai: tw`bg-abura-dark text-gray-100`, +}; + +const fix2 = fixed(2); + +// This is the inner most wrapper which holds 9 boxes. +// As you can see, we have 3 rows and 3 columns. +const wrapperStyle = css` + width: calc(100% - 2px); + height: calc(100% - 2px); + display: grid; + grid-gap: 1px; + grid-template-columns: repeat(3, 1fr); + grid-template-rows: repeat(3, 1fr); +`; + +// This is the wrapper for each box. +// As you can see, it has 2 rows and 2 columns. +// However, the bottom row will fill up +// using all 2 columns, and 運盤星 (Un-Pan Xing) +// is placed in the middle. +const boxStyle = css` + ${tw`text-gray-900 text-sm`} + display: grid; + grid-gap: 1px; + grid-template-columns: repeat(2, 0.5fr); + grid-template-rows: 0.333fr 0.666fr; +`; + +const xingStyle = tw` + flex flex-col justify-center items-center text-sm font-medium +`; + +export const FengShuiJiuXing = () => { + const { worldInfo: world } = useWorld(); + const deviceOrientation = useDeviceOrientation(); + const { + ready, + unpan_xing, + shan_xing, + xiang_xing, + get_xiaguatu_from_unpan_index, + get_jiuxing_dipan_positions_from_direction, + get_twentyfour_direction_from_degrees, + get_shengsi_mapping, + } = useFengShui(); + + const [flyingStarChart, setFlyingStarChart] = useState([]); + + const chart_w = world?.chart?.width; + const chart_h = world?.chart?.height; + const body_h = world?.body?.height; + + // Passing current degrees for the device, and obtaining + // the compass direction: "n", "ne", "e", "se", etc. + const alpha = deviceOrientation?.alpha || 0; + + // `alpha` is a value that you get from Web API, + // but what you get for `alpha` is counterintuitive... + // When you have 10 degrees, it means that your device + // is not pointing toward the compass NE, but NW. + // When the device is pointing NW, you will see + // the red arrow (which usually points the magnetic N) + // will come to the top right. There, getting 10 degrees + // means that your device is rotating counter-clockwise, + // but we want the opposite. When it gives us 10 degrees, + // we want it to mean it is rotating clockwise, + // and the device to be pointing NE (instead of NW). + // That is why we are passing the complementary angle + // as a function argument (by subtracting the degree + // from 360). + const { direction: curr_dir } = get_twentyfour_direction_from_degrees( + 360 - alpha + ); + + // This is the outer most wrapper, and is positioned `absolute`. + const wrapperWrapperWrapperStyle = useMemo( + () => css` + ${tw`absolute w-full flex flex-col justify-center items-center`} + height: ${fix2(body_h)}px; + z-index: ${Z_INDEX_FENGSHUI_JIU_XING_BOXES}; + `, + [body_h] + ); + + // The 2nd wrapper which basically defines width and height, + // and place the inner wrapper vertically and horizontally + // in the center. + const wrapperWrapperStyle = useMemo(() => { + const width = chart_w * BOX_RATIO; + return css` + ${tw`flex flex-col justify-center items-center bg-gray-900`} + width: ${fix2(width)}px; + height: ${fix2(width)}px; + `; + }, [chart_w]); + + // As long as you have information for the current + // 運盤星 (Un-Pan Xing) and 向星 (Xiang-Xing), + // you can have `get_xiaguatu_from_unpan_index()` + // calculates 下卦図 (Xia-Gua-Tu) for you. + // Once you obtain 下卦図 (Xia-Gua-Tu) + // (expressed as `xiagua` in the program), + // you will get charts for all 3 stars. + // For 生死衰旺 (Sheng-Si Shuai-Wang) is + // calculated from 運盤星 (Un-Pan Xing) only. + useEffect(() => { + if (ready && unpan_xing && shan_xing && xiang_xing) { + // console.log('[fengshui/jiuxing] curr_dir: ', curr_dir); + + // The current 運盤星 (Un-Pan Xing) holds the key to everything! + const u_id = unpan_xing.center; + + // When calculating for 下卦図 (Xia-Gua-Tu), not only + // the current 運盤星 (Un-Pan Xing), but we also want + // all 九星 (Jiu-Xing) in the 洛書 (Lo-Shu) order. + // Although we have `JIU_XING_DI_PAN_POSITIONS` + // which defines 洛書 (Lo-Shu) order, we want it + // in re-arranged order for the current device rotation, + // and that is what we pass for the second argument + // of `get_xiaguatu_from_unpan_index()`. + const u_order = get_jiuxing_dipan_positions_from_direction(curr_dir); + + // Now, calculate for 下卦図 (Xia-Gua-Tu). + const xiagua = get_xiaguatu_from_unpan_index({ + unpan_xing_center: u_id, + unpan_xing_order: u_order, + xiang_xing_direction: xiang_xing.direction, + xiang_xing_sector: xiang_xing.sector, + }); + + const u_chart = xiagua?.unpan_xing?.chart || []; + const s_chart = xiagua?.shan_xing?.chart || []; + const x_chart = xiagua?.xiang_xing?.chart || []; + + if (u_chart.length > 0 && s_chart.length > 0 && x_chart.length > 0) { + // 生死衰旺 (Sheng-Si Shuai-Wang) for the current 運盤星 (Un-Pan Xing). + const shengsi = get_shengsi_mapping({ + unpan_id: u_id, + unpan_xing_chart: u_chart, + }); + + let arr = []; + + // Iterating for 9 boxes, and for each box, we have 3 stars. + // For each star, we are simply adding 1 to the star's "index" + // to get the star's "number" which is to be displayed. + for (let i = 0; i < 9; i++) { + const kanji = shengsi[i]?.kanji; + + arr.push({ + key: gen_code_12(), + style: SHENG_SI_COLOR[kanji] || tw`bg-cream`, + unpan_xing: { num: u_chart[i] + 1, kanji }, + shan_xing: { num: s_chart[i] + 1 }, + xiang_xing: { num: x_chart[i] + 1 }, + }); + } + + if (arr.length > 0) { + setFlyingStarChart(arr); + } + } + } + }, [ + ready, + unpan_xing?.center, + shan_xing?.center, + xiang_xing?.center, + curr_dir, + ]); + + return ( +
+
+
+ {flyingStarChart.map((box, i) => ( +
+
+ {box.shan_xing.num} +
+ +
+ {box.xiang_xing.num} +
+ +
+
{box.unpan_xing.num}
+
{box.unpan_xing.kanji}
+
+
+ ))} +
+
+
+ ); +}; diff --git a/docs/examples/lib.rs b/docs/examples/lib.rs new file mode 100644 index 0000000..f0bc9bc --- /dev/null +++ b/docs/examples/lib.rs @@ -0,0 +1,201 @@ +use mikaboshi::bagua::{get_bagua_start_north as _bagua_start_north, Bagua}; +use mikaboshi::compass::{ + get_direction_positions_in_chart as _direction_positions_in_chart, + get_opposite_direction as _opposite_direction, + get_twentyfour_data_from_direction as _twentyfour_data_from_direction, + get_twentyfour_data_from_index as _twentyfour_data_from_index, + get_twentyfour_direction_from_degrees as _twentyfour_direction_from_degrees, + get_twentyfour_direction_from_index as _twentyfour_direction_from_index, Direction, + TwentyFourType, +}; +use mikaboshi::ganzhi::Bazi; +use mikaboshi::jiuxing::{ + get_jiuxing_dipan_positions_from_direction as _jiuxing_dipan_positions_from_direction, + get_jiuxing_from_index as _jiuxing_from_index, + get_xiaguatu_from_unpan_index as _xiaguatu_from_unpan_index, + unpan_xing_index as _unpan_xing_index, JiuXing, XiaGuaTu, +}; +use mikaboshi::shengsi::{get_shengsi_mapping as _get_shengsi_mapping, ShengSi}; +use mikaboshi::solar_terms::get_lichun as _get_lichun; +use mikaboshi::time::{Date, DateTime}; +use std::collections::HashMap; +use std::convert::{From, TryInto}; +use wasm_bindgen::prelude::*; + +// use log::info; +// use log::Level; + +pub mod structs; + +use crate::structs::{DateParams, DateTimeParams, ShengSiParams, XiaGuaTuParams}; + +/// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global allocator. +#[cfg(feature = "wee_alloc")] +#[global_allocator] +static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; + +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace = console)] + fn log(s: &str); +} + +#[wasm_bindgen(start)] +pub fn main() { + console_error_panic_hook::set_once(); +} + +// ================================================================ +// 八卦 (Bagua) +// ================================================================ + +#[wasm_bindgen] +pub fn get_bagua_start_north(index: usize) -> JsValue { + let bagua: Option<&Bagua> = _bagua_start_north(index); + JsValue::from_serde(&bagua).unwrap() +} + +// ================================================================ +// 二十四山向 (Er-Shi Si-Shan Xiang) +// ================================================================ + +#[wasm_bindgen] +pub fn get_twentyfour_direction_from_index(index: usize) -> JsValue { + let dir: &Direction = _twentyfour_direction_from_index(index); + JsValue::from_serde(dir).unwrap() +} + +#[wasm_bindgen] +pub fn get_twentyfour_data_from_index(index: usize) -> JsValue { + let t_type: TwentyFourType = _twentyfour_data_from_index(index); + match t_type { + TwentyFourType::Bagua(bagua) => JsValue::from_serde(bagua).unwrap(), + TwentyFourType::Stem(stem) => JsValue::from_serde(stem).unwrap(), + TwentyFourType::Branch(branch) => JsValue::from_serde(branch).unwrap(), + } +} + +#[wasm_bindgen] +pub fn get_twentyfour_direction_from_degrees(degrees: f32) -> JsValue { + let dir: Direction = _twentyfour_direction_from_degrees(degrees); + // log(&format!("[wasm] degrees: {}", degrees)); + // log(&format!("[wasm] dir: {:?}", dir)); + JsValue::from_serde(&dir).unwrap() +} + +#[wasm_bindgen] +pub fn get_twentyfour_data_from_direction(direction: &str, sector: usize) -> JsValue { + let t_type: TwentyFourType = _twentyfour_data_from_direction(direction, sector); + match t_type { + TwentyFourType::Bagua(bagua) => JsValue::from_serde(bagua).unwrap(), + TwentyFourType::Stem(stem) => JsValue::from_serde(stem).unwrap(), + TwentyFourType::Branch(branch) => JsValue::from_serde(branch).unwrap(), + } +} + +// ================================================================ +// 干支 (Gan-Zhi) +// ================================================================ + +#[wasm_bindgen] +pub fn get_bazi(params: &JsValue) -> JsValue { + let params: DateTimeParams = params.into_serde().unwrap(); + let localtime = DateTime::from(¶ms); + let zone = params.zone; + JsValue::from_serde(&Bazi::from_local(&localtime, zone)).unwrap() +} + +#[wasm_bindgen] +pub fn get_lichun(year: i16) -> JsValue { + // log(&format!("{:?}", year)); + + let lichun = _get_lichun(year); + JsValue::from_str(&format!( + "{:04}-{:02}-{:02}", + lichun.year as u16, lichun.month as u8, lichun.day as u8 + )) +} + +// ================================================================ +// 九星 (Jiu-Xing) +// ================================================================ + +#[wasm_bindgen] +pub fn get_jiuxing_from_index(index: usize) -> JsValue { + let dir: &JiuXing = _jiuxing_from_index(index); + JsValue::from_serde(dir).unwrap() +} + +#[wasm_bindgen] +pub fn get_unpan_xing_index(current: &JsValue, lichun: &JsValue) -> JsValue { + let params_1: DateParams = current.into_serde().unwrap(); + let params_2: DateParams = lichun.into_serde().unwrap(); + // log(&format!("params_1: {:?}", params_1)); + // log(&format!("params_2: {:?}", params_2)); + + let current = Date::from(¶ms_1); + let lichun = Date::from(¶ms_2); + + let index: usize = _unpan_xing_index(¤t, &lichun); + JsValue::from_f64(index as f64) +} + +#[wasm_bindgen] +pub fn get_xiaguatu_from_unpan_index(params: &JsValue) -> JsValue { + let params: XiaGuaTuParams = params.into_serde().unwrap(); + // log("[wasm] get_xiaguatu_from_unpan_index()"); + // log(&format!("[wasm] params: {:?}", params)); + + let unpan_xing_order: [usize; 9] = + params + .unpan_xing_order + .try_into() + .unwrap_or_else(|v: Vec| { + panic!("Expected a Vec of length 9 but it was {}", v.len()) + }); + + let xia_gua_tu: HashMap<&str, XiaGuaTu> = _xiaguatu_from_unpan_index( + params.unpan_xing_center, + &unpan_xing_order, + params.xiang_xing_direction.as_str(), + params.xiang_xing_sector, + ); + + JsValue::from_serde(&xia_gua_tu).unwrap() +} + +// A simple accessor for getting values in JIU_XING_DI_PAN_POSITIONS. +#[wasm_bindgen] +pub fn get_jiuxing_dipan_positions_from_direction(direction: &str) -> JsValue { + JsValue::from( + (match _jiuxing_dipan_positions_from_direction(direction) { + Some(positions) => positions.to_vec(), + _ => Vec::new(), + }) + .into_iter() + .map(|index| JsValue::from(index as u32)) + .collect::(), + ) +} + +// ================================================================ +// 生死衰旺 (Sheng-Si Shuai-Wang) +// ================================================================ + +#[wasm_bindgen] +pub fn get_shengsi_mapping(params: &JsValue) -> JsValue { + let params: ShengSiParams = params.into_serde().unwrap(); + let unpan_id: usize = params.unpan_id; + + let chart: [usize; 9] = params + .unpan_xing_chart + .try_into() + .unwrap_or_else(|v: Vec| { + panic!("Expected a Vec of length 9 but it was {}", v.len()) + }); + + let mapping: Vec> = _get_shengsi_mapping(unpan_id, &chart); + // log(&format!("[wasm] mapping: {:?}", mapping)); + + JsValue::from_serde(&mapping).unwrap() +} diff --git a/docs/examples/north.jsx b/docs/examples/north.jsx new file mode 100644 index 0000000..3ee8259 --- /dev/null +++ b/docs/examples/north.jsx @@ -0,0 +1,94 @@ +/** + * SVG Pie Drawing + * https://medium.com/hackernoon/a-simple-pie-chart-in-svg-dbdd653b6936 + */ +import React, { useRef, useMemo, useEffect, useCallback } from 'react'; +import { compose, tap } from 'ramda'; +import tw, { css } from 'twin.macro'; +import Snap from 'snapsvg-cjs'; + +import { RADIAN_45, RADIAN_90, Z_INDEX_FENGSHUI_NORTH } from '@/constants'; +import { int, rad_to_deg, normalize_angle, get_position } from '@/lib/utils'; + +import { useWorld } from '@/contexts/World'; +import { useDeviceOrientation } from '@/contexts/DeviceOrientation'; + +const FILL_COLOR = '#ef4444'; +const OUTER_RATIO = 0.8; +const INNER_RATIO = 0.7; +const ARROW_SIZE = (OUTER_RATIO - INNER_RATIO) * 0.5; + +const wrapperStyle = css` + ${tw`absolute w-full flex flex-col justify-center items-center`} + z-index: ${Z_INDEX_FENGSHUI_NORTH}; +`; + +export const FengShuiNorth = () => { + const { worldInfo: world } = useWorld(); + const deviceOrientation = useDeviceOrientation(); + + const snap = useRef(null); + + const chart_w = world?.chart?.width; + const chart_h = world?.chart?.height; + const alpha = deviceOrientation?.alpha; + + const northStyle = useMemo(() => { + const rotation = normalize_angle(alpha - rad_to_deg(Math.PI / 2)); + return css` + width: ${chart_w}px; + height: ${chart_h}px; + transform: rotate(${rotation}deg); + `; + }, [chart_w, alpha]); + + // A: rx,ry x-axis-rotation large-flag,sweep-flag end-x,end-y + const draw = useCallback( + ({ index }) => { + const s = snap.current && Snap(snap.current); + + if (s) { + } + }, + [chart_w, chart_h] + ); + + useEffect(() => { + const s = snap.current && Snap(snap.current); + if (s) { + const g = s.path(''); + g.remove(); + + const pos = []; + pos[0] = { + x: INNER_RATIO, + y: -ARROW_SIZE, + }; + pos[1] = { + x: OUTER_RATIO, + y: 0, + }; + pos[2] = { + x: INNER_RATIO, + y: ARROW_SIZE, + }; + + const path = [ + `M${pos[0].x},${pos[0].y}`, + `L${pos[1].x},${pos[1].y}`, + `L${pos[2].x},${pos[2].y}`, + `L${pos[0].x},${pos[0].y}`, + ].join(' '); + + s.path(path).attr({ + fill: FILL_COLOR, + }); + } + }, [chart_w, chart_h]); + + return ( +
+ +
+ ); +}; diff --git a/docs/examples/twentyfour.jsx b/docs/examples/twentyfour.jsx new file mode 100644 index 0000000..6ba6063 --- /dev/null +++ b/docs/examples/twentyfour.jsx @@ -0,0 +1,147 @@ +/** + * SVG Pie Drawing + * https://medium.com/hackernoon/a-simple-pie-chart-in-svg-dbdd653b6936 + */ +import React, { useRef, useMemo, useEffect, useCallback } from 'react'; +import { compose, tap } from 'ramda'; +import tw, { css } from 'twin.macro'; +import Snap from 'snapsvg-cjs'; + +import { RADIAN_15, Z_INDEX_FENGSHUI_ER_SHI_SI } from '@/constants'; + +import { + rad_to_deg, + deg_to_rad, + normalize_angle, + get_position, +} from '@/lib/utils'; + +import { TW_CUSTOM_COLORS } from '@/styles/shared'; + +import { useWorld } from '@/contexts/World'; +import { useDeviceOrientation } from '@/contexts/DeviceOrientation'; +import { useFengShui } from '@/contexts/FengShui'; + +const FILL_COLOR = '#303030'; +const FILL_COLOR_DARK = '#000000'; +const STROKE_COLOR = '#ffffff'; + +const wrapperStyle = css` + ${tw`absolute w-full flex flex-col justify-center items-center`} + z-index: ${Z_INDEX_FENGSHUI_ER_SHI_SI}; +`; + +export const FengShuiTwentyFour = () => { + const { worldInfo: world } = useWorld(); + const deviceOrientation = useDeviceOrientation(); + const { + ready, + xiang_xing, + get_twentyfour_direction_from_index, + get_twentyfour_data_from_index, + } = useFengShui(); + + const snap = useRef(null); + + const chart_w = world?.chart?.width; + const chart_h = world?.chart?.height; + const alpha = deviceOrientation?.alpha || 0; + + const svgStyle = useMemo(() => { + const rotation = normalize_angle( + alpha - rad_to_deg(Math.PI / 2 + RADIAN_15 / 2) + ); + + return css` + transform: rotate(${rotation}deg); + width: ${chart_w}px; + height: ${chart_h}px; + `; + }, [chart_w, alpha]); + + const draw = useCallback( + ({ index }) => { + const s = snap.current && Snap(snap.current); + + if (s && ready) { + const beg = get_position(index * RADIAN_15); + const end = get_position(index * RADIAN_15 + RADIAN_15); + const large = end.deg - beg.deg > 180 ? 1 : 0; + + // Remember, the whole wrapper is rotated later + // by 262.5 (= 90 + 15/2), degrees so that + // the first slice which originally sits + // at the 3 o'clock position will come + // to the 12 o'clock position. + // + // Also, we apply `viewbox="-1 -1 2 2"` for the SVG, + // meaning, the origin of SVG is situated + // at the very center of the wrapper. + // That is to say, we have `x = 0`. + // When we have `x = 1`, it means `x` is reaching + // all the way at the right edge of the wrapper. + // + // For each slice, we use SVG's arc function + // which is defined as: + // + // A rx ry x-axis-rotation large-arc-flag sweep-flag x y + // + // A1,1 0 0,1 0.965,0.258 + // + // At first, we will first move (`M`) to where + // it is close to the right edge of the screen. + // Since we have no ratio specified, and the SVG + // will fill up the whole space for the wrapper, + // we will have it being `M1,0`. + // Next, for the arc, we will probably have + // `A1,1 0 0,1 0.965,0.258`. + // So, it is an arc having `1` for the radius, + // and it will draw the arc for 15 degrees. + // Lastly, we have `L0,0` to go back to the origin, + // otherwise, it won't fill (with given color) + // the region surrounded by the path. + + const path = [ + `M${beg.x},${beg.y}`, + `A1,1 0 ${large},1 ${end.x},${end.y}`, + `L0,0`, + ].join(' '); + + const er_shi_si = get_twentyfour_data_from_index(index); + const { direction, sector } = + get_twentyfour_direction_from_index(index); + + let fill = er_shi_si[0] === 2 ? FILL_COLOR : FILL_COLOR_DARK; + if ( + xiang_xing && + direction === xiang_xing.direction && + sector === xiang_xing.sector + ) { + fill = TW_CUSTOM_COLORS['abura-lightest']; + } + + s.path(path).attr({ + fill, + stroke: STROKE_COLOR, + strokeWidth: world?.stroke_size, + }); + } + }, + [ready, chart_w, xiang_xing] + ); + + useEffect(() => { + const s = snap.current && Snap(snap.current); + if (s && ready) { + [...new Array(24)].map((_, i) => { + draw({ index: i }); + }); + } + }, [ready, chart_w, xiang_xing, draw]); + + return ( +
+ +
+ ); +}; diff --git a/docs/examples/twentyfour_info.jsx b/docs/examples/twentyfour_info.jsx new file mode 100644 index 0000000..dd0f2c6 --- /dev/null +++ b/docs/examples/twentyfour_info.jsx @@ -0,0 +1,147 @@ +/** + * SVG Pie Drawing + * https://medium.com/hackernoon/a-simple-pie-chart-in-svg-dbdd653b6936 + */ +import React, { useState, useMemo, useEffect, useCallback } from 'react'; +import { compose, tap } from 'ramda'; +import tw, { css } from 'twin.macro'; + +import { RADIAN_15, Z_INDEX_FENGSHUI_ER_SHI_SI_INFO } from '@/constants'; + +import { + int, + fixed, + deg_to_rad, + get_position_clock, + gen_code_12, +} from '@/lib/utils'; + +import { useWorld } from '@/contexts/World'; +import { useDeviceOrientation } from '@/contexts/DeviceOrientation'; +import { useFengShui } from '@/contexts/FengShui'; + +const RATIO = 0.9; +const RADIAN_15_HALF = RADIAN_15 / 2; + +const fix2 = fixed(2); + +const boxBaseStyle = css` + ${tw`absolute flex flex-col justify-center items-center`} + line-height: 1em; + transform: translate(-50%, -50%); +`; + +const sectorStyle = css` + font-size: 0.94em; +`; + +export const FengShuiTwentyFourInfo = () => { + const { worldInfo: world } = useWorld(); + const deviceOrientation = useDeviceOrientation(); + const { + ready, + xiang_xing, + get_twentyfour_direction_from_index, + get_twentyfour_direction_from_degrees, + get_twentyfour_data_from_index, + } = useFengShui(); + + const [boxes, setBoxes] = useState([]); + + const chart_w = world?.chart?.width; + const chart_h = world?.chart?.height; + const alpha = deviceOrientation?.alpha || 0; + + const wrapperStyle = useMemo( + () => css` + ${tw`absolute text-white`} + width: ${chart_w}px; + height: ${chart_h}px; + `, + [chart_w] + ); + + const update = useCallback( + index => { + if (!ready) return; + + const z_index = Z_INDEX_FENGSHUI_ER_SHI_SI_INFO + index * 1; + const chart_w_half = chart_w / 2; + const chart_h_half = chart_h / 2; + const angle = index * RADIAN_15 + deg_to_rad(alpha); + const radius = chart_w_half * RATIO; + + const pos = get_position_clock(angle, radius, { + x: chart_w_half, + y: chart_h_half, + }); + + const { direction, sector } = get_twentyfour_direction_from_index(index); + + const color = + xiang_xing && + direction === xiang_xing.direction && + sector === xiang_xing.sector + ? 'color: #000000' + : ''; + + return { + style: css` + z-index: ${z_index}; + top: ${fix2(pos.y)}px; + left: ${fix2(pos.x)}px; + font-size: ${world?.text_base}px; + ${color} + `, + }; + }, + [ready, chart_w, alpha, xiang_xing] + ); + + useEffect(() => { + if (ready) { + const arr = [...new Array(24)].map((_, i) => { + const er_shi_si = get_twentyfour_data_from_index(i); + const name = er_shi_si?.name; + const degrees = i * 15; + + const { direction, sector } = + get_twentyfour_direction_from_degrees(degrees); + + const text = name?.zh_cn?.alphabet || ''; + const text2 = `${direction.toUpperCase()}${sector}`; + // console.log(`[fengshui/twentyfour_info] [${i}] (${degrees} degrees)`); + // console.log(`[fengshui/twentyfour_info] --> ${text2}: ${text}`); + + return { + key: gen_code_12(), + text, + text2, + }; + }); + + setBoxes(arr); + } + }, [ready]); + + useEffect(() => { + if (ready) { + setBoxes(prev => prev.map((p, i) => ({ ...p, ...update(i) }))); + } + }, [ready, chart_w, alpha, update]); + + return ( +
+ {boxes.map((box, i) => ( +
+
{box.text}
+
{box.text2}
+
+ ))} +
+ ); +}; diff --git a/docs/examples/utils.js b/docs/examples/utils.js new file mode 100644 index 0000000..4d85f17 --- /dev/null +++ b/docs/examples/utils.js @@ -0,0 +1,139 @@ +import { compose } from 'ramda'; +import { PIE_UNIT_HALF } from '@/constants'; + +export const int = Math.trunc; + +export const noop = () => {}; + +export const fixed = + (decimals = 3) => + n => { + const place = Math.pow(10, decimals); + return int(n * place) / place; + }; + +// export const to_fixed = (n, decimals = 3) => fixed(decimals)(n); + +export const capitalize = s => s[0].toUpperCase() + s.slice(1); + +export const gen_code_4 = () => + Math.floor((1 + Math.random()) * 0x10000) + .toString(16) + .substring(1); + +export const gen_code_12 = () => + `${gen_code_4()}${gen_code_4()}${gen_code_4()}`; + +export const rad_to_deg = rad => rad * (180 / Math.PI); +export const deg_to_rad = deg => deg * (Math.PI / 180); + +export const normalize_degree = deg => ((deg % 360) + 360) % 360; +export const normalize_angle = normalize_degree; +export const normalize_radian = compose( + deg_to_rad, + normalize_degree, + rad_to_deg +); + +export const get_position = (rad, radius = 1, center = { x: 0, y: 0 }) => ({ + deg: normalize_degree(rad_to_deg(rad)), + x: center.x + Math.cos(rad) * radius, + y: center.y + Math.sin(rad) * radius, +}); + +// Compared to `get_position`, this function uses +// `Math.sin()` for `x`, and `Math.cos()` for `y`. +export const get_position_clock = ( + rad, + radius = 1, + center = { x: 0, y: 0 } +) => ({ + deg: normalize_degree(rad_to_deg(rad)), + x: center.x + Math.sin(rad) * radius, + y: center.y - Math.cos(rad) * radius, +}); + +export const euler_from_quaternion = (q = []) => { + /* + * alpha + * - Yew + * - Rotation around Z-axis (a ray coming out of your phone) + * - Screen-face rotation (like a car handle when driving) + */ + const alpha = normalize_degree( + rad_to_deg( + Math.atan2( + 2 * q[0] * q[1] + 2 * q[2] * q[3], + 1 - 2 * q[1] * q[1] - 2 * q[2] * q[2] + ) + ) + ); + + /* + * gamma + * - Roll + * - Rotation around Y-axis (phone's vertical axis) + * - Horizontal tilt (left-right tilt) + */ + const gamma = normalize_degree( + rad_to_deg( + Math.atan2( + 2 * (q[3] * q[0] + q[1] * q[2]), + 1 - 2 * (q[0] * q[0] + q[1] * q[1]) + ) + ) + ); + + return [alpha, gamma]; +}; + +export const get_utc_offset_in_hours = dt => + int(Math.floor(dt.utcOffset() / 60)); + +export const str_to_hex = str => parseInt(str.slice(1), 16); + +export const pad = + (digits = 2) => + (n = 0) => + n.toString().padStart(digits, '0'); + +export const is_leap_year = year => { + if (year % 4 == 0) { + if (year % 100 == 0) { + return year % 400 == 0; + } else { + return true; + } + } else { + return false; + } +}; + +export const is_iOS = + navigator.userAgent.match(/(iPod|iPhone|iPad)/) && + navigator.userAgent.match(/AppleWebKit/); + +let time = Date.now(); + +export const debounce = (f, delay) => { + let timeout = null; + let args = null; + + const g = () => { + f.apply(null, args); + time = Date.now(); + }; + + return function () { + args = arguments; + + if (Date.now() >= time + delay) { + // Execute if the time has passed. + g(); + } else { + // Cancel the previous ones, and execute only the last one. + !!timeout && clearTimeout(timeout); + timeout = setTimeout(g, delay); + } + }; +}; diff --git a/docs/ganzhi.md b/docs/ganzhi.md new file mode 100644 index 0000000..9321fcd --- /dev/null +++ b/docs/ganzhi.md @@ -0,0 +1,264 @@ +# 干支 (Gan-Zhi) + +Source: [src/ganzhi.rs](../src/ganzhi.rs) + +Based on 5 elements in nature with its 陰 (Yin) and 陽 (Yang) for each, +ancient Chinese described the plant growth using 10 conventional symbols +known as "10 Gan" (十干). Also, they tracked the motion of Jupiter +(which has 12 year cycle) and so they did divided the night sky into 12 regions, +and this is known as "12 Zhi" (十二支). When they record time and space, +they used the combinations of 10 Gan (干) and 12 Zhi (支) +which makes 60 patterns, and this is called 干支 (Gan-Zhi). + +10 Gan (干): + +[0] 甲 (Jia) +[1] 乙 (Yi) +[2] 丙 (Bing) +[3] 丁 (Ding) +[4] 戊 (Wu) +[5] 己 (Ji) +[6] 庚 (Geng) +[7] 辛 (Xin) +[8] 壬 (Ren) +[9] 癸 (Gui) + +12 Zhi (支): + +[0] 子 (Zi) +[1] 丑 (Chou) +[2] 寅 (Yin) +[3] 卯 (Mao) +[4] 辰 (Chen) +[5] 巳 (Si) +[6] 午 (Wu) +[7] 未 (Wei) +[8] 申 (Shen) +[9] 酉 (You) +[10] 戌 (Xu) +[11] 亥 (Hai) + +Reference: +- [Sexagenary cycle - Wiki](https://en.wikipedia.org/wiki/Sexagenary_cycle) + + +## ganzhi::Stem + +A struct representing 干 (Gan) or "Stem" and stores its attributes. + +```rust +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Stem { + pub num: u8, + pub name: Language, +} +``` + +## ganzhi::Branch + +```rust +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Branch { + pub num: u8, + pub name: Language, +} +``` + +A struct representing 支 (Zhi) or "Branch" and stores its attributes. + +## ganzhi::StemRawData + +A temporary struct for loading JSON data when defining a static const `STEMS`. + +```rust +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct StemRawData { + pub num: u8, + pub name: LanguageData, +} +``` + +## ganzhi::BranchRawData + +A temporary struct for loading JSON data when defining a static const `BRANCHES`. + +```rust +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct BranchRawData { + pub num: u8, + pub name: LanguageData, +} +``` + +## ganzhi::GanZhi + +A struct for holding `Stem` and `Branch`, or denoted as 干支 (Gan-Zhi). + +``` +#[derive(Debug, Serialize)] +pub struct GanZhi<'a> { + pub stem: &'a Stem, + pub branch: &'a Branch, +} +``` + +## ganzhi::Bazi + +A struct representing 八字 (Bazi) and stores `GanZhi` as its attributes. +It is referred as _"The Four Pillars of Destiny"_ in English +mainly because the structure of 八字 (Bazi) necessary +for divinations in 四柱命理学 (_"The Four Pillars of Destiny"_). + +```rust +#[derive(Debug, Serialize)] +pub struct Bazi<'a> { + pub year: GanZhi<'a>, + pub month: GanZhi<'a>, + pub day: GanZhi<'a>, + pub hour: GanZhi<'a>, +} +``` + +## ganzhi::STEMS + +`Vec` + +A static vector with 10 items, each represents 干 (Gan). +Each stores associated attributes for the 干 (Gan). + +[0] 甲 (Jia) +[1] 乙 (Yi) +[2] 丙 (Bing) +[3] 丁 (Ding) +[4] 戊 (Wu) +[5] 己 (Ji) +[6] 庚 (Geng) +[7] 辛 (Xin) +[8] 壬 (Ren) +[9] 癸 (Gui) + +For attributes details stored in the vector is found in JSON file: +[json/ganzhi_stems.json](../json/ganzhi_stems.json) + +## ganzhi::BRANCHES + +`Vec` + +A static vector with 10 items, each represents 支 (Zhi). +Each stores associated attributes for the 支 (Zhi). + +[0] 子 (Zi) +[1] 丑 (Chou) +[2] 寅 (Yin) +[3] 卯 (Mao) +[4] 辰 (Chen) +[5] 巳 (Si) +[6] 午 (Wu) +[7] 未 (Wei) +[8] 申 (Shen) +[9] 酉 (You) +[10] 戌 (Xu) +[11] 亥 (Hai) + +For attributes details stored in the vector is found in JSON file: +`src/json/ganzhi_branches.json` + +## ganzhi::GANZHI_SEXAGESIMAL + +`Vec<(usize, usize)>` + +A static vector with 60 items. `Vec` where the first +`usize` being the `STEMS` index, and the second for the `BRANCHES`. +It is simply the combination of 10 stems and 12 branches +which eventually adds up to 60 patterns. + +## ganzhi::HOUR_STEM_TABLE + +`[[usize; 5]; 12]` + +This is a table used when finding "Hour Stem". +Columns represents "Day Stem" groups, and there are 5 groups. +For insntace, if you have 甲 for "Day Stem", +you are looking into the first column (group). +Rows represents "Hour Branches" for which there are 12. +For instance, if you have 子 for "Hour Branch", +you are looking into the first row. +So, when you have 甲 for "Day Stem", +and 子 for "Hour Branch", "Hour Stem" is located +in the first column in the first row, which is 甲. + +      甲乙丙丁戊 +      己庚辛壬癸 +‐‐‐‐‐‐‐‐‐‐‐‐‐ +子: 甲丙戊庚壬 +丑: 乙丁己辛癸 +寅: 丙戊庚壬甲 +卯: 丁己辛癸乙 +辰: 戊庚壬甲丙 +巳: 己辛癸乙丁 +午: 庚壬甲丙戊 +未: 辛癸乙丁己 +申: 壬甲丙戊庚 +酉: 癸乙丁己辛 +戌: 甲丙戊庚壬 +亥: 乙丁己辛癸 + +## ganzhi::Bazi::from_local + +Returns `Bazi` from localtime (`DateTime`) and zone (`i8`). + +Example: + +```rust +use mikaboshi::time::{ Month, DateTime }; +use mikaboshi::ganzhi::{ Bazi, GanZhi }; + +let zone: i8 = 9; + +let lt = DateTime { + year: 2021, + month: Month::Jul, + day: 7.0, + hour: 0, + min: 0, + sec: 0.0, +}; +let bazi: Bazi = Bazi::from_local(<, zone); + +let year: GanZhi = bazi.year; +let month: GanZhi = bazi.month; +let day: GanZhi = bazi.day; +let hour: GanZhi = bazi.hour; + +println!("年: {} ({})", year.alphabet(), year.alphabet_ja()); +println!("月: {} ({})", month.alphabet(), month.alphabet_ja()); +println!("日: {} ({})", day.alphabet(), day.alphabet_ja()); +println!("時: {} ({})", hour.alphabet(), hour.alphabet_ja()); + +// 年: 辛丑 (かのと・うし) +// 月: 甲午 (きのえ・うま) +// 日: 乙卯 (きのと・う) +// 時: 癸未 (みずのと・ひつじ) +``` + +Example using `js_sys`: + +```rust +use mikaboshi::ganzhi::Bazi; +use mikaboshi::time::{DateTime, Month}; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn get_bazi(params: &JsValue) -> JsValue { + let localtime = DateTime { + year: 1985, + month: Month::Nov, + day: 5.0, + hour: 1, + min: 35, + sec: 0.0, + }; + let zone: i8 = 9; + JsValue::from_serde(&Bazi::from_local(&localtime, zone)).unwrap() +} +``` diff --git a/docs/jiuxing.md b/docs/jiuxing.md new file mode 100644 index 0000000..8e70326 --- /dev/null +++ b/docs/jiuxing.md @@ -0,0 +1,301 @@ +# 九星 (Jiu-Xing) + +Source: [src/jiuxing.rs](../src/jiuxing.rs) + +At the beginning, the law governing the universe was simple. +Yet, as man acquired the faculty of thought, was it no longer so. +It was not the universe which changed, but was about how man began +to see the universe differently. Thought, after all, is nothing +but reflections of the outer world. In another word, the outer +world we perceive could only be understood via patterns +that are innate to man's thought. Just like "Malkuth" in _Kabbalha_ +is about both the earthly kingdom and the man himself, +as ancient Chinese attempted describing patterns in the universe, +they introduced another artificial element "metal" +(or "earth" when it is deployed in actual reality). +For the ancient Chinese, the former is called +先天八卦 ("the Primordial Heaven"), and the latter, +後天八卦 ("the Manifested Heaven"). +To study the patterns peculiar to each universe, a conventional +board with 8 directions and 1 in the center has been in use, +where "8 Gua" (八卦) are assigned for slots on the board. +However, for many 風水 (Feng-Shui) systems, we are normally +dealing with the latter, or 後天八卦 ("the Manifested Heaven"). + +For 後天八卦 ("the Manifested Heaven") has a specific name +in 玄空飞星風水 (Xuan-Kong Fei-Xing Feng-Shui), and is called +地盤 (Di-Pan). However, there are 3 more boards in +玄空飞星風水 (Xuan-Kong Fei-Xing Feng-Shui) +in addition to 地盤 (Di-Pan), namely: + +(1) 運盤 (Un-Pan) (or 天盤 (Tien-Pan)) +(2) 山星 (Shan-Xing) +(3) 向星 (Xiang-Xing) + +In practice, for all the above 3 boards, 九星 (Jiu-Xing) +or "the Nine Stars" are assigned. While "8 Gua" (八卦) +has fixed positions, 九星 (Jiu-Xing) changes +over time for spatial constraints given. +When their positions change, the movement is called +飞泊 (Fei-Po) or "flying" because of how it appears +to our eyes when they move. + +For the first board 運盤 (Un-Pan), positions of 九星 (Jiu-Xing) +are determined by building's construction year, +and calculated based on 三元九運 (Sang-Yuan Jiu-Yun) +or "9 Yearly Cycles". We could say that 運盤 (Un-Pan) +essentially describes of the temporal aspect of the building +For 山星 (Shan-Xing) and 向星 (Xiang-Xing) are determined +by spatial aspects of the building, though, temporal aspects +are also associated indirectly in calculations. + +When 運盤 (Un-Pan), 山星 (Shan-Xing), and 向星 (Xiang-Xing) +are added to 地盤 (Di-Pan) at the bottom, it is called +下卦図 (Xia-Gua-Tu), or simply referred as +飞星図 (Fei-Xing-Tu; "the Flying Star Chart"). + +Jiu-Xing (九星): + +[0] 一白水星 (1 White) +[1] 二黒土星 (2 Black) +[2] 三碧木星 (3 Jade) +[3] 四緑木星 (4 Green) +[4] 五黄土星 (5 Yellow) +[5] 六白金星 (6 White) +[6] 七赤金星 (7 Red) +[7] 八白土星 (8 White) +[8] 九紫火星 (9 Purple) + + +Reference: +- [Flying Star Feng Shui - Wiki](https://en.wikipedia.org/wiki/Flying_Star_Feng_Shui) + + +## jiuxing::JiuXing + +A struct representing 九星 (Jiu-Xing). + +```rust +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct JiuXing { + pub num: u8, + pub direction: String, + pub name: Language, + pub color: String, + pub element: WuXing, + pub planet: Planet, +} +``` + +## jiuxing::JiuXingRawData + +A temporary struct for loading JSON data when defining a static const `JIU_XING`. + +```rust +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct JiuXingRawData { + pub num: u8, + pub direction: String, + pub name: LanguageData, + pub color: String, + pub element: u8, + pub planet: u8, +} +``` + +## jiuxing::XiaGuaTuKind + +```rust +#[derive(Debug, Clone, Serialize, Deserialize, Copy)] +pub enum XiaGuaTuKind { + UnPanXing, // 運盤 + ShanXing, // 山星 + XiangXing, // 向星 +} +``` + +## jiuxing::XiaGuaTu + +A struct representing 下卦図 (Xia-Gua-Tu). + +```rust +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct XiaGuaTu<'a> { + pub kind: XiaGuaTuKind, + pub center: Option, + pub direction: Option<&'a str>, + pub sector: Option, + pub chart: Option<[usize; 9]>, +} +``` + +## jiuxing::DIRECTION_TO_JIU_XING + +`HashMap<&str, usize>` + +## jiuxing::JIU_XING + +`[JiuXing; 9]` + +A static vector with 9 items, each represents 九星 (Jiu-Xing). + +[0] 一白水星 (1 White) +[1] 二黒土星 (2 Black) +[2] 三碧木星 (3 Jade) +[3] 四緑木星 (4 Green) +[4] 五黄土星 (5 Yellow) +[5] 六白金星 (6 White) +[6] 七赤金星 (7 Red) +[7] 八白土星 (8 White) +[8] 九紫火星 (9 Purple) + +For attributes details stored in the vector is found in JSON file: +[json/jiuxing.json](../json/jiuxing.json) + +## jiuxing::JIU_XING_DI_PAN_POSITIONS + +`HashMap<&str, [usize; 9]>` + +Although 洛書 (Lo-Shu) order is fixed, when 地盤 (Di-Pan) +is drawn on a device screen, the mapping for +九星 (Jiu-Xing) changes as the device rotates. +For example, 一白水星 (1 White) usually comes to the top +of the board when a device is pointing north. However, +when pointing north east, 一白水星 (1 White) moves +to the top left (which is north west). +For 8 compass directions, this constant provides +a mapping for the 洛書 (Lo-Shu) order. +For "n", 一白水星 (1 White) is the 2nd in the array. +For "ne", 一白水星 (1 White) is the 1st in the array. + +It would look like this: + +[5] 六白 [0] 一白 [7] 八白 +[6] 七赤 [4] 五黄 [2] 三碧 +[1] 二黒 [8] 九紫 [3] 四緑 +n: [5, 0, 7, 6, 4, 2, 1, 8, 3] + +[0] 一白 [7] 八白 [2] 三碧 +[5] 六白 [4] 五黄 [3] 四緑 +[6] 七赤 [1] 二黒 [8] 九紫 +ne: [0, 7, 2, 5, 4, 3, 6, 1, 8] + +[7] 八白 [2] 三碧 [3] 四緑 +[0] 一白 [4] 五黄 [8] 九紫 +[5] 六白 [6] 七赤 [1] 二黒 +e: [7, 2, 3, 0, 4, 8, 5, 6, 1] + +[2] 三碧 [3] 四緑 [8] 九紫 +[7] 八白 [4] 五黄 [1] 二黒 +[0] 一白 [5] 六白 [6] 七赤 +se: [2, 3, 8, 7, 4, 1, 0, 5, 6] + +[3] 四緑 [8] 九紫 [1] 二黒 +[2] 三碧 [4] 五黄 [6] 七赤 +[7] 八白 [0] 一白 [5] 六白 +s: [3, 8, 1, 2, 4, 6, 7, 0, 5] + +[8] 九紫 [1] 二黒 [6] 七赤 +[3] 四緑 [4] 五黄 [5] 六白 +[2] 三碧 [7] 八白 [0] 一白 +sw: [8, 1, 6, 3, 4, 5, 2, 7, 0] + +[1] 二黒 [6] 七赤 [5] 六白 +[8] 九紫 [4] 五黄 [0] 一白 +[3] 四緑 [2] 三碧 [7] 八白 +w: [1, 6, 5, 8, 4, 0, 3, 2, 7] + +[6] 七赤 [5] 六白 [0] 一白 +[1] 二黒 [4] 五黄 [7] 八白 +[8] 九紫 [3] 四緑 [2] 三碧 +nw: [6, 5, 0, 1, 4, 7, 8, 3, 2] + +## jiuxing::get_jiuxing_dipan_positions_from_direction + +A getter for `JIU_XING_DI_PAN_POSITIONS`. + +## jiuxing::get_jiuxing_from_index + +A getter for `JIU_XING`. + +Example: + +```rust +use mikaboshi::jiuxing::{get_jiuxing_from_index, JiuXing}; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn xx(index: usize) -> JsValue { + let dir: &JiuXing = get_jiuxing_from_index(index); + JsValue::from_serde(dir).unwrap() +} +``` + +## jiuxing::normalize_jiuxing + +Given incorrect value for Jiu-Xing index, applies a modulo +to normalize it to fit within the range of 0 to 8. + +Example: +0 --> 0 ... Stays the same. "0" being "一白水星 (1 White)". +8 --> 8 ... Stays the same. "8" being "九紫火星 (9 Purple)". +9 --> 0 ... "9" is too much for the range, and becoming "0" which is "一白水星". +10 --> 1 ... "10" is too much, and becoming "1" which is "二黒土星 (2 Black)". +-1 --> 8 ... Making it positive. "8" being "九紫火星 (9 Purple)". +-2 --> 7 ... Making it positive. "8" being "八白土星 (8 White)". + + +## jiuxing::fly_flying_stars + +This is a function for 飞泊 (Fei-Po) or "flying". +The idea is quite simple. Given the order (which is +the second argument `order` in array) of +九星 (Jiu-Xing) indexes, increments or decrements +each in the array, and simply return the array. +Depending on whichever currently resides in the center of +the board (which is the first argument `center`), +the value to increment or decrement changes. +For `order` is fundamentally that of the Lo-Shu order +(which is defined in `JIU_XING_DI_PAN_POSITIONS`), +however, the layout is always different since +the position changes depending on which direction +the device is pointing as the device rotates. + + +## jiuxing::get_xiaguatu_from_unpan_index + +Calculates for 下卦図 (Xia-Gua-Tu). 1st and 2nd +arguments (`unpan_xing_center` and `unpan_xing_order`) +are required for all. For calculating a chart +for 運盤星 (Un-Pan Xing), that is all we need. +However, to calculate charts for 山星 (Shan-Xing) +and 向星 (Xiang-Xing), requires 3rd and 4th arguments +(`xiang_xing_direction` and `xiang_xing_sector`. + +Example: +```rust +use std::collections::HashMap; +use std::convert::TryInto; +use mikaboshi::jiuxing::{get_xiaguatu_from_unpan_index, XiaGuaTu}; +use mikaboshi::test_mods::XiaGuaTuParams; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn xx(params: &JsValue) -> JsValue { + let params: XiaGuaTuParams = params.into_serde().unwrap(); + let unpan_xing_order: [usize; 9] = + params + .unpan_xing_order + .try_into() + .unwrap_or_else(|v: Vec| { + panic!("Expected a Vec of length 9 but it was {}", v.len()) + }); + let xia_gua_tu: HashMap<&str, XiaGuaTu> = get_xiaguatu_from_unpan_index( + params.unpan_xing_center, + &unpan_xing_order, + params.xiang_xing_direction.as_str(), + params.xiang_xing_sector, + ); + JsValue::from_serde(&xia_gua_tu).unwrap() +} +``` diff --git a/docs/planet.md b/docs/planet.md new file mode 100644 index 0000000..ed425bc --- /dev/null +++ b/docs/planet.md @@ -0,0 +1,68 @@ +# Planets + +Source: [src/planet.rs](../src/planet.rs) + +Information about planets in our solar system. +Notice the planets in `PLANETS` are stored in a special order +known as _the Ptolemaic Order_. In many ancient traditions, +when a man is deceased, he will depart the Earth, +and head toward the Moon. Leaving the Moon behind, +the Mercury, the Venus, and the Sun. He will continue +his journey after the Sun, this time, to _the outer planets_, +that are the Mars, the Jupiter, and the Saturn. + +After all, this library provides methodologies +_NOT_ for _"astronomy"_, but for _"astrology"_, hence, +follows the tradition which was common to the ancients. + +Also noteworthy that, according to Rudolf Steiner, +"Mercury" was formerly known as "Venus" in ancient times. +Yet, it is only so when we are talking about the order +of the _physical_ planets, not in its _symbolical_ sense. +For instance, when ancients mentioned of "Mercury", +it was simply about "Mercury" and not "Venus". + +## planet::Planet + +A struct representing a planet and stores its attributes. + +```rust +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Planet { + pub name: Language, +} +``` + +## planet::PlanetRawData + +A temporary struct for loading JSON data when defining a static const `PLANETS`. + +```rust +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct PlanetRawData { + pub name: LanguageData, +} +``` + +## planet::PLANETS + +`Vec` + +A static vector with 11 items, each represents a planet +in our solar system. Planets are in Ptolemaic order. + +[0] Earth +[1] Moon +[2] Mercury +[3] Venus +[4] Sun +[5] Mars +[6] Jupiter +[7] Saturn +[8] Uranus +[9] Neptune +[10] Pluto + +For attributes details stored in the vector is found in JSON file: +[json/planets.json](../json/planets.json) + diff --git a/docs/sample_bagua.png b/docs/sample_bagua.png new file mode 100644 index 0000000000000000000000000000000000000000..5768a4cf31ee6db56d0e7a306c0a30e98c25b25c GIT binary patch literal 37134 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

CQD=HM&?xF!qw@thwd=6iKDwQ1!R&%h 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 literal 0 HcmV?d00001 diff --git a/docs/sample_shengsi.png b/docs/sample_shengsi.png new file mode 100644 index 0000000000000000000000000000000000000000..be6434020dc906cef64b526fb20ae75374812556 GIT binary patch literal 19737 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 literal 0 HcmV?d00001 diff --git a/docs/sample_twentyfour.png b/docs/sample_twentyfour.png new file mode 100644 index 0000000000000000000000000000000000000000..9358ec5aa207ccc9f21c800b1b91c4552ddddfb4 GIT binary patch literal 66642 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 Lx~}*UZyxYp*+s7I literal 0 HcmV?d00001 diff --git a/docs/shengsi.md b/docs/shengsi.md new file mode 100644 index 0000000..4b9c130 --- /dev/null +++ b/docs/shengsi.md @@ -0,0 +1,104 @@ +# 生死衰旺 (Sheng-Si Shuai-Wang) + +Source: [src/shengsi.rs](../src/shengsi.rs) + +![sample_shengsi](./sample_shengsi.png) + +生死衰旺 (Sheng-Si Shuai-Wang) is just a combination +of 4 Chinese characters, each being: + +(1) Growing --> 生 (Sheng) +(2) Deadly --> 死 (Si) +(3) Perishing --> 衰 (Shuai) +(4) Prosperous --> 旺 (Wang) + +They are often used in 四柱命理学 (The Four Pillars of Destiny), +but used in Feng-Shui as well. It simply suggests +that there are 4 states to the energy occupying the space. +In 玄空飞星風水 (Xuan-Kong Fei-Xing Feng-Shui), +it describes the state for the target year +in 三元九運 (Sang-Yuan Jiu-Yun), +especially, for its 向星 (Xiang-Xing). + + +## shengsi::ShengSi + +A struct representing 生死衰旺 (Sheng-Si Shuai-Wang). +`key` would be: "sheng", "si", "shuai", or "wang". + +```rust +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct ShengSi<'a> { + pub key: &'a str, + pub kanji: &'a str, + pub meaning: &'a str, +} +``` + +## shengsi::ShengSiYearlyAlloc + +A struct holding allocations of 生死衰旺 (Sheng-Si Shuai-Wang) for the given year. +For `usize` (in `Vec`) is 九星 (Jiu-Xing) index. + +```rust +#[derive(Debug, Clone)] +pub struct ShengSiYearlyAlloc { + pub wang: Vec, + pub sheng: Vec, + pub shuai: Vec, + pub si: Vec, +} +``` + +## shengsi::SHENG_SI + +`HashMap<&str, ShengSi>` + +A HashMap for 生死衰旺 (Sheng-Si Shuai-Wang) by key +(for each holds `ShengSi`). + +## shengsi::SHENG_SI_ALLOC + +`Vec` + +For every year, some 九星 (Jiu-Xing) maybe in 旺 (Wang = Prospering) +phase, but some maybe in 死 (Si = Dying). 生死衰旺 (Sheng-Si Shuai-Wang) +for 九星 (Jiu-Xing) is no random, but has certain patterns, +and is repeated every 9 years. This cycle is called +三元九運 (Sang-Yuan Jiu-Yun), and given the 運盤星 (Un-Pan Xing) index +for the specific year, you can tell of 生死衰旺 (Sheng-Si Shuai-Wang) +for all the other 九星 (Jiu-Xing). Here, it is constructing +the patterns for 9 years, and making them into a static vector +for which each index being the 運盤星 (Un-Pan Xing) index. +If you know the 運盤星 (Un-Pan Xing) index for the year, +this static vector will tell you 生死衰旺 (Sheng-Si Shuai-Wang) +for all 九星 (Jiu-Xing). + +## shengsi::get_shengsi_mapping + +Given 運盤 (Un-Pan) index and given a layout for the current +運盤 (Un-Pan) positions (`&[usize; 9]`), returns the corresponding +生死衰旺 (Sheng-Si Shuai-Wang) situation. + +Example: + +```rust +use std::convert::TryInto; +use mikaboshi::shengsi::{get_shengsi_mapping, ShengSi}; +use mikaboshi::test_mods::ShengSiParams; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn xx(params: &JsValue) -> JsValue { + let params: ShengSiParams = params.into_serde().unwrap(); + let unpan_id: usize = params.unpan_id; + let chart: [usize; 9] = params + .unpan_xing_chart + .try_into() + .unwrap_or_else(|v: Vec| { + panic!("Expected a Vec of length 9 but it was {}", v.len()) + }); + let mapping: Vec> = get_shengsi_mapping(unpan_id, &chart); + JsValue::from_serde(&mapping).unwrap() +} +``` diff --git a/docs/solar_terms.md b/docs/solar_terms.md new file mode 100644 index 0000000..7709b0b --- /dev/null +++ b/docs/solar_terms.md @@ -0,0 +1,56 @@ +# 二十四节气 (Er-Shi-Si Jie-Qi) and 立春 (Li-Chun) + +Source: [src/solar_terms.rs](../src/solar_terms.rs) + +A module for 二十四节气 (Er-Shi-Si Jie-Qi). +Or, for calculating 立春 (Li-Chun). + +Reference: +- [Solar term - Wiki](https://en.wikipedia.org/wiki/Solar_term) + + +## solar_terms::SolarTerm + +```rust +#[derive(Debug)] +pub struct SolarTerm { + pub id: u8, + pub name: Language, + pub angle: u16, +} +``` + +## solar_terms::SolarTermRawData + +```rust +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SolarTermRawData { + pub id: u8, + pub name: LanguageData, + pub angle: u16, +} +``` + +## solar_terms::SOLAR_TERMS + +`Vec` + +## solar_terms::get_last_term + +## solar_terms::get_lichun + +Example: + +```rust +use mikaboshi::solar_terms::get_lichun; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn xx(year: i16) -> JsValue { + let lichun = get_lichun(year); + JsValue::from_str(&format!( + "{:04}-{:02}-{:02}", + lichun.year as u16, lichun.month as u8, lichun.day as u8 + )) +} +``` diff --git a/docs/time.md b/docs/time.md new file mode 100644 index 0000000..c7d3224 --- /dev/null +++ b/docs/time.md @@ -0,0 +1,44 @@ +# Time + +Source: [src/time.rs](../src/time.rs) + +All the time related. Currently, has only 1 function. + +## time::Date +## time::DateTime +## time::Time + +## time::ut_from_local + +You may convert your local time into _UT_: + +```rust +use mikaboshi::time::{ + Month, + DateTime, + ut_from_local, +}; + +let zone: i8 = 9; + +let local = DateTime { + year: 2021, + month: Month::Jul, + day: 7.0, + hour: 0, + min: 0, + sec: 0.0, +}; + +let ut: DateTime = ut_from_local(&local, zone); +println!("ut: {:?}", ut); + +// { +// year: 2021, +// month: Jul, +// day: 6.0, +// hour: 14, +// min: 57, +// sec: 17.13778432735566 +// } +``` diff --git a/json/bagua.json b/json/bagua.json index e18b62e..c41dffb 100644 --- a/json/bagua.json +++ b/json/bagua.json @@ -4,7 +4,7 @@ "name": { "en": "kan", "zh_cn": ["坎", "kǎn"], - "zh_cn": ["坎", "kǎn"], + "zh_tw": ["坎", "kǎn"], "ja": ["かん", "kan"], "vi": [] }, diff --git a/json/ganzhi_branches.json b/json/ganzhi_branches.json index 15ecd94..5fc5bcd 100644 --- a/json/ganzhi_branches.json +++ b/json/ganzhi_branches.json @@ -1,6 +1,6 @@ [ { - "no": 1, + "num": 1, "name": { "en": "zi", "ja": ["ね", "ne"], @@ -10,7 +10,7 @@ } }, { - "no": 2, + "num": 2, "name": { "en": "chou", "ja": ["うし", "ushi"], @@ -20,7 +20,7 @@ } }, { - "no": 3, + "num": 3, "name": { "en": "", "ja": ["とら", "tora"], @@ -30,7 +30,7 @@ } }, { - "no": 4, + "num": 4, "name": { "en": "mao", "ja": ["う", "u"], @@ -40,7 +40,7 @@ } }, { - "no": 5, + "num": 5, "name": { "en": "", "ja": ["たつ", "tatsu"], @@ -50,7 +50,7 @@ } }, { - "no": 6, + "num": 6, "name": { "en": "si", "ja": ["み", "mi"], @@ -60,7 +60,7 @@ } }, { - "no": 7, + "num": 7, "name": { "en": "wu", "ja": ["うま", "uma"], @@ -70,7 +70,7 @@ } }, { - "no": 8, + "num": 8, "name": { "en": "wei", "ja": ["ひつじ", "hitsuji"], @@ -80,7 +80,7 @@ } }, { - "no": 9, + "num": 9, "name": { "en": "shen", "ja": ["さる", "saru"], @@ -90,7 +90,7 @@ } }, { - "no": 10, + "num": 10, "name": { "en": "you", "ja": ["とり", "tori"], @@ -100,7 +100,7 @@ } }, { - "no": 11, + "num": 11, "name": { "en": "xu", "ja": ["いぬ", "inu"], @@ -110,7 +110,7 @@ } }, { - "no": 12, + "num": 12, "name": { "en": "hai", "ja": ["い", "i"], diff --git a/json/ganzhi_stems.json b/json/ganzhi_stems.json index 311c149..9f23052 100644 --- a/json/ganzhi_stems.json +++ b/json/ganzhi_stems.json @@ -1,6 +1,6 @@ [ { - "no": 1, + "num": 1, "name": { "en": "jia", "ja": ["きのえ", "kinoe"], @@ -10,7 +10,7 @@ } }, { - "no": 2, + "num": 2, "name": { "en": "yi", "ja": ["きのと", "kinoto"], @@ -20,7 +20,7 @@ } }, { - "no": 3, + "num": 3, "name": { "en": "bing", "ja": ["ひのえ", "hinoe"], @@ -30,7 +30,7 @@ } }, { - "no": 4, + "num": 4, "name": { "en": "ding", "ja": ["ひのと", "hinoto"], @@ -40,7 +40,7 @@ } }, { - "no": 5, + "num": 5, "name": { "en": "wu", "ja": ["つちのえ", "tsuchinoe"], @@ -50,7 +50,7 @@ } }, { - "no": 6, + "num": 6, "name": { "en": "ji", "ja": ["つちのと", "tsuchinoe"], @@ -60,7 +60,7 @@ } }, { - "no": 7, + "num": 7, "name": { "en": "geng", "ja": ["かのえ", "kanoe"], @@ -70,7 +70,7 @@ } }, { - "no": 8, + "num": 8, "name": { "en": "xin", "ja": ["かのと", "kanoto"], @@ -80,7 +80,7 @@ } }, { - "no": 9, + "num": 9, "name": { "en": "ren", "ja": ["みずのえ", "mizunoe"], @@ -90,7 +90,7 @@ } }, { - "no": 10, + "num": 10, "name": { "en": "gui", "ja": ["みずのと", "mizunoto"], diff --git a/json/jiuxing.json b/json/jiuxing.json index 9462947..66173f0 100644 --- a/json/jiuxing.json +++ b/json/jiuxing.json @@ -57,7 +57,7 @@ }, { "num": 5, - "direction": null, + "direction": "", "name": { "en": "5 Green", "zh_cn": ["五黄土星", "wǔ huáng tǔ xīng"], diff --git a/json/planet.json b/json/planet.json index e57d5b2..ace7964 100644 --- a/json/planet.json +++ b/json/planet.json @@ -1,79 +1,101 @@ [ { - "en": "earth", - "zh_cn": ["地球", "dì qiú"], - "zh_tw": ["地球", "dì qiú"], - "ja": ["ちきゅう", "chikyu"], - "vi": [] + "name": { + "en": "earth", + "zh_cn": ["地球", "dì qiú"], + "zh_tw": ["地球", "dì qiú"], + "ja": ["ちきゅう", "chikyu"], + "vi": [] + } }, { - "en": "moon", - "zh_cn": ["月", ""], - "zh_tw": ["月", ""], - "ja": ["つき", "tsuki"], - "vi": [] + "name": { + "en": "moon", + "zh_cn": ["月", ""], + "zh_tw": ["月", ""], + "ja": ["つき", "tsuki"], + "vi": [] + } }, { - "en": "mercury" - "zh_cn": ["水星", "shuǐ xīng"], - "zh_tw": ["水星", "shuǐ xīng"], - "ja": ["すいせい", "suisei"], - "vi": [] + "name": { + "en": "mercury", + "zh_cn": ["水星", "shuǐ xīng"], + "zh_tw": ["水星", "shuǐ xīng"], + "ja": ["すいせい", "suisei"], + "vi": [] + } }, { - "en": "venus", - "zh_cn": ["金星", "jīn xīng"], - "zh_tw": ["金星", "jīn xīng"], - "ja": ["きんせい", "kinsei"], - "vi": [] + "name": { + "en": "venus", + "zh_cn": ["金星", "jīn xīng"], + "zh_tw": ["金星", "jīn xīng"], + "ja": ["きんせい", "kinsei"], + "vi": [] + } }, { - "en": "sun", - "zh_cn": ["太陽", ""], - "zh_tw": ["太陽", ""], - "ja": ["たいよう", "taiyo"], - "vi": [] + "name": { + "en": "sun", + "zh_cn": ["太陽", ""], + "zh_tw": ["太陽", ""], + "ja": ["たいよう", "taiyo"], + "vi": [] + } }, { - "en": "mars", - "zh_cn": ["火星", "huǒ xīng"], - "zh_tw": ["火星", "huǒ xīng"], - "ja": ["かせい", "kasei"], - "vi": [] + "name": { + "en": "mars", + "zh_cn": ["火星", "huǒ xīng"], + "zh_tw": ["火星", "huǒ xīng"], + "ja": ["かせい", "kasei"], + "vi": [] + } }, { - "en": "jupiter", - "zh_cn": ["木星", "mù xīng"], - "zh_tw": ["木星", "mù xīng"], - "ja": ["もくせい", "mokusei"], - "vi": [] + "name": { + "en": "jupiter", + "zh_cn": ["木星", "mù xīng"], + "zh_tw": ["木星", "mù xīng"], + "ja": ["もくせい", "mokusei"], + "vi": [] + } }, { - "en": "saturn", - "zh_cn": ["土星", "tǔ xīng"], - "zh_tw": ["土星", "tǔ xīng"], - "ja": ["どせい", "dosei"], - "vi": [] + "name": { + "en": "saturn", + "zh_cn": ["土星", "tǔ xīng"], + "zh_tw": ["土星", "tǔ xīng"], + "ja": ["どせい", "dosei"], + "vi": [] + } }, { - "en": "uranus", - "zh_cn": ["天王星", "tiānwáng xīng"], - "zh_tw": ["天王星", "tiānwáng xīng"], - "ja": ["てんのうせい", ""], - "vi": [] + "name": { + "en": "uranus", + "zh_cn": ["天王星", "tiānwáng xīng"], + "zh_tw": ["天王星", "tiānwáng xīng"], + "ja": ["てんのうせい", ""], + "vi": [] + } }, { - "en": "neptune", - "zh_cn": ["海王星", "hǎiwáng xīng"], - "zh_tw": ["海王星", "hǎiwáng xīng"], - "ja": ["かいおうせい", "kaiosei"], - "vi": [] + "name": { + "en": "neptune", + "zh_cn": ["海王星", "hǎiwáng xīng"], + "zh_tw": ["海王星", "hǎiwáng xīng"], + "ja": ["かいおうせい", "kaiosei"], + "vi": [] + } }, { - "en": "pluto", - "zh_cn": ["冥王星", "míngwáng xīng"], - "zh_tw": ["冥王星", "míngwáng xīng"], - "ja": ["めいおうせい", "meiosei"], - "vi": [] + "name": { + "en": "pluto", + "zh_cn": ["冥王星", "míngwáng xīng"], + "zh_tw": ["冥王星", "míngwáng xīng"], + "ja": ["めいおうせい", "meiosei"], + "vi": [] + } } ] diff --git a/json/wuxing.json b/json/wuxing.json index c29f618..ec98616 100644 --- a/json/wuxing.json +++ b/json/wuxing.json @@ -1,37 +1,47 @@ [ { - "en": "wood", - "zh_cn": ["木", "mù"], - "zh_tw": ["木", "mù"], - "ja": ["もく", "moku", "ki"], - "vi": [] + "name": { + "en": "wood", + "zh_cn": ["木", "mù"], + "zh_tw": ["木", "mù"], + "ja": ["もく", "moku", "ki"], + "vi": [] + } }, { - "en": "fire", - "zh_cn": ["火", "huǒ"], - "zh_tw": ["火", "huǒ"], - "ja": ["か", "ka", "hi"], - "vi": [] + "name": { + "en": "fire", + "zh_cn": ["火", "huǒ"], + "zh_tw": ["火", "huǒ"], + "ja": ["か", "ka", "hi"], + "vi": [] + } }, { - "en": "earth", - "zh_cn": ["土", "tǔ"], - "zh_tw": ["土", "tǔ"], - "ja": ["ど", "do"], - "vi": [] + "name": { + "en": "earth", + "zh_cn": ["土", "tǔ"], + "zh_tw": ["土", "tǔ"], + "ja": ["ど", "do"], + "vi": [] + } }, { - "en": "metal", - "zh_cn": ["金", "jīn"], - "zh_tw": ["金", "jīn"], - "ja": ["ごん", "gon"], - "vi": [] + "name": { + "en": "metal", + "zh_cn": ["金", "jīn"], + "zh_tw": ["金", "jīn"], + "ja": ["ごん", "gon"], + "vi": [] + } }, { - "en": "water", - "zh_cn": ["水", "shuǐ"], - "zh_tw": ["水", "shuǐ"], - "ja": ["すい", "sui"], - "vi": [] + "name": { + "en": "water", + "zh_cn": ["水", "shuǐ"], + "zh_tw": ["水", "shuǐ"], + "ja": ["すい", "sui"], + "vi": [] + } } ] diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..44e6af1aecbdae90992a3565111fe2606ed51fc7 GIT binary patch literal 72401 zcmV(tKq00E5%1^@s63y$WM002U^dQ@0+Qek%> zaB^>EX>4U6ba`-PAZ2)IW&i+q+NHf~mgYE)ZTVlLs3C}NaySx6t#xP6!|%Om7Ll1z zk##G(!^7Ro&A*340te@S0KRMgKmX^u{_DT~E0h@el}qb&)Ozz@9(lxvZ~Fc7-*f&9 zcRqif|9b!ZF8u4yufBf2jeJdfO}|g5KVQQiKmUEgA78`6cjcd7X#W1g`>+2n^3T`U z|MEh=Z2TEh4S~ia+dy|-Z}R_&E#Kx9$A*3 zEBedo`}_M=|IR&g7f-G%b^X1mKW^oG$Kzh!!nf`hmsan_@4`#8^K0;{W7U&gTlc(Q ze$6mKWV^nQ!wOIM!aiSTm|S9x`-+WkVw`N3KkTW+5$D;r?62^}mPT5sv!j!3Py96g zc`f0*?YQT4-mUY_EAY@5c(I^e{HMRJ|MUspv4arq-^J&zTvv=PHkaYf`6mx!N5c2J zsO2p1AHV+kpZl8F!Qv|GB7=o}e_rA(;U7ql&PFF5Sor$mE}^a87hs8a>%zr^#161) zA(c?W-C}GZu#lY%dbsqMa(vl=P)b}}Bo>n@d()$D%~M)94~-@AspL{hEv@u2%2QL#wbWW$6%?PATE1FowYApUXirZ)_tI-`z4y_d z5k~?v%c!G`KE`++-t*y=AD;d2faiJRo8J7E>#c8l`#aueVm>p^GV5%!&oQ4BS6bl5 zs;jNO#(H+xn9|O>?7G|Td+g`K)V_3m`72-j+SkAFJ%8?6_;uUA{`wDgE&T3UJUitB z+n>9}Ph0!rC4z8L+%q;TUOBMi%`L#7qkDGukaKkB+_QT`yrM)dvbbj}xMS>K-XWGR z{IPde{Mk`=?*G@mT`m91zQzBqJ9oKt|KZO4_kH`jU0dSaal~IQbW!hw_kFEDk^f&J z${o-5_dmW~fBnIEB#T(u%=x?5*Hf*zr_$dEw(Xev<^9}s?d#o79ZzX@ zdbs;{#;;^9E3-Y3#a*%Gn}6@Ktu-PK4q>FvJ-pjDR&D!vzmU?k+1)z6Q~;Lsq{T~N zS932s`hLddp2&D=P!_u zg-GRHZ^uMCf5oQmz>>DX#;J!t0 zv9uDO$*(Z-7q17a3Ss41`&aW!qkqp^`}6TiGrix7ul4@acVlZsrHn|iRl zh=IQEMffrL%|SfeqbzJ}@$3kXi(js50gu>Q-s~0k)#lFMTy1Yw|o}b2)p*w`}}_DE4D}8TP}9U*-P!=0E&ecKh&^ zv)f^Q_jA=Jg*tXEiN$QYKG@K>!|Z?w*YL89I7ny9Qy%Z?5mS;_vKXlo7oJ^V3EW!8 z`LJBpF6MxXyJFaQT63_I3CDWhUenlNln5$tN$em&ADpEbJYeO{1RmC&wE_w! zc1;{unATH27MTEsv=k-tU`3dcn9kSlkB_287`W&l)&*))xphJMls|EPiYdVWfe8hD6^AZv|#2(9R zg*^;<{|fajW#D5kuA>#seK%quk6{ydSn3-m|0!;Gcq$T8lswF&(#Bk@c(iDU`1g;MjB^jxbeYY5Cpz`v?W)DRE_55CW@rD(MsK8#y0Ag-Lx3!+h;$<)j z;lSo`#TYJo0oTQZU=MHd8USWMb0KP;S=vZk#Hwn&iMO#p{Z51zTm}b+Zaf1VTdRWg zt$novwk&pUlATeZI^kkla985mjcw&NbxiPYEmRUn0xW1C&-b+1Y9TaEp7!XUH@7=p zdD)O2e*y(+42WPEc(G?-#YE3K$M_%#9oUHv@7`tso1fXZ6I^V-@mS`TQ{B5EApmH$ zalZksHmjJEA7cfJ4ggNJ1_oC#x4L-!Z}d{$7~pUn`$9C$ySUd^XCs6TyfP4+Ap+m# zZLof&IJl(5k>jW&y-MNMb1cGqhm$#5}hq5ZzbU z8}fpk&t$~x?C6Qn_o{lsD!2jh?RsD_cR3;JfA|Xbgk?n{DPOg(T;k-vW^Mrc8n9X) z5jxb01>_M>AIPf70RRBj#AVGQ?csV3^?>in!CHUM_=~8LTlMIJSVfr1^&_MjSYVVYO`^pM(E@6KUj1b;13Zr!n-FS z28bYT&PEi}Xs{`w2$u}`0Do5{ykIWy45AHM;LV8aIqs65exLXzxP34rwjY>Um^xu( z5aqrL7vxS?d+S`{7WWTDpEoZ(y)^jjP24&F({Jo%PnPR`K3HIW^Zxd_Gm8g8Vt!l+ zGMy0k26+~w0pHxxZGZ(pfcInGIAul9V0Rr3!alQO6$)!w=er$ zHI9~ub_uk=hPZ)(#3PEpa4;3qB5XRm`vWi5F$fH40@7UGMOYV!5p(SN0f+_O^5xU{ zxqw)!Adp}%x<3BA${4HnLpAYvA`MjcDjPNr>4A~9f|r6i1fGhoa}yOoiEvtMxtR^b zIN=-ujx=g0rzb9)31UBhT2=&29AvHl+UlSKG~AsHo(YfSOvtDpo77&Zy?luL#K z7O;nJnmqHK@^m(gHUD6_(Bu{h3p9a|{0xBjfiS_`QB-2%<~v^WdZU;UR)+*778kkz zc?UZ%z*Yrw@M3rO4b=h0Z1fK-EWi{C4g)nq@%Q&C#BAd4;`Ik^&PC?Xo3PIY0+_$a}dcMrWItRXa;keC8)V2BQgU>M*BI&?&2CEV_(11>B8 ztdFHb1NQ6Q1ScphxO$%e3nAmRQQ*c^LeIc6Q4LRpuLDDvHlDHIAS(tHCF@qdRZ-bQ zTw=n0#eCxE8;k-Inbg=JtV9|%PJR~O*8Y-`7H68^C%lIk5+g3cvJ+M?7?jPZI4~@h zi|ca5xBm!qB>j?I5F#>0+dsMV^8t*2Cl}Ac1GQg8#6vZK&Ih;}xMvK0B|wGe$LCO` zpcvqXkFwq@>q(RRQ;@#?IXZ);Kv+fb#5NSJ2Et`m>u4qi~8N57@QR?)JxZ0I}w^?#Xz>_01$mh4KEkizjO`2Wk#SL zf&m{drXO4;V(ur=1?o}bJe7b>xP$T|dsvfNZrpuBhHe(GVUV!$PaQJ>?i;OWVjS*? z;dw1Ro2HWAfGB}b3t~-zAPo6!=oTV3M#vssTpWPIH54K&m=EGA``6r1MMTH)8eR$G zJI$r_NK_%bVsPof%9cr)C}B_R-$#%~5Wo=(HW1A39^3qwmj_V6>K||lCI;FdP$riT z?N0EU4JW)qtrr}dCvklpYeng<(q7`>Td>+xZsat23D0}p4(d%JEKZ4uOrr5OL75!~ z)UjMO0X|Pu3max)HZMbfh-sUX#JdMD$KG=#hc^O~MB+%yfeaC%@esnqcYQsphL6n4 z#I5(2F7Qyy)*nM1y3)KW!P|F|=Jf;z_p9JQh^H~D7@sNk7lq)U= zrcGExZ0SSjz*~CwU_Yz?YV;i|@5_AR7)lJ-X)J{u`NS-vQ+x_n#htQ=+zR>%d6^do z{Vn{OSoNXUBFh~21?F+>m{b$s8%rZ;*_|t`tmTc^Vg<{sT4+CdVorKHq6==(*Vv_m5o-_-zn<)<1Lf<^&xxlxTxNdk+ z;Q^ zNEbKuymf2!i~EDqaBUa#h^68APyIf*9DE0h#ngaH$+9Z9VZDfAILdnzYm-nD1&}rb zFjztz1W1A)p*JUAzNco+5VR!jmK1A;r{8$sYckuM7aIW(LnZ~@a|QLh*(C?rrjpK^ zV$*C6T*{r&)+v*}`T@NKf3UC`?z~FJdB=uWngL$yJ6}neFE&5Om2oNHVehH!==|E?~3dRnx z;UZrQ;TS+ZR|?POdVnCV1!CD{aiG<~VuBGm6x#FZczEwOhOu*~z5@g^ev9}Dr%hpB z2^T_k8>YaqzEDMW!Ccn(O9%q}a|HTK+~JdrtX zBO;1V)T8KL$OTf*mhvLYqRJ!hi zv;mtYradscSqNt)l_P{^L4?AD!(dvN21bWR1eqbAfhFSoL{uy!x^F;b+}o6)WC2Y2 zaNYgln_Xl=B|~7*tN~^L*5fLxp$s78>B_7iZ^_ES`|Ewg%nOWy51%d!K)t9Pu3!BK zuK<8T=)}Ts6I1#7w+P)IPzzNwmsnAiND1i6VO8kqjr@EhpGYrX1&DLEDo`0b)2I{n z9f-t}$ay^;dLPyVQ2l<5VBbgl$G{qK84ak)0%f07v89@^le}-#J)tNqPfq6bnlFSF zA&Eb91+NhE6O#ui#68HyjZK#|O7qzKhVK?$^aB^!Ho_W=g}}AvwUF}l2YbNY0wL&u zAOkIhT?~;VvPJA{MDGK6@bda?ae%)e7vqtFzR(3Pq=OH;Pq%g5Zx2zP4%*M zw`o9J6ty!d$n~L_LW1KG81a^?Oyywi0Z&B6Bp`kk`TtGS!gvn2gS;DkrXIkI@p7Uf zk);(i3yZGGMrdqPJwQXl*m%Wa_8Cl?DmIJ&5{_lDM6IaxpPN1I*rVCbLnR35-?$(y z(8N!L^59=z2UCsxU$}8n)4?!7GsnEKIYf+&8%8gCj5LXI8J*6;U8cbBRRa4&$i64O zYrdvW1A2K0k>Djh{;_Q52+*S`7$s;)98W}NxWa|#F)Q*#{hxR7w8YHOH%<-(_o?w# z`E*t#yT=j6mAG&M^v`)|L%EhK41*^efw1ww#9%jQ$|Z#p2Lt{9NhIRw@q2iB8S&93 z=K}%mxy)C^c*%H)K`2kCb;b8lZHNbAAqF+&_SMv+1ZJZd>U!=$uzD)tiZ3aR9EslJ zIzbGXNpLCfo{X_3!!bs}YO*bl4F4D`jJ5*d@*EgE%44A;v{)-qu25f3$f_sCNN7Bz z10e8*hWSeVcvl>FnhLl@j?c{BASSV2U;u%>EhgUajBu3a=*VTh5o@bbscvC_v@UU_lQj@1JW=@;ACF~l* zn^A!QxdY@1O!c~Rs-N8A&O$UH;6-sopr99HB!)F^>9M*Eui}AzH>(2UEYz$H^ESID$SyRatmz9Q@g>Y+$nGc zX5f&~cvAJJ4KGj>@*>ceh3dvHWXDfs?M~_+E=Pb=FA<<&$B_096e%Sg1v=fh7!Mh| z%{RgQ55$0?D78@x?1bkxuuxwi99ge|h&bfLBctB2k_mS>>w*yye9*f5d_Tp5L*gw2 zw7ggXjLSQkbzed#R1elZP3C#YxV8Z)RL}%CA=G1wF2!ISxIr9xn@j`@ZbXJ>lq+7f z7R(h+4e!VNB2lJTz?=5EBllK<#k)lLs(5{*Dd*r)>F(hgfFCQFbz%v0_ zE;vJE?geAHt0_%ZkvK9Qtjc6R-v0oEvY~7kuN{&r=WK+=DMdz1RH7ql8AOnRPJ}IJ zcSm!Yi>QoSK*28sI6@_`(>(kES?bG15$5B|60txvws{kRBD^aTRU1tA1o2>g?N$E5 z1R$f>HVFUiub32=J#`|%ur4F3+t{&$@3nf)(z!mc?qu0oC0qf+8L?60)yJ(a*z+87 zmk7T?LR9eoHY0s6Pg^iS!tD2Sf+%93CxT%b$5=fWhkID=@xkPjImrG2UH}YGT9o3h zY&I<9$qlUzRY(3Hqjt$`gS8K>vpzTcg8TU{UbB4O)7OTkh^c@9NX&^68q&%pb9*i7 zd3)^W*nu44s!G`e;s{aVox)WH`^{!Igsz8=phC{)gk~TzfPK?WsA#Cq`=!Wzv&Qvs zos7e>z(G5!7x86z80YHUr~V|M=^Er89*sb(?QnLq8SLPb4g%}XdJoHfQ3hpVfsoO{ z1;07h&Z>DMA0~~GdIxTRu+E71Wc~>q4y)M6Oh^zOzmG_KSb0PLStG;q)W|%|s|jx0 z%rfq2VGg_WTCmhhVkdz>L4$=RikfaTl@crng+xFT9$a{n?NKsfKZ74H5dys%nPQ+onrJvvGzn9WuaE?>f1HEjwIeJGo}7Oo6c z#A&hHz8lf{w#=m?&>^n~R#36Y({W4-W^WiseNoJixm6c8djn%3B>2&r#|3ZS0E#DU z8XO2XLpJAvtFYCWMKI9|>v~Wk11v!&hj5e@AwThwD1w?V?rRaM?w(KCaJTNs3_0)# z*-wQy+lVLsS4MFCJtdG4K#a`|VGQwAr$vhhJfg1I1Lhlwqwfp?Ifj2BSGh=3E9=;} zfMy8mziH0?oU_31uaR-WCfm;e`U%2>;Oi#_SFLMA76Yfv5qn;VYdQ;!V}j2zBfO&r znByrVAWjqF^#KTXY8Ot9`2_R({PNsTW{SexDJ!BO>XBGM7zgx_lHtx34S{EJBQRV~ zyA`b01aMK1WqH~J&wz@_U=gRpgF5Sc-P0jQnSJusQR2M81`YY44I?5dR@sX7zR}j~9lEyjGClVjhD& z$e)@muPK(>eWO-*S7&2E07!H7?A_vDEPFH$c0eG-J0`Rm&zo>^i;meL0)YjTP;0Kl zm667H{Uyuc2*BztbEcIGivfbL?~7<_9W-u{ zJyAb0rHXZN9AW{GoU(`oZRjte7G$@GuLI1MMq$t|(Dh!$5{?sla|=ce!rm9KV1y8G zn6r{YA_vajVD{qTy2nvi>ix8CwSqM(7c%g8(yll^^zYE#YP13rh&>Nrhoo=oeOP%o zApwr);^Cc@AS0jR`;5~Dg)|!%t?K$}_b>}RQ>!!iuwR9SItETncd&dln(V@aSDld7@m_B_rD_&aAz#^|9eL8P6rS(` z)ZUVucXdM}XdtE3C2%c}v~jsX>$|4s$a!w7HY>`p#SY1WW};+-z?gk;_fqbijrxNn zudJQvPyRRknC8{bVZ68AC4CdM6B{9)0BCfy?CPD!@((y#=g7+&>21{>D!+I?)F)8e zO|C$fz^;C{F3zyc!UAjfl-C_TBrov-$2M2tK~}xlYxGtj&Oy;$4>QpmaP>!IVUYlc zFo=x+gxR6by0bDpO@JID{NX>*gGxjh0kcA(2C*2+y;^M6PB-QM9kDw63qejKf?%w*YECw?>Zr<|(ir|>fb5f;}_uFIDfO}!))AHzv0T4+Z2>?r1 zBC_DMo`Sb0aHf+^%aDjL!g5Op9$}l?_P7wWmWU6sv6yex3B+e*%>u#{5^=wD^L8lI z*E25&I}QQ164$pWtPkHyza%rVVo*&a1spBldH8OU=jLcq6LE;f%{?jI`(+`)X7jNX z?6soy|82-DCjAra3q^cH$G)vn#H(N!m&YH_y(;fEf5y5-f(I+bg>(}rFQn7Rnyl)< zfe@e(BLIhz8Rv|NV$eV>2otlXXWhE07qqW!rDSIO-@HHS*1B;-EYbpgBDh~kD{Oxp zb??3NAC*AJp>XoEEJc90V2P~Hd^{L~!7rTkwlEaOg}hya!Nzk<+=JZdJ~f9e;%CDI z@}u^Eh*+@FGgOtw$)C_+6BNQf;4HC#*$eCU6q9TDB3oK8)yKbqKJ(;{fsa$h!`l(c zE3tO55?ir2tb+4k2;FamH2Ny3X)KkoI_`ZuGH-}qEKq0)aBZU?%aNYCrxB2~_XO6H zA1+{Bug51F(1uvPw*Uvz)Mzc=um%W_wG41Dk%MKQ6DC$aKY&;bBXI|;l+V0mmQg0Q{T;oH?_4f{rY zqL86u(En}{3O-gFz=k1L@Yf=N;YoJ3nzr3#;6R}7_6)r}I>yTyeZd+%!u?PE%WJ)O z!ERtUz+?F8*SXAxuzdp?ctr%@xV#6NP0+0-@!$;X+IpM9ewibP8`}P07M`plOYjEE zi;!zAScjDD5j<7#H@j=m6q?+YjB%wc3(n0NO>7!oRUe3leMKAG;Eo7Q<_c}>D(oYw zox8Q7v=P^%vb12|CdTy#_Yk-m1N(*~{q#?nbU;X0%L;eEKp+v{!~G@k>En&qPuM5= z`MDPS;{9Mr{E&BfJm$d!U;zZ@_tAyT{+ii3^=}?3JVJnx2j2Q&-@tw(WS_FE(qOpdd3q6MB+EilgG zwT~wghS?-2%@;iw2IR2H0KvE0x^{Y_Ijm$G1%cEQ7VdTGu79#CF9xe(G&k>=17vlQLRg6o7+2rC-pWqGa2lfK~F z0mBqFsxM|baATn`SO9)(~(>IZM4|&Ryt!ON&!;D*6GJ1RBhElWM?5mfhPsTpJg?ZfS6AO4b9Ekk_@A)ySB?xLjJ*?&hVn?43IV&Pm5&ZiQh09d({Y8 zSO9{V@1r!$5Qm2>3!L-CQWtXqY)0lcYgI-i=Ew=gz*tS1+pyy6&b3a_$GYvS!^K#w zr?ZeH68kL{3JrArNRR7O6~28Y@}h1tJAR8*R~wo7m={Rp z%JG(3c=|2U`BzzQJ9mcp=(*D*K63pwV{_<&-KQyEgmoT*947Y94yZ1V@T-Sb)5;`b zXTGDygr^8)n9D*QewNW%N;jJUcE*cvVyVi_?m(ovEqUyg#O5&z94sr>AduPHku?`^AR2^9COSkD3QqD1vMs zYVtraUis{v3>K*gZxB?heiHxDyUUXS%lCOKLNDf8PM=*)Rfy%^}>wut50a&&Fe8g^$`CxCsZjQ=iZ^c<2n9%_Ik{wK?(BMsP+r1I$+v70Z>+Y&d0*w zUK;>#Nu0@Gm3{rOCKT>Itu%J{#`T-3zWz74>OWG|!yyFQZojaGc}|-cxUv~zxgc>f zZkEK3!iNo7IK-EHWvm3LM<)z3O=7#Z{!>rBJ?GZVS68MbYi zyMC=Z5WaTnwxI{^l>K9i?eWm>_HW_YjUWi^@^HcvsBQ#^rUr`8|D00eeGbKT>b8a0 zSp#56iQa!!vp-_?`WH28*!VNDrT-S$*f<_DaHpnH^I*)7bi|AY47Yv6+gR8ud zB6d{^Waotby~pec=xj03+|yQo!GuSAf~G z8O4^L?HTNCHsz#0%X(z~Qe_t261Ug%Z?n)^EG?iq|;nh6iHuI69DcF#6j{)4F-%Pn#cVwad zgb3Yuq45Us$8Kk{B^V^{^>IxIbGXm)BoVQN^}w%h(=x0fqLyC-dBP4m247O_uG5Ea z8qm|<3!He&&D_pxXdlaLHJ4pMRl0c#msUwY>TJ+23Add=;Qx-<*y3-p>x%e-Mc`}Y zi5^2-%$vXu7Fq=1^agI>n`%I>eZyIv(lqE~03x)$iq>=ytzet!J%;)d!JJ|tH?um6 zn0@g3NVE0Zy32NyXnhtode?5=aa;&ASS(><@=dcJx3YSVDyue21cKdkynV6|l#u5+ zl{Liev#j98rLd5@U3wN@KhVVlrV$%k1b0V!5x#`nb0T{}PO$Jg_VqQWSUOqd_mf&6 z?k{7d1@RT>|4d-nkV_25s1a?%3|P~g(~=;2t?f10W+W^~=sncON)*WVHTPMDe_jOj z5#CNbI@iJWM`RDt_YSZoEBUiMQ{TkV<;1TIlh@x8JmV){IzU_^N@L0Fv9|WqvOWml1^qDV zk6@BhqeGJ1##1@RT);kY(|Bm}apf9n|G->oFNANl}HK{6kEmPY}Z z_Uh(lpu@N$(&jeb_>Y_T%RM-t%511u)5HJ=fndXNQW@K0$d9t^>)Mk4|o zYxQ1Mq{Apo16D`Dt*2Vzfk1(7nlMCSJG;V%sgZGI42ob4O%I;dpeBh7wr`Rq* zFb9J6hTw~A}um@Hk1p4aZ$Sv2-W!NEWP9WKl2>7$=p3|X@SY>#LO=c0al6$-!z}reH70v~z z{_nE_*Z-Ur_>%*ydMZY-Cx@Uk1W$RCOJ{1t1I7xqV4f$lDE^kVQ`9;viJ+dNXUixv z%U=Y`+ALA&o@^X$`OlTx*PmJ(F!|A_*``R_Lz*4k?@zO>S40Gy`8APVp?4?|!r2q7 zxkVsd1D=bnn6EOs^EjTgusJ)|I^S5WV$&LXj>{qf6%~$taYT;OK2YfZEqX4fg!R+lv>^>k#RO{VEFo1F=2pd%rRl?JEa z?E394+j%l@TxZOghA|Ow5$C5I14?^-u#5;k-m4X>?i9kiO?K2UV>$Mv}Z9ivR-dm~_?vF*#q8dPr zvWzgQ9&GQ1BhJ9iHS4Vb^ux9bi~`g;!`2bcsrMin@pGNFDg324mUY!tEF^7+ zliO3x>of*fycrz)(5!HGYVA!Va|4m1HpyZJ)hcfA><3dq{bLrI`Q_Qxg@v($1gB+7 zKozj1!}jSWhfqBCPfqzrdhZO?ub0@DsdBNJzW~Ozd9c^`IBwJ<(d3M&OFRUZ;R@@! zF=BX4kBXk=DeP&{jtzj@nVss+AiM5<$m}hnQ`bv%o90IK~%77Z#g~85O)fhz%odfeWW(F z-NaK?Y+~h)MaDg*a$6R*VSV#HXNRHK4P!%Nij~X4w;CMM{ws({vbUfrmA0+z#=}$g z?sN>^%3+Z;J@=W&yU$$U8s8PZ-*&9)zxQK(2=XtRF7O1@zNEALuT7c6yZTgYjL6IW zkE}Zq=kk5Q=TpD4mXc9NAZJmOT^SdE)yf4k}xJHS1@V5v0MtViC`3%Ky?7bt{W zHyzRK1MX+$oyd0L1(55}zp0kshzct=z#aT2^Ck!+tmyH)a9{a;Uc2|O(Ep*#%h>`y zb=8iY_^GURIZkc0mDSvu)nEj}Qxsrl$Fg8Mvi7#VI$+09{hGjrfD80N;w_T*(ZSSIk+KkGy}=!902%Hxh%aU zMBYQ9H1jD|z0cG*_S)zyqv0BZ<07iP&<^Bgq`?gRL#^NZ_T7H<#-!)uaza3W-AR$1qttR1ZV8YXo%Wpf$>)Jl# z78kdjH01EK&!a4Rkzr?+1zwO0`7F-aI_B4kRUc60`$POMC>%haEXyZyJ6|e#T52_L zu{GPl;z*a<>cdBiij`1ecFs|5OO@+jiQ=?a^_~NbP+X2RIsGV(3lR}u2gxZorM7FL zOJQ==ZY8d4mYkaNw=x7ddOQWkgr}ZF83EJN=bDHP4uVwC5)7Pg6|QCC84x?g@K(~U zWp^(41|hMLxeY=jJ9^L6EO7@TKL_vNU~HGifbSfmUrzI}aKE0JL1y&tbPDMS6BZLA zk{6_VJ8X=_Z}rT&s|w=fXaFLMlXNmsq{dmA_RK9 z2wWFegFePGeg?-_3H#?X-Iu5IvGB$II%$fi=Zv%do*`f0OdcoY;=oMEXoXl>hrDcn zB)}vOfIT6#xflrzrF#J*i$(~a&j1)Pnc$?zea3?E4{swJMZ0_8yX?{PQ-B${l>iNx z4g=lgO{&Eng99ZUuuR-wgKvS*$sx`R375>1kOLowK<4*}lSuHWr18z$u?yB2ewzLM zP80oi%H2(0I)9P}DP?imX-UIZ#u+QsKOF5j+}YYZGd=e0O?(-bb687;AX*!aS~s!L z>TRwuzNZlmI#4Wiban;03YcD4)dX1~&)_gb9nKm67}xf()zpr+WR<-gz{TljU$aOA zzHat{EnAN8oU$9ohG`3STPWl#uoV)YF&*A;hLlBX@FIaJIrKhG8%pwPwKebLNa6}} zeYgwLFWVA={4V?Lbzpn-dGY!=6@z(MBYymF#(@*=j(`RvRs~9}xYS?4WY9xTc`VpfQ=#uR0y&d_<$j4?T-#l zvwI|brr7FZixvSW69*i1f|Fn#L>f?p`!;_-e1)x~JZ)vp7Wj{Gb?1L>U>kCZAz2Og zb7_mTaKjjB- za{GQc$r*xj{h-hhd#3SY`hN91!hNQHx*=9ujR{Q;>CC_T1fmp80>3$2uQ^r7HL(rQ z+7Mmd*pV`j^3WWF(VV!AfK2ym)?l1ebgV=Ko2gHTWU0{o%MT(jWe4{CUN2W$JaYdX zUeqMnXIePobh4;v<8YQ`f7l+uBd7PmEQ;<{P94_->5(X=MI3tf!qq>Mkx;nNiH)a) z1>d$>$l9*0oc01?wY=x+B~H)j%-!(q>+IG?OR@6B3S^AP`p>7>yZJ6Fq9x#_IP8Ck z*7+}c*&m!*?&d5|c<^-UsICr^&4i2R^sjI7un64c&1SM<6_Jdu?HX z6T?M3x;zc4_6X>GP*}@#iBONDaXlv|q+)(2y&!e2;o{lAL3Z+0eGuqS-AA_dey2>% z6UTiTQ&o)?QH^_<L)qjBSbZm!}4HYkdp8_M*+6<18k2Y(wZ5)?%>;<6~d;^EP(BL9s;yll^>U<<_>mrslaEp1oxAYt}7w7eTID& zw@32xhdmJ62qlQHGaG+dmSF=(cD|QoUfE(} zFu-FpVAk9xDz2Q*=5WUOJ`E%9GTa7vmcu966Pv_GVs6b<32q# z>Kbh74vutgaET6HvF&1LePpeSGVX;69X)K>OpWA@-+F+4ZK(3D@K;KUOIJFqKaAQ$}he*R7bz%r# zz)(+rEYpBO7}*JXa5qo_S+?0V!k)5$Jrd2nQ-yfLXj?lJ=Cy~~2(GZ{hC^-?fw0ws zPIPXH$&){F6vG-8m7-+|R`xja8OWS~u(Mi?t_@kcbX!Lh9GWqmb>ckspHE>BZQz1U zN-k}BtHlLK)^RF&pq-YzCFg@$S?NH#{Bz!2eg@M&CHvu6*TfnK4t5F}8*GNKZ8Vsh zXT{k8dFN}*`j#3x)6-UiGqZOPrHM+`v|iv2_y^f3@>2p}v^5kTIKy?<4BBCTzXWdQ=Ap5jeXDMIaKu{gUj4A9&~6;ETy{11 z5drsUGA*{LC=UeK98t6$f}EPjtz0-~Y|F;|jhgWlLDH&aT`#gB*k)q!ks9?h)d8ed z&HN*=t%_gco8MZ`uf+BukUhn|7R)=_(W8FcINx>4%M}CUJq!cjF0+N_WFRd3HL6*Dx6d9>*rHBG{c(o{2|xj zW}cfkW=EeL*ou>&zIfW%!s#Lgcl;on;PJ|DWa)qT@SN-Z@1Lggjt4ON9Cu*WX>|v* zU|Dx;#hNm(S}xq#C-|Xb)PS>#z~`ht&Q7d zz78QejTlota6Vk>`!d8iIPA&ACDJ(z$3xBR2N4mi@Q&A+r38%6BF_6@aX&{Ba2__I zU$|G0)mz2sTt)B%ki?a&wXSOpho2|tDEHwD6+|TF6C0+2DC>YhF#*99g*QSgs!fef z`{|y#oAeB*LD>kljB(;vy;?WF;NapGoXgG*ID}l6xVBXHe)vy!n1~%f4Xni9@8`7U z7kehbgXK)F`1)Bw5$J3ufA2h_pNZLk|2d)VO{oRNwHA3f{uXKhO(G^BMNDGs{iQPv z5MBePtR@T!RQ4P^E{6m?X4gP|$n=Mrws_B}9!LVraWpfKOZH(mp(AiH>AI865!I8d zZ9iN6u4XMTVY@&$2!B3tn3>2~_3=fl0-E?dPU}GT**Iw1l~g_# zTTU^?&$88ki!}42W=yPDN9@^i1?he&Yh<2o;(aroM$f>Tj>|y@*=U|DO$Kr8qX~Xc zf}g@rI|gdAk!L0t8awlNYn~;pU~fG9#}hk0ImcR|Q~19fDGStitl+@r=`a}B{P`F( zB=spDmFy5pwYTxvMD7{m8u6M+mg-oqZ`dYw+vX9X9~$85d3@#gd6Q(^k>ivnH+%cJ z2e#0#_RY_00sKqJk9kWXB@EC}%iY8@EEv*nuGKEp&(YydTZ%FNj1x5PLLn zuO)x6e;$tMd9jmD(y)FU+<44RfsWZv%J}iV>7Y|TC#LskXAtbYbx>WwvNs9@f@^}iySux)1Shz= zyF+k?0KwfIfYUyy2R*@>JN71+ z{3AcLrSF@F#E){?2`JV&Mkxc0F!A>@oW)1=u6Q8I9N@Ah&DG*EV#m?zjYhxm z9gG?hcgse$(_VniFWA)&m=cHEIK%IYKZkiEByWc|A^sY=L54jSOffb2E|}H*tUo@c zE$;S9OAkZym+GgmN~14~>f485_-e=*emj`ur4ajbsvfmr=$*bNWp_tb@;#F2{$S^& zQ)E>c%clqV?E%efs$Up$58^BMw8aMm(OuZP#E7SW5Vor_b?_t_)uI7;N%vdPPQ=q z66P1C$%9&l)j18i>d9zL=-zZlg~=@u6!R$BZeyYP zM?Qy{ujP*jw>tlM^r;>lPnav_+DF+7Thy@|7 zmEkh9wWiZIvNbTKbF;PsZnyve;o*0)(>Js9aT=ev= zuC8>h%yhO6ru2-QoSgIwO!Q1lv_K77M|T@1eK%SgN8&#u{y{^;*wN6z+|J3|)`s8@ zO??AfXD41FBH%s2zs6^6CoB732^w!q&|K7sUNz?@(^3MVN zA6q!802hJKD;Yc5Iy)E|i@F%wI1&Fl2_wV*YH#Q4VD)!8MuzmpR>syqRY#y##{cM2 zTvAryzgqlZfvLH*-QQLKv;U)}lex)%GwVOb_UFyt>HPaZfad>2_dja?Ywmw51GQvj zxkPLYo&O9^QiPZ2Pybv-wua_LTz@|@8X7Sf8E~4=8Z)sQ(6TVIvD0#}8Zy&z=rgjL zFdLY#Fd4G{8!1T}M<;z7L*qZB0OEA!038MvHbxFM4n|sL24gl_78YPhISrZgX^r(c z3^|xsIQ8|7Isc7>yn{I)mHJlyKB_;Yi~v$>hMXLnEF4UKMq^0J!f2vTYrw+6PRnj= z%)wyHV#3PE@{iFN8FGo)I#}xi%V}<{Z)!|$XJh)ek3S6O5>$}nC1Rpu`0o-0D}5&u zpaCzDjJb`o+kd}MF}F5WcGCaDO-43W238g(7Ip?sCU#&x|6NJd*ufEy#6L6{8R(ce z{=WIMEL^~30LJS7kyC)c-*R9sT*3~<`cAeEDz>&(yhMM7MDVBOU-2g3`NyJ2m^%VB z-2X`YKV@D>-}E0(|JVXn=6_!i5d0NeE`7s)bmFM*Vr=xcBcRy`}>~) z^{;aC|HEP#a}>`XS|&ynCPpp>MlMDMY6ea&1_mPf ze@>YG&#wO0jCtt)Up(RYTjAf-0MPCqWq^7Cv=#k-sjGkT><=6NFaG=ITKr$^0U-Uq zo&1mZ`@ih^Uv~YEIPgEJ{J+xmzwG)Sao~Sc`G2MB|2KBQ{I|nnYy((9u7Ep(iSb3+UcD z8Frd2_^lFI>HRi&9DPwqLOyal)`NiF80};opKWcs#R+C&F)mhl96~f0YnnzzYAmWt z5_=Uz*5P|oZB-6id)1LI^KIn5`W!_SG>#d2NGR&PC?Zg?ilWfQ>Y-DmaRx-9&-RG# z+1uztqzPrB<0_ggX^s?t!Difx_5mI+%li5P(RE2&%X(pJcduMXI3> zbTTJ+>l&fLHOzgLrtAi9ptjif#9d)Q+wdLQA}oAC(_)CC;CpCsg($YDb;0Kv<`NpB z+F>S1vef$+s2mk0=2RIspR5TL=85Z7&wal8^$p(rRmW(FyzprP0Y4B>Fz_~znn?&S za3~}K0RkxC8Tfz{^ydW>5|q&28c^Vb|EL-O)cI2)_@}ZTh(E#KR(=9V|DVm<`WTQ~ z1O!S#B$R${kiXNjky0~9&^Xf(2xcS%HaA0TF4#if7wz`;yE8-DL zf}pd(<8eb0R#jya6cnUL8uq2l?(>gbYdw6s91vUkqEzxZRpy%tRe|xyca<_tR781s zCH$g`3q_hFDmOv7AKAGm1QJMKQtX8J1!Xlqok0kgnBw8F*+7uc&4ngqTz4hug zn<<3q?yh87k24=}$bt8^O!-lV<`+tRI83G>m(%5~%}q%Q zDI&J-P)3A*M9d>-5v8|~pvHeyMl1%iVj)2kBp=^cvh(l-XIEe>o4GvvH7RZ5qoMsZ z-bz5ov~#bh_BZ*$wW^3E54C3t5|prU*}3eknAABpQ?f;tjo}K(755@7ibFs09*xh6 zF+m1y@QpSbbkna8q|IK31`ikdiL}Q_rmfX+zyN-C7Igqx;43Yyx_`6jdS_`!tQQ{2 z#B{DGZ2QXR;no`gJeNd2`3`;W1O*dc*qRzpnT^DNgl6KXJ$wVtDj5R>c!Qc z70bQ6K$<+F(Rjw4o15EUW7*>;9fVK|@oRMbLuFJ5R z+4oKO;K!9QuERI2rL0{BarOF{)v}c(Pw@+4KC7jI=?gqg&%jKz7<_5Vmt6hr`J0#v zeLKswkn*IYJCvZ0sQVq|--<%WQF)db_J%R%Stuibr%b%e*~9v@lsw^*lg+S@%t6p! zQ$r<-AtLJP7(PBeZftax1M~!DuE4&G4(`NxxFb*oB)WqU_ z;F<|%8I92Tqc7Ky%modSOmzpxM*sA8pprkU zBedNgb^Ftf^9FWvC%r|TSJCZ9lUnasE$Ka0FApoo{?`ookhA0FlH+b0!@OiREv2}p zBkpo~iVQc7*d(N~g$42?DNgq*kubOnba|n%H1-&iu^&0Z5?$RS(xHf?NI`znvT$tf zY~QrMWcFqgGxCV4g6Xt4O<@a?SRc!cS-ZcVj~9Vcg>3pPfTamr$3lo4j%m=z2UO3? z-+Rnui_JRIp+AiGti|<)xZWJC?w_7o$8vlLCXCn{OXE+X;&MI;O%21mV}ts-Vta%_ zgi*2~5IQEX1!C~&bWS4p*RF*05zEE=hF*QCe5-vz3UfV}n(0sD(Qz_3uKFJn3G586 zQ|}L#0cWjW0Oc7N$m@9*WT7M0rx?P))o^5a&fJM7F@QkboNt(R9~3lM(dx3kfi`Qp z8ayLY+b(J#IKm%mxGflkomYLoY{Cp=tqR`)^eNl!)0tG5254R)G&;OKw z_SJuRj;BO%Tc^9H>Tuo)r zw!cnvfH~jA<&KNj*VfvTs)BXZlD0H(HDZv3S6-nEF~#Hk@qC13b-19)Sqtpt<;AaU zMxR(bT7YKy_ns9gQZRua6a$_CgEtXl%8^>s4VMH>N{btR1R5k_l7sw(=Dl9H3<25C#^t%Qh9#=aA_xYB)6DCx3rmCmv>@XOjeA6{EL7nh%l>N`*( zip$ApIk3R(wGmyjs4_a4xXP@bIe#V0$W%z_G@|xNSPOddaaIu;TUuT@u5eC6ziSaj zQrJxtnbrA|^=EIhs?ctF>ZBw8%>Gq-xMpBU}NWlEn%QgXGEfKa!YPMX> zv^(r>|L$W{a>#3WoQqjf*ZYq2#gg$lZPs-5Fd6s~po>3gRN9Mll%crgOE=q<@%YB7 zyFR2YMpIMb)N%SRZIEPLx$LUp4Dm3vfb#7 zuOEx_k;Wo z35s6T(~`&`n54dd3?SV05LNS4?8JHSe%Fe{u~?`atJ&}s&r$e&csR7~4e6ee(qotu z{5zEvFqJb1QTE;W4PnBH>Ju=i;Pvk>2`V$S?@t`P2nAnHOCD@&KZl6T%n4OEf8wrx z1A&BuJcZoEFN1bU8;g&o@5F0p;l|y6mF3Yh*$Pz_VrikMuP20pmy)|j?DtrA;3K)$ zU7)QyV!o7_RetU{H@vC)mC5BSRnww>W%cW&Hh|?pG=Y}P^r{TtuviyR|&tqzW!q&@Y8Gim<*zY3ISF@aO#pg z*r9R3ue|M893^{S{c_t)>XquH7Fh zan#4tH`kq@nz|2-`B+{Qx*EPYF1;NSaUHpn4kqBeJwG^pZ7cfz@bG|yn=IF|%oRfc zjsYK}EYtrn3}OdN68(ml@gzemPt-pD`UG5BH2~UmY(VjP1#E}FC3o#g0BmE%z%?Up zEAMVyf&|6Epm;+90j+Q=@u@E1Zq=z@PmNi}T>Gbhpj-QDU-IN^D~PY*I_ z*i-ZzbyXr=o`7p`#IamZ%3fYha{xl5yjs;d2CpX0|C zjC@FWd3ieB4(;OSp6+f6t$EmH?eWDL!|H~gecdEF9H&Nbo?p5Y$JLEEq4f|B1%x04Wd3XpN9Ub`v1vQTQ<4Wv_ zyAGUMKdq+1e*@b;jmCzqr>*P$1019Zl-_WfQ*ifMRjoBrV5Tvp1L?W z&1ya=QY8WY7z#f>KOT?L?rtuU)h95)wkWs6*si3NORF_B8L?>D!#76xSsBs2B;c%m z%5d|DCkxZ#t0Ks~QoEEtmkigKNVYC;^KjczEaCLgavtHfurYbrztGXq35|@TO2-0$ z{Q=$^@9p}gOxy_ti*?e}MV4ji%dU;$Pj#5u=;|cH@?LK74b{E0?fzSc-CmXm3ZAH= z^F9=o*5~#$;csw+1Ox*68&wJv5839*F6WPu3E$s(npu3THzJhkx_$)kL8UmDwYN+pSw3*mT#_iwHn_Lf!*S)6F?;}64(I9dEr_y*Ut_ovG~@C#hB5j*<4 zj(aj-U^nUfz@7RL~+flbDVL9uY3_^B4wYb#QiND5}n4@t5F^IZaRDfPj8)}&OV zMI6&`mphW@^FA3>o?&W8SS&X8I-%12f z05QRIOH35K$;0{hjNnbh+GbId82f@zzCqd0*`TDsjKykUHftRj8ag?gwyXe{t-&hLfI?XD^5nrAWP>Z^=bZi(5-2QF>Z_TG#w=2rhrA zd(7>;w5?4)zh2W7(Gamon5kU?SvO|@JBJ=D? zLiY{NKTGMJR7gY+J4ow&(pM5n?sh+KQ8#Mi31KTl2<8K@bSsUv32`}0>iCb3kDKS` z6Ft2&)6BBq=73O42RkK&E(U3P+#OwKDfNuFNO<}#ix=jn z{Q`_&_2w5}b!ikQnC7^Z<>V4AF-8kt*t<>)+6E8TLe+_^28|%ymazJkkh9n9@Z1q` ze0!Y%9b^0M{{DH26~HQ9YSI^u%bd#Inns^{sQ%@u7-wis%w3K&OdXsF)k!PKJq4?W`?WFcoL zl%Pw2Bx}$@p*o_NaGSh7b}<@VAD>uyxBvMzAuIFLK<((k zeYB3rN!5a3Po-3#6xI+Yg;ZHd_u}~OQ-X2Llo~0_|E|5W&r&S$=uV1FKbYe7`?GIG z^REK_Gn8b!v9X!`$Kz25I+_H+<<1oNWEkB_ZMq`)jSiB0qxc7PlHzpm0EUlI@hQD5 z%6Oy&o7>xYfK%}0V8a&##gcvvetynN<7E@=qjjX`<85c>{&pB6ix&TPx}O&9^=r?s zr2r0MUSBmfED<$pQdmH~vV3zmv#20qPL7WlQ%O)fD(+M-K~6{;=k|q+s3H8}h6H6A z#a+b~{6oAd%8lC8Fgz@5o_6z9(3_Kh0w*-M;&i*|N0T${r)R3&;iLs>&Yg3o*O!+; zhLT(@K`dr0nbcwNl}0;(m$pS*SAy7|y2e+Rdz_+hl$Ietes||d+6L&ezW%Ca|mw%N!^IwRT&DWdHh50poo1G?Hv3R2_dPqzs zhi(KgQhkY(MSpY5m)FIet+ zX|I5Umix&yzSn~wd=#9^^++$VO0Go3z|hdErV4-^i*C~eE1MYfyTM%!2&c=n8m)1l z)+Ux;d(4#H4AH)wnfjVBIPwk7HCqAub0V`nG)kIOmNe*aQc930=$Veofh4+@Jb$uC zUbkHuzG_)xz10;lej>TjtjdM8#O^aS|_a-bmn?NiQ!(X$4?P!52 zd4$vVP2T6pJWFm@{RV#9p*>S2^(pj9#$fJ?XGi5Ds%drhSS5C(x|aWX$nAAU3_gE! zMii-wszsL@tprkEh*JY<4dN%W)uu4PK|a~1eB>No}ehMQs(Qh| zk2stTB1KFjZWo)ShE~tzFr2NPleK$#syz016CBLRnYaAe8%HX`6Fh^N$WPY39haIM zn<^Yo(GFDwlRW$E!9xC7SsRwN6JubK)9&3uF39%Bcxo0^n;!e54>#P}2ZJe9LI9GK z<9R>T>d8GyiTe|ZT9F2TQ|2S2wq(B(0JfkYHak}PO|{vk(AqtGubrEWjzy;hLR{~f zu;b&)2#)*Q6s;<7}i$-2BA`(7`$9M&!d=(H6XQBU)$XuDBzlSBbVP0nv| zD-azK;q4>mS>_u&!9rad$vui`($b=?Eu1?937Bd@YOusaP$eqE0Ms3+=~1j+L$p7k zOL0}Vo7$`Dj4}{{j)Ay$-E8MYvJ10XM@yZMAK*xGMBZ^T+-f6?xOdVnr=kr8U84q_ zHicoz`%5MNu%L173nv2z`I}4Yv-bA6;VVjKvMEuOKaYc9(HOj+Zi?bX z>h{JYmCfA}i&6fJMlGSIr|GlD{h=WPKBP{sVSCV~8|wIa0R4h+8y?y;4yw-bNMz~z z9~-}rmR7TVlC#&3H7$&W3@etqSBHn9hM=0_9yu27xp2P_Hd@LYAQjPue-auDK~}z zhkotWv}dpLmo24sTb`r+m*LczY(ek5LvCi~Z9*vYWF{k1Q|w)g>)YG8rEP6uC428~ z_LpT(+Ju7TB*LyhAAT}Na$}b7pb3k)##%makER`&{8>N@q|Iq&_jE0wcSnVAzd-;A z;$wB#2Z{0GiZj+u?bQI zi%Uzp!R}MYOXa3_JknzCRn*b+&~=H5J|u+lCx~%1;_4UOndBiDKW`g~a_7K^3eS8j zvM68z0sc_1Qd$zd{ z!IpwEG)#2LTcOqqx-~cGFVDR|41?bL^P0WvIQP{=@Um~@Y_^J)Y0)Lu`EKwb;PYu0 zbI#?8O2;cruY1J1wL%M7L8D;5N+EQ@?`Ak;PGFY4-yYV2dKU&MQhX*k;)V-3BJ}~g z_VuTq7qH4z6`im8l3Dtt6l0(aJ)(vIj5|n$YIhdj7o*@t&%)v<9S8^JJH}h*jbFdr z$TgY4pjXUAN;$n6u#T9_|H8Cm#uVJpRO7rfoeHHRBm1V))g`*@mPD_cnV(qSxJ-5l zK<0~Ahl=yl`KlgsdgHJ?o7wzdlr8o~I^Qpu;J(86uFnQIl%2Askv#Z4=Vv}9dR&wb37^%Ia} z!`x=OI_e|JcJ;4=yx}rrJ%FS)ST0!1t$W2wOw_tjOKzRQ-M@Z}6BhL9H2?Jad?OHF z9)fG0K~F$;+j;1 z1!;$WGuTWx(`7Fg3&u3COYn25*t&#zjsD=p4r^{WDC=6gPNm^&E>-Y?h9;(}>Qa)i2Y5Ac#NtdYC+h9d$pFG1cf)~A@)L0H z!gl=3F@IVubw6Bg+uPeyW?HIM}`BxGg1&k_<7MU<3KC@EWl!(5!538|?^%nHL~$hI#wi3?nQ04|To zM5bsA9&dO>bagdD$Eyo`md_RR_}%x|G(sd1b8#;i?GBVX7OFC(5~GJuWZ;-j1j6L@ zZ!hlc^XT^raALZ=vcG~J>)lnDjy?g{jB1tkH_~OKAcUN1{tf8i5QY+RiLZp&CjFBI zj^sY89m2Mq&0ddJD#Z%^SmzzmfPH;&b=5sJ1?|YJOoH->038{tm&{<4!~h2umw}m` zl$e$uuk|Ag-U1TuDlU@26s_|eqbY-nTivDspDOs2Z7 z0f>o!aJu*36}hc9nc3v_tI!Y;-=hw=!}3re`zK-Qk?n10YC!ABiPCEwEmVrg*+}CR zl`0sQAcx5gj*e~#o_wg(ZXPaCE`mlx+@H!57c=z*j_-2a&dS;G>&Z!lLYY*d(Ll(L zCFkz(q27j)TTx`8R&l&TF$n;!(MRpN4B&L#3k&F;p4>u0cLx<`>S)aNJ(w;}OF|Mu z63D=Q9#UpC?iVmYW|}l77IdlvYuEY}5**r?2*hv+mE-0sw36p5G^dIcg;!U#<3dGK zegxD7!kf)r%x+R;fz)OtgMYpKR9DByykHoQ5%p1l7}-CtB45ChhVuLp;k;8Vs#0e; zE~x^*!~!ECU;$LJM5~c5nNEl5vYE+v_%oN&fdbY3;{^ZvXt{>2{p*u+;Cz}qN&>lj z?=Z<}6iFC+GJ(tqLy|hPo!#Ef{KC-QLA@td0|14&5MP z5994fSc)kc;ddp)+6wq$Sl%C9kfN{{X4GMM$^!@|{B{@3=avhVvPIFj=F9caz=DS= zY#Z4ImxS%PhY_f`uC=RMWiw;_(4I8fw7RG14N7ZeUE^-d4R-y+k`kMkK8o*~Zt(v0 zLA%+Z?>FpPi*tdp2NVp9!4Ug~-QMUD5$}FKNQV?cuBi}!-cbyIE=XN)5K+>zRxkR) zlt`PaI?@&C&bU@+HsoGDM=^XN?X)MkG~pWN<*ZSe-7a@%PJeiCQ!Q7&>~{+Oa}<{F z+cl2))e9Z9Rc%0KE%d(Qzk)j1!Z=fzFEE5bSh@x?n@^K)xtsvu!qXB0+8Bw%z`6`n z6BGdzFX5Tl+0UMyo_M?-Dn#dfYdsl|j1aSgSjbDw7ZjAZ@MIzs#2j`P1ds?gB&@6r z>MOOT6L>Ao$ErvDKeg%hhm)v*s9f3LL<^%|m4W7E+5khqkhEq!OA8k^PlzMPg%O`8 zo$0m4>C)%DbPW|1lFDe+lu+Ob`r9;eK{H8&#}9IJ$;^iRP91L^Z`f0~kK)%t_uz)6 zXDS?DW_%@)K6zh-ZsOuP7(~c+jY4nudzUD-W08?@a;#{8amw$~2g0G&6!)%6tD4M5 zXtBzW{@zSaJ{+HE#`;p0xIa^4C@CSc^E*fQWEoY)%d2f2ed)YIOY5k=0SG7};_*y| z= zL2VxNAa|GU^_3jCxiA6|qq>`)Fm81fbYXN#T0YTjZP(H`@WVeCAD5PvLVHP>UrtX? z6-vG~&Wr*t;MmEb&sAOY7k~4etTzPm61HAm;|2r=`&`BOUUWg?xCxG#o&a07skODv zWDF}~c&OoU=qSy#+4Y)E-<5oF{naoa^Tqq>&I~IQw#woQRg%~9DOT*_PL#7?pOKfu z#LvC%z7aQ1;0NWtt56xAtv179u^dDxvSx5PVyPY1FO>Zl*AB6v&i?-C;pvyS>@QX6 zDnsD*7(2*Mu!BQjvUki{0TLnx4j+L7lXRLK4-c=mw>L4=gOZI6O|}wES)PQ5k2Arl zA;|OoEN8Jkth(Az)An05E_c6e=c{VzpdkKb(oKZ{)nd^naxecV_hs0k1HhHmNLfU_ zzF^GE%=DmU$|Cs&k8PrYAlnkU3z!XkWXDW9#b3R*ho~JtzDK3K2_g)er3&J!I-bIDR~omEjx>*2De2(`<`zOW%~WAq*l4*pQ^XLGvOQq^38IjKP^2#13%o0rTNoyIE;ux^{U z>^>ymq#|U-W=TnYV$HjeMk0bvX$H{S_Zw{od$@7<;{|4qQ4AnO>dVm=SpaMa98hb3 z?YU%1Y4$4+&)l}RVcS95OevQT@iO?a9#s`AxKwK#79P%ImT`CIV#acSQ@GukAAZm@ zkY8A;-e|+?>HBn8V5rv>0C97?P&FI5G*_kuY^DK&vTae+1iodjvlETsMawG^Gr<4~ zOrCKDQW~1_#X&;dcnmf#4p7htv&CxtlCvt{Jj68M1;=i*gADP|JN($3nmtZ|#R+1@ zvbdNiqcXQDWWqW_E+Z=&!Tvc&EXov9x>VK4q&rCdad%%B4v*!cS2VU$Xf#`mj zWHJLp5|!8|R4cy978W`|-cqlD>l+Mgvm^;_4eSK(r3e(sWtah6C^`EHm@Sps?H^rO z8>oLxe>mCrP{))lH=#^?SiSfoE!Dun#KLW}4qQbBB@B9L=_6D@#ZX_*QasGrJRCM# zXiw)$WL6eEU|2fr4%=UD6(}*PqSI;)0sx|8Pk!)#S%Ot zDc_~OC?6&g)L*zF=?f;XBBx)>>BPs5?9Ntbq3doC7Pw6Ag=`M8RB1xBhZ1wlLck`Q zq6G3~EJ;a>CFZetsRyBO!;?=djE^Chu4wZet!4^C-e2pd&5LpK`9AKVqtT@39u0wB zr5_|J#y~)KD=6$PU+h0hyLmRcHK64y5^G0*6yjklS~9`V2W|fPu=sFaE80d%MWGvNT<#O6%r@=`*?eDGvKzg9Op7 zh0pf@1vxmbir(6?^MyjWKXqrvsJ3p70Ob>Ia(^JC{b&kj1d#iQHP!?N1G6_DRuBUm{{jZeB(F74u=$3Fm&e63UeiWYkk!Aaghg92zj^^? za*6B(UBVC)JaoUD)4BVXgj;Ssljoh3Qcw}YxRk{vlK6xK_!hl>auT!s>OxXNb0B?y z7!Xc-J12s(&1*T}3Us0^lsXQ_I~wIeIdSFgaUEc?fWKdDz4CJl+d_R(ZwOuvj+u~f zdxLYlET zIv`OT2j!UII6< zqJASQ$`71*);qfj!hlP!|C-meJPa1+|KR|WNl#bRWoQu}U@#~$Cuf!F2Io?$^3OMBjZq_fh`qR zZWtDo@dwEZ_8}qVOL?r|``u$~6Z!ba!2JfZHxd+Ae^M86;|jLqY(v^(eS3dpI-WiR zWN9(7)9c_RuC=<7zA57TSf!afxO7sAlN5@IYS1r$it{Id0u17I{5%?(^o$G%35uW} zBKci2ec{VcTKg+<~>59E0 z^V=lO?np8@i4nU_YrS|PuDpqu$NJ?aN}&Fn3}9J&Od?=X`8I(HARtnzE^N)B3f8F- zEKS_0lec-%K_>`>e{9crzEl}8z~4#baxU$9E}Yt;$TiFj17cn-mTGXueBXzRwA*j} zru~%k^W{crw^kn`L>)rwaxwFK*2YvC>w-SgnqFS@tPVM3XKq-qjaQBLG2ULTDf65H znH^S()&7itUwgebrnbJnyBiE-kbjK<+^zPcB-{M29_?W3?{N|n9;@bb%`VevaZjR> z1~=7jP0i}q&Yjr4-2^qH^FI+pm1sc$@aFdQxaLj}4paR%VcO{Xo=kq{7_H4Nm(pA- zvGX1N?{kA#5&(hi`3Ar3`>r*-pzAxZR!hImGPvvT zbaN<+S)@&Zvi)TTqcePnW#UXhWiB2Hc699rliv8p0D7wCw+!}Nd@jX`4)!riZ>ho7 zGS17!0QqB7`8uGZEZ;W>TyB?q+2i?c8gznRg9-|LpK(9Qc5liTTYyC60hZN7CU3b$ z-S;wf!>E>+NX>x3=|#u8Ug*y-qH$TytXX~EUvU}ue3s!vY5TQV zB3Pa_8#w9TwMtJGzgU0h37l{>b&aOLvE5z%nIJnTN3bvJ6SW@WW#_rH)>P1N9|31m zQxk*TZviD`WqT*5-VtvQx#)i2mlfOCLQ%pSRMLrnq)V^pleV@ta8@Bu)_}jPD5bwK z52Sz|G-48q#*kBp4d@Y%=5akemqstq8SCRn);BzzjI@%@aFE6(7L+JZ;(NAAXV`{- za*IIv{8^+-wc>zZ?{_C)oY)<{D~J_f7_USn06JDeN{VhC2a!}11<3v?V512ERy~}I z^<=dCKMqk?VvK9Nn+l=>2dDqE zc^ssP$!|`v74vc@o|5%~H?{ATbRyoZsk1e1-|yg|WKm zYeH{@R-<}@MbcexzP3@T7dSqfwcM^|hS`)aG&VgpM`ATa0(a{^bDNJUQ&W;0r6a-1D!qB>jP7)qOH_dvhj`r$C|J=2qi^xUX%P zw*k_@^Yyz+0$SZ$8e#ny?_l?oCDaJp?_-{ZQ2m4$l(%(>`AV%{?CoPsEiO31^O$!k z{ruG8%nsggbRTxCH2DLe8!Bs_ujx~ryZrX)MN(gQeF@s<`}H7fOX6m`-ea@0Wo;n#MdY{`Ww zQrA3_CRm|LzWqL&T*%&9mI%Ylig)*u8Hn_11p((3Q6F-8bMb&n)>|R*v4(pNX5Rd$ z@$>*bf#pV8s^AL8+X#nI;Wx*Pn0B|+APQTtr~6#z851WgZqSV*Xq?9pzsu*om}ZAd zBFqL)Mpq;0A8fb!7o+Q51RXm!qTw0>{TWOhZ&UymFn$y6Eq zPX83oaW|pfZF??nVo-siX;qGQePJ*AO~xX^;}$aK>pf zU;OQ16J@cz;~b{zx=u_<9kIiI??}-NpCvX2zYwaeWx-Y&vYU}$^~~&FUOuq8;vIRM zOEqh4^lR-}*Vlow8Ps}B_~B+drdT--;=Cd5)5E}rz_Jt+mofdbX2i#<<3f(T{=`v& z2D6_0FWZ=Fv+yDX92+LcXm^y#g$!ns0vR7%DzzFj7u~jpcuYl9jK5V>e0qC(6ZK&^ ztHO-zI1>K_&U~WV^gY!l(c9RlKA#5OSn{O?Uk)!i=c}b_?GgKKVCUV{mVWmlHgKE6 z_P8hi)5U462gVHa?&yxhbUZ?>Sp+oxxaN2?{Pw~3R{Y0F5SJ1-igEU*fWFr+>6uFr z%dBlBbEdHDrBU0y!fWu$_^4vz#$HJYH0NuXuD~8Ic*ms)k<-`I>5*lUbwC+HSO7o` zo;&YXMXRsB>OVF@XYxS2*L_rR?)%8>{S{p4of58^{fz*+02jzzsL=BL9mD^oH=4qj zpMOBtFud!)ROhI;9~!yEjs-8+OTPd6{JbjZi1Z&AV0Uj6oQwN<1#wv3i%0H9Ywr4- zqCU=O-fs?Cbg|3zh;yy81V@wS@?Ru=B4l99@=g58kVc6SrXwibjjBV2mvZ!^FW+J+ zx$65Y)==E%iSJ~*m-tgfhGT?&AC9G1B$Yx9(bP?XlWRL6YFDCK*I!iJ(QxPV4=wkev$m6w z>(~8LJvVHfxb3FZ9gF;i(5Be32F}UTNe$&JL=+UEY}U(@o$nw%Q;vJB0OlQkp-vDA zR#DyC9GNCJplPTv+6&)+d91ei7#0{_=6R-QJxyTob!}urfJvNlXEAEYdYe;;fIZAQ zZQ+Hxz5MB8)-$b`Nr?HKDwe zZOWa`T1a@?qhXegno^NAgu^vpH2AY!-KQ@IgZZo@geq&Fv{F%K$r{-W&QD}Ip z3I{VT=;xFF?e}k;a?OVDRAy5&X?_e1rHuq#R!fz_GDfuX~fRQANVa4C2O>F#gQ};|66TO0h&|bp%^D}&+8?L`h7bKh!u?sW7_0XP zhhi)OeW&6~Ek^`s5MD#8QGbNdG0Z}`4fVB2YiEQda4 zobOedT!&HQvbeO(WK-vvA{2zo`gvu!L`{;Gso!gHu;2vqXVM+~LiRz{_ zAkf--;)7DV)ZNe0;^l`iI9JFesPd+=)bO%az%_kP7Pq$=^7?+#JlJ3)onFdXbiBWv zx<0K~wsnJSvAsGPe$!U(NBsP(OxkGVl1EOKY<$rCc*1ce-kz>q@tjK{Z2j=`G~MiI zN+zEPz(n_Os7vqQL=Y-TG zWrJ}?QgI{$>0Bb>_oQRN9ECqylZKXdsqvh=#pP83qXGE#Btz)z#byZpbfYdm0`8N> zvp0RxK?6$=Z|8fsK`e9;nQ!kZELy#`N8rW9MNw9DDk==AX!+ZnmXb=LExI6&YFO&y zoLW^|C6M$5Wb1Qq{XcAdV_0Ti*ze?;Y}_K3;0u?|{fW+?XX(h&N7=~6>eps;% z9#F2NvRR<~Oy@WVCT!ZixS)?P2QG39ArVbb2>2>I-|Z2nviORd9UR4IRA7jDW6SV) zZn_E|O#oesTJ>j=O5*Ce5RyeIh1jhJzzG5szv)DZ)Y($yYNHiqBn}6fcr#FzHuwW5 zZ*OmJ1Rj@vPmf@}UA1toU}7Oh3!1?ne4d7tP{_?6yRPmxn2KT0L1_^(`SxJ zBq*3mlqmgTaizzG1JCDvzYWNG26ghuTMf~%x!YK%5~YD2Et+O{F6YDK+NcV9)ieVC zq}b8yp!oV8uwZPoOhZFM1AoNR2M1Vcdt``{$8YZMjjv;f$tWmr3gjGlW7bS!N`gy{ z{)cy|V-Yk;nV}9Mhpr`0I$Y9{Li|ho9k3LDf`W!bMPZl*0MFygOL~7io4-0D}^Avm3usG(9E6Aw7_pYcLSM@Prk#|yI>?)ov~-xf)XTOSUQ_x9a2 z>}KpxH8~KzZFB)5U%w1GCEodKk4Hy1Y~lLWd7$g+;7G)<7#4z7;AF=YY7NCI>r2rw z+)xIQ92^`p@sNCJSm&vrs*x=BumfjMgni!C_0iZDf&i-V?q*N3<~Om~6jm4E;4Y5S z_m!bC#3m-urj#0MSgmuee&1GSY&X5;I#SXr<)wch3xnDHYrn)#WgGv~l+(C4{Gm{M zu6MgLO`_KyYO&u7)T9vX(e}@mh@Pu45NUJ1(j(dbCFk{yV6zANz{Wj}ahIMI&sU}2 z?bjj^Bvoql1Ey~Sm5?x-q!4wnShSXnDF)d1>umpV1CBfslvX>-x(cwB*q65-EB{yxMiv-|0{eRo)yh zgC$yV8vj$B$}Csurt-S6Gy|JQzSMPZ0Mk9#u;-2yl{pqTR9m3o#q__=3Sti zbg|x=l7I6yygQ`ts8k@#l$*Z6WWKn8f#r7%F4u;EzBkKIcJ8A{^myamKeaui`!_Om zhePMEb*Yk>w-P*H+9guH`WaF2C_8MUyxD8MPM0XH+3G+Jya!HKn;(^b3RgSSVh~%gv@HWpD(aKS8q1d{+BF7>s5>1ZA5_gRafnMe zg8s1PRN}lZVv<4@T^_cA)bJa#-1zZ>KW=W!f3AN4y6nxg<@@syE9+XE^6)K4Vvhc? zvBSo>0M)(4j2|9;A7-zLoxLhi8Ld5wnWQC`s{zC=oGld+lflBdzqWgXR#sM!aB!rL zrZP9n*n0*_2{NJBCuK-T$H-p#4Ehq-Emq22*ITJLaQer%K8{s1M-F7qMM%aAZl62_ zI?g=qj%UaWm9E`9xntO075tjku;25BYq)Kn)D?n1+8;7MF@rp@l8u6wgmb6u!JYoGkpo zU7ltv___DGaOMnN{PoZ?ZossjCFreT{l8iOQNa#}J#Z_nvuLWJXhQi^7KZbc+5mu5 z#kD5-nZ=en097AE>Zw>r+~^T}n{&pN^yDhqvmV)?!;GH6ma>F9F?XeYvv+T~e;Lba ze3^)1vs@6W&r8YfbUfq7@AX>edZm|t)_*SIRRUN)kK&_cP<^~1$o_11k|V9gnyT2_ z?{-ErC|m7uyPIoH1H^dmK$Awl9U702#yU494Tu7^d(D1V93Qc>)X3#{w3$&zw?|-( zyU@KyF$KHjzL-#jY9&{G^l7!%3kXQ}`>jkzXXons#}k{)T7$-00l@47X8qOys5;4w z6l!9g7mI&Lrx~fT%NCdlp@CwzHbKtAcFza<++Fx{{y~kWGbPJx6wV=}AIpyKmDF6+ zc{0fiK!24E7$C3jrh`*hOr)vLb!FIG)rk;8Nbn`QJF+{YtrXX#-rz3-pb!C8Q|LYH zDKeZM;5cX+?AO@5G3VDBi&Wc}oU*TRqdzxC>$eX{U7; zFoSOD6>P0epOPDhhGn0liE5Ux{2Z-gA68OwxUke{{?2M9o3Gt$o5Ahert)Zm;L3G- zz==0PX|$OidZ221mV?jZbc}S8I>>1jz9?C#l+NmCx}!>+YQoLxQJo;aNHQ_DFwAX8 zJ`VNM1Q|mG8+|CYH`nt``KD_idDu;B0FV$pD0N-M^#0&kCq+(Hp!uzc(cHvnq*(%W zWC+DlQ$>3C^jLeVPF?j6M@c>d76-heaD=-(xY6p;o{By4hLAhP-h?w8v0d3jr=B-m z6=ui4n(XFg6b_p=@V0 z7IwMnpkW0AzdusCfq|`RL4KuSBt#MlES;=q3i`?~k3Ulq%&c)-KQSDK1fgj4$iAzq ztAm1K{*C|`V_`S(Bj(z^H4hj zeSXc+Zy-qIu>dlm zr2eTI49}~~%ZS{-emIlH55|uX&)6zP>#MCW@P@fxeV0Nra?#>KNMm_fZxNyUBV#2pwE~dkkU^Y zyJTmznJj)wnt9t0>@dsP>mnG_={5k{8;%_8ZNqwe8C*oRz_tW5bV|>e?@Rl zd$(h%m<8~c{r>Ghoir~yh-xWf4e;C{qGDV0m`({YxsY8)&9mmBy5f2xXWI@S26UhK zFkX)d=R`5mg+S|^3Gj#Y)~mP6VI4fK?~<9W;{k`OUX?tLn4oohen=T|$I)M>;rUQa z7#fYTEoh&Jz)6G7eFOu9d{F5xNnL@whl%-*jIvWN%q}epP3l&Giz(Z^@m+32Qyl93 zpwtSiHS!tlMk-Vq4M8S_LD-xG1PRZ^=PT-)>!r$+IvIG`q)vc>Wr_DP~tp&e1DXwsX^~=EFX|(1UhcsMICu(-|)+Sq6V(O$&91?O-iX| z3e5w&TfigT04W#uSJ|35#v#kUWPg%F?(L%zZFh2<%rRBjY>nOs0u8Z3aA_%4b#FFI zKq9%%T-1~#dkq25lB)0a0%2O|r{o}bNPCz`Xvudz-)RqEAI(E5rO+PS2h`{1b+?4F?E z(J6mFFsK@fyQ{u$ptu~?IYJ)?FYYv=2Y z!pF7-mBK(KzMl;`Cj$eT?|{(WE!>IDbHP=q)G5qi9Ng=d6SPPkJ5prMw(5=E=zrq| zlrTq2b-DLxu75Sa6ko=Y>`k|Q`CAekD2R#u78VwSZInlHTRm$p|DujhG?I|d=Z8ed z5r42hNsh{M&UHnl*PKRxgV3(so_w-=eg66|Z>#pXDR(o+?TXMGF_!@wxu=;kAPE4J zRdwzUTKNP5jEsz0jh2I-V8O>*NBN%RsIlGP#2meSbElbyg(*;vo{x?`-WPQr`piAG z8HXA@aQt_^&St#?uDm~OQ4jb7%jn3FW}HjqH%fB{Kno>oe)-)AyC-ak$FyPIUD_Q6 z?=9Zx%rSOv@9cn_8t3IDXlN(*thIr|z=Q(Dg|LNuA~hv+DkzLL)ZDp`3APWBV=iUo zl~}y~hUWD&r;}K~w>^z@BQ+d!aY3ORt3MnZvgIbZpdyNi3?l}=j79Nm>$f7x%mJHjDpImMrj zLqPb=5oGM@I`(E~EMLFWU`QQZD!9jBp)++0CQ&X|fBI&#p%f58YAw(mH`oXQMic@_ zG>PI(%XTaq(^6720PD%p5;>KDu76-)ps+=<9L~@zsrNu4_0Rpo2Rh7DrQKB-GuDAo zaDADf+ALOwUK>M|nNa^{t3mnms+CmJsk-E zMVL95y6j4=%@F5g`At<*TH1qCcnba?uLwRlLJkhEeRV>&1K;7HuVv!}G9AompsNL|VZg-$!8oPNo z3_-iOt|1g0MEsi++vhsMcKUU~88!00jPG?9-}#sTf6LemFyn>s5V zeO^H&7a*voP6FRKH~`GF^hlxG?=P^jS!|&zt_xj&+S}R`=h~BoETI}4n1=bM`nd4; zY#z(&jRm$lO};%vT|h=Xqi@~dN9Br0fdnXKvTrq;f1(Y(B6-{V{VRnYqAeqHNT^z}(v2GA<8jMxIbUi6DieHCe4EPtgx876izbJMC=J zX92pO?G}!jGb$ux7pypwLSh@4xH{pIB*OH>LuQoaANtzKQbj2V-V=?!WN`w4my2-6 z5Oto&*`9O3y6rBQuu8vO?ZRYD{hOOP0lkh;p}Ro*>}tIkpko|vEzs=RHyso3A1UMc z;GdPjA$e|pa^LOaxL%D@FH`_6{&7(sXpg@hOYvl6!jkY0M{w+zcZ0g99pJ|9wH?t*NL{qz5pt6}(tKPPP zG?u&!oZ$&Eqq|Bh%>FM?B$Jlw*$jOP%J!a(Q&Np;q+IuablJU`SnP8C!o1R*mr^|Z z3GCeiRb!aG@$qng4MM@e2?8Dlz}3bcIzL~}7+>#C{l)nA!6%y?k*F^b1T{y zIo`W`a)tOn|KDWJ{-fWpN;+>yS~H?OtmHo0uuVJbUA~6gT%;VUbb?qqt*Box>N%VV?Jabl{wvaL40; zW04PFM`G1k(*&HQ5;a?ntQ3k^R5=$OErs*G8bM!(B+q$`k?)E^YN$#Vi!dZ({Hd*e zr}!IBDfeIf0K`^F0Jg7ZK>7L%h{|uBwg8K_fx$rxqs@c>ys&X!tK-q853eE$w-JI5 z!e;+jiM+a7 zaTN8!ur@OSggiJ$N=Z5F9lA*-XNs~=NReg^!>G?Tc4H$uRVi1qd5PW6ddIbs&p#e= z^>ugdn-v9}la0okYd%&qry#A6taQ!4-jqIqQX;_|2O7`n|bA8N87&-Z4AtwT940Tu#%hvZ;JR5+7(`vfjDV zZh3jLjAOsE(Bw%ek5mo4fiulw(&tdyxokaR)b8A+jxM{3-3ocpnT6K91 zwILtHP#dOd0-6{I35nqer3^^X?+&fh{QO-L z&zFEu7uFjL7v(mgE=tYqQDh%gDCPIfu2?=F-v^%2a70mHA&A81z~--`xtED87ok94BsBI@ww3%e$koE$Ag`nAQqmy>U$A6RVhNLmOh#^ORXYpHr?Nl?!Z4$4**P+1)+r z`rc9%m31L5?|CevDt3@m%tGY6#tAy;SJcH}3HH5uC7 zGdlXshqAUtX7`HSz(;IeS#17*At6j+qYsQZk;&0xF_nTg(zYrUTC$g^G)(X!?tKvB zH(47zR1H%}b77rtFeS^FZ+2+r#t6?B{fv<|!Q=N#QOp-dw_I$0|L!`8=^ryP;kfTZ z6?MGS2#XTBRD)}=9w()(ZTeZ^@$mYrO0N$~h%wT;vdwJ_^2IH6?U^O1`g0uuEU{!rPNjr#h5-DVQ$=<42FU+4II$+tQj&;%n8u$i~I-Y!tT zKAnNA^^rl7z26KY)}RohQPla)2r zY1!_-x0r{9MPzjFLc+s~NKC{pIO@7^qXgp$wo}M0?-6ouj3@y-+Oa#K90(yWsZ4Y{jp&8h>=ce244<3poxs_Ci+Jil5xT#+3 zwsRvWw;zbHoc>5sl2TH+M!^UwWh$ZJU0u&FZ|HJaxx&H#d(6zv4iYPf01A!;C(6C= zfI5~$FC!^AqAitcF;5XPi1OdXfC7IOT?sM}%~NwJk8ND9U9a{)+Iwp~ZN`9bKLjs} zl#MNcrI6m?qGXCx2oPZ>h;Dg*{C0L8TwF}F-y2fS7k4Hh&2Mo$LcnBvbvRqv8gwCe z{AyraQWJIu;Cwi_@S3#x^SAM0 zz4ln`^2+&ggR9Nu(pQtA9CkmHNC_RA*X?${GFzZ}`WV<%Ked3yhfjZz#nbEN?un9yW-JG)zTJ#-Vlps~ z8~Db)Q->hMCKVA;aHmDU!Anu&oG!fhjwe^6!8lL}Y=85h1ZT-VplT93{K#TNn2@@c zMIw=M0lR$#wVPuZio%!q$;k=GtXnb*0odGrJ_oYF>&-<&8|#;)9SCT|U$lt{pz?7wPnr7SVtM0e?$n@{~t<60_+9mgSNYDK|~ny6dIGO&;TN_126`x)z&VltzM( z9$2q1fgZA&R}vH2tMGAj^TXfzde&1o_EKtUGK#}wQ zp$sP+ZuSuY2{y2Q^Q>HiU|BOffezyQi~nH*LLNSl8}*p^G#2` z<=E=_;ekU_eV-`>%o|m`oUE4{DzA+xT10is%_I0i##|-vt%5V_4H35gcKzgIq37PmTl=YYJB$#j0t!>M*s;^i|2`wi})~yjrQIz zBjS{l|8C}YO>K@>I|rl`(%j>lTT?fBnX$~F2o6DX4;DxUm( zxs84Zn?QM;%5H@LFr}sdp;WR+1CWVS+D&wTc`SiW6@`|Twt%ISKpTDXf!)Ylrx5}S zQ5v?e8kymB)2Vn>CCe-q#R%G7R?@By!xAXaO+>U*!`xO zM84zu4|+oo)KYpE`<=kUp-a+9x7jouDU3#Lvqx912P{t~0cFb$G{eGp<+Z`2$7mjt z`op3|A0?xLD_qS51qEPHqM#VYh96wV#hKaKMnyKVQxp}Mv*D_R2p+c7LTaBEDSpB6##NH@7DC##ur)R-a+RC4%z# zK5>=Hk4s$~_Vp+b(gN%Tk!3Y?q8&<;UoM7KW#5PXa<{iBh?i%_KVlab&3W{}8+Y;_ z1&2oc_TYg{o-pmub)J%Au+lNQ6^|Rqv0N+zhlIr7ii_DEp!C_;Yqn*6mMxiH!u#|B z&XFWFa>2x;e1&BlyD?+BgSPOEMl`>=^=sJa1flk1PNgRLXv#PQTB=SJu%B~7F9TZ}Lzr3!k;d6;r zBhIlyF-S+137UoIrOD}&{O`=p7?35U_wVKSrsUKnMdM56o@(d&S#D;gPW9mT)>AQ} z_0>M86gmz$#*wq{Z1ec7a$h?$+;X?7iHxfv7Bp^CzpQ+;XHFv=W%W){WKoqB{bA5= z-W|wAX#N%6o%5tfO3YL**?7J?dRGG*e+HgIljcY(B=MM=yA`toUBNFdbKGV^@S7h@ zAwBW>3ZLRQi~L!A8wSxDO$Fx0qU@}k{VTcgLH5APs^Z9)7^{NZeMY5pbezTX{8U$U zuS}8jNf$;EO^b7S{)G0qeD}+J>}GD;5@$FYaJLKkj~se)b^P=1*Qw46&h!^V4jT4J zN(ZEfvx-?-N*~PhD<(>9Dzb0fHy4-Gp%+t$7ao!fUqN}6qI&~P2G7r@t1T$|DTL?4 zJ}6>hIyySD0Dn@|!JUj1mWUH=Jsnqbg=Dv6iP&@1*oV;|Ml8T|fDD_shxGS-FbP(g zq;TG1|54{hl5oE?x2nE;e5+4gVKTv)alxj^bhC1bb3H+Rv%Hy(&4;)%HG%$ik0N~J zP(zW!%V|quwOnBny5>V8;Sovj?0_PoRv@6|pp{s~&MP8s&Bjh}u zHHHJfC2)WcLLFESTWG~YD*DkO$Lgjk(^w2qZn5_(+Q+l|2*a$gTo0q*eYyw`L(*W; zs#S!j(DWVetfcFIS&DfMg?F_yH}GT&U`@55>z3|NiRqJTpnh=N{Yyy9Xnqg8+47Mk zJ;1Me^IOYBiKNjuE`&ev?ylcX9$taq-*cRH_(645W4A}TuqaTZYQYC%5*r4^lU#S7 zgX$d%hW+eEUliS`X}^}J^bc1-y<$;YRYwFXzS-8Ukc3918cNCd`@hnQ<@e`1rm~BRpX2?otF?Q$1n<*npOM*h z^S(SSMcVMv8Y!USS*9Y!f4$sj&-L5T^hsa})LK;RiyGAAKS)Cl7wWjqeNMlf@4n@> z*9m;LX@>rHn&fT~WV3~S&aOMfnBL5K6mC{9GOkcLh^6MkC+gGgQi(o^X>H`Vs;_DP zn;BKzn8>+8aL-SmX20Bh^=IM!ZtdKS_74!r`0tuUYl;=#L z8$o&Fc!49tIl%B6)##rjhANruf-+AR;lF_fvK5cG0_W6|nNqe`EY<3jYUrq`SWb|_ zNa#bqw?DCn@@LZLuHS}vL1s>C?bygqS`U!h^m2q_Dd{^p|j)@E5CdqHv6(~~2fAu;hp}HkWmOhYp?5BUlqi{@ZszJZmV30|vBn}WqQTHA`aQ0?OKjD3E)$L- zaqYB!*N1dD5!`)wQL5J&zfmFnP6JNh$B;l)AQ>OcEu;X8UdWt{E4*S{-T#~9`yMSt z8O7avkB<+=G_{;wrPSNwwxBk*}~6{>PG0wWSN$ z^-(OeT7$D7=BeD|dU=ZoOw<}&J{W^&gQ`PWwSh}TWu;A$qYM)(43a{Efu*IAHFV$N z;zQ(D_ov&-?Lj?f+h1vPX7~qSgl^}%WUy%bcK0str z*1GVu?qDmTm?r$FRLjU5P)oOik$`&?u_Y-~q5fDb{1boey*>??RV4Cfb7qbIiz1LN z>>C>kYiMAbn@a#hEr4@j>y?p)=KEg~bg?r3gatH!WD>EoJiIFX4)I?^r2F4T;B}hL z`e+7UjuYI*41cCHXZct7RkK?-ZOGLpHJ|-l<%n0z?TbMEBqyrid~25S>@`jgmZ{Rj z!O@2e3^)h_1D5PV1{87CqWQ>-IhE!dh^l)Ml6p~Wk)#Mse5Y~m{?)gKtg{RAvtDb{0Z>L~-a7T5SGS0^O%*QhPWOQ|iVp?W7YUW7}FTR^P%VMM7Q& zrhkn`Ce<*22vewofPRN(Nj*>eV)aS-Jahb3DhtUCaDp_kIrAq-;e+PR+)muoV33c+ zrj=S(XuI;+{G%AVN7I?4syBv|Rf{+h{7s&u(BvT273;5wR!{0)z6WK?p9JK~6iMFX z4Ag<84Y9IbdtUv*!%CGVJFW?TTOmRkKqUYW3Hpy-n|k?t-ux+x&yuC0nQ_ket7dFc z(nCE$_;Qu*LFo4lW+vb+4X6L$mG zv^E^7SQufcL(k(qe0a)Ow{t3bLS<+3Yb{TutjUSJE0mxsb2gh{Px_yMXJZLPA&Oni zQ*t3(=H*zS>d#tQgfsmD)VV`6EFrAYNHLm3jC9w~jvG#U1Nvu67s54Z_L+&$l6+k( z_YZO3K>DVie*o4OLD2l)Lhl^_LdQ`$CQqp#FIl zv>55ZE}6&0x}kln)jVS9!0}G=0q=1k=J^<2+I38WJx?)DjQ7C)LU!XUe5NJc{Z3 z4w-||@c4#irZ3YSku zOUobxvyK(#$-}(+{H;yX(s%6#B>rB$R9A+IbB~M`FGAR9gSZ|?OAi|~sR^{RxcH3* zR^Bk)mTTy-DcDP{59;Z1sdRjF5Nl;I*s1RDwH%9Fp%SHg#MNKXx%8zaeS8a%y%9J} zoP|o?DV4u87lmii5Zq_G4^`NM#(cOLkOmcSxoV|?>i1i^fv}1HbYe2zBN;h+drl9H zMfFV9vzX?roQtde+CvhD%w7Jz3x#0#M}t$%Hj}F4@ywJ)s58{YEK`fC8a-Egq}fbL zFs_GxOhHR=Q9MAB(XDw1laz zOWGXCB(>1MloAa(VKNj_jBtIO_z-9D^!L|k8)^eZLFm^;vlHTG(V&?{ITwLA46QFPRY6fgH=(hQ86urqX^lU z&U8>4HaacWn=|>E9lbw}sNx}1>js*mBP<==1T$xI&)nQ@;nrkrQ&VqW-)`g=kWd|3 zAJ0dk2&q+x5i1!;ArikzsF@j;J0&Y$rPiHRq*FO17;u<)R_!BET~p$B6oLL{>KW4m ztNND{P9Gs+5HtrwPeT@Fxa%MEy;fop)mY1wp9u+O*InHyN*`PN+4u2A=8uD1odx79 zKj8Zo2EZM|Iic+x9Vh5F=?CcP=oHFTfJA-(xb0n72wX|gAVYycDMgEwOu#>UaQ_(& zGzq)AyZWu4x6|=muW_*=ul{o6l1TrR2tt6;71sroU4CVw9w+_orD=NJ839wQ|-thj{CH{D&09z!F)I%B=fk6u=Zzybn_E&BtJ0%5z)Pt zNJC*jo8g2#*bj1JJubNRJ{S0xlY&TJAZ3Tys`XAHc{jH7uG9I2Xo^8#a_g#AV(hp1 zz_z><=GmtrZ>z+$%uA9}TX{wL7wr?ITA?u|>_lCL9f=K$w9m0l!JBY$E-3}Y5EEyf zSKGF?J##-j&9>T7QXRXuf#yS*N@Zfu)>o5Z_dA2cncU&Jm_$orI8#wZ(DG3VQ5*^? zfYH-qc>m1+T6xHU!JZDX(8Jx>_b3NmKaJ+l^bF(tAmY=$PUL%tA_>jVOwMc2OXt?Pc4(y(s^UuaiYfbG+ zBLw%3j$+UC!$uJepwud+r8H>KW8=Up3`p(Pa<*4#<(GS93nYsnqZrEs^#wnS=hwN0 z8vYd1@|+Fg9{iZe7)qk}TJPz5`)6KzgsPT_Evy@vG_vSr-dRU3kewlzesuFS$Sa`w z|7bN1b&LK-t3kE)lET7<6HsB5Pww{?|H_KKZHdaed7Zf*NJ@w85=icDsT>7EqMK@3 z;W1UQ_afFZ6Y>K)+oZgOs5W2aT-D_q(z%0+f?ELLyfyiQ9o589+G{h3+aF}EBnK7Z zW;rZ-MYoo9GQ)&XSDtcr2x5xUVVoo+FY?}Lk9RyFJ<=;m%vY9zRT>@?_;N7RF=?st z9+z7>l~X-?!nE{l_ot`F{i!nJ_h?v{Oer?MZiURlzI?;xVYr+8*l%d&_G{limYE5P zPb6Vvg+-W-5D6$1^9Cy{wYgOi(YL%~MEANczIDOKw^r5n%oTDsZs?hhaoe-B^{|c* z;+wsM@g&#?_+KuD9ls-m!i{y1Jkt#|uAvS00H3V%qlY zH$Q!(N;;98XZK%L;%RnKLhtnb07*0HL1y+7rdDg_B|MdZf33ZZA!H;AD2ARcb!%UZ zx~_556orJ2^hBZih`An(d9O`#c$kyak_nkzv88eLe_Hg2WcLPww=R!n+63PPHnZr@ z7l+@JTAxCF3YTJ%v8Rh1<4ZhABQzpgeBEh-nOMiYYVDxhnIDIEUsH`&oyj>`+Qwe? zTrklzLD1r!bt7y!!dW4IG+u5YiZ1qo#phYN*H+6QJ_R(KcBc_lJ{MBg#8ac{drsy} zi(f9<(|&^I)((2zIueSCbhXvQZRy_%RkS?BA?E$KGY*0!oP0@ise_%UqKCJ^M}c_s1}T%2rCx8yTpgIKF}6 z@FK4=-NF6imz>}J&W;}mJH#E{NHyMklqehkzE5R_26ax9YG=L%M5EgOfrc;RGP1Rl z_?z~CWv?_@iEXRGs^IVq;P4ovN>9YJ0prbRtDpeDq!91Vx^cL`iT(Qx$w{a?+3|S& z{mGjN)B)+*&LCzsgm}D&r6mi-p*$!;mpkE5OWobJb0l9NXola3`d_gQNfor&xvW}A zi^o%zfw?VJYnLe_xv9Y6X_m?RvzWk|x>_vWOBSaBggrgfkqSWGjw&3dMvhhbCaH zsc1Dse|1+sPHjB-w!7-%rQ^s5!Fx3r1I!h5&X}9$upRS+6$u-g8~6;kBEHh2;kkw( z!NUx>p#?88ST6$myJ5(b?t6UA;7r~KXi8p^3^P~n0%d}%6G(D;d}Jw5I)@XZ!qnbd11ik?)iDPmoz0TOI*r zJ~5WS6>G_$R!o~hy-4G(c9^Ojq**4YX8ldY%Om!gc!o$($WGN37z%Au@#%{|tIhh~ z)II*9BDYzNRtscgOiZ&M9tk+MKQYt4 zVtko$3}X|+S;3qPN!kzRSwXvYpqE<2ofi6*qJGs|2RSumOU z{zjKJ@f_Q#`>`_H1jfgYJ%U+z&%{epjdztr4p+gZGaoi+-Jt*RYY)LHVonAAcwTJQMxA$sDY%P1p^1imh!2F(vvo2RIB$u zYS!OGI;N24=9vN!VA@H7$of-uEZKAy=I{r+sV+kHa)X7k!V%qodVzA#frg!&qBe{7 zJ2)U*N?;wT;LP4zcUL%Vg=eJ=qdwiKx6Umj4bkOmXL`#rV8{ajgS=i0jMW&sv$eEb zFBKq0tcETk$gw^c64rkPo#4@VOQ(4aV7$zQetXUjtC0tsl*uAs7yP+YU6aT``M zKvGJsk0ltSq?H7k6%{#=Ms>_Fzp)@!1%ofx&aw>jTpF5I84zo1kay3p?AABHmCA|- ziH`vRl(mhGAfoS|Z&v^eiYsPniHL}3T$d64rjrdbh3F5xN6EcR@1E&(xAc=H(F%;a zu?7n$M?ptMdKvJENfr$i?02dD=UNciru-N{4O$P#zFtq1pEan|EBDj;m zb9;eg5UMlbZ-CbzC}|RR@0Sfp1usyJf6GHv;&M9`!>U&+Ke#=h)#-XCLCTR$WdVp8 zUk2SF11l?$m)k1qe{JmPY+)>GjaK0sDv;P*<3pJ|{xdjFqw|0`Ax2Sfv=&gZ#C*+| z4}6{EAi%?u1EPzMH^gs5D52&HCB#6!7n{W#I4UZ(&)0{1>;em5w?sJ2NY?{5p_{BTYwC%^7nug?pmu2Jeby3&-yjWbto#)~0&L`E?SP^SARO(mQ|vVsVSI z*lx7MGB$sQg(U?{KwwY^rutS3HN?PuTtb3isE+6%z+eN3 zj~4Sq4?H5e?4rLHd9ujy@wTnuMlUZDp0-A^Oe-x0l?asmhIHpzc-g`az>4N-^$(|u zR!CTV#6?pKrdsNGW29swR)Q4MF*tm*?l4#ZLXF z)YNnX6AKs;D-5?V6#kf0#S8jE4TgxZ1TZ=}pj~s& zYE90fiN|vDXX#j9Yg^!qcETt6|BjEmA|k!U=WUC3esX8ZNyy5=MLo*d(Fs`^SokFt zl5-2DCW(7`_TeI)K%b!LL5uu%XCtn8XrX|$lHuO<`srzSYbzVTFTu9=_eJ|5;j#GK z*??rUmNqpiCi=a-Xo0?o4LBADTZCyoA#+tSO7c%iA+q0L^ZYVc%eD9x4gzWvBCC}k z1sRtz&W*SR!_#JFHuST`-)vBt?Y9}s8(n`qn}OB~IQeEWLvq>6XZ(=TOqQ>0iXp-X z2U_2OxjE2EH3_XWf3ssVxpqIkFO07@cA>mDgke-)5#pU z@_0;Go98J6j>=_W+xBY!&G0xwX@dF(;Q z2D7n#I`|6=cfCxtd>fFiFzB}ZmqH_Kh|+fd0|_Sa5D-gI9g9*Wo`{NL{QUX3S}%#< z;o-Ql&hw@Py!hr@U3@@bxF7@P0bta- zP;WFmW%v;Vgc|~J{eh$sdVx3I&pW{j)%wxIB0)1i?xs%R$_ShkX#`MHqA_zvVvw-`w1;QELGI@^H=#8%Uc@I3pLt3 z{x$?C0{FZyYpsVT3dy&=0ZLW1Vqht1Q8K#*JV1wU`uN z0?fye1o!<)zstpopHF|pN8_&h?+-D8uoB<)*OFv!FK&7 zBfSSdOOnrXJ>{00{yknnSOFD6k{=>lEt;NMkF9y}ce|F(EZ+?O4SN=w9=p|z$VQfJ zRrEkb(}z7C-avLBt?f_czdngH%q+f2s*r9|dSlnfAhz12`2i|{5D470PNgRubRWOO zd7!j!B3^9N>SQDRNpCp5WP`;Dlp$iC*5FM^t=$s*)^6-L;0lu1rv z7P!%~au%8DP`wdYTH*rQ+6sSo2ywm+W}EwhkBwQGfXx`ukf@c|OA$PE_T=^n?}r=l z+q^rA&+<2%)MJZ?3Z3VizvD7Ip+t}H@0r>U-AC6AX(P_BSeP)#)521cl1!HV=D_gX zCi4Bi$j<(3}k&x=*qEiNQRhtIzX9C5*4s!tMi2KlP6?gT-^ko~qu=Th<1( za&w4_o7W$FT-*AkfHnJ{tf+1q_r;q}e?_cn&HPC)8JwxC-p~iUtVU_xY8m5+t@a=A ztQs#!M=)-t7i&(M@Q3-RkruQjoV>>wCw_^pH=;N7df)8h)?zLzA9H`PC6z?+i+$Yc zt=3e+yE+{%g#-ElPW^~O!&n5s<^v>(tByph;>b^5N*1C3lXEn?y*oD>()xotUmSJ= zL4D*-as`;L9?`loSAy}eiQ-fX9tz~mAD@s>l$=*!%3PCyWolZy|Os zhHR&aj>C!HhnrOaUi`c?>t8wJ+TBO6LK-PDFUR?h?tq6#HVNOYK&`yh=>$dK>)kOo zwawFuajw;fmQEJ-S~gG$-kniEbo!WyV7Rn~PC0gNM_}G43r}6=cBd)AJ-C7X0#RJZ=6dr$6}h1P%;4-g*GfbX}j^ zg14Sj^?Nwpx5?6gbN4l0f@~GAdsLyCBBA~|C|hhWpY0HYA-VYES9`}1oBW$SUs?b;b90`-=!ebz+!FP9ei!&26rl!1f>!7Z?sN18oASu#~bT^NHv~+iOhjfQ@H_{;8-Hm{BcXxMp zyvIB9&fJ+h_g|6W7w4SsK6|gVKGZZ*!wRX7(GuAX`qFQIn$KsSZTOmoCCo(?mPj~e z)|x&Ef;Sc0y55Z;tn^r4Ihm^KH8l^V$r;pT^yy^iC@MErz78bJECT&gfl~H$s)WfH zWbT$w!^xGY4n4tXdA4(bW6yghbmYq1p)(iPy%ROCZT^lf(#pIBd62O&aMh4vx{AM5I!P{H;vH?TIK7<_;V;aB<;$z|L{~GFKrlb| z6X9hP5d`X?2M@9whF|3?uAcbZXYeWQNWCUdr{_RNqP!9VjIQYjwY?K|wlnk|W3 zTWF%yMLyrx2vxcBGBQYnnDtn6;bECSGaF3Fgs+zK@2UpfqW@yDw`}6b|HgoYDBOGgx@B&_;E zcjd&Xfs5jw!N5+n%afq$RiGBN6--v>_P0rg*b0aw*OXNq->UC$lIrQtFJehcCX*oF5qsE z{a;!khH{PK+~Ihf}$q~d?I0KcP!{&PCiuRPNmgLvJ0W3$SgjW5!ZT72p2F%BLd zNc&MzxHHfu8b1(}bjTEz#Q4#T2|1@^5_HWv& zg=ZNUo!K$MkDFUjyj{zRX$)SS9wQ(1$P?cR2)jVL-w{rQLgq1OoJ}KX>#5rtt?sP zK1Kj@d#1Gxy9cU77$M>BdKLy@!$KmK!zDtf_!YW$r&=&8UTn_uGjEVcOB^{jzuzI^ z%O}PspCWP*6)c*3oo7<+UF*B8^qew|{5H@wvj&V@`~4{5i`!Ai^lu(00N5POC7UGx z?PEz{Z)!>jME1KNBte9&NGAO`j5%-H=0)?IztuT{;B`>8h`jlB@@DRzQj-TZ;t+usVcVXs}iXeOK!CU|3zL1@{*a&23;@3 zwe0zGdx~R!AL0&b_#6!LQ~B>!A3v~!5CWldBG_cWQO%r_KJR{ex--?z15GF3c-*7!z>d1cB^4LL?^B&U6TVQ;P$d>^2f=E1snK--;c}q68?}GNo z4g7OCgPBj$JETPbF%grQ^A#N@0s1A5V4>Usi-p<;XNc#Q3MP;HAJXaE10XKrLpo)t z1k!q6++DB>jzK8N{b|mc;3y=;w3kUqi9ey7Cql>f)J`8cQ^Y@;>LLhR`+1}uk z%cg!;Q=2 znZTU+r`Secb$0xhJkm)LRm$k&#hF(=FlkpkSZY%<`bGy&0}3j$&ak9YxIxL9BZv)Z zys$7BMCR&S^%1MJ#~;kMcn1XqweDTZZ`~ zo>rRdX^GF+dKUy3-k)#G@71^#b;7+b`ygyC{+g65nO=n7k+gerC})2wby`*$VAA$C z4RO^+<;AVGlp|wpTj}ykkQ=}LqVpOmDybwrc3aq4Z8WRJ zEbZEe1ke`wG~opzk9AD-$S?1+&4(QAIU4>JqKGkwOzO2SVChu0IFI{}@%-J~`|`M? z($C6`5bv6V^s7TH=H9!Uuk%N~S})aG)!MwFf*>%2y|KNa-5aa%tnJHe9A|gR36juyHrewBE#^`Z9133Fz?Hi5wpaEyWepe4Zev=aX>JmQ(T#@c?7yT z{f^X-Ft5cK{{1Bpeh#OJRLj#Zvt>F@b7$1UX;F0K=K()n8cSq3U5dirGW-bl;mtmU z3z(@^#k@$H{AY$a?+&mX)oU%qP8REc_e}gJN&pxMmy^HVf(TgE2W zze=z|5-)T@n5M;0{{?8?>0PaXmg4t8yet-j(hJqF0O;-$<8aoK`ODU9l0yjno9(j z1kSOP7=@%aKKcC-gebX6+bd(%l-9HOLrG!g*(OPe0%`m! z55kZ&=UQhQks6NYr^W}D&)f;0lGz$vuRaeCm;JD#)-bh#Yy1&u;>450UciCB)I8;Q zF1hQ7j#>xqW3gmdU&`OQI64xI=M(WOCvd3vO;7D6DFO~Ny~oBNH70sd3xtot;INUCbV(@a% z`r5wF(sdUVa#GpmGt{p1!o_Bsm}@jTZOK-3cBMlBHTiI*-@pv#GreX{`HK6+v9gQn z(NF?agqbg4Uli=t>?G>cI_dE(I&sYM_Tm}|Ofznlnc3ny{U947^%(?2R{1X<FZf#emQTXw*Z!2PWF5Hp4p$F z;z}rZjTlG8>PNk5CS{NfzBR&SPR$q%^Rqllp}y}OYs;x4RfH9lg>MnbT;Je+*DGU- ziLQHP!V<Gxu=UeLC_9B|C*+$J^Zq} z`($3aG8_z;16ySR3OX)M?j}S7$GV3!MO^JRZ8NY3cdF!>FIyXWE+~@NuZcb*)L#X- z3sWBq3@Le&=`8%|S~%jgxn)xL<(Oxr%sE%i7wL$vKFdy*D0DHW(~!id_nw}f4oJi) zn3=1mL-c!sQOUma=o=NUj)Y~1WRP<}+p|mwG{q|E!5w8Iea;_n}QrIP8WrsV9+ z|HDp@h9&R?Xfnj{8JU?kf#1HjJBJ5!Ce<~F2F4vf!*<|`9`!)dCUXZ(;1bH|tz#bR z9ERtnah>lgl?Sf4*SS_iURF3sDTEt|$j2-d@9tz&Lybwxps(~Sz8HrH$zPIn3_H&|C@M-Z# z8u&{(xD^&RFP;EkT1Fsn56oUBD|FuMRFsu`d@e&33S_44a-teNpV%p6GNwf{D8Rwm zD;Q~S$L9^!yMQ zw1@zz>{{?CCLOik)&hA^E@GEJ%s<^{d`;hUaRR2O2Dhvne@CjzSr1L4=>13B|3G3J z0m$c(Xs})x^fXff5k{RLP4WOVdPPJ;`~w4vzl=?R@B-QG+#))=W<~f-rNp@g;t;;k zK+efLcZx@ea+I_WY)(2~My!Z#-2X#!e0=U8^Y0?Br>5E+%N!d{UPUC}7LuiaMmNwogBxZj6y~ zHcoPup<>~;9Rhgo9bEq;doo1PiR+id{szs9G;Uj8&}&Xm9HLP&G>J=Zcqi6w8@QFI zAD~9Z=M!4xbfOMK6hLNZaJ4J-W%O!$YfDgM5g|eh`F9p)@LY7NZ$Q((WL2A)C0snN z?kz|J#@h}77$TDRskt<@%~~i>F;RT0QmSb*Jxq@@=KbARg%Xva(Ny8Pi-U!=zPI;X zT>L`@k6V1mPuvy@N_>!|x^q(`S|6?}`Apsg$(x&7yD^4=W8PU5FFCLs*R22*cNvNMbU1#EBbep>!RCq}hH!=^#dXMg9lhspGKi-{< z{g&a~XaRAvUk}MH?7Ms`VwLPs93!^5sVZ3Rq#&GUpw4>}O8;r}`VdW+cCX1DayRoN2 zet(op|0Er5-LJb~z4^S1+=?LxMqPoZ0o#aB_-eRqPWmT~rua(IG>< zOG@6avRs&K05AEc%(s_#UQag`y{?|>z4Y8f@&1ORCZclD1kA*RJM?X`6y3tcu8qvI z&v?d3Gbz+@|7|KF$)9s`xrLW(0yAKJ*qQZE5s@_M6^4|=Wm!w^SN2Zn3cSKKc|R^M ze&n!bRJ=zgnh$~q@{=@zUdF!1-~GQ8Mj8kT>g6#IlaOYvpYVh|-W&o1hJz9L!W&%u z6<{L`z%yJ@kj=xR2}AUX9Vv=Vs?S+BiSvjZSW30``IlR&TFl zMM$BAwB+N?aTmhKw;>o}nx`7p6U3vtza&L!>Hh0e$8P7rE>AGi@1qOQs@##Zhbl;L zI})Rd*akhEg{;^5FP2jj$J+lez-C;`O%-$ghvNrzotbGea?j=QbS^lXp(CnuWyi?N z>eF&}%49TX0umYhM^f2QG4Nj)vR$ZnMA=r`C^g3Y?`y(EkEL6Y=7T=`Q)a{7 z)D~`%)&uJm&d83))ne}38FS*VkGp-}6sitdf^X2xv+6@>)k(!4wrUQr12dL5+lsLV z)^2`}jP|nDxr)keTf^Kv`wcywBsag>|HPa2IhwO!bXw+IUS6IDGX)@h_{S&&kcCNk zG!Q5FOT0x~C4@+#Z?da(TK;E)*;LBE=7`&k3P`}qK91@VmpV9d@^|v%I2SFy8$_8O zJ08;^F#fMIvqd`6sF?;0GN0vPkG5K>ywYkK?U+}bjI!(tVT;Q4^=d~G`cm=*F0YAt zU$N*XBjALjuW{PscqV5P@GzvxoJY#DQe_>m(irD9!c8C)iQzP*f^Bub{3-mvB)ybW zx?y@LTHM#s6kF>$gXL9t^UhvTwT}`=1OS!_aQHd_GxXtpD{4laNxB98JtNDg(Xr}C z{`T$i0|8@F5jT3^Dp;y)&G=nK=wuI>sD~G55I=G>WHJ( zsrK-tetk|k2%h68Nji$x;Fb5pW$V1^W=g8V=et5^mweepXdfsZ={%r|wv3D2VNW#} zTKwgi?E%^2eZLu#NOr9x`op-t&at&3{|N>r!)Sk8Pv|?(-%&ud=s8Mw#Emx6)2E$K z%`S=JeGK;T@x=S;RJx48h<5&=*t`EaxvWsR0l9rkLte@-XfNJ+{*a2t!4Sr^Z{@$v zN75MR(@G;WJNv_k%wg5OV%BuVgc!$3CR?1rPaHe1Okcfmsl23<-lCv-x8b(FkM!SZ zR+s2&7N3ky1&&rS$6Xy1Y>DHU-Loqe$p@S)H5lmW@dK!$KP&e8c(^;0_%Su+7HI?i zJ`T8P+pJQ;{jmwWHoI}`G5BN-KL)~D*IwK%nw8qjFtDa)7%<1R;5NXXH@u z!Ki`7F2mljPi6RJ7m?}ao5>M1a`DiPu6anzg#GJcOTbz2;6Sq@@&PR27A^f!bN+A( zg=&Mt$2H9|fjI`{>f9J!O2jJWgsitYwf2`&;@(gbe<9_(QOYAb78An}Px#Q}m)^DE zlHPMaoKrP*xv5176uvJKOkfa8T_^l+3JfM5S2HR)8wUqsuHU;x6!3WCAEU0(&aT?; z>4T6u!u?RF!Ws8Z|#K z05n_Hx7At9JUO}1Uc-+R?@1A;)y&_glzvvhGELB*S;h)Pd~6h|hXb@HfD#=18;0rl z?Wp))hPTS0fbUYul*fv6z-0I34o=DE0(+=;>$2UkVB(FDOm=;J4RA0RAe%iOgs%9a zs{8mb`%j*8vi6ITwHqU-E4p5tVMsnsoRQ*Qzbdb=sH>^@a4Qf6ziIDh<)=HwENeeq z9|-bw@=B+15;vBAK#_%sAyg|B6RHVFSfXZPWA#mO@K-j{_)IUj2C6;Q5Qqh*?0)1Mh(J`Z|)dZC9UNl_ZudRcZT*=Z+{b~rvn!ifk zgyGqP6Hy#a0ja2rA%n+V1X)Jr@#d@#+){^@Su#L)!>^H4J^ko%rIX1;k91>^$%f{( zNCKV|FGA0r9%%q?pN}#TP!)j0uYUo_2{5zj$^>1B zCa2U&Vsab)rAI*u+N^C*CgeJ?vFP|pzx6{y-Fr6l2G@i|e_+)mN}w{4y{7YRCq#so zYu&q7XdV>QevP-2O_LTwfk0v_o3D0d0V(V-y0fKftUw>M+U8zz&719CK8$dg7nFq; z@DqRJXwYn8pJfuGcb+}UIBr|8{nKtf#5?t$9j}jJ#D1_fdRrn1P#vMRzZE)3a4d_z zr@s(kw6NT-Yu~yM{M(xZtk3zJ1|EI{twUl3r}=z-{bI$o^E6oWKm{h% zUe`23iI+$0;|^B57)^lyb@uZ<4sHwHgq5yV@OLeu(_*{&2)&0vD_phNL9J>oi0nPQ zW{odo;%n~f0Q$2RadaGo??XxOYQEA@+17SuPT`X-9i&Fv(>=ho#U{iA3(?Lj^3H}J z8akS*77N>rcPCK?hTy$SryJ9cvfA7BPW{bX+E|+$`kOpk*1L)68glcV3l8OX9gs{R zDilc5If1v0TIqM!d_v08aVuECu|zan<~H7UL((GMK^aX}e!uo-<>c$CqC`LN z<_8A{%hQmmlf%C!BBAy}!v9(#Ib+!OAyQk+_y@wb(;NqP{2!N}G7maBsqLsw4H(X| z<1-w=G^O?J^$7(N`A(F{h*`e;)p#W5Jm?@nD+N~ zZy=8MD8K`cgFxK~;mGorM-7;d1cPNyG9g|W??Rn1`#^fv7m5N0m_}gSW+4?cxKl8# zj7`y`|E{S1H{=sZcBaXXlZv3{N-xqmo98_H*j}J-aRo_rF}tJo?Iv~&ez{RC{V(^X z8NC5$<1RGXQ`$HwI!a7CZ!4kA?tr!0k%JmA#jNT>g& zp5XR9QBmSQ2^5H`5EAt|I~x1H-Z-qLor4Kp*T)Mb4zK~DJ&8J{oilk~l&EpC?xNJ; zjCYMi!^4B481SJrBXHPU9|kyR-V2eZ*KQt8Yr2wc zl}~IHL#N<<^GF#r7QVecmIh6JY##Nm^7f!rFuvSG6_{<9eju1$nxi@)*$XlqXVkM5 zrwWxvBLB9x=Sd@pCxrSg*zYpiU8|O_c}WhhB@?-EDS}iWi3mK12r(pRbHV`QJK3hD zCM;~R=~jes(*Jnljv7cWaM%LD@3o5{L2y_vZ?CSj46>s97yM5|XSKu*x;E;ERu?xn zdEmvRlfb4Y5JBi~*38!$sU-KWnj0I7^L2WajWA4sg$4K>fjy# zWFlDD*k;$S?Ck74z2>u~nt(1*U0tnMVJsgU>=h%e{40D$r;M19@jSiY`Etk%h}QCJ zu1aikL`pRpBK5k15<_SIba(rKz{-PobFqRia1a_62H+2A8&ZKP=H>laRgNctAW7Ci ztmr393VDvRBx*#xDZjGop(jhZBEq5WSl7zhSoI8}p@RLe?W@0Sq zZToH;z-(9&KolM^&_7;z=0e47uC5N))V^~Vw=T!u$Kse2W~0SS7?{hZHPVYePQbavTapr6#2? z+2?b7bvoS=(}byFU}ls4)Qe^?Qj)ZtB2xu0Dlu3kK182L^mPm`$>{w~zTQscS*X0f zJ!6>s@-P2cNI$oxnB1p8Ci7x|0#fZ@uRt#LU**ik_0CSgp?b|Bi3q|K$(Z~x9EYt~ zlwrkM2dlc?ujrj(R|HaQj%Diu!9%3r#S1Ud;kBMNgp4(VfvN!}Oj@vl>lIij{TXfU zj`@!(AU<)S-Sg|xbHh}Vgi5{T(!kcdgT8jFb&f2Bq1_0kol3vNcZAf0MM} zcwm`%z|Ie`8>`8i3B2-M$1FLJ3l?)3)_jpQxDn-qJAG^VMRTJtkmg$pTyd3KuCU(& zuT)wOol5~w^mqxRzVz!|ZV%kw-?!eblxw-~FV^8&%zE^_1iNH!vGC`%Uu)}oGP${> z5LN^1JR~G!#2N=3UERJpc?|EwMe=e~@Lmbq+GL#thtt`r!e%{)o~!nLd(|(f87Bw2 z>|dbLDY{X+M88PJ-P?E2IpF4}6eCHcile}AQ;C+OG!ei%SjJ{<;k;zM|FG*`9(%Z& zdbcmCGlb%$l!Ljm++@$?co;7|GeW@bubYyGahUri&OA3%o=G-G zktrb%>Ycbo&r)tc5@s@Y#L#wUjLyIRn$s7)1%~qG7Gu>$5^9yY{K=~9p!OD(kWk_h z`v=Ono+eAL`x?*V3lVJ+drcC0wdaQ*j5gyGbm?rN)0?72&WRxpzcW4)h^Qu;X=36l z*T?I4zWxVXD~0n81g1Y47{C({oP-LQiiwGNJme9AI`nU!GgpUBlc1#l{l&n7tS>8C zp5E`kNhW#BLZ`_ood&^Rp;pmRa(3dxN*d?$3oZVFQLTr`v8dc!vbu)7g&In5`sGi- z9H~@+c0^BKUr9LGsdVCI_gZr$kbFEX!;(dwX6fuC?F=;RgEDd@kY%RPBj#Is(U8u0WnRS>7(%6G>3ZoBL>fSM9>5zw6r7c^Jv2YdiB zf^l$G%xE|03xj565FnQVRm3~Us_@WXy`A3fl-Oe7(Waby^n~R3t2EP+h*Rb3pQe6VJQP0ivMT9wf8;7)8LbyzG7o5)FJEu&(*^j zjlJfJA%+e^@Dw&b5mZo60BkeqJL{FIhKBDlGJy#JOlXkn3Dd~R7^R{z5)2qrUGu8G zSy@?b17c(XDUb}YEV7h6++KJC0}2#eu9vLfZb?o>C3bYI45GI;pC7JpYyjMwV2L!@ zIiEURNwe_p%1Xpp`xAkQ$(}%FT&BNFMrvdRZF04LwHS&k87gLGV2MSEJSqIwuU~Hg zoIU8fd-_qk`OGmEi!p5&Cd2GLXxW$xMG>snTFiU^>3c%k@_)LL)Y(pgLn5gY+QBSH zh$N=)7m<+L_O^h49n6PoF>!Gc+GFR)OwIw&7ttXce0&6spWrS3!vNU? z!^3(q7aspV7sl5qnGm;(2vr&Xc3xE#Mo3|L(@toma>^{sI8kJw$5v7C?>x_W^}ygSG)&CyvZV%i zgcea37fuH4Pdw<>=MPt44rH31anQRcz;+20<{kivd{HrH<)dSuv;(Z z*4$8oQ?+}(%AhX)pZ$UId=^yI(0gNhU6GPu9j@^f$?yWY86Rf zVBmh(%{#8&e5DmZS*pmMke=b!e}iwX@E<;%Q)dQ$c;%DMiKYLZLL*48K=j=o zj>pcZ3FI+=yaiB@Vj~mskZ?aE$z*VE48&1TANd*dMgE)Vl!a%iwHm^M#Wx|k)H6T% zqlBZ3-Lt>2=gV=&cF!}t!a_x$dtQD%c)v3LuKO)_t*;(n+9z%^kmj;8js_>-tXG=Z z8;(5%F@3sF3v5fbhq50cyt9Fq3a6w)Q?;?F1rWb>8wlb$h=Tn6TQ8gewG70I`2Y(P z$ddpIRNvS*u&9WNoSYmB2j@4#XHv9~Xqr!evzIGRm7JWMTVQg2P>@;ea-k0*iNvI( z$(fj9K)W^KhF>1MyO0>=$YfAqzkh#=Y1uUm9g@f5_k35CeR_v@cOUUP4dFV9_wVZ! z?!=YC+EoPhR}exw3#zy=fMWx3&Yf#(IuujR2v8Ry_&*U@x+U{Hd6mk@E_M=i&`?lh zE$tY))3bke<40N>gB^%?CHMnR(X_uc-4ABb9&KM9JC zmMv3cdG`!j#icqOk-vWv)rpN7)01LHxA`D{ed`&)^PzoRp2WW^C1_3LRV*9huzGa( z%y9d6ZS9+koha?qHiQwa?5P%+o?h(G^jLmj0MYJf`VdeKOR&1`_y`-(Q2&x2c?5*d zbHI4CSSbk$4yL?epPyHxyI}`%FrgCCq(nNcUSBk{hb5G^qfc&8Zy~7_jZ{?qBu;nl z=#6kl2jwaR^E=+0z(Okux2F`WLh^-@t9&m}Rb8n&Xqac>Timk&k52xHrb8au?Og4c znB0(8p?Q~zENP}VcsnWxaV(7avr58`E%dK$_)6Y);e_9Qg4Axa85)blS}JfV=dB`{ zIUSsR&gAtJ0TSU_CpTf??^k;>CDe&_+lDa-8KS+om)}wvOShI^PZbA3Nq!7CPGbz- zGtUy^+G)#b%X*Oodw`Q{Lfp5bqeHw}9tnpv7}$(Hr&`+WP^hXdy$f1IVztBSJcRA2 z$#=!aGyf`EP){o8Ju9iJ+EQ<&WUi=$0j5!T7}N=tMNYXg_b+#Ab?Tw29bP<{UjIqw z&Bdd37a{W`xj(IS7-^;ihk06=&)JL=wgEKka;d|$;Z6|VAO-(+3{*8Mz}kolq5XT5 zfyw(9c{Oax|0L;cAw?)uM@cBlhy@*MWEDzHFj(Lrm zVsjLLoSuCYave%!P{FYsf&d1r1ws@)WfAJf>}rfJ;Gu{kmJLQtlBw)vJx!)|LMF*; zmBf*eksjlwSS2J3)vLk}O<6fCf{}$fzCaSZ{rd7|wqqeKH4`ajW^P`Laq`bx?|9T+ zF{1#Is+YLku0@T6@`Etw3J5j_U$Fk+<6Gq7 z%dgel?2Jh=q}mqff>>X-r}xTh_Z!m@m}h8B9=6w~8@-Z?j)+kFVMM!ndi(*>aBR-XrwWY0=rl_XxbAIyUO%m6f{Q zJ)P1D9wcv-^5>s%3I=7F${^Yg3kxegX}HwsbhqG_d!vIf1umwP?r)8cc9}F`qyu7` zuQynVM#O_EG+b=vK1KWwKa4QovV+MkbfANPxV|f%DzoVL7ni@i+s3bkUmPz_>(1t+ z!9a(5F*Wwh;)G`6Gb9_IdWzG|Qj_;tyR>A8l5 zlIV)Vij7%yxP*&RiCob8aj2?!(HcyZHWGEDkNi`pG^lrgsD(Z`-h5BgVC%d8vDV1u1>r=FwfAS0jIP4Z z#TEr^Z9It#T3tmkq~wpFvj`;z75i_eJ+VgXQ2EKSPg_LU{CXs`2WkXbt$Ild9YLV> zgM){kNx21z;KZy;ORTRQxg{f?y2a(r4m@?>8zTRYIt)VW>a{cpqoC~i+x^YDX8&$x+RJ0S@QKT?D?^7NMfy3_HMlIXTDWzqxt+#rw4{Y{_p>- z@`|7g%7>NZx5PAe2AU_(OuBX2H+wOKkqeuSfeQ{6qppv#bCYA9cv7l{sZy$ZY#qah zuOhXQ#w#rc&`w9k)__vRsMm(dr!Gls!{z)YMApjBG4^dM~{l~`h14+!k zmjQ8n8$fLFH3^6B%kn-E*I;kzSxm=7=-J&nxdP;?_t6)@3f(O%ub4YfpOqLzKI01u z5HEq!K?HarYTGBZ5a>Qc(?k<7GuKN0h57-89d(7t)Duy}ei1Iu1?Cm*Pfnc31l*Kt zGf5pC-=+#Ywdq4&;GnYfVj0oC03WoZs;X%gW>^FC1B9UnZ1r3@&x#M82?vhWx5226 zzw#C7A7Q3@YwXGO`rfL#^9f7z6&mZt!nN%0&THW&{pv9w-O$yWn#|Ha(2@#%ouUI1 z*LYM?kwQ&3#?=49_yg;(oY_+L_n{{3S;RsCqwVc%-qifl)gyQ&^ttEn@>Kfz`8~Ms zc@Ia}LxII1z{AKAt8Za-JL}V|a#2o{X(+&jzA3sl8ols0rr?hXqhuKE@Dz9Mqx6bF*30$AF!3Q zHTbr%WNge0BYoBQs(GS(zO+SmU8m$#UsKmzzBemiBe@C%?qxV(>kSPJdy{!#jm@>4 zLf?dmV1E)#Bf8@BPpa1JmN+9{Izv75i;)~VKuNXKXSoM~<^mt{&$LSGAon9>&KKKK zqDgg`v6xjqbvY_;6?eMmPIKu`20_veHim||vvpL05=xQ~#93L?3Jbx} zL^hwgGrV|Ii$oX}ul5*zS1>5I6jQB5%rvPPAc_h3@S&veTYtb9-X2ckJ^99y_5pWW z!OEG^yW!TTbiv41fjB`HNz1A~8v4f7iM)}hvblIUF6&#Vfvd`niQpK)wUF#<)6QH+!wYwCclY#MnY6UDx*Y$h4pdBe+eBS4t+2U2X+|7* z%{m_|lT5sKBI(}5f)}EDX6rNk;{qv3gX5oEs5|vm7xITr3|uCwfFp{ z>ao%K#_)sgVmy~0gQ z2?t45%wKzzZqwq{trBiYY%TqptpsRfY?ehtt}pH(d2|V6he`})ISAHnfw%b{k>MU) zu!Ni?+v;kXMiP7K&;uk^7K;pE-G@pgisk0j;F|?~ zDA(ToJzv}sK9sy*?k&d}@|!i&L`unM8Jw(AYm)52!c=H zIR)Hf%ag(xOQ)xRQw*okau7zYAgJ17eai-e*xP$0p>H}Tbw zM=)}T1BO7Q2t1VBBjcw$KiY^oS0{L@36-%7mV*ATtP)pMrH`&`28VN9S0xJf;cR`I zgCr?)j=zuQVl*`sgL)lp*hG+s_N2uOOVCDWT&+WC% zNa;>dZmp`oe#8&2bVUS}%%x{rD@=r=o#NUy;JNQv?vl6Au~EXsEwfrWS=yMcP?4c1 zkkZt|3qr!DSH_9-XhrmLkId5k{2t18T)ICmX}@56x`;nZOK&Csl;4Gt9Tv7msHakR z2bY3mn3x>7t}HVWD2rG`chtF)mSqHPs8KTtp{$9t)z#B2`__Pl1m+i?AGpDkoBs9n zs{(mMz%dqo9vO#-^P^p$;vTaJkAezXIFtLRPR(m zH?0)PnsWA#8^f_Tz5Kc}6!r_qL+3y^U6Iw>im;f$S;sHZ!N zc(Pva|JsEn{od6T*)00R>{-`%$r{P4({4nmgim{~sI-NOX?&c1U~H%yKiqHvjj0q? zv+SCwf4=|a4)3>gG7}pc89;w0ZG$02{X#rDgfWZrlgQzd9Ti#|nK~y283~C1>7)>7 zk_1!!5wNhTjpiBqHF0@u;!j4hd&S2zR#~kUaP`QZsbFSN zc%q3|>G0MmC>X-j@%RJg0k2oiKrssl7D8ddWG{O8(k%)}EeRnD8xC(zk3F?~j`2<1aDl1X8lklFDwK8z!G zyFDIAZ*i7z_y`T`|C|WbB^ERZ^Mu1cOtx?A@0ArH`3>VGeMK9YV#wL+8LqGw7B{9@ z;QR_`&Rup|QW9XFX($cYUw*p;J&?8zUwr=JtH7_1TXP@Eo12HnTEcOo2ZNhRI@Z__?b` zDIS!DXFQrFJx8yV^wlO~FuVr9z4JkquDOMK&!$_gT(_f^rsjOBYmIoh5iOHQc3=$M z>|DeF+C`y@SUjyMpJyM`see}dXQQm+YxBV>?mq{A-I+829F@lwV&l2>4e8spUAI4@ zVwr~qK)L?wAAxa^TsN$I_pGQYClq|PhZuVPV^Qt%Zzf=kjuX!f0Vqp5u+7ttBd@PF zjU+ILvqlSwUV+1q2RE^Q$^wl!HmZk`rr;PIJRL=PDar!$4(IDPJNBSsP8@_ZNi ziCV4mSd9gqMo(E9EVhU|S>-SPdLF_|klR3xyHTSKUO=-G&xO|yzmHPd#g^vtk$f1{ zA?&kxUg$tg(+j37VKa%CDr|q6wmwLIEA=<%sNj0&_)*`%PgJJu{BiAuCu;4#nfetl z@9ykmp}k8NhP{Kq!hx#?iy6x7eTX)5y%HU#$GvWqc&eMLYZVw?kfdL+`x!>0EHyfN zS@O#z9ZDM8JJEh?mzQrWzWYc&ru?cy`2De><&WRK5Zb0SI_p{<5#2+}?-Ou5p!w4i z(a<39@W@r=R=G);qdV_G;I=3A1Z$6&?%w#XZo#(Q($oA`q5Bl#miA_haCt)YK41BT{kK zAGaXjb4Gvvkd=W@liBKW@^p`KCV-(#jR5s-&<#O2L8J`3yV@Rhfnyj39gLMNc`Lu{ z4B#_g!S%GSu_IZR{K;CyPj*&gv%0yt*}2S<@Zh!O1bPY*GiehI=NLx=&1FfPm zWDjRQybd4aM+{fol=wIDs>}7|i<3jOL$A5kSelmjC;POvy*yZDwgli!TQMrk<^~{& zvFJAY2)}P?=Rsb{?9BvlvZpkEiN+BSpkHV6AWERKuc}2soOsU$6zvEU~#6$S1AlHvTdCzm^TB6V3Kz3FtV;UYE6v{UQhMS)7bGC+n-1G`|F6x-&*>RDu{4S5DbMSPL!F9 zii+xcul6oLw-4Bu8;2yYr+PCEXPp#F4*7E0*X-!es3Lz4gsF<$E~-_fn^^i)itj`Z7*pRm9Gqrxl`i_@2qiuM-#2po1Y+S2=X zb|hremNn5@&h?jKx;kzZ;Y84=$qk>G8}Gj0Kre4>zgICY?3_)GO)HI6F&9Su^({6w zIe8$Cw49sU_Lqq{)_+;lw8F(7w$TNJgrHaoBJ)BM-t+Jfqk%5RyDx#N<+Qeo%T1ud zKm~nb0~?#DmKOJ_>$?CZ(R|eYC}jed#)j;F(tM%b72qwHZKuQk&ls)#Y;Df+@qqZ& z4VuNMU-=YM|For^+RG;m4xWC>ud#L{qalLS~=OBMa9Ww@-=QYAr(% zR91HLv{;&MyB{$~4pc1N_Bq=8QP&t+T>Z&REJg+~Q;Gm~QdKe{fD3%A5D6ve!{NEn z=ws{rnUz2UU=5IbrNT#AFk-T^y-2O=q7`32Exr2zn=fKTMa=4~TXzcq&+W^VKNjrb z19Vl*9u;|A`p6&50E_Qp$H*V58?hKe>qlT1-x@ef)JJ}0=o)3_*J3x7^el)@)z&6W zcoUOsGSQ`QFgWT1@bYj{IqjR;AIWzgnivzIeNlc(XET!hye-3JF}W?BBMa@?)Pfm! zhQ9yv2Tt9ge|=GJ$9VwCu38*dU30bfO}j}u;g35PZwWkGx^c~2WOd<-@Y>;-<#!P` zc)zji?uRv+L{ZXs#~ZEWt2>$%VKnD%1BvAmY>?B)q3G42`d^;tRfyhh_(624PjZ&* zs{;7Sa40^I%8_jMT*+l-2$P34V3Q$C6Bo4T5g&%zWYk6r5Dgt+%ezi)%}tXqxoa_@ zV;iW|sPoIYtE@Fx%$AjwR#w(dCZCQ{{tTT)_!R~L0hcZ&#IGoZOrtK%)06NtXy_R; z=Ty0lk)FsK=~CWQ7*0AM<6rQ;B_v-Wrd=9wAPFbeSF-S&9ISZY%R|_*><=l>S=0U- zODPW7j7F3g1s-G)C`ve`dVTA-!{){kY#OkOE(KFocgBIcBYd8FS&~&(dpURUA?LG- z>b)KqxzmqF6&kFjvN{Gm>pb@V^-o>~6Kf@uWgBV$87&?N-bqS-t6mtC}!z8c*2X?bAFz^o(9rWzyu6+{<>?HF)@a1C zWEqFt$@?ckZ4z0T=Q`Pexk82M`pYq}X=9bPr7*=y*^x>fl+MpDFCoFfx~FMs z(Q(05oN7e>9;o{`a-u!Ss>y@4_Ex=BIp5(B5a<$c7Hqm|Oaks+z2}gY{~s}hHvj)L zcJ=X0=W%?~%#iXh4@;g$899ee3wN50F@)$;E~}WLbfgO%MkWi9RUYzK%RCef=b^}R zH>IX@r~lyPK^A**?;3+=Ci~C-WJYcXjtrgu|XXpm1uMvspqhy6F6aqjnur*OekJ=1ND`7^ZLO3=Yw zzX}8VMvs5g*Lxj->#j2ujwSmOHcS$Y@teGflnJ5j>&QGejNPTnaoB8qLQ~=juQ7REUDiYX(%LL%u^)dTAHIJ&?*K{JGiLzf;(H>{7e-8 zQt_fPgTdO0hhWPS<~&T~f}V@(6^Z}U9le?0)xr8dE+HRV0r_ymKJyR7&y?3h1a=r^ zg*`bDkbAHDXC#TVTUMRSm)xuC-UaQs1_lOxxtzgm>)W4u zs&I2GJXN-&K!cfP6>01F%z|W_(Ux5`lC@6Jf#T0fG#ahGLAkCvZg`cWL4T3>T9iW3 z_`<;5wvYOy9^5z{N-n#yBE!bkHs~GcN~cSvstjp8q}=2Je$asibwh-z zdHu!Im{W3p@w2S)PPA0d@@y6>lx>;;6IfsHhBMaO^gv7cw6!5n>`2p<<#u zxfB+&%WryKGsnbQpfov5lDk$#ng<0#B(^jiybZ6VwQcirSk-c8Vr* zEn+Asf^{eaoGBuj`*`e(;^TgulroY!PymQOI4rWI{I@wKm$Qx^@h)*Z&F7mZ%}22s z8>fzWXhXUl2vW)REORIRpG_M|u@It2`Sb>mBU+y`cPh}ust@5T$Xn+Oqeh{zvdAy< z6SK&((7wv6X`r%GkN|?oM44C{9D#S6WL8#&ZJra1_~&gdRfUEUDsVOK?%pKJ?ey@2 zhzFZIRVH6zQ>7z-2B`YH2|?oj>X+TqB zZ}|8e&`51>Z@=AsUC9M4LrbiR9foe-Rbfh{o|#jjFr{VTg)K!EEnFo)6`594ZJCLs zo5!8iYy1v_U)&M#vN?!$hJT?8oo)#Hg=6A;;9GYW4RzRS0@A4Q@UxPpLr)0f#ph22 zooBTcL?w?1FsNNAfF+~Os&ro)_-3Pd)}?StLT5ViOZh1t70c2artWyXy;lwRkaLuly=2q}bI2qP*6bROdM52j_7k8}R3Iu{- zDO$Fe^yx-73b~m`^yTmE8@>rXRay{81ayv1&GrpasdV?8lZlf`tEIvUC!FgobyGzV zEdX+vV8midFerr63Xzi9Kp_OLt*;6PTea7w{Y|7fT_O|6_CHV&@`K$!Op1(d{Xr2w2=H-sD;mJ>?&?^IcQ` literal 0 HcmV?d00001 diff --git a/screenshot2.png b/screenshot2.png new file mode 100644 index 0000000000000000000000000000000000000000..988de75f817b1b917520f01b56f48d9bfb653ddd GIT binary patch literal 73744 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 Box { Box::new(self.name.clone()) } } + +impl NameDataTrait for BaguaRawData { + fn name(&self) -> Box { + Box::new(self.name.clone()) + } +} + +lazy_static! { + /// A static vector with 9 items, each represents 卦 (Gua) of 八卦 (Ba-Gua), + /// or what known as "Eight Trigrams". Each stores associated attributes + /// for the 卦 (Gua), and are in the order of Ba-Gua Numbers. For instance, + /// 坎 (Kan) is the first in Ba-Gua, so it comes first in the vector. + /// However, be careful when you refer to each 卦 (Gua) as the program + /// refers 卦 (Gua) not by Ba-Gua Numbers, but by vector indexes. + /// For 坎 (Kan), for instance, while it has the Ba-Gua Number of 1, + /// it is referred as 0 because that is the index is for 坎 (Kan). + /// + /// [0] 坎 (1 = Kan) + /// [1] 坤 (2 = Kun) + /// [2] 震 (3 = Zhen) + /// [3] 巽 (4 = Xun) + /// [4] 中 (5 = Zhong) + /// [5] 乾 (6 = Qian) + /// [6] 兌 (7 = Dui) + /// [7] 艮 (8 = Gen) + /// [8] 離 (9 = Li) + /// + /// For attributes details stored in the vector is found in JSON file: + /// `src/json/bagua.json` + pub static ref BAGUA: Vec = { + let json = &include_str!("../json/bagua.json"); + let data: Vec = get_json::(json); + data.iter().map(|item| { + let item = item.clone(); + Bagua { + num: item.num, + name: item.language_from_data(), + direction: item.direction, + element: item.element, + } + }).collect() + }; + + /// Another static vector for 八卦 (Ba-Gua) (and is `Vec`). + /// However, this time, it has only 8 items because this is used + /// for compass rotation. When using a compass, only 8 directions matter, + /// and the middle does not mean anything. When 八卦 (Ba-Gua) are + /// placed in 洛書 (Lo-Shu) order, 中 (Zhong) comes in the middle. + /// So, 中 (Zhong) is missing for this vector. For 八卦 (Ba-Gua), + /// it begins with 坎 (Kan) which resides in the north + /// when they are placed in Lo-Shu order. Moving clockwise, + /// what you see next in the north-east, is 艮 (Gen). + /// Then, comes 震 (3 = Zhen) which is in the east, and, so on. + /// Note that it is `Vec`, and not `Vec`. + /// + /// [0] 坎 (1 = Kan) + /// [1] 艮 (8 = Gen) + /// [2] 震 (3 = Zhen) + /// [3] 巽 (4 = Xun) + /// [4] 離 (9 = Li) + /// [5] 坤 (2 = Kun) + /// [6] 兌 (7 = Dui) + /// [7] 乾 (6 = Qian) + pub static ref BAGUA_START_NORTH_INDEXES: Vec = vec![0, 7, 2, 3, 8, 1, 6, 5]; + + /// The order is the same as `BAGUA_START_NORTH_INDEXES`, + /// however, it is not `Vec` but `Vec` for this time. + pub static ref BAGUA_START_NORTH: Vec = make_sort( + BAGUA_START_NORTH_INDEXES.to_vec() + )( + BAGUA.to_vec() + ); +} + +/// A getter for `BAGUA_START_NORTH`. +/// +/// Example: +/// ```rust +/// use mikaboshi::bagua::{get_bagua_start_north, Bagua}; +/// use wasm_bindgen::prelude::*; +/// +/// #[wasm_bindgen] +/// pub fn xx(index: usize) -> JsValue { +/// let bagua: Option<&Bagua> = get_bagua_start_north(index); +/// JsValue::from_serde(&bagua).unwrap() +/// } +/// ``` +pub fn get_bagua_start_north(index: usize) -> Option<&'static Bagua> { + match BAGUA_START_NORTH.get(index) { + Some(bagua) => Some(bagua), + None => None, + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_constant_bagua() { + assert_eq!(BAGUA[0].num, 1); + } + + // TODO: BAGUA_START_NORTH_INDEXES + // TODO: BAGUA_START_NORTH + // TODO: get_get_bagua_start_north +} diff --git a/src/compass.rs b/src/compass.rs new file mode 100644 index 0000000..afc1aea --- /dev/null +++ b/src/compass.rs @@ -0,0 +1,486 @@ +//! A module for compass directions. When dividing 360 degrees into 8, +//! we get 45 degrees. Ancient Chinese further divided them each into 3 +//! (called "sectors"), each having 15 degrees. Meaning, there are +//! 24 sectors as a total. This is called, 二十四山向 (Er-Shi-Si Shan-Xiang). +//! Not only for 8 directions, but these 24 directions (sectors) +//! are used in Feng-Shui, and this is the module for these directions. +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +use crate::bagua::{Bagua, BAGUA}; +use crate::ganzhi::{Branch, Stem, BRANCHES, STEMS}; + +/// 二十四山向 (Er-Shi-Si Shan-Xiang) can be +/// either 卦 (Gua), 干 (Gan), or 支 (Zhi). +pub enum TwentyFourType<'a> { + Bagua(&'a Bagua), + Stem(&'a Stem), + Branch(&'a Branch), +} + +/// A struct representing compass direction. +/// For each direction, there are 3 sectors. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct Direction { + pub direction: String, + pub sector: usize, +} + +impl Direction { + pub fn new(direction: &str, sector: usize) -> Direction { + Direction { + direction: direction.to_string(), + sector, + } + } +} + +/// An array for 8 directions. +pub const DIRECTIONS: [&str; 8] = ["n", "ne", "e", "se", "s", "sw", "w", "nw"]; + +lazy_static! { + /// A hash map with 9 items. + /// Say, we have 9 boxes displayed on a device screen. + /// Except for the box in the middle, we have 8 boxes + /// around the middle to represent 8 compass directions. + /// When facing "n" (north), for the first row, + /// we have "nw", "n", and "ne". For the second row, + /// we have "w", "", and "e" (where "" being the middle box). + /// For the last, we have "sw", "s", and "se". + /// + /// [0] nw [1] n [2] ne + /// [3] w [4] [5] e + /// [6] sw [7] s [8] se + /// + /// Now, consider when the device rotates. + /// Depending on which direction the device is facing, + /// we have different labels. For all 8 directions, + /// this HashMap provides a map for the positions. + pub static ref DIRECTION_POSITIONS_IN_CHART: HashMap<&'static str, [&'static str; 9]> = [ + ("n", ["nw", "n", "ne", "w", "", "e", "sw", "s", "se"]), + ("ne", ["n", "ne", "e", "nw", "", "se", "w", "sw", "s"]), + ("e", ["ne", "e", "se", "n", "", "s", "nw", "w", "sw"]), + ("se", ["e", "se", "s", "ne", "", "sw", "n", "nw", "w"]), + ("s", ["se", "s", "sw", "e", "", "w", "ne", "n", "nw"]), + ("sw", ["s", "sw", "w", "se", "", "nw", "e", "ne", "n"]), + ("w", ["sw", "w", "nw", "s", "", "n", "se", "e", "ne"]), + ("nw", ["w", "nw", "n", "sw", "", "ne", "s", "se", "e"]), + ].iter().cloned().collect(); +} + +/// An getter for `DIRECTION_POSITIONS_IN_CHART`. +/// +/// Example: +/// ```rust +/// use mikaboshi::compass::get_direction_positions_in_chart; +/// use wasm_bindgen::prelude::*; +/// +/// #[wasm_bindgen] +/// pub fn xx(direction: &str) -> JsValue { +/// JsValue::from( +/// (match get_direction_positions_in_chart(direction) { +/// Some(positions) => positions.to_vec(), +/// _ => Vec::new(), +/// }) +/// .into_iter() +/// .map(JsValue::from) +/// .collect::(), +/// ) +/// } +/// ``` +pub fn get_direction_positions_in_chart(direction: &str) -> Option<&[&str; 9]> { + DIRECTION_POSITIONS_IN_CHART.get(direction) +} + +lazy_static! { + /// A hash map for the opposite direction. + pub static ref OPPOSITE_DIRECTION: HashMap<&'static str, &'static str> = [ + ("n", "s"), + ("ne", "sw"), + ("e", "w"), + ("se", "nw"), + ("s", "n"), + ("sw", "ne"), + ("w", "e"), + ("nw", "se"), + ] + .iter() + .cloned() + .collect(); +} + +/// A getter for `OPPOSITE_DIRECTION`. +/// +/// Example: +/// ```rust +/// use mikaboshi::compass::get_opposite_direction; +/// use wasm_bindgen::prelude::*; +/// +/// #[wasm_bindgen] +/// pub fn xx(direction: &str) -> JsValue { +/// JsValue::from(get_opposite_direction(direction)) +/// } +/// ``` +pub fn get_opposite_direction(dir: &str) -> &str { + if !OPPOSITE_DIRECTION.contains_key(dir) { + panic!("Invalid direction: {}", dir); + } + OPPOSITE_DIRECTION[dir] +} + +/// An array with 24 items. Imagine having a circlar disc displayed +/// on a device screen. When dividing 360 by 8 directions, we get +/// 45 degrees for each. When each direction is further divided +/// into 3, then each is called a "sector", and it has 15 degrees +/// for each "sector". Sectors are placed in clockwise order +/// (left to right) for each direction, so that you see +/// the sector 1 being placed on your very left. Then, you see +/// the sector 2 in the middle, and the sector 3 on your right. +/// Imagine the device pointing north. On the circular disc, +/// what you see at the very top is the sector 2 of "N" (north), +/// denoted as "N2". On your left, you see "N1". +/// On your right, "N3". +/// +/// When we want to express all the 24 sectors, we want +/// an array with 24 items. For the first item in the array [0], +/// it is convenient to have "N2". Then, for the second item +/// in the array [1], we want "N3". For [2], we want "NE1". +/// For [3], we want "NE2". And, so on. As you can imagine, +/// "N1" comes to the very last in the array, or [23]. +pub const TWENTYFOUR_SECTORS: [u8; 24] = [ + 2, // 0: n + 3, // 1: n + 1, // 2: ne + 2, // 3: ne + 3, // 4: ne + 1, // 5: e + 2, // 6: e + 3, // 7: e + 1, // 8: se + 2, // 9: se + 3, // 10: se + 1, // 11: s + 2, // 12: s + 3, // 13: s + 1, // 14: sw + 2, // 15: sw + 3, // 16: sw + 1, // 17: w + 2, // 18: w + 3, // 19: w + 1, // 20: nw + 2, // 21: nw + 3, // 22: nw + 1, // 23: n +]; + +lazy_static! { + /// An array with 24 items, for each represents + /// each in 二十四山向 (Er-Shi-Si Shan-Xiang). + /// Note, the array begins with "N2" + /// (and "N1" is stored at the very last, or [23]). + /// Ex. + /// 0: Direction { direction: "n", sector: 2 } + /// 1: Direction { direction: "n", sector: 3 } + /// 2: Direction { direction: "ne", sector: 1 } + /// 3: Direction { direction: "ne", sector: 2 } + pub static ref TWENTYFOUR_INDEX_TO_DIRECTIONS: Vec = { + let mut vec: Vec = DIRECTIONS + .iter() + .fold(Vec::new(), |mut acc: Vec, &direction: &&str| { + acc.append( + &mut (1..4).map(|sector: usize| { + Direction { + direction: direction.to_string(), + sector, + } + }).collect() + ); + acc + }); + vec.rotate_left(1); + vec + }; +} + +/// A getter for `TWENTYFOUR_INDEX_TO_DIRECTIONS` +/// +/// Example: +/// ```rust +/// use mikaboshi::compass::{get_twentyfour_direction_from_index, Direction}; +/// use wasm_bindgen::prelude::*; +/// +/// #[wasm_bindgen] +/// pub fn xx(index: usize) -> JsValue { +/// let dir: &Direction = get_twentyfour_direction_from_index(index); +/// JsValue::from_serde(dir).unwrap() +/// } +/// ``` +pub fn get_twentyfour_direction_from_index(index: usize) -> &'static Direction { + &TWENTYFOUR_INDEX_TO_DIRECTIONS[index] +} + +lazy_static! { + /// A HashMap mapping direction (combination of "direction" and "sector") + /// to the corresponding index. + /// + /// n2: 0 + /// n3: 1 + /// ne1: 2 + /// ne2: 3 + /// ... + /// ... + pub static ref TWENTYFOUR_DIRECTIONS_TO_INDEX: HashMap = TWENTYFOUR_INDEX_TO_DIRECTIONS + .iter() + .enumerate() + .map(|(i, dir)| { + let key = format!("{}{}", dir.direction, dir.sector); + (key, i) + }) + .collect(); +} + +/// An array with 24 items, each being a tuple. For each tuple, +/// the first represents the type of 二十四山向 (Er-Shi-Si Shan-Xiang), +/// and the second is the index of the type. +/// The type being: [0] BAGUA, [1] STEM, or [2] BRANCH. +pub const TWENTYFOUR_ORDER_START_NORTH: [(usize, usize); 24] = [ + (2, 0), // 0: [0] 子 + (1, 9), // 1: [9] 癸 + (2, 1), // 2: [1] 丑 + (0, 7), // 3: [7] 艮 + (2, 2), // 4: [2] 寅 + (1, 0), // 5: [0] 甲 + (2, 3), // 6: [3] 卯 + (1, 1), // 7: [1] 乙 + (2, 4), // 8: [4] 辰 + (0, 3), // 9: [3] 巽 + (2, 5), // 10: [5] 巳 + (1, 2), // 11: [2] 丙 + (2, 6), // 12: [6] 午 + (1, 3), // 13: [3] 丁 + (2, 7), // 14: [7] 未 + (0, 1), // 15: [1] 坤 + (2, 8), // 16: [8] 申 + (1, 6), // 17: [6] 庚 + (2, 9), // 18: [9] 酉 + (1, 7), // 19: [7] 辛 + (2, 10), // 20: [10] 戌 + (0, 5), // 21: [5] 乾 + (2, 11), // 22: [11] 亥 + (1, 8), // 23: [8] 壬 +]; + +/// From index, simply returns the corresponding `TwentyFourType`. +/// +/// Example: +/// ```rust +/// use mikaboshi::compass::{get_twentyfour_data_from_index, TwentyFourType}; +/// use wasm_bindgen::prelude::*; +/// +/// #[wasm_bindgen] +/// pub fn xx(index: usize) -> JsValue { +/// let t_type: TwentyFourType = get_twentyfour_data_from_index(index); +/// match t_type { +/// TwentyFourType::Bagua(bagua) => JsValue::from_serde(bagua).unwrap(), +/// TwentyFourType::Stem(stem) => JsValue::from_serde(stem).unwrap(), +/// TwentyFourType::Branch(branch) => JsValue::from_serde(branch).unwrap(), +/// } +/// } +/// ``` +pub fn get_twentyfour_data_from_index(index: usize) -> TwentyFourType<'static> { + let (t_type, t_index) = TWENTYFOUR_ORDER_START_NORTH[index]; + match t_type { + 0 => TwentyFourType::Bagua(&BAGUA[t_index]), + 1 => TwentyFourType::Stem(&STEMS[t_index]), + 2 => TwentyFourType::Branch(&BRANCHES[t_index]), + _ => panic!("Unknown type: {}", t_type), + } +} + +// =========================================================== +// From **DEGREES** +// =========================================================== + +/// From the given degrees, returns the corresponding `Direction`. +/// +/// Example: +/// ```rust +/// use mikaboshi::compass::{get_twentyfour_direction_from_degrees, Direction}; +/// use wasm_bindgen::prelude::*; +/// +/// #[wasm_bindgen] +/// pub fn xx(degrees: f32) -> JsValue { +/// let dir: Direction = get_twentyfour_direction_from_degrees(degrees); +/// JsValue::from_serde(&dir).unwrap() +/// } +/// ``` +pub fn get_twentyfour_direction_from_degrees(d: f32) -> Direction { + if !(7.5..352.5).contains(&d) { + // d >= 352.5 || d < 7.5 + Direction::new("n", 2) + } else if d < 22.5 { + Direction::new("n", 3) + } else if d < 37.5 { + Direction::new("ne", 1) + } else if d < 52.5 { + Direction::new("ne", 2) + } else if d < 67.5 { + Direction::new("ne", 3) + } else if d < 82.5 { + Direction::new("e", 1) + } else if d < 97.5 { + Direction::new("e", 2) + } else if d < 112.5 { + Direction::new("e", 3) + } else if d < 127.5 { + Direction::new("se", 1) + } else if d < 142.5 { + Direction::new("se", 2) + } else if d < 157.5 { + Direction::new("se", 3) + } else if d < 172.5 { + Direction::new("s", 1) + } else if d < 187.5 { + Direction::new("s", 2) + } else if d < 202.5 { + Direction::new("s", 3) + } else if d < 217.5 { + Direction::new("sw", 1) + } else if d < 232.5 { + Direction::new("sw", 2) + } else if d < 247.5 { + Direction::new("sw", 3) + } else if d < 262.5 { + Direction::new("w", 1) + } else if d < 277.5 { + Direction::new("w", 2) + } else if d < 292.5 { + Direction::new("w", 3) + } else if d < 307.5 { + Direction::new("nw", 1) + } else if d < 322.5 { + Direction::new("nw", 2) + } else if d < 337.5 { + Direction::new("nw", 3) + } else { + // d < 352.5 + Direction::new("n", 1) + } +} + +// =========================================================== +// From **DIRECTION** +// =========================================================== + +/// From the given direction and sector, finds the corresponding index +/// in `TWENTYFOUR_DIRECTIONS_TO_INDEX` +pub fn get_twentyfour_index_from_direction(direction: &str, sector: usize) -> usize { + *TWENTYFOUR_DIRECTIONS_TO_INDEX + .get(format!("{}{}", direction, sector).as_str()) + .unwrap() +} + +/// From the given direction and sector, returns `TwentyFourType`. +/// +/// Example: +/// ```rust +/// use mikaboshi::compass::{get_twentyfour_data_from_direction, TwentyFourType}; +/// use wasm_bindgen::prelude::*; +/// +/// #[wasm_bindgen] +/// pub fn xx(direction: &str, sector: usize) -> JsValue { +/// let t_type: TwentyFourType = get_twentyfour_data_from_direction(direction, sector); +/// match t_type { +/// TwentyFourType::Bagua(bagua) => JsValue::from_serde(bagua).unwrap(), +/// TwentyFourType::Stem(stem) => JsValue::from_serde(stem).unwrap(), +/// TwentyFourType::Branch(branch) => JsValue::from_serde(branch).unwrap(), +/// } +/// } +/// ``` +pub fn get_twentyfour_data_from_direction( + direction: &str, + sector: usize, +) -> TwentyFourType<'static> { + get_twentyfour_data_from_index(get_twentyfour_index_from_direction(direction, sector)) +} + +/// From the given direction and sector, returns `Direction`. +pub fn get_twentyfour_direction_from_direction(direction: &str, sector: usize) -> &Direction { + &TWENTYFOUR_INDEX_TO_DIRECTIONS[get_twentyfour_index_from_direction(direction, sector)] +} + +#[cfg(test)] +mod tests { + use super::*; + + // TODO: DIRECTION + // TODO: DIRECTION_POSITIONS_IN_CHART + + #[test] + fn test_get_direction_positions_in_chart() { + let exp = ["nw", "n", "ne", "w", "", "e", "sw", "s", "se"]; + assert_eq!(get_direction_positions_in_chart("n").unwrap(), &exp); + } + + // TODO: OPPOSITE_DIRECTION + // TODO: get_opposite_direction + // TODO: TWENTYFOUR_SECTORS + + #[test] + fn test_constant_twentyfour_index_to_directions() { + assert_eq!( + TWENTYFOUR_INDEX_TO_DIRECTIONS[0], + Direction { + direction: String::from("n"), + sector: 2, + } + ); + } + + #[test] + fn test_get_twentyfour_direction_from_index() { + let exp = Direction { + direction: String::from("n"), + sector: 2, + }; + assert_eq!(get_twentyfour_direction_from_index(0), &exp); + } + + #[test] + fn test_constant_twentyfour_directions_to_index() { + assert_eq!(*TWENTYFOUR_DIRECTIONS_TO_INDEX.get("n2").unwrap(), 0_usize); + } + + // Only for test + impl TwentyFourType<'static> { + fn is_branch(&self) -> bool { + match self { + TwentyFourType::Branch(_) => true, + _ => false, + } + } + } + + // TODO: TWENTYFOUR_ORDER_START_NORTH + + #[test] + fn test_get_twentyfour_data_from_index() { + assert!(get_twentyfour_data_from_index(0).is_branch()); + } + + #[test] + fn test_get_twentyfour_direction_from_degrees() { + assert_eq!( + get_twentyfour_direction_from_degrees(0_f32), + Direction { + direction: String::from("n"), + sector: 2, + } + ); + } + + // TODO: get_twentyfour_index_from_direction + // TODO: get_twentyfour_data_from_direction + // TODO: get_twentyfour_direction_from_direction +} diff --git a/src/constants.rs b/src/constants.rs deleted file mode 100644 index 1c723d1..0000000 --- a/src/constants.rs +++ /dev/null @@ -1,128 +0,0 @@ -use serde::{Deserialize}; - -use crate::ganzhi::{Stem, Branch, StemData, BranchData}; -use crate::language::NameDataTrait; -use crate::solar_terms::{SolarTerm, SolarTermData}; -use crate::wuxing::{WuXing, WuXingData}; - -fn get_json<'a, T: Deserialize<'a>>(json: &'a str) -> Vec { - match serde_json::from_str(json) { - Ok(json) => json, - Err(err) => panic!("Error: {}", err), - } -} - -lazy_static! { - pub static ref SOLAR_TERMS: Vec = { - let json = &include_str!("../json/solar_terms.json"); - let data: Vec = get_json::(json); - data.iter().map(|item| { - let item = item.clone(); - SolarTerm { - id: item.id, - name: item.language_from_data(), - angle: item.angle, - } - }).collect() - }; - - // Combination of Stems (10) and Branches (12) which makes 60 patterns. - pub static ref GANZHI_SEXAGESIMAL: Vec<(usize, usize)> = { - let mut v = vec![]; - for i in 0..60 { - let stem = (i % 10) as usize; - let branch = (i % 12) as usize; - v.push((stem, branch)); - } - v - }; - - pub static ref STEMS: Vec = { - let json = &include_str!("../json/ganzhi_stems.json"); - let data: Vec = get_json::(json); - data.iter().map(|item| { - let item = item.clone(); - Stem { - no: item.no, - name: item.language_from_data(), - } - }).collect() - }; - - pub static ref BRANCHES: Vec = { - let json = &include_str!("../json/ganzhi_branches.json"); - let data: Vec = get_json::(json); - data.iter().map(|item| { - let item = item.clone(); - Branch { - no: item.no, - name: item.language_from_data(), - } - }).collect() - }; - - pub static ref WUXING: Vec = { - let json = &include_str!("../json/wuxing.json"); - let data: Vec = get_json::(json); - data.iter().map(|item| { - let item = item.clone(); - WuXing { - no: item.no, - name: item.language_from_data(), - } - }).collect() - }; - - /// This is a table used when finding Hour Stem. - /// Columns represents Day Stem groups, and there are 5 groups. - /// For insntace, if you have "甲" for Day Stem, - /// you are looking into the first column (group). - /// Rows represents Hour Branches, and there are 12. - /// For instance, if you have "子" for Hour Branch, - /// you are looking into the first row. - /// Therefore, when you have "甲" for Day Stem, - /// and "子" for Hour Branch, Hour Stem is located - /// in the first column in the first row, which is "甲". - /// - ///   甲乙丙丁戊 - ///   己庚辛壬癸 - /// ------------- - /// 子: 甲丙戊庚壬 - /// 丑: 乙丁己辛癸 - /// 寅: 丙戊庚壬甲 - /// 卯: 丁己辛癸乙 - /// 辰: 戊庚壬甲丙 - /// 巳: 己辛癸乙丁 - /// 午: 庚壬甲丙戊 - /// 未: 辛癸乙丁己 - /// 申: 壬甲丙戊庚 - /// 酉: 癸乙丁己辛 - /// 戌: 甲丙戊庚壬 - /// 亥: 乙丁己辛癸 - pub static ref HOUR_STEM_TABLE: [[usize; 5]; 12] = [ - // 子 - [0, 2, 4, 6, 8], // 甲丙戊庚壬 - // 丑 - [1, 3, 5, 7, 9], // 乙丁己辛癸 - // 寅 - [2, 4, 6, 8, 0], // 丙戊庚壬甲 - // 卯 - [3, 5, 7, 9, 1], // 丁己辛癸乙 - // 辰 - [4, 6, 8, 0, 2], // 戊庚壬甲丙 - // 巳 - [5, 7, 9, 1, 3], // 己辛癸乙丁 - // 午 - [6, 8, 0, 2, 4], // 庚壬甲丙戊 - // 未 - [7, 9, 1, 3, 5], // 辛癸乙丁己 - // 申 - [8, 0, 2, 4, 6], // 壬甲丙戊庚 - // 酉 - [9, 1, 3, 5, 7], // 癸乙丁己辛 - // 戌 - [0, 2, 4, 6, 8], // 甲丙戊庚壬 - // 亥 - [1, 3, 5, 7, 9], // 乙丁己辛癸 - ]; -} diff --git a/src/ganzhi.rs b/src/ganzhi.rs index f19871d..7d8991c 100644 --- a/src/ganzhi.rs +++ b/src/ganzhi.rs @@ -1,3 +1,39 @@ +//! Based on 5 elements in nature with its 陰 (Yin) and 陽 (Yang) for each, +//! ancient Chinese described the plant growth using 10 conventional symbols +//! known as "10 Gan" (十干). Also, they tracked the motion of Jupiter +//! (which has 12 year cycle) and so they did divided the night sky into 12 regions, +//! and this is known as "12 Zhi" (十二支). When they record time and space, +//! they used the combinations of 10 Gan (干) and 12 Zhi (支) +//! which makes 60 patterns, and this is called 干支 (Gan-Zhi). +//! +//! 10 Gan (干): +//! +//! [0] 甲 (Jia) +//! [1] 乙 (Yi) +//! [2] 丙 (Bing) +//! [3] 丁 (Ding) +//! [4] 戊 (Wu) +//! [5] 己 (Ji) +//! [6] 庚 (Geng) +//! [7] 辛 (Xin) +//! [8] 壬 (Ren) +//! [9] 癸 (Gui) +//! +//! 12 Zhi (支): +//! +//! [0] 子 (Zi) +//! [1] 丑 (Chou) +//! [2] 寅 (Yin) +//! [3] 卯 (Mao) +//! [4] 辰 (Chen) +//! [5] 巳 (Si) +//! [6] 午 (Wu) +//! [7] 未 (Wei) +//! [8] 申 (Shen) +//! [9] 酉 (You) +//! [10] 戌 (Xu) +//! [11] 亥 (Hai) + #[cfg(test)] use sowngwala::time::Month; @@ -6,54 +42,62 @@ use sowngwala::time::{ julian_day, julian_day_from_ut, modified_julian_day_from_ut, Date, DateTime, Time, }; -use crate::constants::{BRANCHES, GANZHI_SEXAGESIMAL, HOUR_STEM_TABLE, STEMS}; use crate::language::{Language, LanguageData, LanguageTrait, NameDataTrait}; use crate::solar_terms::get_lichun; use crate::time::ut_from_local; -use crate::utils::longitude_of_the_sun_from_date; +use crate::utils::{get_json, longitude_of_the_sun_from_date}; +/// A struct representing 干 (Gan) or "Stem" and stores its attributes. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Stem { - pub no: u8, + pub num: u8, pub name: Language, } +/// A struct representing 支 (Zhi) or "Branch" and stores its attributes. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Branch { - pub no: u8, + pub num: u8, pub name: Language, } +/// A temporary struct for loading JSON data when defining a static const `STEMS`. #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct StemData { - pub no: u8, +pub struct StemRawData { + pub num: u8, pub name: LanguageData, } +/// A temporary struct for loading JSON data when defining a static const `BRANCHES`. #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct BranchData { - pub no: u8, +pub struct BranchRawData { + pub num: u8, pub name: LanguageData, } -impl NameDataTrait for StemData { +impl NameDataTrait for StemRawData { fn name(&self) -> Box { Box::new(self.name.clone()) } } -impl NameDataTrait for BranchData { +impl NameDataTrait for BranchRawData { fn name(&self) -> Box { Box::new(self.name.clone()) } } +/// A struct for holding `Stem` and `Branch`, or denoted as 干支 (Gan-Zhi). #[derive(Debug, Serialize)] pub struct GanZhi<'a> { pub stem: &'a Stem, pub branch: &'a Branch, } +/// A struct representing 八字 (Bazi) and stores `GanZhi` as its attributes. +/// It is referred as "The Four Pillars of Destiny" in English +/// mainly because the structure of 八字 (Bazi) necessary +/// for divinations in 四柱命理学 (_"The Four Pillars of Destiny"_). #[derive(Debug, Serialize)] pub struct Bazi<'a> { pub year: GanZhi<'a>, @@ -104,28 +148,177 @@ impl<'a> Bazi<'a> { } } + /// Returns `Bazi` from localtime (`DateTime`) and zone (`i8`). + /// + /// Example: + /// ```rust + /// use mikaboshi::ganzhi::Bazi; + /// use mikaboshi::time::{DateTime, Month}; + /// use wasm_bindgen::prelude::*; + /// + /// #[wasm_bindgen] + /// pub fn get_bazi(params: &JsValue) -> JsValue { + /// let localtime = DateTime { + /// year: 1985, + /// month: Month::Nov, + /// day: 5.0, + /// hour: 1, + /// min: 35, + /// sec: 0.0, + /// }; + /// let zone: i8 = 9; + /// JsValue::from_serde(&Bazi::from_local(&localtime, zone)).unwrap() + /// } + /// ``` pub fn from_local(lt: &DateTime, zone: i8) -> Bazi { - let ut = ut_from_local(<, zone); + let ut = ut_from_local(lt, zone); println!("ut: {:?}", ut); - let year = _year_ganzhi(Box::new(ut)); - let month = _month_ganzhi(Box::new(ut), year.stem.no); - let day = _day_ganzhi(Box::new(ut)); - let hour = _hour_ganzhi(Box::new(Time::from(lt)), day.stem.no); + let year = get_year_ganzhi(Box::new(ut)); + let month = get_month_ganzhi(Box::new(ut), year.stem.num); + let day = get_day_ganzhi(Box::new(ut)); + let hour = get_hour_ganzhi(Box::new(Time::from(lt)), day.stem.num); Bazi::new(year, month, day, hour) } pub fn from_ut(ut: &DateTime, t: &Time) -> Bazi<'a> { - let year = _year_ganzhi(Box::new(*ut)); - let month = _month_ganzhi(Box::new(*ut), year.stem.no); - let day = _day_ganzhi(Box::new(*ut)); - let hour = _hour_ganzhi(Box::new(*t), day.stem.no); + let year = get_year_ganzhi(Box::new(*ut)); + let month = get_month_ganzhi(Box::new(*ut), year.stem.num); + let day = get_day_ganzhi(Box::new(*ut)); + let hour = get_hour_ganzhi(Box::new(*t), day.stem.num); Bazi::new(year, month, day, hour) } } +lazy_static! { + /// A static vector with 60 items. `Vec` where the first + /// `usize` being the `STEMS` index, and the second for the `BRANCHES`. + /// It is simply the combination of 10 stems and 12 branches + /// which eventually adds up to 60 patterns. + pub static ref GANZHI_SEXAGESIMAL: Vec<(usize, usize)> = { + let mut v = vec![]; + for i in 0..60 { + let stem = (i % 10) as usize; + let branch = (i % 12) as usize; + v.push((stem, branch)); + } + v + }; + + /// A static vector with 10 items, each represents 干 (Gan). + /// Each stores associated attributes for the 干 (Gan). + /// + /// [0] 甲 (Jia) + /// [1] 乙 (Yi) + /// [2] 丙 (Bing) + /// [3] 丁 (Ding) + /// [4] 戊 (Wu) + /// [5] 己 (Ji) + /// [6] 庚 (Geng) + /// [7] 辛 (Xin) + /// [8] 壬 (Ren) + /// [9] 癸 (Gui) + /// + /// For attributes details stored in the vector is found in JSON file: + /// `src/json/ganzhi_stems.json` + pub static ref STEMS: Vec = { + let json = &include_str!("../json/ganzhi_stems.json"); + let data: Vec = get_json::(json); + data.iter().map(|item| { + let item = item.clone(); + Stem { + num: item.num, + name: item.language_from_data(), + } + }).collect() + }; + + /// A static vector with 10 items, each represents 支 (Zhi). + /// Each stores associated attributes for the 支 (Zhi). + /// + /// [0] 子 (Zi) + /// [1] 丑 (Chou) + /// [2] 寅 (Yin) + /// [3] 卯 (Mao) + /// [4] 辰 (Chen) + /// [5] 巳 (Si) + /// [6] 午 (Wu) + /// [7] 未 (Wei) + /// [8] 申 (Shen) + /// [9] 酉 (You) + /// [10] 戌 (Xu) + /// [11] 亥 (Hai) + /// + /// For attributes details stored in the vector is found in JSON file: + /// `src/json/ganzhi_branches.json` + pub static ref BRANCHES: Vec = { + let json = &include_str!("../json/ganzhi_branches.json"); + let data: Vec = get_json::(json); + data.iter().map(|item| { + let item = item.clone(); + Branch { + num: item.num, + name: item.language_from_data(), + } + }).collect() + }; + + /// This is a table used when finding "Hour Stem". + /// Columns represents "Day Stem" groups, and there are 5 groups. + /// For insntace, if you have 甲 for "Day Stem", + /// you are looking into the first column (group). + /// Rows represents "Hour Branches" for which there are 12. + /// For instance, if you have 子 for "Hour Branch", + /// you are looking into the first row. + /// So, when you have 甲 for "Day Stem", + /// and 子 for "Hour Branch", "Hour Stem" is located + /// in the first column in the first row, which is 甲. + /// + ///       甲乙丙丁戊 + ///       己庚辛壬癸 + /// ‐‐‐‐‐‐‐‐‐‐‐‐‐ + /// 子: 甲丙戊庚壬 + /// 丑: 乙丁己辛癸 + /// 寅: 丙戊庚壬甲 + /// 卯: 丁己辛癸乙 + /// 辰: 戊庚壬甲丙 + /// 巳: 己辛癸乙丁 + /// 午: 庚壬甲丙戊 + /// 未: 辛癸乙丁己 + /// 申: 壬甲丙戊庚 + /// 酉: 癸乙丁己辛 + /// 戌: 甲丙戊庚壬 + /// 亥: 乙丁己辛癸 + pub static ref HOUR_STEM_TABLE: [[usize; 5]; 12] = [ + // 子 + [0, 2, 4, 6, 8], // 甲丙戊庚壬 + // 丑 + [1, 3, 5, 7, 9], // 乙丁己辛癸 + // 寅 + [2, 4, 6, 8, 0], // 丙戊庚壬甲 + // 卯 + [3, 5, 7, 9, 1], // 丁己辛癸乙 + // 辰 + [4, 6, 8, 0, 2], // 戊庚壬甲丙 + // 巳 + [5, 7, 9, 1, 3], // 己辛癸乙丁 + // 午 + [6, 8, 0, 2, 4], // 庚壬甲丙戊 + // 未 + [7, 9, 1, 3, 5], // 辛癸乙丁己 + // 申 + [8, 0, 2, 4, 6], // 壬甲丙戊庚 + // 酉 + [9, 1, 3, 5, 7], // 癸乙丁己辛 + // 戌 + [0, 2, 4, 6, 8], // 甲丙戊庚壬 + // 亥 + [1, 3, 5, 7, 9], // 乙丁己辛癸 + ]; +} + /// Year Ganzhi -fn _year_ganzhi(ut: Box) -> GanZhi<'static> { +fn get_year_ganzhi(ut: Box) -> GanZhi<'static> { // Year Stem and Branch are easily found. // However, we must watch out if it is before // or after Lichun. The year begins from Lichun, @@ -161,7 +354,7 @@ fn _year_ganzhi(ut: Box) -> GanZhi<'static> { /// Month Ganzhi #[allow(clippy::boxed_local)] -fn _month_ganzhi(ut: Box, year_stem_no: u8) -> GanZhi<'static> { +fn get_month_ganzhi(ut: Box, year_stem_num: u8) -> GanZhi<'static> { let lng: f64 = longitude_of_the_sun_from_date(&Date::from(&*ut)); // Branch is easily found by looking at the longitude of the sun. @@ -198,13 +391,13 @@ fn _month_ganzhi(ut: Box, year_stem_no: u8) -> GanZhi<'static> { // you simply count up to the current month. // This is done by adding 'branch_id' because 'branch_id' // is nothing but how many month from the beginning (Lichun). - let stem_index: usize = if year_stem_no == 1 || year_stem_no == 6 { + let stem_index: usize = if year_stem_num == 1 || year_stem_num == 6 { 2 // 甲(jia:1) or 己(ji:6) ---> 丙(bing:3) - } else if year_stem_no == 2 || year_stem_no == 7 { + } else if year_stem_num == 2 || year_stem_num == 7 { 4 // 乙(yi:2) or 庚(geng:7) ---> 戊(wu:5) - } else if year_stem_no == 3 || year_stem_no == 8 { + } else if year_stem_num == 3 || year_stem_num == 8 { 6 // 丙(bing:3) or 辛(xin:8) ---> 庚(geng:7) - } else if year_stem_no == 4 || year_stem_no == 9 { + } else if year_stem_num == 4 || year_stem_num == 9 { 8 // 丁(ding:4) or 壬(ren:9) ---> 壬(ren:9) } else { 0 // 戊(wu:5) or 癸(gui:10) ---> 甲(jia:1) @@ -218,7 +411,7 @@ fn _month_ganzhi(ut: Box, year_stem_no: u8) -> GanZhi<'static> { /// Day Ganzhi #[allow(clippy::boxed_local)] -fn _day_ganzhi(ut: Box) -> GanZhi<'static> { +fn get_day_ganzhi(ut: Box) -> GanZhi<'static> { let mjd: f64 = modified_julian_day_from_ut(&*ut); let index = ((mjd - 10.0) % 60.0).floor() as usize; @@ -232,7 +425,7 @@ fn _day_ganzhi(ut: Box) -> GanZhi<'static> { /// Hour Ganzhi #[allow(clippy::boxed_local)] -fn _hour_ganzhi(t: Box